diff --git a/.clang-format-ignore b/.clang-format-ignore index b5ffeafaf2..1f24beecaa 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -12,3 +12,5 @@ driver/syscall_compat_s390x.h driver/syscall_compat_x86_64.h driver/syscall_ia32_64_map.c driver/syscall_table.c +# All third party code is not formatted +./contrib \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4bbe7a7c18..fd7fb83992 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,7 +95,7 @@ jobs: steps: - name: Install deps ⛓️ run: | - apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils clang llvm + apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils clang llvm bsd-compat-headers git clone https://github.com/libbpf/bpftool.git --branch v7.3.0 --single-branch cd bpftool git submodule update --init @@ -345,7 +345,7 @@ jobs: - name: Install deps ⛓️ run: | sudo apt update - sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libelf-dev libcap-dev linux-headers-$(uname -r) emscripten + sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 llvm-14 git pkg-config autoconf automake libtool libcap-dev linux-headers-$(uname -r) emscripten libc6-dev - name: Checkout Libs ⤵️ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 0000000000..ad66b56ef2 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1 @@ +contrib/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 03af22f2b6..42235d987e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,8 @@ if(BUILD_SHARED_LIBS) message(STATUS "Shared library soversion: ${FALCOSECURITY_SHARED_LIBS_SOVERSION}") endif() +add_subdirectory(contrib/elftoolchain) + include(libscap) include(libsinsp) diff --git a/cmake/modules/libbpf.cmake b/cmake/modules/libbpf.cmake index e68b862600..c7dda238fc 100644 --- a/cmake/modules/libbpf.cmake +++ b/cmake/modules/libbpf.cmake @@ -13,42 +13,45 @@ # the License. # -option(USE_BUNDLED_LIBBPF "Enable building of the bundled libbpf" ${USE_BUNDLED_DEPS}) - if(LIBBPF_INCLUDE) # we already have libbpf -elseif(NOT USE_BUNDLED_LIBBPF) - find_path(LIBBPF_INCLUDE bpf/libbpf.h) - find_library(LIBBPF_LIB NAMES bpf) - if(LIBBPF_INCLUDE AND LIBBPF_LIB) - message(STATUS "Found libbpf: include: ${LIBBPF_INCLUDE}, lib: ${LIBBPF_LIB}") - else() - message(FATAL_ERROR "Couldn't find system libbpf") - endif() else() include(zlib) - include(libelf) set(LIBBPF_SRC "${PROJECT_BINARY_DIR}/libbpf-prefix/src") set(LIBBPF_BUILD_DIR "${LIBBPF_SRC}/libbpf-build") set(LIBBPF_INCLUDE "${LIBBPF_BUILD_DIR}/root/usr/include") set(LIBBPF_LIB "${LIBBPF_BUILD_DIR}/root/usr/lib64/libbpf.a") + + get_target_property(LIBELF_INCLUDE_DIR elf INCLUDE_DIRECTORIES) + + foreach(dir ${LIBELF_INCLUDE_DIR}) + string(APPEND LIBELF_COMPILER_STRING "-I${dir} ") + endforeach() + ExternalProject_Add( libbpf PREFIX "${PROJECT_BINARY_DIR}/libbpf-prefix" - DEPENDS zlib libelf + DEPENDS zlib elf URL "https://github.com/libbpf/libbpf/archive/refs/tags/v1.3.0.tar.gz" URL_HASH "SHA256=11db86acd627e468bc48b7258c1130aba41a12c4d364f78e184fd2f5a913d861" CONFIGURE_COMMAND mkdir -p build root BUILD_COMMAND make BUILD_STATIC_ONLY=y OBJDIR=${LIBBPF_BUILD_DIR}/build DESTDIR=${LIBBPF_BUILD_DIR}/root NO_PKG_CONFIG=1 - "EXTRA_CFLAGS=-fPIC -I${LIBELF_INCLUDE} -I${ZLIB_INCLUDE}" "LDFLAGS=-Wl,-Bstatic" + "EXTRA_CFLAGS=-fPIC ${LIBELF_COMPILER_STRING} -I${ZLIB_INCLUDE}" "LDFLAGS=-Wl,-Bstatic" "EXTRA_LDFLAGS=-L${LIBELF_SRC}/libelf/libelf -L${ZLIB_SRC}" -C ${LIBBPF_SRC}/libbpf/src install install_uapi_headers INSTALL_COMMAND "" UPDATE_COMMAND "" BUILD_BYPRODUCTS ${LIBBPF_LIB} ) + + add_library(lbpf STATIC IMPORTED) + set_target_properties(lbpf PROPERTIES IMPORTED_LOCATION ${LIBBPF_LIB}) + file(MAKE_DIRECTORY ${LIBBPF_INCLUDE}) # necessary to make target_include_directories() work + target_include_directories(lbpf INTERFACE ${LIBBPF_INCLUDE}) + target_link_libraries(lbpf INTERFACE elf ${ZLIB_LIB}) + message(STATUS "Using bundled libbpf: include'${LIBBPF_INCLUDE}', lib: ${LIBBPF_LIB}") install( FILES "${LIBBPF_LIB}" @@ -57,8 +60,3 @@ else() ) endif() -if(NOT TARGET libbpf) - add_custom_target(libbpf) -endif() - -include_directories(${LIBBPF_INCLUDE}) diff --git a/contrib/README.md b/contrib/README.md new file mode 100644 index 0000000000..d265fbe51f --- /dev/null +++ b/contrib/README.md @@ -0,0 +1,25 @@ +# Contrib directory + +This directory contains forks of some projects that may not be included as-is and require custom patches. + +## Elftoolchain + +This is the version of Elftoolchain (https://sourceforge.net/projects/elftoolchain/) that is used to satisfy the `libelf` requirement of the Falco libraries and its dependent `libbpf`. + +This is how this fork was created: + +* We downloaded the code from https://sourceforge.net/projects/elftoolchain/ +* We precompiled the autogenerated files by running: + +```sh +cd common/sys +m4 -I$(pwd) -D SRCDIR=$(pwd) elfdefinitions.m4 > elfdefinitions.h +cd ../../libelf +m4 -D SRCDIR=$(pwd) libelf_fsize.m4 > libelf_fsize.c +m4 -D SRCDIR=$(pwd) libelf_msize.m4 > libelf_msize.c +m4 -D SRCDIR=$(pwd) libelf_convert.m4 > libelf_convert.c +``` + +* We wrote `CMakeLists.txt` and `libelf/CMakeLists.txt` to enable CMake to build `libelf` +* We added compatibility patches `elf.h`, `gelf_getnote.c`, `gelf_versym.c` and modified `gelf.h`, `libelf.h` to make this flavor of libelf work with libbpf +* This way, a new target `elf` is built and can be linked via `target_link_libraries()` diff --git a/contrib/elftoolchain/.cirrus.yml b/contrib/elftoolchain/.cirrus.yml new file mode 100644 index 0000000000..7f0c7fc703 --- /dev/null +++ b/contrib/elftoolchain/.cirrus.yml @@ -0,0 +1,31 @@ +env: + CIRRUS_CLONE_DEPTH: 1 + +freebsd_task: + freebsd_instance: + matrix: + image: freebsd-11-2-release-amd64 + image: freebsd-12-1-release-amd64 + install_script: pkg install -y git py27-yaml + script: + - fetch http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz + - tar -x -C test/tet -f tet3.8-src.tar.gz + - make + test_script: + - make run-tests + +ubuntu_task: + container: + image: ubuntu:18.04 + setup_script: + - apt-get update + - apt-get install -y + binutils bison bmake curl flex g++ gcc git + libarchive-dev libbsd-dev libc6-dev libexpat1-dev lsb-release + m4 perl python-yaml sharutils zlib1g-dev + script: + - curl -O http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz + - tar -x -C test/tet -z -f tet3.8-src.tar.gz + - bmake + test_script: + - bmake run-tests diff --git a/contrib/elftoolchain/.style.yapf b/contrib/elftoolchain/.style.yapf new file mode 100644 index 0000000000..50ade98db3 --- /dev/null +++ b/contrib/elftoolchain/.style.yapf @@ -0,0 +1,217 @@ +[style] +# Align closing bracket with visual indentation. +align_closing_bracket_with_visual_indent=True + +# Allow dictionary keys to exist on multiple lines. For example: +# +# x = { +# ('this is the first element of a tuple', +# 'this is the second element of a tuple'): +# value, +# } +allow_multiline_dictionary_keys=False + +# Allow lambdas to be formatted on more than one line. +allow_multiline_lambdas=True + +# Allow splits before the dictionary value. +allow_split_before_dict_value=True + +# Insert a blank line before a class-level docstring. +blank_line_before_class_docstring=False + +# Insert a blank line before a 'def' or 'class' immediately nested +# within another 'def' or 'class'. For example: +# +# class Foo: +# # <------ this blank line +# def method(): +# ... +blank_line_before_nested_class_or_def=True + +# Do not split consecutive brackets. Only relevant when +# dedent_closing_brackets is set. For example: +# +# call_func_that_takes_a_dict( +# { +# 'key1': 'value1', +# 'key2': 'value2', +# } +# ) +# +# would reformat to: +# +# call_func_that_takes_a_dict({ +# 'key1': 'value1', +# 'key2': 'value2', +# }) +coalesce_brackets=True + +# The column limit. +column_limit=79 + +# Indent width used for line continuations. +continuation_indent_width=4 + +# Put closing brackets on a separate line, dedented, if the bracketed +# expression can't fit in a single line. Applies to all kinds of brackets, +# including function definitions and calls. For example: +# +# config = { +# 'key1': 'value1', +# 'key2': 'value2', +# } # <--- this bracket is dedented and on a separate line +# +# time_series = self.remote_client.query_entity_counters( +# entity='dev3246.region1', +# key='dns.query_latency_tcp', +# transform=Transformation.AVERAGE(window=timedelta(seconds=60)), +# start_ts=now()-timedelta(days=3), +# end_ts=now(), +# ) # <--- this bracket is dedented and on a separate line +dedent_closing_brackets=False + +# Place each dictionary entry onto its own line. +each_dict_entry_on_separate_line=True + +# The regex for an i18n comment. The presence of this comment stops +# reformatting of that line, because the comments are required to be +# next to the string they translate. +i18n_comment= + +# The i18n function call names. The presence of this function stops +# reformattting on that line, because the string it has cannot be moved +# away from the i18n comment. +i18n_function_call= + +# Indent the dictionary value if it cannot fit on the same line as the +# dictionary key. For example: +# +# config = { +# 'key1': +# 'value1', +# 'key2': value1 + +# value2, +# } +indent_dictionary_value=False + +# The number of columns to use for indentation. +indent_width=4 + +# Join short lines into one line. E.g., single line 'if' statements. +join_multiple_lines=True + +# Do not include spaces around selected binary operators. For example: +# +# 1 + 2 * 3 - 4 / 5 +# +# will be formatted as follows when configured with a value "*,/": +# +# 1 + 2*3 - 4/5 +# +no_spaces_around_selected_binary_operators=set() + +# Use spaces around default or named assigns. +spaces_around_default_or_named_assign=False + +# Use spaces around the power operator. +spaces_around_power_operator=False + +# The number of spaces required before a trailing comment. +spaces_before_comment=2 + +# Insert a space between the ending comma and closing bracket of a list, +# etc. +space_between_ending_comma_and_closing_bracket=True + +# Split before arguments if the argument list is terminated by a +# comma. +split_arguments_when_comma_terminated=False + +# Set to True to prefer splitting before '&', '|' or '^' rather than +# after. +split_before_bitwise_operator=True + +# Split before a dictionary or set generator (comp_for). For example, note +# the split before the 'for': +# +# foo = { +# variable: 'Hello world, have a nice day!' +# for variable in bar if variable != 42 +# } +split_before_dict_set_generator=True + +# Split after the opening paren which surrounds an expression if it doesn't +# fit on a single line. +split_before_expression_after_opening_paren=False + +# If an argument / parameter list is going to be split, then split before +# the first argument. +split_before_first_argument=False + +# Set to True to prefer splitting before 'and' or 'or' rather than +# after. +split_before_logical_operator=True + +# Split named assignments onto individual lines. +split_before_named_assigns=True + +# Set to True to split list comprehensions and generators that have +# non-trivial expressions and multiple clauses before each of these +# clauses. For example: +# +# result = [ +# a_long_var + 100 for a_long_var in xrange(1000) +# if a_long_var % 10] +# +# would reformat to something like: +# +# result = [ +# a_long_var + 100 +# for a_long_var in xrange(1000) +# if a_long_var % 10] +split_complex_comprehension=False + +# The penalty for splitting right after the opening bracket. +split_penalty_after_opening_bracket=30 + +# The penalty for splitting the line after a unary operator. +split_penalty_after_unary_operator=10000 + +# The penalty for splitting right before an if expression. +split_penalty_before_if_expr=0 + +# The penalty of splitting the line around the '&', '|', and '^' +# operators. +split_penalty_bitwise_operator=300 + +# The penalty for splitting a list comprehension or generator +# expression. +split_penalty_comprehension=80 + +# The penalty for characters over the column limit. +split_penalty_excess_character=4500 + +# The penalty incurred by adding a line split to the unwrapped line. The +# more line splits added the higher the penalty. +split_penalty_for_added_line_split=30 + +# The penalty of splitting a list of "import as" names. For example: +# +# from a_very_long_or_indented_module_name_yada_yad import (long_argument_1, +# long_argument_2, +# long_argument_3) +# +# would reformat to something like: +# +# from a_very_long_or_indented_module_name_yada_yad import ( +# long_argument_1, long_argument_2, long_argument_3) +split_penalty_import_names=0 + +# The penalty of splitting the line around the 'and' and 'or' +# operators. +split_penalty_logical_operator=300 + +# Use the Tab character for indentation. +use_tabs=False + diff --git a/contrib/elftoolchain/BASE-SYSTEM-IMPORT.rst b/contrib/elftoolchain/BASE-SYSTEM-IMPORT.rst new file mode 100644 index 0000000000..63ed779cca --- /dev/null +++ b/contrib/elftoolchain/BASE-SYSTEM-IMPORT.rst @@ -0,0 +1,62 @@ +Importing Elftoolchain Code +=========================== + +Downstream operating system projects often import Elftoolchain code +into their 'base system' source tree. Such imports often involve +project-specific modifications to Elftoolchain source code, e.g. the +addition of project-specific version control identifiers, the use of +project-specific headers, and so on. + +This document describes the placeholders that are present in the +Elftoolchain project's source code that help automate source code imports. + + +List of placeholders +-------------------- + +@ELFTC-DECLARE-DOWNSTREAM-VCSID@ + + A placeholder to be replaced with the definition of the downstream + project's version control system ID. + + E.g. on NetBSD this placeholder could be replaced with:: + + #if !defined(__RCSID) + #define __RCSID(ID) /**/ + #endif + +@ELFTC-DEFINE-ELFTC-VCSID@ + + This placeholder is meant to be replaced by a project-specific + definition of the ``ELFTC_VCSID()`` macro if the default definition + needs to be overridden. + +@ELFTC-USE-DOWNSTREAM-VCSID@ + + A placeholder to be replaced by the use of the downstream project's + version control ID. + + E.g. on NetBSD this placeholder could be replaced with:: + + __RCSID("$NetBSD$"); + +@ELFTC-INCLUDE-SYS-CDEFS@ + + Some projects define their copyright and revision control macros + in ````, and mandate that these macros should appear + immediately after any copyright text. Such projects can replace this + placeholder with the appropriate ``#include`` statement. + +@LIBELF-DEFINE-HOST-BYTEORDER@ + + A placeholder to be replaced by the downstream project's method to + determine the runtime byte order to use (ELF2LSB or ELF2MSB). + + Projects using GCC or CLANG would not ordinarily need to use this + placeholder. + +.. $Id$ + +.. Local Variables: +.. mode: rst +.. End: diff --git a/contrib/elftoolchain/CMakeLists.txt b/contrib/elftoolchain/CMakeLists.txt new file mode 100644 index 0000000000..8fcf2e3665 --- /dev/null +++ b/contrib/elftoolchain/CMakeLists.txt @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (C) 2024 The Falco Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License +# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +# or implied. See the License for the specific language governing permissions and limitations under +# the License. +# + +cmake_minimum_required(VERSION 3.12) + +# We only need libelf at this point +add_subdirectory(libelf) diff --git a/contrib/elftoolchain/GNUmakefile b/contrib/elftoolchain/GNUmakefile new file mode 100644 index 0000000000..89e9d16809 --- /dev/null +++ b/contrib/elftoolchain/GNUmakefile @@ -0,0 +1,22 @@ +# -*- mode: makefile; -*- +# +# Issue a useful error message if a user tries to build the project +# using GNU make. + +all: + $(error ERROR: This source tree needs to be built with BSD 'make'.) + +# Some GNU/Linux distributions offer pre-built packages of BSD 'make': +# +# - On Debian-derived distributions, the "bmake" package provides a +# version of NetBSD 'make' that should suffice. +# - On Fedora, the 'bmake' package seems appropriate (untested). +# +# Portable source code for NetBSD 'make' may be found at: +# http://www.crufty.net/help/sjg/bmake.html +# +# +# Please also read the file "INSTALL" for additional information about +# building the project from source. +# +# $Id: GNUmakefile 3910 2020-11-29 12:40:43Z jkoshy $ diff --git a/contrib/elftoolchain/INSTALL b/contrib/elftoolchain/INSTALL new file mode 100644 index 0000000000..9fa873da7e --- /dev/null +++ b/contrib/elftoolchain/INSTALL @@ -0,0 +1,284 @@ +Installation Instructions +========================= + +This file contains instructions on building and installing the +libraries and utilities in the elftoolchain project's sources. + +Supported Operating Systems +--------------------------- + +The source tree is currently built and tested on the following +operating systems. + + ================= ======== ======================= + Operating System Version Supported Architectures + ----------------- -------- ----------------------- + `DragonFly BSD`_ 5.8.1 amd64 + FreeBSD_ 13.1 arm64, amd64 & i386 + Minix_ 3.0.2 i386 + NetBSD_ 9.1 amd64 + OpenBSD_ 6.5 amd64 + Raspbian_ 10 armv7l + Ubuntu_ GNU/Linux 20.04 x86_64 + ================= ======== ======================= + +.. _DragonFly BSD: http://www.dragonflybsd.org/ +.. _FreeBSD: http://www.freebsd.org/ +.. _Minix: http://www.minix3.org/ +.. _NetBSD: http://www.netbsd.org/ +.. _OpenBSD: http://www.openbsd.org/ +.. _Raspbian: https://www.raspberrypi.org/software/ +.. _Ubuntu: http://www.ubuntu.com/ + +Building the Source Tree +======================== + +The core libraries and utilities that make up the software release are +always built by default. Builds of the project's test suites (in the +``test/`` subdirectory), and of additional documentation (in the directory +``documentation/``) are optional, and will only be attempted if these +directories are present. + +Prerequisites +------------- + +:DragonFly BSD 5.8.1: + - The core libraries and utilities should build out of the box on + a stock install of DragonFly BSD. + + - To build and run the test suite: + + #. The current release of the `Test Execution Toolkit`_ needs to + be downloaded and unpacked into the ``test/tet/`` directory. + + #. The ``py37-yaml`` package needs to be installed:: + + % sudo pkg install py37-yaml + + - Building additional documentation is not currently supported + under DragonFly BSD. + +:FreeBSD 13.1: + - The core libraries and utilities should build out of the box on + a stock install of FreeBSD. + + - To build and run the test suite: + + #. The current release of the `Test Execution Toolkit`_ needs to + be downloaded and unpacked into the ``test/tet/`` directory:: + + % cd /test/tet + % tar -xf /PATH/TO/DOWNLOADED/TET-3.8-SOURCES + + #. The ``py39-yaml`` package needs to be installed:: + + % sudo pkg install py39-yaml + + - Building additional documentation is not currently supported under + FreeBSD 13.1. + +:Minix 3.2.0: + - The following packages are pre-requisites for building the + sources on Minix 3.2.0: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``gcc44`` The GNU C compiler. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + # pkgin install gcc44 + + - The test suites cannot currently be built under Minix. + + - Building additional documentation is not currently supported + under Minix. + +:OpenBSD 6.5: + - The following packages are pre-requisites for building the + sources on OpenBSD 6.5: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``libarchive`` An archive access library. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + # pkg_add libarchive + + - Building additional documentation is not currently supported + under OpenBSD. + +:NetBSD 9.1: + - The core libraries and utilities should build out of the box on + a stock install of NetBSD 9.1. + + - To build and run the test suite: + + #. The current release of the `Test Execution Toolkit`_, needs + to be downloaded and unpacked into the ``test/tet/`` + directory. + + #. The following additional package needs to be installed, as + listed in the example command line below :: + + % sudo pkgin install py38-yaml + + - Building additional documentation is not currently supported + under NetBSD. + +:Ubuntu GNU/Linux 20.04: + - The following packages are pre-requisites for building the + sources on Ubuntu GNU/Linux 20.04: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``binutils`` Needed for the build. + ``bison`` Parser generator. + ``flex`` Lexical analyser. + ``gcc`` C compiler. + ``libarchive-dev`` Archive access library. + ``libbsd-dev`` BSD headers and libraries. + ``libc6-dev`` Files for C language development. + ``libexpat1-dev`` An XML processing library. + ``m4`` Macro processor. + ``bmake`` NetBSD ``make``. + ``python3-yaml`` A YAML library for Python. + ``sharutils`` For ``uudecode``. + ``zlib1g-dev`` Compression library. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + % sudo apt install binutils bison flex gcc libarchive-dev \ + libc6-dev m4 bmake zlib1g-dev + + - To build and run the test suite: + + #. The current release of the `Test Execution Toolkit`_, needs + to be downloaded and unpacked into the ``test/tet/`` + directory. + + #. The following additional packages need to be installed, as + listed in the example command line below:: + + % sudo apt install libexpat1-dev python3.8 python3-yaml \ + sharutils + + - To build additional documentation, the packages listed in the + example command line below are needed:: + + % sudo apt install html-xml-utils libbsd-dev mandoc \ + texlive-extra-utils texlive-latex-recommended texlive-pictures + +:Raspbian 10: + - The following packages are pre-requisites for building the + sources on Raspbian 10: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``bison`` Parser generator. + ``flex`` Lexical analyser. + ``libarchive-dev`` Archive access library. + ``m4`` Macro processor. + ``bmake`` NetBSD ``make``. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + % sudo apt install bison flex libarchive-dev m4 bmake + + - To build and run the test suite: + + #. The current release of the `Test Execution Toolkit`_ needs to + be downloaded and unpacked into the ``test/tet/`` directory:: + + % cd /test/tet + % tar -xf /PATH/TO/DOWNLOADED/TET-3.8-SOURCES + + #. The ``python3-yaml`` package needs to be installed:: + + % sudo apt install python3-yaml + + - Building additional documentation is not currently supported + under Raspbian. + +.. _Test Execution Toolkit: http://tetworks.opengroup.org/ +.. _OpenGroup: http://www.opengroup.org/ + + +Building the software +--------------------- + +The software may be built by running **make**. + +On `DragonFly BSD`_, FreeBSD_, Minix_, NetBSD_ and OpenBSD_, use:: + + % make + +On Ubuntu GNU/Linux with the **bmake** package installed, use:: + + % bmake + + +Testing the software +--------------------- + +The ``run-tests`` target in the top-level Makefile will build and +execute the test suites that are part of this software. + +On `DragonFly BSD`_, FreeBSD_ and NetBSD_, use:: + + % make run-tests + +On Ubuntu GNU/Linux with the **bmake** package installed, use:: + + % bmake run-tests + +Installing the Software +======================= + +The software may be installed using the ``install`` target. + +On `DragonFly BSD`_, FreeBSD_, Minix_, NetBSD_ and OpenBSD_ use:: + + % make install + +On Ubuntu GNU/Linux with the **bmake** package installed, use:: + + % bmake install + + +By default the ``install`` target will install utilities into +``/usr/bin/``, libraries into ``/usr/lib/`` and manual pages into +``/usr/share/man/man[0-9]/``. + +The installation directory may be changed using the ``DESTDIR`` +variable. For example:: + + % bmake DESTDIR=$HOME/local install + + +Additional Information +====================== + +Additional information about the project may be found on the `project +website`_. + +.. _project website: http://elftoolchain.sourceforge.net/ + +.. $Id: INSTALL 4004 2023-04-16 18:12:54Z jkoshy $ + +.. Local Variables: +.. mode: rst +.. End: diff --git a/contrib/elftoolchain/LICENSE b/contrib/elftoolchain/LICENSE new file mode 100644 index 0000000000..c707d2b43c --- /dev/null +++ b/contrib/elftoolchain/LICENSE @@ -0,0 +1,32 @@ +Unless otherwise specified, the Elftoolchain +project's sources are distributed under a +2-clause BSD license. + +SPDX short identifier: BSD-2-Clause + +<<<--->>> +Copyright (c) 2006-2021, Elftoolchain Project Contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +<<<--->>> diff --git a/contrib/elftoolchain/Makefile b/contrib/elftoolchain/Makefile new file mode 100644 index 0000000000..1e26cad908 --- /dev/null +++ b/contrib/elftoolchain/Makefile @@ -0,0 +1,67 @@ +# $Id: Makefile 4035 2024-01-16 17:46:07Z jkoshy $ + +TOP= . + +.include "${TOP}/mk/elftoolchain.components.mk" +.include "${TOP}/mk/elftoolchain.os.mk" + +# Build configuration information first. +SUBDIR += common + +# Build the base libraries next. +SUBDIR += libelf +SUBDIR += libdwarf + +# Build additional APIs. +SUBDIR += libelftc +.if defined(WITH_PE) && ${WITH_PE} == "yes" +SUBDIR += libpe +.endif + +# The instruction set analyser. +.if defined(WITH_ISA) && ${WITH_ISA} == "yes" +SUBDIR += isa # ('isa' does not build on all platforms yet). +.endif + +# Build tools after the libraries. +SUBDIR += addr2line +SUBDIR += ar +SUBDIR += brandelf +SUBDIR += cxxfilt +SUBDIR += elfcopy +SUBDIR += elfdump +SUBDIR += findtextrel +SUBDIR += ld +SUBDIR += nm +SUBDIR += readelf +SUBDIR += size +SUBDIR += strings + +# Build the test suites. +.if exists(${.CURDIR}/tests) && defined(WITH_TESTS) && ${WITH_TESTS} == "yes" +SUBDIR += tests +.endif + +# Build additional build tooling. +.if defined(WITH_BUILD_TOOLS) && ${WITH_BUILD_TOOLS} == "yes" +SUBDIR += tools +.endif + +# Build documentation at the end. +.if exists(${.CURDIR}/documentation) && \ + defined(WITH_ADDITIONAL_DOCUMENTATION) && \ + ${WITH_ADDITIONAL_DOCUMENTATION} == "yes" +SUBDIR += documentation +.endif + +.include "${TOP}/mk/elftoolchain.subdir.mk" + +# +# Special top-level targets. +# + +# Run the test suites. +.if exists(${.CURDIR}/tests) && defined(WITH_TESTS) && ${WITH_TESTS} == "yes" +test: all .PHONY + (cd ${.CURDIR}/tests && ${MAKE} test) +.endif diff --git a/contrib/elftoolchain/README.rst b/contrib/elftoolchain/README.rst new file mode 100644 index 0000000000..fa419657bb --- /dev/null +++ b/contrib/elftoolchain/README.rst @@ -0,0 +1,141 @@ +The Elftoolchain Project +======================== + +.. contents:: Table of Contents + +.. note:: + + If you are reading this README on a mirror site such as GitHub_, + please note that the primary development site for this project is at + `elftoolchain.sourceforge.net`_. + + Please use the SourceForge project's `bug tracker`_ + for reporting bugs and for sending in patches. If you + have other project-related questions, please ask them on the + ```` `mailing list`_. + +.. _GitHub: https://github.com/elftoolchain/elftoolchain +.. _`elftoolchain.sourceforge.net`: http://elftoolchain.sourceforge.net/ +.. _`mailing list`: https://sourceforge.net/p/elftoolchain/mailman/elftoolchain-developers/ + +Description +----------- + +This software implements essential compilation tools and libraries for: + +- managing program objects conforming to the ELF_ object format, and +- for managing DWARF_ debugging information in ELF objects. + +The project currently implements the following utilities and +libraries: + +=========== ============================================ +Name Description +=========== ============================================ +ar Archive manager. +addr2line Debug tool. +brandelf Manage the ELF brand on executables. +c++filt Translate encoded symbols. +elfcopy Copy and translate between object formats. +elfdump Diagnostic tool. +findtextrel Find undesired text relocations. +libdwarf DWARF access library. +libelf ELF access library. +mcs Manage comment sections. +nm List symbols in an ELF object. +ranlib Add archive symbol tables to an archive. +readelf Display ELF information. +size List object sizes. +strings Extract printable strings. +strip Discard information from ELF objects. +=========== ============================================ + +.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format +.. _DWARF: http://www.dwarfstd.org/ + + +Project Documentation +--------------------- + +- Release notes for released versions of this software are present in + the file ``RELEASE-NOTES`` in the current directory. +- The file ``INSTALL`` in the current directory contains instructions + on building and installing this software. +- Reference documentation in the form of manual pages is provided for + the utilities and libraries developed by the project. +- Additional tutorial documentation is present in the + ``documentation`` directory. + + +Tracking Ongoing Development +---------------------------- + +The project uses subversion_ for its version control system. + +.. _subversion: https://subversion.apache.org/ + +The subversion branch for the current set of sources may be accessed +at the following URL:: + + https://sourceforge.net/p/elftoolchain/code/HEAD/tree/trunk/ + +The project's source tree may be checked out from its repository by +using the ``svn checkout`` command:: + + % svn checkout https://svn.code.sf.net/p/elftoolchain/code/trunk + +Checked-out sources may be kept upto-date by running ``svn update`` +inside the source directory:: + + % svn update + + +Instructions on building and installing the software are given in the +file ``INSTALL`` in the current directory. + +Downloading Released Software +----------------------------- + +Released versions of the project's software may also be downloaded +from SourceForge's `file release system`_. + +.. _file release system: http://sourceforge.net/projects/elftoolchain/files/ + +Copyright and License +--------------------- + +This code is copyright its authors, and is distributed under the `BSD +License`_. + +.. _BSD License: http://www.opensource.org/licenses/bsd-license.php + + +Developer Community +------------------- + +The project's developers may be contacted using the mailing list: +````. + + +Reporting Bugs +-------------- + +Please use our `bug tracker`_ for viewing existing bug reports and +for submitting new bug reports. + +.. _`bug tracker`: https://sourceforge.net/p/elftoolchain/tickets/ + + +Additional Information +---------------------- + +Additional information about the project may be found on the `project +website`_. + +.. _project website: http://elftoolchain.sourceforge.net/ + +.. $Id: README.rst 3924 2021-02-26 09:02:10Z jkoshy $ + +.. Local Variables: +.. mode: rst +.. End: diff --git a/contrib/elftoolchain/RELEASE-NOTES b/contrib/elftoolchain/RELEASE-NOTES new file mode 100644 index 0000000000..0aa1c3d266 --- /dev/null +++ b/contrib/elftoolchain/RELEASE-NOTES @@ -0,0 +1,206 @@ +.. $Id: RELEASE-NOTES 3353 2016-01-18 21:50:13Z jkoshy $ + +.. This file contains a template for use when writing release notes. +.. It needs to be updated with release-specific content prior to +.. cutting a release. RST comments (such as this one) also need to be +.. removed prior to the release. + +.. The tokens '%.*%' need be replaced with actual content. + +Release Notes for Elftoolchain Software Version %.%.% +===================================================== + +About The Project +----------------- + +The `Elftoolchain project`_ develops BSD-licensed implementations of +essential compilation tools and libraries for handling ELF based program +objects. + +About The Release +----------------- + +.. Describe the rationale for the release (e.g. new features, +.. significant bug fixes, etc.). + +Libraries and Utilities +~~~~~~~~~~~~~~~~~~~~~~~ + +This release comprises the following libraries and utilities. + + ================= ========================================== + **Name** **Description** + ================= ========================================== + **ar** Archive manager. + **addr2line** Debug tool. + **brandelf** Manage the ELF brand on executables. + **c++filt** Translate encoded symbols. + **elfcopy** Copy and translate between object formats. + **elfdump** Diagnostic tool. + **findtextrel** Find undesired text relocations. + **libdwarf** DWARF access library. + **libelf** ELF access library. + **mcs** Manage comment sections. + **nm** List symbols in an ELF object. + **ranlib** Add archive symbol tables to an archive. + **readelf** Display ELF information. + **size** List object sizes. + **strings** Extract printable strings. + **strip** Discard information from ELF objects. + ================= ========================================== + +Documentation +~~~~~~~~~~~~~ + +Each public API and invocable utility has a reference manual entry. +We currently offer %NENTRIES% manual entries, documented in %NFILES% +manual pages. + +Additionally, this release contains the following documentation: + + ================= ========================================== + **Name** **Description** + ================= ========================================== + libelf-by-example A tutorial introduction to **libelf**. + ================= ========================================== + +Test Suites +~~~~~~~~~~~ + +The release contains the following test suites: + + ================= ========================================== + **Name** **Description** + ================= ========================================== + ar Test the **ar** utility. + elfcopy Test the **elfcopy** utility. + elfdump Test the **elfdump** utility. + libdwarf Test the **libdwarf** library. + libelf Test the **libelf** library. + nm Test the **nm** utility. + ================= ========================================== + + +System Requirements +------------------- + +.. Hardware and software requirements for using this software. + +This software is designed to run on Unix(TM)-like operating systems +such as the BSD-family of operating systems and GNU/Linux. + +This release has been built and tested on the following operating +systems: + + ==================== =========== =========================== + **Operating System** **Version** **Supported Architectures** + -------------------- ----------- --------------------------- + `DragonFly BSD`_ 2.10.1 i386 + FreeBSD_ 10.2 amd64 & i386 + Minix_ 3.2.0 i386 + NetBSD_ 7.0 i386 + OpenBSD_ v5.0 i386 + Ubuntu_ GNU/Linux 14.04LTS x86_64 + ==================== =========== =========================== + + +Installation and Upgrades +========================= + +Installation +------------ + +Instructions for building and installing this software from source are +described in the file "INSTALL". + +Upgrading +--------- + +.. Special notes about upgrading this software from a prior release. +.. For example, if we introduce any backwards-incompatible behaviour, +.. or if we deprecate existing behaviour. + + +Release Information +=================== + +Changes in this release +----------------------- + +.. A list of significant changes in the release. + +Outstanding Issues +------------------ + +.. Problems discovered when testing the release. + +Known Limitations +----------------- + +.. Known limitations. + +Test Statistics +--------------- + +The test summary for this release is presented below: + + ========= ========= ================ =============== ================ =================== + **Suite** **Tests** **DragonFlyBSD** **FreeBSD** **NetBSD** **Ubuntu 10.04LTS** + ========= ========= ================ =============== ================ =================== + ar + elfcopy + elfdump + libdwarf + libelf + nm + ========= ========= ================ =============== ================ =================== + +Key: + + :P: + Test successes. + :F: + Test failures. + :U: + Unresolved tests. + +Notes +~~~~~ + +More Information +================ + +The project's website is at http://elftoolchain.sourceforge.net/. + +Developer Community +------------------- + +The project's developers may be contacted using the mailing list: +````. + +Reporting Bugs +-------------- + +Please use our `Trac instance`_ for viewing existing bug reports and +for submitting new bug reports. + + +Copyright and License +===================== + +This software is copyright its authors, and is distributed under the +`BSD License`_. + +.. _BSD License: http://www.opensource.org/licenses/bsd-license.php +.. _DragonFly BSD: http://www.dragonflybsd.org/ +.. _Elftoolchain project: http://elftoolchain.sourceforge.net/ +.. _FreeBSD: http://www.freebsd.org/ +.. _Minix: http://www.minix3.org/ +.. _NetBSD: http://www.netbsd.org/ +.. _OpenBSD: http://www.openbsd.org/ +.. _`Trac instance`: http://sourceforge.net/apps/trac/elftoolchain/report +.. _Ubuntu: http://www.ubuntu.com/ + +.. Local Variables: +.. mode: rst +.. End: diff --git a/contrib/elftoolchain/addr2line/Makefile b/contrib/elftoolchain/addr2line/Makefile new file mode 100644 index 0000000000..e388bc0a6e --- /dev/null +++ b/contrib/elftoolchain/addr2line/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile 2066 2011-10-26 15:40:28Z jkoshy $ + +TOP= .. + +PROG= addr2line +SRCS= addr2line.c + +WARNS?= 6 + +DPADD= ${LIBELF} ${LIBELFTC} ${LIBDWARF} +LDADD= -lelftc -ldwarf -lelf + +MAN1= addr2line.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/addr2line/addr2line.1 b/contrib/elftoolchain/addr2line/addr2line.1 new file mode 100644 index 0000000000..f1b01954b3 --- /dev/null +++ b/contrib/elftoolchain/addr2line/addr2line.1 @@ -0,0 +1,182 @@ +.\" Copyright (c) 2009,2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: addr2line.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd November 30, 2015 +.Dt ADDR2LINE 1 +.Os +.Sh NAME +.Nm addr2line +.Nd translate program addresses to source file names and line numbers +.Sh SYNOPSIS +.Nm +.Op Fl a | Fl -addresses +.Op Fl b Ar target | Fl -target Ns = Ns Ar target +.Op Fl e Ar pathname | Fl -exe Ns = Ns Ar pathname +.Op Fl f | Fl -functions +.Op Fl i | Fl -inlines +.Op Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname +.Op Fl p | Fl -pretty-print +.Op Fl s | Fl -basename +.Op Fl C | Fl -demangle +.Op Fl H | Fl -help +.Op Fl V | Fl -version +.Op Ar hexaddress Ns ... +.Sh DESCRIPTION +The +.Nm +utility translates program addresses specified by the command line +arguments +.Ar hexaddress +to their corresponding source file names and line numbers. +If no arguments are given to +.Nm , +it will read these addresses from standard input. +.Pp +Program addresses specified by arguments +.Ar hexaddress +are encoded using the conventions accepted by +.Xr strtoull 3 . +.Pp +By default, +.Nm +will use the executable +.Dq Pa a.out . +The +.Fl e +option may be used to specified a different ELF object. +.Pp +The +.Nm +utility recognizes the following options: +.Bl -tag -width indent +.It Fl a | Fl -addresses +Display the address prior to the line number information. +.It Fl b Ar target | Fl -target Ns = Ns Ar target +This option is recognized by +.Nm +but is ignored. +It is supported for compatibility with GNU binutils. +.It Fl e Ar pathname | Fl -exe Ns = Ns Ar pathname +Use the ELF object specified by argument +.Ar pathname +to translate addresses. +If this option is not specified, +.Nm +will use the file +.Dq Pa a.out . +.It Fl f | Fl -functions +Display function names in addition to file and line number information. +.It Fl i | Fl -inlines +If the address specified belongs to an inlined function, also display the line +number information for its caller, recursively until the first non-inlined +caller. +.It Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname +The values specified by arguments +.Ar hexaddress +are to be treated as offsets into the section named +.Ar sectionname . +.It Fl p | -pretty-print +Display the line number information on one line, in human readable manner. +.It Fl s | -basename +Display only the base name for each file name. +.It Fl C | Fl -demangle +Demangle C++ names. +.It Fl H | Fl -help +Print a help message. +.It Fl V | Fl -version +Print a version identifier and exit. +.El +.Sh OUTPUT FORMAT +If the +.Fl f +option was not specified, +.Nm +will print the file name and line number for each address specified +on a separate line. +.Pp +If the +.Fl f +option was specified, +.Nm +will print a line containing the name of the function corresponding +to program address +.Ar hexaddress , +followed by a line with the file name and line number. +.Pp +If the +.Fl p +option was specified, +.Nm +will print line number information and function name on one line in +human readable manner. If the +.Fl i +option was also specified, +.Nm +will print the caller function information prefixed with +.Dq (inlined by) . +.Pp +The +.Nm +utility prints the file name and line number using the format +.Dq FILENAME:LINENUMBER . +.Pp +If a file or function name could not be determined, +.Nm +will print a question mark in their place. +If the line number could not be determined, +.Nm +will print a zero in its place. +.Sh EXAMPLES +To map address 080483c4 in the default executable +.Pa a.out +to a source file name and line number use: +.D1 "% addr2line 080483c4" +.Pp +To map address 080483c4 in executable +.Pa helloworld , +use: +.D1 "% addr2line -e helloworld 080483c4" +.Pp +To have +.Nm +act as a filter reading addresses from its standard input use: +.D1 "% addr2line" +.Pp +To print the function name corresponding to an address in addition to +its source file and line number use: +.D1 "% addr2line -f 080483c4" +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr nm 1 , +.Xr elfdump 1 , +.Xr elfcopy 1 , +.Xr strtoull 3 +.Sh AUTHORS +The +.Nm +utility was written by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/addr2line/addr2line.c b/contrib/elftoolchain/addr2line/addr2line.c new file mode 100644 index 0000000000..37c1e581e2 --- /dev/null +++ b/contrib/elftoolchain/addr2line/addr2line.c @@ -0,0 +1,738 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uthash.h" +#include "_elftc.h" + +ELFTC_VCSID("$Id: addr2line.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +struct Func { + char *name; + Dwarf_Unsigned lopc; + Dwarf_Unsigned hipc; + Dwarf_Unsigned call_file; + Dwarf_Unsigned call_line; + Dwarf_Ranges *ranges; + Dwarf_Signed ranges_cnt; + struct Func *inlined_caller; + STAILQ_ENTRY(Func) next; +}; + +struct CU { + Dwarf_Off off; + Dwarf_Unsigned lopc; + Dwarf_Unsigned hipc; + char **srcfiles; + Dwarf_Signed nsrcfiles; + STAILQ_HEAD(, Func) funclist; + UT_hash_handle hh; +}; + +static struct option longopts[] = { + {"addresses", no_argument, NULL, 'a'}, + {"target" , required_argument, NULL, 'b'}, + {"demangle", no_argument, NULL, 'C'}, + {"exe", required_argument, NULL, 'e'}, + {"functions", no_argument, NULL, 'f'}, + {"inlines", no_argument, NULL, 'i'}, + {"section", required_argument, NULL, 'j'}, + {"pretty-print", no_argument, NULL, 'p'}, + {"basename", no_argument, NULL, 's'}, + {"help", no_argument, NULL, 'H'}, + {"version", no_argument, NULL, 'V'}, + {NULL, 0, NULL, 0} +}; +static int demangle, func, base, inlines, print_addr, pretty_print; +static char unknown[] = { '?', '?', '\0' }; +static Dwarf_Addr section_base; +static struct CU *culist; + +#define USAGE_MESSAGE "\ +Usage: %s [options] hexaddress...\n\ + Map program addresses to source file names and line numbers.\n\n\ + Options:\n\ + -a | --addresses Display address prior to line number info.\n\ + -b TGT | --target=TGT (Accepted but ignored).\n\ + -e EXE | --exe=EXE Use program \"EXE\" to translate addresses.\n\ + -f | --functions Display function names.\n\ + -i | --inlines Display caller info for inlined functions.\n\ + -j NAME | --section=NAME Values are offsets into section \"NAME\".\n\ + -p | --pretty-print Display line number info and function name\n\ + in human readable manner.\n\ + -s | --basename Only show the base name for each file name.\n\ + -C | --demangle Demangle C++ names.\n\ + -H | --help Print a help message.\n\ + -V | --version Print a version identifier and exit.\n" + +static void +usage(int exit_code) +{ + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +version(void) +{ + + fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(0); +} + +/* + * Handle DWARF 4 'offset from' DW_AT_high_pc. Although we don't + * fully support DWARF 4, some compilers (like FreeBSD Clang 3.5.1) + * generate DW_AT_high_pc as an offset from DW_AT_low_pc. + * + * "If the value of the DW_AT_high_pc is of class address, it is the + * relocated address of the first location past the last instruction + * associated with the entity; if it is of class constant, the value + * is an unsigned integer offset which when added to the low PC gives + * the address of the first location past the last instruction + * associated with the entity." + * + * DWARF4 spec, section 2.17.2. + */ +static int +handle_high_pc(Dwarf_Die die, Dwarf_Unsigned lopc, Dwarf_Unsigned *hipc) +{ + Dwarf_Error de; + Dwarf_Half form; + Dwarf_Attribute at; + int ret; + + ret = dwarf_attr(die, DW_AT_high_pc, &at, &de); + if (ret == DW_DLV_ERROR) { + warnx("dwarf_attr failed: %s", dwarf_errmsg(de)); + return (ret); + } + ret = dwarf_whatform(at, &form, &de); + if (ret == DW_DLV_ERROR) { + warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); + return (ret); + } + if (dwarf_get_form_class(2, 0, 0, form) == DW_FORM_CLASS_CONSTANT) + *hipc += lopc; + + return (DW_DLV_OK); +} + +static struct Func * +search_func(struct CU *cu, Dwarf_Unsigned addr) +{ + struct Func *f, *f0; + Dwarf_Unsigned lopc, hipc, addr_base; + int i; + + f0 = NULL; + + STAILQ_FOREACH(f, &cu->funclist, next) { + if (f->ranges != NULL) { + addr_base = 0; + for (i = 0; i < f->ranges_cnt; i++) { + if (f->ranges[i].dwr_type == DW_RANGES_END) + break; + if (f->ranges[i].dwr_type == + DW_RANGES_ADDRESS_SELECTION) { + addr_base = f->ranges[i].dwr_addr2; + continue; + } + + /* DW_RANGES_ENTRY */ + lopc = f->ranges[i].dwr_addr1 + addr_base; + hipc = f->ranges[i].dwr_addr2 + addr_base; + if (addr >= lopc && addr < hipc) { + if (f0 == NULL || + (lopc >= f0->lopc && + hipc <= f0->hipc)) { + f0 = f; + f0->lopc = lopc; + f0->hipc = hipc; + break; + } + } + } + } else if (addr >= f->lopc && addr < f->hipc) { + if (f0 == NULL || + (f->lopc >= f0->lopc && f->hipc <= f0->hipc)) + f0 = f; + } + } + + return (f0); +} + +static void +collect_func(Dwarf_Debug dbg, Dwarf_Die die, struct Func *parent, struct CU *cu) +{ + Dwarf_Die ret_die, abst_die, spec_die; + Dwarf_Error de; + Dwarf_Half tag; + Dwarf_Unsigned lopc, hipc, ranges_off; + Dwarf_Signed ranges_cnt; + Dwarf_Off ref; + Dwarf_Attribute abst_at, spec_at; + Dwarf_Ranges *ranges; + const char *funcname; + struct Func *f; + int found_ranges, ret; + + f = NULL; + abst_die = spec_die = NULL; + + if (dwarf_tag(die, &tag, &de)) { + warnx("dwarf_tag: %s", dwarf_errmsg(de)); + goto cont_search; + } + if (tag == DW_TAG_subprogram || tag == DW_TAG_entry_point || + tag == DW_TAG_inlined_subroutine) { + /* + * Function address range can be specified by either + * a DW_AT_ranges attribute which points to a range list or + * by a pair of DW_AT_low_pc and DW_AT_high_pc attributes. + */ + ranges = NULL; + ranges_cnt = 0; + found_ranges = 0; + if (dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off, + &de) == DW_DLV_OK && + dwarf_get_ranges(dbg, (Dwarf_Off) ranges_off, &ranges, + &ranges_cnt, NULL, &de) == DW_DLV_OK) { + if (ranges != NULL && ranges_cnt > 0) { + found_ranges = 1; + goto get_func_name; + } + } + + /* + * Search for DW_AT_low_pc/DW_AT_high_pc if ranges pointer + * not found. + */ + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) || + dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) + goto cont_search; + if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK) + goto cont_search; + + get_func_name: + /* + * Most common case the function name is stored in DW_AT_name + * attribute. + */ + if (dwarf_attrval_string(die, DW_AT_name, &funcname, &de) == + DW_DLV_OK) + goto add_func; + + /* + * For inlined function, the actual name is probably in the DIE + * referenced by DW_AT_abstract_origin. (if present) + */ + if (dwarf_attr(die, DW_AT_abstract_origin, &abst_at, &de) == + DW_DLV_OK && + dwarf_global_formref(abst_at, &ref, &de) == DW_DLV_OK && + dwarf_offdie(dbg, ref, &abst_die, &de) == DW_DLV_OK && + dwarf_attrval_string(abst_die, DW_AT_name, &funcname, + &de) == DW_DLV_OK) + goto add_func; + + /* + * If DW_AT_name is not present, but DW_AT_specification is + * present, then probably the actual name is in the DIE + * referenced by DW_AT_specification. + */ + if (dwarf_attr(die, DW_AT_specification, &spec_at, &de) == + DW_DLV_OK && + dwarf_global_formref(spec_at, &ref, &de) == DW_DLV_OK && + dwarf_offdie(dbg, ref, &spec_die, &de) == DW_DLV_OK && + dwarf_attrval_string(spec_die, DW_AT_name, &funcname, + &de) == DW_DLV_OK) + goto add_func; + + /* Skip if no name associated with this DIE. */ + goto cont_search; + + add_func: + if ((f = calloc(1, sizeof(*f))) == NULL) + err(EXIT_FAILURE, "calloc"); + if ((f->name = strdup(funcname)) == NULL) + err(EXIT_FAILURE, "strdup"); + if (found_ranges) { + f->ranges = ranges; + f->ranges_cnt = ranges_cnt; + } else { + f->lopc = lopc; + f->hipc = hipc; + } + if (tag == DW_TAG_inlined_subroutine) { + f->inlined_caller = parent; + dwarf_attrval_unsigned(die, DW_AT_call_file, + &f->call_file, &de); + dwarf_attrval_unsigned(die, DW_AT_call_line, + &f->call_line, &de); + } + STAILQ_INSERT_TAIL(&cu->funclist, f, next); + } + +cont_search: + + /* Search children. */ + ret = dwarf_child(die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_child: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) { + if (f != NULL) + collect_func(dbg, ret_die, f, cu); + else + collect_func(dbg, ret_die, parent, cu); + } + + /* Search sibling. */ + ret = dwarf_siblingof(dbg, die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + collect_func(dbg, ret_die, parent, cu); + + /* Cleanup */ + dwarf_dealloc(dbg, die, DW_DLA_DIE); + + if (abst_die != NULL) + dwarf_dealloc(dbg, abst_die, DW_DLA_DIE); + + if (spec_die != NULL) + dwarf_dealloc(dbg, spec_die, DW_DLA_DIE); +} + +static void +print_inlines(struct CU *cu, struct Func *f, Dwarf_Unsigned call_file, + Dwarf_Unsigned call_line) +{ + char demangled[1024]; + char *file; + + if (call_file > 0 && (Dwarf_Signed) call_file <= cu->nsrcfiles) + file = cu->srcfiles[call_file - 1]; + else + file = unknown; + + if (pretty_print) + printf(" (inlined by) "); + + if (func) { + if (demangle && !elftc_demangle(f->name, demangled, + sizeof(demangled), 0)) { + if (pretty_print) + printf("%s at ", demangled); + else + printf("%s\n", demangled); + } else { + if (pretty_print) + printf("%s at ", f->name); + else + printf("%s\n", f->name); + } + } + (void) printf("%s:%ju\n", base ? basename(file) : file, + (uintmax_t) call_line); + + if (f->inlined_caller != NULL) + print_inlines(cu, f->inlined_caller, f->call_file, + f->call_line); +} + +static void +translate(Dwarf_Debug dbg, Elf *e, const char* addrstr) +{ + Dwarf_Die die, ret_die; + Dwarf_Line *lbuf; + Dwarf_Error de; + Dwarf_Half tag; + Dwarf_Unsigned lopc, hipc, addr, lineno, plineno; + Dwarf_Signed lcount; + Dwarf_Addr lineaddr, plineaddr; + Dwarf_Off off; + struct CU *cu; + struct Func *f; + const char *funcname; + char *file, *file0, *pfile; + char demangled[1024]; + int ec, i, ret; + + addr = strtoull(addrstr, NULL, 16); + addr += section_base; + lineno = 0; + file = unknown; + cu = NULL; + die = NULL; + + while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de)) == DW_DLV_OK) { + die = NULL; + while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) { + if (die != NULL) + dwarf_dealloc(dbg, die, DW_DLA_DIE); + die = ret_die; + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + goto next_cu; + } + + /* XXX: What about DW_TAG_partial_unit? */ + if (tag == DW_TAG_compile_unit) + break; + } + if (ret_die == NULL) { + warnx("could not find DW_TAG_compile_unit die"); + goto next_cu; + } + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) == + DW_DLV_OK) { + if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, + &de) == DW_DLV_OK) { + /* + * Check if the address falls into the PC + * range of this CU. + */ + if (handle_high_pc(die, lopc, &hipc) != + DW_DLV_OK) + goto out; + } else { + /* Assume ~0ULL if DW_AT_high_pc not present */ + hipc = ~0ULL; + } + + /* + * Record the CU in the hash table for faster lookup + * later. + */ + if (dwarf_dieoffset(die, &off, &de) != DW_DLV_OK) { + warnx("dwarf_dieoffset failed: %s", + dwarf_errmsg(de)); + goto out; + } + HASH_FIND(hh, culist, &off, sizeof(off), cu); + if (cu == NULL) { + if ((cu = calloc(1, sizeof(*cu))) == NULL) + err(EXIT_FAILURE, "calloc"); + cu->off = off; + cu->lopc = lopc; + cu->hipc = hipc; + STAILQ_INIT(&cu->funclist); + HASH_ADD(hh, culist, off, sizeof(off), cu); + } + + if (addr >= lopc && addr < hipc) + break; + } + + next_cu: + if (die != NULL) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + die = NULL; + } + } + + if (ret != DW_DLV_OK || die == NULL) + goto out; + + switch (dwarf_srclines(die, &lbuf, &lcount, &de)) { + case DW_DLV_OK: + break; + case DW_DLV_NO_ENTRY: + /* If a CU lacks debug info, just skip it. */ + goto out; + default: + warnx("dwarf_srclines: %s", dwarf_errmsg(de)); + goto out; + } + + plineaddr = ~0ULL; + plineno = 0; + pfile = unknown; + for (i = 0; i < lcount; i++) { + if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) { + warnx("dwarf_lineaddr: %s", dwarf_errmsg(de)); + goto out; + } + if (dwarf_lineno(lbuf[i], &lineno, &de)) { + warnx("dwarf_lineno: %s", dwarf_errmsg(de)); + goto out; + } + if (dwarf_linesrc(lbuf[i], &file0, &de)) { + warnx("dwarf_linesrc: %s", dwarf_errmsg(de)); + } else + file = file0; + if (addr == lineaddr) + goto out; + else if (addr < lineaddr && addr > plineaddr) { + lineno = plineno; + file = pfile; + goto out; + } + plineaddr = lineaddr; + plineno = lineno; + pfile = file; + } + +out: + f = NULL; + funcname = NULL; + if (ret == DW_DLV_OK && (func || inlines) && cu != NULL) { + if (cu->srcfiles == NULL) + if (dwarf_srcfiles(die, &cu->srcfiles, &cu->nsrcfiles, + &de)) + warnx("dwarf_srcfiles: %s", dwarf_errmsg(de)); + if (STAILQ_EMPTY(&cu->funclist)) { + collect_func(dbg, die, NULL, cu); + die = NULL; + } + f = search_func(cu, addr); + if (f != NULL) + funcname = f->name; + } + + if (print_addr) { + if ((ec = gelf_getclass(e)) == ELFCLASSNONE) { + warnx("gelf_getclass failed: %s", elf_errmsg(-1)); + ec = ELFCLASS64; + } + if (ec == ELFCLASS32) { + if (pretty_print) + printf("0x%08jx: ", (uintmax_t) addr); + else + printf("0x%08jx\n", (uintmax_t) addr); + } else { + if (pretty_print) + printf("0x%016jx: ", (uintmax_t) addr); + else + printf("0x%016jx\n", (uintmax_t) addr); + } + } + + if (func) { + if (funcname == NULL) + funcname = unknown; + if (demangle && !elftc_demangle(funcname, demangled, + sizeof(demangled), 0)) { + if (pretty_print) + printf("%s at ", demangled); + else + printf("%s\n", demangled); + } else { + if (pretty_print) + printf("%s at ", funcname); + else + printf("%s\n", funcname); + } + } + + (void) printf("%s:%ju\n", base ? basename(file) : file, + (uintmax_t) lineno); + + if (ret == DW_DLV_OK && inlines && cu != NULL && + cu->srcfiles != NULL && f != NULL && f->inlined_caller != NULL) + print_inlines(cu, f->inlined_caller, f->call_file, + f->call_line); + + if (die != NULL) + dwarf_dealloc(dbg, die, DW_DLA_DIE); + + /* + * Reset internal CU pointer, so we will start from the first CU + * next round. + */ + while (ret != DW_DLV_NO_ENTRY) { + if (ret == DW_DLV_ERROR) + errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", + dwarf_errmsg(de)); + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de); + } +} + +static void +find_section_base(const char *exe, Elf *e, const char *section) +{ + Dwarf_Addr off; + Elf_Scn *scn; + GElf_Ehdr eh; + GElf_Shdr sh; + size_t shstrndx; + int elferr; + const char *name; + + if (gelf_getehdr(e, &eh) != &eh) { + warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); + return; + } + + if (!elf_getshstrndx(e, &shstrndx)) { + warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); + return; + } + + (void) elf_errno(); + off = 0; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + continue; + } + if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL) + goto next; + if (!strcmp(section, name)) { + if (eh.e_type == ET_EXEC || eh.e_type == ET_DYN) { + /* + * For executables, section base is the virtual + * address of the specified section. + */ + section_base = sh.sh_addr; + } else if (eh.e_type == ET_REL) { + /* + * For relocatables, section base is the + * relative offset of the specified section + * to the start of the first section. + */ + section_base = off; + } else + warnx("unknown e_type %u", eh.e_type); + return; + } + next: + off += sh.sh_size; + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + errx(EXIT_FAILURE, "%s: cannot find section %s", exe, section); +} + +int +main(int argc, char **argv) +{ + Elf *e; + Dwarf_Debug dbg; + Dwarf_Error de; + const char *exe, *section; + char line[1024]; + int fd, i, opt; + + exe = NULL; + section = NULL; + while ((opt = getopt_long(argc, argv, "ab:Ce:fij:psHV", longopts, + NULL)) != -1) { + switch (opt) { + case 'a': + print_addr = 1; + break; + case 'b': + /* ignored */ + break; + case 'C': + demangle = 1; + break; + case 'e': + exe = optarg; + break; + case 'f': + func = 1; + break; + case 'i': + inlines = 1; + break; + case 'j': + section = optarg; + break; + case 'p': + pretty_print = 1; + break; + case 's': + base = 1; + break; + case 'H': + usage(EX_OK); + break; + case 'V': + version(); + break; + default: + usage(EX_USAGE); + break; + } + } + + argv += optind; + argc -= optind; + + if (exe == NULL) + exe = "a.out"; + + if ((fd = open(exe, O_RDONLY)) < 0) + err(EXIT_FAILURE, "%s", exe); + + if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de)) + errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(de)); + + if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de)); + + if (section) + find_section_base(exe, e, section); + else + section_base = 0; + + if (argc > 0) + for (i = 0; i < argc; i++) + translate(dbg, e, argv[i]); + else { + setvbuf(stdout, NULL, _IOLBF, 0); + while (fgets(line, sizeof(line), stdin) != NULL) + translate(dbg, e, line); + } + + dwarf_finish(dbg, &de); + + (void) elf_end(e); + + exit(0); +} diff --git a/contrib/elftoolchain/addr2line/os.NetBSD.mk b/contrib/elftoolchain/addr2line/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/addr2line/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/ar/Makefile b/contrib/elftoolchain/ar/Makefile new file mode 100644 index 0000000000..e561126b74 --- /dev/null +++ b/contrib/elftoolchain/ar/Makefile @@ -0,0 +1,39 @@ +# $Id: Makefile 4045 2024-07-08 12:36:29Z jkoshy $ + +TOP= .. + +PROG= ar +SRCS= ar.c read.c util.c write.c +LSRC= acplex.l +YSRC= acpyacc.y + +WARNS?= 5 + +DPADD= ${LIBARCHIVE} ${LIBELFTC} ${LIBELF} ${LIBZ} +LDADD= -larchive -lelftc -lelf -lz + +CFLAGS+=-I. -I${.CURDIR} + +LINKS= ${BINDIR}/ar ${BINDIR}/ranlib + +EXTRA_TARGETS= ranlib + +CLEANFILES+= ${EXTRA_TARGETS} + +MAN= ar.1 ranlib.1 ar.5 + +TEST_FRAMEWORK= custom + +all: ${EXTRA_TARGETS} + +${EXTRA_TARGETS}: ${PROG} + ln -s ${PROG} ${.TARGET} + +.include "${TOP}/mk/elftoolchain.prog.mk" + +.if ${OS_HOST} == "OpenBSD" +CFLAGS+= -I/usr/local/include +LDFLAGS+= -L/usr/local/lib +.elif ${OS_HOST} == "DragonFly" +LDADD+= -lbz2 +.endif diff --git a/contrib/elftoolchain/ar/acplex.l b/contrib/elftoolchain/ar/acplex.l new file mode 100644 index 0000000000..6b50fb3b19 --- /dev/null +++ b/contrib/elftoolchain/ar/acplex.l @@ -0,0 +1,83 @@ +%{ +/*- + * Copyright (c) 2008 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: acplex.l 3174 2015-03-27 17:13:41Z emaste $"); + +#include "acpyacc.h" + +#define YY_NO_UNPUT +#if !defined(ELFTC_BROKEN_YY_NO_INPUT) +#define YY_NO_INPUT +#endif + +int lineno = 1; + +int yylex(void); + +%} + +%option nounput +%option noyywrap + +%% + +ADDLIB|addlib { return (ADDLIB); } +ADDMOD|addmod { return (ADDMOD); } +CLEAR|clear { return (CLEAR); } +CREATE|create { return (CREATE); } +DELETE|delete { return (DELETE); } +DIRECTORY|directory { return (DIRECTORY); } +END|end { return (END); } +EXTRACT|extract { return (EXTRACT); } +LIST|list { return (LIST); } +OPEN|open { return (OPEN); } +REPLACE|replace { return (REPLACE); } +VERBOSE|verbose { return (VERBOSE); } +SAVE|save { return (SAVE); } +"(" { return (LP); } +")" { return (RP); } +"," { return (COMMA); } + +[-_A-Za-z0-9/:$.\\]+ { + yylval.str = strdup(yytext); + if (yylval.str == NULL) + err(EXIT_FAILURE, "strdup failed"); + return (FNAME); +} + +[ \t] /* whitespace */ +"*".* /* comment */ +";".* /* comment */ +"+\n" { lineno++; /* '+' is line continuation char */ } +"\n" { lineno++; return (EOL); } diff --git a/contrib/elftoolchain/ar/acpyacc.y b/contrib/elftoolchain/ar/acpyacc.y new file mode 100644 index 0000000000..84f08e2393 --- /dev/null +++ b/contrib/elftoolchain/ar/acpyacc.y @@ -0,0 +1,658 @@ +%{ +/*- + * Copyright (c) 2008 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libelftc.h" + +#include "ar.h" + +ELFTC_VCSID("$Id"); + + +#define TEMPLATE "arscp.XXXXXXXX" + +struct list { + char *str; + struct list *next; +}; + + +extern int yylex(void); +extern int yyparse(void); + +static void yyerror(const char *); +static void arscp_addlib(char *archive, struct list *list); +static void arscp_addmod(struct list *list); +static void arscp_clear(void); +static void arscp_create(char *in, char *out); +static void arscp_delete(struct list *list); +static void arscp_dir(char *archive, struct list *list, char *rlt); +static void arscp_end(int eval); +static void arscp_extract(struct list *list); +static void arscp_free_argv(void); +static void arscp_free_mlist(struct list *list); +static void arscp_list(void); +static struct list *arscp_mlist(struct list *list, char *str); +static void arscp_mlist2argv(struct list *list); +static int arscp_mlist_len(struct list *list); +static void arscp_open(char *fname); +static void arscp_prompt(void); +static void arscp_replace(struct list *list); +static void arscp_save(void); +static int arscp_target_exist(void); + +extern int lineno; + +static struct bsdar *bsdar; +static char *target; +static char *tmpac; +static int interactive; +static int verbose; + +%} + +%token ADDLIB +%token ADDMOD +%token CLEAR +%token CREATE +%token DELETE +%token DIRECTORY +%token END +%token EXTRACT +%token LIST +%token OPEN +%token REPLACE +%token VERBOSE +%token SAVE +%token LP +%token RP +%token COMMA +%token EOL +%token FNAME +%type mod_list + +%union { + char *str; + struct list *list; +} + +%% + +begin + : { arscp_prompt(); } ar_script + ; + +ar_script + : cmd_list + | + ; + +mod_list + : FNAME { $$ = arscp_mlist(NULL, $1); } + | mod_list separator FNAME { $$ = arscp_mlist($1, $3); } + ; + +separator + : COMMA + | + ; + +cmd_list + : rawcmd + | cmd_list rawcmd + ; + +rawcmd + : cmd EOL { arscp_prompt(); } + ; + +cmd + : addlib_cmd + | addmod_cmd + | clear_cmd + | create_cmd + | delete_cmd + | directory_cmd + | end_cmd + | extract_cmd + | list_cmd + | open_cmd + | replace_cmd + | verbose_cmd + | save_cmd + | invalid_cmd + | empty_cmd + | error + ; + +addlib_cmd + : ADDLIB FNAME LP mod_list RP { arscp_addlib($2, $4); } + | ADDLIB FNAME { arscp_addlib($2, NULL); } + ; + +addmod_cmd + : ADDMOD mod_list { arscp_addmod($2); } + ; + +clear_cmd + : CLEAR { arscp_clear(); } + ; + +create_cmd + : CREATE FNAME { arscp_create(NULL, $2); } + ; + +delete_cmd + : DELETE mod_list { arscp_delete($2); } + ; + +directory_cmd + : DIRECTORY FNAME { arscp_dir($2, NULL, NULL); } + | DIRECTORY FNAME LP mod_list RP { arscp_dir($2, $4, NULL); } + | DIRECTORY FNAME LP mod_list RP FNAME { arscp_dir($2, $4, $6); } + ; + +end_cmd + : END { arscp_end(EXIT_SUCCESS); } + ; + +extract_cmd + : EXTRACT mod_list { arscp_extract($2); } + ; + +list_cmd + : LIST { arscp_list(); } + ; + +open_cmd + : OPEN FNAME { arscp_open($2); } + ; + +replace_cmd + : REPLACE mod_list { arscp_replace($2); } + ; + +save_cmd + : SAVE { arscp_save(); } + ; + +verbose_cmd + : VERBOSE { verbose = !verbose; } + ; + +empty_cmd + : + ; + +invalid_cmd + : FNAME { yyerror(NULL); } + ; + +%% + +/* ARGSUSED */ +static void +yyerror(const char *s) +{ + + (void) s; + printf("Syntax error in archive script, line %d\n", lineno); +} + +/* + * The arscp_open() function will first open an archive and check its + * validity. If the archive format is valid, it will call + * arscp_create() to create a temporary copy of the archive. + */ +static void +arscp_open(char *fname) +{ + struct archive *a; + struct archive_entry *entry; + int r; + + if ((a = archive_read_new()) == NULL) + bsdar_errc(bsdar, 0, "archive_read_new failed"); + archive_read_support_format_ar(a); + AC(archive_read_open_filename(a, fname, DEF_BLKSZ)); + if ((r = archive_read_next_header(a, &entry))) + bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); + AC(archive_read_close(a)); + ACV(archive_read_free(a)); + if (r != ARCHIVE_OK) + return; + arscp_create(fname, fname); +} + +/* + * Create an archive. + * + * If the parameter 'in' is NULL (the 'CREATE' command), a new empty + * archive will be created. If the parameter 'in' is not NULL (the + * 'OPEN' command), the resulting archive will be a modified version + * of the existing archive. + */ +static void +arscp_create(char *in, char *out) +{ + struct archive *a; + int ifd, ofd; + + /* Delete the previously created temporary archive, if any. */ + if (tmpac) { + if (unlink(tmpac) < 0) + bsdar_errc(bsdar, errno, "unlink failed"); + free(tmpac); + } + + tmpac = strdup(TEMPLATE); + if (tmpac == NULL) + bsdar_errc(bsdar, errno, "strdup failed"); + if ((ofd = mkstemp(tmpac)) < 0) + bsdar_errc(bsdar, errno, "mkstemp failed"); + + if (in) { + /* + * The 'OPEN' command creates a temporary copy of the + * input archive. + */ + if ((ifd = open(in, O_RDONLY)) < 0 || + elftc_copyfile(ifd, ofd) < 0) { + bsdar_warnc(bsdar, errno, "'OPEN' failed"); + (void) close(ofd); + if (ifd != -1) + (void) close(ifd); + return; + } + (void) close(ifd); + (void) close(ofd); + } else { + /* + * The 'CREATE' command creates an "empty" archive (an + * archive consisting only of the archive header). + */ + if ((a = archive_write_new()) == NULL) + bsdar_errc(bsdar, 0, "archive_write_new failed"); + archive_write_set_format_ar_svr4(a); + AC(archive_write_open_fd(a, ofd)); + AC(archive_write_close(a)); + ACV(archive_write_free(a)); + } + + /* Override the previous target, if any. */ + if (target) + free(target); + + target = out; + bsdar->filename = tmpac; +} + +/* + * Add all modules of an archive to the current archive. If the + * parameter 'list' is not NULL, only those modules specified by + * 'list' will be added. + */ +static void +arscp_addlib(char *archive, struct list *list) +{ + + if (!arscp_target_exist()) + return; + arscp_mlist2argv(list); + bsdar->addlib = archive; + ar_write_archive(bsdar, 'A'); + arscp_free_argv(); + arscp_free_mlist(list); +} + +/* + * Add modules to the current archive. + */ +static void +arscp_addmod(struct list *list) +{ + + if (!arscp_target_exist()) + return; + arscp_mlist2argv(list); + ar_write_archive(bsdar, 'q'); + arscp_free_argv(); + arscp_free_mlist(list); +} + +/* + * Delete modules from the current archive. + */ +static void +arscp_delete(struct list *list) +{ + + if (!arscp_target_exist()) + return; + arscp_mlist2argv(list); + ar_write_archive(bsdar, 'd'); + arscp_free_argv(); + arscp_free_mlist(list); +} + +/* + * Extract modules from the current archive. + */ +static void +arscp_extract(struct list *list) +{ + + if (!arscp_target_exist()) + return; + arscp_mlist2argv(list); + ar_read_archive(bsdar, 'x'); + arscp_free_argv(); + arscp_free_mlist(list); +} + +/* + * List the contents of an archive (simple mode). + */ +static void +arscp_list(void) +{ + + if (!arscp_target_exist()) + return; + bsdar->argc = 0; + bsdar->argv = NULL; + /* Always verbose. */ + bsdar->options |= AR_V; + ar_read_archive(bsdar, 't'); + bsdar->options &= ~AR_V; +} + +/* + * List the contents of an archive (advanced mode). + */ +static void +arscp_dir(char *archive, struct list *list, char *rlt) +{ + FILE *out; + + /* If rlt != NULL, redirect the output to it. */ + out = NULL; + if (rlt) { + out = bsdar->output; + if ((bsdar->output = fopen(rlt, "w")) == NULL) + bsdar_errc(bsdar, errno, "fopen %s failed", rlt); + } + + bsdar->filename = archive; + if (list) + arscp_mlist2argv(list); + else { + bsdar->argc = 0; + bsdar->argv = NULL; + } + if (verbose) + bsdar->options |= AR_V; + ar_read_archive(bsdar, 't'); + bsdar->options &= ~AR_V; + + if (rlt) { + if (fclose(bsdar->output) == EOF) + bsdar_errc(bsdar, errno, "fclose %s failed", rlt); + bsdar->output = out; + free(rlt); + } + free(archive); + bsdar->filename = tmpac; + arscp_free_argv(); + arscp_free_mlist(list); +} + + +/* + * Replace modules in the current archive. + */ +static void +arscp_replace(struct list *list) +{ + + if (!arscp_target_exist()) + return; + arscp_mlist2argv(list); + ar_write_archive(bsdar, 'r'); + arscp_free_argv(); + arscp_free_mlist(list); +} + +/* + * Rename the temporary archive to the target archive. + */ +static void +arscp_save(void) +{ + mode_t mask; + + if (target) { + if (rename(tmpac, target) < 0) + bsdar_errc(bsdar, errno, "rename failed"); + /* + * Because mkstemp() creates temporary files with mode + * 0600, we set target archive's mode as per the + * process umask. + */ + mask = umask(0); + umask(mask); + if (chmod(target, 0666 & ~mask) < 0) + bsdar_errc(bsdar, errno, "chmod failed"); + free(tmpac); + free(target); + tmpac = NULL; + target= NULL; + bsdar->filename = NULL; + } else + bsdar_warnc(bsdar, 0, "no open output archive"); +} + +/* + * Discard the contents of the current archive. This is achieved by + * invoking the 'CREATE' cmd on the current archive. + */ +static void +arscp_clear(void) +{ + char *new_target; + + if (target) { + new_target = strdup(target); + if (new_target == NULL) + bsdar_errc(bsdar, errno, "strdup failed"); + arscp_create(NULL, new_target); + } +} + +/* + * Quit ar(1). Note that the 'END' cmd will not 'SAVE' the current + * archive before exiting. + */ +static void +arscp_end(int eval) +{ + + if (target) + free(target); + if (tmpac) { + if (unlink(tmpac) == -1) + bsdar_errc(bsdar, errno, "unlink %s failed", tmpac); + free(tmpac); + } + + exit(eval); +} + +/* + * Check if a target was specified, i.e, whether an 'OPEN' or 'CREATE' + * had been issued by the user. + */ +static int +arscp_target_exist(void) +{ + + if (target) + return (1); + + bsdar_warnc(bsdar, 0, "no open output archive"); + return (0); +} + +/* + * Construct the list of modules. + */ +static struct list * +arscp_mlist(struct list *list, char *str) +{ + struct list *l; + + l = malloc(sizeof(*l)); + if (l == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + l->str = str; + l->next = list; + + return (l); +} + +/* + * Calculate the length of an mlist. + */ +static int +arscp_mlist_len(struct list *list) +{ + int len; + + for(len = 0; list; list = list->next) + len++; + + return (len); +} + +/* + * Free the space allocated for a module list. + */ +static void +arscp_free_mlist(struct list *list) +{ + struct list *l; + + /* Note: list->str was freed in arscp_free_argv(). */ + for(; list; list = l) { + l = list->next; + free(list); + } +} + +/* + * Convert a module list to an 'argv' array. + */ +static void +arscp_mlist2argv(struct list *list) +{ + char **argv; + int i, n; + + n = arscp_mlist_len(list); + argv = malloc(n * sizeof(*argv)); + if (argv == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + + /* Note that module names are stored in reverse order. */ + for(i = n - 1; i >= 0; i--, list = list->next) { + if (list == NULL) + bsdar_errc(bsdar, errno, "invalid mlist"); + argv[i] = list->str; + } + + bsdar->argc = n; + bsdar->argv = argv; +} + +/* + * Free the space allocated for an argv array and its elements. + */ +static void +arscp_free_argv(void) +{ + int i; + + for(i = 0; i < bsdar->argc; i++) + free(bsdar->argv[i]); + + free(bsdar->argv); +} + +/* + * Show a prompt if we are in interactive mode. + */ +static void +arscp_prompt(void) +{ + + if (interactive) { + printf("AR >"); + fflush(stdout); + } +} + +/* + * The main function implementing script mode. + */ +void +ar_mode_script(struct bsdar *ar) +{ + + bsdar = ar; + interactive = isatty(fileno(stdin)); + while(yyparse()) { + if (!interactive) + arscp_end(EXIT_FAILURE); + } + + /* Script ends without END */ + arscp_end(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/ar/ar.1 b/contrib/elftoolchain/ar/ar.1 new file mode 100644 index 0000000000..4b3c80811d --- /dev/null +++ b/contrib/elftoolchain/ar/ar.1 @@ -0,0 +1,627 @@ +.\" Copyright (c) 2007,2009-2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: ar.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd September 30, 2018 +.Dt AR 1 +.Os +.Sh NAME +.Nm ar +.Nd manage archives +.Sh SYNOPSIS +.Nm +.Fl d +.Op Fl f +.Op Fl j +.Op Fl T +.Op Fl v +.Op Fl z +.Ar archive +.Ar +.Nm +.Fl m +.Op Fl a Ar position-after +.Op Fl b Ar position-before +.Op Fl f +.Op Fl i Ar position-before +.Op Fl j +.Op Fl s | Fl S +.Op Fl T +.Op Fl z +.Ar archive +.Ar +.Nm +.Fl p +.Op Fl f +.Op Fl s +.Op Fl T +.Op Fl v +.Ar archive +.Op Ar +.Nm +.Fl q +.Op Fl c +.Op Fl D +.Op Fl f +.Op Fl F Ar flavor | Fl -flavor Ar flavor +.Op Fl s | Fl S +.Op Fl T +.Op Fl U +.Op Fl v +.Op Fl z +.Ar archive +.Ar +.Nm +.Fl r +.Op Fl a Ar position-after +.Op Fl b Ar position-before +.Op Fl c +.Op Fl D +.Op Fl f +.Op Fl F Ar flavor | Fl -flavor Ar flavor +.Op Fl i Ar position-before +.Op Fl j +.Op Fl s | Fl S +.Op Fl T +.Op Fl u +.Op Fl U +.Op Fl v +.Op Fl z +.Ar archive +.Ar +.Nm +.Fl s +.Op Fl D +.Op Fl j +.Op Fl U +.Op Fl z +.Ar archive +.Nm +.Fl t +.Op Fl f +.Op Fl s +.Op Fl T +.Op Fl v +.Ar archive +.Op Ar +.Nm +.Fl x +.Op Fl C +.Op Fl f +.Op Fl o +.Op Fl s +.Op Fl T +.Op Fl u +.Op Fl v +.Ar archive +.Op Ar +.Nm +.Fl M +.Nm +.Fl V +.Sh DESCRIPTION +The +.Nm +utility creates and maintains groups of files combined into an +archive. +Once an archive has been created, new files can be added to it, and +existing files can be extracted, deleted or replaced. +.Pp +Files are named in the archive by their last file name component, +so if a file referenced by a path containing a +.Dq / +is archived, it will be named by the last component of the path. +Similarly when matching paths listed on the command line against +file names stored in the archive, only the last component of the +path will be compared. +.Pp +The normal use of +.Nm +is for the creation and maintenance of libraries suitable for use +with the link editor +.Xr ld 1 , +although it is not restricted to this purpose. +The +.Nm +utility can create and manage an archive symbol table (see +.Xr ar 5 ) +used to speed up link editing operations. +If a symbol table is present in an archive, it will be +kept up-to-date by subsequent operations on the archive. +.Sh OPTIONS +The +.Nm +utility supports the following options: +.Bl -tag -width indent +.It Fl a Ar member-after +When used with option +.Fl m +this option specifies that the archive members specified by +arguments +.Ar +are moved to after the archive member named by argument +.Ar member-after . +When used with option +.Fl r +this option specifies that the files specified by arguments +.Ar +are added after the archive member named by argument +.Ar member-after . +.It Fl b Ar member-before +When used with option +.Fl m +this option specifies that the archive members specified by +arguments +.Ar +are moved to before the archive member named by argument +.Ar member-before . +When used with option +.Fl r +this option specifies that the files specified by arguments +.Ar +are added before the archive member named by argument +.Ar member-before . +.It Fl c +Suppress the informational message printed when a new archive is +created using the +.Fl r +and +.Fl q +options. +.It Fl C +Prevent extracted files from replacing like-named files +in the file system. +.It Fl d +Delete the members named by arguments +.Ar +from the archive specified by argument +.Ar archive . +The archive's symbol table, if present, is updated to reflect +the new contents of the archive. +.It Fl D +When used in combination with the +.Fl r +or +.Fl q +option, insert 0's instead of the real mtime, uid and gid values +and 0644 instead of file mode from the members named by arguments +.Ar . +This ensures that checksums on the resulting archives are reproducible +when member contents are identical. +If multiple +.Fl D +and +.Fl U +options are specified on the command line, the final one takes precedence. +.It Fl f +Synonymous with option +.Fl T . +.It Fl F Ar flavor | Fl -flavor Ar flavor +Create archives with the specified archive format. +Legal values for argument +.Ar flavor +are: +.Bl -tag -width indent -compact +.It Ar bsd +Create BSD format archives. +.It Ar gnu +An alias for +.Ar svr4 . +.It Ar svr4 +Create SVR4 format archives. +.El +If this option is not specified, +.Nm +will create archives using the SVR4 format. +.It Fl i Ar member-before +Synonymous with option +.Fl b . +.It Fl j +This option is accepted for compatibility with the +.Tn FreeBSD +version of the +.Nm +utility, but is ignored. +.It Fl l +This option is accepted for compatibility with GNU +.Xr ar 1 , +but is ignored. +.It Fl m +Move archive members specified by arguments +.Ar +within the archive. +If a position has been specified by one of the +.Fl a , +.Fl b +or +.Fl i +options, the members are moved to before or after the specified +position. +If no position has been specified, the specified members are moved +to the end of the archive. +If the archive has a symbol table, it is updated to reflect the +new contents of the archive. +.It Fl M +Read and execute MRI librarian commands from standard input. +The commands understood by the +.Nm +utility are described in the section +.Sx "MRI Librarian Commands" . +.It Fl o +Preserve the original modification times of members when extracting +them. +.It Fl p +Write the contents of the specified archive members named by +arguments +.Ar +to standard output. +If no members were specified, the contents of all the files in the +archive are written in the order they appear in the archive. +.It Fl q +Append the files specified by arguments +.Ar +to the archive specified by argument +.Ar archive +without checking if the files already exist in the archive. +The archive symbol table will be updated as needed. +If the file specified by the argument +.Ar archive +does not already exist, a new archive will be created. +.It Fl r +Replace (add) the files specified by arguments +.Ar +in the archive specified by argument +.Ar archive , +creating the archive if necessary. +Replacing existing members will not change the order of members within +the archive. +If a file named in arguments +.Ar +does not exist, existing members in the archive that match that +name are not changed. +New files are added to the end of the archive unless one of the +positioning options +.Fl a , +.Fl b +or +.Fl i +is specified. +The archive symbol table, if it exists, is updated to reflect the +new state of the archive. +.It Fl s +Add an archive symbol table (see +.Xr ar 5 ) +to the archive specified by argument +.Ar archive . +Invoking +.Nm +with the +.Fl s +option alone is equivalent to invoking +.Xr ranlib 1 . +.It Fl S +Do not generate an archive symbol table. +.It Fl t +For +.Nm , +list the files specified by arguments +.Ar +in the order in which they appear in the archive, one per line. +If no files are specified, all files in the archive are listed. +.It Fl T +Use only the first fifteen characters of the archive member name or +command line file name argument when naming archive members. +.It Fl u +Conditionally update the archive or extract members. +When used with the +.Fl r +option, files named by arguments +.Ar +will be replaced in the archive if they are newer than their +archived versions. +When used with the +.Fl x +option, the members specified by arguments +.Ar +will be extracted only if they are newer than the corresponding +files in the file system. +.It Fl U +When used in combination with the +.Fl r +or +.Fl q +option, insert the real mtime, uid and gid, and file mode values +from the members named by arguments +.Ar . +If multiple +.Fl D +and +.Fl U +options are specified on the command line, the final one takes precedence. +.It Fl v +Provide verbose output. +When used with the +.Fl d , +.Fl m , +.Fl q +or +.Fl x +options, +.Nm +gives a file-by-file description of the archive modification being +performed, which consists of three white-space separated fields: +the option letter, a dash +.Dq "-" , +and the file name. +When used with the +.Fl r +option, +.Nm +displays the description as above, but the initial letter is an +.Dq a +if the file is added to the archive, or an +.Dq r +if the file replaces a file already in the archive. +When used with the +.Fl p +option, the name of the file enclosed in +.Dq < +and +.Dq > +characters is written to standard output preceded by a single newline +character and followed by two newline characters. +The contents of the named file follow the file name. +When used with the +.Fl t +option, +.Nm +displays eight whitespace separated fields: +the file permissions as displayed by +.Xr strmode 3 , +decimal user and group IDs separated by a slash ( +.Dq / Ns ) , +the file size in bytes, the file modification time in +.Xr strftime 3 +format +.Dq "%b %e %H:%M %Y" , +and the name of the file. +.It Fl V +Print a version identifier and exit. +.It Fl x +Extract archive members specified by arguments +.Ar +into the current directory. +If no members have been specified, extract all members of the archive. +If the file corresponding to an extracted member does not exist it +will be created. +If the file corresponding to an extracted member does exist, its owner +and group will not be changed while its contents will be overwritten +and its permissions will set to that entered in the archive. +The file's access and modification time would be that of the time +of extraction unless the +.Fl o +option was specified. +.It Fl z +This option is accepted for compatibility with the +.Tn FreeBSD +version of the +.Nm +utility, but is ignored. +.El +.Ss "MRI Librarian Commands" +If the +.Fl M +option is specified, the +.Nm +utility will read and execute commands from its standard input. +If standard input is a terminal, the +.Nm +utility will display the prompt +.Dq Li "AR >" +before reading a line, and will continue operation even if errors are +encountered. +If standard input is not a terminal, the +.Nm +utility will not display a prompt and will terminate execution on +encountering an error. +.Pp +Each input line contains a single command. +Words in an input line are separated by whitespace characters. +The first word of the line is the command, the remaining words are +the arguments to the command. +The command word may be specified in either case. +Arguments may be separated by commas or blanks. +.Pp +Empty lines are allowed and are ignored. +Long lines are continued by ending them with the +.Dq Li + +character. +.Pp +The +.Dq Li * +and +.Dq Li "\;" +characters start a comment. +Comments extend till the end of the line. +.Pp +When executing an MRI librarian script the +.Nm +utility works on a temporary copy of an archive. +Changes to the copy are made permanent using the +.Ic save +command. +.Pp +Commands understood by the +.Nm +utility are: +.Bl -tag -width indent +.It Ic addlib Ar archive | Ic addlib Ar archive Pq Ar member Oo Li , Ar member Oc Ns ... +Add the contents of the archive named by argument +.Ar archive +to the current archive. +If specific members are named using the arguments +.Ar member , +then those members are added to the current archive. +If no members are specified, the entire contents of the archive +are added to the current archive. +.It Ic addmod Ar member Oo Li , Ar member Oc Ns ... +Add the files named by arguments +.Ar member +to the current archive. +.It Ic clear +Discard all the contents of the current archive. +.It Ic create Ar archive +Create a new archive named by the argument +.Ar archive , +and makes it the current archive. +If the named archive already exists, it will be overwritten +when the +.Ic save +command is issued. +.It Ic delete Ar module Oo Li , Ar member Oc Ns ... +Delete the modules named by the arguments +.Ar member +from the current archive. +.It Ic directory Ar archive Po Ar member Oo Li , Ar member Oc Ns ... Pc Op Ar outputfile +List each named module in the archive. +The format of the output depends on the verbosity setting set using +the +.Ic verbose +command. +Output is sent to standard output, or to the file specified by +argument +.Ar outputfile . +.It Ic end +Exit successfully from the +.Nm +utility. +Any unsaved changes to the current archive will be discarded. +.It Ic extract Ar member Oo Li , Ar member Oc Ns ... +Extract the members named by the arguments +.Ar member +from the current archive. +.It Ic list +Display the contents of the current archive in verbose style. +.It Ic open Ar archive +Open the archive named by argument +.Ar archive +and make it the current archive. +.It Ic replace Ar member Oo Li , Ar member Oc Ns ... +Replace named members in the current archive with the files specified +by arguments +.Ar member . +The files must be present in the current directory and the named +modules must already exist in the current archive. +.It Ic save +Commit all changes to the current archive. +.It Ic verbose +Toggle the verbosity of the +.Ic directory +command. +.El +.Sh EXAMPLES +To create a new archive +.Pa ex.a +containing three files +.Pa ex1.o , +.Pa ex2.o +and +.Pa ex3.o , +use: +.Dl "ar -rc ex.a ex1.o ex2.o ex3.o" +.Pp +To add an archive symbol table to an existing archive +.Pa ex.a , +use: +.Dl "ar -s ex.a" +.Pp +To delete file +.Pa ex1.o +from archive +.Pa ex.a , +use: +.D1 "ar -d ex.a ex1.o" +.Pp +To verbosely list the contents of archive +.Pa ex.a , +use: +.D1 "ar -tv ex.a" +.Pp +To create a new archive +.Pa ex.a +containing the files +.Pa ex1.o , +and +.Pa ex2.o , +using MRI librarian commands, use the following script: +.Bd -literal -offset indent +create ex.a * specify the output archive +addmod ex1.o ex2.o * add modules +save * save pending changes +end * exit the utility +.Ed +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ld 1 , +.Xr ranlib 1 , +.Xr archive 3 , +.Xr elf 3 , +.Xr strftime 3 , +.Xr strmode 3 , +.Xr ar 5 +.Sh STANDARDS COMPLIANCE +The +.Nm +utility's support for the +.Fl a , +.Fl b , +.Fl c , +.Fl i , +.Fl m , +.Fl p , +.Fl q , +.Fl r , +.Fl s , +.Fl t , +.Fl u , +.Fl v , +.Fl C +and +.Fl T +options is believed to be compliant with +.St -p1003.2 . +.Sh HISTORY +An +.Nm +command first appeared in AT&T UNIX Version 1. +In +.Fx 8.0 , +.An Kai Wang Aq Mt kaiw@FreeBSD.org +reimplemented +.Nm +using the +.Lb libarchive +and the +.Lb libelf . diff --git a/contrib/elftoolchain/ar/ar.5 b/contrib/elftoolchain/ar/ar.5 new file mode 100644 index 0000000000..9e403d38c5 --- /dev/null +++ b/contrib/elftoolchain/ar/ar.5 @@ -0,0 +1,329 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: ar.5 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd September 30, 2018 +.Dt AR 5 +.Os +.Sh NAME +.Nm ar +.Nd archive file format for +.Xr ar 1 +and +.Xr ranlib 1 +.Sh SYNOPSIS +.In ar.h +.Sh DESCRIPTION +.Xr ar 1 +archives are created and managed by the +.Xr ar 1 +and +.Xr ranlib 1 +utilities. +These archives are typically used during program development to +hold libraries of program objects. +An +.Xr ar 1 +archive is contained in a single operating system file. +.Pp +This manual page documents two variants of the +.Xr ar 1 +archive format: the BSD archive format, and the SVR4/GNU archive +format. +.Pp +In both variants the archive file starts with an identifying byte +sequence of the seven ASCII characters +.Sq Li "!" +followed by a ASCII linefeed character +.Po +see the constant +.Dq ARMAG +in the header file +.In ar.h +.Pc . +.Pp +Archive members follow the initial identifying byte sequence. +Each archive member is prefixed by a fixed size header describing the +file attributes associated with the member. +.Ss "Archive Headers" +An archive header describes the file attributes for the archive member that +follows it. +The +.Xr ar 5 +format only supports a limited number of attributes: the file name, +the file creation time stamp, the uid and gid of the creator, the file +mode and the file size. +.Pp +Archive headers are placed at an even byte offset in the archive file. +If the data for an archive member ends at an odd byte offset, then a +padding byte with value 0x0A is used to position the next archive +header on an even byte offset. +.Pp +An archive header comprises the following fixed sized fields: +.Bl -tag -width "Li ar_name" +.It Ar ar_name +(16 bytes) The file name of the archive member. +This field names a leaf file; absolute paths and relative paths containing +directory names are not supported. +The format of this field varies between the BSD and SVR4/GNU formats and +is described in more detail in the section +.Sx "Representing File Names" +below. +.It Ar ar_date +(12 bytes) The file modification time for the member in seconds since the +epoch, encoded as a decimal number. +.It Ar ar_uid +(6 bytes) The uid associated with the archive member, encoded as a +decimal number. +.It Ar ar_gid +(6 bytes) The gid associated with the archive member, encoded as a +decimal number. +.It Ar ar_mode +(8 bytes) The file mode for the archive member, encoded as an octal +number. +.It Ar ar_size +(10 bytes) In the SVR4/GNU archive format this field holds the size in +bytes of the archive member, encoded as a decimal number. +In the BSD archive format, for short file names, this field +holds the size in bytes of the archive member, encoded as a decimal +number. +For long file names +.Po +see +.Sx "Representing File Names" +below +.Pc , +the field contains the combined size of the +archive member and its file name, encoded as a decimal number. +.It Ar ar_fmag +(2 bytes) This field holds 2 bytes with values 0x96 and 0x0A +respectively, marking the end of the header. +.El +.Pp +Unused bytes in the fields of an archive header are set to the value +0x20. +.Ss "Representing File Names" +The BSD and SVR4/GNU variants use different schemes for encoding file +names for members. +.Bl -tag -width "SVR4/GNU" +.It "BSD" +File names that are up to 16 bytes long and which do not contain +embedded spaces are stored directly in the +.Ar ar_name +field of the archive header. +File names that are either longer than 16 bytes or which contain +embedded spaces are stored immediately after the archive header +and the +.Ar ar_name +field of the archive header is set to the string +.Dq "#1/" +followed by a decimal representation of the number of bytes needed for +the file name. +In addition, the +.Ar ar_size +field of the archive header is set to the decimal representation of +the combined sizes of the archive member and the file name. +The file contents of the member follows the file name without further +padding. +.Pp +As an example, if the file name for a member was +.Dq "A B" +and its contents was the string +.Dq "C D" , +then the +.Ar ar_name +field of the header would contain +.Dq Li "#1/3" , +the +.Ar ar_size +field of the header would contain +.Dq Li 6 , +and the bytes immediately following the header would be 0x41, 0x20, +0x42, 0x43, 0x20 and 0x44 +.Po +ASCII +.Dq "A BC D" +.Pc . +.It "SVR4/GNU" +File names that are up to 15 characters long are stored directly in the +.Ar ar_name +field of the header, terminated by a +.Dq Li / +character. +.Pp +If the file name is larger than would fit in space for the +.Ar ar_name +field, then the actual file name is kept in the archive +string table +.Po +see +.Sx "Archive String Tables" +below +.Pc , +and the decimal offset of the file name in the string table is stored +in the +.Ar ar_name +field, prefixed by a +.Dq Li / +character. +.Pp +As an example, if the real file name has been stored at offset 768 in +the archive string table, the +.Ar ar_name +field of the header will contain the string +.Dq /768 . +.El +.Ss "Special Archive Members" +The following archive members are special. +.Bl -tag -width indent +.It Dq Li / +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li / +denotes an archive symbol table. +If present, this member will be the very first member in the +archive. +.It Dq Li // +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li // +denotes the archive string table. +This special member is used to hold filenames that do not fit in the +file name field of the header +.Po +see +.Sx "Representing File Names" +above +.Pc . +If present, this member immediately follows the archive symbol table +if an archive symbol table is present, or is the first member otherwise. +.It Dq Li "__.SYMDEF" +This special member contains the archive symbol table in the BSD +variant of the archive format. +If present, this member will be the very first member in the +archive. +.El +.Ss "Archive String Tables" +An archive string table is used in the SVR4/GNU archive format to hold +file names that are too large to fit into the constraints of the +.Ar ar_name +field of the archive header. +An archive string table contains a sequence of file names. +Each file name in the archive string table is terminated by the +byte sequence 0x2F, 0x0A +.Po +the ASCII string +.Dq "/\en" +.Pc . +No padding is used to separate adjacent file names. +.Ss "Archive Symbol Tables" +Archive symbol tables are used to speed up link editing by providing a +mapping between the program symbols defined in the archive +and the corresponding archive members. +Archive symbol tables are managed by the +.Xr ranlib 1 +utility. +.Pp +The format of archive symbol tables is as follows: +.Bl -tag -width "SVR4/GNU" +.It BSD +In the BSD archive format, the archive symbol table comprises +of two parts: a part containing an array of +.Vt "struct ranlib" +descriptors, followed by a part containing a symbol string table. +The sizes and layout of the structures that make up a BSD format +archive symbol table are machine dependent. +.Pp +The part containing +.Vt "struct ranlib" +descriptors begins with a field containing the size in bytes of the +array of +.Vt "struct ranlib" +descriptors encoded as a C +.Vt long +value. +.Pp +The array of +.Vt "struct ranlib" +descriptors follows the size field. +Each +.Vt "struct ranlib" +descriptor describes one symbol. +.Pp +A +.Vt "struct ranlib" +descriptor comprises two fields: +.Bl -tag -width "Ar ran_strx" -compact +.It Ar ran_strx +.Pq C Vt long +This field contains the zero-based offset of the symbol name in the +symbol string table. +.It Ar ran_off +.Pq C Vt long +This field is the file offset to the archive header for the archive +member defining the symbol. +.El +.Pp +The part containing the symbol string table begins with a field +containing the size in bytes of the string table, encoded as a C +.Vt long +value. +This string table follows the size field, and contains +NUL-terminated strings for the symbols in the symbol table. +.It SVR4/GNU +In the SVR4/GNU archive format, the archive symbol table starts with a +4-byte binary value containing the number of entries contained in the +archive symbol table. +This count of entries is stored most significant byte first. +.Pp +Next, there are +.Ar count +4-byte numbers, each stored most significant byte first. +Each number is a binary offset to the archive header for the member in +the archive file for the corresponding symbol table entry. +.Pp +After the binary offset values, there are +.Ar count +NUL-terminated strings in sequence, holding the symbol names for +the corresponding symbol table entries. +.El +.Sh STANDARDS COMPLIANCE +The +.Xr ar 1 +archive format is not currently specified by a standard. +.Pp +This manual page documents the +.Xr ar 1 +archive formats used by the +.Bx 4.4 +and +.Ux SVR4 +operating system releases. +.Sh SEE ALSO +.Xr ar 1 , +.Xr ld 1 , +.Xr ranlib 1 , +.Xr elf 3 , +.Xr elf_getarsym 3 , +.Xr elf_rand 3 diff --git a/contrib/elftoolchain/ar/ar.c b/contrib/elftoolchain/ar/ar.c new file mode 100644 index 0000000000..e864d417a8 --- /dev/null +++ b/contrib/elftoolchain/ar/ar.c @@ -0,0 +1,450 @@ +/*- + * Copyright (c) 2007 Kai Wang + * Copyright (c) 2007 Tim Kientzle + * Copyright (c) 2007 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Hugh Smith at The University of Guelph. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ar.h" + +ELFTC_VCSID("$Id: ar.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +enum options +{ + OPTION_HELP +}; + +static struct option longopts[] = +{ + {"flavor", required_argument, NULL, 'F'}, + {"help", no_argument, NULL, OPTION_HELP}, + {"version", no_argument, NULL, 'V'}, + {NULL, 0, NULL, 0} +}; + +static void bsdar_usage(int); +static void ranlib_usage(int); +static void set_mode(struct bsdar *bsdar, char opt); +static void only_mode(struct bsdar *bsdar, const char *opt, + const char *valid_modes); +static void bsdar_version(void); + +int +main(int argc, char **argv) +{ + struct bsdar *bsdar, bsdar_storage; + char *arcmd, *argv1_saved; + size_t len; + int exitcode, i, opt; + + bsdar = &bsdar_storage; + memset(bsdar, 0, sizeof(*bsdar)); + + exitcode = EXIT_SUCCESS; + arcmd = argv1_saved = NULL; + bsdar->output = stdout; + + if ((bsdar->progname = ELFTC_GETPROGNAME()) == NULL) + bsdar->progname = "ar"; + + if (elf_version(EV_CURRENT) == EV_NONE) + bsdar_errc(bsdar, 0, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + /* + * Act like ranlib if our name ends in "ranlib"; this + * accommodates names like "arm-freebsd7.1-ranlib", + * "bsdranlib", etc. + */ + len = strlen(bsdar->progname); + if (len >= strlen("ranlib") && + strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) { + while ((opt = getopt_long(argc, argv, "tDUV", longopts, + NULL)) != -1) { + switch(opt) { + case 't': + /* Ignored. */ + break; + case 'D': + bsdar->options |= AR_D; + break; + case 'U': + bsdar->options &= ~AR_D; + break; + case 'V': + bsdar_version(); + break; + case OPTION_HELP: + ranlib_usage(EX_OK); + break; + default: + ranlib_usage(EX_USAGE); + break; + } + } + argv += optind; + argc -= optind; + + if (*argv == NULL) + ranlib_usage(EX_USAGE); + + bsdar->options |= AR_S; + while ((bsdar->filename = *argv++) != NULL) + exitcode |= ar_write_archive(bsdar, 's'); + + exit(exitcode); + } else { + if (argc < 2) + bsdar_usage(EX_USAGE); + + /* + * Tack on a leading '-', for old-style usage. + */ + if (*argv[1] != '-') { + argv1_saved = argv[1]; + len = strlen(argv[1]) + 2; + if ((arcmd = malloc(len)) == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + (void) snprintf(arcmd, len, "-%s", argv[1]); + argv[1] = arcmd; + } + } + + while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtUuVvxz", + longopts, NULL)) != -1) { + switch(opt) { + case 'a': + bsdar->options |= AR_A; + break; + case 'b': + case 'i': + bsdar->options |= AR_B; + break; + case 'C': + bsdar->options |= AR_CC; + break; + case 'c': + bsdar->options |= AR_C; + break; + case 'd': + set_mode(bsdar, opt); + break; + case 'D': + bsdar->options |= AR_D; + break; + case 'F': + if (!strcasecmp(optarg, "svr4") || + !strcasecmp(optarg, "gnu")) + bsdar->options &= ~AR_BSD; + else if (!strcasecmp(optarg, "bsd")) + bsdar->options |= AR_BSD; + else + bsdar_usage(EX_USAGE); + break; + case 'f': + case 'T': + bsdar->options |= AR_TR; + break; + case 'j': + /* ignored */ + break; + case 'l': + /* ignored, for GNU ar comptibility */ + break; + case 'M': + set_mode(bsdar, opt); + break; + case 'm': + set_mode(bsdar, opt); + break; + case 'o': + bsdar->options |= AR_O; + break; + case 'p': + set_mode(bsdar, opt); + break; + case 'q': + set_mode(bsdar, opt); + break; + case 'r': + set_mode(bsdar, opt); + break; + case 'S': + bsdar->options |= AR_SS; + break; + case 's': + bsdar->options |= AR_S; + break; + case 't': + set_mode(bsdar, opt); + break; + case 'U': + bsdar->options &= ~AR_D; + break; + case 'u': + bsdar->options |= AR_U; + break; + case 'V': + bsdar_version(); + break; + case 'v': + bsdar->options |= AR_V; + break; + case 'x': + set_mode(bsdar, opt); + break; + case 'z': + /* ignored */ + break; + case OPTION_HELP: + bsdar_usage(EX_OK); + break; + default: + bsdar_usage(EX_USAGE); + break; + } + } + + /* Restore argv[1] if we had modified it. */ + if (arcmd != NULL) { + argv[1] = argv1_saved; + free(arcmd); + arcmd = argv1_saved = NULL; + } + + argv += optind; + argc -= optind; + + if (*argv == NULL && bsdar->mode != 'M') + bsdar_usage(EX_USAGE); + + if (bsdar->options & AR_A && bsdar->options & AR_B) + bsdar_errc(bsdar, 0, + "only one of -a and -[bi] options allowed"); + + if (bsdar->options & AR_J && bsdar->options & AR_Z) + bsdar_errc(bsdar, 0, + "only one of -j and -z options allowed"); + + if (bsdar->options & AR_S && bsdar->options & AR_SS) + bsdar_errc(bsdar, 0, + "only one of -s and -S options allowed"); + + if (bsdar->options & (AR_A | AR_B)) { + if (*argv == NULL) + bsdar_errc(bsdar, 0, + "no position operand specified"); + if ((bsdar->posarg = basename(*argv)) == NULL) + bsdar_errc(bsdar, errno, + "basename failed"); + argc--; + argv++; + } + + if (bsdar->options & AR_A) + only_mode(bsdar, "-a", "mqr"); + if (bsdar->options & AR_B) + only_mode(bsdar, "-b", "mqr"); + if (bsdar->options & AR_C) + only_mode(bsdar, "-c", "qr"); + if (bsdar->options & AR_CC) + only_mode(bsdar, "-C", "x"); + if (bsdar->options & AR_D) + only_mode(bsdar, "-D", "qr"); + if (bsdar->options & AR_O) + only_mode(bsdar, "-o", "x"); + if (bsdar->options & AR_SS) + only_mode(bsdar, "-S", "mqr"); + if (bsdar->options & AR_U) + only_mode(bsdar, "-u", "qrx"); + + if (bsdar->mode == 'M') { + ar_mode_script(bsdar); + exit(EXIT_SUCCESS); + } + + if ((bsdar->filename = *argv) == NULL) + bsdar_usage(EX_USAGE); + + bsdar->argc = --argc; + bsdar->argv = ++argv; + + if ((!bsdar->mode || strchr("ptx", bsdar->mode)) && + bsdar->options & AR_S) { + exitcode = ar_write_archive(bsdar, 's'); + if (!bsdar->mode) + exit(exitcode); + } + + switch(bsdar->mode) { + case 'd': case 'm': case 'q': case 'r': + exitcode = ar_write_archive(bsdar, bsdar->mode); + break; + + case 'p': case 't': case 'x': + exitcode = ar_read_archive(bsdar, bsdar->mode); + break; + default: + bsdar_usage(EX_USAGE); + /* NOTREACHED */ + } + + for (i = 0; i < bsdar->argc; i++) { + if (bsdar->argv[i] != NULL) { + bsdar_warnc(bsdar, 0, "%s: not found in archive", + bsdar->argv[i]); + exitcode = EXIT_FAILURE; + } + } + + exit(exitcode); +} + +static void +set_mode(struct bsdar *bsdar, char opt) +{ + + if (bsdar->mode != '\0' && bsdar->mode != opt) + bsdar_errc(bsdar, 0, "Can't specify both -%c and -%c", + opt, bsdar->mode); + bsdar->mode = opt; +} + +static void +only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes) +{ + + if (strchr(valid_modes, bsdar->mode) == NULL) + bsdar_errc(bsdar, 0, "Option %s is not permitted in mode -%c", + opt, bsdar->mode); +} + +#define AR_USAGE_MESSAGE "\ +Usage: %s [options] archive file...\n\ + Manage archives.\n\n\ + Where is one of:\n\ + -d Delete members from the archive.\n\ + -m Move archive members within the archive.\n\ + -p Write the contents of members to standard output.\n\ + -q Append files to an archive.\n\ + -r Replace (add) files to an archive.\n\ + -s Add an archive symbol to an archive.\n\ + -t List files in an archive.\n\ + -x Extract members from an archive.\n\ + -M Execute MRI librarian commands.\n\ + -V Print a version identifier and exit.\n\n\ + Options:\n\ + -a MEMBER Add members after the specified member.\n\ + -b MEMBER | -i MEMBER\n\ + Add members before the specified member.\n\ + -c Do not print a message when creating a new archive.\n\ + -f | -T Only use the first fifteen characters of the member name.\n\ + -j (This option is accepted, but is ignored).\n\ + -l (This option is accepted, but is ignored).\n\ + -o Preserve modification times when extracting members.\n\ + -u Conditionally update or extract members.\n\ + -v Be verbose.\n\ + -z (This option is accepted, but is ignored).\n\ + -C Do not overwrite existing files in the file system.\n\ + -D Use fixed metadata, for consistent archive checksums.\n\ + -F FORMAT | --flavor=FORMAT\n\ + Create archives with the specified format.\n\ + -S Do not generate an archive symbol table.\n\ + -U Use original metadata for archive members.\n" + +static void +bsdar_usage(int exit_code) +{ + (void) fprintf(stderr, AR_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +#define RANLIB_USAGE_MESSAGE "\ +Usage: %s [options] archive...\n\ + Update or create archive symbol tables.\n\n\ + Options:\n\ + -t (This option is accepted, but ignored).\n\ + -D Use fixed metadata, for consistent archive checksums.\n\ + -U Use original metadata, for unique archive checksums.\n\ + -V Print a version identifier and exit.\n" + +static void +ranlib_usage(int exit_code) +{ + (void)fprintf(stderr, RANLIB_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +bsdar_version(void) +{ + (void)printf("%s (%s, %s)\n", ELFTC_GETPROGNAME(), archive_version_string(), + elftc_version()); + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/ar/ar.h b/contrib/elftoolchain/ar/ar.h new file mode 100644 index 0000000000..b39a1d9781 --- /dev/null +++ b/contrib/elftoolchain/ar/ar.h @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 2007 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: ar.h 3629 2018-09-30 19:26:28Z jkoshy $ + */ + +#include + +#include "_elftc.h" + +/* + * ar(1) options. + */ +#define AR_A 0x0001 /* position-after */ +#define AR_B 0x0002 /* position-before */ +#define AR_C 0x0004 /* creating new archive */ +#define AR_CC 0x0008 /* do not overwrite when extracting */ +#define AR_J 0x0010 /* bzip2 compression */ +#define AR_O 0x0020 /* preserve original mtime when extracting */ +#define AR_S 0x0040 /* write archive symbol table */ +#define AR_SS 0x0080 /* do not write archive symbol table */ +#define AR_TR 0x0100 /* only keep first 15 chars for member name */ +#define AR_U 0x0200 /* only extract or update newer members.*/ +#define AR_V 0x0400 /* verbose mode */ +#define AR_Z 0x0800 /* gzip compression */ +#define AR_D 0x1000 /* insert dummy mode, mtime, uid and gid */ +#define AR_BSD 0x2000 /* use the BSD archive format */ + +#define DEF_BLKSZ 10240 /* default block size */ + +/* Special names. */ + +#define AR_STRINGTAB_NAME_SVR4 "//" +#define AR_SYMTAB_NAME_BSD "__.SYMDEF" +#define AR_SYMTAB_NAME_SVR4 "/" + +/* + * Convenient wrapper for general libarchive error handling. + */ +#define AC(CALL) do { \ + if ((CALL)) \ + bsdar_errc(bsdar, 0, "%s", \ + archive_error_string(a)); \ +} while (0) + +/* + * The 'ACV' wrapper is used for libarchive APIs that changed from + * returning 'void' to returning an 'int' in later versions of libarchive. + */ +#if ARCHIVE_VERSION_NUMBER >= 2000000 +#define ACV(CALL) AC(CALL) +#else +#define ACV(CALL) do { \ + (CALL); \ + } while (0) +#endif + +/* + * In-memory representation of archive member(object). + */ +struct ar_obj { + Elf *elf; /* object file descriptor */ + char *name; /* member name */ + uid_t uid; /* user id */ + gid_t gid; /* group id */ + mode_t md; /* octal file permissions */ + size_t size; /* member size */ + time_t mtime; /* modification time */ + dev_t dev; /* inode's device */ + ino_t ino; /* inode's number */ + + TAILQ_ENTRY(ar_obj) objs; +}; + +/* + * Structure encapsulates the "global" data for "ar" program. + */ +struct bsdar { + const char *filename; /* archive name. */ + const char *addlib; /* target of ADDLIB. */ + const char *posarg; /* position arg for modifiers -a, -b. */ + char mode; /* program mode */ + int options; /* command line options */ + FILE *output; /* default output stream */ + + const char *progname; /* program name */ + int argc; + char **argv; + + dev_t ar_dev; /* archive device. */ + ino_t ar_ino; /* archive inode. */ + + /* + * Fields for the archive string table. + */ + char *as; /* buffer for archive string table. */ + size_t as_sz; /* current size of as table. */ + size_t as_cap; /* capacity of as table buffer. */ + + /* + * Fields for the archive symbol table. + */ + uint32_t s_cnt; /* current number of symbols. */ + uint32_t *s_so; /* symbol offset table. */ + size_t s_so_cap; /* capacity of so table buffer. */ + char *s_sn; /* symbol name table */ + size_t s_sn_cap; /* capacity of sn table buffer. */ + size_t s_sn_sz; /* current size of sn table. */ + /* Current member's offset (relative to the end of pseudo members.) */ + off_t rela_off; + + TAILQ_HEAD(, ar_obj) v_obj; /* object(member) list */ +}; + +void ar_mode_script(struct bsdar *ar); +int ar_read_archive(struct bsdar *_ar, int _mode); +int ar_write_archive(struct bsdar *_ar, int _mode); +void bsdar_errc(struct bsdar *, int _code, const char *fmt, ...); +int bsdar_is_pseudomember(struct bsdar *_ar, const char *_name); +const char *bsdar_strmode(mode_t m); +void bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...); diff --git a/contrib/elftoolchain/ar/benchmark/acp.sh b/contrib/elftoolchain/ar/benchmark/acp.sh new file mode 100644 index 0000000000..11be68bf40 --- /dev/null +++ b/contrib/elftoolchain/ar/benchmark/acp.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# $Id: acp.sh 2086 2011-10-27 05:18:01Z jkoshy $ + +# This script is adapted from Jan Psota's Tar Comparison Program(TCP). + +n=3 # number of repetitions +AR="bsdar gnuar" # ar archivers to compare + +test $# -ge 2 || { + echo "usage: $0 source_dir where_to_place_archive [where_to_extract_it]" + exit 0 +} + +THISDIR=`/bin/pwd` +src=$1 +dst=$2/acp.a +ext=${3:-$2}/acptmp +test -e $dst -o -e /tmp/acp \ + && { echo "$dst or /tmp/acp exists, exiting"; exit 1; } +mkdir -p $ext || exit 1 + +show_result () +{ + awk -vL="`du -k $dst`" '{printf "%s\t%s\t%s\%10.1d KB/s\n", +$1, $3, $5, ($1>0?L/$1:0)}' /tmp/acp | sort | head -n 1 +} + +test -d $src || { echo "'$src' is not a directory"; exit 1; } + +# ar versions +for ar in $AR; do echo -n "$ar: "; $ar -V | head -n 1; +done + +echo +echo "best time of $n repetitions" +echo -n " src=$src, " +echo -n "`du -sh $src | awk '{print $1}'`" +echo -n " in " +echo "`find $src | wc -l` files" +echo " archive=$dst, extract to $ext" + +echo "program operation real user system speed" +for op in "cru $dst $src/*" "t $dst" "x `basename $dst`"; do + for ar in $AR; do + echo -n "$ar " + echo $op | grep -q ^cr && echo -n "create " + echo $op | grep -q ^t && echo -n "list " + echo $op | grep -q ^x && echo -n "extract " + num=0 + while [ $num -lt $n ]; do + echo $op | grep -q ^cr && rm -f $dst + echo $op | grep -q ^x && { rm -rf $ext; mkdir -p $ext + cp $dst $ext; cd $ext; } + sync + time $ar $op > /dev/null 2>> /tmp/acp + echo $op | grep -q ^x && cd $THISDIR + num=`expr $num + 1` + done + show_result + rm -rf /tmp/acp + done + echo +done +rm -rf $ext $dst +rm -f /tmp/acp diff --git a/contrib/elftoolchain/ar/os.FreeBSD.mk b/contrib/elftoolchain/ar/os.FreeBSD.mk new file mode 100644 index 0000000000..c29af70518 --- /dev/null +++ b/contrib/elftoolchain/ar/os.FreeBSD.mk @@ -0,0 +1,2 @@ +DPADD+= ${LIBBZ2} +LDADD+= -lbz2 diff --git a/contrib/elftoolchain/ar/os.Linux.mk b/contrib/elftoolchain/ar/os.Linux.mk new file mode 100644 index 0000000000..f5f322e7b8 --- /dev/null +++ b/contrib/elftoolchain/ar/os.Linux.mk @@ -0,0 +1,13 @@ +.if ${OS_DISTRIBUTION} == "Ubuntu" +.if ${OS_DISTRIBUTION_VERSION} >= 14 +# Ubuntu Trusty Tahr and later. + +# Use the --nounput option to flex(1), to prevent unused functions from +# being generated. +LFLAGS += --nounput +.endif +.if ${OS_DISTRIBUTION_VERSION} >= 22 +# 'NOPIC=yes' builds on Ubuntu need -lacl to be explicitly specified. +LDADD+= -lacl +.endif +.endif diff --git a/contrib/elftoolchain/ar/ranlib.1 b/contrib/elftoolchain/ar/ranlib.1 new file mode 100644 index 0000000000..84738634e9 --- /dev/null +++ b/contrib/elftoolchain/ar/ranlib.1 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2007,2009-2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: ranlib.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd December 9, 2012 +.Dt RANLIB 1 +.Os +.Sh NAME +.Nm ranlib +.Nd update archive symbol tables +.Sh SYNOPSIS +.Nm +.Op Fl D +.Op Fl t +.Ar archive Ns ... +.Nm +.Fl V +.Sh DESCRIPTION +The +.Nm ranlib +utility is used to update an existing archive symbol table in an +.Xr ar 1 +archive, or to add an archive symbol table to an archive lacking one. +.Sh OPTIONS +The +.Nm +utility supports the following options: +.Bl -tag -width indent +.It Fl D +Use zeros for the mtime, uid and gid fields, and use mode 0644 for the +file mode field for all archive member headers. +This ensures that checksums on the resulting archives are reproducible +when member contents are identical. +.It Fl t +This option is accepted, but is ignored. +.It Fl V +Print a version identifier and exit. +.El +.Sh EXAMPLES +To update the archive symbol table for an archive +.Pa lib.a , +use: +.Dl "ranlib lib.a" +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr ld 1 , +.Xr archive 3 , +.Xr elf 3 , +.Xr ar 5 +.Sh HISTORY +The +.Nm +command first appeared in AT&T UNIX Version 7. +.Pp +In +.Fx 8.0 , +.An Kai Wang Aq Mt kaiw@FreeBSD.org +reimplemented +.Nm +using the +.Lb libarchive +and the +.Lb libelf . diff --git a/contrib/elftoolchain/ar/read.c b/contrib/elftoolchain/ar/read.c new file mode 100644 index 0000000000..0aea381478 --- /dev/null +++ b/contrib/elftoolchain/ar/read.c @@ -0,0 +1,221 @@ +/*- + * Copyright (c) 2007 Kai Wang + * Copyright (c) 2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ar.h" + +ELFTC_VCSID("$Id: read.c 3629 2018-09-30 19:26:28Z jkoshy $"); + +/* + * Handle read modes: 'x', 't' and 'p'. + * + * Returns EXIT_SUCCESS if all operations completed successfully or returns + * EXIT_FAILURE otherwise. + */ +int +ar_read_archive(struct bsdar *bsdar, int mode) +{ + FILE *out; + struct archive *a; + struct archive_entry *entry; + struct stat sb; + struct tm *tp; + const char *bname; + const char *name; + mode_t md; + size_t size; + time_t mtime; + uid_t uid; + gid_t gid; + char **av; + char buf[25]; + int found; + int exitcode, i, flags, r; + + assert(mode == 'p' || mode == 't' || mode == 'x'); + + if ((a = archive_read_new()) == NULL) + bsdar_errc(bsdar, 0, "archive_read_new failed"); + archive_read_support_format_ar(a); + AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ)); + + exitcode = EXIT_SUCCESS; + out = bsdar->output; + + for (;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) + bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); + if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL) + break; + if (r == ARCHIVE_RETRY) { + bsdar_warnc(bsdar, 0, "Retrying..."); + continue; + } + + if (archive_format(a) == ARCHIVE_FORMAT_AR_BSD) + bsdar->options |= AR_BSD; + else + bsdar->options &= ~AR_BSD; + + if ((name = archive_entry_pathname(entry)) == NULL) + break; + + /* Skip pseudo members. */ + if (bsdar_is_pseudomember(bsdar, name)) + continue; + + /* The ar(5) format only supports 'leaf' file names. */ + if (strchr(name, '/')) { + bsdar_warnc(bsdar, 0, "ignoring entry: %s", + name); + continue; + } + + /* + * If we had been given a list of file names to process, check + * that the current entry is present in this list. + */ + if (bsdar->argc > 0) { + found = 0; + for(i = 0; i < bsdar->argc; i++) { + av = &bsdar->argv[i]; + if (*av == NULL) + continue; + /* + * Per POSIX, only the basename of a file + * argument should be compared. + */ + if ((bname = basename(*av)) == NULL) + bsdar_errc(bsdar, errno, + "basename failed"); + if (strcmp(bname, name) != 0) + continue; + + *av = NULL; + found = 1; + break; + } + if (!found) + continue; + } + + if (mode == 't') { + if (bsdar->options & AR_V) { + md = archive_entry_mode(entry); + uid = archive_entry_uid(entry); + gid = archive_entry_gid(entry); + size = archive_entry_size(entry); + mtime = archive_entry_mtime(entry); + (void)fprintf(out, "%s %6d/%-6d %8ju ", + bsdar_strmode(md) + 1, uid, gid, + (uintmax_t)size); + tp = localtime(&mtime); + (void)strftime(buf, sizeof(buf), + "%b %e %H:%M %Y", tp); + (void)fprintf(out, "%s %s", buf, name); + } else + (void)fprintf(out, "%s", name); + r = archive_read_data_skip(a); + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) { + (void)fprintf(out, "\n"); + bsdar_warnc(bsdar, 0, "%s", + archive_error_string(a)); + } + + if (r == ARCHIVE_FATAL) + break; + + (void)fprintf(out, "\n"); + } else { + /* mode == 'x' || mode = 'p' */ + if (mode == 'p') { + if (bsdar->options & AR_V) { + (void)fprintf(out, "\n<%s>\n\n", + name); + fflush(out); + } + r = archive_read_data_into_fd(a, fileno(out)); + } else { + /* mode == 'x' */ + if (stat(name, &sb) != 0) { + if (errno != ENOENT) { + bsdar_warnc(bsdar, errno, + "stat %s failed", + bsdar->filename); + continue; + } + } else { + /* stat success, file exist */ + if (bsdar->options & AR_CC) + continue; + if (bsdar->options & AR_U && + archive_entry_mtime(entry) <= + sb.st_mtime) + continue; + } + + if (bsdar->options & AR_V) + (void)fprintf(out, "x - %s\n", name); + /* Basic path security flags. */ + flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS | + ARCHIVE_EXTRACT_SECURE_NODOTDOT; + if (bsdar->options & AR_O) + flags |= ARCHIVE_EXTRACT_TIME; + + r = archive_read_extract(a, entry, flags); + } + + if (r) { + bsdar_warnc(bsdar, 0, "%s", + archive_error_string(a)); + exitcode = EXIT_FAILURE; + } + } + } + + if (r == ARCHIVE_FATAL) + exitcode = EXIT_FAILURE; + + AC(archive_read_close(a)); + ACV(archive_read_free(a)); + + return (exitcode); +} diff --git a/contrib/elftoolchain/ar/util.c b/contrib/elftoolchain/ar/util.c new file mode 100644 index 0000000000..f22542e67d --- /dev/null +++ b/contrib/elftoolchain/ar/util.c @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ar.h" + +ELFTC_VCSID("$Id: util.c 3174 2015-03-27 17:13:41Z emaste $"); + +static void bsdar_vwarnc(struct bsdar *, int code, + const char *fmt, va_list ap); +static void bsdar_verrc(struct bsdar *bsdar, int code, + const char *fmt, va_list ap); + +static void +bsdar_vwarnc(struct bsdar *bsdar, int code, const char *fmt, va_list ap) +{ + + fprintf(stderr, "%s: warning: ", bsdar->progname); + vfprintf(stderr, fmt, ap); + if (code != 0) + fprintf(stderr, ": %s", strerror(code)); + fprintf(stderr, "\n"); +} + +void +bsdar_warnc(struct bsdar *bsdar, int code, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + bsdar_vwarnc(bsdar, code, fmt, ap); + va_end(ap); +} + +static void +bsdar_verrc(struct bsdar *bsdar, int code, const char *fmt, va_list ap) +{ + + fprintf(stderr, "%s: fatal: ", bsdar->progname); + vfprintf(stderr, fmt, ap); + if (code != 0) + fprintf(stderr, ": %s", strerror(code)); + fprintf(stderr, "\n"); +} + +void +bsdar_errc(struct bsdar *bsdar, int code, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + bsdar_verrc(bsdar, code, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +#define AR_STRMODE_SIZE 12 +const char * +bsdar_strmode(mode_t m) +{ + static char buf[AR_STRMODE_SIZE]; + +#if ELFTC_HAVE_STRMODE + /* Use the system's strmode(3). */ + strmode(m, buf); + return buf; + +#else + char c; + + /* + * The first character of the string denotes the type of the + * entry. + */ + if (S_ISBLK(m)) + c = 'b'; + else if (S_ISCHR(m)) + c = 'c'; + else if (S_ISDIR(m)) + c = 'd'; +#if defined(S_ISFIFO) + else if (S_ISFIFO(m)) + c = 'p'; +#endif +#if defined(S_ISLNK) + else if (S_ISLNK(m)) + c = 'l'; +#endif + else if (S_ISREG(m)) + c = '-'; +#if defined(S_ISSOCK) + else if (S_ISSOCK(m)) + c = 's'; +#endif + else + c = '?'; + buf[0] = c; + + /* The next 3 characters show permissions for the owner. */ + buf[1] = (m & S_IRUSR) ? 'r' : '-'; + buf[2] = m & S_IWUSR ? 'w' : '-'; + if (m & S_ISUID) + c = (m & S_IXUSR) ? 's' : 'S'; + else + c = (m & S_IXUSR) ? 'x' : '-'; + buf[3] = c; + + /* The next 3 characters describe permissions for the group. */ + buf[4] = (m & S_IRGRP) ? 'r' : '-'; + buf[5] = m & S_IWGRP ? 'w' : '-'; + if (m & S_ISGID) + c = (m & S_IXGRP) ? 's' : 'S'; + else + c = (m & S_IXGRP) ? 'x' : '-'; + buf[6] = c; + + + /* The next 3 characters describe permissions for others. */ + buf[7] = (m & S_IROTH) ? 'r' : '-'; + buf[8] = m & S_IWOTH ? 'w' : '-'; + if (m & S_ISVTX) /* sticky bit */ + c = (m & S_IXOTH) ? 't' : 'T'; + else + c = (m & S_IXOTH) ? 'x' : '-'; + buf[9] = c; + + /* End the string with a blank and NUL-termination. */ + buf[10] = ' '; + buf[11] = '\0'; + + return buf; +#endif /* !ELTC_HAVE_STRMODE */ +} + +int +bsdar_is_pseudomember(struct bsdar *bsdar, const char *name) +{ + /* + * The "__.SYMDEF" member is special in the BSD format + * variant. + */ + if (bsdar->options & AR_BSD) + return (strcmp(name, AR_SYMTAB_NAME_BSD) == 0); + else + /* + * The names "/ " and "// " are special in the SVR4 + * variant. + */ + return (strcmp(name, AR_STRINGTAB_NAME_SVR4) == 0 || + strcmp(name, AR_SYMTAB_NAME_SVR4) == 0); +} diff --git a/contrib/elftoolchain/ar/write.c b/contrib/elftoolchain/ar/write.c new file mode 100644 index 0000000000..f712c45490 --- /dev/null +++ b/contrib/elftoolchain/ar/write.c @@ -0,0 +1,986 @@ +/*- + * Copyright (c) 2007 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ar.h" + +ELFTC_VCSID("$Id: write.c 3812 2020-02-07 02:18:26Z emaste $"); + +#define _ARMAG_LEN 8 /* length of the magic string */ +#define _ARHDR_LEN 60 /* length of the archive header */ +#define _INIT_AS_CAP 128 /* initial archive string table size */ +#define _INIT_SYMOFF_CAP (256*(sizeof(uint32_t))) /* initial so table size */ +#define _INIT_SYMNAME_CAP 1024 /* initial sn table size */ +#define _MAXNAMELEN_SVR4 15 /* max member name length in svr4 variant */ +#define _MAXNAMELEN_BSD 16 /* max member name length in bsd variant */ +#define _TRUNCATE_LEN 15 /* number of bytes to keep for member name */ + +static void add_to_ar_str_table(struct bsdar *bsdar, const char *name); +static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name); +static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, + const char *name, time_t mtime); +static void create_symtab_entry(struct bsdar *bsdar, Elf *e); +static void free_obj(struct ar_obj *obj); +static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, + struct ar_obj *pos); +static void read_objs(struct bsdar *bsdar, const char *archive, + int checkargv); +static void write_cleanup(struct bsdar *bsdar); +static void write_data(struct bsdar *bsdar, struct archive *a, + const void *buf, size_t s); +static void write_objs(struct bsdar *bsdar); + +/* + * Create an object from a file, and return the created object + * descriptor. Return NULL if either an error occurs, or if the '-u' + * option was specified and the member is not newer than the existing + * one in the archive. + */ +static struct ar_obj * +create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime) +{ + struct ar_obj *obj; + struct stat sb; + const char *bname; + char *tmpname; + int fd; + + if (name == NULL) + return (NULL); + + obj = malloc(sizeof(struct ar_obj)); + if (obj == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + + obj->elf = NULL; + + if ((fd = open(name, O_RDONLY, 0)) < 0) { + bsdar_warnc(bsdar, errno, "can't open file: %s", name); + free(obj); + return (NULL); + } + + tmpname = strdup(name); + if ((bname = basename(tmpname)) == NULL) + bsdar_errc(bsdar, errno, "basename failed"); + if (bsdar->options & AR_TR && strlen(bname) > _TRUNCATE_LEN) { + if ((obj->name = malloc(_TRUNCATE_LEN + 1)) == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + (void)strncpy(obj->name, bname, _TRUNCATE_LEN); + obj->name[_TRUNCATE_LEN] = '\0'; + } else + if ((obj->name = strdup(bname)) == NULL) + bsdar_errc(bsdar, errno, "strdup failed"); + free(tmpname); + + if (fstat(fd, &sb) < 0) { + bsdar_warnc(bsdar, errno, "can't fstat file: %s", obj->name); + goto giveup; + } + if (!S_ISREG(sb.st_mode)) { + bsdar_warnc(bsdar, 0, "%s is not an ordinary file", obj->name); + goto giveup; + } + + if (sb.st_dev == bsdar->ar_dev && sb.st_ino == bsdar->ar_ino) { + bsdar_warnc(bsdar, 0, "cannot add archive \"%s\" to itself", + obj->name); + goto giveup; + } + + /* + * If the '-u' option is specified and member is not newer + * than the existing one, we should not replace the member. + * However, if mtime == 0, i.e., if nonexistent members are to + * be forcibly replaced, then the '-u' option is to be ignored. + */ + if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime) + goto giveup; + + /* + * When the '-D' option is specified, the mtime and UID/GID of + * the member will be set to 0, and the file mode will be set + * to 644. This ensures that checksums will match for two + * archives containing identical content. + */ + if (bsdar->options & AR_D) { + obj->uid = 0; + obj->gid = 0; + obj->mtime = 0; + obj->md = S_IFREG | 0644; + } else { + obj->uid = sb.st_uid; + obj->gid = sb.st_gid; + obj->mtime = sb.st_mtime; + obj->md = sb.st_mode; + } + obj->size = sb.st_size; + obj->dev = sb.st_dev; + obj->ino = sb.st_ino; + + if (obj->size == 0) { + return (obj); + } + + if ((obj->elf = elf_open(fd)) == NULL) { + bsdar_warnc(bsdar, 0, "file initialization failed for %s: %s", + obj->name, elf_errmsg(-1)); + goto giveup; + } + + /* + * Read the object fully into memory and close its file + * descriptor. + */ + if (elf_cntl(obj->elf, ELF_C_FDREAD) < 0) { + bsdar_warnc(bsdar, 0, "%s could not be read in: %s", + obj->name, elf_errmsg(-1)); + goto giveup; + } + + if (close(fd) < 0) + bsdar_errc(bsdar, errno, "close failed: %s", + obj->name); + + return (obj); + +giveup: + if (obj->elf) + elf_end(obj->elf); + + if (close(fd) < 0) + bsdar_errc(bsdar, errno, "close failed: %s", + obj->name); + free(obj->name); + free(obj); + return (NULL); +} + +/* + * Free an object and its associated allocations. + */ +static void +free_obj(struct ar_obj *obj) +{ + if (obj->elf) + elf_end(obj->elf); + + free(obj->name); + free(obj); +} + +/* + * Insert an object into a list, either before/after the 'pos' obj or + * at the end of the list. + */ +static void +insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos) +{ + if (obj == NULL) + bsdar_errc(bsdar, 0, "try to insert a null obj"); + + if (pos == NULL || obj == pos) + /* + * If the object to move happens to be the position + * obj, or if there is no position obj, move the + * object to the end. + */ + goto tail; + + if (bsdar->options & AR_B) { + TAILQ_INSERT_BEFORE(pos, obj, objs); + return; + } + if (bsdar->options & AR_A) { + TAILQ_INSERT_AFTER(&bsdar->v_obj, pos, obj, objs); + return; + } + +tail: + TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); + +} + +/* + * Read objects from archive into the 'v_obj' list. Note that + * 'checkargv' is set when read_objs() is used to read objects from + * the target of 'ADDLIB' command in ar script mode; in this case the + * 'argv' array specifies the members that 'ADDLIB' is to operate on. + */ +static void +read_objs(struct bsdar *bsdar, const char *archive, int checkargv) +{ + struct archive *a; + struct archive_entry *entry; + struct ar_obj *obj; + const char *name; + const char *bname; + char *buff; + char **av; + size_t size; + int i, r, find; + + if ((a = archive_read_new()) == NULL) + bsdar_errc(bsdar, 0, "archive_read_new failed"); + archive_read_support_format_ar(a); + AC(archive_read_open_filename(a, archive, DEF_BLKSZ)); + for (;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_FATAL) + bsdar_errc(bsdar, 0, "%s", archive_error_string(a)); + if (r == ARCHIVE_EOF) + break; + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) + bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); + if (r == ARCHIVE_RETRY) { + bsdar_warnc(bsdar, 0, "Retrying..."); + continue; + } + + name = archive_entry_pathname(entry); + + /* + * Skip pseudo members. + */ + if (bsdar_is_pseudomember(bsdar, name)) + continue; + + /* + * If 'checkargv' is set, only read those members + * specified in argv. + */ + if (checkargv && bsdar->argc > 0) { + find = 0; + for(i = 0; i < bsdar->argc; i++) { + av = &bsdar->argv[i]; + if (*av == NULL) + continue; + if ((bname = basename(*av)) == NULL) + bsdar_errc(bsdar, errno, + "basename failed"); + if (strcmp(bname, name) != 0) + continue; + + *av = NULL; + find = 1; + break; + } + if (!find) + continue; + } + + size = archive_entry_size(entry); + + if (size > 0) { + if ((buff = malloc(size)) == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + if (archive_read_data(a, buff, size) != (ssize_t)size) { + bsdar_warnc(bsdar, 0, "%s", + archive_error_string(a)); + free(buff); + continue; + } + } else + buff = NULL; + + obj = malloc(sizeof(struct ar_obj)); + if (obj == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + obj->elf = NULL; + if (buff) { + obj->elf = elf_openmemory(buff, size); + if (obj->elf == NULL) { + bsdar_warnc(bsdar, 0, "elf_openmemory() " + "failed for %s: %s", name, + elf_errmsg(-1)); + free(buff); + free(obj); + continue; + } + } + if ((obj->name = strdup(name)) == NULL) + bsdar_errc(bsdar, errno, "strdup failed"); + obj->size = size; + obj->uid = archive_entry_uid(entry); + obj->gid = archive_entry_gid(entry); + obj->md = archive_entry_mode(entry); + obj->mtime = archive_entry_mtime(entry); + obj->dev = 0; + obj->ino = 0; + + TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); + } + AC(archive_read_close(a)); + ACV(archive_read_free(a)); +} + +/* + * Write an archive. + * + * Returns EXIT_SUCCESS if the write succeeded or EXIT_FAILURE otherwise. + */ +int +ar_write_archive(struct bsdar *bsdar, int mode) +{ + struct ar_obj *nobj, *obj, *obj_temp, *pos; + struct stat sb; + const char *bname; + char **av; + int exitcode, i; + + TAILQ_INIT(&bsdar->v_obj); + exitcode = EXIT_SUCCESS; + nobj = NULL; + pos = NULL; + memset(&sb, 0, sizeof(sb)); + + assert(mode == 'A' || mode == 'd' || mode == 'm' || mode == 'q' || + mode == 'r' || mode == 's'); + + /* + * Test if the specified archive exists, to determine + * whether we are creating a new archive. + */ + if (stat(bsdar->filename, &sb) != 0) { + if (errno != ENOENT) { + bsdar_warnc(bsdar, errno, "stat %s failed", + bsdar->filename); + return (EXIT_FAILURE); + } + + /* We do not create archive in mode 'd', 'm' and 's'. */ + if (mode != 'r' && mode != 'q') { + bsdar_warnc(bsdar, 0, "%s: no such file", + bsdar->filename); + return (EXIT_FAILURE); + } + + /* Issue a message if the '-c' option was not specified. */ + if (!(bsdar->options & AR_C)) + bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename); + goto new_archive; + } + + bsdar->ar_dev = sb.st_dev; + bsdar->ar_ino = sb.st_ino; + + /* + * First read members from the existing archive. + */ + read_objs(bsdar, bsdar->filename, 0); + + /* + * For mode 's', no member will be moved, deleted or replaced. + */ + if (mode == 's') + goto write_objs; + + /* + * For mode 'q', we don't need to adjust existing members either. + * Also, -a, -b and -i are ignored in this mode. New members are + * always inserted at tail. + */ + if (mode == 'q') + goto new_archive; + + /* + * Mode 'A' adds the contents of another archive to the tail + * of current archive. Note that mode 'A' is a special mode + * for the 'ADDLIB' command in ar's script mode. Currently + * there is no option that invokes this function from ar's + * command line. + */ + if (mode == 'A') { + /* + * Read objects from the target archive of the + * 'ADDLIB' command. If there are members specified in + * 'argv', read those members only, otherwise the + * entire archive will be read. + */ + read_objs(bsdar, bsdar->addlib, 1); + goto write_objs; + } + + /* + * Try to find the position member specified by user. + */ + if (bsdar->options & AR_A || bsdar->options & AR_B) { + TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { + if (strcmp(obj->name, bsdar->posarg) == 0) { + pos = obj; + break; + } + } + + /* + * If we cannot find the position specified by the + * user, silently insert objects at the tail of the + * list. + */ + if (pos == NULL) + bsdar->options &= ~(AR_A | AR_B); + } + + for (i = 0; i < bsdar->argc; i++) { + av = &bsdar->argv[i]; + + TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { + if ((bname = basename(*av)) == NULL) + bsdar_errc(bsdar, errno, "basename failed"); + if (bsdar->options & AR_TR) { + if (strncmp(bname, obj->name, _TRUNCATE_LEN)) + continue; + } else + if (strcmp(bname, obj->name) != 0) + continue; + + if (mode == 'r') { + /* + * If the new member should not + * replace the old one, skip it. + */ + nobj = create_obj_from_file(bsdar, *av, + obj->mtime); + if (nobj == NULL) { + exitcode = EXIT_FAILURE; + goto skip_obj; + } + } + + if (bsdar->options & AR_V) + (void)fprintf(bsdar->output, "%c - %s\n", + mode, *av); + + TAILQ_REMOVE(&bsdar->v_obj, obj, objs); + if (mode == 'd' || mode == 'r') + free_obj(obj); + + if (mode == 'm') + insert_obj(bsdar, obj, pos); + if (mode == 'r') + insert_obj(bsdar, nobj, pos); + + skip_obj: + *av = NULL; + break; + } + + } + +new_archive: + /* + * When operating in mode 'r', directly add the specified + * objects which do not exist in current archive. When + * operating in mode 'q', all objects specified by the command + * line args are appended to the archive, without checking + * existing members in the archive. + */ + for (i = 0; i < bsdar->argc; i++) { + av = &bsdar->argv[i]; + if (*av != NULL && (mode == 'r' || mode == 'q')) { + nobj = create_obj_from_file(bsdar, *av, 0); + if (nobj == NULL) { + exitcode = EXIT_FAILURE; + *av = NULL; + continue; + } + insert_obj(bsdar, nobj, pos); + if (bsdar->options & AR_V) + (void)fprintf(bsdar->output, "a - %s\n", *av); + *av = NULL; + } + } + +write_objs: + write_objs(bsdar); + write_cleanup(bsdar); + + return (exitcode); +} + +/* + * Release memory. + */ +static void +write_cleanup(struct bsdar *bsdar) +{ + struct ar_obj *obj, *obj_temp; + + TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { + TAILQ_REMOVE(&bsdar->v_obj, obj, objs); + free_obj(obj); + } + + free(bsdar->as); + free(bsdar->s_so); + free(bsdar->s_sn); + bsdar->as = NULL; + bsdar->s_so = NULL; + bsdar->s_sn = NULL; +} + +/* + * Wrapper for archive_write_data(). + */ +static void +write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s) +{ + if (archive_write_data(a, buf, s) != (ssize_t)s) + bsdar_errc(bsdar, 0, "%s", archive_error_string(a)); +} + +/* + * Compute the size of the symbol table for an archive. + */ +static size_t +bsdar_symtab_size(struct bsdar *bsdar) +{ + size_t sz; + + if (bsdar->options & AR_BSD) { + /* + * A BSD style symbol table has two parts. + * Each part is preceded by its size in bytes, + * encoded as a C 'long'. In the first part, + * there are 's_cnt' entries, each entry being + * 2 'long's in size. The second part + * contains a string table. + */ + sz = 2 * sizeof(long) + (bsdar->s_cnt * 2 * sizeof(long)) + + bsdar->s_sn_sz; + } else { + /* + * An SVR4 style symbol table comprises of a 32 bit + * number holding the number of entries, followed by + * that many 32-bit offsets, followed by a string + * table. + */ + sz = sizeof(uint32_t) + bsdar->s_cnt * sizeof(uint32_t) + + bsdar->s_sn_sz; + } + + return (sz); +} + +static void +write_svr4_symtab_entry(struct bsdar *bsdar, struct archive *a) +{ + int nr; + uint32_t i; + + /* Translate offsets to big-endian form. */ + for (i = 0; i < bsdar->s_cnt; i++) + bsdar->s_so[i] = htobe32(bsdar->s_so[i]); + + nr = htobe32(bsdar->s_cnt); + write_data(bsdar, a, &nr, sizeof(uint32_t)); + write_data(bsdar, a, bsdar->s_so, sizeof(uint32_t) * + bsdar->s_cnt); + write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz); +} + +static void +write_bsd_symtab_entry(struct bsdar *bsdar, struct archive *a) +{ + long br_sz, br_off, br_strx; + char *s; + uint32_t i; + + /* + * Write out the size in the byte of the array of 'ranlib' + * descriptors to follow. + */ + + br_sz = (long) (bsdar->s_cnt * 2 * sizeof(long)); + write_data(bsdar, a, &br_sz, sizeof(long)); + + /* + * Write out the array of 'ranlib' descriptors. Each + * descriptor comprises of (a) an offset into the following + * string table and (b) a file offset to the relevant member. + */ + for (i = 0, s = bsdar->s_sn; i < bsdar->s_cnt; i++) { + br_strx = (long) (s - bsdar->s_sn); + br_off = (long) bsdar->s_so[i]; + write_data(bsdar, a, &br_strx, sizeof(long)); + write_data(bsdar, a, &br_off, sizeof(long)); + + /* Find the start of the next symbol in the string table. */ + while (*s++ != '\0') + ; + } + + /* + * Write out the size of the string table as a 'long', + * followed by the string table itself. + */ + br_sz = (long) bsdar->s_sn_sz; + write_data(bsdar, a, &br_sz, sizeof(long)); + write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz); +} + + +/* + * Write the resulting archive members. + */ +static void +write_objs(struct bsdar *bsdar) +{ + struct ar_obj *obj; + struct archive *a; + struct archive_entry *entry; + size_t s_sz; /* size of archive symbol table. */ + size_t pm_sz; /* size of pseudo members */ + size_t namelen; /* size of member name. */ + size_t obj_sz; /* size of object + extended header. */ + int i; + char *buf; + const char *entry_name; + + bsdar->rela_off = 0; + + /* + * Create the archive symbol table and the archive string + * table, if needed. + */ + TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { + if (!(bsdar->options & AR_SS) && obj->elf != NULL) + create_symtab_entry(bsdar, obj->elf); + + obj_sz = 0; + namelen = strlen(obj->name); + if (bsdar->options & AR_BSD) { + /* Account for the space used by the file name. */ + if (namelen > _MAXNAMELEN_BSD || + strchr(obj->name, ' ')) + obj_sz += namelen; + } else if (namelen > _MAXNAMELEN_SVR4) + add_to_ar_str_table(bsdar, obj->name); + + obj_sz += obj->size; /* add the actual object size */ + + /* Roundup the final size and add the header length. */ + bsdar->rela_off += _ARHDR_LEN + obj_sz + (obj_sz & 1); + } + + /* + * Pad the symbol name string table. It is treated specially + * because symbol name table should be padded by a '\0', and + * not '\n' as for normal members. The size of the 'sn' table + * includes the pad byte. + */ + if (bsdar->s_cnt != 0 && bsdar->s_sn_sz % 2 != 0) + bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; + + /* + * The archive string table is padded by a "\n" like a normal + * member. The difference is that the size of archive string + * table includes the pad byte, while normal members' size + * fields do not. + */ + if (bsdar->as != NULL && bsdar->as_sz % 2 != 0) + bsdar->as[bsdar->as_sz++] = '\n'; + + /* + * If there is a symbol table, calculate the size of pseudo + * members, and convert previously stored relative offsets to + * absolute ones. + * + * absolute_offset = relative_offset + size_of_pseudo_members) + */ + + s_sz = bsdar_symtab_size(bsdar); + if (bsdar->s_cnt != 0) { + pm_sz = _ARMAG_LEN + (_ARHDR_LEN + s_sz); + if (bsdar->as != NULL) /* SVR4 archives only */ + pm_sz += _ARHDR_LEN + bsdar->as_sz; + for (i = 0; (size_t) i < bsdar->s_cnt; i++) + bsdar->s_so[i] = bsdar->s_so[i] + pm_sz; + } + + if ((a = archive_write_new()) == NULL) + bsdar_errc(bsdar, 0, "archive_write_new failed"); + + if (bsdar->options & AR_BSD) + archive_write_set_format_ar_bsd(a); + else + archive_write_set_format_ar_svr4(a); + + AC(archive_write_open_filename(a, bsdar->filename)); + + /* + * Write the archive symbol table, if there is one. If + * options '-s' was explicitly specified or if we were invoked + * as 'ranlib', write the symbol table even if it is empty. + */ + if ((bsdar->s_cnt != 0 && !(bsdar->options & AR_SS)) || + bsdar->options & AR_S) { + if (bsdar->options & AR_BSD) + entry_name = AR_SYMTAB_NAME_BSD; + else + entry_name = AR_SYMTAB_NAME_SVR4; + + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, entry_name); + if ((bsdar->options & AR_D) == 0) + archive_entry_set_mtime(entry, time(NULL), 0); + archive_entry_set_size(entry, s_sz); + AC(archive_write_header(a, entry)); + if (bsdar->options & AR_BSD) + write_bsd_symtab_entry(bsdar, a); + else + write_svr4_symtab_entry(bsdar, a); + archive_entry_free(entry); + } + + /* Write the archive string table, if any. */ + if (bsdar->as != NULL) { + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, AR_STRINGTAB_NAME_SVR4); + archive_entry_set_size(entry, bsdar->as_sz); + AC(archive_write_header(a, entry)); + write_data(bsdar, a, bsdar->as, bsdar->as_sz); + archive_entry_free(entry); + } + + /* Write normal members. */ + TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { + if ((buf = elf_rawfile(obj->elf, NULL)) == NULL) { + bsdar_warnc(bsdar, 0, "elf_rawfile() failed: %s", + elf_errmsg(-1)); + continue; + } + + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, obj->name); + archive_entry_set_uid(entry, obj->uid); + archive_entry_set_gid(entry, obj->gid); + archive_entry_set_mode(entry, obj->md); + archive_entry_set_size(entry, obj->size); + archive_entry_set_mtime(entry, obj->mtime, 0); + archive_entry_set_dev(entry, obj->dev); + archive_entry_set_ino(entry, obj->ino); + archive_entry_set_filetype(entry, AE_IFREG); + AC(archive_write_header(a, entry)); + write_data(bsdar, a, buf, obj->size); + archive_entry_free(entry); + } + + AC(archive_write_close(a)); + ACV(archive_write_free(a)); +} + +/* + * Extract global symbols from ELF binary members. + */ +static void +create_symtab_entry(struct bsdar *bsdar, Elf *e) +{ + Elf_Scn *scn; + GElf_Shdr shdr; + GElf_Sym sym; + Elf_Data *data; + char *name; + size_t n, shstrndx; + int elferr, tabndx, len, i; + + if (elf_kind(e) != ELF_K_ELF) { + /* Silently a ignore non-ELF member. */ + return; + } + if (elf_getshstrndx(e, &shstrndx) == 0) { + bsdar_warnc(bsdar, 0, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + return; + } + + tabndx = -1; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) { + bsdar_warnc(bsdar, 0, + "elf_getshdr failed: %s", elf_errmsg(-1)); + continue; + } + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) { + bsdar_warnc(bsdar, 0, + "elf_strptr failed: %s", elf_errmsg(-1)); + continue; + } + if (strcmp(name, ".strtab") == 0) { + tabndx = elf_ndxscn(scn); + break; + } + } + elferr = elf_errno(); + if (elferr != 0) + bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + if (tabndx == -1) { + bsdar_warnc(bsdar, 0, "can't find .strtab section"); + return; + } + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) { + bsdar_warnc(bsdar, 0, "elf_getshdr failed: %s", + elf_errmsg(-1)); + continue; + } + if (shdr.sh_type != SHT_SYMTAB) + continue; + + data = NULL; + n = 0; + while (n < shdr.sh_size && + (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getsym(data, i, &sym) != &sym) { + bsdar_warnc(bsdar, 0, + "gelf_getsym failed: %s", + elf_errmsg(-1)); + continue; + } + + /* Keep only global and weak symbols. */ + if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL && + GELF_ST_BIND(sym.st_info) != STB_WEAK) + continue; + + /* Keep only defined symbols. */ + if (sym.st_shndx == SHN_UNDEF) + continue; + + if ((name = elf_strptr(e, tabndx, + sym.st_name)) == NULL) { + bsdar_warnc(bsdar, 0, + "elf_strptr failed: %s", + elf_errmsg(-1)); + continue; + } + + add_to_ar_sym_table(bsdar, name); + } + } + } + elferr = elf_errno(); + if (elferr != 0) + bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +/* + * Append to the archive string table buffer. + */ +static void +add_to_ar_str_table(struct bsdar *bsdar, const char *name) +{ + + if (bsdar->as == NULL) { + bsdar->as_cap = _INIT_AS_CAP; + bsdar->as_sz = 0; + if ((bsdar->as = malloc(bsdar->as_cap)) == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + } + + /* + * The space required for holding one member name in the 'as' + * table includes: strlen(name) + (1 for '/') + (1 for '\n') + + * (possibly 1 for padding). + */ + while (bsdar->as_sz + strlen(name) + 3 > bsdar->as_cap) { + bsdar->as_cap *= 2; + bsdar->as = realloc(bsdar->as, bsdar->as_cap); + if (bsdar->as == NULL) + bsdar_errc(bsdar, errno, "realloc failed"); + } + strncpy(&bsdar->as[bsdar->as_sz], name, strlen(name)); + bsdar->as_sz += strlen(name); + bsdar->as[bsdar->as_sz++] = '/'; + bsdar->as[bsdar->as_sz++] = '\n'; +} + +/* + * Append to the archive symbol table buffer. + */ +static void +add_to_ar_sym_table(struct bsdar *bsdar, const char *name) +{ + + if (bsdar->s_so == NULL) { + if ((bsdar->s_so = malloc(_INIT_SYMOFF_CAP)) == + NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + bsdar->s_so_cap = _INIT_SYMOFF_CAP; + bsdar->s_cnt = 0; + } + + if (bsdar->s_sn == NULL) { + if ((bsdar->s_sn = malloc(_INIT_SYMNAME_CAP)) == NULL) + bsdar_errc(bsdar, errno, "malloc failed"); + bsdar->s_sn_cap = _INIT_SYMNAME_CAP; + bsdar->s_sn_sz = 0; + } + + if (bsdar->s_cnt * sizeof(uint32_t) >= bsdar->s_so_cap) { + bsdar->s_so_cap *= 2; + bsdar->s_so = realloc(bsdar->s_so, bsdar->s_so_cap); + if (bsdar->s_so == NULL) + bsdar_errc(bsdar, errno, "realloc failed"); + } + bsdar->s_so[bsdar->s_cnt] = bsdar->rela_off; + bsdar->s_cnt++; + + /* + * The space required for holding one symbol name in the 'sn' + * table includes: strlen(name) + (1 for '\n') + (possibly 1 + * for padding). + */ + while (bsdar->s_sn_sz + strlen(name) + 2 > bsdar->s_sn_cap) { + bsdar->s_sn_cap *= 2; + bsdar->s_sn = realloc(bsdar->s_sn, bsdar->s_sn_cap); + if (bsdar->s_sn == NULL) + bsdar_errc(bsdar, errno, "realloc failed"); + } + memcpy(&bsdar->s_sn[bsdar->s_sn_sz], name, strlen(name)); + bsdar->s_sn_sz += strlen(name); + bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; +} diff --git a/contrib/elftoolchain/as/Makefile b/contrib/elftoolchain/as/Makefile new file mode 100644 index 0000000000..2047b1959c --- /dev/null +++ b/contrib/elftoolchain/as/Makefile @@ -0,0 +1,14 @@ +# $Id: Makefile 2797 2012-12-21 18:10:25Z jkoshy $ + +TOP= .. + +PROG= as +SRCS= as.c + +LSRC= +YSRC= +LDADD= -lelftc + +MAN= as.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/as/as.1 b/contrib/elftoolchain/as/as.1 new file mode 100644 index 0000000000..dde96c0b82 --- /dev/null +++ b/contrib/elftoolchain/as/as.1 @@ -0,0 +1,211 @@ +.\" Copyright (c) 2012 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: as.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd December 22, 2012 +.Dt AS 1 +.Os +.Sh NAME +.Nm as +.Nd an assembler +.Sh SYNOPSIS +.Nm +.Op Fl D +.Op Fl I Ar dir +.Op Fl J +.Op Fl K +.Op Fl L | Fl -keep-locals +.Op Fl R +.Op Fl V +.Op Fl W | Fl -no-warn +.Op Fl Z +.Op Fl a Ns Oo Ar cdghlns Oc Ns Oo Ar =filename Oc +.Op Fl g | Fl -gen-debug +.Op Fl h | Fl -help +.Op Fl march= Ns Ar cpu Ns Oo ,+ Ns Oo Ar extensions Oc Ns "..." Oc +.Op Fl mtune= Ns Ar cpu +.Op Fl n +.Op Fl o Ar obj +.Op Fl q +.Op Fl -MD Ar file +.Op Fl -defsym Ar symbol Ns = Ns Ar value +.Op Fl -fatal-warnings +.Op Fl -listing-lhs-width +.Op Fl -listing-lhs-width2 +.Op Fl -listing-rhs-width +.Op Fl -listing-cont-lines +.Op Fl -statistics +.Op Fl -strip-local-absolute +.Op Fl -target-help +.Op Fl -version +.Op Fl -warn +.Op Ar target-options +.Op Ar +.Sh DESCRIPTION +The +.Nm +utility creates an ELF relocatable object from assembly language +sources. +.Pp +If multiple source files are specified, +.Nm +will read each of them in the order specified. +If no files are specified, +.Nm +will read from standard input. +.Pp +The +.Nm +utility understands the following options: +.Bl -tag -width indent +.It Fl D +Display internal debugging messages. +.It Fl I Ar dir +Add the directory named by argument +.Ar dir +to the search path used by the +.Ic ".include" +directive. +.It Fl J +Suppress warnings about overflows in signed arithmetic. +.It Fl K +Warn about alterations to difference tables if any. +.It Fl L | Fl -keep-locals +Keep local symbols in the output file. +The default is to discard local symbols. +.It Fl R +Merge the +.Li .data +and +.Li .text +sections when creating an object. +.It Fl V +Print the assembler version on standard output before assembling +the inputs. +.It Fl W | Fl -no-warn +Suppress assembler warnings. +.It Fl Z +Generate an output object even if there were errors in the input. +.It Fl a Ns Oo Ar cdghlns Oc Ns Oo Ar =filename Oc +Control generated listings. +The supported flags are: +.Bl -tag -width indent -compact +.It c +Omit listing code in false conditional paths. +.It d +Omit debugging directives. +.It g +Include the version of the assembler and other general information +in the generated listing. +.It h +Include high-level source in the listing. +.It l +Include assembly source in the listing. +.It m +Include macro expansions in the listing. +.It n +Suppress generation of the header and footer in the listing. +.It s +Include symbol information in the listing. +.It = Ns Ar filename +Set the name of the listing file to that specified by argument +.Ar filename . +If specified, this flag must be the last in the list. +.El +If option +.Fl a +is specified without additional arguments, a flag set of +.Sq Ar hls +is assumed. +.It Fl g | Fl -gen-debug +Generate debug information in DWARF format. +.It Fl h | Fl -help +Show a help message and exit. +.It Fl march Ns = Ns Ar cpu Ns Oo ,+ Ns Oo Ar extensions Oc Ns "..." Oc +Generated code for the CPU named by argument +.Ar cpu +with additional instruction set extensions named by the argument +.Ar extensions . +.It Fl mtune Ns = Ns Ar cpu +Optimize the assembled object for the CPU named by the argument +.Ar cpu . +.It Fl n +Do not optimize code alignment. +.It Fl o Ar filename +Write the assembled output to the file named by argument +.Ar filename . +.It Fl q +Suppress warnings. +.It Fl -MD Ar filename +Write dependency information in a form usable by +.Xr make 1 +to the file name by argument +.Ar filename . +.It Fl -defsym Ar symbol Ns = Ns Ar value +Define symbol named by the argument +.Ar symbol +as having the value named by +.Ar value . +The argument value is an integer in one of the forms accepted +by +.Xr atoi 3 . +.It Fl -fatal-warnings +Treat all warnings as fatal. +.It Fl -listing-lhs-width Ns = Ns Ar nwords +Set the width of the output data column in a listing to the number +of machine words specified in argument +.Ar nwords . +.It Fl -listing-lhs-width2 Ns = Ns Ar nwords +Set the width of continuation lines for the data column to the number +of machine words specified in argument +.Ar nwords . +.It Fl -listing-rhs-width Ns = Ns Ar nchars +Set the maximum displayed width of an input source line to the number +of characters specified by argument +.Ar nchars . +.It Fl -listing-cont-lines Ns = Ns Ar nlines +Set the maximum number of listing lines generated by one input source +line to +.Ar nlines Ns No + Ns 1 . +.It Fl -statistics +Print statistics for the run at exit. +.It Fl -strip-local-absolute +Remove local absolute symbols from the generated output. +.It Fl -target-help +Display help for the target CPU. +.It Fl -version +Print a version identifier and exit. +.It Fl -warn +Print warnings. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr elfcopy 1 , +.Xr ld 1 , +.Xr nm 1 , +.Xr strings 1 , +.Xr strip 1 , +.Xr elf 5 diff --git a/contrib/elftoolchain/as/as.c b/contrib/elftoolchain/as/as.c new file mode 100644 index 0000000000..abc70a0fbb --- /dev/null +++ b/contrib/elftoolchain/as/as.c @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2012 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +#include + +ELFTC_VCSID("$Id: as.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +enum as_long_option_index { + AS_OPT_DEFSYM, + AS_OPT_FATAL_WARNINGS, + AS_OPT_LCL, + AS_OPT_LLW, + AS_OPT_LLW2, + AS_OPT_LRW, + AS_OPT_MD, + AS_OPT_STATISTICS, + AS_OPT_STRIP_LOCAL_ABSOLUTE, + AS_OPT_TARGET_HELP, + AS_OPT_VERSION, + AS_OPT_WARN, + AS_OPT__LAST +}; + +struct as_options { + unsigned int as_listing_flags; +}; + +#define AS_OPTION_SHORT_OPTIONS ":a:fghm:no:qswDI:JKLMRVWXZ" +const struct option as_option_long_options[] = { + { "defsym", required_argument, NULL, AS_OPT_DEFSYM }, + { "fatal-warnings", no_argument, NULL, AS_OPT_FATAL_WARNINGS }, + { "gen-debug", no_argument, NULL, 'g' }, + { "help", no_argument, NULL, 'h' }, + { "keep-locals", no_argument, NULL, 'L' }, + { "listing-lhs-width", required_argument, NULL, AS_OPT_LLW }, + { "listing-lhs-width2", required_argument, NULL, AS_OPT_LLW2 }, + { "listing-rhs-width", required_argument, NULL, AS_OPT_LRW }, + { "listing-cont-lines", required_argument, NULL, AS_OPT_LCL }, + { "mri", no_argument, NULL, 'M' }, + { "no-warn", no_argument, NULL, 'W' }, + { "statistics", no_argument, NULL, AS_OPT_STATISTICS }, + { "strip-local-absolute", no_argument, NULL, + AS_OPT_STRIP_LOCAL_ABSOLUTE }, + { "target-help", no_argument, NULL, AS_OPT_TARGET_HELP }, + { "version", no_argument, NULL, AS_OPT_VERSION }, + { "warn", no_argument, NULL, AS_OPT_WARN }, + { "MD", required_argument, NULL, AS_OPT_MD }, + { NULL, 0, NULL, 0 } +}; + +#define AS_OPTION_LISTING_DEFAULT "hls" + +#define AS_OPTION_USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Assemble an ELF object.\n\n\ + Options:\n\ + -D Print assembler debug messages.\n\ + -I DIR Add directory to the search list.\n\ + -J Suppress warnings about signed overflows.\n\ + -K Warn about alterations to difference tables.\n\ + -L | --keep-locals Keep local symbols.\n\ + -R Merge the data and text sections.\n\ + -V Display the assembler version number.\n\ + -W | --no-warn Suppress warnings.\n\ + -Z Generate the object even if there are errors.\n\ + -a[listing-options...] Control assembler listings.\n\ + -g | --gen-debug Generate debugging information.\n\ + -h | --help Show a help message.\n\ + -march=CPU[,+EXT...] Generate code for cpu CPU and extensions EXT.\n\ + -mtune=CPU Optimize for cpu CPU.\n\ + -n Do not optimize code alignment.\n\ + -o OBJ Write the assembled object to file OBJ.\n\ + -q Suppress some warnings.\n\ + --MD FILE Write dependency information to FILE.\n\ + --defsym SYMBOL=VALUE Define symbol SYMBOL with value VALUE.\n\ + --fatal-warnings Treat warnings as fatal errors.\n\ + --listing-lhs-width=NUM Set width of the output data column.\n\ + --listing-lhs-width2=NUM Set the width of continuation lines.\n\ + --listing-rhs-width=NUM Set the max width of source lines.\n\ + --listing-cont-lines=NUM Set the maximum number of continuation lines.\n\ + --statistics Print statistics at exit.\n\ + --strip-local-absolute Strip local absolute symbols.\n\ + --target-help Show target-specific help messages.\n\ + --version Print a version identifier and exit.\n\ + --warn Print warnings.\n\ + [target options] Target specific options.\n\n\ + Options '-f', '-s', '-w', '-M', '-X' and '--mri' are accepted for\n\ + compatibility with other assemblers, but are ignored.\n" + +void +as_option_usage(int exit_code, const char *format, ...) +{ + va_list args; + + if (format) { + va_start(args, format); + vwarnx(format, args); + va_end(args); + } + + (void) fprintf(exit_code != EX_OK ? stderr : stdout, + AS_OPTION_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + + exit(exit_code); +} + +static void +as_option_listing(char *flags) +{ + (void) flags; +} + +int +main(int argc, char **argv) +{ + int option, option_index; + + opterr = 0; /* Suppress error messages from getopt(). */ + + for (option_index = -1; + (option = getopt_long(argc, argv, AS_OPTION_SHORT_OPTIONS, + as_option_long_options, &option_index)) >= 0; + option_index = -1) + { + switch (option) { + + case AS_OPT_VERSION: + /* + * Print a version identifier and exit. + */ + (void) printf("%s (%s)\n", + ELFTC_GETPROGNAME(), elftc_version()); + exit(0); + break; + + case 'h': /* Display a help message. */ + as_option_usage(EX_OK, NULL); + break; + + case 'f': case 's': case 'w': case 'M': case 'X': + /* + * These options are accepted for compatibility + * reasons, but are ignored. + */ + break; + + case ':': + + /* + * A missing option argument: if the user + * supplied a bare '-a', supply a default set + * of listing control flags. + */ + if (optopt == 'a') + as_option_listing(AS_OPTION_LISTING_DEFAULT); + else + errx(1, "option \"-%c\" expects an " + "argument.", optopt); + break; + + case '?': /* An unknown option. */ + if (optopt) + as_option_usage(EX_USAGE, + "ERROR: unrecognized option '-%c'.", + optopt); + else + as_option_usage(EX_USAGE, + "ERROR: Unrecognized option \"--%s\".", + argv[optind-1]); + break; + + default: + if (option_index >= 0) + errx(1, + "ERROR: option \"--%s\" is unimplemented.", + as_option_long_options[option_index].name); + else + errx(1, + "ERROR: option '-%c' is unimplemented.", + option); + } + } + + exit(0); +} diff --git a/contrib/elftoolchain/brandelf/Makefile b/contrib/elftoolchain/brandelf/Makefile new file mode 100644 index 0000000000..28ba3e0df0 --- /dev/null +++ b/contrib/elftoolchain/brandelf/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile 2066 2011-10-26 15:40:28Z jkoshy $ + +TOP= .. + +PROG= brandelf +WARNS?= 6 +LDADD= -lelftc -lelf + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/brandelf/brandelf.1 b/contrib/elftoolchain/brandelf/brandelf.1 new file mode 100644 index 0000000000..8df5fa8cc8 --- /dev/null +++ b/contrib/elftoolchain/brandelf/brandelf.1 @@ -0,0 +1,147 @@ +.\" Copyright 1997 John-Mark Gurney. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.bin/brandelf/brandelf.1,v 1.17 2007/03/09 14:36:18 ru Exp $ +.\" $Id: brandelf.1 3235 2015-07-31 16:44:47Z emaste $ +.\" +.Dd October 27, 2014 +.Dt BRANDELF 1 +.Os +.Sh NAME +.Nm brandelf +.Nd mark an ELF binary for a specific ABI +.Sh SYNOPSIS +.Nm +.Op Fl V | Fl -version +.Op Fl f Ar ELF_ABI_number +.Op Fl h | Fl -help +.Op Fl l +.Op Fl t Ar brand +.Op Fl v +.Ar +.Sh DESCRIPTION +The +.Nm +utility marks an ELF binary to be run under a certain ABI. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl f Ar ELF_ABI_number +Forces branding with the supplied ELF ABI number. +Incompatible with the +.Fl t +option. +These values are assigned by SCO/USL. +.It Fl h | Fl -help +Print a usage message and exit. +.It Fl l +Writes the list of all known ELF types to standard output. +.It Fl t Ar brand +Brands the given ELF binaries to be of the ABI specified by argument +.Ar brand . +Supported ABIs include +.Dq Li 86Open , +.Dq Li AIX , +.Dq Li ARM , +.Dq Li AROS , +.Dq Li FreeBSD , +.Dq Li GNU , +.Dq Li HP/UX , +.Dq Li Hurd , +.Dq Li IRIX , +.Dq Li Linux +(an alias for +.Dq Li GNU ) , +.Dq Li Modesto , +.Dq Li NSK , +.Dq Li NetBSD , +.Dq Li None , +.Dq Li OpenBSD , +.Dq Li OpenVMS , +.Dq Li Standalone , +.Dq Li SVR4 +(an alias for +.Dq Li None ) , +.Dq Li Solaris +and +.Dq Li Tru64 . +.It Fl v +This option is accepted for compatibility with other versions of +.Nm , +but is otherwise ignored. +.It Fl V | Fl -version +Print a version identifier and exit. +.El +.Pp +If the options +.Fl f Ar ELF_ABI_number +or +.Fl t Ar brand +were specified, +.Nm +will brand the files named by command-line arguments +.Ar +to be of type +.Ar ELF_ABI_number +or +.Ar brand +respectively. +.Pp +If neither of the +.Fl f +or +.Fl t +options were specified, +.Nm +will display the current branding for the files named by the arguments +.Ar . +.Sh EXIT STATUS +Exit status is 0 on success, and 1 if the command +fails if a file does not exist, is too short, fails to brand properly, +or the brand requested is not one of the known types and the +.Fl f +option is not set. +.Sh EXAMPLES +The following is an example of a typical usage +of the +.Nm +command: +.Bd -literal -offset indent +brandelf file +brandelf -t GNU file +.Ed +.Sh SEE ALSO +.Rs +.%A The Santa Cruz Operation, Inc. +.%T System V Application Binary Interface +.%D April 29, 1998 (DRAFT) +.%O http://www.sco.com/developer/devspecs/ +.Re +.Sh HISTORY +The +.Nm +manual page first appeared in +.Fx 2.2 . +.Sh AUTHORS +This manual page was written by +.An John-Mark Gurney Aq Mt jmg@FreeBSD.org . diff --git a/contrib/elftoolchain/brandelf/brandelf.c b/contrib/elftoolchain/brandelf/brandelf.c new file mode 100644 index 0000000000..775f58e565 --- /dev/null +++ b/contrib/elftoolchain/brandelf/brandelf.c @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * Copyright (c) 2000, 2001 David O'Brien + * Copyright (c) 1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: brandelf.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +static int elftype(const char *); +static const char *iselftype(int); +static void printelftypes(void); +static void printversion(void); +static void usage(int); + +struct ELFtypes { + const char *str; + int value; +}; +/* XXX - any more types? */ +static struct ELFtypes elftypes[] = { + { "86Open", ELFOSABI_86OPEN }, + { "AIX", ELFOSABI_AIX }, + { "ARM", ELFOSABI_ARM }, + { "AROS", ELFOSABI_AROS }, + { "CloudABI", ELFOSABI_CLOUDABI }, + { "FreeBSD", ELFOSABI_FREEBSD }, + { "GNU", ELFOSABI_GNU }, + { "HP/UX", ELFOSABI_HPUX}, + { "Hurd", ELFOSABI_HURD }, + { "IRIX", ELFOSABI_IRIX }, + { "Linux", ELFOSABI_GNU }, + { "Modesto", ELFOSABI_MODESTO }, + { "NSK", ELFOSABI_NSK }, + { "NetBSD", ELFOSABI_NETBSD}, + { "None", ELFOSABI_NONE}, + { "OpenBSD", ELFOSABI_OPENBSD }, + { "OpenVMS", ELFOSABI_OPENVMS }, + { "Standalone", ELFOSABI_STANDALONE }, + { "SVR4", ELFOSABI_NONE }, + { "Solaris", ELFOSABI_SOLARIS }, + { "Tru64", ELFOSABI_TRU64 } +}; + +static struct option brandelf_longopts[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +int +main(int argc, char **argv) +{ + GElf_Ehdr ehdr; + Elf *elf; + Elf_Kind kind; + int type = ELFOSABI_NONE; + int retval = 0; + int ch, change = 0, force = 0, listed = 0; + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "elf_version error"); + + while ((ch = getopt_long(argc, argv, "Vf:hlt:v", brandelf_longopts, + NULL)) != -1) + switch (ch) { + case 'f': + if (change) + errx(EXIT_FAILURE, "ERROR: the -f option is " + "incompatible with the -t option."); + force = 1; + type = atoi(optarg); + if (errno == ERANGE || type < 0 || type > 255) { + warnx("ERROR: invalid argument to option " + "-f: %s", optarg); + usage(EX_USAGE); + } + break; + case 'h': + usage(EX_OK); + break; + case 'l': + printelftypes(); + listed = 1; + break; + case 'v': + /* This flag is ignored. */ + break; + case 't': + if (force) + errx(EXIT_FAILURE, "the -t option is " + "incompatible with the -f option."); + if ((type = elftype(optarg)) == -1) { + warnx("ERROR: invalid ELF type '%s'", optarg); + usage(EX_USAGE); + } + + change = 1; + break; + case 'V': + printversion(); + break; + default: + usage(EX_USAGE); + } + argc -= optind; + argv += optind; + if (!argc) { + if (listed) + exit(0); + else { + warnx("no file(s) specified"); + usage(EX_USAGE); + } + } + + while (argc) { + int fd; + + elf = NULL; + + if ((fd = open(argv[0], (change || force) ? O_RDWR : + O_RDONLY, 0)) < 0) { + warn("error opening file %s", argv[0]); + retval = 1; + goto fail; + } + + if ((elf = elf_begin(fd, (change || force) ? ELF_C_RDWR : + ELF_C_READ, NULL)) == NULL) { + warnx("elf_begin failed: %s", elf_errmsg(-1)); + retval = 1; + goto fail; + } + + if ((kind = elf_kind(elf)) != ELF_K_ELF) { + if (kind == ELF_K_AR) + warnx("file '%s' is an archive.", argv[0]); + else + warnx("file '%s' is not an ELF file.", + argv[0]); + retval = 1; + goto fail; + } + + if (gelf_getehdr(elf, &ehdr) == NULL) { + warnx("gelf_getehdr: %s", elf_errmsg(-1)); + retval = 1; + goto fail; + } + + if (!change && !force) { + fprintf(stdout, + "File '%s' is of brand '%s' (%u).\n", + argv[0], iselftype(ehdr.e_ident[EI_OSABI]), + ehdr.e_ident[EI_OSABI]); + if (!iselftype(type)) { + warnx("ELF ABI Brand '%u' is unknown", + type); + printelftypes(); + } + } else { + + /* + * Keep the existing layout of the ELF object. + */ + if (elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT) == 0) { + warnx("elf_flagelf failed: %s", + elf_errmsg(-1)); + retval = 1; + goto fail; + } + + /* + * Update the ABI type. + */ + ehdr.e_ident[EI_OSABI] = (unsigned char) type; + if (gelf_update_ehdr(elf, &ehdr) == 0) { + warnx("gelf_update_ehdr error: %s", + elf_errmsg(-1)); + retval = 1; + goto fail; + } + + /* + * Write back changes. + */ + if (elf_update(elf, ELF_C_WRITE) == -1) { + warnx("elf_update error: %s", elf_errmsg(-1)); + retval = 1; + goto fail; + } + } +fail: + + if (elf) + elf_end(elf); + + if (fd >= 0 && close(fd) == -1) { + warnx("%s: close error", argv[0]); + retval = 1; + } + + argc--; + argv++; + } + + return (retval); +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Set or display the ABI field for an ELF object.\n\n\ + Supported options are:\n\ + -f NUM Set the ELF ABI to the number 'NUM'.\n\ + -h | --help Print a usage message and exit.\n\ + -l List known ELF ABI names.\n\ + -t ABI Set the ELF ABI to the value named by \"ABI\".\n\ + -V | --version Print a version identifier and exit.\n" + +static void +usage(int exit_code) +{ + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +printversion(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(EX_OK); +} + +static const char * +iselftype(int etype) +{ + size_t elfwalk; + + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + if (etype == elftypes[elfwalk].value) + return (elftypes[elfwalk].str); + return (0); +} + +static int +elftype(const char *elfstrtype) +{ + size_t elfwalk; + + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + if (strcasecmp(elfstrtype, elftypes[elfwalk].str) == 0) + return (elftypes[elfwalk].value); + return (-1); +} + +static void +printelftypes(void) +{ + size_t elfwalk; + + (void) printf("Known ELF types are: "); + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + (void) printf("%s(%u) ", elftypes[elfwalk].str, + elftypes[elfwalk].value); + (void) printf("\n"); +} diff --git a/contrib/elftoolchain/common/Makefile b/contrib/elftoolchain/common/Makefile new file mode 100644 index 0000000000..a9ab0bc9d3 --- /dev/null +++ b/contrib/elftoolchain/common/Makefile @@ -0,0 +1,18 @@ +# $Id: Makefile 3948 2021-04-24 19:21:00Z jkoshy $ + +TOP= .. + +SUBDIR= sys + +INCS= elfdefinitions.h +INCSDIR= /usr/include + +.PHONY: all clean clobber depend obj + +all depend: + +cleandepend: + rm -f ${.OBJDIR}/.depend + +.include "${TOP}/mk/elftoolchain.inc.mk" +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/common/_elftc.h b/contrib/elftoolchain/common/_elftc.h new file mode 100644 index 0000000000..f334e327b5 --- /dev/null +++ b/contrib/elftoolchain/common/_elftc.h @@ -0,0 +1,505 @@ +/*- + * Copyright (c) 2009 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _elftc.h 4042 2024-06-28 12:34:53Z jkoshy $ + */ + +/** + ** Miscellaneous definitions needed by multiple components. + **/ + +#ifndef _ELFTC_H +#define _ELFTC_H + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#ifndef offsetof +#define offsetof(T, M) ((int) &((T*) 0) -> M) +#endif + +/* --QUEUE-MACROS-- [[ */ + +/* + * Supply macros missing from + */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LIST_FOREACH_SAFE +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef SLIST_FOREACH_SAFE +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef STAILQ_CONCAT +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_EMPTY +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#endif + +#ifndef STAILQ_ENTRY +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} +#endif + +#ifndef STAILQ_FIRST +#define STAILQ_FIRST(head) ((head)->stqh_first) +#endif + +#ifndef STAILQ_HEAD +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first; /* first element */ \ + struct type **stqh_last; /* addr of last next element */ \ +} +#endif + +#ifndef STAILQ_HEAD_INITIALIZER +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } +#endif + +#ifndef STAILQ_FOREACH +#define STAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->stqh_first); \ + (var); \ + (var) = ((var)->field.stqe_next)) +#endif + +#ifndef STAILQ_FOREACH_SAFE +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef STAILQ_INIT +#define STAILQ_INIT(head) do { \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_HEAD +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_TAIL +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_AFTER +#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (listelm)->field.stqe_next = (elm); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_LAST +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) +#endif + +#ifndef STAILQ_NEXT +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) +#endif + +#ifndef STAILQ_REMOVE +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->stqh_first; \ + while (curelm->field.stqe_next != (elm)) \ + curelm = curelm->field.stqe_next; \ + if ((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ + } \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_REMOVE_HEAD +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \ + NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) +#endif + +/* + * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n)) + * mergesort algorithm. + */ +#ifndef STAILQ_SORT +#define STAILQ_SORT(head, type, field, cmp) do { \ + STAILQ_HEAD(, type) _la, _lb; \ + struct type *_p, *_q, *_e; \ + int _i, _sz, _nmerges, _psz, _qsz; \ + \ + _sz = 1; \ + do { \ + _nmerges = 0; \ + STAILQ_INIT(&_lb); \ + while (!STAILQ_EMPTY((head))) { \ + _nmerges++; \ + STAILQ_INIT(&_la); \ + _psz = 0; \ + for (_i = 0; _i < _sz && !STAILQ_EMPTY((head)); \ + _i++) { \ + _e = STAILQ_FIRST((head)); \ + if (_e == NULL) \ + break; \ + _psz++; \ + STAILQ_REMOVE_HEAD((head), field); \ + STAILQ_INSERT_TAIL(&_la, _e, field); \ + } \ + _p = STAILQ_FIRST(&_la); \ + _qsz = _sz; \ + _q = STAILQ_FIRST((head)); \ + while (_psz > 0 || (_qsz > 0 && _q != NULL)) { \ + if (_psz == 0) { \ + _e = _q; \ + _q = STAILQ_NEXT(_q, field); \ + STAILQ_REMOVE_HEAD((head), \ + field); \ + _qsz--; \ + } else if (_qsz == 0 || _q == NULL) { \ + _e = _p; \ + _p = STAILQ_NEXT(_p, field); \ + STAILQ_REMOVE_HEAD(&_la, field);\ + _psz--; \ + } else if (cmp(_p, _q) <= 0) { \ + _e = _p; \ + _p = STAILQ_NEXT(_p, field); \ + STAILQ_REMOVE_HEAD(&_la, field);\ + _psz--; \ + } else { \ + _e = _q; \ + _q = STAILQ_NEXT(_q, field); \ + STAILQ_REMOVE_HEAD((head), \ + field); \ + _qsz--; \ + } \ + STAILQ_INSERT_TAIL(&_lb, _e, field); \ + } \ + } \ + (head)->stqh_first = _lb.stqh_first; \ + (head)->stqh_last = _lb.stqh_last; \ + _sz *= 2; \ + } while (_nmerges > 1); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef TAILQ_FOREACH_SAFE +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +/* ]] --QUEUE-MACROS-- */ + +/* + * VCS Ids. + * + * The placeholder below is intended to be replaced with a project-specific + * definition of the ELFTC_VCSID macro. + */ + +/* @ELFTC-DEFINE-ELFTC-VCSID@ */ + +#ifndef ELFTC_VCSID + +#if defined(__DragonFly__) || defined(__NetBSD__) + +#define ELFTC_VCSID(ID) __RCSID(ID) + +#elif defined(__FreeBSD__) + +#define ELFTC_VCSID(ID) __FBSDID(ID) + +#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__GLIBC__) || \ + defined(__GNU__) || defined(__linux__) || defined(__minix) || \ + defined(__CYGWIN__) + +#if defined(__GNUC__) +#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") +#else +#define ELFTC_VCSID(ID) /**/ +#endif + +#endif + +#endif /* ELFTC_VCSID */ + +/* + * The placeholder below is meant to be replaced by a declaration + * of the downstream project's revision control macro. + * + * E.g. on NetBSD, this placeholder would be replaced by: + * + * #if !defined(__RCSID) + * #define __RCSID(ID) + * #endif + */ +/*@ELFTC-DECLARE-DOWNSTREAM-VCSID@*/ + +/* + * Provide an equivalent for getprogname(3). + */ + +#ifndef ELFTC_GETPROGNAME + +#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ + defined(__minix) || defined(__NetBSD__) + +#include + +#define ELFTC_GETPROGNAME() getprogname() + +#endif /* __APPLE__ || __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */ + + +#if defined(__GLIBC__) || defined(__linux__) +#ifndef _GNU_SOURCE +/* + * GLIBC based systems have a global 'char *' pointer referencing + * the executable's name. + */ +extern const char *program_invocation_short_name; +#endif /* !_GNU_SOURCE */ + +#define ELFTC_GETPROGNAME() program_invocation_short_name + +#endif /* __GLIBC__ || __linux__ */ + + +#if defined(__OpenBSD__) + +extern const char *__progname; + +#define ELFTC_GETPROGNAME() __progname + +#endif /* __OpenBSD__ */ + +#endif /* ELFTC_GETPROGNAME */ + + +/* + * Per-OS configuration. + * + * The following symbols are supported by this configuration fragment, + * although not all the OSes so referenced are fully supported. + * + * Cross-compilation: + * + * HAVE_NBTOOL_CONFIG_H : cross-compiling NetBSD tools on various OSes. + * + * Native compilation: + * + * __APPLE__ : compiling under Mac OS X. + * __DragonFly__ : compiling under DragonFlyBSD. + * __GLIBC__ : compiling under GNU based systems, such as GNU/kFreeBSD. + * __linux__ : compiling under GNU/Linux systems. + * __FreeBSD__ : compiling under FreeBSD. + * __minix : compiling under Minix3. + * __NetBSD__ : compiling (native) under NetBSD. + * __OpenBSD__ : compiling under OpenBSD. + */ + +#if defined(HAVE_NBTOOL_CONFIG_H) + +#include +#include + +#ifndef roundup2 +#define roundup2 roundup +#endif + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 + +#elif defined(__APPLE__) + +#include +#define htobe32(x) OSSwapHostToBigInt32(x) +#define roundup2 roundup + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 + +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 + +#elif defined(__DragonFly__) + +#include +#include + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 + +#elif defined(__GLIBC__) || defined(__linux__) + +#include + +#define ELFTC_BYTE_ORDER __BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 + +/* + * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3). + */ +#define ELFTC_HAVE_STRMODE 0 + +/* Whether we need to supply {be,le}32dec. */ +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 + +#define roundup2 roundup + +#elif defined(__FreeBSD__) + +#include +#include + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 +#if __FreeBSD_version <= 900000 +#define ELFTC_BROKEN_YY_NO_INPUT 1 +#endif + +#elif defined(__minix) +#define ELFTC_HAVE_MMAP 0 + +#elif defined(__NetBSD__) + +#include +#include + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 +#if __NetBSD_Version__ <= 599002100 +/* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */ +/* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */ +# define ELFTC_BROKEN_YY_NO_INPUT 1 +#endif + +#elif defined(__OpenBSD__) + +#include +#include + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 + +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 +#define roundup2 roundup + +#endif /* __OpenBSD__ */ + +#endif /* _ELFTC_H */ diff --git a/contrib/elftoolchain/common/elf.h b/contrib/elftoolchain/common/elf.h new file mode 100644 index 0000000000..320734ead0 --- /dev/null +++ b/contrib/elftoolchain/common/elf.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2024 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#ifndef _ELFTOOLCHAIN_ELF_H +#define _ELFTOOLCHAIN_ELF_H + +#include + +#endif /* _ELFTOOLCHAIN_ELF_H */ diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h new file mode 100644 index 0000000000..755d0ebcb7 --- /dev/null +++ b/contrib/elftoolchain/common/elfdefinitions.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2010,2021 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfdefinitions.h 3942 2021-04-05 12:16:03Z jkoshy $ + */ + +#ifndef _ELFDEFINITIONS_H_ +#define _ELFDEFINITIONS_H_ + +#include + +#endif /* _ELFDEFINITIONS_H_ */ diff --git a/contrib/elftoolchain/common/sys/Makefile b/contrib/elftoolchain/common/sys/Makefile new file mode 100644 index 0000000000..aee9b4c96e --- /dev/null +++ b/contrib/elftoolchain/common/sys/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile 3944 2021-04-10 10:19:00Z jkoshy $ + +TOP= ../.. + +SRCS= elfdefinitions.m4 elfconstants.m4 +INCS= elfdefinitions.h +INCSDIR= /usr/include/sys + +CLEANFILES= ${INCS} + +.PHONY: all clean clobber depend obj + +all: ${INCS} + +elfdefinitions.h: elfdefinitions.m4 elfconstants.m4 + m4 -I${.CURDIR} -D SRCDIR=${.CURDIR} ${M4FLAGS} \ + elfdefinitions.m4 > ${.TARGET} + +depend cleandepend: + +clean clobber: + rm -f ${CLEANFILES} + +.include "${TOP}/mk/elftoolchain.inc.mk" +.include "${TOP}/mk/elftoolchain.m4.mk" diff --git a/contrib/elftoolchain/common/sys/elfconstants.m4 b/contrib/elftoolchain/common/sys/elfconstants.m4 new file mode 100644 index 0000000000..10b00946c9 --- /dev/null +++ b/contrib/elftoolchain/common/sys/elfconstants.m4 @@ -0,0 +1,2757 @@ +# Copyright (c) 2010,2021 Joseph Koshy +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# These definitions are based on: +# - The public specification of the ELF format as defined in the +# October 2009 draft of System V ABI. +# See: http://www.sco.com/developers/gabi/latest/ch4.intro.html +# - The May 1998 (version 1.5) draft of "The ELF-64 object format". +# - Processor-specific ELF ABI definitions for amd64, i386, ia64, +# loongarch, mips, powerpc, riscv and sparc processors. +# - The "Linkers and Libraries Guide", from Sun Microsystems. + +define(`VCSID_ELFCONSTANTS_M4', + `$Id: elfconstants.m4 4053 2024-11-25 13:42:22Z jkoshy $') + +# In the following definitions, `_' is an M4 macro that is meant to be +# expanded later. Its intended usage is: +# +# `_(ELF_SYMBOL, VALUE, OPTIONAL-DESCRIPTION)' +# +# These (deferred) macros are then grouped together into named collections. +# +# At the point of use, `_' would be defined to expand to the desired +# replacement text. +# +# # File: example_expansion.m4 +# +# define(`_',`case $2: return ("$1");') +# include(`elfconstants.m4') +# +# const char *name_of_capability(int capability) +# { +# switch(capability) { +# DEFINE_CAPABILITIES(); +# default: +# return (NULL); +# } +# } + +# +# Types of capabilities. +# +define(`DEFINE_CAPABILITIES',` +_(`CA_SUNW_NULL', 0, `ignored') +_(`CA_SUNW_HW_1', 1, `hardware capability') +_(`CA_SUNW_SW_1', 2, `software capability')') + +# +# Flags used with dynamic linking entries. +# +define(`DEFINE_DYN_FLAGS',` +_(`DF_ORIGIN', 0x1, + `object being loaded may refer to `$ORIGIN'') +_(`DF_SYMBOLIC', 0x2, + `search library for references before executable') +_(`DF_TEXTREL', 0x4, + `relocation entries may modify text segment') +_(`DF_BIND_NOW', 0x8, + `process relocation entries at load time') +_(`DF_STATIC_TLS', 0x10, + `uses static thread-local storage') +_(`DF_1_BIND_NOW', 0x1, + `process relocation entries at load time') +_(`DF_1_GLOBAL', 0x2, + `unused') +_(`DF_1_GROUP', 0x4, + `object is a member of a group') +_(`DF_1_NODELETE', 0x8, + `object cannot be deleted from a process') +_(`DF_1_LOADFLTR', 0x10, + `immediate load filtees') +_(`DF_1_INITFIRST', 0x20, + `initialize object first') +_(`DF_1_NOOPEN', 0x40, + `disallow dlopen()') +_(`DF_1_ORIGIN', 0x80, + `object being loaded may refer to $ORIGIN') +_(`DF_1_DIRECT', 0x100, + `direct bindings enabled') +_(`DF_1_INTERPOSE', 0x400, + `object is interposer') +_(`DF_1_NODEFLIB', 0x800, + `ignore default library search path') +_(`DF_1_NODUMP', 0x1000, + `disallow dldump()') +_(`DF_1_CONFALT', 0x2000, + `object is a configuration alternative') +_(`DF_1_ENDFILTEE', 0x4000, + `filtee terminates filter search') +_(`DF_1_DISPRELDNE', 0x8000, + `displacement relocation done') +_(`DF_1_DISPRELPND', 0x10000, + `displacement relocation pending')') + +# +# Dynamic linking entry types. +# +define(`DEFINE_DYN_TYPES',` +_(`DT_NULL', 0, + `end of array') +_(`DT_NEEDED', 1, + `names a needed library') +_(`DT_PLTRELSZ', 2, + `size in bytes of associated relocation entries') +_(`DT_PLTGOT', 3, + `address associated with the procedure linkage table') +_(`DT_HASH', 4, + `address of the symbol hash table') +_(`DT_STRTAB', 5, + `address of the string table') +_(`DT_SYMTAB', 6, + `address of the symbol table') +_(`DT_RELA', 7, + `address of the relocation table') +_(`DT_RELASZ', 8, + `size of the DT_RELA table') +_(`DT_RELAENT', 9, + `size of each DT_RELA entry') +_(`DT_STRSZ', 10, + `size of the string table') +_(`DT_SYMENT', 11, + `size of a symbol table entry') +_(`DT_INIT', 12, + `address of the initialization function') +_(`DT_FINI', 13, + `address of the finalization function') +_(`DT_SONAME', 14, + `names the shared object') +_(`DT_RPATH', 15, + `runtime library search path') +_(`DT_SYMBOLIC', 16, + `alter symbol resolution algorithm') +_(`DT_REL', 17, + `address of the DT_REL table') +_(`DT_RELSZ', 18, + `size of the DT_REL table') +_(`DT_RELENT', 19, + `size of each DT_REL entry') +_(`DT_PLTREL', 20, + `type of relocation entry in the procedure linkage table') +_(`DT_DEBUG', 21, + `used for debugging') +_(`DT_TEXTREL', 22, + `text segment may be written to during relocation') +_(`DT_JMPREL', 23, + `address of relocation entries associated with the procedure linkage table') +_(`DT_BIND_NOW', 24, + `bind symbols at loading time') +_(`DT_INIT_ARRAY', 25, + `pointers to initialization functions') +_(`DT_FINI_ARRAY', 26, + `pointers to termination functions') +_(`DT_INIT_ARRAYSZ', 27, + `size of the DT_INIT_ARRAY') +_(`DT_FINI_ARRAYSZ', 28, + `size of the DT_FINI_ARRAY') +_(`DT_RUNPATH', 29, + `index of library search path string') +_(`DT_FLAGS', 30, + `flags specific to the object being loaded') +_(`DT_ENCODING', 32, + `standard semantics') +_(`DT_PREINIT_ARRAY', 32, + `pointers to pre-initialization functions') +_(`DT_PREINIT_ARRAYSZ', 33, + `size of pre-initialization array') +_(`DT_MAXPOSTAGS', 34, + `the number of positive tags') +_(`DT_LOOS', 0x6000000D, + `start of OS-specific types') +_(`DT_SUNW_AUXILIARY', 0x6000000D, + `offset of string naming auxiliary filtees') +_(`DT_SUNW_RTLDINF', 0x6000000E, + `rtld internal use') +_(`DT_SUNW_FILTER', 0x6000000F, + `offset of string naming standard filtees') +_(`DT_SUNW_CAP', 0x60000010, + `address of hardware capabilities section') +_(`DT_SUNW_ASLR', 0x60000023, + `Address Space Layout Randomization flag') +_(`DT_HIOS', 0x6FFFF000, + `end of OS-specific types') +_(`DT_VALRNGLO', 0x6FFFFD00, + `start of range using the d_val field') +_(`DT_GNU_PRELINKED', 0x6FFFFDF5, + `prelinking timestamp') +_(`DT_GNU_CONFLICTSZ', 0x6FFFFDF6, + `size of conflict section') +_(`DT_GNU_LIBLISTSZ', 0x6FFFFDF7, + `size of library list') +_(`DT_CHECKSUM', 0x6FFFFDF8, + `checksum for the object') +_(`DT_PLTPADSZ', 0x6FFFFDF9, + `size of PLT padding') +_(`DT_MOVEENT', 0x6FFFFDFA, + `size of DT_MOVETAB entries') +_(`DT_MOVESZ', 0x6FFFFDFB, + `total size of the MOVETAB table') +_(`DT_FEATURE', 0x6FFFFDFC, + `feature values') +_(`DT_POSFLAG_1', 0x6FFFFDFD, + `dynamic position flags') +_(`DT_SYMINSZ', 0x6FFFFDFE, + `size of the DT_SYMINFO table') +_(`DT_SYMINENT', 0x6FFFFDFF, + `size of a DT_SYMINFO entry') +_(`DT_VALRNGHI', 0x6FFFFDFF, + `end of range using the d_val field') +_(`DT_ADDRRNGLO', 0x6FFFFE00, + `start of range using the d_ptr field') +_(`DT_GNU_HASH', 0x6FFFFEF5, + `GNU style hash tables') +_(`DT_TLSDESC_PLT', 0x6FFFFEF6, + `location of PLT entry for TLS descriptor resolver calls') +_(`DT_TLSDESC_GOT', 0x6FFFFEF7, + `location of GOT entry used by TLS descriptor resolver PLT entry') +_(`DT_GNU_CONFLICT', 0x6FFFFEF8, + `address of conflict section') +_(`DT_GNU_LIBLIST', 0x6FFFFEF9, + `address of conflict section') +_(`DT_CONFIG', 0x6FFFFEFA, + `configuration file') +_(`DT_DEPAUDIT', 0x6FFFFEFB, + `string defining audit libraries') +_(`DT_AUDIT', 0x6FFFFEFC, + `string defining audit libraries') +_(`DT_PLTPAD', 0x6FFFFEFD, + `PLT padding') +_(`DT_MOVETAB', 0x6FFFFEFE, + `address of a move table') +_(`DT_SYMINFO', 0x6FFFFEFF, + `address of the symbol information table') +_(`DT_ADDRRNGHI', 0x6FFFFEFF, + `end of range using the d_ptr field') +_(`DT_VERSYM', 0x6FFFFFF0, + `address of the version section') +_(`DT_RELACOUNT', 0x6FFFFFF9, + `count of RELA relocations') +_(`DT_RELCOUNT', 0x6FFFFFFA, + `count of REL relocations') +_(`DT_FLAGS_1', 0x6FFFFFFB, + `flag values') +_(`DT_VERDEF', 0x6FFFFFFC, + `address of the version definition segment') +_(`DT_VERDEFNUM', 0x6FFFFFFD, + `the number of version definition entries') +_(`DT_VERNEED', 0x6FFFFFFE, + `address of section with needed versions') +_(`DT_VERNEEDNUM', 0x6FFFFFFF, + `the number of version needed entries') +_(`DT_LOPROC', 0x70000000, + `start of processor-specific types') +_(`DT_ARM_SYMTABSZ', 0x70000001, + `number of entries in the dynamic symbol table') +_(`DT_SPARC_REGISTER', 0x70000001, + `index of an STT_SPARC_REGISTER symbol') +_(`DT_ARM_PREEMPTMAP', 0x70000002, + `address of the preemption map') +_(`DT_MIPS_RLD_VERSION', 0x70000001, + `version ID for runtime linker interface') +_(`DT_MIPS_TIME_STAMP', 0x70000002, + `timestamp') +_(`DT_MIPS_ICHECKSUM', 0x70000003, + `checksum of all external strings and common sizes') +_(`DT_MIPS_IVERSION', 0x70000004, + `string table index of a version string') +_(`DT_MIPS_FLAGS', 0x70000005, + `MIPS-specific flags') +_(`DT_MIPS_BASE_ADDRESS', 0x70000006, + `base address for the executable/DSO') +_(`DT_MIPS_CONFLICT', 0x70000008, + `address of .conflict section') +_(`DT_MIPS_LIBLIST', 0x70000009, + `address of .liblist section') +_(`DT_MIPS_LOCAL_GOTNO', 0x7000000A, + `number of local GOT entries') +_(`DT_MIPS_CONFLICTNO', 0x7000000B, + `number of entries in the .conflict section') +_(`DT_MIPS_LIBLISTNO', 0x70000010, + `number of entries in the .liblist section') +_(`DT_MIPS_SYMTABNO', 0x70000011, + `number of entries in the .dynsym section') +_(`DT_MIPS_UNREFEXTNO', 0x70000012, + `index of first external dynamic symbol not referenced locally') +_(`DT_MIPS_GOTSYM', 0x70000013, + `index of first dynamic symbol corresponds to a GOT entry') +_(`DT_MIPS_HIPAGENO', 0x70000014, + `number of page table entries in GOT') +_(`DT_MIPS_RLD_MAP', 0x70000016, + `address of runtime linker map') +_(`DT_MIPS_DELTA_CLASS', 0x70000017, + `Delta C++ class definition') +_(`DT_MIPS_DELTA_CLASS_NO', 0x70000018, + `number of entries in DT_MIPS_DELTA_CLASS') +_(`DT_MIPS_DELTA_INSTANCE', 0x70000019, + `Delta C++ class instances') +_(`DT_MIPS_DELTA_INSTANCE_NO', 0x7000001A, + `number of entries in DT_MIPS_DELTA_INSTANCE') +_(`DT_MIPS_DELTA_RELOC', 0x7000001B, + `Delta relocations') +_(`DT_MIPS_DELTA_RELOC_NO', 0x7000001C, + `number of entries in DT_MIPS_DELTA_RELOC') +_(`DT_MIPS_DELTA_SYM', 0x7000001D, + `Delta symbols referred by Delta relocations') +_(`DT_MIPS_DELTA_SYM_NO', 0x7000001E, + `number of entries in DT_MIPS_DELTA_SYM') +_(`DT_MIPS_DELTA_CLASSSYM', 0x70000020, + `Delta symbols for class declarations') +_(`DT_MIPS_DELTA_CLASSSYM_NO', 0x70000021, + `number of entries in DT_MIPS_DELTA_CLASSSYM') +_(`DT_MIPS_CXX_FLAGS', 0x70000022, + `C++ flavor flags') +_(`DT_MIPS_PIXIE_INIT', 0x70000023, + `address of an initialization routine created by pixie') +_(`DT_MIPS_SYMBOL_LIB', 0x70000024, + `address of .MIPS.symlib section') +_(`DT_MIPS_LOCALPAGE_GOTIDX', 0x70000025, + `GOT index of first page table entry for a segment') +_(`DT_MIPS_LOCAL_GOTIDX', 0x70000026, + `GOT index of first page table entry for a local symbol') +_(`DT_MIPS_HIDDEN_GOTIDX', 0x70000027, + `GOT index of first page table entry for a hidden symbol') +_(`DT_MIPS_PROTECTED_GOTIDX', 0x70000028, + `GOT index of first page table entry for a protected symbol') +_(`DT_MIPS_OPTIONS', 0x70000029, + `address of .MIPS.options section') +_(`DT_MIPS_INTERFACE', 0x7000002A, + `address of .MIPS.interface section') +_(`DT_MIPS_DYNSTR_ALIGN', 0x7000002B, + `???') +_(`DT_MIPS_INTERFACE_SIZE', 0x7000002C, + `size of .MIPS.interface section') +_(`DT_MIPS_RLD_TEXT_RESOLVE_ADDR', 0x7000002D, + `address of _rld_text_resolve in GOT') +_(`DT_MIPS_PERF_SUFFIX', 0x7000002E, + `default suffix of DSO to be appended by dlopen') +_(`DT_MIPS_COMPACT_SIZE', 0x7000002F, + `size of a ucode compact relocation record (o32)') +_(`DT_MIPS_GP_VALUE', 0x70000030, + `GP value of a specified GP relative range') +_(`DT_MIPS_AUX_DYNAMIC', 0x70000031, + `address of an auxiliary dynamic table') +_(`DT_MIPS_PLTGOT', 0x70000032, + `address of the PLTGOT') +_(`DT_MIPS_RLD_OBJ_UPDATE', 0x70000033, + `object list update callback') +_(`DT_MIPS_RWPLT', 0x70000034, + `address of a writable PLT') +_(`DT_PPC_GOT', 0x70000000, + `value of _GLOBAL_OFFSET_TABLE_') +_(`DT_PPC_TLSOPT', 0x70000001, + `TLS descriptor should be optimized') +_(`DT_PPC64_GLINK', 0x70000000, + `address of .glink section') +_(`DT_PPC64_OPD', 0x70000001, + `address of .opd section') +_(`DT_PPC64_OPDSZ', 0x70000002, + `size of .opd section') +_(`DT_PPC64_TLSOPT', 0x70000003, + `TLS descriptor should be optimized') +_(`DT_AUXILIARY', 0x7FFFFFFD, + `offset of string naming auxiliary filtees') +_(`DT_USED', 0x7FFFFFFE, + `ignored') +_(`DT_FILTER', 0x7FFFFFFF, + `index of string naming filtees') +_(`DT_HIPROC', 0x7FFFFFFF, + `end of processor-specific types') +') + +define(`DEFINE_DYN_TYPE_ALIASES',` +_(`DT_DEPRECATED_SPARC_REGISTER', `DT_SPARC_REGISTER') +') + +# +# Flags used in the executable header (field: e_flags). +# +define(`DEFINE_EHDR_FLAGS',` +_(EF_ARM_RELEXEC, 0x00000001UL, + `dynamic segment describes only how to relocate segments') +_(EF_ARM_HASENTRY, 0x00000002UL, + `e_entry contains a program entry point') +_(EF_ARM_SYMSARESORTED, 0x00000004UL, + `subsection of symbol table is sorted by symbol value') +_(EF_ARM_DYNSYMSUSESEGIDX, 0x00000008UL, + `dynamic symbol st_shndx = containing segment index + 1') +_(EF_ARM_MAPSYMSFIRST, 0x00000010UL, + `mapping symbols precede other local symbols in symtab') +_(EF_ARM_BE8, 0x00800000UL, + `file contains BE-8 code') +_(EF_ARM_LE8, 0x00400000UL, + `file contains LE-8 code') +_(EF_ARM_EABIMASK, 0xFF000000UL, + `mask for ARM EABI version number (0 denotes GNU or unknown)') +_(EF_ARM_EABI_UNKNOWN, 0x00000000UL, + `Unknown or GNU ARM EABI version number') +_(EF_ARM_EABI_VER1, 0x01000000UL, + `ARM EABI version 1') +_(EF_ARM_EABI_VER2, 0x02000000UL, + `ARM EABI version 2') +_(EF_ARM_EABI_VER3, 0x03000000UL, + `ARM EABI version 3') +_(EF_ARM_EABI_VER4, 0x04000000UL, + `ARM EABI version 4') +_(EF_ARM_EABI_VER5, 0x05000000UL, + `ARM EABI version 5') +_(EF_ARM_INTERWORK, 0x00000004UL, + `GNU EABI extension') +_(EF_ARM_APCS_26, 0x00000008UL, + `GNU EABI extension') +_(EF_ARM_APCS_FLOAT, 0x00000010UL, + `GNU EABI extension') +_(EF_ARM_PIC, 0x00000020UL, + `GNU EABI extension') +_(EF_ARM_ALIGN8, 0x00000040UL, + `GNU EABI extension') +_(EF_ARM_NEW_ABI, 0x00000080UL, + `GNU EABI extension') +_(EF_ARM_OLD_ABI, 0x00000100UL, + `GNU EABI extension') +_(EF_ARM_SOFT_FLOAT, 0x00000200UL, + `GNU EABI extension') +_(EF_ARM_VFP_FLOAT, 0x00000400UL, + `GNU EABI extension') +_(EF_ARM_MAVERICK_FLOAT, 0x00000800UL, + `GNU EABI extension') +_(EF_MIPS_NOREORDER, 0x00000001UL, + `at least one .noreorder directive appeared in the source') +_(EF_MIPS_PIC, 0x00000002UL, + `file contains position independent code') +_(EF_MIPS_CPIC, 0x00000004UL, + `file code uses standard conventions for calling PIC') +_(EF_MIPS_UCODE, 0x00000010UL, + `file contains UCODE (obsolete)') +_(EF_MIPS_ABI, 0x00007000UL, + `Application binary interface, see E_MIPS_* values') +_(EF_MIPS_ABI2, 0x00000020UL, + `file follows MIPS III 32-bit ABI') +_(EF_MIPS_OPTIONS_FIRST, 0x00000080UL, + `ld(1) should process .MIPS.options section first') +_(EF_MIPS_ARCH_ASE, 0x0F000000UL, + `file uses application-specific architectural extensions') +_(EF_MIPS_ARCH_ASE_MDMX, 0x08000000UL, + `file uses MDMX multimedia extensions') +_(EF_MIPS_ARCH_ASE_M16, 0x04000000UL, + `file uses MIPS-16 ISA extensions') +_(EF_MIPS_ARCH_ASE_MICROMIPS, 0x02000000UL, + `MicroMIPS architecture') +_(EF_MIPS_ARCH, 0xF0000000UL, + `4-bit MIPS architecture field') +_(EF_MIPS_ARCH_1, 0x00000000UL, + `MIPS I instruction set') +_(EF_MIPS_ARCH_2, 0x10000000UL, + `MIPS II instruction set') +_(EF_MIPS_ARCH_3, 0x20000000UL, + `MIPS III instruction set') +_(EF_MIPS_ARCH_4, 0x30000000UL, + `MIPS IV instruction set') +_(EF_MIPS_ARCH_5, 0x40000000UL, + `Never introduced') +_(EF_MIPS_ARCH_32, 0x50000000UL, + `Mips32 Revision 1') +_(EF_MIPS_ARCH_64, 0x60000000UL, + `Mips64 Revision 1') +_(EF_MIPS_ARCH_32R2, 0x70000000UL, + `Mips32 Revision 2') +_(EF_MIPS_ARCH_64R2, 0x80000000UL, + `Mips64 Revision 2') +_(EF_PPC_EMB, 0x80000000UL, + `Embedded PowerPC flag') +_(EF_PPC_RELOCATABLE, 0x00010000UL, + `-mrelocatable flag') +_(EF_PPC_RELOCATABLE_LIB, 0x00008000UL, + `-mrelocatable-lib flag') +_(EF_RISCV_RVC, 0x00000001UL, + `Compressed instruction extension') +_(EF_RISCV_FLOAT_ABI_MASK, 0x00000006UL, + `Floating point ABI') +_(EF_RISCV_FLOAT_ABI_SOFT, 0x00000000UL, + `Software emulated floating point') +_(EF_RISCV_FLOAT_ABI_SINGLE, 0x00000002UL, + `Single precision floating point') +_(EF_RISCV_FLOAT_ABI_DOUBLE, 0x00000004UL, + `Double precision floating point') +_(EF_RISCV_FLOAT_ABI_QUAD, 0x00000006UL, + `Quad precision floating point') +_(EF_RISCV_RVE, 0x00000008UL, + `Compressed instruction ABI') +_(EF_RISCV_TSO, 0x00000010UL, + `RVTSO memory consistency model') +_(EF_SPARC_EXT_MASK, 0x00ffff00UL, + `Vendor Extension mask') +_(EF_SPARC_32PLUS, 0x00000100UL, + `Generic V8+ features') +_(EF_SPARC_SUN_US1, 0x00000200UL, + `Sun UltraSPARCTM 1 Extensions') +_(EF_SPARC_HAL_R1, 0x00000400UL, + `HAL R1 Extensions') +_(EF_SPARC_SUN_US3, 0x00000800UL, + `Sun UltraSPARC 3 Extensions') +_(EF_SPARCV9_MM, 0x00000003UL, + `Mask for Memory Model') +_(EF_SPARCV9_TSO, 0x00000000UL, + `Total Store Ordering') +_(EF_SPARCV9_PSO, 0x00000001UL, + `Partial Store Ordering') +_(EF_SPARCV9_RMO, 0x00000002UL, + `Relaxed Memory Ordering') +') + +# +# Offsets in the `ei_ident[]` field of an ELF executable header. +# +define(`DEFINE_EI_OFFSETS',` +_(EI_MAG0, 0, + `magic number') +_(EI_MAG1, 1, + `magic number') +_(EI_MAG2, 2, + `magic number') +_(EI_MAG3, 3, + `magic number') +_(EI_CLASS, 4, + `file class') +_(EI_DATA, 5, + `data encoding') +_(EI_VERSION, 6, + `file version') +_(EI_OSABI, 7, + `OS ABI kind') +_(EI_ABIVERSION, 8, + `OS ABI version') +_(EI_PAD, 9, + `padding start') +_(EI_NIDENT, 16, + `total size') +') + +# +# The ELF class of an object. +# +define(`DEFINE_ELF_CLASSES',` +_(ELFCLASSNONE, 0, + `Unknown ELF class') +_(ELFCLASS32, 1, + `32 bit objects') +_(ELFCLASS64, 2, + `64 bit objects') +') + +# +# Endianness of data in an ELF object. +# +define(`DEFINE_ELF_DATA_ENDIANNESSES',` +_(ELFDATANONE, 0, + `Unknown data endianness') +_(ELFDATA2LSB, 1, + `little endian') +_(ELFDATA2MSB, 2, + `big endian') +') + + +# +# The magic numbers used in the initial four bytes of an ELF object. +# +# These numbers are: 0x7F, 'E', 'L' and 'F'. +define(`DEFINE_ELF_MAGIC_VALUES',` +_(ELFMAG0, 0x7FU) +_(ELFMAG1, 0x45U) +_(ELFMAG2, 0x4CU) +_(ELFMAG3, 0x46U) +') + +# Additional ELFMAG related constants. +define(`DEFINE_ELF_MAGIC_ADDITIONAL_CONSTANTS',` +_(ELFMAG, "\177ELF") +_(SELFMAG, 4) +') + +# +# ELF OS ABI field. +# +define(`DEFINE_ELF_OSABIS',` +_(ELFOSABI_NONE, 0, + `No extensions or unspecified') +_(ELFOSABI_SYSV, 0, + `SYSV') +_(ELFOSABI_HPUX, 1, + `Hewlett-Packard HP-UX') +_(ELFOSABI_NETBSD, 2, + `NetBSD') +_(ELFOSABI_GNU, 3, + `GNU') +_(ELFOSABI_HURD, 4, + `GNU/HURD') +_(ELFOSABI_86OPEN, 5, + `86Open Common ABI') +_(ELFOSABI_SOLARIS, 6, + `Sun Solaris') +_(ELFOSABI_AIX, 7, + `AIX') +_(ELFOSABI_IRIX, 8, + `IRIX') +_(ELFOSABI_FREEBSD, 9, + `FreeBSD') +_(ELFOSABI_TRU64, 10, + `Compaq TRU64 UNIX') +_(ELFOSABI_MODESTO, 11, + `Novell Modesto') +_(ELFOSABI_OPENBSD, 12, + `Open BSD') +_(ELFOSABI_OPENVMS, 13, + `Open VMS') +_(ELFOSABI_NSK, 14, + `Hewlett-Packard Non-Stop Kernel') +_(ELFOSABI_AROS, 15, + `Amiga Research OS') +_(ELFOSABI_FENIXOS, 16, + `The FenixOS highly scalable multi-core OS') +_(ELFOSABI_CLOUDABI, 17, + `Nuxi CloudABI') +_(ELFOSABI_OPENVOS, 18, + `Stratus Technologies OpenVOS') +_(ELFOSABI_ARM_AEABI, 64, + `ARM specific symbol versioning extensions') +_(ELFOSABI_ARM, 97, + `ARM ABI') +_(ELFOSABI_STANDALONE, 255, + `Standalone (embedded) application') +') + +# OS ABI aliases. +define(`DEFINE_ELF_OSABI_ALIASES',` +_(ELFOSABI_LINUX, ELFOSABI_GNU) +') + +# +# ELF Machine types: (EM_*). +# +define(`DEFINE_ELF_MACHINE_TYPES',` +_(EM_NONE, 0, + `No machine') +_(EM_M32, 1, + `AT&T WE 32100') +_(EM_SPARC, 2, + `SPARC') +_(EM_386, 3, + `Intel 80386') +_(EM_68K, 4, + `Motorola 68000') +_(EM_88K, 5, + `Motorola 88000') +_(EM_IAMCU, 6, + `Intel MCU') +_(EM_860, 7, + `Intel 80860') +_(EM_MIPS, 8, + `MIPS I Architecture') +_(EM_S370, 9, + `IBM System/370 Processor') +_(EM_MIPS_RS3_LE, 10, + `MIPS RS3000 Little-endian') +_(EM_PARISC, 15, + `Hewlett-Packard PA-RISC') +_(EM_VPP500, 17, + `Fujitsu VPP500') +_(EM_SPARC32PLUS, 18, + `Enhanced instruction set SPARC') +_(EM_960, 19, + `Intel 80960') +_(EM_PPC, 20, + `PowerPC') +_(EM_PPC64, 21, + `64-bit PowerPC') +_(EM_S390, 22, + `IBM System/390 Processor') +_(EM_SPU, 23, + `IBM SPU/SPC') +_(EM_V800, 36, + `NEC V800') +_(EM_FR20, 37, + `Fujitsu FR20') +_(EM_RH32, 38, + `TRW RH-32') +_(EM_RCE, 39, + `Motorola RCE') +_(EM_ARM, 40, + `Advanced RISC Machines ARM') +_(EM_ALPHA, 41, + `Digital Alpha') +_(EM_SH, 42, + `Hitachi SH') +_(EM_SPARCV9, 43, + `SPARC Version 9') +_(EM_TRICORE, 44, + `Siemens TriCore embedded processor') +_(EM_ARC, 45, + `Argonaut RISC Core, Argonaut Technologies Inc.') +_(EM_H8_300, 46, + `Hitachi H8/300') +_(EM_H8_300H, 47, + `Hitachi H8/300H') +_(EM_H8S, 48, + `Hitachi H8S') +_(EM_H8_500, 49, + `Hitachi H8/500') +_(EM_IA_64, 50, + `Intel IA-64 processor architecture') +_(EM_MIPS_X, 51, + `Stanford MIPS-X') +_(EM_COLDFIRE, 52, + `Motorola ColdFire') +_(EM_68HC12, 53, + `Motorola M68HC12') +_(EM_MMA, 54, + `Fujitsu MMA Multimedia Accelerator') +_(EM_PCP, 55, + `Siemens PCP') +_(EM_NCPU, 56, + `Sony nCPU embedded RISC processor') +_(EM_NDR1, 57, + `Denso NDR1 microprocessor') +_(EM_STARCORE, 58, + `Motorola Star*Core processor') +_(EM_ME16, 59, + `Toyota ME16 processor') +_(EM_ST100, 60, + `STMicroelectronics ST100 processor') +_(EM_TINYJ, 61, + `Advanced Logic Corp. TinyJ embedded processor family') +_(EM_X86_64, 62, + `AMD x86-64 architecture') +_(EM_PDSP, 63, + `Sony DSP Processor') +_(EM_PDP10, 64, + `Digital Equipment Corp. PDP-10') +_(EM_PDP11, 65, + `Digital Equipment Corp. PDP-11') +_(EM_FX66, 66, + `Siemens FX66 microcontroller') +_(EM_ST9PLUS, 67, + `STMicroelectronics ST9+ 8/16 bit microcontroller') +_(EM_ST7, 68, + `STMicroelectronics ST7 8-bit microcontroller') +_(EM_68HC16, 69, + `Motorola MC68HC16 Microcontroller') +_(EM_68HC11, 70, + `Motorola MC68HC11 Microcontroller') +_(EM_68HC08, 71, + `Motorola MC68HC08 Microcontroller') +_(EM_68HC05, 72, + `Motorola MC68HC05 Microcontroller') +_(EM_SVX, 73, + `Silicon Graphics SVx') +_(EM_ST19, 74, + `STMicroelectronics ST19 8-bit microcontroller') +_(EM_VAX, 75, + `Digital VAX') +_(EM_CRIS, 76, + `Axis Communications 32-bit embedded processor') +_(EM_JAVELIN, 77, + `Infineon Technologies 32-bit embedded processor') +_(EM_FIREPATH, 78, + `Element 14 64-bit DSP Processor') +_(EM_ZSP, 79, + `LSI Logic 16-bit DSP Processor') +_(EM_MMIX, 80, + `Educational 64-bit processor by Donald Knuth') +_(EM_HUANY, 81, + `Harvard University machine-independent object files') +_(EM_PRISM, 82, + `SiTera Prism') +_(EM_AVR, 83, + `Atmel AVR 8-bit microcontroller') +_(EM_FR30, 84, + `Fujitsu FR30') +_(EM_D10V, 85, + `Mitsubishi D10V') +_(EM_D30V, 86, + `Mitsubishi D30V') +_(EM_V850, 87, + `NEC v850') +_(EM_M32R, 88, + `Mitsubishi M32R') +_(EM_MN10300, 89, + `Matsushita MN10300') +_(EM_MN10200, 90, + `Matsushita MN10200') +_(EM_PJ, 91, + `picoJava') +_(EM_OPENRISC, 92, + `OpenRISC 32-bit embedded processor') +_(EM_ARC_COMPACT, 93, + `ARC International ARCompact processor') +_(EM_XTENSA, 94, + `Tensilica Xtensa Architecture') +_(EM_VIDEOCORE, 95, + `Alphamosaic VideoCore processor') +_(EM_TMM_GPP, 96, + `Thompson Multimedia General Purpose Processor') +_(EM_NS32K, 97, + `National Semiconductor 32000 series') +_(EM_TPC, 98, + `Tenor Network TPC processor') +_(EM_SNP1K, 99, + `Trebia SNP 1000 processor') +_(EM_ST200, 100, + `STMicroelectronics (www.st.com) ST200 microcontroller') +_(EM_IP2K, 101, + `Ubicom IP2xxx microcontroller family') +_(EM_MAX, 102, + `MAX Processor') +_(EM_CR, 103, + `National Semiconductor CompactRISC microprocessor') +_(EM_F2MC16, 104, + `Fujitsu F2MC16') +_(EM_MSP430, 105, + `Texas Instruments embedded microcontroller msp430') +_(EM_BLACKFIN, 106, + `Analog Devices Blackfin (DSP) processor') +_(EM_SE_C33, 107, + `S1C33 Family of Seiko Epson processors') +_(EM_SEP, 108, + `Sharp embedded microprocessor') +_(EM_ARCA, 109, + `Arca RISC Microprocessor') +_(EM_UNICORE, 110, + `Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University') +_(EM_EXCESS, 111, + `eXcess: 16/32/64-bit configurable embedded CPU') +_(EM_DXP, 112, + `Icera Semiconductor Inc. Deep Execution Processor') +_(EM_ALTERA_NIOS2, 113, + `Altera Nios II soft-core processor') +_(EM_CRX, 114, + `National Semiconductor CompactRISC CRX microprocessor') +_(EM_XGATE, 115, + `Motorola XGATE embedded processor') +_(EM_C166, 116, + `Infineon C16x/XC16x processor') +_(EM_M16C, 117, + `Renesas M16C series microprocessors') +_(EM_DSPIC30F, 118, + `Microchip Technology dsPIC30F Digital Signal Controller') +_(EM_CE, 119, + `Freescale Communication Engine RISC core') +_(EM_M32C, 120, + `Renesas M32C series microprocessors') +_(EM_TSK3000, 131, + `Altium TSK3000 core') +_(EM_RS08, 132, + `Freescale RS08 embedded processor') +_(EM_SHARC, 133, + `Analog Devices SHARC family of 32-bit DSP processors') +_(EM_ECOG2, 134, + `Cyan Technology eCOG2 microprocessor') +_(EM_SCORE7, 135, + `Sunplus S+core7 RISC processor') +_(EM_DSP24, 136, + `New Japan Radio (NJR) 24-bit DSP Processor') +_(EM_VIDEOCORE3, 137, + `Broadcom VideoCore III processor') +_(EM_LATTICEMICO32, 138, + `RISC processor for Lattice FPGA architecture') +_(EM_SE_C17, 139, + `Seiko Epson C17 family') +_(EM_TI_C6000, 140, + `The Texas Instruments TMS320C6000 DSP family') +_(EM_TI_C2000, 141, + `The Texas Instruments TMS320C2000 DSP family') +_(EM_TI_C5500, 142, + `The Texas Instruments TMS320C55x DSP family') +_(EM_TI_ARP32, 143, + `Texas Instruments Application Specific RISC Processor, 32bit fetch') +_(EM_TI_PRU, 144, + `Texas Instruments Programmable Realtime Unit') +_(EM_MMDSP_PLUS, 160, + `STMicroelectronics 64bit VLIW Data Signal Processor') +_(EM_CYPRESS_M8C, 161, + `Cypress M8C microprocessor') +_(EM_R32C, 162, + `Renesas R32C series microprocessors') +_(EM_TRIMEDIA, 163, + `NXP Semiconductors TriMedia architecture family') +_(EM_QDSP6, 164, + `QUALCOMM DSP6 Processor') +_(EM_8051, 165, + `Intel 8051 and variants') +_(EM_STXP7X, 166, + `STMicroelectronics STxP7x family of configurable and extensible RISC processors') +_(EM_NDS32, 167, + `Andes Technology compact code size embedded RISC processor family') +_(EM_ECOG1, 168, + `Cyan Technology eCOG1X family') +_(EM_ECOG1X, 168, + `Cyan Technology eCOG1X family') +_(EM_MAXQ30, 169, + `Dallas Semiconductor MAXQ30 Core Micro-controllers') +_(EM_XIMO16, 170, + `New Japan Radio (NJR) 16-bit DSP Processor') +_(EM_MANIK, 171, + `M2000 Reconfigurable RISC Microprocessor') +_(EM_CRAYNV2, 172, + `Cray Inc. NV2 vector architecture') +_(EM_RX, 173, + `Renesas RX family') +_(EM_METAG, 174, + `Imagination Technologies META processor architecture') +_(EM_MCST_ELBRUS, 175, + `MCST Elbrus general purpose hardware architecture') +_(EM_ECOG16, 176, + `Cyan Technology eCOG16 family') +_(EM_CR16, 177, + `National Semiconductor CompactRISC CR16 16-bit microprocessor') +_(EM_ETPU, 178, + `Freescale Extended Time Processing Unit') +_(EM_SLE9X, 179, + `Infineon Technologies SLE9X core') +_(EM_L10M, 180, + `Intel L10M') +_(EM_K10M, 181, + `Intel K10M') +_(EM_AARCH64, 183, + `AArch64 (64-bit ARM)') +_(EM_AVR32, 185, + `Atmel Corporation 32-bit microprocessor family') +_(EM_STM8, 186, + `STMicroeletronics STM8 8-bit microcontroller') +_(EM_TILE64, 187, + `Tilera TILE64 multicore architecture family') +_(EM_TILEPRO, 188, + `Tilera TILEPro multicore architecture family') +_(EM_MICROBLAZE, 189, + `Xilinx MicroBlaze 32-bit RISC soft processor core') +_(EM_CUDA, 190, + `NVIDIA CUDA architecture') +_(EM_TILEGX, 191, + `Tilera TILE-Gx multicore architecture family') +_(EM_CLOUDSHIELD, 192, + `CloudShield architecture family') +_(EM_COREA_1ST, 193, + `KIPO-KAIST Core-A 1st generation processor family') +_(EM_COREA_2ND, 194, + `KIPO-KAIST Core-A 2nd generation processor family') +_(EM_ARC_COMPACT2, 195, + `Synopsys ARCompact V2') +_(EM_OPEN8, 196, + `Open8 8-bit RISC soft processor core') +_(EM_RL78, 197, + `Renesas RL78 family') +_(EM_VIDEOCORE5, 198, + `Broadcom VideoCore V processor') +_(EM_78KOR, 199, + `Renesas 78KOR family') +_(EM_56800EX, 200, + `Freescale 56800EX Digital Signal Controller') +_(EM_BA1, 201, + `Beyond BA1 CPU architecture') +_(EM_BA2, 202, + `Beyond BA2 CPU architecture') +_(EM_XCORE, 203, + `XMOS xCORE processor family') +_(EM_MCHP_PIC, 204, + `Microchip 8-bit PIC(r) family') +_(EM_INTELGT, 205, + `Intel Graphics Technology') +_(EM_INTEL206, 206, + `Reserved by Intel') +_(EM_INTEL207, 207, + `Reserved by Intel') +_(EM_INTEL208, 208, + `Reserved by Intel') +_(EM_INTEL209, 209, + `Reserved by Intel') +_(EM_KM32, 210, + `KM211 KM32 32-bit processor') +_(EM_KMX32, 211, + `KM211 KMX32 32-bit processor') +_(EM_KMX16, 212, + `KM211 KMX16 16-bit processor') +_(EM_KMX8, 213, + `KM211 KMX8 8-bit processor') +_(EM_KVARC, 214, + `KM211 KMX32 KVARC processor') +_(EM_CDP, 215, + `Paneve CDP architecture family') +_(EM_COGE, 216, + `Cognitive Smart Memory Processor') +_(EM_COOL, 217, + `Bluechip Systems CoolEngine') +_(EM_NORC, 218, + `Nanoradio Optimized RISC') +_(EM_CSR_KALIMBA, 219, + `CSR Kalimba architecture family') +_(EM_Z80, 220, + `Zilog Z80') +_(EM_VISIUM, 221, + `Controls and Data Services VISIUMcore processor') +_(EM_FT32, 222, + `FTDI Chip FT32 high performance 32-bit RISC architecture') +_(EM_MOXIE, 223, + `Moxie processor family') +_(EM_AMDGPU, 224, + `AMD GPU architecture') +_(EM_RISCV, 243, + `RISC-V') +_(EM_LANAI, 244, + `Lanai processor') +_(EM_CEVA, 245, + `CEVA Processor Architecture Family') +_(EM_CEVA_X2, 246, + `CEVA X2 Processor Family') +_(EM_BPF, 247, + `Linux BPF – in-kernel virtual machine') +_(EM_GRAPHCORE_IPU, 248, + `Graphcore Intelligent Processing Unit') +_(EM_IMG1, 249, + `Imagination Technologies') +_(EM_NFP, 250, + `Netronome Flow Processor (NFP)') +_(EM_VE, 251, + `NEC Vector Engine') +_(EM_CSKY, 252, + `C-SKY processor family') +_(EM_ARC_COMPACT3_64, 253, + `Synopsys ARCv2.3 64-bit') +_(EM_MCS6502, 254, + `MOS Technology MCS 6502 processor') +_(EM_ARC_COMPACT3, 255, + `Synopsys ARCv2.3 32-bit') +_(EM_KVX, 256, + `Kalray VLIW core of the MPPA processor family') +_(EM_65816, 257, + `WDC 65816/65C816') +_(EM_LOONGARCH, 258, + `Loongson LoongArch') +_(EM_KF32, 259, + `ChipON KungFu 32') +_(EM_U16_U8CORE, 260, + `LAPIS nX-U16/U8') +_(EM_TACHYUM, 261, + `Reserved for Tachyum processor') +_(EM_56800EF, 262, + `NXP 56800EF Digital Signal Controller (DSC)') +_(EM_SBF, 263, + `Solana Bytecode Format') +_(EM_AIENGINE, 264, + `AMD/Xilinx AIEngine architecture') +_(EM_SIMA_MLA, 265, + `SiMa MLA') +_(EM_BANG, 266, + `Cambricon BANG') +_(EM_LOONGGPU, 267, + `Loongson Loongarch') +') + +define(`DEFINE_ELF_MACHINE_TYPE_SYNONYMS',` +_(EM_AMD64, EM_X86_64) +_(EM_ARC_A5, EM_ARC_COMPACT) +') + +# +# ELF file types: (ET_*). +# +define(`DEFINE_ELF_TYPES',` +_(ET_NONE, 0, + `No file type') +_(ET_REL, 1, + `Relocatable object') +_(ET_EXEC, 2, + `Executable') +_(ET_DYN, 3, + `Shared object') +_(ET_CORE, 4, + `Core file') +_(ET_LOOS, 0xFE00U, + `Begin OS-specific range') +_(ET_HIOS, 0xFEFFU, + `End OS-specific range') +_(ET_LOPROC, 0xFF00U, + `Begin processor-specific range') +_(ET_HIPROC, 0xFFFFU, + `End processor-specific range') +') + +# ELF file format version numbers. +define(`DEFINE_ELF_FILE_VERSIONS',` +_(EV_NONE, 0) +_(EV_CURRENT, 1) +') + +# +# Flags for section groups. +# +define(`DEFINE_GRP_FLAGS',` +_(GRP_COMDAT, 0x1, + `COMDAT semantics') +_(GRP_MASKOS, 0x0ff00000, + `OS-specific flags') +_(GRP_MASKPROC, 0xf0000000, + `processor-specific flags') +') + +# +# Flags / mask for .gnu.versym sections. +# +define(`DEFINE_VERSYMS',` +_(VERSYM_VERSION, 0x7fff) +_(VERSYM_HIDDEN, 0x8000) +') + +# +# Flags used by program header table entries. +# +define(`DEFINE_PHDR_FLAGS',` +_(PF_X, 0x1, + `Execute') +_(PF_W, 0x2, + `Write') +_(PF_R, 0x4, + `Read') +_(PF_MASKOS, 0x0ff00000, + `OS-specific flags') +_(PF_MASKPROC, 0xf0000000, + `Processor-specific flags') +_(PF_ARM_SB, 0x10000000, + `segment contains the location addressed by the static base') +_(PF_ARM_PI, 0x20000000, + `segment is position-independent') +_(PF_ARM_ABS, 0x40000000, + `segment must be loaded at its base address') +') + +# +# Types of program header table entries. +# +define(`DEFINE_PHDR_TYPES',` +_(PT_NULL, 0UL, + `ignored entry') +_(PT_LOAD, 1UL, + `loadable segment') +_(PT_DYNAMIC, 2UL, + `contains dynamic linking information') +_(PT_INTERP, 3UL, + `names an interpreter') +_(PT_NOTE, 4UL, + `auxiliary information') +_(PT_SHLIB, 5UL, + `reserved') +_(PT_PHDR, 6UL, + `describes the program header itself') +_(PT_TLS, 7UL, + `thread local storage') +_(PT_LOOS, 0x60000000UL, + `start of OS-specific range') +_(PT_SUNW_UNWIND, 0x6464E550UL, + `Solaris/amd64 stack unwind tables') +_(PT_GNU_EH_FRAME, 0x6474E550UL, + `GCC generated .eh_frame_hdr segment') +_(PT_GNU_STACK, 0x6474E551UL, + `Stack flags') +_(PT_GNU_RELRO, 0x6474E552UL, + `Segment becomes read-only after relocation') +_(PT_OPENBSD_RANDOMIZE,0x65A3DBE6UL, + `Segment filled with random data') +_(PT_OPENBSD_WXNEEDED, 0x65A3DBE7UL, + `Program violates W^X') +_(PT_OPENBSD_BOOTDATA, 0x65A41BE6UL, + `Boot data') +_(PT_SUNWBSS, 0x6FFFFFFAUL, + `A Solaris .SUNW_bss section') +_(PT_SUNWSTACK, 0x6FFFFFFBUL, + `A Solaris process stack') +_(PT_SUNWDTRACE, 0x6FFFFFFCUL, + `Used by dtrace(1)') +_(PT_SUNWCAP, 0x6FFFFFFDUL, + `Special hardware capability requirements') +_(PT_HIOS, 0x6FFFFFFFUL, + `end of OS-specific range') +_(PT_LOPROC, 0x70000000UL, + `start of processor-specific range') +_(PT_ARM_ARCHEXT, 0x70000000UL, + `platform architecture compatibility information') +_(PT_ARM_EXIDX, 0x70000001UL, + `exception unwind tables') +_(PT_MIPS_REGINFO, 0x70000000UL, + `register usage information') +_(PT_MIPS_RTPROC, 0x70000001UL, + `runtime procedure table') +_(PT_MIPS_OPTIONS, 0x70000002UL, + `options segment') +_(PT_HIPROC, 0x7FFFFFFFUL, + `end of processor-specific range') +') + +define(`DEFINE_PHDR_TYPE_SYNONYMS',` +_(PT_ARM_UNWIND, PT_ARM_EXIDX) +_(PT_HISUNW, PT_HIOS) +_(PT_LOSUNW, PT_SUNWBSS) +') + +# +# Section flags. +# +define(`DEFINE_SECTION_FLAGS',` +_(SHF_WRITE, 0x1, + `writable during program execution') +_(SHF_ALLOC, 0x2, + `occupies memory during program execution') +_(SHF_EXECINSTR, 0x4, + `executable instructions') +_(SHF_MERGE, 0x10, + `may be merged to prevent duplication') +_(SHF_STRINGS, 0x20, + `NUL-terminated character strings') +_(SHF_INFO_LINK, 0x40, + `the sh_info field holds a link') +_(SHF_LINK_ORDER, 0x80, + `special ordering requirements during linking') +_(SHF_OS_NONCONFORMING, 0x100, + `requires OS-specific processing during linking') +_(SHF_GROUP, 0x200, + `member of a section group') +_(SHF_TLS, 0x400, + `holds thread-local storage') +_(SHF_COMPRESSED, 0x800, + `holds compressed data') +_(SHF_MASKOS, 0x0FF00000UL, + `bits reserved for OS-specific semantics') +_(SHF_AMD64_LARGE, 0x10000000UL, + `section uses large code model') +_(SHF_ENTRYSECT, 0x10000000UL, + `section contains an entry point (ARM)') +_(SHF_COMDEF, 0x80000000UL, + `section may be multiply defined in input to link step (ARM)') +_(SHF_MIPS_GPREL, 0x10000000UL, + `section must be part of global data area') +_(SHF_MIPS_MERGE, 0x20000000UL, + `section data should be merged to eliminate duplication') +_(SHF_MIPS_ADDR, 0x40000000UL, + `section data is addressed by default') +_(SHF_MIPS_STRING, 0x80000000UL, + `section data is string data by default') +_(SHF_MIPS_NOSTRIP, 0x08000000UL, + `section data may not be stripped') +_(SHF_MIPS_LOCAL, 0x04000000UL, + `section data local to process') +_(SHF_MIPS_NAMES, 0x02000000UL, + `linker must generate implicit hidden weak names') +_(SHF_MIPS_NODUPE, 0x01000000UL, + `linker must retain only one copy') +_(SHF_ORDERED, 0x40000000UL, + `section is ordered with respect to other sections') +_(SHF_EXCLUDE, 0x80000000UL, + `section is excluded from executables and shared objects') +_(SHF_MASKPROC, 0xF0000000UL, + `bits reserved for processor-specific semantics') +') + +# +# Special section indices. +# +define(`DEFINE_SECTION_INDICES',` +_(SHN_UNDEF, 0, + `undefined section') +_(SHN_LORESERVE, 0xFF00U, + `start of reserved area') +_(SHN_LOPROC, 0xFF00U, + `start of processor-specific range') +_(SHN_BEFORE, 0xFF00U, + `used for section ordering') +_(SHN_AFTER, 0xFF01U, + `used for section ordering') +_(SHN_AMD64_LCOMMON, 0xFF02U, + `large common block label') +_(SHN_MIPS_ACOMMON, 0xFF00U, + `allocated common symbols in a DSO') +_(SHN_MIPS_TEXT, 0xFF01U, + `Reserved (obsolete)') +_(SHN_MIPS_DATA, 0xFF02U, + `Reserved (obsolete)') +_(SHN_MIPS_SCOMMON, 0xFF03U, + `gp-addressable common symbols') +_(SHN_MIPS_SUNDEFINED, 0xFF04U, + `gp-addressable undefined symbols') +_(SHN_MIPS_LCOMMON, 0xFF05U, + `local common symbols') +_(SHN_MIPS_LUNDEFINED, 0xFF06U, + `local undefined symbols') +_(SHN_HIPROC, 0xFF1FU, + `end of processor-specific range') +_(SHN_LOOS, 0xFF20U, + `start of OS-specific range') +_(SHN_SUNW_IGNORE, 0xFF3FU, + `used by dtrace') +_(SHN_HIOS, 0xFF3FU, + `end of OS-specific range') +_(SHN_ABS, 0xFFF1U, + `absolute references') +_(SHN_COMMON, 0xFFF2U, + `references to COMMON areas') +_(SHN_XINDEX, 0xFFFFU, + `extended index') +_(SHN_HIRESERVE, 0xFFFFU, + `end of reserved area') +') + +# +# Section types. +# +define(`DEFINE_SECTION_TYPES',` +_(SHT_NULL, 0, `inactive header') +_(SHT_PROGBITS, 1, `program defined information') +_(SHT_SYMTAB, 2, `symbol table') +_(SHT_STRTAB, 3, `string table') +_(SHT_RELA, 4, + `relocation entries with addends') +_(SHT_HASH, 5, `symbol hash table') +_(SHT_DYNAMIC, 6, + `information for dynamic linking') +_(SHT_NOTE, 7, `additional notes') +_(SHT_NOBITS, 8, `section occupying no space') +_(SHT_REL, 9, + `relocation entries without addends') +_(SHT_SHLIB, 10, `reserved') +_(SHT_DYNSYM, 11, `symbol table') +_(SHT_INIT_ARRAY, 14, + `pointers to initialization functions') +_(SHT_FINI_ARRAY, 15, + `pointers to termination functions') +_(SHT_PREINIT_ARRAY, 16, + `pointers to functions called before initialization') +_(SHT_GROUP, 17, `defines a section group') +_(SHT_SYMTAB_SHNDX, 18, + `used for extended section numbering') +_(SHT_LOOS, 0x60000000UL, + `start of OS-specific range') +_(SHT_SUNW_dof, 0x6FFFFFF4UL, + `used by dtrace') +_(SHT_SUNW_cap, 0x6FFFFFF5UL, + `capability requirements') +_(SHT_GNU_ATTRIBUTES, 0x6FFFFFF5UL, + `object attributes') +_(SHT_SUNW_SIGNATURE, 0x6FFFFFF6UL, + `module verification signature') +_(SHT_GNU_HASH, 0x6FFFFFF6UL, + `GNU Hash sections') +_(SHT_GNU_LIBLIST, 0x6FFFFFF7UL, + `List of libraries to be prelinked') +_(SHT_SUNW_ANNOTATE, 0x6FFFFFF7UL, + `special section where unresolved references are allowed') +_(SHT_SUNW_DEBUGSTR, 0x6FFFFFF8UL, + `debugging information') +_(SHT_CHECKSUM, 0x6FFFFFF8UL, + `checksum for dynamic shared objects') +_(SHT_SUNW_DEBUG, 0x6FFFFFF9UL, + `debugging information') +_(SHT_SUNW_move, 0x6FFFFFFAUL, + `information to handle partially initialized symbols') +_(SHT_SUNW_COMDAT, 0x6FFFFFFBUL, + `section supporting merging of multiple copies of data') +_(SHT_SUNW_syminfo, 0x6FFFFFFCUL, + `additional symbol information') +_(SHT_SUNW_verdef, 0x6FFFFFFDUL, + `symbol versioning information') +_(SHT_SUNW_verneed, 0x6FFFFFFEUL, + `symbol versioning requirements') +_(SHT_SUNW_versym, 0x6FFFFFFFUL, + `symbol versioning table') +_(SHT_HIOS, 0x6FFFFFFFUL, + `end of OS-specific range') +_(SHT_LOPROC, 0x70000000UL, + `start of processor-specific range') +_(SHT_ARM_EXIDX, 0x70000001UL, + `exception index table') +_(SHT_ARM_PREEMPTMAP, 0x70000002UL, + `BPABI DLL dynamic linking preemption map') +_(SHT_ARM_ATTRIBUTES, 0x70000003UL, + `object file compatibility attributes') +_(SHT_ARM_DEBUGOVERLAY, 0x70000004UL, + `overlay debug information') +_(SHT_ARM_OVERLAYSECTION, 0x70000005UL, + `overlay debug information') +_(SHT_MIPS_LIBLIST, 0x70000000UL, + `DSO library information used in link') +_(SHT_MIPS_MSYM, 0x70000001UL, + `MIPS symbol table extension') +_(SHT_MIPS_CONFLICT, 0x70000002UL, + `symbol conflicting with DSO-defined symbols ') +_(SHT_MIPS_GPTAB, 0x70000003UL, + `global pointer table') +_(SHT_MIPS_UCODE, 0x70000004UL, + `reserved') +_(SHT_MIPS_DEBUG, 0x70000005UL, + `reserved (obsolete debug information)') +_(SHT_MIPS_REGINFO, 0x70000006UL, + `register usage information') +_(SHT_MIPS_PACKAGE, 0x70000007UL, + `OSF reserved') +_(SHT_MIPS_PACKSYM, 0x70000008UL, + `OSF reserved') +_(SHT_MIPS_RELD, 0x70000009UL, + `dynamic relocation') +_(SHT_MIPS_IFACE, 0x7000000BUL, + `subprogram interface information') +_(SHT_MIPS_CONTENT, 0x7000000CUL, + `section content classification') +_(SHT_MIPS_OPTIONS, 0x7000000DUL, + `general options') +_(SHT_MIPS_DELTASYM, 0x7000001BUL, + `Delta C++: symbol table') +_(SHT_MIPS_DELTAINST, 0x7000001CUL, + `Delta C++: instance table') +_(SHT_MIPS_DELTACLASS, 0x7000001DUL, + `Delta C++: class table') +_(SHT_MIPS_DWARF, 0x7000001EUL, + `DWARF debug information') +_(SHT_MIPS_DELTADECL, 0x7000001FUL, + `Delta C++: declarations') +_(SHT_MIPS_SYMBOL_LIB, 0x70000020UL, + `symbol-to-library mapping') +_(SHT_MIPS_EVENTS, 0x70000021UL, + `event locations') +_(SHT_MIPS_TRANSLATE, 0x70000022UL, + `???') +_(SHT_MIPS_PIXIE, 0x70000023UL, + `special pixie sections') +_(SHT_MIPS_XLATE, 0x70000024UL, + `address translation table') +_(SHT_MIPS_XLATE_DEBUG, 0x70000025UL, + `SGI internal address translation table') +_(SHT_MIPS_WHIRL, 0x70000026UL, + `intermediate code') +_(SHT_MIPS_EH_REGION, 0x70000027UL, + `C++ exception handling region info') +_(SHT_MIPS_XLATE_OLD, 0x70000028UL, + `obsolete') +_(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, + `runtime procedure descriptor table exception information') +_(SHT_MIPS_ABIFLAGS, 0x7000002AUL, + `ABI flags') +_(SHT_SPARC_GOTDATA, 0x70000000UL, + `SPARC-specific data') +_(SHT_X86_64_UNWIND, 0x70000001UL, + `unwind tables for the AMD64') +_(SHT_ORDERED, 0x7FFFFFFFUL, + `sort entries in the section') +_(SHT_HIPROC, 0x7FFFFFFFUL, + `end of processor-specific range') +_(SHT_LOUSER, 0x80000000UL, + `start of application-specific range') +_(SHT_HIUSER, 0xFFFFFFFFUL, + `end of application-specific range') +') + +# Aliases for section types. +define(`DEFINE_SECTION_TYPE_ALIASES',` +_(SHT_AMD64_UNWIND, SHT_X86_64_UNWIND) +_(SHT_GNU_verdef, SHT_SUNW_verdef) +_(SHT_GNU_verneed, SHT_SUNW_verneed) +_(SHT_GNU_versym, SHT_SUNW_versym) +') + +# +# Symbol binding information. +# +define(`DEFINE_SYMBOL_BINDINGS',` +_(STB_LOCAL, 0, + `not visible outside defining object file') +_(STB_GLOBAL, 1, + `visible across all object files being combined') +_(STB_WEAK, 2, + `visible across all object files but with low precedence') +_(STB_LOOS, 10, + `start of OS-specific range') +_(STB_GNU_UNIQUE, 10, + `unique symbol (GNU)') +_(STB_HIOS, 12, + `end of OS-specific range') +_(STB_LOPROC, 13, + `start of processor-specific range') +_(STB_HIPROC, 15, + `end of processor-specific range') +') + +# +# Symbol types +# +define(`DEFINE_SYMBOL_TYPES',` +_(STT_NOTYPE, 0, + `unspecified type') +_(STT_OBJECT, 1, + `data object') +_(STT_FUNC, 2, + `executable code') +_(STT_SECTION, 3, + `section') +_(STT_FILE, 4, + `source file') +_(STT_COMMON, 5, + `uninitialized common block') +_(STT_TLS, 6, + `thread local storage') +_(STT_LOOS, 10, + `start of OS-specific types') +_(STT_GNU_IFUNC, 10, + `indirect function') +_(STT_HIOS, 12, + `end of OS-specific types') +_(STT_LOPROC, 13, + `start of processor-specific types') +_(STT_ARM_TFUNC, 13, + `Thumb function (GNU)') +_(STT_ARM_16BIT, 15, + `Thumb label (GNU)') +_(STT_SPARC_REGISTER, 13, + `SPARC register information') +_(STT_HIPROC, 15, + `end of processor-specific types') +') + +# Additional symbol type related constants. +define(`DEFINE_SYMBOL_TYPES_ADDITIONAL_CONSTANTS',` +_(STT_NUM, 7, + `the number of symbol types') +') + +# +# Symbol binding. +# +define(`DEFINE_SYMBOL_BINDING_KINDS',` +_(SYMINFO_BT_SELF, 0xFFFFU, + `bound to self') +_(SYMINFO_BT_PARENT, 0xFFFEU, + `bound to parent') +_(SYMINFO_BT_NONE, 0xFFFDU, + `no special binding') +') + +# +# Symbol visibility. +# +define(`DEFINE_SYMBOL_VISIBILITIES',` +_(STV_DEFAULT, 0, + `as specified by symbol type') +_(STV_INTERNAL, 1, + `as defined by processor semantics') +_(STV_HIDDEN, 2, + `hidden from other components') +_(STV_PROTECTED, 3, + `local references are not preemptable') +') + +# +# Symbol flags. +# +define(`DEFINE_SYMBOL_FLAGS',` +_(SYMINFO_FLG_DIRECT, 0x01, + `directly assocated reference') +_(SYMINFO_FLG_COPY, 0x04, + `definition by copy-relocation') +_(SYMINFO_FLG_LAZYLOAD, 0x08, + `object should be lazily loaded') +_(SYMINFO_FLG_DIRECTBIND, 0x10, + `reference should be directly bound') +_(SYMINFO_FLG_NOEXTDIRECT, 0x20, + `external references not allowed to bind to definition') +') + +# +# Version dependencies. +# +define(`DEFINE_VERSIONING_DEPENDENCIES',` +_(VER_NDX_LOCAL, 0, + `local scope') +_(VER_NDX_GLOBAL, 1, + `global scope') +') + +# +# Version flags. +# +define(`DEFINE_VERSIONING_FLAGS',` +_(VER_FLG_BASE, 0x1, + `file version') +_(VER_FLG_WEAK, 0x2, + `weak version') +') + +# +# Version needs +# +define(`DEFINE_VERSIONING_NEEDS',` +_(VER_NEED_NONE, 0, + `invalid version') +_(VER_NEED_CURRENT, 1, + `current version') +') + +# +# Versioning numbers. +# +define(`DEFINE_VERSIONING_NUMBERS',` +_(VER_DEF_NONE, 0, + `invalid version') +_(VER_DEF_CURRENT, 1, + `current version') +') + +# +# Relocation types. +# +define(`DEFINE_386_RELOCATIONS',` +_(R_386_NONE, 0) +_(R_386_32, 1) +_(R_386_PC32, 2) +_(R_386_GOT32, 3) +_(R_386_PLT32, 4) +_(R_386_COPY, 5) +_(R_386_GLOB_DAT, 6) +_(R_386_JMP_SLOT, 7) +_(R_386_JUMP_SLOT, 7) +_(R_386_RELATIVE, 8) +_(R_386_GOTOFF, 9) +_(R_386_GOTPC, 10) +_(R_386_32PLT, 11) +_(R_386_TLS_TPOFF, 14) +_(R_386_TLS_IE, 15) +_(R_386_TLS_GOTIE, 16) +_(R_386_TLS_LE, 17) +_(R_386_TLS_GD, 18) +_(R_386_TLS_LDM, 19) +_(R_386_16, 20) +_(R_386_PC16, 21) +_(R_386_8, 22) +_(R_386_PC8, 23) +_(R_386_TLS_GD_32, 24) +_(R_386_TLS_GD_PUSH, 25) +_(R_386_TLS_GD_CALL, 26) +_(R_386_TLS_GD_POP, 27) +_(R_386_TLS_LDM_32, 28) +_(R_386_TLS_LDM_PUSH, 29) +_(R_386_TLS_LDM_CALL, 30) +_(R_386_TLS_LDM_POP, 31) +_(R_386_TLS_LDO_32, 32) +_(R_386_TLS_IE_32, 33) +_(R_386_TLS_LE_32, 34) +_(R_386_TLS_DTPMOD32, 35) +_(R_386_TLS_DTPOFF32, 36) +_(R_386_TLS_TPOFF32, 37) +_(R_386_SIZE32, 38) +_(R_386_TLS_GOTDESC, 39) +_(R_386_TLS_DESC_CALL, 40) +_(R_386_TLS_DESC, 41) +_(R_386_IRELATIVE, 42) +_(R_386_GOT32X, 43) +') + +define(`DEFINE_AARCH64_RELOCATIONS',` +_(R_AARCH64_NONE, 0) +_(R_AARCH64_ABS64, 257) +_(R_AARCH64_ABS32, 258) +_(R_AARCH64_ABS16, 259) +_(R_AARCH64_PREL64, 260) +_(R_AARCH64_PREL32, 261) +_(R_AARCH64_PREL16, 262) +_(R_AARCH64_MOVW_UABS_G0, 263) +_(R_AARCH64_MOVW_UABS_G0_NC, 264) +_(R_AARCH64_MOVW_UABS_G1, 265) +_(R_AARCH64_MOVW_UABS_G1_NC, 266) +_(R_AARCH64_MOVW_UABS_G2, 267) +_(R_AARCH64_MOVW_UABS_G2_NC, 268) +_(R_AARCH64_MOVW_UABS_G3, 269) +_(R_AARCH64_MOVW_SABS_G0, 270) +_(R_AARCH64_MOVW_SABS_G1, 271) +_(R_AARCH64_MOVW_SABS_G2, 272) +_(R_AARCH64_LD_PREL_LO19, 273) +_(R_AARCH64_ADR_PREL_LO21, 274) +_(R_AARCH64_ADR_PREL_PG_HI21, 275) +_(R_AARCH64_ADR_PREL_PG_HI21_NC, 276) +_(R_AARCH64_ADD_ABS_LO12_NC, 277) +_(R_AARCH64_LDST8_ABS_LO12_NC, 278) +_(R_AARCH64_TSTBR14, 279) +_(R_AARCH64_CONDBR19, 280) +_(R_AARCH64_JUMP26, 282) +_(R_AARCH64_CALL26, 283) +_(R_AARCH64_LDST16_ABS_LO12_NC, 284) +_(R_AARCH64_LDST32_ABS_LO12_NC, 285) +_(R_AARCH64_LDST64_ABS_LO12_NC, 286) +_(R_AARCH64_MOVW_PREL_G0, 287) +_(R_AARCH64_MOVW_PREL_G0_NC, 288) +_(R_AARCH64_MOVW_PREL_G1, 289) +_(R_AARCH64_MOVW_PREL_G1_NC, 290) +_(R_AARCH64_MOVW_PREL_G2, 291) +_(R_AARCH64_MOVW_PREL_G2_NC, 292) +_(R_AARCH64_MOVW_PREL_G3, 293) +_(R_AARCH64_LDST128_ABS_LO12_NC, 299) +_(R_AARCH64_MOVW_GOTOFF_G0, 300) +_(R_AARCH64_MOVW_GOTOFF_G0_NC, 301) +_(R_AARCH64_MOVW_GOTOFF_G1, 302) +_(R_AARCH64_MOVW_GOTOFF_G1_NC, 303) +_(R_AARCH64_MOVW_GOTOFF_G2, 304) +_(R_AARCH64_MOVW_GOTOFF_G2_NC, 305) +_(R_AARCH64_MOVW_GOTOFF_G3, 306) +_(R_AARCH64_GOTREL64, 307) +_(R_AARCH64_GOTREL32, 308) +_(R_AARCH64_GOT_LD_PREL19, 309) +_(R_AARCH64_LD64_GOTOFF_LO15, 310) +_(R_AARCH64_ADR_GOT_PAGE, 311) +_(R_AARCH64_LD64_GOT_LO12_NC, 312) +_(R_AARCH64_LD64_GOTPAGE_LO15, 313) +_(R_AARCH64_TLSGD_ADR_PREL21, 512) +_(R_AARCH64_TLSGD_ADR_PAGE21, 513) +_(R_AARCH64_TLSGD_ADD_LO12_NC, 514) +_(R_AARCH64_TLSGD_MOVW_G1, 515) +_(R_AARCH64_TLSGD_MOVW_G0_NC, 516) +_(R_AARCH64_TLSLD_ADR_PREL21, 517) +_(R_AARCH64_TLSLD_ADR_PAGE21, 518) +_(R_AARCH64_TLSLD_ADD_LO12_NC, 519) +_(R_AARCH64_TLSLD_MOVW_G1, 520) +_(R_AARCH64_TLSLD_MOVW_G0_NC, 521) +_(R_AARCH64_TLSLD_LD_PREL19, 522) +_(R_AARCH64_TLSLD_MOVW_DTPREL_G2, 523) +_(R_AARCH64_TLSLD_MOVW_DTPREL_G1, 524) +_(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, 525) +_(R_AARCH64_TLSLD_MOVW_DTPREL_G0, 526) +_(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, 527) +_(R_AARCH64_TLSLD_ADD_DTPREL_HI12, 529) +_(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, 530) +_(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, 531) +_(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, 532) +_(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, 533) +_(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, 534) +_(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, 535) +_(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, 536) +_(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, 537) +_(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, 538) +_(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, 539) +_(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, 540) +_(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 541) +_(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, 542) +_(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, 543) +_(R_AARCH64_TLSLE_MOVW_TPREL_G2, 544) +_(R_AARCH64_TLSLE_MOVW_TPREL_G1, 545) +_(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 546) +_(R_AARCH64_TLSLE_MOVW_TPREL_G0, 547) +_(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 548) +_(R_AARCH64_TLSLE_ADD_TPREL_HI12, 549) +_(R_AARCH64_TLSLE_ADD_TPREL_LO12, 550) +_(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, 551) +_(R_AARCH64_TLSLE_LDST8_TPREL_LO12, 552) +_(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, 553) +_(R_AARCH64_TLSLE_LDST16_TPREL_LO12, 554) +_(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, 555) +_(R_AARCH64_TLSLE_LDST32_TPREL_LO12, 556) +_(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, 557) +_(R_AARCH64_TLSLE_LDST64_TPREL_LO12, 558) +_(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 559) +_(R_AARCH64_TLSDESC_LD_PREL19, 560) +_(R_AARCH64_TLSDESC_ADR_PREL21, 561) +_(R_AARCH64_TLSDESC_ADR_PAGE21, 562) +_(R_AARCH64_TLSDESC_LD64_LO12, 563) +_(R_AARCH64_TLSDESC_ADD_LO12, 564) +_(R_AARCH64_TLSDESC_OFF_G1, 565) +_(R_AARCH64_TLSDESC_OFF_G0_NC, 566) +_(R_AARCH64_TLSDESC_LDR, 567) +_(R_AARCH64_TLSDESC_ADD, 568) +_(R_AARCH64_TLSDESC_CALL, 569) +_(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 570) +_(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 571) +_(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 572) +_(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 573) +_(R_AARCH64_COPY, 1024) +_(R_AARCH64_GLOB_DAT, 1025) +_(R_AARCH64_JUMP_SLOT, 1026) +_(R_AARCH64_RELATIVE, 1027) +_(R_AARCH64_TLS_DTPREL64, 1028) +_(R_AARCH64_TLS_DTPMOD64, 1029) +_(R_AARCH64_TLS_TPREL64, 1030) +_(R_AARCH64_TLSDESC, 1031) +_(R_AARCH64_IRELATIVE, 1032) +') + +# +# These are the symbols used in the Sun ``Linkers and Loaders +# Guide'', Document No: 817-1984-17. See the X86_64 relocations list +# below for the spellings used in the ELF specification. +# +define(`DEFINE_AMD64_RELOCATIONS',` +_(R_AMD64_NONE, 0) +_(R_AMD64_64, 1) +_(R_AMD64_PC32, 2) +_(R_AMD64_GOT32, 3) +_(R_AMD64_PLT32, 4) +_(R_AMD64_COPY, 5) +_(R_AMD64_GLOB_DAT, 6) +_(R_AMD64_JUMP_SLOT, 7) +_(R_AMD64_RELATIVE, 8) +_(R_AMD64_GOTPCREL, 9) +_(R_AMD64_32, 10) +_(R_AMD64_32S, 11) +_(R_AMD64_16, 12) +_(R_AMD64_PC16, 13) +_(R_AMD64_8, 14) +_(R_AMD64_PC8, 15) +_(R_AMD64_PC64, 24) +_(R_AMD64_GOTOFF64, 25) +_(R_AMD64_GOTPC32, 26) +') + +# +# Relocation definitions from the ARM ELF ABI, version "ARM IHI +# 0044E" released on 30th November 2012. +# +define(`DEFINE_ARM_RELOCATIONS',` +_(R_ARM_NONE, 0) +_(R_ARM_PC24, 1) +_(R_ARM_ABS32, 2) +_(R_ARM_REL32, 3) +_(R_ARM_LDR_PC_G0, 4) +_(R_ARM_ABS16, 5) +_(R_ARM_ABS12, 6) +_(R_ARM_THM_ABS5, 7) +_(R_ARM_ABS8, 8) +_(R_ARM_SBREL32, 9) +_(R_ARM_THM_CALL, 10) +_(R_ARM_THM_PC8, 11) +_(R_ARM_BREL_ADJ, 12) +_(R_ARM_SWI24, 13) +_(R_ARM_TLS_DESC, 13) +_(R_ARM_THM_SWI8, 14) +_(R_ARM_XPC25, 15) +_(R_ARM_THM_XPC22, 16) +_(R_ARM_TLS_DTPMOD32, 17) +_(R_ARM_TLS_DTPOFF32, 18) +_(R_ARM_TLS_TPOFF32, 19) +_(R_ARM_COPY, 20) +_(R_ARM_GLOB_DAT, 21) +_(R_ARM_JUMP_SLOT, 22) +_(R_ARM_RELATIVE, 23) +_(R_ARM_GOTOFF32, 24) +_(R_ARM_BASE_PREL, 25) +_(R_ARM_GOT_BREL, 26) +_(R_ARM_PLT32, 27) +_(R_ARM_CALL, 28) +_(R_ARM_JUMP24, 29) +_(R_ARM_THM_JUMP24, 30) +_(R_ARM_BASE_ABS, 31) +_(R_ARM_ALU_PCREL_7_0, 32) +_(R_ARM_ALU_PCREL_15_8, 33) +_(R_ARM_ALU_PCREL_23_15, 34) +_(R_ARM_LDR_SBREL_11_0_NC, 35) +_(R_ARM_ALU_SBREL_19_12_NC, 36) +_(R_ARM_ALU_SBREL_27_20_CK, 37) +_(R_ARM_TARGET1, 38) +_(R_ARM_SBREL31, 39) +_(R_ARM_V4BX, 40) +_(R_ARM_TARGET2, 41) +_(R_ARM_PREL31, 42) +_(R_ARM_MOVW_ABS_NC, 43) +_(R_ARM_MOVT_ABS, 44) +_(R_ARM_MOVW_PREL_NC, 45) +_(R_ARM_MOVT_PREL, 46) +_(R_ARM_THM_MOVW_ABS_NC, 47) +_(R_ARM_THM_MOVT_ABS, 48) +_(R_ARM_THM_MOVW_PREL_NC, 49) +_(R_ARM_THM_MOVT_PREL, 50) +_(R_ARM_THM_JUMP19, 51) +_(R_ARM_THM_JUMP6, 52) +_(R_ARM_THM_ALU_PREL_11_0, 53) +_(R_ARM_THM_PC12, 54) +_(R_ARM_ABS32_NOI, 55) +_(R_ARM_REL32_NOI, 56) +_(R_ARM_ALU_PC_G0_NC, 57) +_(R_ARM_ALU_PC_G0, 58) +_(R_ARM_ALU_PC_G1_NC, 59) +_(R_ARM_ALU_PC_G1, 60) +_(R_ARM_ALU_PC_G2, 61) +_(R_ARM_LDR_PC_G1, 62) +_(R_ARM_LDR_PC_G2, 63) +_(R_ARM_LDRS_PC_G0, 64) +_(R_ARM_LDRS_PC_G1, 65) +_(R_ARM_LDRS_PC_G2, 66) +_(R_ARM_LDC_PC_G0, 67) +_(R_ARM_LDC_PC_G1, 68) +_(R_ARM_LDC_PC_G2, 69) +_(R_ARM_ALU_SB_G0_NC, 70) +_(R_ARM_ALU_SB_G0, 71) +_(R_ARM_ALU_SB_G1_NC, 72) +_(R_ARM_ALU_SB_G1, 73) +_(R_ARM_ALU_SB_G2, 74) +_(R_ARM_LDR_SB_G0, 75) +_(R_ARM_LDR_SB_G1, 76) +_(R_ARM_LDR_SB_G2, 77) +_(R_ARM_LDRS_SB_G0, 78) +_(R_ARM_LDRS_SB_G1, 79) +_(R_ARM_LDRS_SB_G2, 80) +_(R_ARM_LDC_SB_G0, 81) +_(R_ARM_LDC_SB_G1, 82) +_(R_ARM_LDC_SB_G2, 83) +_(R_ARM_MOVW_BREL_NC, 84) +_(R_ARM_MOVT_BREL, 85) +_(R_ARM_MOVW_BREL, 86) +_(R_ARM_THM_MOVW_BREL_NC, 87) +_(R_ARM_THM_MOVT_BREL, 88) +_(R_ARM_THM_MOVW_BREL, 89) +_(R_ARM_TLS_GOTDESC, 90) +_(R_ARM_TLS_CALL, 91) +_(R_ARM_TLS_DESCSEQ, 92) +_(R_ARM_THM_TLS_CALL, 93) +_(R_ARM_PLT32_ABS, 94) +_(R_ARM_GOT_ABS, 95) +_(R_ARM_GOT_PREL, 96) +_(R_ARM_GOT_BREL12, 97) +_(R_ARM_GOTOFF12, 98) +_(R_ARM_GOTRELAX, 99) +_(R_ARM_GNU_VTENTRY, 100) +_(R_ARM_GNU_VTINHERIT, 101) +_(R_ARM_THM_JUMP11, 102) +_(R_ARM_THM_JUMP8, 103) +_(R_ARM_TLS_GD32, 104) +_(R_ARM_TLS_LDM32, 105) +_(R_ARM_TLS_LDO32, 106) +_(R_ARM_TLS_IE32, 107) +_(R_ARM_TLS_LE32, 108) +_(R_ARM_TLS_LDO12, 109) +_(R_ARM_TLS_LE12, 110) +_(R_ARM_TLS_IE12GP, 111) +_(R_ARM_PRIVATE_0, 112) +_(R_ARM_PRIVATE_1, 113) +_(R_ARM_PRIVATE_2, 114) +_(R_ARM_PRIVATE_3, 115) +_(R_ARM_PRIVATE_4, 116) +_(R_ARM_PRIVATE_5, 117) +_(R_ARM_PRIVATE_6, 118) +_(R_ARM_PRIVATE_7, 119) +_(R_ARM_PRIVATE_8, 120) +_(R_ARM_PRIVATE_9, 121) +_(R_ARM_PRIVATE_10, 122) +_(R_ARM_PRIVATE_11, 123) +_(R_ARM_PRIVATE_12, 124) +_(R_ARM_PRIVATE_13, 125) +_(R_ARM_PRIVATE_14, 126) +_(R_ARM_PRIVATE_15, 127) +_(R_ARM_ME_TOO, 128) +_(R_ARM_THM_TLS_DESCSEQ16, 129) +_(R_ARM_THM_TLS_DESCSEQ32, 130) +_(R_ARM_THM_GOT_BREL12, 131) +_(R_ARM_IRELATIVE, 140) +') + +define(`DEFINE_IA64_RELOCATIONS',` +_(R_IA_64_NONE, 0) +_(R_IA64_NONE, 0) +_(R_IA_64_IMM14, 0x21) +_(R_IA64_IMM14, 0x21) +_(R_IA_64_IMM22, 0x22) +_(R_IA64_IMM22, 0x22) +_(R_IA_64_IMM64, 0x23) +_(R_IA64_IMM64, 0x23) +_(R_IA_64_DIR32MSB, 0x24) +_(R_IA64_DIR32MSB, 0x24) +_(R_IA_64_DIR32LSB, 0x25) +_(R_IA64_DIR32LSB, 0x25) +_(R_IA_64_DIR64MSB, 0x26) +_(R_IA64_DIR64MSB, 0x26) +_(R_IA_64_DIR64LSB, 0x27) +_(R_IA64_DIR64LSB, 0x27) +_(R_IA_64_GPREL22, 0x2a) +_(R_IA64_GPREL22, 0x2a) +_(R_IA_64_GPREL64I, 0x2b) +_(R_IA64_GPREL64I, 0x2b) +_(R_IA_64_GPREL32MSB, 0x2c) +_(R_IA_64_GPREL32LSB, 0x2d) +_(R_IA_64_GPREL64MSB, 0x2e) +_(R_IA64_GPREL64MSB, 0x2e) +_(R_IA_64_GPREL64LSB, 0x2f) +_(R_IA64_GPREL64LSB, 0x2f) +_(R_IA_64_LTOFF22, 0x32) +_(R_IA64_LTOFF22, 0x32) +_(R_IA_64_LTOFF64I, 0x33) +_(R_IA64_LTOFF64I, 0x33) +_(R_IA_64_PLTOFF22, 0x3a) +_(R_IA64_PLTOFF22, 0x3a) +_(R_IA_64_PLTOFF64I, 0x3b) +_(R_IA64_PLTOFF64I, 0x3b) +_(R_IA_64_PLTOFF64MSB, 0x3e) +_(R_IA64_PLTOFF64MSB, 0x3e) +_(R_IA_64_PLTOFF64LSB, 0x3f) +_(R_IA64_PLTOFF64LSB, 0x3f) +_(R_IA_64_FPTR64I, 0x43) +_(R_IA64_FPTR64I, 0x43) +_(R_IA_64_FPTR32MSB, 0x44) +_(R_IA64_FPTR32MSB, 0x44) +_(R_IA_64_FPTR32LSB, 0x45) +_(R_IA64_FPTR32LSB, 0x45) +_(R_IA_64_FPTR64MSB, 0x46) +_(R_IA64_FPTR64MSB, 0x46) +_(R_IA_64_FPTR64LSB, 0x47) +_(R_IA64_FPTR64LSB, 0x47) +_(R_IA_64_PCREL60B, 0x48) +_(R_IA_64_PCREL21B, 0x49) +_(R_IA64_PCREL21B, 0x49) +_(R_IA_64_PCREL21M, 0x4a) +_(R_IA64_PCREL21M, 0x4a) +_(R_IA_64_PCREL21F, 0x4b) +_(R_IA64_PCREL21F, 0x4b) +_(R_IA_64_PCREL32MSB, 0x4c) +_(R_IA64_PCREL32MSB, 0x4c) +_(R_IA_64_PCREL32LSB, 0x4d) +_(R_IA64_PCREL32LSB, 0x4d) +_(R_IA_64_PCREL64MSB, 0x4e) +_(R_IA64_PCREL64MSB, 0x4e) +_(R_IA_64_PCREL64LSB, 0x4f) +_(R_IA64_PCREL64LSB, 0x4f) +_(R_IA_64_LTOFF_FPTR22, 0x52) +_(R_IA64_LTOFF_FPTR22, 0x52) +_(R_IA_64_LTOFF_FPTR64I, 0x53) +_(R_IA64_LTOFF_FPTR64I, 0x53) +_(R_IA_64_LTOFF_FPTR32MSB, 0x54) +_(R_IA64_LTOFF_FPTR32MSB, 0x54) +_(R_IA_64_LTOFF_FPTR32LSB, 0x55) +_(R_IA64_LTOFF_FPTR32LSB, 0x55) +_(R_IA_64_LTOFF_FPTR64MSB, 0x56) +_(R_IA64_LTOFF_FPTR64MSB, 0x56) +_(R_IA_64_LTOFF_FPTR64LSB, 0x57) +_(R_IA64_LTOFF_FPTR64LSB, 0x57) +_(R_IA_64_SEGREL32MSB, 0x5c) +_(R_IA64_SEGREL32MSB, 0x5c) +_(R_IA_64_SEGREL32LSB, 0x5d) +_(R_IA64_SEGREL32LSB, 0x5d) +_(R_IA_64_SEGREL64MSB, 0x5e) +_(R_IA64_SEGREL64MSB, 0x5e) +_(R_IA_64_SEGREL64LSB, 0x5f) +_(R_IA64_SEGREL64LSB, 0x5f) +_(R_IA_64_SECREL32MSB, 0x64) +_(R_IA64_SECREL32MSB, 0x64) +_(R_IA_64_SECREL32LSB, 0x65) +_(R_IA64_SECREL32LSB, 0x65) +_(R_IA_64_SECREL64MSB, 0x66) +_(R_IA64_SECREL64MSB, 0x66) +_(R_IA_64_SECREL64LSB, 0x67) +_(R_IA64_SECREL64LSB, 0x67) +_(R_IA_64_REL32MSB, 0x6c) +_(R_IA64_REL32MSB, 0x6c) +_(R_IA_64_REL32LSB, 0x6d) +_(R_IA64_REL32LSB, 0x6d) +_(R_IA_64_REL64MSB, 0x6e) +_(R_IA64_REL64MSB, 0x6e) +_(R_IA_64_REL64LSB, 0x6f) +_(R_IA64_REL64LSB, 0x6f) +_(R_IA_64_LTV32MSB, 0x74) +_(R_IA64_LTV32MSB, 0x74) +_(R_IA_64_LTV32LSB, 0x75) +_(R_IA64_LTV32LSB, 0x75) +_(R_IA_64_LTV64MSB, 0x76) +_(R_IA64_LTV64MSB, 0x76) +_(R_IA_64_LTV64LSB, 0x77) +_(R_IA64_LTV64LSB, 0x77) +_(R_IA_64_PCREL21BI, 0x79) +_(R_IA_64_PCREL22, 0x7A) +_(R_IA_64_PCREL64I, 0x7B) +_(R_IA_64_IPLTMSB, 0x80) +_(R_IA64_IPLTMSB, 0x80) +_(R_IA_64_IPLTLSB, 0x81) +_(R_IA64_IPLTLSB, 0x81) +_(R_IA_64_SUB, 0x85) +_(R_IA64_SUB, 0x85) +_(R_IA_64_LTOFF22X, 0x86) +_(R_IA64_LTOFF22X, 0x86) +_(R_IA_64_LDXMOV, 0x87) +_(R_IA64_LDXMOV, 0x87) +_(R_IA_64_TPREL14, 0x91) +_(R_IA64_TPREL14, 0x91) +_(R_IA_64_TPREL22, 0x92) +_(R_IA64_TPREL22, 0x92) +_(R_IA_64_TPREL64I, 0x93) +_(R_IA64_TPREL64I, 0x93) +_(R_IA_64_TPREL64MSB, 0x96) +_(R_IA64_TPREL64MSB, 0x96) +_(R_IA_64_TPREL64LSB, 0x97) +_(R_IA64_TPREL64LSB, 0x97) +_(R_IA_64_LTOFF_TPREL22, 0x9A) +_(R_IA64_LTOFF_TPREL22, 0x9A) +_(R_IA_64_DTPMOD64MSB, 0xA6) +_(R_IA64_DTPMOD64MSB, 0xA6) +_(R_IA_64_DTPMOD64LSB, 0xA7) +_(R_IA64_DTPMOD64LSB, 0xA7) +_(R_IA_64_LTOFF_DTPMOD22, 0xAA) +_(R_IA64_LTOFF_DTPMOD22, 0xAA) +_(R_IA_64_DTPREL14, 0xB1) +_(R_IA64_DTPREL14, 0xB1) +_(R_IA_64_DTPREL22, 0xB2) +_(R_IA64_DTPREL22, 0xB2) +_(R_IA_64_DTPREL64I, 0xB3) +_(R_IA64_DTPREL64I, 0xB3) +_(R_IA_64_DTPREL32MSB, 0xB4) +_(R_IA64_DTPREL32MSB, 0xB4) +_(R_IA_64_DTPREL32LSB, 0xB5) +_(R_IA64_DTPREL32LSB, 0xB5) +_(R_IA_64_DTPREL64MSB, 0xB6) +_(R_IA64_DTPREL64MSB, 0xB6) +_(R_IA_64_DTPREL64LSB, 0xB7) +_(R_IA64_DTPREL64LSB, 0xB7) +_(R_IA_64_LTOFF_DTPREL22, 0xBA) +_(R_IA64_LTOFF_DTPREL22, 0xBA) +') + +define(`DEFINE_MIPS_RELOCATIONS',` +_(R_MIPS_NONE, 0) +_(R_MIPS_16, 1) +_(R_MIPS_32, 2) +_(R_MIPS_REL32, 3) +_(R_MIPS_26, 4) +_(R_MIPS_HI16, 5) +_(R_MIPS_LO16, 6) +_(R_MIPS_GPREL16, 7) +_(R_MIPS_LITERAL, 8) +_(R_MIPS_GOT16, 9) +_(R_MIPS_PC16, 10) +_(R_MIPS_CALL16, 11) +_(R_MIPS_GPREL32, 12) +_(R_MIPS_SHIFT5, 16) +_(R_MIPS_SHIFT6, 17) +_(R_MIPS_64, 18) +_(R_MIPS_GOT_DISP, 19) +_(R_MIPS_GOT_PAGE, 20) +_(R_MIPS_GOT_OFST, 21) +_(R_MIPS_GOT_HI16, 22) +_(R_MIPS_GOT_LO16, 23) +_(R_MIPS_SUB, 24) +_(R_MIPS_CALLHI16, 30) +_(R_MIPS_CALLLO16, 31) +_(R_MIPS_JALR, 37) +_(R_MIPS_TLS_DTPMOD32, 38) +_(R_MIPS_TLS_DTPREL32, 39) +_(R_MIPS_TLS_DTPMOD64, 40) +_(R_MIPS_TLS_DTPREL64, 41) +_(R_MIPS_TLS_GD, 42) +_(R_MIPS_TLS_LDM, 43) +_(R_MIPS_TLS_DTPREL_HI16, 44) +_(R_MIPS_TLS_DTPREL_LO16, 45) +_(R_MIPS_TLS_GOTTPREL, 46) +_(R_MIPS_TLS_TPREL32, 47) +_(R_MIPS_TLS_TPREL64, 48) +_(R_MIPS_TLS_TPREL_HI16, 49) +_(R_MIPS_TLS_TPREL_LO16, 50) +') + +define(`DEFINE_PPC32_RELOCATIONS',` +_(R_PPC_NONE, 0) +_(R_PPC_ADDR32, 1) +_(R_PPC_ADDR24, 2) +_(R_PPC_ADDR16, 3) +_(R_PPC_ADDR16_LO, 4) +_(R_PPC_ADDR16_HI, 5) +_(R_PPC_ADDR16_HA, 6) +_(R_PPC_ADDR14, 7) +_(R_PPC_ADDR14_BRTAKEN, 8) +_(R_PPC_ADDR14_BRNTAKEN, 9) +_(R_PPC_REL24, 10) +_(R_PPC_REL14, 11) +_(R_PPC_REL14_BRTAKEN, 12) +_(R_PPC_REL14_BRNTAKEN, 13) +_(R_PPC_GOT16, 14) +_(R_PPC_GOT16_LO, 15) +_(R_PPC_GOT16_HI, 16) +_(R_PPC_GOT16_HA, 17) +_(R_PPC_PLTREL24, 18) +_(R_PPC_COPY, 19) +_(R_PPC_GLOB_DAT, 20) +_(R_PPC_JMP_SLOT, 21) +_(R_PPC_RELATIVE, 22) +_(R_PPC_LOCAL24PC, 23) +_(R_PPC_UADDR32, 24) +_(R_PPC_UADDR16, 25) +_(R_PPC_REL32, 26) +_(R_PPC_PLT32, 27) +_(R_PPC_PLTREL32, 28) +_(R_PPC_PLT16_LO, 29) +_(R_PPC_PLT16_HI, 30) +_(R_PPC_PLT16_HA, 31) +_(R_PPC_SDAREL16, 32) +_(R_PPC_SECTOFF, 33) +_(R_PPC_SECTOFF_LO, 34) +_(R_PPC_SECTOFF_HI, 35) +_(R_PPC_SECTOFF_HA, 36) +_(R_PPC_ADDR30, 37) +_(R_PPC_TLS, 67) +_(R_PPC_DTPMOD32, 68) +_(R_PPC_TPREL16, 69) +_(R_PPC_TPREL16_LO, 70) +_(R_PPC_TPREL16_HI, 71) +_(R_PPC_TPREL16_HA, 72) +_(R_PPC_TPREL32, 73) +_(R_PPC_DTPREL16, 74) +_(R_PPC_DTPREL16_LO, 75) +_(R_PPC_DTPREL16_HI, 76) +_(R_PPC_DTPREL16_HA, 77) +_(R_PPC_DTPREL32, 78) +_(R_PPC_GOT_TLSGD16, 79) +_(R_PPC_GOT_TLSGD16_LO, 80) +_(R_PPC_GOT_TLSGD16_HI, 81) +_(R_PPC_GOT_TLSGD16_HA, 82) +_(R_PPC_GOT_TLSLD16, 83) +_(R_PPC_GOT_TLSLD16_LO, 84) +_(R_PPC_GOT_TLSLD16_HI, 85) +_(R_PPC_GOT_TLSLD16_HA, 86) +_(R_PPC_GOT_TPREL16, 87) +_(R_PPC_GOT_TPREL16_LO, 88) +_(R_PPC_GOT_TPREL16_HI, 89) +_(R_PPC_GOT_TPREL16_HA, 90) +_(R_PPC_GOT_DTPREL16, 91) +_(R_PPC_GOT_DTPREL16_LO, 92) +_(R_PPC_GOT_DTPREL16_HI, 93) +_(R_PPC_GOT_DTPREL16_HA, 94) +_(R_PPC_TLSGD, 95) +_(R_PPC_TLSLD, 96) +_(R_PPC_EMB_NADDR32, 101) +_(R_PPC_EMB_NADDR16, 102) +_(R_PPC_EMB_NADDR16_LO, 103) +_(R_PPC_EMB_NADDR16_HI, 104) +_(R_PPC_EMB_NADDR16_HA, 105) +_(R_PPC_EMB_SDAI16, 106) +_(R_PPC_EMB_SDA2I16, 107) +_(R_PPC_EMB_SDA2REL, 108) +_(R_PPC_EMB_SDA21, 109) +_(R_PPC_EMB_MRKREF, 110) +_(R_PPC_EMB_RELSEC16, 111) +_(R_PPC_EMB_RELST_LO, 112) +_(R_PPC_EMB_RELST_HI, 113) +_(R_PPC_EMB_RELST_HA, 114) +_(R_PPC_EMB_BIT_FLD, 115) +_(R_PPC_EMB_RELSDA, 116) +') + +define(`DEFINE_PPC64_RELOCATIONS',` +_(R_PPC64_NONE, 0) +_(R_PPC64_ADDR32, 1) +_(R_PPC64_ADDR24, 2) +_(R_PPC64_ADDR16, 3) +_(R_PPC64_ADDR16_LO, 4) +_(R_PPC64_ADDR16_HI, 5) +_(R_PPC64_ADDR16_HA, 6) +_(R_PPC64_ADDR14, 7) +_(R_PPC64_ADDR14_BRTAKEN, 8) +_(R_PPC64_ADDR14_BRNTAKEN, 9) +_(R_PPC64_REL24, 10) +_(R_PPC64_REL14, 11) +_(R_PPC64_REL14_BRTAKEN, 12) +_(R_PPC64_REL14_BRNTAKEN, 13) +_(R_PPC64_GOT16, 14) +_(R_PPC64_GOT16_LO, 15) +_(R_PPC64_GOT16_HI, 16) +_(R_PPC64_GOT16_HA, 17) +_(R_PPC64_COPY, 19) +_(R_PPC64_GLOB_DAT, 20) +_(R_PPC64_JMP_SLOT, 21) +_(R_PPC64_RELATIVE, 22) +_(R_PPC64_UADDR32, 24) +_(R_PPC64_UADDR16, 25) +_(R_PPC64_REL32, 26) +_(R_PPC64_PLT32, 27) +_(R_PPC64_PLTREL32, 28) +_(R_PPC64_PLT16_LO, 29) +_(R_PPC64_PLT16_HI, 30) +_(R_PPC64_PLT16_HA, 31) +_(R_PPC64_SECTOFF, 33) +_(R_PPC64_SECTOFF_LO, 34) +_(R_PPC64_SECTOFF_HI, 35) +_(R_PPC64_SECTOFF_HA, 36) +_(R_PPC64_ADDR30, 37) +_(R_PPC64_ADDR64, 38) +_(R_PPC64_ADDR16_HIGHER, 39) +_(R_PPC64_ADDR16_HIGHERA, 40) +_(R_PPC64_ADDR16_HIGHEST, 41) +_(R_PPC64_ADDR16_HIGHESTA, 42) +_(R_PPC64_UADDR64, 43) +_(R_PPC64_REL64, 44) +_(R_PPC64_PLT64, 45) +_(R_PPC64_PLTREL64, 46) +_(R_PPC64_TOC16, 47) +_(R_PPC64_TOC16_LO, 48) +_(R_PPC64_TOC16_HI, 49) +_(R_PPC64_TOC16_HA, 50) +_(R_PPC64_TOC, 51) +_(R_PPC64_PLTGOT16, 52) +_(R_PPC64_PLTGOT16_LO, 53) +_(R_PPC64_PLTGOT16_HI, 54) +_(R_PPC64_PLTGOT16_HA, 55) +_(R_PPC64_ADDR16_DS, 56) +_(R_PPC64_ADDR16_LO_DS, 57) +_(R_PPC64_GOT16_DS, 58) +_(R_PPC64_GOT16_LO_DS, 59) +_(R_PPC64_PLT16_LO_DS, 60) +_(R_PPC64_SECTOFF_DS, 61) +_(R_PPC64_SECTOFF_LO_DS, 62) +_(R_PPC64_TOC16_DS, 63) +_(R_PPC64_TOC16_LO_DS, 64) +_(R_PPC64_PLTGOT16_DS, 65) +_(R_PPC64_PLTGOT16_LO_DS, 66) +_(R_PPC64_TLS, 67) +_(R_PPC64_DTPMOD64, 68) +_(R_PPC64_TPREL16, 69) +_(R_PPC64_TPREL16_LO, 60) +_(R_PPC64_TPREL16_HI, 71) +_(R_PPC64_TPREL16_HA, 72) +_(R_PPC64_TPREL64, 73) +_(R_PPC64_DTPREL16, 74) +_(R_PPC64_DTPREL16_LO, 75) +_(R_PPC64_DTPREL16_HI, 76) +_(R_PPC64_DTPREL16_HA, 77) +_(R_PPC64_DTPREL64, 78) +_(R_PPC64_GOT_TLSGD16, 79) +_(R_PPC64_GOT_TLSGD16_LO, 80) +_(R_PPC64_GOT_TLSGD16_HI, 81) +_(R_PPC64_GOT_TLSGD16_HA, 82) +_(R_PPC64_GOT_TLSLD16, 83) +_(R_PPC64_GOT_TLSLD16_LO, 84) +_(R_PPC64_GOT_TLSLD16_HI, 85) +_(R_PPC64_GOT_TLSLD16_HA, 86) +_(R_PPC64_GOT_TPREL16_DS, 87) +_(R_PPC64_GOT_TPREL16_LO_DS, 88) +_(R_PPC64_GOT_TPREL16_HI, 89) +_(R_PPC64_GOT_TPREL16_HA, 90) +_(R_PPC64_GOT_DTPREL16_DS, 91) +_(R_PPC64_GOT_DTPREL16_LO_DS, 92) +_(R_PPC64_GOT_DTPREL16_HI, 93) +_(R_PPC64_GOT_DTPREL16_HA, 94) +_(R_PPC64_TPREL16_DS, 95) +_(R_PPC64_TPREL16_LO_DS, 96) +_(R_PPC64_TPREL16_HIGHER, 97) +_(R_PPC64_TPREL16_HIGHERA, 98) +_(R_PPC64_TPREL16_HIGHEST, 99) +_(R_PPC64_TPREL16_HIGHESTA, 100) +_(R_PPC64_DTPREL16_DS, 101) +_(R_PPC64_DTPREL16_LO_DS, 102) +_(R_PPC64_DTPREL16_HIGHER, 103) +_(R_PPC64_DTPREL16_HIGHERA, 104) +_(R_PPC64_DTPREL16_HIGHEST, 105) +_(R_PPC64_DTPREL16_HIGHESTA, 106) +_(R_PPC64_TLSGD, 107) +_(R_PPC64_TLSLD, 108) +') + +define(`DEFINE_RISCV_RELOCATIONS',` +_(R_RISCV_NONE, 0) +_(R_RISCV_32, 1) +_(R_RISCV_64, 2) +_(R_RISCV_RELATIVE, 3) +_(R_RISCV_COPY, 4) +_(R_RISCV_JUMP_SLOT, 5) +_(R_RISCV_TLS_DTPMOD32, 6) +_(R_RISCV_TLS_DTPMOD64, 7) +_(R_RISCV_TLS_DTPREL32, 8) +_(R_RISCV_TLS_DTPREL64, 9) +_(R_RISCV_TLS_TPREL32, 10) +_(R_RISCV_TLS_TPREL64, 11) +_(R_RISCV_BRANCH, 16) +_(R_RISCV_JAL, 17) +_(R_RISCV_CALL, 18) +_(R_RISCV_CALL_PLT, 19) +_(R_RISCV_GOT_HI20, 20) +_(R_RISCV_TLS_GOT_HI20, 21) +_(R_RISCV_TLS_GD_HI20, 22) +_(R_RISCV_PCREL_HI20, 23) +_(R_RISCV_PCREL_LO12_I, 24) +_(R_RISCV_PCREL_LO12_S, 25) +_(R_RISCV_HI20, 26) +_(R_RISCV_LO12_I, 27) +_(R_RISCV_LO12_S, 28) +_(R_RISCV_TPREL_HI20, 29) +_(R_RISCV_TPREL_LO12_I, 30) +_(R_RISCV_TPREL_LO12_S, 31) +_(R_RISCV_TPREL_ADD, 32) +_(R_RISCV_ADD8, 33) +_(R_RISCV_ADD16, 34) +_(R_RISCV_ADD32, 35) +_(R_RISCV_ADD64, 36) +_(R_RISCV_SUB8, 37) +_(R_RISCV_SUB16, 38) +_(R_RISCV_SUB32, 39) +_(R_RISCV_SUB64, 40) +_(R_RISCV_GNU_VTINHERIT, 41) +_(R_RISCV_GNU_VTENTRY, 42) +_(R_RISCV_ALIGN, 43) +_(R_RISCV_RVC_BRANCH, 44) +_(R_RISCV_RVC_JUMP, 45) +_(R_RISCV_RVC_LUI, 46) +_(R_RISCV_GPREL_I, 47) +_(R_RISCV_GPREL_S, 48) +_(R_RISCV_TPREL_I, 49) +_(R_RISCV_TPREL_S, 50) +_(R_RISCV_RELAX, 51) +_(R_RISCV_SUB6, 52) +_(R_RISCV_SET6, 53) +_(R_RISCV_SET8, 54) +_(R_RISCV_SET16, 55) +_(R_RISCV_SET32, 56) +_(R_RISCV_32_PCREL, 57) +_(R_RISCV_IRELATIVE, 58) +') + +define(`DEFINE_SPARC_RELOCATIONS',` +_(R_SPARC_NONE, 0) +_(R_SPARC_8, 1) +_(R_SPARC_16, 2) +_(R_SPARC_32, 3) +_(R_SPARC_DISP8, 4) +_(R_SPARC_DISP16, 5) +_(R_SPARC_DISP32, 6) +_(R_SPARC_WDISP30, 7) +_(R_SPARC_WDISP22, 8) +_(R_SPARC_HI22, 9) +_(R_SPARC_22, 10) +_(R_SPARC_13, 11) +_(R_SPARC_LO10, 12) +_(R_SPARC_GOT10, 13) +_(R_SPARC_GOT13, 14) +_(R_SPARC_GOT22, 15) +_(R_SPARC_PC10, 16) +_(R_SPARC_PC22, 17) +_(R_SPARC_WPLT30, 18) +_(R_SPARC_COPY, 19) +_(R_SPARC_GLOB_DAT, 20) +_(R_SPARC_JMP_SLOT, 21) +_(R_SPARC_RELATIVE, 22) +_(R_SPARC_UA32, 23) +_(R_SPARC_PLT32, 24) +_(R_SPARC_HIPLT22, 25) +_(R_SPARC_LOPLT10, 26) +_(R_SPARC_PCPLT32, 27) +_(R_SPARC_PCPLT22, 28) +_(R_SPARC_PCPLT10, 29) +_(R_SPARC_10, 30) +_(R_SPARC_11, 31) +_(R_SPARC_64, 32) +_(R_SPARC_OLO10, 33) +_(R_SPARC_HH22, 34) +_(R_SPARC_HM10, 35) +_(R_SPARC_LM22, 36) +_(R_SPARC_PC_HH22, 37) +_(R_SPARC_PC_HM10, 38) +_(R_SPARC_PC_LM22, 39) +_(R_SPARC_WDISP16, 40) +_(R_SPARC_WDISP19, 41) +_(R_SPARC_GLOB_JMP, 42) +_(R_SPARC_7, 43) +_(R_SPARC_5, 44) +_(R_SPARC_6, 45) +_(R_SPARC_DISP64, 46) +_(R_SPARC_PLT64, 47) +_(R_SPARC_HIX22, 48) +_(R_SPARC_LOX10, 49) +_(R_SPARC_H44, 50) +_(R_SPARC_M44, 51) +_(R_SPARC_L44, 52) +_(R_SPARC_REGISTER, 53) +_(R_SPARC_UA64, 54) +_(R_SPARC_UA16, 55) +_(R_SPARC_TLS_GD_HI22, 56) +_(R_SPARC_TLS_GD_LO10, 57) +_(R_SPARC_TLS_GD_ADD, 58) +_(R_SPARC_TLS_GD_CALL, 59) +_(R_SPARC_TLS_LDM_HI22, 60) +_(R_SPARC_TLS_LDM_LO10, 61) +_(R_SPARC_TLS_LDM_ADD, 62) +_(R_SPARC_TLS_LDM_CALL, 63) +_(R_SPARC_TLS_LDO_HIX22, 64) +_(R_SPARC_TLS_LDO_LOX10, 65) +_(R_SPARC_TLS_LDO_ADD, 66) +_(R_SPARC_TLS_IE_HI22, 67) +_(R_SPARC_TLS_IE_LO10, 68) +_(R_SPARC_TLS_IE_LD, 69) +_(R_SPARC_TLS_IE_LDX, 70) +_(R_SPARC_TLS_IE_ADD, 71) +_(R_SPARC_TLS_LE_HIX22, 72) +_(R_SPARC_TLS_LE_LOX10, 73) +_(R_SPARC_TLS_DTPMOD32, 74) +_(R_SPARC_TLS_DTPMOD64, 75) +_(R_SPARC_TLS_DTPOFF32, 76) +_(R_SPARC_TLS_DTPOFF64, 77) +_(R_SPARC_TLS_TPOFF32, 78) +_(R_SPARC_TLS_TPOFF64, 79) +_(R_SPARC_GOTDATA_HIX22, 80) +_(R_SPARC_GOTDATA_LOX10, 81) +_(R_SPARC_GOTDATA_OP_HIX22, 82) +_(R_SPARC_GOTDATA_OP_LOX10, 83) +_(R_SPARC_GOTDATA_OP, 84) +_(R_SPARC_H34, 85) +') + +define(`DEFINE_VAX_RELOCATIONS',` +_(R_VAX_NONE, 0) +_(R_VAX_32, 1) +_(R_VAX_16, 2) +_(R_VAX_8, 3) +_(R_VAX_PC32, 4) +_(R_VAX_PC16, 5) +_(R_VAX_PC8, 6) +_(R_VAX_GOT32, 7) +_(R_VAX_PLT32, 13) +_(R_VAX_COPY, 19) +_(R_VAX_GLOB_DAT, 20) +_(R_VAX_JMP_SLOT, 21) +_(R_VAX_RELATIVE, 22) +') + +define(`DEFINE_X86_64_RELOCATIONS',` +_(R_X86_64_NONE, 0) +_(R_X86_64_64, 1) +_(R_X86_64_PC32, 2) +_(R_X86_64_GOT32, 3) +_(R_X86_64_PLT32, 4) +_(R_X86_64_COPY, 5) +_(R_X86_64_GLOB_DAT, 6) +_(R_X86_64_JUMP_SLOT, 7) +_(R_X86_64_RELATIVE, 8) +_(R_X86_64_GOTPCREL, 9) +_(R_X86_64_32, 10) +_(R_X86_64_32S, 11) +_(R_X86_64_16, 12) +_(R_X86_64_PC16, 13) +_(R_X86_64_8, 14) +_(R_X86_64_PC8, 15) +_(R_X86_64_DTPMOD64, 16) +_(R_X86_64_DTPOFF64, 17) +_(R_X86_64_TPOFF64, 18) +_(R_X86_64_TLSGD, 19) +_(R_X86_64_TLSLD, 20) +_(R_X86_64_DTPOFF32, 21) +_(R_X86_64_GOTTPOFF, 22) +_(R_X86_64_TPOFF32, 23) +_(R_X86_64_PC64, 24) +_(R_X86_64_GOTOFF64, 25) +_(R_X86_64_GOTPC32, 26) +_(R_X86_64_GOT64, 27) +_(R_X86_64_GOTPCREL64, 28) +_(R_X86_64_GOTPC64, 29) +_(R_X86_64_GOTPLT64, 30) +_(R_X86_64_PLTOFF64, 31) +_(R_X86_64_SIZE32, 32) +_(R_X86_64_SIZE64, 33) +_(R_X86_64_GOTPC32_TLSDESC, 34) +_(R_X86_64_TLSDESC_CALL, 35) +_(R_X86_64_TLSDESC, 36) +_(R_X86_64_IRELATIVE, 37) +_(R_X86_64_RELATIVE64, 38) +_(R_X86_64_PC32_BND, 39) +_(R_X86_64_PLT32_BND, 40) +_(R_X86_64_GOTPCRELX, 41) +_(R_X86_64_REX_GOTPCRELX, 42) +') + +define(`DEFINE_RELOCATIONS',` +DEFINE_386_RELOCATIONS() +DEFINE_AARCH64_RELOCATIONS() +DEFINE_AMD64_RELOCATIONS() +DEFINE_ARM_RELOCATIONS() +DEFINE_IA64_RELOCATIONS() +DEFINE_MIPS_RELOCATIONS() +DEFINE_PPC32_RELOCATIONS() +DEFINE_PPC64_RELOCATIONS() +DEFINE_RISCV_RELOCATIONS() +DEFINE_SPARC_RELOCATIONS() +DEFINE_VAX_RELOCATIONS() +DEFINE_X86_64_RELOCATIONS() +') + +define(`DEFINE_LL_FLAGS',` +_(LL_NONE, 0, + `no flags') +_(LL_EXACT_MATCH, 0x1, + `require an exact match') +_(LL_IGNORE_INT_VER, 0x2, + `ignore version incompatibilities') +_(LL_REQUIRE_MINOR, 0x4, + `') +_(LL_EXPORTS, 0x8, + `') +_(LL_DELAY_LOAD, 0x10, + `') +_(LL_DELTA, 0x20, + `') +') + +# +# Note tags +# +define(`DEFINE_NOTE_ENTRY_TYPES',` +_(NT_ABI_TAG, 1, + `Tag indicating the ABI') +_(NT_GNU_HWCAP, 2, + `Hardware capabilities') +_(NT_GNU_BUILD_ID, 3, + `Build id, set by ld(1)') +_(NT_GNU_GOLD_VERSION, 4, + `Version number of the GNU gold linker') +_(NT_PRSTATUS, 1, + `Process status') +_(NT_FPREGSET, 2, + `Floating point information') +_(NT_PRPSINFO, 3, + `Process information') +_(NT_AUXV, 6, + `Auxiliary vector') +_(NT_PRXFPREG, 0x46E62B7FUL, + `Linux user_xfpregs structure') +_(NT_PSTATUS, 10, + `Linux process status') +_(NT_FPREGS, 12, + `Linux floating point regset') +_(NT_PSINFO, 13, + `Linux process information') +_(NT_LWPSTATUS, 16, + `Linux lwpstatus_t type') +_(NT_LWPSINFO, 17, + `Linux lwpinfo_t type') +_(NT_FREEBSD_NOINIT_TAG, 2, + `FreeBSD no .init tag') +_(NT_FREEBSD_ARCH_TAG, 3, + `FreeBSD arch tag') +_(NT_FREEBSD_FEATURE_CTL, 4, + `FreeBSD feature control') +') + +# Aliases for the ABI tag. +define(`DEFINE_NOTE_ENTRY_ALIASES',` +_(NT_FREEBSD_ABI_TAG, NT_ABI_TAG) +_(NT_GNU_ABI_TAG, NT_ABI_TAG) +_(NT_NETBSD_IDENT, NT_ABI_TAG) +_(NT_OPENBSD_IDENT, NT_ABI_TAG) +') + +# +# Option kinds. +# +define(`DEFINE_OPTION_KINDS',` +_(ODK_NULL, 0, + `undefined') +_(ODK_REGINFO, 1, + `register usage info') +_(ODK_EXCEPTIONS, 2, + `exception processing info') +_(ODK_PAD, 3, + `section padding') +_(ODK_HWPATCH, 4, + `hardware patch applied') +_(ODK_FILL, 5, + `fill value used by linker') +_(ODK_TAGS, 6, + `reserved space for tools') +_(ODK_HWAND, 7, + `hardware AND patch applied') +_(ODK_HWOR, 8, + `hardware OR patch applied') +_(ODK_GP_GROUP, 9, + `GP group to use for text/data sections') +_(ODK_IDENT, 10, + `ID information') +_(ODK_PAGESIZE, 11, + `page size information') +') + +# +# ODK_EXCEPTIONS info field masks. +# +define(`DEFINE_OPTION_EXCEPTIONS',` +_(OEX_FPU_MIN, 0x0000001FUL, + `minimum FPU exception which must be enabled') +_(OEX_FPU_MAX, 0x00001F00UL, + `maximum FPU exception which can be enabled') +_(OEX_PAGE0, 0x00010000UL, + `page zero must be mapped') +_(OEX_SMM, 0x00020000UL, + `run in sequential memory mode') +_(OEX_PRECISEFP, 0x00040000UL, + `run in precise FP exception mode') +_(OEX_DISMISS, 0x00080000UL, + `dismiss invalid address traps') +') + +# +# ODK_PAD info field masks. +# +define(`DEFINE_OPTION_PADS',` +_(OPAD_PREFIX, 0x0001) +_(OPAD_POSTFIX, 0x0002) +_(OPAD_SYMBOL, 0x0004) +') + +# +# ODK_HWPATCH info field masks and ODK_HWAND/ODK_HWOR +# info field and hwp_flags[12] masks. +# +define(`DEFINE_ODK_HWPATCH_MASKS',` +_(OHW_R4KEOP, 0x00000001UL, + `patch for R4000 branch at end-of-page bug') +_(OHW_R8KPFETCH, 0x00000002UL, + `R8000 prefetch bug may occur') +_(OHW_R5KEOP, 0x00000004UL, + `patch for R5000 branch at end-of-page bug') +_(OHW_R5KCVTL, 0x00000008UL, + `R5000 cvt.[ds].l bug: clean == 1') +_(OHW_R10KLDL, 0x00000010UL, + `need patch for R10000 misaligned load') +_(OHWA0_R4KEOP_CHECKED, 0x00000001UL, + `object checked for R4000 end-of-page bug') +_(OHWA0_R4KEOP_CLEAN, 0x00000002UL, + `object verified clean for R4000 end-of-page bug') +_(OHWO0_FIXADE, 0x00000001UL, + `object requires call to fixade') +') + +# +# ODK_IDENT/ODK_GP_GROUP info field masks. +# +define(`DEFINE_ODK_GP_MASKS',` +_(OGP_GROUP, 0x0000FFFFUL, + `GP group number') +_(OGP_SELF, 0x00010000UL, + `GP group is self-contained') +') + +# MIPS ABI related constants. +define(`DEFINE_MIPS_ABIS',` +_(E_MIPS_ABI_O32, 0x00001000, + `MIPS 32 bit ABI (UCODE)') +_(E_MIPS_ABI_O64, 0x00002000, + `UCODE MIPS 64 bit ABI') +_(E_MIPS_ABI_EABI32, 0x00003000, + `Embedded ABI for 32-bit') +_(E_MIPS_ABI_EABI64, 0x00004000, + `Embedded ABI for 64-bit') +') diff --git a/contrib/elftoolchain/common/sys/elfdefinitions.h b/contrib/elftoolchain/common/sys/elfdefinitions.h new file mode 100644 index 0000000000..b113615285 --- /dev/null +++ b/contrib/elftoolchain/common/sys/elfdefinitions.h @@ -0,0 +1,2443 @@ +/*- + * Copyright (c) 2010,2021 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * WARNING: GENERATED FILE. DO NOT MODIFY. + * + * GENERATED FROM: $Id: elfdefinitions.m4 3984 2022-05-06 11:22:42Z jkoshy $ + * GENERATED FROM: $Id: elfconstants.m4 4053 2024-11-25 13:42:22Z jkoshy $ + */ + +/* + * These definitions are based on: + * - The public specification of the ELF format as defined in the + * October 2009 draft of System V ABI. + * See: http://www.sco.com/developers/gabi/latest/ch4.intro.html + * - The May 1998 (version 1.5) draft of "The ELF-64 object format". + * - Processor-specific ELF ABI definitions for sparc, i386, amd64, mips, + * ia64, powerpc, and RISC-V processors. + * - The "Linkers and Libraries Guide", from Sun Microsystems. + */ + +#ifndef _SYS_ELFDEFINITIONS_H_ +#define _SYS_ELFDEFINITIONS_H_ + +/* + * Types of capabilities. + */ + +#define CA_SUNW_NULL 0 +#define CA_SUNW_HW_1 1 +#define CA_SUNW_SW_1 2 + +/* + * Flags used with dynamic linking entries. + */ + +#define DF_ORIGIN 0x1 +#define DF_SYMBOLIC 0x2 +#define DF_TEXTREL 0x4 +#define DF_BIND_NOW 0x8 +#define DF_STATIC_TLS 0x10 +#define DF_1_BIND_NOW 0x1 +#define DF_1_GLOBAL 0x2 +#define DF_1_GROUP 0x4 +#define DF_1_NODELETE 0x8 +#define DF_1_LOADFLTR 0x10 +#define DF_1_INITFIRST 0x20 +#define DF_1_NOOPEN 0x40 +#define DF_1_ORIGIN 0x80 +#define DF_1_DIRECT 0x100 +#define DF_1_INTERPOSE 0x400 +#define DF_1_NODEFLIB 0x800 +#define DF_1_NODUMP 0x1000 +#define DF_1_CONFALT 0x2000 +#define DF_1_ENDFILTEE 0x4000 +#define DF_1_DISPRELDNE 0x8000 +#define DF_1_DISPRELPND 0x10000 + +/* + * Dynamic linking entry types. + */ + +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_BIND_NOW 24 +#define DT_INIT_ARRAY 25 +#define DT_FINI_ARRAY 26 +#define DT_INIT_ARRAYSZ 27 +#define DT_FINI_ARRAYSZ 28 +#define DT_RUNPATH 29 +#define DT_FLAGS 30 +#define DT_ENCODING 32 +#define DT_PREINIT_ARRAY 32 +#define DT_PREINIT_ARRAYSZ 33 +#define DT_MAXPOSTAGS 34 +#define DT_LOOS 0x6000000D +#define DT_SUNW_AUXILIARY 0x6000000D +#define DT_SUNW_RTLDINF 0x6000000E +#define DT_SUNW_FILTER 0x6000000F +#define DT_SUNW_CAP 0x60000010 +#define DT_SUNW_ASLR 0x60000023 +#define DT_HIOS 0x6FFFF000 +#define DT_VALRNGLO 0x6FFFFD00 +#define DT_GNU_PRELINKED 0x6FFFFDF5 +#define DT_GNU_CONFLICTSZ 0x6FFFFDF6 +#define DT_GNU_LIBLISTSZ 0x6FFFFDF7 +#define DT_CHECKSUM 0x6FFFFDF8 +#define DT_PLTPADSZ 0x6FFFFDF9 +#define DT_MOVEENT 0x6FFFFDFA +#define DT_MOVESZ 0x6FFFFDFB +#define DT_FEATURE 0x6FFFFDFC +#define DT_POSFLAG_1 0x6FFFFDFD +#define DT_SYMINSZ 0x6FFFFDFE +#define DT_SYMINENT 0x6FFFFDFF +#define DT_VALRNGHI 0x6FFFFDFF +#define DT_ADDRRNGLO 0x6FFFFE00 +#define DT_GNU_HASH 0x6FFFFEF5 +#define DT_TLSDESC_PLT 0x6FFFFEF6 +#define DT_TLSDESC_GOT 0x6FFFFEF7 +#define DT_GNU_CONFLICT 0x6FFFFEF8 +#define DT_GNU_LIBLIST 0x6FFFFEF9 +#define DT_CONFIG 0x6FFFFEFA +#define DT_DEPAUDIT 0x6FFFFEFB +#define DT_AUDIT 0x6FFFFEFC +#define DT_PLTPAD 0x6FFFFEFD +#define DT_MOVETAB 0x6FFFFEFE +#define DT_SYMINFO 0x6FFFFEFF +#define DT_ADDRRNGHI 0x6FFFFEFF +#define DT_VERSYM 0x6FFFFFF0 +#define DT_RELACOUNT 0x6FFFFFF9 +#define DT_RELCOUNT 0x6FFFFFFA +#define DT_FLAGS_1 0x6FFFFFFB +#define DT_VERDEF 0x6FFFFFFC +#define DT_VERDEFNUM 0x6FFFFFFD +#define DT_VERNEED 0x6FFFFFFE +#define DT_VERNEEDNUM 0x6FFFFFFF +#define DT_LOPROC 0x70000000 +#define DT_ARM_SYMTABSZ 0x70000001 +#define DT_SPARC_REGISTER 0x70000001 +#define DT_ARM_PREEMPTMAP 0x70000002 +#define DT_MIPS_RLD_VERSION 0x70000001 +#define DT_MIPS_TIME_STAMP 0x70000002 +#define DT_MIPS_ICHECKSUM 0x70000003 +#define DT_MIPS_IVERSION 0x70000004 +#define DT_MIPS_FLAGS 0x70000005 +#define DT_MIPS_BASE_ADDRESS 0x70000006 +#define DT_MIPS_CONFLICT 0x70000008 +#define DT_MIPS_LIBLIST 0x70000009 +#define DT_MIPS_LOCAL_GOTNO 0x7000000A +#define DT_MIPS_CONFLICTNO 0x7000000B +#define DT_MIPS_LIBLISTNO 0x70000010 +#define DT_MIPS_SYMTABNO 0x70000011 +#define DT_MIPS_UNREFEXTNO 0x70000012 +#define DT_MIPS_GOTSYM 0x70000013 +#define DT_MIPS_HIPAGENO 0x70000014 +#define DT_MIPS_RLD_MAP 0x70000016 +#define DT_MIPS_DELTA_CLASS 0x70000017 +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 +#define DT_MIPS_DELTA_INSTANCE 0x70000019 +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A +#define DT_MIPS_DELTA_RELOC 0x7000001B +#define DT_MIPS_DELTA_RELOC_NO 0x7000001C +#define DT_MIPS_DELTA_SYM 0x7000001D +#define DT_MIPS_DELTA_SYM_NO 0x7000001E +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 +#define DT_MIPS_CXX_FLAGS 0x70000022 +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 +#define DT_MIPS_INTERFACE 0x7000002A +#define DT_MIPS_DYNSTR_ALIGN 0x7000002B +#define DT_MIPS_INTERFACE_SIZE 0x7000002C +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D +#define DT_MIPS_PERF_SUFFIX 0x7000002E +#define DT_MIPS_COMPACT_SIZE 0x7000002F +#define DT_MIPS_GP_VALUE 0x70000030 +#define DT_MIPS_AUX_DYNAMIC 0x70000031 +#define DT_MIPS_PLTGOT 0x70000032 +#define DT_MIPS_RLD_OBJ_UPDATE 0x70000033 +#define DT_MIPS_RWPLT 0x70000034 +#define DT_PPC_GOT 0x70000000 +#define DT_PPC_TLSOPT 0x70000001 +#define DT_PPC64_GLINK 0x70000000 +#define DT_PPC64_OPD 0x70000001 +#define DT_PPC64_OPDSZ 0x70000002 +#define DT_PPC64_TLSOPT 0x70000003 +#define DT_AUXILIARY 0x7FFFFFFD +#define DT_USED 0x7FFFFFFE +#define DT_FILTER 0x7FFFFFFF +#define DT_HIPROC 0x7FFFFFFF + + +/* Aliases for dynamic linking entry symbols. */ + +#define DT_DEPRECATED_SPARC_REGISTER DT_SPARC_REGISTER + + +/* + * Flags used in the executable header (field: e_flags). + */ + +#define EF_ARM_RELEXEC 0x00000001UL +#define EF_ARM_HASENTRY 0x00000002UL +#define EF_ARM_SYMSARESORTED 0x00000004UL +#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008UL +#define EF_ARM_MAPSYMSFIRST 0x00000010UL +#define EF_ARM_BE8 0x00800000UL +#define EF_ARM_LE8 0x00400000UL +#define EF_ARM_EABIMASK 0xFF000000UL +#define EF_ARM_EABI_UNKNOWN 0x00000000UL +#define EF_ARM_EABI_VER1 0x01000000UL +#define EF_ARM_EABI_VER2 0x02000000UL +#define EF_ARM_EABI_VER3 0x03000000UL +#define EF_ARM_EABI_VER4 0x04000000UL +#define EF_ARM_EABI_VER5 0x05000000UL +#define EF_ARM_INTERWORK 0x00000004UL +#define EF_ARM_APCS_26 0x00000008UL +#define EF_ARM_APCS_FLOAT 0x00000010UL +#define EF_ARM_PIC 0x00000020UL +#define EF_ARM_ALIGN8 0x00000040UL +#define EF_ARM_NEW_ABI 0x00000080UL +#define EF_ARM_OLD_ABI 0x00000100UL +#define EF_ARM_SOFT_FLOAT 0x00000200UL +#define EF_ARM_VFP_FLOAT 0x00000400UL +#define EF_ARM_MAVERICK_FLOAT 0x00000800UL +#define EF_MIPS_NOREORDER 0x00000001UL +#define EF_MIPS_PIC 0x00000002UL +#define EF_MIPS_CPIC 0x00000004UL +#define EF_MIPS_UCODE 0x00000010UL +#define EF_MIPS_ABI 0x00007000UL +#define EF_MIPS_ABI2 0x00000020UL +#define EF_MIPS_OPTIONS_FIRST 0x00000080UL +#define EF_MIPS_ARCH_ASE 0x0F000000UL +#define EF_MIPS_ARCH_ASE_MDMX 0x08000000UL +#define EF_MIPS_ARCH_ASE_M16 0x04000000UL +#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000UL +#define EF_MIPS_ARCH 0xF0000000UL +#define EF_MIPS_ARCH_1 0x00000000UL +#define EF_MIPS_ARCH_2 0x10000000UL +#define EF_MIPS_ARCH_3 0x20000000UL +#define EF_MIPS_ARCH_4 0x30000000UL +#define EF_MIPS_ARCH_5 0x40000000UL +#define EF_MIPS_ARCH_32 0x50000000UL +#define EF_MIPS_ARCH_64 0x60000000UL +#define EF_MIPS_ARCH_32R2 0x70000000UL +#define EF_MIPS_ARCH_64R2 0x80000000UL +#define EF_PPC_EMB 0x80000000UL +#define EF_PPC_RELOCATABLE 0x00010000UL +#define EF_PPC_RELOCATABLE_LIB 0x00008000UL +#define EF_RISCV_RVC 0x00000001UL +#define EF_RISCV_FLOAT_ABI_MASK 0x00000006UL +#define EF_RISCV_FLOAT_ABI_SOFT 0x00000000UL +#define EF_RISCV_FLOAT_ABI_SINGLE 0x00000002UL +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x00000004UL +#define EF_RISCV_FLOAT_ABI_QUAD 0x00000006UL +#define EF_RISCV_RVE 0x00000008UL +#define EF_RISCV_TSO 0x00000010UL +#define EF_SPARC_EXT_MASK 0x00ffff00UL +#define EF_SPARC_32PLUS 0x00000100UL +#define EF_SPARC_SUN_US1 0x00000200UL +#define EF_SPARC_HAL_R1 0x00000400UL +#define EF_SPARC_SUN_US3 0x00000800UL +#define EF_SPARCV9_MM 0x00000003UL +#define EF_SPARCV9_TSO 0x00000000UL +#define EF_SPARCV9_PSO 0x00000001UL +#define EF_SPARCV9_RMO 0x00000002UL + + +/* + * Offsets in the ei_ident[] field of an ELF executable header. + */ + +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 +#define EI_NIDENT 16 + + +/* + * The ELF class of an object. + */ + +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + + +/* + * Endianness of data in an ELF object. + */ + +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + + +/* + * The magic numbers used in the initial four bytes of an ELF object. + * + * These numbers are: 0x7F, 'E', 'L' and 'F'. + */ + +#define ELFMAG0 0x7FU +#define ELFMAG1 0x45U +#define ELFMAG2 0x4CU +#define ELFMAG3 0x46U + +/* Additional magic-related constants. */ + +#define ELFMAG "\177ELF" +#define SELFMAG 4 + + +/* + * ELF OS ABI field. + */ + +#define ELFOSABI_NONE 0 +#define ELFOSABI_SYSV 0 +#define ELFOSABI_HPUX 1 +#define ELFOSABI_NETBSD 2 +#define ELFOSABI_GNU 3 +#define ELFOSABI_HURD 4 +#define ELFOSABI_86OPEN 5 +#define ELFOSABI_SOLARIS 6 +#define ELFOSABI_AIX 7 +#define ELFOSABI_IRIX 8 +#define ELFOSABI_FREEBSD 9 +#define ELFOSABI_TRU64 10 +#define ELFOSABI_MODESTO 11 +#define ELFOSABI_OPENBSD 12 +#define ELFOSABI_OPENVMS 13 +#define ELFOSABI_NSK 14 +#define ELFOSABI_AROS 15 +#define ELFOSABI_FENIXOS 16 +#define ELFOSABI_CLOUDABI 17 +#define ELFOSABI_OPENVOS 18 +#define ELFOSABI_ARM_AEABI 64 +#define ELFOSABI_ARM 97 +#define ELFOSABI_STANDALONE 255 + + +/* OS ABI Aliases. */ + +#define ELFOSABI_LINUX ELFOSABI_GNU + + +/* + * ELF Machine types: (EM_*). + */ + +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_IAMCU 6 +#define EM_860 7 +#define EM_MIPS 8 +#define EM_S370 9 +#define EM_MIPS_RS3_LE 10 +#define EM_PARISC 15 +#define EM_VPP500 17 +#define EM_SPARC32PLUS 18 +#define EM_960 19 +#define EM_PPC 20 +#define EM_PPC64 21 +#define EM_S390 22 +#define EM_SPU 23 +#define EM_V800 36 +#define EM_FR20 37 +#define EM_RH32 38 +#define EM_RCE 39 +#define EM_ARM 40 +#define EM_ALPHA 41 +#define EM_SH 42 +#define EM_SPARCV9 43 +#define EM_TRICORE 44 +#define EM_ARC 45 +#define EM_H8_300 46 +#define EM_H8_300H 47 +#define EM_H8S 48 +#define EM_H8_500 49 +#define EM_IA_64 50 +#define EM_MIPS_X 51 +#define EM_COLDFIRE 52 +#define EM_68HC12 53 +#define EM_MMA 54 +#define EM_PCP 55 +#define EM_NCPU 56 +#define EM_NDR1 57 +#define EM_STARCORE 58 +#define EM_ME16 59 +#define EM_ST100 60 +#define EM_TINYJ 61 +#define EM_X86_64 62 +#define EM_PDSP 63 +#define EM_PDP10 64 +#define EM_PDP11 65 +#define EM_FX66 66 +#define EM_ST9PLUS 67 +#define EM_ST7 68 +#define EM_68HC16 69 +#define EM_68HC11 70 +#define EM_68HC08 71 +#define EM_68HC05 72 +#define EM_SVX 73 +#define EM_ST19 74 +#define EM_VAX 75 +#define EM_CRIS 76 +#define EM_JAVELIN 77 +#define EM_FIREPATH 78 +#define EM_ZSP 79 +#define EM_MMIX 80 +#define EM_HUANY 81 +#define EM_PRISM 82 +#define EM_AVR 83 +#define EM_FR30 84 +#define EM_D10V 85 +#define EM_D30V 86 +#define EM_V850 87 +#define EM_M32R 88 +#define EM_MN10300 89 +#define EM_MN10200 90 +#define EM_PJ 91 +#define EM_OPENRISC 92 +#define EM_ARC_COMPACT 93 +#define EM_XTENSA 94 +#define EM_VIDEOCORE 95 +#define EM_TMM_GPP 96 +#define EM_NS32K 97 +#define EM_TPC 98 +#define EM_SNP1K 99 +#define EM_ST200 100 +#define EM_IP2K 101 +#define EM_MAX 102 +#define EM_CR 103 +#define EM_F2MC16 104 +#define EM_MSP430 105 +#define EM_BLACKFIN 106 +#define EM_SE_C33 107 +#define EM_SEP 108 +#define EM_ARCA 109 +#define EM_UNICORE 110 +#define EM_EXCESS 111 +#define EM_DXP 112 +#define EM_ALTERA_NIOS2 113 +#define EM_CRX 114 +#define EM_XGATE 115 +#define EM_C166 116 +#define EM_M16C 117 +#define EM_DSPIC30F 118 +#define EM_CE 119 +#define EM_M32C 120 +#define EM_TSK3000 131 +#define EM_RS08 132 +#define EM_SHARC 133 +#define EM_ECOG2 134 +#define EM_SCORE7 135 +#define EM_DSP24 136 +#define EM_VIDEOCORE3 137 +#define EM_LATTICEMICO32 138 +#define EM_SE_C17 139 +#define EM_TI_C6000 140 +#define EM_TI_C2000 141 +#define EM_TI_C5500 142 +#define EM_TI_ARP32 143 +#define EM_TI_PRU 144 +#define EM_MMDSP_PLUS 160 +#define EM_CYPRESS_M8C 161 +#define EM_R32C 162 +#define EM_TRIMEDIA 163 +#define EM_QDSP6 164 +#define EM_8051 165 +#define EM_STXP7X 166 +#define EM_NDS32 167 +#define EM_ECOG1 168 +#define EM_ECOG1X 168 +#define EM_MAXQ30 169 +#define EM_XIMO16 170 +#define EM_MANIK 171 +#define EM_CRAYNV2 172 +#define EM_RX 173 +#define EM_METAG 174 +#define EM_MCST_ELBRUS 175 +#define EM_ECOG16 176 +#define EM_CR16 177 +#define EM_ETPU 178 +#define EM_SLE9X 179 +#define EM_L10M 180 +#define EM_K10M 181 +#define EM_AARCH64 183 +#define EM_AVR32 185 +#define EM_STM8 186 +#define EM_TILE64 187 +#define EM_TILEPRO 188 +#define EM_MICROBLAZE 189 +#define EM_CUDA 190 +#define EM_TILEGX 191 +#define EM_CLOUDSHIELD 192 +#define EM_COREA_1ST 193 +#define EM_COREA_2ND 194 +#define EM_ARC_COMPACT2 195 +#define EM_OPEN8 196 +#define EM_RL78 197 +#define EM_VIDEOCORE5 198 +#define EM_78KOR 199 +#define EM_56800EX 200 +#define EM_BA1 201 +#define EM_BA2 202 +#define EM_XCORE 203 +#define EM_MCHP_PIC 204 +#define EM_INTELGT 205 +#define EM_INTEL206 206 +#define EM_INTEL207 207 +#define EM_INTEL208 208 +#define EM_INTEL209 209 +#define EM_KM32 210 +#define EM_KMX32 211 +#define EM_KMX16 212 +#define EM_KMX8 213 +#define EM_KVARC 214 +#define EM_CDP 215 +#define EM_COGE 216 +#define EM_COOL 217 +#define EM_NORC 218 +#define EM_CSR_KALIMBA 219 +#define EM_Z80 220 +#define EM_VISIUM 221 +#define EM_FT32 222 +#define EM_MOXIE 223 +#define EM_AMDGPU 224 +#define EM_RISCV 243 +#define EM_LANAI 244 +#define EM_CEVA 245 +#define EM_CEVA_X2 246 +#define EM_BPF 247 +#define EM_GRAPHCORE_IPU 248 +#define EM_IMG1 249 +#define EM_NFP 250 +#define EM_VE 251 +#define EM_CSKY 252 +#define EM_ARC_COMPACT3_64 253 +#define EM_MCS6502 254 +#define EM_ARC_COMPACT3 255 +#define EM_KVX 256 +#define EM_65816 257 +#define EM_LOONGARCH 258 +#define EM_KF32 259 +#define EM_U16_U8CORE 260 +#define EM_TACHYUM 261 +#define EM_56800EF 262 +#define EM_SBF 263 +#define EM_AIENGINE 264 +#define EM_SIMA_MLA 265 +#define EM_BANG 266 +#define EM_LOONGGPU 267 + +/* Other synonyms. */ + +#define EM_AMD64 EM_X86_64 +#define EM_ARC_A5 EM_ARC_COMPACT + + +/* + * ELF file types: (ET_*). + */ + +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOOS 0xFE00U +#define ET_HIOS 0xFEFFU +#define ET_LOPROC 0xFF00U +#define ET_HIPROC 0xFFFFU + + +/* ELF file format version numbers. */ + +#define EV_NONE 0 +#define EV_CURRENT 1 + + +/* + * Flags for section groups. + */ + +#define GRP_COMDAT 0x1 +#define GRP_MASKOS 0x0ff00000 +#define GRP_MASKPROC 0xf0000000 + + +/* + * Flags / mask for .gnu.versym sections. + */ + +#define VERSYM_VERSION 0x7fff +#define VERSYM_HIDDEN 0x8000 + + +/* + * Flags used by program header table entries. + */ + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKOS 0x0ff00000 +#define PF_MASKPROC 0xf0000000 +#define PF_ARM_SB 0x10000000 +#define PF_ARM_PI 0x20000000 +#define PF_ARM_ABS 0x40000000 + + +/* + * Types of program header table entries. + */ + +#define PT_NULL 0UL +#define PT_LOAD 1UL +#define PT_DYNAMIC 2UL +#define PT_INTERP 3UL +#define PT_NOTE 4UL +#define PT_SHLIB 5UL +#define PT_PHDR 6UL +#define PT_TLS 7UL +#define PT_LOOS 0x60000000UL +#define PT_SUNW_UNWIND 0x6464E550UL +#define PT_GNU_EH_FRAME 0x6474E550UL +#define PT_GNU_STACK 0x6474E551UL +#define PT_GNU_RELRO 0x6474E552UL +#define PT_OPENBSD_RANDOMIZE 0x65A3DBE6UL +#define PT_OPENBSD_WXNEEDED 0x65A3DBE7UL +#define PT_OPENBSD_BOOTDATA 0x65A41BE6UL +#define PT_SUNWBSS 0x6FFFFFFAUL +#define PT_SUNWSTACK 0x6FFFFFFBUL +#define PT_SUNWDTRACE 0x6FFFFFFCUL +#define PT_SUNWCAP 0x6FFFFFFDUL +#define PT_HIOS 0x6FFFFFFFUL +#define PT_LOPROC 0x70000000UL +#define PT_ARM_ARCHEXT 0x70000000UL +#define PT_ARM_EXIDX 0x70000001UL +#define PT_MIPS_REGINFO 0x70000000UL +#define PT_MIPS_RTPROC 0x70000001UL +#define PT_MIPS_OPTIONS 0x70000002UL +#define PT_HIPROC 0x7FFFFFFFUL + +/* synonyms. */ + +#define PT_ARM_UNWIND PT_ARM_EXIDX +#define PT_HISUNW PT_HIOS +#define PT_LOSUNW PT_SUNWBSS + + +/* + * Section flags. + */ + +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MERGE 0x10 +#define SHF_STRINGS 0x20 +#define SHF_INFO_LINK 0x40 +#define SHF_LINK_ORDER 0x80 +#define SHF_OS_NONCONFORMING 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_COMPRESSED 0x800 +#define SHF_MASKOS 0x0FF00000UL +#define SHF_AMD64_LARGE 0x10000000UL +#define SHF_ENTRYSECT 0x10000000UL +#define SHF_COMDEF 0x80000000UL +#define SHF_MIPS_GPREL 0x10000000UL +#define SHF_MIPS_MERGE 0x20000000UL +#define SHF_MIPS_ADDR 0x40000000UL +#define SHF_MIPS_STRING 0x80000000UL +#define SHF_MIPS_NOSTRIP 0x08000000UL +#define SHF_MIPS_LOCAL 0x04000000UL +#define SHF_MIPS_NAMES 0x02000000UL +#define SHF_MIPS_NODUPE 0x01000000UL +#define SHF_ORDERED 0x40000000UL +#define SHF_EXCLUDE 0x80000000UL +#define SHF_MASKPROC 0xF0000000UL + + +/* + * Special section indices. + */ + +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xFF00U +#define SHN_LOPROC 0xFF00U +#define SHN_BEFORE 0xFF00U +#define SHN_AFTER 0xFF01U +#define SHN_AMD64_LCOMMON 0xFF02U +#define SHN_MIPS_ACOMMON 0xFF00U +#define SHN_MIPS_TEXT 0xFF01U +#define SHN_MIPS_DATA 0xFF02U +#define SHN_MIPS_SCOMMON 0xFF03U +#define SHN_MIPS_SUNDEFINED 0xFF04U +#define SHN_MIPS_LCOMMON 0xFF05U +#define SHN_MIPS_LUNDEFINED 0xFF06U +#define SHN_HIPROC 0xFF1FU +#define SHN_LOOS 0xFF20U +#define SHN_SUNW_IGNORE 0xFF3FU +#define SHN_HIOS 0xFF3FU +#define SHN_ABS 0xFFF1U +#define SHN_COMMON 0xFFF2U +#define SHN_XINDEX 0xFFFFU +#define SHN_HIRESERVE 0xFFFFU + + +/* + * Section types. + */ + +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_LOOS 0x60000000UL +#define SHT_SUNW_dof 0x6FFFFFF4UL +#define SHT_SUNW_cap 0x6FFFFFF5UL +#define SHT_GNU_ATTRIBUTES 0x6FFFFFF5UL +#define SHT_SUNW_SIGNATURE 0x6FFFFFF6UL +#define SHT_GNU_HASH 0x6FFFFFF6UL +#define SHT_GNU_LIBLIST 0x6FFFFFF7UL +#define SHT_SUNW_ANNOTATE 0x6FFFFFF7UL +#define SHT_SUNW_DEBUGSTR 0x6FFFFFF8UL +#define SHT_CHECKSUM 0x6FFFFFF8UL +#define SHT_SUNW_DEBUG 0x6FFFFFF9UL +#define SHT_SUNW_move 0x6FFFFFFAUL +#define SHT_SUNW_COMDAT 0x6FFFFFFBUL +#define SHT_SUNW_syminfo 0x6FFFFFFCUL +#define SHT_SUNW_verdef 0x6FFFFFFDUL +#define SHT_SUNW_verneed 0x6FFFFFFEUL +#define SHT_SUNW_versym 0x6FFFFFFFUL +#define SHT_HIOS 0x6FFFFFFFUL +#define SHT_LOPROC 0x70000000UL +#define SHT_ARM_EXIDX 0x70000001UL +#define SHT_ARM_PREEMPTMAP 0x70000002UL +#define SHT_ARM_ATTRIBUTES 0x70000003UL +#define SHT_ARM_DEBUGOVERLAY 0x70000004UL +#define SHT_ARM_OVERLAYSECTION 0x70000005UL +#define SHT_MIPS_LIBLIST 0x70000000UL +#define SHT_MIPS_MSYM 0x70000001UL +#define SHT_MIPS_CONFLICT 0x70000002UL +#define SHT_MIPS_GPTAB 0x70000003UL +#define SHT_MIPS_UCODE 0x70000004UL +#define SHT_MIPS_DEBUG 0x70000005UL +#define SHT_MIPS_REGINFO 0x70000006UL +#define SHT_MIPS_PACKAGE 0x70000007UL +#define SHT_MIPS_PACKSYM 0x70000008UL +#define SHT_MIPS_RELD 0x70000009UL +#define SHT_MIPS_IFACE 0x7000000BUL +#define SHT_MIPS_CONTENT 0x7000000CUL +#define SHT_MIPS_OPTIONS 0x7000000DUL +#define SHT_MIPS_DELTASYM 0x7000001BUL +#define SHT_MIPS_DELTAINST 0x7000001CUL +#define SHT_MIPS_DELTACLASS 0x7000001DUL +#define SHT_MIPS_DWARF 0x7000001EUL +#define SHT_MIPS_DELTADECL 0x7000001FUL +#define SHT_MIPS_SYMBOL_LIB 0x70000020UL +#define SHT_MIPS_EVENTS 0x70000021UL +#define SHT_MIPS_TRANSLATE 0x70000022UL +#define SHT_MIPS_PIXIE 0x70000023UL +#define SHT_MIPS_XLATE 0x70000024UL +#define SHT_MIPS_XLATE_DEBUG 0x70000025UL +#define SHT_MIPS_WHIRL 0x70000026UL +#define SHT_MIPS_EH_REGION 0x70000027UL +#define SHT_MIPS_XLATE_OLD 0x70000028UL +#define SHT_MIPS_PDR_EXCEPTION 0x70000029UL +#define SHT_MIPS_ABIFLAGS 0x7000002AUL +#define SHT_SPARC_GOTDATA 0x70000000UL +#define SHT_X86_64_UNWIND 0x70000001UL +#define SHT_ORDERED 0x7FFFFFFFUL +#define SHT_HIPROC 0x7FFFFFFFUL +#define SHT_LOUSER 0x80000000UL +#define SHT_HIUSER 0xFFFFFFFFUL + +/* Aliases for section types. */ + +#define SHT_AMD64_UNWIND SHT_X86_64_UNWIND +#define SHT_GNU_verdef SHT_SUNW_verdef +#define SHT_GNU_verneed SHT_SUNW_verneed +#define SHT_GNU_versym SHT_SUNW_versym + + +#define PN_XNUM 0xFFFFU /* Use extended section numbering. */ + +/* + * Symbol binding information. + */ + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOOS 10 +#define STB_GNU_UNIQUE 10 +#define STB_HIOS 12 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + + +/* + * Symbol types + */ + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 +#define STT_LOOS 10 +#define STT_GNU_IFUNC 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_ARM_TFUNC 13 +#define STT_ARM_16BIT 15 +#define STT_SPARC_REGISTER 13 +#define STT_HIPROC 15 + +/* Additional constants related to symbol types. */ + +#define STT_NUM 7 + + +/* + * Symbol binding. + */ + +#define SYMINFO_BT_SELF 0xFFFFU +#define SYMINFO_BT_PARENT 0xFFFEU +#define SYMINFO_BT_NONE 0xFFFDU + + +/* + * Symbol visibility. + */ + +#define STV_DEFAULT 0 +#define STV_INTERNAL 1 +#define STV_HIDDEN 2 +#define STV_PROTECTED 3 + + +/* + * Symbol flags. + */ + +#define SYMINFO_FLG_DIRECT 0x01 +#define SYMINFO_FLG_COPY 0x04 +#define SYMINFO_FLG_LAZYLOAD 0x08 +#define SYMINFO_FLG_DIRECTBIND 0x10 +#define SYMINFO_FLG_NOEXTDIRECT 0x20 + + +/* + * Versioning dependencies. + */ + +#define VER_NDX_LOCAL 0 +#define VER_NDX_GLOBAL 1 + + +/* + * Versioning flags. + */ + +#define VER_FLG_BASE 0x1 +#define VER_FLG_WEAK 0x2 + + +/* + * Versioning needs + */ + +#define VER_NEED_NONE 0 +#define VER_NEED_CURRENT 1 + + +/* + * Versioning numbers. + */ + +#define VER_DEF_NONE 0 +#define VER_DEF_CURRENT 1 + + +/** + ** Relocation types. + **/ + + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_JUMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 +#define R_386_TLS_IE 15 +#define R_386_TLS_GOTIE 16 +#define R_386_TLS_LE 17 +#define R_386_TLS_GD 18 +#define R_386_TLS_LDM 19 +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 +#define R_386_TLS_GD_PUSH 25 +#define R_386_TLS_GD_CALL 26 +#define R_386_TLS_GD_POP 27 +#define R_386_TLS_LDM_32 28 +#define R_386_TLS_LDM_PUSH 29 +#define R_386_TLS_LDM_CALL 30 +#define R_386_TLS_LDM_POP 31 +#define R_386_TLS_LDO_32 32 +#define R_386_TLS_IE_32 33 +#define R_386_TLS_LE_32 34 +#define R_386_TLS_DTPMOD32 35 +#define R_386_TLS_DTPOFF32 36 +#define R_386_TLS_TPOFF32 37 +#define R_386_SIZE32 38 +#define R_386_TLS_GOTDESC 39 +#define R_386_TLS_DESC_CALL 40 +#define R_386_TLS_DESC 41 +#define R_386_IRELATIVE 42 +#define R_386_GOT32X 43 + + +#define R_AARCH64_NONE 0 +#define R_AARCH64_ABS64 257 +#define R_AARCH64_ABS32 258 +#define R_AARCH64_ABS16 259 +#define R_AARCH64_PREL64 260 +#define R_AARCH64_PREL32 261 +#define R_AARCH64_PREL16 262 +#define R_AARCH64_MOVW_UABS_G0 263 +#define R_AARCH64_MOVW_UABS_G0_NC 264 +#define R_AARCH64_MOVW_UABS_G1 265 +#define R_AARCH64_MOVW_UABS_G1_NC 266 +#define R_AARCH64_MOVW_UABS_G2 267 +#define R_AARCH64_MOVW_UABS_G2_NC 268 +#define R_AARCH64_MOVW_UABS_G3 269 +#define R_AARCH64_MOVW_SABS_G0 270 +#define R_AARCH64_MOVW_SABS_G1 271 +#define R_AARCH64_MOVW_SABS_G2 272 +#define R_AARCH64_LD_PREL_LO19 273 +#define R_AARCH64_ADR_PREL_LO21 274 +#define R_AARCH64_ADR_PREL_PG_HI21 275 +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 +#define R_AARCH64_ADD_ABS_LO12_NC 277 +#define R_AARCH64_LDST8_ABS_LO12_NC 278 +#define R_AARCH64_TSTBR14 279 +#define R_AARCH64_CONDBR19 280 +#define R_AARCH64_JUMP26 282 +#define R_AARCH64_CALL26 283 +#define R_AARCH64_LDST16_ABS_LO12_NC 284 +#define R_AARCH64_LDST32_ABS_LO12_NC 285 +#define R_AARCH64_LDST64_ABS_LO12_NC 286 +#define R_AARCH64_MOVW_PREL_G0 287 +#define R_AARCH64_MOVW_PREL_G0_NC 288 +#define R_AARCH64_MOVW_PREL_G1 289 +#define R_AARCH64_MOVW_PREL_G1_NC 290 +#define R_AARCH64_MOVW_PREL_G2 291 +#define R_AARCH64_MOVW_PREL_G2_NC 292 +#define R_AARCH64_MOVW_PREL_G3 293 +#define R_AARCH64_LDST128_ABS_LO12_NC 299 +#define R_AARCH64_MOVW_GOTOFF_G0 300 +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 +#define R_AARCH64_MOVW_GOTOFF_G1 302 +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 +#define R_AARCH64_MOVW_GOTOFF_G2 304 +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 +#define R_AARCH64_MOVW_GOTOFF_G3 306 +#define R_AARCH64_GOTREL64 307 +#define R_AARCH64_GOTREL32 308 +#define R_AARCH64_GOT_LD_PREL19 309 +#define R_AARCH64_LD64_GOTOFF_LO15 310 +#define R_AARCH64_ADR_GOT_PAGE 311 +#define R_AARCH64_LD64_GOT_LO12_NC 312 +#define R_AARCH64_LD64_GOTPAGE_LO15 313 +#define R_AARCH64_TLSGD_ADR_PREL21 512 +#define R_AARCH64_TLSGD_ADR_PAGE21 513 +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 +#define R_AARCH64_TLSGD_MOVW_G1 515 +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 +#define R_AARCH64_TLSLD_ADR_PREL21 517 +#define R_AARCH64_TLSLD_ADR_PAGE21 518 +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 +#define R_AARCH64_TLSLD_MOVW_G1 520 +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 +#define R_AARCH64_TLSLD_LD_PREL19 522 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 529 +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 +#define R_AARCH64_TLSDESC_LD_PREL19 560 +#define R_AARCH64_TLSDESC_ADR_PREL21 561 +#define R_AARCH64_TLSDESC_ADR_PAGE21 562 +#define R_AARCH64_TLSDESC_LD64_LO12 563 +#define R_AARCH64_TLSDESC_ADD_LO12 564 +#define R_AARCH64_TLSDESC_OFF_G1 565 +#define R_AARCH64_TLSDESC_OFF_G0_NC 566 +#define R_AARCH64_TLSDESC_LDR 567 +#define R_AARCH64_TLSDESC_ADD 568 +#define R_AARCH64_TLSDESC_CALL 569 +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 +#define R_AARCH64_COPY 1024 +#define R_AARCH64_GLOB_DAT 1025 +#define R_AARCH64_JUMP_SLOT 1026 +#define R_AARCH64_RELATIVE 1027 +#define R_AARCH64_TLS_DTPREL64 1028 +#define R_AARCH64_TLS_DTPMOD64 1029 +#define R_AARCH64_TLS_TPREL64 1030 +#define R_AARCH64_TLSDESC 1031 +#define R_AARCH64_IRELATIVE 1032 + + +#define R_AMD64_NONE 0 +#define R_AMD64_64 1 +#define R_AMD64_PC32 2 +#define R_AMD64_GOT32 3 +#define R_AMD64_PLT32 4 +#define R_AMD64_COPY 5 +#define R_AMD64_GLOB_DAT 6 +#define R_AMD64_JUMP_SLOT 7 +#define R_AMD64_RELATIVE 8 +#define R_AMD64_GOTPCREL 9 +#define R_AMD64_32 10 +#define R_AMD64_32S 11 +#define R_AMD64_16 12 +#define R_AMD64_PC16 13 +#define R_AMD64_8 14 +#define R_AMD64_PC8 15 +#define R_AMD64_PC64 24 +#define R_AMD64_GOTOFF64 25 +#define R_AMD64_GOTPC32 26 + + +#define R_ARM_NONE 0 +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_LDR_PC_G0 4 +#define R_ARM_ABS16 5 +#define R_ARM_ABS12 6 +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 +#define R_ARM_SBREL32 9 +#define R_ARM_THM_CALL 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_BREL_ADJ 12 +#define R_ARM_SWI24 13 +#define R_ARM_TLS_DESC 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 +#define R_ARM_TLS_DTPOFF32 18 +#define R_ARM_TLS_TPOFF32 19 +#define R_ARM_COPY 20 +#define R_ARM_GLOB_DAT 21 +#define R_ARM_JUMP_SLOT 22 +#define R_ARM_RELATIVE 23 +#define R_ARM_GOTOFF32 24 +#define R_ARM_BASE_PREL 25 +#define R_ARM_GOT_BREL 26 +#define R_ARM_PLT32 27 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_THM_JUMP24 30 +#define R_ARM_BASE_ABS 31 +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0_NC 35 +#define R_ARM_ALU_SBREL_19_12_NC 36 +#define R_ARM_ALU_SBREL_27_20_CK 37 +#define R_ARM_TARGET1 38 +#define R_ARM_SBREL31 39 +#define R_ARM_V4BX 40 +#define R_ARM_TARGET2 41 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 +#define R_ARM_MOVW_PREL_NC 45 +#define R_ARM_MOVT_PREL 46 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 +#define R_ARM_THM_MOVW_PREL_NC 49 +#define R_ARM_THM_MOVT_PREL 50 +#define R_ARM_THM_JUMP19 51 +#define R_ARM_THM_JUMP6 52 +#define R_ARM_THM_ALU_PREL_11_0 53 +#define R_ARM_THM_PC12 54 +#define R_ARM_ABS32_NOI 55 +#define R_ARM_REL32_NOI 56 +#define R_ARM_ALU_PC_G0_NC 57 +#define R_ARM_ALU_PC_G0 58 +#define R_ARM_ALU_PC_G1_NC 59 +#define R_ARM_ALU_PC_G1 60 +#define R_ARM_ALU_PC_G2 61 +#define R_ARM_LDR_PC_G1 62 +#define R_ARM_LDR_PC_G2 63 +#define R_ARM_LDRS_PC_G0 64 +#define R_ARM_LDRS_PC_G1 65 +#define R_ARM_LDRS_PC_G2 66 +#define R_ARM_LDC_PC_G0 67 +#define R_ARM_LDC_PC_G1 68 +#define R_ARM_LDC_PC_G2 69 +#define R_ARM_ALU_SB_G0_NC 70 +#define R_ARM_ALU_SB_G0 71 +#define R_ARM_ALU_SB_G1_NC 72 +#define R_ARM_ALU_SB_G1 73 +#define R_ARM_ALU_SB_G2 74 +#define R_ARM_LDR_SB_G0 75 +#define R_ARM_LDR_SB_G1 76 +#define R_ARM_LDR_SB_G2 77 +#define R_ARM_LDRS_SB_G0 78 +#define R_ARM_LDRS_SB_G1 79 +#define R_ARM_LDRS_SB_G2 80 +#define R_ARM_LDC_SB_G0 81 +#define R_ARM_LDC_SB_G1 82 +#define R_ARM_LDC_SB_G2 83 +#define R_ARM_MOVW_BREL_NC 84 +#define R_ARM_MOVT_BREL 85 +#define R_ARM_MOVW_BREL 86 +#define R_ARM_THM_MOVW_BREL_NC 87 +#define R_ARM_THM_MOVT_BREL 88 +#define R_ARM_THM_MOVW_BREL 89 +#define R_ARM_TLS_GOTDESC 90 +#define R_ARM_TLS_CALL 91 +#define R_ARM_TLS_DESCSEQ 92 +#define R_ARM_THM_TLS_CALL 93 +#define R_ARM_PLT32_ABS 94 +#define R_ARM_GOT_ABS 95 +#define R_ARM_GOT_PREL 96 +#define R_ARM_GOT_BREL12 97 +#define R_ARM_GOTOFF12 98 +#define R_ARM_GOTRELAX 99 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_JUMP11 102 +#define R_ARM_THM_JUMP8 103 +#define R_ARM_TLS_GD32 104 +#define R_ARM_TLS_LDM32 105 +#define R_ARM_TLS_LDO32 106 +#define R_ARM_TLS_IE32 107 +#define R_ARM_TLS_LE32 108 +#define R_ARM_TLS_LDO12 109 +#define R_ARM_TLS_LE12 110 +#define R_ARM_TLS_IE12GP 111 +#define R_ARM_PRIVATE_0 112 +#define R_ARM_PRIVATE_1 113 +#define R_ARM_PRIVATE_2 114 +#define R_ARM_PRIVATE_3 115 +#define R_ARM_PRIVATE_4 116 +#define R_ARM_PRIVATE_5 117 +#define R_ARM_PRIVATE_6 118 +#define R_ARM_PRIVATE_7 119 +#define R_ARM_PRIVATE_8 120 +#define R_ARM_PRIVATE_9 121 +#define R_ARM_PRIVATE_10 122 +#define R_ARM_PRIVATE_11 123 +#define R_ARM_PRIVATE_12 124 +#define R_ARM_PRIVATE_13 125 +#define R_ARM_PRIVATE_14 126 +#define R_ARM_PRIVATE_15 127 +#define R_ARM_ME_TOO 128 +#define R_ARM_THM_TLS_DESCSEQ16 129 +#define R_ARM_THM_TLS_DESCSEQ32 130 +#define R_ARM_THM_GOT_BREL12 131 +#define R_ARM_IRELATIVE 140 + + +#define R_IA_64_NONE 0 +#define R_IA64_NONE 0 +#define R_IA_64_IMM14 0x21 +#define R_IA64_IMM14 0x21 +#define R_IA_64_IMM22 0x22 +#define R_IA64_IMM22 0x22 +#define R_IA_64_IMM64 0x23 +#define R_IA64_IMM64 0x23 +#define R_IA_64_DIR32MSB 0x24 +#define R_IA64_DIR32MSB 0x24 +#define R_IA_64_DIR32LSB 0x25 +#define R_IA64_DIR32LSB 0x25 +#define R_IA_64_DIR64MSB 0x26 +#define R_IA64_DIR64MSB 0x26 +#define R_IA_64_DIR64LSB 0x27 +#define R_IA64_DIR64LSB 0x27 +#define R_IA_64_GPREL22 0x2a +#define R_IA64_GPREL22 0x2a +#define R_IA_64_GPREL64I 0x2b +#define R_IA64_GPREL64I 0x2b +#define R_IA_64_GPREL32MSB 0x2c +#define R_IA_64_GPREL32LSB 0x2d +#define R_IA_64_GPREL64MSB 0x2e +#define R_IA64_GPREL64MSB 0x2e +#define R_IA_64_GPREL64LSB 0x2f +#define R_IA64_GPREL64LSB 0x2f +#define R_IA_64_LTOFF22 0x32 +#define R_IA64_LTOFF22 0x32 +#define R_IA_64_LTOFF64I 0x33 +#define R_IA64_LTOFF64I 0x33 +#define R_IA_64_PLTOFF22 0x3a +#define R_IA64_PLTOFF22 0x3a +#define R_IA_64_PLTOFF64I 0x3b +#define R_IA64_PLTOFF64I 0x3b +#define R_IA_64_PLTOFF64MSB 0x3e +#define R_IA64_PLTOFF64MSB 0x3e +#define R_IA_64_PLTOFF64LSB 0x3f +#define R_IA64_PLTOFF64LSB 0x3f +#define R_IA_64_FPTR64I 0x43 +#define R_IA64_FPTR64I 0x43 +#define R_IA_64_FPTR32MSB 0x44 +#define R_IA64_FPTR32MSB 0x44 +#define R_IA_64_FPTR32LSB 0x45 +#define R_IA64_FPTR32LSB 0x45 +#define R_IA_64_FPTR64MSB 0x46 +#define R_IA64_FPTR64MSB 0x46 +#define R_IA_64_FPTR64LSB 0x47 +#define R_IA64_FPTR64LSB 0x47 +#define R_IA_64_PCREL60B 0x48 +#define R_IA_64_PCREL21B 0x49 +#define R_IA64_PCREL21B 0x49 +#define R_IA_64_PCREL21M 0x4a +#define R_IA64_PCREL21M 0x4a +#define R_IA_64_PCREL21F 0x4b +#define R_IA64_PCREL21F 0x4b +#define R_IA_64_PCREL32MSB 0x4c +#define R_IA64_PCREL32MSB 0x4c +#define R_IA_64_PCREL32LSB 0x4d +#define R_IA64_PCREL32LSB 0x4d +#define R_IA_64_PCREL64MSB 0x4e +#define R_IA64_PCREL64MSB 0x4e +#define R_IA_64_PCREL64LSB 0x4f +#define R_IA64_PCREL64LSB 0x4f +#define R_IA_64_LTOFF_FPTR22 0x52 +#define R_IA64_LTOFF_FPTR22 0x52 +#define R_IA_64_LTOFF_FPTR64I 0x53 +#define R_IA64_LTOFF_FPTR64I 0x53 +#define R_IA_64_LTOFF_FPTR32MSB 0x54 +#define R_IA64_LTOFF_FPTR32MSB 0x54 +#define R_IA_64_LTOFF_FPTR32LSB 0x55 +#define R_IA64_LTOFF_FPTR32LSB 0x55 +#define R_IA_64_LTOFF_FPTR64MSB 0x56 +#define R_IA64_LTOFF_FPTR64MSB 0x56 +#define R_IA_64_LTOFF_FPTR64LSB 0x57 +#define R_IA64_LTOFF_FPTR64LSB 0x57 +#define R_IA_64_SEGREL32MSB 0x5c +#define R_IA64_SEGREL32MSB 0x5c +#define R_IA_64_SEGREL32LSB 0x5d +#define R_IA64_SEGREL32LSB 0x5d +#define R_IA_64_SEGREL64MSB 0x5e +#define R_IA64_SEGREL64MSB 0x5e +#define R_IA_64_SEGREL64LSB 0x5f +#define R_IA64_SEGREL64LSB 0x5f +#define R_IA_64_SECREL32MSB 0x64 +#define R_IA64_SECREL32MSB 0x64 +#define R_IA_64_SECREL32LSB 0x65 +#define R_IA64_SECREL32LSB 0x65 +#define R_IA_64_SECREL64MSB 0x66 +#define R_IA64_SECREL64MSB 0x66 +#define R_IA_64_SECREL64LSB 0x67 +#define R_IA64_SECREL64LSB 0x67 +#define R_IA_64_REL32MSB 0x6c +#define R_IA64_REL32MSB 0x6c +#define R_IA_64_REL32LSB 0x6d +#define R_IA64_REL32LSB 0x6d +#define R_IA_64_REL64MSB 0x6e +#define R_IA64_REL64MSB 0x6e +#define R_IA_64_REL64LSB 0x6f +#define R_IA64_REL64LSB 0x6f +#define R_IA_64_LTV32MSB 0x74 +#define R_IA64_LTV32MSB 0x74 +#define R_IA_64_LTV32LSB 0x75 +#define R_IA64_LTV32LSB 0x75 +#define R_IA_64_LTV64MSB 0x76 +#define R_IA64_LTV64MSB 0x76 +#define R_IA_64_LTV64LSB 0x77 +#define R_IA64_LTV64LSB 0x77 +#define R_IA_64_PCREL21BI 0x79 +#define R_IA_64_PCREL22 0x7A +#define R_IA_64_PCREL64I 0x7B +#define R_IA_64_IPLTMSB 0x80 +#define R_IA64_IPLTMSB 0x80 +#define R_IA_64_IPLTLSB 0x81 +#define R_IA64_IPLTLSB 0x81 +#define R_IA_64_SUB 0x85 +#define R_IA64_SUB 0x85 +#define R_IA_64_LTOFF22X 0x86 +#define R_IA64_LTOFF22X 0x86 +#define R_IA_64_LDXMOV 0x87 +#define R_IA64_LDXMOV 0x87 +#define R_IA_64_TPREL14 0x91 +#define R_IA64_TPREL14 0x91 +#define R_IA_64_TPREL22 0x92 +#define R_IA64_TPREL22 0x92 +#define R_IA_64_TPREL64I 0x93 +#define R_IA64_TPREL64I 0x93 +#define R_IA_64_TPREL64MSB 0x96 +#define R_IA64_TPREL64MSB 0x96 +#define R_IA_64_TPREL64LSB 0x97 +#define R_IA64_TPREL64LSB 0x97 +#define R_IA_64_LTOFF_TPREL22 0x9A +#define R_IA64_LTOFF_TPREL22 0x9A +#define R_IA_64_DTPMOD64MSB 0xA6 +#define R_IA64_DTPMOD64MSB 0xA6 +#define R_IA_64_DTPMOD64LSB 0xA7 +#define R_IA64_DTPMOD64LSB 0xA7 +#define R_IA_64_LTOFF_DTPMOD22 0xAA +#define R_IA64_LTOFF_DTPMOD22 0xAA +#define R_IA_64_DTPREL14 0xB1 +#define R_IA64_DTPREL14 0xB1 +#define R_IA_64_DTPREL22 0xB2 +#define R_IA64_DTPREL22 0xB2 +#define R_IA_64_DTPREL64I 0xB3 +#define R_IA64_DTPREL64I 0xB3 +#define R_IA_64_DTPREL32MSB 0xB4 +#define R_IA64_DTPREL32MSB 0xB4 +#define R_IA_64_DTPREL32LSB 0xB5 +#define R_IA64_DTPREL32LSB 0xB5 +#define R_IA_64_DTPREL64MSB 0xB6 +#define R_IA64_DTPREL64MSB 0xB6 +#define R_IA_64_DTPREL64LSB 0xB7 +#define R_IA64_DTPREL64LSB 0xB7 +#define R_IA_64_LTOFF_DTPREL22 0xBA +#define R_IA64_LTOFF_DTPREL22 0xBA + + +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_CALLHI16 30 +#define R_MIPS_CALLLO16 31 +#define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 +#define R_MIPS_TLS_DTPREL32 39 +#define R_MIPS_TLS_DTPMOD64 40 +#define R_MIPS_TLS_DTPREL64 41 +#define R_MIPS_TLS_GD 42 +#define R_MIPS_TLS_LDM 43 +#define R_MIPS_TLS_DTPREL_HI16 44 +#define R_MIPS_TLS_DTPREL_LO16 45 +#define R_MIPS_TLS_GOTTPREL 46 +#define R_MIPS_TLS_TPREL32 47 +#define R_MIPS_TLS_TPREL64 48 +#define R_MIPS_TLS_TPREL_HI16 49 +#define R_MIPS_TLS_TPREL_LO16 50 + + +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR24 2 +#define R_PPC_ADDR16 3 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_ADDR14 7 +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 +#define R_PPC_REL14 11 +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +#define R_PPC_ADDR30 37 +#define R_PPC_TLS 67 +#define R_PPC_DTPMOD32 68 +#define R_PPC_TPREL16 69 +#define R_PPC_TPREL16_LO 70 +#define R_PPC_TPREL16_HI 71 +#define R_PPC_TPREL16_HA 72 +#define R_PPC_TPREL32 73 +#define R_PPC_DTPREL16 74 +#define R_PPC_DTPREL16_LO 75 +#define R_PPC_DTPREL16_HI 76 +#define R_PPC_DTPREL16_HA 77 +#define R_PPC_DTPREL32 78 +#define R_PPC_GOT_TLSGD16 79 +#define R_PPC_GOT_TLSGD16_LO 80 +#define R_PPC_GOT_TLSGD16_HI 81 +#define R_PPC_GOT_TLSGD16_HA 82 +#define R_PPC_GOT_TLSLD16 83 +#define R_PPC_GOT_TLSLD16_LO 84 +#define R_PPC_GOT_TLSLD16_HI 85 +#define R_PPC_GOT_TLSLD16_HA 86 +#define R_PPC_GOT_TPREL16 87 +#define R_PPC_GOT_TPREL16_LO 88 +#define R_PPC_GOT_TPREL16_HI 89 +#define R_PPC_GOT_TPREL16_HA 90 +#define R_PPC_GOT_DTPREL16 91 +#define R_PPC_GOT_DTPREL16_LO 92 +#define R_PPC_GOT_DTPREL16_HI 93 +#define R_PPC_GOT_DTPREL16_HA 94 +#define R_PPC_TLSGD 95 +#define R_PPC_TLSLD 96 +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 + + +#define R_PPC64_NONE 0 +#define R_PPC64_ADDR32 1 +#define R_PPC64_ADDR24 2 +#define R_PPC64_ADDR16 3 +#define R_PPC64_ADDR16_LO 4 +#define R_PPC64_ADDR16_HI 5 +#define R_PPC64_ADDR16_HA 6 +#define R_PPC64_ADDR14 7 +#define R_PPC64_ADDR14_BRTAKEN 8 +#define R_PPC64_ADDR14_BRNTAKEN 9 +#define R_PPC64_REL24 10 +#define R_PPC64_REL14 11 +#define R_PPC64_REL14_BRTAKEN 12 +#define R_PPC64_REL14_BRNTAKEN 13 +#define R_PPC64_GOT16 14 +#define R_PPC64_GOT16_LO 15 +#define R_PPC64_GOT16_HI 16 +#define R_PPC64_GOT16_HA 17 +#define R_PPC64_COPY 19 +#define R_PPC64_GLOB_DAT 20 +#define R_PPC64_JMP_SLOT 21 +#define R_PPC64_RELATIVE 22 +#define R_PPC64_UADDR32 24 +#define R_PPC64_UADDR16 25 +#define R_PPC64_REL32 26 +#define R_PPC64_PLT32 27 +#define R_PPC64_PLTREL32 28 +#define R_PPC64_PLT16_LO 29 +#define R_PPC64_PLT16_HI 30 +#define R_PPC64_PLT16_HA 31 +#define R_PPC64_SECTOFF 33 +#define R_PPC64_SECTOFF_LO 34 +#define R_PPC64_SECTOFF_HI 35 +#define R_PPC64_SECTOFF_HA 36 +#define R_PPC64_ADDR30 37 +#define R_PPC64_ADDR64 38 +#define R_PPC64_ADDR16_HIGHER 39 +#define R_PPC64_ADDR16_HIGHERA 40 +#define R_PPC64_ADDR16_HIGHEST 41 +#define R_PPC64_ADDR16_HIGHESTA 42 +#define R_PPC64_UADDR64 43 +#define R_PPC64_REL64 44 +#define R_PPC64_PLT64 45 +#define R_PPC64_PLTREL64 46 +#define R_PPC64_TOC16 47 +#define R_PPC64_TOC16_LO 48 +#define R_PPC64_TOC16_HI 49 +#define R_PPC64_TOC16_HA 50 +#define R_PPC64_TOC 51 +#define R_PPC64_PLTGOT16 52 +#define R_PPC64_PLTGOT16_LO 53 +#define R_PPC64_PLTGOT16_HI 54 +#define R_PPC64_PLTGOT16_HA 55 +#define R_PPC64_ADDR16_DS 56 +#define R_PPC64_ADDR16_LO_DS 57 +#define R_PPC64_GOT16_DS 58 +#define R_PPC64_GOT16_LO_DS 59 +#define R_PPC64_PLT16_LO_DS 60 +#define R_PPC64_SECTOFF_DS 61 +#define R_PPC64_SECTOFF_LO_DS 62 +#define R_PPC64_TOC16_DS 63 +#define R_PPC64_TOC16_LO_DS 64 +#define R_PPC64_PLTGOT16_DS 65 +#define R_PPC64_PLTGOT16_LO_DS 66 +#define R_PPC64_TLS 67 +#define R_PPC64_DTPMOD64 68 +#define R_PPC64_TPREL16 69 +#define R_PPC64_TPREL16_LO 60 +#define R_PPC64_TPREL16_HI 71 +#define R_PPC64_TPREL16_HA 72 +#define R_PPC64_TPREL64 73 +#define R_PPC64_DTPREL16 74 +#define R_PPC64_DTPREL16_LO 75 +#define R_PPC64_DTPREL16_HI 76 +#define R_PPC64_DTPREL16_HA 77 +#define R_PPC64_DTPREL64 78 +#define R_PPC64_GOT_TLSGD16 79 +#define R_PPC64_GOT_TLSGD16_LO 80 +#define R_PPC64_GOT_TLSGD16_HI 81 +#define R_PPC64_GOT_TLSGD16_HA 82 +#define R_PPC64_GOT_TLSLD16 83 +#define R_PPC64_GOT_TLSLD16_LO 84 +#define R_PPC64_GOT_TLSLD16_HI 85 +#define R_PPC64_GOT_TLSLD16_HA 86 +#define R_PPC64_GOT_TPREL16_DS 87 +#define R_PPC64_GOT_TPREL16_LO_DS 88 +#define R_PPC64_GOT_TPREL16_HI 89 +#define R_PPC64_GOT_TPREL16_HA 90 +#define R_PPC64_GOT_DTPREL16_DS 91 +#define R_PPC64_GOT_DTPREL16_LO_DS 92 +#define R_PPC64_GOT_DTPREL16_HI 93 +#define R_PPC64_GOT_DTPREL16_HA 94 +#define R_PPC64_TPREL16_DS 95 +#define R_PPC64_TPREL16_LO_DS 96 +#define R_PPC64_TPREL16_HIGHER 97 +#define R_PPC64_TPREL16_HIGHERA 98 +#define R_PPC64_TPREL16_HIGHEST 99 +#define R_PPC64_TPREL16_HIGHESTA 100 +#define R_PPC64_DTPREL16_DS 101 +#define R_PPC64_DTPREL16_LO_DS 102 +#define R_PPC64_DTPREL16_HIGHER 103 +#define R_PPC64_DTPREL16_HIGHERA 104 +#define R_PPC64_DTPREL16_HIGHEST 105 +#define R_PPC64_DTPREL16_HIGHESTA 106 +#define R_PPC64_TLSGD 107 +#define R_PPC64_TLSLD 108 + + +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 +#define R_RISCV_IRELATIVE 58 + + +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_HH22 34 +#define R_SPARC_HM10 35 +#define R_SPARC_LM22 36 +#define R_SPARC_PC_HH22 37 +#define R_SPARC_PC_HM10 38 +#define R_SPARC_PC_LM22 39 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_GLOB_JMP 42 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 +#define R_SPARC_DISP64 46 +#define R_SPARC_PLT64 47 +#define R_SPARC_HIX22 48 +#define R_SPARC_LOX10 49 +#define R_SPARC_H44 50 +#define R_SPARC_M44 51 +#define R_SPARC_L44 52 +#define R_SPARC_REGISTER 53 +#define R_SPARC_UA64 54 +#define R_SPARC_UA16 55 +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +#define R_SPARC_GOTDATA_HIX22 80 +#define R_SPARC_GOTDATA_LOX10 81 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#define R_SPARC_GOTDATA_OP 84 +#define R_SPARC_H34 85 + + +#define R_VAX_NONE 0 +#define R_VAX_32 1 +#define R_VAX_16 2 +#define R_VAX_8 3 +#define R_VAX_PC32 4 +#define R_VAX_PC16 5 +#define R_VAX_PC8 6 +#define R_VAX_GOT32 7 +#define R_VAX_PLT32 13 +#define R_VAX_COPY 19 +#define R_VAX_GLOB_DAT 20 +#define R_VAX_JMP_SLOT 21 +#define R_VAX_RELATIVE 22 + + +#define R_X86_64_NONE 0 +#define R_X86_64_64 1 +#define R_X86_64_PC32 2 +#define R_X86_64_GOT32 3 +#define R_X86_64_PLT32 4 +#define R_X86_64_COPY 5 +#define R_X86_64_GLOB_DAT 6 +#define R_X86_64_JUMP_SLOT 7 +#define R_X86_64_RELATIVE 8 +#define R_X86_64_GOTPCREL 9 +#define R_X86_64_32 10 +#define R_X86_64_32S 11 +#define R_X86_64_16 12 +#define R_X86_64_PC16 13 +#define R_X86_64_8 14 +#define R_X86_64_PC8 15 +#define R_X86_64_DTPMOD64 16 +#define R_X86_64_DTPOFF64 17 +#define R_X86_64_TPOFF64 18 +#define R_X86_64_TLSGD 19 +#define R_X86_64_TLSLD 20 +#define R_X86_64_DTPOFF32 21 +#define R_X86_64_GOTTPOFF 22 +#define R_X86_64_TPOFF32 23 +#define R_X86_64_PC64 24 +#define R_X86_64_GOTOFF64 25 +#define R_X86_64_GOTPC32 26 +#define R_X86_64_GOT64 27 +#define R_X86_64_GOTPCREL64 28 +#define R_X86_64_GOTPC64 29 +#define R_X86_64_GOTPLT64 30 +#define R_X86_64_PLTOFF64 31 +#define R_X86_64_SIZE32 32 +#define R_X86_64_SIZE64 33 +#define R_X86_64_GOTPC32_TLSDESC 34 +#define R_X86_64_TLSDESC_CALL 35 +#define R_X86_64_TLSDESC 36 +#define R_X86_64_IRELATIVE 37 +#define R_X86_64_RELATIVE64 38 +#define R_X86_64_PC32_BND 39 +#define R_X86_64_PLT32_BND 40 +#define R_X86_64_GOTPCRELX 41 +#define R_X86_64_REX_GOTPCRELX 42 + + + +/* + * MIPS ABI related. + */ + +#define E_MIPS_ABI_O32 0x00001000 +#define E_MIPS_ABI_O64 0x00002000 +#define E_MIPS_ABI_EABI32 0x00003000 +#define E_MIPS_ABI_EABI64 0x00004000 + + +/** + ** ELF Types. + **/ + +typedef uint32_t Elf32_Addr; /* Program address. */ +typedef uint8_t Elf32_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer. */ +typedef uint32_t Elf32_Off; /* File offset. */ +typedef uint16_t Elf32_Section; /* Section index. */ +typedef int32_t Elf32_Sword; /* Signed integer. */ +typedef uint32_t Elf32_Word; /* Unsigned integer. */ +typedef uint64_t Elf32_Lword; /* Unsigned long integer. */ + +typedef uint64_t Elf64_Addr; /* Program address. */ +typedef uint8_t Elf64_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ +typedef uint64_t Elf64_Off; /* File offset. */ +typedef uint16_t Elf64_Section; /* Section index. */ +typedef int32_t Elf64_Sword; /* Signed integer. */ +typedef uint32_t Elf64_Word; /* Unsigned integer. */ +typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ +typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ +typedef int64_t Elf64_Sxword; /* Signed long integer. */ + + +/* + * Capability descriptors. + */ + +/* 32-bit capability descriptor. */ +typedef struct { + Elf32_Word c_tag; /* Type of entry. */ + union { + Elf32_Word c_val; /* Integer value. */ + Elf32_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf32_Cap; + +/* 64-bit capability descriptor. */ +typedef struct { + Elf64_Xword c_tag; /* Type of entry. */ + union { + Elf64_Xword c_val; /* Integer value. */ + Elf64_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf64_Cap; + +/* + * MIPS .conflict section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Addr c_index; +} Elf32_Conflict; + +/* 64-bit entry. */ +typedef struct { + Elf64_Addr c_index; +} Elf64_Conflict; + +/* + * Dynamic section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Sword d_tag; /* Type of entry. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Pointer value. */ + } d_un; +} Elf32_Dyn; + +/* 64-bit entry. */ +typedef struct { + Elf64_Sxword d_tag; /* Type of entry. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Pointer value; */ + } d_un; +} Elf64_Dyn; + + +/* + * The executable header (EHDR). + */ + +/* 32 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf32_Half e_type; /* Object file type (ET_*). */ + Elf32_Half e_machine; /* Machine type (EM_*). */ + Elf32_Word e_version; /* File format version (EV_*). */ + Elf32_Addr e_entry; /* Start address. */ + Elf32_Off e_phoff; /* File offset to the PHDR table. */ + Elf32_Off e_shoff; /* File offset to the SHDRheader. */ + Elf32_Word e_flags; /* Flags (EF_*). */ + Elf32_Half e_ehsize; /* Elf header size in bytes. */ + Elf32_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf32_Half e_phnum; /* Number of PHDR entries. */ + Elf32_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf32_Half e_shnum; /* Number of SHDR entries. */ + Elf32_Half e_shstrndx; /* Index of section name string table. */ +} Elf32_Ehdr; + + +/* 64 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf64_Half e_type; /* Object file type (ET_*). */ + Elf64_Half e_machine; /* Machine type (EM_*). */ + Elf64_Word e_version; /* File format version (EV_*). */ + Elf64_Addr e_entry; /* Start address. */ + Elf64_Off e_phoff; /* File offset to the PHDR table. */ + Elf64_Off e_shoff; /* File offset to the SHDRheader. */ + Elf64_Word e_flags; /* Flags (EF_*). */ + Elf64_Half e_ehsize; /* Elf header size in bytes. */ + Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf64_Half e_phnum; /* Number of PHDR entries. */ + Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf64_Half e_shnum; /* Number of SHDR entries. */ + Elf64_Half e_shstrndx; /* Index of section name string table. */ +} Elf64_Ehdr; + + +/* + * Shared object information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Word l_name; /* The name of a shared object. */ + Elf32_Word l_time_stamp; /* 32-bit timestamp. */ + Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf32_Word l_version; /* Interface version string index. */ + Elf32_Word l_flags; /* Flags (LL_*). */ +} Elf32_Lib; + +/* 64-bit entry. */ +typedef struct { + Elf64_Word l_name; /* The name of a shared object. */ + Elf64_Word l_time_stamp; /* 32-bit timestamp. */ + Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf64_Word l_version; /* Interface version string index. */ + Elf64_Word l_flags; /* Flags (LL_*). */ +} Elf64_Lib; + + +#define LL_NONE 0 +#define LL_EXACT_MATCH 0x1 +#define LL_IGNORE_INT_VER 0x2 +#define LL_REQUIRE_MINOR 0x4 +#define LL_EXPORTS 0x8 +#define LL_DELAY_LOAD 0x10 +#define LL_DELTA 0x20 + + +/* + * Note tags + */ + +#define NT_ABI_TAG 1 +#define NT_GNU_HWCAP 2 +#define NT_GNU_BUILD_ID 3 +#define NT_GNU_GOLD_VERSION 4 +#define NT_PRSTATUS 1 +#define NT_FPREGSET 2 +#define NT_PRPSINFO 3 +#define NT_AUXV 6 +#define NT_PRXFPREG 0x46E62B7FUL +#define NT_PSTATUS 10 +#define NT_FPREGS 12 +#define NT_PSINFO 13 +#define NT_LWPSTATUS 16 +#define NT_LWPSINFO 17 +#define NT_FREEBSD_NOINIT_TAG 2 +#define NT_FREEBSD_ARCH_TAG 3 +#define NT_FREEBSD_FEATURE_CTL 4 + +/* Aliases for the ABI tag. */ + +#define NT_FREEBSD_ABI_TAG NT_ABI_TAG +#define NT_GNU_ABI_TAG NT_ABI_TAG +#define NT_NETBSD_IDENT NT_ABI_TAG +#define NT_OPENBSD_IDENT NT_ABI_TAG + + +/* + * Note descriptors. + */ + +typedef struct { + uint32_t n_namesz; /* Length of note's name. */ + uint32_t n_descsz; /* Length of note's value. */ + uint32_t n_type; /* Type of note. */ +} Elf_Note; + +typedef Elf_Note Elf32_Nhdr; /* 32-bit note header. */ +typedef Elf_Note Elf64_Nhdr; /* 64-bit note header. */ + +/* + * MIPS ELF options descriptor header. + */ + +typedef struct { + Elf64_Byte kind; /* Type of options. */ + Elf64_Byte size; /* Size of option descriptor. */ + Elf64_Half section; /* Index of section affected. */ + Elf64_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* + * Option kinds. + */ + +#define ODK_NULL 0 +#define ODK_REGINFO 1 +#define ODK_EXCEPTIONS 2 +#define ODK_PAD 3 +#define ODK_HWPATCH 4 +#define ODK_FILL 5 +#define ODK_TAGS 6 +#define ODK_HWAND 7 +#define ODK_HWOR 8 +#define ODK_GP_GROUP 9 +#define ODK_IDENT 10 +#define ODK_PAGESIZE 11 + + +/* + * ODK_EXCEPTIONS info field masks. + */ + +#define OEX_FPU_MIN 0x0000001FUL +#define OEX_FPU_MAX 0x00001F00UL +#define OEX_PAGE0 0x00010000UL +#define OEX_SMM 0x00020000UL +#define OEX_PRECISEFP 0x00040000UL +#define OEX_DISMISS 0x00080000UL + + +/* + * ODK_PAD info field masks. + */ + +#define OPAD_PREFIX 0x0001 +#define OPAD_POSTFIX 0x0002 +#define OPAD_SYMBOL 0x0004 + + +/* + * ODK_HWPATCH info field masks and ODK_HWAND/ODK_HWOR info field + * and hwp_flags[12] masks. + */ + +#define OHW_R4KEOP 0x00000001UL +#define OHW_R8KPFETCH 0x00000002UL +#define OHW_R5KEOP 0x00000004UL +#define OHW_R5KCVTL 0x00000008UL +#define OHW_R10KLDL 0x00000010UL +#define OHWA0_R4KEOP_CHECKED 0x00000001UL +#define OHWA0_R4KEOP_CLEAN 0x00000002UL +#define OHWO0_FIXADE 0x00000001UL + + +/* + * ODK_IDENT/ODK_GP_GROUP info field masks. + */ + +#define OGP_GROUP 0x0000FFFFUL +#define OGP_SELF 0x00010000UL + + +/* + * MIPS ELF register info descriptor. + */ + +/* 32 bit RegInfo entry. */ +typedef struct { + Elf32_Word ri_gprmask; /* Mask of general register used. */ + Elf32_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf32_Addr ri_gp_value; /* GP register value. */ +} Elf32_RegInfo; + +/* 64 bit RegInfo entry. */ +typedef struct { + Elf64_Word ri_gprmask; /* Mask of general register used. */ + Elf64_Word ri_pad; /* Padding. */ + Elf64_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf64_Addr ri_gp_value; /* GP register value. */ +} Elf64_RegInfo; + +/* + * Program Header Table (PHDR) entries. + */ + +/* 32 bit PHDR entry. */ +typedef struct { + Elf32_Word p_type; /* Type of segment. */ + Elf32_Off p_offset; /* File offset to segment. */ + Elf32_Addr p_vaddr; /* Virtual address in memory. */ + Elf32_Addr p_paddr; /* Physical address (if relevant). */ + Elf32_Word p_filesz; /* Size of segment in file. */ + Elf32_Word p_memsz; /* Size of segment in memory. */ + Elf32_Word p_flags; /* Segment flags. */ + Elf32_Word p_align; /* Alignment constraints. */ +} Elf32_Phdr; + +/* 64 bit PHDR entry. */ +typedef struct { + Elf64_Word p_type; /* Type of segment. */ + Elf64_Word p_flags; /* Segment flags. */ + Elf64_Off p_offset; /* File offset to segment. */ + Elf64_Addr p_vaddr; /* Virtual address in memory. */ + Elf64_Addr p_paddr; /* Physical address (if relevant). */ + Elf64_Xword p_filesz; /* Size of segment in file. */ + Elf64_Xword p_memsz; /* Size of segment in memory. */ + Elf64_Xword p_align; /* Alignment constraints. */ +} Elf64_Phdr; + + +/* + * Move entries, for describing data in COMMON blocks in a compact + * manner. + */ + +/* 32-bit move entry. */ +typedef struct { + Elf32_Lword m_value; /* Initialization value. */ + Elf32_Word m_info; /* Encoded size and index. */ + Elf32_Word m_poffset; /* Offset relative to symbol. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Number of units to skip. */ +} Elf32_Move; + +/* 64-bit move entry. */ +typedef struct { + Elf64_Lword m_value; /* Initialization value. */ + Elf64_Xword m_info; /* Encoded size and index. */ + Elf64_Xword m_poffset; /* Offset relative to symbol. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Number of units to skip. */ +} Elf64_Move; + +#define ELF32_M_SYM(I) ((I) >> 8) +#define ELF32_M_SIZE(I) ((unsigned char) (I)) +#define ELF32_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +#define ELF64_M_SYM(I) ((I) >> 8) +#define ELF64_M_SIZE(I) ((unsigned char) (I)) +#define ELF64_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +/* + * Section Header Table (SHDR) entries. + */ + +/* 32 bit SHDR */ +typedef struct { + Elf32_Word sh_name; /* index of section name */ + Elf32_Word sh_type; /* section type */ + Elf32_Word sh_flags; /* section flags */ + Elf32_Addr sh_addr; /* in-memory address of section */ + Elf32_Off sh_offset; /* file offset of section */ + Elf32_Word sh_size; /* section size in bytes */ + Elf32_Word sh_link; /* section header table link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* alignment constraint */ + Elf32_Word sh_entsize; /* size for fixed-size entries */ +} Elf32_Shdr; + +/* 64 bit SHDR */ +typedef struct { + Elf64_Word sh_name; /* index of section name */ + Elf64_Word sh_type; /* section type */ + Elf64_Xword sh_flags; /* section flags */ + Elf64_Addr sh_addr; /* in-memory address of section */ + Elf64_Off sh_offset; /* file offset of section */ + Elf64_Xword sh_size; /* section size in bytes */ + Elf64_Word sh_link; /* section header table link */ + Elf64_Word sh_info; /* extra information */ + Elf64_Xword sh_addralign; /* alignment constraint */ + Elf64_Xword sh_entsize; /* size for fixed-size entries */ +} Elf64_Shdr; + + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* index of symbol's name */ + Elf32_Addr st_value; /* value for the symbol */ + Elf32_Word st_size; /* size of associated data */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf32_Half st_shndx; /* index of related section */ +} Elf32_Sym; + +typedef struct { + Elf64_Word st_name; /* index of symbol's name */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf64_Half st_shndx; /* index of related section */ + Elf64_Addr st_value; /* value for the symbol */ + Elf64_Xword st_size; /* size of associated data */ +} Elf64_Sym; + +#define ELF32_ST_BIND(I) ((I) >> 4) +#define ELF32_ST_TYPE(I) ((I) & 0xFU) +#define ELF32_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF64_ST_BIND(I) ((I) >> 4) +#define ELF64_ST_TYPE(I) ((I) & 0xFU) +#define ELF64_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF32_ST_VISIBILITY(O) ((O) & 0x3) +#define ELF64_ST_VISIBILITY(O) ((O) & 0x3) + +/* + * Syminfo descriptors, containing additional symbol information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Half si_boundto; /* Entry index with additional flags. */ + Elf32_Half si_flags; /* Flags. */ +} Elf32_Syminfo; + +/* 64-bit entry. */ +typedef struct { + Elf64_Half si_boundto; /* Entry index with additional flags. */ + Elf64_Half si_flags; /* Flags. */ +} Elf64_Syminfo; + +/* + * Relocation descriptors. + */ + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ +} Elf32_Rel; + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ + Elf32_Sword r_addend; /* constant addend */ +} Elf32_Rela; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ + Elf64_Sxword r_addend; /* constant addend */ +} Elf64_Rela; + + +#define ELF32_R_SYM(I) ((I) >> 8) +#define ELF32_R_TYPE(I) ((unsigned char) (I)) +#define ELF32_R_INFO(S,T) (((S) << 8) + (unsigned char) (T)) + +#define ELF64_R_SYM(I) ((I) >> 32) +#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL) +#define ELF64_R_INFO(S,T) \ + (((Elf64_Xword) (S) << 32) + ((T) & 0xFFFFFFFFUL)) + +/* + * Symbol versioning structures. + */ + +/* 32-bit structures. */ +typedef struct +{ + Elf32_Word vda_name; /* Index to name. */ + Elf32_Word vda_next; /* Offset to next entry. */ +} Elf32_Verdaux; + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name. */ + Elf32_Half vna_flags; /* Flags. */ + Elf32_Half vna_other; /* Unused. */ + Elf32_Word vna_name; /* Offset to dependency name. */ + Elf32_Word vna_next; /* Offset to next vernaux entry. */ +} Elf32_Vernaux; + +typedef struct +{ + Elf32_Half vd_version; /* Version information. */ + Elf32_Half vd_flags; /* Flags. */ + Elf32_Half vd_ndx; /* Index into the versym section. */ + Elf32_Half vd_cnt; /* Number of aux entries. */ + Elf32_Word vd_hash; /* Hash value of name. */ + Elf32_Word vd_aux; /* Offset to aux entries. */ + Elf32_Word vd_next; /* Offset to next version definition. */ +} Elf32_Verdef; + +typedef struct +{ + Elf32_Half vn_version; /* Version number. */ + Elf32_Half vn_cnt; /* Number of aux entries. */ + Elf32_Word vn_file; /* Offset of associated file name. */ + Elf32_Word vn_aux; /* Offset of vernaux array. */ + Elf32_Word vn_next; /* Offset of next verneed entry. */ +} Elf32_Verneed; + +typedef Elf32_Half Elf32_Versym; + +/* 64-bit structures. */ + +typedef struct { + Elf64_Word vda_name; /* Index to name. */ + Elf64_Word vda_next; /* Offset to next entry. */ +} Elf64_Verdaux; + +typedef struct { + Elf64_Word vna_hash; /* Hash value of dependency name. */ + Elf64_Half vna_flags; /* Flags. */ + Elf64_Half vna_other; /* Unused. */ + Elf64_Word vna_name; /* Offset to dependency name. */ + Elf64_Word vna_next; /* Offset to next vernaux entry. */ +} Elf64_Vernaux; + +typedef struct { + Elf64_Half vd_version; /* Version information. */ + Elf64_Half vd_flags; /* Flags. */ + Elf64_Half vd_ndx; /* Index into the versym section. */ + Elf64_Half vd_cnt; /* Number of aux entries. */ + Elf64_Word vd_hash; /* Hash value of name. */ + Elf64_Word vd_aux; /* Offset to aux entries. */ + Elf64_Word vd_next; /* Offset to next version definition. */ +} Elf64_Verdef; + +typedef struct { + Elf64_Half vn_version; /* Version number. */ + Elf64_Half vn_cnt; /* Number of aux entries. */ + Elf64_Word vn_file; /* Offset of associated file name. */ + Elf64_Word vn_aux; /* Offset of vernaux array. */ + Elf64_Word vn_next; /* Offset of next verneed entry. */ +} Elf64_Verneed; + +typedef Elf64_Half Elf64_Versym; + + +/* + * The header for GNU-style hash sections. + */ + +typedef struct { + uint32_t gh_nbuckets; /* Number of hash buckets. */ + uint32_t gh_symndx; /* First visible symbol in .dynsym. */ + uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ + uint32_t gh_shift2; /* Bloom filter shift count. */ +} Elf_GNU_Hash_Header; + +#endif /* _SYS_ELFDEFINITIONS_H_ */ diff --git a/contrib/elftoolchain/common/sys/elfdefinitions.m4 b/contrib/elftoolchain/common/sys/elfdefinitions.m4 new file mode 100644 index 0000000000..a8a7b03c7e --- /dev/null +++ b/contrib/elftoolchain/common/sys/elfdefinitions.m4 @@ -0,0 +1,718 @@ +/*- + * Copyright (c) 2010,2021 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +divert(-1) +define(`VCSID_ELFDEFINITIONS_M4', + `$Id: elfdefinitions.m4 3984 2022-05-06 11:22:42Z jkoshy $') +include(`elfconstants.m4')dnl + +define(`_',`ifelse(eval(len($1) <= 7),1, + `#define $1 $2', + `#define $1 $2')') +divert(0)dnl + +/* + * WARNING: GENERATED FILE. DO NOT MODIFY. + * + * GENERATED FROM: VCSID_ELFDEFINITIONS_M4 + * GENERATED FROM: VCSID_ELFCONSTANTS_M4 + */ + +/* + * These definitions are based on: + * - The public specification of the ELF format as defined in the + * October 2009 draft of System V ABI. + * See: http://www.sco.com/developers/gabi/latest/ch4.intro.html + * - The May 1998 (version 1.5) draft of "The ELF-64 object format". + * - Processor-specific ELF ABI definitions for sparc, i386, amd64, mips, + * ia64, powerpc, and RISC-V processors. + * - The "Linkers and Libraries Guide", from Sun Microsystems. + */ + +#ifndef _SYS_ELFDEFINITIONS_H_ +#define _SYS_ELFDEFINITIONS_H_ + +/* + * Types of capabilities. + */ +DEFINE_CAPABILITIES() + +/* + * Flags used with dynamic linking entries. + */ +DEFINE_DYN_FLAGS() + +/* + * Dynamic linking entry types. + */ +DEFINE_DYN_TYPES() + +/* Aliases for dynamic linking entry symbols. */ +DEFINE_DYN_TYPE_ALIASES() + +/* + * Flags used in the executable header (field: e_flags). + */ +DEFINE_EHDR_FLAGS() + +/* + * Offsets in the `ei_ident[]' field of an ELF executable header. + */ +DEFINE_EI_OFFSETS() + +/* + * The ELF class of an object. + */ +DEFINE_ELF_CLASSES() + +/* + * Endianness of data in an ELF object. + */ +DEFINE_ELF_DATA_ENDIANNESSES() + +/* + * The magic numbers used in the initial four bytes of an ELF object. + * + * These numbers are: 0x7F, 'E', 'L' and 'F'. + */ +DEFINE_ELF_MAGIC_VALUES() +/* Additional magic-related constants. */ +DEFINE_ELF_MAGIC_ADDITIONAL_CONSTANTS() + +/* + * ELF OS ABI field. + */ +DEFINE_ELF_OSABIS() + +/* OS ABI Aliases. */ +DEFINE_ELF_OSABI_ALIASES() + +/* + * ELF Machine types: (EM_*). + */ +DEFINE_ELF_MACHINE_TYPES() +/* Other synonyms. */ +DEFINE_ELF_MACHINE_TYPE_SYNONYMS() + +/* + * ELF file types: (ET_*). + */ +DEFINE_ELF_TYPES() + +/* ELF file format version numbers. */ +DEFINE_ELF_FILE_VERSIONS() + +/* + * Flags for section groups. + */ +DEFINE_GRP_FLAGS() + +/* + * Flags / mask for .gnu.versym sections. + */ +DEFINE_VERSYMS() + +/* + * Flags used by program header table entries. + */ +DEFINE_PHDR_FLAGS() + +/* + * Types of program header table entries. + */ +DEFINE_PHDR_TYPES() +/* synonyms. */ +DEFINE_PHDR_TYPE_SYNONYMS() + +/* + * Section flags. + */ +DEFINE_SECTION_FLAGS() + +/* + * Special section indices. + */ +DEFINE_SECTION_INDICES() + +/* + * Section types. + */ +DEFINE_SECTION_TYPES() +/* Aliases for section types. */ +DEFINE_SECTION_TYPE_ALIASES() + +#define PN_XNUM 0xFFFFU /* Use extended section numbering. */ + +/* + * Symbol binding information. + */ +DEFINE_SYMBOL_BINDINGS() + +/* + * Symbol types + */ +DEFINE_SYMBOL_TYPES() +/* Additional constants related to symbol types. */ +DEFINE_SYMBOL_TYPES_ADDITIONAL_CONSTANTS() + +/* + * Symbol binding. + */ +DEFINE_SYMBOL_BINDING_KINDS() + +/* + * Symbol visibility. + */ +DEFINE_SYMBOL_VISIBILITIES() + +/* + * Symbol flags. + */ +DEFINE_SYMBOL_FLAGS() + +/* + * Versioning dependencies. + */ +DEFINE_VERSIONING_DEPENDENCIES() + +/* + * Versioning flags. + */ +DEFINE_VERSIONING_FLAGS() + +/* + * Versioning needs + */ +DEFINE_VERSIONING_NEEDS() + +/* + * Versioning numbers. + */ +DEFINE_VERSIONING_NUMBERS() + +/** + ** Relocation types. + **/ +DEFINE_RELOCATIONS() + +/* + * MIPS ABI related. + */ +DEFINE_MIPS_ABIS() + +/** + ** ELF Types. + **/ + +typedef uint32_t Elf32_Addr; /* Program address. */ +typedef uint8_t Elf32_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer. */ +typedef uint32_t Elf32_Off; /* File offset. */ +typedef uint16_t Elf32_Section; /* Section index. */ +typedef int32_t Elf32_Sword; /* Signed integer. */ +typedef uint32_t Elf32_Word; /* Unsigned integer. */ +typedef uint64_t Elf32_Lword; /* Unsigned long integer. */ + +typedef uint64_t Elf64_Addr; /* Program address. */ +typedef uint8_t Elf64_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ +typedef uint64_t Elf64_Off; /* File offset. */ +typedef uint16_t Elf64_Section; /* Section index. */ +typedef int32_t Elf64_Sword; /* Signed integer. */ +typedef uint32_t Elf64_Word; /* Unsigned integer. */ +typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ +typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ +typedef int64_t Elf64_Sxword; /* Signed long integer. */ + + +/* + * Capability descriptors. + */ + +/* 32-bit capability descriptor. */ +typedef struct { + Elf32_Word c_tag; /* Type of entry. */ + union { + Elf32_Word c_val; /* Integer value. */ + Elf32_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf32_Cap; + +/* 64-bit capability descriptor. */ +typedef struct { + Elf64_Xword c_tag; /* Type of entry. */ + union { + Elf64_Xword c_val; /* Integer value. */ + Elf64_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf64_Cap; + +/* + * MIPS .conflict section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Addr c_index; +} Elf32_Conflict; + +/* 64-bit entry. */ +typedef struct { + Elf64_Addr c_index; +} Elf64_Conflict; + +/* + * Dynamic section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Sword d_tag; /* Type of entry. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Pointer value. */ + } d_un; +} Elf32_Dyn; + +/* 64-bit entry. */ +typedef struct { + Elf64_Sxword d_tag; /* Type of entry. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Pointer value; */ + } d_un; +} Elf64_Dyn; + + +/* + * The executable header (EHDR). + */ + +/* 32 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf32_Half e_type; /* Object file type (ET_*). */ + Elf32_Half e_machine; /* Machine type (EM_*). */ + Elf32_Word e_version; /* File format version (EV_*). */ + Elf32_Addr e_entry; /* Start address. */ + Elf32_Off e_phoff; /* File offset to the PHDR table. */ + Elf32_Off e_shoff; /* File offset to the SHDRheader. */ + Elf32_Word e_flags; /* Flags (EF_*). */ + Elf32_Half e_ehsize; /* Elf header size in bytes. */ + Elf32_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf32_Half e_phnum; /* Number of PHDR entries. */ + Elf32_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf32_Half e_shnum; /* Number of SHDR entries. */ + Elf32_Half e_shstrndx; /* Index of section name string table. */ +} Elf32_Ehdr; + + +/* 64 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf64_Half e_type; /* Object file type (ET_*). */ + Elf64_Half e_machine; /* Machine type (EM_*). */ + Elf64_Word e_version; /* File format version (EV_*). */ + Elf64_Addr e_entry; /* Start address. */ + Elf64_Off e_phoff; /* File offset to the PHDR table. */ + Elf64_Off e_shoff; /* File offset to the SHDRheader. */ + Elf64_Word e_flags; /* Flags (EF_*). */ + Elf64_Half e_ehsize; /* Elf header size in bytes. */ + Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf64_Half e_phnum; /* Number of PHDR entries. */ + Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf64_Half e_shnum; /* Number of SHDR entries. */ + Elf64_Half e_shstrndx; /* Index of section name string table. */ +} Elf64_Ehdr; + + +/* + * Shared object information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Word l_name; /* The name of a shared object. */ + Elf32_Word l_time_stamp; /* 32-bit timestamp. */ + Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf32_Word l_version; /* Interface version string index. */ + Elf32_Word l_flags; /* Flags (LL_*). */ +} Elf32_Lib; + +/* 64-bit entry. */ +typedef struct { + Elf64_Word l_name; /* The name of a shared object. */ + Elf64_Word l_time_stamp; /* 32-bit timestamp. */ + Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf64_Word l_version; /* Interface version string index. */ + Elf64_Word l_flags; /* Flags (LL_*). */ +} Elf64_Lib; + +DEFINE_LL_FLAGS() + +/* + * Note tags + */ +DEFINE_NOTE_ENTRY_TYPES() +/* Aliases for the ABI tag. */ +DEFINE_NOTE_ENTRY_ALIASES() + +/* + * Note descriptors. + */ + +typedef struct { + uint32_t n_namesz; /* Length of note's name. */ + uint32_t n_descsz; /* Length of note's value. */ + uint32_t n_type; /* Type of note. */ +} Elf_Note; + +typedef Elf_Note Elf32_Nhdr; /* 32-bit note header. */ +typedef Elf_Note Elf64_Nhdr; /* 64-bit note header. */ + +/* + * MIPS ELF options descriptor header. + */ + +typedef struct { + Elf64_Byte kind; /* Type of options. */ + Elf64_Byte size; /* Size of option descriptor. */ + Elf64_Half section; /* Index of section affected. */ + Elf64_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* + * Option kinds. + */ +DEFINE_OPTION_KINDS() + +/* + * ODK_EXCEPTIONS info field masks. + */ +DEFINE_OPTION_EXCEPTIONS() + +/* + * ODK_PAD info field masks. + */ +DEFINE_OPTION_PADS() + +/* + * ODK_HWPATCH info field masks and ODK_HWAND/ODK_HWOR info field + * and hwp_flags[12] masks. + */ +DEFINE_ODK_HWPATCH_MASKS() + +/* + * ODK_IDENT/ODK_GP_GROUP info field masks. + */ +DEFINE_ODK_GP_MASKS() + +/* + * MIPS ELF register info descriptor. + */ + +/* 32 bit RegInfo entry. */ +typedef struct { + Elf32_Word ri_gprmask; /* Mask of general register used. */ + Elf32_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf32_Addr ri_gp_value; /* GP register value. */ +} Elf32_RegInfo; + +/* 64 bit RegInfo entry. */ +typedef struct { + Elf64_Word ri_gprmask; /* Mask of general register used. */ + Elf64_Word ri_pad; /* Padding. */ + Elf64_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf64_Addr ri_gp_value; /* GP register value. */ +} Elf64_RegInfo; + +/* + * Program Header Table (PHDR) entries. + */ + +/* 32 bit PHDR entry. */ +typedef struct { + Elf32_Word p_type; /* Type of segment. */ + Elf32_Off p_offset; /* File offset to segment. */ + Elf32_Addr p_vaddr; /* Virtual address in memory. */ + Elf32_Addr p_paddr; /* Physical address (if relevant). */ + Elf32_Word p_filesz; /* Size of segment in file. */ + Elf32_Word p_memsz; /* Size of segment in memory. */ + Elf32_Word p_flags; /* Segment flags. */ + Elf32_Word p_align; /* Alignment constraints. */ +} Elf32_Phdr; + +/* 64 bit PHDR entry. */ +typedef struct { + Elf64_Word p_type; /* Type of segment. */ + Elf64_Word p_flags; /* Segment flags. */ + Elf64_Off p_offset; /* File offset to segment. */ + Elf64_Addr p_vaddr; /* Virtual address in memory. */ + Elf64_Addr p_paddr; /* Physical address (if relevant). */ + Elf64_Xword p_filesz; /* Size of segment in file. */ + Elf64_Xword p_memsz; /* Size of segment in memory. */ + Elf64_Xword p_align; /* Alignment constraints. */ +} Elf64_Phdr; + + +/* + * Move entries, for describing data in COMMON blocks in a compact + * manner. + */ + +/* 32-bit move entry. */ +typedef struct { + Elf32_Lword m_value; /* Initialization value. */ + Elf32_Word m_info; /* Encoded size and index. */ + Elf32_Word m_poffset; /* Offset relative to symbol. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Number of units to skip. */ +} Elf32_Move; + +/* 64-bit move entry. */ +typedef struct { + Elf64_Lword m_value; /* Initialization value. */ + Elf64_Xword m_info; /* Encoded size and index. */ + Elf64_Xword m_poffset; /* Offset relative to symbol. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Number of units to skip. */ +} Elf64_Move; + +#define ELF32_M_SYM(I) ((I) >> 8) +#define ELF32_M_SIZE(I) ((unsigned char) (I)) +#define ELF32_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +#define ELF64_M_SYM(I) ((I) >> 8) +#define ELF64_M_SIZE(I) ((unsigned char) (I)) +#define ELF64_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +/* + * Section Header Table (SHDR) entries. + */ + +/* 32 bit SHDR */ +typedef struct { + Elf32_Word sh_name; /* index of section name */ + Elf32_Word sh_type; /* section type */ + Elf32_Word sh_flags; /* section flags */ + Elf32_Addr sh_addr; /* in-memory address of section */ + Elf32_Off sh_offset; /* file offset of section */ + Elf32_Word sh_size; /* section size in bytes */ + Elf32_Word sh_link; /* section header table link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* alignment constraint */ + Elf32_Word sh_entsize; /* size for fixed-size entries */ +} Elf32_Shdr; + +/* 64 bit SHDR */ +typedef struct { + Elf64_Word sh_name; /* index of section name */ + Elf64_Word sh_type; /* section type */ + Elf64_Xword sh_flags; /* section flags */ + Elf64_Addr sh_addr; /* in-memory address of section */ + Elf64_Off sh_offset; /* file offset of section */ + Elf64_Xword sh_size; /* section size in bytes */ + Elf64_Word sh_link; /* section header table link */ + Elf64_Word sh_info; /* extra information */ + Elf64_Xword sh_addralign; /* alignment constraint */ + Elf64_Xword sh_entsize; /* size for fixed-size entries */ +} Elf64_Shdr; + + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* index of symbol's name */ + Elf32_Addr st_value; /* value for the symbol */ + Elf32_Word st_size; /* size of associated data */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf32_Half st_shndx; /* index of related section */ +} Elf32_Sym; + +typedef struct { + Elf64_Word st_name; /* index of symbol's name */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf64_Half st_shndx; /* index of related section */ + Elf64_Addr st_value; /* value for the symbol */ + Elf64_Xword st_size; /* size of associated data */ +} Elf64_Sym; + +#define ELF32_ST_BIND(I) ((I) >> 4) +#define ELF32_ST_TYPE(I) ((I) & 0xFU) +#define ELF32_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF64_ST_BIND(I) ((I) >> 4) +#define ELF64_ST_TYPE(I) ((I) & 0xFU) +#define ELF64_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF32_ST_VISIBILITY(O) ((O) & 0x3) +#define ELF64_ST_VISIBILITY(O) ((O) & 0x3) + +/* + * Syminfo descriptors, containing additional symbol information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Half si_boundto; /* Entry index with additional flags. */ + Elf32_Half si_flags; /* Flags. */ +} Elf32_Syminfo; + +/* 64-bit entry. */ +typedef struct { + Elf64_Half si_boundto; /* Entry index with additional flags. */ + Elf64_Half si_flags; /* Flags. */ +} Elf64_Syminfo; + +/* + * Relocation descriptors. + */ + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ +} Elf32_Rel; + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ + Elf32_Sword r_addend; /* constant addend */ +} Elf32_Rela; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ + Elf64_Sxword r_addend; /* constant addend */ +} Elf64_Rela; + + +#define ELF32_R_SYM(I) ((I) >> 8) +#define ELF32_R_TYPE(I) ((unsigned char) (I)) +#define ELF32_R_INFO(S,T) (((S) << 8) + (unsigned char) (T)) + +#define ELF64_R_SYM(I) ((I) >> 32) +#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL) +#define ELF64_R_INFO(S,T) \ + (((Elf64_Xword) (S) << 32) + ((T) & 0xFFFFFFFFUL)) + +/* + * Symbol versioning structures. + */ + +/* 32-bit structures. */ +typedef struct +{ + Elf32_Word vda_name; /* Index to name. */ + Elf32_Word vda_next; /* Offset to next entry. */ +} Elf32_Verdaux; + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name. */ + Elf32_Half vna_flags; /* Flags. */ + Elf32_Half vna_other; /* Unused. */ + Elf32_Word vna_name; /* Offset to dependency name. */ + Elf32_Word vna_next; /* Offset to next vernaux entry. */ +} Elf32_Vernaux; + +typedef struct +{ + Elf32_Half vd_version; /* Version information. */ + Elf32_Half vd_flags; /* Flags. */ + Elf32_Half vd_ndx; /* Index into the versym section. */ + Elf32_Half vd_cnt; /* Number of aux entries. */ + Elf32_Word vd_hash; /* Hash value of name. */ + Elf32_Word vd_aux; /* Offset to aux entries. */ + Elf32_Word vd_next; /* Offset to next version definition. */ +} Elf32_Verdef; + +typedef struct +{ + Elf32_Half vn_version; /* Version number. */ + Elf32_Half vn_cnt; /* Number of aux entries. */ + Elf32_Word vn_file; /* Offset of associated file name. */ + Elf32_Word vn_aux; /* Offset of vernaux array. */ + Elf32_Word vn_next; /* Offset of next verneed entry. */ +} Elf32_Verneed; + +typedef Elf32_Half Elf32_Versym; + +/* 64-bit structures. */ + +typedef struct { + Elf64_Word vda_name; /* Index to name. */ + Elf64_Word vda_next; /* Offset to next entry. */ +} Elf64_Verdaux; + +typedef struct { + Elf64_Word vna_hash; /* Hash value of dependency name. */ + Elf64_Half vna_flags; /* Flags. */ + Elf64_Half vna_other; /* Unused. */ + Elf64_Word vna_name; /* Offset to dependency name. */ + Elf64_Word vna_next; /* Offset to next vernaux entry. */ +} Elf64_Vernaux; + +typedef struct { + Elf64_Half vd_version; /* Version information. */ + Elf64_Half vd_flags; /* Flags. */ + Elf64_Half vd_ndx; /* Index into the versym section. */ + Elf64_Half vd_cnt; /* Number of aux entries. */ + Elf64_Word vd_hash; /* Hash value of name. */ + Elf64_Word vd_aux; /* Offset to aux entries. */ + Elf64_Word vd_next; /* Offset to next version definition. */ +} Elf64_Verdef; + +typedef struct { + Elf64_Half vn_version; /* Version number. */ + Elf64_Half vn_cnt; /* Number of aux entries. */ + Elf64_Word vn_file; /* Offset of associated file name. */ + Elf64_Word vn_aux; /* Offset of vernaux array. */ + Elf64_Word vn_next; /* Offset of next verneed entry. */ +} Elf64_Verneed; + +typedef Elf64_Half Elf64_Versym; + + +/* + * The header for GNU-style hash sections. + */ + +typedef struct { + uint32_t gh_nbuckets; /* Number of hash buckets. */ + uint32_t gh_symndx; /* First visible symbol in .dynsym. */ + uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ + uint32_t gh_shift2; /* Bloom filter shift count. */ +} Elf_GNU_Hash_Header; + +#endif /* _SYS_ELFDEFINITIONS_H_ */ diff --git a/contrib/elftoolchain/common/utarray.h b/contrib/elftoolchain/common/utarray.h new file mode 100644 index 0000000000..5ecb24d1c1 --- /dev/null +++ b/contrib/elftoolchain/common/utarray.h @@ -0,0 +1,248 @@ +/*- +Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* a dynamic array implementation using macros + */ +#ifndef UTARRAY_H +#define UTARRAY_H + +#define UTARRAY_VERSION 2.3.0 + +#include /* size_t */ +#include /* memset, etc */ +#include /* exit */ + +#ifdef __GNUC__ +#define UTARRAY_UNUSED __attribute__((__unused__)) +#else +#define UTARRAY_UNUSED +#endif + +#ifdef oom +#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code." +#define utarray_oom() oom() +#endif + +#ifndef utarray_oom +#define utarray_oom() exit(-1) +#endif + +typedef void (ctor_f)(void *dst, const void *src); +typedef void (dtor_f)(void *elt); +typedef void (init_f)(void *elt); +typedef struct { + size_t sz; + init_f *init; + ctor_f *copy; + dtor_f *dtor; +} UT_icd; + +typedef struct { + unsigned i,n;/* i: index of next available slot, n: num slots */ + UT_icd icd; /* initializer, copy and destructor functions */ + char *d; /* n slots of size icd->sz*/ +} UT_array; + +#define utarray_init(a,_icd) do { \ + memset(a,0,sizeof(UT_array)); \ + (a)->icd = *(_icd); \ +} while(0) + +#define utarray_done(a) do { \ + if ((a)->n) { \ + if ((a)->icd.dtor) { \ + unsigned _ut_i; \ + for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ + } \ + } \ + free((a)->d); \ + } \ + (a)->n=0; \ +} while(0) + +#define utarray_new(a,_icd) do { \ + (a) = (UT_array*)malloc(sizeof(UT_array)); \ + if ((a) == NULL) { \ + utarray_oom(); \ + } \ + utarray_init(a,_icd); \ +} while(0) + +#define utarray_free(a) do { \ + utarray_done(a); \ + free(a); \ +} while(0) + +#define utarray_reserve(a,by) do { \ + if (((a)->i+(by)) > (a)->n) { \ + char *utarray_tmp; \ + while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ + utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \ + if (utarray_tmp == NULL) { \ + utarray_oom(); \ + } \ + (a)->d=utarray_tmp; \ + } \ +} while(0) + +#define utarray_push_back(a,p) do { \ + utarray_reserve(a,1); \ + if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \ + else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \ +} while(0) + +#define utarray_pop_back(a) do { \ + if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \ + else { (a)->i--; } \ +} while(0) + +#define utarray_extend_back(a) do { \ + utarray_reserve(a,1); \ + if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \ + else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \ + (a)->i++; \ +} while(0) + +#define utarray_len(a) ((a)->i) + +#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) +#define _utarray_eltptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j)))) + +#define utarray_insert(a,p,j) do { \ + if ((j) > (a)->i) utarray_resize(a,j); \ + utarray_reserve(a,1); \ + if ((j) < (a)->i) { \ + memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ + ((a)->i - (j))*((a)->icd.sz)); \ + } \ + if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \ + else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \ + (a)->i++; \ +} while(0) + +#define utarray_inserta(a,w,j) do { \ + if (utarray_len(w) == 0) break; \ + if ((j) > (a)->i) utarray_resize(a,j); \ + utarray_reserve(a,utarray_len(w)); \ + if ((j) < (a)->i) { \ + memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ + _utarray_eltptr(a,j), \ + ((a)->i - (j))*((a)->icd.sz)); \ + } \ + if ((a)->icd.copy) { \ + unsigned _ut_i; \ + for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ + (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \ + } \ + } else { \ + memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ + utarray_len(w)*((a)->icd.sz)); \ + } \ + (a)->i += utarray_len(w); \ +} while(0) + +#define utarray_resize(dst,num) do { \ + unsigned _ut_i; \ + if ((dst)->i > (unsigned)(num)) { \ + if ((dst)->icd.dtor) { \ + for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ + (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ + } \ + } \ + } else if ((dst)->i < (unsigned)(num)) { \ + utarray_reserve(dst, (num) - (dst)->i); \ + if ((dst)->icd.init) { \ + for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ + (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ + } \ + } else { \ + memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \ + } \ + } \ + (dst)->i = (num); \ +} while(0) + +#define utarray_concat(dst,src) do { \ + utarray_inserta(dst, src, utarray_len(dst)); \ +} while(0) + +#define utarray_erase(a,pos,len) do { \ + if ((a)->icd.dtor) { \ + unsigned _ut_i; \ + for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ + } \ + } \ + if ((a)->i > ((pos) + (len))) { \ + memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ + ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ + } \ + (a)->i -= (len); \ +} while(0) + +#define utarray_renew(a,u) do { \ + if (a) utarray_clear(a); \ + else utarray_new(a, u); \ +} while(0) + +#define utarray_clear(a) do { \ + if ((a)->i > 0) { \ + if ((a)->icd.dtor) { \ + unsigned _ut_i; \ + for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ + (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ + } \ + } \ + (a)->i = 0; \ + } \ +} while(0) + +#define utarray_sort(a,cmp) do { \ + qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ +} while(0) + +#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) + +#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) +#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((a)->i != utarray_eltidx(a,e)+1) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) +#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) != 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) +#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) +#define utarray_eltidx(a,e) (((char*)(e) - (a)->d) / (a)->icd.sz) + +/* last we pre-define a few icd for common utarrays of ints and strings */ +static void utarray_str_cpy(void *dst, const void *src) { + char *const *srcc = (char *const *)src; + char **dstc = (char**)dst; + *dstc = (*srcc == NULL) ? NULL : strdup(*srcc); +} +static void utarray_str_dtor(void *elt) { + char **eltc = (char**)elt; + if (*eltc != NULL) free(*eltc); +} +static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; +static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL}; +static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL}; + + +#endif /* UTARRAY_H */ diff --git a/contrib/elftoolchain/common/uthash.h b/contrib/elftoolchain/common/uthash.h new file mode 100644 index 0000000000..fec6aea267 --- /dev/null +++ b/contrib/elftoolchain/common/uthash.h @@ -0,0 +1,1136 @@ +/*- +Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.3.0 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT +/* This codepath is provided for backward compatibility, but I plan to remove it. */ +#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead" +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT +#else +#include /* uint8_t, uint32_t */ +#endif + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifndef HASH_FUNCTION +#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv) +#endif + +#ifndef HASH_KEYCMP +#define HASH_KEYCMP(a,b,n) memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +#ifndef HASH_NONFATAL_OOM +#define HASH_NONFATAL_OOM 0 +#endif + +#if HASH_NONFATAL_OOM +/* malloc failures can be recovered from */ + +#ifndef uthash_nonfatal_oom +#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) +#define IF_HASH_NONFATAL_OOM(x) x + +#else +/* malloc failures result in lost memory, hash tables are unusable */ + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") +#define IF_HASH_NONFATAL_OOM(x) + +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ + unsigned _hd_bkt; \ + HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + (head)->hh.tbl->buckets[_hd_bkt].count++; \ + _hd_hh_item->hh_next = NULL; \ + _hd_hh_item->hh_prev = NULL; \ +} while (0) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FUNCTION(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl,oomed) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ + } \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl,oomed) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head,oomed) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ + if (!(head)->hh.tbl->buckets) { \ + HASH_RECORD_OOM(oomed); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } else { \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + uthash_free((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } \ + ) \ + } \ + } \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#if HASH_NONFATAL_OOM + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + if (!(oomed)) { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + if (oomed) { \ + HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ + HASH_DELETE_HH(hh, head, &(add)->hh); \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } else { \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + } \ + } else { \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } \ +} while (0) + +#else + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ +} while (0) + +#endif + + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (const void*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ +} while (0) + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ +do { \ + unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ + HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ +} while (0) +#define HASH_ADD_STR(head,strfield,add) \ +do { \ + unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ +} while (0) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ +do { \ + unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ +} while (0) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#include /* fprintf, stderr */ +#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \ + default: ; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + break; \ + default: ; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + HASH_DEL_IN_BKT(head,addhh); \ + } \ + ) \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ + if (!_he_new_buckets) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero(_he_new_buckets, \ + sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ + _he_newbkt->expand_mult++; \ + } \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ + } \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ + _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + uthash_nonfatal_oom(_elt); \ + (dst) = NULL; \ + continue; \ + } \ + ) \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ + (dst)->hh_dst.tbl->num_items++; \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ + HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ + _dst_hh->tbl = NULL; \ + uthash_nonfatal_oom(_elt); \ + continue; \ + } \ + ) \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + const void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/contrib/elftoolchain/cxxfilt/Makefile b/contrib/elftoolchain/cxxfilt/Makefile new file mode 100644 index 0000000000..ca50f91fac --- /dev/null +++ b/contrib/elftoolchain/cxxfilt/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile 2066 2011-10-26 15:40:28Z jkoshy $ + +TOP= .. + +PROG= c++filt +SRCS= cxxfilt.c + +WARNS?= 6 + +DPADD= ${LIBELFTC} ${LIBELF} +LDADD= -lelftc -lelf + +MAN1= c++filt.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/cxxfilt/c++filt.1 b/contrib/elftoolchain/cxxfilt/c++filt.1 new file mode 100644 index 0000000000..a473bc38e5 --- /dev/null +++ b/contrib/elftoolchain/cxxfilt/c++filt.1 @@ -0,0 +1,109 @@ +.\" Copyright (c) 2009-2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: c++filt.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd August 24, 2011 +.Dt C++FILT 1 +.Os +.Sh NAME +.Nm c++filt +.Nd decode C++ symbols +.Sh SYNOPSIS +.Nm +.Op Fl -help +.Op Fl _ | Fl -strip-underscores +.Op Fl n | Fl -no-strip-underscores +.Op Fl p | Fl -no-params +.Op Fl s Ar scheme | Fl -format Ns = Ns Ar scheme +.Op Fl V | Fl -version +.Op Ar encoded-names ... +.Sh DESCRIPTION +The +.Nm +utility translates encoded C++ symbol names to human-readable form. +.Pp +The +.Nm +utility has two operating modes. +.Bl -bullet +.It +If arguments +.Ar encoded-names +are not specified, then +.Nm +will act as a filter, reading from standard input +and writing to standard output. +.It +If arguments +.Ar encoded-names +are specified, then +.Nm +will decode each such argument in turn, writing its decoded form +to standard output. +.El +.Pp +The +.Nm +utility recognizes the following options: +.Bl -tag -width indent +.It Fl -help +Print a help message and exit. +.It Fl _ | Fl -strip-underscores +Remove a leading underscore from symbol names prior to decoding them. +.It Fl n | Fl -no-strip-underscores +Do not remove leading underscores from names. +.It Fl p | Fl -no-params +This option is recognized but ignored. +.It Fl s Ar scheme | Fl -format Ns = Ns Ar scheme +Select the encoding scheme to use. +Argument +.Ar scheme +can be one of the following: +.Bl -tag -width "gnu-v5" +.It Ar arm +Use the encoding scheme specified by the C++ Annotated Reference Manual. +.It Ar auto +Guess the encoding scheme from the input. +.It Ar gnu +Use the encoding scheme used by the GNU C++ compiler. +.It Ar gnu-v3 +Use the encoding scheme used by the GNU C++ compiler, version 3. +.El +.It Fl V | Fl -version +Print a version identifier for +.Nm +and exit. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr nm 1 , +.Xr strip 1 , +.Xr elftc_demangle 3 +.Sh AUTHORS +The +.Nm +utility was written by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/cxxfilt/cxxfilt.c b/contrib/elftoolchain/cxxfilt/cxxfilt.c new file mode 100644 index 0000000000..e1d8db3ac7 --- /dev/null +++ b/contrib/elftoolchain/cxxfilt/cxxfilt.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: cxxfilt.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +#define STRBUFSZ 8192 + +static int stripus = 0; +static int noparam = 0; +static int format = 0; + +enum options +{ + OPTION_HELP, + OPTION_VERSION +}; + +static struct option longopts[] = +{ + {"format", required_argument, NULL, 's'}, + {"help", no_argument, NULL, OPTION_HELP}, + {"no-params", no_argument, NULL, 'p'}, + {"no-strip-underscores", no_argument, NULL, 'n'}, + {"strip-underscores", no_argument, NULL, '_'}, + {"version", no_argument, NULL, 'V'}, + {NULL, 0, NULL, 0} +}; + +static struct { + const char *fname; + int fvalue; +} flist[] = { + {"auto", 0}, + {"arm", ELFTC_DEM_ARM}, + {"gnu", ELFTC_DEM_GNU2}, + {"gnu-v3", ELFTC_DEM_GNU3} +}; + +#define USAGE_MESSAGE "\ +Usage: %s [options] [encoded-names...]\n\ + Translate C++ symbol names to human-readable form.\n\n\ + Options:\n\ + -_ | --strip-underscores Remove leading underscores prior to decoding.\n\ + -n | --no-strip-underscores Do not remove leading underscores.\n\ + -p | --no-params (Accepted but ignored).\n\ + -s SCHEME | --format=SCHEME Select the encoding scheme to use.\n\ + Valid schemes are: 'arm', 'auto', 'gnu' and\n\ + 'gnu-v3'.\n\ + --help Print a help message.\n\ + --version Print a version identifier and exit.\n" + +static void +usage(int exit_code) +{ + + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +version(void) +{ + fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(0); +} + +static int +find_format(const char *fstr) +{ + int i; + + for (i = 0; (size_t) i < sizeof(flist) / sizeof(flist[0]); i++) { + if (!strcmp(fstr, flist[i].fname)) + return (flist[i].fvalue); + } + + return (-1); +} + +static char * +demangle(char *name) +{ + static char dem[STRBUFSZ]; + + if (stripus && *name == '_') + name++; + + if (strlen(name) == 0) + return (NULL); + + if (elftc_demangle(name, dem, sizeof(dem), (unsigned) format) < 0) + return (NULL); + + return (dem); +} + +int +main(int argc, char **argv) +{ + char *dem, buf[STRBUFSZ]; + size_t p; + int c, n, opt; + + while ((opt = getopt_long(argc, argv, "_nps:V", longopts, NULL)) != + -1) { + switch (opt) { + case '_': + stripus = 1; + break; + case 'n': + stripus = 0; + break; + case 'p': + noparam = 1; + break; + case 's': + if ((format = find_format(optarg)) < 0) + errx(EXIT_FAILURE, "unsupported format: %s", + optarg); + break; + case 'V': + version(); + break; + case OPTION_HELP: + usage(EX_OK); + break; + default: + usage(EX_USAGE); + break; + } + } + + argv += optind; + argc -= optind; + + if (*argv != NULL) { + for (n = 0; n < argc; n++) { + if ((dem = demangle(argv[n])) == NULL) + printf("%s\n", argv[n]); + else + printf("%s\n", dem); + } + } else { + p = 0; + for (;;) { + setvbuf(stdout, NULL, _IOLBF, 0); + c = fgetc(stdin); + if (c == EOF || !(isalnum(c) || strchr(".$_", c))) { + if (p > 0) { + buf[p] = '\0'; + if ((dem = demangle(buf)) == NULL) + printf("%s", buf); + else + printf("%s", dem); + p = 0; + } + if (c == EOF) + break; + putchar(c); + } else { + if ((size_t) p >= sizeof(buf) - 1) + warnx("buffer overflowed"); + else + buf[p++] = (char) c; + } + + } + } + + exit(0); +} diff --git a/contrib/elftoolchain/documentation/Makefile b/contrib/elftoolchain/documentation/Makefile new file mode 100644 index 0000000000..026ab6d66e --- /dev/null +++ b/contrib/elftoolchain/documentation/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 2139 2011-11-10 14:23:13Z jkoshy $ + +TOP= .. + +SUBDIR= libelf-by-example + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/documentation/libelf-by-example/Makefile b/contrib/elftoolchain/documentation/libelf-by-example/Makefile new file mode 100644 index 0000000000..9257f36028 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/Makefile @@ -0,0 +1,41 @@ +# +# Libelf by Example +# +# $Id: Makefile 3844 2020-03-19 20:43:16Z jkoshy $ + +TOP = ../.. + +DOC= libelf-by-example + +SRCS= libelf-by-example.tex prog1.txt prog2.txt prog3.txt \ + prog4.txt prog5.txt prog6.txt +COVER_SRCS= title-page-content.tex +GENERATED_VERSION_TEX= version.tex + +CLEANFILES+= ${SRCS:Mprog*:S/.txt/.c/} + +.include "${TOP}/mk/elftoolchain.tex.mk" + +.if ${OS_HOST} == "Linux" +EXTRA_FLAGS= -I/usr/include/bsd -DLIBBSD_OVERLAY +EXTRA_LIBS= -lbsd +.endif + +check-example-syntax: .PHONY +.for f in ${SRCS:Mprog*:S/.txt//} + @sed -e 's/@[^@]*@//' \ + ${.CURDIR}/${f}.txt > ${.OBJDIR}/${f}.c; \ + echo -n ${f} ' '; \ + libelf="${.OBJDIR}/${TOP}/libelf"; \ + if [ ! -d $${libelf} -a "${.CURDIR}" != "${.OBJDIR}" ]; then \ + suffix="${.OBJDIR:S,${.CURDIR}/,,}"; \ + libelf="${.CURDIR}/${TOP}/libelf/$${suffix}"; \ + fi; \ + cc -I${.CURDIR}/${TOP}/common \ + -I${.CURDIR}/${TOP}/libelf \ + ${EXTRA_FLAGS} \ + ${.OBJDIR}/${f}.c \ + -L"$${libelf}" -lelf ${EXTRA_LIBS} && \ + rm ${.OBJDIR}/a.out +.endfor + @echo diff --git a/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.cover.tex b/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.cover.tex new file mode 100644 index 0000000000..b1d159cc61 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.cover.tex @@ -0,0 +1,7 @@ +% This LaTeX document generates a single page of output containing the cover +% page for the "libelf by Example" tutorial. +\documentclass[letterpaper]{article} +\usepackage{lmodern} +\begin{document} +\include{title-page-content} +\end{document} diff --git a/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.tex b/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.tex new file mode 100644 index 0000000000..991952d1e7 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/libelf-by-example.tex @@ -0,0 +1,2917 @@ +% +% Libelf by Example +% +% Copyright (c) 2006-2020 Joseph Koshy. All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% 1. Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% 2. Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in the +% documentation and/or other materials provided with the distribution. +% +% This software is provided by Joseph Koshy ``as is'' and +% any express or implied warranties, including, but not limited to, the +% implied warranties of merchantability and fitness for a particular purpose +% are disclaimed. in no event shall Joseph Koshy be liable +% for any direct, indirect, incidental, special, exemplary, or consequential +% damages (including, but not limited to, procurement of substitute goods +% or services; loss of use, data, or profits; or business interruption) +% however caused and on any theory of liability, whether in contract, strict +% liability, or tort (including negligence or otherwise) arising in any way +% out of the use of this software, even if advised of the possibility of +% such damage. +% +% $Id: libelf-by-example.tex 3854 2020-03-30 18:45:59Z jkoshy $ +% +\documentclass[a4paper,pdftex]{book} + +\usepackage{array} +\usepackage{color} +\usepackage{comment} +\usepackage{fancybox} +\usepackage{float} +\usepackage{graphicx} +\usepackage{listings} +\usepackage{lmodern} +\usepackage{makeidx} +\usepackage{tikz} +\usepackage{varioref} +\usepackage{xspace} + +\usepackage[colorlinks=true,linkcolor=blue]{hyperref} + +% TikZ configuration. +\usetikzlibrary{arrows,calc,chains,mindmap,positioning,shapes.multipart} +\tikzset{every picture/.style={ + >=latex' % LaTeX style arrows. + } +} + +% Document-specific LaTeX commands. +\makeatletter +\newcommand{\code}[1]{\texttt{#1}} +\newcommand{\constant}[1]{\texttt{#1}\index{#1@\texttt{#1}}} +\newcommand{\elftoolchainproject}{\href{https://elftoolchain.sourceforge.io/}% + {ElfToolChain Project}\xspace}% +\newcommand{\function}[1]{\texttt{#1}\index{#1@\texttt{#1}}}% +\newcommand{\filename}[1]{\texttt{#1}} +\newcommand{\firstterm}[1]{\textit{#1}} +\newcommand{\library}[1]{\texttt{#1}} +\newcommand{\parameter}[1]{\texttt{#1}\index{#1@\texttt{#1}}} +\newcommand{\reg}{\raisebox{0.7ex}{\small\textregistered}\xspace} +\newcommand{\tableheader}[1]{\small\textbf{#1}} +\newcommand{\tool}[1]{\textbf{#1}} +\newcommand{\trade}{{\small\texttrademark}\xspace} +\newcommand{\type}[1]{\texttt{#1}\index{#1@\texttt{#1}}} +\newcommand{\elfdatastructure}[1]{\textsf{#1}} + +% Define a new environment "callout" that groups a listing and a +% description list together. Inside this environment the "\co" +% command may be used to denote a callout location; a corresponding +% "\coref" command may be used at the place in the text that +% references the callout and the two locations will be cross-linked in +% the PDF file generated. +% +% Usage: +% +% \begin{callout}[color]{UNIQUE-TOKEN} +% ... \co{M} ... +% \begin{lstlisting}[escapechar=@] +% ... @\co{N}@ +% \end{lstlisting} +% \begin{description} +% \item[\coref{M}] ... description ... +% \item[\coref{N}] ... description ... +% \end{description} +% \end{callout} +% +% In the typeset text `M' and `N' are made (PDF) targets and rendered +% in a visually distinct way. `UNIQUE-TOKEN' is used to disambiguate +% between different callout environments in the same text. `color' +% defaults to blue. +\newenvironment{callout}[2][black]{% + \begingroup\newcommand{\@cocolor}{#1}% + \setlength{\shadowsize}{1.2pt}% + \newcommand{\@cogroup}[1]{#2}}{\endgroup} +\newcommand{\@co}[1]{\shadowbox{\color{\@cocolor}#1}} +\newcommand{\co}[1]{% + \hypertarget{\@cogroup.#1.co}{% + \hyperlink{\@cogroup.#1.cr}{\@co{#1}}}} +\newcommand{\coref}[1]{% + \hypertarget{\@cogroup.#1.cr}{% + \hyperlink{\@cogroup.#1.co}{\@co{#1}}}} + +% Add meta-data to the PDF file. +\hypersetup{ + pdftitle={libelf by Example}, + pdfauthor={Joseph Koshy}, + pdfsubject={Handling ELF objects with libelf}, + pdfkeywords={ar archive % + ELF "ELF sections" % + GELF % + loading libelf linker % + programming % + "shared library" "shared objects"} +} +\makeatother + +\makeindex + +\begin{document} +\lstset{language=C,basicstyle=\small\ttfamily,escapechar=@,float} + +% Import the title page. +\begin{titlepage} +\include{title-page-content} +\end{titlepage} + +\setcounter{tocdepth}{1} +\tableofcontents + +\chapter*{Preface} + +This tutorial introduces the \library{libelf} library being developed +at the \elftoolchainproject on +\href{https://sourceforge.net/}{SourceForge.Net}. It uses simple +example programs to show how to create ELF processing tools using the +\library{libelf} library. Along the way the tutorial covers the ELF +file format to the extent needed to understand the example programs +being discussed. + +This tutorial would be of interest to software developers who wish to +write software that processes ELF files. + +The tutorial's example programs are written using the C programming +language. They should compile out of the box on +FreeBSD\makebox[0pt]{,}\trade NetBSD\reg and other BSD-family +operating systems. They should also compile on Debian GNU/Linux\reg +with the \filename{libbsd-dev} package installed. + +\section*{Legal Notice} + +% Adapted from https://brlcad.org/wiki/BSD_Documentation_License. + +Copyright \copyright{} 2006--2020 Joseph Koshy. All rights reserved. + +\vskip.8\baselineskip + +Redistribution and use in source (\LaTeX\ format) and ``compiled'' +forms (EPUB, HTML, PDF, Postscript, RTF, etc), with or without +modification, are permitted provided that the following conditions are +met: + +\begin{itemize} +\item Redistributions of source code (\LaTeX\ format) must retain the + above copyright notice, this list of conditions and the following + disclaimer. +\item Redistributions in compiled form (transformed to other + documentation formats, converted to EPUB, HTML, PDF, Postscript, + RTF, etc) must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. +\item The names of the author and contributors may not be used to + endorse or promote products derived from this documentation without + specific prior written permission. +\end{itemize} + +THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR AND CON\-TRIBUTORS +``\hskip-0.5ex{}AS~IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MER\-CHANT\-ABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CON\-TRIBUTORS BE LIABLE +FOR ANY DIRECT, IN\-DIRECT, INCIDENT\-AL, SPECIAL, EX\-EMPLARY, OR +CON\-SEQUENT\-IAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PRO\-CURE\-MENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHE\-THER IN CONTRACT, STRICT LIA\-BILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHER\-WISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +\vskip.8\baselineskip + +Many of the designations used by manufacturers and sellers to +distinguish their products are claimed as trademarks. Where those +designations appear in this document, and the author and contributors +were aware of the trademark claim, the designations have been followed +by the ``\raisebox{-.5ex}{\texttrademark}'' or the ``\textregistered'' symbol. + +\section*{Document Identifier} + +You are reading the following version of this tutorial: + +\begin{quote} +\texttt{\input{version}\unskip} +\end{quote} + +\section*{Acknowledgements} + +The following people (names in alphabetical order) offered +constructive criticism of this tutorial: Cherry George Mathew, Douglas +Fraser, Hyogeol Lee, Kai Wang, Prashanth Chandra, Ricardo Nabinger +Sanchez, Sam Arun Raj, Wei-Jen Chen and Y.~Giridhar Appaji Nag. Thank +you, all. + +\chapter{Introduction} + +ELF \index{ELF} stands for Extensible Linking Format. +It is a file format used by compilers, linkers, loaders and other +tools that manipulate object code. + +The ELF specification was released to the public in +1990\index{ELF!history~of} by a group of vendors as an +``\href{https://refspecs.linuxbase.org/elf/elf.pdf}{open + standard}''. ELF has been widely adopted by industry and by the +open-source community on account of its availability and modern +features. The ELF standard supports big and little-endian machine +architectures with 32-bit and 64-bit word widths. It supports +cross-compilation, the use of dynamic shared libraries, and the +special compilation needs of the C++ language.\index{ELF!features} + +Among the open-source operating systems\index{ELF!in~open-source}, the +RedHat\trade RHL 2.0 Beta release (late summer 1995) and the Slackware +v3.0 (November 1995) release were among the first Linux\reg-based +operating systems to use ELF. The first ELF based release for +NetBSD\reg was for the DEC Alpha\trade architecture, in release 1.3 +(January 1998). FreeBSD\trade switched to using ELF as its object +format in FreeBSD 3.0 (October 1998). + +The \library{libelf} library implements a large set of APIs, known as +the ELF(3) \& GELF(3) APIs.\index{libelf@\texttt{libelf}!API} +These APIs allow you to write software that can run on one kind of +machine architecture, while manipulating ELF objects meant for +another. + +There are multiple implementations of the ELF(3)/GELF(3) API set in +the open-source world. This tutorial is based on the \library{libelf} +library being developed as part of the \elftoolchainproject on +\href{https://sourceforge.net/}{SourceForge.Net}. + +The ELF(3)/GELF(3) API set contains over 80 callable functions, and +can be daunting to learn. This tutorial offers a gentle introduction +to this API set. + +\section{What to Expect From This Tutorial} + +This tutorial looks at a series of simple but complete programs, with +each program illustrating a different aspect of the ELF format and the +\library{libelf} library's APIs. Along the way, it introduces the +concepts and data structures needed to understand these example +programs. + +Chapter \ref{chap.getting-started} covers getting started with the +\library{libelf} library. This chapter looks at how to compile and +link an application that uses the library, how to establish a working +ELF version number, how to obtain a handle to a ELF object, and how to +handle errors reported by the \library{libelf} library. + +Chapter \ref{chap.peering-inside} looks at how ELF executables, +relocatable objects and shared objects are laid out. This chapter +describes how the ELF data structure known as the +\elfdatastructure{Executable Header}\index{executable~header} +specifies the layout of the rest of the file. The chapter introduces +the notions of the ``file representation''\index{file~representation} +and ``memory representation''\index{memory~representation} of ELF data +types, and explains how the \library{libelf} library enables programs +to work on ELF objects whose word size and endianness differ from +their ``native'' size and endianness. The example program in this +chapter displays the contents of the ELF +\elfdatastructure{Executable~Header}\index{executable~header} for an +ELF object. + +Chapter \ref{chap.elf-phdr} studies ELF segments, and how these +segments are described by entries in the ELF +\elfdatastructure{Prog\-ram Head\-er + Table}.\index{program~header~table} The example program in this +chapter reads and displays the program header table entries in an ELF +executable. + +Chapter \ref{chap.elf-sections} looks at how data is stored in ELF +sections. It looks at how ELF sections are described by the ELF +\elfdatastructure{Section Header Table},\index{section~header~table} +and how ELF string tables (a special kind of ELF section) are +structured. The example program in this chapter traverses an ELF +object, printing out the names of its sections. + +Chapter \ref{chap.creating-elf} demonstrates how to create new ELF +objects using the \library{libelf} library. This chapter covers the +correct ordering of calls to \library{libelf}'s functions when +creating ELF objects, the default layout used by the library, and the +facilities offered by \library{libelf} for creating ELF objects with +custom layouts. The example program in this chapter creates a new ELF +object from scratch. + +The tutorial then moves on to \tool{ar} +archives. Chapter~\ref{chap.ar} looks at the structure of \tool{ar} +archives and covers \library{libelf}'s facilities for reading these +archives. The example program in this chapter lists the names of the +files present in an \tool{ar} archive. + +Finally, chapter \ref{chap.conclusion} concludes the tutorial with +suggestions for further reading. + +Figure~\vref{fig.concept.map} offers a graphical overview of the +concepts covered by this tutorial. + +\begin{figure} +\begin{tikzpicture}[mindmap,concept color=orange!25] + \node[concept] {Programming with \texttt{libelf}} + [clockwise from=60] + child { + node[concept] {The ELF(3) \& GELF(3) APIs} + [clockwise from=180] + child { node[concept] { library data types } } + child { node[concept] { memory \& file representations } } + child { node[concept] { ordering of calls } } + child { node[concept] { memory management } } + child { node[concept] { extended numbering } } + } + child[level distance=5.5cm] { + node[concept] {Basic concepts} + [clockwise from=60] + child { node[concept] { ELF version, class, byte order } } + child[grow=-60] { + node[concept] {object layout} + [clockwise from=-90] + child { node[concept] { Executable header } } + child { node[concept] (shdr) { Section Headers } } + child { node[concept] (phdr) { Program Headers } } + } + } + child { + node[concept] (elfseg) {ELF Segments} + [clockwise from=-45] + child { node[concept] { type, flags \& alignment } } + child { node[concept] { program headers } } + } + child[level distance=5.5cm] { + node[concept] (elfsec) {ELF Sections} + [clockwise from=0] + child { node[concept] { section header contents } } + child { node[concept] { layout constraints } } + child { node[concept] { iterating over sections } } + child { node[concept] { reading \& writing data } } + child { node[concept] { ELF string tables } } + } + child { + node[concept] { \tool{ar} archives } + [clockwise from=-150] + child { node[concept] { archive structure } } + child { node[concept] { symbol \& string tables } } + child { node[concept] { access APIs } + [clockwise from=90] + child { node[concept] { sequential access } } + child { node[concept] { random access } } + child { node[concept] { header information } } + } + }; +\end{tikzpicture} +\caption{An overview of the concepts covered in this + tutorial.}\label{fig.concept.map} +\end{figure} + +\chapter{Getting Started}\label{chap.getting-started} + +It is time to get a taste of programming with \library{libelf}. + +Our first example program (Program 1, listing~\vref{src.prog.1}) opens +the file named on its command line, and displays the file's type as +recognized by the ELF library. This example covers the basics of +using \library{libelf}: how to compile a program that uses +\library{libelf}, how to initialize the library, how to handle any +errors reported by the library, and how to release resources cleanly +when done. + +\begin{callout}{prog1} + \lstinputlisting[caption=Program 1, label=src.prog.1]{prog1.txt} + + \begin{description} + \item[\coref{1}] The functions and dataypes that make up the ELF(3) + API are declared in the header \filename{libelf.h}. This file + must be included by every source file that uses the + \library{libelf} library.% + \index{libelf@\texttt{libelf}!header file \filename{elf.h}} + + \item[\coref{2}] The library uses an opaque C type named \type{Elf} + as a handle to an ELF object.\index{ELF!descriptor} + + \item[\coref{4}] Before the functions in the library can be invoked, + every application that uses \library{libelf} must indicate the + version of the ELF specification that it expects to use. This is + done by calling the \function{elf\_version} function. + + Calling \function{elf\_version} is mandatory---most of + \library{libelf}'s APIs will return an error if invoked before the + expected ELF version is set. + + \begin{figure} + \begin{tikzpicture}[ + version/.style={ + rectangle split, + rounded corners, + minimum width=7em, + text centered, + fill=black!15, + draw, + rectangle split parts=2, + rectangle split part align={left}, + node distance=7.5em, + }] + \node[version] (application) {Application \nodepart{second} $v_1$}; + \node[version,minimum width=5em] (library) [right=of application] { % + \texttt{libelf} \nodepart{second} $v_1$, $v_2$} + edge [thick,<->] node[auto,swap] {$v_1$} (application); + \node[version] (object) [right=of library] { % + ELF Object \nodepart{second} $v_2$} + edge [thick,<->] node[auto,swap] {$v_2$} (library); + \end{tikzpicture} + \caption{Handling ELF versioning.}\label{fig.versions} + \end{figure} + + Multiple ELF specification versions could come into play when an + application reads or writes an ELF object. In + figure~\vref{fig.versions} the application program using + \library{libelf} expects to work with files conforming to version + $v_1$ of the ELF specification. The ELF object file however + conforms to ELF specification version $v_2$. The \library{libelf} + library understands the semantics of both specification versions + $v_1$ and $v_2$, and so would (in theory) be able to mediate + between the application and the ELF object.\index{ELF!versions} + + In practice, the ELF specification's version has not changed since + its inception; the current version (denoted by the symbol + \constant{EV\_CURRENT}) is 1. + + \item[\coref{5}] The \function{elf\_begin} function takes an open + file descriptor and converts it an \type{Elf} handle. + + The second parameter to \function{elf\_begin} can be one of + `\constant{ELF\_C\_READ}' for opening an ELF object for reading, + `\constant{ELF\_C\_WRITE}' for creating a new ELF object, or + `\constant{ELF\_C\_RDWR}' for opening an ELF object for updates. + The file opening mode for the file descriptor \code{fd} should be + compatible with this parameter: the file descriptor should be + opened for reading for use with \constant{ELF\_C\_READ}, for + writing for use with \constant{ELF\_C\_WRITE}, and for updating + for use with \constant{ELF\_C\_RDWR}. + + The third parameter to \function{elf\_begin} is only used when + reading \tool{ar} ar\-chives. Chapter~\vref{chap.ar} covers + \tool{ar} archive processing. + + \item[\coref{6}] When the ELF library encounters an error, it will + record an error number in an internal location and return a + sentinel value (e.g., the \code{NULL} value from functions + that return pointers). The saved error number indicates + the specific class of error that was encountered. This number can + be retrieved using the \function{elf\_errno} function. + + Numeric error numbers are however not user-friendly. The + \function{elf\_errmsg} function returns a human-readable string + describing the error number passed to it. As a programming + convenience, an error number of -1 denotes the most recent error + number that had been recorded by the library. + + \item[\coref{3} \coref{7}] The ELF library can operate on \tool{ar} + archives and ELF objects. The function \function{elf\_kind} + returns the kind of object associated with an \type{Elf} handle. + The return value of the \function{elf\_kind} function is one of + the values defined by the \type{Elf\_Kind} enumeration in + \filename{libelf.h}. Currently, the library only recognizes ELF + files and \tool{ar} archives. + + \item[\coref{8}] The \function{elf\_end} function releases the + resources held by an \type{Elf} handle. + \end{description} +\end{callout} + +It is now time to compile and run our first example program. + +Save the listing in listing~\vref{src.prog.1} to a file named +\filename{prog1.c}, and then compile and run it as shown in +listing~\vref{scr.prog1}.% +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr1} + \begin{lstlisting}[basicstyle=\ttfamily, language={}, + caption=Compiling and running prog1, + label=scr.prog1] +% cc -o prog1 prog1.c -lelf @\co{1}@ +% ./prog1 prog1 @\co{2}@ +prog1: elf object +% ./prog1 /usr/lib/libc.a @\co{3}@ +/usr/lib/libc.a: ar(1) archive + \end{lstlisting} + + \begin{description} + \item[\coref{1}] The \code{-lelf} option to the \tool{cc} + comand informs it to link \tool{prog1} with the \library{libelf} + library. + \item[\coref{2}] We invoke \tool{prog1} on itself. If all went well + it should recognize its own executable file to be an ELF object. + \item[\coref{3}] \tool{prog1} should recognize an \tool{ar} archive + correctly. + \end{description} +\end{callout} + +Congratulations! You have created your first ELF-aware program using +\library{libelf}. + +\chapter{Peering Inside an ELF Object}\label{chap.peering-inside} + +This chapter takes a deeper look at the structure of ELF objects. + +\section{ELF Object Kinds} +ELF supports multiple kinds of objects: + +\begin{itemize} +\item \firstterm{Relocatable objects}\index{ELF!relocatable objects} + contain compiled code along with extra information used by tools + like linkers. Relocatable objects are usually created by compilers + when source code is compiled. +\item \firstterm{Executables}\index{ELF!executables} contain + code in a form that an operating system can directly use to launch a + process. The process of forming executables from collections of + relocatable objects is called + \firstterm{linking}\index{linking!definition~of}. +\item \firstterm{Dynamically loadable objects}\index{ELF!dynamically + loadable objects} contain code in a form suitable for + loading into a running process. Shared + libraries\index{shared library} are examples of dynamically loadable + objects. +\item \firstterm{Core files}\index{core files} contain the memory + image of a process. Core files are usually generated when programs + crash. +\end{itemize} + +Each of these kinds of objects has a different internal structure. + +\section{ELF File Layout} + +Figure~\vref{fig.elf.layout} shows the layout of a typical ELF +object.\index{ELF!typical layout} + +Every ELF object starts with a mandatory data structure known as the +ELF \elfdatastructure{Executable Header}.\index{executable~header} +This header is followed by optional content---depending on the kind of +ELF object, this could be an optional ELF \elfdatastructure{Program + Header Table}\index{program~header~table} and zero or more ELF +\elfdatastructure{Sections}\index{sections}: + +\begin{itemize} +\item The ELF \elfdatastructure{Program Header + Table}\index{program~header~table} is found in executables and + dynamically loadable objects. This data structure contains + information that is used when the ELF object is loaded into a + process\index{loading}. We look at the \elfdatastructure{Program + Header Table} more closely in chapter~\vref{chap.elf-phdr}. +\item ELF \elfdatastructure{Sections}\index{sections} are present in + most ELF files. Sections are contiguous regions inside the ELF + object holding data of a specific kind. ELF sections are described + by entries in an ELF \elfdatastructure{Section Header + Table}\index{section~header~table}. + Chapter~\vref{chap.elf-sections} describes ELF + \elfdatastructure{Sections} and the \elfdatastructure{Section + Header Table} in further detail. +\end{itemize} + +\begin{figure} + \begin{center} + \begin{tikzpicture}[ + start chain, + node distance=0pt, + elfpart/.style={ + rectangle, + draw, + minimum height=3\baselineskip, + font=\small, + text width=4.2em + }, + gap/.style={ + draw, + minimum height=3\baselineskip, + minimum width=2ex + }] + + % Depict the structure of an ELF object. + \node[on chain,elfpart,text width=4.4em,fill=black!15] (ehdr) + {Executable Header}; + \node[on chain,gap] (g0) {}; + \node[on chain,elfpart,fill=black!5] (phdr) {Program Header Table}; + \node[on chain,gap] (g1) {}; + \node[on chain,elfpart,fill=black!5] (s0) {Section Data$_{(1)}$}; + \node[on chain,gap] (gl0) {}; + \node[on chain,elfpart,text centered,fill=black!5] (sdots) {\ldots}; + \node[on chain,gap] (gl1) {}; + \node[on chain,elfpart,fill=black!5] (sn) {Section Data$_{(n)}$}; + \node[on chain,gap] (g3) {}; + \node[on chain,elfpart,fill=black!15,fill=black!5] (shdr) + {Section Header Table}; + + % Label the gaps needed for alignments. + \node[below=2em of sdots,text width=10em] + {Possible gaps due to alignment constraints.} + edge [->] ([yshift=-1pt] g0.south) + edge [->] ([yshift=-1pt] g1.south) + edge [->] ([yshift=-1pt] gl0.south) + edge [->] ([yshift=-1pt] gl1.south) + edge [->] ([yshift=-1pt] g3.south); + \end{tikzpicture} + \end{center} + \caption{The layout of a typical ELF File.}\label{fig.elf.layout} +\end{figure} + + +The optional elements of an ELF object are shown with a lighter +background in figure~\vref{fig.elf.layout}. + +\subsubsection{The ELF Executable Header}\label{sec.ehdr} +Table \vref{src.elf.ehdr} describes the layout of an ELF +\elfdatastructure{Executable Header} using a ``C-like'' notation that +shows the sizes and ordering of its +members.\index{executable~header!layout} In an actual ELF object the +data in the header would be stored using the ELF object's ``native'' +byte ordering; this ordering could differ from the byte ordering used +by the program reading the header. 32-bit and 64-bit ELF +\elfdatastructure{Executable Header} structures also have slightly +different layouts due to the differing sizes of their members. + +\begin{callout}{ehdr} + \begin{table} + \begin{tabular}{rl|l} + \mbox{} & \tableheader{32 bit Executable Header} & + \tableheader{64 bit Executable Header} \\ \hline + & \verb+typedef struct {+& + \verb+typedef struct {+\\ +\co{1} & \verb+ unsigned char e_ident[16];+& + \verb+ unsigned char e_ident[16];+\\ +\co{2} & \verb+ uint16_t e_type;+& + \verb+ uint16_t e_type;+\\ +\co{3} & \verb+ uint16_t e_machine;+& + \verb+ uint16_t e_machine;+\\ + & \verb+ uint32_t e_version;+& + \verb+ uint32_t e_version;+\\ + & \verb+ uint32_t e_entry;+& + \verb+ uint32_t e_entry;+\\ +\co{4} & \verb+ uint32_t e_phoff;+& + \verb+ uint64_t e_phoff;+\\ +\co{5} & \verb+ uint32_t e_shoff;+& + \verb+ uint64_t e_shoff;+\\ + & \verb+ uint32_t e_flags;+& + \verb+ uint32_t e_flags;+\\ + & \verb+ uint16_t e_ehsize;+& + \verb+ uint16_t e_ehsize;+\\ + & \verb+ uint16_t e_phentsize;+& + \verb+ uint16_t e_phentsize;+\\ +\co{6} & \verb+ uint16_t e_phnum;+& + \verb+ uint16_t e_phnum;+\\ +\co{7} & \verb+ uint16_t e_shnum;+& + \verb+ uint16_t e_shnum;+\\ +\co{8} & \verb+ uint16_t e_shstrndx;+& + \verb+ uint16_t e_shstrndx;+\\ + & \verb+} Elf32_Ehdr;+& + \verb+} Elf64_Ehdr;+\\ + \end{tabular} + \caption{The ELF \elfdatastructure{Executable Header}.}\label{src.elf.ehdr} + \end{table} + + \begin{description} + \item[\coref{1}] Figure \vref{fig.elf.eident} shows the contents of + the first 16 bytes of the ELF header (the \parameter{e\_ident} + array). + + \begin{figure} + \begin{tikzpicture}[ + start chain, + node distance=0pt, + ei/.style={ + on chain, + draw, + fill=black!#1, + minimum width=3.2em, + minimum height=1.5\baselineskip + }] + + % Helper macro. + \def\e#1{\draw[-,rotate=-45] + ([yshift=-1pt] \tikzchaincurrent.south) -- +(0:0.5cm) + node[rotate=-45,base right] {\footnotesize EI\_#1}} + + % Draw the e_ident[] array. + \node[ei=10] (e0) {0x7F}; \e{MAG0}; + \node[ei=5] (e1) {`E'}; \e{MAG1}; + \node[ei=10] (e2) {`L'}; \e{MAG2}; + \node[ei=5] (e3) {`F'}; \e{MAG3}; + \node[ei=10] (e4) { }; \e{CLASS}; + \node[ei=5] (e5) { }; \e{DATA}; + \node[ei=10] (e6) { }; \e{VERSION}; + \node[ei=5] (e7) { }; \e{OSABI}; + \node[ei=10] (e8) { }; \e{OSABIVERSION}; + \node[ei=0] (e9) {$\ldots$}; + + % Add Labels. + \node[above=1.5em of e2.north] {ELF class: 32/64} + edge [->] ([yshift=1pt] e4.north); + \node[above=3.5em of e3.north east] {Byte order: LSB/MSB} + edge [->] ([yshift=1pt] e5.north); + \node[above=2.8em of e7.north] {ELF version} + edge [->] ([yshift=1pt] e6.north); + \node[above=1.5em of e8.north east,text width=4em] {OS ABI} + edge [->] ([yshift=1pt] e7.north) + edge [->] ([yshift=1pt] e8.north); + \end{tikzpicture} + \caption{The layout of the \parameter{e\_ident} array.}% + \label{fig.elf.eident} + \end{figure} + + The first 4 bytes of an ELF object always contain 0x7F, 0x45 + (ASCII `E'), 0x4c (ASCII `L') and 0x46 (ASCII `F'). + + The next three bytes specify: + \begin{itemize} + \item The ELF class\index{ELF!class} of the object---whether it is a 32 + bit ELF object (\constant{ELFCLASS32}) or a 64 bit + (\constant{ELFCLASS64}) one. + \item The endianness\index{ELF!endianness} of the object---whether + little-endian (\constant{ELFDATA2LSB}) or big-endian + (\constant{ELFDATA2MSB}). + \item The ELF specification version\index{ELF!version~number} + number that the object conforms to. ELF object versioning was + discussed in chapter~\vref{chap.getting-started}. + \end{itemize} + + With this information on hand, the \library{libelf} library can + then interpret the rest of the ELF \elfdatastructure{Executable + Header} correctly. + + \item[\coref{2}] The \parameter{e\_type} member determines the type + of the ELF object. For example, the member would contain the + value `1' (\constant{ET\_REL}) in a relocatable or the value `3' + (\constant{ET\_DYN}) in a shared + object.\index{executable~header!executable type} + + \item[\coref{3}] The \parameter{e\_machine} member describes the + machine architecture for the ELF object. Example values are `3' + (\constant{EM\_386}) for the Intel\reg i386\trade architecture, + and `20' (\constant{EM\_PPC}) for the 32-bit PowerPC\trade + architecture.\index{executable~header!executable architecture} + + \begin{figure} + \begin{tikzpicture}[ + start chain, + node distance=0pt, + ei/.style={ + on chain, + draw, + fill=black!#1, + minimum height=1.2\baselineskip, + text centered + }] + + % Draw the major parts of the ELF object. + \node[ei=15,text width=2cm] (ehdr) { Ehdr }; + \node[ei=0,text width=1.5em] (gap0) {}; + \node[ei=5,text width=3.2cm] (phdr) { Phdr }; + \node[ei=0,text width=5em] (gap1) {}; + \node[ei=5,text width=3.2cm] (shdr) { Shdr }; + + % Draw the marks. + \def\l#1#2#3{ \draw[-] ([yshift=#2] #1) -- +(90:#3) }; % Helper. + + \l{ehdr.north west}{1pt}{0.5cm}; + \l{ehdr.south west}{-1pt}{-1.2cm}; + \l{ehdr.north east}{1pt}{0.5cm}; + + \l{phdr.south west}{-1pt}{-0.67cm}; + \l{phdr.north west}{1pt}{0.5cm}; + \l{phdr.north east}{1pt}{0.5cm}; + + \l{shdr.north west}{1pt}{0.5cm}; + \l{shdr.north east}{1pt}{0.5cm}; + \l{shdr.south west}{-1pt}{-1.2cm}; + + % Render the labels. + \def\sz#1#2#3#4{ % Helper macro. + \draw[<->] ([yshift=#3] #1) -- node [auto] {\small #4 } + ([yshift=#3] #2) + } + + \sz{ehdr.north west}{ehdr.north east}{0.44cm}{e\_ehsize}; + \sz{phdr.north west}{phdr.north east}{0.44cm}% + {N\raisebox{-1ex}{phdr} $\times$ e\_phentsize}; + \sz{shdr.north west}{shdr.north east}{0.44cm}% + {N\raisebox{-1ex}{shdr} $\times$ e\_shentsize}; + + \sz{ehdr.south west}{phdr.south west}{-0.6cm}{e\_phoff}; + \sz{ehdr.south west}{shdr.south west}{-1.1cm}{e\_shoff}; + + \end{tikzpicture} + \caption{The ELF \elfdatastructure{Executable Header} describes + the layout of the rest of the ELF object.} + \label{fig.elf.ehdr-layout} + \end{figure} + + \item[\coref{4} \coref{5}] The ELF \elfdatastructure{Executable + Header} also describes where to find the ELF + \elfdatastructure{Program Header Table} and the + \elfdatastructure{Section Header Table}, if these data structures + are present in the ELF object (Figure~\vref{fig.elf.ehdr-layout}). + + The \parameter{e\_phoff} and \parameter{e\_shoff} members contain + the file offsets at which the ELF \elfdatastructure{Program Header + Table} and the ELF \elfdatastructure{Section Header Table} + reside in the ELF object. These members are zero if the file does + not contain the corresponding data structures. The sizes of these + tables are determined by the \parameter{e\_phentsize} and + \parameter{e\_shentsize} members of the executable header, in + conjunction with the number of entries in these tables.% + \index{section~header~table!layout in file}% + \index{section~header~table!entry size}% + \index{program~header~table!layout}% + \index{program~header~table!entry~size} + + The ELF \elfdatastructure{Executable Header} describes its own + size (in bytes) in member + \parameter{e\_ehsize}.\index{executable~header!own size} + + \item[\coref{6} \coref{7}] The \parameter{e\_phnum} and + \parameter{e\_shnum} members contain the number of ELF program + header table entries and section header table entries + respectively. + + These fields are only 2 bytes wide, so if an ELF object has a + large number of sections or program header table entries, then a + scheme known as ``Extended Numbering''\index{extended~numbering} + (section~\vref{sec.extended-numbering}) is used to encode the + actual number of sections or program header table entries. When + extended numbering is in use these fields will contain special + values instead of actual counts. + + \item[\coref{8}] When an ELF object contains sections, the names of + these sections are stored in a separate string table section. ELF + string tables will be covered in more detail in + section~\vref{sec.shdr.strtab}.\index{sections!names!string~table} + + The \parameter{e\_shstrndx} member stores the section index of + this string table (possibly using ``Extended Numbering'', see + section \vref{sec.extended-numbering}). This allows tools + processing the ELF object to use the correct string table for + looking up section names. + \end{description} + + The \parameter{e\_entry} and \parameter{e\_flags} members are used + for executables. These members are placed in the executable header + for easy access at program load time. This tutorial will not discuss + these members any further.\index{executable~header!program entry + point}\index{executable~header!flags} +\end{callout} + +\section{Extended Numbering}\label{sec.extended-numbering}% +\index{extended~numbering} + +The \parameter{e\_shnum}, \parameter{e\_phnum} and +\parameter{e\_shstrndx} members of the ELF +\elfdatastructure{Executable Header} are 2 bytes long and are not wide +enough to represent numbers larger than 65535. We would therefore need +a different way of encoding these numbers for ELF objects with a large +number of sections or segments.\index{extended~numbering!need for} + +When extended numbering is in use, the actual values of these members +will be stored in the normally unused zeroth section header table +entry.\footnote{Section header table entries are covered in more + detail in section~\vref{chap.elf-sections}.} + +\begin{itemize} +\item The true number of sections will stored in the + \parameter{sh\_size} field of the zeroth section header table entry, + while the \parameter{e\_shnum} member of the ELF executable header + will be set to zero. +\item The actual number of program header table entries will be stored + in the \parameter{sh\_info} field of the zeroth section header table + entry, while the \parameter{e\_phnum} member of the executable + header will be set to the value \constant{PN\_XNUM} + (0xFFFF).\index{extended~numbering!program headers} +\item The true index of the section name string table will be stored + in the \parameter{sh\_link} field of the zeroth entry of the section + header table, while the \parameter{e\_shstrndx} member of the + executable header will be set to the value \constant{SHN\_XINDEX} + (0xFFFF).\index{extended~numbering!sections} +\end{itemize} + +You should always use the functions \function{elf\_getphdrnum}, +\function{elf\_getshdrnum} and \function{elf\_getshdrstrndx} to read +the value of these members from an \type{Elf} descriptor. Directly +using the values of the \parameter{e\_phnum}, \parameter{e\_shnum} and +\parameter{e\_shstrndx} members of the executable header is likely to +lead to incorrect program behavior. + +\section{The Elf32, Elf64 and GElf APIs} + +The ELF(3) API is defined in terms of ELF class-dep\-endent types +(\type{Elf32\_Ehdr}, \type{Elf64\_Shdr}, etc). Consequently many +operations on ELF handles in the ELF(3) API have both 32- and 64- bit +variants. + +For example, in order to retrieve an ELF executable header from a 32 +bit ELF object we would use the function \function{elf32\_getehdr}, +which would return a pointer to an \type{Elf32\_Ehdr} structure. For +a 64-bit ELF object, we would need to use the function +\function{elf64\_getehdr}, which would return a pointer to an +\type{Elf64\_Ehdr} structure. + +This duplication is awkward when you want to write applications that +need to process either class of ELF objects.% +\index{ELF!class~agnostic~APIs}. + +The GELF(3)\index{GELF API} APIs provide a way to write applications +that can handle objects of both ELF classes without code duplication. +These APIs are defined in terms of ``generic'' C types that are large +enough to hold their corresponding 32-bit and 64- bit ELF types. The +GELF(3) data types have names that start with \code{GElf\_}, and the +functions have names that start with \code{gelf\_}. You can freely +mix calls to GELF(3) and ELF(3) functions in your code. + +The downside to using the GELF(3) APIs is the small cost of the +copying and conversion that happens behind the scenes inside +\library{libelf}.\index{GELF API!downsides to} This overhead is +usually insignificant for most programs. + +\section{File and Memory Representations}\label{sec.representations} + +\begin{figure} + \begin{tikzpicture}[ + start chain, + node distance=0pt, + ef/.style={ + on chain, + draw, + minimum height=1.2\baselineskip, + text centered + }] + + % Helper macros. + \def\l#1#2#3{ \draw[-] ([yshift=#2] #1) -- +(90:#3) } + \def\sz#1#2#3#4{ + \draw[<->] ([yshift=#3] #1) -- node [auto] {\small #4 } + ([yshift=#3] #2) + } + + % Draw a skeletal ELF object. + \node[ef,text width=3em] (ehdr) {}; + \node[ef,text width=8em] (g0) {}; + \node[ef,text width=2em,fill=black!15] (file) {}; + \node[ef,text width=8em] (g1) {}; + \node[ef,text width=3em] (shdr) {}; + + % Label the ELF object as a whole. + \node[left=3em of ehdr.west,text width=3em] { ELF object } + edge [->,shorten >=1pt] (ehdr.west); + + % Label the box denoting the file representation of data. + \node[above=2em of ehdr.north east] {The file representation} + edge [->,shorten >=1pt] (file.center); + + % Place tick marks around the file representation box. + \l{file.north west}{1pt}{0.3cm}; + \l{file.north east}{1pt}{0.3cm}; + \l{file.south west}{-1pt}{-0.5cm}; + + % Show the size of the file representation and its alignment. + \draw[<->,shorten >=1pt,shorten <=1pt] + ([yshift=0.25cm] file.north west) -- + node [above=0.75ex,text centered,text width=5em] {file size} + ([yshift=0.25cm] file.north east); + \node[below right=0.2cm and 0cm of file.south west] {\%falign}; + + % Draw and label the memory representation of the data. + \node[below=2cm of file.south,minimum width=6em, + minimum height=1.2\baselineskip,draw,fill=black!5] + (mem) { }; + \node[left=1.6cm of mem] + {The memory representation} + edge [->,semithick,shorten >=1pt] (mem.center); + + % Show the memory alignment. + \l{mem.north west}{1pt}{0.5cm}; + \node[above right=0.15cm and 0cm of mem.north west] {\%malign}; + + % Indicate the memory size. + \l{mem.south west}{-1pt}{-0.3cm}; + \l{mem.south east}{-1pt}{-0.3cm}; + \draw[<->,shorten >=1pt,shorten <=1pt] + ([yshift=-0.25cm] mem.south west) -- + node [below=0.75ex] {memory size} + ([yshift=-0.25cm] mem.south east); + + % Draw the arrows denoting translation between file and memory. + \draw[->,semithick,shorten >=1pt,shorten <=1pt] (file.south east) .. + controls ++(1,-.5) and ++(2,0.5) .. + (mem.north east) node[midway,right=1ex] {xlatetom()} ; + \draw[<-,semithick,shorten >=1pt,shorten <=1pt] (file.south west) .. + controls ++(-1,-.5) and ++(-2,0.5) .. + (mem.north west) node[midway,left=1ex] {xlatetof()} ; + \end{tikzpicture} + \caption{The relationship between the file and memory representation + of an ELF data structure.}\label{fig.representations} +\end{figure} + +ELF objects use the native word width, enddianness and data alignment +rules of the machine they are intended for. These could be different +from the native word width, enddianness and data alignment rules for +the machine that the program reading the ELF object is running on. + +ELF data structures therefore have two distinct +representations:\index{object~representation} + +\begin{itemize} +\item An \emph{in-memory representation} that obeys the constraints + for the machine architecture that the program handling the ELF + object is running on. +\item An \emph{in-file representation} that corresponds to the target + architecture for the ELF object. +\end{itemize} + +Figure \vref{fig.representations} depicts the relationship between the +in-file and in-memory representations of an ELF data structure. This +figure shows that:\index{object~representation!file vs memory} + +\begin{itemize} +\item The size of an ELF data structure in the file could be different + from its size in memory. +\item The alignment restrictions placed on the data structure (denoted + by \code{\%falign} and \code{\%malign} in the figure) + could differ. +\item The byte ordering of data in the file could be different + from that in memory. +\end{itemize} + +When using \library{libelf} you do not need to handle these +differences in your code---\library{libelf} will handle the +conversions of in-memory ELF data structures to and from their in-file +representations automatically. For example, in +program~\ref{src.prog.2} below, the \library{libelf} library will +automatically do the necessary byteswapping and alignment adjustments +when reading in the ELF executable header.% +\index{ELF!class~agnostic~APIs}% +\index{libelf@\texttt{libelf}!automatic~data~conversion} + +If you need finer-grain control over the conversion process, the +\library{libelf} library offers the class-dependent +\code{elf\textit{NN}\_xlatetof} and \code{elf\textit{NN}\_xlatetom} +functions.\index{libelf@\texttt{libelf}!manual~data~conversion} This +introductory tutorial does not discuss these functions further. + +\section{Example: Reading an ELF Executable Header} + +Let us now examine a program that will print out the ELF +\elfdatastructure{Executable Header} present in an ELF object. Our +example program will use the class-independent GELF(3) +APIs.\index{GELF API} + +\begin{callout}{prog2} + \lstinputlisting[caption=Program 2, label=src.prog.2]{prog2.txt} + + \begin{description} + \item[\coref{1}] Source code that uses the GELF(3) APIs should + include the \filename{gelf.h} header file.% + \index{libelf@\texttt{libelf}!header file \filename{gelf.h}} + + \item[\coref{2}] The \type{GElf\_Ehdr} type used here has fields + that are large enough to contain values for a 64 bit ELF + executable header. + + \item[\coref{3}] The \function{elf\_begin} function allocates an + \type{Elf} handle opened for reading. + + \item[\coref{4}] The function \function{gelf\_getehdr} retrieves the + executable header present in the ELF object. + + This function translates the ELF executable header in the file to + its corresponding in-memory representation in the C type + \type{GElf\_Ehdr}. For example, if a 32-bit ELF object is being + examined, then the values in its executable header would be + appropriately expanded and/or byte swapped by this function.% + \index{executable~header!retrieval of} + + \item[\coref{5}] The \function{gelf\_getclass} function retrieves + the ELF class of the object being examined.% + \index{ELF!class!retrieval of} + + \item[\coref{6}] The \function{elf\_getident} function retrieves the + contents of the \parameter{e\_ident} array from the ELF + descriptor. These bytes would also be present in the + \parameter{e\_ident} member of the \elfdatastructure{Executable + Header} structure. We print the first few bytes of the + \parameter{e\_ident} byte array. + + \item[\coref{7}] After printing out the values of the bytes in the + \parameter{e\_ident} array, we print the values of some of the + fields of the ELF executable header structure. + + \item[\coref{8}] The function \function{elf\_getphdrnum} retrieves + the count of program header table entries in the ELF object. + + \item[\coref{9}] The \function{elf\_getshdrnum} function retrieves + the number of sections in the ELF object. + + \item[\coref{10}] The function \function{elf\_getshdrstrndx} + function retrieves the index of the section name string table in + the object. + \end{description} +\end{callout} + +Save the program in listing~\vref{src.prog.2} to a file named +\filename{prog2.c}, and compile and run it as shown in +listing~\vref{scr.prog2}.% +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr2} + \newcommand{\at}{@} + \begin{lstlisting}[language={}, basicstyle=\small\ttfamily, + label=scr.prog2, caption=Compiling and Running prog2] +% cc -o prog2 prog2.c -lelf @\co{1}@ +% ./prog2 prog2 @\co{2}@ +prog2: 64-bit ELF object + e_ident[0..8] ['\^?' 7F] ['E' 45] ['L' 4C] ['F' 46] \ + ['\^B' 2] ['\^A' 1] ['\^A' 1] ['\^I' 9] ['\^@\at@' 0] + e_type 0x2 + e_machine 0x3e + e_version 0x1 + e_entry 0x400a10 + e_phoff 0x40 + e_shoff 0x16f8 + e_flags 0x0 + e_ehsize 0x40 + e_phentsize 0x38 + e_shentsize 0x40 + (shnum) 0x18 + (shstrndx) 0x15 + (phnum) 0x5 + \end{lstlisting} + \begin{description} + \item[\coref{1}] The process for compiling and linking a GELF(3) + application is the same as for other \library{libelf} based + programs. + + \item[\coref{2}] We run our program on itself. This listing in this + tutorial was generated on an AMD64\trade machine running + FreeBSD\makebox[0pt]{.}\trade + \end{description} + + You should now run \tool{prog2} on other object files that you have + lying around. Try it on a few non-native ELF object files too. +\end{callout} + +\chapter{Examining the Program Header Table}\label{chap.elf-phdr} + +Before a program on disk can be executed by a processor it needs to +brought into system memory. The technical name for this process is +``loading''.\index{loading} + +When loading an ELF program into memory, the operating system views it +as comprising of distinct parts, where each part has a particular +characteristic. For example, one part of the program could contain +read-only data that needs to be loaded at a specific virtual memory +address. Another part could contain executable code.\index{segments} +Each such part of the ELF object is called an ELF +\elfdatastructure{Segment}\index{segments!definition~of}. + +By way of an example, the FreeBSD\trade operating system expects +programs to contain a segment containing executable +code.\index{segments!example~layout} This segment is called the +program's ``\filename{text}'' segment. A \filename{text} segment would +usually be loaded into memory with `read' and `execute' permissions. +Multiple processes using the same executable could potentially share +the same \filename{text} segment. FreeBSD programs would usually have +\filename{data} segments too; these segments are placed in memory with +`read' and `write' permissions, and made private to each process. + +Like executables, dynamically linked objects can be viewed as +comprising segments. + +The segments present in an ELF object are described by a data +structure known as the ELF \elfdatastructure{Program Header + Table}.\index{program~header~table} We will study this data +structure in this chapter, and write an example program that displays +the \elfdatastructure{Program Header Table} present in an ELF object. + +\section{The ELF Program Header Table} + +An ELF \elfdatastructure{Program Header Table} is a contiguous array +of \elfdatastructure{Program Header Table Entry} structures. Every +segment present in the ELF object would have a corresponding entry in +the program header table. + +The location of the program header table within the ELF object is +given by the \parameter{e\_phoff} member of the ELF executable header +(see figure~\ref{fig.elf.ehdr-layout} in section~\ref{sec.ehdr}). This +member holds the offset in bytes from the start of the ELF object to +the start of its program header table. + +Table~\vref{src.elf.phdr} lists the members of a +\elfdatastructure{Program Header Table Entry} +structure.\index{program~header~table!entry} +Figure~\vref{fig.elf.phdr.layout} illustrates how these members +specify the segment's placement both in memory and within the ELF +object. + +\begin{figure} + \index{program~header~table!layout} + \begin{tikzpicture}[ + start chain=1 going right, + start chain=2 going above, + node distance=0pt, + ef/.style={ + on chain=1, + draw, + minimum height=1.4\baselineskip, + text centered + }, + ph/.style={ + on chain=2, + draw, + text width=4.2em, + fill=black!15, + font=\ttfamily + }] + + % Helper macros. + \def\l#1#2#3{ \draw[-] ([yshift=#2] #1) -- +(90:#3) } + \def\sz#1#2#3#4{ + \draw[<->] ([yshift=#3] #1) -- node [auto] {\small #4 } + ([yshift=#3] #2) + } + + % Draw a ELF object with a highlighted PHDR entry. + \node[on chain=1,text width=5 em] {ELF object}; + \node[ef,text width=4em,fill=black!10] (ehdr) {Ehdr}; + \node[ef,text width=1.5ex] (g0) {}; + \node[ef,text width=4em,fill=black!10] (Phdr) {Phdr}; + \node[ef,text width=0.5ex,fill=black!25] (p0) { }; + \node[ef,text width=1ex,fill=black!10] (p1) { }; + \node[ef,text width=4em] (g1) {}; + \node[ef,text width=5em,fill=black!10] (seg) + {Segment${}_n$}; + \node[ef,text width=4em] (shdr) {}; + + % Draw the marks and label sizes and offsets. + \l{ehdr.south west}{-1pt}{-0.6cm}; + \l{seg.south west}{-1pt}{-0.6cm}; + \l{seg.south east}{-1pt}{-0.6cm}; + \l{seg.north west}{1pt}{0.5cm}; + \node[above right=0.2cm and .5cm of seg.north west] {\%p\_align} + edge[->,shorten >=1pt] ([yshift=0.25cm] seg.north west); + + \sz{ehdr.south west}{seg.south west}{-0.55cm}{p\_offset}; + \sz{seg.south west}{seg.south east}{-0.55cm}{p\_filesz}; + + % Draw the segment in memory. + \node[above right=2cm and 0cm of seg.north west,draw,fill=black!10] + (segmem) {Segment${}_n$ in memory}; + \l{segmem.north west}{1pt}{0.3cm}; + \node[above=2em of segmem.north] {p\_vaddr} + edge [->,shorten >=1pt] ([yshift=0.15cm] segmem.north west); + \l{segmem.south west}{-1pt}{-0.6cm}; + \l{segmem.south east}{-1pt}{-0.6cm}; + \sz{segmem.south west}{segmem.south east}{-0.55cm}{p\_memsz}; + + % Draw the expanded segment. + \node[ph,above=1cm of g0.north,text centered] (phbot) {\dots}; + \node[ph] {p\_align}; + \node[ph] {p\_memsiz}; + \node[ph] {p\_filesz}; + \node[ph] {p\_vaddr}; + \node[ph] {p\_offset}; + \node[ph] (phtop) {p\_type}; + + \node[above=1ex of phtop.north] {Program Header Table Entry}; + + % Draw the expansion lines. + \draw [-,shorten >=1pt,shorten <=2pt] (phbot.south west) -- + ([yshift=1pt] p0.north west); + \draw [-,shorten >=1pt,shorten <=2pt] (phtop.north east) -- + ([yshift=1pt] p0.north east); + + \end{tikzpicture} + \caption{ELF Segment Placement.}\label{fig.elf.phdr.layout} +\end{figure} + +\begin{callout}{phdr} + \begin{table}[H] + \begin{tabular}{rl|ll} + \mbox{} & \tableheader{32 bit PHDR Table Entry} & + \tableheader{64 bit PHDR Table Entry}\\ \hline + & \verb+typedef struct {+& + \verb+typedef struct {+\\ +\co{1} & \verb+ Elf32_Word p_type;+& + \verb+ Elf64_Word p_type;+&\\ +\co{2} & \verb+ Elf32_Off p_offset;+& + \verb+ Elf64_Word p_flags;+&\\ +\co{3} & \verb+ Elf32_Addr p_vaddr;+& + \verb+ Elf64_Off p_offset;+&\\ +\co{4} & \verb+ Elf32_Addr p_paddr;+& + \verb+ Elf64_Addr p_vaddr;+&\\ +\co{5} & \verb+ Elf32_Word p_filesz;+& + \verb+ Elf64_Addr p_paddr;+&\\ +\co{6} & \verb+ Elf32_Word p_memsz;+& + \verb+ Elf64_Xword p_filesz;+&\\ +\co{7} & \verb+ Elf32_Word p_flags;+& + \verb+ Elf64_Xword p_memsz;+&\\ +\co{8} & \verb+ Elf32_Word p_align;+& + \verb+ Elf64_Xword p_align;+&\\ + & \verb+} Elf32_Phdr;+ & \verb+} Elf64_Phdr;+&\\ + \end{tabular} + \caption{ELF Program Header Table Entries.}\label{src.elf.phdr} + \end{table} + + \begin{description} + \item[\coref{1}] The \parameter{p\_type} member of the program + specifies the type of the ELF segment.\index{segments!type} The + type of the segment is specified by one of the \code{PT\_*} + constants in the programming API. Examples include: + \begin{itemize} + \item A segment of type \constant{PT\_LOAD} contains data that + needs to be placed in memory. + \item A segment of type \constant{PT\_PHDR} describes the ELF + \elfdatastructure{Program Header Table} itself. + \item A segment of type \constant{PT\_INTERP} contains a path to + the runtime linker used by dynamically linked executables. + \item A segment of type \constant{PT\_NOTE} contains auxiliary + information. + \end{itemize} + + \item[\coref{2}] The \parameter{p\_offset} member holds the offset + from the start of the ELF object to the start of the segment being + described by this table entry.\index{segments!offset in object} + + \item[\coref{3}] The \parameter{p\_vaddr} member specifies the + virtual address that this segment should be placed + at.\index{segments!virtual address of} + + \item[\coref{4}] The \parameter{p\_paddr} member specifies the + physical memory address this segment should be loaded at. + + \item[\coref{5}] The \parameter{p\_filesz} member specifies the size + of the segment in the file. This number can be zero if the + segment does not use data from file (for example, if the segment + is a memory-only segment).\index{segments!file size of} + + \item[\coref{6}] The \parameter{p\_memsz} member specifies the + number of bytes of memory the segment would use.% + \index{segments!memory size of} + + \item[\coref{7}] The \parameter{p\_flags} member specifies + additional segment properties. For example, the value + \constant{PF\_X} specifies that the segment should be made + executable, the value \constant{PF\_W} specifies that the segment + should be writable, and so on.\index{segments!flags} + + \item[\coref{8}] The \parameter{p\_align} member specifies the + alignment requirements of the segment in memory and in the file. + This member holds a number that is a power of two. + \index{segments!aligment of} + \end{description} +\end{callout} + +The file representation of a \elfdatastructure{Program Header Table} +uses the ELF object's native endianness. The \library{libelf} library +will handle the translation between the in-file and in-memory +representations of program header table entries for you. Please see +section~\vref{sec.representations} for more information on in-memory +and in-file representations of ELF data structures. + +\section{Example: Reading a Program Header Table} + +The example program in this chapter will read and print out the +program header table in an ELF object. This example, like the previous +one, uses the class-agnostic GELF(3) +APIs.\index{ELF!class~agnostic~APIs} + +\begin{callout}{prog3} + \lstinputlisting[caption=Program 3, label=src.prog.3]{prog3.txt} + + \begin{description} + \item[\coref{1}] Source code that uses the GELF(3) functions needs + to include the \filename{gelf.h} header file. + \item[\coref{2}] \code{print\_ptype} is a helper function that + translates the value of the \parameter{p\_type} member to + human-readable form. + \item[\coref{3}] The GELF(3) functions in this example will use the + \type{GElf\_Phdr} C type. This type has members that are large + enough for both the 32-bit (\type{Elf32\_Phdr}) and 64-bit + (\type{Elf64\_Phdr}) header table + entries.\index{ELF!class~agnostic~APIs} + \item[\coref{4}] The function \function{elf\_getphdrnum} will + retrieve the number of program header table entries in the ELF + object.\index{program~header~table!retrieval of} + \item[\coref{5}] This \code{for} loop iterates over the valid + indices for the \elfdatastructure{Program Header Table}. + \item[\coref{6}] The \function{gelf\_getphdr} function retrieves the + program header table entry at a specified index. + \index{program~header~table!iteration over} If successful it will + return the \type{GElf\_Phdr} pointer that was passed to it. + \item[\coref{7}] The remaining lines of the loop's body print out + the contents of the returned \type{GElf\_Phdr} entry. + \end{description} +\end{callout} + +Save the program in listing~\vref{src.prog.3} to file \filename{prog3.c} and +then compile and run it as shown in listing~\vref{scr.prog3}.% +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr3} + \begin{lstlisting}[language={}, basicstyle=\small\ttfamily, + label=scr.prog3, caption=Compiling and Running prog3] +% cc -o prog3 prog3.c -lelf @\co{1}@ +% ./prog3 prog3 @\co{2}@ +PHDR 0: + p_type 0x6 "PHDR" @\co{3}@ + p_offset 0x34 + p_vaddr 0x8048034 + p_paddr 0x8048034 + p_filesz 0xc0 + p_memsz 0xc0 + p_flags 0x5 [ execute read ] + p_align 0x4 +PHDR 1: + p_type 0x3 "INTERP" @\co{4}@ + p_offset 0xf4 + p_vaddr 0x80480f4 + p_paddr 0x80480f4 + p_filesz 0x15 + p_memsz 0x15 + p_flags 0x4 [ read ] + p_align 0x1 +PHDR 2: + p_type 0x1 "LOAD" @\co{5}@ + p_offset 0x0 + p_vaddr 0x8048000 + p_paddr 0x8048000 + p_filesz 0xe67 + p_memsz 0xe67 + p_flags 0x5 [ execute read ] + p_align 0x1000 +PHDR 3: + p_type 0x1 "LOAD" @\co{6}@ + p_offset 0xe68 + p_vaddr 0x8049e68 + p_paddr 0x8049e68 + p_filesz 0x11c + p_memsz 0x13c + p_flags 0x6 [ read write ] + p_align 0x1000 +PHDR 4: + p_type 0x2 "DYNAMIC" + p_offset 0xe78 + p_vaddr 0x8049e78 + p_paddr 0x8049e78 + p_filesz 0xb8 + p_memsz 0xb8 + p_flags 0x6 [ read write ] + p_align 0x4 +PHDR 5: + p_type 0x4 "NOTE" + p_offset 0x10c + p_vaddr 0x804810c + p_paddr 0x804810c + p_filesz 0x18 + p_memsz 0x18 + p_flags 0x4 [ read ] + p_align 0x4 + \end{lstlisting} + + \begin{description} + \item[\coref{1}] Compile and link the program with \library{libelf}, + as before. + \item[\coref{2}] We run our program on itself, and have it print out + its own program header table. This listing was generated on an + i386\trade machine running FreeBSD\makebox[0pt]{.}\trade + \item[\coref{3}] The very first entry of this particular program + header table describes the object's \elfdatastructure{Program + Header Table} itself.% + \index{program~header~table!self-description} + \item[\coref{4}] The program \tool{prog3} contains a header entry of + type \constant{PT\_INTERP} because it is dynamically linked. A + segment of type \constant{PT\_INTERP} contains the path name to + the ``interpreter'' that the kernel should use when executing the + program. This is usually the runtime loader (the file + \filename{/libexec/ld-elf.so.1} on FreeBSD systems). + \item[\coref{5} \coref{6}] This object contains two loadable + segments. The first segment requires execute and read permissions, + and the second read and write permissions. Both segments require + page (4096 byte) alignment.\index{segments!examples of} + \end{description} +\end{callout} + +You should try runing \tool{prog3} on other object files. + +\begin{itemize} +\item Try running \tool{prog3} on a relocatable object created by a + \tool{cc -c} invocation. Does this object have a program header + table? +\item Try running \tool{prog3} on a shared library. What does the + \elfdatastructure{Program Header Table} look like for a shared + library? +\item Can you find ELF objects on your system that contain program + header table entries of type \constant{PT\_TLS}? +\end{itemize} + +\chapter{Looking at Sections}\label{chap.elf-sections} + +Compilers and linkers view ELF objects differently than operating +systems do. These tools treat ELF files as a collection of ELF +\elfdatastructure{Sections}. + +An ELF \elfdatastructure{Section}\index{sections} is contiguous region +of an ELF object holding one kind of data. For example, an ELF +relocatable object could have sections with executable code, symbol +tables, code relocation entries, and so on.\index{sections!use~of} +Non-empty sections do not overlap in the ELF object. + +\section{The Section Header Table} + +The sections of an ELF object are described by a data structure known +as the ELF \elfdatastructure{Section Header Table}. The +\elfdatastructure{Section Header Table} is usually found at +the very end of the ELF object (see figure~\vref{fig.elf.layout}). +The \parameter{e\_shoff} member in the ELF +\elfdatastructure{Executable Header} for the object specifies the +location of the \elfdatastructure{Section Header Table}. + +Every ELF \elfdatastructure{Section} present in an ELF object is +described by an ELF \elfdatastructure{Section Header Table Entry} (see +table~\vref{src.elf.shdr}). Figure~\vref{fig.elf.shdrlayout} shows how +the fields of an ELF \elfdatastructure{Section Header Entry} specify +the section's placement within the ELF +object.\index{sections!placement in file} + +\begin{figure} + \begin{tikzpicture}[ + start chain=1 going right, + start chain=2 going below, + node distance=0pt, + ef/.style={ + on chain=1, + draw, + minimum height=1.4\baselineskip, + text centered + }, + sh/.style={ + on chain=2, + draw, + text width=6.2em, + fill=black!15, + font=\ttfamily + }] + + % Helper macros. + \def\l#1#2#3{ \draw[-] ([yshift=#2] #1) -- +(90:#3) } + \def\sz#1#2#3#4{ + \draw[<->] ([yshift=#3] #1) -- node [auto] {\small #4 } + ([yshift=#3] #2) + } + + % Draw a ELF object with a highlighted SHDR entry. + \node[on chain=1,text width=5 em] {ELF object}; + \node[ef,text width=4em,fill=black!10] (ehdr) {Ehdr}; + \node[ef,text width=4em] (g0) {}; + \node[ef,text width=5em,fill=black!10] (sec) + {Section${}_n$}; + \node[ef,text width=4em] (g1) {}; + \node[ef,text width=4em,fill=black!10] (shdr) {Shdr}; + \node[ef,text width=0.1ex,fill=black!25] (sh0) { }; + \node[ef,text width=1ex,fill=black!10] {}; + + % Draw the marks and label sizes and offsets. + \l{ehdr.south west}{-1pt}{-0.6cm}; + \l{sec.south west}{-1pt}{-0.6cm}; + \l{sec.north west}{1pt}{0.5cm}; + \l{sec.south east}{-1pt}{-0.6cm}; + + \node[above right=0.2cm and 0.4cm of sec.north west] {\%sh\_addralign} + edge [->,shorten >=1pt] ([yshift=0.25cm] sec.north west); + \sz{ehdr.south west}{sec.south west}{-0.55cm}{sh\_offset}; + \sz{sec.south west}{sec.south east}{-0.55cm}{sh\_size}; + + % Draw the expanded section header entry. + \node[sh,below=1cm of g1.south east] (shtop) {sh\_type}; + \node[sh] {sh\_size}; + \node[sh] {sh\_addralign}; + \node[sh] {sh\_offset}; + \node[sh,text centered] (shbot) {\dots}; + \node[below=1ex of shbot.south] {Section Header Table Entry}; + + % Draw the expansion lines. + \draw [-,shorten <=2pt] (shtop.north west) -- + ([yshift=-1.2pt] sh0.south west); + \draw [-,shorten <=2pt] (shbot.south east) -- + ([yshift=-1pt] sh0.south east); + \end{tikzpicture} + \caption{Section layout.}\label{fig.elf.shdrlayout} +\end{figure} + +\begin{callout}{shdr} + \begin{table}[H] + \begin{tabular}{rl|l} + \mbox{} & \tableheader{32 bit SHDR Table Entry} & + \tableheader{64 bit SHDR Table Entry} \\ \hline + & \verb+typedef struct {+ & \verb+typedef struct {+ \\ +\co{1} & \verb+ Elf32_Word sh_name;+& + \verb+ Elf64_Word sh_name;+\\ +\co{2} & \verb+ Elf32_Word sh_type;+& + \verb+ Elf64_Word sh_type;+\\ +\co{3} & \verb+ Elf32_Xword sh_flags;+& + \verb+ Elf64_Xword sh_flags;+\\ + & \verb+ Elf32_Addr sh_addr;+& + \verb+ Elf64_Addr sh_addr;+\\ + & \verb+ Elf32_Off sh_offset;+& + \verb+ Elf64_Off sh_offset;+\\ +\co{4} & \verb+ Elf32_Xword sh_size;+& + \verb+ Elf64_Xword sh_size;+\\ +\co{5} & \verb+ Elf32_Word sh_link;+& + \verb+ Elf64_Word sh_link;+\\ +\co{6} & \verb+ Elf32_Word sh_info;+& + \verb+ Elf64_Word sh_info;+\\ +\co{7} & \verb+ Elf32_Word sh_addralign;+& + \verb+ Elf64_Word sh_addralign;+\\ +\co{8} & \verb+ Elf32_Word sh_entsize;+& + \verb+ Elf64_Word sh_entsize;+\\ + & \verb+} Elf32_Shdr;+ & \verb+} Elf64_Shdr;+ \\ + \end{tabular} + \caption{ELF Section Header Table Entries.}\label{src.elf.shdr} + \end{table} + + \begin{description} + \item[\coref{1}] The \parameter{sh\_name} member encodes the + section's name.\index{sections!names} Because section names can be + of variable length, they are not kept in the section header table + entry itself.\index{sections!names!as offsets} Instead, all + section names are placed in a common ``section name string + table'', and the \parameter{sh\_name} member in the section header + entry stores the byte offset of the section's name in that string + table. The ELF \elfdatastructure{Executable Header} has an + \parameter{e\_shstrndx} member that contains the section index of + the section name string table itself.% + \index{sections!names!string~table} We will look at ELF string + tables in greater detail in section~\vref{sec.shdr.strtab}. + + \item[\coref{2}] The \parameter{sh\_type} member specifies the + section's type. Section types are defined by the + \code{SHT\_*} constants defined in the system's ELF headers. + For example, a section of type \constant{SHT\_PROGBITS} would + contain executable code, and a section of type + \constant{SHT\_SYMTAB} would hold a symbol + table.\index{sections!type} + + \item[\coref{3}] The flags field indicates whether the section has + specific properties; for example, whether it contains writable + data, whether it has special link ordering requirements, and so + on.\index{sections!flags} + + \item[\coref{4}] The \parameter{sh\_size} member specifies the size + of the section in bytes.\index{sections!size of} + + \item[\coref{5} \coref{6}] The \parameter{sh\_link} and + \parameter{sh\_info} members contain additional section-specific + information. We do not look at these members further in this + tutorial. + + \item[\coref{7}] For sections with specific alignment requirements, + the \parameter{sh\_addralign} member holds the required alignment. + Its value would be a power of two.\index{sections!alignment of} + + \item[\coref{8}] For sections that contain arrays of fixed-size + elements, the \parameter{sh\_entsize} member specifies the size of + each element.\index{section~header~table!entry size} + \end{description} +\end{callout} + + +There are a couple of quirks to keep mind when handling ELF sections: + +\begin{itemize} +\item First, the section header table entry at index `0' + (\constant{SHN\_UNDEF}) is special: it is always of type + \constant{SHT\_NULL}. When extended numbering is not in use this + entry has its members set to zero. When extended numbering is in + use, the fields of this entry could be non-zero; please see + section~\vref{sec.extended-numbering} for a discussion of extended + numbering.\index{sections!indices} + +\item Next, valid section indices range from \constant{SHN\_UNDEF} (0) + up to $\constant{SHN\_LORESERVE} - 1$ (0xFEFF). Section indices + between 0xFF00 (\constant{SHN\_LORESERVE}) and 0xFF\-FF + (\constant{SHN\_HIRESERVE}) have special meanings. If an ELF object + has more than 65279 (0xFEFF) sections, then it will need to use + extended section numbering.\index{sections!indices!valid~indices} +\end{itemize} + +\section{ELF Section Handling With \library{libelf}} + +The \library{libelf} library offers APIs to retrieve section header +table entries and the contents of sections.\footnote{We will cover the + adding new sections to ELF objects in + chapter~\vref{chap.creating-elf}.} These APIs take care of +translating between the in-file and in-memory representations of data +in the ELF object; your application can then directly work with the +in-memory representation of data.% +\index{object~representation!automatic translation} + +ELF sections are represented by \library{libelf} using a type named +\type{Elf\_Scn}. This type is meant to be opaque to application +code---the only way to allocate an \type{Elf\_Scn} is by calling one +of \library{libelf}'s APIs.\index{Elf\_Scn@\texttt{Elf\_Scn}!allocation}. + +Notable functions in the API that operate on sections include: + +\begin{itemize} +\item The function \function{elf\_getscn} retrieves section + information for a specified section index.% + \index{sections!retrieval} +\item The function \function{elf\_nextscn} is used to iterate through + the sections in the ELF object.\index{sections!iteration over}. +\item The function \function{gelf\_getshdr} retrieves the section + header table entry for a section.% + \index{section~header~table!retrieval of} +\item The functions \function{elf\_getdata} retrieves the contents of + the section. +\end{itemize} + +\begin{figure} + \begin{tikzpicture}[ + start chain=1 going right, + start chain=2 going right, + ed/.style={ + on chain=2, + rectangle, + rounded corners, + minimum height=1.2\baselineskip, + draw, + node distance=0.5cm, + fill=black!#1, + text centered + }, + eh/.style={ + on chain=1, + minimum width=4ex, + text height=\baselineskip, + draw + }] + + % Draw the ELF structure. + \begin{scope}[ + node distance=0pt + ] + \node[on chain=1] {ELF object}; + \node[eh,text width=10em] (s0) {}; + \node[eh,fill=black!10] (f0) {}; + \node[eh,fill=black!20] (f1) {}; + \node[eh,fill=black!10] (f2) {}; + \node[eh,fill=black!20] (f3) {}; + \node[eh,text width=10em] {}; + + % Highlight the border of the section. + \draw[-,thick] (f0.north west) -- (f3.north east) -- + (f3.south east) -- (f0.south west) -- cycle; + + % Label the section. + \node[below=.8cm of f0.south] + {Section contents.} edge [->] ([yshift=-2pt] f1.south east); + \end{scope} + + % Draw a linked list of descriptors. + \begin{scope}[ + node distance=1.3cm, + every join/.style={->,dashed}, + every on chain/.style={join} + ] + \node[ed=10,above=1cm and -1cm of s0.north] (d0) {D1}; + \node[ed=20] (d1) {D2}; + \node[ed=10] (d2) {D3}; + \node[ed=20] (d3) {D4}; + + \node[right=1ex of d3,text width=6em] + {List of \texttt{Elf\_Data} descriptors.}; + \end{scope} + + % Depict an Elf_Scn descriptor referencing the list of descriptors. + \node[above=0.7cm and -1cm of d0.north west,draw,rounded corners, + fill=black!20,text width=4em,text centered] + (scn) {\texttt{Elf\_Scn}}; + \node[right=1ex of scn] {An \texttt{Elf\_Scn} descriptor.}; + \draw[->,dashed,bend right] (scn) .. controls +(-0.75,-0.5) and + +(-0.75,0) .. (d0.west); + + % Link the Elf_Data descriptors to their section contents. + \foreach \s in {0,1,2,3} { + \draw[->] (d\s.south) .. controls +(0,-0.5) and +(0,0.5) + .. (f\s.north); + } + \end{tikzpicture} + \caption{Coverage of an ELF section by \texttt{Elf\_Scn} and + \texttt{Elf\_Data} descriptors.}\label{fig.elf.scn} +\end{figure} + +An \type{Elf\_Scn} descriptor is associated with zero or more +\type{Elf\_Data} descriptors. Each \type{Elf\_Data} descriptor +describes a region of application memory containing data for the ELF +section. Figure~\vref{fig.elf.scn} shows how the \type{Elf\_Data} +descriptors for an \type{Elf\_Scn} descriptor could cover the content +of a section.\index{sections!coverage by data descriptors} + +Listing~\vref{fig.elf.scn-data.decl} shows the C definition of the +\type{Elf\_Scn} and \type{Elf\_Data} types. + +\begin{callout}{data} + \begin{lstlisting}[caption=The \type{Elf\_Data} and \type{Elf\_Scn} types, + label=fig.elf.scn-data.decl, basicstyle=\small\ttfamily] +typedef struct _Elf_Scn Elf_Scn; @\co{1}@ +typedef struct _Elf_Data { + /* + * `Public' members that are part of the ELF(3) API. + */ + uint64_t d_align; @\co{2}@ + void *d_buf; @\co{3}@ + uint64_t d_off; @\co{4}@ + uint64_t d_size; @\co{5}@ + Elf_Type d_type; @\co{6}@ + unsigned int d_version; @\co{7}@ + /* ... other library-private fields ... */ +} Elf_Data; + \end{lstlisting} + + \begin{description} + \item[\coref{1}] The \type{Elf\_Scn} type is opaque to the + application. + \item[\coref{2}] The \parameter{d\_align} member specifies the + alignment of the data referenced in the \type{Elf\_Data} with + respect to its containing section.% + \index{Elf\_Data@\texttt{Elf\_Data}!alignment} + \item[\coref{3}] The \parameter{d\_buf} member points to a contiguous + region of application memory containing the section's data.% + \index{Elf\_Data@\texttt{Elf\_Data}!data pointer} + \item[\coref{4}] The \parameter{d\_off} member contains the file + offset from the start of the section for the data in this buffer. + \index{Elf\_Data@\texttt{Elf\_Data}!offset in section} + \item[\coref{5}] The \parameter{d\_size} member contains the size of + the memory buffer in bytes.% + \index{Elf\_Data@\texttt{Elf\_Data}!data size} + \item[\coref{6}] The \parameter{d\_type} member specifies the ELF + type of the data contained in the data buffer. Legal values for + this member are defined by the \type{Elf\_Type} + enumeration in the \filename{libelf.h} header file.% + \index{Elf\_Data@\texttt{Elf\_Data}!data type} + \item[\coref{7}] The \parameter{d\_version} member specifies the + working version for the data in this descriptor. It must be one + of the values supported by the \library{libelf} library.% + \index{Elf\_Data@\texttt{Elf\_Data}!descriptor version} + Please see chapter~\ref{chap.getting-started} for more information on + ELF version numbers. + \end{description} +\end{callout} + +Figure~\vref{fig.elf.data} shows how the members of the +\type{Elf\_Data} descriptor describe a region of application memory +containing section data. As seen in the figure, the in-memory +representation of this data might have a different size and different +endianness than its in-file +representation.\index{Elf\_Data@\texttt{Elf\_Data}!describing application + memory} + +\begin{figure} + \begin{tikzpicture}[ + eh/.style={ + text width=1.25cm, + text height=1.2cm, + draw + }] + + \node[text width=2cm,minimum height=1.5\baselineskip,font=\ttfamily, + draw,rounded corners,fill=black!10,text centered] + (data) {Elf\_Data}; + \node[node distance=0pt,right=of data] {An \texttt{Elf\_Data} descriptor}; + + % Draw the memory representation of the data. + \node[below right=2.3cm of data.south,text width=1.25cm,text height=2.5cm, + draw,fill=black!15] (mem) {}; + % .. and label it. + \node[below=1ex of mem.south] {Memory buffer}; + + % Place tick marks. + \coordinate (a0) at ([xshift=-0.3cm] mem.north west); + \coordinate (a1) at ([xshift=-0.3cm] mem.south west); + + \draw[-,shorten >=1pt] (a0) -- (mem.north west); + \draw[-,shorten >=1pt] (a1) -- (mem.south west); + \draw[<->,shorten >=1pt,shorten <=1pt] ([xshift=0.15cm] a0) -- + ([xshift=0.15cm] a1) node [midway,left] {d\_size}; + + % Link the Elf_Data descriptor to the memory buffer. + \draw[->,bend right=45,shorten >=1pt] (data) .. controls +(0,-2) + and +(-.5,0) .. (a0) node[left=1ex,midway] {d\_buf}; + + % Draw the ELF object. + \begin{scope}[ + node distance=0pt + ] + \node[eh,right=1.8cm of mem,fill=black!15] (e1) {}; + \node[eh,above=of e1] (e0) {}; + \node[eh,below=of e1] (e2) {}; + \end{scope} + + % Label the ELF object. + \node[below=1.5ex of e2.south] {A section in an ELF object.}; + + % Place tick marks and the d_align label. + \foreach \c in {0,1,2} { + \coordinate (b\c) at ([xshift=-.3cm] e\c.north west); + \draw[-,shorten >=1pt] (b\c) -- (e\c.north west); + }; + + \draw[-,shorten <=1pt] (e0.north east) -- +(.3cm,0); + \draw[-,shorten <=1pt] (e1.north east) -- +(.3cm,0) + node[right] {\%d\_align}; + + % Place other labels. + \node[right=2em of e0.east] {Start of the section.} + edge [->,shorten >=1pt] ([xshift=.3cm] e0.north east); + + \draw[<->,shorten >=1pt,shorten <=1pt] ([xshift=.15cm] b0) -- + ([xshift=.15cm] b1) node [midway,left] {d\_off}; + + \node[right=2em of e2.east,text width=8em] + {The file representation of the data in memory.} + edge [->] (e1.center); + + % Link the memory and file representations. + \draw[->,shorten >=1pt,shorten <=1pt] (mem.north east) .. controls +(1,0) + and +(-1,0) .. (b1); + \draw[->,shorten >=1pt,shorten <=1pt] (mem.south east) .. controls +(1,0) + and +(-1,0) .. (b2); + \end{tikzpicture} + \caption{How \type{Elf\_Data} descriptors work.}\label{fig.elf.data} +\end{figure} + +\section{ELF String Tables}\label{sec.shdr.strtab} + +ELF string tables hold variable length strings. Other ELF data +structures refer to the strings stored in these tables by using byte +offsets from the start of the string table. + +\begin{figure} + \begin{tikzpicture}[ + rectangle, + node distance=0pt, + minimum size=2.7em, + minimum width=3.3em, + inner sep=0pt, + se/.style={ + draw, + fill=black!5 + }, + so/.style={ + draw, + fill=black!10 + }] + + % Draw the string table. + \matrix [row sep=0pt, column sep=0pt] { + \node[se] (n0) {'\textbackslash 0'}; & \node[so] {'S'}; & + \node[se] {'t'}; & \node[so] {'r'}; & + \node[se] {'i'}; & \node[so] {'n'}; & + \node[se] {'g'}; & \node[so] {'1'}; & + \node[se] (n1) {'\textbackslash 0'}; & \node[so] {'S'}; \\ + \node[se] {'t'}; & \node[so] {'r'}; & + \node[se] {'i'}; & \node[so] {'n'}; & + \node[se] {'g' }; & \node[so] {'2'}; & + \node[se] (n2) {'\textbackslash 0'}; & \node[so] {$\cdots$}; & + \node[se] {$\cdots$}; & \node[so] (n3) {'\textbackslash 0' };\\ + }; + + % Add labels. + \def\N{\texttt{NUL}\xspace} + \node[above right=0.5cm of n0.north] {The initial \N byte} + edge [->,shorten >=1pt] (n0.north); + + \node[above right=0.4cm of n1.north] + {\N terminator} edge [->,shorten >=1pt] (n1.north); + + \node[below left=0.4cm of n2.south] {\N terminator} + edge [->,shorten >=1pt] (n2.south); + + \node[below left=1.5cm of n3.south] {The final \N byte} + edge [->,shorten >=1pt] (n3.south); + \end{tikzpicture} + \caption{String Table Layout.}\label{fig.elf.strtab} +\end{figure} + +Figure~\vref{fig.elf.strtab} shows the layout of a string table.% +\index{string~tables!layout} + +\begin{itemize} +\item The initial byte of a string table is \code{NUL} (a + `\(\backslash\)0'). This allows a byte offset value of zero to + denote the empty string. +\item Subsequent strings are separated by \code{NUL} bytes. +\item The final byte in the section is a \code{NUL}, in order to + \code{NUL}-terminate the last string in the string table. +\end{itemize} + +Sections containing string tables have section type +\constant{SHT\_STRTAB}. + +An ELF file can have multiple string tables. For example, the names of +the sections could be kept in a section name string table while the +names of program symbols could be kept in a symbol name string +table.\index{ELF!string tables} + +The \function{elf\_strptr} function in the \library{libelf} library +converts string table offsets into \code{char *} pointers usable by +C code.\index{string~tables!retrieval of strings} + +\section{Example: Listing Section Names} + +Let us now write an example program that prints the names of the +sections in an ELF object. + +\begin{callout}{prog4} + \lstinputlisting[caption=Program 4, label=src.prog.4]{prog4.txt} + + \begin{description} + \item[\coref{1}] The function \function{elf\_getshdrstrndx} + retrieves the section index of the section name string table. + Using this function allows our program to work correctly when + the object being examined uses extended + numbering.\index{sections!names!string~table}% + \index{extended~numbering!use of} + \item[\coref{2}] The function \function{elf\_nextscn} has the + useful property that it will return the pointer to the + \type{Elf\_Scn} descriptor for section number 1 if a NULL + pointer is passed in to it. Section number 0 is always of type + \constant{SHT\_NULL}, and is not for use by applications. + \item[\coref{3}] This \code{while} loop iterates through the + sections in the ELF object. Function \function{elf\_nextscn} + will return NULL after the last section has been traversed, + giving us a convenient way to exit the loop. + \item[\coref{4}] The function \function{gelf\_getshdr} retrieves + the section header table entry for an \type{Elf\_Scn} + descriptor. The \parameter{sh\_name} member of the returned + section header table entry holds the byte offset of the + section's name inside the section name string + table.\index{sections!header table entry} + \item[\coref{5}] The \function{elf\_strptr} function converts the + byte offset in the \parameter{sh\_name} member to a \code{char + *} pointer. The pointed-to C string can then be printed using + \code{printf}. + \item[\coref{6}] Next, the contents of the section name string + table itself are printed out. The call to \function{elf\_getscn} + returns the \type{Elf\_Scn} descriptor for the section name + string table itself.\index{sections!names!string~table} + \item[\coref{7}] This code cycles through the \type{Elf\_Data} + descriptors for the section, printing out the characters in each + \type{Elf\_Data} buffer for the section. + \end{description} +\end{callout} + +Save the program in listing~\vref{src.prog.4} to file +\filename{prog4.c} and then compile and run it as shown in +listing~\vref{scr.prog4}.% +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr4} + \newcommand{\at}{@} + \begin{lstlisting}[language={}, basicstyle=\small\ttfamily, + label=scr.prog4, caption=Compiling and Running prog4] +% cc -o prog4 prog4.c -lelf @\co{1}@ +% ./prog4 prog4 @\co{2}@ +Section 0001 .interp +Section 0002 .note.ABI-tag +Section 0003 .hash +Section 0004 .dynsym +Section 0005 .dynstr +Section 0006 .rela.plt +Section 0007 .init +Section 0008 .plt +Section 0009 .text +Section 0010 .fini +Section 0011 .rodata +Section 0012 .data +Section 0013 .eh_frame +Section 0014 .dynamic +Section 0015 .ctors +Section 0016 .dtors +Section 0017 .jcr +Section 0018 .got +Section 0019 .bss +Section 0020 .comment +Section 0021 .shstrtab @\co{3}@ +Section 0022 .symtab +Section 0023 .strtab +.shstrab: size=287 @\co{4}@ +\^@\at@ . s y m t a b \^@\at@ . s t r t a b +\^@\at@ . s h s t r t a b \^@\at@ . i n t e +r p \^@\at@ . h a s h \^@\at@ . d y n s y m +@\ldots{}\textit{etc}\ldots@ + \end{lstlisting} + + \begin{description} + \item[\coref{1}] Compile and link the program in the standard way. + \item[\coref{2}] The program is invoked on itself, to print the + names of its own sections. + \item[\coref{3}] The section name string table is called + \code{.shstrtab} by convention. + \item[\coref{4}] This is the content of the section name string + table in this object. + \end{description} +\end{callout} + +\chapter{Creating New ELF Objects}\label{chap.creating-elf} + +This chapter shows how to use the \library{libelf} library to create +new ELF objects.\index{ELF!creation~of} + +\section{Example: Creating an ELF Object} + +The example program in listing~\vref{src.prog.5} creates an ELF file +with the following content: + +\begin{itemize} +\item A section named ``\code{.foo}'' containing data in the form + of 32-bit words that may need byte-swapping. We had discussed + \library{libelf}'s handling of data needing byte-swapping in + section~\vref{sec.representations}. +\item A section named ``\code{.shstrtab}'' containing the section + name string table for our ELF object. We covered string tables + in section~\vref{sec.shdr.strtab}. +\item A \elfdatastructure{Program Header Table} with a single + \elfdatastructure{Program Header Table Entry} covering the program + header table itself. We studied the ELF \elfdatastructure{Program + Header Table} in chapter~\ref{chap.elf-phdr}. +\end{itemize} + +The new ELF object will be marked as a 32-bit PowerPC\trade +executable, and will use big-endian data ordering. + +\begin{callout}{prog5} + \lstinputlisting[caption=Program 5, label=src.prog.5]{prog5.txt} + + \begin{description} + \item[\coref{1}] The header file \filename{libelf.h} brings in function + prototypes for \library{libelf}'s functions. + + \item[\coref{2}] The \code{hash\_words} array holds 32-bit + words. The values in the array would need to be written using + big-endian byte ordering when the section is written to + file.\index{sections!hash~values} + + \item[\coref{3}] The \code{string\_table} array holds a + pre-fabricated string table containing the names of our two + sections, ``\code{.foo}'' and + ``\code{.shstrtab}''.\index{string~tables} + + \item[\coref{4}] The first step in creating a new ELF object is to + obtain a file descriptor opened for writing. + + \item[\coref{5}] The call to function \function{elf\_begin} + allocates an \type{Elf} handle. The parameter + \constant{ELF\_C\_WRITE} informs \library{libelf} of our intent to + create a brand new ELF object.\index{object~creation} + + \item[\coref{6}] The function \function{elf32\_newehdr} allocates an + ELF \elfdatastructure{Executable Header}. An + \elfdatastructure{Executable Header} is always needed for an ELF + object.\index{executable~header!allocation} + + The next few lines populate the executable header: + \begin{enumerate} + \item The \constant{EI\_DATA} byte in the \parameter{e\_ident} + member is set to the desired endianness (big-endian in our + case). + \item The machine type is set to the constant \constant{EM\_PPC}, + for the PowerPC\trade architecture. + \item The object is marked as an ELF executable. + \end{enumerate} + + The new ELF object will be a 32-bit object, since its + \elfdatastructure{Executable Header} had been allocated using the + 32-bit \function{elf32\_newehdr} function. + + \item[\coref{7}] The call to \function{elf\_newphdr} allocates an + ELF \elfdatastructure{Program Header Table} containing a single + entry. This entry is meant to cover the \elfdatastructure{Program + Header Table} itself. + + At this point in our program we do not know the file offset at + which the ELF \elfdatastructure{Program Header Table} will be + placed inside our new ELF object. This offset would only be known + after the object is laid out. We need to defer filling in our + program header table entry until \library{libelf} has computed an + object layout for us (please see step 11 below). + + \item[\coref{8}] The call to \function{elf\_newscn} allocates an + \type{Elf\_Scn} descriptor for the ELF section that will hold the + values in the \code{hash\_words} array. + + To actually associate data with our new section we allocate an + \type{Elf\_Data} descriptor and set its fields to map the + \code{hash\_words} array. + + A call to \function{elf32\_getshdr} then returns the + \elfdatastructure{Section Header Table Entry} for the new section. + + \begin{enumerate} + \item The type of the new section is set to \constant{SHT\_HASH}. + The \library{libelf} library knows how to byte-swap sections of + this type. + + \item The section is marked as containing content in the file by + setting its \parameter{sh\_flags} field to the constant + \constant{SHF\_ALLOC}. + \end{enumerate} + + \item[\coref{9}] The next call to \function{elf\_newscn} allocates + another section descriptor; this descriptor will be used for the + section name string table.\index{string~tables!allocation~of} The + code then allocates an \type{Elf\_Data} descriptor for this + section, and sets its members to map the pre-fabricated string + table in the array \code{string\_table}. + + The call to \function{elf32\_getshdr} retrieves the + \elfdatastructure{Section Header Table Entry} for this section. + The members of this section header table entry are set as follows: + + \begin{enumerate} + \item The type of the section is set to \constant{SHT\_STRTAB}, + the section type for string tables. + \item The section flags are set to indicate that the section + contains data in the file, and that it contains + \code{NUL}-terminated strings. + \end{enumerate} + + \item[\coref{10}] The function \function{elf\_ndxscn} retrieves the + section index for the string table section. The call to function + \function{elf\_setshstrndx} then sets the section name string + table index field in the ELF \elfdatastructure{Executable + Header}.\index{executable~header!section name string table} + + \item[\coref{11}] The call of the function \function{elf\_update} + with the parameter \constant{ELF\_C\_NULL} requests the + \library{libelf} library to compute a layout for an ELF object + without writing the object out.. + + After the call to \function{elf\_update} returns, the code + examines the ELF object's \elfdatastructure{Executable Header} to + determine where \library{libelf} had placed the object's + \elfdatastructure{Program Header Table}. It then updates the + \elfdatastructure{Program Header Table Entry} created in step 7 to + cover the program header table's file location. + + The call to function \function{elf\_flagdata} marks the + \elfdatastructure{Program Header Table} as having been modified.% + \index{executable~header!updating} + + \item[\coref{12}] Finally, the function \function{elf\_update} is + called with parameter \constant{ELF\_C\_WRITE} in order to write + the ELF object out to file.\index{object~creation!writing to + file} + + If this example program is run on a little-endian host the + \library{libelf} library will byte-swap the sections that need + byte-swapping when the ELF object is written out to file. + \end{description} +\end{callout} + +Save the program in listing~\vref{src.prog.5} to file +\filename{prog5.c} and then compile and run it as shown in +listing~\vref{scr.prog5}.% +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr5} + \begin{lstlisting}[language={}, basicstyle=\small\ttfamily, + label=scr.prog5, caption=Compiling and Running prog5] +% cc -o prog5 prog5.c -lelf @\co{1}@ +% ./prog5 foo +% file foo @\co{2}@ +foo: ELF 32-bit MSB executable, PowerPC or cisco 4500, \ + version 1 (SYSV), statically linked, stripped +% readelf -a foo @\co{3}@ +ELF Header: + Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 + Class: ELF32 + Data: 2's@\,@complement,@\,@big@\,@endian + Version: 1 (current) + OS/ABI: UNIX - System V + ABI Version: 0 + Type: EXEC (Executable file) + Machine: PowerPC + Version: 0x1 + Entry point address: 0x0 + Start of program headers: 52 (bytes into file) + Start of section headers: 112 (bytes into file) + Flags: 0x0 + Size of this header: 52 (bytes) + Size of program headers: 32 (bytes) + Number of program headers: 1 + Size of section headers: 40 (bytes) + Number of section headers: 3 + Section header string table index: 2 +@\ldots etc\ldots@ + \end{lstlisting} + + \begin{description} + \item[\coref{1}] Compile, link and run the program as in our + previous examples. + \item[\coref{2} \coref{3}] We can use the \tool{file} and + \tool{readelf} programs to examine the object that we have + created. + \end{description} +\end{callout} + +\section{Controlling ELF Layout}\label{sec.controlling-layout} +By default, the \library{libelf} library will lay out your ELF objects +for you. The default layout is shown in +figure~\vref{fig.elf.layout}.\index{object~creation!default~layout}% + +You can request fine-grained control over the ELF object's layout by +setting the \constant{ELF\_F\_LAYOUT} flag on its \type{Elf} +descriptor. This flag is set using the function \function{elf\_flagelf}.% +\index{object~creation!application control of layout} + +After setting the \constant{ELF\_F\_LAYOUT} flag on an \type{Elf} +descriptor, you can control the layout of the ELF object using the +following parameters: + +\begin{itemize} +\item You can set the values of the \parameter{e\_phoff} and + \parameter{e\_shoff} members of the \elfdatastructure{Executable + Header}. These values determine where the ELF + \elfdatastructure{Program Header Table} and + \elfdatastructure{Section Header Table} would be placed in the ELF + object. + +\item For each section you can set the \parameter{sh\_addralign}, + \parameter{sh\_offset}, and \parameter{sh\_size} members of the + section's header table entry. These members control the placement + of the section within the ELF object. +\end{itemize} + +These members must be set prior to calling the \function{elf\_update} +function. + +\section{Fill Characters} + +The \library{libelf} library will fill the gaps between the parts of +the ELF object with a fill character.\index{ELF!fill character} These +gaps may arise due to the alignment constraints on adjacent sections. + +You can set the fill character to use by calling the function +\function{elf\_fill} before calling \function{elf\_update}. The +default fill character is a zero byte.% +\index{object~creation!fill~character}% + +\section{Memory Ownership} + +Some of the APIs implemented by \library{libelf} return pointers to +memory arenas; other APIs accept pointers to memory arenas as input. +Knowing when you should (or should not) call \code{free()} on a +pointer is essential to avoid corrupting memory. + +The \library{libelf} library follows a simple rule: it will not free +data that it did not allocate. Conversely, it \emph{will} free memory +that it had allocated.% +\index{libelf@\texttt{libelf}!API!memory~management~rules} + +You should not free pointers returned by \library{libelf}, such as the +\code{Elf\_Scn *} pointers returned by calls to \function{elf\_getscn} +and the \code{Elf\_Data~*} pointers returned by calls to +\function{elf\_newdata}. Conversely, if you had allocated a memory +arena mapped by an \type{Elf\_Data} structure, then you should release +the arena once you are done with it. + + +\section{Data Structure Lifetimes} + +Many of \library{libelf}'s APIs return pointers to its internal data +structures. In objects opened for writing these pointers have a +limited lifetime---they are only valid up till the time the ELF object +is written out to file by a call to function \function{elf\_update}.% +\index{libelf@\texttt{libelf}!API!data structure refresh rules} + +This is because when \library{libelf} writes out an ELF object, it +releases and reallocates some of its internal bookkeeping structures. + +After calling function \function{elf\_update} with parameter +\constant{ELF\_C\_WRITE} you should treat any prior pointers returned +by \library{libelf}, such as pointers to \type{Elf\_Scn} and +\type{Elf\_Data} structures, as invalid. If you wish to continue +working with your ELF object, you should retrieve these pointers +afresh from \library{libelf}.% +\index{libelf@\texttt{libelf}!API!pointer validity} + +\section{Modifying Existing ELF Objects}\label{sec.modifying-elf} + +You can use the \library{libelf} library to modify existing ELF +objects. + +The process to update an ELF object is similar to that for creating +ELF objects, with the following +differences:\index{object~modification} + +\begin{itemize} +\item You would open the underlying file for both reading and writing, + i.e., with mode \code{O\_RDWR}. + +\item You would need an \type{Elf} descriptor that is valid for + updates. You can allocate a suitable descriptor by calling function + \function{elf\_begin} using the parameter \constant{ELF\_C\_RDWR}. + +\item You can use functions such as \function{elf\_newscn}, + \function{elf32\_newphdr} and \function{elf64\_newphdr} to add new + data structures to your object.% + \index{object~modification!adding new structures} + You can also retrieve existing ELF data structures in the file using + APIs such as those discussed in the previous chapters of this + tutorial. You can add new data to existing sections using the + function \function{elf\_newdata}. + +\item After you modify the fields of a data structure retrieved from + the ELF object, you should call the appropriate + \function{elf\_flag} functions to inform \library{libelf} about + your change.\index{object~modification!flagging modified data} +\end{itemize} + +A caution: when you update an ELF object, you should take care to +ensure that the resulting object remains a valid ELF object. For +example, if you move the sections of an ELF executable around, then +you should also keep the relevant offsets in its +\elfdatastructure{Program Header Table} entries updated. We will not +however explore this topic further in this introductory tutorial. + +\chapter{Processing \tool{ar} Archives}\label{chap.ar} + +During program development the \tool{ar} archiver is used to manage +``libraries'' of object files.\index{archive library} + +You can use the \library{libelf} library to read these archives. The +\library{libelf} library's APIs are however `read-only'---\tool{ar} +archives cannot be created or modified using these APIs.% +\footnote{The + \href{https://github.com/libarchive/libarchive/wiki}{\library{libarchive}} + library could be used instead to create or modify \tool{ar} + archives.} + +In this chapter we will build an example program that takes an +\tool{ar} archive as input and lists the names and sizes of the files +contained within it. + +\section{The Structure of \tool{ar} Archives} + +Every \tool{ar} archive starts with a signature sequence of 8 bytes +(please see the constant \constant{ARMAG}\index{ar~archive!magic} +defined in the system header \filename{ar.h}). The members of the +archive follow this signature. + +Figure~\vref{fig.arstr} shows the structure of an +\tool{ar} archive. + +\begin{figure} + \begin{tikzpicture}[ + file/.style={ % Boxes denoting archive content. + rectangle, + draw, + text centered, + text width=6.45em, + node distance=0pt, + minimum height=2em + }, + arhdr/.style={ % Boxes denoting archive headers. + rectangle, + draw, + fill=black!25, + node distance=0pt, + minimum height=2em, + minimum width=1ex, + inner sep=0pt + }, + lbl/.style={ % Styling of label text. + text height=1em + }, + hdr/.style={ + text width=4.2em, + draw, + fill=black!15, + node distance=0pt, + font=\ttfamily + }] + + % Depict the structure of the archive. + \node[arhdr,fill=black!50] (magic) {}; + \node[arhdr] (s0) [right=of magic] {}; + \node[file,text width=1.3em] (symtab) [right=of s0] {``/''}; + \node[arhdr] (s1) [right=of symtab] {}; + \node[file,text width=1.7em] (strtab) [right=of s1] {``$/\!/$''}; + \node[arhdr] (h0) [right=of strtab] {}; + \node[file] (f0) [right=of h0] {File 0}; + \node[arhdr] (h1) [right=of f0] {}; + \node[file] (f1) [right=of h1] {File 1}; + \node[arhdr] (h2) [right=of f1] {}; + \node[file] (f2) [right=of h2] {File 2}; + \node[arhdr] (h3) [right=of f2] {}; + \node[file,text width=1em] (f3) [right=of h3] {$\ldots$}; + + % Label the elements of the archive. + \node[lbl] (lmagic) [below=of magic,text height=1em] {archive ``magic''} + edge [->] ([yshift=-1pt] magic.south); + \node[lbl] (lheader) [below=of f0.south,text height=1em] {archive headers} + edge [->] ([yshift=-1pt] s0.south) + edge [->] ([yshift=-1pt] s1.south) + edge [->] ([yshift=-1pt] h0.south) + edge [->] ([yshift=-1pt] h1.south) + edge [->] ([yshift=-1.2pt] h2.south) + edge [->] ([yshift=-1.2pt] h3.south); + \node[lbl] (lsymtab) [above=5em of symtab.north] + {archive symbol table} + edge [->] ([yshift=1pt] symtab.north); + \node[lbl] (lstrtab) [above=3em of f0.north] + {archive string table} + edge [->] ([yshift=1pt] strtab.north); + + % Show the internal structure of an archive header. + \node[hdr] (arfmag) [above=2.2em of h2.north] + {\texttt{ar\_fmag}}; + \node[hdr] (arsize) [above=of arfmag.north] {ar\_size}; + \node[hdr] (armode) [above=of arsize.north] {ar\_mode}; + \node[hdr] (argid) [above=of armode.north] {ar\_gid}; + \node[hdr] (aruid) [above=of argid.north] {ar\_uid}; + \node[hdr] (ardate) [above=of aruid.north] {ar\_date}; + \node[hdr] (arname) [above=of ardate.north] {ar\_name}; + + % Draw "expansion" lines. + \draw[shorten >=1pt, shorten <=1pt] ([yshift=1.2pt] h1.north east) + to (arfmag.south west); + \draw[shorten >=1pt, shorten <=1pt] ([yshift=1pt] h1.north west) + to (arname.north west); + \end{tikzpicture} + \caption{The structure of \tool{ar} archives.}\label{fig.arstr} +\end{figure} + +\subsection{The Archive Header} + +Each member of an \tool{ar} archive is preceded by an archive +header\index{ar~archive!header} that describes the member's +attributes. The archive header is a collection of fixed-size ASCII +strings that resides at an even offset within the archive +file.\index{ar~archive!header!layout} Listing~\vref{src.arhdr} shows +the layout of the archive header as a C \code{struct}. + +\begin{lstlisting}[caption=Archive Header Layout, label=src.arhdr] +struct ar_hdr { + char ar_name[16]; /* file name */ + char ar_date[12]; /* file modification time */ + char ar_uid[6]; /* creator user id */ + char ar_gid[6]; /* creator group id */ + char ar_mode[8]; /* octal file permissions */ + char ar_size[10]; /* size in bytes */ +#define ARFMAG "`\n" + char ar_fmag[2]; /* consistency check */ +} __packed; +\end{lstlisting} + +\section{Special Archive Members} +The initial members of an \tool{ar} archive may be special: + +\begin{itemize} +\item An archive member with the name ``/'' is an archive symbol + table\index{ar~archive!symbol~table}. This symbol table maps + program symbols to archive members in the archive. It is usually + maintained by tools like \tool{ranlib} and \tool{ar}. + +\item An archive member with the name ``/\hskip-.2ex/'' is an archive + string table\index{ar~archive!string~table}. + + The \tool{ar} archive header can only contain fixed size ASCII + strings. Member file names that exceed the length limits of the + \parameter{ar\_name} archive header field would need to be placed in + a special string table.\footnote{Archive string tables are not to be + confused with ELF string tables. ELF string tables were examined + in section~\ref{sec.shdr.strtab}.} The \parameter{ar\_name} field + of the archive header would then hold the offset within the archive + string table of the real file name, encoded as a decimal + number.\index{ar~archive!long~file~names} +\end{itemize} + +\section{Archive Flavors} + +\tool{ar} archives come in two flavors mainly: BSD and SVR4. These +flavors are different in many respects---for example, SVR4 archives +use a `/' character to terminate file names in the archive header, +whereas BSD format archives use a ASCII space character as a +terminator. The way the two formats handle long file names is also +different. The archive handling APIs offered by the \library{libelf} +library will insulate your code from the differences between the +archive formats. + +\section{Archive Symbol Tables}\label{sec.ar.symtab} + +An archive symbol table helps linkers to quickly locate the ELF +objects in an archive. The BSD and SVR4 archive flavors have their own +archive symbol table formats. + +If an archive symbol table is present in an \tool{ar} archive, it will +be the archive's first member. + +\tool{ar} archive symbol tables are read using the function +\function{elf\_getarsym}.\index{ar~archive!symbol~table!retrieval of} +This function returns an array of \type{Elf\_Arsym} structures, where +each \type{Elf\_Arsym} structure maps a program symbol to a file +offset within the \tool{ar} archive. These file offsets can then be +used with the \function{elf\_rand} function to retrieve the ELF object +in question (please see section~\ref{sec.ar.random-access} below). + +Listing~\vref{fig.arsym} contains the C definition of an +\type{Elf\_Arsym} data type. + +\begin{lstlisting}[caption=The \type{Elf\_Arsym} structure, + label=fig.arsym, basicstyle=\small\ttfamily] +typedef struct { + off_t as_off; /* byte offset to member header */ + unsigned long as_hash; /* elf_hash() value for name */ + char *as_name; /* null terminated symbol name */ +} Elf_Arsym; +\end{lstlisting} + +\section{Random Archive Access Using \function{elf\_rand}} +\label{sec.ar.random-access} + +Instead of iterating over the members of an \tool{ar} archive in +sequence, you can also directly access specific members in the archive +using the \function{elf\_rand} +function.\index{ar~archive!random~access} + +This function configures the parent archive's \type{Elf} descriptor to +open the desired archive member on the next call to +\function{elf\_begin}. + +The \function{elf\_rand} function takes the file offset to an archive +header as its input parameter. This means that the function is only +useful when the file offset to the desired member's archive header is +already known. If an archive contains an archive symbol table +\index{ar~archive!symbol~table} then the function +\function{elf\_getarsym} could be used to retrieve the relevant file +offsets to its member's headers. + +The \function{elf\_getarsym} function was described in +section~\ref{sec.ar.symtab} above. + +\section{Example: Stepping Through an \filename{ar} Archive} + +Listing~\vref{src.prog.6} contains a program that traverses an +\tool{ar} archive, printing out the file names and byte sizes of its +members. + +\begin{figure}[h] + \begin{tikzpicture}[ + file/.style={ % Boxes denoting file content. + rectangle, + draw, + text centered, + text width=6.45em, + node distance=0pt, + minimum height=2em + }, + header/.style={ % Boxes denoting archive headers. + rectangle, + draw, + fill=black!25, + node distance=0pt, + minimum height=2em, + minimum width=1ex, + inner sep=0pt, + }, + lbl/.style={ % Styling of label text. + text height=1em + }] + + % Depict the structure of the archive pictorially. + \node[header,fill=black!50] (magic) {}; + \node[header] (s0) [right=of magic] {}; + \node[file,text width=1.3em] (symtab) [right=of s0] {``/''}; + \node[header] (s1) [right=of symtab] {}; + \node[file,text width=1.7em] (strtab) [right=of s1] {``$/\!/$''}; + \node[header] (h0) [right=of strtab] {}; + \node[file] (f0) [right=of h0] {File 0}; + \node[header] (h1) [right=of f0] {}; + \node[file] (f1) [right=of h1] {File 1}; + \node[header] (h2) [right=of f1] {}; + \node[file] (f2) [right=of h2] {File 2}; + \node[header] (h3) [right=of f2] {}; + \node[file,text width=1em] (f3) [right=of h3] {$\ldots$}; + + % Label the parts of the archive. + \node[lbl] (lmagic) [below=of magic,text height=1em] {archive ``magic''} + edge [->] ([yshift=-1pt] magic.south); + \node[lbl] (lheader) [below=of f0.south,text height=1em] {archive headers} + edge [->] ([yshift=-1pt] s0.south) + edge [->] ([yshift=-1pt] s1.south) + edge [->] ([yshift=-1pt] h0.south) + edge [->] ([yshift=-1pt] h1.south) + edge [->] ([yshift=-1.2pt] h2.south) + edge [->] ([yshift=-1.2pt] h3.south); + + % Label the contents retrieved by calls to elf_begin(). + \node[lbl] (eb0) [above=of f0.north west] {$\texttt{elf\_begin}_{(0)}$} + edge[->] ([yshift=1pt] f0.north west); + \node[lbl] (eb1) [above=of f1.north west] {$\texttt{elf\_begin}_{(1)}$} + edge [->] ([yshift=1pt] f1.north west); + \node[lbl] (eb2) [above=of f2.north west] {$\texttt{elf\_begin}_{(2)}$} + edge [->] ([yshift=1pt] f2.north west); + + % Show the traversal of the archive by elf_next(). + \draw[->,shorten >=1pt,shorten <=1pt,bend left] (h0.north east) to + node[auto] {$\texttt{elf\_next}_{(0)}$} (h1.north east); + \draw[->,shorten >=1pt,shorten <=1pt,bend left] (h1.north east) to + node[auto] {$\texttt{elf\_next}_{(1)}$} (h2.north east); + \draw[->,shorten >=1pt,shorten <=1pt,bend left] (h2.north east) to + node[auto] {$\texttt{elf\_next}_{(2)}$} (h3.north east); + \end{tikzpicture} + \caption{Iterating through \tool{ar} archives with + \function{elf\_begin} and \function{elf\_next}.}\label{fig.ariter} +\end{figure} + +\begin{callout}{prog6} + \lstinputlisting[caption=Program 6, label=src.prog.6]{prog6.txt} + + \begin{description} + \item[\coref{1}] The call to \code{open()} opens the archive for + reading. + \item[\coref{2}] The function \function{elf\_begin} is used to + obtain an \type{Elf} descriptor.\index{ar~archive!reading of} The + code then checks that \library{libelf} library has recognized the + file as an \tool{ar} archive. + + \item[\coref{3}] The call of \function{elf\_begin} returns a nested + \type{Elf} descriptor to an archive + member.\index{ELF!nested descriptors} The third + parameter passed to \function{elf\_begin} is a pointer to the + \type{Elf} descriptor for the archive itself. + + \item[\coref{4}] The function \function{elf\_getarhdr} retrieves the + archive header for the current archive member. This function + translates the (possibly encoded) file names in the archive header + to \code{NUL}-terminated strings suitable for use with + \code{printf}.\index{ar~archive!header!retrieval~of} + + Figure~\vref{fig.arhdr} shows the translated information returned + by the \function{elf\_getarhdr} function. + + \begin{lstlisting}[caption=The \type{Elf\_Arhdr} Structure, + label=fig.arhdr, basicstyle=\small\ttfamily] +typedef struct { + time_t ar_date; /* time of creation */ + char *ar_name; /* archive member name */ + gid_t ar_gid; /* creator's group */ + mode_t ar_mode; /* file creation mode */ + char *ar_rawname; /* 'raw' member name */ + size_t ar_size; /* member size in bytes */ + uid_t ar_uid; /* creator's user id */ +} Elf_Arhdr; + \end{lstlisting} + + The code then prints out the name and the size of the archive + member using the \parameter{ar\_name} and \parameter{ar\_size} + fields of the returned \type{Elf\_Arhdr} structure. + + \item[\coref{5}] The call of the \function{elf\_next} function sets + up the parent archive descriptor (held in the variable \code{ar} + in our example) to return the next archive member on a subsequent + call to function \function{elf\_begin}. + + The \function{elf\_next} function will return the value + \constant{ELF\_C\_READ} as long as the traversal of the archive + can continue. When called with a descriptor to the last member of + an archive the \function{elf\_next} function will return the value + \constant{ELF\_C\_NULL}. This value will cause the subsequent + call to function \function{elf\_begin} at step 3 to return + \code{NULL}, thereby terminating the loop. + + Figure \vref{fig.ariter} shows how the functions + \function{elf\_begin} and \function{elf\_next} work together to + step through an \tool{ar} archive.% + \index{ar~archive!sequential~access} + + \item[\coref{6}] The \function{elf\_end} function releases the + resources held by \type{Elf} descriptors. + \end{description} +\end{callout} + +Save the program in listing~\ref{src.prog.6} to a file named +\filename{prog6.c}, and compile and run it as shown. +\index{libelf@\texttt{libelf}!linking with} + +\begin{callout}{scr6} + \begin{lstlisting}[language={}, basicstyle=\small\ttfamily, + label=scr.prog6, caption=Compiling and Running prog6] +% cc -o prog6 prog6.c -lelf @\co{1}@ +% ./prog6 /usr/lib/librt.a @\co{2}@ + timer.o 7552 + mq.o 8980 + aio.o 8212 + sigev_thread.o 15528 + \end{lstlisting} + \begin{description} + \item[\coref{1}] We compile and link the program with \library{libelf}. + \item[\coref{2}] We run the program on an archive and obtain a + listing of the archive's contents. + \end{description} +\end{callout} + +\chapter{Conclusion}\label{chap.conclusion} + +This tutorial covered the following topics: +\begin{itemize} +\item We studied the basics of the ELF format. We looked at a few key + ELF data structures, and at their layout inside ELF objects. +\item We covered the facilities offered by the \library{libelf} + library for manipulating ELF objects. +\item We wrote example programs that retrieved and displayed the ELF + data structures present in a few ELF objects. +\item We studied how to create new ELF objects using the + \library{libelf} library. +\item We looked at how to read \tool{ar} archives using + \library{libelf}. +\end{itemize} + +\section{Further Reading} + +\index{ELF!further reading} + +\subsection{On the Web} +Peter Seebach's DeveloperWorks article ``\href{% +https://web.archive.org/web/20070224140341/http://www-128.ibm.com/developerworks/power/library/pa-spec12/% +}{An unsung hero: The hardworking ELF}'' covers the history and +features of the ELF format. Hongjiu Liu's ``\href{% +https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.8698}{ELF: +From The Programmer's Perspective}'' describes how to use the +features of ELF with GCC and GNU ld. The paper ``\href{% +http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.136.2517}{Extending +Sim286 to the Intel386 Architecture with 32-bit processing and Elf +Binary input} by Michael L. Haungs and Brian A. Malloy contains a +description of the ELF format in the chapter ``\href{% +https://web.archive.org/web/20071217235525/www.cs.ucdavis.edu/~haungs/paper/node10.html% +}{Executable and Linking Format (ELF)}''. + +Neelakanth Nadgir's tutorial ``\href{% +https://web.archive.org/web/20110926220119/http://developers.sun.com/solaris/articles/elf.html% +}{LibElf and GElf - A Library to Manipulate ELf Files}'' is a readable +introduction to the ELF(3) and GELF(3) APIs in Solaris\trade. + +\index{linking!books about}The +\href{https://docs.oracle.com/cd/E53394_01/html/E54813/index.html}{Linkers +and Libraries Guide} from Oracle\reg describes the linking and +loading tools present in Solaris\trade. Chapter 14 of this book, +titled ``Object File Format'', contains a readable introduction to the +ELF format. + +\subsection{More Example Programs} + +\index{libelf@\texttt{libelf}!additional examples} +The +\href{https://sourceforge.net/p/elftoolchain/code/HEAD/tree/trunk/}% +{source code for the tools} being developed at the +\elftoolchainproject at \href{https://sourceforge.net/}{SourceForge.Net} +show the use of the ELF(3)/GELF(3) APIs in useful programs. + +For readers looking for smaller programs to study, Emmanuel Azencot +offers a website with +\href{http://freemanu1.free.fr/elf_examples/index.html}{example + programs}. + +\subsection{Books} + +\index{linking!books about}John Levine's +``\href{https://linker.iecc.com/}{Linkers and Loaders}'' is a readable +book offering a overview of the process of linking and loading object +files. + +\subsection{Standards} + +\index{ELF!specification}The current specification of the ELF +format, the ``\href{https://refspecs.linuxbase.org/elf/elf.pdf}% +{Tool Interface Standard (TIS) Executable and Linking Format +(ELF) Specification, Version 1.2}'' is freely available to be +downloaded. + +\section{Getting Further Help} + +\index{getting help!mailing list}If you have further questions about +the use of \library{libelf}, please feel free to use our discussion +list: \texttt{elftoolchain-\-developers@lists.sourceforge.net}. + +\backmatter + +% Typeset an index. +\printindex +\end{document} diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog1.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog1.txt new file mode 100644 index 0000000000..44dc9edbc9 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog1.txt @@ -0,0 +1,58 @@ +/* + * Getting started with libelf. + * + * $Id: prog1.txt 2133 2011-11-10 08:28:22Z jkoshy $ + */ + +#include +#include +#include @\co{1}@ +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd; + Elf *e; @\co{2}@ + char *k; + Elf_Kind ek; @\co{3}@ + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) @\co{4}@ + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) + err(EXIT_FAILURE, "open \%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_READ@\co{5}@, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); @\co{6}@ + + ek = elf_kind(e); @\co{7}@ + + switch (ek) { + case ELF_K_AR: + k = "ar(1) archive"; + break; + case ELF_K_ELF: + k = "elf object"; + break; + case ELF_K_NONE: + k = "data"; + break; + default: + k = "unrecognized"; + } + + (void) printf("%s: %s\n", argv[1], k); + + (void) elf_end(e); @\co{8}@ + (void) close(fd); + + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog2.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog2.txt new file mode 100644 index 0000000000..344af08ad6 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog2.txt @@ -0,0 +1,102 @@ +/* + * Print the ELF Executable Header from an ELF object. + * + * $Id: prog2.txt 3830 2020-03-01 14:15:53Z jkoshy $ + */ + +#include +#include +#include @\co{1}@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int i, fd; + Elf *e; + char *id, bytes[5]; + size_t n; + GElf_Ehdr ehdr; @\co{2}@ + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) + err(EXIT_FAILURE, "open \"%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) @\co{3}@ + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EXIT_FAILURE, "\"%s\" is not an ELF object.", + argv[1]); + + if (gelf_getehdr(e, &ehdr) == NULL) @\co{4}@ + errx(EXIT_FAILURE, "getehdr() failed: %s.", + elf_errmsg(-1)); + + if ((i = gelf_getclass(e)) == ELFCLASSNONE) @\co{5}@ + errx(EXIT_FAILURE, "getclass() failed: %s.", + elf_errmsg(-1)); + + (void) printf("%s: %d-bit ELF object\n", argv[1], + i == ELFCLASS32 ? 32 : 64); + + if ((id = elf_getident(e, NULL)) == NULL) @\co{6}@ + errx(EXIT_FAILURE, "getident() failed: %s.", + elf_errmsg(-1)); + + (void) printf("%3s e_ident[0..%1d] %7s", " ", + EI_ABIVERSION, " "); + + for (i = 0; i <= EI_ABIVERSION; i++) { + (void) vis(bytes, id[i], VIS_WHITE, 0); + (void) printf(" ['%s' %X]", bytes, id[i]); + } + + (void) printf("\n"); + +#define PRINT_FMT " %-20s 0x%jx\n" +#define PRINT_FIELD(N) do { \ + (void) printf(PRINT_FMT, #N, (uintmax_t) ehdr.N); \ + } while (0) + + PRINT_FIELD(e_type); @\co{7}@ + PRINT_FIELD(e_machine); + PRINT_FIELD(e_version); + PRINT_FIELD(e_entry); + PRINT_FIELD(e_phoff); + PRINT_FIELD(e_shoff); + PRINT_FIELD(e_flags); + PRINT_FIELD(e_ehsize); + PRINT_FIELD(e_phentsize); + PRINT_FIELD(e_shentsize); + + if (elf_getshdrnum(e, &n) != 0) @\co{8}@ + errx(EXIT_FAILURE, "getshdrnum() failed: %s.", + elf_errmsg(-1)); + (void) printf(PRINT_FMT, "(shnum)", (uintmax_t) n); + + if (elf_getshdrstrndx(e, &n) != 0) @\co{9}@ + errx(EXIT_FAILURE, "getshdrstrndx() failed: %s.", + elf_errmsg(-1)); + (void) printf(PRINT_FMT, "(shstrndx)", (uintmax_t) n); + + if (elf_getphdrnum(e, &n) != 0) @\co{10}@ + errx(EXIT_FAILURE, "getphdrnum() failed: %s.", + elf_errmsg(-1)); + (void) printf(PRINT_FMT, "(phnum)", (uintmax_t) n); + + (void) elf_end(e); + (void) close(fd); + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog3.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog3.txt new file mode 100644 index 0000000000..40264ba64a --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog3.txt @@ -0,0 +1,101 @@ +/* + * Print the ELF Program Header Table in an ELF object. + * + * $Id: prog3.txt 3834 2020-03-03 21:40:31Z jkoshy $ + */ + +#include +#include +#include @\co{1}@ +#include +#include +#include +#include + +void +print_ptype(size_t pt) @\co{2}@ +{ + char *s; + +#define C(V) case PT_##V: s = #V; break + switch (pt) { + C(NULL); C(LOAD); C(DYNAMIC); + C(INTERP); C(NOTE); C(SHLIB); + C(PHDR); C(TLS); C(SUNW_UNWIND); + C(SUNWBSS); C(SUNWSTACK); C(SUNWDTRACE); + C(SUNWCAP); + default: + s = "unknown"; + break; + } + (void) printf(" \"%s\"", s); +#undef C +} + +int +main(int argc, char **argv) +{ + int i, fd; + Elf *e; + char *id, bytes[5]; + size_t n; + GElf_Phdr phdr; @\co{3}@ + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) + err(EXIT_FAILURE, "open \"%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EXIT_FAILURE, "\"%s\" is not an ELF object.", + argv[1]); + + if (elf_getphdrnum(e, &n) != 0) @\co{4}@ + errx(EXIT_FAILURE, "elf_getphdrnum() failed: %s.", + elf_errmsg(-1)); + + for (i = 0; i < n; i++) { @\co{5}@ + if (gelf_getphdr(e, i, &phdr) != &phdr) @\co{6}@ + errx(EXIT_FAILURE, "getphdr() failed: %s.", + elf_errmsg(-1)); + + (void) printf("PHDR %d:\n", i); +#define PRINT_FMT " %-20s 0x%jx" +#define PRINT_FIELD(N) do { \ + (void) printf(PRINT_FMT, #N, (uintmax_t) phdr.N); \ + } while (0) +#define NL() do { (void) printf("\n"); } while (0) + PRINT_FIELD(p_type); @\co{7}@ + print_ptype(phdr.p_type); NL(); + PRINT_FIELD(p_offset); NL(); + PRINT_FIELD(p_vaddr); NL(); + PRINT_FIELD(p_paddr); NL(); + PRINT_FIELD(p_filesz); NL(); + PRINT_FIELD(p_memsz); NL(); + PRINT_FIELD(p_flags); + (void) printf(" ["); + if (phdr.p_flags & PF_X) + (void) printf(" execute"); + if (phdr.p_flags & PF_R) + (void) printf(" read"); + if (phdr.p_flags & PF_W) + (void) printf(" write"); + printf(" ]"); NL(); + PRINT_FIELD(p_align); NL(); + } + + (void) elf_end(e); + (void) close(fd); + exit(EXIT_SUCCESS); +} + + diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog4.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog4.txt new file mode 100644 index 0000000000..919e4f5dc1 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog4.txt @@ -0,0 +1,92 @@ +/* + * Print the names of ELF sections. + * + * $Id: prog4.txt 3687 2019-02-22 07:55:09Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd; + Elf *e; + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + size_t n, shstrndx, sz; + char *name, *p, pc[(4 * sizeof(char)) + 1]; + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) + err(EXIT_FAILURE, "open \%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EXIT_FAILURE, "%s is not an ELF object.", + argv[1]); + + if (elf_getshdrstrndx(e, &shstrndx) != 0) @\co{1}@ + errx(EXIT_FAILURE, "elf_getshdrstrndx() failed: %s.", + elf_errmsg(-1)); + + scn = NULL; @\co{2}@ + while ((scn = elf_nextscn(e, scn)) != NULL) { @\co{3}@ + if (gelf_getshdr(scn, &shdr) != &shdr) @\co{4}@ + errx(EXIT_FAILURE, "getshdr() failed: %s.", + elf_errmsg(-1)); + + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) + == NULL) @\co{5}@ + errx(EXIT_FAILURE, "elf_strptr() failed: %s.", + elf_errmsg(-1)); + + (void) printf("Section %-4.4jd %s\n", (uintmax_t) + elf_ndxscn(scn), name); + } + + if ((scn = elf_getscn(e, shstrndx)) == NULL) @\co{6}@ + errx(EXIT_FAILURE, "getscn() failed: %s.", + elf_errmsg(-1)); + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EXIT_FAILURE, "getshdr(shstrndx) failed: %s.", + elf_errmsg(-1)); + + (void) printf(".shstrab: size=%jd\n", (uintmax_t) + shdr.sh_size); + + data = NULL; n = 0; + while (n < shdr.sh_size && + (data = elf_getdata(scn, data)) != NULL) { @\co{7}@ + p = (char *) data->d_buf; + while (p < (char *) data->d_buf + data->d_size) { + if (vis(pc, *p, VIS_WHITE, 0)) + printf("%s", pc); + n++; p++; + (void) putchar((n % 16) ? ' ' : '\n'); + } + } + (void) putchar('\n'); + + (void) elf_end(e); + (void) close(fd); + exit(EXIT_SUCCESS); +} + diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog5.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog5.txt new file mode 100644 index 0000000000..d44cf935fe --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog5.txt @@ -0,0 +1,133 @@ +/* + * Create an ELF object. + * + * $Id: prog5.txt 2133 2011-11-10 08:28:22Z jkoshy $ + */ + +#include +#include +#include @\co{1}@ +#include +#include +#include + +uint32_t hash_words[] = { @\co{2}@ + 0x01234567, + 0x89abcdef, + 0xdeadc0de +}; + +char string_table[] = { @\co{3}@ + /* Offset 0 */ '\0', + /* Offset 1 */ '.', 'f', 'o', 'o', '\0', + /* Offset 6 */ '.', 's', 'h', 's', 't', + 'r', 't', 'a', 'b', '\0' +}; + +int +main(int argc, char **argv) +{ + int fd; + Elf *e; + Elf_Scn *scn; + Elf_Data *data; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + Elf32_Shdr *shdr; + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_WRONLY|O_CREAT, 0777)) < 0) @\co{4}@ + err(EXIT_FAILURE, "open \%s\" failed", argv[1]); + + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) @\co{5}@ + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if ((ehdr = elf32_newehdr(e)) == NULL) @\co{6}@ + errx(EXIT_FAILURE, "elf32_newehdr() failed: %s.", + elf_errmsg(-1)); + + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_machine = EM_PPC; /* 32-bit PowerPC object */ + ehdr->e_type = ET_EXEC; + + if ((phdr = elf32_newphdr(e, 1)) == NULL) @\co{7}@ + errx(EXIT_FAILURE, "elf32_newphdr() failed: %s.", + elf_errmsg(-1)); + + if ((scn = elf_newscn(e)) == NULL) @\co{8}@ + errx(EXIT_FAILURE, "elf_newscn() failed: %s.", + elf_errmsg(-1)); + + if ((data = elf_newdata(scn)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + + data->d_align = 4; + data->d_off = 0LL; + data->d_buf = hash_words; + data->d_type = ELF_T_WORD; + data->d_size = sizeof(hash_words); + data->d_version = EV_CURRENT; + + if ((shdr = elf32_getshdr(scn)) == NULL) + errx(EXIT_FAILURE, "elf32_getshdr() failed: %s.", + elf_errmsg(-1)); + + shdr->sh_name = 1; + shdr->sh_type = SHT_HASH; + shdr->sh_flags = SHF_ALLOC; + shdr->sh_entsize = 0; + + if ((scn = elf_newscn(e)) == NULL) @\co{9}@ + errx(EXIT_FAILURE, "elf_newscn() failed: %s.", + elf_errmsg(-1)); + + if ((data = elf_newdata(scn)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + + data->d_align = 1; + data->d_buf = string_table; + data->d_off = 0LL; + data->d_size = sizeof(string_table); + data->d_type = ELF_T_BYTE; + data->d_version = EV_CURRENT; + + if ((shdr = elf32_getshdr(scn)) == NULL) + errx(EXIT_FAILURE, "elf32_getshdr() failed: %s.", + elf_errmsg(-1)); + + shdr->sh_name = 6; + shdr->sh_type = SHT_STRTAB; + shdr->sh_flags = SHF_STRINGS | SHF_ALLOC; + shdr->sh_entsize = 0; + + elf_setshstrndx(e, elf_ndxscn(scn)); @\co{10}@ + + if (elf_update(e, ELF_C_NULL) < 0) @\co{11}@ + errx(EXIT_FAILURE, "elf_update(NULL) failed: %s.", + elf_errmsg(-1)); + + phdr->p_type = PT_PHDR; + phdr->p_offset = ehdr->e_phoff; + phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT); + + (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); + + if (elf_update(e, ELF_C_WRITE) < 0) @\co{12}@ + errx(EXIT_FAILURE, "elf_update() failed: %s.", + elf_errmsg(-1)); + + (void) elf_end(e); + (void) close(fd); + + exit(EXIT_SUCCESS); +} + diff --git a/contrib/elftoolchain/documentation/libelf-by-example/prog6.txt b/contrib/elftoolchain/documentation/libelf-by-example/prog6.txt new file mode 100644 index 0000000000..c614d78ff0 --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/prog6.txt @@ -0,0 +1,56 @@ +/* + * Iterate through an ar(1) archive. + * + * $Id: prog6.txt 3840 2020-03-14 21:19:09Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd; + Elf *ar, *e; + Elf_Cmd cmd; + Elf_Arhdr *arh; + + if (argc != 2) + errx(EXIT_FAILURE, "usage: %s file-name", argv[0]); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization " + "failed: %s", elf_errmsg(-1)); + + if ((fd = open(argv[1], O_RDONLY, 0)) < 0) @\co{1}@ + err(EXIT_FAILURE, "open \%s\" failed", argv[1]); + + if ((ar = elf_begin(fd, ELF_C_READ, NULL)) == NULL) @\co{2}@ + errx(EXIT_FAILURE, "elf_begin() failed: %s.", + elf_errmsg(-1)); + + if (elf_kind(ar) != ELF_K_AR) + errx(EXIT_FAILURE, "%s is not an ar(1) archive.", + argv[1]); + + cmd = ELF_C_READ; + while ((e = elf_begin(fd, cmd, ar)) != NULL) { @\co{3}@ + if ((arh = elf_getarhdr(e)) == NULL) @\co{4}@ + errx(EXIT_FAILURE, "elf_getarhdr() failed: %s.", + elf_errmsg(-1)); + + (void) printf("%20s %zd\n", arh->ar_name, + arh->ar_size); + + cmd = elf_next(e); @\co{5}@ + (void) elf_end(e); @\co{6}@ + } + + (void) elf_end(ar); + (void) close(fd); + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/documentation/libelf-by-example/title-page-content.tex b/contrib/elftoolchain/documentation/libelf-by-example/title-page-content.tex new file mode 100644 index 0000000000..0f6d9e4a3a --- /dev/null +++ b/contrib/elftoolchain/documentation/libelf-by-example/title-page-content.tex @@ -0,0 +1,19 @@ +% A simple title page. +\pagestyle{empty} +\raggedleft + +\sffamily +\fontseries{b} + +\vspace*{\baselineskip} + +\fontsize{60}{64}\selectfont + +libelf \\[0.25\baselineskip] +by Example + +\vskip 0.55\textheight + +\fontsize{32}{36}\selectfont + +Joseph Koshy diff --git a/contrib/elftoolchain/elfcopy/Makefile b/contrib/elftoolchain/elfcopy/Makefile new file mode 100644 index 0000000000..ad9bdc0800 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/Makefile @@ -0,0 +1,58 @@ +# $Id: Makefile 4045 2024-07-08 12:36:29Z jkoshy $ + +TOP= .. + +.include "${TOP}/mk/elftoolchain.components.mk" + +PROG= elfcopy + +SRCS= archive.c ascii.c binary.c main.c sections.c segments.c \ + symbols.c + +WARNS?= 5 + +DPADD= ${LIBELF} ${LIBELFTC} +LDADD= -lelf -lelftc + +.if !defined(LIBELF_AR) +LDADD+= -larchive +.endif + +.if defined(WITH_PE) && ${WITH_PE} == "yes" +SRCS+= pe.c +CFLAGS+= -DWITH_PE=1 + +DPADD+= ${LIBPE} +LDADD+= -lpe +.endif + +MAN= elfcopy.1 mcs.1 strip.1 +MLINKS= elfcopy.1 objcopy.1 + +NO_SHARED?= yes + +LINKS= ${BINDIR}/elfcopy ${BINDIR}/mcs \ + ${BINDIR}/elfcopy ${BINDIR}/objcopy \ + ${BINDIR}/elfcopy ${BINDIR}/strip + +EXTRA_TARGETS= mcs strip objcopy + +TEST_FRAMEWORK= custom + +CLEANFILES+= ${EXTRA_TARGETS} + +# Create in-place symbolic links to "elfcopy" at build time. + +all: ${EXTRA_TARGETS} + +${EXTRA_TARGETS}: ${PROG} + ln -s ${PROG} ${.TARGET} + +.include "${TOP}/mk/elftoolchain.prog.mk" + +.if ${OS_HOST} == "OpenBSD" +CFLAGS+= -I/usr/local/include +LDFLAGS+= -L/usr/local/lib +.elif ${OS_HOST} == "DragonFly" +LDADD+= -lbz2 +.endif diff --git a/contrib/elftoolchain/elfcopy/archive.c b/contrib/elftoolchain/elfcopy/archive.c new file mode 100644 index 0000000000..7971fb9d3f --- /dev/null +++ b/contrib/elftoolchain/elfcopy/archive.c @@ -0,0 +1,541 @@ +/*- + * Copyright (c) 2007-2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#ifndef LIBELF_AR +#include +#include +#endif /* ! LIBELF_AR */ + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: archive.c 3919 2021-02-19 21:50:21Z jkoshy $"); + +#define _ARMAG_LEN 8 /* length of ar magic string */ +#define _ARHDR_LEN 60 /* length of ar header */ +#define _INIT_AS_CAP 128 /* initial archive string table size */ +#define _INIT_SYMOFF_CAP (256*(sizeof(uint32_t))) /* initial so table size */ +#define _INIT_SYMNAME_CAP 1024 /* initial sn table size */ +#define _MAXNAMELEN_SVR4 15 /* max member name length in svr4 variant */ + +#ifndef LIBELF_AR +static void ac_read_objs(struct elfcopy *ecp, int ifd); +static void ac_write_cleanup(struct elfcopy *ecp); +static void ac_write_data(struct archive *a, const void *buf, size_t s); +static void ac_write_objs(struct elfcopy *ecp, int ofd); +#endif /* ! LIBELF_AR */ +static void add_to_ar_str_table(struct elfcopy *elfcopy, const char *name); +static void add_to_ar_sym_table(struct elfcopy *ecp, const char *name); +static void extract_arsym(struct elfcopy *ecp); +static void process_ar_obj(struct elfcopy *ecp, struct ar_obj *obj); +static void sync_ar(struct elfcopy *ecp); + + +static void +process_ar_obj(struct elfcopy *ecp, struct ar_obj *obj) +{ + struct stat sb; + char *tempfile; + int fd; + + /* Output to a temporary file. */ + create_tempfile(NULL, &tempfile, &fd); + if ((ecp->eout = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + } + elf_flagelf(ecp->eout, ELF_C_SET, ELF_F_LAYOUT); + create_elf(ecp); + elf_end(ecp->ein); + elf_end(ecp->eout); + free(obj->buf); + obj->buf = NULL; + + /* Extract archive symbols. */ + if (lseek(fd, 0, SEEK_SET) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "lseek failed for '%s'", tempfile); + } + if ((ecp->eout = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + } + extract_arsym(ecp); + elf_end(ecp->eout); + + if (fstat(fd, &sb) == -1) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "fstat %s failed", tempfile); + } + if (lseek(fd, 0, SEEK_SET) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "lseek %s failed", tempfile); + } + obj->size = sb.st_size; + if ((obj->maddr = malloc(obj->size)) == NULL) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "memory allocation failed for '%s'", + tempfile); + } + if ((size_t) read(fd, obj->maddr, obj->size) != obj->size) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "read failed for '%s'", tempfile); + } + if (cleanup_tempfile(tempfile) < 0) + err(EXIT_FAILURE, "unlink %s failed", tempfile); + free(tempfile); + tempfile = NULL; + close(fd); + if (strlen(obj->name) > _MAXNAMELEN_SVR4) + add_to_ar_str_table(ecp, obj->name); + ecp->rela_off += _ARHDR_LEN + obj->size + obj->size % 2; + STAILQ_INSERT_TAIL(&ecp->v_arobj, obj, objs); +} + +/* + * Append to the archive string table buffer. + */ +static void +add_to_ar_str_table(struct elfcopy *ecp, const char *name) +{ + + if (ecp->as == NULL) { + ecp->as_cap = _INIT_AS_CAP; + ecp->as_sz = 0; + if ((ecp->as = malloc(ecp->as_cap)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + } + + /* + * The space required for holding one member name in as table includes: + * strlen(name) + (1 for '/') + (1 for '\n') + (possibly 1 for padding). + */ + while (ecp->as_sz + strlen(name) + 3 > ecp->as_cap) { + ecp->as_cap *= 2; + ecp->as = realloc(ecp->as, ecp->as_cap); + if (ecp->as == NULL) + err(EXIT_FAILURE, "realloc failed"); + } + strncpy(&ecp->as[ecp->as_sz], name, strlen(name)); + ecp->as_sz += strlen(name); + ecp->as[ecp->as_sz++] = '/'; + ecp->as[ecp->as_sz++] = '\n'; +} + +/* + * Append to the archive symbol table buffer. + */ +static void +add_to_ar_sym_table(struct elfcopy *ecp, const char *name) +{ + + if (ecp->s_so == NULL) { + if ((ecp->s_so = malloc(_INIT_SYMOFF_CAP)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + ecp->s_so_cap = _INIT_SYMOFF_CAP; + ecp->s_cnt = 0; + } + + if (ecp->s_sn == NULL) { + if ((ecp->s_sn = malloc(_INIT_SYMNAME_CAP)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + ecp->s_sn_cap = _INIT_SYMNAME_CAP; + ecp->s_sn_sz = 0; + } + + if (ecp->s_cnt * sizeof(uint32_t) >= ecp->s_so_cap) { + ecp->s_so_cap *= 2; + ecp->s_so = realloc(ecp->s_so, ecp->s_so_cap); + if (ecp->s_so == NULL) + err(EXIT_FAILURE, "realloc failed"); + } + ecp->s_so[ecp->s_cnt] = ecp->rela_off; + ecp->s_cnt++; + + /* + * The space required for holding one symbol name in sn table includes: + * strlen(name) + (1 for '\n') + (possibly 1 for padding). + */ + while (ecp->s_sn_sz + strlen(name) + 2 > ecp->s_sn_cap) { + ecp->s_sn_cap *= 2; + ecp->s_sn = realloc(ecp->s_sn, ecp->s_sn_cap); + if (ecp->s_sn == NULL) + err(EXIT_FAILURE, "realloc failed"); + } + memcpy(&ecp->s_sn[ecp->s_sn_sz], name, strlen(name)); + ecp->s_sn_sz += strlen(name); + ecp->s_sn[ecp->s_sn_sz++] = '\0'; +} + +static void +sync_ar(struct elfcopy *ecp) +{ + size_t s_sz; /* size of archive symbol table. */ + size_t pm_sz; /* size of pseudo members */ + int i; + + /* + * Pad the symbol name string table. It is treated specially because + * symbol name table should be padded by a '\0', not the common '\n' + * for other members. The size of sn table includes the pad bit. + */ + if (ecp->s_cnt != 0 && ecp->s_sn_sz % 2 != 0) + ecp->s_sn[ecp->s_sn_sz++] = '\0'; + + /* + * Archive string table is padded by a "\n" as the normal members. + * The difference is that the size of archive string table counts + * in the pad bit, while normal members' size fileds do not. + */ + if (ecp->as != NULL && ecp->as_sz % 2 != 0) + ecp->as[ecp->as_sz++] = '\n'; + + /* + * If there is a symbol table, calculate the size of pseudo members, + * convert previously stored relative offsets to absolute ones, and + * then make them Big Endian. + * + * absolute_offset = htobe32(relative_offset + size_of_pseudo_members) + */ + + if (ecp->s_cnt != 0) { + s_sz = (ecp->s_cnt + 1) * sizeof(uint32_t) + ecp->s_sn_sz; + pm_sz = _ARMAG_LEN + (_ARHDR_LEN + s_sz); + if (ecp->as != NULL) + pm_sz += _ARHDR_LEN + ecp->as_sz; + for (i = 0; (size_t)i < ecp->s_cnt; i++) + *(ecp->s_so + i) = htobe32(*(ecp->s_so + i) + + pm_sz); + } +} + +/* + * Extract global symbols from archive members. + */ +static void +extract_arsym(struct elfcopy *ecp) +{ + Elf_Scn *scn; + GElf_Shdr shdr; + GElf_Sym sym; + Elf_Data *data; + char *name; + size_t n, shstrndx; + int elferr, tabndx, len, i; + + if (elf_kind(ecp->eout) != ELF_K_ELF) { + warnx("internal: cannot extract symbols from non-elf object"); + return; + } + if (elf_getshstrndx(ecp->eout, &shstrndx) == 0) { + warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); + return; + } + + tabndx = -1; + scn = NULL; + while ((scn = elf_nextscn(ecp->eout, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) { + warnx("elf_getshdr failed: %s", elf_errmsg(-1)); + continue; + } + if ((name = elf_strptr(ecp->eout, shstrndx, shdr.sh_name)) == + NULL) { + warnx("elf_strptr failed: %s", elf_errmsg(-1)); + continue; + } + if (strcmp(name, ".strtab") == 0) { + tabndx = elf_ndxscn(scn); + break; + } + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + /* Ignore members without symbol table. */ + if (tabndx == -1) + return; + + scn = NULL; + while ((scn = elf_nextscn(ecp->eout, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) { + warnx("elf_getshdr failed: %s", elf_errmsg(-1)); + continue; + } + if (shdr.sh_type != SHT_SYMTAB) + continue; + + data = NULL; + n = 0; + while (n < shdr.sh_size && + (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getsym(data, i, &sym) != &sym) { + warnx("gelf_getsym failed: %s", + elf_errmsg(-1)); + continue; + } + + /* keep only global or weak symbols */ + if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL && + GELF_ST_BIND(sym.st_info) != STB_WEAK) + continue; + + /* keep only defined symbols */ + if (sym.st_shndx == SHN_UNDEF) + continue; + + if ((name = elf_strptr(ecp->eout, tabndx, + sym.st_name)) == NULL) { + warnx("elf_strptr failed: %s", + elf_errmsg(-1)); + continue; + } + + add_to_ar_sym_table(ecp, name); + } + } + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); +} + +#ifndef LIBELF_AR + +/* + * Convenient wrapper for general libarchive error handling. + */ +#define AC(CALL) do { \ + if ((CALL)) \ + errx(EXIT_FAILURE, "%s", archive_error_string(a)); \ +} while (0) + +/* Earlier versions of libarchive had some functions that returned 'void'. */ +#if ARCHIVE_VERSION_NUMBER >= 2000000 +#define ACV(CALL) AC(CALL) +#else +#define ACV(CALL) do { \ + (CALL); \ + } while (0) +#endif + +int +ac_detect_ar(int ifd) +{ + struct archive *a; + struct archive_entry *entry; + int r; + + r = -1; + if ((a = archive_read_new()) == NULL) + return (0); + archive_read_support_format_ar(a); + if (archive_read_open_fd(a, ifd, 10240) == ARCHIVE_OK) + r = archive_read_next_header(a, &entry); + archive_read_close(a); + archive_read_free(a); + + return (r == ARCHIVE_OK); +} + +void +ac_create_ar(struct elfcopy *ecp, int ifd, int ofd) +{ + + ac_read_objs(ecp, ifd); + sync_ar(ecp); + ac_write_objs(ecp, ofd); + ac_write_cleanup(ecp); +} + +static void +ac_read_objs(struct elfcopy *ecp, int ifd) +{ + struct archive *a; + struct archive_entry *entry; + struct ar_obj *obj; + const char *name; + char *buff; + size_t size; + int r; + + ecp->rela_off = 0; + if (lseek(ifd, 0, SEEK_SET) == -1) + err(EXIT_FAILURE, "lseek failed"); + if ((a = archive_read_new()) == NULL) + errx(EXIT_FAILURE, "archive_read_new failed"); + archive_read_support_format_ar(a); + AC(archive_read_open_fd(a, ifd, 10240)); + for(;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_FATAL) + errx(EXIT_FAILURE, "%s", archive_error_string(a)); + if (r == ARCHIVE_EOF) + break; + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) + warnx("%s", archive_error_string(a)); + if (r == ARCHIVE_RETRY) + continue; + + name = archive_entry_pathname(entry); + + /* skip pseudo members. */ + if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0) + continue; + + size = archive_entry_size(entry); + + if (size > 0) { + if ((buff = malloc(size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if (archive_read_data(a, buff, size) != (ssize_t)size) { + warnx("%s", archive_error_string(a)); + free(buff); + continue; + } + if ((obj = malloc(sizeof(*obj))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if ((obj->name = strdup(name)) == NULL) + err(EXIT_FAILURE, "strdup failed"); + obj->buf = buff; + obj->uid = archive_entry_uid(entry); + obj->gid = archive_entry_gid(entry); + obj->md = archive_entry_mode(entry); + obj->mtime = archive_entry_mtime(entry); + if ((ecp->ein = elf_memory(buff, size)) == NULL) + errx(EXIT_FAILURE, "elf_memory() failed: %s", + elf_errmsg(-1)); + if (elf_kind(ecp->ein) != ELF_K_ELF) + errx(EXIT_FAILURE, + "file format not recognized"); + process_ar_obj(ecp, obj); + } + } + AC(archive_read_close(a)); + ACV(archive_read_free(a)); +} + +static void +ac_write_objs(struct elfcopy *ecp, int ofd) +{ + struct archive *a; + struct archive_entry *entry; + struct ar_obj *obj; + time_t timestamp; + int nr; + + if ((a = archive_write_new()) == NULL) + errx(EXIT_FAILURE, "archive_write_new failed"); + archive_write_set_format_ar_svr4(a); + AC(archive_write_open_fd(a, ofd)); + + /* Write the archive symbol table, even if it's empty. */ + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, "/"); + if (elftc_timestamp(×tamp) != 0) + err(EXIT_FAILURE, "elftc_timestamp"); + archive_entry_set_mtime(entry, timestamp, 0); + archive_entry_set_size(entry, (ecp->s_cnt + 1) * sizeof(uint32_t) + + ecp->s_sn_sz); + AC(archive_write_header(a, entry)); + nr = htobe32(ecp->s_cnt); + ac_write_data(a, &nr, sizeof(uint32_t)); + ac_write_data(a, ecp->s_so, sizeof(uint32_t) * ecp->s_cnt); + ac_write_data(a, ecp->s_sn, ecp->s_sn_sz); + archive_entry_free(entry); + + /* Write the archive string table, if exist. */ + if (ecp->as != NULL) { + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, "//"); + archive_entry_set_size(entry, ecp->as_sz); + AC(archive_write_header(a, entry)); + ac_write_data(a, ecp->as, ecp->as_sz); + archive_entry_free(entry); + } + + /* Write normal members. */ + STAILQ_FOREACH(obj, &ecp->v_arobj, objs) { + entry = archive_entry_new(); + archive_entry_copy_pathname(entry, obj->name); + archive_entry_set_uid(entry, obj->uid); + archive_entry_set_gid(entry, obj->gid); + archive_entry_set_mode(entry, obj->md); + archive_entry_set_size(entry, obj->size); + archive_entry_set_mtime(entry, obj->mtime, 0); + archive_entry_set_filetype(entry, AE_IFREG); + AC(archive_write_header(a, entry)); + ac_write_data(a, obj->maddr, obj->size); + archive_entry_free(entry); + } + + AC(archive_write_close(a)); + ACV(archive_write_free(a)); +} + +static void +ac_write_cleanup(struct elfcopy *ecp) +{ + struct ar_obj *obj, *obj_temp; + + STAILQ_FOREACH_SAFE(obj, &ecp->v_arobj, objs, obj_temp) { + STAILQ_REMOVE(&ecp->v_arobj, obj, ar_obj, objs); + if (obj->maddr != NULL) + free(obj->maddr); + free(obj->name); + free(obj); + } + + free(ecp->as); + free(ecp->s_so); + free(ecp->s_sn); + ecp->as = NULL; + ecp->s_so = NULL; + ecp->s_sn = NULL; +} + +/* + * Wrapper for archive_write_data(). + */ +static void +ac_write_data(struct archive *a, const void *buf, size_t s) +{ + if (archive_write_data(a, buf, s) != (ssize_t)s) + errx(EXIT_FAILURE, "%s", archive_error_string(a)); +} + +#endif /* ! LIBELF_AR */ diff --git a/contrib/elftoolchain/elfcopy/ascii.c b/contrib/elftoolchain/elfcopy/ascii.c new file mode 100644 index 0000000000..caa2ada1dd --- /dev/null +++ b/contrib/elftoolchain/elfcopy/ascii.c @@ -0,0 +1,1073 @@ +/*- + * Copyright (c) 2010,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: ascii.c 3757 2019-06-28 01:15:28Z emaste $"); + +static void append_data(struct section *s, const void *buf, size_t sz); +static char hex_digit(uint8_t n); +static int hex_value(int x); +static void finalize_data_section(struct section *s); +static int ishexdigit(int x); +static int ihex_read(const char *line, char *type, uint64_t *addr, + uint64_t *num, uint8_t *data, size_t *sz); +static void ihex_write(int ofd, int type, uint64_t addr, uint64_t num, + const void *buf, size_t sz); +static void ihex_write_00(int ofd, uint64_t addr, const void *buf, size_t sz); +static void ihex_write_01(int ofd); +static void ihex_write_04(int ofd, uint16_t addr); +static void ihex_write_05(int ofd, uint64_t e_entry); +static struct section *new_data_section(struct elfcopy *ecp, int sec_index, + uint64_t off, uint64_t addr); +static int read_num(const char *line, int *len, uint64_t *num, size_t sz, + int *checksum); +static int srec_read(const char *line, char *type, uint64_t *addr, + uint8_t *data, size_t *sz); +static void srec_write(int ofd, char type, uint64_t addr, const void *buf, + size_t sz); +static void srec_write_symtab(int ofd, const char *ofn, Elf *e, Elf_Scn *scn, + GElf_Shdr *sh); +static void srec_write_S0(int ofd, const char *ofn); +static void srec_write_Sd(int ofd, char dr, uint64_t addr, const void *buf, + size_t sz, size_t rlen); +static void srec_write_Se(int ofd, uint64_t e_entry, int forceS3); +static void write_num(char *line, int *len, uint64_t num, size_t sz, + int *checksum); + +#define _LINE_BUFSZ 1024 +#define _DATA_BUFSZ 256 + +/* + * Convert ELF object to S-Record. + */ +void +create_srec(struct elfcopy *ecp, int ifd, int ofd, const char *ofn) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Ehdr eh; + GElf_Shdr sh; + uint64_t max_addr; + size_t rlen; + int elferr, addr_sz; + char dr; + + if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + /* Output a symbol table for `symbolsrec' target. */ + if (!strncmp(ecp->otgt, "symbolsrec", strlen("symbolsrec"))) { + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", + elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if (sh.sh_type != SHT_SYMTAB) + continue; + srec_write_symtab(ofd, ofn, e, scn, &sh); + break; + } + } + + if (ecp->flags & SREC_FORCE_S3) + dr = '3'; + else { + /* + * Find maximum address size in the first iteration. + */ + max_addr = 0; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", + elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((sh.sh_flags & SHF_ALLOC) == 0 || + sh.sh_type == SHT_NOBITS || + sh.sh_size == 0) + continue; + if ((uint64_t) sh.sh_addr > max_addr) + max_addr = sh.sh_addr; + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + if (max_addr <= 0xFFFF) + dr = '1'; + else if (max_addr <= 0xFFFFFF) + dr = '2'; + else + dr = '3'; + } + + if (ecp->flags & SREC_FORCE_LEN) { + addr_sz = dr - '0' + 1; + if (ecp->srec_len < 1) + rlen = 1; + else if (ecp->srec_len + addr_sz + 1 > 255) + rlen = 255 - (addr_sz + 1); + else + rlen = ecp->srec_len; + } else + rlen = 16; + + /* Generate S0 record which contains the output filename. */ + srec_write_S0(ofd, ofn); + + /* Generate S{1,2,3} data records for section data. */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((sh.sh_flags & SHF_ALLOC) == 0 || + sh.sh_type == SHT_NOBITS || + sh.sh_size == 0) + continue; + if (sh.sh_addr > 0xFFFFFFFF) { + warnx("address space too big for S-Record file"); + continue; + } + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + continue; + } + if (d->d_buf == NULL || d->d_size == 0) + continue; + srec_write_Sd(ofd, dr, sh.sh_addr, d->d_buf, d->d_size, rlen); + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + /* Generate S{7,8,9} end of block record. */ + if (gelf_getehdr(e, &eh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + srec_write_Se(ofd, eh.e_entry, ecp->flags & SREC_FORCE_S3); +} + +void +create_elf_from_srec(struct elfcopy *ecp, int ifd) +{ + char line[_LINE_BUFSZ], name[_LINE_BUFSZ]; + uint8_t data[_DATA_BUFSZ]; + GElf_Ehdr oeh; + struct section *s, *shtab; + FILE *ifp; + uint64_t addr, entry, off, sec_addr; + uintmax_t st_value; + size_t sz; + int _ifd, first, sec_index, in_symtab, symtab_created; + char *rlt; + char type; + + if ((_ifd = dup(ifd)) < 0) + err(EXIT_FAILURE, "dup failed"); + if ((ifp = fdopen(_ifd, "r")) == NULL) + err(EXIT_FAILURE, "fdopen failed"); + + /* Create EHDR for output .o file. */ + if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) + errx(EXIT_FAILURE, "gelf_newehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Initialise e_ident fields. */ + oeh.e_ident[EI_CLASS] = ecp->oec; + oeh.e_ident[EI_DATA] = ecp->oed; + /* + * TODO: Set OSABI according to the OS platform where elfcopy(1) + * was build. (probably) + */ + oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; + oeh.e_machine = ecp->oem; + oeh.e_type = ET_REL; + oeh.e_entry = 0; + + ecp->flags |= RELOCATABLE; + + /* Create .shstrtab section */ + init_shstrtab(ecp); + ecp->shstrtab->off = 0; + + /* Data sections are inserted after EHDR. */ + off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); + if (off == 0) + errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); + + /* Create data sections. */ + s = NULL; + first = 1; + sec_index = 1; + sec_addr = entry = 0; + while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { + sz = 0; + if (line[0] == '\r' || line[0] == '\n') + continue; + if (line[0] == '$' && line[1] == '$') { + ecp->flags |= SYMTAB_EXIST; + while ((rlt = fgets(line, _LINE_BUFSZ, ifp)) != NULL) { + if (line[0] == '$' && line[1] == '$') + break; + } + if (rlt == NULL) + break; + continue; + } + if (line[0] != 'S' || line[1] < '0' || line[1] > '9') { + warnx("Invalid srec record"); + continue; + } + if (srec_read(line, &type, &addr, data, &sz) < 0) { + warnx("Invalid srec record or mismatched checksum"); + continue; + } + switch (type) { + case '1': + case '2': + case '3': + if (sz == 0) + break; + if (first || sec_addr != addr) { + if (s != NULL) + finalize_data_section(s); + s = new_data_section(ecp, sec_index, off, + addr); + if (s == NULL) { + warnx("new_data_section failed"); + break; + } + sec_index++; + sec_addr = addr; + first = 0; + } + append_data(s, data, sz); + off += sz; + sec_addr += sz; + break; + case '7': + case '8': + case '9': + entry = addr; + break; + default: + break; + } + } + if (s != NULL) + finalize_data_section(s); + if (ferror(ifp)) + warn("fgets failed"); + + /* Insert .shstrtab after data sections. */ + if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + insert_to_sec_list(ecp, ecp->shstrtab, 1); + + /* Insert section header table here. */ + shtab = insert_shtab(ecp, 1); + + /* + * Rescan and create symbol table if we found '$$' section in + * the first scan. + */ + symtab_created = 0; + in_symtab = 0; + if (ecp->flags & SYMTAB_EXIST) { + if (fseek(ifp, 0, SEEK_SET) < 0) { + warn("fseek failed"); + ecp->flags &= ~SYMTAB_EXIST; + goto done; + } + while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { + if (in_symtab) { + if (line[0] == '$' && line[1] == '$') { + in_symtab = 0; + continue; + } + if (sscanf(line, "%s $%jx", name, + &st_value) != 2) { + warnx("Invalid symbolsrec record"); + continue; + } + if (!symtab_created) { + create_external_symtab(ecp); + symtab_created = 1; + } + add_to_symtab(ecp, name, st_value, 0, SHN_ABS, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); + } + if (line[0] == '$' && line[1] == '$') { + in_symtab = 1; + continue; + } + } + } + if (ferror(ifp)) + warn("fgets failed"); + if (symtab_created) { + finalize_external_symtab(ecp); + create_symtab_data(ecp); + /* Count in .symtab and .strtab section headers. */ + shtab->sz += gelf_fsize(ecp->eout, ELF_T_SHDR, 2, EV_CURRENT); + } else + ecp->flags &= ~SYMTAB_EXIST; + +done: + fclose(ifp); + + /* Set entry point. */ + oeh.e_entry = entry; + + /* + * Write the underlying ehdr. Note that it should be called + * before elf_setshstrndx() since it will overwrite e->e_shstrndx. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Update sh_name pointer for each section header entry. */ + update_shdr(ecp, 0); + + /* Renew oeh to get the updated e_shstrndx. */ + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Resync section offsets. */ + resync_sections(ecp); + + /* Store SHDR offset in EHDR. */ + oeh.e_shoff = shtab->off; + + /* Update ehdr since we modified e_shoff. */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Write out the output elf object. */ + if (elf_update(ecp->eout, ELF_C_WRITE) < 0) + errx(EXIT_FAILURE, "elf_update() failed: %s", + elf_errmsg(-1)); + + /* Release allocated resource. */ + free_elf(ecp); +} + +void +create_ihex(int ifd, int ofd) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Ehdr eh; + GElf_Shdr sh; + int elferr; + uint16_t addr_hi, old_addr_hi; + + if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + old_addr_hi = 0; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((sh.sh_flags & SHF_ALLOC) == 0 || + sh.sh_type == SHT_NOBITS || + sh.sh_size == 0) + continue; + if (sh.sh_addr > 0xFFFFFFFF) { + warnx("address space too big for Intel Hex file"); + continue; + } + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + continue; + } + if (d->d_buf == NULL || d->d_size == 0) + continue; + addr_hi = (sh.sh_addr >> 16) & 0xFFFF; + if (addr_hi > 0 && addr_hi != old_addr_hi) { + /* Write 04 record if addr_hi is new. */ + old_addr_hi = addr_hi; + ihex_write_04(ofd, addr_hi); + } + ihex_write_00(ofd, sh.sh_addr, d->d_buf, d->d_size); + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + if (gelf_getehdr(e, &eh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + ihex_write_05(ofd, eh.e_entry); + ihex_write_01(ofd); +} + +void +create_elf_from_ihex(struct elfcopy *ecp, int ifd) +{ + char line[_LINE_BUFSZ]; + uint8_t data[_DATA_BUFSZ]; + GElf_Ehdr oeh; + struct section *s, *shtab; + FILE *ifp; + uint64_t addr, addr_base, entry, num, off, rec_addr, sec_addr; + size_t sz; + int _ifd, first, sec_index; + char type; + + if ((_ifd = dup(ifd)) < 0) + err(EXIT_FAILURE, "dup failed"); + if ((ifp = fdopen(_ifd, "r")) == NULL) + err(EXIT_FAILURE, "fdopen failed"); + + /* Create EHDR for output .o file. */ + if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) + errx(EXIT_FAILURE, "gelf_newehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Initialise e_ident fields. */ + oeh.e_ident[EI_CLASS] = ecp->oec; + oeh.e_ident[EI_DATA] = ecp->oed; + /* + * TODO: Set OSABI according to the OS platform where elfcopy(1) + * was build. (probably) + */ + oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; + oeh.e_machine = ecp->oem; + oeh.e_type = ET_REL; + oeh.e_entry = 0; + + ecp->flags |= RELOCATABLE; + + /* Create .shstrtab section */ + init_shstrtab(ecp); + ecp->shstrtab->off = 0; + + /* Data sections are inserted after EHDR. */ + off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); + if (off == 0) + errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); + + /* Create data sections. */ + s = NULL; + first = 1; + sec_index = 1; + addr_base = rec_addr = sec_addr = entry = 0; + while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { + if (line[0] == '\r' || line[0] == '\n') + continue; + if (line[0] != ':') { + warnx("Invalid ihex record"); + continue; + } + if (ihex_read(line, &type, &addr, &num, data, &sz) < 0) { + warnx("Invalid ihex record or mismatched checksum"); + continue; + } + switch (type) { + case '0': + /* Data record. */ + if (sz == 0) + break; + rec_addr = addr_base + addr; + if (first || sec_addr != rec_addr) { + if (s != NULL) + finalize_data_section(s); + s = new_data_section(ecp, sec_index, off, + rec_addr); + if (s == NULL) { + warnx("new_data_section failed"); + break; + } + sec_index++; + sec_addr = rec_addr; + first = 0; + } + append_data(s, data, sz); + off += sz; + sec_addr += sz; + break; + case '1': + /* End of file record. */ + goto done; + case '2': + /* Extended segment address record. */ + addr_base = addr << 4; + break; + case '3': + /* Start segment address record (CS:IP). Ignored. */ + break; + case '4': + /* Extended linear address record. */ + addr_base = num << 16; + break; + case '5': + /* Start linear address record. */ + entry = num; + break; + default: + break; + } + } +done: + if (s != NULL) + finalize_data_section(s); + if (ferror(ifp)) + warn("fgets failed"); + fclose(ifp); + + /* Insert .shstrtab after data sections. */ + if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + insert_to_sec_list(ecp, ecp->shstrtab, 1); + + /* Insert section header table here. */ + shtab = insert_shtab(ecp, 1); + + /* Set entry point. */ + oeh.e_entry = entry; + + /* + * Write the underlying ehdr. Note that it should be called + * before elf_setshstrndx() since it will overwrite e->e_shstrndx. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Update sh_name pointer for each section header entry. */ + update_shdr(ecp, 0); + + /* Renew oeh to get the updated e_shstrndx. */ + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Resync section offsets. */ + resync_sections(ecp); + + /* Store SHDR offset in EHDR. */ + oeh.e_shoff = shtab->off; + + /* Update ehdr since we modified e_shoff. */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Write out the output elf object. */ + if (elf_update(ecp->eout, ELF_C_WRITE) < 0) + errx(EXIT_FAILURE, "elf_update() failed: %s", + elf_errmsg(-1)); + + /* Release allocated resource. */ + free_elf(ecp); +} + +#define _SEC_NAMESZ 64 +#define _SEC_INIT_CAP 1024 + +static struct section * +new_data_section(struct elfcopy *ecp, int sec_index, uint64_t off, + uint64_t addr) +{ + char *name; + + if ((name = malloc(_SEC_NAMESZ)) == NULL) + errx(EXIT_FAILURE, "malloc failed"); + snprintf(name, _SEC_NAMESZ, ".sec%d", sec_index); + + return (create_external_section(ecp, name, name, NULL, 0, off, + SHT_PROGBITS, ELF_T_BYTE, SHF_ALLOC | SHF_WRITE, 1, addr, 0)); +} + +static void +finalize_data_section(struct section *s) +{ + Elf_Data *od; + + if ((od = elf_newdata(s->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s", + elf_errmsg(-1)); + od->d_align = s->align; + od->d_off = 0; + od->d_buf = s->buf; + od->d_size = s->sz; + od->d_version = EV_CURRENT; +} + +static void +append_data(struct section *s, const void *buf, size_t sz) +{ + uint8_t *p; + + if (s->buf == NULL) { + s->sz = 0; + s->cap = _SEC_INIT_CAP; + if ((s->buf = malloc(s->cap)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + } + + while (sz + s->sz > s->cap) { + s->cap *= 2; + if ((s->buf = realloc(s->buf, s->cap)) == NULL) + err(EXIT_FAILURE, "realloc failed"); + } + + p = s->buf; + memcpy(&p[s->sz], buf, sz); + s->sz += sz; +} + +static int +srec_read(const char *line, char *type, uint64_t *addr, uint8_t *data, + size_t *sz) +{ + uint64_t count, _checksum, num; + size_t addr_sz; + int checksum, i, len; + + checksum = 0; + len = 2; + if (read_num(line, &len, &count, 1, &checksum) < 0) + return (-1); + *type = line[1]; + switch (*type) { + case '0': + case '1': + case '5': + case '9': + addr_sz = 2; + break; + case '2': + case '8': + addr_sz = 3; + break; + case '3': + case '7': + addr_sz = 4; + break; + default: + return (-1); + } + + if (read_num(line, &len, addr, addr_sz, &checksum) < 0) + return (-1); + + count -= addr_sz + 1; + if (*type >= '0' && *type <= '3') { + for (i = 0; (uint64_t) i < count; i++) { + if (read_num(line, &len, &num, 1, &checksum) < 0) + return -1; + data[i] = (uint8_t) num; + } + *sz = count; + } else + *sz = 0; + + if (read_num(line, &len, &_checksum, 1, NULL) < 0) + return (-1); + + if ((int) _checksum != (~checksum & 0xFF)) + return (-1); + + return (0); +} + +static void +srec_write_symtab(int ofd, const char *ofn, Elf *e, Elf_Scn *scn, GElf_Shdr *sh) +{ + char line[_LINE_BUFSZ]; + GElf_Sym sym; + Elf_Data *d; + const char *name; + size_t sc; + int elferr, i; + +#define _WRITE_LINE do { \ + if (write(ofd, line, strlen(line)) != (ssize_t) strlen(line)) \ + errx(EXIT_FAILURE, "write failed"); \ + } while (0) + + + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(-1)); + return; + } + if (d->d_buf == NULL || d->d_size == 0) + return; + + snprintf(line, sizeof(line), "$$ %s\r\n", ofn); + _WRITE_LINE; + sc = d->d_size / sh->sh_entsize; + for (i = 1; (size_t) i < sc; i++) { + if (gelf_getsym(d, i, &sym) != &sym) { + warnx("gelf_getsym failed: %s", elf_errmsg(-1)); + continue; + } + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION || + GELF_ST_TYPE(sym.st_info) == STT_FILE) + continue; + if ((name = elf_strptr(e, sh->sh_link, sym.st_name)) == NULL) { + warnx("elf_strptr failed: %s", elf_errmsg(-1)); + continue; + } + snprintf(line, sizeof(line), " %s $%jx\r\n", name, + (uintmax_t) sym.st_value); + _WRITE_LINE; + } + snprintf(line, sizeof(line), "$$ \r\n"); + _WRITE_LINE; + +#undef _WRITE_LINE +} + +static void +srec_write_S0(int ofd, const char *ofn) +{ + + srec_write(ofd, '0', 0, ofn, strlen(ofn)); +} + +static void +srec_write_Sd(int ofd, char dr, uint64_t addr, const void *buf, size_t sz, + size_t rlen) +{ + const uint8_t *p, *pe; + + p = buf; + pe = p + sz; + while (pe - p >= (int) rlen) { + srec_write(ofd, dr, addr, p, rlen); + addr += rlen; + p += rlen; + } + if (pe - p > 0) + srec_write(ofd, dr, addr, p, pe - p); +} + +static void +srec_write_Se(int ofd, uint64_t e_entry, int forceS3) +{ + char er; + + if (e_entry > 0xFFFFFFFF) { + warnx("address space too big for S-Record file"); + return; + } + + if (forceS3) + er = '7'; + else { + if (e_entry <= 0xFFFF) + er = '9'; + else if (e_entry <= 0xFFFFFF) + er = '8'; + else + er = '7'; + } + + srec_write(ofd, er, e_entry, NULL, 0); +} + +static void +srec_write(int ofd, char type, uint64_t addr, const void *buf, size_t sz) +{ + char line[_LINE_BUFSZ]; + const uint8_t *p, *pe; + int len, addr_sz, checksum; + + if (type == '0' || type == '1' || type == '5' || type == '9') + addr_sz = 2; + else if (type == '2' || type == '8') + addr_sz = 3; + else + addr_sz = 4; + + checksum = 0; + line[0] = 'S'; + line[1] = type; + len = 2; + write_num(line, &len, addr_sz + sz + 1, 1, &checksum); + write_num(line, &len, addr, addr_sz, &checksum); + for (p = buf, pe = p + sz; p < pe; p++) + write_num(line, &len, *p, 1, &checksum); + write_num(line, &len, ~checksum & 0xFF, 1, NULL); + line[len++] = '\r'; + line[len++] = '\n'; + if (write(ofd, line, len) != (ssize_t) len) + err(EXIT_FAILURE, "write failed"); +} + +static void +ihex_write_00(int ofd, uint64_t addr, const void *buf, size_t sz) +{ + uint16_t addr_hi, old_addr_hi; + const uint8_t *p, *pe; + + old_addr_hi = (addr >> 16) & 0xFFFF; + p = buf; + pe = p + sz; + while (pe - p >= 16) { + ihex_write(ofd, 0, addr, 0, p, 16); + addr += 16; + p += 16; + addr_hi = (addr >> 16) & 0xFFFF; + if (addr_hi != old_addr_hi) { + old_addr_hi = addr_hi; + ihex_write_04(ofd, addr_hi); + } + } + if (pe - p > 0) + ihex_write(ofd, 0, addr, 0, p, pe - p); +} + +static int +ihex_read(const char *line, char *type, uint64_t *addr, uint64_t *num, + uint8_t *data, size_t *sz) +{ + uint64_t count, _checksum; + int checksum, i, len; + + *sz = 0; + checksum = 0; + len = 1; + if (read_num(line, &len, &count, 1, &checksum) < 0) + return (-1); + if (read_num(line, &len, addr, 2, &checksum) < 0) + return (-1); + if (line[len++] != '0') + return (-1); + *type = line[len++]; + checksum += *type - '0'; + switch (*type) { + case '0': + for (i = 0; (uint64_t) i < count; i++) { + if (read_num(line, &len, num, 1, &checksum) < 0) + return (-1); + data[i] = (uint8_t) *num; + } + *sz = count; + break; + case '1': + if (count != 0) + return (-1); + break; + case '2': + case '4': + if (count != 2) + return (-1); + if (read_num(line, &len, num, 2, &checksum) < 0) + return (-1); + break; + case '3': + case '5': + if (count != 4) + return (-1); + if (read_num(line, &len, num, 4, &checksum) < 0) + return (-1); + break; + default: + return (-1); + } + + if (read_num(line, &len, &_checksum, 1, &checksum) < 0) + return (-1); + + if ((checksum & 0xFF) != 0) { + return (-1); + } + + return (0); +} + +static void +ihex_write_01(int ofd) +{ + + ihex_write(ofd, 1, 0, 0, NULL, 0); +} + +static void +ihex_write_04(int ofd, uint16_t addr) +{ + + ihex_write(ofd, 4, 0, addr, NULL, 2); +} + +static void +ihex_write_05(int ofd, uint64_t e_entry) +{ + + if (e_entry > 0xFFFFFFFF) { + warnx("address space too big for Intel Hex file"); + return; + } + + ihex_write(ofd, 5, 0, e_entry, NULL, 4); +} + +static void +ihex_write(int ofd, int type, uint64_t addr, uint64_t num, const void *buf, + size_t sz) +{ + char line[_LINE_BUFSZ]; + const uint8_t *p, *pe; + int len, checksum; + + if (sz > 16) + errx(EXIT_FAILURE, "Internal: ihex_write() sz too big"); + checksum = 0; + line[0] = ':'; + len = 1; + write_num(line, &len, sz, 1, &checksum); + write_num(line, &len, addr, 2, &checksum); + write_num(line, &len, type, 1, &checksum); + if (sz > 0) { + if (buf != NULL) { + for (p = buf, pe = p + sz; p < pe; p++) + write_num(line, &len, *p, 1, &checksum); + } else + write_num(line, &len, num, sz, &checksum); + } + write_num(line, &len, (~checksum + 1) & 0xFF, 1, NULL); + line[len++] = '\r'; + line[len++] = '\n'; + if (write(ofd, line, len) != (ssize_t) len) + err(EXIT_FAILURE, "write failed"); +} + +static int +read_num(const char *line, int *len, uint64_t *num, size_t sz, int *checksum) +{ + uint8_t b; + + *num = 0; + for (; sz > 0; sz--) { + if (!ishexdigit(line[*len]) || !ishexdigit(line[*len + 1])) + return (-1); + b = (hex_value(line[*len]) << 4) | hex_value(line[*len + 1]); + *num = (*num << 8) | b; + *len += 2; + if (checksum != NULL) + *checksum = (*checksum + b) & 0xFF; + } + + return (0); +} + +static void +write_num(char *line, int *len, uint64_t num, size_t sz, int *checksum) +{ + uint8_t b; + + for (; sz > 0; sz--) { + b = (num >> ((sz - 1) * 8)) & 0xFF; + line[*len] = hex_digit((b >> 4) & 0xF); + line[*len + 1] = hex_digit(b & 0xF); + *len += 2; + if (checksum != NULL) + *checksum = (*checksum + b) & 0xFF; + } +} + +static char +hex_digit(uint8_t n) +{ + + return ((n < 10) ? '0' + n : 'A' + (n - 10)); +} + +static int +hex_value(int x) +{ + + if (isdigit(x)) + return (x - '0'); + else if (x >= 'a' && x <= 'f') + return (x - 'a' + 10); + else + return (x - 'A' + 10); +} + +static int +ishexdigit(int x) +{ + + if (isdigit(x)) + return (1); + if ((x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F')) + return (1); + + return (0); +} diff --git a/contrib/elftoolchain/elfcopy/binary.c b/contrib/elftoolchain/elfcopy/binary.c new file mode 100644 index 0000000000..df45f55f94 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/binary.c @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 2010,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: binary.c 3832 2020-03-02 00:22:47Z emaste $"); + +/* + * Convert ELF object to `binary'. Sections with SHF_ALLOC flag set + * are copied to the result binary. The relative offsets for each section + * are retained, so the result binary file might contain "holes". + */ +void +create_binary(int ifd, int ofd) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Shdr sh; + off_t base, off; + int elferr; + + if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + base = 0; + if (lseek(ofd, base, SEEK_SET) < 0) + err(EXIT_FAILURE, "lseek failed"); + + /* + * Find base offset in the first iteration. + */ + base = -1; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((sh.sh_flags & SHF_ALLOC) == 0 || + sh.sh_type == SHT_NOBITS || + sh.sh_size == 0) + continue; + if (base == -1 || (off_t) sh.sh_offset < base) + base = sh.sh_offset; + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); + + if (base == -1) + return; + + /* + * Write out sections in the second iteration. + */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((sh.sh_flags & SHF_ALLOC) == 0 || + sh.sh_type == SHT_NOBITS || + sh.sh_size == 0) + continue; + (void) elf_errno(); + if ((d = elf_rawdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", elf_errmsg(-1)); + continue; + } + if (d->d_buf == NULL || d->d_size == 0) + continue; + + /* lseek to section offset relative to `base'. */ + off = sh.sh_offset - base; + if (lseek(ofd, off, SEEK_SET) < 0) + err(EXIT_FAILURE, "lseek failed"); + + /* Write out section contents. */ + if (write(ofd, d->d_buf, d->d_size) != (ssize_t) d->d_size) + err(EXIT_FAILURE, "write failed"); + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); +} + +#define _SYMBOL_NAMSZ 1024 + +/* + * Convert `binary' to ELF object. The input `binary' is converted to + * a relocatable (.o) file, a few symbols will also be created to make + * it easier to access the binary data in other compilation units. + */ +void +create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn) +{ + char name[_SYMBOL_NAMSZ]; + struct section *sec, *sec_temp, *shtab; + struct stat sb; + GElf_Ehdr oeh; + GElf_Shdr sh; + void *content; + uint64_t off, data_start, data_end, data_size; + char *sym_basename, *p; + + /* Reset internal section list. */ + if (!TAILQ_EMPTY(&ecp->v_sec)) + TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) { + TAILQ_REMOVE(&ecp->v_sec, sec, sec_list); + free(sec); + } + + if (fstat(ifd, &sb) == -1) + err(EXIT_FAILURE, "fstat failed"); + + /* Read the input binary file to a internal buffer. */ + if ((content = malloc(sb.st_size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if (read(ifd, content, sb.st_size) != sb.st_size) + err(EXIT_FAILURE, "read failed"); + + /* + * TODO: copy the input binary to output binary verbatim if -O is not + * specified. + */ + + /* Create EHDR for output .o file. */ + if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) + errx(EXIT_FAILURE, "gelf_newehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Initialise e_ident fields. */ + oeh.e_ident[EI_CLASS] = ecp->oec; + oeh.e_ident[EI_DATA] = ecp->oed; + /* + * TODO: Set OSABI according to the OS platform where elfcopy(1) + * was build. (probably) + */ + oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; + oeh.e_machine = ecp->oem; + oeh.e_type = ET_REL; + oeh.e_entry = 0; + + ecp->flags |= RELOCATABLE; + + /* Create .shstrtab section */ + init_shstrtab(ecp); + ecp->shstrtab->off = 0; + + /* + * Create `.data' section which contains the binary data. The + * section is inserted immediately after EHDR. + */ + off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); + if (off == 0) + errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); + (void) create_external_section(ecp, ".data", NULL, content, sb.st_size, + off, SHT_PROGBITS, ELF_T_BYTE, SHF_ALLOC | SHF_WRITE, 1, 0, 1); + + /* Insert .shstrtab after .data section. */ + if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + insert_to_sec_list(ecp, ecp->shstrtab, 1); + + /* Insert section header table here. */ + shtab = insert_shtab(ecp, 1); + + /* Count in .symtab and .strtab section headers. */ + shtab->sz += gelf_fsize(ecp->eout, ELF_T_SHDR, 2, EV_CURRENT); + + if ((sym_basename = strdup(ifn)) == NULL) + err(1, "strdup"); + for (p = sym_basename; *p != '\0'; p++) + if (!isalnum(*p & 0xFF)) + *p = '_'; +#define _GEN_SYMNAME(S) do { \ + snprintf(name, sizeof(name), "%s%s%s", "_binary_", sym_basename, S); \ +} while (0) + + /* + * Create symbol table. + */ + create_external_symtab(ecp); + data_start = 0; + data_end = data_start + sb.st_size; + data_size = sb.st_size; + _GEN_SYMNAME("_start"); + add_to_symtab(ecp, name, data_start, 0, 1, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); + _GEN_SYMNAME("_end"); + add_to_symtab(ecp, name, data_end, 0, 1, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); + _GEN_SYMNAME("_size"); + add_to_symtab(ecp, name, data_size, 0, SHN_ABS, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); + finalize_external_symtab(ecp); + create_symtab_data(ecp); +#undef _GEN_SYMNAME + free(sym_basename); + + /* + * Write the underlying ehdr. Note that it should be called + * before elf_setshstrndx() since it will overwrite e->e_shstrndx. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Update sh_name pointer for each section header entry. */ + ecp->flags |= SYMTAB_EXIST; + update_shdr(ecp, 0); + + /* Properly set sh_link field of .symtab section. */ + if (gelf_getshdr(ecp->symtab->os, &sh) == NULL) + errx(EXIT_FAILURE, "692 gelf_getshdr() failed: %s", + elf_errmsg(-1)); + sh.sh_link = elf_ndxscn(ecp->strtab->os); + if (!gelf_update_shdr(ecp->symtab->os, &sh)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + + /* Renew oeh to get the updated e_shstrndx. */ + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* Resync section offsets. */ + resync_sections(ecp); + + /* Store SHDR offset in EHDR. */ + oeh.e_shoff = shtab->off; + + /* Update ehdr since we modified e_shoff. */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* Write out the output elf object. */ + if (elf_update(ecp->eout, ELF_C_WRITE) < 0) + errx(EXIT_FAILURE, "elf_update() failed: %s", + elf_errmsg(-1)); + + /* Release allocated resource. */ + free(content); + free_elf(ecp); +} diff --git a/contrib/elftoolchain/elfcopy/elfcopy.1 b/contrib/elftoolchain/elfcopy/elfcopy.1 new file mode 100644 index 0000000000..ee465bd353 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/elfcopy.1 @@ -0,0 +1,390 @@ +.\" Copyright (c) 2008-2009,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elfcopy.1 3972 2022-04-23 12:55:28Z jkoshy $ +.\" +.Dd April 23, 2022 +.Dt ELFCOPY 1 +.Os +.Sh NAME +.Nm elfcopy , +.Nm objcopy +.Nd copy and translate object files +.Sh SYNOPSIS +.Nm +.Op Fl I Ar objformat | Fl s Ar objformat | Fl -input-target= Ns Ar objformat +.Op Fl G Ar filename | Fl --keep-global-symbols= Ns Ar filename +.Op Fl K Ar symbolname | Fl -keep-symbol= Ns Ar symbolname +.Op Fl L Ar symbolname | Fl -localize-symbol= Ns Ar symbolname +.Op Fl N Ar symbolname | Fl -strip-symbol= Ns Ar symbolname +.Op Fl O Ar objformat | Fl -output-target= Ns Ar objformat +.Op Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname +.Op Fl S | Fl -strip-all +.Op Fl V | Fl -version +.Op Fl W Ar symbolname | Fl -weaken-symbol= Ns Ar symbolname +.Op Fl X | Fl -discard-locals +.Op Fl d | Fl g | Fl -strip-debug +.Op Fl h | Fl -help +.Op Fl j Ar sectionname | Fl -only-section= Ns Ar sectionname +.Op Fl p | Fl -preserve-dates +.Op Fl w | Fl -wildcard +.Op Fl x | Fl -discard-all +.Op Fl -add-gnu-debuglink Ns = Ns Ar filename +.Op Fl -add-section Ar sectionname Ns = Ns Ar filename +.Oo +.Fl -adjust-section-vma Ar section Ns {+|-|=} Ns Ar val | +.Fl -change-section-address Ar section Ns {+|-|=} Ns Ar val +.Oc +.Oo +.Fl -adjust-start Ns = Ns Ar increment | +.Fl -change-start Ns = Ns Ar increment +.Oc +.Oo +.Fl -adjust-vma Ns = Ns Ar increment | +.Fl -change-addresses Ns = Ns Ar increment +.Oc +.Op Fl -adjust-warnings | Fl -change-warnings +.Op Fl -change-section-lma Ar section Ns {+|-|=} Ns Ar val +.Op Fl -change-section-vma Ar section Ns {+|-|=} Ns Ar val +.Op Fl -extract-dwo +.Op Fl -gap-fill Ns = Ns Ar val +.Op Fl -globalize-symbol Ns = Ns ar symbolname +.Op Fl -globalize-symbols Ns = Ns Ar filename +.Op Fl -keep-global-symbol Ns = Ns Ar symbolname +.Op Fl -localize-hidden +.Op Fl -localize-symbols Ns = Ns Ar filename +.Op Fl -no-adjust-warnings | Fl -no-change-warnings +.Op Fl -only-keep-debug +.Op Fl -pad-to Ns = Ns Ar address +.Op Fl -prefix-alloc-sections Ns = Ns Ar string +.Op Fl -prefix-sections Ns = Ns Ar string +.Op Fl -prefix-symbols Ns = Ns Ar string +.Op Fl -rename-section Ar oldname Ns = Ns Ar newname Ns Op Ar ,flags +.Op Fl -set-section-flags Ar sectionname Ns = Ns Ar flags +.Op Fl -set-start Ns = Ns Ar address +.Op Fl -srec-forceS3 +.Op Fl -srec-len Ns = Ns Ar val +.Op Fl -strip-dwo +.Op Fl -strip-symbols= Ns Ar filename +.Op Fl -strip-unneeded +.Ar infile +.Op Ar outfile +.Sh DESCRIPTION +The +.Nm +utility copies the content of the binary object named by argument +.Ar infile +to that named by argument +.Ar outfile , +transforming it according to the command line options specified. +If argument +.Ar outfile +is not specified, +.Nm +will create a temporary file and will subsequently rename it as +.Ar infile . +.Pp +The +.Nm +utility supports the following options: +.Bl -tag -width indent +.It Fl I Ar objformat | Fl s Ar objformat | Fl -input-target= Ns Ar objformat +Specify that the input file named by the argument +.Ar infile +is in the object format specified by the argument +.Ar objformat . +.It Fl G Ar filename | Fl --keep-global-symbols= Ns Ar filename +Make the symbols specified in +.Ar filename +global. +File +.Ar filename +contains a newline-separated list of symbols, with the +.Sq Li # +character starting a comment that extends to the end of the line. +If this option is specified, any other symbols not specified +as global will be made local to the output file. +This option may be specified multiple times. +.It Fl K Ar symbolname | Fl -keep-symbol= Ns Ar symbolname +Copy the symbol named by argument +.Ar symbolname +to the output. +.It Fl L Ar symbolname | Fl -localize-symbol= Ns Ar symbolname +Make the symbol named by argument +.Ar symbolname +local to the output file. +.It Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbolname +Do not copy the symbol named by argument +.Ar symbolname +to the output. +.It Fl O Ar objformat | Fl -output-target= Ns Ar objformat +Write the output file using the object format specified in argument +.Ar objformat . +The argument +.Ar objformat +should be one of the target names recognized by +.Xr elftc_bfd_find_target 3 . +.It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname +Remove any section with name +.Ar sectionname +from the output file. +.It Fl S | Fl -strip-all +Do not copy symbol and relocation information to the target file. +.It Fl V | Fl -version +Print a version identifier and exit. +.It Fl W Ar symbolname | Fl -weaken-symbol= Ns Ar symbolname +Mark the symbol named by argument +.Ar symbolname +as weak in the output. +.It Fl X | Fl -discard-locals +Do not copy compiler generated local symbols to the output. +.It Fl d | Fl g | Fl -strip-debug +Do not copy debugging information to the target file. +.It Fl h | Fl -help +Display a help message and exit. +.It Fl j Ar sectionname | Fl -only-section= Ns Ar sectionname +Copy only the section named by argument +.Ar sectionname +to the output. +.It Fl p | Fl -preserve-dates +Set the access and modification times of the output file to the +same as those of the input. +.It Fl w | Fl -wildcard +Use shell-style patterns to name symbols. +The following meta-characters are recognized in patterns: +.Bl -tag -width "...." -compact +.It Li ! +If this is the first character of the pattern, invert the sense of the +pattern match. +.It Li * +Matches any string of characters in a symbol name. +.It Li ? +Matches zero or one character in a symbol name. +.It Li [ +Mark the start of a character class. +.It Li \e +Remove the special meaning of the next character in the pattern. +.It Li ] +Mark the end of a character class. +.El +.It Fl x | Fl -discard-all +Do not copy non-global symbols to the output. +.It Fl -add-gnu-debuglink Ns = Ns Ar filename +Create a .gnu_debuglink section in the output file that references the +debug data in +.Ar filename . +.It Fl -add-section Ar sectionname Ns = Ns Ar filename +Add a new section to the output file with name +.Ar sectionname . +The contents of the section are taken from the file named by +argument +.Ar filename . +The size of the section will be the number of bytes in file +.Ar filename . +.It Xo +.Fl -adjust-section-vma Ar section Ns {+|-|=} Ns Ar val | +.Fl -change-section-address Ar section Ns {+|-|=} Ns Ar val +.Xc +Depending on the operator specified, increase, decrease or set both +the virtual memory address and the load memory address of the section +named by the argument +.Ar section . +The argument +.Ar val +specifies the desired increment, decrement or new value for the +address. +.It Xo +.Fl -adjust-start Ns = Ns Ar increment | +.Fl -change-start Ns = Ns Ar increment +.Xc +Increase the entry point address of the output ELF object by the value +specified in the argument +.Ar increment . +.It Xo +.Fl -adjust-vma Ns = Ns Ar increment | +.Fl -change-addresses Ns = Ns Ar increment +.Xc +Increase the virtual memory address and the load memory address of all +sections by the value specified by the argument +.Ar increment . +.It Fl -adjust-warnings | Fl -change-warnings +Issue a warning if the section specified by the options +.Fl -change-section-address , +.Fl -change-section-lma +or +.Fl -change-section-vma +does not exist in the input object. +This is the default. +.It Fl -change-section-lma Ar section Ns {+|-|=} Ns Ar val +Change or set the load memory address of the section named by the +argument +.Ar section . +Depending on the operator specified, the value in argument +.Ar val +will be used as an increment, a decrement or as the new value +of the load memory address. +.It Fl -change-section-vma Ar section Ns {+|-|=} Ns Ar val +Change or set the virtual memory address of the section named by the +argument +.Ar section . +Depending on the operator specified, the value in argument +.Ar val +will be used as an increment, a decrement or as the new value +of the virtual memory address. +.It Fl -extract-dwo +Copy only .dwo debug sections to the output file. +.It Fl -gap-fill Ns = Ns Ar val +Fill the gaps between sections with the byte value specified by +the argument +.Ar val . +.It Fl -globalize-symbol Ns = Ns Ar symbolname +Make the symbol named by argument +.Ar symbolname +global, so that it is visible outside of the file in which it is defined. +.It Fl -globalize-symbols Ns = Ns Ar filename +Make each symbol listed in the file specified by +.Ar filename +global. +.It Fl -keep-global-symbol Ns = Ns Ar symbolname +Make the symbol named by argument +.Ar symbolname +global. +If this option is specified, any other symbols not +specified as global will be made local to the output file. +This option may be specified multiple times. +.It Fl -localize-hidden +Make all hidden symbols local to the output file. +This includes symbols with internal visiblity. +.It Fl -localize-symbols Ns = Ns Ar filename +Make each symbol listed in the file specified by +.Ar filename +local to the output file. +.It Fl -no-adjust-warnings | Fl -no-change-warnings +Do not issue a warning if the section specified by the options +.Fl -change-section-address , +.Fl -change-section-lma +or +.Fl -change-section-vma +is missing in the input object. +.It Fl -only-keep-debug +Copy only debugging information to the output file. +.It Fl -pad-to Ns = Ns Ar address +Pad the load memory address of the output object to the value +specified by the argument +.Ar address +by increasing the size of the section with the highest load memory +address. +.It Fl -prefix-alloc-sections Ns = Ns Ar string +Prefix the section names of all the allocated sections with +.Ar string . +.It Fl -prefix-sections Ns = Ns Ar string +Prefix the section names of all the sections with +.Ar string . +.It Fl -prefix-symbols Ns = Ns Ar string +Prefix the symbol names of all the symbols with +.Ar string . +.It Fl -rename-section Ar oldname Ns = Ns Ar newname Ns Op Ar ,flags +Rename the section named by argument +.Ar oldname +to +.Ar newname , +optionally changing the sections flags to that specified by argument +.Ar flags . +Allowed values for the argument +.Ar flags +are as for option +.Fl -set-section-flags +below. +.It Fl -set-section-flags Ar sectionname Ns = Ns Ar flags +Set the flags for the section named by argument +.Ar sectionname +to those specified by argument +.Ar flags . +Argument +.Ar flags +is a comma separated list of the following flag names: +.Bl -tag -width "readonly" -compact +.It alloc +The section occupies space in the output file. +.It code +The section contains machine instructions. +.It contents +This flag is accepted but is ignored. +.It data +The section contains writeable data. +.It debug +The section holds debugging information. +.It load +The section is loadable. +.It noload +The section should not be loaded into memory. +.It readonly +The section is not writable. +.It rom +The section contains ROM'able contents. +.It share +This flag is accepted but is ignored. +.El +.It Fl -set-start Ns = Ns Ar address +Set the start address of the output ELF object to the value specified +by the argument +.Ar address . +.It Fl -srec-forceS3 +Only generate S-records of type +.Dq S3 . +This option is only meaningful when the output target is set to +.Dq srec . +.It Fl -srec-len Ns = Ns Ar val +Set the maximum length of an S-record line to +.Ar val . +This option is only meaningful when the output target is set to +.Dq srec . +.It Fl -strip-dwo +Do not copy .dwo debug sections to the output file. +.It Fl -strip-symbols= Ns Ar filename +Do not copy any of the symbols specified by +.Ar filename +to the output. +.It Fl -strip-unneeded +Do not copy symbols that are not needed for relocation processing. +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr ld 1 , +.Xr mcs 1 , +.Xr strip 1 , +.Xr elf 3 , +.Xr elftc_bfd_find_target 3 , +.Xr ar 5 , +.Xr elf 5 +.Sh COMPATIBILITY +The +.Nm +utility is expected to be option compatible with GNU +.Nm objcopy . +.Sh HISTORY +.Nm +has been implemented by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/elfcopy/elfcopy.h b/contrib/elftoolchain/elfcopy/elfcopy.h new file mode 100644 index 0000000000..858d47b3d7 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/elfcopy.h @@ -0,0 +1,325 @@ +/*- + * Copyright (c) 2007-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfcopy.h 3919 2021-02-19 21:50:21Z jkoshy $ + */ + +#include +#include +#include + +#include "_elftc.h" + +/* + * User specified symbol operation (strip, keep, localize, globalize, + * weaken, rename, etc). + */ +struct symop { + const char *name; + const char *newname; + +#define SYMOP_KEEP 0x0001U +#define SYMOP_STRIP 0x0002U +#define SYMOP_GLOBALIZE 0x0004U +#define SYMOP_LOCALIZE 0x0008U +#define SYMOP_KEEPG 0x0010U +#define SYMOP_WEAKEN 0x0020U +#define SYMOP_REDEF 0x0040U + + unsigned int op; + + STAILQ_ENTRY(symop) symop_list; +}; + +/* File containing symbol list. */ +struct symfile { + dev_t dev; + ino_t ino; + size_t size; + char *data; + unsigned int op; + + STAILQ_ENTRY(symfile) symfile_list; +}; + +/* Sections to copy/remove/rename/... */ +struct sec_action { + const char *name; + const char *addopt; + const char *newname; + const char *string; + uint64_t lma; + uint64_t vma; + int64_t lma_adjust; + int64_t vma_adjust; + +#define SF_ALLOC 0x0001U +#define SF_LOAD 0x0002U +#define SF_NOLOAD 0x0004U +#define SF_READONLY 0x0008U +#define SF_DEBUG 0x0010U +#define SF_CODE 0x0020U +#define SF_DATA 0x0040U +#define SF_ROM 0x0080U +#define SF_SHARED 0X0100U +#define SF_CONTENTS 0x0200U + + int flags; + int add; + int append; + int compress; + int copy; + int print; + int remove; + int rename; + int setflags; + int setlma; + int setvma; + + STAILQ_ENTRY(sec_action) sac_list; +}; + +/* Sections to add from file. */ +struct sec_add { + char *name; + char *content; + size_t size; + + STAILQ_ENTRY(sec_add) sadd_list; +}; + +struct segment; + +/* Internal data structure for sections. */ +struct section { + struct segment *seg; /* containing segment */ + struct segment *seg_tls; /* tls segment */ + const char *name; /* section name */ + char *newname; /* new section name */ + Elf_Scn *is; /* input scn */ + Elf_Scn *os; /* output scn */ + void *buf; /* section content */ + uint8_t *pad; /* section padding */ + uint64_t off; /* section offset */ + uint64_t sz; /* section size */ + uint64_t cap; /* section capacity */ + uint64_t align; /* section alignment */ + uint64_t type; /* section type */ + uint64_t flags; /* section flags */ + uint64_t vma; /* section virtual addr */ + uint64_t lma; /* section load addr */ + uint64_t pad_sz;/* section padding size */ + int loadable; /* whether loadable */ + int pseudo; + int nocopy; + + Elftc_String_Table *strtab; + + TAILQ_ENTRY(section) sec_list; /* next section */ +}; + +TAILQ_HEAD(sectionlist, section); + +/* Internal data structure for segments. */ +struct segment { + uint64_t vaddr; /* virtual addr (VMA) */ + uint64_t paddr; /* physical addr (LMA) */ + uint64_t off; /* file offset */ + uint64_t fsz; /* file size */ + uint64_t msz; /* memory size */ + uint64_t type; /* segment type */ + int remove; /* whether remove */ + int nsec; /* number of sections contained */ + struct section **v_sec; /* list of sections contained */ + + STAILQ_ENTRY(segment) seg_list; /* next segment */ +}; + +/* + * In-memory representation of ar(1) archive member(object). + */ +struct ar_obj { + char *name; /* member name */ + char *buf; /* member content */ + void *maddr; /* mmap start address */ + uid_t uid; /* user id */ + gid_t gid; /* group id */ + mode_t md; /* octal file permissions */ + size_t size; /* member size */ + time_t mtime; /* modification time */ + + STAILQ_ENTRY(ar_obj) objs; +}; + +/* + * Structure encapsulates the "global" data for "elfcopy" program. + */ +struct elfcopy { + const char *progname; /* program name */ + int iec; /* elfclass of input object */ + Elftc_Bfd_Target_Flavor itf; /* flavour of input object */ + Elftc_Bfd_Target_Flavor otf; /* flavour of output object */ + const char *otgt; /* output target name */ + int oec; /* elfclass of output object */ + unsigned char oed; /* endianness of output object */ + int oem; /* EM_XXX of output object */ + int abi; /* OSABI of output object */ + Elf *ein; /* ELF descriptor of input object */ + Elf *eout; /* ELF descriptor of output object */ + int iphnum; /* num. of input object phdr entries */ + int ophnum; /* num. of output object phdr entries */ + int nos; /* num. of output object sections */ + + enum { + STRIP_NONE = 0, + STRIP_ALL, + STRIP_DEBUG, + STRIP_DWO, + STRIP_NONDEBUG, + STRIP_NONDWO, + STRIP_UNNEEDED + } strip; + +#define EXECUTABLE 0x00000001U +#define DYNAMIC 0x00000002U +#define RELOCATABLE 0x00000004U +#define SYMTAB_EXIST 0x00000010U +#define SYMTAB_INTACT 0x00000020U +#define KEEP_GLOBAL 0x00000040U +#define DISCARD_LOCAL 0x00000080U +#define WEAKEN_ALL 0x00000100U +#define PRESERVE_DATE 0x00001000U +#define SREC_FORCE_S3 0x00002000U +#define SREC_FORCE_LEN 0x00004000U +#define SET_START 0x00008000U +#define GAP_FILL 0x00010000U +#define WILDCARD 0x00020000U +#define NO_CHANGE_WARN 0x00040000U +#define SEC_ADD 0x00080000U +#define SEC_APPEND 0x00100000U +#define SEC_COMPRESS 0x00200000U +#define SEC_PRINT 0x00400000U +#define SEC_REMOVE 0x00800000U +#define SEC_COPY 0x01000000U +#define DISCARD_LLABEL 0x02000000U +#define LOCALIZE_HIDDEN 0x04000000U + + int flags; /* elfcopy run control flags. */ + int64_t change_addr; /* Section address adjustment. */ + int64_t change_start; /* Entry point adjustment. */ + uint64_t set_start; /* Entry point value. */ + unsigned long srec_len; /* S-Record length. */ + uint64_t pad_to; /* load address padding. */ + uint8_t fill; /* gap fill value. */ + char *prefix_sec; /* section prefix. */ + char *prefix_alloc; /* alloc section prefix. */ + char *prefix_sym; /* symbol prefix. */ + char *debuglink; /* GNU debuglink file. */ + struct section *symtab; /* .symtab section. */ + struct section *strtab; /* .strtab section. */ + struct section *shstrtab; /* .shstrtab section. */ + uint64_t *secndx; /* section index map. */ + uint64_t *symndx; /* symbol index map. */ + unsigned char *v_rel; /* symbols needed by relocation. */ + unsigned char *v_grp; /* symbols referred by section group. */ + unsigned char *v_secsym; /* sections with section symbol. */ + STAILQ_HEAD(, segment) v_seg; /* list of segments. */ + STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */ + STAILQ_HEAD(, sec_add) v_sadd; /* list of sections to add. */ + STAILQ_HEAD(, symop) v_symop; /* list of symbols operations. */ + STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */ + TAILQ_HEAD(, section) v_sec; /* list of sections. */ + + /* + * Fields for the ar(1) archive. + */ + char *as; /* buffer for archive string table. */ + size_t as_sz; /* current size of as table. */ + size_t as_cap; /* capacity of as table buffer. */ + uint32_t s_cnt; /* current number of symbols. */ + uint32_t *s_so; /* symbol offset table. */ + size_t s_so_cap; /* capacity of so table buffer. */ + char *s_sn; /* symbol name table */ + size_t s_sn_cap; /* capacity of sn table buffer. */ + size_t s_sn_sz; /* current size of sn table. */ + off_t rela_off; /* offset relative to pseudo members. */ + STAILQ_HEAD(, ar_obj) v_arobj; /* archive object(member) list. */ +}; + +void add_section(struct elfcopy *_ecp, const char *_optarg); +void add_to_shstrtab(struct elfcopy *_ecp, const char *_name); +void add_to_symop_list(struct elfcopy *_ecp, const char *_name, + const char *_newname, unsigned int _op); +void add_to_symtab(struct elfcopy *_ecp, const char *_name, + uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx, + unsigned char _st_info, unsigned char _st_other, int _ndx_known); +int add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec); +void adjust_addr(struct elfcopy *_ecp); +int cleanup_tempfile(char *_fn); +void copy_content(struct elfcopy *_ecp); +void copy_data(struct section *_s); +void copy_phdr(struct elfcopy *_ecp); +void copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name, + int _copy, int _sec_flags); +void create_binary(int _ifd, int _ofd); +void create_elf(struct elfcopy *_ecp); +void create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn); +void create_elf_from_ihex(struct elfcopy *_ecp, int _ifd); +void create_elf_from_srec(struct elfcopy *_ecp, int _ifd); +struct section *create_external_section(struct elfcopy *_ecp, const char *_name, + char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype, + Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma, + int _loadable); +void create_external_symtab(struct elfcopy *_ecp); +void create_ihex(int _ifd, int _ofd); +void create_pe(struct elfcopy *_ecp, int _ifd, int _ofd); +void create_scn(struct elfcopy *_ecp); +void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn); +void create_symtab(struct elfcopy *_ecp); +void create_symtab_data(struct elfcopy *_ecp); +void create_tempfile(const char *_src, char **_fn, int *_fd); +void finalize_external_symtab(struct elfcopy *_ecp); +void free_elf(struct elfcopy *_ecp); +void free_sec_act(struct elfcopy *_ecp); +void free_sec_add(struct elfcopy *_ecp); +void free_symtab(struct elfcopy *_ecp); +void init_shstrtab(struct elfcopy *_ecp); +void insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec, + int _tail); +struct section *insert_shtab(struct elfcopy *_ecp, int tail); +int is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info); +int is_remove_section(struct elfcopy *_ecp, const char *_name); +struct sec_action *lookup_sec_act(struct elfcopy *_ecp, + const char *_name, int _add); +struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name, + unsigned int _op); +void resync_sections(struct elfcopy *_ecp); +void setup_phdr(struct elfcopy *_ecp); +void update_shdr(struct elfcopy *_ecp, int _update_link); + +#ifndef LIBELF_AR +int ac_detect_ar(int _ifd); +void ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd); +#endif /* ! LIBELF_AR */ diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c new file mode 100644 index 0000000000..4824f8ad92 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/main.c @@ -0,0 +1,1740 @@ +/*- + * Copyright (c) 2007-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: main.c 3971 2022-04-23 11:57:28Z jkoshy $"); + +enum options +{ + ECP_ADD_GNU_DEBUGLINK, + ECP_ADD_SECTION, + ECP_CHANGE_ADDR, + ECP_CHANGE_SEC_ADDR, + ECP_CHANGE_SEC_LMA, + ECP_CHANGE_SEC_VMA, + ECP_CHANGE_START, + ECP_CHANGE_WARN, + ECP_GAP_FILL, + ECP_GLOBALIZE_SYMBOL, + ECP_GLOBALIZE_SYMBOLS, + ECP_KEEP_SYMBOLS, + ECP_KEEP_GLOBAL_SYMBOLS, + ECP_LOCALIZE_HIDDEN, + ECP_LOCALIZE_SYMBOLS, + ECP_NO_CHANGE_WARN, + ECP_ONLY_DEBUG, + ECP_ONLY_DWO, + ECP_PAD_TO, + ECP_PREFIX_ALLOC, + ECP_PREFIX_SEC, + ECP_PREFIX_SYM, + ECP_REDEF_SYMBOL, + ECP_REDEF_SYMBOLS, + ECP_RENAME_SECTION, + ECP_SET_OSABI, + ECP_SET_SEC_FLAGS, + ECP_SET_START, + ECP_SREC_FORCE_S3, + ECP_SREC_LEN, + ECP_STRIP_DWO, + ECP_STRIP_SYMBOLS, + ECP_STRIP_UNNEEDED, + ECP_WEAKEN_ALL, + ECP_WEAKEN_SYMBOLS +}; + +static struct option mcs_longopts[] = +{ + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +static struct option strip_longopts[] = +{ + {"discard-all", no_argument, NULL, 'x'}, + {"discard-locals", no_argument, NULL, 'X'}, + {"help", no_argument, NULL, 'h'}, + {"input-target", required_argument, NULL, 'I'}, + {"keep-symbol", required_argument, NULL, 'K'}, + {"only-keep-debug", no_argument, NULL, ECP_ONLY_DEBUG}, + {"output-file", required_argument, NULL, 'o'}, + {"output-target", required_argument, NULL, 'O'}, + {"preserve-dates", no_argument, NULL, 'p'}, + {"remove-section", required_argument, NULL, 'R'}, + {"strip-all", no_argument, NULL, 's'}, + {"strip-debug", no_argument, NULL, 'S'}, + {"strip-symbol", required_argument, NULL, 'N'}, + {"strip-unneeded", no_argument, NULL, ECP_STRIP_UNNEEDED}, + {"version", no_argument, NULL, 'V'}, + {"wildcard", no_argument, NULL, 'w'}, + {NULL, 0, NULL, 0} +}; + +static struct option elfcopy_longopts[] = +{ + {"add-gnu-debuglink", required_argument, NULL, ECP_ADD_GNU_DEBUGLINK}, + {"add-section", required_argument, NULL, ECP_ADD_SECTION}, + {"adjust-section-vma", required_argument, NULL, ECP_CHANGE_SEC_ADDR}, + {"adjust-vma", required_argument, NULL, ECP_CHANGE_ADDR}, + {"adjust-start", required_argument, NULL, ECP_CHANGE_START}, + {"adjust-warnings", no_argument, NULL, ECP_CHANGE_WARN}, + {"binary-architecture", required_argument, NULL, 'B'}, + {"change-addresses", required_argument, NULL, ECP_CHANGE_ADDR}, + {"change-section-address", required_argument, NULL, + ECP_CHANGE_SEC_ADDR}, + {"change-section-lma", required_argument, NULL, ECP_CHANGE_SEC_LMA}, + {"change-section-vma", required_argument, NULL, ECP_CHANGE_SEC_VMA}, + {"change-start", required_argument, NULL, ECP_CHANGE_START}, + {"change-warnings", no_argument, NULL, ECP_CHANGE_WARN}, + {"discard-all", no_argument, NULL, 'x'}, + {"discard-locals", no_argument, NULL, 'X'}, + {"extract-dwo", no_argument, NULL, ECP_ONLY_DWO}, + {"gap-fill", required_argument, NULL, ECP_GAP_FILL}, + {"globalize-symbol", required_argument, NULL, ECP_GLOBALIZE_SYMBOL}, + {"globalize-symbols", required_argument, NULL, ECP_GLOBALIZE_SYMBOLS}, + {"help", no_argument, NULL, 'h'}, + {"input-target", required_argument, NULL, 'I'}, + {"keep-symbol", required_argument, NULL, 'K'}, + {"keep-symbols", required_argument, NULL, ECP_KEEP_SYMBOLS}, + {"keep-global-symbol", required_argument, NULL, 'G'}, + {"keep-global-symbols", required_argument, NULL, + ECP_KEEP_GLOBAL_SYMBOLS}, + {"localize-hidden", no_argument, NULL, ECP_LOCALIZE_HIDDEN}, + {"localize-symbol", required_argument, NULL, 'L'}, + {"localize-symbols", required_argument, NULL, ECP_LOCALIZE_SYMBOLS}, + {"no-adjust-warnings", no_argument, NULL, ECP_NO_CHANGE_WARN}, + {"no-change-warnings", no_argument, NULL, ECP_NO_CHANGE_WARN}, + {"only-keep-debug", no_argument, NULL, ECP_ONLY_DEBUG}, + {"only-section", required_argument, NULL, 'j'}, + {"osabi", required_argument, NULL, ECP_SET_OSABI}, + {"output-target", required_argument, NULL, 'O'}, + {"pad-to", required_argument, NULL, ECP_PAD_TO}, + {"preserve-dates", no_argument, NULL, 'p'}, + {"prefix-alloc-sections", required_argument, NULL, ECP_PREFIX_ALLOC}, + {"prefix-sections", required_argument, NULL, ECP_PREFIX_SEC}, + {"prefix-symbols", required_argument, NULL, ECP_PREFIX_SYM}, + {"redefine-sym", required_argument, NULL, ECP_REDEF_SYMBOL}, + {"redefine-syms", required_argument, NULL, ECP_REDEF_SYMBOLS}, + {"remove-section", required_argument, NULL, 'R'}, + {"rename-section", required_argument, NULL, ECP_RENAME_SECTION}, + {"set-section-flags", required_argument, NULL, ECP_SET_SEC_FLAGS}, + {"set-start", required_argument, NULL, ECP_SET_START}, + {"srec-forceS3", no_argument, NULL, ECP_SREC_FORCE_S3}, + {"srec-len", required_argument, NULL, ECP_SREC_LEN}, + {"strip-all", no_argument, NULL, 'S'}, + {"strip-debug", no_argument, 0, 'g'}, + {"strip-dwo", no_argument, NULL, ECP_STRIP_DWO}, + {"strip-symbol", required_argument, NULL, 'N'}, + {"strip-symbols", required_argument, NULL, ECP_STRIP_SYMBOLS}, + {"strip-unneeded", no_argument, NULL, ECP_STRIP_UNNEEDED}, + {"version", no_argument, NULL, 'V'}, + {"weaken", no_argument, NULL, ECP_WEAKEN_ALL}, + {"weaken-symbol", required_argument, NULL, 'W'}, + {"weaken-symbols", required_argument, NULL, ECP_WEAKEN_SYMBOLS}, + {"wildcard", no_argument, NULL, 'w'}, + {NULL, 0, NULL, 0} +}; + +static struct { + const char *name; + int value; +} sec_flags[] = { + {"alloc", SF_ALLOC}, + {"load", SF_LOAD}, + {"noload", SF_NOLOAD}, + {"readonly", SF_READONLY}, + {"debug", SF_DEBUG}, + {"code", SF_CODE}, + {"data", SF_DATA}, + {"rom", SF_ROM}, + {"share", SF_SHARED}, + {"contents", SF_CONTENTS}, + {NULL, 0} +}; + +static struct { + const char *name; + int abi; +} osabis[] = { + {"sysv", ELFOSABI_SYSV}, + {"hpus", ELFOSABI_HPUX}, + {"netbsd", ELFOSABI_NETBSD}, + {"linux", ELFOSABI_LINUX}, + {"hurd", ELFOSABI_HURD}, + {"86open", ELFOSABI_86OPEN}, + {"solaris", ELFOSABI_SOLARIS}, + {"aix", ELFOSABI_AIX}, + {"irix", ELFOSABI_IRIX}, + {"freebsd", ELFOSABI_FREEBSD}, + {"tru64", ELFOSABI_TRU64}, + {"modesto", ELFOSABI_MODESTO}, + {"openbsd", ELFOSABI_OPENBSD}, + {"openvms", ELFOSABI_OPENVMS}, + {"nsk", ELFOSABI_NSK}, + {"cloudabi", ELFOSABI_CLOUDABI}, + {"arm", ELFOSABI_ARM}, + {"standalone", ELFOSABI_STANDALONE}, + {NULL, 0} +}; + +static int copy_from_tempfile(const char *src, const char *dst, + int infd, int *outfd, int in_place); +static void create_file(struct elfcopy *ecp, const char *src, + const char *dst); +static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv); +static void elfcopy_usage(int); +static void mcs_main(struct elfcopy *ecp, int argc, char **argv); +static void mcs_usage(int); +static void parse_sec_address_op(struct elfcopy *ecp, int optnum, + const char *optname, char *s); +static void parse_sec_flags(struct sec_action *sac, char *s); +static void parse_symlist_file(struct elfcopy *ecp, const char *fn, + unsigned int op); +static void print_version(void); +static void set_input_target(struct elfcopy *ecp, const char *target_name); +static void set_osabi(struct elfcopy *ecp, const char *abi); +static void set_output_target(struct elfcopy *ecp, const char *target_name); +static void strip_main(struct elfcopy *ecp, int argc, char **argv); +static void strip_usage(int); + +/* + * An ELF object usually has a structure described by the + * diagram below. + * _____________ + * | | + * | NULL | <- always a SHT_NULL section + * |_____________| + * | | + * | .interp | + * |_____________| + * | | + * | ... | + * |_____________| + * | | + * | .text | + * |_____________| + * | | + * | ... | + * |_____________| + * | | + * | .comment | <- above(include) this: normal sections + * |_____________| + * | | + * | add sections| <- unloadable sections added by --add-section + * |_____________| + * | | + * | .shstrtab | <- section name string table + * |_____________| + * | | + * | shdrs | <- section header table + * |_____________| + * | | + * | .symtab | <- symbol table, if any + * |_____________| + * | | + * | .strtab | <- symbol name string table, if any + * |_____________| + * | | + * | .rel.text | <- relocation info for .o files. + * |_____________| + */ +void +create_elf(struct elfcopy *ecp) +{ + struct section *shtab; + GElf_Ehdr ieh; + GElf_Ehdr oeh; + size_t ishnum; + + ecp->flags |= SYMTAB_INTACT; + ecp->flags &= ~SYMTAB_EXIST; + + /* Create EHDR. */ + if (gelf_getehdr(ecp->ein, &ieh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + if ((ecp->iec = gelf_getclass(ecp->ein)) == ELFCLASSNONE) + errx(EXIT_FAILURE, "getclass() failed: %s", + elf_errmsg(-1)); + + if (ecp->oec == ELFCLASSNONE) + ecp->oec = ecp->iec; + if (ecp->oed == ELFDATANONE) + ecp->oed = ieh.e_ident[EI_DATA]; + + if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) + errx(EXIT_FAILURE, "gelf_newehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + memcpy(oeh.e_ident, ieh.e_ident, sizeof(ieh.e_ident)); + oeh.e_ident[EI_CLASS] = ecp->oec; + oeh.e_ident[EI_DATA] = ecp->oed; + if (ecp->abi != -1) + oeh.e_ident[EI_OSABI] = ecp->abi; + oeh.e_flags = ieh.e_flags; + oeh.e_machine = ieh.e_machine; + oeh.e_type = ieh.e_type; + oeh.e_entry = ieh.e_entry; + oeh.e_version = ieh.e_version; + + ecp->flags &= ~(EXECUTABLE | DYNAMIC | RELOCATABLE); + if (ieh.e_type == ET_EXEC) + ecp->flags |= EXECUTABLE; + else if (ieh.e_type == ET_DYN) + ecp->flags |= DYNAMIC; + else if (ieh.e_type == ET_REL) + ecp->flags |= RELOCATABLE; + else + errx(EXIT_FAILURE, "unsupported e_type"); + + if (!elf_getshnum(ecp->ein, &ishnum)) + errx(EXIT_FAILURE, "elf_getshnum failed: %s", + elf_errmsg(-1)); + if (ishnum > 0 && (ecp->secndx = calloc(ishnum, + sizeof(*ecp->secndx))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + + /* Read input object program header. */ + setup_phdr(ecp); + + /* + * Scan of input sections: we iterate through sections from input + * object, skip sections need to be stripped, allot Elf_Scn and + * create internal section structure for sections we want. + * (i.e., determine output sections) + */ + create_scn(ecp); + + /* Apply section address changes, if any. */ + adjust_addr(ecp); + + /* + * Determine if the symbol table needs to be changed based on + * command line options. + */ + if (ecp->strip == STRIP_DEBUG || + ecp->strip == STRIP_UNNEEDED || + ecp->flags & WEAKEN_ALL || + ecp->flags & LOCALIZE_HIDDEN || + ecp->flags & DISCARD_LOCAL || + ecp->flags & DISCARD_LLABEL || + ecp->prefix_sym != NULL || + !STAILQ_EMPTY(&ecp->v_symop)) + ecp->flags &= ~SYMTAB_INTACT; + + /* + * Create symbol table. Symbols are filtered or stripped according to + * command line args specified by user, and later updated for the new + * layout of sections in the output object. + */ + if ((ecp->flags & SYMTAB_EXIST) != 0) + create_symtab(ecp); + + /* + * First processing of output sections: at this stage we copy the + * content of each section from input to output object. Section + * content will be modified and printed (mcs) if need. Also content of + * relocation section probably will be filtered and updated according + * to symbol table changes. + */ + copy_content(ecp); + + /* + * Write the underlying ehdr. Note that it should be called + * before elf_setshstrndx() since it will overwrite e->e_shstrndx. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* + * Second processing of output sections: Update section headers. + * At this stage we set name string index, update st_link and st_info + * for output sections. + */ + update_shdr(ecp, 1); + + /* Renew oeh to get the updated e_shstrndx. */ + if (gelf_getehdr(ecp->eout, &oeh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* + * Insert SHDR table into the internal section list as a "pseudo" + * section, so later it will get sorted and resynced just as "normal" + * sections. + * + * Under FreeBSD, Binutils objcopy always put the section header + * at the end of all the sections. We want to do the same here. + * + * However, note that the behaviour is still different with Binutils: + * elfcopy checks the FreeBSD OSABI tag to tell whether it needs to + * move the section headers, while Binutils is probably configured + * this way when it's compiled on FreeBSD. + */ + if (oeh.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) + shtab = insert_shtab(ecp, 1); + else + shtab = insert_shtab(ecp, 0); + + /* + * Resync section offsets in the output object. This is needed + * because probably sections are modified or new sections are added, + * as a result overlap/gap might appears. + */ + resync_sections(ecp); + + /* Store SHDR offset in EHDR. */ + oeh.e_shoff = shtab->off; + + /* Put program header table immediately after the Elf header. */ + if (ecp->ophnum > 0) { + oeh.e_phoff = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); + if (oeh.e_phoff == 0) + errx(EXIT_FAILURE, "gelf_fsize() failed: %s", + elf_errmsg(-1)); + } + + /* + * Update ELF object entry point if requested. + */ + if (ecp->change_addr != 0) + oeh.e_entry += ecp->change_addr; + if (ecp->flags & SET_START) + oeh.e_entry = ecp->set_start; + if (ecp->change_start != 0) + oeh.e_entry += ecp->change_start; + + /* + * Update ehdr again before we call elf_update(), since we + * modified e_shoff and e_phoff. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + if (ecp->ophnum > 0) + copy_phdr(ecp); + + /* Write out the output elf object. */ + if (elf_update(ecp->eout, ELF_C_WRITE) < 0) + errx(EXIT_FAILURE, "elf_update() failed: %s", + elf_errmsg(-1)); + + /* Release allocated resource. */ + free_elf(ecp); +} + +void +free_elf(struct elfcopy *ecp) +{ + struct segment *seg, *seg_temp; + struct section *sec, *sec_temp; + + /* Free internal segment list. */ + if (!STAILQ_EMPTY(&ecp->v_seg)) { + STAILQ_FOREACH_SAFE(seg, &ecp->v_seg, seg_list, seg_temp) { + STAILQ_REMOVE(&ecp->v_seg, seg, segment, seg_list); + free(seg); + } + } + + /* Free symbol table buffers. */ + free_symtab(ecp); + + /* Free section name string table. */ + elftc_string_table_destroy(ecp->shstrtab->strtab); + + /* Free internal section list. */ + if (!TAILQ_EMPTY(&ecp->v_sec)) { + TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) { + TAILQ_REMOVE(&ecp->v_sec, sec, sec_list); + if (sec->buf != NULL) + free(sec->buf); + if (sec->newname != NULL) + free(sec->newname); + if (sec->pad != NULL) + free(sec->pad); + free(sec); + } + } + + ecp->symtab = NULL; + ecp->strtab = NULL; + ecp->shstrtab = NULL; + + if (ecp->secndx != NULL) { + free(ecp->secndx); + ecp->secndx = NULL; + } +} + +/* + * Remove a temporary file, without freeing its filename. + * + * Safe to pass NULL, will just ignore it. + */ +int +cleanup_tempfile(char *fn) +{ + int errno_save, retval; + + if (fn == NULL) + return 0; + errno_save = errno; + if ((retval = unlink(fn)) < 0) { + warn("unlink tempfile %s failed", fn); + errno = errno_save; + return retval; + } + return 0; +} + +/* + * Determine the directory to write to. + * + * If 'src' is non-NULL, it is treated as a file name whose containing + * directory is returned. + * + * If 'src' is NULL and if the environment variable TMPDIR is non-empty, + * then the value of TMPDIR is used. + * + * If 'src' is NULL and if the environment variable TMPDIR is empty, + * then the string "/tmp" is returned. + * + * The returned pointer is owned by the caller. + */ +static char * +get_directory_path(const char *src) +{ + char *tmpsrc, *tmpdir; + + if (src == NULL) { + if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') + return strdup("/tmp"); + return strdup(tmpdir); + } + + /* Make a copy of 'src', so that dirname(3) can be used. */ + tmpsrc = strdup(src); + + tmpdir = strdup(dirname(tmpsrc)); + + free(tmpsrc); + + return (tmpdir); +} + +/* + * Create a temporary file. + * + * If 'src' is non-NULL, the temporary file is created in its containing + * directory. Otherwise, the temporary file is created in the directory + * named by $TMPDIR if $TMPDIR is set, or in /tmp otherwise. + * + * The generated temporary file is stored in '*fn' and a file descriptor + * opened for reading and writing is stored in '*fd'. + */ +void +create_tempfile(const char *src, char **fn, int *fd) +{ + static const char _TEMPLATE[] = "/ecp.XXXXXXXX"; + char *tmpdir; + char *tmpfile; + size_t pathlen, retries; + + if (fn == NULL || fd == NULL) + return; + + /* + * If src is not NULL, we first try to create the temporary file in + * the containing directory for 'src'. If that attempt fails, we + * try again using ${TMPDIR:-/tmp}. + * + * If src is NULL, we only try once to create the file in + * ${TMPDIR:-/tmp}. + */ + for (retries = (src == NULL); retries < 2; src = NULL, retries++) { + tmpdir = get_directory_path(src); + + /* + * Reserve space for the directory name and the template, + * including its trailing NUL. + */ + pathlen = strlen(tmpdir) + sizeof(_TEMPLATE); + if ((tmpfile = malloc(pathlen)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + + /* Construct the file path. */ + stpcpy(stpcpy(tmpfile, tmpdir), _TEMPLATE); + + free(tmpdir); + + /* Try to create the file */ + errno = 0; + if ((*fd = mkstemp(tmpfile)) != -1) + break; /* Success. */ + + /* Otherwise, check if we should retry. */ + if (errno != EACCES || retries != 0) + err(EXIT_FAILURE, "mkstemp %s failed", tmpfile); + } + + if (fchmod(*fd, 0644) == -1) + err(EXIT_FAILURE, "fchmod %s failed", tmpfile); + *fn = tmpfile; +} + +/* + * Copy temporary file with path src and file descriptor infd to path dst. + * If in_place is set act as if editing the file in place, avoiding rename() + * to preserve hard and symbolic links. Output file remains open, with file + * descriptor returned in outfd. + */ +static int +copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd, + int in_place) +{ + int tmpfd; + + /* + * First, check if we can use rename(). + */ + if (in_place == 0) { + if (rename(src, dst) >= 0) { + *outfd = infd; + return (0); + } else if (errno != EXDEV) + return (-1); + + /* + * If the rename() failed due to 'src' and 'dst' residing in + * two different file systems, invoke a helper function in + * libelftc to do the copy. + */ + + if (unlink(dst) < 0) + return (-1); + } + + if ((tmpfd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, 0755)) < 0) + return (-1); + + if (elftc_copyfile(infd, tmpfd) < 0) { + (void) close(tmpfd); + return (-1); + } + + /* + * Remove the temporary file from the file system + * namespace, and close its file descriptor. + */ + if (unlink(src) < 0) { + (void) close(tmpfd); + return (-1); + } + + (void) close(infd); + + /* + * Return the file descriptor for the destination. + */ + *outfd = tmpfd; + + return (0); +} + +static void +create_file(struct elfcopy *ecp, const char *src, const char *dst) +{ + struct stat sb; + char *tempfile, *elftemp; + int efd, ifd, ofd, ofd0, tfd; + int in_place; + + tempfile = NULL; + + if (src == NULL) + errx(EXIT_FAILURE, "internal: src == NULL"); + if ((ifd = open(src, O_RDONLY)) == -1) + err(EXIT_FAILURE, "open %s failed", src); + + if (fstat(ifd, &sb) == -1) + err(EXIT_FAILURE, "fstat %s failed", src); + + if (dst == NULL) + create_tempfile(src, &tempfile, &ofd); + else + if ((ofd = open(dst, O_RDWR|O_CREAT, 0755)) == -1) + err(EXIT_FAILURE, "open %s failed", dst); + +#ifndef LIBELF_AR + /* Detect and process ar(1) archive using libarchive. */ + if (ac_detect_ar(ifd)) { + ac_create_ar(ecp, ifd, ofd); + goto copy_done; + } +#endif + + if (lseek(ifd, 0, SEEK_SET) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "lseek failed"); + } + + /* + * If input object is not ELF file, convert it to an intermediate + * ELF object before processing. + */ + if (ecp->itf != ETF_ELF) { + /* + * If the output object is not an ELF file, choose an arbitrary + * ELF format for the intermediate file. srec, ihex and binary + * formats are independent of class, endianness and machine + * type so these choices do not affect the output. + */ + if (ecp->otf != ETF_ELF) { + if (ecp->oec == ELFCLASSNONE) + ecp->oec = ELFCLASS64; + if (ecp->oed == ELFDATANONE) + ecp->oed = ELFDATA2LSB; + } + create_tempfile(src, &elftemp, &efd); + if ((ecp->eout = elf_begin(efd, ELF_C_WRITE, NULL)) == NULL) { + cleanup_tempfile(elftemp); + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + } + elf_flagelf(ecp->eout, ELF_C_SET, ELF_F_LAYOUT); + if (ecp->itf == ETF_BINARY) + create_elf_from_binary(ecp, ifd, src); + else if (ecp->itf == ETF_IHEX) + create_elf_from_ihex(ecp, ifd); + else if (ecp->itf == ETF_SREC) + create_elf_from_srec(ecp, ifd); + else { + cleanup_tempfile(elftemp); + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "Internal: invalid target flavour"); + } + elf_end(ecp->eout); + + /* Open intermediate ELF object as new input object. */ + close(ifd); + if ((ifd = open(elftemp, O_RDONLY)) == -1) { + cleanup_tempfile(elftemp); + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "open %s failed", src); + } + close(efd); + if (cleanup_tempfile(elftemp) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "unlink %s failed", elftemp); + } + free(elftemp); + elftemp = NULL; + } + + if ((ecp->ein = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) { + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + } + + switch (elf_kind(ecp->ein)) { + case ELF_K_NONE: + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "file format not recognized"); + case ELF_K_ELF: + if ((ecp->eout = elf_begin(ofd, ELF_C_WRITE, NULL)) == NULL) { + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + } + + /* elfcopy(1) manage ELF layout by itself. */ + elf_flagelf(ecp->eout, ELF_C_SET, ELF_F_LAYOUT); + + /* + * Create output ELF object. + */ + create_elf(ecp); + elf_end(ecp->eout); + + /* + * Convert the output ELF object to binary/srec/ihex if need. + */ + if (ecp->otf != ETF_ELF) { + /* + * Create (another) tempfile for binary/srec/ihex + * output object. + */ + if (cleanup_tempfile(tempfile) < 0) + errx(EXIT_FAILURE, "unlink %s failed", + tempfile); + free(tempfile); + create_tempfile(src, &tempfile, &ofd0); + + + /* + * Rewind the file descriptor being processed. + */ + if (lseek(ofd, 0, SEEK_SET) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, + "lseek failed for the output object"); + } + + /* + * Call flavour-specific conversion routine. + */ + switch (ecp->otf) { + case ETF_BINARY: + create_binary(ofd, ofd0); + break; + case ETF_IHEX: + create_ihex(ofd, ofd0); + break; + case ETF_SREC: + create_srec(ecp, ofd, ofd0, + dst != NULL ? dst : src); + break; + case ETF_PE: + case ETF_EFI: +#if WITH_PE + create_pe(ecp, ofd, ofd0); +#else + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "PE/EFI support not enabled" + " at compile time"); +#endif + break; + default: + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "Internal: unsupported" + " output flavour %d", ecp->oec); + } + + close(ofd); + ofd = ofd0; + } + + break; + + case ELF_K_AR: + /* XXX: Not yet supported. */ + break; + default: + cleanup_tempfile(tempfile); + errx(EXIT_FAILURE, "file format not supported"); + } + + elf_end(ecp->ein); + +#ifndef LIBELF_AR +copy_done: +#endif + + if (tempfile != NULL) { + in_place = 0; + if (dst == NULL) { + dst = src; + if (lstat(dst, &sb) != -1 && + (sb.st_nlink > 1 || S_ISLNK(sb.st_mode))) + in_place = 1; + } + + if (copy_from_tempfile(tempfile, dst, ofd, + &tfd, in_place) < 0) { + cleanup_tempfile(tempfile); + err(EXIT_FAILURE, "creation of %s failed", dst); + } + + /* 'tempfile' has been removed by copy_from_tempfile(). */ + free(tempfile); + tempfile = NULL; + + ofd = tfd; + } + + if (strcmp(dst, "/dev/null") && fchmod(ofd, sb.st_mode) == -1) + err(EXIT_FAILURE, "fchmod %s failed", dst); + + if ((ecp->flags & PRESERVE_DATE) && + elftc_set_timestamps(dst, &sb) < 0) + err(EXIT_FAILURE, "setting timestamps failed"); + + close(ifd); + close(ofd); +} + +static void +elfcopy_main(struct elfcopy *ecp, int argc, char **argv) +{ + struct sec_action *sac; + const char *infile, *outfile; + char *fn, *s; + int opt; + + while ((opt = getopt_long(argc, argv, "dB:gG:I:j:K:L:N:O:pR:s:SwW:xXV", + elfcopy_longopts, NULL)) != -1) { + switch(opt) { + case 'B': + /* ignored */ + break; + case 'R': + sac = lookup_sec_act(ecp, optarg, 1); + if (sac->copy != 0) + errx(EXIT_FAILURE, + "both copy and remove specified"); + sac->remove = 1; + ecp->flags |= SEC_REMOVE; + break; + case 'S': + ecp->strip = STRIP_ALL; + break; + case 'g': + ecp->strip = STRIP_DEBUG; + break; + case 'G': + ecp->flags |= KEEP_GLOBAL; + add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEPG); + break; + case 'I': + case 's': + set_input_target(ecp, optarg); + break; + case 'j': + sac = lookup_sec_act(ecp, optarg, 1); + if (sac->remove != 0) + errx(EXIT_FAILURE, + "both copy and remove specified"); + sac->copy = 1; + ecp->flags |= SEC_COPY; + break; + case 'K': + add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEP); + break; + case 'L': + add_to_symop_list(ecp, optarg, NULL, SYMOP_LOCALIZE); + break; + case 'N': + add_to_symop_list(ecp, optarg, NULL, SYMOP_STRIP); + break; + case 'O': + set_output_target(ecp, optarg); + break; + case 'p': + ecp->flags |= PRESERVE_DATE; + break; + case 'V': + print_version(); + break; + case 'w': + ecp->flags |= WILDCARD; + break; + case 'W': + add_to_symop_list(ecp, optarg, NULL, SYMOP_WEAKEN); + break; + case 'x': + ecp->flags |= DISCARD_LOCAL; + break; + case 'X': + ecp->flags |= DISCARD_LLABEL; + break; + case ECP_ADD_GNU_DEBUGLINK: + ecp->debuglink = optarg; + break; + case ECP_ADD_SECTION: + add_section(ecp, optarg); + break; + case ECP_CHANGE_ADDR: + ecp->change_addr = (int64_t) strtoll(optarg, NULL, 0); + break; + case ECP_CHANGE_SEC_ADDR: + parse_sec_address_op(ecp, opt, "--change-section-addr", + optarg); + break; + case ECP_CHANGE_SEC_LMA: + parse_sec_address_op(ecp, opt, "--change-section-lma", + optarg); + break; + case ECP_CHANGE_SEC_VMA: + parse_sec_address_op(ecp, opt, "--change-section-vma", + optarg); + break; + case ECP_CHANGE_START: + ecp->change_start = (int64_t) strtoll(optarg, NULL, 0); + break; + case ECP_CHANGE_WARN: + /* default */ + break; + case ECP_GAP_FILL: + ecp->fill = (uint8_t) strtoul(optarg, NULL, 0); + ecp->flags |= GAP_FILL; + break; + case ECP_GLOBALIZE_SYMBOL: + add_to_symop_list(ecp, optarg, NULL, SYMOP_GLOBALIZE); + break; + case ECP_GLOBALIZE_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_GLOBALIZE); + break; + case ECP_KEEP_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_KEEP); + break; + case ECP_KEEP_GLOBAL_SYMBOLS: + ecp->flags |= KEEP_GLOBAL; + parse_symlist_file(ecp, optarg, SYMOP_KEEPG); + break; + case ECP_LOCALIZE_HIDDEN: + ecp->flags |= LOCALIZE_HIDDEN; + break; + case ECP_LOCALIZE_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_LOCALIZE); + break; + case ECP_NO_CHANGE_WARN: + ecp->flags |= NO_CHANGE_WARN; + break; + case ECP_ONLY_DEBUG: + ecp->strip = STRIP_NONDEBUG; + break; + case ECP_ONLY_DWO: + ecp->strip = STRIP_NONDWO; + break; + case ECP_PAD_TO: + ecp->pad_to = (uint64_t) strtoull(optarg, NULL, 0); + break; + case ECP_PREFIX_ALLOC: + ecp->prefix_alloc = optarg; + break; + case ECP_PREFIX_SEC: + ecp->prefix_sec = optarg; + break; + case ECP_PREFIX_SYM: + ecp->prefix_sym = optarg; + break; + case ECP_REDEF_SYMBOL: + if ((s = strchr(optarg, '=')) == NULL) + errx(EXIT_FAILURE, + "illegal format for --redefine-sym"); + *s++ = '\0'; + add_to_symop_list(ecp, optarg, s, SYMOP_REDEF); + break; + case ECP_REDEF_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_REDEF); + break; + case ECP_RENAME_SECTION: + if ((fn = strchr(optarg, '=')) == NULL) + errx(EXIT_FAILURE, + "illegal format for --rename-section"); + *fn++ = '\0'; + + /* Check for optional flags. */ + if ((s = strchr(fn, ',')) != NULL) + *s++ = '\0'; + + sac = lookup_sec_act(ecp, optarg, 1); + sac->rename = 1; + sac->newname = fn; + if (s != NULL) + parse_sec_flags(sac, s); + break; + case ECP_SET_OSABI: + set_osabi(ecp, optarg); + break; + case ECP_SET_SEC_FLAGS: + if ((s = strchr(optarg, '=')) == NULL) + errx(EXIT_FAILURE, + "illegal format for --set-section-flags"); + *s++ = '\0'; + sac = lookup_sec_act(ecp, optarg, 1); + parse_sec_flags(sac, s); + break; + case ECP_SET_START: + ecp->flags |= SET_START; + ecp->set_start = (uint64_t) strtoull(optarg, NULL, 0); + break; + case ECP_SREC_FORCE_S3: + ecp->flags |= SREC_FORCE_S3; + break; + case ECP_SREC_LEN: + ecp->flags |= SREC_FORCE_LEN; + ecp->srec_len = strtoul(optarg, NULL, 0); + break; + case ECP_STRIP_DWO: + ecp->strip = STRIP_DWO; + break; + case ECP_STRIP_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_STRIP); + break; + case ECP_STRIP_UNNEEDED: + ecp->strip = STRIP_UNNEEDED; + break; + case ECP_WEAKEN_ALL: + ecp->flags |= WEAKEN_ALL; + break; + case ECP_WEAKEN_SYMBOLS: + parse_symlist_file(ecp, optarg, SYMOP_WEAKEN); + break; + default: + elfcopy_usage(EX_USAGE); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0 || argc > 2) + elfcopy_usage(EX_USAGE); + + infile = argv[0]; + outfile = NULL; + if (argc > 1) + outfile = argv[1]; + + create_file(ecp, infile, outfile); +} + +static void +mcs_main(struct elfcopy *ecp, int argc, char **argv) +{ + struct sec_action *sac; + const char *string; + int append, delete, compress, name, print; + int opt, i; + + append = delete = compress = name = print = 0; + string = NULL; + while ((opt = getopt_long(argc, argv, "a:cdhn:pV", mcs_longopts, + NULL)) != -1) { + switch(opt) { + case 'a': + append = 1; + string = optarg; /* XXX multiple -a not supported */ + break; + case 'c': + compress = 1; + break; + case 'd': + delete = 1; + break; + case 'n': + name = 1; + (void)lookup_sec_act(ecp, optarg, 1); + break; + case 'p': + print = 1; + break; + case 'V': + print_version(); + break; + case 'h': + mcs_usage(EX_OK); + break; + default: + mcs_usage(EX_USAGE); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + mcs_usage(EX_USAGE); + + /* Must specify one operation at least. */ + if (!append && !compress && !delete && !print) + mcs_usage(EX_USAGE); + + /* + * If we are going to delete, ignore other operations. This is + * different from the Solaris implementation, which can print + * and delete a section at the same time, for example. Also, this + * implementation do not respect the order between operations that + * user specified, i.e., "mcs -pc a.out" equals to "mcs -cp a.out". + */ + if (delete) { + append = compress = print = 0; + ecp->flags |= SEC_REMOVE; + } + if (append) + ecp->flags |= SEC_APPEND; + if (compress) + ecp->flags |= SEC_COMPRESS; + if (print) + ecp->flags |= SEC_PRINT; + + /* .comment is the default section to operate on. */ + if (!name) + (void)lookup_sec_act(ecp, ".comment", 1); + + STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { + sac->append = append; + sac->compress = compress; + sac->print = print; + sac->remove = delete; + sac->string = string; + } + + for (i = 0; i < argc; i++) { + /* If only -p is specified, output to /dev/null */ + if (print && !append && !compress && !delete) + create_file(ecp, argv[i], "/dev/null"); + else + create_file(ecp, argv[i], NULL); + } +} + +static void +strip_main(struct elfcopy *ecp, int argc, char **argv) +{ + struct sec_action *sac; + const char *outfile; + int opt; + int i; + + outfile = NULL; + while ((opt = getopt_long(argc, argv, "hI:K:N:o:O:pR:sSdgVxXw", + strip_longopts, NULL)) != -1) { + switch(opt) { + case 'R': + sac = lookup_sec_act(ecp, optarg, 1); + sac->remove = 1; + ecp->flags |= SEC_REMOVE; + break; + case 's': + ecp->strip = STRIP_ALL; + break; + case 'S': + case 'g': + case 'd': + ecp->strip = STRIP_DEBUG; + break; + case 'I': + /* ignored */ + break; + case 'K': + add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEP); + break; + case 'N': + add_to_symop_list(ecp, optarg, NULL, SYMOP_STRIP); + break; + case 'o': + outfile = optarg; + break; + case 'O': + set_output_target(ecp, optarg); + break; + case 'p': + ecp->flags |= PRESERVE_DATE; + break; + case 'V': + print_version(); + break; + case 'w': + ecp->flags |= WILDCARD; + break; + case 'x': + ecp->flags |= DISCARD_LOCAL; + break; + case 'X': + ecp->flags |= DISCARD_LLABEL; + break; + case ECP_ONLY_DEBUG: + ecp->strip = STRIP_NONDEBUG; + break; + case ECP_STRIP_UNNEEDED: + ecp->strip = STRIP_UNNEEDED; + break; + case 'h': + strip_usage(EX_OK); + break; + default: + strip_usage(EX_USAGE); + break; + } + } + + argc -= optind; + argv += optind; + + if (ecp->strip == 0 && + ((ecp->flags & DISCARD_LOCAL) == 0) && + ((ecp->flags & DISCARD_LLABEL) == 0) && + lookup_symop_list(ecp, NULL, SYMOP_STRIP) == NULL) + ecp->strip = STRIP_ALL; + if (argc == 0) + strip_usage(EX_USAGE); + /* + * Only accept a single input file if an output file had been + * specified. + */ + if (outfile != NULL && argc != 1) + strip_usage(EX_USAGE); + + for (i = 0; i < argc; i++) + create_file(ecp, argv[i], outfile); +} + +static void +parse_sec_flags(struct sec_action *sac, char *s) +{ + const char *flag; + int found, i; + + for (flag = strtok(s, ","); flag; flag = strtok(NULL, ",")) { + found = 0; + for (i = 0; sec_flags[i].name != NULL; i++) + if (strcasecmp(sec_flags[i].name, flag) == 0) { + sac->flags |= sec_flags[i].value; + found = 1; + break; + } + if (!found) + errx(EXIT_FAILURE, "unrecognized section flag %s", + flag); + } +} + +static void +parse_sec_address_op(struct elfcopy *ecp, int optnum, const char *optname, + char *s) +{ + struct sec_action *sac; + const char *name; + char *v; + char op; + + name = v = s; + do { + v++; + } while (*v != '\0' && *v != '=' && *v != '+' && *v != '-'); + if (*v == '\0' || *(v + 1) == '\0') + errx(EXIT_FAILURE, "invalid format for %s", optname); + op = *v; + *v++ = '\0'; + sac = lookup_sec_act(ecp, name, 1); + switch (op) { + case '=': + if (optnum == ECP_CHANGE_SEC_LMA || + optnum == ECP_CHANGE_SEC_ADDR) { + sac->setlma = 1; + sac->lma = (uint64_t) strtoull(v, NULL, 0); + } + if (optnum == ECP_CHANGE_SEC_VMA || + optnum == ECP_CHANGE_SEC_ADDR) { + sac->setvma = 1; + sac->vma = (uint64_t) strtoull(v, NULL, 0); + } + break; + case '+': + if (optnum == ECP_CHANGE_SEC_LMA || + optnum == ECP_CHANGE_SEC_ADDR) + sac->lma_adjust = (int64_t) strtoll(v, NULL, 0); + if (optnum == ECP_CHANGE_SEC_VMA || + optnum == ECP_CHANGE_SEC_ADDR) + sac->vma_adjust = (int64_t) strtoll(v, NULL, 0); + break; + case '-': + if (optnum == ECP_CHANGE_SEC_LMA || + optnum == ECP_CHANGE_SEC_ADDR) + sac->lma_adjust = (int64_t) -strtoll(v, NULL, 0); + if (optnum == ECP_CHANGE_SEC_VMA || + optnum == ECP_CHANGE_SEC_ADDR) + sac->vma_adjust = (int64_t) -strtoll(v, NULL, 0); + break; + default: + break; + } +} + +static void +parse_symlist_file(struct elfcopy *ecp, const char *fn, unsigned int op) +{ + struct symfile *sf; + struct stat sb; + FILE *fp; + char *data, *p, *line, *end, *e, *n; + + if (stat(fn, &sb) == -1) + err(EXIT_FAILURE, "stat %s failed", fn); + + /* Check if we already read and processed this file. */ + STAILQ_FOREACH(sf, &ecp->v_symfile, symfile_list) { + if (sf->dev == sb.st_dev && sf->ino == sb.st_ino) + goto process_symfile; + } + + if ((fp = fopen(fn, "r")) == NULL) + err(EXIT_FAILURE, "can not open %s", fn); + if ((data = malloc(sb.st_size + 1)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if (sb.st_size > 0) + if (fread(data, sb.st_size, 1, fp) != 1) + err(EXIT_FAILURE, "fread failed"); + fclose(fp); + data[sb.st_size] = '\0'; + + if ((sf = calloc(1, sizeof(*sf))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + sf->dev = sb.st_dev; + sf->ino = sb.st_ino; + sf->size = sb.st_size + 1; + sf->data = data; + +process_symfile: + + /* + * Basically what we do here is to convert EOL to '\0', and remove + * leading and trailing whitespaces for each line. + */ + + end = sf->data + sf->size; + line = NULL; + for(p = sf->data; p < end; p++) { + if ((*p == '\t' || *p == ' ') && line == NULL) + continue; + if (*p == '\r' || *p == '\n' || *p == '\0') { + *p = '\0'; + if (line == NULL) + continue; + + /* Skip comment. */ + if (*line == '#') { + line = NULL; + continue; + } + + e = p - 1; + while(e != line && (*e == '\t' || *e == ' ')) + *e-- = '\0'; + if (op != SYMOP_REDEF) + add_to_symop_list(ecp, line, NULL, op); + else { + if (strlen(line) < 3) + errx(EXIT_FAILURE, + "illegal format for" + " --redefine-sym"); + for(n = line + 1; n < e; n++) { + if (*n == ' ' || *n == '\t') { + while(*n == ' ' || *n == '\t') + *n++ = '\0'; + break; + } + } + if (n >= e) + errx(EXIT_FAILURE, + "illegal format for" + " --redefine-sym"); + add_to_symop_list(ecp, line, n, op); + } + line = NULL; + continue; + } + + if (line == NULL) + line = p; + } +} + +static void +set_input_target(struct elfcopy *ecp, const char *target_name) +{ + Elftc_Bfd_Target *tgt; + + if ((tgt = elftc_bfd_find_target(target_name)) == NULL) + errx(EXIT_FAILURE, "%s: invalid target name", target_name); + ecp->itf = elftc_bfd_target_flavor(tgt); +} + +static void +set_output_target(struct elfcopy *ecp, const char *target_name) +{ + Elftc_Bfd_Target *tgt; + + if ((tgt = elftc_bfd_find_target(target_name)) == NULL) + errx(EXIT_FAILURE, "%s: invalid target name", target_name); + ecp->otf = elftc_bfd_target_flavor(tgt); + if (ecp->otf == ETF_ELF) { + ecp->oec = elftc_bfd_target_class(tgt); + ecp->oed = elftc_bfd_target_byteorder(tgt); + ecp->oem = elftc_bfd_target_machine(tgt); + ecp->abi = elftc_bfd_target_osabi(tgt); + } + if (ecp->otf == ETF_EFI || ecp->otf == ETF_PE) + ecp->oem = elftc_bfd_target_machine(tgt); + + ecp->otgt = target_name; +} + +static void +set_osabi(struct elfcopy *ecp, const char *abi) +{ + int i, found; + + found = 0; + for (i = 0; osabis[i].name != NULL; i++) + if (strcasecmp(osabis[i].name, abi) == 0) { + ecp->abi = osabis[i].abi; + found = 1; + break; + } + if (!found) + errx(EXIT_FAILURE, "unrecognized OSABI %s", abi); +} + +#define ELFCOPY_USAGE_MESSAGE "\ +Usage: %s [options] infile [outfile]\n\ + Transform object files.\n\n\ + Options:\n\ + -d | -g | --strip-debug Remove debugging information from the output.\n\ + -j SECTION | --only-section=SECTION\n\ + Copy only the named section to the output.\n\ + -p | --preserve-dates Preserve access and modification times.\n\ + -w | --wildcard Use shell-style patterns to name symbols.\n\ + -x | --discard-all Do not copy non-globals to the output.\n\ + -G SYMFILE | --keep-global-symbols=SYMFILE\n\ + Keep the symbols specified in SYMFILE as\n\ + global, making other symbols local to the\n\ + file.\n\ + -I FORMAT | --input-target=FORMAT\n\ + Specify object format for the input file.\n\ + -K SYM | --keep-symbol=SYM Copy symbol SYM to the output.\n\ + -L SYM | --localize-symbol=SYM\n\ + Make symbol SYM local to the output file.\n\ + -N SYM | --strip-symbol=SYM Do not copy symbol SYM to the output.\n\ + -O FORMAT | --output-target=FORMAT\n\ + Specify object format for the output file.\n\ + FORMAT should be a target name understood by\n\ + elftc_bfd_find_target(3).\n\ + -R NAME | --remove-section=NAME\n\ + Remove the named section.\n\ + -S | --strip-all Remove all symbol and relocation information\n\ + from the output.\n\ + -V | --version Print a version identifier and exit.\n\ + -W SYM | --weaken-symbol=SYM Mark symbol SYM as weak in the output.\n\ + -X | --discard-locals Do not copy compiler generated symbols to\n\ + the output.\n\ + --add-section NAME=FILE Add the contents of FILE to the ELF object as\n\ + a new section named NAME.\n\ + --adjust-section-vma SECTION{=,+,-}VAL | \\\n\ + --change-section-address SECTION{=,+,-}VAL\n\ + Set or adjust the VMA and the LMA of the\n\ + named section by VAL.\n\ + --adjust-start=INCR | --change-start=INCR\n\ + Add INCR to the start address for the ELF\n\ + object.\n\ + --adjust-vma=INCR | --change-addresses=INCR\n\ + Increase the VMA and LMA of all sections by\n\ + INCR.\n\ + --adjust-warning | --change-warnings\n\ + Issue warnings for non-existent sections.\n\ + --change-section-lma SECTION{=,+,-}VAL\n\ + Set or adjust the LMA address of the named\n\ + section by VAL.\n\ + --change-section-vma SECTION{=,+,-}VAL\n\ + Set or adjust the VMA address of the named\n\ + section by VAL.\n\ + --gap-fill=VAL Fill the gaps between sections with bytes\n\ + of value VAL.\n\ + --keep-global-symbol=SYM Keep the symbol SYM as global, and make any\n\ + other symbols not otherwise specified as\n\ + global to be local to the file.\n\ + --localize-hidden Make all hidden symbols local to the output\n\ + file.\n\ + --no-adjust-warning| --no-change-warnings\n\ + Do not issue warnings for non-existent\n\ + sections.\n\ + --only-keep-debug Copy only debugging information.\n\ + --output-target=FORMAT Use the specified format for the output.\n\ + --pad-to=ADDRESS Pad the output object up to the given address.\n\ + --prefix-alloc-sections=STRING\n\ + Prefix the section names of all the allocated\n\ + sections with STRING.\n\ + --prefix-sections=STRING Prefix the section names of all the sections\n\ + with STRING.\n\ + --prefix-symbols=STRING Prefix the symbol names of all the symbols\n\ + with STRING.\n\ + --rename-section OLDNAME=NEWNAME[,FLAGS]\n\ + Rename and optionally change section flags.\n\ + --set-section-flags SECTION=FLAGS\n\ + Set section flags for the named section.\n\ + Supported flags are: 'alloc', 'code',\n\ + 'contents', 'data', 'debug', 'load',\n\ + 'noload', 'readonly', 'rom', and 'shared'.\n\ + --set-start=ADDRESS Set the start address of the ELF object.\n\ + --srec-forceS3 Only generate S3 S-Records.\n\ + --srec-len=LEN Set the maximum length of a S-Record line.\n\ + --strip-unneeded Do not copy relocation information.\n" + +static void +elfcopy_usage(int exit_code) +{ + (void) fprintf(stderr, ELFCOPY_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +#define MCS_USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Manipulate the comment section in an ELF object.\n\n\ + Options:\n\ + -a STRING Append 'STRING' to the comment section.\n\ + -c Remove duplicate entries from the comment section.\n\ + -d Delete the comment section.\n\ + -h | --help Print a help message and exit.\n\ + -n NAME Operate on the ELF section with name 'NAME'.\n\ + -p Print the contents of the comment section.\n\ + -V | --version Print a version identifier and exit.\n" + +static void +mcs_usage(int exit_code) +{ + (void) fprintf(stderr, MCS_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +#define STRIP_USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Discard information from ELF objects.\n\n\ + Options:\n\ + -d | -g | -S | --strip-debug Remove debugging symbols.\n\ + -h | --help Print a help message.\n\ + -o FILE | --output-file FILE Write output to FILE.\n\ + --only-keep-debug Keep debugging information only.\n\ + -p | --preserve-dates Preserve access and modification times.\n\ + -s | --strip-all Remove all symbols.\n\ + --strip-unneeded Remove symbols not needed for relocation\n\ + processing.\n\ + -w | --wildcard Use shell-style patterns to name symbols.\n\ + -x | --discard-all Discard all non-global symbols.\n\ + -I TGT| --input-target=TGT (Accepted, but ignored).\n\ + -K SYM | --keep-symbol=SYM Keep symbol 'SYM' in the output.\n\ + -N SYM | --strip-symbol=SYM Remove symbol 'SYM' from the output.\n\ + -O TGT | --output-target=TGT Set the output file format to 'TGT'.\n\ + -R SEC | --remove-section=SEC Remove the section named 'SEC'.\n\ + -V | --version Print a version identifier and exit.\n\ + -X | --discard-locals Remove compiler-generated local symbols.\n" + +static void +strip_usage(int exit_code) +{ + (void) fprintf(stderr, STRIP_USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +print_version(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(EXIT_SUCCESS); +} + +/* + * Compare the ending of s with end. + */ +static int +strrcmp(const char *s, const char *end) +{ + size_t endlen, slen; + + slen = strlen(s); + endlen = strlen(end); + + if (slen >= endlen) + s += slen - endlen; + return (strcmp(s, end)); +} + +int +main(int argc, char **argv) +{ + struct elfcopy *ecp; + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + ecp = calloc(1, sizeof(*ecp)); + if (ecp == NULL) + err(EXIT_FAILURE, "calloc failed"); + + ecp->itf = ecp->otf = ETF_ELF; + ecp->iec = ecp->oec = ELFCLASSNONE; + ecp->oed = ELFDATANONE; + ecp->abi = -1; + /* There is always an empty section. */ + ecp->nos = 1; + ecp->fill = 0; + + STAILQ_INIT(&ecp->v_seg); + STAILQ_INIT(&ecp->v_sac); + STAILQ_INIT(&ecp->v_sadd); + STAILQ_INIT(&ecp->v_symop); + STAILQ_INIT(&ecp->v_symfile); + STAILQ_INIT(&ecp->v_arobj); + TAILQ_INIT(&ecp->v_sec); + + if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL) + ecp->progname = "elfcopy"; + + if (strrcmp(ecp->progname, "strip") == 0) + strip_main(ecp, argc, argv); + else if (strrcmp(ecp->progname, "mcs") == 0) + mcs_main(ecp, argc, argv); + else { + if (strrcmp(ecp->progname, "elfcopy") != 0 && + strrcmp(ecp->progname, "objcopy") != 0) + warnx("program mode not known, defaulting to elfcopy"); + elfcopy_main(ecp, argc, argv); + } + + free_sec_add(ecp); + free_sec_act(ecp); + free(ecp); + + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/elfcopy/mcs.1 b/contrib/elftoolchain/elfcopy/mcs.1 new file mode 100644 index 0000000000..890154c19d --- /dev/null +++ b/contrib/elftoolchain/elfcopy/mcs.1 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JOSEPH KOSHY ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL JOSEPH KOSHY BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: mcs.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd November 29, 2011 +.Dt MCS 1 +.Os +.Sh NAME +.Nm mcs +.Nd manipulate the comment section of an ELF object +.Sh SYNOPSIS +.Nm +.Op Fl a Ar string +.Op Fl c +.Op Fl n Ar name +.Op Fl p +.Ar +.Nm +.Fl d +.Op Fl n Ar name +.Ar +.Nm +.Fl h | Fl -help +.Nm +.Fl V | Fl -version +.Sh DESCRIPTION +The +.Nm +utility is used to manipulate comment sections in an ELF object. +If a command-line argument +.Ar file +names an +.Xr ar 1 +archive, then +.Nm +will operate on the ELF objects contained in the archive. +.Pp +By default +.Nm +operates on the ELF section named +.Dq .comment . +This may be changed using the +.Fl n +option. +.Pp +The +.Nm +utility supports the following options: +.Bl -tag -width ".Fl a Ar string" +.It Fl a Ar string +Append the text in +.Ar string +to the comment section. +This option may be specified multiple times. +.It Fl c +Compress the comment section by removing duplicate entries. +.It Fl d +Delete the comment section from the ELF object. +.It Fl h | Fl -help +Display a usage message and exit. +.It Fl n Ar name +Operate on the section named +.Ar name . +.It Fl p +Print the contents of the comment section. +This step is taken after actions specified by the +.Fl a +and +.Fl c +options (if any) are completed. +.It Fl V | Fl -version +Print a version identifier and exit. +.El +.Sh COMPATIBILITY +The behavior of the +.Nm +utility differs from its SVR4 counterpart in the following ways: +.Bl -bullet -compact +.It +If the +.Fl d +option is specified, it causes any +.Fl a , +.Fl c +and +.Fl p +options present to be ignored. +.It +The order of options +.Fl a , +.Fl c , +.Fl d , +and +.Fl p +on the command line is not significant. +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr elfcopy 1 , +.Xr ld 1 , +.Xr nm 1 , +.Xr strip 1 diff --git a/contrib/elftoolchain/elfcopy/os.FreeBSD.mk b/contrib/elftoolchain/elfcopy/os.FreeBSD.mk new file mode 100644 index 0000000000..389cb59e8c --- /dev/null +++ b/contrib/elftoolchain/elfcopy/os.FreeBSD.mk @@ -0,0 +1,4 @@ +.if !defined(LIBELF_AR) +DPADD+= ${LIBBZ2} +LDADD+= -lbz2 +.endif diff --git a/contrib/elftoolchain/elfcopy/pe.c b/contrib/elftoolchain/elfcopy/pe.c new file mode 100644 index 0000000000..605e6fd45c --- /dev/null +++ b/contrib/elftoolchain/elfcopy/pe.c @@ -0,0 +1,250 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: pe.c 3897 2020-11-21 11:07:50Z jkoshy $"); + +/* Convert ELF object to Portable Executable (PE). */ +void +create_pe(struct elfcopy *ecp, int ifd, int ofd) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Ehdr eh; + GElf_Shdr sh; + PE *pe; + PE_Scn *ps; + PE_SecHdr psh; + PE_CoffHdr pch; + PE_OptHdr poh; + PE_Object po; + PE_Buffer *pb; + const char *name; + size_t indx; + time_t timestamp; + int elferr; + + if (ecp->otf == ETF_EFI || ecp->oem == EM_X86_64) + po = PE_O_PE32P; + else + po = PE_O_PE32; + + if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + if (gelf_getehdr(e, &eh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + if (elf_getshstrndx(e, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx() failed: %s", + elf_errmsg(-1)); + + if ((pe = pe_init(ofd, PE_C_WRITE, po)) == NULL) + err(EXIT_FAILURE, "pe_init() failed"); + + /* Setup PE COFF header. */ + memset(&pch, 0, sizeof(pch)); + switch (ecp->oem) { + case EM_386: + pch.ch_machine = IMAGE_FILE_MACHINE_I386; + break; + case EM_X86_64: + pch.ch_machine = IMAGE_FILE_MACHINE_AMD64; + break; + default: + pch.ch_machine = IMAGE_FILE_MACHINE_UNKNOWN; + break; + } + if (elftc_timestamp(×tamp) != 0) + err(EXIT_FAILURE, "elftc_timestamp"); + pch.ch_timestamp = (uint32_t) timestamp; + if (pe_update_coff_header(pe, &pch) < 0) + err(EXIT_FAILURE, "pe_update_coff_header() failed"); + + /* Setup PE optional header. */ + memset(&poh, 0, sizeof(poh)); + if (ecp->otf == ETF_EFI) + poh.oh_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION; + poh.oh_entry = (uint32_t) eh.e_entry; + + /* + * Default section alignment and file alignment. (Here the + * section alignment is set to the default page size of the + * archs supported. We should use different section alignment + * for some arch. (e.g. IA64) + */ + poh.oh_secalign = 0x1000; + poh.oh_filealign = 0x200; + + /* Copy sections. */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + + /* + * Read in ELF section. + */ + + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((name = elf_strptr(e, indx, sh.sh_name)) == + NULL) { + warnx("elf_strptr() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + + /* Skip sections unneeded. */ + if (strcmp(name, ".shstrtab") == 0 || + strcmp(name, ".symtab") == 0 || + strcmp(name, ".strtab") == 0) + continue; + + if ((d = elf_getdata(scn, NULL)) == NULL) { + warnx("elf_getdata() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + + if (strcmp(name, ".text") == 0) { + poh.oh_textbase = (uint32_t) sh.sh_addr; + poh.oh_textsize = (uint32_t) roundup(sh.sh_size, + poh.oh_filealign); + } else { + if (po == PE_O_PE32 && strcmp(name, ".data") == 0) + poh.oh_database = sh.sh_addr; + if (sh.sh_type == SHT_NOBITS) + poh.oh_bsssize += (uint32_t) + roundup(sh.sh_size, poh.oh_filealign); + else if (sh.sh_flags & SHF_ALLOC) + poh.oh_datasize += (uint32_t) + roundup(sh.sh_size, poh.oh_filealign); + } + + /* + * Create PE/COFF section. + */ + + if ((ps = pe_newscn(pe)) == NULL) { + warn("pe_newscn() failed"); + continue; + } + + /* + * Setup PE/COFF section header. The section name is not + * NUL-terminated if its length happens to be 8. Long + * section name should be truncated for PE image according + * to the PE/COFF specification. + */ + memset(&psh, 0, sizeof(psh)); + + /* + * Turn off the '-Wstringop-truncation' warning in GCC 8 and + * later, since we require strncpy's non-null-terminating + * behavior here. + */ +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif + strncpy(psh.sh_name, name, sizeof(psh.sh_name)); +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + + psh.sh_addr = sh.sh_addr; + psh.sh_virtsize = sh.sh_size; + if (sh.sh_type != SHT_NOBITS) + psh.sh_rawsize = roundup(sh.sh_size, poh.oh_filealign); + else + psh.sh_char |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; + + /* + * Translate ELF section flags to PE/COFF section flags. + */ + psh.sh_char |= IMAGE_SCN_MEM_READ; + if (sh.sh_flags & SHF_WRITE) + psh.sh_char |= IMAGE_SCN_MEM_WRITE; + if (sh.sh_flags & SHF_EXECINSTR) + psh.sh_char |= IMAGE_SCN_MEM_EXECUTE | + IMAGE_SCN_CNT_CODE; + if ((sh.sh_flags & SHF_ALLOC) && (psh.sh_char & 0xF0) == 0) + psh.sh_char |= IMAGE_SCN_CNT_INITIALIZED_DATA; + + /* Mark relocation section "discardable". */ + if (strcmp(name, ".reloc") == 0) + psh.sh_char |= IMAGE_SCN_MEM_DISCARDABLE; + + if (pe_update_section_header(ps, &psh) < 0) { + warn("pe_update_section_header() failed"); + continue; + } + + /* Copy section content. */ + if ((pb = pe_newbuffer(ps)) == NULL) { + warn("pe_newbuffer() failed"); + continue; + } + pb->pb_align = 1; + pb->pb_off = 0; + if (sh.sh_type != SHT_NOBITS) { + pb->pb_size = roundup(sh.sh_size, poh.oh_filealign); + if ((pb->pb_buf = calloc(1, pb->pb_size)) == NULL) { + warn("calloc failed"); + continue; + } + memcpy(pb->pb_buf, d->d_buf, sh.sh_size); + } + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn() failed: %s", elf_errmsg(elferr)); + + /* Update PE optional header. */ + if (pe_update_opt_header(pe, &poh) < 0) + err(EXIT_FAILURE, "pe_update_opt_header() failed"); + + /* Write out PE/COFF object. */ + if (pe_update(pe) < 0) + err(EXIT_FAILURE, "pe_update() failed"); + + pe_finish(pe); + elf_end(e); +} diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c new file mode 100644 index 0000000000..9c96f5c8eb --- /dev/null +++ b/contrib/elftoolchain/elfcopy/sections.c @@ -0,0 +1,1693 @@ +/*- + * Copyright (c) 2007-2011,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: sections.c 3827 2020-02-28 00:50:12Z emaste $"); + +static void add_gnu_debuglink(struct elfcopy *ecp); +static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); +static void check_section_rename(struct elfcopy *ecp, struct section *s); +static void filter_reloc(struct elfcopy *ecp, struct section *s); +static int get_section_flags(struct elfcopy *ecp, const char *name); +static void insert_sections(struct elfcopy *ecp); +static int is_append_section(struct elfcopy *ecp, const char *name); +static int is_compress_section(struct elfcopy *ecp, const char *name); +static int is_debug_section(const char *name); +static int is_dwo_section(const char *name); +static int is_modify_section(struct elfcopy *ecp, const char *name); +static int is_print_section(struct elfcopy *ecp, const char *name); +static void modify_section(struct elfcopy *ecp, struct section *s); +static void pad_section(struct elfcopy *ecp, struct section *s); +static void print_data(const char *d, size_t sz); +static void print_section(struct section *s); +static void *read_section(struct section *s, size_t *size); +static void set_shstrtab(struct elfcopy *ecp); +static void update_reloc(struct elfcopy *ecp, struct section *s); +static void update_section_group(struct elfcopy *ecp, struct section *s); + +int +is_remove_section(struct elfcopy *ecp, const char *name) +{ + + /* Always keep section name table */ + if (strcmp(name, ".shstrtab") == 0) + return 0; + if (strcmp(name, ".symtab") == 0 || + strcmp(name, ".strtab") == 0) { + if (ecp->strip == STRIP_ALL && lookup_symop_list( + ecp, NULL, SYMOP_KEEP) == NULL) + return (1); + else + return (0); + } + + if (ecp->strip == STRIP_DWO && is_dwo_section(name)) + return (1); + if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name)) + return (1); + + if (is_debug_section(name)) { + if (ecp->strip == STRIP_ALL || + ecp->strip == STRIP_DEBUG || + ecp->strip == STRIP_UNNEEDED || + (ecp->flags & DISCARD_LOCAL)) + return (1); + if (ecp->strip == STRIP_NONDEBUG) + return (0); + } + + if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) { + struct sec_action *sac; + + sac = lookup_sec_act(ecp, name, 0); + if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove) + return (1); + if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy)) + return (1); + } + + return (0); +} + +/* + * Relocation section needs to be removed if the section it applies to + * will be removed. + */ +int +is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info) +{ + const char *name; + GElf_Shdr ish; + Elf_Scn *is; + size_t indx; + int elferr; + + if (elf_getshstrndx(ecp->ein, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + + is = elf_getscn(ecp->ein, sh_info); + if (is != NULL) { + if (gelf_getshdr(is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == + NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (is_remove_section(ecp, name)) + return (1); + else + return (0); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + + /* Remove reloc section if we can't find the target section. */ + return (1); +} + +static int +is_append_section(struct elfcopy *ecp, const char *name) +{ + struct sec_action *sac; + + sac = lookup_sec_act(ecp, name, 0); + if (sac != NULL && sac->append != 0 && sac->string != NULL) + return (1); + + return (0); +} + +static int +is_compress_section(struct elfcopy *ecp, const char *name) +{ + struct sec_action *sac; + + sac = lookup_sec_act(ecp, name, 0); + if (sac != NULL && sac->compress != 0) + return (1); + + return (0); +} + +static void +check_section_rename(struct elfcopy *ecp, struct section *s) +{ + struct sec_action *sac; + char *prefix; + size_t namelen; + + if (s->pseudo) + return; + + sac = lookup_sec_act(ecp, s->name, 0); + if (sac != NULL && sac->rename) + s->name = sac->newname; + + if (!strcmp(s->name, ".symtab") || + !strcmp(s->name, ".strtab") || + !strcmp(s->name, ".shstrtab")) + return; + + prefix = NULL; + if (s->loadable && ecp->prefix_alloc != NULL) + prefix = ecp->prefix_alloc; + else if (ecp->prefix_sec != NULL) + prefix = ecp->prefix_sec; + + if (prefix != NULL) { + namelen = strlen(s->name) + strlen(prefix) + 1; + if ((s->newname = malloc(namelen)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + snprintf(s->newname, namelen, "%s%s", prefix, s->name); + s->name = s->newname; + } +} + +static int +get_section_flags(struct elfcopy *ecp, const char *name) +{ + struct sec_action *sac; + + sac = lookup_sec_act(ecp, name, 0); + if (sac != NULL && sac->flags) + return sac->flags; + + return (0); +} + +/* + * Determine whether the section are debugging section. + * According to libbfd, debugging sections are recognized + * only by name. + */ +static int +is_debug_section(const char *name) +{ + const char *dbg_sec[] = { + ".apple_", + ".debug", + ".gnu.linkonce.wi.", + ".line", + ".stab", + NULL + }; + const char **p; + + for(p = dbg_sec; *p; p++) { + if (strncmp(name, *p, strlen(*p)) == 0) + return (1); + } + + return (0); +} + +static int +is_dwo_section(const char *name) +{ + size_t len; + + if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0) + return (1); + return (0); +} + +static int +is_print_section(struct elfcopy *ecp, const char *name) +{ + struct sec_action *sac; + + sac = lookup_sec_act(ecp, name, 0); + if (sac != NULL && sac->print != 0) + return (1); + + return (0); +} + +static int +is_modify_section(struct elfcopy *ecp, const char *name) +{ + + if (is_append_section(ecp, name) || + is_compress_section(ecp, name)) + return (1); + + return (0); +} + +struct sec_action* +lookup_sec_act(struct elfcopy *ecp, const char *name, int add) +{ + struct sec_action *sac; + + if (name == NULL) + return NULL; + + STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { + if (strcmp(name, sac->name) == 0) + return sac; + } + + if (add == 0) + return NULL; + + if ((sac = malloc(sizeof(*sac))) == NULL) + errx(EXIT_FAILURE, "not enough memory"); + memset(sac, 0, sizeof(*sac)); + sac->name = name; + STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list); + + return (sac); +} + +void +free_sec_act(struct elfcopy *ecp) +{ + struct sec_action *sac, *sac_temp; + + STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) { + STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list); + free(sac); + } +} + +void +insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail) +{ + struct section *s; + + if (tail || TAILQ_EMPTY(&ecp->v_sec) || + TAILQ_LAST(&ecp->v_sec, sectionlist)->off <= sec->off) { + TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list); + } else { + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (sec->off < s->off) { + TAILQ_INSERT_BEFORE(s, sec, sec_list); + break; + } + } + } + + if (sec->pseudo == 0) + ecp->nos++; +} + +/* + * First step of section creation: create scn and internal section + * structure, discard sections to be removed. + */ +void +create_scn(struct elfcopy *ecp) +{ + struct section *s; + const char *name; + Elf_Scn *is; + GElf_Shdr ish; + size_t indx; + uint64_t oldndx, newndx; + int elferr, sec_flags, reorder; + + /* + * Insert a pseudo section that contains the ELF header + * and program header. Used as reference for section offset + * or load address adjustment. + */ + if ((s = calloc(1, sizeof(*s))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + s->off = 0; + s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) + + gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); + s->align = 1; + s->pseudo = 1; + s->loadable = add_to_inseg_list(ecp, s); + insert_to_sec_list(ecp, s, 0); + + /* Create internal .shstrtab section. */ + init_shstrtab(ecp); + + if (elf_getshstrndx(ecp->ein, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + + reorder = 0; + is = NULL; + while ((is = elf_nextscn(ecp->ein, is)) != NULL) { + if (gelf_getshdr(is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + + /* Skip sections to be removed. */ + if (is_remove_section(ecp, name)) + continue; + + /* + * Relocation section need to be remove if the section + * it applies will be removed. + */ + if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) + if (ish.sh_info != 0 && + is_remove_reloc_sec(ecp, ish.sh_info)) + continue; + + /* + * Section groups should be removed if symbol table will + * be removed. (section group's signature stored in symbol + * table) + */ + if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL) + continue; + + /* Get section flags set by user. */ + sec_flags = get_section_flags(ecp, name); + + /* Create internal section object. */ + if (strcmp(name, ".shstrtab") != 0) { + if ((s = calloc(1, sizeof(*s))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + s->name = name; + s->is = is; + s->off = ish.sh_offset; + s->sz = ish.sh_size; + s->align = ish.sh_addralign; + s->type = ish.sh_type; + s->flags = ish.sh_flags; + s->vma = ish.sh_addr; + + /* + * Search program headers to determine whether section + * is loadable, but if user explicitly set section flags + * while neither "load" nor "alloc" is set, we make the + * section unloadable. + * + * Sections in relocatable object is loadable if + * section flag SHF_ALLOC is set. + */ + if (sec_flags && + (sec_flags & (SF_LOAD | SF_ALLOC)) == 0) + s->loadable = 0; + else { + s->loadable = add_to_inseg_list(ecp, s); + if ((ecp->flags & RELOCATABLE) && + (ish.sh_flags & SHF_ALLOC)) + s->loadable = 1; + } + } else { + /* Assuming .shstrtab is "unloadable". */ + s = ecp->shstrtab; + s->off = ish.sh_offset; + } + + oldndx = newndx = SHN_UNDEF; + if (strcmp(name, ".symtab") != 0 && + strcmp(name, ".strtab") != 0) { + if (!strcmp(name, ".shstrtab")) { + /* + * Add sections specified by --add-section and + * gnu debuglink. we want these sections have + * smaller index than .shstrtab section. + */ + if (ecp->debuglink != NULL) + add_gnu_debuglink(ecp); + if (ecp->flags & SEC_ADD) + insert_sections(ecp); + } + if ((s->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF) + errx(EXIT_FAILURE, "elf_ndxscn failed: %s", + elf_errmsg(-1)); + } + if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF) + errx(EXIT_FAILURE, "elf_ndxscn failed: %s", + elf_errmsg(-1)); + if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF) + ecp->secndx[oldndx] = newndx; + + /* + * If strip action is STRIP_NONDEBUG(only keep debug), + * change sections type of loadable sections and section + * groups to SHT_NOBITS, and the content of those sections + * will be discarded. However, SHT_NOTE sections should + * be kept. + */ + if (ecp->strip == STRIP_NONDEBUG) { + if (((ish.sh_flags & SHF_ALLOC) || + (ish.sh_flags & SHF_GROUP)) && + ish.sh_type != SHT_NOTE) + s->type = SHT_NOBITS; + } + + check_section_rename(ecp, s); + + /* create section header based on input object. */ + if (strcmp(name, ".symtab") != 0 && + strcmp(name, ".strtab") != 0 && + strcmp(name, ".shstrtab") != 0) { + copy_shdr(ecp, s, NULL, 0, sec_flags); + /* + * elfcopy puts .symtab, .strtab and .shstrtab + * sections in the end of the output object. + * If the input objects have more sections + * after any of these 3 sections, the section + * table will be reordered. section symbols + * should be regenerated for relocations. + */ + if (reorder) + ecp->flags &= ~SYMTAB_INTACT; + } else + reorder = 1; + + if (strcmp(name, ".symtab") == 0) { + ecp->flags |= SYMTAB_EXIST; + ecp->symtab = s; + } + if (strcmp(name, ".strtab") == 0) + ecp->strtab = s; + + insert_to_sec_list(ecp, s, 0); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +struct section * +insert_shtab(struct elfcopy *ecp, int tail) +{ + struct section *s, *shtab; + GElf_Ehdr ieh; + int nsecs; + + /* + * Treat section header table as a "pseudo" section, insert it + * into section list, so later it will get sorted and resynced + * just as normal sections. + */ + if ((shtab = calloc(1, sizeof(*shtab))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + if (!tail) { + /* + * "shoff" of input object is used as a hint for section + * resync later. + */ + if (gelf_getehdr(ecp->ein, &ieh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + shtab->off = ieh.e_shoff; + } else + shtab->off = 0; + /* Calculate number of sections in the output object. */ + nsecs = 0; + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (!s->pseudo) + nsecs++; + } + /* Remember there is always a null section, so we +1 here. */ + shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT); + if (shtab->sz == 0) + errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); + shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8); + shtab->loadable = 0; + shtab->pseudo = 1; + insert_to_sec_list(ecp, shtab, tail); + + return (shtab); +} + +void +copy_content(struct elfcopy *ecp) +{ + struct section *s; + + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + /* Skip pseudo section. */ + if (s->pseudo) + continue; + + /* Skip special sections. */ + if (strcmp(s->name, ".symtab") == 0 || + strcmp(s->name, ".strtab") == 0 || + strcmp(s->name, ".shstrtab") == 0) + continue; + + /* + * If strip action is STRIP_ALL, relocation info need + * to be stripped. Skip filtering otherwisw. + */ + if (ecp->strip == STRIP_ALL && + (s->type == SHT_REL || s->type == SHT_RELA)) + filter_reloc(ecp, s); + + /* + * The section indices in the SHT_GROUP section needs + * to be updated since we might have stripped some + * sections and changed section numbering. + */ + if (s->type == SHT_GROUP) + update_section_group(ecp, s); + + if (is_modify_section(ecp, s->name)) + modify_section(ecp, s); + + copy_data(s); + + /* + * If symbol table is modified, relocation info might + * need update, as symbol index may have changed. + */ + if ((ecp->flags & SYMTAB_INTACT) == 0 && + (ecp->flags & SYMTAB_EXIST) && + (s->type == SHT_REL || s->type == SHT_RELA)) + update_reloc(ecp, s); + + if (is_print_section(ecp, s->name)) + print_section(s); + } +} + + +/* + * Update section group section. The section indices in the SHT_GROUP + * section need update after section numbering changed. + */ +static void +update_section_group(struct elfcopy *ecp, struct section *s) +{ + GElf_Shdr ish; + Elf_Data *id; + uint32_t *ws, *wd; + uint64_t n; + size_t ishnum; + int i, j; + + if (!elf_getshnum(ecp->ein, &ishnum)) + errx(EXIT_FAILURE, "elf_getshnum failed: %s", + elf_errmsg(-1)); + + if (gelf_getshdr(s->is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + if ((id = elf_getdata(s->is, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(-1)); + + if (ish.sh_size == 0) + return; + + if (ish.sh_entsize == 0) + ish.sh_entsize = 4; + + ws = id->d_buf; + + /* We only support COMDAT section. */ + if ((*ws & GRP_COMDAT) == 0) + return; + + if ((s->buf = malloc(ish.sh_size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + + s->sz = ish.sh_size; + + wd = s->buf; + + /* Copy the flag word as-is. */ + *wd = *ws; + + /* Update the section indices. */ + n = ish.sh_size / ish.sh_entsize; + for(i = 1, j = 1; (uint64_t)i < n; i++) { + if (ws[i] != SHN_UNDEF && ws[i] < ishnum && + ecp->secndx[ws[i]] != 0) + wd[j++] = ecp->secndx[ws[i]]; + else + s->sz -= 4; + } + + s->nocopy = 1; +} + +/* + * Filter relocation entries, only keep those entries whose + * symbol is in the keep list. + */ +static void +filter_reloc(struct elfcopy *ecp, struct section *s) +{ + const char *name; + GElf_Shdr ish; + GElf_Rel rel; + GElf_Rela rela; + Elf32_Rel *rel32; + Elf64_Rel *rel64; + Elf32_Rela *rela32; + Elf64_Rela *rela64; + Elf_Data *id; + uint64_t cap, n, nrels, sym; + int elferr, i; + + if (gelf_getshdr(s->is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + /* We don't want to touch relocation info for dynamic symbols. */ + if ((ecp->flags & SYMTAB_EXIST) == 0) { + /* + * No symbol table in output. If sh_link points to a section + * that exists in the output object, this relocation section + * is for dynamic symbols. Don't touch it. + */ + if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0) + return; + } else { + /* Symbol table exist, check if index equals. */ + if (ish.sh_link != elf_ndxscn(ecp->symtab->is)) + return; + } + +#define COPYREL(REL, SZ) do { \ + if (nrels == 0) { \ + if ((REL##SZ = malloc(cap * \ + sizeof(*REL##SZ))) == NULL) \ + err(EXIT_FAILURE, "malloc failed"); \ + } \ + if (nrels >= cap) { \ + cap *= 2; \ + if ((REL##SZ = realloc(REL##SZ, cap * \ + sizeof(*REL##SZ))) == NULL) \ + err(EXIT_FAILURE, "realloc failed"); \ + } \ + REL##SZ[nrels].r_offset = REL.r_offset; \ + REL##SZ[nrels].r_info = REL.r_info; \ + if (s->type == SHT_RELA) \ + rela##SZ[nrels].r_addend = rela.r_addend; \ + nrels++; \ +} while (0) + + nrels = 0; + cap = 4; /* keep list is usually small. */ + rel32 = NULL; + rel64 = NULL; + rela32 = NULL; + rela64 = NULL; + if ((id = elf_getdata(s->is, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(-1)); + n = ish.sh_size / ish.sh_entsize; + for(i = 0; (uint64_t)i < n; i++) { + if (s->type == SHT_REL) { + if (gelf_getrel(id, i, &rel) != &rel) + errx(EXIT_FAILURE, "gelf_getrel failed: %s", + elf_errmsg(-1)); + sym = GELF_R_SYM(rel.r_info); + } else { + if (gelf_getrela(id, i, &rela) != &rela) + errx(EXIT_FAILURE, "gelf_getrel failed: %s", + elf_errmsg(-1)); + sym = GELF_R_SYM(rela.r_info); + } + /* + * If a relocation references a symbol and we are omitting + * either that symbol or the entire symbol table we cannot + * produce valid output, and so just omit the relocation. + * Broken output like this is generally not useful, but some + * uses of elfcopy/strip rely on it - for example, GCC's build + * process uses it to check for build reproducibility by + * stripping objects and comparing them. + * + * Relocations that do not reference a symbol are retained. + */ + if (sym != 0) { + if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0) + continue; + name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is), + sym); + if (name == NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL) + continue; + } + if (ecp->oec == ELFCLASS32) { + if (s->type == SHT_REL) + COPYREL(rel, 32); + else + COPYREL(rela, 32); + } else { + if (s->type == SHT_REL) + COPYREL(rel, 64); + else + COPYREL(rela, 64); + } + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(elferr)); + + if (ecp->oec == ELFCLASS32) { + if (s->type == SHT_REL) + s->buf = rel32; + else + s->buf = rela32; + } else { + if (s->type == SHT_REL) + s->buf = rel64; + else + s->buf = rela64; + } + s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL : + ELF_T_RELA), nrels, EV_CURRENT); + s->nocopy = 1; +} + +static void +update_reloc(struct elfcopy *ecp, struct section *s) +{ + GElf_Shdr osh; + GElf_Rel rel; + GElf_Rela rela; + Elf_Data *od; + uint64_t n; + int i; + +#define UPDATEREL(REL) do { \ + if (gelf_get##REL(od, i, &REL) != &REL) \ + errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \ + elf_errmsg(-1)); \ + REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)], \ + GELF_R_TYPE(REL.r_info)); \ + if (!gelf_update_##REL(od, i, &REL)) \ + errx(EXIT_FAILURE, "gelf_update_##REL failed: %s", \ + elf_errmsg(-1)); \ +} while(0) + + if (s->sz == 0) + return; + if (gelf_getshdr(s->os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + /* Only process .symtab reloc info. */ + if (osh.sh_link != elf_ndxscn(ecp->symtab->is)) + return; + if ((od = elf_getdata(s->os, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(-1)); + n = osh.sh_size / osh.sh_entsize; + for(i = 0; (uint64_t)i < n; i++) { + if (s->type == SHT_REL) + UPDATEREL(rel); + else + UPDATEREL(rela); + } +} + +static void +pad_section(struct elfcopy *ecp, struct section *s) +{ + GElf_Shdr osh; + Elf_Data *od; + + if (s == NULL || s->pad_sz == 0) + return; + + if ((s->pad = malloc(s->pad_sz)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + memset(s->pad, ecp->fill, s->pad_sz); + + /* Create a new Elf_Data to contain the padding bytes. */ + if ((od = elf_newdata(s->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s", + elf_errmsg(-1)); + od->d_align = 1; + od->d_off = s->sz; + od->d_buf = s->pad; + od->d_type = ELF_T_BYTE; + od->d_size = s->pad_sz; + od->d_version = EV_CURRENT; + + /* Update section header. */ + if (gelf_getshdr(s->os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + osh.sh_size = s->sz + s->pad_sz; + if (!gelf_update_shdr(s->os, &osh)) + errx(EXIT_FAILURE, "elf_update_shdr failed: %s", + elf_errmsg(-1)); +} + +void +resync_sections(struct elfcopy *ecp) +{ + struct section *s, *ps; + GElf_Shdr osh; + uint64_t off; + int first; + + ps = NULL; + first = 1; + off = 0; + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (first) { + off = s->off; + first = 0; + } + + /* + * Ignore TLS sections with load address 0 and without + * content. We don't need to adjust their file offset or + * VMA, only the size matters. + */ + if (s->seg_tls != NULL && s->type == SHT_NOBITS && + s->off == 0) + continue; + + /* Align section offset. */ + if (s->align == 0) + s->align = 1; + if (off <= s->off) { + if (!s->loadable || (ecp->flags & RELOCATABLE)) + s->off = roundup(off, s->align); + } else { + if (s->loadable && (ecp->flags & RELOCATABLE) == 0) + warnx("moving loadable section %s, " + "is this intentional?", s->name); + s->off = roundup(off, s->align); + } + + /* Calculate next section offset. */ + off = s->off; + if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL)) + off += s->sz; + + if (s->pseudo) { + ps = NULL; + continue; + } + + /* Count padding bytes added through --pad-to. */ + if (s->pad_sz > 0) + off += s->pad_sz; + + /* Update section header accordingly. */ + if (gelf_getshdr(s->os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + osh.sh_addr = s->vma; + osh.sh_offset = s->off; + osh.sh_size = s->sz; + if (!gelf_update_shdr(s->os, &osh)) + errx(EXIT_FAILURE, "elf_update_shdr failed: %s", + elf_errmsg(-1)); + + /* Add padding for previous section, if need. */ + if (ps != NULL) { + if (ps->pad_sz > 0) { + /* Apply padding added by --pad-to. */ + pad_section(ecp, ps); + } else if ((ecp->flags & GAP_FILL) && + (ps->off + ps->sz < s->off)) { + /* + * Fill the gap between sections by padding + * the section with lower address. + */ + ps->pad_sz = s->off - (ps->off + ps->sz); + pad_section(ecp, ps); + } + } + + ps = s; + } + + /* Pad the last section, if need. */ + if (ps != NULL && ps->pad_sz > 0) + pad_section(ecp, ps); +} + +static void +modify_section(struct elfcopy *ecp, struct section *s) +{ + struct sec_action *sac; + size_t srcsz, dstsz, p, len; + char *b, *c, *d, *src, *end; + int dupe; + + src = read_section(s, &srcsz); + if (src == NULL || srcsz == 0) { + /* For empty section, we proceed if we need to append. */ + if (!is_append_section(ecp, s->name)) + return; + } + + /* Allocate buffer needed for new section data. */ + dstsz = srcsz; + if (is_append_section(ecp, s->name)) { + sac = lookup_sec_act(ecp, s->name, 0); + dstsz += strlen(sac->string) + 1; + } + if ((b = malloc(dstsz)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + s->buf = b; + + /* Compress section. */ + p = 0; + if (is_compress_section(ecp, s->name)) { + end = src + srcsz; + for(c = src; c < end;) { + len = 0; + while(c + len < end && c[len] != '\0') + len++; + if (c + len == end) { + /* XXX should we warn here? */ + strncpy(&b[p], c, len); + p += len; + break; + } + dupe = 0; + for (d = b; d < b + p; ) { + if (strcmp(d, c) == 0) { + dupe = 1; + break; + } + d += strlen(d) + 1; + } + if (!dupe) { + strncpy(&b[p], c, len); + b[p + len] = '\0'; + p += len + 1; + } + c += len + 1; + } + } else { + memcpy(b, src, srcsz); + p += srcsz; + } + + /* Append section. */ + if (is_append_section(ecp, s->name)) { + sac = lookup_sec_act(ecp, s->name, 0); + len = strlen(sac->string); + memcpy(&b[p], sac->string, len); + b[p + len] = '\0'; + p += len + 1; + } + + s->sz = p; + s->nocopy = 1; +} + +static void +print_data(const char *d, size_t sz) +{ + const char *c; + + for (c = d; c < d + sz; c++) { + if (*c == '\0') + putchar('\n'); + else + putchar(*c); + } +} + +static void +print_section(struct section *s) +{ + Elf_Data *id; + int elferr; + + if (s->buf != NULL && s->sz > 0) { + print_data(s->buf, s->sz); + } else { + id = NULL; + while ((id = elf_getdata(s->is, id)) != NULL || + (id = elf_rawdata(s->is, id)) != NULL) { + (void) elf_errno(); + print_data(id->d_buf, id->d_size); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(elferr)); + } + putchar('\n'); +} + +static void * +read_section(struct section *s, size_t *size) +{ + Elf_Data *id; + char *b; + size_t sz; + int elferr; + + sz = 0; + b = NULL; + id = NULL; + while ((id = elf_getdata(s->is, id)) != NULL || + (id = elf_rawdata(s->is, id)) != NULL) { + (void) elf_errno(); + if (b == NULL) + b = malloc(id->d_size); + else + b = realloc(b, sz + id->d_size); + if (b == NULL) + err(EXIT_FAILURE, "malloc or realloc failed"); + + memcpy(&b[sz], id->d_buf, id->d_size); + sz += id->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_getdata() failed: %s", + elf_errmsg(elferr)); + + *size = sz; + + return (b); +} + +void +copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, + int sec_flags) +{ + GElf_Shdr ish, osh; + + if (gelf_getshdr(s->is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(s->os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + + if (copy) + (void) memcpy(&osh, &ish, sizeof(ish)); + else { + osh.sh_type = s->type; + osh.sh_addr = s->vma; + osh.sh_offset = s->off; + osh.sh_size = s->sz; + osh.sh_link = ish.sh_link; + osh.sh_info = ish.sh_info; + osh.sh_addralign = s->align; + osh.sh_entsize = ish.sh_entsize; + + if (sec_flags) { + osh.sh_flags = 0; + if (sec_flags & SF_ALLOC) + osh.sh_flags |= SHF_ALLOC; + if ((sec_flags & SF_READONLY) == 0) + osh.sh_flags |= SHF_WRITE; + if (sec_flags & SF_CODE) + osh.sh_flags |= SHF_EXECINSTR; + if ((sec_flags & SF_CONTENTS) && + s->type == SHT_NOBITS && s->sz > 0) { + /* + * Convert SHT_NOBITS section to section with + * (zero'ed) content on file. + */ + osh.sh_type = s->type = SHT_PROGBITS; + if ((s->buf = calloc(1, s->sz)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + s->nocopy = 1; + } + } else { + osh.sh_flags = ish.sh_flags; + /* + * Newer binutils as(1) emits the section flag + * SHF_INFO_LINK for relocation sections. elfcopy + * emits this flag in the output section if it's + * missing in the input section, to remain compatible + * with binutils. + */ + if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) + osh.sh_flags |= SHF_INFO_LINK; + } + } + + if (name == NULL) + add_to_shstrtab(ecp, s->name); + else + add_to_shstrtab(ecp, name); + + if (!gelf_update_shdr(s->os, &osh)) + errx(EXIT_FAILURE, "elf_update_shdr failed: %s", + elf_errmsg(-1)); +} + +void +copy_data(struct section *s) +{ + Elf_Data *id, *od; + int elferr; + + if (s->nocopy && s->buf == NULL) + return; + + if ((id = elf_getdata(s->is, NULL)) == NULL) { + (void) elf_errno(); + if ((id = elf_rawdata(s->is, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "failed to read section:" + " %s", s->name); + return; + } + } + + if ((od = elf_newdata(s->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s", + elf_errmsg(-1)); + + if (s->nocopy) { + /* Use s->buf as content if s->nocopy is set. */ + od->d_align = id->d_align; + od->d_off = 0; + od->d_buf = s->buf; + od->d_type = id->d_type; + od->d_size = s->sz; + od->d_version = id->d_version; + } else { + od->d_align = id->d_align; + od->d_off = id->d_off; + od->d_buf = id->d_buf; + od->d_type = id->d_type; + od->d_size = id->d_size; + od->d_version = id->d_version; + } + + /* + * Alignment Fixup. libelf does not allow the alignment for + * Elf_Data descriptor to be set to 0. In this case we workaround + * it by setting the alignment to 1. + * + * According to the ELF ABI, alignment 0 and 1 has the same + * meaning: the section has no alignment constraints. + */ + if (od->d_align == 0) + od->d_align = 1; +} + +struct section * +create_external_section(struct elfcopy *ecp, const char *name, char *newname, + void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype, + uint64_t flags, uint64_t align, uint64_t vma, int loadable) +{ + struct section *s; + Elf_Scn *os; + Elf_Data *od; + GElf_Shdr osh; + + if ((os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn() failed: %s", + elf_errmsg(-1)); + if ((s = calloc(1, sizeof(*s))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + s->name = name; + s->newname = newname; /* needs to be free()'ed */ + s->off = off; + s->sz = size; + s->vma = vma; + s->align = align; + s->loadable = loadable; + s->is = NULL; + s->os = os; + s->type = stype; + s->nocopy = 1; + insert_to_sec_list(ecp, s, 1); + + if (gelf_getshdr(os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + osh.sh_flags = flags; + osh.sh_type = s->type; + osh.sh_addr = s->vma; + osh.sh_addralign = s->align; + if (!gelf_update_shdr(os, &osh)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + add_to_shstrtab(ecp, name); + + if (buf != NULL && size != 0) { + if ((od = elf_newdata(os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s", + elf_errmsg(-1)); + od->d_align = align; + od->d_off = 0; + od->d_buf = buf; + od->d_size = size; + od->d_type = dtype; + od->d_version = EV_CURRENT; + } + + /* + * Clear SYMTAB_INTACT, as we probably need to update/add new + * STT_SECTION symbols into the symbol table. + */ + ecp->flags &= ~SYMTAB_INTACT; + + return (s); +} + +/* + * Insert sections specified by --add-section to the end of section list. + */ +static void +insert_sections(struct elfcopy *ecp) +{ + struct sec_add *sa; + struct section *s; + size_t off; + uint64_t stype; + + /* Put these sections in the end of current list. */ + off = 0; + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->type != SHT_NOBITS && s->type != SHT_NULL) + off = s->off + s->sz; + else + off = s->off; + } + + STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) { + + /* TODO: Add section header vma/lma, flag changes here */ + + /* + * The default section type for user added section is + * SHT_PROGBITS. If the section name match certain patterns, + * elfcopy will try to set a more appropriate section type. + * However, data type is always set to ELF_T_BYTE and no + * translation is performed by libelf. + */ + stype = SHT_PROGBITS; + if (strcmp(sa->name, ".note") == 0 || + strncmp(sa->name, ".note.", strlen(".note.")) == 0) + stype = SHT_NOTE; + + (void) create_external_section(ecp, sa->name, NULL, sa->content, + sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); + } +} + +void +add_to_shstrtab(struct elfcopy *ecp, const char *name) +{ + + if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0) + errx(EXIT_FAILURE, "elftc_string_table_insert failed"); +} + +void +update_shdr(struct elfcopy *ecp, int update_link) +{ + struct section *s; + GElf_Shdr osh; + int elferr; + + /* Finalize the section name string table (.shstrtab). */ + set_shstrtab(ecp); + + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->pseudo) + continue; + + if (gelf_getshdr(s->os, &osh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + + /* Find section name in string table and set sh_name. */ + osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab, + s->name); + + /* + * sh_link needs to be updated, since the index of the + * linked section might have changed. + */ + if (update_link && osh.sh_link != 0) + osh.sh_link = ecp->secndx[osh.sh_link]; + + /* + * sh_info of relocation section links to the section to which + * its relocation info applies. So it may need update as well. + */ + if ((s->type == SHT_REL || s->type == SHT_RELA) && + osh.sh_info != 0) + osh.sh_info = ecp->secndx[osh.sh_info]; + + /* + * sh_info of SHT_GROUP section needs to point to the correct + * string in the symbol table. + */ + if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) && + (ecp->flags & SYMTAB_INTACT) == 0) + osh.sh_info = ecp->symndx[osh.sh_info]; + + if (!gelf_update_shdr(s->os, &osh)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +void +init_shstrtab(struct elfcopy *ecp) +{ + Elf_Scn *shstrtab; + GElf_Shdr shdr; + struct section *s; + size_t indx, sizehint; + + if (elf_getshdrstrndx(ecp->ein, &indx) == 0) { + shstrtab = elf_getscn(ecp->ein, indx); + if (shstrtab == NULL) + errx(EXIT_FAILURE, "elf_getscn failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(shstrtab, &shdr) != &shdr) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + sizehint = shdr.sh_size; + } else { + /* Clear the error from elf_getshdrstrndx(3). */ + (void)elf_errno(); + sizehint = 0; + } + + if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + s = ecp->shstrtab; + s->name = ".shstrtab"; + s->is = NULL; + s->sz = 0; + s->align = 1; + s->loadable = 0; + s->type = SHT_STRTAB; + s->vma = 0; + s->strtab = elftc_string_table_create(sizehint); + + add_to_shstrtab(ecp, ".symtab"); + add_to_shstrtab(ecp, ".strtab"); + add_to_shstrtab(ecp, ".shstrtab"); +} + +static void +set_shstrtab(struct elfcopy *ecp) +{ + struct section *s; + Elf_Data *data; + GElf_Shdr sh; + const char *image; + size_t sz; + + s = ecp->shstrtab; + + if (s->os == NULL) { + /* Input object does not contain .shstrtab section */ + if ((s->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + insert_to_sec_list(ecp, s, 1); + } + + if (gelf_getshdr(s->os, &sh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + sh.sh_addr = 0; + sh.sh_addralign = 1; + sh.sh_offset = s->off; + sh.sh_type = SHT_STRTAB; + sh.sh_flags = 0; + sh.sh_entsize = 0; + sh.sh_info = 0; + sh.sh_link = 0; + + if ((data = elf_newdata(s->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s", + elf_errmsg(-1)); + + /* + * If we don't have a symbol table, skip those a few bytes + * which are reserved for this in the beginning of shstrtab. + */ + if (!(ecp->flags & SYMTAB_EXIST)) { + elftc_string_table_remove(s->strtab, ".symtab"); + elftc_string_table_remove(s->strtab, ".strtab"); + } + + image = elftc_string_table_image(s->strtab, &sz); + s->sz = sz; + + sh.sh_size = sz; + if (!gelf_update_shdr(s->os, &sh)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + + data->d_align = 1; + data->d_buf = (void *)(uintptr_t)image; + data->d_size = sz; + data->d_off = 0; + data->d_type = ELF_T_BYTE; + data->d_version = EV_CURRENT; + + if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) + errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", + elf_errmsg(-1)); +} + +void +add_section(struct elfcopy *ecp, const char *arg) +{ + struct sec_add *sa; + struct stat sb; + const char *s, *fn; + FILE *fp; + int len; + + if ((s = strchr(arg, '=')) == NULL) + errx(EXIT_FAILURE, + "illegal format for --add-section option"); + if ((sa = malloc(sizeof(*sa))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + + len = s - arg; + if ((sa->name = malloc(len + 1)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + strncpy(sa->name, arg, len); + sa->name[len] = '\0'; + + fn = s + 1; + if (stat(fn, &sb) == -1) + err(EXIT_FAILURE, "stat failed"); + sa->size = sb.st_size; + if (sa->size > 0) { + if ((sa->content = malloc(sa->size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if ((fp = fopen(fn, "r")) == NULL) + err(EXIT_FAILURE, "can not open %s", fn); + if (fread(sa->content, 1, sa->size, fp) == 0 || + ferror(fp)) + err(EXIT_FAILURE, "fread failed"); + fclose(fp); + } else + sa->content = NULL; + + STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); + ecp->flags |= SEC_ADD; +} + +void +free_sec_add(struct elfcopy *ecp) +{ + struct sec_add *sa, *sa_temp; + + STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) { + STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list); + free(sa->name); + free(sa->content); + free(sa); + } +} + +static void +add_gnu_debuglink(struct elfcopy *ecp) +{ + struct sec_add *sa; + struct stat sb; + FILE *fp; + char *fnbase, *buf; + int crc_off; + int crc; + + if (ecp->debuglink == NULL) + return; + + /* Read debug file content. */ + if ((sa = malloc(sizeof(*sa))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if ((sa->name = strdup(".gnu_debuglink")) == NULL) + err(EXIT_FAILURE, "strdup failed"); + if (stat(ecp->debuglink, &sb) == -1) + err(EXIT_FAILURE, "stat failed"); + if (sb.st_size == 0) + errx(EXIT_FAILURE, "empty debug link target %s", + ecp->debuglink); + if ((buf = malloc(sb.st_size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if ((fp = fopen(ecp->debuglink, "r")) == NULL) + err(EXIT_FAILURE, "can not open %s", ecp->debuglink); + if (fread(buf, 1, sb.st_size, fp) == 0 || + ferror(fp)) + err(EXIT_FAILURE, "fread failed"); + fclose(fp); + + /* Calculate crc checksum. */ + crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF); + free(buf); + + /* Calculate section size and the offset to store crc checksum. */ + if ((fnbase = basename(ecp->debuglink)) == NULL) + err(EXIT_FAILURE, "basename failed"); + crc_off = roundup(strlen(fnbase) + 1, 4); + sa->size = crc_off + 4; + + /* Section content. */ + if ((sa->content = calloc(1, sa->size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + memcpy(sa->content, fnbase, strlen(fnbase)); + if (ecp->oed == ELFDATA2LSB) { + sa->content[crc_off] = crc & 0xFF; + sa->content[crc_off + 1] = (crc >> 8) & 0xFF; + sa->content[crc_off + 2] = (crc >> 16) & 0xFF; + sa->content[crc_off + 3] = crc >> 24; + } else { + sa->content[crc_off] = crc >> 24; + sa->content[crc_off + 1] = (crc >> 16) & 0xFF; + sa->content[crc_off + 2] = (crc >> 8) & 0xFF; + sa->content[crc_off + 3] = crc & 0xFF; + } + + STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); + ecp->flags |= SEC_ADD; +} + +static uint32_t crctable[256] = +{ + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL +}; + +static uint32_t +calc_crc32(const char *p, size_t len, uint32_t crc) +{ + uint32_t i; + + for (i = 0; i < len; i++) { + crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8); + } + + return (crc ^ 0xFFFFFFFF); +} diff --git a/contrib/elftoolchain/elfcopy/segments.c b/contrib/elftoolchain/elfcopy/segments.c new file mode 100644 index 0000000000..9030248f8d --- /dev/null +++ b/contrib/elftoolchain/elfcopy/segments.c @@ -0,0 +1,592 @@ +/*- + * Copyright (c) 2007-2010,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: segments.c 3615 2018-05-17 04:12:24Z kaiwang27 $"); + +static void insert_to_inseg_list(struct segment *seg, struct section *sec); + +/* + * elfcopy's segment handling is relatively simpler and less powerful than + * libbfd. Program headers are modified or copied from input to output objects, + * but never re-generated. As a result, if the input object has incorrect + * program headers, the output object's program headers will remain incorrect + * or become even worse. + */ + +/* + * Check whether a section is "loadable". If so, add it to the + * corresponding segment list(s) and return 1. + */ +int +add_to_inseg_list(struct elfcopy *ecp, struct section *s) +{ + struct segment *seg; + int loadable; + + if (ecp->ophnum == 0) + return (0); + + /* + * Segment is a different view of an ELF object. One segment can + * contain one or more sections, and one section can be included + * in one or more segments, or not included in any segment at all. + * We call those sections which can be found in one or more segments + * "loadable" sections, and call the rest "unloadable" sections. + * We keep track of "loadable" sections in their containing + * segment(s)' v_sec queue. These information are later used to + * recalculate the extents of segments, when sections are removed, + * for example. + */ + loadable = 0; + STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { + if (s->off < seg->off || (s->vma < seg->vaddr && !s->pseudo)) + continue; + if (s->off + s->sz > seg->off + seg->fsz && + s->type != SHT_NOBITS) + continue; + if (s->vma + s->sz > seg->vaddr + seg->msz) + continue; + if (seg->type == PT_TLS && ((s->flags & SHF_TLS) == 0)) + continue; + + insert_to_inseg_list(seg, s); + if (seg->type == PT_LOAD) + s->seg = seg; + else if (seg->type == PT_TLS) + s->seg_tls = seg; + if (s->pseudo) + s->vma = seg->vaddr + (s->off - seg->off); + if (seg->paddr > 0) + s->lma = seg->paddr + (s->off - seg->off); + else + s->lma = 0; + loadable = 1; + } + + return (loadable); +} + +void +adjust_addr(struct elfcopy *ecp) +{ + struct section *s, *s0; + struct segment *seg; + struct sec_action *sac; + uint64_t dl, vma, lma, start, end; + int found, i; + + /* + * Apply VMA and global LMA changes in the first iteration. + */ + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + + /* Only adjust loadable section's address. */ + if (!s->loadable) + continue; + + /* Apply global VMA adjustment. */ + if (ecp->change_addr != 0) + s->vma += ecp->change_addr; + + /* Apply global LMA adjustment. */ + if (ecp->change_addr != 0 && s->seg != NULL && + s->seg->paddr > 0) + s->lma += ecp->change_addr; + } + + /* + * Apply sections VMA change in the second iteration. + */ + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + + if (!s->loadable) + continue; + + /* + * Check if there is a VMA change request for this + * section. + */ + sac = lookup_sec_act(ecp, s->name, 0); + if (sac == NULL) + continue; + vma = s->vma; + if (sac->setvma) + vma = sac->vma; + if (sac->vma_adjust != 0) + vma += sac->vma_adjust; + if (vma == s->vma) + continue; + + /* + * No need to make segment adjustment if the section doesn't + * belong to any segment. + */ + if (s->seg == NULL) { + s->vma = vma; + continue; + } + + /* + * Check if the VMA change is viable. + * + * 1. Check if the new VMA is properly aligned accroding to + * section alignment. + * + * 2. Compute the new extent of segment that contains this + * section, make sure it doesn't overlap with other + * segments. + */ +#ifdef DEBUG + printf("VMA for section %s: %#jx\n", s->name, vma); +#endif + + if (vma % s->align != 0) + errx(EXIT_FAILURE, "The VMA %#jx for " + "section %s is not aligned to %ju", + (uintmax_t) vma, s->name, (uintmax_t) s->align); + + if (vma < s->vma) { + /* Move section to lower address. */ + if (vma < s->vma - s->seg->vaddr) + errx(EXIT_FAILURE, "Not enough space to move " + "section %s VMA to %#jx", s->name, + (uintmax_t) vma); + start = vma - (s->vma - s->seg->vaddr); + if (s == s->seg->v_sec[s->seg->nsec - 1]) + end = start + s->seg->msz; + else + end = s->seg->vaddr + s->seg->msz; + } else { + /* Move section to upper address. */ + if (s == s->seg->v_sec[0]) + start = vma; + else + start = s->seg->vaddr; + end = vma + (s->seg->vaddr + s->seg->msz - s->vma); + if (end < start) + errx(EXIT_FAILURE, "Not enough space to move " + "section %s VMA to %#jx", s->name, + (uintmax_t) vma); + } + +#ifdef DEBUG + printf("new extent for segment containing %s: (%#jx,%#jx)\n", + s->name, start, end); +#endif + + STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { + if (seg == s->seg || seg->type != PT_LOAD) + continue; + if (start > seg->vaddr + seg->msz) + continue; + if (end < seg->vaddr) + continue; + errx(EXIT_FAILURE, "The extent of segment containing " + "section %s overlaps with segment(%#jx,%#jx)", + s->name, (uintmax_t) seg->vaddr, + (uintmax_t) (seg->vaddr + seg->msz)); + } + + /* + * Update section VMA and file offset. + */ + + if (vma < s->vma) { + /* + * To move a section to lower VMA, we decrease + * the VMA of the section and all the sections that + * are before it, and we increase the file offsets + * of all the sections that are after it. + */ + dl = s->vma - vma; + for (i = 0; i < s->seg->nsec; i++) { + s0 = s->seg->v_sec[i]; + s0->vma -= dl; +#ifdef DEBUG + printf("section %s VMA set to %#jx\n", + s0->name, (uintmax_t) s0->vma); +#endif + if (s0 == s) + break; + } + for (i = i + 1; i < s->seg->nsec; i++) { + s0 = s->seg->v_sec[i]; + s0->off += dl; +#ifdef DEBUG + printf("section %s offset set to %#jx\n", + s0->name, (uintmax_t) s0->off); +#endif + } + } else { + /* + * To move a section to upper VMA, we increase + * the VMA of the section and all the sections that + * are after it, and we increase the their file + * offsets too unless the section in question + * is the first in its containing segment. + */ + dl = vma - s->vma; + for (i = 0; i < s->seg->nsec; i++) + if (s->seg->v_sec[i] == s) + break; + if (i >= s->seg->nsec) + errx(EXIT_FAILURE, "Internal: section `%s' not" + " found in its containing segement", + s->name); + for (; i < s->seg->nsec; i++) { + s0 = s->seg->v_sec[i]; + s0->vma += dl; +#ifdef DEBUG + printf("section %s VMA set to %#jx\n", + s0->name, (uintmax_t) s0->lma); +#endif + if (s != s->seg->v_sec[0]) { + s0->off += dl; +#ifdef DEBUG + printf("section %s offset set to %#jx\n", + s0->name, (uintmax_t) s0->off); +#endif + } + } + } + } + + /* + * Apply load address padding. + */ + + if (ecp->pad_to != 0) { + + /* + * Find the section with highest VMA. + */ + s = NULL; + STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { + if (seg->type != PT_LOAD) + continue; + for (i = seg->nsec - 1; i >= 0; i--) + if (seg->v_sec[i]->type != SHT_NOBITS) + break; + if (i < 0) + continue; + if (s == NULL) + s = seg->v_sec[i]; + else { + s0 = seg->v_sec[i]; + if (s0->vma > s->vma) + s = s0; + } + } + + if (s == NULL) + goto adjust_lma; + + /* No need to pad if the pad_to address is lower. */ + if (ecp->pad_to <= s->vma + s->sz) + goto adjust_lma; + + s->pad_sz = ecp->pad_to - (s->vma + s->sz); +#ifdef DEBUG + printf("pad section %s VMA to address %#jx by %#jx\n", s->name, + (uintmax_t) ecp->pad_to, (uintmax_t) s->pad_sz); +#endif + } + + +adjust_lma: + + /* + * Apply sections LMA change in the third iteration. + */ + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + + /* + * Only loadable section that's inside a segment can have + * LMA adjusted. Also, if LMA of the containing segment is + * set to 0, it probably means we should ignore the LMA. + */ + if (!s->loadable || s->seg == NULL || s->seg->paddr == 0) + continue; + + /* + * Check if there is a LMA change request for this + * section. + */ + sac = lookup_sec_act(ecp, s->name, 0); + if (sac == NULL) + continue; + if (!sac->setlma && sac->lma_adjust == 0) + continue; + lma = s->lma; + if (sac->setlma) + lma = sac->lma; + if (sac->lma_adjust != 0) + lma += sac->lma_adjust; + if (lma == s->lma) + continue; + +#ifdef DEBUG + printf("LMA for section %s: %#jx\n", s->name, lma); +#endif + + /* Check alignment. */ + if (lma % s->align != 0) + errx(EXIT_FAILURE, "The LMA %#jx for " + "section %s is not aligned to %ju", + (uintmax_t) lma, s->name, (uintmax_t) s->align); + + /* + * Update section LMA. + */ + + if (lma < s->lma) { + /* + * To move a section to lower LMA, we decrease + * the LMA of the section and all the sections that + * are before it. + */ + dl = s->lma - lma; + for (i = 0; i < s->seg->nsec; i++) { + s0 = s->seg->v_sec[i]; + s0->lma -= dl; +#ifdef DEBUG + printf("section %s LMA set to %#jx\n", + s0->name, (uintmax_t) s0->lma); +#endif + if (s0 == s) + break; + } + } else { + /* + * To move a section to upper LMA, we increase + * the LMA of the section and all the sections that + * are after it. + */ + dl = lma - s->lma; + for (i = 0; i < s->seg->nsec; i++) + if (s->seg->v_sec[i] == s) + break; + if (i >= s->seg->nsec) + errx(EXIT_FAILURE, "Internal: section `%s' not" + " found in its containing segement", + s->name); + for (; i < s->seg->nsec; i++) { + s0 = s->seg->v_sec[i]; + s0->lma += dl; +#ifdef DEBUG + printf("section %s LMA set to %#jx\n", + s0->name, (uintmax_t) s0->lma); +#endif + } + } + } + + /* + * Issue a warning if there are VMA/LMA adjust requests for + * some nonexistent sections. + */ + if ((ecp->flags & NO_CHANGE_WARN) == 0) { + STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { + if (!sac->setvma && !sac->setlma && + !sac->vma_adjust && !sac->lma_adjust) + continue; + found = 0; + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->pseudo || s->name == NULL) + continue; + if (!strcmp(s->name, sac->name)) { + found = 1; + break; + } + } + if (!found) + warnx("cannot find section `%s'", sac->name); + } + } +} + +static void +insert_to_inseg_list(struct segment *seg, struct section *sec) +{ + struct section *s; + int i; + + seg->nsec++; + seg->v_sec = realloc(seg->v_sec, seg->nsec * sizeof(*seg->v_sec)); + if (seg->v_sec == NULL) + err(EXIT_FAILURE, "realloc failed"); + + /* + * Sort the section in order of offset. + */ + + for (i = seg->nsec - 1; i > 0; i--) { + s = seg->v_sec[i - 1]; + if (sec->off >= s->off) { + seg->v_sec[i] = sec; + break; + } else + seg->v_sec[i] = s; + } + if (i == 0) + seg->v_sec[0] = sec; +} + +void +setup_phdr(struct elfcopy *ecp) +{ + struct segment *seg; + GElf_Phdr iphdr; + size_t iphnum, i; + + if (elf_getphnum(ecp->ein, &iphnum) == 0) + errx(EXIT_FAILURE, "elf_getphnum failed: %s", + elf_errmsg(-1)); + + ecp->ophnum = ecp->iphnum = iphnum; + if (iphnum == 0) + return; + + /* If --only-keep-debug is specified, discard all program headers. */ + if (ecp->strip == STRIP_NONDEBUG) { + ecp->ophnum = 0; + return; + } + + for (i = 0; i < iphnum; i++) { + if (gelf_getphdr(ecp->ein, i, &iphdr) != &iphdr) + errx(EXIT_FAILURE, "gelf_getphdr failed: %s", + elf_errmsg(-1)); + if ((seg = calloc(1, sizeof(*seg))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + seg->vaddr = iphdr.p_vaddr; + seg->paddr = iphdr.p_paddr; + seg->off = iphdr.p_offset; + seg->fsz = iphdr.p_filesz; + seg->msz = iphdr.p_memsz; + seg->type = iphdr.p_type; + STAILQ_INSERT_TAIL(&ecp->v_seg, seg, seg_list); + } +} + +void +copy_phdr(struct elfcopy *ecp) +{ + struct segment *seg; + struct section *s; + GElf_Phdr iphdr, ophdr; + int i; + + STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { + if (seg->type == PT_PHDR) { + if (!TAILQ_EMPTY(&ecp->v_sec)) { + s = TAILQ_FIRST(&ecp->v_sec); + if (s->pseudo) { + seg->vaddr = s->vma + + gelf_fsize(ecp->eout, ELF_T_EHDR, + 1, EV_CURRENT); + seg->paddr = s->lma + + gelf_fsize(ecp->eout, ELF_T_EHDR, + 1, EV_CURRENT); + } + } + seg->fsz = seg->msz = gelf_fsize(ecp->eout, ELF_T_PHDR, + ecp->ophnum, EV_CURRENT); + continue; + } + + if (seg->nsec > 0) { + s = seg->v_sec[0]; + seg->vaddr = s->vma; + seg->paddr = s->lma; + } + + seg->fsz = seg->msz = 0; + for (i = 0; i < seg->nsec; i++) { + s = seg->v_sec[i]; + seg->msz = s->vma + s->sz - seg->vaddr; + if (s->type != SHT_NOBITS) + seg->fsz = s->off + s->sz - seg->off; + } + } + + /* + * Allocate space for program headers, note that libelf keep + * track of the number in internal variable, and a call to + * elf_update is needed to update e_phnum of ehdr. + */ + if (gelf_newphdr(ecp->eout, ecp->ophnum) == NULL) + errx(EXIT_FAILURE, "gelf_newphdr() failed: %s", + elf_errmsg(-1)); + + /* + * This elf_update() call is to update the e_phnum field in + * ehdr. It's necessary because later we will call gelf_getphdr(), + * which does sanity check by comparing ndx argument with e_phnum. + */ + if (elf_update(ecp->eout, ELF_C_NULL) < 0) + errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); + + /* + * iphnum == ophnum, since we don't remove program headers even if + * they no longer contain sections. + */ + i = 0; + STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { + if (i >= ecp->iphnum) + break; + if (gelf_getphdr(ecp->ein, i, &iphdr) != &iphdr) + errx(EXIT_FAILURE, "gelf_getphdr failed: %s", + elf_errmsg(-1)); + if (gelf_getphdr(ecp->eout, i, &ophdr) != &ophdr) + errx(EXIT_FAILURE, "gelf_getphdr failed: %s", + elf_errmsg(-1)); + + ophdr.p_type = iphdr.p_type; + ophdr.p_vaddr = seg->vaddr; + ophdr.p_paddr = seg->paddr; + ophdr.p_flags = iphdr.p_flags; + ophdr.p_align = iphdr.p_align; + ophdr.p_offset = seg->off; + ophdr.p_filesz = seg->fsz; + ophdr.p_memsz = seg->msz; + if (!gelf_update_phdr(ecp->eout, i, &ophdr)) + errx(EXIT_FAILURE, "gelf_update_phdr failed: %s", + elf_errmsg(-1)); + + i++; + } +} diff --git a/contrib/elftoolchain/elfcopy/strip.1 b/contrib/elftoolchain/elfcopy/strip.1 new file mode 100644 index 0000000000..02e5af960f --- /dev/null +++ b/contrib/elftoolchain/elfcopy/strip.1 @@ -0,0 +1,141 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY JOSEPH KOSHY ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL JOSEPH KOSHY BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: strip.1 3779 2019-07-27 11:40:09Z jkoshy $ +.\" +.Dd July 27, 2019 +.Dt STRIP 1 +.Os +.Sh NAME +.Nm strip +.Nd discard information from ELF objects +.Sh SYNOPSIS +.Nm +.Op Fl d | Fl g | Fl S | Fl -strip-debug +.Op Fl h | Fl -help +.Op Fl -only-keep-debug +.Op Fl o Ar outputfile | Fl -output-file= Ns Ar outputfile +.Op Fl p | Fl -preserve-dates +.Op Fl s | Fl -strip-all +.Op Fl -strip-unneeded +.Op Fl w | Fl -wildcard +.Op Fl x | Fl -discard-all +.Op Fl I Ar format | Fl -input-target= Ns Ar format +.Op Fl K Ar symbol | Fl -keep-symbol= Ns Ar symbol +.Op Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbol +.Op Fl O Ar format | Fl -output-target= Ns Ar format +.Op Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname +.Op Fl V | Fl -version +.Op Fl X | Fl -discard-locals +.Ar +.Sh DESCRIPTION +The +.Nm +utility is used to discard information from the ELF objects +specified by the arguments +.Ar . +.Pp +If an explicit output file name is not specified using the +.Fl o +option, the +.Nm +utility will modify its input arguments in-place. +.Pp +The +.Nm +utility supports the following options: +.Bl -tag -width indent +.It Fl d | Fl g | Fl S | Fl -strip-debug +Remove debugging symbols only. +.It Fl h | Fl -help +Print a help message and exit. +.It Fl -only-keep-debug +Remove all content except that which would be used for debugging. +.It Fl o Ar outputfile | Fl -output-file= Ns Ar outputfile +Write the stripped object to file +.Ar outputfile +instead of modifying the input in-place. +Only a single input object should be specified if this option is used. +.It Fl p | Fl -preserve-dates +Preserve the object's access and modification times. +.It Fl s | Fl -strip-all +Remove all symbols. +.It Fl -strip-unneeded +Remove all symbols not needed for further relocation processing. +.It Fl w | Fl -wildcard +Use shell-style patterns to name symbols. +The following meta-characters are recognized in patterns: +.Bl -tag -width "...." -compact +.It Li ! +If this is the first character of the pattern, invert the sense of the +pattern match. +.It Li * +Matches any string of characters in a symbol name. +.It Li ? +Matches zero or one character in a symbol name. +.It Li [ +Mark the start of a character class. +.It Li \e +Remove the special meaning of the next character in the pattern. +.It Li ] +Mark the end of a character class. +.El +.It Fl x | Fl -discard-all +Discard all non-global symbols. +.It Fl I Ar format | Fl -input-target= Ns Ar format +These options are accepted, but are ignored. +.It Fl K Ar symbol | Fl -keep-symbol= Ns Ar symbol +Keep the symbol +.Ar symbol +even if it would otherwise be stripped. +This option may be specified multiple times. +.It Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbol +Remove the symbol +.Ar symbol +even if it would otherwise have been kept. +This option may be specified multiple times. +.It Fl O Ar format | Fl -output-target= Ns Ar format +Set the output file format to +.Ar format . +For the full list of supported formats, please see the documentation +for function +.Xr elftc_bfd_find_target 3 . +.It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname +Remove the section named by the argument +.Ar sectionname . +This option may be specified multiple times. +.It Fl V | Fl -version +Print a version identifier and exit. +.It Fl X | Fl -discard-locals +Remove compiler-generated local symbols. +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr elfcopy 1 , +.Xr ld 1 , +.Xr mcs 1 , +.Xr elf 3 , +.Xr elftc_bfd_find_target 3 , +.Xr fnmatch 3 diff --git a/contrib/elftoolchain/elfcopy/symbols.c b/contrib/elftoolchain/elfcopy/symbols.c new file mode 100644 index 0000000000..b892662fb2 --- /dev/null +++ b/contrib/elftoolchain/elfcopy/symbols.c @@ -0,0 +1,1207 @@ +/*- + * Copyright (c) 2007-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: symbols.c 3812 2020-02-07 02:18:26Z emaste $"); + +/* Symbol table buffer structure. */ +struct symbuf { + Elf32_Sym *l32; /* 32bit local symbol */ + Elf32_Sym *g32; /* 32bit global symbol */ + Elf64_Sym *l64; /* 64bit local symbol */ + Elf64_Sym *g64; /* 64bit global symbol */ + size_t ngs, nls; /* number of each kind */ + size_t gcap, lcap; /* buffer capacities. */ +}; + +struct sthash { + LIST_ENTRY(sthash) sh_next; + size_t sh_off; +}; +typedef LIST_HEAD(,sthash) hash_head; +#define STHASHSIZE 65536 + +struct strimpl { + char *buf; /* string table */ + size_t sz; /* entries */ + size_t cap; /* buffer capacity */ + hash_head hash[STHASHSIZE]; +}; + + +/* String table buffer structure. */ +struct strbuf { + struct strimpl l; /* local symbols */ + struct strimpl g; /* global symbols */ +}; + +static int is_debug_symbol(unsigned char st_info); +static int is_global_symbol(unsigned char st_info); +static int is_local_symbol(unsigned char st_info); +static int is_local_label(const char *name); +static int is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s); +static int is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, + GElf_Sym *s, const char *name); +static int is_weak_symbol(unsigned char st_info); +static int lookup_exact_string(hash_head *hash, const char *buf, + const char *s); +static int generate_symbols(struct elfcopy *ecp); +static void mark_reloc_symbols(struct elfcopy *ecp, size_t sc); +static void mark_section_group_symbols(struct elfcopy *ecp, size_t sc); +uint32_t str_hash(const char *s); + +/* Convenient bit vector operation macros. */ +#define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7)) +#define BIT_CLR(v, n) (v[(n)>>3] &= ~(1U << ((n) & 7))) +#define BIT_ISSET(v, n) (v[(n)>>3] & (1U << ((n) & 7))) + +static int +is_debug_symbol(unsigned char st_info) +{ + + if (GELF_ST_TYPE(st_info) == STT_SECTION || + GELF_ST_TYPE(st_info) == STT_FILE) + return (1); + + return (0); +} + +static int +is_global_symbol(unsigned char st_info) +{ + + if (GELF_ST_BIND(st_info) == STB_GLOBAL || + GELF_ST_BIND(st_info) == STB_GNU_UNIQUE) + return (1); + + return (0); +} + +static int +is_weak_symbol(unsigned char st_info) +{ + + if (GELF_ST_BIND(st_info) == STB_WEAK) + return (1); + + return (0); +} + +static int +is_local_symbol(unsigned char st_info) +{ + + if (GELF_ST_BIND(st_info) == STB_LOCAL) + return (1); + + return (0); +} + +static int +is_hidden_symbol(unsigned char st_other) +{ + + if (GELF_ST_VISIBILITY(st_other) == STV_HIDDEN || + GELF_ST_VISIBILITY(st_other) == STV_INTERNAL) + return (1); + + return (0); +} + +static int +is_local_label(const char *name) +{ + + /* Compiler generated local symbols that start with .L */ + if (name[0] == '.' && name[1] == 'L') + return (1); + + return (0); +} + +/* + * Symbols related to relocation are needed. + */ +static int +is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s) +{ + + /* If symbol involves relocation, it is needed. */ + if (BIT_ISSET(ecp->v_rel, i)) + return (1); + + /* Symbols referred by COMDAT sections are needed. */ + if (BIT_ISSET(ecp->v_grp, i)) + return (1); + + /* + * For relocatable files (.o files), global and weak symbols + * are needed. + */ + if (ecp->flags & RELOCATABLE) { + if (is_global_symbol(s->st_info) || is_weak_symbol(s->st_info)) + return (1); + } + + return (0); +} + +static int +is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s, + const char *name) +{ + GElf_Sym sym0 = { + 0, /* st_name */ + 0, /* st_value */ + 0, /* st_size */ + 0, /* st_info */ + 0, /* st_other */ + SHN_UNDEF, /* st_shndx */ + }; + + /* + * Keep the first symbol if it is the special reserved symbol. + * XXX Should we generate one if it's missing? + */ + if (i == 0 && !memcmp(s, &sym0, sizeof(GElf_Sym))) + return (0); + + /* Remove the symbol if the section it refers to was removed. */ + if (s->st_shndx != SHN_UNDEF && s->st_shndx < SHN_LORESERVE && + ecp->secndx[s->st_shndx] == 0) + return (1); + + /* Keep the symbol if specified by command line option -K. */ + if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) + return (0); + + if (ecp->strip == STRIP_ALL) + return (1); + + /* Mark symbols used in relocation. */ + if (ecp->v_rel == NULL) + mark_reloc_symbols(ecp, sc); + + /* Mark symbols used in section groups. */ + if (ecp->v_grp == NULL) + mark_section_group_symbols(ecp, sc); + + /* + * Strip the symbol if specified by command line option -N, + * unless it's used in relocation. + */ + if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL) { + if (BIT_ISSET(ecp->v_rel, i)) { + warnx("not stripping symbol `%s' because it is named" + " in a relocation", name); + return (0); + } + return (1); + } + + if (is_needed_symbol(ecp, i, s)) + return (0); + + if (ecp->strip == STRIP_UNNEEDED) + return (1); + + if ((ecp->flags & DISCARD_LOCAL) && is_local_symbol(s->st_info) && + !is_debug_symbol(s->st_info)) + return (1); + + if ((ecp->flags & DISCARD_LLABEL) && is_local_symbol(s->st_info) && + !is_debug_symbol(s->st_info) && is_local_label(name)) + return (1); + + if (ecp->strip == STRIP_DEBUG && is_debug_symbol(s->st_info)) + return (1); + + return (0); +} + +/* + * Mark symbols referred by relocation entries. + */ +static void +mark_reloc_symbols(struct elfcopy *ecp, size_t sc) +{ + const char *name; + Elf_Data *d; + Elf_Scn *s; + GElf_Rel r; + GElf_Rela ra; + GElf_Shdr sh; + size_t n, indx; + int elferr, i, len; + + ecp->v_rel = calloc((sc + 7) / 8, 1); + if (ecp->v_rel == NULL) + err(EXIT_FAILURE, "calloc failed"); + + if (elf_getshstrndx(ecp->ein, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + + s = NULL; + while ((s = elf_nextscn(ecp->ein, s)) != NULL) { + if (gelf_getshdr(s, &sh) != &sh) + errx(EXIT_FAILURE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + + if (sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA) + continue; + + /* + * Skip if this reloc section won't appear in the + * output object. + */ + if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (is_remove_section(ecp, name) || + is_remove_reloc_sec(ecp, sh.sh_info)) + continue; + + /* Skip if it's not for .symtab */ + if (sh.sh_link != elf_ndxscn(ecp->symtab->is)) + continue; + + d = NULL; + n = 0; + while (n < sh.sh_size && (d = elf_getdata(s, d)) != NULL) { + len = d->d_size / sh.sh_entsize; + for (i = 0; i < len; i++) { + if (sh.sh_type == SHT_REL) { + if (gelf_getrel(d, i, &r) != &r) + errx(EXIT_FAILURE, + "elf_getrel failed: %s", + elf_errmsg(-1)); + n = GELF_R_SYM(r.r_info); + } else { + if (gelf_getrela(d, i, &ra) != &ra) + errx(EXIT_FAILURE, + "elf_getrela failed: %s", + elf_errmsg(-1)); + n = GELF_R_SYM(ra.r_info); + } + if (n > 0 && n < sc) + BIT_SET(ecp->v_rel, n); + else if (n != 0) + warnx("invalid symbox index"); + } + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_getdata failed: %s", + elf_errmsg(elferr)); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +static void +mark_section_group_symbols(struct elfcopy *ecp, size_t sc) +{ + const char *name; + Elf_Scn *s; + GElf_Shdr sh; + size_t indx; + int elferr; + + ecp->v_grp = calloc((sc + 7) / 8, 1); + if (ecp->v_grp == NULL) + err(EXIT_FAILURE, "calloc failed"); + + if (elf_getshstrndx(ecp->ein, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + + s = NULL; + while ((s = elf_nextscn(ecp->ein, s)) != NULL) { + if (gelf_getshdr(s, &sh) != &sh) + errx(EXIT_FAILURE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + + if (sh.sh_type != SHT_GROUP) + continue; + + if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (is_remove_section(ecp, name)) + continue; + + if (sh.sh_info > 0 && sh.sh_info < sc) + BIT_SET(ecp->v_grp, sh.sh_info); + else if (sh.sh_info != 0) + warnx("invalid symbox index"); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +static int +generate_symbols(struct elfcopy *ecp) +{ + struct section *s; + struct symop *sp; + struct symbuf *sy_buf; + struct strbuf *st_buf; + const char *name; + char *newname; + unsigned char *gsym; + GElf_Shdr ish; + GElf_Sym sym; + Elf_Data* id; + Elf_Scn *is; + size_t ishstrndx, namelen, ndx, sc, symndx; + int ec, elferr, i; + + if (elf_getshstrndx(ecp->ein, &ishstrndx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + if ((ec = gelf_getclass(ecp->eout)) == ELFCLASSNONE) + errx(EXIT_FAILURE, "gelf_getclass failed: %s", + elf_errmsg(-1)); + + /* Create buffers for .symtab and .strtab. */ + if ((sy_buf = calloc(1, sizeof(*sy_buf))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + sy_buf->gcap = sy_buf->lcap = 64; + st_buf->g.cap = 256; + st_buf->l.cap = 64; + st_buf->l.sz = 1; /* '\0' at start. */ + st_buf->g.sz = 0; + + ecp->symtab->sz = 0; + ecp->strtab->sz = 0; + ecp->symtab->buf = sy_buf; + ecp->strtab->buf = st_buf; + + gsym = NULL; + + /* + * Create bit vector v_secsym, which is used to mark sections + * that already have corresponding STT_SECTION symbols. + */ + ecp->v_secsym = calloc((ecp->nos + 7) / 8, 1); + if (ecp->v_secsym == NULL) + err(EXIT_FAILURE, "calloc failed"); + + /* Locate .strtab of input object. */ + symndx = 0; + name = NULL; + is = NULL; + while ((is = elf_nextscn(ecp->ein, is)) != NULL) { + if (gelf_getshdr(is, &ish) != &ish) + errx(EXIT_FAILURE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, ishstrndx, ish.sh_name)) == + NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (strcmp(name, ".strtab") == 0) { + symndx = elf_ndxscn(is); + break; + } + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + + /* Symbol table should exist if this function is called. */ + if (symndx == 0) { + warnx("can't find .strtab section"); + goto clean; + } + + /* Locate .symtab of input object. */ + is = NULL; + while ((is = elf_nextscn(ecp->ein, is)) != NULL) { + if (gelf_getshdr(is, &ish) != &ish) + errx(EXIT_FAILURE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, ishstrndx, ish.sh_name)) == + NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (strcmp(name, ".symtab") == 0) + break; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + if (is == NULL) + errx(EXIT_FAILURE, "can't find .strtab section"); + + /* + * Create bit vector gsym to mark global symbols, and symndx + * to keep track of symbol index changes from input object to + * output object, it is used by update_reloc() later to update + * relocation information. + */ + sc = ish.sh_size / ish.sh_entsize; + if (sc > 0) { + ecp->symndx = calloc(sc, sizeof(*ecp->symndx)); + if (ecp->symndx == NULL) + err(EXIT_FAILURE, "calloc failed"); + gsym = calloc((sc + 7) / 8, sizeof(*gsym)); + if (gsym == NULL) + err(EXIT_FAILURE, "calloc failed"); + if ((id = elf_getdata(is, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "elf_getdata failed: %s", + elf_errmsg(elferr)); + goto clean; + } + } else + return (0); + + /* Copy/Filter each symbol. */ + for (i = 0; (size_t)i < sc; i++) { + if (gelf_getsym(id, i, &sym) != &sym) + errx(EXIT_FAILURE, "gelf_getsym failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, symndx, sym.st_name)) == NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + + /* Symbol filtering. */ + if (is_remove_symbol(ecp, sc, i, &sym, name) != 0) + continue; + + /* Check if we need to change the binding of this symbol. */ + if (is_global_symbol(sym.st_info) || + is_weak_symbol(sym.st_info)) { + /* + * XXX Binutils objcopy does not weaken certain + * symbols. + */ + if (ecp->flags & WEAKEN_ALL || + lookup_symop_list(ecp, name, SYMOP_WEAKEN) != NULL) + sym.st_info = GELF_ST_INFO(STB_WEAK, + GELF_ST_TYPE(sym.st_info)); + /* Do not localize undefined symbols. */ + if (sym.st_shndx != SHN_UNDEF && + lookup_symop_list(ecp, name, SYMOP_LOCALIZE) != + NULL) + sym.st_info = GELF_ST_INFO(STB_LOCAL, + GELF_ST_TYPE(sym.st_info)); + if (ecp->flags & KEEP_GLOBAL && + sym.st_shndx != SHN_UNDEF && + lookup_symop_list(ecp, name, SYMOP_KEEPG) == NULL) + sym.st_info = GELF_ST_INFO(STB_LOCAL, + GELF_ST_TYPE(sym.st_info)); + if (ecp->flags & LOCALIZE_HIDDEN && + sym.st_shndx != SHN_UNDEF && + is_hidden_symbol(sym.st_other)) + sym.st_info = GELF_ST_INFO(STB_LOCAL, + GELF_ST_TYPE(sym.st_info)); + } else { + /* STB_LOCAL binding. */ + if (lookup_symop_list(ecp, name, SYMOP_GLOBALIZE) != + NULL) + sym.st_info = GELF_ST_INFO(STB_GLOBAL, + GELF_ST_TYPE(sym.st_info)); + /* XXX We should globalize weak symbol? */ + } + + /* Check if we need to rename this symbol. */ + if ((sp = lookup_symop_list(ecp, name, SYMOP_REDEF)) != NULL) + name = sp->newname; + + /* Check if we need to prefix the symbols. */ + newname = NULL; + if (ecp->prefix_sym != NULL && name != NULL && *name != '\0') { + namelen = strlen(name) + strlen(ecp->prefix_sym) + 1; + if ((newname = malloc(namelen)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + snprintf(newname, namelen, "%s%s", ecp->prefix_sym, + name); + name = newname; + } + + /* Copy symbol, mark global/weak symbol and add to index map. */ + if (is_global_symbol(sym.st_info) || + is_weak_symbol(sym.st_info)) { + BIT_SET(gsym, i); + ecp->symndx[i] = sy_buf->ngs; + } else + ecp->symndx[i] = sy_buf->nls; + add_to_symtab(ecp, name, sym.st_value, sym.st_size, + sym.st_shndx, sym.st_info, sym.st_other, 0); + + if (newname != NULL) + free(newname); + + /* + * If the symbol is a STT_SECTION symbol, mark the section + * it points to. + */ + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && + sym.st_shndx < SHN_LORESERVE) { + assert(ecp->secndx[sym.st_shndx] < (uint64_t)ecp->nos); + BIT_SET(ecp->v_secsym, ecp->secndx[sym.st_shndx]); + } + } + + /* + * Give up if there is no real symbols inside the table. + * XXX The logic here needs to be improved. We need to + * check if that only local symbol is the reserved symbol. + */ + if (sy_buf->nls <= 1 && sy_buf->ngs == 0) + goto clean; + + /* + * Create STT_SECTION symbols for sections that do not already + * got one. However, we do not create STT_SECTION symbol for + * .symtab, .strtab, .shstrtab and reloc sec of relocatables. + */ + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->pseudo) + continue; + if (strcmp(s->name, ".symtab") == 0 || + strcmp(s->name, ".strtab") == 0 || + strcmp(s->name, ".shstrtab") == 0) + continue; + if ((ecp->flags & RELOCATABLE) != 0 && + ((s->type == SHT_REL) || (s->type == SHT_RELA))) + continue; + + if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF) + errx(EXIT_FAILURE, "elf_ndxscn failed: %s", + elf_errmsg(-1)); + + if (!BIT_ISSET(ecp->v_secsym, ndx)) { + sym.st_name = 0; + sym.st_value = s->vma; + sym.st_size = 0; + sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); + sym.st_other = STV_DEFAULT; + /* + * Don't let add_to_symtab() touch sym.st_shndx. + * In this case, we know the index already. + */ + add_to_symtab(ecp, NULL, sym.st_value, sym.st_size, + ndx, sym.st_info, sym.st_other, 1); + } + } + + /* + * Update st_name and index map for global/weak symbols. Note that + * global/weak symbols are put after local symbols. + */ + if (gsym != NULL) { + for(i = 0; (size_t) i < sc; i++) { + if (!BIT_ISSET(gsym, i)) + continue; + + /* Update st_name. */ + if (ec == ELFCLASS32) + sy_buf->g32[ecp->symndx[i]].st_name += + st_buf->l.sz; + else + sy_buf->g64[ecp->symndx[i]].st_name += + st_buf->l.sz; + + /* Update index map. */ + ecp->symndx[i] += sy_buf->nls; + } + free(gsym); + } + + return (1); + +clean: + free(gsym); + free_symtab(ecp); + + return (0); +} + +void +create_symtab(struct elfcopy *ecp) +{ + struct section *s, *sy, *st; + size_t maxndx, ndx; + + sy = ecp->symtab; + st = ecp->strtab; + + assert(sy != NULL && st != NULL); + + /* + * Set section index map for .symtab and .strtab. We need to set + * these map because otherwise symbols which refer to .symtab and + * .strtab will be removed by symbol filtering unconditionally. + * And we have to figure out scn index this way (instead of calling + * elf_ndxscn) because we can not create Elf_Scn before we're certain + * that .symtab and .strtab will exist in the output object. + */ + maxndx = 0; + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->os == NULL) + continue; + if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF) + errx(EXIT_FAILURE, "elf_ndxscn failed: %s", + elf_errmsg(-1)); + if (ndx > maxndx) + maxndx = ndx; + } + ecp->secndx[elf_ndxscn(sy->is)] = maxndx + 1; + ecp->secndx[elf_ndxscn(st->is)] = maxndx + 2; + + /* + * Generate symbols for output object if SYMTAB_INTACT is not set. + * If there is no symbol in the input object or all the symbols are + * stripped, then free all the resouces allotted for symbol table, + * and clear SYMTAB_EXIST flag. + */ + if (((ecp->flags & SYMTAB_INTACT) == 0) && !generate_symbols(ecp)) { + TAILQ_REMOVE(&ecp->v_sec, ecp->symtab, sec_list); + TAILQ_REMOVE(&ecp->v_sec, ecp->strtab, sec_list); + free(ecp->symtab->buf); + free(ecp->symtab); + free(ecp->strtab->buf); + free(ecp->strtab); + ecp->symtab = NULL; + ecp->strtab = NULL; + ecp->flags &= ~SYMTAB_EXIST; + return; + } + + /* Create output Elf_Scn for .symtab and .strtab. */ + if ((sy->os = elf_newscn(ecp->eout)) == NULL || + (st->os = elf_newscn(ecp->eout)) == NULL) + errx(EXIT_FAILURE, "elf_newscn failed: %s", + elf_errmsg(-1)); + /* Update secndx anyway. */ + ecp->secndx[elf_ndxscn(sy->is)] = elf_ndxscn(sy->os); + ecp->secndx[elf_ndxscn(st->is)] = elf_ndxscn(st->os); + + /* + * Copy .symtab and .strtab section headers from input to output + * object to start with, these will be overridden later if need. + */ + copy_shdr(ecp, sy, ".symtab", 1, 0); + copy_shdr(ecp, st, ".strtab", 1, 0); + + /* Copy verbatim if symbol table is intact. */ + if (ecp->flags & SYMTAB_INTACT) { + copy_data(sy); + copy_data(st); + return; + } + + create_symtab_data(ecp); +} + +void +free_symtab(struct elfcopy *ecp) +{ + struct symbuf *sy_buf; + struct strbuf *st_buf; + struct sthash *sh, *shtmp; + int i; + + if (ecp->symtab != NULL && ecp->symtab->buf != NULL) { + sy_buf = ecp->symtab->buf; + if (sy_buf->l32 != NULL) + free(sy_buf->l32); + if (sy_buf->g32 != NULL) + free(sy_buf->g32); + if (sy_buf->l64 != NULL) + free(sy_buf->l64); + if (sy_buf->g64 != NULL) + free(sy_buf->g64); + } + + if (ecp->strtab != NULL && ecp->strtab->buf != NULL) { + st_buf = ecp->strtab->buf; + if (st_buf->l.buf != NULL) + free(st_buf->l.buf); + if (st_buf->g.buf != NULL) + free(st_buf->g.buf); + for (i = 0; i < STHASHSIZE; i++) { + LIST_FOREACH_SAFE(sh, &st_buf->l.hash[i], sh_next, + shtmp) { + LIST_REMOVE(sh, sh_next); + free(sh); + } + LIST_FOREACH_SAFE(sh, &st_buf->g.hash[i], sh_next, + shtmp) { + LIST_REMOVE(sh, sh_next); + free(sh); + } + } + } + + if (ecp->symndx != NULL) { + free(ecp->symndx); + ecp->symndx = NULL; + } + if (ecp->v_rel != NULL) { + free(ecp->v_rel); + ecp->v_rel = NULL; + } + if (ecp->v_grp != NULL) { + free(ecp->v_grp); + ecp->v_grp = NULL; + } + if (ecp->v_secsym != NULL) { + free(ecp->v_secsym); + ecp->v_secsym = NULL; + } +} + +void +create_external_symtab(struct elfcopy *ecp) +{ + struct section *s; + struct symbuf *sy_buf; + struct strbuf *st_buf; + GElf_Shdr sh; + size_t ndx; + + if (ecp->oec == ELFCLASS32) + ecp->symtab = create_external_section(ecp, ".symtab", NULL, + NULL, 0, 0, SHT_SYMTAB, ELF_T_SYM, 0, 4, 0, 0); + else + ecp->symtab = create_external_section(ecp, ".symtab", NULL, + NULL, 0, 0, SHT_SYMTAB, ELF_T_SYM, 0, 8, 0, 0); + + ecp->strtab = create_external_section(ecp, ".strtab", NULL, NULL, 0, 0, + SHT_STRTAB, ELF_T_BYTE, 0, 1, 0, 0); + + /* Let sh_link field of .symtab section point to .strtab section. */ + if (gelf_getshdr(ecp->symtab->os, &sh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + sh.sh_link = elf_ndxscn(ecp->strtab->os); + if (!gelf_update_shdr(ecp->symtab->os, &sh)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + + /* Create buffers for .symtab and .strtab. */ + if ((sy_buf = calloc(1, sizeof(*sy_buf))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + sy_buf->gcap = sy_buf->lcap = 64; + st_buf->g.cap = 256; + st_buf->l.cap = 64; + st_buf->l.sz = 1; /* '\0' at start. */ + st_buf->g.sz = 0; + + ecp->symtab->sz = 0; + ecp->strtab->sz = 0; + ecp->symtab->buf = sy_buf; + ecp->strtab->buf = st_buf; + + /* Always create the special symbol at the symtab beginning. */ + add_to_symtab(ecp, NULL, 0, 0, SHN_UNDEF, + ELF32_ST_INFO(STB_LOCAL, STT_NOTYPE), 0, 1); + + /* Create STT_SECTION symbols. */ + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { + if (s->pseudo) + continue; + if (strcmp(s->name, ".symtab") == 0 || + strcmp(s->name, ".strtab") == 0 || + strcmp(s->name, ".shstrtab") == 0) + continue; + (void) elf_errno(); + if ((ndx = elf_ndxscn(s->os)) == SHN_UNDEF) { + warnx("elf_ndxscn failed: %s", + elf_errmsg(-1)); + continue; + } + add_to_symtab(ecp, NULL, 0, 0, ndx, + GELF_ST_INFO(STB_LOCAL, STT_SECTION), 0, 1); + } +} + +void +add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value, + uint64_t st_size, uint16_t st_shndx, unsigned char st_info, + unsigned char st_other, int ndx_known) +{ + struct symbuf *sy_buf; + struct strbuf *st_buf; + struct sthash *sh; + uint32_t hash; + int pos; + + /* + * Convenient macro for copying global/local 32/64 bit symbols + * from input object to the buffer created for output object. + * It handles buffer growing, st_name calculating and st_shndx + * updating for symbols with non-special section index. + */ +#define _ST_NAME_EMPTY_l 0 +#define _ST_NAME_EMPTY_g -1 +#define _ADDSYM(B, SZ) do { \ + if (sy_buf->B##SZ == NULL) { \ + sy_buf->B##SZ = malloc(sy_buf->B##cap * \ + sizeof(Elf##SZ##_Sym)); \ + if (sy_buf->B##SZ == NULL) \ + err(EXIT_FAILURE, "malloc failed"); \ + } else if (sy_buf->n##B##s >= sy_buf->B##cap) { \ + sy_buf->B##cap *= 2; \ + sy_buf->B##SZ = realloc(sy_buf->B##SZ, sy_buf->B##cap * \ + sizeof(Elf##SZ##_Sym)); \ + if (sy_buf->B##SZ == NULL) \ + err(EXIT_FAILURE, "realloc failed"); \ + } \ + sy_buf->B##SZ[sy_buf->n##B##s].st_info = st_info; \ + sy_buf->B##SZ[sy_buf->n##B##s].st_other = st_other; \ + sy_buf->B##SZ[sy_buf->n##B##s].st_value = st_value; \ + sy_buf->B##SZ[sy_buf->n##B##s].st_size = st_size; \ + if (ndx_known) \ + sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = st_shndx; \ + else if (st_shndx == SHN_UNDEF || st_shndx >= SHN_LORESERVE) \ + sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = st_shndx; \ + else \ + sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = \ + ecp->secndx[st_shndx]; \ + if (st_buf->B.buf == NULL) { \ + st_buf->B.buf = calloc(st_buf->B.cap, \ + sizeof(*st_buf->B.buf)); \ + if (st_buf->B.buf == NULL) \ + err(EXIT_FAILURE, "malloc failed"); \ + } \ + if (name != NULL && *name != '\0') { \ + pos = lookup_exact_string(st_buf->B.hash, st_buf->B.buf,\ + name); \ + if (pos != -1) \ + sy_buf->B##SZ[sy_buf->n##B##s].st_name = pos; \ + else { \ + sy_buf->B##SZ[sy_buf->n##B##s].st_name = \ + st_buf->B.sz; \ + while (st_buf->B.sz + strlen(name) >= \ + st_buf->B.cap - 1) { \ + st_buf->B.cap *= 2; \ + st_buf->B.buf = realloc(st_buf->B.buf, \ + st_buf->B.cap); \ + if (st_buf->B.buf == NULL) \ + err(EXIT_FAILURE, \ + "realloc failed"); \ + } \ + if ((sh = malloc(sizeof(*sh))) == NULL) \ + err(EXIT_FAILURE, "malloc failed"); \ + sh->sh_off = st_buf->B.sz; \ + hash = str_hash(name); \ + LIST_INSERT_HEAD(&st_buf->B.hash[hash], sh, \ + sh_next); \ + memcpy(&st_buf->B.buf[st_buf->B.sz], name, \ + strlen(name)); \ + st_buf->B.buf[st_buf->B.sz + strlen(name)] = '\0'; \ + st_buf->B.sz += strlen(name) + 1; \ + } \ + } else \ + sy_buf->B##SZ[sy_buf->n##B##s].st_name = \ + (Elf##SZ##_Word)_ST_NAME_EMPTY_##B; \ + sy_buf->n##B##s++; \ +} while (0) + + sy_buf = ecp->symtab->buf; + st_buf = ecp->strtab->buf; + + if (ecp->oec == ELFCLASS32) { + if (is_local_symbol(st_info)) + _ADDSYM(l, 32); + else + _ADDSYM(g, 32); + } else { + if (is_local_symbol(st_info)) + _ADDSYM(l, 64); + else + _ADDSYM(g, 64); + } + + /* Update section size. */ + ecp->symtab->sz = (sy_buf->nls + sy_buf->ngs) * + (ecp->oec == ELFCLASS32 ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym)); + ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz; + +#undef _ADDSYM +#undef _ST_NAME_EMPTY_l +#undef _ST_NAME_EMPTY_g +} + +void +finalize_external_symtab(struct elfcopy *ecp) +{ + struct symbuf *sy_buf; + struct strbuf *st_buf; + int i; + + /* + * Update st_name for global/weak symbols. (global/weak symbols + * are put after local symbols) + */ + sy_buf = ecp->symtab->buf; + st_buf = ecp->strtab->buf; + for (i = 0; (size_t) i < sy_buf->ngs; i++) { + if (ecp->oec == ELFCLASS32) { + if (sy_buf->g32[i].st_name == (Elf32_Word)-1) + sy_buf->g32[i].st_name = 0; + else + sy_buf->g32[i].st_name += st_buf->l.sz; + } else { + if (sy_buf->g64[i].st_name == (Elf64_Word)-1) + sy_buf->g64[i].st_name = 0; + else + sy_buf->g64[i].st_name += st_buf->l.sz; + } + } +} + +void +create_symtab_data(struct elfcopy *ecp) +{ + struct section *sy, *st; + struct symbuf *sy_buf; + struct strbuf *st_buf; + Elf_Data *gsydata, *lsydata, *gstdata, *lstdata; + GElf_Shdr shy, sht; + + sy = ecp->symtab; + st = ecp->strtab; + + if (gelf_getshdr(sy->os, ­) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(st->os, &sht) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", + elf_errmsg(-1)); + + /* + * Create two Elf_Data for .symtab section of output object, one + * for local symbols and another for global symbols. Note that + * local symbols appear first in the .symtab. + */ + sy_buf = sy->buf; + if (sy_buf->nls > 0) { + if ((lsydata = elf_newdata(sy->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + if (ecp->oec == ELFCLASS32) { + lsydata->d_align = 4; + lsydata->d_off = 0; + lsydata->d_buf = sy_buf->l32; + lsydata->d_size = sy_buf->nls * + sizeof(Elf32_Sym); + lsydata->d_type = ELF_T_SYM; + lsydata->d_version = EV_CURRENT; + } else { + lsydata->d_align = 8; + lsydata->d_off = 0; + lsydata->d_buf = sy_buf->l64; + lsydata->d_size = sy_buf->nls * + sizeof(Elf64_Sym); + lsydata->d_type = ELF_T_SYM; + lsydata->d_version = EV_CURRENT; + } + } + if (sy_buf->ngs > 0) { + if ((gsydata = elf_newdata(sy->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + if (ecp->oec == ELFCLASS32) { + gsydata->d_align = 4; + gsydata->d_off = sy_buf->nls * + sizeof(Elf32_Sym); + gsydata->d_buf = sy_buf->g32; + gsydata->d_size = sy_buf->ngs * + sizeof(Elf32_Sym); + gsydata->d_type = ELF_T_SYM; + gsydata->d_version = EV_CURRENT; + } else { + gsydata->d_align = 8; + gsydata->d_off = sy_buf->nls * + sizeof(Elf64_Sym); + gsydata->d_buf = sy_buf->g64; + gsydata->d_size = sy_buf->ngs * + sizeof(Elf64_Sym); + gsydata->d_type = ELF_T_SYM; + gsydata->d_version = EV_CURRENT; + } + } + + /* + * Create two Elf_Data for .strtab, one for local symbol name + * and another for globals. Same as .symtab, local symbol names + * appear first. + */ + st_buf = st->buf; + if ((lstdata = elf_newdata(st->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + lstdata->d_align = 1; + lstdata->d_off = 0; + lstdata->d_buf = st_buf->l.buf; + lstdata->d_size = st_buf->l.sz; + lstdata->d_type = ELF_T_BYTE; + lstdata->d_version = EV_CURRENT; + + if (st_buf->g.sz > 0) { + if ((gstdata = elf_newdata(st->os)) == NULL) + errx(EXIT_FAILURE, "elf_newdata() failed: %s.", + elf_errmsg(-1)); + gstdata->d_align = 1; + gstdata->d_off = lstdata->d_size; + gstdata->d_buf = st_buf->g.buf; + gstdata->d_size = st_buf->g.sz; + gstdata->d_type = ELF_T_BYTE; + gstdata->d_version = EV_CURRENT; + } + + shy.sh_addr = 0; + shy.sh_addralign = (ecp->oec == ELFCLASS32 ? 4 : 8); + shy.sh_size = sy->sz; + shy.sh_type = SHT_SYMTAB; + shy.sh_flags = 0; + shy.sh_entsize = gelf_fsize(ecp->eout, ELF_T_SYM, 1, + EV_CURRENT); + /* + * According to SYSV abi, here sh_info is one greater than + * the symbol table index of the last local symbol(binding + * STB_LOCAL). + */ + shy.sh_info = sy_buf->nls; + + sht.sh_addr = 0; + sht.sh_addralign = 1; + sht.sh_size = st->sz; + sht.sh_type = SHT_STRTAB; + sht.sh_flags = 0; + sht.sh_entsize = 0; + sht.sh_info = 0; + sht.sh_link = 0; + + if (!gelf_update_shdr(sy->os, ­)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); + if (!gelf_update_shdr(st->os, &sht)) + errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", + elf_errmsg(-1)); +} + +void +add_to_symop_list(struct elfcopy *ecp, const char *name, const char *newname, + unsigned int op) +{ + struct symop *s; + + assert (name != NULL); + STAILQ_FOREACH(s, &ecp->v_symop, symop_list) + if (!strcmp(name, s->name)) + goto found; + + if ((s = calloc(1, sizeof(*s))) == NULL) + errx(EXIT_FAILURE, "not enough memory"); + STAILQ_INSERT_TAIL(&ecp->v_symop, s, symop_list); + s->name = name; +found: + if (op == SYMOP_REDEF) + s->newname = newname; + s->op |= op; +} + +struct symop * +lookup_symop_list(struct elfcopy *ecp, const char *name, unsigned int op) +{ + struct symop *s, *ret; + const char *pattern; + + STAILQ_FOREACH(s, &ecp->v_symop, symop_list) { + if ((s->op & op) == 0) + continue; + if (name == NULL || !strcmp(name, s->name)) + return (s); + if ((ecp->flags & WILDCARD) == 0) + continue; + + /* Handle wildcards. */ + pattern = s->name; + if (pattern[0] == '!') { + /* Negative match. */ + pattern++; + ret = NULL; + } else { + /* Regular wildcard match. */ + ret = s; + } + if (!fnmatch(pattern, name, 0)) + return (ret); + } + + return (NULL); +} + +static int +lookup_exact_string(hash_head *buckets, const char *buf, const char *s) +{ + struct sthash *sh; + uint32_t hash; + + hash = str_hash(s); + LIST_FOREACH(sh, &buckets[hash], sh_next) + if (strcmp(buf + sh->sh_off, s) == 0) + return sh->sh_off; + return (-1); +} + +uint32_t +str_hash(const char *s) +{ + uint32_t hash; + + for (hash = 2166136261UL; *s; s++) + hash = (hash ^ *s) * 16777619; + + return (hash & (STHASHSIZE - 1)); +} diff --git a/contrib/elftoolchain/elfdump/Makefile b/contrib/elftoolchain/elfdump/Makefile new file mode 100644 index 0000000000..b78d465266 --- /dev/null +++ b/contrib/elftoolchain/elfdump/Makefile @@ -0,0 +1,11 @@ +# $Id: Makefile 2289 2011-12-04 07:11:47Z jkoshy $ + +TOP= .. + +PROG= elfdump +WARNS?= 6 + +DPADD= ${LIBELFTC} ${LIBELF} +LDADD= -lelftc -lelf + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/elfdump/elfdump.1 b/contrib/elftoolchain/elfdump/elfdump.1 new file mode 100644 index 0000000000..e586ab23c5 --- /dev/null +++ b/contrib/elftoolchain/elfdump/elfdump.1 @@ -0,0 +1,158 @@ +.\" Copyright (c) 2003 David O'Brien +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.bin/elfdump/elfdump.1,v 1.6 2005/01/18 13:43:48 ru Exp $ +.\" $Id: elfdump.1 3231 2015-07-30 13:47:56Z emaste $ +.\" +.Dd August 25, 2011 +.Dt ELFDUMP 1 +.Os +.Sh NAME +.Nm elfdump +.Nd "display information about" +.Tn ELF +files +.Sh SYNOPSIS +.Nm +.Fl a | cdeGhiknprsv +.Op Fl S +.Op Fl V +.Op Fl N Ar name +.Op Fl w Ar file +.Ar file ... +.Sh DESCRIPTION +The +.Nm +utility +dumps various information about the specified +.Tn ELF +.Ar file . +.Pp +The options are as follows: +.Bl -tag -width ".Fl w Ar file" +.It Fl a +Dump all information. +.It Fl c +Dump section headers. +.It Fl d +Dump dynamic symbols. +.It Fl e +Dump ELF header. +.It Fl G +Dump the GOT. +.It Fl h +Dump the hash values. +.It Fl i +Dump the dynamic interpreter. +.It Fl k +Dump the ELF checksum. +.It Fl n +Dump note sections. +.It Fl N Ar name +Only dump the section with the specific +.Ar name . +Archive symbol table can be specified with +the special section name ARSYM. +More than one +.Fl N +option may appear. +.It Fl p +Dump the program header. +.It Fl r +Dump relocations. +.It Fl s +Dump the symbol table. +.It Fl S +Output in the Solaris +.Nm +format. +.It Fl v +Dump the symbol-versioning sections. +.It Fl V +Print a version identifier and exit. +.It Fl w Ar file +Write output to a +.Ar file +instead of the standard output. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +The following is an example of a typical usage +of the +.Nm +command: +.Pp +.Dl "elfdump -a -w output /bin/ls" +.Pp +To dump the content of '.dynsym' symbol table: +.Pp +.Dl "elfdump -s -N .dynsym /bin/ls" +.Pp +To dump the archive symbol table, +but not the symbol tables of archive members: +.Pp +.Dl "elfdump -s -N ARSYM /usr/lib/libelf.a" +.Pp +To dump the content of .got section and +the symbol-versioning sections in Solaris +.Nm +format: +.Pp +.Dl "elfdump -S -Gv /bin/ls" +.Sh SEE ALSO +.Xr objdump 1 , +.Xr readelf 1 , +.Xr elf 3 +.Rs +.%A "AT&T Unix Systems Labs" +.%T "System V Application Binary Interface" +.%O http://www.sco.com/developers/gabi/ +.Re +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 5.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +utility +was written by +.An Jake Burkholder Aq Mt jake@FreeBSD.org . +Later it was rewritten based on the +libelf library. +This +manual page was written by +.An David O'Brien Aq Mt obrien@FreeBSD.org . +.Pp +.An Kai Wang Aq Mt kaiw@FreeBSD.org +rewrote it using the +.Lb libelf +and implemented additional functionality. +.Sh BUGS +Does not fully implement the +.Tn ELF +gABI. diff --git a/contrib/elftoolchain/elfdump/elfdump.c b/contrib/elftoolchain/elfdump/elfdump.c new file mode 100644 index 0000000000..1bc7fe7239 --- /dev/null +++ b/contrib/elftoolchain/elfdump/elfdump.c @@ -0,0 +1,2703 @@ +/*- + * Copyright (c) 2007-2012 Kai Wang + * Copyright (c) 2003 David O'Brien. All rights reserved. + * Copyright (c) 2001 Jake Burkholder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_LIBARCHIVE_AR +#include +#include +#endif + +#include "_elftc.h" + +ELFTC_VCSID("$Id: elfdump.c 4000 2023-04-15 20:29:04Z jkoshy $"); + +/* elfdump(1) options. */ +#define ED_DYN (1<<0) +#define ED_EHDR (1<<1) +#define ED_GOT (1<<2) +#define ED_HASH (1<<3) +#define ED_INTERP (1<<4) +#define ED_NOTE (1<<5) +#define ED_PHDR (1<<6) +#define ED_REL (1<<7) +#define ED_SHDR (1<<8) +#define ED_SYMTAB (1<<9) +#define ED_SYMVER (1<<10) +#define ED_CHECKSUM (1<<11) +#define ED_ALL ((1<<12)-1) + +/* elfdump(1) run control flags. */ +#define SOLARIS_FMT (1<<0) +#define PRINT_FILENAME (1<<1) +#define PRINT_ARSYM (1<<2) +#define ONLY_ARSYM (1<<3) + +/* Convenient print macro. */ +#define PRT(...) fprintf(ed->out, __VA_ARGS__) + +/* Internal data structure for sections. */ +struct section { + const char *name; /* section name */ + Elf_Scn *scn; /* section scn */ + uint64_t off; /* section offset */ + uint64_t sz; /* section size */ + uint64_t entsize; /* section entsize */ + uint64_t align; /* section alignment */ + uint64_t type; /* section type */ + uint64_t flags; /* section flags */ + uint64_t addr; /* section virtual addr */ + uint32_t link; /* section link ndx */ + uint32_t info; /* section info ndx */ +}; + +struct spec_name { + const char *name; + STAILQ_ENTRY(spec_name) sn_list; +}; + +/* Structure encapsulates the global data for readelf(1). */ +struct elfdump { + FILE *out; /* output redirection. */ + const char *filename; /* current processing file. */ + const char *archive; /* archive name */ + int options; /* command line options. */ + int flags; /* run control flags. */ + Elf *elf; /* underlying ELF descriptor. */ +#ifndef USE_LIBARCHIVE_AR + Elf *ar; /* ar(1) archive descriptor. */ +#endif + GElf_Ehdr ehdr; /* ELF header. */ + int ec; /* ELF class. */ + size_t shnum; /* #sections. */ + struct section *sl; /* list of sections. */ + STAILQ_HEAD(, spec_name) snl; /* list of names specified by -N. */ +}; + +/* Relocation entry. */ +struct rel_entry { + union { + GElf_Rel rel; + GElf_Rela rela; + } u_r; + const char *symn; + uint32_t type; +}; + +#if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) +static __inline uint32_t +be32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); +} + +static __inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} +#endif + +/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#tag_encodings */ +static const char * +d_tags(uint64_t tag) +{ + static char unknown_buf[64]; + + switch (tag) { + case DT_NULL: return "DT_NULL"; + case DT_NEEDED: return "DT_NEEDED"; + case DT_PLTRELSZ: return "DT_PLTRELSZ"; + case DT_PLTGOT: return "DT_PLTGOT"; + case DT_HASH: return "DT_HASH"; + case DT_STRTAB: return "DT_STRTAB"; + case DT_SYMTAB: return "DT_SYMTAB"; + case DT_RELA: return "DT_RELA"; + case DT_RELASZ: return "DT_RELASZ"; + case DT_RELAENT: return "DT_RELAENT"; + case DT_STRSZ: return "DT_STRSZ"; + case DT_SYMENT: return "DT_SYMENT"; + case DT_INIT: return "DT_INIT"; + case DT_FINI: return "DT_FINI"; + case DT_SONAME: return "DT_SONAME"; + case DT_RPATH: return "DT_RPATH"; + case DT_SYMBOLIC: return "DT_SYMBOLIC"; + case DT_REL: return "DT_REL"; + case DT_RELSZ: return "DT_RELSZ"; + case DT_RELENT: return "DT_RELENT"; + case DT_PLTREL: return "DT_PLTREL"; + case DT_DEBUG: return "DT_DEBUG"; + case DT_TEXTREL: return "DT_TEXTREL"; + case DT_JMPREL: return "DT_JMPREL"; + case DT_BIND_NOW: return "DT_BIND_NOW"; + case DT_INIT_ARRAY: return "DT_INIT_ARRAY"; + case DT_FINI_ARRAY: return "DT_FINI_ARRAY"; + case DT_INIT_ARRAYSZ: return "DT_INIT_ARRAYSZ"; + case DT_FINI_ARRAYSZ: return "DT_FINI_ARRAYSZ"; + case DT_RUNPATH: return "DT_RUNPATH"; + case DT_FLAGS: return "DT_FLAGS"; + case DT_PREINIT_ARRAY: return "DT_PREINIT_ARRAY"; /* XXX DT_ENCODING */ + case DT_PREINIT_ARRAYSZ:return "DT_PREINIT_ARRAYSZ"; + /* 0x6000000D - 0x6ffff000 operating system-specific semantics */ + case 0x6ffffdf5: return "DT_GNU_PRELINKED"; + case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ"; + case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ"; + case 0x6ffffdf8: return "DT_SUNW_CHECKSUM"; + case DT_PLTPADSZ: return "DT_PLTPADSZ"; + case DT_MOVEENT: return "DT_MOVEENT"; + case DT_MOVESZ: return "DT_MOVESZ"; + case 0x6ffffdfc: return "DT_FEATURE"; + case DT_POSFLAG_1: return "DT_POSFLAG_1"; + case DT_SYMINSZ: return "DT_SYMINSZ"; + case DT_SYMINENT: return "DT_SYMINENT (DT_VALRNGHI)"; + case DT_ADDRRNGLO: return "DT_ADDRRNGLO"; + case DT_GNU_HASH: return "DT_GNU_HASH"; + case 0x6ffffef8: return "DT_GNU_CONFLICT"; + case 0x6ffffef9: return "DT_GNU_LIBLIST"; + case 0x6ffffefa: return "DT_CONFIG"; + case 0x6ffffefb: return "DT_DEPAUDIT"; + case 0x6ffffefc: return "DT_AUDIT"; + case 0x6ffffefd: return "DT_PLTPAD"; + case 0x6ffffefe: return "DT_MOVETAB"; + case DT_SYMINFO: return "DT_SYMINFO (DT_ADDRRNGHI)"; + case DT_RELACOUNT: return "DT_RELACOUNT"; + case DT_RELCOUNT: return "DT_RELCOUNT"; + case DT_FLAGS_1: return "DT_FLAGS_1"; + case DT_VERDEF: return "DT_VERDEF"; + case DT_VERDEFNUM: return "DT_VERDEFNUM"; + case DT_VERNEED: return "DT_VERNEED"; + case DT_VERNEEDNUM: return "DT_VERNEEDNUM"; + case 0x6ffffff0: return "DT_GNU_VERSYM"; + /* 0x70000000 - 0x7fffffff processor-specific semantics */ + case 0x70000000: return "DT_IA_64_PLT_RESERVE"; + case DT_AUXILIARY: return "DT_AUXILIARY"; + case DT_USED: return "DT_USED"; + case DT_FILTER: return "DT_FILTER"; + } + + snprintf(unknown_buf, sizeof(unknown_buf), + "", (unsigned long long)tag); + return (unknown_buf); +} + +static const char * +e_machines(unsigned int mach) +{ + static char machdesc[64]; + + switch (mach) { + case EM_NONE: return "EM_NONE"; + case EM_M32: return "EM_M32"; + case EM_SPARC: return "EM_SPARC"; + case EM_386: return "EM_386"; + case EM_68K: return "EM_68K"; + case EM_88K: return "EM_88K"; + case EM_IAMCU: return "EM_IAMCU"; + case EM_860: return "EM_860"; + case EM_MIPS: return "EM_MIPS"; + case EM_PPC: return "EM_PPC"; + case EM_PPC64: return "EM_PPC64"; + case EM_ARM: return "EM_ARM"; + case EM_ALPHA: return "EM_ALPHA (legacy)"; + case EM_SPARCV9:return "EM_SPARCV9"; + case EM_IA_64: return "EM_IA_64"; + case EM_X86_64: return "EM_X86_64"; + case EM_AARCH64:return "EM_AARCH64"; + case EM_RISCV: return "EM_RISCV"; + } + snprintf(machdesc, sizeof(machdesc), + "(unknown machine) -- type 0x%x", mach); + return (machdesc); +} + +static const char * +elf_type_str(unsigned int type) +{ + static char s_type[32]; + + switch (type) + { + case ET_NONE: return "ET_NONE"; + case ET_REL: return "ET_REL"; + case ET_EXEC: return "ET_EXEC"; + case ET_DYN: return "ET_DYN"; + case ET_CORE: return "ET_CORE"; + } + if (type >= ET_LOPROC) + snprintf(s_type, sizeof(s_type), "", type); + else if (type >= ET_LOOS && type <= ET_HIOS) + snprintf(s_type, sizeof(s_type), "", type); + else + snprintf(s_type, sizeof(s_type), "", ver); + return (s_ver); +} + +static const char * +elf_class_str(unsigned int class) +{ + static char s_class[32]; + + switch (class) { + case ELFCLASSNONE: return "ELFCLASSNONE"; + case ELFCLASS32: return "ELFCLASS32"; + case ELFCLASS64: return "ELFCLASS64"; + } + snprintf(s_class, sizeof(s_class), "", class); + return (s_class); +} + +static const char * +elf_data_str(unsigned int data) +{ + static char s_data[32]; + + switch (data) { + case ELFDATANONE: return "ELFDATANONE"; + case ELFDATA2LSB: return "ELFDATA2LSB"; + case ELFDATA2MSB: return "ELFDATA2MSB"; + } + snprintf(s_data, sizeof(s_data), "", data); + return (s_data); +} + +static const char *ei_abis[256] = { + [0] = "ELFOSABI_NONE", + [1] = "ELFOSABI_HPUX", + [2] = "ELFOSABI_NETBSD", + [3] = "ELFOSABI_GNU", + [4] = "ELFOSABI_HURD", + [5] = "ELFOSABI_86OPEN", + [6] = "ELFOSABI_SOLARIS", + [7] = "ELFOSABI_AIX", + [8] = "ELFOSABI_IRIX", + [9] = "ELFOSABI_FREEBSD", + [10] = "ELFOSABI_TRU64", + [11] = "ELFOSABI_MODESTO", + [12] = "ELFOSABI_OPENBSD", + [13] = "ELFOSABI_OPENVMS", + [14] = "ELFOSABI_NSK", + [15] = "ELFOSABI_AROS", + [16] = "ELFOSABI_FENIXOS", + [17] = "ELFOSABI_CLOUDABI", + [18] = "ELFOSABI_OPENVOS", + [64] = "ELFOSABI_ARM_AEABI", + [97] = "ELFOSABI_ARM", + [255] = "ELFOSABI_STANDALONE" +}; + +static const char * +elf_phdr_type_str(unsigned int type) +{ + static char s_type[32]; + + switch (type) { + case PT_NULL: return "PT_NULL"; + case PT_LOAD: return "PT_LOAD"; + case PT_DYNAMIC: return "PT_DYNAMIC"; + case PT_INTERP: return "PT_INTERP"; + case PT_NOTE: return "PT_NOTE"; + case PT_SHLIB: return "PT_SHLIB"; + case PT_PHDR: return "PT_PHDR"; + case PT_TLS: return "PT_TLS"; + case PT_GNU_EH_FRAME: return "PT_GNU_EH_FRAME"; + case PT_GNU_STACK: return "PT_GNU_STACK"; + case PT_GNU_RELRO: return "PT_GNU_RELRO"; + case PT_OPENBSD_RANDOMIZE: return "PT_OPENBSD_RANDOMIZE"; + case PT_OPENBSD_WXNEEDED: return "PT_OPENBSD_WXNEEDED"; + case PT_OPENBSD_BOOTDATA: return "PT_OPENBSD_BOOTDATA"; + } + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} + +static const char *p_flags[] = { + "", "PF_X", "PF_W", "PF_X|PF_W", "PF_R", "PF_X|PF_R", "PF_W|PF_R", + "PF_X|PF_W|PF_R" +}; + +static const char * +sh_name(struct elfdump *ed, int ndx) +{ + static char num[10]; + + switch (ndx) { + case SHN_UNDEF: return "UNDEF"; + case SHN_ABS: return "ABS"; + case SHN_COMMON: return "COMMON"; + default: + if ((uint64_t)ndx < ed->shnum) + return (ed->sl[ndx].name); + else { + snprintf(num, sizeof(num), "%d", ndx); + return (num); + } + } +} + +/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */ +static const char * +sh_types(uint64_t mach, uint64_t sht) { + static char unknown_buf[64]; + + if (sht < 0x60000000) { + switch (sht) { + case SHT_NULL: return "SHT_NULL"; + case SHT_PROGBITS: return "SHT_PROGBITS"; + case SHT_SYMTAB: return "SHT_SYMTAB"; + case SHT_STRTAB: return "SHT_STRTAB"; + case SHT_RELA: return "SHT_RELA"; + case SHT_HASH: return "SHT_HASH"; + case SHT_DYNAMIC: return "SHT_DYNAMIC"; + case SHT_NOTE: return "SHT_NOTE"; + case SHT_NOBITS: return "SHT_NOBITS"; + case SHT_REL: return "SHT_REL"; + case SHT_SHLIB: return "SHT_SHLIB"; + case SHT_DYNSYM: return "SHT_DYNSYM"; + case SHT_INIT_ARRAY: return "SHT_INIT_ARRAY"; + case SHT_FINI_ARRAY: return "SHT_FINI_ARRAY"; + case SHT_PREINIT_ARRAY: return "SHT_PREINIT_ARRAY"; + case SHT_GROUP: return "SHT_GROUP"; + case SHT_SYMTAB_SHNDX: return "SHT_SYMTAB_SHNDX"; + } + } else if (sht < 0x70000000) { + /* 0x60000000-0x6fffffff operating system-specific semantics */ + switch (sht) { + case 0x6ffffff0: return "XXX:VERSYM"; + case SHT_SUNW_dof: return "SHT_SUNW_dof"; + case SHT_GNU_HASH: return "SHT_GNU_HASH"; + case 0x6ffffff7: return "SHT_GNU_LIBLIST"; + case 0x6ffffffc: return "XXX:VERDEF"; + case SHT_SUNW_verdef: return "SHT_SUNW(GNU)_verdef"; + case SHT_SUNW_verneed: return "SHT_SUNW(GNU)_verneed"; + case SHT_SUNW_versym: return "SHT_SUNW(GNU)_versym"; + } + } else if (sht < 0x80000000) { + /* 0x70000000 - 0x7fffffff processor-specific semantics */ + switch (mach) { + case EM_ARM: + switch (sht) { + case SHT_ARM_EXIDX: return "SHT_ARM_EXIDX"; + case SHT_ARM_PREEMPTMAP: return "SHT_ARM_PREEMPTMAP"; + case SHT_ARM_ATTRIBUTES: return "SHT_ARM_ATTRIBUTES"; + case SHT_ARM_DEBUGOVERLAY: + return "SHT_ARM_DEBUGOVERLAY"; + case SHT_ARM_OVERLAYSECTION: + return "SHT_ARM_OVERLAYSECTION"; + } + break; + case EM_IA_64: + switch (sht) { + case 0x70000000: return "SHT_IA_64_EXT"; + case 0x70000001: return "SHT_IA_64_UNWIND"; + } + break; + case EM_MIPS: + switch (sht) { + case SHT_MIPS_REGINFO: return "SHT_MIPS_REGINFO"; + case SHT_MIPS_OPTIONS: return "SHT_MIPS_OPTIONS"; + case SHT_MIPS_ABIFLAGS: return "SHT_MIPS_ABIFLAGS"; + } + break; + } + switch (sht) { + case 0x7ffffffd: return "XXX:AUXILIARY"; + case 0x7fffffff: return "XXX:FILTER"; + } + } + /* 0x80000000 - 0xffffffff application programs */ + + snprintf(unknown_buf, sizeof(unknown_buf), + "", (unsigned long long)sht); + return (unknown_buf); +} + +/* + * Define known section flags. These flags are defined in the order + * they are to be printed out. + */ +#define DEFINE_SHFLAGS() \ + DEFINE_SHF(WRITE) \ + DEFINE_SHF(ALLOC) \ + DEFINE_SHF(EXECINSTR) \ + DEFINE_SHF(MERGE) \ + DEFINE_SHF(STRINGS) \ + DEFINE_SHF(INFO_LINK) \ + DEFINE_SHF(LINK_ORDER) \ + DEFINE_SHF(OS_NONCONFORMING) \ + DEFINE_SHF(GROUP) \ + DEFINE_SHF(TLS) \ + DEFINE_SHF(COMPRESSED) + +#undef DEFINE_SHF +#define DEFINE_SHF(F) "SHF_" #F "|" +#define ALLSHFLAGS DEFINE_SHFLAGS() + +static const char * +sh_flags(uint64_t shf) +{ + static char flg[sizeof(ALLSHFLAGS)+1]; + + flg[0] = '\0'; + +#undef DEFINE_SHF +#define DEFINE_SHF(N) \ + if (shf & SHF_##N) \ + strcat(flg, "SHF_" #N "|"); \ + + DEFINE_SHFLAGS() + + flg[strlen(flg) - 1] = '\0'; /* Remove the trailing "|". */ + + return (flg); +} + +static const char * +st_type(unsigned int mach, unsigned int type) +{ + static char s_type[32]; + + switch (type) { + case STT_NOTYPE: return "STT_NOTYPE"; + case STT_OBJECT: return "STT_OBJECT"; + case STT_FUNC: return "STT_FUNC"; + case STT_SECTION: return "STT_SECTION"; + case STT_FILE: return "STT_FILE"; + case STT_COMMON: return "STT_COMMON"; + case STT_TLS: return "STT_TLS"; + case 13: + if (mach == EM_SPARCV9) + return "STT_SPARC_REGISTER"; + break; + } + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} + +static const char * +st_type_S(unsigned int type) +{ + static char s_type[32]; + + switch (type) { + case STT_NOTYPE: return "NOTY"; + case STT_OBJECT: return "OBJT"; + case STT_FUNC: return "FUNC"; + case STT_SECTION: return "SECT"; + case STT_FILE: return "FILE"; + } + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} + +static const char * +st_bindings(unsigned int sbind) +{ + static char s_sbind[32]; + + switch (sbind) { + case STB_LOCAL: return "STB_LOCAL"; + case STB_GLOBAL: return "STB_GLOBAL"; + case STB_WEAK: return "STB_WEAK"; + case STB_GNU_UNIQUE: return "STB_GNU_UNIQUE"; + default: + if (sbind >= STB_LOOS && sbind <= STB_HIOS) + return "OS"; + else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) + return "PROC"; + else + snprintf(s_sbind, sizeof(s_sbind), "", + sbind); + return (s_sbind); + } +} + +static const char * +st_bindings_S(unsigned int sbind) +{ + static char s_sbind[32]; + + switch (sbind) { + case STB_LOCAL: return "LOCL"; + case STB_GLOBAL: return "GLOB"; + case STB_WEAK: return "WEAK"; + case STB_GNU_UNIQUE: return "UNIQ"; + default: + if (sbind >= STB_LOOS && sbind <= STB_HIOS) + return "OS"; + else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) + return "PROC"; + else + snprintf(s_sbind, sizeof(s_sbind), "<%#x>", + sbind); + return (s_sbind); + } +} + +static unsigned char st_others[] = { + 'D', 'I', 'H', 'P' +}; + +static void add_name(struct elfdump *ed, const char *name); +static void elf_print_object(struct elfdump *ed); +static void elf_print_elf(struct elfdump *ed); +static void elf_print_ehdr(struct elfdump *ed); +static void elf_print_phdr(struct elfdump *ed); +static void elf_print_shdr(struct elfdump *ed); +static void elf_print_symtab(struct elfdump *ed, int i); +static void elf_print_symtabs(struct elfdump *ed); +static void elf_print_symver(struct elfdump *ed); +static void elf_print_verdef(struct elfdump *ed, struct section *s); +static void elf_print_verneed(struct elfdump *ed, struct section *s); +static void elf_print_interp(struct elfdump *ed); +static void elf_print_dynamic(struct elfdump *ed); +static void elf_print_rel_entry(struct elfdump *ed, struct section *s, + int j, struct rel_entry *r); +static void elf_print_rela(struct elfdump *ed, struct section *s, + Elf_Data *data); +static void elf_print_rel(struct elfdump *ed, struct section *s, + Elf_Data *data); +static void elf_print_reloc(struct elfdump *ed); +static void elf_print_got(struct elfdump *ed); +static void elf_print_got_section(struct elfdump *ed, struct section *s); +static void elf_print_notes(struct elfdump *ed); +static void elf_print_note(struct elfdump *ed, struct section *s); +static void elf_print_svr4_hash(struct elfdump *ed, struct section *s); +static void elf_print_svr4_hash64(struct elfdump *ed, struct section *s); +static void elf_print_gnu_hash(struct elfdump *ed, struct section *s); +static void elf_print_hash(struct elfdump *ed); +static void elf_print_checksum(struct elfdump *ed); +static void find_gotrel(struct elfdump *ed, struct section *gs, + struct rel_entry *got); +static struct spec_name *find_name(struct elfdump *ed, const char *name); +static int get_ent_count(const struct section *s, int *ent_count); +static const char *get_symbol_name(struct elfdump *ed, uint32_t symtab, int i); +static const char *get_string(struct elfdump *ed, int strtab, size_t off); +static void get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs); +static void load_sections(struct elfdump *ed); +static void unload_sections(struct elfdump *ed); +static void usage(int); +#ifdef USE_LIBARCHIVE_AR +static int ac_detect_ar(int fd); +static void ac_print_ar(struct elfdump *ed, int fd); +#else +static void elf_print_ar(struct elfdump *ed, int fd); +#endif /* USE_LIBARCHIVE_AR */ + +static struct option elfdump_longopts[] = +{ + { "help", no_argument, NULL, 'H' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +int +main(int ac, char **av) +{ + struct elfdump *ed, ed_storage; + struct spec_name *sn; + int ch, i; + + ed = &ed_storage; + memset(ed, 0, sizeof(*ed)); + STAILQ_INIT(&ed->snl); + ed->out = stdout; + while ((ch = getopt_long(ac, av, "acdeiGHhknN:prsSvVw:", + elfdump_longopts, NULL)) != -1) + switch (ch) { + case 'a': + ed->options = ED_ALL; + break; + case 'c': + ed->options |= ED_SHDR; + break; + case 'd': + ed->options |= ED_DYN; + break; + case 'e': + ed->options |= ED_EHDR; + break; + case 'i': + ed->options |= ED_INTERP; + break; + case 'G': + ed->options |= ED_GOT; + break; + case 'h': + ed->options |= ED_HASH; + break; + case 'k': + ed->options |= ED_CHECKSUM; + break; + case 'n': + ed->options |= ED_NOTE; + break; + case 'N': + add_name(ed, optarg); + break; + case 'p': + ed->options |= ED_PHDR; + break; + case 'r': + ed->options |= ED_REL; + break; + case 's': + ed->options |= ED_SYMTAB; + break; + case 'S': + ed->flags |= SOLARIS_FMT; + break; + case 'v': + ed->options |= ED_SYMVER; + break; + case 'V': + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), + elftc_version()); + exit(EXIT_SUCCESS); + break; + case 'w': + if ((ed->out = fopen(optarg, "w")) == NULL) + err(EXIT_FAILURE, "%s", optarg); + break; + case 'H': + usage(EX_OK); + break; + case '?': + default: + usage(EX_USAGE); + break; + } + + ac -= optind; + av += optind; + + if (ed->options == 0) + ed->options = ED_ALL; + sn = NULL; + if (ed->options & ED_SYMTAB && + (STAILQ_EMPTY(&ed->snl) || (sn = find_name(ed, "ARSYM")) != NULL)) { + ed->flags |= PRINT_ARSYM; + if (sn != NULL) { + STAILQ_REMOVE(&ed->snl, sn, spec_name, sn_list); + if (STAILQ_EMPTY(&ed->snl)) + ed->flags |= ONLY_ARSYM; + } + } + if (ac == 0) + usage(EX_USAGE); + if (ac > 1) + ed->flags |= PRINT_FILENAME; + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + for (i = 0; i < ac; i++) { + ed->filename = av[i]; + ed->archive = NULL; + elf_print_object(ed); + } + + exit(EXIT_SUCCESS); +} + +#ifdef USE_LIBARCHIVE_AR + +/* Archive symbol table entry. */ +struct arsym_entry { + char *sym_name; + size_t off; +}; + +/* + * Convenient wrapper for general libarchive error handling. + */ +#define AC(CALL) do { \ + if ((CALL)) { \ + warnx("%s", archive_error_string(a)); \ + return; \ + } \ +} while (0) + +/* + * Detect an ar(1) archive using libarchive(3). + */ +static int +ac_detect_ar(int fd) +{ + struct archive *a; + struct archive_entry *entry; + int r; + + r = -1; + if ((a = archive_read_new()) == NULL) + return (0); + archive_read_support_format_ar(a); + if (archive_read_open_fd(a, fd, 10240) == ARCHIVE_OK) + r = archive_read_next_header(a, &entry); + archive_read_close(a); + archive_read_free(a); + + return (r == ARCHIVE_OK); +} + +/* + * Dump an ar(1) archive using libarchive(3). + */ +static void +ac_print_ar(struct elfdump *ed, int fd) +{ + struct archive *a; + struct archive_entry *entry; + struct arsym_entry *arsym; + const char *name; + char idx[10], *b; + void *buff; + size_t size; + uint32_t cnt, i; + int r; + + if (lseek(fd, 0, SEEK_SET) == -1) + err(EXIT_FAILURE, "lseek failed"); + if ((a = archive_read_new()) == NULL) + errx(EXIT_FAILURE, "%s", archive_error_string(a)); + archive_read_support_format_ar(a); + AC(archive_read_open_fd(a, fd, 10240)); + for(;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_FATAL) + errx(EXIT_FAILURE, "%s", archive_error_string(a)); + if (r == ARCHIVE_EOF) + break; + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) + warnx("%s", archive_error_string(a)); + if (r == ARCHIVE_RETRY) + continue; + name = archive_entry_pathname(entry); + size = archive_entry_size(entry); + if (size == 0) + continue; + if ((buff = malloc(size)) == NULL) { + warn("malloc failed"); + continue; + } + if (archive_read_data(a, buff, size) != (ssize_t)size) { + warnx("%s", archive_error_string(a)); + free(buff); + continue; + } + + /* + * Note that when processing arsym via libarchive, there is + * no way to tell which member a certain symbol belongs to, + * since we can not just "lseek" to a member offset and read + * the member header. + */ + if (!strcmp(name, "/") && ed->flags & PRINT_ARSYM) { + b = buff; + cnt = be32dec(b); + if (cnt == 0) { + free(buff); + continue; + } + arsym = calloc(cnt, sizeof(*arsym)); + if (arsym == NULL) + err(EXIT_FAILURE, "calloc failed"); + b += sizeof(uint32_t); + for (i = 0; i < cnt; i++) { + arsym[i].off = be32dec(b); + b += sizeof(uint32_t); + } + for (i = 0; i < cnt; i++) { + arsym[i].sym_name = b; + b += strlen(b) + 1; + } + if (ed->flags & SOLARIS_FMT) { + PRT("\nSymbol Table: (archive)\n"); + PRT(" index offset symbol\n"); + } else + PRT("\nsymbol table (archive):\n"); + for (i = 0; i < cnt; i++) { + if (ed->flags & SOLARIS_FMT) { + snprintf(idx, sizeof(idx), "[%d]", i); + PRT("%10s ", idx); + PRT("0x%8.8jx ", + (uintmax_t)arsym[i].off); + PRT("%s\n", arsym[i].sym_name); + } else { + PRT("\nentry: %d\n", i); + PRT("\toffset: %#jx\n", + (uintmax_t)arsym[i].off); + PRT("\tsymbol: %s\n", + arsym[i].sym_name); + } + } + free(arsym); + free(buff); + /* No need to continue if we only dump ARSYM. */ + if (ed->flags & ONLY_ARSYM) { + AC(archive_read_close(a)); + AC(archive_read_free(a)); + return; + } + continue; + } + if ((ed->elf = elf_memory(buff, size)) == NULL) { + warnx("elf_memroy() failed: %s", + elf_errmsg(-1)); + free(buff); + continue; + } + /* Skip non-ELF member. */ + if (elf_kind(ed->elf) == ELF_K_ELF) { + printf("\n%s(%s):\n", ed->archive, name); + elf_print_elf(ed); + } + elf_end(ed->elf); + free(buff); + } + AC(archive_read_close(a)); + AC(archive_read_free(a)); +} + +#else /* USE_LIBARCHIVE_AR */ + +/* + * Dump an ar(1) archive. + */ +static void +elf_print_ar(struct elfdump *ed, int fd) +{ + Elf *e; + Elf_Arhdr *arh; + Elf_Arsym *arsym; + Elf_Cmd cmd; + char idx[21]; + size_t cnt, i; + + ed->ar = ed->elf; + + if (ed->flags & PRINT_ARSYM) { + cnt = 0; + if ((arsym = elf_getarsym(ed->ar, &cnt)) == NULL) { + warnx("elf_getarsym failed: %s", elf_errmsg(-1)); + goto print_members; + } + if (cnt == 0) + goto print_members; + if (ed->flags & SOLARIS_FMT) { + PRT("\nSymbol Table: (archive)\n"); + PRT(" index offset member name and symbol\n"); + } else + PRT("\nsymbol table (archive):\n"); + for (i = 0; i < cnt - 1; i++) { + if (elf_rand(ed->ar, arsym[i].as_off) != + arsym[i].as_off) { + warnx("elf_rand failed: %s", elf_errmsg(-1)); + break; + } + if ((e = elf_begin(fd, ELF_C_READ, ed->ar)) == NULL) { + warnx("elf_begin failed: %s", elf_errmsg(-1)); + break; + } + if ((arh = elf_getarhdr(e)) == NULL) { + warnx("elf_getarhdr failed: %s", + elf_errmsg(-1)); + break; + } + if (ed->flags & SOLARIS_FMT) { + snprintf(idx, sizeof(idx), "[%zu]", i); + PRT("%10s ", idx); + PRT("0x%8.8jx ", + (uintmax_t)arsym[i].as_off); + PRT("(%s):%s\n", arh->ar_name, + arsym[i].as_name); + } else { + PRT("\nentry: %zu\n", i); + PRT("\toffset: %#jx\n", + (uintmax_t)arsym[i].as_off); + PRT("\tmember: %s\n", arh->ar_name); + PRT("\tsymbol: %s\n", arsym[i].as_name); + } + elf_end(e); + } + + /* No need to continue if we only dump ARSYM. */ + if (ed->flags & ONLY_ARSYM) + return; + } + +print_members: + + /* Rewind the archive. */ + if (elf_rand(ed->ar, SARMAG) != SARMAG) { + warnx("elf_rand failed: %s", elf_errmsg(-1)); + return; + } + + /* Dump each member of the archive. */ + cmd = ELF_C_READ; + while ((ed->elf = elf_begin(fd, cmd, ed->ar)) != NULL) { + /* Skip non-ELF member. */ + if (elf_kind(ed->elf) == ELF_K_ELF) { + if ((arh = elf_getarhdr(ed->elf)) == NULL) { + warnx("elf_getarhdr failed: %s", + elf_errmsg(-1)); + break; + } + printf("\n%s(%s):\n", ed->archive, arh->ar_name); + elf_print_elf(ed); + } + cmd = elf_next(ed->elf); + elf_end(ed->elf); + } +} + +#endif /* USE_LIBARCHIVE_AR */ + +/* + * Dump an object. (ELF object or ar(1) archive) + */ +static void +elf_print_object(struct elfdump *ed) +{ + int fd; + + if ((fd = open(ed->filename, O_RDONLY)) == -1) { + warn("open %s failed", ed->filename); + return; + } + +#ifdef USE_LIBARCHIVE_AR + if (ac_detect_ar(fd)) { + ed->archive = ed->filename; + ac_print_ar(ed, fd); + return; + } +#endif /* USE_LIBARCHIVE_AR */ + + if ((ed->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warnx("elf_begin() failed: %s", elf_errmsg(-1)); + return; + } + + switch (elf_kind(ed->elf)) { + case ELF_K_NONE: + warnx("Not an ELF file."); + return; + case ELF_K_ELF: + if (ed->flags & PRINT_FILENAME) + printf("\n%s:\n", ed->filename); + elf_print_elf(ed); + break; + case ELF_K_AR: +#ifndef USE_LIBARCHIVE_AR + ed->archive = ed->filename; + elf_print_ar(ed, fd); +#endif + break; + default: + warnx("Internal: libelf returned unknown elf kind."); + return; + } + + elf_end(ed->elf); +} + +/* + * Dump an ELF object. + */ +static void +elf_print_elf(struct elfdump *ed) +{ + + if (gelf_getehdr(ed->elf, &ed->ehdr) == NULL) { + warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); + return; + } + if ((ed->ec = gelf_getclass(ed->elf)) == ELFCLASSNONE) { + warnx("gelf_getclass failed: %s", elf_errmsg(-1)); + return; + } + + if (ed->options & (ED_SHDR | ED_DYN | ED_REL | ED_GOT | ED_SYMTAB | + ED_SYMVER | ED_NOTE | ED_HASH)) + load_sections(ed); + + if (ed->options & ED_EHDR) + elf_print_ehdr(ed); + if (ed->options & ED_PHDR) + elf_print_phdr(ed); + if (ed->options & ED_INTERP) + elf_print_interp(ed); + if (ed->options & ED_SHDR) + elf_print_shdr(ed); + if (ed->options & ED_DYN) + elf_print_dynamic(ed); + if (ed->options & ED_REL) + elf_print_reloc(ed); + if (ed->options & ED_GOT) + elf_print_got(ed); + if (ed->options & ED_SYMTAB) + elf_print_symtabs(ed); + if (ed->options & ED_SYMVER) + elf_print_symver(ed); + if (ed->options & ED_NOTE) + elf_print_notes(ed); + if (ed->options & ED_HASH) + elf_print_hash(ed); + if (ed->options & ED_CHECKSUM) + elf_print_checksum(ed); + + unload_sections(ed); +} + +/* + * Read the section headers from ELF object and store them in the + * internal cache. + */ +static void +load_sections(struct elfdump *ed) +{ + struct section *s; + const char *name; + Elf_Scn *scn; + GElf_Shdr sh; + size_t shstrndx, ndx; + int elferr; + + assert(ed->sl == NULL); + + if (!elf_getshnum(ed->elf, &ed->shnum)) { + warnx("elf_getshnum failed: %s", elf_errmsg(-1)); + return; + } + if (ed->shnum == 0) + return; + if ((ed->sl = calloc(ed->shnum, sizeof(*ed->sl))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + if (!elf_getshstrndx(ed->elf, &shstrndx)) { + warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); + return; + } + if ((scn = elf_getscn(ed->elf, 0)) == NULL) { + warnx("elf_getscn failed: %s", elf_errmsg(-1)); + return; + } + (void) elf_errno(); + do { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((name = elf_strptr(ed->elf, shstrndx, sh.sh_name)) == NULL) { + (void) elf_errno(); + name = "ERROR"; + } + if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) + if ((elferr = elf_errno()) != 0) { + warnx("elf_ndxscn failed: %s", + elf_errmsg(elferr)); + continue; + } + if (ndx >= ed->shnum) { + warnx("section index of '%s' out of range", name); + continue; + } + s = &ed->sl[ndx]; + s->name = name; + s->scn = scn; + s->off = sh.sh_offset; + s->sz = sh.sh_size; + s->entsize = sh.sh_entsize; + s->align = sh.sh_addralign; + s->type = sh.sh_type; + s->flags = sh.sh_flags; + s->addr = sh.sh_addr; + s->link = sh.sh_link; + s->info = sh.sh_info; + } while ((scn = elf_nextscn(ed->elf, scn)) != NULL); + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); +} + +/* + * Release section related resources. + */ +static void +unload_sections(struct elfdump *ed) +{ + if (ed->sl != NULL) { + free(ed->sl); + ed->sl = NULL; + } +} + +/* + * Add a name to the '-N' name list. + */ +static void +add_name(struct elfdump *ed, const char *name) +{ + struct spec_name *sn; + + if (find_name(ed, name)) + return; + if ((sn = malloc(sizeof(*sn))) == NULL) { + warn("malloc failed"); + return; + } + sn->name = name; + STAILQ_INSERT_TAIL(&ed->snl, sn, sn_list); +} + +/* + * Lookup a name in the '-N' name list. + */ +static struct spec_name * +find_name(struct elfdump *ed, const char *name) +{ + struct spec_name *sn; + + STAILQ_FOREACH(sn, &ed->snl, sn_list) { + if (!strcmp(sn->name, name)) + return (sn); + } + + return (NULL); +} + +/* + * Retrieve the name of a symbol using the section index of the symbol + * table and the index of the symbol within that table. + */ +static const char * +get_symbol_name(struct elfdump *ed, uint32_t symtab, int i) +{ + static char sname[64]; + struct section *s; + const char *name; + GElf_Sym sym; + Elf_Data *data; + int elferr; + + if (symtab >= ed->shnum) + return (""); + s = &ed->sl[symtab]; + if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) + return (""); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return (""); + } + if (gelf_getsym(data, i, &sym) != &sym) + return (""); + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) { + if (sym.st_shndx < ed->shnum) { + snprintf(sname, sizeof(sname), "%s (section)", + ed->sl[sym.st_shndx].name); + return (sname); + } else + return (""); + } + if ((name = elf_strptr(ed->elf, s->link, sym.st_name)) == NULL) + return (""); + + return (name); +} + +/* + * Retrieve a string using string table section index and the string offset. + */ +static const char* +get_string(struct elfdump *ed, int strtab, size_t off) +{ + const char *name; + + if ((name = elf_strptr(ed->elf, strtab, off)) == NULL) + return (""); + + return (name); +} + +/* + * Dump the ELF Executable Header. + */ +static void +elf_print_ehdr(struct elfdump *ed) +{ + + if (!STAILQ_EMPTY(&ed->snl)) + return; + + if (ed->flags & SOLARIS_FMT) { + PRT("\nELF Header\n"); + PRT(" ei_magic: { %#x, %c, %c, %c }\n", + ed->ehdr.e_ident[0], ed->ehdr.e_ident[1], + ed->ehdr.e_ident[2], ed->ehdr.e_ident[3]); + PRT(" ei_class: %-18s", + elf_class_str(ed->ehdr.e_ident[EI_CLASS])); + PRT(" ei_data: %s\n", + elf_data_str(ed->ehdr.e_ident[EI_DATA])); + PRT(" e_machine: %-18s", e_machines(ed->ehdr.e_machine)); + PRT(" e_version: %s\n", + elf_version_str(ed->ehdr.e_version)); + PRT(" e_type: %s\n", elf_type_str(ed->ehdr.e_type)); + PRT(" e_flags: %18d\n", ed->ehdr.e_flags); + PRT(" e_entry: %#18jx", (uintmax_t)ed->ehdr.e_entry); + PRT(" e_ehsize: %6d", ed->ehdr.e_ehsize); + PRT(" e_shstrndx:%5d\n", ed->ehdr.e_shstrndx); + PRT(" e_shoff: %#18jx", (uintmax_t)ed->ehdr.e_shoff); + PRT(" e_shentsize: %3d", ed->ehdr.e_shentsize); + PRT(" e_shnum: %5d\n", ed->ehdr.e_shnum); + PRT(" e_phoff: %#18jx", (uintmax_t)ed->ehdr.e_phoff); + PRT(" e_phentsize: %3d", ed->ehdr.e_phentsize); + PRT(" e_phnum: %5d\n", ed->ehdr.e_phnum); + } else { + PRT("\nelf header:\n"); + PRT("\n"); + PRT("\te_ident: %s %s %s\n", + elf_class_str(ed->ehdr.e_ident[EI_CLASS]), + elf_data_str(ed->ehdr.e_ident[EI_DATA]), + ei_abis[ed->ehdr.e_ident[EI_OSABI]]); + PRT("\te_type: %s\n", elf_type_str(ed->ehdr.e_type)); + PRT("\te_machine: %s\n", e_machines(ed->ehdr.e_machine)); + PRT("\te_version: %s\n", elf_version_str(ed->ehdr.e_version)); + PRT("\te_entry: %#jx\n", (uintmax_t)ed->ehdr.e_entry); + PRT("\te_phoff: %ju\n", (uintmax_t)ed->ehdr.e_phoff); + PRT("\te_shoff: %ju\n", (uintmax_t) ed->ehdr.e_shoff); + PRT("\te_flags: %u\n", ed->ehdr.e_flags); + PRT("\te_ehsize: %u\n", ed->ehdr.e_ehsize); + PRT("\te_phentsize: %u\n", ed->ehdr.e_phentsize); + PRT("\te_phnum: %u\n", ed->ehdr.e_phnum); + PRT("\te_shentsize: %u\n", ed->ehdr.e_shentsize); + PRT("\te_shnum: %u\n", ed->ehdr.e_shnum); + PRT("\te_shstrndx: %u\n", ed->ehdr.e_shstrndx); + } +} + +/* + * Dump the ELF Program Header Table. + */ +static void +elf_print_phdr(struct elfdump *ed) +{ + GElf_Phdr ph; + size_t phnum, i; + int header; + + if (elf_getphnum(ed->elf, &phnum) == 0) { + warnx("elf_getphnum failed: %s", elf_errmsg(-1)); + return; + } + header = 0; + for (i = 0; i < phnum; i++) { + if (gelf_getphdr(ed->elf, i, &ph) != &ph) { + warnx("elf_getphdr failed: %s", elf_errmsg(-1)); + continue; + } + if (!STAILQ_EMPTY(&ed->snl) && + find_name(ed, elf_phdr_type_str(ph.p_type)) == NULL) + continue; + if (ed->flags & SOLARIS_FMT) { + PRT("\nProgram Header[%zu]:\n", i); + PRT(" p_vaddr: %#-14jx", (uintmax_t)ph.p_vaddr); + PRT(" p_flags: [ %s ]\n", + p_flags[ph.p_flags & 0x7]); + PRT(" p_paddr: %#-14jx", (uintmax_t)ph.p_paddr); + PRT(" p_type: [ %s ]\n", + elf_phdr_type_str(ph.p_type)); + PRT(" p_filesz: %#-14jx", + (uintmax_t)ph.p_filesz); + PRT(" p_memsz: %#jx\n", (uintmax_t)ph.p_memsz); + PRT(" p_offset: %#-14jx", + (uintmax_t)ph.p_offset); + PRT(" p_align: %#jx\n", (uintmax_t)ph.p_align); + } else { + if (!header) { + PRT("\nprogram header:\n"); + header = 1; + } + PRT("\n"); + PRT("entry: %zu\n", i); + PRT("\tp_type: %s\n", elf_phdr_type_str(ph.p_type)); + PRT("\tp_offset: %ju\n", (uintmax_t)ph.p_offset); + PRT("\tp_vaddr: %#jx\n", (uintmax_t)ph.p_vaddr); + PRT("\tp_paddr: %#jx\n", (uintmax_t)ph.p_paddr); + PRT("\tp_filesz: %ju\n", (uintmax_t)ph.p_filesz); + PRT("\tp_memsz: %ju\n", (uintmax_t)ph.p_memsz); + PRT("\tp_flags: %s\n", p_flags[ph.p_flags & 0x7]); + PRT("\tp_align: %ju\n", (uintmax_t)ph.p_align); + } + } +} + +/* + * Dump the ELF Section Header Table. + */ +static void +elf_print_shdr(struct elfdump *ed) +{ + struct section *s; + size_t i; + + if (!STAILQ_EMPTY(&ed->snl)) + return; + + if ((ed->flags & SOLARIS_FMT) == 0) + PRT("\nsection header:\n"); + for (i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if (ed->flags & SOLARIS_FMT) { + if (i == 0) + continue; + PRT("\nSection Header[%zu]:", i); + PRT(" sh_name: %s\n", s->name); + PRT(" sh_addr: %#-14jx", (uintmax_t)s->addr); + if (s->flags != 0) + PRT(" sh_flags: [ %s ]\n", sh_flags(s->flags)); + else + PRT(" sh_flags: 0\n"); + PRT(" sh_size: %#-14jx", (uintmax_t)s->sz); + PRT(" sh_type: [ %s ]\n", + sh_types(ed->ehdr.e_machine, s->type)); + PRT(" sh_offset: %#-14jx", (uintmax_t)s->off); + PRT(" sh_entsize: %#jx\n", (uintmax_t)s->entsize); + PRT(" sh_link: %-14u", s->link); + PRT(" sh_info: %u\n", s->info); + PRT(" sh_addralign: %#jx\n", (uintmax_t)s->align); + } else { + PRT("\n"); + PRT("entry: %ju\n", (uintmax_t)i); + PRT("\tsh_name: %s\n", s->name); + PRT("\tsh_type: %s\n", + sh_types(ed->ehdr.e_machine, s->type)); + PRT("\tsh_flags: %s\n", sh_flags(s->flags)); + PRT("\tsh_addr: %#jx\n", (uintmax_t)s->addr); + PRT("\tsh_offset: %ju\n", (uintmax_t)s->off); + PRT("\tsh_size: %ju\n", (uintmax_t)s->sz); + PRT("\tsh_link: %u\n", s->link); + PRT("\tsh_info: %u\n", s->info); + PRT("\tsh_addralign: %ju\n", (uintmax_t)s->align); + PRT("\tsh_entsize: %ju\n", (uintmax_t)s->entsize); + } + } +} + +/* + * Return number of entries in the given section. We'd prefer ent_count be a + * size_t, but libelf APIs already use int for section indices. + */ +static int +get_ent_count(const struct section *s, int *ent_count) +{ + if (s->entsize == 0) { + warnx("section %s has entry size 0", s->name); + return (0); + } else if (s->sz / s->entsize > INT_MAX) { + warnx("section %s has invalid section count", s->name); + return (0); + } + *ent_count = (int)(s->sz / s->entsize); + return (1); +} + +/* + * Retrieve the content of the corresponding SHT_SUNW_versym section for + * a symbol table section. + */ +static void +get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs) +{ + struct section *s; + Elf_Data *data; + size_t j; + int elferr; + + s = NULL; + for (j = 0; j < ed->shnum; j++) { + s = &ed->sl[j]; + if (s->type == SHT_SUNW_versym && s->link == (uint32_t)i) + break; + } + if (j >= ed->shnum) { + *vs = NULL; + return; + } + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + *vs = NULL; + return; + } + + *vs = data->d_buf; + assert(data->d_size == s->sz); + if (!get_ent_count(s, nvs)) + *nvs = 0; +} + +/* + * Dump the symbol table section. + */ +static void +elf_print_symtab(struct elfdump *ed, int i) +{ + struct section *s; + const char *name; + uint16_t *vs; + char idx[13]; + Elf_Data *data; + GElf_Sym sym; + int len, j, elferr, nvs; + + s = &ed->sl[i]; + if (ed->flags & SOLARIS_FMT) + PRT("\nSymbol Table Section: %s\n", s->name); + else + PRT("\nsymbol table (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + vs = NULL; + nvs = 0; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + if (ed->flags & SOLARIS_FMT) { + if (ed->ec == ELFCLASS32) + PRT(" index value "); + else + PRT(" index value "); + PRT("size type bind oth ver shndx name\n"); + get_versym(ed, i, &vs, &nvs); + if (vs != NULL && nvs != len) { + warnx("#symbol not equal to #versym"); + vs = NULL; + } + } + for (j = 0; j < len; j++) { + if (gelf_getsym(data, j, &sym) != &sym) { + warnx("gelf_getsym failed: %s", elf_errmsg(-1)); + continue; + } + name = get_string(ed, s->link, sym.st_name); + if (ed->flags & SOLARIS_FMT) { + snprintf(idx, sizeof(idx), "[%d]", j); + if (ed->ec == ELFCLASS32) + PRT("%10s ", idx); + else + PRT("%10s ", idx); + PRT("0x%8.8jx ", (uintmax_t)sym.st_value); + if (ed->ec == ELFCLASS32) + PRT("0x%8.8jx ", (uintmax_t)sym.st_size); + else + PRT("0x%12.12jx ", (uintmax_t)sym.st_size); + PRT("%s ", st_type_S(GELF_ST_TYPE(sym.st_info))); + PRT("%s ", st_bindings_S(GELF_ST_BIND(sym.st_info))); + PRT("%c ", st_others[sym.st_other]); + PRT("%3u ", (vs == NULL ? 0 : vs[j])); + PRT("%-11.11s ", sh_name(ed, sym.st_shndx)); + PRT("%s\n", name); + } else { + PRT("\nentry: %d\n", j); + PRT("\tst_name: %s\n", name); + PRT("\tst_value: %#jx\n", (uintmax_t)sym.st_value); + PRT("\tst_size: %ju\n", (uintmax_t)sym.st_size); + PRT("\tst_info: %s %s\n", + st_type(ed->ehdr.e_machine, + GELF_ST_TYPE(sym.st_info)), + st_bindings(GELF_ST_BIND(sym.st_info))); + PRT("\tst_shndx: %ju\n", (uintmax_t)sym.st_shndx); + } + } +} + +/* + * Dump the symbol tables. (.dynsym and .symtab) + */ +static void +elf_print_symtabs(struct elfdump *ed) +{ + size_t i; + + for (i = 0; i < ed->shnum; i++) + if ((ed->sl[i].type == SHT_SYMTAB || + ed->sl[i].type == SHT_DYNSYM) && + (STAILQ_EMPTY(&ed->snl) || find_name(ed, ed->sl[i].name))) + elf_print_symtab(ed, i); +} + +/* + * Dump the content of .dynamic section. + */ +static void +elf_print_dynamic(struct elfdump *ed) +{ + struct section *s; + const char *name; + char idx[13]; + Elf_Data *data; + GElf_Dyn dyn; + int elferr, i, len; + + s = NULL; + for (i = 0; (size_t)i < ed->shnum; i++) { + s = &ed->sl[i]; + if (s->type == SHT_DYNAMIC && + (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) + break; + } + if ((size_t)i >= ed->shnum) + return; + + if (ed->flags & SOLARIS_FMT) { + PRT("Dynamic Section: %s\n", s->name); + PRT(" index tag value\n"); + } else + PRT("\ndynamic:\n"); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (i = 0; i < len; i++) { + if (gelf_getdyn(data, i, &dyn) != &dyn) { + warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); + continue; + } + + if (ed->flags & SOLARIS_FMT) { + snprintf(idx, sizeof(idx), "[%d]", i); + PRT("%10s %-16s ", idx, d_tags(dyn.d_tag)); + } else { + PRT("\n"); + PRT("entry: %d\n", i); + PRT("\td_tag: %s\n", d_tags(dyn.d_tag)); + } + switch(dyn.d_tag) { + case DT_NEEDED: + case DT_SONAME: + case DT_RPATH: + case DT_RUNPATH: + if ((name = elf_strptr(ed->elf, s->link, + dyn.d_un.d_val)) == NULL) + name = ""; + if (ed->flags & SOLARIS_FMT) + PRT("%#-16jx %s\n", (uintmax_t)dyn.d_un.d_val, + name); + else + PRT("\td_val: %s\n", name); + break; + case DT_PLTRELSZ: + case DT_RELA: + case DT_RELASZ: + case DT_RELAENT: + case DT_RELACOUNT: + case DT_STRSZ: + case DT_SYMENT: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + case DT_VERDEF: + case DT_VERDEFNUM: + case DT_VERNEED: + case DT_VERNEEDNUM: + case DT_VERSYM: + if (ed->flags & SOLARIS_FMT) + PRT("%#jx\n", (uintmax_t)dyn.d_un.d_val); + else + PRT("\td_val: %ju\n", + (uintmax_t)dyn.d_un.d_val); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_GNU_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_JMPREL: + case DT_DEBUG: + if (ed->flags & SOLARIS_FMT) + PRT("%#jx\n", (uintmax_t)dyn.d_un.d_ptr); + else + PRT("\td_ptr: %#jx\n", + (uintmax_t)dyn.d_un.d_ptr); + break; + case DT_NULL: + case DT_SYMBOLIC: + case DT_TEXTREL: + default: + if (ed->flags & SOLARIS_FMT) + PRT("\n"); + break; + } + } +} + +/* + * Dump a .rel/.rela section entry. + */ +static void +elf_print_rel_entry(struct elfdump *ed, struct section *s, int j, + struct rel_entry *r) +{ + + if (ed->flags & SOLARIS_FMT) { + PRT(" %-23s ", elftc_reloc_type_str(ed->ehdr.e_machine, + GELF_R_TYPE(r->u_r.rel.r_info))); + PRT("%#12jx ", (uintmax_t)r->u_r.rel.r_offset); + if (r->type == SHT_RELA) + PRT("%10jd ", (intmax_t)r->u_r.rela.r_addend); + else + PRT(" "); + PRT("%-14s ", s->name); + PRT("%s\n", r->symn); + } else { + PRT("\n"); + PRT("entry: %d\n", j); + PRT("\tr_offset: %#jx\n", (uintmax_t)r->u_r.rel.r_offset); + if (ed->ec == ELFCLASS32) + PRT("\tr_info: %#jx\n", (uintmax_t) + ELF32_R_INFO(ELF64_R_SYM(r->u_r.rel.r_info), + ELF64_R_TYPE(r->u_r.rel.r_info))); + else + PRT("\tr_info: %#jx\n", (uintmax_t)r->u_r.rel.r_info); + if (r->type == SHT_RELA) + PRT("\tr_addend: %jd\n", + (intmax_t)r->u_r.rela.r_addend); + } +} + +/* + * Dump a relocation section of type SHT_RELA. + */ +static void +elf_print_rela(struct elfdump *ed, struct section *s, Elf_Data *data) +{ + struct rel_entry r; + int j, len; + + if (ed->flags & SOLARIS_FMT) { + PRT("\nRelocation Section: %s\n", s->name); + PRT(" type offset " + "addend section with respect to\n"); + } else + PRT("\nrelocation with addend (%s):\n", s->name); + r.type = SHT_RELA; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (j = 0; j < len; j++) { + if (gelf_getrela(data, j, &r.u_r.rela) != &r.u_r.rela) { + warnx("gelf_getrela failed: %s", + elf_errmsg(-1)); + continue; + } + r.symn = get_symbol_name(ed, s->link, + GELF_R_SYM(r.u_r.rela.r_info)); + elf_print_rel_entry(ed, s, j, &r); + } +} + +/* + * Dump a relocation section of type SHT_REL. + */ +static void +elf_print_rel(struct elfdump *ed, struct section *s, Elf_Data *data) +{ + struct rel_entry r; + int j, len; + + if (ed->flags & SOLARIS_FMT) { + PRT("\nRelocation Section: %s\n", s->name); + PRT(" type offset " + "section with respect to\n"); + } else + PRT("\nrelocation (%s):\n", s->name); + r.type = SHT_REL; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (j = 0; j < len; j++) { + if (gelf_getrel(data, j, &r.u_r.rel) != &r.u_r.rel) { + warnx("gelf_getrel failed: %s", elf_errmsg(-1)); + continue; + } + r.symn = get_symbol_name(ed, s->link, + GELF_R_SYM(r.u_r.rel.r_info)); + elf_print_rel_entry(ed, s, j, &r); + } +} + +/* + * Dump relocation sections. + */ +static void +elf_print_reloc(struct elfdump *ed) +{ + struct section *s; + Elf_Data *data; + size_t i; + int elferr; + + for (i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if ((s->type == SHT_REL || s->type == SHT_RELA) && + (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) { + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + if (s->type == SHT_REL) + elf_print_rel(ed, s, data); + else + elf_print_rela(ed, s, data); + } + } +} + +/* + * Dump the content of PT_INTERP segment. + */ +static void +elf_print_interp(struct elfdump *ed) +{ + const char *s; + GElf_Phdr phdr; + size_t filesize, i, phnum; + + if (!STAILQ_EMPTY(&ed->snl) && find_name(ed, "PT_INTERP") == NULL) + return; + + if ((s = elf_rawfile(ed->elf, &filesize)) == NULL) { + warnx("elf_rawfile failed: %s", elf_errmsg(-1)); + return; + } + if (!elf_getphnum(ed->elf, &phnum)) { + warnx("elf_getphnum failed: %s", elf_errmsg(-1)); + return; + } + for (i = 0; i < phnum; i++) { + if (gelf_getphdr(ed->elf, i, &phdr) != &phdr) { + warnx("elf_getphdr failed: %s", elf_errmsg(-1)); + continue; + } + if (phdr.p_type == PT_INTERP) { + if (phdr.p_offset >= filesize) { + warnx("invalid phdr offset"); + continue; + } + PRT("\ninterp:\n"); + PRT("\t%s\n", s + phdr.p_offset); + } + } +} + +/* + * Search the relocation sections for entries referring to the .got section. + */ +static void +find_gotrel(struct elfdump *ed, struct section *gs, struct rel_entry *got) +{ + struct section *s; + struct rel_entry r; + Elf_Data *data; + size_t i; + int elferr, j, k, len; + + for(i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if (s->type != SHT_REL && s->type != SHT_RELA) + continue; + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + memset(&r, 0, sizeof(struct rel_entry)); + r.type = s->type; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (j = 0; j < len; j++) { + if (s->type == SHT_REL) { + if (gelf_getrel(data, j, &r.u_r.rel) != + &r.u_r.rel) { + warnx("gelf_getrel failed: %s", + elf_errmsg(-1)); + continue; + } + } else { + if (gelf_getrela(data, j, &r.u_r.rela) != + &r.u_r.rela) { + warnx("gelf_getrel failed: %s", + elf_errmsg(-1)); + continue; + } + } + if (r.u_r.rel.r_offset >= gs->addr && + r.u_r.rel.r_offset < gs->addr + gs->sz) { + r.symn = get_symbol_name(ed, s->link, + GELF_R_SYM(r.u_r.rel.r_info)); + k = (r.u_r.rel.r_offset - gs->addr) / + gs->entsize; + memcpy(&got[k], &r, sizeof(struct rel_entry)); + } + } + } +} + +static void +elf_print_got_section(struct elfdump *ed, struct section *s) +{ + struct rel_entry *got; + Elf_Data *data, dst; + int elferr, i, len; + + if (s->entsize == 0) { + /* XXX IA64 GOT section generated by gcc has entry size 0. */ + if (s->align != 0) + s->entsize = s->align; + else + return; + } + + if (!get_ent_count(s, &len)) + return; + if (ed->flags & SOLARIS_FMT) + PRT("\nGlobal Offset Table Section: %s (%d entries)\n", + s->name, len); + else + PRT("\nglobal offset table: %s\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + + /* + * GOT section has section type SHT_PROGBITS, thus libelf treats it as + * byte stream and will not perform any translation on it. As a result, + * an exlicit call to gelf_xlatetom is needed here. Depends on arch, + * GOT section should be translated to either WORD or XWORD. + */ + if (ed->ec == ELFCLASS32) + data->d_type = ELF_T_WORD; + else + data->d_type = ELF_T_XWORD; + memcpy(&dst, data, sizeof(Elf_Data)); + if (gelf_xlatetom(ed->elf, &dst, data, ed->ehdr.e_ident[EI_DATA]) != + &dst) { + warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); + return; + } + assert(dst.d_size == s->sz); + if (ed->flags & SOLARIS_FMT) { + /* + * In verbose/Solaris mode, we search the relocation sections + * and try to find the corresponding reloc entry for each GOT + * section entry. + */ + if ((got = calloc(len, sizeof(struct rel_entry))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + find_gotrel(ed, s, got); + if (ed->ec == ELFCLASS32) { + PRT(" ndx addr value reloc "); + PRT("addend symbol\n"); + } else { + PRT(" ndx addr value "); + PRT("reloc addend symbol\n"); + } + for(i = 0; i < len; i++) { + PRT("[%5.5d] ", i); + if (ed->ec == ELFCLASS32) { + PRT("%-8.8jx ", + (uintmax_t) (s->addr + i * s->entsize)); + PRT("%-8.8x ", *((uint32_t *)dst.d_buf + i)); + } else { + PRT("%-16.16jx ", + (uintmax_t) (s->addr + i * s->entsize)); + PRT("%-16.16jx ", + (uintmax_t) *((uint64_t *)dst.d_buf + i)); + } + PRT("%-18s ", elftc_reloc_type_str(ed->ehdr.e_machine, + GELF_R_TYPE(got[i].u_r.rel.r_info))); + if (ed->ec == ELFCLASS32) + PRT("%-8.8jd ", + (intmax_t)got[i].u_r.rela.r_addend); + else + PRT("%-12.12jd ", + (intmax_t)got[i].u_r.rela.r_addend); + if (got[i].symn == NULL) + got[i].symn = ""; + PRT("%s\n", got[i].symn); + } + free(got); + } else { + for(i = 0; i < len; i++) { + PRT("\nentry: %d\n", i); + if (ed->ec == ELFCLASS32) + PRT("\t%#x\n", *((uint32_t *)dst.d_buf + i)); + else + PRT("\t%#jx\n", + (uintmax_t) *((uint64_t *)dst.d_buf + i)); + } + } +} + +/* + * Dump the content of Global Offset Table section. + */ +static void +elf_print_got(struct elfdump *ed) +{ + struct section *s; + size_t i; + + if (!STAILQ_EMPTY(&ed->snl)) + return; + + s = NULL; + for (i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if (s->name && !strncmp(s->name, ".got", 4) && + (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) + elf_print_got_section(ed, s); + } +} + +/* + * Dump the content of a single note section. + */ +static void +elf_print_note(struct elfdump *ed, struct section *s) +{ + Elf_Data *data; + Elf_Note *en; + uint32_t namesz; + uint32_t descsz; + uint32_t desc; + size_t count; + int elferr, i; + uint8_t *src; + char idx[17]; + + if (ed->flags & SOLARIS_FMT) + PRT("\nNote Section: %s\n", s->name); + else + PRT("\nnote (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + src = data->d_buf; + count = data->d_size; + while (count > sizeof(Elf_Note)) { + en = (Elf_Note *) (uintptr_t) src; + namesz = en->n_namesz; + descsz = en->n_descsz; + src += sizeof(Elf_Note); + count -= sizeof(Elf_Note); + if (roundup2(namesz, 4) + roundup2(descsz, 4) > count) { + warnx("truncated note section"); + return; + } + if (ed->flags & SOLARIS_FMT) { + PRT("\n type %#x\n", en->n_type); + PRT(" namesz %#x:\n", en->n_namesz); + PRT("%s\n", src); + } else + PRT("\t%s ", src); + src += roundup2(namesz, 4); + count -= roundup2(namesz, 4); + + /* + * Note that we dump the whole desc part if we're in + * "Solaris mode", while in the normal mode, we only look + * at the first 4 bytes (a 32bit word) of the desc, i.e, + * we assume that it's always a FreeBSD version number. + */ + if (ed->flags & SOLARIS_FMT) { + PRT(" descsz %#x:", en->n_descsz); + for (i = 0; (uint32_t)i < descsz; i++) { + if ((i & 0xF) == 0) { + snprintf(idx, sizeof(idx), "desc[%d]", + i); + PRT("\n %-9s", idx); + } else if ((i & 0x3) == 0) + PRT(" "); + PRT(" %2.2x", src[i]); + } + PRT("\n"); + } else { + if (ed->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) + desc = be32dec(src); + else + desc = le32dec(src); + PRT("%d\n", desc); + } + src += roundup2(descsz, 4); + count -= roundup2(descsz, 4); + } +} + +/* + * Dump the content of note sections. + */ +static void +elf_print_notes(struct elfdump *ed) +{ + struct section *s; + int i; + + if (!STAILQ_EMPTY(&ed->snl)) + return; + + s = NULL; + for (i = 0; (size_t)i < ed->shnum; i++) { + s = &ed->sl[i]; + if (s->type != SHT_NOTE) + continue; + elf_print_note(ed, s); + } +} + +/* + * Dump a hash table. + */ +static void +elf_print_svr4_hash(struct elfdump *ed, struct section *s) +{ + Elf_Data *data; + uint32_t *buf; + uint32_t *bucket, *chain; + uint32_t nbucket, nchain; + uint32_t *bl, *c, maxl, total; + uint32_t i, j; + int first, elferr; + char idx[10]; + + if (ed->flags & SOLARIS_FMT) + PRT("\nHash Section: %s\n", s->name); + else + PRT("\nhash table (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (data->d_size < 2 * sizeof(uint32_t)) { + warnx(".hash section too small"); + return; + } + buf = data->d_buf; + nbucket = buf[0]; + nchain = buf[1]; + if (nbucket <= 0 || nchain <= 0) { + warnx("Malformed .hash section"); + return; + } + if (data->d_size != + ((uint64_t)nbucket + (uint64_t)nchain + 2) * sizeof(uint32_t)) { + warnx("Malformed .hash section"); + return; + } + bucket = &buf[2]; + chain = &buf[2 + nbucket]; + + if (ed->flags & SOLARIS_FMT) { + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) + if (++bl[i] > maxl) + maxl = bl[i]; + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + c[bl[i]]++; + PRT(" bucket symndx name\n"); + for (i = 0; i < nbucket; i++) { + first = 1; + for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) { + if (first) { + PRT("%10d ", i); + first = 0; + } else + PRT(" "); + snprintf(idx, sizeof(idx), "[%d]", j); + PRT("%-10s ", idx); + PRT("%s\n", get_symbol_name(ed, s->link, j)); + } + } + PRT("\n"); + total = 0; + for (i = 0; i <= maxl; i++) { + total += c[i] * i; + PRT("%10u buckets contain %8d symbols\n", c[i], i); + } + PRT("%10u buckets %8u symbols (globals)\n", nbucket, + total); + } else { + PRT("\nnbucket: %u\n", nbucket); + PRT("nchain: %u\n\n", nchain); + for (i = 0; i < nbucket; i++) + PRT("bucket[%d]:\n\t%u\n\n", i, bucket[i]); + for (i = 0; i < nchain; i++) + PRT("chain[%d]:\n\t%u\n\n", i, chain[i]); + } +} + +/* + * Dump a 64bit hash table. + */ +static void +elf_print_svr4_hash64(struct elfdump *ed, struct section *s) +{ + Elf_Data *data, dst; + uint64_t *buf; + uint64_t *bucket, *chain; + uint64_t nbucket, nchain; + uint64_t *bl, *c, j, maxl, total; + size_t i; + int elferr, first; + char idx[10]; + + if (ed->flags & SOLARIS_FMT) + PRT("\nHash Section: %s\n", s->name); + else + PRT("\nhash table (%s):\n", s->name); + + /* + * ALPHA uses 64-bit hash entries. Since libelf assumes that + * .hash section contains only 32-bit entry, an explicit + * gelf_xlatetom is needed here. + */ + (void) elf_errno(); + if ((data = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + return; + } + data->d_type = ELF_T_XWORD; + memcpy(&dst, data, sizeof(Elf_Data)); + if (gelf_xlatetom(ed->elf, &dst, data, + ed->ehdr.e_ident[EI_DATA]) != &dst) { + warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); + return; + } + if (dst.d_size < 2 * sizeof(uint64_t)) { + warnx(".hash section too small"); + return; + } + buf = dst.d_buf; + nbucket = buf[0]; + nchain = buf[1]; + if (nbucket <= 0 || nchain <= 0) { + warnx("Malformed .hash section"); + return; + } + if (dst.d_size != (nbucket + nchain + 2) * sizeof(uint64_t)) { + warnx("Malformed .hash section"); + return; + } + bucket = &buf[2]; + chain = &buf[2 + nbucket]; + + if (ed->flags & SOLARIS_FMT) { + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) + if (++bl[i] > maxl) + maxl = bl[i]; + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + c[bl[i]]++; + PRT(" bucket symndx name\n"); + for (i = 0; i < nbucket; i++) { + first = 1; + for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) { + if (first) { + PRT("%10zu ", i); + first = 0; + } else + PRT(" "); + snprintf(idx, sizeof(idx), "[%zu]", (size_t)j); + PRT("%-10s ", idx); + PRT("%s\n", get_symbol_name(ed, s->link, j)); + } + } + PRT("\n"); + total = 0; + for (i = 0; i <= maxl; i++) { + total += c[i] * i; + PRT("%10ju buckets contain %8zu symbols\n", + (uintmax_t)c[i], i); + } + PRT("%10ju buckets %8ju symbols (globals)\n", + (uintmax_t)nbucket, (uintmax_t)total); + } else { + PRT("\nnbucket: %ju\n", (uintmax_t)nbucket); + PRT("nchain: %ju\n\n", (uintmax_t)nchain); + for (i = 0; i < nbucket; i++) + PRT("bucket[%zu]:\n\t%ju\n\n", i, (uintmax_t)bucket[i]); + for (i = 0; i < nchain; i++) + PRT("chain[%zu]:\n\t%ju\n\n", i, (uintmax_t)chain[i]); + } + +} + +/* + * Dump a GNU hash table. + */ +static void +elf_print_gnu_hash(struct elfdump *ed, struct section *s) +{ + struct section *ds; + Elf_Data *data; + uint32_t *buf; + uint32_t *bucket, *chain; + uint32_t nbucket, nchain, symndx, maskwords, shift2; + uint32_t *bl, *c, maxl, total; + uint32_t i, j; + int first, elferr, dynsymcount; + char idx[10]; + + if (ed->flags & SOLARIS_FMT) + PRT("\nGNU Hash Section: %s\n", s->name); + else + PRT("\ngnu hash table (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (data->d_size < 4 * sizeof(uint32_t)) { + warnx(".gnu.hash section too small"); + return; + } + buf = data->d_buf; + nbucket = buf[0]; + symndx = buf[1]; + maskwords = buf[2]; + shift2 = buf[3]; + buf += 4; + if (s->link >= ed->shnum) { + warnx("Malformed .gnu.hash section"); + return; + } + ds = &ed->sl[s->link]; + if (!get_ent_count(ds, &dynsymcount)) + return; + if (symndx >= (uint32_t)dynsymcount) { + warnx("Malformed .gnu.hash section"); + return; + } + nchain = dynsymcount - symndx; + if (data->d_size != 4 * sizeof(uint32_t) + maskwords * + (ed->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + + ((uint64_t)nbucket + (uint64_t)nchain) * sizeof(uint32_t)) { + warnx("Malformed .gnu.hash section"); + return; + } + bucket = buf + (ed->ec == ELFCLASS32 ? maskwords : maskwords * 2); + chain = bucket + nbucket; + + if (ed->flags & SOLARIS_FMT) { + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + for (j = bucket[i]; j > 0 && j - symndx < nchain; j++) { + if (++bl[i] > maxl) + maxl = bl[i]; + if (chain[j - symndx] & 1) + break; + } + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + for (i = 0; i < nbucket; i++) + c[bl[i]]++; + PRT(" bucket symndx name\n"); + for (i = 0; i < nbucket; i++) { + first = 1; + for (j = bucket[i]; j > 0 && j - symndx < nchain; j++) { + if (first) { + PRT("%10d ", i); + first = 0; + } else + PRT(" "); + snprintf(idx, sizeof(idx), "[%d]", j ); + PRT("%-10s ", idx); + PRT("%s\n", get_symbol_name(ed, s->link, j)); + if (chain[j - symndx] & 1) + break; + } + } + PRT("\n"); + total = 0; + for (i = 0; i <= maxl; i++) { + total += c[i] * i; + PRT("%10u buckets contain %8d symbols\n", c[i], i); + } + PRT("%10u buckets %8u symbols (globals)\n", nbucket, + total); + } else { + PRT("\nnbucket: %u\n", nbucket); + PRT("symndx: %u\n", symndx); + PRT("maskwords: %u\n", maskwords); + PRT("shift2: %u\n", shift2); + PRT("nchain: %u\n\n", nchain); + for (i = 0; i < nbucket; i++) + PRT("bucket[%d]:\n\t%u\n\n", i, bucket[i]); + for (i = 0; i < nchain; i++) + PRT("chain[%d]:\n\t%u\n\n", i, chain[i]); + } +} + +/* + * Dump hash tables. + */ +static void +elf_print_hash(struct elfdump *ed) +{ + struct section *s; + size_t i; + + for (i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if ((s->type == SHT_HASH || s->type == SHT_GNU_HASH) && + (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) { + if (s->type == SHT_GNU_HASH) + elf_print_gnu_hash(ed, s); + else if (ed->ehdr.e_machine == EM_ALPHA && + s->entsize == 8) + elf_print_svr4_hash64(ed, s); + else + elf_print_svr4_hash(ed, s); + } + } +} + +/* + * Dump the content of a Version Definition(SHT_SUNW_Verdef) Section. + */ +static void +elf_print_verdef(struct elfdump *ed, struct section *s) +{ + Elf_Data *data; + Elf32_Verdef *vd; + Elf32_Verdaux *vda; + const char *str; + char idx[10]; + uint8_t *buf, *end, *buf2; + int i, j, elferr, count; + + if (ed->flags & SOLARIS_FMT) + PRT("Version Definition Section: %s\n", s->name); + else + PRT("\nversion definition section (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + buf = data->d_buf; + end = buf + data->d_size; + i = 0; + if (ed->flags & SOLARIS_FMT) + PRT(" index version dependency\n"); + while (buf + sizeof(Elf32_Verdef) <= end) { + vd = (Elf32_Verdef *) (uintptr_t) buf; + if (ed->flags & SOLARIS_FMT) { + snprintf(idx, sizeof(idx), "[%d]", vd->vd_ndx); + PRT("%10s ", idx); + } else { + PRT("\nentry: %d\n", i++); + PRT("\tvd_version: %u\n", vd->vd_version); + PRT("\tvd_flags: %u\n", vd->vd_flags); + PRT("\tvd_ndx: %u\n", vd->vd_ndx); + PRT("\tvd_cnt: %u\n", vd->vd_cnt); + PRT("\tvd_hash: %u\n", vd->vd_hash); + PRT("\tvd_aux: %u\n", vd->vd_aux); + PRT("\tvd_next: %u\n\n", vd->vd_next); + } + buf2 = buf + vd->vd_aux; + j = 0; + count = 0; + while (buf2 + sizeof(Elf32_Verdaux) <= end && j < vd->vd_cnt) { + vda = (Elf32_Verdaux *) (uintptr_t) buf2; + str = get_string(ed, s->link, vda->vda_name); + if (ed->flags & SOLARIS_FMT) { + if (count == 0) + PRT("%-26.26s", str); + else if (count == 1) + PRT(" %-20.20s", str); + else { + PRT("\n%40.40s", ""); + PRT("%s", str); + } + } else { + PRT("\t\tvda: %d\n", j++); + PRT("\t\t\tvda_name: %s\n", str); + PRT("\t\t\tvda_next: %u\n", vda->vda_next); + } + if (vda->vda_next == 0) { + if (ed->flags & SOLARIS_FMT) { + if (vd->vd_flags & VER_FLG_BASE) { + if (count == 0) + PRT("%-20.20s", ""); + PRT("%s", "[ BASE ]"); + } + PRT("\n"); + } + break; + } + if (ed->flags & SOLARIS_FMT) + count++; + buf2 += vda->vda_next; + } + if (vd->vd_next == 0) + break; + buf += vd->vd_next; + } +} + +/* + * Dump the content of a Version Needed(SHT_SUNW_Verneed) Section. + */ +static void +elf_print_verneed(struct elfdump *ed, struct section *s) +{ + Elf_Data *data; + Elf32_Verneed *vn; + Elf32_Vernaux *vna; + uint8_t *buf, *end, *buf2; + int i, j, elferr, first; + + if (ed->flags & SOLARIS_FMT) + PRT("\nVersion Needed Section: %s\n", s->name); + else + PRT("\nversion need section (%s):\n", s->name); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + buf = data->d_buf; + end = buf + data->d_size; + if (ed->flags & SOLARIS_FMT) + PRT(" file version\n"); + i = 0; + while (buf + sizeof(Elf32_Verneed) <= end) { + vn = (Elf32_Verneed *) (uintptr_t) buf; + if (ed->flags & SOLARIS_FMT) + PRT(" %-26.26s ", + get_string(ed, s->link, vn->vn_file)); + else { + PRT("\nentry: %d\n", i++); + PRT("\tvn_version: %u\n", vn->vn_version); + PRT("\tvn_cnt: %u\n", vn->vn_cnt); + PRT("\tvn_file: %s\n", + get_string(ed, s->link, vn->vn_file)); + PRT("\tvn_aux: %u\n", vn->vn_aux); + PRT("\tvn_next: %u\n\n", vn->vn_next); + } + buf2 = buf + vn->vn_aux; + j = 0; + first = 1; + while (buf2 + sizeof(Elf32_Vernaux) <= end && j < vn->vn_cnt) { + vna = (Elf32_Vernaux *) (uintptr_t) buf2; + if (ed->flags & SOLARIS_FMT) { + if (!first) + PRT("%40.40s", ""); + else + first = 0; + PRT("%s\n", get_string(ed, s->link, + vna->vna_name)); + } else { + PRT("\t\tvna: %d\n", j++); + PRT("\t\t\tvna_hash: %u\n", vna->vna_hash); + PRT("\t\t\tvna_flags: %u\n", vna->vna_flags); + PRT("\t\t\tvna_other: %u\n", vna->vna_other); + PRT("\t\t\tvna_name: %s\n", + get_string(ed, s->link, vna->vna_name)); + PRT("\t\t\tvna_next: %u\n", vna->vna_next); + } + if (vna->vna_next == 0) + break; + buf2 += vna->vna_next; + } + if (vn->vn_next == 0) + break; + buf += vn->vn_next; + } +} + +/* + * Dump the symbol-versioning sections. + */ +static void +elf_print_symver(struct elfdump *ed) +{ + struct section *s; + size_t i; + + for (i = 0; i < ed->shnum; i++) { + s = &ed->sl[i]; + if (!STAILQ_EMPTY(&ed->snl) && !find_name(ed, s->name)) + continue; + if (s->type == SHT_SUNW_verdef) + elf_print_verdef(ed, s); + if (s->type == SHT_SUNW_verneed) + elf_print_verneed(ed, s); + } +} + +/* + * Dump the ELF checksum. See gelf_checksum(3) for details. + */ +static void +elf_print_checksum(struct elfdump *ed) +{ + + if (!STAILQ_EMPTY(&ed->snl)) + return; + + PRT("\nelf checksum: %#lx\n", gelf_checksum(ed->elf)); +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Display information about ELF objects and ar(1) archives.\n\n\ + Options:\n\ + -a Show all information.\n\ + -c Show shared headers.\n\ + -d Show dynamic symbols.\n\ + -e Show the ELF header.\n\ + -G Show the GOT.\n\ + -H | --help Show a usage message and exit.\n\ + -h Show hash values.\n\ + -i Show the dynamic interpreter.\n\ + -k Show the ELF checksum.\n\ + -n Show the contents of note sections.\n\ + -N NAME Show the section named \"NAME\".\n\ + -p Show the program header.\n\ + -r Show relocations.\n\ + -s Show the symbol table.\n\ + -S Use the Solaris elfdump format.\n\ + -v Show symbol-versioning information.\n\ + -V | --version Print a version identifier and exit.\n\ + -w FILE Write output to \"FILE\".\n" + +static void +usage(int exit_code) +{ + fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} diff --git a/contrib/elftoolchain/elfdump/os.NetBSD.mk b/contrib/elftoolchain/elfdump/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/elfdump/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/findtextrel/Makefile b/contrib/elftoolchain/findtextrel/Makefile new file mode 100644 index 0000000000..4c316eb0b4 --- /dev/null +++ b/contrib/elftoolchain/findtextrel/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile 2069 2011-10-26 15:53:48Z jkoshy $ + +TOP= .. + +PROG= findtextrel +SRCS= findtextrel.c + +WARNS?= 6 + +DPADD= ${LIBELFTC} ${LIBDWARF} ${LIBELF} +LDADD= -lelftc -ldwarf -lelf + +MAN1= findtextrel.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/findtextrel/findtextrel.1 b/contrib/elftoolchain/findtextrel/findtextrel.1 new file mode 100644 index 0000000000..125cc7ffbf --- /dev/null +++ b/contrib/elftoolchain/findtextrel/findtextrel.1 @@ -0,0 +1,104 @@ +.\" Copyright (c) 2010,2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: findtextrel.1 3195 2015-05-12 17:22:19Z emaste $ +.\" +.Dd August 25, 2011 +.Os +.Dt FINDTEXTREL 1 +.Sh NAME +.Nm findtextrel +.Nd locate text relocation entries in position independent ELF executables +.Sh SYNOPSIS +.Nm +.Op Fl V +.Op Fl H +.Op Ar +.Sh DESCRIPTION +The +.Nm +utility displays information about text relocations in ELF objects +containing position independent code. +.Pp +Text relocations are usually undesirable because they require that the +text sections of objects be modified at load time, preventing the +sharing of text sections across multiple processes using a dynamic +shared object. +.Pp +Arguments +.Ar +name ELF executables to be examined. +If no files are specified, the +.Nm +utility will examine the file +.Pa a.out +in the current directory. +.Pp +The +.Nm +utility recognizes the following options: +.Bl -tag -width indent +.It Fl H +Print a brief help message. +.It Fl V +Print a version identifier and exit. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +To list text relocations in an object, use: +.Bd -literal -offset indent +% findtextrel a.out +a.out: ELF object contains text relocation records: +a.out: off: 0x530, func: main, file: a.c, line: 5 +.Ed +.Sh DIAGNOSTICS +The +.Nm +may issue the following diagnostics: +.Bl -diag +.It "ELF object is not a DSO/PIE" +The ELF executable specified by argument +.Ar object +was not a position independent executable. +.It "ELF object does not contain a text relocation" +The ELF executable specified by argument +.Ar object +contained no text relocations. +.El +.Sh SEE ALSO +.Xr addr2line 1 , +.Xr nm 1 , +.Xr readelf 1 +.Sh HISTORY +A +.Nm +utility first appeared in the +.Nm elfutils +toolset from Red Hat, Inc. +.Sh AUTHORS +This implementation of the +.Nm +utility was created by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/findtextrel/findtextrel.c b/contrib/elftoolchain/findtextrel/findtextrel.c new file mode 100644 index 0000000000..29a7d08f51 --- /dev/null +++ b/contrib/elftoolchain/findtextrel/findtextrel.c @@ -0,0 +1,428 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: findtextrel.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +static struct option longopts[] = { + {"help", no_argument, NULL, 'H'}, + {"version", no_argument, NULL, 'V'}, + {NULL, 0, NULL, 0} +}; + +#define USAGE_MESSAGE "\ +Usage: %s [options] [files...]\n\ + Show text relocations present in position independent code.\n\n\ + Options:\n\ + -H Print a help message.\n\ + -V Print a version identifier and exit.\n" + +static void +usage(int exit_code) +{ + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +version(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(0); +} + +static const char * +find_symbol(const char *fn, Elf *e, Elf_Data *d, GElf_Shdr *sh, uintmax_t off) +{ + const char *name; + GElf_Sym sym; + int i, len; + + if (sh->sh_entsize == 0) { + warnx("invalid sh_entsize"); + return (NULL); + } + len = (int) (d->d_size / sh->sh_entsize); + for (i = 0; i < len; i++) { + if (gelf_getsym(d, i, &sym) != &sym) { + warnx("%s: gelf_getsym() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + if (GELF_ST_TYPE(sym.st_info) != STT_FUNC) + continue; + if (off >= sym.st_value && off < sym.st_value + sym.st_size) { + name = elf_strptr(e, sh->sh_link, sym.st_name); + if (name == NULL) + warnx("%s: elf_strptr() failed: %s", fn, + elf_errmsg(-1)); + return (name); + } + } + + return (NULL); +} + +static void +report_textrel(const char *fn, Elf *e, Dwarf_Debug dbg, uintmax_t off, + int *textrel) +{ + Dwarf_Die die; + Dwarf_Line *lbuf; + Dwarf_Error de; + Dwarf_Half tag; + Dwarf_Unsigned lopc, hipc, lineno, plineno; + Dwarf_Signed lcount; + Dwarf_Addr lineaddr, plineaddr; + Elf_Scn *scn; + Elf_Data *d; + GElf_Shdr sh; + const char *name; + char *file, *pfile; + int elferr, found, i, ret; + + if (!*textrel) { + printf("%s: ELF object contains text relocation records:\n", + fn); + *textrel = 1; + } + + printf("%s: off: %#jx", fn, off); + + found = 0; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("%s: gelf_getshdr() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + if (sh.sh_type != SHT_DYNSYM && + sh.sh_type != SHT_SYMTAB) + continue; + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("%s: elf_getdata() failed: %s", + fn, elf_errmsg(-1)); + continue; + } + if (d->d_size <= 0) + continue; + if ((name = find_symbol(fn, e, d, &sh, off)) != NULL) { + printf(", func: %s", name); + break; + } + } + elferr = elf_errno(); + if (elferr != 0) + warnx("%s: elf_nextscn() failed: %s", fn, + elf_errmsg(elferr)); + + if (dbg == NULL) + goto done; + + /* + * More verbose output if debugging information is available. + */ + + while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de)) == DW_DLV_OK) { + die = NULL; + while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) + goto out; + /* XXX: What about DW_TAG_partial_unit? */ + if (tag == DW_TAG_compile_unit) + break; + } + if (die == NULL) { + /* Could not find DW_TAG_compile_unit DIE. */ + goto out; + } + if (!dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) && + !dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) { + /* + * Check if the address falls into the PC range of + * this CU. + */ + if (off < lopc || off >= hipc) + continue; + } else + continue; + + if (dwarf_srclines(die, &lbuf, &lcount, &de) != DW_DLV_OK) + continue; + + found = 0; + plineaddr = ~0ULL; + plineno = 0; + pfile = NULL; + for (i = 0; i < lcount; i++) { + if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) + continue; + if (dwarf_lineno(lbuf[i], &lineno, &de)) + continue; + if (dwarf_linesrc(lbuf[i], &file, &de)) + continue; + if (off == lineaddr) { + found = 1; + goto out; + } else if (off < lineaddr && off > plineaddr) { + lineno = plineno; + file = pfile; + found = 1; + goto out; + } + plineaddr = lineaddr; + plineno = lineno; + pfile = file; + } + } + +out: + if (found) + printf(", file: %s, line: %ju", file, (uintmax_t) lineno); + + /* + * Reset internal CU pointer, so we will start from the first CU + * next round. + */ + while (ret != DW_DLV_NO_ENTRY) { + if (ret == DW_DLV_ERROR) + break; + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de); + } + +done: + putchar('\n'); +} + +static void +examine_reloc(const char *fn, Elf *e, Elf_Data *d, GElf_Shdr *sh, GElf_Phdr *ph, + int phnum, Dwarf_Debug dbg, int *textrel) +{ + GElf_Rela rela; + int i, j, len; + GElf_Rel rel; + + if (sh->sh_entsize == 0) { + warnx("invalid sh_entsize"); + return; + } + len = (int) (d->d_size / sh->sh_entsize); + for (i = 0; i < len; i++) { + if (sh->sh_type == SHT_REL) { + if (gelf_getrel(d, i, &rel) != &rel) { + warnx("%s: gelf_getrel() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + } else { + if (gelf_getrela(d, i, &rela) != &rela) { + warnx("%s: gelf_getrela() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + } + for (j = 0; j < phnum; j++) { + if (sh->sh_type == SHT_REL) { + if (rel.r_offset >= ph[j].p_offset && + rel.r_offset < ph[j].p_offset + + ph[j].p_filesz) + report_textrel(fn, e, dbg, + (uintmax_t) rel.r_offset, textrel); + } else { + if (rela.r_offset >= ph[j].p_offset && + rela.r_offset < ph[j].p_offset + + ph[j].p_filesz) + report_textrel(fn, e, dbg, + (uintmax_t) rela.r_offset, textrel); + } + } + } +} + +static void +find_textrel(const char *fn) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Ehdr eh; + GElf_Phdr *ph; + GElf_Shdr sh; + Dwarf_Debug dbg; + Dwarf_Error de; + int elferr, fd, i, phnum, textrel; + + e = NULL; + ph = NULL; + dbg = NULL; + + if ((fd = open(fn, O_RDONLY)) < 0) { + warn("%s", fn); + return; + } + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warnx("%s: elf_begin() failed: %s", fn, elf_errmsg(-1)); + goto exit; + } + + if (gelf_getehdr(e, &eh) != &eh) { + warnx("%s: gelf_getehdr() failed: %s", fn, elf_errmsg(-1)); + goto exit; + } + + if (eh.e_type != ET_DYN) { + printf("%s: ELF object is not a DSO/PIE\n", fn); + goto exit; + } + + /* + * Search program header for executable segments. + */ + + if (eh.e_phnum == 0) { + printf("%s: ELF object does not contain program headers\n", + fn); + goto exit; + } + if ((ph = calloc(eh.e_phnum, sizeof(GElf_Phdr))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + phnum = 0; + for (i = 0; (unsigned) i < eh.e_phnum; i++) { + if (gelf_getphdr(e, i, &ph[phnum]) != &ph[phnum]) { + warnx("%s: gelf_getphdr() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + if (ph[phnum].p_flags & PF_X) + phnum++; + } + if (phnum == 0) { + printf("%s: ELF object does not contain any executable " + "segment\n", fn); + goto exit; + } + + /* Check if debugging information is available. */ + if (dwarf_elf_init(e, DW_DLC_READ, NULL, NULL, &dbg, &de)) + dbg = NULL; + + /* + * Search relocation records for possible text relocations. + */ + textrel = 0; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("%s: gelf_getshdr() failed: %s", fn, + elf_errmsg(-1)); + continue; + } + if (sh.sh_type == SHT_REL || sh.sh_type == SHT_RELA) { + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("%s: elf_getdata() failed: %s", + fn, elf_errmsg(-1)); + continue; + } + if (d->d_size <= 0) + continue; + examine_reloc(fn, e, d, &sh, ph, phnum, dbg, &textrel); + } + } + elferr = elf_errno(); + if (elferr != 0) + warnx("%s: elf_nextscn() failed: %s", fn, elf_errmsg(elferr)); + + if (!textrel) + printf("%s: ELF object does not contain a text relocation\n", + fn); + +exit: + if (dbg) + dwarf_finish(dbg, &de); + if (ph) + free(ph); + if (e) + (void) elf_end(e); + close(fd); +} + +int +main(int argc, char **argv) +{ + int i, opt; + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "elf_version(): %s", elf_errmsg(-1)); + + while ((opt = getopt_long(argc, argv, "HV", longopts, NULL)) != -1) { + switch (opt) { + case 'H': + usage(EX_OK); + break; + case 'V': + version(); + break; + default: + usage(EX_USAGE); + break; + } + } + + argv += optind; + argc -= optind; + + if (argc > 0) + for (i = 0; i < argc; i++) + find_textrel(argv[i]); + else + find_textrel("a.out"); + + exit(0); +} diff --git a/contrib/elftoolchain/isa/Makefile b/contrib/elftoolchain/isa/Makefile new file mode 100644 index 0000000000..796f43b22e --- /dev/null +++ b/contrib/elftoolchain/isa/Makefile @@ -0,0 +1,20 @@ +# $Id: Makefile 2903 2013-01-16 12:35:50Z jkoshy $ + +TOP= .. + +PROG= isa +SRCS= isa.c +LSRC= +YSRC= +LDADD= -lelftc + +ISA= avr.isa + +MAN= isa.1 isa.5 + +check-specifications: .PHONY +.for f in ${ISA} + ${.OBJDIR}/${PROG} -n --query ${f} +.endfor + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/isa/avr.isa b/contrib/elftoolchain/isa/avr.isa new file mode 100644 index 0000000000..a6b7381795 --- /dev/null +++ b/contrib/elftoolchain/isa/avr.isa @@ -0,0 +1,280 @@ +; +; $Id: avr.isa 2899 2013-01-16 05:17:02Z jkoshy $ +; +; An instruction set description for Atmel AVR(TM) 8 bit CPUs. +; +; * Most instructions are 16 bit wide, except a few that use an +; additional 16-bit offset field. +; * There are 32 general purpose registers which are 8-bit wide. +; Three pairs of registers are used for 16bit memory addressing: +; X (r27:r26), Y (r29:r28), and Z (r31:r30). +; * Some instructions operate on limited subsets of these registers: +; - The 'movw' instruction operates on register pairs. +; - Some instructions only operate on subsets of the register file. + +arch avr +cpus + core = [ AT90S1200 ATtiny11 ATtiny12 ATtiny15 ATtiny28 ] + core8k = core ++ [ AT90S2313 AT90S2323 ATtiny22 AT90S2333 + AT90S2343 AT90S4414 AT90S4433 AT90S4434 AT90S8515 + AT90C8534 AT90S8535 ATtiny26 ATmega8515 ] + core128k = core8k ++ [ ATmega103 ATmega603 AT43USB320 AT76C711 ] + enhancedcore = core ++ [ ATmega8 ATmega83 ATmega85 ] + ; TODO fill in the rest. + +; The instruction stream has two types of tokens: +token i(16) ; a 16 bit instruction. + offset(16) ; a 16 bit offset + +; The 32 source registers are encoded using a combination of a 4-bit +; and a 1-bit field. +let Rsrclow = i[3:0] + Rsrchighbit = i[9] + Rsrc = Rsrchighbit & Rsrclow + where Rsrc[4] = Rsrchighbit + Rsrc[3:0] = Rsrclow + names [ R%n | n = 0..31 ] + Rsrcpair = i[3:0] ; Source register pairs. + names [ R%n | n = 0..31, n % 2 == 0 ] + + Rdst = i[8:4] ; The 32 dst registers use 5 contiguous bits. + names [ R%n | n = 0..31 ] + Rdstpair = i[7:4] ; destination register pairs + names [ R%n | n = 0..31, n %2 == 0 ] + + ; Some instructions work on the 16 higher numbered registers. + Rsrchigh = i[7:4] + names [ R%n | n = 16..31 ] + Rdsthigh = i[7:4] + names [ R%n | n = 16..31 ] + + ; Registers used for the MUL instructions (R16-23). + Rmulsrc = i[2:0] + names [ R%n | n = 16..23 ] + Rmuldst = i[6:4] + names [ R%n | n = 16..23 ] + +; 8 bit immediate value. +let Khigh = i[11:8] + Klow = i[ 3:0] + K = Khigh & Klow + where K[8:4] = Khigh + K[3:0] = Klow + +; call or jmp to an absolute location +let jmpcallbit = i[1] + Jmpcall loc = i[15:9] = 0b1001010 & i[3:2] = 0b11 & + i[8:4] = loc[21:17] & i[0] = loc[16] + <+> ; next location + offset[15:0] = loc[15:0] + in + call %loc <=> Jmpcall loc & jmpcallbit = 1 + jmp %loc <=> Jmpcall loc & jmpcallbit = 0 + +; Immediate operations on the high registers. +let immediateops@[ sbci subi sbr cbr ] = [ i[13:12] = n | n = 0..3 ] + with i[15:14] = 0b01 + @immediateops %Rdsthigh, %K <=> &* + +; The CPI (Compare Immediate) instruction has a different encoding. +cpi %Rdsthigh, %K <=> i[15:12] = 0b0011 &* + +; Move register pair. +movw %Rdstpair, %Rsrcpair <=> i[15:8] = 0b00000001 &* + +; 8x8 -> 16 bit signed multiply. +muls %Rdsthigh, %Rsrchigh <=> i[15:8] = 0b00000010 &* + +; Unsigned multiply. +mul %Rdst, %Rsrc <=> i[15:10] = 0b100111 &* + +; Fractional multiply instructions. +with i[15:8] = 0b00000011 + fmulsu %Rmuldst, %Rmulsrc <=> i[7,3] = [1,1] &* + fmuls %Rmuldst, %Rmulsrc <=> i[7,3] = [1,0] &* + fmul %Rmuldst, %Rmulsrc <=> i[7,3] = [0,1] &* + mulsu %Rmuldst, %Rmulsrc <=> i[7,3] = [0,0] &* + +; 2-operand instructions operating on all 32 registers. +let OpTwo@[ cpc sbc add cpse cp sub adc and eor or mov ] in + cpc = i[15:10] = 0b000001 + with i[15:12] = 0b0010 + [ and eor or mov ] = [ i[11:10] = n | n = 0..3 ] + with i[15:12] = 0b0001 + [ cpse cp sub adc ] = [ i[11:10] = n | n = 0..3 ] + with i[15:11] = 0b00001 + [ sbc add ] = [ i[10] = n | n = 0..1 ] + in + @OpTwo %Rdst, %Rsrc <=> &* + +let OpOne = [ com neg swap inc asr lsr ror ] + with i[15:9] = 0b1001010 & i[3] = 0 + [ com neg swap inc _ asr lsr ror ] = [ i[2:0] = n | n = 0..7 ] + in + @OpOne %Rdst <=> &* + +let bitno = i[2:0] + +let clear = i[7] in + with i[15:8] = 0b10010100 & i[3:0] = 0b1000 + bclr %bitno <=> clear = 1 &* + bset %bitno <=> clear = 0 &* + +; Additional aliases. +let statusbit = i[6:4] + names [ "C" "Z" "N" "V" "S" "H" "T" "I" ] + cl%statusbit <=> bclr & bitno = statusbit + se%statusbit <=> bset & bitno = statusbit + + +; NOP +nop <=> i[15:0] = 0 + +let loadstore = i[9] + +; Index load/store with offset +let lddlow = i[2:0] + lddmid = i[11:10] + lddhigh = i[13] + Lddoffset = lddlow & lddmid & lddhigh + where Lddoffset[5] = lddhigh + Lddoffset[4:3] = lddmid + Lddoffset[2:0] = lddlow + yz = i[3] ; Y/Z bit for LDD with offset + names [ "Z" "Y" ] + with i[15:14] = 0b10 & i[12] = 0b0 + ldd %Rdst, %yz "+" %Lddoffset <=> loadstore = 0 &* + std %Rdst, %yz "+" %Lddoffset <=> loadstore = 1 &* + +; Indexed load/store with increment & decrement +let xyz = i[3:2] ; X/Y/Z for LD ops + names [ "Z" _ "Y" "X" ] + auto = i[0:1] + with i[15:10] = 0b100100 ; prefix for indexed loads + ld %Rdst, %xyz <=> loadstore = 0 & auto = 0 &* + ld %Rdst, %xyz+ <=> loadstore = 0 & auto = 1 &* + ld %Rdst, -%xyz <=> loadstore = 0 & auto = 2 &* + st %xyz, %Rdst <=> loadstore = 1 & auto = 0 &* + st %xyz+, %Rdst <=> loadstore = 1 & auto = 1 &* + st -%xyz, %Rdst <=> loadstore = 1 & auto = 2 &* + +; The 'andi' instruction is 'cbi' with a negated constant. +andi %Rdsthigh, %Kcomp <=> cbr & Rdsthigh & K = ~Kcomp +; The 'ori' instruction is an alias for 'sbr'. +ori %Rdsthigh, %K <=> sbr &* + +; Single operand instructions implemented using two operand ones. +clr %Rdst <=> eor & Rsrc = Rdst & Rdst +lsl %Rdst <=> add & Rsrc = Rdst & Rdst +rol %Rdst <=> adc & Rsrc = Rdst & Rdst +tst %Rdst <=> and & Rsrc = Rdst & Rdst + +with i[15:9] = 0b1001010 & i[7:0] = 0b0001001 + ijmp <=> indircallbit = 0 & eibit = 0 + icall <=> indircallbit = 1 & eibit = 0 + eijmp <=> indircallbit = 0 & eibit = 1 + eicall <=> indircallbit = 1 & eibit = 1 + where indircallbit = i[7] + eibit = i[4] + +with i[15:8] = 0b10010101 & i[3:0] = 0b1000 + let splops = i[7:4] + miscops@[ ret reti sleep break wdr lpm elpm spm ] = + [ splops = [ 0 1 8 9 10 12 13 14 ] ] + in + @miscops <=> &* + +; Load program memory has two variants. +lpm <=> i[15:0] = 0b1001010111001000 ; load to R0 +lpm %Rdst,Z%zincr <=> i[15:9] = 0b1001000 & i[3:1] = 0b010 &* + where zincr = i[0] names [ "" "+" ] + +; Store program memory. +spm <=> i[15:0] = 0b1001010111101000 + +; Decrement register. +dec %Rdst <=> i[15:9] = 0b1001010 & i[3:0] = 0b1010 &* + +; DES round %des, operates on R0..R15 +let des = i[7:4] in + des %des <=> i[15:8] = 0b10010100 & i[3:0] = 0b1011 &* + +; Add/Sub register pairs with an immediate +let addsub = i[8] + Rdstimm = i[5:4] + names [ R24 R26 R28 R30 ] + Kimm6high = i[7:6] + Kimm6low = i[3:0] + Kimm6 = Kimm6high & Kimm6low + where Kimm6[5:4] = Kimm6high + Kimm6[3:0] = Kimm6low + with i[15:9] = 0b1001011 + adiw %Rdstimm, %Kimm6 <=> addsub = 0 &* + sbiw %Rdstimm, %Kimm6 <=> addsub = 1 &* + +; Operations on bits in I/O registers. +let bitops@[ cbi sbic sbi sbis ] = [ instr[9:8] = n | n = 0..3 ] + ioaddr = i[7:3] + with i[15:10] = 0b100110 + @bitops %ioaddr, %bit <=> &* + +; IN/OUT operations +let inout = i[11] + Alow = i[3:0] + Ahigh = i[10:9] + A = Ahigh & Alow + with i[15..12] = 0b1011 + in %Rdst, %A <=> inout = 0 & * + out %Rst, %A <=> inout = 1 & * + +; Relative jmp/call +let reljmpcall = i[12] + reloffset = i[11:0] + with i[15:13] = 0b110 + rjmp %label <=> reljmpcall = 0 & reloffset = (label - . - 1) + rcall %label <=> reljmpcall = 1 & reloffset = (label - . - 1) + +; Load Immediate +ldi %Rdsthigh, %K <=> i[15:12] = 0b1110 &* + +; Conditional branches +let clearedorset = i[10] + condoffset = i[9:3] + with i[15:11] = 0b11110 + brbs %bitno, %label <=> clearedorset = 0 & bitno & + condoffset = (label - . - 1) + brbc %bitno, %label <=> clearedorset = 1 & bitno & + condoffset = (label - . - 1) + +; Aliases +brcs %l => brbs & bitno = 0 & label = l +brlo %l => brbs & bitno = 0 & label = l +breq %l => brbs & bitno = 1 & label = l +brmi %l => brbs & bitno = 2 & label = l +brvs %l => brbs & bitno = 3 & label = l +brlt %l => brbs & bitno = 4 & label = l +brhs %l => brbs & bitno = 5 & label = l +brts %l => brbs & bitno = 6 & label = l +brie %l => brbs & bitno = 7 & label = l + +brcc %l => brbc & bitno = 0 & label = l +brsh %l => brbc & bitno = 0 & label = l +brne %l => brbc & bitno = 1 & label = l +brpl %l => brbc & bitno = 2 & label = l +brvc %l => brbc & bitno = 3 & label = l +brge %l => brbc & bitno = 4 & label = l +brhc %l => brbc & bitno = 5 & label = l +brtc %l => brbc & bitno = 6 & label = l +brid %l => brbc & bitno = 7 & label = l + +; BLD/BST +let bldst = i[9] + with i[15:10] = 0b111110 & i[3] = 0 + bld %Rdst, %bitno <=> bldst = 0 &* + bst %Rdst, %bitno <=> bldst = 1 &* + +; SBRC/SBRS +let setclr = i[9] + with i[15:10] = 0b111111 & i[3] = 0 + sbrc %Rdst, %bit <=> setclr = 0 &* + sbrc %Rdst, %bit <=> setclr = 1 &* diff --git a/contrib/elftoolchain/isa/isa.1 b/contrib/elftoolchain/isa/isa.1 new file mode 100644 index 0000000000..e515283fe2 --- /dev/null +++ b/contrib/elftoolchain/isa/isa.1 @@ -0,0 +1,247 @@ +.\" Copyright (c) 2012,2013 Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + \" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + \" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + \" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: isa.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd January 13, 2013 +.Dt ISA 1 +.Os +.Sh NAME +.Nm isa +.Nd instruction set analyser +.Sh SYNOPSIS +.Nm +.Op Fl a Ar architecture | Fl -arch Ns = Ns Ar architecture +.Op Fl c Ar cpu | Fl -cpu Ns = Ns Ar cpu +.Op Fl h | Fl -help +.Op Fl i Ar filename | Fl -input Ns = Ns Ar filename +.Op Fl n | Fl -dry-run +.Op Fl o Ar filename | Fl -output Ns = Ns Ar filename +.Op Fl p Ar string | Fl -prefix Ns = Ns Ar string +.Op Fl s Ar filename | Fl -spec Ns = Ns Ar filename +.Op Fl q | Fl -quiet +.Op Fl v | Fl -verbose +.Op Fl D | Fl -decode +.Op Fl E | Fl -encode +.Op Fl L | Fl -list-instructions +.Op Fl N Ar number | Fl -ntests Ns = Ns Ar number +.Op Fl Q | Fl -query +.Op Fl R Ar number | Fl -random-seed Ns = Ns Ar number +.Op Fl T | Fl -test +.Op Fl V | Fl -version +.Ar +.Sh DESCRIPTION +The +.Nm +utility is used to generate instruction stream encoders and decoders +from a textual description of a CPU instruction set. +.Pp +The +.Nm +utility supports three operational modes, as specified by the use of +the +.Fl D , +.Fl E +or +.Fl Q +options: +.Bl -tag -width indent +.It Cm Decode +.Pq Fl D | Fl -decode +In this mode, the +.Nm +utility transforms source code, expanding match pattern between the +tokens +.Dq Li "[ISA[" +and +.Dq Li "]ISA]" +into the appropriate code for matching instruction streams. +The section +.Sx "Matching Instructions" +describes the decode functionality in greater depth. +.It Cm Encode +.Pq Fl E | Fl -encode +In this mode, the +.Nm +utility generates C code to emit binary instruction streams. +.It Cm Query +.Pq Fl Q | Fl -query +In this mode, the +.Nm +utility is used to retrieve information from instruction set +specifications. +.El +.Pp +If no operational mode is specified, a default of +.Cm Query +will be used. +.Pp +Instruction set specifications may be specified using the +.Fa a +option, or by using the command line arguments +.Ar . +.Pp +The +.Nm +utility accepts the following options: +.Bl -tag -width indent +.It Fl a Ar architecture | Fl -arch Ns = N Ar architecture +Use instruction set specifications specified by the argument +.Ar architecture . +The +.Nm +utility will look for these specifications in the locations +specified by the environment variable +.Ev ISAPATH , +in addition to a built-in search location. +The default architecture is that for the host the +.Nm +utility is being executed on.s +.It Fl c Ar cpu | Fl -cpu Ns = Ns Ar cpu +Generate encoders and decoders for the specific instruction set +variant supported by CPU +.Ar cpu . +This option may be specified multiple times. +If the argument +.Ar cpu +starts with a minus, the CPU specified will be removed from list of +CPUs to be supported. +.It Fl h | Fl -help +Print a help message and exit. +.It Fl i Ar filename | Fl -input Ns = Ns Ar filename +When generating a decoder, read the source to be expanded from the +file named in the argument +.Ar filename . +If an input file is not specified, the +.Nm +utility will read from its standard input. +.It Fl n | Fl -dry-run +Exit without creating any output after checking inputs for errors. +.It Fl o Ar filename | Fl -output Ns = Ns Ar filename +When generating encoders and decoders, send the output to the file +specified by the argument +.Ar filename . +If an output file is not specified, the +.Nm +utility will write to its standard output. +.It Fl p Ar string | Fl -prefix Ns = Ns Ar string +When in encode mode, use the string in argument +.Ar string +as a prefix for generated symbols. +.It Fl q | Fl -quiet +Suppress warning messages. +.It Fl s Ar filename | Fl -spec Ns = Ns Ar filename +Read an instruction set specification from the file named by argument +.Ar filename . +This option may be specified multiple times, in which case the +.Nm +utilitiy behaves as if the specifications had been concatenated in the +sequence specified. +.It Fl v | Fl -verbose +Increase the verbosity level. +This option may be specified multiple times. +.It Fl D | Fl -decode +Transform sources expanding match patterns in source code to +lower-level instruction stream decoding code. +By default, the +.Nm +utility will read from standard input and write to standard output, +unless otherwise specified by the +.Fl i +and +.Fl o +options. +.It Fl E | Fl -encode +Build an instruction stream encoder. +.It Fl L | Fl -list-instructions +When in query mode, generate a list of all known instructions. +.It Fl N Ar number | Fl -ntests Ns = Ns Ar number +When in query mode, specify the number of test sequences to be +generated if the +.Fl -T | Fl -test +option was specified. +.It Fl Q | Fl -query +Retrieve information about an instruction set. +.It Fl R Ar number | Fl -random-seed Ns = Ns Ar number +Use the argument +.Ar number +as the seed for pseudorandom number generation. +If this option is not specified, the +.Nm +utility will initialize the pseudorandom number generator in an +implementation-defined manner. +.It Fl T | Fl -test +Generate instruction sequences for use in testing tools such as +assemblers. +.It Fl V | Fl -version +Print a version identifier and exit. +.El +.Sh ENVIRONMENT +The behavior of the +.Nm +utility is affected by the following environemnt variables: +.Bl -tag +.It Ev ISAPATH +Specifies a colon-separated set of directories tp be used when +searching for instruction specifications. +.El +.Sh FILES +.Bl -tag -width indent +.It Pa /usr/share/isa/ +The default location for instruction set specifications. +.El +.Sh EXAMPLES +To check the instruction specifications in file +.Pa spec.isa , +use: +.D1 isa -n "spec.isa" +.Pp +To expand instruction decoding templates in the file +.Pa a.m , +assuming a generic +.Tn AVR +CPU, and generating a C source file, use: +.D1 isa -a avr -D < a.m > a.c +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf 5 , +.Xr isa 5 +.Sh HISTORY +The +.Nm +utility is scheduled to appear in a future release from the +Elftoolchain project. +.\" TODO Reword the above when the target release is finalized. +.Sh AUTHORS +The +.Xr isa 1 +utility was written by +.An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net . +.Sh BUGS +The +.Nm +utility is wildly unstable at this point of time. +If you intend to use this utility, please get in touch with the +project's developers at +.Aq elftoolchain-developers@lists.sourceforge.net . diff --git a/contrib/elftoolchain/isa/isa.5 b/contrib/elftoolchain/isa/isa.5 new file mode 100644 index 0000000000..211d0e1f83 --- /dev/null +++ b/contrib/elftoolchain/isa/isa.5 @@ -0,0 +1,365 @@ +.\" Copyright (c) 2013 Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: isa.5 3195 2015-05-12 17:22:19Z emaste $ +.\" +.Dd January 16, 2013 +.Os +.Dt ISA 1 +.Sh NAME +.Nm isa +.Nd input file format for the isa utility +.Sh DESCRIPTION +The +.Nm +utility is used to generate instruction stream encoders and decoders +from a textual description of a machine instruction set. +This manual page documents the form of the textual description +accepted by the +.Nm +utility. +.Ss Basic Concepts +A machine instruction is composed of one +.Em tokens , +each kind of token having a defined width. +Simple RISC-like instruction sets have instructions that use 1 or 2 +tokens, typically an instruction word and an optional immediate field. +More complex CISC instruction sets may use many more kinds of tokens. +.Pp +Each token is made up of +.Em fields , +for example, an instruction token could be made up of an opcode field, +additional fields naming registers, fields containing flags, immediate +values and so on. +Fields may be named using the +.Cm let +directive, or can be unnamed. +The bitslice operator +.Pq Li \&[] +can be used to denote specific portions of a token. +.Pp +Non-overlapping fields are grouped together into +.Em fragments . +Fragments may be composed using the +.Dq "&" +operator. +The textual form of a fragment may be specified using +the +.Li names +directive. +.Pp +A set of fragments that fully specifies each bit in a token is +said to be +.Sq complete . +Only complete fragment sets can be emitted. +.Pp +.Ss Input Syntax +The semicolon +.Dq "\&;" +introduces a comment. +All text from the semicolon to the end of the line is ignored. +.Pp +The language uses indentation to specify scope (i.e., it uses the +offside rule), as in the +.Ic Python +and +.Ic Haskell +programming languages. +.Ss Operators +.Bl -tag +.It "Composing Fragments" +The +.Dq Li \&& +operator is used to join fragments, forming a larger fragment. +For example, to specify a fragment that is comprised of two +previously named fragments +.Ar Rtop +and +.Ar Rbottom , +use: +.Bd -literal -offset indent +Rtop & Rbottom +.Ed +.It "Generators" +A generator expression has the form +.Li [ Ar expr1 Ns Li \&| Ns Ar expr2 Ns \&... Ns Li ] +and denotes a sequence of values +.Va expr1 , +where the additional expressions +.Va expr2 +serve to define the range of values generated. +Any +.Dq Li \&% Ns +-escapes in +.Va expr1 +are expanded. +For example, +.Dl [ R%n | n = 0..31 ] +generates the sequence +.Li R0 , +.Li R1 , +\&... , +.Li R31 . +.It "Numeric Ranges" +The notation +.Dq \&.. +denotes a numeric range. +For example, +.Dl 0..(2^16-1) +represents the numbers 0 to 65535, inclusive. +.It Sequences +Sequences of items are bracketed by square brackets +.Dq "\&[" +and +.Dq "\&]" . +For example, +.Dl "let n = [ a b c d ]" +Sequences can be given a local name using the +.Va name +.Li @ +.Va sequence +syntax, for example: +.Dl bar@[ 1 2 3 ] +defines +.Va bar +as a local name for the expression [ 1 2 3 ]. +.Pp +The +.Dq Li \&++ +operator is used to concatenate sequences. +These sequences must be of the same type. +.It "Sequencing Tokens" +The +.Dq Li \&<+> +operator separates tokens in sequence. +For example, to specify an instruction that has two tokens T1 and T2 +in sequence, use: +.Bd -literal -offset indent +\&..the definition of T1.. +<+> +\&..the definition of T2.. +.Ed +.It Slices +Slices may be specified using the slice notation, namely +.Ar name Ns +.Li \&[ Ns +.Ar highbit Ns +.Li \&: Ns +.Ar lowbit Ns +.Li \&] , +where +.Ar highbit +and +.Ar lowbit +are inclusive zero-based indices and +.Ar name +is the name of a token. +.Bd -literal -offset indent +let Rsrc = instruction[3:0] +.Ed +.Pp +Sparse slices may be specified by separating slice expressions using +commas, for example bit 7 and 5 of the +.Va ifield +token may be specified using: +.Dl ifield[7,5] +.It "Specifying Assembly Formats" +The +.Dq Li \&<=> +infix operator is used to specify assembly language syntax and its +mapping to sequences of fragments defined earlier, see the section +.Sx "Defining Assembly Syntax" . +.Pp +The +.Dq Li \&&* +operator indicates that all the named fragments in the LHS (the +assembly syntax side) of the +.Dq Li \&<=> +operator should be treated as being present on the RHS. +This operator allows instructions that have a simple one-to-one +mapping between their assembly language definition and instruction +encoding to be described succinctly. +For example: +.Bd -literal -offset indent +muls %Rd, %Rs <=> i[15:8] = 0b00000010 &* +.Ed +.El +.Ss Language Constructs +The input language has the following constructs: +.Bl -tag -width indent +.It Li arch Ar string +Specifies the name of the instruction set architecture being +processed. +.Bd -literal -offset indent +arch myarch +.Ed +.It Li cpus +Starts a block naming CPU identifiers. +Specific instructions or groups of instructions may be flagged +as being supported on sets of the CPUs so declared. +.Bd -literal -offset indent +cpus + basic = [ CPU1 CPU2 ] + advanced = basic ++ [ CPU3 ] +.Ed +.It Li token Ar name "(" Ar width ")" +Defines a token with name +.Ar name +and width +.Ar width . +For example, to define a 16 bit named +.Ar i +(short for +.Dq instruction ) , +and a 8 bit offset token named +.Ar o , +use: +.Bd -literal -offset indent +token i(16) ; a comment here + o(8) +.Ed +.It Li let Ar name [ Ar params ] "=" Ar expression +Declare +.Ar name +as being the equivalent of +.Ar expression . +.It Li names Ar generator-expression +Defines the textual representation for a fragment. +For example, +.Bd -literal -offset indent -compact +let Rsrc = i[3:0] + names [ R%n | n = 0..7 ] +.Ed +specifies that a value of 0 for fragment +.Va Rsrc +should be shown as +.Li R0 , +and so on. +Conversely, when assembing text, the string +.Dq R15 +would be translated to a fragment value of 15. +.It Li where Ar name [ Ar params ] = Ar expression +Like the +.Li let +statement, a +.Li where +statement introduces local definitions, except that the scope of these +definitions is the statement preceding the +.Li where +keyword. +Example: +.Bd -literal -offset indent +let Kimm6 = Kimm6high & Kimm6low + where Kimm6[5:4] = Kimm6high + Kimm6[3:0] = Kimm6low +.Ed +.It Li with Ar fragment-definition +Defines fragment assignments that hold for statements in the scope of +the +.Li with +statement. +For example, +.Bd -literal -offset indent +with i[15:8] = 0b00000011 + fmulsu %Rd, %Rs <=> i[7,3] = [1,1] &* +.Ed +.El +.Ss Defining Assembly Syntax +Assembly syntax is described using the +.Li \&<=> +operator. +The form of the operator is +.Bd -ragged -offset indent +assembler-text +.Li \&<=> +.Va fragment +.Li \&& +.Va fragment +.Li & \&... +.Ed +.Pp +The RHS of the +.Li \&<=> +operator must specify a +.Sq complete +fragment set, i.e., no bits should be unspecified in any of the tokens +used in the RHS. +The LHS of the +.Li \&<=> +operator consists of literal text interspersed by fragment names. +Fragment names are prefixed by the +.Sq \&% +character. +These fragment names in the LHS may refer to fragment names defined +earlier, or may be new names that are local to the current definition. +.Pp +For example, the following definition defines an instruction with +mnemonic +.Dq Li rjmp . +.Bd -literal -offset indent +let reloffset = i[11:0] + reljmpcall = i[12] +in + with i[15:13] = 0b110 + rjmp %label <=> reljmpcall = 0 & reloffset = (label - . - 1) +.Ed +.Pp +In this definition, the field +.Va label +is a local fragment, one that is used to compute the value of the +.Va reloffset +field in the instruction. +In the RHS, the +.Va reljmpcall +bit is defined as being 0. +The rest of the bits in the token +.Va i +are specified by the enclosing +.Li with +statement. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf 5 , +.Xr isa 1 +.Sh HISTORY +The +.Nm +utility is scheduled to appear in a future release from the +Elftoolchain project. +.\" TODO Reword the above when the target release is finalized. +.Sh AUTHORS +The +.Xr isa 1 +utility was written by +.An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net . +.Sh BUGS +The +.Nm +utility is +.Ud +The input format documented in this manual is likely to change +in the future. +If you intend to use this utility, please get in touch with the +project's developers at +.Aq elftoolchain-developers@lists.sourceforge.net . diff --git a/contrib/elftoolchain/isa/isa.c b/contrib/elftoolchain/isa/isa.c new file mode 100644 index 0000000000..87c5a579d1 --- /dev/null +++ b/contrib/elftoolchain/isa/isa.c @@ -0,0 +1,286 @@ +/*- + * Copyright (c) 2012,2013 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: isa.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +/* + * Option handling. + */ + +enum isa_mode { + ISA_MODE_DECODE, + ISA_MODE_ENCODE, + ISA_MODE_QUERY +}; + +enum isa_submode { + ISA_SUBMODE_GENERATE_TESTS, + ISA_SUBMODE_LIST_INSTRUCTIONS +}; + +#define ISA_OPT_DRY_RUN 0x0001 +#define ISA_OPT_NO_WARNINGS 0x0002 +#define ISA_OPT_VERBOSE 0x0004 + +/* Record a option. */ +struct isa_option { + const char *isa_option; + SLIST_ENTRY(isa_option) isa_next; +}; + +struct isa_config { + unsigned int isa_flags; + enum isa_mode isa_mode; + enum isa_submode isa_submode; + int isa_ntests; + int isa_seed; + const char *isa_arch; + const char *isa_input; + const char *isa_output; + const char *isa_prefix; + SLIST_HEAD(,isa_option) isa_cpus; + SLIST_HEAD(,isa_option) isa_specs; +}; + +#define ISA_MAX_LONG_OPTION_LENGTH 64 + +static struct option isa_long_options[] = { + { "arch", required_argument, NULL, 'a' }, + { "cpu", required_argument, NULL, 'c' }, + { "decode", no_argument, NULL, 'D' }, + { "dry-run", no_argument, NULL, 'n' }, + { "encode", no_argument, NULL, 'E' }, + { "help", no_argument, NULL, 'h' }, + { "input", required_argument, NULL, 'i' }, + { "list-instructions", no_argument, NULL, 'L' }, + { "ntests", required_argument, NULL, 'N' }, + { "output", required_argument, NULL, 'o' }, + { "prefix", required_argument, NULL, 'p' }, + { "query", no_argument, NULL, 'Q' }, + { "quiet", no_argument, NULL, 'q' }, + { "random-seed", required_argument, NULL, 'R' }, + { "spec", required_argument, NULL, 's' }, + { "test", no_argument, NULL, 'T' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +static const char *isa_usage_message = "\ +usage: %s [options] [command] [specfiles]...\n\ + Process an instruction set specification.\n\ +\n\ +Supported values for 'command' are:\n\ + decode Build an instruction stream decoder.\n\ + encode Build an instruction stream encoder.\n\ + query (default) Retrieve information about an instruction set.\n\ +\n\ +Supported global options are:\n\ + -a ARCH | --arch ARCH Process instruction specifications for ARCH.\n\ + -c CPU | --cpu CPU Process instruction specifications for CPU.\n\ + -n | --dry-run Exit after checking inputs for errors.\n\ + -s FILE | --spec FILE Read instruction specifications from FILE.\n\ + -q | --quiet Suppress warning messages.\n\ + -v | --verbose Be verbose.\n\ + -V | --version Display a version identifier and exit.\n\ +\n\ +Supported options for command 'decode' are:\n\ + -i FILE | --input FILE Read source to be expanded from FILE.\n\ + -o FILE | --output FILE Write generated output to FILE.\n\ +\n\ +Supported options for command 'encode' are:\n\ + -o FILE | --output FILE Write generated output to FILE.\n\ + -p STR | --prefix STR Use STR as a prefix for generated symbols.\n\ +\n\ +Supported options for command 'query' are:\n\ + -L | --list-instructions Generate a list of all known instructions.\n\ + -N NUM | --ntests NUM Specify the number of test sequences generated.\n\ + -R N | --random-seed N Use N as the random number generator seed.\n\ + -T | --test Generate test sequences.\n\ +"; + +void +isa_usage(int exit_code, const char *message, ...) +{ + FILE *channel; + va_list ap; + + channel = exit_code != EX_OK ? stderr : stdout; + + if (message) { + va_start(ap, message); + (void) vfprintf(channel, message, ap); + va_end(ap); + } + + (void) fprintf(channel, isa_usage_message, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +void +isa_unimplemented(int option, int option_index, struct option *options_table) +{ + char msgbuf[ISA_MAX_LONG_OPTION_LENGTH]; + + if (option_index >= 0) + (void) snprintf(msgbuf, sizeof(msgbuf), "\"--%s\"", + options_table[option_index].name); + else + (void) snprintf(msgbuf, sizeof(msgbuf), "'-%c'", + option); + errx(1, "ERROR: option %s is unimplemented.", msgbuf); +} + +struct isa_option * +isa_make_option(const char *arg) +{ + struct isa_option *isa_opt; + + if ((isa_opt = malloc(sizeof(*isa_opt))) == NULL) + return (NULL); + isa_opt->isa_option = optarg; + + return (isa_opt); +} + +int +main(int argc, char **argv) +{ + int option, option_index; + struct isa_option *isa_opt; + struct isa_config config; + + (void) memset(&config, 0, sizeof(config)); + config.isa_mode = ISA_MODE_QUERY; + config.isa_arch = config.isa_input = config.isa_output = + config.isa_prefix = NULL; + SLIST_INIT(&config.isa_cpus); + SLIST_INIT(&config.isa_specs); + + for (option_index = -1; + (option = getopt_long(argc, argv, "a:c:hi:no:p:qs:vDELN:QR:TV", + isa_long_options, &option_index)) != -1; + option_index = -1) { + switch (option) { + case 'h': + isa_usage(EX_OK, NULL); + break; + case 'V': + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), + elftc_version()); + exit(0); + break; + + case 'a': + config.isa_arch = optarg; + break; + case 'c': + if ((isa_opt = isa_make_option(optarg)) == NULL) + goto error; + SLIST_INSERT_HEAD(&config.isa_cpus, isa_opt, isa_next); + break; + case 'i': + config.isa_input = optarg; + break; + case 'n': + config.isa_flags |= ISA_OPT_DRY_RUN; + break; + case 'o': + config.isa_output = optarg; + break; + case 'p': + config.isa_prefix = optarg; + break; + case 'q': + config.isa_flags |= ISA_OPT_NO_WARNINGS; + break; + case 's': + if ((isa_opt = isa_make_option(optarg)) == NULL) + goto error; + SLIST_INSERT_HEAD(&config.isa_specs, isa_opt, + isa_next); + break; + case 'v': + config.isa_flags |= ISA_OPT_VERBOSE; + break; + case 'D': + config.isa_mode = ISA_MODE_DECODE; + break; + case 'E': + config.isa_mode = ISA_MODE_ENCODE; + break; + case 'L': + config.isa_submode = ISA_SUBMODE_LIST_INSTRUCTIONS; + break; + case 'N': + config.isa_ntests = atoi(optarg); + break; + case 'Q': + config.isa_mode = ISA_MODE_QUERY; + break; + case 'R': + config.isa_seed = atoi(optarg); + break; + case 'T': + config.isa_submode = ISA_SUBMODE_GENERATE_TESTS; + break; + default: + isa_usage(EX_USAGE, "\n"); + break; + } + } + + /* + * Create the canonical list of specification files to + * be processed. + */ + for (;optind < argc; optind++) { + if ((isa_opt = isa_make_option(argv[optind])) == NULL) + goto error; + SLIST_INSERT_HEAD(&config.isa_specs, isa_opt, + isa_next); + } + + exit(0); + +error: + err(1, "ERROR: Invocation failed"); +} + diff --git a/contrib/elftoolchain/ld/Makefile b/contrib/elftoolchain/ld/Makefile new file mode 100644 index 0000000000..caef75c92d --- /dev/null +++ b/contrib/elftoolchain/ld/Makefile @@ -0,0 +1,52 @@ +# $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $ + +TOP= .. + +PROG= ld +WARNS?= 5 + +SRCS= amd64.c \ + amd64_script.c \ + i386.c \ + i386_script.c \ + ld_arch.c \ + ld_dynamic.c \ + ld_ehframe.c \ + ld_error.c \ + ld_exp.c \ + ld_file.c \ + ld_hash.c \ + ld_input.c \ + ld_layout.c \ + ld_main.c \ + ld_options.c \ + ld_output.c \ + ld_path.c \ + ld_reloc.c \ + ld_script.c \ + ld_strtab.c \ + ld_symbols.c \ + ld_symver.c \ + mips.c \ + littlemips_script.c \ + bigmips_script.c + +LSRC= ld_script_lexer.l +YSRC= ld_script_parser.y + +GENSRCS= amd64_script.c i386_script.c littlemips_script.c \ + bigmips_script.c + +CLEANFILES+= ${GENSRCS} + +DPADD= ${LIBELFTC} ${LIBELF} ${LIBDWARF} +LDADD= -lelftc -ldwarf -lelf + +CFLAGS+= -I. -I${.CURDIR} +YFLAGS= -d + +.SUFFIXES: .ld .c +.ld.c: + awk -f ${.CURDIR}/ld_script.awk ${.ALLSRC} > ${.TARGET} + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/ld/amd64.c b/contrib/elftoolchain/ld/amd64.c new file mode 100644 index 0000000000..324aa6c804 --- /dev/null +++ b/contrib/elftoolchain/ld/amd64.c @@ -0,0 +1,1327 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_input.h" +#include "ld_layout.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_symbols.h" +#include "ld_utils.h" +#include "amd64.h" + +ELFTC_VCSID("$Id: amd64.c 3419 2016-02-19 20:07:15Z emaste $"); + +static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, + uint64_t offset); +static void _create_got_reloc(struct ld *ld, struct ld_symbol *lsb, + uint64_t type, uint64_t offset); +static void _create_copy_reloc(struct ld *ld, struct ld_symbol *lsb); +static void _create_dynamic_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_symbol *lsb, uint64_t type, uint64_t offset, int64_t addend); +static void _scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre); +static struct ld_input_section *_find_and_create_got_section(struct ld *ld, + int create); +static struct ld_input_section *_find_and_create_gotplt_section(struct ld *ld, + int create); +static struct ld_input_section *_find_and_create_plt_section(struct ld *ld, + int create); +static void _finalize_got_and_plt(struct ld *ld); +static uint64_t _get_max_page_size(struct ld *ld); +static uint64_t _get_common_page_size(struct ld *ld); +static void _adjust_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf); +static void _process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf); +static void _reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num); +static void _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb); +static void _reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb); +static int _is_absolute_reloc(uint64_t r); +static void _warn_pic(struct ld *ld, struct ld_reloc_entry *lre); +static void _create_tls_gd_reloc(struct ld *ld, struct ld_symbol *lsb); +static void _create_tls_ld_reloc(struct ld *ld, struct ld_symbol *lsb); +static void _create_tls_ie_reloc(struct ld *ld, struct ld_symbol *lsb); +static enum ld_tls_relax _tls_check_relax(struct ld *ld, + struct ld_reloc_entry *lre); +static uint64_t _got_offset(struct ld *ld, struct ld_symbol *lsb); +static int _tls_verify_gd(uint8_t *buf, uint64_t off); +static int _tls_verify_ld(uint8_t *buf, uint64_t off); +static void _tls_relax_gd_to_ie(struct ld *ld, struct ld_state *ls, + struct ld_output *lo,struct ld_reloc_entry *lre, uint64_t p, uint64_t g, + uint8_t *buf); +static void _tls_relax_gd_to_le(struct ld *ld, struct ld_state *ls, + struct ld_output *lo, struct ld_reloc_entry *lre, struct ld_symbol *lsb, + uint8_t *buf); +static void _tls_relax_ld_to_le(struct ld *ld, struct ld_state *ls, + struct ld_reloc_entry *lre, uint8_t *buf); +static void _tls_relax_ie_to_le(struct ld *ld, struct ld_output *lo, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf); +static int32_t _tls_dtpoff(struct ld_output *lo, struct ld_symbol *lsb); +static int32_t _tls_tpoff(struct ld_output *lo, struct ld_symbol *lsb); + +static uint64_t +_get_max_page_size(struct ld *ld) +{ + + (void) ld; + return (0x200000); +} + +static uint64_t +_get_common_page_size(struct ld *ld) +{ + + (void) ld; + return (0x1000); +} + +static int +_is_absolute_reloc(uint64_t r) +{ + + if (r == R_X86_64_64 || r == R_X86_64_32 || r == R_X86_64_32S || + r == R_X86_64_16 || r == R_X86_64_8) + return (1); + + return (0); +} + +static int +_is_relative_reloc(uint64_t r) +{ + + if (r == R_X86_64_RELATIVE) + return (1); + + return (0); +} + +static void +_warn_pic(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = lre->lre_sym; + + if (lsb->lsb_bind != STB_LOCAL) + ld_warn(ld, "relocation %s against `%s' can not be used" + " by runtime linker; recompile with -fPIC", + elftc_reloc_type_str(EM_X86_64, + lre->lre_type), lsb->lsb_name); + else + ld_warn(ld, "relocation %s can not be used by runtime linker;" + " recompile with -fPIC", elftc_reloc_type_str(EM_X86_64, + lre->lre_type)); +} + +static struct ld_input_section * +_find_and_create_got_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the GOT section is already created. */ + is = ld_input_find_internal_section(ld, ".got"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".got"); + is->is_entsize = 8; + is->is_align = 8; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_WRITE; + } + + return (is); +} + +static struct ld_input_section * +_find_and_create_gotplt_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the GOT (for PLT) section is already created. */ + is = ld_input_find_internal_section(ld, ".got.plt"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".got.plt"); + is->is_entsize = 8; + is->is_align = 8; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_WRITE; + + /* Reserve space for the initial entries. */ + (void) ld_input_reserve_ibuf(is, 3); + + /* Create _GLOBAL_OFFSET_TABLE_ symbol. */ + ld_symbols_add_internal(ld, "_GLOBAL_OFFSET_TABLE_", 0, 0, + is->is_index, STB_LOCAL, STT_OBJECT, STV_HIDDEN, is, NULL); + } + + return (is); +} + +static struct ld_input_section * +_find_and_create_plt_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the PLT section is already created. */ + is = ld_input_find_internal_section(ld, ".plt"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".plt"); + is->is_entsize = 16; + is->is_align = 4; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_EXECINSTR; + + /* Reserve space for the initial entry. */ + (void) ld_input_reserve_ibuf(is, 1); + } + + return (is); +} + +static void +_reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num) +{ + struct ld_input_section *is; + + is = _find_and_create_got_section(ld, 1); + + /* Check if the entry already has a GOT entry. */ + if (lsb->lsb_got) + return; + + /* Reserve GOT entries. */ + lsb->lsb_got_off = ld_input_reserve_ibuf(is, num); + lsb->lsb_got = 1; +} + +static void +_reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *is; + + is = _find_and_create_gotplt_section(ld, 1); + + /* Reserve a GOT entry for PLT. */ + (void) ld_input_reserve_ibuf(is, 1); + + /* + * Record a R_X86_64_JUMP_SLOT entry for this symbol. Note that + * we don't need to record the offset (relative to the GOT section) + * here, since the PLT relocations will be sorted later and we + * will generate GOT section according to the new order. + */ + _create_plt_reloc(ld, lsb, 0); +} + +static void +_reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *is; + + is = _find_and_create_plt_section(ld, 1); + + (void) ld_input_reserve_ibuf(is, 1); + lsb->lsb_plt = 1; +} + +static void +_create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset) +{ + + ld_reloc_create_entry(ld, ".rela.plt", NULL, R_X86_64_JUMP_SLOT, + lsb, offset, 0); + + lsb->lsb_dynrel = 1; +} + +static void +_create_got_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t type, + uint64_t offset) +{ + struct ld_input_section *tis; + + tis = _find_and_create_got_section(ld, 0); + assert(tis != NULL); + + ld_reloc_create_entry(ld, ".rela.got", tis, type, lsb, offset, 0); + + if (type != R_X86_64_RELATIVE) + lsb->lsb_dynrel = 1; +} + +static void +_create_copy_reloc(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *tis; + + ld_dynamic_reserve_dynbss_entry(ld, lsb); + + tis = ld_input_find_internal_section(ld, ".dynbss"); + assert(tis != NULL); + + ld_reloc_create_entry(ld, ".rela.bss", tis, R_X86_64_COPY, lsb, + lsb->lsb_value, 0); + + lsb->lsb_dynrel = 1; +} + +static void +_create_dynamic_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_symbol *lsb, uint64_t type, uint64_t offset, int64_t addend) +{ + + if (lsb->lsb_bind == STB_LOCAL) { + if (is->is_flags & SHF_WRITE) + ld_reloc_create_entry(ld, ".rela.data.rel.local", + is, type, lsb, offset, addend); + else + ld_reloc_create_entry(ld, ".rela.data.rel.ro.local", + is, type, lsb, offset, addend); + } else { + if (is->is_flags & SHF_WRITE) + ld_reloc_create_entry(ld, ".rela.data.rel", + is, type, lsb, offset, addend); + else + ld_reloc_create_entry(ld, ".rela.data.rel.ro", + is, type, lsb, offset, addend); + } + + if (type != R_X86_64_RELATIVE) + lsb->lsb_dynrel = 1; +} + +static void +_finalize_reloc(struct ld *ld, struct ld_input_section *tis, + struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + (void) ld; + (void) tis; + + lsb = ld_symbols_ref(lre->lre_sym); + + switch (lre->lre_type) { + case R_X86_64_RELATIVE: + /* + * Update the addend stored in the original relocation to + * point to the new location, by adding the updated symbol + * value. + */ + lre->lre_addend += lsb->lsb_value; + + /* R_X86_64_RELATIVE should not associate with a symbol. */ + lre->lre_sym = NULL; + break; + + case R_X86_64_DTPMOD64: + /* + * Relocation R_X86_64_DTPMOD64 generated for local dynamic + * TLS model should not assoicate with a symbol. + */ + if (lre->lre_type == R_X86_64_DTPMOD64 && + lsb->lsb_tls_ld) + lre->lre_sym = NULL; + break; + + default: + break; + } +} + +static void +_finalize_got_and_plt(struct ld *ld) +{ + struct ld_output *lo; + struct ld_input_section *got_is, *rela_got_is, *plt_is, *rela_plt_is; + struct ld_output_section *got_os, *plt_os, *rela_plt_os; + struct ld_reloc_entry *lre; + struct ld_symbol *lsb; + char dynamic_symbol[] = "_DYNAMIC"; + uint8_t *got, *plt; + uint64_t u64; + int32_t s32, pltgot, gotpcrel; + int i, j; + + lo = ld->ld_output; + assert(lo != NULL); + + /* + * Intiailze all .got section entries to zero. + */ + got_is = _find_and_create_got_section(ld, 0); + if (got_is != NULL) + memset(got_is->is_ibuf, 0, got_is->is_size); + + /* + * Search for GOT relocations that requires filling in symbol + * value. + */ + rela_got_is = ld_input_find_internal_section(ld, ".rela.got"); + if (rela_got_is != NULL && rela_got_is->is_reloc != NULL) { + STAILQ_FOREACH(lre, rela_got_is->is_reloc, lre_next) { + if (lre->lre_type == R_X86_64_RELATIVE) { + lsb = lre->lre_sym; + got = (uint8_t *) got_is->is_ibuf + + lsb->lsb_got_off; + WRITE_64(got, lsb->lsb_value); + } + } + } + + /* + * Find the .plt section. The buffers should have been allocated + * at this point. + */ + plt_is = _find_and_create_plt_section(ld, 0); + if (plt_is == NULL) + return; + plt_os = plt_is->is_output; + plt = plt_is->is_ibuf; + assert(plt != NULL); + + /* + * Find the .got.plt and .rela.plt section. If the .plt section + * exists, the .got.plt and .rela.plt section should exist too. + */ + got_is = _find_and_create_gotplt_section(ld, 0); + assert(got_is != NULL); + got_os = got_is->is_output; + lo->lo_gotplt = got_os; + got = got_is->is_ibuf; + assert(got != NULL); + rela_plt_is = ld_input_find_internal_section(ld, ".rela.plt"); + assert(rela_plt_is != NULL); + rela_plt_os = rela_plt_is->is_output; + lo->lo_rel_plt = rela_plt_os; + + /* Point sh_info field of the .rela.plt to .plt section. */ + rela_plt_os->os_info = plt_os; + + /* Fill in the value of symbol _DYNAMIC in the first GOT entry. */ + ld_symbols_get_value(ld, dynamic_symbol, &u64); + WRITE_64(got, u64); + got += 8; + + /* Reserve the second and the third entry for the dynamic linker. */ + memset(got, 0, 16); + got += 16; + + /* + * Write the initial PLT entry. + */ + + /* Calculate the relative offset from PLT to GOT. */ + pltgot = got_os->os_addr - plt_os->os_addr; + + /* + * Push the second GOT entry to the stack for the dynamic + * linker. (PUSH reg/memXX [RIP+disp32]) (6 bytes for push) + */ + WRITE_8(plt, 0xff); + WRITE_8(plt + 1, 0x35); + s32 = pltgot - 6 + 8; + WRITE_32(plt + 2, s32); + plt += 6; + + /* + * Jump to the address in the third GOT entry (call into + * the dynamic linker). (JMP reg/memXX [RIP+disp32]) + * (6 bytes for jmp) + */ + WRITE_8(plt, 0xff); + WRITE_8(plt + 1, 0x25); + s32 = pltgot - 12 + 16; + WRITE_32(plt + 2, s32); + plt += 6; + + /* Padding: 4-byte nop. (NOP [rAx+disp8]) */ + WRITE_8(plt, 0x0f); + WRITE_8(plt + 1, 0x1f); + WRITE_8(plt + 2, 0x40); + WRITE_8(plt + 3, 0x0); + plt += 4; + + /* + * Walk through the sorted PLT relocations in the output section + * and fill in each GOT and PLT entries. + */ + i = 3; + j = 0; + STAILQ_FOREACH(lre, rela_plt_is->is_reloc, lre_next) { + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * Set symbol's PLT offset to the address of this PLT entry. + * The PLT offset is used in relocation processing later. + */ + lsb->lsb_plt_off = plt_os->os_addr + (i - 2) * 16; + + /* + * Update the offset for the R_X86_64_JUMP_SLOT relocation + * entry, pointing to the corresponding GOT entry. + */ + lre->lre_offset = got_os->os_addr + i * 8; + + /* + * Calculate the IP-relative offset to the GOT entry for + * this function. (6 bytes for jmp) + */ + gotpcrel = pltgot + i * 8 - (i - 2) * 16 - 6; + + /* + * PLT: Jump to the address in the GOT entry for this + * function. (JMP reg/memXX [RIP+disp32]) + */ + WRITE_8(plt, 0xff); + WRITE_8(plt + 1, 0x25); + WRITE_32(plt + 2, gotpcrel); + plt += 6; + + /* + * PLT: Symbol is not resolved, push the relocation index to + * the stack. (PUSH imm32) + */ + WRITE_8(plt, 0x68); + WRITE_32(plt + 1, j); + plt += 5; + + /* + * PLT: Jump to the first PLT entry, eventually call the + * dynamic linker. (JMP rel32off) + */ + WRITE_8(plt, 0xe9); + s32 = - (i - 1) * 16; + WRITE_32(plt + 1, s32); + plt += 5; + + /* + * GOT: Write the GOT entry for this function, pointing to + * the push op. + */ + u64 = plt_os->os_addr + (i - 2) * 16 + 6; + WRITE_64(got, u64); + + /* Increase relocation entry index. */ + j++; + + /* Move to next GOT entry. */ + got += 8; + i++; + } + + assert(got == (uint8_t *) got_is->is_ibuf + got_is->is_size); + assert(plt == (uint8_t *) plt_is->is_ibuf + plt_is->is_size); +} + +static void +_scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + enum ld_tls_relax tr; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * TODO: We do not yet support "Large Models" and relevant + * relocation types R_X86_64_GOT64, R_X86_64_GOTPCREL64, + * R_X86_64_GOTPC64, R_X86_64_GOTPLT64 and R_X86_64_PLTOFF64. + * Refer to AMD64 ELF ABI for details. + */ + + switch (lre->lre_type) { + case R_X86_64_NONE: + break; + + case R_X86_64_64: + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_16: + case R_X86_64_8: + + /* + * For a local symbol, if the linker output a PIE or DSO, + * we should generate a R_X86_64_RELATIVE reloc for + * R_X86_64_64. We don't know how to generate dynamic reloc + * for other reloc types since R_X86_64_RELATIVE is 64 bits. + * We can not use them directly either because FreeBSD rtld(1) + * (and probably glibc) doesn't accept absolute address + * reloction other than R_X86_64_64. + */ + if (lsb->lsb_bind == STB_LOCAL) { + if (ld->ld_pie || ld->ld_dso) { + if (lre->lre_type == R_X86_64_64) + _create_dynamic_reloc(ld, is, lsb, + R_X86_64_RELATIVE, lre->lre_offset, + lre->lre_addend); + else + _warn_pic(ld, lre); + } + break; + } + + /* + * For a global symbol, we probably need to generate PLT entry + * and/or a dynamic relocation. + * + * Note here, normally the compiler will generate a PC-relative + * relocation for function calls. However, if the code retrieve + * the address of a function and call it indirectly, assembler + * will generate absolute relocation instead. That's why we + * should check if we need to create a PLT entry here. Also, if + * we're going to create the PLT entry, we should also set the + * symbol value to the address of PLT entry just in case the + * function address is used to compare with other function + * addresses. (If PLT address is used, function will have + * unified address in the main executable and DSOs) + */ + if (ld_reloc_require_plt(ld, lre)) { + if (!lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + /* + * Note here even if we have generated PLT for this + * function before, we still need to set this flag. + * It's possible that we first see the relative + * relocation then this absolute relocation, in + * other words, the same function can be called in + * different ways. + */ + lsb->lsb_func_addr = 1; + } + + if (ld_reloc_require_copy_reloc(ld, lre) && + !lsb->lsb_copy_reloc) + _create_copy_reloc(ld, lsb); + else if (ld_reloc_require_dynamic_reloc(ld, lre)) { + /* We only support R_X86_64_64. (See above) */ + if (lre->lre_type != R_X86_64_64) { + _warn_pic(ld, lre); + break; + } + /* + * Check if we can relax R_X86_64_64 to + * R_X86_64_RELATIVE instead. + */ + if (ld_reloc_relative_relax(ld, lre)) + _create_dynamic_reloc(ld, is, lsb, + R_X86_64_RELATIVE, lre->lre_offset, + lre->lre_addend); + else + _create_dynamic_reloc(ld, is, lsb, + R_X86_64_64, lre->lre_offset, + lre->lre_addend); + } + + break; + + case R_X86_64_PLT32: + /* + * In some cases we don't really need to generate a PLT + * entry, then a R_X86_64_PLT32 relocation can be relaxed + * to a R_X86_64_PC32 relocation. + */ + + if (lsb->lsb_bind == STB_LOCAL || + !ld_reloc_require_plt(ld, lre)) { + lre->lre_type = R_X86_64_PC32; + break; + } + + /* + * If linker outputs an normal executable and the symbol is + * defined but is not defined inside a DSO, we can generate + * a R_X86_64_PC32 relocation instead. + */ + if (ld->ld_exec && lsb->lsb_shndx != SHN_UNDEF && + (lsb->lsb_input == NULL || + lsb->lsb_input->li_type != LIT_DSO)) { + lre->lre_type = R_X86_64_PC32; + break; + } + + /* Create an PLT entry otherwise. */ + if (!lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + break; + + case R_X86_64_PC64: + case R_X86_64_PC32: + case R_X86_64_PC16: + case R_X86_64_PC8: + + /* + * When these relocations apply to a global symbol, we should + * check if we need to generate PLT entry and/or a dynamic + * relocation. + */ + if (lsb->lsb_bind != STB_LOCAL) { + if (ld_reloc_require_plt(ld, lre) && !lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + + if (ld_reloc_require_copy_reloc(ld, lre) && + !lsb->lsb_copy_reloc) + _create_copy_reloc(ld, lsb); + else if (ld_reloc_require_dynamic_reloc(ld, lre)) { + /* + * We can not generate dynamic relocation for + * these PC-relative relocation since they + * are probably not supported by the runtime + * linkers. + * + * Note: FreeBSD rtld(1) does support + * R_X86_64_PC32. + */ + _warn_pic(ld, lre); + } + } + break; + + case R_X86_64_GOTOFF64: + case R_X86_64_GOTPC32: + /* + * These relocation types use GOT address as a base address + * and instruct the linker to build a GOT. + */ + (void) _find_and_create_got_section(ld, 1); + break; + + case R_X86_64_GOT32: + case R_X86_64_GOTPCREL: + /* + * These relocation types instruct the linker to build a + * GOT and generate a GOT entry. + */ + if (!lsb->lsb_got) { + _reserve_got_entry(ld, lsb, 1); + /* + * TODO: For now we always create a R_X86_64_GLOB_DAT + * relocation for a GOT entry. There are cases that + * the symbol's address is known at link time and + * the GOT entry value can be filled in by the program + * linker instead. + */ + if (ld_reloc_require_glob_dat(ld, lre)) + _create_got_reloc(ld, lsb, R_X86_64_GLOB_DAT, + lsb->lsb_got_off); + else + _create_got_reloc(ld, lsb, R_X86_64_RELATIVE, + lsb->lsb_got_off); + } + break; + + case R_X86_64_TLSGD: /* Global Dynamic */ + tr = _tls_check_relax(ld, lre); + switch (tr) { + case TLS_RELAX_NONE: + _create_tls_gd_reloc(ld, lsb); + break; + case TLS_RELAX_INIT_EXEC: + _create_tls_ie_reloc(ld, lsb); + break; + case TLS_RELAX_LOCAL_EXEC: + break; + default: + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + } + break; + + case R_X86_64_TLSLD: /* Local Dynamic */ + tr = _tls_check_relax(ld, lre); + if (tr == TLS_RELAX_NONE) + _create_tls_ld_reloc(ld, lsb); + else if (tr != TLS_RELAX_LOCAL_EXEC) + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + + case R_X86_64_DTPOFF32: + /* Handled by R_X86_64_TLSLD case. */ + break; + + case R_X86_64_GOTTPOFF: /* Initial Exec */ + tr = _tls_check_relax(ld, lre); + if (tr == TLS_RELAX_NONE) + _create_tls_ie_reloc(ld, lsb); + else if (tr != TLS_RELAX_LOCAL_EXEC) + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + + case R_X86_64_TPOFF32: /* Local Exec */ + /* No further relaxation possible. */ + break; + + case R_X86_64_GOTPC32_TLSDESC: + case R_X86_64_TLSDESC_CALL: + /* TODO. */ + break; + + default: + ld_warn(ld, "can not handle relocation %ju", + lre->lre_type); + break; + } +} + +static uint64_t +_got_offset(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_output_section *os; + + assert(lsb->lsb_got); + + if (ld->ld_got == NULL) { + ld->ld_got = _find_and_create_got_section(ld, 0); + assert(ld->ld_got != NULL); + } + + os = ld->ld_got->is_output; + + return (os->os_addr + ld->ld_got->is_reloff + lsb->lsb_got_off); +} + +static void +_process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + struct ld_state *ls; + struct ld_output *lo; + uint64_t u64, s, l, p, g; + int64_t s64; + uint32_t u32; + int32_t s32; + enum ld_tls_relax tr; + + ls = &ld->ld_state; + + lo = ld->ld_output; + assert(lo != NULL); + + l = lsb->lsb_plt_off; + p = lre->lre_offset + is->is_output->os_addr + is->is_reloff; + s = lsb->lsb_value; + + switch (lre->lre_type) { + case R_X86_64_NONE: + break; + + case R_X86_64_64: + WRITE_64(buf + lre->lre_offset, s + lre->lre_addend); + break; + + case R_X86_64_PC32: + if (lsb->lsb_plt) + s32 = l + lre->lre_addend - p; + else + s32 = s + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + break; + + case R_X86_64_PLT32: + if (!ls->ls_ignore_next_plt) { + s32 = l + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + } else + ls->ls_ignore_next_plt = 0; + break; + + case R_X86_64_GOTPCREL: + g = _got_offset(ld, lsb); + s32 = g + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + break; + + case R_X86_64_32: + u64 = s + lre->lre_addend; + u32 = u64 & 0xffffffff; + if (u64 != u32) + ld_fatal(ld, "R_X86_64_32 relocation failed"); + WRITE_32(buf + lre->lre_offset, u32); + break; + + case R_X86_64_32S: + s64 = s + lre->lre_addend; + s32 = s64 & 0xffffffff; + if (s64 != s32) + ld_fatal(ld, "R_X86_64_32S relocation failed"); + WRITE_32(buf + lre->lre_offset, s32); + break; + + case R_X86_64_TLSGD: /* Global Dynamic */ + tr = _tls_check_relax(ld, lre); + switch (tr) { + case TLS_RELAX_NONE: + g = _got_offset(ld, lsb); + s32 = g + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + break; + case TLS_RELAX_INIT_EXEC: + g = _got_offset(ld, lsb); + _tls_relax_gd_to_ie(ld, ls, lo, lre, p, g, buf); + break; + case TLS_RELAX_LOCAL_EXEC: + _tls_relax_gd_to_le(ld, ls, lo, lre, lsb, buf); + break; + default: + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + } + break; + + case R_X86_64_TLSLD: /* Local Dynamic */ + tr = _tls_check_relax(ld, lre); + switch (tr) { + case TLS_RELAX_NONE: + g = _got_offset(ld, lsb); + s32 = g + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + break; + case TLS_RELAX_LOCAL_EXEC: + _tls_relax_ld_to_le(ld, ls, lre, buf); + break; + default: + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + } + break; + + case R_X86_64_DTPOFF32: /* Local Dynamic (offset) */ + tr = _tls_check_relax(ld, lre); + switch (tr) { + case TLS_RELAX_NONE: + s32 = _tls_dtpoff(lo, lsb); + WRITE_32(buf + lre->lre_offset, s32); + break; + case TLS_RELAX_LOCAL_EXEC: + s32 = _tls_tpoff(lo, lsb); + WRITE_32(buf + lre->lre_offset, s32); + break; + default: + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + } + break; + + case R_X86_64_GOTTPOFF: /* Initial Exec */ + tr = _tls_check_relax(ld, lre); + switch (tr) { + case TLS_RELAX_NONE: + g = _got_offset(ld, lsb); + s32 = g + lre->lre_addend - p; + WRITE_32(buf + lre->lre_offset, s32); + break; + case TLS_RELAX_LOCAL_EXEC: + _tls_relax_ie_to_le(ld, lo, lre, lsb, buf); + break; + default: + ld_fatal(ld, "Internal: invalid TLS relaxation %d", + tr); + break; + } + break; + + case R_X86_64_TPOFF32: /* Local Exec */ + s32 = _tls_tpoff(lo, lsb); + WRITE_32(buf + lre->lre_offset, s32); + break; + + default: + ld_warn(ld, "Relocation %s not supported", + elftc_reloc_type_str(EM_X86_64, lre->lre_type)); + break; + } +} + +static void +_adjust_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + struct ld_input_section *_is; + + (void) ld; + (void) is; + (void) buf; + + /* Only need to adjust relocation against section symbols. */ + if (lsb->lsb_type != STT_SECTION) + return; + + if ((_is = lsb->lsb_is) == NULL || _is->is_output == NULL) + return; + + /* + * Update the relocation addend to point to the new location + * in the output object. + */ + lre->lre_addend += _is->is_reloff; +} + +static enum ld_tls_relax +_tls_check_relax(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * If the linker is performing -static linking, we should always + * use the Local Exec model. + */ + if (!ld->ld_dynamic_link) + return (TLS_RELAX_LOCAL_EXEC); + + /* + * If the linker is creating a DSO, we can not perform any TLS + * relaxation. + */ + if (ld->ld_dso) + return (TLS_RELAX_NONE); + + /* + * The linker is creating an executable, if the symbol is + * defined in a regular object, we can use the Local Exec model. + */ + if (lsb->lsb_shndx != SHN_UNDEF && ld_symbols_in_regular(lsb)) + return (TLS_RELAX_LOCAL_EXEC); + + /* + * If the TLS model is Global Dynamic, we can relax it to Initial + * Exec model since the linker is creating an executable. + */ + if (lre->lre_type == R_X86_64_TLSGD) + return (TLS_RELAX_INIT_EXEC); + + /* For all the other cases, no relaxation can be done. */ + return (TLS_RELAX_NONE); +} + +static int32_t +_tls_tpoff(struct ld_output *lo, struct ld_symbol *lsb) +{ + int32_t tls_off; + + tls_off = -roundup(lo->lo_tls_size, lo->lo_tls_align); + + return (tls_off + (lsb->lsb_value - lo->lo_tls_addr)); +} + +static int32_t +_tls_dtpoff(struct ld_output *lo, struct ld_symbol *lsb) +{ + + return (lsb->lsb_value - lo->lo_tls_addr); +} + +static int +_tls_verify_gd(uint8_t *buf, uint64_t off) +{ + /* + * Global Dynamic model: + * + * 0x00 .byte 0x66 + * 0x01 leaq x@tlsgd(%rip), %rdi + * 0x08 .word 0x6666 + * 0x0a rex64 + * 0x0b call _tls_get_addr@plt + */ + uint8_t gd[] = "\x66\x48\x8d\x3d\x00\x00\x00\x00" + "\x66\x66\x48\xe8\x00\x00\x00\x00"; + + if (memcmp(buf + off, gd, sizeof(gd) - 1) == 0) + return (1); + + return (0); +} + +static int +_tls_verify_ld(uint8_t *buf, uint64_t off) +{ + /* + * Local Dynamic model: + * + * 0x00 leaq x@tlsld(%rip), %rdi + * 0x07 call _tls_get_addr@plt + */ + uint8_t ld[] = "\x48\x8d\x3d\x00\x00\x00\x00" + "\xe8\x00\x00\x00\x00"; + + if (memcmp(buf + off, ld, sizeof(ld) - 1) == 0) + return (1); + + return (0); +} + +static void +_tls_relax_gd_to_ie(struct ld *ld, struct ld_state *ls, struct ld_output *lo, + struct ld_reloc_entry *lre, uint64_t p, uint64_t g, uint8_t *buf) +{ + /* + * Initial Exec model: + * + * 0x00 movq %fs:0, %rax + * 0x09 addq x@gottpoff(%rip), %rax + */ + uint8_t ie[] = "\x64\x48\x8b\x04\x25\x00\x00\x00\x00" + "\x48\x03\x05\x00\x00\x00\x00"; + int32_t s32; + + assert(lre->lre_type == R_X86_64_TLSGD); + + if (!_tls_verify_gd(buf, lre->lre_offset - 4)) + ld_warn(ld, "unrecognized TLS global dynamic model code"); + + /* Rewrite Global Dynamic to Initial Exec model. */ + memcpy((uint8_t *) buf + lre->lre_offset - 4, ie, sizeof(ie) - 1); + + /* + * R_X86_64_TLSGD relocation is applied at gd[4]. After it's relaxed + * to Initial Exec model, the resulting R_X86_64_GOTTPOFF relocation + * should be applied at ie[12]. The addend should remain the same + * since instruction "leaq x@tlsgd(%rip), %rdi" and + * "addq x@gottpoff(%rip), %rax" has the same length. `p' is moved + * 8 bytes forward. + */ + s32 = g + lre->lre_addend - (p + 8); + WRITE_32(buf + lre->lre_offset + 8, s32); + + /* Ignore the next R_X86_64_PLT32 relocation for _tls_get_addr. */ + ls->ls_ignore_next_plt = 1; +} + +static void +_tls_relax_gd_to_le(struct ld *ld, struct ld_state *ls, struct ld_output *lo, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + /* + * Local Exec model: + * + * 0x00 movq %fs:0, %rax + * 0x09 leaq x@tpoff(%rax), %rax + */ + uint8_t le[] = "\x64\x48\x8b\x04\x25\x00\x00\x00\x00" + "\x48\x8d\x80\x00\x00\x00\x00"; + int32_t s32; + + if (!_tls_verify_gd(buf, lre->lre_offset - 4)) + ld_warn(ld, "unrecognized TLS global dynamic model code"); + + /* Rewrite Global Dynamic to Local Exec model. */ + memcpy((uint8_t *) buf + lre->lre_offset - 4, le, sizeof(le) - 1); + + /* + * R_X86_64_TLSGD relocation is applied at gd[4]. After it's relaxed + * to Local Exec model, the resulting R_X86_64_TPOFF32 should be + * applied at le[12]. + */ + s32 = _tls_tpoff(lo, lsb); + WRITE_32(buf + lre->lre_offset + 8, s32); + + /* Ignore the next R_X86_64_PLT32 relocation for _tls_get_addr. */ + ls->ls_ignore_next_plt = 1; +} + +static void +_tls_relax_ld_to_le(struct ld *ld, struct ld_state *ls, + struct ld_reloc_entry *lre, uint8_t *buf) +{ + /* + * Local Exec model: (with padding) + * + * 0x00 .word 0x6666 + * 0x02 .byte 0x66 + * 0x03 movq %fs:0, %rax + */ + uint8_t le_p[] = "\x66\x66\x66\x64\x48\x8b\x04\x25\x00\x00\x00\x00"; + + assert(lre->lre_type == R_X86_64_TLSLD); + + if (!_tls_verify_ld(buf, lre->lre_offset - 3)) + ld_warn(ld, "unrecognized TLS local dynamic model code"); + + /* Rewrite Local Dynamic to Local Exec model. */ + memcpy(buf + lre->lre_offset - 3, le_p, sizeof(le_p) - 1); + + /* Ignore the next R_X86_64_PLT32 relocation for _tls_get_addr. */ + ls->ls_ignore_next_plt = 1; +} + +static void +_tls_relax_ie_to_le(struct ld *ld, struct ld_output *lo, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + int32_t s32; + uint8_t reg; + + (void) ld; + + assert(lre->lre_type == R_X86_64_GOTTPOFF); + + /* + * Rewrite Initial Exec to Local Exec model: rewrite + * "movq 0x0(%rip),%reg" to "movq 0x0,%reg". or, + * "addq 0x0(%rip),%rsp" to "addq 0x0,%rsp". or, + * "addq 0x0(%rip),%reg" to "leaq 0x0(%reg),%reg" + */ + reg = buf[lre->lre_offset - 1] >> 3; + if (buf[lre->lre_offset - 2] == 0x8b) { + /* movq 0x0(%rip),%reg -> movq 0x0,%reg. */ + buf[lre->lre_offset - 2] = 0xc7; + buf[lre->lre_offset - 1] = 0xc0 | reg; /* Set r/m to `reg' */ + /* + * Set REX.B (high bit for r/m) if REX.R (high bit for reg) + * is set. + */ + if (buf[lre->lre_offset - 3] == 0x4c) + buf[lre->lre_offset - 3] = 0x49; + } else if (reg == 4) { + /* addq 0x0(%rip),%rsp -> addq 0x0,%rsp */ + buf[lre->lre_offset - 2] = 0x81; + buf[lre->lre_offset - 1] = 0xc0 | reg; /* Set r/m to `reg' */ + /* + * Set REX.B (high bit for r/m) if REX.R (high bit for reg) + * is set. + */ + if (buf[lre->lre_offset - 3] == 0x4c) + buf[lre->lre_offset - 3] = 0x49; + } else { + /* addq 0x0(%rip),%reg -> leaq 0x0(%reg),%reg */ + buf[lre->lre_offset - 2] = 0x8d; + /* Both reg and r/m in ModRM should be set to `reg' */ + buf[lre->lre_offset - 1] = 0x80 | reg | (reg << 3); + /* Set both REX.B and REX.R if REX.R is set */ + if (buf[lre->lre_offset - 3] == 0x4c) + buf[lre->lre_offset - 3] = 0x4d; + } + /* + * R_X86_64_GOTTPOFF relocation is applied at ie[12]. After it's + * relaxed to Local Exec model, the resulting R_X86_64_TPOFF32 + * should be applied at le[12]. Thus the offset remains the same. + */ + s32 = _tls_tpoff(lo, lsb); + WRITE_32(buf + lre->lre_offset, s32); +} + +static void +_create_tls_gd_reloc(struct ld *ld, struct ld_symbol *lsb) +{ + + /* + * Reserve 2 GOT entries and generate R_X86_64_DTPMOD64 and + * R_X86_64_DTPOFF64 relocations. + */ + if (!lsb->lsb_got) { + _reserve_got_entry(ld, lsb, 2); + _create_got_reloc(ld, lsb, R_X86_64_DTPMOD64, + lsb->lsb_got_off); + _create_got_reloc(ld, lsb, R_X86_64_DTPOFF64, + lsb->lsb_got_off + 8); + } +} + +static void +_create_tls_ld_reloc(struct ld *ld, struct ld_symbol *lsb) +{ + + /* Reserve 2 GOT entries and generate R_X86_64_DTPMOD64 reloation. */ + if (!lsb->lsb_got) { + _reserve_got_entry(ld, lsb, 2); + _create_got_reloc(ld, lsb, R_X86_64_DTPMOD64, + lsb->lsb_got_off); + lsb->lsb_tls_ld = 1; + } +} + +static void +_create_tls_ie_reloc(struct ld *ld, struct ld_symbol *lsb) +{ + + /* Reserve 1 GOT entry and generate R_X86_64_TPOFF64 relocation. */ + if (!lsb->lsb_got) { + _reserve_got_entry(ld, lsb, 1); + _create_got_reloc(ld, lsb, R_X86_64_TPOFF64, + lsb->lsb_got_off); + } +} + +void +amd64_register(struct ld *ld) +{ + struct ld_arch *amd64, *amd64_alt; + + if ((amd64 = calloc(1, sizeof(*amd64))) == NULL) + ld_fatal_std(ld, "calloc"); + + snprintf(amd64->name, sizeof(amd64->name), "%s", "amd64"); + + amd64->script = amd64_script; + amd64->interp = "/libexec/ld-elf.so.1"; + amd64->get_max_page_size = _get_max_page_size; + amd64->get_common_page_size = _get_common_page_size; + amd64->scan_reloc = _scan_reloc; + amd64->process_reloc = _process_reloc; + amd64->adjust_reloc = _adjust_reloc; + amd64->is_absolute_reloc = _is_absolute_reloc; + amd64->is_relative_reloc = _is_relative_reloc; + amd64->finalize_reloc = _finalize_reloc; + amd64->finalize_got_and_plt = _finalize_got_and_plt; + amd64->reloc_is_64bit = 1; + amd64->reloc_is_rela = 1; + amd64->reloc_entsize = sizeof(Elf64_Rela); + + HASH_ADD_STR(ld->ld_arch_list, name, amd64); + + if ((amd64_alt = calloc(1, sizeof(*amd64_alt))) == NULL) + ld_fatal_std(ld, "calloc"); + memcpy(amd64_alt, amd64, sizeof(struct ld_arch)); + amd64_alt->alias = amd64; + snprintf(amd64_alt->name, sizeof(amd64_alt->name), "%s", "x86-64"); + + HASH_ADD_STR(ld->ld_arch_list, name, amd64_alt); +} diff --git a/contrib/elftoolchain/ld/amd64.h b/contrib/elftoolchain/ld/amd64.h new file mode 100644 index 0000000000..7b28d26a3c --- /dev/null +++ b/contrib/elftoolchain/ld/amd64.h @@ -0,0 +1,31 @@ +/*- + * Copyright (c) 2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: amd64.h 3879 2020-11-07 18:50:43Z jkoshy $ + */ + +extern char *amd64_script; + +void amd64_register(struct ld *); diff --git a/contrib/elftoolchain/ld/amd64_script.ld b/contrib/elftoolchain/ld/amd64_script.ld new file mode 100644 index 0000000000..bb44fbe39c --- /dev/null +++ b/contrib/elftoolchain/ld/amd64_script.ld @@ -0,0 +1,151 @@ +/* $Id: amd64_script.ld 2806 2012-12-24 08:23:59Z kaiwang27 $ */ + +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE(__executable_start = 0x400000); + . = 0x400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x90909090 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x90909090 + .fini : + { + KEEP(*(.fini)) + } = 0x90909090 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + . = ALIGN (CONSTANT(MAXPAGESIZE)) - ((CONSTANT(MAXPAGESIZE) - .) & (CONSTANT(MAXPAGESIZE) - 1)); + . = DATA_SEGMENT_ALIGN (CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE)); + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .data.rel.ro : { + *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) + *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) + } + .dynamic : { *(.dynamic) } + .got : { *(.got) } + .got.plt : { *(.got.plt) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(64 / 8); + } + . = ALIGN(64 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/contrib/elftoolchain/ld/bigmips_script.ld b/contrib/elftoolchain/ld/bigmips_script.ld new file mode 100644 index 0000000000..7f60e19bd9 --- /dev/null +++ b/contrib/elftoolchain/ld/bigmips_script.ld @@ -0,0 +1,165 @@ +/* $Id$ */ + +OUTPUT_FORMAT("elf32-bigmips") +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE (__executable_start = 0x00400000); + . = 0x00400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x00000000 + .plt : { *(.plt) } + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x00000000 + .fini : + { + KEEP(*(.fini)) + } = 0x00000000 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + + .tdata : ALIGN(4096) { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .dynamic : { *(.dynamic) } + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .got : { *(.got.plt) *(.got) } + .data : + { + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _gp = ALIGN(16) + 0x7ff0; + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + /* Align the end of data segment to page boundary. */ + . = ALIGN(. != 0 ? 4096 : 1); + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + _fbss = .; + .sbss : ALIGN(8) + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) *(.reginfo) } +} diff --git a/contrib/elftoolchain/ld/i386.c b/contrib/elftoolchain/ld/i386.c new file mode 100644 index 0000000000..b4f13efb12 --- /dev/null +++ b/contrib/elftoolchain/ld/i386.c @@ -0,0 +1,579 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_symbols.h" +#include "ld_utils.h" +#include "i386.h" + +ELFTC_VCSID("$Id: i386.c 3887 2020-11-11 18:54:48Z jkoshy $"); + +static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, + uint64_t offset); +static void _create_got_reloc(struct ld *ld, struct ld_symbol *lsb, + uint64_t type, uint64_t offset); +static void _create_copy_reloc(struct ld *ld, struct ld_symbol *lsb); +static void _create_dynamic_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_symbol *lsb, uint64_t type, uint64_t offset); +static void _scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre); +static struct ld_input_section *_find_and_create_got_section(struct ld *ld, + int create); +static struct ld_input_section *_find_and_create_gotplt_section(struct ld *ld, + int create); +static struct ld_input_section *_find_and_create_plt_section(struct ld *ld, + int create); +static uint64_t _get_max_page_size(struct ld *ld); +static uint64_t _get_common_page_size(struct ld *ld); +static void _process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf); +static void _reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num); +static void _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb); +static void _reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb); +static int _is_absolute_reloc(uint64_t r); +static int _is_relative_reloc(uint64_t r); +static void _warn_pic(struct ld *ld, struct ld_reloc_entry *lre); +static uint32_t _got_offset(struct ld *ld, struct ld_symbol *lsb); + +static uint64_t +_get_max_page_size(struct ld *ld) +{ + + (void) ld; + return (0x1000); +} + +static uint64_t +_get_common_page_size(struct ld *ld) +{ + + (void) ld; + return (0x1000); +} + +static int +_is_absolute_reloc(uint64_t r) +{ + + if (r == R_386_32) + return (1); + + return (0); +} + +static int +_is_relative_reloc(uint64_t r) +{ + + if (r == R_386_RELATIVE) + return (1); + + return (0); +} + +static void +_warn_pic(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = lre->lre_sym; + + if (lsb->lsb_bind != STB_LOCAL) + ld_warn(ld, "relocation %s against `%s' can not be used" + " by runtime linker; recompile with -fPIC", + elftc_reloc_type_str(EM_386, lre->lre_type), lsb->lsb_name); + else + ld_warn(ld, "relocation %s can not be used by runtime linker;" + " recompile with -fPIC", + elftc_reloc_type_str(EM_386, lre->lre_type)); +} + +static struct ld_input_section * +_find_and_create_got_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the GOT section is already created. */ + is = ld_input_find_internal_section(ld, ".got"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".got"); + is->is_entsize = 4; + is->is_align = 4; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_WRITE; + } + + return (is); +} + +static struct ld_input_section * +_find_and_create_gotplt_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the GOT (for PLT) section is already created. */ + is = ld_input_find_internal_section(ld, ".got.plt"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".got.plt"); + is->is_entsize = 4; + is->is_align = 4; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_WRITE; + + /* Reserve space for the initial entries. */ + (void) ld_input_reserve_ibuf(is, 3); + + /* Create _GLOBAL_OFFSET_TABLE_ symbol. */ + ld_symbols_add_internal(ld, "_GLOBAL_OFFSET_TABLE_", 0, 0, + is->is_index, STB_LOCAL, STT_OBJECT, STV_HIDDEN, is, NULL); + } + + return (is); +} + +static struct ld_input_section * +_find_and_create_plt_section(struct ld *ld, int create) +{ + struct ld_input_section *is; + + /* Check if the PLT section is already created. */ + is = ld_input_find_internal_section(ld, ".plt"); + if (is != NULL) + return (is); + + if (create) { + is = ld_input_add_internal_section(ld, ".plt"); + is->is_entsize = 4; + is->is_align = 4; + is->is_type = SHT_PROGBITS; + is->is_flags = SHF_ALLOC | SHF_EXECINSTR; + + /* Reserve space for the initial entry. */ + (void) ld_input_reserve_ibuf(is, 1); + } + + return (is); +} + +static void +_reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num) +{ + struct ld_input_section *is; + + is = _find_and_create_got_section(ld, 1); + + /* Check if the entry already has a GOT entry. */ + if (lsb->lsb_got) + return; + + /* Reserve GOT entries. */ + lsb->lsb_got_off = ld_input_reserve_ibuf(is, num); + lsb->lsb_got = 1; +} + +static void +_reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *is; + + is = _find_and_create_gotplt_section(ld, 1); + + /* Reserve a GOT entry for PLT. */ + (void) ld_input_reserve_ibuf(is, 1); + + /* + * Record a R_386_JUMP_SLOT entry for this symbol. Note that + * we don't need to record the offset (relative to the GOT section) + * here, since the PLT relocations will be sorted later and we + * will generate GOT section according to the new order. + */ + _create_plt_reloc(ld, lsb, 0); +} + +static void +_reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *is; + + is = _find_and_create_plt_section(ld, 1); + + (void) ld_input_reserve_ibuf(is, 1); + lsb->lsb_plt = 1; +} + +static void +_create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset) +{ + + ld_reloc_create_entry(ld, ".rel.plt", NULL, R_386_JUMP_SLOT, + lsb, offset, 0); + + lsb->lsb_dynrel = 1; +} + +static void +_create_got_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t type, + uint64_t offset) +{ + struct ld_input_section *tis; + + tis = _find_and_create_got_section(ld, 0); + assert(tis != NULL); + + ld_reloc_create_entry(ld, ".rel.got", tis, type, lsb, offset, 0); + + if (type != R_386_RELATIVE) + lsb->lsb_dynrel = 1; +} + +static void +_create_copy_reloc(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input_section *tis; + + ld_dynamic_reserve_dynbss_entry(ld, lsb); + + tis = ld_input_find_internal_section(ld, ".dynbss"); + assert(tis != NULL); + + ld_reloc_create_entry(ld, ".rel.bss", tis, R_386_COPY, lsb, + lsb->lsb_value, 0); + + lsb->lsb_dynrel = 1; +} + +static void +_create_dynamic_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_symbol *lsb, uint64_t type, uint64_t offset) +{ + + if (lsb->lsb_bind == STB_LOCAL) { + if (is->is_flags & SHF_WRITE) + ld_reloc_create_entry(ld, ".rel.data.rel.local", + is, type, lsb, offset, 0); + else + ld_reloc_create_entry(ld, ".rel.data.rel.ro.local", + is, type, lsb, offset, 0); + } else { + if (is->is_flags & SHF_WRITE) + ld_reloc_create_entry(ld, ".rel.data.rel", + is, type, lsb, offset, 0); + else + ld_reloc_create_entry(ld, ".rel.data.rel.ro", + is, type, lsb, offset, 0); + } + + if (type != R_386_RELATIVE) + lsb->lsb_dynrel = 1; +} + +static void +_scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + switch (lre->lre_type) { + case R_386_NONE: + break; + + case R_386_32: + /* + * For a local symbol, if te linker output a PIE or DSO, + * we should generate a R_386_RELATIVE reloc for R_386_32. + */ + if (lsb->lsb_bind == STB_LOCAL) { + if (ld->ld_pie || ld->ld_dso) + _create_dynamic_reloc(ld, is, lsb, + R_386_RELATIVE, lre->lre_offset); + break; + } + + /* + * For a global symbol, we probably need to generate PLE entry + * and/ore a dynamic relocation. + * + * Note here, normally the compiler will generate a PC-relative + * relocation for function calls. However, if the code retrieve + * the address of a function and call it indirectly, assembler + * will generate absolute relocation instead. That's why we + * should check if we need to create a PLT entry here. Also, if + * we're going to create the PLT entry, we should also set the + * symbol value to the address of PLT entry just in case the + * function address is used to compare with other function + * addresses. (If PLT address is used, function will have + * unified address in the main executable and DSOs) + */ + if (ld_reloc_require_plt(ld, lre)) { + if (!lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + /* + * Note here even if we have generated PLT for this + * function before, we still need to set this flag. + * It's possible that we first see the relative + * relocation then this absolute relocation, in + * other words, the same function can be called in + * different ways. + */ + lsb->lsb_func_addr = 1; + } + + if (ld_reloc_require_copy_reloc(ld, lre) && + !lsb->lsb_copy_reloc) + _create_copy_reloc(ld, lsb); + else if (ld_reloc_require_dynamic_reloc(ld, lre)) { + /* + * Check if we can relax R_386_32 to + * R_386_RELATIVE instead. + */ + if (ld_reloc_relative_relax(ld, lre)) + _create_dynamic_reloc(ld, is, lsb, + R_386_RELATIVE, lre->lre_offset); + else + _create_dynamic_reloc(ld, is, lsb, + R_386_32, lre->lre_offset); + } + + break; + + case R_386_PLT32: + /* + * In some cases we don't really need to generate a PLT + * entry, then a R_386_PLT32 relocation can be relaxed + * to a R_386_PC32 relocation. + */ + if (lsb->lsb_bind == STB_LOCAL || + !ld_reloc_require_plt(ld, lre)) { + lre->lre_type = R_386_PC32; + break; + } + + /* + * If linker outputs an normal executable and the symbol is + * defined but is not defined inside a DSO, we can generate + * a R_386_PC32 relocation instead. + */ + if (ld->ld_exec && lsb->lsb_shndx != SHN_UNDEF && + (lsb->lsb_input == NULL || + lsb->lsb_input->li_type != LIT_DSO)) { + lre->lre_type = R_386_PC32; + break; + } + + /* Create an PLT entry otherwise. */ + if (!lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + break; + + case R_386_PC32: + /* + * When R_386_PC32 apply to a global symbol, we should + * check if we need to generate PLT entry and/or a dynamic + * relocation. + */ + if (lsb->lsb_bind != STB_LOCAL) { + if (ld_reloc_require_plt(ld, lre) && !lsb->lsb_plt) { + _reserve_gotplt_entry(ld, lsb); + _reserve_plt_entry(ld, lsb); + } + + if (ld_reloc_require_copy_reloc(ld, lre) && + !lsb->lsb_copy_reloc) + _create_copy_reloc(ld, lsb); + else if (ld_reloc_require_dynamic_reloc(ld, lre)) { + /* + * We can not generate dynamic relocation for + * these PC-relative relocation since they + * are probably not supported by the runtime + * linkers. + */ + _warn_pic(ld, lre); + } + } + break; + + case R_386_GOTOFF: + case R_386_GOTPC: + /* + * These relocation types use GOT address as a base address + * and instruct the linker to build a GOT. + */ + (void) _find_and_create_got_section(ld, 1); + break; + + case R_386_GOT32: + /* + * R_386_GOT32 relocation instructs the linker to build a + * GOT and generate a GOT entry. + */ + if (!lsb->lsb_got) { + _reserve_got_entry(ld, lsb, 1); + /* + * TODO: For now we always create a R_386_GLOB_DAT + * relocation for a GOT entry. There are cases that + * the symbol's address is known at link time and + * the GOT entry value can be filled in by the program + * linker instead. + */ + if (ld_reloc_require_glob_dat(ld, lre)) + _create_got_reloc(ld, lsb, R_386_GLOB_DAT, + lsb->lsb_got_off); + else + _create_got_reloc(ld, lsb, R_386_RELATIVE, + lsb->lsb_got_off); + } + /* FALLTHROUGH */ + default: + ld_warn(ld, "can not handle relocation %ju", + lre->lre_type); + break; + } +} + +static uint32_t +_got_offset(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_output_section *os; + + assert(lsb->lsb_got); + + if (ld->ld_got == NULL) { + ld->ld_got = _find_and_create_got_section(ld, 0); + assert(ld->ld_got != NULL); + } + + os = ld->ld_got->is_output; + + return (os->os_addr + ld->ld_got->is_reloff + lsb->lsb_got_off); +} + +static void +_process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + struct ld_state *ls; + struct ld_output *lo; + uint32_t p, s, l, g, got; + int32_t a, v; + + ls = &ld->ld_state; + + lo = ld->ld_output; + assert(lo != NULL); + + l = lsb->lsb_plt_off; + p = lre->lre_offset + is->is_output->os_addr + is->is_reloff; + got = ld->ld_got->is_output->os_addr; + s = (uint32_t) lsb->lsb_value; + READ_32(buf + lre->lre_offset, a); + + switch (lre->lre_type) { + case R_386_NONE: + break; + + case R_386_32: + v = s + a; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_386_PC32: + if (lsb->lsb_plt) + v = l + a - p; + else + v = s + a - p; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_386_PLT32: + if (!ls->ls_ignore_next_plt) { + v = l + a - p; + WRITE_32(buf + lre->lre_offset, v); + } else + ls->ls_ignore_next_plt = 0; + break; + + case R_386_GOT32: + g = _got_offset(ld, lsb); + v = g + a; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_386_GOTOFF: + v = s + a - got; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_386_GOTPC: + v = got + a - p; + WRITE_32(buf + lre->lre_offset, v); + break; + + default: + ld_fatal(ld, "Relocation %d not supported", lre->lre_type); + break; + } +} + +void +i386_register(struct ld *ld) +{ + struct ld_arch *i386_arch; + + if ((i386_arch = calloc(1, sizeof(*i386_arch))) == NULL) + ld_fatal_std(ld, "calloc"); + + snprintf(i386_arch->name, sizeof(i386_arch->name), "%s", "i386"); + + i386_arch->script = i386_script; + i386_arch->get_max_page_size = _get_max_page_size; + i386_arch->get_common_page_size = _get_common_page_size; + i386_arch->scan_reloc = _scan_reloc; + i386_arch->process_reloc = _process_reloc; + i386_arch->is_absolute_reloc = _is_absolute_reloc; + i386_arch->is_relative_reloc = _is_relative_reloc; + i386_arch->reloc_is_64bit = 0; + i386_arch->reloc_is_rela = 0; + i386_arch->reloc_entsize = sizeof(Elf32_Rel); + + HASH_ADD_STR(ld->ld_arch_list, name, i386_arch); +} diff --git a/contrib/elftoolchain/ld/i386.h b/contrib/elftoolchain/ld/i386.h new file mode 100644 index 0000000000..edfd95699b --- /dev/null +++ b/contrib/elftoolchain/ld/i386.h @@ -0,0 +1,31 @@ +/*- + * Copyright (c) 2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: i386.h 3879 2020-11-07 18:50:43Z jkoshy $ + */ + +extern char *i386_script; + +void i386_register(struct ld *); diff --git a/contrib/elftoolchain/ld/i386_script.ld b/contrib/elftoolchain/ld/i386_script.ld new file mode 100644 index 0000000000..7df2be0c7b --- /dev/null +++ b/contrib/elftoolchain/ld/i386_script.ld @@ -0,0 +1,148 @@ +/* $Id: i386_script.ld 2664 2012-11-04 08:39:22Z kaiwang27 $ */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE (__executable_start = 0x08048000); + . = 0x08048000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x90909090 + .plt : { *(.plt) } + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x90909090 + .fini : + { + KEEP(*(.fini)) + } = 0x90909090 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + . = ALIGN (CONSTANT(COMMONPAGESIZE)) - ((CONSTANT(COMMONPAGESIZE) - .) & (CONSTANT(COMMONPAGESIZE) - 1)); + . = DATA_SEGMENT_ALIGN (CONSTANT(COMMONPAGESIZE), CONSTANT(COMMONPAGESIZE)); + . = ALIGN(32 / 8); + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .dynamic : { *(.dynamic) } + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .got : { *(.got.plt) *(.got) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/contrib/elftoolchain/ld/ld.1 b/contrib/elftoolchain/ld/ld.1 new file mode 100644 index 0000000000..c05042f564 --- /dev/null +++ b/contrib/elftoolchain/ld/ld.1 @@ -0,0 +1,478 @@ +.\" Copyright (c) 2016 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by the author and contributors ``as is'' +.\" and any express or implied warranties, including, but not limited +.\" to, the implied warranties of merchantability and fitness for a +.\" particular purpose are disclaimed. In no event shall the author or +.\" contributors be liable for any direct, indirect, incidental, special, +.\" exemplary, or consequential damages (including, but not limited to, +.\" procurement of substitute goods or services; loss of use, data, or +.\" profits; or business interruption) however caused and on any +.\" theory of liability, whether in contract, strict liability, or +.\" tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the +.\" possibility of such damage. +.\" +.\" $Id$ +.\" +.Dd February 14, 2016 +.Dt LD 1 +.Os +.Sh NAME +.Nm ld +.Nd link editor +.Sh SYNOPSIS +.Nm +.Op Fl \&( +.Op Fl \&) +.Op Fl Bdynamic +.Op Fl Bshareable +.Op Fl Bstatic +.Op Fl I Ar file | Fl -dynamic-linker= Ns Ar file +.Op Fl L Ar dir | Fl -library-path= Ns Ar dir +.Op Fl M | Fl -print-map +.Op Fl T Ar script-file | Fl -script= Ns Ar script-file +.Op Fl V | Fl v | Fl -version +.Op Fl a Ar linkmode +.Op Fl b Ar input-format | Fl -format= Ns Ar input-format +.Op Fl call_shared +.Op Fl d | Fl dc | Fl dp +.Op Fl dn +.Op Fl dy +.Op Fl e Ar symbol | Fl -entry= Ns Ar symbol +.Op Fl h Ar name | Fl soname= Ns Ar name +.Op Fl l Ar library | Fl -library= Ns Ar library +.Op Fl o Ar output-file | Fl -output= Ns Ar output-file +.Op Fl q | Fl -emit-relocs +.Op Fl r | Fl -relocatable +.Op Fl u Ar name | Fl -undefined= Ns Ar name +.Op Fl z Ar keyword +.Op Fl -as-needed +.Op Fl -eh-frame-hdr +.Op Fl -end-group +.Op Fl -gc-sections +.Op Fl -no-as-needed +.Op Fl -no-define-common +.Op Fl -no-gc-sections +.Op Fl -no-print-gc-sections +.Op Fl -no-whole-archive +.Op Fl -oformat= Ns Ar format +.Op Fl -pic-executable | Fl pie +.Op Fl -print-gc-sections +.Op Fl -rpath= Ns Ar dirs +.Op Fl -rpath-link= Ns Ar dirs +.Op Fl -start-group +.Op Fl shared +.Op Fl static +.Op Fl -version-script= Ns Ar script +.Op Fl -whole-archive +.Ar +.Sh DESCRIPTION +The +.Nm +utility combines ELF objects and +.Xr ar 1 +archives containing ELF objects into an executable or a partially +relocated object. +.Pp +The +.Nm +utility processes options and files in the order presented on the +command line. +Unlike most +.Ux +utilities, options and file names may be interspersed. +Options seen on the command line will generally apply to subsequent +files, or till overridden by another option. +.Sh OPTIONS +.Pp +The +.Nm +utility supports the following options: +.Bl -tag -width indent +.It Xo +.Fl \&( +.Ar archives Ns ... +.Fl \&) +.Xc +Start a group of archives that are to be searched repeatedly until no new +undefined references are created. +This option is used when there are circular references between one or +more archives in the archive group. +.Pp +The files named by the arguments +.Ar archives +are expected to be archive files. +.Pp +Each use of the +.Fl \&( +option starts a new archive group that is ended by a matching +.Fl \&) +option. +.It Fl Bdynamic +Choose dynamic libraries for the libraries specified by subsequent +.Fl l +options. +.It Fl Bshareable +Create a shared library. +.It Fl Bstatic +Choose static libraries for the libraries specified by subsequent +.Fl l +options. +.It Fl I Ar file | Fl -dynamic-linker= Ns Ar file +Set the name of the dynamic linker when generating ELF executables. +.It Fl L Ar dir | Fl -library-path= Ns Ar dir +Add directory +.Ar dir +to the list of paths that +.Nm +will search for archive libraries. +This option may be specified multiple times. +User supplied directories are searched in the order specified on +the command line. +.It Fl M | Fl -print-map +Print a link map to standard output. +.It Fl T Ar script-file | Fl -script= Ns Ar script-file +Use the file name by argument +.Ar script-file +as the linker script instead of the default. +.It Fl V | Fl v | Fl version +Print a version identifier for +.Nm +and exit. +.It Fl a Ar linkmode +Select linking mode. +The value of the argument +.Ar linkmode +should be one of the following literals: +.Bl -tag -width ".Li default" -compact +.It Cm default +Equivalent to specifying +.Fl Bdynamic . +.It Cm archive +Equivalent to specifying +.Fl Bstatic . +.It Cm shared +Equivalent to specifying +.Fl Bdynamic . +.El +.It Fl b Ar input-format | Fl -format Ar input-format +Set the input format to that specified by argument +.Ar input-format . +The legal values for the argument +.Ar input-format +are those supported by +.Xr elftc_bfd_find_target 3 . +.It Fl d | Fl dc | Fl dp +Assign space for common symbols even if generating a relocatable object. +.It Fl dn +Equivalent to specifying option +.Fl Bstatic . +.It Fl dy +Equivalent to specifying option +.Fl Bdynamic . +.It Fl e Ar entry | Fl -entry Ar entry +Set execution to start at the symbol named by the argument +.Ar entry . +The argument should be the name of a symbol. +.It Fl h Ar name | Fl soname Ar name +Set the +.Li DT_SONAME +field in the object to that specified by the argument +.Ar name . +.It Fl l Ar name | Fl -library= Ns Ar name +Add the archive library or shared library named by argument +.Ar name +to the set of files to link. +This file is looked for in the list of directories specified by prior +.Fl L +options on the command line. +.It Fl o Ar output-file | Fl -output= Ns Ar output-file +Use the file specified by argument +.Ar output-file +for the output, instead of the default file name of +.Sq a.out . +.It Fl q | Fl -emit-relocs +Preserve relocation information in executables, for use by post-link +analysis tools. +.It Fl r | Fl -relocatable +Generate a relocatable output file that can be used as input for subsequent +linker runs. +.It Fl u Ar name | Fl -undefined= Ns Ar name +Add the symbol specified by argument +.Ar name +to the output file as an undefined symbol. +This option may be specified multiple times. +.It Fl z Ar keyword +Recognized keywords include: +.Bl -tag -width ".Li defaultextract" -compact +.It Cm execstack +Require the object to use an executable stack. +.It Cm noexecstack +Do not require the object to use an executable stack. +.El +.It Fl -as-needed +Add +.Li DT_NEEDED +tags for only those shared libraries that satisfy non-weak +unresolved references from object files or other dynamic libraries +seen so far on the command line. +.It Fl call_shared +Equivalent to specifying option +.Fl Bdynamic . +.It Fl -eh-frame-hdr +Create a +.Dq ".eh_frame_hdr" +section, and a +.Li PT_GNU_EH_FRAME +segment header, containing exception handling information. +.It Fl -end-group +Equivalent to specifying option +.Fl \&) . +.It Fl -gc-sections +Garbage collect unused input sections. +.It Fl -no-as-needed +Insert +.Li DT_NEEDED +tags for all shared libraries seen henceforth on the command line, +irrespective of whether the shared library is needed to resolve an +undefined symbol or not. +This behavior is the default. +.It Fl -no-define-common +Do not assign addresses to common symbols. +.It Fl -no-gc-sections +Do not garbage collect input sections that contain unreferenced +symbols. +.It Fl -no-print-gc-sections +Do not print the list of sections removed when the +.Fl -gc-sections +directive is active. +.It Fl -no-whole-archive +Only include objects in an archive that satisfy an unresolved reference +in the link. +This behavior is the default. +.It Fl non_shared +Equivalent to specifying option +.Fl Bstatic . +.It Fl -oformat= Ns Ar format +Set the desired output format to that specified by the argument +.Ar format . +Supported values for argument +.Ar format +are those understood by +.Xr elftc_bfd_find_target 3 . +.It Fl -pic-executable | Fl pie +Create a position-independent executable. +.It Fl -print-gc-sections +Print the list of sections removed when the +.Fl -gc-sections +directive is active. +The output is printed to stderr. +.It Fl -rpath= Ns Ar dirs +Add the colon-separated list of directories named by the argument +.Ar dirs +to the runtime library search path and to the link-time search +path. +.It Fl -rpath-link= Ns Ar dirs +Add the directories specified by the colon-separated list of directories +in argument +.Ar dirs +to the link-time search path for libraries. +The directories specified by this option are searched before those +specified by +.Fl -rpath +options. +.It Fl shared +Equivalent to specifying option +.Fl Bshareable . +.It Fl -start-group +Equivalent to specifying option +.Fl \&( . +.It Fl static +Equivalent to specifying option +.Fl Bstatic . +.It Fl -version-script= Ns Ar script-file +Use the version script in the file named by argument +.Ar script-file . +.It Fl -whole-archive +Include the entire contents of every archive file encountered on the +command line after this option in the link. +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr ranlib 1 , +.Xr archive 3 , +.Xr elf 3 , +.Xr elftc_bfd_find_target 3 , +.Xr dwarf 3 +.Sh IMPLEMENTATION NOTES +The +.Nm +utility differs from its GNU equivalent in the following: +.Bl -bullet +.It +The +.Nm +utility currently supports a limited range of output formats. +.It +The +.Fl e +and +.Fl -entry +options only accept a symbol name as an argument, and not a numeric +address. +.It +The +.Fl l +option only searches files in the directories specified by +prior +.Fl L +options. +.It +The +.Fl T | Fl -script +option does not search for script files in the directories specified +by prior +.Fl L +options. +.It +The +.Fl -rpath +option accepts a colon-separated list of directories instead of +single directory. +.El +.Pp +The following options are recognized, but are currently unimplemented: +.Fl Bgroup , +.Fl Bsymbolic , +.Fl Bsymbolic_functions , +.Fl E , +.Fl EB , +.Fl EL , +.Fl F , +.Fl Map , +.Fl N , +.Fl O , +.Fl Qy , +.Fl R , +.Fl S , +.Fl Tbss , +.Fl Tdata , +.Fl Ttext , +.Fl X , +.Fl Y , +.Fl Ur , +.Fl c , +.Fl f , +.Fl g , +.Fl i , +.Fl m , +.Fl n , +.Fl s , +.Fl t , +.Fl x , +.Fl y , +.Fl -accept-unknown-input-arch , +.Fl -allow-multiple-definition , +.Fl -allow-shlib-undefined , +.Fl -assert , +.Fl -auxiliary , +.Fl -build-id , +.Fl -check-sections , +.Fl -cref , +.Fl -defsym , +.Fl -demangle , +.Fl -disable-new-dtags , +.Fl -discard-all , +.Fl -discard-locals , +.Fl -error-unresolved-symbols , +.Fl -export-dynamic , +.Fl -emulation , +.Fl -enable-new-dtags , +.Fl -fatal-warnings , +.Fl -filter , +.Fl -fini , +.Fl -hash-style , +.Fl -help , +.Fl -init , +.Fl -just-symbols , +.Fl -mri-script , +.Fl -nmagic , +.Fl nostdlib , +.Fl -no-accept-unknown-input-arch , +.Fl -no-allow-shlib-undefined , +.Fl -no-assert , +.Fl -no-check-sections , +.Fl -no-demangle , +.Fl -no-keep-memory , +.Fl -no-omagic , +.Fl -no-undefined , +.Fl -no-undefined-version , +.Fl -no-warn-mismatch , +.Fl -omagic , +.Fl -qmagic , +.Fl -relax , +.Fl -retain-symbols-file , +.Fl -runpath , +.Fl -section-start , +.Fl -sort-common , +.Fl -split-by-file , +.Fl -split-by-reloc , +.Fl -stats , +.Fl -strip-all , +.Fl -strip-debug , +.Fl -trace , +.Fl -trace_symbol , +.Fl -traditional-format , +.Fl -unique , +.Fl -unresolved-symbols , +.Fl -verbose , +.Fl -warn-common , +.Fl -warn-constructors , +.Fl -warn-multiple-gp , +.Fl -warn-once , +.Fl -warn-section-align , +.Fl -warn-shared-textrel , +.Fl -warn-unresolved-symbols , +.Fl -wrap . +.Pp +The following keywords are recognized by the +.Fl z +option, but are currently unimplemented: +.Cm allextract , +.Cm defaultextract , +.Cm defs , +.Cm ignore , +.Cm initfirst , +.Cm lazyload , +.Cm muldefs , +.Cm nodefaultlib , +.Cm nodefs , +.Cm nodelete , +.Cm nodlopen , +.Cm nolazyload , +.Cm now , +.Cm origin , +.Cm record , +.Cm systemlibrary , +.Cm weakextract . +.Sh HISTORY +A +.Nm +command first appeared in AT&T UNIX Version 1. +.Pp +The Elftoolchain implementation of +.Nm +was written by +.An Kai Wang Aq Mt kaiwang27@gmail.com . diff --git a/contrib/elftoolchain/ld/ld.h b/contrib/elftoolchain/ld/ld.h new file mode 100644 index 0000000000..3ed3ae6247 --- /dev/null +++ b/contrib/elftoolchain/ld/ld.h @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld.h 3870 2020-06-27 22:21:26Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dwarf.h" +#define utarray_oom() ld_fatal(ld, "out of memory") +#include "utarray.h" +#define uthash_fatal(msg) ld_fatal(ld, msg) +#include "uthash.h" +#include "_elftc.h" + +struct ld_file; +struct ld_input_section_head; +struct ld_path; +struct ld_symbol; +struct ld_symbol_head; +struct ld_output_data_buffer; +struct ld_wildcard_match; +struct ld_ehframe_cie_head; +struct ld_ehframe_fde_head; +struct ld_section_group; + +#define LD_MAX_NESTED_GROUP 16 + +struct ld_state { + Elftc_Bfd_Target *ls_itgt; /* input bfd target set by -b */ + struct ld_file *ls_file; /* current open file */ + unsigned ls_static; /* use static library */ + unsigned ls_whole_archive; /* include whole archive */ + unsigned ls_as_needed; /* DT_NEEDED */ + unsigned ls_group_level; /* archive group level */ + unsigned ls_extracted[LD_MAX_NESTED_GROUP + 1]; + /* extracted from archive group */ + unsigned ls_search_dir; /* search library directories */ + uint64_t ls_loc_counter; /* location counter */ + uint64_t ls_offset; /* cur. output section file offset */ + STAILQ_HEAD(, ld_path) ls_lplist; /* search path list */ + STAILQ_HEAD(, ld_path) ls_rplist; /* rpath list */ + STAILQ_HEAD(, ld_path) ls_rllist; /* rpath-link list */ + unsigned ls_arch_conflict; /* input arch conflict with output */ + unsigned ls_first_elf_object; /* first ELF object to process */ + unsigned ls_rerun; /* ld(1) restarted */ + unsigned ls_archive_mb_header; /* extracted list header printed */ + unsigned ls_first_output_sec; /* flag indicates 1st output section */ + unsigned ls_ignore_next_plt; /* ignore next PLT relocation */ + unsigned ls_version_local; /* version entry is local */ + uint64_t ls_relative_reloc; /* number of *_RELATIVE relocations */ + struct ld_input_section_head *ls_gc; + /* garbage collection search list */ +}; + +struct ld { + const char *ld_progname; /* ld(1) program name */ + struct ld_arch *ld_arch; /* arch-specific callbacks */ + struct ld_arch *ld_arch_list; /* list of supported archs */ + Elftc_Bfd_Target *ld_otgt; /* default output format */ + Elftc_Bfd_Target *ld_otgt_be; /* big-endian output format */ + Elftc_Bfd_Target *ld_otgt_le; /* little-endian output format */ + char *ld_otgt_name; /* output format name */ + char *ld_otgt_be_name; /* big-endian output format name */ + char *ld_otgt_le_name; /* little-endian output format name */ + struct ld_output *ld_output; /* output object */ + char *ld_output_file; /* output file name */ + char *ld_entry; /* entry point set by -e */ + char *ld_scp_entry; /* entry point set by linker script */ + char *ld_interp; /* dynamic linker */ + char *ld_soname; /* DT_SONAME */ + struct ld_script *ld_scp; /* linker script */ + struct ld_state ld_state; /* linker state */ + struct ld_strtab *ld_shstrtab; /* section name table */ + struct ld_symbol_head *ld_ext_symbols; /* -u/EXTERN symbols */ + struct ld_symbol_head *ld_var_symbols; /* ldscript var symbols */ + struct ld_symbol *ld_sym; /* internal symbol table */ + struct ld_symbol *ld_symtab_import; /* hash for import symbols */ + struct ld_symbol *ld_symtab_export; /* hash for export symbols */ + struct ld_symbol_defver *ld_defver; /* default version table */ + struct ld_symbol_table *ld_symtab; /* .symtab symbol table */ + struct ld_strtab *ld_strtab; /* .strtab string table */ + struct ld_symbol_table *ld_dynsym; /* .dynsym symbol table */ + struct ld_strtab *ld_dynstr; /* .dynstr string table */ + struct ld_symbol_head *ld_dyn_symbols; /* dynamic symbol list */ + struct ld_wildcard_match *ld_wm; /* wildcard hash table */ + struct ld_input_section *ld_dynbss; /* .dynbss section */ + struct ld_input_section *ld_got; /* .got section */ + struct ld_ehframe_cie_head *ld_cie; /* ehframe CIE list */ + struct ld_ehframe_fde_head *ld_fde; /* ehframe FDE list */ + struct ld_section_group *ld_sg; /* included section groups */ + unsigned char ld_common_alloc; /* always alloc space for common sym */ + unsigned char ld_common_no_alloc; /* never alloc space for common sym */ + unsigned char ld_emit_reloc; /* emit relocations */ + unsigned char ld_gen_gnustack; /* generate PT_GNUSTACK */ + unsigned char ld_print_linkmap; /* print link map */ + unsigned char ld_stack_exec; /* stack executable */ + unsigned char ld_stack_exec_set; /* stack executable override */ + unsigned char ld_exec; /* output normal executable */ + unsigned char ld_pie; /* position-independent executable */ + unsigned char ld_dso; /* output shared library */ + unsigned char ld_reloc; /* output relocatable object */ + unsigned char ld_dynamic_link; /* perform dynamic linking */ + unsigned char ld_print_version; /* linker version printed */ + unsigned char ld_gc; /* perform garbage collection */ + unsigned char ld_gc_print; /* print removed sections */ + unsigned char ld_ehframe_hdr; /* create .eh_frame_hdr section */ + STAILQ_HEAD(ld_input_head, ld_input) ld_lilist; /* input object list */ + TAILQ_HEAD(ld_file_head, ld_file) ld_lflist; /* input file list */ +}; + +void ld_err(struct ld *, const char *, ...); +void ld_fatal(struct ld *, const char *, ...); +void ld_fatal_std(struct ld *, const char *, ...); +void ld_warn(struct ld *, const char *, ...); +void ld_info(struct ld *, const char *, ...); diff --git a/contrib/elftoolchain/ld/ld_arch.c b/contrib/elftoolchain/ld/ld_arch.c new file mode 100644 index 0000000000..186beea7cb --- /dev/null +++ b/contrib/elftoolchain/ld/ld_arch.c @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 2011,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "i386.h" +#include "amd64.h" +#include "mips.h" + +ELFTC_VCSID("$Id: ld_arch.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); + +#define LD_DEFAULT_ARCH "amd64" + +static struct ld_arch *_get_arch_from_target(struct ld *ld, char *target); + +void +ld_arch_init(struct ld *ld) +{ + char *end; + char arch[MAX_ARCH_NAME_LEN + 1], target[MAX_TARGET_NAME_LEN + 1]; + size_t len; + + /* + * Register supported architectures. + */ + + i386_register(ld); + amd64_register(ld); + mips_register(ld); + + /* + * Find out default arch for output object. + */ + + if ((end = strrchr(ld->ld_progname, '-')) != NULL && + end != ld->ld_progname) { + len = end - ld->ld_progname + 1; + if (len > MAX_TARGET_NAME_LEN) + return; + strncpy(target, ld->ld_progname, len); + target[len] = '\0'; + ld->ld_arch = _get_arch_from_target(ld, target); + } + + if (ld->ld_arch == NULL) { + snprintf(arch, sizeof(arch), "%s", LD_DEFAULT_ARCH); + ld->ld_arch = ld_arch_find(ld, arch); + if (ld->ld_arch == NULL) + ld_fatal(ld, "Internal: could not determine output" + " object architecture"); + } +} + +void +ld_arch_set(struct ld *ld, char *arch) +{ + + ld->ld_arch = ld_arch_find(ld, arch); + if (ld->ld_arch == NULL) + ld_fatal(ld, "arch '%s' is not supported", arch); +} + +void +ld_arch_set_from_target(struct ld *ld) +{ + + if (ld->ld_otgt != NULL) { + ld->ld_arch = _get_arch_from_target(ld, ld->ld_otgt_name); + if (ld->ld_arch == NULL) + ld_fatal(ld, "target '%s' is not supported", + ld->ld_otgt_name); + } +} + +int +ld_arch_equal(struct ld_arch *a1, struct ld_arch *a2) +{ + + assert(a1 != NULL && a2 != NULL); + + if (a1 == a2) + return (1); + + if (a1->alias == a2 || a2->alias == a1) + return (1); + + if (a1->alias != NULL && a1->alias == a2->alias) + return (1); + + return (0); +} + +void +ld_arch_verify(struct ld *ld, const char *name, int mach, int endian, + unsigned flags) +{ + struct ld_arch *la; + struct ld_state *ls; + + assert(ld->ld_arch != NULL); + ls = &ld->ld_state; + + if ((la = ld_arch_guess_arch_name(ld, mach, endian)) == NULL) + ld_fatal(ld, "%s: ELF object architecture %#x not supported", + name, mach); + + if (!ld_arch_equal(la, ld->ld_arch)) { + ls->ls_arch_conflict = 1; + if (ls->ls_rerun || !ls->ls_first_elf_object) + ld_fatal(ld, "%s: ELF object architecture `%s' " + "conflicts with output object architecture `%s'", + name, la->name, ld->ld_arch->name); + ld->ld_arch = la; + } + + if (ls->ls_first_elf_object) { + la->flags = flags; + } else if (la->merge_flags) { + la->merge_flags(ld, flags); + } + + ls->ls_first_elf_object = 0; +} + +struct ld_arch * +ld_arch_guess_arch_name(struct ld *ld, int mach, int endian) +{ + char arch[MAX_ARCH_NAME_LEN + 1]; + + /* TODO: we should also consider elf class and endianess. */ + + switch (mach) { + case EM_386: + snprintf(arch, sizeof(arch), "%s", "i386"); + break; + case EM_ARM: + snprintf(arch, sizeof(arch), "%s", "arm"); + break; + case EM_MIPS: + case EM_MIPS_RS3_LE: + snprintf(arch, sizeof(arch), "%s", + endian==ELFDATA2MSB ? "bigmips" : "littlemips"); + break; + case EM_PPC: + case EM_PPC64: + snprintf(arch, sizeof(arch), "%s", "ppc"); + break; + case EM_SPARC: + case EM_SPARCV9: + snprintf(arch, sizeof(arch), "%s", "sparc"); + break; + case EM_X86_64: + snprintf(arch, sizeof(arch), "%s", "amd64"); + break; + default: + return (NULL); + } + + return (ld_arch_find(ld, arch)); +} + +static struct ld_arch * +_get_arch_from_target(struct ld *ld, char *target) +{ + struct ld_arch *la; + char *begin, *end, name[MAX_TARGET_NAME_LEN + 1]; + + if ((begin = strchr(target, '-')) == NULL) { + la = ld_arch_find(ld, target); + return (la); + } + la = ld_arch_find(ld, begin + 1); + if (la != NULL) + return (la); + + strncpy(name, begin + 1, sizeof(name) - 1); + name[sizeof(name) - 1] = '\0'; + while ((end = strrchr(name, '-')) != NULL) { + *end = '\0'; + la = ld_arch_find(ld, name); + if (la != NULL) + return (la); + } + + return (NULL); +} + +struct ld_arch * +ld_arch_find(struct ld *ld, char *arch) +{ + struct ld_arch *la; + + HASH_FIND_STR(ld->ld_arch_list, arch, la); + + return (la); +} diff --git a/contrib/elftoolchain/ld/ld_arch.h b/contrib/elftoolchain/ld/ld_arch.h new file mode 100644 index 0000000000..2165627d68 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_arch.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2011,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_arch.h 3281 2015-12-11 21:39:23Z kaiwang27 $ + */ + +#define MAX_ARCH_NAME_LEN 64 +#define MAX_TARGET_NAME_LEN 128 + +struct ld_input_section; +struct ld_reloc_entry; + +struct ld_arch { + char name[MAX_ARCH_NAME_LEN + 1]; + char *script; + const char *interp; + uint64_t (*get_max_page_size)(struct ld *); + uint64_t (*get_common_page_size)(struct ld *); + void (*scan_reloc)(struct ld *, struct ld_input_section *, + struct ld_reloc_entry *); + void (*adjust_reloc)(struct ld *, struct ld_input_section *, + struct ld_reloc_entry *, struct ld_symbol *, uint8_t *); + void (*process_reloc)(struct ld *, struct ld_input_section *, + struct ld_reloc_entry *, struct ld_symbol *, uint8_t *); + void (*finalize_reloc)(struct ld *, struct ld_input_section *, + struct ld_reloc_entry *); + void (*finalize_got_and_plt)(struct ld *); + void (*merge_flags)(struct ld *, unsigned flags); + int (*is_absolute_reloc)(uint64_t); + int (*is_relative_reloc)(uint64_t); + unsigned char reloc_is_64bit; + unsigned char reloc_is_rela; + size_t reloc_entsize; + unsigned flags; /* processor-specific flags */ + UT_hash_handle hh; + struct ld_arch *alias; +}; + +void ld_arch_init(struct ld *); +int ld_arch_equal(struct ld_arch *, struct ld_arch *); +struct ld_arch *ld_arch_find(struct ld *, char *); +struct ld_arch *ld_arch_guess_arch_name(struct ld *, int, int); +void ld_arch_set(struct ld *, char *); +void ld_arch_set_from_target(struct ld *); +void ld_arch_verify(struct ld *, const char *, int, int, unsigned); diff --git a/contrib/elftoolchain/ld/ld_dynamic.c b/contrib/elftoolchain/ld/ld_dynamic.c new file mode 100644 index 0000000000..efc052790a --- /dev/null +++ b/contrib/elftoolchain/ld/ld_dynamic.c @@ -0,0 +1,610 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_file.h" +#include "ld_hash.h" +#include "ld_input.h" +#include "ld_layout.h" +#include "ld_output.h" +#include "ld_path.h" +#include "ld_symbols.h" +#include "ld_symver.h" +#include "ld_strtab.h" + +ELFTC_VCSID("$Id: ld_dynamic.c 3812 2020-02-07 02:18:26Z emaste $"); + +static void _check_dso_needed(struct ld *ld, struct ld_output *lo); +static void _create_dynamic(struct ld *ld, struct ld_output *lo); +static void _create_interp(struct ld *ld, struct ld_output *lo); +static void _create_dynsym_and_dynstr_section(struct ld *ld, + struct ld_output *lo); +static void _finalize_dynamic(struct ld *ld, struct ld_output *lo); + +void +ld_dynamic_create(struct ld *ld) +{ + struct ld_output *lo; + + lo = ld->ld_output; + assert(lo != NULL); + + /* Check how many DSOs is needed for output object. */ + _check_dso_needed(ld, lo); + + /* Link statically if we don't use DSOs? */ + if (lo->lo_dso_needed == 0) + return; + + ld->ld_dynamic_link = 1; + + /* Create .interp section. */ + if (!ld->ld_dso) + _create_interp(ld, lo); + + /* Create .dynamic section. */ + _create_dynamic(ld, lo); + + /* Create .dynsym and .dynstr sections. */ + _create_dynsym_and_dynstr_section(ld, lo); + + /* Create .hash section. */ + ld_hash_create_svr4_hash_section(ld); + + /* + * Create .gnu.version_d section if the linker creats a shared + * library and version script is provided. + */ + lo->lo_version_index = 2; + if (ld->ld_dso) + ld_symver_create_verdef_section(ld); + + /* Create .gnu.version_r section. */ + ld_symver_create_verneed_section(ld); + + /* Create .gnu.version section. */ + ld_symver_create_versym_section(ld); +} + +void +ld_dynamic_finalize(struct ld *ld) +{ + struct ld_output *lo; + + lo = ld->ld_output; + assert(lo != NULL); + + if (lo->lo_dso_needed == 0) + return; + + /* Finalize .dynamic section */ + _finalize_dynamic(ld, lo); +} + +void +ld_dynamic_load_dso_dynamic(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *scn, size_t strndx) +{ + GElf_Shdr shdr; + GElf_Dyn dyn; + Elf_Data *d; + int elferr, i, len; + const char *name; + + if (strndx == SHN_UNDEF) + return; + + if (gelf_getshdr(scn, &shdr) != &shdr) { + ld_warn(ld, "%s: gelf_getshdr failed: %s", li->li_name, + elf_errmsg(-1)); + return; + } + + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s: elf_getdata failed: %s", li->li_name, + elf_errmsg(elferr)); + return; + } + + len = d->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getdyn(d, i, &dyn) != &dyn) { + ld_warn(ld, "%s: gelf_getdyn failed: %s", li->li_name, + elf_errmsg(-1)); + continue; + } + switch (dyn.d_tag) { + case DT_SONAME: + name = elf_strptr(e, strndx, dyn.d_un.d_ptr); + if (name != NULL && + (li->li_soname = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + break; + case DT_NEEDED: + name = elf_strptr(e, strndx, dyn.d_un.d_ptr); + if (name != NULL) + ld_path_search_dso_needed(ld, li->li_file, + name); + break; + default: + break; + } + } +} + +void +ld_dynamic_reserve_dynbss_entry(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input *li; + struct ld_input_section *dynbss, *is; + uint64_t a; + + /* Create .dynbss section if it doesn't yet exist. */ + dynbss = ld_input_find_internal_section(ld, ".dynbss"); + if (dynbss == NULL) { + dynbss = ld_input_add_internal_section(ld, ".dynbss"); + dynbss->is_type = SHT_NOBITS; + } + + li = lsb->lsb_input; + assert(li != NULL && li->li_type == LIT_DSO); + + /* + * TODO: we don't have to create copy relocation + * for every import object. Some import objects + * are read-only, in that case we can create other + * dynamic relocations for them. + */ + + /* + * If the section to which the symbols belong has a larger + * alignment requirement, we increase .dynbss section alignment + * accordingly. XXX What if it is a DSO common symbol? + */ + is = NULL; + if (lsb->lsb_shndx != SHN_COMMON) { + assert(lsb->lsb_shndx < li->li_shnum - 1); + is = &li->li_is[lsb->lsb_shndx]; + if (is->is_align > dynbss->is_align) + dynbss->is_align = is->is_align; + } + + /* + * Calculate the alignment for this object. + */ + if (is != NULL) { + for (a = is->is_align; a > 1; a >>= 1) { + if ((lsb->lsb_value - is->is_off) % a == 0) + break; + } + } else + a = 1; + + if (a > 1) + dynbss->is_size = roundup(dynbss->is_size, a); + + lsb->lsb_value = dynbss->is_size; + lsb->lsb_copy_reloc = 1; + lsb->lsb_input = dynbss->is_input; + lsb->lsb_shndx = dynbss->is_index; + lsb->lsb_is = dynbss; + + dynbss->is_size += lsb->lsb_size; +} + +static void +_create_interp(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os; + struct ld_output_data_buffer *odb; + const char *interp; + char interp_name[] = ".interp"; + + HASH_FIND_STR(lo->lo_ostbl, interp_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, interp_name, + SHF_ALLOC); + os->os_type = SHT_PROGBITS; + os->os_align = 1; + os->os_entsize = 0; + os->os_flags = SHF_ALLOC; + + lo->lo_interp = os; + + if (ld->ld_interp != NULL) + interp = ld->ld_interp; + else + interp = ld->ld_arch->interp; + assert(interp != NULL); + + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + odb->odb_size = strlen(interp) + 1; + odb->odb_align = 1; + odb->odb_type = ELF_T_BYTE; + + if ((odb->odb_buf = calloc(odb->odb_size, 1)) == NULL) + ld_fatal_std(ld, "calloc"); + memcpy(odb->odb_buf, interp, strlen(interp)); + odb->odb_buf[strlen(interp)] = '\0'; + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, odb, + NULL); +} + +static void +_create_dynamic(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os, *_os; + struct ld_output_data_buffer *odb; + char dynamic_name[] = ".dynamic"; + char init_name[] = ".init"; + char fini_name[] = ".fini"; + char *rpath; + int entries; + + HASH_FIND_STR(lo->lo_ostbl, dynamic_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, dynamic_name, + SHF_ALLOC | SHF_WRITE); + os->os_type = SHT_DYNAMIC; + os->os_flags = SHF_ALLOC | SHF_WRITE; + if (lo->lo_ec == ELFCLASS32) { + os->os_entsize = 8; + os->os_align = 4; + } else { + os->os_entsize = 16; + os->os_align = 8; + } + + lo->lo_dynamic = os; + + /* .dynamic section should link to .dynstr section. */ + if ((os->os_link = strdup(".dynstr")) == NULL) + ld_fatal_std(ld, "strdup"); + + /* DT_NEEDED */ + entries = lo->lo_dso_needed; + + /* DT_SONAME. */ + if (ld->ld_soname != NULL) { + lo->lo_soname_nameindex = ld_strtab_insert_no_suffix(ld, + ld->ld_dynstr, ld->ld_soname); + entries++; + } + + /* DT_INIT */ + HASH_FIND_STR(lo->lo_ostbl, init_name, _os); + if (_os != NULL && !_os->os_empty) { + lo->lo_init = _os; + entries++; + } + + /* DT_FINI */ + HASH_FIND_STR(lo->lo_ostbl, fini_name, _os); + if (_os != NULL && !_os->os_empty) { + lo->lo_fini = _os; + entries++; + } + + /* DT_HASH, DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT */ + if (ld->ld_dynsym) + entries += 5; + + /* DT_RPATH. */ + if (!STAILQ_EMPTY(&ld->ld_state.ls_rplist)) { + rpath = ld_path_join_rpath(ld); + lo->lo_rpath_nameindex = ld_strtab_insert_no_suffix(ld, + ld->ld_dynstr, rpath); + entries++; + } + + /* + * DT_DEBUG. dynamic linker changes this at runtime, gdb uses + * it to find all the loaded DSOs. (thus .dynamic has to be + * writable) + */ + if (!ld->ld_dso) + entries++; + + /* DT_PLTGOT, DT_PLTRELSZ, DT_PLTREL and DT_JMPREL. */ + entries += 4; + + /* DT_REL/DT_RELA, DT_RELSZ/DT_RELASZ and DT_RELENT/DT_RELAENT */ + entries += 3; + + /* + * DT_VERNEED, DT_VERNEEDNUM, DT_VERDEF, DT_VERDEFNUM and DT_VERSYM. + */ + entries += 5; + + /* DT_RELCOUNT/DT_RELACOUNT. */ + if (ld->ld_state.ls_relative_reloc > 0) + entries++; + + /* DT_NULL. TODO: Reserve multiple DT_NULL entries for DT_RPATH? */ + entries++; + + /* + * Reserve space for .dynamic section, based on number of entries. + */ + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + odb->odb_size = entries * os->os_entsize; + if ((odb->odb_buf = malloc(odb->odb_size)) == NULL) + ld_fatal_std(ld, "malloc"); + odb->odb_align = os->os_align; + odb->odb_type = ELF_T_DYN; + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, odb, + NULL); + + lo->lo_dynamic_odb = odb; + + /* Create _DYNAMIC symobl. */ + ld_symbols_add_internal(ld, "_DYNAMIC", 0, 0, SHN_ABS, STB_LOCAL, + STT_OBJECT, STV_HIDDEN, NULL, os); +} + +#define DT_ENTRY_VAL(tag,val) \ + do { \ + if (lo->lo_ec == ELFCLASS32) { \ + assert(dt32 < end32); \ + dt32->d_tag = (int32_t) (tag); \ + dt32->d_un.d_val = (uint32_t) (val); \ + dt32++; \ + } else { \ + assert(dt64 < end64); \ + dt64->d_tag = (tag); \ + dt64->d_un.d_val = (val); \ + dt64++; \ + } \ + } while(0) + +#define DT_ENTRY_PTR(tag,ptr) \ + do { \ + if (lo->lo_ec == ELFCLASS32) { \ + assert(dt32 < end32); \ + dt32->d_tag = (int32_t) (tag); \ + dt32->d_un.d_ptr = (uint32_t) (ptr); \ + dt32++; \ + } else { \ + assert(dt64 < end64); \ + dt64->d_tag = (tag); \ + dt64->d_un.d_ptr = (ptr); \ + dt64++; \ + } \ + } while(0) + +#define DT_ENTRY_NULL \ + do { \ + if (lo->lo_ec == ELFCLASS32) { \ + assert(dt32 < end32); \ + while (dt32 < end32) \ + DT_ENTRY_VAL(DT_NULL, 0); \ + assert(dt32 == end32); \ + } else { \ + assert(dt64 < end64); \ + while (dt64 < end64) \ + DT_ENTRY_VAL(DT_NULL, 0); \ + assert(dt64 == end64); \ + } \ + } while(0) + +static void +_finalize_dynamic(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_data_buffer *odb; + Elf32_Dyn *dt32, *end32; + Elf64_Dyn *dt64, *end64; + int *p; + + odb = lo->lo_dynamic_odb; + assert(odb != NULL); + + dt32 = (Elf32_Dyn *) (uintptr_t) odb->odb_buf; + dt64 = (Elf64_Dyn *) (uintptr_t) odb->odb_buf; + end32 = (Elf32_Dyn *) (uintptr_t) (odb->odb_buf + odb->odb_size); + end64 = (Elf64_Dyn *) (uintptr_t) (odb->odb_buf + odb->odb_size); + + /* DT_NEEDED. */ + for (p = (int *) (uintptr_t) utarray_front(lo->lo_dso_nameindex); + p != NULL; + p = (int *) (uintptr_t) utarray_next(lo->lo_dso_nameindex, p)) + DT_ENTRY_VAL(DT_NEEDED, *p); + + /* DT_SONAME. */ + if (ld->ld_soname != NULL) + DT_ENTRY_VAL(DT_SONAME, lo->lo_soname_nameindex); + + /* DT_INIT and DT_FINI */ + if (lo->lo_init != NULL) + DT_ENTRY_PTR(DT_INIT, lo->lo_init->os_addr); + if (lo->lo_fini != NULL) + DT_ENTRY_PTR(DT_FINI, lo->lo_fini->os_addr); + + /* DT_HASH */ + if (lo->lo_hash != NULL) + DT_ENTRY_PTR(DT_HASH, lo->lo_hash->os_addr); + + /* DT_HASH, DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT */ + if (lo->lo_dynsym != NULL && lo->lo_dynstr != NULL) { + DT_ENTRY_PTR(DT_STRTAB, lo->lo_dynstr->os_addr); + DT_ENTRY_PTR(DT_SYMTAB, lo->lo_dynsym->os_addr); + DT_ENTRY_VAL(DT_STRSZ, ld_strtab_getsize(ld->ld_dynstr)); + DT_ENTRY_VAL(DT_SYMENT, + lo->lo_ec == ELFCLASS32 ? sizeof(Elf32_Sym) : + sizeof(Elf64_Sym)); + } + + /* DT_RPATH */ + if (!STAILQ_EMPTY(&ld->ld_state.ls_rplist)) + DT_ENTRY_VAL(DT_RPATH, lo->lo_rpath_nameindex); + + /* DT_DEBUG */ + if (!ld->ld_dso) + DT_ENTRY_VAL(DT_DEBUG, 0); + + /* DT_PLTGOT, DT_PLTRELSZ, DT_PLTREL and DT_JMPREL. */ + if (lo->lo_gotplt != NULL) + DT_ENTRY_PTR(DT_PLTGOT, lo->lo_gotplt->os_addr); + if (lo->lo_rel_plt != NULL) { + DT_ENTRY_VAL(DT_PLTRELSZ, lo->lo_rel_plt->os_size); + DT_ENTRY_VAL(DT_PLTREL, + ld->ld_arch->reloc_is_rela ? DT_RELA : DT_REL); + DT_ENTRY_PTR(DT_JMPREL, lo->lo_rel_plt->os_addr); + } + + /* DT_REL/DT_RELA, DT_RELSZ/DT_RELASZ and DT_RELENT/DT_RELAENT */ + if (lo->lo_rel_dyn != NULL) { + if (!ld->ld_arch->reloc_is_rela) { + DT_ENTRY_PTR(DT_REL, lo->lo_rel_dyn->os_addr); + DT_ENTRY_VAL(DT_RELSZ, lo->lo_rel_dyn->os_size); + DT_ENTRY_VAL(DT_RELENT, ld->ld_arch->reloc_entsize); + } else { + DT_ENTRY_PTR(DT_RELA, lo->lo_rel_dyn->os_addr); + DT_ENTRY_VAL(DT_RELASZ, lo->lo_rel_dyn->os_size); + DT_ENTRY_VAL(DT_RELAENT, ld->ld_arch->reloc_entsize); + } + } + + /* + * DT_VERNEED, DT_VERNEEDNUM, DT_VERDEF, DT_VERDEFNUM and + * DT_VERSYM. + */ + if (lo->lo_verdef != NULL) { + DT_ENTRY_PTR(DT_VERDEF, lo->lo_verdef->os_addr); + DT_ENTRY_VAL(DT_VERDEFNUM, lo->lo_verdef_num); + } + if (lo->lo_verneed != NULL) { + DT_ENTRY_PTR(DT_VERNEED, lo->lo_verneed->os_addr); + DT_ENTRY_VAL(DT_VERNEEDNUM, lo->lo_verneed_num); + } + if (lo->lo_versym != NULL) + DT_ENTRY_PTR(DT_VERSYM, lo->lo_versym->os_addr); + + /* DT_RELCOUNT/DT_RELACOUNT. */ + if (ld->ld_state.ls_relative_reloc > 0) + DT_ENTRY_VAL(ld->ld_arch->reloc_is_rela ? DT_RELACOUNT : + DT_RELCOUNT, ld->ld_state.ls_relative_reloc); + + /* Fill in the space left with DT_NULL entries */ + DT_ENTRY_NULL; +} + +static void +_create_dynsym_and_dynstr_section(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os; + char dynsym_name[] = ".dynsym"; + char dynstr_name[] = ".dynstr"; + + /* + * Create .dynsym section. + */ + + HASH_FIND_STR(lo->lo_ostbl, dynsym_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, dynsym_name, + SHF_ALLOC); + os->os_type = SHT_DYNSYM; + os->os_flags = SHF_ALLOC; + if (lo->lo_ec == ELFCLASS32) { + os->os_entsize = sizeof(Elf32_Sym); + os->os_align = 4; + } else { + os->os_entsize = sizeof(Elf64_Sym); + os->os_align = 8; + } + lo->lo_dynsym = os; + + (void) ld_output_create_section_element(ld, os, OET_SYMTAB, + ld->ld_dynsym, NULL); + + /* + * Create .dynstr section. + */ + + HASH_FIND_STR(lo->lo_ostbl, dynstr_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, dynstr_name, + SHF_ALLOC); + os->os_type = SHT_STRTAB; + os->os_flags = SHF_ALLOC; + os->os_entsize = 0; + os->os_align = 1; + lo->lo_dynstr = os; + + (void) ld_output_create_section_element(ld, os, OET_STRTAB, + ld->ld_dynstr, NULL); + + if ((lo->lo_dynsym->os_link = strdup(".dynstr")) == NULL) + ld_fatal_std(ld, "strdup"); +} + +static void +_check_dso_needed(struct ld *ld, struct ld_output *lo) +{ + struct ld_input *li; + char *bn; + int ndx; + + lo->lo_dso_needed = 0; + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + if (li->li_type != LIT_DSO) + continue; + + if (li->li_dso_refcnt > 0 || !li->li_file->lf_as_needed) { + lo->lo_dso_needed++; + + if (ld->ld_dynstr == NULL) + ld->ld_dynstr = ld_strtab_alloc(ld, 0); + + /* Insert DSO name to the .dynstr string table. */ + if (li->li_soname != NULL) + bn = li->li_soname; + else { + if ((bn = strrchr(li->li_name, '/')) == NULL) + bn = li->li_name; + else + bn++; + } + ndx = ld_strtab_insert_no_suffix(ld, ld->ld_dynstr, + bn); + + /* Save the generated name index for later use. */ + if (lo->lo_dso_nameindex == NULL) + utarray_new(lo->lo_dso_nameindex, &ut_int_icd); + utarray_push_back(lo->lo_dso_nameindex, &ndx); + } + } +} diff --git a/contrib/elftoolchain/ld/ld_dynamic.h b/contrib/elftoolchain/ld/ld_dynamic.h new file mode 100644 index 0000000000..3a98dfcac0 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_dynamic.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_dynamic.h 2784 2012-12-15 19:19:48Z kaiwang27 $ + */ + +void ld_dynamic_create(struct ld *); +void ld_dynamic_finalize(struct ld *); +void ld_dynamic_load_dso_dynamic(struct ld *, struct ld_input *, Elf *, + Elf_Scn *, size_t); +void ld_dynamic_create_copy_reloc(struct ld *); +void ld_dynamic_reserve_dynbss_entry(struct ld *, struct ld_symbol *); diff --git a/contrib/elftoolchain/ld/ld_ehframe.c b/contrib/elftoolchain/ld/ld_ehframe.c new file mode 100644 index 0000000000..e2a043bfa9 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_ehframe.c @@ -0,0 +1,770 @@ +/*- + * Copyright (c) 2009-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_ehframe.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_utils.h" + +ELFTC_VCSID("$Id: ld_ehframe.c 3885 2020-11-11 18:54:22Z jkoshy $"); + +struct ld_ehframe_cie { + uint64_t cie_off; /* offset in section */ + uint64_t cie_off_orig; /* orignial offset (before optimze) */ + uint64_t cie_size; /* CIE size (include length field) */ + uint8_t *cie_content; /* CIE content */ + uint8_t cie_fde_encode; /* FDE PC start/range encode. */ + struct ld_ehframe_cie *cie_dup; /* duplicate entry */ + STAILQ_ENTRY(ld_ehframe_cie) cie_next; +}; + +STAILQ_HEAD(ld_ehframe_cie_head, ld_ehframe_cie); + +struct ld_ehframe_fde { + struct ld_ehframe_cie *fde_cie; /* associated CIE */ + uint64_t fde_off; /* offset in section */ + uint64_t fde_off_pcbegin; /* section offset of "PC Begin" field */ + int32_t fde_pcrel; /* relative offset to "PC Begin" */ + int32_t fde_datarel; /* relative offset to FDE entry */ + STAILQ_ENTRY(ld_ehframe_fde) fde_next; +}; + +STAILQ_HEAD(ld_ehframe_fde_head, ld_ehframe_fde); + +static int64_t _decode_sleb128(uint8_t **dp); +static uint64_t _decode_uleb128(uint8_t **dp); +static void _process_ehframe_section(struct ld *ld, struct ld_output *lo, + struct ld_input_section *is); +static int _read_encoded(struct ld *ld, struct ld_output *lo, uint64_t *val, + uint8_t *data, uint8_t encode, uint64_t pc); +static int _cmp_fde(struct ld_ehframe_fde *a, struct ld_ehframe_fde *b); + +void +ld_ehframe_adjust(struct ld *ld, struct ld_input_section *is) +{ + struct ld_output *lo; + uint8_t *p, *d, *end, *s; + uint64_t length, length_size, remain, adjust; + uint32_t cie_id; + + lo = ld->ld_output; + assert(lo != NULL); + + /* + * If the .eh_frame section is unchanged, we don't need to + * do much. + */ + assert(is->is_ehframe != NULL); + if (is->is_shrink == 0) { + is->is_ehframe = NULL; + return; + } + + /* + * Otherwise the section is shrinked becase some FDE's are + * discarded. We copy the section content to a buffer while + * skipping those discarded FDE's. + */ + + if ((is->is_ibuf = malloc(is->is_size - is->is_shrink)) == NULL) + ld_fatal_std(ld, "malloc"); + d = is->is_ibuf; + end = d + is->is_size - is->is_shrink; + p = is->is_ehframe; + adjust = 0; + remain = is->is_size; + while (remain > 0) { + + s = p; + + /* Read CIE/FDE length field. */ + READ_32(p, length); + p += 4; + if (length == 0xffffffff) { + READ_64(p, length); + p += 8; + length_size = 8; + } else + length_size = 4; + + /* Check for terminator */ + if (length == 0) { + memset(d, 0, 4); + d += 4; + break; + } + + /* Read CIE ID/Pointer field. */ + READ_32(p, cie_id); + + /* Clear adjustment if CIE is found. */ + if (cie_id == 0) + adjust = 0; + + /* Check for our special mark. */ + if (cie_id != 0xFFFFFFFF) { + if (cie_id != 0) { + /* Adjust FDE pointer. */ + assert(cie_id > adjust); + cie_id -= adjust; + WRITE_32(p, cie_id); + } + memcpy(d, s, length + length_size); + d += length + length_size; + } else { + /* Discard FDE and increate adjustment. */ + adjust += length + length_size; + } + + /* Next entry. */ + p += length; + remain -= length + length_size; + } + + is->is_size -= is->is_shrink; + is->is_shrink = 0; + assert(d == end); + free(is->is_ehframe); + is->is_ehframe = NULL; +} + +void +ld_ehframe_scan(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_element *oe; + struct ld_input_section *is; + struct ld_input_section_head *islist; + uint64_t ehframe_off; + char ehframe_name[] = ".eh_frame"; + + lo = ld->ld_output; + assert(lo != NULL); + + /* + * Search for .eh_frame output section. Nothing needs to be done + * if .eh_frame section not exist or is empty. + */ + HASH_FIND_STR(lo->lo_ostbl, ehframe_name, os); + if (os == NULL || os->os_empty) + return; + + if ((ld->ld_cie = malloc(sizeof(*ld->ld_cie))) == NULL) + ld_fatal_std(ld, "malloc"); + STAILQ_INIT(ld->ld_cie); + + /* + * Remove duplicate CIE from each input .eh_frame section. + */ + ehframe_off = 0; + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + /* + * XXX We currently do not support .eh_frame section which + * contains elements other than OET_INPUT_SECTION_LIST. + */ + if (oe->oe_type != OET_INPUT_SECTION_LIST) + continue; + + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) { + /* + * Process each input .eh_frame section and search + * for duplicate CIE's. The input section relative + * offset in the output section is resync'ed since + * the input section might be shrinked. + */ + is->is_reloff = ehframe_off; + _process_ehframe_section(ld, lo, is); + ehframe_off += is->is_size; + } + } + + /* Calculate the size of .eh_frame_hdr section. */ + if (ld->ld_ehframe_hdr) { + is = ld_input_find_internal_section(ld, ".eh_frame_hdr"); + assert(is != NULL); + if (lo->lo_fde_num > 0) + is->is_size += 4 + lo->lo_fde_num * 8; + } +} + +void +ld_ehframe_create_hdr(struct ld *ld) +{ + struct ld_input_section *is; + + is = ld_input_add_internal_section(ld, ".eh_frame_hdr"); + is->is_type = SHT_PROGBITS; + is->is_size = 8; /* initial size */ + is->is_align = 4; + is->is_entsize = 0; +} + +void +ld_ehframe_finalize_hdr(struct ld *ld) +{ + struct ld_input_section *is, *hdr_is; + struct ld_input_section_head *islist; + struct ld_output *lo; + struct ld_output_section *os, *hdr_os; + struct ld_output_element *oe; + struct ld_ehframe_fde *fde, *_fde; + char ehframe_name[] = ".eh_frame"; + uint64_t pcbegin; + int32_t pcrel; + uint8_t *p, *end; + + lo = ld->ld_output; + assert(lo != NULL); + + hdr_is = ld_input_find_internal_section(ld, ".eh_frame_hdr"); + assert(hdr_is != NULL); + hdr_os = hdr_is->is_output; + lo->lo_ehframe_hdr = hdr_os; + + if (hdr_is->is_discard || hdr_os == NULL) + return; + + p = hdr_is->is_ibuf; + end = p + hdr_is->is_size; + + /* Find .eh_frame output section. */ + HASH_FIND_STR(lo->lo_ostbl, ehframe_name, os); + assert(os != NULL); + + /* .eh_frame_hdr version */ + *p++ = 1; + + /* + * eh_frame_ptr_enc: encoding format for eh_frame_ptr field. + * Usually a signed 4-byte PC relateive offset is used here. + */ + *p++ = DW_EH_PE_pcrel | DW_EH_PE_sdata4; + + /* + * fde_count_enc: encoding format for fde_count field. Unsigned + * 4 byte encoding should be used here. Note that If the binary + * search table is not present, DW_EH_PE_omit should be used + * instead. + */ + *p++ = lo->lo_fde_num == 0 ? DW_EH_PE_omit : DW_EH_PE_udata4; + + /* + * table_enc: encoding format for the binary search table entry. + * Signed 4 byte table relative offset is used here. Note that + * if the binary search table is not present, DW_EH_PE_omit should + * be used instaed. + */ + *p++ = lo->lo_fde_num == 0 ? DW_EH_PE_omit : + (DW_EH_PE_datarel | DW_EH_PE_sdata4); + + /* Write 4 byte PC relative offset to the .eh_frame section. */ + pcrel = os->os_addr - hdr_os->os_addr - 4; + WRITE_32(p, pcrel); + p += 4; + + /* Write the total number of FDE's. */ + WRITE_32(p, lo->lo_fde_num); + p += 4; + + /* Allocate global FDE list. */ + if (ld->ld_fde == NULL) { + if ((ld->ld_fde = calloc(1, sizeof(ld->ld_fde))) == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(ld->ld_fde); + } + + /* Link together the FDE's from each input object. */ + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + if (oe->oe_type != OET_INPUT_SECTION_LIST) + continue; + + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) { + if (is->is_fde == NULL || STAILQ_EMPTY(is->is_fde)) + continue; + STAILQ_FOREACH_SAFE(fde, is->is_fde, fde_next, _fde) { + (void) _read_encoded(ld, lo, &pcbegin, + (uint8_t *) is->is_ibuf + + fde->fde_off_pcbegin, + fde->fde_cie->cie_fde_encode, os->os_addr); + fde->fde_pcrel = pcbegin - hdr_os->os_addr; + fde->fde_datarel = os->os_addr + + is->is_reloff + fde->fde_off - + hdr_os->os_addr; + STAILQ_REMOVE(is->is_fde, fde, ld_ehframe_fde, + fde_next); + STAILQ_INSERT_TAIL(ld->ld_fde, fde, fde_next); + } + } + } + + /* Sort the binary search table in an increasing order by pcrel. */ + STAILQ_SORT(ld->ld_fde, ld_ehframe_fde, fde_next, _cmp_fde); + + /* Write binary search table. */ + STAILQ_FOREACH(fde, ld->ld_fde, fde_next) { + WRITE_32(p, fde->fde_pcrel); + p += 4; + WRITE_32(p, fde->fde_datarel); + p += 4; + } + + assert(p == end); +} + +static int +_cmp_fde(struct ld_ehframe_fde *a, struct ld_ehframe_fde *b) +{ + + if (a->fde_pcrel < b->fde_pcrel) + return (-1); + else if (a->fde_pcrel == b->fde_pcrel) + return (0); + else + return (1); +} + +static void +_parse_cie_augment(struct ld *ld, struct ld_ehframe_cie *cie, uint8_t *aug_p, + uint8_t *augdata_p, uint64_t auglen) +{ + uint64_t dummy; + uint8_t encode, *augdata_end; + int len; + + assert(aug_p != NULL && *aug_p == 'z'); + + augdata_end = augdata_p + auglen; + + /* + * Here we're only interested in the presence of augment 'R' + * and associated CIE augment data, which describes the + * encoding scheme of FDE PC begin and range. + */ + aug_p++; + while (*aug_p != '\0') { + switch (*aug_p) { + case 'L': + /* Skip one augment in augment data. */ + augdata_p++; + break; + case 'P': + /* Skip two augments in augment data. */ + encode = *augdata_p++; + len = _read_encoded(ld, ld->ld_output, &dummy, + augdata_p, encode, 0); + augdata_p += len; + break; + case 'R': + cie->cie_fde_encode = *augdata_p++; + break; + default: + ld_warn(ld, "unsupported eh_frame augmentation `%c'", + *aug_p); + return; + } + aug_p++; + } + + if (augdata_p > augdata_end) + ld_warn(ld, "invalid eh_frame augmentation"); +} + +static void +_process_ehframe_section(struct ld *ld, struct ld_output *lo, + struct ld_input_section *is) +{ + struct ld_input *li; + struct ld_output_section *os; + struct ld_ehframe_cie *cie, *_cie; + struct ld_ehframe_cie_head cie_h; + struct ld_ehframe_fde *fde; + struct ld_reloc_entry *lre, *_lre; + uint64_t length, es, off, off_orig, remain, shrink, auglen; + uint32_t cie_id, cie_pointer, length_size; + uint8_t *p, *et, cie_version, *augment; + + li = is->is_input; + os = is->is_output; + + STAILQ_INIT(&cie_h); + + /* + * .eh_frame section content should already be preloaded + * in is->is_ibuf. + */ + assert(is->is_ibuf != NULL && is->is_size > 0); + + shrink = 0; + p = is->is_ibuf; + off = off_orig = 0; + remain = is->is_size; + while (remain > 0) { + + et = p; + off = et - (uint8_t *) is->is_ibuf; + + /* Read CIE/FDE length field. */ + READ_32(p, length); + p += 4; + es = length + 4; + if (length == 0xffffffff) { + READ_64(p, length); + p += 8; + es += 8; + length_size = 8; + } else + length_size = 4; + + /* Check for terminator */ + if (length == 0) + break; + + /* Read CIE ID/Pointer field. */ + READ_32(p, cie_id); + p += 4; + + if (cie_id == 0) { + + /* This is a Common Information Entry (CIE). */ + if ((cie = calloc(1, sizeof(*cie))) == NULL) + ld_fatal_std(ld, "calloc"); + cie->cie_off = off; + cie->cie_off_orig = off_orig; + cie->cie_size = es; + cie->cie_content = et; + cie->cie_dup = NULL; + STAILQ_INSERT_TAIL(&cie_h, cie, cie_next); + + /* + * This is a Common Information Entry (CIE). Search + * in the CIE list see if we can found a duplicate + * entry. + */ + STAILQ_FOREACH(_cie, ld->ld_cie, cie_next) { + if (memcmp(et, _cie->cie_content, es) == 0) { + cie->cie_dup = _cie; + break; + } + } + if (_cie != NULL) { + /* + * We found a duplicate entry. It should be + * removed and the subsequent FDE's should + * point to the previously stored CIE. + */ + memmove(et, et + es, remain - es); + shrink += es; + p = et; + } else { + /* + * This is a new CIE entry which should be + * kept. Read its augmentation which is + * used to parse assoicated FDE's later. + */ + cie_version = *p++; + if (cie_version != 1) { + ld_warn(ld, "unsupported CIE version"); + goto ignore_cie; + } + augment = p; + if (*p != 'z') { + ld_warn(ld, "unsupported CIE " + "augmentation"); + goto ignore_cie; + } + while (*p++ != '\0') + ; + + /* Skip EH Data field. */ + if (strstr((char *)augment, "eh") != NULL) + p += lo->lo_ec == ELFCLASS32 ? 4 : 8; + + /* Skip CAF and DAF. */ + (void) _decode_uleb128(&p); + (void) _decode_sleb128(&p); + + /* Skip RA. */ + p++; + + /* Parse augmentation data. */ + auglen = _decode_uleb128(&p); + _parse_cie_augment(ld, cie, augment, p, + auglen); + + ignore_cie: + p = et + es; + } + + } else { + + /* + * This is a Frame Description Entry (FDE). First + * Search for the associated CIE. + */ + STAILQ_FOREACH(cie, &cie_h, cie_next) { + if (cie->cie_off_orig == + off_orig + length_size - cie_id) + break; + } + + /* + * If we can not found the associated CIE, this FDE + * is invalid and we ignore it. + */ + if (cie == NULL) { + ld_warn(ld, "%s(%s): malformed FDE", + li->li_name, is->is_name); + p = et + es; + goto next_entry; + } + + /* Allocate new FDE entry. */ + if ((fde = calloc(1, sizeof(*fde))) == NULL) + ld_fatal_std(ld, "calloc"); + fde->fde_off = off; + fde->fde_off_pcbegin = off + length_size + 4; + if (is->is_fde == NULL) { + is->is_fde = calloc(1, sizeof(*is->is_fde)); + if (is->is_fde == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(is->is_fde); + } + STAILQ_INSERT_TAIL(is->is_fde, fde, fde_next); + lo->lo_fde_num++; + + /* Calculate the new CIE pointer value. */ + if (cie->cie_dup != NULL) { + cie_pointer = off + length_size + + is->is_reloff - cie->cie_dup->cie_off; + fde->fde_cie = cie->cie_dup; + } else { + cie_pointer = off + length_size - cie->cie_off; + fde->fde_cie = cie; + } + + /* Rewrite CIE pointer value. */ + if (cie_id != cie_pointer) { + p -= 4; + WRITE_32(p, cie_pointer); + } + + p = et + es; + } + + next_entry: + off_orig += es; + remain -= es; + } + + /* + * Update the relocation entry offsets since we shrinked the + * section content. + */ + if (shrink > 0 && is->is_ris != NULL && is->is_ris->is_reloc != NULL) { + STAILQ_FOREACH_SAFE(lre, is->is_ris->is_reloc, lre_next, + _lre) { + STAILQ_FOREACH(cie, &cie_h, cie_next) { + if (cie->cie_off_orig > lre->lre_offset) + break; + if (cie->cie_dup == NULL) + continue; + + /* + * Remove relocations for the duplicated CIE + * entries. + */ + if (lre->lre_offset < + cie->cie_off_orig + cie->cie_size) { + STAILQ_REMOVE(is->is_ris->is_reloc, + lre, ld_reloc_entry, lre_next); + is->is_ris->is_num_reloc--; + is->is_ris->is_size -= + ld->ld_arch->reloc_entsize; + if (os->os_r != NULL) + os->os_r->os_size -= + ld->ld_arch->reloc_entsize; + break; + } + + /* Adjust relocation offset for FDE entries. */ + lre->lre_offset -= cie->cie_size; + } + } + } + + /* Insert newly found non-duplicate CIE's to the global CIE list. */ + STAILQ_FOREACH_SAFE(cie, &cie_h, cie_next, _cie) { + STAILQ_REMOVE(&cie_h, cie, ld_ehframe_cie, cie_next); + if (cie->cie_dup == NULL) { + cie->cie_off += is->is_reloff; + STAILQ_INSERT_TAIL(ld->ld_cie, cie, cie_next); + } + } + + /* Update the size of input .eh_frame section */ + is->is_size -= shrink; +} + +static int +_read_encoded(struct ld *ld, struct ld_output *lo, uint64_t *val, + uint8_t *data, uint8_t encode, uint64_t pc) +{ + int16_t s16; + int32_t s32; + uint8_t application, *begin; + int len; + + if (encode == DW_EH_PE_omit) + return (0); + + application = encode & 0xf0; + encode &= 0x0f; + + len = 0; + begin = data; + + switch (encode) { + case DW_EH_PE_absptr: + if (lo->lo_ec == ELFCLASS32) + READ_32(data, *val); + else + READ_64(data, *val); + break; + case DW_EH_PE_uleb128: + *val = _decode_uleb128(&data); + len = data - begin; + break; + case DW_EH_PE_udata2: + READ_16(data, *val); + len = 2; + break; + case DW_EH_PE_udata4: + READ_32(data, *val); + len = 4; + break; + case DW_EH_PE_udata8: + READ_64(data, *val); + len = 8; + break; + case DW_EH_PE_sleb128: + *val = _decode_sleb128(&data); + len = data - begin; + break; + case DW_EH_PE_sdata2: + READ_16(data, s16); + *val = s16; + len = 2; + break; + case DW_EH_PE_sdata4: + READ_32(data, s32); + *val = s32; + len = 4; + break; + case DW_EH_PE_sdata8: + READ_64(data, *val); + len = 8; + break; + default: + ld_warn(ld, "unsupported eh_frame encoding"); + break; + } + + if (application == DW_EH_PE_pcrel) { + /* + * Value is relative to .eh_frame section virtual addr. + */ + switch (encode) { + case DW_EH_PE_uleb128: + case DW_EH_PE_udata2: + case DW_EH_PE_udata4: + case DW_EH_PE_udata8: + *val += pc; + break; + case DW_EH_PE_sleb128: + case DW_EH_PE_sdata2: + case DW_EH_PE_sdata4: + case DW_EH_PE_sdata8: + *val = pc + (int64_t) *val; + break; + default: + /* DW_EH_PE_absptr is absolute value. */ + break; + } + } + + /* XXX Applications other than DW_EH_PE_pcrel are not handled. */ + + return (len); +} + +static int64_t +_decode_sleb128(uint8_t **dp) +{ + int64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 32 && (b & 0x40) != 0) + ret |= (~0UL << shift); + + *dp = src; + + return (ret); +} + +static uint64_t +_decode_uleb128(uint8_t **dp) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + *dp = src; + + return (ret); +} diff --git a/contrib/elftoolchain/ld/ld_ehframe.h b/contrib/elftoolchain/ld/ld_ehframe.h new file mode 100644 index 0000000000..a532a1855d --- /dev/null +++ b/contrib/elftoolchain/ld/ld_ehframe.h @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_ehframe.h 2960 2013-08-25 03:13:07Z kaiwang27 $ + */ + +void ld_ehframe_adjust(struct ld *, struct ld_input_section *); +void ld_ehframe_scan(struct ld *); +void ld_ehframe_create_hdr(struct ld *); +void ld_ehframe_finalize_hdr(struct ld *); diff --git a/contrib/elftoolchain/ld/ld_error.c b/contrib/elftoolchain/ld/ld_error.c new file mode 100644 index 0000000000..348b5314f8 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_error.c @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" + +ELFTC_VCSID("$Id: ld_error.c 2895 2013-01-15 23:05:31Z kaiwang27 $"); + +/* + * Support routines for error and warning message generation. + */ + +void +ld_fatal(struct ld *ld, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", ld->ld_progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); + exit(EXIT_FAILURE); +} + +void +ld_fatal_std(struct ld *ld, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", ld->ld_progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, ": %s\n", strerror(errno)); + exit(EXIT_FAILURE); +} + +void +ld_err(struct ld *ld, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", ld->ld_progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); +} + +void +ld_warn(struct ld *ld, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: warning: ", ld->ld_progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); +} + +void +ld_info(struct ld *ld, const char *fmt, ...) +{ + va_list ap; + + fprintf(stdout, "%s: ", ld->ld_progname); + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); + fputc('\n', stdout); +} diff --git a/contrib/elftoolchain/ld/ld_exp.c b/contrib/elftoolchain/ld/ld_exp.c new file mode 100644 index 0000000000..9c57cd8b24 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_exp.c @@ -0,0 +1,715 @@ +/*- + * Copyright (c) 2011,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_script.h" +#include "ld_exp.h" +#include "ld_layout.h" + +ELFTC_VCSID("$Id: ld_exp.c 3278 2015-12-11 21:39:13Z kaiwang27 $"); + +/* + * Support routines for ldscript expression. + */ + +static struct ld_exp *_alloc_exp(struct ld *ld); +static int64_t _assignment(struct ld *ld, struct ld_exp *le); +static int64_t _func_addr(struct ld *ld, struct ld_exp *le); +static int64_t _func_align(struct ld *ld, struct ld_exp *le); +static int64_t _func_alignof(struct ld *ld, struct ld_exp *le); +static int64_t _func_data_segment_align(struct ld *ld, struct ld_exp *le); +static int64_t _func_data_segment_end(struct ld *ld, struct ld_exp *le); +static int64_t _func_data_segment_relro_end(struct ld *ld, struct ld_exp *le); +static int64_t _func_defined(struct ld *ld, struct ld_exp *le); +static int64_t _func_length(struct ld *ld, struct ld_exp *le); +static int64_t _func_loadaddr(struct ld *ld, struct ld_exp *le); +static int64_t _func_max(struct ld *ld, struct ld_exp *le); +static int64_t _func_min(struct ld *ld, struct ld_exp *le); +static int64_t _func_next(struct ld *ld, struct ld_exp *le); +static int64_t _func_origin(struct ld *ld, struct ld_exp *le); +static int64_t _func_segment_start(struct ld *ld, struct ld_exp *le); +static int64_t _func_sizeof(struct ld *ld, struct ld_exp *le); +static int64_t _func_sizeof_headers(struct ld *ld); +static int64_t _symbol_val(struct ld *ld, char *name); +static int64_t _symbolic_constant(struct ld *ld, const char *name); + +#define _EXP_EVAL(x) ld_exp_eval(ld, (x)) +#define _EXP_DUMP(x) ld_exp_dump(ld, (x)) + +void +ld_exp_free(struct ld_exp *le) +{ + + if (le == NULL) + return; + + ld_exp_free(le->le_e1); + ld_exp_free(le->le_e2); + ld_exp_free(le->le_e3); + if (le->le_assign != NULL) + ld_script_assign_free(le->le_assign); + if (le->le_name != NULL) + free(le->le_name); + free(le); +} + +struct ld_exp * +ld_exp_unary(struct ld *ld, enum ld_exp_op op, struct ld_exp *e1) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = op; + le->le_e1 = e1; + + return (le); +} + +struct ld_exp * +ld_exp_binary(struct ld *ld, enum ld_exp_op op, struct ld_exp *e1, + struct ld_exp *e2) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = op; + le->le_e1 = e1; + le->le_e2 = e2; + + return (le); +} + +struct ld_exp * +ld_exp_trinary(struct ld *ld, struct ld_exp *e1, struct ld_exp *e2, + struct ld_exp *e3) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_TRINARY; + le->le_e1 = e1; + le->le_e2 = e2; + le->le_e3 = e3; + + return (le); +} + +struct ld_exp * +ld_exp_sizeof_headers(struct ld *ld) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_SIZEOF_HEADERS; + + return (le); +} + +struct ld_exp * +ld_exp_constant(struct ld *ld, int64_t val) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_CONSTANT; + le->le_val = val; + + return (le); +} + +struct ld_exp * +ld_exp_symbolic_constant(struct ld *ld, const char *name) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_SYMBOLIC_CONSTANT; + le->le_name = strdup(name); + if (le->le_name == NULL) + ld_fatal_std(ld, "calloc"); + + return (le); +} + +struct ld_exp * +ld_exp_symbol(struct ld *ld, const char *name) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_SYMBOL; + le->le_name = strdup(name); + if (le->le_name == NULL) + ld_fatal_std(ld, "calloc"); + + return (le); +} + +struct ld_exp * +ld_exp_name(struct ld *ld, const char *name) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_SECTION_NAME; + le->le_name = strdup(name); + if (le->le_name == NULL) + ld_fatal_std(ld, "calloc"); + + return (le); +} + +struct ld_exp * +ld_exp_assign(struct ld *ld, struct ld_script_assign *assign) +{ + struct ld_exp *le; + + le = _alloc_exp(ld); + le->le_op = LEOP_ASSIGN; + le->le_assign = assign; + + return (le); +} + +int64_t +ld_exp_eval(struct ld* ld, struct ld_exp *le) +{ + + assert(le != NULL); + switch (le->le_op) { + case LEOP_ABS: + return (llabs(_EXP_EVAL(le->le_e1))); + case LEOP_ADD: + return (_EXP_EVAL(le->le_e1) + _EXP_EVAL(le->le_e2)); + case LEOP_ADDR: + return (_func_addr(ld, le)); + case LEOP_ALIGN: + case LEOP_BLOCK: + return (_func_align(ld, le)); + case LEOP_ALIGNOF: + return (_func_alignof(ld, le)); + case LEOP_AND: + return (_EXP_EVAL(le->le_e1) & _EXP_EVAL(le->le_e2)); + case LEOP_ASSIGN: + return (_assignment(ld, le)); + case LEOP_CONSTANT: + return (le->le_val); + case LEOP_DIV: + return (_EXP_EVAL(le->le_e1) / _EXP_EVAL(le->le_e2)); + case LEOP_DSA: + return (_func_data_segment_align(ld, le)); + case LEOP_DSE: + return (_func_data_segment_end(ld, le)); + case LEOP_DSRE: + return (_func_data_segment_relro_end(ld, le)); + case LEOP_DEFINED: + return (_func_defined(ld, le)); + case LEOP_EQUAL: + return (_EXP_EVAL(le->le_e1) == _EXP_EVAL(le->le_e2)); + case LEOP_GE: + return (_EXP_EVAL(le->le_e1) >= _EXP_EVAL(le->le_e2)); + case LEOP_GREATER: + return (_EXP_EVAL(le->le_e1) > _EXP_EVAL(le->le_e2)); + case LEOP_LENGTH: + return (_func_length(ld, le)); + case LEOP_LOADADDR: + return (_func_loadaddr(ld, le)); + case LEOP_LOGICAL_AND: + return (_EXP_EVAL(le->le_e1) && _EXP_EVAL(le->le_e2)); + case LEOP_LOGICAL_OR: + return (_EXP_EVAL(le->le_e1) || _EXP_EVAL(le->le_e2)); + case LEOP_LSHIFT: + return (_EXP_EVAL(le->le_e1) << _EXP_EVAL(le->le_e2)); + case LEOP_MAX: + return (_func_max(ld, le)); + case LEOP_MIN: + return (_func_min(ld, le)); + case LEOP_MINUS: + return (-(_EXP_EVAL(le->le_e1))); + case LEOP_MOD: + return (_EXP_EVAL(le->le_e1) % _EXP_EVAL(le->le_e2)); + case LEOP_MUL: + return (_EXP_EVAL(le->le_e1) * _EXP_EVAL(le->le_e2)); + case LEOP_NE: + return (_EXP_EVAL(le->le_e1) != _EXP_EVAL(le->le_e2)); + case LEOP_NEGATION: + return (~(_EXP_EVAL(le->le_e1))); + case LEOP_NEXT: + return (_func_next(ld, le)); + case LEOP_NOT: + return (!(_EXP_EVAL(le->le_e1))); + case LEOP_OR: + return (_EXP_EVAL(le->le_e1) | _EXP_EVAL(le->le_e2)); + case LEOP_ORIGIN: + return (_func_origin(ld, le)); + case LEOP_RSHIFT: + return (_EXP_EVAL(le->le_e1) >> _EXP_EVAL(le->le_e2)); + case LEOP_SEGMENT_START: + return (_func_segment_start(ld, le)); + case LEOP_SIZEOF: + return (_func_sizeof(ld, le)); + case LEOP_SIZEOF_HEADERS: + return (_func_sizeof_headers(ld)); + case LEOP_SUBSTRACT: + return (_EXP_EVAL(le->le_e1) - _EXP_EVAL(le->le_e2)); + case LEOP_SYMBOL: + return (_symbol_val(ld, le->le_name)); + case LEOP_SYMBOLIC_CONSTANT: + return (_symbolic_constant(ld, le->le_name)); + case LEOP_TRINARY: + return (_EXP_EVAL(le->le_e1) ? _EXP_EVAL(le->le_e2) : + _EXP_EVAL(le->le_e3)); + default: + ld_fatal(ld, "internal: unknown ldscript expression op"); + } + + return (0); +} + +void +ld_exp_dump(struct ld *ld, struct ld_exp *le) +{ + + assert(le != NULL); + + if (le->le_par) + printf("("); + + switch (le->le_op) { + case LEOP_ABS: + printf("ABS("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_ADD: + _EXP_DUMP(le->le_e1); + printf(" + "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_ADDR: + printf("ADDR("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_ALIGN: + case LEOP_BLOCK: + printf("ALIGN("); + _EXP_DUMP(le->le_e1); + if (le->le_e2 != NULL) { + printf(", "); + _EXP_DUMP(le->le_e2); + } + printf(")"); + break; + case LEOP_ALIGNOF: + printf("ALIGNOF("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_AND: + _EXP_DUMP(le->le_e1); + printf(" & "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_ASSIGN: + printf("0x%jx", (uintmax_t) le->le_assign->lda_res); + break; + case LEOP_CONSTANT: + printf("0x%jx", (uintmax_t) le->le_val); + break; + case LEOP_DIV: + _EXP_DUMP(le->le_e1); + printf(" / "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_DSA: + printf("DATA_SEGMENT_ALIGN("); + _EXP_DUMP(le->le_e1); + printf(", "); + _EXP_DUMP(le->le_e2); + printf(")"); + break; + case LEOP_DSE: + printf("DATA_SEGMENT_END("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_DSRE: + printf("DATA_SEGMENT_RELRO_END("); + _EXP_DUMP(le->le_e1); + printf(", "); + _EXP_DUMP(le->le_e2); + printf(")"); + break; + case LEOP_DEFINED: + printf("DEFINED("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_EQUAL: + _EXP_DUMP(le->le_e1); + printf(" == "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_GE: + _EXP_DUMP(le->le_e1); + printf(" >= "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_GREATER: + _EXP_DUMP(le->le_e1); + printf(" > "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_LENGTH: + printf("LENGTH("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_LOADADDR: + printf("LOADADDR("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_LOGICAL_AND: + _EXP_DUMP(le->le_e1); + printf(" && "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_LOGICAL_OR: + _EXP_DUMP(le->le_e1); + printf(" || "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_LSHIFT: + _EXP_DUMP(le->le_e1); + printf(" << "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_MAX: + printf("MAX("); + _EXP_DUMP(le->le_e1); + printf(", "); + _EXP_DUMP(le->le_e2); + printf(")"); + break; + case LEOP_MIN: + printf("MIN("); + _EXP_DUMP(le->le_e1); + printf(", "); + _EXP_DUMP(le->le_e2); + printf(")"); + break; + case LEOP_MINUS: + printf("-"); + _EXP_DUMP(le->le_e1); + break; + case LEOP_MOD: + _EXP_DUMP(le->le_e1); + printf(" %% "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_MUL: + _EXP_DUMP(le->le_e1); + printf(" * "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_NE: + _EXP_DUMP(le->le_e1); + printf(" != "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_NEGATION: + printf("~"); + _EXP_DUMP(le->le_e1); + break; + case LEOP_NEXT: + printf("NEXT("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_NOT: + printf("!"); + _EXP_DUMP(le->le_e1); + break; + case LEOP_OR: + _EXP_DUMP(le->le_e1); + printf(" | "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_ORIGIN: + printf("ORIGIN("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_RSHIFT: + _EXP_DUMP(le->le_e1); + printf(" >> "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_SEGMENT_START: + printf("SEGMENT_START("); + _EXP_DUMP(le->le_e1); + printf(", "); + _EXP_DUMP(le->le_e2); + printf(")"); + break; + case LEOP_SIZEOF: + printf("SIZEOF("); + _EXP_DUMP(le->le_e1); + printf(")"); + break; + case LEOP_SIZEOF_HEADERS: + printf("SIZEOF_HEADERS"); + break; + case LEOP_SUBSTRACT: + _EXP_DUMP(le->le_e1); + printf(" - "); + _EXP_DUMP(le->le_e2); + break; + case LEOP_SYMBOL: + printf("%s", le->le_name); + break; + case LEOP_SYMBOLIC_CONSTANT: + printf("0x%jx", + (uintmax_t) _symbolic_constant(ld, le->le_name)); + break; + case LEOP_TRINARY: + _EXP_DUMP(le->le_e1); + printf(" ? "); + _EXP_DUMP(le->le_e2); + printf(" : "); + _EXP_DUMP(le->le_e3); + break; + default: + ld_fatal(ld, "internal: unknown ldscript expression op"); + } + + if (le->le_par) + printf(")"); +} + +static struct ld_exp * +_alloc_exp(struct ld *ld) +{ + struct ld_exp *le; + + if ((le = calloc(1, sizeof(*le))) == NULL) + ld_fatal_std(ld, "calloc"); + + return (le); +} + +static int64_t +_assignment(struct ld *ld, struct ld_exp *le) +{ + struct ld_exp *var; + + assert(le->le_assign != NULL); + ld_script_process_assign(ld, le->le_assign); + var = le->le_assign->lda_var; + return (ld_script_variable_value(ld, var->le_name)); +} + +static int64_t +_func_addr(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_align(struct ld *ld, struct ld_exp *le) +{ + struct ld_state *ls; + + ls = &ld->ld_state; + if (le->le_e2 != NULL) + return (roundup(_EXP_EVAL(le->le_e1), _EXP_EVAL(le->le_e2))); + else + return (roundup(ls->ls_loc_counter, _EXP_EVAL(le->le_e1))); +} + +static int64_t +_func_alignof(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_data_segment_align(struct ld *ld, struct ld_exp *le) +{ + struct ld_state *ls; + uint64_t maxpagesize; + /* uint64_t commonpagesize; */ + + /* + * TODO: test if align to common page size use less number + * of pages. + */ + ls = &ld->ld_state; + maxpagesize = _EXP_EVAL(le->le_e1); + /* commonpagesize = _EXP_EVAL(le->le_e2); */ + + return (roundup(ls->ls_loc_counter, maxpagesize) + + (ls->ls_loc_counter & (maxpagesize - 1))); +} + +static int64_t +_func_data_segment_end(struct ld *ld, struct ld_exp *le) +{ + + return (_EXP_EVAL(le->le_e1)); +} + +static int64_t +_func_data_segment_relro_end(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_defined(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_length(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_loadaddr(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_max(struct ld *ld, struct ld_exp *le) +{ + uint64_t val1, val2; + + val1 = _EXP_EVAL(le->le_e1); + val2 = _EXP_EVAL(le->le_e2); + + return (val1 > val2 ? val1 : val2); +} + +static int64_t +_func_min(struct ld *ld, struct ld_exp *le) +{ + uint64_t val1, val2; + + val1 = _EXP_EVAL(le->le_e1); + val2 = _EXP_EVAL(le->le_e2); + + return (val1 > val2 ? val2 : val1); +} + +static int64_t +_func_next(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_origin(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_segment_start(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_sizeof(struct ld *ld, struct ld_exp *le) +{ + + /* TODO */ + (void) ld; (void) le; + return (0); +} + +static int64_t +_func_sizeof_headers(struct ld *ld) +{ + + return (ld_layout_calc_header_size(ld)); +} + +static int64_t +_symbol_val(struct ld *ld, char *name) +{ + + return (ld_script_variable_value(ld, name)); +} + +static int64_t +_symbolic_constant(struct ld *ld, const char *name) +{ + + if (ld->ld_arch == NULL) + return (0); + + if (strcmp(name, "COMMONPAGESIZE") == 0) + return (ld->ld_arch->get_common_page_size(ld)); + else if (strcmp(name, "MAXPAGESIZE") == 0) + return (ld->ld_arch->get_max_page_size(ld)); + + return (0); +} diff --git a/contrib/elftoolchain/ld/ld_exp.h b/contrib/elftoolchain/ld/ld_exp.h new file mode 100644 index 0000000000..50f654f1b6 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_exp.h @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2011,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_exp.h 2525 2012-07-17 17:36:19Z kaiwang27 $ + */ + +enum ld_exp_op { + LEOP_ABS, + LEOP_ADD, + LEOP_ADDR, + LEOP_ALIGN, + LEOP_ALIGNOF, + LEOP_AND, + LEOP_ASSIGN, + LEOP_BLOCK, + LEOP_CONSTANT, + LEOP_DIV, + LEOP_DSA, + LEOP_DSE, + LEOP_DSRE, + LEOP_DEFINED, + LEOP_EQUAL, + LEOP_GE, + LEOP_GREATER, + LEOP_LENGTH, + LEOP_LE, + LEOP_LESSER, + LEOP_LOADADDR, + LEOP_LOGICAL_AND, + LEOP_LOGICAL_OR, + LEOP_LSHIFT, + LEOP_MAX, + LEOP_MIN, + LEOP_MINUS, + LEOP_MOD, + LEOP_MUL, + LEOP_NE, + LEOP_NEGATION, + LEOP_NEXT, + LEOP_NOT, + LEOP_OR, + LEOP_ORIGIN, + LEOP_RSHIFT, + LEOP_SEGMENT_START, + LEOP_SIZEOF, + LEOP_SIZEOF_HEADERS, + LEOP_SECTION_NAME, + LEOP_SUBSTRACT, + LEOP_SYMBOL, + LEOP_SYMBOLIC_CONSTANT, + LEOP_TRINARY, +}; + +struct ld_exp { + enum ld_exp_op le_op; /* expression operator */ + struct ld_exp *le_e1; /* fisrt operand */ + struct ld_exp *le_e2; /* second operand */ + struct ld_exp *le_e3; /* third operand */ + struct ld_script_assign *le_assign; /* assignment */ + char *le_name; /* symbol/section name */ + unsigned le_par; /* parenthesis */ + int64_t le_val; /* constant value */ +}; + +struct ld_exp *ld_exp_assign(struct ld *, struct ld_script_assign *); +struct ld_exp *ld_exp_binary(struct ld *, enum ld_exp_op, struct ld_exp *, + struct ld_exp *); +struct ld_exp *ld_exp_constant(struct ld *, int64_t); +int64_t ld_exp_eval(struct ld *, struct ld_exp *); +void ld_exp_dump(struct ld *, struct ld_exp *); +struct ld_exp *ld_exp_name(struct ld *, const char *); +struct ld_exp *ld_exp_sizeof_headers(struct ld *); +struct ld_exp *ld_exp_symbol(struct ld *, const char *); +struct ld_exp *ld_exp_symbolic_constant(struct ld *, const char *); +struct ld_exp *ld_exp_trinary(struct ld *, struct ld_exp *, struct ld_exp *, + struct ld_exp *); +struct ld_exp *ld_exp_unary(struct ld *, enum ld_exp_op, struct ld_exp *); +void ld_exp_free(struct ld_exp *); diff --git a/contrib/elftoolchain/ld/ld_file.c b/contrib/elftoolchain/ld/ld_file.c new file mode 100644 index 0000000000..75a5d90c40 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_file.c @@ -0,0 +1,238 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_file.h" +#include "ld_path.h" + +ELFTC_VCSID("$Id: ld_file.c 3887 2020-11-11 18:54:48Z jkoshy $"); + +/* + * Support routines for input file handling. + */ + +static void _add_file(struct ld *ld, const char *name, enum ld_file_type type, + int first, struct ld_file *after); + +void +ld_file_cleanup(struct ld *ld) +{ + struct ld_file *lf, *_lf; + struct ld_archive_member *lam, *_lam; + + TAILQ_FOREACH_SAFE(lf, &ld->ld_lflist, lf_next, _lf) { + TAILQ_REMOVE(&ld->ld_lflist, lf, lf_next); + free(lf->lf_name); + if (lf->lf_ar != NULL) { + HASH_ITER(hh, lf->lf_ar->la_m, lam, _lam) { + HASH_DEL(lf->lf_ar->la_m, lam); + free(lam->lam_name); + free(lam); + } + free(lf->lf_ar); + } + free(lf); + } +} + +void +ld_file_add(struct ld *ld, const char *name, enum ld_file_type type) +{ + + _add_file(ld, name, type, 0, NULL); +} + +void +ld_file_add_first(struct ld *ld, const char *name, enum ld_file_type type) +{ + + _add_file(ld, name, type, 1, NULL); +} + +void +ld_file_add_after(struct ld *ld, const char *name, enum ld_file_type type, + struct ld_file *after) +{ + + _add_file(ld, name, type, 0, after); +} + +void +ld_file_load(struct ld *ld, struct ld_file *lf) +{ + struct ld_archive *la; + struct ld_state *ls; + struct stat sb; + Elf_Kind k; + GElf_Ehdr ehdr; + int fd; + + assert(lf != NULL && lf->lf_name != NULL); + + ls = &ld->ld_state; + if (ls->ls_file == lf) + return; + + if ((fd = open(lf->lf_name, O_RDONLY)) < 0) + ld_fatal_std(ld, "%s: open", lf->lf_name); + + if (fstat(fd, &sb) < 0) + ld_fatal_std(ld, "%s: stat", lf->lf_name); + if (sb.st_size == 0) + ld_fatal(ld, "%s: File truncated", lf->lf_name); + + lf->lf_size = sb.st_size; + if ((lf->lf_mmap = mmap(NULL, lf->lf_size, PROT_READ, MAP_PRIVATE, fd, + (off_t) 0)) == MAP_FAILED) + ld_fatal_std(ld, "%s: mmap", lf->lf_name); + close(fd); + + if (lf->lf_type == LFT_BINARY) + return; + + if ((lf->lf_elf = elf_memory(lf->lf_mmap, lf->lf_size)) == NULL) + ld_fatal(ld, "%s: elf_memory failed: %s", lf->lf_name, + elf_errmsg(-1)); + + k = elf_kind(lf->lf_elf); + + if (k == ELF_K_AR) { + lf->lf_type = LFT_ARCHIVE; + if (lf->lf_ar == NULL) { + if ((la = calloc(1, sizeof(*la))) == NULL) + ld_fatal_std(ld, "calloc"); + lf->lf_ar = la; + } + return; + } + + assert(k != ELF_K_AR); + if (k == ELF_K_NONE) + ld_fatal(ld, "%s: File format not recognized", lf->lf_name); + + if (gelf_getehdr(lf->lf_elf, &ehdr) == NULL) + ld_fatal(ld, "%s: gelf_getehdr failed: %s", lf->lf_name, + elf_errmsg(-1)); + + switch (ehdr.e_type) { + case ET_NONE: + ld_fatal(ld, "%s: ELF type ET_NONE not supported", lf->lf_name); + break; + case ET_REL: + lf->lf_type = LFT_RELOCATABLE; + break; + case ET_EXEC: + ld_fatal(ld, "%s: ELF type ET_EXEC not supported yet", + lf->lf_name); + break; + case ET_DYN: + lf->lf_type = LFT_DSO; + break; + case ET_CORE: + ld_fatal(ld, "%s: ELF type ET_NONE not supported", lf->lf_name); + break; + default: + ld_fatal(ld, "%s: unknown ELF type %u", ehdr.e_type); + break; + } + + ld_arch_verify(ld, lf->lf_name, ehdr.e_machine, ehdr.e_ident[EI_DATA], + ehdr.e_flags); +} + +void +ld_file_unload(struct ld *ld, struct ld_file *lf) +{ + struct ld_state *ls; + + ls = &ld->ld_state; + + if (lf->lf_type != LFT_BINARY) + elf_end(lf->lf_elf); + + if (lf->lf_mmap != NULL) { + if (munmap(lf->lf_mmap, lf->lf_size) < 0) + ld_fatal_std(ld, "%s: munmap", lf->lf_name); + } + + if (ls->ls_file == lf) + ls->ls_file = NULL; +} + +static void +_add_file(struct ld *ld, const char *name, enum ld_file_type type, + int first, struct ld_file *after) +{ + struct ld_state *ls; + struct ld_file *lf; + int fd; + + assert(ld != NULL && name != NULL); + + if (!strncmp(name, "-l", 2)) { + ld_path_search_library(ld, &name[2]); + return; + } + + ls = &ld->ld_state; + + if ((lf = calloc(1, sizeof(*lf))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((lf->lf_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + lf->lf_type = type; + lf->lf_whole_archive = ls->ls_whole_archive; + lf->lf_as_needed = ls->ls_as_needed; + lf->lf_group_level = ls->ls_group_level; + lf->lf_search_dir = ls->ls_search_dir; + + if ((fd = open(lf->lf_name, O_RDONLY)) < 0) { + if (!lf->lf_search_dir) + ld_fatal_std(ld, "%s: open", lf->lf_name); + + /* Search library path for this file. */ + ld_path_search_file(ld, lf); + } else + (void) close(fd); + + if (lf->lf_type == LFT_UNKNOWN && ls->ls_itgt != NULL) { + if (elftc_bfd_target_flavor(ls->ls_itgt) == ETF_BINARY) + lf->lf_type = LFT_BINARY; + } + + if (lf->lf_type == LFT_DSO) + ld->ld_dynamic_link = 1; + + if (after != NULL) + TAILQ_INSERT_AFTER(&ld->ld_lflist, after, lf, lf_next); + else if (first) + TAILQ_INSERT_HEAD(&ld->ld_lflist, lf, lf_next); + else + TAILQ_INSERT_TAIL(&ld->ld_lflist, lf, lf_next); +} diff --git a/contrib/elftoolchain/ld/ld_file.h b/contrib/elftoolchain/ld/ld_file.h new file mode 100644 index 0000000000..5705f648d2 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_file.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_file.h 2930 2013-03-17 22:54:26Z kaiwang27 $ + */ + +enum ld_file_type { + LFT_UNKNOWN, + LFT_RELOCATABLE, + LFT_DSO, + LFT_ARCHIVE, + LFT_BINARY +}; + +struct ld_archive_member { + char *lam_ar_name; /* archive name */ + char *lam_name; /* archive member name */ + off_t lam_off; /* archive member offset */ + struct ld_input *lam_input; /* input object */ + UT_hash_handle hh; /* hash handle */ +}; + +struct ld_archive { + struct ld_archive_member *la_m; /* extracted member list. */ +}; + +struct ld_file { + char *lf_name; /* input file name */ + enum ld_file_type lf_type; /* input file type */ + void *lf_mmap; /* input file image */ + size_t lf_size; /* input file size */ + Elf *lf_elf; /* input file ELF descriptor */ + struct ld_archive *lf_ar; /* input archive */ + struct ld_input *lf_input; /* input object */ + unsigned lf_whole_archive; /* include whole archive */ + unsigned lf_as_needed; /* DT_NEEDED */ + unsigned lf_group_level; /* archive group level */ + unsigned lf_search_dir; /* search library directories */ + TAILQ_ENTRY(ld_file) lf_next; /* next input file */ +}; + +void ld_file_add(struct ld *, const char *, enum ld_file_type); +void ld_file_add_first(struct ld *, const char *, enum ld_file_type); +void ld_file_add_after(struct ld *, const char *, enum ld_file_type, + struct ld_file *); +void ld_file_cleanup(struct ld *); +void ld_file_load(struct ld *, struct ld_file *); +void ld_file_unload(struct ld *, struct ld_file *); diff --git a/contrib/elftoolchain/ld/ld_hash.c b/contrib/elftoolchain/ld/ld_hash.c new file mode 100644 index 0000000000..fc41251260 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_hash.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_hash.h" +#include "ld_layout.h" +#include "ld_output.h" +#include "ld_symbols.h" + +ELFTC_VCSID("$Id: ld_hash.c 2917 2013-02-16 07:16:02Z kaiwang27 $"); + +/* + * The number of buckets to use for a certain number of symbols. + * If there are less than 3 symbols, 1 bucket will be used. If + * there are less than 17 symbols, 3 buckets will be used, and so + * forth. The bucket numbers are defined by GNU ld. We use the + * same rules here so we generate hash sections with the same + * size as those generated by GNU ld. + */ +static unsigned hash_buckets[] = { + 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147 +}; + +void +ld_hash_create_svr4_hash_section(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_data_buffer *odb; + struct ld_symbol *lsb; + char hash_name[] = ".hash"; + uint32_t *buf, *buckets, *chains, nbuckets, nchains; + int i, j; + + lo = ld->ld_output; + assert(lo != NULL); + + HASH_FIND_STR(lo->lo_ostbl, hash_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, hash_name, SHF_ALLOC); + os->os_type = SHT_HASH; + os->os_flags = SHF_ALLOC; + os->os_entsize = 4; + if (lo->lo_ec == ELFCLASS32) + os->os_align = 4; + else + os->os_align = 8; + + if ((os->os_link = strdup(".dynsym")) == NULL) + ld_fatal_std(ld, "strdup"); + + lo->lo_hash = os; + + assert(ld->ld_dynsym != NULL && ld->ld_dynsym->sy_size > 0); + + nchains = ld->ld_dynsym->sy_size; + nbuckets = 0; + for (i = 1; + (size_t) i < sizeof(hash_buckets) / sizeof(hash_buckets[0]); + i++) { + if (nchains < hash_buckets[i]) { + nbuckets = hash_buckets[i - 1]; + break; + } + } + if (nbuckets == 0) + nbuckets = hash_buckets[i - 1]; + + if ((buf = calloc(nbuckets + nchains + 2, sizeof(uint32_t))) == NULL) + ld_fatal_std(ld, "calloc"); + + buf[0] = nbuckets; + buf[1] = nchains; + buckets = &buf[2]; + chains = &buf[2 + nbuckets]; + + assert(ld->ld_dyn_symbols != NULL); + + i = 1; + STAILQ_FOREACH(lsb, ld->ld_dyn_symbols, lsb_dyn) { + if (lsb->lsb_name == NULL) { + i++; + continue; + } + + j = elf_hash(lsb->lsb_name) % nbuckets; + chains[i] = buckets[j]; + buckets[j] = i; + i++; + } + + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + + odb->odb_buf = (void *) buf; + odb->odb_size = (nbuckets + nchains + 2) * sizeof(uint32_t); + odb->odb_align = os->os_align; + odb->odb_type = ELF_T_WORD; /* enable libelf translation */ + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, + odb, NULL); +} diff --git a/contrib/elftoolchain/ld/ld_hash.h b/contrib/elftoolchain/ld/ld_hash.h new file mode 100644 index 0000000000..84e511a994 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_hash.h @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_hash.h 2669 2012-11-11 13:20:43Z kaiwang27 $ + */ + +void ld_hash_create_svr4_hash_section(struct ld *); diff --git a/contrib/elftoolchain/ld/ld_input.c b/contrib/elftoolchain/ld/ld_input.c new file mode 100644 index 0000000000..bcef610921 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_input.c @@ -0,0 +1,653 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_file.h" +#include "ld_input.h" +#include "ld_symbols.h" + +ELFTC_VCSID("$Id: ld_input.c 2960 2013-08-25 03:13:07Z kaiwang27 $"); + +/* + * Support routines for input section handling. + */ + +static void _discard_section_group(struct ld *ld, struct ld_input *li, + Elf_Scn *scn); +static off_t _offset_sort(struct ld_archive_member *a, + struct ld_archive_member *b); + +#define _MAX_INTERNAL_SECTIONS 16 + +void +ld_input_init(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + + assert(STAILQ_EMPTY(&ld->ld_lilist)); + + /* + * Create an internal pseudo input object to hold internal + * input sections. + */ + + li = ld_input_alloc(ld, NULL, NULL); + + li->li_is = calloc(_MAX_INTERNAL_SECTIONS, + sizeof(struct ld_input_section)); + if (li->li_is == NULL) + ld_fatal_std(ld, "calloc"); + + STAILQ_INSERT_TAIL(&ld->ld_lilist, li, li_next); + + /* + * Create an initial SHT_NULL section for the pseudo input object, + * so all the internal sections will have valid section index. + * (other than SHN_UNDEF) + */ + is = &li->li_is[li->li_shnum]; + if ((is->is_name = strdup("")) == NULL) + ld_fatal_std(ld, "strdup"); + is->is_input = li; + is->is_type = SHT_NULL; + is->is_index = li->li_shnum; + li->li_shnum++; +} + +struct ld_input_section * +ld_input_add_internal_section(struct ld *ld, const char *name) +{ + struct ld_input *li; + struct ld_input_section *is; + + li = STAILQ_FIRST(&ld->ld_lilist); + assert(li != NULL); + + if (li->li_shnum >= _MAX_INTERNAL_SECTIONS) + ld_fatal(ld, "Internal: not enough buffer for internal " + "sections"); + + is = &li->li_is[li->li_shnum]; + if ((is->is_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + is->is_input = li; + is->is_index = li->li_shnum; + + /* Use a hash table to accelerate lookup for internal sections. */ + HASH_ADD_KEYPTR(hh, li->li_istbl, is->is_name, strlen(is->is_name), + is); + + li->li_shnum++; + + return (is); +} + +struct ld_input_section * +ld_input_find_internal_section(struct ld *ld, const char *name) +{ + struct ld_input *li; + struct ld_input_section *is; + char _name[32]; + + li = STAILQ_FIRST(&ld->ld_lilist); + assert(li != NULL); + + snprintf(_name, sizeof(_name), "%s", name); + HASH_FIND_STR(li->li_istbl, _name, is); + + return (is); +} + +uint64_t +ld_input_reserve_ibuf(struct ld_input_section *is, uint64_t n) +{ + uint64_t off; + + assert(is->is_entsize != 0); + + off = is->is_size; + is->is_size += n * is->is_entsize; + + return (off); +} + +void +ld_input_alloc_internal_section_buffers(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + int i; + + li = STAILQ_FIRST(&ld->ld_lilist); + assert(li != NULL); + + for (i = 0; (uint64_t) i < li->li_shnum; i++) { + is = &li->li_is[i]; + + if (is->is_type == SHT_NOBITS || is->is_size == 0 || + is->is_dynrel) + continue; + + if ((is->is_ibuf = malloc(is->is_size)) == NULL) + ld_fatal_std(ld, "malloc"); + } +} + +void +ld_input_cleanup(struct ld *ld) +{ + struct ld_input *li, *_li; + int i; + + STAILQ_FOREACH_SAFE(li, &ld->ld_lilist, li_next, _li) { + STAILQ_REMOVE(&ld->ld_lilist, li, ld_input, li_next); + if (li->li_symindex) + free(li->li_symindex); + if (li->li_local) + free(li->li_local); + if (li->li_versym) + free(li->li_versym); + if (li->li_vername) { + for (i = 0; (size_t) i < li->li_vername_sz; i++) + if (li->li_vername[i]) + free(li->li_vername[i]); + free(li->li_vername); + } + if (li->li_is) + free(li->li_is); + if (li->li_fullname) + free(li->li_fullname); + if (li->li_name) + free(li->li_name); + if (li->li_soname) + free(li->li_soname); + free(li); + } +} + +void +ld_input_add_symbol(struct ld *ld, struct ld_input *li, struct ld_symbol *lsb) +{ + + if (li->li_symindex == NULL) { + assert(li->li_symnum != 0); + li->li_symindex = calloc(li->li_symnum, + sizeof(*li->li_symindex)); + if (li->li_symindex == NULL) + ld_fatal_std(ld, "calloc"); + } + + li->li_symindex[lsb->lsb_index] = lsb; + + if (lsb->lsb_bind == STB_LOCAL) { + if (li->li_local == NULL) { + li->li_local = calloc(1, sizeof(*li->li_local)); + if (li->li_local == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(li->li_local); + } + STAILQ_INSERT_TAIL(li->li_local, lsb, lsb_next); + } +} + +struct ld_input * +ld_input_alloc(struct ld *ld, struct ld_file *lf, const char *name) +{ + struct ld_input *li; + + if ((li = calloc(1, sizeof(*li))) == NULL) + ld_fatal_std(ld, "calloc"); + + if (name != NULL && (li->li_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + li->li_file = lf; + + if (lf != NULL) { + switch (lf->lf_type) { + case LFT_ARCHIVE: + case LFT_RELOCATABLE: + li->li_type = LIT_RELOCATABLE; + break; + case LFT_DSO: + li->li_type = LIT_DSO; + break; + case LFT_BINARY: + case LFT_UNKNOWN: + default: + li->li_type = LIT_UNKNOWN; + break; + } + } else + li->li_type = LIT_RELOCATABLE; + + return (li); +} + +char * +ld_input_get_fullname(struct ld *ld, struct ld_input *li) +{ + struct ld_archive_member *lam; + size_t len; + + if (li->li_fullname != NULL) + return (li->li_fullname); + + if (li->li_lam == NULL) + return (li->li_name); + + lam = li->li_lam; + len = strlen(lam->lam_ar_name) + strlen(lam->lam_name) + 3; + if ((li->li_fullname = malloc(len)) == NULL) + ld_fatal_std(ld, "malloc"); + snprintf(li->li_fullname, len, "%s(%s)", lam->lam_ar_name, + lam->lam_name); + + return (li->li_fullname); +} + +void +ld_input_link_objects(struct ld *ld) +{ + struct ld_file *lf; + struct ld_archive_member *lam, *tmp; + struct ld_input *li; + + TAILQ_FOREACH(lf, &ld->ld_lflist, lf_next) { + if (lf->lf_ar != NULL) { + HASH_SORT(lf->lf_ar->la_m, _offset_sort); + HASH_ITER(hh, lf->lf_ar->la_m, lam, tmp) { + li = lam->lam_input; + if (li != NULL) + STAILQ_INSERT_TAIL(&ld->ld_lilist, li, + li_next); + } + } else { + li = lf->lf_input; + if (li != NULL) + STAILQ_INSERT_TAIL(&ld->ld_lilist, li, li_next); + } + } +} + +void * +ld_input_get_section_rawdata(struct ld *ld, struct ld_input_section *is) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + struct ld_input *li; + char *buf; + int elferr; + + li = is->is_input; + e = li->li_elf; + assert(e != NULL); + + if ((scn = elf_getscn(e, is->is_index)) == NULL) + ld_fatal(ld, "%s(%s): elf_getscn failed: %s", li->li_name, + is->is_name, elf_errmsg(-1)); + + (void) elf_errno(); + if ((d = elf_rawdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s(%s): elf_rawdata failed: %s", + li->li_name, is->is_name, elf_errmsg(elferr)); + return (NULL); + } + + if (d->d_buf == NULL || d->d_size == 0) + return (NULL); + + if ((buf = malloc(d->d_size)) == NULL) + ld_fatal_std(ld, "malloc"); + + memcpy(buf, d->d_buf, d->d_size); + + return (buf); +} + +void +ld_input_load(struct ld *ld, struct ld_input *li) +{ + struct ld_state *ls; + struct ld_file *lf; + struct ld_archive_member *lam; + + if (li->li_file == NULL) + return; + + assert(li->li_elf == NULL); + ls = &ld->ld_state; + if (li->li_file != ls->ls_file) { + if (ls->ls_file != NULL) + ld_file_unload(ld, ls->ls_file); + ld_file_load(ld, li->li_file); + } + lf = li->li_file; + if (lf->lf_ar != NULL) { + assert(li->li_lam != NULL); + lam = li->li_lam; + if (elf_rand(lf->lf_elf, lam->lam_off) != lam->lam_off) + ld_fatal(ld, "%s: elf_rand: %s", lf->lf_name, + elf_errmsg(-1)); + if ((li->li_elf = elf_begin(-1, ELF_C_READ, lf->lf_elf)) == + NULL) + ld_fatal(ld, "%s: elf_begin: %s", lf->lf_name, + elf_errmsg(-1)); + } else + li->li_elf = lf->lf_elf; +} + +void +ld_input_unload(struct ld *ld, struct ld_input *li) +{ + struct ld_file *lf; + + (void) ld; + + if (li->li_file == NULL) + return; + + assert(li->li_elf != NULL); + lf = li->li_file; + if (lf->lf_ar != NULL) + (void) elf_end(li->li_elf); + li->li_elf = NULL; +} + +void +ld_input_init_sections(struct ld *ld, struct ld_input *li, Elf *e) +{ + struct ld_input_section *is; + struct ld_section_group *sg; + Elf_Scn *scn, *_scn; + Elf_Data *d, *_d; + char *name; + GElf_Shdr sh; + GElf_Sym sym; + size_t shstrndx, strndx, ndx; + int elferr; + + _d = NULL; + strndx = 0; + + if (elf_getshdrnum(e, &li->li_shnum) < 0) + ld_fatal(ld, "%s: elf_getshdrnum: %s", li->li_name, + elf_errmsg(-1)); + + /* Allocate one more pseudo section to hold common symbols */ + li->li_shnum++; + + assert(li->li_is == NULL); + if ((li->li_is = calloc(li->li_shnum, sizeof(*is))) == NULL) + ld_fatal_std(ld, "%s: calloc: %s", li->li_name); + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + ld_fatal(ld, "%s: elf_getshdrstrndx: %s", li->li_name, + elf_errmsg(-1)); + + (void) elf_errno(); + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) != &sh) + ld_fatal(ld, "%s: gelf_getshdr: %s", li->li_name, + elf_errmsg(-1)); + + if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL) + ld_fatal(ld, "%s: elf_strptr: %s", li->li_name, + elf_errmsg(-1)); + + if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) + ld_fatal(ld, "%s: elf_ndxscn: %s", li->li_name, + elf_errmsg(-1)); + + if (ndx >= li->li_shnum - 1) + ld_fatal(ld, "%s: section index of '%s' section is" + " invalid", li->li_name, name); + + is = &li->li_is[ndx]; + if ((is->is_name = strdup(name)) == NULL) + ld_fatal_std(ld, "%s: calloc", li->li_name); + is->is_off = sh.sh_offset; + is->is_size = sh.sh_size; + is->is_entsize = sh.sh_entsize; + is->is_addr = sh.sh_addr; + is->is_align = sh.sh_addralign; + is->is_type = sh.sh_type; + is->is_flags = sh.sh_flags; + is->is_link = sh.sh_link; + is->is_info = sh.sh_info; + is->is_index = elf_ndxscn(scn); + is->is_shrink = 0; + is->is_input = li; + + /* + * Section groups are identified by their signatures. + * A section group's signature is used to compare with the + * the section groups that are already added. If a match + * is found, the sections included in this section group + * should be discarded. + * + * Note that since signatures are stored in the symbol + * table, in order to handle that here we have to load + * the symbol table earlier. + */ + if (is->is_type == SHT_GROUP) { + is->is_discard = 1; + if (_d == NULL) { + _scn = elf_getscn(e, is->is_link); + if (_scn == NULL) { + ld_warn(ld, "%s: elf_getscn failed" + " with the `sh_link' of group" + " section %ju as index: %s", + li->li_name, ndx, elf_errmsg(-1)); + continue; + } + if (gelf_getshdr(_scn, &sh) != &sh) { + ld_warn(ld, "%s: gelf_getshdr: %s", + li->li_name, elf_errmsg(-1)); + continue; + } + strndx = sh.sh_link; + (void) elf_errno(); + _d = elf_getdata(_scn, NULL); + if (_d == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s: elf_getdata" + " failed: %s", li->li_name, + elf_errmsg(elferr)); + continue; + } + } + if (gelf_getsym(_d, is->is_info, &sym) != &sym) { + ld_warn(ld, "%s: gelf_getsym failed (section" + " group signature): %s", li->li_name, + elf_errmsg(-1)); + continue; + } + if ((name = elf_strptr(e, strndx, sym.st_name)) == + NULL) { + ld_warn(ld, "%s: elf_strptr failed (section" + " group signature): %s", li->li_name, + elf_errmsg(-1)); + continue; + } + + /* + * Search the currently added section groups for the + * signature. If found, this section group should not + * be added and the sections it contains should be + * discarded. If not found, we add this section group + * to the set. + */ + HASH_FIND_STR(ld->ld_sg, name, sg); + if (sg != NULL) + _discard_section_group(ld, li, scn); + else { + if ((sg = calloc(1, sizeof(*sg))) == NULL) + ld_fatal_std(ld, "%s: calloc", + li->li_name); + if ((sg->sg_name = strdup(name)) == NULL) + ld_fatal_std(ld, "%s: strdup", + li->li_name); + HASH_ADD_KEYPTR(hh, ld->ld_sg, sg->sg_name, + strlen(sg->sg_name), sg); + } + } + + /* + * Check for informational sections which should not + * be included in the output object, process them + * and mark them as discarded if need. + */ + + if (strcmp(is->is_name, ".note.GNU-stack") == 0) { + ld->ld_gen_gnustack = 1; + if (is->is_flags & SHF_EXECINSTR) + ld->ld_stack_exec = 1; + is->is_discard = 1; + continue; + } + + /* + * The content of input .eh_frame section is preloaded for + * output .eh_frame optimization. + */ + if (strcmp(is->is_name, ".eh_frame") == 0) { + if ((d = elf_rawdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s(%s): elf_rawdata " + "failed: %s", li->li_name, + is->is_name, elf_errmsg(elferr)); + continue; + } + + if (d->d_buf == NULL || d->d_size == 0) + continue; + + if ((is->is_ehframe = malloc(d->d_size)) == NULL) + ld_fatal_std(ld, "malloc"); + + memcpy(is->is_ehframe, d->d_buf, d->d_size); + is->is_ibuf = is->is_ehframe; + } + } + elferr = elf_errno(); + if (elferr != 0) + ld_fatal(ld, "%s: elf_nextscn failed: %s", li->li_name, + elf_errmsg(elferr)); +} + +void +ld_input_alloc_common_symbol(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_input *li; + struct ld_input_section *is; + + li = lsb->lsb_input; + if (li == NULL) + return; /* unlikely */ + + /* + * Do not allocate memory for common symbols when the linker + * creates a relocatable output object, unless option -d is + * specified. + */ + if (ld->ld_reloc && !ld->ld_common_alloc) + return; + + is = &li->li_is[li->li_shnum - 1]; + if (is->is_name == NULL) { + /* + * Create a pseudo section named COMMON to keep track of + * common symbols. + */ + if ((is->is_name = strdup("COMMON")) == NULL) + ld_fatal_std(ld, "%s: calloc", li->li_name); + is->is_off = 0; + is->is_size = 0; + is->is_entsize = 0; + is->is_align = 1; + is->is_type = SHT_NOBITS; + is->is_flags = SHF_ALLOC | SHF_WRITE; + is->is_link = 0; + is->is_info = 0; + is->is_index = SHN_COMMON; + is->is_input = li; + } + + /* + * Allocate space for this symbol in the pseudo COMMON section. + * Properly handle the alignment. (For common symbols, symbol + * value stores the required alignment) + */ + if (lsb->lsb_value > is->is_align) + is->is_align = lsb->lsb_value; + is->is_size = roundup(is->is_size, is->is_align); + lsb->lsb_value = is->is_size; + is->is_size += lsb->lsb_size; +} + +static void +_discard_section_group(struct ld *ld, struct ld_input *li, Elf_Scn *scn) +{ + Elf_Data *d; + uint32_t *w; + int elferr, i; + + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s: elf_getdata failed (section group):" + " %s", li->li_name, elf_errmsg(elferr)); + return; + } + + if (d->d_buf == NULL || d->d_size == 0) + return; + + w = d->d_buf; + if ((*w & GRP_COMDAT) == 0) + return; + + for (i = 1; (size_t) i < d->d_size / 4; i++) { + if (w[i] < li->li_shnum - 1) + li->li_is[w[i]].is_discard = 1; + } +} + +static off_t +_offset_sort(struct ld_archive_member *a, struct ld_archive_member *b) +{ + + return (a->lam_off - b->lam_off); +} diff --git a/contrib/elftoolchain/ld/ld_input.h b/contrib/elftoolchain/ld/ld_input.h new file mode 100644 index 0000000000..48a00eafec --- /dev/null +++ b/contrib/elftoolchain/ld/ld_input.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_input.h 2960 2013-08-25 03:13:07Z kaiwang27 $ + */ + +struct ld_reloc_entry_head; +struct ld_ehframe_fde_head; + +struct ld_section_group { + char *sg_name; + UT_hash_handle hh; +}; + +struct ld_input_section { + char *is_name; /* section name */ + struct ld_input *is_input; /* containing input object */ + struct ld_output_section *is_output; /* containing output section */ + uint64_t is_off; /* section file offset */ + uint64_t is_reloff; /* relative offset in output section */ + uint64_t is_addr; /* section vma */ + uint64_t is_size; /* section file size */ + uint64_t is_shrink; /* section shrinked bytes */ + uint64_t is_entsize; /* seciton entry size */ + uint64_t is_align; /* section align */ + uint64_t is_type; /* section type */ + uint64_t is_flags; /* section flags */ + uint64_t is_link; /* section link */ + uint64_t is_info; /* section info */ + uint64_t is_index; /* section index */ + unsigned char is_discard; /* dicard section */ + unsigned char is_dynrel; /* section holds dynamic relocations */ + unsigned char is_pltrel; /* section holds PLT relocations */ + unsigned char is_refed; /* should not be gc'ed */ + unsigned char is_need_reloc; /* need apply relocation */ + void *is_data; /* output section data descriptor */ + void *is_ibuf; /* buffer for internal sections */ + void *is_ehframe; /* temp buffer for ehframe section. */ + struct ld_reloc_entry_head *is_reloc; /* list of relocation entries */ + uint64_t is_num_reloc; /* number of reloc entries */ + struct ld_input_section *is_tis; /* relocation target */ + struct ld_input_section *is_ris; /* relocation section */ + struct ld_ehframe_fde_head *is_fde; /* list of FDE */ + STAILQ_ENTRY(ld_input_section) is_next; /* next section */ + STAILQ_ENTRY(ld_input_section) is_gc_next; /* next gc search */ + UT_hash_handle hh; /* hash handle (internal section) */ +}; + +STAILQ_HEAD(ld_input_section_head, ld_input_section); + +enum ld_input_type { + LIT_UNKNOWN, + LIT_RELOCATABLE, + LIT_DSO, +}; + +struct ld_symver_verdef_head; + +struct ld_input { + char *li_name; /* input object name */ + char *li_fullname; /* input object and archive name */ + char *li_soname; /* input object DT_SONAME. */ + Elf *li_elf; /* input object ELF descriptor */ + enum ld_input_type li_type; /* input object kind */ + struct ld_file *li_file; /* containing file */ + size_t li_shnum; /* num of sections in ELF object */ + struct ld_input_section *li_is; /* input section list */ + struct ld_input_section *li_istbl; /* internal section hash table */ + struct ld_archive_member *li_lam; /* archive member */ + struct ld_symbol_head *li_local; /* local symbol list */ + struct ld_symbol **li_symindex; /* symbol index table */ + size_t li_symnum; /* number of symbols */ + char **li_vername; /* version name array */ + size_t li_vername_sz; /* version name array size */ + uint16_t *li_versym; /* symbol version array */ + size_t li_versym_sz; /* symbol version array size */ + int li_dso_refcnt; /* symbol reference count (DSO) */ + struct ld_symver_verdef_head *li_verdef; /* version definition */ + STAILQ_ENTRY(ld_input) li_next; /* next input object */ +}; + +void ld_input_init(struct ld *); +void ld_input_add_symbol(struct ld *, struct ld_input *, + struct ld_symbol *); +struct ld_input_section *ld_input_add_internal_section(struct ld *, + const char *); +struct ld_input_section *ld_input_find_internal_section(struct ld *, + const char *); +void ld_input_alloc_internal_section_buffers(struct ld *); +struct ld_input *ld_input_alloc(struct ld *, struct ld_file *, const char *); +void ld_input_alloc_common_symbol(struct ld *, struct ld_symbol *); +void *ld_input_get_section_rawdata(struct ld *, struct ld_input_section *); +void ld_input_cleanup(struct ld *); +char *ld_input_get_fullname(struct ld *, struct ld_input *); +void ld_input_init_sections(struct ld *, struct ld_input *, Elf *); +void ld_input_link_objects(struct ld *); +void ld_input_load(struct ld *, struct ld_input *); +void ld_input_unload(struct ld *, struct ld_input *); +uint64_t ld_input_reserve_ibuf(struct ld_input_section *, uint64_t); diff --git a/contrib/elftoolchain/ld/ld_layout.c b/contrib/elftoolchain/ld/ld_layout.c new file mode 100644 index 0000000000..747054f6e0 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_layout.c @@ -0,0 +1,1253 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_ehframe.h" +#include "ld_exp.h" +#include "ld_file.h" +#include "ld_script.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_layout.h" +#include "ld_options.h" +#include "ld_symbols.h" +#include "ld_strtab.h" + +ELFTC_VCSID("$Id: ld_layout.c 3884 2020-11-11 18:29:42Z jkoshy $"); + +struct ld_wildcard_match { + char *wm_name; + unsigned wm_no_match; + struct ld_output_section *wm_os; + struct ld_input_section_head *wm_islist; + struct ld_script_sections_output_input *wm_ldoi; + struct ld_wildcard_match *wm_next; + UT_hash_handle hh; +}; + +/* + * Support routines for output section layout. + */ + +static void _calc_offset(struct ld *ld); +static void _calc_output_section_offset(struct ld *ld, + struct ld_output_section *os); +static void _calc_reloc_section_offset(struct ld *ld, struct ld_output *lo); +static void _calc_shdr_offset(struct ld *ld); +static int _check_filename_constraint(struct ld_input *li, + struct ld_script_sections_output_input *ldoi); +static void _insert_input_to_output(struct ld *ld, struct ld_output *lo, + struct ld_output_section *os, struct ld_input_section *is, + struct ld_input_section_head *islist); +static void _layout_input_sections(struct ld *ld, struct ld_input *li); +static void _layout_orphan_section(struct ld *ld, struct ld_input_section *is); +static void _layout_sections(struct ld *ld, struct ld_script_sections *ldss); +static void _parse_output_section_descriptor(struct ld *ld, + struct ld_output_section *os); +static void _prepare_output_section(struct ld *ld, + struct ld_script_sections_output *ldso); +static void _print_section_layout(struct ld *ld, struct ld_output_section *os); +static void _print_wildcard(struct ld_wildcard *lw); +static void _print_wildcard_list(struct ld_script_list *ldl); +static void _record_wildcard_match(struct ld *ld, char *name, + struct ld_output_section *os, struct ld_output_element *oe); +static void _record_wildcard_no_match(struct ld *ld, char *name); +static void _set_output_section_loadable_flag(struct ld_output_section *os); +static int _wildcard_match(struct ld_wildcard *lw, const char *string); +static int _wildcard_list_match(struct ld_script_list *list, + const char *string); + +void +ld_layout_sections(struct ld *ld) +{ + struct ld_output *lo; + struct ld_script *lds; + struct ld_script_cmd *ldc; + int sections_cmd_exist; + + lo = ld->ld_output; + lds = ld->ld_scp; + + sections_cmd_exist = 0; + STAILQ_FOREACH(ldc, &lds->lds_c, ldc_next) { + switch (ldc->ldc_type) { + case LSC_ASSERT: + ld_output_create_element(ld, &lo->lo_oelist, OET_ASSERT, + ldc->ldc_cmd, NULL); + break; + case LSC_ASSIGN: + ld_output_create_element(ld, &lo->lo_oelist, OET_ASSIGN, + ldc->ldc_cmd, NULL); + break; + case LSC_ENTRY: + ld_output_create_element(ld, &lo->lo_oelist, OET_ENTRY, + ldc->ldc_cmd, NULL); + break; + case LSC_SECTIONS: + if (sections_cmd_exist) + ld_fatal(ld, "found multiple SECTIONS commands" + " in the linker script"); + sections_cmd_exist = 1; + _layout_sections(ld, ldc->ldc_cmd); + break; + default: + break; + } + } + + if (!sections_cmd_exist) + _layout_sections(ld, NULL); + + /* Scan and optimize .eh_frame section. */ + ld_ehframe_scan(ld); + + /* Initialise sections for dyanmically linked output object. */ + ld_dynamic_create(ld); + + /* Create ELF sections. */ + ld_output_create_elf_sections(ld); + + /* Calculate section offsets of the output object. */ + _calc_offset(ld); + + /* Calculate symbol values and indices of the output object. */ + ld_symbols_update(ld); + + /* Print out link map if requested. */ + if (ld->ld_print_linkmap) + ld_layout_print_linkmap(ld); +} + +void +ld_layout_print_linkmap(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + struct ld_output *lo; + struct ld_output_element *oe; + struct ld_script *lds; + int i; + + lo = ld->ld_output; + assert(lo != NULL); + + /* Print out the list of discarded sections. */ + printf("\nDiscarded input sections:\n\n"); + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + for (i = 0; (size_t) i < li->li_shnum; i++) { + is = &li->li_is[i]; + if (is->is_discard) { + printf(" %-20s ", is->is_name); + if (lo->lo_ec == ELFCLASS32) + printf("0x%08jx ", + (uintmax_t) is->is_addr); + else + printf("0x%016jx ", + (uintmax_t) is->is_addr); + printf("0x%jx ", (uintmax_t) is->is_size); + printf("%s\n", ld_input_get_fullname(ld, li)); + } + } + } + + + lds = ld->ld_scp; + if (lds == NULL) + return; + + /* TODO: Dump memory configuration */ + + printf("\nLinker script and memory map\n\n"); + + /* TODO: Dump loaded objects. */ + + STAILQ_FOREACH(oe, &lo->lo_oelist, oe_next) { + + switch (oe->oe_type) { + case OET_ASSERT: + /* TODO */ + break; + case OET_ASSIGN: + ld_script_assign_dump(ld, oe->oe_entry); + break; + case OET_ENTRY: + /* TODO */ + break; + case OET_OUTPUT_SECTION: + _print_section_layout(ld, oe->oe_entry); + break; + default: + break; + } + } +} + +static void +_print_section_layout(struct ld *ld, struct ld_output_section *os) +{ + struct ld_input_section *is; + struct ld_input_section_head *islist; + struct ld_output *lo; + struct ld_output_element *oe; + struct ld_script_sections_output_input *ldoi; + + lo = ld->ld_output; + + if (os->os_empty) + printf("\n%s\n", os->os_name); + else { + printf("\n%-15s", os->os_name); + if (lo->lo_ec == ELFCLASS32) + printf(" 0x%08jx", (uintmax_t) os->os_addr); + else + printf(" 0x%016jx", (uintmax_t) os->os_addr); + printf(" %#10jx\n", (uintmax_t) os->os_size); + } + + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + switch (oe->oe_type) { + case OET_ASSIGN: + ld_script_assign_dump(ld, oe->oe_entry); + break; + case OET_INPUT_SECTION_LIST: + /* + * Print out wildcard patterns and input sections + * matched by these patterns. + */ + ldoi = oe->oe_entry; + if (ldoi == NULL) + break; + putchar(' '); + if (ldoi->ldoi_ar) { + _print_wildcard(ldoi->ldoi_ar); + putchar(':'); + } + _print_wildcard(ldoi->ldoi_file); + putchar('('); + if (ldoi->ldoi_exclude) { + printf("(EXCLUDE_FILE("); + _print_wildcard_list(ldoi->ldoi_exclude); + putchar(')'); + putchar(' '); + } + _print_wildcard_list(ldoi->ldoi_sec); + putchar(')'); + putchar('\n'); + if ((islist = oe->oe_islist) == NULL) + break; + STAILQ_FOREACH(is, islist, is_next) { + if (!strcmp(is->is_name, "COMMON") && + is->is_size == 0) + continue; + printf(" %-14s", is->is_name); + if (lo->lo_ec == ELFCLASS32) + printf(" 0x%08jx", (uintmax_t) + (os->os_addr + is->is_reloff)); + else + printf(" 0x%016jx", (uintmax_t) + (os->os_addr + is->is_reloff)); + if (is->is_size == 0) + printf(" %10s", "0x0"); + else + printf(" %#10jx", (uintmax_t) + is->is_size); + printf(" %s\n", ld_input_get_fullname(ld, + is->is_input)); + } + break; + default: + break; + } + } +} + +static void +_print_wildcard(struct ld_wildcard *lw) +{ + + switch (lw->lw_sort) { + case LWS_NONE: + printf("%s", lw->lw_name); + break; + case LWS_NAME: + printf("SORT_BY_NAME(%s)", lw->lw_name); + break; + case LWS_ALIGN: + printf("SORT_BY_ALIGNMENT(%s)", lw->lw_name); + break; + case LWS_NAME_ALIGN: + printf("SORT_BY_NAME(SORT_BY_ALIGNMENT(%s))", lw->lw_name); + break; + case LWS_ALIGN_NAME: + printf("SORT_BY_ALIGNMENT(SORT_BY_NAME(%s))", lw->lw_name); + break; + default: + break; + } +} + +static void +_print_wildcard_list(struct ld_script_list *ldl) +{ + + _print_wildcard(ldl->ldl_entry); + if (ldl->ldl_next != NULL) { + putchar(' '); + _print_wildcard_list(ldl->ldl_next); + } +} + +off_t +ld_layout_calc_header_size(struct ld *ld) +{ + struct ld_script_phdr *ldsp; + struct ld_output *lo; + struct ld_output_section *os; + off_t header_size; + unsigned ec, w, num_phdrs; + int new, tls; + + lo = ld->ld_output; + assert(lo != NULL); + + header_size = 0; + + ec = elftc_bfd_target_class(ld->ld_otgt); + + if (ec == ELFCLASS32) + header_size += sizeof(Elf32_Ehdr); + else + header_size += sizeof(Elf64_Ehdr); + + /* Do not generate segments for relocatable output. */ + if (ld->ld_reloc) { + lo->lo_phdr_num = 0; + return (header_size); + } + + if (!STAILQ_EMPTY(&ld->ld_scp->lds_p)) { + num_phdrs = 0; + STAILQ_FOREACH(ldsp, &ld->ld_scp->lds_p, ldsp_next) + num_phdrs++; + } else { + if (lo->lo_phdr_num > 0) + num_phdrs = lo->lo_phdr_num; + else { + num_phdrs = 0; + new = 1; + tls = 0; + w = 0; + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_empty) + continue; + + if ((os->os_flags & SHF_ALLOC) == 0) { + new = 1; + continue; + } + + if ((os->os_flags & SHF_WRITE) != w || new) { + new = 0; + num_phdrs++; + w = os->os_flags & SHF_WRITE; + } + + if ((os->os_flags & SHF_TLS) != 0 && !tls) { + tls = 1; + num_phdrs++; + } + } + + /* + * PT_PHDR and PT_DYNAMIC for dynamic linking. But + * do not create PT_PHDR for shared libraries. + */ + if (lo->lo_dso_needed > 0) { + num_phdrs++; + if (!ld->ld_dso) + num_phdrs++; + } + + if (lo->lo_interp != NULL) + num_phdrs++; + + if (lo->lo_phdr_note) + num_phdrs++; + + if (ld->ld_ehframe_hdr) + num_phdrs++; + + if (ld->ld_gen_gnustack) + num_phdrs++; + } + } + + if (ec == ELFCLASS32) + header_size += num_phdrs * sizeof(Elf32_Phdr); + else + header_size += num_phdrs * sizeof(Elf64_Phdr); + + lo->lo_phdr_num = num_phdrs; + + return (header_size); +} + +static void +_layout_sections(struct ld *ld, struct ld_script_sections *ldss) +{ + struct ld_input *li; + struct ld_output *lo; + struct ld_script_cmd *ldc; + + lo = ld->ld_output; + + /* + * Process commands inside the SECTIONS command and create + * output elements. + */ + STAILQ_FOREACH(ldc, &ldss->ldss_c, ldc_next) { + switch (ldc->ldc_type) { + case LSC_ASSERT: + ld_output_create_element(ld, &lo->lo_oelist, + OET_ASSERT, ldc->ldc_cmd, NULL); + break; + case LSC_ASSIGN: + ld_output_create_element(ld, &lo->lo_oelist, + OET_ASSIGN, ldc->ldc_cmd, NULL); + break; + case LSC_ENTRY: + ld_output_create_element(ld, &lo->lo_oelist, + OET_ENTRY, ldc->ldc_cmd, NULL); + break; + case LSC_SECTIONS_OUTPUT: + _prepare_output_section(ld, ldc->ldc_cmd); + break; + case LSC_SECTIONS_OVERLAY: + /* TODO */ + break; + default: + break; + } + } + + /* Lay out each input object. */ + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + + /* Only lay out relocatable input objects. */ + if (li->li_type != LIT_RELOCATABLE) + continue; + + /* Lay out sections for the input object. */ + _layout_input_sections(ld, li); + } +} + +static void +_prepare_output_section(struct ld *ld, struct ld_script_sections_output *ldso) +{ + struct ld_script_cmd *ldc; + struct ld_input_section_head *islist; + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_element *oe; + + lo = ld->ld_output; + + HASH_FIND_STR(lo->lo_ostbl, ldso->ldso_name, os); + if (os != NULL) + return; + + os = ld_output_alloc_section(ld, ldso->ldso_name, NULL, NULL); + os->os_ldso = ldso; + _set_output_section_loadable_flag(os); + + STAILQ_FOREACH(ldc, &ldso->ldso_c, ldc_next) { + switch (ldc->ldc_type) { + case LSC_ASSERT: + oe = ld_output_create_section_element(ld, os, + OET_ASSERT, ldc->ldc_cmd, NULL); + break; + case LSC_ASSIGN: + oe = ld_output_create_section_element(ld, os, + OET_ASSIGN, ldc->ldc_cmd, NULL); + break; + case LSC_SECTIONS_OUTPUT_DATA: + oe = ld_output_create_section_element(ld, os, + OET_DATA, ldc->ldc_cmd, NULL); + break; + case LSC_SECTIONS_OUTPUT_INPUT: + islist = calloc(1, sizeof(*islist)); + if (islist == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(islist); + oe = ld_output_create_section_element(ld, os, + OET_INPUT_SECTION_LIST, ldc->ldc_cmd, NULL); + oe->oe_islist = islist; + break; + case LSC_SECTIONS_OUTPUT_KEYWORD: + ld_output_create_section_element(ld, os, + OET_KEYWORD, ldc->ldc_cmd, NULL); + break; + default: + ld_fatal(ld, "internal: invalid output section " + "command: %d", ldc->ldc_type); + } + } +} + +static int +_wildcard_match(struct ld_wildcard *lw, const char *string) +{ + + return (fnmatch(lw->lw_name, string, 0) == 0); +} + +static int +_wildcard_list_match(struct ld_script_list *list, const char *string) +{ + struct ld_script_list *ldl; + + for (ldl = list; ldl != NULL; ldl = ldl->ldl_next) + if (_wildcard_match(ldl->ldl_entry, string)) + return (1); + + return (0); +} + +static void +_set_output_section_loadable_flag(struct ld_output_section *os) +{ + struct ld_script_sections_output *ldso; + struct ld_exp *le; + + if ((ldso = os->os_ldso) == NULL) + return; + + if (ldso->ldso_vma == NULL) + os->os_flags |= SHF_ALLOC; + else { + le = ldso->ldso_vma; + if (le->le_op != LEOP_CONSTANT || le->le_val != 0) + os->os_flags |= SHF_ALLOC; + } + + if (ldso->ldso_type != NULL && strcmp(ldso->ldso_type, "NOLOAD") == 0) + os->os_flags &= ~SHF_ALLOC; +} + +static int +_check_filename_constraint(struct ld_input *li, + struct ld_script_sections_output_input *ldoi) +{ + struct ld_file *lf; + + /* Internal sections always suffice any constraint. */ + if (li->li_name == NULL) + return (1); + + lf = li->li_file; + + if (ldoi->ldoi_ar != NULL && li->li_lam != NULL && + !_wildcard_match(ldoi->ldoi_ar, lf->lf_name)) + return (0); + + assert(ldoi->ldoi_file != NULL); + if (!_wildcard_match(ldoi->ldoi_file, li->li_name)) + return (0); + + if (ldoi->ldoi_exclude != NULL && + _wildcard_list_match(ldoi->ldoi_exclude, li->li_name)) + return (0); + + return (1); +} + +static void +_record_wildcard_match(struct ld *ld, char *name, struct ld_output_section *os, + struct ld_output_element *oe) +{ + struct ld_wildcard_match *wm, *_wm; + + assert(name != NULL && os != NULL); + assert(oe != NULL && oe->oe_type == OET_INPUT_SECTION_LIST); + + HASH_FIND_STR(ld->ld_wm, name, wm); + + /* Create a new wildcard match. */ + if (wm == NULL) { + if ((wm = calloc(1, sizeof(*wm))) == NULL) + ld_fatal_std(ld, "calloc"); + if ((wm->wm_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + wm->wm_os = os; + wm->wm_islist = oe->oe_islist; + wm->wm_ldoi = oe->oe_entry; + wm->wm_next = NULL; + HASH_ADD_KEYPTR(hh, ld->ld_wm, wm->wm_name, + strlen(wm->wm_name), wm); + return; + } + + /* + * Wildcard match already exist, compare the "ldoi" to check + * if this is a new wildcard match with a different file/archive + * constraint. If so, Insert it to the tail of the wildcard match + * list. + */ + do { + if (oe->oe_entry == (void *) wm->wm_ldoi) + return; + } while (wm->wm_next != NULL && (wm = wm->wm_next)); + + if ((_wm = calloc(1, sizeof(*_wm))) == NULL) + ld_fatal_std(ld, "calloc"); + _wm->wm_os = os; + _wm->wm_islist = oe->oe_islist; + _wm->wm_ldoi = oe->oe_entry; + _wm->wm_next = NULL; + wm->wm_next = _wm; +} + +static void +_record_wildcard_no_match(struct ld *ld, char *name) +{ + struct ld_wildcard_match *wm; + + assert(name != NULL); + + HASH_FIND_STR(ld->ld_wm, name, wm); + + /* + * Unfortunately this section is an orphan section because + * it doesn't satisfy the file/archive constraint but does + * match certain section name wildcard. We can not record this. + */ + if (wm != NULL) + return; + + /* Create the wildcard "no-match" for the orphan. */ + if ((wm = calloc(1, sizeof(*wm))) == NULL) + ld_fatal_std(ld, "calloc"); + if ((wm->wm_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + wm->wm_no_match = 1; +} + +static void +_layout_input_sections(struct ld *ld, struct ld_input *li) +{ + struct ld_input_section *is; + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_element *oe; + struct ld_wildcard_match *wm; + struct ld_script_sections_output_input *ldoi; + int i; + + lo = ld->ld_output; + + for (i = 0; (size_t) i < li->li_shnum; i++) { + + is = &li->li_is[i]; + + if (is->is_type == SHT_NULL) + continue; + + /* Ignore discarded section groups. */ + if (is->is_discard) + continue; + + if (strcmp(is->is_name, ".shstrtab") == 0 || + strcmp(is->is_name, ".symtab") == 0 || + strcmp(is->is_name, ".strtab") == 0) + continue; + + /* Search the wildcard match table for a quick match. */ + HASH_FIND_STR(ld->ld_wm, is->is_name, wm); + if (wm != NULL) { + if (wm->wm_no_match) { + /* + * We found a "no-match". This is certainly + * an orphan section. + */ + _layout_orphan_section(ld, is); + continue; + } + } else + goto full_search; + + /* There is a match! Verify file/archive constraint. */ + while (wm != NULL) { + ldoi = wm->wm_ldoi; + + if (!_check_filename_constraint(li, ldoi)) + goto next_wm; + + if (strcmp(wm->wm_os->os_name, "/DISCARD/") == 0) { + is->is_discard = 1; + break; + } + + /* + * File/archive constraint satisfied. Insert the + * this section to the input section list of the + * output section element. + */ + _insert_input_to_output(ld, lo, wm->wm_os, is, + wm->wm_islist); + break; + + next_wm: + wm = wm->wm_next; + } + + if (wm != NULL) + continue; + + full_search: + + /* + * Otherwise, we have to do a full search for the section + * name in all the wildcard list. + */ + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + + if (oe->oe_type != OET_INPUT_SECTION_LIST) + continue; + + /* + * Skip output sections created for orphan + * input sections. They don't have wildcard + * list. + */ + if ((ldoi = oe->oe_entry) == NULL) + continue; + + /* Check if the section name match wildcard */ + assert(ldoi->ldoi_sec != NULL); + if (!_wildcard_list_match(ldoi->ldoi_sec, + is->is_name)) + continue; + + /* + * Record this wildcard match to speed up + * wildcard match for sections with the same + * name. + */ + _record_wildcard_match(ld, is->is_name, os, + oe); + + /* Check file/archive constraint. */ + if (!_check_filename_constraint(li, ldoi)) { + continue; + } + + /* Check if we should discard the section. */ + if (strcmp(os->os_name, "/DISCARD/") == 0) { + is->is_discard = 1; + goto next_input_section; + } + + /* Match! Insert to the input section list. */ + _insert_input_to_output(ld, lo, os, is, + oe->oe_islist); + goto next_input_section; + } + } + + /* + * We found an orphan section. Record this so we can quickly + * identify other orphan sections with the same name. + */ + _record_wildcard_no_match(ld, is->is_name); + + /* Lay out the orphan section. */ + _layout_orphan_section(ld, is); + + next_input_section: + ; + } +} + +static void +_layout_orphan_section(struct ld *ld, struct ld_input_section *is) +{ + struct ld_input_section_head *islist; + struct ld_output *lo; + struct ld_output_element *oe; + struct ld_output_section *os, *_os; + + /* + * Layout the input sections that are not listed in the output + * section descriptor in the linker script. + */ + + lo = ld->ld_output; + + if (is->is_discard) + return; + + if (strcmp(is->is_name, ".shstrtab") == 0 || + strcmp(is->is_name, ".symtab") == 0 || + strcmp(is->is_name, ".strtab") == 0) + return; + + if ((is->is_type == SHT_REL || is->is_type == SHT_RELA) && + !is->is_dynrel) + return; + + /* + * When garbage collection is enabled (option `-gc-sections' + * specified), remove sections that are not used. + */ + if (ld->ld_gc) { + if ((is->is_flags & SHF_ALLOC) != 0 && !is->is_refed) { + if (ld->ld_gc_print) + ld_info(ld, "Remove unused ection `%s' in " + "file %s", is->is_name, + ld_input_get_fullname(ld, is->is_input)); + return; + } + } + + HASH_FIND_STR(lo->lo_ostbl, is->is_name, os); + if (os != NULL) { + oe = STAILQ_FIRST(&os->os_e); + assert(oe != NULL && + oe->oe_type == OET_INPUT_SECTION_LIST); + _insert_input_to_output(ld, lo, os, is, oe->oe_islist); + return; + } + + /* + * Create a new output secton and put it in a proper place, + * based on the section flag. + */ + _os = ld_layout_insert_output_section(ld, is->is_name, + is->is_flags); + + if ((islist = calloc(1, sizeof(*islist))) == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(islist); + + oe = ld_output_create_section_element(ld, _os, OET_INPUT_SECTION_LIST, + NULL, NULL); + oe->oe_islist = islist; + _insert_input_to_output(ld, lo, _os, is, oe->oe_islist); +} + +struct ld_output_section * +ld_layout_insert_output_section(struct ld *ld, const char *name, + uint64_t flags) +{ + struct ld_output *lo; + struct ld_output_section *os, *_os; + + lo = ld->ld_output; + assert(lo != NULL); + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if ((os->os_flags & SHF_ALLOC) != (flags & SHF_ALLOC)) + continue; + + if (os->os_flags == flags) { + _os = STAILQ_NEXT(os, os_next); + if (_os == NULL || _os->os_flags != flags) + break; + } + + _os = STAILQ_NEXT(os, os_next); + if (_os != NULL && + (_os->os_flags & SHF_ALLOC) != (flags & SHF_ALLOC)) + break; + } + + _os = ld_output_alloc_section(ld, name, os, NULL); + _os->os_flags |= flags & SHF_ALLOC; + + return (_os); +} + +static void +_insert_input_to_output(struct ld *ld, struct ld_output *lo, + struct ld_output_section *os, struct ld_input_section *is, + struct ld_input_section_head *islist) +{ + struct ld_output_section *_os; + char *name; + int len; + + /* + * Relocation sections is handled separately. + */ + if ((is->is_type == SHT_REL || is->is_type == SHT_RELA) && + !is->is_dynrel) + return; + + os->os_empty = 0; + + os->os_flags |= is->is_flags & (SHF_EXECINSTR | SHF_WRITE | SHF_TLS); + os->os_dynrel |= is->is_dynrel; + os->os_pltrel |= is->is_pltrel; + + if (!is->is_dynrel && !is->is_pltrel && is->is_type != SHT_NOBITS && + is->is_size != 0) + is->is_need_reloc = 1; + + if (is->is_align > os->os_align) + os->os_align = is->is_align; + + /* + * The entsize of the output section is determined by the + * input sections it contains. If all the input sections has + * the same entsize, the output section will also have that + * entsize. If any input section has a different entsize, + * the entsize for output section is set to 0, meaning that + * it has variable entry sizes. + */ + if (!os->os_entsize_set) { + os->os_entsize = is->is_entsize; + os->os_entsize_set = 1; + } else if (os->os_entsize != is->is_entsize) + os->os_entsize = 0; + + if (os->os_type == SHT_NULL) + os->os_type = is->is_type; + if (is->is_type == SHT_NOTE) + lo->lo_phdr_note = 1; + + is->is_output = os; + + STAILQ_INSERT_TAIL(islist, is, is_next); + + /* + * Lay out relocation section for this input section if the linker + * creates relocatable output object or if -emit-relocs option is + * sepcified. + */ + if ((ld->ld_reloc || ld->ld_emit_reloc) && is->is_ris != NULL && + is->is_ris->is_num_reloc > 0) { + if (os->os_r == NULL) { + /* + * Create relocation section for output sections. + */ + if (ld->ld_arch->reloc_is_rela) { + len = strlen(os->os_name) + 6; + if ((name = malloc(len)) == NULL) + ld_fatal_std(ld, "malloc"); + snprintf(name, len, ".rela%s", os->os_name); + } else { + len = strlen(os->os_name) + 5; + if ((name = malloc(len)) == NULL) + ld_fatal_std(ld, "malloc"); + snprintf(name, len, ".rel%s", os->os_name); + } + _os = ld_output_alloc_section(ld, name, NULL, os); + _os->os_rel = 1; + + /* + * Fill in entry size, alignment and type for output + * relocation sections. + */ + _os->os_entsize = ld->ld_arch->reloc_entsize; + _os->os_type = ld->ld_arch->reloc_is_rela ? SHT_RELA : + SHT_REL; + _os->os_align = ld->ld_arch->reloc_is_64bit ? 8 : 4; + + /* Setup sh_link and sh_info. */ + if ((_os->os_link = strdup(".symtab")) == NULL) + ld_fatal_std(ld, "strdup"); + _os->os_info = os; + + /* Relocation sections are not allocated in memory. */ + _os->os_addr = 0; + } else + _os = os->os_r; + + _os->os_size += is->is_ris->is_num_reloc * _os->os_entsize; + } + +} + +static void +_parse_output_section_descriptor(struct ld *ld, struct ld_output_section *os) +{ + struct ld_script_sections_output *ldso; + + if ((ldso = os->os_ldso) == NULL) + return; + + if (ldso->ldso_vma != NULL) + os->os_addr = ld_exp_eval(ld, ldso->ldso_vma); + + if (ldso->ldso_lma != NULL) + os->os_lma = ld_exp_eval(ld, ldso->ldso_lma); + + if (ldso->ldso_align != NULL) + os->os_align = ld_exp_eval(ld, ldso->ldso_align); + + /* TODO: handle other output section parameters. */ +} + +static void +_calc_offset(struct ld *ld) +{ + struct ld_state *ls; + struct ld_output *lo; + struct ld_output_element *oe; + + ls = &ld->ld_state; + lo = ld->ld_output; + ls->ls_loc_counter = 0; + ls->ls_offset = ld_layout_calc_header_size(ld); + ls->ls_first_output_sec = 1; + + STAILQ_FOREACH(oe, &lo->lo_oelist, oe_next) { + switch (oe->oe_type) { + case OET_ASSERT: + /* TODO */ + break; + case OET_ASSIGN: + ld_script_process_assign(ld, oe->oe_entry); + break; + case OET_ENTRY: + ld_script_process_entry(ld, oe->oe_entry); + break; + case OET_OUTPUT_SECTION: + _parse_output_section_descriptor(ld, oe->oe_entry); + _calc_output_section_offset(ld, oe->oe_entry); + break; + default: + break; + } + } + + /* Emit .note.GNU-stack section for reloctable output object. */ + if (ld->ld_gen_gnustack && ld->ld_reloc) + ld_output_emit_gnu_stack_section(ld); + + /* Lay out section header table after normal input sections. */ + _calc_shdr_offset(ld); + + /* Create .shstrtab section and put it after section header table. */ + ld_output_create_string_table_section(ld, ".shstrtab", + ld->ld_shstrtab, NULL); + + /* Lay out relocation sections. */ + if (ld->ld_reloc || ld->ld_emit_reloc) + _calc_reloc_section_offset(ld, lo); +} + +static void +_calc_output_section_offset(struct ld *ld, struct ld_output_section *os) +{ + struct ld_state *ls; + struct ld_output_element *oe; + struct ld_output_data_buffer *odb; + struct ld_input_section *is; + struct ld_input_section_head *islist; + struct ld_symbol_table *sy; + struct ld_strtab *st; + uint64_t addr; + + /* Relocation sections are handled separately. */ + if (os->os_rel) + return; + + ls = &ld->ld_state; + + /* + * Position independent output object should have VMA from 0. + * So if we are building a DSO or PIE, and this output section is + * the first one, we should set current VMA to SIZEOF_HEADERS + * and ignore all the previous assignments to the location counter. + */ + if ((ld->ld_dso || ld->ld_pie) && ls->ls_first_output_sec) { + ls->ls_loc_counter = ld_layout_calc_header_size(ld); + if (!os->os_empty) + ls->ls_first_output_sec = 0; + } + + /* + * Location counter stores the end VMA offset of the previous output + * section. We use that value as the base VMA offset for this output + * section. + */ + addr = ls->ls_loc_counter; + + /* + * Location counter when refered inside an output section descriptor, + * is an offset relative to the start of the section. + */ + ls->ls_loc_counter = 0; + + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + switch (oe->oe_type) { + case OET_ASSERT: + /* TODO */ + break; + case OET_ASSIGN: + ld_script_process_assign(ld, oe->oe_entry); + break; + case OET_DATA: + /* TODO */ + break; + case OET_DATA_BUFFER: + odb = oe->oe_entry; + odb->odb_off = roundup(ls->ls_loc_counter, + odb->odb_align); + ls->ls_loc_counter = odb->odb_off + odb->odb_size; + break; + case OET_ENTRY: + ld_script_process_entry(ld, oe->oe_entry); + break; + case OET_INPUT_SECTION_LIST: + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) { + if (is->is_size == 0) + continue; + is->is_reloff = roundup(ls->ls_loc_counter, + is->is_align); +#if 0 + printf("\t%s(%s): %#jx,%#jx(%#jx)\n", + is->is_input->li_name, + is->is_name, is->is_reloff, + is->is_size, is->is_align); +#endif + ls->ls_loc_counter = is->is_reloff + + is->is_size; + } + break; + case OET_KEYWORD: + /* TODO */ + break; + case OET_SYMTAB: + assert(ls->ls_loc_counter == 0); + sy = oe->oe_entry; + ls->ls_loc_counter = sy->sy_size * os->os_entsize; + break; + case OET_STRTAB: + assert(ls->ls_loc_counter == 0); + st = oe->oe_entry; + ls->ls_loc_counter = ld_strtab_getsize(st); + break; + default: + break; + } + } + + /* + * Properly align section vma and offset to the required section + * alignment. + */ + + if ((os->os_flags & SHF_ALLOC) != 0 && !ld->ld_reloc) { + if (os->os_ldso == NULL || os->os_ldso->ldso_vma == NULL) + os->os_addr = roundup(addr, os->os_align); + } else + os->os_addr = 0; + + os->os_off = roundup(ls->ls_offset, os->os_align); + os->os_size = ls->ls_loc_counter; + +#if 0 + printf("layout output section %s: (off:%#jx,size:%#jx) " + "vma:%#jx,align:%#jx\n", os->os_name, os->os_off, os->os_size, + os->os_addr, os->os_align); +#endif + + /* + * Calculate the file offset for the next output section. Note that + * only sections with type other than SHT_NOBITS consume file space. + */ + ls->ls_offset = os->os_off; + if (os->os_type != SHT_NOBITS) + ls->ls_offset += os->os_size; + + /* Reset location counter to the current VMA. */ + if (os->os_flags & SHF_ALLOC) { + ls->ls_loc_counter = os->os_addr; + /* + * Do not allocate VMA for TLS .tbss sections. TLS sections + * are only used as an initialization image and .tbss section + * will not be allocated in memory. + */ + if (os->os_type != SHT_NOBITS || (os->os_flags & SHF_TLS) == 0) + ls->ls_loc_counter += os->os_size; + } +} + +static void +_calc_reloc_section_offset(struct ld *ld, struct ld_output *lo) +{ + struct ld_state *ls; + struct ld_output_section *os, *_os; + + ls = &ld->ld_state; + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_r != NULL) { + _os = os->os_r; + _os->os_off = roundup(ls->ls_offset, _os->os_align); + ls->ls_offset = _os->os_off + _os->os_size; + } + } +} + +static void +_calc_shdr_offset(struct ld *ld) +{ + struct ld_state *ls; + struct ld_output *lo; + struct ld_output_section *os; + uint64_t shoff; + int n; + + ls = &ld->ld_state; + lo = ld->ld_output; + + if (lo->lo_ec == ELFCLASS32) + shoff = roundup(ls->ls_offset, 4); + else + shoff = roundup(ls->ls_offset, 8); + + ls->ls_offset = shoff; + + n = 0; + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_scn != NULL) + n++; + } + + /* TODO: n + 2 if ld(1) will not create symbol table. */ + ls->ls_offset += gelf_fsize(lo->lo_elf, ELF_T_SHDR, n + 4, EV_CURRENT); + + lo->lo_shoff = shoff; +} diff --git a/contrib/elftoolchain/ld/ld_layout.h b/contrib/elftoolchain/ld/ld_layout.h new file mode 100644 index 0000000000..43326dbb25 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_layout.h @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2011,2012 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_layout.h 2696 2012-11-24 17:12:24Z kaiwang27 $ + */ + +void ld_layout_sections(struct ld *); +off_t ld_layout_calc_header_size(struct ld *); +struct ld_output_section *ld_layout_insert_output_section(struct ld *, + const char *, uint64_t); +void ld_layout_print_linkmap(struct ld *); diff --git a/contrib/elftoolchain/ld/ld_main.c b/contrib/elftoolchain/ld/ld_main.c new file mode 100644 index 0000000000..4dcae01472 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_main.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_ehframe.h" +#include "ld_options.h" +#include "ld_reloc.h" +#include "ld_script.h" +#include "ld_file.h" +#include "ld_input.h" +#include "ld_layout.h" +#include "ld_output.h" +#include "ld_path.h" +#include "ld_symbols.h" + +ELFTC_VCSID("$Id: ld_main.c 2959 2013-08-25 03:12:47Z kaiwang27 $"); + +static struct ld _ld; +struct ld* ld = &_ld; + +static void +_init(void) +{ + + if ((ld->ld_progname = ELFTC_GETPROGNAME()) == NULL) + ld->ld_progname = "ld"; + + /* Initialise libelf. */ + if (elf_version(EV_CURRENT) == EV_NONE) + ld_fatal(ld, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + /* Initialise internal data structure. */ + TAILQ_INIT(&ld->ld_lflist); + STAILQ_INIT(&ld->ld_lilist); + STAILQ_INIT(&ld->ld_state.ls_lplist); + STAILQ_INIT(&ld->ld_state.ls_rplist); + STAILQ_INIT(&ld->ld_state.ls_rllist); +} + +static void +_cleanup(void) +{ + + ld_script_cleanup(ld); + ld_symbols_cleanup(ld); + ld_path_cleanup(ld); + ld_input_cleanup(ld); + ld_file_cleanup(ld); +} + +int +main(int argc, char **argv) +{ + struct ld_state *ls; + + _init(); + + ls = &ld->ld_state; + + ld->ld_progname = basename(argv[0]); + + ld_arch_init(ld); + +restart: + + /* The linker generate an executable by default */ + ld->ld_exec = 1; + + ld_script_init(ld); + + ld_options_parse(ld, argc, argv); + + ld_output_early_init(ld); + + ls->ls_arch_conflict = 0; + ls->ls_first_elf_object = 1; + + ld_input_init(ld); + + ld_symbols_resolve(ld); + + if (ls->ls_arch_conflict) { + _cleanup(); + ls->ls_rerun = 1; + goto restart; + } + + ld_reloc_load(ld); + + /* + * Perform section garbage collection if command line option + * -gc-sections is specified. Perform deferred relocation scan + * after garbage sections are found. + */ + if (ld->ld_gc) { + ld_reloc_gc_sections(ld); + ld_reloc_deferred_scan(ld); + } + + /* + * Search for undefined symbols and allocate space for common + * symbols. Copy relevant symbols to the dynamic symbol table + * if the linker is performing a dyanmic linking. + */ + ld_symbols_scan(ld); + + /* Create .eh_frame_hdr section. */ + if (ld->ld_ehframe_hdr) + ld_ehframe_create_hdr(ld); + + ld_output_init(ld); + + ld_layout_sections(ld); + + ld_output_create(ld); + + _cleanup(); + + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/ld/ld_options.c b/contrib/elftoolchain/ld/ld_options.c new file mode 100644 index 0000000000..bc26105689 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_options.c @@ -0,0 +1,507 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_file.h" +#include "ld_path.h" +#include "ld_script.h" +#include "ld_symbols.h" +#include "ld_options.h" +#include "ld_output.h" + +ELFTC_VCSID("$Id: ld_options.c 3406 2016-02-14 17:45:43Z jkoshy $"); + +/* + * Support routines for parsing command line options. + */ + +static const char *ld_short_opts = + "b:c:de:Ef:Fgh:iI:l:L:m:MnNo:O::qrR:sStT:xXyY:u:vV()"; + +static struct ld_option ld_opts[] = { + {"aarchive", KEY_STATIC, ONE_DASH, NO_ARG}, + {"adefault", KEY_DYNAMIC, ONE_DASH, NO_ARG}, + {"ashared", KEY_DYNAMIC, ONE_DASH, NO_ARG}, + {"accept-unknown-input-arch", KEY_ACCEPT_UNKNOWN, ANY_DASH, NO_ARG}, + {"allow-multiple-definition", KEY_Z_MULDEFS, ANY_DASH, NO_ARG}, + {"allow-shlib-undefined", KEY_ALLOW_SHLIB_UNDEF, ANY_DASH, NO_ARG}, + {"assert", KEY_ASSERT, ANY_DASH, NO_ARG}, + {"as-needed", KEY_AS_NEEDED, ANY_DASH, NO_ARG}, + {"auxiliary", 'f', ANY_DASH, REQ_ARG}, + {"build-id", KEY_BUILD_ID, ANY_DASH, OPT_ARG}, + {"call_shared", KEY_DYNAMIC, ONE_DASH, NO_ARG}, + {"check-sections", KEY_CHECK_SECTIONS, ANY_DASH, NO_ARG}, + {"cref", KEY_CREF, ANY_DASH, NO_ARG}, + {"defsym", KEY_DEFSYM, ANY_DASH, REQ_ARG}, + {"demangle", KEY_DEMANGLE, ANY_DASH, OPT_ARG}, + {"dc", 'd', ONE_DASH, NO_ARG}, + {"dp", 'd', ONE_DASH, NO_ARG}, + {"disable-new-dtags", KEY_DISABLE_NEW_DTAGS, ANY_DASH, NO_ARG}, + {"discard-all", 'x', ANY_DASH, NO_ARG}, + {"discard-locals", 'X', ANY_DASH, NO_ARG}, + {"dn", KEY_STATIC, ONE_DASH, NO_ARG}, + {"dy", KEY_DYNAMIC, ONE_DASH, NO_ARG}, + {"dynamic-linker", 'I', ANY_DASH, REQ_ARG}, + {"end-group", ')', ANY_DASH, NO_ARG}, + {"entry", 'e', ANY_DASH, REQ_ARG}, + {"error-unresolved-symbols", KEY_ERR_UNRESOLVE_SYM, ANY_DASH, NO_ARG}, + {"export-dynamic", 'E', ANY_DASH, NO_ARG}, + {"eh-frame-hdr", KEY_EH_FRAME_HDR, ANY_DASH, NO_ARG}, + {"emit-relocs", 'q', ANY_DASH, NO_ARG}, + {"emulation", 'm', ANY_DASH, REQ_ARG}, + {"enable-new-dtags", KEY_ENABLE_NEW_DTAGS, ANY_DASH, NO_ARG}, + {"fatal-warnings", KEY_FATAL_WARNINGS, ANY_DASH, NO_ARG}, + {"filter", 'F', ANY_DASH, NO_ARG}, + {"fini", KEY_FINI, ANY_DASH, NO_ARG}, + {"format", 'b', ANY_DASH, REQ_ARG}, + {"gc-sections", KEY_GC_SECTIONS, ANY_DASH, NO_ARG}, + {"hash-style", KEY_HASH_STYLE, ANY_DASH, REQ_ARG}, + {"help", KEY_HELP, ANY_DASH, NO_ARG}, + {"init", KEY_INIT, ANY_DASH, REQ_ARG}, + {"just-symbols", 'R', ANY_DASH, REQ_ARG}, + {"library", 'l', ANY_DASH, REQ_ARG}, + {"library-path", 'L', ANY_DASH, REQ_ARG}, + {"mri-script", 'c', ANY_DASH, REQ_ARG}, + {"nmagic", 'n', ANY_DASH, NO_ARG}, + {"nostdlib", KEY_NO_STDLIB, ONE_DASH, NO_ARG}, + {"no-accept-unknown-input-arch", KEY_NO_UNKNOWN, ANY_DASH, NO_ARG}, + {"no-allow-shlib-undefined", KEY_NO_SHLIB_UNDEF, ANY_DASH, NO_ARG}, + {"no-as-needed", KEY_NO_AS_NEEDED, ANY_DASH, NO_ARG}, + {"no-check-sections", KEY_NO_CHECK_SECTIONS, ANY_DASH, NO_ARG}, + {"no-define-common", KEY_NO_DEFINE_COMMON, ANY_DASH, NO_ARG}, + {"no-demangle", KEY_NO_DEMANGLE, ANY_DASH, OPT_ARG}, + {"no-gc-sections", KEY_NO_GC_SECTIONS, ANY_DASH, NO_ARG}, + {"no-keep-memory", KEY_NO_KEEP_MEMORY, ANY_DASH, NO_ARG}, + {"no-omagic", KEY_NO_OMAGIC, ANY_DASH, NO_ARG}, + {"no-print-gc-sections", KEY_NO_PRINT_GC_SECTIONS, ANY_DASH, NO_ARG}, + {"no-undefined", KEY_Z_DEFS, ANY_DASH, NO_ARG}, + {"no-undefined-version", KEY_NO_UNDEF_VERSION, ANY_DASH, NO_ARG}, + {"no-whole-archive", KEY_NO_WHOLE_ARCHIVE, ANY_DASH, NO_ARG}, + {"no-warn-mismatch", KEY_NO_WARN_MISMATCH, ANY_DASH, NO_ARG}, + {"non_shared", KEY_STATIC, ONE_DASH, NO_ARG}, + {"oformat", KEY_OFORMAT, TWO_DASH, REQ_ARG}, + {"omagic", 'N', TWO_DASH, NO_ARG}, + {"output", 'o', TWO_DASH, REQ_ARG}, + {"pic-executable", KEY_PIE, ANY_DASH, NO_ARG}, + {"pie", KEY_PIE, ONE_DASH, NO_ARG}, + {"print-gc-sections", KEY_PRINT_GC_SECTIONS, ANY_DASH, NO_ARG}, + {"print-map", 'M', ANY_DASH, NO_ARG}, + {"qmagic", KEY_QMAGIC, ANY_DASH, NO_ARG}, + {"relax", KEY_RELAX, ANY_DASH, NO_ARG}, + {"relocatable", 'r', ANY_DASH, NO_ARG}, + {"retain-symbols-file", KEY_RETAIN_SYM_FILE, ANY_DASH, REQ_ARG}, + {"rpath", KEY_RPATH, ANY_DASH, REQ_ARG}, + {"rpath-link", KEY_RPATH_LINK, ANY_DASH, REQ_ARG}, + {"runpath", KEY_RUNPATH, ANY_DASH, REQ_ARG}, + {"script", 'T', ANY_DASH, REQ_ARG}, + {"section-start", KEY_SECTION_START, ANY_DASH, REQ_ARG}, + {"shared", KEY_SHARED, ONE_DASH, NO_ARG}, + {"soname", 'h', ONE_DASH, REQ_ARG}, + {"sort-common", KEY_SORT_COMMON, ANY_DASH, NO_ARG}, + {"split-by-file", KEY_SPLIT_BY_FILE, ANY_DASH, REQ_ARG}, + {"split-by-reloc", KEY_SPLIT_BY_RELOC, ANY_DASH, REQ_ARG}, + {"start-group", '(', ANY_DASH, NO_ARG}, + {"stats", KEY_STATS, ANY_DASH, NO_ARG}, + {"static", KEY_STATIC, ONE_DASH, NO_ARG}, + {"strip-all", 's', ANY_DASH, NO_ARG}, + {"strip-debug", 'S', ANY_DASH, NO_ARG}, + {"trace", 't', ANY_DASH, NO_ARG}, + {"trace_symbol", 'y', ANY_DASH, NO_ARG}, + {"traditional-format", KEY_TRADITIONAL_FORMAT, ANY_DASH, NO_ARG}, + {"undefined", 'u', ANY_DASH, REQ_ARG}, + {"unique", KEY_UNIQUE, ANY_DASH, OPT_ARG}, + {"unresolved-symbols", KEY_UNRESOLVED_SYMBOLS, ANY_DASH, REQ_ARG}, + {"verbose" , KEY_VERBOSE, ANY_DASH, NO_ARG}, + {"version", 'V', ANY_DASH, NO_ARG}, + {"version-script", KEY_VERSION_SCRIPT, ANY_DASH, REQ_ARG}, + {"warn-common", KEY_WARN_COMMON, ANY_DASH, NO_ARG}, + {"warn-constructors", KEY_WARN_CONSTRUCTORS, ANY_DASH, NO_ARG}, + {"warn-multiple-gp", KEY_WARN_MULTIPLE_GP, ANY_DASH, NO_ARG}, + {"warn-once", KEY_WARN_ONCE, ANY_DASH, NO_ARG}, + {"warn-section-align", KEY_WARN_SECTION_ALIGN, ANY_DASH, NO_ARG}, + {"warn-shared-textrel", KEY_WARN_SHARED_TEXTREL, ANY_DASH, NO_ARG}, + {"warn-unresolved-symbols", KEY_WARN_UNRESOLVE_SYM, ANY_DASH, NO_ARG}, + {"whole-archive", KEY_WHOLE_ARCHIVE, ANY_DASH, NO_ARG}, + {"wrap", KEY_WRAP, ANY_DASH, REQ_ARG}, + {"EB", KEY_EB, ONE_DASH, NO_ARG}, + {"EL", KEY_EL, ONE_DASH, NO_ARG}, + {"Map", KEY_MAP, ONE_DASH, REQ_ARG}, + {"Qy", KEY_QY, ONE_DASH, NO_ARG}, + {"Tbss", KEY_TBSS, ONE_DASH, REQ_ARG}, + {"Tdata", KEY_TDATA, ONE_DASH, REQ_ARG}, + {"Ttext", KEY_TTEXT, ONE_DASH, REQ_ARG}, + {"Ur", KEY_UR, ONE_DASH, NO_ARG}, + {NULL, 0, 0, 0}, +}; + +static struct ld_option ld_opts_B[] = { + {"shareable", KEY_SHARED, ONE_DASH, NO_ARG}, + {"static", KEY_STATIC, ONE_DASH, NO_ARG}, + {"dynamic", KEY_DYNAMIC, ONE_DASH, NO_ARG}, + {"group", KEY_GROUP, ONE_DASH, NO_ARG}, + {"symbolic", KEY_SYMBOLIC, ONE_DASH, NO_ARG}, + {"symbolic_functions", KEY_SYMBOLIC_FUNC, ONE_DASH, NO_ARG}, +}; + +static struct ld_option ld_opts_z[] = { + {"nodefaultlib", KEY_Z_NO_DEFAULT_LIB, ONE_DASH, NO_ARG}, + {"allextract", KEY_WHOLE_ARCHIVE, ONE_DASH, NO_ARG}, + {"defaultextract", KEY_Z_DEFAULT_EXTRACT, ONE_DASH, NO_ARG}, + {"weakextract", KEY_Z_WEAK_EXTRACT, ONE_DASH, NO_ARG}, + {"muldefs", KEY_Z_MULDEFS, ONE_DASH, NO_ARG}, + {"defs", KEY_Z_DEFS, ONE_DASH, NO_ARG}, + {"execstack", KEY_Z_EXEC_STACK, ONE_DASH, NO_ARG}, + {"nodefs", KEY_Z_NO_DEFS, ONE_DASH, NO_ARG}, + {"origin", KEY_Z_ORIGIN, ONE_DASH, NO_ARG}, + {"now", KEY_Z_NOW, ONE_DASH, NO_ARG}, + {"nodelete", KEY_Z_NO_DELETE, ONE_DASH, NO_ARG}, + {"initfirst", KEY_Z_INIT_FIRST, ONE_DASH, NO_ARG}, + {"lazyload", KEY_Z_LAZYLOAD, ONE_DASH, NO_ARG}, + {"noexecstack", KEY_Z_NO_EXEC_STACK, ONE_DASH, NO_ARG}, + {"nodlopen", KEY_Z_NO_DLOPEN, ONE_DASH, NO_ARG}, + {"nolazyload", KEY_Z_NO_LAZYLOAD, ONE_DASH, NO_ARG}, + {"ignore", KEY_Z_IGNORE, ONE_DASH, NO_ARG}, + {"record", KEY_Z_RECORD, ONE_DASH, NO_ARG}, + {"systemlibrary", KEY_Z_SYSTEM_LIBRARY, ONE_DASH, NO_ARG}, +}; + +static void _copy_optarg(struct ld *ld, char **dst, char *src); +static void _process_options(struct ld *ld, int key, char *arg); +static int _parse_long_options(struct ld *, struct ld_option *, int, + int, char **, char *, enum ld_dash); +static void _print_version(struct ld *ld); + +void +ld_options_parse(struct ld* ld, int argc, char **argv) +{ + enum ld_dash d; + char *p, *p0, *oli; + int ac, ac0; + + ac = 1; + + while (ac < argc) { + p = argv[ac]; + if (*p != '-' || p[1] == '\0') { + _process_options(ld, KEY_FILE, p); + ac++; + continue; + } + + if (*++p == '-') { + if (p[1] == '\0') { + /* Option --. Ignore the rest of options. */ + return; + } + p++; + d = TWO_DASH; + } else { + d = ONE_DASH; + if (*p == 'B' || *p == 'z') { + ac0 = ac; + if (*(p0 = p + 1) == '\0') + p0 = argv[++ac0]; + ac = _parse_long_options(ld, + *p == 'B' ? ld_opts_B : ld_opts_z, + ac0, argc, argv, p0, d); + if (ac > 0) + continue; + ld_fatal(ld, "unrecognized options -%c: %s", + *p, p0); + } + } + + ac0 = _parse_long_options(ld, ld_opts, ac, argc, argv, p, d); + if (ac0 > 0) { + ac = ac0; + continue; + } + + if (d == TWO_DASH) + ld_fatal(ld, "unrecognized option %s", p); + + /* + * Search short options. + */ + while (*p != '\0') { + if ((oli = strchr(ld_short_opts, *p)) == NULL) + ld_fatal(ld, "unrecognized option -%c", *p); + if (*++oli != ':') { + _process_options(ld, *p++, NULL); + continue; + } + if (p[1] != '\0') + _process_options(ld, *p, &p[1]); + else if (oli[1] != ':') { + if (++ac >= argc) + ld_fatal(ld, "require arg for" + " option -%c", *p); + _process_options(ld, *p, argv[ac]); + } + break; + } + + ac++; + } +} + +static int +_parse_long_options(struct ld *ld, struct ld_option *opts, int ac, + int argc, char **argv, char *opt, enum ld_dash dash) +{ + char *equal; + size_t av_len; + int i, match; + + if ((equal = strchr(opt, '=')) != NULL) { + av_len = equal - opt; + equal++; + if (*equal == '\0') + ld_fatal(ld, "no argument after ="); + } else + av_len = strlen(opt); + + match = 0; + for (i = 0; opts[i].lo_long != NULL; i++) { + if (opts[i].lo_dash != ANY_DASH && opts[i].lo_dash != dash) + continue; + if (strlen(opts[i].lo_long) == av_len && + !strncmp(opt, opts[i].lo_long, av_len)) { + match = 1; + break; + } + } + if (!match) + return (-1); + + switch (opts[i].lo_arg) { + case NO_ARG: + if (equal != NULL) { + ld_fatal(ld, "option %s does not accept argument", + opts[i].lo_long); + } + _process_options(ld, opts[i].lo_key, NULL); + break; + case REQ_ARG: + if (equal != NULL) + _process_options(ld, opts[i].lo_key, equal); + else { + if (++ac >= argc) + ld_fatal(ld, "require arg for option %s", + opts[i].lo_long); + _process_options(ld, opts[i].lo_key, argv[ac]); + } + break; + case OPT_ARG: + _process_options(ld, opts[i].lo_key, equal); + break; + default: + assert(0); + break; + } + + return (++ac); +} + +static void +_process_options(struct ld *ld, int key, char *arg) +{ + struct ld_state *ls; + + assert(ld != NULL); + ls = &ld->ld_state; + + switch (key) { + case 'b': + ls->ls_itgt = elftc_bfd_find_target(arg); + if (ls->ls_itgt == NULL) + ld_fatal(ld, "invalid BFD target `%s'", arg); + break; + case 'd': + ld->ld_common_alloc = 1; + break; + case 'e': + _copy_optarg(ld, &ld->ld_entry, arg); + break; + case 'h': + _copy_optarg(ld, &ld->ld_soname, arg); + break; + case 'I': + _copy_optarg(ld, &ld->ld_interp, arg); + break; + case 'l': + ld_path_search_library(ld, arg); + break; + case 'L': + ld_path_add(ld, arg, LPT_L); + break; + case 'M': + ld->ld_print_linkmap = 1; + break; + case 'o': + _copy_optarg(ld, &ld->ld_output_file, arg); + break; + case 'q': + ld->ld_emit_reloc = 1; + break; + case 'r': + ld->ld_reloc = 1; + break; + case 'T': + ld_script_parse(arg); + break; + case 'u': + ld_symbols_add_extern(ld, arg); + break; + case 'v': + case 'V': + _print_version(ld); + break; + case '(': + ls->ls_group_level++; + if (ls->ls_group_level > LD_MAX_NESTED_GROUP) + ld_fatal(ld, "too many nested archive groups"); + break; + case ')': + ls->ls_group_level--; + break; + case KEY_AS_NEEDED: + ls->ls_as_needed = 1; + break; + case KEY_DYNAMIC: + ls->ls_static = 0; + break; + case KEY_EH_FRAME_HDR: + ld->ld_ehframe_hdr = 1; + break; + case KEY_GC_SECTIONS: + ld->ld_gc = 1; + break; + case KEY_NO_AS_NEEDED: + ls->ls_as_needed = 0; + break; + case KEY_NO_DEFINE_COMMON: + ld->ld_common_no_alloc = 1; + break; + case KEY_NO_GC_SECTIONS: + ld->ld_gc = 0; + break; + case KEY_NO_PRINT_GC_SECTIONS: + ld->ld_gc_print = 0; + break; + case KEY_NO_WHOLE_ARCHIVE: + ls->ls_whole_archive = 0; + break; + case KEY_OFORMAT: + ld_output_format(ld, arg, arg, arg); + break; + case KEY_PIE: + ld->ld_exec = 0; + ld->ld_pie = 1; + ld->ld_dynamic_link = 1; + break; + case KEY_PRINT_GC_SECTIONS: + ld->ld_gc_print = 1; + break; + case KEY_RPATH: + ld_path_add_multiple(ld, arg, LPT_RPATH); + break; + case KEY_RPATH_LINK: + ld_path_add_multiple(ld, arg, LPT_RPATH_LINK); + break; + case KEY_SHARED: + ld->ld_exec = 0; + ld->ld_dso = 1; + ld->ld_dynamic_link = 1; + break; + case KEY_STATIC: + ls->ls_static = 1; + break; + case KEY_WHOLE_ARCHIVE: + ls->ls_whole_archive = 1; + break; + case KEY_FILE: + ld_file_add(ld, arg, LFT_UNKNOWN); + break; + case KEY_VERSION_SCRIPT: + ld_script_parse(arg); + break; + case KEY_Z_EXEC_STACK: + ld->ld_gen_gnustack = 1; + ld->ld_stack_exec_set = 1; + ld->ld_stack_exec = 1; + break; + case KEY_Z_NO_EXEC_STACK: + ld->ld_gen_gnustack = 1; + ld->ld_stack_exec_set = 1; + ld->ld_stack_exec = 0; + break; + default: + break; + } +} + +static void +_print_version(struct ld *ld) +{ + + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + ld->ld_print_version = 1; +} + +static void +_copy_optarg(struct ld *ld, char **dst, char *src) +{ + + if (*dst != NULL) + free(*dst); + if ((*dst = strdup(src)) == NULL) + ld_fatal_std(ld, "strdup"); +} + +struct ld_wildcard * +ld_wildcard_alloc(struct ld *ld) +{ + struct ld_wildcard *lw; + + if ((lw = calloc(1, sizeof(*lw))) == NULL) + ld_fatal_std(ld, "calloc"); + + return (lw); +} + +void +ld_wildcard_free(void *ptr) +{ + struct ld_wildcard *lw; + + lw = ptr; + if (lw == NULL) + return; + + free(lw->lw_name); + free(lw); +} diff --git a/contrib/elftoolchain/ld/ld_options.h b/contrib/elftoolchain/ld/ld_options.h new file mode 100644 index 0000000000..ef43b0ca6f --- /dev/null +++ b/contrib/elftoolchain/ld/ld_options.h @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_options.h 3405 2016-02-14 10:56:34Z jkoshy $ + */ + +enum ld_dash { + ONE_DASH, + TWO_DASH, + ANY_DASH +}; + +enum ld_arg { + NO_ARG, + REQ_ARG, + OPT_ARG +}; + +enum ld_key { + KEY_ACCEPT_UNKNOWN = 0x10000, + KEY_ALLOW_SHLIB_UNDEF, + KEY_ASSERT, + KEY_AS_NEEDED, + KEY_BUILD_ID, + KEY_CHECK_SECTIONS, + KEY_CREF, + KEY_DEFSYM, + KEY_DEMANGLE, + KEY_DISABLE_NEW_DTAGS, + KEY_DYNAMIC, + KEY_EB, + KEY_EL, + KEY_EH_FRAME_HDR, + KEY_ENABLE_NEW_DTAGS, + KEY_ERR_UNRESOLVE_SYM, + KEY_FATAL_WARNINGS, + KEY_FINI, + KEY_GC_SECTIONS, + KEY_GROUP, + KEY_HASH_STYLE, + KEY_HELP, + KEY_INIT, + KEY_MAP, + KEY_NO_AS_NEEDED, + KEY_NO_CHECK_SECTIONS, + KEY_NO_DEFINE_COMMON, + KEY_NO_DEMANGLE, + KEY_NO_GC_SECTIONS, + KEY_NO_KEEP_MEMORY, + KEY_NO_OMAGIC, + KEY_NO_PRINT_GC_SECTIONS, + KEY_NO_SHLIB_UNDEF, + KEY_NO_STDLIB, + KEY_NO_UNDEF_VERSION, + KEY_NO_UNKNOWN, + KEY_NO_WHOLE_ARCHIVE, + KEY_NO_WARN_MISMATCH, + KEY_RPATH, + KEY_RPATH_LINK, + KEY_RUNPATH, + KEY_SECTION_START, + KEY_OFORMAT, + KEY_PIE, + KEY_PRINT_GC_SECTIONS, + KEY_QMAGIC, + KEY_QY, + KEY_RELAX, + KEY_RETAIN_SYM_FILE, + KEY_SHARED, + KEY_SORT_COMMON, + KEY_SPLIT_BY_FILE, + KEY_SPLIT_BY_RELOC, + KEY_STATIC, + KEY_STATS, + KEY_SYMBOLIC, + KEY_SYMBOLIC_FUNC, + KEY_TBSS, + KEY_TDATA, + KEY_TTEXT, + KEY_TRADITIONAL_FORMAT, + KEY_UNRESOLVED_SYMBOLS, + KEY_UNIQUE, + KEY_UR, + KEY_VERBOSE, + KEY_VERSION_SCRIPT, + KEY_WARN_COMMON, + KEY_WARN_CONSTRUCTORS, + KEY_WARN_MULTIPLE_GP, + KEY_WARN_ONCE, + KEY_WARN_SECTION_ALIGN, + KEY_WARN_SHARED_TEXTREL, + KEY_WARN_UNRESOLVE_SYM, + KEY_WHOLE_ARCHIVE, + KEY_WRAP, + KEY_Z_DEFAULT_EXTRACT, + KEY_Z_DEFS, + KEY_Z_EXEC_STACK, + KEY_Z_IGNORE, + KEY_Z_INIT_FIRST, + KEY_Z_LAZYLOAD, + KEY_Z_MULDEFS, + KEY_Z_NOW, + KEY_Z_NO_DEFAULT_LIB, + KEY_Z_NO_DEFS, + KEY_Z_NO_DELETE, + KEY_Z_NO_DLOPEN, + KEY_Z_NO_EXEC_STACK, + KEY_Z_NO_LAZYLOAD, + KEY_Z_ORIGIN, + KEY_Z_RECORD, + KEY_Z_SYSTEM_LIBRARY, + KEY_Z_WEAK_EXTRACT, + + KEY_FILE = 0x10000000, +}; + +struct ld_option { + const char *lo_long; + int lo_key; + enum ld_dash lo_dash; + enum ld_arg lo_arg; +}; + +enum ld_wildcard_sort { + LWS_NONE, + LWS_NAME, + LWS_ALIGN, + LWS_NAME_ALIGN, + LWS_ALIGN_NAME, +}; + +struct ld_wildcard { + char *lw_name; /* wildcard */ + enum ld_wildcard_sort lw_sort; /* sort mode */ +}; + +void ld_options_parse(struct ld*, int, char **); +struct ld_wildcard *ld_wildcard_alloc(struct ld *); +void ld_wildcard_free(void *); diff --git a/contrib/elftoolchain/ld/ld_output.c b/contrib/elftoolchain/ld/ld_output.c new file mode 100644 index 0000000000..fc4a7762af --- /dev/null +++ b/contrib/elftoolchain/ld/ld_output.c @@ -0,0 +1,1155 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_ehframe.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_layout.h" +#include "ld_reloc.h" +#include "ld_script.h" +#include "ld_strtab.h" +#include "ld_symbols.h" + +ELFTC_VCSID("$Id: ld_output.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); + +static void _alloc_input_section_data(struct ld *ld, Elf_Scn *scn, + struct ld_input_section *is); +static void _alloc_section_data_from_buffer(struct ld *ld, Elf_Scn *scn, + struct ld_output_data_buffer *odb); +static void _alloc_section_data_for_symtab(struct ld *ld, + struct ld_output_section *os, Elf_Scn *scn, + struct ld_symbol_table *symtab); +static void _alloc_section_data_for_strtab(struct ld *ld, Elf_Scn *scn, + struct ld_strtab *strtab); +static void _add_to_shstrtab(struct ld *ld, const char *name); +static void _copy_and_reloc_input_sections(struct ld *ld); +static Elf_Scn *_create_elf_scn(struct ld *ld, struct ld_output *lo, + struct ld_output_section *os); +static void _create_elf_section(struct ld *ld, struct ld_output_section *os); +static void _create_phdr(struct ld *ld); +static void _create_symbol_table(struct ld *ld); +static uint64_t _find_entry_point(struct ld *ld); +static void _produce_reloc_sections(struct ld *ld, struct ld_output *lo); +static void _join_and_finalize_dynamic_reloc_sections(struct ld *ld, + struct ld_output *lo); +static void _join_normal_reloc_sections(struct ld *ld, struct ld_output *lo); +static void _update_section_header(struct ld *ld); + +void +ld_output_early_init(struct ld *ld) +{ + struct ld_output *lo; + + if (ld->ld_output == NULL) { + if ((lo = calloc(1, sizeof(*lo))) == NULL) + ld_fatal_std(ld, "calloc"); + + STAILQ_INIT(&lo->lo_oelist); + STAILQ_INIT(&lo->lo_oslist); + ld->ld_output = lo; + } else + lo = ld->ld_output; + + assert(ld->ld_otgt != NULL); + lo->lo_ec = elftc_bfd_target_class(ld->ld_otgt); + lo->lo_endian = elftc_bfd_target_byteorder(ld->ld_otgt); +} + +void +ld_output_init(struct ld *ld) +{ + struct ld_output *lo; + const char *fn; + GElf_Ehdr eh; + + lo = ld->ld_output; + assert(lo != NULL); + + if (ld->ld_output_file == NULL) + fn = "a.out"; + else + fn = ld->ld_output_file; + + lo->lo_fd = open(fn, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); + if (lo->lo_fd < 0) + ld_fatal_std(ld, "can not create output file: open %s", fn); + + if ((lo->lo_elf = elf_begin(lo->lo_fd, ELF_C_WRITE, NULL)) == NULL) + ld_fatal(ld, "elf_begin failed: %s", elf_errmsg(-1)); + + elf_flagelf(lo->lo_elf, ELF_C_SET, ELF_F_LAYOUT); + + if (gelf_newehdr(lo->lo_elf, lo->lo_ec) == NULL) + ld_fatal(ld, "gelf_newehdr failed: %s", elf_errmsg(-1)); + + if (gelf_getehdr(lo->lo_elf, &eh) == NULL) + ld_fatal(ld, "gelf_getehdr failed: %s", elf_errmsg(-1)); + + eh.e_ident[EI_CLASS] = lo->lo_ec; + eh.e_ident[EI_DATA] = lo->lo_endian; + eh.e_flags = ld->ld_arch->flags; + eh.e_machine = elftc_bfd_target_machine(ld->ld_otgt); + if (ld->ld_dso || ld->ld_pie) + eh.e_type = ET_DYN; + else if (ld->ld_reloc) + eh.e_type = ET_REL; + else + eh.e_type = ET_EXEC; + eh.e_version = EV_CURRENT; + + /* Save updated ELF header. */ + if (gelf_update_ehdr(lo->lo_elf, &eh) == 0) + ld_fatal(ld, "gelf_update_ehdr failed: %s", elf_errmsg(-1)); +} + +void +ld_output_format(struct ld *ld, char *def, char *be, char *le) +{ + + ld->ld_otgt_name = def; + if ((ld->ld_otgt = elftc_bfd_find_target(def)) == NULL) + ld_fatal(ld, "invalid BFD format %s", def); + + ld->ld_otgt_be_name = be; + if ((ld->ld_otgt_be = elftc_bfd_find_target(be)) == NULL) + ld_fatal(ld, "invalid BFD format %s", be); + + ld->ld_otgt_le_name = le; + if ((ld->ld_otgt_le = elftc_bfd_find_target(le)) == NULL) + ld_fatal(ld, "invalid BFD format %s", le); + + ld_arch_set_from_target(ld); +} + +struct ld_output_element * +ld_output_create_element(struct ld *ld, struct ld_output_element_head *head, + enum ld_output_element_type type, void *entry, + struct ld_output_element *after) +{ + struct ld_output_element *oe; + + if ((oe = calloc(1, sizeof(*oe))) == NULL) + ld_fatal_std(ld, "calloc"); + + oe->oe_type = type; + oe->oe_entry = entry; + + if (after == NULL) + STAILQ_INSERT_TAIL(head, oe, oe_next); + else + STAILQ_INSERT_AFTER(head, after, oe, oe_next); + + return (oe); +} + +struct ld_output_element * +ld_output_create_section_element(struct ld *ld, struct ld_output_section *os, + enum ld_output_element_type type, void *entry, + struct ld_output_element *after) +{ + struct ld_output_element *oe; + + oe = ld_output_create_element(ld, &os->os_e, type, entry, after); + + switch (type) { + case OET_DATA: + case OET_DATA_BUFFER: + case OET_SYMTAB: + case OET_STRTAB: + os->os_empty = 0; + break; + default: + break; + } + + return (oe); +} + +struct ld_output_section * +ld_output_alloc_section(struct ld *ld, const char *name, + struct ld_output_section *after, struct ld_output_section *ros) +{ + struct ld_output *lo; + struct ld_output_section *os; + + lo = ld->ld_output; + + if ((os = calloc(1, sizeof(*os))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((os->os_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + os->os_align = 1; + os->os_empty = 1; + + STAILQ_INIT(&os->os_e); + + HASH_ADD_KEYPTR(hh, lo->lo_ostbl, os->os_name, strlen(os->os_name), os); + + if (after == NULL) { + STAILQ_INSERT_TAIL(&lo->lo_oslist, os, os_next); + os->os_pe = ld_output_create_element(ld, &lo->lo_oelist, + OET_OUTPUT_SECTION, os, NULL); + } else { + STAILQ_INSERT_AFTER(&lo->lo_oslist, after, os, os_next); + os->os_pe = ld_output_create_element(ld, &lo->lo_oelist, + OET_OUTPUT_SECTION, os, after->os_pe); + } + + if (ros != NULL) + ros->os_r = os; + + return (os); +} + +static Elf_Scn * +_create_elf_scn(struct ld *ld, struct ld_output *lo, + struct ld_output_section *os) +{ + Elf_Scn *scn; + + assert(lo->lo_elf != NULL); + + if ((scn = elf_newscn(lo->lo_elf)) == NULL) + ld_fatal(ld, "elf_newscn failed: %s", elf_errmsg(-1)); + + if (os != NULL) + os->os_scn = scn; + + return (scn); +} + +static void +_create_elf_section(struct ld *ld, struct ld_output_section *os) +{ + struct ld_output *lo; + struct ld_output_element *oe; + struct ld_input_section *is; + struct ld_input_section_head *islist; + Elf_Data *d; + Elf_Scn *scn; + + lo = ld->ld_output; + assert(lo->lo_elf != NULL); + + /* Create section data. */ + scn = NULL; + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + switch (oe->oe_type) { + case OET_DATA: + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + /* TODO */ + break; + case OET_DATA_BUFFER: + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + _alloc_section_data_from_buffer(ld, scn, oe->oe_entry); + break; + case OET_INPUT_SECTION_LIST: + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) { + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + if (os->os_type != SHT_NOBITS && + !os->os_dynrel) + _alloc_input_section_data(ld, scn, is); + } + if ((ld->ld_reloc || ld->ld_emit_reloc) && + os->os_r != NULL) { + /* Create Scn for relocation section. */ + if (os->os_r->os_scn == NULL) { + os->os_r->os_scn = _create_elf_scn(ld, + lo, os->os_r); + _add_to_shstrtab(ld, + os->os_r->os_name); + } + } + break; + case OET_KEYWORD: + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + /* TODO */ + break; + case OET_SYMTAB: + /* TODO: Check symtab size. */ + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + break; + case OET_STRTAB: + /* TODO: Check strtab size. */ + if (scn == NULL) + scn = _create_elf_scn(ld, lo, os); + _alloc_section_data_for_strtab(ld, scn, oe->oe_entry); + break; + default: + break; + } + } + + if (scn == NULL) + return; + + if (os->os_type == SHT_NOBITS) { + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = os->os_align; + d->d_off = 0; + d->d_type = ELF_T_BYTE; + d->d_size = os->os_size; + d->d_version = EV_CURRENT; + d->d_buf = NULL; + } + + _add_to_shstrtab(ld, os->os_name); +} + +static void +_alloc_input_section_data(struct ld *ld, Elf_Scn *scn, + struct ld_input_section *is) +{ + Elf_Data *d; + + if (is->is_type == SHT_NOBITS || is->is_size == 0) + return; + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + is->is_data = d; +} + +static void +_alloc_section_data_from_buffer(struct ld *ld, Elf_Scn *scn, + struct ld_output_data_buffer *odb) +{ + Elf_Data *d; + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = odb->odb_align; + d->d_off = odb->odb_off; + d->d_type = odb->odb_type; + d->d_size = odb->odb_size; + d->d_version = EV_CURRENT; + d->d_buf = odb->odb_buf; +} + +static void +_alloc_section_data_from_reloc_buffer(struct ld *ld, Elf_Scn *scn, + void *buf, size_t sz) +{ + Elf_Data *d; + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = ld->ld_arch->reloc_is_64bit ? 8 : 4; + d->d_off = 0; /* has to be the only data descriptor */ + d->d_type = ld->ld_arch->reloc_is_rela ? ELF_T_RELA : ELF_T_REL; + d->d_size = sz; + d->d_version = EV_CURRENT; + d->d_buf = buf; +} + +static void +_alloc_section_data_for_symtab(struct ld *ld, struct ld_output_section *os, + Elf_Scn *scn, struct ld_symbol_table *symtab) +{ + Elf_Data *d; + + if (symtab->sy_buf == NULL || symtab->sy_size == 0) + return; + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = os->os_align; + d->d_off = 0; + d->d_type = ELF_T_SYM; + d->d_size = os->os_entsize * symtab->sy_size; + d->d_version = EV_CURRENT; + d->d_buf = symtab->sy_buf; +} + +static void +_alloc_section_data_for_strtab(struct ld *ld, Elf_Scn *scn, + struct ld_strtab *strtab) +{ + Elf_Data *d; + void *buf; + size_t sz; + + buf = ld_strtab_getbuf(ld, strtab); + sz = ld_strtab_getsize(strtab); + if (buf == NULL || sz == 0) + return; + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = 1; + d->d_off = 0; + d->d_type = ELF_T_BYTE; + d->d_size = sz; + d->d_version = EV_CURRENT; + d->d_buf = buf; +} + +static void +_copy_and_reloc_input_sections(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + Elf_Data *d; + int i; + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + ld_input_load(ld, li); + for (i = 0; (uint64_t) i < li->li_shnum; i++) { + is = &li->li_is[i]; + + if (is->is_discard || !is->is_need_reloc) + continue; + + d = is->is_data; + + d->d_align = is->is_align; + d->d_off = is->is_reloff; + d->d_type = ELF_T_BYTE; + d->d_size = is->is_size; + d->d_version = EV_CURRENT; + + /* + * Take different actions depending on different types + * of input sections: + * + * For internal input sections, assign the internal + * buffer directly to the data descriptor. + * For relocation sections, they should be ignored + * since they are handled elsewhere. + * For other input sections, load the raw data from + * input object and preform relocation. + */ + if (is->is_ibuf != NULL) { + d->d_buf = is->is_ibuf; + /* .eh_frame section needs relocation */ + if (strcmp(is->is_name, ".eh_frame") == 0) + ld_reloc_process_input_section(ld, is, + d->d_buf); + } else if (is->is_reloc == NULL) { + d->d_buf = ld_input_get_section_rawdata(ld, + is); + ld_reloc_process_input_section(ld, is, + d->d_buf); + } + } + ld_input_unload(ld, li); + } +} + +static void +_produce_reloc_sections(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os; + void *buf; + size_t sz; + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_reloc != NULL) { + /* Serialize relocation records. */ + buf = ld_reloc_serialize(ld, os, &sz); + _alloc_section_data_from_reloc_buffer(ld, os->os_scn, + buf, sz); + + /* + * Link dynamic relocation sections to .dynsym + * section. + */ + if (os->os_dynrel) { + if ((os->os_link = strdup(".dynsym")) == NULL) + ld_fatal_std(ld, "strdup"); + } + } + } +} + +static void +_join_and_finalize_dynamic_reloc_sections(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os; + struct ld_output_element *oe; + struct ld_input_section *is; + struct ld_input_section_head *islist; + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + + if (!os->os_dynrel) + continue; + + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + switch (oe->oe_type) { + case OET_INPUT_SECTION_LIST: + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) + ld_reloc_join(ld, os, is); + break; + default: + break; + } + } + + /* Sort dynamic relocations for the runtime linker. */ + if (os->os_reloc != NULL && os->os_dynrel && !os->os_pltrel) + ld_reloc_sort(ld, os); + + /* Finalize relocations. */ + ld_reloc_finalize_dynamic(ld, lo, os); + } +} + +static void +_join_normal_reloc_sections(struct ld *ld, struct ld_output *lo) +{ + struct ld_output_section *os; + struct ld_output_element *oe; + struct ld_input_section *is; + struct ld_input_section_head *islist; + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + + if (os->os_r == NULL) + continue; + + STAILQ_FOREACH(oe, &os->os_e, oe_next) { + switch (oe->oe_type) { + case OET_INPUT_SECTION_LIST: + islist = oe->oe_islist; + STAILQ_FOREACH(is, islist, is_next) { + if (is->is_ris == NULL) + continue; + ld_reloc_join(ld, os->os_r, + is->is_ris); + } + break; + default: + break; + } + } + } +} + +void +ld_output_create_elf_sections(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_element *oe; + + lo = ld->ld_output; + assert(lo->lo_elf != NULL); + + STAILQ_FOREACH(oe, &lo->lo_oelist, oe_next) { + switch (oe->oe_type) { + case OET_OUTPUT_SECTION: + _create_elf_section(ld, oe->oe_entry); + break; + default: + break; + } + } +} + +void +ld_output_emit_gnu_stack_section(struct ld *ld) +{ + struct ld_state *ls; + struct ld_output *lo; + struct ld_output_section *os; + + ls = &ld->ld_state; + lo = ld->ld_output; + + os = ld_output_alloc_section(ld, ".note.GNU-stack", NULL, NULL); + os->os_empty = 0; + os->os_addr = 0; + os->os_type = SHT_PROGBITS; + os->os_align = 1; + os->os_entsize = 0; + os->os_off = ls->ls_offset; + os->os_size = 0; + if (ld->ld_stack_exec) + os->os_flags = SHF_EXECINSTR; + + (void) _create_elf_scn(ld, lo, os); + + _add_to_shstrtab(ld, ".note.GNU-stack"); + + /* + * .note.GNU-stack is an empty section so we don't allocate any + * Elf_Data descriptors. + */ +} + +static uint64_t +_find_entry_point(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os; + char entry_symbol[] = "start"; + uint64_t entry; + + lo = ld->ld_output; + + if (ld->ld_entry != NULL) { + if (ld_symbols_get_value(ld, ld->ld_entry, &entry) < 0) + ld_fatal(ld, "symbol %s is undefined", ld->ld_entry); + return (entry); + } + + if (ld->ld_scp->lds_entry_point != NULL) { + if (ld_symbols_get_value(ld, ld->ld_scp->lds_entry_point, + &entry) == 0) + return (entry); + } + + if (ld_symbols_get_value(ld, entry_symbol, &entry) == 0) + return (entry); + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_empty) + continue; + if (strcmp(os->os_name, ".text") == 0) + return (os->os_addr); + } + + return (0); +} + +static void +_create_phdr(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os; + Elf32_Phdr *p32; + Elf64_Phdr *p64; + void *phdrs; + uint64_t addr, off, align, flags, filesz, memsz, phdr_addr; + uint64_t tls_addr, tls_off, tls_align, tls_flags; + uint64_t tls_filesz, tls_memsz; + unsigned w; + int i, new, first, tls; + + /* TODO: support segments created by linker script command PHDR. */ + +#define _WRITE_PHDR(T,O,A,FSZ,MSZ,FL,AL) \ + do { \ + if (lo->lo_ec == ELFCLASS32) { \ + p32[i].p_type = (T); \ + p32[i].p_offset = (O); \ + p32[i].p_vaddr = (A); \ + p32[i].p_paddr = (A); \ + p32[i].p_filesz = (FSZ); \ + p32[i].p_memsz = (MSZ); \ + p32[i].p_flags = (FL); \ + p32[i].p_align = (AL); \ + } else { \ + p64[i].p_type = (T); \ + p64[i].p_offset = (O); \ + p64[i].p_vaddr = (A); \ + p64[i].p_paddr = (A); \ + p64[i].p_filesz = (FSZ); \ + p64[i].p_memsz = (MSZ); \ + p64[i].p_flags = (FL); \ + p64[i].p_align = (AL); \ + } \ + } while(0) + + lo = ld->ld_output; + assert(lo->lo_elf != NULL); + assert(lo->lo_phdr_num != 0); + assert(ld->ld_arch != NULL); + + if ((phdrs = gelf_newphdr(lo->lo_elf, lo->lo_phdr_num)) == NULL) + ld_fatal(ld, "gelf_newphdr failed: %s", elf_errmsg(-1)); + + p32 = NULL; + p64 = NULL; + if (lo->lo_ec == ELFCLASS32) + p32 = phdrs; + else + p64 = phdrs; + + i = -1; + + /* Calculate the start vma of output object. */ + os = STAILQ_FIRST(&lo->lo_oslist); + addr = os->os_addr - os->os_off; + + /* Create PT_PHDR segment for dynamically linked output object */ + if (lo->lo_dso_needed > 0 && !ld->ld_dso) { + i++; + off = gelf_fsize(lo->lo_elf, ELF_T_EHDR, 1, EV_CURRENT); + phdr_addr = addr + off; + filesz = memsz = gelf_fsize(lo->lo_elf, ELF_T_PHDR, + lo->lo_phdr_num, EV_CURRENT); + align = lo->lo_ec == ELFCLASS32 ? 4 : 8; + flags = PF_R | PF_X; + _WRITE_PHDR(PT_PHDR, off, phdr_addr, filesz, memsz, flags, + align); + } + + /* Create PT_INTERP segment for dynamically linked output object */ + if (lo->lo_interp != NULL) { + i++; + os = lo->lo_interp; + _WRITE_PHDR(PT_INTERP, os->os_off, os->os_addr, os->os_size, + os->os_size, PF_R, 1); + } + + /* + * Create PT_LOAD segments. + */ + + align = ld->ld_arch->get_max_page_size(ld); + new = 1; + w = 0; + off = filesz = memsz = 0; + flags = PF_R; + first = 1; + + tls = 0; + tls_off = tls_addr = tls_filesz = tls_memsz = tls_align = 0; + tls_flags = PF_R; /* TLS segment is a read-only image */ + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_empty) + continue; + + if ((os->os_flags & SHF_ALLOC) == 0) { + new = 1; + continue; + } + + if ((os->os_flags & SHF_TLS) != 0) { + if (tls < 0) + ld_warn(ld, "can not have multiple TLS " + "segments"); + else { + if (tls == 0) { + tls = 1; + tls_addr = os->os_addr; + tls_off = os->os_off; + } + + if (os->os_align > tls_align) + tls_align = os->os_align; + } + + } else if (tls > 0) + tls = -1; + + if ((os->os_flags & SHF_WRITE) != w || new) { + new = 0; + w = os->os_flags & SHF_WRITE; + + if (!first) + _WRITE_PHDR(PT_LOAD, off, addr, filesz, memsz, + flags, align); + + i++; + if ((unsigned) i >= lo->lo_phdr_num) + ld_fatal(ld, "not enough room for program" + " headers"); + if (!first) { + addr = os->os_addr; + off = os->os_off; + } + first = 0; + flags = PF_R; + filesz = 0; + memsz = 0; + } + + memsz = os->os_addr + os->os_size - addr; + if (tls > 0) + tls_memsz = memsz; + + if (os->os_type != SHT_NOBITS) { + filesz = memsz; + if (tls > 0) + tls_filesz = tls_memsz; + } + + if (os->os_flags & SHF_WRITE) + flags |= PF_W; + + if (os->os_flags & SHF_EXECINSTR) + flags |= PF_X; + } + if (i >= 0) + _WRITE_PHDR(PT_LOAD, off, addr, filesz, memsz, flags, align); + + /* + * Create PT_DYNAMIC segment. + */ + if (lo->lo_dynamic != NULL) { + i++; + os = lo->lo_dynamic; + _WRITE_PHDR(PT_DYNAMIC, os->os_off, os->os_addr, os->os_size, + os->os_size, PF_R | PF_W, lo->lo_ec == ELFCLASS32 ? 4 : 8); + } + + /* + * Create PT_NOTE segment. + */ + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_type == SHT_NOTE) { + i++; + if ((unsigned) i >= lo->lo_phdr_num) + ld_fatal(ld, "not enough room for program" + " headers"); + _WRITE_PHDR(PT_NOTE, os->os_off, os->os_addr, + os->os_size, os->os_size, PF_R, os->os_align); + break; + } + } + + /* + * Create PT_TLS segment. + */ + + if (tls != 0) { + i++; + lo->lo_tls_size = tls_memsz; + lo->lo_tls_align = tls_align; + lo->lo_tls_addr = tls_addr; + _WRITE_PHDR(PT_TLS, tls_off, tls_addr, tls_filesz, tls_memsz, + tls_flags, tls_align); + } + + /* + * Create PT_GNU_EH_FRAME segment. + */ + if (ld->ld_ehframe_hdr) { + i++; + os = lo->lo_ehframe_hdr; + assert(os != NULL); + _WRITE_PHDR(PT_GNU_EH_FRAME, os->os_off, os->os_addr, + os->os_size, os->os_size, PF_R, 4); + } + + /* + * Create PT_GNU_STACK segment. + */ + + if (ld->ld_gen_gnustack) { + i++; + flags = PF_R | PF_W; + if (ld->ld_stack_exec) + flags |= PF_X; + align = (lo->lo_ec == ELFCLASS32) ? 4 : 8; + _WRITE_PHDR(PT_GNU_STACK, 0, 0, 0, 0, flags, align); + } + + assert((unsigned) i + 1 == lo->lo_phdr_num); + +#undef _WRITE_PHDR +} + +void +ld_output_create(struct ld *ld) +{ + struct ld_output *lo; + GElf_Ehdr eh; + + lo = ld->ld_output; + + if (gelf_getehdr(lo->lo_elf, &eh) == NULL) + ld_fatal(ld, "gelf_getehdr failed: %s", elf_errmsg(-1)); + + /* Set program header table offset. */ + eh.e_phoff = gelf_fsize(lo->lo_elf, ELF_T_EHDR, 1, EV_CURRENT); + if (eh.e_phoff == 0) + ld_fatal(ld, "gelf_fsize failed: %s", elf_errmsg(-1)); + + /* Set section headers table offset. */ + eh.e_shoff = lo->lo_shoff; + + /* Set executable entry point. */ + eh.e_entry = _find_entry_point(ld); + + /* Save updated ELF header. */ + if (gelf_update_ehdr(lo->lo_elf, &eh) == 0) + ld_fatal(ld, "gelf_update_ehdr failed: %s", elf_errmsg(-1)); + + /* Allocate space for internal sections. */ + ld_input_alloc_internal_section_buffers(ld); + + /* Finalize PLT and GOT sections. */ + if (ld->ld_arch->finalize_got_and_plt) + ld->ld_arch->finalize_got_and_plt(ld); + + /* Join and sort dynamic relocation sections. */ + _join_and_finalize_dynamic_reloc_sections(ld, lo); + + /* Finalize sections for dynamically linked output object. */ + ld_dynamic_finalize(ld); + + /* Finalize dynamic symbol section. */ + if (lo->lo_dynsym != NULL) { + ld_symbols_finalize_dynsym(ld); + _alloc_section_data_for_symtab(ld, lo->lo_dynsym, + lo->lo_dynsym->os_scn, ld->ld_dynsym); + } + + /* Generate symbol table. */ + _create_symbol_table(ld); + + /* Copy and relocate input section data to output section. */ + _copy_and_reloc_input_sections(ld); + + /* Finalize .eh_frame_hdr section. */ + if (ld->ld_ehframe_hdr) + ld_ehframe_finalize_hdr(ld); + + /* + * Join normal relocation sections if the linker is creating a + * relocatable object or if option -emit-relocs is specified. + */ + if (ld->ld_reloc || ld->ld_emit_reloc) + _join_normal_reloc_sections(ld, lo); + + /* Produce relocation entries. */ + _produce_reloc_sections(ld, lo); + + /* Update section headers for the output sections. */ + _update_section_header(ld); + + /* Create program headers. */ + if (!ld->ld_reloc) + _create_phdr(ld); + + /* Finally write out the output ELF object. */ + if (elf_update(lo->lo_elf, ELF_C_WRITE) < 0) + ld_fatal(ld, "elf_update failed: %s", elf_errmsg(-1)); +} + +static void +_add_to_shstrtab(struct ld *ld, const char *name) +{ + + if (ld->ld_shstrtab == NULL) { + ld->ld_shstrtab = ld_strtab_alloc(ld, 1); + ld_strtab_insert(ld, ld->ld_shstrtab, ".symtab"); + ld_strtab_insert(ld, ld->ld_shstrtab, ".strtab"); + ld_strtab_insert(ld, ld->ld_shstrtab, ".shstrtab"); + } + + ld_strtab_insert(ld, ld->ld_shstrtab, name); +} + +static void +_update_section_header(struct ld *ld) +{ + struct ld_strtab *st; + struct ld_output *lo; + struct ld_output_section *os, *_os; + GElf_Shdr sh; + + lo = ld->ld_output; + st = ld->ld_shstrtab; + assert(st != NULL); + + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_scn == NULL) + continue; + + if (gelf_getshdr(os->os_scn, &sh) == NULL) + ld_fatal(ld, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + + sh.sh_name = ld_strtab_lookup(st, os->os_name); + sh.sh_flags = os->os_flags; + sh.sh_addr = os->os_addr; + sh.sh_addralign = os->os_align; + sh.sh_offset = os->os_off; + sh.sh_size = os->os_size; + sh.sh_type = os->os_type; + sh.sh_entsize = os->os_entsize; + + /* Update "sh_link" field. */ + if (os->os_link != NULL) { + if (!strcmp(os->os_link, ".symtab")) + sh.sh_link = lo->lo_symtab_shndx; + else { + HASH_FIND_STR(lo->lo_ostbl, os->os_link, _os); + if (_os == NULL) + ld_fatal(ld, "Internal: can not find" + " link section %s", os->os_link); + sh.sh_link = elf_ndxscn(_os->os_scn); + } + } + + /* Update "sh_info" field. */ + if (os->os_info != NULL) + sh.sh_info = elf_ndxscn(os->os_info->os_scn); + else + sh.sh_info = os->os_info_val; + +#if 0 + printf("name=%s, shname=%#jx, offset=%#jx, size=%#jx, type=%#jx\n", + os->os_name, (uint64_t) sh.sh_name, (uint64_t) sh.sh_offset, + (uint64_t) sh.sh_size, (uint64_t) sh.sh_type); +#endif + + if (!gelf_update_shdr(os->os_scn, &sh)) + ld_fatal(ld, "gelf_update_shdr failed: %s", + elf_errmsg(-1)); + } +} + +static void +_create_symbol_table(struct ld *ld) +{ + struct ld_state *ls; + struct ld_strtab *st; + struct ld_output *lo; + Elf_Scn *scn_symtab, *scn_strtab; + Elf_Data *d; + GElf_Shdr sh; + size_t strndx; + + ld_symbols_build_symtab(ld); + + ls = &ld->ld_state; + lo = ld->ld_output; + st = ld->ld_shstrtab; + assert(st != NULL); + + /* + * Create .symtab section. + */ + scn_symtab = _create_elf_scn(ld, lo, NULL); + scn_strtab = _create_elf_scn(ld, lo, NULL); + lo->lo_symtab_shndx = elf_ndxscn(scn_symtab); + strndx = elf_ndxscn(scn_strtab); + + if (gelf_getshdr(scn_symtab, &sh) == NULL) + ld_fatal(ld, "gelf_getshdr failed: %s", elf_errmsg(-1)); + + sh.sh_name = ld_strtab_lookup(st, ".symtab"); + sh.sh_flags = 0; + sh.sh_addr = 0; + sh.sh_addralign = (lo->lo_ec == ELFCLASS32) ? 4 : 8; + sh.sh_offset = roundup(ls->ls_offset, sh.sh_addralign); + sh.sh_entsize = (lo->lo_ec == ELFCLASS32) ? sizeof(Elf32_Sym) : + sizeof(Elf64_Sym); + sh.sh_size = ld->ld_symtab->sy_size * sh.sh_entsize; + sh.sh_type = SHT_SYMTAB; + sh.sh_link = strndx; + sh.sh_info = ld->ld_symtab->sy_first_nonlocal; + + if (!gelf_update_shdr(scn_symtab, &sh)) + ld_fatal(ld, "gelf_update_shdr failed: %s", elf_errmsg(-1)); + + if ((d = elf_newdata(scn_symtab)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = sh.sh_addralign; + d->d_off = 0; + d->d_type = ELF_T_SYM; + d->d_size = sh.sh_size; + d->d_version = EV_CURRENT; + d->d_buf = ld->ld_symtab->sy_buf; + + ls->ls_offset = sh.sh_offset + sh.sh_size; + + /* + * Create .strtab section. + */ + ld_output_create_string_table_section(ld, ".strtab", ld->ld_strtab, + scn_strtab); +} + +void +ld_output_create_string_table_section(struct ld *ld, const char *name, + struct ld_strtab *st, Elf_Scn *scn) +{ + struct ld_state *ls; + struct ld_output *lo; + Elf_Data *d; + GElf_Shdr sh; + size_t sz; + + assert(st != NULL && name != NULL); + + ls = &ld->ld_state; + lo = ld->ld_output; + + if (scn == NULL) + scn = _create_elf_scn(ld, lo, NULL); + + if (strcmp(name, ".shstrtab") == 0) { + if (!elf_setshstrndx(lo->lo_elf, elf_ndxscn(scn))) + ld_fatal(ld, "elf_setshstrndx failed: %s", + elf_errmsg(-1)); + } + + if (gelf_getshdr(scn, &sh) == NULL) + ld_fatal(ld, "gelf_getshdr failed: %s", elf_errmsg(-1)); + + sh.sh_name = ld_strtab_lookup(ld->ld_shstrtab, name); + sh.sh_flags = 0; + sh.sh_addr = 0; + sh.sh_addralign = 1; + sh.sh_offset = ls->ls_offset; + sh.sh_size = ld_strtab_getsize(st); + sh.sh_type = SHT_STRTAB; + + if (!gelf_update_shdr(scn, &sh)) + ld_fatal(ld, "gelf_update_shdr failed: %s", elf_errmsg(-1)); + + sz = ld_strtab_getsize(st); + + if ((d = elf_newdata(scn)) == NULL) + ld_fatal(ld, "elf_newdata failed: %s", elf_errmsg(-1)); + + d->d_align = 1; + d->d_off = 0; + d->d_type = ELF_T_BYTE; + d->d_size = sz; + d->d_version = EV_CURRENT; + d->d_buf = ld_strtab_getbuf(ld, st); + + ls->ls_offset += sz; +} diff --git a/contrib/elftoolchain/ld/ld_output.h b/contrib/elftoolchain/ld/ld_output.h new file mode 100644 index 0000000000..0f981e2716 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_output.h @@ -0,0 +1,165 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_output.h 2959 2013-08-25 03:12:47Z kaiwang27 $ + */ + +enum ld_output_element_type { + OET_ASSERT, + OET_ASSIGN, + OET_DATA, + OET_ENTRY, + OET_INPUT_SECTION_LIST, + OET_KEYWORD, + OET_OUTPUT_SECTION, + OET_OVERLAY, + OET_DATA_BUFFER, + OET_SYMTAB, + OET_STRTAB +}; + +struct ld_output_element { + enum ld_output_element_type oe_type; /* output element type */ + uint64_t oe_off; /* output element offset */ + void *oe_entry; /* output element */ + void *oe_islist; /* input section list */ + unsigned char oe_insec; /* element inside SECTIONS */ + STAILQ_ENTRY(ld_output_element) oe_next; /* next element */ +}; + +STAILQ_HEAD(ld_output_element_head, ld_output_element); + +struct ld_output_data_buffer { + uint8_t *odb_buf; /* point to data */ + uint64_t odb_size; /* buffer size */ + uint64_t odb_off; /* relative offset in output section */ + uint64_t odb_align; /* buffer alignment */ + uint64_t odb_type; /* buffer data type */ +}; + +struct ld_reloc_entry_head; +struct ld_symbol; + +struct ld_output_section { + Elf_Scn *os_scn; /* output section descriptor */ + char *os_name; /* output section name */ + uint64_t os_addr; /* output section vma */ + uint64_t os_lma; /* output section lma */ + uint64_t os_off; /* output section offset */ + uint64_t os_size; /* output section size */ + uint64_t os_align; /* output section alignment */ + uint64_t os_flags; /* output section flags */ + uint64_t os_type; /* output section type */ + uint64_t os_entsize; /* output seciton entry size */ + uint64_t os_info_val; /* output section info */ + unsigned char os_empty; /* output section is empty */ + unsigned char os_dynrel; /* contains dynamic relocations */ + unsigned char os_pltrel; /* contains PLT relocations */ + unsigned char os_rel; /* contains normal relocations */ + unsigned char os_entsize_set; /* entsize is set */ + char *os_link; /* link to other output section */ + struct ld_symbol *os_secsym; /* assoicated STT_SECTION symbol */ + struct ld_output_section *os_info; /* info refer to other section */ + struct ld_output_section *os_r; /* relocation section */ + struct ld_script_sections_output *os_ldso; + /* output section descriptor */ + struct ld_output_element *os_pe; /* parent element */ + struct ld_output_element_head os_e; /* list of child elements */ + struct ld_reloc_entry_head *os_reloc; /* list of relocations */ + uint64_t os_num_reloc; /* number of relocations */ + STAILQ_ENTRY(ld_output_section) os_next; /* next output section */ + UT_hash_handle hh; /* hash handle */ +}; + +STAILQ_HEAD(ld_output_section_head, ld_output_section); + +struct ld_symver_verneed_head; + +struct ld_output { + int lo_fd; /* output file descriptor */ + Elf *lo_elf; /* output ELF descriptor */ + int lo_ec; /* output object elf class */ + int lo_endian; /* outout object endianess */ + int lo_osabi; /* output object osabi */ + int lo_soname_nameindex; /* string index for DT_SONAME */ + int lo_rpath_nameindex; /* string index for DT_RPATH */ + unsigned lo_phdr_num; /* num of phdrs */ + unsigned lo_phdr_note; /* create PT_NOTE */ + unsigned lo_dso_needed; /* num of DSO referenced */ + unsigned lo_version_index; /* current symver index */ + unsigned lo_verdef_num; /* num of verdef entries */ + unsigned lo_verneed_num; /* num of verneed entries */ + unsigned lo_rel_plt_type; /* type of PLT relocation */ + unsigned lo_rel_dyn_type; /* type of dynamic relocation */ + unsigned lo_fde_num; /* num of FDE in .eh_frame */ + uint64_t lo_shoff; /* section header table offset */ + uint64_t lo_tls_size; /* TLS segment size */ + uint64_t lo_tls_align; /* TLS segment align */ + uint64_t lo_tls_addr; /* TLS segment VMA */ + size_t lo_symtab_shndx; /* .symtab section index */ + UT_array *lo_dso_nameindex; /* array of DSO name indices */ + struct ld_symver_verneed_head *lo_vnlist; /* Verneed list */ + struct ld_output_element_head lo_oelist; /* output element list */ + struct ld_output_section_head lo_oslist; /* output section list */ + struct ld_output_section *lo_ostbl; /* output section hash table */ + struct ld_output_section *lo_interp; /* .interp section. */ + struct ld_output_section *lo_init; /* .init section */ + struct ld_output_section *lo_fini; /* .fini section */ + struct ld_output_section *lo_dynamic; /* .dynamic section. */ + struct ld_output_section *lo_dynsym; /* .dynsym section. */ + struct ld_output_section *lo_dynstr; /* .dynstr section. */ + struct ld_output_section *lo_hash; /* .hash section. */ + struct ld_output_section *lo_verdef; /* .gnu.version.d section */ + struct ld_output_section *lo_verneed; /* .gnu.version.r section */ + struct ld_output_section *lo_versym; /* .gnu.version section */ + struct ld_output_section *lo_gotplt; /* GOT(for PLT) section */ + struct ld_output_section *lo_plt; /* PLT section */ + struct ld_output_section *lo_rel_plt; /* PLT relocation section */ + struct ld_output_section *lo_rel_dyn; /* Dynamic relocation section */ + struct ld_output_section *lo_ehframe_hdr; /* .eh_frame_hdr section */ + struct ld_output_data_buffer *lo_dynamic_odb; /* .dynamic buffer */ + struct ld_output_data_buffer *lo_got_odb; /* GOT section data */ + struct ld_output_data_buffer *lo_plt_odb; /* PLT section data */ + struct ld_output_data_buffer *lo_rel_plt_odb; /* PLT reloc data */ + struct ld_output_data_buffer *lo_rel_dyn_odb; /* dynamic reloc data */ +}; + +struct ld_output_section *ld_output_alloc_section(struct ld *, const char *, + struct ld_output_section *, struct ld_output_section *); +void ld_output_create(struct ld *); +struct ld_output_element *ld_output_create_element(struct ld *, + struct ld_output_element_head *, enum ld_output_element_type, void *, + struct ld_output_element *); +struct ld_output_element *ld_output_create_section_element(struct ld *, + struct ld_output_section *, enum ld_output_element_type, void *, + struct ld_output_element *); +void ld_output_create_elf_sections(struct ld *); +void ld_output_create_string_table_section(struct ld *, const char *, + struct ld_strtab *, Elf_Scn *); +void ld_output_emit_gnu_stack_section(struct ld *); +void ld_output_format(struct ld *, char *, char *, char *); +void ld_output_early_init(struct ld *); +void ld_output_init(struct ld *); +void ld_output_write(struct ld *); diff --git a/contrib/elftoolchain/ld/ld_path.c b/contrib/elftoolchain/ld/ld_path.c new file mode 100644 index 0000000000..15687b5a40 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_path.c @@ -0,0 +1,295 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_path.c 2930 2013-03-17 22:54:26Z kaiwang27 $ + */ + +#include "ld.h" +#include "ld_file.h" +#include "ld_path.h" + +static char *_search_file(struct ld *ld, const char *path, const char *file); + +static char * +_search_file(struct ld *ld, const char *path, const char *file) +{ + struct dirent *dp; + DIR *dirp; + char *fp; + + assert(path != NULL && file != NULL); + + if ((dirp = opendir(path)) == NULL) { + ld_warn(ld, "opendir failed: %s", strerror(errno)); + return (NULL); + } + + fp = NULL; + while ((dp = readdir(dirp)) != NULL) { + if (!strcmp(dp->d_name, file)) { + if ((fp = malloc(PATH_MAX + 1)) == NULL) + ld_fatal_std(ld, "malloc"); + fp[0] = '\0'; + snprintf(fp, PATH_MAX + 1, "%s/%s", path, dp->d_name); + break; + } + } + (void) closedir(dirp); + + return (fp); +} + +void +ld_path_add(struct ld *ld, char *path, enum ld_path_type lpt) +{ + struct ld_state *ls; + struct ld_path *lp; + + assert(ld != NULL && path != NULL); + ls = &ld->ld_state; + + if ((lp = calloc(1, sizeof(*lp))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((lp->lp_path = strdup(path)) == NULL) + ld_fatal_std(ld, "strdup"); + + switch (lpt) { + case LPT_L: + STAILQ_INSERT_TAIL(&ls->ls_lplist, lp, lp_next); + break; + case LPT_RPATH: + STAILQ_INSERT_TAIL(&ls->ls_rplist, lp, lp_next); + break; + case LPT_RPATH_LINK: + STAILQ_INSERT_TAIL(&ls->ls_rllist, lp, lp_next); + break; + default: + ld_fatal(ld, "Internal: invalid path type %d", lpt); + break; + } +} + +void +ld_path_add_multiple(struct ld *ld, char *str, enum ld_path_type lpt) +{ + char *p; + + while ((p = strsep(&str, ":")) != NULL) { + if (*p != '\0') + ld_path_add(ld, p, lpt); + } +} + +void +ld_path_cleanup(struct ld *ld) +{ + struct ld_state *ls; + struct ld_path *lp, *_lp; + + ls = &ld->ld_state; + + STAILQ_FOREACH_SAFE(lp, &ls->ls_lplist, lp_next, _lp) { + STAILQ_REMOVE(&ls->ls_lplist, lp, ld_path, lp_next); + free(lp->lp_path); + free(lp); + } + + STAILQ_FOREACH_SAFE(lp, &ls->ls_rplist, lp_next, _lp) { + STAILQ_REMOVE(&ls->ls_rplist, lp, ld_path, lp_next); + free(lp->lp_path); + free(lp); + } + + STAILQ_FOREACH_SAFE(lp, &ls->ls_rllist, lp_next, _lp) { + STAILQ_REMOVE(&ls->ls_rllist, lp, ld_path, lp_next); + free(lp->lp_path); + free(lp); + } +} + +char * +ld_path_join_rpath(struct ld *ld) +{ + struct ld_state *ls; + struct ld_path *lp; + char *s; + int len; + + ls = &ld->ld_state; + + if (STAILQ_EMPTY(&ls->ls_rplist)) + return (NULL); + + len = 0; + STAILQ_FOREACH(lp, &ls->ls_rplist, lp_next) + len += strlen(lp->lp_path) + 1; + + if ((s = malloc(len)) == NULL) + ld_fatal_std(ld, "malloc"); + + STAILQ_FOREACH(lp, &ls->ls_rplist, lp_next) { + strcat(s, lp->lp_path); + if (lp != STAILQ_LAST(&ls->ls_rplist, ld_path, lp_next)) + strcat(s, ":"); + } + + return (s); +} + +void +ld_path_search_file(struct ld *ld, struct ld_file *lf) +{ + struct ld_state *ls; + struct ld_path *lp; + char *fp; + int found; + + assert(lf != NULL); + ls = &ld->ld_state; + + found = 0; + STAILQ_FOREACH(lp, &ls->ls_lplist, lp_next) { + if ((fp = _search_file(ld, lp->lp_path, lf->lf_name)) != + NULL) { + free(lf->lf_name); + lf->lf_name = fp; + found = 1; + break; + } + } + + if (!found) + ld_fatal(ld, "cannot find %s", lf->lf_name); +} + +void +ld_path_search_library(struct ld *ld, const char *name) +{ + struct ld_state *ls; + struct ld_path *lp; + struct dirent *dp; + DIR *dirp; + char fp[PATH_MAX + 1], sfp[PATH_MAX + 1]; + size_t len; + int found; + + assert(ld != NULL && name != NULL); + ls = &ld->ld_state; + + len = strlen(name); + found = 0; + STAILQ_FOREACH(lp, &ls->ls_lplist, lp_next) { + assert(lp->lp_path != NULL); + if ((dirp = opendir(lp->lp_path)) == NULL) { + ld_warn(ld, "opendir failed: %s", strerror(errno)); + continue; + } + + fp[0] = sfp[0] = '\0'; + while ((dp = readdir(dirp)) != NULL) { + if (strncmp(dp->d_name, "lib", 3)) + continue; + if (strncmp(name, &dp->d_name[3], len)) + continue; + if (ls->ls_static == 0 && + !strcmp(&dp->d_name[len + 3], ".so")) { + snprintf(fp, sizeof(fp), "%s/%s", lp->lp_path, + dp->d_name); + ld_file_add(ld, fp, LFT_DSO); + (void) closedir(dirp); + found = 1; + goto done; + } else if (*sfp == '\0' && + !strcmp(&dp->d_name[len + 3], ".a")) { + snprintf(sfp, sizeof(sfp), "%s/%s", lp->lp_path, + dp->d_name); + if (ls->ls_static == 1) { + ld_file_add(ld, sfp, LFT_ARCHIVE); + (void) closedir(dirp); + found = 1; + goto done; + } + } + } + (void) closedir(dirp); + } +done: + if (!found) { + if (ls->ls_static == 0 && *sfp != '\0') { + ld_file_add(ld, sfp, LFT_ARCHIVE); + } else + ld_fatal(ld, "cannot find -l%s", name); + } +} + +void +ld_path_search_dso_needed(struct ld *ld, struct ld_file *lf, const char *name) +{ + struct ld_state *ls; + struct ld_path *lp; + struct ld_file *_lf; + char *fp; + + ls = &ld->ld_state; + + /* + * First check if we've seen this shared library or if it's + * already listed in the input file list. + */ + TAILQ_FOREACH(_lf, &ld->ld_lflist, lf_next) { + if (!strcmp(_lf->lf_name, name) || + !strcmp(basename(_lf->lf_name), name)) + return; + } + + /* Search -rpath-link directories. */ + STAILQ_FOREACH(lp, &ls->ls_rllist, lp_next) { + if ((fp = _search_file(ld, lp->lp_path, name)) != NULL) + goto done; + } + + /* Search -rpath directories. */ + STAILQ_FOREACH(lp, &ls->ls_rplist, lp_next) { + if ((fp = _search_file(ld, lp->lp_path, name)) != NULL) + goto done; + } + + /* TODO: search additional directories and environment variables. */ + + /* Search /lib and /usr/lib. */ + if ((fp = _search_file(ld, "/lib", name)) != NULL) + goto done; + if ((fp = _search_file(ld, "/usr/lib", name)) != NULL) + goto done; + + /* Not found. */ + ld_warn(ld, "cannot find needed shared library: %s", name); + return; + +done: + ld_file_add_after(ld, fp, LFT_DSO, lf); + free(fp); +} diff --git a/contrib/elftoolchain/ld/ld_path.h b/contrib/elftoolchain/ld/ld_path.h new file mode 100644 index 0000000000..791a82a518 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_path.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_path.h 2930 2013-03-17 22:54:26Z kaiwang27 $ + */ + +enum ld_path_type { + LPT_L, + LPT_RPATH, + LPT_RPATH_LINK, +}; + +struct ld_path { + char *lp_path; + STAILQ_ENTRY(ld_path) lp_next; +}; + +void ld_path_add(struct ld *, char *, enum ld_path_type); +void ld_path_add_multiple(struct ld *, char *, enum ld_path_type); +void ld_path_cleanup(struct ld *); +char *ld_path_join_rpath(struct ld *); +void ld_path_search_file(struct ld *, struct ld_file *); +void ld_path_search_library(struct ld *, const char *); +void ld_path_search_dso_needed(struct ld *, struct ld_file *, const char *); diff --git a/contrib/elftoolchain/ld/ld_reloc.c b/contrib/elftoolchain/ld/ld_reloc.c new file mode 100644 index 0000000000..0ca6ec8e4c --- /dev/null +++ b/contrib/elftoolchain/ld/ld_reloc.c @@ -0,0 +1,875 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_ehframe.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_script.h" +#include "ld_symbols.h" +#include "ld_utils.h" + +ELFTC_VCSID("$Id: ld_reloc.c 2962 2013-08-25 16:34:57Z kaiwang27 $"); + +static struct ld *_ld; + +/* + * Support routines for relocation handling. + */ + +static int _discard_reloc(struct ld *ld, struct ld_input_section *is, + uint64_t sym, uint64_t off, uint64_t *reloc_adjust); +static void _scan_reloc(struct ld *ld, struct ld_input_section *is, + uint64_t sym, struct ld_reloc_entry *lre); +static void _read_rel(struct ld *ld, struct ld_input_section *is, + Elf_Data *d); +static void _read_rela(struct ld *ld, struct ld_input_section *is, + Elf_Data *d); +static void _add_to_gc_search_list(struct ld_state *ls, + struct ld_input_section *is); +static uint64_t _reloc_addr(struct ld_reloc_entry *lre); +static int _cmp_reloc(struct ld_reloc_entry *a, struct ld_reloc_entry *b); + +void +ld_reloc_load(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + int elferr, i; + + ld_input_link_objects(ld); + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + + if (li->li_name == NULL || li->li_type == LIT_DSO) + continue; + + ld_input_load(ld, li); + e = li->li_elf; + + for (i = 0; (uint64_t) i < li->li_shnum - 1; i++) { + is = &li->li_is[i]; + + if (is->is_type != SHT_REL && is->is_type != SHT_RELA) + continue; + + if ((scn = elf_getscn(e, is->is_index)) == NULL) { + ld_warn(ld, "%s(%s): elf_getscn failed: %s", + li->li_name, is->is_name, elf_errmsg(-1)); + continue; + } + + (void) elf_errno(); + if ((d = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s(%s): elf_getdata " + "failed: %s", li->li_name, + is->is_name, elf_errmsg(elferr)); + continue; + } + + /* + * Find out the section to which this relocation + * section applies. + */ + if (is->is_info < li->li_shnum) { + is->is_tis = &li->li_is[is->is_info]; + li->li_is[is->is_info].is_ris = is; + } else { + ld_warn(ld, "%s(%s): invalid relocation" + " section", li->li_name, is->is_name); + continue; + } + + /* + * Load and process relocation entries. + */ + if ((is->is_reloc = malloc(sizeof(*is->is_reloc))) == + NULL) + ld_fatal(ld, "malloc"); + STAILQ_INIT(is->is_reloc); + + if (is->is_type == SHT_REL) + _read_rel(ld, is, d); + else + _read_rela(ld, is, d); + + if (!strcmp(is->is_tis->is_name, ".eh_frame")) + ld_ehframe_adjust(ld, is->is_tis); + } + + ld_input_unload(ld, li); + } +} + +void +ld_reloc_deferred_scan(struct ld *ld) +{ + struct ld_input *li; + struct ld_input_section *is; + struct ld_reloc_entry *lre; + int i; + + if (ld->ld_reloc) + return; + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + + if (li->li_name == NULL || li->li_type == LIT_DSO) + continue; + + for (i = 0; (uint64_t) i < li->li_shnum - 1; i++) { + is = &li->li_is[i]; + + if (is->is_type != SHT_REL && is->is_type != SHT_RELA) + continue; + + if (is->is_reloc == NULL) + continue; + + STAILQ_FOREACH(lre, is->is_reloc, lre_next) { + ld->ld_arch->scan_reloc(ld, is->is_tis, lre); + } + } + } +} + +static int +_discard_reloc(struct ld *ld, struct ld_input_section *is, uint64_t sym, + uint64_t off, uint64_t *reloc_adjust) +{ + struct ld_output *lo; + uint8_t *p; + uint64_t length; + uint32_t cie_id; + + lo = ld->ld_output; + assert(lo != NULL); + + /* + * Relocation entry should be discarded if the symbol it refers + * to was discarded. + */ + if (is->is_input->li_symindex[sym] != NULL) + return (0); + + if (strcmp(is->is_tis->is_name, ".eh_frame")) + goto discard_reloc; + + /* + * If we discard a relocation entry for a FDE in the .eh_frame + * section, we need also to remove the FDE entry and adjust the + * relocation offset of the following relocation entries for + * the .eh_frame section. + */ + + assert(is->is_tis->is_ehframe != NULL); + p = is->is_tis->is_ehframe; + p += off - 8; /* XXX extended length unsupported */ + + /* Read CIE/FDE length field. */ + READ_32(p, length); + p += 4; + + /* Check for terminator. (Shouldn't happen) */ + if (length == 0) + goto discard_reloc; + + /* Read CIE ID/Pointer field. */ + READ_32(p, cie_id); + if (cie_id == 0) + goto discard_reloc; /* Shouldn't happen */ + + /* Set CIE ID to 0xFFFFFFFF to mark this FDE to be discarded */ + WRITE_32(p, 0xFFFFFFFF); + + /* Update relocation offset adjustment. */ + *reloc_adjust += length + 4; + + /* Reduce the size of the .eh_frame section. */ + is->is_tis->is_shrink += length + 4; + +discard_reloc: + + /* Reduce the size of the relocation section accordingly */ + is->is_size -= ld->ld_arch->reloc_entsize; + + return (1); +} + +static void +_read_rel(struct ld *ld, struct ld_input_section *is, Elf_Data *d) +{ + struct ld_reloc_entry *lre; + GElf_Rel r; + uint64_t reloc_adjust, sym; + int i, len; + + assert(is->is_reloc != NULL); + + reloc_adjust = 0; + len = d->d_size / is->is_entsize; + for (i = 0; i < len; i++) { + if (gelf_getrel(d, i, &r) != &r) { + ld_warn(ld, "gelf_getrel failed: %s", elf_errmsg(-1)); + continue; + } + sym = GELF_R_SYM(r.r_info); + if (_discard_reloc(ld, is, sym, r.r_offset, &reloc_adjust)) + continue; + if ((lre = calloc(1, sizeof(*lre))) == NULL) + ld_fatal(ld, "calloc"); + assert(r.r_offset >= reloc_adjust); + lre->lre_offset = r.r_offset - reloc_adjust; + lre->lre_type = GELF_R_TYPE(r.r_info); + lre->lre_tis = is->is_tis; + _scan_reloc(ld, is, sym, lre); + STAILQ_INSERT_TAIL(is->is_reloc, lre, lre_next); + is->is_num_reloc++; + } + is->is_tis->is_shrink = reloc_adjust; +} + +static void +_read_rela(struct ld *ld, struct ld_input_section *is, Elf_Data *d) +{ + struct ld_reloc_entry *lre; + GElf_Rela r; + uint64_t reloc_adjust, sym; + int i, len; + + assert(is->is_reloc != NULL); + + reloc_adjust = 0; + len = d->d_size / is->is_entsize; + for (i = 0; i < len; i++) { + if (gelf_getrela(d, i, &r) != &r) { + ld_warn(ld, "gelf_getrel failed: %s", elf_errmsg(-1)); + continue; + } + sym = GELF_R_SYM(r.r_info); + if (_discard_reloc(ld, is, sym, r.r_offset, &reloc_adjust)) + continue; + if ((lre = calloc(1, sizeof(*lre))) == NULL) + ld_fatal(ld, "calloc"); + assert(r.r_offset >= reloc_adjust); + lre->lre_offset = r.r_offset - reloc_adjust; + lre->lre_type = GELF_R_TYPE(r.r_info); + lre->lre_addend = r.r_addend; + lre->lre_tis = is->is_tis; + _scan_reloc(ld, is, sym, lre); + STAILQ_INSERT_TAIL(is->is_reloc, lre, lre_next); + is->is_num_reloc++; + } + is->is_tis->is_shrink = reloc_adjust; +} + +static void +_scan_reloc(struct ld *ld, struct ld_input_section *is, uint64_t sym, + struct ld_reloc_entry *lre) +{ + struct ld_input *li; + + (void) ld; + + li = is->is_input; + + lre->lre_sym = li->li_symindex[sym]; + + if (!ld->ld_reloc && !ld->ld_gc) + ld->ld_arch->scan_reloc(ld, is->is_tis, lre); +} + +static void +_add_to_gc_search_list(struct ld_state *ls, struct ld_input_section *is) +{ + + assert(is != NULL); + + /* Only add allocated sections. */ + if ((is->is_flags & SHF_ALLOC) == 0) + return; + + /* + * Do not add sections that are already exist in the search list, + * or sections that don't have assoicated relocations. + */ + if (is->is_refed || is->is_ris == NULL || is->is_ris->is_reloc == NULL) + return; + + STAILQ_INSERT_TAIL(ls->ls_gc, is, is_gc_next); +} + +void +ld_reloc_gc_sections(struct ld *ld) +{ + struct ld_state *ls; + struct ld_symbol *lsb; + struct ld_input_section *is; + struct ld_reloc_entry *lre; + char *entry; + + /* + * Initialise search list. Initial search list consists of sections + * contains the entry and extern symbols. + */ + ls = &ld->ld_state; + if ((ls->ls_gc = calloc(1, sizeof(*ls->ls_gc))) == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(ls->ls_gc); + + /* + * Add the section that contains the entry symbol to the initial + * search list. + */ + entry = ld->ld_entry != NULL ? ld->ld_entry : + ld->ld_scp->lds_entry_point; + if (entry != NULL) { + HASH_FIND_STR(ld->ld_sym, entry, lsb); + if (lsb != NULL && lsb->lsb_is != NULL) + _add_to_gc_search_list(ls, lsb->lsb_is); + } + + /* + * Add sections that contain the symbols specified by command line + * option `-u' (extern symbols) to the initial search list. + */ + if (ld->ld_ext_symbols != NULL) { + STAILQ_FOREACH(lsb, ld->ld_ext_symbols, lsb_next) { + if (lsb->lsb_is != NULL) + _add_to_gc_search_list(ls, lsb->lsb_is); + } + } + + /* + * Breadth-first search for sections referenced by relocations + * assoicated with the initial sections. The search is recusive, + * the relocations assoicated with the found sections are again + * used to search for more referenced sections. + */ + STAILQ_FOREACH(is, ls->ls_gc, is_gc_next) { + assert(is->is_ris != NULL); + STAILQ_FOREACH(lre, is->is_ris->is_reloc, lre_next) { + if (lre->lre_sym == NULL) + continue; + lsb = ld_symbols_ref(lre->lre_sym); + if (lsb->lsb_is != NULL) + _add_to_gc_search_list(ls, lsb->lsb_is); + } + } +} + +void * +ld_reloc_serialize(struct ld *ld, struct ld_output_section *os, size_t *sz) +{ + struct ld_reloc_entry *lre; + struct ld_symbol *lsb; + Elf32_Rel *r32; + Elf64_Rel *r64; + Elf32_Rela *ra32; + Elf64_Rela *ra64; + uint8_t *p; + void *b; + size_t entsize; + uint64_t sym; + unsigned char is_64; + unsigned char is_rela; + + is_64 = ld->ld_arch->reloc_is_64bit; + is_rela = ld->ld_arch->reloc_is_rela; + entsize = ld->ld_arch->reloc_entsize; + + b = malloc(ld->ld_arch->reloc_entsize * os->os_num_reloc); + if (b == NULL) + ld_fatal_std(ld, "malloc"); + + p = b; + STAILQ_FOREACH(lre, os->os_reloc, lre_next) { + if (lre->lre_sym != NULL) { + lsb = ld_symbols_ref(lre->lre_sym); + if (os->os_dynrel) + sym = lsb->lsb_dyn_index; + else + sym = lsb->lsb_out_index; + } else + sym = 0; + + if (is_64 && is_rela) { + ra64 = (Elf64_Rela *) (uintptr_t) p; + ra64->r_offset = lre->lre_offset; + ra64->r_info = ELF64_R_INFO(sym, lre->lre_type); + ra64->r_addend = lre->lre_addend; + } else if (!is_64 && !is_rela) { + r32 = (Elf32_Rel *) (uintptr_t) p; + r32->r_offset = (uint32_t) lre->lre_offset; + r32->r_info = (uint32_t) ELF32_R_INFO(sym, + lre->lre_type); + } else if (!is_64 && is_rela) { + ra32 = (Elf32_Rela *) (uintptr_t) p; + ra32->r_offset = (uint32_t) lre->lre_offset; + ra32->r_info = (uint32_t) ELF32_R_INFO(sym, + lre->lre_type); + ra32->r_addend = (int32_t) lre->lre_addend; + } else if (is_64 && !is_rela) { + r64 = (Elf64_Rel *) (uintptr_t) p; + r64->r_offset = lre->lre_offset; + r64->r_info = ELF64_R_INFO(sym, lre->lre_type); + } + + p += entsize; + } + + *sz = entsize * os->os_num_reloc; + assert((size_t) (p - (uint8_t *) b) == *sz); + + return (b); +} + +void +ld_reloc_create_entry(struct ld *ld, const char *name, + struct ld_input_section *tis, uint64_t type, struct ld_symbol *lsb, + uint64_t offset, int64_t addend) +{ + struct ld_input_section *is; + struct ld_reloc_entry *lre; + int len; + + /* + * List of internal sections to hold dynamic relocations: + * + * .rel.bss contains copy relocations + * .rel.plt contains PLT (*_JMP_SLOT) relocations + * .rel.got contains GOT (*_GLOB_DATA) relocations + * .rel.data.* contains *_RELATIVE and absolute relocations + */ + + is = ld_input_find_internal_section(ld, name); + if (is == NULL) { + is = ld_input_add_internal_section(ld, name); + is->is_dynrel = 1; + is->is_type = ld->ld_arch->reloc_is_rela ? SHT_RELA : SHT_REL; + is->is_align = ld->ld_arch->reloc_is_64bit ? 8 : 4; + is->is_entsize = ld->ld_arch->reloc_entsize; + + len = strlen(name); + if (len > 3 && name[len - 1] == 't' && name[len - 2] == 'l' && + name[len - 3] == 'p') + is->is_pltrel = 1; + } + + if (is->is_reloc == NULL) { + is->is_reloc = calloc(1, sizeof(*is->is_reloc)); + if (is->is_reloc == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(is->is_reloc); + } + + if ((lre = malloc(sizeof(*lre))) == NULL) + ld_fatal_std(ld, "calloc"); + + lre->lre_tis = tis; + lre->lre_type = type; + lre->lre_sym = lsb; + lre->lre_offset = offset; + lre->lre_addend = addend; + + STAILQ_INSERT_TAIL(is->is_reloc, lre, lre_next); + is->is_num_reloc++; + is->is_size += ld->ld_arch->reloc_entsize; + + /* Keep track of the total number of *_RELATIVE relocations. */ + if (ld->ld_arch->is_relative_reloc(type)) + ld->ld_state.ls_relative_reloc++; +} + +void +ld_reloc_finalize_dynamic(struct ld *ld, struct ld_output *lo, + struct ld_output_section *os) +{ + struct ld_input_section *is; + struct ld_output_section *_os; + struct ld_reloc_entry *lre; + + if (!os->os_dynrel || os->os_reloc == NULL) + return; + + /* PLT relocation is handled in arch-specified code. */ + if (os->os_pltrel) + return; + + /* + * Set the lo->lo_rel_dyn here so that the DT_* entries needed for + * dynamic relocation will be generated. + * + * Note that besides the PLT relocation section, we can only have one + * dynamic relocation section in the output object. + */ + if (lo->lo_rel_dyn == NULL) + lo->lo_rel_dyn = os; + + STAILQ_FOREACH(lre, os->os_reloc, lre_next) { + /* + * Found out the corresponding output section for the input + * section which the relocation applies to. + */ + is = lre->lre_tis; + assert(is != NULL); + if ((_os = is->is_output) == NULL) + continue; + + /* + * Update the relocation offset to make it point to the + * correct place in the output section. + */ + lre->lre_offset += _os->os_addr + is->is_reloff; + + /* + * Perform arch-specific dynamic relocation + * finalization. + */ + ld->ld_arch->finalize_reloc(ld, is, lre); + } +} + +void +ld_reloc_join(struct ld *ld, struct ld_output_section *os, + struct ld_input_section *is) +{ + + assert(is->is_reloc != NULL); + + if (os->os_reloc == NULL) { + if ((os->os_reloc = malloc(sizeof(*os->os_reloc))) == NULL) + ld_fatal_std(ld, "malloc"); + STAILQ_INIT(os->os_reloc); + } + + STAILQ_CONCAT(os->os_reloc, is->is_reloc); + os->os_num_reloc += is->is_num_reloc; + + is->is_num_reloc = 0; + free(is->is_reloc); + is->is_reloc = NULL; +} + +static uint64_t +_reloc_addr(struct ld_reloc_entry *lre) +{ + + return (lre->lre_tis->is_output->os_addr + lre->lre_tis->is_reloff + + lre->lre_offset); +} + +static int +_cmp_reloc(struct ld_reloc_entry *a, struct ld_reloc_entry *b) +{ + struct ld *ld; + + ld = _ld; + + /* + * Sort dynamic relocation entries to make the runtime linker + * run faster. *_RELATIVE relocations should be sorted to the + * front. Between two *_RELATIVE relocations, the one with + * lower address should appear first. For other relocations + * we sort them by assoicated dynamic symbol index, then + * by relocation type. + */ + + if (ld->ld_arch->is_relative_reloc(a->lre_type) && + !ld->ld_arch->is_relative_reloc(b->lre_type)) + return (-1); + + if (!ld->ld_arch->is_relative_reloc(a->lre_type) && + ld->ld_arch->is_relative_reloc(b->lre_type)) + return (1); + + if (ld->ld_arch->is_relative_reloc(a->lre_type) && + ld->ld_arch->is_relative_reloc(b->lre_type)) { + if (_reloc_addr(a) < _reloc_addr(b)) + return (-1); + else if (_reloc_addr(a) > _reloc_addr(b)) + return (1); + else + return (0); + } + + if (a->lre_sym->lsb_dyn_index < b->lre_sym->lsb_dyn_index) + return (-1); + else if (a->lre_sym->lsb_dyn_index > b->lre_sym->lsb_dyn_index) + return (1); + + if (a->lre_type < b->lre_type) + return (-1); + else if (a->lre_type > b->lre_type) + return (1); + + return (0); +} + +void +ld_reloc_sort(struct ld *ld, struct ld_output_section *os) +{ + + _ld = ld; + + if (os->os_reloc == NULL) + return; + + STAILQ_SORT(os->os_reloc, ld_reloc_entry, lre_next, _cmp_reloc); +} + +int +ld_reloc_require_plt(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* Only need PLT for functions. */ + if (lsb->lsb_type != STT_FUNC) + return (0); + + /* Create PLT for functions in DSOs. */ + if (ld_symbols_in_dso(lsb)) + return (1); + + /* + * If the linker outputs a DSO, PLT entry is needed if the symbol + * if undefined or it can be overridden. + */ + if (ld->ld_dso && + (lsb->lsb_shndx == SHN_UNDEF || ld_symbols_overridden(ld, lsb))) + return (1); + + /* Otherwise, we do not create PLT entry. */ + return (0); +} + +int +ld_reloc_require_copy_reloc(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* Functions do not need copy reloc. */ + if (lsb->lsb_type == STT_FUNC) + return (0); + + /* + * If we are generating a normal executable and the symbol is + * defined in a DSO, we need a copy reloc. + */ + if (ld->ld_exec && ld_symbols_in_dso(lsb)) + return (1); + + return (0); +} + +int +ld_reloc_require_glob_dat(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * If the symbol is undefined or if it's defined in a DSO, + * GLOB_DAT relocation is required. + */ + if (lsb->lsb_shndx == SHN_UNDEF || ld_symbols_in_dso(lsb)) + return (1); + + /* + * If the linker creates a DSO and the symbol can be overridden + * GLOB_DAT relocation is required. + */ + if (ld->ld_dso && ld_symbols_overridden(ld, lsb)) + return (1); + + /* + * If the linker creates a DSO and the symbol visibility is + * STV_PROTECTED, GLOB_DAT relocation is required for function + * address comparsion to work. + */ + if (ld->ld_dso && lsb->lsb_other == STV_PROTECTED) + return (1); + + /* + * Otherwise GLOB_DAT relocation is not required, RELATIVE + * relocation can be used instead. + */ + return (0); +} + +int +ld_reloc_require_dynamic_reloc(struct ld *ld, struct ld_reloc_entry *lre) +{ + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * If the symbol is defined in a DSO, we create specific dynamic + * relocations when we create PLT, GOT or copy reloc. + */ + if (ld_symbols_in_dso(lsb)) + return (0); + + /* + * When we are creating a DSO, we create dynamic relocation if + * the symbol is undefined, or if the symbol can be overridden. + */ + if (ld->ld_dso && (lsb->lsb_shndx == SHN_UNDEF || + ld_symbols_overridden(ld, lsb))) + return (1); + + /* + * When we are creating a PIE/DSO (position-independent), if the + * relocation is referencing the absolute address of a symbol, + * we should create dynamic relocation. + */ + if ((ld->ld_pie || ld->ld_dso) && + ld->ld_arch->is_absolute_reloc(lre->lre_type)) + return (1); + + /* Otherwise we do not generate dynamic relocation. */ + return (0); +} + +int +ld_reloc_relative_relax(struct ld *ld, struct ld_reloc_entry *lre) +{ + + struct ld_symbol *lsb; + + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * We only use *_RELATIVE relocation when we create PIE/DSO. + */ + if (!ld->ld_pie && !ld->ld_dso) + return (0); + + /* + * If the symbol is defined in a DSO, we can not relax the + * relocation. + */ + if (ld_symbols_in_dso(lsb)) + return (0); + + /* + * When we are creating a DSO, we can not relax dynamic relocation + * to *_RELATIVE relocation if the symbol is undefined, or if the + * symbol can be overridden. + */ + if (ld->ld_dso && (lsb->lsb_shndx == SHN_UNDEF || + ld_symbols_overridden(ld, lsb))) + return (0); + + /* Otherwise it's ok to use *_RELATIVE. */ + return (1); +} + +void +ld_reloc_process_input_section(struct ld *ld, struct ld_input_section *is, + void *buf) +{ + struct ld_input *li; + struct ld_input_section *ris; + struct ld_output_section *os; + struct ld_reloc_entry *lre; + struct ld_symbol *lsb; + int i; + + if (is->is_type == SHT_REL || is->is_type == SHT_RELA) + return; + + os = is->is_output; + + li = is->is_input; + if (is->is_ris != NULL) + ris = is->is_ris; + else { + ris = NULL; + for (i = 0; (uint64_t) i < li->li_shnum; i++) { + if (li->li_is[i].is_type != SHT_REL && + li->li_is[i].is_type != SHT_RELA) + continue; + if (li->li_is[i].is_info == is->is_index) { + ris = &li->li_is[i]; + break; + } + } + } + + if (ris == NULL) + return; + + assert(ris->is_reloc != NULL); + + STAILQ_FOREACH(lre, ris->is_reloc, lre_next) { + lsb = ld_symbols_ref(lre->lre_sym); + + /* + * Arch-specific relocation handling for non-relocatable + * output object. + */ + if (!ld->ld_reloc) + ld->ld_arch->process_reloc(ld, is, lre, lsb, buf); + + /* + * Arch-specific relocation handling for relocatable output + * object and -emit-relocs option. + * + * Note that for SHT_REL relocation sections, relocation + * addend (in-place) is not adjusted since it will overwrite + * the already applied relocation. + */ + if (ld->ld_reloc || + (ld->ld_emit_reloc && ld->ld_arch->reloc_is_rela)) + ld->ld_arch->adjust_reloc(ld, is, lre, lsb, buf); + + /* + * Update the relocation offset to make it point to the + * correct place in the output section. For -emit-relocs + * option, the section VMA is used. For relocatable output + * object, the section relative offset is added to the + * relocation offset. + */ + if (ld->ld_reloc) + lre->lre_offset += is->is_reloff; + else if (ld->ld_emit_reloc) + lre->lre_offset += os->os_addr + is->is_reloff; + } +} diff --git a/contrib/elftoolchain/ld/ld_reloc.h b/contrib/elftoolchain/ld/ld_reloc.h new file mode 100644 index 0000000000..9fc4e9d7e6 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_reloc.h @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_reloc.h 2898 2013-01-15 23:05:59Z kaiwang27 $ + */ + +struct ld_symbol; +struct ld_input_section; +struct ld_output_section; + +struct ld_reloc_entry { + struct ld_input_section *lre_tis; /* input section to apply to */ + struct ld_symbol *lre_sym; /* reloc symbol */ + uint64_t lre_type; /* reloc type */ + uint64_t lre_offset; /* reloc offset */ + uint64_t lre_addend; /* reloc addend */ + STAILQ_ENTRY(ld_reloc_entry) lre_next; /* next reloc */ +}; + +STAILQ_HEAD(ld_reloc_entry_head, ld_reloc_entry); + +enum ld_tls_relax { + TLS_RELAX_NONE, + TLS_RELAX_INIT_EXEC, + TLS_RELAX_LOCAL_EXEC +}; + +void ld_reloc_create_entry(struct ld *, const char *, + struct ld_input_section *, uint64_t, struct ld_symbol *, uint64_t, + int64_t); +void ld_reloc_deferred_scan(struct ld *); +void ld_reloc_finalize(struct ld *, struct ld_output_section *); +void ld_reloc_finalize_dynamic(struct ld *, struct ld_output *, + struct ld_output_section *); +void ld_reloc_gc_sections(struct ld *); +void ld_reloc_join(struct ld *, struct ld_output_section *, + struct ld_input_section *); +void ld_reloc_sort(struct ld *, struct ld_output_section *); +void ld_reloc_load(struct ld *); +void ld_reloc_process_input_section(struct ld *, struct ld_input_section *, + void *); +int ld_reloc_require_plt(struct ld *, struct ld_reloc_entry *); +int ld_reloc_require_copy_reloc(struct ld *, struct ld_reloc_entry *); +int ld_reloc_require_dynamic_reloc(struct ld *, struct ld_reloc_entry *); +int ld_reloc_require_glob_dat(struct ld *, struct ld_reloc_entry *); +int ld_reloc_relative_relax(struct ld *, struct ld_reloc_entry *); +void *ld_reloc_serialize(struct ld *, struct ld_output_section *, size_t *); diff --git a/contrib/elftoolchain/ld/ld_script.awk b/contrib/elftoolchain/ld/ld_script.awk new file mode 100644 index 0000000000..12f2e3e5b7 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_script.awk @@ -0,0 +1,25 @@ +# Transform text file contents into a string literal. +# +# Usage: awk -f THIS-SCRIPT INPUT > OUTPUT +# +# $Id: ld_script.awk 3593 2018-04-11 18:26:20Z jkoshy $ + +BEGIN { + # Generate a symbol name based on the last component + # of the input file name. + split(ARGV[1], s, "."); + sub(".*/", "", s[1]); + printf "const char *%s = ", s[1]; +} + +# Enclose each line of text with a preceding and trailing '"', +# escaping any '"' characters that are present. +{ + printf "\""; + gsub("\"", "\\\""); + printf "%s\\n\"\n", $0; +} + +END { + print ";"; +} diff --git a/contrib/elftoolchain/ld/ld_script.c b/contrib/elftoolchain/ld/ld_script.c new file mode 100644 index 0000000000..685c47d35d --- /dev/null +++ b/contrib/elftoolchain/ld/ld_script.c @@ -0,0 +1,785 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_exp.h" +#include "ld_options.h" +#include "ld_script.h" +#include "ld_file.h" +#include "ld_symbols.h" +#include "ld_output.h" + +ELFTC_VCSID("$Id: ld_script.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); + +static void _input_file_add(struct ld *ld, struct ld_script_input_file *ldif); +static void _overlay_section_free(void *ptr); +static struct ld_script_variable *_variable_find(struct ld *ld, char *name); + +#define _variable_add(v) \ + HASH_ADD_KEYPTR(hh, ld->ld_scp->lds_v, (v)->ldv_name, \ + strlen((v)->ldv_name), (v)) + +struct ld_script_cmd * +ld_script_assert(struct ld *ld, struct ld_exp *exp, char *msg) +{ + struct ld_script_assert *a; + + if ((a = calloc(1, sizeof(*a))) == NULL) + ld_fatal_std(ld, "calloc"); + a->lda_exp = exp; + a->lda_msg = msg; + + return (ld_script_cmd(ld, LSC_ASSERT, a)); +} + +struct ld_script_assign * +ld_script_assign(struct ld *ld, struct ld_exp *var, enum ld_script_assign_op op, + struct ld_exp *val, unsigned provide, unsigned hidden) +{ + struct ld_script_assign *lda; + struct ld_script_variable *ldv; + + if ((lda = calloc(1, sizeof(*lda))) == NULL) + ld_fatal_std(ld, "calloc"); + + lda->lda_var = var; + lda->lda_op = op; + lda->lda_val = val; + lda->lda_provide = provide; + + if ((ldv = _variable_find(ld, var->le_name)) == NULL) { + ldv = calloc(1, sizeof(*ldv)); + if ((ldv->ldv_name = strdup(var->le_name)) == NULL) + ld_fatal_std(ld, "strdup"); + _variable_add(ldv); + if (*var->le_name != '.') + ld_symbols_add_variable(ld, ldv, provide, hidden); + } + + return (lda); +} + +void +ld_script_assign_dump(struct ld *ld, struct ld_script_assign *lda) +{ + + printf("%16s", ""); + printf("0x%016jx ", (uintmax_t) lda->lda_res); + + if (lda->lda_provide) + printf("PROVIDE("); + + ld_exp_dump(ld, lda->lda_var); + + switch (lda->lda_op) { + case LSAOP_ADD_E: + printf(" += "); + break; + case LSAOP_AND_E: + printf(" &= "); + break; + case LSAOP_DIV_E: + printf(" /= "); + break; + case LSAOP_E: + printf(" = "); + break; + case LSAOP_LSHIFT_E: + printf(" <<= "); + break; + case LSAOP_MUL_E: + printf(" *= "); + break; + case LSAOP_OR_E: + printf(" |= "); + break; + case LSAOP_RSHIFT_E: + printf(" >>= "); + break; + case LSAOP_SUB_E: + printf(" -= "); + break; + default: + ld_fatal(ld, "internal: unknown assignment op: %d", + lda->lda_op); + } + + ld_exp_dump(ld, lda->lda_val); + + if (lda->lda_provide) + printf(")"); + + printf("\n"); +} + +void +ld_script_assign_free(struct ld_script_assign *lda) +{ + + if (lda == NULL) + return; + ld_exp_free(lda->lda_var); + ld_exp_free(lda->lda_val); + free(lda); +} + +static void +_update_variable_section(struct ld *ld, struct ld_script_variable *ldv) +{ + struct ld_output_section *os, *last; + + if (ldv->ldv_os_base) { + /* Get base address of the section. */ + STAILQ_FOREACH(os, &ld->ld_output->lo_oslist, os_next) { + if (strcmp(os->os_name, ldv->ldv_os_base) == 0) { + ldv->ldv_base = os->os_addr; + ldv->ldv_os_ref = ldv->ldv_os_base; + ldv->ldv_os_base = 0; + break; + } + } + } + + if (ldv->ldv_os_ref) { + /* Bind the symbol to the last section. */ + last = 0; + STAILQ_FOREACH(os, &ld->ld_output->lo_oslist, os_next) { + if (! os->os_empty) + last = os; + if (strcmp(os->os_name, ldv->ldv_os_ref) == 0) { + if (last) { + ldv->ldv_symbol->lsb_shndx = elf_ndxscn(last->os_scn); + } + ldv->ldv_os_ref = 0; + break; + } + } + } +} + +void +ld_script_process_assign(struct ld *ld, struct ld_script_assign *lda) +{ + struct ld_state *ls; + struct ld_exp *var; + struct ld_script_variable *ldv; + + ls = &ld->ld_state; + var = lda->lda_var; + ldv = _variable_find(ld, var->le_name); + assert(ldv != NULL); + + ldv->ldv_val = ld_exp_eval(ld, lda->lda_val); + if (*var->le_name == '.') { + /* + * TODO: location counter is allowed to move backwards + * outside output section descriptor, as long as the + * move will not cause overlapping LMA's. + */ + if ((uint64_t) ldv->ldv_val < ls->ls_loc_counter) + ld_fatal(ld, "cannot move location counter backwards" + " from %#jx to %#jx", + (uintmax_t) ls->ls_loc_counter, + (uintmax_t) ldv->ldv_val); + ls->ls_loc_counter = (uint64_t) ldv->ldv_val; + + } else if (ldv->ldv_symbol != NULL) { + _update_variable_section(ld, ldv); + ldv->ldv_symbol->lsb_value = ldv->ldv_val + ldv->ldv_base; + } + lda->lda_res = ldv->ldv_val; +} + +void +ld_script_process_entry(struct ld *ld, char *name) +{ + + if (ld->ld_scp->lds_entry_point != NULL) { + free(ld->ld_scp->lds_entry_point); + ld->ld_scp->lds_entry_point = NULL; + } + + ld->ld_scp->lds_entry_point = strdup(name); + if (ld->ld_scp->lds_entry_point == NULL) + ld_fatal_std(ld, "strdup"); +} + +int64_t +ld_script_variable_value(struct ld *ld, char *name) +{ + struct ld_script_variable *ldv; + struct ld_state *ls; + + ls = &ld->ld_state; + if (*name == '.') + return (ls->ls_loc_counter); + + ldv = _variable_find(ld, name); + assert(ldv != NULL); + + return (ldv->ldv_val); +} + +struct ld_script_cmd * +ld_script_cmd(struct ld *ld, enum ld_script_cmd_type type, void *cmd) +{ + struct ld_script_cmd *ldc; + + if ((ldc = calloc(1, sizeof(*ldc))) == NULL) + ld_fatal_std(ld, "calloc"); + ldc->ldc_type = type; + ldc->ldc_cmd = cmd; + + return (ldc); +} + +void +ld_script_cmd_insert(struct ld_script_cmd_head *head, struct ld_script_cmd *ldc) +{ + + STAILQ_INSERT_TAIL(head, ldc, ldc_next); +} + +static void +_overlay_section_free(void *ptr) +{ + struct ld_script_cmd *c, *_c; + struct ld_script_sections_overlay_section *ldos; + + ldos = ptr; + if (ldos == NULL) + return; + free(ldos->ldos_name); + ld_script_list_free(ldos->ldos_phdr, free); + ld_exp_free(ldos->ldos_fill); + STAILQ_FOREACH_SAFE(c, &ldos->ldos_c, ldc_next, _c) { + STAILQ_REMOVE(&ldos->ldos_c, c, ld_script_cmd, ldc_next); + ld_script_cmd_free(c); + } + free(ldos); +} + +void +ld_script_cmd_free(struct ld_script_cmd *ldc) +{ + struct ld_script_cmd *c, *_c; + struct ld_script_assert *lda; + struct ld_script_sections *ldss; + struct ld_script_sections_output *ldso; + struct ld_script_sections_output_data *ldod; + struct ld_script_sections_output_input *ldoi; + struct ld_script_sections_overlay *ldso2; + + switch (ldc->ldc_type) { + case LSC_ASSERT: + lda = ldc->ldc_cmd; + ld_exp_free(lda->lda_exp); + free(lda->lda_msg); + free(lda); + break; + + case LSC_ASSIGN: + ld_script_assign_free(ldc->ldc_cmd); + break; + + case LSC_ENTRY: + free(ldc->ldc_cmd); + break; + + case LSC_SECTIONS: + ldss = ldc->ldc_cmd; + STAILQ_FOREACH_SAFE(c, &ldss->ldss_c, ldc_next, _c) { + STAILQ_REMOVE(&ldss->ldss_c, c, ld_script_cmd, + ldc_next); + ld_script_cmd_free(c); + } + free(ldss); + break; + + case LSC_SECTIONS_OUTPUT: + ldso = ldc->ldc_cmd; + free(ldso->ldso_name); + free(ldso->ldso_type); + ld_exp_free(ldso->ldso_vma); + ld_exp_free(ldso->ldso_lma); + ld_exp_free(ldso->ldso_align); + ld_exp_free(ldso->ldso_subalign); + free(ldso->ldso_constraint); + free(ldso->ldso_region); + free(ldso->ldso_lma_region); + ld_script_list_free(ldso->ldso_phdr, free); + ld_exp_free(ldso->ldso_fill); + STAILQ_FOREACH_SAFE(c, &ldso->ldso_c, ldc_next, _c) { + STAILQ_REMOVE(&ldso->ldso_c, c, ld_script_cmd, + ldc_next); + ld_script_cmd_free(c); + } + free(ldso); + break; + + case LSC_SECTIONS_OUTPUT_DATA: + ldod = ldc->ldc_cmd; + ld_exp_free(ldod->ldod_exp); + free(ldod); + break; + + case LSC_SECTIONS_OUTPUT_INPUT: + ldoi = ldc->ldc_cmd; + ld_wildcard_free(ldoi->ldoi_ar); + ld_wildcard_free(ldoi->ldoi_file); + ld_script_list_free(ldoi->ldoi_exclude, ld_wildcard_free); + ld_script_list_free(ldoi->ldoi_sec, ld_wildcard_free); + free(ldoi); + break; + + case LSC_SECTIONS_OVERLAY: + ldso2 = ldc->ldc_cmd; + ld_exp_free(ldso2->ldso_vma); + ld_exp_free(ldso2->ldso_lma); + free(ldso2->ldso_region); + ld_script_list_free(ldso2->ldso_phdr, free); + ld_exp_free(ldso2->ldso_fill); + ld_script_list_free(ldso2->ldso_s, _overlay_section_free); + free(ldso2); + break; + + default: + break; + } + + free(ldc); +} + +void +ld_script_extern(struct ld *ld, struct ld_script_list *list) +{ + struct ld_script_list *ldl; + + ldl = list; + while (ldl != NULL) { + ld_symbols_add_extern(ld, ldl->ldl_entry); + ldl = ldl->ldl_next; + } + ld_script_list_free(list, free); +} + +void +ld_script_group(struct ld *ld, struct ld_script_list *list) +{ + struct ld_script_list *ldl; + + ld->ld_state.ls_group_level++; + if (ld->ld_state.ls_group_level > LD_MAX_NESTED_GROUP) + ld_fatal(ld, "too many nested archive groups"); + ldl = list; + while (ldl != NULL) { + _input_file_add(ld, ldl->ldl_entry); + ldl = ldl->ldl_next; + } + ld->ld_state.ls_group_level--; + ld_script_list_free(list, free); +} + +void +ld_script_init(struct ld *ld) +{ + + ld->ld_scp = calloc(1, sizeof(*ld->ld_scp)); + if (ld->ld_scp == NULL) + ld_fatal_std(ld, "calloc"); + + STAILQ_INIT(&ld->ld_scp->lds_a); + STAILQ_INIT(&ld->ld_scp->lds_c); + STAILQ_INIT(&ld->ld_scp->lds_n); + STAILQ_INIT(&ld->ld_scp->lds_p); + STAILQ_INIT(&ld->ld_scp->lds_r); + STAILQ_INIT(&ld->ld_scp->lds_vn); + + ld_script_parse_internal(); +} + +void +ld_script_cleanup(struct ld *ld) +{ + struct ld_script *lds; + struct ld_script_phdr *p, *_p; + struct ld_script_region *r, *_r; + struct ld_script_region_alias *a, *_a; + struct ld_script_nocrossref *n, *_n; + struct ld_script_cmd *c, *_c; + struct ld_script_variable *v, *_v; + + if (ld->ld_scp == NULL) + return; + + lds = ld->ld_scp; + + if (lds->lds_entry_point != NULL) { + free(lds->lds_entry_point); + lds->lds_entry_point = NULL; + } + + STAILQ_FOREACH_SAFE(p, &lds->lds_p, ldsp_next, _p) { + STAILQ_REMOVE(&lds->lds_p, p, ld_script_phdr, ldsp_next); + free(p->ldsp_name); + free(p->ldsp_type); + ld_exp_free(p->ldsp_addr); + free(p); + } + + STAILQ_FOREACH_SAFE(r, &lds->lds_r, ldsr_next, _r) { + STAILQ_REMOVE(&lds->lds_r, r, ld_script_region, ldsr_next); + free(r->ldsr_name); + free(r->ldsr_attr); + ld_exp_free(r->ldsr_origin); + ld_exp_free(r->ldsr_len); + free(r); + } + + STAILQ_FOREACH_SAFE(a, &lds->lds_a, ldra_next, _a) { + STAILQ_REMOVE(&lds->lds_a, a, ld_script_region_alias, + ldra_next); + free(a->ldra_alias); + free(a->ldra_region); + free(a); + } + + STAILQ_FOREACH_SAFE(n, &lds->lds_n, ldn_next, _n) { + STAILQ_REMOVE(&lds->lds_n, n, ld_script_nocrossref, ldn_next); + ld_script_list_free(n->ldn_l, free); + free(n); + } + + STAILQ_FOREACH_SAFE(c, &lds->lds_c, ldc_next, _c) { + STAILQ_REMOVE(&lds->lds_c, c, ld_script_cmd, ldc_next); + ld_script_cmd_free(c); + } + + if (lds->lds_v != NULL) { + HASH_ITER(hh, lds->lds_v, v, _v) { + HASH_DEL(lds->lds_v, v); + free(v->ldv_name); + free(v); + } + lds->lds_v = NULL; + } +} + +void +ld_script_input(struct ld *ld, struct ld_script_list *list) +{ + struct ld_script_list *ldl; + + ld->ld_state.ls_search_dir = 1; + ldl = list; + while (ldl != NULL) { + _input_file_add(ld, ldl->ldl_entry); + ldl = ldl->ldl_next; + } + ld->ld_state.ls_search_dir = 0; + ld_script_list_free(list, free); +} + +struct ld_script_input_file * +ld_script_input_file(struct ld *ld, unsigned as_needed, void *in) +{ + struct ld_script_input_file *ldif; + + if ((ldif = calloc(1, sizeof(*ldif))) == NULL) + ld_fatal_std(ld, "calloc"); + ldif->ldif_as_needed = as_needed; + if (as_needed) + ldif->ldif_u.ldif_ldl = in; + else + ldif->ldif_u.ldif_name = in; + + return (ldif); +} + +struct ld_script_list * +ld_script_list(struct ld *ld, struct ld_script_list *list, void *entry) +{ + struct ld_script_list *ldl; + + if ((ldl = malloc(sizeof(*ldl))) == NULL) + ld_fatal_std(ld, "malloc"); + ldl->ldl_entry = entry; + ldl->ldl_next = list; + + return (ldl); +} + +void +ld_script_list_free(struct ld_script_list *list, void (*_free)(void *ptr)) +{ + struct ld_script_list *ldl; + + if (list == NULL) + return; + + do { + ldl = list; + list = ldl->ldl_next; + if (ldl->ldl_entry) + _free(ldl->ldl_entry); + free(ldl); + } while (list != NULL); +} + +struct ld_script_list * +ld_script_list_reverse(struct ld_script_list *list) +{ + struct ld_script_list *root, *next; + + root = NULL; + while (list != NULL) { + next = list->ldl_next; + list->ldl_next = root; + root = list; + list = next; + } + + return (root); +} + +void +ld_script_nocrossrefs(struct ld *ld, struct ld_script_list *list) +{ + struct ld_script_nocrossref *ldn; + + if ((ldn = calloc(1, sizeof(*ldn))) == NULL) + ld_fatal_std(ld, "calloc"); + ldn->ldn_l = list; + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_n, ldn, ldn_next); +} + +struct ld_script_phdr * +ld_script_phdr(struct ld *ld, char *name, char *type, unsigned filehdr, + unsigned phdrs, struct ld_exp *addr, unsigned flags) +{ + struct ld_script_phdr *ldsp; + + if ((ldsp = calloc(1, sizeof(*ldsp))) == NULL) + ld_fatal_std(ld, "calloc"); + + ldsp->ldsp_name = name; + ldsp->ldsp_type = type; + ldsp->ldsp_filehdr = filehdr; + ldsp->ldsp_phdrs = phdrs; + ldsp->ldsp_addr = addr; + ldsp->ldsp_flags = flags; + + return (ldsp); +} + +struct ld_script_region * +ld_script_region(struct ld *ld, char *name, char *attr, struct ld_exp *origin, + struct ld_exp *len) +{ + struct ld_script_region *ldsr; + + if ((ldsr = malloc(sizeof(*ldsr))) == NULL) + ld_fatal_std(ld, "malloc"); + + ldsr->ldsr_name = name; + ldsr->ldsr_attr = attr; + ldsr->ldsr_origin = origin; + ldsr->ldsr_len = len; + + return (ldsr); +} + +void +ld_script_region_alias(struct ld *ld, char *alias, char *region) +{ + struct ld_script_region_alias *ldra; + + if ((ldra = calloc(1, sizeof(*ldra))) == NULL) + ld_fatal_std(ld, "calloc"); + + ldra->ldra_alias = alias; + ldra->ldra_region = region; + + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_a, ldra, ldra_next); +} + +void +ld_script_version_add_node(struct ld *ld, char *ver, void *head, char *depend) +{ + struct ld_script_version_node *ldvn; + + if ((ldvn = calloc(1, sizeof(*ldvn))) == NULL) + ld_fatal_std(ld, "calloc"); + + ldvn->ldvn_name = ver; + if (ldvn->ldvn_name == NULL) { + /* + * Version name can be omitted only when this is the only + * node in the version script. + */ + if (ld->ld_scp->lds_vn_name_omitted || + !STAILQ_EMPTY(&ld->ld_scp->lds_vn)) + ld_fatal(ld, "version script can only have one " + "version node that is without a version name"); + ld->ld_scp->lds_vn_name_omitted = 1; + } + + ldvn->ldvn_dep = depend; + ldvn->ldvn_e = head; + + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_vn, ldvn, ldvn_next); +} + +struct ld_script_version_entry * +ld_script_version_alloc_entry(struct ld *ld, char *sym, void *extern_block) +{ + struct ld_state *ls; + struct ld_script_version_entry *ldve; + int ignore; + char *p; + + ls = &ld->ld_state; + + if ((ldve = calloc(1, sizeof(*ldve))) == NULL) + ld_fatal_std(ld, "calloc"); + + ldve->ldve_sym = sym; + ldve->ldve_local = ls->ls_version_local; + ldve->ldve_list = extern_block; + + if (ldve->ldve_sym == NULL) + return (ldve); + + ignore = 0; + for (p = ldve->ldve_sym; *p != '\0'; p++) { + switch (*p) { + case '\\': + /* Ignore the next char */ + ignore = 1; + break; + case '?': + case '*': + case '[': + if (!ignore) { + ldve->ldve_glob = 1; + goto done; + } else + ignore = 0; + } + } + +done: + return (ldve); +} + +void * +ld_script_version_link_entry(struct ld *ld, + struct ld_script_version_entry_head *head, + struct ld_script_version_entry *ldve) +{ + + if (ldve == NULL) + return (head); + + if (head == NULL) { + if ((head = calloc(1, sizeof(*head))) == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(head); + } + + if (ldve->ldve_list != NULL) { + STAILQ_CONCAT(head, ldve->ldve_list); + free(ldve->ldve_list); + free(ldve); + } else + STAILQ_INSERT_TAIL(head, ldve, ldve_next); + + return (head); +} + +void +ld_script_version_set_lang(struct ld * ld, + struct ld_script_version_entry_head *head, char *lang) +{ + struct ld_script_version_entry *ldve; + enum ld_script_version_lang vl; + + vl = VL_C; + + if (!strcasecmp(lang, "c")) + vl = VL_C; + else if (!strcasecmp(lang, "c++")) + vl = VL_CPP; + else if (!strcasecmp(lang, "java")) + vl = VL_JAVA; + else + ld_warn(ld, "unrecognized language `%s' in version script", + lang); + + STAILQ_FOREACH(ldve, head, ldve_next) { + /* Do not overwrite lang set by inner extern blocks. */ + if (!ldve->ldve_lang_set) { + ldve->ldve_lang = vl; + ldve->ldve_lang_set = 1; + } + } +} + + +static void +_input_file_add(struct ld *ld, struct ld_script_input_file *ldif) +{ + struct ld_state *ls; + struct ld_script_list *ldl; + unsigned old_as_needed; + + ls = &ld->ld_state; + + if (!ldif->ldif_as_needed) { + ld_file_add(ld, ldif->ldif_u.ldif_name, LFT_UNKNOWN); + free(ldif->ldif_u.ldif_name); + } else { + old_as_needed = ls->ls_as_needed; + ls->ls_as_needed = 1; + ldl = ldif->ldif_u.ldif_ldl; + while (ldl != NULL) { + ld_file_add(ld, ldl->ldl_entry, LFT_UNKNOWN); + ldl = ldl->ldl_next; + } + ls->ls_as_needed = old_as_needed; + ld_script_list_free(ldif->ldif_u.ldif_ldl, free); + } +} + +static struct ld_script_variable * +_variable_find(struct ld *ld, char *name) +{ + struct ld_script_variable *ldv; + + HASH_FIND_STR(ld->ld_scp->lds_v, name, ldv); + + return (ldv); +} diff --git a/contrib/elftoolchain/ld/ld_script.h b/contrib/elftoolchain/ld/ld_script.h new file mode 100644 index 0000000000..1de4ce0353 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_script.h @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_script.h 3281 2015-12-11 21:39:23Z kaiwang27 $ + */ + +enum ld_script_cmd_type { + LSC_ASSERT, + LSC_ASSIGN, + LSC_AS_NEEDED, + LSC_ENTRY, + LSC_EXTERN, + LSC_FCA, + LSC_HIDDEN_ASSIGN, + LSC_ICA, + LSC_INPUT, + LSC_MEMORY, + LSC_NOCROSSREFS, + LSC_OUTPUT, + LSC_OUTPUT_ARCH, + LSC_OUTPUT_FORMAT, + LSC_PHDRS, + LSC_PROVIDE_ASSIGN, + LSC_REGION_ALIAS, + LSC_SEARCH_DIR, + LSC_SECTIONS, + LSC_SECTIONS_OUTPUT, + LSC_SECTIONS_OUTPUT_DATA, + LSC_SECTIONS_OUTPUT_INPUT, + LSC_SECTIONS_OUTPUT_KEYWORD, + LSC_SECTIONS_OVERLAY, + LSC_STARTUP, + LSC_TARGET, + LSC_VERSION, +}; + +struct ld_script_cmd { + enum ld_script_cmd_type ldc_type; /* ldscript cmd type */ + void *ldc_cmd; /* ldscript cmd */ + STAILQ_ENTRY(ld_script_cmd) ldc_next; /* next cmd */ +}; + +STAILQ_HEAD(ld_script_cmd_head, ld_script_cmd); + +struct ld_script_list { + void *ldl_entry; /* list entry */ + struct ld_script_list *ldl_next; /* next entry */ +}; + +struct ld_script_assert { + struct ld_exp *lda_exp; /* expression to assert */ + char *lda_msg; /* assertion message */ +}; + +enum ld_script_assign_op { + LSAOP_ADD_E, + LSAOP_AND_E, + LSAOP_DIV_E, + LSAOP_E, + LSAOP_LSHIFT_E, + LSAOP_MUL_E, + LSAOP_OR_E, + LSAOP_RSHIFT_E, + LSAOP_SUB_E, +}; + +struct ld_script_assign { + struct ld_exp *lda_var; /* symbol */ + struct ld_exp *lda_val; /* value */ + enum ld_script_assign_op lda_op; /* assign op */ + unsigned lda_provide; /* provide assign */ + int64_t lda_res; /* assign result */ +}; + +struct ld_script_input_file { + unsigned ldif_as_needed; /* as_needed list */ + union { + char *ldif_name; /* input file name */ + struct ld_script_list *ldif_ldl; /* input file list */ + } ldif_u; +}; + +struct ld_script_nocrossref { + struct ld_script_list *ldn_l; /* nocrossref sections */ + STAILQ_ENTRY(ld_script_nocrossref) ldn_next; /* next nocrossref */ +}; + +struct ld_script_region { + char *ldsr_name; /* memory region name */ + char *ldsr_attr; /* memory region attribute */ + struct ld_exp *ldsr_origin; /* memroy region start address */ + struct ld_exp *ldsr_len; /* memroy region length */ + STAILQ_ENTRY(ld_script_region) ldsr_next; /* next memory region */ +}; + +struct ld_script_region_alias { + char *ldra_alias; /* memory region alias name */ + char *ldra_region; /* memory region */ + STAILQ_ENTRY(ld_script_region_alias) ldra_next; /* next region alias */ +}; + +struct ld_script_phdr { + char *ldsp_name; /* phdr name */ + char *ldsp_type; /* phdr type */ + unsigned ldsp_filehdr; /* FILEHDR keyword */ + unsigned ldsp_phdrs; /* PHDRS keyword */ + struct ld_exp *ldsp_addr; /* segment address */ + unsigned ldsp_flags; /* segment flags */ + STAILQ_ENTRY(ld_script_phdr) ldsp_next; /* next phdr */ +}; + +enum ld_script_sections_output_data_type { + LSODT_BYTE, + LSODT_SHORT, + LSODT_LONG, + LSODT_QUAD, + LSODT_SQUAD, + LSODT_FILL, +}; + +struct ld_script_sections_output_data { + enum ld_script_sections_output_data_type ldod_type; /* data type */ + struct ld_exp *ldod_exp; /* data expression */ +}; + +struct ld_script_sections_output_input { + struct ld_wildcard *ldoi_ar; /* archive name */ + struct ld_wildcard *ldoi_file; /* file/member name */ + struct ld_script_list *ldoi_exclude; /* exclude file list */ + struct ld_script_list *ldoi_sec; /* section name list */ + unsigned ldoi_flags; /* input section flags */ + unsigned ldoi_keep; /* keep input section */ +}; + +enum ld_script_sections_output_keywords { + LSOK_CONSTRUCTORS, + LSOK_CONSTRUCTORS_SORT_BY_NAME, + LSOK_CREATE_OBJECT_SYMBOLS, +}; + +struct ld_script_sections_output { + char *ldso_name; /* output section name */ + char *ldso_type; /* output section type */ + struct ld_exp *ldso_vma; /* output section vma */ + struct ld_exp *ldso_lma; /* output section lma */ + struct ld_exp *ldso_align; /* output section align */ + struct ld_exp *ldso_subalign; /* output sectino subalign */ + char *ldso_constraint; /* output section constraint */ + char *ldso_region; /* output section region */ + char *ldso_lma_region; /* output section lma region */ + struct ld_script_list *ldso_phdr; /* output section segment list */ + struct ld_exp *ldso_fill; /* output section fill exp */ + struct ld_script_cmd_head ldso_c; /* output section cmd list */ +}; + +struct ld_script_sections_overlay_section { + char *ldos_name; /* overlay section name */ + struct ld_script_list *ldos_phdr; /* overlay section segment */ + struct ld_exp *ldos_fill; /* overlay section fill exp */ + struct ld_script_cmd_head ldos_c; /* output section cmd list */ +}; + +struct ld_script_sections_overlay { + struct ld_exp *ldso_vma; /* overlay vma */ + struct ld_exp *ldso_lma; /* overlay lma */ + unsigned ldso_nocrossref; /* no corss-ref between sections */ + char *ldso_region; /* overlay region */ + struct ld_script_list *ldso_phdr; /* overlay segment */ + struct ld_exp *ldso_fill; /* overlay fill exp */ + struct ld_script_list *ldso_s; /* overlay section list */ +}; + +struct ld_script_sections { + struct ld_script_cmd_head ldss_c; /* section cmd list */ +}; + +struct ld_script_variable { + char *ldv_name; /* variable name */ + char *ldv_os_base; /* add base address of this section */ + char *ldv_os_ref; /* link symbol to this section */ + struct ld_symbol *ldv_symbol; /* assoicated symbol */ + int64_t ldv_val; /* variable value */ + int64_t ldv_base; /* base value */ + UT_hash_handle hh; /* hash handle */ +}; + +enum ld_script_version_lang { + VL_C = 0, + VL_CPP, + VL_JAVA +}; + +struct ld_script_version_entry_head; + +struct ld_script_version_entry { + enum ld_script_version_lang ldve_lang; /* version entry lanauage */ + char *ldve_sym; /* symbol wildcard */ + unsigned char ldve_local; /* symbol scope */ + unsigned char ldve_glob; /* ldve_sym contains glob chars. */ + STAILQ_ENTRY(ld_script_version_entry) ldve_next; + + /* Following fields are only used during script parsing. */ + struct ld_script_version_entry_head *ldve_list; /* extern block */ + unsigned char ldve_lang_set; /* lang is set */ +}; + +STAILQ_HEAD(ld_script_version_entry_head, ld_script_version_entry); + +struct ld_script_version_node { + char *ldvn_name; /* version name */ + char *ldvn_dep; /* version dependency */ + struct ld_script_version_entry_head *ldvn_e; /* version entries */ + STAILQ_ENTRY(ld_script_version_node) ldvn_next; +}; + +struct ld_script { + char *lds_entry_point; /* entry point symbol */ + STAILQ_HEAD(, ld_script_phdr) lds_p; /* phdr table */ + STAILQ_HEAD(, ld_script_region_alias) lds_a; /* region aliases list */ + STAILQ_HEAD(, ld_script_region) lds_r; /* memory region list */ + STAILQ_HEAD(, ld_script_nocrossref) lds_n; /* nocrossref list */ + STAILQ_HEAD(, ld_script_version_node) lds_vn; /* version node list */ + unsigned char lds_vn_name_omitted; /* version node w/o name exists */ + struct ld_script_cmd_head lds_c; /* other ldscript cmd list */ + struct ld_script_variable *lds_v; /* variable table */ + char *lds_last_os_name; /* last output section */ + char *lds_base_os_name; /* current output section */ +}; + +struct ld_script_cmd *ld_script_assert(struct ld *, struct ld_exp *, char *); +struct ld_script_assign *ld_script_assign(struct ld *, struct ld_exp *, + enum ld_script_assign_op, struct ld_exp *, unsigned, unsigned); +void ld_script_assign_dump(struct ld *, struct ld_script_assign *); +void ld_script_assign_free(struct ld_script_assign *); +void ld_script_cleanup(struct ld *); +struct ld_script_cmd *ld_script_cmd(struct ld *, enum ld_script_cmd_type, + void *); +void ld_script_cmd_free(struct ld_script_cmd *); +void ld_script_cmd_insert(struct ld_script_cmd_head *, + struct ld_script_cmd *); +void ld_script_extern(struct ld *, struct ld_script_list *); +void ld_script_group(struct ld *, struct ld_script_list *); +void ld_script_init(struct ld *); +void ld_script_input(struct ld *, struct ld_script_list *); +struct ld_script_input_file *ld_script_input_file(struct ld *, unsigned, + void *); +struct ld_script_list *ld_script_list(struct ld *, struct ld_script_list *, + void *); +void ld_script_list_free(struct ld_script_list *, void (*)(void *)); +struct ld_script_list *ld_script_list_reverse(struct ld_script_list *); +void ld_script_nocrossrefs(struct ld *, struct ld_script_list *); +struct ld_script_phdr *ld_script_phdr(struct ld *, char *, char *, unsigned, + unsigned, struct ld_exp *, unsigned); +void ld_script_parse(const char *); +void ld_script_parse_internal(void); +struct ld_script_region *ld_script_region(struct ld *, char *, char *, + struct ld_exp *, struct ld_exp *); +void ld_script_process_assign(struct ld *, struct ld_script_assign *); +void ld_script_process_entry(struct ld *, char *); +void ld_script_region_alias(struct ld *, char *, char *); +int64_t ld_script_variable_value(struct ld *, char *); +void ld_script_version_add_node(struct ld *, char *, void *, char *); +struct ld_script_version_entry *ld_script_version_alloc_entry(struct ld *, + char *, void *); +void *ld_script_version_link_entry(struct ld *, + struct ld_script_version_entry_head *, struct ld_script_version_entry *); +void ld_script_version_set_lang(struct ld *, + struct ld_script_version_entry_head *, char *); diff --git a/contrib/elftoolchain/ld/ld_script_lexer.l b/contrib/elftoolchain/ld/ld_script_lexer.l new file mode 100644 index 0000000000..f516da33a6 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_script_lexer.l @@ -0,0 +1,265 @@ +%{ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_script_parser.h" + +ELFTC_VCSID("$Id: ld_script_lexer.l 3385 2016-01-31 14:26:26Z jkoshy $"); + +#define YY_NO_UNPUT +int lineno = 1; + +int yylex(void); + +static void _calc_num(void); +static void _get_string(void); +static void _get_ident(void); +static void _skip_comment(void); + +%} + +DEC [0-9]+[kKmMdD]? +OCT (0[0-7]*+[kKmM]?)|([0-7]+[oO]) +HEX (0[xX][0-9a-fA-F]+[kKmMhH]?)|([0-9a-fA-F]+[hH]) +IDENT [-_A-Za-z/:$.\\~][-_A-Za-z/:$.\\~0-9]* +WILDCARD [-_A-Za-z/:$.\\~0-9\[\]?*]+ +MATTR \(!?[rRwWxXaAiIlL]+\) + +%option noyywrap +%option never-interactive +%option nounput + +%% + +ABSOLUTE { return (T_ABSOLUTE); } +ADDR { return (T_ADDR); } +ALIGN { return (T_ALIGN); } +ALIGNOF { return (T_ALIGNOF); } +ASSERT { return (T_ASSERT); } +AS_NEEDED { return (T_AS_NEEDED); } +AT { return (T_AT); } +BIND { return (T_BIND); } +BLOCK { return (T_BLOCK); } +BYTE { return (T_BYTE); } +COMMONPAGESIZE { _get_ident(); return (T_COMMONPAGESIZE); } +CONSTANT { return (T_CONSTANT); } +CONSTRUCTORS { return (T_CONSTRUCTORS); } +COPY { return (T_COPY); } +CREATE_OBJECT_SYMBOLS { return (T_CREATE_OBJECT_SYMBOLS); } +DATA_SEGMENT_ALIGN { return (T_DATA_SEGMENT_ALIGN); } +DATA_SEGMENT_END { return (T_DATA_SEGMENT_END); } +DATA_SEGMENT_RELRO_END { return (T_DATA_SEGMENT_RELRO_END); } +DEFINED { return (T_DEFINED); } +DSECT { return (T_DSECT); } +ENTRY { return (T_ENTRY); } +EXCLUDE_FILE { return (T_EXCLUDE_FILE); } +EXTERN { return (T_EXTERN); } +FILEHDR { return (T_FILEHDR); } +FILL { return (T_FILL); } +FLAGS { return (T_FLAGS); } +FLOAT { return (T_FLOAT); } +FORCE_COMMON_ALLOCATION { return (T_FORCE_COMMON_ALLOCATION); } +GROUP { return (T_GROUP); } +HLL { return (T_HLL); } +INCLUDE { return (T_INCLUDE); } +INFO { return (T_INFO); } +INHIBIT_COMMON_ALLOCATION { return (T_INHIBIT_COMMON_ALLOCATION); } +INPUT { return (T_INPUT); } +KEEP { return (T_KEEP); } +LENGTH { return (T_LENGTH); } +LOADADDR { return (T_LOADADDR); } +LONG { return (T_LONG); } +MAP { return (T_MAP); } +MAX { return (T_MAX); } +MAXPAGESIZE { _get_ident(); return (T_MAXPAGESIZE); } +MEMORY { return (T_MEMORY); } +MIN { return (T_MIN); } +NEXT { return (T_NEXT); } +NOCROSSREFS { return (T_NOCROSSREFS); } +NOFLOAT { return (T_NOFLOAT); } +NOLOAD { return (T_NOLOAD); } +ONLY_IF_RO { return (T_ONLY_IF_RO); } +ONLY_IF_RW { return (T_ONLY_IF_RW); } +OPTION { return (T_OPTION); } +ORIGIN { return (T_ORIGIN); } +OUTPUT { return (T_OUTPUT); } +OUTPUT_ARCH { return (T_OUTPUT_ARCH); } +OUTPUT_FORMAT { return (T_OUTPUT_FORMAT); } +OVERLAY { return (T_OVERLAY); } +PHDRS { return (T_PHDRS); } +PROVIDE { return (T_PROVIDE); } +PROVIDE_HIDDEN { return (T_PROVIDE_HIDDEN); } +QUAD { return (T_QUAD); } +REGION_ALIAS { return (T_REGION_ALIAS); } +SEARCH_DIR { return (T_SEARCH_DIR); } +SECTIONS { return (T_SECTIONS); } +SEGMENT_START { return (T_SEGMENT_START); } +SHORT { return (T_SHORT); } +SIZEOF { return (T_SIZEOF); } +SIZEOF_HEADERS { return (T_SIZEOF_HEADERS); } +SORT { return (T_SORT_BY_NAME); } +SORT_BY_ALIGNMENT { return (T_SORT_BY_ALIGNMENT); } +SORT_BY_NAME { return (T_SORT_BY_NAME); } +SPECIAL { return (T_SPECIAL); } +SQUAD { return (T_SQUAD); } +STARTUP { return (T_STARTUP); } +SUBALIGN { return (T_SUBALIGN); } +SYSLIB { return (T_SYSLIB); } +TARGET { return (T_TARGET); } +TRUNCATE { return (T_TRUNCATE); } +extern { return (T_VER_EXTERN); } +global: { return (T_VER_GLOBAL); } +l { return (T_LENGTH); } +len { return (T_LENGTH); } +local: { return (T_VER_LOCAL); } +o { return (T_ORIGIN); } +org { return (T_ORIGIN); } +sizeof_headers { return (T_SIZEOF_HEADERS); } +"/*" { _skip_comment(); } +"\""[^\"]+"\"" { _get_string(); return (T_STRING); } +{DEC}|{OCT}|{HEX} { _calc_num(); return (T_NUM); } +"<<=" { return (T_LSHIFT_E); } +">>=" { return (T_RSHIFT_E); } +"<<" { return (T_LSHIFT); } +">>" { return (T_RSHIFT); } +"==" { return (T_EQ); } +"!=" { return (T_NE); } +">=" { return (T_GE); } +"<=" { return (T_LE); } +"+=" { return (T_ADD_E); } +"-=" { return (T_SUB_E); } +"*=" { return (T_MUL_E); } +"/=" { return (T_DIV_E); } +"&=" { return (T_AND_E); } +"|=" { return (T_OR_E); } +"&&" { return (T_LOGICAL_AND); } +"||" { return (T_LOGICAL_OR); } +"!" { return ('!'); } +"{" { return ('{'); } +"}" { return ('}'); } +"[" { return ('['); } +"]" { return (']'); } +"(" { return ('('); } +")" { return (')'); } +"?" { return ('?'); } +":" { return (':'); } +";" { return (';'); } +"&" { return ('&'); } +"|" { return ('|'); } +"~" { return ('~'); } +"+" { return ('+'); } +"-" { return ('-'); } +"*" { return ('*'); } +"/" { return ('/'); } +"%" { return ('%'); } +"=" { return ('='); } +"<" { return ('<'); } +">" { return ('>'); } +"," { return (','); } +"." { return ('.'); } +{MATTR} { _get_ident(); return (T_MEMORY_ATTR); } +{IDENT} { _get_ident(); return (T_IDENT); } +{WILDCARD} { _get_ident(); return (T_WILDCARD); } +"\n" { lineno++; } +[ \t] /* Ignore whitespaces. */ + +%% + +static void +_calc_num(void) +{ + int base, mul; + + base = 0; + mul = 1; + switch (yytext[yyleng - 1]) { + case 'd': case 'D': + base = 10; + break; + case 'o': case 'O': + base = 8; + break; + case 'h': case 'H': + base = 16; + break; + case 'k': case 'K': + mul = 1024; + break; + case 'm': case 'M': + mul = 1024 * 1024; + break; + default: + break; + } + + if (base || mul > 1) + yytext[yyleng - 1] = '\0'; + + yylval.num = strtoimax(yytext, NULL, base); + yylval.num *= mul; +} + +static void +_get_ident(void) +{ + + yylval.str = strdup(yytext); + if (yylval.str == NULL) + err(1, "strdup"); +} + +static void +_get_string(void) +{ + + yytext[yyleng - 1] = '\0'; + yylval.str = strdup(yytext + 1); + if (yylval.str == NULL) + err(1, "strdup"); +} + +static void +_skip_comment(void) +{ + int c; + + for (;;) { + while ((c = input()) != '*' && c != EOF) + if (c == '\n') + lineno++; + if (c == '*') { + while ((c = input()) == '*') + ; + if (c == '\n') + lineno++; + if (c == '/') + break; + } + if (c == EOF) + errx(1, "lexer: EOF in comment"); + } +} diff --git a/contrib/elftoolchain/ld/ld_script_parser.y b/contrib/elftoolchain/ld/ld_script_parser.y new file mode 100644 index 0000000000..71c9131457 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_script_parser.y @@ -0,0 +1,1232 @@ +%{ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_options.h" +#include "ld_output.h" +#include "ld_script.h" +#include "ld_file.h" +#include "ld_path.h" +#include "ld_exp.h" + +ELFTC_VCSID("$Id: ld_script_parser.y 3281 2015-12-11 21:39:23Z kaiwang27 $"); + +struct yy_buffer_state; +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +extern int yylex(void); +extern int yyparse(void); +extern YY_BUFFER_STATE yy_create_buffer(FILE *file, int size); +extern YY_BUFFER_STATE yy_scan_string(char *yy_str); +extern void yy_switch_to_buffer(YY_BUFFER_STATE b); +extern void yy_delete_buffer(YY_BUFFER_STATE b); +extern int lineno; +extern FILE *yyin; +extern struct ld *ld; + +static void yyerror(const char *s); +static void _init_script(void); +static struct ld_script_cmd_head ldss_c, ldso_c; + +%} + +%token T_ABSOLUTE +%token T_ADDR +%token T_ALIGN +%token T_ALIGNOF +%token T_ASSERT +%token T_AS_NEEDED +%token T_AT +%token T_BIND +%token T_BLOCK +%token T_BYTE +%token T_CONSTANT +%token T_CONSTRUCTORS +%token T_CREATE_OBJECT_SYMBOLS +%token T_DATA_SEGMENT_ALIGN +%token T_DATA_SEGMENT_END +%token T_DATA_SEGMENT_RELRO_END +%token T_DEFINED +%token T_ENTRY +%token T_EXCLUDE_FILE +%token T_EXTERN +%token T_FILEHDR +%token T_FILL +%token T_FLAGS +%token T_FLOAT +%token T_FORCE_COMMON_ALLOCATION +%token T_GROUP +%token T_HLL +%token T_INCLUDE +%token T_INHIBIT_COMMON_ALLOCATION +%token T_INPUT +%token T_KEEP +%token T_LENGTH +%token T_LOADADDR +%token T_LONG +%token T_MAP +%token T_MAX +%token T_MEMORY +%token T_MIN +%token T_NEXT +%token T_NOCROSSREFS +%token T_NOFLOAT +%token T_OPTION +%token T_ORIGIN +%token T_OUTPUT +%token T_OUTPUT_ARCH +%token T_OUTPUT_FORMAT +%token T_PHDRS +%token T_PROVIDE +%token T_PROVIDE_HIDDEN +%token T_QUAD +%token T_REGION_ALIAS +%token T_SEARCH_DIR +%token T_SECTIONS +%token T_SEGMENT_START +%token T_SHORT +%token T_SIZEOF +%token T_SIZEOF_HEADERS +%token T_SORT_BY_ALIGNMENT +%token T_SORT_BY_NAME +%token T_SPECIAL +%token T_SQUAD +%token T_STARTUP +%token T_SUBALIGN +%token T_SYSLIB +%token T_TARGET +%token T_TRUNCATE +%token T_VER_EXTERN +%token T_VER_GLOBAL +%token T_VER_LOCAL + +%token T_LSHIFT_E +%token T_RSHIFT_E +%token T_LSHIFT +%token T_RSHIFT +%token T_EQ +%token T_NE +%token T_GE +%token T_LE +%token T_ADD_E +%token T_SUB_E +%token T_MUL_E +%token T_DIV_E +%token T_AND_E +%token T_OR_E +%token T_LOGICAL_AND +%token T_LOGICAL_OR + +%right '=' T_AND_E T_OR_E T_MUL_E T_DIV_E T_ADD_E T_SUB_E T_LSHIFT_E T_RSHIFT_E +%right '?' ':' +%left T_LOGICAL_OR +%left T_LOGICAL_AND +%left '|' +%left '&' +%left T_EQ T_NE T_GE T_LE '>' '<' +%left T_LSHIFT T_RSHIFT +%left '+' '-' +%left '*' '/' '%' +%left UNARY + +%token T_NUM +%token T_COMMONPAGESIZE +%token T_COPY +%token T_DSECT +%token T_IDENT +%token T_INFO +%token T_MAXPAGESIZE +%token T_MEMORY_ATTR +%token T_NOLOAD +%token T_ONLY_IF_RO +%token T_ONLY_IF_RW +%token T_OVERLAY +%token T_STRING +%token T_WILDCARD + +%type assignment +%type provide_assignment +%type provide_hidden_assignment +%type simple_assignment +%type assert_command +%type entry_command +%type ldscript_command +%type output_section_command +%type sections_command +%type sections_sub_command +%type expression +%type function +%type constant +%type variable +%type absolute_function +%type addr_function +%type align_function +%type alignof_function +%type block_function +%type data_segment_align_function +%type data_segment_end_function +%type data_segment_relro_end_function +%type defined_function +%type length_function +%type loadaddr_function +%type max_function +%type min_function +%type next_function +%type origin_function +%type output_section_addr +%type output_section_align +%type output_section_fillexp +%type output_section_lma +%type output_section_subalign +%type overlay_vma +%type phdr_at +%type segment_start_function +%type sizeof_function +%type sizeof_headers_function +%type input_file +%type input_section +%type input_section_desc +%type input_section_desc_no_keep +%type as_needed_list +%type ident_list +%type ident_list_nosep +%type input_file_list +%type output_section_addr_and_type +%type output_section_phdr +%type overlay_section_list +%type wildcard_list +%type assign_op +%type data_type +%type output_section_keywords +%type overlay_nocref +%type phdr_filehdr +%type phdr_flags +%type phdr_phdrs +%type output_section_data +%type output_sections_desc +%type overlay_desc +%type overlay_section +%type phdr +%type memory_region +%type ident +%type memory_attr +%type output_section_constraint +%type output_section_lma_region +%type output_section_region +%type output_section_type +%type output_section_type_keyword +%type symbolic_constant +%type wildcard +%type wildcard_sort +%type version_entry +%type version_block +%type version_entry_list +%type extern_block +%type version_dependency + +%union { + struct ld_exp *exp; + struct ld_script_assign *assign; + struct ld_script_cmd *cmd; + struct ld_script_list *list; + struct ld_script_input_file *input_file; + struct ld_script_phdr *phdr; + struct ld_script_region *region; + struct ld_script_sections_output *output_desc; + struct ld_script_sections_output_data *output_data; + struct ld_script_sections_output_input *input_section; + struct ld_script_sections_overlay *overlay_desc; + struct ld_script_sections_overlay_section *overlay_section; + struct ld_script_version_entry *version_entry; + struct ld_script_version_entry_head *version_entry_head; + struct ld_wildcard *wildcard; + char *str; + int64_t num; +} + +%% + +script + : ldscript + | + ; + +ldscript + : ldscript_command { + if ($1 != NULL) + ld_script_cmd_insert(&ld->ld_scp->lds_c, $1); + } + | ldscript ldscript_command { + if ($2 != NULL) + ld_script_cmd_insert(&ld->ld_scp->lds_c, $2); + } + ; + +expression + : expression '+' expression { + $$ = ld_exp_binary(ld, LEOP_ADD, $1, $3); + } + | expression '-' expression { + $$ = ld_exp_binary(ld, LEOP_SUBSTRACT, $1, $3); + } + | expression '*' expression { + $$ = ld_exp_binary(ld, LEOP_MUL, $1, $3); + } + | expression '/' expression { + $$ = ld_exp_binary(ld, LEOP_DIV, $1, $3); + } + | expression '%' expression { + $$ = ld_exp_binary(ld, LEOP_MOD, $1, $3); + } + | expression '&' expression { + $$ = ld_exp_binary(ld, LEOP_AND, $1, $3); + } + | expression '|' expression { + $$ = ld_exp_binary(ld, LEOP_OR, $1, $3); + } + | expression '>' expression { + $$ = ld_exp_binary(ld, LEOP_GREATER, $1, $3); + } + | expression '<' expression { + $$ = ld_exp_binary(ld, LEOP_LESSER, $1, $3); + } + | expression T_EQ expression { + $$ = ld_exp_binary(ld, LEOP_EQUAL, $1, $3); + } + | expression T_NE expression { + $$ = ld_exp_binary(ld, LEOP_NE, $1, $3); + } + | expression T_GE expression { + $$ = ld_exp_binary(ld, LEOP_GE, $1, $3); + } + | expression T_LE expression { + $$ = ld_exp_binary(ld, LEOP_LE, $1, $3); + } + | expression T_LSHIFT expression { + $$ = ld_exp_binary(ld, LEOP_LSHIFT, $1, $3); + } + | expression T_RSHIFT expression { + $$ = ld_exp_binary(ld, LEOP_RSHIFT, $1, $3); + } + | expression T_LOGICAL_AND expression { + $$ = ld_exp_binary(ld, LEOP_LOGICAL_AND, $1, $3); + } + | expression T_LOGICAL_OR expression { + $$ = ld_exp_binary(ld, LEOP_LOGICAL_OR, $1, $3); + } + | '!' expression %prec UNARY { + $$ = ld_exp_unary(ld, LEOP_NOT, $2); + } + | '-' expression %prec UNARY { + $$ = ld_exp_unary(ld, LEOP_MINUS, $2); + } + | '~' expression %prec UNARY { + $$ = ld_exp_unary(ld, LEOP_NEGATION, $2); + } + | expression '?' expression ':' expression { + $$ = ld_exp_trinary(ld, $1, $3, $5); + } + | simple_assignment { + $$ = ld_exp_assign(ld, $1); + } + | function + | constant + | variable + | '(' expression ')' { $$ = $2; $$->le_par = 1; } + ; + +function + : absolute_function + | addr_function + | align_function + | alignof_function + | block_function + | data_segment_align_function + | data_segment_end_function + | data_segment_relro_end_function + | defined_function + | length_function + | loadaddr_function + | max_function + | min_function + | next_function + | origin_function + | segment_start_function + | sizeof_function + | sizeof_headers_function + ; + +absolute_function + : T_ABSOLUTE '(' expression ')' { + $$ = ld_exp_unary(ld, LEOP_ABS, $3); + } + ; + +addr_function + : T_ADDR '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_ADDR, ld_exp_name(ld, $3)); + } + ; + +align_function + : T_ALIGN '(' expression ')' { + $$ = ld_exp_unary(ld, LEOP_ALIGN, $3); + } + | T_ALIGN '(' expression ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_ALIGN, $3, $5); + } + ; + +alignof_function + : T_ALIGNOF '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_ALIGNOF, ld_exp_name(ld, $3)); + } + ; + +block_function + : T_BLOCK '(' expression ')' { + $$ = ld_exp_unary(ld, LEOP_BLOCK, $3); + } + ; + +data_segment_align_function + : T_DATA_SEGMENT_ALIGN '(' expression ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_DSA, $3, $5); + } + ; + +data_segment_end_function + : T_DATA_SEGMENT_END '(' expression ')' { + $$ = ld_exp_unary(ld, LEOP_DSE, $3); + } + ; + +data_segment_relro_end_function + : T_DATA_SEGMENT_RELRO_END '(' expression ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_DSRE, $3, $5); + } + ; + +defined_function + : T_DEFINED '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_DEFINED, ld_exp_symbol(ld, $3)); + } + ; + +length_function + : T_LENGTH '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_LENGTH, ld_exp_name(ld, $3)); + } + ; + +loadaddr_function + : T_LOADADDR '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_LOADADDR, ld_exp_name(ld, $3)); + } + ; + +max_function + : T_MAX '(' expression ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_MAX, $3, $5); + } + ; + +min_function + : T_MIN '(' expression ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_MIN, $3, $5); + } + ; + +next_function + : T_NEXT '(' expression ')' { + $$ = ld_exp_unary(ld, LEOP_NEXT, $3); + } + ; + +origin_function + : T_ORIGIN '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_ORIGIN, ld_exp_name(ld, $3)); + } + ; + +segment_start_function + : T_SEGMENT_START '(' ident ',' expression ')' { + $$ = ld_exp_binary(ld, LEOP_MIN, ld_exp_name(ld, $3), $5); + } + ; + +sizeof_function + : T_SIZEOF '(' ident ')' { + $$ = ld_exp_unary(ld, LEOP_SIZEOF, ld_exp_name(ld, $3)); + } + ; + +sizeof_headers_function + : T_SIZEOF_HEADERS { + $$ = ld_exp_sizeof_headers(ld); + } + ; + +constant + : T_NUM { + $$ = ld_exp_constant(ld, $1); + } + | symbolic_constant { + $$ = ld_exp_symbolic_constant(ld, $1); + } + ; + +symbolic_constant + : T_CONSTANT '(' T_COMMONPAGESIZE ')' { $$ = $3; } + | T_CONSTANT '(' T_MAXPAGESIZE ')' { $$ = $3; } + ; + +ldscript_command + : assert_command + | assignment { + if (*$1->lda_var->le_name == '.') + ld_fatal(ld, "variable . can only be used inside" + " SECTIONS command"); + $$ = ld_script_cmd(ld, LSC_ASSIGN, $1); + } + | entry_command + | extern_command { $$ = NULL; } + | force_common_allocation_command { $$ = NULL; } + | group_command { $$ = NULL; } + | inhibit_common_allocation_command { $$ = NULL; } + | input_command { $$ = NULL; } + | memory_command { $$ = NULL; } + | nocrossrefs_command { $$ = NULL; } + | output_command { $$ = NULL; } + | output_arch_command { $$ = NULL; } + | output_format_command { $$ = NULL; } + | phdrs_command { $$ = NULL; } + | region_alias_command { $$ = NULL; } + | search_dir_command { $$ = NULL; } + | sections_command + | startup_command { $$ = NULL; } + | target_command { $$ = NULL; } + | version_script_node { $$ = NULL; } + | ';' { $$ = NULL; } + ; + +assignment + : simple_assignment + | provide_assignment + | provide_hidden_assignment + ; + +simple_assignment + : variable assign_op expression %prec '=' { + $$ = ld_script_assign(ld, $1, $2, $3, 0, 0); + } + ; + +provide_assignment + : T_PROVIDE '(' variable '=' expression ')' { + $$ = ld_script_assign(ld, $3, LSAOP_E, $5, 1, 0); + } + ; + +provide_hidden_assignment + : T_PROVIDE_HIDDEN '(' variable '=' expression ')' { + $$ = ld_script_assign(ld, $3, LSAOP_E, $5, 1, 1); + } + ; + +assign_op + : T_LSHIFT_E { $$ = LSAOP_LSHIFT_E; } + | T_RSHIFT_E { $$ = LSAOP_RSHIFT_E; } + | T_ADD_E { $$ = LSAOP_ADD_E; } + | T_SUB_E { $$ = LSAOP_SUB_E; } + | T_MUL_E { $$ = LSAOP_MUL_E; } + | T_DIV_E { $$ = LSAOP_DIV_E; } + | T_AND_E { $$ = LSAOP_AND_E; } + | T_OR_E { $$ = LSAOP_OR_E; } + | '=' { $$ = LSAOP_E; } + ; + +assert_command + : T_ASSERT '(' expression ',' T_STRING ')' { + $$ = ld_script_assert(ld, $3, $5); + } + ; + +entry_command + : T_ENTRY '(' ident ')' { + $$ = ld_script_cmd(ld, LSC_ENTRY, $3); + } + ; + +extern_command + : T_EXTERN '(' ident_list_nosep ')' { ld_script_extern(ld, $3); } + ; + +force_common_allocation_command + : T_FORCE_COMMON_ALLOCATION { ld->ld_common_alloc = 1; } + ; + +group_command + : T_GROUP '(' input_file_list ')' { + ld_script_group(ld, ld_script_list_reverse($3)); + } + ; + +inhibit_common_allocation_command + : T_INHIBIT_COMMON_ALLOCATION { ld->ld_common_no_alloc = 1; } + ; + +input_command + : T_INPUT '(' input_file_list ')' { + ld_script_input(ld, ld_script_list_reverse($3)); + } + ; + +memory_command + : T_MEMORY '{' memory_region_list '}' + ; + +memory_region_list + : memory_region { + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_r, $1, ldsr_next); + } + | memory_region_list memory_region { + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_r, $2, ldsr_next); + } + ; + +memory_region + : ident memory_attr ':' T_ORIGIN '=' expression ',' T_LENGTH '=' + expression { + ld_script_region(ld, $1, $2, $6, $10); + } + ; + +memory_attr + : T_MEMORY_ATTR + | { $$ = NULL; } + ; + +nocrossrefs_command + : T_NOCROSSREFS '(' ident_list_nosep ')' { + ld_script_nocrossrefs(ld, $3); + } + ; + +output_command + : T_OUTPUT '(' ident ')' { + if (ld->ld_output == NULL) + ld->ld_output_file = $3; + else + free($3); + } + ; + +output_arch_command + : T_OUTPUT_ARCH '(' ident ')' { + ld_arch_set(ld, $3); + free($3); + } + ; + +output_format_command + : T_OUTPUT_FORMAT '(' ident ')' { + ld_output_format(ld, $3, $3, $3); + } + | T_OUTPUT_FORMAT '(' ident ',' ident ',' ident ')' { + ld_output_format(ld, $3, $5, $7); + } + ; + +phdrs_command + : T_PHDRS '{' phdr_list '}' + ; + +phdr_list + : phdr { + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_p, $1, ldsp_next); + } + | phdr_list phdr { + STAILQ_INSERT_TAIL(&ld->ld_scp->lds_p, $2, ldsp_next); + } + +phdr + : ident ident phdr_filehdr phdr_phdrs phdr_at phdr_flags ';' { + $$ = ld_script_phdr(ld, $1, $2, $3, $4, $5, $6); + } + ; + +phdr_filehdr + : T_FILEHDR { $$ = 1; } + | { $$ = 0; } + ; + +phdr_phdrs + : T_PHDRS { $$ = 1; } + | { $$ = 0; } + ; + +phdr_at + : T_AT '(' expression ')' { $$ = $3; } + | { $$ = NULL; } + ; + +phdr_flags + : T_FLAGS '(' T_NUM ')' { $$ = $3; } + | { $$ = 0; } + ; + +region_alias_command + : T_REGION_ALIAS '(' ident ',' ident ')' { + ld_script_region_alias(ld, $3, $5); + } + ; + +search_dir_command + : T_SEARCH_DIR '(' ident ')' { + ld_path_add(ld, $3, LPT_L); + free($3); + } + ; + +sections_command + : T_SECTIONS '{' sections_command_list '}' { + struct ld_script_sections *ldss; + ldss = malloc(sizeof(struct ld_script_sections)); + if (ldss == NULL) + ld_fatal_std(ld, "malloc"); + memcpy(&ldss->ldss_c, &ldss_c, sizeof(ldss_c)); + $$ = ld_script_cmd(ld, LSC_SECTIONS, ldss); + STAILQ_INIT(&ldss_c); + } + ; + +sections_command_list + : sections_sub_command { + if ($1 != NULL) + ld_script_cmd_insert(&ldss_c, $1); + } + | sections_command_list sections_sub_command { + if ($2 != NULL) + ld_script_cmd_insert(&ldss_c, $2); + } + ; + +sections_sub_command + : entry_command + | assignment { + $$ = ld_script_cmd(ld, LSC_ASSIGN, $1); + } + | output_sections_desc { + $$ = ld_script_cmd(ld, LSC_SECTIONS_OUTPUT, $1); + } + | overlay_desc { + $$ = ld_script_cmd(ld, LSC_SECTIONS_OVERLAY, $1); + } + | ';' { $$ = NULL; } + ; + +output_sections_desc + : ident output_section_addr_and_type ':' { + /* Remember the name of last output section, needed later for assignment. */ + ld->ld_scp->lds_base_os_name = $1; + } + output_section_lma + output_section_align + output_section_subalign + output_section_constraint + '{' output_section_command_list '}' + output_section_region + output_section_lma_region + output_section_phdr + output_section_fillexp { + $$ = calloc(1, sizeof(struct ld_script_sections_output)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldso_name = $1; + $$->ldso_vma = $2->ldl_entry; + $$->ldso_type = $2->ldl_next->ldl_entry; + $$->ldso_lma = $5; + $$->ldso_align = $6; + $$->ldso_subalign = $7; + $$->ldso_constraint = $8; + memcpy(&$$->ldso_c, &ldso_c, sizeof(ldso_c)); + $$->ldso_region = $12; + $$->ldso_lma_region = $13; + $$->ldso_phdr = ld_script_list_reverse($14); + $$->ldso_fill = $15; + STAILQ_INIT(&ldso_c); + ld->ld_scp->lds_base_os_name = 0; + ld->ld_scp->lds_last_os_name = $1; + } + ; + +output_section_addr_and_type + : output_section_addr output_section_type { + $$ = ld_script_list(ld, NULL, $2); + $$ = ld_script_list(ld, $$, $1); + } + | output_section_type { + $$ = ld_script_list(ld, NULL, NULL); + $$ = ld_script_list(ld, $$, $1); + } + ; + +output_section_addr + : expression + ; + +output_section_type + : '(' output_section_type_keyword ')' { $$ = $2; } + | '(' ')' { $$ = NULL; } + | { $$ = NULL; } + ; + +output_section_type_keyword + : T_COPY + | T_DSECT + | T_INFO + | T_NOLOAD + | T_OVERLAY + ; + +output_section_lma + : T_AT '(' expression ')' { $$ = $3; } + | { $$ = NULL; } + ; + +output_section_align + : T_ALIGN '(' expression ')' { $$ = $3; } + | { $$ = NULL; } + ; + +output_section_subalign + : T_SUBALIGN '(' expression ')' { $$ = $3; } + | { $$ = NULL; } + ; + +output_section_constraint + : T_ONLY_IF_RO + | T_ONLY_IF_RW + | { $$ = NULL; } + ; + +output_section_command_list + : output_section_command { + if ($1 != NULL) + ld_script_cmd_insert(&ldso_c, $1); + } + | output_section_command_list output_section_command { + if ($2 != NULL) + ld_script_cmd_insert(&ldso_c, $2); + } + ; + +output_section_command + : assignment { + $$ = ld_script_cmd(ld, LSC_ASSIGN, $1); + } + | input_section_desc { + $$ = ld_script_cmd(ld, LSC_SECTIONS_OUTPUT_INPUT, $1); + } + | output_section_data { + $$ = ld_script_cmd(ld, LSC_SECTIONS_OUTPUT_DATA, $1); + } + | output_section_keywords { + $$ = ld_script_cmd(ld, LSC_SECTIONS_OUTPUT_KEYWORD, + (void *) (uintptr_t) $1); + } + | ';' { $$ = NULL; } + ; + +input_section_desc + : input_section_desc_no_keep { + $1->ldoi_keep = 0; + $$ = $1; + } + | T_KEEP '(' input_section_desc_no_keep ')' { + $3->ldoi_keep = 0; + $$ = $3; + } + ; + +input_section_desc_no_keep + : wildcard_sort input_section { + $2->ldoi_ar = NULL; + $2->ldoi_file = $1; + $$ = $2; + } + | wildcard_sort ':' wildcard_sort input_section { + $4->ldoi_ar = $1; + $4->ldoi_ar = $3; + $$ = $4; + } + ; + +input_section + : '(' T_EXCLUDE_FILE '(' wildcard_list ')' wildcard_list ')' { + $$ = calloc(1, sizeof(struct ld_script_sections_output_input)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldoi_exclude = ld_script_list_reverse($4); + $$->ldoi_sec = ld_script_list_reverse($6); + } + | '(' wildcard_list ')' { + $$ = calloc(1, sizeof(struct ld_script_sections_output_input)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldoi_exclude = NULL; + $$->ldoi_sec = ld_script_list_reverse($2); + } + ; + +output_section_data + : data_type '(' expression ')' { + $$ = calloc(1, sizeof(struct ld_script_sections_output_data)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldod_type = $1; + $$->ldod_exp = $3; + } + ; + +data_type + : T_BYTE { $$ = LSODT_BYTE; } + | T_SHORT { $$ = LSODT_SHORT; } + | T_LONG { $$ = LSODT_LONG; } + | T_QUAD { $$ = LSODT_QUAD; } + | T_SQUAD { $$ = LSODT_SQUAD; } + | T_FILL { $$ = LSODT_FILL; } + ; + +output_section_keywords + : T_CREATE_OBJECT_SYMBOLS { + $$ = LSOK_CREATE_OBJECT_SYMBOLS; + } + | T_CONSTRUCTORS { + $$ = LSOK_CONSTRUCTORS; + } + | T_SORT_BY_NAME '(' T_CONSTRUCTORS ')' { + $$ = LSOK_CONSTRUCTORS_SORT_BY_NAME; + } + ; + +output_section_region + : '>' ident { $$ = $2; } + | { $$ = NULL; } + ; + +output_section_lma_region + : T_AT '>' ident { $$ = $3; } + | { $$ = NULL; } + ; + +output_section_phdr + : output_section_phdr ':' ident { + $$ = ld_script_list(ld, $$, $3); + } + | { $$ = NULL; } + ; + + +output_section_fillexp + : '=' expression { $$ = $2; } + | { $$ = NULL; } + ; + +overlay_desc + : T_OVERLAY + overlay_vma ':' + overlay_nocref + output_section_lma + '{' overlay_section_list '}' + output_section_region + output_section_phdr + output_section_fillexp { + $$ = calloc(1, sizeof(struct ld_script_sections_overlay)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldso_vma = $2; + $$->ldso_nocrossref = !!$4; + $$->ldso_lma = $5; + $$->ldso_s = $7; + $$->ldso_region = $9; + $$->ldso_phdr = $10; + $$->ldso_fill = $11; + } + ; + +overlay_vma + : expression + | { $$ = NULL; } + ; + +overlay_nocref + : T_NOCROSSREFS { $$ = 1; } + | { $$ = 0; } + ; + +overlay_section_list + : overlay_section { + $$ = ld_script_list(ld, NULL, $1); + } + | overlay_section_list overlay_section { + $$ = ld_script_list(ld, $1, $2); + } + ; + +overlay_section + : ident + '{' output_section_command_list '}' + output_section_phdr + output_section_fillexp { + $$ = calloc(1, + sizeof(struct ld_script_sections_overlay_section)); + if ($$ == NULL) + ld_fatal_std(ld, "calloc"); + $$->ldos_name = $1; + memcpy(&$$->ldos_c, &ldso_c, sizeof(ldso_c)); + $$->ldos_phdr = $5; + $$->ldos_fill = $6; + STAILQ_INIT(&ldso_c); + } + ; + +startup_command + : T_STARTUP '(' ident ')' { + ld_file_add_first(ld, $3, LFT_UNKNOWN); + free($3); + } + ; + +target_command + : T_TARGET '(' ident ')' + ; + +version_script_node + : ident extern_block version_dependency ';' { + ld_script_version_add_node(ld, $1, $2, $3); + } + | ident version_block version_dependency ';' { + ld_script_version_add_node(ld, $1, $2, $3); + } + | extern_block version_dependency ';' { + ld_script_version_add_node(ld, NULL, $1, $2); + } + | version_block version_dependency ';' { + ld_script_version_add_node(ld, NULL, $1, $2); + } + ; + +extern_block + : T_VER_EXTERN T_STRING version_block { + ld_script_version_set_lang(ld, $3, $2); + $$ = $3; + } + ; + +version_block + : '{' version_entry_list '}' { + $$ = $2; + ld->ld_state.ls_version_local = 0; + } + ; + +version_entry_list + : version_entry { + $$ = ld_script_version_link_entry(ld, NULL, $1); + } + | version_entry_list version_entry { + $$ = ld_script_version_link_entry(ld, $1, $2); + } + ; + +version_entry + : T_VER_GLOBAL { + ld->ld_state.ls_version_local = 0; + $$ = NULL; + } + | T_VER_LOCAL { + ld->ld_state.ls_version_local = 1; + $$ = NULL; + } + | wildcard ';' { + $$ = ld_script_version_alloc_entry(ld, $1, NULL); + } + | extern_block ';' { + $$ = ld_script_version_alloc_entry(ld, NULL, $1); + } + ; + +version_dependency + : ident + | { $$ = NULL; } + ; + +ident + : T_IDENT + | T_STRING + ; + +variable + : ident { $$ = ld_exp_symbol(ld, $1); } + | '.' { $$ = ld_exp_symbol(ld, "."); } + ; + +wildcard + : ident + | T_WILDCARD + | '*' { $$ = strdup("*"); } + | '?' { $$ = strdup("?"); } + ; + +wildcard_sort + : wildcard { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $1; + $$->lw_sort = LWS_NONE; + } + | T_SORT_BY_NAME '(' wildcard ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $3; + $$->lw_sort = LWS_NAME; + } + | T_SORT_BY_NAME '(' T_SORT_BY_NAME '(' wildcard ')' ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $5; + $$->lw_sort = LWS_NAME; + } + | T_SORT_BY_NAME '(' T_SORT_BY_ALIGNMENT '(' wildcard ')' ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $5; + $$->lw_sort = LWS_NAME_ALIGN; + } + | T_SORT_BY_ALIGNMENT '(' wildcard ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $3; + $$->lw_sort = LWS_ALIGN; + } + | T_SORT_BY_ALIGNMENT '(' T_SORT_BY_NAME '(' wildcard ')' ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $5; + $$->lw_sort = LWS_ALIGN_NAME; + } + | T_SORT_BY_ALIGNMENT '(' T_SORT_BY_ALIGNMENT '(' wildcard ')' ')' { + $$ = ld_wildcard_alloc(ld); + $$->lw_name = $5; + $$->lw_sort = LWS_ALIGN; + } + ; + +ident_list + : ident { $$ = ld_script_list(ld, NULL, $1); } + | ident_list separator ident { $$ = ld_script_list(ld, $1, $3); } + ; + +ident_list_nosep + : ident { $$ = ld_script_list(ld, NULL, $1); } + | ident_list_nosep ident { $$ = ld_script_list(ld, $1, $2); } + ; + +input_file_list + : input_file { $$ = ld_script_list(ld, NULL, $1); } + | input_file_list separator input_file { $$ = ld_script_list(ld, $1, $3); } + ; + +input_file + : ident { $$ = ld_script_input_file(ld, 0, $1); } + | as_needed_list { $$ = ld_script_input_file(ld, 1, $1); } + ; + +as_needed_list + : T_AS_NEEDED '(' ident_list ')' { $$ = $3; } + ; + +wildcard_list + : wildcard_sort { $$ = ld_script_list(ld, NULL, $1); } + | wildcard_list wildcard_sort { $$ = ld_script_list(ld, $1, $2); } + ; + +separator + : ',' + | + ; + +%% + +/* ARGSUSED */ +static void +yyerror(const char *s) +{ + + (void) s; + errx(1, "Syntax error in ld script, line %d\n", lineno); +} + +static void +_init_script(void) +{ + + STAILQ_INIT(&ldss_c); + STAILQ_INIT(&ldso_c); +} + +void +ld_script_parse(const char *name) +{ + YY_BUFFER_STATE b; + + _init_script(); + + if ((yyin = fopen(name, "r")) == NULL) + ld_fatal_std(ld, "fopen %s name failed", name); + b = yy_create_buffer(yyin, YY_BUF_SIZE); + yy_switch_to_buffer(b); + if (yyparse() < 0) + ld_fatal(ld, "unable to parse linker script %s", name); + yy_delete_buffer(b); +} + +void +ld_script_parse_internal(void) +{ + YY_BUFFER_STATE b; + + _init_script(); + + assert(ld->ld_arch != NULL && ld->ld_arch->script != NULL); + b = yy_scan_string(ld->ld_arch->script); + yy_switch_to_buffer(b); + if (yyparse() < 0) + ld_fatal(ld, "unable to parse internal linker script"); + yy_delete_buffer(b); +} diff --git a/contrib/elftoolchain/ld/ld_strtab.c b/contrib/elftoolchain/ld/ld_strtab.c new file mode 100644 index 0000000000..989e8e9bf7 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_strtab.c @@ -0,0 +1,238 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_strtab.h" + +ELFTC_VCSID("$Id: ld_strtab.c 3812 2020-02-07 02:18:26Z emaste $"); + +#define _DEFAULT_STRTAB_SIZE 512 + +struct ld_str { + char *s; + size_t off, len; + UT_hash_handle hh; +}; + +struct ld_strtab { + struct ld_str *st_pool; + char *st_buf; + size_t st_cap; + size_t st_size; + unsigned char st_suffix; +}; + + +static void _resize_strtab(struct ld *ld, struct ld_strtab *st, + size_t newsize); + +struct ld_strtab * +ld_strtab_alloc(struct ld *ld, unsigned char suffix) +{ + struct ld_strtab *st; + + if ((st = calloc(1, sizeof(*st))) == NULL) + ld_fatal_std(ld, "calloc"); + + st->st_size = 0; + if (suffix) { + st->st_suffix = 1; + st->st_cap = _DEFAULT_STRTAB_SIZE; + if ((st->st_buf = calloc(1, st->st_cap)) == NULL) + ld_fatal_std(ld, "calloc"); + ld_strtab_insert(ld, st, ""); + } else + st->st_size = 1; + + return (st); +} + +void +ld_strtab_free(struct ld_strtab *st) +{ + struct ld_str *str, *tmp; + + if (st == NULL) + return; + + if (st->st_pool != NULL) { + HASH_ITER(hh, st->st_pool, str, tmp) { + HASH_DELETE(hh, st->st_pool, str); + free(str->s); + free(str); + } + } + + free(st->st_buf); + free(st); +} + +char * +ld_strtab_getbuf(struct ld *ld, struct ld_strtab *st) +{ + struct ld_str *str, *tmp; + char *p, *end; + + assert(st != NULL); + + if (st->st_suffix) + return (st->st_buf); + + if (st->st_buf == NULL) { + if ((st->st_buf = malloc(st->st_size)) == NULL) + ld_fatal_std(ld, "malloc"); + /* Flatten the string hash table. */ + p = st->st_buf; + end = p + st->st_size; + *p++ = '\0'; + HASH_ITER(hh, st->st_pool, str, tmp) { + memcpy(p, str->s, str->len); + p[str->len] = '\0'; + p += str->len + 1; + } + assert(p == end); + } + + return (st->st_buf); +} + +size_t +ld_strtab_getsize(struct ld_strtab *st) +{ + + return (st->st_size); +} + +static void +_resize_strtab(struct ld *ld, struct ld_strtab *st, size_t newsize) +{ + + assert(st != NULL && st->st_suffix); + if ((st->st_buf = realloc(st->st_buf, newsize)) == NULL) + ld_fatal_std(ld, "realloc"); + st->st_cap = newsize; +} + +size_t +ld_strtab_insert_no_suffix(struct ld *ld, struct ld_strtab *st, char *s) +{ + struct ld_str *str; + + assert(st != NULL && st->st_suffix == 0); + + if (s == NULL) + return (0); + + if (*s == '\0') + return (0); + + HASH_FIND_STR(st->st_pool, s, str); + if (str != NULL) + return (str->off); + + if ((str = calloc(1, sizeof(*str))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((str->s = strdup(s)) == NULL) + ld_fatal_std(ld, "strdup"); + + str->len = strlen(s); + HASH_ADD_KEYPTR(hh, st->st_pool, str->s, str->len, str); + + str->off = st->st_size; + st->st_size += str->len + 1; + + return (str->off); +} + +void +ld_strtab_insert(struct ld *ld, struct ld_strtab *st, const char *s) +{ + const char *r; + char *b, *c; + size_t len, slen; + int append; + + assert(st != NULL && st->st_buf != NULL && st->st_suffix); + + if (s == NULL) + return; + + slen = strlen(s); + append = 0; + b = st->st_buf; + for (c = b; c < b + st->st_size;) { + len = strlen(c); + if (!append && len >= slen) { + r = c + (len - slen); + if (strcmp(r, s) == 0) + return; + } else if (len < slen && len != 0) { + r = s + (slen - len); + if (strcmp(c, r) == 0) { + st->st_size -= len + 1; + memmove(c, c + len + 1, st->st_size - (c - b)); + append = 1; + continue; + } + } + c += len + 1; + } + + while (st->st_size + slen + 1 >= st->st_cap) + _resize_strtab(ld, st, st->st_cap * 2); + + b = st->st_buf; + memcpy(&b[st->st_size], s, slen); + b[st->st_size + slen] = '\0'; + st->st_size += slen + 1; +} + +size_t +ld_strtab_lookup(struct ld_strtab *st, const char *s) +{ + const char *b, *c, *r; + size_t len, slen; + + assert(st != NULL && st->st_buf != NULL && st->st_suffix); + + if (s == NULL) + return (0); + + slen = strlen(s); + b = st->st_buf; + for (c = b; c < b + st->st_size;) { + len = strlen(c); + if (len >= slen) { + r = c + (len - slen); + if (strcmp(r, s) == 0) + return (r - b); + } + c += len + 1; + } + + return (-1); +} diff --git a/contrib/elftoolchain/ld/ld_strtab.h b/contrib/elftoolchain/ld/ld_strtab.h new file mode 100644 index 0000000000..bcd5f71454 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_strtab.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_strtab.h 2965 2013-09-10 02:46:29Z kaiwang27 $ + */ + +struct ld_strtab *ld_strtab_alloc(struct ld *, unsigned char); +void ld_strtab_free(struct ld_strtab *); +void ld_strtab_insert(struct ld *, struct ld_strtab *, const char *); +size_t ld_strtab_insert_no_suffix(struct ld *, struct ld_strtab *, char *); +size_t ld_strtab_lookup(struct ld_strtab *, const char *); +char *ld_strtab_getbuf(struct ld *, struct ld_strtab *); +size_t ld_strtab_getsize(struct ld_strtab *); diff --git a/contrib/elftoolchain/ld/ld_symbols.c b/contrib/elftoolchain/ld/ld_symbols.c new file mode 100644 index 0000000000..cb034a66b0 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_symbols.c @@ -0,0 +1,1415 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_dynamic.h" +#include "ld_file.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_symbols.h" +#include "ld_symver.h" +#include "ld_script.h" +#include "ld_strtab.h" + +ELFTC_VCSID("$Id: ld_symbols.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); + +#define _INIT_SYMTAB_SIZE 128 + +static void _load_symbols(struct ld *ld, struct ld_file *lf); +static void _load_archive_symbols(struct ld *ld, struct ld_file *lf); +static void _load_elf_symbols(struct ld *ld, struct ld_input *li, Elf *e); +static void _unload_symbols(struct ld_input *li); +static void _add_elf_symbol(struct ld *ld, struct ld_input *li, Elf *e, + GElf_Sym *sym, size_t strndx, int i); +static void _add_to_dynsym_table(struct ld *ld, struct ld_symbol *lsb); +static void _write_to_dynsym_table(struct ld *ld, struct ld_symbol *lsb); +static void _add_to_symbol_table(struct ld *ld, struct ld_symbol *lsb); +static void _free_symbol_table(struct ld_symbol_table *symtab); +struct ld_symbol_table *_alloc_symbol_table(struct ld *ld); +static int _archive_member_extracted(struct ld_archive *la, off_t off); +static struct ld_archive_member * _extract_archive_member(struct ld *ld, + struct ld_file *lf, struct ld_archive *la, off_t off); +static void _print_extracted_member(struct ld *ld, + struct ld_archive_member *lam, struct ld_symbol *lsb); +static void _resolve_and_add_symbol(struct ld *ld, struct ld_symbol *lsb); +static struct ld_symbol *_alloc_symbol(struct ld *ld); +static void _free_symbol(struct ld_symbol *lsb); +static struct ld_symbol *_find_symbol(struct ld_symbol *tbl, char *name); +static void _update_symbol(struct ld_symbol *lsb); + +#define _add_symbol(tbl, s) do { \ + HASH_ADD_KEYPTR(hh, (tbl), (s)->lsb_longname, \ + strlen((s)->lsb_longname), (s)); \ + } while (0) +#define _remove_symbol(tbl, s) do { \ + HASH_DEL((tbl), (s)); \ + } while (0) +#define _resolve_symbol(_s, s) do { \ + assert((_s) != (s)); \ + (s)->lsb_ref_dso |= (_s)->lsb_ref_dso; \ + (s)->lsb_ref_ndso |= (_s)->lsb_ref_ndso; \ + if ((s)->lsb_prev != NULL) { \ + (s)->lsb_prev->lsb_ref = (_s); \ + (_s)->lsb_prev = (s)->lsb_prev; \ + } \ + (s)->lsb_prev = (_s); \ + (_s)->lsb_ref = (s); \ + } while (0) + +void +ld_symbols_cleanup(struct ld *ld) +{ + struct ld_input *li; + struct ld_symbol *lsb, *_lsb; + + HASH_CLEAR(hh, ld->ld_sym); + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + _unload_symbols(li); + } + + if (ld->ld_ext_symbols != NULL) { + STAILQ_FOREACH_SAFE(lsb, ld->ld_ext_symbols, lsb_next, _lsb) { + STAILQ_REMOVE(ld->ld_ext_symbols, lsb, ld_symbol, + lsb_next); + _free_symbol(lsb); + } + free(ld->ld_ext_symbols); + ld->ld_ext_symbols = NULL; + } + + if (ld->ld_var_symbols != NULL) { + STAILQ_FOREACH_SAFE(lsb, ld->ld_var_symbols, lsb_next, _lsb) { + STAILQ_REMOVE(ld->ld_var_symbols, lsb, ld_symbol, + lsb_next); + _free_symbol(lsb); + } + free(ld->ld_var_symbols); + ld->ld_var_symbols = NULL; + } + + if (ld->ld_dyn_symbols != NULL) { + free(ld->ld_dyn_symbols); + ld->ld_dyn_symbols = NULL; + } + + if (ld->ld_symtab != NULL) { + _free_symbol_table(ld->ld_symtab); + ld->ld_symtab = NULL; + } + + if (ld->ld_strtab != NULL) { + ld_strtab_free(ld->ld_strtab); + ld->ld_strtab = NULL; + } +} + +void +ld_symbols_add_extern(struct ld *ld, char *name) +{ + struct ld_symbol *lsb; + + /* Check if the extern symbol has been added before. */ + if (_find_symbol(ld->ld_sym, name) != NULL) + return; + + lsb = _alloc_symbol(ld); + if ((lsb->lsb_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + if ((lsb->lsb_longname = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + if (ld->ld_ext_symbols == NULL) { + ld->ld_ext_symbols = malloc(sizeof(*ld->ld_ext_symbols)); + if (ld->ld_ext_symbols == NULL) + ld_fatal_std(ld, "malloc"); + STAILQ_INIT(ld->ld_ext_symbols); + } + STAILQ_INSERT_TAIL(ld->ld_ext_symbols, lsb, lsb_next); + + _add_symbol(ld->ld_sym, lsb); +} + +void +ld_symbols_add_variable(struct ld *ld, struct ld_script_variable *ldv, + unsigned provide, unsigned hidden) +{ + struct ld_symbol *lsb; + + lsb = _alloc_symbol(ld); + if ((lsb->lsb_name = strdup(ldv->ldv_name)) == NULL) + ld_fatal_std(ld, "strdup"); + if ((lsb->lsb_longname = strdup(ldv->ldv_name)) == NULL) + ld_fatal_std(ld, "strdup"); + lsb->lsb_var = ldv; + lsb->lsb_bind = STB_GLOBAL; + lsb->lsb_shndx = SHN_ABS; + lsb->lsb_provide = provide; + if (hidden) + lsb->lsb_other = STV_HIDDEN; + lsb->lsb_ref_ndso = 1; + ldv->ldv_symbol = lsb; + ldv->ldv_os_ref = ld->ld_scp->lds_last_os_name; + ldv->ldv_os_base = ld->ld_scp->lds_base_os_name; + + if (ld->ld_var_symbols == NULL) { + ld->ld_var_symbols = malloc(sizeof(*ld->ld_var_symbols)); + if (ld->ld_var_symbols == NULL) + ld_fatal_std(ld, "malloc"); + STAILQ_INIT(ld->ld_var_symbols); + } + STAILQ_INSERT_TAIL(ld->ld_var_symbols, lsb, lsb_next); + + _resolve_and_add_symbol(ld, lsb); +} + +void +ld_symbols_add_internal(struct ld *ld, const char *name, uint64_t size, + uint64_t value, uint16_t shndx, unsigned char bind, unsigned char type, + unsigned char other, struct ld_input_section *is, + struct ld_output_section *preset_os) +{ + struct ld_symbol *lsb; + + lsb = _alloc_symbol(ld); + if ((lsb->lsb_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + if ((lsb->lsb_longname = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + lsb->lsb_size = size; + lsb->lsb_value = value; + lsb->lsb_shndx = shndx; + lsb->lsb_bind = bind; + lsb->lsb_type = type; + lsb->lsb_other = other; + lsb->lsb_preset_os = preset_os; + lsb->lsb_ref_ndso = 1; + lsb->lsb_input = (is == NULL) ? NULL : is->is_input; + lsb->lsb_is = is; + + _resolve_and_add_symbol(ld, lsb); +} + +int +ld_symbols_get_value(struct ld *ld, char *name, uint64_t *val) +{ + struct ld_symbol *lsb; + + if ((lsb = _find_symbol(ld->ld_sym, name)) != NULL) + *val = lsb->lsb_value; + else + return (-1); + + return (0); +} + +void +ld_symbols_resolve(struct ld *ld) +{ + struct ld_state *ls; + struct ld_file *lf; + struct ld_symbol *lsb, *_lsb; + + if (TAILQ_EMPTY(&ld->ld_lflist)) { + if (ld->ld_print_version) + exit(EXIT_SUCCESS); + else + ld_fatal(ld, "no input files"); + } + + ls = &ld->ld_state; + lf = TAILQ_FIRST(&ld->ld_lflist); + ls->ls_group_level = lf->lf_group_level; + + while (lf != NULL) { + /* Process archive groups. */ + if (lf->lf_group_level < ls->ls_group_level && + ls->ls_extracted[ls->ls_group_level]) { + do { + lf = TAILQ_PREV(lf, ld_file_head, lf_next); + } while (lf->lf_group_level >= ls->ls_group_level); + lf = TAILQ_NEXT(lf, lf_next); + ls->ls_extracted[ls->ls_group_level] = 0; + } + ls->ls_group_level = lf->lf_group_level; + + /* Load symbols. */ + ld_file_load(ld, lf); + if (ls->ls_arch_conflict) { + ld_file_unload(ld, lf); + return; + } + _load_symbols(ld, lf); + ld_file_unload(ld, lf); + lf = TAILQ_NEXT(lf, lf_next); + } + + /* Print information regarding space allocated for common symbols. */ + if (ld->ld_print_linkmap) { + printf("\nCommon symbols:\n"); + printf("%-34s %-10s %s\n", "name", "size", "file"); + HASH_ITER(hh, ld->ld_sym, lsb, _lsb) { + if (lsb->lsb_shndx != SHN_COMMON) + continue; + printf("%-34s", lsb->lsb_name); + if (strlen(lsb->lsb_name) > 34) + printf("\n%-34s", ""); + printf(" %#-10jx %s\n", (uintmax_t) lsb->lsb_size, + ld_input_get_fullname(ld, lsb->lsb_input)); + } + } +} + +void +ld_symbols_update(struct ld *ld) +{ + struct ld_input *li; + struct ld_symbol *lsb, *_lsb; + + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + if (li->li_local == NULL) + continue; + STAILQ_FOREACH(lsb, li->li_local, lsb_next) + _update_symbol(lsb); + } + + HASH_ITER(hh, ld->ld_sym, lsb, _lsb) { + /* Skip symbols from DSOs. */ + if (ld_symbols_in_dso(lsb)) + continue; + + _update_symbol(lsb); + } +} + +void +ld_symbols_build_symtab(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os, *_os; + struct ld_input *li; + struct ld_input_section *is; + struct ld_symbol *lsb, *tmp, _lsb; + + lo = ld->ld_output; + + ld->ld_symtab = _alloc_symbol_table(ld); + ld->ld_strtab = ld_strtab_alloc(ld, 0); + + /* Create an initial symbol at the beginning of symbol table. */ + _lsb.lsb_name = NULL; + _lsb.lsb_size = 0; + _lsb.lsb_value = 0; + _lsb.lsb_shndx = SHN_UNDEF; + _lsb.lsb_bind = STB_LOCAL; + _lsb.lsb_type = STT_NOTYPE; + _lsb.lsb_other = 0; + _add_to_symbol_table(ld, &_lsb); + + /* Create STT_SECTION symbols. */ + STAILQ_FOREACH(os, &lo->lo_oslist, os_next) { + if (os->os_empty) + continue; + if (os->os_secsym != NULL) + continue; + if (os->os_rel) + continue; + os->os_secsym = calloc(1, sizeof(*os->os_secsym)); + if (os->os_secsym == NULL) + ld_fatal_std(ld, "calloc"); + os->os_secsym->lsb_name = NULL; + os->os_secsym->lsb_size = 0; + os->os_secsym->lsb_value = os->os_addr; + os->os_secsym->lsb_shndx = elf_ndxscn(os->os_scn); + os->os_secsym->lsb_bind = STB_LOCAL; + os->os_secsym->lsb_type = STT_SECTION; + os->os_secsym->lsb_other = 0; + _add_to_symbol_table(ld, os->os_secsym); + + /* Create STT_SECTION symbols for relocation sections. */ + if (os->os_r != NULL && !ld->ld_reloc) { + _os = os->os_r; + _os->os_secsym = calloc(1, sizeof(*_os->os_secsym)); + if (_os->os_secsym == NULL) + ld_fatal_std(ld, "calloc"); + _os->os_secsym->lsb_name = NULL; + _os->os_secsym->lsb_size = 0; + _os->os_secsym->lsb_value = _os->os_addr; + _os->os_secsym->lsb_shndx = elf_ndxscn(_os->os_scn); + _os->os_secsym->lsb_bind = STB_LOCAL; + _os->os_secsym->lsb_type = STT_SECTION; + _os->os_secsym->lsb_other = 0; + _add_to_symbol_table(ld, _os->os_secsym); + } + } + + /* Copy local symbols from each input object. */ + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + if (li->li_local == NULL) + continue; + STAILQ_FOREACH(lsb, li->li_local, lsb_next) { + if (lsb->lsb_type != STT_SECTION && + lsb->lsb_index != 0) + _add_to_symbol_table(ld, lsb); + + /* + * Set the symbol index of the STT_SECTION symbols + * to the index of the section symbol for the + * corresponding output section. The updated + * symbol index will be used by the relocation + * serialization function If the linker generates + * relocatable object or option -emit-relocs is + * specified. + */ + if (lsb->lsb_type == STT_SECTION) { + is = lsb->lsb_is; + if (is->is_output != NULL) { + os = is->is_output; + assert(os->os_secsym != NULL); + lsb->lsb_out_index = + os->os_secsym->lsb_out_index; + } + } + } + } + + /* Copy resolved global symbols from hash table. */ + HASH_ITER(hh, ld->ld_sym, lsb, tmp) { + + /* Skip undefined/unreferenced symbols from DSO. */ + if (ld_symbols_in_dso(lsb) && + (lsb->lsb_shndx == SHN_UNDEF || !lsb->lsb_ref_ndso)) + continue; + + /* + * Skip linker script defined symbols when creating + * relocatable output object. + */ + if (lsb->lsb_input == NULL && ld->ld_reloc) + continue; + + /* Skip "provide" symbols that are not referenced. */ + if (lsb->lsb_provide && lsb->lsb_prev == NULL) + continue; + + if (lsb->lsb_import) { + if (lsb->lsb_type == STT_FUNC && lsb->lsb_func_addr) + lsb->lsb_value = lsb->lsb_plt_off; + else + lsb->lsb_value = 0; + lsb->lsb_shndx = SHN_UNDEF; + } + + _add_to_symbol_table(ld, lsb); + } +} + +void +ld_symbols_scan(struct ld *ld) +{ + struct ld_symbol *lsb, *tmp; + + ld->ld_dynsym = _alloc_symbol_table(ld); + if (ld->ld_dynstr == NULL) + ld->ld_dynstr = ld_strtab_alloc(ld, 0); + + /* Reserve space for the initial symbol. */ + ld->ld_dynsym->sy_size++; + + HASH_ITER(hh, ld->ld_sym, lsb, tmp) { + + /* + * Warn undefined symbols if the linker is creating an + * executable. + */ + if ((ld->ld_exec || ld->ld_pie) && + lsb->lsb_shndx == SHN_UNDEF && + lsb->lsb_bind != STB_WEAK) + ld_warn(ld, "undefined symbol: %s", lsb->lsb_name); + + /* + * Allocate space for common symbols and add them to the + * special input section COMMON for section layout later. + */ + if (lsb->lsb_shndx == SHN_COMMON) + ld_input_alloc_common_symbol(ld, lsb); + + /* + * The code below handles the dynamic symbol table. If + * we are doing a -static linking, we can skip. + */ + if (!ld->ld_dynamic_link) + continue; + + /* + * Following symbols should not be added to the dynamic + * symbol table: + * + * 1. Do not add undefined symbols in DSOs. + */ + if (ld_symbols_in_dso(lsb) && lsb->lsb_shndx == SHN_UNDEF) + continue; + + /* + * Add following symbols to the dynamic symbol table: + * + * 1. A symbol that is defined in a regular object and + * referenced by a DSO. + * + * 2. A symbol that is defined in a DSO and referenced + * by a regular object. + * + * 3. A symbol that is referenced by a dynamic relocation. + * + * 4. The linker creates a DSO and the symbol is defined + * in a regular object and is visible externally. + * + */ + if (lsb->lsb_ref_dso && ld_symbols_in_regular(lsb)) + _add_to_dynsym_table(ld, lsb); + else if (lsb->lsb_ref_ndso && ld_symbols_in_dso(lsb)) { + lsb->lsb_import = 1; + lsb->lsb_input->li_dso_refcnt++; + ld_symver_add_verdef_refcnt(ld, lsb); + _add_to_dynsym_table(ld, lsb); + } else if (lsb->lsb_dynrel) + _add_to_dynsym_table(ld, lsb); + else if (ld->ld_dso && ld_symbols_in_regular(lsb) && + lsb->lsb_other == STV_DEFAULT && + ld_symver_search_version_script(ld, lsb) != 0) + + _add_to_dynsym_table(ld, lsb); + } +} + +void +ld_symbols_finalize_dynsym(struct ld *ld) +{ + struct ld_output *lo; + struct ld_symbol *lsb, _lsb; + + lo = ld->ld_output; + assert(lo != NULL); + + /* Create an initial symbol at the beginning of symbol table. */ + _lsb.lsb_name = NULL; + _lsb.lsb_nameindex = 0; + _lsb.lsb_size = 0; + _lsb.lsb_value = 0; + _lsb.lsb_shndx = SHN_UNDEF; + _lsb.lsb_bind = STB_LOCAL; + _lsb.lsb_type = STT_NOTYPE; + _lsb.lsb_other = 0; + _write_to_dynsym_table(ld, &_lsb); + + assert(ld->ld_dyn_symbols != NULL); + + STAILQ_FOREACH(lsb, ld->ld_dyn_symbols, lsb_dyn) { + if (lsb->lsb_import) { + memcpy(&_lsb, lsb, sizeof(_lsb)); + if (lsb->lsb_type == STT_FUNC && lsb->lsb_func_addr) + _lsb.lsb_value = lsb->lsb_plt_off; + else + _lsb.lsb_value = 0; + _lsb.lsb_shndx = SHN_UNDEF; + _write_to_dynsym_table(ld, &_lsb); + } else + _write_to_dynsym_table(ld, lsb); + } + + lo->lo_dynsym->os_info_val = ld->ld_dynsym->sy_first_nonlocal; +} + +/* + * Retrieve the resolved symbol. + */ +struct ld_symbol * +ld_symbols_ref(struct ld_symbol *lsb) +{ + + while (lsb->lsb_ref != NULL) + lsb = lsb->lsb_ref; + + return (lsb); +} + +/* + * Check if a symbol can be overriden (by symbols in main executable). + */ +int +ld_symbols_overridden(struct ld *ld, struct ld_symbol *lsb) +{ + + /* Symbols can be overridden only when we are creating a DSO. */ + if (!ld->ld_dso) + return (0); + + /* Only visible symbols can be overriden. */ + if (lsb->lsb_other != STV_DEFAULT) + return (0); + + /* + * Symbols converted to local by version script can not be + * overridden. + */ + if (ld_symver_search_version_script(ld, lsb) == 0) + return (0); + + /* TODO: other cases. */ + + /* Otherwise symbol can be overridden. */ + return (1); +} + +/* + * Check if a symbol is defined in regular object. + */ +int +ld_symbols_in_regular(struct ld_symbol *lsb) +{ + + return (lsb->lsb_input == NULL || lsb->lsb_input->li_type != LIT_DSO); +} + +/* + * Check if a symbol is defined in a DSO. + */ +int +ld_symbols_in_dso(struct ld_symbol *lsb) +{ + + return (lsb->lsb_input != NULL && lsb->lsb_input->li_type == LIT_DSO); +} + +static struct ld_symbol * +_alloc_symbol(struct ld *ld) +{ + struct ld_symbol *s; + + if ((s = calloc(1, sizeof(*s))) == NULL) + ld_fatal_std(ld, "calloc"); + + return (s); +} + +static struct ld_symbol * +_find_symbol(struct ld_symbol *tbl, char *name) +{ + struct ld_symbol *s; + + HASH_FIND_STR(tbl, name, s); + return (s); +} + +#define _prefer_new() do { \ + _resolve_symbol(_lsb, lsb); \ + _remove_symbol(ld->ld_sym, _lsb); \ + _add_symbol(ld->ld_sym, lsb); \ + } while (0) + +#define _prefer_old() _resolve_symbol(lsb, _lsb) + +#undef max +#define max(a, b) ((a) > (b) ? (a) : (b)) + +static void +_resolve_and_add_symbol(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_symbol *_lsb; + struct ld_symbol_defver *dv; + char *name, *sn; + + /* "long" name is a symbol name plus a symbol version string. */ + name = lsb->lsb_longname; + + /* "sn" stores the bare symbol name. */ + sn = lsb->lsb_name; + + /* + * Search in the symbol table for the symbol with the same name and + * same version. + */ + if ((_lsb = _find_symbol(ld->ld_sym, name)) != NULL) + goto found; + + /* + * If there is a default version recorded for the symbol name: + * + * 1. If the symbol to resolve doesn't have a version, search the + * symbol with the same name and with a default version. + * + * 2. If the symbol to resolve has the default version, search the + * symbol with the same name but without a version. + */ + HASH_FIND_STR(ld->ld_defver, sn, dv); + if (dv != NULL) { + if (!strcmp(name, sn)) { + if ((_lsb = _find_symbol(ld->ld_sym, + dv->dv_longname)) != NULL) + goto found; + } else if (!strcmp(name, dv->dv_longname)) { + if ((_lsb = _find_symbol(ld->ld_sym, sn)) != NULL) + goto found; + } + } + + /* + * This is *probably* a new symbol, add it to the symbol table + * and proceed. + * + * Note that if one symbol has a version but another one doesn't, + * and they are both undefined, there is still a chance that they are + * the same symbol. We will solve that when we see the definition. + */ + _add_symbol(ld->ld_sym, lsb); + + return; + +found: + + /* + * We found the same symbol in the symbol table. Now we should + * decide which symbol to resolve and which symbol to keep. + */ + + /* + * Verify both symbol has the same TLS (thread local storage) + * characteristics. + */ + if ((lsb->lsb_type == STT_TLS || _lsb->lsb_type == STT_TLS) && + lsb->lsb_type != _lsb->lsb_type) + ld_fatal(ld, "TLS symbol %s is non-TLS in another reference"); + + + /* + * If the symbol to resolve is undefined, we always resolve this + * symbol to the symbol that is already in the table, no matter it is + * defined or not. + */ + + if (lsb->lsb_shndx == SHN_UNDEF) { + _prefer_old(); + return; + } + + /* + * If the symbol to resolve is a common symbol and is defined in + * a regular object: + * + * 1. If the symbol in the table is undefined, we prefer the + * common symbol. + * + * 2. If both symbols are common symbols, we prefer the symbol + * already in the table. However if the symbol in the table + * is found in a DSO, we prefer the common symbol in regular + * object. The size of the symbol we decided to keep is set to + * the larger one of the two. + * + * 3. If the symbol in the table is defined, we prefer the + * defined symbol. However if the defined symbol is found + * in a DSO, we prefer the common symbol in regular object. + * + */ + + if (lsb->lsb_shndx == SHN_COMMON && ld_symbols_in_regular(lsb)) { + if (_lsb->lsb_shndx == SHN_UNDEF) + _prefer_new(); + else if (_lsb->lsb_shndx == SHN_COMMON) { + if (ld_symbols_in_dso(_lsb)) { + _prefer_new(); + lsb->lsb_size = max(lsb->lsb_size, + _lsb->lsb_size); + } else { + _prefer_old(); + _lsb->lsb_size = max(lsb->lsb_size, + _lsb->lsb_size); + } + } else { + if (ld_symbols_in_dso(_lsb)) + _prefer_new(); + else + _prefer_old(); + } + return; + } + + + /* + * If the symbol to resolve is a common symbol and is defined in + * a DSO: + * + * 1. If the symbol in the table is undefined, we prefer the common + * symbol. + * + * 2. If the symbol in the table is also a common symbol, we prefer + * the one in the table. The size of the symbol we decided to + * keep is set to the larger one of the two. + * + * 3. If the symbol in the table is defined, we prefer the defined + * symbol. + */ + + if (lsb->lsb_shndx == SHN_COMMON && ld_symbols_in_dso(lsb)) { + if (_lsb->lsb_shndx == SHN_UNDEF) + _prefer_new(); + else if (_lsb->lsb_shndx == SHN_COMMON) { + _prefer_old(); + _lsb->lsb_size = max(lsb->lsb_size, _lsb->lsb_size); + } else + _prefer_old(); + return; + } + + /* + * Now we know the symbol to resolve is a defined symbol. If it is + * defined in a regular object: + * + * 1. If the symbol in the table is undefined, we prefer the defined + * symbol. (no doubt!) + * + * 2. If the symbol in the table is a common symbol, we perfer the + * defined symbol. + * + * 3. If the symbol in the table is also a defined symbol, we need to + * consider: + * + * a) If the symbol in the table is also defined in a regular object, + * and both symbols are strong, we have a multi-definition error. + * If only one of them is strong, we pick that one. If both of them + * are weak, we pick the one that is already in the table. (fisrt + * seen). Another case is that if one of them is a "provide" symbol, + * we prefer the one that is not "provide". + * + * b) If the symbol in the table is defined in a DSO, we pick the one + * defined in the regular object. (no matter weak or strong!) + */ + + if (ld_symbols_in_regular(lsb)) { + if (_lsb->lsb_shndx == SHN_UNDEF || + _lsb->lsb_shndx == SHN_COMMON) + _prefer_new(); + else { + if (ld_symbols_in_regular(_lsb)) { + if (_lsb->lsb_provide && !lsb->lsb_provide) + _prefer_new(); + else if (lsb->lsb_bind == _lsb->lsb_bind) { + if (lsb->lsb_bind == STB_WEAK) + _prefer_old(); + else + ld_fatal(ld, "multiple " + "definition of symbol %s", + lsb->lsb_longname); + } else if (lsb->lsb_bind == STB_WEAK) + _prefer_old(); + else + _prefer_new(); + } else + _prefer_new(); + } + return; + } + + /* + * Last case, the symbol to resolve is a defined symbol in a DSO. + * + * 1. If the symbol in the table is undefined, we prefer the defined + * symbol. (no doubt!) + * + * 2. If the symbol in the table is a common symbol: if it is in a + * regular object and the defined DSO symbol is a function, we + * prefer the common symbol. For all the other cases, we prefer + * the defined symbol in the DSO. + * + * 3. If the symbol in the table is a defined symbol. We always pick + * the symbol already in the table. (no matter it's in regular + * object or DSO, strong or weak) + */ + + if (_lsb->lsb_shndx != SHN_UNDEF && _lsb->lsb_shndx != SHN_COMMON) + _prefer_old(); + else if (_lsb->lsb_shndx == SHN_COMMON && + ld_symbols_in_regular(_lsb) && lsb->lsb_type == STT_FUNC) + _prefer_old(); + else { + _prefer_new(); + + /* + * Now we added a defined symbol from DSO. Here we should + * check if the DSO symbol has a default symbol version. + * If so, we search the symbol table for the symbol with the + * same name but without a symbol version. If there is one, + * we resolve the found symbol to this newly added DSO symbol + * and remove the found symbol from the table. + */ + HASH_FIND_STR(ld->ld_defver, sn, dv); + if (dv != NULL) { + if ((_lsb = _find_symbol(ld->ld_sym, sn)) != NULL) { + _resolve_symbol(_lsb, lsb); + _remove_symbol(ld->ld_sym, _lsb); + } + } + } +} + +static void +_add_elf_symbol(struct ld *ld, struct ld_input *li, Elf *e, GElf_Sym *sym, + size_t strndx, int i) +{ + struct ld_symbol *lsb; + struct ld_symbol_defver *dv; + char *name; + int j, len, ndx; + unsigned char st_bind; + + if ((name = elf_strptr(e, strndx, sym->st_name)) == NULL) + return; + + /* + * First check if the section this symbol refers to is belong + * to a section group that has been removed. + */ + st_bind = GELF_ST_BIND(sym->st_info); + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_COMMON && + sym->st_shndx != SHN_ABS && sym->st_shndx < li->li_shnum - 1 && + li->li_is[sym->st_shndx].is_discard) { + st_bind = GELF_ST_BIND(sym->st_info); + if (st_bind == STB_GLOBAL || st_bind == STB_WEAK) { + /* + * For symbol with STB_GLOBAL or STB_WEAK binding, + * we convert it to an undefined symbol. + */ + sym->st_shndx = SHN_UNDEF; + } else { + /* + * Local symbols are discarded, if the section they + * refer to are removed. + */ + return; + } + } + + lsb = _alloc_symbol(ld); + + if ((lsb->lsb_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + lsb->lsb_value = sym->st_value; + lsb->lsb_size = sym->st_size; + lsb->lsb_bind = GELF_ST_BIND(sym->st_info); + lsb->lsb_type = GELF_ST_TYPE(sym->st_info); + lsb->lsb_other = sym->st_other; + lsb->lsb_shndx = sym->st_shndx; + lsb->lsb_index = i; + lsb->lsb_input = li; + lsb->lsb_ver = NULL; + + if (lsb->lsb_shndx != SHN_UNDEF && lsb->lsb_shndx != SHN_ABS) { + if (lsb->lsb_shndx == SHN_COMMON) + lsb->lsb_is = &li->li_is[li->li_shnum - 1]; + else { + assert(lsb->lsb_shndx < li->li_shnum - 1); + lsb->lsb_is = &li->li_is[lsb->lsb_shndx]; + } + } + + if (li->li_type == LIT_DSO) + lsb->lsb_ref_dso = 1; + else + lsb->lsb_ref_ndso = 1; + + /* Find out symbol version info. */ + j = 0; + if (li->li_file->lf_type == LFT_DSO && li->li_vername != NULL && + li->li_versym != NULL && (size_t) i < li->li_versym_sz) { + j = li->li_versym[i]; + ndx = j & ~0x8000; + if ((size_t) ndx < li->li_vername_sz) { + lsb->lsb_ver = li->li_vername[ndx]; +#if 0 + printf("symbol: %s ver: %s\n", lsb->lsb_name, + lsb->lsb_ver); +#endif + if (j >= 2 && (j & 0x8000) == 0 && + lsb->lsb_shndx != SHN_UNDEF) + lsb->lsb_default = 1; + } + } + + /* Build "long" symbol name which is used for hash key. */ + if (lsb->lsb_ver == NULL || j < 2) { + lsb->lsb_longname = strdup(lsb->lsb_name); + if (lsb->lsb_longname == NULL) + ld_fatal_std(ld, "strdup"); + } else { + len = strlen(lsb->lsb_name) + strlen(lsb->lsb_ver) + 2; + if ((lsb->lsb_longname = malloc(len)) == NULL) + ld_fatal_std(ld, "malloc"); + snprintf(lsb->lsb_longname, len, "%s@%s", lsb->lsb_name, + lsb->lsb_ver); + } + + /* Keep track of default versions. */ + if (lsb->lsb_default) { + if ((dv = calloc(1, sizeof(*dv))) == NULL) + ld_fatal(ld, "calloc"); + dv->dv_name = lsb->lsb_name; + dv->dv_longname = lsb->lsb_longname; + dv->dv_ver = lsb->lsb_ver; + HASH_ADD_KEYPTR(hh, ld->ld_defver, dv->dv_name, + strlen(dv->dv_name), dv); + } + + /* + * Insert symbol to input object internal symbol list and + * perform symbol resolving. + */ + ld_input_add_symbol(ld, li, lsb); + if (lsb->lsb_bind != STB_LOCAL) + _resolve_and_add_symbol(ld, lsb); +} + +static int +_archive_member_extracted(struct ld_archive *la, off_t off) +{ + struct ld_archive_member *_lam; + + HASH_FIND(hh, la->la_m, &off, sizeof(off), _lam); + if (_lam != NULL) + return (1); + + return (0); +} + +static struct ld_archive_member * +_extract_archive_member(struct ld *ld, struct ld_file *lf, + struct ld_archive *la, off_t off) +{ + Elf *e; + Elf_Arhdr *arhdr; + struct ld_archive_member *lam; + struct ld_input *li; + + if (elf_rand(lf->lf_elf, off) == 0) + ld_fatal(ld, "%s: elf_rand failed: %s", lf->lf_name, + elf_errmsg(-1)); + + if ((e = elf_begin(-1, ELF_C_READ, lf->lf_elf)) == NULL) + ld_fatal(ld, "%s: elf_begin failed: %s", lf->lf_name, + elf_errmsg(-1)); + + if ((arhdr = elf_getarhdr(e)) == NULL) + ld_fatal(ld, "%s: elf_getarhdr failed: %s", lf->lf_name, + elf_errmsg(-1)); + + /* Keep record of extracted members. */ + if ((lam = calloc(1, sizeof(*lam))) == NULL) + ld_fatal_std(ld, "calloc"); + + lam->lam_ar_name = strdup(lf->lf_name); + if (lam->lam_ar_name == NULL) + ld_fatal_std(ld, "strdup"); + + lam->lam_name = strdup(arhdr->ar_name); + if (lam->lam_name == NULL) + ld_fatal_std(ld, "strdup"); + + lam->lam_off = off; + + HASH_ADD(hh, la->la_m, lam_off, sizeof(lam->lam_off), lam); + + /* Allocate input object for this member. */ + li = ld_input_alloc(ld, lf, lam->lam_name); + li->li_lam = lam; + lam->lam_input = li; + + /* Load the symbols of this member. */ + _load_elf_symbols(ld, li, e); + + elf_end(e); + + return (lam); +} + +static void +_print_extracted_member(struct ld *ld, struct ld_archive_member *lam, + struct ld_symbol *lsb) +{ + struct ld_state *ls; + char *c1, *c2; + + ls = &ld->ld_state; + + if (!ls->ls_archive_mb_header) { + printf("Extracted archive members:\n\n"); + ls->ls_archive_mb_header = 1; + } + + c1 = ld_input_get_fullname(ld, lam->lam_input); + c2 = ld_input_get_fullname(ld, lsb->lsb_input); + + printf("%-30s", c1); + if (strlen(c1) >= 30) { + printf("\n%-30s", ""); + } + printf("%s (%s)\n", c2, lsb->lsb_name); +} + +static void +_load_archive_symbols(struct ld *ld, struct ld_file *lf) +{ + struct ld_state *ls; + struct ld_archive *la; + struct ld_archive_member *lam; + struct ld_symbol *lsb; + Elf_Arsym *as; + size_t c; + int extracted, i; + + assert(lf != NULL && lf->lf_type == LFT_ARCHIVE); + assert(lf->lf_ar != NULL); + + ls = &ld->ld_state; + la = lf->lf_ar; + if ((as = elf_getarsym(lf->lf_elf, &c)) == NULL) + ld_fatal(ld, "%s: elf_getarsym failed: %s", lf->lf_name, + elf_errmsg(-1)); + do { + extracted = 0; + for (i = 0; (size_t) i < c; i++) { + if (as[i].as_name == NULL) + break; + if (_archive_member_extracted(la, as[i].as_off)) + continue; + if ((lsb = _find_symbol(ld->ld_sym, as[i].as_name)) != + NULL) { + lam = _extract_archive_member(ld, lf, la, + as[i].as_off); + extracted = 1; + ls->ls_extracted[ls->ls_group_level] = 1; + if (ld->ld_print_linkmap) + _print_extracted_member(ld, lam, lsb); + } + } + } while (extracted); +} + +static void +_load_elf_symbols(struct ld *ld, struct ld_input *li, Elf *e) +{ + struct ld_input_section *is; + Elf_Scn *scn_sym, *scn_dynamic; + Elf_Scn *scn_versym, *scn_verneed, *scn_verdef; + Elf_Data *d; + GElf_Sym sym; + GElf_Shdr shdr; + size_t dyn_strndx, strndx; + int elferr, i; + + /* Load section list from input object. */ + ld_input_init_sections(ld, li, e); + + strndx = dyn_strndx = SHN_UNDEF; + scn_sym = scn_versym = scn_verneed = scn_verdef = scn_dynamic = NULL; + + for (i = 0; (uint64_t) i < li->li_shnum - 1; i++) { + is = &li->li_is[i]; + if (li->li_type == LIT_DSO) { + if (is->is_type == SHT_DYNSYM) { + scn_sym = elf_getscn(e, is->is_index); + strndx = is->is_link; + } else if (is->is_type == SHT_SUNW_versym) + scn_versym = elf_getscn(e, is->is_index); + else if (is->is_type == SHT_SUNW_verneed) + scn_verneed = elf_getscn(e, is->is_index); + else if (is->is_type == SHT_SUNW_verdef) + scn_verdef = elf_getscn(e, is->is_index); + else if (is->is_type == SHT_DYNAMIC) { + scn_dynamic = elf_getscn(e, is->is_index); + dyn_strndx = is->is_link; + } + } else { + if (is->is_type == SHT_SYMTAB) { + scn_sym = elf_getscn(e, is->is_index); + strndx = is->is_link; + } + } + } + + if (scn_sym == NULL || strndx == SHN_UNDEF) + return; + + ld_symver_load_symbol_version_info(ld, li, e, scn_versym, scn_verneed, + scn_verdef); + + if (scn_dynamic != NULL) + ld_dynamic_load_dso_dynamic(ld, li, e, scn_dynamic, + dyn_strndx); + + if (gelf_getshdr(scn_sym, &shdr) != &shdr) { + ld_warn(ld, "%s: gelf_getshdr failed: %s", li->li_name, + elf_errmsg(-1)); + return; + } + + (void) elf_errno(); + if ((d = elf_getdata(scn_sym, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_warn(ld, "%s: elf_getdata failed: %s", li->li_name, + elf_errmsg(elferr)); + /* Empty symbol table section? */ + return; + } + + li->li_symnum = d->d_size / shdr.sh_entsize; + for (i = 0; (uint64_t) i < li->li_symnum; i++) { + if (gelf_getsym(d, i, &sym) != &sym) + ld_warn(ld, "%s: gelf_getsym failed: %s", li->li_name, + elf_errmsg(-1)); + _add_elf_symbol(ld, li, e, &sym, strndx, i); + } + +} + +static void +_load_symbols(struct ld *ld, struct ld_file *lf) +{ + + if (lf->lf_type == LFT_ARCHIVE) + _load_archive_symbols(ld, lf); + else { + lf->lf_input = ld_input_alloc(ld, lf, lf->lf_name); + _load_elf_symbols(ld, lf->lf_input, lf->lf_elf); + } +} + +static void +_unload_symbols(struct ld_input *li) +{ + int i; + + if (li->li_symindex == NULL) + return; + + for (i = 0; (uint64_t) i < li->li_symnum; i++) + _free_symbol(li->li_symindex[i]); +} + +static void +_free_symbol(struct ld_symbol *lsb) +{ + + if (lsb == NULL) + return; + + free(lsb->lsb_name); + free(lsb->lsb_longname); + free(lsb); +} + +static void +_update_symbol(struct ld_symbol *lsb) +{ + struct ld_input_section *is; + struct ld_output_section *os; + + if (lsb->lsb_preset_os != NULL) { + lsb->lsb_value = lsb->lsb_preset_os->os_addr; + lsb->lsb_shndx = elf_ndxscn(lsb->lsb_preset_os->os_scn); + return; + } + + if (lsb->lsb_shndx == SHN_ABS) + return; + + if (lsb->lsb_input != NULL) { + is = lsb->lsb_is; + if (is == NULL || (os = is->is_output) == NULL) + return; + lsb->lsb_value += os->os_addr + is->is_reloff; + lsb->lsb_shndx = elf_ndxscn(os->os_scn); + } +} + +struct ld_symbol_table * +_alloc_symbol_table(struct ld *ld) +{ + struct ld_symbol_table *symtab; + + if ((symtab = calloc(1, sizeof(*ld->ld_symtab))) == NULL) + ld_fatal_std(ld, "calloc"); + + return (symtab); +} + +static void +_add_to_dynsym_table(struct ld *ld, struct ld_symbol *lsb) +{ + + assert(ld->ld_dynsym != NULL && ld->ld_dynstr != NULL); + + if (ld->ld_dyn_symbols == NULL) { + ld->ld_dyn_symbols = malloc(sizeof(*ld->ld_dyn_symbols)); + if (ld->ld_dyn_symbols == NULL) + ld_fatal_std(ld, "malloc"); + STAILQ_INIT(ld->ld_dyn_symbols); + } + STAILQ_INSERT_TAIL(ld->ld_dyn_symbols, lsb, lsb_dyn); + + lsb->lsb_nameindex = ld_strtab_insert_no_suffix(ld, ld->ld_dynstr, + lsb->lsb_name); + + lsb->lsb_dyn_index = ld->ld_dynsym->sy_size++; +} + +static void +_write_to_dynsym_table(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_output *lo; + struct ld_symbol_table *symtab; + Elf32_Sym *s32; + Elf64_Sym *s64; + size_t es; + + assert(lsb != NULL); + assert(ld->ld_dynsym != NULL && ld->ld_dynstr != NULL); + symtab = ld->ld_dynsym; + + lo = ld->ld_output; + assert(lo != NULL); + + es = (lo->lo_ec == ELFCLASS32) ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym); + + /* Allocate buffer for the dynsym table. */ + if (symtab->sy_buf == NULL) { + symtab->sy_buf = malloc(symtab->sy_size * es); + symtab->sy_write_pos = 0; + } + + if (lo->lo_ec == ELFCLASS32) { + s32 = symtab->sy_buf; + s32 += symtab->sy_write_pos; + s32->st_name = lsb->lsb_nameindex; + s32->st_info = ELF32_ST_INFO(lsb->lsb_bind, lsb->lsb_type); + s32->st_other = lsb->lsb_other; + s32->st_shndx = lsb->lsb_shndx; + s32->st_value = lsb->lsb_value; + s32->st_size = lsb->lsb_size; + } else { + s64 = symtab->sy_buf; + s64 += symtab->sy_write_pos; + s64->st_name = lsb->lsb_nameindex; + s64->st_info = ELF64_ST_INFO(lsb->lsb_bind, lsb->lsb_type); + s64->st_other = lsb->lsb_other; + s64->st_shndx = lsb->lsb_shndx; + s64->st_value = lsb->lsb_value; + s64->st_size = lsb->lsb_size; + } + + /* Remember the index for the first non-local symbol. */ + if (symtab->sy_first_nonlocal == 0 && lsb->lsb_bind != STB_LOCAL) + symtab->sy_first_nonlocal = symtab->sy_write_pos; + + symtab->sy_write_pos++; +} + +static void +_add_to_symbol_table(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_output *lo; + struct ld_symbol_table *symtab; + struct ld_strtab *strtab; + Elf32_Sym *s32; + Elf64_Sym *s64; + size_t es; + + assert(lsb != NULL); + assert(ld->ld_symtab != NULL && ld->ld_strtab != NULL); + symtab = ld->ld_symtab; + strtab = ld->ld_strtab; + + lo = ld->ld_output; + assert(lo != NULL); + + es = (lo->lo_ec == ELFCLASS32) ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym); + + /* Allocate/Reallocate buffer for the symbol table. */ + if (symtab->sy_buf == NULL) { + symtab->sy_size = 0; + symtab->sy_cap = _INIT_SYMTAB_SIZE; + symtab->sy_buf = malloc(symtab->sy_cap * es); + if (symtab->sy_buf == NULL) + ld_fatal_std(ld, "malloc"); + } else if (symtab->sy_size >= symtab->sy_cap) { + symtab->sy_cap *= 2; + symtab->sy_buf = realloc(symtab->sy_buf, symtab->sy_cap * es); + if (symtab->sy_buf == NULL) + ld_fatal_std(ld, "relloc"); + } + + /* + * Insert the symbol into the symbol table and the symbol name to + * the assoicated name string table. + */ + lsb->lsb_nameindex = ld_strtab_insert_no_suffix(ld, strtab, + lsb->lsb_name); + if (lo->lo_ec == ELFCLASS32) { + s32 = symtab->sy_buf; + s32 += symtab->sy_size; + s32->st_name = lsb->lsb_nameindex; + s32->st_info = ELF32_ST_INFO(lsb->lsb_bind, lsb->lsb_type); + s32->st_other = lsb->lsb_other; + s32->st_shndx = lsb->lsb_shndx; + s32->st_value = lsb->lsb_value; + s32->st_size = lsb->lsb_size; + } else { + s64 = symtab->sy_buf; + s64 += symtab->sy_size; + s64->st_name = lsb->lsb_nameindex; + s64->st_info = ELF64_ST_INFO(lsb->lsb_bind, lsb->lsb_type); + s64->st_other = lsb->lsb_other; + s64->st_shndx = lsb->lsb_shndx; + s64->st_value = lsb->lsb_value; + s64->st_size = lsb->lsb_size; + } + + /* Remember the index for the first non-local symbol. */ + if (symtab->sy_first_nonlocal == 0 && lsb->lsb_bind != STB_LOCAL) + symtab->sy_first_nonlocal = symtab->sy_size; + + lsb->lsb_out_index = symtab->sy_size; + symtab->sy_size++; +} + +static void +_free_symbol_table(struct ld_symbol_table *symtab) +{ + + if (symtab == NULL) + return; + + free(symtab->sy_buf); + free(symtab); +} diff --git a/contrib/elftoolchain/ld/ld_symbols.h b/contrib/elftoolchain/ld/ld_symbols.h new file mode 100644 index 0000000000..a0466373f6 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_symbols.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_symbols.h 2882 2013-01-09 22:47:04Z kaiwang27 $ + */ + +struct ld_symver_verdef; + +struct ld_symbol { + char *lsb_name; /* symbol name */ + uint64_t lsb_nameindex; /* symbol name index */ + char *lsb_ver; /* symbol version */ + char *lsb_longname; /* symbol name+version (as hash key)*/ + uint64_t lsb_size; /* symbol size */ + uint64_t lsb_value; /* symbol value */ + uint16_t lsb_shndx; /* symbol section index */ + uint64_t lsb_index; /* symbol index */ + uint64_t lsb_dyn_index; /* dynamic symbol index */ + uint64_t lsb_out_index; /* symbol index (in output) */ + uint64_t lsb_got_off; /* got entry offset */ + uint64_t lsb_plt_off; /* plt entry offset */ + struct ld_script_variable *lsb_var; /* associated ldscript variable */ + unsigned char lsb_bind; /* symbol binding */ + unsigned char lsb_type; /* symbol type */ + unsigned char lsb_other; /* symbol visibility */ + unsigned char lsb_default; /* symbol is default/only version */ + unsigned char lsb_provide; /* provide symbol */ + unsigned char lsb_import; /* symbol is a import symbol */ + unsigned char lsb_ref_dso; /* symbol appeared in a DSO */ + unsigned char lsb_ref_ndso; /* symbol appeared in elsewhere */ + unsigned char lsb_dynrel; /* symbol used by dynamic reloc */ + unsigned char lsb_copy_reloc; /* symbol has copy reloc */ + unsigned char lsb_got; /* symbol has got entry */ + unsigned char lsb_plt; /* symbol has plt entry */ + unsigned char lsb_func_addr; /* symbol(function) has address */ + unsigned char lsb_tls_ld; /* local dynamic TLS symbol */ + unsigned char lsb_vndx_known; /* version index is known */ + uint16_t lsb_vndx; /* version index */ + struct ld_symver_verdef *lsb_vd; /* version definition */ + struct ld_symbol *lsb_prev; /* symbol resolved by this symbol */ + struct ld_symbol *lsb_ref; /* this symbol resolves to ... */ + struct ld_input *lsb_input; /* containing input object */ + struct ld_input_section *lsb_is; /* containing input section */ + struct ld_output_section *lsb_preset_os; /* Preset output section */ + UT_hash_handle hh; /* hash handle */ + STAILQ_ENTRY(ld_symbol) lsb_next; /* next symbol */ + STAILQ_ENTRY(ld_symbol) lsb_dyn; /* next dynamic symbol */ +}; + +STAILQ_HEAD(ld_symbol_head, ld_symbol); + +struct ld_symbol_table { + void *sy_buf; + size_t sy_cap; + size_t sy_size; + size_t sy_first_nonlocal; + size_t sy_write_pos; +}; + +struct ld_symbol_defver { + char *dv_name; + char *dv_longname; + char *dv_ver; + UT_hash_handle hh; +}; + +void ld_symbols_add_extern(struct ld *, char *); +void ld_symbols_add_variable(struct ld *, struct ld_script_variable *, + unsigned, unsigned); +void ld_symbols_add_internal(struct ld *, const char *, uint64_t, uint64_t, + uint16_t, unsigned char, unsigned char, unsigned char, + struct ld_input_section *, struct ld_output_section *); +void ld_symbols_build_symtab(struct ld *); +void ld_symbols_cleanup(struct ld *); +void ld_symbols_scan(struct ld *); +void ld_symbols_finalize_dynsym(struct ld *); +int ld_symbols_get_value(struct ld *, char *, uint64_t *); +void ld_symbols_resolve(struct ld *); +void ld_symbols_update(struct ld *); +struct ld_symbol *ld_symbols_ref(struct ld_symbol *); +int ld_symbols_overridden(struct ld *, struct ld_symbol *); +int ld_symbols_in_dso(struct ld_symbol *); +int ld_symbols_in_regular(struct ld_symbol *); diff --git a/contrib/elftoolchain/ld/ld_symver.c b/contrib/elftoolchain/ld/ld_symver.c new file mode 100644 index 0000000000..e45e87aa56 --- /dev/null +++ b/contrib/elftoolchain/ld/ld_symver.c @@ -0,0 +1,854 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_input.h" +#include "ld_layout.h" +#include "ld_output.h" +#include "ld_script.h" +#include "ld_symbols.h" +#include "ld_symver.h" +#include "ld_strtab.h" + +ELFTC_VCSID("$Id: ld_symver.c 2917 2013-02-16 07:16:02Z kaiwang27 $"); + +/* + * Symbol versioning sections are the same for 32bit and 64bit + * ELF objects. + */ +#define Elf_Verdef Elf32_Verdef +#define Elf_Verdaux Elf32_Verdaux +#define Elf_Verneed Elf32_Verneed +#define Elf_Vernaux Elf32_Vernaux + +static void _add_version_name(struct ld *ld, struct ld_input *li, int ndx, + const char *name); +static struct ld_symver_vda *_alloc_vda(struct ld *ld, const char *name, + struct ld_symver_verdef *svd); +static struct ld_symver_vna *_alloc_vna(struct ld *ld, const char *name, + struct ld_symver_verneed *svn); +static struct ld_symver_verdef *_alloc_verdef(struct ld *ld, + struct ld_symver_verdef_head *head); +static struct ld_symver_verneed *_alloc_verneed(struct ld *ld, + struct ld_input *li, struct ld_symver_verneed_head *head); +static struct ld_symver_verdef *_load_verdef(struct ld *ld, + struct ld_input *li, Elf_Verdef *vd); +static void _load_verdef_section(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *verdef); +static void _load_verneed_section(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *verneed); + +void +ld_symver_load_symbol_version_info(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *versym, Elf_Scn *verneed, Elf_Scn *verdef) +{ + Elf_Data *d_vs; + int elferr; + + if (versym == NULL) + return; + + (void) elf_errno(); + if ((d_vs = elf_getdata(versym, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_fatal(ld, "%s: elf_getdata failed: %s", li->li_name, + elf_errmsg(elferr)); + return; + } + if (d_vs->d_size == 0) + return; + + if ((li->li_versym = malloc(d_vs->d_size)) == NULL) + ld_fatal_std(ld, "malloc"); + memcpy(li->li_versym, d_vs->d_buf, d_vs->d_size); + li->li_versym_sz = d_vs->d_size / sizeof(uint16_t); + + _add_version_name(ld, li, 0, "*local*"); + _add_version_name(ld, li, 1, "*global*"); + + if (verneed != NULL) + _load_verneed_section(ld, li, e, verneed); + + if (verdef != NULL) + _load_verdef_section(ld, li, e, verdef); +} + +void +ld_symver_create_verneed_section(struct ld *ld) +{ + struct ld_input *li; + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_data_buffer *odb; + struct ld_symver_verdef *svd; + struct ld_symver_verneed *svn; + struct ld_symver_vda *sda; + struct ld_symver_vna *sna; + char verneed_name[] = ".gnu.version_r"; + Elf_Verneed *vn; + Elf_Vernaux *vna; + uint8_t *buf, *buf2, *end; + size_t sz; + + lo = ld->ld_output; + assert(lo != NULL); + assert(lo->lo_dynstr != NULL); + + /* + * Create .gnu.version_r section. + */ + HASH_FIND_STR(lo->lo_ostbl, verneed_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, verneed_name, + SHF_ALLOC); + os->os_type = SHT_GNU_verneed; + os->os_flags = SHF_ALLOC; + os->os_entsize = 0; + if (lo->lo_ec == ELFCLASS32) + os->os_align = 4; + else + os->os_align = 8; + + if ((os->os_link = strdup(".dynstr")) == NULL) + ld_fatal_std(ld, "strdup"); + + lo->lo_verneed = os; + + /* + * Build Verneed/Vernaux structures. + */ + sz = 0; + STAILQ_FOREACH(li, &ld->ld_lilist, li_next) { + if (li->li_type != LIT_DSO || li->li_dso_refcnt == 0 || + li->li_verdef == NULL) + continue; + + svn = NULL; + STAILQ_FOREACH(svd, li->li_verdef, svd_next) { + if (svd->svd_flags & VER_FLG_BASE) + continue; + + /* Skip version definition that is never ref'ed. */ + if (svd->svd_ref == 0) + continue; + + /* Invalid Verdef? */ + if ((sda = STAILQ_FIRST(&svd->svd_aux)) == NULL) + continue; + + if (lo->lo_vnlist == NULL) { + lo->lo_vnlist = calloc(1, + sizeof(*lo->lo_vnlist)); + if (lo->lo_vnlist == NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(lo->lo_vnlist); + } + + /* Allocate Verneed entry. */ + if (svn == NULL) { + svn = _alloc_verneed(ld, li, lo->lo_vnlist); + svn->svn_version = VER_NEED_CURRENT; + svn->svn_cnt = 0; + svn->svn_fileindex = + ld_strtab_insert_no_suffix(ld, + ld->ld_dynstr, svn->svn_file); + sz += sizeof(Elf_Verneed); + lo->lo_verneed_num++; + } + + /* Allocate Vernaux entry. */ + sna = _alloc_vna(ld, sda->sda_name, svn); + sna->sna_other = lo->lo_version_index++; + sna->sna_nameindex = ld_strtab_insert_no_suffix(ld, + ld->ld_dynstr, sna->sna_name); + /* TODO: flags? VER_FLG_WEAK */ + svn->svn_cnt++; + + sz += sizeof(Elf_Vernaux); + + /* + * Store the index in Verdef structure, so later we can + * quickly find the version index for a dynamic symbol, + * when we build the .gnu.version section. + */ + svd->svd_ndx_output = sna->sna_other; + } + } + + if (lo->lo_verneed_num == 0) + return; + + /* Store the number of verneed entries in the sh_info field. */ + os->os_info_val = lo->lo_verneed_num; + + /* + * Write Verneed/Vernaux structures. + */ + if ((buf = malloc(sz)) == NULL) + ld_fatal_std(ld, "malloc"); + + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + + odb->odb_buf = buf; + odb->odb_size = sz; + odb->odb_align = os->os_align; + odb->odb_type = ELF_T_VNEED; /* enable libelf translation */ + + end = buf + sz; + vn = NULL; + STAILQ_FOREACH(svn, lo->lo_vnlist, svn_next){ + vn = (Elf_Verneed *) (uintptr_t) buf; + vn->vn_version = VER_NEED_CURRENT; + vn->vn_cnt = svn->svn_cnt; + vn->vn_file = svn->svn_fileindex; + vn->vn_aux = sizeof(Elf_Verneed); + vn->vn_next = sizeof(Elf_Verneed) + + svn->svn_cnt * sizeof(Elf_Vernaux); + + /* + * Write Vernaux entries. + */ + buf2 = buf + sizeof(Elf_Verneed); + vna = NULL; + STAILQ_FOREACH(sna, &svn->svn_aux, sna_next) { + vna = (Elf_Vernaux *) (uintptr_t) buf2; + vna->vna_hash = sna->sna_hash; + vna->vna_flags = 0; /* TODO: VER_FLG_WEAK? */ + vna->vna_other = sna->sna_other; + vna->vna_name = sna->sna_nameindex; + vna->vna_next = sizeof(Elf_Vernaux); + buf2 += sizeof(Elf_Vernaux); + } + + /* Set last Vernaux entry's vna_next to 0. */ + if (vna != NULL) + vna->vna_next = 0; + + buf += vn->vn_next; + } + + /* Set last Verneed entry's vn_next to 0 */ + if (vn != NULL) + vn->vn_next = 0; + + assert(buf == end); + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, + odb, NULL); +} + +void +ld_symver_create_verdef_section(struct ld *ld) +{ + struct ld_script *lds; + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_data_buffer *odb; + struct ld_script_version_node *ldvn; + char verdef_name[] = ".gnu.version_d"; + Elf_Verdef *vd; + Elf_Verdaux *vda; + uint8_t *buf, *end; + char *soname; + size_t sz; + + lo = ld->ld_output; + assert(lo != NULL); + assert(lo->lo_dynstr != NULL); + + lds = ld->ld_scp; + if (STAILQ_EMPTY(&lds->lds_vn)) + return; + + /* + * Create .gnu.version_d section. + */ + HASH_FIND_STR(lo->lo_ostbl, verdef_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, verdef_name, + SHF_ALLOC); + os->os_type = SHT_GNU_verdef; + os->os_flags = SHF_ALLOC; + os->os_entsize = 0; + if (lo->lo_ec == ELFCLASS32) + os->os_align = 4; + else + os->os_align = 8; + + if ((os->os_link = strdup(".dynstr")) == NULL) + ld_fatal_std(ld, "strdup"); + + lo->lo_verdef = os; + + /* + * Calculate verdef section size: .gnu.version_d section consists + * of one file version entry and several symbol version definition + * entries (with corresponding) auxiliary entries. + */ + lo->lo_verdef_num = 1; + sz = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux); + STAILQ_FOREACH(ldvn, &lds->lds_vn, ldvn_next) { + sz += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux); + if (ldvn->ldvn_dep != NULL) + sz += sizeof(Elf_Verdaux); + lo->lo_verdef_num++; + } + + /* Store the number of verdef entries in the sh_info field. */ + os->os_info_val = lo->lo_verdef_num; + + /* Allocate buffer for Verdef/Verdaux entries. */ + if ((buf = malloc(sz)) == NULL) + ld_fatal_std(ld, "malloc"); + + end = buf + sz; + + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + + odb->odb_buf = buf; + odb->odb_size = sz; + odb->odb_align = os->os_align; + odb->odb_type = ELF_T_VDEF; /* enable libelf translation */ + + /* + * Set file version name to `soname' if it is provided, + * otherwise set version name to output file name. + */ + if (ld->ld_soname != NULL) + soname = ld->ld_soname; + else { + if ((soname = strrchr(ld->ld_output_file, '/')) == NULL) + soname = ld->ld_output_file; + else + soname++; + } + + /* Write file version entry. */ + vd = (Elf_Verdef *) (uintptr_t) buf; + vd->vd_version = VER_DEF_CURRENT; + vd->vd_flags |= VER_FLG_BASE; + vd->vd_ndx = 1; + vd->vd_cnt = 1; + vd->vd_hash = elf_hash(soname); + vd->vd_aux = sizeof(Elf_Verdef); + vd->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux); + buf += sizeof(Elf_Verdef); + + /* Write file version auxiliary entry. */ + vda = (Elf_Verdaux *) (uintptr_t) buf; + vda->vda_name = ld_strtab_insert_no_suffix(ld, ld->ld_dynstr, + soname); + vda->vda_next = 0; + buf += sizeof(Elf_Verdaux); + + /* Write symbol version definition entries. */ + STAILQ_FOREACH(ldvn, &lds->lds_vn, ldvn_next) { + vd = (Elf_Verdef *) (uintptr_t) buf; + vd->vd_version = VER_DEF_CURRENT; + vd->vd_flags = 0; + vd->vd_ndx = lo->lo_version_index++; + vd->vd_cnt = (ldvn->ldvn_dep == NULL) ? 1 : 2; + vd->vd_hash = elf_hash(ldvn->ldvn_name); + vd->vd_aux = sizeof(Elf_Verdef); + if (STAILQ_NEXT(ldvn, ldvn_next) == NULL) + vd->vd_next = 0; + else + vd->vd_next = sizeof(Elf_Verdef) + + ((ldvn->ldvn_dep == NULL) ? 1 : 2) * + sizeof(Elf_Verdaux); + buf += sizeof(Elf_Verdef); + + /* Write version name auxiliary entry. */ + vda = (Elf_Verdaux *) (uintptr_t) buf; + vda->vda_name = ld_strtab_insert_no_suffix(ld, ld->ld_dynstr, + ldvn->ldvn_name); + vda->vda_next = ldvn->ldvn_dep == NULL ? 0 : + sizeof(Elf_Verdaux); + buf += sizeof(Elf_Verdaux); + + if (ldvn->ldvn_dep == NULL) + continue; + + /* Write version dependency auxiliary entry. */ + vda = (Elf_Verdaux *) (uintptr_t) buf; + vda->vda_name = ld_strtab_insert_no_suffix(ld, ld->ld_dynstr, + ldvn->ldvn_dep); + vda->vda_next = 0; + buf += sizeof(Elf_Verdaux); + } + + assert(buf == end); + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, + odb, NULL); +} + +void +ld_symver_create_versym_section(struct ld *ld) +{ + struct ld_output *lo; + struct ld_output_section *os; + struct ld_output_data_buffer *odb; + struct ld_symbol *lsb; + char versym_name[] = ".gnu.version"; + uint16_t *buf; + size_t sz; + int i; + + lo = ld->ld_output; + assert(lo != NULL); + assert(lo->lo_dynsym != NULL); + assert(ld->ld_dynsym != NULL); + + /* + * Create .gnu.version section. + */ + HASH_FIND_STR(lo->lo_ostbl, versym_name, os); + if (os == NULL) + os = ld_layout_insert_output_section(ld, versym_name, + SHF_ALLOC); + os->os_type = SHT_GNU_versym; + os->os_flags = SHF_ALLOC; + os->os_entsize = 2; + os->os_align = 2; + + if ((os->os_link = strdup(".dynsym")) == NULL) + ld_fatal_std(ld, "strdup"); + + lo->lo_versym = os; + + /* + * Write versym table. + */ + sz = ld->ld_dynsym->sy_size * sizeof(*buf); + if ((buf = malloc(sz)) == NULL) + ld_fatal_std(ld, "malloc"); + + buf[0] = 0; /* special index 0 symbol */ + i = 1; + STAILQ_FOREACH(lsb, ld->ld_dyn_symbols, lsb_dyn) { + /* + * Assign version index according to the following rules: + * + * 1. If the symbol is local, the version is *local*. + * + * 2. If the symbol is defined in shared libraries and there + * exists a version definition for this symbol, use the + * version defined by the shared library. + * + * 3. If the symbol is defined in regular objects and the + * linker creates a shared library, use the version + * defined in the version script, if provided. + * + * 4. Otherwise, the version is *global*. + */ + if (lsb->lsb_bind == STB_LOCAL) + buf[i] = 0; /* Version is *local* */ + else if (lsb->lsb_vd != NULL) + buf[i] = lsb->lsb_vd->svd_ndx_output; + else if (ld->ld_dso && ld_symbols_in_regular(lsb)) + buf[i] = ld_symver_search_version_script(ld, lsb); + else { + buf[i] = 1; /* Version is *global* */ + } + i++; + } + assert((size_t) i == ld->ld_dynsym->sy_size); + + if ((odb = calloc(1, sizeof(*odb))) == NULL) + ld_fatal_std(ld, "calloc"); + + odb->odb_buf = (void *) buf; + odb->odb_size = sz; + odb->odb_align = os->os_align; + odb->odb_type = ELF_T_HALF; /* enable libelf translation */ + + (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, + odb, NULL); +} + +void +ld_symver_add_verdef_refcnt(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_symbol_defver *dv; + struct ld_symver_verdef *svd; + struct ld_symver_vda *sda; + struct ld_input *li; + const char *ver; + + li = lsb->lsb_input; + assert(li != NULL); + + if (li->li_verdef == NULL) + return; + + if (lsb->lsb_ver != NULL) + ver = lsb->lsb_ver; + else { + HASH_FIND_STR(ld->ld_defver, lsb->lsb_name, dv); + if (dv == NULL || dv->dv_ver == NULL) + return; + ver = dv->dv_ver; + } + + STAILQ_FOREACH(svd, li->li_verdef, svd_next) { + if (svd->svd_flags & VER_FLG_BASE) + continue; + + /* Invalid Verdef? */ + if ((sda = STAILQ_FIRST(&svd->svd_aux)) == NULL) + continue; + + if (!strcmp(ver, sda->sda_name)) + break; + } + + if (svd != NULL) { + svd->svd_ref++; + lsb->lsb_vd = svd; + } +} + +static void +_add_version_name(struct ld *ld, struct ld_input *li, int ndx, + const char *name) +{ + int i; + + assert(name != NULL); + + if (ndx <= 1) + return; + + if (li->li_vername == NULL) { + li->li_vername_sz = 10; + li->li_vername = calloc(li->li_vername_sz, + sizeof(*li->li_vername)); + if (li->li_vername == NULL) + ld_fatal_std(ld, "calloc"); + } + + if ((size_t) ndx >= li->li_vername_sz) { + li->li_vername = realloc(li->li_vername, + sizeof(*li->li_vername) * li->li_vername_sz * 2); + if (li->li_vername == NULL) + ld_fatal_std(ld, "realloc"); + for (i = li->li_vername_sz; (size_t) i < li->li_vername_sz * 2; + i++) + li->li_vername[i] = NULL; + li->li_vername_sz *= 2; + } + + if (li->li_vername[ndx] == NULL) { + li->li_vername[ndx] = strdup(name); + if (li->li_vername[ndx] == NULL) + ld_fatal_std(ld, "strdup"); + } +} + +static struct ld_symver_vna * +_alloc_vna(struct ld *ld, const char *name, struct ld_symver_verneed *svn) +{ + struct ld_symver_vna *sna; + + assert(name != NULL); + + if ((sna = calloc(1, sizeof(*sna))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((sna->sna_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + sna->sna_hash = (uint32_t) elf_hash(sna->sna_name); + + if (svn != NULL) + STAILQ_INSERT_TAIL(&svn->svn_aux, sna, sna_next); + + return (sna); +} + +static struct ld_symver_vda * +_alloc_vda(struct ld *ld, const char *name, struct ld_symver_verdef *svd) +{ + struct ld_symver_vda *sda; + + if ((sda = calloc(1, sizeof(*sda))) == NULL) + ld_fatal_std(ld, "calloc"); + + if ((sda->sda_name = strdup(name)) == NULL) + ld_fatal_std(ld, "strdup"); + + if (svd != NULL) + STAILQ_INSERT_TAIL(&svd->svd_aux, sda, sda_next); + + return (sda); +} + +static struct ld_symver_verneed * +_alloc_verneed(struct ld *ld, struct ld_input *li, + struct ld_symver_verneed_head *head) +{ + struct ld_symver_verneed *svn; + const char *bn; + + if ((svn = calloc(1, sizeof(*svn))) == NULL) + ld_fatal_std(ld, "calloc"); + + if (li->li_soname != NULL) + bn = li->li_soname; + else { + if ((bn = strrchr(li->li_name, '/')) == NULL) + bn = li->li_name; + else + bn++; + } + + if ((svn->svn_file = strdup(bn)) == NULL) + ld_fatal_std(ld, "strdup"); + + STAILQ_INIT(&svn->svn_aux); + + if (head != NULL) + STAILQ_INSERT_TAIL(head, svn, svn_next); + + return (svn); +} + +static struct ld_symver_verdef * +_alloc_verdef(struct ld *ld, struct ld_symver_verdef_head *head) +{ + struct ld_symver_verdef *svd; + + if ((svd = calloc(1, sizeof(*svd))) == NULL) + ld_fatal_std(ld, "calloc"); + + STAILQ_INIT(&svd->svd_aux); + + if (head != NULL) + STAILQ_INSERT_TAIL(head, svd, svd_next); + + return (svd); +} + +static void +_load_verneed_section(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *verneed) +{ + Elf_Data *d_vn; + Elf_Verneed *vn; + Elf_Vernaux *vna; + GElf_Shdr sh_vn; + uint8_t *buf, *end, *buf2; + char *name; + int elferr, i; + + if (gelf_getshdr(verneed, &sh_vn) != &sh_vn) + ld_fatal(ld, "%s: gelf_getshdr failed: %s", li->li_name, + elf_errmsg(-1)); + + (void) elf_errno(); + if ((d_vn = elf_getdata(verneed, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_fatal(ld, "%s: elf_getdata failed: %s", li->li_name, + elf_errmsg(elferr)); + return; + } + if (d_vn->d_size == 0) + return; + + buf = d_vn->d_buf; + end = buf + d_vn->d_size; + while (buf + sizeof(Elf_Verneed) <= end) { + vn = (Elf_Verneed *) (uintptr_t) buf; + buf2 = buf + vn->vn_aux; + i = 0; + while (buf2 + sizeof(Elf_Vernaux) <= end && i < vn->vn_cnt) { + vna = (Elf32_Vernaux *) (uintptr_t) buf2; + name = elf_strptr(e, sh_vn.sh_link, + vna->vna_name); + if (name != NULL) + _add_version_name(ld, li, (int) vna->vna_other, + name); + buf2 += vna->vna_next; + i++; + } + if (vn->vn_next == 0) + break; + buf += vn->vn_next; + } +} + +static void +_load_verdef_section(struct ld *ld, struct ld_input *li, Elf *e, + Elf_Scn *verdef) +{ + struct ld_symver_verdef *svd; + Elf_Data *d_vd; + Elf_Verdef *vd; + Elf_Verdaux *vda; + GElf_Shdr sh_vd; + uint8_t *buf, *end, *buf2; + char *name; + int elferr, i; + + if (gelf_getshdr(verdef, &sh_vd) != &sh_vd) + ld_fatal(ld, "%s: gelf_getshdr failed: %s", li->li_name, + elf_errmsg(-1)); + + (void) elf_errno(); + if ((d_vd = elf_getdata(verdef, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + ld_fatal(ld, "%s: elf_getdata failed: %s", li->li_name, + elf_errmsg(elferr)); + return; + } + if (d_vd->d_size == 0) + return; + + buf = d_vd->d_buf; + end = buf + d_vd->d_size; + while (buf + sizeof(Elf_Verdef) <= end) { + vd = (Elf_Verdef *) (uintptr_t) buf; + svd = _load_verdef(ld, li, vd); + buf2 = buf + vd->vd_aux; + i = 0; + while (buf2 + sizeof(Elf_Verdaux) <= end && i < vd->vd_cnt) { + vda = (Elf_Verdaux *) (uintptr_t) buf2; + name = elf_strptr(e, sh_vd.sh_link, vda->vda_name); + if (name != NULL) { + _add_version_name(ld, li, (int) vd->vd_ndx, + name); + (void) _alloc_vda(ld, name, svd); + } + if (vda->vda_next == 0) + break; + buf2 += vda->vda_next; + i++; + } + if (vd->vd_next == 0) + break; + buf += vd->vd_next; + } +} + +static struct ld_symver_verdef * +_load_verdef(struct ld *ld, struct ld_input *li, Elf_Verdef *vd) +{ + struct ld_symver_verdef *svd; + + if (li->li_verdef == NULL) { + if ((li->li_verdef = calloc(1, sizeof(*li->li_verdef))) == + NULL) + ld_fatal_std(ld, "calloc"); + STAILQ_INIT(li->li_verdef); + } + + svd = _alloc_verdef(ld, li->li_verdef); + svd->svd_version = vd->vd_version; + svd->svd_flags = vd->vd_flags; + svd->svd_ndx = vd->vd_ndx; + svd->svd_cnt = vd->vd_cnt; + svd->svd_hash = vd->vd_hash; + + return (svd); +} + +uint16_t +ld_symver_search_version_script(struct ld *ld, struct ld_symbol *lsb) +{ + struct ld_script *lds; + struct ld_script_version_node *ldvn; + struct ld_script_version_entry *ldve, *ldve_g; + uint16_t ndx, ret_ndx, ret_ndx_g; + + /* If the symbol version index was known, return it directly. */ + if (lsb->lsb_vndx_known) + return (lsb->lsb_vndx); + + /* The symbol version index will be known after searching. */ + lsb->lsb_vndx_known = 1; + + lds = ld->ld_scp; + + /* If there isn't a version script, the default version is *global* */ + if (STAILQ_EMPTY(&lds->lds_vn)) { + lsb->lsb_vndx = 1; + return (1); + } + + /* Search for a match in the version patterns. */ + ndx = 2; + ldve_g = NULL; + ret_ndx_g = 0; + STAILQ_FOREACH(ldvn, &lds->lds_vn, ldvn_next) { + STAILQ_FOREACH(ldve, ldvn->ldvn_e, ldve_next) { + assert(ldve->ldve_sym != NULL); + if (fnmatch(ldve->ldve_sym, lsb->lsb_name, 0) == 0) { + if (ldve->ldve_local) + ret_ndx = 0; + else if (ldvn->ldvn_name != NULL) + ret_ndx = ndx; + else + ret_ndx = 1; + + /* + * If the version name is a globbing pattern, + * we only consider it is a match when there + * doesn't exist a exact match. + */ + if (ldve->ldve_glob) { + if (ldve_g == NULL) { + ldve_g = ldve; + ret_ndx_g = ret_ndx; + } + } else { + lsb->lsb_vndx = ret_ndx; + return (ret_ndx); + } + } + } + if (ldvn->ldvn_name != NULL) + ndx++; + } + + /* There is no exact match, check if there is a globbing match. */ + if (ldve_g != NULL) { + lsb->lsb_vndx = ret_ndx_g; + return (ret_ndx_g); + } + + /* + * Symbol doesn't match any version definition, set version + * to *global*. + */ + lsb->lsb_vndx = 1; + return (1); +} diff --git a/contrib/elftoolchain/ld/ld_symver.h b/contrib/elftoolchain/ld/ld_symver.h new file mode 100644 index 0000000000..971743573c --- /dev/null +++ b/contrib/elftoolchain/ld/ld_symver.h @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2010-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_symver.h 2882 2013-01-09 22:47:04Z kaiwang27 $ + */ + +struct ld_symver_vna { + char *sna_name; + uint32_t sna_hash; + uint16_t sna_flags; + uint16_t sna_other; + uint32_t sna_nameindex; + STAILQ_ENTRY(ld_symver_vna) sna_next; +}; + +STAILQ_HEAD(ld_symver_vna_head, ld_symver_vna); + +struct ld_symver_verneed { + char *svn_file; + uint16_t svn_version; + uint16_t svn_cnt; + uint32_t svn_fileindex; + struct ld_symver_vna_head svn_aux; + STAILQ_ENTRY(ld_symver_verneed) svn_next; +}; + +STAILQ_HEAD(ld_symver_verneed_head, ld_symver_verneed); + +struct ld_symver_vda { + char *sda_name; + uint32_t sda_nameindex; + STAILQ_ENTRY(ld_symver_vda) sda_next; +}; + +STAILQ_HEAD(ld_symver_vda_head, ld_symver_vda); + +struct ld_symver_verdef { + uint16_t svd_version; + uint16_t svd_flags; + uint16_t svd_ndx; + uint16_t svd_ndx_output; + uint16_t svd_cnt; + uint32_t svd_hash; + uint64_t svd_ref; + struct ld_symver_vda_head svd_aux; + STAILQ_ENTRY(ld_symver_verdef) svd_next; +}; + +STAILQ_HEAD(ld_symver_verdef_head, ld_symver_verdef); + +void ld_symver_load_symbol_version_info(struct ld *, struct ld_input *, + Elf *, Elf_Scn *, Elf_Scn *, Elf_Scn *); +void ld_symver_create_verdef_section(struct ld *); +void ld_symver_create_verneed_section(struct ld *); +void ld_symver_create_versym_section(struct ld *); +void ld_symver_add_verdef_refcnt(struct ld *, struct ld_symbol *); +uint16_t ld_symver_search_version_script(struct ld *, struct ld_symbol *); diff --git a/contrib/elftoolchain/ld/ld_utils.h b/contrib/elftoolchain/ld/ld_utils.h new file mode 100644 index 0000000000..a4ed642d1b --- /dev/null +++ b/contrib/elftoolchain/ld/ld_utils.h @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2012,2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_utils.h 2908 2013-02-03 06:06:01Z kaiwang27 $ + */ + +#define READ_16(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + READ_16BE(P, V); \ + else \ + READ_16LE(P, V); \ + } while (0) + +#define READ_32(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + READ_32BE(P, V); \ + else \ + READ_32LE(P, V); \ + } while (0) + +#define READ_64(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + READ_64BE(P, V); \ + else \ + READ_64LE(P, V); \ + } while (0) + +#define READ_16BE(P,V) \ + do { \ + (V) = ((P)[0] << 8) | (P)[1]; \ + } while (0) + +#define READ_32BE(P,V) \ + do { \ + (V) = ((unsigned)(P)[0] << 24) | ((P)[1] << 16) | \ + ((P)[2] << 8) | (P)[3]; \ + } while (0) + +#define READ_64BE(P,V) \ + do { \ + (V) = ((uint64_t)(P)[0] << 56) | \ + ((uint64_t)(P)[1] << 48) | \ + ((uint64_t)(P)[2] << 40) | \ + ((uint64_t)(P)[3] << 32) | \ + ((uint64_t)(P)[4] << 24) | \ + ((uint64_t)(P)[5] << 16) | \ + ((uint64_t)(P)[6] << 8) | (P)[7]; \ + } while (0) + +#define READ_16LE(P,V) \ + do { \ + (V) = ((P)[1] << 8) | (P)[0]; \ + } while (0) + +#define READ_32LE(P,V) \ + do { \ + (V) = ((unsigned)(P)[3] << 24) | ((P)[2] << 16) | \ + ((P)[1] << 8) | (P)[0]; \ + } while (0) + +#define READ_64LE(P,V) \ + do { \ + (V) = ((uint64_t)(P)[7] << 56) | \ + ((uint64_t)(P)[6] << 48) | \ + ((uint64_t)(P)[5] << 40) | \ + ((uint64_t)(P)[4] << 32) | \ + ((uint64_t)(P)[3] << 24) | \ + ((uint64_t)(P)[2] << 16) | \ + ((uint64_t)(P)[1] << 8) | (P)[0]; \ + } while (0) + +#define WRITE_8(P,V) \ + do { \ + *(P) = (V) & 0xff; \ + } while (0) + +#define WRITE_16(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + WRITE_16BE(P, V); \ + else \ + WRITE_16LE(P, V); \ + } while (0) + +#define WRITE_32(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + WRITE_32BE(P, V); \ + else \ + WRITE_32LE(P, V); \ + } while (0) + +#define WRITE_64(P,V) \ + do { \ + if (lo->lo_endian == ELFDATA2MSB) \ + WRITE_64BE(P, V); \ + else \ + WRITE_64LE(P, V); \ + } while (0) + +#define WRITE_16BE(P,V) \ + do { \ + (P)[0] = ((V) >> 8) & 0xff; \ + (P)[1] = (V) & 0xff; \ + } while (0) + +#define WRITE_32BE(P,V) \ + do { \ + (P)[0] = ((V) >> 24) & 0xff; \ + (P)[1] = ((V) >> 16) & 0xff; \ + (P)[2] = ((V) >> 8) & 0xff; \ + (P)[3] = (V) & 0xff; \ + } while (0) + +#define WRITE_64BE(P,V) \ + do { \ + WRITE_32BE((P),(V) >> 32); \ + WRITE_32BE((P) + 4, (V) & 0xffffffffU); \ + } while (0) + +#define WRITE_16LE(P,V) \ + do { \ + (P)[0] = (V) & 0xff; \ + (P)[1] = ((V) >> 8) & 0xff; \ + } while (0) + +#define WRITE_32LE(P,V) \ + do { \ + (P)[0] = (V) & 0xff; \ + (P)[1] = ((V) >> 8) & 0xff; \ + (P)[2] = ((V) >> 16) & 0xff; \ + (P)[3] = ((V) >> 24) & 0xff; \ + } while (0) + +#define WRITE_64LE(P,V) \ + do { \ + WRITE_32LE((P), (V) & 0xffffffffU); \ + WRITE_32LE((P) + 4, (V) >> 32); \ + } while (0) diff --git a/contrib/elftoolchain/ld/littlemips_script.ld b/contrib/elftoolchain/ld/littlemips_script.ld new file mode 100644 index 0000000000..3fe3779a8c --- /dev/null +++ b/contrib/elftoolchain/ld/littlemips_script.ld @@ -0,0 +1,165 @@ +/* $Id$ */ + +OUTPUT_FORMAT("elf32-littlemips") +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE (__executable_start = 0x00400000); + . = 0x00400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x00000000 + .plt : { *(.plt) } + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x00000000 + .fini : + { + KEEP(*(.fini)) + } = 0x00000000 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + + .tdata : ALIGN(4096) { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .dynamic : { *(.dynamic) } + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .got : { *(.got.plt) *(.got) } + .data : + { + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _gp = ALIGN(16) + 0x7ff0; + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + /* Align the end of data segment to page boundary. */ + . = ALIGN(. != 0 ? 4096 : 1); + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + _fbss = .; + .sbss : ALIGN(8) + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) *(.reginfo) } +} diff --git a/contrib/elftoolchain/ld/mips.c b/contrib/elftoolchain/ld/mips.c new file mode 100644 index 0000000000..2ebc683c96 --- /dev/null +++ b/contrib/elftoolchain/ld/mips.c @@ -0,0 +1,382 @@ +/*- + * Copyright (c) 2015 Serge Vakulenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_symbols.h" +#include "ld_utils.h" +#include "mips.h" + +ELFTC_VCSID("$Id$"); + +static void +_scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre) +{ + + (void) is; + + switch (lre->lre_type) { + + case R_MIPS_NONE: + case R_MIPS_32: + case R_MIPS_26: + case R_MIPS_PC16: + case R_MIPS_GPREL16: + case R_MIPS_HI16: + case R_MIPS_LO16: + break; + + default: + ld_warn(ld, "can not handle relocation %ju", + lre->lre_type); + break; + } +} + +static void +_process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + struct ld_output *lo = ld->ld_output; + uint32_t pc, s; + int32_t a, v, la; + static uint64_t gp; + static char gp_name[] = "_gp"; + + assert(lo != NULL); + + pc = lre->lre_offset + is->is_output->os_addr + is->is_reloff; + s = (uint32_t) lsb->lsb_value; + READ_32(buf + lre->lre_offset, a); + + switch (lre->lre_type) { + + case R_MIPS_NONE: + break; + + case R_MIPS_32: + /* 32-bit byte address. */ + v = s + a; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_26: + /* Word address at lower 26 bits. */ + s += (a & 0x3ffffff) << 2; + v = (a & ~0x3ffffff) | ((s >> 2) & 0x3ffffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_PC16: + /* PC-relative word address at lower 16 bits. */ + s += ((a & 0xffff) << 2) - pc; + v = (a & ~0xffff) | ((s >> 2) & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_GPREL16: + /* GP-relative byte address at lower 16 bits. */ + if (! gp && ld_symbols_get_value(ld, gp_name, &gp) < 0) + ld_fatal(ld, "symbol _gp is undefined"); + + s += (int16_t)(a & 0xffff) - gp; + v = (a & ~0xffff) | (s & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_HI16: + /* 16-bit high part of address pair. */ + if (! STAILQ_NEXT(lre, lre_next) || + STAILQ_NEXT(lre, lre_next)->lre_type != R_MIPS_LO16) + ld_fatal(ld, "no LO16 after HI16 relocation"); + READ_32(buf + STAILQ_NEXT(lre, lre_next)->lre_offset, la); + s += (a << 16) + (int16_t)la; + v = (a & ~0xffff) | (((s - (int16_t)s) >> 16) & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_LO16: + /* 16-bit low part of address pair. */ + s += (int16_t)a; + v = (a & ~0xffff) | (s & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + default: + ld_fatal(ld, "Relocation %d not supported", lre->lre_type); + break; + } +} + +/* + * Map flags into a valid MIPS architecture level value. + */ +static unsigned +_map_arch(unsigned flags) +{ + flags &= EF_MIPS_ARCH; + + switch (flags) { + default: + case EF_MIPS_ARCH_1: + return EF_MIPS_ARCH_1; + case EF_MIPS_ARCH_2: + case EF_MIPS_ARCH_3: + case EF_MIPS_ARCH_4: + case EF_MIPS_ARCH_5: + case EF_MIPS_ARCH_32: + case EF_MIPS_ARCH_64: + case EF_MIPS_ARCH_32R2: + case EF_MIPS_ARCH_64R2: + return flags; + } +} + +/* + * Merge architecture levels of two files. + */ +static unsigned +_merge_arch(unsigned old_arch, unsigned new_arch) +{ + unsigned base, extended; + + if (old_arch < new_arch) { + base = old_arch; + extended = new_arch; + } else if (old_arch > new_arch) { + base = new_arch; + extended = old_arch; + } else + return old_arch; + + switch (extended) { + default: + case EF_MIPS_ARCH_1: + case EF_MIPS_ARCH_2: + case EF_MIPS_ARCH_3: + case EF_MIPS_ARCH_4: + case EF_MIPS_ARCH_5: + return extended; + + case EF_MIPS_ARCH_32: + if (base <= EF_MIPS_ARCH_2) + return EF_MIPS_ARCH_32; + return EF_MIPS_ARCH_64; + + case EF_MIPS_ARCH_64: + return EF_MIPS_ARCH_64; + + case EF_MIPS_ARCH_32R2: + if (base <= EF_MIPS_ARCH_2 || base == EF_MIPS_ARCH_32) + return EF_MIPS_ARCH_32R2; + return EF_MIPS_ARCH_64R2; + + case EF_MIPS_ARCH_64R2: + return EF_MIPS_ARCH_64R2; + } +} + +static const char* +_abi_name(int flags) +{ + switch (flags & EF_MIPS_ABI) { + case 0: + return (flags & EF_MIPS_ABI2) ? "N32" : "none"; + case E_MIPS_ABI_O32: + return "O32"; + case E_MIPS_ABI_O64: + return "O64"; + case E_MIPS_ABI_EABI32: + return "EABI32"; + case E_MIPS_ABI_EABI64: + return "EABI64"; + default: + return "Unknown"; + } +} + +/* + * Merge options of application binary interface. + */ +static unsigned +_merge_abi(struct ld *ld, unsigned new_flags) +{ + int old = ld->ld_arch->flags & EF_MIPS_ABI; + int new = new_flags & EF_MIPS_ABI; + + if (old == 0) + return new; + + if (new != old && new != 0) + ld_fatal(ld, "ABI mismatch: linking '%s' module with previous '%s' modules", + _abi_name(new_flags), _abi_name(ld->ld_arch->flags)); + + return old; +} + +/* + * Merge options of application-specific extensions. + */ +static unsigned +_merge_ase(struct ld *ld, unsigned new_flags) +{ + int old_micro = ld->ld_arch->flags & EF_MIPS_ARCH_ASE_MICROMIPS; + int new_micro = new_flags & EF_MIPS_ARCH_ASE_MICROMIPS; + int old_m16 = ld->ld_arch->flags & EF_MIPS_ARCH_ASE_M16; + int new_m16 = new_flags & EF_MIPS_ARCH_ASE_M16; + + if ((old_m16 && new_micro) || (old_micro && new_m16)) + ld_fatal(ld, "ASE mismatch: linking '%s' module with previous '%s' modules", + new_m16 ? "MIPS16" : "microMIPS", + old_micro ? "microMIPS" : "MIPS16"); + return old_micro | new_micro | old_m16 | new_m16; +} + +/* + * Merge architecture-specific flags of the file to be linked + * into a resulting value for output file. + */ +static void +_merge_flags(struct ld *ld, unsigned new_flags) +{ + struct ld_arch *la = ld->ld_arch; + unsigned value; + + /* At least one .noreorder directive appeared in the source. */ + la->flags |= new_flags & EF_MIPS_NOREORDER; + + /* Merge position-independent flags. */ + if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0) != + ((la->flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)) + ld_warn(ld, "linking PIC files with non-PIC files"); + if (new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) + la->flags |= EF_MIPS_CPIC; + if (! (new_flags & EF_MIPS_PIC)) + la->flags &= ~EF_MIPS_PIC; + + /* Merge architecture level. */ + value = _merge_arch(_map_arch(la->flags), _map_arch(new_flags)); + la->flags &= ~EF_MIPS_ARCH; + la->flags |= value; + + /* Merge ABI options. */ + value = _merge_abi(ld, new_flags); + la->flags &= ~EF_MIPS_ABI; + la->flags |= value; + + /* Merge application-specific extensions. */ + value = _merge_ase(ld, new_flags); + la->flags &= ~EF_MIPS_ARCH_ASE; + la->flags |= value; +} + +static uint64_t +_get_max_page_size(struct ld *ld) +{ + + (void) ld; + + return 0x1000; +} + +static uint64_t +_get_common_page_size(struct ld *ld) +{ + + (void) ld; + + return 0x1000; +} + +static int +_is_absolute_reloc(uint64_t r) +{ + if (r == R_MIPS_32) + return 1; + + return 0; +} + +static int +_is_relative_reloc(uint64_t r) +{ + if (r == R_MIPS_REL32) + return 1; + + return 0; +} + +void +mips_register(struct ld *ld) +{ + struct ld_arch *mips_little_endian, *mips_big_endian; + + if ((mips_little_endian = calloc(1, sizeof(*mips_little_endian))) == NULL) + ld_fatal_std(ld, "calloc"); + if ((mips_big_endian = calloc(1, sizeof(*mips_big_endian))) == NULL) + ld_fatal_std(ld, "calloc"); + + /* + * Little endian. + */ + snprintf(mips_little_endian->name, sizeof(mips_little_endian->name), "%s", "littlemips"); + + mips_little_endian->script = littlemips_script; + mips_little_endian->get_max_page_size = _get_max_page_size; + mips_little_endian->get_common_page_size = _get_common_page_size; + mips_little_endian->scan_reloc = _scan_reloc; + mips_little_endian->process_reloc = _process_reloc; + mips_little_endian->is_absolute_reloc = _is_absolute_reloc; + mips_little_endian->is_relative_reloc = _is_relative_reloc; + mips_little_endian->merge_flags = _merge_flags; + mips_little_endian->reloc_is_64bit = 0; + mips_little_endian->reloc_is_rela = 0; + mips_little_endian->reloc_entsize = sizeof(Elf32_Rel); + + /* + * Big endian. + */ + snprintf(mips_big_endian->name, sizeof(mips_big_endian->name), "%s", "bigmips"); + + mips_big_endian->script = bigmips_script; + mips_big_endian->get_max_page_size = _get_max_page_size; + mips_big_endian->get_common_page_size = _get_common_page_size; + mips_big_endian->scan_reloc = _scan_reloc; + mips_big_endian->process_reloc = _process_reloc; + mips_big_endian->is_absolute_reloc = _is_absolute_reloc; + mips_big_endian->is_relative_reloc = _is_relative_reloc; + mips_little_endian->merge_flags = _merge_flags; + mips_big_endian->reloc_is_64bit = 0; + mips_big_endian->reloc_is_rela = 0; + mips_big_endian->reloc_entsize = sizeof(Elf32_Rel); + + HASH_ADD_STR(ld->ld_arch_list, name, mips_little_endian); + HASH_ADD_STR(ld->ld_arch_list, name, mips_big_endian); +} diff --git a/contrib/elftoolchain/ld/mips.h b/contrib/elftoolchain/ld/mips.h new file mode 100644 index 0000000000..92d166cce2 --- /dev/null +++ b/contrib/elftoolchain/ld/mips.h @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2015 Serge Vakulenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern char *littlemips_script; +extern char *bigmips_script; + +void mips_register(struct ld *); diff --git a/contrib/elftoolchain/libdwarf/Makefile b/contrib/elftoolchain/libdwarf/Makefile new file mode 100644 index 0000000000..4cd3cb734d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/Makefile @@ -0,0 +1,337 @@ +# $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $ + +TOP= .. + +LIB= dwarf + +SRCS= \ + dwarf_abbrev.c \ + dwarf_arange.c \ + dwarf_attr.c \ + dwarf_attrval.c \ + dwarf_cu.c \ + dwarf_dealloc.c \ + dwarf_die.c \ + dwarf_dump.c \ + dwarf_errmsg.c \ + dwarf_finish.c \ + dwarf_form.c \ + dwarf_frame.c \ + dwarf_funcs.c \ + dwarf_init.c \ + dwarf_lineno.c \ + dwarf_loclist.c \ + dwarf_macinfo.c \ + dwarf_pro_arange.c \ + dwarf_pro_attr.c \ + dwarf_pro_die.c \ + dwarf_pro_expr.c \ + dwarf_pro_finish.c \ + dwarf_pro_frame.c \ + dwarf_pro_funcs.c \ + dwarf_pro_init.c \ + dwarf_pro_lineno.c \ + dwarf_pro_macinfo.c \ + dwarf_pro_pubnames.c \ + dwarf_pro_reloc.c \ + dwarf_pro_sections.c \ + dwarf_pro_types.c \ + dwarf_pro_vars.c \ + dwarf_pro_weaks.c \ + dwarf_pubnames.c \ + dwarf_pubtypes.c \ + dwarf_ranges.c \ + dwarf_reloc.c \ + dwarf_sections.c \ + dwarf_seterror.c \ + dwarf_str.c \ + dwarf_types.c \ + dwarf_vars.c \ + dwarf_weaks.c \ + libdwarf.c \ + libdwarf_abbrev.c \ + libdwarf_arange.c \ + libdwarf_attr.c \ + libdwarf_die.c \ + libdwarf_error.c \ + libdwarf_elf_access.c \ + libdwarf_elf_init.c \ + libdwarf_frame.c \ + libdwarf_info.c \ + libdwarf_init.c \ + libdwarf_lineno.c \ + libdwarf_loc.c \ + libdwarf_loclist.c \ + libdwarf_macinfo.c \ + libdwarf_nametbl.c \ + libdwarf_ranges.c \ + libdwarf_reloc.c \ + libdwarf_rw.c \ + libdwarf_sections.c \ + libdwarf_str.c + +INCS= dwarf.h libdwarf.h +INCSDIR= /usr/include + +GENSRCS= dwarf_pubnames.c dwarf_pubtypes.c dwarf_weaks.c \ + dwarf_funcs.c dwarf_vars.c dwarf_types.c \ + dwarf_pro_pubnames.c dwarf_pro_weaks.c \ + dwarf_pro_funcs.c dwarf_pro_types.c \ + dwarf_pro_vars.c +CLEANFILES= ${GENSRCS} + +SHLIB_MAJOR= 3 + +WARNS?= 6 + +LDADD+= -lelf + +MAN= dwarf.3 \ + dwarf_add_arange.3 \ + dwarf_add_AT_comp_dir.3 \ + dwarf_add_AT_const_value_string.3 \ + dwarf_add_AT_dataref.3 \ + dwarf_add_AT_flag.3 \ + dwarf_add_AT_location_expr.3 \ + dwarf_add_AT_name.3 \ + dwarf_add_AT_producer.3 \ + dwarf_add_AT_ref_address.3 \ + dwarf_add_AT_reference.3 \ + dwarf_add_AT_signed_const.3 \ + dwarf_add_AT_string.3 \ + dwarf_add_AT_targ_address.3 \ + dwarf_add_die_to_debug.3 \ + dwarf_add_directory_decl.3 \ + dwarf_add_expr_addr.3 \ + dwarf_add_expr_gen.3 \ + dwarf_add_fde_inst.3 \ + dwarf_add_file_decl.3 \ + dwarf_add_frame_cie.3 \ + dwarf_add_frame_fde.3 \ + dwarf_add_funcname.3 \ + dwarf_add_line_entry.3 \ + dwarf_add_pubname.3 \ + dwarf_add_typename.3 \ + dwarf_add_varname.3 \ + dwarf_add_weakname.3 \ + dwarf_attr.3 \ + dwarf_attrlist.3 \ + dwarf_attroffset.3 \ + dwarf_attrval_signed.3 \ + dwarf_child.3 \ + dwarf_dealloc.3 \ + dwarf_def_macro.3 \ + dwarf_die_abbrev_code.3 \ + dwarf_die_link.3 \ + dwarf_diename.3 \ + dwarf_dieoffset.3 \ + dwarf_end_macro_file.3 \ + dwarf_errmsg.3 \ + dwarf_errno.3 \ + dwarf_expand_frame_instructions.3 \ + dwarf_expr_current_offset.3 \ + dwarf_expr_into_block.3 \ + dwarf_fde_cfa_offset.3 \ + dwarf_find_macro_value_start.3 \ + dwarf_finish.3 \ + dwarf_formaddr.3 \ + dwarf_formblock.3 \ + dwarf_formexprloc.3 \ + dwarf_formflag.3 \ + dwarf_formref.3 \ + dwarf_formsig8.3 \ + dwarf_formstring.3 \ + dwarf_formudata.3 \ + dwarf_get_abbrev.3 \ + dwarf_get_abbrev_children_flag.3 \ + dwarf_get_abbrev_code.3 \ + dwarf_get_abbrev_entry.3 \ + dwarf_get_abbrev_tag.3 \ + dwarf_get_address_size.3 \ + dwarf_get_arange.3 \ + dwarf_get_arange_info.3 \ + dwarf_get_aranges.3 \ + dwarf_get_AT_name.3 \ + dwarf_get_cie_index.3 \ + dwarf_get_cie_info.3 \ + dwarf_get_cie_of_fde.3 \ + dwarf_get_cu_die_offset.3 \ + dwarf_get_die_infotypes_flag.3 \ + dwarf_get_elf.3 \ + dwarf_get_fde_at_pc.3 \ + dwarf_get_fde_info_for_all_regs.3 \ + dwarf_get_fde_info_for_all_regs3.3 \ + dwarf_get_fde_info_for_cfa_reg3.3 \ + dwarf_get_fde_info_for_reg.3 \ + dwarf_get_fde_info_for_reg3.3 \ + dwarf_get_fde_instr_bytes.3 \ + dwarf_get_fde_list.3 \ + dwarf_get_fde_n.3 \ + dwarf_get_fde_range.3 \ + dwarf_get_form_class.3 \ + dwarf_get_funcs.3 \ + dwarf_get_globals.3 \ + dwarf_get_loclist_entry.3 \ + dwarf_get_macro_details.3 \ + dwarf_get_pubtypes.3 \ + dwarf_get_ranges.3 \ + dwarf_get_relocation_info.3 \ + dwarf_get_relocation_info_count.3 \ + dwarf_get_section_bytes.3 \ + dwarf_get_section_max_offsets.3 \ + dwarf_get_str.3 \ + dwarf_get_types.3 \ + dwarf_get_vars.3 \ + dwarf_get_weaks.3 \ + dwarf_hasattr.3 \ + dwarf_hasform.3 \ + dwarf_highpc.3 \ + dwarf_init.3 \ + dwarf_lineno.3 \ + dwarf_lne_end_sequence.3 \ + dwarf_lne_set_address.3 \ + dwarf_loclist.3 \ + dwarf_loclist_from_expr.3 \ + dwarf_new_die.3 \ + dwarf_new_expr.3 \ + dwarf_new_fde.3 \ + dwarf_next_cu_header.3 \ + dwarf_next_types_section.3 \ + dwarf_object_init.3 \ + dwarf_producer_init.3 \ + dwarf_producer_set_isa.3 \ + dwarf_reset_section_bytes.3 \ + dwarf_seterrarg.3 \ + dwarf_set_frame_cfa_value.3 \ + dwarf_set_reloc_application.3 \ + dwarf_srcfiles.3 \ + dwarf_srclines.3 \ + dwarf_start_macro_file.3 \ + dwarf_tag.3 \ + dwarf_transform_to_disk_form.3 \ + dwarf_undef_macro.3 \ + dwarf_vendor_ext.3 \ + dwarf_whatattr.3 + +MLINKS+= \ + dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_signedint.3 \ + dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_unsignedint.3 \ + dwarf_add_AT_signed_const.3 dwarf_add_AT_unsigned_const.3 \ + dwarf_add_AT_targ_address.3 dwarf_add_AT_targ_address_b.3 \ + dwarf_add_arange.3 dwarf_add_arange_b.3 \ + dwarf_add_expr_addr.3 dwarf_add_expr_addr_b.3 \ + dwarf_add_frame_fde.3 dwarf_add_frame_fde_b.3 \ + dwarf_attrval_signed.3 dwarf_attrval_flag.3 \ + dwarf_attrval_signed.3 dwarf_attrval_string.3 \ + dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \ + dwarf_child.3 dwarf_offdie.3 \ + dwarf_child.3 dwarf_offdie_b.3 \ + dwarf_child.3 dwarf_siblingof.3 \ + dwarf_child.3 dwarf_siblingof_b.3 \ + dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \ + dwarf_dealloc.3 dwarf_funcs_dealloc.3 \ + dwarf_dealloc.3 dwarf_globals_dealloc.3 \ + dwarf_dealloc.3 dwarf_pubtypes_dealloc.3 \ + dwarf_dealloc.3 dwarf_types_dealloc.3 \ + dwarf_dealloc.3 dwarf_vars_dealloc.3 \ + dwarf_dealloc.3 dwarf_weaks_dealloc.3 \ + dwarf_dealloc.3 dwarf_ranges_dealloc.3 \ + dwarf_dealloc.3 dwarf_srclines_dealloc.3 \ + dwarf_init.3 dwarf_elf_init.3 \ + dwarf_dieoffset.3 dwarf_die_CU_offset.3 \ + dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \ + dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \ + dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset_b.3 \ + dwarf_finish.3 dwarf_object_finish.3 \ + dwarf_formref.3 dwarf_global_formref.3 \ + dwarf_formudata.3 dwarf_formsdata.3 \ + dwarf_get_AT_name.3 dwarf_get_ACCESS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ATE_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CC_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CFA_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CHILDREN_name.3 \ + dwarf_get_AT_name.3 dwarf_get_DS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_DSC_name.3 \ + dwarf_get_AT_name.3 dwarf_get_EH_name.3 \ + dwarf_get_AT_name.3 dwarf_get_END_name.3 \ + dwarf_get_AT_name.3 dwarf_get_FORM_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ID_name.3 \ + dwarf_get_AT_name.3 dwarf_get_INL_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LANG_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LNE_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LNS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_MACINFO_name.3 \ + dwarf_get_AT_name.3 dwarf_get_OP_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ORD_name.3 \ + dwarf_get_AT_name.3 dwarf_get_TAG_name.3 \ + dwarf_get_AT_name.3 dwarf_get_VIRTUALITY_name.3 \ + dwarf_get_AT_name.3 dwarf_get_VIS_name.3 \ + dwarf_get_cu_die_offset.3 dwarf_get_arange_cu_header_offset.3 \ + dwarf_get_fde_list.3 dwarf_get_fde_list_eh.3 \ + dwarf_get_funcs.3 dwarf_func_die_offset.3 \ + dwarf_get_funcs.3 dwarf_func_cu_offset.3 \ + dwarf_get_funcs.3 dwarf_func_name_offsets.3 \ + dwarf_get_funcs.3 dwarf_funcname.3 \ + dwarf_get_globals.3 dwarf_global_die_offset.3 \ + dwarf_get_globals.3 dwarf_global_cu_offset.3 \ + dwarf_get_globals.3 dwarf_global_name_offsets.3 \ + dwarf_get_globals.3 dwarf_globname.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_die_offset.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_cu_offset.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \ + dwarf_get_pubtypes.3 dwarf_pubtypename.3 \ + dwarf_get_ranges.3 dwarf_get_ranges_a.3 \ + dwarf_get_section_max_offsets.3 dwarf_get_section_max_offsets_b.3 \ + dwarf_get_types.3 dwarf_type_die_offset.3 \ + dwarf_get_types.3 dwarf_type_cu_offset.3 \ + dwarf_get_types.3 dwarf_type_name_offsets.3 \ + dwarf_get_types.3 dwarf_typename.3 \ + dwarf_get_vars.3 dwarf_var_die_offset.3 \ + dwarf_get_vars.3 dwarf_var_cu_offset.3 \ + dwarf_get_vars.3 dwarf_var_name_offsets.3 \ + dwarf_get_vars.3 dwarf_varname.3 \ + dwarf_get_weaks.3 dwarf_weak_die_offset.3 \ + dwarf_get_weaks.3 dwarf_weak_cu_offset.3 \ + dwarf_get_weaks.3 dwarf_weak_name_offsets.3 \ + dwarf_get_weaks.3 dwarf_weakname.3 \ + dwarf_hasform.3 dwarf_whatform.3 \ + dwarf_hasform.3 dwarf_whatform_direct.3 \ + dwarf_highpc.3 dwarf_arrayorder.3 \ + dwarf_highpc.3 dwarf_bitoffset.3 \ + dwarf_highpc.3 dwarf_bitsize.3 \ + dwarf_highpc.3 dwarf_bytesize.3 \ + dwarf_highpc.3 dwarf_highpc_b.3 \ + dwarf_highpc.3 dwarf_lowpc.3 \ + dwarf_highpc.3 dwarf_srclang.3 \ + dwarf_lineno.3 dwarf_lineaddr.3 \ + dwarf_lineno.3 dwarf_linebeginstatement.3 \ + dwarf_lineno.3 dwarf_lineblock.3 \ + dwarf_lineno.3 dwarf_lineendsequence.3 \ + dwarf_lineno.3 dwarf_lineoff.3 \ + dwarf_lineno.3 dwarf_linesrc.3 \ + dwarf_lineno.3 dwarf_line_srcfileno.3 \ + dwarf_loclist.3 dwarf_loclist_n.3 \ + dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \ + dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_c.3 \ + dwarf_producer_init.3 dwarf_producer_init_b.3 \ + dwarf_seterrarg.3 dwarf_seterrhand.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_table_size.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_same_value.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_undefined_value.3 + +dwarf_pubnames.c: dwarf_nametbl.m4 dwarf_pubnames.m4 +dwarf_pubtypes.c: dwarf_nametbl.m4 dwarf_pubtypes.m4 +dwarf_weaks.c: dwarf_nametbl.m4 dwarf_weaks.m4 +dwarf_funcs.c: dwarf_nametbl.m4 dwarf_funcs.m4 +dwarf_vars.c: dwarf_nametbl.m4 dwarf_vars.m4 +dwarf_types.c: dwarf_nametbl.m4 dwarf_types.m4 +dwarf_pro_pubnames.c: dwarf_pro_nametbl.m4 dwarf_pro_pubnames.m4 +dwarf_pro_weaks.c: dwarf_pro_nametbl.m4 dwarf_pro_weaks.m4 +dwarf_pro_funcs.c: dwarf_pro_nametbl.m4 dwarf_pro_funcs.m4 +dwarf_pro_types.c: dwarf_pro_nametbl.m4 dwarf_pro_types.m4 +dwarf_pro_vars.c: dwarf_pro_nametbl.m4 dwarf_pro_vars.m4 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libdwarf/Version.map b/contrib/elftoolchain/libdwarf/Version.map new file mode 100644 index 0000000000..669f70e44d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/Version.map @@ -0,0 +1,239 @@ +/* $Id: Version.map 3085 2014-09-02 22:08:23Z kaiwang27 $ */ + +R1.0 { +global: + dwarf_add_AT_comp_dir; + dwarf_add_AT_const_value_signedint; + dwarf_add_AT_const_value_string; + dwarf_add_AT_const_value_unsignedint; + dwarf_add_AT_dataref; + dwarf_add_AT_flag; + dwarf_add_AT_location_expr; + dwarf_add_AT_name; + dwarf_add_AT_producer; + dwarf_add_AT_ref_address; + dwarf_add_AT_reference; + dwarf_add_AT_signed_const; + dwarf_add_AT_string; + dwarf_add_AT_targ_address; + dwarf_add_AT_targ_address_b; + dwarf_add_AT_unsigned_const; + dwarf_add_arange; + dwarf_add_arange_b; + dwarf_add_die_to_debug; + dwarf_add_directory_decl; + dwarf_add_expr_addr; + dwarf_add_expr_addr_b; + dwarf_add_expr_gen; + dwarf_add_fde_inst; + dwarf_add_file_decl; + dwarf_add_frame_cie; + dwarf_add_frame_fde; + dwarf_add_frame_fde_b; + dwarf_add_funcname; + dwarf_add_line_entry; + dwarf_add_pubname; + dwarf_add_typename; + dwarf_add_varname; + dwarf_add_weakname; + dwarf_arrayorder; + dwarf_attr; + dwarf_attrlist; + dwarf_attroffset; + dwarf_attrval_flag; + dwarf_attrval_signed; + dwarf_attrval_string; + dwarf_attrval_unsigned; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_child; + dwarf_dealloc; + dwarf_def_macro; + dwarf_die_CU_offset; + dwarf_die_CU_offset_range; + dwarf_die_abbrev_code; + dwarf_die_link; + dwarf_diename; + dwarf_dieoffset; + dwarf_elf_init; + dwarf_end_macro_file; + dwarf_errmsg_; + dwarf_expand_frame_instructions; + dwarf_expr_current_offset; + dwarf_expr_into_block; + dwarf_fde_cfa_offset; + dwarf_fde_cie_list_dealloc; + dwarf_find_macro_value_start; + dwarf_finish; + dwarf_formaddr; + dwarf_formblock; + dwarf_formexprloc; + dwarf_formflag; + dwarf_formref; + dwarf_formsdata; + dwarf_formsig8; + dwarf_formstring; + dwarf_formudata; + dwarf_func_cu_offset; + dwarf_func_die_offset; + dwarf_func_name_offsets; + dwarf_funcname; + dwarf_funcs_dealloc; + dwarf_get_ACCESS_name; + dwarf_get_ATE_name; + dwarf_get_AT_name; + dwarf_get_CC_name; + dwarf_get_CFA_name; + dwarf_get_CHILDREN_name; + dwarf_get_DSC_name; + dwarf_get_DS_name; + dwarf_get_EH_name; + dwarf_get_END_name; + dwarf_get_FORM_name; + dwarf_get_ID_name; + dwarf_get_INL_name; + dwarf_get_LANG_name; + dwarf_get_LNE_name; + dwarf_get_LNS_name; + dwarf_get_MACINFO_name; + dwarf_get_OP_name; + dwarf_get_ORD_name; + dwarf_get_TAG_name; + dwarf_get_VIRTUALITY_name; + dwarf_get_VIS_name; + dwarf_get_abbrev; + dwarf_get_abbrev_children_flag; + dwarf_get_abbrev_code; + dwarf_get_abbrev_entry; + dwarf_get_abbrev_tag; + dwarf_get_address_size; + dwarf_get_arange; + dwarf_get_arange_cu_header_offset; + dwarf_get_arange_info; + dwarf_get_aranges; + dwarf_get_cie_index; + dwarf_get_cie_info; + dwarf_get_cie_of_fde; + dwarf_get_cu_die_offset; + dwarf_get_cu_die_offset_given_cu_header_offset; + dwarf_get_cu_die_offset_given_cu_header_offset_b; + dwarf_get_die_infotypes_flag; + dwarf_get_elf; + dwarf_get_fde_at_pc; + dwarf_get_fde_info_for_all_regs3; + dwarf_get_fde_info_for_all_regs; + dwarf_get_fde_info_for_cfa_reg3; + dwarf_get_fde_info_for_reg3; + dwarf_get_fde_info_for_reg; + dwarf_get_fde_instr_bytes; + dwarf_get_fde_list; + dwarf_get_fde_list_eh; + dwarf_get_fde_n; + dwarf_get_fde_range; + dwarf_get_form_class; + dwarf_get_funcs; + dwarf_get_globals; + dwarf_get_loclist_entry; + dwarf_get_macro_details; + dwarf_get_pubtypes; + dwarf_get_ranges; + dwarf_get_ranges_a; + dwarf_get_relocation_info; + dwarf_get_relocation_info_count; + dwarf_get_section_bytes; + dwarf_get_section_max_offsets; + dwarf_get_section_max_offsets_b; + dwarf_get_str; + dwarf_get_types; + dwarf_get_vars; + dwarf_get_weaks; + dwarf_global_cu_offset; + dwarf_global_die_offset; + dwarf_global_formref; + dwarf_global_name_offsets; + dwarf_globals_dealloc; + dwarf_globname; + dwarf_hasattr; + dwarf_hasform; + dwarf_highpc; + dwarf_highpc_b; + dwarf_init; + dwarf_line_srcfileno; + dwarf_lineaddr; + dwarf_linebeginstatement; + dwarf_lineblock; + dwarf_lineendsequence; + dwarf_lineno; + dwarf_lineoff; + dwarf_linesrc; + dwarf_lne_end_sequence; + dwarf_lne_set_address; + dwarf_loclist; + dwarf_loclist_from_expr; + dwarf_loclist_from_expr_a; + dwarf_loclist_from_expr_b; + dwarf_loclist_n; + dwarf_lowpc; + dwarf_new_die; + dwarf_new_expr; + dwarf_new_fde; + dwarf_next_cu_header; + dwarf_next_cu_header_b; + dwarf_next_cu_header_c; + dwarf_next_types_section; + dwarf_object_finish; + dwarf_object_init; + dwarf_offdie; + dwarf_offdie_b; + dwarf_producer_finish; + dwarf_producer_init; + dwarf_producer_init_b; + dwarf_producer_set_isa; + dwarf_pubtype_cu_offset; + dwarf_pubtype_die_offset; + dwarf_pubtype_name_offsets; + dwarf_pubtypename; + dwarf_pubtypes_dealloc; + dwarf_ranges_dealloc; + dwarf_reset_section_bytes; + dwarf_set_frame_cfa_value; + dwarf_set_frame_rule_initial_value; + dwarf_set_frame_rule_table_size; + dwarf_set_frame_same_value; + dwarf_set_frame_undefined_value; + dwarf_set_reloc_application; + dwarf_seterrarg; + dwarf_seterrhand; + dwarf_siblingof; + dwarf_siblingof_b; + dwarf_srcfiles; + dwarf_srclang; + dwarf_srclines; + dwarf_srclines_dealloc; + dwarf_start_macro_file; + dwarf_tag; + dwarf_transform_to_disk_form; + dwarf_type_cu_offset; + dwarf_type_die_offset; + dwarf_type_name_offsets; + dwarf_typename; + dwarf_types_dealloc; + dwarf_undef_macro; + dwarf_var_cu_offset; + dwarf_var_die_offset; + dwarf_var_name_offsets; + dwarf_varname; + dwarf_vars_dealloc; + dwarf_vendor_ext; + dwarf_weak_cu_offset; + dwarf_weak_die_offset; + dwarf_weak_name_offsets; + dwarf_weakname; + dwarf_weaks_dealloc; + dwarf_whatattr; + dwarf_whatform; + dwarf_whatform_direct; +local: + *; +}; diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h new file mode 100644 index 0000000000..23204bd7e4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/_libdwarf.h @@ -0,0 +1,687 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2014,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libdwarf.h 4039 2024-03-15 04:07:32Z kaiwang27 $ + */ + +#ifndef __LIBDWARF_H_ +#define __LIBDWARF_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "uthash.h" + +#include "_elftc.h" + +#define DWARF_DIE_HASH_SIZE 8191 + +struct _libdwarf_globals { + Dwarf_Handler errhand; + Dwarf_Ptr errarg; + int applyreloc; +}; + +extern struct _libdwarf_globals _libdwarf; + +#define _DWARF_SET_ERROR(_d, _e, _err, _elf_err) \ + _dwarf_set_error(_d, _e, _err, _elf_err, __func__, __LINE__) +#define DWARF_SET_ERROR(_d, _e, _err) \ + _DWARF_SET_ERROR(_d, _e, _err, 0) +#define DWARF_SET_ELF_ERROR(_d, _e) \ + _DWARF_SET_ERROR(_d, _e, DW_DLE_ELF, elf_errno()) + +/* + * Convenient macros for producer bytes stream generation. + */ +#define WRITE_VALUE(value, bytes) \ + dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, \ + (value), (bytes), error) +#define WRITE_ULEB128(value) \ + _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (value), error) +#define WRITE_SLEB128(value) \ + _dwarf_write_sleb128_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (value), error) +#define WRITE_STRING(string) \ + _dwarf_write_string_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (string), error) +#define WRITE_BLOCK(blk, size) \ + _dwarf_write_block_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (blk), (size), error) +#define WRITE_PADDING(byte, cnt) \ + _dwarf_write_padding_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (byte), (cnt), error) +#define RCHECK(expr) \ + do { \ + ret = expr; \ + if (ret != DW_DLE_NONE) \ + goto gen_fail; \ + } while (/* CONSTCOND */ 0) + +typedef struct _Dwarf_CU *Dwarf_CU; + +struct _Dwarf_AttrDef { + Dwarf_Half ad_attrib; /* DW_AT_XXX */ + Dwarf_Half ad_form; /* DW_FORM_XXX */ + uint64_t ad_offset; /* Offset in abbrev section. */ + int64_t ad_const; /* Implicit constant */ + STAILQ_ENTRY(_Dwarf_AttrDef) ad_next; /* Next attribute define. */ +}; + +struct _Dwarf_Attribute { + Dwarf_Die at_die; /* Ptr to containing DIE. */ + Dwarf_Die at_refdie; /* Ptr to reference DIE. */ + uint64_t at_offset; /* Offset in info section. */ + Dwarf_Half at_attrib; /* DW_AT_XXX */ + Dwarf_Half at_form; /* DW_FORM_XXX */ + int at_indirect; /* Has indirect form. */ + union { + uint64_t u64; /* Unsigned value. */ + int64_t s64; /* Signed value. */ + char *s; /* String. */ + uint8_t *u8p; /* Block data. */ + } u[2]; /* Value. */ + Dwarf_Block at_block; /* Block. */ + Dwarf_Locdesc *at_ld; /* at value is locdesc. */ + Dwarf_P_Expr at_expr; /* at value is expr. */ + uint64_t at_relsym; /* Relocation symbol index. */ + const char *at_relsec; /* Rel. to dwarf section. */ + STAILQ_ENTRY(_Dwarf_Attribute) at_next; /* Next attribute. */ +}; + +struct _Dwarf_Abbrev { + uint64_t ab_entry; /* Abbrev entry. */ + uint64_t ab_tag; /* Tag: DW_TAG_ */ + uint8_t ab_children; /* DW_CHILDREN_no or DW_CHILDREN_yes */ + uint64_t ab_offset; /* Offset in abbrev section. */ + uint64_t ab_length; /* Length of this abbrev entry. */ + uint64_t ab_atnum; /* Number of attribute defines. */ + UT_hash_handle ab_hh; /* Uthash handle. */ + STAILQ_HEAD(, _Dwarf_AttrDef) ab_attrdef; /* List of attribute defs. */ +}; + +struct _Dwarf_Die { + Dwarf_Die die_parent; /* Parent DIE. */ + Dwarf_Die die_child; /* First child DIE. */ + Dwarf_Die die_left; /* Left sibling DIE. */ + Dwarf_Die die_right; /* Right sibling DIE. */ + uint64_t die_offset; /* DIE offset in section. */ + uint64_t die_next_off; /* Next DIE offset in section. */ + uint64_t die_abnum; /* Abbrev number. */ + Dwarf_Abbrev die_ab; /* Abbrev pointer. */ + Dwarf_Tag die_tag; /* DW_TAG_ */ + Dwarf_Debug die_dbg; /* Dwarf_Debug pointer. */ + Dwarf_CU die_cu; /* Compilation unit pointer. */ + char *die_name; /* Ptr to the name string. */ + Dwarf_Attribute *die_attrarray; /* Array of attributes. */ + STAILQ_HEAD(, _Dwarf_Attribute) die_attr; /* List of attributes. */ + STAILQ_ENTRY(_Dwarf_Die) die_pro_next; /* Next die in pro-die list. */ +}; + +struct _Dwarf_P_Expr_Entry { + Dwarf_Loc ee_loc; /* Location expression. */ + Dwarf_Unsigned ee_sym; /* Optional related reloc sym index. */ + STAILQ_ENTRY(_Dwarf_P_Expr_Entry) ee_next; /* Next entry in list. */ +}; + +struct _Dwarf_P_Expr { + Dwarf_Debug pe_dbg; /* Dwarf_Debug pointer. */ + uint8_t *pe_block; /* Expression block data. */ + int pe_invalid; /* Block data is up-to-date or not. */ + Dwarf_Unsigned pe_length; /* Length of the block. */ + STAILQ_HEAD(, _Dwarf_P_Expr_Entry) pe_eelist; /* List of entries. */ + STAILQ_ENTRY(_Dwarf_P_Expr) pe_next; /* Next expr in list. */ +}; + +struct _Dwarf_Line { + Dwarf_LineInfo ln_li; /* Ptr to line info. */ + Dwarf_Addr ln_addr; /* Line address. */ + Dwarf_Unsigned ln_symndx; /* Symbol index for relocation. */ + Dwarf_Unsigned ln_fileno; /* File number. */ + Dwarf_Unsigned ln_lineno; /* Line number. */ + Dwarf_Signed ln_column; /* Column number. */ + Dwarf_Bool ln_bblock; /* Basic block flag. */ + Dwarf_Bool ln_stmt; /* Begin statement flag. */ + Dwarf_Bool ln_endseq; /* End sequence flag. */ + STAILQ_ENTRY(_Dwarf_Line) ln_next; /* Next line in list. */ +}; + +struct _Dwarf_LineFile { + char *lf_fname; /* Filename. */ + char *lf_fullpath; /* Full pathname of the file. */ + Dwarf_Unsigned lf_dirndx; /* Dir index. */ + Dwarf_Unsigned lf_mtime; /* Modification time. */ + Dwarf_Unsigned lf_size; /* File size. */ + Dwarf_Form_Data16 lf_md5; /* File md5 digest. */ + STAILQ_ENTRY(_Dwarf_LineFile) lf_next; /* Next file in list. */ +}; + +struct _Dwarf_LineInfo { + Dwarf_Unsigned li_length; /* Length of line info data. */ + Dwarf_Half li_version; /* Version of line info. */ + Dwarf_Unsigned li_hdrlen; /* Length of line info header. */ + Dwarf_Small li_minlen; /* Minimum instrutction length. */ + Dwarf_Small li_maxop; /* Maximum operations per inst. */ + Dwarf_Small li_defstmt; /* Default value of is_stmt. */ + int8_t li_lbase; /* Line base for special opcode. */ + Dwarf_Small li_lrange; /* Line range for special opcode. */ + Dwarf_Small li_opbase; /* Fisrt std opcode number. */ + Dwarf_Small *li_oplen; /* Array of std opcode len. */ + char **li_incdirs; /* Array of include dirs. */ + Dwarf_Unsigned li_inclen; /* Length of inc dir array. */ + char **li_lfnarray; /* Array of file names. */ + Dwarf_Unsigned li_lflen; /* Length of filename array. */ + STAILQ_HEAD(, _Dwarf_LineFile) li_lflist; /* List of files. */ + Dwarf_Line *li_lnarray; /* Array of lines. */ + Dwarf_Unsigned li_lnlen; /* Length of the line array. */ + STAILQ_HEAD(, _Dwarf_Line) li_lnlist; /* List of lines. */ +}; + +struct _Dwarf_NamePair { + Dwarf_NameTbl np_nt; /* Ptr to containing name table. */ + Dwarf_Die np_die; /* Ptr to Ref. Die. */ + Dwarf_Unsigned np_offset; /* Offset in CU. */ + char *np_name; /* Object/Type name. */ + STAILQ_ENTRY(_Dwarf_NamePair) np_next; /* Next pair in the list. */ +}; + +struct _Dwarf_NameTbl { + Dwarf_Unsigned nt_length; /* Name lookup table length. */ + Dwarf_Half nt_version; /* Name lookup table version. */ + Dwarf_CU nt_cu; /* Ptr to Ref. CU. */ + Dwarf_Off nt_cu_offset; /* Ref. CU offset in .debug_info */ + Dwarf_Unsigned nt_cu_length; /* Ref. CU length. */ + STAILQ_HEAD(, _Dwarf_NamePair) nt_nplist; /* List of offset+name pairs. */ + STAILQ_ENTRY(_Dwarf_NameTbl) nt_next; /* Next name table in the list. */ +}; + +struct _Dwarf_NameSec { + STAILQ_HEAD(, _Dwarf_NameTbl) ns_ntlist; /* List of name tables. */ + Dwarf_NamePair *ns_array; /* Array of pairs of all tables. */ + Dwarf_Unsigned ns_len; /* Length of the pair array. */ +}; + +struct _Dwarf_Fde { + Dwarf_Debug fde_dbg; /* Ptr to containing dbg. */ + Dwarf_Cie fde_cie; /* Ptr to associated CIE. */ + Dwarf_FrameSec fde_fs; /* Ptr to containing .debug_frame. */ + Dwarf_Ptr fde_addr; /* Ptr to start of the FDE. */ + Dwarf_Unsigned fde_offset; /* Offset of the FDE. */ + Dwarf_Unsigned fde_length; /* Length of the FDE. */ + Dwarf_Unsigned fde_cieoff; /* Offset of associated CIE. */ + Dwarf_Unsigned fde_initloc; /* Initial location. */ + Dwarf_Unsigned fde_adrange; /* Address range. */ + Dwarf_Unsigned fde_auglen; /* Augmentation length. */ + uint8_t *fde_augdata; /* Augmentation data. */ + uint8_t *fde_inst; /* Instructions. */ + Dwarf_Unsigned fde_instlen; /* Length of instructions. */ + Dwarf_Unsigned fde_instcap; /* Capacity of inst buffer. */ + Dwarf_Unsigned fde_symndx; /* Symbol index for relocation. */ + Dwarf_Unsigned fde_esymndx; /* End symbol index for relocation. */ + Dwarf_Addr fde_eoff; /* Offset from the end symbol. */ + STAILQ_ENTRY(_Dwarf_Fde) fde_next; /* Next FDE in list. */ +}; + +struct _Dwarf_Cie { + Dwarf_Debug cie_dbg; /* Ptr to containing dbg. */ + Dwarf_Unsigned cie_index; /* Index of the CIE. */ + Dwarf_Unsigned cie_offset; /* Offset of the CIE. */ + Dwarf_Unsigned cie_length; /* Length of the CIE. */ + Dwarf_Half cie_version; /* CIE version. */ + uint8_t *cie_augment; /* CIE augmentation (UTF-8). */ + Dwarf_Unsigned cie_ehdata; /* Optional EH Data. */ + uint8_t cie_addrsize; /* Address size. (DWARF4) */ + uint8_t cie_segmentsize; /* Segment size. (DWARF4) */ + Dwarf_Unsigned cie_caf; /* Code alignment factor. */ + Dwarf_Signed cie_daf; /* Data alignment factor. */ + Dwarf_Unsigned cie_ra; /* Return address register. */ + Dwarf_Unsigned cie_auglen; /* Augmentation length. */ + uint8_t *cie_augdata; /* Augmentation data; */ + uint8_t cie_fde_encode; /* FDE PC start/range encode. */ + Dwarf_Ptr cie_initinst; /* Initial instructions. */ + Dwarf_Unsigned cie_instlen; /* Length of init instructions. */ + STAILQ_ENTRY(_Dwarf_Cie) cie_next; /* Next CIE in list. */ +}; + +struct _Dwarf_FrameSec { + STAILQ_HEAD(, _Dwarf_Cie) fs_cielist; /* List of CIE. */ + STAILQ_HEAD(, _Dwarf_Fde) fs_fdelist; /* List of FDE. */ + Dwarf_Cie *fs_ciearray; /* Array of CIE. */ + Dwarf_Unsigned fs_cielen; /* Length of CIE array. */ + Dwarf_Fde *fs_fdearray; /* Array of FDE.*/ + Dwarf_Unsigned fs_fdelen; /* Length of FDE array. */ +}; + +struct _Dwarf_Arange { + Dwarf_ArangeSet ar_as; /* Ptr to the set it belongs to. */ + Dwarf_Unsigned ar_address; /* Start PC. */ + Dwarf_Unsigned ar_range; /* PC range. */ + Dwarf_Unsigned ar_symndx; /* First symbol index for reloc. */ + Dwarf_Unsigned ar_esymndx; /* Second symbol index for reloc. */ + Dwarf_Addr ar_eoff; /* Offset from second symbol. */ + STAILQ_ENTRY(_Dwarf_Arange) ar_next; /* Next arange in list. */ +}; + +struct _Dwarf_ArangeSet { + Dwarf_Unsigned as_length; /* Length of the arange set. */ + Dwarf_Half as_version; /* Version of the arange set. */ + Dwarf_Off as_cu_offset; /* Offset of associated CU. */ + Dwarf_CU as_cu; /* Ptr to associated CU. */ + Dwarf_Small as_addrsz; /* Target address size. */ + Dwarf_Small as_segsz; /* Target segment size. */ + STAILQ_HEAD (, _Dwarf_Arange) as_arlist; /* List of ae entries. */ + STAILQ_ENTRY(_Dwarf_ArangeSet) as_next; /* Next set in list. */ +}; + +struct _Dwarf_MacroSet { + Dwarf_Macro_Details *ms_mdlist; /* Array of macinfo entries. */ + Dwarf_Unsigned ms_cnt; /* Length of the array. */ + STAILQ_ENTRY(_Dwarf_MacroSet) ms_next; /* Next set in list. */ +}; + +struct _Dwarf_Rangelist { + Dwarf_CU rl_cu; /* Ptr to associated CU. */ + Dwarf_Unsigned rl_offset; /* Offset of the rangelist. */ + Dwarf_Ranges *rl_rgarray; /* Array of ranges. */ + Dwarf_Unsigned rl_rglen; /* Length of the ranges array. */ + STAILQ_ENTRY(_Dwarf_Rangelist) rl_next; /* Next rangelist in list. */ +}; + +struct _Dwarf_CU { + Dwarf_Debug cu_dbg; /* Ptr to containing dbg. */ + Dwarf_Off cu_offset; /* Offset to the this CU. */ + uint32_t cu_length; /* Length of CU data. */ + uint16_t cu_length_size; /* Size in bytes of the length field. */ + uint16_t cu_version; /* DWARF version. */ + uint64_t cu_abbrev_offset; /* Offset into .debug_abbrev. */ + uint64_t cu_abbrev_offset_cur; /* Current abbrev offset. */ + int cu_abbrev_loaded; /* Abbrev table parsed. */ + uint64_t cu_abbrev_cnt; /* Abbrev entry count. */ + uint64_t cu_lineno_offset; /* Offset into .debug_lineno. */ + uint64_t cu_dwo_id; /* DWARF5 dwo id. */ + uint8_t cu_pointer_size;/* Number of bytes in pointer. */ + uint8_t cu_dwarf_size; /* CU section dwarf size. */ + uint8_t cu_unit_type; /* DWARF5 unit type. */ + Dwarf_Sig8 cu_type_sig; /* Type unit's signature. */ + uint64_t cu_type_offset; /* Type unit's type offset. */ + Dwarf_Off cu_next_offset; /* Offset to the next CU. */ + uint64_t cu_1st_offset; /* First DIE offset. */ + int cu_stroff_base_valid; /* DWARF5 str offset base is valid. */ + uint64_t cu_stroff_base; /* DWARF5 base offset into str offsets. */ + int cu_pass2; /* Two pass DIE traverse. */ + Dwarf_LineInfo cu_lineinfo; /* Ptr to Dwarf_LineInfo. */ + Dwarf_Abbrev cu_abbrev_hash; /* Abbrev hash table. */ + Dwarf_Bool cu_is_info; /* Compilation/type unit flag. */ + STAILQ_ENTRY(_Dwarf_CU) cu_next; /* Next compilation unit. */ +}; + +typedef struct _Dwarf_Section { + const char *ds_name; /* Section name. */ + Dwarf_Small *ds_data; /* Section data. */ + Dwarf_Unsigned ds_addr; /* Section virtual addr. */ + Dwarf_Unsigned ds_size; /* Section size. */ +} Dwarf_Section; + +typedef struct _Dwarf_P_Section { + char *ds_name; /* Section name. */ + Dwarf_Small *ds_data; /* Section data. */ + Dwarf_Unsigned ds_size; /* Section size. */ + Dwarf_Unsigned ds_cap; /* Section capacity. */ + Dwarf_Unsigned ds_ndx; /* ELF section index. */ + Dwarf_Unsigned ds_symndx; /* Section symbol index. (for reloc) */ + STAILQ_ENTRY(_Dwarf_P_Section) ds_next; /* Next section in the list. */ +} *Dwarf_P_Section; + +typedef struct _Dwarf_Rel_Entry { + unsigned char dre_type; /* Reloc type. */ + unsigned char dre_length; /* Reloc storage unit length. */ + Dwarf_Unsigned dre_offset; /* Reloc storage unit offset. */ + Dwarf_Unsigned dre_addend; /* Reloc addend. */ + Dwarf_Unsigned dre_symndx; /* Reloc symbol index. */ + const char *dre_secname; /* Refer to some debug section. */ + STAILQ_ENTRY(_Dwarf_Rel_Entry) dre_next; /* Next reloc entry. */ +} *Dwarf_Rel_Entry; + +typedef struct _Dwarf_Rel_Section { + struct _Dwarf_P_Section *drs_ds; /* Ptr to actual reloc ELF section. */ + struct _Dwarf_P_Section *drs_ref; /* Which debug section it refers. */ + struct Dwarf_Relocation_Data_s *drs_drd; /* Reloc data array. */ + STAILQ_HEAD(, _Dwarf_Rel_Entry) drs_dre; /* Reloc entry list. */ + Dwarf_Unsigned drs_drecnt; /* Count of entries. */ + Dwarf_Unsigned drs_size; /* Size of ELF section in bytes. */ + int drs_addend; /* Elf_Rel or Elf_Rela */ + STAILQ_ENTRY(_Dwarf_Rel_Section) drs_next; /* Next reloc section. */ +} *Dwarf_Rel_Section; + +typedef struct { + Elf_Data *ed_data; + void *ed_alloc; +} Dwarf_Elf_Data; + +typedef struct { + Elf *eo_elf; + GElf_Ehdr eo_ehdr; + GElf_Shdr *eo_shdr; + Dwarf_Elf_Data *eo_data; + Dwarf_Unsigned eo_seccnt; + size_t eo_strndx; + Dwarf_Obj_Access_Methods eo_methods; +} Dwarf_Elf_Object; + +typedef struct _Dwarf_StrOffsets { + Dwarf_Unsigned so_length; + Dwarf_Half so_version; + Dwarf_Unsigned so_header_size; + Dwarf_Small so_dwarf_size; + Dwarf_Small *so_data; +} Dwarf_StrOffsets; + +struct _Dwarf_Debug { + Dwarf_Obj_Access_Interface *dbg_iface; + Dwarf_Section *dbg_section; /* Dwarf section list. */ + Dwarf_Section *dbg_info_sec; /* Pointer to info section. */ + Dwarf_Off dbg_info_off; /* Current info section offset. */ + Dwarf_Section *dbg_types_sec; /* Pointer to type section. */ + Dwarf_Off dbg_types_off; /* Current types section offset. */ + Dwarf_Unsigned dbg_seccnt; /* Total number of dwarf sections. */ + int dbg_mode; /* Access mode. */ + int dbg_pointer_size; /* Object address size. */ + int dbg_offset_size; /* DWARF offset size. */ + int dbg_info_loaded; /* Flag indicating all CU loaded. */ + int dbg_types_loaded; /* Flag indicating all TU loaded. */ + Dwarf_Half dbg_machine; /* ELF machine architecture. */ + Dwarf_Handler dbg_errhand; /* Error handler. */ + Dwarf_Ptr dbg_errarg; /* Argument to the error handler. */ + STAILQ_HEAD(, _Dwarf_CU) dbg_cu;/* List of compilation units. */ + STAILQ_HEAD(, _Dwarf_CU) dbg_tu;/* List of type units. */ + Dwarf_CU dbg_cu_current; /* Ptr to the current CU. */ + Dwarf_CU dbg_tu_current; /* Ptr to the current TU. */ + Dwarf_NameSec dbg_globals; /* Ptr to pubnames lookup section. */ + Dwarf_NameSec dbg_pubtypes; /* Ptr to pubtypes lookup section. */ + Dwarf_NameSec dbg_weaks; /* Ptr to weaknames lookup section. */ + Dwarf_NameSec dbg_funcs; /* Ptr to static funcs lookup sect. */ + Dwarf_NameSec dbg_vars; /* Ptr to static vars lookup sect. */ + Dwarf_NameSec dbg_types; /* Ptr to types lookup section. */ + Dwarf_FrameSec dbg_frame; /* Ptr to .debug_frame section. */ + Dwarf_FrameSec dbg_eh_frame; /* Ptr to .eh_frame section. */ + STAILQ_HEAD(, _Dwarf_ArangeSet) dbg_aslist; /* List of arange set. */ + Dwarf_Arange *dbg_arange_array; /* Array of arange. */ + Dwarf_Unsigned dbg_arange_cnt; /* Length of the arange array. */ + char *dbg_strtab; /* Dwarf string table. */ + Dwarf_Unsigned dbg_strtab_cap; /* Dwarf string table capacity. */ + Dwarf_Unsigned dbg_strtab_size; /* Dwarf string table size. */ + char *dbg_line_strtab;/* Dwarf line info string table. */ + Dwarf_StrOffsets *dbg_str_offsets; /* Dwarf string offsets. */ + STAILQ_HEAD(, _Dwarf_MacroSet) dbg_mslist; /* List of macro set. */ + STAILQ_HEAD(, _Dwarf_Rangelist) dbg_rllist; /* List of rangelist. */ + uint64_t (*read)(uint8_t *, uint64_t *, int); + void (*write)(uint8_t *, uint64_t *, uint64_t, int); + int (*write_alloc)(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); + uint64_t (*decode)(uint8_t **, int); + + Dwarf_Half dbg_frame_rule_table_size; + Dwarf_Half dbg_frame_rule_initial_value; + Dwarf_Half dbg_frame_cfa_value; + Dwarf_Half dbg_frame_same_value; + Dwarf_Half dbg_frame_undefined_value; + + Dwarf_Regtable3 *dbg_internal_reg_table; + + /* + * Fields used by libdwarf producer. + */ + + Dwarf_Unsigned dbgp_flags; + Dwarf_Unsigned dbgp_isa; + Dwarf_Callback_Func dbgp_func; + Dwarf_Callback_Func_b dbgp_func_b; + Dwarf_Die dbgp_root_die; + STAILQ_HEAD(, _Dwarf_Die) dbgp_dielist; + STAILQ_HEAD(, _Dwarf_P_Expr) dbgp_pelist; + Dwarf_LineInfo dbgp_lineinfo; + Dwarf_ArangeSet dbgp_as; + Dwarf_Macro_Details *dbgp_mdlist; + Dwarf_Unsigned dbgp_mdcnt; + STAILQ_HEAD(, _Dwarf_Cie) dbgp_cielist; + STAILQ_HEAD(, _Dwarf_Fde) dbgp_fdelist; + Dwarf_Unsigned dbgp_cielen; + Dwarf_Unsigned dbgp_fdelen; + Dwarf_NameTbl dbgp_pubs; + Dwarf_NameTbl dbgp_weaks; + Dwarf_NameTbl dbgp_funcs; + Dwarf_NameTbl dbgp_types; + Dwarf_NameTbl dbgp_vars; + STAILQ_HEAD(, _Dwarf_P_Section) dbgp_seclist; + Dwarf_Unsigned dbgp_seccnt; + Dwarf_P_Section dbgp_secpos; + Dwarf_P_Section dbgp_info; + STAILQ_HEAD(, _Dwarf_Rel_Section) dbgp_drslist; + Dwarf_Unsigned dbgp_drscnt; + Dwarf_Rel_Section dbgp_drspos; +}; + +/* + * Internal function prototypes. + */ + +int _dwarf_abbrev_add(Dwarf_CU, uint64_t, uint64_t, uint8_t, + uint64_t, Dwarf_Abbrev *, Dwarf_Error *); +void _dwarf_abbrev_cleanup(Dwarf_CU); +int _dwarf_abbrev_find(Dwarf_CU, uint64_t, Dwarf_Abbrev *, + Dwarf_Error *); +int _dwarf_abbrev_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_abbrev_parse(Dwarf_Debug, Dwarf_CU, Dwarf_Unsigned *, + Dwarf_Abbrev *, Dwarf_Error *); +int _dwarf_add_AT_dataref(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Unsigned, Dwarf_Unsigned, const char *, + Dwarf_P_Attribute *, Dwarf_Error *); +int _dwarf_add_string_attr(Dwarf_P_Die, Dwarf_P_Attribute *, + Dwarf_Half, char *, Dwarf_Error *); +int _dwarf_alloc(Dwarf_Debug *, int, Dwarf_Error *); +void _dwarf_arange_cleanup(Dwarf_Debug); +int _dwarf_arange_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_arange_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_arange_pro_cleanup(Dwarf_P_Debug); +int _dwarf_attr_alloc(Dwarf_Die, Dwarf_Attribute *, Dwarf_Error *); +Dwarf_Attribute _dwarf_attr_find(Dwarf_Die, Dwarf_Half); +int _dwarf_attr_gen(Dwarf_P_Debug, Dwarf_P_Section, Dwarf_Rel_Section, + Dwarf_CU, Dwarf_Die, int, Dwarf_Error *); +int _dwarf_attr_init(Dwarf_Debug, Dwarf_Section *, uint64_t *, int, + Dwarf_CU, Dwarf_Die, Dwarf_AttrDef, uint64_t, int, + Dwarf_Error *); +int _dwarf_attrdef_add(Dwarf_Debug, Dwarf_Abbrev, uint64_t, + uint64_t, int64_t, uint64_t, Dwarf_AttrDef *, + Dwarf_Error *); +uint64_t _dwarf_decode_lsb(uint8_t **, int); +uint64_t _dwarf_decode_msb(uint8_t **, int); +int64_t _dwarf_decode_sleb128(uint8_t **); +uint64_t _dwarf_decode_uleb128(uint8_t **); +void _dwarf_deinit(Dwarf_Debug); +int _dwarf_die_alloc(Dwarf_Debug, Dwarf_Die *, Dwarf_Error *); +int _dwarf_die_count_links(Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die); +Dwarf_Die _dwarf_die_find(Dwarf_Die, Dwarf_Unsigned); +int _dwarf_die_gen(Dwarf_P_Debug, Dwarf_CU, Dwarf_Rel_Section, + Dwarf_Error *); +void _dwarf_die_link(Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die); +int _dwarf_die_parse(Dwarf_Debug, Dwarf_Section *, Dwarf_CU, int, + uint64_t, uint64_t, Dwarf_Die *, int, Dwarf_Error *); +void _dwarf_die_pro_cleanup(Dwarf_P_Debug); +void _dwarf_elf_deinit(Dwarf_Debug); +int _dwarf_elf_init(Dwarf_Debug, Elf *, Dwarf_Error *); +int _dwarf_elf_load_section(void *, Dwarf_Half, Dwarf_Small **, + int *); +Dwarf_Endianness _dwarf_elf_get_byte_order(void *); +Dwarf_Small _dwarf_elf_get_length_size(void *); +Dwarf_Small _dwarf_elf_get_pointer_size(void *); +Dwarf_Unsigned _dwarf_elf_get_section_count(void *); +int _dwarf_elf_get_section_info(void *, Dwarf_Half, + Dwarf_Obj_Access_Section *, int *); +void _dwarf_expr_cleanup(Dwarf_P_Debug); +int _dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Error *); +Dwarf_Section *_dwarf_find_next_types_section(Dwarf_Debug, Dwarf_Section *); +Dwarf_Section *_dwarf_find_section(Dwarf_Debug, const char *); +void _dwarf_frame_cleanup(Dwarf_Debug); +int _dwarf_frame_fde_add_inst(Dwarf_P_Fde, Dwarf_Small, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +int _dwarf_frame_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t, uint8_t *, + Dwarf_Unsigned, Dwarf_Frame_Op **, Dwarf_Signed *, + Dwarf_Error *); +int _dwarf_frame_get_internal_table(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable3 **, Dwarf_Addr *, Dwarf_Error *); +int _dwarf_frame_interal_table_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_frame_params_init(Dwarf_Debug); +void _dwarf_frame_pro_cleanup(Dwarf_P_Debug); +int _dwarf_frame_regtable_copy(Dwarf_Debug, Dwarf_Regtable3 **, + Dwarf_Regtable3 *, Dwarf_Error *); +int _dwarf_frame_section_load(Dwarf_Debug, Dwarf_Error *); +int _dwarf_frame_section_load_eh(Dwarf_Debug, Dwarf_Error *); +int _dwarf_generate_sections(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_Unsigned _dwarf_get_reloc_type(Dwarf_P_Debug, int); +int _dwarf_get_reloc_size(Dwarf_Debug, Dwarf_Unsigned); +void _dwarf_info_cleanup(Dwarf_Debug); +int _dwarf_info_first_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_first_tu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_info_load(Dwarf_Debug, Dwarf_Bool, Dwarf_Bool, + Dwarf_Error *); +int _dwarf_info_next_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_next_tu(Dwarf_Debug, Dwarf_Error *); +void _dwarf_info_pro_cleanup(Dwarf_P_Debug); +int _dwarf_init(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Handler, + Dwarf_Ptr, Dwarf_Error *); +int _dwarf_lineno_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_lineno_init(Dwarf_Die, uint64_t, Dwarf_Error *); +void _dwarf_lineno_cleanup(Dwarf_LineInfo); +void _dwarf_lineno_pro_cleanup(Dwarf_P_Debug); +int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *, + uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t, + Dwarf_Error *); +int _dwarf_loc_fill_locexpr(Dwarf_Debug, Dwarf_Locdesc **, + uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t, + Dwarf_Error *); +int _dwarf_loc_add(Dwarf_Die, Dwarf_Attribute, Dwarf_Error *); +int _dwarf_loc_expr_add_atom(Dwarf_Debug, uint8_t *, uint8_t *, + Dwarf_Small, Dwarf_Unsigned, Dwarf_Unsigned, int *, + Dwarf_Error *); +int _dwarf_loclist_find(Dwarf_Debug, Dwarf_CU, uint64_t, + Dwarf_Locdesc ***, Dwarf_Signed *, Dwarf_Unsigned *, + Dwarf_Error *); +void _dwarf_macinfo_cleanup(Dwarf_Debug); +int _dwarf_macinfo_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_macinfo_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_macinfo_pro_cleanup(Dwarf_P_Debug); +int _dwarf_nametbl_init(Dwarf_Debug, Dwarf_NameSec *, + Dwarf_Section *, Dwarf_Error *); +void _dwarf_nametbl_cleanup(Dwarf_NameSec *); +int _dwarf_nametbl_gen(Dwarf_P_Debug, const char *, Dwarf_NameTbl, + Dwarf_Error *); +void _dwarf_nametbl_pro_cleanup(Dwarf_NameTbl *); +int _dwarf_pro_callback(Dwarf_P_Debug, char *, int, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned *, int *); +Dwarf_P_Section _dwarf_pro_find_section(Dwarf_P_Debug, const char *); +int _dwarf_ranges_add(Dwarf_Debug, Dwarf_CU, uint64_t, + Dwarf_Rangelist *, Dwarf_Error *); +void _dwarf_ranges_cleanup(Dwarf_Debug); +int _dwarf_ranges_find(Dwarf_Debug, uint64_t, Dwarf_Rangelist *); +uint64_t _dwarf_read_lsb(uint8_t *, uint64_t *, int); +uint64_t _dwarf_read_msb(uint8_t *, uint64_t *, int); +int64_t _dwarf_read_sleb128(uint8_t *, uint64_t *); +uint64_t _dwarf_read_uleb128(uint8_t *, uint64_t *); +char *_dwarf_read_string(void *, Dwarf_Unsigned, uint64_t *); +uint8_t *_dwarf_read_block(void *, uint64_t *, uint64_t); +int _dwarf_reloc_section_finalize(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_Error *); +int _dwarf_reloc_entry_add(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_P_Section, unsigned char, unsigned char, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + const char *, Dwarf_Error *); +int _dwarf_reloc_entry_add_pair(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_P_Section, unsigned char, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +void _dwarf_reloc_cleanup(Dwarf_P_Debug); +int _dwarf_reloc_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_reloc_section_gen(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_Error *); +int _dwarf_reloc_section_init(Dwarf_P_Debug, Dwarf_Rel_Section *, + Dwarf_P_Section, Dwarf_Error *); +void _dwarf_reloc_section_free(Dwarf_P_Debug, Dwarf_Rel_Section *); +void _dwarf_section_cleanup(Dwarf_P_Debug); +int _dwarf_section_callback(Dwarf_P_Debug, Dwarf_P_Section, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +void _dwarf_section_free(Dwarf_P_Debug, Dwarf_P_Section *); +int _dwarf_section_init(Dwarf_P_Debug, Dwarf_P_Section *, + const char *, int, Dwarf_Error *); +void _dwarf_set_error(Dwarf_Debug, Dwarf_Error *, int, int, + const char *, int); +int _dwarf_strtab_add(Dwarf_Debug, char *, uint64_t *, + Dwarf_Error *); +void _dwarf_strtab_cleanup(Dwarf_Debug); +int _dwarf_strtab_gen(Dwarf_P_Debug, Dwarf_Error *); +char *_dwarf_strtab_get_table(Dwarf_Debug); +char *_dwarf_strtab_get_line_table(Dwarf_Debug); +void _dwarf_str_offsets_cleanup(Dwarf_Debug); +int _dwarf_read_indexed_str(Dwarf_Debug, Dwarf_CU, uint64_t, + char **, Dwarf_Error *); +int _dwarf_strtab_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_type_unit_cleanup(Dwarf_Debug); +void _dwarf_write_block(void *, uint64_t *, uint8_t *, uint64_t); +int _dwarf_write_block_alloc(uint8_t **, uint64_t *, uint64_t *, + uint8_t *, uint64_t, Dwarf_Error *); +void _dwarf_write_lsb(uint8_t *, uint64_t *, uint64_t, int); +int _dwarf_write_lsb_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); +void _dwarf_write_msb(uint8_t *, uint64_t *, uint64_t, int); +int _dwarf_write_msb_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); +void _dwarf_write_padding(void *, uint64_t *, uint8_t, uint64_t); +int _dwarf_write_padding_alloc(uint8_t **, uint64_t *, uint64_t *, + uint8_t, uint64_t, Dwarf_Error *); +void _dwarf_write_string(void *, uint64_t *, char *); +int _dwarf_write_string_alloc(uint8_t **, uint64_t *, uint64_t *, + char *, Dwarf_Error *); +int _dwarf_write_sleb128(uint8_t *, uint8_t *, int64_t); +int _dwarf_write_sleb128_alloc(uint8_t **, uint64_t *, uint64_t *, + int64_t, Dwarf_Error *); +int _dwarf_write_uleb128(uint8_t *, uint8_t *, uint64_t); +int _dwarf_write_uleb128_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, Dwarf_Error *); + +#endif /* !__LIBDWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/dwarf.3 b/contrib/elftoolchain/libdwarf/dwarf.3 new file mode 100644 index 0000000000..08a3eb68df --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf.3 @@ -0,0 +1,753 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf.3 3929 2021-03-07 21:43:46Z jkoshy $ +.\" +.Dd December 21, 2014 +.Dt DWARF 3 +.Os +.Sh NAME +.Nm dwarf +.Nd access debugging information in object files +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Sh DESCRIPTION +The +.Lb libdwarf +provides functions that allow an application to read and write debugging +information in object files. +The format of debugging information accessible through this API +is defined by the DWARF standard, see +.Xr dwarf 4 . +.Pp +The +.Xr DWARF 3 +API has two parts: +.Bl -bullet +.It +A consumer API set allows applications to read existing debug information +in a program object. +The functions that comprise the DWARF consumer API are described in +the section +.Sx "DWARF Consumer API" +below. +.It +A producer API set that allows applications to add debug information +to a program object. +The functions that comprise the DWARF producer API are described in +the section +.Sx "DWARF Producer API" +below. +.El +.Pp +Each function referenced below is further described in its own manual page. +.Ss Namespace use +The DWARF library uses the following prefixes: +.Pp +.Bl -tag -width ".Li Dwarf_*" -compact +.It Li DWARF_* +Used for error numbers and constants. +.It Li DW_* +Used for constants. +.It Li Dwarf_* +Used for types. +.It Li dwarf_* +Used for functions and macros that make up the API. +.El +.Ss Data Types +The DWARF(3) API uses the following data types: +.Pp +.Bl -tag -width ".Vt Dwarf_Unsigned" -compact +.It Vt Dwarf_Abbrev +Describes DWARF abbreviations. +.It Vt Dwarf_Addr +A program address in the target object. +.It Vt Dwarf_Arange +Describes address ranges. +.It Vt Dwarf_Attribute , Vt Dwarf_P_Attribute +Describes attributes of debugging information entries. +.It Vt Dwarf_Bool +Used for boolean states. +.It Vt Dwarf_Cie , Vt Dwarf_P_Cie +Describes call information that is common to several frames. +.It Vt Dwarf_Debug , Vt Dwarf_P_Debug +An opaque type describing a debug context. +.It Vt Dwarf_Die , Vt Dwarf_P_Die +A debugging information entry. +.It Vt Dwarf_Fde , Vt Dwarf_P_Fde +A frame descriptor. +.It Vt Dwarf_Func +A descriptor representing a function. +.It Vt Dwarf_Global +A descriptor representing a global name. +.It Vt Dwarf_Half +A 16-bit wide unsigned numeric type. +.It Vt Dwarf_Handler +A pointer to an error handling function. +.It Vt Dwarf_Line +A descriptor for a source line. +.It Vt Dwarf_Off +An unsigned file offset. +.It Vt Dwarf_P_Expr +A descriptor for a location expression. +.It Vt Dwarf_Ptr +A virtual address used by an application. +.It Vt Dwarf_Signed +A 64-bit wide signed numeric type. +.It Vt Dwarf_Small +An 8-bit wide unsigned numeric type. +.It Vt Dwarf_Type +A descriptor representing a user-specified type. +.It Vt Dwarf_Unsigned +A 64-bit wide unsigned numeric type. +.It Vt Dwarf_Var +A descriptor representing a static variable. +.It Vt Dwarf_Weak +A descriptor representing a weak name. +.El +.Ss Error Handling +Library functions that encounter an error will return with a value +other than +.Dv DW_DLV_OK . +.Pp +The +.Lb libdwarf +allows applications to specify three levels of error handling: +.Bl -enum -compact +.It +Most library functions take a parameter of type +.Vt Dwarf_Error +that specifies a location to store an error descriptor in +case of an error. +If an error occurs during the execution on an API, and if this +parameter is +.No non- Ns Dv NULL , +then an error descriptor is written to the location specified. +.It +Otherwise, if the error parameter was +.Dv NULL , +but if an error handler was defined for the debug context in use using +.Xr dwarf_init 3 +or +.Xr dwarf_seterrhand 3 , +then the library will invoke the specified error handler with an error +descriptor as argument. +.It +Otherwise, if a library wide error handler was specified using +.Xr dwarf_seterrhand 3 , +it is called. +.El +.Pp +Error descriptors may be used with +.Xr dwarf_errmsg 3 +or +.Xr dwarf_errno 3 . +.Sh The DWARF Consumer API +The DWARF consumer API permits applications to read DWARF information in +an object file. +.Pp +The major functional groups of functions in the consumer API are listed +below. +.Pp +.Bl -tag -compact -width "CCCC" +.It Abbreviations +.Bl -tag -compact -width indent +.It Fn dwarf_get_abbrev +Retrieve abbreviation information at a given offset. +.It Fn dwarf_get_abbrev_children_flag +Check if an abbreviation has child elements. +.It Fn dwarf_get_abbrev_code +Retrieve the abbreviation code for an abbreviation entry descriptor. +.It Fn dwarf_get_abbrev_entry +Retrieve abbreviation information for an abbreviation entry +descriptor. +.It Fn dwarf_get_abbrev_tag +Retrieve the tag for an abbreviation entry. +.El +.It Addresses +.Bl -tag -compact -width indent +.It Fn dwarf_get_address_size +Return the number of bytes needed to represent an address. +.It Fn dwarf_get_arange +Search for an address range descriptor covering an address. +.It Fn dwarf_get_arange_cu_header_offset +Retrieve the offsets associated with an address range descriptor. +.It Fn dwarf_get_arange_info +Extract address range information from a descriptor. +.It Fn dwarf_get_aranges +Retrieve program address space mappings. +.It Fn dwarf_get_cu_die_offset +Retrieve the offset associated with a compilation unit for an address +range descriptor. +.It Fn dwarf_get_ranges , Fn dwarf_get_ranges_a +Retrieve information about non-contiguous address ranges for +a debugging information entry. +.El +.It Attributes +.Bl -tag -compact -width indent +.It Fn dwarf_arrayorder +Retrieve the value of a +.Dv DW_AT_ordering +attribute. +.It Fn dwarf_attr +Retrieve an attribute descriptor. +.It Fn dwarf_attrlist +Retrieve attribute descriptors for a debugging information entry. +.It Fn dwarf_attroffset +Retrieve the section-relative offset of an attribute descriptor. +.It Fn dwarf_attrval_flag +Retrieve a +.Dv DW_AT_FORM_flag +value. +.It Fn dwarf_attrval_signed +Retrieve an attribute's value as a signed integral quantity. +.It Fn dwarf_attrval_string +Retrieve an attribute's value as a NUL-terminated string. +.It Fn dwarf_attrval_unsigned +Retrieve an attribute's value as an unsigned integral quantity. +.It Fn dwarf_bitoffset , +Retrieve the value of a +.Dv DW_AT_bit_offset +attribute. +.It Fn dwarf_bitsize , +Retrieve the value of a +.Dv DW_AT_bit_size +attribute. +.It Fn dwarf_bytesize +Retrieve the value of a +.Dv DW_AT_byte_size +attribute. +.It Fn dwarf_formaddr +Return the value of an +.Dv ADDRESS Ns - Ns +class attribute. +.It Fn dwarf_formblock +Return the value of a +.Dv BLOCK Ns - Ns +class attribute +.It Fn dwarf_formexprloc +Return information about a location expression. +.It Fn dwarf_formflag +Retrieve information about a +.Dv BOOLEAN Ns - Ns +class attribute. +.It Fn dwarf_formref , Fn dwarf_global_formref +Retrieve offsets for +.Dv REFERENCE Ns - Ns +class attributes. +.It Fn dwarf_formsdata , Fn dwarf_formudata +Retrieve the value of a +.Dv CONSTANT Ns - Ns +class attribute. +.It Fn dwarf_formsig8 +Return the type signature for a DWARF type. +.It Fn dwarf_formstring +Retrieve information about a +.Dv STRING Ns - Ns +class attribute. +.It Fn dwarf_get_form_class +Retrieve the form class for an attribute. +.It Fn dwarf_hasattr +Check for the presence of an attribute. +.It Fn dwarf_hasform +Check if an attribute has the given form. +.It Fn dwarf_whatattr +Retrieve the attribute code for an attribute. +.It Fn dwarf_whatform , Fn dwarf_whatform_direct +Retrieve the form of an attribute. +.El +.It Call Information Entries and Frame Descriptor Entries +.Bl -tag -compact -width indent +.It Fn dwarf_get_cie_index +Retrieve the index for a CIE descriptor. +.It Fn dwarf_get_cie_info +Retrieve information from a CIE descriptor. +.It Fn dwarf_get_cie_of_fde +Retrieve a CIE descriptor. +.It Fn dwarf_get_fde_at_pc +Retrieve an FDE descriptor for an address. +.It Fn dwarf_get_fde_info_for_all_regs +Retrieve register rule row. +.It Fn dwarf_get_fde_info_for_all_regs3 +Retrieve register rule row (revised API). +.It Fn dwarf_get_fde_info_for_cfa_reg3 +Retrieve a CFA register rule. +.It Fn dwarf_get_fde_info_for_reg +Retrieve a register rule. +.It Fn dwarf_get_fde_info_for_reg3 +Retrieve a register rule (revised API). +.It Fn dwarf_get_fde_instr_bytes +Retrieve instructions from an FDE descriptor. +.It Fn dwarf_get_fde_list , Fn dwarf_get_fde_list_eh +Retrieve frame information. +.It Fn dwarf_get_fde_n +Retrieve an FDE descriptor. +.It Fn dwarf_get_fde_range +Retrieve range information from an FDE descriptor. +.El +.It Compilation Units +.Bl -tag -compact -width indent +.It Xo +.Fn dwarf_get_cu_die_offset_given_cu_header_offset , +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +.Xc +Retrieve the offset of the debugging information entry for a +compilation or type unit. +.It Xo +.Fn dwarf_next_cu_header , +.Fn dwarf_next_cu_header_b , +.Fn dwarf_next_cu_header_c +.Xc +Step through compilation units in a debug context. +.El +.It Debugging Information Entries +.Bl -tag -compact -width indent +.It Fn dwarf_child +Returns the child of a debugging information entry. +.It Fn dwarf_die_abbrev_code +Returns the abbreviation code for a debugging information entry. +.It Fn dwarf_die_CU_offset , Fn dwarf_die_CU_offset_range +Retrieve offsets and lengths for a compilation unit. +.It Fn dwarf_diename +Returns the +.Dv DW_AT_name +attribute for a debugging information entry. +.It Fn dwarf_dieoffset +Retrieves the offset for a debugging information entry. +.It Fn dwarf_get_die_infotypes_flag +Indicate the originating section for a debugging information entry. +.It Fn dwarf_highpc , Fn dwarf_highpc_b +Return the highest PC value for a debugging information entry. +.It Fn dwarf_lowpc +Return the lowest PC value for a debugging information entry. +.It Fn dwarf_offdie , Fn dwarf_offdie_b +Retrieve a debugging information entry given an offset. +.It Fn dwarf_siblingof , Fn dwarf_siblingof_b +Retrieve the sibling descriptor for a debugging information entry. +.It Fn dwarf_srclang +Retrieve the source language attribute for a debugging information +entry. +.It Fn dwarf_tag +Retrieve the tag for a debugging information entry. +.El +.It Functions +.Bl -tag -compact -width indent +.It Fn dwarf_func_cu_offset +Retrieves the offset for the compilation unit for a function. +.It Fn dwarf_func_die_offset +Retrieves the offset for the debugging information entry for a +function. +.It Fn dwarf_funcname +Retrieves the name of a function. +.It Fn dwarf_func_name_offsets +Retrieve both the name and offsets for a function. +.It Fn dwarf_get_funcs +Retrieve information about static functions. +.El +.It Globals +.Bl -tag -compact -width indent +.It Fn dwarf_get_globals +Retrieve a list of globals. +.It Fn dwarf_global_cu_offset +Return the offset for compilation unit for a global. +.It Fn dwarf_global_die_offset +Return the offset for the debugging information entry for a global. +.It Fn dwarf_global_name_offsets +Return the name and offsets for a global. +.It Fn dwarf_globname +Return the name for a global. +.El +.It Initialization and Finalization +Functions +.Fn dwarf_elf_init +and +.Fn dwarf_init +may be used for initialization. +The function +.Fn dwarf_finish +may be used to release resources. +.Pp +The functions +.Fn dwarf_object_init +and +.Fn dwarf_object_finish +allow an application to specify alternate low-level file access +routines. +.It Line Numbers +.Bl -tag -compact -width indent +.It Fn dwarf_lineaddr +Retrieve the program address for a source line. +.It Fn dwarf_linebeginstatement +Check if a source line corresponds to the beginning of a statement. +.It Fn dwarf_lineblock +Check if a source line corresponds to the start of a basic block. +.It Fn dwarf_lineendsequence +Check if the source line corresponds to the end of a sequence of +instructions. +.It Fn dwarf_lineno +Retrieve the line number for a line descriptor. +.It Fn dwarf_lineoff +Retrieve the column number for a line descriptor. +.It Fn dwarf_linesrc +Retrieve the source file for a line descriptor. +.It Fn dwarf_line_srcfileno +Retrieve the index of the source file for a line descriptor. +.It Fn dwarf_srcfiles +Retrieve source files for a compilation unit. +.It Fn dwarf_srclines +Return line number information for a compilation unit. +.El +.It Location Lists +.Bl -tag -compact -width indent +.It Fn dwarf_get_loclist_entry +Retrieve a location list entry. +.It Fn dwarf_loclist , Fn dwarf_loclist_n +Retrieve location expressions. +.It Xo +.Fn dwarf_loclist_from_expr , +.Fn dwarf_loclist_from_expr_a , +.Fn dwarf_loclist_from_expr_b +.Xc +Translate a location expression into a location descriptor. +.El +.It Error Handling +.Bl -tag -compact -width indent +.It Fn dwarf_errmsg +Retrieve a human-readable error message. +.It Fn dwarf_errno +Retrieve an error number from an error descriptor. +.It Fn dwarf_seterrarg +Set the argument passed to a callback error handler. +.It Fn dwarf_seterrhand +Set the callback handler to be called in case of an error. +.El +.It Frame Handling +.Bl -tag -compact -width indent +.It Fn dwarf_expand_frame_instructions +Translate frame instruction bytes. +.It Fn dwarf_set_frame_cfa_value +Set the CFA parameter for the internal register rule table. +.It Fn dwarf_set_frame_rule_initial_value +Set the initial value of the register rules in the internal register +rule table. +.It Fn dwarf_set_frame_rule_table_size +Set the maximum number of columns in the register rule table. +.It Fn dwarf_set_frame_same_value +Set the register number representing the +.Dq "same value" +rule. +.It Fn dwarf_set_frame_undefined_value +Set the register number representing the +.Dq "undefined" +rule. +.El +.It Macros +.Bl -tag -compact -width indent +.It Fn dwarf_find_macro_value_start +Return the macro value part of a macro string. +.It Fn dwarf_get_macro_details +Retrieve macro information. +.El +.It Memory Management +In the DWARF consumer API, the rules for memory management differ +between functions. +In some cases, the memory areas returned to the application by the +library are freed by calling specific API functions. +In others, the deallocation function +.Fn dwarf_dealloc +suffices. +The individual manual pages for the API's functions document the +specific memory management rules to be followed. +.Pp +The function +.Fn dwarf_dealloc +is used to mark memory arenas as unused. +Additionally, the following functions release specific types of +DWARF resources: +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc , +and +.Fn dwarf_weaks_dealloc . +.It Symbol Constants +The following functions may be used to return symbolic names +for DWARF constants: +.Fn dwarf_get_ACCESS_name , +.Fn dwarf_get_AT_name , +.Fn dwarf_get_ATE_name , +.Fn dwarf_get_CC_name , +.Fn dwarf_get_CFA_name , +.Fn dwarf_get_CHILDREN_name , +.Fn dwarf_get_DS_name , +.Fn dwarf_get_DSC_name , +.Fn dwarf_get_EH_name , +.Fn dwarf_get_END_name , +.Fn dwarf_get_FORM_name , +.Fn dwarf_get_ID_name , +.Fn dwarf_get_INL_name , +.Fn dwarf_get_LANG_name , +.Fn dwarf_get_LNE_name , +.Fn dwarf_get_LNS_name , +.Fn dwarf_get_MACINFO_name , +.Fn dwarf_get_OP_name , +.Fn dwarf_get_ORD_name , +.Fn dwarf_get_TAG_name , +.Fn dwarf_get_VIRTUALITY_name , +and +.Fn dwarf_get_VIS_name . +.It Types +.Bl -tag -compact -width indent +.It Fn dwarf_get_pubtypes , Fn dwarf_get_types +Retrieve descriptors for user-defined types. +.It Fn dwarf_next_types_section +Step through +.Dq \&.debug_types +sections in a debug context. +.It Fn dwarf_pubtype_cu_offset , Fn dwarf_type_cu_offset +Return the offset for the compilation unit for a type. +.It Fn dwarf_pubtype_die_offset , Fn dwarf_type_die_offset +Return the offset for the debugging information entry for a type. +.It Fn dwarf_pubtypename , Fn dwarf_typename +Retrieve the name of a type. +.It Fn dwarf_pubtype_name_offsets , Fn dwarf_type_name_offsets +Retrieve the name and offsets for a type. +.El +.It Variables +.Bl -tag -compact -width indent +.It Fn dwarf_get_vars +Retrieve descriptors for static variables. +.It Fn dwarf_var_cu_offset +Return the offset for the compilation unit for a variable. +.It Fn dwarf_var_die_offset +Return the offset for the debugging information entry for a variable. +.It Fn dwarf_varname +Retrieve the name of a variable. +.It Fn dwarf_var_name_offsets +Retrieve the name and offsets for a variable. +.El +.It Weak Symbols +.Bl -tag -compact -width indent +.It Fn dwarf_get_weaks +Retrieve information about weak symbols. +.It Fn dwarf_weak_cu_offset +Return the offset for the compilation unit for a weak symbol. +.It Fn dwarf_weak_die_offset +Return the offset for the debugging information entry for a weak symbol. +.It Fn dwarf_weakname +Retrieve the name of a weak symbol. +.It Fn dwarf_weak_name_offsets +Retrieve the name and offsets for a weak symbol. +.El +.It Miscellaneous +.Bl -tag -compact -width indent +.It Fn dwarf_get_elf +Retrieve the ELF descriptor for a debug context, see +.Xr elf 3 . +.It Fn dwarf_get_str +Retrieve a NUL-terminated string from the DWARF string section. +.It Fn dwarf_set_reloc_application +Control whether relocations are to be handled by +.Lb libdwarf . +.El +.El +.Sh The DWARF Producer API +The DWARF producer API permits applications to add DWARF information to +an object file. +.Pp +The major functional groups of functions in the producer API are listed +below. +.Bl -tag -width "CCCC" +.It Attribute Management +The following functions are used to attach attributes to a debugging +information entry: +.Fn dwarf_add_AT_comp_dir , +.Fn dwarf_add_AT_const_value_signedint , +.Fn dwarf_add_AT_const_value_string , +.Fn dwarf_add_AT_const_value_unsignedint , +.Fn dwarf_add_AT_dataref , +.Fn dwarf_add_AT_flag , +.Fn dwarf_add_AT_location_expr , +.Fn dwarf_add_AT_name , +.Fn dwarf_add_AT_producer , +.Fn dwarf_add_AT_ref_address , +.Fn dwarf_add_AT_reference , +.Fn dwarf_add_AT_signed_const , +.Fn dwarf_add_AT_string , +.Fn dwarf_add_AT_targ_address , +.Fn dwarf_add_AT_targ_address_b +and +.Fn dwarf_add_AT_unsigned_const . +.It Debugging Information Entry Management +.Bl -tag -compact -width indent +.It Fn dwarf_add_die_to_debug +Set the root debugging information entry for a DWARF producer instance. +.It Fn dwarf_die_link +Links debugging information entries. +.It Fn dwarf_new_die +Allocate a new debugging information entry. +.El +.It Initialization and Finalization +The functions +.Fn dwarf_producer_init +and +.Fn dwarf_producer_init_b +are used to initialize a producer instance. +.Pp +When done, applications release resources using the function +.Fn dwarf_producer_finish . +.It Relocations and Sections +.Bl -tag -compact -width indent +.It Fn dwarf_get_relocation_info +Retrieve a relocation array from a producer instance. +.It Fn dwarf_get_relocation_info_count +Return the number of relocation arrays for a producer instance. +.It Fn dwarf_get_section_bytes +Retrieve the ELF byte stream for a section. +.It Fn dwarf_reset_section_bytes +Reset internal state for a producer instance. +.It Fn dwarf_transform_to_disk_form +Prepare byte streams for writing out. +.El +.It Macros +.Bl -tag -compact -width indent +.It Fn dwarf_def_macro +Add a macro definition. +.It Fn dwarf_end_macro_file , Fn dwarf_start_macro_file +Record macro file related information. +.It Fn dwarf_undef_macro +Note the removal of a macro definition. +.It Fn dwarf_vendor_ext +Enables storing macro information as specified in the DWARF standard. +.El +.It Symbols, Expressions, Addresses and Offsets +.Bl -tag -compact -width indent +.It Fn dwarf_add_arange , Fn dwarf_add_arange_b +Add address range information. +.It Fn dwarf_add_directory_decl +Add information about an include directory to a producer instance. +.It Fn dwarf_add_fde_inst +Add an operation to a frame descriptor entry. +.It Fn dwarf_add_file_decl +Add information about a source file to a producer instance. +.It Fn dwarf_add_frame_cie +Add call information to a frame descriptor. +.It Fn dwarf_add_frame_fde , Fn dwarf_add_frame_fde_b +Link a frame descriptor to a producer instance. +.It Fn dwarf_add_funcname +Add information about a function to a producer instance. +.It Fn dwarf_add_line_entry +Record mapping information between machine addresses and a source line. +.It Fn dwarf_add_expr_addr , Fn dwarf_add_expr_addr_b +Add a +.Dv DW_OP_addr +opcode to a location expression. +.It Fn dwarf_add_expr_gen +Add an operator to a location expression. +.It Fn dwarf_add_pubname +Add information about a global name to a producer instance. +.It Fn dwarf_add_typename +Add information about a type to a producer instance. +.It Fn dwarf_add_varname +Add information about a static variable to a producer instance. +.It Fn dwarf_add_weakname +Add information about a weak symbol to a producer instance. +.It Fn dwarf_expr_current_offset +Retrieve the current size of a location expression. +.It Fn dwarf_expr_into_block +Convert a location expression into a byte stream. +.It Fn dwarf_fde_cfa_offset +Append a +.Dv DW_CFA_offset +operation to a frame descriptor. +.It Fn dwarf_lne_end_sequence , Fn dwarf_lne_set_address +Note address ranges for source lines. +.It Fn dwarf_new_expr +Allocate a location expression descriptor. +.It Fn dwarf_new_fde +Allocate a frame descriptor. +.El +.It Miscellaneous +The function +.Fn dwarf_producer_set_isa +sets the instruction set architecture for the producer instance. +.El +.Sh COMPATIBILITY +This implementation is believed to be source compatible with the +SGI/GNU DWARF(3) library, version 20110113. +.Pp +Known differences with the SGI/GNU library include: +.Bl -bullet -compact +.It +The memory management scheme used differs, in a backward-compatible +way. +See +.Sx Memory Management +above, for coding guidelines for portable applications. +.It +There is provision for setting a library-wide error handler in +addition to the per-debug context handlers supported by the SGI/GNU +API, see the subsection +.Sx Error Handling +above. +.El +.Ss Extensions +The following APIs are extensions specific to this implementation: +.Bl -bullet -compact +.It +.Fn dwarf_attroffset +.It +.Fn dwarf_next_types_section +.It +.Fn dwarf_producer_set_isa +.El +.Sh SEE ALSO +.Xr elf 3 +.Sh STANDARDS +The DWARF standard is defined by +.Rs +.%T "The DWARF Debugging Information Format" +.%V "Version 4" +.%O "http://www.dwarfstd.org/" +.Re +.Sh HISTORY +The DWARF(3) API originated at Silicon Graphics Inc. +.Pp +A BSD-licensed implementation of a subset of the API was written by +.An John Birrell Aq Mt jb@FreeBSD.org +for the +.Fx +project. +The implementation was subsequently revised and completed by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . +.Pp +Manual pages for this implementation were written by +.An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net +and +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/libdwarf/dwarf.h b/contrib/elftoolchain/libdwarf/dwarf.h new file mode 100644 index 0000000000..fa39f914d8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf.h @@ -0,0 +1,964 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf.h 4011 2023-10-13 01:14:59Z kaiwang27 $ + */ + +#ifndef _DWARF_H_ +#define _DWARF_H_ + +/* + * DWARF5 Section 7.3.5.3, Table 7.1: Package file section identifier + * encodings. + */ + +#define DW_SECT_INFO 1 /* .debug_info.dwo */ + /* Reserved: 2 */ +#define DW_SECT_ABBREV 3 /* .debug_abbrev.dwo */ +#define DW_SECT_LINE 4 /* .debug_line.dwo */ +#define DW_SECT_LOCLISTS 5 /* .debug_loclists.dwo */ +#define DW_SECT_STR_OFFSETS 6 /* .debug_str_offsets.dwo */ +#define DW_SECT_MACRO 7 /* .debug_macro.dwo */ +#define DW_SECT_RNGLISTS 8 /* .debug_rnglists.dwo */ + + +/* + * DWARF5 Section 7.5.1, Table 7.2: Unit header unit type encodings. + */ + +#define DW_UT_compile 0x01 +#define DW_UT_type 0x02 +#define DW_UT_partial 0x03 +#define DW_UT_skeleton 0x04 +#define DW_UT_split_compile 0x05 +#define DW_UT_split_type 0x06 +#define DW_UT_lo_user 0x80 +#define DW_UT_hi_user 0XFF + +/* + * DWARF5 Section 7.5.3, Table 7.3: Tag encodings. + */ + +#define DW_TAG_array_type 0x01 +#define DW_TAG_class_type 0x02 +#define DW_TAG_entry_point 0x03 +#define DW_TAG_enumeration_type 0x04 +#define DW_TAG_formal_parameter 0x05 + /* Reserved: 0x06, 0x07. */ +#define DW_TAG_imported_declaration 0x08 + /* Reserved: 0x09. */ +#define DW_TAG_label 0x0a +#define DW_TAG_lexical_block 0x0b + /* Reserved: 0x0C. */ +#define DW_TAG_member 0x0d + /* Reserved: 0x0E. */ +#define DW_TAG_pointer_type 0x0f +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 +#define DW_TAG_string_type 0x12 +#define DW_TAG_structure_type 0x13 + /* Reserved: 0x14. */ +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 +#define DW_TAG_unspecified_parameters 0x18 +#define DW_TAG_variant 0x19 +#define DW_TAG_common_block 0x1a +#define DW_TAG_common_inclusion 0x1b +#define DW_TAG_inheritance 0x1c +#define DW_TAG_inlined_subroutine 0x1d +#define DW_TAG_module 0x1e +#define DW_TAG_ptr_to_member_type 0x1f +#define DW_TAG_set_type 0x20 +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_with_stmt 0x22 +#define DW_TAG_access_declaration 0x23 +#define DW_TAG_base_type 0x24 +#define DW_TAG_catch_block 0x25 +#define DW_TAG_const_type 0x26 +#define DW_TAG_constant 0x27 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_file_type 0x29 +#define DW_TAG_friend 0x2a +#define DW_TAG_namelist 0x2b +#define DW_TAG_namelist_item 0x2c +#define DW_TAG_packed_type 0x2d +#define DW_TAG_subprogram 0x2e +#define DW_TAG_template_type_parameter 0x2f +#define DW_TAG_template_type_param 0x2f +#define DW_TAG_template_value_parameter 0x30 +#define DW_TAG_template_value_param 0x30 +#define DW_TAG_thrown_type 0x31 +#define DW_TAG_try_block 0x32 +#define DW_TAG_variant_part 0x33 +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 +#define DW_TAG_dwarf_procedure 0x36 +#define DW_TAG_restrict_type 0x37 +#define DW_TAG_interface_type 0x38 +#define DW_TAG_namespace 0x39 +#define DW_TAG_imported_module 0x3a +#define DW_TAG_unspecified_type 0x3b +#define DW_TAG_partial_unit 0x3c +#define DW_TAG_imported_unit 0x3d + /* Reserved: 0x3E. */ +#define DW_TAG_condition 0x3f +#define DW_TAG_shared_type 0x40 +#define DW_TAG_type_unit 0x41 +#define DW_TAG_rvalue_reference_type 0x42 +#define DW_TAG_template_alias 0x43 +#define DW_TAG_coarray_type 0x44 +#define DW_TAG_generic_subrange 0x45 +#define DW_TAG_dynamic_type 0x46 +#define DW_TAG_atomic_type 0x47 +#define DW_TAG_call_site 0x48 +#define DW_TAG_call_site_parameter 0x49 +#define DW_TAG_skeleton_unit 0x4a +#define DW_TAG_immutable_type 0x4b +#define DW_TAG_lo_user 0x4080 +#define DW_TAG_hi_user 0xffff + +/* GNU extensions. */ +#define DW_TAG_format_label 0x4101 +#define DW_TAG_function_template 0x4102 +#define DW_TAG_class_template 0x4103 +#define DW_TAG_GNU_BINCL 0x4104 +#define DW_TAG_GNU_EINCL 0x4105 +#define DW_TAG_GNU_template_template_parameter 0x4106 +#define DW_TAG_GNU_template_template_param 0x4106 +#define DW_TAG_GNU_template_parameter_pack 0x4107 +#define DW_TAG_GNU_formal_parameter_pack 0x4108 +#define DW_TAG_GNU_call_site 0x4109 +#define DW_TAG_GNU_call_site_parameter 0x410a + +/* + * DWARF5 Section 7.5.3, Table 7.4: Child determination encodings. + */ + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +/* + * DWARF5 Section 7.5.4, Table 7.5: Attribute encodings. + */ + +#define DW_AT_sibling 0x01 +#define DW_AT_location 0x02 +#define DW_AT_name 0x03 + /* Reserved: 0x04, 0x05, 0x06, 0x07, 0x08. */ +#define DW_AT_ordering 0x09 +#define DW_AT_subscr_data 0x0a +#define DW_AT_byte_size 0x0b +#define DW_AT_bit_offset 0x0c +#define DW_AT_bit_size 0x0d + /* Reserved: 0x0e. */ +#define DW_AT_element_list 0x0f +#define DW_AT_stmt_list 0x10 +#define DW_AT_low_pc 0x11 +#define DW_AT_high_pc 0x12 +#define DW_AT_language 0x13 +#define DW_AT_member 0x14 +#define DW_AT_discr 0x15 +#define DW_AT_discr_value 0x16 +#define DW_AT_visibility 0x17 +#define DW_AT_import 0x18 +#define DW_AT_string_length 0x19 +#define DW_AT_common_reference 0x1a +#define DW_AT_comp_dir 0x1b +#define DW_AT_const_value 0x1c +#define DW_AT_containing_type 0x1d +#define DW_AT_default_value 0x1e + /* Reserved: 0x1f. */ +#define DW_AT_inline 0x20 +#define DW_AT_is_optional 0x21 +#define DW_AT_lower_bound 0x22 + /* Reserved: 0x23, 0x24. */ +#define DW_AT_producer 0x25 + /* Reserved: 0x26. */ +#define DW_AT_prototyped 0x27 + /* Reserved: 0x28, 0x29. */ +#define DW_AT_return_addr 0x2a + /* Reserved: 0x2b. */ +#define DW_AT_start_scope 0x2c + /* Reserved: 0x2d. */ +#define DW_AT_bit_stride 0x2e +#define DW_AT_stride_size 0x2e +#define DW_AT_upper_bound 0x2f + /* Reserved: 0x30. */ +#define DW_AT_abstract_origin 0x31 +#define DW_AT_accessibility 0x32 +#define DW_AT_address_class 0x33 +#define DW_AT_artificial 0x34 +#define DW_AT_base_types 0x35 +#define DW_AT_calling_convention 0x36 +#define DW_AT_count 0x37 +#define DW_AT_data_member_location 0x38 +#define DW_AT_decl_column 0x39 +#define DW_AT_decl_file 0x3a +#define DW_AT_decl_line 0x3b +#define DW_AT_declaration 0x3c +#define DW_AT_discr_list 0x3d +#define DW_AT_encoding 0x3e +#define DW_AT_external 0x3f +#define DW_AT_frame_base 0x40 +#define DW_AT_friend 0x41 +#define DW_AT_identifier_case 0x42 +#define DW_AT_macro_info 0x43 +#define DW_AT_namelist_item 0x44 +#define DW_AT_priority 0x45 +#define DW_AT_segment 0x46 +#define DW_AT_specification 0x47 +#define DW_AT_static_link 0x48 +#define DW_AT_type 0x49 +#define DW_AT_use_location 0x4a +#define DW_AT_variable_parameter 0x4b +#define DW_AT_virtuality 0x4c +#define DW_AT_vtable_elem_location 0x4d +#define DW_AT_allocated 0x4e +#define DW_AT_associated 0x4f +#define DW_AT_data_location 0x50 +#define DW_AT_byte_stride 0x51 +#define DW_AT_entry_pc 0x52 +#define DW_AT_use_UTF8 0x53 +#define DW_AT_extension 0x54 +#define DW_AT_ranges 0x55 +#define DW_AT_trampoline 0x56 +#define DW_AT_call_column 0x57 +#define DW_AT_call_file 0x58 +#define DW_AT_call_line 0x59 +#define DW_AT_description 0x5a +#define DW_AT_binary_scale 0x5b +#define DW_AT_decimal_scale 0x5c +#define DW_AT_small 0x5d +#define DW_AT_decimal_sign 0x5e +#define DW_AT_digit_count 0x5f +#define DW_AT_picture_string 0x60 +#define DW_AT_mutable 0x61 +#define DW_AT_threads_scaled 0x62 +#define DW_AT_explicit 0x63 +#define DW_AT_object_pointer 0x64 +#define DW_AT_endianity 0x65 +#define DW_AT_elemental 0x66 +#define DW_AT_pure 0x67 +#define DW_AT_recursive 0x68 +#define DW_AT_signature 0x69 +#define DW_AT_main_subprogram 0x6a +#define DW_AT_data_bit_offset 0x6b +#define DW_AT_const_expr 0x6c +#define DW_AT_enum_class 0x6d +#define DW_AT_linkage_name 0x6e +#define DW_AT_string_length_bit_size 0x6f +#define DW_AT_string_length_byte_size 0x70 +#define DW_AT_rank 0x71 +#define DW_AT_str_offsets_base 0x72 +#define DW_AT_addr_base 0x73 +#define DW_AT_rnglists_base 0x74 + /* Reserved: 0x75. */ +#define DW_AT_dwo_name 0x76 +#define DW_AT_reference 0x77 +#define DW_AT_rvalue_reference 0x78 +#define DW_AT_macros 0x79 +#define DW_AT_call_all_calls 0x7a +#define DW_AT_call_all_source_calls 0x7b +#define DW_AT_call_all_tail_calls 0x7c +#define DW_AT_call_return_pc 0x7d +#define DW_AT_call_value 0x7e +#define DW_AT_call_origin 0x7f +#define DW_AT_call_parameter 0x80 +#define DW_AT_call_pc 0x81 +#define DW_AT_call_tail_call 0x82 +#define DW_AT_call_target 0x83 +#define DW_AT_call_target_clobbered 0x84 +#define DW_AT_call_data_location 0x85 +#define DW_AT_call_data_value 0x86 +#define DW_AT_noreturn 0x87 +#define DW_AT_alignment 0x88 +#define DW_AT_export_symbols 0x89 +#define DW_AT_deleted 0x8a +#define DW_AT_defaulted 0x8b +#define DW_AT_loclists_base 0x8c +#define DW_AT_lo_user 0x2000 +#define DW_AT_hi_user 0x3fff + +/* SGI/MIPS extensions. */ +#define DW_AT_MIPS_fde 0x2001 +#define DW_AT_MIPS_loop_begin 0x2002 +#define DW_AT_MIPS_tail_loop_begin 0x2003 +#define DW_AT_MIPS_epilog_begin 0x2004 +#define DW_AT_MIPS_loop_unroll_factor 0x2005 +#define DW_AT_MIPS_software_pipeline_depth 0x2006 +#define DW_AT_MIPS_linkage_name 0x2007 +#define DW_AT_MIPS_stride 0x2008 +#define DW_AT_MIPS_abstract_name 0x2009 +#define DW_AT_MIPS_clone_origin 0x200a +#define DW_AT_MIPS_has_inlines 0x200b +#define DW_AT_MIPS_stride_byte 0x200c +#define DW_AT_MIPS_stride_elem 0x200d +#define DW_AT_MIPS_ptr_dopetype 0x200e +#define DW_AT_MIPS_allocatable_dopetype 0x200f +#define DW_AT_MIPS_assumed_shape_dopetype 0x2010 +#define DW_AT_MIPS_assumed_size 0x2011 + +/* GNU extensions. */ +#define DW_AT_sf_names 0x2101 +#define DW_AT_src_info 0x2102 +#define DW_AT_mac_info 0x2103 +#define DW_AT_src_coords 0x2104 +#define DW_AT_body_begin 0x2105 +#define DW_AT_body_end 0x2106 +#define DW_AT_GNU_vector 0x2107 +#define DW_AT_GNU_guarded_by 0x2108 +#define DW_AT_GNU_pt_guarded_by 0x2109 +#define DW_AT_GNU_guarded 0x210a +#define DW_AT_GNU_pt_guarded 0x210b +#define DW_AT_GNU_locks_excluded 0x210c +#define DW_AT_GNU_exclusive_locks_required 0x210d +#define DW_AT_GNU_shared_locks_required 0x210e +#define DW_AT_GNU_odr_signature 0x210f +#define DW_AT_GNU_template_name 0x2110 +#define DW_AT_GNU_call_site_value 0x2111 +#define DW_AT_GNU_call_site_data_value 0x2112 +#define DW_AT_GNU_call_site_target 0x2113 +#define DW_AT_GNU_call_site_target_clobbered 0x2114 +#define DW_AT_GNU_tail_call 0x2115 +#define DW_AT_GNU_all_tail_call_sites 0x2116 +#define DW_AT_GNU_all_call_sites 0x2117 +#define DW_AT_GNU_all_source_call_sites 0x2118 + +/* Apple extensions. */ +#define DW_AT_APPLE_optimized 0x3fe1 +#define DW_AT_APPLE_flags 0x3fe2 +#define DW_AT_APPLE_isa 0x3fe3 +#define DW_AT_APPLE_block 0x3fe4 +#define DW_AT_APPLE_major_runtime_vers 0x3fe5 +#define DW_AT_APPLE_runtime_class 0x3fe6 +#define DW_AT_APPLE_omit_frame_ptr 0x3fe7 +#define DW_AT_APPLE_property_name 0x3fe8 +#define DW_AT_APPLE_property_getter 0x3fe9 +#define DW_AT_APPLE_property_setter 0x3fea +#define DW_AT_APPLE_property_attribute 0x3feb +#define DW_AT_APPLE_objc_complete_type 0x3fec +#define DW_AT_APPLE_property 0x3fed + +/* + * DWARF5 Section 7.5.6, Table 7.6: Attribute form encodings. + */ + +#define DW_FORM_addr 0x01 + /* Reserved: 0x02. */ +#define DW_FORM_block2 0x03 +#define DW_FORM_block4 0x04 +#define DW_FORM_data2 0x05 +#define DW_FORM_data4 0x06 +#define DW_FORM_data8 0x07 +#define DW_FORM_string 0x08 +#define DW_FORM_block 0x09 +#define DW_FORM_block1 0x0a +#define DW_FORM_data1 0x0b +#define DW_FORM_flag 0x0c +#define DW_FORM_sdata 0x0d +#define DW_FORM_strp 0x0e +#define DW_FORM_udata 0x0f +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_ref1 0x11 +#define DW_FORM_ref2 0x12 +#define DW_FORM_ref4 0x13 +#define DW_FORM_ref8 0x14 +#define DW_FORM_ref_udata 0x15 +#define DW_FORM_indirect 0x16 +#define DW_FORM_sec_offset 0x17 +#define DW_FORM_exprloc 0x18 +#define DW_FORM_flag_present 0x19 +#define DW_FORM_strx 0x1a +#define DW_FORM_addrx 0x1b +#define DW_FORM_ref_sup4 0x1c +#define DW_FORM_strp_sup 0x1d +#define DW_FORM_data16 0x1e +#define DW_FORM_line_strp 0x1f +#define DW_FORM_ref_sig8 0x20 +#define DW_FORM_implicit_const 0x21 +#define DW_FORM_loclistx 0x22 +#define DW_FORM_rnglistx 0x23 +#define DW_FORM_ref_sup8 0x24 +#define DW_FORM_strx1 0x25 +#define DW_FORM_strx2 0x26 +#define DW_FORM_strx3 0x27 +#define DW_FORM_strx4 0x28 +#define DW_FORM_addrx1 0x29 +#define DW_FORM_addrx2 0x2a +#define DW_FORM_addrx3 0x2b +#define DW_FORM_addrx4 0x2c +#define DW_FORM_GNU_ref_alt 0x1f20 +#define DW_FORM_GNU_strp_alt 0x1f21 + +/* + * DWARF5 Section 7.7.1, Table 7.9: DWARF operation encodings. + */ + + /* Reserved: 0x01, 0x02. */ +#define DW_OP_addr 0x03 + /* Reserved: 0x04, 0x05. */ +#define DW_OP_deref 0x06 + /* Reserved: 0x07. */ +#define DW_OP_const1u 0x08 +#define DW_OP_const1s 0x09 +#define DW_OP_const2u 0x0a +#define DW_OP_const2s 0x0b +#define DW_OP_const4u 0x0c +#define DW_OP_const4s 0x0d +#define DW_OP_const8u 0x0e +#define DW_OP_const8s 0x0f +#define DW_OP_constu 0x10 +#define DW_OP_consts 0x11 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_xderef 0x18 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2a +#define DW_OP_gt 0x2b +#define DW_OP_le 0x2c +#define DW_OP_lt 0x2d +#define DW_OP_ne 0x2e +#define DW_OP_skip 0x2f +#define DW_OP_lit0 0x30 +#define DW_OP_lit1 0x31 +#define DW_OP_lit2 0x32 +#define DW_OP_lit3 0x33 +#define DW_OP_lit4 0x34 +#define DW_OP_lit5 0x35 +#define DW_OP_lit6 0x36 +#define DW_OP_lit7 0x37 +#define DW_OP_lit8 0x38 +#define DW_OP_lit9 0x39 +#define DW_OP_lit10 0x3a +#define DW_OP_lit11 0x3b +#define DW_OP_lit12 0x3c +#define DW_OP_lit13 0x3d +#define DW_OP_lit14 0x3e +#define DW_OP_lit15 0x3f +#define DW_OP_lit16 0x40 +#define DW_OP_lit17 0x41 +#define DW_OP_lit18 0x42 +#define DW_OP_lit19 0x43 +#define DW_OP_lit20 0x44 +#define DW_OP_lit21 0x45 +#define DW_OP_lit22 0x46 +#define DW_OP_lit23 0x47 +#define DW_OP_lit24 0x48 +#define DW_OP_lit25 0x49 +#define DW_OP_lit26 0x4a +#define DW_OP_lit27 0x4b +#define DW_OP_lit28 0x4c +#define DW_OP_lit29 0x4d +#define DW_OP_lit30 0x4e +#define DW_OP_lit31 0x4f +#define DW_OP_reg0 0x50 +#define DW_OP_reg1 0x51 +#define DW_OP_reg2 0x52 +#define DW_OP_reg3 0x53 +#define DW_OP_reg4 0x54 +#define DW_OP_reg5 0x55 +#define DW_OP_reg6 0x56 +#define DW_OP_reg7 0x57 +#define DW_OP_reg8 0x58 +#define DW_OP_reg9 0x59 +#define DW_OP_reg10 0x5a +#define DW_OP_reg11 0x5b +#define DW_OP_reg12 0x5c +#define DW_OP_reg13 0x5d +#define DW_OP_reg14 0x5e +#define DW_OP_reg15 0x5f +#define DW_OP_reg16 0x60 +#define DW_OP_reg17 0x61 +#define DW_OP_reg18 0x62 +#define DW_OP_reg19 0x63 +#define DW_OP_reg20 0x64 +#define DW_OP_reg21 0x65 +#define DW_OP_reg22 0x66 +#define DW_OP_reg23 0x67 +#define DW_OP_reg24 0x68 +#define DW_OP_reg25 0x69 +#define DW_OP_reg26 0x6a +#define DW_OP_reg27 0x6b +#define DW_OP_reg28 0x6c +#define DW_OP_reg29 0x6d +#define DW_OP_reg30 0x6e +#define DW_OP_reg31 0x6f +#define DW_OP_breg0 0x70 +#define DW_OP_breg1 0x71 +#define DW_OP_breg2 0x72 +#define DW_OP_breg3 0x73 +#define DW_OP_breg4 0x74 +#define DW_OP_breg5 0x75 +#define DW_OP_breg6 0x76 +#define DW_OP_breg7 0x77 +#define DW_OP_breg8 0x78 +#define DW_OP_breg9 0x79 +#define DW_OP_breg10 0x7a +#define DW_OP_breg11 0x7b +#define DW_OP_breg12 0x7c +#define DW_OP_breg13 0x7d +#define DW_OP_breg14 0x7e +#define DW_OP_breg15 0x7f +#define DW_OP_breg16 0x80 +#define DW_OP_breg17 0x81 +#define DW_OP_breg18 0x82 +#define DW_OP_breg19 0x83 +#define DW_OP_breg20 0x84 +#define DW_OP_breg21 0x85 +#define DW_OP_breg22 0x86 +#define DW_OP_breg23 0x87 +#define DW_OP_breg24 0x88 +#define DW_OP_breg25 0x89 +#define DW_OP_breg26 0x8a +#define DW_OP_breg27 0x8b +#define DW_OP_breg28 0x8c +#define DW_OP_breg29 0x8d +#define DW_OP_breg30 0x8e +#define DW_OP_breg31 0x8f +#define DW_OP_regx 0x90 +#define DW_OP_fbreg 0x91 +#define DW_OP_bregx 0x92 +#define DW_OP_piece 0x93 +#define DW_OP_deref_size 0x94 +#define DW_OP_xderef_size 0x95 +#define DW_OP_nop 0x96 +#define DW_OP_push_object_address 0x97 +#define DW_OP_call2 0x98 +#define DW_OP_call4 0x99 +#define DW_OP_call_ref 0x9a +#define DW_OP_form_tls_address 0x9b +#define DW_OP_call_frame_cfa 0x9c +#define DW_OP_bit_piece 0x9d +#define DW_OP_implicit_value 0x9e +#define DW_OP_stack_value 0x9f +#define DW_OP_implicit_pointer 0xa0 +#define DW_OP_addrx 0xa1 +#define DW_OP_constx 0xa2 +#define DW_OP_entry_value 0xa3 +#define DW_OP_const_type 0xa4 +#define DW_OP_regval_type 0xa5 +#define DW_OP_deref_type 0xa6 +#define DW_OP_xderef_type 0xa7 +#define DW_OP_convert 0xa8 +#define DW_OP_reinterpret 0xa9 +#define DW_OP_lo_user 0xe0 +#define DW_OP_hi_user 0xff + +/* GNU extensions. */ +#define DW_OP_GNU_push_tls_address 0xe0 +#define DW_OP_GNU_uninit 0xf0 +#define DW_OP_GNU_encoded_addr 0xf1 +#define DW_OP_GNU_implicit_pointer 0xf2 +#define DW_OP_GNU_entry_value 0xf3 +#define DW_OP_GNU_const_type 0xf4 +#define DW_OP_GNU_regval_type 0xf5 +#define DW_OP_GNU_deref_type 0xf6 +#define DW_OP_GNU_convert 0xf7 +#define DW_OP_GNU_reinterpret 0xf9 +#define DW_OP_GNU_parameter_ref 0xfa +#define DW_OP_GNU_addr_index 0xfb +#define DW_OP_GNU_const_index 0xfc + +/* + * DWARF5 Section 7.7.3, Table 7.10: location list entry encoding + * values. + */ + +#define DW_LLE_end_of_list 0x00 +#define DW_LLE_base_addressx 0x01 +#define DW_LLE_startx_endx 0x02 +#define DW_LLE_startx_length 0x03 +#define DW_LLE_offset_pair 0x04 +#define DW_LLE_default_location 0x05 +#define DW_LLE_base_address 0x06 +#define DW_LLE_start_end 0x07 +#define DW_LLE_start_lenght 0x08 + +/* + * DWARF5 Section 7.8, Table 7.11: Base type encoding values. + */ + +#define DW_ATE_address 0x1 +#define DW_ATE_boolean 0x2 +#define DW_ATE_complex_float 0x3 +#define DW_ATE_float 0x4 +#define DW_ATE_signed 0x5 +#define DW_ATE_signed_char 0x6 +#define DW_ATE_unsigned 0x7 +#define DW_ATE_unsigned_char 0x8 +#define DW_ATE_imaginary_float 0x9 +#define DW_ATE_packed_decimal 0xa +#define DW_ATE_numeric_string 0xb +#define DW_ATE_edited 0xc +#define DW_ATE_signed_fixed 0xd +#define DW_ATE_unsigned_fixed 0xe +#define DW_ATE_decimal_float 0xf +#define DW_ATE_UTF 0x10 +#define DW_ATE_UCS 0x11 +#define DW_ATE_ASCII 0x12 +#define DW_ATE_lo_user 0x80 +#define DW_ATE_hi_user 0xff + +#define DW_ATE_HP_float80 0x80 /* FP (80 bit) */ +#define DW_ATE_HP_complex_float80 0x81 /* Complex FP (80 bit) */ +#define DW_ATE_HP_float128 0x82 /* FP (128 bit) */ +#define DW_ATE_HP_complex_float128 0x83 /* Complex FP (128 bit) */ +#define DW_ATE_HP_floathpintel 0x84 /* FP (82 bit IA64) */ +#define DW_ATE_HP_imaginary_float80 0x85 +#define DW_ATE_HP_imaginary_float128 0x86 +#define DW_ATE_HP_VAX_float 0x88 /* FP (F, G) */ +#define DW_ATE_HP_VAX_float_d 0x89 /* FP (D) */ +#define DW_ATE_HP_packed_decimal 0x8a /* Cobol */ +#define DW_ATE_HP_zoned_decimal 0x8b /* Cobol */ +#define DW_ATE_HP_edited 0x8c /* Cobol */ +#define DW_ATE_HP_signed_fixed 0x8d /* Cobol */ +#define DW_ATE_HP_unsigned_fixed 0x8e /* Cobol */ +#define DW_ATE_HP_VAX_complex_float 0x8f /* Complex FP (F, G) */ +#define DW_ATE_HP_VAX_complex_float_d 0x90 /* Complex FP (D) */ + +/* + * DWARF5 Section 7.8, Table 7.12: Decimal sign encodings. + */ + +#define DW_DS_unsigned 0x01 +#define DW_DS_leading_overpunch 0x02 +#define DW_DS_trailing_overpunch 0x03 +#define DW_DS_leading_separate 0x04 +#define DW_DS_trailing_separate 0x05 + +/* + * DWARF5 Section 7.8, Table 7.13: Endianity encodings. + */ + +#define DW_END_default 0x00 +#define DW_END_big 0x01 +#define DW_END_little 0x02 +#define DW_END_lo_user 0x40 +#define DW_END_high_user 0xff + +/* + * DWARF5 Section 7.9, Table 7.14: Accessibility encodings. + */ + +#define DW_ACCESS_public 0x01 +#define DW_ACCESS_protected 0x02 +#define DW_ACCESS_private 0x03 + +/* + * DWARF5 Section 7.10, Table 7.15: Visibility encodings. + */ + +#define DW_VIS_local 0x01 +#define DW_VIS_exported 0x02 +#define DW_VIS_qualified 0x03 + +/* + * DWARF5 Section 7.11, Table 7.16: Virtuality encodings. + */ + +#define DW_VIRTUALITY_none 0x00 +#define DW_VIRTUALITY_virtual 0x01 +#define DW_VIRTUALITY_pure_virtual 0x02 + +/* + * DWARF5 Section 7.12, Table 7.17: Language encodings. + */ + +#define DW_LANG_C89 0x0001 +#define DW_LANG_C 0x0002 +#define DW_LANG_Ada83 0x0003 +#define DW_LANG_C_plus_plus 0x0004 +#define DW_LANG_Cobol74 0x0005 +#define DW_LANG_Cobol85 0x0006 +#define DW_LANG_Fortran77 0x0007 +#define DW_LANG_Fortran90 0x0008 +#define DW_LANG_Pascal83 0x0009 +#define DW_LANG_Modula2 0x000a +#define DW_LANG_Java 0x000b +#define DW_LANG_C99 0x000c +#define DW_LANG_Ada95 0x000d +#define DW_LANG_Fortran95 0x000e +#define DW_LANG_PLI 0x000f +#define DW_LANG_ObjC 0x0010 +#define DW_LANG_ObjC_plus_plus 0x0011 +#define DW_LANG_UPC 0x0012 +#define DW_LANG_D 0x0013 +#define DW_LANG_Python 0x0014 +#define DW_LANG_OpenCL 0x0015 +#define DW_LANG_Go 0x0016 +#define DW_LANG_Modula3 0x0017 +#define DW_LANG_Haskell 0x0018 +#define DW_LANG_C_plus_plus_03 0x0019 +#define DW_LANG_C_plus_plus_11 0x001a +#define DW_LANG_OCaml 0x001b +#define DW_LANG_Rust 0x001c +#define DW_LANG_C11 0x001d +#define DW_LANG_Swift 0x001e +#define DW_LANG_Julia 0x001f +#define DW_LANG_Dylan 0x0020 +#define DW_LANG_C_plus_plus_14 0x0021 +#define DW_LANG_Fortran03 0x0022 +#define DW_LANG_Fortran08 0x0023 +#define DW_LANG_RenderScript 0x0024 +#define DW_LANG_BLISS 0x0025 +#define DW_LANG_Kotlin 0x0026 +#define DW_LANG_Zig 0x0027 +#define DW_LANG_Crystal 0x0028 +#define DW_LANG_C_plus_plus_17 0x002a +#define DW_LANG_C_plus_plus_20 0x002b +#define DW_LANG_C17 0x002c +#define DW_LANG_Fortran18 0x002d +#define DW_LANG_Ada2005 0x002e +#define DW_LANG_Ada2012 0x002f +#define DW_LANG_HIP 0x0030 +#define DW_LANG_Assembly 0x0031 +#define DW_LANG_C_sharp 0x0032 +#define DW_LANG_Mojo 0x0033 +#define DW_LANG_lo_user 0x8000 +#define DW_LANG_Mips_Assembler 0x8001 +#define DW_LANG_hi_user 0xffff + +/* + * DWARF5 Section 7.14, Table 7.18: Identifier case encodings. + */ + +#define DW_ID_case_sensitive 0x00 +#define DW_ID_up_case 0x01 +#define DW_ID_down_case 0x02 +#define DW_ID_case_insensitive 0x03 + +/* + * DWARF5 Section 7.15, Table 7.19: Calling convention encodings. + */ + +#define DW_CC_normal 0x01 +#define DW_CC_program 0x02 +#define DW_CC_nocall 0x03 +#define DW_CC_pass_by_reference 0x04 +#define DW_CC_pass_by_value 0x05 +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + +/* + * DWARF5 Section 7.16, Table 7.20: Inline encodings. + */ + +#define DW_INL_not_inlined 0x00 +#define DW_INL_inlined 0x01 +#define DW_INL_declared_not_inlined 0x02 +#define DW_INL_declared_inlined 0x03 + +/* + * DWARF5 Section 7.17, Table 7.21: Ordering encodings. + */ + +#define DW_ORD_row_major 0x00 +#define DW_ORD_col_major 0x01 + +/* + * DWARF5 Section 7.18, Table 7.22: Discriminant descriptor encodings. + */ + +#define DW_DSC_label 0x00 +#define DW_DSC_range 0x01 + +/* + * DWARF5 Section 7.19, Table 7.23: Name index attribute encodings. + */ + +#define DW_IDX_compile_unit 1 +#define DW_IDX_type_unit 2 +#define DW_IDX_die_offset 3 +#define DW_IDX_parent 4 +#define DW_IDX_type_hash 5 +#define DW_IDX_lo_user 0x2000 +#define DW_IDX_hi_user 0x3fff + +/* + * DWARF5 Section 7.20, Table 7.24: Defaulted attribute encodings. + */ + +#define DW_DEFAULTED_no 0x00 +#define DW_DEFAULTED_in_class 0x01 +#define DW_DEFAULTED_out_of_class 0x02 + +/* + * DWARF5 Section 7.22, Table 7.25: Line number standard opcode + * encodings. + */ + +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_fixed_advance_pc 0x09 +#define DW_LNS_set_prologue_end 0x0a +#define DW_LNS_set_epilogue_begin 0x0b +#define DW_LNS_set_isa 0x0c + +/* + * DWARF5 Section 7.22, Table 7.26: Line number extended opcode + * encodings. + */ + +#define DW_LNE_end_sequence 0x01 +#define DW_LNE_set_address 0x02 +#define DW_LNE_define_file 0x03 /* Marked reserved in DWARF5. */ +#define DW_LNE_lo_user 0x80 +#define DW_LNE_hi_user 0xff + +/* + * DWARF5 Section 7.22, Table 7.27: Line number header entry format + * encodings. + */ + +#define DW_LNCT_path 0x1 +#define DW_LNCT_directory_index 0x2 +#define DW_LNCT_timestamp 0x3 +#define DW_LNCT_size 0x4 +#define DW_LNCT_MD5 0x5 +#define DW_LNCT_lo_user 0x2000 +#define DW_LNCT_hi_user 0x3fff + +/* + * DWARF5 Section 7.23, Table 7.28: Macro information entry type + * encodings. + */ + +#define DW_MACRO_define 0x01 +#define DW_MACRO_undef 0x02 +#define DW_MACRO_start_file 0x03 +#define DW_MACRO_end_file 0x04 +#define DW_MACRO_define_strp 0x05 +#define DW_MACRO_undef_strp 0x06 +#define DW_MACRO_import 0x07 +#define DW_MACRO_define_sup 0x08 +#define DW_MACRO_undef_sup 0x09 +#define DW_MACRO_import_sup 0x0a +#define DW_MACRO_define_strx 0x0b +#define DW_MACRO_undef_strx 0x0c +#define DW_MACRO_lo_user 0xe0 +#define DW_MACRO_hi_user 0xff + +#define DW_MACINFO_define 0x01 +#define DW_MACINFO_undef 0x02 +#define DW_MACINFO_start_file 0x03 +#define DW_MACINFO_end_file 0x04 +#define DW_MACINFO_vendor_ext 0xff + +/* + * DWARF5 Section 7.24, Table 7.29: Call frame instruction encodings. + */ + +#define DW_CFA_advance_loc 0x40 +#define DW_CFA_offset 0x80 +#define DW_CFA_restore 0xc0 +#define DW_CFA_extended 0 + +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_register 0x0d +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_def_cfa_expression 0x0f +#define DW_CFA_expression 0x10 +#define DW_CFA_offset_extended_sf 0x11 +#define DW_CFA_def_cfa_sf 0x12 +#define DW_CFA_def_cfa_offset_sf 0x13 +#define DW_CFA_val_offset 0x14 +#define DW_CFA_val_offset_sf 0x15 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_lo_user 0x1c +#define DW_CFA_high_user 0x3f + +/* + * DWARF5 Section 7.25, Table 7.30: Range list entry encoding values. + */ + +#define DW_RLE_end_of_list 0x00 +#define DW_RLE_base_addressx 0x01 +#define DW_RLE_startx_endx 0x02 +#define DW_RLE_startx_length 0x03 +#define DW_RLE_offset_pair 0x04 +#define DW_RLE_base_address 0x05 +#define DW_RLE_start_end 0x06 +#define DW_RLE_start_length 0x07 + +/* + * LSB(Linux Standard Base) extension to DWARF2. + */ + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0a +#define DW_EH_PE_sdata4 0x0b +#define DW_EH_PE_sdata8 0x0c +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 +#define DW_EH_PE_omit 0xff + +#endif /* !_DWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/dwarf_abbrev.c b/contrib/elftoolchain/libdwarf/dwarf_abbrev.c new file mode 100644 index 0000000000..448dc77c37 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_abbrev.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_abbrev.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, + Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length, + Dwarf_Unsigned *attr_count, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + int ret; + + if (dbg == NULL || return_abbrev == NULL || length == NULL || + attr_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error); + if (ret != DW_DLE_NONE) { + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else + return (DW_DLV_ERROR); + } + + *return_abbrev = ab; + *length = ab->ab_length; + *attr_count = ab->ab_atnum; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half *return_tag, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_tag == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_tag = (Dwarf_Half) abbrev->ab_tag; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned *return_code, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_code == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_code = abbrev->ab_entry; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed *return_flag, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_flag == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_flag = (Dwarf_Signed) abbrev->ab_children; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx, + Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, + Dwarf_Error *error) +{ + Dwarf_AttrDef ad; + int i; + + if (abbrev == NULL || attr_num == NULL || form == NULL || + offset == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) { + DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + ad = STAILQ_FIRST(&abbrev->ab_attrdef); + for (i = 0; i < ndx && ad != NULL; i++) + ad = STAILQ_NEXT(ad, ad_next); + + assert(ad != NULL); + + *attr_num = ad->ad_attrib; + *form = ad->ad_form; + *offset = ad->ad_offset; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 new file mode 100644 index 0000000000..41a2c22d29 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_comp_dir.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_COMP_DIR 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_comp_dir +.Nd create and attach a DW_AT_comp_dir attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_comp_dir +.Fa "Dwarf_P_Die die" +.Fa "char *dir" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_comp_dir +creates a +.Dv DW_AT_comp_dir +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Fa die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa dir +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_comp_dir +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_comp_dir +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_comp_dir +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa die +or +.Fa dir +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_producer 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 new file mode 100644 index 0000000000..fbac28714f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 @@ -0,0 +1,129 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_const_value_string.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_CONST_VALUE_STRING 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_const_value_signedint , +.Nm dwarf_add_AT_const_value_string , +.Nm dwarf_add_AT_const_value_unsignedint +.Nd create and attach a DW_AT_const_value attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_signedint +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Signed value" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_string +.Fa "Dwarf_P_Die die" +.Fa "char *str" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_unsignedint +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions create a +.Dv DW_AT_const_value +attribute descriptor and attach it to the debugging information entry +referenced by argument +.Fa die . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Function +.Fn dwarf_add_AT_const_value_signedint +creates a +.Dv DW_AT_const_value +attribute descriptor containing the signed value specified by argument +.Fa value . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_sdata . +.Pp +Function +.Fn dwarf_add_AT_const_value_unsignedint +creates a +.Dv DW_AT_const_value +attribute descriptor containing the unsigned value specified by +argument +.Fa value . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_udata . +.Pp +Function +.Fn dwarf_add_AT_const_value_string +creates a +.Dv DW_AT_const_value +attribute descriptor containing the string pointed to by the +NUL-terminated argument +.Fa str . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_strp . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used by these functions to store error +information in case of an error. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and set the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa die +or +.Fa str +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 new file mode 100644 index 0000000000..f026314028 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_dataref.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_DATAREF 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_dataref +.Nd create an attribute descriptor for a relocatable address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_dataref +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_dataref +creates an attribute descriptor for a relocatable address and attaches +it to the debugging information entry referenced by argument +.Fa die . +.Pp +If flag +.Dv DW_DLC_SIZE_64 +is set, the address value will be 8 bytes in size and of the DWARF form +.Dv DW_FORM_data8 . +Otherwise, the address value will be 4 bytes in size and of the DWARF form +.Dv DW_FORM_data4 . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +specifies the attribute code of the created attribute descriptor. +.Pp +Argument +.Fa pc_value +specifies the value of the relocatable address. +.Pp +Argument +.Fa sym_index +specifies the ELF symbol index of the symbol to be used for +relocation. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_dataref +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_dataref +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_dataref +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_reference 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 new file mode 100644 index 0000000000..f85a7a65b1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_flag.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_FLAG 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_flag +.Nd create and attach a flag attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_flag +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Small flag" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_flag +creates an attribute descriptor belonging to the +.Sq flag +class, and attaches it to the debugging information entry referenced +by argument +.Fa die . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_flag . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +should specify the attribute code for the new attribute descriptor. +.Pp +Argument +.Fa flag +should specify the value of the new attribute descriptor. +A zero value is treated as +.Sq false +and a non-zero value as +.Sq true . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_flag +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_flag +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_flag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 new file mode 100644 index 0000000000..740ca52fd3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_location_expr.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 5, 2011 +.Dt DWARF_ADD_AT_LOCATION_EXPR 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_location_expr +.Nd create an attribute descriptor for a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_location_expr +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_P_Expr loc_expr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_location_expr +creates an attribute descriptor for a location expression and attaches +it to the debugging information entry referenced by argument +.Fa die . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +specifies the attribute code of the created attribute descriptor. +.Pp +Argument +.Fa loc_expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +The attribute created by function +.Fn dwarf_add_AT_location_expr +will have one of the DWARF forms +.Dv DW_FORM_block , +.Dv DW_FORM_block1 , +.Dv DW_FORM_block2 +or +.Dv DW_FORM_block4 , +depending on the size of the byte stream generated by the location +expression descriptor referenced by argument +.Fa loc_expr . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used by to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_location_expr +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_location_expr +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_location_expr +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa loc_expr +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_new_expr 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 new file mode 100644 index 0000000000..438438bd47 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_name.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_NAME 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_name +.Nd create and attach a DW_AT_name attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_name +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_name +creates a +.Dv DW_AT_name +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Fa die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa name +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_name +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_name +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_name +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_comp_dir 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_producer 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 new file mode 100644 index 0000000000..f57a421c83 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_producer.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_PRODUCER 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_producer +.Nd create and attach a DW_AT_producer attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_producer +.Fa "Dwarf_P_Die die" +.Fa "char *producer" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_producer +creates a +.Dv DW_AT_producer +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Fa die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa producer +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_producer +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_producer +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_producer +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa die +or +.Fa producer +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_comp_dir 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 new file mode 100644 index 0000000000..2650e0b72d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_ref_address.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 7, 2011 +.Dt DWARF_ADD_AT_REF_ADDRESS 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_ref_address +.Nd create a reference class attribute descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_ref_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_ref_address +creates a +.Sq reference +class attribute descriptor containing a relocatable address value. +The created attribute will use DWARF form +.Dv DW_FORM_ref_addr . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +specifies the attribute code of the created attribute. +.Pp +Argument +.Fa pc_value +contains a relocatable address which will become the value of the +created attribute. +.Pp +Argument +.Fa sym_index +should specify the ELF symbol index of the symbol to be used when +relocating the address value. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_ref_address +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_ref_address +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_ref_address +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_reference 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 new file mode 100644 index 0000000000..de6ac0aebd --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_reference.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_REFERENCE 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_reference +.Nd create and attach an attribute that references another DIE +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_reference +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_P_Die ref_die" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_reference +creates an attribute descriptor that references another debugging +information entry in the same compilation unit. +The attribute will be of DWARF form +.Dv DW_FORM_ref4 +or +.Dv DW_FORM_ref8 +depending on the target address size, and will contain the +section-relative offset of the referenced debugging information entry +as its value. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +should specify the attribute code of the created attribute descriptor. +.Pp +Argument +.Fa ref_die +should hold the debugging information entry descriptor that +the attribute should refer to. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_reference +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_reference +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_reference +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa ref_die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 new file mode 100644 index 0000000000..a764d67a4c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_signed_const.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_SIGNED_CONST 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_signed_const , +.Nm dwarf_add_AT_unsigned_const +.Nd create and attach constant class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_signed_const +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Signed value" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_unsigned_const +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions create attribute descriptors belonging to the +.Sq constant +class +and attach them to the debugging information entry referenced by +argument +.Fa die . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +specifies the attribute code of the created attribute descriptor. +.Pp +Function +.Fn dwarf_add_AT_signed_const +creates an attribute descriptor with the signed value specified in +argument +.Fa value . +.Pp +Function +.Fn dwarf_add_AT_unsigned_const +creates an attribute descriptor with the unsigned value specified in +argument +.Fa value . +.Pp +The attribute created by these function will have one of the +DWARF forms +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 +or +.Dv DW_FORM_data8 , +depending on the size of the value specified in argument +.Fa value . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used by these functions to store error +information in case of an error. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and set the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_signedint 3 , +.Xr dwarf_add_AT_const_value_unsignedint 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_targ_address_b 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 new file mode 100644 index 0000000000..c75fb620a9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_string.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_STRING 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_string +.Nd create and attach a string class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_string +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "char *str" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_string +creates an attribute descriptor belonging to the +.Sq string +class and attaches it to the debugging information entry referenced by +argument +.Fa die . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +should specify the attribute code for the created attribute +descriptor. +.Pp +Argument +.Fa str +should hold a pointer to a NUL-terminated string which will become the +value of the created attribute descriptor. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_string +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_string +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_string +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa str +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 new file mode 100644 index 0000000000..c5727bc517 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 @@ -0,0 +1,139 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_AT_targ_address.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_ADD_AT_TARG_ADDRESS 3 +.Os +.Sh NAME +.Nm dwarf_add_AT_targ_address , +.Nm dwarf_add_AT_targ_address_b +.Nd create and attach address class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_targ_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Signed sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_targ_address_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_targ_address_b +creates an attribute descriptor belonging to the +.Sq address +class and attaches it to the debugging information entry referenced by +argument +.Fa die . +.Pp +The created attribute descriptor will have DWARF form +.Dv DW_FORM_addr . +If flag +.Dv DW_DLC_SIZE_64 +is set on the producer instance, the attribute value will be 8 bytes +in size. +Otherwise the attribute value will be 4 bytes in size. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Fa attr +should specify the attribute code of the created attribute descriptor. +.Pp +Argument +.Fa pc_value +should hold a relocatable address value which will become the value of +the created attribute descriptor. +.Pp +Argument +.Fa sym_index +should specify the ELF symbol index of the symbol to be used for +relocating the address value. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_add_AT_targ_address +is deprecated. +It is similar to function +.Fn dwarf_add_AT_targ_address_b +except that it cannot handle all possible symbol index values. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_unsignedint 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 b/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 new file mode 100644 index 0000000000..7208b02714 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 @@ -0,0 +1,153 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_arange.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 18, 2011 +.Dt DWARF_ADD_ARANGE 3 +.Os +.Sh NAME +.Nm dwarf_add_arange , +.Nm dwarf_add_arange_b +.Nd add address range information to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_arange +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr start" +.Fa "Dwarf_Unsigned length" +.Fa "Dwarf_Signed symbol_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_arange_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr start" +.Fa "Dwarf_Unsigned length" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Unsigned end_symbol_index" +.Fa "Dwarf_Addr offset_from_end_symbol" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_arange_b +adds an address range entry to a producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa start +specifies the relocatable start address of the address range. +.Pp +Argument +.Fa length +specifies the length of the address range. +.Pp +Argument +.Fa symbol_index +specifies the ELF symbol index of the first symbol to be used for +relocation. +.Pp +Argument +.Fa end_symbol_index +specifies the ELF symbol index of the second symbol to be used for +relocation. +.Bl -bullet +.It +If argument +.Fa end_symbol_index +is not 0, the +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the DWARF producer instance. +The address value specified by argument +.Fa start +will be treated as an offset value from the first symbol, +and the argument +.Fa offset_from_end_symbol +should hold an offset value from the second symbol. +Application code can retrieve the relocation entries for the +symbol pair by calling function +.Xr dwarf_get_relocation_info 3 . +The relocation entry for the first symbol will have type +.Dv dwarf_drt_first_of_length_pair +and the relocation entry for the second symbol will have type +.Dv dwarf_drt_second_of_length_pair . +.It +If argument +.Fa end_symbol_index +is 0, argument +.Fa offset_from_end_symbol +will be ignored and only one symbol is used for relocation. +.El +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_add_arange +is deprecated. +It is similar to function +.Fn dwarf_add_arange_b +except that it cannot handle all possible symbol index values +and supports only one relocation symbol. +.Sh RETURN VALUES +On success, these functions return a non-zero value. +In case of an error, these functions return 0 and set +the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa end_symbol_index +was non-zero, but the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 b/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 new file mode 100644 index 0000000000..74e4480dc7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_die_to_debug.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd August 21, 2011 +.Dt DWARF_ADD_DIE_TO_DEBUG 3 +.Os +.Sh NAME +.Nm dwarf_add_die_to_debug +.Nd set the root debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Unsigned +.Fo dwarf_add_die_to_debug +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die first_die" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_die_to_debug +sets the root debugging information entry of a DWARF producer +instance. +All debugging information entries linked to the root entry will also +be added to the producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa first_die +should hold the debugging information entry which will become +the root DIE. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_die_to_debug +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_add_die_to_debug +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_die_to_debug +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa first_die +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_die_link 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 b/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 new file mode 100644 index 0000000000..9e94eab73f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_directory_decl.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 17, 2011 +.Dt DWARF_ADD_DIRECTORY_DECL 3 +.Os +.Sh NAME +.Nm dwarf_add_directory_decl +.Nd add a directory name to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_directory_decl +.Fa "Dwarf_P_Debug dbg" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_directory_decl +adds a source directory name to a producer instance and returns the +index value generated for the directory name. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa name +should point a NUL-terminated string containing the name of +the directory. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_directory_decl +returns the index value generated for the directory. +In case of an error, function +.Fn dwarf_add_directory_decl +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_directory_decl +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa dbg +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 b/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 new file mode 100644 index 0000000000..2a4b019adb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_expr_addr.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 9, 2011 +.Dt DWARF_ADD_EXPR_ADDR 3 +.Os +.Sh NAME +.Nm dwarf_add_expr_addr , +.Nm dwarf_add_expr_addr_b +.Nd add a DW_OP_addr location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_addr +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned address" +.Fa "Dwarf_Signed sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_addr_b +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned address" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_expr_addr_b +adds a +.Dv DW_OP_addr +location expression to the location expression descriptor referenced +by argument +.Fa expr . +.Pp +Argument +.Fa expr +should reference a location expression descriptor allocated using +the function +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Fa address +specifies the operand, a relocatable address value. +.Pp +Argument +.Fa sym_index +specifies the ELF symbol index of the symbol to be used for +relocation. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_add_expr_addr +is deprecated. +It is similar to function +.Fn dwarf_add_expr_addr_b +except that it cannot handle all possible symbol index values. +.Sh RETURN VALUES +On success, these functions return the size in bytes of the location +expression byte stream generated. +In case of an error, these functions return +.Dv DW_DLV_NOCOUNT +and set the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa expr +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 b/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 new file mode 100644 index 0000000000..437dce879b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_expr_gen.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 9, 2011 +.Dt DWARF_ADD_EXPR_GEN 3 +.Os +.Sh NAME +.Nm dwarf_add_expr_gen +.Nd add an operator to a location expression descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_gen +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Small opcode" +.Fa "Dwarf_Unsigned val1" +.Fa "Dwarf_Unsigned val2" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_expr_gen +adds a location expression operator to the location expression +descriptor referenced by argument +.Fa expr . +.Pp +Argument +.Fa expr +should reference a location expression descriptor allocated using +the function +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Fa opcode +specifies the operation code of the location expression operator. +Valid values for this argument are those denoted by the +.Dv DW_OP_ Ns * +constants defined in +.In libdwarf.h . +.Pp +To generate a +.Dv DW_OP_addr +operation, application code should instead use +.Xr dwarf_add_expr_addr_b 3 . +.Pp +Argument +.Fa val1 +specifies the first operand of the location expression operator. +.Pp +Argument +.Fa val2 +specifies the second operand of the location expression operator. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_expr_gen +returns the size in bytes of the location expression byte stream +generated. +In case of an error, function +.Fn dwarf_add_expr_gen +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_expr_gen +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa expr +was +.Dv NULL . +.It Bq Er DW_DLE_LOC_EXPR_BAD +The operation code specified in argument +.Fa opcode +was invalid. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 b/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 new file mode 100644 index 0000000000..b19243a6b2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_fde_inst.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 26, 2011 +.Dt DWARF_ADD_FDE_INST 3 +.Os +.Sh NAME +.Nm dwarf_add_fde_inst +.Nd add a call frame instruction to a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_add_fde_inst +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_Small op" +.Fa "Dwarf_Unsigned val1" +.Fa "Dwarf_Unsigned val2" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_fde_inst +adds a call frame instruction to the DWARF frame descriptor +referenced by argument +.Fa fde . +.Pp +Argument +.Fa fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Fa op +specifies the operator for the frame instruction. +The DWARF standard defines the set of legal values for this argument. +.Pp +Argument +.Fa val1 +specifies the first operand of the frame instruction. +.Pp +Argument +.Fa val2 +specifies the second operand of the frame instruction. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_fde_inst +returns the frame descriptor given in argument +.Fa fde . +In case of an error, function +.Fn dwarf_add_fde_inst +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_fde_inst +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa fde +was +.Dv NULL . +.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR +The frame instruction operator specified in argument +.Fa op +was invalid. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_new_fde 3 +.Rs +.%T "The DWARF Debugging Information Format" +.%V "Version 4" +.%O "http://www.dwarfstd.org/" +.Re diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 b/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 new file mode 100644 index 0000000000..ab80aec786 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_file_decl.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 17, 2011 +.Dt DWARF_ADD_FILE_DECL 3 +.Os +.Sh NAME +.Nm dwarf_add_file_decl +.Nd add a source file entry to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_file_decl +.Fa "Dwarf_P_Debug dbg" +.Fa "char *name" +.Fa "Dwarf_Unsigned dirndx" +.Fa "Dwarf_Unsigned mtime" +.Fa "Dwarf_Unsigned size" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_file_decl +adds a source file entry to a producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name of +the source file. +.Pp +If the file name in argument +.Fa name +is not a fully qualified pathname, argument +.Fa dirndx +should specify the index of the directory where the source file resides. +Otherwise, argument +.Fa dirndx +should be 0. +Valid directory indices are those returned by the function +.Xr dwarf_add_directory_decl 3 . +.Pp +Argument +.Fa mtime +specifies the time when the file was last modified. +.Pp +Argument +.Fa size +specifies the size of the file in bytes. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_file_decl +returns the index value generated for the source file. +In case of an error, function +.Fn dwarf_add_file_decl +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_file_decl +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Fa dbg +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The length of the NUL-teminated string pointed to by argument +.Fa name +was 0. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 b/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 new file mode 100644 index 0000000000..cf01122e89 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 @@ -0,0 +1,126 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_frame_cie.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 26, 2011 +.Dt DWARF_ADD_FRAME_CIE 3 +.Os +.Sh NAME +.Nm dwarf_add_frame_cie +.Nd add a call frame common information entry to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_cie +.Fa "Dwarf_P_Debug dbg" +.Fa "char *augmenter" +.Fa "Dwarf_Small caf" +.Fa "Dwarf_Small daf" +.Fa "Dwarf_Small ra" +.Fa "Dwarf_Ptr initinst" +.Fa "Dwarf_Unsigned initlen" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_frame_cie +adds a DWARF call frame common information entry (CIE) to a producer +instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa augmenter +should point to a NUL-terminated augmentation string for the common +information entry. +.Pp +Argument +.Fa caf +specifies the code alignment factor. +.Pp +Argument +.Fa daf +specifies the data alignment factor. +.Pp +Argument +.Fa ra +specifies the column number used for the return address register. +.Pp +Argument +.Fa initinst +should point to a byte stream containing the initial instructions +for the common information entry. +.Pp +Argument +.Fa initlen +should hold the length in bytes of the byte stream pointed to by +argument +.Fa initinst . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_frame_cie +returns the index value of the created common information entry. +In case of an error, function +.Fn dwarf_add_frame_cie +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_frame_cie +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_new_fde 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 new file mode 100644 index 0000000000..69df0789d7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_frame_fde.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 26, 2011 +.Dt DWARF_ADD_FRAME_FDE 3 +.Os +.Sh NAME +.Nm dwarf_add_frame_fde +.Nd add a call frame descriptor to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_fde +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned cie" +.Fa "Dwarf_Addr virt_addr" +.Fa "Dwarf_Unsigned code_len" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_fde_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned cie" +.Fa "Dwarf_Addr virt_addr" +.Fa "Dwarf_Unsigned code_len" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Unsigned end_symbol_index" +.Fa "Dwarf_Addr offset_from_end_sym" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_frame_fde_b +adds the call frame descriptor referenced by argument +.Fa fde +to a producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Fa die +is ignored by this implementation of the +.Lb libdwarf . +.Pp +Argument +.Fa cie +specifies the index of call frame common information entry for +the frame descriptor. +Valid indices are those returned by the function +.Xr dwarf_add_frame_cie 3 . +.Pp +Argument +.Fa symbol_index +specifies the ELF symbol index of the first symbol to be used for +relocation. +.Pp +The meaning of the arguments +.Fa virt_addr , +.Fa code_len +and +.Fa offset_from_end_sym +depend on the value of argument +.Fa end_symbol_index : +.Bl -bullet +.It +If the argument +.Fa end_symbol_index +is zero, the argument +.Fa virt_addr +specifies the relocatable address of the start of the function +associated with the frame descriptor, the argument +.Fa code_len +specifies the size in bytes of the machine instructions for this +function, the argument +.Fa symbol_index +specifies the ELF symbol to be used for relocating the address in +argument +.Fa virt_addr , +and the argument +.Fa offset_from_end_symbol +is ignored. +.It +If the argument +.Fa end_symbol_index +is non-zero, it specifies the ELF symbol index of the second symbol to +be used for relocation. +In this case, the argument +.Fa virt_addr +specifies an offset from the relocatable symbol specified by argument +.Fa symbol_index , +the argument +.Fa offset_from_end_symbol +should specify an offset from the symbol named by the argument +.Fa end_symbol_index , +and the argument +.Fa code_len +will be ignored. +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should also have been set on the DWARF producer instance. +.Pp +Application code can retrieve the relocation entries for the symbol +pair by calling function +.Xr dwarf_get_relocation_info 3 . +The relocation entry for the first symbol will have type +.Dv dwarf_drt_first_of_length_pair +and the relocation entry for the second symbol will have type +.Dv dwarf_drt_second_of_length_pair . +.El +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_add_frame_fde +is similar to function +.Fn dwarf_add_frame_fde_b +except that it supports only one relocation symbol. +.Sh RETURN VALUES +On success, these functions return the index value for +the added frame descriptor. +In case of an error, these functions return +.Dv DW_DLV_NOCOUNT +and set the argument +.Fa err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg +or +.Fa fde +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The frame descriptor referenced by argument +.Fa fde +did not belong to the producer instance referenced by argument +.Fa dbg . +.It Bq Er DW_DLE_ARGUMENT +The common information entry index specified by argument +.Fa cie +was invalid. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa end_symbol_index +was non-zero, but the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_new_fde 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 new file mode 100644 index 0000000000..07985126a2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_funcname.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_ADD_FUNCNAME 3 +.Os +.Sh NAME +.Nm dwarf_add_funcname +.Nd add information about a static function to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_funcname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_funcname +adds information about a static function to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +specifies the debugging information entry associated with the static +function. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the static function. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_funcname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_funcname +returns 0 and sets +the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_funcname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 new file mode 100644 index 0000000000..9fe4ecdd82 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 @@ -0,0 +1,166 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_line_entry.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd June 30, 2013 +.Dt DWARF_ADD_LINE_ENTRY 3 +.Os +.Sh NAME +.Nm dwarf_add_line_entry +.Nd add a line number information entry to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_line_entry +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned filendx" +.Fa "Dwarf_Addr off" +.Fa "Dwarf_Unsigned lineno" +.Fa "Dwarf_Signed column" +.Fa "Dwarf_Bool is_stmt" +.Fa "Dwarf_Bool basic_block" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_line_entry +adds a line number information entry to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa filendx +specifies the index of the source file that contains the source line +in question. +Valid source file indices are those returned by the function +.Xr dwarf_add_file_decl 3 . +.Pp +Argument +.Fa off +specifies a relocatable program address. +The ELF symbol to be used +for relocation is set by a prior call to the function +.Xr dwarf_lne_set_address 3 . +.Pp +Argument +.Fa lineno +specifies the line number of the source line. +.Pp +Argument +.Fa column +specifies the column number within the source line. +.Pp +If the argument +.Fa is_stmt +is set to true, it indicates that the instruction at the address +specified by argument +.Fa off +is a recommended breakpoint location, i.e., the first instruction in +the instruction sequence generated by the source line. +.Pp +If the argument +.Fa basic_block +is set to true, it indicates that the instruction at the address +specified by argument +.Fa off +is the first instruction of a basic block. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_line_entry +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_add_line_entry +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh EXAMPLES +To add line number information to the producer instance, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; +Dwarf_Unsigned dir, filendx; + +/* ... assume dbg refers to a DWARF producer instance ... */ + +dir = dwarf_add_directory_decl(dbg, "/home/foo", &de); +if (dir == DW_DLV_NOCOUNT) + errx(EXIT_FAILURE, "dwarf_add_directory_decl failed: %s", + dwarf_errmsg(-1)); + +filendx = dwarf_add_file_decl(dbg, "bar.c", dir, 0, 1234, &de); +if (filendx == DW_DLV_NOCOUNT) + errx(EXIT_FAILURE, "dwarf_add_file_decl failed: %s", + dwarf_errmsg(-1)); + +if (dwarf_lne_set_address(dbg, 0x4012b0, 12, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_lne_set_address failed: %s", + dwarf_errmsg(-1)); + +if (dwarf_add_line_entry(dbg, filendx, 10, 258, 0, 1, 1, &de) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_add_line_entry failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_add_line_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The function +.Xr dwarf_lne_set_address 3 +was not called before calling this function. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 new file mode 100644 index 0000000000..9c7bdf0faa --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_pubname.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_ADD_PUBNAME 3 +.Os +.Sh NAME +.Nm dwarf_add_pubname +.Nd add information about a global object to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_pubname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_pubname +adds information about a global object to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +specifies the debugging information entry associated with the global +object. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the global object. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_pubname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_pubname +returns 0 and sets +the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_pubname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 b/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 new file mode 100644 index 0000000000..86ae0d0836 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_typename.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_ADD_TYPENAME 3 +.Os +.Sh NAME +.Nm dwarf_add_typename +.Nd add information about a user-defined type to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_typename +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_typename +adds information about a user-defined type to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +specifies the debugging information entry associated with the +user-defined type. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the user-defined type. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_typename +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_typename +returns 0 and sets +the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_typename +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 new file mode 100644 index 0000000000..d8852f2a1c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_varname.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_ADD_VARNAME 3 +.Os +.Sh NAME +.Nm dwarf_add_varname +.Nd add information about a static variable to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_varname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_varname +adds information about a static variable to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +specifies the debugging information entry associated with the static +variable. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the static variable. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_varname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_varname +returns 0 and sets +the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_varname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 new file mode 100644 index 0000000000..ec77141443 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_add_weakname.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_ADD_WEAKNAME 3 +.Os +.Sh NAME +.Nm dwarf_add_weakname +.Nd add information about a weak object to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_weakname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_weakname +adds information about a weak object to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa die +specifies the debugging information entry associated with the weak +object. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the weak object. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_weakname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_weakname +returns 0 and sets +the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_add_weakname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa die +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_arange.c b/contrib/elftoolchain/libdwarf/dwarf_arange.c new file mode 100644 index 0000000000..46b42cb9ab --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_arange.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_arange.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange **arlist, + Dwarf_Signed *ret_arange_cnt, Dwarf_Error *error) +{ + + if (dbg == NULL || arlist == NULL || ret_arange_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_arange_cnt == 0) { + if (_dwarf_arange_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_arange_cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + assert(dbg->dbg_arange_array != NULL); + + *arlist = dbg->dbg_arange_array; + *ret_arange_cnt = dbg->dbg_arange_cnt; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange(Dwarf_Arange *arlist, Dwarf_Unsigned arange_cnt, + Dwarf_Addr addr, Dwarf_Arange *ret_arange, Dwarf_Error *error) +{ + Dwarf_Arange ar; + Dwarf_Debug dbg; + int i; + + if (arlist == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + dbg = (*arlist)->ar_as->as_cu->cu_dbg; + + if (ret_arange == NULL || arange_cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + for (i = 0; (Dwarf_Unsigned)i < arange_cnt; i++) { + ar = arlist[i]; + if (addr >= ar->ar_address && addr < ar->ar_address + + ar->ar_range) { + *ret_arange = ar; + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_get_cu_die_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + cu = as->as_cu; + assert(cu != NULL); + + if (ret_offset == NULL) { + DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange_cu_header_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + + if (ret_offset == NULL) { + DWARF_SET_ERROR(as->as_cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = as->as_cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange_info(Dwarf_Arange ar, Dwarf_Addr *start, + Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + cu = as->as_cu; + assert(cu != NULL); + + if (start == NULL || length == NULL || + cu_die_offset == NULL) { + DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *start = ar->ar_address; + *length = ar->ar_range; + *cu_die_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.3 b/contrib/elftoolchain/libdwarf/dwarf_attr.3 new file mode 100644 index 0000000000..2b5e55f424 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_attr.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd April 8, 2010 +.Dt DWARF_ATTR 3 +.Os +.Sh NAME +.Nm dwarf_attr +.Nd retrieve an attribute descriptor associated with a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attr +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Attribute *atp" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attr +retrieves the attribute descriptor for an attribute associated +with the DWARF debugging information entry descriptor in +argument +.Fa die . +.Pp +DWARF attribute descriptors are represented by value of the opaque +type +.Vt Dwarf_Attribute , +see +.Xr dwarf 3 . +.Pp +Argument +.Fa attr +names the desired DWARF attribute. +Legal values for argument +.Fa attr +are those denoted by the +.Dv DW_AT_* +constants in the DWARF specification. +.Pp +Argument +.Fa atp +points to a location into which the returned attribute descriptor +will be written. +The returned descriptor may then be passed to the form query functions in the +.Xr dwarf 3 +API set to access the data associated with the attribute. +.Pp +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_attr +returns +.Dv DW_DLV_OK +on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Fa die +does not contain the named attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Fa err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_attr +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa die +or +.Fa atp +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa die +had no attribute corresponding to the value +in argument +.Fa attr . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attrlist 3 , +.Xr dwarf_attroffset 3 , +.Xr dwarf_hasattr 3 , +.Xr dwarf_hasform 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.c b/contrib/elftoolchain/libdwarf/dwarf_attr.c new file mode 100644 index 0000000000..a081d7b93a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.c @@ -0,0 +1,312 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); + +int +dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Attribute at; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || atp == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *atp = at; + + return (DW_DLV_OK); +} + +int +dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute **attrbuf, + Dwarf_Signed *attrcount, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || attrbuf == NULL || attrcount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_ab->ab_atnum == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *attrcount = die->die_ab->ab_atnum; + + if (die->die_attrarray != NULL) { + *attrbuf = die->die_attrarray; + return (DW_DLV_OK); + } + + if ((die->die_attrarray = malloc(*attrcount * sizeof(Dwarf_Attribute))) + == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, at = STAILQ_FIRST(&die->die_attr); + i < *attrcount && at != NULL; i++, at = STAILQ_NEXT(at, at_next)) + die->die_attrarray[i] = at; + + *attrbuf = die->die_attrarray; + + return (DW_DLV_OK); +} + +int +dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = (_dwarf_attr_find(die, attr) != NULL); + + return (DW_DLV_OK); +} + +int +dwarf_attroffset(Dwarf_Attribute at, Dwarf_Off *ret_off, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || ret_off == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_off = at->at_offset; + + return (DW_DLV_OK); +} + +int +dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_lowpc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_lowpc = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) +{ + + return (dwarf_highpc_b(die, ret_highpc, NULL, NULL, error)); +} + +int +dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form, + enum Dwarf_Form_Class *ret_class, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_highpc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_highpc = at->u[0].u64; + + if (ret_form != NULL) { + *ret_form = at->at_form; + } + + if (ret_class != NULL) { + cu = die->die_cu; + *ret_class = dwarf_get_form_class(cu->cu_version, + DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8, + at->at_form); + } + + return (DW_DLV_OK); +} + +int +dwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_byte_size)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_bit_size)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_bit_offset)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_srclang(Dwarf_Die die, Dwarf_Unsigned *ret_lang, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_lang == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_language)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_lang = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_order == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_order = at->u[0].u64; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 b/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 new file mode 100644 index 0000000000..d464020bc0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 @@ -0,0 +1,149 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_attrlist.3 3964 2022-03-13 21:41:26Z jkoshy $ +.\" +.Dd March 13, 2022 +.Dt DWARF_ATTRLIST 3 +.Os +.Sh NAME +.Nm dwarf_attrlist +.Nd retrieve DWARF attribute descriptors +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attrlist +.Fa "Dwarf_Die die" +.Fa "Dwarf_Attribute **attrbuf" +.Fa "Dwarf_Signed *attrcount" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attrlist +retrieves the DWARF attribute descriptors associated with a +debugging information entry descriptor in argument +.Fa die . +The descriptors are returned as an array of values of the opaque type +.Vt Dwarf_Attribute . +The data associated with each returned attribute descriptor may be +queried using the form query functions in the +.Xr dwarf 3 +API set. +.Pp +Argument +.Fa attrbuf +points to a location that will hold a pointer to the returned +array of DWARF attribute descriptors. +Argument +.Fa attrcount +points to a location that will hold the number of descriptors in +the returned array. +.Pp +If argument +.Fa err +is +.No non- Ns Dv NULL , +it is used to return an error descriptor in case of an error. +.Ss Memory Management +In the current implementation, the memory allocated for each DWARF +attribute descriptor and for the returned array of descriptors is +managed by the library and the application does not need to explicitly +free the returned pointers. +However, for compatibility with other implementations of the +.Xr dwarf 3 +API, the application is permitted to pass the pointers returned by to +the +.Fn dwarf_dealloc +function. +.Sh RETURN VALUES +Function +.Fn dwarf_attrlist +returns +.Dv DW_DLV_OK +on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Fa die +does not contain any attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Fa err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh EXAMPLES +To retrieve the attribute list for a DWARF debugging information +entry use: +.Bd -literal -offset indent +Dwarf_Die dw_die; +Dwarf_Error dw_e; +Dwarf_Unsigned dw_count; +Dwarf_Attribute *dw_attributes; +int error, i; + +\&... variable dw_die contains a reference to the DIE of interest ... + +/* Retrieve the attribute list from the DIE. */ +if ((error = dwarf_attrlist(dw_die, &dw_attributes, &dw_count, + &dw_e)) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_attrlist: %s", dwarf_errmsg(dw_e)); + +/* Process the attribute list. */ +for (i = 0; i < dw_count; ++i) { + /* Use the returned pointers in dw_attributes[i] here. */ +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_attrlist +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Fa die , +.Fa attrbuf , +or +.Fa attrcount +were +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa die +had no attributes. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_hasattr 3 , +.Xr dwarf_hasform 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 b/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 new file mode 100644 index 0000000000..8c049a1d21 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_attroffset.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd December 20, 2014 +.Dt DWARF_ATTROFFSET 3 +.Os +.Sh NAME +.Nm dwarf_attroffset +.Nd retrieve the section-relative offset of an attribute descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attroffset +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Off *ret_off" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attroffset +retrieves the section-relative offset of the attribute descriptor +referenced by argument +.Fa at . +.Pp +Argument +.Fa ret_off +should point to a location that is to hold the returned +section-relative offset. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it is used to return an error descriptor in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_attroffset +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_attroffset +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa at +or +.Fa ret_off +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval.c b/contrib/elftoolchain/libdwarf/dwarf_attrval.c new file mode 100644 index 0000000000..4d19283060 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval.c @@ -0,0 +1,238 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_attrval.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +int +dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_flag: + case DW_FORM_flag_present: + *valp = (Dwarf_Bool) (!!at->u[0].u64); + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + Dwarf_CU cu; + char *str; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || strp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = die->die_cu; + assert(cu != NULL); + + *strp = NULL; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_strp: + *strp = at->u[1].s; + break; + case DW_FORM_string: + *strp = at->u[0].s; + break; + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + if (_dwarf_read_indexed_str(dbg, cu, at->u[0].u64, &str, err) != + DW_DLE_NONE) + return (DW_DLV_ERROR); + *strp = str; + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_data1: + *valp = (int8_t) at->u[0].s64; + break; + case DW_FORM_data2: + *valp = (int16_t) at->u[0].s64; + break; + case DW_FORM_data4: + *valp = (int32_t) at->u[0].s64; + break; + case DW_FORM_data8: + case DW_FORM_sdata: + *valp = at->u[0].s64; + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Die die1; + Dwarf_Unsigned val; + Dwarf_Debug dbg; + int first; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + die1 = NULL; + for (;;) { + if ((at = _dwarf_attr_find(die, attr)) != NULL || + attr != DW_AT_type) + break; + if ((at = _dwarf_attr_find(die, DW_AT_abstract_origin)) == + NULL && + (at = _dwarf_attr_find(die, DW_AT_specification)) == NULL) + break; + + switch (at->at_form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + val = at->u[0].u64; + first = (die1 == NULL); + die1 = _dwarf_die_find(die, val); + if (!first) + dwarf_dealloc(dbg, die, DW_DLA_DIE); + if (die1 == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + die = die1; + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + } + + if (at == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_addr: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + case DW_FORM_sec_offset: + *valp = at->u[0].u64; + break; + default: + if (die1 != NULL) + dwarf_dealloc(dbg, die1, DW_DLA_DIE); + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + if (die1 != NULL) + dwarf_dealloc(dbg, die1, DW_DLA_DIE); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 new file mode 100644 index 0000000000..7b44078497 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 @@ -0,0 +1,227 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_attrval_signed.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd December 26, 2016 +.Dt DWARF_ATTRVAL_SIGNED 3 +.Os +.Sh NAME +.Nm dwarf_attrval_flag , +.Nm dwarf_attrval_signed , +.Nm dwarf_attrval_string , +.Nm dwarf_attrval_unsigned +.Nd retrieve the value of an attribute within a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attrval_flag +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_signed +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_string +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "const char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_unsigned +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions search the debugging information entry referenced +by argument +.Fa die +for the attribute named by argument +.Fa attr . +If the named attribute is found, the functions set the location +pointed to by argument +.Fa ret +to the value of the attribute. +The argument +.Fa err , +if +.No non- Ns Dv NULL , +will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_attrval_flag +sets the location pointed to by argument +.Fa ret +to either 0 or 1. If the form of the attribute named by argument +.Fa attr +is +.Dv DW_FORM_flag , +function +.Fn dwarf_attrval_flag +sets the location pointed to by argument +.Fa ret +to 1 if the attribute has a non-zero value, or to 0 otherwise. +If the form of the attribute named by argument +.Fa attr +is +.Dv DW_FORM_flag_present , +function +.Fn dwarf_attrval_flag +unconditionally sets the location pointed to by argument +.Fa ret +to 1. +The form of the attribute must be one of +.Dv DW_FORM_flag +or +.Dv DW_FORM_flag_present . +.Pp +Function +.Fn dwarf_attrval_signed +stores the value for the attribute named by argument +.Fa attr , +into the location pointed to by argument +.Fa ret . +The attribute's value is treated as a signed integral quantity and is +sign-extended as needed. +The attribute named by the argument +.Fa attr +must belong to the +.Dv CONSTANT +class and must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +or +.Dv DW_FORM_sdata . +.Pp +Function +.Fn dwarf_attrval_string +sets the location pointed to by argument +.Fa ret +to a pointer to a NUL-terminated string that is the value of the +attribute named by argument +.Fa attr . +The form of the attribute must be one of +.Dv DW_FORM_string +or +.Dv DW_FORM_strp . +.Pp +Function +.Fn dwarf_attrval_unsigned +stores the value for the attribute named by argument +.Fa attr +into the location pointed to by argument +.Fa ret . +The attribute's value is treated as an unsigned integral quantity, and +is zero-extended as needed. +The named attribute must belong to one of the +.Dv CONSTANT , +.Dv ADDRESS +or +.Dv REFERENCE +classes and must have one of the following forms: +.Dv DW_FORM_addr , +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 , +.Dv DW_FORM_udata , +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 , +or +.Dv DW_FORM_ref_udata . +.Pp +If the attribute named by argument +.Fa attr +is +.Dv DW_AT_type +and is not present in the debugging information entry referenced by argument +.Fa die , +and if a +.Dv DW_AT_abstract_origin +or +.Dv DW_AT_specification +attribute is present in the debugging information entry, +function +.Fn dwarf_attrval_unsigned +will search for the named attribute in the debugging information entry +referenced by the +.Dv DW_AT_abstract_origin +or +.Dv DW_AT_specification +attribute. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +If the named attribute was not found in the specified debugging +information entry descriptor these functions return +.Dv DW_DLV_NO_ENTRY +and set argument +.Fa err . +For other errors, these functions return +.Dv DW_DLV_ERROR +and set argument +.Fa err . +.Sh COMPATIBILITY +These functions are extensions added by this implementation of the +DWARF(3) API. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Va die +or +.Va ret +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa die +did not contain an attribute corresponding to the value in argument +.Fa attr . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute named by argument +.Fa attr +was not of a permitted form. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_child.3 b/contrib/elftoolchain/libdwarf/dwarf_child.3 new file mode 100644 index 0000000000..56a0942cdb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_child.3 @@ -0,0 +1,282 @@ +.\" Copyright (c) 2010,2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_child.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd December 21, 2014 +.Dt DWARF_CHILD 3 +.Os +.Sh NAME +.Nm dwarf_child , +.Nm dwarf_offdie , +.Nm dwarf_offdie_b , +.Nm dwarf_siblingof , +.Nm dwarf_siblingof_b +.Nd retrieve DWARF Debugging Information Entry descriptors +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err" +.Ft int +.Fo dwarf_offdie +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_offdie_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_siblingof +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Die die" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_siblingof_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Die die" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to retrieve and traverse DWARF +Debugging Information Entry (DIE) descriptors associated with +a compilation unit. +These descriptors are arranged in the form of a tree, traversable +using +.Dq child +and +.Dq sibling +links; see +.Xr dwarf 3 +for more information. +DWARF Debugging Information Entry descriptors are represented +by the +.Vt Dwarf_Die +opaque type. +.Pp +Function +.Fn dwarf_child +retrieves the child of descriptor denoted by argument +.Fa die , +and stores it in the location pointed to by argument +.Fa ret_die . +.Pp +Function +.Fn dwarf_siblingof +retrieves the sibling of the descriptor denoted by argument +.Fa die , +and stores it in the location pointed to by argument +.Fa ret_die . +If argument +.Fa die +is +.Dv NULL , +the first debugging information entry descriptor for the +current compilation unit will be returned. +This function and function +.Fn dwarf_child +may be used together to traverse the tree of debugging information +entry descriptors for a compilation unit. +.Pp +Function +.Fn dwarf_siblingof_b +is identical to the function +.Fn dwarf_siblingof +except that it can retrieve the sibling descriptor from either the +current compilation unit or type unit. +If argument +.Fa is_info +is non-zero, the function behaves identically to function +.Fn dwarf_siblingof . +If argument +.Fa is_info +is zero, the descriptor referred by argument +.Fa die +should be associated with a debugging information entry in the +type unit. +The function will store the sibling of the descriptor in the location +pointed to by argument +.Fa ret_die . +If argument +.Fa is_info +is zero and argument +.Fa die +is +.Dv NULL , +the first debugging information entry descriptor for the +current type unit will be returned. +.Pp +Function +.Fn dwarf_offdie +retrieves the debugging information entry descriptor at global offset +.Fa offset +in the +.Dq .debug_info +section of the object associated with argument +.Fa dbg . +The returned descriptor is written to the location pointed to by argument +.Fa ret_die . +.Pp +Function +.Fn dwarf_offdie_b +is identical to the function +.Fn dwarf_offdie +except that it can retrieve the debugging information entry descriptor at +global offset +.Fa offset +from either of the +.Dq .debug_info +and +.Dq .debug_types +sections of the object associated with argument +.Fa dbg . +If argument +.Fa is_info +is non-zero, the function will retrieve the debugging information +entry from the +.Dq .debug_info +section, otherwise the function will retrieve the debugging +information entry from the +.Dq .debug_types +section. +The returned descriptor is written to the location pointed to by argument +.Fa ret_die . +.Ss Memory Management +The memory area used for the +.Vt Dwarf_Die +descriptor returned in argument +.Fa ret_die +is allocated by the +.Lb libdwarf . +Application code should use function +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_DIE +to free the memory area when the +.Vt Dwarf_Die +descriptor is no longer needed. +.Sh RETURN VALUES +These functions return the following values: +.Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" +.It Bq Er DW_DLV_OK +The call succeeded. +.It Bq Er DW_DLV_ERROR +The requested operation failed. +Additional information about the error encountered will be recorded in +argument +.Fa err , +if it is not +.Dv NULL . +.It Bq Er DW_DLV_NO_ENTRY +For functions +.Fn dwarf_child , +.Fn dwarf_siblingof +and +.Fn dwarf_siblingof_b , +the descriptor denoted by argument +.Fa die +did not have a child or sibling. +.Pp +For functions +.Fn dwarf_offdie +and +.Fn dwarf_offdie_b , +there was no debugging information entry at the offset specified by +argument +.Fa offset . +.El +.Sh EXAMPLES +To retrieve the first DWARF Debugging Information Entry descriptor for +the first compilation unit associated with a +.Vt Dwarf_Debug +instance, and to traverse all its children, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Die die, die0; +Dwarf_Error de; + +\&... allocate dbg using dwarf_init() etc ... + +if (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &de) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", + dwarf_errmsg(de)); + +/* Get the first DIE for the current compilation unit. */ +die = NULL; +if (dwarf_siblingof(dbg, die, &die0, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de)); + +/* Get the first child of this DIE. */ +die = die0; +if (dwarf_child(die, &die0, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_child: %s", dwarf_errmsg(de)); + +/* Get the rest of children. */ +do { + die = die0; + if (dwarf_siblingof(dbg, die, &die0, &de) == DW_DLV_ERROR) + errx(EXIT_FAILURE, "dwarf_siblingof: %s", + dwarf_errmsg(de)); +} while (die0 != NULL); +.Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_DIE_NO_CU_CONTEXT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Fa dbg , +.Fa die +or +.Fa ret_die +were +.Dv NULL . +.It Bq Er DW_DLE_DIE_NO_CU_CONTEXT +Argument +.Fa dbg +was not associated with a compilation unit. +.It Bq Er DW_DLE_NO_ENTRY +The descriptor denoted by argument +.Fa die +had no child or sibling, or there was no DWARF debugging information +entry at the offset specified by argument +.Va offset . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_get_die_infotypes_flag 3 , +.Xr dwarf_next_cu_header 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_cu.c b/contrib/elftoolchain/libdwarf/dwarf_cu.c new file mode 100644 index 0000000000..31397fe02e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_cu.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_cu.c 4040 2024-03-19 14:01:45Z jkoshy $"); + +int +dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Bool is_info, + Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, + Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size, + Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size, + Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset, + Dwarf_Unsigned *cu_next_offset, Dwarf_Half *cu_type, + Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (is_info) { + if (dbg->dbg_cu_current == NULL) + ret = _dwarf_info_first_cu(dbg, error); + else + ret = _dwarf_info_next_cu(dbg, error); + } else { + if (dbg->dbg_tu_current == NULL) + ret = _dwarf_info_first_tu(dbg, error); + else + ret = _dwarf_info_next_tu(dbg, error); + } + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (is_info) { + if (dbg->dbg_cu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_cu_current; + } else { + if (dbg->dbg_tu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_tu_current; + } + + if (cu_length) + *cu_length = cu->cu_length; + if (cu_version) + *cu_version = cu->cu_version; + if (cu_abbrev_offset) + *cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset; + if (cu_pointer_size) + *cu_pointer_size = cu->cu_pointer_size; + if (cu_offset_size) { + if (cu->cu_length_size == 4) + *cu_offset_size = 4; + else + *cu_offset_size = 8; + } + if (cu_extension_size) { + if (cu->cu_length_size == 4) + *cu_extension_size = 0; + else + *cu_extension_size = 4; + } + if (cu_next_offset) + *cu_next_offset = cu->cu_next_offset; + + if (!is_info) { + if (type_signature) + *type_signature = cu->cu_type_sig; + if (type_offset) + *type_offset = cu->cu_type_offset; + } + + if (cu_type) + *cu_type = cu->cu_unit_type; + + return (DW_DLV_OK); +} + +int +dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info, + Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, + Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size, + Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size, + Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset, + Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error) +{ + return (dwarf_next_cu_header_d(dbg, is_info, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, cu_offset_size, + cu_extension_size, type_signature, type_offset, cu_next_offset, + NULL, error)); +} + + +int +dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, + Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, + Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size, + Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset, + Dwarf_Error *error) +{ + + return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, cu_offset_size, + cu_extension_size, NULL, NULL, cu_next_offset, error)); +} + +int +dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, + Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, + Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset, + Dwarf_Error *error) +{ + + return (dwarf_next_cu_header_b(dbg, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset, + error)); +} + +int +dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error) +{ + + /* Free resource allocated for current .debug_types section. */ + _dwarf_type_unit_cleanup(dbg); + dbg->dbg_types_loaded = 0; + dbg->dbg_types_off = 0; + + /* Reset type unit pointer. */ + dbg->dbg_tu_current = NULL; + + /* Search for the next .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, + dbg->dbg_types_sec); + + if (dbg->dbg_types_sec == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 b/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 new file mode 100644 index 0000000000..d546475f45 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2009-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_dealloc.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd July 23, 2011 +.Dt DWARF_DEALLOC 3 +.Os +.Sh NAME +.Nm dwarf_dealloc , +.Nm dwarf_fde_cie_list_dealloc , +.Nm dwarf_funcs_dealloc , +.Nm dwarf_globals_dealloc , +.Nm dwarf_pubtypes_dealloc , +.Nm dwarf_ranges_dealloc , +.Nm dwarf_srclines_dealloc , +.Nm dwarf_types_dealloc , +.Nm dwarf_vars_dealloc , +.Nm dwarf_weaks_dealloc +.Nd release resources +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft void +.Fo dwarf_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr ptr" +.Fa "Dwarf_Unsigned type" +.Fc +.Fo dwarf_fde_cie_list_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie *cie_list" +.Fa "Dwarf_Signed cie_count" +.Fa "Dwarf_Fde *fde_list" +.Fa "Dwarf_Signed fde_count" +.Fc +.Ft void +.Fo dwarf_funcs_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Func *funcs" +.Fa "Dwarf_Signed funccount" +.Fc +.Ft void +.Fo dwarf_globals_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Global *globals" +.Fa "Dwarf_Signed globalcount" +.Fc +.Ft void +.Fo dwarf_pubtypes_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type *pubtypes" +.Fa "Dwarf_Signed pubtypecount" +.Fc +.Ft void +.Fo dwarf_ranges_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ranges *ranges" +.Fa "Dwarf_Signed rangecount" +.Fc +.Ft void +.Fo dwarf_srclines_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Line *lines" +.Fa "Dwarf_Signed linecount" +.Fc +.Ft void +.Fo dwarf_types_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type *types" +.Fa "Dwarf_Signed typecount" +.Fc +.Ft void +.Fo dwarf_vars_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Var *vars" +.Fa "Dwarf_Signed varcount" +.Fc +.Ft void +.Fo dwarf_weaks_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Weak *weaks" +.Fa "Dwarf_Signed weakcount" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_dealloc +is used by applications to indicate that memory areas returned by +.Lb libdwarf +may be safely disposed off. +Due to the way memory is managed in the current implementation, the +use of +.Fn dwarf_dealloc +is only necessary for a small set of DWARF types. +.Pp +Argument +.Fa dbg +should reference a valid debugging context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa ptr +should point to an object or memory area obtained by a prior call +to a DWARF(3) function. +.Pp +Argument +.Fa type +indicates the type of object being deallocated. +The indicated type must match that of the object being passed in +argument +.Fa ptr . +Valid values for the +.Fa type +argument are: +.Bl -tag -width ".Dv DW_DLA_FRAME_BLOCK" +.It Dv DW_DLA_ABBREV +An object of type +.Vt Dwarf_Abbrev , +as returned by a call to the function +.Xr dwarf_get_abbrev 3 . +.It Dv DW_DLA_DIE +An object of type +.Vt Dwarf_Die , +as returned by calls to the functions +.Xr dwarf_child 3 , +.Xr dwarf_offdie 3 +or +.Xr dwarf_siblingof 3 . +.It Dv DW_DLA_FRAME_BLOCK +An array of objects of type +.Vt Dwarf_Frame_op , +as returned by a call to the function +.Xr dwarf_expand_frame_instructions 3 . +.El +.Pp +Calls to +.Fn dwarf_dealloc +with other values for argument +.Fa type +are no-ops in this implementation. +.Pp +The functions +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc +and +.Fn dwarf_weaks_dealloc +are provided for compatibility with other implementations of the +DWARF(3) API. +Due to the way memory is managed in the current implementation, these +functions are effectively no-ops. +.Pp +See +.Xr dwarf 3 +for more information about the memory management scheme in this +implementation of the DWARF(3) API. +.Sh RETURN VALUES +Functions +.Fn dwarf_dealloc , +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc +and +.Fn dwarf_weaks_dealloc +have no return value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_child 3 , +.Xr dwarf_expand_frame_instructions 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_offdie 3 , +.Xr dwarf_siblingof 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dealloc.c b/contrib/elftoolchain/libdwarf/dwarf_dealloc.c new file mode 100644 index 0000000000..eb7ed1cb68 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dealloc.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_dealloc.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +void +dwarf_dealloc(Dwarf_Debug dbg, Dwarf_Ptr p, Dwarf_Unsigned alloc_type) +{ + Dwarf_Abbrev ab; + Dwarf_AttrDef ad, tad; + Dwarf_Attribute at, tat; + Dwarf_Die die; + + /* + * This libdwarf implementation does not use the SGI/libdwarf + * style of memory allocation. In most cases it does not copy + * things to return to the client, so the client does not need + * to remember to free them. The remaining cases are handled + * below. + */ + + (void) dbg; + + if (alloc_type == DW_DLA_LIST || alloc_type == DW_DLA_FRAME_BLOCK || + alloc_type == DW_DLA_LOC_BLOCK || alloc_type == DW_DLA_LOCDESC) + free(p); + else if (alloc_type == DW_DLA_ABBREV) { + ab = p; + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + free(ab); + } else if (alloc_type == DW_DLA_DIE) { + die = p; + STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { + STAILQ_REMOVE(&die->die_attr, at, + _Dwarf_Attribute, at_next); + if (at->at_ld != NULL) + free(at->at_ld); + free(at); + } + if (die->die_attrarray) + free(die->die_attrarray); + free(die); + } +} + +void +dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line *linebuf, + Dwarf_Signed count) +{ + /* + * In this libdwarf implementation, line information remains + * associated with the DIE for a compilation unit for the + * lifetime of the DIE. The client does not need to free + * the memory returned by `dwarf_srclines()`. + */ + + (void) dbg; (void) linebuf; (void) count; +} + +void +dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges *ranges, + Dwarf_Signed range_count) +{ + /* + * In this libdwarf implementation, ranges information is + * kept by a STAILQ inside Dwarf_Debug object. The client + * does not need to free the memory returned by + * `dwarf_get_ranges()` or `dwarf_get_ranges_a()`. + */ + + (void) dbg; (void) ranges; (void) range_count; +} + +void +dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, Dwarf_Cie *cie_list, + Dwarf_Signed cie_count, Dwarf_Fde *fde_list, Dwarf_Signed fde_count) +{ + /* + * In this implementation, FDE and CIE information is managed + * as part of the Dwarf_Debug object. The client does not need + * to explicitly free these memory arenas. + */ + (void) dbg; + (void) cie_list; + (void) cie_count; + (void) fde_list; + (void) fde_count; +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 b/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 new file mode 100644 index 0000000000..203f79119c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 @@ -0,0 +1,132 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_def_macro.3 3961 2022-03-12 15:13:22Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_DEF_MACRO 3 +.Os +.Sh NAME +.Nm dwarf_def_macro +.Nd add a macro definition to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_def_macro +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "char *name" +.Fa "char *value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_def_macro +adds a macro definition to a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa lineno +specifies the line number of the source line where the macro is +defined. +A line number of zero is used for macros that are defined +before any source file is read. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the macro. +For function-like macros this parameter should also include +parentheses and parameter names if any. +.Pp +Argument +.Fa value +should point to a NUL-terminated string containing the value +of the macro. +If the macro does not have a value, argument +.Fa value +should be set to +.Dv NULL . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_def_macro +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_def_macro +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To record the fact that a macro named +.Dv _STDIO_H_ +was defined at line 20 of the current macro file, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; + +/* ... Assume 'dbg' refers to a DWARF producer instance... */ +if (dwarf_def_macro(dbg, 20, "_STDIO_H_", NULL, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_def_macro +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Fa dbg +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_die.c b/contrib/elftoolchain/libdwarf/dwarf_die.c new file mode 100644 index 0000000000..de6351ac60 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die.c @@ -0,0 +1,413 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009,2011,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); + +int +dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Section *ds; + Dwarf_CU cu; + int ret; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_ab->ab_children == DW_CHILDREN_no) + return (DW_DLV_NO_ENTRY); + + dbg = die->die_dbg; + cu = die->die_cu; + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size, + die->die_next_off, cu->cu_next_offset, ret_die, 0, error); + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + +int +dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Bool is_info, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Attribute at; + Dwarf_Section *ds; + uint64_t offset; + int ret, search_sibling; + + if (dbg == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + + if (cu == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + /* Application requests the first DIE in this CU. */ + if (die == NULL) + return (dwarf_offdie_b(dbg, cu->cu_1st_offset, is_info, + ret_die, error)); + + /* + * Check if the `is_info' flag matches the debug section the + * DIE belongs to. + */ + if (is_info != die->die_cu->cu_is_info) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + /* + * If the DIE doesn't have any children, its sibling sits next + * right to it. + */ + search_sibling = 0; + if (die->die_ab->ab_children == DW_CHILDREN_no) + offset = die->die_next_off; + else { + /* + * Look for DW_AT_sibling attribute for the offset of + * its sibling. + */ + if ((at = _dwarf_attr_find(die, DW_AT_sibling)) != NULL) { + if (at->at_form != DW_FORM_ref_addr) + offset = at->u[0].u64 + cu->cu_offset; + else + offset = at->u[0].u64; + } else { + offset = die->die_next_off; + search_sibling = 1; + } + } + + ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size, offset, + cu->cu_next_offset, ret_die, search_sibling, error); + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + + +int +dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_siblingof_b(dbg, die, ret_die, 1, error)); +} + +static int +_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_Section *s, Dwarf_CU cu, + Dwarf_Off offset, Dwarf_Die *ret_die, Dwarf_Error *error) +{ + + assert(dbg != NULL && cu != NULL && ret_die != NULL); + + return (_dwarf_die_parse(dbg, s, cu, cu->cu_dwarf_size, + offset, cu->cu_next_offset, ret_die, 0, error)); +} + +int +dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, + Dwarf_Die *ret_die, Dwarf_Error *error) +{ + Dwarf_Section *ds; + Dwarf_CU cu; + int ret; + + if (dbg == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + + /* First search the current CU. */ + if (cu != NULL) { + if (offset > cu->cu_offset && offset < cu->cu_next_offset) { + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + } + + /* Search other CUs. */ + ret = _dwarf_info_load(dbg, 1, is_info, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (is_info) { + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (offset < cu->cu_offset || + offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (offset < cu->cu_offset || + offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_offdie_b(dbg, offset, 1, ret_die, error)); +} + +int +dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || tag == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(die->die_ab != NULL); + + *tag = (Dwarf_Half) die->die_ab->ab_tag; + + return (DW_DLV_OK); +} + +int +dwarf_dieoffset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = die->die_offset; + + return (DW_DLV_OK); +} + +int +dwarf_die_CU_offset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = die->die_cu; + assert(cu != NULL); + + *ret_offset = die->die_offset - cu->cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_die_CU_offset_range(Dwarf_Die die, Dwarf_Off *cu_offset, + Dwarf_Off *cu_length, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || cu_offset == NULL || cu_length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = die->die_cu; + assert(cu != NULL); + + *cu_offset = cu->cu_offset; + *cu_length = cu->cu_length + cu->cu_length_size; + + return (DW_DLV_OK); +} + +int +dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_name = die->die_name; + + return (DW_DLV_OK); +} + +int +dwarf_die_abbrev_code(Dwarf_Die die) +{ + + assert(die != NULL); + + return (die->die_abnum); +} + +int +dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, + Dwarf_Off *out_cu_die_offset, Dwarf_Error *error) +{ + Dwarf_CU cu; + + if (dbg == NULL || out_cu_die_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (is_info) { + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } + } + } + + if (cu == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset, + Dwarf_Error *error) +{ + + return (dwarf_get_cu_die_offset_given_cu_header_offset_b(dbg, + in_cu_header_offset, 1, out_cu_die_offset, error)); +} + +int +dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, + Dwarf_Error *error) +{ + + if (dbg == NULL || addr_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *addr_size = dbg->dbg_pointer_size; + + return (DW_DLV_OK); +} + +Dwarf_Bool +dwarf_get_die_infotypes_flag(Dwarf_Die die) +{ + + assert(die != NULL); + + return (die->die_cu->cu_is_info); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 b/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 new file mode 100644 index 0000000000..6c02a7b89a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 @@ -0,0 +1,55 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_die_abbrev_code.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 14, 2010 +.Dt DWARF_DIE_ABBREV_CODE 3 +.Os +.Sh NAME +.Nm dwarf_die_abbrev_code +.Nd retrieve the abbreviation code for a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_die_abbrev_code "Dwarf_Die die" +.Sh DESCRIPTION +Function +.Fn dwarf_die_abbrev_code +returns the abbreviation code for the debugging information entry descriptor +referenced by argument +.Fa die . +Argument +.Fa die +should be a valid pointer to a value of type +.Vt Dwarf_Die . +.Sh RETURN VALUES +The function returns an integral value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_diename 3 , +.Xr dwarf_dieoffset 3 , +.Xr dwarf_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_die_link.3 b/contrib/elftoolchain/libdwarf/dwarf_die_link.3 new file mode 100644 index 0000000000..e4a9276404 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die_link.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_die_link.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_DIE_LINK 3 +.Os +.Sh NAME +.Nm dwarf_die_link +.Nd link a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Die +.Fo dwarf_die_link +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_P_Die parent" +.Fa "Dwarf_P_Die child" +.Fa "Dwarf_P_Die left" +.Fa "Dwarf_P_Die right" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_die_link +links debugging information entries together. +.Pp +Argument +.Fa die +should specify the debugging information entry to be updated. +.Pp +Argument +.Fa parent +specifies the new parent link for the debugging information entry. +.Pp +Argument +.Fa child +specifies the new first child link for the debugging information entry. +.Pp +Argument +.Fa left +specifies the new left sibling link for the debugging information entry. +.Pp +Argument +.Fa right +specifies the new right sibling link for the debugging information entry. +.Pp +Only one of arguments +.Fa parent , +.Fa child , +.Fa left +and +.Fa right +is allowed to be +.No non- Ns Dv NULL . +Existing links to parent, child, left or right debugging information +entries, if any, will be unlinked before the specified link is +established. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_die_link +returns the debugging information entry provided in argument +.Fa die . +In case of an error, function +.Fn dwarf_die_link +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +The function +.Fn dwarf_die_link +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa die +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +More than one of the arguments +.Fa parent , +.Fa child , +.Fa left +and +.Fa right +were +.No non- Ns Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_die_to_debug 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_diename.3 b/contrib/elftoolchain/libdwarf/dwarf_diename.3 new file mode 100644 index 0000000000..177fbcb538 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_diename.3 @@ -0,0 +1,92 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_diename.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 31, 2010 +.Dt DWARF_DIENAME 3 +.Os +.Sh NAME +.Nm dwarf_diename +.Nd retrieve the name associated with a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_diename "Dwarf_Die die" "char **ret_name" "Dwarf_Error *err" +.Sh DESCRIPTION +Function +.Fn dwarf_diename +retrieves a pointer to the NUL-terminated string associated with the +.Dv DW_AT_name +attribute of the debugging information entry descriptor referenced by +argument +.Fa die . +If the pointer was successfully retrieved, it is stored in the location +pointed to by argument +.Fa ret_name . +.Sh RETURN VALUES +Function +.Fn dwarf_diename +returns +.Dv DW_DLV_OK +on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Fa die +does not contain a +.Dv DW_AT_name +attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Fa err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_diename +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa die +or +.Fa ret_name +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa die +had no +.Dv DW_AT_name +attribute. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_die_abbrev_code 3 , +.Xr dwarf_dieoffset 3 , +.Xr dwarf_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 new file mode 100644 index 0000000000..13fd660d36 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 @@ -0,0 +1,212 @@ +.\" Copyright (c) 2010,2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_dieoffset.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd December 21, 2014 +.Dt DWARF_DIEOFFSET 3 +.Os +.Sh NAME +.Nm dwarf_die_CU_offset , +.Nm dwarf_die_CU_offset_range , +.Nm dwarf_dieoffset , +.Nm dwarf_get_cu_die_offset_given_cu_header_offset , +.Nm dwarf_get_cu_die_offset_given_cu_header_offset_b +.Nd return offsets of DWARF debugging information entries +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_die_CU_offset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *ret_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_die_CU_offset_range +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Off *cu_length" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_dieoffset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *ret_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_cu_die_offset_given_cu_header_offset +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off in_cu_header_offset" +.Fa "Dwarf_Off *out_cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_cu_die_offset_given_cu_header_offset_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off in_cu_header_offset" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Off *out_cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to retrieve offsets for DWARF debugging +information entries. +.Pp +Function +.Fn dwarf_die_CU_offset +returns the offset of the debugging information entry referenced by +argument +.Fa die +relative to the start of its containing compilation unit. +Argument +.Fa ret_offset +should point to the location that is to hold the returned offset. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_die_CU_offset_range +returns the section-relative offset and length of the compilation unit +containing the debugging information entry referenced by argument +.Fa die . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +Argument +.Fa cu_length +should point to a location that will hold the returned length of the +compilation unit. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_dieoffset +retrieves the section-relative offset of the debugging information +entry referenced by argument +.Fa die . +Argument +.Fa ret_offset +should point to a location that is to hold the returned +section-relative offset. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +returns the offset for the first debugging information entry for a +compilation unit, given an offset to the header of the compilation +unit. +Argument +.Fa dbg +should reference a valid debugging context allocated using +.Xr dwarf_init 3 . +Argument +.Fa in_cu_header_offset +contains the offset to the start of a compilation unit. +Argument +.Fa out_cu_die_offset +points to a location that will hold the returned offset. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +behaves identically to the function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +when the argument +.Fa is_info +is non-zero. +When the argument +.Fa is_info +is zero, function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +returns the offset for the first debugging information entry for a +type unit, given an offset to the header of the type unit in argument +.Fa in_cu_header_offset . +Argument +.Fa out_cu_die_offset +points to a location that will hold the returned offset. +If the argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +In case of an error, these functions return +.Dv DW_DLV_ERROR +and set argument +.Fa err . +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +and +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Fa err +if there is no compilation or type unit located at the +offset specified in argument +.Fa in_cu_header_offset . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_length , +.Va cu_offset , +.Va dbg , +.Va die , +.Va out_cu_die_offset +or +.Va ret_offset +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa in_cu_header_offset +specified an unknown offset. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_next_cu_header 3 , +.Xr dwarf_offdie 3 , +.Xr dwarf_offdie_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dump.c b/contrib/elftoolchain/libdwarf/dwarf_dump.c new file mode 100644 index 0000000000..79af6f4a70 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dump.c @@ -0,0 +1,1622 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_dump.c 4012 2023-10-13 01:15:02Z kaiwang27 $"); + +int +dwarf_get_ACCESS_name(unsigned access, const char **s) +{ + + assert(s != NULL); + + switch (access) { + case DW_ACCESS_public: + *s = "DW_ACCESS_public"; break; + case DW_ACCESS_protected: + *s = "DW_ACCESS_protected"; break; + case DW_ACCESS_private: + *s = "DW_ACCESS_private"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_AT_name(unsigned attr, const char **s) +{ + + assert(s != NULL); + + switch (attr) { + case DW_AT_abstract_origin: + *s = "DW_AT_abstract_origin"; break; + case DW_AT_accessibility: + *s = "DW_AT_accessibility"; break; + case DW_AT_address_class: + *s = "DW_AT_address_class"; break; + case DW_AT_addr_base: + *s = "DW_AT_addr_base"; break; + case DW_AT_alignment: + *s = "DW_AT_alignment"; break; + case DW_AT_artificial: + *s = "DW_AT_artificial"; break; + case DW_AT_allocated: + *s = "DW_AT_allocated"; break; + case DW_AT_associated: + *s = "DW_AT_associated"; break; + case DW_AT_base_types: + *s = "DW_AT_base_types"; break; + case DW_AT_binary_scale: + *s = "DW_AT_binary_scale"; break; + case DW_AT_bit_offset: + *s = "DW_AT_bit_offset"; break; + case DW_AT_bit_size: + *s = "DW_AT_bit_size"; break; + case DW_AT_bit_stride: + *s = "DW_AT_bit_stride"; break; + case DW_AT_byte_size: + *s = "DW_AT_byte_size"; break; + case DW_AT_byte_stride: + *s = "DW_AT_byte_stride"; break; + case DW_AT_calling_convention: + *s = "DW_AT_calling_convention"; break; + case DW_AT_call_all_calls: + *s = "DW_AT_call_all_calls"; break; + case DW_AT_call_all_source_calls: + *s = "DW_AT_call_all_source_calls"; break; + case DW_AT_call_all_tail_calls: + *s = "DW_AT_call_all_tail_calls"; break; + case DW_AT_call_data_location: + *s = "DW_AT_call_data_location"; break; + case DW_AT_call_data_value: + *s = "DW_AT_call_data_value"; break; + case DW_AT_call_origin: + *s = "DW_AT_call_origin"; break; + case DW_AT_call_parameter: + *s = "DW_AT_call_parameter"; break; + case DW_AT_call_pc: + *s = "DW_AT_call_pc"; break; + case DW_AT_call_return_pc: + *s = "DW_AT_call_return_pc"; break; + case DW_AT_call_tail_call: + *s = "DW_AT_call_tail_call"; break; + case DW_AT_call_target: + *s = "DW_AT_call_target"; break; + case DW_AT_call_target_clobbered: + *s = "DW_AT_call_target_clobbered"; break; + case DW_AT_call_value: + *s = "DW_AT_call_value"; break; + case DW_AT_common_reference: + *s = "DW_AT_common_reference"; break; + case DW_AT_comp_dir: + *s = "DW_AT_comp_dir"; break; + case DW_AT_const_expr: + *s = "DW_AT_const_expr"; break; + case DW_AT_const_value: + *s = "DW_AT_const_value"; break; + case DW_AT_containing_type: + *s = "DW_AT_containing_type"; break; + case DW_AT_count: + *s = "DW_AT_count"; break; + case DW_AT_call_column: + *s = "DW_AT_call_column"; break; + case DW_AT_call_file: + *s = "DW_AT_call_file"; break; + case DW_AT_call_line: + *s = "DW_AT_call_line"; break; + case DW_AT_data_bit_offset: + *s = "DW_AT_data_bit_offset"; break; + case DW_AT_data_location: + *s = "DW_AT_data_location"; break; + case DW_AT_data_member_location: + *s = "DW_AT_data_member_location"; break; + case DW_AT_decl_column: + *s = "DW_AT_decl_column"; break; + case DW_AT_decl_file: + *s = "DW_AT_decl_file"; break; + case DW_AT_decl_line: + *s = "DW_AT_decl_line"; break; + case DW_AT_declaration: + *s = "DW_AT_declaration"; break; + case DW_AT_default_value: + *s = "DW_AT_default_value"; break; + case DW_AT_decimal_scale: + *s = "DW_AT_decimal_scale"; break; + case DW_AT_decimal_sign: + *s = "DW_AT_decimal_sign"; break; + case DW_AT_defaulted: + *s = "DW_AT_defaulted"; break; + case DW_AT_deleted: + *s = "DW_AT_deleted"; break; + case DW_AT_description: + *s = "DW_AT_description"; break; + case DW_AT_digit_count: + *s = "DW_AT_digit_count"; break; + case DW_AT_discr: + *s = "DW_AT_discr"; break; + case DW_AT_discr_list: + *s = "DW_AT_discr_list"; break; + case DW_AT_discr_value: + *s = "DW_AT_discr_value"; break; + case DW_AT_dwo_name: + *s = "DW_AT_dwo_name"; break; + case DW_AT_element_list: + *s = "DW_AT_element_list"; break; + case DW_AT_encoding: + *s = "DW_AT_encoding"; break; + case DW_AT_enum_class: + *s = "DW_AT_enum_class"; break; + case DW_AT_external: + *s = "DW_AT_external"; break; + case DW_AT_entry_pc: + *s = "DW_AT_entry_pc"; break; + case DW_AT_extension: + *s = "DW_AT_extension"; break; + case DW_AT_explicit: + *s = "DW_AT_explicit"; break; + case DW_AT_export_symbols: + *s = "DW_AT_export_symbols"; break; + case DW_AT_endianity: + *s = "DW_AT_endianity"; break; + case DW_AT_elemental: + *s = "DW_AT_elemental"; break; + case DW_AT_frame_base: + *s = "DW_AT_frame_base"; break; + case DW_AT_friend: + *s = "DW_AT_friend"; break; + case DW_AT_high_pc: + *s = "DW_AT_high_pc"; break; + case DW_AT_hi_user: + *s = "DW_AT_hi_user"; break; + case DW_AT_identifier_case: + *s = "DW_AT_identifier_case"; break; + case DW_AT_import: + *s = "DW_AT_import"; break; + case DW_AT_inline: + *s = "DW_AT_inline"; break; + case DW_AT_is_optional: + *s = "DW_AT_is_optional"; break; + case DW_AT_language: + *s = "DW_AT_language"; break; + case DW_AT_linkage_name: + *s = "DW_AT_linkage_name"; break; + case DW_AT_lo_user: + *s = "DW_AT_lo_user"; break; + case DW_AT_location: + *s = "DW_AT_location"; break; + case DW_AT_loclists_base: + *s = "DW_AT_loclists_base"; break; + case DW_AT_low_pc: + *s = "DW_AT_low_pc"; break; + case DW_AT_lower_bound: + *s = "DW_AT_lower_bound"; break; + case DW_AT_macros: + *s = "DW_AT_macros"; break; + case DW_AT_macro_info: + *s = "DW_AT_macro_info"; break; + case DW_AT_main_subprogram: + *s = "DW_AT_main_subprogram"; break; + case DW_AT_mutable: + *s = "DW_AT_mutable"; break; + case DW_AT_member: + *s = "DW_AT_member"; break; + case DW_AT_name: + *s = "DW_AT_name"; break; + case DW_AT_namelist_item: + *s = "DW_AT_namelist_item"; break; + case DW_AT_noreturn: + *s = "DW_AT_noreturn"; break; + case DW_AT_ordering: + *s = "DW_AT_ordering"; break; + case DW_AT_object_pointer: + *s = "DW_AT_object_pointer"; break; + case DW_AT_priority: + *s = "DW_AT_priority"; break; + case DW_AT_producer: + *s = "DW_AT_producer"; break; + case DW_AT_prototyped: + *s = "DW_AT_prototyped"; break; + case DW_AT_picture_string: + *s = "DW_AT_picture_string"; break; + case DW_AT_pure: + *s = "DW_AT_pure"; break; + case DW_AT_reference: + *s = "DW_AT_reference"; break; + case DW_AT_return_addr: + *s = "DW_AT_return_addr"; break; + case DW_AT_ranges: + *s = "DW_AT_ranges"; break; + case DW_AT_rank: + *s = "DW_AT_rank"; break; + case DW_AT_recursive: + *s = "DW_AT_recursive"; break; + case DW_AT_rnglists_base: + *s = "DW_AT_rnglists_base"; break; + case DW_AT_rvalue_reference: + *s = "DW_AT_rvalue_reference"; break; + case DW_AT_segment: + *s = "DW_AT_segment"; break; + case DW_AT_sibling: + *s = "DW_AT_sibling"; break; + case DW_AT_signature: + *s = "DW_AT_signature"; break; + case DW_AT_specification: + *s = "DW_AT_specification"; break; + case DW_AT_start_scope: + *s = "DW_AT_start_scope"; break; + case DW_AT_static_link: + *s = "DW_AT_static_link"; break; + case DW_AT_stmt_list: + *s = "DW_AT_stmt_list"; break; + case DW_AT_string_length: + *s = "DW_AT_string_length"; break; + case DW_AT_string_length_bit_size: + *s = "DW_AT_string_length_bit_size"; break; + case DW_AT_string_length_byte_size: + *s = "DW_AT_string_length_byte_size"; break; + case DW_AT_str_offsets_base: + *s = "DW_AT_str_offsets_base"; break; + case DW_AT_subscr_data: + *s = "DW_AT_subscr_data"; break; + case DW_AT_small: + *s = "DW_AT_small"; break; + case DW_AT_type: + *s = "DW_AT_type"; break; + case DW_AT_trampoline: + *s = "DW_AT_trampoline"; break; + case DW_AT_threads_scaled: + *s = "DW_AT_threads_scaled"; break; + case DW_AT_upper_bound: + *s = "DW_AT_upper_bound"; break; + case DW_AT_use_location: + *s = "DW_AT_use_location"; break; + case DW_AT_use_UTF8: + *s = "DW_AT_use_UTF8"; break; + case DW_AT_variable_parameter: + *s = "DW_AT_variable_parameter"; break; + case DW_AT_virtuality: + *s = "DW_AT_virtuality"; break; + case DW_AT_visibility: + *s = "DW_AT_visibility"; break; + case DW_AT_vtable_elem_location: + *s = "DW_AT_vtable_elem_location"; break; + case DW_AT_sf_names: + *s = "DW_AT_sf_names"; break; + case DW_AT_src_info: + *s = "DW_AT_src_info"; break; + case DW_AT_mac_info: + *s = "DW_AT_mac_info"; break; + case DW_AT_src_coords: + *s = "DW_AT_src_coords"; break; + case DW_AT_body_begin: + *s = "DW_AT_body_begin"; break; + case DW_AT_body_end: + *s = "DW_AT_body_end"; break; + case DW_AT_MIPS_fde: + *s = "DW_AT_MIPS_fde"; break; + case DW_AT_MIPS_loop_begin: + *s = "DW_AT_MIPS_loop_begin"; break; + case DW_AT_MIPS_tail_loop_begin: + *s = "DW_AT_MIPS_tail_loop_begin"; break; + case DW_AT_MIPS_epilog_begin: + *s = "DW_AT_MIPS_epilog_begin"; break; + case DW_AT_MIPS_loop_unroll_factor: + *s = "DW_AT_MIPS_loop_unroll_factor"; break; + case DW_AT_MIPS_software_pipeline_depth: + *s = "DW_AT_MIPS_software_pipeline_depth"; break; + case DW_AT_MIPS_linkage_name: + *s = "DW_AT_MIPS_linkage_name"; break; + case DW_AT_MIPS_stride: + *s = "DW_AT_MIPS_stride"; break; + case DW_AT_MIPS_abstract_name: + *s = "DW_AT_MIPS_abstract_name"; break; + case DW_AT_MIPS_clone_origin: + *s = "DW_AT_MIPS_clone_origin"; break; + case DW_AT_MIPS_has_inlines: + *s = "DW_AT_MIPS_has_inlines"; break; + case DW_AT_MIPS_stride_byte: + *s = "DW_AT_MIPS_stride_byte"; break; + case DW_AT_MIPS_stride_elem: + *s = "DW_AT_MIPS_stride_elem"; break; + case DW_AT_MIPS_ptr_dopetype: + *s = "DW_AT_MIPS_ptr_dopetype"; break; + case DW_AT_MIPS_allocatable_dopetype: + *s = "DW_AT_MIPS_allocatable_dopetype"; break; + case DW_AT_MIPS_assumed_shape_dopetype: + *s = "DW_AT_MIPS_assumed_shape_dopetype"; break; + case DW_AT_MIPS_assumed_size: + *s = "DW_AT_MIPS_assumed_size"; break; + case DW_AT_GNU_vector: + *s = "DW_AT_GNU_vector"; break; + case DW_AT_GNU_guarded_by: + *s = "DW_AT_GNU_guarded_by"; break; + case DW_AT_GNU_pt_guarded_by: + *s = "DW_AT_GNU_pt_guarded_by"; break; + case DW_AT_GNU_guarded: + *s = "DW_AT_GNU_guarded"; break; + case DW_AT_GNU_pt_guarded: + *s = "DW_AT_GNU_pt_guarded"; break; + case DW_AT_GNU_locks_excluded: + *s = "DW_AT_GNU_locks_excluded"; break; + case DW_AT_GNU_exclusive_locks_required: + *s = "DW_AT_GNU_exclusive_locks_required"; break; + case DW_AT_GNU_shared_locks_required: + *s = "DW_AT_GNU_shared_locks_required"; break; + case DW_AT_GNU_odr_signature: + *s = "DW_AT_GNU_odr_signature"; break; + case DW_AT_GNU_template_name: + *s = "DW_AT_GNU_template_name"; break; + case DW_AT_GNU_call_site_value: + *s = "DW_AT_GNU_call_site_value"; break; + case DW_AT_GNU_call_site_data_value: + *s = "DW_AT_GNU_call_site_data_value"; break; + case DW_AT_GNU_call_site_target: + *s = "DW_AT_GNU_call_site_target"; break; + case DW_AT_GNU_call_site_target_clobbered: + *s = "DW_AT_GNU_call_site_target_clobbered"; break; + case DW_AT_GNU_tail_call: + *s = "DW_AT_GNU_tail_call"; break; + case DW_AT_GNU_all_tail_call_sites: + *s = "DW_AT_GNU_all_tail_call_sites"; break; + case DW_AT_GNU_all_call_sites: + *s = "DW_AT_GNU_all_call_sites"; break; + case DW_AT_GNU_all_source_call_sites: + *s = "DW_AT_GNU_all_source_call_sites"; break; + case DW_AT_APPLE_optimized: + *s = "DW_AT_APPLE_optimized"; break; + case DW_AT_APPLE_flags: + *s = "DW_AT_APPLE_flags"; break; + case DW_AT_APPLE_isa: + *s = "DW_AT_APPLE_isa"; break; + case DW_AT_APPLE_block: + *s = "DW_AT_APPLE_block"; break; + case DW_AT_APPLE_major_runtime_vers: + *s = "DW_AT_APPLE_major_runtime_vers"; break; + case DW_AT_APPLE_runtime_class: + *s = "DW_AT_APPLE_runtime_class"; break; + case DW_AT_APPLE_omit_frame_ptr: + *s = "DW_AT_APPLE_omit_frame_ptr"; break; + case DW_AT_APPLE_property_name: + *s = "DW_AT_APPLE_property_name"; break; + case DW_AT_APPLE_property_getter: + *s = "DW_AT_APPLE_property_getter"; break; + case DW_AT_APPLE_property_setter: + *s = "DW_AT_APPLE_property_setter"; break; + case DW_AT_APPLE_property_attribute: + *s = "DW_AT_APPLE_property_attribute"; break; + case DW_AT_APPLE_objc_complete_type: + *s = "DW_AT_APPLE_objc_complete_type"; break; + case DW_AT_APPLE_property: + *s = "DW_AT_APPLE_property"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ATE_name(unsigned ate, const char **s) +{ + + assert(s != NULL); + + switch(ate) { + case DW_ATE_address: + *s = "DW_ATE_address"; break; + case DW_ATE_boolean: + *s = "DW_ATE_boolean"; break; + case DW_ATE_complex_float: + *s = "DW_ATE_complex_float"; break; + case DW_ATE_float: + *s = "DW_ATE_float"; break; + case DW_ATE_signed: + *s = "DW_ATE_signed"; break; + case DW_ATE_signed_char: + *s = "DW_ATE_signed_char"; break; + case DW_ATE_unsigned: + *s = "DW_ATE_unsigned"; break; + case DW_ATE_unsigned_char: + *s = "DW_ATE_unsigned_char"; break; + case DW_ATE_imaginary_float: + *s = "DW_ATE_imaginary_float"; break; + case DW_ATE_packed_decimal: + *s = "DW_ATE_packed_decimal"; break; + case DW_ATE_numeric_string: + *s = "DW_ATE_numeric_string"; break; + case DW_ATE_edited: + *s = "DW_ATE_edited"; break; + case DW_ATE_signed_fixed: + *s = "DW_ATE_signed_fixed"; break; + case DW_ATE_unsigned_fixed: + *s = "DW_ATE_unsigned_fixed"; break; + case DW_ATE_decimal_float: + *s = "DW_ATE_decimal_float"; break; + case DW_ATE_lo_user: + *s = "DW_ATE_lo_user"; break; + case DW_ATE_hi_user: + *s = "DW_ATE_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CC_name(unsigned cc, const char **s) +{ + + assert(s != NULL); + + switch (cc) { + case DW_CC_normal: + *s = "DW_CC_normal"; break; + case DW_CC_program: + *s = "DW_CC_program"; break; + case DW_CC_nocall: + *s = "DW_CC_nocall"; break; + case DW_CC_lo_user: + *s = "DW_CC_lo_user"; break; + case DW_CC_hi_user: + *s = "DW_CC_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CFA_name(unsigned cfa, const char **s) +{ + + assert(s != NULL); + + switch (cfa) { + case DW_CFA_advance_loc: + *s = "DW_CFA_advance_loc"; break; + case DW_CFA_offset: + *s = "DW_CFA_offset"; break; + case DW_CFA_restore: + *s = "DW_CFA_restore"; break; + case DW_CFA_nop: + *s = "DW_CFA_nop"; break; + case DW_CFA_set_loc: + *s = "DW_CFA_set_loc"; break; + case DW_CFA_advance_loc1: + *s = "DW_CFA_advance_loc1"; break; + case DW_CFA_advance_loc2: + *s = "DW_CFA_advance_loc2"; break; + case DW_CFA_advance_loc4: + *s = "DW_CFA_advance_loc4"; break; + case DW_CFA_offset_extended: + *s = "DW_CFA_offset_extended"; break; + case DW_CFA_restore_extended: + *s = "DW_CFA_restore_extended"; break; + case DW_CFA_undefined: + *s = "DW_CFA_undefined"; break; + case DW_CFA_same_value: + *s = "DW_CFA_same_value"; break; + case DW_CFA_register: + *s = "DW_CFA_register"; break; + case DW_CFA_remember_state: + *s = "DW_CFA_remember_state"; break; + case DW_CFA_restore_state: + *s = "DW_CFA_restore_state"; break; + case DW_CFA_def_cfa: + *s = "DW_CFA_def_cfa"; break; + case DW_CFA_def_cfa_register: + *s = "DW_CFA_def_cfa_register"; break; + case DW_CFA_def_cfa_offset: + *s = "DW_CFA_def_cfa_offset"; break; + case DW_CFA_def_cfa_expression: + *s = "DW_CFA_def_cfa_expression"; break; + case DW_CFA_expression: + *s = "DW_CFA_expression"; break; + case DW_CFA_offset_extended_sf: + *s = "DW_CFA_offset_extended_sf"; break; + case DW_CFA_def_cfa_sf: + *s = "DW_CFA_def_cfa_sf"; break; + case DW_CFA_def_cfa_offset_sf: + *s = "DW_CFA_def_cfa_offset_sf"; break; + case DW_CFA_val_offset: + *s = "DW_CFA_val_offset"; break; + case DW_CFA_val_offset_sf: + *s = "DW_CFA_val_offset_sf"; break; + case DW_CFA_val_expression: + *s = "DW_CFA_val_expression"; break; + case DW_CFA_lo_user: + *s = "DW_CFA_lo_user"; break; + case DW_CFA_high_user: + *s = "DW_CFA_high_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CHILDREN_name(unsigned children, const char **s) +{ + + assert(s != NULL); + + switch (children) { + case DW_CHILDREN_no: + *s = "DW_CHILDREN_no"; break; + case DW_CHILDREN_yes: + *s = "DW_CHILDREN_yes"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_FORM_name(unsigned form, const char **s) +{ + + assert(s != NULL); + + switch (form) { + case DW_FORM_addr: + *s = "DW_FORM_addr"; break; + case DW_FORM_addrx: + *s = "DW_FORM_addrx"; break; + case DW_FORM_addrx1: + *s = "DW_FORM_addrx1"; break; + case DW_FORM_addrx2: + *s = "DW_FORM_addrx2"; break; + case DW_FORM_addrx3: + *s = "DW_FORM_addrx3"; break; + case DW_FORM_addrx4: + *s = "DW_FORM_addrx4"; break; + case DW_FORM_block: + *s = "DW_FORM_block"; break; + case DW_FORM_block1: + *s = "DW_FORM_block1"; break; + case DW_FORM_block2: + *s = "DW_FORM_block2"; break; + case DW_FORM_block4: + *s = "DW_FORM_block4"; break; + case DW_FORM_data1: + *s = "DW_FORM_data1"; break; + case DW_FORM_data2: + *s = "DW_FORM_data2"; break; + case DW_FORM_data4: + *s = "DW_FORM_data4"; break; + case DW_FORM_data8: + *s = "DW_FORM_data8"; break; + case DW_FORM_data16: + *s = "DW_FORM_data16"; break; + case DW_FORM_exprloc: + *s = "DW_FORM_exprloc"; break; + case DW_FORM_flag: + *s = "DW_FORM_flag"; break; + case DW_FORM_flag_present: + *s = "DW_FORM_flag_present"; break; + case DW_FORM_implicit_const: + *s = "DW_FORM_implicit_const"; break; + case DW_FORM_indirect: + *s = "DW_FORM_indirect"; break; + case DW_FORM_line_strp: + *s = "DW_FORM_line_strp"; break; + case DW_FORM_loclistx: + *s = "DW_FORM_loclistx"; break; + case DW_FORM_ref1: + *s = "DW_FORM_ref1"; break; + case DW_FORM_ref2: + *s = "DW_FORM_ref2"; break; + case DW_FORM_ref4: + *s = "DW_FORM_ref4"; break; + case DW_FORM_ref8: + *s = "DW_FORM_ref8"; break; + case DW_FORM_ref_addr: + *s = "DW_FORM_ref_addr"; break; + case DW_FORM_ref_sig8: + *s = "DW_FORM_ref_sig8"; break; + case DW_FORM_ref_sup4: + *s = "DW_FORM_ref_sup4"; break; + case DW_FORM_ref_sup8: + *s = "DW_FORM_ref_sup8"; break; + case DW_FORM_ref_udata: + *s = "DW_FORM_ref_udata"; break; + case DW_FORM_rnglistx: + *s = "DW_FORM_rnglistx"; break; + case DW_FORM_sdata: + *s = "DW_FORM_sdata"; break; + case DW_FORM_sec_offset: + *s = "DW_FORM_sec_offset"; break; + case DW_FORM_string: + *s = "DW_FORM_string"; break; + case DW_FORM_strp: + *s = "DW_FORM_strp"; break; + case DW_FORM_strp_sup: + *s = "DW_FORM_strp_sup"; break; + case DW_FORM_strx: + *s = "DW_FORM_strx"; break; + case DW_FORM_strx1: + *s = "DW_FORM_strx1"; break; + case DW_FORM_strx2: + *s = "DW_FORM_strx2"; break; + case DW_FORM_strx3: + *s = "DW_FORM_strx3"; break; + case DW_FORM_strx4: + *s = "DW_FORM_strx4"; break; + case DW_FORM_udata: + *s = "DW_FORM_udata"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_DS_name(unsigned ds, const char **s) +{ + + assert(s != NULL); + + switch (ds) { + case DW_DS_unsigned: + *s = "DW_DS_unsigned"; break; + case DW_DS_leading_overpunch: + *s = "DW_DS_leading_overpunch"; break; + case DW_DS_trailing_overpunch: + *s = "DW_DS_trailing_overpunch"; break; + case DW_DS_leading_separate: + *s = "DW_DS_leading_separate"; break; + case DW_DS_trailing_separate: + *s = "DW_DS_trailing_separate"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_DSC_name(unsigned dsc, const char **s) +{ + + assert(s != NULL); + + switch (dsc) { + case DW_DSC_label: + *s = "DW_DSC_label"; break; + case DW_DSC_range: + *s = "DW_DSC_range"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_EH_name(unsigned eh, const char **s) +{ + + assert(s != NULL); + + switch (eh) { + case DW_EH_PE_absptr: + *s = "DW_EH_PE_absptr"; break; + case DW_EH_PE_uleb128: + *s = "DW_EH_PE_uleb128"; break; + case DW_EH_PE_udata2: + *s = "DW_EH_PE_udata2"; break; + case DW_EH_PE_udata4: + *s = "DW_EH_PE_udata4"; break; + case DW_EH_PE_udata8: + *s = "DW_EH_PE_udata8"; break; + case DW_EH_PE_sleb128: + *s = "DW_EH_PE_sleb128"; break; + case DW_EH_PE_sdata2: + *s = "DW_EH_PE_sdata2"; break; + case DW_EH_PE_sdata4: + *s = "DW_EH_PE_sdata4"; break; + case DW_EH_PE_sdata8: + *s = "DW_EH_PE_sdata8"; break; + case DW_EH_PE_pcrel: + *s = "DW_EH_PE_pcrel"; break; + case DW_EH_PE_textrel: + *s = "DW_EH_PE_textrel"; break; + case DW_EH_PE_datarel: + *s = "DW_EH_PE_datarel"; break; + case DW_EH_PE_funcrel: + *s = "DW_EH_PE_funcrel"; break; + case DW_EH_PE_aligned: + *s = "DW_EH_PE_aligned"; break; + case DW_EH_PE_omit: + *s = "DW_EH_PE_omit"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_END_name(unsigned end, const char **s) +{ + + assert(s != NULL); + + switch (end) { + case DW_END_default: + *s = "DW_END_default"; break; + case DW_END_big: + *s = "DW_END_big"; break; + case DW_END_little: + *s = "DW_END_little"; break; + case DW_END_lo_user: + *s = "DW_END_lo_user"; break; + case DW_END_high_user: + *s = "DW_END_high_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ID_name(unsigned id, const char **s) +{ + + assert(s != NULL); + + switch (id) { + case DW_ID_case_sensitive: + *s = "DW_ID_case_sensitive"; break; + case DW_ID_up_case: + *s = "DW_ID_up_case"; break; + case DW_ID_down_case: + *s = "DW_ID_down_case"; break; + case DW_ID_case_insensitive: + *s = "DW_ID_case_insensitive"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_INL_name(unsigned inl, const char **s) +{ + + assert(s != NULL); + + switch (inl) { + case DW_INL_not_inlined: + *s = "DW_INL_not_inlined"; break; + case DW_INL_inlined: + *s = "DW_INL_inlined"; break; + case DW_INL_declared_not_inlined: + *s = "DW_INL_declared_not_inlined"; break; + case DW_INL_declared_inlined: + *s = "DW_INL_declared_inlined"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LANG_name(unsigned lang, const char **s) +{ + + assert(s != NULL); + + switch (lang) { + case DW_LANG_C89: + *s = "DW_LANG_C89"; break; + case DW_LANG_C: + *s = "DW_LANG_C"; break; + case DW_LANG_Ada83: + *s = "DW_LANG_Ada83"; break; + case DW_LANG_C_plus_plus: + *s = "DW_LANG_C_plus_plus"; break; + case DW_LANG_Cobol74: + *s = "DW_LANG_Cobol74"; break; + case DW_LANG_Cobol85: + *s = "DW_LANG_Cobol85"; break; + case DW_LANG_Fortran77: + *s = "DW_LANG_Fortran77"; break; + case DW_LANG_Fortran90: + *s = "DW_LANG_Fortran90"; break; + case DW_LANG_Pascal83: + *s = "DW_LANG_Pascal83"; break; + case DW_LANG_Modula2: + *s = "DW_LANG_Modula2"; break; + case DW_LANG_Java: + *s = "DW_LANG_Java"; break; + case DW_LANG_C99: + *s = "DW_LANG_C99"; break; + case DW_LANG_Ada95: + *s = "DW_LANG_Ada95"; break; + case DW_LANG_Fortran95: + *s = "DW_LANG_Fortran95"; break; + case DW_LANG_PLI: + *s = "DW_LANG_PLI"; break; + case DW_LANG_ObjC: + *s = "DW_LANG_ObjC"; break; + case DW_LANG_ObjC_plus_plus: + *s = "DW_LANG_ObjC_plus_plus"; break; + case DW_LANG_UPC: + *s = "DW_LANG_UPC"; break; + case DW_LANG_D: + *s = "DW_LANG_D"; break; + case DW_LANG_Python: + *s = "DW_LANG_Python"; break; + case DW_LANG_OpenCL: + *s = "DW_LANG_OpenCL"; break; + case DW_LANG_Go: + *s = "DW_LANG_Go"; break; + case DW_LANG_Modula3: + *s = "DW_LANG_Modula3"; break; + case DW_LANG_Haskell: + *s = "DW_LANG_Haskell"; break; + case DW_LANG_C_plus_plus_03: + *s = "DW_LANG_C_plus_plus_03"; break; + case DW_LANG_C_plus_plus_11: + *s = "DW_LANG_C_plus_plus_11"; break; + case DW_LANG_OCaml: + *s = "DW_LANG_OCaml"; break; + case DW_LANG_Rust: + *s = "DW_LANG_Rust"; break; + case DW_LANG_C11: + *s = "DW_LANG_C11"; break; + case DW_LANG_Swift: + *s = "DW_LANG_Swift"; break; + case DW_LANG_Julia: + *s = "DW_LANG_Julia"; break; + case DW_LANG_Dylan: + *s = "DW_LANG_Dylan"; break; + case DW_LANG_C_plus_plus_14: + *s = "DW_LANG_C_plus_plus_14"; break; + case DW_LANG_Fortran03: + *s = "DW_LANG_Fortran03"; break; + case DW_LANG_Fortran08: + *s = "DW_LANG_Fortran08"; break; + case DW_LANG_RenderScript: + *s = "DW_LANG_RenderScript"; break; + case DW_LANG_BLISS: + *s = "DW_LANG_BLISS"; break; + case DW_LANG_lo_user: + *s = "DW_LANG_lo_user"; break; + case DW_LANG_Mips_Assembler: + *s = "DW_LANG_Mips_Assembler"; break; + case DW_LANG_hi_user: + *s = "DW_LANG_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LNE_name(unsigned lne, const char **s) +{ + + assert(s != NULL); + + switch (lne) { + case DW_LNE_end_sequence: + *s = "DW_LNE_end_sequence"; break; + case DW_LNE_set_address: + *s = "DW_LNE_set_address"; break; + case DW_LNE_define_file: + *s = "DW_LNE_define_file"; break; + case DW_LNE_lo_user: + *s = "DW_LNE_lo_user"; break; + case DW_LNE_hi_user: + *s = "DW_LNE_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LNS_name(unsigned lns, const char **s) +{ + + assert(s != NULL); + + switch (lns) { + case DW_LNS_copy: + *s = "DW_LNS_copy"; break; + case DW_LNS_advance_pc: + *s = "DW_LNS_advance_pc"; break; + case DW_LNS_advance_line: + *s = "DW_LNS_advance_line"; break; + case DW_LNS_set_file: + *s = "DW_LNS_set_file"; break; + case DW_LNS_set_column: + *s = "DW_LNS_set_column"; break; + case DW_LNS_negate_stmt: + *s = "DW_LNS_negate_stmt"; break; + case DW_LNS_set_basic_block: + *s = "DW_LNS_set_basic_block"; break; + case DW_LNS_const_add_pc: + *s = "DW_LNS_const_add_pc"; break; + case DW_LNS_fixed_advance_pc: + *s = "DW_LNS_fixed_advance_pc"; break; + case DW_LNS_set_prologue_end: + *s = "DW_LNS_set_prologue_end"; break; + case DW_LNS_set_epilogue_begin: + *s = "DW_LNS_set_epilogue_begin"; break; + case DW_LNS_set_isa: + *s = "DW_LNS_set_isa"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_MACINFO_name(unsigned mi, const char **s) +{ + + assert(s != NULL); + + switch (mi) { + case DW_MACINFO_define: + *s = "DW_MACINFO_define"; break; + case DW_MACINFO_undef: + *s = "DW_MACINFO_undef"; break; + case DW_MACINFO_start_file: + *s = "DW_MACINFO_start_file"; break; + case DW_MACINFO_end_file: + *s = "DW_MACINFO_end_file"; break; + case DW_MACINFO_vendor_ext: + *s = "DW_MACINFO_vendor_ext"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_OP_name(unsigned op, const char **s) +{ + + assert(s != NULL); + + switch (op) { + case DW_OP_deref: + *s = "DW_OP_deref"; break; + case DW_OP_reg0: + *s = "DW_OP_reg0"; break; + case DW_OP_reg1: + *s = "DW_OP_reg1"; break; + case DW_OP_reg2: + *s = "DW_OP_reg2"; break; + case DW_OP_reg3: + *s = "DW_OP_reg3"; break; + case DW_OP_reg4: + *s = "DW_OP_reg4"; break; + case DW_OP_reg5: + *s = "DW_OP_reg5"; break; + case DW_OP_reg6: + *s = "DW_OP_reg6"; break; + case DW_OP_reg7: + *s = "DW_OP_reg7"; break; + case DW_OP_reg8: + *s = "DW_OP_reg8"; break; + case DW_OP_reg9: + *s = "DW_OP_reg9"; break; + case DW_OP_reg10: + *s = "DW_OP_reg10"; break; + case DW_OP_reg11: + *s = "DW_OP_reg11"; break; + case DW_OP_reg12: + *s = "DW_OP_reg12"; break; + case DW_OP_reg13: + *s = "DW_OP_reg13"; break; + case DW_OP_reg14: + *s = "DW_OP_reg14"; break; + case DW_OP_reg15: + *s = "DW_OP_reg15"; break; + case DW_OP_reg16: + *s = "DW_OP_reg16"; break; + case DW_OP_reg17: + *s = "DW_OP_reg17"; break; + case DW_OP_reg18: + *s = "DW_OP_reg18"; break; + case DW_OP_reg19: + *s = "DW_OP_reg19"; break; + case DW_OP_reg20: + *s = "DW_OP_reg20"; break; + case DW_OP_reg21: + *s = "DW_OP_reg21"; break; + case DW_OP_reg22: + *s = "DW_OP_reg22"; break; + case DW_OP_reg23: + *s = "DW_OP_reg23"; break; + case DW_OP_reg24: + *s = "DW_OP_reg24"; break; + case DW_OP_reg25: + *s = "DW_OP_reg25"; break; + case DW_OP_reg26: + *s = "DW_OP_reg26"; break; + case DW_OP_reg27: + *s = "DW_OP_reg27"; break; + case DW_OP_reg28: + *s = "DW_OP_reg28"; break; + case DW_OP_reg29: + *s = "DW_OP_reg29"; break; + case DW_OP_reg30: + *s = "DW_OP_reg30"; break; + case DW_OP_reg31: + *s = "DW_OP_reg31"; break; + case DW_OP_lit0: + *s = "DW_OP_lit0"; break; + case DW_OP_lit1: + *s = "DW_OP_lit1"; break; + case DW_OP_lit2: + *s = "DW_OP_lit2"; break; + case DW_OP_lit3: + *s = "DW_OP_lit3"; break; + case DW_OP_lit4: + *s = "DW_OP_lit4"; break; + case DW_OP_lit5: + *s = "DW_OP_lit5"; break; + case DW_OP_lit6: + *s = "DW_OP_lit6"; break; + case DW_OP_lit7: + *s = "DW_OP_lit7"; break; + case DW_OP_lit8: + *s = "DW_OP_lit8"; break; + case DW_OP_lit9: + *s = "DW_OP_lit9"; break; + case DW_OP_lit10: + *s = "DW_OP_lit10"; break; + case DW_OP_lit11: + *s = "DW_OP_lit11"; break; + case DW_OP_lit12: + *s = "DW_OP_lit12"; break; + case DW_OP_lit13: + *s = "DW_OP_lit13"; break; + case DW_OP_lit14: + *s = "DW_OP_lit14"; break; + case DW_OP_lit15: + *s = "DW_OP_lit15"; break; + case DW_OP_lit16: + *s = "DW_OP_lit16"; break; + case DW_OP_lit17: + *s = "DW_OP_lit17"; break; + case DW_OP_lit18: + *s = "DW_OP_lit18"; break; + case DW_OP_lit19: + *s = "DW_OP_lit19"; break; + case DW_OP_lit20: + *s = "DW_OP_lit20"; break; + case DW_OP_lit21: + *s = "DW_OP_lit21"; break; + case DW_OP_lit22: + *s = "DW_OP_lit22"; break; + case DW_OP_lit23: + *s = "DW_OP_lit23"; break; + case DW_OP_lit24: + *s = "DW_OP_lit24"; break; + case DW_OP_lit25: + *s = "DW_OP_lit25"; break; + case DW_OP_lit26: + *s = "DW_OP_lit26"; break; + case DW_OP_lit27: + *s = "DW_OP_lit27"; break; + case DW_OP_lit28: + *s = "DW_OP_lit28"; break; + case DW_OP_lit29: + *s = "DW_OP_lit29"; break; + case DW_OP_lit30: + *s = "DW_OP_lit30"; break; + case DW_OP_lit31: + *s = "DW_OP_lit31"; break; + case DW_OP_dup: + *s = "DW_OP_dup"; break; + case DW_OP_drop: + *s = "DW_OP_drop"; break; + case DW_OP_over: + *s = "DW_OP_over"; break; + case DW_OP_swap: + *s = "DW_OP_swap"; break; + case DW_OP_rot: + *s = "DW_OP_rot"; break; + case DW_OP_xderef: + *s = "DW_OP_xderef"; break; + case DW_OP_abs: + *s = "DW_OP_abs"; break; + case DW_OP_and: + *s = "DW_OP_and"; break; + case DW_OP_div: + *s = "DW_OP_div"; break; + case DW_OP_minus: + *s = "DW_OP_minus"; break; + case DW_OP_mod: + *s = "DW_OP_mod"; break; + case DW_OP_mul: + *s = "DW_OP_mul"; break; + case DW_OP_neg: + *s = "DW_OP_neg"; break; + case DW_OP_not: + *s = "DW_OP_not"; break; + case DW_OP_or: + *s = "DW_OP_or"; break; + case DW_OP_plus: + *s = "DW_OP_plus"; break; + case DW_OP_shl: + *s = "DW_OP_shl"; break; + case DW_OP_shr: + *s = "DW_OP_shr"; break; + case DW_OP_shra: + *s = "DW_OP_shra"; break; + case DW_OP_xor: + *s = "DW_OP_xor"; break; + case DW_OP_eq: + *s = "DW_OP_eq"; break; + case DW_OP_ge: + *s = "DW_OP_ge"; break; + case DW_OP_gt: + *s = "DW_OP_gt"; break; + case DW_OP_le: + *s = "DW_OP_le"; break; + case DW_OP_lt: + *s = "DW_OP_lt"; break; + case DW_OP_ne: + *s = "DW_OP_ne"; break; + case DW_OP_nop: + *s = "DW_OP_nop"; break; + case DW_OP_const1u: + *s = "DW_OP_const1u"; break; + case DW_OP_const1s: + *s = "DW_OP_const1s"; break; + case DW_OP_pick: + *s = "DW_OP_pick"; break; + case DW_OP_deref_size: + *s = "DW_OP_deref_size"; break; + case DW_OP_xderef_size: + *s = "DW_OP_xderef_size"; break; + case DW_OP_const2u: + *s = "DW_OP_const2u"; break; + case DW_OP_const2s: + *s = "DW_OP_const2s"; break; + case DW_OP_bra: + *s = "DW_OP_bra"; break; + case DW_OP_skip: + *s = "DW_OP_skip"; break; + case DW_OP_const4u: + *s = "DW_OP_const4u"; break; + case DW_OP_const4s: + *s = "DW_OP_const4s"; break; + case DW_OP_const8u: + *s = "DW_OP_const8u"; break; + case DW_OP_const8s: + *s = "DW_OP_const8s"; break; + case DW_OP_constu: + *s = "DW_OP_constu"; break; + case DW_OP_plus_uconst: + *s = "DW_OP_plus_uconst"; break; + case DW_OP_regx: + *s = "DW_OP_regx"; break; + case DW_OP_piece: + *s = "DW_OP_piece"; break; + case DW_OP_consts: + *s = "DW_OP_consts"; break; + case DW_OP_breg0: + *s = "DW_OP_breg0"; break; + case DW_OP_breg1: + *s = "DW_OP_breg1"; break; + case DW_OP_breg2: + *s = "DW_OP_breg2"; break; + case DW_OP_breg3: + *s = "DW_OP_breg3"; break; + case DW_OP_breg4: + *s = "DW_OP_breg4"; break; + case DW_OP_breg5: + *s = "DW_OP_breg5"; break; + case DW_OP_breg6: + *s = "DW_OP_breg6"; break; + case DW_OP_breg7: + *s = "DW_OP_breg7"; break; + case DW_OP_breg8: + *s = "DW_OP_breg8"; break; + case DW_OP_breg9: + *s = "DW_OP_breg9"; break; + case DW_OP_breg10: + *s = "DW_OP_breg10"; break; + case DW_OP_breg11: + *s = "DW_OP_breg11"; break; + case DW_OP_breg12: + *s = "DW_OP_breg12"; break; + case DW_OP_breg13: + *s = "DW_OP_breg13"; break; + case DW_OP_breg14: + *s = "DW_OP_breg14"; break; + case DW_OP_breg15: + *s = "DW_OP_breg15"; break; + case DW_OP_breg16: + *s = "DW_OP_breg16"; break; + case DW_OP_breg17: + *s = "DW_OP_breg17"; break; + case DW_OP_breg18: + *s = "DW_OP_breg18"; break; + case DW_OP_breg19: + *s = "DW_OP_breg19"; break; + case DW_OP_breg20: + *s = "DW_OP_breg20"; break; + case DW_OP_breg21: + *s = "DW_OP_breg21"; break; + case DW_OP_breg22: + *s = "DW_OP_breg22"; break; + case DW_OP_breg23: + *s = "DW_OP_breg23"; break; + case DW_OP_breg24: + *s = "DW_OP_breg24"; break; + case DW_OP_breg25: + *s = "DW_OP_breg25"; break; + case DW_OP_breg26: + *s = "DW_OP_breg26"; break; + case DW_OP_breg27: + *s = "DW_OP_breg27"; break; + case DW_OP_breg28: + *s = "DW_OP_breg28"; break; + case DW_OP_breg29: + *s = "DW_OP_breg29"; break; + case DW_OP_breg30: + *s = "DW_OP_breg30"; break; + case DW_OP_breg31: + *s = "DW_OP_breg31"; break; + case DW_OP_fbreg: + *s = "DW_OP_fbreg"; break; + case DW_OP_bregx: + *s = "DW_OP_bregx"; break; + case DW_OP_addr: + *s = "DW_OP_addr"; break; + case DW_OP_push_object_address: + *s = "DW_OP_push_object_address"; break; + case DW_OP_call2: + *s = "DW_OP_call2"; break; + case DW_OP_call4: + *s = "DW_OP_call4"; break; + case DW_OP_call_ref: + *s = "DW_OP_call_ref"; break; + case DW_OP_form_tls_address: + *s = "DW_OP_form_tls_address"; break; + case DW_OP_call_frame_cfa: + *s = "DW_OP_call_frame_cfa"; break; + case DW_OP_bit_piece: + *s = "DW_OP_bit_piece"; break; + case DW_OP_implicit_value: + *s = "DW_OP_implicit_value"; break; + case DW_OP_stack_value: + *s = "DW_OP_stack_value"; break; + case DW_OP_GNU_push_tls_address: + *s = "DW_OP_GNU_push_tls_address"; break; + case DW_OP_GNU_uninit: + *s = "DW_OP_GNU_uninit"; break; + case DW_OP_GNU_encoded_addr: + *s = "DW_OP_GNU_encoded_addr"; break; + case DW_OP_GNU_implicit_pointer: + *s = "DW_OP_GNU_implicit_pointer"; break; + case DW_OP_GNU_entry_value: + *s = "DW_OP_GNU_entry_value"; break; + case DW_OP_GNU_const_type: + *s = "DW_OP_GNU_const_type"; break; + case DW_OP_GNU_regval_type: + *s = "DW_OP_GNU_regval_type"; break; + case DW_OP_GNU_deref_type: + *s = "DW_OP_GNU_deref_type"; break; + case DW_OP_GNU_convert: + *s = "DW_OP_GNU_convert"; break; + case DW_OP_GNU_reinterpret: + *s = "DW_OP_GNU_reinterpret"; break; + case DW_OP_GNU_parameter_ref: + *s = "DW_OP_GNU_parameter_ref"; break; + case DW_OP_GNU_addr_index: + *s = "DW_OP_GNU_addr_index"; break; + case DW_OP_GNU_const_index: + *s = "DW_OP_GNU_const_index"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ORD_name(unsigned ord, const char **s) +{ + + assert(s != NULL); + + switch (ord) { + case DW_ORD_row_major: + *s = "DW_ORD_row_major"; break; + case DW_ORD_col_major: + *s = "DW_ORD_col_major"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_TAG_name(unsigned tag, const char **s) +{ + + assert(s != NULL); + + switch (tag) { + case DW_TAG_access_declaration: + *s = "DW_TAG_access_declaration"; break; + case DW_TAG_array_type: + *s = "DW_TAG_array_type"; break; + case DW_TAG_atomic_type: + *s = "DW_TAG_atomic_type"; break; + case DW_TAG_base_type: + *s = "DW_TAG_base_type"; break; + case DW_TAG_call_site: + *s = "DW_TAG_call_site"; break; + case DW_TAG_call_site_parameter: + *s = "DW_TAG_call_site_parameter"; break; + case DW_TAG_catch_block: + *s = "DW_TAG_catch_block"; break; + case DW_TAG_class_type: + *s = "DW_TAG_class_type"; break; + case DW_TAG_coarray_type: + *s = "DW_TAG_coarray_type"; break; + case DW_TAG_common_block: + *s = "DW_TAG_common_block"; break; + case DW_TAG_common_inclusion: + *s = "DW_TAG_common_inclusion"; break; + case DW_TAG_compile_unit: + *s = "DW_TAG_compile_unit"; break; + case DW_TAG_condition: + *s = "DW_TAG_condition"; break; + case DW_TAG_const_type: + *s = "DW_TAG_const_type"; break; + case DW_TAG_constant: + *s = "DW_TAG_constant"; break; + case DW_TAG_dwarf_procedure: + *s = "DW_TAG_dwarf_procedure"; break; + case DW_TAG_dynamic_type: + *s = "DW_TAG_dynamic_type"; break; + case DW_TAG_entry_point: + *s = "DW_TAG_entry_point"; break; + case DW_TAG_enumeration_type: + *s = "DW_TAG_enumeration_type"; break; + case DW_TAG_enumerator: + *s = "DW_TAG_enumerator"; break; + case DW_TAG_formal_parameter: + *s = "DW_TAG_formal_parameter"; break; + case DW_TAG_friend: + *s = "DW_TAG_friend"; break; + case DW_TAG_generic_subrange: + *s = "DW_TAG_generic_subrange"; break; + case DW_TAG_immutable_type: + *s = "DW_TAG_immutable_type"; break; + case DW_TAG_imported_declaration: + *s = "DW_TAG_imported_declaration"; break; + case DW_TAG_imported_module: + *s = "DW_TAG_imported_module"; break; + case DW_TAG_imported_unit: + *s = "DW_TAG_imported_unit"; break; + case DW_TAG_inheritance: + *s = "DW_TAG_inheritance"; break; + case DW_TAG_inlined_subroutine: + *s = "DW_TAG_inlined_subroutine"; break; + case DW_TAG_interface_type: + *s = "DW_TAG_interface_type"; break; + case DW_TAG_label: + *s = "DW_TAG_label"; break; + case DW_TAG_lexical_block: + *s = "DW_TAG_lexical_block"; break; + case DW_TAG_member: + *s = "DW_TAG_member"; break; + case DW_TAG_module: + *s = "DW_TAG_module"; break; + case DW_TAG_namelist: + *s = "DW_TAG_namelist"; break; + case DW_TAG_namelist_item: + *s = "DW_TAG_namelist_item"; break; + case DW_TAG_namespace: + *s = "DW_TAG_namespace"; break; + case DW_TAG_packed_type: + *s = "DW_TAG_packed_type"; break; + case DW_TAG_partial_unit: + *s = "DW_TAG_partial_unit"; break; + case DW_TAG_pointer_type: + *s = "DW_TAG_pointer_type"; break; + case DW_TAG_ptr_to_member_type: + *s = "DW_TAG_ptr_to_member_type"; break; + case DW_TAG_reference_type: + *s = "DW_TAG_reference_type"; break; + case DW_TAG_restrict_type: + *s = "DW_TAG_restrict_type"; break; + case DW_TAG_rvalue_reference_type: + *s = "DW_TAG_rvalue_reference_type"; break; + case DW_TAG_set_type: + *s = "DW_TAG_set_type"; break; + case DW_TAG_shared_type: + *s = "DW_TAG_shared_type"; break; + case DW_TAG_skeleton_unit: + *s = "DW_TAG_skeleton_unit"; break; + case DW_TAG_string_type: + *s = "DW_TAG_string_type"; break; + case DW_TAG_structure_type: + *s = "DW_TAG_structure_type"; break; + case DW_TAG_subprogram: + *s = "DW_TAG_subprogram"; break; + case DW_TAG_subrange_type: + *s = "DW_TAG_subrange_type"; break; + case DW_TAG_subroutine_type: + *s = "DW_TAG_subroutine_type"; break; + case DW_TAG_template_alias: + *s = "DW_TAG_template_alias"; break; + case DW_TAG_template_type_parameter: + *s = "DW_TAG_template_type_parameter"; break; + case DW_TAG_template_value_parameter: + *s = "DW_TAG_template_value_parameter"; break; + case DW_TAG_thrown_type: + *s = "DW_TAG_thrown_type"; break; + case DW_TAG_try_block: + *s = "DW_TAG_try_block"; break; + case DW_TAG_type_unit: + *s = "DW_TAG_type_unit"; break; + case DW_TAG_typedef: + *s = "DW_TAG_typedef"; break; + case DW_TAG_union_type: + *s = "DW_TAG_union_type"; break; + case DW_TAG_unspecified_parameters: + *s = "DW_TAG_unspecified_parameters"; break; + case DW_TAG_unspecified_type: + *s = "DW_TAG_unspecified_type"; break; + case DW_TAG_variable: + *s = "DW_TAG_variable"; break; + case DW_TAG_variant: + *s = "DW_TAG_variant"; break; + case DW_TAG_variant_part: + *s = "DW_TAG_variant_part"; break; + case DW_TAG_volatile_type: + *s = "DW_TAG_volatile_type"; break; + case DW_TAG_with_stmt: + *s = "DW_TAG_with_stmt"; break; + case DW_TAG_format_label: + *s = "DW_TAG_format_label"; break; + case DW_TAG_function_template: + *s = "DW_TAG_function_template"; break; + case DW_TAG_class_template: + *s = "DW_TAG_class_template"; break; + case DW_TAG_GNU_BINCL: + *s = "DW_TAG_GNU_BINCL"; break; + case DW_TAG_GNU_EINCL: + *s = "DW_TAG_GNU_EINCL"; break; + case DW_TAG_GNU_template_template_param: + *s = "DW_TAG_GNU_template_template_param"; break; + case DW_TAG_GNU_template_parameter_pack: + *s = "DW_TAG_GNU_template_parameter_pack"; break; + case DW_TAG_GNU_formal_parameter_pack: + *s = "DW_TAG_GNU_formal_parameter_pack"; break; + case DW_TAG_GNU_call_site: + *s = "DW_TAG_GNU_call_site"; break; + case DW_TAG_GNU_call_site_parameter: + *s = "DW_TAG_GNU_call_site_parameter"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_UT_name(unsigned ut, const char **s) +{ + + assert(s != NULL); + + switch (ut) { + case DW_UT_compile: + *s = "DW_UT_compile"; break; + case DW_UT_type: + *s = "DW_UT_type"; break; + case DW_UT_partial: + *s = "DW_UT_partial"; break; + case DW_UT_skeleton: + *s = "DW_UT_skeleton"; break; + case DW_UT_split_compile: + *s = "DW_UT_split_compile"; break; + case DW_UT_split_type: + *s = "DW_UT_split_type"; break; + case DW_UT_lo_user: + *s = "DW_UT_lo_user"; break; + case DW_UT_hi_user: + *s = "DW_UT_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_VIRTUALITY_name(unsigned vir, const char **s) +{ + + assert(s != NULL); + + switch (vir) { + case DW_VIRTUALITY_none: + *s = "DW_VIRTUALITY_none"; break; + case DW_VIRTUALITY_virtual: + *s = "DW_VIRTUALITY_virtual"; break; + case DW_VIRTUALITY_pure_virtual: + *s = "DW_VIRTUALITY_pure_virtual"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_VIS_name(unsigned vis, const char **s) +{ + + assert(s != NULL); + + switch (vis) { + case DW_VIS_local: + *s = "DW_VIS_local"; break; + case DW_VIS_exported: + *s = "DW_VIS_exported"; break; + case DW_VIS_qualified: + *s = "DW_VIS_qualified"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 b/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 new file mode 100644 index 0000000000..8d19434273 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 @@ -0,0 +1,91 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_end_macro_file.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd September 25, 2011 +.Dt DWARF_END_MACRO_FILE 3 +.Os +.Sh NAME +.Nm dwarf_end_macro_file +.Nd mark the end of the current source file inclusion +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_end_macro_file +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_end_macro_file +marks the end of the current source file inclusion. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_end_macro_file +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_end_macro_file +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_end_macro_file +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 b/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 new file mode 100644 index 0000000000..c639c4d094 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 @@ -0,0 +1,67 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_errmsg.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd December 12, 2009 +.Dt DWARF_ERRMSG 3 +.Os +.Sh NAME +.Nm dwarf_errmsg +.Nd retrieve a human-readable string corresponding to a +.Vt Dwarf_Error +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "const char *" +.Fn dwarf_errmsg "Dwarf_Error err" +.Sh DESCRIPTION +Function +.Fn dwarf_errmsg +returns a +.Dv NUL Ns - Ns +terminated string for the error denoted by +argument +.Fa err . +.Pp +Argument +.Fa err +should be a valid handle to a +.Vt Dwarf_Error +instance. +.Sh Memory Management +The returned pointer should not be freed using +.Xr free 3 +or +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_errmsg +returns a pointer to a +.Dv NUL Ns - Ns +terminated string. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errno 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_errmsg.c b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c new file mode 100644 index 0000000000..e300893a61 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_errmsg.c 2975 2014-01-21 20:08:04Z kaiwang27 $"); + +static const char *_libdwarf_errors[] = { +#define DEFINE_ERROR(N,S) [DW_DLE_##N] = S + DEFINE_ERROR(NONE, "No Error"), + DEFINE_ERROR(ERROR, "An error"), + DEFINE_ERROR(NO_ENTRY, "No entry found"), + DEFINE_ERROR(ARGUMENT, "Invalid argument"), + DEFINE_ERROR(DEBUG_INFO_NULL, "Debug info NULL"), + DEFINE_ERROR(MEMORY, "Insufficient memory"), + DEFINE_ERROR(ELF, "ELF error"), + DEFINE_ERROR(CU_LENGTH_ERROR, "Invalid compilation unit data"), + DEFINE_ERROR(VERSION_STAMP_ERROR, "Unsupported version"), + DEFINE_ERROR(DEBUG_ABBREV_NULL, "Abbrev not found"), + DEFINE_ERROR(DIE_NO_CU_CONTEXT, "No current compilation unit"), + DEFINE_ERROR(LOC_EXPR_BAD, "Invalid location expression"), + DEFINE_ERROR(EXPR_LENGTH_BAD, "Invalid DWARF expression length"), + DEFINE_ERROR(DEBUG_LOC_SECTION_SHORT, "Loclist section too short"), + DEFINE_ERROR(ATTR_FORM_BAD, "Invalid attribute form"), + DEFINE_ERROR(DEBUG_LINE_LENGTH_BAD, "Line info section too short"), + DEFINE_ERROR(LINE_FILE_NUM_BAD, "Invalid file number."), + DEFINE_ERROR(DIR_INDEX_BAD, "Invalid dir index."), + DEFINE_ERROR(DEBUG_FRAME_LENGTH_BAD, "Frame section too short"), + DEFINE_ERROR(NO_CIE_FOR_FDE, "FDE without corresponding CIE"), + DEFINE_ERROR(FRAME_AUGMENTATION_UNKNOWN, "Unknown CIE augmentation"), + DEFINE_ERROR(FRAME_INSTR_EXEC_ERROR, "Frame instruction exec error"), + DEFINE_ERROR(FRAME_VERSION_BAD, "Unsupported frame section version"), + DEFINE_ERROR(FRAME_TABLE_COL_BAD, "Invalid table column value"), + DEFINE_ERROR(DF_REG_NUM_TOO_HIGH, "Register number too large"), + DEFINE_ERROR(PC_NOT_IN_FDE_RANGE, "PC requested not in the FDE range"), + DEFINE_ERROR(ARANGE_OFFSET_BAD, "Invalid address range offset"), + DEFINE_ERROR(DEBUG_MACRO_INCONSISTENT, "Invalid macinfo data"), + DEFINE_ERROR(ELF_SECT_ERR, "Application callback failed"), + DEFINE_ERROR(NUM, "Unknown DWARF error") +#undef DEFINE_ERROR +}; + +const char * +dwarf_errmsg_(Dwarf_Error *error) +{ + const char *p; + + if (error == NULL) + return NULL; + + if (error->err_error < 0 || error->err_error >= DW_DLE_NUM) + return _libdwarf_errors[DW_DLE_NUM]; + else if (error->err_error == DW_DLE_NONE) + return _libdwarf_errors[DW_DLE_NONE]; + else + p = _libdwarf_errors[error->err_error]; + + if (error->err_error == DW_DLE_ELF) + snprintf(error->err_msg, sizeof(error->err_msg), + "ELF error : %s [%s(%d)]", elf_errmsg(error->err_elferror), + error->err_func, error->err_line); + else + snprintf(error->err_msg, sizeof(error->err_msg), + "%s [%s(%d)]", p, error->err_func, error->err_line); + + return (const char *) error->err_msg; +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_errno.3 b/contrib/elftoolchain/libdwarf/dwarf_errno.3 new file mode 100644 index 0000000000..2ae93c29e2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errno.3 @@ -0,0 +1,58 @@ +.\" Copyright (c) 2009,2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_errno.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 25, 2010 +.Dt DWARF_ERRNO 3 +.Os +.Sh NAME +.Nm dwarf_errno +.Nd retrieve the error number corresponding to a +.Vt Dwarf_Error +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_errno "Dwarf_Error err" +.Sh DESCRIPTION +Function +.Fn dwarf_errno +returns the error number associated with a +.Vt Dwarf_Error +instance. +.Pp +Argument +.Fa err +should be a valid handle to a +.Vt Dwarf_Error +instance. +.Sh RETURN VALUES +Function +.Fn dwarf_errno +returns an integral value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 b/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 new file mode 100644 index 0000000000..fc8ea34552 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 @@ -0,0 +1,184 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_expand_frame_instructions.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_EXPAND_FRAME_INSTRUCTIONS 3 +.Os +.Sh NAME +.Nm dwarf_expand_frame_instructions +.Nd expand frame instructions +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_expand_frame_instructions +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Ptr instructions" +.Fa "Dwarf_Unsigned len" +.Fa "Dwarf_Frame_Op **ret_ops" +.Fa "Dwarf_Signed *ret_opcnt" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expand_frame_instructions +translates DWARF frame instruction bytes into an array of +.Vt Dwarf_Frame_Op +descriptors. +.Pp +Argument +.Fa cie +should reference the CIE descriptor associated with the instructions +to be translated. +.Pp +Arugment +.Fa instructions +should point to an array of frame instruction bytes, as +returned by the functions +.Xr dwarf_get_cie_info 3 +or +.Xr dwarf_get_fde_instr_bytes 3 . +.Pp +Argument +.Fa len +should specify the number of the frame instruction bytes to be +translated. +.Pp +Argument +.Fa ret_ops +should point to a location that will be set to a pointer to +an array of translated +.Vt Dwarf_Frame_Op +descriptors. +.Pp +Argument +.Fa ret_opcnt +should point to a location that will hold the total number of the +returned descriptors. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory area used for the descriptor array returned in argument +.Fa ret_ops +is allocated by +.Lb libdwarf . +Application code should use function +.Xr dwarf_dealloc 3 +with type +.Dv DW_DLA_FRAME_BLOCK +to free the memory area when the descriptor array is no longer needed. +.Sh RETURN VALUES +Function +.Fn dwarf_expand_frame_instructions +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To retrieve and expand the frame instructions for a given FDE +descriptor, use: +.Bd -literal -offset indent +Dwarf_Dbg dbg; +Dwarf_Cie cie; +Dwarf_Fde fde; +Dwarf_Ptr fde_inst; +Dwarf_Unsigned fde_instlen; +Dwarf_Frame_Op *ops; +Dwarf_Signed opcnt; +Dwarf_Error de; + +/* ... assuming `dbg` references a valid DWARF debugging context, + `fde` references a valid FDE descriptor and `cie` holds the CIE + descriptor associated with the FDE descriptor ... */ + +if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, + &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_fde_instr_bytes failed: %s", + dwarf_errmsg(de)); + +if (dwarf_expand_frame_instructions(cie, fde_inst, fde_instlen, + &ops, &opcnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, + "dwarf_expand_frame_instructions failed: %s", + dwarf_errmsg(de)); + +for (i = 0; i < opcnt; i++) { + /* ... use ops[i] ... */ +} + +/* Free the memory area when no longer needed. */ +dwarf_dealloc(dbg, ops, DW_DLA_FRAME_BLOCK); +.Ed +.Sh ERRORS +Function +.Fn dwarf_expand_frame_instructions +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa cie , +.Fa instructions , +.Fa ret_ops +or +.Fa ret_opcnt +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa len +was 0. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR +An unknown instruction was found in the instruction bytes provided +in argument +.Fa instructions . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_frame_instructions_dealloc 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 new file mode 100644 index 0000000000..baa0ef04c6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_expr_current_offset.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd September 13, 2011 +.Dt DWARF_EXPR_CURRENT_OFFSET 3 +.Os +.Sh NAME +.Nm dwarf_expr_current_offset +.Nd retrieve the number of bytes in a location expression stream +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_expr_current_offset +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expr_current_offset +returns the size in bytes of the stream representation of a location +expression. +.Pp +Argument +.Fa expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_expr_current_offset +returns the size in bytes of the location descriptor's stream +representation. +In case of an error, function +.Fn dwarf_expr_current_offset +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_expr_current_offset +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa expr +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 b/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 new file mode 100644 index 0000000000..4c8246f4c1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_expr_into_block.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd September 13, 2011 +.Dt DWARF_EXPR_INTO_BLOCK 3 +.Os +.Sh NAME +.Nm dwarf_expr_into_block +.Nd retrieve the byte stream for a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Addr" +.Fo dwarf_expr_into_block +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expr_into_block +retrieves the byte stream representation of a location expression. +.Pp +Argument +.Fa expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Fa length +should point to a location which will hold the size in bytes of +the retrieved byte stream. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_expr_into_block +returns the address of the first byte of the generated byte stream. +In case of an error, function +.Fn dwarf_expr_into_block +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_expr_into_block +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa expr +or +.Fa length +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 new file mode 100644 index 0000000000..3f35fcb8d7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_fde_cfa_offset.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd September 26, 2011 +.Dt DWARF_FDE_CFA_OFFSET 3 +.Os +.Sh NAME +.Nm dwarf_fde_cfa_offset +.Nd add a DW_CFA_offset frame instruction to a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_fde_cfa_offset +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_Unsigned reg" +.Fa "Dwarf_Signed offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_fde_cfa_offset +appends a +.Dv DW_CFA_offset +frame instruction to the frame descriptor referenced by argument +.Fa fde . +.Pp +Argument +.Fa fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Fa reg +specifies the register operand for the frame instruction. +.Pp +Argument +.Fa offset +specifies the offset operand for the frame instruction. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_fde_cfa_offset +returns the frame descriptor given in argument +.Fa fde . +In case of an error, function +.Fn dwarf_fde_cfa_offset +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_fde_cfa_offset +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa fde +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_new_fde 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 b/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 new file mode 100644 index 0000000000..db3a601615 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_find_macro_value_start.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 26, 2011 +.Dt DWARF_FIND_MACRO_VALUE_START 3 +.Os +.Sh NAME +.Nm dwarf_find_macro_value_start +.Nd return the address of the first byte of a macro value +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft char * +.Fo dwarf_find_macro_value_start +.Fa "char *macro_string" +.Fc +.Sh DESCRIPTION +Given a DWARF macro string, function +.Fn dwarf_find_macro_value_start +returns a pointer to the first byte of the macro value part of the +macro string. +.Pp +Argument +.Fa macro_string +should be a NUL-terminated string conforming to the macro format +defined in the DWARF standard; see +.Xr dwarf 4 . +.Sh RETURN VALUES +On success, function +.Fn dwarf_find_macro_value_start +returns a pointer to the first byte of the macro value. +If the macro value part was not found, function +.Fn dwarf_find_macro_value_start +returns a pointer to the NUL-byte terminating argument +.Fa macro_string . +.Pp +Function +.Fn dwarf_find_macro_value_start +returns +.Dv NULL +if argument +.Fa macro_string +was +.Dv NULL . +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_macro_details 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_finish.3 b/contrib/elftoolchain/libdwarf/dwarf_finish.3 new file mode 100644 index 0000000000..cf7583d058 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_finish.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 2009,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_finish.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_FINISH 3 +.Os +.Sh NAME +.Nm dwarf_finish , +.Nm dwarf_object_finish +.Nd free resources associated with a debug descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_finish "Dwarf_Debug dbg" "Dwarf_Error *err" +.Ft int +.Fn dwarf_object_finish "Dwarf_Debug dbg" "Dwarf_Error *err" +.Sh DESCRIPTION +The +.Fn dwarf_finish +and +.Fn dwarf_object_finish +functions are used to release the resources associated with a debug +descriptor allocated by a prior call to +.Xr dwarf_init 3 +and +.Xr dwarf_object_init 3 +respectively. +.Pp +Argument +.Fa dbg +denotes a valid +.Vt Dwarf_Debug +instance. +Argument +.Fa err +will be used to record error information in case of an error. +.Pp +After a call to +.Fn dwarf_finish +or +.Fn dwarf_object_finish , +the argument +.Fa dbg +will be invalid and should not be used further. +.Pp +For +.Vt Dwarf_Debug +descriptors opened using +.Xr dwarf_init 3 , +the application would need to explicitly release the +.Vt Elf +instance associated with the descriptor by first retrieving +the instance using +.Xr dwarf_get_elf 3 +and closing it using +.Xr elf_end 3 . +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +if successful. +In case of an error, the functions return +.Dv DW_DLV_ERROR +and record additional information in argument +.Fa err . +.Sh EXAMPLES +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_elf_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; + +if (dwarf_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); +.Ed +.Pp +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_object_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; + +if (dwarf_object_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_object_finish: %s", + dwarf_errmsg(de)); +.Ed +.Pp +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dward_Error de; +Elf *e; + +if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(&de)); + +if (dwarf_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); + +(void) elf_end(e); +.Ed +.Sh SEE ALSO +.Xr dwarf_elf_init 3 , +.Xr dwarf_get_elf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_object_init 3 , +.Xr elf_end 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_finish.c b/contrib/elftoolchain/libdwarf/dwarf_finish.c new file mode 100644 index 0000000000..b3bdc0b478 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_finish.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_finish.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_finish(Dwarf_Debug dbg, Dwarf_Error *error) +{ + (void) error; /* unused */ + + if (dbg == NULL) + return (DW_DLV_OK); + + _dwarf_deinit(dbg); + _dwarf_elf_deinit(dbg); + + free(dbg); + + return (DW_DLV_OK); +} + + +int +dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error *error) +{ + (void) error; /* unused */ + + if (dbg == NULL) + return (DW_DLV_OK); + + _dwarf_deinit(dbg); + + free(dbg); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_form.c b/contrib/elftoolchain/libdwarf/dwarf_form.c new file mode 100644 index 0000000000..4ee3860936 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_form.c @@ -0,0 +1,503 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009,2010,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_form.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +int +dwarf_hasform(Dwarf_Attribute at, Dwarf_Half form, Dwarf_Bool *return_hasform, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_hasform == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_hasform = (at->at_form == form); + + return (DW_DLV_OK); +} + +int +dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_form == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_form = at->at_form; + + return (DW_DLV_OK); +} + +int +dwarf_whatform_direct(Dwarf_Attribute at, Dwarf_Half *return_form, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_form == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_indirect) + *return_form = DW_FORM_indirect; + else + *return_form = (Dwarf_Half) at->at_form; + + return (DW_DLV_OK); +} + +int +dwarf_whatattr(Dwarf_Attribute at, Dwarf_Half *return_attr, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_attr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_attr = (Dwarf_Half) at->at_attrib; + + return (DW_DLV_OK); +} + +int +dwarf_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + *return_offset = (Dwarf_Off) at->u[0].u64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_global_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_ref_addr: + case DW_FORM_sec_offset: + *return_offset = (Dwarf_Off) at->u[0].u64; + ret = DW_DLV_OK; + break; + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + *return_offset = (Dwarf_Off) at->u[0].u64 + + at->at_die->die_cu->cu_offset; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formaddr(Dwarf_Attribute at, Dwarf_Addr *return_addr, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_addr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form == DW_FORM_addr) { + *return_addr = at->u[0].u64; + ret = DW_DLV_OK; + } else { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formflag(Dwarf_Attribute at, Dwarf_Bool *return_bool, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_bool == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form == DW_FORM_flag || + at->at_form == DW_FORM_flag_present) { + *return_bool = (Dwarf_Bool) (!!at->u[0].u64); + ret = DW_DLV_OK; + } else { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formudata(Dwarf_Attribute at, Dwarf_Unsigned *return_uvalue, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_uvalue == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + *return_uvalue = at->u[0].u64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formsdata(Dwarf_Attribute at, Dwarf_Signed *return_svalue, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_svalue == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_data1: + *return_svalue = (int8_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data2: + *return_svalue = (int16_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data4: + *return_svalue = (int32_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data8: + case DW_FORM_sdata: + *return_svalue = at->u[0].s64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formblock(Dwarf_Attribute at, Dwarf_Block **return_block, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_block == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + *return_block = &at->at_block; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formsig8(Dwarf_Attribute at, Dwarf_Sig8 *return_sig8, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_sig8 == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form != DW_FORM_ref_sig8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + assert(at->u[0].u64 == 8); + memcpy(return_sig8->signature, at->u[1].u8p, at->u[0].u64); + + return (DW_DLV_OK); +} + +int +dwarf_formexprloc(Dwarf_Attribute at, Dwarf_Unsigned *return_exprlen, + Dwarf_Ptr *return_expr, Dwarf_Error *error) +{ + + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_exprlen == NULL || return_expr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form != DW_FORM_exprloc) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + *return_exprlen = at->u[0].u64; + *return_expr = (void *) at->u[1].u8p; + + return (DW_DLV_OK); +} + +int +dwarf_formstring(Dwarf_Attribute at, char **return_string, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = at->at_die->die_cu; + assert(cu != NULL); + + switch (at->at_form) { + case DW_FORM_string: + *return_string = (char *) at->u[0].s; + ret = DW_DLV_OK; + break; + case DW_FORM_strp: + case DW_FORM_line_strp: + *return_string = (char *) at->u[1].s; + ret = DW_DLV_OK; + break; + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + if (_dwarf_read_indexed_str(dbg, cu, at->u[0].u64, + return_string, error) != DW_DLE_NONE) + ret = DW_DLV_ERROR; + else + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +enum Dwarf_Form_Class +dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr, + Dwarf_Half offset_size, Dwarf_Half form) +{ + + switch (form) { + case DW_FORM_addr: + return (DW_FORM_CLASS_ADDRESS); + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + return (DW_FORM_CLASS_BLOCK); + case DW_FORM_string: + case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_strp_sup: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + return (DW_FORM_CLASS_STRING); + case DW_FORM_flag: + case DW_FORM_flag_present: + return (DW_FORM_CLASS_FLAG); + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_ref_udata: + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + return (DW_FORM_CLASS_REFERENCE); + case DW_FORM_exprloc: + return (DW_FORM_CLASS_EXPRLOC); + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_sdata: + case DW_FORM_udata: + return (DW_FORM_CLASS_CONSTANT); + case DW_FORM_data4: + case DW_FORM_data8: + if (dwversion > 3) + return (DW_FORM_CLASS_CONSTANT); + if (form == DW_FORM_data4 && offset_size != 4) + return (DW_FORM_CLASS_CONSTANT); + if (form == DW_FORM_data8 && offset_size != 8) + return (DW_FORM_CLASS_CONSTANT); + /* FALLTHROUGH */ + case DW_FORM_sec_offset: + /* + * DW_FORM_data4 and DW_FORM_data8 can be used as + * offset/pointer before DWARF4. Newly added + * DWARF4 form DW_FORM_sec_offset intents to replace + * DW_FORM_data{4,8} for this purpose. Anyway, to + * determine the actual class for these forms, we need + * to also look at the attribute number. + */ + switch (attr) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + return (DW_FORM_CLASS_LOCLISTPTR); + case DW_AT_stmt_list: + return (DW_FORM_CLASS_LINEPTR); + case DW_AT_start_scope: + case DW_AT_ranges: + return (DW_FORM_CLASS_RANGELISTPTR); + case DW_AT_macro_info: + return (DW_FORM_CLASS_MACPTR); + default: + if (form == DW_FORM_data4 || form == DW_FORM_data8) + return (DW_FORM_CLASS_CONSTANT); + else + return (DW_FORM_CLASS_UNKNOWN); + } + default: + return (DW_FORM_CLASS_UNKNOWN); + } +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 b/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 new file mode 100644 index 0000000000..8fcaab85c1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formaddr.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd July 23, 2010 +.Dt DWARF_FORMADDR 3 +.Os +.Sh NAME +.Nm dwarf_formaddr +.Nd return the value of an ADDRESS class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formaddr +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Addr *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formaddr +sets the location pointed to by argument +.Fa ret +to the address represented by the attribute referenced +by argument +.Fa attr . +The form of argument +.Fa attr +must be +.Dv DW_FORM_addr . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formaddr +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formblock +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of form +.Dv DW_FORM_addr . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formblock.3 b/contrib/elftoolchain/libdwarf/dwarf_formblock.3 new file mode 100644 index 0000000000..ec30b6a11b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formblock.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formblock.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd July 23, 2010 +.Dt DWARF_FORMBLOCK 3 +.Os +.Sh NAME +.Nm dwarf_formblock +.Nd return the value of a BLOCK attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formblock +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Block **ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formblock +sets the location pointed to by argument +.Fa ret +to a pointer to a +.Vt Dwarf_Block +structure containing the value of the attribute referenced +by argument +.Fa attr . +The form of argument +.Fa attr +must be one of +.Dv DW_FORM_block , +.Dv DW_FORM_block1 , +.Dv DW_FORM_block2 +or +.Dv DW_FORM_block4 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Ss Memory Management +The memory area referenced by the returned pointer is managed by +the DWARF(3) library. +The application should not attempt to free this memory +area. +Portable code may indicate that the memory area is to be freed by +using +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_formblock +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formblock +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 b/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 new file mode 100644 index 0000000000..55930ed012 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formexprloc.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd July 25, 2010 +.Dt DWARF_FORMEXPRLOC 3 +.Os +.Sh NAME +.Nm dwarf_formexprloc +.Nd return information about a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formexprloc +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Unsigned *retlen" +.Fa "Dwarf_Ptr *retexpr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formexprloc +allows an application to retrieve the length and the bytes of a +DWARF location expression. +.Pp +Argument +.Fa attr +should reference a DWARF attribute of the form +.Dv DW_FORM_exprloc . +Argument +.Fa retlen +should point to a location that will be set to the length of the +location expression. +Argument +.Fa retexpr +should point to a location that will be set to a pointer to the +content of the location expression itself. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Ss Memory Management +The application should not attempt to free the memory +area referenced by the pointer returned in argument +.Fa retexpr . +.Sh RETURN VALUES +Function +.Fn dwarf_formexprloc +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formexprloc +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of arguments +.Fa attr , +.Fa retlen +or +.Fa retexpr +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of form +.Dv DW_FORM_exprloc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formflag.3 b/contrib/elftoolchain/libdwarf/dwarf_formflag.3 new file mode 100644 index 0000000000..0fbd9fee2d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formflag.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formflag.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 21, 2010 +.Dt DWARF_FORMFLAG 3 +.Os +.Sh NAME +.Nm dwarf_formflag +.Nd return the value of a BOOLEAN class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formflag +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formflag +sets the location pointed to by argument +.Fa ret +to 1 if the attribute referenced by argument +.Fa attr +has a non-zero value, or 0 otherwise. +The form of argument +.Fa attr +must be one of +.Dv DW_FORM_flag +or +.Dv DW_FORM_flag_present . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formflag +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formflag +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formref.3 b/contrib/elftoolchain/libdwarf/dwarf_formref.3 new file mode 100644 index 0000000000..5df5cc1936 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formref.3 @@ -0,0 +1,138 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formref.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 21, 2010 +.Dt DWARF_FORMREF 3 +.Os +.Sh NAME +.Nm dwarf_formref , +.Nm dwarf_global_formref +.Nd retrieve offsets for REFERENCE class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formref +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Off *retoffset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_formref +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Off *retoffset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions return the offsets associated with a DWARF attribute +descriptor. +.Pp +Function +.Fn dwarf_formref +returns the compilation unit relative offset of the descriptor +referenced by argument +.Fa attr +in the location pointed to by argument +.Fa retoffset . +Argument +.Fa attr +must be a reference that is local to a compilation unit. +Permitted forms for argument +.Fa attr +are +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 +and +.Dv DW_FORM_ref_udata . +.Pp +Function +.Fn dwarf_global_formref +returns the section-relative offset of the descriptor referenced by +argument +.Fa attr +in the location pointed to by argument +.Fa retoffset . +Argument +.Fa attr +should be a legal +.Sy REFERENCE +class form. +Permitted forms for argument +.Fa attr +are: +.Dv DW_FORM_ref_addr , +.Dv DW_FORM_ref_udata , +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 +and +.Dv DW_FORM_sec_offset . +The returned offset is relative to the start of the +.Dq .debug_info +ELF section. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, these functions return +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa retoffset +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 b/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 new file mode 100644 index 0000000000..e87bee55f0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formsig8.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd July 24, 2010 +.Dt DWARF_FORMSIG8 3 +.Os +.Sh NAME +.Nm dwarf_formsig8 +.Nd return the 64-bit type signature for a DWARF type +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formsig8 +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Sig8 *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formsig8 +sets the location pointed to by argument +.Fa ret +to the 64-bit type signature that is the value of +the attribute referenced by argument +.Fa attr . +The form of argument +.Fa attr +must be +.Dv DW_FORM_ref_sig8 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formsig8 +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formsig8 +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 +.Sh HISTORY +Type signatures were added in version 4 of the DWARF specification. diff --git a/contrib/elftoolchain/libdwarf/dwarf_formstring.3 b/contrib/elftoolchain/libdwarf/dwarf_formstring.3 new file mode 100644 index 0000000000..2f0361fe7c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formstring.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formstring.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd July 24, 2010 +.Dt DWARF_FORMSTRING 3 +.Os +.Sh NAME +.Nm dwarf_formstring +.Nd return the value of a STRING class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formstring +.Fa "Dwarf_Attribute attr" +.Fa "char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formstring +sets the location pointed to by argument +.Fa ret +to a pointer to a NUL-terminated string containing +the value of the attribute referenced by argument +.Fa attr . +The form of argument +.Fa attr +must be one of +.Dv DW_FORM_string +or +.Dv DW_FORM_strp . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Ss Memory Management +The memory area referenced by the returned pointer is managed by +the DWARF(3) library. +The application should not attempt to directly free this memory +area. +.Sh RETURN VALUES +Function +.Fn dwarf_formstring +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_formstring +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formudata.3 b/contrib/elftoolchain/libdwarf/dwarf_formudata.3 new file mode 100644 index 0000000000..5a8a8751be --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formudata.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_formudata.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 21, 2010 +.Dt DWARF_FORMUDATA 3 +.Os +.Sh NAME +.Nm dwarf_formudata , +.Nm dwarf_formsdata +.Nd return the value of a CONSTANT class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formudata +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_formsdata +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions return the value associated with a DWARF attribute +describing a constant. +.Pp +Function +.Fn dwarf_formudata +sets the location pointed to by argument +.Fa ret +to the value of the attribute referenced by argument +.Fa attr , +treating the value as an unsigned quantity. +Argument +.Fa attr +must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +and +.Dv DW_FORM_udata . +.Pp +Function +.Fn dwarf_formsdata +sets the location pointed to by argument +.Fa ret +to the value of the attribute referenced by argument +.Fa attr , +appropriately sign extended. +Argument +.Fa attr +must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +and +.Dv DW_FORM_sdata . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, they return +.Dv DW_DLV_ERROR +and set argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa attr +or +.Fa ret +was +.Dv NULL . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Fa attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_frame.c b/contrib/elftoolchain/libdwarf/dwarf_frame.c new file mode 100644 index 0000000000..442f232cf0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_frame.c @@ -0,0 +1,603 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); + +int +dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list, + Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, + Dwarf_Error *error) +{ + + if (dbg == NULL || cie_list == NULL || cie_count == NULL || + fde_list == NULL || fde_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_internal_reg_table == NULL) { + if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + if (dbg->dbg_frame == NULL) { + if (_dwarf_frame_section_load(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_frame == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + if (dbg->dbg_frame->fs_ciearray == NULL || + dbg->dbg_frame->fs_fdearray == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *cie_list = dbg->dbg_frame->fs_ciearray; + *cie_count = dbg->dbg_frame->fs_cielen; + *fde_list = dbg->dbg_frame->fs_fdearray; + *fde_count = dbg->dbg_frame->fs_fdelen; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie **cie_list, + Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, + Dwarf_Error *error) +{ + + if (dbg == NULL || cie_list == NULL || cie_count == NULL || + fde_list == NULL || fde_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_internal_reg_table == NULL) { + if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + if (dbg->dbg_eh_frame == NULL) { + if (_dwarf_frame_section_load_eh(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_eh_frame == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + if (dbg->dbg_eh_frame->fs_ciearray == NULL || + dbg->dbg_eh_frame->fs_fdearray == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *cie_list = dbg->dbg_eh_frame->fs_ciearray; + *cie_count = dbg->dbg_eh_frame->fs_cielen; + *fde_list = dbg->dbg_eh_frame->fs_fdearray; + *fde_count = dbg->dbg_eh_frame->fs_fdelen; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_n(Dwarf_Fde *fdelist, Dwarf_Unsigned fde_index, + Dwarf_Fde *ret_fde, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Debug dbg; + + dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; + + if (fdelist == NULL || ret_fde == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + fs = fdelist[0]->fde_fs; + assert(fs != NULL); + + if (fde_index >= fs->fs_fdelen) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_fde = fdelist[fde_index]; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_at_pc(Dwarf_Fde *fdelist, Dwarf_Addr pc, Dwarf_Fde *ret_fde, + Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Debug dbg; + Dwarf_Fde fde; + int i; + + dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; + + if (fdelist == NULL || ret_fde == NULL || lopc == NULL || + hipc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + fs = fdelist[0]->fde_fs; + assert(fs != NULL); + + for (i = 0; (Dwarf_Unsigned)i < fs->fs_fdelen; i++) { + fde = fdelist[i]; + if (pc >= fde->fde_initloc && pc < fde->fde_initloc + + fde->fde_adrange) { + *ret_fde = fde; + *lopc = fde->fde_initloc; + *hipc = fde->fde_initloc + fde->fde_adrange - 1; + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *ret_cie, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || ret_cie == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_cie = fde->fde_cie; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len, + Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset, + Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || low_pc == NULL || func_len == NULL || + fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL || + cie_index == NULL || fde_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *low_pc = fde->fde_initloc; + *func_len = fde->fde_adrange; + *fde_bytes = fde->fde_addr; + *fde_byte_len = fde->fde_length; + *cie_offset = fde->fde_cieoff; + *cie_index = fde->fde_cie->cie_index; + *fde_offset = fde->fde_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, + Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf, + Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst, + Dwarf_Unsigned *inst_len, Dwarf_Error *error) +{ + + if (cie == NULL || bytes_in_cie == NULL || version == NULL || + augmenter == NULL || caf == NULL || daf == NULL || ra == NULL || + initinst == NULL || inst_len == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *bytes_in_cie = cie->cie_length; + *version = cie->cie_version; + *augmenter = (char *) cie->cie_augment; + *caf = cie->cie_caf; + *daf = cie->cie_daf; + *ra = cie->cie_ra; + *initinst = cie->cie_initinst; + *inst_len = cie->cie_instlen; + + return (DW_DLV_OK); +} + +int +dwarf_get_cie_index(Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error) +{ + + if (cie == NULL || cie_index == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *cie_index = cie->cie_index; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_instr_bytes(Dwarf_Fde fde, Dwarf_Ptr *ret_inst, + Dwarf_Unsigned *ret_len, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || ret_inst == NULL || ret_len == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_inst = fde->fde_inst; + *ret_len = fde->fde_instlen; + + return (DW_DLV_OK); +} + +#define RL rt->rt3_rules[table_column] +#define CFA rt->rt3_cfa_rule + +int +dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, + Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, + Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || offset_relevant == NULL || register_num == NULL || + offset == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (table_column == dbg->dbg_frame_cfa_value) { + /* Application ask for CFA. */ + *offset_relevant = CFA.dw_offset_relevant; + *register_num = CFA.dw_regnum; + *offset = CFA.dw_offset_or_block_len; + } else { + /* Application ask for normal registers. */ + if (table_column >= dbg->dbg_frame_rule_table_size || + table_column >= DW_REG_TABLE_SIZE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + *offset_relevant = RL.dw_offset_relevant; + *register_num = RL.dw_regnum; + *offset = RL.dw_offset_or_block_len; + } + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Regtable3 *rt; + Dwarf_Addr pc; + Dwarf_Half cfa; + int i, ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg_table == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(dbg != NULL); + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + /* + * Copy the CFA rule to the column intended for holding the CFA, + * if it's within the range of regtable. + */ + cfa = dbg->dbg_frame_cfa_value; + if (cfa < DW_REG_TABLE_SIZE) { + reg_table->rules[cfa].dw_offset_relevant = + CFA.dw_offset_relevant; + reg_table->rules[cfa].dw_regnum = CFA.dw_regnum; + reg_table->rules[cfa].dw_offset = CFA.dw_offset_or_block_len; + } + + /* + * Copy other columns. + */ + for (i = 0; i < DW_REG_TABLE_SIZE && i < dbg->dbg_frame_rule_table_size; + i++) { + + /* Do not overwrite CFA column */ + if (i == cfa) + continue; + + reg_table->rules[i].dw_offset_relevant = + rt->rt3_rules[i].dw_offset_relevant; + reg_table->rules[i].dw_regnum = rt->rt3_rules[i].dw_regnum; + reg_table->rules[i].dw_offset = + rt->rt3_rules[i].dw_offset_or_block_len; + } + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, + Dwarf_Addr pc_requested, Dwarf_Small *value_type, + Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, + Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, + Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || value_type == NULL || offset_relevant == NULL || + register_num == NULL || offset_or_block_len == NULL || + block_ptr == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (table_column >= dbg->dbg_frame_rule_table_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + *value_type = RL.dw_value_type; + *offset_relevant = RL.dw_offset_relevant; + *register_num = RL.dw_regnum; + *offset_or_block_len = RL.dw_offset_or_block_len; + *block_ptr = RL.dw_block_ptr; + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, + Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || value_type == NULL || offset_relevant == NULL || + register_num == NULL || offset_or_block_len == NULL || + block_ptr == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *value_type = CFA.dw_value_type; + *offset_relevant = CFA.dw_offset_relevant; + *register_num = CFA.dw_regnum; + *offset_or_block_len = CFA.dw_offset_or_block_len; + *block_ptr = CFA.dw_block_ptr; + *row_pc = pc; + + return (DW_DLV_OK); +} + +#undef RL +#undef CFA + +int +dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg_table == NULL || reg_table->rt3_rules == NULL || + row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(dbg != NULL); + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + ret = _dwarf_frame_regtable_copy(dbg, ®_table, rt, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, + Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int ret; + + dbg = cie != NULL ? cie->cie_dbg : NULL; + + if (cie == NULL || instruction == NULL || len == 0 || + ret_oplist == NULL || ret_opcnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len, + ret_oplist, ret_opcnt, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + +Dwarf_Half +dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_rule_table_size; + dbg->dbg_frame_rule_table_size = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_rule_initial_value; + dbg->dbg_frame_rule_initial_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_cfa_value; + dbg->dbg_frame_cfa_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_same_value; + dbg->dbg_frame_same_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_undefined_value; + dbg->dbg_frame_undefined_value = value; + + return (old_value); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 b/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 new file mode 100644 index 0000000000..5960ee909f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_funcs.m4 2073 2011-10-27 03:30:47Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(func,Func,func,static_func) diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 new file mode 100644 index 0000000000..0c082da3eb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 @@ -0,0 +1,260 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_AT_name.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 22, 2011 +.Dt DWARF_GET_AT_NAME 3 +.Os +.Sh NAME +.Nm dwarf_get_ACCESS_name , +.Nm dwarf_get_AT_name , +.Nm dwarf_get_ATE_name , +.Nm dwarf_get_CC_name , +.Nm dwarf_get_CFA_name , +.Nm dwarf_get_CHILDREN_name , +.Nm dwarf_get_DS_name , +.Nm dwarf_get_DSC_name , +.Nm dwarf_get_EH_name , +.Nm dwarf_get_END_name , +.Nm dwarf_get_FORM_name , +.Nm dwarf_get_ID_name , +.Nm dwarf_get_INL_name , +.Nm dwarf_get_LANG_name , +.Nm dwarf_get_LNE_name , +.Nm dwarf_get_LNS_name , +.Nm dwarf_get_MACINFO_name , +.Nm dwarf_get_OP_name , +.Nm dwarf_get_ORD_name , +.Nm dwarf_get_TAG_name , +.Nm dwarf_get_VIRTUALITY_name , +.Nm dwarf_get_VIS_name +.Nd retrieve the symbolic names of DWARF constants +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_ACCESS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_AT_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ATE_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CC_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CFA_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CHILDREN_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_DS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_DSC_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_EH_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_END_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_FORM_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ID_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_INL_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LANG_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LNE_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LNS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_MACINFO_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_OP_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ORD_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_TAG_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_VIRTUALITY_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_VIS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Sh DESCRIPTION +These functions return the symbolic name of a numeric DWARF constant. +.Pp +Argument +.Fa val +specifies the numeric value whose symbolic name is desired. +.Pp +Argument +.Fa str +should point to a location which will hold the returned +NUL-terminated string containing the symbolic name of the +specified value. +.Pp +The list of functions and the DWARF constants that they accept are: +.Pp +.Bl -tag -width ".Fn dwarf_get_VIRTUALITY_name" -compact +.It Fn dwarf_get_ACCESS_name +.Dv DW_ACCESS_* +constants. +.It Fn dwarf_get_AT_name +.Dv DW_AT_* +constants. +.It Fn dwarf_get_ATE_name +.Dv DW_ATE_* +constants. +.It Fn dwarf_get_CC_name +.Dv DW_CC_* +constants. +.It Fn dwarf_get_CFA_name +.Dv DW_CFA_* +constants. +.It Fn dwarf_get_CHILDREN_name +.Dv DW_CHILDREN_* +constants. +.It Fn dwarf_get_DS_name +.Dv DW_DS_* +constants. +.It Fn dwarf_get_DSC_name +.Dv DW_DSC_* +constants. +.It Fn dwarf_get_EH_name +.Dv DW_EH_PE_* +constants. +.It Fn dwarf_get_END_name +.Dv DW_END_* +constants. +.It Fn dwarf_get_FORM_name +.Dv DW_FORM_* +constants. +.It Fn dwarf_get_ID_name +.Dv DW_ID_* +constants. +.It Fn dwarf_get_INL_name +.Dv DW_INL_* +constants. +.It Fn dwarf_get_LANG_name +.Dv DW_LANG_* +constants. +.It Fn dwarf_get_LNE_name +.Dv DW_LNE_* +constants. +.It Fn dwarf_get_LNS_name +.Dv DW_LNS_* +constants. +.It Fn dwarf_get_MACINFO_name +.Dv DW_MACINFO_* +constants. +.It Fn dwarf_get_OP_name +.Dv DW_OP_* +constants. +.It Fn dwarf_get_ORD_name +.Dv DW_ORD_* +constants. +.It Fn dwarf_get_TAG_name +.Dv DW_TAG_* +constants. +.It Fn dwarf_get_VIRTUALITY_name +.Dv DW_VIRTUALITY_* +constants. +.It Fn dwarf_get_VIS_name +.Dv DW_VIS_* +constants. +.El +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +If the DWARF constant denoted by argument +.Fa val +is not recognized, these function return +.Dv DW_DLV_NO_ENTRY . +.Sh SEE ALSO +.Xr dwarf 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 new file mode 100644 index 0000000000..d86811ee0c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 @@ -0,0 +1,181 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_abbrev.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 27, 2011 +.Dt DWARF_GET_ABBREV 3 +.Os +.Sh NAME +.Nm dwarf_get_abbrev +.Nd retrieve abbreviation information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned offset" +.Fa "Dwarf_Abbrev *ret_abbrev" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Unsigned *attr_count" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev +retrieves information about an abbreviation from the DWARF abbreviations +section, +.Dq ".debug_abbrev" . +Abbreviation information is returned using an opaque descriptor +of type +.Vt Dwarf_Abbrev . +The returned +.Vt Dwarf_Abbrev +descriptor may then be passed to the other abbreviation related APIs +in the DWARF(3) API to retrieve specific information about the +abbreviation. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa offset +should be an offset, relative to the +.Dq ".debug_abbrev" +section, to the start of an abbreviation entry. +.Pp +Argument +.Fa ret_abbrev +should point to a location that will hold a pointer to the +returned +.Vt Dwarf_Abbrev +descriptor. +.Pp +Argument +.Fa length +should point to a location that will hold the number of bytes used +by the abbrevation in the DWARF +.Dq ".debug_abbrev" +section. +.Pp +Argument +.Fa attr_count +should point to a location that will hold the number of +attributes in the abbrevation. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory area used for the +.Vt Dwarf_Abbrev +descriptor returned in argument +.Fa ret_abbrev +is allocated by the +.Lb libdwarf . +Application code should use function +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_ABBREV +to free the memory area when the +.Vt Dwarf_Abbrev +descriptor is no longer needed. +.Ss Application Programming Notes +The last abbreviation entry in a standard DWARF abbreviation section +will have a special length value of 1. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no abbreviation information at offset +.Fa offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To loop through all the abbreviation information associated with +a DWARF debug context, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Abbrev ab; +Dwarf_Off aboff; +Dwarf_Unsigned length, attr_count; +Dwarf_Half tag; +Dwarf_Error de; +int ret; + +while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, + NULL, NULL, &de)) == DW_DLV_OK) { + while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, + &attr_count, &de)) == DW_DLV_OK) { + if (length == 1) /* Last entry. */ + break; + aboff += length; + if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + if (ret != DW_DLV_OK) + warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); +} +if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_abbrev +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa ret_abbrev , +.Fa length +or +.Fa attr_count +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There is no abbreviation information at offset +.Fa offset . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 new file mode 100644 index 0000000000..07d1048cc3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_abbrev_children_flag.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 14, 2011 +.Dt DWARF_GET_ABBREV_CHILDREN_FLAG 3 +.Os +.Sh NAME +.Nm dwarf_get_abbrev_children_flag +.Nd return a flag indicating the presence of children +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_children_flag +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_children_flag +retrieves a flag indicating whether the DWARF debug information entry +associated with a DWARF abbreviation descriptor has child entries. +.Pp +Argument +.Fa abbrev +should be a valid DWARF abbreviation descriptor, as returned by +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Fa ret +should point to a location which will hold the returned +flag. +The value returned will be one of the following: +.Bl -tag -width ".Dv DW_CHILDREN_yes" -compact +.It Dv DW_CHILDREN_yes +The debugging information entry associated with the +specified abbreviation descriptor has children. +.It Dv DW_CHILDREN_no +The debugging information entry associated with the +specified abbreviation descriptor has no children. +.El +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_children_flag +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_children_flag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa abbrev +or +.Fa ret +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 new file mode 100644 index 0000000000..3dc9f6a638 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_abbrev_code.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 13, 2011 +.Dt DWARF_GET_ABBREV_CODE 3 +.Os +.Sh NAME +.Nm dwarf_get_abbrev_code +.Nd retrieve the abbreviation code for an abbreviation +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_code +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_code +retrieves the abbreviation code for the abbreviation entry descriptor +referenced by argument +.Fa abbrev . +.Pp +Argument +.Fa ret +should point to a location which will hold the returned +abbreviation code. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_code +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_code +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa abbrev +or +.Fa ret +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 new file mode 100644 index 0000000000..f2524e4fdd --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 @@ -0,0 +1,161 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_abbrev_entry.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 02, 2011 +.Dt DWARF_GET_ABBREV_ENTRY 3 +.Os +.Sh NAME +.Nm dwarf_get_abbrev_entry +.Nd retrieve attribute information from an abbreviation descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_entry +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Signed ndx" +.Fa "Dwarf_Half *code" +.Fa "Dwarf_Signed *form" +.Fa "Dwarf_Off *offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_entry +retrieves attribute information from a DWARF abbreviation descriptor. +.Pp +Argument +.Fa abbrev +should be a valid abbreviation descriptor, as returned by function +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Fa ndx +specifies the 0-based index of the attribute. +The total count of the attributes contained in the abbreviation +entry can be retrieved using the function +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Fa code +should point to a location which will hold a returned +attribute code. +.Pp +Argument +.Fa form +should point to a location which will hold the returned +form of the attribute. +.Pp +Argument +.Fa offset +should point to a location which will hold a returned offset, relative +to the +.Dq ".debug_abbrev" +section, for the specified attribute. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_entry +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if the attribute index specified by argument +.Fa ndx +is out of range. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To loop through all the attribute entries contained in the +abbreviation section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Abbrev ab; +Dwarf_Off aboff, atoff; +Dwarf_Signed form; +Dwarf_Half attr; +Dwarf_Unsigned length, attr_count; +Dwarf_Error de; +int i, ret; + +/* ...allocate 'dbg' using dwarf_init(3) ... */ + +while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, + NULL, NULL, &de)) == DW_DLV_OK) { + while ((ret = dwarf_get_abbrev(dbg, aboff, &ab, &length, + &attr_count, &de)) == DW_DLV_OK) { + if (length == 1) /* Last entry. */ + break; + aboff += length; + for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { + if (dwarf_get_abbrev_entry(ab, i, + &attr, &form, &atoff, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_entry failed:" + " %s", dwarf_errmsg(de)); + continue; + } + /* .. use the retrieved information ... */ + } + } + + if (ret != DW_DLV_OK) + warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); +} + +if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa abbrev , +.Fa code , +.Fa form +or +.Fa offset +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The attribute index specified by argument +.Fa ndx +was out of range. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 new file mode 100644 index 0000000000..15eb14bc90 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_abbrev_tag.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd March 13, 2011 +.Dt DWARF_GET_ABBREV_TAG 3 +.Os +.Sh NAME +.Nm dwarf_get_abbrev_tag +.Nd retrieve the tag for an abbreviation +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_tag +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Half *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_tag +retrieves the tag for the abbreviation entry descriptor referenced by +argument +.Fa abbrev . +.Pp +Argument +.Fa ret +should point to a location which will hold the returned +abbreviation tag. +.Pp +If argument +.Fa err +is not +.Dv NULL, +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_tag +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_tag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa abbrev +or +.Fa ret +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 b/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 new file mode 100644 index 0000000000..cb420c517a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 @@ -0,0 +1,85 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_address_size.3 3964 2022-03-13 21:41:26Z jkoshy $ +.\" +.Dd March 13, 2022 +.Dt DWARF_GET_ADDRESS_SIZE 3 +.Os +.Sh NAME +.Nm dwarf_get_address_size +.Nd return the number of bytes needed to represent an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_address_size +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half *addr_size" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_address_size +returns the size in bytes of a native address for a program object. +.Pp +Argument +.Fa dbg +should denote a DWARF debug context created from a program object using +.Xr dwarf_init 3 . +Argument +.Fa addr_size +should point to a location that will hold the returned size. +Argument +.Fa err , +if +.No non- Ns Dv NULL , +it will be used to return error information. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_address_size +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_address_size +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Fa dbg +or +.Fa addr_size +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_finish 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 new file mode 100644 index 0000000000..2126aa538a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_arange.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 16, 2011 +.Dt DWARF_GET_ARANGE 3 +.Os +.Sh NAME +.Nm dwarf_get_arange +.Nd retrieve the address range descriptor for an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange +.Fa "Dwarf_Arange *ar_list" +.Fa "Dwarf_Unsigned ar_cnt" +.Fa "Dwarf_Addr addr" +.Fa "Dwarf_Arange *ret_ar" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_arange +searches an array of +.Vt Dwarf_Arange +descriptors for one that covers a given address. +.Pp +Argument +.Fa ar_list +should point to an array of +.Vt Dwarf_Arange +descriptors. +.Pp +Argument +.Fa ar_cnt +specifies the number of +.Vt Dwarf_Arange +descriptors in the array pointed to by argument +.Fa ar_list . +.Pp +Argument +.Fa addr +specifies the address being looked up. +.Pp +Argument +.Fa ret_ar +will be used to store the +.Vt Dwarf_Arange +descriptor that covers the given address. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_arange +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Vt Dwarf_Arange +descriptor that covers the provided address. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_arange +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa ar_list +or +.Fa ret_ar +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +Value of argument +.Fa ar_cnt +equals to 0. +.It Bq Er DW_DLE_NO_ENTRY +A +.Vt Dwarf_Arange +descriptor that covers the given address +was not found. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_aranges 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 new file mode 100644 index 0000000000..2d94587471 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 @@ -0,0 +1,137 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_arange_info.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 16, 2011 +.Dt DWARF_GET_ARANGE_INFO 3 +.Os +.Sh NAME +.Nm dwarf_get_arange_info +.Nd extract address range information from a descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange_info +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Addr *start" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_arange_info +extracts address range information from a +.Vt Dwarf_Arange +descriptor. +.Pp +Argument +.Fa ar +should reference a valid +.Vt Dwarf_Arange +descriptor returned by function +.Xr dwarf_get_aranges 3 . +.Pp +Argument +.Fa start +should point to a location which will hold the start value of the +address range associated with the descriptor. +.Pp +Argument +.Fa length +should point to a location which will hold the length in bytes of the +address range associated with the descriptor. +.Pp +Argument +.Fa cu_die_offset +should point to a location which will be set to an offset, relative to +the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Fa ar . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_arange_info +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To loop through all the address lookup table entries, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Addr start; +Dwarf_Arange *aranges; +Dwarf_Off die_off; +Dwarf_Signed i, cnt; +Dwarf_Unsigned length; +Dwarf_Error de; + +if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_aranges: %s", + dwarf_errmsg(de)); +for (i = 0; i < cnt; i++) { + if (dwarf_get_arange_info(aranges[i], &start, &length, + &die_off, &de) != DW_DLV_OK) { + warnx("dwarf_get_arange_info: %s", + dwarf_errmsg(de)); + continue; + } + /* Do something with the returned information. */ +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_arange_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa ar , +.Fa start , +.Fa length +or +.Fa cu_die_offset +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_aranges 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 b/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 new file mode 100644 index 0000000000..2205d60198 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 @@ -0,0 +1,150 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_aranges.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_GET_ARANGES 3 +.Os +.Sh NAME +.Nm dwarf_get_aranges +.Nd retrieve program address space mappings +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_aranges +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Arange **ar_list" +.Fa "Dwarf_Signed *ar_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_get_aranges +retrieves address range information from the +.Dq ".debug_aranges" +DWARF section. +Information about address ranges is returned using opaque descriptors +of type +.Vt Dwarf_Arange , +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa ar_list +should point to a location which will be set to a pointer to an array +of +.Vt Dwarf_Arange +descriptors. +.Pp +Argument +.Fa ar_cnt +should point to a location which will be set to the number of +descriptors returned. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory area used for the array returned in argument +.Fa ar_list +is owned by +.Lb libdwarf . +Application code should not attempt to directly free this area. +Portable applications should instead use +.Xr dwarf_dealloc 3 +to indicate that the memory area may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_get_aranges +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Dq ".debug_aranges" +section associated with the specified debugging context. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To loop through all the address lookup table entries, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Addr start; +Dwarf_Arange *aranges; +Dwarf_Off die_off; +Dwarf_Signed i, cnt; +Dwarf_Unsigned length; +Dwarf_Error de; + +if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_aranges: %s", + dwarf_errmsg(de)); + +for (i = 0; i < cnt; i++) { + if (dwarf_get_arange_info(aranges[i], &start, &length, + &die_off, &de) != DW_DLV_OK) { + warnx("dwarf_get_arange_info: %s", + dwarf_errmsg(de)); + continue; + } + /* Do something with the returned information. */ +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_aranges +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa ar_list +or +.Fa ar_cnt +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The debugging context +.Fa dbg +did not contain a +.Dq ".debug_aranges" +string section. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 new file mode 100644 index 0000000000..08277d2bf5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_cie_index.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 22, 2011 +.Dt DWARF_GET_CIE_INDEX 3 +.Os +.Sh NAME +.Nm dwarf_get_cie_index +.Nd retrieve the index of a CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_index +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Signed *cie_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_index +retrieves the zero-based index of a given CIE descriptor in the array +of CIE descriptors returned by the functions +.Xr dwarf_get_fde_list 3 +and +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Fa cie +should reference a valid DWARF CIE descriptor. +.Pp +Argument +.Fa cie_index +should point to a location that will hold the returned index. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_index +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_index +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arugments +.Fa cie +or +.Fa cie_index +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 new file mode 100644 index 0000000000..017e72344e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 @@ -0,0 +1,152 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_cie_info.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 29, 2011 +.Dt DWARF_GET_CIE_INFO 3 +.Os +.Sh NAME +.Nm dwarf_get_cie_info +.Nd retrieve information associated with a CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_info +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Unsigned *cie_byte_len" +.Fa "Dwarf_Small *version" +.Fa "char **augmentation" +.Fa "Dwarf_Unsigned *caf" +.Fa "Dwarf_Unsigned *daf" +.Fa "Dwarf_Half *ra" +.Fa "Dwarf_Ptr *init_inst" +.Fa "Dwarf_Unsigned *inst_len" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_info +retrieves the information associated with a given CIE descriptor. +.Pp +Argument +.Fa cie +should reference a valid DWARF CIE descriptor, such as would be +returned by function +.Xr dwarf_get_cie_of_fde 3 . +.Pp +Argument +.Fa cie_byte_len +should point to a location that will hold the length in bytes of +the CIE descriptor itself. +.Pp +Argument +.Fa version +should point to a location that will hold the version number of +the CIE descriptor. +.Pp +Arugment +.Fa augmentation +should point to a location that will be set to a pointer to a +NUL-terminated string containing augmentation data encoded as UTF-8. +.Pp +Argument +.Fa caf +should point to a location that will hold the code alignment +factor recorded in the CIE descriptor. +.Pp +Arugment +.Fa daf +should point to a location that will hold the data alignment +factor recorded in the CIE descriptor. +.Pp +Argument +.Fa ra +should point to a location that will hold the return address +recorded in the CIE descriptor. +.Pp +Argument +.Fa init_inst +should point to a location that will be set to a pointer to an array +of bytes containing the initial instructions associated with the CIE +descriptor. +.Pp +Argument +.Fa inst_len +should point to a location that will hold the length in bytes +of the initial instructions returned in argument +.Fa init_inst . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_info +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa cie , +.Fa cie_byte_len , +.Fa version , +.Fa augmentation , +.Fa caf , +.Fa daf , +.Fa ra , +.Fa init_inst +or +.Fa inst_len +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 new file mode 100644 index 0000000000..143ade86c5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_cie_of_fde.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 22, 2011 +.Dt DWARF_GET_CIE_OF_FDE 3 +.Os +.Sh NAME +.Nm dwarf_get_cie_of_fde +.Nd retrieve CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_of_fde +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Cie *ret_cie" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_of_fde +retrieves the CIE descriptor associated with a given FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid FDE descriptor. +.Pp +Argument +.Fa ret_cie +should point to a location that will hold the returned CIE +descriptor. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_of_fde +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_of_fde +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arugments +.Fa fde +or +.Fa ret_cie +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 new file mode 100644 index 0000000000..c83b563cdf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_cu_die_offset.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd April 10, 2011 +.Dt DWARF_GET_CU_DIE_OFFSET 3 +.Os +.Sh NAME +.Nm dwarf_get_arange_cu_header_offset , +.Nm dwarf_get_cu_die_offset +.Nd retrieve compilation unit offsets +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange_cu_header_offset +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Off *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_cu_die_offset +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Off *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve the offsets, relative to the +.Dq ".debug_info" +DWARF section, of the debugging information entries describing the +compilation unit associated with a +.Vt Dwarf_Arange +descriptor. +.Pp +Function +.Fn dwarf_get_arange_cu_header_offset +retrieves the offset of the compilation unit header associated with +argument +.Fa ar , +and stores it in the location pointed to by argument +.Fa ret . +.Pp +Function +.Fn dwarf_get_cu_die_offset +retrieves the offset of the debugging information entry for the +compilation unit associated with argument +.Fa ar , +and stores it in the location pointed to by argument +.Fa ret . +.Pp +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa ar +was not a valid +.Vt Dwarf_Arange +descriptor. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa ret +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_aranges 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 new file mode 100644 index 0000000000..086bfbf01b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_die_infotypes_flag.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd December 20, 2014 +.Dt DWARF_GET_DIE_INFOTYPES_FLAG 3 +.Os +.Sh NAME +.Nm dwarf_get_die_infotypes_flag +.Nd indicate the originating DWARF section for a DIE +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Bool +.Fo dwarf_get_die_infotypes_flag +.Fa "Dwarf_Die die" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_die_infotypes_flag +returns a flag indicating the originating DWARF section for the +debugging information entry referenced by argument +.Fa die . +.Pp +Argument +.Fa die +should reference a valid debugging information entry descriptor. +.Sh RETURN VALUES +Function +.Fn dwarf_get_die_infotypes_flag +returns a non-zero value if argument +.Fa die +originates in the +.Dq .debug_info +section. +.Pp +It returns zero if argument +.Fa die +originates in the +.Dq .debug_types +section. +.Sh ERRORS +Function +.Fn dwarf_get_die_infotypes_flag +always succeeds. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_next_cu_header_c 3 , +.Xr dwarf_offdie_b 3 , +.Xr dwarf_siblingof_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 b/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 new file mode 100644 index 0000000000..f015012daf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_get_elf.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_GET_ELF 3 +.Os +.Sh NAME +.Nm dwarf_get_elf +.Nd retrieve the +.Vt Elf +descriptor associated with a +.Vt Dwarf_Debug +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_elf +.Fa "Dwarf_Debug dbg" +.Fa "Elf **elf" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_elf +returns the +.Vt Elf +descriptor associated with a +.Vt Dwarf_Debug +instance. +.Pp +Argument +.Fa dbg +should be a handle to a valid +.Vt Dwarf_Debug +instance returned by a prior call to +.Xr dwarf_init 3 +or +.Xr dwarf_elf_init 3 . +.Pp +Argument +.Fa elf +points a location into which a handle to an +.Vt Elf +descriptor will be written. +.Pp +Argument +.Fa err +is used to record error information in case of failure. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_elf +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh EXAMPLES +To retrieve the +.Vt Elf +instance associated with a +.Vt Dwarf_Debug +instance use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; +Elf *elf; + +\&... allocate dbg using dwarf_init() etc ... + +if (dwarf_get_elf(dbg, &elf, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_finish 3 , +.Xr dwarf_init 3 , +.Xr elf 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 new file mode 100644 index 0000000000..1abb418cd6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 @@ -0,0 +1,127 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_at_pc.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 22, 2011 +.Dt DWARF_GET_FDE_AT_PC 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_at_pc +.Nd retrieve the FDE descriptor for an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_at_pc +.Fa "Dwarf_Fde *fdelist" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Fde *ret_fde" +.Fa "Dwarf_Addr *lopc" +.Fa "Dwarf_Addr *hipc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_at_pc +searches the provided array of DWARF FDE descriptors for a descriptor +covering a given program counter address. +.Pp +Argument +.Fa fdelist +should point to an array of FDE descriptors, as returned by the functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Fa pc +should contain the program counter address being looked up. +.Pp +Argument +.Fa ret_fde +should point to a location that will hold the returned FDE descriptor. +.Pp +Argument +.Fa lopc +should point to a location that will be set to the lowest address +covered by the returned FDE descriptor. +.Pp +Argument +.Fa hipc +should point to a location that will be set to the highest address +covered by the returned FDE descriptor. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_at_pc +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if a FDE descriptor that covers the address specified by argument +.Fa pc +is not found. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_at_pc +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va fdelist , +.Va ret_fde , +.Va lopc , +or +.Va hipc +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +These was no FDE descriptor covering the address specified by argument +.Fa pc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 new file mode 100644 index 0000000000..a00a8cfe75 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 @@ -0,0 +1,158 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_info_for_all_regs.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 4, 2011 +.Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_info_for_all_regs +.Nd retrieve register rule row +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_all_regs +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Regtable *reg_table" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_all_regs +retrieves a row from the register rule table associated with the given +FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Fa pc +should hold the program counter address to be used to locate the +desired table row. +.Pp +Argument +.Fa reg_table +should point to a +.Vt Dwarf_Regtable +descriptor which will hold the returned table row of register rules. +.Pp +Argument +.Fa row_pc +should point to a location which will be set to the lowest program +counter address associated with the table row. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +The +.Vt Dwarf_Regtable +descriptor is defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct { + struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Half dw_regnum; + Dwarf_Addr dw_offset; + } rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable; +.Ed +.Pp +For each of the register rules returned, +the +.Va dw_offset_relevant +field is set to 1 if the register rule has a offset value. +The +.Va dw_regnum +field is set to the register number associated with the regsiter rule. +The +.Va dw_offset +field is set to the offset value associated with the register rule. +.Pp +The number of register columns returned is either the constant +value +.Dv DW_REG_TABLE_SIZE as defined +in the header file +.In libdwarf.h , +or the value set by function +.Xr dwarf_set_frame_rule_table_size 3 , +whichever is smaller. +.Ss COMPATIBILITY +Function +.Fn dwarf_get_fde_info_for_all_regs +is deprecated since it only supports DWARF2 frame sections. +Applications should instead use function +.Xr dwarf_get_fde_info_for_all_regs3 3 +which supports both DWARF2 and DWARF3 frame sections. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_all_regs +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_all_regs +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa fde , +.Fa reg_table +or +.Fa row_pc +was +.Dv NULL . +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Fa pc +did not fall in the range covered by argument +.Fa fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 new file mode 100644 index 0000000000..e521ec8c50 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 @@ -0,0 +1,185 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_info_for_all_regs3.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 26, 2011 +.Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS3 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_info_for_all_regs3 +.Nd retrieve register rule row +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_all_regs3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Regtable3 *reg_table" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_all_regs3 +retrieves a row from the register rule table associated with the given +FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Fa pc +should hold the program counter address to be used to locate the +desired table row. +.Pp +Argument +.Fa reg_table +should point to a +.Vt Dwarf_Regtable3 +descriptor which will hold the returned table row of register rules. +The +.Vt Dwarf_Regtable3 +descriptor is defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; +} Dwarf_Regtable_Entry3; + +typedef struct { + Dwarf_Regtable_Entry3 rt3_cfa_rule; + Dwarf_Half rt3_reg_table_size; + Dwarf_Regtable_Entry3 *rt3_rules; +} Dwarf_Regtable3; +.Ed +.Pp +The +.Va rt3_reg_table_size +field specifies the maximum number of register rule columns to be +returned, and should be set by the application before calling the +function. +The +.Va rt3_rules +field should point to a memory arena allocated by the application with +space for at least +.Vt rt3_reg_table_size +descriptors of type +.Vt Dwarf_Regtable_Entry3 . +.Pp +On a successful execution of this function, the +.Va rt3_cfa_rule +field will be set to the CFA register rule associated with the table +row, and the +.Va rt3_rules +array will hold the returned register rules contained in the table row. +.Pp +For each register rule descriptor returned, +the +.Va dw_offset_relevant +field will be set to 1 if the register rule has a offset value, +the +.Va dw_value_type +field will be set to the type code of the register rule and the +.Va dw_regnum +field will be set to the register number associated with the register rule. +If the register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the +.Va dw_offset_or_block_len +field will be set to the offset value associated with the register rule. +If the type is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the +.Va dw_offset_or_block_len +field will be set to the length in bytes of the DWARF expression block +associated with the register rule. +The +.Va dw_block_ptr +field will be set to a pointer to the content of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Fa row_pc +should point to a location which will be set to the lowest program +counter address associated with the table row. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_all_regs3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_all_regs3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa fde , +.Fa reg_table +or +.Fa row_pc +was +.Dv NULL . +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Fa pc +did not fall in the range covered by argument +.Fa fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 new file mode 100644 index 0000000000..e09d4b69e2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 @@ -0,0 +1,173 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_info_for_cfa_reg3.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 12, 2011 +.Dt DWARF_GET_FDE_INFO_FOR_CFA_REGS3 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_info_for_cfa_regs3 +.Nd retrieve a CFA register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_cfa_regs3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Small *type" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset_or_block_len" +.Fa "Dwarf_Ptr *block_ptr" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +retrieves the CFA register rule for a given program counter address +from the register rule table associated with an FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Fa pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_cfa_reg3 +stores information about the CFA register rule found into the locations +pointed to by the arguments +.Fa type , +.Fa offset_relevant , +.Fa register_num , +.Fa offset_or_block_len , +.Fa block_ptr +and +.Fa row_pc . +.Pp +Argument +.Fa type +should point to a location which will hold the type code of the +register rule found. +The returned value is one of the +.Dv DW_EXPR_* +contants defined in the header file +.In libdwarf.h . +.Pp +If there is an offset value associated with the CFA register rule, +the location pointed to by argument +.Fa offset_relevant +will be set to 1. +.Pp +Argument +.Fa register_num +should point to a location which will hold the register number associated +with the CFA register rule. +.Pp +If the CFA register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the location pointed to by argument +.Fa offset_or_block_len +will be set to the offset value associated with the register rule, +or to 0 if the register rule does not have an offset value. +If the type code is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the location pointed to by argument +.Fa offset_or_block_len +will be set to the length in bytes of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Fa block_ptr +should point to a location which will be set to a pointer to the +content of the DWARF expression block associated with the CFA register +rule. +.Pp +Argument +.Fa row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa block_ptr , +.Fa fde , +.Fa offset_or_block_len , +.Fa offset_relevant , +.Fa register_num , +.Fa row_pc , +or +.Fa type +was +.Dv NULL . +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Fa pc +did not fall in the range covered by argument +.Fa fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 new file mode 100644 index 0000000000..7a7b6e9e17 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 @@ -0,0 +1,158 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_info_for_reg.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd June 4, 2011 +.Dt DWARF_GET_FDE_INFO_FOR_REG 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_info_for_reg +.Nd retrieve register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_reg +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Half table_column" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_reg +retrieves a register rule from the register rule table associated with +a given FDE descriptor, given a program counter address and rule +column number. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Arugment +.Fa table_column +should hold the column number of the register rule desired. +.Pp +Argument +.Fa pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_reg +stores information about the register rule found into the locations +pointed to by the arguments +.Fa offset_relevant , +.Fa register_num , +.Fa offset +and +.Fa row_pc . +.Pp +If there is an offset value associated with the register rule, +the location pointed to by argument +.Fa offset_relevant +will be set to 1. +.Pp +Argument +.Fa register_num +should point to a location which will hold the register number associated +with the register rule. +.Pp +Argument +.Fa offset +should point to a location which will be set to the offset value +associated with the register rule, or to 0 if the register rule +does not have an offset value. +.Pp +Argument +.Fa row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Ss COMPATIBILITY +Function +.Fn dwarf_get_fde_info_for_reg +is deprecated since it only supports DWARF2 frame sections. +Applications should instead use function +.Xr dwarf_get_fde_info_for_reg3 3 +which supports both DWARF2 and DWARF3 frame sections. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_reg +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_reg +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa fde , +.Fa offset_relevant , +.Fa register_num , +.Fa offset +or +.Fa row_pc +was +.Dv NULL . +.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD +The column number provided in argument +.Fa table_column +was too large. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Fa pc +did not fall in the range covered by argument +.Fa fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 new file mode 100644 index 0000000000..440573503c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 @@ -0,0 +1,216 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_info_for_reg3.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_GET_FDE_INFO_FOR_REG3 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_info_for_reg3 +.Nd retrieve register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_reg3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Half table_column" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Small *type" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset_or_block_len" +.Fa "Dwarf_Ptr *block_ptr" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_reg3 +retrieves a register rule from the register rule table associated with +a given FDE descriptor, given a program counter address and rule +column number. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Arugment +.Fa table_column +should hold the column number of the register rule desired. +.Pp +Argument +.Fa pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_reg3 +stores information about the register rule found into the locations +pointed to by the arguments +.Fa type , +.Fa offset_relevant , +.Fa register_num , +.Fa offset_or_block_len , +.Fa block_ptr +and +.Fa row_pc . +.Pp +Argument +.Fa type +should point to a location which will hold the type code of the +register rule found. +The returned value is one of the +.Dv DW_EXPR_* +contants defined in the header file +.In libdwarf.h . +.Pp +If there is an offset value associated with the register rule, +the location pointed to by argument +.Fa offset_relevant +will be set to 1. +.Pp +Argument +.Fa register_num +should point to a location which will hold the register number associated +with the register rule. +.Pp +If the register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the location pointed to by argument +.Fa offset_or_block_len +will be set to the offset value associated with the register rule, +or to 0 if the register rule does not have an offset value. +If the type code is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the location pointed to by argument +.Fa offset_or_block_len +will be set to the length in bytes of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Fa block_ptr +should point to a location which will be set to a pointer to the +content of the DWARF expression block associated with the register +rule. +.Pp +Argument +.Fa row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_reg3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To retrieve the register rules at column 3 from a rule table +associated with a FDE descriptor: +.Bd -literal -offset indent +Dwarf_Fde fde; +Dwarf_Off fde_offset, cie_offset; +Dwarf_Unsigned func_len, fde_length; +Dwarf_Signed cie_index, offset_relevant, register_num; +Dwarf_Signed offset_or_block_len; +Dwarf_Addr low_pc, row_pc; +Dwarf_Ptr fde_addr, block_ptr; +Dwarf_Small type; +Dwarf_Error de; + +/* ... assuming `fde` references a valid FDE descriptor... */ +if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, + &fde_length, &cie_offset, &cie_index, &fde_offset, + &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_fde_range failed: %s", + dwarf_errmsg(de)); + +/* Iterate all the table rows. */ +for (pc = low_pc; pc < low_pc + func_len; pc++) { + if (dwarf_get_fde_info_for_reg3(fde, 3, pc, &type, + &offset_relevant, ®ister_num, &offset_or_block_len, + &block_ptr, &row_pc, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_info_for_reg3 failed: %s", + dwarf_errmsg(de)); + continue; + } + /* ... use the retrieved register rule ... */ +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_reg3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa block_ptr , +.Fa fde , +.Fa offset_or_block_len , +.Fa offset_relevant , +.Fa register_num , +.Fa row_pc , +or +.Fa type +was +.Dv NULL . +.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD +The column number provided in argument +.Fa table_column +was too large. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Fa pc +did not fall in the range covered by argument +.Fa fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 new file mode 100644 index 0000000000..28d6592c57 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_instr_bytes.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 23, 2011 +.Dt DWARF_GET_FDE_INSTR_BYTES 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_instr_bytes +.Nd retrieve instructions from FDE descritpor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_instr_bytes +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Ptr *ret_inst" +.Fa "Dwarf_Unsigned *ret_len" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_instr_bytes +retrieves instruction bytes from a given FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Fa ret_inst +should point to a location that will be set to a pointer +to an array of bytes containing the instructions of the +FDE descriptor. +.Pp +Argument +.Fa ret_len +should point to a location that will hold the length in +bytes of the instructions returned in argument +.Fa ret_inst . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Applications can use the function +.Xr dwarf_expand_frame_instructions 3 +to parse and expand the returned instruction bytes into an array of +.Vt Dwarf_Frame_Op +descriptors. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_instr_bytes +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_instr_bytes +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa fde , +.Fa ret_inst +or +.Fa ret_len +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_expand_frame_instructions 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 new file mode 100644 index 0000000000..af393b06e8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 @@ -0,0 +1,220 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_list.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_GET_FDE_LIST 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_list +.Nd retrieve frame information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_list +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie **cie_list" +.Fa "Dwarf_Signed *cie_count" +.Fa "Dwarf_Fde **fde_list" +.Fa "Dwarf_Signed *fde_count" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_fde_list_eh +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie **cie_list" +.Fa "Dwarf_Signed *cie_count" +.Fa "Dwarf_Fde **fde_list" +.Fa "Dwarf_Signed *fde_count" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve frame related information for the specified +DWARF debug context. +.Pp +Function +.Fn dwarf_get_fde_list +retrieves frame information from the DWARF section named +.Dq ".debug_frame" . +For objects containing GNU style C++ exception handling +information, the function +.Fn dwarf_get_fde_list_eh +retrieves frame information from the section named +.Dq ".eh_frame" . +.Pp +Frame information is returned using opaque descriptors +of type +.Vt Dwarf_Cie +and +.Vt Dwarf_Fde . +Applications need to use the other frame related functions in the +DWARF(3) API set to retrieve the information contained in these +descriptors. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa cie_list +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Cie +descriptors. +.Pp +Argument +.Fa cie_count +should point to a location that will be set to the number of +.Vt Dwarf_Cie +descriptors returned. +.Pp +Argument +.Fa fde_list +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Fde +descriptors. +.Pp +Argument +.Fa fde_count +should point to a location that will be set to the number of +.Vt Dwarf_Fde +descriptors returned. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory areas used for the arrays returned in arguments +.Fa cie_list +and +.Fa fde_list +are owned by the +.Lb libdwarf . +Application code should not attempt to directly free these areas. +Portable applications should instead use the +.Xr dwarf_fde_cie_list_dealloc 3 +function to indicate that these memory areas may be freed. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +They return +.Dv DW_DLV_NO_ENTRY +if there is no frame information associated with the given DWARF +debug context. +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh EXAMPLES +To obtain frame information from the +.Dq ".debug_frame" +section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Cie *cie_list, cie; +Dwarf_Fde *fde_list, fde; +Dwarf_Off fde_offset, cie_offset; +Dwarf_Unsigned func_len, fde_length, fde_instlen; +Dwarf_Signed cie_count, fde_count, cie_index; +Dwarf_Addr low_pc; +Dwarf_Ptr fde_addr, fde_inst, cie_inst; +Dwarf_Error de; +int i; + +if (dwarf_get_fde_list(dbg, &cie_list, &cie_count, + &fde_list, &fde_count, &de) != DW_DLV_OK) { + errx(EXIT_FAILURE, "dwarf_get_fde_list failed: %s", + dwarf_errmsg(de)); +} + +for (i = 0; i < fde_count; i++) { + if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, + &fde_length, &cie_offset, &cie_index, &fde_offset, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_range failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_instr_bytes failed: %s", + dwarf_errmsg(de)); + continue; + } + + /* ... Use the retrieved frame information ... */ +} + +/* Indicate that the returned arrays may be freed. */ +dwarf_fde_cie_list_dealloc(dbg, cie_list, cie_count, fde_list, + fde_count); +.Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va dbg , +.Va cie_list , +.Va cie_count , +.Va fde_list +or +.Va fde_count +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There is no frame information associated with the giving DWARF debug +context. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_fde_cie_list_dealloc 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 new file mode 100644 index 0000000000..9eff99563c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_n.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 14, 2011 +.Dt DWARF_GET_FDE_N 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_n +.Nd retrieve FDE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_n +.Fa "Dwarf_Fde *fdelist" +.Fa "Dwarf_Unsigned fde_index" +.Fa "Dwarf_Fde *ret_fde" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_n +retrieves an FDE descriptor from an array of FDE descriptors. +.Pp +Argument +.Fa fdelist +should point to an array of FDE descriptors, as returned by the functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Fa fde_index +specifies the 0-based index of the desired FDE descriptor. +.Pp +Argument +.Fa ret_fde +should point to a location that will hold the returned FDE descriptor. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_n +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if the FDE descriptor index specified by argument +.Fa fde_index +is out of range. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_n +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Fa fdelist +or +.Fa ret_fde +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The FDE descriptor index specified by argument +.Fa fde_index +was out of range. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 new file mode 100644 index 0000000000..26d5947f12 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 @@ -0,0 +1,151 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_fde_range.3 3962 2022-03-12 15:56:10Z jkoshy $ +.\" +.Dd May 22, 2011 +.Dt DWARF_GET_FDE_RANGE 3 +.Os +.Sh NAME +.Nm dwarf_get_fde_range +.Nd retrieve range information from an FDE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_range +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr *low_pc" +.Fa "Dwarf_Unsigned *func_len" +.Fa "Dwarf_Ptr *fde_bytes" +.Fa "Dwarf_Unsigned *fde_byte_len" +.Fa "Dwarf_Off *cie_offset" +.Fa "Dwarf_Signed *cie_index" +.Fa "Dwarf_Off *fde_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_range +retrieves range and offset information from a given FDE descriptor. +.Pp +Argument +.Fa fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Fa low_pc +should point to a location that will be set to the lowest +program counter address covered by the FDE descriptor. +.Pp +Argument +.Fa func_len +should point to a location that will hold the length in bytes of +the address range covered by the FDE descriptor. +.Pp +Argument +.Fa fde_bytes +should point to a location that will be set to a pointer to the +content of the FDE descriptor itself. +.Pp +Argument +.Fa fde_byte_len +should point to a location that will hold the length in bytes of +the FDE descriptor itself. +.Pp +Argument +.Fa cie_offset +should point to a location that will be set to the offset, relative to +the DWARF +.Dq ".debug_frame" +section, of the CIE descriptor associated with the given FDE +descriptor. +.Pp +Argument +.Fa cie_index +should point to a location that will hold the index of the CIE +descriptor associated with the FDE descriptor. +The returned value is a zero-based index into the array of CIE +descriptors returned by a prior call to functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Fa fde_offset +should point to a location that will be set to the offset, relative to +the DWARF +.Dq ".debug_frame" +section, of the FDE descriptor. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_range +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_range +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa fde , +.Fa low_pc , +.Fa func_len , +.Fa fde_bytes , +.Fa fde_byte_len , +.Fa cie_offset , +.Fa cie_index +or +.Fa fde_offset +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 b/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 new file mode 100644 index 0000000000..89e3bf19d0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_form_class.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd June 26, 2011 +.Dt DWARF_GET_FORM_CLASS 3 +.Os +.Sh NAME +.Nm dwarf_get_form_class +.Nd retrieve the form class of an attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft enum Dwarf_Form_Class +.Fo dwarf_get_form_class +.Fa "Dwarf_Half dwversion" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Half offset_size" +.Fa "Dwarf_Half form" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_form_class +returns the class of the form of a DWARF attribute. +.Pp +Argument +.Fa dwversion +should specify the version number of DWARF specification +to use: 2 for DWARF2, 3 for DWARF3 and 4 for DWARF4. +.Pp +Argument +.Fa attr +should hold the attribute code of the attribute, i.e., one of the +.Li DW_AT_* +values defined in +.In libdwarf.h . +.Pp +Argument +.Fa offset_size +should hold the size of a DWARF offset for the relevant compilation +unit. +.Pp +Argument +.Fa form +should hold the form code of the attribute. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_form_class +returns the form class code, which is one of the +.Dv DW_FORM_CLASS_* +contants defined in header file +.In libdwarf.h . +If the function was not able to determine the form class of the +attribute, it returns the special form class code +.Dv DW_FORM_CLASS_UNKNOWN . +.Sh ERRORS +Function +.Fn dwarf_get_form_class +does not return an error. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 b/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 new file mode 100644 index 0000000000..b0c38b982f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 @@ -0,0 +1,217 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_funcs.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 10, 2011 +.Dt DWARF_GET_FUNCS 3 +.Os +.Sh NAME +.Nm dwarf_get_funcs , +.Nm dwarf_func_cu_offset , +.Nm dwarf_func_die_offset , +.Nm dwarf_func_name_offsets , +.Nm dwarf_funcname +.Nd retrieve information about static functions +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_funcs +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Func **funcs" +.Fa "Dwarf_Signed *nfuncs" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_cu_offset +.Fa "Dwarf_Func func" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_die_offset +.Fa "Dwarf_Func func" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_name_offsets +.Fa "Dwarf_Func func" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_funcname +.Fa "Dwarf_Func func" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about static functions from the +lookup tables in the (SGI-specific) +.Dq ".debug_funcnames" +section. +Information about these functions is returned using opaque descriptors +of type +.Vt Dwarf_Func . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_funcs +retrieves descriptors for all the static functions associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa funcs +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Func +descriptors. +The argument +.Fa nfuncs +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_func_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Fa func . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_func_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Fa func , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_func_name_offsets +retrieves the name and offsets for the debugging information entry for +argument +.Fa func . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Fa func . +.Pp +Function +.Fn dwarf_funcname +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa func . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Func +descriptors returned in argument +.Fa funcs +by function +.Fn dwarf_get_funcs +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_funcs_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_func_name_offsets +and +.Fn dwarf_funcname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va func , +.Va funcs , +.Va name , +or +.Va nfuncs +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Fa dbg +did not contain information about static functions. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_funcs_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 b/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 new file mode 100644 index 0000000000..96eb06c87c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 @@ -0,0 +1,214 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_globals.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 2, 2011 +.Dt DWARF_GET_GLOBALS 3 +.Os +.Sh NAME +.Nm dwarf_get_globals , +.Nm dwarf_global_cu_offset , +.Nm dwarf_global_die_offset , +.Nm dwarf_global_name_offsets , +.Nm dwarf_globname +.Nd retrieve information about global objects +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_globals +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Global **globals" +.Fa "Dwarf_Signed *nglobals" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_cu_offset +.Fa "Dwarf_Global global" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_die_offset +.Fa "Dwarf_Global global" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_name_offsets +.Fa "Dwarf_Global global" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_globname +.Fa "Dwarf_Global global" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about global symbols from the +lookup tables in the +.Dq ".debug_pubnames" +DWARF section. +Information about these global symbols is returned using opaque descriptors +of type +.Vt Dwarf_Global . +Applications need to use the functions described below to retrieve the +name and the offsets for these descriptors. +.Pp +Function +.Fn dwarf_get_globals +retrieves descriptors for all the global symbols associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa globals +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Global +descriptors. +The argument +.Fa nglobals +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_global_cu_offset +returns the section-relative offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Fa global . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_global_die_offset +retrieves the section-relative offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Fa global , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_global_name_offsets +retrieves the name and the offsets for the debugging information +entry for argument +.Fa global . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to a section-relative +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to a +section-relative offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in +the compilation unit associated with argument +.Fa global . +.Pp +Function +.Fn dwarf_globname +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa global . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Global +descriptors returned in argument +.Fa globals +by function +.Fn dwarf_get_globals +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_globals_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_globname +and +.Fn dwarf_global_name_offsets +is owned by the +.Lb libdwarf . +Portable code should use the +.Xr dwarf_dealloc 3 +function to indicate that the memory area may be freed. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va global , +.Va globals , +.Va name , +or +.Va nglobals +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_globals_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 new file mode 100644 index 0000000000..7026471b15 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 @@ -0,0 +1,158 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_loclist_entry.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd July 6, 2011 +.Dt DWARF_GET_LOCLIST_ENTRY 3 +.Os +.Sh NAME +.Nm dwarf_get_loclist_entry +.Nd retrieve DWARF location list entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_loclist_entry +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned offset" +.Fa "Dwarf_Addr *hipc" +.Fa "Dwarf_Addr *lopc" +.Fa "Dwarf_Ptr *data" +.Fa "Dwarf_Unsigned *entry_len" +.Fa "Dwarf_Unsigned *next_entry" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_loclist_entry +retrieves a location list entry from the DWARF section +.Dq ".debug_loc" . +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa offset +is an offset, relative to the +.Dq ".debug_loc" +section, to the start of the desired location list entry. +.Pp +Argument +.Fa hipc +should point to a location which will hold the offset, relative to the +base address of the location list entry, of the highest program +counter value for the entry. +.Pp +Argument +.Fa lowpc +should point to a location which will hold the offset, relative to the +base address of the location list entry, of the lowest program counter +value for the entry. +.Pp +Argument +.Fa data +should point to a location which will be set to a pointer to the location +list data. +.Pp +Argument +.Fa entry_len +should point to a location which will hold the length in bytes of the +location list data returned in argument +.Fa data . +.Pp +Argument +.Fa next_entry +should point to a location which will hold the offset of the next +location list entry. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_loclist_entry +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no location list at the specified offset +.Fa offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To iterate through all the location list entries in the +.Dq ".debug_loc" +section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Unsigned off, len, next; +Dwarf_Addr hipc, lopc; +Dwarf_Ptr data; +Dwarf_Error de; +int ret; + +off = 0; +while ((ret = dwarf_get_loclist_entry(dbg, off, &hipc, &lopc, &data, + &len, &next, &de)) == DW_DLV_OK) { + /* ... use loclist entry ... */ + off = next; +} +if (ret == DW_DLV_ERROR) + warnx("dwarf_get_loclist_entry failed: %s", dwarf_errmsg(de)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_loclist_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa hipc , +.Fa lopc , +.Fa data , +.Fa entry_len +or +.Fa next_entry +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There is no location list at the specified offset +.Fa offset . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_loclist 3 , +.Xr dwarf_loclist_from_expr 3 , +.Xr dwarf_loclist_from_expr_a 3 , +.Xr dwarf_loclist_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 b/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 new file mode 100644 index 0000000000..c8e5772109 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 @@ -0,0 +1,196 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_macro_details.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd March 20, 2011 +.Dt DWARF_GET_MACRO_DETAILS 3 +.Os +.Sh NAME +.Nm dwarf_get_macro_details +.Nd retrieve macro information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_macro_details +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Unsigned max_count" +.Fa "Dwarf_Signed *entry_cnt" +.Fa "Dwarf_Macro_Details **details" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_macro_details +retrieves information about macros associated with a DWARF debug +context. +Information about macro entries are returned as an array of +descriptors of type +.Vt Dwarf_Macro_Details , +with each +.Vt Dwarf_Macro_Details +descriptor describing one macro information entry. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Fa offset +is an offset, relative to the +.Dq ".debug_macinfo" +section, to the start of the desired macro information. +Argument +.Fa max_count +specifies the maximum number of macro information entries +to be returned, or 0 if all entries are to be returned. +Argument +.Fa entry_cnt +should point to a location that will be set to the number +of entries actually returned. +Argument +.Fa details +should point to a location that will be set to a pointer to +an array of +.Vt Dwarf_Macro_Details +descriptors. +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +.Vt Dwarf_Macro_Details +descriptors are defined in the header file +.In libdwarf.h , +and consist of the following fields: +.Bl -tag -width ".Va dmd_fileindex" -compact +.It Va dmd_offset +The section-relative offset within the +.Dq ".debug_macinfo" +section of the macro information entry being described. +.It Va dmd_type +The type code of this macro information entry; one of the +.Dv DW_MACINFO_* +constants defined by the DWARF specification. +.It Va dmd_lineno +The line number associated with the macro information +entry, or 0 if there is no applicable line number. +.It Va dmd_fileindex +The source file index for the macro information entry. +This field is only meaningful when +.Va dmd_type +field is set to +.Dv DW_MACINFO_start_file . +.It Va dmd_macro +The contents of this field is a pointer to a NUL-terminated string +whose meaning depends on the value of the +.Va dmd_type +field: +.Bl -tag -width ".Dv DW_MACINFO_vendor_ext" -compact +.It Dv DW_MACINFO_define +The returned string contains the macro name and value. +.It Dv DW_MACINFO_undef +The string holds the macro name. +.It Dv DW_MACINFO_vendor_ext +The +.Va dmd_macro +field points to a vendor defined string. +.El +The field is +.Dv NULL +for other values of +.Va dmd_type . +.El +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Macro_Details +descriptors returned in argument +.Fa details +is owned by the +.Lb libdwarf . +The application should not attempt to directly free this pointer. +Portable code should instead use +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_STRING +to indicate that the memory may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_get_macro_details +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no more macro information at the specified offset +.Fa offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To loop through all the macro information entries associated with +a DWARF debug context: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Unsigned offset; +Dwarf_Signed cnt; +Dwarf_Macro_Details *md; +Dwarf_Error de; + +offset = 0; +while (dwarf_get_macro_details(dbg, offset, 0, + &cnt, &md, &de) == DW_DLV_OK) { + for (i = 0; i < cnt; i++) { + /* Access fields of md[i] ... */ + } + offset = md[cnt - 1].dmd_offset + 1; +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_macro_details +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa entry_cnt +or +.Fa details +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There is no more macro information at the specified offset +.Fa offset . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_find_macro_value_start 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 new file mode 100644 index 0000000000..4550b04418 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 @@ -0,0 +1,246 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_pubtypes.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 4, 2011 +.Dt DWARF_GET_PUBTYPES 3 +.Os +.Sh NAME +.Nm dwarf_get_pubtypes , +.Nm dwarf_pubtype_cu_offset , +.Nm dwarf_pubtype_die_offset , +.Nm dwarf_pubtype_name_offsets , +.Nm dwarf_pubtypename +.Nd retrieve information about user-defined types +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_pubtypes +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type **types" +.Fa "Dwarf_Signed *ntypes" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_cu_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_die_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_name_offsets +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtypename +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about file-scope, user-defined +types recorded in lookup tables in the +.Dq ".debug_pubtypes" +DWARF section. +Information about these types is returned using opaque descriptors +of type +.Vt Dwarf_Type . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_pubtypes +retrieves descriptors for all the user-defined types associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa types +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Type +descriptors. +The argument +.Fa ntypes +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_pubtype_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Fa type . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_pubtype_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Fa type , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_pubtype_name_offsets +retrieves the name and offsets for the debugging information entry for +argument +.Fa type . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Fa type . +.Pp +Function +.Fn dwarf_pubtypename +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa type . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Type +descriptors returned in argument +.Fa types +by function +.Fn dwarf_get_pubtypes +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_types_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_pubtype_name_offsets +and +.Fn dwarf_pubtypename +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh EXAMPLES +To retrieve the list of file scope user-defined types and print +their names, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Signed ntypes; +Dwarf_Type *types; +Dwarf_Error err; +int n, result; +char *typename; + +/* Initialize dbg etc. */; +result = dwarf_get_pubtypes(dbg, &types, &ntypes, &err); +if (result != DW_DLV_OK) /* Handle the error. */ + ; + +/* Iterate over the returned array of descriptors. */ +for (n = 0; n < ntypes; n++) { + result = dwarf_pubtypename(types[n], &typename, &err); + if (result != DW_DLV_OK) /* Handle the error. */ + ; + printf("%s\en", typename); +} + +/* Deallocate the returned array. */ +dwarf_types_dealloc(dbg, types, ntypes); +.Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va type , +.Va types , +.Va name , +or +.Va ntypes +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Fa dbg +did not contain information about user-defined types. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_pubtypes_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 b/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 new file mode 100644 index 0000000000..43609a9e54 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 @@ -0,0 +1,262 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_ranges.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_GET_RANGES 3 +.Os +.Sh NAME +.Nm dwarf_get_ranges +.Nd retrieve non-contiguous address ranges +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_ranges +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Ranges **ranges" +.Fa "Dwarf_Signed *cnt" +.Fa "Dwarf_Unsigned *byte_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_ranges_a +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die die" +.Fa "Dwarf_Ranges **ranges" +.Fa "Dwarf_Signed *cnt" +.Fa "Dwarf_Unsigned *byte_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_ranges +retrieves information about the non-contiguous address ranges associated +with a DWARF debugging information entry. +Information about address ranges is returned as an array of +descriptors of type +.Vt Dwarf_Ranges , +with each +.Vt Dwarf_Ranges +descriptor describing one address range entry. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa offset +is an offset, relative to the +.Dq ".debug_ranges" +section, to the start of the desired list of address ranges. +The offset of an address ranges list is indicated by the +.Dv DW_AT_ranges +attribute of a debugging information entry. +.Pp +Argument +.Fa die +(function +.Fn dwarf_get_ranges_a +only) is ignored in this implementation; see the section +.Sx "Compatibility Notes" +below. +.Pp +Argument +.Fa ranges +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Ranges +descriptors. +.Pp +Argument +.Fa cnt +should point to a location that will be set to the number of entries +returned. +If argument +.Fa byte_cnt +is not +.Dv NULL , +it will be set to the number of bytes occupied by the +returned entries in the +.Dq ".debug_ranges" +section. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +.Vt Dwarf_Ranges +descriptors are defined in the header file +.In libdwarf.h , +and consists of the following fields: +.Bl -tag -width ".Va dwr_addr1" +.It Va dwr_addr1 +The first address offset, whose meaning depends on the type of the +entry. +.It Va dwr_addr2 +The second address offset, whose meaning depends on the type of the +entry. +.It Va dwr_type +The type of this address range entry: +.Bl -tag -width ".Dv DW_RANGES_ENTRY" -compact +.It Dv DW_RANGES_ENTRY +A range list entry. +For this type of entry, the fields +.Va dwr_addr1 +and +.Va dwr_addr2 +hold the beginning and ending offsets of the address range, respectively. +.It Dv DW_RANGES_ADDRESS_SELECTION +A base address selection entry. +For this type of entry, the field +.Va dwr_addr1 +is the value of the largest representable address offset, and +.Va dwr_addr2 +is a base address for the beginning and ending address offsets of +subsequent address range entries in the list. +.It Dv DW_RANGES_END +An end of list mark. +Both +.Va dwr_addr1 +and +.Va dwr_addr2 +are set to 0. +.El +.El +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Ranges +descriptors returned in argument +.Fa ranges +is owned by the +.Lb libdwarf . +The application should not attempt to directly free this pointer. +Portable code should instead use +.Fn dwarf_ranges_dealloc +to indicate that the memory may be freed. +.Sh RETURN VALUES +These functions +return +.Dv DW_DLV_OK +when they succeed. +They return +.Dv DW_DLV_NO_ENTRY +if there is no address range list at the specified offset +.Fa offset . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh EXAMPLES +To retrieve the address range list associated with a debugging +information entry, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Die die; +Dwarf_Error de; +Dwarf_Addr base; +Dwarf_Attribute *attr_list; +Dwarf_Ranges *ranges; +Dwarf_Signed cnt; +Dwarf_Unsigned off, attr_count, bytecnt; +int i, j; + +if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_attrlist failed: %s", + dwarf_errmsg(de)); + +for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { + if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { + warnx("dwarf_whatattr failed: %s", + dwarf_errmsg(de)); + continue; + } + if (attr != DW_AT_ranges) + continue; + if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_ranges(dbg, (Dwarf_Off) off, &ranges, &cnt, + &bytecnt, &de) != DW_DLV_OK) + continue; + for (j = 0; j < cnt; j++) { + if (ranges[j].dwr_type == DW_RANGES_END) + break; + else if (ranges[j].dwr_type == + DW_RANGES_ADDRESS_SELECTION) + base = ranges[j].dwr_addr2; + else { + /* + * DW_RANGES_ENTRY entry. + * .. Use dwr_addr1 and dwr_addr2 .. + */ + } + } +} +.Ed +.Sh COMPATIBILITY +Function +.Fn dwarf_get_ranges_a +is identical to +.Fn dwarf_get_ranges , +except that it requires one additional argument +.Fa die +denoting the debugging information entry associated with +the address range list. +In this implementation of the +.Lb libdwarf , +the argument +.Fa die +is ignored, and function +.Fn dwarf_get_ranges_a +is only provided for compatibility with other implementations of the +DWARF(3) API. +.Sh ERRORS +These function can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa ranges +or +.Fa cnt +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There is no address range list at the specified offset +.Fa offset . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_ranges_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 new file mode 100644 index 0000000000..48382b0322 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 @@ -0,0 +1,230 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_relocation_info.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 3, 2011 +.Dt DWARF_GET_RELOCATION_INFO 3 +.Os +.Sh NAME +.Nm dwarf_get_relocation_info +.Nd retrieve generated relocation arrays +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_relocation_info +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Signed *elf_section_index" +.Fa "Dwarf_Signed *elf_section_link" +.Fa "Dwarf_Unsigned *reloc_entry_count" +.Fa "Dwarf_Relocation_Data *reloc_buf" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_get_relocation_info +is used to retrieve the relocation arrays generated by a prior call to +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Each call to this function retrieves the next available relocation +array. +Application code should call this function repeatly to retrieve all +the relocation arrays. +The total number of generated relocation arrays retrievable +by this function may be obtained by calling function +.Xr dwarf_get_relocation_info_count 3 . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 in sequence. +or +.Xr dwarf_producer_init_b 3 . +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the DWARF producer instance. +.Pp +Argument +.Fa elf_section_index +should point to a location which will be set to the ELF section index +of the relocation section to which the retrieved relocation array +belongs. +.Pp +Argument +.Fa elf_section_link +should point to a location which will be set to the section index of +the ELF section to which the retrieved relocation array applies. +.Pp +Argument +.Fa reloc_entry_count +should point to a location which will be set to the total number of +relocation entries contained in the relocation array. +.Pp +Argument +.Fa reloc_buf +should point to a location which will be set to a pointer to the +retrieved array of relocation entries. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +The retrieved relocation entries are described using structure +.Vt Dwarf_Relocation_Data_s , +defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct Dwarf_Relocation_Data_s { + unsigned char drd_type; + unsigned char drd_length; + Dwarf_Unsigned drd_offset; + Dwarf_Unsigned drd_symbol_index; +} *Dwarf_Relocation_Data; +.Ed +.Pp +Struct +.Vt Dwarf_Relocation_Data_s +consists of following fields: +.Bl -tag -width ".Va drd_symbol_index" -compact -offset indent +.It Va drd_type +The type code of the relocation entry. +The +.Vt Dwarf_Rel_Type +enumeration defined in the header file +.In libdwarf.h +specifies legal values for this field. +.It Va drd_length +The size in bytes of the field to be relocated. +.It Va drd_offset +The section-relative offset of the field to be relocated. +.It Va drd_symbol_index +The symbol index associated with the relocation entry. +.El +.Ss Memory Management +The memory area used for the relocation arrays is managed by the +.Lb libdwarf . +The function +.Fn dwarf_producer_finish +may be used to release it, along with other resources associated +with the producer instance. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_relocation_info +returns +.Dv DW_DLV_OK . +It returns +.Dv DW_DLV_NO_ENTRY +if there were no more relocation arrays to retrieve, or if the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +In case of an error, function +.Fn dwarf_get_relocation_info +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To generate relocation entries and retrieve them, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Relocation_Data buf; +Dwarf_Signed count, index, link; +Dwarf_Unsigned reloc_cnt, entry_cnt; +Dwarf_Error de; +int version, i, j; + +/* + * Assume that dbg refers to a DWARF producer instance created + * created with DW_DLC_SYMBOLIC_RELOCATIONS flag set and that + * application code has added DWARF debugging information + * to the producer instance. + */ +if ((count = dwarf_transform_to_disk_form(dbg, &de)) == + DW_DLV_NOCOUNT) { + warnx("dwarf_transform_to_disk_form failed: %s", + dwarf_errmsg(-1)); + return; +} + +/* ... process generated section byte streams ... */ +if (dwarf_get_relocation_info_count(dbg, &reloc_cnt, &version, &de) != + DW_DLV_OK) { + warnx("dwarf_get_relocation_info_count failed: %s", + dwarf_errmsg(-1)); + return; +} + +for (i = 0; (Dwarf_Unsigned) i < reloc_cnt; i++) { + if (dwarf_get_relocation_info(dbg, &index, &link, &entry_cnt, + &buf, &de) != DW_DLV_OK) { + warnx("dwarf_get_relocation_info failed: %s", + dwarf_errmsg(-1)); + continue; + } + for (j = 0; (Dwarf_Unsigned) j < entry_cnt; j++) { + /* ...use each reloc data in buf[j]... */ + } +} + +dwarf_producer_finish(dbg, &de); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_relocation_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa elf_section_index , +.Fa elf_section_link , +.Fa reloc_entry_count +or +.Fa reloc_buf +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF relocation arrays to retrieve. +.It Bq Er DW_DLE_NO_ENTRY +The flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.It Bq Er DW_DLE_NO_ENTRY +Function +.Xr dwarf_transform_to_disk_form 3 +was not called prior to calling function +.Fn dwarf_get_relocation_info . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info_count 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_reset_section_bytes 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 new file mode 100644 index 0000000000..de8fc3af5a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_relocation_info_count.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 3, 2011 +.Dt DWARF_GET_RELOCATION_INFO_COUNT 3 +.Os +.Sh NAME +.Nm dwarf_get_relocation_info_count +.Nd return the number of relocation arrays +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_relocation_info_count +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned *reloc_cnt" +.Fa "int *drd_buffer_version" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_relocation_info_count +retrieves the total number of relocation arrays generated by a prior +call to +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the producer instance. +.Pp +Argument +.Fa reloc_cnt +should point to a location which will be set to the total number of +relocation arrays generated. +.Pp +Argument +.Fa drd_buffer_version +should point to a location which will be set to the version number +of the relocation structures returned (see the symbol +.Dv DWARF_DRD_BUFFER_VERSION , +defined in the header file +.In libdwarf.h ) . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_relocation_info_count +returns +.Dv DW_DLV_OK . +It returns +.Dv DW_DLV_NO_ENTRY +if the +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag is not set on the producer instance. +In case of an error, function +.Fn dwarf_get_relocation_info_count +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_get_relocation_info_count +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa reloc_cnt +or +.Fa drd_buffer_version +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag was not set. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 new file mode 100644 index 0000000000..12f1e7a02a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 @@ -0,0 +1,161 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_section_bytes.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd August 26, 2011 +.Dt DWARF_GET_SECTION_BYTES 3 +.Os +.Sh NAME +.Nm dwarf_get_section_bytes +.Nd retrieve ELF section byte streams +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Ptr +.Fo dwarf_get_section_bytes +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Signed dwarf_section" +.Fa "Dwarf_Signed *elf_section_index" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_section_bytes +returns the ELF section byte streams generated by a prior call +to function +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Each call to function +.Fn dwarf_get_section_bytes +will return the byte stream for one ELF section. +The first call to this function will always return the first ELF +section, and the subsequent calls will return the rest of sections +in the order when they were generated, until the last one. +The total number of sections generated is returned by the function +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using the +functions +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa dwarf_section +is currently ignored. +.Pp +Argument +.Fa elf_section_index +should point to a location which will be set to the section index value +of the returned ELF section. +.Pp +Argument +.Fa length +should point to a location which will hold the length in bytes of the +returned ELF section. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory areas used for the returned ELF section byte streams should +be freed using the function +.Fn dwarf_producer_finish . +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_section_bytes +returns a pointer to a ELF section byte stream. +In case of an error, function +.Fn dwarf_get_section_bytes +will return +.Dv NULL +and set the argument +.Fa err . +.Sh EXAMPLES +To generate and retrieve ELF section byte streams, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Signed count, i, sec_index; +Dwarf_Unsigned len; +Dwarf_Ptr bytes; +Dwarf_Error de; + +/* ... Assume that `dbg' refers to a DWARF producer instance, + * and that application code has added DWARF debugging + * information to the producer instance. ... + */ +if ((count = dwarf_transform_to_disk_form(dbg, &de)) == + DW_DLV_NOCOUNT) { + warnx("dwarf_transform_to_disk_form failed: %s", + dwarf_errmsg(-1)); + return; +} + +/* Retrieve section data. */ +for (i = 0; i < count; i++) { + bytes = dwarf_get_section_bytes(dbg, i, &sec_index, &len, + &de); + if (bytes == NULL) { + warnx("dwarf_get_section_bytes failed: %s", + dwarf_errmsg(-1)); + continue; + } + /* ... use the returned byte stream ... */ +} + +/* Release resources. */ +dwarf_producer_finish(dbg, &de); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_section_bytes +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa elf_section_index , +or +.Fa length +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF sections to retrieve, or the function was +called before a call to +.Xr dwarf_transform_to_disk_form 3 . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_reset_section_bytes 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 b/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 new file mode 100644 index 0000000000..c2d0c512ef --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_section_max_offsets.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd December 21, 2014 +.Dt DWARF_GET_SECTION_MAX_OFFSETS 3 +.Os +.Sh NAME +.Nm dwarf_get_section_max_offsets , +.Nm dwarf_get_section_max_offsets_b +.Nd return the size of DWARF sections +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_section_max_offsets +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fc +.Ft int +.Fo dwarf_get_section_max_offsets_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fa "Dwarf_Unsigned *debug_types" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_section_max_offsets_b +retrieves the sizes of the DWARF sections in a DWARF debug context. +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +The function stores the size of each DWARF section to the location +pointed to by the argument corresponding to the section name. +If a DWARF section does not exist, the location pointed to by the +argument corresponding to that section will be set to zero. +.Pp +A value of +.Dv NULL +may be used for any of the arguments +.Fa debug_info , +.Fa debug_abbrev , +.Fa debug_line , +.Fa debug_loc , +.Fa debug_aranges , +.Fa debug_macinfo , +.Fa debug_pubnames , +.Fa debug_str , +.Fa debug_frame , +.Fa debug_ranges , +.Fa debug_pubtypes +and +.Fa debug_types +if the caller is not interested in the respective section size. +.Pp +Function +.Fn dwarf_get_section_max_offsets +is identical to function +.Fn dwarf_get_section_max_offsets_b +except that it does not provide argument +.Fa debug_types , +and thus cannot return the size of the +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +If argument +.Fa dbg +is +.Dv NULL , +they return +.Dv DW_DLV_ERROR . +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_str.3 b/contrib/elftoolchain/libdwarf/dwarf_get_str.3 new file mode 100644 index 0000000000..21992bcfa1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_str.3 @@ -0,0 +1,151 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_str.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 3, 2011 +.Dt DWARF_GET_STR 3 +.Os +.Sh NAME +.Nm dwarf_get_str +.Nd retrieve a string from the DWARF string section +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_str +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "char **string" +.Fa "Dwarf_Signed *len" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_str +retrieves a NUL-terminated string from the DWARF string section +.Dq ".debug_str" . +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa offset +should be an offset, relative to the +.Dq ".debug_str" +section, specifying the start of the desired string. +.Pp +Argument +.Fa string +should point to a location which will hold a returned +pointer to a NUL-terminated string. +.Pp +Argument +.Fa len +should point to a location which will hold the length +of the returned string. +The returned length does not include the space needed for +the NUL-terminator. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_str +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Dq ".debug_str" +section associated with the specified debugging context, +or if the provided offset +.Fa offset +is at the very end of +.Dq ".debug_str" +section. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To retrieve all the strings in the DWARF string section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Off offset; +Dwarf_Signed len; +Dwarf_Error de; +char *str; +int ret + +offset = 0; +while ((ret = dwarf_get_str(dbg, offset, &str, &len, &de)) == + DW_DLV_OK) { + /* .. Use the retrieved string. .. */ + offset += len + 1; /* Account for the terminating NUL. */ +} + +if (ret == DW_DLV_ERROR) + warnx("dwarf_get_str: %s", dwarf_errmsg(de)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_get_str +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa dbg , +.Fa string +or +.Fa len +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa offset +was out of range. +.It Bq Er DW_DLE_NO_ENTRY +The debugging context +.Fa dbg +did not contain a +.Dq ".debug_str" +string section. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa offset +was at the very end of the +.Dq ".debug_str" +section. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_types.3 b/contrib/elftoolchain/libdwarf/dwarf_get_types.3 new file mode 100644 index 0000000000..53f6f9d942 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_types.3 @@ -0,0 +1,235 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_types.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 10, 2011 +.Dt DWARF_GET_TYPES 3 +.Os +.Sh NAME +.Nm dwarf_get_types , +.Nm dwarf_type_cu_offset , +.Nm dwarf_type_die_offset , +.Nm dwarf_type_name_offsets , +.Nm dwarf_typename +.Nd retrieve information about user-defined types +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_types +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type **types" +.Fa "Dwarf_Signed *ntypes" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_cu_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_die_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_name_offsets +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_typename +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These APIs retrieve information about user-defined types from the +SGI-specific +.Dq ".debug_typenames" +section. +.Pp +Standards-conformant applications should use the functions +.Xr dwarf_get_pubtypes 3 , +.Xr dwarf_pubtype_cu_offset 3 , +.Xr dwarf_pubtype_die_offset 3 , +.Xr dwarf_pubtype_name_offsets 3 +and +.Xr dwarf_pubtypename 3 , +which operate on the equivalent +.Dq ".debug_pubtypes" +section defined by the DWARF3 standard. +.Pp +Information about user-defined types is returned using opaque descriptors +of type +.Vt Dwarf_Type . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_types +retrieves descriptors for all user-defined types associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa types +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Type +descriptors. +The argument +.Fa ntypes +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_type_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Fa type . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_type_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Fa type , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_type_name_offsets +retrieves the name and offsets for the debugging information +entry for argument +.Fa type . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to a offset, relative to +the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Fa type . +.Pp +Function +.Fn dwarf_typename +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa type . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Type +descriptors returned in argument +.Fa types +by function +.Fn dwarf_get_types +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_types_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_type_name_offsets +and +.Fn dwarf_typename +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va type , +.Va types , +.Va name , +or +.Va ntypes +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Fa dbg +did not contain information about user-defined types. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_get_pubtypes 3 , +.Xr dwarf_pubtype_cu_offset 3 , +.Xr dwarf_pubtype_die_offset 3 , +.Xr dwarf_pubtype_name_offsets 3 , +.Xr dwarf_pubtypename 3 , +.Xr dwarf_types_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 b/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 new file mode 100644 index 0000000000..606d9c64a7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 @@ -0,0 +1,213 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_vars.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 2, 2011 +.Dt DWARF_GET_VARS 3 +.Os +.Sh NAME +.Nm dwarf_get_vars , +.Nm dwarf_var_cu_offset , +.Nm dwarf_var_die_offset , +.Nm dwarf_var_name_offsets , +.Nm dwarf_varname +.Nd retrieve information about static variables +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_vars +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Var **vars" +.Fa "Dwarf_Signed *nvars" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_cu_offset +.Fa "Dwarf_Var var" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_die_offset +.Fa "Dwarf_Var var" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_name_offsets +.Fa "Dwarf_Var var" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_varname +.Fa "Dwarf_Var var" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about the file scope static +variables associated with a DWARF debug context. +Information about these static variables is returned using opaque +descriptors of type +.Vt Dwarf_Var . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_vars +retrieves descriptors for all the static variables associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa vars +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Var +descriptors. +The argument +.Fa nvars +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_var_cu_offset +returns the section-relative offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that +contains the debugging information entry associated with the argument +.Fa var . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_var_die_offset +retrieves the section-relative offset, relative to the +.Dq ".debug_info" +section, of the debugging information +entry associated with the argument +.Fa var , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_var_name_offsets +retrieves both the name and the associated offsets for the debugging +information entry for argument +.Fa var . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to a section-relative +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to a +section-relative offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in +the compilation unit associated with argument +.Fa var . +.Pp +Function +.Fn dwarf_varname +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa var . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Var +descriptors returned in argument +.Fa vars +by function +.Fn dwarf_get_vars +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_vars_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_var_name_offsets +and +.Fn dwarf_varname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va var , +.Va vars , +.Va name , +or +.Va nvars +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_vars_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 b/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 new file mode 100644 index 0000000000..aa8e66acdf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 @@ -0,0 +1,218 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_weaks.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 10, 2011 +.Dt DWARF_GET_WEAKS 3 +.Os +.Sh NAME +.Nm dwarf_get_weaks , +.Nm dwarf_weak_cu_offset , +.Nm dwarf_weak_die_offset , +.Nm dwarf_weak_name_offsets , +.Nm dwarf_weakname +.Nd retrieve information about weak symbols +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_weaks +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Weak **weaks" +.Fa "Dwarf_Signed *nweaks" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_cu_offset +.Fa "Dwarf_Weak weak" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_die_offset +.Fa "Dwarf_Weak weak" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_name_offsets +.Fa "Dwarf_Weak weak" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weakname +.Fa "Dwarf_Weak weak" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about weak symbols from the +lookup tables in the (SGI-specific) +.Dq ".debug_weaknames" +section. +Information about weak symbols is returned using opaque descriptors +of type +.Vt Dwarf_Weak . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_weaks +retrieves descriptors for all the weak symbols associated with the +DWARF debug context specified by argument +.Fa dbg . +The argument +.Fa weaks +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Weak +descriptors. +The argument +.Fa nweaks +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_weak_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Fa weak . +Argument +.Fa cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_weak_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Fa weak , +and stores it into the location pointed to by the argument +.Fa die_offset . +.Pp +Function +.Fn dwarf_weak_name_offsets +retrieves the name and offsets for the debugging information +entry for argument +.Fa weak . +Argument +.Fa name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Fa die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Fa cu_die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Fa weak . +.Pp +Function +.Fn dwarf_weakname +sets the location pointed to by argument +.Fa name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Fa weak . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Weak +descriptors returned in argument +.Fa weaks +by function +.Fn dwarf_get_weaks +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_weaks_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Fa name +argument to functions +.Fn dwarf_weak_name_offsets +and +.Fn dwarf_weakname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Fa err +is not +.Dv NULL , +these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va weak , +.Va weaks , +.Va name , +or +.Va nweaks +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Fa dbg +did not contain information about weak symbols. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_weaks_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 new file mode 100644 index 0000000000..c5dba3eb71 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_hasattr.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 17, 2010 +.Dt DWARF_HASATTR 3 +.Os +.Sh NAME +.Nm dwarf_hasattr +.Nd check for the presence of an attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_hasattr +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Bool *ret_bool" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_hasattr +tests whether the debugging information entry referenced in argument +.Fa die +contains the attribute named by argument +.Fa attr . +Legal values for argument +.Fa attr +are those denoted by the +.Dv DW_AT_* +constants in the DWARF specification. +.Pp +If the named attribute is present in the debugging information entry, +function +.Fn dwarf_hasattr +returns a non-zero value in the location pointed to by argument +.Fa ret_bool . +If the named attribute is not present, a zero is written instead. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_hasattr +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_hasattr +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of argument +.Va die +or +.Va ret_bool +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_whatattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasform.3 b/contrib/elftoolchain/libdwarf/dwarf_hasform.3 new file mode 100644 index 0000000000..660f3e4b2f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_hasform.3 @@ -0,0 +1,131 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_hasform.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd May 22, 2010 +.Dt DWARF_HASFORM 3 +.Os +.Sh NAME +.Nm dwarf_hasform , +.Nm dwarf_whatform , +.Nm dwarf_whatform_direct +.Nd query attribute forms +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_hasform +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half form" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_whatform +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retform" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_whatform_direct +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retform" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_hasform +indicates whether the DWARF attribute denoted by argument +.Fa attr +has the attribute form specified by argument +.Fa form . +If the attribute has the specified form, then +argument +.Fa ret +is set to a non-zero value, otherwise it is set to zero. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_whatform +sets the location specified by argument +.Fa retform +to the attribute form code for the DWARF attribute referenced +by argument +.Fa attr . +If the attribute referenced by argument +.Fa attr +has an indirect form attribute, this function will return the final +form for the attribute. +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_whatform_direct +sets the location specified by argument +.Fa retform +to the attribute form code for the DWARF attribute referenced +by argument +.Fa attr . +If the form is an indirect form, the function sets the location +specified by argument +.Fa retform +to +.Dv DW_FORM_indirect . +If argument +.Fa err +is +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, these functions return +.Dv DW_DLV_ERR +and set argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Any of the arguments +.Fa attr , +.Fa ret , +or +.Fa retform +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_highpc.3 b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 new file mode 100644 index 0000000000..de89732bb4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 @@ -0,0 +1,197 @@ +.\" Copyright (c) 2010,2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_highpc.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd July 22, 2014 +.Dt DWARF_HIGHPC 3 +.Os +.Sh NAME +.Nm dwarf_arrayorder , +.Nm dwarf_bitoffset , +.Nm dwarf_bitsize , +.Nm dwarf_bytesize , +.Nm dwarf_highpc , +.Nm dwarf_highpc_b , +.Nm dwarf_lowpc , +.Nm dwarf_srclang +.Nd retrieve the value of a DWARF attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_arrayorder +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_order" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bitoffset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bitsize +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bytesize +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_highpc +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_highpc" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_highpc_b +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_highpc" +.Fa "Dwarf_Half *ret_form" +.Fa "enum Dwarf_Form_Class *ret_class" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lowpc +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_lowpc" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_srclang +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_lang" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These convenience functions are used to retrieve DWARF attribute +values associated with a Debugging Information Entry (DIE) descriptor +denoted by argument +.Fa die . +These functions store the value of the requested attribute into the +location pointed to by their second argument, provided that the requested +attribute exists in the debugging information entry. +.Pp +The list of functions and the DWARF attribute that they retrieve are: +.Pp +.Bl -tag -width ".Fn dwarf_arrayorder" -compact +.It Fn dwarf_arrayorder +Retrieve the +.Dv DW_AT_ordering +attribute value. +.It Fn dwarf_bitoffset +Retrieve the +.Dv DW_AT_bit_offset +attribute value. +.It Fn dwarf_bitsize +Retrieve the +.Dv DW_AT_bit_size +attribute value. +.It Fn dwarf_bytesize +Retrieve the +.Dv DW_AT_byte_size +attribute value. +.It Fn dwarf_highpc +Retrieve the +.Dv DW_AT_high_pc +attribute value. +.It Fn dwarf_highpc_b +Retrieve the +.Dv DW_AT_high_pc +attribute value. +.It Fn dwarf_lowpc +Retrieve the +.Dv DW_AT_low_pc +attribute value. +.It Fn dwarf_srclang +Retrieve the +.Dv DW_AT_language +attribute value. +.El +.Pp +Function +.Fn dwarf_highpc_b +is an enhanced version of function +.Fn dwarf_highpc . +It sets the location specified by argument +.Fa ret_form +to the form code of the attribute +.Dv DW_AT_high_pc , +and sets the location specified by argument +.Fa ret_class +to the class of that form. +A value of +.Dv NULL +may be used for either of the arguments +.Fa ret_form +or +.Fa ret_class +if the caller is not interested in the respective value. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Fa die +does not contain the requested attribute, these functions return +.Dv DW_DLV_NO_ENTRY +and set argument +.Fa err . +For other errors, they return +.Dv DW_DLV_ERROR +and set argument +.Fa err . +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Fa die , +.Fa ret_highpc , +.Fa ret_lowpc , +.Fa ret_size , +.Fa ret_lang +or +.Fa ret_order +were +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Fa die +had no requested attribute. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_attrlist 3 , +.Xr dwarf_get_form_class 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_init.3 b/contrib/elftoolchain/libdwarf/dwarf_init.3 new file mode 100644 index 0000000000..95c1ca33a9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_init.3 @@ -0,0 +1,178 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_init.3 3964 2022-03-13 21:41:26Z jkoshy $ +.\" +.Dd March 13, 2022 +.Dt DWARF_INIT 3 +.Os +.Sh NAME +.Nm dwarf_init , +.Nm dwarf_elf_init +.Nd allocate a DWARF debug descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_init +.Fa "int fd" +.Fa "int mode" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_elf_init +.Fa "Elf *elf" +.Fa "int mode" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions allocate and return a +.Vt Dwarf_Debug +instance for the object denoted by argument +.Fa fd +or +.Fa elf . +This instance would be used for subsequent access to debugging information in the object by other functions in the DWARF(3) library. +.Pp +For function +.Fn dwarf_init , +argument +.Fa fd +denotes an open file descriptor referencing a compilation object. +Function +.Fn dwarf_init +implicitly allocates an +.Vt Elf +descriptor for argument +.Fa fd . +.Pp +For function +.Fn dwarf_elf_init , +argument +.Fa elf +denotes a descriptor returned by +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +.Pp +Argument +.Fa mode +specifies the access mode desired. +It should be at least as permissive as the mode with which +the file descriptor +.Fa fd +or the ELF descriptor +.Fa elf +was created with. +Legal values for argument +.Fa mode +are: +.Pp +.Bl -tag -width "DW_DLC_WRITE" -compact +.It DW_DLC_RDWR +Permit reading and writing of DWARF information. +.It DW_DLC_READ +Operate in read-only mode. +.It DW_DLC_WRITE +Permit writing of DWARF information. +.El +.Pp +Argument +.Fa errhand +denotes a function to be called in case of an error. +If this argument is +.Dv NULL +then a default error handling scheme is used. +See +.Xr dwarf 3 +for a description of the error handling scheme used by the +DWARF(3) library. +.Pp +Argument +.Fa errarg +is passed to the error handler function denoted by argument +.Fa errhand +when it is invoked. +.Pp +Argument +.Fa ret +points to the memory location that will hold a +.Vt Dwarf_Debug +reference on a successful call these functions. +.Pp +Argument +.Fa err +references a memory location that would hold a +.Vt Dwarf_Error +descriptor in case of an error. +.Ss Memory Management +The +.Vt Dwarf_Debug +instance returned by these functions should be freed using +.Fn dwarf_finish . +.Sh IMPLEMENTATION NOTES +The current implementation does not support access modes +.Dv DW_DLC_RDWR +and +.Dv DW_DLC_WRITE . +.Sh RETURN VALUES +These functions return the following values: +.Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" +.It Bq Er DW_DLV_OK +This return value indicates a successful return. +.It Bq Er DW_DLV_ERROR +The operation failed. +.It Bq Er DW_DLV_NO_ENTRY +The object specified by arguments +.Fa "fd" +or +.Fa "elf" +did not contain debug information. +.El +.Sh EXAMPLES +To initialize a +.Vt Dwarf_Debug +instance from a open file descriptor referencing an ELF object, and +with the default error handler, use: +.Bd -literal -offset indent +Dwarf_Error err; +Dwarf_Debug dbg; + +if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &err) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(err)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_finish 3 , +.Xr dwarf_get_elf 3 , +.Xr elf_begin 3 , +.Xr elf_memory 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_init.c b/contrib/elftoolchain/libdwarf/dwarf_init.c new file mode 100644 index 0000000000..16ec53c573 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_init.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_init.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_elf_init(Elf *elf, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg, + Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int ret; + + if (elf == NULL || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (mode != DW_DLC_READ) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) != + DW_DLE_NONE) { + _dwarf_elf_deinit(dbg); + free(dbg); + if (ret == DW_DLE_DEBUG_INFO_NULL) + return (DW_DLV_NO_ENTRY); + else + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} + +int +dwarf_get_elf(Dwarf_Debug dbg, Elf **elf, Dwarf_Error *error) +{ + Dwarf_Elf_Object *e; + + if (dbg == NULL || elf == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + e = dbg->dbg_iface->object; + *elf = e->eo_elf; + + return (DW_DLV_OK); +} + +int +dwarf_init(int fd, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg, + Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Elf *elf; + int ret; + + if (fd < 0 || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (mode != DW_DLC_READ) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (elf_version(EV_CURRENT) == EV_NONE) { + DWARF_SET_ELF_ERROR(NULL, error); + return (DW_DLV_ERROR); + } + + if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + DWARF_SET_ELF_ERROR(NULL, error); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) != + DW_DLE_NONE) { + _dwarf_elf_deinit(dbg); + free(dbg); + if (ret == DW_DLE_DEBUG_INFO_NULL) + return (DW_DLV_NO_ENTRY); + else + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} + +int +dwarf_object_init(Dwarf_Obj_Access_Interface *iface, Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + if (iface == NULL || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_READ, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + dbg->dbg_iface = iface; + + if (_dwarf_init(dbg, 0, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_lineno.3 b/contrib/elftoolchain/libdwarf/dwarf_lineno.3 new file mode 100644 index 0000000000..2d08a036a8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lineno.3 @@ -0,0 +1,204 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_lineno.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd February 5, 2011 +.Dt DWARF_LINENO 3 +.Os +.Sh NAME +.Nm dwarf_lineaddr , +.Nm dwarf_linebeginstatement , +.Nm dwarf_lineblock , +.Nm dwarf_lineendsequence , +.Nm dwarf_lineno , +.Nm dwarf_lineoff , +.Nm dwarf_linesrc , +.Nm dwarf_line_srcfileno +.Nd retrieve information associated with a DWARF line descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_lineaddr +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Addr *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_linebeginstatement +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineblock +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineendsequence +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineno +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineoff +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_linesrc +.Fa "Dwarf_Line ln" +.Fa "char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_line_srcfileno +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve specific line information associated with +the line descriptor specified by argument +.Fa ln , +and stores it in the location pointed to by argument +.Fa ret . +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_lineaddr +stores the program address corresponding to the source line specified +in argument +.Fa ln +into the location pointed to by argument +.Fa ret . +.Pp +Function +.Fn dwarf_linebeginstatement +sets the location pointed to by argument +.Fa ret +to 1 if the source line specified by the line descriptor +.Fa ln +is the beginning of a statement, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineblock +sets the location pointed to by argument +.Fa ret +to 1 if the source line specified by the line descriptor +.Fa ln +is the beginning of a basic block, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineendsequence +sets the location pointed to by argument +.Fa ret +to 1 if the program address associated with the line descriptor +.Fa ln +is the address immediately following the end of a sequence of target +machine instructions, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineno +stores the line number of the source line associated with the line +descriptor +.Fa ln +into the location pointed to by argument +.Fa ret . +.Pp +Function +.Fn dwarf_lineoff +stores the column number within a line associated with descriptor +.Fa ln +into the location pointed to by argument +.Fa ret . +The retrieved column numbers are 1-based, with the value -1 indicating +that column number information was not available. +.Pp +Function +.Fn dwarf_linesrc +stores a pointer to a NUL-terminated string containing the source file +name associated with line descriptor +.Fa ln +into the location pointed to by argument +.Fa ret . +The full path of the source file is returned if possible. +The memory used for the source file name string is managed by the DWARF(3) +library and should not be directly freed by application code. +Instead, portable code should use +.Xr dwarf_dealloc 3 +to indicate that the string should be freed. +.Pp +Function +.Fn dwarf_line_srcfileno +stores the index of the source file associated with the line descriptor +.Fa ln +in the location pointed to by argument +.Fa ret . +The returned value is 1-based index into the array of source file +names returned by +.Xr dwarf_srcfiles 3 . +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_LINE_FILE_NUM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Va ln +or +.Va ret +was +.Dv NULL . +.It Bq Er DW_DLE_LINE_FILE_NUM_BAD +The source file name associated with the line descriptor +.Fa ln +could not be retrieved by function +.Fn dwarf_linesrc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_srcfiles 3 , +.Xr dwarf_srclines 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_lineno.c b/contrib/elftoolchain/libdwarf/dwarf_lineno.c new file mode 100644 index 0000000000..cbcc9aeaa6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lineno.c @@ -0,0 +1,294 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 $"); + +int +dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Debug dbg; + Dwarf_Line ln; + Dwarf_CU cu; + Dwarf_Attribute at; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || linebuf == NULL || linecount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + cu = die->die_cu; + if (cu->cu_lineinfo == NULL) { + if (_dwarf_lineno_init(die, at->u[0].u64, error) != + DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (cu->cu_lineinfo == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + li = cu->cu_lineinfo; + *linecount = (Dwarf_Signed) li->li_lnlen; + + if (*linecount == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (li->li_lnarray != NULL) { + *linebuf = li->li_lnarray; + return (DW_DLV_OK); + } + + if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist); + i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next)) + li->li_lnarray[i] = ln; + + *linebuf = li->li_lnarray; + + return (DW_DLV_OK); +} + +int +dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + Dwarf_Debug dbg; + Dwarf_CU cu; + Dwarf_Attribute at; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || srcfiles == NULL || srccount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + cu = die->die_cu; + if (cu->cu_lineinfo == NULL) { + if (_dwarf_lineno_init(die, at->u[0].u64, error) != + DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (cu->cu_lineinfo == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + li = cu->cu_lineinfo; + *srccount = (Dwarf_Signed) li->li_lflen; + + if (*srccount == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (li->li_lfnarray != NULL) { + *srcfiles = li->li_lfnarray; + return (DW_DLV_OK); + } + + if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, lf = STAILQ_FIRST(&li->li_lflist); + i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) { + if (lf->lf_fullpath) + li->li_lfnarray[i] = lf->lf_fullpath; + else + li->li_lfnarray[i] = lf->lf_fname; + } + + *srcfiles = li->li_lfnarray; + + return (DW_DLV_OK); +} + +int +dwarf_linebeginstatement(Dwarf_Line ln, Dwarf_Bool *ret_bool, + Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_stmt; + + return (DW_DLV_OK); +} + +int +dwarf_lineendsequence(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_endseq; + + return (DW_DLV_OK); +} + +int +dwarf_lineno(Dwarf_Line ln, Dwarf_Unsigned *ret_lineno, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineno == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_lineno = ln->ln_lineno; + + return (DW_DLV_OK); +} + +int +dwarf_line_srcfileno(Dwarf_Line ln, Dwarf_Unsigned *ret_fileno, + Dwarf_Error *error) +{ + + if (ln == NULL || ret_fileno == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_fileno = ln->ln_fileno; + + return (DW_DLV_OK); +} + +int +dwarf_lineaddr(Dwarf_Line ln, Dwarf_Addr *ret_lineaddr, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineaddr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_lineaddr = ln->ln_addr; + + return (DW_DLV_OK); +} + +int +dwarf_lineoff(Dwarf_Line ln, Dwarf_Signed *ret_lineoff, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineoff == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (ln->ln_column == 0) + *ret_lineoff = -1; + else + *ret_lineoff = (Dwarf_Signed) ln->ln_column; + + return (DW_DLV_OK); +} + +int +dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + int i; + + if (ln == NULL || ret_linesrc == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + li = ln->ln_li; + assert(li != NULL); + + for (i = 1, lf = STAILQ_FIRST(&li->li_lflist); + (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL; + i++, lf = STAILQ_NEXT(lf, lf_next)) + ; + + if (lf == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD); + return (DW_DLV_ERROR); + } + + if (lf->lf_fullpath) { + *ret_linesrc = (char *) lf->lf_fullpath; + return (DW_DLV_OK); + } + + *ret_linesrc = lf->lf_fname; + + return (DW_DLV_OK); +} + +int +dwarf_lineblock(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_bblock; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 b/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 new file mode 100644 index 0000000000..8cc456a1c6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_lne_end_sequence.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 15, 2011 +.Dt DWARF_LNE_END_SEQUENCE 3 +.Os +.Sh NAME +.Nm dwarf_lne_end_sequence +.Nd set the end of instruction sequence +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_lne_end_sequence +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr addr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_lne_end_sequence +sets the address that indicates the end of a sequence of target machine +instructions. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa addr +specifies an address value which is the first byte after the end of a +instruction sequence. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_lne_end_sequence +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_lne_end_sequence +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_lne_end_sequence +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The value in argument +.Fa addr +overlapped an existing line information entry. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 b/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 new file mode 100644 index 0000000000..6aecc0faaf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 @@ -0,0 +1,107 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_lne_set_address.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 14, 2011 +.Dt DWARF_LNE_SET_ADDRESS 3 +.Os +.Sh NAME +.Nm dwarf_lne_set_address +.Nd set the base address for line number information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_lne_set_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr off" +.Fa "Dwarf_Unsigned symndx" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_lne_set_address +sets the base address used by subsequent invocations of the +.Xr dwarf_add_line_entry 3 +function. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa off +specifies a relocatable program address. +.Pp +Argument +.Fa symndx +specifies the index of the ELF symbol to be used for relocation. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_lne_set_address +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_lne_set_address +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_lne_set_address +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The argument +.Fa symndx +had an illegal value. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist.3 b/contrib/elftoolchain/libdwarf/dwarf_loclist.3 new file mode 100644 index 0000000000..b2aaaa1d1c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist.3 @@ -0,0 +1,233 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_loclist.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_LOCLIST 3 +.Os +.Sh NAME +.Nm dwarf_loclist , +.Nm dwarf_loclist_n +.Nd retrieve DWARF location expression information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_loclist +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc +.Ft int +.Fo dwarf_loclist_n +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Locdesc ***llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +These functions retrieve the location expressions +associated with a DWARF attribute. +.Pp +Note: function +.Fn dwarf_loclist +is deprecated. +New application code should instead use function +.Fn dwarf_loclist_n +.Pp +Function +.Fn dwarf_loclist_n +retrieves the list of location expressions associated with a DWARF +attribute. +Argument +.Fa at +should reference a valid DWARF attribute. +Argument +.Fa llbuf +should point to a location which will hold a returned array of +pointers to +.Vt Dwarf_Locdesc +descriptors. +Argument +.Fa listlen +should point to a location which will be set to the number of +elements contained in the returned array. +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_loclist +retrieves the first location expression associated with an attribute. +Argument +.Fa at +should reference a valid DWARF attribute. +Argument +.Fa llbuf +should point to a location which will hold the returned pointer +to a +.Vt Dwarf_Locdesc +descriptor. +Argument +.Fa listlen +should point to a location which will be always set to 1. +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +.Vt Dwarf_Locdesc +descriptors are defined in the header file +.In libdwarf.h , +and consist of following fields: +.Pp +.Bl -tag -width ".Va ld_cents" -compact +.It Va ld_lopc +The lowest program counter address covered by the descriptor. +This field will be set to 0 if the descriptor is not associated with +an address range. +.It Va ld_hipc +The highest program counter address covered by the descriptor. +This field will be set to 0 if the descriptor is not associated with +an address range. +.It Va ld_cents +The number of entries returned in +.Va ld_s +field. +.It Va ld_s +Pointer to an array of +.Vt Dwarf_Loc +descriptors. +.El +.Pp +Each +.Vt Dwarf_Loc +descriptor represents one operation of a location expression. +These descriptors are defined in the header file +.In libdwarf.h , +and consist of following fields: +.Pp +.Bl -tag -width ".Va lr_number2" -compact +.It Va lr_atom +The operator name, one of the +.Dv DW_OP_* +constants defined in the header file +.In dwarf.h . +.It Va lr_number +The first operand of this operation. +.It Va lr_number2 +The second operand of this operation. +.It Va lr_offset +The byte offset of this operation within the containing location +expression. +.El +.Ss Memory Management +The memory area used for the descriptor array returned in argument +.Fa llbuf +is allocated by the +.Lb libdwarf . +When the descriptor array is no longer needed, application code should +use function +.Xr dwarf_dealloc 3 +to free the memory area in the following manner: +.Bl -enum +.It +First, the +.Fa ld_s +field of each +.Vt Dwarf_Locdesc +descriptor should be deallocated using the allocation type +.Dv DW_DLA_LOC_BLOCK . +.It +Then, the application should free each +.Vt Dwarf_Locdesc +descriptor using the allocation type +.Dv DW_DLA_LOCDESC . +.It +Finally, the +.Va llbuf +pointer should be deallocated using the allocation type +.Dv DW_DLA_LIST . +.El +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh EXAMPLES +To retrieve the location list associated with an attribute, use: +.Bd -literal -offset indent +Dwarf_Attribute at; +Dwarf_Locdesc **llbuf; +Dwarf_Signed lcnt; +Dwarf_Loc *lr; +Dwarf_Error de; +int i; + +if (dwarf_loclist_n(at, &llbuf, &lcnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_loclist_n failed: %s", + dwarf_errmsg(de)); + +for (i = 0; i < lcnt; i++) { + /* ... Use llbuf[i] ... */ + for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { + lr = &llbuf[i]->ld_s[j]; + /* ... Use each Dwarf_Loc descriptor ... */ + } + dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); +} +dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); +.Ed +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa at , +.Fa llbuf +or +.Fa listlen +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The attribute provided by argument +.Fa at +does not contain a location expression or is not associated with a +location expression list. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_loclist_entry 3 , +.Xr dwarf_loclist_from_expr 3 , +.Xr dwarf_loclist_from_expr_a 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist.c b/contrib/elftoolchain/libdwarf/dwarf_loclist.c new file mode 100644 index 0000000000..e780a87128 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist.c @@ -0,0 +1,302 @@ +/*- + * Copyright (c) 2009,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_loclist.c 3066 2014-06-06 19:36:06Z kaiwang27 $"); + +static int +copy_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *dst, Dwarf_Locdesc *src, + Dwarf_Error *error) +{ + + assert(src != NULL && dst != NULL); + + dst->ld_lopc = src->ld_lopc; + dst->ld_hipc = src->ld_hipc; + dst->ld_cents = src->ld_cents; + + if (dst->ld_cents > 0) { + dst->ld_s = calloc(dst->ld_cents, sizeof(Dwarf_Loc)); + if (dst->ld_s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(dst->ld_s, src->ld_s, src->ld_cents * + sizeof(Dwarf_Loc)); + } else + dst->ld_s = NULL; + + return (DW_DLE_NONE); +} + +int +dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int ret; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_attrib) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + switch (at->at_form) { + case DW_FORM_data4: + case DW_FORM_data8: + /* + * DW_FORM_data[48] can not be used as section offset + * since DWARF4. For DWARF[23], the application needs + * to determine if DW_FORM_data[48] is representing + * a constant or a section offset. + */ + if (at->at_die->die_cu->cu_version >= 4) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + /* FALLTHROUGH */ + case DW_FORM_sec_offset: + ret = _dwarf_loclist_find(dbg, at->at_die->die_cu, + at->u[0].u64, llbuf, listlen, NULL, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, ret); + return (DW_DLV_NO_ENTRY); + } + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_exprloc: + if (at->at_ld == NULL) { + ret = _dwarf_loc_add(at->at_die, at, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + *llbuf = calloc(1, sizeof(Dwarf_Locdesc *)); + if (*llbuf == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + (*llbuf)[0] = calloc(1, sizeof(Dwarf_Locdesc)); + if ((*llbuf)[0] == NULL) { + free(*llbuf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + if (copy_locdesc(dbg, (*llbuf)[0], at->at_ld, error) != + DW_DLE_NONE) { + free((*llbuf)[0]); + free(*llbuf); + return (DW_DLV_ERROR); + } + *listlen = 1; + return (DW_DLV_OK); + default: + /* Malformed Attr? */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_NO_ENTRY); + } + default: + /* Wrong attr supplied. */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } +} + +int +dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Locdesc **_llbuf; + int i, ret; + + ret = dwarf_loclist_n(at, &_llbuf, listlen, error); + if (ret != DW_DLV_OK) + return (ret); + + /* Only return the first location description of the list. */ + *llbuf = _llbuf[0]; + + /* Free the rest of the list. */ + for (i = 1; i < *listlen; i++) { + if (_llbuf[i]->ld_s) + free(_llbuf[i]->ld_s); + free(_llbuf[i]); + } + free(_llbuf); + + *listlen = 1; + + return (DW_DLV_OK); +} + +int +dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, + Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data, + Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, + Dwarf_Error *error) +{ + Dwarf_Locdesc *ld, **llbuf; + Dwarf_Section *ds; + Dwarf_Signed listlen; + int i, ret; + + /* + * Note that this API sometimes will not work correctly because + * it assumes that all units have the same pointer size and offset + * size. + */ + + if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL || + entry_len == NULL || next_entry == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, + &llbuf, &listlen, entry_len, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *hipc = *lopc = 0; + for (i = 0; i < listlen; i++) { + ld = llbuf[i]; + if (i == 0) { + *hipc = ld->ld_hipc; + *lopc = ld->ld_lopc; + } else { + if (ld->ld_lopc < *lopc) + *lopc = ld->ld_lopc; + if (ld->ld_hipc > *hipc) + *hipc = ld->ld_hipc; + } + } + + ds = _dwarf_find_section(dbg, ".debug_loc"); + assert(ds != NULL); + *data = (uint8_t *) ds->ds_data + offset; + *next_entry = offset + *entry_len; + + return (DW_DLV_OK); +} + +int +dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, + Dwarf_Error *error) +{ + + return (dwarf_loclist_from_expr_a(dbg, bytes_in, bytes_len, + dbg->dbg_pointer_size, llbuf, listlen, error)); +} + +int +dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Half offset_size; + Dwarf_Small version; + + /* + * Obtain offset size and DWARF version from the current + * Compilation Unit or Type Unit. These values are needed + * for correctly parsing DW_OP_GNU_implicit_pointer operator. + * + * Note that dwarf_loclist_from_expr_b() should be used instead + * if the application knows correct values for offset size + * and DWARF version. + */ + if (dbg->dbg_cu_current) { + offset_size = dbg->dbg_cu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_cu_current->cu_version; + } else if (dbg->dbg_tu_current) { + offset_size = dbg->dbg_tu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_tu_current->cu_version; + } else { + /* Default values if no CU/TU context. */ + offset_size = 4; + version = 2; /* DWARF2 */ + } + + return (dwarf_loclist_from_expr_b(dbg, bytes_in, bytes_len, addr_size, + offset_size, version, llbuf, listlen, error)); +} + +int +dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, + Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, + Dwarf_Error *error) +{ + Dwarf_Locdesc *ld; + int ret; + + if (dbg == NULL || bytes_in == NULL || bytes_len == 0 || + llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (addr_size != 4 && addr_size != 8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (offset_size != 4 && offset_size != 8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size, + offset_size, version, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *llbuf = ld; + *listlen = 1; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 new file mode 100644 index 0000000000..d920150323 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2011,2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_loclist_from_expr.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd December 21, 2014 +.Dt DWARF_LOCLIST_FROM_EXPR 3 +.Os +.Sh NAME +.Nm dwarf_loclist_from_expr , +.Nm dwarf_loclist_from_expr_a , +.Nm dwarf_loclist_from_expr_b +.Nd translate DWARF location expression bytes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_loclist_from_expr +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_loclist_from_expr_a +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Half addr_size" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_loclist_from_expr_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Half addr_size" +.Fa "Dwarf_Half offset_size" +.Fa "Dwarf_Small version" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_loclist_from_expr +translates DWARF location expression bytes into a +.Vt Dwarf_Locdesc +descriptor. +The size for address related data is taken to be the default address +size for the object being read. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa bytes_in +should point to an array of DWARF location expression bytes. +.Pp +Argument +.Fa bytes_len +should specify the number of the location expression bytes to be +translated. +.Pp +Argument +.Fa llbuf +should point to a location which will be set to a pointer +to a returned +.Vt Dwarf_Locdesc +descriptor. +.Pp +Argument +.Fa listlen +should point to a location which will hold the number of the +.Vt Dwarf_Locdesc +descriptors returned. +In this case it is always set to 1. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +Function +.Fn dwarf_loclist_from_expr_a +is identical to function +.Fn dwarf_loclist_from_expr , +except that it requires one additional argument +.Fa addr_size , +which specifies the address size to use when translating the location +expression bytes. +.Pp +Function +.Fn dwarf_loclist_from_expr_b +is identical to function +.Fn dwarf_loclist_from_expr_a +except that it requires two additional arguments for translating the +location expression bytes. +Argument +.Fa offset_size +specifies the offset size, and argument +.Fa version +specifies the DWARF version. +These values are required to correctly translate the +.Dv DW_OP_GNU_implicit_pointer +opcode. +.Ss Memory Management +The memory area used for the descriptor returned in argument +.Fa llbuf +is allocated by +.Lb libdwarf . +When the descriptor is no longer needed, application code should use +function +.Xr dwarf_dealloc 3 +to free the memory area in two steps: +.Bl -enum -compact +.It +First, the array of +.Vt Dwarf_Loc +descriptors pointed to by the +.Fa ld_s +field of the +.Vt Dwarf_Locdesc +descriptor should be deallocated using the allocation type +.Dv DW_DLA_LOC_BLOCK . +.It +Next, the application should free the +.Fa llbuf +pointer using the allocation type +.Dv DW_DLA_LOCDESC . +.El +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Fa err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va dbg , +.Va bytes_in , +.Va llbuf +or +.Va listlen +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa bytes_len +was 0. +.It Bq Er DW_DLE_ARGUMENT +The value of argument +.Fa addr_size +was invalid. +.It Bq Er DW_DLE_LOC_EXPR_BAD +An unknown or invalid operation was found in the location expression +bytes provided in argument +.Fa bytes_in . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_loclist_entry 3 , +.Xr dwarf_loclist_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_macinfo.c b/contrib/elftoolchain/libdwarf/dwarf_macinfo.c new file mode 100644 index 0000000000..325c653850 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_macinfo.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_macinfo.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +char * +dwarf_find_macro_value_start(char *macro_string) +{ + char *p; + + if (macro_string == NULL) + return (NULL); + + p = macro_string; + while (*p != '\0' && *p != ' ') + p++; + if (*p == ' ') + p++; + + return (p); +} + +int +dwarf_get_macro_details(Dwarf_Debug dbg, Dwarf_Off offset, + Dwarf_Unsigned max_count, Dwarf_Signed *entry_cnt, + Dwarf_Macro_Details **details, Dwarf_Error *error) +{ + Dwarf_MacroSet ms; + Dwarf_Unsigned cnt; + int i; + + if (dbg == NULL || entry_cnt == NULL || details == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (STAILQ_EMPTY(&dbg->dbg_mslist)) { + if (_dwarf_macinfo_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (STAILQ_EMPTY(&dbg->dbg_mslist)) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + STAILQ_FOREACH(ms, &dbg->dbg_mslist, ms_next) { + for (i = 0; (Dwarf_Unsigned) i < ms->ms_cnt; i++) + if (ms->ms_mdlist[i].dmd_offset == offset) { + cnt = ms->ms_cnt - i; + if (max_count != 0 && cnt > max_count) + cnt = max_count; + + *details = &ms->ms_mdlist[i]; + *entry_cnt = cnt; + + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + + return (DW_DLV_NO_ENTRY); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 b/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 new file mode 100644 index 0000000000..34ec280add --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_nametbl.m4 2074 2011-10-27 03:34:33Z jkoshy $ + */ + +define(`MAKE_NAMETBL_API',` +int +dwarf_get_$1s(Dwarf_Debug dbg, Dwarf_$2 **$1s, + Dwarf_Signed *ret_count, Dwarf_Error *error) +{ + Dwarf_Section *ds; + int ret; + + if (dbg == NULL || $1s == NULL || ret_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_$1s == NULL) { + if ((ds = _dwarf_find_section(dbg, ".debug_$4")) != NULL) { + ret = _dwarf_nametbl_init(dbg, &dbg->dbg_$1s, ds, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (dbg->dbg_$1s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + *$1s = dbg->dbg_$1s->ns_array; + *ret_count = dbg->dbg_$1s->ns_len; + + return (DW_DLV_OK); +} + +int +dwarf_$3name(Dwarf_$2 $1, char **ret_name, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_name = $1->np_name; + + return (DW_DLV_OK); +} + +int +dwarf_$1_die_offset(Dwarf_$2 $1, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + *ret_offset = nt->nt_cu_offset + $1->np_offset; + + return (DW_DLV_OK); +} + +int +dwarf_$1_cu_offset(Dwarf_$2 $1, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + *ret_offset = nt->nt_cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_$1_name_offsets(Dwarf_$2 $1, char **ret_name, Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Debug dbg; + Dwarf_NameTbl nt; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_name == NULL || die_offset == NULL || + cu_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + cu = nt->nt_cu; + assert(cu != NULL); + + *ret_name = $1->np_name; + *die_offset = nt->nt_cu_offset + $1->np_offset; + *cu_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} + +void +dwarf_$1s_dealloc(Dwarf_Debug dbg, Dwarf_$2 *$1s, Dwarf_Signed count) +{ + + (void) dbg; + (void) $1s; + (void) count; +} +') diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_die.3 b/contrib/elftoolchain/libdwarf/dwarf_new_die.3 new file mode 100644 index 0000000000..0ddbb9215f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_die.3 @@ -0,0 +1,168 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_new_die.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 4, 2011 +.Dt DWARF_NEW_DIE 3 +.Os +.Sh NAME +.Nm dwarf_new_die +.Nd allocate a new debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Die +.Fo dwarf_new_die +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Tag tag" +.Fa "Dwarf_P_Die parent" +.Fa "Dwarf_P_Die child" +.Fa "Dwarf_P_Die left" +.Fa "Dwarf_P_Die right" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_die +allocates a new DWARF debugging information entry and links it +to another debugging information entry. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa tag +should specify the tag of the newly created debugging information entry. +Valid values for this argument are those for the +.Dv DW_TAG_ Ns * +symbols defined in +.In libdwarf.h . +.Pp +Argument +.Fa parent +specifies the parent link of the debugging information entry. +.Pp +Argument +.Fa child +specifies the first child link of the debugging information entry. +.Pp +Argument +.Fa left +specifies the left sibling link of the debugging information entry. +.Pp +Argument +.Fa right +specifies the right sibling link of the debugging information entry. +.Pp +Only one of arguments +.Fa parent , +.Fa child , +.Fa left +and +.Fa right +is allowed to be +.No non- Ns Dv NULL . +Application code can subsequently call the function +.Xr dwarf_die_link 3 +to change the links for the created debugging information entry. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_die +returns the newly created debugging information entry. +In case of an error, function +.Fn dwarf_new_die +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh EXAMPLES +To create debugging information entries and add them to the producer +instance, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_P_Die die1, die2; +Dwarf_Error de; + +/* ... assume dbg refers to a DWARF producer instance ... */ + +die1 = dwarf_new_die(dbg, DW_TAG_compilation_unit, NULL, NULL, NULL, + NULL, &de); +if (die1 == NULL) { + warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); + return; +} + +die2 = dwarf_new_die(dbg, DW_TAG_base_type, die1, NULL, NULL, + NULL, &de); +if (die1 == NULL) { + warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); + return; +} + +if (dwarf_add_die_to_debug(dbg, die1, &de) != DW_DLV_OK) { + warnx("dwarf_add_die_to_debug failed: %s", dwarf_errmsg(-1)); + return; +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_new_die +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +More than one of the arguments +.Fa parent , +.Fa child , +.Fa left +and +.Fa right +were +.No non- Ns Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_die_to_debug 3 , +.Xr dwarf_die_link 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 new file mode 100644 index 0000000000..c11e9d2075 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 @@ -0,0 +1,137 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_new_expr.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 8, 2011 +.Dt DWARF_NEW_EXPR 3 +.Os +.Sh NAME +.Nm dwarf_new_expr +.Nd create a location expression descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Expr" +.Fo dwarf_new_expr +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_expr +allocates a DWARF location expression descriptor used to build up a +location expression stream. +.Pp +The application can use the functions +.Xr dwarf_add_expr_gen 3 +and +.Xr dwarf_add_expr_addr_b 3 +to add location expression operators to the created descriptor. +When done, the application can call the function +.Xr dwarf_expr_into_block 3 +to retrieve the generated byte stream for the location expression, +or call the function +.Xr dwarf_add_AT_location_expr 3 +to create an attribute with the location expression stream as its +value. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_expr +returns the created location expression descriptor. +In case of an error, function +.Fn dwarf_new_expr +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh EXAMPLES +To create a location expression descriptor, add location expression +operators to it and to retrieve the generated byte stream, +use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; +Dwarf_P_Expr pe; +Dwarf_Addr buf; +Dwarf_Unsigned len; + +/* ...Assume that `dbg' refers to a DWARF producer instance... */ + +if ((pe = dwarf_new_expr(dbg, &de)) == DW_DLV_BADADDR) { + warnx("dwarf_new_expr failed: %s", dwarf_errmsg(-1)); + return; +} + +if (dwarf_add_expr_gen(pe, DW_OP_regx, 55, 0, &de) == + DW_DLV_NOCOUNT) { + warnx("dwarf_add_expr_gen failed: %s", dwarf_errmsg(-1)); + return; +} + +if ((buf = dwarf_expr_into_block(pe, &len, &de)) == + DW_DLV_BADADDR) { + warnx("dwarf_expr_into_block failed: %s", + dwarf_errmsg(-1)); + return; +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_new_expr +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 new file mode 100644 index 0000000000..c05df82b6c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 @@ -0,0 +1,89 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_new_fde.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 24, 2011 +.Dt DWARF_NEW_FDE 3 +.Os +.Sh NAME +.Nm dwarf_new_fde +.Nd allocate a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_new_fde +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_fde +allocates a new DWARF frame descriptor. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_fde +returns the newly created frame descriptor. +In case of an error, function +.Fn dwarf_new_fde +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_new_fde +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_fde_cfa_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 new file mode 100644 index 0000000000..ac16644958 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 @@ -0,0 +1,322 @@ +.\" Copyright (c) 2010,2014,2023 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_next_cu_header.3 4013 2023-10-14 22:40:50Z kaiwang27 $ +.\" +.Dd October 15, 2023 +.Dt DWARF_NEXT_CU_HEADER 3 +.Os +.Sh NAME +.Nm dwarf_next_cu_header , +.Nm dwarf_next_cu_header_b , +.Nm dwarf_next_cu_header_c , +.Nm dwarf_next_cu_header_d +.Nd step through compilation units in a DWARF debug context +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_next_cu_header +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_next_cu_header_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Half *cu_offset_size" +.Fa "Dwarf_Half *cu_extension_size" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_next_cu_header_c +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Half *cu_offset_size" +.Fa "Dwarf_Half *cu_extension_size" +.Fa "Dwarf_Sig8 *type_signature" +.Fa "Dwarf_Unsigned *type_offset" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_next_cu_header_d +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Half *cu_offset_size" +.Fa "Dwarf_Half *cu_extension_size" +.Fa "Dwarf_Sig8 *type_signature" +.Fa "Dwarf_Unsigned *type_offset" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Half *cu_type" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to step through compilation or type units +associated with a DWARF debug context, optionally returning information +about the unit. +.Pp +Function +.Fn dwarf_next_cu_header_d +is the API recommended for new application code. +Function +.Fn dwarf_next_cu_header_c +can not return the unit type defined by the DWARF5 standard. +Function +.Fn dwarf_next_cu_header +and +.Fn dwarf_next_cu_header_b +can only operate on compilation units associated with the +.Dq \&.debug_info +section. +The earlier revisions are less general than function +.Fn dwarf_next_cu_header_d , +and are deprecated for use by new application code. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +If argument +.Fa is_info +is set to 1, +the function returns information for compilation units found in the +.Dq \&.debug_info +section. +If argument +.Fa is_info +is set to 0, +the function returns information for type units found in the +.Dq \&.debug_types +sections. +Argument +.Fa cu_length +should point to a location that will be set to the +length of the compilation or type unit. +Argument +.Fa cu_version +should point to a location that will be set to the +version number for the compilation or type unit. +Argument +.Fa cu_abbrev_offset +should point to a location that will be set to the +starting offset (in the +.Dq .debug_abbrev +section) of the set of debugging information entry abbreviations +associated with this compilation or type unit. +Argument +.Fa cu_pointer_size +should point to a location that will be set to the +size in bytes of an address for the machine architecture of the +underlying object being debugged. +Argument +.Fa cu_offset_size +should point to a location that will be set to the +size in bytes for a DWARF offset in the compilation or type unit. +Argument +.Fa cu_extension_size +is only needed for processing MIPS/IRIX objects that use +a non-standard DWARF format. +It should point to a location that will be set to 4 for normal +objects and to 0 for non-standard ones. +Argument +.Fa type_signature +and +.Fa type_offset +is only needed for processing type units. +Argument +.Fa type_signature +should point to a location that will be set to the 64-bit unique signature +of the type described in the type unit. +Argument +.Fa type_offset +should point to a location that will be set to the offset of the debugging +information entry that describes the type. +Argument +.Fa cu_next_offset +should point to a location that will be set to the +offset of the next compilation unit header in the +.Dq \&.debug_info +section, +or the offset of the next type unit header in the +.Dq \&.debug_types +section. +Argument +.Fa cu_type +should point to a location that will be set to the +type of the compilation unit. +Argument +.Fa err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +Function +.Fn dwarf_next_cu_header_c +is identical to function +.Fn dwarf_next_cu_header_d +except that it does not provide argument +.Fa cu_type . +.Pp +Function +.Fn dwarf_next_cu_header_b +is identical to function +.Fn dwarf_next_cu_header_c +except that it does not provide arguments +.Fa is_info , +.Fa type_signature +and +.Fa type_offset . +.Pp +Function +.Fn dwarf_next_cu_header +is identical to function +.Fn dwarf_next_cu_header_b +except that it does not provide arguments +.Fa cu_offset_size +and +.Fa cu_extension_size . +.Pp +A value of +.Dv NULL +may be used for any of the arguments +.Fa cu_length , +.Fa cu_version , +.Fa cu_abbrev_offset , +.Fa cu_pointer_size , +.Fa cu_offset_size , +.Fa cu_extension_size , +.Fa type_signature , +.Fa type_offset , +.Fa cu_next_offset , +.Fa cu_type +and +.Fa err +if the caller is not interested in the respective value. +.Ss Iterating Through Compilation Units in a Debug Context +The first call to function +.Fn dwarf_next_cu_header_c +for a given debug context with argument +.Fa is_info +set to 1 will return information about the first +compilation unit in the +.Dq \&.debug_info +section. +Subsequent calls to the function will iterate through the remaining +compilation units in the section. +On stepping past the last compilation unit in the section, +function +.Fn dwarf_next_cu_header_d +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first compilation +unit in the section. +.Ss Iterating Through Type Units in a Debug Context +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer associated with the context will point to the first +.Dq \&.debug_types +section found in the debug object. +The first call to function +.Fn dwarf_next_cu_header_d +for the debug context with argument +.Fa is_info +set to 0 will return information about the first +type unit in that +.Dq \&.debug_types +section. +Subsequent calls to the function will iterate through the remaining +type units in the section. +On stepping past the last type unit in the debug context, +function +.Fn dwarf_next_cu_header_d +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first type +unit in the +.Dq \&.debug_types +section. +.Pp +If the debug object contains multiple +.Dq \&.debug_types +sections, the function +.Fn dwarf_next_types_section +can be called to move the internal pointer to the next +.Dq \&.debug_types +section. +As a result, subsequent calls of the function +.Fn dwarf_next_cu_header_d +will operate on the new +.Dq \&.debug_types +section. +Function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_NO_ENTRY +when there are no more +.Dq \&.debug_types +sections left in the debug object. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set argument +.Fa err . +When there are no more compilation units left to traverse, they return +.Dv DW_DLV_NO_ENTRY . +.Sh ERRORS +These functions can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_init 3 , +.Xr dwarf_next_types_section 3 , +.Xr dwarf_siblingof 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 b/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 new file mode 100644 index 0000000000..a95726cf09 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 @@ -0,0 +1,135 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_next_types_section.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd December 20, 2014 +.Dt DWARF_NEXT_TYPES_SECTION 3 +.Os +.Sh NAME +.Nm dwarf_next_types_section +.Nd step through .debug_types sections in a debug context +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_next_types_section +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_next_types_section +steps through the +.Dq \&.debug_types +sections found in a debug context. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Fa err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer associated with the context will point to the +first +.Dq \&.debug_types +section present in the debug object. +When the application calls function +.Fn dwarf_next_types_section , +this internal pointer will move to the next +.Dq \&.debug_types +section present. +On stepping past the last +.Dq \&.debug_types +section left in the debug context, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_NO_ENTRY . +The next call to the function will restart from the first +.Dq \&.debug_types +section in the debug context. +.Pp +Application code should call function +.Xr dwarf_next_cu_header_c 3 +to iterate though the type units associated with the current +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +When there are no more +.Dq \&.debug_types +sections left to traverse, it returns +.Dv DW_DLV_NO_ENTRY . +.Sh EXAMPLES +To iterate though every type unit in all the +.Dq \&.debug_types +sections found in a debug context: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Sig8 sig8; +Dwarf_Unsigned typeoff; +Dwarf_Error de; + +\&... allocate dbg using dwarf_init() etc ... + +do { + while ((ret = dwarf_next_cu_header_c(dbg, 0, NULL, NULL, NULL, + NULL, NULL, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) { + /* Access DIEs etc ... */ + } +} while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); +.Ed +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_next_types_section +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_next_cu_header_c 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_object_init.3 b/contrib/elftoolchain/libdwarf/dwarf_object_init.3 new file mode 100644 index 0000000000..4d35487544 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_object_init.3 @@ -0,0 +1,227 @@ +.\" Copyright (c) 2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_object_init.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 29, 2011 +.Dt DWARF_OBJECT_INIT 3 +.Os +.Sh NAME +.Nm dwarf_object_init +.Nd allocate a DWARF debug descriptor with application-specific file \ +access methods +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_object_init +.Fa "Dwarf_Obj_Access_Interface *iface" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The +.Fn dwarf_object_init +function allocates and returns a +.Vt Dwarf_Debug +instance that uses application-supplied access methods to read file +content. +.Pp +The argument +.Fa iface +should point to a populated +.Vt Dwarf_Obj_Access_Interface +structure. +The contents of the +.Vt Dwarf_Obj_Access_Interface +structure are described in the section +.Sx "Object Access Functions" +below. +.Pp +The argument +.Fa errhand +should point to a function to be called in case of an error. +If this argument is +.Dv NULL +then a default error handling scheme is used. +See +.Xr dwarf 3 +for a description of the error handling schemes available. +.Pp +The argument +.Fa errarg +will be passed to the error handler function pointed to by argument +.Fa errhand . +.Pp +The argument +.Fa dbg +should point to a memory location that will be set to a reference to +the returned +.Vt Dwarf_Debug +descriptor. +.Pp +The argument +.Fa err +will be used to return a +.Vt Dwarf_Error +descriptor in case of an error. +.Ss Object Access Functions +The data structures used to specify object access methods are defined +in +.In libdwarf.h . +.Bl -tag -width indent +.It Vt "Dwarf_Obj_Access_Interface" +This structure bundles together a set of file access methods along +with a pointer to application-private state. +.Bd -literal -offset indent +typedef struct { + void *object; + const Dwarf_Obj_Access_Methods *methods; +} Dwarf_Obj_Access_Interface; +.Ed +.Pp +.Bl -tag -width ".Ar methods" -compact +.It Ar object +This field points to application-specific state that will be passed as +the first parameter to the actual access object methods. +.It Ar methods +This structure contains pointers to the functions implementing the +access methods, as described below. +.El +.It Vt Dwarf_Obj_Access_Methods +This structure specifies the functions implementing low-level access. +.Bd -literal -offset indent +typedef struct { + int (*get_section_info)(void *obj, Dwarf_Half index, + Dwarf_Obj_Access_Section *ret, int *error); + Dwarf_Endianness (*get_byte_order)(void *obj); + Dwarf_Small (*get_length_size)(void *obj); + Dwarf_Small (*get_pointer_size)(void *obj); + Dwarf_Unsigned (*get_section_count)(void *obj); + int (*load_section)(void *obj, Dwarf_Half ndx, + Dwarf_Small **ret_data, int *error); +} Dwarf_Obj_Access_Methods; +.Ed +.Pp +.Bl -tag -width ".Ar get_section_count" -compact +.It Ar get_byte_order +This function should return the endianness of the DWARF object by +returning one of the constants +.Dv DW_OBJECT_MSB +or +.Dv DW_OBJECT_LSB . +.It Ar get_length_size +This function should return the number of bytes needed to represent a +DWARF offset in the object being debugged. +.It Ar get_pointer_size +This function should return the size in bytes, in the object being +debugged, of a memory address. +.It Ar get_section_count +This function should return the number of sections in the object being +debugged. +.It Ar get_section_info +This function should return information about the section at the +index +.Fa ndx +by filling in the structure of type +.Vt Dwarf_Obj_Access_Section +pointed to by argument +.Fa ret . +The +.Vt Dwarf_Obj_Access_Section +structure is described below. +.It Ar load_section +This function should load the section specified by argument +.Fa ndx +into memory and place a pointer to the section's data into +the location pointed to by argument +.Fa ret_data . +.El +.Pp +The argument +.Fa obj +passed to these functions will be set to the pointer value in the +.Fa object +field of the associated +.Vt Dwarf_Obj_Access_Interface +structure. +.Pp +The argument +.Fa error +is used to return an error code in case of an error. +.It Vt Dwarf_Obj_Access_Section +This structure describes the layout of a section in the DWARF object. +.Bd -literal -offset indent +typedef struct { + Dwarf_Addr addr; + Dwarf_Unsigned size; + const char *name; +} Dwarf_Obj_Access_Section; +.Ed +.Pp +.Bl -tag -width ".Ar name" -compact +.It Ar addr +A pointer to the start of the section's data. +.It Ar size +The size of the section in bytes. +.It Ar name +A pointer to a NUL-terminated string containing the name of the +section. +.El +.El +.Sh RETURN VALUES +On success, the +.Fn dwarf_object_init +function returns +.Dv DW_DLV_OK . +In case of an error, the function returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +The +.Fn dwarf_object_init +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_DEBUG_INFO_NULL" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa iface +or +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_DEBUG_INFO_NULL +The underlying object did not contain debugging information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_init_elf 3 , +.Xr dwarf_object_finish 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c b/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c new file mode 100644 index 0000000000..61e14db7c0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_arange.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_add_arange(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length, + Dwarf_Signed symbol_index, Dwarf_Error *error) +{ + + return (dwarf_add_arange_b(dbg, start, length, symbol_index, 0, 0, + error)); +} + +Dwarf_Unsigned +dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length, + Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error) +{ + Dwarf_ArangeSet as; + Dwarf_Arange ar; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + as = dbg->dbgp_as; + + if (end_symbol_index > 0 && + (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + + if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + ar->ar_as = as; + ar->ar_address = start; + ar->ar_range = length; + ar->ar_symndx = symbol_index; + ar->ar_esymndx = end_symbol_index; + ar->ar_eoff = offset_from_end_symbol; + STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next); + + return (1); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c b/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c new file mode 100644 index 0000000000..09529894ea --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c @@ -0,0 +1,386 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_attr.c 3802 2020-02-07 02:13:19Z emaste $"); + +Dwarf_P_Attribute +dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_P_Expr loc_expr, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL || loc_expr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_expr = loc_expr; + + if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) { + free(at); + return (DW_DLV_BADADDR); + } + at->u[0].u64 = loc_expr->pe_length; + at->u[1].u8p = loc_expr->pe_block; + if (loc_expr->pe_length <= UCHAR_MAX) + at->at_form = DW_FORM_block1; + else if (loc_expr->pe_length <= USHRT_MAX) + at->at_form = DW_FORM_block2; + else if (loc_expr->pe_length <= UINT_MAX) + at->at_form = DW_FORM_block4; + else + at->at_form = DW_FORM_block; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = DW_AT_const_value; + at->at_form = DW_FORM_sdata; + at->u[0].s64 = value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = DW_AT_const_value; + at->at_form = DW_FORM_udata; + at->u[0].u64 = value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, + error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) +{ + + return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, + error)); +} + +Dwarf_P_Attribute +dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_addr; + at->at_relsym = sym_index; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, + NULL, &at, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); + +} + +Dwarf_P_Attribute +dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_ref_addr; + at->at_relsym = sym_index; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned value, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->u[0].u64 = value; + + if (value <= UCHAR_MAX) + at->at_form = DW_FORM_data1; + else if (value <= USHRT_MAX) + at->at_form = DW_FORM_data2; + else if (value <= UINT_MAX) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Signed value, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->u[0].u64 = value; + + if (value >= SCHAR_MIN && value <= SCHAR_MAX) + at->at_form = DW_FORM_data1; + else if (value >= SHRT_MIN && value <= SHRT_MAX) + at->at_form = DW_FORM_data2; + else if (value >= INT_MIN && value <= INT_MAX) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_P_Die ref_die, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + if (dbg->dbg_offset_size == 4) + at->at_form = DW_FORM_ref4; + else + at->at_form = DW_FORM_ref8; + + at->at_refdie = ref_die; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Small flag, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_flag; + at->u[0].u64 = flag ? 1 : 0; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + char *string, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + /* XXX Add DW_FORM_string style string instead? */ + + if (_dwarf_add_string_attr(die, &at, attr, string, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_die.c b/contrib/elftoolchain/libdwarf/dwarf_pro_die.c new file mode 100644 index 0000000000..3d28236c05 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_die.c @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_die.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_add_die_to_debug(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, + Dwarf_Error *error) +{ + + if (dbg == NULL || first_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + dbg->dbgp_root_die = first_die; + + return (DW_DLV_OK); +} + +Dwarf_P_Die +dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, + Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, + Dwarf_P_Die right_sibling, Dwarf_Error *error) +{ + Dwarf_P_Die die; + int count; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + count = _dwarf_die_count_links(parent, child, left_sibling, + right_sibling); + + if (count > 1) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_die_alloc(dbg, &die, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + die->die_dbg = dbg; + die->die_tag = new_tag; + + STAILQ_INSERT_TAIL(&dbg->dbgp_dielist, die, die_pro_next); + + if (count == 0) + return (die); + + _dwarf_die_link(die, parent, child, left_sibling, right_sibling); + + return (die); +} + +Dwarf_P_Die +dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, + Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int count; + + + if (die == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + dbg = die->die_dbg; + count = _dwarf_die_count_links(parent, child, left_sibling, + right_sibling); + + if (count > 1) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } else if (count == 0) + return (die); + + _dwarf_die_link(die, parent, child, left_sibling, right_sibling); + + return (die); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c b/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c new file mode 100644 index 0000000000..c1cef44e14 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_expr.c 3801 2020-02-07 02:05:54Z emaste $"); + +static struct _Dwarf_P_Expr_Entry * +_dwarf_add_expr(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + Dwarf_Debug dbg; + int len; + + dbg = expr->pe_dbg; + + if (_dwarf_loc_expr_add_atom(dbg, NULL, NULL, opcode, val1, val2, &len, + error) != DW_DLE_NONE) + return (NULL); + assert(len > 0); + + if ((ee = calloc(1, sizeof(*ee))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (NULL); + } + + STAILQ_INSERT_TAIL(&expr->pe_eelist, ee, ee_next); + + ee->ee_loc.lr_atom = opcode; + ee->ee_loc.lr_number = val1; + ee->ee_loc.lr_number2 = val2; + ee->ee_loc.lr_offset = expr->pe_length; + expr->pe_length += len; + expr->pe_invalid = 1; + + return (ee); +} + +int +_dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + Dwarf_Debug dbg; + int len, pos, ret; + + dbg = expr->pe_dbg; + + if (expr->pe_block != NULL) { + free(expr->pe_block); + expr->pe_block = NULL; + } + + if (expr->pe_length <= 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLE_EXPR_LENGTH_BAD); + } + + + if ((expr->pe_block = calloc((size_t) expr->pe_length, 1)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + pos = 0; + STAILQ_FOREACH(ee, &expr->pe_eelist, ee_next) { + assert((Dwarf_Unsigned) pos < expr->pe_length); + ret = _dwarf_loc_expr_add_atom(dbg, + &expr->pe_block[pos], &expr->pe_block[expr->pe_length], + ee->ee_loc.lr_atom, ee->ee_loc.lr_number, + ee->ee_loc.lr_number2, &len, error); + assert(ret == DW_DLE_NONE); + assert(len > 0); + pos += len; + } + + expr->pe_invalid = 0; + + return (DW_DLE_NONE); +} + +void +_dwarf_expr_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Expr pe, tpe; + struct _Dwarf_P_Expr_Entry *ee, *tee; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(pe, &dbg->dbgp_pelist, pe_next, tpe) { + STAILQ_REMOVE(&dbg->dbgp_pelist, pe, _Dwarf_P_Expr, pe_next); + STAILQ_FOREACH_SAFE(ee, &pe->pe_eelist, ee_next, tee) { + STAILQ_REMOVE(&pe->pe_eelist, ee, _Dwarf_P_Expr_Entry, + ee_next); + free(ee); + } + if (pe->pe_block) + free(pe->pe_block); + free(pe); + } +} + +Dwarf_P_Expr +dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Expr pe; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if ((pe = calloc(1, sizeof(struct _Dwarf_P_Expr))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_BADADDR); + } + STAILQ_INIT(&pe->pe_eelist); + + STAILQ_INSERT_TAIL(&dbg->dbgp_pelist, pe, pe_next); + pe->pe_dbg = dbg; + + return (pe); +} + +Dwarf_Unsigned +dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (_dwarf_add_expr(expr, opcode, val1, val2, error) == NULL) + return (DW_DLV_NOCOUNT); + + return (expr->pe_length); +} + +Dwarf_Unsigned +dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned address, + Dwarf_Signed sym_index, Dwarf_Error *error) +{ + + return (dwarf_add_expr_addr_b(expr, address, sym_index, error)); +} + +Dwarf_Unsigned +dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned address, + Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ee = _dwarf_add_expr(expr, DW_OP_addr, address, 0, error)) == NULL) + return (DW_DLV_NOCOUNT); + + ee->ee_sym = sym_index; + + return (expr->pe_length); +} + +Dwarf_Unsigned +dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error *error) +{ + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + return (expr->pe_length); +} + +Dwarf_Addr +dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Unsigned *length, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = expr != NULL ? expr->pe_dbg : NULL; + + if (expr == NULL || length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); + } + + if (expr->pe_block == NULL || expr->pe_invalid) + if (_dwarf_expr_into_block(expr, error) != DW_DLE_NONE) + return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); + + *length = expr->pe_length; + + return ((Dwarf_Addr) (uintptr_t) expr->pe_block); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c b/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c new file mode 100644 index 0000000000..8e1dc4afa0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_finish.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL || dbg->dbg_mode != DW_DLC_WRITE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + _dwarf_deinit(dbg); + + free(dbg); + + return (1); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c b/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c new file mode 100644 index 0000000000..fac390e477 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c @@ -0,0 +1,195 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_frame.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_P_Fde +dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Fde fde; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_BADADDR); + } + + fde->fde_dbg = dbg; + + return (fde); +} + +Dwarf_Unsigned +dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small caf, + Dwarf_Small daf, Dwarf_Small ra, Dwarf_Ptr initinst, + Dwarf_Unsigned inst_len, Dwarf_Error *error) +{ + Dwarf_P_Cie cie; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { + DWARF_SET_ERROR(dbg, error,DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + STAILQ_INSERT_TAIL(&dbg->dbgp_cielist, cie, cie_next); + + cie->cie_index = dbg->dbgp_cielen++; + + if (augmenter != NULL) { + cie->cie_augment = (uint8_t *) strdup(augmenter); + if (cie->cie_augment == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + } + + cie->cie_caf = caf; + cie->cie_daf = (int8_t) daf; /* daf is signed. */ + cie->cie_ra = ra; + if (initinst != NULL && inst_len > 0) { + cie->cie_initinst = malloc((size_t) inst_len); + if (cie->cie_initinst == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + memcpy(cie->cie_initinst, initinst, inst_len); + cie->cie_instlen = inst_len; + } + + return (cie->cie_index); +} + +Dwarf_Unsigned +dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, + Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, + Dwarf_Unsigned symbol_index, Dwarf_Error *error) +{ + + return (dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, code_len, + symbol_index, 0, 0, error)); +} + +Dwarf_Unsigned +dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, + Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, + Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_sym, Dwarf_Error *error) +{ + Dwarf_P_Cie ciep; + int i; + + /* + * XXX SGI libdwarf need the DIE arg because later it will insert a + * DW_AT_MIPS_fde attribute, which points to the offset the + * correspoding FDE, into this DIE. Do we need this? + */ + (void) die; + + if (dbg == NULL || fde == NULL || fde->fde_dbg != dbg) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + ciep = STAILQ_FIRST(&dbg->dbgp_cielist); + for (i = 0; (Dwarf_Unsigned) i < cie; i++) { + ciep = STAILQ_NEXT(ciep, cie_next); + if (ciep == NULL) + break; + } + if (ciep == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (end_symbol_index > 0 && + (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + fde->fde_cie = ciep; + fde->fde_initloc = virt_addr; + fde->fde_adrange = code_len; + fde->fde_symndx = symbol_index; + fde->fde_esymndx = end_symbol_index; + fde->fde_eoff = offset_from_end_sym; + + STAILQ_INSERT_TAIL(&dbg->dbgp_fdelist, fde, fde_next); + + return (dbg->dbgp_fdelen++); +} + +Dwarf_P_Fde +dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg > 0x3f) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_frame_fde_add_inst(fde, DW_CFA_offset | (reg & 0x3f), + offset, 0, error); + + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (fde); +} + +Dwarf_P_Fde +dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + int ret; + + if (fde == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_frame_fde_add_inst(fde, op, val1, val2, error); + + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (fde); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 new file mode 100644 index 0000000000..6e8bee113d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_funcs.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(func) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_init.c b/contrib/elftoolchain/libdwarf/dwarf_pro_init.c new file mode 100644 index 0000000000..de7a2d5ab8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_init.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_init.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_P_Debug +dwarf_producer_init(Dwarf_Unsigned flags, Dwarf_Callback_Func func, + Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + int mode; + + if (flags & DW_DLC_READ || flags & DW_DLC_RDWR) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (flags & DW_DLC_WRITE) + mode = DW_DLC_WRITE; + else { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (func == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_WRITE, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + dbg->dbg_mode = mode; + + if (_dwarf_init(dbg, flags, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_BADADDR); + } + + dbg->dbgp_func = func; + + return (dbg); +} + +Dwarf_P_Debug +dwarf_producer_init_b(Dwarf_Unsigned flags, Dwarf_Callback_Func_b func, + Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + int mode; + + if (flags & DW_DLC_READ || flags & DW_DLC_RDWR) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (flags & DW_DLC_WRITE) + mode = DW_DLC_WRITE; + else { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (func == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_WRITE, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + dbg->dbg_mode = mode; + + if (_dwarf_init(dbg, flags, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_BADADDR); + } + + dbg->dbgp_func_b = func; + + return (dbg); +} + +int +dwarf_producer_set_isa(Dwarf_P_Debug dbg, enum Dwarf_ISA isa, + Dwarf_Error *error) +{ + + if (dbg == NULL || isa >= DW_ISA_MAX) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + dbg->dbgp_isa = isa; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c b/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c new file mode 100644 index 0000000000..91e40ee211 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_lineno.c 2973 2013-12-23 06:46:16Z kaiwang27 $"); + +Dwarf_Unsigned +dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file, + Dwarf_Addr off, Dwarf_Unsigned lineno, Dwarf_Signed column, + Dwarf_Bool is_stmt, Dwarf_Bool basic_block, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next); + + if (ln == NULL || ln->ln_addr > off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = off; + ln->ln_symndx = 0; + ln->ln_fileno = file; + ln->ln_lineno = lineno; + ln->ln_column = column; + ln->ln_bblock = basic_block != 0; + ln->ln_stmt = is_stmt != 0; + ln->ln_endseq = 0; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symndx, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL || symndx == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = offs; + ln->ln_symndx = symndx; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr addr, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next); + if (ln && ln->ln_addr >= addr) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = addr; + ln->ln_endseq = 1; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_add_directory_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + + if (dbg == NULL || name == NULL || strlen(name) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + li->li_incdirs = realloc(li->li_incdirs, (li->li_inclen + 1) * + sizeof(char *)); + if (li->li_incdirs == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + if ((li->li_incdirs[li->li_inclen] = strdup(name)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + + return (++li->li_inclen); +} + +Dwarf_Unsigned +dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dirndx, + Dwarf_Unsigned mtime, Dwarf_Unsigned size, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + + if (dbg == NULL || name == NULL || strlen(name) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((lf->lf_fname = strdup(name)) == NULL) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + lf->lf_dirndx = dirndx; + lf->lf_mtime = mtime; + lf->lf_size = size; + STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); + + return (++li->li_lflen); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c b/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c new file mode 100644 index 0000000000..2119b5b7af --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_macinfo.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +static int +_dwarf_add_macro(Dwarf_P_Debug dbg, int type, Dwarf_Unsigned lineno, + Dwarf_Signed fileindex, char *str1, char *str2, Dwarf_Error *error) +{ + Dwarf_Macro_Details *md; + int len; + + dbg->dbgp_mdlist = realloc(dbg->dbgp_mdlist, + (size_t) dbg->dbgp_mdcnt + 1); + if (dbg->dbgp_mdlist == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + md = &dbg->dbgp_mdlist[dbg->dbgp_mdcnt]; + dbg->dbgp_mdcnt++; + + md->dmd_offset = 0; + md->dmd_type = type; + md->dmd_lineno = lineno; + md->dmd_fileindex = fileindex; + md->dmd_macro = NULL; + + if (str1 == NULL) + return (DW_DLV_OK); + else if (str2 == NULL) { + if ((md->dmd_macro = strdup(str1)) == NULL) { + dbg->dbgp_mdcnt--; + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + return (DW_DLV_OK); + } else { + len = strlen(str1) + strlen(str2) + 2; + if ((md->dmd_macro = malloc(len)) == NULL) { + dbg->dbgp_mdcnt--; + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + snprintf(md->dmd_macro, len, "%s %s", str1, str2); + return (DW_DLV_OK); + } +} + +int +dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, + char *value, Dwarf_Error *error) +{ + + if (dbg == NULL || name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_define, lineno, -1, name, + value, error)); +} + +int +dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, + Dwarf_Error *error) +{ + + if (dbg == NULL || name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_undef, lineno, -1, name, + NULL, error)); +} + +int +dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, + Dwarf_Unsigned fileindex, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_start_file, lineno, fileindex, + NULL, NULL, error)); +} + +int +dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_end_file, 0, -1, + NULL, NULL, error)); +} + +int +dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char *string, + Dwarf_Error *error) +{ + + if (dbg == NULL || string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_vendor_ext, constant, -1, + string, NULL, error)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 new file mode 100644 index 0000000000..df57688021 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_pro_nametbl.m4 2074 2011-10-27 03:34:33Z jkoshy $ + */ + +define(`MAKE_NAMETBL_PRO_API',` +Dwarf_Unsigned +dwarf_add_$1name(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *$1_name, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_NamePair np; + + if (dbg == NULL || die == NULL || $1_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + + if (dbg->dbgp_$1s == NULL) { + dbg->dbgp_$1s = calloc(1, sizeof(struct _Dwarf_NameTbl)); + if (dbg->dbgp_$1s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + STAILQ_INIT(&dbg->dbgp_$1s->nt_nplist); + } + + nt = dbg->dbgp_$1s; + + if ((np = calloc(1, sizeof(struct _Dwarf_NamePair))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + + np->np_nt = nt; + np->np_die = die; + if ((np->np_name = strdup($1_name)) == NULL) { + free(np); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + + STAILQ_INSERT_TAIL(&nt->nt_nplist, np, np_next); + + return (1); +} +') diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 new file mode 100644 index 0000000000..2ceafd5d17 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_pubnames.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(pub) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c b/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c new file mode 100644 index 0000000000..6b0b2e263d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_reloc.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +int +dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, Dwarf_Unsigned *reloc_cnt, + int *drd_buffer_version, Dwarf_Error *error) +{ + + if (dbg == NULL || reloc_cnt == NULL || drd_buffer_version == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *reloc_cnt = dbg->dbgp_drscnt; + *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; + + return (DW_DLV_OK); +} + +int +dwarf_get_relocation_info(Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, + Dwarf_Signed *elf_section_link, Dwarf_Unsigned *reloc_entry_count, + Dwarf_Relocation_Data *reloc_buffer, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + Dwarf_Rel_Entry dre; + int i; + + if (dbg == NULL || elf_section_index == NULL || + elf_section_link == NULL || reloc_entry_count == NULL || + reloc_buffer == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (dbg->dbgp_drscnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (dbg->dbgp_drspos == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + drs = dbg->dbgp_drspos; + assert(drs->drs_ds != NULL && drs->drs_ref != NULL); + assert(drs->drs_drecnt > 0); + + *elf_section_index = drs->drs_ds->ds_ndx; + *elf_section_link = drs->drs_ref->ds_ndx; + *reloc_entry_count = drs->drs_drecnt; + + if (drs->drs_drd == NULL) { + drs->drs_drd = calloc(*reloc_entry_count, + sizeof(struct Dwarf_Relocation_Data_s)); + if (drs->drs_drd == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + for (i = 0, dre = STAILQ_FIRST(&drs->drs_dre); + (Dwarf_Unsigned) i < *reloc_entry_count && dre != NULL; + i++, dre = STAILQ_NEXT(dre, dre_next)) { + drs->drs_drd[i].drd_type = dre->dre_type; + drs->drs_drd[i].drd_length = dre->dre_length; + drs->drs_drd[i].drd_offset = dre->dre_offset; + drs->drs_drd[i].drd_symbol_index = dre->dre_symndx; + } + assert((Dwarf_Unsigned) i == *reloc_entry_count && dre == NULL); + } + + *reloc_buffer = drs->drs_drd; + + dbg->dbgp_drspos = STAILQ_NEXT(dbg->dbgp_drspos, drs_next); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c b/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c new file mode 100644 index 0000000000..42aa516cde --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_sections.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Signed +dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (_dwarf_generate_sections(dbg, error) != DW_DLE_NONE) + return (DW_DLV_NOCOUNT); + + return (dbg->dbgp_seccnt); +} + +Dwarf_Ptr +dwarf_get_section_bytes(Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, + Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error *error) +{ + Dwarf_Ptr data; + + (void) dwarf_section; /* ignored. */ + + if (dbg == NULL || elf_section_index == NULL || length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (NULL); + } + + if (dbg->dbgp_secpos == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (NULL); + } + + *elf_section_index = dbg->dbgp_secpos->ds_ndx; + *length = dbg->dbgp_secpos->ds_size; + data = dbg->dbgp_secpos->ds_data; + + dbg->dbgp_secpos = STAILQ_NEXT(dbg->dbgp_secpos, ds_next); + + return (data); +} + +void +dwarf_reset_section_bytes(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL); + + dbg->dbgp_secpos = STAILQ_FIRST(&dbg->dbgp_seclist); + dbg->dbgp_drspos = STAILQ_FIRST(&dbg->dbgp_drslist); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 new file mode 100644 index 0000000000..eab6cc63c4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_types.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(type) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 new file mode 100644 index 0000000000..ac7424d1cc --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_vars.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(var) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 new file mode 100644 index 0000000000..60984fdff1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_weaks.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(weak) diff --git a/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 b/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 new file mode 100644 index 0000000000..710d20b2b1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 @@ -0,0 +1,297 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_producer_init.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd August 20, 2011 +.Dt DWARF_PRODUCER_INIT 3 +.Os +.Sh NAME +.Nm dwarf_producer_init , +.Nm dwarf_producer_init_b +.Nd allocate a DWARF producer descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Debug +.Fo dwarf_producer_init +.Fa "Dwarf_Unsigned flags" +.Fa "Dwarf_Callback_Func func" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Debug +.Fo dwarf_producer_init_b +.Fa "Dwarf_Unsigned flags" +.Fa "Dwarf_Callback_Func_b func" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +These functions allocate and return a +.Vt Dwarf_P_Debug +descriptor representing a DWARF producer instance. +.Pp +The argument +.Fa errhand +should contain the address of a function to be called in case of an +error. +If this argument is +.Dv NULL , +the default error handling scheme is used, see +.Xr dwarf 3 . +.Pp +The argument +.Fa errarg +will be passed to the error handler function when it is invoked. +.Pp +The argument +.Fa err +references a memory location that would hold a +.Vt Dwarf_Error +descriptor in case of an error. +.Pp +The argument +.Fa flags +specifies additional characteristics of the DWARF producer instance. +The following flags are recognized: +.Bl -tag -width "Dv DW_DLC_ISA_MIPS" +.It Dv DW_DLC_ISA_IA64 +.Pq Deprecated +The target instruction set architecture is IA64. +This flag is deprecated. +Application code should use the +.Xr dwarf_producer_set_isa 3 +function to specify target instruction set architecture. +.It Dv DW_DLC_ISA_MIPS +.Pq Deprecated +The target instruction set architecture is MIPS. +This flag is deprecated. +Application code should use the +.Xr dwarf_producer_set_isa 3 +function to specify target instruction set architecture. +.It Dv DW_DLC_SIZE_32 +.Pq Default +The target address size is 32-bit. +.It Dv DW_DLC_SIZE_64 +The target address size is 64-bit. +.It Dv DW_DLC_STREAM_RELOCATIONS +.Pq Default +Generate stream relocations. +.It Dv DW_DLC_SYMBOLIC_RELOCATIONS +Generate symbolic relocations. +.It Dv DW_DLC_TARGET_BIGENDIAN +The target is big endian. +.It Dv DW_DLC_TARGET_LITTLEENDIAN +The target is little endian. +.It Dv DW_DLC_WRITE +.Pq Required +Permit writing of DWARF information. +.El +.Pp +The following flags are mutually exclusive. +.Bl -bullet -compact +.It +Flags +.Dv DW_DLC_ISA_IA64 +and +.Dv DW_DLC_ISA_MIPS . +.It +Flags +.Dv DW_DLC_SIZE_32 +and +.Dv DW_DLC_SIZE_64 . +.It +Flags +.Dv DW_DLC_STREAM_RELOCATIONS +and +.Dv DW_DLC_SYMBOLIC_RELOCATIONS . +.It +Flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN . +.El +If neither of the flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN +is set, the target's endianness is assumed to be the same as the host's +endianness. +.Pp +Argument +.Fa func +should point to an application-provided callback function of type +.Vt Dwarf_Callback_Func_b . +The type +.Vt Dwarf_Callback_Func_b +is defined in the header file +.In libdwarf.h +as: +.Bd -literal -offset indent +typedef int (*Dwarf_Callback_Func_b)(char *name, int size, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Unsigned *index, int *error); +.Ed +.Pp +This function is called by the +.Lb libdwarf +once for each section in the object file that the library needs to +create. +The arguments to this callback function specify the values in the ELF +section header for the section being created: +.Pp +.Bl -tag -width indent -compact -offset indent +.It Ar name +The name of the section being created. +.It Ar size +The +.Va sh_size +value in the section header. +.It Ar type +The +.Va sh_type +value in the section header. +.It Ar flags +The +.Va sh_flags +value in the section header. +.It Ar link +The +.Va sh_link +value in the section header. +.It Ar info +The +.Va sh_info +value in the section header. +.El +.Pp +On success, the callback function should return the section index +value of the created section, and set the location pointed to by +argument +.Fa index +to the symbol table index of the symbol that associated with the newly +created section. +This symbol table index will be used in relocation entries +referring to the created section. +.Pp +In case of failure, the callback function should return -1 and set the +location pointed to by argument +.Fa error +to an application-defined error code. +This application returned error code is currently ignored by the +library. +.Pp +Function +.Fn dwarf_producer_init +is deprecated. +Function +.Fn dwarf_producer_init +is identical to function +.Fn dwarf_producer_init_b +except that the callback function it expects can not properly handle +arbitrary section symbol index values. +.Ss Memory Management +The +.Vt Dwarf_P_Debug +instance returned by these functions should be freed using the +function +.Fn dwarf_producer_finish . +.Sh RETURN VALUES +On success, these functions return the created DWARF producer +descriptor. +In case of an error, they return +.Dv DW_DLV_BADADDR +and set the argument +.Fa err . +.Sh EXAMPLES +To initialize a +.Vt Dwarf_P_Debug +instance for a MIPS32 big endian object, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Unsigned flags; +Dwarf_Error de; + +/* ... assume cb_func points to the callback function ... */ + +flags = DW_DLC_WRITE | DW_DLC_SIZE_32 | DW_DLC_ISA_MIPS | + DW_DLC_STREAM_RELOCATIONS | DW_DLC_TARGET_BIGENDIAN; +if ((dbg = dwarf_producer_init(flags, cb_func, NULL, NULL, &de)) == + DW_DLV_BADADDR) + warnx("dwarf_producer_init failed: %s", dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa func +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The flag +.Dv DW_DLC_WRITE +was not set in argument +.Fa flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_SIZE_32 +and +.Dv DW_DLC_SIZE_64 +were both set in argument +.Fa flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_ISA_IA64 +and +.Dv DW_DLC_ISA_MIPS +were both set in argument +.Fa flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN +were both set in argument +.Fa flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_STREAM_RELOCATIONS +and +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +were both set in argument +.Fa flags . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_set_isa 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 b/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 new file mode 100644 index 0000000000..be048c10c2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_producer_set_isa.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 29, 2011 +.Dt DWARF_PRODUCER_SET_ISA 3 +.Os +.Sh NAME +.Nm dwarf_producer_set_isa +.Nd specify the instruction set architecture for a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_producer_set_isa +.Fa "Dwarf_P_Debug dbg" +.Fa "enum Dwarf_ISA isa" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_producer_set_isa +sets the instruction set architecture for a DWARF producer instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using one of +the functions +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa isa +specifies the desired instruction set architecture. +Legal values for this argument are those defined by the +.Vt "enum Dwarf_ISA" +enumeration defined in the header file +.In libdwarf.h . +.Pp +If the argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, the function +.Fn dwarf_producer_set_isa +returns +.Dv DW_DLV_OK . +In case of an error, this function returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh COMPATIBILITY +The +.Fn dwarf_producer_set_isa +function is a local extension. +.Sh ERRORS +The +.Fn dwarf_producer_set_isa +function can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +The argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_ARGUMENT +The argument +.Fa isa +was invalid. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 b/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 new file mode 100644 index 0000000000..c3971065f3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pubnames.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(global,Global,glob,pubnames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 b/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 new file mode 100644 index 0000000000..5188ea7cca --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pubtypes.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(pubtype,Type,pubtype,pubtypes) diff --git a/contrib/elftoolchain/libdwarf/dwarf_ranges.c b/contrib/elftoolchain/libdwarf/dwarf_ranges.c new file mode 100644 index 0000000000..2e01da553f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_ranges.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_ranges.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); + +static int +_dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off off, + Dwarf_Ranges **ranges, Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, + Dwarf_Error *error) +{ + Dwarf_Rangelist rl; + int ret; + + assert(cu != NULL); + if (_dwarf_ranges_find(dbg, off, &rl) == DW_DLE_NO_ENTRY) { + ret = _dwarf_ranges_add(dbg, cu, off, &rl, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + *ranges = rl->rl_rgarray; + *ret_cnt = rl->rl_rglen; + + if (ret_byte_cnt != NULL) + *ret_byte_cnt = cu->cu_pointer_size * rl->rl_rglen * 2; + + return (DW_DLV_OK); +} + +int +dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Ranges **ranges, + Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, Dwarf_Error *error) +{ + + if (dbg == NULL || ranges == NULL || ret_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (!dbg->dbg_info_loaded) { + if (_dwarf_info_load(dbg, 1, 1, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + return (_dwarf_get_ranges(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, + ranges, ret_cnt, ret_byte_cnt, error)); +} + +int +dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die, + Dwarf_Ranges **ranges, Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, + Dwarf_Error *error) +{ + + if (dbg == NULL || die == NULL || ranges == NULL || ret_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_get_ranges(dbg, die->die_cu, offset, ranges, ret_cnt, + ret_byte_cnt, error)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_reloc.c b/contrib/elftoolchain/libdwarf/dwarf_reloc.c new file mode 100644 index 0000000000..0430e4db49 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_reloc.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_reloc.c 3161 2015-02-15 21:43:36Z emaste $"); + +int +dwarf_set_reloc_application(int apply) +{ + int oldapply; + + oldapply = _libdwarf.applyreloc; + _libdwarf.applyreloc = apply; + + return (oldapply); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 new file mode 100644 index 0000000000..203bca289c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 @@ -0,0 +1,69 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_reset_section_bytes.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 3, 2011 +.Dt DWARF_RESET_SECTION_BYTES 3 +.Os +.Sh NAME +.Nm dwarf_reset_section_bytes +.Nd reset the internal state of a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft void +.Fo dwarf_reset_section_bytes +.Fa "Dwarf_P_Debug dbg" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_reset_section_bytes +resets the internal state of a DWARF producer instance, so that the +next call to the function +.Xr dwarf_get_section_bytes 3 +will return the byte stream for the first generated section, and +the next call to the function +.Xr dwarf_get_relocation_info 3 +will return the first relocation array for the DWARF producer +instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_reset_section_bytes +has no return value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_get_section_bytes 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_sections.c b/contrib/elftoolchain/libdwarf/dwarf_sections.c new file mode 100644 index 0000000000..fec933c818 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_sections.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_sections.c 3902 2020-11-24 21:17:41Z jkoshy $"); + +#define SET(N, V) \ + do { \ + if ((N) != NULL) \ + *(N) = (V); \ + } while (/* CONSTCOND */ 0) + +int +dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes, + Dwarf_Unsigned *debug_types) +{ + const char *n; + Dwarf_Unsigned sz; + int i; + + if (dbg == NULL) + return (DW_DLV_ERROR); + + SET(debug_info, 0); + SET(debug_abbrev, 0); + SET(debug_line, 0); + SET(debug_loc, 0); + SET(debug_aranges, 0); + SET(debug_macinfo, 0); + SET(debug_pubnames, 0); + SET(debug_str, 0); + SET(debug_frame, 0); + SET(debug_ranges, 0); + SET(debug_pubtypes, 0); + SET(debug_types, 0); + + for (i = 0; (Dwarf_Unsigned) i < dbg->dbg_seccnt; i++) { + n = dbg->dbg_section[i].ds_name; + sz = dbg->dbg_section[i].ds_size; + if (!strcmp(n, ".debug_info")) + SET(debug_info, sz); + else if (!strcmp(n, ".debug_abbrev")) + SET(debug_abbrev, sz); + else if (!strcmp(n, ".debug_line")) + SET(debug_line, sz); + else if (!strcmp(n, ".debug_loc")) + SET(debug_loc, sz); + else if (!strcmp(n, ".debug_aranges")) + SET(debug_aranges, sz); + else if (!strcmp(n, ".debug_macinfo")) + SET(debug_macinfo, sz); + else if (!strcmp(n, ".debug_pubnames")) + SET(debug_pubnames, sz); + else if (!strcmp(n, ".debug_str")) + SET(debug_str, sz); + else if (!strcmp(n, ".debug_frame")) + SET(debug_frame, sz); + else if (!strcmp(n, ".debug_ranges")) + SET(debug_ranges, sz); + else if (!strcmp(n, ".debug_pubtypes")) + SET(debug_pubtypes, sz); + else if (!strcmp(n, ".debug_types")) + SET(debug_types, sz); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes) +{ + + return (dwarf_get_section_max_offsets_b(dbg, debug_info, debug_abbrev, + debug_line, debug_loc, debug_aranges, debug_macinfo, + debug_pubnames, debug_str, debug_frame, debug_ranges, + debug_pubtypes, NULL)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 b/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 new file mode 100644 index 0000000000..4619ec79c4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_set_frame_cfa_value.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd June 18, 2011 +.Dt DWARF_SET_FRAME_CFA_VALUE 3 +.Os +.Sh NAME +.Nm dwarf_set_frame_cfa_value , +.Nm dwarf_set_frame_rule_initial_value , +.Nm dwarf_set_frame_rule_table_size , +.Nm dwarf_set_frame_same_value , +.Nm dwarf_set_frame_undefined_value +.Nd set internal register rule table parameters +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Half +.Fo dwarf_set_frame_cfa_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_rule_initial_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_rule_table_size +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_same_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_undefined_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Sh DESCRIPTION +These functions set the parameters of the internal register +rule table. +.Pp +Argument +.Fa dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Fa value +should hold the parameter value to set. +.Pp +Function +.Fn dwarf_set_frame_cfa_value +sets the column number for the CFA register rule in the internal +register rule table. +The constant +.Dv DW_FRAME_CFA_COL +is the default CFA register column number for DWARF2-only +interfaces, and the constant +.Dv DW_FRAME_CFA_COL3 +is the default CFA column number for DWARF3-compatible interfaces. +.Pp +Function +.Fn dwarf_set_frame_rule_initial_value +sets the initial value of the register rules in the internal register +rule table. +The default initial value is the constant +.Dv DW_FRAME_REG_INITIAL_VALUE , +defined in the header file +.In libdwarf.h . +.Pp +Function +.Fn dwarf_set_frame_rule_table_size +sets the maxmium number of columns of the internal register rule table. +Argument +.Fa value +should be at least as large as the number of real registers in the ABI. +.Pp +Function +.Fn dwarf_set_frame_same_value +sets the register number representing the +.Dq "same value" +register rule. +The default register number for the +.Dq "same value" +rule is the constant +.Dv DW_FRAME_SAME_VAL , +defined in the header file +.In libdwarf.h . +.Pp +Function +.Fn dwarf_set_frame_undefined_value +sets the register number representing the +.Dq undefined +register rule. +The default register number for the +.Dq undefined +rule is the constant +.Dv DW_FRAME_UNDEFINED_VAL , +defined in the header file +.In libdwarf.h . +.Sh RETURN VALUES +These functions return the previous value of the parameter being +set. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 new file mode 100644 index 0000000000..613e7e482e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_set_reloc_application.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd February 11, 2015 +.Dt DWARF_SET_RELOC_APPLICATION 3 +.Os +.Sh NAME +.Nm dwarf_set_reloc_application +.Nd set a library-wide relocation flag +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_set_reloc_application +.Fa "int apply" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_set_reloc_application +allows applications to specify how relocation information is to be +handled by the DWARF(3) library. +.Pp +If the argument +.Fa apply +holds a non-zero value, the library will process all the relevant +.Dq ".rel" +and +.Dq ".rela" +relocation sections and will apply the relocation records found to +their corresponding DWARF sections. +.Pp +If the argument +.Fa apply +is zero, the library will not attempt to apply any relocations. +.Pp +The default behaviour of the library is to process relocation records. +.Sh NOTES +Function +.Fn dwarf_set_reloc_application +should be called before initialising a dwarf debugging context, i.e, +it should be called by the application before calling either of the +functions +.Xr dwarf_init 3 +or +.Xr dwarf_elf_init 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_set_reloc_application +returns the previous value of the library-wide relocation application +flag. +.Sh ERRORS +Function +.Fn dwarf_set_reloc_application +does not return an error. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_elf_init 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 b/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 new file mode 100644 index 0000000000..47d290d96c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_seterrarg.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd May 01, 2010 +.Dt DWARF_SETERRARG 3 +.Os +.Sh NAME +.Nm dwarf_seterrarg , +.Nm dwarf_seterrhand +.Nd configure error handling +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Ptr +.Fn dwarf_seterrarg "Dwarf_Debug dbg" "Dwarf_Ptr arg" +.Ft Dwarf_Handler +.Fn dwarf_seterrhand "Dwarf_Debug dbg" "Dwarf_Handler handler" +.Sh DESCRIPTION +These functions may be used by applications to configure error handling +callbacks. +The error handling scheme used by the library is described in +.Xr dwarf 3 . +.Pp +Function +.Fn dwarf_seterrarg +may be used to set the callback argument passed to a configured +error handler at the time it is invoked. +Argument +.Fa arg +is the callback argument being set. +Argument +.Fa dbg +can be a debug context allocated by a prior call to +.Xr dwarf_init 3 , +or can be +.Dv NULL +to indicate that the library-wide callback argument +is to be set. +.Pp +Function +.Fn dwarf_seterrhand +may be used to associate an error handler denoted by argument +.Fa handler +with the DWARF debug context descriptor denoted by argument +.Fa dbg . +Argument +.Fa dbg +should be a debug context allocated by a prior call to +.Xr dwarf_init 3 , +or may be +.Dv NULL +to indicate that the library-wide error handler +is to be set. +.Sh RETURN VALUES +Function +.Fn dwarf_seterrhand +returns the previous error handler associated with argument +.Fa dbg . +If argument +.Fa dbg +is +.Dv NULL , +function +.Fn dwarf_seterrhand +returns the previous library-wide error handler. +.Pp +Function +.Fn dwarf_seterrarg +returns the previous callback argument associated with argument +.Fa dbg . +If argument +.Fa dbg +is +.Dv NULL , +function +.Fn dwarf_seterrarg +returns the previous library-wide callback argument. +.Sh COMPATIBILITY +The behavior of these functions when argument +.Fa dbg +is +.Dv NULL +is a local extension. +.Sh ERRORS +These functions do not set an error code. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_seterror.c b/contrib/elftoolchain/libdwarf/dwarf_seterror.c new file mode 100644 index 0000000000..b93062b876 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_seterror.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_seterror.c 3902 2020-11-24 21:17:41Z jkoshy $"); + +#define _SET_FIELD(R, F, V) \ + do { \ + (R) = (F); \ + (F) = (V); \ + } while (/* CONSTCOND */ 0) + +#define SET_FIELD(D, R, F) \ + do { \ + if (D) \ + _SET_FIELD(R, (D)->dbg_##F, F); \ + else \ + _SET_FIELD(R, _libdwarf.F, F); \ + } while (/* CONSTCOND */ 0) + +Dwarf_Handler +dwarf_seterrhand(Dwarf_Debug dbg, Dwarf_Handler errhand) +{ + Dwarf_Handler oldhandler; + + SET_FIELD(dbg, oldhandler, errhand); + + return (oldhandler); +} + +Dwarf_Ptr +dwarf_seterrarg(Dwarf_Debug dbg, Dwarf_Ptr errarg) +{ + Dwarf_Ptr oldarg; + + SET_FIELD(dbg, oldarg, errarg); + + return (oldarg); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 b/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 new file mode 100644 index 0000000000..9d14c1bc69 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 @@ -0,0 +1,107 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_srcfiles.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 28, 2010 +.Dt DWARF_SRCFILES 3 +.Os +.Sh NAME +.Nm dwarf_srcfiles +.Nd retrieve source file information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_srcfiles +.Fa "Dwarf_Die die" +.Fa "char ***filenames" +.Fa "Dwarf_Signed *filenamecount" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_srcfiles +returns the source file names associated with a compilation unit. +Source file names are returned as an array of NUL-terminated strings. +.Pp +Argument +.Fa die +should reference a DWARF debugging information entry descriptor with +source file information, see +.Xr dwarf 3 . +Argument +.Fa filenames +should point to a location that will hold a pointer to the returned array +of file names. +Argument +.Fa filenamecount +should point to a location that will hold the number of file names returned. +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Ss Memory Management +The memory areas used for the file names and for array of pointers +being returned are managed by the DWARF(3) library. +The application should not attempt to directly free these memory areas. +Portable code should indicate that the memory areas are to be freed +by using +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_srcfiles +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_srcfiles +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa die , +.Fa filenames +or +.Fa filenamecount +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The compilation unit referenced by argument +.Fa die +does not have associated source file information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_srclines 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_srclines.3 b/contrib/elftoolchain/libdwarf/dwarf_srclines.3 new file mode 100644 index 0000000000..fabf42aa99 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_srclines.3 @@ -0,0 +1,165 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: dwarf_srclines.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_SRCLINES 3 +.Os +.Sh NAME +.Nm dwarf_srclines +.Nd retrieve line number information for a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_srclines +.Fa "Dwarf_Die die" +.Fa "Dwarf_Line **lines" +.Fa "Dwarf_Signed *nlines" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_srclines +returns line number information associated with a compilation unit. +Line number information is returned as an array of +.Vt Dwarf_Line +descriptors. +.Pp +Argument +.Fa die +should reference a DWARF debugging information entry descriptor +with line number information, see +.Xr dwarf 3 . +Argument +.Fa lines +should point to a location that will hold a pointer to the returned array +of +.Vt Dwarf_Line +descriptors. +Argument +.Fa nlines +should point to a location that will hold the number of descriptors +returned. +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +The returned +.Vt Dwarf_Line +descriptors may be passed to the other line number functions in the +API set to retrieve specific information about each source line. +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Line +descriptors returned in argument +.Fa lines +is owned by the +.Lb libdwarf . +The application should not attempt to free this pointer. +Portable code should instead use +.Fn dwarf_srclines_dealloc +to indicate that the memory may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_srclines +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To obtain an array of +.Vt Dwarf_Line +descriptors and to retrieve the source file, line number, and virtual address +associated with each descriptor: +.Bd -literal -offset indent +int n; +Dwarf_Die die; +Dwarf_Error de; +char *filename; +Dwarf_Line *lines; +Dwarf_Signed nlines; +Dwarf_Addr lineaddr; +Dwarf_Unsigned lineno; + +/* variable "die" should reference a DIE for a compilation unit */ + +if (dwarf_srclines(die, &lines, &nlines, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_srclines: %s", dwarf_errmsg(de)); + +for (n = 0; n < nlines; n++) { + /* Retrieve the file name for this descriptor. */ + if (dwarf_linesrc(lines[n], &filename, &de)) + errx(EXIT_FAILURE, "dwarf_linesrc: %s", + dwarf_errmsg(de)); + + /* Retrieve the line number in the source file. */ + if (dwarf_lineno(lines[n], &lineno, &de)) + errx(EXIT_FAILURE, "dwarf_lineno: %s", + dwarf_errmsg(de)); + /* Retrieve the virtual address for this line. */ + if (dwarf_lineaddr(lines[n], &lineaddr, &de)) + errx(EXIT_FAILURE, "dwarf_lineaddr: %s", + dwarf_errmsg(de)); + } +.Ed +.Sh ERRORS +Function +.Fn dwarf_srclines +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Fa die , +.Fa lines +or +.Fa nlines +was +.Dv NULL . +.It Bq Er DW_DLE_NO_ENTRY +The compilation unit referenced by argument +.Fa die +does not have associated line number information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_line_srcfileno 3 , +.Xr dwarf_lineaddr 3 , +.Xr dwarf_linebeginstatement 3 , +.Xr dwarf_lineblock 3 , +.Xr dwarf_lineendsequence 3 , +.Xr dwarf_lineno 3 , +.Xr dwarf_lineoff 3 , +.Xr dwarf_linesrc 3 , +.Xr dwarf_srcfiles 3 , +.Xr dwarf_srclines_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 b/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 new file mode 100644 index 0000000000..9680174c9a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 @@ -0,0 +1,107 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_start_macro_file.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 25, 2011 +.Dt DWARF_START_MACRO_FILE 3 +.Os +.Sh NAME +.Nm dwarf_start_macro_file +.Nd mark the start of a source file inclusion +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_start_macro_file +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "Dwarf_Unsigned fileindex" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_start_macro_file +marks the start of a new source file inclusion. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa lineno +specifies the line number of the source line where the source +file inclusion occurs. +A value of zero is used to indicate the file for the compilation unit +source itself. +.Pp +Argument +.Fa fileindex +specifies the index of the source file that is being included. +Valid source file indices are those returned by +.Xr dwarf_add_file_decl 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_start_macro_file +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_start_macro_file +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_start_macro_file +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_str.c b/contrib/elftoolchain/libdwarf/dwarf_str.c new file mode 100644 index 0000000000..c402f21819 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_str.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_str.c 3295 2016-01-08 22:08:10Z jkoshy $"); + +int +dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, + Dwarf_Signed *ret_strlen, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if (dbg == NULL || string == NULL || ret_strlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ds = _dwarf_find_section(dbg, ".debug_str"); + if (ds == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (offset > ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (offset == ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *string = (char *) ds->ds_data + offset; + *ret_strlen = strlen(*string); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_tag.3 b/contrib/elftoolchain/libdwarf/dwarf_tag.3 new file mode 100644 index 0000000000..26158cf46a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_tag.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_tag.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd April 14, 2010 +.Dt DWARF_TAG 3 +.Os +.Sh NAME +.Nm dwarf_tag +.Nd retrieve the tag associated with a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_tag "Dwarf_Die die" "Dwarf_Half *tag" "Dwarf_Error *err" +.Sh DESCRIPTION +Function +.Fn dwarf_tag +retrieves the tag associated with the debugging information entry +referenced by argument +.Fa die , +and stores it into the location pointed to by argument +.Fa tag . +.Pp +If argument +.Fa err +if +.No non- Ns Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_tag +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_tag +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va die +or +.Va tag +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_die_abbrev_code 3 , +.Xr dwarf_diename 3 , +.Xr dwarf_dieoffset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 b/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 new file mode 100644 index 0000000000..ce4d736287 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_transform_to_disk_form.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd August 25, 2011 +.Dt DWARF_TRANSFORM_TO_DISK_FORM 3 +.Os +.Sh NAME +.Nm dwarf_transform_to_disk_form +.Nd transform DWARF information into byte streams +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Signed +.Fo dwarf_transform_to_disk_form +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_transform_to_disk_form +transforms the DWARF information gathered by the producer into +byte streams for the application to write out as ELF sections. +If the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +is set on the producer, the function will also generate the associated +relocation arrays. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +After a call to this function, the application can call the function +.Xr dwarf_get_section_bytes 3 +to retrieve the byte streams for each ELF section. +If the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was set on the descriptor, the application can also call the function +.Xr dwarf_get_relocation_info 3 +to retrieve the generated relocation arrays. +.Sh RETURN VALUES +On success, function +.Fn dwarf_transform_to_disk_form +returns the total number of ELF sections generated. +In case of an error, function +.Fn dwarf_transform_to_disk_form +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_transform_to_disk_form +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Fa dbg +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_get_section_bytes 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_types.m4 b/contrib/elftoolchain/libdwarf/dwarf_types.m4 new file mode 100644 index 0000000000..ddab7f13d4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_types.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_types.m4 2697 2012-11-24 17:12:36Z kaiwang27 $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(type,Type,type,typenames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 b/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 new file mode 100644 index 0000000000..d9200672a1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_undef_macro.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt DWARF_UNDEF_MACRO 3 +.Os +.Sh NAME +.Nm dwarf_undef_macro +.Nd record the removal of a macro definition +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_undef_macro +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_undef_macro +records the removal of a macro definition in a DWARF producer +instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa lineno +specifies the line number of the source line where the macro +definition was removed. +A value of zero indicates that the macro definition was removed before +any source files were read. +.Pp +Argument +.Fa name +should point to a NUL-terminated string containing the name +of the macro. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_undef_macro +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_undef_macro +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh EXAMPLES +To record the fact that the macro named +.Dv _STDIO_H_ +was removed at line 220 of the current macro file, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; + +/* ... Assume 'dbg' refers to a DWARF producer instance... */ +if (dwarf_undef_macro(dbg, 220, "_STDIO_H_", &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_undef_macro +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Fa dbg +or +.Fa name +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_vars.m4 b/contrib/elftoolchain/libdwarf/dwarf_vars.m4 new file mode 100644 index 0000000000..b512fdf3f5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_vars.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_vars.m4 2075 2011-10-27 03:47:28Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(var,Var,var,static_vars) diff --git a/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 b/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 new file mode 100644 index 0000000000..f71dcd6a6d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_vendor_ext.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd September 25, 2011 +.Dt DWARF_VENDOR_EXT 3 +.Os +.Sh NAME +.Nm dwarf_vendor_ext +.Nd add vendor-specific macro information to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_vendor_ext +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned constant" +.Fa "char *string" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_vendor_ext +adds a vendor-specific macro information entry to a DWARF producer +instance. +.Pp +Argument +.Fa dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Fa constant +specifies a constant value for the macro information entry. +.Pp +Argument +.Fa string +point to a NUL-terminated string containing the string value +for the macro information entry. +.Pp +If argument +.Fa err +is not +.Dv NULL , +it will be used to store error information in case of an error. +.Pp +The meaning of the arguments +.Fa constant +and +.Fa string +are not defined by the DWARF specification, but are instead governed +by application and vendor conventions. +.Sh RETURN VALUES +On success, function +.Fn dwarf_vendor_ext +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_vendor_ext +returns +.Dv DW_DLV_ERROR +and sets the argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_vendor_ext +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Fa dbg +or +.Fa string +was +.Dv NULL . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 b/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 new file mode 100644 index 0000000000..7ae335ea98 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_weaks.m4 2075 2011-10-27 03:47:28Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(weak,Weak,weak,weaknames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 new file mode 100644 index 0000000000..598e9dee01 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 @@ -0,0 +1,81 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_whatattr.3 3963 2022-03-12 16:07:32Z jkoshy $ +.\" +.Dd May 22, 2010 +.Dt DWARF_WHATATTR 3 +.Os +.Sh NAME +.Nm dwarf_whatattr +.Nd retrieve the attribute code for a DWARF attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_whatattr +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retcode" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_whatattr +retrieves the attribute code for the DWARF attribute referenced +by argument +.Fa attr , +and writes it to the location pointed to by argument +.Fa retcode . +If argument +.Fa err +is not +.Dv NULL , +it will be used to return an error descriptor in case of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_whatattr +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Fa err . +.Sh ERRORS +Function +.Fn dwarf_whatattr +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of argument +.Va attr +or +.Va retcode +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/libdwarf.c b/contrib/elftoolchain/libdwarf/libdwarf.c new file mode 100644 index 0000000000..b2406cb73f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf.c 3161 2015-02-15 21:43:36Z emaste $"); + +struct _libdwarf_globals _libdwarf = { + .errhand = NULL, + .errarg = NULL, + .applyreloc = 1 +}; diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h new file mode 100644 index 0000000000..2754461904 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf.h @@ -0,0 +1,853 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011,2014,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: libdwarf.h 4019 2023-10-22 03:06:17Z kaiwang27 $ + */ + +#ifndef _LIBDWARF_H_ +#define _LIBDWARF_H_ + +#include + +typedef int Dwarf_Bool; +typedef uint64_t Dwarf_Off; +typedef uint64_t Dwarf_Unsigned; +typedef uint16_t Dwarf_Half; +typedef uint8_t Dwarf_Small; +typedef int64_t Dwarf_Signed; +typedef uint64_t Dwarf_Addr; +typedef void *Dwarf_Ptr; + +typedef struct _Dwarf_Abbrev *Dwarf_Abbrev; +typedef struct _Dwarf_Arange *Dwarf_Arange; +typedef struct _Dwarf_ArangeSet *Dwarf_ArangeSet; +typedef struct _Dwarf_Attribute *Dwarf_Attribute; +typedef struct _Dwarf_Attribute *Dwarf_P_Attribute; +typedef struct _Dwarf_AttrDef *Dwarf_AttrDef; +typedef struct _Dwarf_Cie *Dwarf_Cie; +typedef struct _Dwarf_Cie *Dwarf_P_Cie; +typedef struct _Dwarf_Debug *Dwarf_Debug; +typedef struct _Dwarf_Debug *Dwarf_P_Debug; +typedef struct _Dwarf_Die *Dwarf_Die; +typedef struct _Dwarf_Die *Dwarf_P_Die; +typedef struct _Dwarf_Fde *Dwarf_Fde; +typedef struct _Dwarf_Fde *Dwarf_P_Fde; +typedef struct _Dwarf_FrameSec *Dwarf_FrameSec; +typedef struct _Dwarf_Line *Dwarf_Line; +typedef struct _Dwarf_LineFile *Dwarf_LineFile; +typedef struct _Dwarf_LineInfo *Dwarf_LineInfo; +typedef struct _Dwarf_MacroSet *Dwarf_MacroSet; +typedef struct _Dwarf_NamePair *Dwarf_NamePair; +typedef struct _Dwarf_NamePair *Dwarf_Func; +typedef struct _Dwarf_NamePair *Dwarf_Global; +typedef struct _Dwarf_NamePair *Dwarf_Type; +typedef struct _Dwarf_NamePair *Dwarf_Var; +typedef struct _Dwarf_NamePair *Dwarf_Weak; +typedef struct _Dwarf_NameTbl *Dwarf_NameTbl; +typedef struct _Dwarf_NameSec *Dwarf_NameSec; +typedef struct _Dwarf_P_Expr *Dwarf_P_Expr; +typedef struct _Dwarf_Rangelist *Dwarf_Rangelist; + +typedef enum { + DW_OBJECT_MSB, + DW_OBJECT_LSB +} Dwarf_Endianness; + +typedef struct { + Dwarf_Addr addr; + Dwarf_Unsigned size; + const char *name; +} Dwarf_Obj_Access_Section; + +typedef struct { + int (*get_section_info)(void *_obj, Dwarf_Half _index, + Dwarf_Obj_Access_Section *_ret_section, int *_error); + Dwarf_Endianness (*get_byte_order)(void *_obj); + Dwarf_Small (*get_length_size)(void *_obj); + Dwarf_Small (*get_pointer_size)(void *_obj); + Dwarf_Unsigned (*get_section_count)(void *_obj); + int (*load_section)(void *_obj, Dwarf_Half _index, + Dwarf_Small **_ret_data, int *_error); +} Dwarf_Obj_Access_Methods; + +typedef struct { + void *object; + const Dwarf_Obj_Access_Methods *methods; +} Dwarf_Obj_Access_Interface; + +typedef int (*Dwarf_Callback_Func)(char *_name, int _size, + Dwarf_Unsigned _type, Dwarf_Unsigned _flags, Dwarf_Unsigned _link, + Dwarf_Unsigned _info, int *_index, int *_error); + +typedef int (*Dwarf_Callback_Func_b)(char *_name, int _size, + Dwarf_Unsigned _type, Dwarf_Unsigned _flags, Dwarf_Unsigned _link, + Dwarf_Unsigned _info, Dwarf_Unsigned *_index, int *_error); + +typedef Dwarf_Unsigned Dwarf_Tag; + +typedef struct { + Dwarf_Small lr_atom; + Dwarf_Unsigned lr_number; + Dwarf_Unsigned lr_number2; + Dwarf_Unsigned lr_offset; +} Dwarf_Loc; + +typedef struct { + Dwarf_Addr ld_lopc; + Dwarf_Addr ld_hipc; + Dwarf_Half ld_cents; + Dwarf_Loc *ld_s; +} Dwarf_Locdesc; + +typedef struct { + char signature[8]; +} Dwarf_Sig8; + +typedef struct { + unsigned char fd_data[16]; +} Dwarf_Form_Data16; + +typedef struct { + Dwarf_Unsigned bl_len; + Dwarf_Ptr bl_data; +} Dwarf_Block; + +enum Dwarf_Ranges_Entry_Type { + DW_RANGES_ENTRY, + DW_RANGES_ADDRESS_SELECTION, + DW_RANGES_END +}; + +typedef struct { + Dwarf_Unsigned dwr_addr1; + Dwarf_Unsigned dwr_addr2; + enum Dwarf_Ranges_Entry_Type dwr_type; +} Dwarf_Ranges; + +enum Dwarf_Form_Class { + DW_FORM_CLASS_UNKNOWN, + DW_FORM_CLASS_ADDRESS, + DW_FORM_CLASS_BLOCK, + DW_FORM_CLASS_CONSTANT, + DW_FORM_CLASS_EXPRLOC, + DW_FORM_CLASS_FLAG, + DW_FORM_CLASS_LINEPTR, + DW_FORM_CLASS_LOCLISTPTR, + DW_FORM_CLASS_MACPTR, + DW_FORM_CLASS_RANGELISTPTR, + DW_FORM_CLASS_REFERENCE, + DW_FORM_CLASS_STRING +}; + +#ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER +#define DW_FRAME_HIGHEST_NORMAL_REGISTER 63 +#endif + +#define DW_FRAME_RA_COL (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1) +#define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2) + +#ifndef DW_FRAME_LAST_REG_NUM +#define DW_FRAME_LAST_REG_NUM (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3) +#endif + +#ifndef DW_FRAME_REG_INITIAL_VALUE +#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL +#endif + +#define DW_FRAME_UNDEFINED_VAL 1034 +#define DW_FRAME_SAME_VAL 1035 +#define DW_FRAME_CFA_COL3 1436 + +#define DW_EXPR_OFFSET 0 +#define DW_EXPR_VAL_OFFSET 1 +#define DW_EXPR_EXPRESSION 2 +#define DW_EXPR_VAL_EXPRESSION 3 + +/* + * Frame operation only for DWARF 2. + */ + +#define DW_FRAME_CFA_COL 0 + +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Signed fp_offset; + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op; + +#ifndef DW_REG_TABLE_SIZE +#define DW_REG_TABLE_SIZE 66 +#endif + +typedef struct { + struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Half dw_regnum; + Dwarf_Addr dw_offset; + } rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable; + +/* + * Frame operation for DWARF 3 and DWARF 2. + */ + +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Unsigned fp_offset_or_block_len; + Dwarf_Small *fp_expr_block; + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op3; + +typedef struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; +} Dwarf_Regtable_Entry3; + +typedef struct { + Dwarf_Regtable_Entry3 rt3_cfa_rule; + Dwarf_Half rt3_reg_table_size; + Dwarf_Regtable_Entry3 *rt3_rules; +} Dwarf_Regtable3; + +typedef struct { + Dwarf_Off dmd_offset; + Dwarf_Small dmd_type; + Dwarf_Signed dmd_lineno; + Dwarf_Signed dmd_fileindex; + char *dmd_macro; +} Dwarf_Macro_Details; + +/* + * Symbols denoting allocation types, for use with dwarf_dealloc(3). + */ + +enum Dwarf_Allocation_Type { + DW_DLA_ABBREV, + DW_DLA_ADDR, + DW_DLA_ARANGE, + DW_DLA_ATTR, + DW_DLA_BLOCK, + DW_DLA_BOUNDS, + DW_DLA_CIE, + DW_DLA_DEBUG, + DW_DLA_DIE, + DW_DLA_ELLIST, + DW_DLA_ERROR, + DW_DLA_FDE, + DW_DLA_FRAME_BLOCK, + DW_DLA_FRAME_OP, + DW_DLA_FUNC, + DW_DLA_GLOBAL, + DW_DLA_LINE, + DW_DLA_LINEBUF, + DW_DLA_LIST, + DW_DLA_LOC, + DW_DLA_LOCDESC, + DW_DLA_LOC_BLOCK, + DW_DLA_RANGES, + DW_DLA_STRING, + DW_DLA_SUBSCR, + DW_DLA_TYPE, + DW_DLA_TYPENAME, + DW_DLA_VAR, + DW_DLA_WEAK +}; + +/* + * Relocation Type. + */ +enum Dwarf_Rel_Type { + dwarf_drt_none = 0, + dwarf_drt_data_reloc, + dwarf_drt_segment_rel, + dwarf_drt_first_of_length_pair, + dwarf_drt_second_of_length_pair +}; + +/* + * Relocation Entry. + */ +typedef struct Dwarf_Relocation_Data_s { + unsigned char drd_type; + unsigned char drd_length; + Dwarf_Unsigned drd_offset; + Dwarf_Unsigned drd_symbol_index; +} *Dwarf_Relocation_Data; + +#define DWARF_DRD_BUFFER_VERSION 2 + +/* + * Error numbers which are specific to this implementation. + */ +enum { + DW_DLE_NONE, /* No error. */ + DW_DLE_ERROR, /* An error! */ + DW_DLE_ARGUMENT, /* Invalid argument. */ + DW_DLE_DEBUG_INFO_NULL, /* Debug info NULL. */ + DW_DLE_NO_ENTRY, /* No entry. */ + DW_DLE_MEMORY, /* Insufficient memory. */ + DW_DLE_ELF, /* ELF error. */ + DW_DLE_CU_LENGTH_ERROR, /* Invalid compilation unit data. */ + DW_DLE_VERSION_STAMP_ERROR, /* Invalid version. */ + DW_DLE_DEBUG_ABBREV_NULL, /* Abbrev not found. */ + DW_DLE_DIE_NO_CU_CONTEXT, /* No current compilation unit. */ + DW_DLE_LOC_EXPR_BAD, /* Invalid location expression. */ + DW_DLE_EXPR_LENGTH_BAD, /* Invalid DWARF expression. */ + DW_DLE_DEBUG_LOC_SECTION_SHORT, /* Loclist section too short. */ + DW_DLE_ATTR_FORM_BAD, /* Invalid attribute form. */ + DW_DLE_DEBUG_LINE_LENGTH_BAD, /* Line info section too short. */ + DW_DLE_LINE_FILE_NUM_BAD, /* Invalid file number. */ + DW_DLE_DIR_INDEX_BAD, /* Invalid dir index. */ + DW_DLE_DEBUG_FRAME_LENGTH_BAD, /* Frame section too short. */ + DW_DLE_NO_CIE_FOR_FDE, /* CIE not found for certain FDE. */ + DW_DLE_FRAME_AUGMENTATION_UNKNOWN, /* Unknown CIE augmentation. */ + DW_DLE_FRAME_INSTR_EXEC_ERROR, /* Frame instruction exec error. */ + DW_DLE_FRAME_VERSION_BAD, /* Invalid frame section version. */ + DW_DLE_FRAME_TABLE_COL_BAD, /* Invalid table column. */ + DW_DLE_DF_REG_NUM_TOO_HIGH, /* Insufficient regtable space. */ + DW_DLE_PC_NOT_IN_FDE_RANGE, /* PC requested not in the FDE range. */ + DW_DLE_ARANGE_OFFSET_BAD, /* Invalid arange offset. */ + DW_DLE_DEBUG_MACRO_INCONSISTENT,/* Invalid macinfo data. */ + DW_DLE_ELF_SECT_ERR, /* Application callback failed. */ + DW_DLE_DIR_COUNT_BAD, /* Invalid directory count. */ + DW_DLE_FILE_COUNT_BAD, /* Invalid filename count. */ + DW_DLE_LNCT_DESC_BAD, /* Invalid LNCT descriptor. */ + DW_DLE_NUM /* Max error number. */ +}; + +/* + * Mapping of SGI libdwarf error codes for comptibility. + */ +#define DW_DLE_DBG_ALLOC DW_DLE_MEMORY +#define DW_DLE_ALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_SECT_ALLOC DW_DLE_MEMORY +#define DW_DLE_FILE_ENTRY_ALLOC DW_DLE_MEMORY +#define DW_DLE_LINE_ALLOC DW_DLE_MEMORY +#define DW_DLE_FPGM_ALLOC DW_DLE_MEMORY +#define DW_DLE_INCDIR_ALLOC DW_DLE_MEMORY +#define DW_DLE_STRING_ALLOC DW_DLE_MEMORY +#define DW_DLE_CHUNK_ALLOC DW_DLE_MEMORY +#define DW_DLE_CIE_ALLOC DW_DLE_MEMORY +#define DW_DLE_FDE_ALLOC DW_DLE_MEMORY +#define DW_DLE_CIE_OFFS_ALLOC DW_DLE_MEMORY +#define DW_DLE_DIE_ALLOC DW_DLE_MEMORY +#define DW_DLE_ATTR_ALLOC DW_DLE_MEMORY +#define DW_DLE_ABBREV_ALLOC DW_DLE_MEMORY +#define DW_DLE_ADDR_ALLOC DW_DLE_MEMORY +#define DW_DLE_REL_ALLOC DW_DLE_MEMORY +#define DW_DLE_MACINFO_MALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE DW_DLE_MEMORY +#define DW_DLE_DF_ALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_RELOC_SECTION_MALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_DBG_NULL DW_DLE_ARGUMENT +#define DW_DLE_DIE_NULL DW_DLE_ARGUMENT +#define DW_DLE_FDE_NULL DW_DLE_ARGUMENT +#define DW_DLE_CIE_NULL DW_DLE_ARGUMENT +#define DW_DLE_ATTR_NULL DW_DLE_ARGUMENT +#define DW_DLE_GLOBAL_NULL DW_DLE_ARGUMENT +#define DW_DLE_ARANGES_NULL DW_DLE_ARGUMENT +#define DW_DLE_ARANGE_NULL DW_DLE_ARGUMENT +#define DW_DLE_EXPR_NULL DW_DLE_ARGUMENT +#define DW_DLE_FUNC_NULL DW_DLE_ARGUMENT +#define DW_DLE_TYPE_NULL DW_DLE_ARGUMENT +#define DW_DLE_VAR_NULL DW_DLE_ARGUMENT +#define DW_DLE_WEAK_NULL DW_DLE_ARGUMENT +#define DW_DLE_ELF_BEGIN_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETEHDR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETSHDR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_STRPTR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_SECT_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETIDENT_ERROR DW_DLE_ELF + +typedef struct _Dwarf_Error { + int err_error; /* DWARF error. */ + int err_elferror; /* ELF error. */ + const char *err_func; /* Function name where error occurred. */ + int err_line; /* Line number where error occurred. */ + char err_msg[1024]; /* Formatted error message. */ +} Dwarf_Error; + +/* + * Dwarf error handler. + */ +typedef void (*Dwarf_Handler)(Dwarf_Error, Dwarf_Ptr); + +#define dwarf_errno(error) error.err_error +#define dwarf_errmsg(error) dwarf_errmsg_(&error) + +/* + * Return values which have to be compatible with other + * implementations of libdwarf. + */ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 +#define DW_DLV_BADADDR NULL +#define DW_DLV_NOCOUNT ((Dwarf_Signed) -1) + +/* + * Access modes. + */ +#define DW_DLC_READ 0x0001 +#define DW_DLC_WRITE 0x0002 +#define DW_DLC_RDWR 0x0004 + +/* + * Flags used by libdwarf producer. + */ +#define DW_DLC_SIZE_64 0x40000000 +#define DW_DLC_SIZE_32 0x20000000 +#define DW_DLC_OFFSET_SIZE_64 0x10000000 +#define DW_DLC_ISA_MIPS 0x80000000 +#define DW_DLC_ISA_IA64 0x01000000 +#define DW_DLC_STREAM_RELOCATIONS 0x02000000 +#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 +#define DW_DLC_TARGET_BIGENDIAN 0x08000000 +#define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 + +/* + * Instruction set architectures supported by this implementation. + */ +enum Dwarf_ISA { + DW_ISA_ARM, + DW_ISA_IA64, + DW_ISA_MIPS, + DW_ISA_PPC, + DW_ISA_SPARC, + DW_ISA_X86, + DW_ISA_X86_64, + DW_ISA_AARCH64, + DW_ISA_RISCV, + DW_ISA_MAX +}; + +/* Function prototype definitions. */ +#ifdef __cplusplus +extern "C" { +#endif +Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die, Dwarf_Signed, + Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_dataref(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Small, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_P_Expr, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_P_Die, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Signed, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Signed, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Signed, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_die_to_debug(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug, char *, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr, Dwarf_Unsigned, + Dwarf_Signed, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr, Dwarf_Small, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde, Dwarf_Small, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug, char *, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug, char *, Dwarf_Small, + Dwarf_Small, Dwarf_Small, Dwarf_Ptr, Dwarf_Unsigned, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug, Dwarf_P_Fde, Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug, Dwarf_P_Fde, Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_funcname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug, Dwarf_Unsigned, + Dwarf_Addr, Dwarf_Unsigned, Dwarf_Signed, Dwarf_Bool, + Dwarf_Bool, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_pubname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_typename(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_varname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_weakname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +int dwarf_arrayorder(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *, + Dwarf_Error *); +int dwarf_attrlist(Dwarf_Die, Dwarf_Attribute **, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_attroffset(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *); +int dwarf_attrval_flag(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_attrval_signed(Dwarf_Die, Dwarf_Half, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_attrval_string(Dwarf_Die, Dwarf_Half, const char **, + Dwarf_Error *); +int dwarf_attrval_unsigned(Dwarf_Die, Dwarf_Half, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_bitoffset(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_bitsize(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_bytesize(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_child(Dwarf_Die, Dwarf_Die *, Dwarf_Error *); +void dwarf_dealloc(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned); +int dwarf_def_macro(Dwarf_P_Debug, Dwarf_Unsigned, char *, char *, + Dwarf_Error *); +int dwarf_die_CU_offset(Dwarf_Die, Dwarf_Off *, Dwarf_Error *); +int dwarf_die_CU_offset_range(Dwarf_Die, Dwarf_Off *, Dwarf_Off *, + Dwarf_Error *); +int dwarf_die_abbrev_code(Dwarf_Die); +Dwarf_P_Die dwarf_die_link(Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die, Dwarf_Error *); +int dwarf_diename(Dwarf_Die, char **, Dwarf_Error *); +int dwarf_dieoffset(Dwarf_Die, Dwarf_Off *, Dwarf_Error *); +int dwarf_elf_init(Elf *, int, Dwarf_Handler, Dwarf_Ptr, + Dwarf_Debug *, Dwarf_Error *); +int dwarf_end_macro_file(Dwarf_P_Debug, Dwarf_Error *); +const char *dwarf_errmsg_(Dwarf_Error *); +int dwarf_expand_frame_instructions(Dwarf_Cie, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Frame_Op **, Dwarf_Signed *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr, Dwarf_Error *); +Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Unsigned *, + Dwarf_Error *); +Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde, Dwarf_Unsigned, Dwarf_Signed, + Dwarf_Error *); +void dwarf_fde_cie_list_dealloc(Dwarf_Debug, Dwarf_Cie *, + Dwarf_Signed, Dwarf_Fde *, Dwarf_Signed); +char *dwarf_find_macro_value_start(char *); +int dwarf_finish(Dwarf_Debug, Dwarf_Error *); +int dwarf_formaddr(Dwarf_Attribute, Dwarf_Addr *, Dwarf_Error *); +int dwarf_formblock(Dwarf_Attribute, Dwarf_Block **, Dwarf_Error *); +int dwarf_formexprloc(Dwarf_Attribute, Dwarf_Unsigned *, + Dwarf_Ptr *, Dwarf_Error *); +int dwarf_formflag(Dwarf_Attribute, Dwarf_Bool *, Dwarf_Error *); +int dwarf_formref(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *); +int dwarf_formsdata(Dwarf_Attribute, Dwarf_Signed *, Dwarf_Error *); +int dwarf_formsig8(Dwarf_Attribute, Dwarf_Sig8 *, Dwarf_Error *); +int dwarf_formstring(Dwarf_Attribute, char **, Dwarf_Error *); +int dwarf_formudata(Dwarf_Attribute, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_func_cu_offset(Dwarf_Func, Dwarf_Off *, Dwarf_Error *); +int dwarf_func_die_offset(Dwarf_Func, Dwarf_Off *, + Dwarf_Error *); +int dwarf_func_name_offsets(Dwarf_Func, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_funcname(Dwarf_Func, char **, Dwarf_Error *); +void dwarf_funcs_dealloc(Dwarf_Debug, Dwarf_Func *, Dwarf_Signed); +int dwarf_get_ACCESS_name(unsigned, const char **); +int dwarf_get_ATE_name(unsigned, const char **); +int dwarf_get_AT_name(unsigned, const char **); +int dwarf_get_CC_name(unsigned, const char **); +int dwarf_get_CFA_name(unsigned, const char **); +int dwarf_get_CHILDREN_name(unsigned, const char **); +int dwarf_get_DSC_name(unsigned, const char **); +int dwarf_get_DS_name(unsigned, const char **); +int dwarf_get_EH_name(unsigned, const char **); +int dwarf_get_END_name(unsigned, const char **); +int dwarf_get_FORM_name(unsigned, const char **); +int dwarf_get_ID_name(unsigned, const char **); +int dwarf_get_INL_name(unsigned, const char **); +int dwarf_get_LANG_name(unsigned, const char **); +int dwarf_get_LNE_name(unsigned, const char **); +int dwarf_get_LNS_name(unsigned, const char **); +int dwarf_get_MACINFO_name(unsigned, const char **); +int dwarf_get_OP_name(unsigned, const char **); +int dwarf_get_ORD_name(unsigned, const char **); +int dwarf_get_TAG_name(unsigned, const char **); +int dwarf_get_UT_name(unsigned, const char **); +int dwarf_get_VIRTUALITY_name(unsigned, const char **); +int dwarf_get_VIS_name(unsigned, const char **); +int dwarf_get_abbrev(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Abbrev *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_abbrev_children_flag(Dwarf_Abbrev, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_abbrev_code(Dwarf_Abbrev, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_get_abbrev_entry(Dwarf_Abbrev, Dwarf_Signed, Dwarf_Half *, + Dwarf_Signed *, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_abbrev_tag(Dwarf_Abbrev, Dwarf_Half *, Dwarf_Error *); +int dwarf_get_address_size(Dwarf_Debug, Dwarf_Half *, + Dwarf_Error *); +int dwarf_get_arange(Dwarf_Arange *, Dwarf_Unsigned, Dwarf_Addr, + Dwarf_Arange *, Dwarf_Error *); +int dwarf_get_arange_cu_header_offset(Dwarf_Arange, Dwarf_Off *, + Dwarf_Error *); +int dwarf_get_arange_info(Dwarf_Arange, Dwarf_Addr *, + Dwarf_Unsigned *, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_aranges(Dwarf_Debug, Dwarf_Arange **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_cie_index(Dwarf_Cie, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_cie_info(Dwarf_Cie, Dwarf_Unsigned *, Dwarf_Small *, + char **, Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Half *, + Dwarf_Ptr *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_cie_of_fde(Dwarf_Fde, Dwarf_Cie *, Dwarf_Error *); +int dwarf_get_cu_die_offset(Dwarf_Arange, Dwarf_Off *, + Dwarf_Error *); +int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug, + Dwarf_Off, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug, + Dwarf_Off, Dwarf_Bool, Dwarf_Off *, Dwarf_Error *); +Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die); +int dwarf_get_elf(Dwarf_Debug, Elf **, Dwarf_Error *); +int dwarf_get_fde_at_pc(Dwarf_Fde *, Dwarf_Addr, Dwarf_Fde *, + Dwarf_Addr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_all_regs(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable3 *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde, Dwarf_Addr, + Dwarf_Small *, Dwarf_Signed *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Ptr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_reg(Dwarf_Fde, Dwarf_Half, Dwarf_Addr, + Dwarf_Signed *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_reg3(Dwarf_Fde, Dwarf_Half, Dwarf_Addr, + Dwarf_Small *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Signed *, Dwarf_Ptr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_instr_bytes(Dwarf_Fde, Dwarf_Ptr *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_fde_list(Dwarf_Debug, Dwarf_Cie **, Dwarf_Signed *, + Dwarf_Fde **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_fde_list_eh(Dwarf_Debug, Dwarf_Cie **, Dwarf_Signed *, + Dwarf_Fde **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_fde_n(Dwarf_Fde *, Dwarf_Unsigned, Dwarf_Fde *, + Dwarf_Error *); +int dwarf_get_fde_range(Dwarf_Fde, Dwarf_Addr *, Dwarf_Unsigned *, + Dwarf_Ptr *, Dwarf_Unsigned *, Dwarf_Off *, Dwarf_Signed *, + Dwarf_Off *, Dwarf_Error *); +enum Dwarf_Form_Class dwarf_get_form_class(Dwarf_Half, Dwarf_Half, Dwarf_Half, + Dwarf_Half); +int dwarf_get_funcs(Dwarf_Debug, Dwarf_Func **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_globals(Dwarf_Debug, Dwarf_Global **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_loclist_entry(Dwarf_Debug, Dwarf_Unsigned, + Dwarf_Addr *, Dwarf_Addr *, Dwarf_Ptr *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_macro_details(Dwarf_Debug, Dwarf_Off, Dwarf_Unsigned, + Dwarf_Signed *, Dwarf_Macro_Details **, Dwarf_Error *); +int dwarf_get_pubtypes(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_ranges(Dwarf_Debug, Dwarf_Off, Dwarf_Ranges **, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_ranges_a(Dwarf_Debug, Dwarf_Off, Dwarf_Die, + Dwarf_Ranges **, Dwarf_Signed *, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_get_relocation_info(Dwarf_P_Debug, Dwarf_Signed *, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Relocation_Data *, + Dwarf_Error *); +int dwarf_get_relocation_info_count(Dwarf_P_Debug, Dwarf_Unsigned *, + int *, Dwarf_Error *); +Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug, Dwarf_Signed, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_section_max_offsets(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *); +int dwarf_get_section_max_offsets_b(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *); +int dwarf_get_str(Dwarf_Debug, Dwarf_Off, char **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_types(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_vars(Dwarf_Debug, Dwarf_Var **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_weaks(Dwarf_Debug, Dwarf_Weak **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_global_cu_offset(Dwarf_Global, Dwarf_Off *, Dwarf_Error *); +int dwarf_global_die_offset(Dwarf_Global, Dwarf_Off *, + Dwarf_Error *); +int dwarf_global_formref(Dwarf_Attribute, Dwarf_Off *, + Dwarf_Error *); +int dwarf_global_name_offsets(Dwarf_Global, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +void dwarf_globals_dealloc(Dwarf_Debug, Dwarf_Global *, Dwarf_Signed); +int dwarf_globname(Dwarf_Global, char **, Dwarf_Error *); +int dwarf_hasattr(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_hasform(Dwarf_Attribute, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_highpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +int dwarf_highpc_b(Dwarf_Die, Dwarf_Addr *, Dwarf_Half *, + enum Dwarf_Form_Class *, Dwarf_Error *); +int dwarf_init(int, int, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *, + Dwarf_Error *); +int dwarf_line_srcfileno(Dwarf_Line, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_lineaddr(Dwarf_Line, Dwarf_Addr *, Dwarf_Error *); +int dwarf_linebeginstatement(Dwarf_Line, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_lineblock(Dwarf_Line, Dwarf_Bool *, Dwarf_Error *); +int dwarf_lineendsequence(Dwarf_Line, Dwarf_Bool *, Dwarf_Error *); +int dwarf_lineno(Dwarf_Line, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_lineoff(Dwarf_Line, Dwarf_Signed *, Dwarf_Error *); +int dwarf_linesrc(Dwarf_Line, char **, Dwarf_Error *); +Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Error *); +int dwarf_loclist(Dwarf_Attribute, Dwarf_Locdesc **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_loclist_from_expr(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, + Dwarf_Locdesc **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_from_expr_a(Dwarf_Debug, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Half, Dwarf_Locdesc **, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_from_expr_b(Dwarf_Debug, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Half, Dwarf_Half, + Dwarf_Small, Dwarf_Locdesc **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_loclist_n(Dwarf_Attribute, Dwarf_Locdesc ***, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_lowpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug, Dwarf_Tag, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, Dwarf_Error *); +Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug, Dwarf_Error *); +int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_cu_header_b(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_cu_header_c(Dwarf_Debug, Dwarf_Bool, + Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Half *, Dwarf_Sig8 *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_cu_header_d(Dwarf_Debug, Dwarf_Bool, + Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Half *, Dwarf_Sig8 *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Error *); +int dwarf_next_types_section(Dwarf_Debug, Dwarf_Error *); +int dwarf_object_finish(Dwarf_Debug, Dwarf_Error *); +int dwarf_object_init(Dwarf_Obj_Access_Interface *, Dwarf_Handler, + Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *); +int dwarf_offdie(Dwarf_Debug, Dwarf_Off, Dwarf_Die *, + Dwarf_Error *); +int dwarf_offdie_b(Dwarf_Debug, Dwarf_Off, Dwarf_Bool, Dwarf_Die *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_P_Debug dwarf_producer_init(Dwarf_Unsigned, Dwarf_Callback_Func, + Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); +Dwarf_P_Debug dwarf_producer_init_b(Dwarf_Unsigned, Dwarf_Callback_Func_b, + Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); +int dwarf_producer_set_isa(Dwarf_P_Debug, enum Dwarf_ISA, + Dwarf_Error *); +int dwarf_pubtype_cu_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_pubtype_die_offset(Dwarf_Type, Dwarf_Off *, + Dwarf_Error *); +int dwarf_pubtype_name_offsets(Dwarf_Type, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_pubtypename(Dwarf_Type, char **, Dwarf_Error *); +void dwarf_pubtypes_dealloc(Dwarf_Debug, Dwarf_Type *, Dwarf_Signed); +void dwarf_ranges_dealloc(Dwarf_Debug, Dwarf_Ranges *, Dwarf_Signed); +void dwarf_reset_section_bytes(Dwarf_P_Debug); +Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug, Dwarf_Half); +int dwarf_set_reloc_application(int); +Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug, Dwarf_Ptr); +Dwarf_Handler dwarf_seterrhand(Dwarf_Debug, Dwarf_Handler); +int dwarf_siblingof(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Error *); +int dwarf_siblingof_b(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Bool, + Dwarf_Error *); +int dwarf_srcfiles(Dwarf_Die, char ***, Dwarf_Signed *, Dwarf_Error *); +int dwarf_srclang(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_srclines(Dwarf_Die, Dwarf_Line **, Dwarf_Signed *, + Dwarf_Error *); +void dwarf_srclines_dealloc(Dwarf_Debug, Dwarf_Line *, + Dwarf_Signed); +int dwarf_start_macro_file(Dwarf_P_Debug, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +int dwarf_tag(Dwarf_Die, Dwarf_Half *, Dwarf_Error *); +Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug, Dwarf_Error *); +int dwarf_type_cu_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_type_die_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_type_name_offsets(Dwarf_Type, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_typename(Dwarf_Type, char **, Dwarf_Error *); +void dwarf_types_dealloc(Dwarf_Debug, Dwarf_Type *, Dwarf_Signed); +int dwarf_undef_macro(Dwarf_P_Debug, Dwarf_Unsigned, char *, + Dwarf_Error *); +int dwarf_var_cu_offset(Dwarf_Var, Dwarf_Off *, Dwarf_Error *); +int dwarf_var_die_offset(Dwarf_Var, Dwarf_Off *, + Dwarf_Error *); +int dwarf_var_name_offsets(Dwarf_Var, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_varname(Dwarf_Var, char **, Dwarf_Error *); +void dwarf_vars_dealloc(Dwarf_Debug, Dwarf_Var *, Dwarf_Signed); +int dwarf_vendor_ext(Dwarf_P_Debug, Dwarf_Unsigned, char *, + Dwarf_Error *); +int dwarf_weak_cu_offset(Dwarf_Weak, Dwarf_Off *, Dwarf_Error *); +int dwarf_weak_die_offset(Dwarf_Weak, Dwarf_Off *, + Dwarf_Error *); +int dwarf_weak_name_offsets(Dwarf_Weak, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_weakname(Dwarf_Weak, char **, Dwarf_Error *); +void dwarf_weaks_dealloc(Dwarf_Debug, Dwarf_Weak *, Dwarf_Signed); +int dwarf_whatattr(Dwarf_Attribute, Dwarf_Half *, Dwarf_Error *); +int dwarf_whatform(Dwarf_Attribute, Dwarf_Half *, Dwarf_Error *); +int dwarf_whatform_direct(Dwarf_Attribute, Dwarf_Half *, + Dwarf_Error *); +#ifdef __cplusplus +} +#endif + +#endif /* !_LIBDWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c new file mode 100644 index 0000000000..514be62146 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c @@ -0,0 +1,306 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_abbrev.c 4049 2024-07-20 07:38:17Z jkoshy $"); + +static int +_dwarf_abbrev_allocate(Dwarf_Debug dbg, Dwarf_Abbrev *abp, + Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + + if ((ab = calloc(1, sizeof(struct _Dwarf_Abbrev))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* Initialise the list of attribute definitions. */ + STAILQ_INIT(&ab->ab_attrdef); + + *abp = ab; + + return (DW_DLE_NONE); +} + +static void +_dwarf_abbrev_release(Dwarf_Abbrev ab) { + Dwarf_AttrDef ad, tad; + + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + + free(ab); +} + +int +_dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, + uint64_t aboff, Dwarf_Abbrev *abp, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_Debug dbg; + int ret; + + dbg = cu != NULL ? cu->cu_dbg : NULL; + + if ((ret = _dwarf_abbrev_allocate(dbg, &ab, error)) != DW_DLE_NONE) + return (ret); + + /* Initialise the abbrev structure. */ + ab->ab_entry = entry; + ab->ab_tag = tag; + ab->ab_children = children; + ab->ab_offset = aboff; + ab->ab_length = 0; /* fill in later. */ + ab->ab_atnum = 0; /* fill in later. */ + + /* Add the abbrev to the hash table of the compilation unit. */ + if (cu != NULL) + HASH_ADD(ab_hh, cu->cu_abbrev_hash, ab_entry, + sizeof(ab->ab_entry), ab); + + *abp = ab; + return (DW_DLE_NONE); +} + +int +_dwarf_attrdef_add(Dwarf_Debug dbg, Dwarf_Abbrev ab, uint64_t attr, + uint64_t form, int64_t ic, uint64_t adoff, Dwarf_AttrDef *adp, + Dwarf_Error *error) +{ + Dwarf_AttrDef ad; + + if (ab == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((ad = malloc(sizeof(struct _Dwarf_AttrDef))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* Initialise the attribute definition structure. */ + ad->ad_attrib = attr; + ad->ad_form = form; + ad->ad_const = ic; + ad->ad_offset = adoff; + + /* Add the attribute definition to the list in the abbrev. */ + STAILQ_INSERT_TAIL(&ab->ab_attrdef, ad, ad_next); + + /* Increase number of attribute counter. */ + ab->ab_atnum++; + + if (adp != NULL) + *adp = ad; + + return (DW_DLE_NONE); +} + +int +_dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, + Dwarf_Abbrev *abp, Dwarf_Error *error) +{ + Dwarf_Section *ds; + uint64_t attr; + uint64_t entry; + uint64_t form; + uint64_t aboff; + uint64_t adoff; + uint64_t tag; + int64_t ic; + uint8_t children; + int ret; + + assert(abp != NULL); + + ds = _dwarf_find_section(dbg, ".debug_abbrev"); + if (ds == NULL || *offset >= ds->ds_size) + return (DW_DLE_NO_ENTRY); + + aboff = *offset; + + entry = _dwarf_read_uleb128(ds->ds_data, offset); + if (entry == 0) { + /* Last entry. */ + ret = _dwarf_abbrev_add(cu, entry, 0, 0, aboff, abp, + error); + if (ret != DW_DLE_NONE) + goto error; + + (*abp)->ab_length = 1; + return (ret); + } + tag = _dwarf_read_uleb128(ds->ds_data, offset); + children = dbg->read(ds->ds_data, offset, 1); + if ((ret = _dwarf_abbrev_add(cu, entry, tag, children, aboff, + abp, error)) != DW_DLE_NONE) + goto error; + + /* Parse attribute definitions. */ + do { + adoff = *offset; + attr = _dwarf_read_uleb128(ds->ds_data, offset); + form = _dwarf_read_uleb128(ds->ds_data, offset); + ic = 0; + if (form == DW_FORM_implicit_const) { + /* + * DWARF5 7.5.3: atrribute definition with the form + * DW_FORM_implicit_const contains a third part, a + * signed LEB128 value indicating a constant value. + * No value is needed to store in the .debug_info + * as a result. + */ + ic = _dwarf_read_sleb128(ds->ds_data, offset); + } + if (attr != 0) { + if ((ret = _dwarf_attrdef_add(dbg, *abp, attr, + form, ic, adoff, NULL, error)) != DW_DLE_NONE) + goto error; + } + } while (attr != 0); + + (*abp)->ab_length = *offset - aboff; + + return (ret); + + error: + _dwarf_abbrev_release(*abp); + + return (ret); +} + +int +_dwarf_abbrev_find(Dwarf_CU cu, uint64_t entry, Dwarf_Abbrev *abp, + Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_Section *ds; + Dwarf_Unsigned offset; + int ret; + + if (entry == 0) + return (DW_DLE_NO_ENTRY); + + /* Check if the desired abbrev entry is already in the hash table. */ + HASH_FIND(ab_hh, cu->cu_abbrev_hash, &entry, sizeof(entry), ab); + if (ab != NULL) { + *abp = ab; + return (DW_DLE_NONE); + } + + if (cu->cu_abbrev_loaded) { + return (DW_DLE_NO_ENTRY); + } + + /* Load and search the abbrev table. */ + ds = _dwarf_find_section(cu->cu_dbg, ".debug_abbrev"); + if (ds == NULL) + return (DW_DLE_NO_ENTRY); + + offset = cu->cu_abbrev_offset_cur; + while (offset < ds->ds_size) { + ret = _dwarf_abbrev_parse(cu->cu_dbg, cu, &offset, &ab, error); + if (ret != DW_DLE_NONE) + return (ret); + if (ab->ab_entry == entry) { + cu->cu_abbrev_offset_cur = offset; + *abp = ab; + return (DW_DLE_NONE); + } + if (ab->ab_entry == 0) { + cu->cu_abbrev_offset_cur = offset; + cu->cu_abbrev_loaded = 1; + break; + } + } + + return (DW_DLE_NO_ENTRY); +} + +void +_dwarf_abbrev_cleanup(Dwarf_CU cu) +{ + Dwarf_Abbrev ab, tab; + + assert(cu != NULL); + + HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { + HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); + _dwarf_abbrev_release(ab); + } +} + +int +_dwarf_abbrev_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Abbrev ab; + Dwarf_AttrDef ad; + Dwarf_P_Section ds; + int ret; + + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu == NULL) + return (DW_DLE_NONE); + + /* Create .debug_abbrev section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_abbrev", 0, error)) != + DW_DLE_NONE) + return (ret); + + for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { + RCHECK(WRITE_ULEB128(ab->ab_entry)); + RCHECK(WRITE_ULEB128(ab->ab_tag)); + RCHECK(WRITE_VALUE(ab->ab_children, 1)); + STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { + RCHECK(WRITE_ULEB128(ad->ad_attrib)); + RCHECK(WRITE_ULEB128(ad->ad_form)); + } + /* Signal end of attribute spec list. */ + RCHECK(WRITE_ULEB128(0)); + RCHECK(WRITE_ULEB128(0)); + } + /* End of abbreviation for this CU. */ + RCHECK(WRITE_ULEB128(0)); + + /* Notify the creation of .debug_abbrev ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + return (DW_DLE_NONE); + +gen_fail: + + _dwarf_section_free(dbg, &ds); + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_arange.c b/contrib/elftoolchain/libdwarf/libdwarf_arange.c new file mode 100644 index 0000000000..eefb63ba6b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_arange.c @@ -0,0 +1,260 @@ +/*- + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_arange.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); + +void +_dwarf_arange_cleanup(Dwarf_Debug dbg) +{ + Dwarf_ArangeSet as, tas; + Dwarf_Arange ar, tar; + + STAILQ_FOREACH_SAFE(as, &dbg->dbg_aslist, as_next, tas) { + STAILQ_FOREACH_SAFE(ar, &as->as_arlist, ar_next, tar) { + STAILQ_REMOVE(&as->as_arlist, ar, _Dwarf_Arange, + ar_next); + free(ar); + } + STAILQ_REMOVE(&dbg->dbg_aslist, as, _Dwarf_ArangeSet, as_next); + free(as); + } + + if (dbg->dbg_arange_array) + free(dbg->dbg_arange_array); + + dbg->dbg_arange_array = NULL; + dbg->dbg_arange_cnt = 0; +} + +int +_dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + Dwarf_Arange ar; + Dwarf_Section *ds; + uint64_t offset, dwarf_size, length, addr, range; + int i, ret; + + ret = DW_DLE_NONE; + + if ((ds = _dwarf_find_section(dbg, ".debug_aranges")) == NULL) + return (DW_DLE_NONE); + + if (!dbg->dbg_info_loaded) { + ret = _dwarf_info_load(dbg, 1, 1, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + offset = 0; + while (offset < ds->ds_size) { + + if ((as = malloc(sizeof(struct _Dwarf_ArangeSet))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&as->as_arlist); + STAILQ_INSERT_TAIL(&dbg->dbg_aslist, as, as_next); + + /* Read in the table header. */ + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + as->as_length = length; + as->as_version = dbg->read(ds->ds_data, &offset, 2); + if (as->as_version != 2) { + DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + ret = DW_DLE_VERSION_STAMP_ERROR; + goto fail_cleanup; + } + + as->as_cu_offset = dbg->read(ds->ds_data, &offset, dwarf_size); + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == as->as_cu_offset) + break; + } + if (cu == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + ret = DW_DLE_ARANGE_OFFSET_BAD; + goto fail_cleanup; + } + as->as_cu = cu; + + as->as_addrsz = dbg->read(ds->ds_data, &offset, 1); + as->as_segsz = dbg->read(ds->ds_data, &offset, 1); + + /* Skip the padding bytes. */ + offset = roundup(offset, 2 * as->as_addrsz); + + /* Read in address range descriptors. */ + while (offset < ds->ds_size) { + addr = dbg->read(ds->ds_data, &offset, as->as_addrsz); + range = dbg->read(ds->ds_data, &offset, as->as_addrsz); + if (addr == 0 && range == 0) + break; + if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + goto fail_cleanup; + } + ar->ar_as = as; + ar->ar_address = addr; + ar->ar_range = range; + STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next); + dbg->dbg_arange_cnt++; + } + } + + /* Build arange array. */ + if (dbg->dbg_arange_cnt > 0) { + if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * + sizeof(Dwarf_Arange))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + i = 0; + STAILQ_FOREACH(as, &dbg->dbg_aslist, as_next) { + STAILQ_FOREACH(ar, &as->as_arlist, ar_next) + dbg->dbg_arange_array[i++] = ar; + } + assert((Dwarf_Unsigned)i == dbg->dbg_arange_cnt); + } + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_arange_cleanup(dbg); + + return (ret); +} + +int +_dwarf_arange_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_ArangeSet as; + Dwarf_Arange ar; + uint64_t offset; + int ret; + + as = dbg->dbgp_as; + assert(as != NULL); + if (STAILQ_EMPTY(&as->as_arlist)) + return (DW_DLE_NONE); + + as->as_length = 0; + as->as_version = 2; + as->as_cu_offset = 0; /* We have only one CU. */ + as->as_addrsz = dbg->dbg_pointer_size; + as->as_segsz = 0; /* XXX */ + + /* Create .debug_arange section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_aranges", 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for .debug_aranges */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Write section header. */ + RCHECK(WRITE_VALUE(as->as_length, 4)); + RCHECK(WRITE_VALUE(as->as_version, 2)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, as->as_cu_offset, ".debug_info", error)); + RCHECK(WRITE_VALUE(as->as_addrsz, 1)); + RCHECK(WRITE_VALUE(as->as_segsz, 1)); + + /* Pad to (2 * address_size) */ + offset = roundup(ds->ds_size, 2 * as->as_addrsz); + if (offset > ds->ds_size) + RCHECK(WRITE_PADDING(0, offset - ds->ds_size)); + + /* Write tuples. */ + STAILQ_FOREACH(ar, &as->as_arlist, ar_next) { + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, ds->ds_size, + ar->ar_symndx, ar->ar_address, NULL, error)); + if (ar->ar_esymndx > 0) + RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds, + dbg->dbg_pointer_size, ds->ds_size, ar->ar_symndx, + ar->ar_esymndx, ar->ar_address, ar->ar_eoff, error)); + else + RCHECK(WRITE_VALUE(ar->ar_range, dbg->dbg_pointer_size)); + } + RCHECK(WRITE_VALUE(0, dbg->dbg_pointer_size)); + RCHECK(WRITE_VALUE(0, dbg->dbg_pointer_size)); + + /* Fill in the length field. */ + as->as_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, as->as_length, 4); + + /* Inform application the creation of .debug_aranges ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_aranges */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_arange_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_ArangeSet as; + Dwarf_Arange ar, tar; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_as == NULL) + return; + + as = dbg->dbgp_as; + STAILQ_FOREACH_SAFE(ar, &as->as_arlist, ar_next, tar) { + STAILQ_REMOVE(&as->as_arlist, ar, _Dwarf_Arange, ar_next); + free(ar); + } + free(as); + dbg->dbgp_as = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_attr.c b/contrib/elftoolchain/libdwarf/libdwarf_attr.c new file mode 100644 index 0000000000..1bca816351 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_attr.c @@ -0,0 +1,515 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_attr.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +int +_dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + assert(die != NULL); + assert(atp != NULL); + + if ((at = calloc(1, sizeof(struct _Dwarf_Attribute))) == NULL) { + DWARF_SET_ERROR(die->die_dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + *atp = at; + + return (DW_DLE_NONE); +} + +static int +_dwarf_attr_add(Dwarf_Die die, Dwarf_Attribute atref, Dwarf_Attribute *atp, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + memcpy(at, atref, sizeof(struct _Dwarf_Attribute)); + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + /* Save a pointer to the attribute name if this is one. */ + if (at->at_attrib == DW_AT_name) { + switch (at->at_form) { + case DW_FORM_strp: + die->die_name = at->u[1].s; + break; + case DW_FORM_string: + die->die_name = at->u[0].s; + break; + default: + break; + } + } + + if (atp != NULL) + *atp = at; + + return (DW_DLE_NONE); +} + +Dwarf_Attribute +_dwarf_attr_find(Dwarf_Die die, Dwarf_Half attr) +{ + Dwarf_Attribute at; + + STAILQ_FOREACH(at, &die->die_attr, at_next) { + if (at->at_attrib == attr) + break; + } + + return (at); +} + +int +_dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, + int dwarf_size, Dwarf_CU cu, Dwarf_Die die, Dwarf_AttrDef ad, + uint64_t form, int indirect, Dwarf_Error *error) +{ + struct _Dwarf_Attribute atref; + int ret; + + ret = DW_DLE_NONE; + memset(&atref, 0, sizeof(atref)); + atref.at_die = die; + atref.at_offset = *offsetp; + atref.at_attrib = ad->ad_attrib; + atref.at_form = indirect ? form : ad->ad_form; + atref.at_indirect = indirect; + atref.at_ld = NULL; + + switch (form) { + case DW_FORM_addr: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + cu->cu_pointer_size); + break; + case DW_FORM_block: + case DW_FORM_exprloc: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + break; + case DW_FORM_data2: + case DW_FORM_ref2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); + break; + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_ref_sup4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + break; + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sup8: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 8); + break; + case DW_FORM_indirect: + form = _dwarf_read_uleb128(ds->ds_data, offsetp); + return (_dwarf_attr_init(dbg, ds, offsetp, dwarf_size, cu, die, + ad, form, 1, error)); + case DW_FORM_ref_addr: + if (cu->cu_version == 2) + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + cu->cu_pointer_size); + else + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + dwarf_size); + break; + case DW_FORM_ref_udata: + case DW_FORM_udata: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + break; + case DW_FORM_sdata: + atref.u[0].s64 = _dwarf_read_sleb128(ds->ds_data, offsetp); + break; + case DW_FORM_sec_offset: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + break; + case DW_FORM_string: + atref.u[0].s = _dwarf_read_string(ds->ds_data, ds->ds_size, + offsetp); + break; + case DW_FORM_strp: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + atref.u[1].s = _dwarf_strtab_get_table(dbg) + atref.u[0].u64; + break; + case DW_FORM_ref_sig8: + atref.u[0].u64 = 8; + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_flag_present: + /* This form has no value encoded in the DIE. */ + atref.u[0].u64 = 1; + break; + case DW_FORM_strx: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + break; + case DW_FORM_addrx: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + /* TODO: .debug_addr */ + break; + case DW_FORM_strp_sup: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + /* TODO: supplementary object file. */ + break; + case DW_FORM_data16: + atref.u[0].u64 = 16; + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_line_strp: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + atref.u[1].s = _dwarf_strtab_get_line_table(dbg) + + atref.u[0].u64; + break; + case DW_FORM_implicit_const: + /* DWARF5 7.5.3 Implicit constant stored in attrdef. + This form has no value encoded in the DIE. */ + atref.u[0].s64 = ad->ad_const; + break; + case DW_FORM_strx1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + break; + case DW_FORM_strx2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + break; + case DW_FORM_strx3: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 3); + break; + case DW_FORM_strx4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + break; + case DW_FORM_addrx1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + /* TODO: .debug_addr */ + break; + case DW_FORM_addrx2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); + /* TODO: .debug_addr */ + break; + case DW_FORM_addrx3: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 3); + /* TODO: .debug_addr */ + break; + case DW_FORM_addrx4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + /* TODO: .debug_addr */ + break; + + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + } + + if (ret == DW_DLE_NONE) { + if (form == DW_FORM_block || form == DW_FORM_block1 || + form == DW_FORM_block2 || form == DW_FORM_block4) { + atref.at_block.bl_len = atref.u[0].u64; + atref.at_block.bl_data = atref.u[1].u8p; + } + ret = _dwarf_attr_add(die, &atref, NULL, error); + } + + return (ret); +} + +static int +_dwarf_attr_write(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, + Dwarf_CU cu, Dwarf_Attribute at, int pass2, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + uint64_t value, offset, bs; + int ret; + + assert(dbg != NULL && ds != NULL && cu != NULL && at != NULL); + + /* Fill in reference to other DIE in the second pass. */ + if (pass2) { + if (at->at_form != DW_FORM_ref4 && at->at_form != DW_FORM_ref8) + return (DW_DLE_NONE); + if (at->at_refdie == NULL || at->at_offset == 0) + return (DW_DLE_NONE); + offset = at->at_offset; + dbg->write(ds->ds_data, &offset, at->at_refdie->die_offset, + at->at_form == DW_FORM_ref4 ? 4 : 8); + return (DW_DLE_NONE); + } + + switch (at->at_form) { + case DW_FORM_addr: + if (at->at_relsym) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, cu->cu_pointer_size, + ds->ds_size, at->at_relsym, at->u[0].u64, NULL, + error); + else + ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); + break; + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + /* Write block size. */ + if (at->at_form == DW_FORM_block) { + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, at->u[0].u64, error); + if (ret != DW_DLE_NONE) + break; + } else { + if (at->at_form == DW_FORM_block1) + bs = 1; + else if (at->at_form == DW_FORM_block2) + bs = 2; + else + bs = 4; + ret = WRITE_VALUE(at->u[0].u64, bs); + if (ret != DW_DLE_NONE) + break; + } + + /* Keep block data offset for later use. */ + offset = ds->ds_size; + + /* Write block data. */ + ret = WRITE_BLOCK(at->u[1].u8p, at->u[0].u64); + if (ret != DW_DLE_NONE) + break; + if (at->at_expr == NULL) + break; + + /* Generate relocation entry for DW_OP_addr expressions. */ + STAILQ_FOREACH(ee, &at->at_expr->pe_eelist, ee_next) { + if (ee->ee_loc.lr_atom != DW_OP_addr || ee->ee_sym == 0) + continue; + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, + offset + ee->ee_loc.lr_offset + 1, ee->ee_sym, + ee->ee_loc.lr_number, NULL, error); + if (ret != DW_DLE_NONE) + break; + } + break; + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + ret = WRITE_VALUE(at->u[0].u64, 1); + break; + case DW_FORM_data2: + case DW_FORM_ref2: + ret = WRITE_VALUE(at->u[0].u64, 2); + break; + case DW_FORM_data4: + if (at->at_relsym || at->at_relsec != NULL) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, 4, ds->ds_size, at->at_relsym, + at->u[0].u64, at->at_relsec, error); + else + ret = WRITE_VALUE(at->u[0].u64, 4); + break; + case DW_FORM_data8: + if (at->at_relsym || at->at_relsec != NULL) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, 8, ds->ds_size, at->at_relsym, + at->u[0].u64, at->at_relsec, error); + else + ret = WRITE_VALUE(at->u[0].u64, 8); + break; + case DW_FORM_ref4: + case DW_FORM_ref8: + /* + * The value of ref4 and ref8 could be a reference to another + * DIE within the CU. And if we don't know the ref DIE's + * offset at the moement, then we remember at_offset and fill + * it in the second pass. + */ + if (at->at_refdie) { + value = at->at_refdie->die_offset; + if (value == 0) { + cu->cu_pass2 = 1; + at->at_offset = ds->ds_size; + } + } else + value = at->u[0].u64; + ret = WRITE_VALUE(value, at->at_form == DW_FORM_ref4 ? 4 : 8); + break; + case DW_FORM_indirect: + /* TODO. */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + case DW_FORM_ref_addr: + /* DWARF2 format. */ + if (at->at_relsym) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, cu->cu_pointer_size, + ds->ds_size, at->at_relsym, at->u[0].u64, NULL, + error); + else + ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); + break; + case DW_FORM_ref_udata: + case DW_FORM_udata: + ret = WRITE_ULEB128(at->u[0].u64); + break; + case DW_FORM_sdata: + ret = WRITE_SLEB128(at->u[0].s64); + break; + case DW_FORM_string: + assert(at->u[0].s != NULL); + ret = WRITE_STRING(at->u[0].s); + break; + case DW_FORM_strp: + ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, + 4, ds->ds_size, 0, at->u[0].u64, ".debug_str", error); + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + } + + return (ret); +} + +int +_dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, const char *secname, + Dwarf_P_Attribute *atp, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + assert(dbg != NULL && die != NULL); + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + at->at_die = die; + at->at_attrib = attr; + if (dbg->dbg_pointer_size == 4) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + at->at_relsym = sym_index; + at->at_relsec = secname; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + if (atp) + *atp = at; + + return (DW_DLE_NONE); +} + +int +_dwarf_add_string_attr(Dwarf_P_Die die, Dwarf_P_Attribute *atp, Dwarf_Half attr, + char *string, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + int ret; + + dbg = die != NULL ? die->die_dbg : NULL; + + assert(atp != NULL); + + if (die == NULL || string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_strp; + if ((ret = _dwarf_strtab_add(dbg, string, &at->u[0].u64, + error)) != DW_DLE_NONE) { + free(at); + return (ret); + } + at->u[1].s = _dwarf_strtab_get_table(dbg) + at->u[0].u64; + + *atp = at; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_attr_gen(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, + Dwarf_CU cu, Dwarf_Die die, int pass2, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + assert(dbg != NULL && ds != NULL && cu != NULL && die != NULL); + + STAILQ_FOREACH(at, &die->die_attr, at_next) { + ret = _dwarf_attr_write(dbg, ds, drs, cu, at, pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_die.c b/contrib/elftoolchain/libdwarf/libdwarf_die.c new file mode 100644 index 0000000000..da8389043a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_die.c @@ -0,0 +1,457 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_die.c 4008 2023-10-12 18:17:06Z kaiwang27 $"); + +int +_dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) +{ + Dwarf_Die die; + + assert(ret_die != NULL); + + if ((die = calloc(1, sizeof(struct _Dwarf_Die))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + STAILQ_INIT(&die->die_attr); + + *ret_die = die; + + return (DW_DLE_NONE); +} + +static int +_dwarf_die_add(Dwarf_CU cu, uint64_t offset, uint64_t abnum, Dwarf_Abbrev ab, + Dwarf_Die *diep, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Die die; + int ret; + + assert(cu != NULL); + assert(ab != NULL); + + dbg = cu->cu_dbg; + + if ((ret = _dwarf_die_alloc(dbg, &die, error)) != DW_DLE_NONE) + return (ret); + + die->die_offset = offset; + die->die_abnum = abnum; + die->die_ab = ab; + die->die_cu = cu; + die->die_dbg = cu->cu_dbg; + + if (diep != NULL) + *diep = die; + + return (DW_DLE_NONE); +} + +/* Find die at offset 'off' within the same CU. */ +Dwarf_Die +_dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) +{ + Dwarf_Debug dbg; + Dwarf_Section *ds; + Dwarf_CU cu; + Dwarf_Die die1; + Dwarf_Error de; + int ret; + + cu = die->die_cu; + dbg = die->die_dbg; + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + + ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off, + cu->cu_next_offset, &die1, 0, &de); + + if (ret == DW_DLE_NONE) + return (die1); + else + return (NULL); +} + +int +_dwarf_die_parse(Dwarf_Debug dbg, Dwarf_Section *ds, Dwarf_CU cu, + int dwarf_size, uint64_t offset, uint64_t next_offset, Dwarf_Die *ret_die, + int search_sibling, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_AttrDef ad; + Dwarf_Die die; + uint64_t abnum; + uint64_t die_offset; + int ret, level; + + assert(cu != NULL); + + level = 1; + die = NULL; + + while (offset < next_offset && offset < ds->ds_size) { + + die_offset = offset; + + abnum = _dwarf_read_uleb128(ds->ds_data, &offset); + + if (abnum == 0) { + if (level == 0 || !search_sibling) + return (DW_DLE_NO_ENTRY); + + /* + * Return to previous DIE level. + */ + level--; + continue; + } + + if ((ret = _dwarf_abbrev_find(cu, abnum, &ab, error)) != + DW_DLE_NONE) + return (ret); + + if ((ret = _dwarf_die_add(cu, die_offset, abnum, ab, &die, + error)) != DW_DLE_NONE) + return (ret); + + STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { + if ((ret = _dwarf_attr_init(dbg, ds, &offset, + dwarf_size, cu, die, ad, ad->ad_form, 0, + error)) != DW_DLE_NONE) + return (ret); + } + + die->die_next_off = offset; + if (search_sibling && level > 0) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + if (ab->ab_children == DW_CHILDREN_yes) { + /* Advance to next DIE level. */ + level++; + } + } else { + *ret_die = die; + return (DW_DLE_NONE); + } + } + + return (DW_DLE_NO_ENTRY); +} + +void +_dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, + Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) +{ + Dwarf_P_Die last_child; + + assert(die != NULL); + + if (parent) { + + /* Disconnect from old parent. */ + if (die->die_parent) { + if (die->die_parent != parent) { + if (die->die_parent->die_child == die) + die->die_parent->die_child = NULL; + die->die_parent = NULL; + } + } + + /* Find the last child of this parent. */ + last_child = parent->die_child; + if (last_child) { + while (last_child->die_right != NULL) + last_child = last_child->die_right; + } + + /* Connect to new parent. */ + die->die_parent = parent; + + /* + * Attach this DIE to the end of sibling list. If new + * parent doesn't have any child, set this DIE as the + * first child. + */ + if (last_child) { + assert(last_child->die_right == NULL); + last_child->die_right = die; + die->die_left = last_child; + } else + parent->die_child = die; + } + + if (child) { + + /* Disconnect from old child. */ + if (die->die_child) { + if (die->die_child != child) { + die->die_child->die_parent = NULL; + die->die_child = NULL; + } + } + + /* Connect to new child. */ + die->die_child = child; + child->die_parent = die; + } + + if (left_sibling) { + + /* Disconnect from old left sibling. */ + if (die->die_left) { + if (die->die_left != left_sibling) { + die->die_left->die_right = NULL; + die->die_left = NULL; + } + } + + /* Connect to new right sibling. */ + die->die_left = left_sibling; + left_sibling->die_right = die; + } + + if (right_sibling) { + + /* Disconnect from old right sibling. */ + if (die->die_right) { + if (die->die_right != right_sibling) { + die->die_right->die_left = NULL; + die->die_right = NULL; + } + } + + /* Connect to new right sibling. */ + die->die_right = right_sibling; + right_sibling->die_left = die; + } +} + +int +_dwarf_die_count_links(Dwarf_P_Die parent, Dwarf_P_Die child, + Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) +{ + int count; + + count = 0; + + if (parent) + count++; + if (child) + count++; + if (left_sibling) + count++; + if (right_sibling) + count++; + + return (count); +} + +static int +_dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, + Dwarf_P_Die die, int pass2, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Abbrev ab; + Dwarf_Attribute at; + Dwarf_AttrDef ad; + int match, ret; + + ds = dbg->dbgp_info; + assert(ds != NULL); + + if (pass2) + goto attr_gen; + + /* + * Add DW_AT_sibling attribute for DIEs with children, so consumers + * can quickly scan chains of siblings, while ignoring the children + * of individual siblings. + */ + if (die->die_child && die->die_right) { + if (_dwarf_attr_find(die, DW_AT_sibling) == NULL) + (void) dwarf_add_AT_reference(dbg, die, DW_AT_sibling, + die->die_right, error); + } + + /* + * Search abbrev list to find a matching entry. + */ + die->die_ab = NULL; + for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { + if (die->die_tag != ab->ab_tag) + continue; + if (ab->ab_children == DW_CHILDREN_no && die->die_child != NULL) + continue; + if (ab->ab_children == DW_CHILDREN_yes && + die->die_child == NULL) + continue; + at = STAILQ_FIRST(&die->die_attr); + ad = STAILQ_FIRST(&ab->ab_attrdef); + match = 1; + while (at != NULL && ad != NULL) { + if (at->at_attrib != ad->ad_attrib || + at->at_form != ad->ad_form) { + match = 0; + break; + } + at = STAILQ_NEXT(at, at_next); + ad = STAILQ_NEXT(ad, ad_next); + } + if ((at == NULL && ad != NULL) || (at != NULL && ad == NULL)) + match = 0; + if (match) { + die->die_ab = ab; + break; + } + } + + /* + * Create a new abbrev entry if we can not reuse any existing one. + */ + if (die->die_ab == NULL) { + ret = _dwarf_abbrev_add(cu, ++cu->cu_abbrev_cnt, die->die_tag, + die->die_child != NULL ? DW_CHILDREN_yes : DW_CHILDREN_no, + 0, &ab, error); + if (ret != DW_DLE_NONE) + return (ret); + STAILQ_FOREACH(at, &die->die_attr, at_next) { + ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib, + at->at_form, 0, 0, NULL, error); + if (ret != DW_DLE_NONE) + return (ret); + } + die->die_ab = ab; + } + + die->die_offset = ds->ds_size; + + /* + * Transform the DIE to bytes stream. + */ + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, die->die_ab->ab_entry, error); + if (ret != DW_DLE_NONE) + return (ret); + +attr_gen: + + /* Transform the attributes of this DIE. */ + ret = _dwarf_attr_gen(dbg, ds, drs, cu, die, pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + + /* Proceed to child DIE. */ + if (die->die_child != NULL) { + ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_child, + pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* Proceed to sibling DIE. */ + if (die->die_right != NULL) { + ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_right, + pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* Write a null DIE indicating the end of current level. */ + if (die->die_right == NULL) { + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_die_gen(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_Abbrev ab, tab; + Dwarf_AttrDef ad, tad; + Dwarf_Die die; + int ret; + + assert(dbg != NULL && cu != NULL); + assert(dbg->dbgp_root_die != NULL); + + die = dbg->dbgp_root_die; + + /* + * Insert a DW_AT_stmt_list attribute into root DIE, if there are + * line number information. + */ + if (!STAILQ_EMPTY(&dbg->dbgp_lineinfo->li_lnlist)) + RCHECK(_dwarf_add_AT_dataref(dbg, die, DW_AT_stmt_list, 0, 0, + ".debug_line", NULL, error)); + + RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 0, error)); + + if (cu->cu_pass2) + RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 1, error)); + + return (DW_DLE_NONE); + +gen_fail: + + HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { + HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + free(ab); + } + + return (ret); +} + +void +_dwarf_die_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Die die, tdie; + Dwarf_P_Attribute at, tat; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(die, &dbg->dbgp_dielist, die_pro_next, tdie) { + STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { + STAILQ_REMOVE(&die->die_attr, at, _Dwarf_Attribute, + at_next); + free(at); + } + free(die); + } +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c new file mode 100644 index 0000000000..d3e381b039 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_elf_access.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +int +_dwarf_elf_get_section_info(void *obj, Dwarf_Half ndx, + Dwarf_Obj_Access_Section *ret_section, int *error) +{ + Dwarf_Elf_Object *e; + GElf_Shdr *sh; + + e = obj; + assert(e != NULL); + + if (ret_section == NULL) { + if (error) + *error = DW_DLE_ARGUMENT; + return (DW_DLV_ERROR); + } + + if (ndx >= e->eo_seccnt) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + + sh = &e->eo_shdr[ndx]; + + ret_section->addr = sh->sh_addr; + ret_section->size = sh->sh_size; + + ret_section->name = elf_strptr(e->eo_elf, e->eo_strndx, sh->sh_name); + if (ret_section->name == NULL) { + if (error) + *error = DW_DLE_ELF; + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +Dwarf_Endianness +_dwarf_elf_get_byte_order(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + switch (e->eo_ehdr.e_ident[EI_DATA]) { + case ELFDATA2MSB: + return (DW_OBJECT_MSB); + + case ELFDATA2LSB: + case ELFDATANONE: + default: + return (DW_OBJECT_LSB); + } +} + +Dwarf_Small +_dwarf_elf_get_length_size(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + if (gelf_getclass(e->eo_elf) == ELFCLASS32) + return (4); + else if (e->eo_ehdr.e_machine == EM_MIPS) + return (8); + else + return (4); +} + +Dwarf_Small +_dwarf_elf_get_pointer_size(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + if (gelf_getclass(e->eo_elf) == ELFCLASS32) + return (4); + else + return (8); +} + +Dwarf_Unsigned +_dwarf_elf_get_section_count(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + return (e->eo_seccnt); +} + +int +_dwarf_elf_load_section(void *obj, Dwarf_Half ndx, Dwarf_Small** ret_data, + int *error) +{ + Dwarf_Elf_Object *e; + Dwarf_Elf_Data *ed; + + e = obj; + assert(e != NULL); + + if (ret_data == NULL) { + if (error) + *error = DW_DLE_ARGUMENT; + return (DW_DLV_ERROR); + } + + if (ndx >= e->eo_seccnt) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + + ed = &e->eo_data[ndx]; + + if (ed->ed_alloc != NULL) + *ret_data = ed->ed_alloc; + else { + if (ed->ed_data == NULL) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + *ret_data = ed->ed_data->d_buf; + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c new file mode 100644 index 0000000000..a88ddde6e0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c @@ -0,0 +1,392 @@ +/*- + * Copyright (c) 2009,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_elf_init.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +static const char *debug_name[] = { + ".debug_abbrev", + ".debug_aranges", + ".debug_frame", + ".debug_info", + ".debug_types", + ".debug_line", + ".debug_pubnames", + ".eh_frame", + ".debug_macinfo", + ".debug_str", + ".debug_str_offsets", + ".debug_line_str", + ".debug_loc", + ".debug_pubtypes", + ".debug_ranges", + ".debug_static_func", + ".debug_static_vars", + ".debug_typenames", + ".debug_weaknames", + NULL +}; + +static void +_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, + Elf_Data *rel_data, Elf_Data *symtab_data, int endian) +{ + Dwarf_Unsigned type; + GElf_Rel rel; + GElf_Sym sym; + size_t symndx; + uint64_t offset; + uint64_t addend; + int size, j; + + j = 0; + while (gelf_getrel(rel_data, j++, &rel) != NULL) { + symndx = GELF_R_SYM(rel.r_info); + type = GELF_R_TYPE(rel.r_info); + + if (gelf_getsym(symtab_data, symndx, &sym) == NULL) + continue; + + size = _dwarf_get_reloc_size(dbg, type); + if (size == 0) + continue; /* Unknown or non-absolute relocation. */ + + offset = rel.r_offset; + if (offset + size >= bufsize) + continue; + + if (endian == ELFDATA2MSB) + addend = _dwarf_read_msb(buf, &offset, size); + else + addend = _dwarf_read_lsb(buf, &offset, size); + + offset = rel.r_offset; + if (endian == ELFDATA2MSB) + _dwarf_write_msb(buf, &offset, sym.st_value + addend, + size); + else + _dwarf_write_lsb(buf, &offset, sym.st_value + addend, + size); + } +} + +static void +_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, + Elf_Data *rel_data, Elf_Data *symtab_data, int endian) +{ + Dwarf_Unsigned type; + GElf_Rela rela; + GElf_Sym sym; + size_t symndx; + uint64_t offset; + int size, j; + + j = 0; + while (gelf_getrela(rel_data, j++, &rela) != NULL) { + symndx = GELF_R_SYM(rela.r_info); + type = GELF_R_TYPE(rela.r_info); + + if (gelf_getsym(symtab_data, symndx, &sym) == NULL) + continue; + + offset = rela.r_offset; + size = _dwarf_get_reloc_size(dbg, type); + if (size == 0) + continue; /* Unknown or non-absolute relocation. */ + if (offset + size >= bufsize) + continue; + + if (endian == ELFDATA2MSB) + _dwarf_write_msb(buf, &offset, + sym.st_value + rela.r_addend, size); + else + _dwarf_write_lsb(buf, &offset, + sym.st_value + rela.r_addend, size); + } +} + +static int +_dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx, + size_t symtab, Elf_Data *symtab_data, Dwarf_Error *error) +{ + GElf_Ehdr eh; + GElf_Shdr sh; + Elf_Scn *scn; + Elf_Data *rel; + int elferr; + + if (symtab == 0 || symtab_data == NULL) + return (DW_DLE_NONE); + + if (gelf_getehdr(elf, &eh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + scn = NULL; + (void) elf_errno(); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + if ((sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA) || + sh.sh_size == 0) + continue; + + if (sh.sh_info == shndx && sh.sh_link == symtab) { + if ((rel = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(NULL, error, + DW_DLE_ELF, elferr); + return (DW_DLE_ELF); + } else + return (DW_DLE_NONE); + } + + ed->ed_alloc = malloc(ed->ed_data->d_size); + if (ed->ed_alloc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(ed->ed_alloc, ed->ed_data->d_buf, + ed->ed_data->d_size); + if (sh.sh_type == SHT_REL) + _dwarf_elf_apply_rel_reloc(dbg, + ed->ed_alloc, ed->ed_data->d_size, + rel, symtab_data, eh.e_ident[EI_DATA]); + else + _dwarf_elf_apply_rela_reloc(dbg, + ed->ed_alloc, ed->ed_data->d_size, + rel, symtab_data, eh.e_ident[EI_DATA]); + + return (DW_DLE_NONE); + } + } + elferr = elf_errno(); + if (elferr != 0) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) +{ + Dwarf_Obj_Access_Interface *iface; + Dwarf_Elf_Object *e; + const char *name; + GElf_Shdr sh; + Elf_Scn *scn; + Elf_Data *symtab_data; + size_t symtab_ndx; + int elferr, i, j, n, ret; + + ret = DW_DLE_NONE; + + if ((iface = calloc(1, sizeof(*iface))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((e = calloc(1, sizeof(*e))) == NULL) { + free(iface); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + e->eo_elf = elf; + e->eo_methods.get_section_info = _dwarf_elf_get_section_info; + e->eo_methods.get_byte_order = _dwarf_elf_get_byte_order; + e->eo_methods.get_length_size = _dwarf_elf_get_length_size; + e->eo_methods.get_pointer_size = _dwarf_elf_get_pointer_size; + e->eo_methods.get_section_count = _dwarf_elf_get_section_count; + e->eo_methods.load_section = _dwarf_elf_load_section; + + iface->object = e; + iface->methods = &e->eo_methods; + + dbg->dbg_iface = iface; + + if (gelf_getehdr(elf, &e->eo_ehdr) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + dbg->dbg_machine = e->eo_ehdr.e_machine; + + if (!elf_getshstrndx(elf, &e->eo_strndx)) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + n = 0; + symtab_ndx = 0; + symtab_data = NULL; + scn = NULL; + (void) elf_errno(); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + if ((name = elf_strptr(elf, e->eo_strndx, sh.sh_name)) == + NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + if (!strcmp(name, ".symtab")) { + symtab_ndx = elf_ndxscn(scn); + if ((symtab_data = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(NULL, error, + DW_DLE_ELF, elferr); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + } + continue; + } + + for (i = 0; debug_name[i] != NULL; i++) { + if (!strcmp(name, debug_name[i])) + n++; + } + } + elferr = elf_errno(); + if (elferr != 0) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + e->eo_seccnt = n; + + if (n == 0) + return (DW_DLE_NONE); + + if ((e->eo_data = calloc(n, sizeof(Dwarf_Elf_Data))) == NULL || + (e->eo_shdr = calloc(n, sizeof(GElf_Shdr))) == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + scn = NULL; + j = 0; + while ((scn = elf_nextscn(elf, scn)) != NULL && j < n) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + memcpy(&e->eo_shdr[j], &sh, sizeof(sh)); + + if ((name = elf_strptr(elf, e->eo_strndx, sh.sh_name)) == + NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + for (i = 0; debug_name[i] != NULL; i++) { + if (strcmp(name, debug_name[i])) + continue; + + (void) elf_errno(); + if ((e->eo_data[j].ed_data = elf_getdata(scn, NULL)) == + NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(dbg, error, + DW_DLE_ELF, elferr); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + } + + if (_libdwarf.applyreloc) { + if (_dwarf_elf_relocate(dbg, elf, + &e->eo_data[j], elf_ndxscn(scn), symtab_ndx, + symtab_data, error) != DW_DLE_NONE) + goto fail_cleanup; + } + + j++; + } + } + + assert(j == n); + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_elf_deinit(dbg); + + return (ret); +} + +void +_dwarf_elf_deinit(Dwarf_Debug dbg) +{ + Dwarf_Obj_Access_Interface *iface; + Dwarf_Elf_Object *e; + int i; + + iface = dbg->dbg_iface; + assert(iface != NULL); + + e = iface->object; + assert(e != NULL); + + if (e->eo_data) { + for (i = 0; (Dwarf_Unsigned) i < e->eo_seccnt; i++) { + if (e->eo_data[i].ed_alloc) + free(e->eo_data[i].ed_alloc); + } + free(e->eo_data); + } + if (e->eo_shdr) + free(e->eo_shdr); + + free(e); + free(iface); + + dbg->dbg_iface = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_error.c b/contrib/elftoolchain/libdwarf/libdwarf_error.c new file mode 100644 index 0000000000..da16029ce3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_error.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_error.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +void +_dwarf_set_error(Dwarf_Debug dbg, Dwarf_Error *error, int errorcode, + int elferrorcode, const char *functionname, int linenumber) +{ + Dwarf_Error de; + + de.err_error = errorcode; + de.err_elferror = elferrorcode; + de.err_func = functionname; + de.err_line = linenumber; + de.err_msg[0] = '\0'; + + /* + * If the user supplied a destination for the error, copy the + * error descriptor over and return. Otherwise, if the debug + * context is known and has an error handler, invoke that. + * Otherwise, if a 'default' error handler was registered, + * invoke it. + */ + if (error) + *error = de; + else if (dbg && dbg->dbg_errhand) + dbg->dbg_errhand(de, dbg->dbg_errarg); + else if (_libdwarf.errhand) + _libdwarf.errhand(de, _libdwarf.errarg); + + /* No handler found, do nothing. */ +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_frame.c b/contrib/elftoolchain/libdwarf/libdwarf_frame.c new file mode 100644 index 0000000000..1bd3a2b98a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_frame.c @@ -0,0 +1,1608 @@ +/*- + * Copyright (c) 2009-2011,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_frame.c 3804 2020-02-07 02:13:34Z emaste $"); + +static int +_dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, + Dwarf_Cie *ret_cie) +{ + Dwarf_Cie cie; + + STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { + if (cie->cie_offset == offset) + break; + } + + if (cie == NULL) + return (DW_DLE_NO_ENTRY); + + if (ret_cie != NULL) + *ret_cie = cie; + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val, + uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, + Dwarf_Error *error) +{ + uint8_t application; + + if (encode == DW_EH_PE_omit) + return (DW_DLE_NONE); + + application = encode & 0xf0; + encode &= 0x0f; + + switch (encode) { + case DW_EH_PE_absptr: + *val = dbg->read(data, offsetp, cie->cie_addrsize); + break; + case DW_EH_PE_uleb128: + *val = _dwarf_read_uleb128(data, offsetp); + break; + case DW_EH_PE_udata2: + *val = dbg->read(data, offsetp, 2); + break; + case DW_EH_PE_udata4: + *val = dbg->read(data, offsetp, 4); + break; + case DW_EH_PE_udata8: + *val = dbg->read(data, offsetp, 8); + break; + case DW_EH_PE_sleb128: + *val = _dwarf_read_sleb128(data, offsetp); + break; + case DW_EH_PE_sdata2: + *val = (int16_t) dbg->read(data, offsetp, 2); + break; + case DW_EH_PE_sdata4: + *val = (int32_t) dbg->read(data, offsetp, 4); + break; + case DW_EH_PE_sdata8: + *val = dbg->read(data, offsetp, 8); + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + } + + if (application == DW_EH_PE_pcrel) { + /* + * Value is relative to .eh_frame section virtual addr. + */ + switch (encode) { + case DW_EH_PE_uleb128: + case DW_EH_PE_udata2: + case DW_EH_PE_udata4: + case DW_EH_PE_udata8: + *val += pc; + break; + case DW_EH_PE_sleb128: + case DW_EH_PE_sdata2: + case DW_EH_PE_sdata4: + case DW_EH_PE_sdata8: + *val = pc + (int64_t) *val; + break; + default: + /* DW_EH_PE_absptr is absolute value. */ + break; + } + } + + /* XXX Applications other than DW_EH_PE_pcrel are not handled. */ + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie, + Dwarf_Error *error) +{ + uint8_t *aug_p, *augdata_p; + uint64_t val, offset; + uint8_t encode; + int ret; + + assert(cie->cie_augment != NULL && *cie->cie_augment == 'z'); + + /* + * Here we're only interested in the presence of augment 'R' + * and associated CIE augment data, which describes the + * encoding scheme of FDE PC begin and range. + */ + aug_p = &cie->cie_augment[1]; + augdata_p = cie->cie_augdata; + while (*aug_p != '\0') { + switch (*aug_p) { + case 'S': + break; + case 'L': + /* Skip one augment in augment data. */ + augdata_p++; + break; + case 'P': + /* Skip two augments in augment data. */ + encode = *augdata_p++; + offset = 0; + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, + augdata_p, &offset, encode, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + augdata_p += offset; + break; + case 'R': + cie->cie_fde_encode = *augdata_p++; + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + } + aug_p++; + } + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, + Dwarf_Unsigned *off, Dwarf_Cie *ret_cie, Dwarf_Error *error) +{ + Dwarf_Cie cie; + uint64_t length; + int dwarf_size, ret; + char *p; + + /* Check if we already added this CIE. */ + if (_dwarf_frame_find_cie(fs, *off, &cie) != DW_DLE_NO_ENTRY) { + *off += cie->cie_length + 4; + return (DW_DLE_NONE); + } + + if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&fs->fs_cielist, cie, cie_next); + + cie->cie_dbg = dbg; + cie->cie_index = fs->fs_cielen; + cie->cie_offset = *off; + + length = dbg->read(ds->ds_data, off, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, off, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - *off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + } + + (void) dbg->read(ds->ds_data, off, dwarf_size); /* Skip CIE id. */ + cie->cie_length = length; + + cie->cie_version = dbg->read(ds->ds_data, off, 1); + if (cie->cie_version != 1 && cie->cie_version != 3 && + cie->cie_version != 4) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_VERSION_BAD); + return (DW_DLE_FRAME_VERSION_BAD); + } + + cie->cie_augment = ds->ds_data + *off; + p = (char *) ds->ds_data; + while (p[(*off)++] != '\0') + ; + + /* We only recognize normal .dwarf_frame and GNU .eh_frame sections. */ + if (*cie->cie_augment != 0 && *cie->cie_augment != 'z') { + *off = cie->cie_offset + ((dwarf_size == 4) ? 4 : 12) + + cie->cie_length; + return (DW_DLE_NONE); + } + + /* Optional EH Data field for .eh_frame section. */ + if (strstr((char *)cie->cie_augment, "eh") != NULL) + cie->cie_ehdata = dbg->read(ds->ds_data, off, + dbg->dbg_pointer_size); + + /* DWARF4 added "address_size" and "segment_size". */ + if (cie->cie_version == 4) { + cie->cie_addrsize = dbg->read(ds->ds_data, off, 1); + cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1); + } else { + /* + * Otherwise (DWARF[23]) we just set CIE addrsize to the + * debug context pointer size. + */ + cie->cie_addrsize = dbg->dbg_pointer_size; + } + + cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off); + cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off); + + /* Return address register. */ + if (cie->cie_version == 1) + cie->cie_ra = dbg->read(ds->ds_data, off, 1); + else + cie->cie_ra = _dwarf_read_uleb128(ds->ds_data, off); + + /* Optional CIE augmentation data for .eh_frame section. */ + if (*cie->cie_augment == 'z') { + cie->cie_auglen = _dwarf_read_uleb128(ds->ds_data, off); + cie->cie_augdata = ds->ds_data + *off; + *off += cie->cie_auglen; + /* + * XXX Use DW_EH_PE_absptr for default FDE PC start/range, + * in case _dwarf_frame_parse_lsb_cie_augment fails to + * find out the real encode. + */ + cie->cie_fde_encode = DW_EH_PE_absptr; + ret = _dwarf_frame_parse_lsb_cie_augment(dbg, cie, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* CIE Initial instructions. */ + cie->cie_initinst = ds->ds_data + *off; + if (dwarf_size == 4) + cie->cie_instlen = cie->cie_offset + 4 + length - *off; + else + cie->cie_instlen = cie->cie_offset + 12 + length - *off; + + *off += cie->cie_instlen; + +#ifdef FRAME_DEBUG + printf("cie:\n"); + printf("\tcie_version=%u cie_offset=%ju cie_length=%ju cie_augment=%s" + " cie_instlen=%ju cie->cie_caf=%ju cie->cie_daf=%jd off=%ju\n", + cie->cie_version, cie->cie_offset, cie->cie_length, + (char *)cie->cie_augment, cie->cie_instlen, cie->cie_caf, + cie->cie_daf, *off); +#endif + + if (ret_cie != NULL) + *ret_cie = cie; + + fs->fs_cielen++; + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, + Dwarf_Unsigned *off, int eh_frame, Dwarf_Error *error) +{ + Dwarf_Cie cie; + Dwarf_Fde fde; + Dwarf_Unsigned cieoff; + uint64_t length, val; + int dwarf_size, ret; + + if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&fs->fs_fdelist, fde, fde_next); + + fde->fde_dbg = dbg; + fde->fde_fs = fs; + fde->fde_addr = ds->ds_data + *off; + fde->fde_offset = *off; + + length = dbg->read(ds->ds_data, off, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, off, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - *off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + } + + fde->fde_length = length; + + if (eh_frame) { + fde->fde_cieoff = dbg->read(ds->ds_data, off, 4); + cieoff = *off - (4 + fde->fde_cieoff); + /* This delta should never be 0. */ + if (cieoff == fde->fde_offset) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_CIE_FOR_FDE); + return (DW_DLE_NO_CIE_FOR_FDE); + } + } else { + fde->fde_cieoff = dbg->read(ds->ds_data, off, dwarf_size); + cieoff = fde->fde_cieoff; + } + + if (_dwarf_frame_find_cie(fs, cieoff, &cie) == + DW_DLE_NO_ENTRY) { + ret = _dwarf_frame_add_cie(dbg, fs, ds, &cieoff, &cie, + error); + if (ret != DW_DLE_NONE) + return (ret); + } + fde->fde_cie = cie; + if (eh_frame) { + /* + * The FDE PC start/range for .eh_frame is encoded according + * to the LSB spec's extension to DWARF2. + */ + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, + ds->ds_data, off, cie->cie_fde_encode, ds->ds_addr + *off, + error); + if (ret != DW_DLE_NONE) + return (ret); + fde->fde_initloc = val; + /* + * FDE PC range should not be relative value to anything. + * So pass 0 for pc value. + */ + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, + ds->ds_data, off, cie->cie_fde_encode, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + fde->fde_adrange = val; + } else { + fde->fde_initloc = dbg->read(ds->ds_data, off, + cie->cie_addrsize); + fde->fde_adrange = dbg->read(ds->ds_data, off, + cie->cie_addrsize); + } + + /* Optional FDE augmentation data for .eh_frame section. (ignored) */ + if (eh_frame && *cie->cie_augment == 'z') { + fde->fde_auglen = _dwarf_read_uleb128(ds->ds_data, off); + fde->fde_augdata = ds->ds_data + *off; + *off += fde->fde_auglen; + } + + fde->fde_inst = ds->ds_data + *off; + if (dwarf_size == 4) + fde->fde_instlen = fde->fde_offset + 4 + length - *off; + else + fde->fde_instlen = fde->fde_offset + 12 + length - *off; + + *off += fde->fde_instlen; + +#ifdef FRAME_DEBUG + printf("fde:"); + if (eh_frame) + printf("(eh_frame)"); + putchar('\n'); + printf("\tfde_offset=%ju fde_length=%ju fde_cieoff=%ju" + " fde_instlen=%ju off=%ju\n", fde->fde_offset, fde->fde_length, + fde->fde_cieoff, fde->fde_instlen, *off); +#endif + + fs->fs_fdelen++; + + return (DW_DLE_NONE); +} + +static void +_dwarf_frame_section_cleanup(Dwarf_FrameSec fs) +{ + Dwarf_Cie cie, tcie; + Dwarf_Fde fde, tfde; + + STAILQ_FOREACH_SAFE(cie, &fs->fs_cielist, cie_next, tcie) { + STAILQ_REMOVE(&fs->fs_cielist, cie, _Dwarf_Cie, cie_next); + free(cie); + } + + STAILQ_FOREACH_SAFE(fde, &fs->fs_fdelist, fde_next, tfde) { + STAILQ_REMOVE(&fs->fs_fdelist, fde, _Dwarf_Fde, fde_next); + free(fde); + } + + if (fs->fs_ciearray != NULL) + free(fs->fs_ciearray); + if (fs->fs_fdearray != NULL) + free(fs->fs_fdearray); + + free(fs); +} + +static int +_dwarf_frame_section_init(Dwarf_Debug dbg, Dwarf_FrameSec *frame_sec, + Dwarf_Section *ds, int eh_frame, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Cie cie; + Dwarf_Fde fde; + uint64_t length, offset, cie_id, entry_off; + int dwarf_size, i, ret; + + assert(frame_sec != NULL); + assert(*frame_sec == NULL); + + if ((fs = calloc(1, sizeof(struct _Dwarf_FrameSec))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&fs->fs_cielist); + STAILQ_INIT(&fs->fs_fdelist); + + offset = 0; + while (offset < ds->ds_size) { + entry_off = offset; + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - offset || + (length == 0 && !eh_frame)) { + ret = DW_DLE_DEBUG_FRAME_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + /* Check terminator for .eh_frame */ + if (eh_frame && length == 0) + break; + + cie_id = dbg->read(ds->ds_data, &offset, dwarf_size); + + if (eh_frame) { + /* GNU .eh_frame use CIE id 0. */ + if (cie_id == 0) + ret = _dwarf_frame_add_cie(dbg, fs, ds, + &entry_off, NULL, error); + else + ret = _dwarf_frame_add_fde(dbg, fs, ds, + &entry_off, 1, error); + } else { + /* .dwarf_frame use CIE id ~0 */ + if ((dwarf_size == 4 && cie_id == ~0U) || + (dwarf_size == 8 && cie_id == ~0ULL)) + ret = _dwarf_frame_add_cie(dbg, fs, ds, + &entry_off, NULL, error); + else + ret = _dwarf_frame_add_fde(dbg, fs, ds, + &entry_off, 0, error); + } + + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + offset = entry_off; + } + + /* Create CIE array. */ + if (fs->fs_cielen > 0) { + if ((fs->fs_ciearray = malloc(sizeof(Dwarf_Cie) * + fs->fs_cielen)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + i = 0; + STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { + fs->fs_ciearray[i++] = cie; + } + assert((Dwarf_Unsigned)i == fs->fs_cielen); + } + + /* Create FDE array. */ + if (fs->fs_fdelen > 0) { + if ((fs->fs_fdearray = malloc(sizeof(Dwarf_Fde) * + fs->fs_fdelen)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + i = 0; + STAILQ_FOREACH(fde, &fs->fs_fdelist, fde_next) { + fs->fs_fdearray[i++] = fde; + } + assert((Dwarf_Unsigned)i == fs->fs_fdelen); + } + + *frame_sec = fs; + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_frame_section_cleanup(fs); + + return (ret); +} + +static int +_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size, + uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, + Dwarf_Addr pc, Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *init_rt, *saved_rt; + uint8_t *p, *pe; + uint8_t high2, low6; + uint64_t reg, reg2, uoff, soff; + int ret; + +#define CFA rt->rt3_cfa_rule +#define INITCFA init_rt->rt3_cfa_rule +#define RL rt->rt3_rules +#define INITRL init_rt->rt3_rules + +#define CHECK_TABLE_SIZE(x) \ + do { \ + if ((x) >= rt->rt3_reg_table_size) { \ + DWARF_SET_ERROR(dbg, error, \ + DW_DLE_DF_REG_NUM_TOO_HIGH); \ + ret = DW_DLE_DF_REG_NUM_TOO_HIGH; \ + goto program_done; \ + } \ + } while(0) + +#ifdef FRAME_DEBUG + printf("frame_run_inst: (caf=%ju, daf=%jd)\n", caf, daf); +#endif + + ret = DW_DLE_NONE; + init_rt = saved_rt = NULL; + *row_pc = pc; + + /* Save a copy of the table as initial state. */ + _dwarf_frame_regtable_copy(dbg, &init_rt, rt, error); + + p = insts; + pe = p + len; + + while (p < pe) { + +#ifdef FRAME_DEBUG + printf("p=%p pe=%p pc=%#jx pc_req=%#jx\n", p, pe, pc, pc_req); +#endif + + if (*p == DW_CFA_nop) { +#ifdef FRAME_DEBUG + printf("DW_CFA_nop\n"); +#endif + p++; + continue; + } + + high2 = *p & 0xc0; + low6 = *p & 0x3f; + p++; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + pc += low6 * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_advance_loc(%#jx(%u))\n", pc, + low6); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_offset: + *row_pc = pc; + CHECK_TABLE_SIZE(low6); + RL[low6].dw_offset_relevant = 1; + RL[low6].dw_value_type = DW_EXPR_OFFSET; + RL[low6].dw_regnum = dbg->dbg_frame_cfa_value; + RL[low6].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p) * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset(%jd)\n", + RL[low6].dw_offset_or_block_len); +#endif + break; + case DW_CFA_restore: + *row_pc = pc; + CHECK_TABLE_SIZE(low6); + memcpy(&RL[low6], &INITRL[low6], + sizeof(Dwarf_Regtable_Entry3)); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore(%u)\n", low6); +#endif + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; + goto program_done; + } + + continue; + } + + switch (low6) { + case DW_CFA_set_loc: + pc = dbg->decode(&p, addr_size); +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc1: + pc += dbg->decode(&p, 1) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc1(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc2: + pc += dbg->decode(&p, 2) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc2(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc4: + pc += dbg->decode(&p, 4) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc4(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_offset_extended: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = uoff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset_extended(reg=%ju,uoff=%ju)\n", + reg, uoff); +#endif + break; + case DW_CFA_restore_extended: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + memcpy(&RL[reg], &INITRL[reg], + sizeof(Dwarf_Regtable_Entry3)); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore_extended(%ju)\n", reg); +#endif + break; + case DW_CFA_undefined: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = dbg->dbg_frame_undefined_value; +#ifdef FRAME_DEBUG + printf("DW_CFA_undefined(%ju)\n", reg); +#endif + break; + case DW_CFA_same_value: + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = dbg->dbg_frame_same_value; +#ifdef FRAME_DEBUG + printf("DW_CFA_same_value(%ju)\n", reg); +#endif + break; + case DW_CFA_register: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + reg2 = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = reg2; +#ifdef FRAME_DEBUG + printf("DW_CFA_register(reg=%ju,reg2=%ju)\n", reg, + reg2); +#endif + break; + case DW_CFA_remember_state: + _dwarf_frame_regtable_copy(dbg, &saved_rt, rt, error); +#ifdef FRAME_DEBUG + printf("DW_CFA_remember_state\n"); +#endif + break; + case DW_CFA_restore_state: + *row_pc = pc; + _dwarf_frame_regtable_copy(dbg, &rt, saved_rt, error); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore_state\n"); +#endif + break; + case DW_CFA_def_cfa: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_regnum = reg; + CFA.dw_offset_or_block_len = uoff; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa(reg=%ju,uoff=%ju)\n", reg, uoff); +#endif + break; + case DW_CFA_def_cfa_register: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CFA.dw_regnum = reg; + /* + * Note that DW_CFA_def_cfa_register change the CFA + * rule register while keep the old offset. So we + * should not touch the CFA.dw_offset_relevant flag + * here. + */ +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_register(%ju)\n", reg); +#endif + break; + case DW_CFA_def_cfa_offset: + *row_pc = pc; + uoff = _dwarf_decode_uleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_offset_or_block_len = uoff; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_offset(%ju)\n", uoff); +#endif + break; + case DW_CFA_def_cfa_expression: + *row_pc = pc; + CFA.dw_offset_relevant = 0; + CFA.dw_value_type = DW_EXPR_EXPRESSION; + CFA.dw_offset_or_block_len = _dwarf_decode_uleb128(&p); + CFA.dw_block_ptr = p; + p += CFA.dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_expression\n"); +#endif + break; + case DW_CFA_expression: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_value_type = DW_EXPR_EXPRESSION; + RL[reg].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p); + RL[reg].dw_block_ptr = p; + p += RL[reg].dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_expression\n"); +#endif + break; + case DW_CFA_offset_extended_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset_extended_sf(reg=%ju,soff=%jd)\n", + reg, soff); +#endif + break; + case DW_CFA_def_cfa_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_regnum = reg; + CFA.dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_sf(reg=%ju,soff=%jd)\n", reg, + soff); +#endif + break; + case DW_CFA_def_cfa_offset_sf: + *row_pc = pc; + soff = _dwarf_decode_sleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_offset_sf(soff=%jd)\n", soff); +#endif + break; + case DW_CFA_val_offset: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = uoff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_offset(reg=%ju,uoff=%ju)\n", reg, + uoff); +#endif + break; + case DW_CFA_val_offset_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_offset_sf(reg=%ju,soff=%jd)\n", reg, + soff); +#endif + break; + case DW_CFA_val_expression: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_value_type = DW_EXPR_VAL_EXPRESSION; + RL[reg].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p); + RL[reg].dw_block_ptr = p; + p += RL[reg].dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_expression\n"); +#endif + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; + goto program_done; + } + } + +program_done: + + free(init_rt->rt3_rules); + free(init_rt); + if (saved_rt) { + free(saved_rt->rt3_rules); + free(saved_rt); + } + + return (ret); + +#undef CFA +#undef INITCFA +#undef RL +#undef INITRL +#undef CHECK_TABLE_SIZE +} + +static int +_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, + Dwarf_Frame_Op3 *fop3, Dwarf_Error *error) +{ + uint8_t *p, *pe; + uint8_t high2, low6; + uint64_t reg, reg2, uoff, soff, blen; + +#define SET_BASE_OP(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_base_op = (x) >> 6; \ + if (fop3 != NULL) \ + fop3[*count].fp_base_op = (x) >> 6; \ + } while(0) + +#define SET_EXTENDED_OP(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_extended_op = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_extended_op = (x); \ + } while(0) + +#define SET_REGISTER(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_register = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_register = (x); \ + } while(0) + +#define SET_OFFSET(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_offset = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_offset_or_block_len = \ + (x); \ + } while(0) + +#define SET_INSTR_OFFSET(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_instr_offset = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_instr_offset = (x); \ + } while(0) + +#define SET_BLOCK_LEN(x) \ + do { \ + if (fop3 != NULL) \ + fop3[*count].fp_offset_or_block_len = \ + (x); \ + } while(0) + +#define SET_EXPR_BLOCK(addr, len) \ + do { \ + if (fop3 != NULL) { \ + fop3[*count].fp_expr_block = \ + malloc((size_t) (len)); \ + if (fop3[*count].fp_expr_block == NULL) { \ + DWARF_SET_ERROR(dbg, error, \ + DW_DLE_MEMORY); \ + return (DW_DLE_MEMORY); \ + } \ + memcpy(&fop3[*count].fp_expr_block, \ + (addr), (len)); \ + } \ + } while(0) + + *count = 0; + + p = insts; + pe = p + len; + + while (p < pe) { + + SET_INSTR_OFFSET(p - insts); + + if (*p == DW_CFA_nop) { + p++; + (*count)++; + continue; + } + + high2 = *p & 0xc0; + low6 = *p & 0x3f; + p++; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + SET_BASE_OP(high2); + SET_OFFSET(low6); + break; + case DW_CFA_offset: + SET_BASE_OP(high2); + SET_REGISTER(low6); + uoff = _dwarf_decode_uleb128(&p); + SET_OFFSET(uoff); + break; + case DW_CFA_restore: + SET_BASE_OP(high2); + SET_REGISTER(low6); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + (*count)++; + continue; + } + + SET_EXTENDED_OP(low6); + + switch (low6) { + case DW_CFA_set_loc: + uoff = dbg->decode(&p, addr_size); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc1: + uoff = dbg->decode(&p, 1); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc2: + uoff = dbg->decode(&p, 2); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc4: + uoff = dbg->decode(&p, 4); + SET_OFFSET(uoff); + break; + case DW_CFA_offset_extended: + case DW_CFA_def_cfa: + case DW_CFA_val_offset: + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(uoff); + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_def_cfa_register: + reg = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + break; + case DW_CFA_register: + reg = _dwarf_decode_uleb128(&p); + reg2 = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(reg2); + break; + case DW_CFA_remember_state: + case DW_CFA_restore_state: + break; + case DW_CFA_def_cfa_offset: + uoff = _dwarf_decode_uleb128(&p); + SET_OFFSET(uoff); + break; + case DW_CFA_def_cfa_expression: + blen = _dwarf_decode_uleb128(&p); + SET_BLOCK_LEN(blen); + SET_EXPR_BLOCK(p, blen); + p += blen; + break; + case DW_CFA_expression: + case DW_CFA_val_expression: + reg = _dwarf_decode_uleb128(&p); + blen = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_BLOCK_LEN(blen); + SET_EXPR_BLOCK(p, blen); + p += blen; + break; + case DW_CFA_offset_extended_sf: + case DW_CFA_def_cfa_sf: + case DW_CFA_val_offset_sf: + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(soff); + break; + case DW_CFA_def_cfa_offset_sf: + soff = _dwarf_decode_sleb128(&p); + SET_OFFSET(soff); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + (*count)++; + } + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, + Dwarf_Error *error) +{ + Dwarf_Frame_Op *oplist; + Dwarf_Unsigned count; + int ret; + + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + NULL, NULL, error); + if (ret != DW_DLE_NONE) + return (ret); + + if ((oplist = calloc(count, sizeof(Dwarf_Frame_Op))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + oplist, NULL, error); + if (ret != DW_DLE_NONE) { + free(oplist); + return (ret); + } + + *ret_oplist = oplist; + *ret_opcnt = count; + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_regtable_copy(Dwarf_Debug dbg, Dwarf_Regtable3 **dest, + Dwarf_Regtable3 *src, Dwarf_Error *error) +{ + int i; + + assert(dest != NULL); + assert(src != NULL); + + if (*dest == NULL) { + if ((*dest = malloc(sizeof(Dwarf_Regtable3))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + (*dest)->rt3_reg_table_size = src->rt3_reg_table_size; + (*dest)->rt3_rules = malloc(src->rt3_reg_table_size * + sizeof(Dwarf_Regtable_Entry3)); + if ((*dest)->rt3_rules == NULL) { + free(*dest); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + memcpy(&(*dest)->rt3_cfa_rule, &src->rt3_cfa_rule, + sizeof(Dwarf_Regtable_Entry3)); + + for (i = 0; i < (*dest)->rt3_reg_table_size && + i < src->rt3_reg_table_size; i++) + memcpy(&(*dest)->rt3_rules[i], &src->rt3_rules[i], + sizeof(Dwarf_Regtable_Entry3)); + + for (; i < (*dest)->rt3_reg_table_size; i++) + (*dest)->rt3_rules[i].dw_regnum = + dbg->dbg_frame_undefined_value; + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req, + Dwarf_Regtable3 **ret_rt, Dwarf_Addr *ret_row_pc, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Cie cie; + Dwarf_Regtable3 *rt; + Dwarf_Addr row_pc; + int i, ret; + + assert(ret_rt != NULL); + + dbg = fde->fde_dbg; + assert(dbg != NULL); + + rt = dbg->dbg_internal_reg_table; + + /* Clear the content of regtable from previous run. */ + memset(&rt->rt3_cfa_rule, 0, sizeof(Dwarf_Regtable_Entry3)); + memset(rt->rt3_rules, 0, rt->rt3_reg_table_size * + sizeof(Dwarf_Regtable_Entry3)); + + /* Set rules to initial values. */ + for (i = 0; i < rt->rt3_reg_table_size; i++) + rt->rt3_rules[i].dw_regnum = dbg->dbg_frame_rule_initial_value; + + /* Run initial instructions in CIE. */ + cie = fde->fde_cie; + assert(cie != NULL); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + cie->cie_initinst, cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, + ~0ULL, &row_pc, error); + if (ret != DW_DLE_NONE) + return (ret); + + /* Run instructions in FDE. */ + if (pc_req >= fde->fde_initloc) { + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + fde->fde_inst, fde->fde_instlen, cie->cie_caf, + cie->cie_daf, fde->fde_initloc, pc_req, &row_pc, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + *ret_rt = rt; + *ret_row_pc = row_pc; + + return (DW_DLE_NONE); +} + +void +_dwarf_frame_cleanup(Dwarf_Debug dbg) +{ + Dwarf_Regtable3 *rt; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + if (dbg->dbg_internal_reg_table) { + rt = dbg->dbg_internal_reg_table; + free(rt->rt3_rules); + free(rt); + dbg->dbg_internal_reg_table = NULL; + } + + if (dbg->dbg_frame) { + _dwarf_frame_section_cleanup(dbg->dbg_frame); + dbg->dbg_frame = NULL; + } + + if (dbg->dbg_eh_frame) { + _dwarf_frame_section_cleanup(dbg->dbg_eh_frame); + dbg->dbg_eh_frame = NULL; + } +} + +int +_dwarf_frame_section_load(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if ((ds = _dwarf_find_section(dbg, ".debug_frame")) != NULL) { + return (_dwarf_frame_section_init(dbg, &dbg->dbg_frame, + ds, 0, error)); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_section_load_eh(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if ((ds = _dwarf_find_section(dbg, ".eh_frame")) != NULL) { + return (_dwarf_frame_section_init(dbg, &dbg->dbg_eh_frame, + ds, 1, error)); + } + + return (DW_DLE_NONE); +} + +void +_dwarf_frame_params_init(Dwarf_Debug dbg) +{ + + /* Initialise call frame related parameters. */ + dbg->dbg_frame_rule_table_size = DW_FRAME_LAST_REG_NUM; + dbg->dbg_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; + dbg->dbg_frame_cfa_value = DW_FRAME_CFA_COL3; + dbg->dbg_frame_same_value = DW_FRAME_SAME_VAL; + dbg->dbg_frame_undefined_value = DW_FRAME_UNDEFINED_VAL; +} + +int +_dwarf_frame_interal_table_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + + if (dbg->dbg_internal_reg_table != NULL) + return (DW_DLE_NONE); + + /* Initialise internal register table. */ + if ((rt = calloc(1, sizeof(Dwarf_Regtable3))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + rt->rt3_reg_table_size = dbg->dbg_frame_rule_table_size; + if ((rt->rt3_rules = calloc(rt->rt3_reg_table_size, + sizeof(Dwarf_Regtable_Entry3))) == NULL) { + free(rt); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_internal_reg_table = rt; + + return (DW_DLE_NONE); +} + +#define _FDE_INST_INIT_SIZE 128 + +int +_dwarf_frame_fde_add_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + uint8_t high2, low6; + int ret; + +#define ds fde +#define ds_data fde_inst +#define ds_cap fde_instcap +#define ds_size fde_instlen + + assert(fde != NULL && fde->fde_dbg != NULL); + dbg = fde->fde_dbg; + + if (fde->fde_inst == NULL) { + fde->fde_instcap = _FDE_INST_INIT_SIZE; + fde->fde_instlen = 0; + if ((fde->fde_inst = malloc((size_t) fde->fde_instcap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + assert(fde->fde_instcap != 0); + + RCHECK(WRITE_VALUE(op, 1)); + if (op == DW_CFA_nop) + return (DW_DLE_NONE); + + high2 = op & 0xc0; + low6 = op & 0x3f; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + case DW_CFA_restore: + break; + case DW_CFA_offset: + RCHECK(WRITE_ULEB128(val1)); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + return (DW_DLE_NONE); + } + + switch (low6) { + case DW_CFA_set_loc: + RCHECK(WRITE_VALUE(val1, dbg->dbg_pointer_size)); + break; + case DW_CFA_advance_loc1: + RCHECK(WRITE_VALUE(val1, 1)); + break; + case DW_CFA_advance_loc2: + RCHECK(WRITE_VALUE(val1, 2)); + break; + case DW_CFA_advance_loc4: + RCHECK(WRITE_VALUE(val1, 4)); + break; + case DW_CFA_offset_extended: + case DW_CFA_def_cfa: + case DW_CFA_register: + RCHECK(WRITE_ULEB128(val1)); + RCHECK(WRITE_ULEB128(val2)); + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa_offset: + RCHECK(WRITE_ULEB128(val1)); + break; + case DW_CFA_remember_state: + case DW_CFA_restore_state: + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + return (DW_DLE_NONE); + +gen_fail: + return (ret); + +#undef ds +#undef ds_data +#undef ds_cap +#undef ds_size +} + +static int +_dwarf_frame_gen_cie(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_P_Cie cie, + Dwarf_Error *error) +{ + Dwarf_Unsigned len; + uint64_t offset; + int ret; + + assert(dbg != NULL && ds != NULL && cie != NULL); + + cie->cie_offset = offset = ds->ds_size; + cie->cie_length = 0; + cie->cie_version = 1; + + /* Length placeholder. */ + RCHECK(WRITE_VALUE(cie->cie_length, 4)); + + /* .debug_frame use CIE id ~0. */ + RCHECK(WRITE_VALUE(~0U, 4)); + + /* .debug_frame version is 1. (DWARF2) */ + RCHECK(WRITE_VALUE(cie->cie_version, 1)); + + /* Write augmentation, if present. */ + if (cie->cie_augment != NULL) + RCHECK(WRITE_BLOCK(cie->cie_augment, + strlen((char *) cie->cie_augment) + 1)); + else + RCHECK(WRITE_VALUE(0, 1)); + + /* Write caf, daf and ra. */ + RCHECK(WRITE_ULEB128(cie->cie_caf)); + RCHECK(WRITE_SLEB128(cie->cie_daf)); + RCHECK(WRITE_VALUE(cie->cie_ra, 1)); + + /* Write initial instructions, if present. */ + if (cie->cie_initinst != NULL) + RCHECK(WRITE_BLOCK(cie->cie_initinst, cie->cie_instlen)); + + /* Add padding. */ + len = ds->ds_size - cie->cie_offset - 4; + cie->cie_length = roundup(len, dbg->dbg_pointer_size); + while (len++ < cie->cie_length) + RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); + + /* Fill in the length field. */ + dbg->write(ds->ds_data, &offset, cie->cie_length, 4); + + return (DW_DLE_NONE); + +gen_fail: + return (ret); +} + +static int +_dwarf_frame_gen_fde(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Rel_Section drs, Dwarf_P_Fde fde, Dwarf_Error *error) +{ + Dwarf_Unsigned len; + uint64_t offset; + int ret; + + assert(dbg != NULL && ds != NULL && drs != NULL); + assert(fde != NULL && fde->fde_cie != NULL); + + fde->fde_offset = offset = ds->ds_size; + fde->fde_length = 0; + fde->fde_cieoff = fde->fde_cie->cie_offset; + + /* Length placeholder. */ + RCHECK(WRITE_VALUE(fde->fde_length, 4)); + + /* Write CIE pointer. */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, fde->fde_cieoff, ".debug_frame", error)); + + /* Write FDE initial location. */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, + dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, + fde->fde_initloc, NULL, error)); + + /* + * Write FDE address range. Use a pair of relocation entries if + * application provided end symbol index. Otherwise write the + * length without assoicating any relocation info. + */ + if (fde->fde_esymndx > 0) + RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds, + dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, + fde->fde_esymndx, fde->fde_initloc, fde->fde_eoff, error)); + else + RCHECK(WRITE_VALUE(fde->fde_adrange, dbg->dbg_pointer_size)); + + /* Write FDE frame instructions. */ + RCHECK(WRITE_BLOCK(fde->fde_inst, fde->fde_instlen)); + + /* Add padding. */ + len = ds->ds_size - fde->fde_offset - 4; + fde->fde_length = roundup(len, dbg->dbg_pointer_size); + while (len++ < fde->fde_length) + RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); + + /* Fill in the length field. */ + dbg->write(ds->ds_data, &offset, fde->fde_length, 4); + + return (DW_DLE_NONE); + +gen_fail: + return (ret); +} + +int +_dwarf_frame_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_P_Cie cie; + Dwarf_P_Fde fde; + int ret; + + if (STAILQ_EMPTY(&dbg->dbgp_cielist)) + return (DW_DLE_NONE); + + /* Create .debug_frame section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_frame", 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for .debug_frame */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Generate list of CIE. */ + STAILQ_FOREACH(cie, &dbg->dbgp_cielist, cie_next) + RCHECK(_dwarf_frame_gen_cie(dbg, ds, cie, error)); + + /* Generate list of FDE. */ + STAILQ_FOREACH(fde, &dbg->dbgp_fdelist, fde_next) + RCHECK(_dwarf_frame_gen_fde(dbg, ds, drs, fde, error)); + + /* Inform application the creation of .debug_frame ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_frame */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_frame_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Cie cie, tcie; + Dwarf_P_Fde fde, tfde; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(cie, &dbg->dbgp_cielist, cie_next, tcie) { + STAILQ_REMOVE(&dbg->dbgp_cielist, cie, _Dwarf_Cie, cie_next); + if (cie->cie_augment) + free(cie->cie_augment); + if (cie->cie_initinst) + free(cie->cie_initinst); + free(cie); + } + dbg->dbgp_cielen = 0; + + STAILQ_FOREACH_SAFE(fde, &dbg->dbgp_fdelist, fde_next, tfde) { + STAILQ_REMOVE(&dbg->dbgp_fdelist, fde, _Dwarf_Fde, fde_next); + if (fde->fde_inst != NULL) + free(fde->fde_inst); + free(fde); + } + dbg->dbgp_fdelen = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_info.c b/contrib/elftoolchain/libdwarf/libdwarf_info.c new file mode 100644 index 0000000000..38091a367d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_info.c @@ -0,0 +1,410 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2010,2011,2014,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_info.c 4038 2024-03-06 10:17:40Z jkoshy $"); + +int +_dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_cu_current == NULL); + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu != NULL) { + dbg->dbg_cu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_info_loaded) + return (DW_DLE_NO_ENTRY); + + dbg->dbg_info_off = 0; + ret = _dwarf_info_load(dbg, 0, 1, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_cu_current = STAILQ_FIRST(&dbg->dbg_cu); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_first_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU tu; + int ret; + + assert(dbg->dbg_tu_current == NULL); + tu = STAILQ_FIRST(&dbg->dbg_tu); + if (tu != NULL) { + dbg->dbg_tu_current = tu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) + return (DW_DLE_NO_ENTRY); + + dbg->dbg_types_off = 0; + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_FIRST(&dbg->dbg_tu); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_cu_current != NULL); + cu = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); + if (cu != NULL) { + dbg->dbg_cu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_info_loaded) { + dbg->dbg_cu_current = NULL; + return (DW_DLE_NO_ENTRY); + } + + ret = _dwarf_info_load(dbg, 0, 1, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_cu_current = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_next_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_tu_current != NULL); + cu = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + if (cu != NULL) { + dbg->dbg_tu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) { + dbg->dbg_tu_current = NULL; + return (DW_DLE_NO_ENTRY); + } + + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Section *ds; + int dwarf_size, ret; + uint64_t length; + uint64_t next_offset; + uint64_t offset; + + ret = DW_DLE_NONE; + + if (is_info) { + if (dbg->dbg_info_loaded) + return (ret); + offset = dbg->dbg_info_off; + ds = dbg->dbg_info_sec; + if (ds == NULL) + return (DW_DLE_NO_ENTRY); + } else { + if (dbg->dbg_types_loaded) + return (ret); + offset = dbg->dbg_types_off; + ds = dbg->dbg_types_sec; + if (ds == NULL) + return (DW_DLE_NO_ENTRY); + } + + while (offset < ds->ds_size) { + if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + cu->cu_dbg = dbg; + cu->cu_is_info = is_info; + cu->cu_offset = offset; + + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + length = dbg->read(ds->ds_data, &offset, 8); + dwarf_size = 8; + } else + dwarf_size = 4; + cu->cu_dwarf_size = dwarf_size; + + /* + * Check if there is enough ELF data for this CU. This assumes + * that libelf gives us the entire section in one Elf_Data + * object. + */ + if (length > ds->ds_size - offset) { + free(cu); + DWARF_SET_ERROR(dbg, error, DW_DLE_CU_LENGTH_ERROR); + return (DW_DLE_CU_LENGTH_ERROR); + } + + /* Compute the offset to the next compilation unit: */ + next_offset = offset + length; + if (is_info) + dbg->dbg_info_off = next_offset; + else + dbg->dbg_types_off = next_offset; + + /* Initialise the compilation unit. */ + cu->cu_length = length; + cu->cu_length_size = (dwarf_size == 4 ? 4 : 12); + cu->cu_version = dbg->read(ds->ds_data, &offset, 2); + + /* Verify the DWARF version is supported. */ + if (cu->cu_version < 2 || cu->cu_version > 5) { + free(cu); + DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + ret = DW_DLE_VERSION_STAMP_ERROR; + break; + } + + if (cu->cu_version == 5) { + /* + * DWARF5 has unit_type, abbrev_offset and pointer_size + * fields are reordered. + */ + cu->cu_unit_type = dbg->read(ds->ds_data, &offset, 1); + cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, + 1); + cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + } else { + /* DWARF4 or lower. */ + cu->cu_unit_type = is_info ? DW_UT_compile : DW_UT_type; + cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, + 1); + } + + cu->cu_abbrev_offset_cur = cu->cu_abbrev_offset; + cu->cu_next_offset = next_offset; + + /* DWARF5 Section 7.5.1.2 defines the dwo_id field. */ + if (cu->cu_unit_type == DW_UT_skeleton || + cu->cu_unit_type == DW_UT_split_compile) { + /* TODO: the ID is implementation defined. */ + cu->cu_dwo_id = dbg->read(ds->ds_data, &offset, 8); + } + + /* .debug_types extra fields. */ + if (!is_info || cu->cu_unit_type == DW_UT_type || + cu->cu_unit_type == DW_UT_split_type) { + memcpy(cu->cu_type_sig.signature, + (char *) ds->ds_data + offset, 8); + offset += 8; + cu->cu_type_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + } + + /* Add the compilation unit to the list. */ + if (is_info) + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + else + STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next); + + cu->cu_1st_offset = offset; + + offset = next_offset; + + if (!load_all) + break; + } + + if (is_info) { + if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) + dbg->dbg_info_loaded = 1; + } else { + if ((Dwarf_Unsigned) dbg->dbg_types_off >= ds->ds_size) + dbg->dbg_types_loaded = 1; + } + + return (ret); +} + +void +_dwarf_info_cleanup(Dwarf_Debug dbg) +{ + Dwarf_CU cu, tcu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + STAILQ_FOREACH_SAFE(cu, &dbg->dbg_cu, cu_next, tcu) { + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + if (cu->cu_lineinfo != NULL) { + _dwarf_lineno_cleanup(cu->cu_lineinfo); + cu->cu_lineinfo = NULL; + } + free(cu); + } + + _dwarf_type_unit_cleanup(dbg); +} + +void +_dwarf_type_unit_cleanup(Dwarf_Debug dbg) +{ + Dwarf_CU cu, tcu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + STAILQ_FOREACH_SAFE(cu, &dbg->dbg_tu, cu_next, tcu) { + STAILQ_REMOVE(&dbg->dbg_tu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + free(cu); + } +} + +int +_dwarf_info_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_Unsigned offset; + Dwarf_CU cu; + int ret; + + assert(dbg != NULL && dbg->write_alloc != NULL); + + if (dbg->dbgp_root_die == NULL) + return (DW_DLE_NONE); + + /* Create the single CU for this debugging object. */ + if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + cu->cu_dbg = dbg; + cu->cu_version = 2; /* DWARF2 */ + cu->cu_pointer_size = dbg->dbg_pointer_size; + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + + /* Create .debug_info section. */ + if ((ret = _dwarf_section_init(dbg, &dbg->dbgp_info, ".debug_info", 0, + error)) != DW_DLE_NONE) + goto gen_fail1; + ds = dbg->dbgp_info; + + /* Create relocation section for .debug_init */ + if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Length placeholder. (We only use 32-bit DWARF format) */ + RCHECK(WRITE_VALUE(cu->cu_length, 4)); + + /* Write CU version */ + RCHECK(WRITE_VALUE(cu->cu_version, 2)); + + /* + * Write abbrev offset. (always 0, we only support single CU) + * Also generate a relocation entry for this offset. + */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, cu->cu_abbrev_offset, ".debug_abbrev", error)); + + /* Pointer size. */ + RCHECK(WRITE_VALUE(cu->cu_pointer_size, 1)); + + /* Transform the DIE(s) of this CU. */ + RCHECK(_dwarf_die_gen(dbg, cu, drs, error)); + + /* Now we can fill in the length of this CU. */ + cu->cu_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, cu->cu_length, 4); + + /* Inform application the creation of .debug_info ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* + * Inform application the creation of relocation section for + * .debug_info. + */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &dbg->dbgp_info); + +gen_fail1: + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + free(cu); + + return (ret); +} + +void +_dwarf_info_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_CU cu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu != NULL) { + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + free(cu); + } +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_init.c new file mode 100644 index 0000000000..89f67d6388 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_init.c @@ -0,0 +1,316 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_init.c 4048 2024-07-20 07:15:26Z jkoshy $"); + +static int +_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + const Dwarf_Obj_Access_Methods *m; + Dwarf_Obj_Access_Section sec; + void *obj; + Dwarf_Unsigned cnt; + Dwarf_Half i; + int ret; + + assert(dbg != NULL); + assert(dbg->dbg_iface != NULL); + + m = dbg->dbg_iface->methods; + obj = dbg->dbg_iface->object; + + assert(m != NULL); + assert(obj != NULL); + + if (m->get_byte_order(obj) == DW_OBJECT_MSB) { + dbg->read = _dwarf_read_msb; + dbg->write = _dwarf_write_msb; + dbg->decode = _dwarf_decode_msb; + } else { + dbg->read = _dwarf_read_lsb; + dbg->write = _dwarf_write_lsb; + dbg->decode = _dwarf_decode_lsb; + } + + dbg->dbg_pointer_size = m->get_pointer_size(obj); + dbg->dbg_offset_size = m->get_length_size(obj); + + cnt = m->get_section_count(obj); + + if (cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); + return (DW_DLE_DEBUG_INFO_NULL); + } + + dbg->dbg_seccnt = cnt; + + if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + for (i = 0; i < cnt; i++) { + if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + + dbg->dbg_section[i].ds_addr = sec.addr; + dbg->dbg_section[i].ds_size = sec.size; + dbg->dbg_section[i].ds_name = sec.name; + + if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) + != DW_DLV_OK) { + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + } + dbg->dbg_section[cnt].ds_name = NULL; + + dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info"); + + /* Try to find the optional DWARF4 .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); + + /* Initialise call frame API related parameters. */ + _dwarf_frame_params_init(dbg); + + return (DW_DLV_OK); +} + +static int +_dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) +{ + + /* Producer only support DWARF2 which has fixed 32bit offset. */ + dbg->dbg_offset_size = 4; + + if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) + pf |= DW_DLC_SIZE_32; + + if (pf & DW_DLC_SIZE_64) + dbg->dbg_pointer_size = 8; + else + dbg->dbg_pointer_size = 4; + + if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if (pf & DW_DLC_ISA_IA64) + dbg->dbgp_isa = DW_ISA_IA64; + else + dbg->dbgp_isa = DW_ISA_MIPS; + + if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 && + (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) { +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN + pf |= DW_DLC_TARGET_BIGENDIAN; +#else + pf |= DW_DLC_TARGET_LITTLEENDIAN; +#endif + } + + if (pf & DW_DLC_TARGET_BIGENDIAN) { + dbg->write = _dwarf_write_msb; + dbg->write_alloc = _dwarf_write_msb_alloc; + } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) { + dbg->write = _dwarf_write_lsb; + dbg->write_alloc = _dwarf_write_lsb_alloc; + } else + assert(0); + + if (pf & DW_DLC_STREAM_RELOCATIONS && + pf & DW_DLC_SYMBOLIC_RELOCATIONS) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && + (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) + pf |= DW_DLC_STREAM_RELOCATIONS; + + dbg->dbgp_flags = pf; + + STAILQ_INIT(&dbg->dbgp_dielist); + STAILQ_INIT(&dbg->dbgp_pelist); + STAILQ_INIT(&dbg->dbgp_seclist); + STAILQ_INIT(&dbg->dbgp_drslist); + STAILQ_INIT(&dbg->dbgp_cielist); + STAILQ_INIT(&dbg->dbgp_fdelist); + + if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); + STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); + + if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&dbg->dbgp_as->as_arlist); + + return (DW_DLE_NONE); +} + +int +_dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Error *error) +{ + int ret; + + ret = DW_DLE_NONE; + + /* + * Set the error handler fields early, so that the application + * is notified of initialization errors. + */ + dbg->dbg_errhand = errhand; + dbg->dbg_errarg = errarg; + + STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_tu); + STAILQ_INIT(&dbg->dbg_rllist); + STAILQ_INIT(&dbg->dbg_aslist); + STAILQ_INIT(&dbg->dbg_mslist); + + if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { + ret = _dwarf_consumer_init(dbg, error); + if (ret != DW_DLE_NONE) { + _dwarf_deinit(dbg); + return (ret); + } + } + + if (dbg->dbg_mode == DW_DLC_WRITE) { + ret = _dwarf_producer_init(dbg, pro_flags, error); + if (ret != DW_DLE_NONE) { + _dwarf_deinit(dbg); + return (ret); + } + } + + /* + * Initialise internal string table. + */ + if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) + return (ret); + + return (DW_DLE_NONE); +} + +static void +_dwarf_producer_deinit(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + _dwarf_info_pro_cleanup(dbg); + _dwarf_die_pro_cleanup(dbg); + _dwarf_expr_cleanup(dbg); + _dwarf_lineno_pro_cleanup(dbg); + _dwarf_frame_pro_cleanup(dbg); + _dwarf_arange_pro_cleanup(dbg); + _dwarf_macinfo_pro_cleanup(dbg); + _dwarf_strtab_cleanup(dbg); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars); + _dwarf_section_cleanup(dbg); + _dwarf_reloc_cleanup(dbg); +} + +static void +_dwarf_consumer_deinit(Dwarf_Debug dbg) +{ + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + _dwarf_info_cleanup(dbg); + _dwarf_ranges_cleanup(dbg); + _dwarf_frame_cleanup(dbg); + _dwarf_arange_cleanup(dbg); + _dwarf_macinfo_cleanup(dbg); + _dwarf_strtab_cleanup(dbg); + _dwarf_str_offsets_cleanup(dbg); + _dwarf_nametbl_cleanup(&dbg->dbg_globals); + _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); + _dwarf_nametbl_cleanup(&dbg->dbg_weaks); + _dwarf_nametbl_cleanup(&dbg->dbg_funcs); + _dwarf_nametbl_cleanup(&dbg->dbg_vars); + _dwarf_nametbl_cleanup(&dbg->dbg_types); + + free(dbg->dbg_section); +} + +void +_dwarf_deinit(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_READ) + _dwarf_consumer_deinit(dbg); + else if (dbg->dbg_mode == DW_DLC_WRITE) + _dwarf_producer_deinit(dbg); +} + +int +_dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + if ((dbg = calloc(1, sizeof(struct _Dwarf_Debug))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_mode = mode; + + *ret_dbg = dbg; + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c new file mode 100644 index 0000000000..4c165d6124 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c @@ -0,0 +1,1118 @@ +/*- + * Copyright (c) 2009,2010,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_lineno.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +static int +_dwarf_lineno_make_fullpath(Dwarf_Debug dbg, Dwarf_LineInfo li, + Dwarf_LineFile lf, const char *compdir, Dwarf_Error *error) +{ + const char *dirname; + int slen; + + /* Make full pathname if need. */ + if (*lf->lf_fname != '/') { + dirname = compdir; + if (lf->lf_dirndx > 0) + dirname = li->li_incdirs[lf->lf_dirndx - 1]; + if (dirname != NULL) { + slen = strlen(dirname) + strlen(lf->lf_fname) + 2; + if ((lf->lf_fullpath = malloc(slen)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + snprintf(lf->lf_fullpath, slen, "%s/%s", dirname, + lf->lf_fname); + } + } + + return (DW_DLE_NONE); +} + +static int +_dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, + Dwarf_Error *error, Dwarf_Debug dbg) +{ + Dwarf_LineFile lf; + uint8_t *src; + int ret; + + src = *p; + + if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + lf->lf_fullpath = NULL; + lf->lf_fname = (char *) src; + src += strlen(lf->lf_fname) + 1; + lf->lf_dirndx = _dwarf_decode_uleb128(&src); + if (lf->lf_dirndx > li->li_inclen) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_DIR_INDEX_BAD); + return (DW_DLE_DIR_INDEX_BAD); + } + + ret = _dwarf_lineno_make_fullpath(dbg, li, lf, compdir, error); + if (ret != DW_DLE_NONE) { + free(lf); + return (ret); + } + + lf->lf_mtime = _dwarf_decode_uleb128(&src); + lf->lf_size = _dwarf_decode_uleb128(&src); + STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); + li->li_lflen++; + + *p = src; + + return (DW_DLE_NONE); +} + +static int +_dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, + uint8_t *pe, const char *compdir, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Line ln, tln; + uint64_t address, file, line, column, opsize; + int is_stmt, basic_block, end_sequence; + int ret; + +#define RESET_REGISTERS \ + do { \ + address = 0; \ + file = 1; \ + line = 1; \ + column = 0; \ + is_stmt = li->li_defstmt; \ + basic_block = 0; \ + end_sequence = 0; \ + } while(0) + +#define APPEND_ROW \ + do { \ + ln = malloc(sizeof(struct _Dwarf_Line)); \ + if (ln == NULL) { \ + ret = DW_DLE_MEMORY; \ + DWARF_SET_ERROR(dbg, error, ret); \ + goto prog_fail; \ + } \ + ln->ln_li = li; \ + ln->ln_addr = address; \ + ln->ln_symndx = 0; \ + ln->ln_fileno = file; \ + ln->ln_lineno = line; \ + ln->ln_column = column; \ + ln->ln_bblock = basic_block; \ + ln->ln_stmt = is_stmt; \ + ln->ln_endseq = end_sequence; \ + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);\ + li->li_lnlen++; \ + } while(0) + +#define LINE(x) (li->li_lbase + (((x) - li->li_opbase) % li->li_lrange)) +#define ADDRESS(x) ((((x) - li->li_opbase) / li->li_lrange) * li->li_minlen) + + dbg = cu->cu_dbg; + + /* + * Set registers to their default values. + */ + RESET_REGISTERS; + + /* + * Start line number program. + */ + while (p < pe) { + if (*p == 0) { + + /* + * Extended Opcodes. + */ + + p++; + opsize = _dwarf_decode_uleb128(&p); + switch (*p) { + case DW_LNE_end_sequence: + p++; + end_sequence = 1; + APPEND_ROW; + RESET_REGISTERS; + break; + case DW_LNE_set_address: + p++; + address = dbg->decode(&p, cu->cu_pointer_size); + break; + case DW_LNE_define_file: + p++; + ret = _dwarf_lineno_add_file(li, &p, compdir, + error, dbg); + if (ret != DW_DLE_NONE) + goto prog_fail; + break; + default: + /* Unrecognized extened opcodes. */ + p += opsize; + } + + } else if (*p > 0 && *p < li->li_opbase) { + + /* + * Standard Opcodes. + */ + + switch (*p++) { + case DW_LNS_copy: + APPEND_ROW; + basic_block = 0; + break; + case DW_LNS_advance_pc: + address += _dwarf_decode_uleb128(&p) * + li->li_minlen; + break; + case DW_LNS_advance_line: + line += _dwarf_decode_sleb128(&p); + break; + case DW_LNS_set_file: + file = _dwarf_decode_uleb128(&p); + break; + case DW_LNS_set_column: + column = _dwarf_decode_uleb128(&p); + break; + case DW_LNS_negate_stmt: + is_stmt = !is_stmt; + break; + case DW_LNS_set_basic_block: + basic_block = 1; + break; + case DW_LNS_const_add_pc: + address += ADDRESS(255); + break; + case DW_LNS_fixed_advance_pc: + address += dbg->decode(&p, 2); + break; + case DW_LNS_set_prologue_end: + break; + case DW_LNS_set_epilogue_begin: + break; + case DW_LNS_set_isa: + (void) _dwarf_decode_uleb128(&p); + break; + default: + /* Unrecognized extened opcodes. What to do? */ + break; + } + + } else { + + /* + * Special Opcodes. + */ + + line += LINE(*p); + address += ADDRESS(*p); + APPEND_ROW; + basic_block = 0; + p++; + } + } + + return (DW_DLE_NONE); + +prog_fail: + + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); + free(ln); + } + + return (ret); + +#undef RESET_REGISTERS +#undef APPEND_ROW +#undef LINE +#undef ADDRESS +} + +struct lnct { + unsigned type; + unsigned form; +}; + + +static int +_dwarf_lineno_parse_lnct_desc(Dwarf_Debug dbg, int fmt, struct lnct **lnct, + uint8_t *data, uint64_t *offsetp, Dwarf_Error *error) +{ + int i; + + if (fmt == 0) { + *lnct = NULL; + return (DW_DLE_NONE); + } + + if ((*lnct = calloc(fmt, sizeof(struct lnct))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + for (i = 0; i < fmt; i++) { + (*lnct)[i].type = _dwarf_read_uleb128(data, offsetp); + (*lnct)[i].form = _dwarf_read_uleb128(data, offsetp); + } + + return (DW_DLE_NONE); +} + +static int +_dwarf_lineno_lnct_path(Dwarf_Debug dbg, char **fname, unsigned form, + uint8_t *data, uint64_t size, uint64_t *offsetp, int dwarf_size, + Dwarf_Error *error) +{ + Dwarf_Unsigned sp; + int ret; + + ret = DW_DLE_NONE; + + switch (form) { + case DW_FORM_string: + *fname = _dwarf_read_string(data, size, offsetp); + break; + case DW_FORM_strp: + sp = dbg->read(data, offsetp, dwarf_size); + *fname = _dwarf_strtab_get_table(dbg) + sp; + break; + case DW_FORM_line_strp: + sp = dbg->read(data, offsetp, dwarf_size); + *fname = _dwarf_strtab_get_line_table(dbg) + sp; + break; + case DW_FORM_strp_sup: + sp = dbg->read(data, offsetp, dwarf_size); + *fname = NULL; /* TODO: support sup string table. */ + break; + default: + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + break; + } + + return (ret); +} + +static int +_dwarf_lineno_lnct_dirndx(Dwarf_Debug dbg, Dwarf_Unsigned *dirndx, + unsigned form, uint8_t *data, uint64_t *offsetp, Dwarf_Error *error) +{ + int ret; + + ret = DW_DLE_NONE; + + switch (form) { + case DW_FORM_data1: + *dirndx = dbg->read(data, offsetp, 1); + break; + case DW_FORM_data2: + *dirndx = dbg->read(data, offsetp, 2); + break; + case DW_FORM_udata: + *dirndx = _dwarf_read_uleb128(data, offsetp); + break; + default: + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + break; + } + + return (ret); +} + +static int +_dwarf_lineno_lnct_timestamp(Dwarf_Debug dbg, Dwarf_Unsigned *ts, + unsigned form, uint8_t *data, uint64_t *offsetp, Dwarf_Error *error) +{ + int ret; + + ret = DW_DLE_NONE; + + switch (form) { + case DW_FORM_udata: + *ts = _dwarf_read_uleb128(data, offsetp); + break; + case DW_FORM_data4: + *ts = dbg->read(data, offsetp, 4); + break; + case DW_FORM_data8: + *ts = dbg->read(data, offsetp, 8); + break; + case DW_FORM_block: + /* TODO: Not supported. */ + default: + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + break; + } + + return (ret); +} + +static int +_dwarf_lineno_lnct_size(Dwarf_Debug dbg, Dwarf_Unsigned *sz, unsigned form, + uint8_t *data, uint64_t *offsetp, Dwarf_Error *error) +{ + int ret; + + ret = DW_DLE_NONE; + + switch (form) { + case DW_FORM_udata: + *sz = _dwarf_read_uleb128(data, offsetp); + break; + case DW_FORM_data1: + *sz = dbg->read(data, offsetp, 1); + break; + case DW_FORM_data2: + *sz = dbg->read(data, offsetp, 2); + break; + case DW_FORM_data4: + *sz = dbg->read(data, offsetp, 4); + break; + case DW_FORM_data8: + *sz = dbg->read(data, offsetp, 8); + break; + default: + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + break; + } + + return (ret); +} + +static int +_dwarf_lineno_lnct_md5(Dwarf_Debug dbg, Dwarf_Form_Data16 *md5, + unsigned form, uint8_t *data, uint64_t *offsetp, Dwarf_Error *error) +{ + + if (form != DW_FORM_data16) { + DWARF_SET_ERROR(dbg, error, DW_DLE_LNCT_DESC_BAD); + return (DW_DLE_LNCT_DESC_BAD); + } + + memcpy(md5->fd_data, data + *offsetp, 16); + offsetp += 16; + + return (DW_DLE_NONE); +} + +int +_dwarf_lineno_init(Dwarf_Die die, uint64_t offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Section *ds; + Dwarf_CU cu; + Dwarf_Attribute at; + Dwarf_LineInfo li; + Dwarf_LineFile lf, tlf; + struct lnct *lnct; + char *compdir; + uint64_t length, hdroff, endoff; + uint8_t *p; + int dwarf_size, fmt, i, j, ret; + + cu = die->die_cu; + assert(cu != NULL); + + dbg = cu->cu_dbg; + assert(dbg != NULL); + + if ((ds = _dwarf_find_section(dbg, ".debug_line")) == NULL) + return (DW_DLE_NONE); + + /* + * Try to find out the dir where the CU was compiled. Later we + * will use the dir to create full pathnames, if need. + */ + compdir = NULL; + at = _dwarf_attr_find(die, DW_AT_comp_dir); + if (at != NULL) { + switch (at->at_form) { + case DW_FORM_strp: + case DW_FORM_strp_sup: + case DW_FORM_line_strp: + compdir = at->u[1].s; + break; + case DW_FORM_string: + compdir = at->u[0].s; + break; + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + if (_dwarf_read_indexed_str(dbg, cu, at->u[0].u64, + &compdir, error) != DW_DLE_NONE) + return ret; + default: + break; + } + } + + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - offset) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLE_DEBUG_LINE_LENGTH_BAD); + } + + if ((li = calloc(1, sizeof(struct _Dwarf_LineInfo))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* + * Read in line number program header. + */ + li->li_length = length; + endoff = offset + length; + li->li_version = dbg->read(ds->ds_data, &offset, 2); + if (li->li_version == 5) { + (void) dbg->read(ds->ds_data, &offset, 1); /* TODO */ + (void) dbg->read(ds->ds_data, &offset, 1); /* TODO */ + } + li->li_hdrlen = dbg->read(ds->ds_data, &offset, dwarf_size); + hdroff = offset; + li->li_minlen = dbg->read(ds->ds_data, &offset, 1); + if (li->li_version >= 4) + li->li_maxop = dbg->read(ds->ds_data, &offset, 1); + li->li_defstmt = dbg->read(ds->ds_data, &offset, 1); + li->li_lbase = dbg->read(ds->ds_data, &offset, 1); + li->li_lrange = dbg->read(ds->ds_data, &offset, 1); + li->li_opbase = dbg->read(ds->ds_data, &offset, 1); + STAILQ_INIT(&li->li_lflist); + STAILQ_INIT(&li->li_lnlist); + + if ((int)li->li_hdrlen - 5 < li->li_opbase - 1) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + if ((li->li_oplen = malloc(li->li_opbase)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + /* + * Read in std opcode arg length list. Note that the first + * element is not used. + */ + for (i = 1; i < li->li_opbase; i++) + li->li_oplen[i] = dbg->read(ds->ds_data, &offset, 1); + + /* + * Directory and filename parser for DWARF4 and below. + */ + if (li->li_version <= 4) { + + /* + * Check how many strings in the include dir string array. + */ + length = 0; + p = ds->ds_data + offset; + while (*p != '\0') { + while (*p++ != '\0') + ; + length++; + } + li->li_inclen = length; + + /* Sanity check. */ + if (p - ds->ds_data > (int) ds->ds_size) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + if (length != 0) { + if ((li->li_incdirs = malloc(length * sizeof(char *))) == + NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + } + + /* Fill in include dir array. */ + i = 0; + p = ds->ds_data + offset; + while (*p != '\0') { + li->li_incdirs[i++] = (char *) p; + while (*p++ != '\0') + ; + } + + p++; + + /* + * Process file list. + */ + while (*p != '\0') { + ret = _dwarf_lineno_add_file(li, &p, compdir, error, dbg); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + if (p - ds->ds_data > (int) ds->ds_size) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + } + + p++; + + /* Sanity check. */ + if (p - ds->ds_data - hdroff != li->li_hdrlen) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + goto lnprog; + } + + /* + * DWARF5 has completely overhauled the dir/source file information + * fields, which are incompatible with DWARF4 or lower. + */ + + lnct = NULL; + fmt = dbg->read(ds->ds_data, &offset, 1); + if ((ret = _dwarf_lineno_parse_lnct_desc(dbg, fmt, &lnct, ds->ds_data, + &offset, error)) != DW_DLE_NONE) + goto fail_cleanup; + + li->li_inclen = dbg->read(ds->ds_data, &offset, 1); + if (li->li_inclen == 0) { + if (fmt > 0) { + free(lnct); + ret = DW_DLE_DIR_COUNT_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + goto file_entries; + } + + if (fmt == 0) { + ret = DW_DLE_DIR_COUNT_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + if ((li->li_incdirs = malloc(length * sizeof(char *))) == NULL) { + free(lnct); + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + for (i = 0; i < li->li_inclen; i++) { + for (j = 0; j < fmt; j++) { + if (lnct[j].type != DW_LNCT_path) { + free(lnct); + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + ret = _dwarf_lineno_lnct_path(dbg, &li->li_incdirs[i], + lnct[j].form, ds->ds_data, ds->ds_size, &offset, + dwarf_size, error); + if (ret != DW_DLE_NONE) { + free(lnct); + goto fail_cleanup; + } + } + } + if (lnct) + free(lnct); + +file_entries: + + lnct = NULL; + fmt = dbg->read(ds->ds_data, &offset, 1); + if ((ret = _dwarf_lineno_parse_lnct_desc(dbg, fmt, &lnct, ds->ds_data, + &offset, error)) != DW_DLE_NONE) + goto fail_cleanup; + + li->li_lflen = dbg->read(ds->ds_data, &offset, 1); + if (li->li_lflen == 0) { + if (fmt > 0) { + free(lnct); + ret = DW_DLE_FILE_COUNT_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + p = ds->ds_data + offset; + goto lnprog; + } + + for (i = 0; i < li->li_lflen; i++) { + if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { + free(lnct); + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + for (j = 0; j < fmt; j++) { + switch (lnct[j].type) { + case DW_LNCT_path: + ret = _dwarf_lineno_lnct_path(dbg, + &lf->lf_fname, lnct[j].form, ds->ds_data, + ds->ds_size, &offset, dwarf_size, error); + break; + case DW_LNCT_directory_index: + ret = _dwarf_lineno_lnct_dirndx(dbg, + &lf->lf_dirndx, lnct[j].form, ds->ds_data, + &offset, error); + break; + case DW_LNCT_timestamp: + ret = _dwarf_lineno_lnct_timestamp(dbg, + &lf->lf_mtime, lnct[j].form, ds->ds_data, + &offset, error); + break; + case DW_LNCT_size: + ret = _dwarf_lineno_lnct_size(dbg, + &lf->lf_size, lnct[j].form, ds->ds_data, + &offset, error); + break; + case DW_LNCT_MD5: + ret = _dwarf_lineno_lnct_md5(dbg, + &lf->lf_md5, lnct[j].form, ds->ds_data, + &offset, error); + break; + default: + ret = DW_DLE_LNCT_DESC_BAD; + DWARF_SET_ERROR(dbg, error, ret); + break; + } + if (ret != DW_DLE_NONE) { + free(lf); + free(lnct); + goto fail_cleanup; + } + } + ret = _dwarf_lineno_make_fullpath(dbg, li, lf, compdir, error); + if (ret != DW_DLE_NONE) { + free(lf); + free(lnct); + goto fail_cleanup; + } + STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); + } + if (lnct) + free(lnct); + + p = ds->ds_data + offset; + +lnprog: + /* + * Process line number program. + */ + ret = _dwarf_lineno_run_program(cu, li, p, ds->ds_data + endoff, compdir, + error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + cu->cu_lineinfo = li; + + return (DW_DLE_NONE); + +fail_cleanup: + + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); + if (lf->lf_fullpath) + free(lf->lf_fullpath); + free(lf); + } + + if (li->li_oplen) + free(li->li_oplen); + if (li->li_incdirs) + free(li->li_incdirs); + free(li); + + return (ret); +} + +void +_dwarf_lineno_cleanup(Dwarf_LineInfo li) +{ + Dwarf_LineFile lf, tlf; + Dwarf_Line ln, tln; + + if (li == NULL) + return; + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, + _Dwarf_LineFile, lf_next); + if (lf->lf_fullpath) + free(lf->lf_fullpath); + free(lf); + } + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, + ln_next); + free(ln); + } + if (li->li_oplen) + free(li->li_oplen); + if (li->li_incdirs) + free(li->li_incdirs); + if (li->li_lnarray) + free(li->li_lnarray); + if (li->li_lfnarray) + free(li->li_lfnarray); + free(li); +} + +static int +_dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Rel_Section drs, Dwarf_Error * error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + Dwarf_Unsigned address, file, line, spc; + Dwarf_Unsigned addr0, maddr; + Dwarf_Signed line0, column; + int is_stmt, basic_block; + int need_copy; + int ret; + +#define RESET_REGISTERS \ + do { \ + address = 0; \ + file = 1; \ + line = 1; \ + column = 0; \ + is_stmt = li->li_defstmt; \ + basic_block = 0; \ + } while(0) + + li = dbg->dbgp_lineinfo; + maddr = (255 - li->li_opbase) / li->li_lrange; + + RESET_REGISTERS; + + STAILQ_FOREACH(ln, &li->li_lnlist, ln_next) { + if (ln->ln_symndx > 0) { + /* + * Generate DW_LNE_set_address extended op. + */ + RCHECK(WRITE_VALUE(0, 1)); + RCHECK(WRITE_ULEB128(dbg->dbg_pointer_size + 1)); + RCHECK(WRITE_VALUE(DW_LNE_set_address, 1)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, + ds->ds_size, ln->ln_symndx, ln->ln_addr, + NULL, error)); + address = ln->ln_addr; + continue; + } else if (ln->ln_endseq) { + addr0 = (ln->ln_addr - address) / li->li_minlen; + if (addr0 != 0) { + RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); + RCHECK(WRITE_ULEB128(addr0)); + } + + /* + * Generate DW_LNE_end_sequence. + */ + RCHECK(WRITE_VALUE(0, 1)); + RCHECK(WRITE_ULEB128(1)); + RCHECK(WRITE_VALUE(DW_LNE_end_sequence, 1)); + RESET_REGISTERS; + continue; + } + + /* + * Generate standard opcodes for file, column, is_stmt or + * basic_block changes. + */ + if (ln->ln_fileno != file) { + RCHECK(WRITE_VALUE(DW_LNS_set_file, 1)); + RCHECK(WRITE_ULEB128(ln->ln_fileno)); + file = ln->ln_fileno; + } + if (ln->ln_column != column) { + RCHECK(WRITE_VALUE(DW_LNS_set_column, 1)); + RCHECK(WRITE_ULEB128(ln->ln_column)); + column = ln->ln_column; + } + if (ln->ln_stmt != is_stmt) { + RCHECK(WRITE_VALUE(DW_LNS_negate_stmt, 1)); + is_stmt = ln->ln_stmt; + } + if (ln->ln_bblock && !basic_block) { + RCHECK(WRITE_VALUE(DW_LNS_set_basic_block, 1)); + basic_block = 1; + } + + /* + * Calculate address and line number change. + */ + addr0 = (ln->ln_addr - address) / li->li_minlen; + line0 = ln->ln_lineno - line; + + if (addr0 == 0 && line0 == 0) + continue; + + /* + * Check if line delta is with the range and if the special + * opcode can be used. + */ + assert(li->li_lbase <= 0); + if (line0 >= li->li_lbase && + line0 <= li->li_lbase + li->li_lrange - 1) { + spc = (line0 - li->li_lbase) + + (li->li_lrange * addr0) + li->li_opbase; + if (spc <= 255) { + RCHECK(WRITE_VALUE(spc, 1)); + basic_block = 0; + goto next_line; + } + } + + /* Generate DW_LNS_advance_line for line number change. */ + if (line0 != 0) { + RCHECK(WRITE_VALUE(DW_LNS_advance_line, 1)); + RCHECK(WRITE_SLEB128(line0)); + line0 = 0; + need_copy = 1; + } else + need_copy = basic_block; + + if (addr0 != 0) { + /* See if it can be handled by DW_LNS_const_add_pc. */ + spc = (line0 - li->li_lbase) + + (li->li_lrange * (addr0 - maddr)) + li->li_opbase; + if (addr0 >= maddr && spc <= 255) { + RCHECK(WRITE_VALUE(DW_LNS_const_add_pc, 1)); + RCHECK(WRITE_VALUE(spc, 1)); + } else { + /* Otherwise we use DW_LNS_advance_pc. */ + RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); + RCHECK(WRITE_ULEB128(addr0)); + } + } + + if (need_copy) { + RCHECK(WRITE_VALUE(DW_LNS_copy, 1)); + basic_block = 0; + } + + next_line: + address = ln->ln_addr; + line = ln->ln_lineno; + } + + return (DW_DLE_NONE); + +gen_fail: + return (ret); + +#undef RESET_REGISTERS +} + +static uint8_t +_dwarf_get_minlen(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL); + + switch (dbg->dbgp_isa) { + case DW_ISA_ARM: + return (2); + case DW_ISA_X86: + case DW_ISA_X86_64: + return (1); + default: + return (4); + } +} + +static uint8_t oplen[] = {0, 1, 1, 1, 1, 0, 0, 0, 1}; + +int +_dwarf_lineno_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_Unsigned offset; + int i, ret; + + assert(dbg != NULL && dbg->dbgp_lineinfo != NULL); + + li = dbg->dbgp_lineinfo; + if (STAILQ_EMPTY(&li->li_lnlist)) + return (DW_DLE_NONE); + + li->li_length = 0; + li->li_version = 2; + li->li_hdrlen = 0; + li->li_minlen = _dwarf_get_minlen(dbg); + li->li_defstmt = 1; + li->li_lbase = -5; + li->li_lrange = 14; + li->li_opbase = 10; + + /* Create .debug_line section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_line", 0, error)) != + DW_DLE_NONE) + return (ret); + + /* Create relocation section for .debug_line */ + if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != + DW_DLE_NONE) + goto gen_fail1; + + /* Length placeholder. (We only use 32-bit DWARF format) */ + RCHECK(WRITE_VALUE(0, 4)); + + /* Write line number dwarf version. (DWARF2) */ + RCHECK(WRITE_VALUE(li->li_version, 2)); + + /* Header length placeholder. */ + offset = ds->ds_size; + RCHECK(WRITE_VALUE(li->li_hdrlen, 4)); + + /* Write minimum instruction length. */ + RCHECK(WRITE_VALUE(li->li_minlen, 1)); + + /* + * Write initial value for is_stmt. XXX Which default value we + * should use? + */ + RCHECK(WRITE_VALUE(li->li_defstmt, 1)); + + /* + * Write line_base and line_range. FIXME These value needs to be + * fine tuned. + */ + RCHECK(WRITE_VALUE(li->li_lbase, 1)); + RCHECK(WRITE_VALUE(li->li_lrange, 1)); + + /* Write opcode_base. (DWARF2) */ + RCHECK(WRITE_VALUE(li->li_opbase, 1)); + + /* Write standard op length array. */ + RCHECK(WRITE_BLOCK(oplen, sizeof(oplen) / sizeof(oplen[0]))); + + /* Write the list of include directories. */ + for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) + RCHECK(WRITE_STRING(li->li_incdirs[i])); + RCHECK(WRITE_VALUE(0, 1)); + + /* Write the list of filenames. */ + STAILQ_FOREACH(lf, &li->li_lflist, lf_next) { + RCHECK(WRITE_STRING(lf->lf_fname)); + RCHECK(WRITE_ULEB128(lf->lf_dirndx)); + RCHECK(WRITE_ULEB128(lf->lf_mtime)); + RCHECK(WRITE_ULEB128(lf->lf_size)); + } + RCHECK(WRITE_VALUE(0, 1)); + + /* Fill in the header length. */ + li->li_hdrlen = ds->ds_size - offset - 4; + dbg->write(ds->ds_data, &offset, li->li_hdrlen, 4); + + /* Generate the line number program. */ + RCHECK(_dwarf_lineno_gen_program(dbg, ds, drs, error)); + + /* Fill in the length of this line info. */ + li->li_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, li->li_length, 4); + + /* Notify the creation of .debug_line ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_line. */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail1: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_lineno_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf, tlf; + Dwarf_Line ln, tln; + int i; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_lineinfo == NULL) + return; + + li = dbg->dbgp_lineinfo; + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, + lf_next); + if (lf->lf_fname) + free(lf->lf_fname); + free(lf); + } + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); + free(ln); + } + if (li->li_incdirs) { + for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) + free(li->li_incdirs[i]); + free(li->li_incdirs); + } + free(li); + dbg->dbgp_lineinfo = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loc.c b/contrib/elftoolchain/libdwarf/libdwarf_loc.c new file mode 100644 index 0000000000..c2d3f5cc66 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_loc.c @@ -0,0 +1,701 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $"); + +/* + * Given an array of bytes of length 'len' representing a + * DWARF expression, compute the number of operations based + * on there being one byte describing the operation and + * zero or more bytes of operands as defined in the standard + * for each operation type. Also, if lbuf is non-null, store + * the opcode and oprand in it. + */ +static int +_dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, + uint8_t offset_size, uint8_t version, uint8_t *p, int len) +{ + int count; + uint64_t operand1; + uint64_t operand2; + uint8_t *ps, *pe, s; + + count = 0; + ps = p; + pe = p + len; + + /* + * Process each byte. If an error occurs, then the + * count will be set to -1. + */ + while (p < pe) { + + operand1 = 0; + operand2 = 0; + + if (lbuf != NULL) { + lbuf->ld_s[count].lr_atom = *p; + lbuf->ld_s[count].lr_offset = p - ps; + } + + switch (*p++) { + /* Operations with no operands. */ + case DW_OP_deref: + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + + case DW_OP_dup: + case DW_OP_drop: + + case DW_OP_over: + + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + + case DW_OP_nop: + case DW_OP_push_object_address: + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + case DW_OP_stack_value: + case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: + break; + + /* Operations with 1-byte operands. */ + case DW_OP_const1u: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + operand1 = *p++; + break; + + case DW_OP_const1s: + operand1 = (int8_t) *p++; + break; + + /* Operations with 2-byte operands. */ + case DW_OP_call2: + case DW_OP_const2u: + case DW_OP_bra: + case DW_OP_skip: + operand1 = dbg->decode(&p, 2); + break; + + case DW_OP_const2s: + operand1 = (int16_t) dbg->decode(&p, 2); + break; + + /* Operations with 4-byte operands. */ + case DW_OP_call4: + case DW_OP_const4u: + case DW_OP_GNU_parameter_ref: + operand1 = dbg->decode(&p, 4); + break; + + case DW_OP_const4s: + operand1 = (int32_t) dbg->decode(&p, 4); + break; + + /* Operations with 8-byte operands. */ + case DW_OP_const8u: + case DW_OP_const8s: + operand1 = dbg->decode(&p, 8); + break; + + /* Operations with an unsigned LEB128 operand. */ + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + case DW_OP_GNU_deref_type: + case DW_OP_GNU_convert: + case DW_OP_GNU_reinterpret: + operand1 = _dwarf_decode_uleb128(&p); + break; + + /* Operations with a signed LEB128 operand. */ + case DW_OP_consts: + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_fbreg: + operand1 = _dwarf_decode_sleb128(&p); + break; + + /* + * Oeration with two unsigned LEB128 operands. + */ + case DW_OP_bit_piece: + case DW_OP_GNU_regval_type: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = _dwarf_decode_uleb128(&p); + break; + + /* + * Operations with an unsigned LEB128 operand + * followed by a signed LEB128 operand. + */ + case DW_OP_bregx: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = _dwarf_decode_sleb128(&p); + break; + + /* + * Operation with an unsigned LEB128 operand + * representing the size of a block, followed + * by the block content. + * + * Store the size of the block in the operand1 + * and a pointer to the block in the operand2. + */ + case DW_OP_implicit_value: + case DW_OP_GNU_entry_value: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = (Dwarf_Unsigned) (uintptr_t) p; + p += operand1; + break; + + /* Target address size operand. */ + case DW_OP_addr: + case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: + operand1 = dbg->decode(&p, pointer_size); + break; + + /* Offset size operand. */ + case DW_OP_call_ref: + operand1 = dbg->decode(&p, offset_size); + break; + + /* + * The first byte is address byte length, followed by + * the address value. If the length is 0, the address + * size is the same as target pointer size. + */ + case DW_OP_GNU_encoded_addr: + s = *p++; + if (s == 0) + s = pointer_size; + operand1 = dbg->decode(&p, s); + break; + + /* + * Operand1: DIE offset (size depending on DWARF version) + * DWARF2: pointer size + * DWARF{3,4}: offset size + * + * Operand2: SLEB128 + */ + case DW_OP_GNU_implicit_pointer: + if (version == 2) + operand1 = dbg->decode(&p, pointer_size); + else + operand1 = dbg->decode(&p, offset_size); + operand2 = _dwarf_decode_sleb128(&p); + break; + + /* + * Operand1: DIE offset (ULEB128) + * Operand2: pointer to a block. The block's first byte + * is its size. + */ + case DW_OP_GNU_const_type: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = (Dwarf_Unsigned) (uintptr_t) p; + s = *p++; + p += s; + break; + + /* All other operations cause an error. */ + default: + count = -1; + goto done; + } + + if (lbuf != NULL) { + lbuf->ld_s[count].lr_number = operand1; + lbuf->ld_s[count].lr_number2 = operand2; + } + + count++; + } + +done: + return (count); +} + +int +_dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, + Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, + int *length, Dwarf_Error *error) +{ + uint8_t buf[64]; + uint8_t *p, *pe; + uint64_t offset; + int len; + + if (out != NULL && end != NULL) { + p = out; + pe = end; + } else { + p = out = buf; + pe = &buf[sizeof(buf)]; + } + + switch (atom) { + /* Operations with no operands. */ + case DW_OP_deref: + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + + case DW_OP_dup: + case DW_OP_drop: + + case DW_OP_over: + + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + + case DW_OP_nop: + case DW_OP_GNU_push_tls_address: + *p++ = atom; + break; + + /* Operations with 1-byte operands. */ + case DW_OP_const1u: + case DW_OP_const1s: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + *p++ = atom; + *p++ = (uint8_t) operand1; + break; + + /* Operations with 2-byte operands. */ + case DW_OP_const2u: + case DW_OP_const2s: + case DW_OP_bra: + case DW_OP_skip: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 2); + p += 2; + break; + + /* Operations with 4-byte operands. */ + case DW_OP_const4u: + case DW_OP_const4s: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 4); + p += 4; + break; + + /* Operations with 8-byte operands. */ + case DW_OP_const8u: + case DW_OP_const8s: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 8); + p += 8; + break; + + /* Operations with an unsigned LEB128 operand. */ + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + *p++ = atom; + len = _dwarf_write_uleb128(p, pe, operand1); + assert(len > 0); + p += len; + break; + + /* Operations with a signed LEB128 operand. */ + case DW_OP_consts: + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_fbreg: + *p++ = atom; + len = _dwarf_write_sleb128(p, pe, operand1); + assert(len > 0); + p += len; + break; + + /* + * Operations with an unsigned LEB128 operand + * followed by a signed LEB128 operand. + */ + case DW_OP_bregx: + *p++ = atom; + len = _dwarf_write_uleb128(p, pe, operand1); + assert(len > 0); + p += len; + len = _dwarf_write_sleb128(p, pe, operand2); + assert(len > 0); + p += len; + break; + + /* Target address size operand. */ + case DW_OP_addr: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); + p += dbg->dbg_pointer_size; + break; + + /* All other operations cause an error. */ + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (DW_DLE_LOC_EXPR_BAD); + } + + if (length) + *length = p - out; + + return (DW_DLE_NONE); +} + +int +_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) +{ + int num; + + assert(llbuf != NULL); + assert(in != NULL); + assert(in_len > 0); + + /* Compute the number of locations. */ + if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, + version, in, in_len)) < 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (DW_DLE_LOC_EXPR_BAD); + } + + llbuf->ld_cents = num; + if (num <= 0) + return (DW_DLE_NONE); + + if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, + version, in, in_len); + + return (DW_DLE_NONE); +} + +int +_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) +{ + Dwarf_Locdesc *llbuf; + int ret; + + if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + llbuf->ld_lopc = 0; + llbuf->ld_hipc = ~0ULL; + llbuf->ld_s = NULL; + + ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, + offset_size, version, error); + if (ret != DW_DLE_NONE) { + free(llbuf); + return (ret); + } + + *ret_llbuf = llbuf; + + return (ret); +} + +int +_dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + int ret; + + assert(at->at_ld == NULL); + assert(at->u[1].u8p != NULL); + assert(at->u[0].u64 > 0); + + cu = die->die_cu; + assert(cu != NULL); + + dbg = cu->cu_dbg; + assert(dbg != NULL); + + ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, + at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8, + cu->cu_version, error); + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loclist.c b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c new file mode 100644 index 0000000000..bb3e39f6c8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c @@ -0,0 +1,165 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_loclist.c 3061 2014-06-02 00:42:41Z kaiwang27 $"); + +static int +_dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, + Dwarf_Unsigned *off, Dwarf_Locdesc **ld, Dwarf_Signed *ldlen, + Dwarf_Unsigned *total_len, Dwarf_Error *error) +{ + uint64_t start, end; + int i, len, ret; + + if (total_len != NULL) + *total_len = 0; + + for (i = 0; *off < ds->ds_size; i++) { + start = dbg->read(ds->ds_data, off, cu->cu_pointer_size); + end = dbg->read(ds->ds_data, off, cu->cu_pointer_size); + if (ld != NULL) { + ld[i]->ld_lopc = start; + ld[i]->ld_hipc = end; + } + + if (total_len != NULL) + *total_len += 2 * cu->cu_pointer_size; + + /* Check if it is the end entry. */ + if (start == 0 && end ==0) { + i++; + break; + } + + /* Check if it is base-select entry. */ + if ((cu->cu_pointer_size == 4 && start == ~0U) || + (cu->cu_pointer_size == 8 && start == ~0ULL)) + continue; + + /* Otherwise it's normal entry. */ + len = dbg->read(ds->ds_data, off, 2); + if (*off + len > ds->ds_size) { + DWARF_SET_ERROR(dbg, error, + DW_DLE_DEBUG_LOC_SECTION_SHORT); + return (DW_DLE_DEBUG_LOC_SECTION_SHORT); + } + + if (total_len != NULL) + *total_len += len; + + if (ld != NULL) { + ret = _dwarf_loc_fill_locdesc(dbg, ld[i], + ds->ds_data + *off, len, cu->cu_pointer_size, + cu->cu_length_size == 4 ? 4 : 8, cu->cu_version, + error); + if (ret != DW_DLE_NONE) + return (ret); + } + + *off += len; + } + + if (ldlen != NULL) + *ldlen = i; + + return (DW_DLE_NONE); +} + +int +_dwarf_loclist_find(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, + Dwarf_Locdesc ***ret_llbuf, Dwarf_Signed *listlen, + Dwarf_Unsigned *entry_len, Dwarf_Error *error) +{ + Dwarf_Locdesc **llbuf; + Dwarf_Section *ds; + Dwarf_Signed ldlen; + Dwarf_Unsigned off; + int i, ret; + + if ((ds = _dwarf_find_section(dbg, ".debug_loc")) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + if (lloff >= ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + /* Get the number of locdesc the first round. */ + off = lloff; + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, NULL, &ldlen, + NULL, error); + if (ret != DW_DLE_NONE) + return (ret); + + if (ldlen == 0) + return (DW_DLE_NO_ENTRY); + + /* + * Dwarf_Locdesc list memory is allocated in this way (one more level + * of indirect) to make the loclist API be compatible with SGI libdwarf. + */ + if ((llbuf = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + for (i = 0; i < ldlen; i++) { + if ((llbuf[i] = calloc(1, sizeof(Dwarf_Locdesc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + } + + off = lloff; + + /* Fill in locdesc. */ + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, llbuf, NULL, + entry_len, error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + *ret_llbuf = llbuf; + *listlen = ldlen; + + return (DW_DLE_NONE); + +fail_cleanup: + + if (llbuf != NULL) { + for (i = 0; i < ldlen; i++) { + if (llbuf[i]->ld_s) + free(llbuf[i]->ld_s); + free(llbuf[i]); + } + free(llbuf); + } + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c b/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c new file mode 100644 index 0000000000..1c9101ce66 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c @@ -0,0 +1,254 @@ +/*- + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_macinfo.c 2974 2013-12-23 06:46:22Z kaiwang27 $"); + +#define _FILEINDEX_STACK_SIZE 16384 + +static int +_dwarf_macinfo_parse(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *off, + Dwarf_Macro_Details *dmd, Dwarf_Unsigned *cnt, Dwarf_Error *error) +{ + Dwarf_Unsigned lineno; + Dwarf_Signed fileindex[_FILEINDEX_STACK_SIZE]; + char *p; + int i, type, sp; + + i = 0; + sp = 0; + fileindex[sp] = -1; + while (*off < ds->ds_size) { + + if (dmd != NULL) + dmd[i].dmd_offset = *off; + + type = dbg->read(ds->ds_data, off, 1); + + if (dmd != NULL) { + dmd[i].dmd_type = type; + dmd[i].dmd_fileindex = fileindex[sp]; + } + + switch (type) { + case 0: + break; + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + lineno = _dwarf_read_uleb128(ds->ds_data, off); + p = (char *) ds->ds_data; + if (dmd != NULL) { + dmd[i].dmd_lineno = lineno; + dmd[i].dmd_macro = p + *off; + + } + while (p[(*off)++] != '\0') + ; + break; + case DW_MACINFO_start_file: + lineno = _dwarf_read_uleb128(ds->ds_data, off); + if (sp >= _FILEINDEX_STACK_SIZE - 1) { + assert(0); + } + fileindex[++sp] = _dwarf_read_uleb128(ds->ds_data, off); + if (dmd != NULL) { + dmd[i].dmd_lineno = lineno; + dmd[i].dmd_fileindex = fileindex[sp]; + } + break; + case DW_MACINFO_end_file: + if (sp > 0) { + sp--; + break; + } + /* FALLTHROUGH */ + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLE_DEBUG_MACRO_INCONSISTENT); + } + + i++; + + if (type == 0) + break; + } + + if (cnt != NULL) + *cnt = i; + + return (DW_DLE_NONE); +} + +void +_dwarf_macinfo_cleanup(Dwarf_Debug dbg) +{ + Dwarf_MacroSet ms, tms; + + if (STAILQ_EMPTY(&dbg->dbg_mslist)) + return; + + STAILQ_FOREACH_SAFE(ms, &dbg->dbg_mslist, ms_next, tms) { + STAILQ_REMOVE(&dbg->dbg_mslist, ms, _Dwarf_MacroSet, ms_next); + if (ms->ms_mdlist) + free(ms->ms_mdlist); + free(ms); + } +} + +int +_dwarf_macinfo_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_MacroSet ms; + Dwarf_Unsigned cnt; + Dwarf_Section *ds; + uint64_t offset, entry_off; + int ret; + + if ((ds = _dwarf_find_section(dbg, ".debug_macinfo")) == NULL) + return (DW_DLE_NONE); + + offset = 0; + while (offset < ds->ds_size) { + + entry_off = offset; + + ret = _dwarf_macinfo_parse(dbg, ds, &offset, NULL, &cnt, error); + if (ret != DW_DLE_NONE) + return (ret); + + if (cnt == 0) + break; + + if ((ms = calloc(1, sizeof(struct _Dwarf_MacroSet))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + STAILQ_INSERT_TAIL(&dbg->dbg_mslist, ms, ms_next); + + if ((ms->ms_mdlist = calloc(cnt, sizeof(Dwarf_Macro_Details))) + == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + ms->ms_cnt = cnt; + + offset = entry_off; + + ret = _dwarf_macinfo_parse(dbg, ds, &offset, ms->ms_mdlist, + NULL, error); + + if (ret != DW_DLE_NONE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + } + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_macinfo_cleanup(dbg); + + return (ret); +} + +int +_dwarf_macinfo_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Macro_Details *md; + int i, ret; + + if (dbg->dbgp_mdcnt == 0) + return (DW_DLE_NONE); + + /* Create .debug_frame section. */ + RCHECK(_dwarf_section_init(dbg, &ds, ".debug_macinfo", 0, error)); + + /* Write the list of Dwarf_Macro_Details. */ + for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { + md = &dbg->dbgp_mdlist[i]; + md->dmd_offset = ds->ds_size; + RCHECK(WRITE_VALUE(md->dmd_type, 1)); + switch (md->dmd_type) { + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + RCHECK(WRITE_ULEB128(md->dmd_lineno)); + assert(md->dmd_macro != NULL); + RCHECK(WRITE_STRING(md->dmd_macro)); + break; + case DW_MACINFO_start_file: + RCHECK(WRITE_ULEB128(md->dmd_lineno)); + RCHECK(WRITE_ULEB128(md->dmd_fileindex)); + break; + case DW_MACINFO_end_file: + break; + default: + assert(0); + break; + } + } + RCHECK(WRITE_VALUE(0, 1)); + + /* Inform application the creation of .debug_macinfo ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_macinfo_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_Macro_Details *md; + int i; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_mdlist == NULL) + return; + + assert(dbg->dbgp_mdcnt > 0); + for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { + md = &dbg->dbgp_mdlist[i]; + if (md->dmd_macro) + free(md->dmd_macro); + } + free(dbg->dbgp_mdlist); + dbg->dbgp_mdlist = NULL; + dbg->dbgp_mdcnt = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c new file mode 100644 index 0000000000..661b56f1c9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c @@ -0,0 +1,253 @@ +/*- + * Copyright (c) 2009,2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_nametbl.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); + +void +_dwarf_nametbl_cleanup(Dwarf_NameSec *nsp) +{ + Dwarf_NameSec ns; + Dwarf_NameTbl nt, tnt; + Dwarf_NamePair np, tnp; + + assert(nsp != NULL); + if ((ns = *nsp) == NULL) + return; + + STAILQ_FOREACH_SAFE(nt, &ns->ns_ntlist, nt_next, tnt) { + STAILQ_FOREACH_SAFE(np, &nt->nt_nplist, np_next, tnp) { + STAILQ_REMOVE(&nt->nt_nplist, np, _Dwarf_NamePair, + np_next); + free(np); + } + STAILQ_REMOVE(&ns->ns_ntlist, nt, _Dwarf_NameTbl, nt_next); + free(nt); + } + if (ns->ns_array) + free(ns->ns_array); + free(ns); + *nsp = NULL; +} + +int +_dwarf_nametbl_init(Dwarf_Debug dbg, Dwarf_NameSec *namesec, Dwarf_Section *ds, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_NameSec ns; + Dwarf_NameTbl nt; + Dwarf_NamePair np; + uint64_t offset, dwarf_size, length, cuoff; + char *p; + int i, ret; + + assert(*namesec == NULL); + + if ((ns = malloc(sizeof(struct _Dwarf_NameSec))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&ns->ns_ntlist); + ns->ns_array = NULL; + ns->ns_len = 0; + + offset = 0; + while (offset < ds->ds_size) { + + /* Allocate a new name table. */ + if ((nt = malloc(sizeof(struct _Dwarf_NameTbl))) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + STAILQ_INIT(&nt->nt_nplist); + STAILQ_INSERT_TAIL(&ns->ns_ntlist, nt, nt_next); + + /* Read in the table header. */ + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + nt->nt_length = length; + /* FIXME: verify version */ + nt->nt_version = dbg->read(ds->ds_data, &offset, 2); + nt->nt_cu_offset = dbg->read(ds->ds_data, &offset, dwarf_size); + nt->nt_cu_length = dbg->read(ds->ds_data, &offset, dwarf_size); + + if (!dbg->dbg_info_loaded) { + ret = _dwarf_info_load(dbg, 1, 1, error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + } + + /* Find the referenced CU. */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == nt->nt_cu_offset) + break; + } + nt->nt_cu = cu; /* FIXME: Check if NULL here */ + + /* Add name pairs. */ + while (offset < ds->ds_size) { + cuoff = dbg->read(ds->ds_data, &offset, dwarf_size); + if (cuoff == 0) + break; + if ((np = malloc(sizeof(struct _Dwarf_NamePair))) == + NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + np->np_nt = nt; + np->np_offset = cuoff; + p = (char *) ds->ds_data; + np->np_name = &p[offset]; + while (p[offset++] != '\0') + ; + STAILQ_INSERT_TAIL(&nt->nt_nplist, np, np_next); + ns->ns_len++; + } + } + + /* Build array of name pairs from all tables. */ + if (ns->ns_len > 0) { + if ((ns->ns_array = malloc(sizeof(Dwarf_NamePair) * + ns->ns_len)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + i = 0; + STAILQ_FOREACH(nt, &ns->ns_ntlist, nt_next) { + STAILQ_FOREACH(np, &nt->nt_nplist, np_next) + ns->ns_array[i++] = np; + } + assert((Dwarf_Unsigned)i == ns->ns_len); + } + + *namesec = ns; + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_nametbl_cleanup(&ns); + + return (ret); +} + +int +_dwarf_nametbl_gen(Dwarf_P_Debug dbg, const char *name, Dwarf_NameTbl nt, + Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_NamePair np; + uint64_t offset; + int ret; + + assert(dbg != NULL && name != NULL); + if (nt == NULL || STAILQ_EMPTY(&nt->nt_nplist)) + return (DW_DLE_NONE); + + nt->nt_length = 0; + nt->nt_version = 2; + nt->nt_cu = STAILQ_FIRST(&dbg->dbg_cu); + assert(nt->nt_cu != NULL); + nt->nt_cu_offset = nt->nt_cu->cu_offset; + nt->nt_cu_length = nt->nt_cu->cu_length; + + /* Create name lookup section. */ + if ((ret = _dwarf_section_init(dbg, &ds, name, 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for the name lookup section. */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Write table header. */ + RCHECK(WRITE_VALUE(nt->nt_length, 4)); + RCHECK(WRITE_VALUE(nt->nt_version, 2)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, nt->nt_cu_offset, ".debug_info", error)); + RCHECK(WRITE_VALUE(nt->nt_cu_length, 4)); + + /* Write tuples. */ + STAILQ_FOREACH(np, &nt->nt_nplist, np_next) { + assert(np->np_die != NULL); + np->np_offset = np->np_die->die_offset; + RCHECK(WRITE_VALUE(np->np_offset, 4)); + RCHECK(WRITE_STRING(np->np_name)); + } + RCHECK(WRITE_VALUE(0, 4)); + + /* Fill in the length field. */ + nt->nt_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, nt->nt_length, 4); + + /* Inform application the creation of name lookup ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for the name lookup section. */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_nametbl_pro_cleanup(Dwarf_NameTbl *ntp) +{ + Dwarf_NameTbl nt; + Dwarf_NamePair np, tnp; + + assert(ntp != NULL); + if ((nt = *ntp) == NULL) + return; + + STAILQ_FOREACH_SAFE(np, &nt->nt_nplist, np_next, tnp) { + STAILQ_REMOVE(&nt->nt_nplist, np, _Dwarf_NamePair, np_next); + if (np->np_name) + free(np->np_name); + free(np); + } + free(nt); + *ntp = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_ranges.c b/contrib/elftoolchain/libdwarf/libdwarf_ranges.c new file mode 100644 index 0000000000..3396bb9a1b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_ranges.c @@ -0,0 +1,152 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_ranges.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); + +static int +_dwarf_ranges_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, + uint64_t off, Dwarf_Ranges *rg, Dwarf_Unsigned *cnt) +{ + Dwarf_Unsigned start, end; + int i; + + i = 0; + while (off < ds->ds_size) { + + start = dbg->read(ds->ds_data, &off, cu->cu_pointer_size); + end = dbg->read(ds->ds_data, &off, cu->cu_pointer_size); + + if (rg != NULL) { + rg[i].dwr_addr1 = start; + rg[i].dwr_addr2 = end; + if (start == 0 && end == 0) + rg[i].dwr_type = DW_RANGES_END; + else if ((start == ~0U && cu->cu_pointer_size == 4) || + (start == ~0ULL && cu->cu_pointer_size == 8)) + rg[i].dwr_type = DW_RANGES_ADDRESS_SELECTION; + else + rg[i].dwr_type = DW_RANGES_ENTRY; + } + + i++; + + if (start == 0 && end == 0) + break; + } + + if (cnt != NULL) + *cnt = i; + + return (DW_DLE_NONE); +} + +int +_dwarf_ranges_find(Dwarf_Debug dbg, uint64_t off, Dwarf_Rangelist *ret_rl) +{ + Dwarf_Rangelist rl; + + STAILQ_FOREACH(rl, &dbg->dbg_rllist, rl_next) + if (rl->rl_offset == off) + break; + + if (rl == NULL) + return (DW_DLE_NO_ENTRY); + + if (ret_rl != NULL) + *ret_rl = rl; + + return (DW_DLE_NONE); +} + +void +_dwarf_ranges_cleanup(Dwarf_Debug dbg) +{ + Dwarf_Rangelist rl, trl; + + if (STAILQ_EMPTY(&dbg->dbg_rllist)) + return; + + STAILQ_FOREACH_SAFE(rl, &dbg->dbg_rllist, rl_next, trl) { + STAILQ_REMOVE(&dbg->dbg_rllist, rl, _Dwarf_Rangelist, rl_next); + if (rl->rl_rgarray) + free(rl->rl_rgarray); + free(rl); + } +} + +int +_dwarf_ranges_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t off, + Dwarf_Rangelist *ret_rl, Dwarf_Error *error) +{ + Dwarf_Section *ds; + Dwarf_Rangelist rl; + Dwarf_Unsigned cnt; + int ret; + + if ((ds = _dwarf_find_section(dbg, ".debug_ranges")) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + if ((rl = malloc(sizeof(struct _Dwarf_Rangelist))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + rl->rl_offset = off; + + ret = _dwarf_ranges_parse(dbg, cu, ds, off, NULL, &cnt); + if (ret != DW_DLE_NONE) { + free(rl); + return (ret); + } + + rl->rl_rglen = cnt; + if (cnt != 0) { + if ((rl->rl_rgarray = calloc(cnt, sizeof(Dwarf_Ranges))) == + NULL) { + free(rl); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + ret = _dwarf_ranges_parse(dbg, cu, ds, off, rl->rl_rgarray, + NULL); + if (ret != DW_DLE_NONE) { + free(rl->rl_rgarray); + free(rl); + return (ret); + } + } else + rl->rl_rgarray = NULL; + + STAILQ_INSERT_TAIL(&dbg->dbg_rllist, rl, rl_next); + *ret_rl = rl; + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_reloc.c b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c new file mode 100644 index 0000000000..e76675838e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c @@ -0,0 +1,499 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_reloc.c 3741 2019-06-07 06:32:01Z jkoshy $"); + +Dwarf_Unsigned +_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64) +{ + + assert(dbg != NULL); + + switch (dbg->dbgp_isa) { + case DW_ISA_AARCH64: + return (is64 ? R_AARCH64_ABS64 : R_AARCH64_ABS32); + case DW_ISA_X86: + return (R_386_32); + case DW_ISA_X86_64: + return (is64 ? R_X86_64_64 : R_X86_64_32); + case DW_ISA_SPARC: + return (is64 ? R_SPARC_UA64 : R_SPARC_UA32); + case DW_ISA_PPC: + return (is64 ? R_PPC64_ADDR64 : R_PPC_ADDR32); + case DW_ISA_ARM: + return (R_ARM_ABS32); + case DW_ISA_MIPS: + return (is64 ? R_MIPS_64 : R_MIPS_32); + case DW_ISA_RISCV: + return (is64 ? R_RISCV_64 : R_RISCV_32); + case DW_ISA_IA64: + return (is64 ? R_IA_64_DIR64LSB : R_IA_64_DIR32LSB); + default: + break; + } + return (0); /* NOT REACHED */ +} + +int +_dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type) +{ + + switch (dbg->dbg_machine) { + case EM_NONE: + break; + case EM_AARCH64: + if (rel_type == R_AARCH64_ABS32) + return (4); + else if (rel_type == R_AARCH64_ABS64) + return (8); + break; + case EM_ARM: + if (rel_type == R_ARM_ABS32) + return (4); + break; + case EM_386: + case EM_IAMCU: + if (rel_type == R_386_32) + return (4); + break; + case EM_X86_64: + if (rel_type == R_X86_64_32) + return (4); + else if (rel_type == R_X86_64_64) + return (8); + break; + case EM_SPARC: + if (rel_type == R_SPARC_UA32) + return (4); + else if (rel_type == R_SPARC_UA64) + return (8); + break; + case EM_PPC: + if (rel_type == R_PPC_ADDR32) + return (4); + break; + case EM_PPC64: + if (rel_type == R_PPC_ADDR32) + return (4); + else if (rel_type == R_PPC64_ADDR64) + return (8); + break; + case EM_MIPS: + if (rel_type == R_MIPS_32) + return (4); + else if (rel_type == R_MIPS_64) + return (8); + break; + case EM_RISCV: + if (rel_type == R_RISCV_32) + return (4); + else if (rel_type == R_RISCV_64) + return (8); + break; + case EM_IA_64: + if (rel_type == R_IA_64_SECREL32LSB) + return (4); + else if (rel_type == R_IA_64_DIR64LSB) + return (8); + break; + default: + break; + } + + /* unknown relocation. */ + return (0); +} + +int +_dwarf_reloc_section_init(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp, + Dwarf_P_Section ref, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + char name[128]; + int pseudo; + + assert(dbg != NULL && drsp != NULL && ref != NULL); + + if ((drs = calloc(1, sizeof(struct _Dwarf_Rel_Section))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + drs->drs_ref = ref; + + /* + * FIXME The logic here is most likely wrong. It should + * be the ISA that determines relocation type. + */ + if (dbg->dbgp_flags & DW_DLC_SIZE_64) + drs->drs_addend = 1; + else + drs->drs_addend = 0; + + if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) + pseudo = 1; + else + pseudo = 0; + + snprintf(name, sizeof(name), "%s%s", + drs->drs_addend ? ".rela" : ".rel", ref->ds_name); + if (_dwarf_section_init(dbg, &drs->drs_ds, name, pseudo, error) != + DW_DLE_NONE) { + free(drs); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + STAILQ_INIT(&drs->drs_dre); + STAILQ_INSERT_TAIL(&dbg->dbgp_drslist, drs, drs_next); + dbg->dbgp_drscnt++; + *drsp = drs; + + return (DW_DLE_NONE); +} + +void +_dwarf_reloc_section_free(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp) +{ + Dwarf_Rel_Section drs, tdrs; + Dwarf_Rel_Entry dre, tdre; + + assert(dbg != NULL && drsp != NULL); + + if (*drsp == NULL) + return; + + STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { + if (drs != *drsp) + continue; + STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, + drs_next); + STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { + STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, + dre_next); + free(dre); + } + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) + _dwarf_section_free(dbg, &drs->drs_ds); + else { + if (drs->drs_ds->ds_name) + free(drs->drs_ds->ds_name); + free(drs->drs_ds); + } + free(drs); + *drsp = NULL; + dbg->dbgp_drscnt--; + break; + } +} + +int +_dwarf_reloc_entry_add(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_P_Section ds, unsigned char type, unsigned char length, + Dwarf_Unsigned offset, Dwarf_Unsigned symndx, Dwarf_Unsigned addend, + const char *secname, Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_Unsigned reloff; + int ret; + + assert(drs != NULL); + assert(offset <= ds->ds_size); + reloff = offset; + + /* + * If the DW_DLC_SYMBOLIC_RELOCATIONS flag is set or ElfXX_Rel + * is used instead of ELfXX_Rela, we need to write the addend + * in the storage unit to be relocated. Otherwise write 0 in the + * storage unit and the addend will be written into relocation + * section later. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) || + drs->drs_addend == 0) + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + addend, length, error); + else + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + 0, length, error); + if (ret != DW_DLE_NONE) + return (ret); + if (offset > ds->ds_size) + ds->ds_size = offset; + + if ((dre = calloc(1, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&drs->drs_dre, dre, dre_next); + dre->dre_type = type; + dre->dre_length = length; + dre->dre_offset = reloff; + dre->dre_symndx = symndx; + dre->dre_addend = addend; + dre->dre_secname = secname; + drs->drs_drecnt++; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_entry_add_pair(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_P_Section ds, unsigned char length, Dwarf_Unsigned offset, + Dwarf_Unsigned symndx, Dwarf_Unsigned esymndx, Dwarf_Unsigned symoff, + Dwarf_Unsigned esymoff, Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_Unsigned reloff; + int ret; + + assert(drs != NULL); + assert(offset <= ds->ds_size); + assert(dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS); + reloff = offset; + + /* Write net offset into section stream. */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + esymoff - symoff, length, error); + if (ret != DW_DLE_NONE) + return (ret); + if (offset > ds->ds_size) + ds->ds_size = offset; + + if ((dre = calloc(2, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[0], dre_next); + STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[1], dre_next); + dre[0].dre_type = dwarf_drt_first_of_length_pair; + dre[0].dre_length = length; + dre[0].dre_offset = reloff; + dre[0].dre_symndx = symndx; + dre[0].dre_addend = 0; + dre[0].dre_secname = NULL; + dre[1].dre_type = dwarf_drt_second_of_length_pair; + dre[1].dre_length = length; + dre[1].dre_offset = reloff; + dre[1].dre_symndx = esymndx; + dre[1].dre_addend = 0; + dre[1].dre_secname = NULL; + drs->drs_drecnt += 2; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_section_finalize(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Unsigned unit; + int ret, size; + + assert(dbg != NULL && drs != NULL && drs->drs_ds != NULL && + drs->drs_ref != NULL); + + ds = drs->drs_ds; + + /* + * Calculate the size (in bytes) of the relocation section. + */ + if (dbg->dbgp_flags & DW_DLC_SIZE_64) + unit = drs->drs_addend ? sizeof(Elf64_Rela) : sizeof(Elf64_Rel); + else + unit = drs->drs_addend ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel); + assert(ds->ds_size == 0); + size = drs->drs_drecnt * unit; + + /* + * Discard this relocation section if there is no entry in it. + */ + if (size == 0) { + _dwarf_reloc_section_free(dbg, &drs); + return (DW_DLE_NONE); + } + + /* + * If we are under stream mode, realloc the section data block to + * this size. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + ds->ds_cap = size; + if ((ds->ds_data = realloc(ds->ds_data, (size_t) ds->ds_cap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + /* + * Notify the application the creation of this relocation section. + * Note that the section link here should point to the .symtab + * section, we set it to 0 since we have no way to know .symtab + * section index. + */ + ret = _dwarf_pro_callback(dbg, ds->ds_name, size, + drs->drs_addend ? SHT_RELA : SHT_REL, 0, 0, drs->drs_ref->ds_ndx, + &ds->ds_symndx, NULL); + if (ret < 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ELF_SECT_ERR); + return (DW_DLE_ELF_SECT_ERR); + } + ds->ds_ndx = ret; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_section_gen(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_P_Section ds; + Dwarf_Unsigned type; + int ret; + + assert((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0); + assert(drs->drs_ds != NULL && drs->drs_ds->ds_size == 0); + assert(!STAILQ_EMPTY(&drs->drs_dre)); + ds = drs->drs_ds; + + STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { + assert(dre->dre_length == 4 || dre->dre_length == 8); + type = _dwarf_get_reloc_type(dbg, dre->dre_length == 8); + if (dbg->dbgp_flags & DW_DLC_SIZE_64) { + /* Write r_offset (8 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, dre->dre_offset, 8, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_info (8 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, ELF64_R_INFO(dre->dre_symndx, type), + 8, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_addend (8 bytes) */ + if (drs->drs_addend) { + ret = dbg->write_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, dre->dre_addend, + 8, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } else { + /* Write r_offset (4 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, dre->dre_offset, 4, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_info (4 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, ELF32_R_INFO(dre->dre_symndx, type), + 4, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_addend (4 bytes) */ + if (drs->drs_addend) { + ret = dbg->write_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, dre->dre_addend, + 4, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } + } + assert(ds->ds_size == ds->ds_cap); + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + Dwarf_Rel_Entry dre; + Dwarf_P_Section ds; + int ret; + + STAILQ_FOREACH(drs, &dbg->dbgp_drslist, drs_next) { + /* + * Update relocation entries: translate any section name + * reference to section symbol index. + */ + STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { + if (dre->dre_secname == NULL) + continue; + ds = _dwarf_pro_find_section(dbg, dre->dre_secname); + assert(ds != NULL && ds->ds_symndx != 0); + dre->dre_symndx = ds->ds_symndx; + } + + /* + * Generate ELF relocation section if we are under stream + * mode. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + ret = _dwarf_reloc_section_gen(dbg, drs, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } + + return (DW_DLE_NONE); +} + +void +_dwarf_reloc_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_Rel_Section drs, tdrs; + Dwarf_Rel_Entry dre, tdre; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { + STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, + drs_next); + free(drs->drs_drd); + STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { + STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, + dre_next); + free(dre); + } + if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + if (drs->drs_ds) { + if (drs->drs_ds->ds_name) + free(drs->drs_ds->ds_name); + free(drs->drs_ds); + } + } + free(drs); + } + dbg->dbgp_drscnt = 0; + dbg->dbgp_drspos = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_rw.c b/contrib/elftoolchain/libdwarf/libdwarf_rw.c new file mode 100644 index 0000000000..95844e0437 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_rw.c @@ -0,0 +1,587 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_rw.c 4007 2023-10-12 18:17:02Z kaiwang27 $"); + +uint64_t +_dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = data + *offsetp; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ + case 4: + ret |= ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ + case 3: + ret |= ((uint64_t) src[2]) << 16; + /* FALLTHROUGH */ + case 2: + ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_decode_lsb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ + case 4: + ret |= ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ + case 3: + ret |= ((uint64_t) src[2]) << 16; + /* FALLTHROUGH */ + case 2: + ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *data += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = data + *offsetp; + + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 3: + ret = src[2] | ((uint64_t) src[1]) << 8; + ret |= ((uint64_t) src[0]) << 16; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_decode_msb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 3: + ret = src[2] | ((uint64_t) src[1]) << 8; + ret |= ((uint64_t) src[0]) << 16; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + } + + *data += bytes_to_read; + + return (ret); +} + +void +_dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value, + int bytes_to_write) +{ + uint8_t *dst; + + dst = data + *offsetp; + + switch (bytes_to_write) { + case 8: + dst[7] = (value >> 56) & 0xff; + dst[6] = (value >> 48) & 0xff; + dst[5] = (value >> 40) & 0xff; + dst[4] = (value >> 32) & 0xff; + /* FALLTHROUGH */ + case 4: + dst[3] = (value >> 24) & 0xff; + dst[2] = (value >> 16) & 0xff; + /* FALLTHROUGH */ + case 2: + dst[1] = (value >> 8) & 0xff; + /* FALLTHROUGH */ + case 1: + dst[0] = value & 0xff; + break; + default: + return; + } + + *offsetp += bytes_to_write; +} + +int +_dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t value, int bytes_to_write, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + bytes_to_write > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_lsb(*block, offsetp, value, bytes_to_write); + + return (DW_DLE_NONE); +} + +void +_dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value, + int bytes_to_write) +{ + uint8_t *dst; + + dst = data + *offsetp; + + switch (bytes_to_write) { + case 8: + dst[7] = value & 0xff; + dst[6] = (value >> 8) & 0xff; + dst[5] = (value >> 16) & 0xff; + dst[4] = (value >> 24) & 0xff; + value >>= 32; + /* FALLTHROUGH */ + case 4: + dst[3] = value & 0xff; + dst[2] = (value >> 8) & 0xff; + value >>= 16; + /* FALLTHROUGH */ + case 2: + dst[1] = value & 0xff; + value >>= 8; + /* FALLTHROUGH */ + case 1: + dst[0] = value & 0xff; + break; + default: + return; + } + + *offsetp += bytes_to_write; +} + +int +_dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t value, int bytes_to_write, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + bytes_to_write > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_msb(*block, offsetp, value, bytes_to_write); + + return (DW_DLE_NONE); +} + +int64_t +_dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp) +{ + int64_t ret = 0; + uint8_t b; + int shift = 0; + uint8_t *src; + + src = data + *offsetp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + (*offsetp)++; + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 64 && (b & 0x40) != 0) + ret |= (~0UL << shift); + + return (ret); +} + +int +_dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val) +{ + uint8_t *p; + + p = data; + + for (;;) { + if (p >= end) + return (-1); + *p = val & 0x7f; + val >>= 7; + if ((val == 0 && (*p & 0x40) == 0) || + (val == -1 && (*p & 0x40) != 0)) { + p++; + break; + } + *p++ |= 0x80; + } + + return (p - data); +} + +int +_dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + int64_t val, Dwarf_Error *error) +{ + int len; + + assert(*size > 0); + + while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size, + val)) < 0) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + *offsetp += len; + + return (DW_DLE_NONE); +} + +uint64_t +_dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + uint8_t *src; + + src = data + *offsetp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + (*offsetp)++; + shift += 7; + } while ((b & 0x80) != 0); + + return (ret); +} + +int +_dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val) +{ + uint8_t *p; + + p = data; + + do { + if (p >= end) + return (-1); + *p = val & 0x7f; + val >>= 7; + if (val > 0) + *p |= 0x80; + p++; + } while (val > 0); + + return (p - data); +} + +int +_dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t val, Dwarf_Error *error) +{ + int len; + + assert(*size > 0); + + while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size, + val)) < 0) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + *offsetp += len; + + return (DW_DLE_NONE); +} + +int64_t +_dwarf_decode_sleb128(uint8_t **dp) +{ + int64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 64 && (b & 0x40) != 0) + ret |= (~0UL << shift); + + *dp = src; + + return (ret); +} + +uint64_t +_dwarf_decode_uleb128(uint8_t **dp) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + *dp = src; + + return (ret); +} + +char * +_dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp) +{ + char *ret, *src; + + ret = src = (char *) data + *offsetp; + + while (*src != '\0' && *offsetp < size) { + src++; + (*offsetp)++; + } + + if (*src == '\0' && *offsetp < size) + (*offsetp)++; + + return (ret); +} + +void +_dwarf_write_string(void *data, uint64_t *offsetp, char *string) +{ + char *dst; + + dst = (char *) data + *offsetp; + strcpy(dst, string); + (*offsetp) += strlen(string) + 1; +} + +int +_dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + char *string, Dwarf_Error *error) +{ + size_t len; + + assert(*size > 0); + + len = strlen(string) + 1; + while (*offsetp + len > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_string(*block, offsetp, string); + + return (DW_DLE_NONE); +} + +uint8_t * +_dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length) +{ + uint8_t *ret, *src; + + ret = src = (uint8_t *) data + *offsetp; + + (*offsetp) += length; + + return (ret); +} + +void +_dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk, + uint64_t length) +{ + uint8_t *dst; + + dst = (uint8_t *) data + *offsetp; + memcpy(dst, blk, length); + (*offsetp) += length; +} + +int +_dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint8_t *blk, uint64_t length, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + length > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_block(*block, offsetp, blk, length); + + return (DW_DLE_NONE); +} + +void +_dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte, + uint64_t length) +{ + uint8_t *dst; + + dst = (uint8_t *) data + *offsetp; + memset(dst, byte, length); + (*offsetp) += length; +} + +int +_dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint8_t byte, uint64_t cnt, Dwarf_Error *error) +{ + assert(*size > 0); + + while (*offsetp + cnt > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_padding(*block, offsetp, byte, cnt); + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_sections.c b/contrib/elftoolchain/libdwarf/libdwarf_sections.c new file mode 100644 index 0000000000..24d5db839e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_sections.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_sections.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); + +#define _SECTION_INIT_SIZE 128 + +int +_dwarf_section_init(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp, const char *name, + int pseudo, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + + assert(dbg != NULL && dsp != NULL && name != NULL); + + if ((ds = calloc(1, sizeof(struct _Dwarf_P_Section))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((ds->ds_name = strdup(name)) == NULL) { + free(ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if (!pseudo) { + ds->ds_cap = _SECTION_INIT_SIZE; + if ((ds->ds_data = malloc((size_t) ds->ds_cap)) == NULL) { + free(ds->ds_name); + free(ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&dbg->dbgp_seclist, ds, ds_next); + dbg->dbgp_seccnt++; + } + + *dsp = ds; + + return (DW_DLE_NONE); +} + +void +_dwarf_section_free(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp) +{ + Dwarf_P_Section ds, tds; + + assert(dbg != NULL && dsp != NULL); + + if (*dsp == NULL) + return; + + STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { + if (ds == *dsp) { + STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, + ds_next); + dbg->dbgp_seccnt--; + break; + } + } + ds = *dsp; + if (ds->ds_name) + free(ds->ds_name); + if (ds->ds_data) + free(ds->ds_data); + free(ds); + *dsp = NULL; +} + +int +_dwarf_pro_callback(Dwarf_P_Debug dbg, char *name, int size, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Unsigned *symndx, int *error) +{ + int e, ret, isymndx; + + assert(dbg != NULL && name != NULL && symndx != NULL); + + if (dbg->dbgp_func_b) + ret = dbg->dbgp_func_b(name, size, type, flags, link, info, + symndx, &e); + else { + ret = dbg->dbgp_func(name, size, type, flags, link, info, + &isymndx, &e); + *symndx = isymndx; + } + if (ret < 0) { + if (error) + *error = e; + } + + return (ret); +} + +int +_dwarf_section_callback(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Error *error) +{ + int ret, ndx; + + ndx = _dwarf_pro_callback(dbg, ds->ds_name, (int) ds->ds_size, + type, flags, link, info, &ds->ds_symndx, NULL); + if (ndx < 0) { + ret = DW_DLE_ELF_SECT_ERR; + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + ds->ds_ndx = ndx; + + return (DW_DLE_NONE); +} + +int +_dwarf_generate_sections(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + int ret; + + /* Produce .debug_info section. */ + if ((ret = _dwarf_info_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_abbrev section. */ + if ((ret = _dwarf_abbrev_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_line section. */ + if ((ret = _dwarf_lineno_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_frame section. */ + if ((ret = _dwarf_frame_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_aranges section. */ + if ((ret = _dwarf_arange_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_macinfo section. */ + if ((ret = _dwarf_macinfo_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_pubnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_pubnames", dbg->dbgp_pubs, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_weaknames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_weaknames", dbg->dbgp_weaks, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_funcnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_funcnames", dbg->dbgp_funcs, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_typenames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_typenames", dbg->dbgp_types, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_varnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_varnames", dbg->dbgp_vars, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_str section. */ + if ((ret = _dwarf_strtab_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Finally, update and generate all relocation sections. */ + if ((ret = _dwarf_reloc_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Set section/relocation iterator to the first element. */ + dbg->dbgp_secpos = STAILQ_FIRST(&dbg->dbgp_seclist); + dbg->dbgp_drspos = STAILQ_FIRST(&dbg->dbgp_drslist); + + return (DW_DLE_NONE); +} + +Dwarf_Section * +_dwarf_find_section(Dwarf_Debug dbg, const char *name) +{ + Dwarf_Section *ds; + Dwarf_Half i; + + assert(dbg != NULL && name != NULL); + + for (i = 0; i < dbg->dbg_seccnt; i++) { + ds = &dbg->dbg_section[i]; + if (ds->ds_name != NULL && !strcmp(ds->ds_name, name)) + return (ds); + } + + return (NULL); +} + +Dwarf_Section * +_dwarf_find_next_types_section(Dwarf_Debug dbg, Dwarf_Section *ds) +{ + + assert(dbg != NULL); + + if (ds == NULL) + return (_dwarf_find_section(dbg, ".debug_types")); + + assert(ds->ds_name != NULL); + + do { + ds++; + if (ds->ds_name != NULL && + !strcmp(ds->ds_name, ".debug_types")) + return (ds); + } while (ds->ds_name != NULL); + + return (NULL); +} + +Dwarf_P_Section +_dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name) +{ + Dwarf_P_Section ds; + + assert(dbg != NULL && name != NULL); + + STAILQ_FOREACH(ds, &dbg->dbgp_seclist, ds_next) { + if (ds->ds_name != NULL && !strcmp(ds->ds_name ,name)) + return (ds); + } + + return (NULL); +} + +void +_dwarf_section_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Section ds, tds; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { + STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, + ds_next); + if (ds->ds_name) + free(ds->ds_name); + if (ds->ds_data) + free(ds->ds_data); + free(ds); + } + dbg->dbgp_seccnt = 0; + dbg->dbgp_secpos = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_str.c b/contrib/elftoolchain/libdwarf/libdwarf_str.c new file mode 100644 index 0000000000..3d769649fa --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_str.c @@ -0,0 +1,301 @@ +/*- + * Copyright (c) 2009,2010,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_str.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +#define _INIT_DWARF_STRTAB_SIZE 1024 + +int +_dwarf_strtab_add(Dwarf_Debug dbg, char *string, uint64_t *off, + Dwarf_Error *error) +{ + size_t len; + + assert(dbg != NULL && string != NULL); + + len = strlen(string) + 1; + while (dbg->dbg_strtab_size + len > dbg->dbg_strtab_cap) { + dbg->dbg_strtab_cap *= 2; + dbg->dbg_strtab = realloc(dbg->dbg_strtab, + (size_t) dbg->dbg_strtab_cap); + if (dbg->dbg_strtab == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + if (off != NULL) + *off = dbg->dbg_strtab_size; + + memcpy(&dbg->dbg_strtab[dbg->dbg_strtab_size], string, len - 1); + dbg->dbg_strtab_size += len; + dbg->dbg_strtab[dbg->dbg_strtab_size - 1] = '\0'; + + return (DW_DLE_NONE); +} + +char * +_dwarf_strtab_get_table(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + return (dbg->dbg_strtab); +} + +char * +_dwarf_strtab_get_line_table(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + return (dbg->dbg_line_strtab); +} + +static int +_dwarf_str_offsets_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + Dwarf_StrOffsets *str_off; + Dwarf_Half version; + uint64_t offset, length; + int dwarf_size; + + assert(dbg != NULL); + + dbg->dbg_str_offsets = NULL; + + if ((ds = _dwarf_find_section(dbg, ".debug_str_offsets")) == NULL) + return (DW_DLE_NONE); + + offset = 0; + + /* Read in the table header. */ + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + version = dbg->read(ds->ds_data, &offset, 2); + if (version != 5) { + DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return (DW_DLE_VERSION_STAMP_ERROR); + } + + if ((str_off = calloc(1, sizeof(*str_off))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* 2 byte padding. */ + offset += 2; + + str_off->so_length = length; + str_off->so_version = version; + str_off->so_header_size = offset; + str_off->so_dwarf_size = dwarf_size; + str_off->so_data = ds->ds_data; + + dbg->dbg_str_offsets = str_off; + + return (DW_DLE_NONE); +} + +static int +_dwarf_find_cu_str_offsets_base(Dwarf_Debug dbg, Dwarf_CU cu, + uint64_t *offset_basep, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Die cu_die; + int ret; + + assert(dbg->dbg_str_offsets != NULL); + + if (!cu->cu_stroff_base_valid) { + if ((ret = dwarf_siblingof(dbg, 0, &cu_die, error)) != + DW_DLV_OK) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + if ((at = _dwarf_attr_find(cu_die, DW_AT_str_offsets_base)) != + NULL) { + cu->cu_stroff_base = at->u[0].u64; + } else { + /* + * No DW_AT_str_offsets_base found. Use header size + * instead. + */ + cu->cu_stroff_base = + dbg->dbg_str_offsets->so_header_size; + } + cu->cu_stroff_base_valid = 1; + dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); + } + *offset_basep = cu->cu_stroff_base; + + return (DW_DLE_NONE); +} + +int +_dwarf_read_indexed_str(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t index, + char **str_p, Dwarf_Error *error) +{ + Dwarf_StrOffsets *so; + uint64_t offset, offsets_base, strtab_offset; + int ret; + + if (dbg->dbg_str_offsets == NULL) { + if ((ret = _dwarf_str_offsets_init(dbg, error)) != DW_DLE_NONE) + return (ret); + if (dbg->dbg_str_offsets == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + } + + if ((ret = _dwarf_find_cu_str_offsets_base(dbg, cu, &offsets_base, + error)) != DW_DLE_NONE) + return (ret); + + so = dbg->dbg_str_offsets; + /* Caculate where to read from string offsets array. */ + offset = offsets_base + so->so_dwarf_size * index; + /* Read from the str offsets array to get offset into string table. */ + strtab_offset = dbg->read(so->so_data, &offset, so->so_dwarf_size); + *str_p = _dwarf_strtab_get_table(dbg) + strtab_offset; + + return (DW_DLE_NONE); +} + +int +_dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { + ds = _dwarf_find_section(dbg, ".debug_str"); + if (ds == NULL) { + dbg->dbg_strtab = NULL; + dbg->dbg_strtab_cap = dbg->dbg_strtab_size = 0; + return (DW_DLE_NONE); + } + + dbg->dbg_strtab_cap = dbg->dbg_strtab_size = ds->ds_size; + + if (dbg->dbg_mode == DW_DLC_RDWR) { + if ((dbg->dbg_strtab = malloc((size_t) ds->ds_size)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(dbg->dbg_strtab, ds->ds_data, ds->ds_size); + } else + dbg->dbg_strtab = (char *) ds->ds_data; + + ds = _dwarf_find_section(dbg, ".debug_line_str"); + if (ds != NULL) { + dbg->dbg_line_strtab = (char *) ds->ds_data; + } + } else { + /* DW_DLC_WRITE */ + + dbg->dbg_strtab_cap = _INIT_DWARF_STRTAB_SIZE; + dbg->dbg_strtab_size = 0; + + if ((dbg->dbg_strtab = malloc((size_t) dbg->dbg_strtab_cap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_strtab[0] = '\0'; + } + + return (DW_DLE_NONE); +} + +void +_dwarf_str_offsets_cleanup(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + if (dbg->dbg_str_offsets) + free(dbg->dbg_str_offsets); +} + +void +_dwarf_strtab_cleanup(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_RDWR || dbg->dbg_mode == DW_DLC_WRITE) + free(dbg->dbg_strtab); +} + +int +_dwarf_strtab_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + int ret; + + assert(dbg != NULL); + + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_str", 0, error)) != + DW_DLE_NONE) + return (ret); + + if (dbg->dbg_strtab_size > ds->ds_cap) { + ds->ds_data = realloc(ds->ds_data, + (size_t) dbg->dbg_strtab_size); + if (ds->ds_data == NULL) { + _dwarf_section_free(dbg, &ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + ds->ds_cap = dbg->dbg_strtab_size; + } + + memcpy(ds->ds_data, dbg->dbg_strtab, dbg->dbg_strtab_size); + ds->ds_size = dbg->dbg_strtab_size; + + /* + * Inform application the creation of .debug_str ELF section. + * Note that .debug_str use a different format than usual ELF + * string table, so it should not have SHT_STRTAB as its type. + */ + ret = _dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error); + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/os.NetBSD.mk b/contrib/elftoolchain/libdwarf/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/libelf/CMakeLists.txt b/contrib/elftoolchain/libelf/CMakeLists.txt new file mode 100644 index 0000000000..7734a6b957 --- /dev/null +++ b/contrib/elftoolchain/libelf/CMakeLists.txt @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (C) 2024 The Falco Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License +# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +# or implied. See the License for the specific language governing permissions and limitations under +# the License. +# + +add_library(elf + elf.c + elf_begin.c + elf_cntl.c + elf_end.c + elf_errmsg.c + elf_errno.c + elf_data.c + elf_fill.c + elf_flag.c + elf_getarhdr.c + elf_getarsym.c + elf_getbase.c + elf_getident.c + elf_getversion.c + elf_hash.c + elf_kind.c + elf_memory.c + elf_next.c + elf_open.c + elf_rand.c + elf_rawfile.c + elf_phnum.c + elf_shnum.c + elf_shstrndx.c + elf_scn.c + elf_strptr.c + elf_update.c + elf_version.c + gelf_cap.c + gelf_checksum.c + gelf_dyn.c + gelf_ehdr.c + gelf_getclass.c + gelf_fsize.c + gelf_move.c + gelf_phdr.c + gelf_rel.c + gelf_rela.c + gelf_shdr.c + gelf_sym.c + gelf_syminfo.c + gelf_symshndx.c + gelf_xlate.c + libelf_align.c + libelf_allocate.c + libelf_ar.c + libelf_ar_util.c + libelf_checksum.c + libelf_data.c + libelf_ehdr.c + libelf_elfmachine.c + libelf_extended.c + libelf_memory.c + libelf_open.c + libelf_phdr.c + libelf_shdr.c + libelf_xlate.c + + # the ones below are gensrcs, so they need to be generated beforehand + + libelf_fsize.c + libelf_msize.c + libelf_convert.c + + # custom files for compatibility + + gelf_getnote.c + gelf_versym.c +) + +target_compile_options(elf PRIVATE -Wno-unused-but-set-variable) +target_include_directories(elf PUBLIC ../common .) diff --git a/contrib/elftoolchain/libelf/Makefile b/contrib/elftoolchain/libelf/Makefile new file mode 100644 index 0000000000..abd5db249f --- /dev/null +++ b/contrib/elftoolchain/libelf/Makefile @@ -0,0 +1,168 @@ +# $Id: Makefile 3925 2021-03-07 12:16:49Z jkoshy $ + +TOP= .. + +LIB= elf + +SRCS= elf.c \ + elf_begin.c \ + elf_cntl.c \ + elf_end.c elf_errmsg.c elf_errno.c \ + elf_data.c \ + elf_fill.c \ + elf_flag.c \ + elf_getarhdr.c \ + elf_getarsym.c \ + elf_getbase.c \ + elf_getident.c \ + elf_getversion.c \ + elf_hash.c \ + elf_kind.c \ + elf_memory.c \ + elf_next.c \ + elf_open.c \ + elf_rand.c \ + elf_rawfile.c \ + elf_phnum.c \ + elf_shnum.c \ + elf_shstrndx.c \ + elf_scn.c \ + elf_strptr.c \ + elf_update.c \ + elf_version.c \ + gelf_cap.c \ + gelf_checksum.c \ + gelf_dyn.c \ + gelf_ehdr.c \ + gelf_getclass.c \ + gelf_fsize.c \ + gelf_move.c \ + gelf_phdr.c \ + gelf_rel.c \ + gelf_rela.c \ + gelf_shdr.c \ + gelf_sym.c \ + gelf_syminfo.c \ + gelf_symshndx.c \ + gelf_xlate.c \ + libelf_align.c \ + libelf_allocate.c \ + libelf_ar.c \ + libelf_ar_util.c \ + libelf_checksum.c \ + libelf_data.c \ + libelf_ehdr.c \ + libelf_elfmachine.c \ + libelf_extended.c \ + libelf_memory.c \ + libelf_open.c \ + libelf_phdr.c \ + libelf_shdr.c \ + libelf_xlate.c \ + ${GENSRCS} + +INCS= libelf.h gelf.h +INCSDIR= /usr/include + +GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c +CLEANFILES= ${GENSRCS} + +SHLIB_MAJOR= 1 + +WARNS?= 6 + +MAN= elf.3 \ + elf_begin.3 \ + elf_cntl.3 \ + elf_end.3 \ + elf_errmsg.3 \ + elf_fill.3 \ + elf_flagdata.3 \ + elf_getarhdr.3 \ + elf_getarsym.3 \ + elf_getbase.3 \ + elf_getdata.3 \ + elf_getident.3 \ + elf_getscn.3 \ + elf_getphdrnum.3 \ + elf_getphnum.3 \ + elf_getshdrnum.3 \ + elf_getshnum.3 \ + elf_getshdrstrndx.3 \ + elf_getshstrndx.3 \ + elf_getversion.3 \ + elf_hash.3 \ + elf_kind.3 \ + elf_memory.3 \ + elf_next.3 \ + elf_open.3 \ + elf_rawfile.3 \ + elf_rand.3 \ + elf_strptr.3 \ + elf_update.3 \ + elf_version.3 \ + gelf.3 \ + gelf_checksum.3 \ + gelf_fsize.3 \ + gelf_getcap.3 \ + gelf_getclass.3 \ + gelf_getdyn.3 \ + gelf_getehdr.3 \ + gelf_getmove.3 \ + gelf_getphdr.3 \ + gelf_getrel.3 \ + gelf_getrela.3 \ + gelf_getshdr.3 \ + gelf_getsym.3 \ + gelf_getsyminfo.3 \ + gelf_getsymshndx.3 \ + gelf_newehdr.3 \ + gelf_newphdr.3 \ + gelf_update_ehdr.3 \ + gelf_xlatetof.3 + +MLINKS+= \ + elf_errmsg.3 elf_errno.3 \ + elf_flagdata.3 elf_flagarhdr.3 \ + elf_flagdata.3 elf_flagehdr.3 \ + elf_flagdata.3 elf_flagelf.3 \ + elf_flagdata.3 elf_flagphdr.3 \ + elf_flagdata.3 elf_flagscn.3 \ + elf_flagdata.3 elf_flagshdr.3 \ + elf_getdata.3 elf_newdata.3 \ + elf_getdata.3 elf_rawdata.3 \ + elf_getscn.3 elf_ndxscn.3 \ + elf_getscn.3 elf_newscn.3 \ + elf_getscn.3 elf_nextscn.3 \ + elf_getshstrndx.3 elf_setshstrndx.3 \ + elf_open.3 elf_openmemory.3 \ + gelf_getcap.3 gelf_update_cap.3 \ + gelf_getdyn.3 gelf_update_dyn.3 \ + gelf_getmove.3 gelf_update_move.3 \ + gelf_getrel.3 gelf_update_rel.3 \ + gelf_getrela.3 gelf_update_rela.3 \ + gelf_getsym.3 gelf_update_sym.3 \ + gelf_getsyminfo.3 gelf_update_syminfo.3 \ + gelf_getsymshndx.3 gelf_update_symshndx.3 \ + gelf_update_ehdr.3 gelf_update_phdr.3 \ + gelf_update_ehdr.3 gelf_update_shdr.3 \ + gelf_xlatetof.3 gelf_xlatetom.3 + +.for E in 32 64 +MLINKS+= \ + gelf_checksum.3 elf${E}_checksum.3 \ + gelf_fsize.3 elf${E}_fsize.3 \ + gelf_getehdr.3 elf${E}_getehdr.3 \ + gelf_getphdr.3 elf${E}_getphdr.3 \ + gelf_getshdr.3 elf${E}_getshdr.3 \ + gelf_newehdr.3 elf${E}_newehdr.3 \ + gelf_newphdr.3 elf${E}_newphdr.3 \ + gelf_xlatetof.3 elf${E}_xlatetof.3 \ + gelf_xlatetof.3 elf${E}_xlatetom.3 +.endfor + +libelf_convert.c: elf_types.m4 libelf_convert.m4 +libelf_fsize.c: elf_types.m4 libelf_fsize.m4 +libelf_msize.c: elf_types.m4 libelf_msize.m4 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libelf/Version.map b/contrib/elftoolchain/libelf/Version.map new file mode 100644 index 0000000000..e71a59197d --- /dev/null +++ b/contrib/elftoolchain/libelf/Version.map @@ -0,0 +1,96 @@ +/* $Id: Version.map 2574 2012-09-11 15:11:59Z jkoshy $ */ + +R1.0 { +global: + elf32_checksum; + elf32_fsize; + elf32_getehdr; + elf32_getphdr; + elf32_getshdr; + elf32_newehdr; + elf32_newphdr; + elf32_xlatetof; + elf32_xlatetom; + elf64_checksum; + elf64_fsize; + elf64_getehdr; + elf64_getphdr; + elf64_getshdr; + elf64_newehdr; + elf64_newphdr; + elf64_xlatetof; + elf64_xlatetom; + elf_begin; + elf_cntl; + elf_end; + elf_errmsg; + elf_errno; + elf_fill; + elf_flagarhdr; + elf_flagdata; + elf_flagehdr; + elf_flagelf; + elf_flagphdr; + elf_flagscn; + elf_flagshdr; + elf_getarhdr; + elf_getarsym; + elf_getbase; + elf_getdata; + elf_getident; + elf_getphdrnum; + elf_getphnum; + elf_getscn; + elf_getshdrnum; + elf_getshdrstrndx; + elf_getshnum; + elf_getshstrndx; + elf_hash; + elf_kind; + elf_memory; + elf_ndxscn; + elf_newdata; + elf_newscn; + elf_next; + elf_nextscn; + elf_open; + elf_openmemory; + elf_rand; + elf_rawdata; + elf_rawfile; + elf_setshstrndx; + elf_strptr; + elf_update; + elf_version; + gelf_checksum; + gelf_fsize; + gelf_getcap; + gelf_getclass; + gelf_getdyn; + gelf_getehdr; + gelf_getmove; + gelf_getphdr; + gelf_getrel; + gelf_getrela; + gelf_getshdr; + gelf_getsym; + gelf_getsyminfo; + gelf_getsymshndx; + gelf_newehdr; + gelf_newphdr; + gelf_update_cap; + gelf_update_dyn; + gelf_update_ehdr; + gelf_update_move; + gelf_update_phdr; + gelf_update_rel; + gelf_update_rela; + gelf_update_shdr; + gelf_update_sym; + gelf_update_syminfo; + gelf_update_symshndx; + gelf_xlatetof; + gelf_xlatetom; +local: + *; +}; diff --git a/contrib/elftoolchain/libelf/_libelf.h b/contrib/elftoolchain/libelf/_libelf.h new file mode 100644 index 0000000000..d13dcd095c --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf.h @@ -0,0 +1,242 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libelf.h 3902 2020-11-24 21:17:41Z jkoshy $ + */ + +#ifndef __LIBELF_H_ +#define __LIBELF_H_ + +#include + +#include "_libelf_config.h" + +#include "_elftc.h" + +/* + * Library-private data structures. + */ + +#define LIBELF_MSG_SIZE 256 + +struct _libelf_globals { + int libelf_arch; + unsigned int libelf_byteorder; + int libelf_class; + int libelf_error; + int libelf_fillchar; + unsigned int libelf_version; + unsigned char libelf_msg[LIBELF_MSG_SIZE]; +}; + +extern struct _libelf_globals _libelf; + +#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) + +#define LIBELF_ELF_ERROR_MASK 0xFF +#define LIBELF_OS_ERROR_SHIFT 8 + +#define LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ + ((O) << LIBELF_OS_ERROR_SHIFT)) + +#define LIBELF_SET_ERROR(E, O) do { \ + LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ + } while (/* CONSTCOND */ 0) + +#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) + +/* + * Flags for library internal use. These use the upper 16 bits of the + * `e_flags' field. + */ +#define LIBELF_F_API_MASK 0x00FFFFU /* Flags defined by the API. */ +#define LIBELF_F_AR_HEADER 0x010000U /* translated header available */ +#define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */ +#define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ +#define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ +#define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ +#define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ +#define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ + +struct _Elf { + int e_activations; /* activation count */ + unsigned int e_byteorder; /* ELFDATA* */ + int e_class; /* ELFCLASS* */ + Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ + int e_fd; /* associated file descriptor */ + unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ + Elf_Kind e_kind; /* ELF_K_* */ + Elf *e_parent; /* non-NULL for archive members */ + unsigned char *e_rawfile; /* uninterpreted bytes */ + off_t e_rawsize; /* size of uninterpreted bytes */ + unsigned int e_version; /* file version */ + + /* + * Header information for archive members. See the + * LIBELF_F_AR_HEADER flag. + */ + union { + Elf_Arhdr *e_arhdr; /* translated header */ + unsigned char *e_rawhdr; /* untranslated header */ + } e_hdr; + + union { + struct { /* ar(1) archives */ + off_t e_next; /* set by elf_rand()/elf_next() */ + int e_nchildren; + unsigned char *e_rawstrtab; /* file name strings */ + size_t e_rawstrtabsz; + unsigned char *e_rawsymtab; /* symbol table */ + size_t e_rawsymtabsz; + Elf_Arsym *e_symtab; + size_t e_symtabsz; + } e_ar; + struct { /* regular ELF files */ + union { + Elf32_Ehdr *e_ehdr32; + Elf64_Ehdr *e_ehdr64; + } e_ehdr; + union { + Elf32_Phdr *e_phdr32; + Elf64_Phdr *e_phdr64; + } e_phdr; + STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ + size_t e_nphdr; /* number of Phdr entries */ + size_t e_nscn; /* number of sections */ + size_t e_strndx; /* string table section index */ + } e_elf; + } e_u; +}; + +/* + * The internal descriptor wrapping the "Elf_Data" type. + */ +struct _Libelf_Data { + Elf_Data d_data; /* The exported descriptor. */ + Elf_Scn *d_scn; /* The containing section */ + unsigned int d_flags; + STAILQ_ENTRY(_Libelf_Data) d_next; +}; + +struct _Elf_Scn { + union { + Elf32_Shdr s_shdr32; + Elf64_Shdr s_shdr64; + } s_shdr; + STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ + STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ + STAILQ_ENTRY(_Elf_Scn) s_next; + struct _Elf *s_elf; /* parent ELF descriptor */ + unsigned int s_flags; /* flags for the section as a whole */ + size_t s_ndx; /* index# for this section */ + uint64_t s_offset; /* managed by elf_update() */ + uint64_t s_rawoff; /* original offset in the file */ + uint64_t s_size; /* managed by elf_update() */ +}; + + +enum { + ELF_TOFILE, + ELF_TOMEMORY +}; + + +/* + * The LIBELF_COPY macros are used to copy fields from a GElf_* + * structure to their 32-bit counterparts, while checking for out of + * range values. + * + * - LIBELF_COPY_U32 :: copy an unsigned 32 bit field. + * - LIBELF_COPY_S32 :: copy a signed 32 bit field. + */ + +#define LIBELF_COPY_U32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > UINT32_MAX) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \ + } while (/* CONSTCOND */ 0) + +#define LIBELF_COPY_S32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > INT32_MAX || \ + (SRC)->NAME < INT32_MIN) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (int32_t) (SRC)->NAME; \ + } while (/* CONSTCOND */ 0) + + +/* + * Function Prototypes. + */ + +typedef int _libelf_translator_function(unsigned char *_dst, size_t dsz, + unsigned char *_src, size_t _cnt, int _byteswap); + +#ifdef __cplusplus +extern "C" { +#endif +struct _Libelf_Data *_libelf_allocate_data(Elf_Scn *_s); +Elf *_libelf_allocate_elf(void); +Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); +Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); +Elf *_libelf_ar_open(Elf *_e, int _reporterror); +Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); +Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); +Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); +long _libelf_checksum(Elf *_e, int _elfclass); +void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); +int _libelf_elfmachine(Elf *_e); +unsigned int _libelf_falign(Elf_Type _t, int _elfclass); +size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, + size_t count); +_libelf_translator_function *_libelf_get_translator(Elf_Type _t, + int _direction, int _elfclass, int _elfmachine); +void *_libelf_getphdr(Elf *_e, int _elfclass); +void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); +void _libelf_init_elf(Elf *_e, Elf_Kind _kind); +int _libelf_load_section_headers(Elf *e, void *ehdr); +unsigned int _libelf_malign(Elf_Type _t, int _elfclass); +Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror); +size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); +void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); +Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); +struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); +void _libelf_release_elf(Elf *_e); +Elf_Scn *_libelf_release_scn(Elf_Scn *_s); +int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); +int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); +int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, + size_t _shstrndx); +Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, + unsigned int _encoding, int _elfclass, int _elfmachine, int _direction); +int _libelf_xlate_shtype(uint32_t _sht); +#ifdef __cplusplus +} +#endif + +#endif /* __LIBELF_H_ */ diff --git a/contrib/elftoolchain/libelf/_libelf_ar.h b/contrib/elftoolchain/libelf/_libelf_ar.h new file mode 100644 index 0000000000..45a7e16be8 --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf_ar.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libelf_ar.h 3013 2014-03-23 06:16:59Z jkoshy $ + */ + +#ifndef __LIBELF_AR_H_ +#define __LIBELF_AR_H_ + +/* + * Prototypes and declarations needed by libelf's ar(1) archive + * handling code. + */ + +#include + +#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX "#1/" +#define LIBELF_AR_BSD_SYMTAB_NAME "__.SYMDEF" +#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE \ + (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) + +#define IS_EXTENDED_BSD_NAME(NAME) \ + (strncmp((const char *) (NAME), \ + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0) + + +unsigned char *_libelf_ar_get_string(const char *_buf, size_t _sz, + unsigned int _rawname, int _svr4names); +char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh); +char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar); +int _libelf_ar_get_number(const char *_buf, size_t _sz, + unsigned int _base, size_t *_ret); + +#endif /* __LIBELF_AR_H_ */ diff --git a/contrib/elftoolchain/libelf/_libelf_config.h b/contrib/elftoolchain/libelf/_libelf_config.h new file mode 100644 index 0000000000..bb71b96486 --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf_config.h @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libelf_config.h 3975 2022-04-30 20:10:58Z jkoshy $ + */ + +#if defined(__NetBSD__) + +#include + +#if !defined(ARCH_ELFSIZE) +#error ARCH_ELFSIZE is not defined. +#endif + +#if ARCH_ELFSIZE == 32 +#define Elf_Note Elf32_Nhdr +#else +#define Elf_Note Elf64_Nhdr +#endif + +#endif + +/* + * Downstream projects can replace the following placeholder with a custom + * definition of LIBELF_BYTEORDER, if the host's native byte order cannot + * be determined using the compilation environment. + */ +/* @LIBELF-DEFINE-HOST-BYTEORDER@ */ + +#if !defined(LIBELF_BYTEORDER) + +/* + * Use the __BYTE_ORDER__ and __ORDER_{LITTLE|BIG}_ENDIAN__ macros to + * determine the host's byte order. These macros are predefined by the + * GNU and CLANG C compilers. + */ +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define LIBELF_BYTEORDER ELFDATA2LSB +#else +#define LIBELF_BYTEORDER ELFDATA2MSB +#endif + +#else + +#error unknown host byte order + +#endif /* defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) */ +#endif /* !defined(LIBELF_BYTEORDER) */ diff --git a/contrib/elftoolchain/libelf/elf.3 b/contrib/elftoolchain/libelf/elf.3 new file mode 100644 index 0000000000..b90ca7c127 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf.3 @@ -0,0 +1,628 @@ +.\" Copyright (c) 2006-2008,2011,2019 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf.3 3927 2021-03-07 17:22:22Z jkoshy $ +.\" +.Dd March 7, 2021 +.Dt ELF 3 +.Os +.Sh NAME +.Nm elf +.Nd API for manipulating ELF objects +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Sh DESCRIPTION +The +.Lb libelf +provides functions that allow an application to read and manipulate +ELF object files, and to read +.Xr ar 1 +archives. +The library allows the manipulation of ELF objects in a byte ordering +and word-size independent way, allowing an application to read and +create ELF objects for 32 and 64 bit architectures and for little- +and big-endian machines. +The library is capable of processing ELF objects that use extended +section numbering. +.Pp +This manual page serves to provide an overview of the functionality in +the ELF library. +Further information may found in the manual pages for individual +.Xr ELF 3 +functions that comprise the library. +.Ss ELF Concepts +As described in +.Xr elf 5 , +ELF files contain several data structures that are laid out in a +specific way. +ELF files begin with an +.Dq Executable Header , +and may contain an optional +.Dq Program Header Table , +and optional data in the form of ELF +.Dq sections . +A +.Dq Section Header Table +describes the content of the data in these sections. +.Pp +ELF objects have an associated +.Dq "ELF class" +which denotes the natural machine word size for the architecture +the object is associated with. +Objects for 32 bit architectures have an ELF class of +.Dv ELFCLASS32 . +Objects for 64 bit architectures have an ELF class of +.Dv ELFCLASS64 . +.Pp +ELF objects also have an associated +.Dq endianness +which denotes the endianness of the machine architecture associated +with the object. +This may be +.Dv ELFDATA2LSB +for little-endian architectures and +.Dv ELFDATA2MSB +for big-endian architectures. +.Pp +ELF objects are also associated with an API version number. +This version number determines the layout of the individual components +of an ELF file and the semantics associated with these. +.Ss Data Representation And Translation +The +.Xr ELF 3 +library distinguishes between +.Dq native +representations of ELF data structures and their +.Dq file +representations. +.Pp +An application would work with ELF data in its +.Dq native +representation, i.e., using the native byteorder and alignment mandated +by the processor the application is running on. +The +.Dq file +representation of the same data could use a different byte ordering +and follow different constraints on object alignment than these native +constraints. +.Pp +Accordingly, the +.Xr ELF 3 +library offers translation facilities +.Xr ( elf32_xlatetof 3 , +.Xr elf32_xlatetom 3 , +.Xr elf64_xlatetof 3 +and +.Xr elf64_xlatetom 3 ) +to and from these representations. +It also provides higher-level APIs +.Xr ( gelf_xlatetof 3 , +.Xr gelf_xlatetom 3 ) +that retrieve and store data from the ELF object in a class-agnostic +manner. +.Ss Library Working Version +Conceptually, there are three version numbers associated with an +application using the ELF library to manipulate ELF objects: +.Bl -bullet -compact -offset indent +.It +The ELF version that the application was compiled against. +This version determines the ABI expected by the application. +.It +The ELF version of the ELF object being manipulated by the +application through the ELF library. +.It +The ELF version (or set of versions) supported by the ELF library itself. +.El +.Pp +In order to facilitate working with ELF objects of differing versions, +the ELF library requires the application to call the +.Fn elf_version +function before invoking many of its operations, in order to inform +the library of the application's desired working version. +.Pp +In the current implementation, all three versions have to be +.Dv EV_CURRENT . +.Ss Namespace use +The ELF library uses the following prefixes: +.Bl -tag -width "ELF_F_*" +.It Dv elf_ +Used for class-independent functions. +.It Dv elf32_ +Used for functions working with 32 bit ELF objects. +.It Dv elf64_ +Used for functions working with 64 bit ELF objects. +.It Dv Elf_ +Used for class-independent data types. +.It Dv ELF_C_ +Used for command values used in a few functions. +These symbols are defined as members of the +.Vt Elf_Cmd +enumeration. +.It Dv ELF_E_ +Used for error numbers. +.It Dv ELF_F_ +Used for flags. +.It Dv ELF_K_ +These constants define the kind of file associated with an ELF +descriptor. +See +.Xr elf_kind 3 . +The symbols are defined by the +.Vt Elf_Kind +enumeration. +.It Dv ELF_T_ +These values are defined by the +.Vt Elf_Type +enumeration, and denote the types of ELF data structures +that can be present in an ELF object. +.El +.Pp +In addition, the library uses symbols with prefixes +.Dv _ELF +and +.Dv _libelf +for its internal use. +.Ss Descriptors +Applications communicate with the library using descriptors. +These are: +.Bl -tag -width ".Vt Elf_Data" +.It Vt Elf +An +.Vt Elf +descriptor represents an ELF object or an +.Xr ar 1 +archive. +It is allocated using one of the +.Fn elf_begin +or +.Fn elf_memory +functions. +An +.Vt Elf +descriptor can be used to read and write data to an ELF file. +An +.Vt Elf +descriptor can be associated with zero or more +.Vt Elf_Scn +section descriptors. +.Pp +Given an ELF descriptor, the application may retrieve the ELF +object's class-dependent +.Dq "Executable Header" +structures using the +.Fn elf32_getehdr +or +.Fn elf64_getehdr +functions. +A new Ehdr structure may be allocated using the +.Fn elf64_newehdr +or +.Fn elf64_newehdr +functions. +.Pp +The +.Dq "Program Header Table" +associated with an ELF descriptor may be allocated using the +.Fn elf32_getphdr +or +.Fn elf64_getphdr +functions. +A new program header table may be allocated or an existing table +resized using the +.Fn elf32_newphdr +or +.Fn elf64_newphdr +functions. +.Pp +The +.Vt Elf +structure is opaque and has no members visible to the +application. +.It Vt Elf_Data +An +.Vt Elf_Data +data structure describes an individual chunk of a ELF file as +represented in memory. +It has the following application-visible members: +.Bl -tag -width ".Vt unsigned int d_version" -compact +.It Vt "uint64_t d_align" +The in-file alignment of the data buffer within its containing ELF section. +This value must be non-zero and a power of two. +.It Vt "void *d_buf" +A pointer to data in memory. +.It Vt "uint64_t d_off" +The offset within the containing section where this descriptor's data +would be placed. +This field will be computed by the library unless the application +requests full control of the ELF object's layout. +.It Vt "uint64_t d_size" +The number of bytes of data in this descriptor. +.It Vt "Elf_Type d_type" +The ELF type (see below) of the data in this descriptor. +.It Vt "unsigned int d_version" +The operating version for the data in this buffer. +.El +.Pp +.Vt Elf_Data +descriptors are usually used in conjunction with +.Vt Elf_Scn +descriptors. +.It Vt Elf_Scn +.Vt Elf_Scn +descriptors represent sections in an ELF object. +These descriptors are opaque and contain no application modifiable +fields. +.Pp +The +.Vt Elf_Scn +descriptor for a specific section in an ELF object can be +retrieved using the +.Fn elf_getscn +function. +The sections contained in an ELF object can be traversed using the +.Fn elf_nextscn +function. +New sections are allocated using the +.Fn elf_newscn +function. +.Pp +The +.Vt Elf_Data +descriptors associated with a given section can be retrieved +using the +.Fn elf_getdata +function. +New data descriptors can be added to a section +descriptor using the +.Fn elf_newdata +function. +The untranslated +.Dq file +representation of data in a section can be retrieved using the +.Fn elf_rawdata +function. +.El +.Ss Supported Elf Types +The following ELF datatypes are supported by the library. +.Pp +.Bl -tag -width ".Dv ELF_T_SYMINFO" -compact +.It Dv ELF_T_ADDR +Machine addresses. +.It Dv ELF_T_BYTE +Byte data. +The library will not attempt to translate byte data. +.It Dv ELF_T_CAP +Software and hardware capability records. +.It Dv ELF_T_DYN +Records used in a section of type +.Dv SHT_DYNAMIC . +.It Dv ELF_T_EHDR +ELF executable header. +.It Dv ELF_T_GNUHASH +GNU-style hash tables. +.It Dv ELF_T_HALF +16-bit unsigned words. +.It Dv ELF_T_LWORD +64 bit unsigned words. +.It Dv ELF_T_MOVE +ELF Move records. +.\".It Dv ELF_T_MOVEP +.\" As yet unsupported. +.It Dv ELF_T_NOTE +ELF Note structures. +.It Dv ELF_T_OFF +File offsets. +.It Dv ELF_T_PHDR +ELF program header table entries. +.It Dv ELF_T_REL +ELF relocation entries. +.It Dv ELF_T_RELA +ELF relocation entries with addends. +.It Dv ELF_T_SHDR +ELF section header entries. +.It Dv ELF_T_SWORD +Signed 32-bit words. +.It Dv ELF_T_SXWORD +Signed 64-bit words. +.It Dv ELF_T_SYMINFO +ELF symbol information. +.It Dv ELF_T_SYM +ELF symbol table entries. +.It Dv ELF_T_VDEF +Symbol version definition records. +.It Dv ELF_T_VNEED +Symbol version requirement records. +.It Dv ELF_T_WORD +Unsigned 32-bit words. +.It Dv ELF_T_XWORD +Unsigned 64-bit words. +.El +.Pp +The symbol +.Dv ELF_T_NUM +denotes the number of Elf types known to the library. +.Pp +The following table shows the mapping between ELF section types +defined in +.Xr elf 5 +and the types supported by the library. +.Bl -column ".Dv SHT_PREINIT_ARRAY" ".Dv ELF_T_SYMINFO" +.It Em Section Type Ta Em "Library Type" Ta Em Description +.It Dv SHT_DYNAMIC Ta Dv ELF_T_DYN Ta Xo +.Sq .dynamic +section entries. +.Xc +.It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. +.It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. +.It Dv SHT_GNU_HASH Ta Dv ELF_T_GNUHASH Ta GNU hash sections. +.It Dv SHT_GNU_LIBLIST Ta Dv ELF_T_WORD Ta List of libraries to be pre-linked. +.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. +.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. +.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. +.It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. +.It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. +.It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. +.It Dv SHT_NOBITS Ta Dv ELF_T_BYTE Ta Xo +Empty sections. +See +.Xr elf 5 . +.Xc +.It Dv SHT_NOTE Ta Dv ELF_T_NOTE Ta ELF note records. +.It Dv SHT_PREINIT_ARRAY Ta Dv ELF_T_ADDR Ta Pre-initialization function pointers. +.It Dv SHT_PROGBITS Ta Dv ELF_T_BYTE Ta Machine code. +.It Dv SHT_REL Ta Dv ELF_T_REL Ta ELF relocation records. +.It Dv SHT_RELA Ta Dv ELF_T_RELA Ta Relocation records with addends. +.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. +.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. +.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. +.It Dv SHT_SUNW_dof Ta Dv ELF_T_BYTE Ta Xo +Used by +.Xr dtrace 1 . +.Xc +.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. +.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. +.It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo +Same as +.Dv SHT_GNU_verdef . +.Xc +.It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo +Same as +.Dv SHT_GNU_verneed . +.Xc +.It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo +Same as +.Dv SHT_GNU_versym . +.Xc +.El +.Pp +Section types in the range +.Dv [ SHT_LOOS , +.Dv SHT_HIUSER ] +are otherwise considered to be of type +.Dv ELF_T_BYTE . +.Ss Functional Grouping +This section contains a brief overview of the available functionality +in the ELF library. +Each function listed here is described further in its own manual page. +.Bl -tag -width indent +.It "Archive Access" +.Bl -tag -compact -width indent +.It Fn elf_getarsym +Retrieve the archive symbol table. +.It Fn elf_getarhdr +Retrieve the archive header for an object. +.It Fn elf_getbase +Retrieve the offset of a member inside an archive. +.It Fn elf_next +Iterate through an +.Xr ar 1 +archive. +.It Fn elf_rand +Random access inside an +.Xr ar 1 +archive. +.El +.It "Data Structures" +.Bl -tag -compact -width indent +.It Fn elf_getdata +Retrieve translated data for an ELF section. +.It Fn elf_getscn +Retrieve the section descriptor for a named section. +.It Fn elf_ndxscn +Retrieve the index for a section. +.It Fn elf_newdata +Add a new +.Vt Elf_Data +descriptor to an ELF section. +.It Fn elf_newscn +Add a new section descriptor to an ELF descriptor. +.It Fn elf_nextscn +Iterate through the sections in an ELF object. +.It Fn elf_rawdata +Retrieve untranslated data for an ELF section. +.It Fn elf_rawfile +Return a pointer to the untranslated file contents for an ELF object. +.It Fn elf32_getehdr , Fn elf64_getehdr +Retrieve the Executable Header in an ELF object. +.It Fn elf32_getphdr , Fn elf64_getphdr +Retrieve the Program Header Table in an ELF object. +.It Fn elf32_getshdr , Fn elf64_getshdr +Retrieve the ELF section header associated with an +.Vt Elf_Scn +descriptor. +.It Fn elf32_newehdr , Fn elf64_newehdr +Allocate an Executable Header in an ELF object. +.It Fn elf32_newphdr , Fn elf64_newphdr +Allocate or resize the Program Header Table in an ELF object. +.El +.It "Data Translation" +.Bl -tag -compact -width indent +.It Fn elf32_xlatetof , Fn elf64_xlatetof +Translate an ELF data structure from its native representation to its +file representation. +.It Fn elf32_xlatetom , Fn elf64_xlatetom +Translate an ELF data structure from its file representation to a +native representation. +.El +.It "Error Reporting" +.Bl -tag -compact -width indent +.It Fn elf_errno +Retrieve the current error. +.It Fn elf_errmsg +Retrieve a human readable description of the current error. +.El +.It "Initialization" +.Bl -tag -compact -width indent +.It Fn elf_begin +Opens an +.Xr ar 1 +archive or ELF object given a file descriptor. +.It Fn elf_end +Close an ELF descriptor and release all its resources. +.It Fn elf_memory +Opens an +.Xr ar 1 +archive or ELF object present in a memory arena. +.It Fn elf_version +Sets the operating version. +.El +.It "IO Control" +.Bl -tag -width ".Fn elf_setshstrndx" -compact +.It Fn elf_cntl +Manage the association between and ELF descriptor and its underlying file. +.It Fn elf_flagdata +Mark an +.Vt Elf_Data +descriptor as dirty. +.It Fn elf_flagehdr +Mark the ELF Executable Header in an ELF descriptor as dirty. +.It Fn elf_flagphdr +Mark the ELF Program Header Table in an ELF descriptor as dirty. +.It Fn elf_flagscn +Mark an +.Vt Elf_Scn +descriptor as dirty. +.It Fn elf_flagshdr +Mark an ELF Section Header as dirty. +.It Fn elf_setshstrndx +Set the index of the section name string table for the ELF object. +.It Fn elf_update +Recompute ELF object layout and optionally write the modified object +back to the underlying file. +.El +.It "Queries" +.Bl -tag -width ".Fn elf_getshstrndx" -compact +.It Fn elf32_checksum , Fn elf64_checkum +Compute checksum of an ELF object. +.It Fn elf_getident +Retrieve the identification bytes for an ELF object. +.It Fn elf_getphdrnum +Retrieve the number of program headers in an ELF object. +.It Fn elf_getshdrnum +Retrieve the number of sections in an ELF object. +.It Fn elf_getshdrstrndx +Retrieve the section index of the section name string table in +an ELF object. +.It Fn elf_hash +Compute the ELF hash value of a string. +.It Fn elf_kind +Query the kind of object associated with an ELF descriptor. +.It Fn elf32_fsize , Fn elf64_fsize +Return the size of the file representation of an ELF type. +.El +.El +.Ss Controlling ELF Object Layout +In the usual mode of operation, library will compute section +offsets and alignments based on the contents of an ELF descriptor's +sections without need for further intervention by the +application. +.Pp +However, if the application wishes to take complete charge of the +layout of the ELF file, it may set the +.Dv ELF_F_LAYOUT +flag on an ELF descriptor using +.Xr elf_flagelf 3 , +following which the library will use the data offsets and alignments +specified by the application when laying out the file. +Application control of file layout is described further in the +.Xr elf_update 3 +manual page. +.Pp +Gaps in between sections will be filled with the fill character +set by function +.Fn elf_fill . +.Ss Error Handling +In case an error is encountered, these library functions set an +internal error number and signal the presence of the error by +returning a special return value. +The application can check the +current error number by calling +.Xr elf_errno 3 . +A human readable description of the recorded error is available by +calling +.Xr elf_errmsg 3 . +.Ss Memory Management Rules +The library keeps track of all +.Vt Elf_Scn +and +.Vt Elf_Data +descriptors associated with an ELF descriptor and recovers them +when the descriptor is closed using +.Xr elf_end 3 . +Thus the application must not call +.Xr free 3 +on data structures allocated by the ELF library. +.Pp +Conversely the library will not +free data that it has not allocated. +As an example, an application may call +.Xr elf_newdata 3 +to allocate a new +.Vt Elf_Data +descriptor and can set the +.Va d_off +member of the descriptor to point to a region of memory allocated +using +.Xr malloc 3 . +It is the applications responsibility to free this arena, though the +library will reclaim the space used by the +.Vt Elf_Data +descriptor itself. +.Sh SEE ALSO +.Xr gelf 3 , +.Xr ar 5 , +.Xr elf 5 +.Sh HISTORY +The original +.Nm +API was developed for +.At V . +The current implementation of the API appeared in +.Fx 7.0 +and +.Nx 6.0 . +.Sh AUTHORS +The ELF library was written by +.An Joseph Koshy Aq Mt jkoshy@FreeBSD.org . diff --git a/contrib/elftoolchain/libelf/elf.c b/contrib/elftoolchain/libelf/elf.c new file mode 100644 index 0000000000..b168c41a73 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +struct _libelf_globals _libelf = { + .libelf_byteorder = LIBELF_BYTEORDER, + .libelf_error = 0, + .libelf_fillchar = 0, + .libelf_version = EV_NONE +}; diff --git a/contrib/elftoolchain/libelf/elf_begin.3 b/contrib/elftoolchain/libelf/elf_begin.3 new file mode 100644 index 0000000000..f12de85aff --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_begin.3 @@ -0,0 +1,327 @@ +.\" Copyright (c) 2006,2008-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_begin.3 3952 2022-03-12 09:09:50Z jkoshy $ +.\" +.Dd December 11, 2011 +.Dt ELF_BEGIN 3 +.Os +.Sh NAME +.Nm elf_begin +.Nd open an ELF file or ar(1) archive +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_begin "int fd" "Elf_Cmd cmd" "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_begin +is used to open ELF files and +.Xr ar 1 +archives for further processing by other APIs in the +.Xr elf 3 +library. +It is also used to access individual ELF members of an +.Xr ar 1 +archive in combination with the +.Xr elf_next 3 +and +.Xr elf_rand 3 +APIs. +.Pp +Argument +.Fa fd +is an open file descriptor returned from an +.Xr open 2 +system call. +Function +.Fn elf_begin +uses argument +.Fa fd +for reading or writing depending on the value of argument +.Fa cmd . +Argument +.Fa elf +is primarily used for iterating through archives. +.Pp +The argument +.Fa cmd +can have the following values: +.Bl -tag -width "ELF_C_WRITE" +.It ELF_C_NULL +Causes +.Fn elf_begin +to return +.Dv NULL . +Arguments +.Fa fd +and +.Fa elf +are ignored, and no additional error is signalled. +.It ELF_C_READ +This value is to be when the application wishes to examine (but not +modify) the contents of the file specified by the arguments +.Fa fd +and +.Fa elf . +It can be used for both +.Xr ar 1 +archives and for ELF objects. +.Pp +If argument +.Fa elf +is +.Dv NULL , +the library will allocate a new ELF descriptor for the file +being processed. +The argument +.Fa fd +should have been opened for reading. +.Pp +If argument +.Fa elf +is not +.Dv NULL , +and references a regular ELF file previously opened with +.Fn elf_begin , +then the activation count for the descriptor referenced by argument +.Fa elf +is incremented. +The value in argument +.Fa fd +should match that used to open the descriptor argument +.Fa elf . +.Pp +If argument +.Fa elf +is not +.Dv NULL , +and references a descriptor for an +.Xr ar 1 +archive opened earlier with +.Fn elf_begin , +a descriptor for an element in the archive is returned as +described in the section +.Sx "Processing ar(1) archives" +below. +The value for argument +.Fa fd +should match that used to open the archive earlier. +.Pp +If argument +.Fa elf +is not +.Dv NULL , +and references an +.Xr ar 1 +archive opened earlier with +.Fn elf_memory , +then the value of the argument +.Fa fd +is ignored. +.It Dv ELF_C_RDWR +This command is used to prepare an ELF file for reading and writing. +This command is not supported for +.Xr ar 1 +archives. +.Pp +Argument +.Fa fd +should have been opened for reading and writing. +If argument +.Fa elf +is +.Dv NULL , +the library will allocate a new ELF descriptor for +the file being processed. +If the argument +.Fa elf +is non-null, it should point to a descriptor previously +allocated with +.Fn elf_begin +with the same values for arguments +.Fa fd +and +.Fa cmd ; +in this case the library will increment the activation count for descriptor +.Fa elf +and return the same descriptor. +.Pp +Changes to the in-memory image of the ELF file may be written back to +disk using the +.Xr elf_update 3 +function. +.It Dv ELF_C_WRITE +This command is used when the application wishes to create a new ELF +file. +Argument +.Fa fd +should have been opened for writing. +Argument +.Fa elf +is ignored, and the previous contents of file referenced by argument +.Fa fd +are overwritten. +.El +.Ss Processing ar(1) archives +An +.Xr ar 1 +archive may be opened in read mode (with argument +.Fa cmd +set to +.Dv ELF_C_READ ) +using +.Fn elf_begin +or +.Fn elf_memory . +The returned ELF descriptor can be passed into to +subsequent calls to +.Fn elf_begin +to access individual members of the archive. +.Pp +Random access within an opened archive is possible using +the +.Xr elf_next 3 +and +.Xr elf_rand 3 +functions. +.Pp +The symbol table of the archive may be retrieved +using +.Xr elf_getarsym 3 . +.Sh RETURN VALUES +The function returns a pointer to a ELF descriptor if successful, or +.Dv NULL +if an error occurred. +.Sh EXAMPLES +To iterate through the members of an +.Xr ar 1 +archive, use: +.Bd -literal -offset indent +Elf_Cmd c; +Elf *ar_e, *elf_e; +\&... +c = ELF_C_READ; +if ((ar_e = elf_begin(fd, c, (Elf *) 0)) == 0) { + \&... handle error in opening the archive ... +} +while ((elf_e = elf_begin(fd, c, ar_e)) != 0) { + \&... process member referenced by elf_e here ... + c = elf_next(elf_e); + elf_end(elf_e); +} +.Ed +.Pp +To create a new ELF file, use: +.Bd -literal -offset indent +int fd; +Elf *e; +\&... +if ((fd = open("filename", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) { + \&... handle the error from open(2) ... +} +if ((e = elf_begin(fd, ELF_C_WRITE, (Elf *) 0)) == 0) { + \&... handle the error from elf_begin() ... +} +\&... create the ELF image using other elf(3) APIs ... +elf_update(e, ELF_C_WRITE); +elf_end(e); +.Ed +.Sh ERRORS +Function +.Fn elf_begin +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARCHIVE +The archive denoted by argument +.Fa elf +could not be parsed. +.It Bq Er ELF_E_ARGUMENT +The value in argument +.Fa cmd +was unrecognized. +.It Bq Er ELF_E_ARGUMENT +A non-null value for argument +.Fa elf +was specified when +.Fa cmd +was set to +.Dv ELF_C_RDWR . +.It Bq Er ELF_E_ARGUMENT +The value of argument +.Fa fd +differs from the one the ELF descriptor +.Fa elf +was created with. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa cmd +differs from the value specified when ELF descriptor +.Fa elf +was created. +.It Bq Er ELF_E_ARGUMENT +An +.Xr ar 1 +archive was opened with +.Fa cmd +set to +.Dv ELF_C_RDWR . +.It Bq Er ELF_E_ARGUMENT +The file referenced by argument +.Fa fd +was empty. +.It Bq Er ELF_E_ARGUMENT +The underlying file for argument +.Fa fd +was of an unsupported type. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Fa fd +was invalid. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Fa fd +could not be read or written to. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was encountered. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_begin +was called before a working version was established with +.Xr elf_version 3 . +.It Bq Er ELF_E_VERSION +The ELF object referenced by argument +.Fa fd +was of an unsupported ELF version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_end 3 , +.Xr elf_errno 3 , +.Xr elf_memory 3 , +.Xr elf_next 3 , +.Xr elf_rand 3 , +.Xr elf_update 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_begin.c b/contrib/elftoolchain/libelf/elf_begin.c new file mode 100644 index 0000000000..5045de07b4 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_begin.c @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_begin.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf * +elf_begin(int fd, Elf_Cmd c, Elf *a) +{ + Elf *e; + + e = NULL; + + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + switch (c) { + case ELF_C_NULL: + return (NULL); + + case ELF_C_WRITE: + /* + * The ELF_C_WRITE command is required to ignore the + * descriptor passed in. + */ + a = NULL; + break; + + case ELF_C_RDWR: + if (a != NULL) { /* not allowed for ar(1) archives. */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + /*FALLTHROUGH*/ + case ELF_C_READ: + /* + * Descriptor `a' could be for a regular ELF file, or + * for an ar(1) archive. If descriptor `a' was opened + * using a valid file descriptor, we need to check if + * the passed in `fd' value matches the original one. + */ + if (a && + ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + break; + + default: + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + + } + + if (a == NULL) + e = _libelf_open_object(fd, c, 1); + else if (a->e_kind == ELF_K_AR) + e = _libelf_ar_open_member(a->e_fd, c, a); + else + (e = a)->e_activations++; + + return (e); +} diff --git a/contrib/elftoolchain/libelf/elf_cntl.3 b/contrib/elftoolchain/libelf/elf_cntl.3 new file mode 100644 index 0000000000..8848320312 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_cntl.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_cntl.3 3953 2022-03-12 09:57:05Z jkoshy $ +.\" +.Dd August 9, 2006 +.Dt ELF_CNTL 3 +.Os +.Sh NAME +.Nm elf_cntl +.Nd control an elf file descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_cntl "Elf *elf" "Elf_Cmd cmd" +.Sh DESCRIPTION +Function +.Fn elf_cntl +controls the ELF library's subsequent use of the file descriptor +used to create ELF descriptor +.Fa elf . +.Pp +Argument +.Fa cmd +informs the library of the action to be taken: +.Bl -tag -width "ELF_C_FDDONE" +.It Dv ELF_C_FDDONE +This value instructs the ELF library not to perform any further +I/O on the file descriptor associated with argument +.Fa elf . +For ELF descriptors opened with mode +.Dv ELF_C_WRITE +or +.Dv ELF_C_RDWR +subsequent +.Fn elf_update +operations on the descriptor will fail. +.It Dv ELF_C_FDREAD +This value instructs the ELF library to read in all necessary +data associated with ELF descriptor +.Fa elf +into memory so that the underlying file descriptor can be +safely closed with command +.Dv ELF_C_FDDONE . +.El +.Pp +Argument +.Fa elf +must be an ELF descriptor associated with a file system object +(e.g., an +.Xr ar 1 +archive, an ELF file, or other data file). +.Sh IMPLEMENTATION NOTES +Due to use of +.Xr mmap 2 +internally, this function is a no-op for ELF objects opened in +.Dv ELF_C_READ +mode. +.Sh RETURN VALUES +Function +.Fn elf_cntl +returns 0 on success, or -1 if an error was detected. +.Sh ERRORS +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARCHIVE +Argument +.Fa elf +is a descriptor for an archive member. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa cmd +was not recognized. +.It Bq Er ELF_E_MODE +An +.Dv ELF_C_FDREAD +operation was requested on an ELF descriptor opened +for writing. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_next 3 , +.Xr elf_update 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_cntl.c b/contrib/elftoolchain/libelf/elf_cntl.c new file mode 100644 index 0000000000..5d14375a5b --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_cntl.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_cntl.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +int +elf_cntl(Elf *e, Elf_Cmd c) +{ + if (e == NULL || + (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if (e->e_parent) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (-1); + } + + if (c == ELF_C_FDREAD) { + if (e->e_cmd == ELF_C_WRITE) { + LIBELF_SET_ERROR(MODE, 0); + return (-1); + } + else + return (0); + } + + e->e_fd = -1; + return 0; +} diff --git a/contrib/elftoolchain/libelf/elf_data.c b/contrib/elftoolchain/libelf/elf_data.c new file mode 100644 index 0000000000..2ab6783cba --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_data.c @@ -0,0 +1,284 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_data.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Data * +elf_getdata(Elf_Scn *s, Elf_Data *ed) +{ + Elf *e; + unsigned int sh_type; + int elfclass, elftype; + size_t count, fsz, msz; + struct _Libelf_Data *d; + uint64_t sh_align, sh_offset, sh_size, raw_size; + _libelf_translator_function *xlate; + + d = (struct _Libelf_Data *) ed; + + if (s == NULL || (e = s->s_elf) == NULL || + (d != NULL && s != d->d_scn)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) + return (&d->d_data); + + if (d != NULL) + return (STAILQ_NEXT(d, d_next) ? + &STAILQ_NEXT(d, d_next)->d_data : NULL); + + if (e->e_rawfile == NULL) { + /* + * In the ELF_C_WRITE case, there is no source that + * can provide data for the section. + */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + elfclass = e->e_class; + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + + if (elfclass == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_offset = s->s_shdr.s_shdr64.sh_offset; + sh_size = s->s_shdr.s_shdr64.sh_size; + sh_align = s->s_shdr.s_shdr64.sh_addralign; + } + + if (sh_type == SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + raw_size = (uint64_t) e->e_rawsize; + if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || + elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && + (sh_offset > raw_size || sh_size > raw_size - sh_offset))) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) + (elftype, (size_t) 1, e->e_version)) == 0) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (NULL); + } + + if (sh_size % fsz) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if (sh_size / fsz > SIZE_MAX) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + count = (size_t) (sh_size / fsz); + + if ((msz = _libelf_msize(elftype, elfclass, e->e_version)) == 0) + return (NULL); + + if (count > 0 && msz > SIZE_MAX / count) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + assert(msz > 0); + assert(count <= SIZE_MAX); + assert(msz * count <= SIZE_MAX); + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + d->d_data.d_buf = NULL; + d->d_data.d_off = 0; + d->d_data.d_align = sh_align; + d->d_data.d_size = msz * count; + d->d_data.d_type = elftype; + d->d_data.d_version = e->e_version; + + if (sh_type == SHT_NOBITS || sh_size == 0) { + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + return (&d->d_data); + } + + if ((d->d_data.d_buf = malloc(msz * count)) == NULL) { + (void) _libelf_release_data(d); + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + d->d_flags |= LIBELF_F_DATA_MALLOCED; + + xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass, + _libelf_elfmachine(e)); + if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size, + e->e_rawfile + sh_offset, count, + e->e_byteorder != LIBELF_PRIVATE(byteorder))) { + _libelf_release_data(d); + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + + return (&d->d_data); +} + +Elf_Data * +elf_newdata(Elf_Scn *s) +{ + Elf *e; + struct _Libelf_Data *d; + + if (s == NULL || (e = s->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + /* + * elf_newdata() has to append a data descriptor, so + * bring in existing section data if not already present. + */ + if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) + if (elf_getdata(s, NULL) == NULL) + return (NULL); + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + + d->d_data.d_align = 1; + d->d_data.d_buf = NULL; + d->d_data.d_off = (uint64_t) ~0; + d->d_data.d_size = 0; + d->d_data.d_type = ELF_T_BYTE; + d->d_data.d_version = LIBELF_PRIVATE(version); + + (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); + + return (&d->d_data); +} + +/* + * Retrieve a data descriptor for raw (untranslated) data for section + * `s'. + */ + +Elf_Data * +elf_rawdata(Elf_Scn *s, Elf_Data *ed) +{ + Elf *e; + int elf_class; + uint32_t sh_type; + struct _Libelf_Data *d; + uint64_t sh_align, sh_offset, sh_size, raw_size; + + if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + d = (struct _Libelf_Data *) ed; + + if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) + return (&d->d_data); + + if (d != NULL) + return (&STAILQ_NEXT(d, d_next)->d_data); + + elf_class = e->e_class; + + assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); + + if (elf_class == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_offset = s->s_shdr.s_shdr64.sh_offset; + sh_size = s->s_shdr.s_shdr64.sh_size; + sh_align = s->s_shdr.s_shdr64.sh_addralign; + } + + if (sh_type == SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + raw_size = (uint64_t) e->e_rawsize; + if (sh_type != SHT_NOBITS && + (sh_offset > raw_size || sh_size > raw_size - sh_offset)) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + d->d_data.d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : + e->e_rawfile + sh_offset; + d->d_data.d_off = 0; + d->d_data.d_align = sh_align; + d->d_data.d_size = sh_size; + d->d_data.d_type = ELF_T_BYTE; + d->d_data.d_version = e->e_version; + + STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); + + return (&d->d_data); +} diff --git a/contrib/elftoolchain/libelf/elf_end.3 b/contrib/elftoolchain/libelf/elf_end.3 new file mode 100644 index 0000000000..dafaf1f233 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_end.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_end.3 3954 2022-03-12 12:07:16Z jkoshy $ +.\" +.Dd June 29, 2006 +.Dt ELF_END 3 +.Os +.Sh NAME +.Nm elf_end +.Nd release an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_end "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_end +is used to release the resources associated with an ELF descriptor +pointed to by argument +.Fa elf . +This descriptor must have been allocated by a previous call to +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +For programming convenience, a +.Dv NULL +value is permitted for argument +.Fa elf . +.Pp +A call to +.Fn elf_end +decrements the activation count for descriptor +.Fa elf +by one. +The resources associated with the descriptor are only released +with its activation count goes to zero. +.Pp +Once function +.Fn elf_end +returns zero, the ELF descriptor +.Fa elf +will no longer be valid and should not be used further. +.Sh RETURN VALUES +Function +.Fn elf_end +returns the current value of the ELF descriptor +.Fa elf Ap s +activation count, or zero if argument +.Fa elf +was +.Dv NULL . +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_memory 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_end.c b/contrib/elftoolchain/libelf/elf_end.c new file mode 100644 index 0000000000..f7f3f7c8f6 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_end.c @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 2006,2008-2009,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include +#endif + +ELFTC_VCSID("$Id: elf_end.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +int +elf_end(Elf *e) +{ + Elf *sv; + Elf_Scn *scn, *tscn; + + if (e == NULL || e->e_activations == 0) + return (0); + + if (--e->e_activations > 0) + return (e->e_activations); + + assert(e->e_activations == 0); + + while (e && e->e_activations == 0) { + switch (e->e_kind) { + case ELF_K_AR: + /* + * If we still have open child descriptors, we + * need to defer reclaiming resources till all + * the child descriptors for the archive are + * closed. + */ + if (e->e_u.e_ar.e_nchildren > 0) + return (0); + break; + case ELF_K_ELF: + /* + * Reclaim all section descriptors. + */ + STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, + tscn) + scn = _libelf_release_scn(scn); + break; + case ELF_K_NUM: + assert(0); + default: + break; + } + + if (e->e_rawfile) { + if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) + free(e->e_rawfile); +#if ELFTC_HAVE_MMAP + else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) + (void) munmap(e->e_rawfile, (size_t) e->e_rawsize); +#endif + } + + sv = e; + if ((e = e->e_parent) != NULL) + e->e_u.e_ar.e_nchildren--; + _libelf_release_elf(sv); + } + + return (0); +} diff --git a/contrib/elftoolchain/libelf/elf_errmsg.3 b/contrib/elftoolchain/libelf/elf_errmsg.3 new file mode 100644 index 0000000000..a05cf4d953 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errmsg.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_errmsg.3 3954 2022-03-12 12:07:16Z jkoshy $ +.\" +.Dd June 11, 2006 +.Dt ELF_ERRMSG 3 +.Os +.Sh NAME +.Nm elf_errmsg , +.Nm elf_errno +.Nd ELF library error message handling +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_errno "void" +.Ft "const char *" +.Fn elf_errmsg "int error" +.Sh DESCRIPTION +When an error occurs during an ELF library API call, the library +encodes the error using an error number and stores the error number +internally for retrieval by the application at a later point of time. +Error numbers may contain an OS supplied error code in addition to +an ELF API specific error code. +An error number value of zero indicates no error. +.Pp +Function +.Fn elf_errno +is used to retrieve the last error recorded by the ELF library. +Invoking this function has the side-effect of resetting the +ELF library's recorded error number to zero. +.Pp +The function +.Fn elf_errmsg +returns a null-terminated string with a human readable +description of the error specified in argument +.Fa error . +A zero value for argument +.Fa error +retrieves the most recent error encountered by the ELF +library. +An argument value of -1 behaves identically, except that +it guarantees a +.No non- Ns Dv NULL +return from +.Fn elf_errmsg . +.Sh RETURN VALUES +Function +.Fn elf_errno +returns a non-zero value encoding the last error encountered +by the ELF library, or zero if no error was encountered. +.Pp +Function +.Fn elf_errmsg +returns a pointer to library local storage for non-zero values +of argument +.Fa error . +With a zero argument, the function will return a +.Dv NULL +pointer if no +error had been encountered by the library, or will return a pointer to +library local storage containing an appropriate message otherwise. +.Sh EXAMPLES +Clearing the ELF library's recorded error number can be accomplished +by invoking +.Fn elf_errno +and discarding its return value. +.Bd -literal -offset indent +/* clear error */ +(void) elf_errno(); +.Ed +.Pp +Retrieving a human-readable description of the current error number +can be done with the following snippet: +.Bd -literal -offset indent +int err; +const char *errmsg; +\&... +err = elf_errno(); +if (err != 0) + errmsg = elf_errmsg(err); +.Ed +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 +.Sh BUGS +Function +.Fn elf_errmsg +is not localized. diff --git a/contrib/elftoolchain/libelf/elf_errmsg.c b/contrib/elftoolchain/libelf/elf_errmsg.c new file mode 100644 index 0000000000..f0a3829051 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errmsg.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_errmsg.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Retrieve a human readable translation for an error message. + */ + +static const char *_libelf_errors[] = { +#define DEFINE_ERROR(N,S) [ELF_E_##N] = S + DEFINE_ERROR(NONE, "No Error"), + DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), + DEFINE_ERROR(ARGUMENT, "Invalid argument"), + DEFINE_ERROR(CLASS, "ELF class mismatch"), + DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), + DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), + DEFINE_ERROR(IO, "I/O error"), + DEFINE_ERROR(LAYOUT, "Layout constraint violation"), + DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), + DEFINE_ERROR(RANGE, "Value out of range of target"), + DEFINE_ERROR(RESOURCE, "Resource exhaustion"), + DEFINE_ERROR(SECTION, "Invalid section descriptor"), + DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), + DEFINE_ERROR(UNIMPL, "Unimplemented feature"), + DEFINE_ERROR(VERSION, "Unknown ELF API version"), + DEFINE_ERROR(NUM, "Unknown error") +#undef DEFINE_ERROR +}; + +const char * +elf_errmsg(int error) +{ + int oserr; + + if (error == ELF_E_NONE && + (error = LIBELF_PRIVATE(error)) == 0) + return NULL; + else if (error == -1) + error = LIBELF_PRIVATE(error); + + oserr = error >> LIBELF_OS_ERROR_SHIFT; + error &= LIBELF_ELF_ERROR_MASK; + + if (error < ELF_E_NONE || error >= ELF_E_NUM) + return _libelf_errors[ELF_E_NUM]; + if (oserr) { + (void) snprintf((char *) LIBELF_PRIVATE(msg), + sizeof(LIBELF_PRIVATE(msg)), "%s: %s", + _libelf_errors[error], strerror(oserr)); + return (const char *)&LIBELF_PRIVATE(msg); + } + return _libelf_errors[error]; +} diff --git a/contrib/elftoolchain/libelf/elf_errno.c b/contrib/elftoolchain/libelf/elf_errno.c new file mode 100644 index 0000000000..e81193a5be --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errno.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_errno.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +int +elf_errno(void) +{ + int old; + + old = LIBELF_PRIVATE(error); + LIBELF_PRIVATE(error) = 0; + return (old & LIBELF_ELF_ERROR_MASK); +} diff --git a/contrib/elftoolchain/libelf/elf_fill.3 b/contrib/elftoolchain/libelf/elf_fill.3 new file mode 100644 index 0000000000..2b78d5907c --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_fill.3 @@ -0,0 +1,52 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_fill.3 3639 2018-10-14 14:07:02Z jkoshy $ +.\" +.Dd June 11, 2006 +.Dt ELF_FILL 3 +.Os +.Sh NAME +.Nm elf_fill +.Nd set fill byte for inter-section padding +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft void +.Fn elf_fill "int fill" +.Sh DESCRIPTION +Function +.Fn elf_fill +allows an application to specify a fill value for the padding inserted +between two sections of an ELF file to meet section alignment +constraints. +By default the ELF library uses zero bytes for padding. +.Pp +The ELF library will only pad bytes if the +.Dv ELF_F_LAYOUT +flag is not set for the ELF file. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagelf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_fill.c b/contrib/elftoolchain/libelf/elf_fill.c new file mode 100644 index 0000000000..5e0d26c1af --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_fill.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_fill.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +void +elf_fill(int fill) +{ + LIBELF_PRIVATE(fillchar) = fill; +} diff --git a/contrib/elftoolchain/libelf/elf_flag.c b/contrib/elftoolchain/libelf/elf_flag.c new file mode 100644 index 0000000000..1d7b0df085 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_flag.c @@ -0,0 +1,200 @@ +/*- + * Copyright (c) 2006,2008-2009,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_flag.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +unsigned int +elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + + if (a == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (c == ELF_C_SET) + r = a->ar_flags |= flags; + else + r = a->ar_flags &= ~flags; + + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + struct _Libelf_Data *ld; + + if (d == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ld = (struct _Libelf_Data *) d; + + if (c == ELF_C_SET) + r = ld->d_flags |= flags; + else + r = ld->d_flags &= ~flags; + + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) +{ + int ec; + void *ehdr; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; + else + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; + + if (ehdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); +} + +unsigned int +elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || + (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV | + ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if (c == ELF_C_SET) + r = e->e_flags |= flags; + else + r = e->e_flags &= ~flags; + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) +{ + int ec; + void *phdr; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) + phdr = e->e_u.e_elf.e_phdr.e_phdr32; + else + phdr = e->e_u.e_elf.e_phdr.e_phdr64; + + if (phdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); +} + +unsigned int +elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + + if (s == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (c == ELF_C_SET) + r = s->s_flags |= flags; + else + r = s->s_flags &= ~flags; + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) +{ + return (elf_flagscn(s, c, flags)); +} diff --git a/contrib/elftoolchain/libelf/elf_flagdata.3 b/contrib/elftoolchain/libelf/elf_flagdata.3 new file mode 100644 index 0000000000..794697bad5 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_flagdata.3 @@ -0,0 +1,228 @@ +.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_flagdata.3 3954 2022-03-12 12:07:16Z jkoshy $ +.\" +.Dd June 12, 2019 +.Dt ELF_FLAGDATA 3 +.Os +.Sh NAME +.Nm elf_flagarhdr , +.Nm elf_flagdata , +.Nm elf_flagehdr , +.Nm elf_flagelf , +.Nm elf_flagphdr , +.Nm elf_flagscn , +.Nm elf_flagshdr +.Nd manipulate flags associated with ELF data structures +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "unsigned int" +.Fn elf_flagarhdr "Elf_Arhdr *arhdr" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagdata "Elf_Data *data" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagehdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagelf "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagphdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagscn "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" +.Sh DESCRIPTION +These functions are used to query, set or reset flags on data +structures associated with an ELF file. +.Pp +Arguments +.Fa arhdr , +.Fa data , +.Fa elf +and +.Fa scn +denote the data structures whose flags need to be changed. +These values should have been returned by prior calls to +functions in the +.Xr elf 3 +API set: +.Bl -bullet -compact +.It +Argument +.Fa arhdr +should have been returned by a prior call to +.Xr elf_getarhdr 3 . +.It +Argument +.Fa data +should have been returned by a prior call to one of +.Xr elf_newdata 3 , +.Xr elf_getdata 3 +or +.Xr elf_rawdata 3 . +.It +Argument +.Fa elf +should have been allocated by a prior call to one of +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +.It +Argument +.Fa scn +should have been returned by a prior call to one of +.Xr elf_getscn 3 , +.Xr elf_newscn 3 +or +.Xr elf_nextscn 3 . +.El +These values are allowed to be +.Dv NULL +to simplify error handling in application code. +.Pp +Argument +.Fa cmd +may have the following values: +.Bl -tag -width ELF_C_SET +.It Dv ELF_C_CLR +The argument +.Fa flags +specifies the flags to be cleared. +.It Dv ELF_C_SET +The argument +.Fa flags +specifies the flags to be set. +.El +.Pp +The argument +.Fa flags +is allowed to have the following flags set: +.Bl -tag -width ELF_F_ARCHIVE_SYSV +.It Dv ELF_F_ARCHIVE +This flag is only valid with the +.Fn elf_flagelf +API. +It informs the library that the application desires to create an +.Xr ar 1 +archive. +Argument +.Fa elf +should have been opened for writing using the +.Dv ELF_C_WRITE +command to function +.Fn elf_begin . +.It Dv ELF_F_ARCHIVE_SYSV +This flag is used in conjunction with the +.Dv ELF_F_ARCHIVE +flag to indicate that library should create archives that conform +to System V layout rules. +The default is to create BSD style archives. +.It Dv ELF_F_DIRTY +Mark the associated data structure as needing to be written back +to the underlying file. +A subsequent call to +.Xr elf_update 3 +will resynchronize the library's internal data structures. +.It Dv ELF_F_LAYOUT +This flag is only valid with the +.Fn elf_flagelf +API. +It informs the library that the application will take +responsibility for the layout of the file and that the library is +not to insert any padding in between sections. +.El +.Pp +Marking a given data structure as +.Dq dirty +affects all of its contained elements. +Thus marking an ELF descriptor +.Fa elf +with +.Fn elf_flagelf "elf" "ELF_C_SET" "ELF_F_DIRTY" +means that the entire contents of the descriptor are +.Dq dirty . +.Pp +Using a value of zero for argument +.Fa flags +will return the current set of flags for the data structure being +queried. +.Sh RETURN VALUES +These functions return the updated flags if successful, or zero if +an error is detected. +.Sh COMPATIBILITY +The +.Fn elf_flagarhdr +function and the +.Dv ELF_F_ARCHIVE +and +.Dv ELF_F_ARCHIVE_SYSV +flags are an extension to the +.Xr elf 3 +API. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +An unsupported value was used for the +.Fa cmd +argument. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa flags +had unsupported flags set. +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_MODE +The +.Dv ELF_F_ARCHIVE +flag was used with an ELF descriptor that had not been opened for writing. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_flagehdr +was called without an executable header being allocated. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_flagphdr +was called without a program header being allocated. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_newehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf_newdata 3 , +.Xr elf_update 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr gelf_newphdr 3 , +.Xr gelf_update_dyn 3 , +.Xr gelf_update_move 3 , +.Xr gelf_update_rel 3 , +.Xr gelf_update_rela 3 , +.Xr gelf_update_sym 3 , +.Xr gelf_update_syminfo 3 diff --git a/contrib/elftoolchain/libelf/elf_getarhdr.3 b/contrib/elftoolchain/libelf/elf_getarhdr.3 new file mode 100644 index 0000000000..2fbdc479a5 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarhdr.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getarhdr.3 3955 2022-03-12 12:24:36Z jkoshy $ +.\" +.Dd August 15, 2006 +.Dt ELF_GETARHDR 3 +.Os +.Sh NAME +.Nm elf_getarhdr +.Nd retrieve ar(1) header for an archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Arhdr *" +.Fn elf_getarhdr "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_getarhdr +function returns a pointer to an archive member header for +a descriptor +.Fa elf . +This descriptor must have been returned by a prior call to +.Xr elf_begin 3 , +and must be a descriptor for a member inside an +.Xr ar 1 +archive. +.Pp +Structure +.Vt Elf_Arhdr +includes the following members: +.Bl -tag -width indent +.It Vt "char *" Va ar_name +A pointer to a null terminated string containing the translated +name of the archive member. +.It Vt "char *" Va ar_rawname +A pointer to a null terminated string containing the untranslated +name for the archive member, including all +.Xr ar 1 +formatting characters and trailing white space. +.It Vt time_t Va ar_date +The timestamp associated with the member. +.It Vt uid_t Va ar_uid +The uid of the creator of the member. +.It Vt gid_t Va ar_gid +The gid of the creator of the member. +.It Vt mode_t Va ar_mode +The file mode of the member. +.It Vt size_t Va ar_size +The size of the member in bytes. +.El +.Sh RETURN VALUES +This function returns a valid pointer to an +.Vt Elf_Arhdr +structure if successful, or +.Dv NULL +if an error is encountered. +.Sh ERRORS +Function +.Fn elf_getarhdr +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for a member of an +.Xr ar 1 +archive. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getarsym 3 , +.Xr elf_memory 3 diff --git a/contrib/elftoolchain/libelf/elf_getarhdr.c b/contrib/elftoolchain/libelf/elf_getarhdr.c new file mode 100644 index 0000000000..1a1649f736 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarhdr.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getarhdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Arhdr * +elf_getarhdr(Elf *e) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (e->e_flags & LIBELF_F_AR_HEADER) + return (e->e_hdr.e_arhdr); + + return (_libelf_ar_gethdr(e)); +} diff --git a/contrib/elftoolchain/libelf/elf_getarsym.3 b/contrib/elftoolchain/libelf/elf_getarsym.3 new file mode 100644 index 0000000000..ed462d5c47 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarsym.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getarsym.3 3955 2022-03-12 12:24:36Z jkoshy $ +.\" +.Dd August 15, 2006 +.Dt ELF_GETARSYM 3 +.Os +.Sh NAME +.Nm elf_getarsym +.Nd retrieve the symbol table of an archive +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Arsym *" +.Fn elf_getarsym "Elf *elf" "size_t *ptr" +.Sh DESCRIPTION +The function +.Fn elf_getarsym +retrieves the symbol table for an +.Xr ar 1 +archive, if one is available. +.Pp +Argument +.Fa elf +should be a descriptor for an +.Xr ar 1 +archive opened using +.Fn elf_begin +or +.Fn elf_memory . +.Pp +If the archive +.Fa elf +contains a symbol table with n entries, this function returns a +pointer to an array of n+1 +.Vt Elf_Arsym +structures. +An +.Vt Elf_Arsym +structure has the following elements: +.Bl -tag -width indent -compact +.It Vt "char *" Va as_name +This structure member is a pointer to a null-terminated symbol name. +.It Vt "off_t" Va as_off +This structure member contains the byte offset from the beginning of the archive to +the header for the archive member. +This value is suitable for use with +.Xr elf_rand 3 . +.It Vt "unsigned long" Va as_hash +This structure member contains a portable hash value for the symbol +name, as computed by +.Xr elf_hash 3 . +.El +.Pp +The last entry of the returned array will have a +.Dv NULL +value for member +.Va as_name , +a zero value for member +.Va as_off +and an illegal value of ~0UL for +.Va as_hash . +.Pp +If argument +.Fa ptr +is non-null, the +.Fn elf_getarsym +function will store the number of table entries returned (including the +sentinel entry at the end) into the location it points to. +.Sh RETURN VALUES +Function +.Fn elf_getarsym +returns a pointer to an array of +.Vt Elf_Arsym +structures if successful, or a +.Dv NULL +pointer if an error was encountered. +.Pp +If argument +.Fa ptr +is non-null and there was no error, the library will store the +number of archive symbol entries returned into the location it +points to. +If argument +.Fa ptr +is non-null and an error was encountered, the library will +set the location pointed to by it to zero. +.Sh ERRORS +Function +.Fn elf_getarsym +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an +.Xr ar 1 +archive. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getarhdr 3 , +.Xr elf_hash 3 , +.Xr elf_memory 3 , +.Xr elf_next 3 , +.Xr elf_rand 3 diff --git a/contrib/elftoolchain/libelf/elf_getarsym.c b/contrib/elftoolchain/libelf/elf_getarsym.c new file mode 100644 index 0000000000..a65e0b74ce --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarsym.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getarsym.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Arsym * +elf_getarsym(Elf *ar, size_t *ptr) +{ + size_t n; + Elf_Arsym *symtab; + + n = 0; + symtab = NULL; + + if (ar == NULL || ar->e_kind != ELF_K_AR) + LIBELF_SET_ERROR(ARGUMENT, 0); + else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) + n = ar->e_u.e_ar.e_symtabsz; + else if (ar->e_u.e_ar.e_rawsymtab) + symtab = (ar->e_flags & LIBELF_F_AR_VARIANT_SVR4) ? + _libelf_ar_process_svr4_symtab(ar, &n) : + _libelf_ar_process_bsd_symtab(ar, &n); + else + LIBELF_SET_ERROR(ARCHIVE, 0); + + if (ptr) + *ptr = n; + return (symtab); +} diff --git a/contrib/elftoolchain/libelf/elf_getbase.3 b/contrib/elftoolchain/libelf/elf_getbase.3 new file mode 100644 index 0000000000..85d4ae1ce5 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getbase.3 @@ -0,0 +1,72 @@ +.\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getbase.3 3955 2022-03-12 12:24:36Z jkoshy $ +.\" +.Dd June 6, 2010 +.Dt ELF_GETBASE 3 +.Os +.Sh NAME +.Nm elf_getbase +.Nd get the base offset for an object file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_getbase "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_getbase +returns the file offset to the first byte of the object referenced by ELF +descriptor +.Fa elf . +.Pp +For descriptors referencing members of archives, the returned offset is +the file offset of the member in its containing archive. +For descriptors to regular objects, the returned offset is (vacuously) +zero. +.Sh RETURN VALUES +Function +.Fn elf_getbase +returns a valid file offset if successful, or +.Pq Vt off_t +.Li -1 +in case of an error. +.Sh ERRORS +Function +.Fn elf_getbase +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getarhdr 3 , +.Xr elf_getident 3 , +.Xr elf_rawfile 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getbase.c b/contrib/elftoolchain/libelf/elf_getbase.c new file mode 100644 index 0000000000..08ece9fdb2 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getbase.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getbase.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +off_t +elf_getbase(Elf *e) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return ((off_t) -1); + } + + if (e->e_parent == NULL) + return ((off_t) 0); + + return ((off_t) ((uintptr_t) e->e_rawfile - + (uintptr_t) e->e_parent->e_rawfile)); +} diff --git a/contrib/elftoolchain/libelf/elf_getdata.3 b/contrib/elftoolchain/libelf/elf_getdata.3 new file mode 100644 index 0000000000..189b9879ee --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getdata.3 @@ -0,0 +1,252 @@ +.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getdata.3 3955 2022-03-12 12:24:36Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt ELF_GETDATA 3 +.Os +.Sh NAME +.Nm elf_getdata , +.Nm elf_newdata , +.Nm elf_rawdata +.Nd iterate through or allocate section data +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Data *" +.Fn elf_getdata "Elf_Scn *scn" "Elf_Data *data" +.Ft "Elf_Data *" +.Fn elf_newdata "Elf_Scn *scn" +.Ft "Elf_Data *" +.Fn elf_rawdata "Elf_Scn *scn" "Elf_Data *data" +.Sh DESCRIPTION +These functions are used to access and manipulate data descriptors +associated with section descriptors. +Data descriptors used by the ELF library are described in +.Xr elf 3 . +.Pp +Function +.Fn elf_getdata +will return the next data descriptor associated with section descriptor +.Fa scn . +The returned data descriptor will be setup to contain translated data. +Argument +.Fa data +may be +.Dv NULL , +in which case the function returns the first data descriptor +associated with section +.Fa scn . +If argument +.Fa data +is not +.Dv NULL , +it must be a pointer to a data descriptor associated with +section descriptor +.Fa scn , +and function +.Fn elf_getdata +will return a pointer to the next data descriptor for the section, +or +.Dv NULL +when the end of the section's descriptor list is reached. +.Pp +Function +.Fn elf_newdata +will allocate a new data descriptor and append it to the list of data +descriptors associated with section descriptor +.Fa scn . +The new data descriptor will be initialized as follows: +.Bl -tag -width "d_version" -compact -offset indent +.It Va d_align +Set to 1. +.It Va d_buf +Initialized to +.Dv NULL . +.It Va d_off +Set to (off_t) -1. +This field is under application control if the +.Dv ELF_F_LAYOUT +flag was set on the ELF descriptor. +.It Va d_size +Set to zero. +.It Va d_type +Initialized to +.Dv ELF_T_BYTE . +.It Va d_version +Set to the current working version of the library, as set by +.Xr elf_version 3 . +.El +The application must set these values as appropriate before +calling +.Xr elf_update 3 . +Section +.Fa scn +must be associated with an ELF file opened for writing. +If the application has not requested full control of layout by +setting the +.Dv ELF_F_LAYOUT +flag on descriptor +.Fa elf , +then the data referenced by the returned descriptor will be positioned +after the existing content of the section, honoring the file alignment +specified in member +.Va d_align . +On successful completion of a call to +.Fn elf_newdata , +the ELF library will mark the section +.Fa scn +as +.Dq dirty . +.Pp +Function +.Fn elf_rawdata +is used to step through the data descriptors associated with +section +.Fa scn . +In contrast to function +.Fn elf_getdata , +this function returns untranslated data. +If argument +.Fa data +is +.Dv NULL , +the first data descriptor associated with section +.Fa scn +is returned. +If argument +.Fa data +is not +.Dv NULL , +is must be a data descriptor associated with +section +.Fa scn , +and function +.Fn elf_rawdata +will return the next data descriptor in the list, or +.Dv NULL +if no further descriptors are present. +Function +.Fn elf_rawdata +always returns +.Vt Elf_Data +structures of type +.Dv ELF_T_BYTE . +.Ss Special handling of zero-sized and SHT_NOBITS sections +For sections of type +.Dv SHT_NOBITS , +and for zero-sized sections, +the functions +.Fn elf_getdata +and +.Fn elf_rawdata +return a pointer to a valid +.Vt Elf_Data +structure that has its +.Va d_buf +member set to +.Dv NULL +and its +.Va d_size +member set to the size of the section. +.Pp +If an application wishes to create a section of type +.Dv SHT_NOBITS , +it should add a data buffer to the section using function +.Fn elf_newdata . +It should then set the +.Va d_buf +and +.Va d_size +members of the returned +.Vt Elf_Data +structure to +.Dv NULL +and the desired size of the section respectively. +.Sh RETURN VALUES +These functions return a valid pointer to a data descriptor if successful, or +.Dv NULL +if an error occurs. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Either of the arguments +.Fa scn +or +.Fa data +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +The data descriptor referenced by argument +.Fa data +is not associated with section descriptor +.Fa scn . +.It Bq Er ELF_E_ARGUMENT +The section denoted by argument +.Fa scn +had no data associated with it. +.It Bq Er ELF_E_DATA +Retrieval of data from the underlying object failed. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +Section +.Fa scn +had type +.Dv SHT_NULL . +.It Bq Er ELF_E_SECTION +The type of the section +.Fa scn +was not recognized by the library. +.It Bq Er ELF_E_SECTION +The size of the section +.Fa scn +is not a multiple of the file size for its section type. +.It Bq Er ELF_E_SECTION +The file offset for section +.Fa scn +is incorrect. +.It Bq Er ELF_E_UNIMPL +The section type associated with section +.Fa scn +is not supported. +.It Bq Er ELF_E_VERSION +Section +.Fa scn +was associated with an ELF object with an unsupported +version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagdata 3 , +.Xr elf_flagscn 3 , +.Xr elf_getscn 3 , +.Xr elf_getshdr 3 , +.Xr elf_newscn 3 , +.Xr elf_rawfile 3 , +.Xr elf_update 3 , +.Xr elf_version 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getident.3 b/contrib/elftoolchain/libelf/elf_getident.3 new file mode 100644 index 0000000000..9325d51774 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getident.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getident.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd July 3, 2006 +.Dt ELF_GETIDENT 3 +.Os +.Sh NAME +.Nm elf_getident +.Nd return the initial bytes of a file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft char * +.Fn elf_getident "Elf *elf" "size_t *sz" +.Sh DESCRIPTION +Function +.Fn elf_getident +returns a pointer to the initial bytes of the file for descriptor +.Fa elf . +.Pp +If argument +.Fa sz +is non-null, the size of the identification area returned is written +to the location pointed to by +.Fa sz . +This location is set to zero on errors. +.Sh RETURN VALUES +Function +.Fn elf_getident +will return a +.No non- Ns Dv NULL +pointer to the initial bytes of the file if successful, or +.Dv NULL +if an error condition is detected. +.Sh ERRORS +Function +.Fn elf_getident +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_SEQUENCE +ELF descriptor +.Fa elf +was opened for writing and function +.Fn elf_getident +was called before a call to +.Xr elf_update 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getarhdr 3 , +.Xr elf_getbase 3 , +.Xr elf_getflags 3 , +.Xr elf_kind 3 , +.Xr elf_rawfile 3 , +.Xr elf_update 3 , +.Xr gelf 3 , +.Xr gelf_getclass 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getident.c b/contrib/elftoolchain/libelf/elf_getident.c new file mode 100644 index 0000000000..d943ad39c1 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getident.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getident.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +char * +elf_getident(Elf *e, size_t *sz) +{ + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + goto error; + } + + if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + goto error; + } + + assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); + + if (sz) { + if (e->e_kind == ELF_K_AR) + *sz = SARMAG; + else if (e->e_kind == ELF_K_ELF) + *sz = EI_NIDENT; + else + *sz = (size_t) e->e_rawsize; + } + + return ((char *) e->e_rawfile); + + error: + if (sz) + *sz = 0; + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/elf_getphdrnum.3 b/contrib/elftoolchain/libelf/elf_getphdrnum.3 new file mode 100644 index 0000000000..502b3cabae --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getphdrnum.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getphdrnum.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd July 25, 2018 +.Dt ELF_GETPHDRNUM 3 +.Os +.Sh NAME +.Nm elf_getphdrnum +.Nd return the number of program headers in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getphdrnum "Elf *elf" "size_t *phnum" +.Sh DESCRIPTION +Function +.Fn elf_getphdrnum +retrieves the number of ELF program headers associated with descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa phnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects and ELF objects that use extended numbering. +.Sh RETURN VALUES +Function +.Fn elf_getphdrnum +returns a zero value if successful, or -1 in case of an error. +.Sh ERRORS +Function +.Fn elf_getphdrnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable Header. +.It Bq Er ELF_E_HEADER +The ELF Executable Header associated with argument +.Fa elf +was corrupt. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +was corrupt. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getshdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getphnum.3 b/contrib/elftoolchain/libelf/elf_getphnum.3 new file mode 100644 index 0000000000..8a1fd6a24b --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getphnum.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getphnum.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd August 5, 2009 +.Dt ELF_GETPHNUM 3 +.Os +.Sh NAME +.Nm elf_getphnum +.Nd return the number of program headers in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getphnum "Elf *elf" "size_t *phnum" +.Sh DESCRIPTION +This function is deprecated. +Please use function +.Xr elf_getphdrnum 3 +instead. +.Pp +Function +.Fn elf_getphnum +retrieves the number of ELF program headers associated with descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa phnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects and ELF objects that use extended numbering. +.Sh RETURN VALUES +Function +.Fn elf_getphnum +returns a non-zero value if successful, or zero in case of an +error. +.Sh ERRORS +Function +.Fn elf_getphnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable Header. +.It Bq Er ELF_E_HEADER +The ELF Executable Header associated with argument +.Fa elf +was corrupt. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +was corrupt. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getscn.3 b/contrib/elftoolchain/libelf/elf_getscn.3 new file mode 100644 index 0000000000..e1a2d89338 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getscn.3 @@ -0,0 +1,161 @@ +.\" Copyright (c) 2006-2008,2018 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getscn.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd September 24, 2018 +.Dt ELF_GETSCN 3 +.Os +.Sh NAME +.Nm elf_getscn , +.Nm elf_ndxscn , +.Nm elf_newscn , +.Nm elf_nextscn +.Nd get/allocate section information for an ELF object +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Scn *" +.Fn elf_getscn "Elf *elf" "size_t index" +.Ft size_t +.Fn elf_ndxscn "Elf_Scn *scn" +.Ft "Elf_Scn *" +.Fn elf_newscn "Elf *elf" +.Ft "Elf_Scn *" +.Fn elf_nextscn "Elf *elf" "Elf_Scn *scn" +.Sh DESCRIPTION +These functions are used to iterate through the sections associated +with an ELF descriptor. +.Pp +Function +.Fn elf_getscn +will return a section descriptor for the section at index +.Fa index +in the object denoted by ELF descriptor +.Fa elf . +An error will be signalled if the specified section does not +exist. +.Pp +Function +.Fn elf_ndxscn +returns the section table index associated with section descriptor +.Fa scn . +.Pp +Function +.Fn elf_newscn +creates a new section and appends it to the list of sections +associated with descriptor +.Fa elf . +The library will automatically increment the +.Va e_shnum +field of the ELF header associated with descriptor +.Fa elf , +and will set the +.Dv ELF_F_DIRTY +flag on the returned section descriptor. +For ELF descriptors opened for writing, the ELF library will +automatically create an empty section at index zero +.Dv ( SHN_UNDEF ) +on the first call to +.Fn elf_newscn . +.Pp +Function +.Fn elf_nextscn +takes a section descriptor +.Fa scn +and returns a pointer to the section descriptor at the next higher +index. +As a consequence, +.Fn elf_nextscn +will never return a pointer to the empty section at index zero +.Dv ( SHN_UNDEF ) . +Argument +.Fa scn +is allowed to be +.Dv NULL , +in which case this function will return a pointer to the section +descriptor at index 1. +If no further sections are present, function +.Fn elf_nextscn +will return a +.Dv NULL +pointer. +.Sh RETURN VALUES +Functions +.Fn elf_getscn , +.Fn elf_newscn +and +.Fn elf_nextscn +return a valid pointer to a section descriptor if successful, or +.Dv NULL +if an error occurs. +.Pp +Function +.Fn elf_ndxscn +returns a valid section table index if successful, or +.Dv SHN_UNDEF +if an error occurs. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa elf +or +.Fa scn +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa index +exceeded the current number of sections in the ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Section descriptor +.Fa scn +was not associated with ELF descriptor +.Fa elf . +.It Bq Er ELF_E_CLASS +Descriptor +.Fa elf +was of an unknown ELF class. +.It Bq Er ELF_E_SECTION +Argument +.Fa elf +specified extended section numbering in the ELF header with the section header at +index +.Dv SHN_UNDEF +not being of type +.Dv SHT_NULL . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagdata 3 , +.Xr elf_flagscn 3 , +.Xr elf_getdata 3 , +.Xr elf_getshdr 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getshdrnum.3 b/contrib/elftoolchain/libelf/elf_getshdrnum.3 new file mode 100644 index 0000000000..21aeca80ef --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshdrnum.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getshdrnum.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd August 4, 2009 +.Dt ELF_GETSHDRNUM 3 +.Os +.Sh NAME +.Nm elf_getshdrnum +.Nd return the number of sections in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshdrnum "Elf *elf" "size_t *shnum" +.Sh DESCRIPTION +Function +.Fn elf_getshdrnum +retrieves the number of ELF sections associated with descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa shnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects, and ELF objects that use extended section numbering. +.Sh RETURN VALUES +Function +.Fn elf_getshdrnum +returns zero value if successful, or -1 in case of an error. +.Sh ERRORS +Function +.Fn elf_getshdrnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable header. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 b/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 new file mode 100644 index 0000000000..747b8ce08f --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 @@ -0,0 +1,80 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getshdrstrndx.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd August 5, 2009 +.Dt ELF_GETSHDRSTRNDX 3 +.Os +.Sh NAME +.Nm elf_getshdrstrndx +.Nd retrieve the index of the section name string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshdrstrndx "Elf *elf" "size_t *ndxptr" +.Sh DESCRIPTION +Function +.Fn elf_getshdrstrndx +retrieves the section index of the string table containing section +names from descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa ndxptr . +.Pp +This function allow applications to process both normal ELF +objects and ELF objects that use extended section numbering uniformly. +.Sh RETURN VALUES +These functions return zero if successful, or -1 in case of an error. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable header. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +contained a value in the reserved range of section indices. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshnum.3 b/contrib/elftoolchain/libelf/elf_getshnum.3 new file mode 100644 index 0000000000..7bd53fad68 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshnum.3 @@ -0,0 +1,85 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getshnum.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd August 5, 2009 +.Dt ELF_GETSHNUM 3 +.Os +.Sh NAME +.Nm elf_getshnum +.Nd return the number of sections in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshnum "Elf *elf" "size_t *shnum" +.Sh DESCRIPTION +This function is deprecated. +Please use +.Xr elf_getshdrnum 3 +instead. +.Pp +Function +.Fn elf_getshnum +retrieves the number of ELF sections associated with descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa shnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects, and ELF objects that use extended section numbering. +.Sh RETURN VALUES +Function +.Fn elf_getshnum +returns a non-zero value if successful, or zero in case of an +error. +.Sh ERRORS +Function +.Fn elf_getshnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable header. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshstrndx.3 b/contrib/elftoolchain/libelf/elf_getshstrndx.3 new file mode 100644 index 0000000000..1f5089e1e7 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshstrndx.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_getshstrndx.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd July 25, 2018 +.Dt ELF_GETSHSTRNDX 3 +.Os +.Sh NAME +.Nm elf_getshstrndx , +.Nm elf_setshstrndx +.Nd retrieve/update the index of the section name string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshstrndx "Elf *elf" "size_t *ndxptr" +.Ft int +.Fn elf_setshstrndx "Elf *elf" "size_t ndx" +.Sh DESCRIPTION +Function +.Fn elf_getshstrndx +is deprecated. +Please use +.Xr elf_getshdrstrndx 3 +instead. +.Pp +Function +.Fn elf_getshstrndx +retrieves the section index of the string table containing section +names from descriptor +.Fa elf +and stores it into the location pointed to by argument +.Fa ndxptr . +.Pp +Function +.Fn elf_setshstrndx +sets the index of the section name string table to argument +.Fa ndx . +.Pp +These routines allow applications to process both normal ELF +objects and ELF objects that use extended section numbering uniformly. +.Sh RETURN VALUES +These functions return a non-zero value if successful, or zero in case +of an error. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was passed in for argument +.Fa elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +lacks an ELF Executable header. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +contained a value in the reserved range of section indices. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getversion.3 b/contrib/elftoolchain/libelf/elf_getversion.3 new file mode 100644 index 0000000000..9f031309e4 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getversion.3 @@ -0,0 +1,91 @@ +.\" Copyright (c) 2021 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +.\" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +.\" OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: elf_getversion.3 3956 2022-03-12 12:39:30Z jkoshy $ +.\" +.Dd March 7, 2021 +.Dt ELF_GETVERSION 3 +.Os +.Sh NAME +.Nm elf_getversion +.Nd retrieve the operating version for an ELF object +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft unsigned int +.Fn elf_getversion "Elf *elf" +.Sh DESCRIPTION +.Em Important : +The function +.Fn elf_getversion +is an extension to the +.Xr ELF 3 +API. +Applications that need to be portable to other implementations of +.Li libelf +should take care not to use this function. +.Pp +The function +.Fn elf_getversion +returns the operating version for the ELF descriptor pointed to by +argument +.Fa elf . +.Pp +This descriptor must have been allocated by a previous call to one of +the functions that return an ELF descriptor, such as +.Xr elf_begin 3 , +.Xr elf_memory 3 , +.Xr elf_open 3 +and +.Xr elf_openmemory 3 . +The object associated with the descriptor +.Fa elf +should be an ELF object. +.Sh RETURN VALUES +The function returns the operating version for the ELF object if +successful or +.Dv EV_NONE +if an error occurred. +.Sh COMPATIBILITY +This function is an extension to the +.Xr ELF 3 +API set. +.Sh ERRORS +This function can fail with the following errors: +.Bl -tag -width "[ELF_E_ARGUMENT]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +The underlying object referenced by the descriptor +.Fa elf +was not an ELF object. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_errno 3 , +.Xr elf_version 3 diff --git a/contrib/elftoolchain/libelf/elf_getversion.c b/contrib/elftoolchain/libelf/elf_getversion.c new file mode 100644 index 0000000000..b32a2fa068 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getversion.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2021 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getversion.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +unsigned int +elf_getversion(Elf *e) +{ + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (EV_NONE); + } + + return (e->e_version); +} diff --git a/contrib/elftoolchain/libelf/elf_hash.3 b/contrib/elftoolchain/libelf/elf_hash.3 new file mode 100644 index 0000000000..f2d39f9338 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_hash.3 @@ -0,0 +1,57 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_hash.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd August 15, 2006 +.Dt ELF_HASH 3 +.Os +.Sh NAME +.Nm elf_hash +.Nd compute a hash value for a string +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "unsigned long" +.Fn elf_hash "const char *name" +.Sh DESCRIPTION +Function +.Fn elf_hash +computes a portable hash value for the null terminated string +pointed to by argument +.Fa name . +.Pp +The hash value returned is will be identical across +machines of different architectures. +This allows hash tables to be built on one machine and +correctly used on another of a different architecture. +The hash value returned is also guaranteed +.Em not +to be the bit pattern of all ones (~0UL). +.Sh IMPLEMENTATION NOTES +The library internally uses unsigned 32 bit arithmetic to compute +the hash value. +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_hash.c b/contrib/elftoolchain/libelf/elf_hash.c new file mode 100644 index 0000000000..a6a585414a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_hash.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_hash.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * This elf_hash function is defined by the System V ABI. + */ + +unsigned long +elf_hash(const char *name) +{ + unsigned long h, t; + const unsigned char *s; + + s = (const unsigned char *) name; + h = t = 0; + + for (; *s != '\0'; h = h & ~t) { + h = (h << 4) + *s++; + t = h & 0xF0000000UL; + if (t) + h ^= t >> 24; + } + + return (h); +} diff --git a/contrib/elftoolchain/libelf/elf_kind.3 b/contrib/elftoolchain/libelf/elf_kind.3 new file mode 100644 index 0000000000..7c24b7e11c --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_kind.3 @@ -0,0 +1,74 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_kind.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd June 1, 2006 +.Dt ELF_KIND 3 +.Os +.Sh NAME +.Nm elf_kind +.Nd determine ELF file type +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft Elf_Kind +.Fn elf_kind "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_kind +function identifies the kind of file associated with its argument +.Fa elf . +The argument +.Fa elf +is allowed to be +.Dv NULL . +.Sh RETURN VALUES +The +.Fn elf_kind +function returns one of the following values: +.Bl -tag -width indent +.It Dv ELF_K_AR +The file associated with argument +.Fa elf +is an archive. +.It Dv ELF_K_ELF +The file associated with argument +.Fa elf +is an ELF file. +.It Dv ELF_K_NONE +The argument +.Fa elf +was +.Dv NULL , +or the ELF library could not determine the type of the file +associated with argument +.Fa elf , +or an error occurred when processing. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getident 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_kind.c b/contrib/elftoolchain/libelf/elf_kind.c new file mode 100644 index 0000000000..0cdf8214b0 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_kind.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_kind.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Kind +elf_kind(Elf *e) +{ + if (e == NULL) + return (ELF_K_NONE); + if (e->e_kind == ELF_K_AR || + e->e_kind == ELF_K_ELF) + return (e->e_kind); + return (ELF_K_NONE); +} diff --git a/contrib/elftoolchain/libelf/elf_memory.3 b/contrib/elftoolchain/libelf/elf_memory.3 new file mode 100644 index 0000000000..0afae83a85 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_memory.3 @@ -0,0 +1,126 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_memory.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd June 28, 2006 +.Dt ELF_MEMORY 3 +.Os +.Sh NAME +.Nm elf_memory +.Nd process an ELF or ar(1) archive mapped into memory +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_memory "char *image" "size_t size" +.Sh DESCRIPTION +Function +.Fn elf_memory +is used to process an ELF file or +.Xr ar 1 +archive whose image is present in memory. +.Pp +Argument +.Fa image +points to the start of the memory image of the file or archive. +Argument +.Fa size +contains the size in bytes of the memory image. +.Pp +The ELF descriptor is created for reading (i.e., analogous to the +use of +.Xr elf_begin 3 +with a command argument value of +.Dv ELF_C_READ Ns ). +.Sh RETURN VALUES +Function +.Fn elf_memory +returns a pointer to a new ELF descriptor if successful, or +.Dv NULL +if an +error occurred. +.Pp +The return value may be queried for the file type using +.Xr elf_kind 3 . +.Sh EXAMPLES +To read parse an elf file, use: +.Bd -literal -offset indent +int fd; +void *p; +struct stat sb; +Elf *e; +\&... +if ((fd = open("./elf-file", O_RDONLY)) < 0 || + fstat(fd, &sb) < 0 || + (p = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == + MAP_FAILED) { + ... handle system error ... +} + +if ((e = elf_memory(p, sb.st_size)) == NULL) { + ... handle elf(3) error ... +} +\&... use ELF descriptor "e" here ... +.Ed +.Sh ERRORS +Function +.Fn elf_memory +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A +.Dv NULL +value was used for argument +.Fa image +or the value of argument +.Fa sz +was zero. +.It Bq Er ELF_E_HEADER +The header of the ELF object contained an unsupported value in its +.Va e_ident[EI_CLASS] +field. +.It Bq Er ELF_E_HEADER +The header of the ELF object contained an unsupported value in its +.Va e_ident[EI_DATA] +field. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_memory +was called before a working version was set using +.Xr elf_version 3 . +.It Bq Er ELF_E_VERSION +The ELF object referenced by argument +.Fa image +was of an unsupported ELF version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_errno 3 , +.Xr elf_kind 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_memory.c b/contrib/elftoolchain/libelf/elf_memory.c new file mode 100644 index 0000000000..9f677d63f1 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_memory.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_memory.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf * +elf_memory(char *image, size_t sz) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + if (image == NULL || sz == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (_libelf_memory((unsigned char *) image, sz, 1)); +} diff --git a/contrib/elftoolchain/libelf/elf_next.3 b/contrib/elftoolchain/libelf/elf_next.3 new file mode 100644 index 0000000000..f61ad7998e --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_next.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_next.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd February 27, 2019 +.Dt ELF_NEXT 3 +.Os +.Sh NAME +.Nm elf_next +.Nd provide sequential access to the next archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft Elf_Cmd +.Fn elf_next "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_next +function causes the ELF archive descriptor corresponding to argument +.Fa elf +to be adjusted to provide access to the next member in +the archive on a subsequent call to +.Fn elf_begin . +.Pp +The return value of +.Fn elf_next +is suitable for use in a loop invoking +.Fn elf_begin . +.Sh RETURN VALUES +If successful, function +.Fn elf_next +returns the value +.Dv ELF_C_READ . +Otherwise, if argument +.Fa elf +was not associated with an archive, or if it was +.Dv NULL , +or if any other error occurred, the value +.Dv ELF_C_NULL +is returned. +.Sh EXAMPLES +To process all the members of an archive use: +.Bd -literal -offset indent +Elf_Cmd cmd; +Elf *archive, *e; +\&... +cmd = ELF_C_READ; +archive = elf_begin(fd, cmd, NULL); +while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) +{ + ... process `e' here ... + + cmd = elf_next(e); + elf_end(e); +} +elf_end(archive); +.Ed +.Sh ERRORS +Function +.Fn elf_next +may fail with the following error: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not associated with a containing +.Xr ar 1 +archive. +.It Bq Er ELF_E_ARGUMENT +An error was encountered while parsing the archive containing argument +.Fa elf . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_rand 3 diff --git a/contrib/elftoolchain/libelf/elf_next.c b/contrib/elftoolchain/libelf/elf_next.c new file mode 100644 index 0000000000..957a14bf8d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_next.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_next.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Cmd +elf_next(Elf *e) +{ + off_t next; + Elf *parent; + + if (e == NULL) + return (ELF_C_NULL); + + if ((parent = e->e_parent) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (ELF_C_NULL); + } + + assert(parent->e_kind == ELF_K_AR); + assert(parent->e_cmd == ELF_C_READ); + assert(e->e_rawfile > parent->e_rawfile); + + next = e->e_rawfile - parent->e_rawfile + (off_t) e->e_rawsize; + next = (next + 1) & ~1; /* round up to an even boundary */ + + /* + * Setup the 'e_next' field of the archive descriptor for the + * next call to 'elf_begin()'. + */ + parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? + (off_t) 0 : next; + + /* + * Return an error if the 'e_next' field falls outside the current + * file. + * + * This check is performed after updating the parent descriptor's + * 'e_next' field so that the next call to elf_begin(3) will terminate + * traversal of a too-small archive even if client code forgets to + * check the return value from elf_next(3). + */ + if (next > (off_t) parent->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (ELF_C_NULL); + } + + return (ELF_C_READ); +} diff --git a/contrib/elftoolchain/libelf/elf_open.3 b/contrib/elftoolchain/libelf/elf_open.3 new file mode 100644 index 0000000000..ce94e40c1a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_open.3 @@ -0,0 +1,127 @@ +.\" Copyright (c) 2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_open.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd June 12, 2019 +.Dt ELF_OPEN 3 +.Os +.Sh NAME +.Nm elf_open +.Nd open ELF objects and ar(1) archives +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_open "int fd" +.Ft "Elf *" +.Fn elf_openmemory "char *image" "size_t sz" +.Sh DESCRIPTION +.Em Important : +The functions +.Fn elf_open +and +.Fn elf_openmemory +are extensions to the +.Xr elf 3 +API, for the internal use of the +Elftoolchain project. +Portable applications should not use these functions. +.Pp +The function +.Fn elf_open +returns an Elf descriptor opened with mode +.Dv ELF_C_READ +for the ELF object or +.Xr ar 1 +archive referenced by the file descriptor in argument +.Fa fd . +.Pp +The function +.Fn elf_openmemory +returns an ELF descriptor opened with mode +.Dv ELF_C_READ +for the ELF object or +.Xr ar 1 +archive contained in the memory area pointed to by the argument +.Fa image . +The argument +.Fa sz +specifies the size of the memory area in bytes. +.Sh RETURN VALUES +The function returns a pointer to a ELF descriptor if successful, or +.Dv NULL +if an error occurred. +.Sh COMPATIBILITY +These functions are non-standard extensions to the +.Xr elf 3 +API set. +.Pp +The behavior of these functions differs from their counterparts +.Xr elf_begin 3 +and +.Xr elf_memory 3 +in that these functions will successfully open malformed ELF objects +and +.Xr ar 1 +archives, returning an Elf descriptor of type +.Dv ELF_K_NONE . +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa fd +was of an unsupported file type. +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa sz +was zero, or the argument +.Fa image +was +.Dv NULL . +.It Bq Er ELF_E_IO +The file descriptor in argument +.Fa fd +was invalid. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Fa fd +could not be read. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was encountered. +.It Bq Er ELF_E_SEQUENCE +Functions +.Fn elf_open +or +.Fn elf_openmemory +was called before a working version was established with +.Xr elf_version 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_errno 3 , +.Xr elf_memory 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_open.c b/contrib/elftoolchain/libelf/elf_open.c new file mode 100644 index 0000000000..57a814f124 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_open.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_open.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Extension API: open a file for reading, ignoring parse errors. + */ + +Elf * +elf_open(int fd) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + return (_libelf_open_object(fd, ELF_C_READ, 0)); +} + +/* + * Extension API: create an ELF descriptor for an in-memory object, + * ignoring parse errors. + */ + +Elf * +elf_openmemory(char *image, size_t sz) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + if (image == NULL || sz == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (_libelf_memory((unsigned char *) image, sz, 0)); +} diff --git a/contrib/elftoolchain/libelf/elf_phnum.c b/contrib/elftoolchain/libelf/elf_phnum.c new file mode 100644 index 0000000000..9dcee5a5ef --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_phnum.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_phnum.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +static int +_libelf_getphdrnum(Elf *e, size_t *phnum) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *phnum = e->e_u.e_elf.e_nphdr; + + return (0); +} + +int +elf_getphdrnum(Elf *e, size_t *phnum) +{ + return (_libelf_getphdrnum(e, phnum)); +} + +/* Deprecated API */ +int +elf_getphnum(Elf *e, size_t *phnum) +{ + return (_libelf_getphdrnum(e, phnum) >= 0); +} diff --git a/contrib/elftoolchain/libelf/elf_rand.3 b/contrib/elftoolchain/libelf/elf_rand.3 new file mode 100644 index 0000000000..e7e7429cb0 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rand.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_rand.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd June 17, 2006 +.Dt ELF_RAND 3 +.Os +.Sh NAME +.Nm elf_rand +.Nd provide sequential access to the next archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_rand "Elf *archive" "off_t offset" +.Sh DESCRIPTION +The +.Fn elf_rand +function causes the ELF descriptor +.Fa archive +to be adjusted so that the next call to +.Xr elf_begin 3 +will provide access to the archive member at byte offset +.Fa offset +in the archive. +Argument +.Fa offset +is the byte offset from the start of the archive to the beginning of +the archive header for the desired member. +.Pp +Archive member offsets may be retrieved using the +.Xr elf_getarsym 3 +function. +.Sh RETURN VALUES +Function +.Fn elf_rand +returns +.Fa offset +if successful or zero in case of an error. +.Sh EXAMPLES +To process all the members of an archive use: +.Bd -literal -offset indent +off_t off; +Elf *archive, *e; +\&... +cmd = ELF_C_READ; +archive = elf_begin(fd, cmd, NULL); +while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) +{ + ... process `e' here ... + elf_end(e); + + off = ...new value...; + if (elf_rand(archive, off) != off) { + ... process error ... + } +} +elf_end(archive); +.Ed +.Pp +To rewind an archive, use: +.Bd -literal -offset indent +Elf *archive; +\&... +if (elf_rand(archive, SARMAG) != SARMAG) { + ... error ... +} +.Ed +.Sh ERRORS +Function +.Fn elf_rand +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa archive +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa archive +was not a descriptor for an +.Xr ar 1 +archive. +.It Bq Er ELF_E_ARCHIVE +Argument +.Fa offset +did not correspond to the start of an archive member header. +.El +.Sh SEE ALSO +.Xr ar 1 , +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_getarsym 3 , +.Xr elf_next 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_rand.c b/contrib/elftoolchain/libelf/elf_rand.c new file mode 100644 index 0000000000..72c5563da7 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rand.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_rand.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +off_t +elf_rand(Elf *ar, off_t offset) +{ + struct ar_hdr *arh; + off_t offset_of_member; + + if (ar == NULL || ar->e_kind != ELF_K_AR || + (offset & 1) || offset < SARMAG || + offset >= ar->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return 0; + } + + offset_of_member = offset + (off_t) sizeof(struct ar_hdr); + + if (offset_of_member <= 0 || /* Numeric overflow. */ + offset_of_member >= ar->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return 0; + } + + arh = (struct ar_hdr *) (ar->e_rawfile + offset); + + /* a too simple sanity check */ + if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { + LIBELF_SET_ERROR(ARCHIVE, 0); + return 0; + } + + ar->e_u.e_ar.e_next = offset; + + return (offset); +} diff --git a/contrib/elftoolchain/libelf/elf_rawfile.3 b/contrib/elftoolchain/libelf/elf_rawfile.3 new file mode 100644 index 0000000000..66371f9198 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rawfile.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_rawfile.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd July 3, 2006 +.Dt ELF_RAWFILE 3 +.Os +.Sh NAME +.Nm elf_rawfile +.Nd return uninterpreted contents of an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft char * +.Fn elf_rawfile "Elf *elf" "size_t *sz" +.Sh DESCRIPTION +Function +.Fn elf_rawfile +returns the uninterpreted contents of the file referenced by ELF descriptor +.Fa elf . +.Pp +If argument +.Fa sz +is non-null, the function stores the file's size in bytes +in the location to which it points. +A value of zero is written to this location if an error is +encountered. +.Sh RETURN VALUES +Function +.Fn elf_rawfile +returns a valid pointer if successful or +.Dv NULL +if an error occurs. +.Sh ERRORS +Function +.Fn elf_rawfile +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_SEQUENCE +Argument +.Fa elf +was opened for writing and function +.Fn elf_rawfile +was invoked before +.Xr elf_update 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getident 3 , +.Xr elf_kind 3 , +.Xr elf_update 3 diff --git a/contrib/elftoolchain/libelf/elf_rawfile.c b/contrib/elftoolchain/libelf/elf_rawfile.c new file mode 100644 index 0000000000..76632ff647 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rawfile.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_rawfile.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +char * +elf_rawfile(Elf *e, size_t *sz) +{ + unsigned char *ptr; + + ptr = NULL; + + if (e == NULL) + LIBELF_SET_ERROR(ARGUMENT, 0); + else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) + LIBELF_SET_ERROR(SEQUENCE, 0); + + if (sz) + *sz = e ? (size_t) e->e_rawsize : 0; + + return ((char *) ptr); +} diff --git a/contrib/elftoolchain/libelf/elf_scn.c b/contrib/elftoolchain/libelf/elf_scn.c new file mode 100644 index 0000000000..0a25890a60 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_scn.c @@ -0,0 +1,239 @@ +/*- + * Copyright (c) 2006,2008-2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_scn.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Load an ELF section table and create a list of Elf_Scn structures. + */ +int +_libelf_load_section_headers(Elf *e, void *ehdr) +{ + Elf_Scn *scn; + uint64_t shoff; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + int ec, swapbytes; + unsigned char *src; + size_t fsz, i, shnum; + _libelf_translator_function *xlator; + + assert(e != NULL); + assert(ehdr != NULL); + assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); + +#define CHECK_EHDR(E,EH) do { \ + uintmax_t rawsize = (uintmax_t) e->e_rawsize; \ + if (shoff > (uintmax_t) e->e_rawsize || \ + fsz != (EH)->e_shentsize || \ + shnum > SIZE_MAX / fsz || \ + fsz * shnum > rawsize - shoff) { \ + LIBELF_SET_ERROR(HEADER, 0); \ + return (0); \ + } \ + } while (/* CONSTCOND */ 0) + + ec = e->e_class; + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); + assert(fsz > 0); + + shnum = e->e_u.e_elf.e_nscn; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + shoff = (uint64_t) eh32->e_shoff; + CHECK_EHDR(e, eh32); + } else { + eh64 = (Elf64_Ehdr *) ehdr; + shoff = eh64->e_shoff; + CHECK_EHDR(e, eh64); + } + + xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); + + swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); + src = e->e_rawfile + shoff; + + /* + * If the file is using extended numbering then section #0 + * would have already been read in. + */ + + i = 0; + if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { + assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == + STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); + + i = 1; + src += fsz; + } + + for (; i < shnum; i++, src += fsz) { + if ((scn = _libelf_allocate_scn(e, i)) == NULL) + return (0); + + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + src, (size_t) 1, swapbytes); + + if (ec == ELFCLASS32) { + scn->s_offset = scn->s_rawoff = + scn->s_shdr.s_shdr32.sh_offset; + scn->s_size = scn->s_shdr.s_shdr32.sh_size; + } else { + scn->s_offset = scn->s_rawoff = + scn->s_shdr.s_shdr64.sh_offset; + scn->s_size = scn->s_shdr.s_shdr64.sh_size; + } + } + + e->e_flags |= LIBELF_F_SHDRS_LOADED; + + return (1); +} + + +Elf_Scn * +elf_getscn(Elf *e, size_t index) +{ + int ec; + void *ehdr; + Elf_Scn *s; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return (NULL); + + STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) + if (s->s_ndx == index) + return (s); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +size_t +elf_ndxscn(Elf_Scn *s) +{ + if (s == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (SHN_UNDEF); + } + return (s->s_ndx); +} + +Elf_Scn * +elf_newscn(Elf *e) +{ + int ec; + void *ehdr; + Elf_Scn *scn; + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + /* + * The application may be asking for a new section descriptor + * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We + * need to bring in the existing section information before + * appending a new one to the list. + * + * Per the ELF(3) API, an application is allowed to open a + * file using ELF_C_READ, mess with its internal structure and + * use elf_update(...,ELF_C_NULL) to compute its new layout. + */ + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return (NULL); + + if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { + assert(e->e_u.e_elf.e_nscn == 0); + if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == + NULL) + return (NULL); + e->e_u.e_elf.e_nscn++; + } + + assert(e->e_u.e_elf.e_nscn > 0); + + if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) + return (NULL); + + e->e_u.e_elf.e_nscn++; + + (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); + + return (scn); +} + +Elf_Scn * +elf_nextscn(Elf *e, Elf_Scn *s) +{ + if (e == NULL || (e->e_kind != ELF_K_ELF) || + (s && s->s_elf != e)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (s == NULL ? elf_getscn(e, (size_t) 1) : + STAILQ_NEXT(s, s_next)); +} diff --git a/contrib/elftoolchain/libelf/elf_shnum.c b/contrib/elftoolchain/libelf/elf_shnum.c new file mode 100644 index 0000000000..2980a3ff58 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_shnum.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_shnum.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +static int +_libelf_getshdrnum(Elf *e, size_t *shnum) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *shnum = e->e_u.e_elf.e_nscn; + + return (0); +} + +int +elf_getshdrnum(Elf *e, size_t *shnum) +{ + return (_libelf_getshdrnum(e, shnum)); +} + +/* Deprecated API. */ +int +elf_getshnum(Elf *e, size_t *shnum) +{ + return (_libelf_getshdrnum(e, shnum) >= 0); +} diff --git a/contrib/elftoolchain/libelf/elf_shstrndx.c b/contrib/elftoolchain/libelf/elf_shstrndx.c new file mode 100644 index 0000000000..5dd0393841 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_shstrndx.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_shstrndx.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +static int +_libelf_getshdrstrndx(Elf *e, size_t *strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *strndx = e->e_u.e_elf.e_strndx; + + return (0); +} + +int +elf_getshdrstrndx(Elf *e, size_t *strndx) +{ + return (_libelf_getshdrstrndx(e, strndx)); +} + +int +elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ +{ + return (_libelf_getshdrstrndx(e, strndx) >= 0); +} + +int +elf_setshstrndx(Elf *e, size_t strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + return (_libelf_setshstrndx(e, eh, ec, strndx)); +} diff --git a/contrib/elftoolchain/libelf/elf_strptr.3 b/contrib/elftoolchain/libelf/elf_strptr.3 new file mode 100644 index 0000000000..7bcb10c22b --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_strptr.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_strptr.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd December 16, 2006 +.Dt ELF_STRPTR 3 +.Os +.Sh NAME +.Nm elf_strptr +.Nd retrieve a string pointer in a string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "char *" +.Fn elf_strptr "Elf *elf" "size_t scndx" "size_t stroffset" +.Sh DESCRIPTION +Function +.Fn elf_strptr +allows an application to convert a string table offset to a string +pointer, correctly translating the offset in the presence +of multiple +.Vt Elf_Data +descriptors covering the contents of the section. +.Pp +Argument +.Fa elf +is a descriptor for an ELF object. +Argument +.Fa scndx +is the section index for an ELF string table. +Argument +.Fa stroffset +is the index of the desired string in the string +table. +.Sh RETURN VALUES +Function +.Fn elf_strptr +returns a valid pointer on success or +.Dv NULL +in case an error was encountered. +.Sh ERRORS +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa scndx +was not the section index for a string table. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa stroffset +exceeded the size of the string table. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa stroffset +index an unallocated region of the string table. +.It Bq Er ELF_E_DATA +Offset +.Fa stroffset +indexed a region that was not covered by any Elf_Data +descriptor. +.It Bq Er ELF_E_DATA +An erroneous +.Vt Elf_Data +descriptor was part of the section specified by argument +.Fa scndx . +.It Bq Er ELF_E_HEADER +ELF descriptor +.Fa elf +contained an invalid section header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +Section +.Fa scndx +contained a malformed section header. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Fa elf +did not adhere to the conventions used for extended numbering. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getshdr 3 , +.Xr elf64_getshdr 3 , +.Xr elf_getdata 3 , +.Xr elf_rawdata 3 , +.Xr gelf 3 , +.Xr gelf_getshdr 3 diff --git a/contrib/elftoolchain/libelf/elf_strptr.c b/contrib/elftoolchain/libelf/elf_strptr.c new file mode 100644 index 0000000000..e88cf04f36 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_strptr.c @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ +#include + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_strptr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Convert an ELF section#,offset pair to a string pointer. + */ + +char * +elf_strptr(Elf *e, size_t scndx, size_t offset) +{ + Elf_Scn *s; + Elf_Data *d; + GElf_Shdr shdr; + uint64_t alignment, count; + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((s = elf_getscn(e, scndx)) == NULL || + gelf_getshdr(s, &shdr) == NULL) + return (NULL); + + if (shdr.sh_type != SHT_STRTAB || + offset >= shdr.sh_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + d = NULL; + if (e->e_flags & ELF_F_LAYOUT) { + + /* + * The application is taking responsibility for the + * ELF object's layout, so we can directly translate + * an offset to a `char *' address using the `d_off' + * members of Elf_Data descriptors. + */ + while ((d = elf_getdata(s, d)) != NULL) { + + if (d->d_buf == 0 || d->d_size == 0) + continue; + + if (d->d_type != ELF_T_BYTE) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if (offset >= d->d_off && + offset < d->d_off + d->d_size) + return ((char *) d->d_buf + offset - d->d_off); + } + } else { + /* + * Otherwise, the `d_off' members are not useable and + * we need to compute offsets ourselves, taking into + * account 'holes' in coverage of the section introduced + * by alignment requirements. + */ + count = (uint64_t) 0; /* cumulative count of bytes seen */ + while ((d = elf_getdata(s, d)) != NULL && count <= offset) { + + if (d->d_buf == NULL || d->d_size == 0) + continue; + + if (d->d_type != ELF_T_BYTE) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((alignment = d->d_align) > 1) { + if ((alignment & (alignment - 1)) != 0) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + count = roundup2(count, alignment); + } + + if (offset < count) { + /* offset starts in the 'hole' */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (offset < count + d->d_size) { + if (d->d_buf != NULL) + return ((char *) d->d_buf + + offset - count); + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + count += d->d_size; + } + } + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/elf_types.m4 b/contrib/elftoolchain/libelf/elf_types.m4 new file mode 100644 index 0000000000..9e9680d9b8 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_types.m4 @@ -0,0 +1,309 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ + */ + +/* + * ELF types, defined in the "enum Elf_Type" API. + * + * The members of the list form a 2-tuple: (name, C-type-suffix). + * + `name' is an Elf_Type symbol without the `ELF_T_' prefix. + * + `C-type-suffix' is the suffix for Elf32_ and Elf64_ type names. + */ + +define(`ELF_TYPE_LIST', + ``ADDR, Addr', + `BYTE, Byte', + `CAP, Cap', + `DYN, Dyn', + `EHDR, Ehdr', + `GNUHASH, -', + `HALF, Half', + `LWORD, Lword', + `MOVE, Move', + `MOVEP, MoveP', + `NOTE, Note', + `OFF, Off', + `PHDR, Phdr', + `REL, Rel', + `RELA, Rela', + `SHDR, Shdr', + `SWORD, Sword', + `SXWORD, Sxword', + `SYMINFO, Syminfo', + `SYM, Sym', + `VDEF, Verdef', + `VNEED, Verneed', + `WORD, Word', + `XWORD, Xword', + `NUM, _'') + +/* + * DEFINE_STRUCT(NAME,MEMBERLIST...) + * + * Map a type name to its members. + * + * Each member-list element comprises of pairs of (field name, type), + * in the sequence used in the file representation of `NAME'. + * + * Each member list element comprises a pair containing a field name + * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, + * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. + * + * The last element of a member list is the null element: `_,_'. + */ + +define(`DEFINE_STRUCT',`define(`$1_DEF',shift($@))dnl') + +DEFINE_STRUCT(`Elf32_Cap', + ``c_tag, WORD', + `c_un.c_val, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Cap', + ``c_tag, XWORD', + `c_un.c_val, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Dyn', + ``d_tag, SWORD', + `d_un.d_ptr, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Dyn', + ``d_tag, SXWORD', + `d_un.d_ptr, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Ehdr', + ``e_ident, IDENT', + `e_type, HALF', + `e_machine, HALF', + `e_version, WORD', + `e_entry, ADDR', + `e_phoff, OFF', + `e_shoff, OFF', + `e_flags, WORD', + `e_ehsize, HALF', + `e_phentsize, HALF', + `e_phnum, HALF', + `e_shentsize, HALF', + `e_shnum, HALF', + `e_shstrndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Ehdr', + ``e_ident, IDENT', + `e_type, HALF', + `e_machine, HALF', + `e_version, WORD', + `e_entry, ADDR', + `e_phoff, OFF', + `e_shoff, OFF', + `e_flags, WORD', + `e_ehsize, HALF', + `e_phentsize, HALF', + `e_phnum, HALF', + `e_shentsize, HALF', + `e_shnum, HALF', + `e_shstrndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Move', + ``m_value, LWORD', + `m_info, WORD', + `m_poffset, WORD', + `m_repeat, HALF', + `m_stride, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Move', + ``m_value, LWORD', + `m_info, XWORD', + `m_poffset, XWORD', + `m_repeat, HALF', + `m_stride, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Phdr', + ``p_type, WORD', + `p_offset, OFF', + `p_vaddr, ADDR', + `p_paddr, ADDR', + `p_filesz, WORD', + `p_memsz, WORD', + `p_flags, WORD', + `p_align, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Phdr', + ``p_type, WORD', + `p_flags, WORD', + `p_offset, OFF', + `p_vaddr, ADDR', + `p_paddr, ADDR', + `p_filesz, XWORD', + `p_memsz, XWORD', + `p_align, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Rel', + ``r_offset, ADDR', + `r_info, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Rel', + ``r_offset, ADDR', + `r_info, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Rela', + ``r_offset, ADDR', + `r_info, WORD', + `r_addend, SWORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Rela', + ``r_offset, ADDR', + `r_info, XWORD', + `r_addend, SXWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Shdr', + ``sh_name, WORD', + `sh_type, WORD', + `sh_flags, WORD', + `sh_addr, ADDR', + `sh_offset, OFF', + `sh_size, WORD', + `sh_link, WORD', + `sh_info, WORD', + `sh_addralign, WORD', + `sh_entsize, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Shdr', + ``sh_name, WORD', + `sh_type, WORD', + `sh_flags, XWORD', + `sh_addr, ADDR', + `sh_offset, OFF', + `sh_size, XWORD', + `sh_link, WORD', + `sh_info, WORD', + `sh_addralign, XWORD', + `sh_entsize, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Sym', + ``st_name, WORD', + `st_value, ADDR', + `st_size, WORD', + `st_info, BYTE', + `st_other, BYTE', + `st_shndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Sym', + ``st_name, WORD', + `st_info, BYTE', + `st_other, BYTE', + `st_shndx, HALF', + `st_value, ADDR', + `st_size, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Syminfo', + ``si_boundto, HALF', + `si_flags, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Syminfo', + ``si_boundto, HALF', + `si_flags, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verdaux', + ``vda_name, WORD', + `vda_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verdaux', + ``vda_name, WORD', + `vda_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verdef', + ``vd_version, HALF', + `vd_flags, HALF', + `vd_ndx, HALF', + `vd_cnt, HALF', + `vd_hash, WORD', + `vd_aux, WORD', + `vd_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verdef', + ``vd_version, HALF', + `vd_flags, HALF', + `vd_ndx, HALF', + `vd_cnt, HALF', + `vd_hash, WORD', + `vd_aux, WORD', + `vd_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verneed', + ``vn_version, HALF', + `vn_cnt, HALF', + `vn_file, WORD', + `vn_aux, WORD', + `vn_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verneed', + ``vn_version, HALF', + `vn_cnt, HALF', + `vn_file, WORD', + `vn_aux, WORD', + `vn_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Vernaux', + ``vna_hash, WORD', + `vna_flags, HALF', + `vna_other, HALF', + `vna_name, WORD', + `vna_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Vernaux', + ``vna_hash, WORD', + `vna_flags, HALF', + `vna_other, HALF', + `vna_name, WORD', + `vna_next, WORD', + `_,_'') diff --git a/contrib/elftoolchain/libelf/elf_update.3 b/contrib/elftoolchain/libelf/elf_update.3 new file mode 100644 index 0000000000..549b589b5e --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_update.3 @@ -0,0 +1,382 @@ +.\" Copyright (c) 2006-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_update.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt ELF_UPDATE 3 +.Os +.Sh NAME +.Nm elf_update +.Nd update an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_update "Elf *elf" "Elf_Cmd cmd" +.Sh DESCRIPTION +Function +.Fn elf_update +causes the library to recalculate the structure of an ELF +object and optionally write out the image of the object +to file. +.Pp +Argument +.Fa elf +should reference a valid ELF descriptor. +.Pp +Argument +.Fa cmd +can be one of the following values: +.Bl -tag -width "Dv ELF_C_WRITE" +.It Dv ELF_C_NULL +The library will recalculate structural information flagging +modified structures with the +.Dv ELF_F_DIRTY +flag, but will not write data to the underlying file image. +.It Dv ELF_C_WRITE +The library will recalculate structural information and will +also write the new image to the underlying file. +The ELF descriptor referenced by argument +.Fa elf +should permit the underlying ELF object to be written or updated +(see +.Xr elf_begin 3 ) . +.El +.Pp +All pointers to +.Vt Elf_Scn +and +.Vt Elf_Data +descriptors associated with descriptor +.Fa elf +should be considered invalid after a call to +.Fn elf_update . +.Ss Specifying Object Layout +The +.Lb libelf +supports two layout modes. +.Bl -tag -width indent +.It "Library Layout" +If the +.Dv ELF_F_LAYOUT +flag is not set on the ELF descriptor, the ELF library will lay out +the ELF object according to the following scheme: +.Bl -tag -compact -width "Section Data" +.It Em EHDR +The ELF executable header will be placed at the start of the object. +.It Em PHDR +If the ELF descriptor contains a program header table, it will be +placed after the Executable Header. +.It Em Section Data +ELF section data, if any, will be placed next, keeping each section's +alignment requirements in mind. +.It Em SHDR +The ELF section header table, if any, will be placed last. +.El +.It "Application Controlled Layout" +The application can take full control of the layout of the ELF object +by setting the +.Dv ELF_F_LAYOUT +flag on the ELF descriptor (see +.Xr elf_flagelf 3 ) . +In this case the library will lay out the ELF object using +application-supplied information as below: +.Pp +.Bl -tag -compact -width "Section Data" +.It Em EHDR +The ELF executable header will be placed at the start of the object. +.It Em PHDR +The ELF program header table, if any, it will be placed at the offset +specified in the +.Va e_phoff +field of the ELF executable header. +.It Em Section Data +The data for each ELF section will be placed at the offset specified +by the +.Va sh_offset +field of the section's header. +The size of the section will be taken from the +.Va sh_size +field of the section header. +.It Em SHDR +The ELF section header table, if any, will be placed at the offset +specified by the +.Va e_shoff +field of the executable header. +.El +.El +.Pp +Gaps in the coverage of the file's contents will be set to the fill value +specified by +.Xr elf_fill 3 . +.Ss Application Supplied Information +The application needs to set the following fields in the data +structures associated with the ELF descriptor prior to calling +.Fn elf_update . +.Bl -tag -width indent +.It "Executable Header" +The fields of the ELF executable header that need to be set by the +application are: +.Pp +.Bl -tag -width "e_ident[EI_OSABI]" -compact +.It Va e_entry +To be set to the desired entry address for executables. +.It Va e_flags +To be set to the desired processor specific flags. +.It Va "e_ident[EI_DATA]" +Must be set to one of +.Dv ELFDATA2LSB +or +.Dv ELFDATA2MSB . +.It Va "e_ident[EI_OSABI]" +To be set to the OS ABI desired. +For example, for +.Fx +executables, this field should be set to +.Dv ELFOSABI_FREEBSD . +.It Va e_machine +To be set to the desired machine architecture, one of the +.Dv EM_* +values in the header file +.In elfdefinitions.h . +.It Va e_phoff +If the application is managing the object's layout, it must +set this field to the file offset of the ELF program header table. +.It Va e_shoff +If the application is managing the object's layout, it must +set this field to the file offset of the ELF section header table. +.It Va e_shstrndx +To be set to the index of the string table containing +section names. +.It Va e_type +To be set to the type of the ELF object, one of the +.Dv ET_* +values in the header file +.In elfdefinitions.h . +.It Va e_version +To be set to the desired version of the ELF object. +.El +.It "Program Header" +All fields of the entries in the program header table need to be +set by the application. +.It "Section Header" +The fields of ELF section headers that need to be set by the +application are: +.Pp +.Bl -tag -width "sh_addralign" -compact +.It Va sh_addr +To be set to the memory address where the section should reside. +.It Va sh_addralign +If the application is managing the file layout, it must set this +field to the desired alignment for the section's contents. +This value must be a power of two and must be at least as large as the +largest alignment needed by any +.Vt Elf_Data +descriptor associated with the section. +.It Va sh_entsize +To be set to the size of each entry, for sections containing fixed size +elements, or set to zero for sections without fixed size elements. +If the application is not managing file layout, it may leave this +field as zero for those sections whose types are known to the library. +.It Va sh_flags +To be set to the desired section flags. +.It Va sh_info +To be set as described in +.Xr elf 5 . +.It Va sh_link +To be set as described in +.Xr elf 5 . +.It Va sh_name +To be set to the index of the section's name in the string table +containing section names. +.It Va sh_offset +If the application is managing the file layout, it must set this +field to the file offset of the section's contents. +.It Va sh_size +If the application is managing the file layout, it must set this +field to the file size of the section's contents. +.It Va sh_type +To be set to the type of the section. +.El +.It "Section Data" +The +.Vt Elf_Data +descriptors associated with each section specify its contents +(see +.Xr elf_getdata 3 ) . +While all the fields in these descriptors are under application +control, the following fields influence object layout: +.Bl -tag -width "Va d_align" -compact +.It Va d_align +To be set to the desired alignment, within the containing section, of +the descriptor's data. +.It Va d_off +If the application is managing object layout, it must set this field +to the file offset, within the section, at which the descriptor's data +should be placed. +.It Va d_size +To be set to the size in bytes of the memory representation of the +descriptor's data. +.El +.El +.Sh RETURN VALUES +Function +.Fn elf_update +returns the total size of the file image if successful, or -1 if an +error occurred. +.Sh ERRORS +This function may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa cmd +was not recognized. +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +The +.Va e_ident[EI_CLASS] +field of the executable header of argument +.Fa elf +did not match the class of the file. +.It Bq Er ELF_E_DATA +An +.Vt Elf_Data +descriptor contained in argument +.Fa elf +specified an unsupported type. +.It Bq Er ELF_E_DATA +An +.Vt Elf_Data +descriptor specified an alignment that was zero or was not a power of +two. +.It Bq Er ELF_E_HEADER +The ELF header in argument +.Fa elf +requested a different byte order from the byte order already +associated with the file. +.It Bq Er ELF_E_IO +An I/O error was encountered. +.It Bq Er ELF_E_LAYOUT +An +.Vt Elf_Data +descriptor contained in argument +.Fa elf +specified an alignment incompatible with its containing section. +.It Bq Er ELF_E_LAYOUT +Argument +.Fa elf +contained section descriptors that overlapped in extent. +.It Bq Er ELF_E_LAYOUT +Argument +.Fa elf +contained section descriptors that were incorrectly aligned or were +too small for their data. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the executable header overlapped +with the program header table. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the program header table was placed +at a misaligned file offset. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the section header table overlapped +an extent mapped by a section descriptor. +.It Bq Er ELF_E_LAYOUT +The +.Dv ELF_F_LAYOUT +flag was set on the Elf descriptor, and the +.Va d_offset +field in an +.Vt Elf_Data +descriptor contained a value that was not a multiple of the +descriptor's specified alignment. +.It Bq Er ELF_E_MODE +An +.Dv ELF_C_WRITE +operation was requested with an ELF descriptor that was not opened for +writing or updating. +.It Bq Er ELF_E_SECTION +Argument +.Fa elf +contained a section with an unrecognized type. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +had an illegal section type. +.It Bq Er ELF_E_SEQUENCE +An +.Dv ELF_C_WRITE +operation was requested after a prior call to +.Fn elf_cntl elf ELF_C_FDDONE +disassociated the ELF descriptor +.Fa elf +from its underlying file. +.It Bq Er ELF_E_UNIMPL +Argument +.Fa elf +contained a section with an unsupported ELF type. +.It Bq Er ELF_E_VERSION +Argument +.Fa elf +had an unsupported version or contained an +.Vt Elf_Data +descriptor with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf32_getphdr 3 , +.Xr elf32_newehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf64_getphdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf_begin 3 , +.Xr elf_cntl 3 , +.Xr elf_fill 3 , +.Xr elf_flagehdr 3 , +.Xr elf_flagelf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr elf_newdata 3 , +.Xr elf_newscn 3 , +.Xr elf_rawdata 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr gelf_newphdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/elf_update.c b/contrib/elftoolchain/libelf/elf_update.c new file mode 100644 index 0000000000..f341245a3d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_update.c @@ -0,0 +1,1246 @@ +/*- + * Copyright (c) 2006-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include +#endif + +ELFTC_VCSID("$Id: elf_update.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Layout strategy: + * + * - Case 1: ELF_F_LAYOUT is asserted + * In this case the application has full control over where the + * section header table, program header table, and section data + * will reside. The library only perform error checks. + * + * - Case 2: ELF_F_LAYOUT is not asserted + * + * The library will do the object layout using the following + * ordering: + * - The executable header is placed first, are required by the + * ELF specification. + * - The program header table is placed immediately following the + * executable header. + * - Section data, if any, is placed after the program header + * table, aligned appropriately. + * - The section header table, if needed, is placed last. + * + * There are two sub-cases to be taken care of: + * + * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR + * + * In this sub-case, the underlying ELF object may already have + * content in it, which the application may have modified. The + * library will retrieve content from the existing object as + * needed. + * + * - Case 2b: e->e_cmd == ELF_C_WRITE + * + * The ELF object is being created afresh in this sub-case; + * there is no pre-existing content in the underlying ELF + * object. + */ + +/* + * The types of extents in an ELF object. + */ +enum elf_extent { + ELF_EXTENT_EHDR, + ELF_EXTENT_PHDR, + ELF_EXTENT_SECTION, + ELF_EXTENT_SHDR +}; + +/* + * A extent descriptor, used when laying out an ELF object. + */ +struct _Elf_Extent { + SLIST_ENTRY(_Elf_Extent) ex_next; + uint64_t ex_start; /* Start of the region. */ + uint64_t ex_size; /* The size of the region. */ + enum elf_extent ex_type; /* Type of region. */ + void *ex_desc; /* Associated descriptor. */ +}; + +SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); + +/* + * Compute the extents of a section, by looking at the data + * descriptors associated with it. The function returns 1 + * if successful, or zero if an error was detected. + */ +static int +_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) +{ + Elf_Data *d; + size_t fsz, msz; + int ec, elftype; + uint32_t sh_type; + uint64_t d_align; + Elf32_Shdr *shdr32; + Elf64_Shdr *shdr64; + struct _Libelf_Data *ld; + uint64_t scn_size, scn_alignment; + uint64_t sh_align, sh_entsize, sh_offset, sh_size; + + ec = e->e_class; + + shdr32 = &s->s_shdr.s_shdr32; + shdr64 = &s->s_shdr.s_shdr64; + if (ec == ELFCLASS32) { + sh_type = shdr32->sh_type; + sh_align = (uint64_t) shdr32->sh_addralign; + sh_entsize = (uint64_t) shdr32->sh_entsize; + sh_offset = (uint64_t) shdr32->sh_offset; + sh_size = (uint64_t) shdr32->sh_size; + } else { + sh_type = shdr64->sh_type; + sh_align = shdr64->sh_addralign; + sh_entsize = shdr64->sh_entsize; + sh_offset = shdr64->sh_offset; + sh_size = shdr64->sh_size; + } + + assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); + + elftype = _libelf_xlate_shtype(sh_type); + if (elftype < ELF_T_FIRST || elftype > ELF_T_LAST) { + LIBELF_SET_ERROR(SECTION, 0); + return (0); + } + + if (sh_align == 0) + sh_align = _libelf_falign(elftype, ec); + + /* + * Compute the section's size and alignment using the data + * descriptors associated with the section. + */ + if (STAILQ_EMPTY(&s->s_data)) { + /* + * The section's content (if any) has not been read in + * yet. If section is not dirty marked dirty, we can + * reuse the values in the 'sh_size' and 'sh_offset' + * fields of the section header. + */ + if ((s->s_flags & ELF_F_DIRTY) == 0) { + /* + * If the library is doing the layout, then we + * compute the new start offset for the + * section based on the current offset and the + * section's alignment needs. + * + * If the application is doing the layout, we + * can use the value in the 'sh_offset' field + * in the section header directly. + */ + if (e->e_flags & ELF_F_LAYOUT) + goto updatedescriptor; + else + goto computeoffset; + } + + /* + * Otherwise, we need to bring in the section's data + * from the underlying ELF object. + */ + if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) + return (0); + } + + /* + * Loop through the section's data descriptors. + */ + scn_size = 0L; + scn_alignment = 0; + STAILQ_FOREACH(ld, &s->s_data, d_next) { + + d = &ld->d_data; + + /* + * The data buffer's type is known. + */ + if (d->d_type >= ELF_T_NUM) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * The data buffer's version is supported. + */ + if (d->d_version != e->e_version) { + LIBELF_SET_ERROR(VERSION, 0); + return (0); + } + + /* + * The buffer's alignment is non-zero and a power of + * two. + */ + if ((d_align = d->d_align) == 0 || + (d_align & (d_align - 1))) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * The data buffer's ELF type, ELF class and ELF version + * should be supported. + */ + if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0) + return (0); + + /* + * The buffer's size should be a multiple of the + * memory size of the underlying type. + */ + if (d->d_size % msz) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * If the application is controlling layout, then the + * d_offset field should be compatible with the + * buffer's specified alignment. + */ + if ((e->e_flags & ELF_F_LAYOUT) && + (d->d_off & (d_align - 1))) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + + /* + * Compute the section's size. + */ + if (e->e_flags & ELF_F_LAYOUT) { + if ((uint64_t) d->d_off + d->d_size > scn_size) + scn_size = d->d_off + d->d_size; + } else { + scn_size = roundup2(scn_size, d->d_align); + d->d_off = scn_size; + fsz = _libelf_fsize(d->d_type, ec, d->d_version, + (size_t) d->d_size / msz); + scn_size += fsz; + } + + /* + * The section's alignment is the maximum alignment + * needed for its data buffers. + */ + if (d_align > scn_alignment) + scn_alignment = d_align; + } + + + /* + * If the application is requesting full control over the + * layout of the section, check the section's specified size, + * offsets and alignment for sanity. + */ + if (e->e_flags & ELF_F_LAYOUT) { + if (scn_alignment > sh_align || + sh_offset % sh_align || + sh_size < scn_size || + sh_offset % _libelf_falign(elftype, ec)) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + goto updatedescriptor; + } + + /* + * Otherwise, compute the values in the section header. + * + * The section alignment is the maximum alignment for any of + * its contained data descriptors. + */ + if (scn_alignment > sh_align) + sh_align = scn_alignment; + + /* + * If the section entry size is zero, try and fill in an + * appropriate entry size. Per the elf(5) manual page + * sections without fixed-size entries should have their + * 'sh_entsize' field set to zero. + */ + if (sh_entsize == 0 && + (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, + (size_t) 1)) == 1) + sh_entsize = 0; + + sh_size = scn_size; + +computeoffset: + /* + * Compute the new offset for the section based on + * the section's alignment needs. + */ + sh_offset = roundup((uint64_t) rc, sh_align); + + /* + * Update the section header. + */ + if (ec == ELFCLASS32) { + shdr32->sh_addralign = (uint32_t) sh_align; + shdr32->sh_entsize = (uint32_t) sh_entsize; + shdr32->sh_offset = (uint32_t) sh_offset; + shdr32->sh_size = (uint32_t) sh_size; + } else { + shdr64->sh_addralign = sh_align; + shdr64->sh_entsize = sh_entsize; + shdr64->sh_offset = sh_offset; + shdr64->sh_size = sh_size; + } + +updatedescriptor: + /* + * Update the section descriptor. + */ + s->s_size = sh_size; + s->s_offset = sh_offset; + + return (1); +} + +/* + * Free a list of extent descriptors. + */ + +static void +_libelf_release_extents(struct _Elf_Extent_List *extents) +{ + struct _Elf_Extent *ex; + + while ((ex = SLIST_FIRST(extents)) != NULL) { + SLIST_REMOVE_HEAD(extents, ex_next); + free(ex); + } +} + +/* + * Check if an extent 's' defined by [start..start+size) is free. + * This routine assumes that the given extent list is sorted in order + * of ascending extent offsets. + */ + +static int +_libelf_extent_is_unused(struct _Elf_Extent_List *extents, + const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt) +{ + uint64_t tmax, tmin; + struct _Elf_Extent *t, *pt; + const uint64_t smax = start + size; + + /* First, look for overlaps with existing extents. */ + pt = NULL; + SLIST_FOREACH(t, extents, ex_next) { + tmin = t->ex_start; + tmax = tmin + t->ex_size; + + if (tmax <= start) { + /* + * 't' lies entirely before 's': ...| t |...| s |... + */ + pt = t; + continue; + } else if (smax <= tmin) { + /* + * 's' lies entirely before 't', and after 'pt': + * ...| pt |...| s |...| t |... + */ + assert(pt == NULL || + pt->ex_start + pt->ex_size <= start); + break; + } else + /* 's' and 't' overlap. */ + return (0); + } + + if (prevt) + *prevt = pt; + return (1); +} + +/* + * Insert an extent into the list of extents. + */ + +static int +_libelf_insert_extent(struct _Elf_Extent_List *extents, int type, + uint64_t start, uint64_t size, void *desc) +{ + struct _Elf_Extent *ex, *prevt; + + assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR); + + prevt = NULL; + + /* + * If the requested range overlaps with an existing extent, + * signal an error. + */ + if (!_libelf_extent_is_unused(extents, start, size, &prevt)) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + + /* Allocate and fill in a new extent descriptor. */ + if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return (0); + } + ex->ex_start = start; + ex->ex_size = size; + ex->ex_desc = desc; + ex->ex_type = type; + + /* Insert the region descriptor into the list. */ + if (prevt) + SLIST_INSERT_AFTER(prevt, ex, ex_next); + else + SLIST_INSERT_HEAD(extents, ex, ex_next); + return (1); +} + +/* + * Recompute section layout. + */ + +static off_t +_libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) +{ + int ec; + Elf_Scn *s; + size_t sh_type; + + ec = e->e_class; + + /* + * Make a pass through sections, computing the extent of each + * section. + */ + STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { + if (ec == ELFCLASS32) + sh_type = s->s_shdr.s_shdr32.sh_type; + else + sh_type = s->s_shdr.s_shdr64.sh_type; + + if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) + continue; + + if (_libelf_compute_section_extents(e, s, rc) == 0) + return ((off_t) -1); + + if (s->s_size == 0) + continue; + + if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION, + s->s_offset, s->s_size, s)) + return ((off_t) -1); + + if ((size_t) rc < s->s_offset + s->s_size) + rc = (off_t) (s->s_offset + s->s_size); + } + + return (rc); +} + +/* + * Recompute the layout of the ELF object and update the internal data + * structures associated with the ELF descriptor. + * + * Returns the size in bytes the ELF object would occupy in its file + * representation. + * + * After a successful call to this function, the following structures + * are updated: + * + * - The ELF header is updated. + * - All extents in the ELF object are sorted in order of ascending + * addresses. Sections have their section header table entries + * updated. An error is signalled if an overlap was detected among + * extents. + * - Data descriptors associated with sections are checked for valid + * types, offsets and alignment. + * + * After a resync_elf() successfully returns, the ELF descriptor is + * ready for being handed over to _libelf_write_elf(). + */ + +static off_t +_libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) +{ + int ec, eh_class; + unsigned int eh_byteorder, eh_version; + size_t align, fsz; + size_t phnum, shnum; + off_t rc, phoff, shoff; + void *ehdr, *phdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + rc = 0; + + ec = e->e_class; + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + /* + * Prepare the EHDR. + */ + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return ((off_t) -1); + + eh32 = ehdr; + eh64 = ehdr; + + if (ec == ELFCLASS32) { + eh_byteorder = eh32->e_ident[EI_DATA]; + eh_class = eh32->e_ident[EI_CLASS]; + phoff = (off_t) eh32->e_phoff; + shoff = (off_t) eh32->e_shoff; + eh_version = eh32->e_version; + } else { + eh_byteorder = eh64->e_ident[EI_DATA]; + eh_class = eh64->e_ident[EI_CLASS]; + phoff = (off_t) eh64->e_phoff; + shoff = (off_t) eh64->e_shoff; + eh_version = eh64->e_version; + } + + if (phoff < 0 || shoff < 0) { + LIBELF_SET_ERROR(HEADER, 0); + return ((off_t) -1); + } + + if (eh_version == EV_NONE) + eh_version = EV_CURRENT; + + if (eh_version != e->e_version) { /* always EV_CURRENT */ + LIBELF_SET_ERROR(VERSION, 0); + return ((off_t) -1); + } + + if (eh_class != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return ((off_t) -1); + } + + if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { + LIBELF_SET_ERROR(HEADER, 0); + return ((off_t) -1); + } + + shnum = e->e_u.e_elf.e_nscn; + phnum = e->e_u.e_elf.e_nphdr; + + e->e_byteorder = eh_byteorder; + +#define INITIALIZE_EHDR(E,EC,V) do { \ + unsigned int _version = (unsigned int) (V); \ + (E)->e_ident[EI_MAG0] = ELFMAG0; \ + (E)->e_ident[EI_MAG1] = ELFMAG1; \ + (E)->e_ident[EI_MAG2] = ELFMAG2; \ + (E)->e_ident[EI_MAG3] = ELFMAG3; \ + (E)->e_ident[EI_CLASS] = (unsigned char) (EC); \ + (E)->e_ident[EI_VERSION] = (_version & 0xFFU); \ + (E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \ + (EC), _version, (size_t) 1); \ + (E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \ + _libelf_fsize(ELF_T_PHDR, (EC), _version, \ + (size_t) 1)); \ + (E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \ + (EC), _version, (size_t) 1); \ + } while (/* CONSTCOND */ 0) + + if (ec == ELFCLASS32) + INITIALIZE_EHDR(eh32, ec, eh_version); + else + INITIALIZE_EHDR(eh64, ec, eh_version); + + (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); + + rc += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); + + if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) rc, + ehdr)) + return ((off_t) -1); + + /* + * Compute the layout the program header table, if one is + * present. The program header table needs to be aligned to a + * `natural' boundary. + */ + if (phnum) { + fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); + align = _libelf_falign(ELF_T_PHDR, ec); + + if (e->e_flags & ELF_F_LAYOUT) { + /* + * Check offsets for sanity. + */ + if (rc > phoff) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + + if (phoff % (off_t) align) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + + } else + phoff = roundup(rc, (off_t) align); + + rc = phoff + (off_t) fsz; + + phdr = _libelf_getphdr(e, ec); + + if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, + (uint64_t) phoff, fsz, phdr)) + return ((off_t) -1); + } else + phoff = 0; + + /* + * Compute the layout of the sections associated with the + * file. + */ + + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return ((off_t) -1); + + if ((rc = _libelf_resync_sections(e, rc, extents)) < 0) + return ((off_t) -1); + + /* + * Compute the space taken up by the section header table, if + * one is needed. + * + * If ELF_F_LAYOUT has been asserted, the application may have + * placed the section header table in between existing + * sections, so the net size of the file need not increase due + * to the presence of the section header table. + * + * If the library is responsible for laying out the object, + * the section header table is placed after section data. + */ + if (shnum) { + fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum); + align = _libelf_falign(ELF_T_SHDR, ec); + + if (e->e_flags & ELF_F_LAYOUT) { + if (shoff % (off_t) align) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + } else + shoff = roundup(rc, (off_t) align); + + if (shoff + (off_t) fsz > rc) + rc = shoff + (off_t) fsz; + + if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, + (uint64_t) shoff, fsz, NULL)) + return ((off_t) -1); + } else + shoff = 0; + + /* + * Set the fields of the Executable Header that could potentially use + * extended numbering. + */ + _libelf_setphnum(e, ehdr, ec, phnum); + _libelf_setshnum(e, ehdr, ec, shnum); + + /* + * Update the `e_phoff' and `e_shoff' fields if the library is + * doing the layout. + */ + if ((e->e_flags & ELF_F_LAYOUT) == 0) { + if (ec == ELFCLASS32) { + eh32->e_phoff = (uint32_t) phoff; + eh32->e_shoff = (uint32_t) shoff; + } else { + eh64->e_phoff = (uint64_t) phoff; + eh64->e_shoff = (uint64_t) shoff; + } + } + + return (rc); +} + +/* + * Write out the contents of an ELF section. + */ + +static off_t +_libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) +{ + off_t rc; + int ec, em; + Elf_Scn *s; + int elftype; + Elf_Data *d, dst; + uint32_t sh_type; + struct _Libelf_Data *ld; + uint64_t sh_off, sh_size; + size_t fsz, msz, nobjects; + + assert(ex->ex_type == ELF_EXTENT_SECTION); + + s = ex->ex_desc; + rc = (off_t) ex->ex_start; + + if ((ec = e->e_class) == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_size = s->s_shdr.s_shdr64.sh_size; + } + + /* + * Ignore sections that do not allocate space in the file. + */ + if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) + return (rc); + + elftype = _libelf_xlate_shtype(sh_type); + assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); + + sh_off = s->s_offset; + assert(sh_off % _libelf_falign(elftype, ec) == 0); + + em = _libelf_elfmachine(e); + + /* + * If the section has a `rawdata' descriptor, and the section + * contents have not been modified, use its contents directly. + * The `s_rawoff' member contains the offset into the original + * file, while `s_offset' contains its new location in the + * destination. + */ + + if (STAILQ_EMPTY(&s->s_data)) { + + if ((d = elf_rawdata(s, NULL)) == NULL) + return ((off_t) -1); + + STAILQ_FOREACH(ld, &s->s_rawdata, d_next) { + + d = &ld->d_data; + + if ((uint64_t) rc < sh_off + d->d_off) + (void) memset(nf + rc, + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - + (uint64_t) rc)); + rc = (off_t) (sh_off + d->d_off); + + assert(d->d_buf != NULL); + assert(d->d_type == ELF_T_BYTE); + assert(d->d_version == e->e_version); + + (void) memcpy(nf + rc, + e->e_rawfile + s->s_rawoff + d->d_off, + (size_t) d->d_size); + + rc += (off_t) d->d_size; + } + + return (rc); + } + + /* + * Iterate over the set of data descriptors for this section. + * The prior call to _libelf_resync_elf() would have setup the + * descriptors for this step. + */ + + dst.d_version = e->e_version; + + STAILQ_FOREACH(ld, &s->s_data, d_next) { + + d = &ld->d_data; + + if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0) + return ((off_t) -1); + + if ((uint64_t) rc < sh_off + d->d_off) + (void) memset(nf + rc, + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - (uint64_t) rc)); + + rc = (off_t) (sh_off + d->d_off); + + assert(d->d_buf != NULL); + assert(d->d_version == e->e_version); + assert(d->d_size % msz == 0); + assert(msz != 0); + + nobjects = (size_t) (d->d_size / msz); + + fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); + + dst.d_buf = nf + rc; + dst.d_size = fsz; + + if (_libelf_xlate(&dst, d, e->e_byteorder, ec, em, ELF_TOFILE) + == NULL) + return ((off_t) -1); + + rc += (off_t) fsz; + } + + return (rc); +} + +/* + * Write out an ELF Executable Header. + */ + +static off_t +_libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) +{ + int ec, em; + void *ehdr; + size_t fsz, msz; + Elf_Data dst, src; + + assert(ex->ex_type == ELF_EXTENT_EHDR); + assert(ex->ex_start == 0); /* Ehdr always comes first. */ + + ec = e->e_class; + + ehdr = _libelf_ehdr(e, ec, 0); + assert(ehdr != NULL); + + fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); + if ((msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version)) == 0) + return ((off_t) -1); + + em = _libelf_elfmachine(e); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + src.d_buf = ehdr; + src.d_size = msz; + src.d_type = ELF_T_EHDR; + src.d_version = dst.d_version = e->e_version; + + dst.d_buf = nf; + dst.d_size = fsz; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, ELF_TOFILE) == + NULL) + return ((off_t) -1); + + return ((off_t) fsz); +} + +/* + * Write out an ELF program header table. + */ + +static off_t +_libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) +{ + int ec, em; + void *ehdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + Elf_Data dst, src; + size_t fsz, msz, phnum; + uint64_t phoff; + + assert(ex->ex_type == ELF_EXTENT_PHDR); + + ec = e->e_class; + + ehdr = _libelf_ehdr(e, ec, 0); + assert(ehdr != NULL); + + phnum = e->e_u.e_elf.e_nphdr; + assert(phnum > 0); + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + phoff = (uint64_t) eh32->e_phoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + phoff = eh64->e_phoff; + } + + em = _libelf_elfmachine(e); + + assert(phoff > 0); + assert(ex->ex_start == phoff); + assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0) + return ((off_t) -1); + fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); + assert(fsz > 0); + + src.d_buf = _libelf_getphdr(e, ec); + src.d_version = dst.d_version = e->e_version; + src.d_type = ELF_T_PHDR; + src.d_size = phnum * msz; + + dst.d_size = fsz; + dst.d_buf = nf + ex->ex_start; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, ELF_TOFILE) == + NULL) + return ((off_t) -1); + + return ((off_t) (phoff + fsz)); +} + +/* + * Write out an ELF section header table. + */ + +static off_t +_libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) +{ + int ec, em; + void *ehdr; + Elf_Scn *scn; + uint64_t shoff; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + size_t fsz, msz, nscn; + Elf_Data dst, src; + + assert(ex->ex_type == ELF_EXTENT_SHDR); + + ec = e->e_class; + + ehdr = _libelf_ehdr(e, ec, 0); + assert(ehdr != NULL); + + nscn = e->e_u.e_elf.e_nscn; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + shoff = (uint64_t) eh32->e_shoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + shoff = eh64->e_shoff; + } + + em = _libelf_elfmachine(e); + + assert(nscn > 0); + assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0); + assert(ex->ex_start == shoff); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + if ((msz = _libelf_msize(ELF_T_SHDR, ec, e->e_version)) == 0) + return ((off_t) -1); + + src.d_type = ELF_T_SHDR; + src.d_size = msz; + src.d_version = dst.d_version = e->e_version; + + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); + + STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { + if (ec == ELFCLASS32) + src.d_buf = &scn->s_shdr.s_shdr32; + else + src.d_buf = &scn->s_shdr.s_shdr64; + + dst.d_size = fsz; + dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, + ELF_TOFILE) == NULL) + return ((off_t) -1); + } + + return ((off_t) (ex->ex_start + nscn * fsz)); +} + +/* + * Write out the file image. + * + * The original file could have been mapped in with an ELF_C_RDWR + * command and the application could have added new content or + * re-arranged its sections before calling elf_update(). Consequently + * its not safe to work `in place' on the original file. So we + * malloc() the required space for the updated ELF object and build + * the object there and write it out to the underlying file at the + * end. Note that the application may have opened the underlying file + * in ELF_C_RDWR and only retrieved/modified a few sections. We take + * care to avoid translating file sections unnecessarily. + * + * Gaps in the coverage of the file by the file's sections will be + * filled with the fill character set by elf_fill(3). + */ + +static off_t +_libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) +{ + off_t nrc, rc; + Elf_Scn *scn, *tscn; + struct _Elf_Extent *ex; + unsigned char *newfile; + + assert(e->e_kind == ELF_K_ELF); + assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); + assert(e->e_fd >= 0); + + if ((newfile = malloc((size_t) newsize)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return ((off_t) -1); + } + + nrc = rc = 0; + SLIST_FOREACH(ex, extents, ex_next) { + + /* Fill inter-extent gaps. */ + if (ex->ex_start > (size_t) rc) + (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), + (size_t) (ex->ex_start - (uint64_t) rc)); + + switch (ex->ex_type) { + case ELF_EXTENT_EHDR: + if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_PHDR: + if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_SECTION: + if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_SHDR: + if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0) + goto error; + break; + + default: + assert(0); + break; + } + + assert(ex->ex_start + ex->ex_size == (size_t) nrc); + assert(rc < nrc); + + rc = nrc; + } + + assert(rc == newsize); + + /* + * For regular files, throw away existing file content and + * unmap any existing mappings. + */ + if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) { + if (ftruncate(e->e_fd, (off_t) 0) < 0 || + lseek(e->e_fd, (off_t) 0, SEEK_SET)) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } +#if ELFTC_HAVE_MMAP + if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { + assert(e->e_rawfile != NULL); + assert(e->e_cmd == ELF_C_RDWR); + if (munmap(e->e_rawfile, (size_t) e->e_rawsize) < 0) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + } +#endif + } + + /* + * Write out the new contents. + */ + if (write(e->e_fd, newfile, (size_t) newsize) != newsize) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + + /* + * For files opened in ELF_C_RDWR mode, set up the new 'raw' + * contents. + */ + if (e->e_cmd == ELF_C_RDWR) { + assert(e->e_rawfile != NULL); + assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) || + (e->e_flags & LIBELF_F_RAWFILE_MMAP)); + if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { + assert((e->e_flags & LIBELF_F_RAWFILE_MMAP) == 0); + free(e->e_rawfile); + e->e_rawfile = newfile; + newfile = NULL; + } +#if ELFTC_HAVE_MMAP + else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { + assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) == 0); + if ((e->e_rawfile = mmap(NULL, (size_t) newsize, + PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == + MAP_FAILED) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + } +#endif /* ELFTC_HAVE_MMAP */ + + /* Record the new size of the file. */ + e->e_rawsize = newsize; + } else { + /* File opened in ELF_C_WRITE mode. */ + assert(e->e_rawfile == NULL); + } + + /* + * Reset flags, remove existing section descriptors and + * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() + * and elf_getscn() will function correctly. + */ + + e->e_flags &= ~ELF_F_DIRTY; + + STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) + _libelf_release_scn(scn); + + if (e->e_class == ELFCLASS32) { + free(e->e_u.e_elf.e_ehdr.e_ehdr32); + if (e->e_u.e_elf.e_phdr.e_phdr32) + free(e->e_u.e_elf.e_phdr.e_phdr32); + + e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; + e->e_u.e_elf.e_phdr.e_phdr32 = NULL; + } else { + free(e->e_u.e_elf.e_ehdr.e_ehdr64); + if (e->e_u.e_elf.e_phdr.e_phdr64) + free(e->e_u.e_elf.e_phdr.e_phdr64); + + e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; + e->e_u.e_elf.e_phdr.e_phdr64 = NULL; + } + + /* Free the temporary buffer. */ + if (newfile) + free(newfile); + + return (rc); + + error: + free(newfile); + + return ((off_t) -1); +} + +/* + * Update an ELF object. + */ + +off_t +elf_update(Elf *e, Elf_Cmd c) +{ + int ec; + off_t rc; + struct _Elf_Extent_List extents; + + rc = (off_t) -1; + + if (e == NULL || e->e_kind != ELF_K_ELF || + (c != ELF_C_NULL && c != ELF_C_WRITE)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (rc); + } + + if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { + LIBELF_SET_ERROR(CLASS, 0); + return (rc); + } + + if (e->e_version == EV_NONE) + e->e_version = EV_CURRENT; + + if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (rc); + } + + SLIST_INIT(&extents); + + if ((rc = _libelf_resync_elf(e, &extents)) < 0) + goto done; + + if (c == ELF_C_NULL) + goto done; + + if (e->e_fd < 0) { + rc = (off_t) -1; + LIBELF_SET_ERROR(SEQUENCE, 0); + goto done; + } + + rc = _libelf_write_elf(e, rc, &extents); + +done: + _libelf_release_extents(&extents); + return (rc); +} diff --git a/contrib/elftoolchain/libelf/elf_version.3 b/contrib/elftoolchain/libelf/elf_version.3 new file mode 100644 index 0000000000..ae5ce35202 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_version.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elf_version.3 3957 2022-03-12 14:11:52Z jkoshy $ +.\" +.Dd November 9, 2011 +.Dt ELF_VERSION 3 +.Os +.Sh NAME +.Nm elf_version +.Nd retrieve or set ELF library operating version +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft unsigned int +.Fn elf_version "unsigned int version" +.Sh DESCRIPTION +The +.Fn elf_version +function is used to query the current operating version of the ELF +library, and to inform the ELF library about the application's desired +operating version. +.Pp +If the argument +.Fa version +is +.Dv EV_NONE , +the +.Fn elf_version +function returns the currently configured operating version for the +ELF library. +.Pp +If the argument +.Fa version +is not +.Dv EV_NONE , +and if argument +.Fa version +is supported by the ELF library, function +.Fn elf_version +sets the library's operating version to +.Fa version , +and returns the previous value of the operating version. +If argument +.Fa version +cannot be supported, then the +.Fn elf_version +function returns +.Dv EV_NONE . +.Sh RETURN VALUES +The +.Fn elf_version +function returns the currently configured ELF library version, or +.Dv EV_NONE +if an unsupported version is requested. +.Sh EXAMPLES +An application program would inform the ELF library about its desired +operating version and check for an error using the following code +snippet: +.Bd -literal -offset indent +if (elf_version(EV_CURRENT) == EV_NONE) + err(EXIT_FAILURE, "ELF library too old"); +.Ed +.Sh ERRORS +Function +.Fn elf_version +may fail with the following error: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er "ELF_E_VERSION" +An unsupported library version number was requested. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_version.c b/contrib/elftoolchain/libelf/elf_version.c new file mode 100644 index 0000000000..dd98d763d1 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_version.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_version.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +unsigned int +elf_version(unsigned int v) +{ + unsigned int old; + + if ((old = LIBELF_PRIVATE(version)) == EV_NONE) + old = EV_CURRENT; + + if (v == EV_NONE) + return old; + if (v > EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return EV_NONE; + } + + LIBELF_PRIVATE(version) = v; + return (old); +} diff --git a/contrib/elftoolchain/libelf/gelf.3 b/contrib/elftoolchain/libelf/gelf.3 new file mode 100644 index 0000000000..d703c1b3f6 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf.3 3743 2019-06-12 19:36:30Z jkoshy $ +.\" +.Dd June 12, 2019 +.Dt GELF 3 +.Os +.Sh NAME +.Nm gelf +.Nd class-independent API for ELF manipulation +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Sh DESCRIPTION +This manual page describes a class independent API for manipulating +ELF objects. +This API allows an application to operate on ELF descriptors without +needing to the know the ELF class of the descriptor. +.Pp +The GElf API may be used alongside the ELF API without restriction. +.Ss GElf Data Structures +The GElf API defines the following class-independent data structures: +.Bl -tag -width GElf_Sxword +.It Vt GElf_Addr +A representation of ELF addresses. +.It Vt GElf_Dyn +A class-independent representation of ELF +.Sy .dynamic +section entries. +.It Vt GElf_Ehdr +A class-independent representation of an ELF Executable Header. +.It Vt GElf_Half +An unsigned 16 bit quantity. +.It Vt GElf_Off +A class-independent representation of a ELF offset. +.It Vt GElf_Phdr +A class-independent representation of an ELF Program Header Table +entry. +.It Vt GElf_Rel +A class-independent representation of an ELF relocation entry. +.It Vt GElf_Rela +A class-independent representation of an ELF relocation entry with +addend. +.It Vt GElf_Shdr +A class-independent representation of an ELF Section Header Table +entry. +.It Vt GElf_Sword +A signed 32 bit quantity. +.It Vt GElf_Sxword +A signed 64 bit quantity. +.It Vt GElf_Sym +A class-independent representation of an ELF symbol table entry. +.It Vt GElf_Word +An unsigned 32 bit quantity. +.It Vt GElf_Xword +An unsigned 64 bit quantity. +.El +.Pp +These data structures are sized to be compatible with the +corresponding 64 bit ELF structures, and have the same internal +structure as their 64 bit class-dependent counterparts. +Class-dependent ELF structures are described in +.Xr elf 5 . +.Ss GElf Programming Model +GElf functions always return a +.Em copy +of the underlying (class-dependent) ELF data structure. +The programming model with GElf is as follows: +.Bl -enum +.It +An application will retrieve data from an ELF descriptor using a +.Fn gelf_get_* +function. +This will copy out data into a private +.Vt GElf_* +data structure. +.It +The application will work with its private copy of the GElf +structure. +.It +Once done, the application copies the new values back to the +underlying ELF data structure using the +.Fn gelf_update_* +functions. +.It +The application will then use the +.Fn elf_flag* +APIs to indicate to the ELF library that an ELF data structure is dirty. +.El +.Pp +When updating an underlying 32 bit ELF data structure, the GElf +routines will signal an error if a GElf value is out of range +for the underlying ELF data type. +.Ss Namespace use +The GElf interface uses the following symbols: +.Bl -tag -width indent +.It GElf_* +Class-independent data types. +.It gelf_* +For functions defined in the API set. +.El +.Ss GElf Programming APIs +This section provides an overview of the GElf programming APIs. +Further information is provided in the manual page of each function +listed here. +.Bl -tag -width indent +.It "Allocating ELF Data Structures" +.Bl -tag -compact -width indent +.It Fn gelf_newehdr +Allocate a new ELF Executable Header. +.It Fn gelf_newphdr +Allocate a new ELF Program Header Table. +.El +.It "Data Translation" +.Bl -tag -compact -width indent +.It Fn gelf_xlatetof +Translate the native representation of an ELF data structure to its +file representation. +.It Fn gelf_xlatetom +Translate from the file representation of an ELF data structure to a +native representation. +.El +.It "Retrieving ELF Data" +.Bl -tag -compact -width indent +.It Fn gelf_getdyn +Retrieve an ELF +.Sy .dynamic +table entry. +.It Fn gelf_getehdr +Retrieve an ELF Executable Header from the underlying ELF descriptor. +.It Fn gelf_getphdr +Retrieve an ELF Program Header Table entry from the underlying ELF descriptor. +.It Fn gelf_getrel +Retrieve an ELF relocation entry. +.It Fn gelf_getrela +Retrieve an ELF relocation entry with addend. +.It Fn gelf_getshdr +Retrieve an ELF Section Header Table entry from the underlying ELF descriptor. +.It Fn gelf_getsym +Retrieve an ELF symbol table entry. +.El +.It Queries +.Bl -tag -compact -width indent +.It Fn gelf_checksum +Retrieves the ELF checksum for an ELF descriptor. +.It Fn gelf_fsize +Retrieves the size of the file representation of an ELF type. +.It Fn gelf_getclass +Retrieves the ELF class of an ELF descriptor. +.El +.It "Updating ELF Data" +.Bl -tag -compact -width ".Fn gelf_update_shdr" +.It Fn gelf_update_dyn +Copy back an ELF +.Sy .dynamic +Table entry. +.It Fn gelf_update_phdr +Copy back an ELF Program Header Table entry. +.It Fn gelf_update_rel +Copy back an ELF relocation entry. +.It Fn gelf_update_rela +Copy back an ELF relocation with addend entry. +.It Fn gelf_update_shdr +Copy back an ELF Section Header Table entry. +.It Fn gelf_update_sym +Copy back an ELF symbol table entry. +.El +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf 5 +.Sh HISTORY +The +.Nm +API first appeared in +.At V.4 . +This implementation of the API first appeared in +.Fx 7.0 . +.Sh AUTHORS +The GElf API was implemented by +.An Joseph Koshy Aq Mt jkoshy@FreeBSD.org . diff --git a/contrib/elftoolchain/libelf/gelf.h b/contrib/elftoolchain/libelf/gelf.h new file mode 100644 index 0000000000..1953c7b8ee --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf.h @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: gelf.h 3174 2015-03-27 17:13:41Z emaste $ + */ + +#ifndef _GELF_H_ +#define _GELF_H_ + +#include + +typedef Elf64_Addr GElf_Addr; /* Addresses */ +typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ +typedef Elf64_Off GElf_Off; /* Offsets */ +typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ +typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ +typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ +typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ + +typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ +typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ +typedef Elf64_Phdr GElf_Phdr; /* Program header */ +typedef Elf64_Shdr GElf_Shdr; /* Section header */ +typedef Elf64_Nhdr GElf_Nhdr; /* Note header */ +typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ +typedef Elf64_Rel GElf_Rel; /* Relocation entries */ +typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ + +typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ +typedef Elf64_Move GElf_Move; /* Move entries */ +typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ + +/* Version symbol information. */ +typedef Elf64_Versym GElf_Versym; +typedef Elf64_Verdaux GElf_Verdaux; +typedef Elf64_Verdef GElf_Verdef; + +#define GELF_M_INFO ELF64_M_INFO +#define GELF_M_SIZE ELF64_M_SIZE +#define GELF_M_SYM ELF64_M_SYM + +#define GELF_R_INFO ELF64_R_INFO +#define GELF_R_SYM ELF64_R_SYM +#define GELF_R_TYPE ELF64_R_TYPE +#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA +#define GELF_R_TYPE_ID ELF64_R_TYPE_ID +#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO + +#define GELF_ST_BIND ELF64_ST_BIND +#define GELF_ST_INFO ELF64_ST_INFO +#define GELF_ST_TYPE ELF64_ST_TYPE +#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY + +#ifdef __cplusplus +extern "C" { +#endif +long gelf_checksum(Elf *_elf); +size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, + unsigned int _version); +int gelf_getclass(Elf *_elf); +GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); +GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); +GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); +GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); +GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); +GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); +GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); +GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, + int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); +void * gelf_newehdr(Elf *_elf, int _class); +void * gelf_newphdr(Elf *_elf, size_t _phnum); +int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); +int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); +int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); +int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); +int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); +int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); +int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); +int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, + int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); +Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); +Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); + +GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); +GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); +GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); +int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); +int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); +int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); + +/* Added for compatibility with libbpf */ +size_t gelf_getnote(Elf_Data *__data, size_t __offset, GElf_Nhdr *__result, size_t *__name_offset, size_t *__desc_offset); +GElf_Versym *gelf_getversym (Elf_Data *data, int ndx, GElf_Versym *dst); +GElf_Verdef *gelf_getverdef (Elf_Data *data, int offset, GElf_Verdef *dst); +GElf_Verdaux *gelf_getverdaux (Elf_Data *data, int offset, GElf_Verdaux *dst); +#ifdef __cplusplus +} +#endif + +#endif /* _GELF_H_ */ diff --git a/contrib/elftoolchain/libelf/gelf_cap.c b/contrib/elftoolchain/libelf/gelf_cap.c new file mode 100644 index 0000000000..27b05dc48b --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_cap.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_cap.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Cap * +gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Cap *cap32; + Elf64_Cap *cap64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0) + return (NULL); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; + + dst->c_tag = cap32->c_tag; + dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; + + } else { + + cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; + + *dst = *cap64; + } + + return (dst); +} + +int +gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Cap *cap32; + Elf64_Cap *cap64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gc == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0) + return (0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(cap32, gc, c_tag); + LIBELF_COPY_U32(cap32, gc, c_un.c_val); + } else { + cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; + + *cap64 = *gc; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_checksum.3 b/contrib/elftoolchain/libelf/gelf_checksum.3 new file mode 100644 index 0000000000..bc5cf5d8b6 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_checksum.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_checksum.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd August 29, 2006 +.Dt GELF_CHECKSUM 3 +.Os +.Sh NAME +.Nm elf32_checksum , +.Nm elf64_checksum , +.Nm gelf_checksum +.Nd return the checksum of an ELF object +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft long +.Fn elf32_checksum "Elf *elf" +.Ft long +.Fn elf64_checksum "Elf *elf" +.In gelf.h +.Ft long +.Fn gelf_checksum "Elf *elf" +.Sh DESCRIPTION +These functions return a simple checksum of the ELF object described +by their argument +.Fa elf . +The checksum is computed in way that allows its value to remain +unchanged in presence of modifications to the ELF object by utilities +like +.Xr strip 1 . +.Pp +Function +.Fn elf32_checksum +returns a checksum for an ELF descriptor +.Fa elf +of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_checksum +returns a checksum for an ELF descriptor +.Fa elf +of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_checksum +provides a class-independent way retrieving the checksum +for ELF object +.Fa elf . +.Sh RETURN VALUES +These functions return the checksum of the ELF object, or zero in case +an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +The ELF descriptor +.Fa elf +was not opened for reading or updating. +.It Bq Er ELF_E_CLASS +For functions +.Fn elf32_checksum +and +.Fn elf64_checksum , +ELF descriptor +.Fa elf +did not match the class of the called function. +.It Bq Er ELF_E_HEADER +The ELF object specified by argument +.Fa elf +had a malformed executable header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during processing. +.It Bq Er ELF_E_SECTION +The ELF object specified by argument +.Fa elf +contained a section with a malformed section header. +.It Bq Er ELF_E_VERSION +The ELF object was of an unsupported version. +.El +.Sh SEE ALSO +.Xr strip 1 , +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_checksum.c b/contrib/elftoolchain/libelf/gelf_checksum.c new file mode 100644 index 0000000000..a1fc87ad6f --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_checksum.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_checksum.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +long +elf32_checksum(Elf *e) +{ + return (_libelf_checksum(e, ELFCLASS32)); +} + +long +elf64_checksum(Elf *e) +{ + return (_libelf_checksum(e, ELFCLASS64)); +} + +long +gelf_checksum(Elf *e) +{ + int ec; + if (e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0L); + } + return (_libelf_checksum(e, ec)); +} diff --git a/contrib/elftoolchain/libelf/gelf_dyn.c b/contrib/elftoolchain/libelf/gelf_dyn.c new file mode 100644 index 0000000000..2edf5bb3a3 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_dyn.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_dyn.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Dyn * +gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Dyn *dyn32; + Elf64_Dyn *dyn64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; + + dst->d_tag = dyn32->d_tag; + dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; + + } else { + + dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; + + *dst = *dyn64; + } + + return (dst); +} + +int +gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Dyn *dyn32; + Elf64_Dyn *dyn64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || ds == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; + + LIBELF_COPY_S32(dyn32, ds, d_tag); + LIBELF_COPY_U32(dyn32, ds, d_un.d_val); + } else { + dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; + + *dyn64 = *ds; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_ehdr.c b/contrib/elftoolchain/libelf/gelf_ehdr.c new file mode 100644 index 0000000000..2414e718f2 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_ehdr.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_ehdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf32_Ehdr * +elf32_getehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS32, 0)); +} + +Elf64_Ehdr * +elf64_getehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS64, 0)); +} + +GElf_Ehdr * +gelf_getehdr(Elf *e, GElf_Ehdr *d) +{ + int ec; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (d == NULL || e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) + return (NULL); + + (void) memcpy(d->e_ident, eh32->e_ident, + sizeof(eh32->e_ident)); + d->e_type = eh32->e_type; + d->e_machine = eh32->e_machine; + d->e_version = eh32->e_version; + d->e_entry = eh32->e_entry; + d->e_phoff = eh32->e_phoff; + d->e_shoff = eh32->e_shoff; + d->e_flags = eh32->e_flags; + d->e_ehsize = eh32->e_ehsize; + d->e_phentsize = eh32->e_phentsize; + d->e_phnum = eh32->e_phnum; + d->e_shentsize = eh32->e_shentsize; + d->e_shnum = eh32->e_shnum; + d->e_shstrndx = eh32->e_shstrndx; + + return (d); + } + + assert(ec == ELFCLASS64); + + if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) + return (NULL); + *d = *eh64; + + return (d); +} + +Elf32_Ehdr * +elf32_newehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS32, 1)); +} + +Elf64_Ehdr * +elf64_newehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS64, 1)); +} + +void * +gelf_newehdr(Elf *e, int ec) +{ + if (e != NULL && + (ec == ELFCLASS32 || ec == ELFCLASS64)) + return (_libelf_ehdr(e, ec, 1)); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +int +gelf_update_ehdr(Elf *e, GElf_Ehdr *s) +{ + int ec; + void *ehdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (0); + + (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + eh64 = (Elf64_Ehdr *) ehdr; + *eh64 = *s; + return (1); + } + + eh32 = (Elf32_Ehdr *) ehdr; + + (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); + + eh32->e_type = s->e_type; + eh32->e_machine = s->e_machine; + eh32->e_version = s->e_version; + LIBELF_COPY_U32(eh32, s, e_entry); + LIBELF_COPY_U32(eh32, s, e_phoff); + LIBELF_COPY_U32(eh32, s, e_shoff); + eh32->e_flags = s->e_flags; + eh32->e_ehsize = s->e_ehsize; + eh32->e_phentsize = s->e_phentsize; + eh32->e_phnum = s->e_phnum; + eh32->e_shentsize = s->e_shentsize; + eh32->e_shnum = s->e_shnum; + eh32->e_shstrndx = s->e_shstrndx; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_fsize.3 b/contrib/elftoolchain/libelf/gelf_fsize.3 new file mode 100644 index 0000000000..51809fc31b --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_fsize.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_fsize.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd February 5, 2008 +.Dt GELF_FSIZE 3 +.Os +.Sh NAME +.Nm gelf_fsize , +.Nm elf32_fsize , +.Nm elf64_fsize +.Nd return the size of a file type +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft size_t +.Fn elf32_fsize "Elf_Type type" "size_t count" "unsigned int version" +.Ft size_t +.Fn elf64_fsize "Elf_Type type" "size_t count" "unsigned int version" +.In gelf.h +.Ft size_t +.Fn gelf_fsize "Elf *elf" "Elf_Type type" "size_t count" "unsigned int version" +.Sh DESCRIPTION +These functions return the size in bytes of the file representation of +.Fa count +numbers of objects of ELF type +.Fa type . +For ELF types that are of variable length, these functions return a +size of one byte. +.Pp +Functions +.Fn elf32_fsize +and +.Fn elf64_fsize +return sizes for files of class +.Dv ELFCLASS32 +and +.Dv ELFCLASS64 +respectively. +Function +.Fn gelf_fsize +returns the size for the class of ELF descriptor +.Fa elf . +.Sh RETURN VALUES +These functions return a non-zero value in case of success, or zero in +case of an error. +.Sh ERRORS +These functions may fail with: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL +in a call to +.Fn gelf_fsize . +.It Bq Er ELF_E_ARGUMENT +ELF descriptor +.Fa elf +had an unknown ELF class. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa type +contained an illegal value. +.It Bq Er ELF_E_UNIMPL +Support for ELF type +.Fa type +has not been implemented. +.It Bq Er ELF_E_VERSION +Argument +.Fa version +is not a supported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_fsize.c b/contrib/elftoolchain/libelf/gelf_fsize.c new file mode 100644 index 0000000000..b61f23c1fb --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_fsize.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_fsize.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +size_t +elf32_fsize(Elf_Type t, size_t c, unsigned int v) +{ + return (_libelf_fsize(t, ELFCLASS32, v, c)); +} + +size_t +elf64_fsize(Elf_Type t, size_t c, unsigned int v) +{ + return (_libelf_fsize(t, ELFCLASS64, v, c)); +} + +size_t +gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) +{ + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) + return (_libelf_fsize(t, e->e_class, v, c)); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); +} diff --git a/contrib/elftoolchain/libelf/gelf_getcap.3 b/contrib/elftoolchain/libelf/gelf_getcap.3 new file mode 100644 index 0000000000..4faa3747df --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getcap.3 @@ -0,0 +1,130 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getcap.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETCAP 3 +.Os +.Sh NAME +.Nm gelf_getcap , +.Nm gelf_update_cap +.Nd read and update ELF capability information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Cap *" +.Fn gelf_getcap "Elf_Data *data" "int ndx" "GElf_Cap *cap" +.Ft int +.Fn gelf_update_cap "Elf_Data *data" "int ndx" "GElf_Cap *cap" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Cap +or +.Vt Elf64_Cap +information. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_cap . +Argument +.Fa ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Cap +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getcap +retrieves the class-dependent entry at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa cap +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_cap +converts the class-independent entry pointed to +by argument +.Fa cap +to class-dependent form, and writes it to the entry at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_cap +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getcap +returns the value of argument +.Fa cap +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_cap +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa cap +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section of type +.Dv SHT_SUNW_cap . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getclass.3 b/contrib/elftoolchain/libelf/gelf_getclass.3 new file mode 100644 index 0000000000..3004ef2217 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getclass.3 @@ -0,0 +1,61 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getclass.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd July 3, 2006 +.Dt GELF_GETCLASS 3 +.Os +.Sh NAME +.Nm gelf_getclass +.Nd retrieve the class of an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft int +.Fn gelf_getclass "Elf *elf" +.Sh DESCRIPTION +Function +.Fn gelf_getclass +returns the ELF class of the descriptor supplied in argument +.Fa elf . +.Sh RETURN VALUES +Function +.Fn gelf_getclass +will return one of +.Dv ELFCLASS32 +or +.Dv ELFCLASS64 +if the argument +.Fa elf +is a descriptor for an ELF file. +The value +.Dv ELFCLASSNONE +is returned if argument +.Fa elf +was null, or if it was not a descriptor for an ELF file. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_kind 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getclass.c b/contrib/elftoolchain/libelf/gelf_getclass.c new file mode 100644 index 0000000000..6f7fd3700c --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getclass.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_getclass.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +int +gelf_getclass(Elf *e) +{ + return (e != NULL ? e->e_class : ELFCLASSNONE); +} diff --git a/contrib/elftoolchain/libelf/gelf_getdyn.3 b/contrib/elftoolchain/libelf/gelf_getdyn.3 new file mode 100644 index 0000000000..de90d1cdaa --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getdyn.3 @@ -0,0 +1,133 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getdyn.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETDYN 3 +.Os +.Sh NAME +.Nm gelf_getdyn , +.Nm gelf_update_dyn +.Nd read and update ELF dynamic entries +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Dyn *" +.Fn gelf_getdyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" +.Ft int +.Fn gelf_update_dyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Dyn +or +.Vt Elf64_Dyn +information in the +.Sy dynamic +table of an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_DYNAMIC . +Argument +.Fa ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Dyn +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getdyn +retrieves the class-dependent entry at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa dyn +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_dyn +converts the class-independent entry pointed to +by argument +.Fa dyn +to class-dependent form, and writes it to the entry at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_dyn +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getdyn +returns the value of argument +.Fa dyn +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_dyn +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa dyn +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section of type +.Dv SHT_DYNAMIC . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getehdr.3 b/contrib/elftoolchain/libelf/gelf_getehdr.3 new file mode 100644 index 0000000000..350e9c25d7 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getehdr.3 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getehdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd December 16, 2006 +.Dt GELF_GETEHDR 3 +.Os +.Sh NAME +.Nm elf32_getehdr , +.Nm elf64_getehdr , +.Nm gelf_getehdr +.Nd retrieve the object file header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Ehdr *" +.Fn elf32_getehdr "Elf *elf" +.Ft "Elf64_Ehdr *" +.Fn elf64_getehdr "Elf *elf" +.In gelf.h +.Ft "GElf_Ehdr *" +.Fn gelf_getehdr "Elf *elf" "GElf_Ehdr *dst" +.Sh DESCRIPTION +These functions retrieve the ELF object file +header from the ELF descriptor +.Fa elf +and return a translated header descriptor to their callers. +.Pp +Functions +.Fn elf32_getehdr +and +.Fn elf64_getehdr +return a pointer to the appropriate class-specific header descriptor +if it exists in the file referenced by descriptor +.Fa elf . +These functions return +.Dv NULL +if an ELF header was not found in file +.Fa elf . +.Pp +Function +.Fn gelf_getehdr +stores a translated copy of the header for ELF file +.Fa elf +into the descriptor pointed to by argument +.Fa dst . +It returns argument +.Fa dst +if successful or +.Dv NULL +in case of failure. +.Sh RETURN VALUES +These functions return a pointer to a translated header descriptor +if successful, or +.Dv NULL +on failure. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +The elf class of descriptor +.Fa elf +was not recognized. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa dst +was null. +.It Bq Er ELF_E_CLASS +The ELF class of descriptor +.Fa elf +did not match that of the API function being called. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Fa elf +does not have an associated header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during execution. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Fa elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_E_VERSION +The ELF descriptor +.Fa elf +had an unsupported ELF version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_newehdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf_flagehdr 3 , +.Xr elf_getident 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_getmove.3 b/contrib/elftoolchain/libelf/gelf_getmove.3 new file mode 100644 index 0000000000..807b5abd1e --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getmove.3 @@ -0,0 +1,129 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getmove.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETMOVE 3 +.Os +.Sh NAME +.Nm gelf_getmove , +.Nm gelf_update_move +.Nd read and update Elf Move information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Move *" +.Fn gelf_getmove "Elf_Data *data" "int ndx" "GElf_Move *move" +.Ft int +.Fn gelf_update_move "Elf_Data *data" "int ndx" "GElf_Move *move" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Move +and +.Vt Elf64_Move +structures in an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_move . +Argument +.Fa ndx +is the index of the move record being retrieved or updated. +The class-independent +.Vt GElf_Move +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getmove +retrieves class-dependent move record at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa move +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_move +converts the class-independent move information pointed to +by argument +.Fa move +to class-dependent form, and writes it to the move record at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_move +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getmove +returns the value of argument +.Fa move +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_move +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa move +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of records in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section containing move information. +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getnote.c b/contrib/elftoolchain/libelf/gelf_getnote.c new file mode 100644 index 0000000000..6537cf842c --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getnote.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2024 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include + +#include "_libelf.h" + +#define NOTE_ALIGN(n) (((n) + 3) & -4U) + +size_t gelf_getnote(Elf_Data *data, size_t offset, GElf_Nhdr *result, + size_t *name_offset, size_t *desc_offset) { + if(data == NULL || data->d_type != ELF_T_NOTE) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return 0; + } + + if(offset + sizeof(GElf_Nhdr) > data->d_size) { + LIBELF_SET_ERROR(RANGE, 0); + return 0; + } + + const GElf_Nhdr *n = data->d_buf + offset; + offset += sizeof(*n); + + GElf_Word namesz = NOTE_ALIGN(n->n_namesz); + GElf_Word descsz = NOTE_ALIGN(n->n_descsz); + + if(data->d_size - offset < descsz) { + return 0; + } + + *name_offset = offset; + offset += namesz; + + if (data->d_size - offset < descsz) { + return 0; + } + + *desc_offset = offset; + offset += descsz; + *result = *n; + + return offset; +} diff --git a/contrib/elftoolchain/libelf/gelf_getphdr.3 b/contrib/elftoolchain/libelf/gelf_getphdr.3 new file mode 100644 index 0000000000..742b6b7bfc --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getphdr.3 @@ -0,0 +1,144 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getphdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd October 21, 2007 +.Dt GELF_GETPHDR 3 +.Os +.Sh NAME +.Nm elf32_getphdr , +.Nm elf64_getphdr , +.Nm gelf_getphdr +.Nd retrieve an ELF program header table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Phdr *" +.Fn elf32_getphdr "Elf *elf" +.Ft "Elf64_Phdr *" +.Fn elf64_getphdr "Elf *elf" +.In gelf.h +.Ft "GElf_Phdr *" +.Fn gelf_getphdr "Elf *elf" "int index" "GElf_Phdr *dst" +.Sh DESCRIPTION +These functions retrieve and translate ELF program header information +from an ELF descriptor, if this information exists. +.Pp +Functions +.Fn elf32_getphdr +and +.Fn elf64_getphdr +return a pointer to an array of translated +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors respectively. +These descriptors are described in +.Xr elf 5 . +The number of entries in this array may be determined using the +.Xr elf_getphnum 3 +function. +.Pp +Function +.Fn gelf_getphdr +will retrieve the program header table entry at index +.Fa index +from ELF descriptor +.Fa elf . +The translated program header table entry will be written to the +address pointed to be argument +.Fa dst . +.Pp +Applications may inform the library of modifications to a program header table entry +by using the +.Xr elf_flagphdr 3 +API. +Applications using the +.Xr gelf 3 +interface need to use the +.Xr gelf_update_phdr 3 +API to copy modifications to a program header entry back to the underlying +ELF descriptor. +.Sh RETURN VALUES +The functions a valid pointer if successful, or +.Dv NULL +in case an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa dst +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Index +.Fa index +was out of range. +.It Bq Er ELF_E_CLASS +The class of ELF descriptor +.Fa elf +did not match the expected class of the function being called. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Fa elf +did not possess an executable header. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Fa elf +had a corrupt executable header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Fa elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_VERSION +ELF descriptor +.Fa elf +was of an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf_flagphdr 3 , +.Xr elf_getphnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr gelf_newphdr 3 , +.Xr gelf_update_phdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_getrel.3 b/contrib/elftoolchain/libelf/gelf_getrel.3 new file mode 100644 index 0000000000..77dde57d14 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getrel.3 @@ -0,0 +1,130 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getrel.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETREL 3 +.Os +.Sh NAME +.Nm gelf_getrel , +.Nm gelf_update_rel +.Nd read and update ELF relocation entries +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Rel *" +.Fn gelf_getrel "Elf_Data *data" "int ndx" "GElf_Rel *rel" +.Ft int +.Fn gelf_update_rel "Elf_Data *data" "int ndx" "GElf_Rel *rel" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Rel +or +.Vt Elf64_Rel +structures in an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_REL . +Argument +.Fa ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Rel +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getrel +retrieves the class-dependent entry at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa rel +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_rel +converts the class-independent entry pointed to +by argument +.Fa rel +to class-dependent form, and writes it to the entry at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_rel +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getrel +returns the value of argument +.Fa rel +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_rel +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa rel +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section of type +.Dv SHT_REL . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getrela.3 b/contrib/elftoolchain/libelf/gelf_getrela.3 new file mode 100644 index 0000000000..4cc2ae4e82 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getrela.3 @@ -0,0 +1,130 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getrela.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETRELA 3 +.Os +.Sh NAME +.Nm gelf_getrela , +.Nm gelf_update_rela +.Nd read and update ELF relocation entries with addends +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Rela *" +.Fn gelf_getrela "Elf_Data *data" "int ndx" "GElf_Rela *rela" +.Ft int +.Fn gelf_update_rela "Elf_Data *data" "int ndx" "GElf_Rela *rela" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Rela +or +.Vt Elf64_Rela +structures in an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_RELA . +Argument +.Fa ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Rela +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getrela +retrieves the class-dependent entry at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa rela +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_rela +converts the class-independent entry pointed to +by argument +.Fa rela +to class-dependent form, and writes it to the entry at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_rela +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getrela +returns the value of argument +.Fa rela +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_rela +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa rela +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section of type +.Dv SHT_RELA . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getshdr.3 b/contrib/elftoolchain/libelf/gelf_getshdr.3 new file mode 100644 index 0000000000..07c18160d8 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getshdr.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getshdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd August 27, 2006 +.Dt GELF_GETSHDR 3 +.Os +.Sh NAME +.Nm elf32_getshdr , +.Nm elf64_getshdr , +.Nm gelf_getshdr +.Nd retrieve the class-dependent section header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Shdr *" +.Fn elf32_getshdr "Elf_Scn *scn" +.Ft "Elf64_Shdr *" +.Fn elf64_getshdr "Elf_Scn *scn" +.In gelf.h +.Ft "GElf_Shdr *" +.Fn gelf_getshdr "Elf_Scn *scn" "GElf_Shdr *shdr" +.Sh DESCRIPTION +These functions return a pointer to the ELF Section Header data +structure associated with section descriptor +.Fa scn . +.Pp +Function +.Fn elf32_getshdr +retrieves a pointer to an +.Vt Elf32_Shdr +structure. +Section descriptor +.Fa scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_getshdr +retrieves a pointer to an +.Vt Elf64_Shdr +structure. +Section descriptor +.Fa scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_getshdr +copies the values in the section header associated with argument +.Fa scn +to the structure pointed to be argument +.Fa dst . +The +.Vt GElf_Shdr +data structure is described in +.Xr gelf 3 . +.Sh RETURN VALUES +Functions +.Fn elf32_getshdr +and +.Fn elf64_getshdr +return a valid pointer to the appropriate section header on success +or +.Dv NULL +if an error was encountered. +.Pp +Function +.Fn gelf_getshdr +returns argument +.Fa dst +if successful, or +.Dv NULL +if an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa scn +or +.Fa shdr +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa scn +was not associated a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +The ELF class associated with the section descriptor +.Fa scn +did not match the class expected by the API. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_update_shdr 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsym.3 b/contrib/elftoolchain/libelf/gelf_getsym.3 new file mode 100644 index 0000000000..55dcadbf5f --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsym.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getsym.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETSYM 3 +.Os +.Sh NAME +.Nm gelf_getsym , +.Nm gelf_update_sym +.Nd read and update symbol information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Sym *" +.Fn gelf_getsym "Elf_Data *data" "int ndx" "GElf_Sym *sym" +.Ft int +.Fn gelf_update_sym "Elf_Data *data" "int ndx" "GElf_Sym *sym" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Sym +and +.Vt Elf64_Sym +structures in an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB , +.Dv SHT_DYNSYM +or +.Dv SHT_GNU_versym . +Argument +.Fa ndx +is the index of the symbol being retrieved or updated. +The class-independent +.Vt GElf_Sym +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsym +retrieves class-dependent symbol information at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa sym +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_sym +converts the class-independent symbol information pointed to +by argument +.Fa sym +to class-dependent form, and writes it to the symbol entry at index +.Fa ndx +in the data buffer described by argument +.Fa data . +Function +.Fn gelf_update_sym +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getsym +returns the value of argument +.Fa sym +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_sym +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa sym +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of symbols in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section containing symbol information. +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsyminfo 3 , +.Xr gelf_update_syminfo 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsyminfo.3 b/contrib/elftoolchain/libelf/gelf_getsyminfo.3 new file mode 100644 index 0000000000..ca1e627c41 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsyminfo.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getsyminfo.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd April 22, 2019 +.Dt GELF_GETSYMINFO 3 +.Os +.Sh NAME +.Nm gelf_getsyminfo , +.Nm gelf_update_syminfo +.Nd read and update symbol information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Syminfo *" +.Fn gelf_getsyminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" +.Ft int +.Fn gelf_update_syminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Syminfo +and +.Vt Elf64_Syminfo +records in an ELF object. +.Pp +Argument +.Fa data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_syminfo . +Argument +.Fa ndx +is the index of the record being retrieved or updated. +The class-independent +.Vt GElf_Syminfo +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsyminfo +retrieves class-dependent record at index +.Fa ndx +in data buffer +.Fa data +and copies it to the destination pointed to by argument +.Fa syminfo +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_syminfo +converts the class-independent record pointed to +by argument +.Fa syminfo +to class-dependent form, and writes it to the record at index +.Fa ndx +in the data buffer described by argument +.Fa data . +.Sh RETURN VALUES +Function +.Fn gelf_getsyminfo +returns the value of argument +.Fa syminfo +if successful, or +.Dv NULL +in case of an error. +Function +.Fn gelf_update_syminfo +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa data +or +.Fa syminfo +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero or larger than the number of symbols in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa data +was not associated with a section containing symbol information. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Fa data +is associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsym 3 , +.Xr gelf_update_sym 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsymshndx.3 b/contrib/elftoolchain/libelf/gelf_getsymshndx.3 new file mode 100644 index 0000000000..c4ee05cbf4 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsymshndx.3 @@ -0,0 +1,192 @@ +.\" Copyright (c) 2006,2008,2020 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_getsymshndx.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd September 26, 2020 +.Dt GELF_GETSYMSHNDX 3 +.Os +.Sh NAME +.Nm gelf_getsymshndx , +.Nm gelf_update_symshndx +.Nd read and update symbol information using extended section indices +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Sym *" +.Fo gelf_getsymshndx +.Fa "Elf_Data *symdata" +.Fa "Elf_Data *xndxdata" +.Fa "int ndx" +.Fa "GElf_Sym *sym" +.Fa "Elf32_Word *xndxptr" +.Fc +.Ft int +.Fo gelf_update_symshndx +.Fa "Elf_Data *symdata" +.Fa "Elf_Data *xndxdata" +.Fa "int ndx" +.Fa "GElf_Sym *sym" +.Fa "Elf32_Word xndx" +.Fc +.Sh DESCRIPTION +These functions are analogous to +.Fn gelf_getsym +and +.Fn gelf_update_sym +respectively, but are capable of handling symbol tables using extended +section numbering. +.Pp +Argument +.Fa symdata +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB . +Argument +.Fa xndxdata +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB_SHNDX . +Argument +.Fa ndx +is the index of the symbol table entry being retrieved or updated. +Argument +.Fa sym +is a pointer to a class-independent +.Vt GElf_Sym +structure. +.Vt GElf_Sym +structures are described in detail in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsymshndx +retrieves symbol information at index +.Fa ndx +from the data descriptor specified by argument +.Fa symdata +and stores it in class-independent form in argument +.Fa sym . +Additionally: +.Bl -bullet +.It +If the arguments +.Ad xndxdata +and +.Fa xndxptr +are both not +.Dv NULL , +it retrieves the extended section index for the +symbol from the data buffer pointed to by the +argument +.Fa xndxdata +and stores it into the location pointed to by argument +.Fa xndxptr . +.It +Otherwise, if the argument +.Fa xndxptr +is not +.Dv NULL , +a value of zero is stored into the location pointed to by +argument +.Fa xndxptr . +.El +.Pp +Function +.Fn gelf_update_symshndx +updates the underlying symbol table entry in the data +descriptor +.Fa symdata +with the information in argument +.Fa sym . +In addition it sets the extended section index in +data buffer +.Fa xndxdata +to the value of argument +.Fa xndx . +.Sh RETURN VALUES +Function +.Fn gelf_getsymshndx +returns the value of argument +.Fa sym +if successful, or +.Dv NULL +in case of an error. +.Pp +Function +.Fn gelf_update_symshndx +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa symdata , +.Fa xndxdata , +.Fa xndxptr +or +.Fa sym +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +was less than zero, or too large for either of descriptors +.Fa symdata +or +.Fa xndxdata . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa symdata +was not associated with a section of type +.Dv SHT_SYMTAB . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa xndxdata +was not associated with a section of type +.Dv SHT_SYMTAB_SHNDX . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Fa symdata +and +.Fa xndxdata +were associated with different ELF objects. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptors denoted by arguments +.Fa symdata +and +.Fa xndxdata +are associated with an ELF object with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsym 3 , +.Xr gelf_update_sym 3 diff --git a/contrib/elftoolchain/libelf/gelf_move.c b/contrib/elftoolchain/libelf/gelf_move.c new file mode 100644 index 0000000000..93e92dd7b6 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_move.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_move.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Move * +gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Move *move32; + Elf64_Move *move64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + move32 = (Elf32_Move *) d->d_data.d_buf + ndx; + + dst->m_value = move32->m_value; + dst->m_info = (Elf64_Xword) move32->m_info; + dst->m_poffset = (Elf64_Xword) move32->m_poffset; + dst->m_repeat = move32->m_repeat; + dst->m_stride = move32->m_stride; + } else { + + move64 = (Elf64_Move *) d->d_data.d_buf + ndx; + + *dst = *move64; + } + + return (dst); +} + +int +gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Move *move32; + Elf64_Move *move64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gm == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + move32 = (Elf32_Move *) d->d_data.d_buf + ndx; + + move32->m_value = gm->m_value; + LIBELF_COPY_U32(move32, gm, m_info); + LIBELF_COPY_U32(move32, gm, m_poffset); + move32->m_repeat = gm->m_repeat; + move32->m_stride = gm->m_stride; + + } else { + move64 = (Elf64_Move *) d->d_data.d_buf + ndx; + + *move64 = *gm; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_newehdr.3 b/contrib/elftoolchain/libelf/gelf_newehdr.3 new file mode 100644 index 0000000000..317215f4ad --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_newehdr.3 @@ -0,0 +1,199 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_newehdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd June 12, 2019 +.Dt GELF_NEWEHDR 3 +.Os +.Sh NAME +.Nm elf32_newehdr , +.Nm elf64_newehdr , +.Nm gelf_newehdr +.Nd retrieve or allocate the object file header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Ehdr *" +.Fn elf32_newehdr "Elf *elf" +.Ft "Elf64_Ehdr *" +.Fn elf64_newehdr "Elf *elf" +.In gelf.h +.Ft "void *" +.Fn gelf_newehdr "Elf *elf" "int elfclass" +.Sh DESCRIPTION +These functions retrieve the ELF header from the ELF descriptor +.Fa elf , +allocating a new header if needed. +File data structures are translated to their in-memory representations +as described in +.Xr elf 3 . +.Pp +Function +.Fn elf32_newehdr +returns a pointer to a 32 bit +.Vt Elf32_Ehdr +structure. +Function +.Fn elf64_newehdr +returns a pointer to a 64 bit +.Vt Elf64_Ehdr +structure. +.Pp +When argument +.Fa elfclass +has value +.Dv ELFCLASS32 , +function +.Fn gelf_newehdr +returns the value returned by +.Fn elf32_newehdr "elf" . +When argument +.Fa elfclass +has value +.Dv ELFCLASS64 +it returns the value returned by +.Fn elf64_newehdr "elf" . +.Pp +If a fresh header structure is allocated, the members of the +structure are initialized as follows: +.Bl -tag -width indent +.It Va "e_ident[EI_MAG0..EI_MAG3]" +Identification bytes at offsets +.Dv EI_MAG0 , +.Dv EI_MAG1 , +.Dv EI_MAG2 +and +.Dv EI_MAG3 +are set to the ELF signature. +.It Va "e_ident[EI_CLASS]" +The identification byte at offset +.Dv EI_CLASS +is set to the ELF class associated with the function being called +or to argument +.Fa elfclass +for function +.Fn gelf_newehdr . +.It Va "e_ident[EI_DATA]" +The identification byte at offset +.Dv EI_DATA +is set to +.Dv ELFDATANONE . +.It Va "e_ident[EI_VERSION]" +The identification byte at offset +.Dv EI_VERSION +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . +.It Va e_machine +is set to +.Dv EM_NONE . +.It Va e_type +is set to +.Dv ELF_K_NONE . +.It Va e_version +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . +.El +.Pp +Other members of the header are set to zero. +The application is responsible for changing these values +as needed before calling +.Fn elf_update . +.Pp +If successful, these three functions set the +.Dv ELF_F_DIRTY +flag on ELF descriptor +.Fa elf . +.Sh RETURN VALUES +These functions return a pointer to a translated header descriptor +if successful, or +.Dv NULL +on failure. +.Sh COMPATIBILITY +The +.Fn gelf_newehdr +function uses a type of +.Ft "void *" +for its returned value. +This differs from some other implementations of the +.Xr elf 3 +API, which use an +.Ft "unsigned long" +return type. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Fa elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elfclass +had an unsupported value. +.It Bq Er ELF_E_ARGUMENT +The class of the ELF descriptor +.Fa elf +did not match that of the requested operation. +.It Bq Er ELF_E_ARGUMENT +For function +.Fn gelf_newehdr , +the class of argument +.Fa elf +was not +.Dv ELFCLASSNONE +and did not match the argument +.Fa elfclass . +.It Bq Er ELF_E_CLASS +The ELF class of descriptor +.Fa elf +did not match that of the API function being called. +.It Bq Er ELF_E_HEADER +A malformed ELF header was detected. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during execution. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Fa elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_E_VERSION +The ELF descriptor +.Fa elf +had an unsupported ELF version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_flagdata 3 , +.Xr elf_getident 3 , +.Xr elf_update 3 , +.Xr elf_version 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_newphdr.3 b/contrib/elftoolchain/libelf/gelf_newphdr.3 new file mode 100644 index 0000000000..d882cc888d --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_newphdr.3 @@ -0,0 +1,146 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_newphdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd June 12, 2019 +.Dt GELF_NEWPHDR 3 +.Os +.Sh NAME +.Nm elf32_newphdr , +.Nm elf64_newphdr , +.Nm gelf_newphdr +.Nd allocate an ELF program header table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Phdr *" +.Fn elf32_newphdr "Elf *elf" "size_t count" +.Ft "Elf64_Phdr *" +.Fn elf64_newphdr "Elf *elf" "size_t count" +.In gelf.h +.Ft "void *" +.Fn gelf_newphdr "Elf *elf" "size_t count" +.Sh DESCRIPTION +These functions allocate an ELF Program Header table +for an ELF descriptor. +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors are described further in +.Xr elf 5 . +.Pp +Functions +.Fn elf32_newphdr +and +.Fn elf64_newphdr +allocate a table of +.Fa count +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors respectively, +discarding any existing program header table +already present in the ELF descriptor +.Fa elf . +A value of zero for argument +.Fa count +may be used to delete an existing program header table +from an ELF descriptor. +.Pp +Function +.Fn gelf_newphdr +will return a table of +.Vt Elf32_Phdr +or +.Vt Elf64_Phdr +with +.Fa count +elements depending on the ELF class of ELF descriptor +.Fa elf . +.Pp +The functions set the +.Dv ELF_F_DIRTY +flag on the program header table. +All members of the returned array of Phdr structures +will be initialized to zero. +.Pp +After a successful call to these functions, the pointer returned +by a prior call to +.Fn elf32_getphdr +or +.Fn elf64_getphdr +on the same descriptor +.Fa elf +will no longer be valid. +.Sh RETURN VALUES +The functions a valid pointer if successful, or +.Dv NULL +in case an error was encountered. +.Sh COMPATIBILITY +The +.Fn gelf_newphdr +function uses a type of +.Ft "void *" +for its returned value. +This differs from some other implementations of the +.Xr elf 3 +API, which use an +.Ft "unsigned long" +return type. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +ELF descriptor +.Fa elf +was of an unrecognized class. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SEQUENCE +An executable header was not allocated for ELF descriptor +.Fa elf +before using these APIs. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getphdr 3 , +.Xr elf32_newehdr 3 , +.Xr elf64_getphdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf_flagphdr 3 , +.Xr elf_getphnum 3 , +.Xr gelf 3 , +.Xr gelf_getphdr 3 , +.Xr gelf_newehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_phdr.c b/contrib/elftoolchain/libelf/gelf_phdr.c new file mode 100644 index 0000000000..b6a8627b83 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_phdr.c @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_phdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf32_Phdr * +elf32_getphdr(Elf *e) +{ + return (_libelf_getphdr(e, ELFCLASS32)); +} + +Elf64_Phdr * +elf64_getphdr(Elf *e) +{ + return (_libelf_getphdr(e, ELFCLASS64)); +} + +GElf_Phdr * +gelf_getphdr(Elf *e, int index, GElf_Phdr *d) +{ + int ec; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + Elf32_Phdr *ep32; + Elf64_Phdr *ep64; + size_t phnum; + + if (d == NULL || e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + (e->e_kind != ELF_K_ELF) || index < 0 || + elf_getphdrnum(e, &phnum) < 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((size_t)index >= phnum) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || + ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) + return (NULL); + + ep32 += index; + + d->p_type = ep32->p_type; + d->p_offset = ep32->p_offset; + d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; + d->p_paddr = (Elf64_Addr) ep32->p_paddr; + d->p_filesz = (Elf64_Xword) ep32->p_filesz; + d->p_memsz = (Elf64_Xword) ep32->p_memsz; + d->p_flags = ep32->p_flags; + d->p_align = (Elf64_Xword) ep32->p_align; + + } else { + if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || + (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) + return (NULL); + + ep64 += index; + + *d = *ep64; + } + + return (d); +} + +Elf32_Phdr * +elf32_newphdr(Elf *e, size_t count) +{ + return (_libelf_newphdr(e, ELFCLASS32, count)); +} + +Elf64_Phdr * +elf64_newphdr(Elf *e, size_t count) +{ + return (_libelf_newphdr(e, ELFCLASS64, count)); +} + +void * +gelf_newphdr(Elf *e, size_t count) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + return (_libelf_newphdr(e, e->e_class, count)); +} + +int +gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) +{ + int ec; + size_t phnum; + void *ehdr; + Elf32_Phdr *ph32; + Elf64_Phdr *ph64; + + if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + elf_getphdrnum(e, &phnum) < 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (0); + + if (ndx < 0 || (size_t)ndx > phnum) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; + *ph64 = *s; + return (1); + } + + ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; + + ph32->p_type = s->p_type; + ph32->p_flags = s->p_flags; + LIBELF_COPY_U32(ph32, s, p_offset); + LIBELF_COPY_U32(ph32, s, p_vaddr); + LIBELF_COPY_U32(ph32, s, p_paddr); + LIBELF_COPY_U32(ph32, s, p_filesz); + LIBELF_COPY_U32(ph32, s, p_memsz); + LIBELF_COPY_U32(ph32, s, p_align); + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_rel.c b/contrib/elftoolchain/libelf/gelf_rel.c new file mode 100644 index 0000000000..788589fd2e --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_rel.c @@ -0,0 +1,166 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_rel.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Rel * +gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rel *rel32; + Elf64_Rel *rel64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; + + dst->r_offset = (Elf64_Addr) rel32->r_offset; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rel32->r_info), + ELF32_R_TYPE(rel32->r_info)); + + } else { + + rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; + + *dst = *rel64; + } + + return (dst); +} + +int +gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rel *rel32; + Elf64_Rel *rel64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dr == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(rel32, dr, r_offset); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rel32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); + } else { + rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; + + *rel64 = *dr; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_rela.c b/contrib/elftoolchain/libelf/gelf_rela.c new file mode 100644 index 0000000000..f6e825e0ae --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_rela.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_rela.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Rela * +gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rela *rela32; + Elf64_Rela *rela64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; + + dst->r_offset = (Elf64_Addr) rela32->r_offset; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rela32->r_info), + ELF32_R_TYPE(rela32->r_info)); + dst->r_addend = (Elf64_Sxword) rela32->r_addend; + + } else { + + rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; + + *dst = *rela64; + } + + return (dst); +} + +int +gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rela *rela32; + Elf64_Rela *rela64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dr == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(rela32, dr, r_offset); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rela32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); + + LIBELF_COPY_S32(rela32, dr, r_addend); + } else { + rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; + + *rela64 = *dr; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_shdr.c b/contrib/elftoolchain/libelf/gelf_shdr.c new file mode 100644 index 0000000000..0d1acae8ef --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_shdr.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_shdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf32_Shdr * +elf32_getshdr(Elf_Scn *s) +{ + return (_libelf_getshdr(s, ELFCLASS32)); +} + +Elf64_Shdr * +elf64_getshdr(Elf_Scn *s) +{ + return (_libelf_getshdr(s, ELFCLASS64)); +} + +GElf_Shdr * +gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) +{ + int ec; + void *sh; + Elf32_Shdr *sh32; + Elf64_Shdr *sh64; + + if (d == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) + return (NULL); + + ec = s->s_elf->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) { + sh32 = (Elf32_Shdr *) sh; + + d->sh_name = sh32->sh_name; + d->sh_type = sh32->sh_type; + d->sh_flags = (Elf64_Xword) sh32->sh_flags; + d->sh_addr = (Elf64_Addr) sh32->sh_addr; + d->sh_offset = (Elf64_Off) sh32->sh_offset; + d->sh_size = (Elf64_Xword) sh32->sh_size; + d->sh_link = sh32->sh_link; + d->sh_info = sh32->sh_info; + d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; + d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; + } else { + sh64 = (Elf64_Shdr *) sh; + *d = *sh64; + } + + return (d); +} + +int +gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) +{ + int ec; + Elf *e; + Elf32_Shdr *sh32; + + + if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || + e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + scn->s_shdr.s_shdr64 = *s; + return (1); + } + + sh32 = &scn->s_shdr.s_shdr32; + + sh32->sh_name = s->sh_name; + sh32->sh_type = s->sh_type; + LIBELF_COPY_U32(sh32, s, sh_flags); + LIBELF_COPY_U32(sh32, s, sh_addr); + LIBELF_COPY_U32(sh32, s, sh_offset); + LIBELF_COPY_U32(sh32, s, sh_size); + sh32->sh_link = s->sh_link; + sh32->sh_info = s->sh_info; + LIBELF_COPY_U32(sh32, s, sh_addralign); + LIBELF_COPY_U32(sh32, s, sh_entsize); + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_sym.c b/contrib/elftoolchain/libelf/gelf_sym.c new file mode 100644 index 0000000000..18d9e303b4 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_sym.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_sym.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Sym * +gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Sym *sym32; + Elf64_Sym *sym64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; + + dst->st_name = sym32->st_name; + dst->st_value = (Elf64_Addr) sym32->st_value; + dst->st_size = (Elf64_Xword) sym32->st_size; + dst->st_info = sym32->st_info; + dst->st_other = sym32->st_other; + dst->st_shndx = sym32->st_shndx; + } else { + sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; + + *dst = *sym64; + } + + return (dst); +} + +int +gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Sym *sym32; + Elf64_Sym *sym64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gs == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; + + sym32->st_name = gs->st_name; + sym32->st_info = gs->st_info; + sym32->st_other = gs->st_other; + sym32->st_shndx = gs->st_shndx; + + LIBELF_COPY_U32(sym32, gs, st_value); + LIBELF_COPY_U32(sym32, gs, st_size); + } else { + sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; + + *sym64 = *gs; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_syminfo.c b/contrib/elftoolchain/libelf/gelf_syminfo.c new file mode 100644 index 0000000000..c46d80a69c --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_syminfo.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_syminfo.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Syminfo * +gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *d; + Elf32_Syminfo *syminfo32; + Elf64_Syminfo *syminfo64; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; + + dst->si_boundto = syminfo32->si_boundto; + dst->si_flags = syminfo32->si_flags; + + } else { + + syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; + + *dst = *syminfo64; + } + + return (dst); +} + +int +gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *d; + Elf32_Syminfo *syminfo32; + Elf64_Syminfo *syminfo64; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gs == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; + + syminfo32->si_boundto = gs->si_boundto; + syminfo32->si_flags = gs->si_flags; + + } else { + syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; + + *syminfo64 = *gs; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_symshndx.c b/contrib/elftoolchain/libelf/gelf_symshndx.c new file mode 100644 index 0000000000..6005f469df --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_symshndx.c @@ -0,0 +1,148 @@ +/*- + * Copyright (c) 2006,2008,2020 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_symshndx.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +GElf_Sym * +gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, + Elf32_Word *shindex) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *ld, *lid; + + ld = (struct _Libelf_Data *) d; + lid = (struct _Libelf_Data *) id; + + if (gelf_getsym(d, ndx, dst) == 0) + return (NULL); + + if (shindex == NULL) + return (dst); + + if (lid == NULL) { + *shindex = 0; + return (dst); + } + + if ((scn = lid->d_scn) == NULL || + (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || + id->d_type != ELF_T_WORD) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0) + return (NULL); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= id->d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + *shindex = ((Elf32_Word *) id->d_buf)[ndx]; + + return (dst); +} + +int +gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, + Elf32_Word xindex) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *ld, *lid; + + ld = (struct _Libelf_Data *) d; + lid = (struct _Libelf_Data *) id; + + if (gelf_update_sym(d, ndx, gs) == 0) + return (0); + + if (lid == NULL || (scn = lid->d_scn) == NULL || + (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || + d->d_type != ELF_T_WORD) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0) + return (0); + + assert(ndx >= 0); + + if (msz * (size_t) ndx >= id->d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + *(((Elf32_Word *) id->d_buf) + ndx) = xindex; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_update_ehdr.3 b/contrib/elftoolchain/libelf/gelf_update_ehdr.3 new file mode 100644 index 0000000000..82987c8c29 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_update_ehdr.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_update_ehdr.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd August 27, 2006 +.Dt GELF_UPDATE_EHDR 3 +.Os +.Sh NAME +.Nm gelf_update_ehdr , +.Nm gelf_update_phdr , +.Nm gelf_update_shdr +.Nd update underlying ELF data structures +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft int +.Fn gelf_update_ehdr "Elf *elf" "GElf_Ehdr *ehdr" +.Ft int +.Fn gelf_update_phdr "Elf *elf" "int ndx" "GElf_Phdr *phdr" +.Ft int +.Fn gelf_update_shdr "Elf_Scn *scn" "GElf_Shdr *shdr" +.Sh DESCRIPTION +These functions are used to update ELF data structures on the underlying +ELF descriptor. +Class-dependent data structures in the underlying ELF descriptor +are updated using the data in the class-independent GElf descriptors +and the underlying ELF data structures are marked +.Dq dirty . +The conversion process signals an error if the values being copied +to the target ELF data structure would exceed representation +limits. +GElf descriptors are described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_update_ehdr +updates the ELF Executable Header with the values in the +class-independent executable header +.Fa ehdr . +.Pp +Function +.Fn gelf_update_phdr +updates the ELF Program Header structure at index +.Fa ndx +with the values in the class-independent program header +.Fa phdr . +.Pp +Function +.Fn gelf_update_shdr +updates the ELF Section Header structure associated with section +descriptor +.Fa scn +with the values in argument +.Fa shdr . +.Sh RETURN VALUES +These functions return a non-zero integer on success, or zero in case +of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa elf , +.Fa ehdr , +.Fa phdr , +.Fa scn , +or +.Fa shdr +were +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa elf +had an unsupported ELF class. +.It Bq Er ELF_E_ARGUMENT +Argument +.Fa ndx +exceeded the number of entries in the program header table. +.It Bq Er ELF_E_ARGUMENT +Section descriptor +.Fa scn +was not associated with an ELF descriptor. +.It Bq Er ELF_E_MODE +ELF descriptor +.Fa elf +was not opened for writing or updating. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagelf 3 , +.Xr elf_flagphdr 3 , +.Xr elf_flagshdr 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr gelf_getphdr 3 , +.Xr gelf_getshdr 3 diff --git a/contrib/elftoolchain/libelf/gelf_versym.c b/contrib/elftoolchain/libelf/gelf_versym.c new file mode 100644 index 0000000000..2e949203e3 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_versym.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2024 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include +#include +#include + +#include "_libelf.h" + +GElf_Versym * +gelf_getversym(Elf_Data *data, int ndx, GElf_Versym *dst) +{ + GElf_Versym *result; + + if (data == NULL || data->d_type != ELF_T_HALF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (((ndx + 1) * sizeof(GElf_Versym) > data->d_size)) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + *dst = ((GElf_Versym *) data->d_buf)[ndx]; + + result = dst; + return result; +} + +GElf_Verdef * +gelf_getverdef(Elf_Data *data, int offset, GElf_Verdef *dst) +{ + GElf_Verdef *result; + + if (data == NULL || data->d_type != ELF_T_VDEF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if((offset < 0) + || (offset + sizeof(GElf_Verdef) > data->d_size) + || (offset % __alignof__(GElf_Verdef) != 0)) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + result = (GElf_Verdef *) memcpy(dst, (char *) data->d_buf + offset, sizeof(GElf_Verdef)); + + return result; +} + +GElf_Verdaux * +gelf_getverdaux (Elf_Data *data, int offset, GElf_Verdaux *dst) +{ + if (data == NULL || data->d_type != ELF_T_VDEF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if((offset < 0) + || (offset + sizeof(GElf_Verdaux) > data->d_size) + || (offset % __alignof__ (GElf_Verdaux) != 0)) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + GElf_Verdaux *result; + result = (GElf_Verdaux *) memcpy(dst, (char *) data->d_buf + offset, sizeof(GElf_Verdaux)); + + return result; +} diff --git a/contrib/elftoolchain/libelf/gelf_xlate.c b/contrib/elftoolchain/libelf/gelf_xlate.c new file mode 100644 index 0000000000..27370a6ae1 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_xlate.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2006,2008,2018 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_xlate.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf_Data * +elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS32, EM_NONE, + ELF_TOFILE); +} + +Elf_Data * +elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS64, EM_NONE, + ELF_TOFILE); +} + +Elf_Data * +elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS32, EM_NONE, + ELF_TOMEMORY); +} + +Elf_Data * +elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS64, EM_NONE, + ELF_TOMEMORY); +} + +Elf_Data * +gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, + unsigned int encoding) +{ + if (e != NULL) + return (_libelf_xlate(dst, src, encoding, e->e_class, + _libelf_elfmachine(e), ELF_TOMEMORY)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +Elf_Data * +gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, + unsigned int encoding) +{ + if (e != NULL) + return (_libelf_xlate(dst, src, encoding, e->e_class, + _libelf_elfmachine(e), ELF_TOFILE)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/gelf_xlatetof.3 b/contrib/elftoolchain/libelf/gelf_xlatetof.3 new file mode 100644 index 0000000000..e6d3e8d168 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_xlatetof.3 @@ -0,0 +1,280 @@ +.\" Copyright (c) 2006,2008,2018 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: gelf_xlatetof.3 3958 2022-03-12 14:31:32Z jkoshy $ +.\" +.Dd October 11, 2018 +.Dt GELF_XLATETOF 3 +.Os +.Sh NAME +.Nm elf32_xlate , +.Nm elf64_xlate , +.Nm gelf_xlate +.Nd translate data between files and memory +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Data *" +.Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" +.Ft "Elf_Data *" +.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" +.Ft "Elf_Data *" +.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" +.Ft "Elf_Data *" +.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" +.In gelf.h +.Ft "Elf_Data *" +.Fo gelf_xlatetof +.Fa "Elf *elf" +.Fa "Elf_Data *dst" +.Fa "Elf_Data *src" +.Fa "unsigned int file_encoding" +.Fc +.Ft "Elf_Data *" +.Fo gelf_xlatetom +.Fa "Elf *elf" +.Fa "Elf_Data *dst" +.Fa "Elf_Data *src" +.Fa "unsigned int file_encoding" +.Fc +.Sh DESCRIPTION +These functions translate between the file and memory representations +of ELF data structures. +The in-memory representation of an ELF data structure would conform to +the byte ordering and data alignment restrictions dictated by the host +processor. +As described in +.Xr elf 3 , +the file representation of this data structure could use a different byte +ordering from that of the host, or could use a different layout within +the file. +.Pp +Functions +.Fn elf32_xlatetom , +.Fn elf64_xlatetom , +and +.Fn gelf_xlatetom +translate data from file representations to native, in-memory representations. +Functions +.Fn elf32_xlatetof , +.Fn elf64_xlatetof , +and +.Fn gelf_xlatetof +translate data from in-memory representations to file representations. +.Pp +Argument +.Fa src +denotes an +.Vt Elf_Data +descriptor describing the source to be translated. +The following elements of the descriptor need to be set before +invoking these functions: +.Bl -hang -offset indent +.It Va d_buf +Set to a valid pointer value denoting the beginning of the data area +to be translated. +.It Va d_size +Set to the total size in bytes of the source data area to be +translated. +.It Va d_type +Set to the type of the source data being translated. +This value is one of the values defined in the +.Vt Elf_Type +enumeration. +The +.Vt Elf_Type +enumeration is described in +.Xr elf 3 . +.It Va d_version +Set to the version number of the ELF data structures being +translated. +Currently only version +.Dv EV_CURRENT +is supported. +.El +.Pp +Argument +.Fa dst +describes the destination buffer. +The following elements of the +.Vt Elf_Data +descriptor need to be set before invoking these functions: +.Bl -hang -offset indent +.It Va d_buf +Set to a valid pointer value that denotes the start of the destination +buffer that will hold translated data. +This value may be the same as that of the source buffer, in which case +an in-place conversion will be attempted. +.It Va d_size +Set to the size of the destination buffer in bytes. +This value will be modified if the function call succeeds. +.It Va d_version +Set to the desired version number of the destination. +Currently only version +.Dv EV_CURRENT +is supported. +.El +.Pp +These translations routines allow the source and destination buffers +to coincide, in which case an in-place translation will be done +if the destination is large enough to hold the translated data. +Other kinds of overlap between the source and destination buffers +are not permitted. +.Pp +On successful completion of the translation request the following +fields of the +.Fa dst +descriptor would be modified: +.Bl -hang -offset indent +.It Va d_size +Set to the size in bytes of the translated data. +.It Va d_type +Set to the +.Va d_type +value of the source data descriptor. +.El +.Pp +Argument +.Fa file_encoding +specifies the encoding in which the file objects are represented. +It must be one of: +.Bl -hang -offset indent +.It Dv ELFDATANONE +File objects use the library's native byte ordering. +.It Dv ELFDATA2LSB +File objects use a little-endian ordering. +.It Dv ELFDATA2MSB +File objects use a big-endian ordering. +.El +.Pp +The functions +.Fn gelf_xlatetof +and +.Fn gelf_xlatetom +select the appropriate translation scheme based on the properties of +argument +.Fa elf . +.Sh RETURN VALUES +These functions return argument +.Fa dst +if successful, or +.Dv NULL +in case of an error. +.Sh EXAMPLES +To translate a +.Vt GElf_Rel +structure to its LSB file representation use: +.Bd -literal -offset indent +Elf_Data dst, src; +GElf_Rel rel; +Elf *e; + +e = ...; /* See elf_begin(3). */ + +/* Set up the 'src' descriptor. */ +memset(&src, 0, sizeof src); +src.d_buf = &rel; +src.d_size = sizeof(rel); +src.d_type = ELF_T_REL; +src.d_version = EV_CURRENT; + +/* Set up the 'dst' descriptor. */ +memset(&dst, 0, sizeof dst); +dst.d_buf = filebuf; +dst.d_size = gelf_fsize(e, ELF_T_REL, 1, EV_CURRENT); +dst.d_version = EV_CURRENT; + +if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) == NULL) { + printf("error: %s", elf_errmsg(0)); +} +.Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +One of arguments +.Fa src , +.Fa dst +or +.Fa elf +was +.Dv NULL . +.It Bq Er ELF_E_ARGUMENT +Arguments +.Fa src +and +.Fa dst +were equal. +.It Bq Er ELF_E_ARGUMENT +The desired encoding parameter was not one of +.Dv ELFDATANONE , +.Dv ELFDATA2LSB +or +.Dv ELFDATA2MSB . +.It Bq Er ELF_E_ARGUMENT +The +.Fa d_type +field of argument +.Fa src +specified an unsupported type. +.It Bq Er ELF_E_DATA +The +.Fa src +argument specified a buffer size that was not an integral multiple of +its underlying type. +.It Bq Er ELF_E_DATA +The +.Fa dst +argument specified a buffer size that was too small. +.It Bq Er ELF_E_DATA +Argument +.Fa dst +specified a destination buffer that overlaps with the source +buffer. +.It Bq Er ELF_E_DATA +The destination buffer for a conversion to memory had an alignment +inappropriate for the underlying ELF type. +.It Bq Er ELF_E_DATA +The source buffer for a conversion to file had an alignment +inappropriate for the underlying ELF type. +.It Bq Er ELF_E_UNIMPL +The version numbers for arguments +.Fa dst +and +.Fa src +were not identical. +.It Bq Er ELF_E_UNIMPL +The argument +.Fa src +requested conversion for a type which is not currently +supported. +.It Bq Er ELF_E_VERSION +Argument +.Fa src +specified an unsupported version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/libelf.h b/contrib/elftoolchain/libelf/libelf.h new file mode 100644 index 0000000000..4353e7ca32 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf.h @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2006,2008-2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: libelf.h 3984 2022-05-06 11:22:42Z jkoshy $ + */ + +#ifndef _LIBELF_H_ +#define _LIBELF_H_ + +#include + +#include + +#include "elfdefinitions.h" + +/* Library private data structures */ +typedef struct _Elf Elf; +typedef struct _Elf_Scn Elf_Scn; + +/* File types */ +typedef enum { + ELF_K_NONE = 0, + ELF_K_AR, /* `ar' archives */ + ELF_K_COFF, /* COFF files (unsupported) */ + ELF_K_ELF, /* ELF files */ + ELF_K_NUM +} Elf_Kind; + +#define ELF_K_FIRST ELF_K_NONE +#define ELF_K_LAST ELF_K_NUM + +/* Data types */ +typedef enum { + ELF_T_ADDR, + ELF_T_BYTE, + ELF_T_CAP, + ELF_T_DYN, + ELF_T_EHDR, + ELF_T_HALF, + ELF_T_LWORD, + ELF_T_MOVE, + ELF_T_MOVEP, + ELF_T_NOTE, + ELF_T_OFF, + ELF_T_PHDR, + ELF_T_REL, + ELF_T_RELA, + ELF_T_SHDR, + ELF_T_SWORD, + ELF_T_SXWORD, + ELF_T_SYMINFO, + ELF_T_SYM, + ELF_T_VDEF, + ELF_T_VNEED, + ELF_T_WORD, + ELF_T_XWORD, + ELF_T_GNUHASH, /* GNU style hash tables. */ + ELF_T_NUM +} Elf_Type; + +#define ELF_T_FIRST ELF_T_ADDR +#define ELF_T_LAST ELF_T_GNUHASH + +/* Commands */ +typedef enum { + ELF_C_NULL = 0, + ELF_C_CLR, + ELF_C_FDDONE, + ELF_C_FDREAD, + ELF_C_RDWR, + ELF_C_READ, + ELF_C_SET, + ELF_C_WRITE, + ELF_C_NUM +} Elf_Cmd; + +#define ELF_C_FIRST ELF_C_NULL +#define ELF_C_LAST ELF_C_NUM + +/* + * An `Elf_Data' structure describes data in an + * ELF section. + */ +typedef struct _Elf_Data { + /* + * `Public' members that are part of the ELF(3) API. + */ + uint64_t d_align; + void *d_buf; + uint64_t d_off; + uint64_t d_size; + Elf_Type d_type; + unsigned int d_version; +} Elf_Data; + +/* + * An `Elf_Arhdr' structure describes an archive + * header. + */ +typedef struct { + time_t ar_date; + char *ar_name; /* archive member name */ + gid_t ar_gid; + mode_t ar_mode; + char *ar_rawname; /* 'raw' member name */ + size_t ar_size; + uid_t ar_uid; + + /* + * Members that are not part of the public API. + */ + unsigned int ar_flags; +} Elf_Arhdr; + +/* + * An `Elf_Arsym' describes an entry in the archive + * symbol table. + */ +typedef struct { + off_t as_off; /* byte offset to member's header */ + unsigned long as_hash; /* elf_hash() value for name */ + char *as_name; /* null terminated symbol name */ +} Elf_Arsym; + +/* + * Error numbers. + */ + +enum Elf_Error { + ELF_E_NONE, /* No error */ + ELF_E_ARCHIVE, /* Malformed ar(1) archive */ + ELF_E_ARGUMENT, /* Invalid argument */ + ELF_E_CLASS, /* Mismatched ELF class */ + ELF_E_DATA, /* Invalid data descriptor */ + ELF_E_HEADER, /* Missing or malformed ELF header */ + ELF_E_IO, /* I/O error */ + ELF_E_LAYOUT, /* Layout constraint violation */ + ELF_E_MODE, /* Wrong mode for ELF descriptor */ + ELF_E_RANGE, /* Value out of range */ + ELF_E_RESOURCE, /* Resource exhaustion */ + ELF_E_SECTION, /* Invalid section descriptor */ + ELF_E_SEQUENCE, /* API calls out of sequence */ + ELF_E_UNIMPL, /* Feature is unimplemented */ + ELF_E_VERSION, /* Unknown API version */ + ELF_E_NUM /* Max error number */ +}; + +/* + * Flags defined by the API. + */ + +#define ELF_F_LAYOUT 0x001U /* application will layout the file */ +#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ + +/* ELF(3) API extensions. */ +#define ELF_F_ARCHIVE 0x100U /* archive creation */ +#define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */ + +#ifdef __cplusplus +extern "C" { +#endif +Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); +int elf_cntl(Elf *_elf, Elf_Cmd _cmd); +int elf_end(Elf *_elf); +const char *elf_errmsg(int _error); +int elf_errno(void); +void elf_fill(int _fill); +unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd, + unsigned int _flags); +unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, + unsigned int _flags); +unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); +Elf_Arhdr *elf_getarhdr(Elf *_elf); +Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); +off_t elf_getbase(Elf *_elf); +Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); +char *elf_getident(Elf *_elf, size_t *_ptr); +int elf_getphdrnum(Elf *_elf, size_t *_dst); +int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ +Elf_Scn *elf_getscn(Elf *_elf, size_t _index); +int elf_getshdrnum(Elf *_elf, size_t *_dst); +int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ +int elf_getshdrstrndx(Elf *_elf, size_t *_dst); +int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ +unsigned int elf_getversion(Elf *_elf); +unsigned long elf_hash(const char *_name); +Elf_Kind elf_kind(Elf *_elf); +Elf *elf_memory(char *_image, size_t _size); +size_t elf_ndxscn(Elf_Scn *_scn); +Elf_Data *elf_newdata(Elf_Scn *_scn); +Elf_Scn *elf_newscn(Elf *_elf); +Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); +Elf_Cmd elf_next(Elf *_elf); +/* Elf *elf_open(int _fd); */ /* removed due to incompatibility with libbpf */ +Elf *elf_openmemory(char *_image, size_t _size); +off_t elf_rand(Elf *_elf, off_t _off); +Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); +char *elf_rawfile(Elf *_elf, size_t *_size); +int elf_setshstrndx(Elf *_elf, size_t _shnum); +char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); +off_t elf_update(Elf *_elf, Elf_Cmd _cmd); +unsigned int elf_version(unsigned int _version); + +long elf32_checksum(Elf *_elf); +size_t elf32_fsize(Elf_Type _type, size_t _count, + unsigned int _version); +Elf32_Ehdr *elf32_getehdr(Elf *_elf); +Elf32_Phdr *elf32_getphdr(Elf *_elf); +Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); +Elf32_Ehdr *elf32_newehdr(Elf *_elf); +Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); +Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); + +long elf64_checksum(Elf *_elf); +size_t elf64_fsize(Elf_Type _type, size_t _count, + unsigned int _version); +Elf64_Ehdr *elf64_getehdr(Elf *_elf); +Elf64_Phdr *elf64_getphdr(Elf *_elf); +Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); +Elf64_Ehdr *elf64_newehdr(Elf *_elf); +Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); +Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +#ifdef __cplusplus +} +#endif + +#endif /* _LIBELF_H_ */ diff --git a/contrib/elftoolchain/libelf/libelf_align.c b/contrib/elftoolchain/libelf/libelf_align.c new file mode 100644 index 0000000000..6be6e46993 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_align.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_align.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +struct align { + unsigned int a32; + unsigned int a64; +}; + +#ifdef __GNUC__ +#define MALIGN(N) { \ + .a32 = __alignof__(Elf32_##N), \ + .a64 = __alignof__(Elf64_##N) \ + } +#define MALIGN64(V) { \ + .a32 = 0, \ + .a64 = __alignof__(Elf64_##V) \ + } +#define MALIGN_WORD() { \ + .a32 = __alignof__(int32_t), \ + .a64 = __alignof__(int64_t) \ + } +#elif defined(__lint__) +#define MALIGN(N) { .a32 = 0, .a64 = 0 } +#define MALIGN64(N) { .a32 = 0, .a64 = 0 } +#define MALIGN_WORD(N) { .a32 = 0, .a64 = 0 } +#else +#error Need the __alignof__ builtin. +#endif +#define UNSUPPORTED() { \ + .a32 = 0, \ + .a64 = 0 \ + } + +static struct align malign[ELF_T_NUM] = { + [ELF_T_ADDR] = MALIGN(Addr), + [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, + [ELF_T_CAP] = MALIGN(Cap), + [ELF_T_DYN] = MALIGN(Dyn), + [ELF_T_EHDR] = MALIGN(Ehdr), + [ELF_T_HALF] = MALIGN(Half), + [ELF_T_LWORD] = MALIGN(Lword), + [ELF_T_MOVE] = MALIGN(Move), + [ELF_T_MOVEP] = UNSUPPORTED(), + [ELF_T_NOTE] = MALIGN(Nhdr), + [ELF_T_OFF] = MALIGN(Off), + [ELF_T_PHDR] = MALIGN(Phdr), + [ELF_T_REL] = MALIGN(Rel), + [ELF_T_RELA] = MALIGN(Rela), + [ELF_T_SHDR] = MALIGN(Shdr), + [ELF_T_SWORD] = MALIGN(Sword), + [ELF_T_SXWORD] = MALIGN64(Sxword), + [ELF_T_SYM] = MALIGN(Sym), + [ELF_T_SYMINFO] = MALIGN(Syminfo), + [ELF_T_VDEF] = MALIGN(Verdef), + [ELF_T_VNEED] = MALIGN(Verneed), + [ELF_T_WORD] = MALIGN(Word), + [ELF_T_XWORD] = MALIGN64(Xword), + [ELF_T_GNUHASH] = MALIGN_WORD() +}; + +unsigned int +_libelf_malign(Elf_Type t, int elfclass) +{ + if (t >= ELF_T_NUM || (int) t < 0) + return (0); + + return (elfclass == ELFCLASS32 ? malign[t].a32 : + malign[t].a64); +} + +#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } + +static struct align falign[ELF_T_NUM] = { + [ELF_T_ADDR] = FALIGN(4,8), + [ELF_T_BYTE] = FALIGN(1,1), + [ELF_T_CAP] = FALIGN(4,8), + [ELF_T_DYN] = FALIGN(4,8), + [ELF_T_EHDR] = FALIGN(4,8), + [ELF_T_HALF] = FALIGN(2,2), + [ELF_T_LWORD] = FALIGN(8,8), + [ELF_T_MOVE] = FALIGN(8,8), + [ELF_T_MOVEP] = UNSUPPORTED(), + [ELF_T_NOTE] = FALIGN(4,4), + [ELF_T_OFF] = FALIGN(4,8), + [ELF_T_PHDR] = FALIGN(4,8), + [ELF_T_REL] = FALIGN(4,8), + [ELF_T_RELA] = FALIGN(4,8), + [ELF_T_SHDR] = FALIGN(4,8), + [ELF_T_SWORD] = FALIGN(4,4), + [ELF_T_SXWORD] = FALIGN(0,8), + [ELF_T_SYM] = FALIGN(4,8), + [ELF_T_SYMINFO] = FALIGN(2,2), + [ELF_T_VDEF] = FALIGN(4,4), + [ELF_T_VNEED] = FALIGN(4,4), + [ELF_T_WORD] = FALIGN(4,4), + [ELF_T_XWORD] = FALIGN(0,8), + [ELF_T_GNUHASH] = FALIGN(4,8) +}; + +unsigned int +_libelf_falign(Elf_Type t, int elfclass) +{ + if (t >= ELF_T_NUM || (int) t < 0) + return (0); + + return (elfclass == ELFCLASS32 ? falign[t].a32 : + falign[t].a64); +} diff --git a/contrib/elftoolchain/libelf/libelf_allocate.c b/contrib/elftoolchain/libelf/libelf_allocate.c new file mode 100644 index 0000000000..0ac5813513 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_allocate.c @@ -0,0 +1,199 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Internal APIs + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_allocate.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +Elf * +_libelf_allocate_elf(void) +{ + Elf *e; + + if ((e = calloc((size_t) 1, sizeof(*e))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return NULL; + } + + e->e_activations = 1; + e->e_byteorder = ELFDATANONE; + e->e_class = ELFCLASSNONE; + e->e_cmd = ELF_C_NULL; + e->e_fd = -1; + e->e_kind = ELF_K_NONE; + e->e_version = LIBELF_PRIVATE(version); + + return (e); +} + +void +_libelf_init_elf(Elf *e, Elf_Kind kind) +{ + assert(e != NULL); + assert(e->e_kind == ELF_K_NONE); + + e->e_kind = kind; + + switch (kind) { + case ELF_K_ELF: + STAILQ_INIT(&e->e_u.e_elf.e_scn); + break; + default: + break; + } +} + +void +_libelf_release_elf(Elf *e) +{ + Elf_Arhdr *arh; + + switch (e->e_kind) { + case ELF_K_AR: + free(e->e_u.e_ar.e_symtab); + break; + + case ELF_K_ELF: + switch (e->e_class) { + case ELFCLASS32: + free(e->e_u.e_elf.e_ehdr.e_ehdr32); + free(e->e_u.e_elf.e_phdr.e_phdr32); + break; + case ELFCLASS64: + free(e->e_u.e_elf.e_ehdr.e_ehdr64); + free(e->e_u.e_elf.e_phdr.e_phdr64); + break; + } + + assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); + + if (e->e_flags & LIBELF_F_AR_HEADER) { + arh = e->e_hdr.e_arhdr; + free(arh->ar_name); + free(arh->ar_rawname); + free(arh); + } + + break; + + default: + break; + } + + free(e); +} + +struct _Libelf_Data * +_libelf_allocate_data(Elf_Scn *s) +{ + struct _Libelf_Data *d; + + if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + d->d_scn = s; + + return (d); +} + +struct _Libelf_Data * +_libelf_release_data(struct _Libelf_Data *d) +{ + + if (d->d_flags & LIBELF_F_DATA_MALLOCED) + free(d->d_data.d_buf); + + free(d); + + return (NULL); +} + +Elf_Scn * +_libelf_allocate_scn(Elf *e, size_t ndx) +{ + Elf_Scn *s; + + if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return (NULL); + } + + s->s_elf = e; + s->s_ndx = ndx; + + STAILQ_INIT(&s->s_data); + STAILQ_INIT(&s->s_rawdata); + + STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); + + return (s); +} + +Elf_Scn * +_libelf_release_scn(Elf_Scn *s) +{ + Elf *e; + struct _Libelf_Data *d, *td; + + assert(s != NULL); + + STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { + STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); + d = _libelf_release_data(d); + } + + STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { + assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); + STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); + d = _libelf_release_data(d); + } + + e = s->s_elf; + + assert(e != NULL); + + STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); + + free(s); + + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_ar.c b/contrib/elftoolchain/libelf/libelf_ar.c new file mode 100644 index 0000000000..8a355192a2 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ar.c @@ -0,0 +1,501 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include +#include + +#include "_libelf.h" +#include "_libelf_ar.h" + +ELFTC_VCSID("$Id: libelf_ar.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +#define LIBELF_NALLOC_SIZE 16 + +/* + * `ar' archive handling. + * + * `ar' archives start with signature `ARMAG'. Each archive member is + * preceded by a header containing meta-data for the member. This + * header is described in (struct ar_hdr). The header always + * starts on an even address. File data is padded with "\n" + * characters to keep this invariant. + * + * Special considerations for `ar' archives: + * + * There are two variants of the `ar' archive format: traditional BSD + * and SVR4. These differ in the way long file names are treated, and + * in the layout of the archive symbol table. + * + * The `ar' header only has space for a 16 character file name. + * + * In the SVR4 format, file names are terminated with a '/', so this + * effectively leaves 15 characters for the actual file name. Longer + * file names stored in a separate 'string table' and referenced + * indirectly from the name field. The string table itself appears as + * an archive member with name "// ". An `indirect' file name in an + * `ar' header matches the pattern "/[0-9]*". The digits form a + * decimal number that corresponds to a byte offset into the string + * table where the actual file name of the object starts. Strings in + * the string table are padded to start on even addresses. + * + * In the BSD format, file names can be up to 16 characters. File + * names shorter than 16 characters are padded to 16 characters using + * (ASCII) space characters. File names with embedded spaces and file + * names longer than 16 characters are stored immediately after the + * archive header and the name field set to a special indirect name + * matching the pattern "#1/[0-9]+". The digits form a decimal number + * that corresponds to the actual length of the file name following + * the archive header. The content of the archive member immediately + * follows the file name, and the size field of the archive member + * holds the sum of the sizes of the member and of the appended file + * name. + * + * Archives may also have a symbol table (see ranlib(1)), mapping + * program symbols to object files inside the archive. + * + * In the SVR4 format, a symbol table uses a file name of "/ " in its + * archive header. The symbol table is structured as: + * - a 4-byte count of entries stored as a binary value, MSB first + * - 'n' 4-byte offsets, stored as binary values, MSB first + * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. + * + * In the BSD format, the symbol table uses a file name of "__.SYMDEF". + * It is structured as two parts: + * - The first part is an array of "ranlib" structures preceded by + * the size of the array in bytes. Each "ranlib" structure + * describes one symbol. Each structure contains an offset into + * the string table for the symbol name, and a file offset into the + * archive for the member defining the symbol. + * - The second part is a string table containing NUL-terminated + * strings, preceded by the size of the string table in bytes. + * + * If the symbol table and string table are is present in an archive + * they must be the very first objects and in that order. + */ + + +/* + * Retrieve an archive header descriptor. + */ + +Elf_Arhdr * +_libelf_ar_gethdr(Elf *e) +{ + Elf *parent; + Elf_Arhdr *eh; + char *namelen; + size_t n, nlen; + struct ar_hdr *arh; + + if ((parent = e->e_parent) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert((e->e_flags & LIBELF_F_AR_HEADER) == 0); + + arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr; + + assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG); + + /* + * There needs to be enough space remaining in the file for the + * archive header. + */ + if ((uintptr_t) arh > (uintptr_t) parent->e_rawfile + + (uintptr_t) parent->e_rawsize - sizeof(struct ar_hdr)) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + e->e_hdr.e_arhdr = eh; + e->e_flags |= LIBELF_F_AR_HEADER; + + eh->ar_name = eh->ar_rawname = NULL; + + if ((eh->ar_name = _libelf_ar_get_translated_name(arh, parent)) == + NULL) + goto error; + + if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, + &n) == 0) + goto error; + eh->ar_uid = (uid_t) n; + + if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, + &n) == 0) + goto error; + eh->ar_gid = (gid_t) n; + + if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, + &n) == 0) + goto error; + eh->ar_mode = (mode_t) n; + + if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, + &n) == 0) + goto error; + + /* + * Get the true size of the member if extended naming is being used. + */ + if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { + namelen = arh->ar_name + + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nlen) == 0) + goto error; + n -= nlen; + } + + eh->ar_size = n; + + if ((eh->ar_rawname = _libelf_ar_get_raw_name(arh)) == NULL) + goto error; + + eh->ar_flags = 0; + + return (eh); + + error: + if (eh) { + if (eh->ar_name) + free(eh->ar_name); + if (eh->ar_rawname) + free(eh->ar_rawname); + free(eh); + } + + e->e_flags &= ~LIBELF_F_AR_HEADER; + e->e_hdr.e_rawhdr = (unsigned char *) arh; + + return (NULL); +} + +Elf * +_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) +{ + Elf *e; + size_t nsz, sz; + off_t next, end; + struct ar_hdr *arh; + char *member, *namelen; + + assert(elf->e_kind == ELF_K_AR); + + next = elf->e_u.e_ar.e_next; + + /* + * `next' is only set to zero by elf_next() when the last + * member of an archive is processed. + */ + if (next == (off_t) 0) + return (NULL); + + assert((next & 1) == 0); + + /* + * There needs to be enough space in the file to contain an + * ar(1) header. + */ + end = next + (off_t) sizeof(struct ar_hdr); + if ((uintmax_t) end < (uintmax_t) next || /* Overflow. */ + end > (off_t) elf->e_rawsize) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + arh = (struct ar_hdr *) (elf->e_rawfile + next); + + /* + * Retrieve the size of the member. + */ + if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, + &sz) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + /* + * Check if the archive member that follows will fit in the + * containing archive. + */ + end += (off_t) sz; + if (end < next || /* Overflow. */ + end > (off_t) elf->e_rawsize) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + /* + * Adjust the size field for members in BSD archives using + * extended naming. + */ + if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { + namelen = arh->ar_name + + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nsz) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + member = (char *) (arh + 1) + nsz; + sz -= nsz; + } else + member = (char *) (arh + 1); + + + if ((e = elf_memory(member, sz)) == NULL) + return (NULL); + + e->e_fd = fd; + e->e_cmd = c; + e->e_hdr.e_rawhdr = (unsigned char *) arh; + + elf->e_u.e_ar.e_nchildren++; + e->e_parent = elf; + + return (e); +} + +/* + * A BSD-style ar(1) symbol table has the following layout: + * + * - A count of bytes used by the following array of 'ranlib' + * structures, stored as a 'long'. + * - An array of 'ranlib' structures. Each array element is + * two 'long's in size. + * - A count of bytes used for the following symbol table. + * - The symbol table itself. + */ + +/* + * A helper macro to read in a 'long' value from the archive. + * + * We use memcpy() since the source pointer may be misaligned with + * respect to the natural alignment for a C 'long'. + */ +#define GET_LONG(P, V)do { \ + memcpy(&(V), (P), sizeof(long)); \ + (P) += sizeof(long); \ + } while (/* CONSTCOND */ 0) + +Elf_Arsym * +_libelf_ar_process_bsd_symtab(Elf *e, size_t *count) +{ + Elf_Arsym *symtab, *sym; + unsigned int n; + size_t nentries; + unsigned char *end, *p, *p0, *s, *s0; + const size_t entrysize = 2 * sizeof(long); + long arraysize, fileoffset, stroffset, strtabsize; + + assert(e != NULL); + assert(count != NULL); + assert(e->e_u.e_ar.e_symtab == NULL); + + symtab = NULL; + + /* + * The BSD symbol table always contains the count fields even + * if there are no entries in it. + */ + if (e->e_u.e_ar.e_rawsymtabsz < 2 * sizeof(long)) + goto symtaberror; + + p = p0 = (unsigned char *) e->e_u.e_ar.e_rawsymtab; + end = p0 + e->e_u.e_ar.e_rawsymtabsz; + + /* + * Retrieve the size of the array of ranlib descriptors and + * check it for validity. + */ + GET_LONG(p, arraysize); + + if (arraysize < 0 || p0 + arraysize >= end || + ((size_t) arraysize % entrysize != 0)) + goto symtaberror; + + /* + * Check the value of the string table size. + */ + s = p + arraysize; + GET_LONG(s, strtabsize); + + s0 = s; /* Start of string table. */ + if (strtabsize < 0 || s0 + strtabsize > end) + goto symtaberror; + + nentries = (size_t) arraysize / entrysize; + + /* + * Allocate space for the returned Elf_Arsym array. + */ + if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries + 1))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + /* Read in symbol table entries. */ + for (n = 0, sym = symtab; n < nentries; n++, sym++) { + GET_LONG(p, stroffset); + GET_LONG(p, fileoffset); + + if (stroffset < 0 || fileoffset < 0 || + (off_t) fileoffset >= e->e_rawsize) + goto symtaberror; + + s = s0 + stroffset; + + if (s >= end) + goto symtaberror; + + sym->as_off = (off_t) fileoffset; + sym->as_hash = elf_hash((char *) s); + sym->as_name = (char *) s; + } + + /* Fill up the sentinel entry. */ + sym->as_name = NULL; + sym->as_hash = ~0UL; + sym->as_off = (off_t) 0; + + /* Remember the processed symbol table. */ + e->e_u.e_ar.e_symtab = symtab; + + *count = e->e_u.e_ar.e_symtabsz = nentries + 1; + + return (symtab); + +symtaberror: + if (symtab) + free(symtab); + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} + +/* + * An SVR4-style ar(1) symbol table has the following layout: + * + * - The first 4 bytes are a binary count of the number of entries in the + * symbol table, stored MSB-first. + * - Then there are 'n' 4-byte binary offsets, also stored MSB first. + * - Following this, there are 'n' null-terminated strings. + */ + +#define GET_WORD(P, V) do { \ + (V) = 0; \ + (V) = (P)[0]; (V) <<= 8; \ + (V) += (P)[1]; (V) <<= 8; \ + (V) += (P)[2]; (V) <<= 8; \ + (V) += (P)[3]; \ + } while (/* CONSTCOND */ 0) + +#define INTSZ 4 + + +Elf_Arsym * +_libelf_ar_process_svr4_symtab(Elf *e, size_t *count) +{ + uint32_t off; + size_t n, nentries; + Elf_Arsym *symtab, *sym; + unsigned char *p, *s, *end; + + assert(e != NULL); + assert(count != NULL); + assert(e->e_u.e_ar.e_symtab == NULL); + + symtab = NULL; + + if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) + goto symtaberror; + + p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; + end = p + e->e_u.e_ar.e_rawsymtabsz; + + GET_WORD(p, nentries); + p += INTSZ; + + if (nentries == 0 || p + nentries * INTSZ >= end) + goto symtaberror; + + /* Allocate space for a nentries + a sentinel. */ + if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + s = p + (nentries * INTSZ); /* start of the string table. */ + + for (n = nentries, sym = symtab; n > 0; n--) { + if (s >= end) + goto symtaberror; + + GET_WORD(p, off); + if ((off_t) off >= e->e_rawsize) + goto symtaberror; + + sym->as_off = (off_t) off; + sym->as_hash = elf_hash((char *) s); + sym->as_name = (char *) s; + + p += INTSZ; + sym++; + + for (; s < end && *s++ != '\0';) /* skip to next string */ + ; + } + + /* Fill up the sentinel entry. */ + sym->as_name = NULL; + sym->as_hash = ~0UL; + sym->as_off = (off_t) 0; + + *count = e->e_u.e_ar.e_symtabsz = nentries + 1; + e->e_u.e_ar.e_symtab = symtab; + + return (symtab); + +symtaberror: + if (symtab) + free(symtab); + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_ar_util.c b/contrib/elftoolchain/libelf/libelf_ar_util.c new file mode 100644 index 0000000000..25f0fb39c6 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ar_util.c @@ -0,0 +1,364 @@ +/*- + * Copyright (c) 2006,2009,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" +#include "_libelf_ar.h" + +ELFTC_VCSID("$Id: libelf_ar_util.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Convert a string bounded by `start' and `start+sz' (exclusive) to a + * number in the specified base. + */ +int +_libelf_ar_get_number(const char *src, size_t sz, unsigned int base, + size_t *ret) +{ + size_t r; + unsigned int c, v; + const unsigned char *e, *s; + + assert(base <= 10); + + s = (const unsigned char *) src; + e = s + sz; + + /* skip leading blanks */ + for (;s < e && (c = *s) == ' '; s++) + ; + + r = 0L; + for (;s < e; s++) { + if ((c = *s) == ' ') + break; + if (c < '0' || c > '9') + return (0); + v = c - '0'; + if (v >= base) /* Illegal digit. */ + break; + r *= base; + r += v; + } + + *ret = r; + + return (1); +} + +/* + * Return the translated name for an archive member. + */ +char * +_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) +{ + char *s; + unsigned char c; + size_t len, offset; + const unsigned char *buf, *p, *q, *r; + const size_t bufsize = sizeof(arh->ar_name); + + assert(arh != NULL); + assert(ar->e_kind == ELF_K_AR); + assert((const unsigned char *) arh >= ar->e_rawfile && + (const unsigned char *) arh < ar->e_rawfile + ar->e_rawsize); + + buf = (const unsigned char *) arh->ar_name; + + /* + * Check for extended naming. + * + * If the name matches the pattern "^/[0-9]+", it is an + * SVR4-style extended name. If the name matches the pattern + * "#1/[0-9]+", the entry uses BSD style extended naming. + */ + if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { + /* + * The value in field ar_name is a decimal offset into + * the archive string table where the actual name + * resides. + */ + if (_libelf_ar_get_number((const char *) (buf + 1), + bufsize - 1, 10, &offset) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + if (offset > ar->e_u.e_ar.e_rawstrtabsz) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + p = q = ar->e_u.e_ar.e_rawstrtab + offset; + r = ar->e_u.e_ar.e_rawstrtab + ar->e_u.e_ar.e_rawstrtabsz; + + for (; p < r && *p != '/'; p++) + ; + len = (size_t) (p - q + 1); /* space for the trailing NUL */ + + if ((s = malloc(len)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(s, (const char *) q, len - 1); + s[len - 1] = '\0'; + + return (s); + } else if (IS_EXTENDED_BSD_NAME(buf)) { + r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + + if (_libelf_ar_get_number((const char *) r, bufsize - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, + &len) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + /* + * Allocate space for the file name plus a + * trailing NUL. + */ + if ((s = malloc(len + 1)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + /* + * The file name follows the archive header. + */ + q = (const unsigned char *) (arh + 1); + + (void) strncpy(s, (const char *) q, len); + s[len] = '\0'; + + return (s); + } + + /* + * A 'normal' name. + * + * Skip back over trailing blanks from the end of the field. + * In the SVR4 format, a '/' is used as a terminator for + * non-special names. + */ + for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) + ; + + if (q >= buf) { + if (*q == '/') { + /* + * SVR4 style names: ignore the trailing + * character '/', but only if the name is not + * one of the special names "/" and "//". + */ + if (q > buf + 1 || + (q == (buf + 1) && *buf != '/')) + q--; + } + + len = (size_t) (q - buf + 2); /* Space for a trailing NUL. */ + } else { + /* The buffer only had blanks. */ + buf = (const unsigned char *) ""; + len = 1; + } + + if ((s = malloc(len)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(s, (const char *) buf, len - 1); + s[len - 1] = '\0'; + + return (s); +} + +/* + * Return the raw name for an archive member, inclusive of any + * formatting characters. + */ +char * +_libelf_ar_get_raw_name(const struct ar_hdr *arh) +{ + char *rawname; + const size_t namesz = sizeof(arh->ar_name); + + if ((rawname = malloc(namesz + 1)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(rawname, arh->ar_name, namesz); + rawname[namesz] = '\0'; + return (rawname); +} + +/* + * Open an 'ar' archive. + */ +Elf * +_libelf_ar_open(Elf *e, int reporterror) +{ + size_t sz; + int scanahead; + struct ar_hdr arh; + unsigned char *s, *end; + + _libelf_init_elf(e, ELF_K_AR); + + e->e_u.e_ar.e_nchildren = 0; + e->e_u.e_ar.e_next = (off_t) -1; + + /* + * Look for special members. + */ + + s = e->e_rawfile + SARMAG; + end = e->e_rawfile + e->e_rawsize; + + assert(e->e_rawsize > 0); + + /* + * We use heuristics to determine the flavor of the archive we + * are examining. + * + * SVR4 flavor archives use the name "/ " and "// " for + * special members. + * + * In BSD flavor archives the symbol table, if present, is the + * first archive with name "__.SYMDEF". + */ + +#define READ_AR_HEADER(S, ARH, SZ, END) \ + do { \ + if ((S) + sizeof((ARH)) > (END)) \ + goto error; \ + (void) memcpy(&(ARH), (S), sizeof((ARH))); \ + if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \ + goto error; \ + if (_libelf_ar_get_number((char *) (ARH).ar_size, \ + sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ + goto error; \ + } while (/* CONSTCOND */ 0) + + READ_AR_HEADER(s, arh, sz, end); + + /* + * Handle special archive members for the SVR4 format. + */ + if (arh.ar_name[0] == '/') { + if (sz == 0) + goto error; + + e->e_flags |= LIBELF_F_AR_VARIANT_SVR4; + + scanahead = 0; + + /* + * The symbol table (file name "/ ") always comes before the + * string table (file name "// "). + */ + if (arh.ar_name[1] == ' ') { + /* "/ " => symbol table. */ + scanahead = 1; /* The string table to follow. */ + + s += sizeof(arh); + e->e_u.e_ar.e_rawsymtab = s; + e->e_u.e_ar.e_rawsymtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + + } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { + /* "// " => string table for long file names. */ + s += sizeof(arh); + e->e_u.e_ar.e_rawstrtab = s; + e->e_u.e_ar.e_rawstrtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + + /* + * If the string table hasn't been seen yet, look for + * it in the next member. + */ + if (scanahead) { + READ_AR_HEADER(s, arh, sz, end); + + /* "// " => string table for long file names. */ + if (arh.ar_name[0] == '/' && arh.ar_name[1] == '/' && + arh.ar_name[2] == ' ') { + + s += sizeof(arh); + + e->e_u.e_ar.e_rawstrtab = s; + e->e_u.e_ar.e_rawstrtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + } + } else if (strncmp(arh.ar_name, LIBELF_AR_BSD_SYMTAB_NAME, + sizeof(LIBELF_AR_BSD_SYMTAB_NAME) - 1) == 0) { + /* + * BSD style archive symbol table. + */ + s += sizeof(arh); + e->e_u.e_ar.e_rawsymtab = s; + e->e_u.e_ar.e_rawsymtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + + /* + * Update the 'next' offset, so that a subsequent elf_begin() + * works as expected. + */ + e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); + + return (e); + +error: + if (!reporterror) { + e->e_kind = ELF_K_NONE; + return (e); + } + + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_checksum.c b/contrib/elftoolchain/libelf/libelf_checksum.c new file mode 100644 index 0000000000..3a0d6af0f6 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_checksum.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_checksum.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +static unsigned long +_libelf_sum(unsigned long c, const unsigned char *s, size_t size) +{ + if (s == NULL || size == 0) + return (c); + + while (size--) + c += *s++; + + return (c); +} + +long +_libelf_checksum(Elf *e, int elfclass) +{ + size_t shn; + Elf_Scn *scn; + Elf_Data *d; + unsigned long checksum; + GElf_Ehdr eh; + GElf_Shdr shdr; + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0L); + } + + if (e->e_class != elfclass) { + LIBELF_SET_ERROR(CLASS, 0); + return (0L); + } + + if (gelf_getehdr(e, &eh) == NULL) + return (0); + + /* + * Iterate over all sections in the ELF file, computing the + * checksum along the way. + * + * The first section is always SHN_UNDEF and can be skipped. + * Non-allocatable sections are skipped, as are sections that + * could be affected by utilities such as strip(1). + */ + + checksum = 0; + for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { + if ((scn = elf_getscn(e, shn)) == NULL) + return (0); + if (gelf_getshdr(scn, &shdr) == NULL) + return (0); + if ((shdr.sh_flags & SHF_ALLOC) == 0 || + shdr.sh_type == SHT_DYNAMIC || + shdr.sh_type == SHT_DYNSYM) + continue; + + d = NULL; + while ((d = elf_rawdata(scn, d)) != NULL) + checksum = _libelf_sum(checksum, + (unsigned char *) d->d_buf, (size_t) d->d_size); + } + + /* + * Return a 16-bit checksum compatible with Solaris. + */ + return (long) (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); +} diff --git a/contrib/elftoolchain/libelf/libelf_convert.c b/contrib/elftoolchain/libelf/libelf_convert.c new file mode 100644 index 0000000000..2bc861cfe7 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_convert.c @@ -0,0 +1,3393 @@ +/*- + * Copyright (c) 2006-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_convert.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM libelf_convert.m4. */ + + + +/* + * C macros to byte swap integral quantities. + */ + +#define SWAP_BYTE(X) do { (void) (X); } while (/*CONSTCOND*/0) +#define SWAP_IDENT(X) do { (void) (X); } while (/*CONSTCOND*/0) +#define SWAP_HALF(X) do { \ + uint16_t _x = (uint16_t) (X); \ + uint32_t _t = _x & 0xFFU; \ + _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ + (X) = (uint16_t) _t; \ + } while (/*CONSTCOND*/0) +#define _SWAP_WORD(X, T) do { \ + uint32_t _x = (uint32_t) (X); \ + uint32_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) +#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) +#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) +#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) +#define _SWAP_WORD64(X, T) do { \ + uint64_t _x = (uint64_t) (X); \ + uint64_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) +#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) +#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) +#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) +#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) + +/* + * C macros to write out various integral values. + * + * Note: + * - The destination pointer could be unaligned. + * - Values are written out in native byte order. + * - The destination pointer is incremented after the write. + */ +#define WRITE_BYTE(P,X) do { \ + unsigned char *const _p = (unsigned char *) (P); \ + _p[0] = (unsigned char) (X); \ + (P) = _p + 1; \ + } while (/*CONSTCOND*/0) +#define WRITE_HALF(P,X) do { \ + uint16_t _t = (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + (P) = _p + 2; \ + } while (/*CONSTCOND*/0) +#define WRITE_WORD(P,X) do { \ + uint32_t _t = (uint32_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + (P) = _p + 4; \ + } while (/*CONSTCOND*/0) +#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) +#define WRITE_OFF32(P,X) WRITE_WORD(P,X) +#define WRITE_SWORD(P,X) WRITE_WORD(P,X) +#define WRITE_WORD64(P,X) do { \ + uint64_t _t = (uint64_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + _p[4] = _q[4]; \ + _p[5] = _q[5]; \ + _p[6] = _q[6]; \ + _p[7] = _q[7]; \ + (P) = _p + 8; \ + } while (/*CONSTCOND*/0) +#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) +#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) +#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_IDENT(P,X) do { \ + (void) memcpy((P), (X), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (/*CONSTCOND*/0) + +/* + * C macros to read in various integral values. + * + * Note: + * - The source pointer could be unaligned. + * - Values are read in native byte order. + * - The source pointer is incremented appropriately. + */ + +#define READ_BYTE(P,X) do { \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + (X) = _p[0]; \ + (P) = (P) + 1; \ + } while (/*CONSTCOND*/0) +#define READ_HALF(P,X) do { \ + uint16_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + (P) = (P) + 2; \ + (X) = _t; \ + } while (/*CONSTCOND*/0) +#define _READ_WORD(P,X,T) do { \ + uint32_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + (P) = (P) + 4; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) +#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) +#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) +#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) +#define _READ_WORD64(P,X,T) do { \ + uint64_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + _q[4] = _p[4]; \ + _q[5] = _p[5]; \ + _q[6] = _p[6]; \ + _q[7] = _p[7]; \ + (P) = (P) + 8; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) +#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) +#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) +#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) +#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) +#define READ_IDENT(P,X) do { \ + (void) memcpy((X), (P), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (/*CONSTCOND*/0) + +#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) + +/*[*/ + +static int +_libelf_cvt_ADDR32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Addr t, *s = (Elf32_Addr *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_ADDR32(t); + WRITE_ADDR32(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_ADDR32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Addr t, *d = (Elf32_Addr *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf32_Addr)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_ADDR32(src,t); + SWAP_ADDR32(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_ADDR64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Addr t, *s = (Elf64_Addr *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_ADDR64(t); + WRITE_ADDR64(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_ADDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Addr t, *d = (Elf64_Addr *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Addr)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_ADDR64(src,t); + SWAP_ADDR64(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_CAP32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Cap t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Cap *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Cap */ + SWAP_WORD(t.c_tag); + SWAP_WORD(t.c_un.c_val); + /**/ + } + /* Write an Elf32_Cap */ + WRITE_WORD(dst,t.c_tag); + WRITE_WORD(dst,t.c_un.c_val); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_CAP32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Cap t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT); + d = ((Elf32_Cap *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Cap)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Cap */ + READ_WORD(s,t.c_tag); + READ_WORD(s,t.c_un.c_val); + /**/ + if (byteswap) { + /* Swap an Elf32_Cap */ + SWAP_WORD(t.c_tag); + SWAP_WORD(t.c_un.c_val); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_CAP64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Cap t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Cap *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Cap */ + SWAP_XWORD(t.c_tag); + SWAP_XWORD(t.c_un.c_val); + /**/ + } + /* Write an Elf64_Cap */ + WRITE_XWORD(dst,t.c_tag); + WRITE_XWORD(dst,t.c_un.c_val); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_CAP64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Cap t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT); + d = ((Elf64_Cap *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Cap)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Cap */ + READ_XWORD(s,t.c_tag); + READ_XWORD(s,t.c_un.c_val); + /**/ + if (byteswap) { + /* Swap an Elf64_Cap */ + SWAP_XWORD(t.c_tag); + SWAP_XWORD(t.c_un.c_val); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_DYN32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Dyn t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Dyn *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Dyn */ + SWAP_SWORD(t.d_tag); + SWAP_WORD(t.d_un.d_ptr); + /**/ + } + /* Write an Elf32_Dyn */ + WRITE_SWORD(dst,t.d_tag); + WRITE_WORD(dst,t.d_un.d_ptr); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_DYN32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Dyn t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT); + d = ((Elf32_Dyn *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Dyn)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Dyn */ + READ_SWORD(s,t.d_tag); + READ_WORD(s,t.d_un.d_ptr); + /**/ + if (byteswap) { + /* Swap an Elf32_Dyn */ + SWAP_SWORD(t.d_tag); + SWAP_WORD(t.d_un.d_ptr); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_DYN64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Dyn t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Dyn *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Dyn */ + SWAP_SXWORD(t.d_tag); + SWAP_XWORD(t.d_un.d_ptr); + /**/ + } + /* Write an Elf64_Dyn */ + WRITE_SXWORD(dst,t.d_tag); + WRITE_XWORD(dst,t.d_un.d_ptr); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_DYN64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Dyn t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT); + d = ((Elf64_Dyn *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Dyn)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Dyn */ + READ_SXWORD(s,t.d_tag); + READ_XWORD(s,t.d_un.d_ptr); + /**/ + if (byteswap) { + /* Swap an Elf64_Dyn */ + SWAP_SXWORD(t.d_tag); + SWAP_XWORD(t.d_un.d_ptr); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_EHDR32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Ehdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Ehdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Ehdr */ + SWAP_IDENT(t.e_ident); + SWAP_HALF(t.e_type); + SWAP_HALF(t.e_machine); + SWAP_WORD(t.e_version); + SWAP_ADDR32(t.e_entry); + SWAP_OFF32(t.e_phoff); + SWAP_OFF32(t.e_shoff); + SWAP_WORD(t.e_flags); + SWAP_HALF(t.e_ehsize); + SWAP_HALF(t.e_phentsize); + SWAP_HALF(t.e_phnum); + SWAP_HALF(t.e_shentsize); + SWAP_HALF(t.e_shnum); + SWAP_HALF(t.e_shstrndx); + /**/ + } + /* Write an Elf32_Ehdr */ + WRITE_IDENT(dst,t.e_ident); + WRITE_HALF(dst,t.e_type); + WRITE_HALF(dst,t.e_machine); + WRITE_WORD(dst,t.e_version); + WRITE_ADDR32(dst,t.e_entry); + WRITE_OFF32(dst,t.e_phoff); + WRITE_OFF32(dst,t.e_shoff); + WRITE_WORD(dst,t.e_flags); + WRITE_HALF(dst,t.e_ehsize); + WRITE_HALF(dst,t.e_phentsize); + WRITE_HALF(dst,t.e_phnum); + WRITE_HALF(dst,t.e_shentsize); + WRITE_HALF(dst,t.e_shnum); + WRITE_HALF(dst,t.e_shstrndx); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_EHDR32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Ehdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT); + d = ((Elf32_Ehdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Ehdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Ehdr */ + READ_IDENT(s,t.e_ident); + READ_HALF(s,t.e_type); + READ_HALF(s,t.e_machine); + READ_WORD(s,t.e_version); + READ_ADDR32(s,t.e_entry); + READ_OFF32(s,t.e_phoff); + READ_OFF32(s,t.e_shoff); + READ_WORD(s,t.e_flags); + READ_HALF(s,t.e_ehsize); + READ_HALF(s,t.e_phentsize); + READ_HALF(s,t.e_phnum); + READ_HALF(s,t.e_shentsize); + READ_HALF(s,t.e_shnum); + READ_HALF(s,t.e_shstrndx); + /**/ + if (byteswap) { + /* Swap an Elf32_Ehdr */ + SWAP_IDENT(t.e_ident); + SWAP_HALF(t.e_type); + SWAP_HALF(t.e_machine); + SWAP_WORD(t.e_version); + SWAP_ADDR32(t.e_entry); + SWAP_OFF32(t.e_phoff); + SWAP_OFF32(t.e_shoff); + SWAP_WORD(t.e_flags); + SWAP_HALF(t.e_ehsize); + SWAP_HALF(t.e_phentsize); + SWAP_HALF(t.e_phnum); + SWAP_HALF(t.e_shentsize); + SWAP_HALF(t.e_shnum); + SWAP_HALF(t.e_shstrndx); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_EHDR64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Ehdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Ehdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Ehdr */ + SWAP_IDENT(t.e_ident); + SWAP_HALF(t.e_type); + SWAP_HALF(t.e_machine); + SWAP_WORD(t.e_version); + SWAP_ADDR64(t.e_entry); + SWAP_OFF64(t.e_phoff); + SWAP_OFF64(t.e_shoff); + SWAP_WORD(t.e_flags); + SWAP_HALF(t.e_ehsize); + SWAP_HALF(t.e_phentsize); + SWAP_HALF(t.e_phnum); + SWAP_HALF(t.e_shentsize); + SWAP_HALF(t.e_shnum); + SWAP_HALF(t.e_shstrndx); + /**/ + } + /* Write an Elf64_Ehdr */ + WRITE_IDENT(dst,t.e_ident); + WRITE_HALF(dst,t.e_type); + WRITE_HALF(dst,t.e_machine); + WRITE_WORD(dst,t.e_version); + WRITE_ADDR64(dst,t.e_entry); + WRITE_OFF64(dst,t.e_phoff); + WRITE_OFF64(dst,t.e_shoff); + WRITE_WORD(dst,t.e_flags); + WRITE_HALF(dst,t.e_ehsize); + WRITE_HALF(dst,t.e_phentsize); + WRITE_HALF(dst,t.e_phnum); + WRITE_HALF(dst,t.e_shentsize); + WRITE_HALF(dst,t.e_shnum); + WRITE_HALF(dst,t.e_shstrndx); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_EHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Ehdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT); + d = ((Elf64_Ehdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Ehdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Ehdr */ + READ_IDENT(s,t.e_ident); + READ_HALF(s,t.e_type); + READ_HALF(s,t.e_machine); + READ_WORD(s,t.e_version); + READ_ADDR64(s,t.e_entry); + READ_OFF64(s,t.e_phoff); + READ_OFF64(s,t.e_shoff); + READ_WORD(s,t.e_flags); + READ_HALF(s,t.e_ehsize); + READ_HALF(s,t.e_phentsize); + READ_HALF(s,t.e_phnum); + READ_HALF(s,t.e_shentsize); + READ_HALF(s,t.e_shnum); + READ_HALF(s,t.e_shstrndx); + /**/ + if (byteswap) { + /* Swap an Elf64_Ehdr */ + SWAP_IDENT(t.e_ident); + SWAP_HALF(t.e_type); + SWAP_HALF(t.e_machine); + SWAP_WORD(t.e_version); + SWAP_ADDR64(t.e_entry); + SWAP_OFF64(t.e_phoff); + SWAP_OFF64(t.e_shoff); + SWAP_WORD(t.e_flags); + SWAP_HALF(t.e_ehsize); + SWAP_HALF(t.e_phentsize); + SWAP_HALF(t.e_phnum); + SWAP_HALF(t.e_shentsize); + SWAP_HALF(t.e_shnum); + SWAP_HALF(t.e_shstrndx); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_HALF_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Half t, *s = (Elf64_Half *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_HALF(t); + WRITE_HALF(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_HALF_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Half t, *d = (Elf64_Half *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Half)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_HALF(src,t); + SWAP_HALF(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_LWORD_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Lword t, *s = (Elf64_Lword *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_LWORD(t); + WRITE_LWORD(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_LWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Lword t, *d = (Elf64_Lword *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Lword)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_LWORD(src,t); + SWAP_LWORD(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_MOVE32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Move t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Move *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Move */ + SWAP_LWORD(t.m_value); + SWAP_WORD(t.m_info); + SWAP_WORD(t.m_poffset); + SWAP_HALF(t.m_repeat); + SWAP_HALF(t.m_stride); + /**/ + } + /* Write an Elf32_Move */ + WRITE_LWORD(dst,t.m_value); + WRITE_WORD(dst,t.m_info); + WRITE_WORD(dst,t.m_poffset); + WRITE_HALF(dst,t.m_repeat); + WRITE_HALF(dst,t.m_stride); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_MOVE32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Move t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT); + d = ((Elf32_Move *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Move)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Move */ + READ_LWORD(s,t.m_value); + READ_WORD(s,t.m_info); + READ_WORD(s,t.m_poffset); + READ_HALF(s,t.m_repeat); + READ_HALF(s,t.m_stride); + /**/ + if (byteswap) { + /* Swap an Elf32_Move */ + SWAP_LWORD(t.m_value); + SWAP_WORD(t.m_info); + SWAP_WORD(t.m_poffset); + SWAP_HALF(t.m_repeat); + SWAP_HALF(t.m_stride); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_MOVE64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Move t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Move *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Move */ + SWAP_LWORD(t.m_value); + SWAP_XWORD(t.m_info); + SWAP_XWORD(t.m_poffset); + SWAP_HALF(t.m_repeat); + SWAP_HALF(t.m_stride); + /**/ + } + /* Write an Elf64_Move */ + WRITE_LWORD(dst,t.m_value); + WRITE_XWORD(dst,t.m_info); + WRITE_XWORD(dst,t.m_poffset); + WRITE_HALF(dst,t.m_repeat); + WRITE_HALF(dst,t.m_stride); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_MOVE64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Move t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT); + d = ((Elf64_Move *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Move)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Move */ + READ_LWORD(s,t.m_value); + READ_XWORD(s,t.m_info); + READ_XWORD(s,t.m_poffset); + READ_HALF(s,t.m_repeat); + READ_HALF(s,t.m_stride); + /**/ + if (byteswap) { + /* Swap an Elf64_Move */ + SWAP_LWORD(t.m_value); + SWAP_XWORD(t.m_info); + SWAP_XWORD(t.m_poffset); + SWAP_HALF(t.m_repeat); + SWAP_HALF(t.m_stride); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_OFF32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Off t, *s = (Elf32_Off *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_OFF32(t); + WRITE_OFF32(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_OFF32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Off t, *d = (Elf32_Off *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf32_Off)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_OFF32(src,t); + SWAP_OFF32(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_OFF64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Off t, *s = (Elf64_Off *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_OFF64(t); + WRITE_OFF64(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_OFF64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Off t, *d = (Elf64_Off *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Off)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_OFF64(src,t); + SWAP_OFF64(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_PHDR32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Phdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Phdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Phdr */ + SWAP_WORD(t.p_type); + SWAP_OFF32(t.p_offset); + SWAP_ADDR32(t.p_vaddr); + SWAP_ADDR32(t.p_paddr); + SWAP_WORD(t.p_filesz); + SWAP_WORD(t.p_memsz); + SWAP_WORD(t.p_flags); + SWAP_WORD(t.p_align); + /**/ + } + /* Write an Elf32_Phdr */ + WRITE_WORD(dst,t.p_type); + WRITE_OFF32(dst,t.p_offset); + WRITE_ADDR32(dst,t.p_vaddr); + WRITE_ADDR32(dst,t.p_paddr); + WRITE_WORD(dst,t.p_filesz); + WRITE_WORD(dst,t.p_memsz); + WRITE_WORD(dst,t.p_flags); + WRITE_WORD(dst,t.p_align); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_PHDR32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Phdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT); + d = ((Elf32_Phdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Phdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Phdr */ + READ_WORD(s,t.p_type); + READ_OFF32(s,t.p_offset); + READ_ADDR32(s,t.p_vaddr); + READ_ADDR32(s,t.p_paddr); + READ_WORD(s,t.p_filesz); + READ_WORD(s,t.p_memsz); + READ_WORD(s,t.p_flags); + READ_WORD(s,t.p_align); + /**/ + if (byteswap) { + /* Swap an Elf32_Phdr */ + SWAP_WORD(t.p_type); + SWAP_OFF32(t.p_offset); + SWAP_ADDR32(t.p_vaddr); + SWAP_ADDR32(t.p_paddr); + SWAP_WORD(t.p_filesz); + SWAP_WORD(t.p_memsz); + SWAP_WORD(t.p_flags); + SWAP_WORD(t.p_align); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_PHDR64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Phdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Phdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Phdr */ + SWAP_WORD(t.p_type); + SWAP_WORD(t.p_flags); + SWAP_OFF64(t.p_offset); + SWAP_ADDR64(t.p_vaddr); + SWAP_ADDR64(t.p_paddr); + SWAP_XWORD(t.p_filesz); + SWAP_XWORD(t.p_memsz); + SWAP_XWORD(t.p_align); + /**/ + } + /* Write an Elf64_Phdr */ + WRITE_WORD(dst,t.p_type); + WRITE_WORD(dst,t.p_flags); + WRITE_OFF64(dst,t.p_offset); + WRITE_ADDR64(dst,t.p_vaddr); + WRITE_ADDR64(dst,t.p_paddr); + WRITE_XWORD(dst,t.p_filesz); + WRITE_XWORD(dst,t.p_memsz); + WRITE_XWORD(dst,t.p_align); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_PHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Phdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT); + d = ((Elf64_Phdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Phdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Phdr */ + READ_WORD(s,t.p_type); + READ_WORD(s,t.p_flags); + READ_OFF64(s,t.p_offset); + READ_ADDR64(s,t.p_vaddr); + READ_ADDR64(s,t.p_paddr); + READ_XWORD(s,t.p_filesz); + READ_XWORD(s,t.p_memsz); + READ_XWORD(s,t.p_align); + /**/ + if (byteswap) { + /* Swap an Elf64_Phdr */ + SWAP_WORD(t.p_type); + SWAP_WORD(t.p_flags); + SWAP_OFF64(t.p_offset); + SWAP_ADDR64(t.p_vaddr); + SWAP_ADDR64(t.p_paddr); + SWAP_XWORD(t.p_filesz); + SWAP_XWORD(t.p_memsz); + SWAP_XWORD(t.p_align); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_REL32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Rel t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Rel *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Rel */ + SWAP_ADDR32(t.r_offset); + SWAP_WORD(t.r_info); + /**/ + } + /* Write an Elf32_Rel */ + WRITE_ADDR32(dst,t.r_offset); + WRITE_WORD(dst,t.r_info); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_REL32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Rel t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT); + d = ((Elf32_Rel *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Rel)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Rel */ + READ_ADDR32(s,t.r_offset); + READ_WORD(s,t.r_info); + /**/ + if (byteswap) { + /* Swap an Elf32_Rel */ + SWAP_ADDR32(t.r_offset); + SWAP_WORD(t.r_info); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_REL64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Rel t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Rel *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Rel */ + SWAP_ADDR64(t.r_offset); + SWAP_XWORD(t.r_info); + /**/ + } + /* Write an Elf64_Rel */ + WRITE_ADDR64(dst,t.r_offset); + WRITE_XWORD(dst,t.r_info); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_REL64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Rel t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT); + d = ((Elf64_Rel *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Rel)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Rel */ + READ_ADDR64(s,t.r_offset); + READ_XWORD(s,t.r_info); + /**/ + if (byteswap) { + /* Swap an Elf64_Rel */ + SWAP_ADDR64(t.r_offset); + SWAP_XWORD(t.r_info); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_RELA32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Rela t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Rela *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Rela */ + SWAP_ADDR32(t.r_offset); + SWAP_WORD(t.r_info); + SWAP_SWORD(t.r_addend); + /**/ + } + /* Write an Elf32_Rela */ + WRITE_ADDR32(dst,t.r_offset); + WRITE_WORD(dst,t.r_info); + WRITE_SWORD(dst,t.r_addend); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_RELA32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Rela t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT); + d = ((Elf32_Rela *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Rela)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Rela */ + READ_ADDR32(s,t.r_offset); + READ_WORD(s,t.r_info); + READ_SWORD(s,t.r_addend); + /**/ + if (byteswap) { + /* Swap an Elf32_Rela */ + SWAP_ADDR32(t.r_offset); + SWAP_WORD(t.r_info); + SWAP_SWORD(t.r_addend); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_RELA64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Rela t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Rela *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Rela */ + SWAP_ADDR64(t.r_offset); + SWAP_XWORD(t.r_info); + SWAP_SXWORD(t.r_addend); + /**/ + } + /* Write an Elf64_Rela */ + WRITE_ADDR64(dst,t.r_offset); + WRITE_XWORD(dst,t.r_info); + WRITE_SXWORD(dst,t.r_addend); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_RELA64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Rela t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT); + d = ((Elf64_Rela *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Rela)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Rela */ + READ_ADDR64(s,t.r_offset); + READ_XWORD(s,t.r_info); + READ_SXWORD(s,t.r_addend); + /**/ + if (byteswap) { + /* Swap an Elf64_Rela */ + SWAP_ADDR64(t.r_offset); + SWAP_XWORD(t.r_info); + SWAP_SXWORD(t.r_addend); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SHDR32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Shdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Shdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Shdr */ + SWAP_WORD(t.sh_name); + SWAP_WORD(t.sh_type); + SWAP_WORD(t.sh_flags); + SWAP_ADDR32(t.sh_addr); + SWAP_OFF32(t.sh_offset); + SWAP_WORD(t.sh_size); + SWAP_WORD(t.sh_link); + SWAP_WORD(t.sh_info); + SWAP_WORD(t.sh_addralign); + SWAP_WORD(t.sh_entsize); + /**/ + } + /* Write an Elf32_Shdr */ + WRITE_WORD(dst,t.sh_name); + WRITE_WORD(dst,t.sh_type); + WRITE_WORD(dst,t.sh_flags); + WRITE_ADDR32(dst,t.sh_addr); + WRITE_OFF32(dst,t.sh_offset); + WRITE_WORD(dst,t.sh_size); + WRITE_WORD(dst,t.sh_link); + WRITE_WORD(dst,t.sh_info); + WRITE_WORD(dst,t.sh_addralign); + WRITE_WORD(dst,t.sh_entsize); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SHDR32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Shdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT); + d = ((Elf32_Shdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Shdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Shdr */ + READ_WORD(s,t.sh_name); + READ_WORD(s,t.sh_type); + READ_WORD(s,t.sh_flags); + READ_ADDR32(s,t.sh_addr); + READ_OFF32(s,t.sh_offset); + READ_WORD(s,t.sh_size); + READ_WORD(s,t.sh_link); + READ_WORD(s,t.sh_info); + READ_WORD(s,t.sh_addralign); + READ_WORD(s,t.sh_entsize); + /**/ + if (byteswap) { + /* Swap an Elf32_Shdr */ + SWAP_WORD(t.sh_name); + SWAP_WORD(t.sh_type); + SWAP_WORD(t.sh_flags); + SWAP_ADDR32(t.sh_addr); + SWAP_OFF32(t.sh_offset); + SWAP_WORD(t.sh_size); + SWAP_WORD(t.sh_link); + SWAP_WORD(t.sh_info); + SWAP_WORD(t.sh_addralign); + SWAP_WORD(t.sh_entsize); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SHDR64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Shdr t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Shdr *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Shdr */ + SWAP_WORD(t.sh_name); + SWAP_WORD(t.sh_type); + SWAP_XWORD(t.sh_flags); + SWAP_ADDR64(t.sh_addr); + SWAP_OFF64(t.sh_offset); + SWAP_XWORD(t.sh_size); + SWAP_WORD(t.sh_link); + SWAP_WORD(t.sh_info); + SWAP_XWORD(t.sh_addralign); + SWAP_XWORD(t.sh_entsize); + /**/ + } + /* Write an Elf64_Shdr */ + WRITE_WORD(dst,t.sh_name); + WRITE_WORD(dst,t.sh_type); + WRITE_XWORD(dst,t.sh_flags); + WRITE_ADDR64(dst,t.sh_addr); + WRITE_OFF64(dst,t.sh_offset); + WRITE_XWORD(dst,t.sh_size); + WRITE_WORD(dst,t.sh_link); + WRITE_WORD(dst,t.sh_info); + WRITE_XWORD(dst,t.sh_addralign); + WRITE_XWORD(dst,t.sh_entsize); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Shdr t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT); + d = ((Elf64_Shdr *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Shdr)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Shdr */ + READ_WORD(s,t.sh_name); + READ_WORD(s,t.sh_type); + READ_XWORD(s,t.sh_flags); + READ_ADDR64(s,t.sh_addr); + READ_OFF64(s,t.sh_offset); + READ_XWORD(s,t.sh_size); + READ_WORD(s,t.sh_link); + READ_WORD(s,t.sh_info); + READ_XWORD(s,t.sh_addralign); + READ_XWORD(s,t.sh_entsize); + /**/ + if (byteswap) { + /* Swap an Elf64_Shdr */ + SWAP_WORD(t.sh_name); + SWAP_WORD(t.sh_type); + SWAP_XWORD(t.sh_flags); + SWAP_ADDR64(t.sh_addr); + SWAP_OFF64(t.sh_offset); + SWAP_XWORD(t.sh_size); + SWAP_WORD(t.sh_link); + SWAP_WORD(t.sh_info); + SWAP_XWORD(t.sh_addralign); + SWAP_XWORD(t.sh_entsize); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SWORD_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sword t, *s = (Elf64_Sword *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_SWORD(t); + WRITE_SWORD(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_SWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sword t, *d = (Elf64_Sword *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Sword)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_SWORD(src,t); + SWAP_SWORD(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_SXWORD_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sxword t, *s = (Elf64_Sxword *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_SXWORD(t); + WRITE_SXWORD(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_SXWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sxword t, *d = (Elf64_Sxword *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Sxword)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_SXWORD(src,t); + SWAP_SXWORD(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_SYMINFO32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Syminfo t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Syminfo *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Syminfo */ + SWAP_HALF(t.si_boundto); + SWAP_HALF(t.si_flags); + /**/ + } + /* Write an Elf32_Syminfo */ + WRITE_HALF(dst,t.si_boundto); + WRITE_HALF(dst,t.si_flags); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SYMINFO32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Syminfo t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT); + d = ((Elf32_Syminfo *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Syminfo)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Syminfo */ + READ_HALF(s,t.si_boundto); + READ_HALF(s,t.si_flags); + /**/ + if (byteswap) { + /* Swap an Elf32_Syminfo */ + SWAP_HALF(t.si_boundto); + SWAP_HALF(t.si_flags); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SYMINFO64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Syminfo t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Syminfo *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Syminfo */ + SWAP_HALF(t.si_boundto); + SWAP_HALF(t.si_flags); + /**/ + } + /* Write an Elf64_Syminfo */ + WRITE_HALF(dst,t.si_boundto); + WRITE_HALF(dst,t.si_flags); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SYMINFO64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Syminfo t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT); + d = ((Elf64_Syminfo *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Syminfo)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Syminfo */ + READ_HALF(s,t.si_boundto); + READ_HALF(s,t.si_flags); + /**/ + if (byteswap) { + /* Swap an Elf64_Syminfo */ + SWAP_HALF(t.si_boundto); + SWAP_HALF(t.si_flags); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SYM32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Sym t, *s; + size_t c; + + (void) dsz; + + s = (Elf32_Sym *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf32_Sym */ + SWAP_WORD(t.st_name); + SWAP_ADDR32(t.st_value); + SWAP_WORD(t.st_size); + SWAP_BYTE(t.st_info); + SWAP_BYTE(t.st_other); + SWAP_HALF(t.st_shndx); + /**/ + } + /* Write an Elf32_Sym */ + WRITE_WORD(dst,t.st_name); + WRITE_ADDR32(dst,t.st_value); + WRITE_WORD(dst,t.st_size); + WRITE_BYTE(dst,t.st_info); + WRITE_BYTE(dst,t.st_other); + WRITE_HALF(dst,t.st_shndx); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SYM32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Sym t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf32_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT); + d = ((Elf32_Sym *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf32_Sym)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf32_Sym */ + READ_WORD(s,t.st_name); + READ_ADDR32(s,t.st_value); + READ_WORD(s,t.st_size); + READ_BYTE(s,t.st_info); + READ_BYTE(s,t.st_other); + READ_HALF(s,t.st_shndx); + /**/ + if (byteswap) { + /* Swap an Elf32_Sym */ + SWAP_WORD(t.st_name); + SWAP_ADDR32(t.st_value); + SWAP_WORD(t.st_size); + SWAP_BYTE(t.st_info); + SWAP_BYTE(t.st_other); + SWAP_HALF(t.st_shndx); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_SYM64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sym t, *s; + size_t c; + + (void) dsz; + + s = (Elf64_Sym *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + /* Swap an Elf64_Sym */ + SWAP_WORD(t.st_name); + SWAP_BYTE(t.st_info); + SWAP_BYTE(t.st_other); + SWAP_HALF(t.st_shndx); + SWAP_ADDR64(t.st_value); + SWAP_XWORD(t.st_size); + /**/ + } + /* Write an Elf64_Sym */ + WRITE_WORD(dst,t.st_name); + WRITE_BYTE(dst,t.st_info); + WRITE_BYTE(dst,t.st_other); + WRITE_HALF(dst,t.st_shndx); + WRITE_ADDR64(dst,t.st_value); + WRITE_XWORD(dst,t.st_size); + /**/ + } + + return (1); +} + +static int +_libelf_cvt_SYM64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Sym t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf64_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT); + d = ((Elf64_Sym *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf64_Sym)) + return (0); + + while (count--) { + s = s0; + /* Read an Elf64_Sym */ + READ_WORD(s,t.st_name); + READ_BYTE(s,t.st_info); + READ_BYTE(s,t.st_other); + READ_HALF(s,t.st_shndx); + READ_ADDR64(s,t.st_value); + READ_XWORD(s,t.st_size); + /**/ + if (byteswap) { + /* Swap an Elf64_Sym */ + SWAP_WORD(t.st_name); + SWAP_BYTE(t.st_info); + SWAP_BYTE(t.st_other); + SWAP_HALF(t.st_shndx); + SWAP_ADDR64(t.st_value); + SWAP_XWORD(t.st_size); + /**/ + } + *d-- = t; s0 -= fsz; + } + + return (1); +} + +static int +_libelf_cvt_WORD_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Word t, *s = (Elf64_Word *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_WORD(t); + WRITE_WORD(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_WORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Word t, *d = (Elf64_Word *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Word)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_WORD(src,t); + SWAP_WORD(t); + *d++ = t; + } + + return (1); +} + +static int +_libelf_cvt_XWORD_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Xword t, *s = (Elf64_Xword *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_XWORD(t); + WRITE_XWORD(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_XWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Xword t, *d = (Elf64_Xword *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf64_Xword)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_XWORD(src,t); + SWAP_XWORD(t); + *d++ = t; + } + + return (1); +} + + +static int +_libelf_cvt_VDEF32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Verdef t; + Elf32_Verdaux a; + const size_t verfsz = 20; + const size_t auxfsz = 8; + const size_t vermsz = sizeof(Elf32_Verdef); + const size_t auxmsz = sizeof(Elf32_Verdaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; + Elf32_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0U; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf32_Verdef structure. */ + t = *((Elf32_Verdef *) (uintptr_t) src); + + aux = t.vd_aux; + cnt = t.vd_cnt; + vnext = t.vd_next; + + if (byteswap) { + /* Swap an Elf32_Verdef */ + SWAP_HALF(t.vd_version); + SWAP_HALF(t.vd_flags); + SWAP_HALF(t.vd_ndx); + SWAP_HALF(t.vd_cnt); + SWAP_WORD(t.vd_hash); + SWAP_WORD(t.vd_aux); + SWAP_WORD(t.vd_next); + /**/ + } + + dst = dtmp; + /* Write an Elf32_Verdef */ + WRITE_HALF(dst,t.vd_version); + WRITE_HALF(dst,t.vd_flags); + WRITE_HALF(dst,t.vd_ndx); + WRITE_HALF(dst,t.vd_cnt); + WRITE_WORD(dst,t.vd_hash); + WRITE_WORD(dst,t.vd_aux); + WRITE_WORD(dst,t.vd_next); + /**/ + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf32_Verdaux structure. */ + a = *((Elf32_Verdaux *) (uintptr_t) srcaux); + anext = a.vda_next; + + if (byteswap) { + /* Swap an Elf32_Verdaux */ + SWAP_WORD(a.vda_name); + SWAP_WORD(a.vda_next); + /**/ + } + + dst = dstaux; + /* Write an Elf32_Verdaux */ + WRITE_WORD(dst,a.vda_name); + WRITE_WORD(dst,a.vda_next); + /**/ + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VDEF32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Verdef t, *dp; + Elf32_Verdaux a, *ap; + const size_t verfsz = 20; + const size_t auxfsz = 8; + const size_t vermsz = sizeof(Elf32_Verdef); + const size_t auxmsz = sizeof(Elf32_Verdaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; + Elf32_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0U; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a VDEF structure. */ + s = stmp; + /* Read an Elf32_Verdef */ + READ_HALF(s,t.vd_version); + READ_HALF(s,t.vd_flags); + READ_HALF(s,t.vd_ndx); + READ_HALF(s,t.vd_cnt); + READ_WORD(s,t.vd_hash); + READ_WORD(s,t.vd_aux); + READ_WORD(s,t.vd_next); + /**/ + if (byteswap) { + /* Swap an Elf32_Verdef */ + SWAP_HALF(t.vd_version); + SWAP_HALF(t.vd_flags); + SWAP_HALF(t.vd_ndx); + SWAP_HALF(t.vd_cnt); + SWAP_WORD(t.vd_hash); + SWAP_WORD(t.vd_aux); + SWAP_WORD(t.vd_next); + /**/ + } + + dp = (Elf32_Verdef *) (uintptr_t) dst; + *dp = t; + + aux = t.vd_aux; + cnt = t.vd_cnt; + vnext = t.vd_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + /* Read an Elf32_Verdaux */ + READ_WORD(s,a.vda_name); + READ_WORD(s,a.vda_next); + /**/ + + if (byteswap) { + /* Swap an Elf32_Verdaux */ + SWAP_WORD(a.vda_name); + SWAP_WORD(a.vda_next); + /**/ + } + + anext = a.vda_next; + + ap = ((Elf32_Verdaux *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VDEF64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Verdef t; + Elf64_Verdaux a; + const size_t verfsz = 20; + const size_t auxfsz = 8; + const size_t vermsz = sizeof(Elf64_Verdef); + const size_t auxmsz = sizeof(Elf64_Verdaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; + Elf64_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0U; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf64_Verdef structure. */ + t = *((Elf64_Verdef *) (uintptr_t) src); + + aux = t.vd_aux; + cnt = t.vd_cnt; + vnext = t.vd_next; + + if (byteswap) { + /* Swap an Elf64_Verdef */ + SWAP_HALF(t.vd_version); + SWAP_HALF(t.vd_flags); + SWAP_HALF(t.vd_ndx); + SWAP_HALF(t.vd_cnt); + SWAP_WORD(t.vd_hash); + SWAP_WORD(t.vd_aux); + SWAP_WORD(t.vd_next); + /**/ + } + + dst = dtmp; + /* Write an Elf64_Verdef */ + WRITE_HALF(dst,t.vd_version); + WRITE_HALF(dst,t.vd_flags); + WRITE_HALF(dst,t.vd_ndx); + WRITE_HALF(dst,t.vd_cnt); + WRITE_WORD(dst,t.vd_hash); + WRITE_WORD(dst,t.vd_aux); + WRITE_WORD(dst,t.vd_next); + /**/ + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf64_Verdaux structure. */ + a = *((Elf64_Verdaux *) (uintptr_t) srcaux); + anext = a.vda_next; + + if (byteswap) { + /* Swap an Elf64_Verdaux */ + SWAP_WORD(a.vda_name); + SWAP_WORD(a.vda_next); + /**/ + } + + dst = dstaux; + /* Write an Elf64_Verdaux */ + WRITE_WORD(dst,a.vda_name); + WRITE_WORD(dst,a.vda_next); + /**/ + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VDEF64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Verdef t, *dp; + Elf64_Verdaux a, *ap; + const size_t verfsz = 20; + const size_t auxfsz = 8; + const size_t vermsz = sizeof(Elf64_Verdef); + const size_t auxmsz = sizeof(Elf64_Verdaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; + Elf64_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0U; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a VDEF structure. */ + s = stmp; + /* Read an Elf64_Verdef */ + READ_HALF(s,t.vd_version); + READ_HALF(s,t.vd_flags); + READ_HALF(s,t.vd_ndx); + READ_HALF(s,t.vd_cnt); + READ_WORD(s,t.vd_hash); + READ_WORD(s,t.vd_aux); + READ_WORD(s,t.vd_next); + /**/ + if (byteswap) { + /* Swap an Elf64_Verdef */ + SWAP_HALF(t.vd_version); + SWAP_HALF(t.vd_flags); + SWAP_HALF(t.vd_ndx); + SWAP_HALF(t.vd_cnt); + SWAP_WORD(t.vd_hash); + SWAP_WORD(t.vd_aux); + SWAP_WORD(t.vd_next); + /**/ + } + + dp = (Elf64_Verdef *) (uintptr_t) dst; + *dp = t; + + aux = t.vd_aux; + cnt = t.vd_cnt; + vnext = t.vd_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + /* Read an Elf64_Verdaux */ + READ_WORD(s,a.vda_name); + READ_WORD(s,a.vda_next); + /**/ + + if (byteswap) { + /* Swap an Elf64_Verdaux */ + SWAP_WORD(a.vda_name); + SWAP_WORD(a.vda_next); + /**/ + } + + anext = a.vda_next; + + ap = ((Elf64_Verdaux *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VNEED32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Verneed t; + Elf32_Vernaux a; + const size_t verfsz = 16; + const size_t auxfsz = 16; + const size_t vermsz = sizeof(Elf32_Verneed); + const size_t auxmsz = sizeof(Elf32_Vernaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; + Elf32_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0U; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf32_Verneed structure. */ + t = *((Elf32_Verneed *) (uintptr_t) src); + + aux = t.vn_aux; + cnt = t.vn_cnt; + vnext = t.vn_next; + + if (byteswap) { + /* Swap an Elf32_Verneed */ + SWAP_HALF(t.vn_version); + SWAP_HALF(t.vn_cnt); + SWAP_WORD(t.vn_file); + SWAP_WORD(t.vn_aux); + SWAP_WORD(t.vn_next); + /**/ + } + + dst = dtmp; + /* Write an Elf32_Verneed */ + WRITE_HALF(dst,t.vn_version); + WRITE_HALF(dst,t.vn_cnt); + WRITE_WORD(dst,t.vn_file); + WRITE_WORD(dst,t.vn_aux); + WRITE_WORD(dst,t.vn_next); + /**/ + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf32_Vernaux structure. */ + a = *((Elf32_Vernaux *) (uintptr_t) srcaux); + anext = a.vna_next; + + if (byteswap) { + /* Swap an Elf32_Vernaux */ + SWAP_WORD(a.vna_hash); + SWAP_HALF(a.vna_flags); + SWAP_HALF(a.vna_other); + SWAP_WORD(a.vna_name); + SWAP_WORD(a.vna_next); + /**/ + } + + dst = dstaux; + /* Write an Elf32_Vernaux */ + WRITE_WORD(dst,a.vna_hash); + WRITE_HALF(dst,a.vna_flags); + WRITE_HALF(dst,a.vna_other); + WRITE_WORD(dst,a.vna_name); + WRITE_WORD(dst,a.vna_next); + /**/ + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VNEED32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf32_Verneed t, *dp; + Elf32_Vernaux a, *ap; + const size_t verfsz = 16; + const size_t auxfsz = 16; + const size_t vermsz = sizeof(Elf32_Verneed); + const size_t auxmsz = sizeof(Elf32_Vernaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; + Elf32_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0U; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a VNEED structure. */ + s = stmp; + /* Read an Elf32_Verneed */ + READ_HALF(s,t.vn_version); + READ_HALF(s,t.vn_cnt); + READ_WORD(s,t.vn_file); + READ_WORD(s,t.vn_aux); + READ_WORD(s,t.vn_next); + /**/ + if (byteswap) { + /* Swap an Elf32_Verneed */ + SWAP_HALF(t.vn_version); + SWAP_HALF(t.vn_cnt); + SWAP_WORD(t.vn_file); + SWAP_WORD(t.vn_aux); + SWAP_WORD(t.vn_next); + /**/ + } + + dp = (Elf32_Verneed *) (uintptr_t) dst; + *dp = t; + + aux = t.vn_aux; + cnt = t.vn_cnt; + vnext = t.vn_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + /* Read an Elf32_Vernaux */ + READ_WORD(s,a.vna_hash); + READ_HALF(s,a.vna_flags); + READ_HALF(s,a.vna_other); + READ_WORD(s,a.vna_name); + READ_WORD(s,a.vna_next); + /**/ + + if (byteswap) { + /* Swap an Elf32_Vernaux */ + SWAP_WORD(a.vna_hash); + SWAP_HALF(a.vna_flags); + SWAP_HALF(a.vna_other); + SWAP_WORD(a.vna_name); + SWAP_WORD(a.vna_next); + /**/ + } + + anext = a.vna_next; + + ap = ((Elf32_Vernaux *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VNEED64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Verneed t; + Elf64_Vernaux a; + const size_t verfsz = 16; + const size_t auxfsz = 16; + const size_t vermsz = sizeof(Elf64_Verneed); + const size_t auxmsz = sizeof(Elf64_Vernaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; + Elf64_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0U; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf64_Verneed structure. */ + t = *((Elf64_Verneed *) (uintptr_t) src); + + aux = t.vn_aux; + cnt = t.vn_cnt; + vnext = t.vn_next; + + if (byteswap) { + /* Swap an Elf64_Verneed */ + SWAP_HALF(t.vn_version); + SWAP_HALF(t.vn_cnt); + SWAP_WORD(t.vn_file); + SWAP_WORD(t.vn_aux); + SWAP_WORD(t.vn_next); + /**/ + } + + dst = dtmp; + /* Write an Elf64_Verneed */ + WRITE_HALF(dst,t.vn_version); + WRITE_HALF(dst,t.vn_cnt); + WRITE_WORD(dst,t.vn_file); + WRITE_WORD(dst,t.vn_aux); + WRITE_WORD(dst,t.vn_next); + /**/ + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf64_Vernaux structure. */ + a = *((Elf64_Vernaux *) (uintptr_t) srcaux); + anext = a.vna_next; + + if (byteswap) { + /* Swap an Elf64_Vernaux */ + SWAP_WORD(a.vna_hash); + SWAP_HALF(a.vna_flags); + SWAP_HALF(a.vna_other); + SWAP_WORD(a.vna_name); + SWAP_WORD(a.vna_next); + /**/ + } + + dst = dstaux; + /* Write an Elf64_Vernaux */ + WRITE_WORD(dst,a.vna_hash); + WRITE_HALF(dst,a.vna_flags); + WRITE_HALF(dst,a.vna_other); + WRITE_WORD(dst,a.vna_name); + WRITE_WORD(dst,a.vna_next); + /**/ + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_VNEED64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf64_Verneed t, *dp; + Elf64_Vernaux a, *ap; + const size_t verfsz = 16; + const size_t auxfsz = 16; + const size_t vermsz = sizeof(Elf64_Verneed); + const size_t auxmsz = sizeof(Elf64_Vernaux); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; + Elf64_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0U; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a VNEED structure. */ + s = stmp; + /* Read an Elf64_Verneed */ + READ_HALF(s,t.vn_version); + READ_HALF(s,t.vn_cnt); + READ_WORD(s,t.vn_file); + READ_WORD(s,t.vn_aux); + READ_WORD(s,t.vn_next); + /**/ + if (byteswap) { + /* Swap an Elf64_Verneed */ + SWAP_HALF(t.vn_version); + SWAP_HALF(t.vn_cnt); + SWAP_WORD(t.vn_file); + SWAP_WORD(t.vn_aux); + SWAP_WORD(t.vn_next); + /**/ + } + + dp = (Elf64_Verneed *) (uintptr_t) dst; + *dp = t; + + aux = t.vn_aux; + cnt = t.vn_cnt; + vnext = t.vn_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + /* Read an Elf64_Vernaux */ + READ_WORD(s,a.vna_hash); + READ_HALF(s,a.vna_flags); + READ_HALF(s,a.vna_other); + READ_WORD(s,a.vna_name); + READ_WORD(s,a.vna_next); + /**/ + + if (byteswap) { + /* Swap an Elf64_Vernaux */ + SWAP_WORD(a.vna_hash); + SWAP_HALF(a.vna_flags); + SWAP_HALF(a.vna_other); + SWAP_WORD(a.vna_name); + SWAP_WORD(a.vna_next); + /**/ + } + + anext = a.vna_next; + + ap = ((Elf64_Vernaux *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} +/*]*/ + +/* + * Sections of type ELF_T_BYTE are never byteswapped, consequently a + * simple memcpy suffices for both directions of conversion. + */ + +static int +_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + (void) byteswap; + if (dsz < count) + return (0); + if (dst != src) + (void) memcpy(dst, src, count); + return (1); +} + +/* + * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit + * words. Bloom filter data comes next, followed by hash buckets and the + * hash chain. + * + * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit + * wide on ELFCLASS32 objects. The other objects in this section are 32 + * bits wide. + * + * Argument srcsz denotes the number of bytes to be converted. In the + * 32-bit case we need to translate srcsz to a count of 32-bit words. + */ + +static int +_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + size_t sz; + uint64_t t64, *bloom64; + Elf_GNU_Hash_Header *gh; + uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; + uint32_t *buckets, *chains; + + sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ + if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) + return (0); + + /* Read in the section header and byteswap if needed. */ + READ_WORD(src, nbuckets); + READ_WORD(src, symndx); + READ_WORD(src, maskwords); + READ_WORD(src, shift2); + + srcsz -= sz; + + if (byteswap) { + SWAP_WORD(nbuckets); + SWAP_WORD(symndx); + SWAP_WORD(maskwords); + SWAP_WORD(shift2); + } + + /* Check source buffer and destination buffer sizes. */ + sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); + if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; + gh->gh_nbuckets = nbuckets; + gh->gh_symndx = symndx; + gh->gh_maskwords = maskwords; + gh->gh_shift2 = shift2; + + dsz -= sizeof(Elf_GNU_Hash_Header); + dst += sizeof(Elf_GNU_Hash_Header); + + bloom64 = (uint64_t *) (uintptr_t) dst; + + /* Copy bloom filter data. */ + for (n = 0; n < maskwords; n++) { + READ_XWORD(src, t64); + if (byteswap) + SWAP_XWORD(t64); + bloom64[n] = t64; + } + + /* The hash buckets follows the bloom filter. */ + dst += maskwords * sizeof(uint64_t); + buckets = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nbuckets; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + buckets[n] = t32; + } + + dst += nbuckets * sizeof(uint32_t); + + /* The hash chain follows the hash buckets. */ + dsz -= sz; + srcsz -= sz; + + if (dsz < srcsz) /* Destination lacks space. */ + return (0); + + nchains = (uint32_t) (srcsz / sizeof(uint32_t)); + chains = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nchains; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + *chains++ = t32; + } + + return (1); +} + +static int +_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + uint32_t *s32; + size_t sz, hdrsz; + uint64_t *s64, t64; + Elf_GNU_Hash_Header *gh; + uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; + + hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ + if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; + + t0 = nbuckets = gh->gh_nbuckets; + t1 = gh->gh_symndx; + t2 = maskwords = gh->gh_maskwords; + t3 = gh->gh_shift2; + + src += sizeof(Elf_GNU_Hash_Header); + srcsz -= sizeof(Elf_GNU_Hash_Header); + dsz -= hdrsz; + + sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * + sizeof(uint64_t); + + if (srcsz < sz || dsz < sz) + return (0); + + /* Write out the header. */ + if (byteswap) { + SWAP_WORD(t0); + SWAP_WORD(t1); + SWAP_WORD(t2); + SWAP_WORD(t3); + } + + WRITE_WORD(dst, t0); + WRITE_WORD(dst, t1); + WRITE_WORD(dst, t2); + WRITE_WORD(dst, t3); + + /* Copy the bloom filter and the hash table. */ + s64 = (uint64_t *) (uintptr_t) src; + for (n = 0; n < maskwords; n++) { + t64 = *s64++; + if (byteswap) + SWAP_XWORD(t64); + WRITE_WORD64(dst, t64); + } + + s32 = (uint32_t *) s64; + for (n = 0; n < nbuckets; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + srcsz -= sz; + dsz -= sz; + + /* Copy out the hash chains. */ + if (dsz < srcsz) + return (0); + + nchains = (uint32_t) (srcsz / sizeof(uint32_t)); + for (n = 0; n < nchains; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + return (1); +} + +/* + * Elf_Note structures comprise a fixed size header followed by variable + * length strings. The fixed size header needs to be byte swapped, but + * not the strings. + * + * Argument count denotes the total number of bytes to be converted. + * The destination buffer needs to be at least count bytes in size. + */ +static int +_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz, hdrsz; + + if (dsz < count) /* Destination buffer is too small. */ + return (0); + + hdrsz = 3 * sizeof(uint32_t); + if (count < hdrsz) /* Source too small. */ + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + /* Process all notes in the section. */ + while (count > hdrsz) { + /* Read the note header. */ + READ_WORD(src, namesz); + READ_WORD(src, descsz); + READ_WORD(src, type); + + /* Translate. */ + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + /* Copy out the translated note header. */ + en = (Elf_Note *) (uintptr_t) dst; + en->n_namesz = namesz; + en->n_descsz = descsz; + en->n_type = type; + + dsz -= sizeof(Elf_Note); + dst += sizeof(Elf_Note); + count -= hdrsz; + + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); + + sz = namesz + descsz; + + if (count < sz || dsz < sz) /* Buffers are too small. */ + return (0); + + /* Copy the remainder of the note as-is. */ + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + + count -= sz; + dsz -= sz; + } + + return (1); +} + +static int +_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz; + + if (dsz < count) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + while (count > sizeof(Elf_Note)) { + + en = (Elf_Note *) (uintptr_t) src; + namesz = en->n_namesz; + descsz = en->n_descsz; + type = en->n_type; + + sz = namesz; + ROUNDUP2(sz, 4U); + sz += descsz; + ROUNDUP2(sz, 4U); + + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + WRITE_WORD(dst, namesz); + WRITE_WORD(dst, descsz); + WRITE_WORD(dst, type); + + src += sizeof(Elf_Note); + count -= sizeof(Elf_Note); + + if (count < sz) + sz = count; + + /* Copy the remainder of the note as-is. */ + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + count -= sz; + } + + return (1); +} + +struct converters { + int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); +}; + + +static struct converters cvt[ELF_T_NUM] = { + /*[*/ + [ELF_T_ADDR] = { + .tof32 = _libelf_cvt_ADDR32_tof, + .tom32 = _libelf_cvt_ADDR32_tom, + .tof64 = _libelf_cvt_ADDR64_tof, + .tom64 = _libelf_cvt_ADDR64_tom + }, + + [ELF_T_CAP] = { + .tof32 = _libelf_cvt_CAP32_tof, + .tom32 = _libelf_cvt_CAP32_tom, + .tof64 = _libelf_cvt_CAP64_tof, + .tom64 = _libelf_cvt_CAP64_tom + }, + + [ELF_T_DYN] = { + .tof32 = _libelf_cvt_DYN32_tof, + .tom32 = _libelf_cvt_DYN32_tom, + .tof64 = _libelf_cvt_DYN64_tof, + .tom64 = _libelf_cvt_DYN64_tom + }, + + [ELF_T_EHDR] = { + .tof32 = _libelf_cvt_EHDR32_tof, + .tom32 = _libelf_cvt_EHDR32_tom, + .tof64 = _libelf_cvt_EHDR64_tof, + .tom64 = _libelf_cvt_EHDR64_tom + }, + + [ELF_T_GNUHASH] = { + .tof32 = _libelf_cvt_GNUHASH32_tof, + .tom32 = _libelf_cvt_GNUHASH32_tom, + .tof64 = _libelf_cvt_GNUHASH64_tof, + .tom64 = _libelf_cvt_GNUHASH64_tom + }, + + [ELF_T_HALF] = { + .tof32 = _libelf_cvt_HALF_tof, + .tom32 = _libelf_cvt_HALF_tom, + .tof64 = _libelf_cvt_HALF_tof, + .tom64 = _libelf_cvt_HALF_tom + }, + + [ELF_T_LWORD] = { + .tof32 = _libelf_cvt_LWORD_tof, + .tom32 = _libelf_cvt_LWORD_tom, + .tof64 = _libelf_cvt_LWORD_tof, + .tom64 = _libelf_cvt_LWORD_tom + }, + + [ELF_T_MOVE] = { + .tof32 = _libelf_cvt_MOVE32_tof, + .tom32 = _libelf_cvt_MOVE32_tom, + .tof64 = _libelf_cvt_MOVE64_tof, + .tom64 = _libelf_cvt_MOVE64_tom + }, + + [ELF_T_OFF] = { + .tof32 = _libelf_cvt_OFF32_tof, + .tom32 = _libelf_cvt_OFF32_tom, + .tof64 = _libelf_cvt_OFF64_tof, + .tom64 = _libelf_cvt_OFF64_tom + }, + + [ELF_T_PHDR] = { + .tof32 = _libelf_cvt_PHDR32_tof, + .tom32 = _libelf_cvt_PHDR32_tom, + .tof64 = _libelf_cvt_PHDR64_tof, + .tom64 = _libelf_cvt_PHDR64_tom + }, + + [ELF_T_REL] = { + .tof32 = _libelf_cvt_REL32_tof, + .tom32 = _libelf_cvt_REL32_tom, + .tof64 = _libelf_cvt_REL64_tof, + .tom64 = _libelf_cvt_REL64_tom + }, + + [ELF_T_RELA] = { + .tof32 = _libelf_cvt_RELA32_tof, + .tom32 = _libelf_cvt_RELA32_tom, + .tof64 = _libelf_cvt_RELA64_tof, + .tom64 = _libelf_cvt_RELA64_tom + }, + + [ELF_T_SHDR] = { + .tof32 = _libelf_cvt_SHDR32_tof, + .tom32 = _libelf_cvt_SHDR32_tom, + .tof64 = _libelf_cvt_SHDR64_tof, + .tom64 = _libelf_cvt_SHDR64_tom + }, + + [ELF_T_SWORD] = { + .tof32 = _libelf_cvt_SWORD_tof, + .tom32 = _libelf_cvt_SWORD_tom, + .tof64 = _libelf_cvt_SWORD_tof, + .tom64 = _libelf_cvt_SWORD_tom + }, + + [ELF_T_SXWORD] = { + .tof32 = NULL, + .tom32 = NULL, + .tof64 = _libelf_cvt_SXWORD_tof, + .tom64 = _libelf_cvt_SXWORD_tom + }, + + [ELF_T_SYMINFO] = { + .tof32 = _libelf_cvt_SYMINFO32_tof, + .tom32 = _libelf_cvt_SYMINFO32_tom, + .tof64 = _libelf_cvt_SYMINFO64_tof, + .tom64 = _libelf_cvt_SYMINFO64_tom + }, + + [ELF_T_SYM] = { + .tof32 = _libelf_cvt_SYM32_tof, + .tom32 = _libelf_cvt_SYM32_tom, + .tof64 = _libelf_cvt_SYM64_tof, + .tom64 = _libelf_cvt_SYM64_tom + }, + + [ELF_T_VDEF] = { + .tof32 = _libelf_cvt_VDEF32_tof, + .tom32 = _libelf_cvt_VDEF32_tom, + .tof64 = _libelf_cvt_VDEF64_tof, + .tom64 = _libelf_cvt_VDEF64_tom + }, + + [ELF_T_VNEED] = { + .tof32 = _libelf_cvt_VNEED32_tof, + .tom32 = _libelf_cvt_VNEED32_tom, + .tof64 = _libelf_cvt_VNEED64_tof, + .tom64 = _libelf_cvt_VNEED64_tom + }, + + [ELF_T_WORD] = { + .tof32 = _libelf_cvt_WORD_tof, + .tom32 = _libelf_cvt_WORD_tom, + .tof64 = _libelf_cvt_WORD_tof, + .tom64 = _libelf_cvt_WORD_tom + }, + + [ELF_T_XWORD] = { + .tof32 = NULL, + .tom32 = NULL, + .tof64 = _libelf_cvt_XWORD_tof, + .tom64 = _libelf_cvt_XWORD_tom + }, + + + /*]*/ + + /* + * Types that need hand-coded converters follow. + */ + + [ELF_T_BYTE] = { + .tof32 = _libelf_cvt_BYTE_tox, + .tom32 = _libelf_cvt_BYTE_tox, + .tof64 = _libelf_cvt_BYTE_tox, + .tom64 = _libelf_cvt_BYTE_tox + }, + + [ELF_T_NOTE] = { + .tof32 = _libelf_cvt_NOTE_tof, + .tom32 = _libelf_cvt_NOTE_tom, + .tof64 = _libelf_cvt_NOTE_tof, + .tom64 = _libelf_cvt_NOTE_tom + } +}; + +/* + * Return a translator function for the specified ELF section type, conversion + * direction, ELF class and ELF machine. + */ +_libelf_translator_function * +_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine) +{ + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + assert(t >= ELF_T_FIRST && t <= ELF_T_LAST); + + /* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */ + (void) elfmachine; + + return ((elfclass == ELFCLASS32) ? + (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : + (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); +} diff --git a/contrib/elftoolchain/libelf/libelf_convert.m4 b/contrib/elftoolchain/libelf/libelf_convert.m4 new file mode 100644 index 0000000000..58c4a38821 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_convert.m4 @@ -0,0 +1,1096 @@ +/*- + * Copyright (c) 2006-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_convert.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) + +# Generate conversion routines for converting between in-memory and +# file representations of Elf data structures. +# +# These conversions use the type information defined in `elf_types.m4'. + +include(SRCDIR`/elf_types.m4') + +# For the purposes of generating conversion code, ELF types may be +# classified according to the following characteristics: +# +# 1. Whether the ELF type can be directly mapped to an integral C +# language type. For example, the ELF_T_WORD type maps directly to +# a 'uint32_t', but ELF_T_GNUHASH lacks a matching C type. +# +# 2. Whether the type has word size dependent variants. For example, +# ELT_T_EHDR is represented using C types Elf32_Ehdr and El64_Ehdr, +# and the ELF_T_ADDR and ELF_T_OFF types have integral C types that +# can be 32- or 64- bit wide. +# +# 3. Whether the ELF types has a fixed representation or not. For +# example, the ELF_T_SYM type has a fixed size file representation, +# some types like ELF_T_NOTE and ELF_T_GNUHASH use a variable size +# representation. +# +# We use m4 macros to generate conversion code for ELF types that have +# a fixed size representation. Conversion functions for the remaining +# types are coded by hand. +# +#* Handling File and Memory Representations +# +# `In-memory' representations of an Elf data structure use natural +# alignments and native byte ordering. This allows pointer arithmetic +# and casting to work as expected. On the other hand, the `file' +# representation of an ELF data structure could possibly be packed +# tighter than its `in-memory' representation, and could be of a +# differing byte order. Reading ELF objects that are members of `ar' +# archives present an additional complication: `ar' pads file data to +# even addresses, so file data structures in an archive member +# residing inside an `ar' archive could be at misaligned memory +# addresses when brought into memory. +# +# In summary, casting the `char *' pointers that point to memory +# representations (i.e., source pointers for the *_tof() functions and +# the destination pointers for the *_tom() functions), is safe, as +# these pointers should be correctly aligned for the memory type +# already. However, pointers to file representations have to be +# treated as being potentially unaligned and no casting can be done. + +# NOCVT(TYPE) -- Do not generate the cvt[] structure entry for TYPE +define(`NOCVT',`define(`NOCVT_'$1,1)') + +# NOFUNC(TYPE) -- Do not generate a conversion function for TYPE +define(`NOFUNC',`define(`NOFUNC_'$1,1)') + +# IGNORE(TYPE) -- Completely ignore the type. +define(`IGNORE',`NOCVT($1)NOFUNC($1)') + +# Mark ELF types that should not be processed by the M4 macros below. + +# Types for which we use functions with non-standard names. +IGNORE(`BYTE') # Uses a wrapper around memcpy(). +IGNORE(`NOTE') # Not a fixed size type. + +# Types for which we supply hand-coded functions. +NOFUNC(`GNUHASH') # A type with complex internal structure. +NOFUNC(`VDEF') # See MAKE_VERSION_CONVERTERS below. +NOFUNC(`VNEED') # .. + +# Unimplemented types. +IGNORE(`MOVEP') + +# ELF types that don't exist in a 32-bit world. +NOFUNC(`XWORD32') +NOFUNC(`SXWORD32') + +# `Primitive' ELF types are those that are an alias for an integral +# type. As they have no internal structure, they can be copied using +# a `memcpy()', and byteswapped in straightforward way. +# +# Mark all ELF types that directly map to integral C types. +define(`PRIM_ADDR', 1) +define(`PRIM_BYTE', 1) +define(`PRIM_HALF', 1) +define(`PRIM_LWORD', 1) +define(`PRIM_OFF', 1) +define(`PRIM_SWORD', 1) +define(`PRIM_SXWORD', 1) +define(`PRIM_WORD', 1) +define(`PRIM_XWORD', 1) + +# Note the primitive types that are size-dependent. +define(`SIZEDEP_ADDR', 1) +define(`SIZEDEP_OFF', 1) + +# Generate conversion functions for primitive types. +# +# Macro use: MAKEPRIMFUNCS(ELFTYPE,CTYPE,TYPESIZE,SYMSIZE) +# `$1': Name of the ELF type. +# `$2': C structure name suffix. +# `$3': ELF class specifier for types, one of [`32', `64']. +# `$4': Additional ELF class specifier, one of [`', `32', `64']. +# +# Generates a pair of conversion functions. +define(`MAKEPRIMFUNCS',` +static int +_libelf_cvt_$1$4_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_$1$4(t); + WRITE_$1$4(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_$1$4_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf$3_$2)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_$1$4(src,t); + SWAP_$1$4(t); + *d++ = t; + } + + return (1); +} +') + +# +# Handling composite ELF types +# + +# SWAP_FIELD(FIELDNAME,ELFTYPE) -- Generate code to swap one field. +define(`SWAP_FIELD', + `ifdef(`SIZEDEP_'$2, + `SWAP_$2'SZ()`(t.$1); + ', + `SWAP_$2(t.$1); + ')') + +# SWAP_MEMBERS(STRUCT) -- Iterate over a structure definition. +define(`SWAP_MEMBERS', + `ifelse($#,1,`/**/', + `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') + +# SWAP_STRUCT(CTYPE,SIZE) -- Generate code to swap an ELF structure. +define(`SWAP_STRUCT', + `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ + SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + +# WRITE_FIELD(ELFTYPE,FIELDNAME) -- Generate code to write one field. +define(`WRITE_FIELD', + `ifdef(`SIZEDEP_'$2, + `WRITE_$2'SZ()`(dst,t.$1); + ', + `WRITE_$2(dst,t.$1); + ')') + +# WRITE_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. +define(`WRITE_MEMBERS', + `ifelse($#,1,`/**/', + `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') + +# WRITE_STRUCT(CTYPE,SIZE) -- Generate code to write out an ELF structure. +define(`WRITE_STRUCT', + `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ + WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + +# READ_FIELD(ELFTYPE,CTYPE) -- Generate code to read one field. +define(`READ_FIELD', + `ifdef(`SIZEDEP_'$2, + `READ_$2'SZ()`(s,t.$1); + ', + `READ_$2(s,t.$1); + ')') + +# READ_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. +define(`READ_MEMBERS', + `ifelse($#,1,`/**/', + `READ_FIELD($1)READ_MEMBERS(shift($@))')') + +# READ_STRUCT(CTYPE,SIZE) -- Generate code to read an ELF structure. +define(`READ_STRUCT', + `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ + READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + + +# MAKECOMPFUNCS -- Generate converters for composite ELF structures. +# +# When converting data to file representation, the source pointer will +# be naturally aligned for a data structure's in-memory +# representation. When converting data to memory, the destination +# pointer will be similarly aligned. +# +# For in-place conversions, when converting to file representations, +# the source buffer is large enough to hold `file' data. When +# converting from file to memory, we need to be careful to work +# `backwards', to avoid overwriting unconverted data. +# +# Macro use: +# `$1': Name of the ELF type. +# `$2': C structure name suffix. +# `$3': ELF class specifier, one of [`', `32', `64'] +define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',` +static int +_libelf_cvt_$1$3_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$3_$2 t, *s; + size_t c; + + (void) dsz; + + s = (Elf$3_$2 *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + SWAP_STRUCT($2,$3) + } + WRITE_STRUCT($2,$3) + } + + return (1); +} + +static int +_libelf_cvt_$1$3_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$3_$2 t, *d; + unsigned char *s,*s0; + size_t fsz; + + fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); + d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); + s0 = src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf$3_$2)) + return (0); + + while (count--) { + s = s0; + READ_STRUCT($2,$3) + if (byteswap) { + SWAP_STRUCT($2,$3) + } + *d-- = t; s0 -= fsz; + } + + return (1); +} +')') + +# MAKE_TYPE_CONVERTER(ELFTYPE,CTYPE) +# +# Make type convertor functions from the type definition +# of the ELF type: +# - Skip convertors marked as `NOFUNC'. +# - Invoke `MAKEPRIMFUNCS' or `MAKECOMPFUNCS' as appropriate. +define(`MAKE_TYPE_CONVERTER', + `ifdef(`NOFUNC_'$1,`', + `ifdef(`PRIM_'$1, + `ifdef(`SIZEDEP_'$1, + `MAKEPRIMFUNCS($1,$2,32,32)dnl + MAKEPRIMFUNCS($1,$2,64,64)', + `MAKEPRIMFUNCS($1,$2,64)')', + `MAKECOMPFUNCS($1,$2,32)dnl + MAKECOMPFUNCS($1,$2,64)')')') + +# MAKE_TYPE_CONVERTERS(ELFTYPELIST) -- Generate conversion functions. +define(`MAKE_TYPE_CONVERTERS', + `ifelse($#,1,`', + `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') + + +# +# Macros to generate entries for the table of convertors. +# + +# CONV(ELFTYPE,SIZE,DIRECTION) +# +# Generate the name of a convertor function. +define(`CONV', + `ifdef(`NOFUNC_'$1$2, + `.$3$2 = NULL', + `ifdef(`PRIM_'$1, + `ifdef(`SIZEDEP_'$1, + `.$3$2 = _libelf_cvt_$1$2_$3', + `.$3$2 = _libelf_cvt_$1_$3')', + `.$3$2 = _libelf_cvt_$1$2_$3')')') + +# CONVERTER_NAME(ELFTYPE) +# +# Generate the contents of one `struct cvt' instance. +define(`CONVERTER_NAME', + `ifdef(`NOCVT_'$1,`', + ` [ELF_T_$1] = { + CONV($1,32,tof), + CONV($1,32,tom), + CONV($1,64,tof), + CONV($1,64,tom) + }, + +')') + +# CONVERTER_NAMES(ELFTYPELIST) +# +# Generate the `struct cvt[]' array. +define(`CONVERTER_NAMES', + `ifelse($#,1,`', + `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') + +# +# Handling ELF version sections. +# + +# _FSZ(FIELD,BASETYPE) - return the file size for a field. +define(`_FSZ', + `ifelse($2,`HALF',2, + $2,`WORD',4)') + +# FSZ(STRUCT) - determine the file size of a structure. +define(`FSZ', + `ifelse($#,1,0, + `eval(_FSZ($1) + FSZ(shift($@)))')') + +# MAKE_VERSION_CONVERTERS(TYPE,BASE,AUX,PFX) -- Generate conversion +# functions for versioning structures. +define(`MAKE_VERSION_CONVERTERS', + `MAKE_VERSION_CONVERTER($1,$2,$3,$4,32) + MAKE_VERSION_CONVERTER($1,$2,$3,$4,64)') + +# MAKE_VERSION_CONVERTOR(TYPE,CBASE,CAUX,PFX,SIZE) -- Generate a +# conversion function. +define(`MAKE_VERSION_CONVERTER',` +static int +_libelf_cvt_$1$5_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$5_$2 t; + Elf$5_$3 a; + const size_t verfsz = FSZ(Elf$5_$2_DEF); + const size_t auxfsz = FSZ(Elf$5_$3_DEF); + const size_t vermsz = sizeof(Elf$5_$2); + const size_t auxmsz = sizeof(Elf$5_$3); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; + Elf$5_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0U; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf$5_$2 structure. */ + t = *((Elf$5_$2 *) (uintptr_t) src); + + aux = t.$4_aux; + cnt = t.$4_cnt; + vnext = t.$4_next; + + if (byteswap) { + SWAP_STRUCT($2, $5) + } + + dst = dtmp; + WRITE_STRUCT($2, $5) + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf$5_$3 structure. */ + a = *((Elf$5_$3 *) (uintptr_t) srcaux); + anext = a.$4a_next; + + if (byteswap) { + pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') + } + + dst = dstaux; + pushdef(`t',`a')WRITE_STRUCT($3, $5)popdef(`t') + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_$1$5_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + Elf$5_$2 t, *dp; + Elf$5_$3 a, *ap; + const size_t verfsz = FSZ(Elf$5_$2_DEF); + const size_t auxfsz = FSZ(Elf$5_$3_DEF); + const size_t vermsz = sizeof(Elf$5_$2); + const size_t auxmsz = sizeof(Elf$5_$3); + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; + Elf$5_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0U; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a $1 structure. */ + s = stmp; + READ_STRUCT($2, $5) + if (byteswap) { + SWAP_STRUCT($2, $5) + } + + dp = (Elf$5_$2 *) (uintptr_t) dst; + *dp = t; + + aux = t.$4_aux; + cnt = t.$4_cnt; + vnext = t.$4_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + pushdef(`t',`a')READ_STRUCT($3, $5)popdef(`t') + + if (byteswap) { + pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') + } + + anext = a.$4a_next; + + ap = ((Elf$5_$3 *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +}') + +divert(0) + +/* + * C macros to byte swap integral quantities. + */ + +#define SWAP_BYTE(X) do { (void) (X); } while (/*CONSTCOND*/0) +#define SWAP_IDENT(X) do { (void) (X); } while (/*CONSTCOND*/0) +#define SWAP_HALF(X) do { \ + uint16_t _x = (uint16_t) (X); \ + uint32_t _t = _x & 0xFFU; \ + _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ + (X) = (uint16_t) _t; \ + } while (/*CONSTCOND*/0) +#define _SWAP_WORD(X, T) do { \ + uint32_t _x = (uint32_t) (X); \ + uint32_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) +#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) +#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) +#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) +#define _SWAP_WORD64(X, T) do { \ + uint64_t _x = (uint64_t) (X); \ + uint64_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) +#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) +#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) +#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) +#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) + +/* + * C macros to write out various integral values. + * + * Note: + * - The destination pointer could be unaligned. + * - Values are written out in native byte order. + * - The destination pointer is incremented after the write. + */ +#define WRITE_BYTE(P,X) do { \ + unsigned char *const _p = (unsigned char *) (P); \ + _p[0] = (unsigned char) (X); \ + (P) = _p + 1; \ + } while (/*CONSTCOND*/0) +#define WRITE_HALF(P,X) do { \ + uint16_t _t = (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + (P) = _p + 2; \ + } while (/*CONSTCOND*/0) +#define WRITE_WORD(P,X) do { \ + uint32_t _t = (uint32_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + (P) = _p + 4; \ + } while (/*CONSTCOND*/0) +#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) +#define WRITE_OFF32(P,X) WRITE_WORD(P,X) +#define WRITE_SWORD(P,X) WRITE_WORD(P,X) +#define WRITE_WORD64(P,X) do { \ + uint64_t _t = (uint64_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + _p[4] = _q[4]; \ + _p[5] = _q[5]; \ + _p[6] = _q[6]; \ + _p[7] = _q[7]; \ + (P) = _p + 8; \ + } while (/*CONSTCOND*/0) +#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) +#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) +#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_IDENT(P,X) do { \ + (void) memcpy((P), (X), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (/*CONSTCOND*/0) + +/* + * C macros to read in various integral values. + * + * Note: + * - The source pointer could be unaligned. + * - Values are read in native byte order. + * - The source pointer is incremented appropriately. + */ + +#define READ_BYTE(P,X) do { \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + (X) = _p[0]; \ + (P) = (P) + 1; \ + } while (/*CONSTCOND*/0) +#define READ_HALF(P,X) do { \ + uint16_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + (P) = (P) + 2; \ + (X) = _t; \ + } while (/*CONSTCOND*/0) +#define _READ_WORD(P,X,T) do { \ + uint32_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + (P) = (P) + 4; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) +#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) +#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) +#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) +#define _READ_WORD64(P,X,T) do { \ + uint64_t _t; \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + _q[4] = _p[4]; \ + _q[5] = _p[5]; \ + _q[6] = _p[6]; \ + _q[7] = _p[7]; \ + (P) = (P) + 8; \ + (X) = (T) _t; \ + } while (/*CONSTCOND*/0) +#define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) +#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) +#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) +#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) +#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) +#define READ_IDENT(P,X) do { \ + (void) memcpy((X), (P), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (/*CONSTCOND*/0) + +#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) + +/*[*/ +MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) +MAKE_VERSION_CONVERTERS(VDEF,Verdef,Verdaux,vd) +MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) +/*]*/ + +/* + * Sections of type ELF_T_BYTE are never byteswapped, consequently a + * simple memcpy suffices for both directions of conversion. + */ + +static int +_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + (void) byteswap; + if (dsz < count) + return (0); + if (dst != src) + (void) memcpy(dst, src, count); + return (1); +} + +/* + * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit + * words. Bloom filter data comes next, followed by hash buckets and the + * hash chain. + * + * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit + * wide on ELFCLASS32 objects. The other objects in this section are 32 + * bits wide. + * + * Argument `srcsz' denotes the number of bytes to be converted. In the + * 32-bit case we need to translate `srcsz' to a count of 32-bit words. + */ + +static int +_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + size_t sz; + uint64_t t64, *bloom64; + Elf_GNU_Hash_Header *gh; + uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; + uint32_t *buckets, *chains; + + sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ + if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) + return (0); + + /* Read in the section header and byteswap if needed. */ + READ_WORD(src, nbuckets); + READ_WORD(src, symndx); + READ_WORD(src, maskwords); + READ_WORD(src, shift2); + + srcsz -= sz; + + if (byteswap) { + SWAP_WORD(nbuckets); + SWAP_WORD(symndx); + SWAP_WORD(maskwords); + SWAP_WORD(shift2); + } + + /* Check source buffer and destination buffer sizes. */ + sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); + if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; + gh->gh_nbuckets = nbuckets; + gh->gh_symndx = symndx; + gh->gh_maskwords = maskwords; + gh->gh_shift2 = shift2; + + dsz -= sizeof(Elf_GNU_Hash_Header); + dst += sizeof(Elf_GNU_Hash_Header); + + bloom64 = (uint64_t *) (uintptr_t) dst; + + /* Copy bloom filter data. */ + for (n = 0; n < maskwords; n++) { + READ_XWORD(src, t64); + if (byteswap) + SWAP_XWORD(t64); + bloom64[n] = t64; + } + + /* The hash buckets follows the bloom filter. */ + dst += maskwords * sizeof(uint64_t); + buckets = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nbuckets; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + buckets[n] = t32; + } + + dst += nbuckets * sizeof(uint32_t); + + /* The hash chain follows the hash buckets. */ + dsz -= sz; + srcsz -= sz; + + if (dsz < srcsz) /* Destination lacks space. */ + return (0); + + nchains = (uint32_t) (srcsz / sizeof(uint32_t)); + chains = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nchains; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + *chains++ = t32; + } + + return (1); +} + +static int +_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) +{ + uint32_t *s32; + size_t sz, hdrsz; + uint64_t *s64, t64; + Elf_GNU_Hash_Header *gh; + uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; + + hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ + if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; + + t0 = nbuckets = gh->gh_nbuckets; + t1 = gh->gh_symndx; + t2 = maskwords = gh->gh_maskwords; + t3 = gh->gh_shift2; + + src += sizeof(Elf_GNU_Hash_Header); + srcsz -= sizeof(Elf_GNU_Hash_Header); + dsz -= hdrsz; + + sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * + sizeof(uint64_t); + + if (srcsz < sz || dsz < sz) + return (0); + + /* Write out the header. */ + if (byteswap) { + SWAP_WORD(t0); + SWAP_WORD(t1); + SWAP_WORD(t2); + SWAP_WORD(t3); + } + + WRITE_WORD(dst, t0); + WRITE_WORD(dst, t1); + WRITE_WORD(dst, t2); + WRITE_WORD(dst, t3); + + /* Copy the bloom filter and the hash table. */ + s64 = (uint64_t *) (uintptr_t) src; + for (n = 0; n < maskwords; n++) { + t64 = *s64++; + if (byteswap) + SWAP_XWORD(t64); + WRITE_WORD64(dst, t64); + } + + s32 = (uint32_t *) s64; + for (n = 0; n < nbuckets; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + srcsz -= sz; + dsz -= sz; + + /* Copy out the hash chains. */ + if (dsz < srcsz) + return (0); + + nchains = (uint32_t) (srcsz / sizeof(uint32_t)); + for (n = 0; n < nchains; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + return (1); +} + +/* + * Elf_Note structures comprise a fixed size header followed by variable + * length strings. The fixed size header needs to be byte swapped, but + * not the strings. + * + * Argument `count' denotes the total number of bytes to be converted. + * The destination buffer needs to be at least `count' bytes in size. + */ +static int +_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz, hdrsz; + + if (dsz < count) /* Destination buffer is too small. */ + return (0); + + hdrsz = 3 * sizeof(uint32_t); + if (count < hdrsz) /* Source too small. */ + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + /* Process all notes in the section. */ + while (count > hdrsz) { + /* Read the note header. */ + READ_WORD(src, namesz); + READ_WORD(src, descsz); + READ_WORD(src, type); + + /* Translate. */ + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + /* Copy out the translated note header. */ + en = (Elf_Note *) (uintptr_t) dst; + en->n_namesz = namesz; + en->n_descsz = descsz; + en->n_type = type; + + dsz -= sizeof(Elf_Note); + dst += sizeof(Elf_Note); + count -= hdrsz; + + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); + + sz = namesz + descsz; + + if (count < sz || dsz < sz) /* Buffers are too small. */ + return (0); + + /* Copy the remainder of the note as-is. */ + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + + count -= sz; + dsz -= sz; + } + + return (1); +} + +static int +_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz; + + if (dsz < count) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + while (count > sizeof(Elf_Note)) { + + en = (Elf_Note *) (uintptr_t) src; + namesz = en->n_namesz; + descsz = en->n_descsz; + type = en->n_type; + + sz = namesz; + ROUNDUP2(sz, 4U); + sz += descsz; + ROUNDUP2(sz, 4U); + + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + WRITE_WORD(dst, namesz); + WRITE_WORD(dst, descsz); + WRITE_WORD(dst, type); + + src += sizeof(Elf_Note); + count -= sizeof(Elf_Note); + + if (count < sz) + sz = count; + + /* Copy the remainder of the note as-is. */ + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + count -= sz; + } + + return (1); +} + +struct converters { + int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); +}; + + +static struct converters cvt[ELF_T_NUM] = { + /*[*/ +CONVERTER_NAMES(ELF_TYPE_LIST) + /*]*/ + + /* + * Types that need hand-coded converters follow. + */ + + [ELF_T_BYTE] = { + .tof32 = _libelf_cvt_BYTE_tox, + .tom32 = _libelf_cvt_BYTE_tox, + .tof64 = _libelf_cvt_BYTE_tox, + .tom64 = _libelf_cvt_BYTE_tox + }, + + [ELF_T_NOTE] = { + .tof32 = _libelf_cvt_NOTE_tof, + .tom32 = _libelf_cvt_NOTE_tom, + .tof64 = _libelf_cvt_NOTE_tof, + .tom64 = _libelf_cvt_NOTE_tom + } +}; + +/* + * Return a translator function for the specified ELF section type, conversion + * direction, ELF class and ELF machine. + */ +_libelf_translator_function * +_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine) +{ + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + assert(t >= ELF_T_FIRST && t <= ELF_T_LAST); + + /* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */ + (void) elfmachine; + + return ((elfclass == ELFCLASS32) ? + (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : + (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); +} diff --git a/contrib/elftoolchain/libelf/libelf_data.c b/contrib/elftoolchain/libelf/libelf_data.c new file mode 100644 index 0000000000..3fa9c7e803 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_data.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_data.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +int +_libelf_xlate_shtype(uint32_t sht) +{ + /* + * Look for known section types. + */ + switch (sht) { + case SHT_DYNAMIC: + return (ELF_T_DYN); + case SHT_DYNSYM: + return (ELF_T_SYM); + case SHT_FINI_ARRAY: + return (ELF_T_ADDR); + case SHT_GNU_HASH: + return (ELF_T_GNUHASH); + case SHT_GNU_LIBLIST: + return (ELF_T_WORD); + case SHT_GROUP: + return (ELF_T_WORD); + case SHT_HASH: + return (ELF_T_WORD); + case SHT_INIT_ARRAY: + return (ELF_T_ADDR); + case SHT_NOBITS: + return (ELF_T_BYTE); + case SHT_NOTE: + return (ELF_T_NOTE); + case SHT_PREINIT_ARRAY: + return (ELF_T_ADDR); + case SHT_PROGBITS: + return (ELF_T_BYTE); + case SHT_REL: + return (ELF_T_REL); + case SHT_RELA: + return (ELF_T_RELA); + case SHT_STRTAB: + return (ELF_T_BYTE); + case SHT_SYMTAB: + return (ELF_T_SYM); + case SHT_SYMTAB_SHNDX: + return (ELF_T_WORD); + case SHT_SUNW_dof: + return (ELF_T_BYTE); + case SHT_SUNW_move: + return (ELF_T_MOVE); + case SHT_SUNW_syminfo: + return (ELF_T_SYMINFO); + case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ + return (ELF_T_VDEF); + case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ + return (ELF_T_VNEED); + case SHT_SUNW_versym: /* == SHT_GNU_versym */ + return (ELF_T_HALF); + default: + /* + * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e., + * OS, processor and user-defined section types) are + * legal, but since we do not know anything more about + * their semantics, we return a type of ELF_T_BYTE. + * + * The ELF specification uses 32 bit unsigned values for + * denoting section types, and defines SHT_HIUSER to be + * 0xFFFFFFFFUL (i.e., UINT32_MAX). Consequently, we only + * need to check that 'sht' is greater than or equal to + * SHT_LOOS. + */ + if (sht >= SHT_LOOS) + return (ELF_T_BYTE); + + /* + * Other values are unsupported. + */ + return (-1); + } +} diff --git a/contrib/elftoolchain/libelf/libelf_ehdr.c b/contrib/elftoolchain/libelf/libelf_ehdr.c new file mode 100644 index 0000000000..14c4f3b7d8 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ehdr.c @@ -0,0 +1,216 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_ehdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Retrieve counts for sections, phdrs and the section string table index + * from section header #0 of the ELF object. + */ +static int +_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, + uint16_t strndx) +{ + size_t fsz; + Elf_Scn *scn; + uint32_t shtype; + _libelf_translator_function *xlator; + + assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); + + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); + assert(fsz > 0); + + if (shoff + fsz < shoff) { /* Numeric overflow. */ + LIBELF_SET_ERROR(HEADER, 0); + return (0); + } + + if ((uint64_t) e->e_rawsize < shoff + fsz) { + LIBELF_SET_ERROR(HEADER, 0); + return (0); + } + + if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) + return (0); + + xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + (unsigned char *) e->e_rawfile + shoff, (size_t) 1, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + +#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ + scn->s_shdr.s_shdr64.M) + + if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (0); + } + + e->e_u.e_elf.e_nscn = (size_t) GET_SHDR_MEMBER(sh_size); + e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : + GET_SHDR_MEMBER(sh_info); + e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : + GET_SHDR_MEMBER(sh_link); +#undef GET_SHDR_MEMBER + + return (1); +} + +#define EHDR_INIT(E,SZ) do { \ + Elf##SZ##_Ehdr *eh = (E); \ + eh->e_ident[EI_MAG0] = ELFMAG0; \ + eh->e_ident[EI_MAG1] = ELFMAG1; \ + eh->e_ident[EI_MAG2] = ELFMAG2; \ + eh->e_ident[EI_MAG3] = ELFMAG3; \ + eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ + eh->e_ident[EI_DATA] = ELFDATANONE; \ + eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \ + eh->e_machine = EM_NONE; \ + eh->e_type = ELF_K_NONE; \ + eh->e_version = LIBELF_PRIVATE(version); \ + } while (/* CONSTCOND */ 0) + +void * +_libelf_ehdr(Elf *e, int ec, int allocate) +{ + void *ehdr; + size_t fsz, msz; + uint16_t phnum, shnum, strndx; + uint64_t shoff; + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (e->e_class != ELFCLASSNONE && e->e_class != ec) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if (e->e_version != EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return (NULL); + } + + if (e->e_class == ELFCLASSNONE) + e->e_class = ec; + + if (ec == ELFCLASS32) + ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; + else + ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; + + if (ehdr != NULL) /* already have a translated ehdr */ + return (ehdr); + + fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); + assert(fsz > 0); + + if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < (off_t) fsz) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT)) == 0) + return (NULL); + + if ((ehdr = calloc((size_t) 1, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; + EHDR_INIT(ehdr,32); + } else { + e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; + EHDR_INIT(ehdr,64); + } + + if (allocate) + e->e_flags |= ELF_F_DIRTY; + + if (e->e_cmd == ELF_C_WRITE) + return (ehdr); + + xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); + (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + + if (ec == ELFCLASS32) { + phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; + shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; + shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; + strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; + } else { + phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; + shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; + shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; + strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; + } + + if (shnum >= SHN_LORESERVE || + (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || + strndx == SHN_XINDEX))) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + /* + * If extended numbering is being used, read the correct + * number of sections and program header entries. + */ + if ((shnum == 0 && shoff != 0) || phnum == PN_XNUM || strndx == SHN_XINDEX) { + if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) + return (NULL); + } else { + /* not using extended numbering */ + e->e_u.e_elf.e_nphdr = phnum; + e->e_u.e_elf.e_nscn = shnum; + e->e_u.e_elf.e_strndx = strndx; + } + + return (ehdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_elfmachine.c b/contrib/elftoolchain/libelf/libelf_elfmachine.c new file mode 100644 index 0000000000..6bc8fb33ce --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_elfmachine.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2018 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_elfmachine.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * A convenience helper that returns the ELF machine architecture for + * a ELF descriptor. + */ +int +_libelf_elfmachine(Elf *e) +{ + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (!e) + return EM_NONE; + + assert(e->e_kind == ELF_K_ELF); + assert(e->e_class != ELFCLASSNONE); + + eh32 = NULL; + eh64 = NULL; + + switch (e->e_class) { + case ELFCLASS32: + eh32 = e->e_u.e_elf.e_ehdr.e_ehdr32; + return eh32 ? eh32->e_machine : EM_NONE; + case ELFCLASS64: + eh64 = e->e_u.e_elf.e_ehdr.e_ehdr64; + return eh64 ? eh64->e_machine : EM_NONE; + } + + return (EM_NONE); +} diff --git a/contrib/elftoolchain/libelf/libelf_extended.c b/contrib/elftoolchain/libelf/libelf_extended.c new file mode 100644 index 0000000000..6164aab98b --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_extended.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_extended.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Retrieve section #0, allocating a new section if needed. + */ +static Elf_Scn * +_libelf_getscn0(Elf *e) +{ + Elf_Scn *s; + + if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) + return (s); + + return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); +} + +int +_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) +{ + Elf_Scn *scn; + + if (shnum >= SHN_LORESERVE) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_size = (Elf32_Word) shnum; + else + scn->s_shdr.s_shdr64.sh_size = shnum; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + shnum = 0; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; + else + ((Elf64_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; + + + return (1); +} + +int +_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) +{ + Elf_Scn *scn; + + if (shstrndx >= SHN_LORESERVE) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_link = (Elf32_Word) shstrndx; + else + scn->s_shdr.s_shdr64.sh_link = (Elf64_Word) shstrndx; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + shstrndx = SHN_XINDEX; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; + else + ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; + + return (1); +} + +int +_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) +{ + Elf_Scn *scn; + + if (phnum >= PN_XNUM) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_info = (Elf32_Word) phnum; + else + scn->s_shdr.s_shdr64.sh_info = (Elf64_Word) phnum; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + phnum = PN_XNUM; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; + else + ((Elf64_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/libelf_fsize.c b/contrib/elftoolchain/libelf/libelf_fsize.c new file mode 100644 index 0000000000..cf8444a919 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_fsize.c @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_fsize.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM libelf_fsize.m4. */ + +/* + * Create an array of file sizes from the elf_type definitions + */ + + + +struct fsize { + size_t fsz32; + size_t fsz64; +}; + +static struct fsize fsize[ELF_T_NUM] = { +[ELF_T_ADDR] = { .fsz32 = sizeof(Elf32_Addr), .fsz64 = sizeof(Elf64_Addr) }, + +[ELF_T_BYTE] = { .fsz32 = 1, .fsz64 = 1 }, + +[ELF_T_CAP] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_DYN] = { .fsz32 = sizeof(Elf32_Sword)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Sxword)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_EHDR] = { .fsz32 = EI_NIDENT+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = EI_NIDENT+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Word)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Off)+sizeof(Elf64_Word)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, + +[ELF_T_GNUHASH] = { .fsz32 = 1, .fsz64 = 1 }, + +[ELF_T_HALF] = { .fsz32 = sizeof(Elf32_Half), .fsz64 = sizeof(Elf64_Half) }, + +[ELF_T_LWORD] = { .fsz32 = sizeof(Elf32_Lword), .fsz64 = sizeof(Elf64_Lword) }, + +[ELF_T_MOVE] = { .fsz32 = sizeof(Elf32_Lword)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Lword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, + +[ELF_T_MOVEP] = { .fsz32 = 0, .fsz64 = 0 }, + +[ELF_T_NOTE] = { .fsz32 = 1, .fsz64 = 1 }, + +[ELF_T_OFF] = { .fsz32 = sizeof(Elf32_Off), .fsz64 = sizeof(Elf64_Off) }, + +[ELF_T_PHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Off)+sizeof(Elf32_Addr)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Off)+sizeof(Elf64_Addr)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_REL] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_RELA] = { .fsz32 = sizeof(Elf32_Addr)+sizeof(Elf32_Word)+sizeof(Elf32_Sword)+0, .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+sizeof(Elf64_Sxword)+0 }, + +[ELF_T_SHDR] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Off)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+sizeof(Elf32_Word)+0, .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Addr)+sizeof(Elf64_Off)+sizeof(Elf64_Xword)+sizeof(Elf64_Word)+sizeof(Elf64_Word)+sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_SWORD] = { .fsz32 = sizeof(Elf32_Sword), .fsz64 = sizeof(Elf64_Sword) }, + +[ELF_T_SXWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Sxword) }, + +[ELF_T_SYMINFO] = { .fsz32 = sizeof(Elf32_Half)+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, + +[ELF_T_SYM] = { .fsz32 = sizeof(Elf32_Word)+sizeof(Elf32_Addr)+sizeof(Elf32_Word)+1+1+sizeof(Elf32_Half)+0, .fsz64 = sizeof(Elf64_Word)+1+1+sizeof(Elf64_Half)+sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, + +[ELF_T_VDEF] = { .fsz32 = 1, .fsz64 = 1 }, + +[ELF_T_VNEED] = { .fsz32 = 1, .fsz64 = 1 }, + +[ELF_T_WORD] = { .fsz32 = sizeof(Elf32_Word), .fsz64 = sizeof(Elf64_Word) }, + +[ELF_T_XWORD] = { .fsz32 = 0, .fsz64 = sizeof(Elf64_Xword) }, + + +}; + +size_t +_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) +{ + size_t sz; + + sz = 0; + if (v != EV_CURRENT) + LIBELF_SET_ERROR(VERSION, 0); + else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) + LIBELF_SET_ERROR(ARGUMENT, 0); + else { + sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; + if (sz == 0) + LIBELF_SET_ERROR(UNIMPL, 0); + } + + return (sz*c); +} diff --git a/contrib/elftoolchain/libelf/libelf_fsize.m4 b/contrib/elftoolchain/libelf/libelf_fsize.m4 new file mode 100644 index 0000000000..029791ba5e --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_fsize.m4 @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_fsize.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM __file__. */ + +/* + * Create an array of file sizes from the elf_type definitions + */ + +divert(-1) +include(SRCDIR`/elf_types.m4') + +/* + * Translations from structure definitions to the size of their file + * representations. + */ + +/* `Basic' types. */ +define(`BYTE_SIZE', 1) +define(`IDENT_SIZE', `EI_NIDENT') + +/* Types that have variable length. */ +define(`GNUHASH_SIZE', 1) +define(`NOTE_SIZE', 1) +define(`VDEF_SIZE', 1) +define(`VNEED_SIZE', 1) + +/* Currently unimplemented types. */ +define(`MOVEP_SIZE', 0) + +/* Overrides for 32 bit types that do not exist. */ +define(`XWORD_SIZE32', 0) +define(`SXWORD_SIZE32', 0) + +/* + * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. + */ + +define(`FSZ32',`_FSZ32($1_DEF)') +define(`_FSZ32', + `ifelse($#,1,0, + `_BSZ32($1)+_FSZ32(shift($@))')') +define(`_BSZ32',`$2_SIZE32') + +define(`FSZ64',`_FSZ64($1_DEF)') +define(`_FSZ64', + `ifelse($#,1,0, + `_BSZ64($1)+_FSZ64(shift($@))')') +define(`_BSZ64',`$2_SIZE64') + +/* + * DEFINE_ELF_FSIZES(TYPE,NAME) + * + * Shorthand for defining for 32 and 64 versions + * of elf type TYPE. + * + * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit + * sizes. + * + * Otherwise, look for a explicit 32/64 bit size definition for TYPE, + * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there + * is nothing further to do. + * + * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, + * compute an expression that adds up the sizes of the structure's + * constituents. + * + * If such a structure definition is not known, treat TYPE as a primitive + * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its + * file representation size. + */ + +define(`DEFINE_ELF_FSIZE', + `ifdef($1`_SIZE', + `define($1_SIZE32,$1_SIZE) + define($1_SIZE64,$1_SIZE)', + `ifdef($1`_SIZE32',`', + `ifdef(`Elf32_'$2`_DEF', + `define($1_SIZE32,FSZ32(Elf32_$2))', + `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') + ifdef($1`_SIZE64',`', + `ifdef(`Elf64_'$2`_DEF', + `define($1_SIZE64,FSZ64(Elf64_$2))', + `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') + +define(`DEFINE_ELF_FSIZES', + `ifelse($#,1,`', + `DEFINE_ELF_FSIZE($1) + DEFINE_ELF_FSIZES(shift($@))')') + +DEFINE_ELF_FSIZES(ELF_TYPE_LIST) +DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type + +define(`FSIZE', + `[ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, +') +define(`FSIZES', + `ifelse($#,1,`', + `FSIZE($1) +FSIZES(shift($@))')') + +divert(0) + +struct fsize { + size_t fsz32; + size_t fsz64; +}; + +static struct fsize fsize[ELF_T_NUM] = { +FSIZES(ELF_TYPE_LIST) +}; + +size_t +_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) +{ + size_t sz; + + sz = 0; + if (v != EV_CURRENT) + LIBELF_SET_ERROR(VERSION, 0); + else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) + LIBELF_SET_ERROR(ARGUMENT, 0); + else { + sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; + if (sz == 0) + LIBELF_SET_ERROR(UNIMPL, 0); + } + + return (sz*c); +} diff --git a/contrib/elftoolchain/libelf/libelf_memory.c b/contrib/elftoolchain/libelf/libelf_memory.c new file mode 100644 index 0000000000..858cef8ee5 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_memory.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_memory.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Create an ELF descriptor for a memory image, optionally reporting + * parse errors. + */ + +Elf * +_libelf_memory(unsigned char *image, size_t sz, int reporterror) +{ + Elf *e; + int e_class; + enum Elf_Error error; + unsigned int e_byteorder, e_version; + + assert(image != NULL); + assert(sz > 0); + + if ((e = _libelf_allocate_elf()) == NULL) + return (NULL); + + e->e_cmd = ELF_C_READ; + e->e_rawfile = image; + e->e_rawsize = (off_t) sz; + +#undef LIBELF_IS_ELF +#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ + (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ + (P)[EI_MAG3] == ELFMAG3) + + if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { + e_byteorder = image[EI_DATA]; + e_class = image[EI_CLASS]; + e_version = image[EI_VERSION]; + + error = ELF_E_NONE; + + if (e_version > EV_CURRENT) + error = ELF_E_VERSION; + else if ((e_byteorder != ELFDATA2LSB && e_byteorder != + ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class != + ELFCLASS64)) + error = ELF_E_HEADER; + + if (error != ELF_E_NONE) { + if (reporterror) { + LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0); + _libelf_release_elf(e); + return (NULL); + } + } else { + _libelf_init_elf(e, ELF_K_ELF); + + e->e_byteorder = e_byteorder; + e->e_class = e_class; + e->e_version = e_version; + } + } else if (sz >= SARMAG && + strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0) + return (_libelf_ar_open(e, reporterror)); + + return (e); +} diff --git a/contrib/elftoolchain/libelf/libelf_msize.c b/contrib/elftoolchain/libelf/libelf_msize.c new file mode 100644 index 0000000000..ce5784cd24 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_msize.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_msize.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM libelf_msize.m4. */ + +struct msize { + size_t msz32; + size_t msz64; +}; + + + +static struct msize msize[ELF_T_NUM] = { +[ELF_T_ADDR] = { .msz32 = sizeof(Elf32_Addr), .msz64 = sizeof(Elf64_Addr) }, + +[ELF_T_BYTE] = { .msz32 = 1, .msz64 = 1 }, + +[ELF_T_CAP] = { .msz32 = sizeof(Elf32_Cap), .msz64 = sizeof(Elf64_Cap) }, + +[ELF_T_DYN] = { .msz32 = sizeof(Elf32_Dyn), .msz64 = sizeof(Elf64_Dyn) }, + +[ELF_T_EHDR] = { .msz32 = sizeof(Elf32_Ehdr), .msz64 = sizeof(Elf64_Ehdr) }, + +[ELF_T_GNUHASH] = { .msz32 = 1, .msz64 = 1 }, + +[ELF_T_HALF] = { .msz32 = sizeof(Elf32_Half), .msz64 = sizeof(Elf64_Half) }, + +[ELF_T_LWORD] = { .msz32 = sizeof(Elf32_Lword), .msz64 = sizeof(Elf64_Lword) }, + +[ELF_T_MOVE] = { .msz32 = sizeof(Elf32_Move), .msz64 = sizeof(Elf64_Move) }, + +[ELF_T_MOVEP] = { .msz32 = 0, .msz64 = 0 }, + +[ELF_T_NOTE] = { .msz32 = 1, .msz64 = 1 }, + +[ELF_T_OFF] = { .msz32 = sizeof(Elf32_Off), .msz64 = sizeof(Elf64_Off) }, + +[ELF_T_PHDR] = { .msz32 = sizeof(Elf32_Phdr), .msz64 = sizeof(Elf64_Phdr) }, + +[ELF_T_REL] = { .msz32 = sizeof(Elf32_Rel), .msz64 = sizeof(Elf64_Rel) }, + +[ELF_T_RELA] = { .msz32 = sizeof(Elf32_Rela), .msz64 = sizeof(Elf64_Rela) }, + +[ELF_T_SHDR] = { .msz32 = sizeof(Elf32_Shdr), .msz64 = sizeof(Elf64_Shdr) }, + +[ELF_T_SWORD] = { .msz32 = sizeof(Elf32_Sword), .msz64 = sizeof(Elf64_Sword) }, + +[ELF_T_SXWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Sxword) }, + +[ELF_T_SYMINFO] = { .msz32 = sizeof(Elf32_Syminfo), .msz64 = sizeof(Elf64_Syminfo) }, + +[ELF_T_SYM] = { .msz32 = sizeof(Elf32_Sym), .msz64 = sizeof(Elf64_Sym) }, + +[ELF_T_VDEF] = { .msz32 = 1, .msz64 = 1 }, + +[ELF_T_VNEED] = { .msz32 = 1, .msz64 = 1 }, + +[ELF_T_WORD] = { .msz32 = sizeof(Elf32_Word), .msz64 = sizeof(Elf64_Word) }, + +[ELF_T_XWORD] = { .msz32 = 0, .msz64 = sizeof(Elf64_Xword) }, + + +}; + +/* + * Returns the memory size of the specified ELF type 't' of ELF + * class 'ec' and ELF version 'version'. + * + * If the specified combination of ELF type, class, and version is + * unsupported then a value of 0 will be returned and the appropriate + * library error code set. + */ +size_t +_libelf_msize(Elf_Type t, int elfclass, unsigned int version) +{ + size_t sz; + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); + + if (version != EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return (0); + } + + sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; + + if (sz == 0) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (0); + } + + return (sz); +} diff --git a/contrib/elftoolchain/libelf/libelf_msize.m4 b/contrib/elftoolchain/libelf/libelf_msize.m4 new file mode 100644 index 0000000000..be01ec11cc --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_msize.m4 @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_msize.m4 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* WARNING: GENERATED FROM __file__. */ + +struct msize { + size_t msz32; + size_t msz64; +}; + +divert(-1) +include(SRCDIR`/elf_types.m4') + +/* + * ELF types whose memory representations have a variable size. + */ +define(BYTE_SIZE, 1) +define(GNUHASH_SIZE, 1) +define(NOTE_SIZE, 1) +define(VDEF_SIZE, 1) +define(VNEED_SIZE, 1) + +/* + * Unimplemented types. + */ +define(MOVEP_SIZE, 0) +define(SXWORD_SIZE32, 0) +define(XWORD_SIZE32, 0) + +define(`DEFINE_ELF_MSIZE', + `ifdef($1`_SIZE', + `define($1_SIZE32,$1_SIZE) + define($1_SIZE64,$1_SIZE)', + `ifdef($1`_SIZE32',`', + `define($1_SIZE32,sizeof(Elf32_$2))') + ifdef($1`_SIZE64',`', + `define($1_SIZE64,sizeof(Elf64_$2))')')') +define(`DEFINE_ELF_MSIZES', + `ifelse($#,1,`', + `DEFINE_ELF_MSIZE($1) + DEFINE_ELF_MSIZES(shift($@))')') + +DEFINE_ELF_MSIZES(ELF_TYPE_LIST) + +define(`MSIZE', + `[ELF_T_$1] = { .msz32 = $1_SIZE32, .msz64 = $1_SIZE64 }, +') +define(`MSIZES', + `ifelse($#,1,`', + `MSIZE($1) +MSIZES(shift($@))')') + +divert(0) + +static struct msize msize[ELF_T_NUM] = { +MSIZES(ELF_TYPE_LIST) +}; + +/* + * Returns the memory size of the specified ELF type 't' of ELF + * class 'ec' and ELF version 'version'. + * + * If the specified combination of ELF type, class, and version is + * unsupported then a value of 0 will be returned and the appropriate + * library error code set. + */ +size_t +_libelf_msize(Elf_Type t, int elfclass, unsigned int version) +{ + size_t sz; + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); + + if (version != EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return (0); + } + + sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; + + if (sz == 0) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (0); + } + + return (sz); +} diff --git a/contrib/elftoolchain/libelf/libelf_open.c b/contrib/elftoolchain/libelf/libelf_open.c new file mode 100644 index 0000000000..c373eafb39 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_open.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ +#include +#include + +#include +#include +#include +#include +#include + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include +#endif + +ELFTC_VCSID("$Id: libelf_open.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +#define _LIBELF_INITSIZE (64*1024) + +/* + * Read from a device file, pipe or socket. + */ +static void * +_libelf_read_special_file(int fd, size_t *fsz) +{ + ssize_t readsz; + size_t bufsz, datasz; + unsigned char *buf, *t; + + datasz = 0; + readsz = 0; + bufsz = _LIBELF_INITSIZE; + if ((buf = malloc(bufsz)) == NULL) + goto resourceerror; + + /* + * Read data from the file descriptor till we reach EOF, or + * till an error is encountered. + */ + do { + /* Check if we need to expand the data buffer. */ + if (datasz == bufsz) { + bufsz *= 2; + if ((t = realloc(buf, bufsz)) == NULL) + goto resourceerror; + buf = t; + } + + do { + assert(bufsz - datasz > 0); + t = buf + datasz; + if ((readsz = read(fd, t, bufsz - datasz)) <= 0) + break; + datasz += (size_t) readsz; + } while (datasz < bufsz); + + } while (readsz > 0); + + if (readsz < 0) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + + assert(readsz == 0); + + /* + * Free up extra buffer space. + */ + if (bufsz > datasz) { + if (datasz > 0) { + if ((t = realloc(buf, datasz)) == NULL) + goto resourceerror; + buf = t; + } else { /* Zero bytes read. */ + LIBELF_SET_ERROR(ARGUMENT, 0); + free(buf); + buf = NULL; + } + } + + *fsz = datasz; + return (buf); + +resourceerror: + LIBELF_SET_ERROR(RESOURCE, 0); +error: + if (buf != NULL) + free(buf); + return (NULL); +} + +/* + * Read the contents of the file referenced by the file descriptor + * 'fd'. + */ + +Elf * +_libelf_open_object(int fd, Elf_Cmd c, int reporterror) +{ + Elf *e; + void *m; + mode_t mode; + size_t fsize; + struct stat sb; + unsigned int flags; + + assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); + + if (fstat(fd, &sb) < 0) { + LIBELF_SET_ERROR(IO, errno); + return (NULL); + } + + mode = sb.st_mode; + fsize = (size_t) sb.st_size; + + /* + * Reject unsupported file types. + */ + if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && + !S_ISSOCK(mode)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + /* + * For ELF_C_WRITE mode, allocate and return a descriptor. + */ + if (c == ELF_C_WRITE) { + if ((e = _libelf_allocate_elf()) != NULL) { + _libelf_init_elf(e, ELF_K_ELF); + e->e_byteorder = LIBELF_PRIVATE(byteorder); + e->e_fd = fd; + e->e_cmd = c; + if (!S_ISREG(mode)) + e->e_flags |= LIBELF_F_SPECIAL_FILE; + } + + return (e); + } + + + /* + * ELF_C_READ and ELF_C_RDWR mode. + */ + m = NULL; + flags = 0; + if (S_ISREG(mode)) { + + /* + * Reject zero length files. + */ + if (fsize == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + +#if ELFTC_HAVE_MMAP + /* + * Always map regular files in with 'PROT_READ' + * permissions. + * + * For objects opened in ELF_C_RDWR mode, when + * elf_update(3) is called, we remove this mapping, + * write file data out using write(2), and map the new + * contents back. + */ + m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0); + + if (m == MAP_FAILED) + m = NULL; + else + flags = LIBELF_F_RAWFILE_MMAP; +#endif + + /* + * Fallback to a read() if the call to mmap() failed, + * or if mmap() is not available. + */ + if (m == NULL) { + if ((m = malloc(fsize)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (read(fd, m, fsize) != (ssize_t) fsize) { + LIBELF_SET_ERROR(IO, errno); + free(m); + return (NULL); + } + + flags = LIBELF_F_RAWFILE_MALLOC; + } + } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) + flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; + else + return (NULL); + + if ((e = _libelf_memory(m, fsize, reporterror)) == NULL) { + assert((flags & LIBELF_F_RAWFILE_MALLOC) || + (flags & LIBELF_F_RAWFILE_MMAP)); + if (flags & LIBELF_F_RAWFILE_MALLOC) + free(m); +#if ELFTC_HAVE_MMAP + else + (void) munmap(m, fsize); +#endif + return (NULL); + } + + /* ar(1) archives aren't supported in RDWR mode. */ + if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { + (void) elf_end(e); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + e->e_flags |= flags; + e->e_fd = fd; + e->e_cmd = c; + + return (e); +} diff --git a/contrib/elftoolchain/libelf/libelf_phdr.c b/contrib/elftoolchain/libelf/libelf_phdr.c new file mode 100644 index 0000000000..9a579dac51 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_phdr.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_phdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +void * +_libelf_getphdr(Elf *e, int ec) +{ + size_t phnum; + size_t fsz, msz; + uint64_t phoff; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + void *ehdr, *phdr; + _libelf_translator_function *xlator; + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((phdr = (ec == ELFCLASS32 ? + (void *) e->e_u.e_elf.e_phdr.e_phdr32 : + (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) + return (phdr); + + /* + * Check the PHDR related fields in the EHDR for sanity. + */ + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + phnum = e->e_u.e_elf.e_nphdr; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + phoff = (uint64_t) eh32->e_phoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + phoff = (uint64_t) eh64->e_phoff; + } + + fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); + + assert(fsz > 0); + + if (phoff + fsz < phoff) { /* Numeric overflow. */ + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if ((uint64_t) e->e_rawsize < (phoff + fsz)) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if ((msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT)) == 0) + return (NULL); + + if ((phdr = calloc(phnum, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) + e->e_u.e_elf.e_phdr.e_phdr32 = phdr; + else + e->e_u.e_elf.e_phdr.e_phdr64 = phdr; + + + xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); + (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + + return (phdr); +} + +void * +_libelf_newphdr(Elf *e, int ec, size_t count) +{ + void *ehdr, *newphdr, *oldphdr; + size_t msz; + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + assert(e->e_class == ec); + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + assert(e->e_version == EV_CURRENT); + + if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0) + return (NULL); + + newphdr = NULL; + if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; + } else { + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; + } + + e->e_u.e_elf.e_nphdr = count; + + elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); + + return (newphdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_shdr.c b/contrib/elftoolchain/libelf/libelf_shdr.c new file mode 100644 index 0000000000..4dca8794e6 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_shdr.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_shdr.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +void * +_libelf_getshdr(Elf_Scn *s, int ec) +{ + Elf *e; + + if (s == NULL || (e = s->s_elf) == NULL || + e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASSNONE) + ec = e->e_class; + + if (ec != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + return ((void *) &s->s_shdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_xlate.c b/contrib/elftoolchain/libelf/libelf_xlate.c new file mode 100644 index 0000000000..2193af969b --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_xlate.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*@ELFTC-INCLUDE-SYS-CDEFS@*/ + +#include +#include + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_xlate.c 3977 2022-05-01 06:45:34Z jkoshy $"); + +/*@ELFTC-USE-DOWNSTREAM-VCSID@*/ + +/* + * Translate to/from the file representation of ELF objects. + * + * Translation could potentially involve the following + * transformations: + * + * - an endianness conversion, + * - a change of layout, as the file representation of ELF objects + * can differ from their in-memory representation. + * - a change in representation due to a layout version change. + */ + +Elf_Data * +_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, + int elfclass, int elfmachine, int direction) +{ + int byteswap; + size_t cnt, dsz, fsz, msz; + uintptr_t sb, se, db, de; + _libelf_translator_function *xlator; + + if (encoding == ELFDATANONE) + encoding = LIBELF_PRIVATE(byteorder); + + if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || + dst == NULL || src == NULL || dst == src) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + + if (dst->d_version != src->d_version) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (NULL); + } + + if (src->d_buf == NULL || dst->d_buf == NULL) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) + (src->d_type, (size_t) 1, src->d_version)) == 0) + return (NULL); + + if ((msz = _libelf_msize(src->d_type, elfclass, src->d_version)) == 0) + return (NULL); + + if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + /* + * Determine the number of objects that need to be converted, and + * the space required for the converted objects in the destination + * buffer. + */ + if (direction == ELF_TOMEMORY) { + cnt = (size_t) src->d_size / fsz; + dsz = cnt * msz; + } else { + cnt = (size_t) src->d_size / msz; + dsz = cnt * fsz; + } + + if (dst->d_size < dsz) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + sb = (uintptr_t) src->d_buf; + se = sb + (size_t) src->d_size; + db = (uintptr_t) dst->d_buf; + de = db + (size_t) dst->d_size; + + /* + * Check for overlapping buffers. Note that db == sb is + * allowed. + */ + if (db != sb && de > sb && se > db) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((direction == ELF_TOMEMORY ? db : sb) % + _libelf_malign(src->d_type, elfclass)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + dst->d_type = src->d_type; + dst->d_size = dsz; + + byteswap = encoding != LIBELF_PRIVATE(byteorder); + + if (src->d_size == 0 || + (db == sb && !byteswap && fsz == msz)) + return (dst); /* nothing more to do */ + + xlator = _libelf_get_translator(src->d_type, direction, elfclass, + elfmachine); + if (!xlator(dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + return (dst); +} diff --git a/contrib/elftoolchain/libelf/os.FreeBSD.mk b/contrib/elftoolchain/libelf/os.FreeBSD.mk new file mode 100644 index 0000000000..72834b757b --- /dev/null +++ b/contrib/elftoolchain/libelf/os.FreeBSD.mk @@ -0,0 +1,7 @@ +# +# Building for a FreeBSD target. +# +# $Id: os.FreeBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ + +# Symbol versioning support [FreeBSD 7.X and later] +VERSION_MAP= ${.CURDIR}/Version.map diff --git a/contrib/elftoolchain/libelf/os.Linux.mk b/contrib/elftoolchain/libelf/os.Linux.mk new file mode 100644 index 0000000000..2292b6ec5f --- /dev/null +++ b/contrib/elftoolchain/libelf/os.Linux.mk @@ -0,0 +1,31 @@ +# Enable additional warnings. +CFLAGS+= -Wa,--fatal-warnings +CFLAGS+= -Wall +CFLAGS+= -Wcast-align +CFLAGS+= -Wcast-qual +CFLAGS+= -Wchar-subscripts +CFLAGS+= -Wconversion +CFLAGS+= -Werror +CFLAGS+= -Wextra +CFLAGS+= -Wformat=2 +CFLAGS+= -Winline +CFLAGS+= -Wmissing-prototypes +CFLAGS+= -Wnested-externs +CFLAGS+= -Wempty-body +CFLAGS+= -Wformat-y2k +CFLAGS+= -Wformat-zero-length +CFLAGS+= -Wpointer-sign +CFLAGS+= -Wpointer-to-int-cast +CFLAGS+= -Wsign-compare +CFLAGS+= -Wunused-const-variable +CFLAGS+= -Wunused-parameter +CFLAGS+= -Wold-style-definition +CFLAGS+= -Wpointer-arith +CFLAGS+= -Wredundant-decls +CFLAGS+= -Wreturn-type +CFLAGS+= -Wshadow +CFLAGS+= -Wstrict-prototypes +CFLAGS+= -Wstrict-overflow +CFLAGS+= -Wswitch +CFLAGS+= -Wunused-parameter +CFLAGS+= -Wwrite-strings diff --git a/contrib/elftoolchain/libelf/os.NetBSD.mk b/contrib/elftoolchain/libelf/os.NetBSD.mk new file mode 100644 index 0000000000..96b833596d --- /dev/null +++ b/contrib/elftoolchain/libelf/os.NetBSD.mk @@ -0,0 +1,7 @@ +# +# Build recipes for NetBSD. +# +# $Id: os.NetBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ +# + +MKLINT= no # lint dies with a sigbus diff --git a/contrib/elftoolchain/libelftc/Makefile b/contrib/elftoolchain/libelftc/Makefile new file mode 100644 index 0000000000..cf4efc0589 --- /dev/null +++ b/contrib/elftoolchain/libelftc/Makefile @@ -0,0 +1,60 @@ +# $Id: Makefile 3601 2018-04-12 16:58:53Z jkoshy $ + +TOP= .. + +LIB= elftc + +SRCS= elftc_bfdtarget.c \ + elftc_copyfile.c \ + elftc_demangle.c \ + elftc_reloc_type_str.c \ + elftc_set_timestamps.c \ + elftc_string_table.c \ + elftc_timestamp.c \ + elftc_version.c \ + libelftc_bfdtarget.c \ + libelftc_dem_arm.c \ + libelftc_dem_gnu2.c \ + libelftc_dem_gnu3.c \ + libelftc_hash.c \ + libelftc_vstr.c + +INCS= libelftc.h +INCSDIR= /usr/include + +RELEASE= HEAD # Change this on release branches. + +SHLIB_MAJOR= 1 + +WARNS?= 6 + +ELFTC_VERSION_FILE= ${.OBJDIR}/elftc_version.c +CLEANFILES+= ${ELFTC_VERSION_FILE} + +LDADD+= -lelf + +MAN= elftc.3 \ + elftc_bfd_find_target.3 \ + elftc_copyfile.3 \ + elftc_demangle.3 \ + elftc_reloc_type_str.3 \ + elftc_set_timestamps.3 \ + elftc_string_table_create.3 \ + elftc_version.3 + +MLINKS= elftc_bfd_find_target.3 elftc_bfd_target_byteorder.3 \ + elftc_bfd_find_target.3 elftc_bfd_target_class.3 \ + elftc_bfd_find_target.3 elftc_bfd_target_flavor.3 \ + elftc_string_table_create.3 elftc_string_table_from_section.3 \ + elftc_string_table_create.3 elftc_string_table_destroy.3 \ + elftc_string_table_create.3 elftc_string_table_image.3 \ + elftc_string_table_create.3 elftc_string_table_insert.3 \ + elftc_string_table_create.3 elftc_string_table_lookup.3 + +.if !make(clean) && !make(clobber) && !make(obj) +.BEGIN: .SILENT + ${.CURDIR}/make-toolchain-version -t ${.CURDIR}/${TOP} \ + -r ${RELEASE} -h ${OS_HOST} -o ${ELFTC_VERSION_FILE} +.endif + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libelftc/Version.map b/contrib/elftoolchain/libelftc/Version.map new file mode 100644 index 0000000000..43f9e823b4 --- /dev/null +++ b/contrib/elftoolchain/libelftc/Version.map @@ -0,0 +1,18 @@ +/* + * $Id: Version.map 2574 2012-09-11 15:11:59Z jkoshy $ + */ + +R1.0 { +global: + elftc_bfd_find_target; + elftc_bfd_target_byteorder; + elftc_bfd_target_class; + elftc_bfd_target_flavor; + elftc_bfd_target_machine; + elftc_copyfile; + elftc_demangle; + elftc_set_timestamps; + elftc_version; +local: + *; +}; diff --git a/contrib/elftoolchain/libelftc/_libelftc.h b/contrib/elftoolchain/libelftc/_libelftc.h new file mode 100644 index 0000000000..1850d4b5b4 --- /dev/null +++ b/contrib/elftoolchain/libelftc/_libelftc.h @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2009 Kai Wang + * Copyright (c) 2007,2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: _libelftc.h 3877 2020-11-03 18:28:08Z jkoshy $ + */ + +#ifndef __LIBELFTC_H_ +#define __LIBELFTC_H_ + +#include + +#include "_elftc.h" + +struct _Elftc_Bfd_Target { + const char *bt_name; /* target name. */ + unsigned int bt_type; /* target type. */ + unsigned int bt_byteorder; /* elf target byteorder. */ + unsigned int bt_elfclass; /* elf target class (32/64bit). */ + unsigned int bt_machine; /* elf target arch. */ + unsigned int bt_osabi; /* elf target abi. */ +}; + +extern struct _Elftc_Bfd_Target _libelftc_targets[]; + +/** @brief Dynamic vector data for string. */ +struct vector_str { + /** Current size */ + size_t size; + /** Total capacity */ + size_t capacity; + /** String array */ + char **container; +}; + +#define BUFFER_GROWFACTOR 1.618 +#define BUFFER_GROW(x) (((x)+0.5)*BUFFER_GROWFACTOR) + +#define ELFTC_FAILURE 0 +#define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF)) +#define ELFTC_SUCCESS 1 + +#define VECTOR_DEF_CAPACITY 8 + + +#ifdef __cplusplus +extern "C" { +#endif +char *cpp_demangle_ARM(const char *_org); +char *cpp_demangle_gnu2(const char *_org); +char *cpp_demangle_gnu3(const char *_org); +bool is_cpp_mangled_ARM(const char *_org); +bool is_cpp_mangled_gnu2(const char *_org); +bool is_cpp_mangled_gnu3(const char *_org); +unsigned int libelftc_hash_string(const char *); +void vector_str_dest(struct vector_str *_vec); +int vector_str_find(const struct vector_str *_vs, const char *_str, + size_t _len); +char *vector_str_get_flat(const struct vector_str *_vs, size_t *_len); +bool vector_str_init(struct vector_str *_vs); +bool vector_str_pop(struct vector_str *_vs); +bool vector_str_push(struct vector_str *_vs, const char *_str, + size_t _len); +bool vector_str_push_vector(struct vector_str *_dst, + struct vector_str *_org); +bool vector_str_push_vector_head(struct vector_str *_dst, + struct vector_str *_org); +char *vector_str_substr(const struct vector_str *_vs, size_t _begin, + size_t _end, size_t *_rlen); +#ifdef __cplusplus +} +#endif + +#endif /* __LIBELFTC_H */ diff --git a/contrib/elftoolchain/libelftc/elftc.3 b/contrib/elftoolchain/libelftc/elftc.3 new file mode 100644 index 0000000000..03961597a7 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc.3 @@ -0,0 +1,85 @@ +.\" Copyright (c) 2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc.3 3871 2020-08-21 23:28:19Z emaste $ +.\" +.Dd August 21, 2020 +.Dt ELFTC 3 +.Os +.Sh NAME +.Nm elftc +.Nd support routines used in the Elftoolchain project +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Sh DESCRIPTION +The +.Lb libelftc +provides support routines used for developing the utilities in the +Elftoolchain source tree. +.Pp +This manual page serves as an overview of the functionality in this +library. +Additional reference information may be found in the individual +manual pages for the functions listed below. +.Ss Functional Grouping +.Bl -tag -width indent +.It "Binary Object Handling" +.Bl -tag -compact -width indent +.It Fn elftc_bfd_find_target +Locate a binary object descriptor. +.It Fn elftc_bfd_target_class +Query the ELF class for a binary object descriptor. +.It Fn elftc_bfd_target_byteorder +Query the byte order for a binary object descriptor. +.It Fn elftc_bfd_target_flavor +Query the object format for a binary object descriptor. +.It Fn elftc_bfd_target_machine +Query the target machine for a binary object descriptor. +.It Fn elftc_bfd_target_osabi +Query the target osabi for a binary object descriptor. +.El +.It "C++ support" +.Bl -tag -compact -width indent +.It Fn elftc_demangle +Decodes a symbol name encoded according to the encoding rules for the +C++ language. +.El +.It "Programming conveniences" +.Bl -tag -compact -width indent +.It Fn elftc_copyfile +Copies the contents of a file to another. +.It Fn elftc_set_timestamp +Portably set the time stamps on a file. +.El +.It "Project Configuration" +.Bl -tag -compact -width indent +.It Fn elftc_version +Returns a project-wide identifier string that encodes the source +revision of the source tree. +.El +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr elf 3 diff --git a/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 b/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 new file mode 100644 index 0000000000..5d93f8e4a3 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 @@ -0,0 +1,208 @@ +.\" Copyright (c) 2010-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc_bfd_find_target.3 3960 2022-03-12 14:41:41Z jkoshy $ +.\" +.Dd August 21, 2020 +.Dt ELFTC_BFD_FIND_TARGET 3 +.Os +.Sh NAME +.Nm elftc_bfd_find_target , +.Nm elftc_bfd_target_byteorder , +.Nm elftc_bfd_target_class , +.Nm elftc_bfd_target_flavor , +.Nm elftc_bfd_target_machine , +.Nm elftc_bfd_target_osabi +.Nd binary object descriptor handling +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Vt struct Elftc_Bfd_Target; +.Ft "Elftc_Bfd_Target *" +.Fn elftc_bfd_find_target "const char *target_name" +.Ft "unsigned int" +.Fn elftc_bfd_target_class "Elftc_Bfd_Target *target" +.Ft "unsigned int" +.Fn elftc_bfd_target_byteorder "Elftc_Bfd_Target *target" +.Ft Elftc_Bfd_Target_Flavor +.Fn elftc_bfd_target_flavor "Elftc_Bfd_Target *target" +.Ft "unsigned int" +.Fn elftc_bfd_target_machine "Elftc_Bfd_Target *target" +.Ft "unsigned int" +.Fn elftc_bfd_target_osabi "Elftc_Bfd_Target *target" +.Sh DESCRIPTION +Function +.Fn elftc_bfd_find_target +locates a binary object descriptor corresponding to the descriptor +name in argument +.Fa "target_name" . +Binary object descriptors encapsulate properties of an object format +such as its file representation, ELF class, and byte endianness. +.Pp +Known descriptor names and their properties include: +.Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "Bit Width" +.It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "Bit Width" +.It Li binary Ta Binary Ta - Ta - +.It Li efi-app-ia32 Ta PE Ta LSB Ta 32 +.It Li efi-app-x86_64 Ta PE Ta LSB Ta 64 +.It Li elf32-avr Ta ELF Ta LSB Ta 32 +.It Li elf32-big Ta ELF Ta MSB Ta 32 +.It Li elf32-bigarm Ta ELF Ta MSB Ta 32 +.It Li elf32-bigmips Ta ELF Ta MSB Ta 32 +.It Li elf32-i386 Ta ELF Ta LSB Ta 32 +.It Li elf32-i386-freebsd Ta ELF Ta LSB Ta 32 +.It Li elf32-ia64-big Ta ELF Ta MSB Ta 32 +.It Li elf32-little Ta ELF Ta LSB Ta 32 +.It Li elf32-littlearm Ta ELF Ta LSB Ta 32 +.It Li elf32-littlemips Ta ELF Ta LSB Ta 32 +.It Li elf32-powerpc Ta ELF Ta MSB Ta 32 +.It Li elf32-powerpc-freebsd Ta ELF Ta MSB Ta 32 +.It Li elf32-powerpcle Ta ELF Ta LSB Ta 32 +.It Li elf32-riscv Ta ELF Ta LSB Ta 32 +.It Li elf64-riscv Ta ELF Ta LSB Ta 64 +.It Li elf64-riscv-freebsd Ta ELF Ta LSB Ta 64 +.It Li elf32-sh Ta ELF Ta MSB Ta 32 +.It Li elf32-shl Ta ELF Ta LSB Ta 32 +.It Li elf32-sh-nbsd Ta ELF Ta MSB Ta 32 +.It Li elf32-shl-nbsd Ta ELF Ta LSB Ta 32 +.It Li elf32-shbig-linux Ta ELF Ta MSB Ta 32 +.It Li elf32-shl-linux Ta ELF Ta LSB Ta 32 +.It Li elf32-sparc Ta ELF Ta MSB Ta 32 +.It Li elf32-tradbigmips Ta ELF Ta MSB Ta 32 +.It Li elf32-tradlittlemips Ta ELF Ta LSB Ta 32 +.It Li elf64-alpha Ta ELF Ta LSB Ta 64 +.It Li elf64-alpha-freebsd Ta ELF Ta LSB Ta 64 +.It Li elf64-big Ta ELF Ta MSB Ta 64 +.It Li elf64-bigmips Ta ELF Ta MSB Ta 64 +.It Li elf64-ia64-big Ta ELF Ta MSB Ta 64 +.It Li elf64-ia64-little Ta ELF Ta LSB Ta 64 +.It Li elf64-little Ta ELF Ta LSB Ta 64 +.It Li elf64-littleaarch64 Ta ELF Ta LSB Ta 64 +.It Li elf64-littlemips Ta ELF Ta LSB Ta 64 +.It Li elf64-powerpc Ta ELF Ta MSB Ta 64 +.It Li elf64-powerpc-freebsd Ta ELF Ta MSB Ta 64 +.It Li elf64-powerpcle Ta ELF Ta LSB Ta 64 +.It Li elf64-sh64 Ta ELF Ta MSB Ta 64 +.It Li elf64-sh64l Ta ELF Ta LSB Ta 64 +.It Li elf64-sh64-nbsd Ta ELF Ta MSB Ta 64 +.It Li elf64-sh64l-nbsd Ta ELF Ta LSB Ta 64 +.It Li elf64-sh64big-linux Ta ELF Ta MSB Ta 64 +.It Li elf64-sh64-linux Ta ELF Ta LSB Ta 64 +.It Li elf64-sparc Ta ELF Ta MSB Ta 64 +.It Li elf64-sparc-freebsd Ta ELF Ta MSB Ta 64 +.It Li elf64-tradbigmips Ta ELF Ta MSB Ta 64 +.It Li elf64-tradlittlemips Ta ELF Ta LSB Ta 64 +.It Li elf64-x86-64 Ta ELF Ta LSB Ta 64 +.It Li elf64-x86-64-freebsd Ta ELF Ta LSB Ta 64 +.It Li ihex Ta IHEX Ta - Ta - +.It Li pei-i386 Ta PE Ta LSB Ta 32 +.It Li pei-x86-64 Ta PE Ta LSB Ta 64 +.It Li srec Ta SREC Ta - Ta - +.It Li symbolsrec Ta SREC Ta - Ta - +.El +.Pp +Function +.Fn elftc_bfd_target_byteorder +returns the ELF byte order associated with target descriptor +.Fa target . +.Pp +Function +.Fn elftc_bfd_target_class +returns the ELF class associated with target descriptor +.Fa target . +.Pp +Function +.Fn elftc_bfd_target_flavor +returns the object format associated with target descriptor +.Fa target . +The known object formats are: +.Bl -tag -offset "XXXX" -width ".Dv ETF_BINARY" -compact +.It Dv ETF_ELF +An ELF object. +.It Dv ETF_BINARY +Raw binary. +.It Dv ETF_IHEX +An object encoded in +.Tn Intel +hex format. +.It Dv ETF_NONE +An unknown object format. +.It Dv ETF_SREC +An object encoded as S-records. +.El +.Sh RETURN VALUES +Function +.Fn elftc_bfd_find_target +returns a valid pointer to an opaque binary target descriptor if +successful, or +.Dv NULL +in case of an error. +.Pp +Function +.Fn elftc_bfd_target_byteorder +returns the ELF byte order associated with the target descriptor; one of +.Dv ELFDATA2MSB +or +.Dv ELFDATA2LSB . +.Pp +Function +.Fn elftc_bfd_target_class +returns the ELF class associated with the target descriptor; one of +.Dv ELFCLASS32 +or +.Dv ELFCLASS64 . +.Pp +Function +.Fn elftc_bfd_target_machine +returns the ELF architecture associated with the target descriptor. +.Pp +Function +.Fn elftc_bfd_target_flavor +returns one of +.Dv ETF_BINARY , +.Dv ETF_ELF , +.Dv ETF_IHEX +or +.Dv ETF_SREC +if successful or +.Dv ETF_NONE +in case of error. +.Sh EXAMPLES +To return descriptor information associated with target name +.Dq elf64-big +use: +.Bd -literal -offset indent +struct Elftc_Bfd_Target *t; + +if ((t = elftc_bfd_find_target("elf64-big")) == NULL) + errx(EXIT_FAILURE, "Cannot find target descriptor"); + +printf("Class: %s\\n", elftc_bfd_target_class(t) == ELFCLASS32 ? + "ELFCLASS32" : "ELFCLASS64"); +printf("Byteorder: %s\\n", + elftc_bfd_target_byteorder(t) == ELFDATA2LSB ? "LSB" : "MSB"); +printf("Flavor: %d\\n", elftc_bfd_target_flavor(t)); +.Ed +.Sh SEE ALSO +.Xr elf 3 diff --git a/contrib/elftoolchain/libelftc/elftc_bfdtarget.c b/contrib/elftoolchain/libelftc/elftc_bfdtarget.c new file mode 100644 index 0000000000..e2c126c648 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_bfdtarget.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2008,2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: elftc_bfdtarget.c 3871 2020-08-21 23:28:19Z emaste $"); + +Elftc_Bfd_Target * +elftc_bfd_find_target(const char *tgt_name) +{ + Elftc_Bfd_Target *tgt; + + for (tgt = _libelftc_targets; tgt->bt_name; tgt++) + if (!strcmp(tgt_name, tgt->bt_name)) + return (tgt); + + return (NULL); /* not found */ +} + +Elftc_Bfd_Target_Flavor +elftc_bfd_target_flavor(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_type); +} + +unsigned int +elftc_bfd_target_byteorder(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_byteorder); +} + +unsigned int +elftc_bfd_target_class(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_elfclass); +} + +unsigned int +elftc_bfd_target_machine(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_machine); +} + +unsigned int +elftc_bfd_target_osabi(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_osabi); +} diff --git a/contrib/elftoolchain/libelftc/elftc_copyfile.3 b/contrib/elftoolchain/libelftc/elftc_copyfile.3 new file mode 100644 index 0000000000..65c984a938 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_copyfile.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc_copyfile.3 3960 2022-03-12 14:41:41Z jkoshy $ +.\" +.Dd December 11, 2011 +.Dt ELFTC_COPYFILE 3 +.Os +.Sh NAME +.Nm elftc_copyfile +.Nd convenience function to copy data +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft in +.Fn elftc_copyfile "int ifd" "int ofd" +.Sh DESCRIPTION +The function +.Fn elftc_copyfile +copies the contents of the file referenced by argument +.Fa ifd +to the file referenced by argument +.Fa ofd . +.Pp +The argument +.Fa ifd +should contain a file descriptor opened for reading, with its file +offset at the beginning of the file. +.Pp +The argument +.Fa ofd +should contain a file descriptor opened for writing. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The function +.Fn elftc_copyfile +may fail with any of the errors returned by +.Xr fstat 2 , +.Xr mmap 2 , +.Xr munmap 2 , +.Xr read 2 , +.Xr write 2 , +or +.Xr malloc 3 . +.Sh SEE ALSO +.Xr fstat 2 , +.Xr mmap 2 , +.Xr munmap 2 , +.Xr read 2 , +.Xr write 2 , +.Xr malloc 3 diff --git a/contrib/elftoolchain/libelftc/elftc_copyfile.c b/contrib/elftoolchain/libelftc/elftc_copyfile.c new file mode 100644 index 0000000000..dac9c145be --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_copyfile.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2011, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include "libelftc.h" +#include "_libelftc.h" + +#if ELFTC_HAVE_MMAP +#include +#endif + +ELFTC_VCSID("$Id: elftc_copyfile.c 3297 2016-01-09 15:26:34Z jkoshy $"); + +/* + * Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on + * success and -1 on error. + */ + +int +elftc_copyfile(int ifd, int ofd) +{ + size_t file_size, n; + int buf_mmapped; + struct stat sb; + char *b, *buf; + ssize_t nr, nw; + + /* Determine the input file's size. */ + if (fstat(ifd, &sb) < 0) + return (-1); + + /* Skip files without content. */ + if (sb.st_size == 0) + return (0); + + buf = NULL; + buf_mmapped = 0; + file_size = (size_t) sb.st_size; + +#if ELFTC_HAVE_MMAP + /* + * Prefer mmap() if it is available. + */ + buf = mmap(NULL, file_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0); + if (buf != MAP_FAILED) + buf_mmapped = 1; + else + buf = NULL; +#endif + + /* + * If mmap() is not available, or if the mmap() operation + * failed, allocate a buffer, and read in input data. + */ + if (buf_mmapped == false) { + if ((buf = malloc(file_size)) == NULL) + return (-1); + b = buf; + for (n = file_size; n > 0; n -= (size_t) nr, b += nr) { + if ((nr = read(ifd, b, n)) < 0) { + free(buf); + return (-1); + } + } + } + + /* + * Write data to the output file descriptor. + */ + for (n = file_size, b = buf; n > 0; n -= (size_t) nw, b += nw) + if ((nw = write(ofd, b, n)) <= 0) + break; + + /* Release the input buffer. */ +#if ELFTC_HAVE_MMAP + if (buf_mmapped && munmap(buf, file_size) < 0) + return (-1); +#endif + + if (!buf_mmapped) + free(buf); + + return (n > 0 ? -1 : 0); +} + diff --git a/contrib/elftoolchain/libelftc/elftc_demangle.3 b/contrib/elftoolchain/libelftc/elftc_demangle.3 new file mode 100644 index 0000000000..bb02b60ecc --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_demangle.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2009,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc_demangle.3 3960 2022-03-12 14:41:41Z jkoshy $ +.\" +.Dd August 24, 2011 +.Dt ELFTC_DEMANGLE 3 +.Os +.Sh NAME +.Nm elftc_demangle +.Nd demangle a C++ name +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft int +.Fo elftc_demangle +.Fa "const char *encodedname" +.Fa "char *buffer" +.Fa "size_t bufsize" +.Fa "unsigned int flags" +.Fc +.Sh DESCRIPTION +Function +.Fn elftc_demangle +decodes a symbol name encoded according to the type encoding rules +for the C++ language and returns a string denoting an equivalent +C++ prototype. +.Pp +Argument +.Fa encodedname +specifies the encoded symbol name. +Argument +.Fa buffer +denotes a programmer-specified area to place the prototype string in. +Argument +.Fa bufsize +specifies the size of the programmer-specified area. +Argument +.Fa flags +specifies the encoding style in use for argument +.Fa encodedname . +Supported encoding styles are: +.Bl -tag -width ".Dv ELFTC_DEM_GNU3" +.It Dv ELFTC_DEM_ARM +The encoding style used by compilers adhering to the conventions of the +C++ Annotated Reference Manual. +.It Dv ELFTC_DEM_GNU2 +The encoding style by GNU C++ version 2. +.It Dv ELFTC_DEM_GNU3 +The encoding style by GNU C++ version 3 and later. +.El +.Pp +Argument +.Fa flags +may be zero, in which case the function will attempt to guess the +encoding scheme from the contents of +.Fa encodedname . +.Sh RETURN VALUES +Function +.Fn elftc_demangle +returns 0 on success. +In case of an error it returns -1 and sets the +.Va errno +variable. +.Sh EXAMPLES +To decode a name that uses an unknown encoding style use: +.Bd -literal -offset indent +char buffer[1024]; +const char *funcname; + +funcname = ...; /* points to string to be demangled */ +if (elftc_demangle(funcname, buffer, sizeof(buffer), 0) == 0) + printf("Demangled name: %\\n", buffer); +else + perror("Cannot demangle %s", funcname); +.Ed +.Sh ERRORS +Function +.Fn elftc_demangle +may fail with the following errors: +.Bl -tag -width ".Bq Er ENAMETOOLONG" +.It Bq Er EINVAL +Argument +.Fa encodedname +was not a valid encoded name. +.It Bq Er ENAMETOOLONG +The output buffer specified by arguments +.Fa buffer +and +.Fa bufsize +was too small to hold the decoded function prototype. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_strptr 3 diff --git a/contrib/elftoolchain/libelftc/elftc_demangle.c b/contrib/elftoolchain/libelftc/elftc_demangle.c new file mode 100644 index 0000000000..945f777791 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_demangle.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: elftc_demangle.c 3296 2016-01-09 14:17:28Z jkoshy $"); + +static unsigned int +is_mangled(const char *s, unsigned int style) +{ + + switch (style) { + case ELFTC_DEM_ARM: return (is_cpp_mangled_ARM(s) ? style : 0); + case ELFTC_DEM_GNU2: return (is_cpp_mangled_gnu2(s) ? style : 0); + case ELFTC_DEM_GNU3: return (is_cpp_mangled_gnu3(s) ? style : 0); + } + + /* No style or invalid style spcified, try to guess. */ + if (is_cpp_mangled_gnu3(s)) + return (ELFTC_DEM_GNU3); + if (is_cpp_mangled_gnu2(s)) + return (ELFTC_DEM_GNU2); + if (is_cpp_mangled_ARM(s)) + return (ELFTC_DEM_ARM); + + /* Cannot be demangled. */ + return (0); +} + +static char * +demangle(const char *s, unsigned int style, unsigned int rc) +{ + + (void) rc; /* XXX */ + switch (style) { + case ELFTC_DEM_ARM: return (cpp_demangle_ARM(s)); + case ELFTC_DEM_GNU2: return (cpp_demangle_gnu2(s)); + case ELFTC_DEM_GNU3: return (cpp_demangle_gnu3(s)); + default: + assert(0); + return (NULL); + } +} + +int +elftc_demangle(const char *mangledname, char *buffer, size_t bufsize, + unsigned int flags) +{ + unsigned int style, rc; + char *rlt; + + style = flags & 0xFFFF; + rc = flags >> 16; + + if (mangledname == NULL || + ((style = is_mangled(mangledname, style)) == 0)) { + errno = EINVAL; + return (-1); + } + + if ((rlt = demangle(mangledname, style, rc)) == NULL) { + errno = EINVAL; + return (-1); + } + + if (buffer == NULL || bufsize < strlen(rlt) + 1) { + free(rlt); + errno = ENAMETOOLONG; + return (-1); + } + + strncpy(buffer, rlt, bufsize); + buffer[bufsize - 1] = '\0'; + free(rlt); + + return (0); +} diff --git a/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 b/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 new file mode 100644 index 0000000000..a632ad6218 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 @@ -0,0 +1,72 @@ +.\" Copyright (c) 2016 The FreeBSD Foundation. All rights reserved. +.\" +.\" This documentation was written by Ed Maste under sponsorship of +.\" the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by the author and contributors ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. In no event shall the author or contributors be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd March 12, 2022 +.Dt ELFTC_RELOC_TYPE_STR 3 +.Os +.Sh NAME +.Nm elftc_reloc_type_str +.Nd return the type name for an ELF relocation +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft const char * +.Fo elftc_reloc_type_str +.Fa "unsigned int mach" +.Fa "unsigned int type" +.Fc +.Sh DESCRIPTION +Function +.Fn elftc_reloc_type_str +returns the name for specified relocation type. +.Pp +Argument +.Fa mach +specifies the machine (architecture) type. +Argument +.Fa type +specifies the relocation value. +.Sh RETURN VALUES +Function +.Fn elftc_reloc_type_str +returns a pointer to a string constant, or to an internal character buffer +if the relocation type is unknown. +.Sh EXAMPLES +To print ARM relocation type 7, use: +.Bd -literal -offset indent +#include +#include +#include + +(void) printf("%s\en", elftc_reloc_type_str(EM_ARM, 7)); +.Ed +.Sh ERRORS +Function +.Fn elftc_reloc_type_str +always succeeds. diff --git a/contrib/elftoolchain/libelftc/elftc_reloc_type_str.c b/contrib/elftoolchain/libelftc/elftc_reloc_type_str.c new file mode 100644 index 0000000000..c8486c802c --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_reloc_type_str.c @@ -0,0 +1,844 @@ +/*- + * Copyright (c) 2009-2015 Kai Wang + * Copyright (c) 2016 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Ed Maste under sponsorship + * of the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +const char * +elftc_reloc_type_str(unsigned int mach, unsigned int type) +{ + static char s_type[32]; + + switch(mach) { + case EM_386: + case EM_IAMCU: + switch(type) { + case 0: return "R_386_NONE"; + case 1: return "R_386_32"; + case 2: return "R_386_PC32"; + case 3: return "R_386_GOT32"; + case 4: return "R_386_PLT32"; + case 5: return "R_386_COPY"; + case 6: return "R_386_GLOB_DAT"; + case 7: return "R_386_JUMP_SLOT"; + case 8: return "R_386_RELATIVE"; + case 9: return "R_386_GOTOFF"; + case 10: return "R_386_GOTPC"; + case 11: return "R_386_32PLT"; /* Not in psabi */ + case 14: return "R_386_TLS_TPOFF"; + case 15: return "R_386_TLS_IE"; + case 16: return "R_386_TLS_GOTIE"; + case 17: return "R_386_TLS_LE"; + case 18: return "R_386_TLS_GD"; + case 19: return "R_386_TLS_LDM"; + case 20: return "R_386_16"; + case 21: return "R_386_PC16"; + case 22: return "R_386_8"; + case 23: return "R_386_PC8"; + case 24: return "R_386_TLS_GD_32"; + case 25: return "R_386_TLS_GD_PUSH"; + case 26: return "R_386_TLS_GD_CALL"; + case 27: return "R_386_TLS_GD_POP"; + case 28: return "R_386_TLS_LDM_32"; + case 29: return "R_386_TLS_LDM_PUSH"; + case 30: return "R_386_TLS_LDM_CALL"; + case 31: return "R_386_TLS_LDM_POP"; + case 32: return "R_386_TLS_LDO_32"; + case 33: return "R_386_TLS_IE_32"; + case 34: return "R_386_TLS_LE_32"; + case 35: return "R_386_TLS_DTPMOD32"; + case 36: return "R_386_TLS_DTPOFF32"; + case 37: return "R_386_TLS_TPOFF32"; + case 38: return "R_386_SIZE32"; + case 39: return "R_386_TLS_GOTDESC"; + case 40: return "R_386_TLS_DESC_CALL"; + case 41: return "R_386_TLS_DESC"; + case 42: return "R_386_IRELATIVE"; + case 43: return "R_386_GOT32X"; + } + break; + case EM_AARCH64: + switch(type) { + case 0: return "R_AARCH64_NONE"; + case 257: return "R_AARCH64_ABS64"; + case 258: return "R_AARCH64_ABS32"; + case 259: return "R_AARCH64_ABS16"; + case 260: return "R_AARCH64_PREL64"; + case 261: return "R_AARCH64_PREL32"; + case 262: return "R_AARCH64_PREL16"; + case 263: return "R_AARCH64_MOVW_UABS_G0"; + case 264: return "R_AARCH64_MOVW_UABS_G0_NC"; + case 265: return "R_AARCH64_MOVW_UABS_G1"; + case 266: return "R_AARCH64_MOVW_UABS_G1_NC"; + case 267: return "R_AARCH64_MOVW_UABS_G2"; + case 268: return "R_AARCH64_MOVW_UABS_G2_NC"; + case 269: return "R_AARCH64_MOVW_UABS_G3"; + case 270: return "R_AARCH64_MOVW_SABS_G0"; + case 271: return "R_AARCH64_MOVW_SABS_G1"; + case 272: return "R_AARCH64_MOVW_SABS_G2"; + case 273: return "R_AARCH64_LD_PREL_LO19"; + case 274: return "R_AARCH64_ADR_PREL_LO21"; + case 275: return "R_AARCH64_ADR_PREL_PG_HI21"; + case 276: return "R_AARCH64_ADR_PREL_PG_HI21_NC"; + case 277: return "R_AARCH64_ADD_ABS_LO12_NC"; + case 278: return "R_AARCH64_LDST8_ABS_LO12_NC"; + case 279: return "R_AARCH64_TSTBR14"; + case 280: return "R_AARCH64_CONDBR19"; + case 282: return "R_AARCH64_JUMP26"; + case 283: return "R_AARCH64_CALL26"; + case 284: return "R_AARCH64_LDST16_ABS_LO12_NC"; + case 285: return "R_AARCH64_LDST32_ABS_LO12_NC"; + case 286: return "R_AARCH64_LDST64_ABS_LO12_NC"; + case 287: return "R_AARCH64_MOVW_PREL_G0"; + case 288: return "R_AARCH64_MOVW_PREL_G0_NC"; + case 289: return "R_AARCH64_MOVW_PREL_G1"; + case 290: return "R_AARCH64_MOVW_PREL_G1_NC"; + case 291: return "R_AARCH64_MOVW_PREL_G2"; + case 292: return "R_AARCH64_MOVW_PREL_G2_NC"; + case 293: return "R_AARCH64_MOVW_PREL_G3"; + case 299: return "R_AARCH64_LDST128_ABS_LO12_NC"; + case 300: return "R_AARCH64_MOVW_GOTOFF_G0"; + case 301: return "R_AARCH64_MOVW_GOTOFF_G0_NC"; + case 302: return "R_AARCH64_MOVW_GOTOFF_G1"; + case 303: return "R_AARCH64_MOVW_GOTOFF_G1_NC"; + case 304: return "R_AARCH64_MOVW_GOTOFF_G2"; + case 305: return "R_AARCH64_MOVW_GOTOFF_G2_NC"; + case 306: return "R_AARCH64_MOVW_GOTOFF_G3"; + case 307: return "R_AARCH64_GOTREL64"; + case 308: return "R_AARCH64_GOTREL32"; + case 309: return "R_AARCH64_GOT_LD_PREL19"; + case 310: return "R_AARCH64_LD64_GOTOFF_LO15"; + case 311: return "R_AARCH64_ADR_GOT_PAGE"; + case 312: return "R_AARCH64_LD64_GOT_LO12_NC"; + case 313: return "R_AARCH64_LD64_GOTPAGE_LO15"; + case 560: return "R_AARCH64_TLSDESC_LD_PREL19"; + case 561: return "R_AARCH64_TLSDESC_ADR_PREL21"; + case 562: return "R_AARCH64_TLSDESC_ADR_PAGE21"; + case 563: return "R_AARCH64_TLSDESC_LD64_LO12"; + case 564: return "R_AARCH64_TLSDESC_ADD_LO12"; + case 565: return "R_AARCH64_TLSDESC_OFF_G1"; + case 566: return "R_AARCH64_TLSDESC_OFF_G0_NC"; + case 567: return "R_AARCH64_TLSDESC_LDR"; + case 568: return "R_AARCH64_TLSDESC_ADD"; + case 569: return "R_AARCH64_TLSDESC_CALL"; + case 1024: return "R_AARCH64_COPY"; + case 1025: return "R_AARCH64_GLOB_DAT"; + case 1026: return "R_AARCH64_JUMP_SLOT"; + case 1027: return "R_AARCH64_RELATIVE"; + case 1028: return "R_AARCH64_TLS_DTPREL64"; + case 1029: return "R_AARCH64_TLS_DTPMOD64"; + case 1030: return "R_AARCH64_TLS_TPREL64"; + case 1031: return "R_AARCH64_TLSDESC"; + case 1032: return "R_AARCH64_IRELATIVE"; + } + break; + case EM_ARM: + switch(type) { + case 0: return "R_ARM_NONE"; + case 1: return "R_ARM_PC24"; /* Deprecated */ + case 2: return "R_ARM_ABS32"; + case 3: return "R_ARM_REL32"; + case 4: return "R_ARM_LDR_PC_G0"; /* Also R_ARM_PC13 */ + case 5: return "R_ARM_ABS16"; + case 6: return "R_ARM_ABS12"; + case 7: return "R_ARM_THM_ABS5"; + case 8: return "R_ARM_ABS8"; + case 9: return "R_ARM_SBREL32"; + case 10: return "R_ARM_THM_CALL"; /* Also R_ARM_THM_PC22 */ + case 11: return "R_ARM_THM_PC8"; + case 12: return "R_ARM_BREL_ADJ"; /* Also R_ARM_AMP_VCALL9 */ + case 13: return "R_ARM_TLS_DESC"; /* Also R_ARM_SWI24 */ + case 14: return "R_ARM_THM_SWI8"; /* Obsolete */ + case 15: return "R_ARM_XPC25"; /* Obsolete */ + case 16: return "R_ARM_THM_XPC22"; /* Obsolete */ + case 17: return "R_ARM_TLS_DTPMOD32"; + case 18: return "R_ARM_TLS_DTPOFF32"; + case 19: return "R_ARM_TLS_TPOFF32"; + case 20: return "R_ARM_COPY"; + case 21: return "R_ARM_GLOB_DAT"; + case 22: return "R_ARM_JUMP_SLOT"; + case 23: return "R_ARM_RELATIVE"; + case 24: return "R_ARM_GOTOFF32"; /* Also R_ARM_GOTOFF */ + case 25: return "R_ARM_BASE_PREL"; /* GNU R_ARM_GOTPC */ + case 26: return "R_ARM_GOT_BREL"; /* GNU R_ARM_GOT32 */ + case 27: return "R_ARM_PLT32"; /* Deprecated */ + case 28: return "R_ARM_CALL"; + case 29: return "R_ARM_JUMP24"; + case 30: return "R_ARM_THM_JUMP24"; + case 31: return "R_ARM_BASE_ABS"; + case 32: return "R_ARM_ALU_PCREL_7_0"; /* Obsolete */ + case 33: return "R_ARM_ALU_PCREL_15_8"; /* Obsolete */ + case 34: return "R_ARM_ALU_PCREL_23_15"; /* Obsolete */ + case 35: return "R_ARM_LDR_SBREL_11_0_NC"; /* Deprecated */ + case 36: return "R_ARM_ALU_SBREL_19_12_NC"; /* Deprecated */ + case 37: return "R_ARM_ALU_SBREL_27_20_CK"; /* Deprecated */ + case 38: return "R_ARM_TARGET1"; + case 39: return "R_ARM_SBREL31"; /* Deprecated. */ + case 40: return "R_ARM_V4BX"; + case 41: return "R_ARM_TARGET2"; + case 42: return "R_ARM_PREL31"; + case 43: return "R_ARM_MOVW_ABS_NC"; + case 44: return "R_ARM_MOVT_ABS"; + case 45: return "R_ARM_MOVW_PREL_NC"; + case 46: return "R_ARM_MOVT_PREL"; + case 47: return "R_ARM_THM_MOVW_ABS_NC"; + case 48: return "R_ARM_THM_MOVT_ABS"; + case 49: return "R_ARM_THM_MOVW_PREL_NC"; + case 50: return "R_ARM_THM_MOVT_PREL"; + case 51: return "R_ARM_THM_JUMP19"; + case 52: return "R_ARM_THM_JUMP6"; + case 53: return "R_ARM_THM_ALU_PREL_11_0"; + case 54: return "R_ARM_THM_PC12"; + case 55: return "R_ARM_ABS32_NOI"; + case 56: return "R_ARM_REL32_NOI"; + case 57: return "R_ARM_ALU_PC_G0_NC"; + case 58: return "R_ARM_ALU_PC_G0"; + case 59: return "R_ARM_ALU_PC_G1_NC"; + case 60: return "R_ARM_ALU_PC_G1"; + case 61: return "R_ARM_ALU_PC_G2"; + case 62: return "R_ARM_LDR_PC_G1"; + case 63: return "R_ARM_LDR_PC_G2"; + case 64: return "R_ARM_LDRS_PC_G0"; + case 65: return "R_ARM_LDRS_PC_G1"; + case 66: return "R_ARM_LDRS_PC_G2"; + case 67: return "R_ARM_LDC_PC_G0"; + case 68: return "R_ARM_LDC_PC_G1"; + case 69: return "R_ARM_LDC_PC_G2"; + case 70: return "R_ARM_ALU_SB_G0_NC"; + case 71: return "R_ARM_ALU_SB_G0"; + case 72: return "R_ARM_ALU_SB_G1_NC"; + case 73: return "R_ARM_ALU_SB_G1"; + case 74: return "R_ARM_ALU_SB_G2"; + case 75: return "R_ARM_LDR_SB_G0"; + case 76: return "R_ARM_LDR_SB_G1"; + case 77: return "R_ARM_LDR_SB_G2"; + case 78: return "R_ARM_LDRS_SB_G0"; + case 79: return "R_ARM_LDRS_SB_G1"; + case 80: return "R_ARM_LDRS_SB_G2"; + case 81: return "R_ARM_LDC_SB_G0"; + case 82: return "R_ARM_LDC_SB_G1"; + case 83: return "R_ARM_LDC_SB_G2"; + case 84: return "R_ARM_MOVW_BREL_NC"; + case 85: return "R_ARM_MOVT_BREL"; + case 86: return "R_ARM_MOVW_BREL"; + case 87: return "R_ARM_THM_MOVW_BREL_NC"; + case 88: return "R_ARM_THM_MOVT_BREL"; + case 89: return "R_ARM_THM_MOVW_BREL"; + case 90: return "R_ARM_TLS_GOTDESC"; + case 91: return "R_ARM_TLS_CALL"; + case 92: return "R_ARM_TLS_DESCSEQ"; + case 93: return "R_ARM_THM_TLS_CALL"; + case 94: return "R_ARM_PLT32_ABS"; + case 95: return "R_ARM_GOT_ABS"; + case 96: return "R_ARM_GOT_PREL"; + case 97: return "R_ARM_GOT_BREL12"; + case 98: return "R_ARM_GOTOFF12"; + case 99: return "R_ARM_GOTRELAX"; + case 100: return "R_ARM_GNU_VTENTRY"; + case 101: return "R_ARM_GNU_VTINHERIT"; + case 102: return "R_ARM_THM_JUMP11"; /* Also R_ARM_THM_PC11 */ + case 103: return "R_ARM_THM_JUMP8"; /* Also R_ARM_THM_PC9 */ + case 104: return "R_ARM_TLS_GD32"; + case 105: return "R_ARM_TLS_LDM32"; + case 106: return "R_ARM_TLS_LDO32"; + case 107: return "R_ARM_TLS_IE32"; + case 108: return "R_ARM_TLS_LE32"; + case 109: return "R_ARM_TLS_LDO12"; + case 110: return "R_ARM_TLS_LE12"; + case 111: return "R_ARM_TLS_IE12GP"; + /* 112-127 R_ARM_PRIVATE_ */ + case 128: return "R_ARM_ME_TOO"; /* Obsolete */ + case 129: return "R_ARM_THM_TLS_DESCSEQ16"; + case 130: return "R_ARM_THM_TLS_DESCSEQ32"; + case 131: return "R_ARM_THM_GOT_BREL12"; + case 132: return "R_ARM_THM_ALU_ABS_G0_NC"; + case 133: return "R_ARM_THM_ALU_ABS_G1_NC"; + case 134: return "R_ARM_THM_ALU_ABS_G2_NC"; + case 135: return "R_ARM_THM_ALU_ABS_G3"; + /* 136-159 Reserved for future allocation. */ + case 160: return "R_ARM_IRELATIVE"; + /* 161-255 Reserved for future allocation. */ + case 249: return "R_ARM_RXPC25"; + case 250: return "R_ARM_RSBREL32"; + case 251: return "R_ARM_THM_RPC22"; + case 252: return "R_ARM_RREL32"; + case 253: return "R_ARM_RABS32"; + case 254: return "R_ARM_RPC24"; + case 255: return "R_ARM_RBASE"; + } + break; + case EM_IA_64: + switch(type) { + case 0: return "R_IA_64_NONE"; + case 33: return "R_IA_64_IMM14"; + case 34: return "R_IA_64_IMM22"; + case 35: return "R_IA_64_IMM64"; + case 36: return "R_IA_64_DIR32MSB"; + case 37: return "R_IA_64_DIR32LSB"; + case 38: return "R_IA_64_DIR64MSB"; + case 39: return "R_IA_64_DIR64LSB"; + case 42: return "R_IA_64_GPREL22"; + case 43: return "R_IA_64_GPREL64I"; + case 44: return "R_IA_64_GPREL32MSB"; + case 45: return "R_IA_64_GPREL32LSB"; + case 46: return "R_IA_64_GPREL64MSB"; + case 47: return "R_IA_64_GPREL64LSB"; + case 50: return "R_IA_64_LTOFF22"; + case 51: return "R_IA_64_LTOFF64I"; + case 58: return "R_IA_64_PLTOFF22"; + case 59: return "R_IA_64_PLTOFF64I"; + case 62: return "R_IA_64_PLTOFF64MSB"; + case 63: return "R_IA_64_PLTOFF64LSB"; + case 67: return "R_IA_64_FPTR64I"; + case 68: return "R_IA_64_FPTR32MSB"; + case 69: return "R_IA_64_FPTR32LSB"; + case 70: return "R_IA_64_FPTR64MSB"; + case 71: return "R_IA_64_FPTR64LSB"; + case 72: return "R_IA_64_PCREL60B"; + case 73: return "R_IA_64_PCREL21B"; + case 74: return "R_IA_64_PCREL21M"; + case 75: return "R_IA_64_PCREL21F"; + case 76: return "R_IA_64_PCREL32MSB"; + case 77: return "R_IA_64_PCREL32LSB"; + case 78: return "R_IA_64_PCREL64MSB"; + case 79: return "R_IA_64_PCREL64LSB"; + case 82: return "R_IA_64_LTOFF_FPTR22"; + case 83: return "R_IA_64_LTOFF_FPTR64I"; + case 84: return "R_IA_64_LTOFF_FPTR32MSB"; + case 85: return "R_IA_64_LTOFF_FPTR32LSB"; + case 86: return "R_IA_64_LTOFF_FPTR64MSB"; + case 87: return "R_IA_64_LTOFF_FPTR64LSB"; + case 92: return "R_IA_64_SEGREL32MSB"; + case 93: return "R_IA_64_SEGREL32LSB"; + case 94: return "R_IA_64_SEGREL64MSB"; + case 95: return "R_IA_64_SEGREL64LSB"; + case 100: return "R_IA_64_SECREL32MSB"; + case 101: return "R_IA_64_SECREL32LSB"; + case 102: return "R_IA_64_SECREL64MSB"; + case 103: return "R_IA_64_SECREL64LSB"; + case 108: return "R_IA_64_REL32MSB"; + case 109: return "R_IA_64_REL32LSB"; + case 110: return "R_IA_64_REL64MSB"; + case 111: return "R_IA_64_REL64LSB"; + case 116: return "R_IA_64_LTV32MSB"; + case 117: return "R_IA_64_LTV32LSB"; + case 118: return "R_IA_64_LTV64MSB"; + case 119: return "R_IA_64_LTV64LSB"; + case 121: return "R_IA_64_PCREL21BI"; + case 122: return "R_IA_64_PCREL22"; + case 123: return "R_IA_64_PCREL64I"; + case 128: return "R_IA_64_IPLTMSB"; + case 129: return "R_IA_64_IPLTLSB"; + case 133: return "R_IA_64_SUB"; + case 134: return "R_IA_64_LTOFF22X"; + case 135: return "R_IA_64_LDXMOV"; + case 145: return "R_IA_64_TPREL14"; + case 146: return "R_IA_64_TPREL22"; + case 147: return "R_IA_64_TPREL64I"; + case 150: return "R_IA_64_TPREL64MSB"; + case 151: return "R_IA_64_TPREL64LSB"; + case 154: return "R_IA_64_LTOFF_TPREL22"; + case 166: return "R_IA_64_DTPMOD64MSB"; + case 167: return "R_IA_64_DTPMOD64LSB"; + case 170: return "R_IA_64_LTOFF_DTPMOD22"; + case 177: return "R_IA_64_DTPREL14"; + case 178: return "R_IA_64_DTPREL22"; + case 179: return "R_IA_64_DTPREL64I"; + case 180: return "R_IA_64_DTPREL32MSB"; + case 181: return "R_IA_64_DTPREL32LSB"; + case 182: return "R_IA_64_DTPREL64MSB"; + case 183: return "R_IA_64_DTPREL64LSB"; + case 186: return "R_IA_64_LTOFF_DTPREL22"; + } + break; + case EM_MIPS: + switch(type) { + case 0: return "R_MIPS_NONE"; + case 1: return "R_MIPS_16"; + case 2: return "R_MIPS_32"; + case 3: return "R_MIPS_REL32"; + case 4: return "R_MIPS_26"; + case 5: return "R_MIPS_HI16"; + case 6: return "R_MIPS_LO16"; + case 7: return "R_MIPS_GPREL16"; + case 8: return "R_MIPS_LITERAL"; + case 9: return "R_MIPS_GOT16"; + case 10: return "R_MIPS_PC16"; + case 11: return "R_MIPS_CALL16"; + case 12: return "R_MIPS_GPREL32"; + case 16: return "R_MIPS_SHIFT5"; + case 17: return "R_MIPS_SHIFT6"; + case 18: return "R_MIPS_64"; + case 19: return "R_MIPS_GOT_DISP"; + case 20: return "R_MIPS_GOT_PAGE"; + case 21: return "R_MIPS_GOT_OFST"; + case 22: return "R_MIPS_GOT_HI16"; + case 23: return "R_MIPS_GOT_LO16"; + case 24: return "R_MIPS_SUB"; + case 28: return "R_MIPS_HIGHER"; + case 29: return "R_MIPS_HIGHEST"; + case 30: return "R_MIPS_CALLHI16"; + case 31: return "R_MIPS_CALLLO16"; + case 37: return "R_MIPS_JALR"; + case 38: return "R_MIPS_TLS_DTPMOD32"; + case 39: return "R_MIPS_TLS_DTPREL32"; + case 40: return "R_MIPS_TLS_DTPMOD64"; + case 41: return "R_MIPS_TLS_DTPREL64"; + case 42: return "R_MIPS_TLS_GD"; + case 43: return "R_MIPS_TLS_LDM"; + case 44: return "R_MIPS_TLS_DTPREL_HI16"; + case 45: return "R_MIPS_TLS_DTPREL_LO16"; + case 46: return "R_MIPS_TLS_GOTTPREL"; + case 47: return "R_MIPS_TLS_TPREL32"; + case 48: return "R_MIPS_TLS_TPREL64"; + case 49: return "R_MIPS_TLS_TPREL_HI16"; + case 50: return "R_MIPS_TLS_TPREL_LO16"; + } + break; + case EM_PPC: + switch(type) { + case 0: return "R_PPC_NONE"; + case 1: return "R_PPC_ADDR32"; + case 2: return "R_PPC_ADDR24"; + case 3: return "R_PPC_ADDR16"; + case 4: return "R_PPC_ADDR16_LO"; + case 5: return "R_PPC_ADDR16_HI"; + case 6: return "R_PPC_ADDR16_HA"; + case 7: return "R_PPC_ADDR14"; + case 8: return "R_PPC_ADDR14_BRTAKEN"; + case 9: return "R_PPC_ADDR14_BRNTAKEN"; + case 10: return "R_PPC_REL24"; + case 11: return "R_PPC_REL14"; + case 12: return "R_PPC_REL14_BRTAKEN"; + case 13: return "R_PPC_REL14_BRNTAKEN"; + case 14: return "R_PPC_GOT16"; + case 15: return "R_PPC_GOT16_LO"; + case 16: return "R_PPC_GOT16_HI"; + case 17: return "R_PPC_GOT16_HA"; + case 18: return "R_PPC_PLTREL24"; + case 19: return "R_PPC_COPY"; + case 20: return "R_PPC_GLOB_DAT"; + case 21: return "R_PPC_JMP_SLOT"; + case 22: return "R_PPC_RELATIVE"; + case 23: return "R_PPC_LOCAL24PC"; + case 24: return "R_PPC_UADDR32"; + case 25: return "R_PPC_UADDR16"; + case 26: return "R_PPC_REL32"; + case 27: return "R_PPC_PLT32"; + case 28: return "R_PPC_PLTREL32"; + case 29: return "R_PPC_PLT16_LO"; + case 30: return "R_PPC_PLT16_HI"; + case 31: return "R_PPC_PLT16_HA"; + case 32: return "R_PPC_SDAREL16"; + case 33: return "R_PPC_SECTOFF"; + case 34: return "R_PPC_SECTOFF_LO"; + case 35: return "R_PPC_SECTOFF_HI"; + case 36: return "R_PPC_SECTOFF_HA"; + case 67: return "R_PPC_TLS"; + case 68: return "R_PPC_DTPMOD32"; + case 69: return "R_PPC_TPREL16"; + case 70: return "R_PPC_TPREL16_LO"; + case 71: return "R_PPC_TPREL16_HI"; + case 72: return "R_PPC_TPREL16_HA"; + case 73: return "R_PPC_TPREL32"; + case 74: return "R_PPC_DTPREL16"; + case 75: return "R_PPC_DTPREL16_LO"; + case 76: return "R_PPC_DTPREL16_HI"; + case 77: return "R_PPC_DTPREL16_HA"; + case 78: return "R_PPC_DTPREL32"; + case 79: return "R_PPC_GOT_TLSGD16"; + case 80: return "R_PPC_GOT_TLSGD16_LO"; + case 81: return "R_PPC_GOT_TLSGD16_HI"; + case 82: return "R_PPC_GOT_TLSGD16_HA"; + case 83: return "R_PPC_GOT_TLSLD16"; + case 84: return "R_PPC_GOT_TLSLD16_LO"; + case 85: return "R_PPC_GOT_TLSLD16_HI"; + case 86: return "R_PPC_GOT_TLSLD16_HA"; + case 87: return "R_PPC_GOT_TPREL16"; + case 88: return "R_PPC_GOT_TPREL16_LO"; + case 89: return "R_PPC_GOT_TPREL16_HI"; + case 90: return "R_PPC_GOT_TPREL16_HA"; + case 101: return "R_PPC_EMB_NADDR32"; + case 102: return "R_PPC_EMB_NADDR16"; + case 103: return "R_PPC_EMB_NADDR16_LO"; + case 104: return "R_PPC_EMB_NADDR16_HI"; + case 105: return "R_PPC_EMB_NADDR16_HA"; + case 106: return "R_PPC_EMB_SDAI16"; + case 107: return "R_PPC_EMB_SDA2I16"; + case 108: return "R_PPC_EMB_SDA2REL"; + case 109: return "R_PPC_EMB_SDA21"; + case 110: return "R_PPC_EMB_MRKREF"; + case 111: return "R_PPC_EMB_RELSEC16"; + case 112: return "R_PPC_EMB_RELST_LO"; + case 113: return "R_PPC_EMB_RELST_HI"; + case 114: return "R_PPC_EMB_RELST_HA"; + case 115: return "R_PPC_EMB_BIT_FLD"; + case 116: return "R_PPC_EMB_RELSDA"; + } + break; + case EM_PPC64: + switch(type) { + case 0: return "R_PPC64_NONE"; + case 1: return "R_PPC64_ADDR32"; + case 2: return "R_PPC64_ADDR24"; + case 3: return "R_PPC64_ADDR16"; + case 4: return "R_PPC64_ADDR16_LO"; + case 5: return "R_PPC64_ADDR16_HI"; + case 6: return "R_PPC64_ADDR16_HA"; + case 7: return "R_PPC64_ADDR14"; + case 8: return "R_PPC64_ADDR14_BRTAKEN"; + case 9: return "R_PPC64_ADDR14_BRNTAKEN"; + case 10: return "R_PPC64_REL24"; + case 11: return "R_PPC64_REL14"; + case 12: return "R_PPC64_REL14_BRTAKEN"; + case 13: return "R_PPC64_REL14_BRNTAKEN"; + case 14: return "R_PPC64_GOT16"; + case 15: return "R_PPC64_GOT16_LO"; + case 16: return "R_PPC64_GOT16_HI"; + case 17: return "R_PPC64_GOT16_HA"; + case 19: return "R_PPC64_COPY"; + case 20: return "R_PPC64_GLOB_DAT"; + case 21: return "R_PPC64_JMP_SLOT"; + case 22: return "R_PPC64_RELATIVE"; + case 24: return "R_PPC64_UADDR32"; + case 25: return "R_PPC64_UADDR16"; + case 26: return "R_PPC64_REL32"; + case 27: return "R_PPC64_PLT32"; + case 28: return "R_PPC64_PLTREL32"; + case 29: return "R_PPC64_PLT16_LO"; + case 30: return "R_PPC64_PLT16_HI"; + case 31: return "R_PPC64_PLT16_HA"; + case 33: return "R_PPC64_SECTOFF"; + case 34: return "R_PPC64_SECTOFF_LO"; + case 35: return "R_PPC64_SECTOFF_HI"; + case 36: return "R_PPC64_SECTOFF_HA"; + case 37: return "R_PPC64_ADDR30"; + case 38: return "R_PPC64_ADDR64"; + case 39: return "R_PPC64_ADDR16_HIGHER"; + case 40: return "R_PPC64_ADDR16_HIGHERA"; + case 41: return "R_PPC64_ADDR16_HIGHEST"; + case 42: return "R_PPC64_ADDR16_HIGHESTA"; + case 43: return "R_PPC64_UADDR64"; + case 44: return "R_PPC64_REL64"; + case 45: return "R_PPC64_PLT64"; + case 46: return "R_PPC64_PLTREL64"; + case 47: return "R_PPC64_TOC16"; + case 48: return "R_PPC64_TOC16_LO"; + case 49: return "R_PPC64_TOC16_HI"; + case 50: return "R_PPC64_TOC16_HA"; + case 51: return "R_PPC64_TOC"; + case 52: return "R_PPC64_PLTGOT16"; + case 53: return "R_PPC64_PLTGOT16_LO"; + case 54: return "R_PPC64_PLTGOT16_HI"; + case 55: return "R_PPC64_PLTGOT16_HA"; + case 56: return "R_PPC64_ADDR16_DS"; + case 57: return "R_PPC64_ADDR16_LO_DS"; + case 58: return "R_PPC64_GOT16_DS"; + case 59: return "R_PPC64_GOT16_LO_DS"; + case 60: return "R_PPC64_PLT16_LO_DS"; + case 61: return "R_PPC64_SECTOFF_DS"; + case 62: return "R_PPC64_SECTOFF_LO_DS"; + case 63: return "R_PPC64_TOC16_DS"; + case 64: return "R_PPC64_TOC16_LO_DS"; + case 65: return "R_PPC64_PLTGOT16_DS"; + case 66: return "R_PPC64_PLTGOT16_LO_DS"; + case 67: return "R_PPC64_TLS"; + case 68: return "R_PPC64_DTPMOD64"; + case 69: return "R_PPC64_TPREL16"; + case 70: return "R_PPC64_TPREL16_LO"; + case 71: return "R_PPC64_TPREL16_HI"; + case 72: return "R_PPC64_TPREL16_HA"; + case 73: return "R_PPC64_TPREL64"; + case 74: return "R_PPC64_DTPREL16"; + case 75: return "R_PPC64_DTPREL16_LO"; + case 76: return "R_PPC64_DTPREL16_HI"; + case 77: return "R_PPC64_DTPREL16_HA"; + case 78: return "R_PPC64_DTPREL64"; + case 79: return "R_PPC64_GOT_TLSGD16"; + case 80: return "R_PPC64_GOT_TLSGD16_LO"; + case 81: return "R_PPC64_GOT_TLSGD16_HI"; + case 82: return "R_PPC64_GOT_TLSGD16_HA"; + case 83: return "R_PPC64_GOT_TLSLD16"; + case 84: return "R_PPC64_GOT_TLSLD16_LO"; + case 85: return "R_PPC64_GOT_TLSLD16_HI"; + case 86: return "R_PPC64_GOT_TLSLD16_HA"; + case 87: return "R_PPC64_GOT_TPREL16_DS"; + case 88: return "R_PPC64_GOT_TPREL16_LO_DS"; + case 89: return "R_PPC64_GOT_TPREL16_HI"; + case 90: return "R_PPC64_GOT_TPREL16_HA"; + case 91: return "R_PPC64_GOT_DTPREL16_DS"; + case 92: return "R_PPC64_GOT_DTPREL16_LO_DS"; + case 93: return "R_PPC64_GOT_DTPREL16_HI"; + case 94: return "R_PPC64_GOT_DTPREL16_HA"; + case 95: return "R_PPC64_TPREL16_DS"; + case 96: return "R_PPC64_TPREL16_LO_DS"; + case 97: return "R_PPC64_TPREL16_HIGHER"; + case 98: return "R_PPC64_TPREL16_HIGHERA"; + case 99: return "R_PPC64_TPREL16_HIGHEST"; + case 100: return "R_PPC64_TPREL16_HIGHESTA"; + case 101: return "R_PPC64_DTPREL16_DS"; + case 102: return "R_PPC64_DTPREL16_LO_DS"; + case 103: return "R_PPC64_DTPREL16_HIGHER"; + case 104: return "R_PPC64_DTPREL16_HIGHERA"; + case 105: return "R_PPC64_DTPREL16_HIGHEST"; + case 106: return "R_PPC64_DTPREL16_HIGHESTA"; + case 107: return "R_PPC64_TLSGD"; + case 108: return "R_PPC64_TLSLD"; + case 249: return "R_PPC64_REL16"; + case 250: return "R_PPC64_REL16_LO"; + case 251: return "R_PPC64_REL16_HI"; + case 252: return "R_PPC64_REL16_HA"; + } + break; + case EM_RISCV: + switch(type) { + case 0: return "R_RISCV_NONE"; + case 1: return "R_RISCV_32"; + case 2: return "R_RISCV_64"; + case 3: return "R_RISCV_RELATIVE"; + case 4: return "R_RISCV_COPY"; + case 5: return "R_RISCV_JUMP_SLOT"; + case 6: return "R_RISCV_TLS_DTPMOD32"; + case 7: return "R_RISCV_TLS_DTPMOD64"; + case 8: return "R_RISCV_TLS_DTPREL32"; + case 9: return "R_RISCV_TLS_DTPREL64"; + case 10: return "R_RISCV_TLS_TPREL32"; + case 11: return "R_RISCV_TLS_TPREL64"; + case 16: return "R_RISCV_BRANCH"; + case 17: return "R_RISCV_JAL"; + case 18: return "R_RISCV_CALL"; + case 19: return "R_RISCV_CALL_PLT"; + case 20: return "R_RISCV_GOT_HI20"; + case 21: return "R_RISCV_TLS_GOT_HI20"; + case 22: return "R_RISCV_TLS_GD_HI20"; + case 23: return "R_RISCV_PCREL_HI20"; + case 24: return "R_RISCV_PCREL_LO12_I"; + case 25: return "R_RISCV_PCREL_LO12_S"; + case 26: return "R_RISCV_HI20"; + case 27: return "R_RISCV_LO12_I"; + case 28: return "R_RISCV_LO12_S"; + case 29: return "R_RISCV_TPREL_HI20"; + case 30: return "R_RISCV_TPREL_LO12_I"; + case 31: return "R_RISCV_TPREL_LO12_S"; + case 32: return "R_RISCV_TPREL_ADD"; + case 33: return "R_RISCV_ADD8"; + case 34: return "R_RISCV_ADD16"; + case 35: return "R_RISCV_ADD32"; + case 36: return "R_RISCV_ADD64"; + case 37: return "R_RISCV_SUB8"; + case 38: return "R_RISCV_SUB16"; + case 39: return "R_RISCV_SUB32"; + case 40: return "R_RISCV_SUB64"; + case 41: return "R_RISCV_GNU_VTINHERIT"; + case 42: return "R_RISCV_GNU_VTENTRY"; + case 43: return "R_RISCV_ALIGN"; + case 44: return "R_RISCV_RVC_BRANCH"; + case 45: return "R_RISCV_RVC_JUMP"; + case 46: return "R_RISCV_RVC_LUI"; + case 47: return "R_RISCV_GPREL_I"; + case 48: return "R_RISCV_GPREL_S"; + case 49: return "R_RISCV_TPREL_I"; + case 50: return "R_RISCV_TPREL_S"; + case 51: return "R_RISCV_RELAX"; + case 52: return "R_RISCV_SUB6"; + case 53: return "R_RISCV_SET6"; + case 54: return "R_RISCV_SET8"; + case 55: return "R_RISCV_SET16"; + case 56: return "R_RISCV_SET32"; + case 57: return "R_RISCV_32_PCREL"; + case 58: return "R_RISCV_IRELATIVE"; + } + break; + case EM_S390: + switch (type) { + case 0: return "R_390_NONE"; + case 1: return "R_390_8"; + case 2: return "R_390_12"; + case 3: return "R_390_16"; + case 4: return "R_390_32"; + case 5: return "R_390_PC32"; + case 6: return "R_390_GOT12"; + case 7: return "R_390_GOT32"; + case 8: return "R_390_PLT32"; + case 9: return "R_390_COPY"; + case 10: return "R_390_GLOB_DAT"; + case 11: return "R_390_JMP_SLOT"; + case 12: return "R_390_RELATIVE"; + case 13: return "R_390_GOTOFF"; + case 14: return "R_390_GOTPC"; + case 15: return "R_390_GOT16"; + case 16: return "R_390_PC16"; + case 17: return "R_390_PC16DBL"; + case 18: return "R_390_PLT16DBL"; + case 19: return "R_390_PC32DBL"; + case 20: return "R_390_PLT32DBL"; + case 21: return "R_390_GOTPCDBL"; + case 22: return "R_390_64"; + case 23: return "R_390_PC64"; + case 24: return "R_390_GOT64"; + case 25: return "R_390_PLT64"; + case 26: return "R_390_GOTENT"; + } + break; + case EM_SPARC: + case EM_SPARCV9: + switch(type) { + case 0: return "R_SPARC_NONE"; + case 1: return "R_SPARC_8"; + case 2: return "R_SPARC_16"; + case 3: return "R_SPARC_32"; + case 4: return "R_SPARC_DISP8"; + case 5: return "R_SPARC_DISP16"; + case 6: return "R_SPARC_DISP32"; + case 7: return "R_SPARC_WDISP30"; + case 8: return "R_SPARC_WDISP22"; + case 9: return "R_SPARC_HI22"; + case 10: return "R_SPARC_22"; + case 11: return "R_SPARC_13"; + case 12: return "R_SPARC_LO10"; + case 13: return "R_SPARC_GOT10"; + case 14: return "R_SPARC_GOT13"; + case 15: return "R_SPARC_GOT22"; + case 16: return "R_SPARC_PC10"; + case 17: return "R_SPARC_PC22"; + case 18: return "R_SPARC_WPLT30"; + case 19: return "R_SPARC_COPY"; + case 20: return "R_SPARC_GLOB_DAT"; + case 21: return "R_SPARC_JMP_SLOT"; + case 22: return "R_SPARC_RELATIVE"; + case 23: return "R_SPARC_UA32"; + case 24: return "R_SPARC_PLT32"; + case 25: return "R_SPARC_HIPLT22"; + case 26: return "R_SPARC_LOPLT10"; + case 27: return "R_SPARC_PCPLT32"; + case 28: return "R_SPARC_PCPLT22"; + case 29: return "R_SPARC_PCPLT10"; + case 30: return "R_SPARC_10"; + case 31: return "R_SPARC_11"; + case 32: return "R_SPARC_64"; + case 33: return "R_SPARC_OLO10"; + case 34: return "R_SPARC_HH22"; + case 35: return "R_SPARC_HM10"; + case 36: return "R_SPARC_LM22"; + case 37: return "R_SPARC_PC_HH22"; + case 38: return "R_SPARC_PC_HM10"; + case 39: return "R_SPARC_PC_LM22"; + case 40: return "R_SPARC_WDISP16"; + case 41: return "R_SPARC_WDISP19"; + case 42: return "R_SPARC_GLOB_JMP"; + case 43: return "R_SPARC_7"; + case 44: return "R_SPARC_5"; + case 45: return "R_SPARC_6"; + case 46: return "R_SPARC_DISP64"; + case 47: return "R_SPARC_PLT64"; + case 48: return "R_SPARC_HIX22"; + case 49: return "R_SPARC_LOX10"; + case 50: return "R_SPARC_H44"; + case 51: return "R_SPARC_M44"; + case 52: return "R_SPARC_L44"; + case 53: return "R_SPARC_REGISTER"; + case 54: return "R_SPARC_UA64"; + case 55: return "R_SPARC_UA16"; + case 56: return "R_SPARC_TLS_GD_HI22"; + case 57: return "R_SPARC_TLS_GD_LO10"; + case 58: return "R_SPARC_TLS_GD_ADD"; + case 59: return "R_SPARC_TLS_GD_CALL"; + case 60: return "R_SPARC_TLS_LDM_HI22"; + case 61: return "R_SPARC_TLS_LDM_LO10"; + case 62: return "R_SPARC_TLS_LDM_ADD"; + case 63: return "R_SPARC_TLS_LDM_CALL"; + case 64: return "R_SPARC_TLS_LDO_HIX22"; + case 65: return "R_SPARC_TLS_LDO_LOX10"; + case 66: return "R_SPARC_TLS_LDO_ADD"; + case 67: return "R_SPARC_TLS_IE_HI22"; + case 68: return "R_SPARC_TLS_IE_LO10"; + case 69: return "R_SPARC_TLS_IE_LD"; + case 70: return "R_SPARC_TLS_IE_LDX"; + case 71: return "R_SPARC_TLS_IE_ADD"; + case 72: return "R_SPARC_TLS_LE_HIX22"; + case 73: return "R_SPARC_TLS_LE_LOX10"; + case 74: return "R_SPARC_TLS_DTPMOD32"; + case 75: return "R_SPARC_TLS_DTPMOD64"; + case 76: return "R_SPARC_TLS_DTPOFF32"; + case 77: return "R_SPARC_TLS_DTPOFF64"; + case 78: return "R_SPARC_TLS_TPOFF32"; + case 79: return "R_SPARC_TLS_TPOFF64"; + } + break; + case EM_X86_64: + switch(type) { + case 0: return "R_X86_64_NONE"; + case 1: return "R_X86_64_64"; + case 2: return "R_X86_64_PC32"; + case 3: return "R_X86_64_GOT32"; + case 4: return "R_X86_64_PLT32"; + case 5: return "R_X86_64_COPY"; + case 6: return "R_X86_64_GLOB_DAT"; + case 7: return "R_X86_64_JUMP_SLOT"; + case 8: return "R_X86_64_RELATIVE"; + case 9: return "R_X86_64_GOTPCREL"; + case 10: return "R_X86_64_32"; + case 11: return "R_X86_64_32S"; + case 12: return "R_X86_64_16"; + case 13: return "R_X86_64_PC16"; + case 14: return "R_X86_64_8"; + case 15: return "R_X86_64_PC8"; + case 16: return "R_X86_64_DTPMOD64"; + case 17: return "R_X86_64_DTPOFF64"; + case 18: return "R_X86_64_TPOFF64"; + case 19: return "R_X86_64_TLSGD"; + case 20: return "R_X86_64_TLSLD"; + case 21: return "R_X86_64_DTPOFF32"; + case 22: return "R_X86_64_GOTTPOFF"; + case 23: return "R_X86_64_TPOFF32"; + case 24: return "R_X86_64_PC64"; + case 25: return "R_X86_64_GOTOFF64"; + case 26: return "R_X86_64_GOTPC32"; + case 27: return "R_X86_64_GOT64"; + case 28: return "R_X86_64_GOTPCREL64"; + case 29: return "R_X86_64_GOTPC64"; + case 30: return "R_X86_64_GOTPLT64"; + case 31: return "R_X86_64_PLTOFF64"; + case 32: return "R_X86_64_SIZE32"; + case 33: return "R_X86_64_SIZE64"; + case 34: return "R_X86_64_GOTPC32_TLSDESC"; + case 35: return "R_X86_64_TLSDESC_CALL"; + case 36: return "R_X86_64_TLSDESC"; + case 37: return "R_X86_64_IRELATIVE"; + case 38: return "R_X86_64_RELATIVE64"; + case 41: return "R_X86_64_GOTPCRELX"; + case 42: return "R_X86_64_REX_GOTPCRELX"; + } + break; + } + + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} diff --git a/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 b/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 new file mode 100644 index 0000000000..78d44fab2c --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 @@ -0,0 +1,84 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd December 15, 2011 +.Dt ELFTC_SET_TIMESTAMPS 3 +.Os +.Sh NAME +.Nm elftc_set_timestamps +.Nd set file timestamps +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft int +.Fn elftc_set_timestamps "const char *filename" "struct stat *sb" +.Sh DESCRIPTION +The +.Fn elftc_set_timestamps +function is used to set the access and modified time stamps on a file +based on the contents of a +.Vt "struct stat" +descriptor. +.Pp +Argument +.Fa filename +names an existing file in the file system. +.Pp +Argument +.Fa sb +points to structure of type +.Vt "struct stat" +populated by a prior call to +.Xr fstat 2 +or +.Xr stat 2 . +.Sh IMPLEMENTATION NOTES +This function will invoke the high-resolution +.Xr utimes 2 +system call if the underlying operating system supports it. +On operating systems lacking support for +.Xr utimes 2 , +the function will use lower resolution +.Xr utime 2 +system call. +.Sh EXAMPLES +To set the access and modified times for a new file to those of an +existing file, use: +.Bd -literal -offset indent +struct stat sb; +const char *existing_filename, *new_filename; + +if (stat(existing_filename, &sb) < 0) + err(EXIT_FAILURE, "stat failed"); + +if (elftc_set_timestamps(new_filename, &sb) < 0) + err(EXIT_FAILURE, "timestamps could not be set"); +.Ed +.Sh SEE ALSO +.Xr fstat 2 , +.Xr stat 2 , +.Xr utime 2 , +.Xr utimes 2 diff --git a/contrib/elftoolchain/libelftc/elftc_set_timestamps.c b/contrib/elftoolchain/libelftc/elftc_set_timestamps.c new file mode 100644 index 0000000000..cb28c351e0 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_set_timestamps.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "libelftc.h" + +#include "_libelftc.h" + +ELFTC_VCSID("$Id$"); + +/* + * Determine the field name for the timestamp fields inside a 'struct + * stat'. + */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#define ATIME st_atimespec +#define MTIME st_mtimespec +#define LIBELFTC_HAVE_UTIMES 1 +#endif + +#if defined(__DragonFly__) || defined(__linux__) || defined(__OpenBSD__) +#define ATIME st_atim +#define MTIME st_mtim +#define LIBELFTC_HAVE_UTIMES 1 +#endif + +#if LIBELFTC_HAVE_UTIMES +#include +#else +#include +#endif + +int +elftc_set_timestamps(const char *fn, struct stat *sb) +{ +#if LIBELFTC_HAVE_UTIMES + /* + * The BSD utimes() system call offers timestamps + * 1-microsecond granularity. + */ + struct timeval tv[2]; + + tv[0].tv_sec = sb->ATIME.tv_sec; + tv[0].tv_usec = sb->ATIME.tv_nsec / 1000; + tv[1].tv_sec = sb->MTIME.tv_sec; + tv[1].tv_usec = sb->MTIME.tv_nsec / 1000; + + return (utimes(fn, tv)); +#else + /* + * On OSes without utimes(), fall back to the POSIX utime() + * call, which offers 1-second granularity. + */ + struct utimbuf utb; + + utb.actime = sb->st_atime; + utb.modtime = sb->st_mtime; + return (utime(fn, &utb)); +#endif +} diff --git a/contrib/elftoolchain/libelftc/elftc_string_table.c b/contrib/elftoolchain/libelftc/elftc_string_table.c new file mode 100644 index 0000000000..f9f50fa91f --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_string_table.c @@ -0,0 +1,393 @@ +/*- + * Copyright (c) 2013, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "libelftc.h" +#include "_libelftc.h" + +ELFTC_VCSID("$Id: elftc_string_table.c 3750 2019-06-28 01:12:10Z emaste $"); + +#define ELFTC_STRING_TABLE_DEFAULT_SIZE (4*1024) +#define ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE 16 +#define ELFTC_STRING_TABLE_EXPECTED_CHAIN_LENGTH 8 +#define ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT (4*1024) + +struct _Elftc_String_Table_Entry { + ssize_t ste_idx; + SLIST_ENTRY(_Elftc_String_Table_Entry) ste_next; +}; + +#define ELFTC_STRING_TABLE_COMPACTION_FLAG 0x1 +#define ELFTC_STRING_TABLE_LENGTH(st) ((st)->st_len >> 1) +#define ELFTC_STRING_TABLE_CLEAR_COMPACTION_FLAG(st) do { \ + (st)->st_len &= ~ELFTC_STRING_TABLE_COMPACTION_FLAG; \ + } while (0) +#define ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st) do { \ + (st)->st_len |= ELFTC_STRING_TABLE_COMPACTION_FLAG; \ + } while (0) +#define ELFTC_STRING_TABLE_UPDATE_LENGTH(st, len) do { \ + (st)->st_len = \ + ((st)->st_len & \ + ELFTC_STRING_TABLE_COMPACTION_FLAG) | \ + ((len) << 1); \ + } while (0) + +struct _Elftc_String_Table { + size_t st_len; /* length and flags */ + int st_nbuckets; + size_t st_string_pool_size; + char *st_string_pool; + SLIST_HEAD(_Elftc_String_Table_Bucket, + _Elftc_String_Table_Entry) st_buckets[]; +}; + +static struct _Elftc_String_Table_Entry * +elftc_string_table_find_hash_entry(Elftc_String_Table *st, const char *string, + int *rhashindex) +{ + struct _Elftc_String_Table_Entry *ste; + int hashindex; + char *s; + + hashindex = libelftc_hash_string(string) % st->st_nbuckets; + + if (rhashindex) + *rhashindex = hashindex; + + SLIST_FOREACH(ste, &st->st_buckets[hashindex], ste_next) { + s = st->st_string_pool + labs(ste->ste_idx); + + assert(s > st->st_string_pool && + s < st->st_string_pool + st->st_string_pool_size); + + if (strcmp(s, string) == 0) + return (ste); + } + + return (NULL); +} + +static int +elftc_string_table_add_to_pool(Elftc_String_Table *st, const char *string) +{ + char *newpool; + size_t len, newsize, stlen; + + len = strlen(string) + 1; /* length, including the trailing NUL */ + stlen = ELFTC_STRING_TABLE_LENGTH(st); + + /* Resize the pool, if needed. */ + if (stlen + len >= st->st_string_pool_size) { + newsize = roundup(st->st_string_pool_size + + ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT, + ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT); + if ((newpool = realloc(st->st_string_pool, newsize)) == + NULL) + return (0); + st->st_string_pool = newpool; + st->st_string_pool_size = newsize; + } + + memcpy(st->st_string_pool + stlen, string, len); + ELFTC_STRING_TABLE_UPDATE_LENGTH(st, stlen + len); + + return (stlen); +} + +Elftc_String_Table * +elftc_string_table_create(size_t sizehint) +{ + struct _Elftc_String_Table *st; + int n, nbuckets, tablesize; + + if (sizehint < ELFTC_STRING_TABLE_DEFAULT_SIZE) + sizehint = ELFTC_STRING_TABLE_DEFAULT_SIZE; + + nbuckets = sizehint / (ELFTC_STRING_TABLE_EXPECTED_CHAIN_LENGTH * + ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE); + + tablesize = sizeof(struct _Elftc_String_Table) + + nbuckets * sizeof(struct _Elftc_String_Table_Bucket); + + if ((st = malloc(tablesize)) == NULL) + return (NULL); + if ((st->st_string_pool = malloc(sizehint)) == NULL) { + free(st); + return (NULL); + } + + for (n = 0; n < nbuckets; n++) + SLIST_INIT(&st->st_buckets[n]); + + st->st_len = 0; + st->st_nbuckets = nbuckets; + st->st_string_pool_size = sizehint; + *st->st_string_pool = '\0'; + ELFTC_STRING_TABLE_UPDATE_LENGTH(st, 1); + + return (st); +} + +void +elftc_string_table_destroy(Elftc_String_Table *st) +{ + int n; + struct _Elftc_String_Table_Entry *s, *t; + + for (n = 0; n < st->st_nbuckets; n++) + SLIST_FOREACH_SAFE(s, &st->st_buckets[n], ste_next, t) + free(s); + free(st->st_string_pool); + free(st); +} + +Elftc_String_Table * +elftc_string_table_from_section(Elf_Scn *scn, size_t sizehint) +{ + Elf_Data *d; + GElf_Shdr sh; + const char *s, *end; + Elftc_String_Table *st; + size_t len; + + /* Verify the type of the section passed in. */ + if (gelf_getshdr(scn, &sh) == NULL || + sh.sh_type != SHT_STRTAB) { + errno = EINVAL; + return (NULL); + } + + if ((d = elf_getdata(scn, NULL)) == NULL || + d->d_size == 0) { + errno = EINVAL; + return (NULL); + } + + if ((st = elftc_string_table_create(sizehint)) == NULL) + return (NULL); + + s = d->d_buf; + + /* + * Verify that the first byte of the data buffer is '\0'. + */ + if (*s != '\0') { + errno = EINVAL; + goto fail; + } + + end = s + d->d_size; + + /* + * Skip the first '\0' and insert the strings in the buffer, + * in order. + */ + for (s += 1; s < end; s += len) { + if (elftc_string_table_insert(st, s) == 0) + goto fail; + + len = strlen(s) + 1; /* Include space for the trailing NUL. */ + } + + return (st); + +fail: + if (st) + (void) elftc_string_table_destroy(st); + + return (NULL); +} + +const char * +elftc_string_table_image(Elftc_String_Table *st, size_t *size) +{ + char *r, *s, *end; + struct _Elftc_String_Table_Entry *ste; + struct _Elftc_String_Table_Bucket *head; + size_t copied, offset, length, newsize; + int hashindex; + + /* + * For the common case of a string table has not seen + * a string deletion, we can just export the current + * pool. + */ + if ((st->st_len & ELFTC_STRING_TABLE_COMPACTION_FLAG) == 0) { + if (size) + *size = ELFTC_STRING_TABLE_LENGTH(st); + return (st->st_string_pool); + } + + /* + * Otherwise, compact the string table in-place. + */ + assert(*st->st_string_pool == '\0'); + + newsize = 1; + end = st->st_string_pool + ELFTC_STRING_TABLE_LENGTH(st); + + for (r = s = st->st_string_pool + 1; + s < end; + s += length, r += copied) { + + copied = 0; + length = strlen(s) + 1; + + ste = elftc_string_table_find_hash_entry(st, s, + &hashindex); + head = &st->st_buckets[hashindex]; + + assert(ste != NULL); + + /* Ignore deleted strings. */ + if (ste->ste_idx < 0) { + SLIST_REMOVE(head, ste, _Elftc_String_Table_Entry, + ste_next); + free(ste); + continue; + } + + /* Move 'live' strings up. */ + offset = newsize; + newsize += length; + copied = length; + + if (r == s) /* Nothing removed yet. */ + continue; + + memmove(r, s, copied); + + /* Update the index for this entry. */ + ste->ste_idx = offset; + } + + ELFTC_STRING_TABLE_CLEAR_COMPACTION_FLAG(st); + ELFTC_STRING_TABLE_UPDATE_LENGTH(st, newsize); + + if (size) + *size = newsize; + + return (st->st_string_pool); +} + +size_t +elftc_string_table_insert(Elftc_String_Table *st, const char *string) +{ + struct _Elftc_String_Table_Entry *ste; + ssize_t idx; + int hashindex; + + hashindex = 0; + + ste = elftc_string_table_find_hash_entry(st, string, &hashindex); + + assert(hashindex >= 0 && hashindex < st->st_nbuckets); + + if (ste == NULL) { + if ((ste = malloc(sizeof(*ste))) == NULL) + return (0); + if ((ste->ste_idx = elftc_string_table_add_to_pool(st, + string)) == 0) { + free(ste); + return (0); + } + + SLIST_INSERT_HEAD(&st->st_buckets[hashindex], ste, ste_next); + } + + idx = ste->ste_idx; + if (idx < 0) /* Undelete. */ + ste->ste_idx = idx = -idx; + + return (idx); +} + +size_t +elftc_string_table_lookup(Elftc_String_Table *st, const char *string) +{ + struct _Elftc_String_Table_Entry *ste; + ssize_t idx; + int hashindex; + + ste = elftc_string_table_find_hash_entry(st, string, &hashindex); + + assert(hashindex >= 0 && hashindex < st->st_nbuckets); + + if (ste == NULL || (idx = ste->ste_idx) < 0) + return (0); + + return (idx); +} + +int +elftc_string_table_remove(Elftc_String_Table *st, const char *string) +{ + struct _Elftc_String_Table_Entry *ste; + ssize_t idx; + + ste = elftc_string_table_find_hash_entry(st, string, NULL); + + if (ste == NULL || (idx = ste->ste_idx) < 0) + return (ELFTC_FAILURE); + + assert(idx > 0 && (size_t)idx < ELFTC_STRING_TABLE_LENGTH(st)); + + ste->ste_idx = -idx; + + ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st); + + return (ELFTC_SUCCESS); +} + +const char * +elftc_string_table_to_string(Elftc_String_Table *st, size_t offset) +{ + const char *s; + + s = st->st_string_pool + offset; + + /* + * Check for: + * - An offset value within pool bounds. + * - A non-NUL byte at the specified offset. + * - The end of the prior string at offset - 1. + */ + if (offset == 0 || offset >= ELFTC_STRING_TABLE_LENGTH(st) || + *s == '\0' || *(s - 1) != '\0') { + errno = EINVAL; + return (NULL); + } + + return (s); +} diff --git a/contrib/elftoolchain/libelftc/elftc_string_table_create.3 b/contrib/elftoolchain/libelftc/elftc_string_table_create.3 new file mode 100644 index 0000000000..8ef16268c3 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_string_table_create.3 @@ -0,0 +1,234 @@ +.\" Copyright (c) 2012-2013 Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc_string_table_create.3 3960 2022-03-12 14:41:41Z jkoshy $ +.\" +.Dd June 27, 2019 +.Dt ELFTC_STRING_TABLE_CREATE 3 +.Os +.Sh NAME +.Nm elftc_string_table_create , +.Nm elftc_string_table_destroy , +.Nm elftc_string_table_from_section , +.Nm elftc_string_table_image , +.Nm elftc_string_table_insert , +.Nm elftc_string_table_lookup , +.Nm elftc_string_table_remove , +.Nm elftc_string_table_to_string +.Nd convenience routines for handling ELF string tables +.Sh SYNOPSIS +.In libelftc.h +.Ft "Elftc_String_Table *" +.Fn elftc_string_table_create "size_t sizehint" +.Ft void +.Fn elftc_string_table_destroy "Elftc_String_Table *table" +.Ft "Elftc_String_Table *" +.Fn elftc_string_table_from_section "Elf_Scn *scn" "size_t sizehint" +.Ft "const char *" +.Fo elftc_string_table_image +.Fa "Elftc_String_Table *table" +.Fa "size_t *size" +.Fc +.Ft size_t +.Fo elftc_string_table_insert +.Fa "Elftc_String_Table *table" +.Fa "const char *string" +.Fc +.Ft size_t +.Fo elftc_string_table_lookup +.Fa "Elftc_String_Table *table" +.Fa "const char *string" +.Fc +.Ft int +.Fo elftc_string_table_remove +.Fa "Elftc_String_Table *table" +.Fa "const char *string" +.Fc +.Ft "const char *" +.Fo elftc_string_table_to_string +.Fa "Elftc_String_Table *table" +.Fa "size_t offset" +.Fc +.Sh DESCRIPTION +This manual page documents convenience routines for handling ELF +string tables. +.Pp +Function +.Fn elftc_string_table_create +creates a new, empty string table. +The argument +.Fa sizehint +provides a hint about the expected number of bytes of string data in +the table. +If the argument +.Fa sizehint +is zero, an implementation-defined default will be used instead. +.Pp +Function +.Fn elftc_string_table_destroy +destroys the previously allocated string table specified by +argument +.Fa table , +and frees the internal resources allocated for it. +.Pp +Function +.Fn elftc_string_table_from_section +creates a new string table and initializes it based on the +contents of the section specified by argument +.Fa scn . +This section must be of type +.Dv SHT_STRTAB . +The argument +.Fa sizehint +provides a hint about expected number of bytes of string data in the +table. +If the value of +.Fa sizehint +is zero, an implementation-default will be used instead. +.Pp +Function +.Fn elftc_string_table_image +returns a pointer to the ELF representation of the contents of the +string table specified by argument +.Fa table . +If argument +.Fa size +is not +.Dv NULL , +the size of the ELF representation of the string table is +stored in the location pointed to by argument +.Fa size . +The function +.Fn elftc_string_table_image +will compact the string table if the table contains deleted strings. +The string offsets returned by prior calls to +.Fn elftc_string_table_insert +and +.Fn elftc_string_table_lookup +should be treated as invalid after a call to this function. +.Pp +Function +.Fn elftc_string_table_insert +inserts the NUL-terminated string pointed to by argument +.Fa string +into the string table specified by argument +.Fa table , +and returns an offset value usable in ELF data structures. +Multiple insertions of the same content will return the same offset. +The offset returned will remain valid until the next call to +.Fn elftc_string_table_image . +.Pp +Function +.Fn elftc_string_table_lookup +looks up the string referenced by argument +.Fa string +in the string table specified by argument +.Fa table , +and if found, returns the offset associated with the string. +The returned offset will be valid until the next call to +.Fn elftc_string_table_image . +.Pp +Function +.Fn elftc_string_table_remove +removes the string pointed by argument +.Fa string +from the string table referenced by argument +.Fa table , +if it is present in the string table. +.Pp +Function +.Fn elftc_string_table_to_string +returns a pointer to the NUL-terminated string residing at argument +.Fa offset +in the string table specified by argument +.Fa table . +The value of argument +.Fa offset +should be one returned by a prior call to +.Fn elftc_string_table_insert +or +.Fn elftc_string_table_lookup . +The returned pointer will remain valid until the next call to +.Fn elftc_string_table_insert +or +.Fn elftc_string_table_image . +.Ss Memory Management +The +.Lb libelftc +library manages its own memory allocations. +The application should not free the pointers returned by the string +table functions. +.Sh IMPLEMENTATION NOTES +The current implementation is optimized for the case where strings are +added to a string table, but rarely removed from it. +.Pp +The functions +.Fn elftc_string_table_insert , +.Fn elftc_string_table_lookup , +.Fn elftc_string_table_remove +and +.Fn elftc_string_table_to_string +have O(1) asymptotic behavior. +The function +.Fn elftc_string_table_image +can have O(size) asymptotic behavior, where +.Fa size +denotes the size of the string table. +.Sh RETURN VALUES +Functions +.Fn elftc_string_table_create +and +.Fn elftc_string_table_from_section +return a valid pointer to an opaque structure of type +.Vt Elftc_String_Table +on success, or +.Dv NULL +in case of an error. +.Pp +The function +.Fn elftc_string_table_image +returns a pointer to an in-memory representation of an ELF string +table on success, or +.Dv NULL +in case of an error. +.Pp +Functions +.Fn elftc_string_table_insert +and +.Fn elftc_string_table_lookup +return a non-zero offset on success, or zero in case of an error. +.Pp +Function +.Fn elftc_string_table_remove +returns a positive value on success, or zero in case of an error. +.Pp +Function +.Fn elftc_string_table_to_string +returns a valid pointer on success, or +.Dv NULL +in case of an error. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr elf 3 , +.Xr elftc 3 diff --git a/contrib/elftoolchain/libelftc/elftc_timestamp.3 b/contrib/elftoolchain/libelftc/elftc_timestamp.3 new file mode 100644 index 0000000000..72c966bba1 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_timestamp.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2016 The FreeBSD Foundation. All rights reserved. +.\" +.\" This documentation was written by Ed Maste under sponsorship of +.\" the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by the author and contributors ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. In no event shall the author or contributors be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd August 24, 2016 +.Dt ELFTC_TIMESTAMP 3 +.Os +.Sh NAME +.Nm elftc_timestamp +.Nd return the current or environment-provided timestamp +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft int +.Fo elftc_timestamp +.Fa "time_t *timestamp" +.Fc +.Sh DESCRIPTION +The +.Fn elftc_timestamp +function returns a timestamp supplied by the +.Ev SOURCE_DATE_EPOCH +environment variable, or the current time provided by +.Xr time 3 +if the environment variable is not set. +.Pp +The +.Fa timestamp +argument specifies a pointer to the location where the timestamp will be +stored. +.Sh RETURN VALUES +Function +.Fn elftc_timestamp +returns 0 on success, and -1 in the event of an error. +.Sh ERRORS +The +.Fn elftc_timestamp +function may fail with the following errors: +.Bl -tag -width ".Bq Er ERANGE" +.It Bq Er EINVAL +.Ev SOURCE_DATE_EPOCH +contains invalid characters. +.It Bq Er ERANGE +.Ev SOURCE_DATE_EPOCH +specifies a negative value or a value that cannot be stored in a +time_t. +.El +The +.Fn elftc_timestamp +function may also fail for any of the reasons described in +.Xr strtoll 3 . +.Sh SEE ALSO +.Xr strtoll 3 , +.Xr time 3 diff --git a/contrib/elftoolchain/libelftc/elftc_timestamp.c b/contrib/elftoolchain/libelftc/elftc_timestamp.c new file mode 100644 index 0000000000..ccf482f276 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_timestamp.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2016 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Ed Maste under sponsorship + * of the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +int +elftc_timestamp(time_t *timestamp) +{ + long long source_date_epoch; + char *env, *eptr; + + if ((env = getenv("SOURCE_DATE_EPOCH")) != NULL) { + errno = 0; + source_date_epoch = strtoll(env, &eptr, 10); + if (*eptr != '\0') + errno = EINVAL; + if (source_date_epoch < 0) + errno = ERANGE; + if (errno != 0) + return (-1); + *timestamp = source_date_epoch; + return (0); + } + *timestamp = time(NULL); + return (0); +} diff --git a/contrib/elftoolchain/libelftc/elftc_version.3 b/contrib/elftoolchain/libelftc/elftc_version.3 new file mode 100644 index 0000000000..b61acad515 --- /dev/null +++ b/contrib/elftoolchain/libelftc/elftc_version.3 @@ -0,0 +1,81 @@ +.\" Copyright (c) 2011,2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id: elftc_version.3 3645 2018-10-15 20:17:14Z jkoshy $ +.\" +.Dd December 30, 2012 +.Dt ELFTC_VERSION 3 +.Os +.Sh NAME +.Nm elftc_version +.Nd return a project-wide version identifier string +.Sh LIBRARY +.Lb libelftc +.Sh SYNOPSIS +.In libelftc.h +.Ft const char * +.Fn elftc_version void +.Sh DESCRIPTION +Function +.Fn elftc_version +returns a project-wide identifier string that encodes the source +revision of the project source tree. +.Pp +The returned identifier has four space-separated fields: +.Bl -tag -width ".Em Project Branch" +.It Em "Project-Name" +This is always +.Dq elftoolchain . +.It Em "Project-Branch" +The branch name for the project source tree. +.It Em "Build-OS" +The operating system that the tool chain was compiled for. +.It Em "Version-Number" +A tree-wide version number extracted from the version control +system in use. +.El +.Sh RETURN VALUES +Function +.Fn elftc_program_version +returns a pointer to an internal character buffer. +.Sh EXAMPLES +To retrieve and print the current toolchain version identifier, use: +.Bd -literal -offset indent +#include +#include + +(void) printf("%s\en", elftc_version()); +.Ed +.Pp +On the HEAD branch of the project's sources, when checked out using +Subversion and compiled on a +.Nx +host, this would print: +.D1 Dq elftoolchain HEAD NetBSD svn: Ns Em REVINFO +where +.Em REVINFO +would be the current revision information for the project source tree. +.Sh ERRORS +Function +.Fn elftc_program_version +always succeeds. diff --git a/contrib/elftoolchain/libelftc/libelftc.h b/contrib/elftoolchain/libelftc/libelftc.h new file mode 100644 index 0000000000..796b5fff85 --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc.h @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $ + * $Id: libelftc.h 3871 2020-08-21 23:28:19Z emaste $ + */ + +#ifndef _LIBELFTC_H_ +#define _LIBELFTC_H_ + +#include + +#include + +/* + * Types meant to be opaque to the consumers of these APIs. + */ +typedef struct _Elftc_Bfd_Target Elftc_Bfd_Target; +typedef struct _Elftc_String_Table Elftc_String_Table; + +/* Target types. */ +typedef enum { + ETF_NONE, + ETF_ELF, + ETF_BINARY, + ETF_SREC, + ETF_IHEX, + ETF_PE, + ETF_EFI, +} Elftc_Bfd_Target_Flavor; + +/* + * Demangler flags. + */ + +/* Name mangling style. */ +#define ELFTC_DEM_UNKNOWN 0x00000000U /* Not specified. */ +#define ELFTC_DEM_ARM 0x00000001U /* C++ Ann. Ref. Manual. */ +#define ELFTC_DEM_GNU2 0x00000002U /* GNU version 2. */ +#define ELFTC_DEM_GNU3 0x00000004U /* GNU version 3. */ + +/* Demangling behaviour control. */ +#define ELFTC_DEM_NOPARAM 0x00010000U + +#ifdef __cplusplus +extern "C" { +#endif +Elftc_Bfd_Target *elftc_bfd_find_target(const char *_tgt_name); +Elftc_Bfd_Target_Flavor elftc_bfd_target_flavor(Elftc_Bfd_Target *_tgt); +unsigned int elftc_bfd_target_byteorder(Elftc_Bfd_Target *_tgt); +unsigned int elftc_bfd_target_class(Elftc_Bfd_Target *_tgt); +unsigned int elftc_bfd_target_machine(Elftc_Bfd_Target *_tgt); +unsigned int elftc_bfd_target_osabi(Elftc_Bfd_Target *_tgt); +int elftc_copyfile(int _srcfd, int _dstfd); +int elftc_demangle(const char *_mangledname, char *_buffer, + size_t _bufsize, unsigned int _flags); +const char *elftc_reloc_type_str(unsigned int mach, unsigned int type); +int elftc_set_timestamps(const char *_filename, struct stat *_sb); +Elftc_String_Table *elftc_string_table_create(size_t _sizehint); +void elftc_string_table_destroy(Elftc_String_Table *_table); +Elftc_String_Table *elftc_string_table_from_section(Elf_Scn *_scn, + size_t _sizehint); +const char *elftc_string_table_image(Elftc_String_Table *_table, + size_t *_sz); +size_t elftc_string_table_insert(Elftc_String_Table *_table, + const char *_string); +size_t elftc_string_table_lookup(Elftc_String_Table *_table, + const char *_string); +int elftc_string_table_remove(Elftc_String_Table *_table, + const char *_string); +const char *elftc_string_table_to_string(Elftc_String_Table *_table, + size_t offset); +int elftc_timestamp(time_t *_timestamp); +const char *elftc_version(void); +#ifdef __cplusplus +} +#endif + +#endif /* _LIBELFTC_H_ */ diff --git a/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c b/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c new file mode 100644 index 0000000000..5bbf89ba78 --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c @@ -0,0 +1,488 @@ +/*- + * Copyright (c) 2008,2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3752 2019-06-28 01:12:53Z emaste $"); + +struct _Elftc_Bfd_Target _libelftc_targets[] = { + + { + .bt_name = "binary", + .bt_type = ETF_BINARY, + }, + + { + .bt_name = "elf32-avr", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_AVR, + }, + + { + .bt_name = "elf32-big", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + }, + + { + .bt_name = "elf32-bigarm", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_ARM, + }, + + { + .bt_name = "elf32-bigmips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf32-i386", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_386, + }, + + { + .bt_name = "elf32-i386-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_386, + .bt_osabi = ELFOSABI_FREEBSD, + }, + + { + .bt_name = "elf32-ia64-big", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_IA_64, + }, + + { + .bt_name = "elf32-little", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + }, + + { + .bt_name = "elf32-littlearm", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_ARM, + }, + + { + .bt_name = "elf32-littlemips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf32-powerpc", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_PPC, + }, + + { + .bt_name = "elf32-powerpc-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_PPC, + .bt_osabi = ELFOSABI_FREEBSD, + }, + + { + .bt_name = "elf32-powerpcle", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_PPC, + }, + + { + .bt_name = "elf32-sh", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + }, + + { + .bt_name = "elf32-shl", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + }, + + { + .bt_name = "elf32-sh-nbsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_NETBSD, + }, + + { + .bt_name = "elf32-shl-nbsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_NETBSD, + }, + + { + .bt_name = "elf32-shbig-linux", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_LINUX, + }, + + { + .bt_name = "elf32-sh-linux", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_LINUX, + }, + + { + .bt_name = "elf32-sparc", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_SPARC, + }, + + { + .bt_name = "elf32-tradbigmips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf32-tradlittlemips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf64-alpha", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_ALPHA, + }, + + { + .bt_name = "elf64-alpha-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_ALPHA, + .bt_osabi = ELFOSABI_FREEBSD + }, + + { + .bt_name = "elf64-big", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + }, + + { + .bt_name = "elf64-bigmips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf64-ia64-big", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_IA_64, + }, + + { + .bt_name = "elf64-ia64-little", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_IA_64, + }, + + { + .bt_name = "elf64-little", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + }, + + { + .bt_name = "elf64-littleaarch64", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_AARCH64, + }, + + { + .bt_name = "elf64-littlemips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf64-powerpc", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_PPC64, + }, + + { + .bt_name = "elf64-powerpc-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_PPC64, + .bt_osabi = ELFOSABI_FREEBSD, + }, + + { + .bt_name = "elf64-powerpcle", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_PPC64, + }, + + { + .bt_name = "elf32-riscv", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_RISCV, + }, + + { + .bt_name = "elf64-riscv", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_RISCV, + }, + + { + .bt_name = "elf64-riscv-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_RISCV, + .bt_osabi = ELFOSABI_FREEBSD, + }, + + { + .bt_name = "elf64-sh64", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + }, + + { + .bt_name = "elf64-sh64l", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + }, + + { + .bt_name = "elf64-sh64-nbsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_NETBSD, + }, + + { + .bt_name = "elf64-sh64l-nbsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_NETBSD, + }, + + { + .bt_name = "elf64-sh64big-linux", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_LINUX, + }, + + { + .bt_name = "elf64-sh64-linux", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SH, + .bt_osabi = ELFOSABI_LINUX, + }, + + { + .bt_name = "elf64-sparc", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SPARCV9, + }, + + { + .bt_name = "elf64-sparc-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_SPARCV9, + .bt_osabi = ELFOSABI_FREEBSD + }, + + { + .bt_name = "elf64-tradbigmips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf64-tradlittlemips", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_MIPS, + }, + + { + .bt_name = "elf64-x86-64", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_X86_64, + }, + + { + .bt_name = "elf64-x86-64-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_X86_64, + .bt_osabi = ELFOSABI_FREEBSD + }, + + { + .bt_name = "ihex", + .bt_type = ETF_IHEX, + }, + + { + .bt_name = "srec", + .bt_type = ETF_SREC, + }, + + { + .bt_name = "symbolsrec", + .bt_type = ETF_SREC, + }, + + { + .bt_name = "efi-app-ia32", + .bt_type = ETF_EFI, + .bt_machine = EM_386, + }, + + { + .bt_name = "efi-app-x86_64", + .bt_type = ETF_EFI, + .bt_machine = EM_X86_64, + }, + + { + .bt_name = "pei-i386", + .bt_type = ETF_PE, + .bt_machine = EM_386, + }, + + { + .bt_name = "pei-x86-64", + .bt_type = ETF_PE, + .bt_machine = EM_X86_64, + }, + + { + .bt_name = NULL, + .bt_type = ETF_NONE, + }, +}; diff --git a/contrib/elftoolchain/libelftc/libelftc_dem_arm.c b/contrib/elftoolchain/libelftc/libelftc_dem_arm.c new file mode 100644 index 0000000000..0c565aa701 --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_dem_arm.c @@ -0,0 +1,1217 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_dem_arm.c 3806 2020-02-07 02:13:49Z emaste $"); + +/** + * @file cpp_demangle_arm.c + * @brief Decode function name encoding in ARM. + * + * Function name encoding in "The Annotated C++ Reference Manual". + * + * Ref : "The Annotated C++ Reference Manual", Margaet A.Ellis, + * Bjarne Stroustrup, AT&T Bell Laboratories 1990, pp 122-126. + */ + +enum encode_type { + ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER +}; + +struct cstring { + char *buf; + size_t size; +}; + +struct demangle_data { + bool ptr, ref, cnst, array; + struct cstring array_str; + const char *p; + enum encode_type type; + struct vector_str vec; + struct vector_str arg; +}; + +#define SIMPLE_HASH(x,y) (64 * x + y) +#define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) +#define CPP_DEMANGLE_ARM_TRY 128 + +static void dest_cstring(struct cstring *); +static void dest_demangle_data(struct demangle_data *); +static bool init_cstring(struct cstring *, size_t); +static bool init_demangle_data(struct demangle_data *); +static bool push_CTDT(const char *, size_t, struct vector_str *); +static bool read_array(struct demangle_data *); +static bool read_class(struct demangle_data *); +static bool read_func(struct demangle_data *); +static bool read_func_name(struct demangle_data *); +static bool read_func_ptr(struct demangle_data *); +static bool read_memptr(struct demangle_data *); +static bool read_op(struct demangle_data *); +static bool read_op_user(struct demangle_data *); +static bool read_qual_name(struct demangle_data *); +static int read_subst(struct demangle_data *); +static int read_subst_iter(struct demangle_data *); +static bool read_type(struct demangle_data *); + +/** + * @brief Decode the input string by the ARM style. + * + * @return New allocated demangled string or NULL if failed. + */ +char * +cpp_demangle_ARM(const char *org) +{ + struct demangle_data d; + size_t arg_begin, arg_len; + unsigned int try; + char *rtn, *arg; + + if (org == NULL) + return (NULL); + + if (init_demangle_data(&d) == false) + return (NULL); + + try = 0; + rtn = NULL; + + d.p = org; + if (read_func_name(&d) == false) + goto clean; + + if (d.type == ENCODE_OP_CT) { + if (push_CTDT("::", 2, &d.vec) == false) + goto clean; + + goto flat; + } + + if (d.type == ENCODE_OP_DT) { + if (push_CTDT("::~", 3, &d.vec) == false) + goto clean; + + goto flat; + } + + if (d.type == ENCODE_OP_USER) + goto flat; + + /* function type */ + if (*d.p != 'F') + goto clean; + ++d.p; + + /* start argument types */ + if (VEC_PUSH_STR(&d.vec, "(") == false) + goto clean; + + for (;;) { + if (*d.p == 'T') { + const int rtn_subst = read_subst(&d); + + if (rtn_subst == -1) + goto clean; + else if (rtn_subst == 1) + break; + + continue; + } + + if (*d.p == 'N') { + const int rtn_subst_iter = read_subst_iter(&d); + + if (rtn_subst_iter == -1) + goto clean; + else if(rtn_subst_iter == 1) + break; + + continue; + } + + arg_begin = d.vec.size; + + if (read_type(&d) == false) + goto clean; + + if (d.ptr == true) { + if (VEC_PUSH_STR(&d.vec, "*") == false) + goto clean; + + d.ptr = false; + } + + if (d.ref == true) { + if (VEC_PUSH_STR(&d.vec, "&") == false) + goto clean; + + d.ref = false; + } + + if (d.cnst == true) { + if (VEC_PUSH_STR(&d.vec, " const") == false) + goto clean; + + d.cnst = false; + } + + if (d.array == true) { + if (vector_str_push(&d.vec, d.array_str.buf, + d.array_str.size) == false) + goto clean; + + dest_cstring(&d.array_str); + d.array = false; + } + + if (*d.p == '\0') + break; + + if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1, + &arg_len)) == NULL) + goto clean; + + if (vector_str_push(&d.arg, arg, arg_len) == false) { + free(arg); + goto clean; + } + + free(arg); + + if (VEC_PUSH_STR(&d.vec, ", ") == false) + goto clean; + + if (++try > CPP_DEMANGLE_ARM_TRY) + goto clean; + } + + /* end argument types */ + if (VEC_PUSH_STR(&d.vec, ")") == false) + goto clean; + +flat: + rtn = vector_str_get_flat(&d.vec, NULL); +clean: + dest_demangle_data(&d); + + return (rtn); +} + +/** + * @brief Test input string is encoded by the ARM style. + * + * @return True if input string is encoded by the ARM style. + */ +bool +is_cpp_mangled_ARM(const char *org) +{ + + if (org == NULL) + return (false); + + return (strstr(org, "__") != NULL); +} + +static void +dest_cstring(struct cstring *s) +{ + + if (s == NULL) + return; + + free(s->buf); + s->buf = NULL; + s->size = 0; +} + +static void +dest_demangle_data(struct demangle_data *d) +{ + + if (d != NULL) { + vector_str_dest(&d->arg); + vector_str_dest(&d->vec); + + dest_cstring(&d->array_str); + } +} + +static bool +init_cstring(struct cstring *s, size_t len) +{ + + if (s == NULL || len <= 1) + return (false); + + if ((s->buf = malloc(sizeof(char) * len)) == NULL) + return (false); + + s->size = len - 1; + + return (true); +} + +static bool +init_demangle_data(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + d->ptr = false; + d->ref = false; + d->cnst = false; + d->array = false; + + d->array_str.buf = NULL; + d->array_str.size = 0; + + d->type = ENCODE_FUNC; + + if (!vector_str_init(&d->vec)) + return (false); + + if (!vector_str_init(&d->arg)) { + vector_str_dest(&d->vec); + return (false); + } + + return (true); +} + +static bool +push_CTDT(const char *s, size_t l, struct vector_str *v) +{ + + if (s == NULL || l == 0 || v == NULL) + return (false); + + if (vector_str_push(v, s, l) == false) + return (false); + + assert(v->size > 1); + if (VEC_PUSH_STR(v, v->container[v->size - 2]) == false) + return (false); + + if (VEC_PUSH_STR(v, "()") == false) + return (false); + + return (true); +} + +static bool +read_array(struct demangle_data *d) +{ + size_t len; + const char *end; + + if (d == NULL || d->p == NULL) + return (false); + + end = d->p; + assert(end != NULL); + + for (;;) { + if (*end == '\0') + return (false); + + if (ELFTC_ISDIGIT(*end) == 0) + break; + + ++end; + } + + if (*end != '_') + return (false); + + len = end - d->p; + assert(len > 0); + + dest_cstring(&d->array_str); + if (init_cstring(&d->array_str, len + 3) == false) + return (false); + + strncpy(d->array_str.buf + 1, d->p, len); + *d->array_str.buf = '['; + *(d->array_str.buf + len + 1) = ']'; + + d->array = true; + d->p = end + 1; + + return (true); +} + +static bool +read_class(struct demangle_data *d) +{ + size_t len; + char *str; + + if (d == NULL) + return (false); + + len = strtol(d->p, &str, 10); + if (len == 0 && (errno == EINVAL || errno == ERANGE)) + return (false); + + assert(len > 0); + assert(str != NULL); + + if (vector_str_push(&d->vec, str, len) == false) + return (false); + + d->p = str + len; + + return (true); +} + +static bool +read_func(struct demangle_data *d) +{ + size_t len; + const char *name; + char *delim; + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + if ((delim = strstr(d->p, "__")) == NULL) + return (false); + + len = delim - d->p; + assert(len != 0); + + name = d->p; + + d->p = delim + 2; + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + if (read_qual_name(d) == false) + return (false); + } else if (ELFTC_ISDIGIT(*d->p)) { + if (read_class(d) == false) + return (false); + + if (VEC_PUSH_STR(&d->vec, "::") == false) + return (false); + } + + if (vector_str_push(&d->vec, name, len) == false) + return (false); + + return (true); +} + +static bool +read_func_name(struct demangle_data *d) +{ + size_t len; + bool rtn; + char *op_name; + + if (d == NULL) + return (false); + + rtn = false; + op_name = NULL; + + assert(d->p != NULL && "d->p (org str) is NULL"); + + if (*d->p == '_' && *(d->p + 1) == '_') { + d->p += 2; + + d->type = ENCODE_OP; + if (read_op(d) == false) + return (false); + + if (d->type == ENCODE_OP_CT || d->type == ENCODE_OP_DT || + d->type == ENCODE_OP_USER) + return (true); + + /* skip "__" */ + d->p += 2; + + /* assume delimiter is removed */ + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + assert(d->vec.size > 0); + + len = strlen(d->vec.container[d->vec.size - 1]); + if ((op_name = malloc(sizeof(char) * (len + 1))) + == NULL) + return (false); + + snprintf(op_name, len + 1, "%s", + d->vec.container[d->vec.size - 1]); + vector_str_pop(&d->vec); + + if (read_qual_name(d) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::") == false) + goto clean; + + if (vector_str_push(&d->vec, op_name, len) == false) + goto clean; + + rtn = true; + } else if (ELFTC_ISDIGIT(*d->p)) { + assert(d->vec.size > 0); + + len = strlen(d->vec.container[d->vec.size - 1]); + if ((op_name = malloc(sizeof(char) * (len + 1))) + == NULL) + return (false); + + snprintf(op_name, len + 1, "%s", + d->vec.container[d->vec.size - 1]); + vector_str_pop(&d->vec); + + if (read_class(d) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::") == false) + goto clean; + + if (vector_str_push(&d->vec, op_name, len) == false) + goto clean; + + rtn = true; + } + } else + return (read_func(d)); + +clean: + free(op_name); + + return (rtn); +} + +/* Read function ptr type */ +static bool +read_func_ptr(struct demangle_data *d) +{ + struct demangle_data fptr; + size_t arg_len, rtn_len; + char *arg_type, *rtn_type; + int lim; + + if (d == NULL) + return (false); + + if (init_demangle_data(&fptr) == false) + return (false); + + fptr.p = d->p + 1; + lim = 0; + arg_type = NULL; + rtn_type = NULL; + + for (;;) { + if (read_type(&fptr) == false) { + dest_demangle_data(&fptr); + + return (false); + } + + if (fptr.ptr == true) { + if (VEC_PUSH_STR(&fptr.vec, "*") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.ptr = false; + } + + if (fptr.ref == true) { + if (VEC_PUSH_STR(&fptr.vec, "&") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.ref = false; + } + + if (fptr.cnst == true) { + if (VEC_PUSH_STR(&fptr.vec, " const") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.cnst = false; + } + + if (*fptr.p == '_') + break; + + if (VEC_PUSH_STR(&fptr.vec, ", ") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + if (++lim > CPP_DEMANGLE_ARM_TRY) { + + dest_demangle_data(&fptr); + + return (false); + } + } + + arg_type = vector_str_get_flat(&fptr.vec, &arg_len); + /* skip '_' */ + d->p = fptr.p + 1; + + dest_demangle_data(&fptr); + + if (init_demangle_data(&fptr) == false) { + free(arg_type); + + return (false); + } + + fptr.p = d->p; + lim = 0; + + if (read_type(&fptr) == false) { + free(arg_type); + dest_demangle_data(&fptr); + + return (false); + } + + rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len); + d->p = fptr.p; + + + dest_demangle_data(&fptr); + + if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) { + free(rtn_type); + free(arg_type); + + return (false); + } + + free(rtn_type); + + if (VEC_PUSH_STR(&d->vec, " (*)(") == false) { + free(arg_type); + + return (false); + } + + if (vector_str_push(&d->vec, arg_type, arg_len) == false) { + free(arg_type); + + return (false); + } + + free(arg_type); + + return (VEC_PUSH_STR(&d->vec, ")")); +} + +static bool +read_memptr(struct demangle_data *d) +{ + struct demangle_data mptr; + size_t len; + bool rtn; + char *mptr_str; + + if (d == NULL || d->p == NULL) + return (false); + + if (init_demangle_data(&mptr) == false) + return (false); + + rtn = false; + mptr_str = NULL; + + mptr.p = d->p; + if (*mptr.p == 'Q') { + ++mptr.p; + + if (read_qual_name(&mptr) == false) + goto clean; + } else { + if (read_class(&mptr) == false) + goto clean; + } + + d->p = mptr.p; + + if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL) + goto clean; + + if (vector_str_push(&d->vec, mptr_str, len) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::*") == false) + goto clean; + + rtn = true; +clean: + free(mptr_str); + dest_demangle_data(&mptr); + + return (rtn); +} + +static bool +read_op(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + + switch (SIMPLE_HASH(*(d->p), *(d->p+1))) { + case SIMPLE_HASH('m', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator*")); + case SIMPLE_HASH('d', 'v') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator/")); + case SIMPLE_HASH('m', 'd') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator%")); + case SIMPLE_HASH('p', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator+")); + case SIMPLE_HASH('m', 'i') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator-")); + case SIMPLE_HASH('l', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<<")); + case SIMPLE_HASH('r', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>>")); + case SIMPLE_HASH('e', 'q') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator==")); + case SIMPLE_HASH('n', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator!=")); + case SIMPLE_HASH('l', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<")); + case SIMPLE_HASH('g', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>")); + case SIMPLE_HASH('l', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<=")); + case SIMPLE_HASH('g', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>=")); + case SIMPLE_HASH('a', 'd') : + d->p += 2; + if (*d->p == 'v') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator/=")); + } else + return (VEC_PUSH_STR(&d->vec, "operator&")); + case SIMPLE_HASH('o', 'r') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator|")); + case SIMPLE_HASH('e', 'r') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator^")); + case SIMPLE_HASH('a', 'a') : + d->p += 2; + if (*d->p == 'd') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator&=")); + } else + return (VEC_PUSH_STR(&d->vec, "operator&&")); + case SIMPLE_HASH('o', 'o') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator||")); + case SIMPLE_HASH('n', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator!")); + case SIMPLE_HASH('c', 'o') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator~")); + case SIMPLE_HASH('p', 'p') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator++")); + case SIMPLE_HASH('m', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator--")); + case SIMPLE_HASH('a', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator=")); + case SIMPLE_HASH('r', 'f') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator->")); + case SIMPLE_HASH('a', 'p') : + /* apl */ + if (*(d->p + 2) != 'l') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator+=")); + case SIMPLE_HASH('a', 'm') : + d->p += 2; + if (*d->p == 'i') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator-=")); + } else if (*d->p == 'u') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator*=")); + } else if (*d->p == 'd') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator%=")); + } + + return (false); + case SIMPLE_HASH('a', 'l') : + /* als */ + if (*(d->p + 2) != 's') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator<<=")); + case SIMPLE_HASH('a', 'r') : + /* ars */ + if (*(d->p + 2) != 's') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator>>=")); + case SIMPLE_HASH('a', 'o') : + /* aor */ + if (*(d->p + 2) != 'r') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator|=")); + case SIMPLE_HASH('a', 'e') : + /* aer */ + if (*(d->p + 2) != 'r') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator^=")); + case SIMPLE_HASH('c', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator,")); + case SIMPLE_HASH('r', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator->*")); + case SIMPLE_HASH('c', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "()")); + case SIMPLE_HASH('v', 'c') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "[]")); + case SIMPLE_HASH('c', 't') : + d->p += 4; + d->type = ENCODE_OP_CT; + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + return (read_qual_name(d)); + } else if (ELFTC_ISDIGIT(*d->p)) + return (read_class(d)); + + return (false); + case SIMPLE_HASH('d', 't') : + d->p += 4; + d->type = ENCODE_OP_DT; + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + return (read_qual_name(d)); + } else if (ELFTC_ISDIGIT(*d->p)) + return (read_class(d)); + + return (false); + case SIMPLE_HASH('n', 'w') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator new()")); + case SIMPLE_HASH('d', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator delete()")); + case SIMPLE_HASH('o', 'p') : + /* __op__ */ + d->p += 2; + + d->type = ENCODE_OP_USER; + + return (read_op_user(d)); + default : + return (false); + }; +} + +static bool +read_op_user(struct demangle_data *d) +{ + struct demangle_data from, to; + size_t from_len, to_len; + bool rtn; + char *from_str, *to_str; + + if (d == NULL) + return (false); + + if (init_demangle_data(&from) == false) + return (false); + + rtn = false; + from_str = NULL; + to_str = NULL; + if (init_demangle_data(&to) == false) + goto clean; + + to.p = d->p; + if (*to.p == 'Q') { + ++to.p; + + if (read_qual_name(&to) == false) + goto clean; + + /* pop last '::' */ + if (vector_str_pop(&to.vec) == false) + goto clean; + } else { + if (read_class(&to) == false) + goto clean; + + /* skip '__' */ + to.p += 2; + } + + if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL) + goto clean; + + from.p = to.p; + if (*from.p == 'Q') { + ++from.p; + + if (read_qual_name(&from) == false) + goto clean; + + /* pop last '::' */ + if (vector_str_pop(&from.vec) == false) + goto clean; + } else { + if (read_class(&from) == false) + goto clean; + } + + if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL) + goto clean; + + if (vector_str_push(&d->vec, from_str, from_len) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::operator ") == false) + goto clean; + + if (vector_str_push(&d->vec, to_str, to_len) == false) + goto clean; + + rtn = VEC_PUSH_STR(&d->vec, "()"); +clean: + free(to_str); + free(from_str); + dest_demangle_data(&to); + dest_demangle_data(&from); + + return (rtn); +} + +/* single digit + class names */ +static bool +read_qual_name(struct demangle_data *d) +{ + int i; + char num; + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); + + num = *d->p - 48; + + assert(num > 0); + + ++d->p; + for (i = 0; i < num ; ++i) { + if (read_class(d) == false) + return (false); + + if (VEC_PUSH_STR(&d->vec, "::") == false) + return (false); + } + + if (*d->p != '\0') + d->p = d->p + 2; + + return (true); +} + +/* Return -1 at fail, 0 at success, and 1 at end */ +static int +read_subst(struct demangle_data *d) +{ + size_t idx; + char *str; + + if (d == NULL) + return (-1); + + idx = strtol(d->p + 1, &str, 10); + if (idx == 0 && (errno == EINVAL || errno == ERANGE)) + return (-1); + + assert(idx > 0); + assert(str != NULL); + + d->p = str; + + if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) + return (-1); + + if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) + return (-1); + + if (*d->p == '\0') + return (1); + + return (0); +} + +static int +read_subst_iter(struct demangle_data *d) +{ + int i; + size_t idx; + char repeat; + char *str; + + if (d == NULL) + return (-1); + + ++d->p; + assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); + + repeat = *d->p - 48; + + assert(repeat > 1); + + ++d->p; + + idx = strtol(d->p, &str, 10); + if (idx == 0 && (errno == EINVAL || errno == ERANGE)) + return (-1); + + assert(idx > 0); + assert(str != NULL); + + d->p = str; + + for (i = 0; i < repeat ; ++i) { + if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) + return (-1); + + if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) + return (-1); + + if (i != repeat - 1 && + VEC_PUSH_STR(&d->vec, ", ") == false) + return (-1); + } + + if (*d->p == '\0') + return (1); + + return (0); +} + +static bool +read_type(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + + while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' || + *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' || + *d->p == 'M') { + switch (*d->p) { + case 'U' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "unsigned ") == false) + return (false); + + break; + case 'C' : + ++d->p; + + if (*d->p == 'P') + d->cnst = true; + else { + if (VEC_PUSH_STR(&d->vec, "const ") == + false) + return (false); + } + + break; + case 'V' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "volatile ") == false) + return (false); + + break; + case 'S' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "signed ") == false) + return (false); + + break; + case 'P' : + ++d->p; + + if (*d->p == 'F') + return (read_func_ptr(d)); + else + d->ptr = true; + + break; + case 'R' : + ++d->p; + + d->ref = true; + + break; + case 'F' : + break; + case 'A' : + ++d->p; + + if (read_array(d) == false) + return (false); + + break; + case 'M' : + ++d->p; + + if (read_memptr(d) == false) + return (false); + + break; + default : + break; + } + } + + if (ELFTC_ISDIGIT(*d->p)) + return (read_class(d)); + + switch (*d->p) { + case 'Q' : + ++d->p; + + return (read_qual_name(d)); + case 'v' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "void")); + case 'c' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "char")); + case 's' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "short")); + case 'i' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "int")); + case 'l' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "long")); + case 'f' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "float")); + case 'd': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "double")); + case 'r': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "long double")); + case 'e': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "...")); + default: + return (false); + }; + + /* NOTREACHED */ + return (false); +} diff --git a/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c b/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c new file mode 100644 index 0000000000..3ba93de9ca --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c @@ -0,0 +1,1366 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_dem_gnu2.c 3806 2020-02-07 02:13:49Z emaste $"); + +/** + * @file cpp_demangle_gnu2.c + * @brief Decode function name encoding in GNU 2. + * + * Function name encoding in GNU 2 based on ARM style. + */ + +enum encode_type { + ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER, + ENCODE_OP_TF, ENCODE_OP_TI, ENCODE_OP_VT +}; + +struct cstring { + char *buf; + size_t size; +}; + +struct demangle_data { + bool ptr, ref, cnst, array, cnst_fn, class_name; + struct cstring array_str; + const char *p; + enum encode_type type; + struct vector_str vec; + struct vector_str arg; +}; + +#define SIMPLE_HASH(x,y) (64 * x + y) +#define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) +#define CPP_DEMANGLE_GNU2_TRY 128 + +static void dest_cstring(struct cstring *); +static void dest_demangle_data(struct demangle_data *); +static bool init_cstring(struct cstring *, size_t); +static bool init_demangle_data(struct demangle_data *); +static bool push_CTDT(const char *, size_t, struct vector_str *); +static bool read_array(struct demangle_data *); +static bool read_class(struct demangle_data *); +static bool read_func(struct demangle_data *); +static bool read_func_name(struct demangle_data *); +static bool read_func_ptr(struct demangle_data *); +static bool read_memptr(struct demangle_data *); +static bool read_op(struct demangle_data *); +static bool read_op_user(struct demangle_data *); +static bool read_qual_name(struct demangle_data *); +static int read_subst(struct demangle_data *); +static int read_subst_iter(struct demangle_data *); +static bool read_type(struct demangle_data *); + +/** + * @brief Decode the input string by the GNU 2 style. + * + * @return New allocated demangled string or NULL if failed. + */ +char * +cpp_demangle_gnu2(const char *org) +{ + struct demangle_data d; + size_t arg_begin, arg_len; + unsigned int try; + char *rtn, *arg; + + if (org == NULL) + return (NULL); + + if (init_demangle_data(&d) == false) + return (NULL); + + try = 0; + rtn = NULL; + + d.p = org; + if (read_func_name(&d) == false) + goto clean; + + switch (d.type) { + case ENCODE_FUNC : + case ENCODE_OP : + break; + + case ENCODE_OP_CT : + if (push_CTDT("::", 2, &d.vec) == false) + goto clean; + + break; + case ENCODE_OP_DT : + if (push_CTDT("::~", 3, &d.vec) == false) + goto clean; + + if (VEC_PUSH_STR(&d.vec, "(void)") == false) + goto clean; + + goto flat; + case ENCODE_OP_USER : + case ENCODE_OP_TF : + case ENCODE_OP_TI : + case ENCODE_OP_VT : + goto flat; + } + + if (*d.p == 'F') + ++d.p; + else if (*d.p == '\0') { + if (d.class_name == true) { + if (VEC_PUSH_STR(&d.vec, "(void)") == false) + goto clean; + + goto flat; + } else + goto clean; + } + + /* start argument types */ + if (VEC_PUSH_STR(&d.vec, "(") == false) + goto clean; + + for (;;) { + if (*d.p == 'T') { + const int rtn_subst = read_subst(&d); + + if (rtn_subst == -1) + goto clean; + else if (rtn_subst == 1) + break; + + continue; + } + + if (*d.p == 'N') { + const int rtn_subst_iter = read_subst_iter(&d); + + if (rtn_subst_iter == -1) + goto clean; + else if(rtn_subst_iter == 1) + break; + + continue; + } + + arg_begin = d.vec.size; + + if (read_type(&d) == false) + goto clean; + + if (d.ptr == true) { + if (VEC_PUSH_STR(&d.vec, "*") == false) + goto clean; + + d.ptr = false; + } + + if (d.ref == true) { + if (VEC_PUSH_STR(&d.vec, "&") == false) + goto clean; + + d.ref = false; + } + + if (d.cnst == true) { + if (VEC_PUSH_STR(&d.vec, " const") == false) + goto clean; + + d.cnst = false; + } + + if (d.array == true) { + if (vector_str_push(&d.vec, d.array_str.buf, + d.array_str.size) == false) + goto clean; + + dest_cstring(&d.array_str); + d.array = false; + } + + if (*d.p == '\0') + break; + + if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1, + &arg_len)) == NULL) + goto clean; + + if (vector_str_push(&d.arg, arg, arg_len) == false) { + free(arg); + goto clean; + } + + free(arg); + + if (VEC_PUSH_STR(&d.vec, ", ") == false) + goto clean; + + if (++try > CPP_DEMANGLE_GNU2_TRY) + goto clean; + } + + /* end argument types */ + if (VEC_PUSH_STR(&d.vec, ")") == false) + goto clean; +flat: + if (d.cnst_fn == true && VEC_PUSH_STR(&d.vec, " const") == false) + goto clean; + + rtn = vector_str_get_flat(&d.vec, NULL); +clean: + dest_demangle_data(&d); + + return (rtn); +} + +/** + * @brief Test input string is encoded by the GNU 2 style. + * + * @return True if input string is encoded by the GNU 2 style. + */ +bool +is_cpp_mangled_gnu2(const char *org) +{ + char *str; + bool rtn = false; + + if (org == NULL) + return (false); + + /* search valid text to end */ + str = strstr(org, "__"); + while (str != NULL) { + if (*(str + 2) != '\0') { + if (*(str + 2) == 'C' || + *(str + 2) == 'F' || + *(str + 2) == 'Q' || + ELFTC_ISDIGIT(*(str + 2))) { + rtn |= true; + + break; + } + + if (*(str + 3) != '\0') { + switch (SIMPLE_HASH(*(str + 2), *(str + 3))) { + case SIMPLE_HASH('m', 'l') : + case SIMPLE_HASH('d', 'v') : + case SIMPLE_HASH('m', 'd') : + case SIMPLE_HASH('p', 'l') : + case SIMPLE_HASH('m', 'i') : + case SIMPLE_HASH('l', 's') : + case SIMPLE_HASH('r', 's') : + case SIMPLE_HASH('e', 'q') : + case SIMPLE_HASH('n', 'e') : + case SIMPLE_HASH('l', 't') : + case SIMPLE_HASH('g', 't') : + case SIMPLE_HASH('l', 'e') : + case SIMPLE_HASH('g', 'e') : + case SIMPLE_HASH('a', 'd') : + case SIMPLE_HASH('o', 'r') : + case SIMPLE_HASH('e', 'r') : + case SIMPLE_HASH('a', 'a') : + case SIMPLE_HASH('o', 'o') : + case SIMPLE_HASH('n', 't') : + case SIMPLE_HASH('c', 'o') : + case SIMPLE_HASH('p', 'p') : + case SIMPLE_HASH('m', 'm') : + case SIMPLE_HASH('a', 's') : + case SIMPLE_HASH('r', 'f') : + case SIMPLE_HASH('a', 'p') : + case SIMPLE_HASH('a', 'm') : + case SIMPLE_HASH('a', 'l') : + case SIMPLE_HASH('a', 'r') : + case SIMPLE_HASH('a', 'o') : + case SIMPLE_HASH('a', 'e') : + case SIMPLE_HASH('c', 'm') : + case SIMPLE_HASH('r', 'm') : + case SIMPLE_HASH('c', 'l') : + case SIMPLE_HASH('v', 'c') : + case SIMPLE_HASH('n', 'w') : + case SIMPLE_HASH('d', 'l') : + case SIMPLE_HASH('o', 'p') : + case SIMPLE_HASH('t', 'f') : + case SIMPLE_HASH('t', 'i') : + rtn |= true; + + break; + } + } + } + + str = strstr(str + 2, "__"); + } + + rtn |= strstr(org, "_$_") != NULL; + rtn |= strstr(org, "_vt$") != NULL; + + return (rtn); +} + +static void +dest_cstring(struct cstring *s) +{ + + if (s == NULL) + return; + + free(s->buf); + s->buf = NULL; + s->size = 0; +} + +static void +dest_demangle_data(struct demangle_data *d) +{ + + if (d != NULL) { + vector_str_dest(&d->arg); + vector_str_dest(&d->vec); + + dest_cstring(&d->array_str); + } +} + +static bool +init_cstring(struct cstring *s, size_t len) +{ + + if (s == NULL || len <= 1) + return (false); + + if ((s->buf = malloc(sizeof(char) * len)) == NULL) + return (false); + + s->size = len - 1; + + return (true); +} + +static bool +init_demangle_data(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + d->ptr = false; + d->ref = false; + d->cnst = false; + d->array = false; + d->cnst_fn = false; + d->class_name = false; + + d->array_str.buf = NULL; + d->array_str.size = 0; + + d->type = ENCODE_FUNC; + + if (!vector_str_init(&d->vec)) + return (false); + + if (!vector_str_init(&d->arg)) { + vector_str_dest(&d->vec); + return (false); + } + + return (true); +} + +static bool +push_CTDT(const char *s, size_t l, struct vector_str *v) +{ + + if (s == NULL || l == 0 || v == NULL) + return (false); + + if (vector_str_push(v, s, l) == false) + return (false); + + assert(v->size > 1); + + return (VEC_PUSH_STR(v, v->container[v->size - 2])); +} + +static bool +read_array(struct demangle_data *d) +{ + size_t len; + const char *end; + + if (d == NULL || d->p == NULL) + return (false); + + end = d->p; + assert(end != NULL); + + for (;;) { + if (*end == '\0') + return (false); + + if (ELFTC_ISDIGIT(*end) == 0) + break; + + ++end; + } + + if (*end != '_') + return (false); + + len = end - d->p; + assert(len > 0); + + dest_cstring(&d->array_str); + if (init_cstring(&d->array_str, len + 3) == false) + return (false); + + strncpy(d->array_str.buf + 1, d->p, len); + *d->array_str.buf = '['; + *(d->array_str.buf + len + 1) = ']'; + + d->array = true; + d->p = end + 1; + + return (true); +} + +static bool +read_class(struct demangle_data *d) +{ + size_t len; + char *str; + + if (d == NULL) + return (false); + + len = strtol(d->p, &str, 10); + if (len == 0 && (errno == EINVAL || errno == ERANGE)) + return (false); + + assert(len > 0); + assert(str != NULL); + + if (vector_str_push(&d->vec, str, len) == false) + return (false); + + d->p = str + len; + + d->class_name = true; + + return (true); +} + +static bool +read_func(struct demangle_data *d) +{ + size_t len; + const char *name; + char *delim; + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + if ((delim = strstr(d->p, "__")) == NULL) + return (false); + + len = delim - d->p; + assert(len != 0); + + name = d->p; + + d->p = delim + 2; + + if (*d->p == 'C') { + ++d->p; + + d->cnst_fn = true; + } + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + if (read_qual_name(d) == false) + return (false); + } else if (ELFTC_ISDIGIT(*d->p)) { + if (read_class(d) == false) + return (false); + + if (VEC_PUSH_STR(&d->vec, "::") == false) + return (false); + } + + return (vector_str_push(&d->vec, name, len)); +} + +static bool +read_func_name(struct demangle_data *d) +{ + size_t len; + bool rtn; + char *op_name; + + if (d == NULL) + return (false); + + rtn = false; + op_name = NULL; + + assert(d->p != NULL && "d->p (org str) is NULL"); + + if (*d->p == '_' && *(d->p + 1) == '_') { + d->p += 2; + + /* CTOR */ + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + d->type = ENCODE_OP_CT; + + if (read_qual_name(d) == false) + return (false); + + return (vector_str_pop(&d->vec)); + } else if (ELFTC_ISDIGIT(*d->p)) { + d->type = ENCODE_OP_CT; + + return (read_class(d)); + } + + d->type = ENCODE_OP; + if (read_op(d) == false) { + /* not good condition, start function name with '__' */ + d->type = ENCODE_FUNC; + + if (VEC_PUSH_STR(&d->vec, "__") == false) + return (false); + + return (read_func(d)); + } + + if (d->type == ENCODE_OP_USER || + d->type == ENCODE_OP_TF || + d->type == ENCODE_OP_TI) + return (true); + + /* skip "__" */ + d->p += 2; + + if (*d->p == 'C') { + ++d->p; + + d->cnst_fn = true; + } + + /* assume delimiter is removed */ + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + assert(d->vec.size > 0); + + len = strlen(d->vec.container[d->vec.size - 1]); + if ((op_name = malloc(sizeof(char) * (len + 1))) + == NULL) + return (false); + + snprintf(op_name, len + 1, "%s", + d->vec.container[d->vec.size - 1]); + vector_str_pop(&d->vec); + + if (read_qual_name(d) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::") == false) + goto clean; + + if (vector_str_push(&d->vec, op_name, len) == false) + goto clean; + + rtn = true; + } else if (ELFTC_ISDIGIT(*d->p)) { + assert(d->vec.size > 0); + + len = strlen(d->vec.container[d->vec.size - 1]); + if ((op_name = malloc(sizeof(char) * (len + 1))) + == NULL) + return (false); + + snprintf(op_name, len + 1, "%s", + d->vec.container[d->vec.size - 1]); + vector_str_pop(&d->vec); + + if (read_class(d) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::") == false) + goto clean; + + if (vector_str_push(&d->vec, op_name, len) == false) + goto clean; + + rtn = true; + } + } else if (memcmp(d->p, "_$_", 3) == 0) { + /* DTOR */ + d->p += 3; + d->type = ENCODE_OP_DT; + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + if (read_qual_name(d) == false) + return (false); + + return (vector_str_pop(&d->vec)); + } else if (ELFTC_ISDIGIT(*d->p)) + return (read_class(d)); + + return (false); + } else if (memcmp(d->p, "_vt$", 4) == 0) { + /* vtable */ + d->p += 4; + d->type = ENCODE_OP_VT; + + if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { + ++d->p; + + if (read_qual_name(d) == false) + return (false); + + if (vector_str_pop(&d->vec) == false) + return (false); + } else if (ELFTC_ISDIGIT(*d->p)) { + if (read_class(d) == false) + return (false); + } + + return (VEC_PUSH_STR(&d->vec, " virtual table")); + } else + return (read_func(d)); +clean: + free(op_name); + + return (rtn); +} + +/* Read function ptr type */ +static bool +read_func_ptr(struct demangle_data *d) +{ + struct demangle_data fptr; + size_t arg_len, rtn_len; + char *arg_type, *rtn_type; + int lim; + + if (d == NULL) + return (false); + + if (init_demangle_data(&fptr) == false) + return (false); + + fptr.p = d->p + 1; + lim = 0; + arg_type = NULL; + rtn_type = NULL; + + for (;;) { + if (read_type(&fptr) == false) { + dest_demangle_data(&fptr); + + return (false); + } + + if (fptr.ptr == true) { + if (VEC_PUSH_STR(&fptr.vec, "*") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.ptr = false; + } + + if (fptr.ref == true) { + if (VEC_PUSH_STR(&fptr.vec, "&") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.ref = false; + } + + if (fptr.cnst == true) { + if (VEC_PUSH_STR(&fptr.vec, " const") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + fptr.cnst = false; + } + + if (*fptr.p == '_') + break; + + if (VEC_PUSH_STR(&fptr.vec, ", ") == false) { + dest_demangle_data(&fptr); + + return (false); + } + + if (++lim > CPP_DEMANGLE_GNU2_TRY) { + + dest_demangle_data(&fptr); + + return (false); + } + } + + arg_type = vector_str_get_flat(&fptr.vec, &arg_len); + /* skip '_' */ + d->p = fptr.p + 1; + + dest_demangle_data(&fptr); + + if (init_demangle_data(&fptr) == false) { + free(arg_type); + + return (false); + } + + fptr.p = d->p; + lim = 0; + + if (read_type(&fptr) == false) { + free(arg_type); + dest_demangle_data(&fptr); + + return (false); + } + + rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len); + d->p = fptr.p; + + + dest_demangle_data(&fptr); + + if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) { + free(rtn_type); + free(arg_type); + + return (false); + } + + free(rtn_type); + + if (VEC_PUSH_STR(&d->vec, " (*)(") == false) { + free(arg_type); + + return (false); + } + + if (vector_str_push(&d->vec, arg_type, arg_len) == false) { + free(arg_type); + + return (false); + } + + free(arg_type); + + return (VEC_PUSH_STR(&d->vec, ")")); +} + +static bool +read_memptr(struct demangle_data *d) +{ + struct demangle_data mptr; + size_t len; + bool rtn; + char *mptr_str; + + if (d == NULL || d->p == NULL) + return (false); + + if (init_demangle_data(&mptr) == false) + return (false); + + rtn = false; + mptr_str = NULL; + + mptr.p = d->p; + if (*mptr.p == 'Q') { + ++mptr.p; + + if (read_qual_name(&mptr) == false) + goto clean; + } else if (read_class(&mptr) == false) + goto clean; + + d->p = mptr.p; + + if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL) + goto clean; + + if (vector_str_push(&d->vec, mptr_str, len) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::*") == false) + goto clean; + + rtn = true; +clean: + free(mptr_str); + dest_demangle_data(&mptr); + + return (rtn); +} + +static bool +read_op(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + + switch (SIMPLE_HASH(*(d->p), *(d->p+1))) { + case SIMPLE_HASH('m', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator*")); + case SIMPLE_HASH('d', 'v') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator/")); + case SIMPLE_HASH('m', 'd') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator%")); + case SIMPLE_HASH('p', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator+")); + case SIMPLE_HASH('m', 'i') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator-")); + case SIMPLE_HASH('l', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<<")); + case SIMPLE_HASH('r', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>>")); + case SIMPLE_HASH('e', 'q') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator==")); + case SIMPLE_HASH('n', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator!=")); + case SIMPLE_HASH('l', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<")); + case SIMPLE_HASH('g', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>")); + case SIMPLE_HASH('l', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator<=")); + case SIMPLE_HASH('g', 'e') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator>=")); + case SIMPLE_HASH('a', 'd') : + d->p += 2; + if (*d->p == 'v') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator/=")); + } else + return (VEC_PUSH_STR(&d->vec, "operator&")); + case SIMPLE_HASH('o', 'r') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator|")); + case SIMPLE_HASH('e', 'r') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator^")); + case SIMPLE_HASH('a', 'a') : + d->p += 2; + if (*d->p == 'd') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator&=")); + } else + return (VEC_PUSH_STR(&d->vec, "operator&&")); + case SIMPLE_HASH('o', 'o') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator||")); + case SIMPLE_HASH('n', 't') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator!")); + case SIMPLE_HASH('c', 'o') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator~")); + case SIMPLE_HASH('p', 'p') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator++")); + case SIMPLE_HASH('m', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator--")); + case SIMPLE_HASH('a', 's') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator=")); + case SIMPLE_HASH('r', 'f') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator->")); + case SIMPLE_HASH('a', 'p') : + /* apl */ + if (*(d->p + 2) != 'l') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator+=")); + case SIMPLE_HASH('a', 'm') : + d->p += 2; + if (*d->p == 'i') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator-=")); + } else if (*d->p == 'u') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator*=")); + } else if (*d->p == 'd') { + ++d->p; + return (VEC_PUSH_STR(&d->vec, "operator%=")); + } + + return (false); + case SIMPLE_HASH('a', 'l') : + /* als */ + if (*(d->p + 2) != 's') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator<<=")); + case SIMPLE_HASH('a', 'r') : + /* ars */ + if (*(d->p + 2) != 's') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator>>=")); + case SIMPLE_HASH('a', 'o') : + /* aor */ + if (*(d->p + 2) != 'r') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator|=")); + case SIMPLE_HASH('a', 'e') : + /* aer */ + if (*(d->p + 2) != 'r') + return (false); + + d->p += 3; + return (VEC_PUSH_STR(&d->vec, "operator^=")); + case SIMPLE_HASH('c', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator,")); + case SIMPLE_HASH('r', 'm') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator->*")); + case SIMPLE_HASH('c', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "()")); + case SIMPLE_HASH('v', 'c') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "[]")); + case SIMPLE_HASH('n', 'w') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator new()")); + case SIMPLE_HASH('d', 'l') : + d->p += 2; + return (VEC_PUSH_STR(&d->vec, "operator delete()")); + case SIMPLE_HASH('o', 'p') : + /* __op__ */ + d->p += 2; + + d->type = ENCODE_OP_USER; + + return (read_op_user(d)); + case SIMPLE_HASH('t', 'f') : + d->p += 2; + d->type = ENCODE_OP_TF; + + if (read_type(d) == false) + return (false); + + return (VEC_PUSH_STR(&d->vec, " type_info function")); + case SIMPLE_HASH('t', 'i') : + d->p += 2; + d->type = ENCODE_OP_TI; + + if (read_type(d) == false) + return (false); + + return (VEC_PUSH_STR(&d->vec, " type_info node")); + default : + return (false); + }; +} + +static bool +read_op_user(struct demangle_data *d) +{ + struct demangle_data from, to; + size_t from_len, to_len; + bool rtn; + char *from_str, *to_str; + + if (d == NULL) + return (false); + + if (init_demangle_data(&from) == false) + return (false); + + rtn = false; + from_str = NULL; + to_str = NULL; + if (init_demangle_data(&to) == false) + goto clean; + + to.p = d->p; + if (*to.p == 'Q') { + ++to.p; + + if (read_qual_name(&to) == false) + goto clean; + + /* pop last '::' */ + if (vector_str_pop(&to.vec) == false) + goto clean; + } else { + if (read_class(&to) == false) + goto clean; + + /* skip '__' */ + to.p += 2; + } + + if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL) + goto clean; + + from.p = to.p; + if (*from.p == 'Q') { + ++from.p; + + if (read_qual_name(&from) == false) + goto clean; + + /* pop last '::' */ + if (vector_str_pop(&from.vec) == false) + goto clean; + } else if (read_class(&from) == false) + goto clean; + + if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL) + goto clean; + + if (vector_str_push(&d->vec, from_str, from_len) == false) + goto clean; + + if (VEC_PUSH_STR(&d->vec, "::operator ") == false) + goto clean; + + if (vector_str_push(&d->vec, to_str, to_len) == false) + goto clean; + + rtn = VEC_PUSH_STR(&d->vec, "()"); +clean: + free(to_str); + free(from_str); + dest_demangle_data(&to); + dest_demangle_data(&from); + + return (rtn); +} + +/* single digit + class names */ +static bool +read_qual_name(struct demangle_data *d) +{ + int i; + char num; + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); + + num = *d->p - 48; + + assert(num > 0); + + ++d->p; + for (i = 0; i < num ; ++i) { + if (read_class(d) == false) + return (false); + + if (VEC_PUSH_STR(&d->vec, "::") == false) + return (false); + } + + if (*d->p != '\0') + d->p = d->p + 2; + + return (true); +} + +/* Return -1 at fail, 0 at success, and 1 at end */ +static int +read_subst(struct demangle_data *d) +{ + size_t idx; + char *str; + + if (d == NULL) + return (-1); + + idx = strtol(d->p + 1, &str, 10); + if (idx == 0 && (errno == EINVAL || errno == ERANGE)) + return (-1); + + assert(idx > 0); + assert(str != NULL); + + d->p = str; + + if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) + return (-1); + + if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) + return (-1); + + if (*d->p == '\0') + return (1); + + return (0); +} + +static int +read_subst_iter(struct demangle_data *d) +{ + int i; + size_t idx; + char repeat; + char *str; + + if (d == NULL) + return (-1); + + ++d->p; + assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); + + repeat = *d->p - 48; + + assert(repeat > 1); + + ++d->p; + + idx = strtol(d->p, &str, 10); + if (idx == 0 && (errno == EINVAL || errno == ERANGE)) + return (-1); + + assert(idx > 0); + assert(str != NULL); + + d->p = str; + + for (i = 0; i < repeat ; ++i) { + if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) + return (-1); + + if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) + return (-1); + + if (i != repeat - 1 && + VEC_PUSH_STR(&d->vec, ", ") == false) + return (-1); + } + + if (*d->p == '\0') + return (1); + + return (0); +} + +static bool +read_type(struct demangle_data *d) +{ + + if (d == NULL) + return (false); + + assert(d->p != NULL && "d->p (org str) is NULL"); + + while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' || + *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' || + *d->p == 'M') { + switch (*d->p) { + case 'U' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "unsigned ") == false) + return (false); + + break; + case 'C' : + ++d->p; + + if (*d->p == 'P') + d->cnst = true; + else { + if (VEC_PUSH_STR(&d->vec, "const ") == + false) + return (false); + } + + break; + case 'V' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "volatile ") == false) + return (false); + + break; + case 'S' : + ++d->p; + + if (VEC_PUSH_STR(&d->vec, "signed ") == false) + return (false); + + break; + case 'P' : + ++d->p; + + if (*d->p == 'F') + return (read_func_ptr(d)); + else + d->ptr = true; + + break; + case 'R' : + ++d->p; + + d->ref = true; + + break; + case 'F' : + break; + case 'A' : + ++d->p; + + if (read_array(d) == false) + return (false); + + break; + case 'M' : + ++d->p; + + if (read_memptr(d) == false) + return (false); + + break; + default : + break; + } + } + + if (ELFTC_ISDIGIT(*d->p)) + return (read_class(d)); + + switch (*d->p) { + case 'Q' : + ++d->p; + + return (read_qual_name(d)); + case 'v' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "void")); + case 'b': + ++d->p; + + return(VEC_PUSH_STR(&d->vec, "bool")); + case 'c' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "char")); + case 's' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "short")); + case 'i' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "int")); + case 'l' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "long")); + case 'f' : + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "float")); + case 'd': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "double")); + case 'r': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "long double")); + case 'e': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "...")); + case 'w': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "wchar_t")); + case 'x': + ++d->p; + + return (VEC_PUSH_STR(&d->vec, "long long")); + default: + return (false); + }; + + /* NOTREACHED */ + return (false); +} diff --git a/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c new file mode 100644 index 0000000000..c8c2d2178d --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c @@ -0,0 +1,4004 @@ +/*- + * Copyright (c) 2007 Hyogeol Lee + * Copyright (c) 2015-2017 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3920 2021-02-20 10:50:38Z jkoshy $"); + +/** + * @file cpp_demangle.c + * @brief Decode IA-64 C++ ABI style implementation. + * + * IA-64 standard ABI(Itanium C++ ABI) references. + * + * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n + * http://www.codesourcery.com/cxx-abi/abi-mangling.html + */ + +enum type_qualifier { + TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, + TYPE_CST, TYPE_VEC, TYPE_RREF +}; + +struct vector_type_qualifier { + size_t size, capacity; + enum type_qualifier *q_container; + struct vector_str ext_name; +}; + +enum read_cmd { + READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, + READ_TYPE, READ_FUNC, READ_PTRMEM +}; + +struct read_cmd_item { + enum read_cmd cmd; + void *data; +}; + +struct vector_read_cmd { + size_t size, capacity; + struct read_cmd_item *r_container; +}; + +enum push_qualifier { + PUSH_ALL_QUALIFIER, + PUSH_CV_QUALIFIER, + PUSH_NON_CV_QUALIFIER, +}; + +struct cpp_demangle_data { + struct vector_str output; /* output string vector */ + struct vector_str subst; /* substitution string vector */ + struct vector_str tmpl; + struct vector_str class_type; + struct vector_str *cur_output; /* ptr to current output vec */ + struct vector_read_cmd cmd; + bool mem_rst; /* restrict member function */ + bool mem_vat; /* volatile member function */ + bool mem_cst; /* const member function */ + bool mem_ref; /* lvalue-ref member func */ + bool mem_rref; /* rvalue-ref member func */ + bool is_tmpl; /* template args */ + bool is_functype; /* function type */ + bool ref_qualifier; /* ref qualifier */ + enum type_qualifier ref_qualifier_type; /* ref qualifier type */ + enum push_qualifier push_qualifier; /* which qualifiers to push */ + int func_type; + const char *cur; /* current mangled name ptr */ + const char *last_sname; /* last source name */ +}; + +struct type_delimit { + bool paren; + bool firstp; +}; + +#if !defined(__SIZEOF_LONG_DOUBLE__) +#error __SIZEOF_LONG_DOUBLE__ must be defined, see ticket [#599] +#endif + +#if !defined(__SIZEOF_DOUBLE__) +#error __SIZEOF_DOUBLE__ must be defined, see ticket [#599] +#endif + +#define CPP_DEMANGLE_TRY_LIMIT 128 +#define FLOAT_SPRINTF_TRY_LIMIT 5 +#define FLOAT_QUADRUPLE_BYTES 16 +#define FLOAT_EXTENDED_BYTES 10 + +#define SIMPLE_HASH(x,y) (64 * x + y) +#define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s))) +#define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) + +static void cpp_demangle_data_dest(struct cpp_demangle_data *); +static int cpp_demangle_data_init(struct cpp_demangle_data *, + const char *); +static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); +static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); +static int cpp_demangle_push_fp(struct cpp_demangle_data *, + char *(*)(const char *, size_t)); +static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, + size_t); +static int cpp_demangle_pop_str(struct cpp_demangle_data *); +static int cpp_demangle_push_subst(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_push_subst_v(struct cpp_demangle_data *, + struct vector_str *); +static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, + struct vector_type_qualifier *, const char *); +static int cpp_demangle_read_array(struct cpp_demangle_data *); +static int cpp_demangle_read_encoding(struct cpp_demangle_data *); +static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); +static int cpp_demangle_read_expression(struct cpp_demangle_data *); +static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, + const char *, size_t); +static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, + const char *, size_t, const char *, size_t); +static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, + struct vector_type_qualifier *); +static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); +static int cpp_demangle_read_local_name(struct cpp_demangle_data *); +static int cpp_demangle_read_name(struct cpp_demangle_data *); +static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, + char**); +static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); +static int cpp_demangle_read_number(struct cpp_demangle_data *, long *); +static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); +static int cpp_demangle_read_offset(struct cpp_demangle_data *); +static int cpp_demangle_read_offset_number(struct cpp_demangle_data *); +static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *, + struct vector_type_qualifier *); +static int cpp_demangle_read_sname(struct cpp_demangle_data *); +static int cpp_demangle_read_subst(struct cpp_demangle_data *); +static int cpp_demangle_read_subst_std(struct cpp_demangle_data *); +static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, + const char *); +static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); +static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); +static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); +static int cpp_demangle_read_type(struct cpp_demangle_data *, + struct type_delimit *); +static int cpp_demangle_read_type_flat(struct cpp_demangle_data *, + char **); +static int cpp_demangle_read_uqname(struct cpp_demangle_data *); +static int cpp_demangle_read_v_offset(struct cpp_demangle_data *); +static char *decode_fp_to_double(const char *, size_t); +static char *decode_fp_to_float(const char *, size_t); +static char *decode_fp_to_float128(const char *, size_t); +static char *decode_fp_to_float80(const char *, size_t); +#if __SIZEOF_LONG_DOUBLE__ != __SIZEOF_DOUBLE__ +static char *decode_fp_to_long_double(const char *, size_t); +#endif +static int hex_to_dec(char); +static void vector_read_cmd_dest(struct vector_read_cmd *); +static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *, + enum read_cmd); +static int vector_read_cmd_init(struct vector_read_cmd *); +static int vector_read_cmd_pop(struct vector_read_cmd *); +static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd, + void *); +static void vector_type_qualifier_dest(struct vector_type_qualifier *); +static int vector_type_qualifier_init(struct vector_type_qualifier *); +static int vector_type_qualifier_push(struct vector_type_qualifier *, + enum type_qualifier); + +/** + * @brief Decode the input string by IA-64 C++ ABI style. + * + * GNU GCC v3 use IA-64 standard ABI. + * @return New allocated demangled string or NULL if failed. + * @todo 1. Testing and more test case. 2. Code cleaning. + */ +char * +cpp_demangle_gnu3(const char *org) +{ + struct cpp_demangle_data ddata; + struct vector_str ret_type; + struct type_delimit td; + ssize_t org_len; + unsigned int limit; + char *rtn; + bool has_ret, more_type; + + if (org == NULL || (org_len = strlen(org)) < 2) + return (NULL); + + if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { + if ((rtn = malloc(org_len + 19)) == NULL) + return (NULL); + snprintf(rtn, org_len + 19, + "global constructors keyed to %s", org + 11); + return (rtn); + } + + if (org[0] != '_' || org[1] != 'Z') + return (NULL); + + if (!cpp_demangle_data_init(&ddata, org + 2)) + return (NULL); + + rtn = NULL; + has_ret = more_type = false; + + if (!cpp_demangle_read_encoding(&ddata)) + goto clean; + + /* + * Pop function name from substitution candidate list. + */ + if (*ddata.cur != 0 && ddata.subst.size >= 1) { + if (!vector_str_pop(&ddata.subst)) + goto clean; + } + + td.paren = false; + td.firstp = true; + limit = 0; + + /* + * The first type is a return type if we just demangled template + * args. (the template args is right next to the function name, + * which means it's a template function) + */ + if (ddata.is_tmpl) { + ddata.is_tmpl = false; + if (!vector_str_init(&ret_type)) + goto clean; + ddata.cur_output = &ret_type; + has_ret = true; + } + + while (*ddata.cur != '\0') { + /* + * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 + */ + if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') + break; + + if (has_ret) { + /* Read return type */ + if (!cpp_demangle_read_type(&ddata, NULL)) + goto clean; + } else { + /* Read function arg type */ + if (!cpp_demangle_read_type(&ddata, &td)) + goto clean; + } + + if (has_ret) { + /* Push return type to the beginning */ + if (!VEC_PUSH_STR(&ret_type, " ")) + goto clean; + if (!vector_str_push_vector_head(&ddata.output, + &ret_type)) + goto clean; + ddata.cur_output = &ddata.output; + vector_str_dest(&ret_type); + has_ret = false; + more_type = true; + } else if (more_type) + more_type = false; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + goto clean; + } + if (more_type) + goto clean; + + if (ddata.output.size == 0) + goto clean; + if (td.paren && !VEC_PUSH_STR(&ddata.output, ")")) + goto clean; + if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile")) + goto clean; + if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const")) + goto clean; + if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict")) + goto clean; + if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &")) + goto clean; + if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&")) + goto clean; + + rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); + +clean: + if (has_ret) + vector_str_dest(&ret_type); + + cpp_demangle_data_dest(&ddata); + + return (rtn); +} + +static void +cpp_demangle_data_dest(struct cpp_demangle_data *d) +{ + + if (d == NULL) + return; + + vector_read_cmd_dest(&d->cmd); + vector_str_dest(&d->class_type); + vector_str_dest(&d->tmpl); + vector_str_dest(&d->subst); + vector_str_dest(&d->output); +} + +static int +cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) +{ + + if (d == NULL || cur == NULL) + return (0); + + if (!vector_str_init(&d->output)) + return (0); + if (!vector_str_init(&d->subst)) + goto clean1; + if (!vector_str_init(&d->tmpl)) + goto clean2; + if (!vector_str_init(&d->class_type)) + goto clean3; + if (!vector_read_cmd_init(&d->cmd)) + goto clean4; + + assert(d->output.container != NULL); + assert(d->subst.container != NULL); + assert(d->tmpl.container != NULL); + assert(d->class_type.container != NULL); + + d->mem_rst = false; + d->mem_vat = false; + d->mem_cst = false; + d->mem_ref = false; + d->mem_rref = false; + d->is_tmpl = false; + d->is_functype = false; + d->ref_qualifier = false; + d->push_qualifier = PUSH_ALL_QUALIFIER; + d->func_type = 0; + d->cur = cur; + d->cur_output = &d->output; + d->last_sname = NULL; + + return (1); + +clean4: + vector_str_dest(&d->class_type); +clean3: + vector_str_dest(&d->tmpl); +clean2: + vector_str_dest(&d->subst); +clean1: + vector_str_dest(&d->output); + + return (0); +} + +static int +cpp_demangle_push_fp(struct cpp_demangle_data *ddata, + char *(*decoder)(const char *, size_t)) +{ + size_t len; + int rtn; + const char *fp; + char *f; + + if (ddata == NULL || decoder == NULL) + return (0); + + fp = ddata->cur; + while (*ddata->cur != 'E') + ++ddata->cur; + + if ((f = decoder(fp, ddata->cur - fp)) == NULL) + return (0); + + rtn = 0; + if ((len = strlen(f)) > 0) + rtn = cpp_demangle_push_str(ddata, f, len); + + free(f); + + ++ddata->cur; + + return (rtn); +} + +static int +cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, + size_t len) +{ + + if (ddata == NULL || str == NULL || len == 0) + return (0); + + /* + * is_tmpl is used to check if the type (function arg) is right next + * to template args, and should always be cleared whenever new string + * pushed. + */ + ddata->is_tmpl = false; + + return (vector_str_push(ddata->cur_output, str, len)); +} + +static int +cpp_demangle_pop_str(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + return (vector_str_pop(ddata->cur_output)); +} + +static int +cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, + size_t len) +{ + + if (ddata == NULL || str == NULL || len == 0) + return (0); + + if (!vector_str_find(&ddata->subst, str, len)) + return (vector_str_push(&ddata->subst, str, len)); + + return (1); +} + +static int +cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) +{ + size_t str_len; + int rtn; + char *str; + + if (ddata == NULL || v == NULL) + return (0); + + if ((str = vector_str_get_flat(v, &str_len)) == NULL) + return (0); + + rtn = cpp_demangle_push_subst(ddata, str, str_len); + + free(str); + + return (rtn); +} + +static int +cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, + struct vector_type_qualifier *v, const char *type_str) +{ + struct vector_str subst_v; + enum type_qualifier t; + size_t idx, e_idx, e_len; + char *buf; + int rtn; + bool cv; + + if (ddata == NULL || v == NULL) + return (0); + + if ((idx = v->size) == 0) + return (1); + + rtn = 0; + if (type_str != NULL) { + if (!vector_str_init(&subst_v)) + return (0); + if (!VEC_PUSH_STR(&subst_v, type_str)) + goto clean; + } + + cv = true; + e_idx = 0; + while (idx > 0) { + switch (v->q_container[idx - 1]) { + case TYPE_PTR: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (!DEM_PUSH_STR(ddata, "*")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, "*")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_REF: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (!DEM_PUSH_STR(ddata, "&")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, "&")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_RREF: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (!DEM_PUSH_STR(ddata, "&&")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, "&&")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_CMX: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (!DEM_PUSH_STR(ddata, " complex")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, " complex")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_IMG: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (!DEM_PUSH_STR(ddata, " imaginary")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, " imaginary")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_EXT: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (v->ext_name.size == 0 || + e_idx > v->ext_name.size - 1) + goto clean; + if ((e_len = strlen(v->ext_name.container[e_idx])) == + 0) + goto clean; + if ((buf = malloc(e_len + 2)) == NULL) + goto clean; + snprintf(buf, e_len + 2, " %s", + v->ext_name.container[e_idx]); + + if (!DEM_PUSH_STR(ddata, buf)) { + free(buf); + goto clean; + } + + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, buf)) { + free(buf); + goto clean; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) { + free(buf); + goto clean; + } + } + free(buf); + ++e_idx; + break; + + case TYPE_RST: + if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && + cv) + break; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) + break; + if (!DEM_PUSH_STR(ddata, " restrict")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, " restrict")) + goto clean; + if (idx - 1 > 0) { + t = v->q_container[idx - 2]; + if (t == TYPE_RST || t == TYPE_VAT || + t == TYPE_CST) + break; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_VAT: + if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && + cv) + break; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) + break; + if (!DEM_PUSH_STR(ddata, " volatile")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, " volatile")) + goto clean; + if (idx - 1 > 0) { + t = v->q_container[idx - 2]; + if (t == TYPE_RST || t == TYPE_VAT || + t == TYPE_CST) + break; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_CST: + if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && + cv) + break; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) + break; + if (!DEM_PUSH_STR(ddata, " const")) + goto clean; + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, " const")) + goto clean; + if (idx - 1 > 0) { + t = v->q_container[idx - 2]; + if (t == TYPE_RST || t == TYPE_VAT || + t == TYPE_CST) + break; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + break; + + case TYPE_VEC: + cv = false; + if (ddata->push_qualifier == PUSH_CV_QUALIFIER) + break; + if (v->ext_name.size == 0 || + e_idx > v->ext_name.size - 1) + goto clean; + if ((e_len = strlen(v->ext_name.container[e_idx])) == + 0) + goto clean; + if ((buf = malloc(e_len + 12)) == NULL) + goto clean; + snprintf(buf, e_len + 12, " __vector(%s)", + v->ext_name.container[e_idx]); + if (!DEM_PUSH_STR(ddata, buf)) { + free(buf); + goto clean; + } + if (type_str != NULL) { + if (!VEC_PUSH_STR(&subst_v, buf)) { + free(buf); + goto clean; + } + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) { + free(buf); + goto clean; + } + } + free(buf); + ++e_idx; + break; + } + --idx; + } + + rtn = 1; +clean: + if (type_str != NULL) + vector_str_dest(&subst_v); + + return (rtn); +} + +static int +cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) +{ + size_t len; + + if (ddata == NULL || ddata->subst.size <= idx) + return (0); + if ((len = strlen(ddata->subst.container[idx])) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) + return (0); + + /* skip '_' */ + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) +{ + size_t len; + + if (ddata == NULL || ddata->tmpl.size <= idx) + return (0); + if ((len = strlen(ddata->tmpl.container[idx])) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) + return (0); + + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_read_array(struct cpp_demangle_data *ddata) +{ + size_t i, num_len, exp_len, p_idx, idx; + const char *num; + char *exp; + + if (ddata == NULL || *(++ddata->cur) == '\0') + return (0); + + if (*ddata->cur == '_') { + if (*(++ddata->cur) == '\0') + return (0); + + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + + if (!DEM_PUSH_STR(ddata, " []")) + return (0); + } else { + if (ELFTC_ISDIGIT(*ddata->cur) != 0) { + num = ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + if (*ddata->cur != '_') + return (0); + num_len = ddata->cur - num; + assert(num_len > 0); + if (*(++ddata->cur) == '\0') + return (0); + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + if (!DEM_PUSH_STR(ddata, " [")) + return (0); + if (!cpp_demangle_push_str(ddata, num, num_len)) + return (0); + if (!DEM_PUSH_STR(ddata, "]")) + return (0); + } else { + p_idx = ddata->output.size; + if (!cpp_demangle_read_expression(ddata)) + return (0); + if ((exp = vector_str_substr(&ddata->output, p_idx, + ddata->output.size - 1, &exp_len)) == NULL) + return (0); + idx = ddata->output.size; + for (i = p_idx; i < idx; ++i) + if (!vector_str_pop(&ddata->output)) { + free(exp); + return (0); + } + if (*ddata->cur != '_') { + free(exp); + return (0); + } + ++ddata->cur; + if (*ddata->cur == '\0') { + free(exp); + return (0); + } + if (!cpp_demangle_read_type(ddata, NULL)) { + free(exp); + return (0); + } + if (!DEM_PUSH_STR(ddata, " [")) { + free(exp); + return (0); + } + if (!cpp_demangle_push_str(ddata, exp, exp_len)) { + free(exp); + return (0); + } + if (!DEM_PUSH_STR(ddata, "]")) { + free(exp); + return (0); + } + free(exp); + } + } + + return (1); +} + +static int +cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) +{ + const char *num; + + if (ddata == NULL || *(++ddata->cur) == '\0') + return (0); + + if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_encoding(ddata)) + return (0); + ++ddata->cur; + return (1); + } + + switch (*ddata->cur) { + case 'b': + if (*(ddata->cur + 2) != 'E') + return (0); + switch (*(++ddata->cur)) { + case '0': + ddata->cur += 2; + return (DEM_PUSH_STR(ddata, "false")); + case '1': + ddata->cur += 2; + return (DEM_PUSH_STR(ddata, "true")); + default: + return (0); + } + + case 'd': + ++ddata->cur; + return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); + + case 'e': + ++ddata->cur; + if (sizeof(long double) == 10) + return (cpp_demangle_push_fp(ddata, + decode_fp_to_double)); + return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); + + case 'f': + ++ddata->cur; + return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); + + case 'g': + ++ddata->cur; + if (sizeof(long double) == 16) + return (cpp_demangle_push_fp(ddata, + decode_fp_to_double)); + return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); + + case 'i': + case 'j': + case 'l': + case 'm': + case 'n': + case 's': + case 't': + case 'x': + case 'y': + if (*(++ddata->cur) == 'n') { + if (!DEM_PUSH_STR(ddata, "-")) + return (0); + ++ddata->cur; + } + num = ddata->cur; + while (*ddata->cur != 'E') { + if (!ELFTC_ISDIGIT(*ddata->cur)) + return (0); + ++ddata->cur; + } + ++ddata->cur; + return (cpp_demangle_push_str(ddata, num, + ddata->cur - num - 1)); + + default: + return (0); + } +} + +static int +cpp_demangle_read_expression(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('s', 't'): + ddata->cur += 2; + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('s', 'r'): + ddata->cur += 2; + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + if (!cpp_demangle_read_uqname(ddata)) + return (0); + if (*ddata->cur == 'I') + return (cpp_demangle_read_tmpl_args(ddata)); + return (1); + + case SIMPLE_HASH('a', 'a'): + /* operator && */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); + + case SIMPLE_HASH('a', 'd'): + /* operator & (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "&", 1)); + + case SIMPLE_HASH('a', 'n'): + /* operator & */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&", 1)); + + case SIMPLE_HASH('a', 'N'): + /* operator &= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); + + case SIMPLE_HASH('a', 'S'): + /* operator = */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "=", 1)); + + case SIMPLE_HASH('c', 'l'): + /* operator () */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "()", 2)); + + case SIMPLE_HASH('c', 'm'): + /* operator , */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ",", 1)); + + case SIMPLE_HASH('c', 'o'): + /* operator ~ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "~", 1)); + + case SIMPLE_HASH('c', 'v'): + /* operator (cast) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); + + case SIMPLE_HASH('d', 'a'): + /* operator delete [] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); + + case SIMPLE_HASH('d', 'e'): + /* operator * (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "*", 1)); + + case SIMPLE_HASH('d', 'l'): + /* operator delete */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); + + case SIMPLE_HASH('d', 'v'): + /* operator / */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "/", 1)); + + case SIMPLE_HASH('d', 'V'): + /* operator /= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); + + case SIMPLE_HASH('e', 'o'): + /* operator ^ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "^", 1)); + + case SIMPLE_HASH('e', 'O'): + /* operator ^= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); + + case SIMPLE_HASH('e', 'q'): + /* operator == */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "==", 2)); + + case SIMPLE_HASH('g', 'e'): + /* operator >= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); + + case SIMPLE_HASH('g', 't'): + /* operator > */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">", 1)); + + case SIMPLE_HASH('i', 'x'): + /* operator [] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); + + case SIMPLE_HASH('l', 'e'): + /* operator <= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); + + case SIMPLE_HASH('l', 's'): + /* operator << */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); + + case SIMPLE_HASH('l', 'S'): + /* operator <<= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); + + case SIMPLE_HASH('l', 't'): + /* operator < */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "<", 1)); + + case SIMPLE_HASH('m', 'i'): + /* operator - */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "-", 1)); + + case SIMPLE_HASH('m', 'I'): + /* operator -= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); + + case SIMPLE_HASH('m', 'l'): + /* operator * */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "*", 1)); + + case SIMPLE_HASH('m', 'L'): + /* operator *= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); + + case SIMPLE_HASH('m', 'm'): + /* operator -- */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "--", 2)); + + case SIMPLE_HASH('n', 'a'): + /* operator new[] */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); + + case SIMPLE_HASH('n', 'e'): + /* operator != */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); + + case SIMPLE_HASH('n', 'g'): + /* operator - (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "-", 1)); + + case SIMPLE_HASH('n', 't'): + /* operator ! */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "!", 1)); + + case SIMPLE_HASH('n', 'w'): + /* operator new */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "new", 3)); + + case SIMPLE_HASH('o', 'o'): + /* operator || */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "||", 2)); + + case SIMPLE_HASH('o', 'r'): + /* operator | */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "|", 1)); + + case SIMPLE_HASH('o', 'R'): + /* operator |= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); + + case SIMPLE_HASH('p', 'l'): + /* operator + */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "+", 1)); + + case SIMPLE_HASH('p', 'L'): + /* operator += */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); + + case SIMPLE_HASH('p', 'm'): + /* operator ->* */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); + + case SIMPLE_HASH('p', 'p'): + /* operator ++ */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "++", 2)); + + case SIMPLE_HASH('p', 's'): + /* operator + (unary) */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "+", 1)); + + case SIMPLE_HASH('p', 't'): + /* operator -> */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "->", 2)); + + case SIMPLE_HASH('q', 'u'): + /* operator ? */ + ddata->cur += 2; + return (cpp_demangle_read_expression_trinary(ddata, "?", 1, + ":", 1)); + + case SIMPLE_HASH('r', 'm'): + /* operator % */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "%", 1)); + + case SIMPLE_HASH('r', 'M'): + /* operator %= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); + + case SIMPLE_HASH('r', 's'): + /* operator >> */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); + + case SIMPLE_HASH('r', 'S'): + /* operator >>= */ + ddata->cur += 2; + return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); + + case SIMPLE_HASH('r', 'z'): + /* operator sizeof */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); + + case SIMPLE_HASH('s', 'v'): + /* operator sizeof */ + ddata->cur += 2; + return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); + } + + switch (*ddata->cur) { + case 'L': + return (cpp_demangle_read_expr_primary(ddata)); + case 'T': + return (cpp_demangle_read_tmpl_param(ddata)); + } + + return (0); +} + +static int +cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, exp_len; + char *exp; + + output = &ddata->output; + + p_idx = output->size; + + if (!cpp_demangle_read_expression(ddata)) + return (0); + + if ((exp = vector_str_substr(output, p_idx, output->size - 1, + &exp_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(exp); + return (0); + } + } + + *str = exp; + + return (1); +} + +static int +cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, + const char *name, size_t len) +{ + + if (ddata == NULL || name == NULL || len == 0) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name, len)) + return (0); + + return (cpp_demangle_read_expression(ddata)); +} + +static int +cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, + const char *name, size_t len) +{ + + if (ddata == NULL || name == NULL || len == 0) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + + return (cpp_demangle_push_str(ddata, name, len)); +} + +static int +cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, + const char *name1, size_t len1, const char *name2, size_t len2) +{ + + if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || + len2 == 0) + return (0); + + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name1, len1)) + return (0); + if (!cpp_demangle_read_expression(ddata)) + return (0); + if (!cpp_demangle_push_str(ddata, name2, len2)) + return (0); + + return (cpp_demangle_read_expression(ddata)); +} + +static int +cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, + struct vector_type_qualifier *v) +{ + struct type_delimit td; + struct read_cmd_item *rc; + size_t class_type_size, class_type_len, limit; + const char *class_type; + int i; + bool paren, non_cv_qualifier; + + if (ddata == NULL || *ddata->cur != 'F' || v == NULL) + return (0); + + ++ddata->cur; + if (*ddata->cur == 'Y') { + if (ext_c != NULL) + *ext_c = 1; + ++ddata->cur; + } + + /* Return type */ + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + + if (*ddata->cur != 'E') { + if (!DEM_PUSH_STR(ddata, " ")) + return (0); + + non_cv_qualifier = false; + if (v->size > 0) { + for (i = 0; (size_t) i < v->size; i++) { + if (v->q_container[i] != TYPE_RST && + v->q_container[i] != TYPE_VAT && + v->q_container[i] != TYPE_CST) { + non_cv_qualifier = true; + break; + } + } + } + + paren = false; + rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM); + if (non_cv_qualifier || rc != NULL) { + if (!DEM_PUSH_STR(ddata, "(")) + return (0); + paren = true; + } + + /* Push non-cv qualifiers. */ + ddata->push_qualifier = PUSH_NON_CV_QUALIFIER; + if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) + return (0); + + if (rc) { + if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " ")) + return (0); + if ((class_type_size = ddata->class_type.size) == 0) + return (0); + class_type = + ddata->class_type.container[class_type_size - 1]; + if (class_type == NULL) + return (0); + if ((class_type_len = strlen(class_type)) == 0) + return (0); + if (!cpp_demangle_push_str(ddata, class_type, + class_type_len)) + return (0); + if (!DEM_PUSH_STR(ddata, "::*")) + return (0); + /* Push pointer-to-member qualifiers. */ + ddata->push_qualifier = PUSH_ALL_QUALIFIER; + if (!cpp_demangle_push_type_qualifier(ddata, rc->data, + NULL)) + return (0); + ++ddata->func_type; + } + + if (paren) { + if (!DEM_PUSH_STR(ddata, ")")) + return (0); + paren = false; + } + + td.paren = false; + td.firstp = true; + limit = 0; + ddata->is_functype = true; + for (;;) { + if (!cpp_demangle_read_type(ddata, &td)) + return (0); + if (*ddata->cur == 'E') + break; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + ddata->is_functype = false; + if (td.paren) { + if (!DEM_PUSH_STR(ddata, ")")) + return (0); + td.paren = false; + } + + /* Push CV qualifiers. */ + ddata->push_qualifier = PUSH_CV_QUALIFIER; + if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) + return (0); + + ddata->push_qualifier = PUSH_ALL_QUALIFIER; + + /* Release type qualifier vector. */ + vector_type_qualifier_dest(v); + if (!vector_type_qualifier_init(v)) + return (0); + + /* Push ref-qualifiers. */ + if (ddata->ref_qualifier) { + switch (ddata->ref_qualifier_type) { + case TYPE_REF: + if (!DEM_PUSH_STR(ddata, " &")) + return (0); + break; + case TYPE_RREF: + if (!DEM_PUSH_STR(ddata, " &&")) + return (0); + break; + default: + return (0); + } + ddata->ref_qualifier = false; + } + } + + ++ddata->cur; + + return (1); +} + +/* read encoding, encoding are function name, data name, special-name */ +static int +cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) +{ + char *name, *type, *num_str; + long offset; + int rtn; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* special name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('G', 'A'): + if (!DEM_PUSH_STR(ddata, "hidden alias for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('G', 'R'): + if (!DEM_PUSH_STR(ddata, "reference temporary #")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_name_flat(ddata, &name)) + return (0); + rtn = 0; + if (!cpp_demangle_read_number_as_string(ddata, &num_str)) + goto clean1; + if (!DEM_PUSH_STR(ddata, num_str)) + goto clean2; + if (!DEM_PUSH_STR(ddata, " for ")) + goto clean2; + if (!DEM_PUSH_STR(ddata, name)) + goto clean2; + rtn = 1; + clean2: + free(num_str); + clean1: + free(name); + return (rtn); + + case SIMPLE_HASH('G', 'T'): + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + switch (*ddata->cur) { + case 'n': + if (!DEM_PUSH_STR(ddata, "non-transaction clone for ")) + return (0); + break; + case 't': + default: + if (!DEM_PUSH_STR(ddata, "transaction clone for ")) + return (0); + break; + } + ++ddata->cur; + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('G', 'V'): + /* sentry object for 1 time init */ + if (!DEM_PUSH_STR(ddata, "guard variable for ")) + return (0); + ddata->cur += 2; + break; + + case SIMPLE_HASH('T', 'c'): + /* virtual function covariant override thunk */ + if (!DEM_PUSH_STR(ddata, + "virtual function covariant override ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_offset(ddata)) + return (0); + if (!cpp_demangle_read_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'C'): + /* construction vtable */ + if (!DEM_PUSH_STR(ddata, "construction vtable for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_type_flat(ddata, &type)) + return (0); + rtn = 0; + if (!cpp_demangle_read_number(ddata, &offset)) + goto clean3; + if (*ddata->cur++ != '_') + goto clean3; + if (!cpp_demangle_read_type(ddata, NULL)) + goto clean3; + if (!DEM_PUSH_STR(ddata, "-in-")) + goto clean3; + if (!DEM_PUSH_STR(ddata, type)) + goto clean3; + rtn = 1; + clean3: + free(type); + return (rtn); + + case SIMPLE_HASH('T', 'D'): + /* typeinfo common proxy */ + break; + + case SIMPLE_HASH('T', 'F'): + /* typeinfo fn */ + if (!DEM_PUSH_STR(ddata, "typeinfo fn for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'h'): + /* virtual function non-virtual override thunk */ + if (!DEM_PUSH_STR(ddata, + "virtual function non-virtual override ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_nv_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'H'): + /* TLS init function */ + if (!DEM_PUSH_STR(ddata, "TLS init function for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + break; + + case SIMPLE_HASH('T', 'I'): + /* typeinfo structure */ + if (!DEM_PUSH_STR(ddata, "typeinfo for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'J'): + /* java class */ + if (!DEM_PUSH_STR(ddata, "java Class for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'S'): + /* RTTI name (NTBS) */ + if (!DEM_PUSH_STR(ddata, "typeinfo name for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'T'): + /* VTT table */ + if (!DEM_PUSH_STR(ddata, "VTT for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'v'): + /* virtual function virtual override thunk */ + if (!DEM_PUSH_STR(ddata, "virtual function virtual override ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + if (!cpp_demangle_read_v_offset(ddata)) + return (0); + return (cpp_demangle_read_encoding(ddata)); + + case SIMPLE_HASH('T', 'V'): + /* virtual table */ + if (!DEM_PUSH_STR(ddata, "vtable for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('T', 'W'): + /* TLS wrapper function */ + if (!DEM_PUSH_STR(ddata, "TLS wrapper function for ")) + return (0); + ddata->cur += 2; + if (*ddata->cur == '\0') + return (0); + break; + } + + return (cpp_demangle_read_name(ddata)); +} + +static int +cpp_demangle_read_local_name(struct cpp_demangle_data *ddata) +{ + struct vector_str local_name; + struct type_delimit td; + size_t limit; + bool more_type; + + if (ddata == NULL) + return (0); + if (*(++ddata->cur) == '\0') + return (0); + + if (!vector_str_init(&local_name)) + return (0); + ddata->cur_output = &local_name; + + if (!cpp_demangle_read_encoding(ddata)) { + vector_str_dest(&local_name); + return (0); + } + + ddata->cur_output = &ddata->output; + + td.paren = false; + td.firstp = true; + more_type = false; + limit = 0; + + /* + * The first type is a return type if we just demangled template + * args. (the template args is right next to the function name, + * which means it's a template function) + */ + if (ddata->is_tmpl) { + ddata->is_tmpl = false; + + /* Read return type */ + if (!cpp_demangle_read_type(ddata, NULL)) { + vector_str_dest(&local_name); + return (0); + } + + more_type = true; + } + + /* Now we can push the name after possible return type is handled. */ + if (!vector_str_push_vector(&ddata->output, &local_name)) { + vector_str_dest(&local_name); + return (0); + } + vector_str_dest(&local_name); + + while (*ddata->cur != '\0') { + if (!cpp_demangle_read_type(ddata, &td)) + return (0); + if (more_type) + more_type = false; + if (*ddata->cur == 'E') + break; + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + if (more_type) + return (0); + + if (*(++ddata->cur) == '\0') + return (0); + if (td.paren == true) { + if (!DEM_PUSH_STR(ddata, ")")) + return (0); + td.paren = false; + } + if (*ddata->cur == 's') + ++ddata->cur; + else { + if (!DEM_PUSH_STR(ddata, "::")) + return (0); + if (!cpp_demangle_read_name(ddata)) + return (0); + } + if (*ddata->cur == '_') { + ++ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + } + + return (1); +} + +static int +cpp_demangle_read_name(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + output = ddata->cur_output; + + subst_str = NULL; + + switch (*ddata->cur) { + case 'S': + return (cpp_demangle_read_subst(ddata)); + case 'N': + return (cpp_demangle_read_nested_name(ddata)); + case 'Z': + return (cpp_demangle_read_local_name(ddata)); + } + + if (!vector_str_init(&v)) + return (0); + + p_idx = output->size; + rtn = 0; + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, + &subst_str_len)) == NULL) + goto clean; + if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { + rtn = 1; + goto clean; + } + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + + if (*ddata->cur == 'I') { + p_idx = output->size; + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + free(subst_str); + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + } + + rtn = 1; + +clean: + free(subst_str); + vector_str_dest(&v); + + return (rtn); +} + +static int +cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, name_len; + char *name; + + output = ddata->cur_output; + + p_idx = output->size; + + if (!cpp_demangle_read_name(ddata)) + return (0); + + if ((name = vector_str_substr(output, p_idx, output->size - 1, + &name_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(name); + return (0); + } + } + + *str = name; + + return (1); +} + +static int +cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t limit, p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL || *ddata->cur != 'N') + return (0); + if (*(++ddata->cur) == '\0') + return (0); + + do { + switch (*ddata->cur) { + case 'r': + ddata->mem_rst = true; + break; + case 'V': + ddata->mem_vat = true; + break; + case 'K': + ddata->mem_cst = true; + break; + case 'R': + ddata->mem_ref = true; + break; + case 'O': + ddata->mem_rref = true; + break; + default: + goto next; + } + } while (*(++ddata->cur)); + +next: + output = ddata->cur_output; + if (!vector_str_init(&v)) + return (0); + + rtn = 0; + limit = 0; + for (;;) { + p_idx = output->size; + switch (*ddata->cur) { + case 'I': + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + break; + case 'S': + if (!cpp_demangle_read_subst(ddata)) + goto clean; + break; + case 'T': + if (!cpp_demangle_read_tmpl_param(ddata)) + goto clean; + break; + default: + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + } + + if (p_idx == output->size) + goto next_comp; + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) { + free(subst_str); + goto clean; + } + free(subst_str); + + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + + next_comp: + if (*ddata->cur == 'E') + break; + else if (*ddata->cur != 'I' && *ddata->cur != 'C' && + *ddata->cur != 'D' && p_idx != output->size) { + if (!DEM_PUSH_STR(ddata, "::")) + goto clean; + if (!VEC_PUSH_STR(&v, "::")) + goto clean; + } + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + goto clean; + } + + ++ddata->cur; + rtn = 1; + +clean: + vector_str_dest(&v); + + return (rtn); +} + +/* + * read number + * number ::= [n] + */ +static int +cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) +{ + long len, negative_factor; + + if (ddata == NULL || rtn == NULL) + return (0); + + negative_factor = 1; + if (*ddata->cur == 'n') { + negative_factor = -1; + + ++ddata->cur; + } + if (ELFTC_ISDIGIT(*ddata->cur) == 0) + return (0); + + errno = 0; + if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && + errno != 0) + return (0); + + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + + assert(len >= 0); + assert(negative_factor == 1 || negative_factor == -1); + + *rtn = len * negative_factor; + + return (1); +} + +static int +cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) +{ + long n; + + if (!cpp_demangle_read_number(ddata, &n)) { + *str = NULL; + return (0); + } + + if (asprintf(str, "%ld", n) < 0) { + *str = NULL; + return (0); + } + + return (1); +} + +static int +cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (!DEM_PUSH_STR(ddata, "offset : ")) + return (0); + + return (cpp_demangle_read_offset_number(ddata)); +} + +/* read offset, offset are nv-offset, v-offset */ +static int +cpp_demangle_read_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (*ddata->cur == 'h') { + ++ddata->cur; + return (cpp_demangle_read_nv_offset(ddata)); + } else if (*ddata->cur == 'v') { + ++ddata->cur; + return (cpp_demangle_read_v_offset(ddata)); + } + + return (0); +} + +static int +cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) +{ + bool negative; + const char *start; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* offset could be negative */ + if (*ddata->cur == 'n') { + negative = true; + start = ddata->cur + 1; + } else { + negative = false; + start = ddata->cur; + } + + while (*ddata->cur != '_') + ++ddata->cur; + + if (negative && !DEM_PUSH_STR(ddata, "-")) + return (0); + + assert(start != NULL); + + if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) + return (0); + if (!DEM_PUSH_STR(ddata, " ")) + return (0); + + ++ddata->cur; + + return (1); +} + +static int +cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata, + struct vector_type_qualifier *v) +{ + size_t class_type_len, i, idx, p_idx; + int p_func_type, rtn; + char *class_type; + + if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') + return (0); + + p_idx = ddata->output.size; + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + + if ((class_type = vector_str_substr(&ddata->output, p_idx, + ddata->output.size - 1, &class_type_len)) == NULL) + return (0); + + rtn = 0; + idx = ddata->output.size; + for (i = p_idx; i < idx; ++i) + if (!vector_str_pop(&ddata->output)) + goto clean1; + + if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v)) + goto clean1; + + if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) + goto clean2; + + p_func_type = ddata->func_type; + if (!cpp_demangle_read_type(ddata, NULL)) + goto clean3; + + if (p_func_type == ddata->func_type) { + if (!DEM_PUSH_STR(ddata, " ")) + goto clean3; + if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) + goto clean3; + if (!DEM_PUSH_STR(ddata, "::*")) + goto clean3; + } + + rtn = 1; +clean3: + if (!vector_str_pop(&ddata->class_type)) + rtn = 0; +clean2: + if (!vector_read_cmd_pop(&ddata->cmd)) + rtn = 0; +clean1: + free(class_type); + + vector_type_qualifier_dest(v); + if (!vector_type_qualifier_init(v)) + return (0); + + return (rtn); +} + +/* read source-name, source-name is */ +static int +cpp_demangle_read_sname(struct cpp_demangle_data *ddata) +{ + long len; + int err; + + if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || + len <= 0) + return (0); + + if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) + err = DEM_PUSH_STR(ddata, "(anonymous namespace)"); + else + err = cpp_demangle_push_str(ddata, ddata->cur, len); + + if (err == 0) + return (0); + + assert(ddata->cur_output->size > 0); + if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL) + ddata->last_sname = + ddata->cur_output->container[ddata->output.size - 1]; + + ddata->cur += len; + + return (1); +} + +static int +cpp_demangle_read_subst(struct cpp_demangle_data *ddata) +{ + long nth; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* abbreviations of the form Sx */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('S', 'a'): + /* std::allocator */ + if (!DEM_PUSH_STR(ddata, "std::allocator")) + return (0); + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::allocator")); + return (1); + + case SIMPLE_HASH('S', 'b'): + /* std::basic_string */ + if (!DEM_PUSH_STR(ddata, "std::basic_string")) + return (0); + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_string")); + return (1); + + case SIMPLE_HASH('S', 'd'): + /* std::basic_iostream > */ + if (!DEM_PUSH_STR(ddata, "std::basic_iostream >")) + return (0); + ddata->last_sname = "basic_iostream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_iostream >")); + return (1); + + case SIMPLE_HASH('S', 'i'): + /* std::basic_istream > */ + if (!DEM_PUSH_STR(ddata, "std::basic_istream >")) + return (0); + ddata->last_sname = "basic_istream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_istream >")); + return (1); + + case SIMPLE_HASH('S', 'o'): + /* std::basic_ostream > */ + if (!DEM_PUSH_STR(ddata, "std::basic_ostream >")) + return (0); + ddata->last_sname = "basic_ostream"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_ostream >")); + return (1); + + case SIMPLE_HASH('S', 's'): + /* + * std::basic_string, + * std::allocator > + * + * a.k.a std::string + */ + if (!DEM_PUSH_STR(ddata, "std::basic_string, std::allocator >")) + return (0); + ddata->last_sname = "string"; + ddata->cur += 2; + if (*ddata->cur == 'I') + return (cpp_demangle_read_subst_stdtmpl(ddata, + "std::basic_string," + " std::allocator >")); + return (1); + + case SIMPLE_HASH('S', 't'): + /* std:: */ + return (cpp_demangle_read_subst_std(ddata)); + } + + if (*(++ddata->cur) == '\0') + return (0); + + /* Skip unknown substitution abbreviations. */ + if (!(*ddata->cur >= '0' && *ddata->cur <= '9') && + !(*ddata->cur >= 'A' && *ddata->cur <= 'Z') && + *ddata->cur != '_') { + ++ddata->cur; + return (1); + } + + /* substitution */ + if (*ddata->cur == '_') + return (cpp_demangle_get_subst(ddata, 0)); + else { + errno = 0; + /* substitution number is base 36 */ + if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && + errno != 0) + return (0); + + /* first was '_', so increase one */ + ++nth; + + while (*ddata->cur != '_') + ++ddata->cur; + + assert(nth > 0); + + return (cpp_demangle_get_subst(ddata, nth)); + } + + /* NOTREACHED */ + return (0); +} + +static int +cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) +{ + struct vector_str *output, v; + size_t p_idx, subst_str_len; + int rtn; + char *subst_str; + + if (ddata == NULL) + return (0); + + if (!vector_str_init(&v)) + return (0); + + subst_str = NULL; + rtn = 0; + if (!DEM_PUSH_STR(ddata, "std::")) + goto clean; + + if (!VEC_PUSH_STR(&v, "std::")) + goto clean; + + ddata->cur += 2; + + output = ddata->cur_output; + + p_idx = output->size; + if (!cpp_demangle_read_uqname(ddata)) + goto clean; + + if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, + &subst_str_len)) == NULL) + goto clean; + + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + + if (*ddata->cur == 'I') { + p_idx = output->size; + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + free(subst_str); + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_push(&v, subst_str, subst_str_len)) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, &v)) + goto clean; + } + + rtn = 1; +clean: + free(subst_str); + vector_str_dest(&v); + + return (rtn); +} + +static int +cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, + const char *str) +{ + struct vector_str *output; + size_t p_idx, substr_len, len; + int rtn; + char *subst_str, *substr; + + if (ddata == NULL || str == NULL) + return (0); + + if ((len = strlen(str)) == 0) + return (0); + + output = ddata->cur_output; + + p_idx = output->size; + substr = NULL; + subst_str = NULL; + + if (!cpp_demangle_read_tmpl_args(ddata)) + return (0); + if ((substr = vector_str_substr(output, p_idx, output->size - 1, + &substr_len)) == NULL) + return (0); + + rtn = 0; + if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == + NULL) + goto clean; + + memcpy(subst_str, str, len); + memcpy(subst_str + len, substr, substr_len); + subst_str[substr_len + len] = '\0'; + + if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) + goto clean; + + rtn = 1; +clean: + free(subst_str); + free(substr); + + return (rtn); +} + +static int +cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + switch (*ddata->cur) { + case 'L': + return (cpp_demangle_read_expr_primary(ddata)); + case 'X': + ++ddata->cur; + if (!cpp_demangle_read_expression(ddata)) + return (0); + return (*ddata->cur++ == 'E'); + } + + return (cpp_demangle_read_type(ddata, NULL)); +} + +static int +cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) +{ + struct vector_str *v; + size_t arg_len, idx, limit, size; + char *arg; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + ++ddata->cur; + + if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL)) + return (0); + + if (!DEM_PUSH_STR(ddata, "<")) + return (0); + + limit = 0; + v = ddata->cur_output; + for (;;) { + idx = v->size; + if (!cpp_demangle_read_tmpl_arg(ddata)) + return (0); + if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == + NULL) + return (0); + if (!vector_str_find(&ddata->tmpl, arg, arg_len) && + !vector_str_push(&ddata->tmpl, arg, arg_len)) { + free(arg); + return (0); + } + + free(arg); + + if (*ddata->cur == 'E') { + ++ddata->cur; + size = v->size; + assert(size > 0); + if (!strncmp(v->container[size - 1], ">", 1)) { + if (!DEM_PUSH_STR(ddata, " >")) + return (0); + } else if (!DEM_PUSH_STR(ddata, ">")) + return (0); + ddata->is_tmpl = true; + break; + } else if (*ddata->cur != 'I' && + !DEM_PUSH_STR(ddata, ", ")) + return (0); + + if (limit++ > CPP_DEMANGLE_TRY_LIMIT) + return (0); + } + + return (vector_read_cmd_pop(&ddata->cmd)); +} + +/* + * Read template parameter that forms in 'T[number]_'. + * This function much like to read_subst but only for types. + */ +static int +cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) +{ + long nth; + + if (ddata == NULL || *ddata->cur != 'T') + return (0); + + ++ddata->cur; + + if (*ddata->cur == '_') + return (cpp_demangle_get_tmpl_param(ddata, 0)); + else { + + errno = 0; + if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && + errno != 0) + return (0); + + /* T_ is first */ + ++nth; + + while (*ddata->cur != '_') + ++ddata->cur; + + assert(nth > 0); + + return (cpp_demangle_get_tmpl_param(ddata, nth)); + } + + /* NOTREACHED */ + return (0); +} + +static int +cpp_demangle_read_type(struct cpp_demangle_data *ddata, + struct type_delimit *td) +{ + struct vector_type_qualifier v; + struct vector_str *output, sv; + size_t p_idx, type_str_len, subst_str_len; + int extern_c, is_builtin; + long len; + const char *p; + char *type_str, *exp_str, *num_str, *subst_str; + bool skip_ref_qualifier, omit_void; + + if (ddata == NULL) + return (0); + + output = ddata->cur_output; + if (td) { + if (td->paren == false) { + if (!DEM_PUSH_STR(ddata, "(")) + return (0); + if (ddata->output.size < 2) + return (0); + td->paren = true; + } + + if (!td->firstp) { + if (*ddata->cur != 'I') { + if (!DEM_PUSH_STR(ddata, ", ")) + return (0); + } + } + } + + assert(output != NULL); + /* + * [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array + * pointer-to-member, template-param, template-template-param, subst + */ + + if (!vector_type_qualifier_init(&v)) + return (0); + + extern_c = 0; + is_builtin = 1; + p_idx = output->size; + type_str = exp_str = num_str = NULL; + skip_ref_qualifier = false; + +again: + + /* Clear ref-qualifier flag */ + if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E') + ddata->ref_qualifier = false; + + /* builtin type */ + switch (*ddata->cur) { + case 'a': + /* signed char */ + if (!DEM_PUSH_STR(ddata, "signed char")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'A': + /* array type */ + if (!cpp_demangle_read_array(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'b': + /* bool */ + if (!DEM_PUSH_STR(ddata, "bool")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'C': + /* complex pair */ + if (!vector_type_qualifier_push(&v, TYPE_CMX)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'c': + /* char */ + if (!DEM_PUSH_STR(ddata, "char")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'd': + /* double */ + if (!DEM_PUSH_STR(ddata, "double")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'D': + ++ddata->cur; + switch (*ddata->cur) { + case 'a': + /* auto */ + if (!DEM_PUSH_STR(ddata, "auto")) + goto clean; + ++ddata->cur; + break; + case 'c': + /* decltype(auto) */ + if (!DEM_PUSH_STR(ddata, "decltype(auto)")) + goto clean; + ++ddata->cur; + break; + case 'd': + /* IEEE 754r decimal floating point (64 bits) */ + if (!DEM_PUSH_STR(ddata, "decimal64")) + goto clean; + ++ddata->cur; + break; + case 'e': + /* IEEE 754r decimal floating point (128 bits) */ + if (!DEM_PUSH_STR(ddata, "decimal128")) + goto clean; + ++ddata->cur; + break; + case 'f': + /* IEEE 754r decimal floating point (32 bits) */ + if (!DEM_PUSH_STR(ddata, "decimal32")) + goto clean; + ++ddata->cur; + break; + case 'h': + /* IEEE 754r half-precision floating point (16 bits) */ + if (!DEM_PUSH_STR(ddata, "half")) + goto clean; + ++ddata->cur; + break; + case 'i': + /* char32_t */ + if (!DEM_PUSH_STR(ddata, "char32_t")) + goto clean; + ++ddata->cur; + break; + case 'n': + /* std::nullptr_t (i.e., decltype(nullptr)) */ + if (!DEM_PUSH_STR(ddata, "decltype(nullptr)")) + goto clean; + ++ddata->cur; + break; + case 's': + /* char16_t */ + if (!DEM_PUSH_STR(ddata, "char16_t")) + goto clean; + ++ddata->cur; + break; + case 'v': + /* gcc vector_size extension. */ + ++ddata->cur; + if (*ddata->cur == '_') { + ++ddata->cur; + if (!cpp_demangle_read_expression_flat(ddata, + &exp_str)) + goto clean; + if (!VEC_PUSH_STR(&v.ext_name, exp_str)) + goto clean; + } else { + if (!cpp_demangle_read_number_as_string(ddata, + &num_str)) + goto clean; + if (!VEC_PUSH_STR(&v.ext_name, num_str)) + goto clean; + } + if (*ddata->cur != '_') + goto clean; + ++ddata->cur; + if (!vector_type_qualifier_push(&v, TYPE_VEC)) + goto clean; + if (td) + td->firstp = false; + goto again; + default: + goto clean; + } + goto rtn; + + case 'e': + /* long double */ + if (!DEM_PUSH_STR(ddata, "long double")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'E': + /* unexpected end except ref-qualifiers */ + if (ddata->ref_qualifier && ddata->is_functype) { + skip_ref_qualifier = true; + /* Pop the delimiter. */ + cpp_demangle_pop_str(ddata); + goto rtn; + } + goto clean; + + case 'f': + /* float */ + if (!DEM_PUSH_STR(ddata, "float")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'F': + /* function */ + if (!cpp_demangle_read_function(ddata, &extern_c, &v)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'g': + /* __float128 */ + if (!DEM_PUSH_STR(ddata, "__float128")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'G': + /* imaginary */ + if (!vector_type_qualifier_push(&v, TYPE_IMG)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'h': + /* unsigned char */ + if (!DEM_PUSH_STR(ddata, "unsigned char")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'i': + /* int */ + if (!DEM_PUSH_STR(ddata, "int")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'I': + /* template args. */ + /* handles */ + p_idx = output->size; + if (!cpp_demangle_read_tmpl_args(ddata)) + goto clean; + if ((subst_str = vector_str_substr(output, p_idx, + output->size - 1, &subst_str_len)) == NULL) + goto clean; + if (!vector_str_init(&sv)) { + free(subst_str); + goto clean; + } + if (!vector_str_push(&sv, subst_str, subst_str_len)) { + free(subst_str); + vector_str_dest(&sv); + goto clean; + } + free(subst_str); + if (!cpp_demangle_push_subst_v(ddata, &sv)) { + vector_str_dest(&sv); + goto clean; + } + vector_str_dest(&sv); + goto rtn; + + case 'j': + /* unsigned int */ + if (!DEM_PUSH_STR(ddata, "unsigned int")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'K': + /* const */ + if (!vector_type_qualifier_push(&v, TYPE_CST)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'l': + /* long */ + if (!DEM_PUSH_STR(ddata, "long")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'm': + /* unsigned long */ + if (!DEM_PUSH_STR(ddata, "unsigned long")) + goto clean; + + ++ddata->cur; + + goto rtn; + case 'M': + /* pointer to member */ + if (!cpp_demangle_read_pointer_to_member(ddata, &v)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'n': + /* __int128 */ + if (!DEM_PUSH_STR(ddata, "__int128")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'o': + /* unsigned __int128 */ + if (!DEM_PUSH_STR(ddata, "unsigned __int128")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'O': + /* rvalue reference */ + if (ddata->ref_qualifier) + goto clean; + if (!vector_type_qualifier_push(&v, TYPE_RREF)) + goto clean; + ddata->ref_qualifier = true; + ddata->ref_qualifier_type = TYPE_RREF; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'P': + /* pointer */ + if (!vector_type_qualifier_push(&v, TYPE_PTR)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'r': + /* restrict */ + if (!vector_type_qualifier_push(&v, TYPE_RST)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'R': + /* reference */ + if (ddata->ref_qualifier) + goto clean; + if (!vector_type_qualifier_push(&v, TYPE_REF)) + goto clean; + ddata->ref_qualifier = true; + ddata->ref_qualifier_type = TYPE_REF; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 's': + /* short, local string */ + if (!DEM_PUSH_STR(ddata, "short")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'S': + /* substitution */ + if (!cpp_demangle_read_subst(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 't': + /* unsigned short */ + if (!DEM_PUSH_STR(ddata, "unsigned short")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'T': + /* template parameter */ + if (!cpp_demangle_read_tmpl_param(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'u': + /* vendor extended builtin */ + ++ddata->cur; + if (!cpp_demangle_read_sname(ddata)) + goto clean; + is_builtin = 0; + goto rtn; + + case 'U': + /* vendor extended type qualifier */ + ++ddata->cur; + if (!cpp_demangle_read_number(ddata, &len)) + goto clean; + if (len <= 0) + goto clean; + if (!vector_str_push(&v.ext_name, ddata->cur, len)) + return (0); + ddata->cur += len; + if (!vector_type_qualifier_push(&v, TYPE_EXT)) + goto clean; + if (td) + td->firstp = false; + goto again; + + case 'v': + /* void */ + omit_void = false; + if (td && td->firstp) { + /* + * peek into next bytes and see if we should omit + * the "void". + */ + omit_void = true; + for (p = ddata->cur + 1; *p != '\0'; p++) { + if (*p == 'E') + break; + if (*p != 'R' && *p != 'O') { + omit_void = false; + break; + } + } + } + if (!omit_void && !DEM_PUSH_STR(ddata, "void")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'V': + /* volatile */ + if (!vector_type_qualifier_push(&v, TYPE_VAT)) + goto clean; + ++ddata->cur; + if (td) + td->firstp = false; + goto again; + + case 'w': + /* wchar_t */ + if (!DEM_PUSH_STR(ddata, "wchar_t")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'x': + /* long long */ + if (!DEM_PUSH_STR(ddata, "long long")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'y': + /* unsigned long long */ + if (!DEM_PUSH_STR(ddata, "unsigned long long")) + goto clean; + ++ddata->cur; + goto rtn; + + case 'z': + /* ellipsis */ + if (!DEM_PUSH_STR(ddata, "...")) + goto clean; + ++ddata->cur; + goto rtn; + } + + if (!cpp_demangle_read_name(ddata)) + goto clean; + + is_builtin = 0; +rtn: + + type_str = vector_str_substr(output, p_idx, output->size - 1, + &type_str_len); + + if (is_builtin == 0) { + if (!vector_str_find(&ddata->subst, type_str, type_str_len) && + !vector_str_push(&ddata->subst, type_str, type_str_len)) + goto clean; + } + + if (!skip_ref_qualifier && + !cpp_demangle_push_type_qualifier(ddata, &v, type_str)) + goto clean; + + if (td) + td->firstp = false; + + free(type_str); + free(exp_str); + free(num_str); + vector_type_qualifier_dest(&v); + + return (1); +clean: + free(type_str); + free(exp_str); + free(num_str); + vector_type_qualifier_dest(&v); + + return (0); +} + +static int +cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) +{ + struct vector_str *output; + size_t i, p_idx, idx, type_len; + char *type; + + output = ddata->cur_output; + + p_idx = output->size; + + if (!cpp_demangle_read_type(ddata, NULL)) + return (0); + + if ((type = vector_str_substr(output, p_idx, output->size - 1, + &type_len)) == NULL) + return (0); + + idx = output->size; + for (i = p_idx; i < idx; ++i) { + if (!vector_str_pop(output)) { + free(type); + return (0); + } + } + + *str = type; + + return (1); +} + +/* + * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, + * source-name + */ +static int +cpp_demangle_read_uqname(struct cpp_demangle_data *ddata) +{ + size_t len; + + if (ddata == NULL || *ddata->cur == '\0') + return (0); + + /* operator name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('a', 'a'): + /* operator && */ + if (!DEM_PUSH_STR(ddata, "operator&&")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'd'): + /* operator & (unary) */ + if (!DEM_PUSH_STR(ddata, "operator&")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'n'): + /* operator & */ + if (!DEM_PUSH_STR(ddata, "operator&")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'N'): + /* operator &= */ + if (!DEM_PUSH_STR(ddata, "operator&=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('a', 'S'): + /* operator = */ + if (!DEM_PUSH_STR(ddata, "operator=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'l'): + /* operator () */ + if (!DEM_PUSH_STR(ddata, "operator()")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'm'): + /* operator , */ + if (!DEM_PUSH_STR(ddata, "operator,")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'o'): + /* operator ~ */ + if (!DEM_PUSH_STR(ddata, "operator~")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('c', 'v'): + /* operator (cast) */ + if (!DEM_PUSH_STR(ddata, "operator(cast)")) + return (0); + ddata->cur += 2; + return (cpp_demangle_read_type(ddata, NULL)); + + case SIMPLE_HASH('d', 'a'): + /* operator delete [] */ + if (!DEM_PUSH_STR(ddata, "operator delete []")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'e'): + /* operator * (unary) */ + if (!DEM_PUSH_STR(ddata, "operator*")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'l'): + /* operator delete */ + if (!DEM_PUSH_STR(ddata, "operator delete")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'v'): + /* operator / */ + if (!DEM_PUSH_STR(ddata, "operator/")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('d', 'V'): + /* operator /= */ + if (!DEM_PUSH_STR(ddata, "operator/=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'o'): + /* operator ^ */ + if (!DEM_PUSH_STR(ddata, "operator^")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'O'): + /* operator ^= */ + if (!DEM_PUSH_STR(ddata, "operator^=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('e', 'q'): + /* operator == */ + if (!DEM_PUSH_STR(ddata, "operator==")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('g', 'e'): + /* operator >= */ + if (!DEM_PUSH_STR(ddata, "operator>=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('g', 't'): + /* operator > */ + if (!DEM_PUSH_STR(ddata, "operator>")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('i', 'x'): + /* operator [] */ + if (!DEM_PUSH_STR(ddata, "operator[]")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 'e'): + /* operator <= */ + if (!DEM_PUSH_STR(ddata, "operator<=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 's'): + /* operator << */ + if (!DEM_PUSH_STR(ddata, "operator<<")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 'S'): + /* operator <<= */ + if (!DEM_PUSH_STR(ddata, "operator<<=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('l', 't'): + /* operator < */ + if (!DEM_PUSH_STR(ddata, "operator<")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'i'): + /* operator - */ + if (!DEM_PUSH_STR(ddata, "operator-")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'I'): + /* operator -= */ + if (!DEM_PUSH_STR(ddata, "operator-=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'l'): + /* operator * */ + if (!DEM_PUSH_STR(ddata, "operator*")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'L'): + /* operator *= */ + if (!DEM_PUSH_STR(ddata, "operator*=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('m', 'm'): + /* operator -- */ + if (!DEM_PUSH_STR(ddata, "operator--")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'a'): + /* operator new[] */ + if (!DEM_PUSH_STR(ddata, "operator new []")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'e'): + /* operator != */ + if (!DEM_PUSH_STR(ddata, "operator!=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'g'): + /* operator - (unary) */ + if (!DEM_PUSH_STR(ddata, "operator-")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 't'): + /* operator ! */ + if (!DEM_PUSH_STR(ddata, "operator!")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('n', 'w'): + /* operator new */ + if (!DEM_PUSH_STR(ddata, "operator new")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'o'): + /* operator || */ + if (!DEM_PUSH_STR(ddata, "operator||")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'r'): + /* operator | */ + if (!DEM_PUSH_STR(ddata, "operator|")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('o', 'R'): + /* operator |= */ + if (!DEM_PUSH_STR(ddata, "operator|=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'l'): + /* operator + */ + if (!DEM_PUSH_STR(ddata, "operator+")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'L'): + /* operator += */ + if (!DEM_PUSH_STR(ddata, "operator+=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'm'): + /* operator ->* */ + if (!DEM_PUSH_STR(ddata, "operator->*")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 'p'): + /* operator ++ */ + if (!DEM_PUSH_STR(ddata, "operator++")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 's'): + /* operator + (unary) */ + if (!DEM_PUSH_STR(ddata, "operator+")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('p', 't'): + /* operator -> */ + if (!DEM_PUSH_STR(ddata, "operator->")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('q', 'u'): + /* operator ? */ + if (!DEM_PUSH_STR(ddata, "operator?")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'm'): + /* operator % */ + if (!DEM_PUSH_STR(ddata, "operator%")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'M'): + /* operator %= */ + if (!DEM_PUSH_STR(ddata, "operator%=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 's'): + /* operator >> */ + if (!DEM_PUSH_STR(ddata, "operator>>")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'S'): + /* operator >>= */ + if (!DEM_PUSH_STR(ddata, "operator>>=")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('r', 'z'): + /* operator sizeof */ + if (!DEM_PUSH_STR(ddata, "operator sizeof ")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('s', 'r'): + /* scope resolution operator */ + if (!DEM_PUSH_STR(ddata, "scope resolution operator ")) + return (0); + ddata->cur += 2; + return (1); + + case SIMPLE_HASH('s', 'v'): + /* operator sizeof */ + if (!DEM_PUSH_STR(ddata, "operator sizeof ")) + return (0); + ddata->cur += 2; + return (1); + } + + /* vendor extened operator */ + if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { + if (!DEM_PUSH_STR(ddata, "vendor extened operator ")) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) + return (0); + ddata->cur += 2; + return (cpp_demangle_read_sname(ddata)); + } + + /* ctor-dtor-name */ + switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { + case SIMPLE_HASH('C', '1'): + case SIMPLE_HASH('C', '2'): + case SIMPLE_HASH('C', '3'): + if (ddata->last_sname == NULL) + return (0); + if ((len = strlen(ddata->last_sname)) == 0) + return (0); + if (!DEM_PUSH_STR(ddata, "::")) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) + return (0); + ddata->cur +=2; + return (1); + + case SIMPLE_HASH('D', '0'): + case SIMPLE_HASH('D', '1'): + case SIMPLE_HASH('D', '2'): + if (ddata->last_sname == NULL) + return (0); + if ((len = strlen(ddata->last_sname)) == 0) + return (0); + if (!DEM_PUSH_STR(ddata, "::~")) + return (0); + if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) + return (0); + ddata->cur +=2; + return (1); + } + + /* source name */ + if (ELFTC_ISDIGIT(*ddata->cur) != 0) + return (cpp_demangle_read_sname(ddata)); + + /* local source name */ + if (*ddata->cur == 'L') + return (cpp_demangle_local_source_name(ddata)); + + return (1); +} + +/* + * Read local source name. + * + * References: + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 + * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 + */ +static int +cpp_demangle_local_source_name(struct cpp_demangle_data *ddata) +{ + /* L */ + if (ddata == NULL || *ddata->cur != 'L') + return (0); + ++ddata->cur; + + /* source name */ + if (!cpp_demangle_read_sname(ddata)) + return (0); + + /* discriminator */ + if (*ddata->cur == '_') { + ++ddata->cur; + while (ELFTC_ISDIGIT(*ddata->cur) != 0) + ++ddata->cur; + } + + return (1); +} + +static int +cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) +{ + + if (ddata == NULL) + return (0); + + if (!DEM_PUSH_STR(ddata, "offset : ")) + return (0); + + if (!cpp_demangle_read_offset_number(ddata)) + return (0); + + if (!DEM_PUSH_STR(ddata, "virtual offset : ")) + return (0); + + return (!cpp_demangle_read_offset_number(ddata)); +} + +/* + * Decode floating point representation to string + * Return new allocated string or NULL + * + * Todo + * Replace these functions to macro. + */ +static char * +decode_fp_to_double(const char *p, size_t len) +{ + double f; + size_t rtn_len, limit, i; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) + return (NULL); + + memset(&f, 0, sizeof(double)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(double) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 64; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return rtn; +} + +static char * +decode_fp_to_float(const char *p, size_t len) +{ + size_t i, rtn_len, limit; + float f; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) + return (NULL); + + memset(&f, 0, sizeof(float)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + if (byte < 0 || byte > 255) + return (NULL); +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(float) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 64; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return rtn; +} + +static char * +decode_fp_to_float128(const char *p, size_t len) +{ +#if __SIZEOF_LONG_DOUBLE__ == FLOAT_QUADRUPLE_BYTES + return (decode_fp_to_long_double(p, len)); +#elif __SIZEOF_LONG_DOUBLE__ == FLOAT_EXTENDED_BYTES + long double f; + size_t rtn_len, limit, i; + int byte; + unsigned char buf[FLOAT_QUADRUPLE_BYTES]; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > FLOAT_QUADRUPLE_BYTES) + return (NULL); + + memset(buf, 0, FLOAT_QUADRUPLE_BYTES); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + if (byte < 0 || byte > 255) + return (NULL); +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + buf[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + buf[FLOAT_QUADRUPLE_BYTES - i -1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + memset(&f, 0, FLOAT_EXTENDED_BYTES); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + memcpy(&f, buf, FLOAT_EXTENDED_BYTES); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + memcpy(&f, buf + 6, FLOAT_EXTENDED_BYTES); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); +#elif __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ + /* Ticket: [#599] */ + return (decode_fp_to_double(p, len)); +#endif +} + +static char * +decode_fp_to_float80(const char *p, size_t len) +{ +#if __SIZEOF_LONG_DOUBLE__ == FLOAT_QUADRUPLE_BYTES + long double f; + size_t rtn_len, limit, i; + int byte; + unsigned char buf[FLOAT_EXTENDED_BYTES]; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > FLOAT_EXTENDED_BYTES) + return (NULL); + + memset(buf, 0, FLOAT_EXTENDED_BYTES); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + buf[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + buf[FLOAT_EXTENDED_BYTES - i -1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + memset(&f, 0, FLOAT_QUADRUPLE_BYTES); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + memcpy(&f, buf, FLOAT_EXTENDED_BYTES); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENDED_BYTES); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); +#elif __SIZEOF_LONG_DOUBLE__ == FLOAT_EXTENDED_BYTES + return (decode_fp_to_long_double(p, len)); +#elif __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ + /* Ticket: [#599] */ + return (decode_fp_to_double(p, len)); +#endif +} + +#if __SIZEOF_LONG_DOUBLE__ != __SIZEOF_DOUBLE__ +static char * +decode_fp_to_long_double(const char *p, size_t len) +{ + long double f; + size_t rtn_len, limit, i; + int byte; + char *rtn; + + if (p == NULL || len == 0 || len % 2 != 0 || + len / 2 > sizeof(long double)) + return (NULL); + + memset(&f, 0, sizeof(long double)); + + for (i = 0; i < len / 2; ++i) { + byte = hex_to_dec(p[len - i * 2 - 1]) + + hex_to_dec(p[len - i * 2 - 2]) * 16; + + if (byte < 0 || byte > 255) + return (NULL); + +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN + ((unsigned char *)&f)[i] = (unsigned char)(byte); +#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + ((unsigned char *)&f)[sizeof(long double) - i - 1] = + (unsigned char)(byte); +#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ + } + + rtn_len = 256; + limit = 0; +again: + if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) + return (NULL); + + if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { + free(rtn); + if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) + return (NULL); + rtn_len *= BUFFER_GROWFACTOR; + goto again; + } + + return (rtn); +} +#endif + +/* Simple hex to integer function used by decode_to_* function. */ +static int +hex_to_dec(char c) +{ + + switch (c) { + case '0': + return (0); + case '1': + return (1); + case '2': + return (2); + case '3': + return (3); + case '4': + return (4); + case '5': + return (5); + case '6': + return (6); + case '7': + return (7); + case '8': + return (8); + case '9': + return (9); + case 'a': + return (10); + case 'b': + return (11); + case 'c': + return (12); + case 'd': + return (13); + case 'e': + return (14); + case 'f': + return (15); + default: + return (-1); + } +} + +/** + * @brief Test input string is mangled by IA-64 C++ ABI style. + * + * Test string heads with "_Z" or "_GLOBAL__I_". + * @return Return 0 at false. + */ +bool +is_cpp_mangled_gnu3(const char *org) +{ + size_t len; + + len = strlen(org); + return ((len > 2 && *org == '_' && *(org + 1) == 'Z') || + (len > 11 && !strncmp(org, "_GLOBAL__I_", 11))); +} + +static void +vector_read_cmd_dest(struct vector_read_cmd *v) +{ + + if (v == NULL) + return; + + free(v->r_container); +} + +static struct read_cmd_item * +vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) +{ + int i; + + if (v == NULL || dst == READ_FAIL) + return (NULL); + + for (i = (int) v->size - 1; i >= 0; i--) + if (v->r_container[i].cmd == dst) + return (&v->r_container[i]); + + return (NULL); +} + +static int +vector_read_cmd_init(struct vector_read_cmd *v) +{ + + if (v == NULL) + return (0); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity)) + == NULL) + return (0); + + return (1); +} + +static int +vector_read_cmd_pop(struct vector_read_cmd *v) +{ + + if (v == NULL || v->size == 0) + return (0); + + --v->size; + v->r_container[v->size].cmd = READ_FAIL; + v->r_container[v->size].data = NULL; + + return (1); +} + +static int +vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data) +{ + struct read_cmd_item *tmp_r_ctn; + size_t tmp_cap; + size_t i; + + if (v == NULL) + return (0); + + if (v->size == v->capacity) { + tmp_cap = BUFFER_GROW(v->capacity); + if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL) + return (0); + for (i = 0; i < v->size; ++i) + tmp_r_ctn[i] = v->r_container[i]; + free(v->r_container); + v->r_container = tmp_r_ctn; + v->capacity = tmp_cap; + } + + v->r_container[v->size].cmd = cmd; + v->r_container[v->size].data = data; + ++v->size; + + return (1); +} + +static void +vector_type_qualifier_dest(struct vector_type_qualifier *v) +{ + + if (v == NULL) + return; + + free(v->q_container); + vector_str_dest(&v->ext_name); +} + +/* size, capacity, ext_name */ +static int +vector_type_qualifier_init(struct vector_type_qualifier *v) +{ + + if (v == NULL) + return (0); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) + == NULL) + return (0); + + assert(v->q_container != NULL); + + if (!vector_str_init(&v->ext_name)) { + free(v->q_container); + return (0); + } + + return (1); +} + +static int +vector_type_qualifier_push(struct vector_type_qualifier *v, + enum type_qualifier t) +{ + enum type_qualifier *tmp_ctn; + size_t tmp_cap; + size_t i; + + if (v == NULL) + return (0); + + if (v->size == v->capacity) { + tmp_cap = BUFFER_GROW(v->capacity); + if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) + == NULL) + return (0); + for (i = 0; i < v->size; ++i) + tmp_ctn[i] = v->q_container[i]; + free(v->q_container); + v->q_container = tmp_ctn; + v->capacity = tmp_cap; + } + + v->q_container[v->size] = t; + ++v->size; + + return (1); +} diff --git a/contrib/elftoolchain/libelftc/libelftc_hash.c b/contrib/elftoolchain/libelftc/libelftc_hash.c new file mode 100644 index 0000000000..6cc54b964e --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_hash.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2013, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * An implementation of the Fowler-Noll-Vo hash function. + * + * References: + * - http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function + * - http://www.isthe.com/chongo/tech/comp/fnv/ + */ + +#include + +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_hash.c 2870 2013-01-07 10:38:43Z jkoshy $"); + +/* + * Use the size of an 'int' to determine the magic numbers used by the + * hash function. + */ + +#if INT_MAX == 2147483647UL +#define FNV_PRIME 16777619UL +#define FNV_OFFSET 2166136261UL +#elif INT_MAX == 18446744073709551615ULL +#define FNV_PRIME 1099511628211ULL +#define FNV_OFFSET 14695981039346656037ULL +#else +#error sizeof(int) is unknown. +#endif + +unsigned int +libelftc_hash_string(const char *s) +{ + char c; + unsigned int hash; + + for (hash = FNV_OFFSET; (c = *s) != '\0'; s++) { + hash ^= c; + hash *= FNV_PRIME; + } + + return (hash); +} diff --git a/contrib/elftoolchain/libelftc/libelftc_vstr.c b/contrib/elftoolchain/libelftc/libelftc_vstr.c new file mode 100644 index 0000000000..a4e4ee7151 --- /dev/null +++ b/contrib/elftoolchain/libelftc/libelftc_vstr.c @@ -0,0 +1,359 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "_libelftc.h" + +ELFTC_VCSID("$Id: libelftc_vstr.c 3877 2020-11-03 18:28:08Z jkoshy $"); + +/** + * @file vector_str.c + * @brief Dynamic vector data for string implementation. + * + * Resemble to std::vector in C++. + */ + +static size_t get_strlen_sum(const struct vector_str *v); +static bool vector_str_grow(struct vector_str *v); + +static size_t +get_strlen_sum(const struct vector_str *v) +{ + size_t i, len = 0; + + if (v == NULL) + return (0); + + assert(v->size > 0); + + for (i = 0; i < v->size; ++i) + len += strlen(v->container[i]); + + return (len); +} + +/** + * @brief Deallocate resource in vector_str. + */ +void +vector_str_dest(struct vector_str *v) +{ + size_t i; + + if (v == NULL) + return; + + for (i = 0; i < v->size; ++i) + free(v->container[i]); + + free(v->container); +} + +/** + * @brief Find string in vector_str. + * @param v Destination vector. + * @param o String to find. + * @param l Length of the string. + * @return -1 at failed, 0 at not found, 1 at found. + */ +int +vector_str_find(const struct vector_str *v, const char *o, size_t l) +{ + size_t i; + + if (v == NULL || o == NULL) + return (-1); + + for (i = 0; i < v->size; ++i) + if (strncmp(v->container[i], o, l) == 0) + return (1); + + return (0); +} + +/** + * @brief Get new allocated flat string from vector. + * + * If l is not NULL, return length of the string. + * @param v Destination vector. + * @param l Length of the string. + * @return NULL at failed or NUL terminated new allocated string. + */ +char * +vector_str_get_flat(const struct vector_str *v, size_t *l) +{ + ssize_t elem_pos, elem_size, rtn_size; + size_t i; + char *rtn; + + if (v == NULL || v->size == 0) + return (NULL); + + if ((rtn_size = get_strlen_sum(v)) == 0) + return (NULL); + + if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL) + return (NULL); + + elem_pos = 0; + for (i = 0; i < v->size; ++i) { + elem_size = strlen(v->container[i]); + + memcpy(rtn + elem_pos, v->container[i], elem_size); + + elem_pos += elem_size; + } + + rtn[rtn_size] = '\0'; + + if (l != NULL) + *l = rtn_size; + + return (rtn); +} + +static bool +vector_str_grow(struct vector_str *v) +{ + size_t i, tmp_cap; + char **tmp_ctn; + + if (v == NULL) + return (false); + + assert(v->capacity > 0); + + tmp_cap = BUFFER_GROW(v->capacity); + + assert(tmp_cap > v->capacity); + + if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) + return (false); + + for (i = 0; i < v->size; ++i) + tmp_ctn[i] = v->container[i]; + + free(v->container); + + v->container = tmp_ctn; + v->capacity = tmp_cap; + + return (true); +} + +/** + * @brief Initialize vector_str. + * @return false at failed, true at success. + */ +bool +vector_str_init(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + v->size = 0; + v->capacity = VECTOR_DEF_CAPACITY; + + assert(v->capacity > 0); + + if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL) + return (false); + + assert(v->container != NULL); + + return (true); +} + +/** + * @brief Remove last element in vector_str. + * @return false at failed, true at success. + */ +bool +vector_str_pop(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + if (v->size == 0) + return (true); + + --v->size; + + free(v->container[v->size]); + v->container[v->size] = NULL; + + return (true); +} + +/** + * @brief Push back string to vector. + * @return false at failed, true at success. + */ +bool +vector_str_push(struct vector_str *v, const char *str, size_t len) +{ + + if (v == NULL || str == NULL) + return (false); + + if (v->size == v->capacity && vector_str_grow(v) == false) + return (false); + + if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL) + return (false); + + snprintf(v->container[v->size], len + 1, "%s", str); + + ++v->size; + + return (true); +} + +/** + * @brief Push front org vector to det vector. + * @return false at failed, true at success. + */ +bool +vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org) +{ + size_t i, j, tmp_cap; + char **tmp_ctn; + + if (dst == NULL || org == NULL) + return (false); + + tmp_cap = BUFFER_GROW(dst->size + org->size); + + if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) + return (false); + + for (i = 0; i < org->size; ++i) + if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) { + for (j = 0; j < i; ++j) + free(tmp_ctn[j]); + + free(tmp_ctn); + + return (false); + } + + for (i = 0; i < dst->size; ++i) + tmp_ctn[i + org->size] = dst->container[i]; + + free(dst->container); + + dst->container = tmp_ctn; + dst->capacity = tmp_cap; + dst->size += org->size; + + return (true); +} + +/** + * @brief Push org vector to the tail of det vector. + * @return false at failed, true at success. + */ +bool +vector_str_push_vector(struct vector_str *dst, struct vector_str *org) +{ + size_t i, j, tmp_cap; + char **tmp_ctn; + + if (dst == NULL || org == NULL) + return (false); + + tmp_cap = BUFFER_GROW(dst->size + org->size); + + if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) + return (false); + + for (i = 0; i < dst->size; ++i) + tmp_ctn[i] = dst->container[i]; + + for (i = 0; i < org->size; ++i) + if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) == + NULL) { + for (j = 0; j < i + dst->size; ++j) + free(tmp_ctn[j]); + + free(tmp_ctn); + + return (false); + } + + free(dst->container); + + dst->container = tmp_ctn; + dst->capacity = tmp_cap; + dst->size += org->size; + + return (true); +} + +/** + * @brief Get new allocated flat string from vector between begin and end. + * + * If r_len is not NULL, string length will be returned. + * @return NULL at failed or NUL terminated new allocated string. + */ +char * +vector_str_substr(const struct vector_str *v, size_t begin, size_t end, + size_t *r_len) +{ + size_t cur, i, len; + char *rtn; + + if (v == NULL || begin > end) + return (NULL); + + len = 0; + for (i = begin; i < end + 1; ++i) + len += strlen(v->container[i]); + + if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL) + return (NULL); + + if (r_len != NULL) + *r_len = len; + + cur = 0; + for (i = begin; i < end + 1; ++i) { + len = strlen(v->container[i]); + memcpy(rtn + cur, v->container[i], len); + cur += len; + } + rtn[cur] = '\0'; + + return (rtn); +} diff --git a/contrib/elftoolchain/libelftc/make-toolchain-version b/contrib/elftoolchain/libelftc/make-toolchain-version new file mode 100755 index 0000000000..1150c48457 --- /dev/null +++ b/contrib/elftoolchain/libelftc/make-toolchain-version @@ -0,0 +1,120 @@ +#!/bin/sh +# +# This script generates a project-wide version identifier for use by +# the `elftc_version()' API. +# +# $Id: make-toolchain-version 4023 2023-12-09 14:41:43Z jkoshy $ + +# +# Defaults. +# +buildhost=`uname -s` +elftcname="elftoolchain" +options="e:h:o:pr:t:" +top="" +version="HEAD" +versionfile="elftc_version.c" +progname=`basename ${0}` + +usage() +{ + exec >&2 + + # Print a message, if supplied. + if [ -n "${*}" ]; then echo "## ${@}"; fi + + echo "Usage: ${progname} -t TOPDIR [options]" + echo " Generate a toolchain-wide version number" + echo " -e PROJECTNAME Set the project name [default: ${elftcname}]." + echo " -h HOSTOS Set the build OS [default: ${buildhost}]." + echo " -o OUTPUT Set the output file [default: ${versionfile}]." + echo " -p Write a plain version string to output." + echo " -r VERSION Set the version string [default: ${version}]." + echo " -t TOPDIR Set the top-of-tree directory [required]." + exit 1 +} + +# Determine the revision number for the source tree. +# +# - If CVS is detected, we use the string `unknown'. +# - If SVN is detected, we use the `svninfo' tool to determine the +# in-tree revision number. +# - Otherwise, we use `git --describe'. +get_revision_string() +{ + v="unknown:unknown" + if [ -d CVS ]; then # Look for CVS (NetBSD). + v="cvs:unknown" + elif [ -d .svn -o -d ../.svn ]; then + # An SVN checkout (SourceForge or FreeBSD prior to r368820). + svnversion="$(svnversion 2>/dev/null)" + if [ -n "${svnversion}" ]; then + v="svn:${svnversion}" + fi + else # Try git (DragonflyBSD, FreeBSD). + gitversion="$(git describe --all --dirty --long 2> /dev/null)" + if [ -n "${gitversion}" ]; then + v="git:${gitversion}" + fi + fi + + echo "${v}" +} + +# +# Parse options. +# + +while getopts ${options} option +do + case ${option} in + 'e') elftcname="${OPTARG}" ;; + 'h') buildhost="${OPTARG}" ;; + 'o') versionfile="${OPTARG}" ;; + 'r') version="${OPTARG}" ;; + 'p') plain_version_string=true ;; + 't') top="${OPTARG}" ;; + '?') usage ;; + esac +done + +[ -n "${top}" ] || usage "The -t flag was not specified." + +curdir=`pwd` +cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"." + +# Determine the in-tree revision number. +versionstring="$(get_revision_string)" + +# Prepare the full toolchain version string. +toolchain_version="${elftcname} ${version} ${buildhost} ${versionstring}" + +cd ${curdir} || usage "Cannot change back to ${curdir}." + +# Create the file content. +tmpfile=`mktemp ${TMPDIR:-/tmp}/MV.XXXXXXX` +trap "rm -f ${tmpfile};" 0 1 2 3 15 + +if [ -n "${plain_version_string}" ]; then + echo ${toolchain_version} > ${tmpfile} +else + # Create a source file. + cat > ${tmpfile} < +#include + +const char * +elftc_version(void) +{ + return "${toolchain_version}"; +} +EOF +fi + +# Only replace the output file if its content changed. +if ! cmp -s ${tmpfile} ${versionfile}; then + echo "@ ${progname}: building \"${versionfile}\"." + cp ${tmpfile} ${versionfile} || exit ${?} +fi diff --git a/contrib/elftoolchain/libelftc/os.FreeBSD.mk b/contrib/elftoolchain/libelftc/os.FreeBSD.mk new file mode 100644 index 0000000000..8079a5b4f2 --- /dev/null +++ b/contrib/elftoolchain/libelftc/os.FreeBSD.mk @@ -0,0 +1,7 @@ +# +# Building for a FreeBSD target. +# +# $Id: os.freebsd.mk 189 2008-07-20 10:38:08Z jkoshy $ + +# Symbol versioning support [FreeBSD 7.X and later] +VERSION_MAP= ${.CURDIR}/Version.map diff --git a/contrib/elftoolchain/libelftc/os.Linux.mk b/contrib/elftoolchain/libelftc/os.Linux.mk new file mode 100644 index 0000000000..d99117d491 --- /dev/null +++ b/contrib/elftoolchain/libelftc/os.Linux.mk @@ -0,0 +1,3 @@ +# $Id: os.Linux.mk 3210 2015-05-17 13:40:49Z kaiwang27 $ + +CFLAGS+= -Wall -D_GNU_SOURCE diff --git a/contrib/elftoolchain/libelftc/os.NetBSD.mk b/contrib/elftoolchain/libelftc/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/libelftc/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/libpe/Makefile b/contrib/elftoolchain/libpe/Makefile new file mode 100644 index 0000000000..f734139962 --- /dev/null +++ b/contrib/elftoolchain/libpe/Makefile @@ -0,0 +1,32 @@ +# $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $ + +TOP= .. + +LIB= pe + +SRCS= libpe_buffer.c \ + libpe_coff.c \ + libpe_dos.c \ + libpe_init.c \ + libpe_rich.c \ + libpe_section.c \ + libpe_utils.c \ + pe_buffer.c \ + pe_cntl.c \ + pe_coff.c \ + pe_dos.c \ + pe_flag.c \ + pe_init.c \ + pe_rich.c \ + pe_section.c \ + pe_symtab.c \ + pe_update.c + +INCS= libpe.h pe.h +INCSDIR= /usr/include + +SHLIB_MAJOR= 1 + +WARNS?= 6 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libpe/_libpe.h b/contrib/elftoolchain/libpe/_libpe.h new file mode 100644 index 0000000000..1a83a67419 --- /dev/null +++ b/contrib/elftoolchain/libpe/_libpe.h @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $ + */ + +#ifndef __LIBPE_H_ +#define __LIBPE_H_ + +#include +#include + +#include "libpe.h" + +#include "_elftc.h" + +typedef struct _PE_SecBuf { + PE_Buffer sb_pb; /* application buffer */ + PE_Scn *sb_ps; /* PE_Scn pointer */ + unsigned int sb_flags; /* buffer flags */ + STAILQ_ENTRY(_PE_SecBuf) sb_next; +} PE_SecBuf; + +struct _PE_Scn { + PE *ps_pe; /* PE descriptor */ + PE_SecHdr ps_sh; /* section header */ + unsigned int ps_ndx; /* 1-based section index */ + unsigned int ps_flags; /* section flags */ + unsigned int ps_falign; /* section file alignment */ + STAILQ_HEAD(, _PE_SecBuf) ps_b; /* buffer list */ + STAILQ_ENTRY(_PE_Scn) ps_next; +}; + +struct _PE { + int pe_fd; /* file descriptor */ + PE_Cmd pe_cmd; /* open mode */ + PE_Object pe_obj; /* PE32/PE32+/COFF */ + size_t pe_fsize; /* file size */ + unsigned int pe_flags; /* library flags */ + PE_DosHdr *pe_dh; /* MS-DOS header */ + char *pe_stub; /* MS-DOS stub */ + size_t pe_stub_ex; /* MS-DOS stub len (exclude hdr) */ + char *pe_stub_app; /* MS-DOS stub (app supplied) */ + size_t pe_stub_app_sz; /* MS-DOS stub len (app supplied) */ + PE_RichHdr *pe_rh; /* rich header */ + char *pe_rh_start; /* pointer to rich header */ + PE_CoffHdr *pe_ch; /* COFF header */ + PE_OptHdr *pe_oh; /* optional header */ + PE_DataDir *pe_dd; /* data directories */ + unsigned int pe_nscn; /* num. of sections */ + char *pe_symtab; /* COFF symbol table */ + size_t pe_symbtab_sz; /* size of symbol table */ + unsigned int pe_nsym; /* num. of symbols */ + unsigned int pe_rvamax; /* maximum RVA */ + STAILQ_HEAD(, _PE_Scn) pe_scn; /* section list */ +}; + +/* Library internal flags */ +#define LIBPE_F_API_MASK 0x000FFFU +#define LIBPE_F_SPECIAL_FILE 0x001000U +#define LIBPE_F_BAD_DOS_HEADER 0x002000U +#define LIBPE_F_BAD_PE_HEADER 0x004000U +#define LIBPE_F_BAD_COFF_HEADER 0x008000U +#define LIBPE_F_BAD_OPT_HEADER 0x010000U +#define LIBPE_F_BAD_SEC_HEADER 0x020000U +#define LIBPE_F_LOAD_DOS_STUB 0x040000U +#define LIBPE_F_FD_DONE 0x080000U +#define LIBPE_F_DIRTY_DOS_HEADER 0x100000U +#define LIBPE_F_DIRTY_COFF_HEADER 0x200000U +#define LIBPE_F_DIRTY_OPT_HEADER 0x400000U +#define LIBPE_F_DIRTY_SEC_HEADER 0x800000U + +/* Internal section flags */ +#define LIBPE_F_LOAD_SECTION 0x1000U +#define LIBPE_F_STRIP_SECTION 0x2000U + +/* Internal buffer flags */ +#define LIBPE_F_BUFFER_MALLOCED 0x1000U + +/* Library internal defines */ +#define PE_DOS_MAGIC 0x5a4dU +#define PE_RICH_TEXT "Rich" +#define PE_RICH_HIDDEN 0x536e6144U /* DanS */ +#define PE_SIGNATURE 0x4550U /* PE\0\0 */ +#define PE_COFF_OPT_SIZE_32 224 +#define PE_COFF_OPT_SIZE_32P 240 +#define PE_SYM_ENTRY_SIZE 18 + +/* Encode/Decode macros */ +#if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) +static __inline uint16_t +le16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[1] << 8) | p[0]); +} + +static __inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static __inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +static __inline void +le16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; +} + +static __inline void +le32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; +} + +static __inline void +le64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + le32enc(p, (uint32_t)(u & 0xffffffffU)); + le32enc(p + 4, (uint32_t)(u >> 32)); +} +#endif /* ELFTC_NEED_BYTEORDER_EXTENSIONS */ + +#define PE_READ16(p,v) do { \ + (v) = le16dec((p)); \ + (p) += 2; \ +} while(0) + +#define PE_READ32(p,v) do { \ + (v) = le32dec((p)); \ + (p) += 4; \ +} while(0) + +#define PE_WRITE16(p,v) do { \ + le16enc((p), (v)); \ + (p) += 2; \ +} while(0) + +#define PE_WRITE32(p,v) do { \ + le32enc((p), (v)); \ + (p) += 4; \ +} while(0) + + +/* Internal function declarations */ +off_t libpe_align(PE *, off_t, size_t); +PE_SecBuf *libpe_alloc_buffer(PE_Scn *, size_t); +PE_Scn *libpe_alloc_scn(PE *); +int libpe_load_all_sections(PE *); +int libpe_load_section(PE *, PE_Scn *); +int libpe_open_object(PE *); +int libpe_pad(PE *, size_t); +int libpe_parse_msdos_header(PE *, char *); +int libpe_parse_coff_header(PE *, char *); +int libpe_parse_rich_header(PE *); +int libpe_parse_section_headers(PE *); +int libpe_read_msdos_stub(PE *); +void libpe_release_buffer(PE_SecBuf *); +void libpe_release_object(PE *); +void libpe_release_scn(PE_Scn *); +size_t libpe_resync_buffers(PE_Scn *); +int libpe_resync_sections(PE *, off_t); +int libpe_write_buffers(PE_Scn *); +off_t libpe_write_coff_header(PE *, off_t); +off_t libpe_write_msdos_stub(PE *, off_t); +off_t libpe_write_pe_header(PE *, off_t); +off_t libpe_write_sections(PE *, off_t); +off_t libpe_write_section_headers(PE *, off_t); + +#endif /* !__LIBPE_H_ */ diff --git a/contrib/elftoolchain/libpe/libpe.h b/contrib/elftoolchain/libpe/libpe.h new file mode 100644 index 0000000000..3cec39a8f5 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $ + */ + +#ifndef _LIBPE_H_ +#define _LIBPE_H_ + +#include + +#include "pe.h" + +/* Library private data structures */ +typedef struct _PE PE; +typedef struct _PE_Scn PE_Scn; + +/* Section buffers */ +typedef struct PE_Buffer { + unsigned int pb_align; + off_t pb_off; + size_t pb_size; + void *pb_buf; +} PE_Buffer; + +/* Object types */ +typedef enum { + PE_O_UNKNOWN = 0, + PE_O_PE32, + PE_O_PE32P, + PE_O_COFF, +} PE_Object; + +/* Commands */ +typedef enum { + PE_C_NULL = 0, + PE_C_CLR, + PE_C_FDDONE, + PE_C_FDREAD, + PE_C_RDWR, + PE_C_READ, + PE_C_SET, + PE_C_WRITE, + PE_C_NUM +} PE_Cmd; + +/* Flags defined by the API. */ +#define PE_F_DIRTY 0x001U +#define PE_F_STRIP_DOS_STUB 0x002U +#define PE_F_STRIP_RICH_HEADER 0x004U +#define PE_F_STRIP_SYMTAB 0x008U +#define PE_F_STRIP_DEBUG 0x010U +#define PE_F_STRIP_SECTION 0x020U + +#ifdef __cplusplus +extern "C" { +#endif + +PE_CoffHdr *pe_coff_header(PE *); +int pe_cntl(PE *, PE_Cmd); +PE_DataDir *pe_data_dir(PE *); +void pe_finish(PE *); +int pe_flag(PE *, PE_Cmd, unsigned int); +int pe_flag_buffer(PE_Buffer *, PE_Cmd, unsigned int); +int pe_flag_coff_header(PE *, PE_Cmd, unsigned int); +int pe_flag_data_dir(PE *, PE_Cmd, unsigned int); +int pe_flag_dos_header(PE *, PE_Cmd, unsigned int); +int pe_flag_opt_header(PE *, PE_Cmd, unsigned int); +int pe_flag_section_header(PE_Scn *, PE_Cmd, unsigned int); +int pe_flag_scn(PE_Scn *, PE_Cmd, unsigned int); +PE_Buffer *pe_getbuffer(PE_Scn *, PE_Buffer *); +PE_Scn *pe_getscn(PE *, size_t); +PE *pe_init(int, PE_Cmd, PE_Object); +PE_Scn *pe_insertscn(PE *, size_t); +PE_DosHdr *pe_msdos_header(PE *); +char *pe_msdos_stub(PE *, size_t *); +size_t pe_ndxscn(PE_Scn *); +PE_Buffer *pe_newbuffer(PE_Scn *); +PE_Scn *pe_newscn(PE *); +PE_Scn *pe_nextscn(PE *, PE_Scn *); +PE_Object pe_object(PE *); +PE_OptHdr *pe_opt_header(PE *); +PE_RichHdr *pe_rich_header(PE *); +int pe_rich_header_validate(PE *); +PE_SecHdr *pe_section_header(PE_Scn *); +off_t pe_update(PE *); +int pe_update_coff_header(PE *, PE_CoffHdr *); +int pe_update_opt_header(PE *, PE_OptHdr *); +int pe_update_data_dir(PE *, PE_DataDir *); +int ps_update_msdos_header(PE *, PE_DosHdr *); +int ps_update_msdos_stub(PE *, char *, size_t); +int pe_update_section_header(PE_Scn *, PE_SecHdr *); +int pe_update_symtab(PE *, char *, size_t, unsigned int); + +#ifdef __cplusplus +} +#endif + +#endif /* !_LIBPE_H_ */ diff --git a/contrib/elftoolchain/libpe/libpe_buffer.c b/contrib/elftoolchain/libpe/libpe_buffer.c new file mode 100644 index 0000000000..cc633dd04e --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_buffer.c @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_SecBuf * +libpe_alloc_buffer(PE_Scn *ps, size_t sz) +{ + PE_SecBuf *sb; + + if ((sb = malloc(sizeof(PE_SecBuf))) == NULL) { + errno = ENOMEM; + return (NULL); + } + + sb->sb_ps = ps; + sb->sb_flags = 0; + sb->sb_pb.pb_align = 1; + sb->sb_pb.pb_off = 0; + sb->sb_pb.pb_size = sz; + if (sz > 0) { + if ((sb->sb_pb.pb_buf = malloc(sz)) == NULL) { + free(sb); + errno = ENOMEM; + return (NULL); + } + sb->sb_flags |= LIBPE_F_BUFFER_MALLOCED; + } else + sb->sb_pb.pb_buf = NULL; + + STAILQ_INSERT_TAIL(&ps->ps_b, sb, sb_next); + + return (sb); +} + +void +libpe_release_buffer(PE_SecBuf *sb) +{ + PE_Scn *ps; + + assert(sb != NULL); + + ps = sb->sb_ps; + + STAILQ_REMOVE(&ps->ps_b, sb, _PE_SecBuf, sb_next); + + if (sb->sb_flags & LIBPE_F_BUFFER_MALLOCED) + free(sb->sb_pb.pb_buf); + + free(sb); +} + +static int +cmp_sb(PE_SecBuf *a, PE_SecBuf *b) +{ + + if (a->sb_pb.pb_off < b->sb_pb.pb_off) + return (-1); + else if (a->sb_pb.pb_off == b->sb_pb.pb_off) + return (0); + else + return (1); +} + +static void +sort_buffers(PE_Scn *ps) +{ + + if (STAILQ_EMPTY(&ps->ps_b)) + return; + + STAILQ_SORT(&ps->ps_b, _PE_SecBuf, sb_next, cmp_sb); +} + +size_t +libpe_resync_buffers(PE_Scn *ps) +{ + PE_SecBuf *sb; + PE_Buffer *pb; + size_t sz; + + assert(ps->ps_flags & LIBPE_F_LOAD_SECTION); + + sort_buffers(ps); + + sz = 0; + STAILQ_FOREACH(sb, &ps->ps_b, sb_next) { + if (ps->ps_flags & PE_F_DIRTY) + sb->sb_flags |= PE_F_DIRTY; + + pb = (PE_Buffer *) sb; + if (pb->pb_align > ps->ps_falign) + pb->pb_align = ps->ps_falign; + if (pb->pb_buf == NULL || pb->pb_size == 0) + continue; + + sz = roundup(sz, pb->pb_align); + + if (pb->pb_off != (off_t) sz) { + pb->pb_off = sz; + sb->sb_flags |= PE_F_DIRTY; + } + sz += pb->pb_size; + } + + return (sz); +} + +int +libpe_write_buffers(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb; + PE_Buffer *pb; + off_t off; + + assert(ps->ps_flags & LIBPE_F_LOAD_SECTION); + + pe = ps->ps_pe; + + off = 0; + STAILQ_FOREACH(sb, &ps->ps_b, sb_next) { + pb = &sb->sb_pb; + if (pb->pb_buf == NULL || pb->pb_size == 0) + continue; + + if ((sb->sb_flags & PE_F_DIRTY) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, (off_t) pb->pb_size, SEEK_CUR) < + 0) { + errno = EIO; + return (-1); + } + goto next_buf; + } + + if (pb->pb_off > off) { + if (libpe_pad(pe, pb->pb_off - off) < 0) + return (-1); + off = pb->pb_off; + } + + if (write(pe->pe_fd, pb->pb_buf, pb->pb_size) != + (ssize_t) pb->pb_size) { + errno = EIO; + return (-1); + } + + next_buf: + off += pb->pb_size; + } + + return (0); +} diff --git a/contrib/elftoolchain/libpe/libpe_coff.c b/contrib/elftoolchain/libpe/libpe_coff.c new file mode 100644 index 0000000000..e161f7c718 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_coff.c @@ -0,0 +1,535 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_coff.c 3326 2016-01-16 17:46:17Z kaiwang27 $"); + +int +libpe_parse_coff_header(PE *pe, char *hdr) +{ + char tmp[128]; + PE_CoffHdr *ch; + PE_OptHdr *oh; + PE_DataDir *dd; + unsigned p, r, s; + int i; + + if ((ch = malloc(sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + + PE_READ16(hdr, ch->ch_machine); + PE_READ16(hdr, ch->ch_nsec); + PE_READ32(hdr, ch->ch_timestamp); + PE_READ32(hdr, ch->ch_symptr); + PE_READ32(hdr, ch->ch_nsym); + PE_READ16(hdr, ch->ch_optsize); + PE_READ16(hdr, ch->ch_char); + + pe->pe_ch = ch; + + /* + * The Optional header is omitted for object files. + */ + if (ch->ch_optsize == 0) + return (libpe_parse_section_headers(pe)); + + if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_oh = oh; + +#define READ_OPT(n) \ + do { \ + /* \ + * Since the Optional Header size is variable, we must \ + * check if the requested read size will overrun the \ + * remaining header bytes. \ + */ \ + if (p + (n) > ch->ch_optsize) { \ + /* Consume the "extra" bytes */ \ + r = ch->ch_optsize - p; \ + if (read(pe->pe_fd, tmp, r) != (ssize_t) r) { \ + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER;\ + return (0); \ + } \ + return (libpe_parse_section_headers(pe)); \ + } \ + if (read(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \ + pe->pe_flags |= LIBPE_F_BAD_OPT_HEADER; \ + return (0); \ + } \ + p += (n); \ + } while (0) +#define READ_OPT8(v) do { READ_OPT(1); (v) = *tmp; } while(0) +#define READ_OPT16(v) do { READ_OPT(2); (v) = le16dec(tmp); } while(0) +#define READ_OPT32(v) do { READ_OPT(4); (v) = le32dec(tmp); } while(0) +#define READ_OPT64(v) do { READ_OPT(8); (v) = le64dec(tmp); } while(0) + + /* + * Read in the Optional header. Size of some fields are depending + * on the PE format specified by the oh_magic field. (PE32 or PE32+) + */ + + p = 0; + READ_OPT16(oh->oh_magic); + if (oh->oh_magic == PE_FORMAT_32P) + pe->pe_obj = PE_O_PE32P; + READ_OPT8(oh->oh_ldvermajor); + READ_OPT8(oh->oh_ldverminor); + READ_OPT32(oh->oh_textsize); + READ_OPT32(oh->oh_datasize); + READ_OPT32(oh->oh_bsssize); + READ_OPT32(oh->oh_entry); + READ_OPT32(oh->oh_textbase); + if (oh->oh_magic != PE_FORMAT_32P) { + READ_OPT32(oh->oh_database); + READ_OPT32(oh->oh_imgbase); + } else + READ_OPT64(oh->oh_imgbase); + READ_OPT32(oh->oh_secalign); + READ_OPT32(oh->oh_filealign); + READ_OPT16(oh->oh_osvermajor); + READ_OPT16(oh->oh_osverminor); + READ_OPT16(oh->oh_imgvermajor); + READ_OPT16(oh->oh_imgverminor); + READ_OPT16(oh->oh_subvermajor); + READ_OPT16(oh->oh_subverminor); + READ_OPT32(oh->oh_win32ver); + READ_OPT32(oh->oh_imgsize); + READ_OPT32(oh->oh_hdrsize); + READ_OPT32(oh->oh_checksum); + READ_OPT16(oh->oh_subsystem); + READ_OPT16(oh->oh_dllchar); + if (oh->oh_magic != PE_FORMAT_32P) { + READ_OPT32(oh->oh_stacksizer); + READ_OPT32(oh->oh_stacksizec); + READ_OPT32(oh->oh_heapsizer); + READ_OPT32(oh->oh_heapsizec); + } else { + READ_OPT64(oh->oh_stacksizer); + READ_OPT64(oh->oh_stacksizec); + READ_OPT64(oh->oh_heapsizer); + READ_OPT64(oh->oh_heapsizec); + } + READ_OPT32(oh->oh_ldrflags); + READ_OPT32(oh->oh_ndatadir); + + /* + * Read in the Data Directories. + */ + + if (oh->oh_ndatadir > 0) { + if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dd = dd; + + dd->dd_total = oh->oh_ndatadir < PE_DD_MAX ? oh->oh_ndatadir : + PE_DD_MAX; + + for (i = 0; (uint32_t) i < dd->dd_total; i++) { + READ_OPT32(dd->dd_e[i].de_addr); + READ_OPT32(dd->dd_e[i].de_size); + } + } + + /* Consume the remaining bytes in the Optional header, if any. */ + if (ch->ch_optsize > p) { + r = ch->ch_optsize - p; + for (; r > 0; r -= s) { + s = r > sizeof(tmp) ? sizeof(tmp) : r; + if (read(pe->pe_fd, tmp, s) != (ssize_t) s) { + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER; + return (0); + } + } + } + + return (libpe_parse_section_headers(pe)); +} + +off_t +libpe_write_pe_header(PE *pe, off_t off) +{ + char tmp[4]; + + if (pe->pe_cmd == PE_C_RDWR && + (pe->pe_flags & LIBPE_F_BAD_PE_HEADER) == 0) { + assert(pe->pe_dh != NULL); + off = lseek(pe->pe_fd, (off_t) pe->pe_dh->dh_lfanew + 4, + SEEK_SET); + return (off); + } + + /* + * PE Header should to be aligned on 8-byte boundary according to + * the PE/COFF specification. + */ + if ((off = libpe_align(pe, off, 8)) < 0) + return (-1); + + le32enc(tmp, PE_SIGNATURE); + if (write(pe->pe_fd, tmp, sizeof(tmp)) != (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + + off += 4; + + pe->pe_flags &= ~LIBPE_F_BAD_PE_HEADER; + + /* Trigger rewrite for the following headers. */ + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (off); +} + +off_t +libpe_write_coff_header(PE *pe, off_t off) +{ + char tmp[128], *hdr; + PE_CoffHdr *ch; + PE_DataDir *dd; + PE_OptHdr *oh; + PE_Scn *ps; + PE_SecHdr *sh; + unsigned p; + uint32_t reloc_rva, reloc_sz; + int i, reloc; + + reloc = 0; + reloc_rva = reloc_sz = 0; + + if (pe->pe_cmd == PE_C_RDWR) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + + if ((pe->pe_flags & LIBPE_F_DIRTY_COFF_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_COFF_HEADER) == 0) { + if (lseek(pe->pe_fd, (off_t) sizeof(PE_CoffHdr), + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += sizeof(PE_CoffHdr); + assert(pe->pe_ch != NULL); + ch = pe->pe_ch; + goto coff_done; + } + + /* lseek(2) to the offset of the COFF header. */ + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + if (pe->pe_ch == NULL) { + if ((ch = calloc(1, sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_ch = ch; + + /* + * Default value for ch_machine if not provided by the + * application. + */ + if (pe->pe_obj == PE_O_PE32P) + ch->ch_machine = IMAGE_FILE_MACHINE_AMD64; + else + ch->ch_machine = IMAGE_FILE_MACHINE_I386; + + } else + ch = pe->pe_ch; + + if (!ch->ch_timestamp) + ch->ch_timestamp = time(NULL); + + if (pe->pe_obj == PE_O_PE32) { + if (!ch->ch_optsize) + ch->ch_optsize = PE_COFF_OPT_SIZE_32; + ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE | + IMAGE_FILE_32BIT_MACHINE; + } else if (pe->pe_obj == PE_O_PE32P) { + if (!ch->ch_optsize) + ch->ch_optsize = PE_COFF_OPT_SIZE_32P; + ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE | + IMAGE_FILE_LARGE_ADDRESS_AWARE; + } else + ch->ch_optsize = 0; + + /* + * COFF line number is deprecated by the PE/COFF + * specification. COFF symbol table is deprecated + * for executables. + */ + ch->ch_char |= IMAGE_FILE_LINE_NUMS_STRIPPED; + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) + ch->ch_char |= IMAGE_FILE_LOCAL_SYMS_STRIPPED; + + ch->ch_nsec = pe->pe_nscn; + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + + if (ps->ps_ndx == 0xFFFFFFFFU) { + ch->ch_symptr = sh->sh_rawptr; + ch->ch_nsym = pe->pe_nsym; + } + + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) { + if (ps->ps_ndx == (0xFFFF0000 | PE_DD_BASERELOC) || + strncmp(sh->sh_name, ".reloc", strlen(".reloc")) == + 0) { + reloc = 1; + reloc_rva = sh->sh_addr; + reloc_sz = sh->sh_virtsize; + } + } + } + + if (!reloc) + ch->ch_char |= IMAGE_FILE_RELOCS_STRIPPED; + + if (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) { + if (pe->pe_obj == PE_O_PE32) + ch->ch_optsize = PE_COFF_OPT_SIZE_32; + else if (pe->pe_obj == PE_O_PE32P) + ch->ch_optsize = PE_COFF_OPT_SIZE_32P; + else + ch->ch_optsize = 0; + } + + /* + * Write the COFF header. + */ + hdr = tmp; + PE_WRITE16(hdr, ch->ch_machine); + PE_WRITE16(hdr, ch->ch_nsec); + PE_WRITE32(hdr, ch->ch_timestamp); + PE_WRITE32(hdr, ch->ch_symptr); + PE_WRITE32(hdr, ch->ch_nsym); + PE_WRITE16(hdr, ch->ch_optsize); + PE_WRITE16(hdr, ch->ch_char); + if (write(pe->pe_fd, tmp, sizeof(PE_CoffHdr)) != + (ssize_t) sizeof(PE_CoffHdr)) { + errno = EIO; + return (-1); + } + +coff_done: + off += sizeof(PE_CoffHdr); + pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_COFF_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + if (ch->ch_optsize == 0) + return (off); + + /* + * Write the Optional header. + */ + + if (pe->pe_cmd == PE_C_RDWR) { + if ((pe->pe_flags & LIBPE_F_DIRTY_OPT_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) == 0) { + if (lseek(pe->pe_fd, (off_t) ch->ch_optsize, + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += ch->ch_optsize; + return (off); + } + + } + + if (pe->pe_oh == NULL) { + if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_oh = oh; + } else + oh = pe->pe_oh; + + if (pe->pe_obj == PE_O_PE32) + oh->oh_magic = PE_FORMAT_32; + else + oh->oh_magic = PE_FORMAT_32P; + + /* + * LinkerVersion should not be less than 2.5, which will cause + * Windows to complain the executable is invalid in some case. + * By default we set LinkerVersion to 2.22 (binutils 2.22) + */ + if (!oh->oh_ldvermajor && !oh->oh_ldverminor) { + oh->oh_ldvermajor = 2; + oh->oh_ldverminor = 22; + } + + /* + * The library always tries to write out all 16 data directories + * but the actual data dir written will depend on ch_optsize. + */ + oh->oh_ndatadir = PE_DD_MAX; + + if (!oh->oh_filealign) + oh->oh_filealign = 0x200; + if (!oh->oh_secalign) + oh->oh_secalign = 0x1000; + oh->oh_hdrsize = roundup(off + ch->ch_optsize + pe->pe_nscn * + sizeof(PE_SecHdr), oh->oh_filealign); + oh->oh_imgsize = roundup(pe->pe_rvamax, oh->oh_secalign); + +#define WRITE_OPT(n) \ + do { \ + /* \ + * Since the Optional Header size is variable, we must \ + * check if the requested write size will overrun the \ + * remaining header bytes. \ + */ \ + if (p + (n) > ch->ch_optsize) { \ + /* Pad the "extra" bytes */ \ + if (libpe_pad(pe, ch->ch_optsize - p) < 0) { \ + errno = EIO; \ + return (-1); \ + } \ + goto opt_done; \ + } \ + if (write(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \ + errno = EIO; \ + return (-1); \ + } \ + p += (n); \ + } while (0) +#define WRITE_OPT8(v) do { *tmp = (v); WRITE_OPT(1); } while(0) +#define WRITE_OPT16(v) do { le16enc(tmp, (v)); WRITE_OPT(2); } while(0) +#define WRITE_OPT32(v) do { le32enc(tmp, (v)); WRITE_OPT(4); } while(0) +#define WRITE_OPT64(v) do { le64enc(tmp, (v)); WRITE_OPT(8); } while(0) + + p = 0; + WRITE_OPT16(oh->oh_magic); + if (oh->oh_magic == PE_FORMAT_32P) + pe->pe_obj = PE_O_PE32P; + WRITE_OPT8(oh->oh_ldvermajor); + WRITE_OPT8(oh->oh_ldverminor); + WRITE_OPT32(oh->oh_textsize); + WRITE_OPT32(oh->oh_datasize); + WRITE_OPT32(oh->oh_bsssize); + WRITE_OPT32(oh->oh_entry); + WRITE_OPT32(oh->oh_textbase); + if (oh->oh_magic != PE_FORMAT_32P) { + WRITE_OPT32(oh->oh_database); + WRITE_OPT32(oh->oh_imgbase); + } else + WRITE_OPT64(oh->oh_imgbase); + WRITE_OPT32(oh->oh_secalign); + WRITE_OPT32(oh->oh_filealign); + WRITE_OPT16(oh->oh_osvermajor); + WRITE_OPT16(oh->oh_osverminor); + WRITE_OPT16(oh->oh_imgvermajor); + WRITE_OPT16(oh->oh_imgverminor); + WRITE_OPT16(oh->oh_subvermajor); + WRITE_OPT16(oh->oh_subverminor); + WRITE_OPT32(oh->oh_win32ver); + WRITE_OPT32(oh->oh_imgsize); + WRITE_OPT32(oh->oh_hdrsize); + WRITE_OPT32(oh->oh_checksum); + WRITE_OPT16(oh->oh_subsystem); + WRITE_OPT16(oh->oh_dllchar); + if (oh->oh_magic != PE_FORMAT_32P) { + WRITE_OPT32(oh->oh_stacksizer); + WRITE_OPT32(oh->oh_stacksizec); + WRITE_OPT32(oh->oh_heapsizer); + WRITE_OPT32(oh->oh_heapsizec); + } else { + WRITE_OPT64(oh->oh_stacksizer); + WRITE_OPT64(oh->oh_stacksizec); + WRITE_OPT64(oh->oh_heapsizer); + WRITE_OPT64(oh->oh_heapsizec); + } + WRITE_OPT32(oh->oh_ldrflags); + WRITE_OPT32(oh->oh_ndatadir); + + /* + * Write the Data Directories. + */ + + if (oh->oh_ndatadir > 0) { + if (pe->pe_dd == NULL) { + if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dd = dd; + dd->dd_total = PE_DD_MAX; + } else + dd = pe->pe_dd; + + assert(oh->oh_ndatadir <= PE_DD_MAX); + + if (reloc) { + dd->dd_e[PE_DD_BASERELOC].de_addr = reloc_rva; + dd->dd_e[PE_DD_BASERELOC].de_size = reloc_sz; + } + + for (i = 0; (uint32_t) i < dd->dd_total; i++) { + WRITE_OPT32(dd->dd_e[i].de_addr); + WRITE_OPT32(dd->dd_e[i].de_size); + } + } + + /* Pad the remaining bytes in the Optional header, if any. */ + if (ch->ch_optsize > p) { + if (libpe_pad(pe, ch->ch_optsize - p) < 0) { + errno = EIO; + return (-1); + } + } + +opt_done: + off += ch->ch_optsize; + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_OPT_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (off); +} diff --git a/contrib/elftoolchain/libpe/libpe_dos.c b/contrib/elftoolchain/libpe/libpe_dos.c new file mode 100644 index 0000000000..a48ad12415 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_dos.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +libpe_parse_msdos_header(PE *pe, char *hdr) +{ + PE_DosHdr *dh; + char coff[sizeof(PE_CoffHdr)]; + uint32_t pe_magic; + int i; + + if ((pe->pe_stub = malloc(sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + memcpy(pe->pe_stub, hdr, sizeof(PE_DosHdr)); + + if ((dh = malloc(sizeof(*dh))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dh = dh; + + /* Read the conventional MS-DOS EXE header. */ + memcpy(dh->dh_magic, hdr, 2); + hdr += 2; + PE_READ16(hdr, dh->dh_lastsize); + PE_READ16(hdr, dh->dh_nblock); + PE_READ16(hdr, dh->dh_nreloc); + PE_READ16(hdr, dh->dh_hdrsize); + PE_READ16(hdr, dh->dh_minalloc); + PE_READ16(hdr, dh->dh_maxalloc); + PE_READ16(hdr, dh->dh_ss); + PE_READ16(hdr, dh->dh_sp); + PE_READ16(hdr, dh->dh_checksum); + PE_READ16(hdr, dh->dh_ip); + PE_READ16(hdr, dh->dh_cs); + PE_READ16(hdr, dh->dh_relocpos); + PE_READ16(hdr, dh->dh_noverlay); + + /* Do not continue if the EXE is not a PE/NE/... (new executable) */ + if (dh->dh_relocpos != 0x40) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + for (i = 0; i < 4; i++) + PE_READ16(hdr, dh->dh_reserved1[i]); + PE_READ16(hdr, dh->dh_oemid); + PE_READ16(hdr, dh->dh_oeminfo); + for (i = 0; i < 10; i++) + PE_READ16(hdr, dh->dh_reserved2[i]); + PE_READ32(hdr, dh->dh_lfanew); + + /* Check if the e_lfanew pointer is valid. */ + if (dh->dh_lfanew > pe->pe_fsize - 4) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + if (dh->dh_lfanew < sizeof(PE_DosHdr) && + (pe->pe_flags & LIBPE_F_SPECIAL_FILE)) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + if (dh->dh_lfanew > sizeof(PE_DosHdr)) { + pe->pe_stub_ex = dh->dh_lfanew - sizeof(PE_DosHdr); + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + /* Read in DOS stub now. */ + if (libpe_read_msdos_stub(pe) < 0) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + } + } + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + /* Jump to the PE header. */ + if (lseek(pe->pe_fd, (off_t) dh->dh_lfanew, SEEK_SET) < 0) { + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + return (0); + } + } + + if (read(pe->pe_fd, &pe_magic, 4) != 4 || + htole32(pe_magic) != PE_SIGNATURE) { + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + return (0); + } + + if (read(pe->pe_fd, coff, sizeof(coff)) != (ssize_t) sizeof(coff)) { + pe->pe_flags |= LIBPE_F_BAD_COFF_HEADER; + return (0); + } + + return (libpe_parse_coff_header(pe, coff)); +} + +int +libpe_read_msdos_stub(PE *pe) +{ + void *m; + + assert(pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0); + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_SET) < + 0) { + errno = EIO; + goto fail; + } + } + + if ((m = realloc(pe->pe_stub, sizeof(PE_DosHdr) + pe->pe_stub_ex)) == + NULL) { + errno = ENOMEM; + goto fail; + } + pe->pe_stub = m; + + if (read(pe->pe_fd, pe->pe_stub + sizeof(PE_DosHdr), pe->pe_stub_ex) != + (ssize_t) pe->pe_stub_ex) { + errno = EIO; + goto fail; + } + + pe->pe_flags |= LIBPE_F_LOAD_DOS_STUB; + + /* Search for the Rich header embedded just before the PE header. */ + (void) libpe_parse_rich_header(pe); + + return (0); + +fail: + pe->pe_stub_ex = 0; + + return (-1); +} + +/* + * The "standard" MS-DOS stub displaying "This program cannot be run in + * DOS mode". + */ +static const char msdos_stub[] = { + '\x0e','\x1f','\xba','\x0e','\x00','\xb4','\x09','\xcd', + '\x21','\xb8','\x01','\x4c','\xcd','\x21','\x54','\x68', + '\x69','\x73','\x20','\x70','\x72','\x6f','\x67','\x72', + '\x61','\x6d','\x20','\x63','\x61','\x6e','\x6e','\x6f', + '\x74','\x20','\x62','\x65','\x20','\x72','\x75','\x6e', + '\x20','\x69','\x6e','\x20','\x44','\x4f','\x53','\x20', + '\x6d','\x6f','\x64','\x65','\x2e','\x0d','\x0d','\x0a', + '\x24','\x00','\x00','\x00','\x00','\x00','\x00','\x00', +}; + +static void +init_dos_header(PE_DosHdr *dh) +{ + + dh->dh_magic[0] = 'M'; + dh->dh_magic[1] = 'Z'; + dh->dh_lastsize = 144; + dh->dh_nblock = 3; + dh->dh_hdrsize = 4; + dh->dh_maxalloc = 65535; + dh->dh_sp = 184; + dh->dh_relocpos = 0x40; + dh->dh_lfanew = 0x80; +} + +off_t +libpe_write_msdos_stub(PE *pe, off_t off) +{ + PE_DosHdr *dh; + char tmp[sizeof(PE_DosHdr)], *hdr; + off_t d; + int i, strip_rich; + + strip_rich = 0; + + if (pe->pe_cmd == PE_C_RDWR) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + + if (pe->pe_dh != NULL && + (pe->pe_flags & PE_F_STRIP_DOS_STUB)) { + /* + * If we strip MS-DOS stub, everything after it + * needs rewritten. + */ + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + goto done; + } + + /* + * lseek(2) to the PE signature if MS-DOS stub is not + * modified. + */ + if (pe->pe_dh != NULL && + (pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 && + (pe->pe_flags & PE_F_STRIP_RICH_HEADER) == 0) { + if (lseek(pe->pe_fd, + (off_t) (sizeof(PE_DosHdr) + pe->pe_stub_ex), + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off = sizeof(PE_DosHdr) + pe->pe_stub_ex; + goto done; + } + + /* Check if we should strip the Rich header. */ + if (pe->pe_dh != NULL && pe->pe_stub_app == NULL && + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 && + (pe->pe_flags & PE_F_STRIP_RICH_HEADER)) { + if ((pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + (void) libpe_read_msdos_stub(pe); + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + if (pe->pe_rh != NULL) { + strip_rich = 1; + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + } + } + + /* + * If length of MS-DOS stub will change, Mark the PE + * signature is broken so that the PE signature and the + * headers follow it will be rewritten. + * + * The sections should be loaded now since the stub might + * overwrite the section data. + */ + if ((pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) || + (pe->pe_stub_app != NULL && pe->pe_stub_app_sz != + sizeof(PE_DosHdr) + pe->pe_stub_ex) || strip_rich) { + if (libpe_load_all_sections(pe) < 0) + return (-1); + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + } + } + + if (pe->pe_flags & PE_F_STRIP_DOS_STUB) + goto done; + + /* Always use application supplied MS-DOS stub, if exists. */ + if (pe->pe_stub_app != NULL && pe->pe_stub_app_sz > 0) { + if (write(pe->pe_fd, pe->pe_stub_app, pe->pe_stub_app_sz) != + (ssize_t) pe->pe_stub_app_sz) { + errno = EIO; + return (-1); + } + off = pe->pe_stub_app_sz; + goto done; + } + + /* + * Write MS-DOS header. + */ + + if (pe->pe_dh == NULL) { + if ((dh = calloc(1, sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dh = dh; + + init_dos_header(dh); + + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + } else + dh = pe->pe_dh; + + if (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) + init_dos_header(dh); + + if (strip_rich) { + d = pe->pe_rh_start - pe->pe_stub; + dh->dh_lfanew = roundup(d, 8); + } + + if ((pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) || + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER)) { + memcpy(tmp, dh->dh_magic, 2); + hdr = tmp + 2; + PE_WRITE16(hdr, dh->dh_lastsize); + PE_WRITE16(hdr, dh->dh_nblock); + PE_WRITE16(hdr, dh->dh_nreloc); + PE_WRITE16(hdr, dh->dh_hdrsize); + PE_WRITE16(hdr, dh->dh_minalloc); + PE_WRITE16(hdr, dh->dh_maxalloc); + PE_WRITE16(hdr, dh->dh_ss); + PE_WRITE16(hdr, dh->dh_sp); + PE_WRITE16(hdr, dh->dh_checksum); + PE_WRITE16(hdr, dh->dh_ip); + PE_WRITE16(hdr, dh->dh_cs); + PE_WRITE16(hdr, dh->dh_relocpos); + PE_WRITE16(hdr, dh->dh_noverlay); + for (i = 0; i < 4; i++) + PE_WRITE16(hdr, dh->dh_reserved1[i]); + PE_WRITE16(hdr, dh->dh_oemid); + PE_WRITE16(hdr, dh->dh_oeminfo); + for (i = 0; i < 10; i++) + PE_WRITE16(hdr, dh->dh_reserved2[i]); + PE_WRITE32(hdr, dh->dh_lfanew); + + if (write(pe->pe_fd, tmp, sizeof(tmp)) != + (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + } else { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_CUR) < + 0) { + errno = EIO; + return (-1); + } + } + + off = sizeof(PE_DosHdr); + + /* + * Write the MS-DOS stub. + */ + + if (strip_rich) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + assert(pe->pe_stub != NULL && pe->pe_rh_start != NULL); + d = pe->pe_rh_start - pe->pe_stub; + if (lseek(pe->pe_fd, d, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + off = d; + goto done; + } + + if (pe->pe_cmd == PE_C_RDWR) { + if (lseek(pe->pe_fd, (off_t) pe->pe_stub_ex, SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += pe->pe_stub_ex; + goto done; + } + + if (write(pe->pe_fd, msdos_stub, sizeof(msdos_stub)) != + (ssize_t) sizeof(msdos_stub)) { + errno = EIO; + return (-1); + } + off += sizeof(msdos_stub); + +done: + pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_DOS_HEADER; + + return (off); +} diff --git a/contrib/elftoolchain/libpe/libpe_init.c b/contrib/elftoolchain/libpe/libpe_init.c new file mode 100644 index 0000000000..2579774bf0 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_init.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +libpe_open_object(PE *pe) +{ + struct stat sb; + mode_t mode; + char magic[sizeof(PE_DosHdr)]; + + if (fstat(pe->pe_fd, &sb) < 0) + return (-1); + + mode = sb.st_mode; + pe->pe_fsize = (size_t) sb.st_size; + + /* Reject unsupported file types. */ + if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && + !S_ISSOCK(mode)) { + errno = EINVAL; + return (-1); + } + + /* Read/Write mode is not supported for non-regular file. */ + if (pe->pe_cmd == PE_C_RDWR && !S_ISREG(mode)) { + errno = EINVAL; + return (-1); + } + + /* The minimal file should at least contain a COFF header. */ + if (S_ISREG(mode) && pe->pe_fsize < sizeof(PE_CoffHdr)) { + errno = ENOENT; + return (-1); + } + + /* + * Search for MS-DOS header or COFF header. + */ + + if (read(pe->pe_fd, magic, 2) != 2) { + errno = EIO; + return (-1); + } + + if (magic[0] == 'M' && magic[1] == 'Z') { + pe->pe_obj = PE_O_PE32; + if (read(pe->pe_fd, &magic[2], sizeof(PE_DosHdr) - 2) != + (ssize_t) sizeof(PE_DosHdr) - 2) { + errno = EIO; + return (-1); + } + return (libpe_parse_msdos_header(pe, magic)); + + } else if (magic[0] == 'P' && magic[1] == 'E') { + if (read(pe->pe_fd, magic, 2) != 2) { + errno = EIO; + return (-1); + } + if (magic[0] == '\0' && magic[1] == '\0') { + pe->pe_obj = PE_O_PE32; + if (read(pe->pe_fd, magic, sizeof(PE_CoffHdr)) != + (ssize_t) sizeof(PE_CoffHdr)) { + errno = EIO; + return (-1); + } + return (libpe_parse_coff_header(pe, magic)); + } + errno = ENOENT; + return (-1); + + } else { + pe->pe_obj = PE_O_COFF; + if (read(pe->pe_fd, &magic[2], sizeof(PE_CoffHdr) - 2) != + (ssize_t) sizeof(PE_CoffHdr) - 2) { + errno = EIO; + return (-1); + } + return (libpe_parse_coff_header(pe, magic)); + } +} + +void +libpe_release_object(PE *pe) +{ + PE_Scn *ps, *_ps; + + if (pe->pe_dh) + free(pe->pe_dh); + + if (pe->pe_rh) { + free(pe->pe_rh->rh_compid); + free(pe->pe_rh->rh_cnt); + free(pe->pe_rh); + } + + if (pe->pe_ch) + free(pe->pe_ch); + + if (pe->pe_oh) + free(pe->pe_oh); + + if (pe->pe_dd) + free(pe->pe_dd); + + if (pe->pe_stub) + free(pe->pe_stub); + + STAILQ_FOREACH_SAFE(ps, &pe->pe_scn, ps_next, _ps) + libpe_release_scn(ps); + + free(pe); +} diff --git a/contrib/elftoolchain/libpe/libpe_rich.c b/contrib/elftoolchain/libpe/libpe_rich.c new file mode 100644 index 0000000000..4669a224d0 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_rich.c @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +static char * +memfind(char *s, const char *find, size_t slen, size_t flen) +{ + int i; + + if (slen == 0 || flen == 0 || flen > slen) + return (NULL); + + for (i = 0; (size_t) i <= slen - flen; i++) { + if (s[i] != find[0]) + continue; + if (flen == 1) + return (&s[i]); + if (memcmp(&s[i + 1], &find[1], flen - 1) == 0) + return (&s[i]); + } + + return (NULL); +} + +int +libpe_parse_rich_header(PE *pe) +{ + PE_RichHdr *rh; + char *p, *r, *s; + uint32_t x; + int found, i; + + assert(pe->pe_stub != NULL && pe->pe_stub_ex > 0); + + /* Search for the "Rich" keyword to locate the Rich header. */ + s = pe->pe_stub + sizeof(PE_DosHdr); + r = memfind(s, PE_RICH_TEXT, pe->pe_stub_ex, 4); + if (r == NULL || r + 8 > s + pe->pe_stub_ex) { + errno = ENOENT; + return (-1); + } + + if ((rh = calloc(1, sizeof(*rh))) == NULL) { + errno = ENOMEM; + return (-1); + } + + rh->rh_xor = le32dec(r + 4); /* Retrieve the "XOR mask" */ + + /* + * Search for the hidden keyword "DanS" by XOR the dwords before + * the "Rich" keyword with the XOR mask. + */ + found = 0; + for (p = r - 4; p >= s; p -= 4) { + x = le32dec(p) ^ rh->rh_xor; + if (x == PE_RICH_HIDDEN) { + found = 1; + break; + } + } + if (!found) { + free(rh); + errno = ENOENT; + return (-1); + } + + /* + * Found the "DanS" keyword, which is the start of the Rich header. + * The next step is to skip the first 16 bytes (DanS, XOR mask, + * XOR mask, XOR mask) and read the (compid,cnt) tuples. + */ + pe->pe_rh_start = p; + p += 16; + rh->rh_total = (r - p) / 8; + if ((rh->rh_compid = malloc(rh->rh_total * sizeof(*rh->rh_compid))) == + NULL) { + free(rh); + errno = ENOMEM; + return (-1); + } + if ((rh->rh_cnt = malloc(rh->rh_total * sizeof(*rh->rh_cnt))) == + NULL) { + free(rh->rh_compid); + free(rh); + errno = ENOMEM; + return (-1); + } + for (i = 0; (uint32_t) i < rh->rh_total; i++, p += 8) { + rh->rh_compid[i] = le32dec(p) ^ rh->rh_xor; + rh->rh_cnt[i] = le32dec(p + 4) ^ rh->rh_xor; + } + + pe->pe_rh = rh; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/libpe_section.c b/contrib/elftoolchain/libpe/libpe_section.c new file mode 100644 index 0000000000..bc1e6f633c --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_section.c @@ -0,0 +1,518 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_section.c 3446 2016-05-03 01:31:17Z emaste $"); + +PE_Scn * +libpe_alloc_scn(PE *pe) +{ + PE_Scn *ps; + + if ((ps = calloc(1, sizeof(PE_Scn))) == NULL) { + errno = ENOMEM; + return (NULL); + } + STAILQ_INIT(&ps->ps_b); + ps->ps_pe = pe; + + return (ps); +} + +void +libpe_release_scn(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb, *_sb; + + assert(ps != NULL); + + pe = ps->ps_pe; + + STAILQ_REMOVE(&pe->pe_scn, ps, _PE_Scn, ps_next); + + STAILQ_FOREACH_SAFE(sb, &ps->ps_b, sb_next, _sb) + libpe_release_buffer(sb); + + free(ps); +} + +static int +cmp_scn(PE_Scn *a, PE_Scn *b) +{ + + if (a->ps_sh.sh_addr < b->ps_sh.sh_addr) + return (-1); + else if (a->ps_sh.sh_addr == b->ps_sh.sh_addr) + return (0); + else + return (1); +} + +static void +sort_sections(PE *pe) +{ + + if (STAILQ_EMPTY(&pe->pe_scn)) + return; + + /* Sort the list of Scn by RVA in ascending order. */ + STAILQ_SORT(&pe->pe_scn, _PE_Scn, ps_next, cmp_scn); +} + +int +libpe_parse_section_headers(PE *pe) +{ + char tmp[sizeof(PE_SecHdr)], *hdr; + PE_Scn *ps; + PE_SecHdr *sh; + PE_CoffHdr *ch; + PE_DataDir *dd; + int found, i; + + assert(pe->pe_ch != NULL); + + for (i = 0; (uint16_t) i < pe->pe_ch->ch_nsec; i++) { + if (read(pe->pe_fd, tmp, sizeof(PE_SecHdr)) != + (ssize_t) sizeof(PE_SecHdr)) { + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER; + return (0); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = ++pe->pe_nscn; /* Setion index is 1-based */ + sh = &ps->ps_sh; + + /* + * Note that the section name won't be NUL-terminated if + * its length happens to be 8. + */ + memcpy(sh->sh_name, tmp, sizeof(sh->sh_name)); + hdr = tmp + 8; + PE_READ32(hdr, sh->sh_virtsize); + PE_READ32(hdr, sh->sh_addr); + PE_READ32(hdr, sh->sh_rawsize); + PE_READ32(hdr, sh->sh_rawptr); + PE_READ32(hdr, sh->sh_relocptr); + PE_READ32(hdr, sh->sh_lineptr); + PE_READ16(hdr, sh->sh_nreloc); + PE_READ16(hdr, sh->sh_nline); + PE_READ32(hdr, sh->sh_char); + } + + /* + * For all the data directories that don't belong to any section, + * we create pseudo sections for them to make layout easier. + */ + dd = pe->pe_dd; + if (dd != NULL && dd->dd_total > 0) { + for (i = 0; (uint32_t) i < pe->pe_dd->dd_total; i++) { + if (dd->dd_e[i].de_size == 0) + continue; + found = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + if (dd->dd_e[i].de_addr >= sh->sh_addr && + dd->dd_e[i].de_addr + dd->dd_e[i].de_size <= + sh->sh_addr + sh->sh_virtsize) { + found = 1; + break; + } + } + if (found) + continue; + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFF0000U | i; + sh = &ps->ps_sh; + sh->sh_rawptr = dd->dd_e[i].de_addr; /* FIXME */ + sh->sh_rawsize = dd->dd_e[i].de_size; + } + } + + /* + * Also consider the COFF symbol table as a pseudo section. + */ + ch = pe->pe_ch; + if (ch->ch_nsym > 0) { + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFFFFFFU; + sh = &ps->ps_sh; + sh->sh_rawptr = ch->ch_symptr; + sh->sh_rawsize = ch->ch_nsym * PE_SYM_ENTRY_SIZE; + pe->pe_nsym = ch->ch_nsym; + } + + /* PE file headers initialization is complete if we reach here. */ + return (0); +} + +int +libpe_load_section(PE *pe, PE_Scn *ps) +{ + PE_SecHdr *sh; + PE_SecBuf *sb; + size_t sz; + char tmp[4]; + + assert(pe != NULL && ps != NULL); + assert((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0); + + sh = &ps->ps_sh; + + /* Allocate a PE_SecBuf struct without buffer for empty sections. */ + if (sh->sh_rawsize == 0) { + (void) libpe_alloc_buffer(ps, 0); + ps->ps_flags |= LIBPE_F_LOAD_SECTION; + return (0); + } + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + if (lseek(pe->pe_fd, (off_t) sh->sh_rawptr, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + if ((sb = libpe_alloc_buffer(ps, sh->sh_rawsize)) == NULL) + return (-1); + + if (read(pe->pe_fd, sb->sb_pb.pb_buf, sh->sh_rawsize) != + (ssize_t) sh->sh_rawsize) { + errno = EIO; + return (-1); + } + + if (ps->ps_ndx == 0xFFFFFFFFU) { + /* + * Index 0xFFFFFFFF indicates this section is a pseudo + * section that contains the COFF symbol table. We should + * read in the string table right after it. + */ + if (read(pe->pe_fd, tmp, sizeof(tmp)) != + (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + sz = le32dec(tmp); + + /* + * The minimum value for the size field is 4, which indicates + * there is no string table. + */ + if (sz > 4) { + sz -= 4; + if ((sb = libpe_alloc_buffer(ps, sz)) == NULL) + return (-1); + if (read(pe->pe_fd, sb->sb_pb.pb_buf, sz) != + (ssize_t) sz) { + errno = EIO; + return (-1); + } + } + } + + ps->ps_flags |= LIBPE_F_LOAD_SECTION; + + return (0); +} + +int +libpe_load_all_sections(PE *pe) +{ + PE_Scn *ps; + PE_SecHdr *sh; + unsigned r, s; + off_t off; + char tmp[256]; + + /* Calculate the current offset into the file. */ + off = 0; + if (pe->pe_dh != NULL) + off += pe->pe_dh->dh_lfanew + 4; + if (pe->pe_ch != NULL) + off += sizeof(PE_CoffHdr) + pe->pe_ch->ch_optsize; + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_LOAD_SECTION) + continue; + sh = &ps->ps_sh; + + /* + * For special files, we consume the padding in between + * and advance to the section offset. + */ + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + /* Can't go backwards. */ + if (off > sh->sh_rawptr) { + errno = EIO; + return (-1); + } + if (off < sh->sh_rawptr) { + r = sh->sh_rawptr - off; + for (; r > 0; r -= s) { + s = r > sizeof(tmp) ? sizeof(tmp) : r; + if (read(pe->pe_fd, tmp, s) != + (ssize_t) s) { + errno = EIO; + return (-1); + } + } + } + } + + /* Load the section content. */ + if (libpe_load_section(pe, ps) < 0) + return (-1); + } + + return (0); +} + +int +libpe_resync_sections(PE *pe, off_t off) +{ + PE_Scn *ps; + PE_SecHdr *sh; + size_t falign, nsec; + + /* Firstly, sort all sections by their file offsets. */ + sort_sections(pe); + + /* Count the number of sections. */ + nsec = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + if (ps->ps_ndx & 0xFFFF0000U) + continue; + nsec++; + } + pe->pe_nscn = nsec; + + /* + * Calculate the file offset for the first section. (`off' is + * currently pointing to the COFF header.) + */ + off += sizeof(PE_CoffHdr); + if (pe->pe_ch != NULL && pe->pe_ch->ch_optsize > 0) + off += pe->pe_ch->ch_optsize; + else { + switch (pe->pe_obj) { + case PE_O_PE32: + off += PE_COFF_OPT_SIZE_32; + break; + case PE_O_PE32P: + off += PE_COFF_OPT_SIZE_32P; + break; + case PE_O_COFF: + default: + break; + } + } + off += nsec * sizeof(PE_SecHdr); + + /* + * Determine the file alignment for sections. + */ + if (pe->pe_oh != NULL && pe->pe_oh->oh_filealign > 0) + falign = pe->pe_oh->oh_filealign; + else { + /* + * Use the default file alignment defined by the + * PE/COFF specification. + */ + if (pe->pe_obj == PE_O_COFF) + falign = 4; + else + falign = 512; + } + + /* + * Step through each section (and pseduo section) and verify + * alignment constraint and overlapping, make adjustment if need. + */ + pe->pe_rvamax = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + + sh = &ps->ps_sh; + + if (sh->sh_addr + sh->sh_virtsize > pe->pe_rvamax) + pe->pe_rvamax = sh->sh_addr + sh->sh_virtsize; + + if (ps->ps_ndx & 0xFFFF0000U) + ps->ps_falign = 4; + else + ps->ps_falign = falign; + + off = roundup(off, ps->ps_falign); + + if (off != sh->sh_rawptr) + ps->ps_flags |= PE_F_DIRTY; + + if (ps->ps_flags & PE_F_DIRTY) { + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (libpe_load_section(pe, ps) < 0) + return (-1); + } + sh->sh_rawsize = libpe_resync_buffers(ps); + } + + /* + * Sections only contains uninitialized data should set + * PointerToRawData to zero according to the PE/COFF + * specification. + */ + if (sh->sh_rawsize == 0) + sh->sh_rawptr = 0; + else + sh->sh_rawptr = off; + + off += sh->sh_rawsize; + } + + return (0); +} + +off_t +libpe_write_section_headers(PE *pe, off_t off) +{ + char tmp[sizeof(PE_SecHdr)], *hdr; + PE_Scn *ps; + PE_SecHdr *sh; + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER || pe->pe_nscn == 0) + return (off); + + if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0) { + off += sizeof(PE_SecHdr) * pe->pe_ch->ch_nsec; + return (off); + } + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + if (ps->ps_ndx & 0xFFFF0000U) + continue; + if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0 && + (ps->ps_flags & PE_F_DIRTY) == 0) + goto next_header; + + sh = &ps->ps_sh; + + memcpy(tmp, sh->sh_name, sizeof(sh->sh_name)); + hdr = tmp + 8; + PE_WRITE32(hdr, sh->sh_virtsize); + PE_WRITE32(hdr, sh->sh_addr); + PE_WRITE32(hdr, sh->sh_rawsize); + PE_WRITE32(hdr, sh->sh_rawptr); + PE_WRITE32(hdr, sh->sh_relocptr); + PE_WRITE32(hdr, sh->sh_lineptr); + PE_WRITE16(hdr, sh->sh_nreloc); + PE_WRITE16(hdr, sh->sh_nline); + PE_WRITE32(hdr, sh->sh_char); + + if (write(pe->pe_fd, tmp, sizeof(PE_SecHdr)) != + (ssize_t) sizeof(PE_SecHdr)) { + errno = EIO; + return (-1); + } + + next_header: + off += sizeof(PE_SecHdr); + } + + return (off); +} + +off_t +libpe_write_sections(PE *pe, off_t off) +{ + PE_Scn *ps; + PE_SecHdr *sh; + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) + return (off); + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + + /* Skip empty sections. */ + if (sh->sh_rawptr == 0 || sh->sh_rawsize == 0) + continue; + + /* + * Padding between sections. (padding always written + * in case the the section headers or sections are + * moved or shrunk.) + */ + assert(off <= sh->sh_rawptr); + if (off < sh->sh_rawptr) + libpe_pad(pe, sh->sh_rawptr - off); + + if ((ps->ps_flags & PE_F_DIRTY) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, + (off_t) (sh->sh_rawptr + sh->sh_rawsize), + SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + off = sh->sh_rawptr + sh->sh_rawsize; + continue; + } + + off = sh->sh_rawptr; + + if (libpe_write_buffers(ps) < 0) + return (-1); + + off += sh->sh_rawsize; + + ps->ps_flags &= ~PE_F_DIRTY; + } + + return (off); +} diff --git a/contrib/elftoolchain/libpe/libpe_utils.c b/contrib/elftoolchain/libpe/libpe_utils.c new file mode 100644 index 0000000000..9bc9a54bc4 --- /dev/null +++ b/contrib/elftoolchain/libpe/libpe_utils.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_utils.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +off_t +libpe_align(PE *pe, off_t off, size_t align) +{ + off_t n; + + assert(align > 0 && (align & (align - 1)) == 0); + + n = roundup(off, align); + if (n > off) { + if (libpe_pad(pe, n - off) < 0) + return (-1); + } + + return (n); +} + +int +libpe_pad(PE *pe, size_t pad) +{ + char tmp[128]; + size_t s; + + memset(tmp, 0, sizeof(tmp)); + for (; pad > 0; pad -= s) { + s = pad > sizeof(tmp) ? sizeof(tmp) : pad; + if (write(pe->pe_fd, tmp, s) != (ssize_t) s) { + errno = EIO; + return (-1); + } + } + + return (0); +} diff --git a/contrib/elftoolchain/libpe/os.Linux.mk b/contrib/elftoolchain/libpe/os.Linux.mk new file mode 100644 index 0000000000..ed5bdf00e8 --- /dev/null +++ b/contrib/elftoolchain/libpe/os.Linux.mk @@ -0,0 +1,6 @@ +# $Id: os.Linux.mk 3312 2016-01-10 09:23:51Z kaiwang27 $ + +CFLAGS+= -Wall -Wno-unused-parameter -Wstrict-prototypes \ + -Wmissing-prototypes -Wpointer-arith -Wreturn-type \ + -Wcast-qual -Wwrite-strings -Wswitch -Wshadow \ + -Wcast-align -Wunused-parameter diff --git a/contrib/elftoolchain/libpe/os.NetBSD.mk b/contrib/elftoolchain/libpe/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/libpe/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/libpe/pe.h b/contrib/elftoolchain/libpe/pe.h new file mode 100644 index 0000000000..33969ed8a3 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe.h @@ -0,0 +1,295 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: pe.h 3441 2016-04-07 15:04:20Z emaste $ + */ + +#ifndef _PE_H_ +#define _PE_H_ + +#include + +/* + * MS-DOS header. + */ + +typedef struct _PE_DosHdr { + char dh_magic[2]; + uint16_t dh_lastsize; + uint16_t dh_nblock; + uint16_t dh_nreloc; + uint16_t dh_hdrsize; + uint16_t dh_minalloc; + uint16_t dh_maxalloc; + uint16_t dh_ss; + uint16_t dh_sp; + uint16_t dh_checksum; + uint16_t dh_ip; + uint16_t dh_cs; + uint16_t dh_relocpos; + uint16_t dh_noverlay; + uint16_t dh_reserved1[4]; + uint16_t dh_oemid; + uint16_t dh_oeminfo; + uint16_t dh_reserved2[10]; + uint32_t dh_lfanew; +} PE_DosHdr; + +/* + * Rich header. + */ + +typedef struct _PE_RichHdr { + uint32_t rh_xor; + uint32_t rh_total; + uint32_t *rh_compid; + uint32_t *rh_cnt; +} PE_RichHdr; + +/* + * COFF header: Machine Types. + */ + +#define IMAGE_FILE_MACHINE_UNKNOWN 0x0 /* not specified */ +#define IMAGE_FILE_MACHINE_AM33 0x1d3 /* Matsushita AM33 */ +#define IMAGE_FILE_MACHINE_AMD64 0x8664 /* x86-64 */ +#define IMAGE_FILE_MACHINE_ARM 0x1c0 /* ARM LE */ +#define IMAGE_FILE_MACHINE_ARMNT 0x1c4 /* ARMv7(or higher) Thumb */ +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 /* ARMv8 64-bit */ +#define IMAGE_FILE_MACHINE_EBC 0xebc /* EFI byte code */ +#define IMAGE_FILE_MACHINE_I386 0x14c /* x86 */ +#define IMAGE_FILE_MACHINE_IA64 0x200 /* IA64 */ +#define IMAGE_FILE_MACHINE_M32R 0x9041 /* Mitsubishi M32R LE */ +#define IMAGE_FILE_MACHINE_MIPS16 0x266 /* MIPS16 */ +#define IMAGE_FILE_MACHINE_MIPSFPU 0x366 /* MIPS with FPU */ +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 /* MIPS16 with FPU */ +#define IMAGE_FILE_MACHINE_POWERPC 0x1f0 /* Power PC LE */ +#define IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 /* Power PC floating point */ +#define IMAGE_FILE_MACHINE_R4000 0x166 /* MIPS R4000 LE */ +#define IMAGE_FILE_MACHINE_RISCV32 0x5032 /* RISC-V 32-bit */ +#define IMAGE_FILE_MACHINE_RISCV64 0x5064 /* RISC-V 64-bit */ +#define IMAGE_FILE_MACHINE_RISCV128 0x5128 /* RISC-V 128-bit */ +#define IMAGE_FILE_MACHINE_SH3 0x1a2 /* Hitachi SH3 */ +#define IMAGE_FILE_MACHINE_SH3DSP 0x1a3 /* Hitachi SH3 DSP */ +#define IMAGE_FILE_MACHINE_SH4 0x1a6 /* Hitachi SH4 */ +#define IMAGE_FILE_MACHINE_SH5 0x1a8 /* Hitachi SH5 */ +#define IMAGE_FILE_MACHINE_THUMB 0x1c2 /* ARM or Thumb interworking */ +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 /* MIPS LE WCE v2 */ + +/* + * COFF header: Characteristics + */ + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +/* + * COFF Header. + */ + +typedef struct _PE_CoffHdr { + uint16_t ch_machine; + uint16_t ch_nsec; + uint32_t ch_timestamp; + uint32_t ch_symptr; + uint32_t ch_nsym; + uint16_t ch_optsize; + uint16_t ch_char; +} PE_CoffHdr; + + +/* + * Optional Header: Subsystem. + */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 + +/* + * Optional Header: DLL Characteristics + */ + +#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE 0x0040 +#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY 0x0080 +#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION 0x0200 +#define IMAGE_DLL_CHARACTERISTICS_NO_SEH 0x0400 +#define IMAGE_DLL_CHARACTERISTICS_NO_BIND 0x0800 +#define IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER 0x2000 +#define IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +/* + * Optional Header. + */ + +#define PE_FORMAT_ROM 0x107 +#define PE_FORMAT_32 0x10b +#define PE_FORMAT_32P 0x20b + +typedef struct _PE_OptHdr { + uint16_t oh_magic; + uint8_t oh_ldvermajor; + uint8_t oh_ldverminor; + uint32_t oh_textsize; + uint32_t oh_datasize; + uint32_t oh_bsssize; + uint32_t oh_entry; + uint32_t oh_textbase; + uint32_t oh_database; + uint64_t oh_imgbase; + uint32_t oh_secalign; + uint32_t oh_filealign; + uint16_t oh_osvermajor; + uint16_t oh_osverminor; + uint16_t oh_imgvermajor; + uint16_t oh_imgverminor; + uint16_t oh_subvermajor; + uint16_t oh_subverminor; + uint32_t oh_win32ver; + uint32_t oh_imgsize; + uint32_t oh_hdrsize; + uint32_t oh_checksum; + uint16_t oh_subsystem; + uint16_t oh_dllchar; + uint64_t oh_stacksizer; + uint64_t oh_stacksizec; + uint64_t oh_heapsizer; + uint64_t oh_heapsizec; + uint32_t oh_ldrflags; + uint32_t oh_ndatadir; +} PE_OptHdr; + +/* + * Optional Header: Data Directories. + */ + +#define PE_DD_EXPORT 0 +#define PE_DD_IMPORT 1 +#define PE_DD_RESROUCE 2 +#define PE_DD_EXCEPTION 3 +#define PE_DD_CERTIFICATE 4 +#define PE_DD_BASERELOC 5 +#define PE_DD_DEBUG 6 +#define PE_DD_ARCH 7 +#define PE_DD_GLOBALPTR 8 +#define PE_DD_TLS 9 +#define PE_DD_LOADCONFIG 10 +#define PE_DD_BOUNDIMPORT 11 +#define PE_DD_IAT 12 +#define PE_DD_DELAYIMPORT 13 +#define PE_DD_CLRRUNTIME 14 +#define PE_DD_RESERVED 15 +#define PE_DD_MAX 16 + +typedef struct _PE_DataDirEntry { + uint32_t de_addr; + uint32_t de_size; +} PE_DataDirEntry; + +typedef struct _PE_DataDir { + PE_DataDirEntry dd_e[PE_DD_MAX]; + uint32_t dd_total; +} PE_DataDir; + +/* + * Section Headers: Section flags. + */ + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 +#define IMAGE_SCN_GPREL 0x00008000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +/* + * Section Headers. + */ + +typedef struct _PE_SecHdr { + char sh_name[8]; + uint32_t sh_virtsize; + uint32_t sh_addr; + uint32_t sh_rawsize; + uint32_t sh_rawptr; + uint32_t sh_relocptr; + uint32_t sh_lineptr; + uint16_t sh_nreloc; + uint16_t sh_nline; + uint32_t sh_char; +} PE_SecHdr; + +#endif /* !_PE_H_ */ diff --git a/contrib/elftoolchain/libpe/pe_buffer.c b/contrib/elftoolchain/libpe/pe_buffer.c new file mode 100644 index 0000000000..e4ac19fa04 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_buffer.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_Buffer * +pe_getbuffer(PE_Scn *ps, PE_Buffer *pb) +{ + PE *pe; + PE_SecBuf *sb; + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + pe = ps->ps_pe; + + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + if (libpe_load_all_sections(pe) < 0) + return (NULL); + } else { + if (libpe_load_section(pe, ps) < 0) + return (NULL); + } + } + + sb = (PE_SecBuf *) pb; + + if (sb == NULL) + sb = STAILQ_FIRST(&ps->ps_b); + else + sb = STAILQ_NEXT(sb, sb_next); + + return ((PE_Buffer *) sb); +} + +PE_Buffer * +pe_newbuffer(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb; + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + pe = ps->ps_pe; + + if (pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (libpe_load_section(pe, ps) < 0) + return (NULL); + } + + if ((sb = libpe_alloc_buffer(ps, 0)) == NULL) + return (NULL); + + sb->sb_flags |= PE_F_DIRTY; + ps->ps_flags |= PE_F_DIRTY; + + return ((PE_Buffer *) sb); +} diff --git a/contrib/elftoolchain/libpe/pe_cntl.c b/contrib/elftoolchain/libpe/pe_cntl.c new file mode 100644 index 0000000000..1fc8c47401 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_cntl.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_cntl.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_cntl(PE *pe, PE_Cmd cmd) +{ + + if (pe == NULL) { + errno = EINVAL; + return (-1); + } + + switch (cmd) { + case PE_C_FDDONE: + pe->pe_flags |= LIBPE_F_FD_DONE; + break; + + case PE_C_FDREAD: + if (pe->pe_cmd == PE_C_WRITE) { + errno = EACCES; + return (-1); + } + if (libpe_load_all_sections(pe) < 0) + return (-1); + break; + + default: + errno = EINVAL; + return (-1); + } + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_coff.c b/contrib/elftoolchain/libpe/pe_coff.c new file mode 100644 index 0000000000..d5cd83311a --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_coff.c @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_coff.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_CoffHdr * +pe_coff_header(PE *pe) +{ + + if (pe->pe_ch == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_ch); +} + +PE_OptHdr * +pe_opt_header(PE *pe) +{ + + if (pe->pe_oh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_oh); +} + +PE_DataDir * +pe_data_dir(PE *pe) +{ + + if (pe->pe_dd == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_dd); +} + +int +pe_update_coff_header(PE *pe, PE_CoffHdr *ch) +{ + + if (pe == NULL || ch == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_ch == NULL) { + if ((pe->pe_ch = malloc(sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } else { + /* Rewrite optional header if `optsize' field changed. */ + if (pe->pe_ch->ch_optsize != ch->ch_optsize) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + } + + *pe->pe_ch = *ch; + + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + + return (0); +} + +int +pe_update_opt_header(PE *pe, PE_OptHdr *oh) +{ + + if (pe == NULL || oh == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_oh == NULL) { + if ((pe->pe_oh = malloc(sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_oh = *oh; + + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_update_data_dir(PE *pe, PE_DataDir *dd) +{ + + if (pe == NULL || dd == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_dd == NULL) { + if ((pe->pe_dd = malloc(sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_dd = *dd; + + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_dos.c b/contrib/elftoolchain/libpe/pe_dos.c new file mode 100644 index 0000000000..01ba42f44a --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_dos.c @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_DosHdr * +pe_msdos_header(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_dh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_dh); +} + +char * +pe_msdos_stub(PE *pe, size_t *len) +{ + + if (pe == NULL || len == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + (void) libpe_read_msdos_stub(pe); + } + + *len = sizeof(PE_DosHdr) + pe->pe_stub_ex; + + return (pe->pe_stub); +} + +int +ps_update_msdos_header(PE *pe, PE_DosHdr *dh) +{ + + if (pe == NULL || dh == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_dh == NULL) { + if ((pe->pe_dh = malloc(sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_dh = *dh; + + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + + return (0); +} + +int +ps_update_msdos_stub(PE *pe, char *dos_stub, size_t sz) +{ + + if (pe == NULL || dos_stub == NULL || sz == 0) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + pe->pe_stub_app = dos_stub; + pe->pe_stub_app_sz = sz; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_flag.c b/contrib/elftoolchain/libpe/pe_flag.c new file mode 100644 index 0000000000..c392a4d2ee --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_flag.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_flag.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_flag(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR)) { + errno = EINVAL; + return (-1); + } + + if ((flags & ~(PE_F_STRIP_DOS_STUB | PE_F_STRIP_RICH_HEADER | + PE_F_STRIP_SYMTAB | PE_F_STRIP_DEBUG)) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= flags; + else + pe->pe_flags &= ~flags; + + return (0); +} + +int +pe_flag_dos_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER; + + return (0); +} + +int +pe_flag_coff_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER; + + return (0); +} + +int +pe_flag_opt_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_flag_data_dir(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_flag_scn(PE_Scn *ps, PE_Cmd c, unsigned int flags) +{ + + if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~(PE_F_DIRTY | PE_F_STRIP_SECTION)) == 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + ps->ps_flags |= flags; + else + ps->ps_flags &= ~flags; + + return (0); +} + +int +pe_flag_section_header(PE_Scn *ps, PE_Cmd c, unsigned int flags) +{ + PE *pe; + + if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + pe = ps->ps_pe; + + /* The library doesn't support per section header dirty flag. */ + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_SEC_HEADER; + + return (0); +} + +int +pe_flag_buffer(PE_Buffer *pb, PE_Cmd c, unsigned int flags) +{ + PE_SecBuf *sb; + + if (pb == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + sb = (PE_SecBuf *) pb; + + if (c == PE_C_SET) + sb->sb_flags |= flags; + else + sb->sb_flags &= ~flags; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_init.c b/contrib/elftoolchain/libpe/pe_init.c new file mode 100644 index 0000000000..4e2f22a260 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_init.c @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE * +pe_init(int fd, PE_Cmd c, PE_Object o) +{ + PE *pe; + + if ((pe = calloc(1, sizeof(*pe))) == NULL) { + errno = ENOMEM; + return (NULL); + } + pe->pe_fd = fd; + pe->pe_cmd = c; + pe->pe_obj = o; + STAILQ_INIT(&pe->pe_scn); + + switch (c) { + case PE_C_READ: + case PE_C_RDWR: + if (libpe_open_object(pe) < 0) + goto init_fail; + break; + + case PE_C_WRITE: + if (o < PE_O_PE32 || o > PE_O_COFF) { + errno = EINVAL; + goto init_fail; + } + break; + + default: + errno = EINVAL; + goto init_fail; + } + + return (pe); + +init_fail: + pe_finish(pe); + return (NULL); +} + +void +pe_finish(PE *pe) +{ + + if (pe == NULL) + return; + + libpe_release_object(pe); +} + +PE_Object +pe_object(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (PE_O_UNKNOWN); + } + + return (pe->pe_obj); +} diff --git a/contrib/elftoolchain/libpe/pe_rich.c b/contrib/elftoolchain/libpe/pe_rich.c new file mode 100644 index 0000000000..ea1029e58f --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_rich.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_RichHdr * +pe_rich_header(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_rh == NULL && pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + (void) libpe_read_msdos_stub(pe); + } + + if (pe->pe_rh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_rh); +} + +static uint32_t +rol32(uint32_t n, int c) +{ + + c &= 0x1f; + + return ((n << c) | (n >> (0x20 - c))); +} + +int +pe_rich_header_validate(PE *pe) +{ + PE_RichHdr *rh; + uint32_t cksum; + char *p; + int i, off; + + if (pe_rich_header(pe) == NULL) + return (-1); + + assert(pe->pe_rh_start != NULL); + + /* + * Initial value of the checksum is the offset to the begin of + * the Rich header. + */ + cksum = pe->pe_rh_start - pe->pe_stub; + + /* + * Add the bytes before the Rich header to the checksum, rotated + * left by the offset. + */ + for (p = pe->pe_stub; p < pe->pe_rh_start; p++) { + /* Skip dh_lfanew. */ + off = p - pe->pe_stub; + if (off >= 0x3c && off < 0x40) + continue; + cksum += rol32((unsigned char) *p, off); + } + + /* Add each compid rotated left by its count to the checksum. */ + rh = pe->pe_rh; + for (i = 0; (uint32_t) i < rh->rh_total; i++) + cksum += rol32(rh->rh_compid[i], rh->rh_cnt[i]); + + /* Validate the checksum with the XOR mask stored after "Rich". */ + if (cksum == rh->rh_xor) + return (1); + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_section.c b/contrib/elftoolchain/libpe/pe_section.c new file mode 100644 index 0000000000..3e82d84805 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_section.c @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_Scn * +pe_getscn(PE *pe, size_t ndx) +{ + PE_Scn *ps; + + if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) { + errno = EINVAL; + return (NULL); + } + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_ndx == ndx) + return (ps); + } + + errno = ENOENT; + + return (NULL); +} + +size_t +pe_ndxscn(PE_Scn *ps) +{ + + if (ps == NULL) { + errno = EINVAL; + return (0); + } + + return (ps->ps_ndx); +} + +PE_Scn * +pe_nextscn(PE *pe, PE_Scn *ps) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (ps == NULL) + ps = STAILQ_FIRST(&pe->pe_scn); + else + ps = STAILQ_NEXT(ps, ps_next); + + while (ps != NULL) { + if (ps->ps_ndx >= 1 && ps->ps_ndx <= 0xFFFFU) + return (ps); + ps = STAILQ_NEXT(ps, ps_next); + } + + return (NULL); +} + +PE_Scn * +pe_newscn(PE *pe) +{ + PE_Scn *ps, *tps, *_tps; + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (NULL); + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) { + STAILQ_FOREACH_SAFE(tps, &pe->pe_scn, ps_next, _tps) + libpe_release_scn(tps); + pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER; + } + + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + + ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (ps); +} + +PE_Scn * +pe_insertscn(PE *pe, size_t ndx) +{ + PE_Scn *ps, *a, *b; + + if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (NULL); + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) { + STAILQ_FOREACH_SAFE(a, &pe->pe_scn, ps_next, b) + libpe_release_scn(a); + pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER; + } + + b = NULL; + STAILQ_FOREACH(a, &pe->pe_scn, ps_next) { + if (a->ps_ndx & 0xFFFF0000U) + continue; + if (a->ps_ndx == ndx) + break; + b = a; + } + + if (a == NULL) { + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + if (b == NULL) + ps->ps_ndx = 1; + else + ps->ps_ndx = b->ps_ndx + 1; + } else if (b == NULL) { + STAILQ_INSERT_HEAD(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 1; + } else { + STAILQ_INSERT_AFTER(&pe->pe_scn, b, ps, ps_next); + ps->ps_ndx = ndx; + } + + a = ps; + while ((a = STAILQ_NEXT(a, ps_next)) != NULL) { + if ((a->ps_ndx & 0xFFFF0000U) == 0) + a->ps_ndx++; + } + + ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (ps); +} + +PE_SecHdr * +pe_section_header(PE_Scn *ps) +{ + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + return (&ps->ps_sh); +} + +int +pe_update_section_header(PE_Scn *ps, PE_SecHdr *sh) +{ + PE *pe; + + if (ps == NULL || sh == NULL) { + errno = EINVAL; + return (-1); + } + + pe = ps->ps_pe; + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + ps->ps_sh = *sh; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_symtab.c b/contrib/elftoolchain/libpe/pe_symtab.c new file mode 100644 index 0000000000..d0e90d14ad --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_symtab.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_symtab.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_update_symtab(PE *pe, char *symtab, size_t sz, unsigned int nsym) +{ + PE_Scn *ps; + PE_SecBuf *sb; + PE_SecHdr *sh; + + if (pe == NULL || symtab == NULL || sz == 0) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + /* Remove the old symbol table. */ + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_ndx == 0xFFFFFFFFU) + libpe_release_scn(ps); + } + + /* + * Insert the new symbol table. + */ + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFFFFFFU; + ps->ps_flags |= PE_F_DIRTY; + + /* + * Set the symbol table section offset to the maximum to make sure + * that it will be placed in the end of the file during section + * layout. + */ + sh = &ps->ps_sh; + sh->sh_rawptr = 0xFFFFFFFFU; + sh->sh_rawsize = sz; + + /* Allocate the buffer. */ + if ((sb = libpe_alloc_buffer(ps, 0)) == NULL) + return (-1); + sb->sb_flags |= PE_F_DIRTY; + sb->sb_pb.pb_size = sz; + sb->sb_pb.pb_buf = symtab; + + pe->pe_nsym = nsym; + + return (0); +} diff --git a/contrib/elftoolchain/libpe/pe_update.c b/contrib/elftoolchain/libpe/pe_update.c new file mode 100644 index 0000000000..ec2b2e5249 --- /dev/null +++ b/contrib/elftoolchain/libpe/pe_update.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_update.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +off_t +pe_update(PE *pe) +{ + off_t off; + + if (pe == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_cmd == PE_C_RDWR || (pe->pe_cmd == PE_C_WRITE && + (pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0)) { + if (lseek(pe->pe_fd, 0, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + off = 0; + + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) { + if ((off = libpe_write_msdos_stub(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_pe_header(pe, off)) < 0) + return (-1); + } + + if (libpe_resync_sections(pe, off) < 0) + return (-1); + + if ((off = libpe_write_coff_header(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_section_headers(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_sections(pe, off)) < 0) + return (-1); + + if (ftruncate(pe->pe_fd, off) < 0) { + errno = EIO; + return (-1); + } + + return (off); +} diff --git a/contrib/elftoolchain/mk/elftoolchain.components.mk b/contrib/elftoolchain/mk/elftoolchain.components.mk new file mode 100644 index 0000000000..041839d800 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.components.mk @@ -0,0 +1,50 @@ +# +# $Id: elftoolchain.components.mk 3607 2018-04-13 19:41:17Z jkoshy $ +# + +# Knobs to turn parts of the source tree on or off. +# +# These knobs should be set to one of "yes" or "no". + +# Build additional tutorial documentation. (Manual page generation is +# controlled by the 'MKDOC' knob). +WITH_ADDITIONAL_DOCUMENTATION?=yes + +# Build the automation tools. +WITH_BUILD_TOOLS?= no + +# Build the instruction set analyser. +WITH_ISA?= no + +# Build PE support. +WITH_PE?= yes + +# Build test suites. +.if defined(MAKEOBJDIR) || defined(MAKEOBJDIRPREFIX) +.if defined(WITH_TESTS) && ${WITH_TESTS} == "yes" +.error Only in-tree builds are supported for tests currently [#271]. +.endif +WITH_TESTS?= no +.else +WITH_TESTS?= yes +.endif + +# Fail the build with an informative message if the value of any +# build knob is not a "yes" or "no". +.if ${WITH_ADDITIONAL_DOCUMENTATION} != "yes" && \ + ${WITH_ADDITIONAL_DOCUMENTATION} != "no" +.error Unrecognized value for WITH_ADDITIONAL_DOCUMENTATION:\ + "${WITH_ADDITIONAL_DOCUMENTATION}". +.endif +.if ${WITH_BUILD_TOOLS} != "yes" && ${WITH_BUILD_TOOLS} != "no" +.error Unrecognized value for WITH_BUILD_TOOLS: "${WITH_BUILD_TOOLS}". +.endif +.if ${WITH_ISA} != "yes" && ${WITH_ISA} != "no" +.error Unrecognized value for WITH_ISA: "${WITH_ISA}". +.endif +.if ${WITH_PE} != "yes" && ${WITH_PE} != "no" +.error Unrecognized value for WITH_PE: "${WITH_PE}". +.endif +.if ${WITH_TESTS} != "yes" && ${WITH_TESTS} != "no" +.error Unrecognized value for WITH_TESTS: "${WITH_TESTS}". +.endif diff --git a/contrib/elftoolchain/mk/elftoolchain.inc.mk b/contrib/elftoolchain/mk/elftoolchain.inc.mk new file mode 100644 index 0000000000..ebf80ceef2 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.inc.mk @@ -0,0 +1,36 @@ +# +# Rules for handling include files. +# +# $Id: elftoolchain.inc.mk 3602 2018-04-12 20:52:01Z jkoshy $ + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.os.mk" + +.include + +.if ${OS_HOST} == "Darwin" || ${OS_HOST} == "DragonFly" || \ + ${OS_HOST} == "FreeBSD" || ${OS_HOST} == "OpenBSD" +# Simulate . + +NOBINMODE?= 444 # Missing in OpenBSD's rule set. + +.PHONY: incinstall +includes: ${INCS} incinstall +.for inc in ${INCS} +install incinstall: ${DESTDIR}${INCSDIR}/${inc} +.PRECIOUS: ${DESTDIR}${INCSDIR}/${inc} +${DESTDIR}${INCSDIR}/${inc}: ${inc} + cmp -s $> $@ > /dev/null 2>&1 || \ + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} $> $@ +.endfor +.else + +# Provide a default 'install' target. +install: incinstall .PHONY + +# Use the standard . +.include +.endif diff --git a/contrib/elftoolchain/mk/elftoolchain.lib.mk b/contrib/elftoolchain/mk/elftoolchain.lib.mk new file mode 100644 index 0000000000..33a0becb9f --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.lib.mk @@ -0,0 +1,75 @@ +# +# $Id: elftoolchain.lib.mk 3913 2020-11-30 21:33:46Z jkoshy $ +# + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.os.mk" + +.include + +# Support a 'clobber' target. +clobber: clean os-specific-clobber .PHONY + +# Remove '.depend' files on a "make clean". +CLEANFILES+= .depend + +# Determine the include directories to use. +_INCDIRS= -I. # OBJDIR +_INCDIRS+= -I${.CURDIR} # Sources +_INCDIRS+= -I${.CURDIR}/${TOP}/common # Common code +.if defined(MAKEOBJDIRPREFIX) +_INCDIRS+= -I${.OBJDIR}/${TOP}/common # Generated common code. +.else +.if ${.CURDIR} != ${.OBJDIR} +_INCDIRS+= -I${.CURDIR}/${TOP}/common/${.OBJDIR:S/${.CURDIR}//} +.endif +.endif + +.if defined(LDADD) +_LDADD_LIBELF=${LDADD:M-lelf} +.if !empty(_LDADD_LIBELF) +_INCDIRS+= -I${.CURDIR}/${TOP}/libelf +LDFLAGS+= -L${.OBJDIR}/${TOP}/libelf +.endif +.endif + +# Set CFLAGS and LINTFLAGS. +CFLAGS+= ${_INCDIRS} +LINTFLAGS+= ${_INCDIRS} + +# Note: include the M4 ruleset after bsd.lib.mk. +.include "${TOP}/mk/elftoolchain.m4.mk" + +.if defined(DEBUG) +CFLAGS:= ${CFLAGS:N-O*} -g +.endif + +.if ${OS_HOST} == "DragonFly" || ${OS_HOST} == "FreeBSD" +# Install headers too, in the 'install' phase. +install: includes +.elif ${OS_HOST} == "Linux" || ${OS_HOST} == "NetBSD" || ${OS_HOST} == "Minix" +install: incinstall +.elif ${OS_HOST} == "OpenBSD" + +# OpenBSD's standard make ruleset does not install header files. Provide +# an alternative. + +NOBINMODE?= 444 + +install: ${INCS} incinstall + +.for inc in ${INCS} +incinstall:: ${DESTDIR}${INCSDIR}/${inc} +.PRECIOUS: ${DESTDIR}${INCSDIR}/${inc} +${DESTDIR}${INCSDIR}/${inc}: ${inc} + cmp -s $> $@ > /dev/null 2>&1 || \ + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} $> $@ +.endfor + +.endif # OpenBSD + +# Bring in rules related to running the related test suite. +.include "${TOP}/mk/elftoolchain.test-target.mk" diff --git a/contrib/elftoolchain/mk/elftoolchain.m4.mk b/contrib/elftoolchain/mk/elftoolchain.m4.mk new file mode 100644 index 0000000000..0523814259 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.m4.mk @@ -0,0 +1,14 @@ +# +# $Id: elftoolchain.m4.mk 2795 2012-12-19 12:39:09Z jkoshy $ +# + +# Implicit rules for the M4 pre-processor. + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.SUFFIXES: .m4 .c +.m4.c: + m4 -D SRCDIR=${.CURDIR} ${M4FLAGS} ${.IMPSRC} > ${.TARGET} + diff --git a/contrib/elftoolchain/mk/elftoolchain.os.mk b/contrib/elftoolchain/mk/elftoolchain.os.mk new file mode 100644 index 0000000000..ab7c227dfe --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.os.mk @@ -0,0 +1,26 @@ +# +# $Id: elftoolchain.os.mk 2985 2014-03-06 03:24:35Z jkoshy $ +# + +# OS specific build instructions + +.if !defined(OS_HOST) + +# Determine the host operating system flavor. +OS_HOST != uname -s + +# Bring in OS-specific Makefiles, if they exist +.if exists(${TOP}/mk/os.${OS_HOST}.mk) +.include "${TOP}/mk/os.${OS_HOST}.mk" +.endif + +# Bring in per-subproject OS-specific Makefiles, if they exist +.if exists(${.CURDIR}/os.${OS_HOST}.mk) +.include "${.CURDIR}/os.${OS_HOST}.mk" +.endif + +# Supply an OS-specific "clobber" rule, if one was not specified. +.if !target(os-specific-clobber) +os-specific-clobber: .PHONY +.endif +.endif diff --git a/contrib/elftoolchain/mk/elftoolchain.prog.mk b/contrib/elftoolchain/mk/elftoolchain.prog.mk new file mode 100644 index 0000000000..b1b38b58c4 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.prog.mk @@ -0,0 +1,134 @@ +# +# Rules for building programs. +# +# $Id: elftoolchain.prog.mk 3913 2020-11-30 21:33:46Z jkoshy $ + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.os.mk" + +LIBDWARF?= ${TOP}/libdwarf +LIBELF?= ${TOP}/libelf +LIBELFTC?= ${TOP}/libelftc + +BINDIR?= /usr/bin + +_INCDIRS= -I. -I${.CURDIR} -I${.CURDIR}/${TOP}/common + +CLEANFILES+= .depend + +# TODO[#271]: Reduce the code duplication below. + +.if defined(LDADD) +_LDADD_LIBDWARF=${LDADD:M-ldwarf} +.if !empty(_LDADD_LIBDWARF) +_INCDIRS+= -I${.CURDIR}/${TOP}/libdwarf +.if exists(${.OBJDIR}/${TOP}/libdwarf) +LDFLAGS+= -L${.OBJDIR}/${TOP}/libdwarf +.elif exists(${TOP}/libdwarf/${.OBJDIR:S,${.CURDIR}/,,}) +LDFLAGS+= -L${.CURDIR}/${TOP}/libdwarf/${.OBJDIR:S,${.CURDIR}/,,} +.else +.error Cannot determine LDFLAGS for -ldwarf. +.endif +.endif + +_LDADD_LIBELF=${LDADD:M-lelf} +.if !empty(_LDADD_LIBELF) +_INCDIRS+= -I${.CURDIR}/${TOP}/libelf +.if exists(${.OBJDIR}/${TOP}/libelf) +LDFLAGS+= -L${.OBJDIR}/${TOP}/libelf +.elif exists(${TOP}/libelf/${.OBJDIR:S,${.CURDIR}/,,}) +LDFLAGS+= -L${.CURDIR}/${TOP}/libelf/${.OBJDIR:S,${.CURDIR}/,,} +.else +.error Cannot determine LDFLAGS for -lelf. +.endif +.endif + +_LDADD_LIBELFTC=${LDADD:M-lelftc} +.if !empty(_LDADD_LIBELFTC) +_INCDIRS+= -I${.CURDIR}/${TOP}/libelftc +.if exists(${.OBJDIR}/${TOP}/libelftc) +LDFLAGS+= -L${.OBJDIR}/${TOP}/libelftc +.elif exists(${TOP}/libelftc/${.OBJDIR:S,${.CURDIR}/,,}) +LDFLAGS+= -L${.CURDIR}/${TOP}/libelftc/${.OBJDIR:S,${.CURDIR}/,,} +.else +.error Cannot determine LDFLAGS for -lelftc. +.endif +.endif + +_LDADD_LIBPE=${LDADD:M-lpe} +.if !empty(_LDADD_LIBPE) +_INCDIRS+= -I${.CURDIR}/${TOP}/libpe +.if exists(${.OBJDIR}/${TOP}/libpe) +LDFLAGS+= -L${.OBJDIR}/${TOP}/libpe +.elif exists(${TOP}/libpe/${.OBJDIR:S,${.CURDIR}/,,}) +LDFLAGS+= -L${.CURDIR}/${TOP}/libpe/${.OBJDIR:S,${.CURDIR}/,,} +.else +.error Cannot determine LDFLAGS for -lpe. +.endif +.endif +.endif + +_LDADD_LIBARCHIVE=${LDADD:M-larchive} +.if !empty(_LDADD_LIBARCHIVE) +.if ${OS_HOST} == NetBSD +_INCDIRS+= -I/usr/pkg/include +LDFLAGS+= -L/usr/pkg/lib +.elif ${OS_HOST} == OpenBSD +_INCDIRS+= -I/usr/local/include +LDFLAGS+= -L/usr/local/lib +.endif +.endif + +# Set CFLAGS and LINTFLAGS. +CFLAGS+= ${_INCDIRS} +LINTFLAGS+= ${_INCDIRS} + +# +# Handle lex(1) and yacc(1) in a portable fashion. +# +# New makefile variables used: +# +# LSRC -- a lexer definition suitable for use with lex(1) +# YSRC -- a parser definition for use with yacc(1) + +# Use standard rules from for building lexers. +.if defined(LSRC) +SRCS+= ${LSRC} +.endif + +# Handle the generation of yacc based parsers. +# If the program uses a lexer, add an automatic dependency +# on the generated parser header. +.if defined(YSRC) +.for _Y in ${YSRC} +SRCS+= ${_Y:R}.c +CLEANFILES+= ${_Y:R}.c ${_Y:R}.h +${_Y:R}.c ${_Y:R}.h: ${_Y} + ${YACC} -d -o ${_Y:R}.c ${.ALLSRC} + +.if defined(LSRC) +.for _L in ${LSRC} +${_L:R}.o: ${_Y:R}.h +.endfor +.endif + +.endfor +.endif + +.include + +# Note: include the M4 ruleset after bsd.prog.mk. +.include "${TOP}/mk/elftoolchain.m4.mk" + +# Support a 'clobber' target. +clobber: clean os-specific-clobber .PHONY + +.if defined(DEBUG) +CFLAGS:= ${CFLAGS:N-O*} -g +.endif + +# Bring in rules related to running the related test suite. +.include "${TOP}/mk/elftoolchain.test-target.mk" diff --git a/contrib/elftoolchain/mk/elftoolchain.subdir.mk b/contrib/elftoolchain/mk/elftoolchain.subdir.mk new file mode 100644 index 0000000000..8dd37b18c9 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.subdir.mk @@ -0,0 +1,19 @@ +# +# Rules for recursing into directories +# $Id: elftoolchain.subdir.mk 4033 2024-01-16 16:29:17Z jkoshy $ + +# Pass down 'test' as a valid target. + +.include "$(TOP)/mk/elftoolchain.os.mk" + +.if ${OS_HOST} == FreeBSD +SUBDIR_TARGETS+= clobber test +.elif ${OS_HOST} == OpenBSD +clobber: _SUBDIRUSE +.elif ${OS_HOST} == Linux # Ubuntu 'bmake' version 20200710-15. +SUBDIR_TARGETS+= cleandepend clobber test +.else # NetBSD +TARGETS+= cleandepend clobber test +.endif + +.include diff --git a/contrib/elftoolchain/mk/elftoolchain.test-target.mk b/contrib/elftoolchain/mk/elftoolchain.test-target.mk new file mode 100644 index 0000000000..3837f127b8 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.test-target.mk @@ -0,0 +1,19 @@ +# $Id: elftoolchain.test-target.mk 4044 2024-07-08 12:07:35Z jkoshy $ + +# +# Rules for invoking test suites. +# + +TEST_DIRECTORY= tests +TEST_TARGET= test + +TEST_FRAMEWORK?= tet # Or: 'atf', 'custom' or 'libtest'. + +.if !target(${TEST_TARGET}) +# The special target 'test' runs the test suite associated with a +# utility or library. +test: all .PHONY + (cd ${TOP}/${TEST_DIRECTORY}/${TEST_FRAMEWORK}/${.CURDIR:T} && \ + ${MAKE} all && \ + ${MAKE} ${TEST_TARGET}) +.endif diff --git a/contrib/elftoolchain/mk/elftoolchain.test.mk b/contrib/elftoolchain/mk/elftoolchain.test.mk new file mode 100644 index 0000000000..e5197821c2 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.test.mk @@ -0,0 +1,49 @@ +# $Id$ +# +# Rules for handling libtest based test suites. +# + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +TEST_BASE= $(TOP)/tests/libtest +TEST_LIB= $(TEST_BASE)/lib # The test(3) API. +TEST_DRIVER= ${TEST_BASE}/driver # A command-line driver for tests. + +CFLAGS+= -I$(TEST_LIB) -I${TEST_DRIVER} + +MAKE_TEST_SCAFFOLDING?= yes + +.if exists(${.CURDIR}/../Makefile.tset) +.include "${.CURDIR}/../Makefile.tset" +.endif + +.if defined(TEST_SRCS) +PROG= tc_${.CURDIR:T:R} + +_C_SRCS= ${TEST_SRCS:M*.c} +_M4_SRCS= ${TEST_SRCS:M*.m4} + +SRCS= ${_C_SRCS} ${_M4_SRCS} # See +CLEANFILES+= ${_M4_SRCS:S/.m4$/.c/g} ${TEST_DATA} + +${PROG}: ${TEST_DATA} + +.if defined(MAKE_TEST_SCAFFOLDING) && ${MAKE_TEST_SCAFFOLDING} == "yes" +_TC_SRC= ${.OBJDIR}/tc.c # Test scaffolding. + +SRCS+= ${_TC_SRC} +CLEANFILES+= ${_TC_SRC} + +# Generate the scaffolding file "tc.c" from the test objects. +_TEST_OBJS= ${_C_SRCS:S/.c$/.o/g} ${_M4_SRCS:S/.m4$/.o/g} +_MAKE_SCAFFOLDING= ${TEST_BASE}/bin/make-test-scaffolding +${_TC_SRC}: ${_TEST_OBJS} + ${_MAKE_SCAFFOLDING} -o ${.TARGET} ${.ALLSRC} +.endif +.endif + +LDADD+= -L${TEST_LIB} -ltest -L${TEST_DRIVER} -ldriver + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/mk/elftoolchain.tet.mk b/contrib/elftoolchain/mk/elftoolchain.tet.mk new file mode 100644 index 0000000000..6994149113 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.tet.mk @@ -0,0 +1,67 @@ +# $Id: elftoolchain.tet.mk 4035 2024-01-16 17:46:07Z jkoshy $ +# +# Rules for handling TET based test suites. +# + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.tetvars.mk" + +# Inform make(1) about the suffixes we use. +.SUFFIXES: .lsb32 .lsb64 .msb32 .msb64 .yaml + +TS_ROOT?= ${.CURDIR:H} +TS_OBJROOT?= ${.OBJDIR:H} + +TS_BASE= ${TOP}/tests/tet/tet + +TET_LIBS= ${TET_ROOT}/lib/tet3 +TET_OBJS= ${TET_LIBS}/tcm.o + +CFLAGS+= -I${TET_ROOT}/inc/tet3 -I${TS_ROOT}/common + +# Bring in test-suite specific definitions, if any. +.if exists(${.CURDIR}/../Makefile.tset) +.include "${.CURDIR}/../Makefile.tset" +.endif + +.if defined(TS_SRCS) +PROG= tc_${.CURDIR:T:R} + +_C_SRCS= ${TS_SRCS:M*.c} +_M4_SRCS= ${TS_SRCS:M*.m4} + +SRCS= ${_C_SRCS} ${_M4_SRCS} # See . +CLEANFILES+= ${_M4_SRCS:S/.m4$/.c/g} ${TS_DATA} + +${PROG}: ${TS_DATA} + +.if defined(GENERATE_TEST_SCAFFOLDING) +_TC_SRC= ${.OBJDIR}/tc.c # Test driver. +_TC_SCN= tet_scen # Scenario file. + +SRCS+= ${_TC_SRC} +CLEANFILES+= ${_TC_SRC} ${_TC_SCN} + +# Generate the driver file "tc.c" from the objects comprising the test case. +_TS_OBJS= ${_C_SRCS:S/.c$/.o/g} ${_M4_SRCS:S/.m4$/.o/g} +_MUNGE_TS= ${TS_BASE}/bin/munge-ts +${_TC_SRC}: ${_TS_OBJS} + ${_MUNGE_TS} -o ${.TARGET} -p ${.CURDIR:H:T}/${.CURDIR:T:R}/${PROG} \ + -s ${_TC_SCN} ${.ALLSRC} +.endif +.endif + +# M4->C translation. +M4FLAGS+= -I${TS_ROOT}/common -I${TS_BASE}/common + +.include "${TOP}/mk/elftoolchain.m4.mk" + +LDADD+= ${TET_OBJS} -L${TET_LIBS} -lapi +CLEANFILES+= tet_xres tet_captured + +ELFTOOLCHAIN_AR= ${TOP}/ar/ar + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/mk/elftoolchain.tetbase.mk b/contrib/elftoolchain/mk/elftoolchain.tetbase.mk new file mode 100644 index 0000000000..6385bf6a27 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.tetbase.mk @@ -0,0 +1,47 @@ +# $Id$ + +# Convenience rules for the top level directory containing a TET-based test +# suite. + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.tetvars.mk" + +.MAIN: all +.PHONY: clobber execute tccbuild tccclean test + + +# Set up the environment for invoking "tcc", based on the target +# specified. + +.if !defined(TET_EXECUTE) +TET_EXECUTE= ${.OBJDIR} +.endif + +.if make(tccbuild) +TET_OPTIONS+= -b +.endif + +.if make(tccclean) +TET_OPTIONS+= -c +.endif + +.if make(execute) || make(test) +TET_OPTIONS+= -e +.endif + +execute tccbuild tccclean test: + TET_ROOT=${TET_ROOT} TET_EXECUTE=${TET_EXECUTE} \ + TET_SUITE_ROOT=${.CURDIR} ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . + ${TOP}/tests/tet/tet/bin/check-tet-journal -t ${.OBJDIR} + +clobber: clean + rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} + +# Ensure that a 'make test' does not recurse further into the test suite's +# directory hierarchy. +.if !make(test) +.include "${TOP}/mk/elftoolchain.subdir.mk" +.endif diff --git a/contrib/elftoolchain/mk/elftoolchain.tetvars.mk b/contrib/elftoolchain/mk/elftoolchain.tetvars.mk new file mode 100644 index 0000000000..a31e7717ab --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.tetvars.mk @@ -0,0 +1,22 @@ +# +# Configuration information for TET. +# +# $Id: elftoolchain.tetvars.mk 4035 2024-01-16 17:46:07Z jkoshy $ +# + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +# Set TET_ROOT and version. +TET_VERSION?= 3.8 +TET_ROOT?= ${TOP}/tests/tet/tet/tet${TET_VERSION} + +TET_DOWNLOAD_URL= \ + http://tetworks.opengroup.org/downloads/38/software/Sources/${TET_VERSION}/tet${TET_VERSION}-src.tar.gz + +# The directory where test journals are placed. +TET_RESULTS_DIR?= results + +# The temporary directory used by TET. +TET_TMP_DIR?= tet_tmp_dir diff --git a/contrib/elftoolchain/mk/elftoolchain.tex.mk b/contrib/elftoolchain/mk/elftoolchain.tex.mk new file mode 100644 index 0000000000..238038a2e0 --- /dev/null +++ b/contrib/elftoolchain/mk/elftoolchain.tex.mk @@ -0,0 +1,142 @@ +# +# Rules to build LateX documentation. +# +# $Id: elftoolchain.tex.mk 3907 2020-11-28 14:01:21Z jkoshy $ +# + +.include "${TOP}/mk/elftoolchain.os.mk" + +.if defined(MKTEX) && ${MKTEX} == "yes" && exists(${MPOST}) && exists(${PDFLATEX}) + +TEXINPUTS= `kpsepath tex`:${.CURDIR} +_TEX= TEXINPUTS=${TEXINPUTS} ${PDFLATEX} -file-line-error \ + -halt-on-error + +DOCSUBDIR= elftoolchain # Destination directory. +COVER_PAGE?= 1 # Cover page number in the document. +COVER_DPI?= 300 # Image resolution for cover page images. + +.MAIN: all + +all: ${DOC}.pdf .PHONY + +# Build an index. +# +# First, we need to remove the existing ".ind" file and run `latex` once +# to generate it afresh. This generates the appropriate ".idx" files used +# by `makeindex`. +# Next, `makeindex` is used to create the ".ind" file. +# Then another set of `latex` runs serves to typeset the index. +index: .PHONY + rm -f ${DOC}.ind + ${_TEX} ${DOC}.tex + ${MAKEINDEX} ${DOC}.idx + ${_TEX} ${DOC}.tex + @if grep 'Rerun to get' ${DOC}.log > /dev/null; then \ + ${_TEX} ${DOC}.tex; \ + fi + +# Cover page generation. +# +# Use the dedicated cover page if present. +.if exists(${DOC}.cover.tex) +${DOC}.cover.pdf: ${DOC}.cover.tex ${COVER_SRCS} + ${_TEX} ${.CURDIR}/${DOC}.cover.tex > /dev/null || \ + (cat ${DOC}.cover.log; rm -f ${.TARGET}; exit 1) +.else +# Otherwise, extract the cover page from the main document. +# +# This uses 'pdfjam' from the Tex Live package. +${DOC}.cover.pdf: ${DOC}.pdf ${GENERATED_VERSION_TEX} .PHONY + ${PDFJAM} -q -o ${DOC}.cover.pdf ${DOC}.pdf ${COVER_PAGE} +.endif + +CLEANFILES+= ${DOC}.cover.pdf + +# Converts the cover page to JPEG format, using US-Letter +# (8.5" x 11.0") dimensions. +# +# This step uses 'pdftoppm' from the Poppler package. +${DOC}.cover.usletter.jpeg: ${DOC}.cover.pdf .PHONY + _W=$$(echo 8.5 '*' ${COVER_DPI} | bc | sed -e 's/\.[0-9]*$$//'); \ + _H=$$(echo 11.0 '*' ${COVER_DPI} | bc | sed -e 's/\.[0-9]*$$//'); \ + pdftoppm -r ${COVER_DPI} -jpeg -scale-to-x $${_W} -scale-to-y $${_H} \ + -aa yes -freetype yes ${DOC}.cover.pdf > ${.TARGET} + +CLEANFILES+= ${DOC}.cover.usletter.jpeg + +# Recognize additional suffixes. +.SUFFIXES: .mp .eps .tex .pdf + +# Rules to build MetaPost figures. +.mp.eps: + @if [ "${.OBJDIR}" != "${.CURDIR}" ]; then cp ${.CURDIR}/${.IMPSRC:T} ${.OBJDIR}/; fi + TEX=${MPOSTTEX} ${MPOST} -halt-on-error ${.IMPSRC:T} || (rm ${.IMPSRC:T:R}.1; false) + mv ${.IMPSRC:T:R}.1 ${.TARGET} +.eps.pdf: + ${EPSTOPDF} ${.IMPSRC} > ${.TARGET} || (rm ${.TARGET}; false) + +.for f in ${IMAGES_MP} +${f:R}.eps: ${.CURDIR}/${f} +CLEANFILES+= ${f:R}.eps ${f:R}.log ${f:R}.pdf ${f:R}.mpx +.endfor + +CLEANFILES+= mpxerr.tex mpxerr.log makempx.log missfont.log + +${DOC}.pdf: ${SRCS} ${IMAGES_MP:S/.mp$/.pdf/g} ${GENERATED_VERSION_TEX} + ${_TEX} ${.CURDIR}/${DOC}.tex > /dev/null || \ + (cat ${DOC}.log; rm -f ${.TARGET}; exit 1) + @if grep 'undefined references' ${DOC}.log > /dev/null; then \ + ${_TEX} ${.CURDIR}/${DOC}.tex > /dev/null; \ + fi + @if grep 'Rerun to get' ${DOC}.log > /dev/null; then \ + ${_TEX} ${.CURDIR}/${DOC}.tex > /dev/null; \ + fi + +.if defined(GENERATED_VERSION_TEX) +CLEANFILES+= ${GENERATED_VERSION_TEX} + +${GENERATED_VERSION_TEX}: .PHONY + ${.CURDIR}/${TOP}/libelftc/make-toolchain-version -t ${TOP} \ + -o ${.TARGET} -h '' -p +.endif + +CLEANFILES+= ${DOC}.pdf + +# Remove temporary files. +.for file in ${DOC} ${DOC}.cover ${COVER_SRCS:M*.tex:C/.tex$//1g} +.for ext in aux log out toc ind idx ilg +CLEANFILES+= ${file}.${ext} +.endfor +.endfor + +# Do something sensible for the `depend` and `cleandepend` targets. +depend: .depend + @true +.depend: + @echo ${DOC}.pdf: ${SRCS} ${IMAGES_MP:S/.mp$/.pdf/g} > ${.TARGET} +cleandepend: .PHONY + rm -f .depend + +clean clobber: .PHONY + rm -f ${CLEANFILES} + +install: all + @mkdir -p ${DESTDIR}/${DOCDIR}/${DOCSUBDIR} + ${INSTALL} -g ${DOCGRP} -o ${DOCOWN} ${DOC}.pdf \ + ${DESTDIR}/${DOCDIR}/${DOCSUBDIR} + +# Include rules for `make obj` +.include + +.else + +all clean cleandepend clobber depend install obj: .PHONY .SILENT + echo -n WARNING: make \"${.TARGET}\" in \"${.CURDIR:T}\" skipped: +.if defined(MKTEX) && ${MKTEX} == "yes" + echo " missing tools." +.else + echo " builds of TeX documentation are disabled." +.endif + true +.endif diff --git a/contrib/elftoolchain/mk/os.Darwin.mk b/contrib/elftoolchain/mk/os.Darwin.mk new file mode 100644 index 0000000000..450c671abd --- /dev/null +++ b/contrib/elftoolchain/mk/os.Darwin.mk @@ -0,0 +1,8 @@ +# $Id$ +# +# Build definitions for Darwin + +# Apple ships libarchive, but for some reason does not provide the headers. +# Build against a homebrew-provided libarchive library and headers. +LDFLAGS+= -L/usr/local/opt/libarchive/lib +CFLAGS+= -I/usr/local/opt/libarchive/include diff --git a/contrib/elftoolchain/mk/os.DragonFly.mk b/contrib/elftoolchain/mk/os.DragonFly.mk new file mode 100644 index 0000000000..7cb4294f0d --- /dev/null +++ b/contrib/elftoolchain/mk/os.DragonFly.mk @@ -0,0 +1,9 @@ +# $Id: os.DragonFly.mk 2569 2012-09-04 16:34:04Z jkoshy $ +# +# Build definitions for DragonFly + +MKTESTS?= yes # Enable the test suites. +MKDOC?= yes # Build documentation. +MKNOWEB?= no # Build literate programs. + +NOSHARED= yes # Link programs statically by default. diff --git a/contrib/elftoolchain/mk/os.FreeBSD.mk b/contrib/elftoolchain/mk/os.FreeBSD.mk new file mode 100644 index 0000000000..105ade2e64 --- /dev/null +++ b/contrib/elftoolchain/mk/os.FreeBSD.mk @@ -0,0 +1,29 @@ +# $Id: os.FreeBSD.mk 4004 2023-04-16 18:12:54Z jkoshy $ +# +# Build definitions for FreeBSD + +MKDOC?= yes # Build documentation. +MKTESTS?= yes # Enable the test suites. +MKTEX?= yes # TeX and friends are packaged in the teTeX package. +MKNOWEB?= no # Build literate programs. + +# Link programs statically by default. +NO_SHARED?= yes + +.if defined(MKTEX) && ${MKTEX} == "yes" +EPSTOPDF?= /usr/local/bin/epstopdf +MAKEINDEX?= /usr/local/bin/makeindex +MPOSTTEX?= /usr/local/bin/latex +MPOST?= /usr/local/bin/mpost +PDFJAM?= /usr/local/bin/pdfjam +PDFLATEX?= /usr/local/bin/pdflatex +.endif + +# Translate the spelling of a build knob (see ticket #316). +.if defined(NOMAN) +MK_MAN= no # FreeBSD 7 and later. +.endif + +# Literate programming utility. +NOWEB?= /usr/local/bin/noweb +PYTHON?= /usr/local/bin/python3.9 diff --git a/contrib/elftoolchain/mk/os.Linux.mk b/contrib/elftoolchain/mk/os.Linux.mk new file mode 100644 index 0000000000..cfd1ee515c --- /dev/null +++ b/contrib/elftoolchain/mk/os.Linux.mk @@ -0,0 +1,31 @@ +# $Id: os.Linux.mk 4021 2023-12-09 13:21:19Z jkoshy $ +# +# Build recipes for GNU/Linux based operating systems. + +OS_DISTRIBUTION != lsb_release -s -i || echo unknown +OS_DISTRIBUTION_VERSION != lsb_release -s -r || echo unknown + +.if ${OS_DISTRIBUTION} == "unknown" || \ + ${OS_DISTRIBUTION_VERSION} == "unknown" +.error ERROR: Unknown host OS distribution. +.endif + +MKDOC?= yes # Build documentation. +MKLINT?= no +NOPIC?= yes # Do not build shared libraries. +MKNOWEB?= yes # Build literate programs. +MKTESTS?= yes # Enable the test suites. +MKTEX?= yes # Build TeX-based documentation. + +OBJECT_FORMAT= ELF # work around a bug in the pmake package + +YFLAGS+= -d # force bison to write y.tab.h + +EPSTOPDF?= /usr/bin/epstopdf +MAKEINDEX?= /usr/bin/makeindex +MPOST?= /usr/bin/mpost +MPOSTTEX?= /usr/bin/latex +NOWEB?= /usr/bin/noweb +PDFJAM?= /usr/bin/pdfjam +PDFLATEX?= /usr/bin/pdflatex +PYTHON?= /usr/bin/python3 diff --git a/contrib/elftoolchain/mk/os.Minix.mk b/contrib/elftoolchain/mk/os.Minix.mk new file mode 100644 index 0000000000..f975fea20d --- /dev/null +++ b/contrib/elftoolchain/mk/os.Minix.mk @@ -0,0 +1,16 @@ +# $Id: os.Minix.mk 2569 2012-09-04 16:34:04Z jkoshy $ +# +# Build definitions for Minix 3.2.0. + +MKDOC?= yes # Build documentation. +MKTESTS?= no # Enable the test suites. +MKNOWEB?= no # Build literate programs. + +# Use GCC to compile the source tree. +CC=/usr/pkg/bin/gcc + +# Use the correct compiler type (override ). +COMPILER_TYPE=gnu + +# Also choose GNU 'ar'. +AR=ar diff --git a/contrib/elftoolchain/mk/os.NetBSD.mk b/contrib/elftoolchain/mk/os.NetBSD.mk new file mode 100644 index 0000000000..0cfd874947 --- /dev/null +++ b/contrib/elftoolchain/mk/os.NetBSD.mk @@ -0,0 +1,22 @@ +# $Id: os.NetBSD.mk 3888 2020-11-11 19:26:14Z jkoshy $ +# +# Build recipes for NetBSD. + +LDSTATIC?= -static # link programs statically + +MKDOC?= yes # Build documentation. +MKLINT?= no # lint dies with a sigbus +MKTESTS?= yes # Enable the test suites. +MKNOWEB?= no # Build literate programs. +PYTHON?= /usr/pkg/bin/python3.8 + +# Literate programming utility. +NOWEB?= /usr/pkgsrc/bin/noweb + +# NetBSD's 'clean' target does not remove 'cat[0-9]' and 'html[0-9]' +# files generate from manual page sources. Augment the 'clobber' +# target to remove these. +os-specific-clobber: .PHONY +.for f in cat html + rm -f ${MANPAGES:@M@${M:R}.$f${M:E}@} +.endfor diff --git a/contrib/elftoolchain/mk/os.OpenBSD.mk b/contrib/elftoolchain/mk/os.OpenBSD.mk new file mode 100644 index 0000000000..4f7bc3a425 --- /dev/null +++ b/contrib/elftoolchain/mk/os.OpenBSD.mk @@ -0,0 +1,9 @@ +# $Id$ +# +# Build recipes for OpenBSD. + +MKDOC?= no # Build documentation. +MKTESTS?= yes # Enable the test suites. +MKNOWEB?= no # Build literate programs. + +NOPIC?= yes diff --git a/contrib/elftoolchain/nm/Makefile b/contrib/elftoolchain/nm/Makefile new file mode 100644 index 0000000000..6177c61221 --- /dev/null +++ b/contrib/elftoolchain/nm/Makefile @@ -0,0 +1,13 @@ + +# $Id: Makefile 2076 2011-10-27 03:50:33Z jkoshy $ + +TOP= .. + +PROG= nm +SRCS= nm.c + +WARNS?= 6 + +LDADD= -ldwarf -lelftc -lelf + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/nm/nm.1 b/contrib/elftoolchain/nm/nm.1 new file mode 100644 index 0000000000..3786caa8ad --- /dev/null +++ b/contrib/elftoolchain/nm/nm.1 @@ -0,0 +1,340 @@ +.\" Copyright (c) 2007 Hyogeol Lee +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: nm.1 3642 2018-10-14 14:24:28Z jkoshy $ +.\" +.Dd September 13, 2017 +.Dt NM 1 +.Os +.Sh NAME +.Nm nm +.Nd display symbolic information in object files +.Sh SYNOPSIS +.Nm +.Op Fl -debug-syms +.Op Fl -defined-only +.Op Fl -demangle Ns Op = Ns style +.Op Fl -dynamic +.Op Fl -extern-only +.Op Fl -help +.Op Fl -line-numbers +.Op Fl -no-demangle +.Op Fl -no-sort +.Op Fl -numeric-sort +.Op Fl -print-armap +.Op Fl -print-file-name +.Op Fl -print-size +.Op Fl -radix= Ns Ar format +.Op Fl -reverse-sort +.Op Fl -size-sort +.Op Fl -undefined-only +.Op Fl -version +.Op Fl A +.Op Fl B +.Op Fl C Op Ar style +.Op Fl D +.Op Fl P +.Op Fl V +.Op Fl a +.Op Fl e +.Op Fl g +.Op Fl h +.Op Fl l +.Op Fl n +.Op Fl o +.Op Fl p +.Op Fl r +.Op Fl S +.Op Fl s +.Op Fl t Ar format +.Op Fl u +.Op Fl x +.Ar +.Sh DESCRIPTION +The +.Nm +utility displays symbolic information in the object files, +executables, and object library files named by its arguments. +Lack of symbolic information in an otherwise valid input +file, is not considered to be an error. +If no files are specified on the command line, +.Nm +will attempt to read +.Pa a.out . +.Pp +The +.Nm +utility recognizes the following options: +.Bl -tag -width ".Fl d Ar argument" +.It Fl -debug-syms +Display all symbols, including debugger-only symbols. +.It Fl -defined-only +Display only defined symbols. +.It Fl -demangle Ns Op = Ns Ar style +Decode (demangle) low-level symbol names into human-readable names. +Supported values for argument +.Ar style +are +.Sq auto , +.Sq gnu-v2 , +.Sq gnu-v3 +and +.Sq arm. +If argument +.Ar style +is not specified, it is taken to be +.Sq auto . +.It Fl -dynamic +Only display dynamic symbols. +This option is only meaningful for shared libraries. +.It Fl -extern-only +Only display information about global (external) symbols. +.It Fl -help +Display a help message and exit. +.It Fl -format Ns = Ns Ar format +Display output in the format specified by argument +.Ar format . +Supported values for the format argument are +.Sq bsd , +.Sq sysv , +and +.Sq posix . +The default output format is +.Sq bsd . +.It Fl -line-numbers +Display the filename and line number associated a symbol using +any debugging information present in the input file. +For defined symbols, look up the line number associated with +the address of the symbol. +For undefined symbols, look up the line number associated with +a relocation entry that refers to the symbol. +If line number information can be determined, it is displayed after +other symbol information. +.It Fl -no-demangle +Do not demangle symbol names (default). +.It Fl -no-sort +Do not sort symbols. +.It Fl -numeric-sort +Sort symbols numerically by address instead of alphabetically by name. +.It Fl -print-armap +For +.Xr ar 1 +archives, include the index of the archive's members. +.It Fl -print-file-name +Write the full pathname or library name of an object on each line, +before the rest of the information for a symbol. +If this option is not specified, +.Nm +will only identify an input file once, before its symbols are +listed. +.It Fl -print-size +Print the size of each symbol instead of its value. +.It Fl -radix Ns = Ns Ar radix +Print numeric values using the specified radix. +Supported values for argument +.Ar radix +are +.Sq d +for decimal, +.Sq o +for octal, and +.Sq x +for hexadecimal. +.It Fl -reverse-sort +Reverse the order of the sort. +.It Fl -size-sort +Sort symbols by size instead of alphabetically by name. +.It Fl -undefined-only +Display only undefined symbols. +.It Fl -version +Display the version identifier for +.Nm +and exit. +.It Fl A +Equivalent to specifying option +.Fl -print-file-name . +.It Fl B +Equivalent to specifying option +.Fl -format= Ns Ar bsd . +.It Fl C Op Ar style +Equivalent to specifying option +.Fl -demangle Ns Op = Ns Ar style . +.It Fl D +Equivalent to specifying option +.Fl -dynamic . +.It Fl F Ar format +Equivalent to specifying option +.Fl -format Ns = Ns Ar format . +.It Fl P +Equivalent to specifying option +.Fl -format Ns = Ns Ar posix . +.It Fl S +Equivalent to specifying option +.Fl -print-size . +.It Fl V +Equivalent to specifying option +.Fl -version . +.It Fl a +Equivalent to specifying option +.Fl -debug-syms . +.It Fl e +Only display information for global and static symbols. +.It Fl f +Produce full output (default). +.It Fl g +Equivalent to specifying option +.Fl -extern-only . +.It Fl h +Equivalent to specifying option +.Fl -help . +.It Fl l +Equivalent to specifying option +.Fl -line-numbers . +.It Fl n +Equivalent to specifying option +.Fl -numeric-sort . +.It Fl o +If POSIX output was specified using the +.Fl F Ar posix +or +.Fl P +options, this option is equivalent to specifying +.Fl -radix Ns = Ns Sq Ar o . +If POSIX output was not specified, this option +acts as a synonym for the +.Fl -print-file-name +option. +.It Fl p +Equivalent to specifying option +.Fl -no-sort . +.It Fl v +Equivalent to option +.Fl n . +.It Fl r +Equivalent to specifying option +.Fl -reverse-sort +.It Fl s +Equivalent to specifying option +.Fl -print-armap . +.It Fl t Ar radix +Equivalent to specifying option +.Fl -radix= Ns Ar radix . +.It Fl u +Equivalent to specifying option +.Fl -undefined-only . +.It Fl x +Write numeric values in hexadecimal (equivalent to -t x). +.El +.Sh OUTPUT FORMAT +.Pp +The +.Nm +utility can present its information in a number of formats, numeric +radices and sort orders. +By default +.Nm +uses BSD style output, a hexadecimal radix, without output sorted +alphabetically by name and without demangling of names. +.Pp +For each symbol listed, +.Nm +presents the following information: +.Bl -bullet -compact +.It +The library or object name, if options +.Fl A +or +.Fl -print-file-name +were specified. +.It +The symbol name. +.It +The type of the symbol denoted by a single character as below: +.Bl -tag -compact -width indent +.It A +A global, absolute symbol. +.It B +A global +.Dq bss +(uninitialized data) symbol. +.It C +A +.Dq common +symbol, representing uninitialized data. +.It D +A global symbol naming initialized data. +.It N +A debugger symbol. +.It R +A read-only data symbol. +.It T +A global text symbol. +.It U +An undefined symbol. +.It V +A weak object. +.It W +A weak reference. +.It a +A local absolute symbol. +.It b +A local +.Dq bss +(uninitialized data) symbol. +.It d +A local data symbol. +.It r +A local read-only data symbol. +.It t +A local text symbol. +.It v +A weak object that is undefined. +.It w +A weak symbol that is undefined. +.It ? +None of the above. +.El +.It +The value of the symbol. +.It +The size of the symbol if applicable. +.It +Line number information, if available and if options +.Fl l +or +.Fl -line-numbers +were specified. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr ar 1 , +.Xr objdump 1 , +.Xr ranlib 1 , +.Xr elf 3 +.Sh AUTHORS +The +.Nm +utility and this manual page were written by +.An Hyogeol Lee Aq Mt hyogeollee@gmail.com . diff --git a/contrib/elftoolchain/nm/nm.c b/contrib/elftoolchain/nm/nm.c new file mode 100644 index 0000000000..cdef6fca14 --- /dev/null +++ b/contrib/elftoolchain/nm/nm.c @@ -0,0 +1,2120 @@ +/*- + * Copyright (c) 2007 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: nm.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +/* symbol information list */ +STAILQ_HEAD(sym_head, sym_entry); + +struct sym_entry { + char *name; + GElf_Sym *sym; + STAILQ_ENTRY(sym_entry) sym_entries; +}; + +typedef int (*fn_sort)(const void *, const void *); +typedef void (*fn_elem_print)(char, const char *, const GElf_Sym *, const char *); +typedef void (*fn_sym_print)(const GElf_Sym *); +typedef int (*fn_filter)(char, const GElf_Sym *, const char *); + +/* output filter list */ +static SLIST_HEAD(filter_head, filter_entry) nm_out_filter = + SLIST_HEAD_INITIALIZER(nm_out_filter); + +struct filter_entry { + fn_filter fn; + SLIST_ENTRY(filter_entry) filter_entries; +}; + +struct sym_print_data { + struct sym_head *headp; + size_t sh_num, list_num; + const char *t_table, **s_table, *filename, *objname; +}; + +struct nm_prog_info { + const char *name; + const char *def_filename; +}; + +/* List for line number information. */ +struct line_info_entry { + uint64_t addr; /* address */ + uint64_t line; /* line number */ + char *file; /* file name with path */ + SLIST_ENTRY(line_info_entry) entries; +}; +SLIST_HEAD(line_info_head, line_info_entry); + +/* List for function line number information. */ +struct func_info_entry { + char *name; /* function name */ + char *file; /* file name with path */ + uint64_t lowpc; /* low address */ + uint64_t highpc; /* high address */ + uint64_t line; /* line number */ + SLIST_ENTRY(func_info_entry) entries; +}; +SLIST_HEAD(func_info_head, func_info_entry); + +/* List for variable line number information. */ +struct var_info_entry { + char *name; /* variable name */ + char *file; /* file name with path */ + uint64_t addr; /* address */ + uint64_t line; /* line number */ + SLIST_ENTRY(var_info_entry) entries; +}; +SLIST_HEAD(var_info_head, var_info_entry); + +/* output numric type */ +enum radix { + RADIX_OCT, + RADIX_HEX, + RADIX_DEC +}; + +/* output symbol type, PRINT_SYM_DYN for dynamic symbol only */ +enum print_symbol { + PRINT_SYM_SYM, + PRINT_SYM_DYN +}; + +/* output name type */ +enum print_name { + PRINT_NAME_NONE, + PRINT_NAME_FULL, + PRINT_NAME_MULTI +}; + +struct nm_prog_options { + enum print_symbol print_symbol; + enum print_name print_name; + enum radix t; + int demangle_type; + bool print_debug; + bool print_armap; + int print_size; + bool debug_line; + int def_only; + bool undef_only; + int sort_size; + bool sort_reverse; + int no_demangle; + + /* + * function pointer to sort symbol list. + * possible function - cmp_name, cmp_none, cmp_size, cmp_value + */ + fn_sort sort_fn; + + /* + * function pointer to print symbol elem. + * possible function - sym_elem_print_all + * sym_elem_print_all_portable + * sym_elem_print_all_sysv + */ + fn_elem_print elem_print_fn; + + fn_sym_print value_print_fn; + fn_sym_print size_print_fn; +}; + +#define CHECK_SYM_PRINT_DATA(p) (p->headp == NULL || p->sh_num == 0 || \ +p->t_table == NULL || p->s_table == NULL || p->filename == NULL) +#define IS_SYM_TYPE(t) ((t) == '?' || isalpha((t)) != 0) +#define IS_UNDEF_SYM_TYPE(t) ((t) == 'U' || (t) == 'v' || (t) == 'w') +#define UNUSED(p) ((void)p) + +static int cmp_name(const void *, const void *); +static int cmp_none(const void *, const void *); +static int cmp_size(const void *, const void *); +static int cmp_value(const void *, const void *); +static void filter_dest(void); +static int filter_insert(fn_filter); +static void get_opt(int, char **); +static int get_sym(Elf *, struct sym_head *, int, size_t, size_t, + const char *, const char **, int); +static const char * get_sym_name(Elf *, const GElf_Sym *, size_t, + const char **, int); +static char get_sym_type(const GElf_Sym *, const char *); +static void global_dest(void); +static void global_init(void); +static bool is_sec_data(GElf_Shdr *); +static bool is_sec_debug(const char *); +static bool is_sec_nobits(GElf_Shdr *); +static bool is_sec_readonly(GElf_Shdr *); +static bool is_sec_text(GElf_Shdr *); +static void print_ar_index(int, Elf *); +static void print_header(const char *, const char *); +static void print_version(void); +static int read_elf(Elf *, const char *, Elf_Kind); +static int read_object(const char *); +static int read_files(int, char **); +static void set_opt_value_print_fn(enum radix); +static int sym_elem_def(char, const GElf_Sym *, const char *); +static int sym_elem_global(char, const GElf_Sym *, const char *); +static int sym_elem_global_static(char, const GElf_Sym *, + const char *); +static int sym_elem_nondebug(char, const GElf_Sym *, const char *); +static int sym_elem_nonzero_size(char, const GElf_Sym *, + const char *); +static void sym_elem_print_all(char, const char *, + const GElf_Sym *, const char *); +static void sym_elem_print_all_portable(char, const char *, + const GElf_Sym *, const char *); +static void sym_elem_print_all_sysv(char, const char *, + const GElf_Sym *, const char *); +static int sym_elem_undef(char, const GElf_Sym *, const char *); +static void sym_list_dest(struct sym_head *); +static int sym_list_insert(struct sym_head *, const char *, + const GElf_Sym *); +static void sym_list_print(struct sym_print_data *, + struct func_info_head *, struct var_info_head *, + struct line_info_head *); +static void sym_list_print_each(struct sym_entry *, + struct sym_print_data *, struct func_info_head *, + struct var_info_head *, struct line_info_head *); +static struct sym_entry *sym_list_sort(struct sym_print_data *); +static void sym_size_oct_print(const GElf_Sym *); +static void sym_size_hex_print(const GElf_Sym *); +static void sym_size_dec_print(const GElf_Sym *); +static void sym_value_oct_print(const GElf_Sym *); +static void sym_value_hex_print(const GElf_Sym *); +static void sym_value_dec_print(const GElf_Sym *); +static void usage(int); + +static struct nm_prog_info nm_info; +static struct nm_prog_options nm_opts; +static int nm_elfclass; + +/* + * Point to current sym_print_data to use portable qsort function. + * (e.g. There is no qsort_r function in NetBSD.) + * + * Using in sym_list_sort. + */ +static struct sym_print_data *nm_print_data; + +static const struct option nm_longopts[] = { + { "debug-syms", no_argument, NULL, 'a' }, + { "defined-only", no_argument, &nm_opts.def_only, 1}, + { "demangle", optional_argument, NULL, 'C' }, + { "dynamic", no_argument, NULL, 'D' }, + { "extern-only", no_argument, NULL, 'g' }, + { "format", required_argument, NULL, 'F' }, + { "help", no_argument, NULL, 'h' }, + { "line-numbers", no_argument, NULL, 'l' }, + { "no-demangle", no_argument, &nm_opts.no_demangle, + 1}, + { "no-sort", no_argument, NULL, 'p' }, + { "numeric-sort", no_argument, NULL, 'v' }, + { "print-armap", no_argument, NULL, 's' }, + { "print-file-name", no_argument, NULL, 'A' }, + { "print-size", no_argument, NULL, 'S' }, + { "radix", required_argument, NULL, 't' }, + { "reverse-sort", no_argument, NULL, 'r' }, + { "size-sort", no_argument, &nm_opts.sort_size, 1}, + { "undefined-only", no_argument, NULL, 'u' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +#if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) +static __inline uint32_t +be32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); +} + +static __inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static __inline uint64_t +be64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); +} + +static __inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} +#endif + +static int +cmp_name(const void *l, const void *r) +{ + + assert(l != NULL); + assert(r != NULL); + assert(((const struct sym_entry *)l)->name != NULL); + assert(((const struct sym_entry *)r)->name != NULL); + + return (strcmp(((const struct sym_entry *)l)->name, + ((const struct sym_entry *)r)->name)); +} + +static int +cmp_none(const void *l, const void *r) +{ + + UNUSED(l); + UNUSED(r); + + return (0); +} + +/* Size comparison. If l and r have same size, compare their name. */ +static int +cmp_size(const void *lp, const void *rp) +{ + const struct sym_entry *l, *r; + + l = lp; + r = rp; + + assert(l != NULL); + assert(l->name != NULL); + assert(l->sym != NULL); + assert(r != NULL); + assert(r->name != NULL); + assert(r->sym != NULL); + + if (l->sym->st_size == r->sym->st_size) + return (strcmp(l->name, r->name)); + + return (l->sym->st_size - r->sym->st_size); +} + +/* Value comparison. Undefined symbols come first. */ +static int +cmp_value(const void *lp, const void *rp) +{ + const struct sym_entry *l, *r; + const char *ttable; + int l_is_undef, r_is_undef; + + l = lp; + r = rp; + + assert(nm_print_data != NULL); + ttable = nm_print_data->t_table; + + assert(l != NULL); + assert(l->name != NULL); + assert(l->sym != NULL); + assert(r != NULL); + assert(r->name != NULL); + assert(r->sym != NULL); + assert(ttable != NULL); + + l_is_undef = IS_UNDEF_SYM_TYPE(get_sym_type(l->sym, ttable)) ? 1 : 0; + r_is_undef = IS_UNDEF_SYM_TYPE(get_sym_type(r->sym, ttable)) ? 1 : 0; + + assert(l_is_undef + r_is_undef >= 0); + assert(l_is_undef + r_is_undef <= 2); + + switch (l_is_undef + r_is_undef) { + case 0: + /* Both defined */ + if (l->sym->st_value == r->sym->st_value) + return (strcmp(l->name, r->name)); + return (l->sym->st_value > r->sym->st_value ? 1 : -1); + case 1: + /* One undefined */ + return (l_is_undef == 0 ? 1 : -1); + case 2: + /* Both undefined */ + return (strcmp(l->name, r->name)); + } + /* NOTREACHED */ + + return (l->sym->st_value - r->sym->st_value); +} + +static void +filter_dest(void) +{ + struct filter_entry *e; + + while (!SLIST_EMPTY(&nm_out_filter)) { + e = SLIST_FIRST(&nm_out_filter); + SLIST_REMOVE_HEAD(&nm_out_filter, filter_entries); + free(e); + } +} + +static int +filter_insert(fn_filter filter_fn) +{ + struct filter_entry *e; + + assert(filter_fn != NULL); + + if ((e = malloc(sizeof(struct filter_entry))) == NULL) { + warn("malloc"); + return (0); + } + e->fn = filter_fn; + SLIST_INSERT_HEAD(&nm_out_filter, e, filter_entries); + + return (1); +} + +static int +parse_demangle_option(const char *opt) +{ + + if (opt == NULL) + return (ELFTC_DEM_UNKNOWN); + else if (!strncasecmp(opt, "gnu-v2", 6)) + return (ELFTC_DEM_GNU2); + else if (!strncasecmp(opt, "gnu-v3", 6)) + return (ELFTC_DEM_GNU3); + else if (!strncasecmp(opt, "arm", 3)) + return (ELFTC_DEM_ARM); + else + errx(EXIT_FAILURE, "unknown demangling style '%s'", opt); + + /* NOTREACHED */ + return (0); +} + +static void +get_opt(int argc, char **argv) +{ + int ch; + bool is_posix, oflag; + + if (argc <= 0 || argv == NULL) + return; + + oflag = is_posix = false; + nm_opts.t = RADIX_HEX; + while ((ch = getopt_long(argc, argv, "ABCDF:PSVaefghlnoprst:uvx", + nm_longopts, NULL)) != -1) { + switch (ch) { + case 'A': + nm_opts.print_name = PRINT_NAME_FULL; + break; + case 'B': + nm_opts.elem_print_fn = &sym_elem_print_all; + break; + case 'C': + nm_opts.demangle_type = parse_demangle_option(optarg); + break; + case 'D': + nm_opts.print_symbol = PRINT_SYM_DYN; + break; + case 'F': + /* sysv, bsd, posix */ + switch (optarg[0]) { + case 'B': + case 'b': + nm_opts.elem_print_fn = &sym_elem_print_all; + break; + case 'P': + case 'p': + is_posix = true; + nm_opts.elem_print_fn = + &sym_elem_print_all_portable; + break; + case 'S': + case 's': + nm_opts.elem_print_fn = + &sym_elem_print_all_sysv; + break; + default: + warnx("%s: Invalid format", optarg); + usage(EX_USAGE); + } + + break; + case 'P': + is_posix = true; + nm_opts.elem_print_fn = &sym_elem_print_all_portable; + break; + case 'S': + nm_opts.print_size = 1; + break; + case 'V': + print_version(); + break; + case 'a': + nm_opts.print_debug = true; + break; + case 'e': + filter_insert(sym_elem_global_static); + break; + case 'f': + break; + case 'g': + filter_insert(sym_elem_global); + break; + case 'h': + usage(EX_OK); + break; + case 'l': + nm_opts.debug_line = true; + break; + case 'n': + case 'v': + nm_opts.sort_fn = &cmp_value; + break; + case 'o': + oflag = true; + break; + case 'p': + nm_opts.sort_fn = &cmp_none; + break; + case 'r': + nm_opts.sort_reverse = true; + break; + case 's': + nm_opts.print_armap = true; + break; + case 't': + /* t require always argument to getopt_long */ + switch (optarg[0]) { + case 'd': + nm_opts.t = RADIX_DEC; + break; + case 'o': + nm_opts.t = RADIX_OCT; + break; + case 'x': + nm_opts.t = RADIX_HEX; + break; + default: + warnx("%s: Invalid radix", optarg); + usage(EX_USAGE); + } + break; + case 'u': + filter_insert(sym_elem_undef); + nm_opts.undef_only = true; + break; + /* case 'v': see case 'n' above. */ + case 'x': + nm_opts.t = RADIX_HEX; + break; + case 0: + if (nm_opts.sort_size != 0) { + nm_opts.sort_fn = &cmp_size; + filter_insert(sym_elem_def); + filter_insert(sym_elem_nonzero_size); + } + if (nm_opts.def_only != 0) + filter_insert(sym_elem_def); + if (nm_opts.no_demangle != 0) + nm_opts.demangle_type = -1; + break; + default : + usage(EX_USAGE); + } + } + + /* + * In POSIX mode, the '-o' option controls the output radix. + * In non-POSIX mode, the option is a synonym for the '-A' and + * '--print-file-name' options. + */ + if (oflag) { + if (is_posix) + nm_opts.t = RADIX_OCT; + else + nm_opts.print_name = PRINT_NAME_FULL; + } + + assert(nm_opts.sort_fn != NULL && "nm_opts.sort_fn is null"); + assert(nm_opts.elem_print_fn != NULL && + "nm_opts.elem_print_fn is null"); + assert(nm_opts.value_print_fn != NULL && + "nm_opts.value_print_fn is null"); + + set_opt_value_print_fn(nm_opts.t); + + if (nm_opts.undef_only == true) { + if (nm_opts.sort_fn == &cmp_size) + errx(EXIT_FAILURE, + "--size-sort with -u is meaningless"); + if (nm_opts.def_only != 0) + errx(EXIT_FAILURE, + "-u with --defined-only is meaningless"); + } + if (nm_opts.print_debug == false) + filter_insert(sym_elem_nondebug); + if (nm_opts.sort_reverse == true && nm_opts.sort_fn == cmp_none) + nm_opts.sort_reverse = false; +} + +/* + * Get symbol information from elf. + */ +static int +get_sym(Elf *elf, struct sym_head *headp, int shnum, size_t dynndx, + size_t strndx, const char *type_table, const char **sec_table, + int sec_table_size) +{ + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + GElf_Sym sym; + struct filter_entry *fep; + size_t ndx; + int rtn; + const char *sym_name; + char type; + bool filter; + int i, j; + + assert(elf != NULL); + assert(headp != NULL); + + rtn = 0; + for (i = 1; i < shnum; i++) { + if ((scn = elf_getscn(elf, i)) == NULL) { + warnx("elf_getscn failed: %s", elf_errmsg(-1)); + continue; + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + continue; + } + if (shdr.sh_type == SHT_SYMTAB) { + if (nm_opts.print_symbol != PRINT_SYM_SYM) + continue; + } else if (shdr.sh_type == SHT_DYNSYM) { + if (nm_opts.print_symbol != PRINT_SYM_DYN) + continue; + } else + continue; + + ndx = shdr.sh_type == SHT_DYNSYM ? dynndx : strndx; + + data = NULL; + while ((data = elf_getdata(scn, data)) != NULL) { + j = 1; + while (gelf_getsym(data, j++, &sym) != NULL) { + sym_name = get_sym_name(elf, &sym, ndx, + sec_table, sec_table_size); + filter = false; + type = get_sym_type(&sym, type_table); + SLIST_FOREACH(fep, &nm_out_filter, + filter_entries) { + if (!fep->fn(type, &sym, sym_name)) { + filter = true; + break; + } + } + if (filter == false) { + if (sym_list_insert(headp, sym_name, + &sym) == 0) + return (0); + rtn++; + } + } + } + } + + return (rtn); +} + +static const char * +get_sym_name(Elf *elf, const GElf_Sym *sym, size_t ndx, const char **sec_table, + int sec_table_size) +{ + const char *sym_name; + + sym_name = NULL; + + /* Show section name as symbol name for STT_SECTION symbols. */ + if (GELF_ST_TYPE(sym->st_info) == STT_SECTION) { + if (sec_table != NULL && sym->st_shndx < sec_table_size) + sym_name = sec_table[sym->st_shndx]; + } else + sym_name = elf_strptr(elf, ndx, sym->st_name); + + if (sym_name == NULL) + sym_name = "(null)"; + + return (sym_name); +} + +static char +get_sym_type(const GElf_Sym *sym, const char *type_table) +{ + bool is_local; + + if (sym == NULL || type_table == NULL) + return ('?'); + + is_local = sym->st_info >> 4 == STB_LOCAL; + + if (sym->st_shndx == SHN_ABS) /* absolute */ + return (is_local ? 'a' : 'A'); + + if (sym->st_shndx == SHN_COMMON) /* common */ + return ('C'); + + if ((sym->st_info) >> 4 == STB_WEAK) { /* weak */ + if ((sym->st_info & 0xf) == STT_OBJECT) + return (sym->st_shndx == SHN_UNDEF ? 'v' : 'V'); + + return (sym->st_shndx == SHN_UNDEF ? 'w' : 'W'); + } + + if (sym->st_shndx == SHN_UNDEF) /* undefined */ + return ('U'); + + return (is_local == true && type_table[sym->st_shndx] != 'N' ? + tolower((unsigned char) type_table[sym->st_shndx]) : + type_table[sym->st_shndx]); +} + +static void +global_dest(void) +{ + + filter_dest(); +} + +static void +global_init(void) +{ + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "elf_version error"); + + nm_info.name = ELFTC_GETPROGNAME(); + nm_info.def_filename = "a.out"; + nm_opts.print_symbol = PRINT_SYM_SYM; + nm_opts.print_name = PRINT_NAME_NONE; + nm_opts.demangle_type = -1; + nm_opts.print_debug = false; + nm_opts.print_armap = false; + nm_opts.print_size = 0; + nm_opts.debug_line = false; + nm_opts.def_only = 0; + nm_opts.undef_only = false; + nm_opts.sort_size = 0; + nm_opts.sort_reverse = false; + nm_opts.no_demangle = 0; + nm_opts.sort_fn = &cmp_name; + nm_opts.elem_print_fn = &sym_elem_print_all; + nm_opts.value_print_fn = &sym_value_dec_print; + nm_opts.size_print_fn = &sym_size_dec_print; + SLIST_INIT(&nm_out_filter); +} + +static bool +is_sec_data(GElf_Shdr *s) +{ + + assert(s != NULL && "shdr is NULL"); + + return (((s->sh_flags & SHF_ALLOC) != 0) && s->sh_type != SHT_NOBITS); +} + +static bool +is_sec_debug(const char *shname) +{ + const char *dbg_sec[] = { + ".debug", + ".gnu.linkonce.wi.", + ".line", + ".rel.debug", + ".rela.debug", + ".stab", + NULL + }; + const char **p; + + if (shname == NULL) + return (false); + + for (p = dbg_sec; *p; p++) { + if (!strncmp(shname, *p, strlen(*p))) + return (true); + } + + return (false); +} + +static bool +is_sec_nobits(GElf_Shdr *s) +{ + + assert(s != NULL && "shdr is NULL"); + + return (s->sh_type == SHT_NOBITS); +} + +static bool +is_sec_readonly(GElf_Shdr *s) +{ + + assert(s != NULL && "shdr is NULL"); + + return ((s->sh_flags & SHF_WRITE) == 0); +} + +static bool +is_sec_text(GElf_Shdr *s) +{ + + assert(s != NULL && "shdr is NULL"); + + return ((s->sh_flags & SHF_EXECINSTR) != 0); +} + +static void +print_ar_index(int fd, Elf *arf) +{ + Elf *elf; + Elf_Arhdr *arhdr; + Elf_Arsym *arsym; + Elf_Cmd cmd; + off_t start; + size_t arsym_size; + + if (arf == NULL) + return; + + if ((arsym = elf_getarsym(arf, &arsym_size)) == NULL) + return; + + printf("\nArchive index:\n"); + + start = arsym->as_off; + cmd = ELF_C_READ; + while (arsym_size > 1) { + if (elf_rand(arf, arsym->as_off) == arsym->as_off && + (elf = elf_begin(fd, cmd, arf)) != NULL) { + if ((arhdr = elf_getarhdr(elf)) != NULL) + printf("%s in %s\n", arsym->as_name, + arhdr->ar_name != NULL ? + arhdr->ar_name : arhdr->ar_rawname); + elf_end(elf); + } + ++arsym; + --arsym_size; + } + + elf_rand(arf, start); +} + +#define DEMANGLED_BUFFER_SIZE (8 * 1024) +#define PRINT_DEMANGLED_NAME(FORMAT, NAME) do { \ + char _demangled[DEMANGLED_BUFFER_SIZE]; \ + if (nm_opts.demangle_type < 0 || \ + elftc_demangle((NAME), _demangled, sizeof(_demangled), \ + nm_opts.demangle_type) < 0) \ + printf((FORMAT), (NAME)); \ + else \ + printf((FORMAT), _demangled); \ + } while (0) + +static void +print_header(const char *file, const char *obj) +{ + + if (file == NULL) + return; + + if (nm_opts.elem_print_fn == &sym_elem_print_all_sysv) { + printf("\n\n%s from %s", + nm_opts.undef_only == false ? "Symbols" : + "Undefined symbols", file); + if (obj != NULL) + printf("[%s]", obj); + printf(":\n\n"); + + printf("\ +Name Value Class Type Size Line Section\n\n"); + } else { + /* archive file without -A option and POSIX */ + if (nm_opts.print_name != PRINT_NAME_FULL && obj != NULL) { + if (nm_opts.elem_print_fn == + sym_elem_print_all_portable) + printf("%s[%s]:\n", file, obj); + else if (nm_opts.elem_print_fn == sym_elem_print_all) + printf("\n%s:\n", obj); + /* multiple files(not archive) without -A option */ + } else if (nm_opts.print_name == PRINT_NAME_MULTI) { + if (nm_opts.elem_print_fn == sym_elem_print_all) + printf("\n"); + printf("%s:\n", file); + } + } +} + +static void +print_version(void) +{ + + (void) printf("%s (%s)\n", nm_info.name, elftc_version()); + exit(0); +} + +static uint64_t +get_block_value(Dwarf_Debug dbg, Dwarf_Block *block) +{ + Elf *elf; + GElf_Ehdr eh; + Dwarf_Error de; + + if (dwarf_get_elf(dbg, &elf, &de) != DW_DLV_OK) { + warnx("dwarf_get_elf failed: %s", dwarf_errmsg(de)); + return (0); + } + + if (gelf_getehdr(elf, &eh) != &eh) { + warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); + return (0); + } + + if (block->bl_len == 5) { + if (eh.e_ident[EI_DATA] == ELFDATA2LSB) + return (le32dec((uint8_t *) block->bl_data + 1)); + else + return (be32dec((uint8_t *) block->bl_data + 1)); + } else if (block->bl_len == 9) { + if (eh.e_ident[EI_DATA] == ELFDATA2LSB) + return (le64dec((uint8_t *) block->bl_data + 1)); + else + return (be64dec((uint8_t *) block->bl_data + 1)); + } + + return (0); +} + +static char * +find_object_name(Dwarf_Debug dbg, Dwarf_Die die) +{ + Dwarf_Die ret_die; + Dwarf_Attribute at; + Dwarf_Off off; + Dwarf_Error de; + const char *str; + char *name; + + if (dwarf_attrval_string(die, DW_AT_name, &str, &de) == DW_DLV_OK) { + if ((name = strdup(str)) == NULL) { + warn("strdup"); + return (NULL); + } + return (name); + } + + if (dwarf_attr(die, DW_AT_specification, &at, &de) != DW_DLV_OK) + return (NULL); + + if (dwarf_global_formref(at, &off, &de) != DW_DLV_OK) + return (NULL); + + if (dwarf_offdie(dbg, off, &ret_die, &de) != DW_DLV_OK) + return (NULL); + + return (find_object_name(dbg, ret_die)); +} + +static void +search_line_attr(Dwarf_Debug dbg, struct func_info_head *func_info, + struct var_info_head *var_info, Dwarf_Die die, char **src_files, + Dwarf_Signed filecount) +{ + Dwarf_Attribute at; + Dwarf_Unsigned udata; + Dwarf_Half tag; + Dwarf_Block *block; + Dwarf_Bool flag; + Dwarf_Die ret_die; + Dwarf_Error de; + struct func_info_entry *func; + struct var_info_entry *var; + int ret; + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + + /* We're interested in DIEs which define functions or variables. */ + if (tag != DW_TAG_subprogram && tag != DW_TAG_entry_point && + tag != DW_TAG_inlined_subroutine && tag != DW_TAG_variable) + goto cont_search; + + if (tag == DW_TAG_variable) { + + /* Ignore "artificial" variable. */ + if (dwarf_attrval_flag(die, DW_AT_artificial, &flag, &de) == + DW_DLV_OK && flag) + goto cont_search; + + /* Ignore pure declaration. */ + if (dwarf_attrval_flag(die, DW_AT_declaration, &flag, &de) == + DW_DLV_OK && flag) + goto cont_search; + + /* Ignore stack varaibles. */ + if (dwarf_attrval_flag(die, DW_AT_external, &flag, &de) != + DW_DLV_OK || !flag) + goto cont_search; + + if ((var = calloc(1, sizeof(*var))) == NULL) { + warn("calloc failed"); + goto cont_search; + } + + if (dwarf_attrval_unsigned(die, DW_AT_decl_file, &udata, + &de) == DW_DLV_OK && udata > 0 && + (Dwarf_Signed) (udata - 1) < filecount) { + var->file = strdup(src_files[udata - 1]); + if (var->file == NULL) { + warn("strdup"); + free(var); + goto cont_search; + } + } + + if (dwarf_attrval_unsigned(die, DW_AT_decl_line, &udata, &de) == + DW_DLV_OK) + var->line = udata; + + var->name = find_object_name(dbg, die); + if (var->name == NULL) { + if (var->file) + free(var->file); + free(var); + goto cont_search; + } + + if (dwarf_attr(die, DW_AT_location, &at, &de) == DW_DLV_OK && + dwarf_formblock(at, &block, &de) == DW_DLV_OK) { + /* + * Since we ignored stack variables, the rest are the + * external varaibles which should always use DW_OP_addr + * operator for DW_AT_location value. + */ + if (*((uint8_t *)block->bl_data) == DW_OP_addr) + var->addr = get_block_value(dbg, block); + } + + SLIST_INSERT_HEAD(var_info, var, entries); + + } else { + + if ((func = calloc(1, sizeof(*func))) == NULL) { + warn("calloc failed"); + goto cont_search; + } + + /* + * Note that dwarf_attrval_unsigned() handles DW_AT_abstract_origin + * internally, so it can retrieve DW_AT_decl_file/DW_AT_decl_line + * attributes for inlined functions as well. + */ + if (dwarf_attrval_unsigned(die, DW_AT_decl_file, &udata, + &de) == DW_DLV_OK && udata > 0 && + (Dwarf_Signed) (udata - 1) < filecount) { + func->file = strdup(src_files[udata - 1]); + if (func->file == NULL) { + warn("strdup"); + free(func); + goto cont_search; + } + } + + if (dwarf_attrval_unsigned(die, DW_AT_decl_line, &udata, &de) == + DW_DLV_OK) + func->line = udata; + + func->name = find_object_name(dbg, die); + if (func->name == NULL) { + if (func->file) + free(func->file); + free(func); + goto cont_search; + } + + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &udata, &de) == + DW_DLV_OK) + func->lowpc = udata; + if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &udata, &de) == + DW_DLV_OK) + func->highpc = udata; + + SLIST_INSERT_HEAD(func_info, func, entries); + } + +cont_search: + + /* Search children. */ + ret = dwarf_child(die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_child: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + search_line_attr(dbg, func_info, var_info, ret_die, src_files, + filecount); + + /* Search sibling. */ + ret = dwarf_siblingof(dbg, die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + search_line_attr(dbg, func_info, var_info, ret_die, src_files, + filecount); + + dwarf_dealloc(dbg, die, DW_DLA_DIE); +} + +/* + * Read elf file and collect symbol information, sort them, print. + * Return 1 at failed, 0 at success. + */ +static int +read_elf(Elf *elf, const char *filename, Elf_Kind kind) +{ + Dwarf_Debug dbg; + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Half tag; + Elf_Arhdr *arhdr; + Elf_Scn *scn; + GElf_Shdr shdr; + Dwarf_Line *lbuf; + Dwarf_Unsigned lineno; + Dwarf_Signed lcount, filecount; + Dwarf_Addr lineaddr; + struct sym_print_data p_data; + struct sym_head list_head; + struct line_info_head *line_info; + struct func_info_head *func_info; + struct var_info_head *var_info; + struct line_info_entry *lie; + struct func_info_entry *func; + struct var_info_entry *var; + const char *shname, *objname; + char *type_table, **sec_table, *sfile, **src_files; + size_t i, shstrndx, shnum, dynndx, strndx; + int ret, rtn, e_err; + +#define OBJNAME (objname == NULL ? filename : objname) + + assert(filename != NULL && "filename is null"); + + STAILQ_INIT(&list_head); + type_table = NULL; + sec_table = NULL; + line_info = NULL; + func_info = NULL; + var_info = NULL; + objname = NULL; + dynndx = SHN_UNDEF; + strndx = SHN_UNDEF; + rtn = 0; + + nm_elfclass = gelf_getclass(elf); + + if (kind == ELF_K_AR) { + if ((arhdr = elf_getarhdr(elf)) == NULL) + goto next_cmd; + objname = arhdr->ar_name != NULL ? arhdr->ar_name : + arhdr->ar_rawname; + } + if (!elf_getshnum(elf, &shnum)) { + if ((e_err = elf_errno()) != 0) + warnx("%s: %s", OBJNAME, "File format not recognized"); + else + warnx("%s: cannot get section number", OBJNAME); + rtn = 1; + goto next_cmd; + } + if (shnum == 0) { + warnx("%s: has no section", OBJNAME); + rtn = 1; + goto next_cmd; + } + if (!elf_getshstrndx(elf, &shstrndx)) { + warnx("%s: cannot get str index", OBJNAME); + rtn = 1; + goto next_cmd; + } + /* type_table for type determine */ + if ((type_table = malloc(sizeof(char) * shnum)) == NULL) { + warn("%s: malloc", OBJNAME); + rtn = 1; + goto next_cmd; + } + /* sec_table for section name to display in sysv format */ + if ((sec_table = calloc(shnum, sizeof(char *))) == NULL) { + warn("%s: calloc", OBJNAME); + rtn = 1; + goto next_cmd; + } + + type_table[0] = 'U'; + if ((sec_table[0] = strdup("*UND*")) == NULL) { + warn("strdup"); + goto next_cmd; + } + + for (i = 1; i < shnum; ++i) { + type_table[i] = 'U'; + if ((scn = elf_getscn(elf, i)) == NULL) { + if ((e_err = elf_errno()) != 0) + warnx("%s: %s", OBJNAME, elf_errmsg(e_err)); + else + warnx("%s: cannot get section", OBJNAME); + rtn = 1; + goto next_cmd; + } + if (gelf_getshdr(scn, &shdr) == NULL) + goto next_cmd; + + /* + * Cannot test by type and attribute for dynstr, strtab + */ + shname = elf_strptr(elf, shstrndx, (size_t) shdr.sh_name); + if (shname != NULL) { + if ((sec_table[i] = strdup(shname)) == NULL) { + warn("strdup"); + goto next_cmd; + } + if (!strncmp(shname, ".dynstr", 7)) { + dynndx = elf_ndxscn(scn); + if (dynndx == SHN_UNDEF) { + warnx("%s: elf_ndxscn failed: %s", + OBJNAME, elf_errmsg(-1)); + goto next_cmd; + } + } + if (!strncmp(shname, ".strtab", 7)) { + strndx = elf_ndxscn(scn); + if (strndx == SHN_UNDEF) { + warnx("%s: elf_ndxscn failed: %s", + OBJNAME, elf_errmsg(-1)); + goto next_cmd; + } + } + } else { + sec_table[i] = strdup("*UND*"); + if (sec_table[i] == NULL) { + warn("strdup"); + goto next_cmd; + } + } + + + if (is_sec_text(&shdr)) + type_table[i] = 'T'; + else if (is_sec_data(&shdr)) { + if (is_sec_readonly(&shdr)) + type_table[i] = 'R'; + else + type_table[i] = 'D'; + } else if (is_sec_nobits(&shdr)) + type_table[i] = 'B'; + else if (is_sec_debug(shname)) + type_table[i] = 'N'; + else if (is_sec_readonly(&shdr) && !is_sec_nobits(&shdr)) + type_table[i] = 'n'; + } + + print_header(filename, objname); + + if ((dynndx == SHN_UNDEF && nm_opts.print_symbol == PRINT_SYM_DYN) || + (strndx == SHN_UNDEF && nm_opts.print_symbol == PRINT_SYM_SYM)) { + warnx("%s: no symbols", OBJNAME); + /* This is not an error case */ + goto next_cmd; + } + + STAILQ_INIT(&list_head); + + if (!nm_opts.debug_line) + goto process_sym; + + /* + * Collect dwarf line number information. + */ + + if (dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &de) != + DW_DLV_OK) { + warnx("dwarf_elf_init failed: %s", dwarf_errmsg(de)); + goto process_sym; + } + + line_info = malloc(sizeof(struct line_info_head)); + func_info = malloc(sizeof(struct func_info_head)); + var_info = malloc(sizeof(struct var_info_head)); + if (line_info == NULL || func_info == NULL || var_info == NULL) { + warn("malloc"); + (void) dwarf_finish(dbg, &de); + goto process_sym; + } + SLIST_INIT(line_info); + SLIST_INIT(func_info); + SLIST_INIT(var_info); + + while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de)) == DW_DLV_OK) { + die = NULL; + while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + /* XXX: What about DW_TAG_partial_unit? */ + if (tag == DW_TAG_compile_unit) + break; + } + if (die == NULL) { + warnx("could not find DW_TAG_compile_unit die"); + continue; + } + + /* Retrieve source file list. */ + ret = dwarf_srcfiles(die, &src_files, &filecount, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_srclines: %s", dwarf_errmsg(de)); + if (ret != DW_DLV_OK) + continue; + + /* + * Retrieve line number information from .debug_line section. + */ + + ret = dwarf_srclines(die, &lbuf, &lcount, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_srclines: %s", dwarf_errmsg(de)); + if (ret != DW_DLV_OK) + goto line_attr; + for (i = 0; (Dwarf_Signed) i < lcount; i++) { + if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) { + warnx("dwarf_lineaddr: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_lineno(lbuf[i], &lineno, &de)) { + warnx("dwarf_lineno: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_linesrc(lbuf[i], &sfile, &de)) { + warnx("dwarf_linesrc: %s", dwarf_errmsg(de)); + continue; + } + if ((lie = malloc(sizeof(*lie))) == NULL) { + warn("malloc"); + continue; + } + lie->addr = lineaddr; + lie->line = lineno; + lie->file = strdup(sfile); + if (lie->file == NULL) { + warn("strdup"); + free(lie); + continue; + } + SLIST_INSERT_HEAD(line_info, lie, entries); + } + + line_attr: + /* Retrieve line number information from DIEs. */ + search_line_attr(dbg, func_info, var_info, die, src_files, filecount); + } + + (void) dwarf_finish(dbg, &de); + +process_sym: + + p_data.list_num = get_sym(elf, &list_head, shnum, dynndx, strndx, + type_table, (void *) sec_table, shnum); + + if (p_data.list_num == 0) + goto next_cmd; + + p_data.headp = &list_head; + p_data.sh_num = shnum; + p_data.t_table = type_table; + p_data.s_table = (void *) sec_table; + p_data.filename = filename; + p_data.objname = objname; + + sym_list_print(&p_data, func_info, var_info, line_info); + +next_cmd: + if (nm_opts.debug_line) { + if (func_info != NULL) { + while (!SLIST_EMPTY(func_info)) { + func = SLIST_FIRST(func_info); + SLIST_REMOVE_HEAD(func_info, entries); + free(func->file); + free(func->name); + free(func); + } + free(func_info); + func_info = NULL; + } + if (var_info != NULL) { + while (!SLIST_EMPTY(var_info)) { + var = SLIST_FIRST(var_info); + SLIST_REMOVE_HEAD(var_info, entries); + free(var->file); + free(var->name); + free(var); + } + free(var_info); + var_info = NULL; + } + if (line_info != NULL) { + while (!SLIST_EMPTY(line_info)) { + lie = SLIST_FIRST(line_info); + SLIST_REMOVE_HEAD(line_info, entries); + free(lie->file); + free(lie); + } + free(line_info); + line_info = NULL; + } + } + + if (sec_table != NULL) + for (i = 0; i < shnum; ++i) + free(sec_table[i]); + free(sec_table); + free(type_table); + + sym_list_dest(&list_head); + + return (rtn); + +#undef OBJNAME +} + +static int +read_object(const char *filename) +{ + Elf *elf, *arf; + Elf_Cmd elf_cmd; + Elf_Kind kind; + int fd, rtn, e_err; + + assert(filename != NULL && "filename is null"); + + if ((fd = open(filename, O_RDONLY)) == -1) { + warn("'%s'", filename); + return (1); + } + + elf_cmd = ELF_C_READ; + if ((arf = elf_begin(fd, elf_cmd, (Elf *) NULL)) == NULL) { + if ((e_err = elf_errno()) != 0) + warnx("elf_begin error: %s", elf_errmsg(e_err)); + else + warnx("elf_begin error"); + close(fd); + return (1); + } + + assert(arf != NULL && "arf is null."); + + rtn = 0; + if ((kind = elf_kind(arf)) == ELF_K_NONE) { + warnx("%s: File format not recognized", filename); + elf_end(arf); + close(fd); + return (1); + } + if (kind == ELF_K_AR) { + if (nm_opts.print_name == PRINT_NAME_MULTI && + nm_opts.elem_print_fn == sym_elem_print_all) + printf("\n%s:\n", filename); + if (nm_opts.print_armap == true) + print_ar_index(fd, arf); + } + + while ((elf = elf_begin(fd, elf_cmd, arf)) != NULL) { + rtn |= read_elf(elf, filename, kind); + + /* + * If file is not archive, elf_next return ELF_C_NULL and + * stop the loop. + */ + elf_cmd = elf_next(elf); + elf_end(elf); + } + + elf_end(arf); + close(fd); + + return (rtn); +} + +static int +read_files(int argc, char **argv) +{ + int rtn = 0; + + if (argc < 0 || argv == NULL) + return (1); + + if (argc == 0) + rtn |= read_object(nm_info.def_filename); + else { + if (nm_opts.print_name == PRINT_NAME_NONE && argc > 1) + nm_opts.print_name = PRINT_NAME_MULTI; + while (argc > 0) { + rtn |= read_object(*argv); + --argc; + ++argv; + } + } + + return (rtn); +} + +static void +print_lineno(struct sym_entry *ep, struct func_info_head *func_info, + struct var_info_head *var_info, struct line_info_head *line_info) +{ + struct func_info_entry *func; + struct var_info_entry *var; + struct line_info_entry *lie; + + /* For function symbol, search the function line information list. */ + if ((ep->sym->st_info & 0xf) == STT_FUNC && func_info != NULL) { + SLIST_FOREACH(func, func_info, entries) { + if (func->name != NULL && + !strcmp(ep->name, func->name) && + ep->sym->st_value >= func->lowpc && + ep->sym->st_value < func->highpc) { + printf("\t%s:%" PRIu64, func->file, func->line); + return; + } + } + } + + /* For variable symbol, search the variable line information list. */ + if ((ep->sym->st_info & 0xf) == STT_OBJECT && var_info != NULL) { + SLIST_FOREACH(var, var_info, entries) { + if (!strcmp(ep->name, var->name) && + ep->sym->st_value == var->addr) { + printf("\t%s:%" PRIu64, var->file, var->line); + return; + } + } + } + + /* Otherwise search line number information the .debug_line section. */ + if (line_info != NULL) { + SLIST_FOREACH(lie, line_info, entries) { + if (ep->sym->st_value == lie->addr) { + printf("\t%s:%" PRIu64, lie->file, lie->line); + return; + } + } + } +} + +static void +set_opt_value_print_fn(enum radix t) +{ + + switch (t) { + case RADIX_OCT: + nm_opts.value_print_fn = &sym_value_oct_print; + nm_opts.size_print_fn = &sym_size_oct_print; + + break; + case RADIX_DEC: + nm_opts.value_print_fn = &sym_value_dec_print; + nm_opts.size_print_fn = &sym_size_dec_print; + + break; + case RADIX_HEX: + default : + nm_opts.value_print_fn = &sym_value_hex_print; + nm_opts.size_print_fn = &sym_size_hex_print; + } + + assert(nm_opts.value_print_fn != NULL && + "nm_opts.value_print_fn is null"); +} + +static void +sym_elem_print_all(char type, const char *sec, const GElf_Sym *sym, + const char *name) +{ + + if (sec == NULL || sym == NULL || name == NULL || + nm_opts.value_print_fn == NULL) + return; + + if (IS_UNDEF_SYM_TYPE(type)) { + if (nm_opts.t == RADIX_HEX && nm_elfclass == ELFCLASS32) + printf("%-8s", ""); + else + printf("%-16s", ""); + } else { + switch ((nm_opts.sort_fn == & cmp_size ? 2 : 0) + + nm_opts.print_size) { + case 3: + if (sym->st_size != 0) { + nm_opts.value_print_fn(sym); + printf(" "); + nm_opts.size_print_fn(sym); + } + break; + + case 2: + if (sym->st_size != 0) + nm_opts.size_print_fn(sym); + break; + + case 1: + nm_opts.value_print_fn(sym); + if (sym->st_size != 0) { + printf(" "); + nm_opts.size_print_fn(sym); + } + break; + + case 0: + default: + nm_opts.value_print_fn(sym); + } + } + + printf(" %c ", type); + PRINT_DEMANGLED_NAME("%s", name); +} + +static void +sym_elem_print_all_portable(char type, const char *sec, const GElf_Sym *sym, + const char *name) +{ + + if (sec == NULL || sym == NULL || name == NULL || + nm_opts.value_print_fn == NULL) + return; + + PRINT_DEMANGLED_NAME("%s", name); + printf(" %c ", type); + if (!IS_UNDEF_SYM_TYPE(type)) { + nm_opts.value_print_fn(sym); + printf(" "); + if (sym->st_size != 0) + nm_opts.size_print_fn(sym); + } else + printf(" "); +} + +static void +sym_elem_print_all_sysv(char type, const char *sec, const GElf_Sym *sym, + const char *name) +{ + + if (sec == NULL || sym == NULL || name == NULL || + nm_opts.value_print_fn == NULL) + return; + + PRINT_DEMANGLED_NAME("%-20s|", name); + if (IS_UNDEF_SYM_TYPE(type)) + printf(" "); + else + nm_opts.value_print_fn(sym); + + printf("| %c |", type); + + switch (sym->st_info & 0xf) { + case STT_OBJECT: + printf("%18s|", "OBJECT"); + break; + + case STT_FUNC: + printf("%18s|", "FUNC"); + break; + + case STT_SECTION: + printf("%18s|", "SECTION"); + break; + + case STT_FILE: + printf("%18s|", "FILE"); + break; + + case STT_LOPROC: + printf("%18s|", "LOPROC"); + break; + + case STT_HIPROC: + printf("%18s|", "HIPROC"); + break; + + case STT_NOTYPE: + default: + printf("%18s|", "NOTYPE"); + } + + if (sym->st_size != 0) + nm_opts.size_print_fn(sym); + else + printf(" "); + + printf("| |%s", sec); +} + +static int +sym_elem_def(char type, const GElf_Sym *sym, const char *name) +{ + + assert(IS_SYM_TYPE((unsigned char) type)); + + UNUSED(sym); + UNUSED(name); + + return (!IS_UNDEF_SYM_TYPE((unsigned char) type)); +} + +static int +sym_elem_global(char type, const GElf_Sym *sym, const char *name) +{ + + assert(IS_SYM_TYPE((unsigned char) type)); + + UNUSED(sym); + UNUSED(name); + + /* weak symbols resemble global. */ + return (isupper((unsigned char) type) || type == 'w'); +} + +static int +sym_elem_global_static(char type, const GElf_Sym *sym, const char *name) +{ + unsigned char info; + + assert(sym != NULL); + + UNUSED(type); + UNUSED(name); + + info = sym->st_info >> 4; + + return (info == STB_LOCAL || + info == STB_GLOBAL || + info == STB_WEAK); +} + +static int +sym_elem_nondebug(char type, const GElf_Sym *sym, const char *name) +{ + + assert(sym != NULL); + + UNUSED(type); + UNUSED(name); + + if (sym->st_value == 0 && (sym->st_info & 0xf) == STT_FILE) + return (0); + if (sym->st_name == 0) + return (0); + + return (1); +} + +static int +sym_elem_nonzero_size(char type, const GElf_Sym *sym, const char *name) +{ + + assert(sym != NULL); + + UNUSED(type); + UNUSED(name); + + return (sym->st_size > 0); +} + +static int +sym_elem_undef(char type, const GElf_Sym *sym, const char *name) +{ + + assert(IS_SYM_TYPE((unsigned char) type)); + + UNUSED(sym); + UNUSED(name); + + return (IS_UNDEF_SYM_TYPE((unsigned char) type)); +} + +static void +sym_list_dest(struct sym_head *headp) +{ + struct sym_entry *ep, *ep_n; + + if (headp == NULL) + return; + + ep = STAILQ_FIRST(headp); + while (ep != NULL) { + ep_n = STAILQ_NEXT(ep, sym_entries); + free(ep->sym); + free(ep->name); + free(ep); + ep = ep_n; + } +} + +static int +sym_list_insert(struct sym_head *headp, const char *name, const GElf_Sym *sym) +{ + struct sym_entry *e; + + if (headp == NULL || name == NULL || sym == NULL) + return (0); + if ((e = malloc(sizeof(struct sym_entry))) == NULL) { + warn("malloc"); + return (0); + } + if ((e->name = strdup(name)) == NULL) { + warn("strdup"); + free(e); + return (0); + } + if ((e->sym = malloc(sizeof(GElf_Sym))) == NULL) { + warn("malloc"); + free(e->name); + free(e); + return (0); + } + + memcpy(e->sym, sym, sizeof(GElf_Sym)); + + /* Display size instead of value for common symbol. */ + if (sym->st_shndx == SHN_COMMON) + e->sym->st_value = sym->st_size; + + STAILQ_INSERT_TAIL(headp, e, sym_entries); + + return (1); +} + +/* If file has not .debug_info, line_info will be NULL */ +static void +sym_list_print(struct sym_print_data *p, struct func_info_head *func_info, + struct var_info_head *var_info, struct line_info_head *line_info) +{ + struct sym_entry *e_v; + size_t si; + int i; + + if (p == NULL || CHECK_SYM_PRINT_DATA(p)) + return; + if ((e_v = sym_list_sort(p)) == NULL) + return; + if (nm_opts.sort_reverse == false) + for (si = 0; si != p->list_num; ++si) + sym_list_print_each(&e_v[si], p, func_info, var_info, + line_info); + else + for (i = p->list_num - 1; i != -1; --i) + sym_list_print_each(&e_v[i], p, func_info, var_info, + line_info); + + free(e_v); +} + +/* If file has not .debug_info, line_info will be NULL */ +static void +sym_list_print_each(struct sym_entry *ep, struct sym_print_data *p, + struct func_info_head *func_info, struct var_info_head *var_info, + struct line_info_head *line_info) +{ + const char *sec; + char type; + + if (ep == NULL || CHECK_SYM_PRINT_DATA(p)) + return; + + assert(ep->name != NULL); + assert(ep->sym != NULL); + + type = get_sym_type(ep->sym, p->t_table); + + if (nm_opts.print_name == PRINT_NAME_FULL) { + printf("%s", p->filename); + if (nm_opts.elem_print_fn == &sym_elem_print_all_portable) { + if (p->objname != NULL) + printf("[%s]", p->objname); + printf(": "); + } else { + if (p->objname != NULL) + printf(":%s", p->objname); + printf(":"); + } + } + + switch (ep->sym->st_shndx) { + case SHN_LOPROC: + /* LOPROC or LORESERVE */ + sec = "*LOPROC*"; + break; + case SHN_HIPROC: + sec = "*HIPROC*"; + break; + case SHN_LOOS: + sec = "*LOOS*"; + break; + case SHN_HIOS: + sec = "*HIOS*"; + break; + case SHN_ABS: + sec = "*ABS*"; + break; + case SHN_COMMON: + sec = "*COM*"; + break; + case SHN_HIRESERVE: + /* HIRESERVE or XINDEX */ + sec = "*HIRESERVE*"; + break; + default: + if (ep->sym->st_shndx > p->sh_num) + return; + sec = p->s_table[ep->sym->st_shndx]; + break; + } + + nm_opts.elem_print_fn(type, sec, ep->sym, ep->name); + + if (nm_opts.debug_line == true && !IS_UNDEF_SYM_TYPE(type)) + print_lineno(ep, func_info, var_info, line_info); + + printf("\n"); +} + +static struct sym_entry * +sym_list_sort(struct sym_print_data *p) +{ + struct sym_entry *ep, *e_v; + int idx; + + if (p == NULL || CHECK_SYM_PRINT_DATA(p)) + return (NULL); + + if ((e_v = malloc(sizeof(struct sym_entry) * p->list_num)) == NULL) { + warn("malloc"); + return (NULL); + } + + idx = 0; + STAILQ_FOREACH(ep, p->headp, sym_entries) { + if (ep->name != NULL && ep->sym != NULL) { + e_v[idx].name = ep->name; + e_v[idx].sym = ep->sym; + ++idx; + } + } + + assert((size_t)idx == p->list_num); + + if (nm_opts.sort_fn != &cmp_none) { + nm_print_data = p; + assert(nm_print_data != NULL); + qsort(e_v, p->list_num, sizeof(struct sym_entry), + nm_opts.sort_fn); + } + + return (e_v); +} + +static void +sym_size_oct_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + printf("%016" PRIo64, sym->st_size); +} + +static void +sym_size_hex_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + if (nm_elfclass == ELFCLASS32) + printf("%08" PRIx64, sym->st_size); + else + printf("%016" PRIx64, sym->st_size); +} + +static void +sym_size_dec_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + printf("%016" PRId64, sym->st_size); +} + +static void +sym_value_oct_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + printf("%016" PRIo64, sym->st_value); +} + +static void +sym_value_hex_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + if (nm_elfclass == ELFCLASS32) + printf("%08" PRIx64, sym->st_value); + else + printf("%016" PRIx64, sym->st_value); +} + +static void +sym_value_dec_print(const GElf_Sym *sym) +{ + + assert(sym != NULL && "sym is null"); + printf("%016" PRId64, sym->st_value); +} + +static void +usage(int exitcode) +{ + + printf("Usage: %s [options] file ...\ +\n Display symbolic information in file.\n\ +\n Options: \ +\n -A, --print-file-name Write the full pathname or library name of an\ +\n object on each line.\ +\n -a, --debug-syms Display all symbols include debugger-only\ +\n symbols.", nm_info.name); + printf("\ +\n -B Equivalent to specifying \"--format=bsd\".\ +\n -C, --demangle[=style] Decode low-level symbol names.\ +\n --no-demangle Do not demangle low-level symbol names.\ +\n -D, --dynamic Display only dynamic symbols.\ +\n -e Display only global and static symbols."); + printf("\ +\n -f Produce full output (default).\ +\n --format=format Display output in specific format. Allowed\ +\n formats are: \"bsd\", \"posix\" and \"sysv\".\ +\n -g, --extern-only Display only global symbol information.\ +\n -h, --help Show this help message.\ +\n -l, --line-numbers Display filename and linenumber using\ +\n debugging information.\ +\n -n, --numeric-sort Sort symbols numerically by value."); + printf("\ +\n -o Write numeric values in octal. Equivalent to\ +\n specifying \"-t o\".\ +\n -p, --no-sort Do not sort symbols.\ +\n -P Write information in a portable output format.\ +\n Equivalent to specifying \"--format=posix\".\ +\n -r, --reverse-sort Reverse the order of the sort.\ +\n -S, --print-size Print symbol sizes instead values.\ +\n -s, --print-armap Include an index of archive members.\ +\n --size-sort Sort symbols by size."); + printf("\ +\n -t, --radix=format Write each numeric value in the specified\ +\n format:\ +\n d In decimal,\ +\n o In octal,\ +\n x In hexadecimal."); + printf("\ +\n -u, --undefined-only Display only undefined symbols.\ +\n --defined-only Display only defined symbols.\ +\n -V, --version Show the version identifier for %s.\ +\n -v Sort output by value.\ +\n -x Write numeric values in hexadecimal.\ +\n Equivalent to specifying \"-t x\".", + nm_info.name); + printf("\n\ +\n The default options are: output in bsd format, use a hexadecimal radix,\ +\n sort by symbol name, do not demangle names.\n"); + + exit(exitcode); +} + +/* + * Display symbolic information in file. + * Return 0 at success, >0 at failed. + */ +int +main(int argc, char **argv) +{ + int rtn; + + global_init(); + get_opt(argc, argv); + rtn = read_files(argc - optind, argv + optind); + global_dest(); + + exit(rtn); +} diff --git a/contrib/elftoolchain/nm/os.NetBSD.mk b/contrib/elftoolchain/nm/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/nm/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/readelf/Makefile b/contrib/elftoolchain/readelf/Makefile new file mode 100644 index 0000000000..09c8650cda --- /dev/null +++ b/contrib/elftoolchain/readelf/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile 2076 2011-10-27 03:50:33Z jkoshy $ + +TOP= .. + +PROG= readelf +SRCS= readelf.c + +WARNS?= 6 + +DPADD= ${LIBDWARF} ${LIBELF} +LDADD= -ldwarf -lelftc -lelf + +MAN1= readelf.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/readelf/os.NetBSD.mk b/contrib/elftoolchain/readelf/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/readelf/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/readelf/readelf.1 b/contrib/elftoolchain/readelf/readelf.1 new file mode 100644 index 0000000000..1f0b7bc918 --- /dev/null +++ b/contrib/elftoolchain/readelf/readelf.1 @@ -0,0 +1,199 @@ +.\" Copyright (c) 2009,2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: readelf.1 3753 2019-06-28 01:13:13Z emaste $ +.\" +.Dd June 27, 2019 +.Dt READELF 1 +.Os +.Sh NAME +.Nm readelf +.Nd display information about ELF objects +.Sh SYNOPSIS +.Nm +.Op Fl a | Fl -all +.Op Fl c | Fl -archive-index +.Op Fl d | Fl -dynamic +.Op Fl e | Fl -headers +.Op Fl g | Fl -section-groups +.Op Fl h | Fl -file-header +.Op Fl l | Fl -program-headers +.Op Fl n | Fl -notes +.Op Fl p Ar section | Fl -string-dump Ns = Ns Ar section +.Op Fl r | Fl -relocs +.Op Fl t | Fl -section-details +.Op Fl v | Fl -version +.Oo +.Fl w Ns Oo Ns Ar afilmoprsFLR Ns Oc | +.Fl -debug-dump Ns Op Ns = Ns Ar long-option-name , Ns ... +.Oc +.Op Fl x Ar section | Fl -hex-dump Ns = Ns Ar section +.Op Fl A | Fl -arch-specific +.Op Fl D | Fl -use-dynamic +.Op Fl H | Fl -help +.Op Fl I | Fl -histogram +.Op Fl N | -full-section-name +.Op Fl S | Fl -sections | Fl -section-headers +.Op Fl V | Fl -version-info +.Op Fl W | Fl -wide +.Ar file... +.Sh DESCRIPTION +The +.Nm +utility displays information about ELF objects and +.Xr ar 1 +archives. +.Pp +The +.Nm +utility recognizes the following options: +.Bl -tag -width indent +.It Fl a | Fl -all +Turn on the following flags: +.Fl d , +.Fl h , +.Fl I , +.Fl l , +.Fl r , +.Fl s , +.Fl A , +.Fl S +and +.Fl V . +.It Fl c | Fl -archive-index +Print the archive symbol table for archives. +.It Fl d | Fl -dynamic +Print the contents of the +.Li SHT_DYNAMIC +sections in the ELF object. +.It Fl e | Fl -headers +Print all program, file and section headers in the ELF object. +.It Fl g | Fl -section-groups +Print the contents of the section groups in the ELF object. +.It Fl h | Fl -file-header +Print the file header of the ELF object. +.It Fl l | Fl -program-headers +Print the content of the program header table for the object. +.It Fl n | Fl -notes +Print the contents of +.Li PT_NOTE +segments or +.Li SHT_NOTE +sections present in the ELF object. +.It Fl p Ar section | Fl -string-dump Ns = Ns Ar section +Print the contents of the specified section as printable strings. +The argument +.Ar section +should be the name of a section or a numeric section index. +.It Fl r | Fl -relocs +Print relocation information. +.It Fl s | Fl -syms | Fl -symbols +Print symbol tables. +.It Fl t | Fl -section-details +Print additional information about sections, such as the flags +fields in section headers. +Implies +.Fl S . +.It Fl v | Fl -version +Prints a version identifier for +.Nm +and exits. +.It Fl w Ns Oo afilmoprsFLR Oc | Xo +.Fl -debug-dump Ns Op Ns = Ns Ar long-option-name , Ns ... +.Xc +Display DWARF information. +The +.Fl w +option is used with the short options in the following +table; the +.Fl -debug-dump +option is used with a comma-separated list of the corresponding long +option names: +.Bl -column ".Em Short Option" "aranges|ranges" +.It Em Short Option Ta Em Long Option Ta Em Description +.It a Ta abbrev Ta Show abbreviation information. +.It f Ta frames Ta Show frame information, displaying frame instructions. +.It i Ta info Ta Show debugging information entries. +.It l Ta rawline Ta Show line information in raw form. +.It m Ta macro Ta Show macro information. +.It o Ta loc Ta Show location list information. +.It p Ta pubnames Ta Show global names. +.It r Ta aranges|ranges Ta Show address range information. +.It s Ta str Ta Show the debug string table. +.It F Ta frames-interp Ta Show frame information, displaying register rules. +.It L Ta decodedline Ta Show line information in decoded form. +.It R Ta Ranges Ta Show range lists. +.El +.Pp +If no sub-options are specified, the default is to show information +corresponding to the +.Ar a , f , i, l , o , p , r , s +and +.Ar R +short options. +.It Fl x Ar section | Fl -hex-dump Ns = Ns Ar section +Display the contents of the specified section in hexadecimal. +The argument +.Ar section +should be the name of a section or a numeric section index. +.It Fl A | Fl -arch-specific +This option is accepted but is currently unimplemented. +.It Fl D | Fl -use-dynamic +Print the symbol table specified by the +.Li DT_SYMTAB +entry in the +.Dq Li .dynamic +section. +.It Fl H | Fl -help +Print a help message. +.It Fl I | Fl -histogram +Print information on bucket list lengths for sections of type +.Li SHT_HASH +and +.Li SHT_GNU_HASH . +.It Fl N | Fl -full-section-name +This option is accepted but is currently unimplemented. +.It Fl S | Fl -sections | Fl -section-headers +Print information in the section headers for each ELF object. +.It Fl V | Fl -version-info +Print symbol versioning information. +.It Fl W | Fl -wide +Print information about ELF structures using one long line per +structure. +If this option is not specified, +.Nm +will list information in the headers of 64 bit ELF objects on two +separate lines. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr nm 1 , +.Xr addr2line 1 , +.Xr elfcopy 1 , +.Sh AUTHORS +The +.Nm +utility was written by +.An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c new file mode 100644 index 0000000000..cebd54201d --- /dev/null +++ b/contrib/elftoolchain/readelf/readelf.c @@ -0,0 +1,7862 @@ +/*- + * Copyright (c) 2009-2018,2023 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: readelf.c 4039 2024-03-15 04:07:32Z kaiwang27 $"); + +/* + * readelf(1) options. + */ +#define RE_AA 0x00000001 +#define RE_C 0x00000002 +#define RE_DD 0x00000004 +#define RE_D 0x00000008 +#define RE_G 0x00000010 +#define RE_H 0x00000020 +#define RE_II 0x00000040 +#define RE_I 0x00000080 +#define RE_L 0x00000100 +#define RE_NN 0x00000200 +#define RE_N 0x00000400 +#define RE_P 0x00000800 +#define RE_R 0x00001000 +#define RE_SS 0x00002000 +#define RE_S 0x00004000 +#define RE_T 0x00008000 +#define RE_U 0x00010000 +#define RE_VV 0x00020000 +#define RE_WW 0x00040000 +#define RE_W 0x00080000 +#define RE_X 0x00100000 + +/* + * dwarf dump options. + */ +#define DW_A 0x00000001 +#define DW_FF 0x00000002 +#define DW_F 0x00000004 +#define DW_I 0x00000008 +#define DW_LL 0x00000010 +#define DW_L 0x00000020 +#define DW_M 0x00000040 +#define DW_O 0x00000080 +#define DW_P 0x00000100 +#define DW_RR 0x00000200 +#define DW_R 0x00000400 +#define DW_S 0x00000800 + +#define DW_DEFAULT_OPTIONS (DW_A | DW_F | DW_I | DW_L | DW_O | DW_P | \ + DW_R | DW_RR | DW_S) + +/* + * readelf(1) run control flags. + */ +#define DISPLAY_FILENAME 0x0001 + +/* Space for printing a prefix, a 4 byte value, and a trailing NUL. */ +#define REGISTER_NAME_BUFFER_SIZE 16 + +/* Space for printing an 8 byte value and a trailing NUL. */ +#define DWARF_ADDR_BUFFER_SIZE 24 + +/* + * Internal data structure for sections. + */ +struct section { + const char *name; /* section name */ + Elf_Scn *scn; /* section scn */ + uint64_t off; /* section offset */ + uint64_t sz; /* section size */ + uint64_t entsize; /* section entsize */ + uint64_t align; /* section alignment */ + uint64_t type; /* section type */ + uint64_t flags; /* section flags */ + uint64_t addr; /* section virtual addr */ + uint32_t link; /* section link ndx */ + uint32_t info; /* section info ndx */ +}; + +struct dumpop { + union { + size_t si; /* section index */ + const char *sn; /* section name */ + } u; + enum { + DUMP_BY_INDEX = 0, + DUMP_BY_NAME + } type; /* dump type */ +#define HEX_DUMP 0x0001 +#define STR_DUMP 0x0002 + int op; /* dump operation */ + STAILQ_ENTRY(dumpop) dumpop_list; +}; + +struct symver { + const char *name; + int type; +}; + +/* + * Structure encapsulates the global data for readelf(1). + */ +struct readelf { + const char *filename; /* current processing file. */ + int options; /* command line options. */ + int flags; /* run control flags. */ + int dop; /* dwarf dump options. */ + Elf *elf; /* underlying ELF descriptor. */ + Elf *ar; /* archive ELF descriptor. */ + Dwarf_Debug dbg; /* DWARF handle. */ + Dwarf_Half cu_psize; /* DWARF CU pointer size. */ + Dwarf_Half cu_osize; /* DWARF CU offset size. */ + Dwarf_Half cu_ver; /* DWARF CU version. */ + GElf_Ehdr ehdr; /* ELF header. */ + int ec; /* ELF class. */ + size_t shnum; /* #sections. */ + struct section *vd_s; /* Verdef section. */ + struct section *vn_s; /* Verneed section. */ + struct section *vs_s; /* Versym section. */ + uint16_t *vs; /* Versym array. */ + int vs_sz; /* Versym array size. */ + struct symver *ver; /* Version array. */ + int ver_sz; /* Size of version array. */ + struct section *sl; /* list of sections. */ + STAILQ_HEAD(, dumpop) v_dumpop; /* list of dump ops. */ + uint64_t (*dw_read)(Elf_Data *, uint64_t *, int); + uint64_t (*dw_decode)(uint8_t **, int); +}; + +enum options +{ + OPTION_DEBUG_DUMP +}; + +static struct option longopts[] = { + {"all", no_argument, NULL, 'a'}, + {"arch-specific", no_argument, NULL, 'A'}, + {"archive-index", no_argument, NULL, 'c'}, + {"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP}, + {"dynamic", no_argument, NULL, 'd'}, + {"file-header", no_argument, NULL, 'h'}, + {"full-section-name", no_argument, NULL, 'N'}, + {"headers", no_argument, NULL, 'e'}, + {"help", no_argument, 0, 'H'}, + {"hex-dump", required_argument, NULL, 'x'}, + {"histogram", no_argument, NULL, 'I'}, + {"notes", no_argument, NULL, 'n'}, + {"program-headers", no_argument, NULL, 'l'}, + {"relocs", no_argument, NULL, 'r'}, + {"sections", no_argument, NULL, 'S'}, + {"section-headers", no_argument, NULL, 'S'}, + {"section-groups", no_argument, NULL, 'g'}, + {"section-details", no_argument, NULL, 't'}, + {"segments", no_argument, NULL, 'l'}, + {"string-dump", required_argument, NULL, 'p'}, + {"symbols", no_argument, NULL, 's'}, + {"syms", no_argument, NULL, 's'}, + {"unwind", no_argument, NULL, 'u'}, + {"use-dynamic", no_argument, NULL, 'D'}, + {"version-info", no_argument, 0, 'V'}, + {"version", no_argument, 0, 'v'}, + {"wide", no_argument, 0, 'W'}, + {NULL, 0, NULL, 0} +}; + +struct eflags_desc { + uint64_t flag; + const char *desc; +}; + +struct flag_desc { + uint64_t flag; + const char *desc; +}; + +struct mips_option { + uint64_t flag; + const char *desc; +}; + +struct lnct { + unsigned type; + unsigned form; +}; + +static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op, + int t); +static const char *aeabi_adv_simd_arch(uint64_t simd); +static const char *aeabi_align_needed(uint64_t an); +static const char *aeabi_align_preserved(uint64_t ap); +static const char *aeabi_arm_isa(uint64_t ai); +static const char *aeabi_cpu_arch(uint64_t arch); +static const char *aeabi_cpu_arch_profile(uint64_t pf); +static const char *aeabi_div(uint64_t du); +static const char *aeabi_enum_size(uint64_t es); +static const char *aeabi_fp_16bit_format(uint64_t fp16); +static const char *aeabi_fp_arch(uint64_t fp); +static const char *aeabi_fp_denormal(uint64_t fd); +static const char *aeabi_fp_exceptions(uint64_t fe); +static const char *aeabi_fp_hpext(uint64_t fh); +static const char *aeabi_fp_number_model(uint64_t fn); +static const char *aeabi_fp_optm_goal(uint64_t fog); +static const char *aeabi_fp_rounding(uint64_t fr); +static const char *aeabi_hardfp(uint64_t hfp); +static const char *aeabi_mpext(uint64_t mp); +static const char *aeabi_optm_goal(uint64_t og); +static const char *aeabi_pcs_config(uint64_t pcs); +static const char *aeabi_pcs_got(uint64_t got); +static const char *aeabi_pcs_r9(uint64_t r9); +static const char *aeabi_pcs_ro(uint64_t ro); +static const char *aeabi_pcs_rw(uint64_t rw); +static const char *aeabi_pcs_wchar_t(uint64_t wt); +static const char *aeabi_t2ee(uint64_t t2ee); +static const char *aeabi_thumb_isa(uint64_t ti); +static const char *aeabi_fp_user_exceptions(uint64_t fu); +static const char *aeabi_unaligned_access(uint64_t ua); +static const char *aeabi_vfp_args(uint64_t va); +static const char *aeabi_virtual(uint64_t vt); +static const char *aeabi_wmmx_arch(uint64_t wmmx); +static const char *aeabi_wmmx_args(uint64_t wa); +static const char *elf_class(unsigned int class); +static const char *elf_endian(unsigned int endian); +static const char *elf_machine(unsigned int mach); +static const char *elf_osabi(unsigned int abi); +static const char *elf_type(unsigned int type); +static const char *elf_ver(unsigned int ver); +static const char *dt_type(unsigned int mach, unsigned int dtype); +static void dump_ar(struct readelf *re, int); +static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); +static void dump_attributes(struct readelf *re); +static uint8_t *dump_compatibility_tag(uint8_t *p, uint8_t *pe); +static void dump_dwarf(struct readelf *re); +static void dump_dwarf_abbrev(struct readelf *re); +static void dump_dwarf_aranges(struct readelf *re); +static void dump_dwarf_block(struct readelf *re, uint8_t *b, + Dwarf_Unsigned len); +static void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level); +static void dump_dwarf_frame(struct readelf *re, int alt); +static void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, + uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, + Dwarf_Addr pc, Dwarf_Debug dbg); +static int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, + Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra); +static void dump_dwarf_frame_section(struct readelf *re, struct section *s, + int alt); +static void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info); +static void dump_dwarf_macinfo(struct readelf *re); +static void dump_dwarf_line(struct readelf *re); +static void dump_dwarf_line_decoded(struct readelf *re); +static void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr); +static void dump_dwarf_loclist(struct readelf *re); +static void dump_dwarf_pubnames(struct readelf *re); +static void dump_dwarf_ranges(struct readelf *re); +static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, + Dwarf_Addr base); +static void dump_dwarf_str(struct readelf *re); +static void dump_eflags(struct readelf *re, uint64_t e_flags); +static void dump_elf(struct readelf *re); +static void dump_flags(struct flag_desc *fd, uint64_t flags); +static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab); +static void dump_dynamic(struct readelf *re); +static void dump_liblist(struct readelf *re); +static void dump_mips_abiflags(struct readelf *re, struct section *s); +static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); +static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz); +static void dump_mips_options(struct readelf *re, struct section *s); +static void dump_mips_option_flags(const char *name, struct mips_option *opt, + uint64_t info); +static void dump_mips_reginfo(struct readelf *re, struct section *s); +static void dump_mips_specific_info(struct readelf *re); +static void dump_notes(struct readelf *re); +static void dump_notes_content(struct readelf *re, const char *buf, size_t sz, + off_t off); +static void dump_notes_data(const char *name, uint32_t type, const char *buf, + size_t sz); +static void dump_svr4_hash(struct section *s); +static void dump_svr4_hash64(struct readelf *re, struct section *s); +static void dump_gnu_hash(struct readelf *re, struct section *s); +static void dump_hash(struct readelf *re); +static void dump_phdr(struct readelf *re); +static void dump_ppc_attributes(uint8_t *p, uint8_t *pe); +static void dump_section_groups(struct readelf *re); +static void dump_symtab(struct readelf *re, int i); +static void dump_symtabs(struct readelf *re); +static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe); +static void dump_ver(struct readelf *re); +static void dump_verdef(struct readelf *re, int dump); +static void dump_verneed(struct readelf *re, int dump); +static void dump_versym(struct readelf *re); +static const char *dwarf_reg(unsigned int mach, unsigned int reg); +static const char *dwarf_regname(struct readelf *re, unsigned int num); +static struct dumpop *find_dumpop(struct readelf *re, size_t si, + const char *sn, int op, int t); +static int get_ent_count(struct section *s, int *ent_count); +static int get_mips_register_size(uint8_t flag); +static char *get_regoff_str(struct readelf *re, Dwarf_Half reg, + Dwarf_Addr off); +static const char *get_string(struct readelf *re, int strtab, size_t off); +static const char *get_symbol_name(struct readelf *re, int symtab, int i); +static uint64_t get_symbol_value(struct readelf *re, int symtab, int i); +static void load_sections(struct readelf *re); +static const char *mips_abi_fp(uint64_t fp); +static const char *note_type(const char *note_name, unsigned int et, + unsigned int nt); +static const char *note_type_freebsd(unsigned int nt); +static const char *note_type_freebsd_core(unsigned int nt); +static const char *note_type_linux_core(unsigned int nt); +static const char *note_type_gnu(unsigned int nt); +static const char *note_type_netbsd(unsigned int nt); +static const char *note_type_openbsd(unsigned int nt); +static const char *note_type_unknown(unsigned int nt); +static const char *note_type_xen(unsigned int nt); +static const char *option_kind(uint8_t kind); +static const char *phdr_type(unsigned int mach, unsigned int ptype); +static const char *ppc_abi_fp(uint64_t fp); +static const char *ppc_abi_vector(uint64_t vec); +static void readelf_usage(int exit_code); +static void readelf_version(void); +static void search_loclist_at(struct readelf *re, Dwarf_Die die, + Dwarf_Unsigned lowpc); +static void search_ver(struct readelf *re); +static const char *section_type(unsigned int mach, unsigned int stype); +static void set_cu_context(struct readelf *re, Dwarf_Half psize, + Dwarf_Half osize, Dwarf_Half ver); +static const char *st_bind(unsigned int sbind); +static const char *st_shndx(unsigned int shndx); +static const char *st_type(unsigned int mach, unsigned int os, + unsigned int stype); +static const char *st_vis(unsigned int svis); +static const char *top_tag(unsigned int tag); +static void unload_sections(struct readelf *re); +static uint64_t _read_lsb(Elf_Data *d, uint64_t *offsetp, + int bytes_to_read); +static uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp, + int bytes_to_read); +static uint64_t _decode_lsb(uint8_t **data, int bytes_to_read); +static uint64_t _decode_msb(uint8_t **data, int bytes_to_read); +static int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe); +static uint64_t _decode_uleb128(uint8_t **dp, uint8_t *dpe); + +static struct eflags_desc arm_eflags_desc[] = { + {EF_ARM_RELEXEC, "relocatable executable"}, + {EF_ARM_HASENTRY, "has entry point"}, + {EF_ARM_SYMSARESORTED, "sorted symbol tables"}, + {EF_ARM_DYNSYMSUSESEGIDX, "dynamic symbols use segment index"}, + {EF_ARM_MAPSYMSFIRST, "mapping symbols precede others"}, + {EF_ARM_BE8, "BE8"}, + {EF_ARM_LE8, "LE8"}, + {EF_ARM_INTERWORK, "interworking enabled"}, + {EF_ARM_APCS_26, "uses APCS/26"}, + {EF_ARM_APCS_FLOAT, "uses APCS/float"}, + {EF_ARM_PIC, "position independent"}, + {EF_ARM_ALIGN8, "8 bit structure alignment"}, + {EF_ARM_NEW_ABI, "uses new ABI"}, + {EF_ARM_OLD_ABI, "uses old ABI"}, + {EF_ARM_SOFT_FLOAT, "software FP"}, + {EF_ARM_VFP_FLOAT, "VFP"}, + {EF_ARM_MAVERICK_FLOAT, "Maverick FP"}, + {0, NULL} +}; + +static struct eflags_desc mips_eflags_desc[] = { + {EF_MIPS_NOREORDER, "noreorder"}, + {EF_MIPS_PIC, "pic"}, + {EF_MIPS_CPIC, "cpic"}, + {EF_MIPS_UCODE, "ugen_reserved"}, + {EF_MIPS_ABI2, "abi2"}, + {EF_MIPS_OPTIONS_FIRST, "odk first"}, + {EF_MIPS_ARCH_ASE_MDMX, "mdmx"}, + {EF_MIPS_ARCH_ASE_M16, "mips16"}, + {0, NULL} +}; + +static struct eflags_desc powerpc_eflags_desc[] = { + {EF_PPC_EMB, "emb"}, + {EF_PPC_RELOCATABLE, "relocatable"}, + {EF_PPC_RELOCATABLE_LIB, "relocatable-lib"}, + {0, NULL} +}; + +static struct eflags_desc riscv_eflags_desc[] = { + {EF_RISCV_RVC, "RVC"}, + {EF_RISCV_RVE, "RVE"}, + {EF_RISCV_TSO, "TSO"}, + {0, NULL} +}; + +static struct eflags_desc sparc_eflags_desc[] = { + {EF_SPARC_32PLUS, "v8+"}, + {EF_SPARC_SUN_US1, "ultrasparcI"}, + {EF_SPARC_HAL_R1, "halr1"}, + {EF_SPARC_SUN_US3, "ultrasparcIII"}, + {0, NULL} +}; + +static const char * +elf_osabi(unsigned int abi) +{ + static char s_abi[32]; + + switch(abi) { + case ELFOSABI_NONE: return "NONE"; + case ELFOSABI_HPUX: return "HPUX"; + case ELFOSABI_NETBSD: return "NetBSD"; + case ELFOSABI_GNU: return "GNU"; + case ELFOSABI_HURD: return "HURD"; + case ELFOSABI_86OPEN: return "86OPEN"; + case ELFOSABI_SOLARIS: return "Solaris"; + case ELFOSABI_AIX: return "AIX"; + case ELFOSABI_IRIX: return "IRIX"; + case ELFOSABI_FREEBSD: return "FreeBSD"; + case ELFOSABI_TRU64: return "TRU64"; + case ELFOSABI_MODESTO: return "MODESTO"; + case ELFOSABI_OPENBSD: return "OpenBSD"; + case ELFOSABI_OPENVMS: return "OpenVMS"; + case ELFOSABI_NSK: return "NSK"; + case ELFOSABI_AROS: return "AROS"; + case ELFOSABI_FENIXOS: return "FenixOS"; + case ELFOSABI_CLOUDABI: return "CloudABI"; + case ELFOSABI_OPENVOS: return "OpenVOS"; + case ELFOSABI_ARM_AEABI: return "ARM EABI"; + case ELFOSABI_ARM: return "ARM"; + case ELFOSABI_STANDALONE: return "StandAlone"; + default: + snprintf(s_abi, sizeof(s_abi), "", abi); + return (s_abi); + } +} + +static const char * +elf_machine(unsigned int mach) +{ + static char s_mach[32]; + + switch (mach) { + case EM_NONE: return "Unknown machine"; + case EM_M32: return "AT&T WE32100"; + case EM_SPARC: return "Sun SPARC"; + case EM_386: return "Intel i386"; + case EM_68K: return "Motorola 68000"; + case EM_IAMCU: return "Intel MCU"; + case EM_88K: return "Motorola 88000"; + case EM_860: return "Intel i860"; + case EM_MIPS: return "MIPS R3000"; + case EM_S370: return "IBM System/370"; + case EM_MIPS_RS3_LE: return "MIPS R3000 Little-Endian"; + case EM_PARISC: return "HP PA-RISC"; + case EM_VPP500: return "Fujitsu VPP500"; + case EM_SPARC32PLUS: return "SPARC v8plus"; + case EM_960: return "Intel 80960"; + case EM_PPC: return "PowerPC 32-bit"; + case EM_PPC64: return "PowerPC 64-bit"; + case EM_S390: return "IBM System/390"; + case EM_V800: return "NEC V800"; + case EM_FR20: return "Fujitsu FR20"; + case EM_RH32: return "TRW RH-32"; + case EM_RCE: return "Motorola RCE"; + case EM_ARM: return "ARM"; + case EM_SH: return "Hitachi SH"; + case EM_SPARCV9: return "SPARC v9 64-bit"; + case EM_TRICORE: return "Siemens TriCore embedded processor"; + case EM_ARC: return "Argonaut RISC Core"; + case EM_H8_300: return "Hitachi H8/300"; + case EM_H8_300H: return "Hitachi H8/300H"; + case EM_H8S: return "Hitachi H8S"; + case EM_H8_500: return "Hitachi H8/500"; + case EM_IA_64: return "Intel IA-64 Processor"; + case EM_MIPS_X: return "Stanford MIPS-X"; + case EM_COLDFIRE: return "Motorola ColdFire"; + case EM_68HC12: return "Motorola M68HC12"; + case EM_MMA: return "Fujitsu MMA"; + case EM_PCP: return "Siemens PCP"; + case EM_NCPU: return "Sony nCPU"; + case EM_NDR1: return "Denso NDR1 microprocessor"; + case EM_STARCORE: return "Motorola Star*Core processor"; + case EM_ME16: return "Toyota ME16 processor"; + case EM_ST100: return "STMicroelectronics ST100 processor"; + case EM_TINYJ: return "Advanced Logic Corp. TinyJ processor"; + case EM_X86_64: return "Advanced Micro Devices x86-64"; + case EM_PDSP: return "Sony DSP Processor"; + case EM_FX66: return "Siemens FX66 microcontroller"; + case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 microcontroller"; + case EM_ST7: return "STmicroelectronics ST7 8-bit microcontroller"; + case EM_68HC16: return "Motorola MC68HC16 microcontroller"; + case EM_68HC11: return "Motorola MC68HC11 microcontroller"; + case EM_68HC08: return "Motorola MC68HC08 microcontroller"; + case EM_68HC05: return "Motorola MC68HC05 microcontroller"; + case EM_SVX: return "Silicon Graphics SVx"; + case EM_ST19: return "STMicroelectronics ST19 8-bit mc"; + case EM_VAX: return "Digital VAX"; + case EM_CRIS: return "Axis Communications 32-bit embedded processor"; + case EM_JAVELIN: return "Infineon Tech. 32bit embedded processor"; + case EM_FIREPATH: return "Element 14 64-bit DSP Processor"; + case EM_ZSP: return "LSI Logic 16-bit DSP Processor"; + case EM_MMIX: return "Donald Knuth's educational 64-bit proc"; + case EM_HUANY: return "Harvard University MI object files"; + case EM_PRISM: return "SiTera Prism"; + case EM_AVR: return "Atmel AVR 8-bit microcontroller"; + case EM_FR30: return "Fujitsu FR30"; + case EM_D10V: return "Mitsubishi D10V"; + case EM_D30V: return "Mitsubishi D30V"; + case EM_V850: return "NEC v850"; + case EM_M32R: return "Mitsubishi M32R"; + case EM_MN10300: return "Matsushita MN10300"; + case EM_MN10200: return "Matsushita MN10200"; + case EM_PJ: return "picoJava"; + case EM_OPENRISC: return "OpenRISC 32-bit embedded processor"; + case EM_ARC_A5: return "ARC Cores Tangent-A5"; + case EM_XTENSA: return "Tensilica Xtensa Architecture"; + case EM_VIDEOCORE: return "Alphamosaic VideoCore processor"; + case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor"; + case EM_NS32K: return "National Semiconductor 32000 series"; + case EM_TPC: return "Tenor Network TPC processor"; + case EM_SNP1K: return "Trebia SNP 1000 processor"; + case EM_ST200: return "STMicroelectronics ST200 microcontroller"; + case EM_IP2K: return "Ubicom IP2xxx microcontroller family"; + case EM_MAX: return "MAX Processor"; + case EM_CR: return "National Semiconductor CompactRISC microprocessor"; + case EM_F2MC16: return "Fujitsu F2MC16"; + case EM_MSP430: return "TI embedded microcontroller msp430"; + case EM_BLACKFIN: return "Analog Devices Blackfin (DSP) processor"; + case EM_SE_C33: return "S1C33 Family of Seiko Epson processors"; + case EM_SEP: return "Sharp embedded microprocessor"; + case EM_ARCA: return "Arca RISC Microprocessor"; + case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd"; + case EM_AARCH64: return "AArch64"; + case EM_RISCV: return "RISC-V"; + default: + snprintf(s_mach, sizeof(s_mach), "", mach); + return (s_mach); + } + +} + +static const char * +elf_class(unsigned int class) +{ + static char s_class[32]; + + switch (class) { + case ELFCLASSNONE: return "none"; + case ELFCLASS32: return "ELF32"; + case ELFCLASS64: return "ELF64"; + default: + snprintf(s_class, sizeof(s_class), "", class); + return (s_class); + } +} + +static const char * +elf_endian(unsigned int endian) +{ + static char s_endian[32]; + + switch (endian) { + case ELFDATANONE: return "none"; + case ELFDATA2LSB: return "2's complement, little endian"; + case ELFDATA2MSB: return "2's complement, big endian"; + default: + snprintf(s_endian, sizeof(s_endian), "", endian); + return (s_endian); + } +} + +static const char * +elf_type(unsigned int type) +{ + static char s_type[32]; + + switch (type) { + case ET_NONE: return "NONE (None)"; + case ET_REL: return "REL (Relocatable file)"; + case ET_EXEC: return "EXEC (Executable file)"; + case ET_DYN: return "DYN (Shared object file)"; + case ET_CORE: return "CORE (Core file)"; + default: + if (type >= ET_LOPROC) + snprintf(s_type, sizeof(s_type), "", type); + else if (type >= ET_LOOS && type <= ET_HIOS) + snprintf(s_type, sizeof(s_type), "", type); + else + snprintf(s_type, sizeof(s_type), "", + type); + return (s_type); + } +} + +static const char * +elf_ver(unsigned int ver) +{ + static char s_ver[32]; + + switch (ver) { + case EV_CURRENT: return "(current)"; + case EV_NONE: return "(none)"; + default: + snprintf(s_ver, sizeof(s_ver), "", + ver); + return (s_ver); + } +} + +static const char * +phdr_type(unsigned int mach, unsigned int ptype) +{ + static char s_ptype[32]; + + if (ptype >= PT_LOPROC && ptype <= PT_HIPROC) { + switch (mach) { + case EM_ARM: + switch (ptype) { + case PT_ARM_ARCHEXT: return "ARM_ARCHEXT"; + case PT_ARM_EXIDX: return "ARM_EXIDX"; + } + break; + } + snprintf(s_ptype, sizeof(s_ptype), "LOPROC+%#lx", + ptype - PT_LOPROC); + return (s_ptype); + } + + switch (ptype) { + case PT_NULL: return "NULL"; + case PT_LOAD: return "LOAD"; + case PT_DYNAMIC: return "DYNAMIC"; + case PT_INTERP: return "INTERP"; + case PT_NOTE: return "NOTE"; + case PT_SHLIB: return "SHLIB"; + case PT_PHDR: return "PHDR"; + case PT_TLS: return "TLS"; + case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; + case PT_GNU_STACK: return "GNU_STACK"; + case PT_GNU_RELRO: return "GNU_RELRO"; + case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE"; + case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED"; + case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA"; + default: + if (ptype >= PT_LOOS && ptype <= PT_HIOS) + snprintf(s_ptype, sizeof(s_ptype), "LOOS+%#lx", + ptype - PT_LOOS); + else + snprintf(s_ptype, sizeof(s_ptype), "", + ptype); + return (s_ptype); + } +} + +static const char * +section_type(unsigned int mach, unsigned int stype) +{ + static char s_stype[32]; + + if (stype >= SHT_LOPROC && stype <= SHT_HIPROC) { + switch (mach) { + case EM_ARM: + switch (stype) { + case SHT_ARM_EXIDX: return "ARM_EXIDX"; + case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP"; + case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES"; + case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY"; + case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION"; + } + break; + case EM_X86_64: + switch (stype) { + case SHT_X86_64_UNWIND: return "X86_64_UNWIND"; + default: + break; + } + break; + case EM_MIPS: + case EM_MIPS_RS3_LE: + switch (stype) { + case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST"; + case SHT_MIPS_MSYM: return "MIPS_MSYM"; + case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT"; + case SHT_MIPS_GPTAB: return "MIPS_GPTAB"; + case SHT_MIPS_UCODE: return "MIPS_UCODE"; + case SHT_MIPS_DEBUG: return "MIPS_DEBUG"; + case SHT_MIPS_REGINFO: return "MIPS_REGINFO"; + case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE"; + case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM"; + case SHT_MIPS_RELD: return "MIPS_RELD"; + case SHT_MIPS_IFACE: return "MIPS_IFACE"; + case SHT_MIPS_CONTENT: return "MIPS_CONTENT"; + case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS"; + case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM"; + case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST"; + case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS"; + case SHT_MIPS_DWARF: return "MIPS_DWARF"; + case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL"; + case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; + case SHT_MIPS_EVENTS: return "MIPS_EVENTS"; + case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE"; + case SHT_MIPS_PIXIE: return "MIPS_PIXIE"; + case SHT_MIPS_XLATE: return "MIPS_XLATE"; + case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG"; + case SHT_MIPS_WHIRL: return "MIPS_WHIRL"; + case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION"; + case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD"; + case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION"; + case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS"; + default: + break; + } + break; + default: + break; + } + + snprintf(s_stype, sizeof(s_stype), "LOPROC+%#lx", + stype - SHT_LOPROC); + return (s_stype); + } + + switch (stype) { + case SHT_NULL: return "NULL"; + case SHT_PROGBITS: return "PROGBITS"; + case SHT_SYMTAB: return "SYMTAB"; + case SHT_STRTAB: return "STRTAB"; + case SHT_RELA: return "RELA"; + case SHT_HASH: return "HASH"; + case SHT_DYNAMIC: return "DYNAMIC"; + case SHT_NOTE: return "NOTE"; + case SHT_NOBITS: return "NOBITS"; + case SHT_REL: return "REL"; + case SHT_SHLIB: return "SHLIB"; + case SHT_DYNSYM: return "DYNSYM"; + case SHT_INIT_ARRAY: return "INIT_ARRAY"; + case SHT_FINI_ARRAY: return "FINI_ARRAY"; + case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY"; + case SHT_GROUP: return "GROUP"; + case SHT_SYMTAB_SHNDX: return "SYMTAB_SHNDX"; + case SHT_SUNW_dof: return "SUNW_dof"; + case SHT_SUNW_cap: return "SUNW_cap"; + case SHT_GNU_HASH: return "GNU_HASH"; + case SHT_SUNW_ANNOTATE: return "SUNW_ANNOTATE"; + case SHT_SUNW_DEBUGSTR: return "SUNW_DEBUGSTR"; + case SHT_SUNW_DEBUG: return "SUNW_DEBUG"; + case SHT_SUNW_move: return "SUNW_move"; + case SHT_SUNW_COMDAT: return "SUNW_COMDAT"; + case SHT_SUNW_syminfo: return "SUNW_syminfo"; + case SHT_SUNW_verdef: return "SUNW_verdef"; + case SHT_SUNW_verneed: return "SUNW_verneed"; + case SHT_SUNW_versym: return "SUNW_versym"; + default: + if (stype >= SHT_LOOS && stype <= SHT_HIOS) + snprintf(s_stype, sizeof(s_stype), "LOOS+%#lx", + stype - SHT_LOOS); + else if (stype >= SHT_LOUSER) + snprintf(s_stype, sizeof(s_stype), "LOUSER+%#lx", + stype - SHT_LOUSER); + else + snprintf(s_stype, sizeof(s_stype), "", + stype); + return (s_stype); + } +} + +static const char * +dt_type(unsigned int mach, unsigned int dtype) +{ + static char s_dtype[32]; + + switch (dtype) { + case DT_NULL: return "NULL"; + case DT_NEEDED: return "NEEDED"; + case DT_PLTRELSZ: return "PLTRELSZ"; + case DT_PLTGOT: return "PLTGOT"; + case DT_HASH: return "HASH"; + case DT_STRTAB: return "STRTAB"; + case DT_SYMTAB: return "SYMTAB"; + case DT_RELA: return "RELA"; + case DT_RELASZ: return "RELASZ"; + case DT_RELAENT: return "RELAENT"; + case DT_STRSZ: return "STRSZ"; + case DT_SYMENT: return "SYMENT"; + case DT_INIT: return "INIT"; + case DT_FINI: return "FINI"; + case DT_SONAME: return "SONAME"; + case DT_RPATH: return "RPATH"; + case DT_SYMBOLIC: return "SYMBOLIC"; + case DT_REL: return "REL"; + case DT_RELSZ: return "RELSZ"; + case DT_RELENT: return "RELENT"; + case DT_PLTREL: return "PLTREL"; + case DT_DEBUG: return "DEBUG"; + case DT_TEXTREL: return "TEXTREL"; + case DT_JMPREL: return "JMPREL"; + case DT_BIND_NOW: return "BIND_NOW"; + case DT_INIT_ARRAY: return "INIT_ARRAY"; + case DT_FINI_ARRAY: return "FINI_ARRAY"; + case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ"; + case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ"; + case DT_RUNPATH: return "RUNPATH"; + case DT_FLAGS: return "FLAGS"; + case DT_PREINIT_ARRAY: return "PREINIT_ARRAY"; + case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ"; + case DT_MAXPOSTAGS: return "MAXPOSTAGS"; + case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY"; + case DT_SUNW_RTLDINF: return "SUNW_RTLDINF"; + case DT_SUNW_FILTER: return "SUNW_FILTER"; + case DT_SUNW_CAP: return "SUNW_CAP"; + case DT_SUNW_ASLR: return "SUNW_ASLR"; + case DT_CHECKSUM: return "CHECKSUM"; + case DT_PLTPADSZ: return "PLTPADSZ"; + case DT_MOVEENT: return "MOVEENT"; + case DT_MOVESZ: return "MOVESZ"; + case DT_FEATURE: return "FEATURE"; + case DT_POSFLAG_1: return "POSFLAG_1"; + case DT_SYMINSZ: return "SYMINSZ"; + case DT_SYMINENT: return "SYMINENT"; + case DT_GNU_HASH: return "GNU_HASH"; + case DT_TLSDESC_PLT: return "DT_TLSDESC_PLT"; + case DT_TLSDESC_GOT: return "DT_TLSDESC_GOT"; + case DT_GNU_CONFLICT: return "GNU_CONFLICT"; + case DT_GNU_LIBLIST: return "GNU_LIBLIST"; + case DT_CONFIG: return "CONFIG"; + case DT_DEPAUDIT: return "DEPAUDIT"; + case DT_AUDIT: return "AUDIT"; + case DT_PLTPAD: return "PLTPAD"; + case DT_MOVETAB: return "MOVETAB"; + case DT_SYMINFO: return "SYMINFO"; + case DT_VERSYM: return "VERSYM"; + case DT_RELACOUNT: return "RELACOUNT"; + case DT_RELCOUNT: return "RELCOUNT"; + case DT_FLAGS_1: return "FLAGS_1"; + case DT_VERDEF: return "VERDEF"; + case DT_VERDEFNUM: return "VERDEFNUM"; + case DT_VERNEED: return "VERNEED"; + case DT_VERNEEDNUM: return "VERNEEDNUM"; + case DT_AUXILIARY: return "AUXILIARY"; + case DT_USED: return "USED"; + case DT_FILTER: return "FILTER"; + case DT_GNU_PRELINKED: return "GNU_PRELINKED"; + case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ"; + case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ"; + } + + if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) { + switch (mach) { + case EM_ARM: + switch (dtype) { + case DT_ARM_SYMTABSZ: + return "ARM_SYMTABSZ"; + default: + break; + } + break; + case EM_MIPS: + case EM_MIPS_RS3_LE: + switch (dtype) { + case DT_MIPS_RLD_VERSION: + return "MIPS_RLD_VERSION"; + case DT_MIPS_TIME_STAMP: + return "MIPS_TIME_STAMP"; + case DT_MIPS_ICHECKSUM: + return "MIPS_ICHECKSUM"; + case DT_MIPS_IVERSION: + return "MIPS_IVERSION"; + case DT_MIPS_FLAGS: + return "MIPS_FLAGS"; + case DT_MIPS_BASE_ADDRESS: + return "MIPS_BASE_ADDRESS"; + case DT_MIPS_CONFLICT: + return "MIPS_CONFLICT"; + case DT_MIPS_LIBLIST: + return "MIPS_LIBLIST"; + case DT_MIPS_LOCAL_GOTNO: + return "MIPS_LOCAL_GOTNO"; + case DT_MIPS_CONFLICTNO: + return "MIPS_CONFLICTNO"; + case DT_MIPS_LIBLISTNO: + return "MIPS_LIBLISTNO"; + case DT_MIPS_SYMTABNO: + return "MIPS_SYMTABNO"; + case DT_MIPS_UNREFEXTNO: + return "MIPS_UNREFEXTNO"; + case DT_MIPS_GOTSYM: + return "MIPS_GOTSYM"; + case DT_MIPS_HIPAGENO: + return "MIPS_HIPAGENO"; + case DT_MIPS_RLD_MAP: + return "MIPS_RLD_MAP"; + case DT_MIPS_DELTA_CLASS: + return "MIPS_DELTA_CLASS"; + case DT_MIPS_DELTA_CLASS_NO: + return "MIPS_DELTA_CLASS_NO"; + case DT_MIPS_DELTA_INSTANCE: + return "MIPS_DELTA_INSTANCE"; + case DT_MIPS_DELTA_INSTANCE_NO: + return "MIPS_DELTA_INSTANCE_NO"; + case DT_MIPS_DELTA_RELOC: + return "MIPS_DELTA_RELOC"; + case DT_MIPS_DELTA_RELOC_NO: + return "MIPS_DELTA_RELOC_NO"; + case DT_MIPS_DELTA_SYM: + return "MIPS_DELTA_SYM"; + case DT_MIPS_DELTA_SYM_NO: + return "MIPS_DELTA_SYM_NO"; + case DT_MIPS_DELTA_CLASSSYM: + return "MIPS_DELTA_CLASSSYM"; + case DT_MIPS_DELTA_CLASSSYM_NO: + return "MIPS_DELTA_CLASSSYM_NO"; + case DT_MIPS_CXX_FLAGS: + return "MIPS_CXX_FLAGS"; + case DT_MIPS_PIXIE_INIT: + return "MIPS_PIXIE_INIT"; + case DT_MIPS_SYMBOL_LIB: + return "MIPS_SYMBOL_LIB"; + case DT_MIPS_LOCALPAGE_GOTIDX: + return "MIPS_LOCALPAGE_GOTIDX"; + case DT_MIPS_LOCAL_GOTIDX: + return "MIPS_LOCAL_GOTIDX"; + case DT_MIPS_HIDDEN_GOTIDX: + return "MIPS_HIDDEN_GOTIDX"; + case DT_MIPS_PROTECTED_GOTIDX: + return "MIPS_PROTECTED_GOTIDX"; + case DT_MIPS_OPTIONS: + return "MIPS_OPTIONS"; + case DT_MIPS_INTERFACE: + return "MIPS_INTERFACE"; + case DT_MIPS_DYNSTR_ALIGN: + return "MIPS_DYNSTR_ALIGN"; + case DT_MIPS_INTERFACE_SIZE: + return "MIPS_INTERFACE_SIZE"; + case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: + return "MIPS_RLD_TEXT_RESOLVE_ADDR"; + case DT_MIPS_PERF_SUFFIX: + return "MIPS_PERF_SUFFIX"; + case DT_MIPS_COMPACT_SIZE: + return "MIPS_COMPACT_SIZE"; + case DT_MIPS_GP_VALUE: + return "MIPS_GP_VALUE"; + case DT_MIPS_AUX_DYNAMIC: + return "MIPS_AUX_DYNAMIC"; + case DT_MIPS_PLTGOT: + return "MIPS_PLTGOT"; + case DT_MIPS_RLD_OBJ_UPDATE: + return "MIPS_RLD_OBJ_UPDATE"; + case DT_MIPS_RWPLT: + return "MIPS_RWPLT"; + default: + break; + } + break; + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + switch (dtype) { + case DT_SPARC_REGISTER: + return "DT_SPARC_REGISTER"; + default: + break; + } + break; + default: + break; + } + } + + snprintf(s_dtype, sizeof(s_dtype), "", dtype); + return (s_dtype); +} + +static const char * +st_bind(unsigned int sbind) +{ + static char s_sbind[32]; + + switch (sbind) { + case STB_LOCAL: return "LOCAL"; + case STB_GLOBAL: return "GLOBAL"; + case STB_WEAK: return "WEAK"; + case STB_GNU_UNIQUE: return "UNIQUE"; + default: + if (sbind >= STB_LOOS && sbind <= STB_HIOS) + return "OS"; + else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) + return "PROC"; + else + snprintf(s_sbind, sizeof(s_sbind), "", + sbind); + return (s_sbind); + } +} + +static const char * +st_type(unsigned int mach, unsigned int os, unsigned int stype) +{ + static char s_stype[32]; + + switch (stype) { + case STT_NOTYPE: return "NOTYPE"; + case STT_OBJECT: return "OBJECT"; + case STT_FUNC: return "FUNC"; + case STT_SECTION: return "SECTION"; + case STT_FILE: return "FILE"; + case STT_COMMON: return "COMMON"; + case STT_TLS: return "TLS"; + default: + if (stype >= STT_LOOS && stype <= STT_HIOS) { + if ((os == ELFOSABI_GNU || os == ELFOSABI_FREEBSD) && + stype == STT_GNU_IFUNC) + return "IFUNC"; + snprintf(s_stype, sizeof(s_stype), "OS+%#x", + stype - STT_LOOS); + } else if (stype >= STT_LOPROC && stype <= STT_HIPROC) { + if (mach == EM_SPARCV9 && stype == STT_SPARC_REGISTER) + return "REGISTER"; + snprintf(s_stype, sizeof(s_stype), "PROC+%#x", + stype - STT_LOPROC); + } else + snprintf(s_stype, sizeof(s_stype), "", + stype); + return (s_stype); + } +} + +static const char * +st_vis(unsigned int svis) +{ + static char s_svis[32]; + + switch(svis) { + case STV_DEFAULT: return "DEFAULT"; + case STV_INTERNAL: return "INTERNAL"; + case STV_HIDDEN: return "HIDDEN"; + case STV_PROTECTED: return "PROTECTED"; + default: + snprintf(s_svis, sizeof(s_svis), "", svis); + return (s_svis); + } +} + +static const char * +st_shndx(unsigned int shndx) +{ + static char s_shndx[32]; + + switch (shndx) { + case SHN_UNDEF: return "UND"; + case SHN_ABS: return "ABS"; + case SHN_COMMON: return "COM"; + default: + if (shndx >= SHN_LOPROC && shndx <= SHN_HIPROC) + return "PRC"; + else if (shndx >= SHN_LOOS && shndx <= SHN_HIOS) + return "OS"; + else + snprintf(s_shndx, sizeof(s_shndx), "%u", shndx); + return (s_shndx); + } +} + +static struct { + const char *ln; + char sn; + int value; +} section_flag[] = { + {"WRITE", 'W', SHF_WRITE}, + {"ALLOC", 'A', SHF_ALLOC}, + {"EXEC", 'X', SHF_EXECINSTR}, + {"MERGE", 'M', SHF_MERGE}, + {"STRINGS", 'S', SHF_STRINGS}, + {"INFO LINK", 'I', SHF_INFO_LINK}, + {"OS NONCONF", 'O', SHF_OS_NONCONFORMING}, + {"GROUP", 'G', SHF_GROUP}, + {"TLS", 'T', SHF_TLS}, + {"COMPRESSED", 'C', SHF_COMPRESSED}, + {NULL, 0, 0} +}; + +static const char * +note_type(const char *name, unsigned int et, unsigned int nt) +{ + if ((strcmp(name, "CORE") == 0 || strcmp(name, "LINUX") == 0) && + et == ET_CORE) + return note_type_linux_core(nt); + else if (strcmp(name, "FreeBSD") == 0) + if (et == ET_CORE) + return note_type_freebsd_core(nt); + else + return note_type_freebsd(nt); + else if (strcmp(name, "GNU") == 0 && et != ET_CORE) + return note_type_gnu(nt); + else if (strcmp(name, "NetBSD") == 0 && et != ET_CORE) + return note_type_netbsd(nt); + else if (strcmp(name, "OpenBSD") == 0 && et != ET_CORE) + return note_type_openbsd(nt); + else if (strcmp(name, "Xen") == 0 && et != ET_CORE) + return note_type_xen(nt); + return note_type_unknown(nt); +} + +static const char * +note_type_freebsd(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_FREEBSD_ABI_TAG"; + case 2: return "NT_FREEBSD_NOINIT_TAG"; + case 3: return "NT_FREEBSD_ARCH_TAG"; + case 4: return "NT_FREEBSD_FEATURE_CTL"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_freebsd_core(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_PRSTATUS"; + case 2: return "NT_FPREGSET"; + case 3: return "NT_PRPSINFO"; + case 7: return "NT_THRMISC"; + case 8: return "NT_PROCSTAT_PROC"; + case 9: return "NT_PROCSTAT_FILES"; + case 10: return "NT_PROCSTAT_VMMAP"; + case 11: return "NT_PROCSTAT_GROUPS"; + case 12: return "NT_PROCSTAT_UMASK"; + case 13: return "NT_PROCSTAT_RLIMIT"; + case 14: return "NT_PROCSTAT_OSREL"; + case 15: return "NT_PROCSTAT_PSSTRINGS"; + case 16: return "NT_PROCSTAT_AUXV"; + case 17: return "NT_PTLWPINFO"; + case 0x100: return "NT_PPC_VMX (ppc Altivec registers)"; + case 0x102: return "NT_PPC_VSX (ppc VSX registers)"; + case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; + case 0x400: return "NT_ARM_VFP (arm VFP registers)"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_linux_core(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_PRSTATUS (Process status)"; + case 2: return "NT_FPREGSET (Floating point information)"; + case 3: return "NT_PRPSINFO (Process information)"; + case 4: return "NT_TASKSTRUCT (Task structure)"; + case 6: return "NT_AUXV (Auxiliary vector)"; + case 10: return "NT_PSTATUS (Linux process status)"; + case 12: return "NT_FPREGS (Linux floating point regset)"; + case 13: return "NT_PSINFO (Linux process information)"; + case 16: return "NT_LWPSTATUS (Linux lwpstatus_t type)"; + case 17: return "NT_LWPSINFO (Linux lwpinfo_t type)"; + case 18: return "NT_WIN32PSTATUS (win32_pstatus structure)"; + case 0x100: return "NT_PPC_VMX (ppc Altivec registers)"; + case 0x102: return "NT_PPC_VSX (ppc VSX registers)"; + case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; + case 0x300: return "NT_S390_HIGH_GPRS (s390 upper register halves)"; + case 0x301: return "NT_S390_TIMER (s390 timer register)"; + case 0x302: return "NT_S390_TODCMP (s390 TOD comparator register)"; + case 0x303: return "NT_S390_TODPREG (s390 TOD programmable register)"; + case 0x304: return "NT_S390_CTRS (s390 control registers)"; + case 0x305: return "NT_S390_PREFIX (s390 prefix register)"; + case 0x400: return "NT_ARM_VFP (arm VFP registers)"; + case 0x46494c45UL: return "NT_FILE (mapped files)"; + case 0x46E62B7FUL: return "NT_PRXFPREG (Linux user_xfpregs structure)"; + case 0x53494749UL: return "NT_SIGINFO (siginfo_t data)"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_gnu(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_GNU_ABI_TAG"; + case 2: return "NT_GNU_HWCAP (Hardware capabilities)"; + case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))"; + case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)"; + case 5: return "NT_GNU_PROPERTY_TYPE_0"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_netbsd(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_NETBSD_IDENT"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_openbsd(unsigned int nt) +{ + switch (nt) { + case 1: return "NT_OPENBSD_IDENT"; + default: return (note_type_unknown(nt)); + } +} + +static const char * +note_type_unknown(unsigned int nt) +{ + static char s_nt[32]; + + snprintf(s_nt, sizeof(s_nt), + nt >= 0x100 ? "" : "", nt); + return (s_nt); +} + +static const char * +note_type_xen(unsigned int nt) +{ + switch (nt) { + case 0: return "XEN_ELFNOTE_INFO"; + case 1: return "XEN_ELFNOTE_ENTRY"; + case 2: return "XEN_ELFNOTE_HYPERCALL_PAGE"; + case 3: return "XEN_ELFNOTE_VIRT_BASE"; + case 4: return "XEN_ELFNOTE_PADDR_OFFSET"; + case 5: return "XEN_ELFNOTE_XEN_VERSION"; + case 6: return "XEN_ELFNOTE_GUEST_OS"; + case 7: return "XEN_ELFNOTE_GUEST_VERSION"; + case 8: return "XEN_ELFNOTE_LOADER"; + case 9: return "XEN_ELFNOTE_PAE_MODE"; + case 10: return "XEN_ELFNOTE_FEATURES"; + case 11: return "XEN_ELFNOTE_BSD_SYMTAB"; + case 12: return "XEN_ELFNOTE_HV_START_LOW"; + case 13: return "XEN_ELFNOTE_L1_MFN_VALID"; + case 14: return "XEN_ELFNOTE_SUSPEND_CANCEL"; + case 15: return "XEN_ELFNOTE_INIT_P2M"; + case 16: return "XEN_ELFNOTE_MOD_START_PFN"; + case 17: return "XEN_ELFNOTE_SUPPORTED_FEATURES"; + default: return (note_type_unknown(nt)); + } +} + +static struct { + const char *name; + int value; +} l_flag[] = { + {"EXACT_MATCH", LL_EXACT_MATCH}, + {"IGNORE_INT_VER", LL_IGNORE_INT_VER}, + {"REQUIRE_MINOR", LL_REQUIRE_MINOR}, + {"EXPORTS", LL_EXPORTS}, + {"DELAY_LOAD", LL_DELAY_LOAD}, + {"DELTA", LL_DELTA}, + {NULL, 0} +}; + +static struct mips_option mips_exceptions_option[] = { + {OEX_PAGE0, "PAGE0"}, + {OEX_SMM, "SMM"}, + {OEX_PRECISEFP, "PRECISEFP"}, + {OEX_DISMISS, "DISMISS"}, + {0, NULL} +}; + +static struct mips_option mips_pad_option[] = { + {OPAD_PREFIX, "PREFIX"}, + {OPAD_POSTFIX, "POSTFIX"}, + {OPAD_SYMBOL, "SYMBOL"}, + {0, NULL} +}; + +static struct mips_option mips_hwpatch_option[] = { + {OHW_R4KEOP, "R4KEOP"}, + {OHW_R8KPFETCH, "R8KPFETCH"}, + {OHW_R5KEOP, "R5KEOP"}, + {OHW_R5KCVTL, "R5KCVTL"}, + {0, NULL} +}; + +static struct mips_option mips_hwa_option[] = { + {OHWA0_R4KEOP_CHECKED, "R4KEOP_CHECKED"}, + {OHWA0_R4KEOP_CLEAN, "R4KEOP_CLEAN"}, + {0, NULL} +}; + +static struct mips_option mips_hwo_option[] = { + {OHWO0_FIXADE, "FIXADE"}, + {0, NULL} +}; + +static const char * +option_kind(uint8_t kind) +{ + static char s_kind[32]; + + switch (kind) { + case ODK_NULL: return "NULL"; + case ODK_REGINFO: return "REGINFO"; + case ODK_EXCEPTIONS: return "EXCEPTIONS"; + case ODK_PAD: return "PAD"; + case ODK_HWPATCH: return "HWPATCH"; + case ODK_FILL: return "FILL"; + case ODK_TAGS: return "TAGS"; + case ODK_HWAND: return "HWAND"; + case ODK_HWOR: return "HWOR"; + case ODK_GP_GROUP: return "GP_GROUP"; + case ODK_IDENT: return "IDENT"; + default: + snprintf(s_kind, sizeof(s_kind), "", kind); + return (s_kind); + } +} + +static const char * +top_tag(unsigned int tag) +{ + static char s_top_tag[32]; + + switch (tag) { + case 1: return "File Attributes"; + case 2: return "Section Attributes"; + case 3: return "Symbol Attributes"; + default: + snprintf(s_top_tag, sizeof(s_top_tag), "Unknown tag: %u", tag); + return (s_top_tag); + } +} + +static const char * +aeabi_cpu_arch(uint64_t arch) +{ + static char s_cpu_arch[32]; + + switch (arch) { + case 0: return "Pre-V4"; + case 1: return "ARM v4"; + case 2: return "ARM v4T"; + case 3: return "ARM v5T"; + case 4: return "ARM v5TE"; + case 5: return "ARM v5TEJ"; + case 6: return "ARM v6"; + case 7: return "ARM v6KZ"; + case 8: return "ARM v6T2"; + case 9: return "ARM v6K"; + case 10: return "ARM v7"; + case 11: return "ARM v6-M"; + case 12: return "ARM v6S-M"; + case 13: return "ARM v7E-M"; + default: + snprintf(s_cpu_arch, sizeof(s_cpu_arch), + "Unknown (%ju)", (uintmax_t) arch); + return (s_cpu_arch); + } +} + +static const char * +aeabi_cpu_arch_profile(uint64_t pf) +{ + static char s_arch_profile[32]; + + switch (pf) { + case 0: + return "Not applicable"; + case 0x41: /* 'A' */ + return "Application Profile"; + case 0x52: /* 'R' */ + return "Real-Time Profile"; + case 0x4D: /* 'M' */ + return "Microcontroller Profile"; + case 0x53: /* 'S' */ + return "Application or Real-Time Profile"; + default: + snprintf(s_arch_profile, sizeof(s_arch_profile), + "Unknown (%ju)\n", (uintmax_t) pf); + return (s_arch_profile); + } +} + +static const char * +aeabi_arm_isa(uint64_t ai) +{ + static char s_ai[32]; + + switch (ai) { + case 0: return "No"; + case 1: return "Yes"; + default: + snprintf(s_ai, sizeof(s_ai), "Unknown (%ju)\n", + (uintmax_t) ai); + return (s_ai); + } +} + +static const char * +aeabi_thumb_isa(uint64_t ti) +{ + static char s_ti[32]; + + switch (ti) { + case 0: return "No"; + case 1: return "16-bit Thumb"; + case 2: return "32-bit Thumb"; + default: + snprintf(s_ti, sizeof(s_ti), "Unknown (%ju)\n", + (uintmax_t) ti); + return (s_ti); + } +} + +static const char * +aeabi_fp_arch(uint64_t fp) +{ + static char s_fp_arch[32]; + + switch (fp) { + case 0: return "No"; + case 1: return "VFPv1"; + case 2: return "VFPv2"; + case 3: return "VFPv3"; + case 4: return "VFPv3-D16"; + case 5: return "VFPv4"; + case 6: return "VFPv4-D16"; + default: + snprintf(s_fp_arch, sizeof(s_fp_arch), "Unknown (%ju)", + (uintmax_t) fp); + return (s_fp_arch); + } +} + +static const char * +aeabi_wmmx_arch(uint64_t wmmx) +{ + static char s_wmmx[32]; + + switch (wmmx) { + case 0: return "No"; + case 1: return "WMMXv1"; + case 2: return "WMMXv2"; + default: + snprintf(s_wmmx, sizeof(s_wmmx), "Unknown (%ju)", + (uintmax_t) wmmx); + return (s_wmmx); + } +} + +static const char * +aeabi_adv_simd_arch(uint64_t simd) +{ + static char s_simd[32]; + + switch (simd) { + case 0: return "No"; + case 1: return "NEONv1"; + case 2: return "NEONv2"; + default: + snprintf(s_simd, sizeof(s_simd), "Unknown (%ju)", + (uintmax_t) simd); + return (s_simd); + } +} + +static const char * +aeabi_pcs_config(uint64_t pcs) +{ + static char s_pcs[32]; + + switch (pcs) { + case 0: return "None"; + case 1: return "Bare platform"; + case 2: return "Linux"; + case 3: return "Linux DSO"; + case 4: return "Palm OS 2004"; + case 5: return "Palm OS (future)"; + case 6: return "Symbian OS 2004"; + case 7: return "Symbian OS (future)"; + default: + snprintf(s_pcs, sizeof(s_pcs), "Unknown (%ju)", + (uintmax_t) pcs); + return (s_pcs); + } +} + +static const char * +aeabi_pcs_r9(uint64_t r9) +{ + static char s_r9[32]; + + switch (r9) { + case 0: return "V6"; + case 1: return "SB"; + case 2: return "TLS pointer"; + case 3: return "Unused"; + default: + snprintf(s_r9, sizeof(s_r9), "Unknown (%ju)", (uintmax_t) r9); + return (s_r9); + } +} + +static const char * +aeabi_pcs_rw(uint64_t rw) +{ + static char s_rw[32]; + + switch (rw) { + case 0: return "Absolute"; + case 1: return "PC-relative"; + case 2: return "SB-relative"; + case 3: return "None"; + default: + snprintf(s_rw, sizeof(s_rw), "Unknown (%ju)", (uintmax_t) rw); + return (s_rw); + } +} + +static const char * +aeabi_pcs_ro(uint64_t ro) +{ + static char s_ro[32]; + + switch (ro) { + case 0: return "Absolute"; + case 1: return "PC-relative"; + case 2: return "None"; + default: + snprintf(s_ro, sizeof(s_ro), "Unknown (%ju)", (uintmax_t) ro); + return (s_ro); + } +} + +static const char * +aeabi_pcs_got(uint64_t got) +{ + static char s_got[32]; + + switch (got) { + case 0: return "None"; + case 1: return "direct"; + case 2: return "indirect via GOT"; + default: + snprintf(s_got, sizeof(s_got), "Unknown (%ju)", + (uintmax_t) got); + return (s_got); + } +} + +static const char * +aeabi_pcs_wchar_t(uint64_t wt) +{ + static char s_wt[32]; + + switch (wt) { + case 0: return "None"; + case 2: return "wchar_t size 2"; + case 4: return "wchar_t size 4"; + default: + snprintf(s_wt, sizeof(s_wt), "Unknown (%ju)", (uintmax_t) wt); + return (s_wt); + } +} + +static const char * +aeabi_enum_size(uint64_t es) +{ + static char s_es[32]; + + switch (es) { + case 0: return "None"; + case 1: return "smallest"; + case 2: return "32-bit"; + case 3: return "visible 32-bit"; + default: + snprintf(s_es, sizeof(s_es), "Unknown (%ju)", (uintmax_t) es); + return (s_es); + } +} + +static const char * +aeabi_align_needed(uint64_t an) +{ + static char s_align_n[64]; + + switch (an) { + case 0: return "No"; + case 1: return "8-byte align"; + case 2: return "4-byte align"; + case 3: return "Reserved"; + default: + if (an >= 4 && an <= 12) + snprintf(s_align_n, sizeof(s_align_n), "8-byte align" + " and up to 2^%ju-byte extended align", + (uintmax_t) an); + else + snprintf(s_align_n, sizeof(s_align_n), "Unknown (%ju)", + (uintmax_t) an); + return (s_align_n); + } +} + +static const char * +aeabi_align_preserved(uint64_t ap) +{ + static char s_align_p[128]; + + switch (ap) { + case 0: return "No"; + case 1: return "8-byte align"; + case 2: return "8-byte align and SP % 8 == 0"; + case 3: return "Reserved"; + default: + if (ap >= 4 && ap <= 12) + snprintf(s_align_p, sizeof(s_align_p), "8-byte align" + " and SP %% 8 == 0 and up to 2^%ju-byte extended" + " align", (uintmax_t) ap); + else + snprintf(s_align_p, sizeof(s_align_p), "Unknown (%ju)", + (uintmax_t) ap); + return (s_align_p); + } +} + +static const char * +aeabi_fp_rounding(uint64_t fr) +{ + static char s_fp_r[32]; + + switch (fr) { + case 0: return "Unused"; + case 1: return "Needed"; + default: + snprintf(s_fp_r, sizeof(s_fp_r), "Unknown (%ju)", + (uintmax_t) fr); + return (s_fp_r); + } +} + +static const char * +aeabi_fp_denormal(uint64_t fd) +{ + static char s_fp_d[32]; + + switch (fd) { + case 0: return "Unused"; + case 1: return "Needed"; + case 2: return "Sign Only"; + default: + snprintf(s_fp_d, sizeof(s_fp_d), "Unknown (%ju)", + (uintmax_t) fd); + return (s_fp_d); + } +} + +static const char * +aeabi_fp_exceptions(uint64_t fe) +{ + static char s_fp_e[32]; + + switch (fe) { + case 0: return "Unused"; + case 1: return "Needed"; + default: + snprintf(s_fp_e, sizeof(s_fp_e), "Unknown (%ju)", + (uintmax_t) fe); + return (s_fp_e); + } +} + +static const char * +aeabi_fp_user_exceptions(uint64_t fu) +{ + static char s_fp_u[32]; + + switch (fu) { + case 0: return "Unused"; + case 1: return "Needed"; + default: + snprintf(s_fp_u, sizeof(s_fp_u), "Unknown (%ju)", + (uintmax_t) fu); + return (s_fp_u); + } +} + +static const char * +aeabi_fp_number_model(uint64_t fn) +{ + static char s_fp_n[32]; + + switch (fn) { + case 0: return "Unused"; + case 1: return "IEEE 754 normal"; + case 2: return "RTABI"; + case 3: return "IEEE 754"; + default: + snprintf(s_fp_n, sizeof(s_fp_n), "Unknown (%ju)", + (uintmax_t) fn); + return (s_fp_n); + } +} + +static const char * +aeabi_fp_16bit_format(uint64_t fp16) +{ + static char s_fp_16[64]; + + switch (fp16) { + case 0: return "None"; + case 1: return "IEEE 754"; + case 2: return "VFPv3/Advanced SIMD (alternative format)"; + default: + snprintf(s_fp_16, sizeof(s_fp_16), "Unknown (%ju)", + (uintmax_t) fp16); + return (s_fp_16); + } +} + +static const char * +aeabi_mpext(uint64_t mp) +{ + static char s_mp[32]; + + switch (mp) { + case 0: return "Not allowed"; + case 1: return "Allowed"; + default: + snprintf(s_mp, sizeof(s_mp), "Unknown (%ju)", + (uintmax_t) mp); + return (s_mp); + } +} + +static const char * +aeabi_div(uint64_t du) +{ + static char s_du[32]; + + switch (du) { + case 0: return "Yes (V7-R/V7-M)"; + case 1: return "No"; + case 2: return "Yes (V7-A)"; + default: + snprintf(s_du, sizeof(s_du), "Unknown (%ju)", + (uintmax_t) du); + return (s_du); + } +} + +static const char * +aeabi_t2ee(uint64_t t2ee) +{ + static char s_t2ee[32]; + + switch (t2ee) { + case 0: return "Not allowed"; + case 1: return "Allowed"; + default: + snprintf(s_t2ee, sizeof(s_t2ee), "Unknown(%ju)", + (uintmax_t) t2ee); + return (s_t2ee); + } + +} + +static const char * +aeabi_hardfp(uint64_t hfp) +{ + static char s_hfp[32]; + + switch (hfp) { + case 0: return "Tag_FP_arch"; + case 1: return "only SP"; + case 2: return "only DP"; + case 3: return "both SP and DP"; + default: + snprintf(s_hfp, sizeof(s_hfp), "Unknown (%ju)", + (uintmax_t) hfp); + return (s_hfp); + } +} + +static const char * +aeabi_vfp_args(uint64_t va) +{ + static char s_va[32]; + + switch (va) { + case 0: return "AAPCS (base variant)"; + case 1: return "AAPCS (VFP variant)"; + case 2: return "toolchain-specific"; + default: + snprintf(s_va, sizeof(s_va), "Unknown (%ju)", (uintmax_t) va); + return (s_va); + } +} + +static const char * +aeabi_wmmx_args(uint64_t wa) +{ + static char s_wa[32]; + + switch (wa) { + case 0: return "AAPCS (base variant)"; + case 1: return "Intel WMMX"; + case 2: return "toolchain-specific"; + default: + snprintf(s_wa, sizeof(s_wa), "Unknown(%ju)", (uintmax_t) wa); + return (s_wa); + } +} + +static const char * +aeabi_unaligned_access(uint64_t ua) +{ + static char s_ua[32]; + + switch (ua) { + case 0: return "Not allowed"; + case 1: return "Allowed"; + default: + snprintf(s_ua, sizeof(s_ua), "Unknown(%ju)", (uintmax_t) ua); + return (s_ua); + } +} + +static const char * +aeabi_fp_hpext(uint64_t fh) +{ + static char s_fh[32]; + + switch (fh) { + case 0: return "Not allowed"; + case 1: return "Allowed"; + default: + snprintf(s_fh, sizeof(s_fh), "Unknown(%ju)", (uintmax_t) fh); + return (s_fh); + } +} + +static const char * +aeabi_optm_goal(uint64_t og) +{ + static char s_og[32]; + + switch (og) { + case 0: return "None"; + case 1: return "Speed"; + case 2: return "Speed aggressive"; + case 3: return "Space"; + case 4: return "Space aggressive"; + case 5: return "Debugging"; + case 6: return "Best Debugging"; + default: + snprintf(s_og, sizeof(s_og), "Unknown(%ju)", (uintmax_t) og); + return (s_og); + } +} + +static const char * +aeabi_fp_optm_goal(uint64_t fog) +{ + static char s_fog[32]; + + switch (fog) { + case 0: return "None"; + case 1: return "Speed"; + case 2: return "Speed aggressive"; + case 3: return "Space"; + case 4: return "Space aggressive"; + case 5: return "Accurary"; + case 6: return "Best Accurary"; + default: + snprintf(s_fog, sizeof(s_fog), "Unknown(%ju)", + (uintmax_t) fog); + return (s_fog); + } +} + +static const char * +aeabi_virtual(uint64_t vt) +{ + static char s_virtual[64]; + + switch (vt) { + case 0: return "No"; + case 1: return "TrustZone"; + case 2: return "Virtualization extension"; + case 3: return "TrustZone and virtualization extension"; + default: + snprintf(s_virtual, sizeof(s_virtual), "Unknown(%ju)", + (uintmax_t) vt); + return (s_virtual); + } +} + +static struct { + uint64_t tag; + const char *s_tag; + const char *(*get_desc)(uint64_t val); +} aeabi_tags[] = { + {4, "Tag_CPU_raw_name", NULL}, + {5, "Tag_CPU_name", NULL}, + {6, "Tag_CPU_arch", aeabi_cpu_arch}, + {7, "Tag_CPU_arch_profile", aeabi_cpu_arch_profile}, + {8, "Tag_ARM_ISA_use", aeabi_arm_isa}, + {9, "Tag_THUMB_ISA_use", aeabi_thumb_isa}, + {10, "Tag_FP_arch", aeabi_fp_arch}, + {11, "Tag_WMMX_arch", aeabi_wmmx_arch}, + {12, "Tag_Advanced_SIMD_arch", aeabi_adv_simd_arch}, + {13, "Tag_PCS_config", aeabi_pcs_config}, + {14, "Tag_ABI_PCS_R9_use", aeabi_pcs_r9}, + {15, "Tag_ABI_PCS_RW_data", aeabi_pcs_rw}, + {16, "Tag_ABI_PCS_RO_data", aeabi_pcs_ro}, + {17, "Tag_ABI_PCS_GOT_use", aeabi_pcs_got}, + {18, "Tag_ABI_PCS_wchar_t", aeabi_pcs_wchar_t}, + {19, "Tag_ABI_FP_rounding", aeabi_fp_rounding}, + {20, "Tag_ABI_FP_denormal", aeabi_fp_denormal}, + {21, "Tag_ABI_FP_exceptions", aeabi_fp_exceptions}, + {22, "Tag_ABI_FP_user_exceptions", aeabi_fp_user_exceptions}, + {23, "Tag_ABI_FP_number_model", aeabi_fp_number_model}, + {24, "Tag_ABI_align_needed", aeabi_align_needed}, + {25, "Tag_ABI_align_preserved", aeabi_align_preserved}, + {26, "Tag_ABI_enum_size", aeabi_enum_size}, + {27, "Tag_ABI_HardFP_use", aeabi_hardfp}, + {28, "Tag_ABI_VFP_args", aeabi_vfp_args}, + {29, "Tag_ABI_WMMX_args", aeabi_wmmx_args}, + {30, "Tag_ABI_optimization_goals", aeabi_optm_goal}, + {31, "Tag_ABI_FP_optimization_goals", aeabi_fp_optm_goal}, + {32, "Tag_compatibility", NULL}, + {34, "Tag_CPU_unaligned_access", aeabi_unaligned_access}, + {36, "Tag_FP_HP_extension", aeabi_fp_hpext}, + {38, "Tag_ABI_FP_16bit_format", aeabi_fp_16bit_format}, + {42, "Tag_MPextension_use", aeabi_mpext}, + {44, "Tag_DIV_use", aeabi_div}, + {64, "Tag_nodefaults", NULL}, + {65, "Tag_also_compatible_with", NULL}, + {66, "Tag_T2EE_use", aeabi_t2ee}, + {67, "Tag_conformance", NULL}, + {68, "Tag_Virtualization_use", aeabi_virtual}, + {70, "Tag_MPextension_use", aeabi_mpext}, +}; + +static const char * +mips_abi_fp(uint64_t fp) +{ + static char s_mips_abi_fp[64]; + + switch (fp) { + case 0: return "N/A"; + case 1: return "Hard float (double precision)"; + case 2: return "Hard float (single precision)"; + case 3: return "Soft float"; + case 4: return "64-bit float (-mips32r2 -mfp64)"; + default: + snprintf(s_mips_abi_fp, sizeof(s_mips_abi_fp), "Unknown(%ju)", + (uintmax_t) fp); + return (s_mips_abi_fp); + } +} + +static const char * +ppc_abi_fp(uint64_t fp) +{ + static char s_ppc_abi_fp[64]; + + switch (fp) { + case 0: return "N/A"; + case 1: return "Hard float (double precision)"; + case 2: return "Soft float"; + case 3: return "Hard float (single precision)"; + default: + snprintf(s_ppc_abi_fp, sizeof(s_ppc_abi_fp), "Unknown(%ju)", + (uintmax_t) fp); + return (s_ppc_abi_fp); + } +} + +static const char * +ppc_abi_vector(uint64_t vec) +{ + static char s_vec[64]; + + switch (vec) { + case 0: return "N/A"; + case 1: return "Generic purpose registers"; + case 2: return "AltiVec registers"; + case 3: return "SPE registers"; + default: + snprintf(s_vec, sizeof(s_vec), "Unknown(%ju)", (uintmax_t) vec); + return (s_vec); + } +} + +static const char * +dwarf_reg(unsigned int mach, unsigned int reg) +{ + + switch (mach) { + case EM_386: + case EM_IAMCU: + switch (reg) { + case 0: return "eax"; + case 1: return "ecx"; + case 2: return "edx"; + case 3: return "ebx"; + case 4: return "esp"; + case 5: return "ebp"; + case 6: return "esi"; + case 7: return "edi"; + case 8: return "eip"; + case 9: return "eflags"; + case 11: return "st0"; + case 12: return "st1"; + case 13: return "st2"; + case 14: return "st3"; + case 15: return "st4"; + case 16: return "st5"; + case 17: return "st6"; + case 18: return "st7"; + case 21: return "xmm0"; + case 22: return "xmm1"; + case 23: return "xmm2"; + case 24: return "xmm3"; + case 25: return "xmm4"; + case 26: return "xmm5"; + case 27: return "xmm6"; + case 28: return "xmm7"; + case 29: return "mm0"; + case 30: return "mm1"; + case 31: return "mm2"; + case 32: return "mm3"; + case 33: return "mm4"; + case 34: return "mm5"; + case 35: return "mm6"; + case 36: return "mm7"; + case 37: return "fcw"; + case 38: return "fsw"; + case 39: return "mxcsr"; + case 40: return "es"; + case 41: return "cs"; + case 42: return "ss"; + case 43: return "ds"; + case 44: return "fs"; + case 45: return "gs"; + case 48: return "tr"; + case 49: return "ldtr"; + default: return (NULL); + } + case EM_RISCV: + switch (reg) { + case 0: return "zero"; + case 1: return "ra"; + case 2: return "sp"; + case 3: return "gp"; + case 4: return "tp"; + case 5: return "t0"; + case 6: return "t1"; + case 7: return "t2"; + case 8: return "s0"; + case 9: return "s1"; + case 10: return "a0"; + case 11: return "a1"; + case 12: return "a2"; + case 13: return "a3"; + case 14: return "a4"; + case 15: return "a5"; + case 16: return "a6"; + case 17: return "a7"; + case 18: return "s2"; + case 19: return "s3"; + case 20: return "s4"; + case 21: return "s5"; + case 22: return "s6"; + case 23: return "s7"; + case 24: return "s8"; + case 25: return "s9"; + case 26: return "s10"; + case 27: return "s11"; + case 28: return "t3"; + case 29: return "t4"; + case 30: return "t5"; + case 31: return "t6"; + case 32: return "ft0"; + case 33: return "ft1"; + case 34: return "ft2"; + case 35: return "ft3"; + case 36: return "ft4"; + case 37: return "ft5"; + case 38: return "ft6"; + case 39: return "ft7"; + case 40: return "fs0"; + case 41: return "fs1"; + case 42: return "fa0"; + case 43: return "fa1"; + case 44: return "fa2"; + case 45: return "fa3"; + case 46: return "fa4"; + case 47: return "fa5"; + case 48: return "fa6"; + case 49: return "fa7"; + case 50: return "fs2"; + case 51: return "fs3"; + case 52: return "fs4"; + case 53: return "fs5"; + case 54: return "fs6"; + case 55: return "fs7"; + case 56: return "fs8"; + case 57: return "fs9"; + case 58: return "fs10"; + case 59: return "fs11"; + case 60: return "ft8"; + case 61: return "ft9"; + case 62: return "ft10"; + case 63: return "ft11"; + default: return (NULL); + } + case EM_X86_64: + switch (reg) { + case 0: return "rax"; + case 1: return "rdx"; + case 2: return "rcx"; + case 3: return "rbx"; + case 4: return "rsi"; + case 5: return "rdi"; + case 6: return "rbp"; + case 7: return "rsp"; + case 16: return "rip"; + case 17: return "xmm0"; + case 18: return "xmm1"; + case 19: return "xmm2"; + case 20: return "xmm3"; + case 21: return "xmm4"; + case 22: return "xmm5"; + case 23: return "xmm6"; + case 24: return "xmm7"; + case 25: return "xmm8"; + case 26: return "xmm9"; + case 27: return "xmm10"; + case 28: return "xmm11"; + case 29: return "xmm12"; + case 30: return "xmm13"; + case 31: return "xmm14"; + case 32: return "xmm15"; + case 33: return "st0"; + case 34: return "st1"; + case 35: return "st2"; + case 36: return "st3"; + case 37: return "st4"; + case 38: return "st5"; + case 39: return "st6"; + case 40: return "st7"; + case 41: return "mm0"; + case 42: return "mm1"; + case 43: return "mm2"; + case 44: return "mm3"; + case 45: return "mm4"; + case 46: return "mm5"; + case 47: return "mm6"; + case 48: return "mm7"; + case 49: return "rflags"; + case 50: return "es"; + case 51: return "cs"; + case 52: return "ss"; + case 53: return "ds"; + case 54: return "fs"; + case 55: return "gs"; + case 58: return "fs.base"; + case 59: return "gs.base"; + case 62: return "tr"; + case 63: return "ldtr"; + case 64: return "mxcsr"; + case 65: return "fcw"; + case 66: return "fsw"; + default: return (NULL); + } + default: + return (NULL); + } +} + +static void +dump_ehdr(struct readelf *re) +{ + size_t phnum, shnum, shstrndx; + int i; + + printf("ELF Header:\n"); + + /* e_ident[]. */ + printf(" Magic: "); + for (i = 0; i < EI_NIDENT; i++) + printf("%.2x ", re->ehdr.e_ident[i]); + putchar('\n'); + + /* EI_CLASS. */ + printf("%-37s%s\n", " Class:", elf_class(re->ehdr.e_ident[EI_CLASS])); + + /* EI_DATA. */ + printf("%-37s%s\n", " Data:", elf_endian(re->ehdr.e_ident[EI_DATA])); + + /* EI_VERSION. */ + printf("%-37s%d %s\n", " Version:", re->ehdr.e_ident[EI_VERSION], + elf_ver(re->ehdr.e_ident[EI_VERSION])); + + /* EI_OSABI. */ + printf("%-37s%s\n", " OS/ABI:", elf_osabi(re->ehdr.e_ident[EI_OSABI])); + + /* EI_ABIVERSION. */ + printf("%-37s%d\n", " ABI Version:", re->ehdr.e_ident[EI_ABIVERSION]); + + /* e_type. */ + printf("%-37s%s\n", " Type:", elf_type(re->ehdr.e_type)); + + /* e_machine. */ + printf("%-37s%s\n", " Machine:", elf_machine(re->ehdr.e_machine)); + + /* e_version. */ + printf("%-37s%#x\n", " Version:", re->ehdr.e_version); + + /* e_entry. */ + printf("%-37s%#jx\n", " Entry point address:", + (uintmax_t)re->ehdr.e_entry); + + /* e_phoff. */ + printf("%-37s%ju (bytes into file)\n", " Start of program headers:", + (uintmax_t)re->ehdr.e_phoff); + + /* e_shoff. */ + printf("%-37s%ju (bytes into file)\n", " Start of section headers:", + (uintmax_t)re->ehdr.e_shoff); + + /* e_flags. */ + printf("%-37s%#x", " Flags:", re->ehdr.e_flags); + dump_eflags(re, re->ehdr.e_flags); + putchar('\n'); + + /* e_ehsize. */ + printf("%-37s%u (bytes)\n", " Size of this header:", + re->ehdr.e_ehsize); + + /* e_phentsize. */ + printf("%-37s%u (bytes)\n", " Size of program headers:", + re->ehdr.e_phentsize); + + /* e_phnum. */ + printf("%-37s%u", " Number of program headers:", re->ehdr.e_phnum); + if (re->ehdr.e_phnum == PN_XNUM) { + /* Extended program header numbering is in use. */ + if (elf_getphnum(re->elf, &phnum)) + printf(" (%zu)", phnum); + } + putchar('\n'); + + /* e_shentsize. */ + printf("%-37s%u (bytes)\n", " Size of section headers:", + re->ehdr.e_shentsize); + + /* e_shnum. */ + printf("%-37s%u", " Number of section headers:", re->ehdr.e_shnum); + if (re->ehdr.e_shnum == SHN_UNDEF) { + /* Extended section numbering is in use. */ + if (elf_getshnum(re->elf, &shnum)) + printf(" (%ju)", (uintmax_t)shnum); + } + putchar('\n'); + + /* e_shstrndx. */ + printf("%-37s%u", " Section header string table index:", + re->ehdr.e_shstrndx); + if (re->ehdr.e_shstrndx == SHN_XINDEX) { + /* Extended section numbering is in use. */ + if (elf_getshstrndx(re->elf, &shstrndx)) + printf(" (%ju)", (uintmax_t)shstrndx); + } + putchar('\n'); +} + +static void +dump_eflags(struct readelf *re, uint64_t e_flags) +{ + struct eflags_desc *edesc; + int arm_eabi; + + edesc = NULL; + switch (re->ehdr.e_machine) { + case EM_ARM: + arm_eabi = (e_flags & EF_ARM_EABIMASK) >> 24; + if (arm_eabi == 0) + printf(", GNU EABI"); + else if (arm_eabi <= 5) + printf(", Version%d EABI", arm_eabi); + edesc = arm_eflags_desc; + break; + case EM_MIPS: + case EM_MIPS_RS3_LE: + switch ((e_flags & EF_MIPS_ARCH) >> 28) { + case 0: printf(", mips1"); break; + case 1: printf(", mips2"); break; + case 2: printf(", mips3"); break; + case 3: printf(", mips4"); break; + case 4: printf(", mips5"); break; + case 5: printf(", mips32"); break; + case 6: printf(", mips64"); break; + case 7: printf(", mips32r2"); break; + case 8: printf(", mips64r2"); break; + default: break; + } + switch ((e_flags & 0x00FF0000) >> 16) { + case 0x81: printf(", 3900"); break; + case 0x82: printf(", 4010"); break; + case 0x83: printf(", 4100"); break; + case 0x85: printf(", 4650"); break; + case 0x87: printf(", 4120"); break; + case 0x88: printf(", 4111"); break; + case 0x8a: printf(", sb1"); break; + case 0x8b: printf(", octeon"); break; + case 0x8c: printf(", xlr"); break; + case 0x91: printf(", 5400"); break; + case 0x98: printf(", 5500"); break; + case 0x99: printf(", 9000"); break; + case 0xa0: printf(", loongson-2e"); break; + case 0xa1: printf(", loongson-2f"); break; + default: break; + } + switch ((e_flags & 0x0000F000) >> 12) { + case 1: printf(", o32"); break; + case 2: printf(", o64"); break; + case 3: printf(", eabi32"); break; + case 4: printf(", eabi64"); break; + default: break; + } + edesc = mips_eflags_desc; + break; + case EM_PPC64: + switch (e_flags) { + case 0: printf(", Unspecified or Power ELF V1 ABI"); break; + case 1: printf(", Power ELF V1 ABI"); break; + case 2: printf(", OpenPOWER ELF V2 ABI"); break; + default: break; + } + /* FALLTHROUGH */ + case EM_PPC: + edesc = powerpc_eflags_desc; + break; + case EM_RISCV: + switch (e_flags & EF_RISCV_FLOAT_ABI_MASK) { + case EF_RISCV_FLOAT_ABI_SOFT: + printf(", soft-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_SINGLE: + printf(", single-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_DOUBLE: + printf(", double-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_QUAD: + printf(", quad-float ABI"); + break; + } + edesc = riscv_eflags_desc; + break; + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + switch ((e_flags & EF_SPARCV9_MM)) { + case EF_SPARCV9_TSO: printf(", tso"); break; + case EF_SPARCV9_PSO: printf(", pso"); break; + case EF_SPARCV9_MM: printf(", rmo"); break; + default: break; + } + edesc = sparc_eflags_desc; + break; + default: + break; + } + + if (edesc != NULL) { + while (edesc->desc != NULL) { + if (e_flags & edesc->flag) + printf(", %s", edesc->desc); + edesc++; + } + } +} + +static void +dump_phdr(struct readelf *re) +{ + const char *rawfile; + GElf_Phdr phdr; + size_t phnum, size; + int i, j; + +#define PH_HDR "Type", "Offset", "VirtAddr", "PhysAddr", "FileSiz", \ + "MemSiz", "Flg", "Align" +#define PH_CT phdr_type(re->ehdr.e_machine, phdr.p_type), \ + (uintmax_t)phdr.p_offset, (uintmax_t)phdr.p_vaddr, \ + (uintmax_t)phdr.p_paddr, (uintmax_t)phdr.p_filesz, \ + (uintmax_t)phdr.p_memsz, \ + phdr.p_flags & PF_R ? 'R' : ' ', \ + phdr.p_flags & PF_W ? 'W' : ' ', \ + phdr.p_flags & PF_X ? 'E' : ' ', \ + (uintmax_t)phdr.p_align + + if (elf_getphnum(re->elf, &phnum) == 0) { + warnx("elf_getphnum failed: %s", elf_errmsg(-1)); + return; + } + if (phnum == 0) { + printf("\nThere are no program headers in this file.\n"); + return; + } + + printf("\nElf file type is %s", elf_type(re->ehdr.e_type)); + printf("\nEntry point 0x%jx\n", (uintmax_t)re->ehdr.e_entry); + printf("There are %ju program headers, starting at offset %ju\n", + (uintmax_t)phnum, (uintmax_t)re->ehdr.e_phoff); + + /* Dump program headers. */ + printf("\nProgram Headers:\n"); + if (re->ec == ELFCLASS32) + printf(" %-15s%-9s%-11s%-11s%-8s%-8s%-4s%s\n", PH_HDR); + else if (re->options & RE_WW) + printf(" %-15s%-9s%-19s%-19s%-9s%-9s%-4s%s\n", PH_HDR); + else + printf(" %-15s%-19s%-19s%s\n %-19s%-20s" + "%-7s%s\n", PH_HDR); + for (i = 0; (size_t) i < phnum; i++) { + if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { + warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); + continue; + } + /* TODO: Add arch-specific segment type dump. */ + if (re->ec == ELFCLASS32) + printf(" %-14.14s 0x%6.6jx 0x%8.8jx 0x%8.8jx " + "0x%5.5jx 0x%5.5jx %c%c%c %#jx\n", PH_CT); + else if (re->options & RE_WW) + printf(" %-14.14s 0x%6.6jx 0x%16.16jx 0x%16.16jx " + "0x%6.6jx 0x%6.6jx %c%c%c %#jx\n", PH_CT); + else + printf(" %-14.14s 0x%16.16jx 0x%16.16jx 0x%16.16jx\n" + " 0x%16.16jx 0x%16.16jx %c%c%c" + " %#jx\n", PH_CT); + if (phdr.p_type == PT_INTERP) { + if ((rawfile = elf_rawfile(re->elf, &size)) == NULL) { + warnx("elf_rawfile failed: %s", elf_errmsg(-1)); + continue; + } + if (phdr.p_offset >= size) { + warnx("invalid program header offset"); + continue; + } + printf(" [Requesting program interpreter: %s]\n", + rawfile + phdr.p_offset); + } + } + + /* Dump section to segment mapping. */ + if (re->shnum == 0) + return; + printf("\n Section to Segment mapping:\n"); + printf(" Segment Sections...\n"); + for (i = 0; (size_t)i < phnum; i++) { + if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { + warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); + continue; + } + printf(" %2.2d ", i); + /* skip NULL section. */ + for (j = 1; (size_t)j < re->shnum; j++) { + if (re->sl[j].off < phdr.p_offset) + continue; + if (re->sl[j].off + re->sl[j].sz > + phdr.p_offset + phdr.p_filesz && + re->sl[j].type != SHT_NOBITS) + continue; + if (re->sl[j].addr < phdr.p_vaddr || + re->sl[j].addr + re->sl[j].sz > + phdr.p_vaddr + phdr.p_memsz) + continue; + if (phdr.p_type == PT_TLS && + (re->sl[j].flags & SHF_TLS) == 0) + continue; + printf("%s ", re->sl[j].name); + } + printf("\n"); + } +#undef PH_HDR +#undef PH_CT +} + +static char * +section_flags(struct readelf *re, struct section *s) +{ +#define BUF_SZ 256 + static char buf[BUF_SZ]; + int i, p, nb; + + p = 0; + nb = re->ec == ELFCLASS32 ? 8 : 16; + if (re->options & RE_T) { + snprintf(buf, BUF_SZ, "[%*.*jx]: ", nb, nb, + (uintmax_t)s->flags); + p += nb + 4; + } + for (i = 0; section_flag[i].ln != NULL; i++) { + if ((s->flags & section_flag[i].value) == 0) + continue; + if (re->options & RE_T) { + snprintf(&buf[p], BUF_SZ - p, "%s, ", + section_flag[i].ln); + p += strlen(section_flag[i].ln) + 2; + } else + buf[p++] = section_flag[i].sn; + } + if (re->options & RE_T && p > nb + 4) + p -= 2; + buf[p] = '\0'; + + return (buf); +} + +static void +dump_shdr(struct readelf *re) +{ + struct section *s; + int i; + +#define S_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ + "Flg", "Lk", "Inf", "Al" +#define S_HDRL "[Nr] Name", "Type", "Address", "Offset", "Size", \ + "EntSize", "Flags", "Link", "Info", "Align" +#define ST_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ + "Lk", "Inf", "Al", "Flags" +#define ST_HDRL "[Nr] Name", "Type", "Address", "Offset", "Link", \ + "Size", "EntSize", "Info", "Align", "Flags" +#define S_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ + (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ + (uintmax_t)s->entsize, section_flags(re, s), \ + s->link, s->info, (uintmax_t)s->align +#define ST_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ + (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ + (uintmax_t)s->entsize, s->link, s->info, \ + (uintmax_t)s->align, section_flags(re, s) +#define ST_CTL i, s->name, section_type(re->ehdr.e_machine, s->type), \ + (uintmax_t)s->addr, (uintmax_t)s->off, s->link, \ + (uintmax_t)s->sz, (uintmax_t)s->entsize, s->info, \ + (uintmax_t)s->align, section_flags(re, s) + + if (re->shnum == 0) { + printf("\nThere are no sections in this file.\n"); + return; + } + printf("There are %ju section headers, starting at offset 0x%jx:\n", + (uintmax_t)re->shnum, (uintmax_t)re->ehdr.e_shoff); + printf("\nSection Headers:\n"); + if (re->ec == ELFCLASS32) { + if (re->options & RE_T) + printf(" %s\n %-16s%-9s%-7s%-7s%-5s%-3s%-4s%s\n" + "%12s\n", ST_HDR); + else + printf(" %-23s%-16s%-9s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", + S_HDR); + } else if (re->options & RE_WW) { + if (re->options & RE_T) + printf(" %s\n %-16s%-17s%-7s%-7s%-5s%-3s%-4s%s\n" + "%12s\n", ST_HDR); + else + printf(" %-23s%-16s%-17s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", + S_HDR); + } else { + if (re->options & RE_T) + printf(" %s\n %-18s%-17s%-18s%s\n %-18s" + "%-17s%-18s%s\n%12s\n", ST_HDRL); + else + printf(" %-23s%-17s%-18s%s\n %-18s%-17s%-7s%" + "-6s%-6s%s\n", S_HDRL); + } + for (i = 0; (size_t)i < re->shnum; i++) { + s = &re->sl[i]; + if (re->ec == ELFCLASS32) { + if (re->options & RE_T) + printf(" [%2d] %s\n %-15.15s %8.8jx" + " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" + " %s\n", ST_CT); + else + printf(" [%2d] %-17.17s %-15.15s %8.8jx" + " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", + S_CT); + } else if (re->options & RE_WW) { + if (re->options & RE_T) + printf(" [%2d] %s\n %-15.15s %16.16jx" + " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" + " %s\n", ST_CT); + else + printf(" [%2d] %-17.17s %-15.15s %16.16jx" + " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", + S_CT); + } else { + if (re->options & RE_T) + printf(" [%2d] %s\n %-15.15s %16.16jx" + " %16.16jx %u\n %16.16jx %16.16jx" + " %-16u %ju\n %s\n", ST_CTL); + else + printf(" [%2d] %-17.17s %-15.15s %16.16jx" + " %8.8jx\n %16.16jx %16.16jx " + "%3s %2u %3u %ju\n", S_CT); + } + } + if ((re->options & RE_T) == 0) + printf("Key to Flags:\n W (write), A (alloc)," + " X (execute), M (merge), S (strings)\n" + " I (info), L (link order), G (group), x (unknown)\n" + " O (extra OS processing required)" + " o (OS specific), p (processor specific)\n"); + +#undef S_HDR +#undef S_HDRL +#undef ST_HDR +#undef ST_HDRL +#undef S_CT +#undef ST_CT +#undef ST_CTL +} + +/* + * Return number of entries in the given section. We'd prefer ent_count be a + * size_t *, but libelf APIs already use int for section indices. + */ +static int +get_ent_count(struct section *s, int *ent_count) +{ + if (s->entsize == 0) { + warnx("section %s has entry size 0", s->name); + return (0); + } else if (s->sz / s->entsize > INT_MAX) { + warnx("section %s has invalid section count", s->name); + return (0); + } + *ent_count = (int)(s->sz / s->entsize); + return (1); +} + +static void +dump_dynamic(struct readelf *re) +{ + GElf_Dyn dyn; + Elf_Data *d; + struct section *s; + int elferr, i, is_dynamic, j, jmax, nentries; + + is_dynamic = 0; + + for (i = 0; (size_t)i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type != SHT_DYNAMIC) + continue; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + continue; + } + if (d->d_size <= 0) + continue; + + is_dynamic = 1; + + /* Determine the actual number of table entries. */ + nentries = 0; + if (!get_ent_count(s, &jmax)) + continue; + for (j = 0; j < jmax; j++) { + if (gelf_getdyn(d, j, &dyn) != &dyn) { + warnx("gelf_getdyn failed: %s", + elf_errmsg(-1)); + continue; + } + nentries ++; + if (dyn.d_tag == DT_NULL) + break; + } + + printf("\nDynamic section at offset 0x%jx", (uintmax_t)s->off); + printf(" contains %u entries:\n", nentries); + + if (re->ec == ELFCLASS32) + printf("%5s%12s%28s\n", "Tag", "Type", "Name/Value"); + else + printf("%5s%20s%28s\n", "Tag", "Type", "Name/Value"); + + for (j = 0; j < nentries; j++) { + if (gelf_getdyn(d, j, &dyn) != &dyn) + continue; + /* Dump dynamic entry type. */ + if (re->ec == ELFCLASS32) + printf(" 0x%8.8jx", (uintmax_t)dyn.d_tag); + else + printf(" 0x%16.16jx", (uintmax_t)dyn.d_tag); + printf(" %-20s", dt_type(re->ehdr.e_machine, + dyn.d_tag)); + /* Dump dynamic entry value. */ + dump_dyn_val(re, &dyn, s->link); + } + } + + if (!is_dynamic) + printf("\nThere is no dynamic section in this file.\n"); +} + +static char * +timestamp(time_t ti) +{ + static char ts[32]; + struct tm *t; + + t = gmtime(&ti); + snprintf(ts, sizeof(ts), "%04d-%02d-%02dT%02d:%02d:%02d", + (t->tm_year + 1900) % 10000u, (t->tm_mon + 1) % 100u, + t->tm_mday % 100u, t->tm_hour % 100u, t->tm_min % 100u, + t->tm_sec % 100u); + + return (ts); +} + +static const char * +dyn_str(struct readelf *re, uint32_t stab, uint64_t d_val) +{ + const char *name; + + if (stab == SHN_UNDEF) + name = "ERROR"; + else if ((name = elf_strptr(re->elf, stab, d_val)) == NULL) { + (void) elf_errno(); /* clear error */ + name = "ERROR"; + } + + return (name); +} + +static void +dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn) +{ + switch (re->ehdr.e_machine) { + case EM_MIPS: + case EM_MIPS_RS3_LE: + switch (dyn->d_tag) { + case DT_MIPS_RLD_VERSION: + case DT_MIPS_LOCAL_GOTNO: + case DT_MIPS_CONFLICTNO: + case DT_MIPS_LIBLISTNO: + case DT_MIPS_SYMTABNO: + case DT_MIPS_UNREFEXTNO: + case DT_MIPS_GOTSYM: + case DT_MIPS_HIPAGENO: + case DT_MIPS_DELTA_CLASS_NO: + case DT_MIPS_DELTA_INSTANCE_NO: + case DT_MIPS_DELTA_RELOC_NO: + case DT_MIPS_DELTA_SYM_NO: + case DT_MIPS_DELTA_CLASSSYM_NO: + case DT_MIPS_LOCALPAGE_GOTIDX: + case DT_MIPS_LOCAL_GOTIDX: + case DT_MIPS_HIDDEN_GOTIDX: + case DT_MIPS_PROTECTED_GOTIDX: + printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); + break; + case DT_MIPS_ICHECKSUM: + case DT_MIPS_FLAGS: + case DT_MIPS_BASE_ADDRESS: + case DT_MIPS_CONFLICT: + case DT_MIPS_LIBLIST: + case DT_MIPS_RLD_MAP: + case DT_MIPS_DELTA_CLASS: + case DT_MIPS_DELTA_INSTANCE: + case DT_MIPS_DELTA_RELOC: + case DT_MIPS_DELTA_SYM: + case DT_MIPS_DELTA_CLASSSYM: + case DT_MIPS_CXX_FLAGS: + case DT_MIPS_PIXIE_INIT: + case DT_MIPS_SYMBOL_LIB: + case DT_MIPS_OPTIONS: + case DT_MIPS_INTERFACE: + case DT_MIPS_DYNSTR_ALIGN: + case DT_MIPS_INTERFACE_SIZE: + case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: + case DT_MIPS_COMPACT_SIZE: + case DT_MIPS_GP_VALUE: + case DT_MIPS_AUX_DYNAMIC: + case DT_MIPS_PLTGOT: + case DT_MIPS_RLD_OBJ_UPDATE: + case DT_MIPS_RWPLT: + printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); + break; + case DT_MIPS_IVERSION: + case DT_MIPS_PERF_SUFFIX: + case DT_MIPS_TIME_STAMP: + printf(" %s\n", timestamp(dyn->d_un.d_val)); + break; + default: + printf("\n"); + break; + } + break; + default: + printf("\n"); + break; + } +} + +static void +dump_flags(struct flag_desc *desc, uint64_t val) +{ + struct flag_desc *fd; + + for (fd = desc; fd->flag != 0; fd++) { + if (val & fd->flag) { + val &= ~fd->flag; + printf(" %s", fd->desc); + } + } + if (val != 0) + printf(" unknown (0x%jx)", (uintmax_t)val); + printf("\n"); +} + +static struct flag_desc dt_flags[] = { + { DF_ORIGIN, "ORIGIN" }, + { DF_SYMBOLIC, "SYMBOLIC" }, + { DF_TEXTREL, "TEXTREL" }, + { DF_BIND_NOW, "BIND_NOW" }, + { DF_STATIC_TLS, "STATIC_TLS" }, + { 0, NULL } +}; + +static struct flag_desc dt_flags_1[] = { + { DF_1_BIND_NOW, "NOW" }, + { DF_1_GLOBAL, "GLOBAL" }, + { 0x4, "GROUP" }, + { DF_1_NODELETE, "NODELETE" }, + { DF_1_LOADFLTR, "LOADFLTR" }, + { 0x20, "INITFIRST" }, + { DF_1_NOOPEN, "NOOPEN" }, + { DF_1_ORIGIN, "ORIGIN" }, + { 0x100, "DIRECT" }, + { DF_1_INTERPOSE, "INTERPOSE" }, + { DF_1_NODEFLIB, "NODEFLIB" }, + { 0x1000, "NODUMP" }, + { 0x2000, "CONFALT" }, + { 0x4000, "ENDFILTEE" }, + { 0x8000, "DISPRELDNE" }, + { 0x10000, "DISPRELPND" }, + { 0x20000, "NODIRECT" }, + { 0x40000, "IGNMULDEF" }, + { 0x80000, "NOKSYMS" }, + { 0x100000, "NOHDR" }, + { 0x200000, "EDITED" }, + { 0x400000, "NORELOC" }, + { 0x800000, "SYMINTPOSE" }, + { 0x1000000, "GLOBAUDIT" }, + { 0, NULL } +}; + +static void +dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab) +{ + const char *name; + + if (dyn->d_tag >= DT_LOPROC && dyn->d_tag <= DT_HIPROC && + dyn->d_tag != DT_AUXILIARY && dyn->d_tag != DT_FILTER) { + dump_arch_dyn_val(re, dyn); + return; + } + + /* These entry values are index into the string table. */ + name = NULL; + if (dyn->d_tag == DT_AUXILIARY || dyn->d_tag == DT_FILTER || + dyn->d_tag == DT_NEEDED || dyn->d_tag == DT_SONAME || + dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) + name = dyn_str(re, stab, dyn->d_un.d_val); + + switch(dyn->d_tag) { + case DT_NULL: + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_SYMBOLIC: + case DT_REL: + case DT_DEBUG: + case DT_TEXTREL: + case DT_JMPREL: + case DT_FINI: + case DT_VERDEF: + case DT_VERNEED: + case DT_VERSYM: + case DT_GNU_HASH: + case DT_GNU_LIBLIST: + case DT_GNU_CONFLICT: + printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); + break; + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_RELSZ: + case DT_RELENT: + case DT_PREINIT_ARRAYSZ: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_GNU_CONFLICTSZ: + case DT_GNU_LIBLISTSZ: + printf(" %ju (bytes)\n", (uintmax_t) dyn->d_un.d_val); + break; + case DT_RELACOUNT: + case DT_RELCOUNT: + case DT_VERDEFNUM: + case DT_VERNEEDNUM: + printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); + break; + case DT_AUXILIARY: + printf(" Auxiliary library: [%s]\n", name); + break; + case DT_FILTER: + printf(" Filter library: [%s]\n", name); + break; + case DT_NEEDED: + printf(" Shared library: [%s]\n", name); + break; + case DT_SONAME: + printf(" Library soname: [%s]\n", name); + break; + case DT_RPATH: + printf(" Library rpath: [%s]\n", name); + break; + case DT_RUNPATH: + printf(" Library runpath: [%s]\n", name); + break; + case DT_PLTREL: + printf(" %s\n", dt_type(re->ehdr.e_machine, dyn->d_un.d_val)); + break; + case DT_GNU_PRELINKED: + printf(" %s\n", timestamp(dyn->d_un.d_val)); + break; + case DT_FLAGS: + dump_flags(dt_flags, dyn->d_un.d_val); + break; + case DT_FLAGS_1: + dump_flags(dt_flags_1, dyn->d_un.d_val); + break; + default: + printf("\n"); + } +} + +static void +dump_rel(struct readelf *re, struct section *s, Elf_Data *d) +{ + GElf_Rel r; + const char *symname; + uint64_t symval; + int i, len; + uint32_t type; + uint8_t type2, type3; + + if (s->link >= re->shnum) + return; + +#define REL_HDR "r_offset", "r_info", "r_type", "st_value", "st_name" +#define REL_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ + elftc_reloc_type_str(re->ehdr.e_machine, \ + ELF32_R_TYPE(r.r_info)), (uintmax_t)symval, symname +#define REL_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ + elftc_reloc_type_str(re->ehdr.e_machine, type), \ + (uintmax_t)symval, symname + + printf("\nRelocation section (%s):\n", s->name); + if (re->ec == ELFCLASS32) + printf("%-8s %-8s %-19s %-8s %s\n", REL_HDR); + else { + if (re->options & RE_WW) + printf("%-16s %-16s %-24s %-16s %s\n", REL_HDR); + else + printf("%-12s %-12s %-19s %-16s %s\n", REL_HDR); + } + assert(d->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (i = 0; i < len; i++) { + if (gelf_getrel(d, i, &r) != &r) { + warnx("gelf_getrel failed: %s", elf_errmsg(-1)); + continue; + } + symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); + symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); + if (re->ec == ELFCLASS32) { + r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), + ELF64_R_TYPE(r.r_info)); + printf("%8.8jx %8.8jx %-19.19s %8.8jx %s\n", REL_CT32); + } else { + type = ELF64_R_TYPE(r.r_info); + if (re->ehdr.e_machine == EM_MIPS) { + type2 = (type >> 8) & 0xFF; + type3 = (type >> 16) & 0xFF; + type = type & 0xFF; + } else { + type2 = type3 = 0; + } + if (re->options & RE_WW) + printf("%16.16jx %16.16jx %-24.24s" + " %16.16jx %s\n", REL_CT64); + else + printf("%12.12jx %12.12jx %-19.19s" + " %16.16jx %s\n", REL_CT64); + if (re->ehdr.e_machine == EM_MIPS) { + if (re->options & RE_WW) { + printf("%32s: %s\n", "Type2", + elftc_reloc_type_str(EM_MIPS, + type2)); + printf("%32s: %s\n", "Type3", + elftc_reloc_type_str(EM_MIPS, + type3)); + } else { + printf("%24s: %s\n", "Type2", + elftc_reloc_type_str(EM_MIPS, + type2)); + printf("%24s: %s\n", "Type3", + elftc_reloc_type_str(EM_MIPS, + type3)); + } + } + } + } + +#undef REL_HDR +#undef REL_CT +} + +static void +dump_rela(struct readelf *re, struct section *s, Elf_Data *d) +{ + GElf_Rela r; + const char *symname; + uint64_t symval; + int i, len; + uint32_t type; + uint8_t type2, type3; + + if (s->link >= re->shnum) + return; + +#define RELA_HDR "r_offset", "r_info", "r_type", "st_value", \ + "st_name + r_addend" +#define RELA_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ + elftc_reloc_type_str(re->ehdr.e_machine, \ + ELF32_R_TYPE(r.r_info)), (uintmax_t)symval, symname +#define RELA_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ + elftc_reloc_type_str(re->ehdr.e_machine, type), \ + (uintmax_t)symval, symname + + printf("\nRelocation section with addend (%s):\n", s->name); + if (re->ec == ELFCLASS32) + printf("%-8s %-8s %-19s %-8s %s\n", RELA_HDR); + else { + if (re->options & RE_WW) + printf("%-16s %-16s %-24s %-16s %s\n", RELA_HDR); + else + printf("%-12s %-12s %-19s %-16s %s\n", RELA_HDR); + } + assert(d->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; + for (i = 0; i < len; i++) { + if (gelf_getrela(d, i, &r) != &r) { + warnx("gelf_getrel failed: %s", elf_errmsg(-1)); + continue; + } + symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); + symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); + if (re->ec == ELFCLASS32) { + r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), + ELF64_R_TYPE(r.r_info)); + printf("%8.8jx %8.8jx %-19.19s %8.8jx %s", RELA_CT32); + printf(" + %x\n", (uint32_t) r.r_addend); + } else { + type = ELF64_R_TYPE(r.r_info); + if (re->ehdr.e_machine == EM_MIPS) { + type2 = (type >> 8) & 0xFF; + type3 = (type >> 16) & 0xFF; + type = type & 0xFF; + } else { + type2 = type3 = 0; + } + if (re->options & RE_WW) + printf("%16.16jx %16.16jx %-24.24s" + " %16.16jx %s", RELA_CT64); + else + printf("%12.12jx %12.12jx %-19.19s" + " %16.16jx %s", RELA_CT64); + printf(" + %jx\n", (uintmax_t) r.r_addend); + if (re->ehdr.e_machine == EM_MIPS) { + if (re->options & RE_WW) { + printf("%32s: %s\n", "Type2", + elftc_reloc_type_str(EM_MIPS, + type2)); + printf("%32s: %s\n", "Type3", + elftc_reloc_type_str(EM_MIPS, + type3)); + } else { + printf("%24s: %s\n", "Type2", + elftc_reloc_type_str(EM_MIPS, + type2)); + printf("%24s: %s\n", "Type3", + elftc_reloc_type_str(EM_MIPS, + type3)); + } + } + } + } + +#undef RELA_HDR +#undef RELA_CT +} + +static void +dump_reloc(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + int i, elferr; + + for (i = 0; (size_t)i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type == SHT_REL || s->type == SHT_RELA) { + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + if (s->type == SHT_REL) + dump_rel(re, s, d); + else + dump_rela(re, s, d); + } + } +} + +static void +dump_symtab(struct readelf *re, int i) +{ + struct section *s; + Elf_Data *d; + GElf_Sym sym; + const char *name; + uint32_t stab; + int elferr, j, len; + uint16_t vs; + + s = &re->sl[i]; + if (s->link >= re->shnum) + return; + stab = s->link; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + if (d->d_size <= 0) + return; + if (!get_ent_count(s, &len)) + return; + printf("Symbol table (%s)", s->name); + printf(" contains %d entries:\n", len); + printf("%7s%9s%14s%5s%8s%6s%9s%5s\n", "Num:", "Value", "Size", "Type", + "Bind", "Vis", "Ndx", "Name"); + + for (j = 0; j < len; j++) { + if (gelf_getsym(d, j, &sym) != &sym) { + warnx("gelf_getsym failed: %s", elf_errmsg(-1)); + continue; + } + printf("%6d:", j); + printf(" %16.16jx", (uintmax_t) sym.st_value); + printf(" %5ju", (uintmax_t) sym.st_size); + printf(" %-7s", st_type(re->ehdr.e_machine, + re->ehdr.e_ident[EI_OSABI], GELF_ST_TYPE(sym.st_info))); + printf(" %-6s", st_bind(GELF_ST_BIND(sym.st_info))); + printf(" %-8s", st_vis(GELF_ST_VISIBILITY(sym.st_other))); + printf(" %3s", st_shndx(sym.st_shndx)); + if ((name = elf_strptr(re->elf, stab, sym.st_name)) != NULL) + printf(" %s", name); + /* Append symbol version string for SHT_DYNSYM symbol table. */ + if (s->type == SHT_DYNSYM && re->ver != NULL && + re->vs != NULL && re->vs[j] > 1) { + vs = re->vs[j] & VERSYM_VERSION; + if (vs >= re->ver_sz || re->ver[vs].name == NULL) { + warnx("invalid versym version index %u", vs); + break; + } + if (re->vs[j] & VERSYM_HIDDEN || re->ver[vs].type == 0) + printf("@%s (%d)", re->ver[vs].name, vs); + else + printf("@@%s (%d)", re->ver[vs].name, vs); + } + putchar('\n'); + } + +} + +static void +dump_symtabs(struct readelf *re) +{ + GElf_Dyn dyn; + Elf_Data *d; + struct section *s; + uint64_t dyn_off; + int elferr, i, len; + + /* + * If -D is specified, only dump the symbol table specified by + * the DT_SYMTAB entry in the .dynamic section. + */ + dyn_off = 0; + if (re->options & RE_DD) { + s = NULL; + for (i = 0; (size_t)i < re->shnum; i++) + if (re->sl[i].type == SHT_DYNAMIC) { + s = &re->sl[i]; + break; + } + if (s == NULL) + return; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + return; + } + if (d->d_size <= 0) + return; + if (!get_ent_count(s, &len)) + return; + + for (i = 0; i < len; i++) { + if (gelf_getdyn(d, i, &dyn) != &dyn) { + warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); + continue; + } + if (dyn.d_tag == DT_SYMTAB) { + dyn_off = dyn.d_un.d_val; + break; + } + } + } + + /* Find and dump symbol tables. */ + for (i = 0; (size_t)i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type == SHT_SYMTAB || s->type == SHT_DYNSYM) { + if (re->options & RE_DD) { + if (dyn_off == s->addr) { + dump_symtab(re, i); + break; + } + } else + dump_symtab(re, i); + } + } +} + +static void +dump_svr4_hash(struct section *s) +{ + Elf_Data *d; + uint32_t *buf; + uint32_t nbucket, nchain; + uint32_t *bucket, *chain; + uint32_t *bl, *c, maxl, total; + int elferr, i, j; + + /* Read and parse the content of .hash section. */ + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + if (d->d_size < 2 * sizeof(uint32_t)) { + warnx(".hash section too small"); + return; + } + buf = d->d_buf; + nbucket = buf[0]; + nchain = buf[1]; + if (nbucket <= 0 || nchain <= 0) { + warnx("Malformed .hash section"); + return; + } + if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { + warnx("Malformed .hash section"); + return; + } + bucket = &buf[2]; + chain = &buf[2 + nbucket]; + + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint32_t)i < nbucket; i++) + for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) + if (++bl[i] > maxl) + maxl = bl[i]; + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint32_t)i < nbucket; i++) + c[bl[i]]++; + printf("\nHistogram for bucket list length (total of %u buckets):\n", + nbucket); + printf(" Length\tNumber\t\t%% of total\tCoverage\n"); + total = 0; + for (i = 0; (uint32_t)i <= maxl; i++) { + total += c[i] * i; + printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], + c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); + } + free(c); + free(bl); +} + +static void +dump_svr4_hash64(struct readelf *re, struct section *s) +{ + Elf_Data *d, dst; + uint64_t *buf; + uint64_t nbucket, nchain; + uint64_t *bucket, *chain; + uint64_t *bl, *c, maxl, total; + int elferr, i, j; + + /* + * ALPHA uses 64-bit hash entries. Since libelf assumes that + * .hash section contains only 32-bit entry, an explicit + * gelf_xlatetom is needed here. + */ + (void) elf_errno(); + if ((d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + return; + } + d->d_type = ELF_T_XWORD; + memcpy(&dst, d, sizeof(Elf_Data)); + if (gelf_xlatetom(re->elf, &dst, d, + re->ehdr.e_ident[EI_DATA]) != &dst) { + warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); + return; + } + if (dst.d_size < 2 * sizeof(uint64_t)) { + warnx(".hash section too small"); + return; + } + buf = dst.d_buf; + nbucket = buf[0]; + nchain = buf[1]; + if (nbucket <= 0 || nchain <= 0) { + warnx("Malformed .hash section"); + return; + } + if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { + warnx("Malformed .hash section"); + return; + } + bucket = &buf[2]; + chain = &buf[2 + nbucket]; + + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint32_t)i < nbucket; i++) + for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) + if (++bl[i] > maxl) + maxl = bl[i]; + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint64_t)i < nbucket; i++) + c[bl[i]]++; + printf("Histogram for bucket list length (total of %ju buckets):\n", + (uintmax_t)nbucket); + printf(" Length\tNumber\t\t%% of total\tCoverage\n"); + total = 0; + for (i = 0; (uint64_t)i <= maxl; i++) { + total += c[i] * i; + printf("%7u\t%-10ju\t(%5.1f%%)\t%5.1f%%\n", i, (uintmax_t)c[i], + c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); + } + free(c); + free(bl); +} + +static void +dump_gnu_hash(struct readelf *re, struct section *s) +{ + struct section *ds; + Elf_Data *d; + uint32_t *buf; + uint32_t *bucket, *chain; + uint32_t nbucket, nchain, symndx, maskwords; + uint32_t *bl, *c, maxl, total; + int elferr, dynsymcount, i, j; + + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (d->d_size < 4 * sizeof(uint32_t)) { + warnx(".gnu.hash section too small"); + return; + } + buf = d->d_buf; + nbucket = buf[0]; + symndx = buf[1]; + maskwords = buf[2]; + buf += 4; + if (s->link >= re->shnum) + return; + ds = &re->sl[s->link]; + if (!get_ent_count(ds, &dynsymcount)) + return; + if (symndx >= (uint32_t)dynsymcount) { + warnx("Malformed .gnu.hash section (symndx out of range)"); + return; + } + nchain = dynsymcount - symndx; + if (d->d_size != 4 * sizeof(uint32_t) + maskwords * + (re->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + + (nbucket + nchain) * sizeof(uint32_t)) { + warnx("Malformed .gnu.hash section"); + return; + } + bucket = buf + (re->ec == ELFCLASS32 ? maskwords : maskwords * 2); + chain = bucket + nbucket; + + maxl = 0; + if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint32_t)i < nbucket; i++) + for (j = bucket[i]; j > 0 && (uint32_t)j - symndx < nchain; + j++) { + if (++bl[i] > maxl) + maxl = bl[i]; + if (chain[j - symndx] & 1) + break; + } + if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); + for (i = 0; (uint32_t)i < nbucket; i++) + c[bl[i]]++; + printf("Histogram for bucket list length (total of %u buckets):\n", + nbucket); + printf(" Length\tNumber\t\t%% of total\tCoverage\n"); + total = 0; + for (i = 0; (uint32_t)i <= maxl; i++) { + total += c[i] * i; + printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], + c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); + } + free(c); + free(bl); +} + +static void +dump_hash(struct readelf *re) +{ + struct section *s; + int i; + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type == SHT_HASH || s->type == SHT_GNU_HASH) { + if (s->type == SHT_GNU_HASH) + dump_gnu_hash(re, s); + else if (re->ehdr.e_machine == EM_ALPHA && + s->entsize == 8) + dump_svr4_hash64(re, s); + else + dump_svr4_hash(s); + } + } +} + +static void +dump_notes(struct readelf *re) +{ + struct section *s; + const char *rawfile; + GElf_Phdr phdr; + Elf_Data *d; + size_t filesize, phnum; + int i, elferr; + + if (re->ehdr.e_type == ET_CORE) { + /* + * Search program headers in the core file for + * PT_NOTE entry. + */ + if (elf_getphnum(re->elf, &phnum) == 0) { + warnx("elf_getphnum failed: %s", elf_errmsg(-1)); + return; + } + if (phnum == 0) + return; + if ((rawfile = elf_rawfile(re->elf, &filesize)) == NULL) { + warnx("elf_rawfile failed: %s", elf_errmsg(-1)); + return; + } + for (i = 0; (size_t) i < phnum; i++) { + if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { + warnx("gelf_getphdr failed: %s", + elf_errmsg(-1)); + continue; + } + if (phdr.p_type == PT_NOTE) { + if (phdr.p_offset >= filesize || + phdr.p_filesz > filesize - phdr.p_offset) { + warnx("invalid PHDR offset"); + continue; + } + /* + * XXX cross-endian core notes are not + * translated - ticket #583. + */ + dump_notes_content(re, rawfile + phdr.p_offset, + phdr.p_filesz, phdr.p_offset); + } + } + + } else { + /* + * For objects other than core files, Search for + * SHT_NOTE sections. + */ + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type == SHT_NOTE) { + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + dump_notes_content(re, d->d_buf, d->d_size, + s->off); + } + } + } +} + +static struct flag_desc note_feature_ctl_flags[] = { + { 0x1, "ASLR_DISABLE" }, + { 0x2, "PROTMAX_DISABLE" }, + { 0x4, "STKGAP_DISABLE" }, + { 0, NULL } +}; + +static void +dump_notes_data(const char *name, uint32_t type, const char *buf, size_t sz) +{ + size_t i; + const uint32_t *ubuf; + + /* Note data is at least 4-byte aligned. */ + if (((uintptr_t)buf & 3) != 0) { + warnx("bad note data alignment"); + goto unknown; + } + ubuf = (const uint32_t *)(const void *)buf; + + if (strcmp(name, "FreeBSD") == 0) { + switch (type) { + case NT_FREEBSD_ABI_TAG: + if (sz != 4) + goto unknown; + printf(" ABI tag: %u\n", ubuf[0]); + return; + /* NT_FREEBSD_NOINIT_TAG carries no data, treat as unknown. */ + case NT_FREEBSD_ARCH_TAG: + if (sz != 4) + goto unknown; + printf(" Arch tag: %x\n", ubuf[0]); + return; + case NT_FREEBSD_FEATURE_CTL: + if (sz != 4) + goto unknown; + printf(" Features:"); + dump_flags(note_feature_ctl_flags, ubuf[0]); + return; + } + } +unknown: + printf(" description data:"); + for (i = 0; i < sz; i++) + printf(" %02x", (unsigned char)buf[i]); + printf("\n"); +} + +static void +dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off) +{ + Elf_Note *note; + const char *end, *name; + uint32_t namesz, descsz; + + printf("\nNotes at offset %#010jx with length %#010jx:\n", + (uintmax_t) off, (uintmax_t) sz); + printf(" %-13s %-15s %s\n", "Owner", "Data size", "Description"); + end = buf + sz; + while (buf < end) { + if (buf + sizeof(*note) > end) { + warnx("invalid note header"); + return; + } + note = (Elf_Note *)(uintptr_t) buf; + namesz = roundup2(note->n_namesz, 4); + descsz = roundup2(note->n_descsz, 4); + if (namesz < note->n_namesz || descsz < note->n_descsz || + buf + namesz + descsz > end) { + warnx("invalid note header"); + return; + } + buf += sizeof(Elf_Note); + name = buf; + buf += namesz; + /* + * The name field is required to be nul-terminated, and + * n_namesz includes the terminating nul in observed + * implementations (contrary to the ELF-64 spec). A special + * case is needed for cores generated by some older Linux + * versions, which write a note named "CORE" without a nul + * terminator and n_namesz = 4. + */ + if (note->n_namesz == 0) + name = ""; + else if (note->n_namesz == 4 && strncmp(name, "CORE", 4) == 0) + name = "CORE"; + else if (strnlen(name, note->n_namesz) >= note->n_namesz) + name = ""; + printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz); + printf(" %s\n", note_type(name, re->ehdr.e_type, + note->n_type)); + dump_notes_data(name, note->n_type, buf, note->n_descsz); + buf += descsz; + } +} + +/* + * Symbol versioning sections are the same for 32bit and 64bit + * ELF objects. + */ +#define Elf_Verdef Elf32_Verdef +#define Elf_Verdaux Elf32_Verdaux +#define Elf_Verneed Elf32_Verneed +#define Elf_Vernaux Elf32_Vernaux + +#define SAVE_VERSION_NAME(x, n, t) \ + do { \ + while (x >= re->ver_sz) { \ + nv = realloc(re->ver, \ + sizeof(*re->ver) * re->ver_sz * 2); \ + if (nv == NULL) { \ + warn("realloc failed"); \ + free(re->ver); \ + return; \ + } \ + re->ver = nv; \ + for (i = re->ver_sz; i < re->ver_sz * 2; i++) { \ + re->ver[i].name = NULL; \ + re->ver[i].type = 0; \ + } \ + re->ver_sz *= 2; \ + } \ + if (x > 1) { \ + re->ver[x].name = n; \ + re->ver[x].type = t; \ + } \ + } while (0) + + +static void +dump_verdef(struct readelf *re, int dump) +{ + struct section *s; + struct symver *nv; + Elf_Data *d; + Elf_Verdef *vd; + Elf_Verdaux *vda; + uint8_t *buf, *end, *buf2; + const char *name; + int elferr, i, j; + + if ((s = re->vd_s) == NULL) + return; + if (s->link >= re->shnum) + return; + + if (re->ver == NULL) { + re->ver_sz = 16; + if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == + NULL) { + warn("calloc failed"); + return; + } + re->ver[0].name = "*local*"; + re->ver[1].name = "*global*"; + } + + if (dump) + printf("\nVersion definition section (%s):\n", s->name); + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + if (d->d_size == 0) + return; + + buf = d->d_buf; + end = buf + d->d_size; + while (buf + sizeof(Elf_Verdef) <= end) { + vd = (Elf_Verdef *) (uintptr_t) buf; + if (dump) { + printf(" 0x%4.4lx", (unsigned long) + (buf - (uint8_t *)d->d_buf)); + printf(" vd_version: %u vd_flags: %d" + " vd_ndx: %u vd_cnt: %u", vd->vd_version, + vd->vd_flags, vd->vd_ndx, vd->vd_cnt); + } + buf2 = buf + vd->vd_aux; + j = 0; + while (buf2 + sizeof(Elf_Verdaux) <= end && j < vd->vd_cnt) { + vda = (Elf_Verdaux *) (uintptr_t) buf2; + name = get_string(re, s->link, vda->vda_name); + if (j == 0) { + if (dump) + printf(" vda_name: %s\n", name); + SAVE_VERSION_NAME((int)vd->vd_ndx, name, 1); + } else if (dump) + printf(" 0x%4.4lx parent: %s\n", + (unsigned long) (buf2 - + (uint8_t *)d->d_buf), name); + if (vda->vda_next == 0) + break; + buf2 += vda->vda_next; + j++; + } + if (vd->vd_next == 0) + break; + buf += vd->vd_next; + } +} + +static void +dump_verneed(struct readelf *re, int dump) +{ + struct section *s; + struct symver *nv; + Elf_Data *d; + Elf_Verneed *vn; + Elf_Vernaux *vna; + uint8_t *buf, *end, *buf2; + const char *name; + int elferr, i, j; + + if ((s = re->vn_s) == NULL) + return; + if (s->link >= re->shnum) + return; + + if (re->ver == NULL) { + re->ver_sz = 16; + if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == + NULL) { + warn("calloc failed"); + return; + } + re->ver[0].name = "*local*"; + re->ver[1].name = "*global*"; + } + + if (dump) + printf("\nVersion needed section (%s):\n", s->name); + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return; + } + if (d->d_size == 0) + return; + + buf = d->d_buf; + end = buf + d->d_size; + while (buf + sizeof(Elf_Verneed) <= end) { + vn = (Elf_Verneed *) (uintptr_t) buf; + if (dump) { + printf(" 0x%4.4lx", (unsigned long) + (buf - (uint8_t *)d->d_buf)); + printf(" vn_version: %u vn_file: %s vn_cnt: %u\n", + vn->vn_version, + get_string(re, s->link, vn->vn_file), + vn->vn_cnt); + } + buf2 = buf + vn->vn_aux; + j = 0; + while (buf2 + sizeof(Elf_Vernaux) <= end && j < vn->vn_cnt) { + vna = (Elf32_Vernaux *) (uintptr_t) buf2; + if (dump) + printf(" 0x%4.4lx", (unsigned long) + (buf2 - (uint8_t *)d->d_buf)); + name = get_string(re, s->link, vna->vna_name); + if (dump) + printf(" vna_name: %s vna_flags: %u" + " vna_other: %u\n", name, + vna->vna_flags, vna->vna_other); + SAVE_VERSION_NAME((int)vna->vna_other, name, 0); + if (vna->vna_next == 0) + break; + buf2 += vna->vna_next; + j++; + } + if (vn->vn_next == 0) + break; + buf += vn->vn_next; + } +} + +static void +dump_versym(struct readelf *re) +{ + int i; + uint16_t vs; + + if (re->vs_s == NULL || re->ver == NULL || re->vs == NULL) + return; + printf("\nVersion symbol section (%s):\n", re->vs_s->name); + for (i = 0; i < re->vs_sz; i++) { + if ((i & 3) == 0) { + if (i > 0) + putchar('\n'); + printf(" %03x:", i); + } + vs = re->vs[i] & VERSYM_VERSION; + if (vs >= re->ver_sz || re->ver[vs].name == NULL) { + warnx("invalid versym version index %u", re->vs[i]); + break; + } + if (re->vs[i] & VERSYM_HIDDEN) + printf(" %3xh %-12s ", vs, + re->ver[re->vs[i] & VERSYM_VERSION].name); + else + printf(" %3x %-12s ", vs, re->ver[re->vs[i]].name); + } + putchar('\n'); +} + +static void +dump_ver(struct readelf *re) +{ + + if (re->vs_s && re->ver && re->vs) + dump_versym(re); + if (re->vd_s) + dump_verdef(re, 1); + if (re->vn_s) + dump_verneed(re, 1); +} + +static void +search_ver(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + int elferr, i; + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type == SHT_SUNW_versym) + re->vs_s = s; + if (s->type == SHT_SUNW_verneed) + re->vn_s = s; + if (s->type == SHT_SUNW_verdef) + re->vd_s = s; + } + if (re->vd_s) + dump_verdef(re, 0); + if (re->vn_s) + dump_verneed(re, 0); + if (re->vs_s && re->ver != NULL) { + (void) elf_errno(); + if ((d = elf_getdata(re->vs_s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (d->d_size == 0) + return; + re->vs = d->d_buf; + re->vs_sz = d->d_size / sizeof(Elf32_Half); + } +} + +#undef Elf_Verdef +#undef Elf_Verdaux +#undef Elf_Verneed +#undef Elf_Vernaux +#undef SAVE_VERSION_NAME + +/* + * Elf32_Lib and Elf64_Lib are identical. + */ +#define Elf_Lib Elf32_Lib + +static void +dump_liblist(struct readelf *re) +{ + struct section *s; + struct tm *t; + time_t ti; + char tbuf[20]; + Elf_Data *d; + Elf_Lib *lib; + int i, j, k, elferr, first, len; + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type != SHT_GNU_LIBLIST) + continue; + if (s->link >= re->shnum) + continue; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + if (d->d_size <= 0) + continue; + lib = d->d_buf; + if (!get_ent_count(s, &len)) + continue; + printf("\nLibrary list section '%s' ", s->name); + printf("contains %d entries:\n", len); + printf("%12s%24s%18s%10s%6s\n", "Library", "Time Stamp", + "Checksum", "Version", "Flags"); + for (j = 0; (uint64_t) j < s->sz / s->entsize; j++) { + printf("%3d: ", j); + printf("%-20.20s ", + get_string(re, s->link, lib->l_name)); + ti = lib->l_time_stamp; + t = gmtime(&ti); + snprintf(tbuf, sizeof(tbuf), "%04d-%02d-%02dT%02d:%02d" + ":%2d", (t->tm_year + 1900) % 10000u, + (t->tm_mon + 1) % 100u, t->tm_mday % 100u, + t->tm_hour % 100u, t->tm_min % 100u, + t->tm_sec % 100u); + printf("%-19.19s ", tbuf); + printf("0x%08x ", lib->l_checksum); + printf("%-7d %#x", lib->l_version, lib->l_flags); + if (lib->l_flags != 0) { + first = 1; + putchar('('); + for (k = 0; l_flag[k].name != NULL; k++) { + if ((l_flag[k].value & lib->l_flags) == + 0) + continue; + if (!first) + putchar(','); + else + first = 0; + printf("%s", l_flag[k].name); + } + putchar(')'); + } + putchar('\n'); + lib++; + } + } +} + +#undef Elf_Lib + +static void +dump_section_groups(struct readelf *re) +{ + struct section *s; + const char *symname; + Elf_Data *d; + uint32_t *w; + int i, j, elferr; + size_t n; + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type != SHT_GROUP) + continue; + if (s->link >= re->shnum) + continue; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + if (d->d_size <= 0) + continue; + + w = d->d_buf; + + /* We only support COMDAT section. */ + if ((*w++ & GRP_COMDAT) == 0) + return; + + if (s->entsize == 0) + s->entsize = 4; + + symname = get_symbol_name(re, s->link, s->info); + n = s->sz / s->entsize; + if (n-- < 1) + return; + + printf("\nCOMDAT group section [%5d] `%s' [%s] contains %ju" + " sections:\n", i, s->name, symname, (uintmax_t)n); + printf(" %-10.10s %s\n", "[Index]", "Name"); + for (j = 0; (size_t) j < n; j++, w++) { + if (*w >= re->shnum) { + warnx("invalid section index: %u", *w); + continue; + } + printf(" [%5u] %s\n", *w, re->sl[*w].name); + } + } +} + +static uint8_t * +dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe) +{ + uint64_t val; + + /* + * According to ARM EABI: For tags > 32, even numbered tags have + * a ULEB128 param and odd numbered ones have NUL-terminated + * string param. This rule probably also applies for tags <= 32 + * if the object arch is not ARM. + */ + + printf(" Tag_unknown_%ju: ", (uintmax_t) tag); + + if (tag & 1) { + printf("%s\n", (char *) p); + p += strlen((char *) p) + 1; + } else { + val = _decode_uleb128(&p, pe); + printf("%ju\n", (uintmax_t) val); + } + + return (p); +} + +static uint8_t * +dump_compatibility_tag(uint8_t *p, uint8_t *pe) +{ + uint64_t val; + + val = _decode_uleb128(&p, pe); + printf("flag = %ju, vendor = %s\n", (uintmax_t) val, p); + p += strlen((char *) p) + 1; + + return (p); +} + +static void +dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) +{ + uint64_t tag, val; + size_t i; + int found, desc; + + (void) re; + + while (p < pe) { + tag = _decode_uleb128(&p, pe); + found = desc = 0; + for (i = 0; i < sizeof(aeabi_tags) / sizeof(aeabi_tags[0]); + i++) { + if (tag == aeabi_tags[i].tag) { + found = 1; + printf(" %s: ", aeabi_tags[i].s_tag); + if (aeabi_tags[i].get_desc) { + desc = 1; + val = _decode_uleb128(&p, pe); + printf("%s\n", + aeabi_tags[i].get_desc(val)); + } + break; + } + if (tag < aeabi_tags[i].tag) + break; + } + if (!found) { + p = dump_unknown_tag(tag, p, pe); + continue; + } + if (desc) + continue; + + switch (tag) { + case 4: /* Tag_CPU_raw_name */ + case 5: /* Tag_CPU_name */ + case 67: /* Tag_conformance */ + printf("%s\n", (char *) p); + p += strlen((char *) p) + 1; + break; + case 32: /* Tag_compatibility */ + p = dump_compatibility_tag(p, pe); + break; + case 64: /* Tag_nodefaults */ + /* ignored, written as 0. */ + (void) _decode_uleb128(&p, pe); + printf("True\n"); + break; + case 65: /* Tag_also_compatible_with */ + val = _decode_uleb128(&p, pe); + /* Must be Tag_CPU_arch */ + if (val != 6) { + printf("unknown\n"); + break; + } + val = _decode_uleb128(&p, pe); + printf("%s\n", aeabi_cpu_arch(val)); + /* Skip NUL terminator. */ + p++; + break; + default: + putchar('\n'); + break; + } + } +} + +#ifndef Tag_GNU_MIPS_ABI_FP +#define Tag_GNU_MIPS_ABI_FP 4 +#endif + +static void +dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) +{ + uint64_t tag, val; + + (void) re; + + while (p < pe) { + tag = _decode_uleb128(&p, pe); + switch (tag) { + case Tag_GNU_MIPS_ABI_FP: + val = _decode_uleb128(&p, pe); + printf(" Tag_GNU_MIPS_ABI_FP: %s\n", mips_abi_fp(val)); + break; + case 32: /* Tag_compatibility */ + p = dump_compatibility_tag(p, pe); + break; + default: + p = dump_unknown_tag(tag, p, pe); + break; + } + } +} + +#ifndef Tag_GNU_Power_ABI_FP +#define Tag_GNU_Power_ABI_FP 4 +#endif + +#ifndef Tag_GNU_Power_ABI_Vector +#define Tag_GNU_Power_ABI_Vector 8 +#endif + +static void +dump_ppc_attributes(uint8_t *p, uint8_t *pe) +{ + uint64_t tag, val; + + while (p < pe) { + tag = _decode_uleb128(&p, pe); + switch (tag) { + case Tag_GNU_Power_ABI_FP: + val = _decode_uleb128(&p, pe); + printf(" Tag_GNU_Power_ABI_FP: %s\n", ppc_abi_fp(val)); + break; + case Tag_GNU_Power_ABI_Vector: + val = _decode_uleb128(&p, pe); + printf(" Tag_GNU_Power_ABI_Vector: %s\n", + ppc_abi_vector(val)); + break; + case 32: /* Tag_compatibility */ + p = dump_compatibility_tag(p, pe); + break; + default: + p = dump_unknown_tag(tag, p, pe); + break; + } + } +} + +static void +dump_attributes(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + uint8_t *p, *pe, *sp; + size_t len, seclen, nlen, sublen; + uint64_t val; + int tag, i, elferr; + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->type != SHT_GNU_ATTRIBUTES && + (re->ehdr.e_machine != EM_ARM || s->type != SHT_LOPROC + 3)) + continue; + (void) elf_errno(); + if ((d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + continue; + } + if (d->d_size <= 0) + continue; + p = d->d_buf; + pe = p + d->d_size; + if (*p != 'A') { + printf("Unknown Attribute Section Format: %c\n", + (char) *p); + continue; + } + len = d->d_size - 1; + p++; + while (len > 0) { + if (len < 4) { + warnx("truncated attribute section length"); + return; + } + seclen = re->dw_decode(&p, 4); + if (seclen > len) { + warnx("invalid attribute section length"); + return; + } + len -= seclen; + nlen = strlen((char *) p) + 1; + if (nlen + 4 > seclen) { + warnx("invalid attribute section name"); + return; + } + printf("Attribute Section: %s\n", (char *) p); + p += nlen; + seclen -= nlen + 4; + while (seclen > 0) { + sp = p; + tag = *p++; + sublen = re->dw_decode(&p, 4); + if (sublen > seclen) { + warnx("invalid attribute sub-section" + " length"); + return; + } + seclen -= sublen; + printf("%s", top_tag(tag)); + if (tag == 2 || tag == 3) { + putchar(':'); + for (;;) { + val = _decode_uleb128(&p, pe); + if (val == 0) + break; + printf(" %ju", (uintmax_t) val); + } + } + putchar('\n'); + if (re->ehdr.e_machine == EM_ARM && + s->type == SHT_LOPROC + 3) + dump_arm_attributes(re, p, sp + sublen); + else if (re->ehdr.e_machine == EM_MIPS || + re->ehdr.e_machine == EM_MIPS_RS3_LE) + dump_mips_attributes(re, p, + sp + sublen); + else if (re->ehdr.e_machine == EM_PPC) + dump_ppc_attributes(p, sp + sublen); + p = sp + sublen; + } + } + } +} + +static void +dump_mips_specific_info(struct readelf *re) +{ + struct section *s; + int i; + + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && (!strcmp(s->name, ".MIPS.options") || + (s->type == SHT_MIPS_OPTIONS))) { + dump_mips_options(re, s); + } + } + + if (s->name != NULL && (!strcmp(s->name, ".MIPS.abiflags") || + (s->type == SHT_MIPS_ABIFLAGS))) + dump_mips_abiflags(re, s); + + /* + * Dump .reginfo if present (although it will be ignored by an OS if a + * .MIPS.options section is present, according to SGI mips64 spec). + */ + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && (!strcmp(s->name, ".reginfo") || + (s->type == SHT_MIPS_REGINFO))) + dump_mips_reginfo(re, s); + } +} + +static void +dump_mips_abiflags(struct readelf *re, struct section *s) +{ + Elf_Data *d; + uint8_t *p; + int elferr; + uint32_t isa_ext, ases, flags1, flags2; + uint16_t version; + uint8_t isa_level, isa_rev, gpr_size, cpr1_size, cpr2_size, fp_abi; + + if ((d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (d->d_size != 24) { + warnx("invalid MIPS abiflags section size"); + return; + } + + p = d->d_buf; + version = re->dw_decode(&p, 2); + printf("MIPS ABI Flags Version: %u", version); + if (version != 0) { + printf(" (unknown)\n\n"); + return; + } + printf("\n\n"); + + isa_level = re->dw_decode(&p, 1); + isa_rev = re->dw_decode(&p, 1); + gpr_size = re->dw_decode(&p, 1); + cpr1_size = re->dw_decode(&p, 1); + cpr2_size = re->dw_decode(&p, 1); + fp_abi = re->dw_decode(&p, 1); + isa_ext = re->dw_decode(&p, 4); + ases = re->dw_decode(&p, 4); + flags1 = re->dw_decode(&p, 4); + flags2 = re->dw_decode(&p, 4); + + printf("ISA: "); + if (isa_rev <= 1) + printf("MIPS%u\n", isa_level); + else + printf("MIPS%ur%u\n", isa_level, isa_rev); + printf("GPR size: %d\n", get_mips_register_size(gpr_size)); + printf("CPR1 size: %d\n", get_mips_register_size(cpr1_size)); + printf("CPR2 size: %d\n", get_mips_register_size(cpr2_size)); + printf("FP ABI: "); + switch (fp_abi) { + case 3: + printf("Soft float"); + break; + default: + printf("%u", fp_abi); + break; + } + printf("\nISA Extension: %u\n", isa_ext); + printf("ASEs: %u\n", ases); + printf("FLAGS 1: %08x\n", flags1); + printf("FLAGS 2: %08x\n", flags2); +} + +static int +get_mips_register_size(uint8_t flag) +{ + switch (flag) { + case 0: return 0; + case 1: return 32; + case 2: return 64; + case 3: return 128; + default: return -1; + } +} +static void +dump_mips_reginfo(struct readelf *re, struct section *s) +{ + Elf_Data *d; + int elferr, len; + + (void) elf_errno(); + if ((d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (d->d_size <= 0) + return; + if (!get_ent_count(s, &len)) + return; + + printf("\nSection '%s' contains %d entries:\n", s->name, len); + dump_mips_odk_reginfo(re, d->d_buf, d->d_size); +} + +static void +dump_mips_options(struct readelf *re, struct section *s) +{ + Elf_Data *d; + uint32_t info; + uint16_t sndx; + uint8_t *p, *pe; + uint8_t kind, size; + int elferr; + + (void) elf_errno(); + if ((d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_rawdata failed: %s", + elf_errmsg(elferr)); + return; + } + if (d->d_size == 0) + return; + + printf("\nSection %s contains:\n", s->name); + p = d->d_buf; + pe = p + d->d_size; + while (p < pe) { + if (pe - p < 8) { + warnx("Truncated MIPS option header"); + return; + } + kind = re->dw_decode(&p, 1); + size = re->dw_decode(&p, 1); + sndx = re->dw_decode(&p, 2); + info = re->dw_decode(&p, 4); + if (size < 8 || size - 8 > pe - p) { + warnx("Malformed MIPS option header"); + return; + } + size -= 8; + switch (kind) { + case ODK_REGINFO: + dump_mips_odk_reginfo(re, p, size); + break; + case ODK_EXCEPTIONS: + printf(" EXCEPTIONS FPU_MIN: %#lx\n", + info & OEX_FPU_MIN); + printf("%11.11s FPU_MAX: %#lx\n", "", + info & OEX_FPU_MAX); + dump_mips_option_flags("", mips_exceptions_option, + info); + break; + case ODK_PAD: + printf(" %-10.10s section: %ju\n", "OPAD", + (uintmax_t) sndx); + dump_mips_option_flags("", mips_pad_option, info); + break; + case ODK_HWPATCH: + dump_mips_option_flags("HWPATCH", mips_hwpatch_option, + info); + break; + case ODK_HWAND: + dump_mips_option_flags("HWAND", mips_hwa_option, info); + break; + case ODK_HWOR: + dump_mips_option_flags("HWOR", mips_hwo_option, info); + break; + case ODK_FILL: + printf(" %-10.10s %#jx\n", "FILL", (uintmax_t) info); + break; + case ODK_TAGS: + printf(" %-10.10s\n", "TAGS"); + break; + case ODK_GP_GROUP: + printf(" %-10.10s GP group number: %#x\n", "GP_GROUP", + info & 0xFFFF); + if (info & 0x10000) + printf(" %-10.10s GP group is " + "self-contained\n", ""); + break; + case ODK_IDENT: + printf(" %-10.10s default GP group number: %#x\n", + "IDENT", info & 0xFFFF); + if (info & 0x10000) + printf(" %-10.10s default GP group is " + "self-contained\n", ""); + break; + case ODK_PAGESIZE: + printf(" %-10.10s\n", "PAGESIZE"); + break; + default: + break; + } + p += size; + } +} + +static void +dump_mips_option_flags(const char *name, struct mips_option *opt, uint64_t info) +{ + int first; + + first = 1; + for (; opt->desc != NULL; opt++) { + if (info & opt->flag) { + printf(" %-10.10s %s\n", first ? name : "", + opt->desc); + first = 0; + } + } +} + +static void +dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz) +{ + uint32_t ri_gprmask; + uint32_t ri_cprmask[4]; + uint64_t ri_gp_value; + uint8_t *pe; + int i; + + pe = p + sz; + while (p < pe) { + ri_gprmask = re->dw_decode(&p, 4); + /* Skip ri_pad padding field for mips64. */ + if (re->ec == ELFCLASS64) + re->dw_decode(&p, 4); + for (i = 0; i < 4; i++) + ri_cprmask[i] = re->dw_decode(&p, 4); + if (re->ec == ELFCLASS32) + ri_gp_value = re->dw_decode(&p, 4); + else + ri_gp_value = re->dw_decode(&p, 8); + printf(" %s ", option_kind(ODK_REGINFO)); + printf("ri_gprmask: 0x%08jx\n", (uintmax_t) ri_gprmask); + for (i = 0; i < 4; i++) + printf("%11.11s ri_cprmask[%d]: 0x%08jx\n", "", i, + (uintmax_t) ri_cprmask[i]); + printf("%12.12s", ""); + printf("ri_gp_value: %#jx\n", (uintmax_t) ri_gp_value); + } +} + +static void +dump_arch_specific_info(struct readelf *re) +{ + + dump_liblist(re); + dump_attributes(re); + + switch (re->ehdr.e_machine) { + case EM_MIPS: + case EM_MIPS_RS3_LE: + dump_mips_specific_info(re); + default: + break; + } +} + +static const char * +dwarf_regname(struct readelf *re, unsigned int num) +{ + static char rx[REGISTER_NAME_BUFFER_SIZE]; + const char *rn; + + if ((rn = dwarf_reg(re->ehdr.e_machine, num)) != NULL) + return (rn); + + snprintf(rx, sizeof(rx), "r%u", num); + + return (rx); +} + +static const char * +get_lnct_path(struct readelf *re, unsigned form, uint8_t **p, const char *st, + const char *ls, int dwarf_size) +{ + const char *s = NULL; + Dwarf_Unsigned sp; + + switch (form) { + case DW_FORM_string: + s = (char *) *p; + *p += strlen((char *) *p) + 1; + break; + case DW_FORM_strp: + sp = re->dw_decode(p, dwarf_size); + if (st == NULL) { + warnx(".debug_str not present"); + break; + } + s = st + sp; + break; + case DW_FORM_line_strp: + sp = re->dw_decode(p, dwarf_size); + if (ls == NULL) { + warnx(".debug_line_str not present"); + break; + } + s = ls + sp; + break; + case DW_FORM_strp_sup: + sp = re->dw_decode(p, dwarf_size); + warnx("DW_FORM_strp_sup not supported"); + break; + default: + warnx("Unrecgonized Form: %u", form); + break; + } + + return (s); +} + +static Dwarf_Unsigned +get_lnct_dirndx(struct readelf *re, unsigned form, uint8_t **p, uint8_t *pe) +{ + + switch (form) { + case DW_FORM_data1: + return (re->dw_decode(p, 1)); + case DW_FORM_data2: + return (re->dw_decode(p, 2)); + case DW_FORM_udata: + return (_decode_uleb128(p, pe)); + default: + warnx("Unrecgonized Form: %u", form); + return (0); + } +} + +static void +dump_dwarf_line_cu(struct readelf *re, Elf_Data *d, Elf_Data *ds, Elf_Data *dl, + Dwarf_Unsigned offset, Dwarf_Unsigned length, int dwarf_size) +{ + struct lnct lnct[10]; + Dwarf_Unsigned endoff, hdrlen, dirndx, mtime, fsize; + Dwarf_Half version, pointer_size; + Dwarf_Small minlen, maxop, defstmt, lrange, opbase, oplen; + Dwarf_Error de; + uint64_t address, file, line, column, isa, opsize, udelta; + int64_t sdelta; + uint8_t *p, *pp, *pe; + char *pn, *st, *ls; + const char *path; + int8_t lbase; + int i, j, is_stmt, fmt_cnt, dir_cnt, file_cnt; + + st = ds ? (char *) ds->d_buf : NULL; + ls = dl ? (char *) dl->d_buf : NULL; + endoff = offset + length; + pe = (uint8_t *) d->d_buf + endoff; + version = re->dw_read(d, &offset, 2); + if (version == 5) { + pointer_size = re->dw_read(d, &offset, 1); + (void) re->dw_read(d, &offset, 1); + } else { + (void) dwarf_get_address_size(re->dbg, &pointer_size, &de); + } + hdrlen = re->dw_read(d, &offset, dwarf_size); + minlen = re->dw_read(d, &offset, 1); + if (version >= 4) + maxop = re->dw_read(d, &offset, 1); + defstmt = re->dw_read(d, &offset, 1); + lbase = re->dw_read(d, &offset, 1); + lrange = re->dw_read(d, &offset, 1); + opbase = re->dw_read(d, &offset, 1); + + printf("\n"); + printf(" Length:\t\t\t%ju\n", (uintmax_t) length); + printf(" DWARF version:\t\t%u\n", version); + printf(" Prologue Length:\t\t%ju\n", (uintmax_t) hdrlen); + printf(" Minimum Instruction Length:\t%u\n", minlen); + if (version >= 4) + printf(" Maximum Ops per Instruction:\t%u\n", maxop); + printf(" Initial value of 'is_stmt':\t%u\n", defstmt); + printf(" Line Base:\t\t\t%d\n", lbase); + printf(" Line Range:\t\t\t%u\n", lrange); + printf(" Opcode Base:\t\t\t%u\n", opbase); + printf(" (Pointer size:\t\t%u)\n", pointer_size); + + printf("\n"); + printf(" Opcodes:\n"); + for (i = 1; i < opbase; i++) { + oplen = re->dw_read(d, &offset, 1); + printf(" Opcode %d has %u %s\n", i, oplen, + oplen == 1 ? "arg" : "args"); + } + + if (version == 5) { + /* DWARF5. */ + fmt_cnt = re->dw_read(d, &offset, 1); + if (fmt_cnt != 1) { + warnx("Too many content descriptors for dir"); + return; + } + pp = p = (uint8_t *) d->d_buf + offset; + lnct[0].type = _decode_uleb128(&p, pe); + if (lnct[0].type != DW_LNCT_path) { + warnx("Invalid content descriptors for dir"); + return; + } + lnct[0].form = _decode_uleb128(&p, pe); + dir_cnt = _decode_uleb128(&p, pe); + offset += p - pp; + pp = p; + printf("\n"); + printf(" The Directory Table (offset %#jx):\n", + (uintmax_t) offset); + for (i = 0; i < dir_cnt; i++) { + path = get_lnct_path(re, lnct[0].form, &p, st, ls, + dwarf_size); + printf(" %d\t%s\n", i, path); + } + + } else { + /* DWARF4 or below. */ + printf("\n"); + printf(" The Directory Table (offset %#jx):\n", + (uintmax_t) offset); + pp = p = (uint8_t *) d->d_buf + offset; + i = 0; + while (*p != '\0') { + i++; + printf(" %d\t%s\n", i, (char *) p); + p += strlen((char *) p) + 1; + } + p++; + } + + offset += p - pp; + pp = p; + + if (version == 5) { + /* DWARF5. */ + fmt_cnt = re->dw_read(d, &offset, 1); + pp = p = (uint8_t *) d->d_buf + offset; + for (i = 0; i < fmt_cnt; i++) { + lnct[i].type = _decode_uleb128(&p, pe); + lnct[i].form = _decode_uleb128(&p, pe); + } + file_cnt = _decode_uleb128(&p, pe); + offset += p - pp; + pp = p; + printf("\n"); + printf(" The File Name Table (offset %#jx):\n", + (uintmax_t) offset); + printf(" Entry\tDir\tName\n"); + for (i = 0; i < file_cnt; i++) { + for (j = 0; j < fmt_cnt; j++) { + switch (lnct[j].type) { + case DW_LNCT_path: + path = get_lnct_path(re, lnct[j].form, + &p, st, ls, dwarf_size); + break; + case DW_LNCT_directory_index: + dirndx = get_lnct_dirndx(re, + lnct[j].form, &p, pe); + break; + default: + warnx("Unhandled type: %u", + lnct[j].type); + break; + } + } + printf(" %d\t%ju\t%s\n", i, (uintmax_t) dirndx, path); + } + } else { + /* DWARF4 or below. */ + printf("\n"); + printf(" The File Name Table (offset %#jx):\n", + (uintmax_t) offset); + printf(" Entry\tDir\tTime\tSize\tName\n"); + i = 0; + while (*p != '\0') { + i++; + pn = (char *) p; + p += strlen(pn) + 1; + dirndx = _decode_uleb128(&p, pe); + mtime = _decode_uleb128(&p, pe); + fsize = _decode_uleb128(&p, pe); + printf(" %d\t%ju\t%ju\t%ju\t%s\n", i, + (uintmax_t) dirndx, (uintmax_t) mtime, + (uintmax_t) fsize, pn); + } + p++; + } + +#define RESET_REGISTERS \ + do { \ + address = 0; \ + file = 1; \ + line = 1; \ + column = 0; \ + is_stmt = defstmt; \ + } while(0) + +#define LINE(x) (lbase + (((x) - opbase) % lrange)) +#define ADDRESS(x) ((((x) - opbase) / lrange) * minlen) + + printf("\n"); + printf(" Line Number Statements:\n"); + + RESET_REGISTERS; + + while (p < pe) { + + offset += p - pp; + pp = p; + printf(" [0x%08jx]" , (uintmax_t) offset); + + if (*p == 0) { + /* + * Extended Opcodes. + */ + p++; + opsize = _decode_uleb128(&p, pe); + printf(" Extended opcode %u: ", *p); + switch (*p) { + case DW_LNE_end_sequence: + p++; + RESET_REGISTERS; + printf("End of Sequence\n"); + break; + case DW_LNE_set_address: + p++; + address = re->dw_decode(&p, + pointer_size); + printf("set Address to %#jx\n", + (uintmax_t) address); + break; + case DW_LNE_define_file: + p++; + pn = (char *) p; + p += strlen(pn) + 1; + dirndx = _decode_uleb128(&p, pe); + mtime = _decode_uleb128(&p, pe); + fsize = _decode_uleb128(&p, pe); + printf("define new file: %s\n", pn); + break; + default: + /* Unrecognized extened opcodes. */ + p += opsize; + printf("unknown opcode\n"); + } + } else if (*p > 0 && *p < opbase) { + /* + * Standard Opcodes. + */ + switch(*p++) { + case DW_LNS_copy: + printf(" Copy\n"); + break; + case DW_LNS_advance_pc: + udelta = _decode_uleb128(&p, pe) * + minlen; + address += udelta; + printf(" Advance PC by %ju to %#jx\n", + (uintmax_t) udelta, + (uintmax_t) address); + break; + case DW_LNS_advance_line: + sdelta = _decode_sleb128(&p, pe); + line += sdelta; + printf(" Advance Line by %jd to %ju\n", + (intmax_t) sdelta, + (uintmax_t) line); + break; + case DW_LNS_set_file: + file = _decode_uleb128(&p, pe); + printf(" Set File to %ju\n", + (uintmax_t) file); + break; + case DW_LNS_set_column: + column = _decode_uleb128(&p, pe); + printf(" Set Column to %ju\n", + (uintmax_t) column); + break; + case DW_LNS_negate_stmt: + is_stmt = !is_stmt; + printf(" Set is_stmt to %d\n", is_stmt); + break; + case DW_LNS_set_basic_block: + printf(" Set basic block flag\n"); + break; + case DW_LNS_const_add_pc: + address += ADDRESS(255); + printf(" Advance PC by constant %ju" + " to %#jx\n", + (uintmax_t) ADDRESS(255), + (uintmax_t) address); + break; + case DW_LNS_fixed_advance_pc: + udelta = re->dw_decode(&p, 2); + address += udelta; + printf(" Advance PC by fixed value " + "%ju to %#jx\n", + (uintmax_t) udelta, + (uintmax_t) address); + break; + case DW_LNS_set_prologue_end: + printf(" Set prologue end flag\n"); + break; + case DW_LNS_set_epilogue_begin: + printf(" Set epilogue begin flag\n"); + break; + case DW_LNS_set_isa: + isa = _decode_uleb128(&p, pe); + printf(" Set isa to %ju\n", + (uintmax_t) isa); + break; + default: + /* Unrecognized extended opcodes. */ + printf(" Unknown extended opcode %u\n", + *(p - 1)); + break; + } + + } else { + /* + * Special Opcodes. + */ + line += LINE(*p); + address += ADDRESS(*p); + printf(" Special opcode %u: advance Address " + "by %ju to %#jx and Line by %jd to %ju\n", + *p - opbase, (uintmax_t) ADDRESS(*p), + (uintmax_t) address, (intmax_t) LINE(*p), + (uintmax_t) line); + p++; + } + + + } + +} + +static void +dump_dwarf_line(struct readelf *re) +{ + struct section *s; + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Half tag; + Dwarf_Unsigned offset, length; + Elf_Data *d, *ds, *dl; + int elferr, ret, i, dwarf_size; + + printf("\nDump of debug contents of section .debug_line:\n"); + + d = ds = dl = NULL; + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name == NULL) + continue; + if (!strcmp(s->name, ".debug_line")) { + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata .debug_line " + "failed: %s", elf_errmsg(-1)); + return; + } + if (d->d_size <= 0) + return; + } else if (!strcmp(s->name, ".debug_str")) { + (void) elf_errno(); + if ((ds = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata .debug_str " + "failed: %s", elf_errmsg(-1)); + return; + } + if (ds->d_size <= 0) + ds = NULL; + } else if (!strcmp(s->name, ".debug_line_str")) { + (void) elf_errno(); + if ((dl = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata .debug_str_line " + "failed: %s", elf_errmsg(-1)); + return; + } + if (dl->d_size <= 0) + dl = NULL; + } + } + + if (d == NULL) + return; + + while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, + NULL, &de)) == DW_DLV_OK) { + die = NULL; + while (dwarf_siblingof(re->dbg, die, &die, &de) == DW_DLV_OK) { + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + return; + } + /* XXX: What about DW_TAG_partial_unit? */ + if (tag == DW_TAG_compile_unit) + break; + } + if (die == NULL) { + warnx("could not find DW_TAG_compile_unit die"); + return; + } + if (dwarf_attrval_unsigned(die, DW_AT_stmt_list, &offset, + &de) != DW_DLV_OK) + continue; + + length = re->dw_read(d, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = re->dw_read(d, &offset, 8); + } else + dwarf_size = 4; + + if (length > d->d_size - offset) { + warnx("invalid .dwarf_line section"); + continue; + } + + dump_dwarf_line_cu(re, d, ds, dl, offset, length, dwarf_size); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + +#undef RESET_REGISTERS +#undef LINE +#undef ADDRESS +} + +static void +dump_dwarf_line_decoded(struct readelf *re) +{ + Dwarf_Die die; + Dwarf_Line *linebuf, ln; + Dwarf_Addr lineaddr; + Dwarf_Signed linecount, srccount; + Dwarf_Unsigned lineno, fn; + Dwarf_Error de; + const char *dir, *file; + char **srcfiles; + int i, ret; + + printf("Decoded dump of debug contents of section .debug_line:\n\n"); + while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, + NULL, &de)) == DW_DLV_OK) { + if (dwarf_siblingof(re->dbg, NULL, &die, &de) != DW_DLV_OK) + continue; + if (dwarf_attrval_string(die, DW_AT_name, &file, &de) != + DW_DLV_OK) + file = NULL; + if (dwarf_attrval_string(die, DW_AT_comp_dir, &dir, &de) != + DW_DLV_OK) + dir = NULL; + printf("CU: "); + if (dir && file && file[0] != '/') + printf("%s/", dir); + if (file) + printf("%s", file); + putchar('\n'); + printf("%-37s %11s %s\n", "Filename", "Line Number", + "Starting Address"); + if (dwarf_srclines(die, &linebuf, &linecount, &de) != DW_DLV_OK) + continue; + if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK) + continue; + for (i = 0; i < linecount; i++) { + ln = linebuf[i]; + if (dwarf_line_srcfileno(ln, &fn, &de) != DW_DLV_OK) + continue; + if (dwarf_lineno(ln, &lineno, &de) != DW_DLV_OK) + continue; + if (dwarf_lineaddr(ln, &lineaddr, &de) != DW_DLV_OK) + continue; + printf("%-37s %11ju %#18jx\n", + basename(srcfiles[fn - 1]), (uintmax_t) lineno, + (uintmax_t) lineaddr); + } + putchar('\n'); + } +} + +static void +dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) +{ + Dwarf_Attribute *attr_list; + Dwarf_Die ret_die; + Dwarf_Off dieoff, cuoff, culen, attroff; + Dwarf_Unsigned ate, lang, v_udata, v_sig; + Dwarf_Signed attr_count, v_sdata; + Dwarf_Off v_off; + Dwarf_Addr v_addr; + Dwarf_Half tag, attr, form; + Dwarf_Block *v_block; + Dwarf_Bool v_bool, is_info; + Dwarf_Sig8 v_sig8; + Dwarf_Error de; + Dwarf_Ptr v_expr; + const char *tag_str, *attr_str, *ate_str, *lang_str; + char unk_tag[32], unk_attr[32]; + char *v_str; + uint8_t *b, *p; + int i, j, abc, ret; + + if (dwarf_dieoffset(die, &dieoff, &de) != DW_DLV_OK) { + warnx("dwarf_dieoffset failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + + printf(" <%d><%jx>: ", level, (uintmax_t) dieoff); + + if (dwarf_die_CU_offset_range(die, &cuoff, &culen, &de) != DW_DLV_OK) { + warnx("dwarf_die_CU_offset_range failed: %s", + dwarf_errmsg(de)); + cuoff = 0; + } + + abc = dwarf_die_abbrev_code(die); + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { + snprintf(unk_tag, sizeof(unk_tag), "[Unknown Tag: %#x]", tag); + tag_str = unk_tag; + } + + printf("Abbrev Number: %d (%s)\n", abc, tag_str); + + if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != + DW_DLV_OK) { + if (ret == DW_DLV_ERROR) + warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + + for (i = 0; i < attr_count; i++) { + if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { + warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { + warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { + snprintf(unk_attr, sizeof(unk_attr), + "[Unknown AT: %#x]", attr); + attr_str = unk_attr; + } + if (dwarf_attroffset(attr_list[i], &attroff, &de) != + DW_DLV_OK) { + warnx("dwarf_attroffset failed: %s", dwarf_errmsg(de)); + attroff = 0; + } + printf(" <%jx> %-18s: ", (uintmax_t) attroff, attr_str); + switch (form) { + case DW_FORM_ref_addr: + case DW_FORM_sec_offset: + if (dwarf_global_formref(attr_list[i], &v_off, &de) != + DW_DLV_OK) { + warnx("dwarf_global_formref failed: %s", + dwarf_errmsg(de)); + continue; + } + if (form == DW_FORM_ref_addr) + printf("<0x%jx>", (uintmax_t) v_off); + else + printf("0x%jx", (uintmax_t) v_off); + break; + + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + if (dwarf_formref(attr_list[i], &v_off, &de) != + DW_DLV_OK) { + warnx("dwarf_formref failed: %s", + dwarf_errmsg(de)); + continue; + } + v_off += cuoff; + printf("<0x%jx>", (uintmax_t) v_off); + break; + + case DW_FORM_addr: + if (dwarf_formaddr(attr_list[i], &v_addr, &de) != + DW_DLV_OK) { + warnx("dwarf_formaddr failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%#jx", (uintmax_t) v_addr); + break; + + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + if (dwarf_formudata(attr_list[i], &v_udata, &de) != + DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + if (attr == DW_AT_high_pc) + printf("0x%jx", (uintmax_t) v_udata); + else + printf("%ju", (uintmax_t) v_udata); + break; + + case DW_FORM_sdata: + if (dwarf_formsdata(attr_list[i], &v_sdata, &de) != + DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%jd", (intmax_t) v_sdata); + break; + + case DW_FORM_flag: + if (dwarf_formflag(attr_list[i], &v_bool, &de) != + DW_DLV_OK) { + warnx("dwarf_formflag failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%jd", (intmax_t) v_bool); + break; + + case DW_FORM_flag_present: + putchar('1'); + break; + + case DW_FORM_string: + case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + if (dwarf_formstring(attr_list[i], &v_str, &de) != + DW_DLV_OK) { + warnx("dwarf_formstring failed: %s", + dwarf_errmsg(de)); + continue; + } + if (form == DW_FORM_string) + printf("%s", v_str); + else if (form == DW_FORM_strp) + printf("(indirect string) %s", v_str); + else if (form == DW_FORM_line_strp) + printf("(indirect line string) %s", v_str); + else if (form == DW_FORM_strx || + form == DW_FORM_strx1 || form == DW_FORM_strx2 || + form == DW_FORM_strx3 || form == DW_FORM_strx4) + printf("(indexed string) %s", v_str); + break; + + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (dwarf_formblock(attr_list[i], &v_block, &de) != + DW_DLV_OK) { + warnx("dwarf_formblock failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%ju byte block:", (uintmax_t) v_block->bl_len); + b = v_block->bl_data; + for (j = 0; (Dwarf_Unsigned) j < v_block->bl_len; j++) + printf(" %x", b[j]); + printf("\t("); + dump_dwarf_block(re, v_block->bl_data, v_block->bl_len); + putchar(')'); + break; + + case DW_FORM_exprloc: + if (dwarf_formexprloc(attr_list[i], &v_udata, &v_expr, + &de) != DW_DLV_OK) { + warnx("dwarf_formexprloc failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%ju byte block:", (uintmax_t) v_udata); + b = v_expr; + for (j = 0; (Dwarf_Unsigned) j < v_udata; j++) + printf(" %x", b[j]); + printf("\t("); + dump_dwarf_block(re, v_expr, v_udata); + putchar(')'); + break; + + case DW_FORM_ref_sig8: + if (dwarf_formsig8(attr_list[i], &v_sig8, &de) != + DW_DLV_OK) { + warnx("dwarf_formsig8 failed: %s", + dwarf_errmsg(de)); + continue; + } + p = (uint8_t *)(uintptr_t) &v_sig8.signature[0]; + v_sig = re->dw_decode(&p, 8); + printf("signature: 0x%jx", (uintmax_t) v_sig); + } + switch (attr) { + case DW_AT_encoding: + if (dwarf_attrval_unsigned(die, attr, &ate, &de) != + DW_DLV_OK) + break; + if (dwarf_get_ATE_name(ate, &ate_str) != DW_DLV_OK) + ate_str = "DW_ATE_UNKNOWN"; + printf("\t(%s)", &ate_str[strlen("DW_ATE_")]); + break; + + case DW_AT_language: + if (dwarf_attrval_unsigned(die, attr, &lang, &de) != + DW_DLV_OK) + break; + if (dwarf_get_LANG_name(lang, &lang_str) != DW_DLV_OK) + break; + printf("\t(%s)", &lang_str[strlen("DW_LANG_")]); + break; + + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + switch (form) { + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_sec_offset: + printf("\t(location list)"); + break; + default: + break; + } + + default: + break; + } + putchar('\n'); + } + + +cont_search: + /* Search children. */ + ret = dwarf_child(die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_child: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + dump_dwarf_die(re, ret_die, level + 1); + + /* Search sibling. */ + is_info = dwarf_get_die_infotypes_flag(die); + ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + dump_dwarf_die(re, ret_die, level); + + dwarf_dealloc(re->dbg, die, DW_DLA_DIE); +} + +static void +set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, + Dwarf_Half ver) +{ + + re->cu_psize = psize; + re->cu_osize = osize; + re->cu_ver = ver; +} + +static void +dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info) +{ + struct section *s; + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Half tag, version, pointer_size, off_size, cu_type; + Dwarf_Off cu_offset, cu_length; + Dwarf_Off aboff; + Dwarf_Unsigned typeoff; + Dwarf_Sig8 sig8; + Dwarf_Unsigned sig; + uint8_t *p; + const char *sn, *ut; + char unk_ut[32]; + int i, ret; + + sn = is_info ? ".debug_info" : ".debug_types"; + + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && !strcmp(s->name, sn)) + break; + } + if ((size_t) i >= re->shnum) + return; + + do { + printf("\nDump of debug contents of section %s:\n", sn); + + while ((ret = dwarf_next_cu_header_d(re->dbg, is_info, NULL, + &version, &aboff, &pointer_size, &off_size, NULL, &sig8, + &typeoff, NULL, &cu_type, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); + die = NULL; + while (dwarf_siblingof_b(re->dbg, die, &die, is_info, + &de) == DW_DLV_OK) { + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + /* XXX: What about DW_TAG_partial_unit? */ + if ((is_info && tag == DW_TAG_compile_unit) || + (!is_info && tag == DW_TAG_type_unit)) + break; + } + if (die == NULL && is_info) { + warnx("could not find DW_TAG_compile_unit " + "die"); + continue; + } else if (die == NULL && !is_info) { + warnx("could not find DW_TAG_type_unit die"); + continue; + } + + if (dwarf_die_CU_offset_range(die, &cu_offset, + &cu_length, &de) != DW_DLV_OK) { + warnx("dwarf_die_CU_offset failed: %s", + dwarf_errmsg(de)); + continue; + } + + cu_length -= off_size == 4 ? 4 : 12; + + sig = 0; + if (!is_info) { + p = (uint8_t *)(uintptr_t) &sig8.signature[0]; + sig = re->dw_decode(&p, 8); + } + + printf("\n %s Unit @ offset 0x%jx:\n", + is_info ? "Compilation" : "Type", + (uintmax_t) cu_offset); + printf(" Length:\t\t%#jx (%d-bit)\n", + (uintmax_t) cu_length, off_size == 4 ? 32 : 64); + printf(" Version:\t\t%u\n", version); + if (version == 5) { + if (dwarf_get_UT_name(cu_type, &ut) != + DW_DLV_OK) { + snprintf(unk_ut, sizeof(unk_ut), + "[Unknown UT: %#x]", cu_type); + ut = unk_ut; + } + printf(" Unit Type:\t\t%s (%u)\n", + ut, cu_type); + } + printf(" Abbrev Offset:\t0x%jx\n", + (uintmax_t) aboff); + printf(" Pointer Size:\t%u\n", pointer_size); + if (!is_info) { + printf(" Signature:\t\t0x%016jx\n", + (uintmax_t) sig); + printf(" Type Offset:\t0x%jx\n", + (uintmax_t) typeoff); + } + + dump_dwarf_die(re, die, 0); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + if (is_info) + break; + } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); +} + +static void +dump_dwarf_abbrev(struct readelf *re) +{ + Dwarf_Abbrev ab; + Dwarf_Off aboff, atoff; + Dwarf_Unsigned length, attr_count; + Dwarf_Signed flag, form; + Dwarf_Half tag, attr; + Dwarf_Error de; + const char *tag_str, *attr_str, *form_str; + char unk_tag[32], unk_attr[32], unk_form[32]; + int i, j, ret; + + printf("\nContents of section .debug_abbrev:\n\n"); + + while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, &aboff, + NULL, NULL, &de)) == DW_DLV_OK) { + printf(" Number TAG\n"); + i = 0; + while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, + &attr_count, &de)) == DW_DLV_OK) { + if (length == 1) { + dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); + break; + } + aboff += length; + printf("%4d", ++i); + if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_tag failed: %s", + dwarf_errmsg(de)); + goto next_abbrev; + } + if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { + snprintf(unk_tag, sizeof(unk_tag), + "[Unknown Tag: %#x]", tag); + tag_str = unk_tag; + } + if (dwarf_get_abbrev_children_flag(ab, &flag, &de) != + DW_DLV_OK) { + warnx("dwarf_get_abbrev_children_flag failed:" + " %s", dwarf_errmsg(de)); + goto next_abbrev; + } + printf(" %s %s\n", tag_str, + flag ? "[has children]" : "[no children]"); + for (j = 0; (Dwarf_Unsigned) j < attr_count; j++) { + if (dwarf_get_abbrev_entry(ab, (Dwarf_Signed) j, + &attr, &form, &atoff, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_entry failed:" + " %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_get_AT_name(attr, &attr_str) != + DW_DLV_OK) { + snprintf(unk_attr, sizeof(unk_attr), + "[Unknown AT: %#x]", attr); + attr_str = unk_attr; + } + if (dwarf_get_FORM_name(form, &form_str) != + DW_DLV_OK) { + snprintf(unk_form, sizeof(unk_form), + "[Unknown Form: %#x]", + (Dwarf_Half) form); + form_str = unk_form; + } + printf(" %-18s %s\n", attr_str, form_str); + } + next_abbrev: + dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); + } + if (ret != DW_DLV_OK) + warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); +} + +static void +dump_dwarf_pubnames(struct readelf *re) +{ + struct section *s; + Dwarf_Off die_off; + Dwarf_Unsigned offset, length, nt_cu_offset, nt_cu_length; + Dwarf_Signed cnt; + Dwarf_Global *globs; + Dwarf_Half nt_version; + Dwarf_Error de; + Elf_Data *d; + char *glob_name; + int i, dwarf_size, elferr; + + printf("\nContents of the .debug_pubnames section:\n"); + + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && !strcmp(s->name, ".debug_pubnames")) + break; + } + if ((size_t) i >= re->shnum) + return; + + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + return; + } + if (d->d_size <= 0) + return; + + /* Read in .debug_pubnames section table header. */ + offset = 0; + length = re->dw_read(d, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = re->dw_read(d, &offset, 8); + } else + dwarf_size = 4; + + if (length > d->d_size - offset) { + warnx("invalid .dwarf_pubnames section"); + return; + } + + nt_version = re->dw_read(d, &offset, 2); + nt_cu_offset = re->dw_read(d, &offset, dwarf_size); + nt_cu_length = re->dw_read(d, &offset, dwarf_size); + printf(" Length:\t\t\t\t%ju\n", (uintmax_t) length); + printf(" Version:\t\t\t\t%u\n", nt_version); + printf(" Offset into .debug_info section:\t%ju\n", + (uintmax_t) nt_cu_offset); + printf(" Size of area in .debug_info section:\t%ju\n", + (uintmax_t) nt_cu_length); + + if (dwarf_get_globals(re->dbg, &globs, &cnt, &de) != DW_DLV_OK) { + warnx("dwarf_get_globals failed: %s", dwarf_errmsg(de)); + return; + } + + printf("\n Offset Name\n"); + for (i = 0; i < cnt; i++) { + if (dwarf_globname(globs[i], &glob_name, &de) != DW_DLV_OK) { + warnx("dwarf_globname failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_global_die_offset(globs[i], &die_off, &de) != + DW_DLV_OK) { + warnx("dwarf_global_die_offset failed: %s", + dwarf_errmsg(de)); + continue; + } + printf(" %-11ju %s\n", (uintmax_t) die_off, glob_name); + } +} + +static void +dump_dwarf_aranges(struct readelf *re) +{ + struct section *s; + Dwarf_Arange *aranges; + Dwarf_Addr start; + Dwarf_Unsigned offset, length, as_cu_offset; + Dwarf_Off die_off; + Dwarf_Signed cnt; + Dwarf_Half as_version, as_addrsz, as_segsz; + Dwarf_Error de; + Elf_Data *d; + int i, dwarf_size, elferr; + + printf("\nContents of section .debug_aranges:\n"); + + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && !strcmp(s->name, ".debug_aranges")) + break; + } + if ((size_t) i >= re->shnum) + return; + + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + return; + } + if (d->d_size <= 0) + return; + + /* Read in the .debug_aranges section table header. */ + offset = 0; + length = re->dw_read(d, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = re->dw_read(d, &offset, 8); + } else + dwarf_size = 4; + + if (length > d->d_size - offset) { + warnx("invalid .dwarf_aranges section"); + return; + } + + as_version = re->dw_read(d, &offset, 2); + as_cu_offset = re->dw_read(d, &offset, dwarf_size); + as_addrsz = re->dw_read(d, &offset, 1); + as_segsz = re->dw_read(d, &offset, 1); + + printf(" Length:\t\t\t%ju\n", (uintmax_t) length); + printf(" Version:\t\t\t%u\n", as_version); + printf(" Offset into .debug_info:\t%ju\n", (uintmax_t) as_cu_offset); + printf(" Pointer Size:\t\t\t%u\n", as_addrsz); + printf(" Segment Size:\t\t\t%u\n", as_segsz); + + if (dwarf_get_aranges(re->dbg, &aranges, &cnt, &de) != DW_DLV_OK) { + warnx("dwarf_get_aranges failed: %s", dwarf_errmsg(de)); + return; + } + + printf("\n Address Length\n"); + for (i = 0; i < cnt; i++) { + if (dwarf_get_arange_info(aranges[i], &start, &length, + &die_off, &de) != DW_DLV_OK) { + warnx("dwarf_get_arange_info failed: %s", + dwarf_errmsg(de)); + continue; + } + printf(" %08jx %ju\n", (uintmax_t) start, + (uintmax_t) length); + } +} + +static void +dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base) +{ + Dwarf_Attribute *attr_list; + Dwarf_Ranges *ranges; + Dwarf_Die ret_die; + Dwarf_Error de; + Dwarf_Addr base0; + Dwarf_Half attr; + Dwarf_Signed attr_count, cnt; + Dwarf_Unsigned off, bytecnt; + int i, j, ret; + + if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != + DW_DLV_OK) { + if (ret == DW_DLV_ERROR) + warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + + for (i = 0; i < attr_count; i++) { + if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { + warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); + continue; + } + if (attr != DW_AT_ranges) + continue; + if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_get_ranges(re->dbg, (Dwarf_Off) off, &ranges, &cnt, + &bytecnt, &de) != DW_DLV_OK) + continue; + base0 = base; + for (j = 0; j < cnt; j++) { + printf(" %08jx ", (uintmax_t) off); + if (ranges[j].dwr_type == DW_RANGES_END) { + printf("%s\n", ""); + continue; + } else if (ranges[j].dwr_type == + DW_RANGES_ADDRESS_SELECTION) { + base0 = ranges[j].dwr_addr2; + continue; + } + if (re->ec == ELFCLASS32) + printf("%08jx %08jx\n", + (uintmax_t) (ranges[j].dwr_addr1 + base0), + (uintmax_t) (ranges[j].dwr_addr2 + base0)); + else + printf("%016jx %016jx\n", + (uintmax_t) (ranges[j].dwr_addr1 + base0), + (uintmax_t) (ranges[j].dwr_addr2 + base0)); + } + } + +cont_search: + /* Search children. */ + ret = dwarf_child(die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_child: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + dump_dwarf_ranges_foreach(re, ret_die, base); + + /* Search sibling. */ + ret = dwarf_siblingof(re->dbg, die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + dump_dwarf_ranges_foreach(re, ret_die, base); +} + +static void +dump_dwarf_ranges(struct readelf *re) +{ + Dwarf_Ranges *ranges; + Dwarf_Die die; + Dwarf_Signed cnt; + Dwarf_Unsigned bytecnt; + Dwarf_Half tag; + Dwarf_Error de; + Dwarf_Unsigned lowpc; + int ret; + + if (dwarf_get_ranges(re->dbg, 0, &ranges, &cnt, &bytecnt, &de) != + DW_DLV_OK) + return; + + printf("Contents of the .debug_ranges section:\n\n"); + if (re->ec == ELFCLASS32) + printf(" %-8s %-8s %s\n", "Offset", "Begin", "End"); + else + printf(" %-8s %-16s %s\n", "Offset", "Begin", "End"); + + while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, + NULL, &de)) == DW_DLV_OK) { + die = NULL; + if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) + continue; + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); + continue; + } + /* XXX: What about DW_TAG_partial_unit? */ + lowpc = 0; + if (tag == DW_TAG_compile_unit) { + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, + &de) != DW_DLV_OK) + lowpc = 0; + } + + dump_dwarf_ranges_foreach(re, die, (Dwarf_Addr) lowpc); + } + putchar('\n'); +} + +static void +dump_dwarf_macinfo(struct readelf *re) +{ + Dwarf_Unsigned offset; + Dwarf_Signed cnt; + Dwarf_Macro_Details *md; + Dwarf_Error de; + const char *mi_str; + char unk_mi[32]; + int i; + +#define _MAX_MACINFO_ENTRY 65535 + + printf("\nContents of section .debug_macinfo:\n\n"); + + offset = 0; + while (dwarf_get_macro_details(re->dbg, offset, _MAX_MACINFO_ENTRY, + &cnt, &md, &de) == DW_DLV_OK) { + for (i = 0; i < cnt; i++) { + offset = md[i].dmd_offset + 1; + if (md[i].dmd_type == 0) + break; + if (dwarf_get_MACINFO_name(md[i].dmd_type, &mi_str) != + DW_DLV_OK) { + snprintf(unk_mi, sizeof(unk_mi), + "[Unknown MACINFO: %#x]", md[i].dmd_type); + mi_str = unk_mi; + } + printf(" %s", mi_str); + switch (md[i].dmd_type) { + case DW_MACINFO_define: + case DW_MACINFO_undef: + printf(" - lineno : %jd macro : %s\n", + (intmax_t) md[i].dmd_lineno, + md[i].dmd_macro); + break; + case DW_MACINFO_start_file: + printf(" - lineno : %jd filenum : %jd\n", + (intmax_t) md[i].dmd_lineno, + (intmax_t) md[i].dmd_fileindex); + break; + default: + putchar('\n'); + break; + } + } + } + +#undef _MAX_MACINFO_ENTRY +} + +static void +dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, + Dwarf_Debug dbg) +{ + Dwarf_Frame_Op *oplist; + Dwarf_Signed opcnt, delta; + Dwarf_Small op; + Dwarf_Error de; + const char *op_str; + char unk_op[32]; + int i; + + if (dwarf_expand_frame_instructions(cie, insts, len, &oplist, + &opcnt, &de) != DW_DLV_OK) { + warnx("dwarf_expand_frame_instructions failed: %s", + dwarf_errmsg(de)); + return; + } + + for (i = 0; i < opcnt; i++) { + if (oplist[i].fp_base_op != 0) + op = oplist[i].fp_base_op << 6; + else + op = oplist[i].fp_extended_op; + if (dwarf_get_CFA_name(op, &op_str) != DW_DLV_OK) { + snprintf(unk_op, sizeof(unk_op), "[Unknown CFA: %#x]", + op); + op_str = unk_op; + } + printf(" %s", op_str); + switch (op) { + case DW_CFA_advance_loc: + delta = oplist[i].fp_offset * caf; + pc += delta; + printf(": %ju to %08jx", (uintmax_t) delta, + (uintmax_t) pc); + break; + case DW_CFA_offset: + case DW_CFA_offset_extended: + case DW_CFA_offset_extended_sf: + delta = oplist[i].fp_offset * daf; + printf(": r%u (%s) at cfa%+jd", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), + (intmax_t) delta); + break; + case DW_CFA_restore: + printf(": r%u (%s)", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register)); + break; + case DW_CFA_set_loc: + pc = oplist[i].fp_offset; + printf(": to %08jx", (uintmax_t) pc); + break; + case DW_CFA_advance_loc1: + case DW_CFA_advance_loc2: + case DW_CFA_advance_loc4: + pc += oplist[i].fp_offset; + printf(": %jd to %08jx", (intmax_t) oplist[i].fp_offset, + (uintmax_t) pc); + break; + case DW_CFA_def_cfa: + printf(": r%u (%s) ofs %ju", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), + (uintmax_t) oplist[i].fp_offset); + break; + case DW_CFA_def_cfa_sf: + printf(": r%u (%s) ofs %jd", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), + (intmax_t) (oplist[i].fp_offset * daf)); + break; + case DW_CFA_def_cfa_register: + printf(": r%u (%s)", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register)); + break; + case DW_CFA_def_cfa_offset: + printf(": %ju", (uintmax_t) oplist[i].fp_offset); + break; + case DW_CFA_def_cfa_offset_sf: + printf(": %jd", (intmax_t) (oplist[i].fp_offset * daf)); + break; + default: + break; + } + putchar('\n'); + } + + dwarf_dealloc(dbg, oplist, DW_DLA_FRAME_BLOCK); +} + +static char * +get_regoff_str(struct readelf *re, Dwarf_Half reg, Dwarf_Addr off) +{ + static char rs[REGISTER_NAME_BUFFER_SIZE + DWARF_ADDR_BUFFER_SIZE - 1]; + + if (reg == DW_FRAME_UNDEFINED_VAL || reg == DW_FRAME_REG_INITIAL_VALUE) + snprintf(rs, sizeof(rs), "%c", 'u'); + else if (reg == DW_FRAME_CFA_COL) + snprintf(rs, sizeof(rs), "c%+jd", (intmax_t) off); + else + snprintf(rs, sizeof(rs), "%s%+jd", dwarf_regname(re, reg), + (intmax_t) off); + + return (rs); +} + +static int +dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, Dwarf_Addr pc, + Dwarf_Unsigned func_len, Dwarf_Half cie_ra) +{ + Dwarf_Regtable rt; + Dwarf_Addr row_pc, end_pc, pre_pc, cur_pc; + Dwarf_Error de; + char *vec; + int i; + +#define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7)) +#define BIT_CLR(v, n) (v[(n)>>3] &= ~(1U << ((n) & 7))) +#define BIT_ISSET(v, n) (v[(n)>>3] & (1U << ((n) & 7))) +#define RT(x) rt.rules[(x)] + + vec = calloc((DW_REG_TABLE_SIZE + 7) / 8, 1); + if (vec == NULL) + err(EXIT_FAILURE, "calloc failed"); + + pre_pc = ~((Dwarf_Addr) 0); + cur_pc = pc; + end_pc = pc + func_len; + for (; cur_pc < end_pc; cur_pc++) { + if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, + &de) != DW_DLV_OK) { + free(vec); + warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", + dwarf_errmsg(de)); + return (-1); + } + if (row_pc == pre_pc) + continue; + pre_pc = row_pc; + for (i = 1; i < DW_REG_TABLE_SIZE; i++) { + if (rt.rules[i].dw_regnum != DW_FRAME_REG_INITIAL_VALUE) + BIT_SET(vec, i); + } + } + + printf(" LOC CFA "); + for (i = 1; i < DW_REG_TABLE_SIZE; i++) { + if (BIT_ISSET(vec, i)) { + if ((Dwarf_Half) i == cie_ra) + printf("ra "); + else + printf("%-5s", + dwarf_regname(re, (unsigned int) i)); + } + } + putchar('\n'); + + pre_pc = ~((Dwarf_Addr) 0); + cur_pc = pc; + end_pc = pc + func_len; + for (; cur_pc < end_pc; cur_pc++) { + if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", + dwarf_errmsg(de)); + return (-1); + } + if (row_pc == pre_pc) + continue; + pre_pc = row_pc; + printf("%08jx ", (uintmax_t) row_pc); + printf("%-8s ", get_regoff_str(re, RT(0).dw_regnum, + RT(0).dw_offset)); + for (i = 1; i < DW_REG_TABLE_SIZE; i++) { + if (BIT_ISSET(vec, i)) { + printf("%-5s", get_regoff_str(re, + RT(i).dw_regnum, RT(i).dw_offset)); + } + } + putchar('\n'); + } + + free(vec); + + return (0); + +#undef BIT_SET +#undef BIT_CLR +#undef BIT_ISSET +#undef RT +} + +static void +dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) +{ + Dwarf_Cie *cie_list, cie, pre_cie; + Dwarf_Fde *fde_list, fde; + Dwarf_Off cie_offset, fde_offset; + Dwarf_Unsigned cie_length, fde_instlen; + Dwarf_Unsigned cie_caf, cie_daf, cie_instlen, func_len, fde_length; + Dwarf_Signed cie_count, fde_count, cie_index; + Dwarf_Addr low_pc; + Dwarf_Half cie_ra; + Dwarf_Small cie_version; + Dwarf_Ptr fde_addr, fde_inst, cie_inst; + char *cie_aug, c; + int i, eh_frame; + Dwarf_Error de; + + printf("\nThe section %s contains:\n\n", s->name); + + if (!strcmp(s->name, ".debug_frame")) { + eh_frame = 0; + if (dwarf_get_fde_list(re->dbg, &cie_list, &cie_count, + &fde_list, &fde_count, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_list failed: %s", + dwarf_errmsg(de)); + return; + } + } else if (!strcmp(s->name, ".eh_frame")) { + eh_frame = 1; + if (dwarf_get_fde_list_eh(re->dbg, &cie_list, &cie_count, + &fde_list, &fde_count, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_list_eh failed: %s", + dwarf_errmsg(de)); + return; + } + } else + return; + + pre_cie = NULL; + for (i = 0; i < fde_count; i++) { + if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, + &fde_length, &cie_offset, &cie_index, &fde_offset, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_range failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_instr_bytes failed: %s", + dwarf_errmsg(de)); + continue; + } + if (pre_cie == NULL || cie != pre_cie) { + pre_cie = cie; + if (dwarf_get_cie_info(cie, &cie_length, &cie_version, + &cie_aug, &cie_caf, &cie_daf, &cie_ra, + &cie_inst, &cie_instlen, &de) != DW_DLV_OK) { + warnx("dwarf_get_cie_info failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%08jx %08jx %8.8jx CIE", + (uintmax_t) cie_offset, + (uintmax_t) cie_length, + (uintmax_t) (eh_frame ? 0 : ~0U)); + if (!alt) { + putchar('\n'); + printf(" Version:\t\t\t%u\n", cie_version); + printf(" Augmentation:\t\t\t\""); + while ((c = *cie_aug++) != '\0') + putchar(c); + printf("\"\n"); + printf(" Code alignment factor:\t%ju\n", + (uintmax_t) cie_caf); + printf(" Data alignment factor:\t%jd\n", + (intmax_t) cie_daf); + printf(" Return address column:\t%ju\n", + (uintmax_t) cie_ra); + putchar('\n'); + dump_dwarf_frame_inst(re, cie, cie_inst, + cie_instlen, cie_caf, cie_daf, 0, + re->dbg); + putchar('\n'); + } else { + printf(" \""); + while ((c = *cie_aug++) != '\0') + putchar(c); + putchar('"'); + printf(" cf=%ju df=%jd ra=%ju\n", + (uintmax_t) cie_caf, + (uintmax_t) cie_daf, + (uintmax_t) cie_ra); + dump_dwarf_frame_regtable(re, fde, low_pc, 1, + cie_ra); + putchar('\n'); + } + } + printf("%08jx %08jx %08jx FDE cie=%08jx pc=%08jx..%08jx\n", + (uintmax_t) fde_offset, (uintmax_t) fde_length, + (uintmax_t) cie_offset, + (uintmax_t) (eh_frame ? fde_offset + 4 - cie_offset : + cie_offset), + (uintmax_t) low_pc, (uintmax_t) (low_pc + func_len)); + if (!alt) + dump_dwarf_frame_inst(re, cie, fde_inst, fde_instlen, + cie_caf, cie_daf, low_pc, re->dbg); + else + dump_dwarf_frame_regtable(re, fde, low_pc, func_len, + cie_ra); + putchar('\n'); + } +} + +static void +dump_dwarf_frame(struct readelf *re, int alt) +{ + struct section *s; + int i; + + (void) dwarf_set_frame_cfa_value(re->dbg, DW_FRAME_CFA_COL); + + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && (!strcmp(s->name, ".debug_frame") || + !strcmp(s->name, ".eh_frame"))) + dump_dwarf_frame_section(re, s, alt); + } +} + +static void +dump_dwarf_str(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + unsigned char *p; + int elferr, end, i, j; + + printf("\nContents of section .debug_str:\n"); + + s = NULL; + for (i = 0; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (s->name != NULL && !strcmp(s->name, ".debug_str")) + break; + } + if ((size_t) i >= re->shnum) + return; + + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(-1)); + return; + } + if (d->d_size <= 0) + return; + + for (i = 0, p = d->d_buf; (size_t) i < d->d_size; i += 16) { + printf(" 0x%08x", (unsigned int) i); + if ((size_t) i + 16 > d->d_size) + end = d->d_size; + else + end = i + 16; + for (j = i; j < i + 16; j++) { + if ((j - i) % 4 == 0) + putchar(' '); + if (j >= end) { + printf(" "); + continue; + } + printf("%02x", (uint8_t) p[j]); + } + putchar(' '); + for (j = i; j < end; j++) { + if (isprint(p[j])) + putchar(p[j]); + else if (p[j] == 0) + putchar('.'); + else + putchar(' '); + } + putchar('\n'); + } +} + +struct loc_at { + Dwarf_Attribute la_at; + Dwarf_Unsigned la_off; + Dwarf_Unsigned la_lowpc; + Dwarf_Half la_cu_psize; + Dwarf_Half la_cu_osize; + Dwarf_Half la_cu_ver; + TAILQ_ENTRY(loc_at) la_next; +}; + +static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist); + +static void +search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) +{ + Dwarf_Attribute *attr_list; + Dwarf_Die ret_die; + Dwarf_Unsigned off; + Dwarf_Off ref; + Dwarf_Signed attr_count; + Dwarf_Half attr, form; + Dwarf_Bool is_info; + Dwarf_Error de; + struct loc_at *la, *nla; + int i, ret; + + is_info = dwarf_get_die_infotypes_flag(die); + + if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != + DW_DLV_OK) { + if (ret == DW_DLV_ERROR) + warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); + goto cont_search; + } + for (i = 0; i < attr_count; i++) { + if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { + warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); + continue; + } + if (attr != DW_AT_location && + attr != DW_AT_string_length && + attr != DW_AT_return_addr && + attr != DW_AT_data_member_location && + attr != DW_AT_frame_base && + attr != DW_AT_segment && + attr != DW_AT_static_link && + attr != DW_AT_use_location && + attr != DW_AT_vtable_elem_location) + continue; + if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { + warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); + continue; + } + if (form == DW_FORM_data4 || form == DW_FORM_data8) { + if (dwarf_formudata(attr_list[i], &off, &de) != + DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + } else if (form == DW_FORM_sec_offset) { + if (dwarf_global_formref(attr_list[i], &ref, &de) != + DW_DLV_OK) { + warnx("dwarf_global_formref failed: %s", + dwarf_errmsg(de)); + continue; + } + off = ref; + } else + continue; + + TAILQ_FOREACH(la, &lalist, la_next) { + if (off == la->la_off) + break; + if (off < la->la_off) { + if ((nla = malloc(sizeof(*nla))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + nla->la_at = attr_list[i]; + nla->la_off = off; + nla->la_lowpc = lowpc; + nla->la_cu_psize = re->cu_psize; + nla->la_cu_osize = re->cu_osize; + nla->la_cu_ver = re->cu_ver; + TAILQ_INSERT_BEFORE(la, nla, la_next); + break; + } + } + if (la == NULL) { + if ((nla = malloc(sizeof(*nla))) == NULL) + err(EXIT_FAILURE, "malloc failed"); + nla->la_at = attr_list[i]; + nla->la_off = off; + nla->la_lowpc = lowpc; + nla->la_cu_psize = re->cu_psize; + nla->la_cu_osize = re->cu_osize; + nla->la_cu_ver = re->cu_ver; + TAILQ_INSERT_TAIL(&lalist, nla, la_next); + } + } + +cont_search: + /* Search children. */ + ret = dwarf_child(die, &ret_die, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_child: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + search_loclist_at(re, ret_die, lowpc); + + /* Search sibling. */ + ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); + if (ret == DW_DLV_ERROR) + warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); + else if (ret == DW_DLV_OK) + search_loclist_at(re, ret_die, lowpc); +} + +static void +dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr) +{ + const char *op_str; + char unk_op[32]; + uint8_t *b, n; + int i; + + if (dwarf_get_OP_name(lr->lr_atom, &op_str) != + DW_DLV_OK) { + snprintf(unk_op, sizeof(unk_op), + "[Unknown OP: %#x]", lr->lr_atom); + op_str = unk_op; + } + + printf("%s", op_str); + + switch (lr->lr_atom) { + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + printf(" (%s)", dwarf_regname(re, lr->lr_atom - DW_OP_reg0)); + break; + + case DW_OP_deref: + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + case DW_OP_dup: + case DW_OP_drop: + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + case DW_OP_nop: + case DW_OP_push_object_address: + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + case DW_OP_stack_value: + case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: + break; + + case DW_OP_const1u: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + case DW_OP_const2u: + case DW_OP_bra: + case DW_OP_skip: + case DW_OP_const4u: + case DW_OP_const8u: + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + printf(": %ju", (uintmax_t) + lr->lr_number); + break; + + case DW_OP_const1s: + case DW_OP_const2s: + case DW_OP_const4s: + case DW_OP_const8s: + case DW_OP_consts: + printf(": %jd", (intmax_t) + lr->lr_number); + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + printf(" (%s): %jd", + dwarf_regname(re, lr->lr_atom - DW_OP_breg0), + (intmax_t) lr->lr_number); + break; + + case DW_OP_fbreg: + printf(": %jd", (intmax_t) + lr->lr_number); + break; + + case DW_OP_bregx: + printf(": %ju (%s) %jd", + (uintmax_t) lr->lr_number, + dwarf_regname(re, (unsigned int) lr->lr_number), + (intmax_t) lr->lr_number2); + break; + + case DW_OP_addr: + case DW_OP_GNU_encoded_addr: + printf(": %#jx", (uintmax_t) + lr->lr_number); + break; + + case DW_OP_GNU_implicit_pointer: + printf(": <0x%jx> %jd", (uintmax_t) lr->lr_number, + (intmax_t) lr->lr_number2); + break; + + case DW_OP_implicit_value: + printf(": %ju byte block:", (uintmax_t) lr->lr_number); + b = (uint8_t *)(uintptr_t) lr->lr_number2; + for (i = 0; (Dwarf_Unsigned) i < lr->lr_number; i++) + printf(" %x", b[i]); + break; + + case DW_OP_GNU_entry_value: + printf(": ("); + dump_dwarf_block(re, (uint8_t *)(uintptr_t) lr->lr_number2, + lr->lr_number); + putchar(')'); + break; + + case DW_OP_GNU_const_type: + printf(": <0x%jx> ", (uintmax_t) lr->lr_number); + b = (uint8_t *)(uintptr_t) lr->lr_number2; + n = *b; + for (i = 1; (uint8_t) i < n; i++) + printf(" %x", b[i]); + break; + + case DW_OP_GNU_regval_type: + printf(": %ju (%s) <0x%jx>", (uintmax_t) lr->lr_number, + dwarf_regname(re, (unsigned int) lr->lr_number), + (uintmax_t) lr->lr_number2); + break; + + case DW_OP_GNU_convert: + case DW_OP_GNU_deref_type: + case DW_OP_GNU_parameter_ref: + case DW_OP_GNU_reinterpret: + printf(": <0x%jx>", (uintmax_t) lr->lr_number); + break; + + default: + break; + } +} + +static void +dump_dwarf_block(struct readelf *re, uint8_t *b, Dwarf_Unsigned len) +{ + Dwarf_Locdesc *llbuf; + Dwarf_Signed lcnt; + Dwarf_Error de; + int i; + + if (dwarf_loclist_from_expr_b(re->dbg, b, len, re->cu_psize, + re->cu_osize, re->cu_ver, &llbuf, &lcnt, &de) != DW_DLV_OK) { + warnx("dwarf_loclist_form_expr_b: %s", dwarf_errmsg(de)); + return; + } + + for (i = 0; (Dwarf_Half) i < llbuf->ld_cents; i++) { + dump_dwarf_loc(re, &llbuf->ld_s[i]); + if (i < llbuf->ld_cents - 1) + printf("; "); + } + + dwarf_dealloc(re->dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(re->dbg, llbuf, DW_DLA_LOCDESC); +} + +static void +dump_dwarf_loclist(struct readelf *re) +{ + Dwarf_Die die; + Dwarf_Locdesc **llbuf; + Dwarf_Unsigned lowpc; + Dwarf_Signed lcnt; + Dwarf_Half tag, version, pointer_size, off_size; + Dwarf_Error de; + struct loc_at *la; + int i, j, ret, has_content; + + /* Search .debug_info section. */ + while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL, + &pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); + die = NULL; + if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) + continue; + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); + continue; + } + /* XXX: What about DW_TAG_partial_unit? */ + lowpc = 0; + if (tag == DW_TAG_compile_unit) { + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, + &lowpc, &de) != DW_DLV_OK) + lowpc = 0; + } + + /* Search attributes for reference to .debug_loc section. */ + search_loclist_at(re, die, lowpc); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + + /* Search .debug_types section. */ + do { + while ((ret = dwarf_next_cu_header_c(re->dbg, 0, NULL, + &version, NULL, &pointer_size, &off_size, NULL, NULL, + NULL, NULL, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); + die = NULL; + if (dwarf_siblingof(re->dbg, die, &die, &de) != + DW_DLV_OK) + continue; + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + + lowpc = 0; + if (tag == DW_TAG_type_unit) { + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, + &lowpc, &de) != DW_DLV_OK) + lowpc = 0; + } + + /* + * Search attributes for reference to .debug_loc + * section. + */ + search_loclist_at(re, die, lowpc); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); + + if (TAILQ_EMPTY(&lalist)) + return; + + has_content = 0; + TAILQ_FOREACH(la, &lalist, la_next) { + if ((ret = dwarf_loclist_n(la->la_at, &llbuf, &lcnt, &de)) != + DW_DLV_OK) { + if (ret != DW_DLV_NO_ENTRY) + warnx("dwarf_loclist_n failed: %s", + dwarf_errmsg(de)); + continue; + } + if (!has_content) { + has_content = 1; + printf("\nContents of section .debug_loc:\n"); + printf(" Offset Begin End Expression\n"); + } + set_cu_context(re, la->la_cu_psize, la->la_cu_osize, + la->la_cu_ver); + for (i = 0; i < lcnt; i++) { + printf(" %8.8jx ", (uintmax_t) la->la_off); + if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) { + printf("\n"); + continue; + } + + /* TODO: handle base selection entry. */ + + printf("%8.8jx %8.8jx ", + (uintmax_t) (la->la_lowpc + llbuf[i]->ld_lopc), + (uintmax_t) (la->la_lowpc + llbuf[i]->ld_hipc)); + + putchar('('); + for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { + dump_dwarf_loc(re, &llbuf[i]->ld_s[j]); + if (j < llbuf[i]->ld_cents - 1) + printf("; "); + } + putchar(')'); + + if (llbuf[i]->ld_lopc == llbuf[i]->ld_hipc) + printf(" (start == end)"); + putchar('\n'); + } + for (i = 0; i < lcnt; i++) { + dwarf_dealloc(re->dbg, llbuf[i]->ld_s, + DW_DLA_LOC_BLOCK); + dwarf_dealloc(re->dbg, llbuf[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(re->dbg, llbuf, DW_DLA_LIST); + } + + if (!has_content) + printf("\nSection '.debug_loc' has no debugging data.\n"); +} + +/* + * Retrieve a string using string table section index and the string offset. + */ +static const char* +get_string(struct readelf *re, int strtab, size_t off) +{ + const char *name; + + if ((name = elf_strptr(re->elf, strtab, off)) == NULL) + return (""); + + return (name); +} + +/* + * Retrieve the name of a symbol using the section index of the symbol + * table and the index of the symbol within that table. + */ +static const char * +get_symbol_name(struct readelf *re, int symtab, int i) +{ + struct section *s; + const char *name; + GElf_Sym sym; + Elf_Data *data; + int elferr; + + s = &re->sl[symtab]; + if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) + return (""); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return (""); + } + if (gelf_getsym(data, i, &sym) != &sym) + return (""); + /* Return section name for STT_SECTION symbol. */ + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) { + if (sym.st_shndx < re->shnum && + re->sl[sym.st_shndx].name != NULL) + return (re->sl[sym.st_shndx].name); + return (""); + } + if (s->link >= re->shnum || + (name = elf_strptr(re->elf, s->link, sym.st_name)) == NULL) + return (""); + + return (name); +} + +static uint64_t +get_symbol_value(struct readelf *re, int symtab, int i) +{ + struct section *s; + GElf_Sym sym; + Elf_Data *data; + int elferr; + + s = &re->sl[symtab]; + if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) + return (0); + (void) elf_errno(); + if ((data = elf_getdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", elf_errmsg(elferr)); + return (0); + } + if (gelf_getsym(data, i, &sym) != &sym) + return (0); + + return (sym.st_value); +} + +static void +hex_dump(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + uint8_t *buf; + size_t sz, nbytes; + uint64_t addr; + int elferr, i, j; + + for (i = 1; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (find_dumpop(re, (size_t) i, s->name, HEX_DUMP, -1) == NULL) + continue; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL && + (d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + (void) elf_errno(); + if (d->d_size <= 0 || d->d_buf == NULL) { + printf("\nSection '%s' has no data to dump.\n", + s->name); + continue; + } + buf = d->d_buf; + sz = d->d_size; + addr = s->addr; + printf("\nHex dump of section '%s':\n", s->name); + while (sz > 0) { + printf(" 0x%8.8jx ", (uintmax_t)addr); + nbytes = sz > 16? 16 : sz; + for (j = 0; j < 16; j++) { + if ((size_t)j < nbytes) + printf("%2.2x", buf[j]); + else + printf(" "); + if ((j & 3) == 3) + printf(" "); + } + for (j = 0; (size_t)j < nbytes; j++) { + if (isprint(buf[j])) + printf("%c", buf[j]); + else + printf("."); + } + printf("\n"); + buf += nbytes; + addr += nbytes; + sz -= nbytes; + } + } +} + +static void +str_dump(struct readelf *re) +{ + struct section *s; + Elf_Data *d; + unsigned char *start, *end, *buf_end; + unsigned int len; + int i, j, elferr, found; + + for (i = 1; (size_t) i < re->shnum; i++) { + s = &re->sl[i]; + if (find_dumpop(re, (size_t) i, s->name, STR_DUMP, -1) == NULL) + continue; + (void) elf_errno(); + if ((d = elf_getdata(s->scn, NULL)) == NULL && + (d = elf_rawdata(s->scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_getdata failed: %s", + elf_errmsg(elferr)); + continue; + } + (void) elf_errno(); + if (d->d_size <= 0 || d->d_buf == NULL) { + printf("\nSection '%s' has no data to dump.\n", + s->name); + continue; + } + buf_end = (unsigned char *) d->d_buf + d->d_size; + start = (unsigned char *) d->d_buf; + found = 0; + printf("\nString dump of section '%s':\n", s->name); + for (;;) { + while (start < buf_end && !isprint(*start)) + start++; + if (start >= buf_end) + break; + end = start + 1; + while (end < buf_end && isprint(*end)) + end++; + printf(" [%6lx] ", + (long) (start - (unsigned char *) d->d_buf)); + len = end - start; + for (j = 0; (unsigned int) j < len; j++) + putchar(start[j]); + putchar('\n'); + found = 1; + if (end >= buf_end) + break; + start = end + 1; + } + if (!found) + printf(" No strings found in this section."); + putchar('\n'); + } +} + +static void +load_sections(struct readelf *re) +{ + struct section *s; + const char *name; + Elf_Scn *scn; + GElf_Shdr sh; + size_t shstrndx, ndx; + int elferr; + + /* Allocate storage for internal section list. */ + if (!elf_getshnum(re->elf, &re->shnum)) { + warnx("elf_getshnum failed: %s", elf_errmsg(-1)); + return; + } + if (re->sl != NULL) + free(re->sl); + if ((re->sl = calloc(re->shnum, sizeof(*re->sl))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + + /* Get the index of .shstrtab section. */ + if (!elf_getshstrndx(re->elf, &shstrndx)) { + warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); + return; + } + + if ((scn = elf_getscn(re->elf, 0)) == NULL) + return; + + (void) elf_errno(); + do { + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((name = elf_strptr(re->elf, shstrndx, sh.sh_name)) == NULL) { + (void) elf_errno(); + name = ""; + } + if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) { + if ((elferr = elf_errno()) != 0) { + warnx("elf_ndxscn failed: %s", + elf_errmsg(elferr)); + continue; + } + } + if (ndx >= re->shnum) { + warnx("section index of '%s' out of range", name); + continue; + } + if (sh.sh_link >= re->shnum) + warnx("section link %llu of '%s' out of range", + (unsigned long long)sh.sh_link, name); + s = &re->sl[ndx]; + s->name = name; + s->scn = scn; + s->off = sh.sh_offset; + s->sz = sh.sh_size; + s->entsize = sh.sh_entsize; + s->align = sh.sh_addralign; + s->type = sh.sh_type; + s->flags = sh.sh_flags; + s->addr = sh.sh_addr; + s->link = sh.sh_link; + s->info = sh.sh_info; + } while ((scn = elf_nextscn(re->elf, scn)) != NULL); + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); +} + +static void +unload_sections(struct readelf *re) +{ + + if (re->sl != NULL) { + free(re->sl); + re->sl = NULL; + } + re->shnum = 0; + re->vd_s = NULL; + re->vn_s = NULL; + re->vs_s = NULL; + re->vs = NULL; + re->vs_sz = 0; + if (re->ver != NULL) { + free(re->ver); + re->ver = NULL; + re->ver_sz = 0; + } +} + +static void +dump_elf(struct readelf *re) +{ + + /* Fetch ELF header. No need to continue if it fails. */ + if (gelf_getehdr(re->elf, &re->ehdr) == NULL) { + warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); + return; + } + if ((re->ec = gelf_getclass(re->elf)) == ELFCLASSNONE) { + warnx("gelf_getclass failed: %s", elf_errmsg(-1)); + return; + } + if (re->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { + re->dw_read = _read_msb; + re->dw_decode = _decode_msb; + } else { + re->dw_read = _read_lsb; + re->dw_decode = _decode_lsb; + } + + if (re->options & ~RE_H) + load_sections(re); + if ((re->options & RE_VV) || (re->options & RE_S)) + search_ver(re); + if (re->options & RE_H) + dump_ehdr(re); + if (re->options & RE_L) + dump_phdr(re); + if (re->options & RE_SS) + dump_shdr(re); + if (re->options & RE_G) + dump_section_groups(re); + if (re->options & RE_D) + dump_dynamic(re); + if (re->options & RE_R) + dump_reloc(re); + if (re->options & RE_S) + dump_symtabs(re); + if (re->options & RE_N) + dump_notes(re); + if (re->options & RE_II) + dump_hash(re); + if (re->options & RE_X) + hex_dump(re); + if (re->options & RE_P) + str_dump(re); + if (re->options & RE_VV) + dump_ver(re); + if (re->options & RE_AA) + dump_arch_specific_info(re); + if (re->options & RE_W) + dump_dwarf(re); + if (re->options & ~RE_H) + unload_sections(re); +} + +static void +dump_dwarf(struct readelf *re) +{ + struct loc_at *la, *_la; + Dwarf_Error de; + int error; + + if (dwarf_elf_init(re->elf, DW_DLC_READ, NULL, NULL, &re->dbg, &de)) { + if ((error = dwarf_errno(de)) != DW_DLE_DEBUG_INFO_NULL) + errx(EXIT_FAILURE, "dwarf_elf_init failed: %s", + dwarf_errmsg(de)); + return; + } + + if (re->dop & DW_A) + dump_dwarf_abbrev(re); + if (re->dop & DW_L) + dump_dwarf_line(re); + if (re->dop & DW_LL) + dump_dwarf_line_decoded(re); + if (re->dop & DW_I) { + dump_dwarf_info(re, 0); + dump_dwarf_info(re, 1); + } + if (re->dop & DW_P) + dump_dwarf_pubnames(re); + if (re->dop & DW_R) + dump_dwarf_aranges(re); + if (re->dop & DW_RR) + dump_dwarf_ranges(re); + if (re->dop & DW_M) + dump_dwarf_macinfo(re); + if (re->dop & DW_F) + dump_dwarf_frame(re, 0); + else if (re->dop & DW_FF) + dump_dwarf_frame(re, 1); + if (re->dop & DW_S) + dump_dwarf_str(re); + if (re->dop & DW_O) + dump_dwarf_loclist(re); + + TAILQ_FOREACH_SAFE(la, &lalist, la_next, _la) { + TAILQ_REMOVE(&lalist, la, la_next); + free(la); + } + + dwarf_finish(re->dbg, &de); +} + +static void +dump_ar(struct readelf *re, int fd) +{ + Elf_Arsym *arsym; + Elf_Arhdr *arhdr; + Elf_Cmd cmd; + Elf *e; + size_t sz; + off_t off; + int i; + + re->ar = re->elf; + + if (re->options & RE_C) { + if ((arsym = elf_getarsym(re->ar, &sz)) == NULL) { + warnx("elf_getarsym() failed: %s", elf_errmsg(-1)); + goto process_members; + } + printf("Index of archive %s: (%ju entries)\n", re->filename, + (uintmax_t) sz - 1); + off = 0; + for (i = 0; (size_t) i < sz; i++) { + if (arsym[i].as_name == NULL) + break; + if (arsym[i].as_off != off) { + off = arsym[i].as_off; + if (elf_rand(re->ar, off) != off) { + warnx("elf_rand() failed: %s", + elf_errmsg(-1)); + continue; + } + if ((e = elf_begin(fd, ELF_C_READ, re->ar)) == + NULL) { + warnx("elf_begin() failed: %s", + elf_errmsg(-1)); + continue; + } + if ((arhdr = elf_getarhdr(e)) == NULL) { + warnx("elf_getarhdr() failed: %s", + elf_errmsg(-1)); + elf_end(e); + continue; + } + printf("Binary %s(%s) contains:\n", + re->filename, arhdr->ar_name); + } + printf("\t%s\n", arsym[i].as_name); + } + if (elf_rand(re->ar, SARMAG) != SARMAG) { + warnx("elf_rand() failed: %s", elf_errmsg(-1)); + return; + } + } + +process_members: + + if ((re->options & ~RE_C) == 0) + return; + + cmd = ELF_C_READ; + while ((re->elf = elf_begin(fd, cmd, re->ar)) != NULL) { + if ((arhdr = elf_getarhdr(re->elf)) == NULL) { + warnx("elf_getarhdr() failed: %s", elf_errmsg(-1)); + goto next_member; + } + if (strcmp(arhdr->ar_name, "/") == 0 || + strcmp(arhdr->ar_name, "//") == 0 || + strcmp(arhdr->ar_name, "__.SYMDEF") == 0) + goto next_member; + printf("\nFile: %s(%s)\n", re->filename, arhdr->ar_name); + dump_elf(re); + + next_member: + cmd = elf_next(re->elf); + elf_end(re->elf); + } + re->elf = re->ar; +} + +static void +dump_object(struct readelf *re, int fd) +{ + if ((re->flags & DISPLAY_FILENAME) != 0) + printf("\nFile: %s\n", re->filename); + + if ((re->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warnx("elf_begin() failed: %s", elf_errmsg(-1)); + goto done; + } + + switch (elf_kind(re->elf)) { + case ELF_K_NONE: + warnx("Not an ELF file."); + goto done; + case ELF_K_ELF: + dump_elf(re); + break; + case ELF_K_AR: + dump_ar(re, fd); + break; + default: + warnx("Internal: libelf returned unknown elf kind."); + } + +done: + elf_end(re->elf); +} + +static void +add_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) +{ + struct dumpop *d; + + if ((d = find_dumpop(re, si, sn, -1, t)) == NULL) { + if ((d = calloc(1, sizeof(*d))) == NULL) + err(EXIT_FAILURE, "calloc failed"); + if (t == DUMP_BY_INDEX) + d->u.si = si; + else + d->u.sn = sn; + d->type = t; + d->op = op; + STAILQ_INSERT_TAIL(&re->v_dumpop, d, dumpop_list); + } else + d->op |= op; +} + +static struct dumpop * +find_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) +{ + struct dumpop *d; + + STAILQ_FOREACH(d, &re->v_dumpop, dumpop_list) { + if ((op == -1 || op & d->op) && + (t == -1 || (unsigned) t == d->type)) { + if ((d->type == DUMP_BY_INDEX && d->u.si == si) || + (d->type == DUMP_BY_NAME && !strcmp(d->u.sn, sn))) + return (d); + } + } + + return (NULL); +} + +static struct { + const char *ln; + char sn; + int value; +} dwarf_op[] = { + {"rawline", 'l', DW_L}, + {"decodedline", 'L', DW_LL}, + {"info", 'i', DW_I}, + {"abbrev", 'a', DW_A}, + {"pubnames", 'p', DW_P}, + {"aranges", 'r', DW_R}, + {"ranges", 'r', DW_R}, + {"Ranges", 'R', DW_RR}, + {"macro", 'm', DW_M}, + {"frames", 'f', DW_F}, + {"frames-interp", 'F', DW_FF}, + {"str", 's', DW_S}, + {"loc", 'o', DW_O}, + {NULL, 0, 0} +}; + +static void +parse_dwarf_op_short(struct readelf *re, const char *op) +{ + int i; + + if (op == NULL) { + re->dop |= DW_DEFAULT_OPTIONS; + return; + } + + for (; *op != '\0'; op++) { + for (i = 0; dwarf_op[i].ln != NULL; i++) { + if (dwarf_op[i].sn == *op) { + re->dop |= dwarf_op[i].value; + break; + } + } + } +} + +static void +parse_dwarf_op_long(struct readelf *re, const char *op) +{ + char *p, *token, *bp; + int i; + + if (op == NULL) { + re->dop |= DW_DEFAULT_OPTIONS; + return; + } + + if ((p = strdup(op)) == NULL) + err(EXIT_FAILURE, "strdup failed"); + bp = p; + + while ((token = strsep(&p, ",")) != NULL) { + for (i = 0; dwarf_op[i].ln != NULL; i++) { + if (!strcmp(token, dwarf_op[i].ln)) { + re->dop |= dwarf_op[i].value; + break; + } + } + } + + free(bp); +} + +static uint64_t +_read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = (uint8_t *) d->d_buf + *offsetp; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ + case 4: + ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ + case 2: + ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +static uint64_t +_read_msb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = (uint8_t *) d->d_buf + *offsetp; + + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +static uint64_t +_decode_lsb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ + case 4: + ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ + case 2: + ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *data += bytes_to_read; + + return (ret); +} + +static uint64_t +_decode_msb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + break; + } + + *data += bytes_to_read; + + return (ret); +} + +static int64_t +_decode_sleb128(uint8_t **dp, uint8_t *dpe) +{ + int64_t ret = 0; + uint8_t b = 0; + int shift = 0; + + uint8_t *src = *dp; + + do { + if (src >= dpe) + break; + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 32 && (b & 0x40) != 0) + ret |= (~0UL << shift); + + *dp = src; + + return (ret); +} + +static uint64_t +_decode_uleb128(uint8_t **dp, uint8_t *dpe) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + if (src >= dpe) + break; + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + *dp = src; + + return (ret); +} + +static void +readelf_version(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), + elftc_version()); + exit(EXIT_SUCCESS); +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] file...\n\ + Display information about ELF objects and ar(1) archives.\n\n\ + Options:\n\ + -a | --all Equivalent to specifying options '-dhIlrsASV'.\n\ + -c | --archive-index Print the archive symbol table for archives.\n\ + -d | --dynamic Print the contents of SHT_DYNAMIC sections.\n\ + -e | --headers Print all headers in the object.\n\ + -g | --section-groups Print the contents of the section groups.\n\ + -h | --file-header Print the file header for the object.\n\ + -l | --program-headers Print the PHDR table for the object.\n\ + -n | --notes Print the contents of SHT_NOTE sections.\n\ + -p INDEX | --string-dump=INDEX\n\ + Print the contents of section at index INDEX.\n\ + -r | --relocs Print relocation information.\n\ + -s | --syms | --symbols Print symbol tables.\n\ + -t | --section-details Print additional information about sections.\n\ + -v | --version Print a version identifier and exit.\n\ + -w[afilmoprsFLR] | --debug-dump={abbrev,aranges,decodedline,frames,\n\ + frames-interp,info,loc,macro,pubnames,\n\ + ranges,Ranges,rawline,str}\n\ + Display DWARF information.\n\ + -x INDEX | --hex-dump=INDEX\n\ + Display contents of a section as hexadecimal.\n\ + -A | --arch-specific (accepted, but ignored)\n\ + -D | --use-dynamic Print the symbol table specified by the DT_SYMTAB\n\ + entry in the \".dynamic\" section.\n\ + -H | --help Print a help message.\n\ + -I | --histogram Print information on bucket list lengths for \n\ + hash sections.\n\ + -N | --full-section-name (accepted, but ignored)\n\ + -S | --sections | --section-headers\n\ + Print information about section headers.\n\ + -V | --version-info Print symbol versoning information.\n\ + -W | --wide Print information without wrapping long lines.\n" + + +static void +readelf_usage(int exit_code) +{ + fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +int +main(int argc, char **argv) +{ + struct readelf *re, re_storage; + unsigned long si; + int fd, opt, i; + char *ep; + + re = &re_storage; + memset(re, 0, sizeof(*re)); + STAILQ_INIT(&re->v_dumpop); + + while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:", + longopts, NULL)) != -1) { + switch(opt) { + case '?': + readelf_usage(EX_OK); + break; + case 'A': + re->options |= RE_AA; + break; + case 'a': + re->options |= RE_AA | RE_D | RE_G | RE_H | RE_II | + RE_L | RE_R | RE_SS | RE_S | RE_VV; + break; + case 'c': + re->options |= RE_C; + break; + case 'D': + re->options |= RE_DD; + break; + case 'd': + re->options |= RE_D; + break; + case 'e': + re->options |= RE_H | RE_L | RE_SS; + break; + case 'g': + re->options |= RE_G; + break; + case 'H': + readelf_usage(EX_OK); + break; + case 'h': + re->options |= RE_H; + break; + case 'I': + re->options |= RE_II; + break; + case 'i': + /* Not implemented yet. */ + break; + case 'l': + re->options |= RE_L; + break; + case 'N': + re->options |= RE_NN; + break; + case 'n': + re->options |= RE_N; + break; + case 'p': + re->options |= RE_P; + si = strtoul(optarg, &ep, 10); + if (*ep == '\0') + add_dumpop(re, (size_t) si, NULL, STR_DUMP, + DUMP_BY_INDEX); + else + add_dumpop(re, 0, optarg, STR_DUMP, + DUMP_BY_NAME); + break; + case 'r': + re->options |= RE_R; + break; + case 'S': + re->options |= RE_SS; + break; + case 's': + re->options |= RE_S; + break; + case 't': + re->options |= RE_SS | RE_T; + break; + case 'u': + re->options |= RE_U; + break; + case 'V': + re->options |= RE_VV; + break; + case 'v': + readelf_version(); + break; + case 'W': + re->options |= RE_WW; + break; + case 'w': + re->options |= RE_W; + parse_dwarf_op_short(re, optarg); + break; + case 'x': + re->options |= RE_X; + si = strtoul(optarg, &ep, 10); + if (*ep == '\0') + add_dumpop(re, (size_t) si, NULL, HEX_DUMP, + DUMP_BY_INDEX); + else + add_dumpop(re, 0, optarg, HEX_DUMP, + DUMP_BY_NAME); + break; + case OPTION_DEBUG_DUMP: + re->options |= RE_W; + parse_dwarf_op_long(re, optarg); + } + } + + argv += optind; + argc -= optind; + + if (argc == 0 || re->options == 0) + readelf_usage(EX_USAGE); + + if (argc > 1) + re->flags |= DISPLAY_FILENAME; + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + for (i = 0; i < argc; i++) { + re->filename = argv[i]; + fd = open(re->filename, O_RDONLY); + if (fd < 0) { + warn("open %s failed", re->filename); + } else { + dump_object(re, fd); + close(fd); + } + } + + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/size/Makefile b/contrib/elftoolchain/size/Makefile new file mode 100644 index 0000000000..6d46d634d4 --- /dev/null +++ b/contrib/elftoolchain/size/Makefile @@ -0,0 +1,11 @@ +# $Id: Makefile 2043 2011-10-23 14:49:16Z jkoshy $ + +TOP= .. + +PROG= size +WARNS?= 6 +LDADD= -lelftc -lelf +DPADD= ${LIBELFTC} ${LIBELF} + +.include "${TOP}/mk/elftoolchain.prog.mk" + diff --git a/contrib/elftoolchain/size/os.NetBSD.mk b/contrib/elftoolchain/size/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/size/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/size/size.1 b/contrib/elftoolchain/size/size.1 new file mode 100644 index 0000000000..97f76c250d --- /dev/null +++ b/contrib/elftoolchain/size/size.1 @@ -0,0 +1,257 @@ +.\" Copyright (c) 2007 S.Sam Arun Raj +.\" Copyright (c) 2008,2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: size.1 3195 2015-05-12 17:22:19Z emaste $ +.\" +.Dd August 25, 2011 +.Dt SIZE 1 +.Os +.Sh NAME +.Nm size +.Nd "display section sizes and total size of ELF objects" +.Sh SYNOPSIS +.Nm +.Op Fl -format= Ns Ar format +.Op Fl -help +.Op Fl -radix= Ns Ar radix +.Op Fl -totals +.Op Fl -version +.Op Fl ABVdhotx +.Op Ar +.Sh DESCRIPTION +The +.Nm +utility +lists the sizes of ELF sections, and optionally the total size, for +each input +.Ar file +specified on the command line. +The +.Nm +utility can operate on ELF objects, on +.Xr ar 1 +archives containing ELF objects, and on core dumps. +If no file name is specified on the command-line, +.Pa a.out +is assumed. +.Pp +The +.Nm +utility recognized the following options: +.Bl -tag -width indent +.It Fl -format= Ns Ar format +Display output using the format specified by argument +.Ar format . +Supported values for this argument are: +.Sq berkeley +and +.Sq sysv . +The default output format is +.Sq berkeley . +See +.Sx Display Formats +below for more information. +.It Fl -help +Display a help message and exit. +.It Fl -radix= Ns Ar radix +Display numeric values using the radix specified by argument +.Ar radix . +Supported values for +.Ar radix +are 8, 10 and 16. +The default radix is 10. +.It Fl -totals +Shows cumulative totals of section sizes from all objects. +This option is ignored for System V style output. +.It Fl -version +Display a version identifier and exit. +.It Fl A +Equivalent to specifying option +.Fl -format= Ns Ar sysv . +.It Fl B +Equivalent to specifying option +.Fl -format= Ns Ar berkeley . +.It Fl V +Equivalent to specifying option +.Fl -version . +.It Fl d +Equivalent to specifying option +.Fl -radix= Ns Ar 10 . +.It Fl h +Equivalent to specifying option +.Fl -help . +.It Fl o +Equivalent to specifying option +.Fl -radix= Ns Ar 8 . +.It Fl t +Equivalent to specifying option +.Fl -totals . +.It Fl x +Equivalent to specifying option +.Fl -radix= Ns Ar 16 . +.El +.Sh DISPLAY FORMATS +.Ss Berkeley Style Output +If +.Sq berkeley +style output is in effect, an initial header line naming fields will +be output, followed by one line of output for each ELF object specified +on the command line or found in an archive. +.Pp +Each line will contain the following whitespace separated fields +in order: +.Bl -enum -compact +.It +The size of the text segment in the object. +.It +The size of the data segment in the object. +.It +The size of the +.Sq bss +segment in the object. +.It +The total size of the object in either decimal or octal. +Decimal output is used if the specified output radix for numeric values +is 10 or 16. +Octal output is used if the radix being used for numeric values +is 8. +.It +The total size of the object in hexadecimal. +.It +The file name of the object. +.El +.Pp +If option +.Fl -totals +was specified, an additional line in the same format as above will be +output at the end containing the sum of the respective fields. +The file name field for the line will contain the string +.Sq (TOTALS) . +.Ss System V Style Output +If System V style output is selected, +.Nm +will output the following information for each object: +.Bl -enum -compact +.It +The name of the object followed by a colon. +.It +A header line containing the names of fields of subsequent lines. +.It +One line per section present in the object. +Each line has three fields: +.Bl -enum -compact +.It +The name of the section. +.It +Its size, in the selected radix for numeric values. +.It +The address associated with the section, in the selected numeric radix. +.El +.It +A line whose section name field contains the string +.Sq Total +and whose size field contains the sum of all reported section sizes. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +To display the section sizes for +.Pa /bin/ls +use: +.Bd -literal +$ size /bin/ls +text data bss dec hex filename +20975 540 392 21907 5593 /bin/ls +.Ed +.Pp +To display sizes and total for +.Pa /bin/ls +and +.Pa /bin/dd +in hexadecimal, use: +.Bd -literal +$ size -tx /bin/ls /bin/dd +text data bss dec hex filename +0x51ef 0x21c 0x188 21907 5593 /bin/ls +0x3df5 0x170 0x200 16741 4165 /bin/dd +0x8fe4 0x38c 0x388 38648 96f8 (TOTALS) +.Ed +.Pp +To display section sizes for +.Pa /bin/ls +in System V format use: +.Bd -literal +$ size -A /bin/ls +/bin/ls : +section size addr +\&.interp 21 4194704 +\&.note.ABI-tag 24 4194728 +\&.hash 624 4194752 +\&.dynsym 2088 4195376 +\&.dynstr 810 4197464 +\&.rela.dyn 120 4198280 +\&.rela.plt 1656 4198400 +\&.init 19 4200056 +\&.plt 1120 4200076 +\&.text 15224 4201200 +\&.fini 14 4216424 +\&.rodata 1472 4216448 +\&.data 80 5267456 +\&.eh_frame 1624 5267536 +\&.dynamic 384 5269160 +\&.ctors 16 5269544 +\&.dtors 16 5269560 +\&.jcr 8 5269576 +\&.got 576 5269584 +\&.bss 528 5270176 +\&.comment 686 0 +Total 27110 +.Ed +.Sh SEE ALSO +.Xr ar 1 , +.Xr nm 1 , +.Xr objdump 1 , +.Xr readelf 1 , +.Xr strings 1 , +.Xr elf 3 , +.Xr gelf 3 +.Rs +.%A "AT&T Unix Systems Labs" +.%T "System V Application Binary Interface" +.%O http://www.sco.com/developers/gabi/ +.Re +.Sh HISTORY +The +.Nm +utility first appeared in +.At v6 . +.Sh AUTHORS +.An -nosplit +The +.Nm +utility was re-written by +.An S. Sam Arun Raj Aq Mt samarunraj@gmail.com +This manual page was written by +.An S. Sam Arun Raj Aq Mt samarunraj@gmail.com diff --git a/contrib/elftoolchain/size/size.c b/contrib/elftoolchain/size/size.c new file mode 100644 index 0000000000..1c23da550d --- /dev/null +++ b/contrib/elftoolchain/size/size.c @@ -0,0 +1,929 @@ +/*- + * Copyright (c) 2007 S.Sam Arun Raj + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: size.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +#define BUF_SIZE 1024 +#define ELF_ALIGN(val,x) (((val)+(x)-1) & ~((x)-1)) +#define SIZE_VERSION_STRING "size 1.0" + +enum return_code { + RETURN_OK, + RETURN_NOINPUT, + RETURN_DATAERR, + RETURN_USAGE +}; + +enum output_style { + STYLE_BERKELEY, + STYLE_SYSV +}; + +enum radix_style { + RADIX_OCTAL, + RADIX_DECIMAL, + RADIX_HEX +}; + +static uint64_t bss_size, data_size, text_size, total_size; +static uint64_t bss_size_total, data_size_total, text_size_total; +static int show_totals; +static int size_option; +static enum radix_style radix = RADIX_DECIMAL; +static enum output_style style = STYLE_BERKELEY; +static const char *default_args[2] = { "a.out", NULL }; + +static struct { + int row; + int col; + int *width; + char ***tbl; +} *tb; + +enum { + OPT_FORMAT, + OPT_RADIX +}; + +static struct option size_longopts[] = { + { "format", required_argument, &size_option, OPT_FORMAT }, + { "help", no_argument, NULL, 'h' }, + { "radix", required_argument, &size_option, OPT_RADIX }, + { "totals", no_argument, NULL, 't' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } +}; + +static void berkeley_calc(GElf_Shdr *); +static void berkeley_footer(const char *, const char *, const char *); +static void berkeley_header(void); +static void berkeley_totals(void); +static int handle_core(char const *, Elf *elf, GElf_Ehdr *); +static void handle_core_note(Elf *, GElf_Ehdr *, GElf_Phdr *, char **); +static int handle_elf(char const *); +static void handle_phdr(Elf *, GElf_Ehdr *, GElf_Phdr *, uint32_t, + const char *); +static void show_version(void); +static void sysv_header(const char *, Elf_Arhdr *); +static void sysv_footer(void); +static void sysv_calc(Elf *, GElf_Ehdr *, GElf_Shdr *); +static void usage(int); +static void tbl_new(int); +static void tbl_print(const char *, int); +static void tbl_print_num(uint64_t, enum radix_style, int); +static void tbl_append(void); +static void tbl_flush(void); + +/* + * size utility using elf(3) and gelf(3) API to list section sizes and + * total in elf files. Supports only elf files (core dumps in elf + * included) that can be opened by libelf, other formats are not supported. + */ +int +main(int argc, char **argv) +{ + int ch, r, rc; + const char **files, *fn; + + rc = RETURN_OK; + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + while ((ch = getopt_long(argc, argv, "ABVdhotx", size_longopts, + NULL)) != -1) + switch((char)ch) { + case 'A': + style = STYLE_SYSV; + break; + case 'B': + style = STYLE_BERKELEY; + break; + case 'V': + show_version(); + break; + case 'd': + radix = RADIX_DECIMAL; + break; + case 'o': + radix = RADIX_OCTAL; + break; + case 't': + show_totals = 1; + break; + case 'x': + radix = RADIX_HEX; + break; + case 0: + switch (size_option) { + case OPT_FORMAT: + if (*optarg == 's' || *optarg == 'S') + style = STYLE_SYSV; + else if (*optarg == 'b' || *optarg == 'B') + style = STYLE_BERKELEY; + else { + warnx("unrecognized format \"%s\".", + optarg); + usage(EX_USAGE); + } + break; + case OPT_RADIX: + r = strtol(optarg, NULL, 10); + if (r == 8) + radix = RADIX_OCTAL; + else if (r == 10) + radix = RADIX_DECIMAL; + else if (r == 16) + radix = RADIX_HEX; + else { + warnx("unsupported radix \"%s\".", + optarg); + usage(EX_USAGE); + } + break; + default: + err(EXIT_FAILURE, "Error in option handling."); + /*NOTREACHED*/ + } + break; + case 'h': + usage(EX_OK); + break; + case '?': + default: + usage(EX_USAGE); + break; + } + argc -= optind; + argv += optind; + + files = (argc == 0) ? default_args : (void *) argv; + + while ((fn = *files) != NULL) { + rc = handle_elf(fn); + if (rc != RETURN_OK) + warnx(rc == RETURN_NOINPUT ? + "'%s': No such file" : + "%s: File format not recognized", fn); + files++; + } + if (style == STYLE_BERKELEY) { + if (show_totals) + berkeley_totals(); + tbl_flush(); + } + return (rc); +} + +static int +xlatetom(Elf *elf, GElf_Ehdr *elfhdr, void *_src, void *_dst, + Elf_Type type, size_t size) +{ + Elf_Data src, dst; + + src.d_buf = _src; + src.d_type = type; + src.d_version = elfhdr->e_version; + src.d_size = size; + dst.d_buf = _dst; + dst.d_version = elfhdr->e_version; + dst.d_size = size; + return (gelf_xlatetom(elf, &dst, &src, elfhdr->e_ident[EI_DATA]) != + NULL ? 0 : 1); +} + +#define NOTE_OFFSET_32(nhdr, namesz, offset) \ + ((char *)nhdr + sizeof(Elf32_Nhdr) + \ + ELF_ALIGN((int32_t)namesz, 4) + offset) + +#define NOTE_OFFSET_64(nhdr, namesz, offset) \ + ((char *)nhdr + sizeof(Elf32_Nhdr) + \ + ELF_ALIGN((int32_t)namesz, 8) + offset) + +#define PID32(nhdr, namesz, offset) \ + (pid_t)*((int *)((uintptr_t)NOTE_OFFSET_32(nhdr, \ + namesz, offset))); + +#define PID64(nhdr, namesz, offset) \ + (pid_t)*((int *)((uintptr_t)NOTE_OFFSET_64(nhdr, \ + namesz, offset))); + +#define NEXT_NOTE(elfhdr, descsz, namesz, offset) do { \ + if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) { \ + offset += ELF_ALIGN((int32_t)descsz, 4) + \ + sizeof(Elf32_Nhdr) + \ + ELF_ALIGN((int32_t)namesz, 4); \ + } else { \ + offset += ELF_ALIGN((int32_t)descsz, 8) + \ + sizeof(Elf32_Nhdr) + \ + ELF_ALIGN((int32_t)namesz, 8); \ + } \ +} while (0) + +/* + * Parse individual note entries inside a PT_NOTE segment. + */ +static void +handle_core_note(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr, + char **cmd_line) +{ + size_t max_size, segment_end; + uint64_t raw_size; + GElf_Off offset; + static pid_t pid; + uintptr_t ver; + Elf32_Nhdr *nhdr, nhdr_l; + static int reg_pseudo = 0, reg2_pseudo = 0, regxfp_pseudo = 0; + char buf[BUF_SIZE], *data, *name; + + if (elf == NULL || elfhdr == NULL || phdr == NULL) + return; + + data = elf_rawfile(elf, &max_size); + offset = phdr->p_offset; + if (offset >= max_size || phdr->p_filesz > max_size - offset) { + warnx("invalid PHDR offset"); + return; + } + segment_end = phdr->p_offset + phdr->p_filesz; + + while (data != NULL && offset + sizeof(Elf32_Nhdr) < segment_end) { + nhdr = (Elf32_Nhdr *)(uintptr_t)((char*)data + offset); + memset(&nhdr_l, 0, sizeof(Elf32_Nhdr)); + if (xlatetom(elf, elfhdr, &nhdr->n_type, &nhdr_l.n_type, + ELF_T_WORD, sizeof(Elf32_Word)) != 0 || + xlatetom(elf, elfhdr, &nhdr->n_descsz, &nhdr_l.n_descsz, + ELF_T_WORD, sizeof(Elf32_Word)) != 0 || + xlatetom(elf, elfhdr, &nhdr->n_namesz, &nhdr_l.n_namesz, + ELF_T_WORD, sizeof(Elf32_Word)) != 0) + break; + + if (offset + sizeof(Elf32_Nhdr) + + ELF_ALIGN(nhdr_l.n_namesz, 4) + + ELF_ALIGN(nhdr_l.n_descsz, 4) >= segment_end) { + warnx("invalid note header"); + return; + } + + name = (char *)((char *)nhdr + sizeof(Elf32_Nhdr)); + switch (nhdr_l.n_type) { + case NT_PRSTATUS: { + raw_size = 0; + if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD && + nhdr_l.n_namesz == 0x8 && + !strcmp(name,"FreeBSD")) { + if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) { + raw_size = (uint64_t)*((uint32_t *) + (uintptr_t)(name + + ELF_ALIGN((int32_t) + nhdr_l.n_namesz, 4) + 8)); + ver = (uintptr_t)NOTE_OFFSET_32(nhdr, + nhdr_l.n_namesz,0); + if (*((int *)ver) == 1) + pid = PID32(nhdr, + nhdr_l.n_namesz, 24); + } else { + raw_size = *((uint64_t *)(uintptr_t) + (name + ELF_ALIGN((int32_t) + nhdr_l.n_namesz, 8) + 16)); + ver = (uintptr_t)NOTE_OFFSET_64(nhdr, + nhdr_l.n_namesz,0); + if (*((int *)ver) == 1) + pid = PID64(nhdr, + nhdr_l.n_namesz, 40); + } + (void)xlatetom(elf, elfhdr, &raw_size, + &raw_size, ELF_T_WORD, sizeof(uint64_t)); + (void)xlatetom(elf, elfhdr, &pid, &pid, + ELF_T_WORD, sizeof(pid_t)); + } + + if (raw_size != 0 && style == STYLE_SYSV) { + (void) snprintf(buf, BUF_SIZE, "%s/%d", + ".reg", pid); + tbl_append(); + tbl_print(buf, 0); + tbl_print_num(raw_size, radix, 1); + tbl_print_num(0, radix, 2); + if (!reg_pseudo) { + tbl_append(); + tbl_print(".reg", 0); + tbl_print_num(raw_size, radix, 1); + tbl_print_num(0, radix, 2); + reg_pseudo = 1; + text_size_total += raw_size; + } + text_size_total += raw_size; + } + } + break; + case NT_FPREGSET: /* same as NT_PRFPREG */ + if (style == STYLE_SYSV) { + (void) snprintf(buf, BUF_SIZE, + "%s/%d", ".reg2", pid); + tbl_append(); + tbl_print(buf, 0); + tbl_print_num(nhdr_l.n_descsz, radix, 1); + tbl_print_num(0, radix, 2); + if (!reg2_pseudo) { + tbl_append(); + tbl_print(".reg2", 0); + tbl_print_num(nhdr_l.n_descsz, radix, + 1); + tbl_print_num(0, radix, 2); + reg2_pseudo = 1; + text_size_total += nhdr_l.n_descsz; + } + text_size_total += nhdr_l.n_descsz; + } + break; + case NT_AUXV: + if (style == STYLE_SYSV) { + tbl_append(); + tbl_print(".auxv", 0); + tbl_print_num(nhdr_l.n_descsz, radix, 1); + tbl_print_num(0, radix, 2); + text_size_total += nhdr_l.n_descsz; + } + break; + case NT_PRXFPREG: + if (style == STYLE_SYSV) { + (void) snprintf(buf, BUF_SIZE, "%s/%d", + ".reg-xfp", pid); + tbl_append(); + tbl_print(buf, 0); + tbl_print_num(nhdr_l.n_descsz, radix, 1); + tbl_print_num(0, radix, 2); + if (!regxfp_pseudo) { + tbl_append(); + tbl_print(".reg-xfp", 0); + tbl_print_num(nhdr_l.n_descsz, radix, + 1); + tbl_print_num(0, radix, 2); + regxfp_pseudo = 1; + text_size_total += nhdr_l.n_descsz; + } + text_size_total += nhdr_l.n_descsz; + } + break; + case NT_PSINFO: + case NT_PRPSINFO: { + /* FreeBSD 64-bit */ + if (nhdr_l.n_descsz == 0x78 && + !strcmp(name,"FreeBSD")) { + *cmd_line = strdup(NOTE_OFFSET_64(nhdr, + nhdr_l.n_namesz, 33)); + /* FreeBSD 32-bit */ + } else if (nhdr_l.n_descsz == 0x6c && + !strcmp(name,"FreeBSD")) { + *cmd_line = strdup(NOTE_OFFSET_32(nhdr, + nhdr_l.n_namesz, 25)); + } + /* Strip any trailing spaces */ + if (*cmd_line != NULL) { + char *s; + + s = *cmd_line + strlen(*cmd_line); + while (s > *cmd_line) { + if (*(s-1) != 0x20) break; + s--; + } + *s = 0; + } + break; + } + case NT_PSTATUS: + case NT_LWPSTATUS: + default: + break; + } + NEXT_NOTE(elfhdr, nhdr_l.n_descsz, nhdr_l.n_namesz, offset); + } +} + +/* + * Handles program headers except for PT_NOTE, when sysv output style is + * chosen, prints out the segment name and length. For berkely output + * style only PT_LOAD segments are handled, and text, + * data, bss size is calculated for them. + */ +static void +handle_phdr(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr, + uint32_t idx, const char *name) +{ + uint64_t addr, size; + int split; + char buf[BUF_SIZE]; + + if (elf == NULL || elfhdr == NULL || phdr == NULL) + return; + + split = (phdr->p_memsz > 0) && (phdr->p_filesz > 0) && + (phdr->p_memsz > phdr->p_filesz); + + if (style == STYLE_SYSV) { + (void) snprintf(buf, BUF_SIZE, + "%s%d%s", name, idx, (split ? "a" : "")); + tbl_append(); + tbl_print(buf, 0); + tbl_print_num(phdr->p_filesz, radix, 1); + tbl_print_num(phdr->p_vaddr, radix, 2); + text_size_total += phdr->p_filesz; + if (split) { + size = phdr->p_memsz - phdr->p_filesz; + addr = phdr->p_vaddr + phdr->p_filesz; + (void) snprintf(buf, BUF_SIZE, "%s%d%s", name, + idx, "b"); + text_size_total += phdr->p_memsz - phdr->p_filesz; + tbl_append(); + tbl_print(buf, 0); + tbl_print_num(size, radix, 1); + tbl_print_num(addr, radix, 2); + } + } else { + if (phdr->p_type != PT_LOAD) + return; + if ((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X)) { + data_size += phdr->p_filesz; + if (split) + data_size += phdr->p_memsz - phdr->p_filesz; + } else { + text_size += phdr->p_filesz; + if (split) + text_size += phdr->p_memsz - phdr->p_filesz; + } + } +} + +/* + * Given a core dump file, this function maps program headers to segments. + */ +static int +handle_core(char const *name, Elf *elf, GElf_Ehdr *elfhdr) +{ + GElf_Phdr phdr; + uint32_t i; + char *core_cmdline; + const char *seg_name; + + if (name == NULL || elf == NULL || elfhdr == NULL) + return (RETURN_DATAERR); + if (elfhdr->e_shnum != 0 || elfhdr->e_type != ET_CORE) + return (RETURN_DATAERR); + + seg_name = core_cmdline = NULL; + if (style == STYLE_SYSV) + sysv_header(name, NULL); + else + berkeley_header(); + + for (i = 0; i < elfhdr->e_phnum; i++) { + if (gelf_getphdr(elf, i, &phdr) != NULL) { + if (phdr.p_type == PT_NOTE) { + handle_phdr(elf, elfhdr, &phdr, i, "note"); + handle_core_note(elf, elfhdr, &phdr, + &core_cmdline); + } else { + switch(phdr.p_type) { + case PT_NULL: + seg_name = "null"; + break; + case PT_LOAD: + seg_name = "load"; + break; + case PT_DYNAMIC: + seg_name = "dynamic"; + break; + case PT_INTERP: + seg_name = "interp"; + break; + case PT_SHLIB: + seg_name = "shlib"; + break; + case PT_PHDR: + seg_name = "phdr"; + break; + case PT_GNU_EH_FRAME: + seg_name = "eh_frame_hdr"; + break; + case PT_GNU_STACK: + seg_name = "stack"; + break; + default: + seg_name = "segment"; + } + handle_phdr(elf, elfhdr, &phdr, i, seg_name); + } + } + } + + if (style == STYLE_BERKELEY) { + if (core_cmdline != NULL) { + berkeley_footer(core_cmdline, name, + "core file invoked as"); + } else { + berkeley_footer(core_cmdline, name, "core file"); + } + } else { + sysv_footer(); + if (core_cmdline != NULL) { + (void) printf(" (core file invoked as %s)\n\n", + core_cmdline); + } else { + (void) printf(" (core file)\n\n"); + } + } + free(core_cmdline); + return (RETURN_OK); +} + +/* + * Given an elf object,ar(1) filename, and based on the output style + * and radix format the various sections and their length will be printed + * or the size of the text, data, bss sections will be printed out. + */ +static int +handle_elf(char const *name) +{ + GElf_Ehdr elfhdr; + GElf_Shdr shdr; + Elf *elf, *elf1; + Elf_Arhdr *arhdr; + Elf_Scn *scn; + Elf_Cmd elf_cmd; + int exit_code, fd; + + if (name == NULL) + return (RETURN_NOINPUT); + + if ((fd = open(name, O_RDONLY, 0)) < 0) + return (RETURN_NOINPUT); + + elf_cmd = ELF_C_READ; + elf1 = elf_begin(fd, elf_cmd, NULL); + while ((elf = elf_begin(fd, elf_cmd, elf1)) != NULL) { + arhdr = elf_getarhdr(elf); + if (elf_kind(elf) == ELF_K_NONE && arhdr == NULL) { + (void) elf_end(elf); + (void) elf_end(elf1); + (void) close(fd); + return (RETURN_DATAERR); + } + if (elf_kind(elf) != ELF_K_ELF || + (gelf_getehdr(elf, &elfhdr) == NULL)) { + elf_cmd = elf_next(elf); + (void) elf_end(elf); + warnx("%s: File format not recognized", + arhdr != NULL ? arhdr->ar_name : name); + continue; + } + /* Core dumps are handled separately */ + if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { + exit_code = handle_core(name, elf, &elfhdr); + (void) elf_end(elf); + (void) elf_end(elf1); + (void) close(fd); + return (exit_code); + } else { + scn = NULL; + if (style == STYLE_BERKELEY) { + berkeley_header(); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != NULL) + berkeley_calc(&shdr); + } + } else { + sysv_header(name, arhdr); + scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != NULL) + sysv_calc(elf, &elfhdr, &shdr); + } + } + if (style == STYLE_BERKELEY) { + if (arhdr != NULL) { + berkeley_footer(name, arhdr->ar_name, + "ex"); + } else { + berkeley_footer(name, NULL, "ex"); + } + } else { + sysv_footer(); + } + } + elf_cmd = elf_next(elf); + (void) elf_end(elf); + } + (void) elf_end(elf1); + (void) close(fd); + return (RETURN_OK); +} + +/* + * Sysv formatting helper functions. + */ +static void +sysv_header(const char *name, Elf_Arhdr *arhdr) +{ + + text_size_total = 0; + if (arhdr != NULL) + (void) printf("%s (ex %s):\n", arhdr->ar_name, name); + else + (void) printf("%s :\n", name); + tbl_new(3); + tbl_append(); + tbl_print("section", 0); + tbl_print("size", 1); + tbl_print("addr", 2); +} + +static void +sysv_calc(Elf *elf, GElf_Ehdr *elfhdr, GElf_Shdr *shdr) +{ + char *section_name; + + section_name = elf_strptr(elf, elfhdr->e_shstrndx, + (size_t) shdr->sh_name); + if ((shdr->sh_type == SHT_SYMTAB || + shdr->sh_type == SHT_STRTAB || shdr->sh_type == SHT_RELA || + shdr->sh_type == SHT_REL) && shdr->sh_addr == 0) + return; + tbl_append(); + tbl_print(section_name, 0); + tbl_print_num(shdr->sh_size, radix, 1); + tbl_print_num(shdr->sh_addr, radix, 2); + text_size_total += shdr->sh_size; +} + +static void +sysv_footer(void) +{ + tbl_append(); + tbl_print("Total", 0); + tbl_print_num(text_size_total, radix, 1); + tbl_flush(); + putchar('\n'); +} + +/* + * berkeley style output formatting helper functions. + */ +static void +berkeley_header(void) +{ + static int printed; + + text_size = data_size = bss_size = 0; + if (!printed) { + tbl_new(6); + tbl_append(); + tbl_print("text", 0); + tbl_print("data", 1); + tbl_print("bss", 2); + if (radix == RADIX_OCTAL) + tbl_print("oct", 3); + else + tbl_print("dec", 3); + tbl_print("hex", 4); + tbl_print("filename", 5); + printed = 1; + } +} + +static void +berkeley_calc(GElf_Shdr *shdr) +{ + if (shdr != NULL) { + if (!(shdr->sh_flags & SHF_ALLOC)) + return; + if ((shdr->sh_flags & SHF_ALLOC) && + ((shdr->sh_flags & SHF_EXECINSTR) || + !(shdr->sh_flags & SHF_WRITE))) + text_size += shdr->sh_size; + else if ((shdr->sh_flags & SHF_ALLOC) && + (shdr->sh_flags & SHF_WRITE) && + (shdr->sh_type != SHT_NOBITS)) + data_size += shdr->sh_size; + else + bss_size += shdr->sh_size; + } +} + +static void +berkeley_totals(void) +{ + uint64_t grand_total; + + grand_total = text_size_total + data_size_total + bss_size_total; + tbl_append(); + tbl_print_num(text_size_total, radix, 0); + tbl_print_num(data_size_total, radix, 1); + tbl_print_num(bss_size_total, radix, 2); + if (radix == RADIX_OCTAL) + tbl_print_num(grand_total, RADIX_OCTAL, 3); + else + tbl_print_num(grand_total, RADIX_DECIMAL, 3); + tbl_print_num(grand_total, RADIX_HEX, 4); +} + +static void +berkeley_footer(const char *name, const char *ar_name, const char *msg) +{ + char buf[BUF_SIZE]; + + total_size = text_size + data_size + bss_size; + if (show_totals) { + text_size_total += text_size; + bss_size_total += bss_size; + data_size_total += data_size; + } + + tbl_append(); + tbl_print_num(text_size, radix, 0); + tbl_print_num(data_size, radix, 1); + tbl_print_num(bss_size, radix, 2); + if (radix == RADIX_OCTAL) + tbl_print_num(total_size, RADIX_OCTAL, 3); + else + tbl_print_num(total_size, RADIX_DECIMAL, 3); + tbl_print_num(total_size, RADIX_HEX, 4); + if (ar_name != NULL && name != NULL) + (void) snprintf(buf, BUF_SIZE, "%s (%s %s)", ar_name, msg, + name); + else if (ar_name != NULL && name == NULL) + (void) snprintf(buf, BUF_SIZE, "%s (%s)", ar_name, msg); + else + (void) snprintf(buf, BUF_SIZE, "%s", name); + tbl_print(buf, 5); +} + + +static void +tbl_new(int col) +{ + + assert(tb == NULL); + assert(col > 0); + if ((tb = calloc(1, sizeof(*tb))) == NULL) + err(EXIT_FAILURE, "calloc"); + if ((tb->tbl = calloc(col, sizeof(*tb->tbl))) == NULL) + err(EXIT_FAILURE, "calloc"); + if ((tb->width = calloc(col, sizeof(*tb->width))) == NULL) + err(EXIT_FAILURE, "calloc"); + tb->col = col; + tb->row = 0; +} + +static void +tbl_print(const char *s, int col) +{ + int len; + + assert(tb != NULL && tb->col > 0 && tb->row > 0 && col < tb->col); + assert(s != NULL && tb->tbl[col][tb->row - 1] == NULL); + if ((tb->tbl[col][tb->row - 1] = strdup(s)) == NULL) + err(EXIT_FAILURE, "strdup"); + len = strlen(s); + if (len > tb->width[col]) + tb->width[col] = len; +} + +static void +tbl_print_num(uint64_t num, enum radix_style rad, int col) +{ + char buf[BUF_SIZE]; + + (void) snprintf(buf, BUF_SIZE, (rad == RADIX_DECIMAL ? "%ju" : + ((rad == RADIX_OCTAL) ? "0%jo" : "0x%jx")), (uintmax_t) num); + tbl_print(buf, col); +} + +static void +tbl_append(void) +{ + int i; + + assert(tb != NULL && tb->col > 0); + tb->row++; + for (i = 0; i < tb->col; i++) { + tb->tbl[i] = realloc(tb->tbl[i], sizeof(*tb->tbl[i]) * tb->row); + if (tb->tbl[i] == NULL) + err(EXIT_FAILURE, "realloc"); + tb->tbl[i][tb->row - 1] = NULL; + } +} + +static void +tbl_flush(void) +{ + const char *str; + int i, j; + + if (tb == NULL) + return; + + assert(tb->col > 0); + for (i = 0; i < tb->row; i++) { + if (style == STYLE_BERKELEY) + printf(" "); + for (j = 0; j < tb->col; j++) { + str = (tb->tbl[j][i] != NULL ? tb->tbl[j][i] : ""); + if (style == STYLE_SYSV && j == 0) + printf("%-*s", tb->width[j], str); + else if (style == STYLE_BERKELEY && j == tb->col - 1) + printf("%s", str); + else + printf("%*s", tb->width[j], str); + if (j == tb->col -1) + putchar('\n'); + else + printf(" "); + } + } + + for (i = 0; i < tb->col; i++) { + for (j = 0; j < tb->row; j++) { + if (tb->tbl[i][j]) + free(tb->tbl[i][j]); + } + free(tb->tbl[i]); + } + free(tb->tbl); + free(tb->width); + free(tb); + tb = NULL; +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] file ...\n\ + Display sizes of ELF sections.\n\n\ + Options:\n\ + --format=format Display output in specified format. Supported\n\ + values are `berkeley' and `sysv'.\n\ + --help Display this help message and exit.\n\ + --radix=radix Display numeric values in the specified radix.\n\ + Supported values are: 8, 10 and 16.\n\ + --totals Show cumulative totals of section sizes.\n\ + --version Display a version identifier and exit.\n\ + -A Equivalent to `--format=sysv'.\n\ + -B Equivalent to `--format=berkeley'.\n\ + -V Equivalent to `--version'.\n\ + -d Equivalent to `--radix=10'.\n\ + -h Same as option --help.\n\ + -o Equivalent to `--radix=8'.\n\ + -t Equivalent to option --totals.\n\ + -x Equivalent to `--radix=16'.\n" + +static void +usage(int exit_code) +{ + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +static void +show_version(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(EX_OK); +} diff --git a/contrib/elftoolchain/strings/Makefile b/contrib/elftoolchain/strings/Makefile new file mode 100644 index 0000000000..0bc4cd5d97 --- /dev/null +++ b/contrib/elftoolchain/strings/Makefile @@ -0,0 +1,11 @@ +# $Id: Makefile 2044 2011-10-23 14:52:59Z jkoshy $ + +TOP= .. + +PROG= strings +WARNS?= 6 +DPADD= ${LIBELFTC} ${LIBELF} +LDADD= -lelftc -lelf + +.include "${TOP}/mk/elftoolchain.prog.mk" + diff --git a/contrib/elftoolchain/strings/os.NetBSD.mk b/contrib/elftoolchain/strings/os.NetBSD.mk new file mode 100644 index 0000000000..ae214e3115 --- /dev/null +++ b/contrib/elftoolchain/strings/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/contrib/elftoolchain/strings/strings.1 b/contrib/elftoolchain/strings/strings.1 new file mode 100644 index 0000000000..205afdfc45 --- /dev/null +++ b/contrib/elftoolchain/strings/strings.1 @@ -0,0 +1,165 @@ +.\" Copyright (c) 2007 S.Sam Arun Raj +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: strings.1 3360 2016-01-24 18:34:06Z jkoshy $ +.\" +.Dd January 24, 2016 +.Dt STRINGS 1 +.Os +.Sh NAME +.Nm strings +.Nd "print the strings of printable characters in files" +.Sh SYNOPSIS +.Nm +.Op Fl a | Fl -all +.Op Fl e Ar encoding | Fl -encoding= Ns Ar encoding +.Op Fl f | Fl -print-file-name +.Op Fl h | Fl -help +.Op Fl n Ar number | Fl -bytes= Ns Ar number | Fl Ar number +.Op Fl o +.Op Fl t Ar radix | Fl -radix= Ns Ar radix +.Op Fl v | Fl -version +.Op Ar +.Sh DESCRIPTION +For each +.Ar file +specified, the +.Nm +utility prints contiguous sequences of printable +characters that are at least +.Va n +characters long and are followed by an unprintable character. +The default value of +.Va n +is 4. +By default, the +.Nm +utility only scans the initialized and loaded sections of ELF objects; +for other file types, the entire file is scanned. +The +.Nm +utility is mainly used for determining the contents of non-text files. +.Pp +If no file name is specified as an argument, standard input is read. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl a | Fl -all +For ELF objects, scan the entire file for printable strings. +.It Fl e Ar encoding | Fl -encoding= Ns Ar encoding +Select the character encoding to be used while searching for strings. +Valid values for argument +.Ar encoding +are: +.Bl -tag -width indent -compact +.It Ar s +for single 7-bit-byte characters (ASCII, ISO 8859). +.It Ar S +for single 8-bit-byte characters. +.It Ar l +for 16-bit little-endian. +.It Ar b +for 16-bit big-endian. +.It Ar L +for 32-bit little-endian. +.It Ar B +for 32-bit big-endian. +.El +The default is to assume that characters are encoded using a single +7-bit byte. +.It Fl f | Fl -print-file-name +Print the name of the file before each string. +.It Fl h | Fl -help +Print a usage summary and exit. +.It Xo +.Fl n Ar number | +.Fl -bytes= Ns Ar number | +.Fl Ar number +.Xc +Print the contiguous character sequence of at least +.Ar number +characters long, instead of the default of 4 characters. +Argument +.Ar number +should specify a positive decimal integer. +.It Fl o +Equivalent to specifying +.Fl t Ar o . +.It Fl t Ar radix | Fl -radix= Ns Ar radix +Print the offset from the start of the file before each string +using the specified radix. +Valid values for argument +.Ar radix +are: +.Bl -tag -width indent -compact +.It Ar d +for decimal +.It Ar o +for octal +.It Ar x +for hexadecimal +.El +.It Fl v | Fl -version +Display a version identifier and exit. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +To display strings in +.Pa /bin/ls +use: +.Dl "$ strings /bin/ls" +.Pp +To display strings in all sections of +.Pa /bin/ln +use: +.Dl "$ strings -a /bin/ln" +.Pp +To display strings in all sections of +.Pa /bin/cat +prefixed with the filename and the offset within the file use: +.Dl "$ strings -a -f -t x /bin/cat" +.Sh SEE ALSO +.Xr ar 1 , +.Xr nm 1 , +.Xr objdump 1 , +.Xr ranlib , +.Xr readelf 1 , +.Xr size 1 +.Sh HISTORY +The first FreeBSD +.Nm +utility appeared in +.Fx v3. +It was later discontinued in +.Fx v5 , +when i386-only a.out format was dropped in favor of ELF. +.Sh AUTHORS +.An -nosplit +The +.Nm +utility was re-written by +.An S.Sam Arun Raj Aq Mt samarunraj@gmail.com . +This manual page was written by +.An S.Sam Arun Raj Aq Mt samarunraj@gmail.com . diff --git a/contrib/elftoolchain/strings/strings.c b/contrib/elftoolchain/strings/strings.c new file mode 100644 index 0000000000..26e63fdb50 --- /dev/null +++ b/contrib/elftoolchain/strings/strings.c @@ -0,0 +1,448 @@ +/*- + * Copyright (c) 2007 S.Sam Arun Raj + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "_elftc.h" + +ELFTC_VCSID("$Id: strings.c 3950 2021-09-08 20:04:20Z jkoshy $"); + +enum radix_style { + RADIX_DECIMAL, + RADIX_HEX, + RADIX_OCTAL +}; + +enum encoding_style { + ENCODING_7BIT, + ENCODING_8BIT, + ENCODING_16BIT_BIG, + ENCODING_16BIT_LITTLE, + ENCODING_32BIT_BIG, + ENCODING_32BIT_LITTLE +}; + +#define PRINTABLE(c) \ + ((c) >= 0 && (c) <= 255 && \ + ((c) == '\t' || isprint((c)) || \ + (encoding == ENCODING_8BIT && (c) > 127))) + +static int encoding_size, entire_file, show_filename, show_loc; +static enum encoding_style encoding; +static enum radix_style radix; +static intmax_t min_len; + +static struct option strings_longopts[] = { + { "all", no_argument, NULL, 'a'}, + { "bytes", required_argument, NULL, 'n'}, + { "encoding", required_argument, NULL, 'e'}, + { "help", no_argument, NULL, 'h'}, + { "print-file-name", no_argument, NULL, 'f'}, + { "radix", required_argument, NULL, 't'}, + { "version", no_argument, NULL, 'v'}, + { NULL, 0, NULL, 0 } +}; + +long getcharacter(void); +int handle_file(const char *); +int handle_elf(const char *, int); +int handle_binary(const char *, int); +int find_strings(const char *, off_t, off_t); +void show_version(void); +void usage(int); + +/* + * strings(1) extracts text(contiguous printable characters) + * from elf and binary files. + */ +int +main(int argc, char **argv) +{ + int ch, rc; + + rc = 0; + min_len = 0; + encoding_size = 1; + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", + strings_longopts, NULL)) != -1) { + switch ((char)ch) { + case 'a': + entire_file = 1; + break; + case 'e': + if (*optarg == 's') { + encoding = ENCODING_7BIT; + } else if (*optarg == 'S') { + encoding = ENCODING_8BIT; + } else if (*optarg == 'b') { + encoding = ENCODING_16BIT_BIG; + encoding_size = 2; + } else if (*optarg == 'B') { + encoding = ENCODING_32BIT_BIG; + encoding_size = 4; + } else if (*optarg == 'l') { + encoding = ENCODING_16BIT_LITTLE; + encoding_size = 2; + } else if (*optarg == 'L') { + encoding = ENCODING_32BIT_LITTLE; + encoding_size = 4; + } else + usage(EX_USAGE); + break; + case 'f': + show_filename = 1; + break; + case 'n': + min_len = strtoimax(optarg, (char**)NULL, 10); + if (min_len <= 0) + errx(EX_USAGE, "option -n should specify a " + "positive decimal integer."); + break; + case 'o': + show_loc = 1; + radix = RADIX_OCTAL; + break; + case 't': + show_loc = 1; + if (*optarg == 'd') + radix = RADIX_DECIMAL; + else if (*optarg == 'o') + radix = RADIX_OCTAL; + else if (*optarg == 'x') + radix = RADIX_HEX; + else + usage(EX_USAGE); + break; + case 'v': + case 'V': + show_version(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + min_len *= 10; + min_len += ch - '0'; + break; + case 'h': + usage(EX_OK); + break; + case '?': + default: + usage(EX_USAGE); + break; + } + } + argc -= optind; + argv += optind; + + if (min_len == 0) + min_len = 4; + if (*argv == NULL) + rc = find_strings("{standard input}", 0, 0); + else while (*argv != NULL) { + if (handle_file(*argv) != 0) + rc = 1; + argv++; + } + return (rc); +} + +int +handle_file(const char *name) +{ + int fd, rt; + + if (name == NULL) + return (1); + if (freopen(name, "rb", stdin) == NULL) { + warnx("'%s': %s", name, strerror(errno)); + return (1); + } + + fd = fileno(stdin); + if (fd < 0) + return (1); + rt = handle_elf(name, fd); + return (rt); +} + +/* + * Files not understood by handle_elf, will be passed off here and will + * treated as a binary file. This would include text file, core dumps ... + */ +int +handle_binary(const char *name, int fd) +{ + struct stat buf; + + memset(&buf, 0, sizeof(buf)); + (void)lseek(fd, 0, SEEK_SET); + if (!fstat(fd, &buf)) + return (find_strings(name, 0, buf.st_size)); + return (1); +} + +/* + * Will analyse a file to see if it ELF, other files including ar(1), + * core dumps are passed off and treated as flat binary files. Unlike + * GNU size in FreeBSD this routine will not treat ELF object from + * different archs as flat binary files(has to overridden using -a). + */ +int +handle_elf(const char *name, int fd) +{ + GElf_Ehdr elfhdr; + GElf_Shdr shdr; + Elf *elf; + Elf_Scn *scn; + int rc; + + rc = 0; + /* If entire file is chosen, treat it as a binary file */ + if (entire_file) + return (handle_binary(name, fd)); + + (void)lseek(fd, 0, SEEK_SET); + elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf_kind(elf) != ELF_K_ELF) { + (void)elf_end(elf); + return (handle_binary(name, fd)); + } + + if (gelf_getehdr(elf, &elfhdr) == NULL) { + (void)elf_end(elf); + warnx("%s: ELF file could not be processed", name); + return (1); + } + + if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { + (void)elf_end(elf); + return (handle_binary(name, fd)); + } else { + scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) == NULL) + continue; + if (shdr.sh_type != SHT_NOBITS && + (shdr.sh_flags & SHF_ALLOC) != 0) { + rc = find_strings(name, shdr.sh_offset, + shdr.sh_size); + } + } + } + (void)elf_end(elf); + return (rc); +} + +/* + * Retrieves a character from input stream based on the encoding + * type requested. + */ +long +getcharacter(void) +{ + long rt; + int i; + char buf[4], c; + + rt = EOF; + for(i = 0; i < encoding_size; i++) { + c = getc(stdin); + if (feof(stdin)) + return (EOF); + buf[i] = c; + } + + switch (encoding) { + case ENCODING_7BIT: + case ENCODING_8BIT: + rt = buf[0]; + break; + case ENCODING_16BIT_BIG: + rt = (buf[0] << 8) | buf[1]; + break; + case ENCODING_16BIT_LITTLE: + rt = buf[0] | (buf[1] << 8); + break; + case ENCODING_32BIT_BIG: + rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | + ((long) buf[2] << 8) | buf[3]; + break; + case ENCODING_32BIT_LITTLE: + rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | + ((long) buf[3] << 24); + break; + } + return (rt); +} + +/* + * Input stream stdin is read until the end of file is reached or until + * the section size is reached in case of ELF files. Contiguous + * characters of >= min_size(default 4) will be displayed. + */ +int +find_strings(const char *name, off_t offset, off_t size) +{ + off_t cur_off, start_off; + char *obuf; + long c; + int i; + + if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { + fprintf(stderr, "Unable to allocate memory: %s\n", + strerror(errno)); + return (1); + } + + (void)fseeko(stdin, offset, SEEK_SET); + cur_off = offset; + start_off = 0; + for (;;) { + if ((offset + size) && (cur_off >= offset + size)) + break; + start_off = cur_off; + memset(obuf, 0, min_len + 1); + for(i = 0; i < min_len; i++) { + c = getcharacter(); + if (c == EOF && feof(stdin)) + goto _exit1; + if (PRINTABLE(c)) { + obuf[i] = c; + obuf[i + 1] = 0; + cur_off += encoding_size; + } else { + if (encoding == ENCODING_8BIT && + (uint8_t)c > 127) { + obuf[i] = c; + obuf[i + 1] = 0; + cur_off += encoding_size; + continue; + } + cur_off += encoding_size; + break; + } + } + + if (i >= min_len && ((cur_off <= offset + size) || + !(offset + size))) { + if (show_filename) + printf("%s: ", name); + if (show_loc) { + switch (radix) { + case RADIX_DECIMAL: + printf("%7ju ", (uintmax_t)start_off); + break; + case RADIX_HEX: + printf("%7jx ", (uintmax_t)start_off); + break; + case RADIX_OCTAL: + printf("%7jo ", (uintmax_t)start_off); + break; + } + } + printf("%s", obuf); + + for (;;) { + if ((offset + size) && + (cur_off >= offset + size)) + break; + c = getcharacter(); + cur_off += encoding_size; + if (encoding == ENCODING_8BIT && + (uint8_t)c > 127) { + putchar(c); + continue; + } + if (!PRINTABLE(c) || c == EOF) + break; + putchar(c); + } + putchar('\n'); + } + } +_exit1: + free(obuf); + return (0); +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] [file...]\n\ + Print contiguous sequences of printable characters.\n\n\ + Options:\n\ + -a | --all Scan the entire file for strings.\n\ + -e ENC | --encoding=ENC Select the character encoding to use.\n\ + -f | --print-file-name Print the file name before each string.\n\ + -h | --help Print a help message and exit.\n\ + -n N | --bytes=N | -N Print sequences with 'N' or more characters.\n\ + -o Print offsets in octal.\n\ + -t R | --radix=R Print offsets using the radix named by 'R'.\n\ + -v | --version Print a version identifier and exit.\n" + +void +usage(int exit_code) +{ + + fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(exit_code); +} + +void +show_version(void) +{ + + printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(EXIT_SUCCESS); +} diff --git a/contrib/elftoolchain/tests/Makefile b/contrib/elftoolchain/tests/Makefile new file mode 100644 index 0000000000..592d0f98dd --- /dev/null +++ b/contrib/elftoolchain/tests/Makefile @@ -0,0 +1,12 @@ +# $Id$ + +TOP = .. + +SUBDIR = +SUBDIR+= atf # ATF based test suites. +SUBDIR+= custom # Test suites using custom frameworks. +SUBDIR+= tet # TET based test suites. + +SUBDIR+= libtest + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/README.rst b/contrib/elftoolchain/tests/README.rst new file mode 100644 index 0000000000..b0eb6992ee --- /dev/null +++ b/contrib/elftoolchain/tests/README.rst @@ -0,0 +1,8 @@ +This directory contains tests. + +- `TET`_ based test suites are in the directory ``tet``. These test + suites are being ported to `ATF`_. +- `ATF`_ based test suites are in the directory ``atf``. + +.. _TET: http://tetworks.opengroup.org/ +.. _ATF: https://github.com/freebsd/atf diff --git a/contrib/elftoolchain/tests/atf/Makefile b/contrib/elftoolchain/tests/atf/Makefile new file mode 100644 index 0000000000..a51a66acf1 --- /dev/null +++ b/contrib/elftoolchain/tests/atf/Makefile @@ -0,0 +1,7 @@ +# $Id$ + +TOP = ../.. + +SUBDIR = + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/custom/Makefile b/contrib/elftoolchain/tests/custom/Makefile new file mode 100644 index 0000000000..e74446084b --- /dev/null +++ b/contrib/elftoolchain/tests/custom/Makefile @@ -0,0 +1,11 @@ +# $Id$ +# +# Test suites that use custom test frameworks. +# + +TOP= ../.. + +SUBDIR+= ar +SUBDIR+= elfcopy + +.include "$(TOP)/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/custom/ar/Makefile b/contrib/elftoolchain/tests/custom/ar/Makefile new file mode 100644 index 0000000000..caa9acab2c --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/Makefile @@ -0,0 +1,20 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. +AR= ${TOP}/ar/ar + +TEST_LOG= test.log + +.MAIN: all + +.PHONY: clobber execute test + +execute test: ${AR} + /bin/sh run.sh + +clean clobber: + rm -f ${TEST_LOG} + +SUBDIR= plugin + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/custom/ar/README b/contrib/elftoolchain/tests/custom/ar/README new file mode 100644 index 0000000000..1786d1794e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/README @@ -0,0 +1,15 @@ +: $Id: README 2080 2011-10-27 04:23:24Z jkoshy $ + +ar(1) test suite depends on libarchive and uudecode(1). To install +the dependencies under Debian/Ubuntu Linux: + + # apt-get install libarchive-dev + # apt-get install sharutils + +To build ar(1) test suite: + + % make + +To execute ar(1) test suite: + + % make execute diff --git a/contrib/elftoolchain/tests/custom/ar/func.sh b/contrib/elftoolchain/tests/custom/ar/func.sh new file mode 100644 index 0000000000..6b96e2c362 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/func.sh @@ -0,0 +1,219 @@ +# $Id: func.sh 4036 2024-01-17 10:07:08Z jkoshy $ +# `init' initializes test engine global data. +# +init() { + THISDIR=`/bin/pwd` + TOPDIR=${THISDIR}/../../.. + AR=${TOPDIR}/ar/ar + RANLIB=${TOPDIR}/ar/ranlib + + # keep a record of total tests and number of tests passed. + TOTALCT=/tmp/bsdar-test-total + PASSEDCT=/tmp/bsdar-test-passed + echo 0 > ${TOTALCT} + echo 0 > ${PASSEDCT} +} + +# `inittest' initializes individual test process. (set up temp dirs, +# make copies of files used in the test if necessary, etc.) +# +inittest() { + if [ $# -ne 2 ]; then + echo "usage: inittest tcname tcdir" + exit 1 + fi + + TC=$1 + TCDIR=$2 + TESTDIR=/tmp/bsdar-${TC} + OUTDIR=/tmp/bsdar-${TC}-out + RLTDIR=/tmp/bsdar-${TC}-rlt + rm -rf ${TESTDIR} + rm -rf ${OUTDIR} + rm -rf ${RLTDIR} + mkdir -p ${TESTDIR} || exit 1 + mkdir -p ${OUTDIR} || exit 1 + mkdir -p ${RLTDIR} || exit 1 + + if [ -d "${TCDIR}/in" ]; then + cp -R ${TCDIR}/in/* ${TESTDIR} || exit 1 + fi + + if [ -d "${TCDIR}/out" ]; then + cp -R ${TCDIR}/out/* ${RLTDIR} || exit 1 + fi +} + +# `extshar' extracts shar file in the specific dir, +# then uudecode the resulting file(s). +# +extshar() { + if [ $# -ne 1 ]; then + echo "usage: extshar dir" + exit 1 + fi + + cd $1 || exit 1 + for f in *.shar; do + sh $f > /dev/null 2>&1 || exit 1 + rm -rf $f + done + + udecode $1 +} + +# `udecode' calls uudecode to decode files encoded by +# uuencode in the specific dir. +# +udecode() { + if [ $# -ne 1 ]; then + echo "usage: uudecode dir" + exit 1 + fi + + cd $1 || exit 1 + find . -type f -a -name '*.uu' -execdir uudecode {} \; + find . -type f -name '*.uu' -delete +} + +# `runcmd' runs `cmd' on the work/result dir. +# +# cmd: command to execute +# loc: work/result +# rec: true (keep a record of the stdout and stderr) +# false (do not record) +# +runcmd() { + if [ $# -ne 3 ]; then + echo "usage: runcmd cmd loc rec" + exit 1 + fi + + # prefix executable with abolute pathname. + executable=`echo $1 | cut -f 1 -d ' '` + relapath=`dirname ${executable}` + cd ${THISDIR} + absolpath=`cd ${relapath} && /bin/pwd` + newcmd=${absolpath}/`basename ${executable}`" "`echo $1 | cut -f 2- -d ' '` + redirin=`echo $newcmd | cut -f 2- -d '<'` + if [ "$redirin" != "$newcmd" ]; then + newcmd=`echo $newcmd | cut -f 1 -d '<'` + redirin=`echo ${redirin} | sed 's/^ *\(.*\) *$/\1/'` + fi + + if [ "$2" = work ]; then + cd ${TESTDIR} || exit 1 + elif [ "$2" = result ]; then + cd ${RLTDIR} || exit 1 + else + echo "loc must be work or result." + exit 1 + fi + + if [ "$3" = true ]; then + if [ "$redirin" != "$newcmd" ]; then + ${newcmd} < ${redirin} > ${OUTDIR}/${TC}.out 2> ${OUTDIR}/${TC}.err + else + ${newcmd} > ${OUTDIR}/${TC}.out 2> ${OUTDIR}/${TC}.err + fi + echo $? > ${OUTDIR}/${TC}.eval + elif [ "$3" = false ]; then + if [ "$redirin" != "$newcmd" ]; then + ${newcmd} < ${redirin} + else + ${newcmd} + fi + else + echo "rec must be true of false." + exit 1 + fi + + cd ${THISDIR} +} + +# `rundiff' performs standard diff to compare exit value, +# stdout output, stderr output and resulting files with +# "standard answers". +# +rundiff() { + # $1 indicates whether we should compare resulting files. + if [ $# -ne 1 ]; then + echo "usage: rundiff [true|false]" + exit 1 + fi + cd ${THISDIR} || exit 1 + if [ -f ${TCDIR}/${TC}.eval ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.eval ${OUTDIR}/${TC}.eval + if [ $? -eq 0 ]; then + echo "${TC} exit value - ok" + incct ${PASSEDCT} + else + echo "${TC} exit value - not ok" + fi + fi + + if [ -f ${TCDIR}/${TC}.out ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.out ${OUTDIR}/${TC}.out + if [ $? -eq 0 ]; then + echo "${TC} stdout - ok" + incct ${PASSEDCT} + else + echo "${TC} stdout - not ok" + fi + fi + + if [ -f ${TCDIR}/${TC}.err ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.err ${OUTDIR}/${TC}.err + if [ $? -eq 0 ]; then + echo "${TC} stderr - ok" + incct ${PASSEDCT} + else + echo "${TC} stderr - not ok" + fi + fi + + if [ "$1" = true ]; then + incct ${TOTALCT} + diff -urN ${RLTDIR} ${TESTDIR} + if [ $? -eq 0 ]; then + echo "${TC} resulting files - ok" + incct ${PASSEDCT} + else + echo "${TC} resulting files - not ok" + fi + fi +} + +# `innct' increase specified counter by 1. +incct() { + if [ $# -ne 1 ]; then + echo "usage: incct counterfile" + exit 1 + fi + if [ -f $1 ]; then + exec 3< $1 + read val <&3 + exec 3<&- + newval=`expr ${val} + 1` + echo ${newval} > $1 + else + echo "$1 not exist" + exit 1 + fi +} + +# `statistic' shows number of test passed. +# +statistic() { + exec 3< ${TOTALCT} + read tval <&3 + exec 3<&- + exec 3< ${PASSEDCT} + read pval <&3 + exec 3<&- + + echo "${pval} out of ${tval} passed." +} diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/Makefile b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile new file mode 100644 index 0000000000..5585ec7366 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile @@ -0,0 +1,17 @@ +# $Id: Makefile 3380 2016-01-29 07:53:10Z jkoshy $ + +PLUGINS= ardiff teraser + +all: ${PLUGINS} + +${PLUGINS}: +.for plugin in ${.TARGET} + ${MAKE} -f Makefile.${plugin} +.endfor + +test: .PHONY + +clean cleandepend clobber depend: .PHONY +.for plugin in ${PLUGINS} + ${MAKE} -f Makefile.${plugin} ${.TARGET} +.endfor diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.ardiff b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.ardiff new file mode 100644 index 0000000000..5e04721d37 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.ardiff @@ -0,0 +1,18 @@ +# $Id: Makefile.ardiff 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. + +PROG= ardiff + +NOMAN= noman + +WARNS?= 6 + +DPADD= ${LIBARCHIVE} +LDADD= -larchive + +.include "${TOP}/mk/elftoolchain.prog.mk" + +.if ${OS_HOST} == "DragonFly" +LDADD+= -lbz2 +.endif diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.teraser b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.teraser new file mode 100644 index 0000000000..46ce340c04 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/Makefile.teraser @@ -0,0 +1,11 @@ +# $Id: Makefile.teraser 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. + +PROG= teraser + +NOMAN= noman + +WARNS?= 6 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/ardiff.c b/contrib/elftoolchain/tests/custom/ar/plugin/ardiff.c new file mode 100644 index 0000000000..f7dbf657cd --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/ardiff.c @@ -0,0 +1,257 @@ +/** + * Selectively compare two ar archives. + * + * Usage: + * ardiff [-ni] [-t name] ar1 ar2 + * Options: + * -c compare member content. (This implies -s) + * -n compare member name. + * -i compare member mtime. + * -l compare archive length (member count). + * -s compare member size. + * -t specify the test name. + * + * By default, it compares nothing and consider the test "not ok" + * iff it encounters errors while reading archive. + * + * $Id: ardiff.c 4025 2023-12-16 22:33:13Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define COUNTER "/tmp/bsdar-test-total" +#define PASSED "/tmp/bsdar-test-passed" + +static void usage(void); +static void filediff(const char *tc, const char *msg, const char *e); +static void filesame(const char *tc); +static void incct(const char *pathname); + +int +main(int argc, char **argv) +{ + struct archive *a1; + struct archive *a2; + struct archive_entry *e1; + struct archive_entry *e2; + const char *tc; + char *buf1; + char *buf2; + char checkcont; + char checklen; + char checkname; + char checksize; + char checktime; + char a1end; + size_t size1; + size_t size2; + int opt, r; + + /* + * Parse command line options. + */ + checkcont = 0; + checklen = 0; + checkname = 0; + checksize = 0; + checktime = 0; + tc = NULL; + while ((opt = getopt(argc, argv, "cilnst:")) != -1) { + switch(opt) { + case 'c': + checkcont = 1; + break; + case 'i': + checktime = 1; + break; + case 'l': + checklen = 1; + break; + case 'n': + checkname = 1; + break; + case 's': + checksize = 1; + break; + case 't': + tc = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + usage(); + + /* Open file 1 */ + a1 = archive_read_new(); + archive_read_support_format_ar(a1); + if (archive_read_open_filename(a1, argv[0], + 1024*10)) { + warnx("%s", archive_error_string(a1)); + filediff(tc, "archive open failed", NULL); + } + + /* Open file 2 */ + a2 = archive_read_new(); + archive_read_support_format_ar(a2); + if (archive_read_open_filename(a2, argv[1], + 1024*10)) { + warnx("%s", archive_error_string(a2)); + filediff(tc, "archive open failed", NULL); + } + + /* Main loop */ + a1end = 0; + size1 = 0; + size2 = 0; + for (;;) { + /* + * Read header from each archive, compare length. + */ + r = archive_read_next_header(a1, &e1); + if (r == ARCHIVE_EOF) + a1end = 1; + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) { + warnx("%s", archive_error_string(a1)); + filediff(tc, "archive data error", NULL); + } + r = archive_read_next_header(a2, &e2); + if (r == ARCHIVE_EOF) { + if (a1end > 0) + break; + else { + if (checklen) + filediff(tc, "length differ", NULL); + break; + } + } + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) { + warnx("%s", archive_error_string(a2)); + filediff(tc, "archive data error", NULL); + } + if (a1end > 0) { + if (checklen) + filediff(tc, "length differ", NULL); + break; + } + + /* + * Check member name if required. + */ + if (checkname) { + if (strcmp(archive_entry_pathname(e1), + archive_entry_pathname(e2)) != 0) + filediff(tc, "member name differ", + archive_entry_pathname(e1)); + } + + /* + * Compare time if required. + */ + if (checktime) { + if (archive_entry_mtime(e1) != + archive_entry_mtime(e2)) + filediff(tc, "member mtime differ", + archive_entry_pathname(e1)); + } + + /* + * Compare member size if required. + */ + if (checksize || checkcont) { + size1 = (size_t) archive_entry_size(e1); + size2 = (size_t) archive_entry_size(e2); + if (size1 != size2) + filediff(tc, "member size differ", + archive_entry_pathname(e1)); + } + + /* + * Compare member content if required. + */ + if (checkcont) { + if ((buf1 = malloc(size1)) == NULL) + filediff(tc, "not enough memory", NULL); + if ((buf2 = malloc(size2)) == NULL) + filediff(tc, "not enough memory", NULL); + if ((size_t) archive_read_data(a1, buf1, size1) != + size1) + filediff(tc, "archive_read_data failed", + archive_entry_pathname(e1)); + if ((size_t) archive_read_data(a2, buf2, size2) != + size2) + filediff(tc, "archive_read_data failed", + archive_entry_pathname(e1)); + if (memcmp(buf1, buf2, size1) != 0) + filediff(tc, "member content differ", + archive_entry_pathname(e1)); + free(buf1); + free(buf2); + } + + /* Proceed to next header. */ + } + + /* Passed! */ + filesame(tc); + exit(EXIT_SUCCESS); +} + +static void +filediff(const char *tc, const char *msg, const char *e) +{ + if (e != NULL) + fprintf(stdout, "%s - archive diff not ok (%s (entry: %s))\n", + tc, msg, e); + else + fprintf(stdout, "%s - archive diff not ok (%s)\n", tc, msg); + + incct(COUNTER); + exit(EXIT_SUCCESS); +} + +static void +filesame(const char *tc) +{ + fprintf(stdout, "%s - archive diff ok\n", tc); + incct(COUNTER); + incct(PASSED); +} + +static void +incct(const char *pathname) +{ + FILE *fp; + char buf[16]; + + if ((fp = fopen(pathname, "r")) != NULL) { + if (fgets(buf, 10, fp) != buf) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", atoi(buf) + 1); + fclose(fp); + } + if ((fp = fopen(pathname, "w")) != NULL) { + fputs(buf, fp); + fclose(fp); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: ardiff archive1 archive2\n"); + exit(EXIT_FAILURE); +} diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/os.FreeBSD.mk b/contrib/elftoolchain/tests/custom/ar/plugin/os.FreeBSD.mk new file mode 100644 index 0000000000..c29af70518 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/os.FreeBSD.mk @@ -0,0 +1,2 @@ +DPADD+= ${LIBBZ2} +LDADD+= -lbz2 diff --git a/contrib/elftoolchain/tests/custom/ar/plugin/teraser.c b/contrib/elftoolchain/tests/custom/ar/plugin/teraser.c new file mode 100644 index 0000000000..8e51b8326c --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/plugin/teraser.c @@ -0,0 +1,154 @@ +/** + * 1. Erase archive symbol table's timestamp from ar archives, + * make it easy to `diff'. (option -e) + * 2. Check the sanity of timestamp. (option -c) + * + * $Id: teraser.c 4025 2023-12-16 22:33:13Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSPOS 24 /* position of timestamp */ +#define TSLEN 10 /* length of timstamp string */ +#define BUFLEN 16 /* size of a temporary buffer */ +#define TDELAY 3 /* max delay allowed */ +#define COUNTER "/tmp/bsdar-test-total" +#define PASSED "/tmp/bsdar-test-passed" + +#if BUFLEN < TSLEN +#error Temporary buffer size too small +#endif + +static void usage(void); + +int +main(int argc, char **argv) +{ + int opt; + char checktime; + char erasetime; + char buf[BUFLEN]; + char *tc; + int fd; + int ts; + time_t now; + FILE *ct, *ps; + + + checktime = 0; + erasetime = 0; + tc = NULL; + while ((opt = getopt(argc, argv, "cet:")) != -1) { + switch(opt) { + case 'c': + checktime = 1; + break; + case 'e': + erasetime = 1; + break; + case 't': + tc = optarg; + break; + default: + usage(); + } + } + + argv += optind; + if (*argv == NULL) + usage(); + + for (; *argv != NULL; argv++) { + if (checktime) { + if ((fd = open(*argv, O_RDONLY)) == -1) { + fprintf(stderr, + "open %s failed(%s), skipping time check...\n,", + *argv, strerror(errno)); + goto ctend; + } + if ((lseek(fd, TSPOS, SEEK_SET)) == -1) { + fprintf(stderr, + "lseek %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + goto ctend; + } + if ((read(fd, buf, TSLEN)) != TSLEN) { + fprintf(stderr, + "read %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + goto ctend; + } + buf[TSLEN] = '\0'; + ts = atoi(buf); + now = time(NULL); + if (ts <= now && ts >= now - TDELAY) { + fprintf(stderr, "%s - timestamp ok\n", tc); + if ((ps = fopen(PASSED, "r")) != NULL) { + if (fgets(buf, TSLEN, ps) != buf) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", + atoi(buf) + 1); + fclose(ps); + } + if ((ps = fopen(PASSED, "w")) != NULL) { + fputs(buf, ps); + fclose(ps); + } + } else { + fprintf(stderr, "%s - timestamp not ok\n", tc); + } + if ((ct = fopen(COUNTER, "r")) != NULL) { + if (fgets(buf, TSLEN, ct) != buf) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", + atoi(buf) + 1); + fclose(ct); + } + if ((ct = fopen(COUNTER, "w")) != NULL) { + fputs(buf, ct); + fclose(ct); + } + + ctend: + close(fd); + } + + if (erasetime) { + if ((fd = open(*argv, O_RDWR)) == -1) { + fprintf(stderr, + "open %s failed(%s), skipping time check...\n,", + *argv, strerror(errno)); + goto etend; + } + if ((lseek(fd, TSPOS, SEEK_SET)) == -1) { + fprintf(stderr, "lseek %s failed(%s), skipping...,", + *argv, strerror(errno)); + goto etend; + } + memset(buf, 32, sizeof buf); + if ((write(fd, buf, TSLEN)) != TSLEN) + fprintf(stderr, + "read %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + + etend: + close(fd); + } + } + + exit(EXIT_SUCCESS); +} + +static void +usage(void) +{ + fprintf(stderr, "usage: teraser [-ce] [-t name] archive ...\n"); + exit(EXIT_FAILURE); +} diff --git a/contrib/elftoolchain/tests/custom/ar/run.sh b/contrib/elftoolchain/tests/custom/ar/run.sh new file mode 100644 index 0000000000..4a3d1d026f --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/run.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# $Id: run.sh 3816 2020-02-08 15:00:18Z jkoshy $ +# +# Run all the tests. + +test_log=test.log + +# setup cleanup trap +trap 'rm -rf /tmp/bsdar-*' 0 2 3 15 + +# load functions. +. ./func.sh + +# global initialization. +init + +exec 4>&1 # Save stdout for later use. + +exec >${test_log} 2>&1 +echo @TEST-RUN: `date` + +# run tests. +for f in tc/*; do + if [ -d $f ]; then + . $f/`basename $f`.sh + fi +done + +# show statistics. +echo @RESULT: `statistic` + +# Exit with an error code if any test had failed. +if grep 'not ok' ${test_log} >&4; then + exit 1 +fi diff --git a/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.err b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.err new file mode 100644 index 0000000000..852a7613ac --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.err @@ -0,0 +1 @@ +ar: warning: can't open file: nonexistent: No such file or directory diff --git a/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.eval b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.eval new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.eval @@ -0,0 +1 @@ +1 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.sh b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.sh new file mode 100644 index 0000000000..7918ee5bef --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/add-nonexistent/add-nonexistent.sh @@ -0,0 +1,4 @@ +# $Id$ +inittest add-nonexistent tc/add-nonexistent +runcmd "${AR} rc archive.a nonexistent" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.err b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.err new file mode 100644 index 0000000000..7257ba01e5 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.err @@ -0,0 +1 @@ +ar: warning: cannot add archive "liba.a" to itself diff --git a/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.eval b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.eval new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.eval @@ -0,0 +1 @@ +1 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.sh b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.sh new file mode 100644 index 0000000000..fd4ae9aa98 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/addself-liba.sh @@ -0,0 +1,8 @@ +# $Id: addself-liba.sh 2095 2011-10-31 03:29:24Z jkoshy $ +inittest addself-liba tc/addself-liba +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} cru liba.a liba.a" work true +rundiff false +runcmd "plugin/teraser -c -t addself-liba liba.a" work false +runcmd "plugin/ardiff -cnlt addself-liba ${RLTDIR}/liba.a liba.a" work false diff --git a/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/in/addself-liba.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/in/addself-liba.in.shar new file mode 100644 index 0000000000..eacc1e4b96 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/addself-liba/in/addself-liba.in.shar @@ -0,0 +1,98 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# liba.a.uu +# +echo x - liba.a.uu +sed 's/^X//' >liba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Ma1.o.uu << 'END-of-a1.o.uu' +Xbegin 644 a1.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2.o.uu << 'END-of-a2.o.uu' +Xbegin 644 a2.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)Sa3.o.uu << 'END-of-a3.o.uu' +Xbegin 644 a3.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +END-of-a3.o.uu +echo x - a4.o.uu +sed 's/^X//' >a4.o.uu << 'END-of-a4.o.uu' +Xbegin 644 a4.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1.o.uu << 'END-of-a1.o.uu' +Xbegin 644 a1.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2.o.uu << 'END-of-a2.o.uu' +Xbegin 644 a2.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)Sa3.o.uu << 'END-of-a3.o.uu' +Xbegin 644 a3.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +END-of-a3.o.uu +echo x - a4.o.uu +sed 's/^X//' >a4.o.uu << 'END-of-a4.o.uu' +Xbegin 644 a4.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1_has_a_long_file_name.o.uu << 'END-of-a1_has_a_long_file_name.o.uu' +Xbegin 644 a1_has_a_long_file_name.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2_is_15_long.o.uu << 'END-of-a2_is_15_long.o.uu' +Xbegin 644 a2_is_15_long.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)Sa3_normal.o.uu << 'END-of-a3_normal.o.uu' +Xbegin 644 a3_normal.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +END-of-a3_normal.o.uu +echo x - a4_is_16_long_.o.uu +sed 's/^X//' >a4_is_16_long_.o.uu << 'END-of-a4_is_16_long_.o.uu' +Xbegin 644 a4_is_16_long_.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1_has_a_long_file_name.o.uu << 'END-of-a1_has_a_long_file_name.o.uu' +Xbegin 644 a1_has_a_long_file_name.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2_non_elf.o.uu << 'END-of-a2_non_elf.o.uu' +Xbegin 644 a2_non_elf.o +X6,3(S-#4V-V%B8V1E9F=H:6IK;&UN"@`` +X` +Xend +END-of-a2_non_elf.o.uu +echo x - a3_non_elf_with_a_long_file_name.o.uu +sed 's/^X//' >a3_non_elf_with_a_long_file_name.o.uu << 'END-of-a3_non_elf_with_a_long_file_name.o.uu' +Xbegin 644 a3_non_elf_with_a_long_file_name.o +XM,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3(R,C(R,C(R,C(R,C(R,C(R,C(R,C,S,S,S +X8,S,S,S,S,S,S,S,S-34U-34U-34U-34* +X` +Xend +END-of-a3_non_elf_with_a_long_file_name.o.uu +echo x - a4_is_16_long_.o.uu +sed 's/^X//' >a4_is_16_long_.o.uu << 'END-of-a4_is_16_long_.o.uu' +Xbegin 644 a4_is_16_long_.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1_ne.o.uu << 'END-of-a1_ne.o.uu' +Xbegin 644 a1_ne.o +X/,3(S-#4V-V%B8V1E9F<* +X` +Xend +END-of-a1_ne.o.uu +echo x - a2_ne.o.uu +sed 's/^X//' >a2_ne.o.uu << 'END-of-a2_ne.o.uu' +Xbegin 644 a2_ne.o +XM9F9F9F9F9F9F9F9F9F9F:&AH:&AH:&AH:&AH:&AH:&AH:VMK:VMK:VMK:VMK +X7:VMK:VMK;&QL;&QL;&QL;&QL;&QL;`H` +X` +Xend +END-of-a2_ne.o.uu +echo x - a3_non_elf_has_a_long_name.o.uu +sed 's/^X//' >a3_non_elf_has_a_long_name.o.uu << 'END-of-a3_non_elf_has_a_long_name.o.uu' +Xbegin 644 a3_non_elf_has_a_long_name.o +XM9F9F9F9F9F9O;V]O;V]O;V]O;V]O;V]O;V]O;V]O;V]E965E965E965E965E +X&965E964* +X` +Xend +END-of-a3_non_elf_has_a_long_name.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.err b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.eval b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.sh b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.sh new file mode 100755 index 0000000000..34b6384b58 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/arscript-1.sh @@ -0,0 +1,8 @@ +# $Id: arscript-1.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest arscript-1 tc/arscript-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} -M < kDep.a.ar-script" work true +rundiff false +runcmd "plugin/teraser -c -t arscript-1 kDep.a" work false +runcmd "plugin/ardiff -cnlt arscript-1 ${RLTDIR}/kDep.a kDep.a" work false diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/in/arscript-1.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/in/arscript-1.in.shar new file mode 100644 index 0000000000..65759288db --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-1/in/arscript-1.in.shar @@ -0,0 +1,492 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# kDep.a.ar-script.uu +# kDep.o.uu +# +echo x - kDep.a.ar-script.uu +sed 's/^X//' >kDep.a.ar-script.uu << '21ca52fca3d8603d40d15d6f65fd1e94' +Xbegin 644 kDep.a.ar-script +XE0U)%051%(&M$97`N80I!1$1-3T0@:T1E<"YO"E-!5D4*14Y$"@`` +X` +Xend +21ca52fca3d8603d40d15d6f65fd1e94 +echo x - kDep.o.uu +sed 's/^X//' >kDep.o.uu << 'a66b557a29668826603dd91bf8f66869' +Xbegin 644 kDep.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````+@K```` +XM`````````$```````$``&P`8`$B+/0````!32,<%``````````!(A?]U"^L8 +XM9F:09F:02(G?2(L?Z`````!(A=MFD'7N6\-F9F:09F9FD&9F9I!52(G]4TB# +XM[`A(BQT`````2(7;=!M(C5,8,<"^`````$B)[^@`````2(L;2(7;=>5(@\0( +XM6UW#9F:09F:09F:0059)B?Y!54%428GT53'M4P^V!X3`="L/MM!(B?EF9I") +XMZ,'@!HT$`HGJP>(0`=`IZ(G%#[9!`4B#P0&$P`^VT'7>2(L=`````$4Q[4B% +XMVW4-ZS=(BP-(A'SIG78 +XM2(G86UU!7$%=05[#28G=28U<)"!(B=_H`````$B%P'142(UX&$F-5"0!3(E@ +XM$$R)]DB)P^@`````387MB6L(=!=)BT4`2(D#28E=`$B)V%M=05Q!74%>PTB+ +XM!0````!(B0-(B=A(B1T`````6UU!7$%=05[#2(L]`````$B)VKX`````Z``` +XM``"_`0```.@`````9I!52(G]4TB#[`A(BQT`````2(7;=!M(C5,8,<"^```` +XM`$B)[^@`````2(L;2(7;=>5(@\0(2(GIN@(```!;7;X!````OP````#I```` +XM`&9FD$%7059!54%455-(@>PX!0``2(L%`````$C'!0``````````B7PD%$B% +XMP$B)1"08#X2?````28G'2(U$)"!(B40D".LMZ`````"+..@`````2(L]```` +XM`$B)P4B)VKX`````,<#H`````$V+/TV%_W1.08!_&#QT;D&`?QDZ28U'&DF- +XM7QA(#T38BT0D%(7`=69(C;0DL`0``$B)W^@`````A05_#28M'$$&`?`<7/G6&Z7+___](C7PD($B)WN@`````2(U\)"#K +XM#&9FD&:02(UX`<8`+[Y<````Z`````!(AY(C;0D,`0``$B-?"0@Q@,`Z`````"%P'1B3#MT)`@/ +XMA(T```!(C7PD($'&1O\`Z`````!)B<5!QD;_+TV%[0^$C@```$R)[^@````` +XM2(7`#X2*````3(U@"$R)]DR)Y^@`````A +XM2(/#`8`[+W75Z^R`?"0@`+\`````2`]%?"0(Z`````!)B<5-A>T/A7+___]` +XMB"M(C5PD(.E`_O__3(GOZ`````!`B"M(C5PD(.DK_O__#[9L)"!,C70D(.G/ +XM_O__`````1$!)0X3"P,.$0$2`1`&```")``+"SX+`PX```,6``,..@L["TD3 +XM```$)``+"SX+`P@```4D``L+/@L```8/``L+```'%P$+"SH+.PL!$P``"`T` +XM`PXZ"SL+21,```D!`4D3`1,```HA`$D3+PL```L3`0,."PLZ"SL+`1,```P- +XM``,..@L["TD3.`H```T/``L+21,```X3`0,."P4Z"SL+`1,```\-``,(.@L[ +XM"TD3.`H``!`5`2<,21,!$P``$04`21,``!(F`$D3```3$P`##CP,```4$P$+ +XM"SH+.PL!$P``%1,!"P4Z"SL+`1,``!86``,(.@L["TD3```7$P$#"`L+.@L[ +XM"P$3```8+@$##CH+.P4G#$D3(`L!$P``&04``P@Z"SL%21,``!HT``,..@L[ +XM!4D3```;-``#"#H+.P5)$P``'"X!/PP##CH+.P4G#!$!$@%`!@$3```=-``# +XM#CH+.P5)$P(&```>"P$1`1(!```?!0`##CH+.P5)$P(&```@+@$_#`,..@L[ +XM!2<,21,1`1(!0`8!$P``(1T!,1-5!E@+604``"(%`#$3```C"P%5!@``)#0` +XM,1,``"4T`#$3`@8``"8N`0,..@L["R<,21,@"P$3```G!0`##CH+.PM)$P`` +XM*#0``P@Z"SL+21,``"DN`0,..@L["R<,(`L!$P``*@L!```K-``##CH+.PM) +XM$P``+"X!/PP##CH+.PLG#!$!$@%`!@$3```M!0`##CH+.PM)$P(&```N-``# +XM#CH+.PM)$P(&```O-``##CH+.PM)$P(*```P-``#"#H+.PM)$P(*```Q'0$Q +XM$Q$!$@%8"UD+`1,``#(=`3$3$0$2`5@+60L``#,T`#$3`@H``#0A`$D3+P4` +XM`#4T``,..@L["TD3/PP\#````+@,```"```````(`0`````!```````````` +XM`````````````````````@$&``````,``````C0[`````@$(``````("!0`` +XM```#``````(V5`````("!P`````#``````(W9@````0$!6EN=``#``````(X +XM>`````($!P`````#``````(YB@````((!0`````#``````(ZG`````((!P`` +XM```""`0``````@0$``````,``````E*1`````P`````"5'\````%"`<&"`,` +XM`````R9M`````P`````#)W\````#``````,I;0````,``````RQM`````P`` +XM```#+FT````#``````,Q20````,``````S-)`````P`````#-'\````#```` +XM``,^;0````,``````U9F`````P`````#5R\!```#``````-;;0````>``V-O +XM`0``"``````#9&\!```(``````-E?P`````)?P$``'\!```*QP```'\``@$& +XM``````,``````V90`0```P`````$+QD!```#``````0RL0````L`````$`1& +XMT`$```P`````!$?0`0```B,`#``````$2&8````"(P@`#0@[````#@`````P +XM`01G1@,```]?<``$:-`!```"(P`/7W(`!&EF`````B,(#U]W``1J9@````(C +XM#`P`````!&M"`````B,0#``````$;$(````"(Q(/7V)F``1MIP$```(C&`P` +XM````!&YF`````B,H#``````$<=`!```"(V@/7W5R``1Z9@````(C<`P`````!'W-`P`` +XM`B-T#``````$?MT#```"(W`P`````!(1F`````R.( +XM`0P`````!(61`0```R.0`0P`````!(?S`P```R.8`0P`````!(C_`P```R.@ +XM`0P`````!(EF`````R.H`0P`````!(IF`````R.L`0P`````!(N&`0```R.P +XM`0`0`68```!6`P``$!````P`````%/FD$```5@!`%0&8%```,```` +XM``5!9@4```(C``P`````!4)V!0```B,(#``````%1*8%```"(R@,``````5% +XMT04```(C,`P`````!48Z`0```B,X#``````%2-<%```"(T`,``````5)YP4` +XM``,CP!`,``````5*YP4```,CP!@,``````51E`0```,CP"`,``````52E`0` +XM``,CT"`,``````53E`0```,CX"`,``````55R@````,C\"`,``````569@`` +XM``,C^"``"7\!``!V!0``"L<````'``E_`0``A@4```K'````'P`0`3H!``"@ +XM!0``$;P#```1L0```!&@!0````T(O`,```T(A@4``!`!9@```,L%```1.@$` +XM`!%V`P``$;$````1RP4````-"'8#```-"*P%```)G````.<%```*QP```/\` +XM"3H!``#W!0``"L<```#_``,`````!5>?!````P`````&+T````#``````9&^`````,`````!DL# +XM`0```P`````&4`X!```#``````95&0$```,`````!EJ\`````P`````&7R0! +XM```+`````!`'+ID&```,```````:#E`<```P`````!H1%`0```B,`#``````&A2X&```"(P0,``````:& +XM.08```(C"`P`````!H=$!@```B,*#``````&B&4&```"(PP,``````:)(P8` +XM``(C$`P`````!HI%`0```B,4#``````&C'`&```"(Q@,``````:-<`8```(C +XM*`P`````!HYP!@```B,X#``````&ET\&```"(T@,``````:8#08```(C4`P` +XM````!ID"!@```B-8#``````&FA@&```"(UP,``````:;;0````(C8`P````` +XM!IQ;`````B-D#``````&GG`&```"(V@`#@`````(`0@RZ`<```P`````"#-M +XM`````B,`#``````(-$D````"(P0,``````@U,`````(C!@P`````"#8P```` +XM`B,'#``````(.>@'```"(P@`"7\!``#X!P``"L<```#_``L`````4`E"D0@` +XM``P`````"4-F`````B,`#``````)1(H````"(P@,``````E%B@````(C$`P` +XM````"49V`P```B,8#``````)1V8````"(R`,``````E(B@````(C*`P````` +XM"4F*`````B,P#``````)2F8````"(S@,``````E+\P,```(C0`P`````"4R7 +XM"````B-(`!,``````0T(D0@``!9$25(`"4WX!P``%T1%4``@"B'M"```#``` +XM```*(^T(```"(P`,``````HE>`````(C"`P`````"B><`0```B,0#``````* +XM*?,(```"(Q@`#0BH"```"7\!```#"0``"L<````#``,`````"BKM"```&``` +XM```!(@$!>`````%#"0``&7-T<@`!(0&\`P``&@`````!(P%X````&V,``20! +XM9@`````<`0`````!9`$!``````````````````````````"4"0``'0`````! +XM90$#"0```````!X`````````````````````&@`````!:0$#"0`````<`0`` +XM```!#P$!``````````````````````````#7"0``'P`````!#@'7"0`````` +XM`!T``````1`!`PD`````````#0@%!```(`$``````34!`0,)```````````` +XM`````````````````'H*```?``````$T`;P#````````'P`````!-`&<`0`` +XM`````!T``````38!>``````````=``````$W`0,)````````'0`````!.`$# +XM"0```````"$."0````````$V`2(@"0``(P`````D+`D``"4X"0`````````` +XM`!P!``````$#`0$``````````````````````````+T*```?``````$"`=<) +XM````````'0`````!!`$#"0`````````F``````%!`78#```!Y0H``"<````` +XM`4!V`P``*'!S>@`!0G8#````*0`````!7@$!0@L``"<``````5UV`P``*'!S +XM>@`!7W8#```J*P`````!;7\!```H7!E +XM7!E7!E+F@`!``````)`@```````````^0"`7`?JO(Z +XM47<#HG_3C[@(*H$#(N\#<<4##RL#<1WP""H#&.$(J@,>"+<#8;<#"3G&7(Q( +XM`W@Y05@W.RUR3[.?-G0#;8T(.@.X?[>/N`@J@D:`*@.H?P@="!-S`WJI3C98 +XM`R2-`PRW`U`")0$##7]T`P[]`Q!_`PD(.0A-6(![6P-*"!T#%_T#ZGX(?W`# +XM(N'P1J$#"8T#<8T#$)M&`PG3`WK%/Y&N5%:`5Y/_""VM`PI_1CH#2G\#"8T# +XM+IM&5D8#87$(>`,1C<*"S`(/``$!)7,Z"@H`(%P*"25S``H*`"X`:T1E<#H@ +XM4VMI<'!I;F<@)R5S)R`M("5S(0H````*3W5T(&]F(&UE;6]R>2$@*')E<75E +XM`````````````````````(``````````EP`````````! +XM`%27`````````/D``````````0!Q@(` +XM```````V`P````````$`7C8#````````=@,````````!`%-V`P```````,T# +XM`````````0!>S0,```````#E`P````````$`4^4#````````[P,````````! +XM`%[O`P````````,$`````````0!3`P0```````!5!`````````$`7@`````` +XM``````````````"A`P```````+8#`````````0!0,00````````Y!``````` +XM``$`4``````````````````````D`@```````,$"`````````0!=Q@(````` +XM``!5!`````````$`70````````````````````!7`````@``````O`P``$,) +XM``!D97!#;&5A;G5P`)0)``!D97!0@H` +XM`&1E<%!R:6YT`$X+``!D97!/<'1I;6EZ90``````+`````(```````@````` +XM````````````500`````````````````````````````C0````````"/```` +XM`````)``````````P@``````````````````````````````C0````````"/ +XM`````````)``````````P@``````````````````````````````&`(````` +XM``!)`@```````,8"````````500```````!1`@```````)H"```````````` +XM`````````````````/`"````````]P(````````!`P````````8#```````` +XM``````````````````````8#````````4@,````````;!````````%4$```` +XM````N@,````````3!````````)X#````````JP,```````"(`P```````)8# +XM````````>P,```````"``P```````&<#````````=@,```````!?`P`````` +XM`&(#`````````````````````````````"T#````````-@,````````;!``` +XM`````%4$````````Y0,````````3!````````+H#````````W`,```````"> +XM`P```````*L#````````B`,```````"6`P```````'L#````````@`,````` +XM``!G`P```````'8#````````7P,```````!B`P```````$`#````````4@,` +XM````````````````````````````:P,```````!V`P```````!L$```````` +XM1@0````````#!````````!,$````````N@,```````#-`P```````)X#```` +XM````JP,```````"(`P```````)8#````````>P,```````"``P`````````` +XM``````````````````!S9&)M`'!S>D9I;&5N86UE`&9I>'-L87-H`%]#=7)R +XM96YT4G5N94QO8V%L90!F1FEX0V%S90!D97!/<'1I;6EZ90!U;G-I9VYE9"!I +XM;G0`7U]S<'5TE-T87)T`&9P;W-?=`!D97!0`!C8VA&:6QE;F%M90!? +XM7W)U;F5T>7!E7V5X=`!?7W9AF5?=`!?7V)L:W-I>F5?=`!? +XM7W5I9%]T`%]?=6EN=#A?=`!D97!0'0`9%]N86UL96X`7W-E96L`7U]R +XM=6YE7W0`7W5B=68``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&#(```````#8 +XM`P```````!H````3````"``````````8``````````D````#```````````` +XM`````````````%`V````````Q0````````````````````$````````````` +XM```````````````````````````````````````!````!`#Q_P`````````` +XM`````````````````P`!`````````````````````````````P`#```````` +XM`````````````````````P`$`````````````````````````````P`%```` +XM`````````````````````````P`&`````````````````````````````P`( +XM```````````````````````(`````0`$````````````"``````````````` +XM`P`*`````````````````````````````P`+```````````````````````` +XM`````P`,`````````````````````````````P`.```````````````````` +XM`````````P`0`````````````````````````````P`1```````````````` +XM`````````````P`3`````````````````````````````P`5```````````` +XM`````````````````P`6`````````````````````````````P`7```````` +XM```````````````0````$@`!````````````-``````````;````$``````` +XM```````````````````@````$@`!`$``````````-P`````````N````$``` +XM```````````````````````V````$@`!`(``````````#@$````````]```` +XM$`````````````````````````!$````$`````````````````````````!+ +XM````$`````````````````````````!5````$``````````````````````` +XM``!:````$@`!`)`!````````30````````!C````$``````````````````` +XM``````!J````$@`!`.`!````````=0(```````!V````$``````````````` +XM``````````!^````$`````````````````````````"'````$``````````` +XM``````````````",````$`````````````````````````"3````$``````` +XM``````````````````":````$`````````````````````````"A````$``` +XM``````````````````````"I````$`````````````````````````"Q```` +XM$`````````````````````````"\````$``````````````````````````` +XM:T1E<"YC`&=?<$1E<',`9&5P0VQE86YU<`!F0!?7W-T9&5RF4`7U]E``````````0!````````"@`` +XM`!$```"X`0````````\!````````"@```!$```">`````````!H!```````` +XM"@```!$```!8!0```````"4!````````"@```!$````I!````````#`!```` +XM````"@```!$````)`P```````#L!````````"@```!$````6!@```````$8! +XM````````"@```!$````5`P```````%D!````````"@```!$```"H```````` +XM`&0!````````"@```!$```#6`0```````((!````````"@```!$```!K`@`` +XM`````(`0```````)4$````````"@`` +XM`!$```#_`````````*D$````````"@```!$```!$!````````+<$```````` +XM"@```!$```#C!0```````,4$````````"@```!$```!Y`@```````-,$```` +XM````"@```!$```!/`````````.$$````````"@```!$````*!0```````.\$ +XM````````"@```!$```#2`@```````/T$````````"@```!$````C!0`````` +XM``P%````````"@```!$```!3`P```````!L%````````"@```!$````Z`@`` +XM`````"H%````````"@```!$````P`P```````#D%````````"@```!$```". +XM`@```````$@%````````"@```!$```!)`@```````%<%````````"@```!$` +XM``#:!````````/@%````````"@```!$```"N`P````````,&````````"@`` +XM`!$````9!0````````X&````````"@```!$```!P`@```````!D&```````` +XM"@```!$```"B`0```````"0&````````"@```!$```#(`P```````"\&```` +XM````"@```!$```#L`````````#H&````````"@```!$```![!0```````$4& +XM````````"@```!$```#I!````````%`&````````"@```!$```""!0`````` +XM`%L&````````"@```!$```"Q`@```````&8&````````"@```!$```#7`P`` +XM`````'$&````````"@```!$```!B`@```````'T&````````"@```!$```"C +XM!````````(L&````````"@```!$```"3`0```````)H&````````"@```!$` +XM``")`0```````*8&````````"@```!$```!H!0```````+0&````````"@`` +XM`!$```#=`@```````,(&````````"@```!$```#]`0```````-`&```````` +XM"@```!$```#4!0```````-X&````````"@```!$```!1!0```````.P&```` +XM````"@```!$```#/`0```````/H&````````"@```!$```#N!0````````@' +XM````````"@```!$```!,!````````!8'````````"@```!$```#R```````` +XM`"0'````````"@```!$```"K`0```````#('````````"@```!$````^!0`` +XM`````$`'````````"@```!$````_`0```````$X'````````"@```!$```!@ +XM`````````%P'````````"@```!$```!I`P```````&H'````````"@```!$` +XM```%!````````'@'````````"@```!$```"4`````````(8'````````"@`` +XM`!$```"\!````````)4'````````"@```!$```#!`P```````*('```````` +XM"@```!$```"E`P```````+`'````````"@```!$```!G`0```````+X'```` +XM````"@```!$```#!`0```````,P'````````"@```!$````'!@```````-H' +XM````````"@```!$```#"`````````/D'````````"@```!$```#W`P`````` +XM``4(````````"@```!$```!P`0```````!,(````````"@```!$```!/`0`` +XM`````"$(````````"@```!$````,!````````"\(````````"@```!$```#G +XM`P```````#T(````````"@```!$```"``P```````$L(````````"@```!$` +XM``!9!````````%D(````````"@```!$```"G`@```````&<(````````"@`` +XM`!$```#Z`@```````'4(````````"@```!$```!X`P```````(,(```````` +XM"@```!$```#F`````````)((````````"@```!$```#.`P```````+4(```` +XM````"@```!$````!!@```````,,(````````"@```!$```!R`P```````-$( +XM````````"@```!$````N`@```````-\(````````"@```!$```#J`0`````` +XM``0)````````"@```!$```".`0````````\)````````"@```!$````````` +XM`````"T)````````"@```!$`````!````````$4)````````"@```!$```!> +XM`P```````$T)`````````0````(``````````````%4)`````````0````(` +XM```T`````````%T)````````"@````T``````````````&8)````````"@`` +XM`!$```!,!0```````'$)````````"@````T````X`````````'8)```````` +XM`0````(````C`````````'X)`````````0````(````K`````````(<)```` +XM````"@```!$```!)`0```````)8)````````"@```!$````:`0```````)X) +XM`````````0````(```!``````````*8)`````````0````(```!W```````` +XM`*X)````````"@````T```"G`````````+<)````````"@```!$```!@!0`` +XM`````,()````````"@````T````'`0```````,<)````````"@```!$```!, +XM!0```````-()````````"@````T```!0`0```````-\)````````"@```!$` +XM``";!0```````.L)`````````0````(```"``````````/,)`````````0`` +XM``(```".`0```````/L)````````"@````T```!S`0````````0*```````` +XM"@```!$````%``````````\*````````"@````T```#[`0```````!0*```` +XM````"@```!$````N`@```````!\*````````"@````T```!J`@```````"0* +XM````````"@```!$```!R`P```````"\*````````"@````T```#9`@`````` +XM`#0*````````"@```!$```!,!0```````#\*````````"@````T```!(`P`` +XM`````$0*````````"@```!$````N`0```````$\*````````"@````T````# +XM!````````%@*````````"@```!```````````````&4*````````"@```!`` +XM```P`````````',*````````"@````T```!?!````````'P*````````"@`` +XM`!$````[!````````(0*`````````0````(```"0`0```````(P*```````` +XM`0````(```#=`0```````)0*````````"@````T```"5!````````)T*```` +XM````"@```!$```!@!0```````*@*````````"@````T```#U!````````*T* +XM````````"@```!$```!,!0```````+@*````````"@````T````^!0`````` +XM`+X*````````"@```!$````1`````````,\*````````"@```!$````%```` +XM`````.8*````````"@```!$````@`@```````/,*````````"@```!$````% +XM``````````H+````````"@```!$```#U`0```````!X+````````"@```!$` +XM```*`0```````"H+````````"@```!$```#(`0```````#4+````````"@`` +XM`!$```#)`````````%`+````````"@```!$````V`````````%<+```````` +XM`0````(```#@`0```````%\+`````````0````(```!5!````````&<+```` +XM````"@````T```!A!0```````'`+````````"@```!$````M`````````'H+ +XM````````"@````T````2!@```````'\+````````"@```!$```"X`@`````` +XM`(D+````````"@````T```!*!@```````(X+````````"@```!$```!,!0`` +XM`````)@+````````"@````T```#E!@```````)T+````````"@```!````!@ +XM`````````*(+````````"@```!$```#J`0```````+$+````````"@```!$` +XM```%`````````+L+````````"@````T````;!P```````-$+`````````0`` +XM``(```#P`@```````-D+`````````0````(````&`P```````.T+```````` +XM"@```!````"@`````````/8+````````"@````T```"=!P````````$,```` +XM`````0````(````&`P````````D,`````````0````(```!5!````````!D, +XM````````"@```!````#0`````````"(,````````"@````T````R"``````` +XM`"<,````````"@```!````!@`0```````#\,````````"@```!`````0`@`` +XM`````$@,````````"@````T```#:"````````%$,````````"@````T````0 +XM"0```````&T,````````"@```!$```#6`````````'D,`````````0````0` +XM`````````````((,````````"@```!$```"*`````````(\,````````"@`` +XM`!$```!4`@```````)P,````````"@```!$````=`P```````*D,```````` +XM"@```!$````:``````````,!`````````0````(``````````````!P````` +XM````"@````L``````````````"```````````0````(``````````````#P` +XM````````"@````L``````````````$```````````0````(```!````````` +XM`&0`````````"@````L``````````````&@``````````0````(```"````` +XM`````)P`````````"@````L``````````````*```````````0````(```"0 +XM`0```````,0`````````"@````L``````````````,@``````````0````(` +XM``#@`0```````"``````````"@````(``````````````#@`````````"@`` +XM``(```!``````````%@`````````"@````(```"``````````(@````````` +XM"@````(```"0`0```````*@`````````"@````(```#@`0````````8````` +XM````"@````8```````````````8`````````"@````8``````````````!`` +X6`````````0````(````````````````` +X` +Xend +a66b557a29668826603dd91bf8f66869 +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.err b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.eval b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.sh b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.sh new file mode 100755 index 0000000000..b33528784d --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/arscript-2.sh @@ -0,0 +1,8 @@ +# $Id: arscript-2.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest arscript-2 tc/arscript-2 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} -M < kUtil.a.ar-script.bsd" work true +rundiff false +runcmd "plugin/teraser -c -t arscript-2 kUtil.a" work false +runcmd "plugin/ardiff -cnlt arscript-2 ${RLTDIR}/kUtil.a kUtil.a" work false diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/in/arscript-2.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/in/arscript-2.in.shar new file mode 100644 index 0000000000..32f3195005 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-2/in/arscript-2.in.shar @@ -0,0 +1,429 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./crc32.o.uu +# ./kUtil.a.ar-script.bsd.uu +# ./kUtil.a.ar-script.gnu.uu +# ./md5.o.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./crc32.o.uu +sed 's/^X//' >./crc32.o.uu << 'a324e56f72c95be57d41e586ca56b982' +Xbegin 644 crc32.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````&@*```` +XM`````````$```````$``&0`6`$B%TG0>B?C!YPC!Z!@R!DB#Q@$/ML`S/(4` +XM````2(/J`77BB?C#```!$0$E#A,+`PX1`1(!$`8```(D``L+/@L##@```Q8` +XM`PXZ"SL+21,```0D``L+/@L#"```!20`"PL^"P``!BX!/PP##CH+.PLG#$D3 +XM$0$2`4`*`1,```<%``,..@L["TD3`@H```@%``,(.@L["TD3`@8```D%``,( +XM.@L["TD3`@H```HT``,(.@L["TD3`@H```L/``L+21,```PF````#28`21,` +XM``X!`4D3`1,```\A`$D3+PL``!`T``,..@L["TD3`@H```!?`0```@`````` +XM"`$``````0````````````````````````````````(!!@`````#``````(T +XM.P````(!"``````"`@4``````@('``````0$!6EN=``#``````(X8@````($ +XM!P`````""`4``````P`````".GL````""`<``````@@$``````($!``````# +XM``````)2<`````4(!P(!!@`````#``````-4,`````,``````UY7`````P`` +XM```#Z)`````""`4`````!@$``````9L!L``````````````````````````" +XM=P@F`0``!P`````!FK`````!50AB=68``9HF`0````````EL96X``9J[```` +XM`5$*<``!G"T!```!5``+""P!```,"P@S`0``#:4````.L````$@!```/FP`` +XM`/\`$``````!.%T!```)`P``````````#3@!````J0````(`B@````$!^PX* +XM``$!`0$````!+W5S7!EGN?<,UF +XM7G3@MB.85ZOBG(Z-H9$YD&"5/,`GBXO=YH]2^Z6"Y>9DAEA;*[[O1NJZ-F"I +XMMX%]:+.$+2^M,S#NJ>H6K:1="VR@D&TRU"=P\]#^5K#=24MQV4P;-L?[!O?# +XM(B"TSI4]=C=1UV]V3:VS`4F^UYA%B`OO0 +XM9K]&GUX(6UY:T7T=5V9@W%-C,)M-U"U:20T+&42Z%MA`E\:EK"#;9*CY_2>E +XM3N#FH4NPH;_\K6"[)8LCMI*6XK(O*ZV*F#9LCD$0+X/V#>Z'\UVIF41`:)V= +XM9BN0*GOJE.<=M.!0`'7DB28VZ3X[]^T[:[#SC'9Q]U50,OKB3?/^7_"\QNCM +XM?<(QRS[/AM;_RX.&N-4TFWG1[;TZW%J@^]CNX`QI6?W-;8#;CF`WQD]D,I8( +XM>H6+R7YP!*$)-&3;U4-@R+':;/YMK6CLFUA4#DL+!FCOMKLGUP&FYM/8@*7>;YUDVFK-(\3=T.+`!/:AS;/K8,E^C3Z]R9#_ +XMN1"VO+2GJWVPHOLZKA7F^ZK,P+BG>]UYH\9@-IMQ??>?J%NTDA]&=98:%C*( +XMK0OSC'0ML('#,'&%F9"*72Z-2UGWJPA40+;)4$7FCD[R^T]**]T,1YS`S4,A +XM?8)[EF!#?T]&`'+X6\%V_0N&:$H61VR3,`1A)"W%9>E+FQ%>5EH5AW`9&#!M +XMV!PU/9\"@B!>!EL&'0OL&]P/4::3-^:[4C,_G1$^B(#0.HW0ER0ZS58@X^L5 +XM+53VU"EY)JG%SCMHP1<=*\R@`.K(I5"MUA)-;-++:R_??';NV\'+H>-VUF#G +XMK_`CZACMXNX=O:7PJJ!D]'.&)_G$F^;]"?VXB;[@>8UGQCJ`T-O[A-6+O)IB +XMEGV>N[`^DPRM_Y>Q$+"O!@UQJ]\K,J9H-O.B;6:TO-I[=;@#73:UM$#WL10` +XM``#_____`0`!>!`,!PB0`0```````!0````````````````````F```````` +XM`!0``````````7I2``%X$`$##`<(D`$``!0````<`````````"8````````` +XM````````````````$P`````````!`%0C`````````"8``````````0!4```` +XM`````````````````!@````"``````!C`0``S0```&-R8S,R```````L```` +XM`@``````"``````````````````F``````````````````````````````!L +XM;VYG(&QO;F<@:6YT`'-I>F5?=`!'3E4@0R`T+C(N,2`R,#`W,#6UT86(`+G-T./kUtil.a.ar-script.bsd.uu << '068e8339e6696dd7f0d5d05e54567937' +Xbegin 644 kUtil.a.ar-script.bsd +XM0U)%051%("XO:U5T:6PN80I!1$1-3T0@+B]C./kUtil.a.ar-script.gnu.uu << '8e00e678c1fca8191d5510a0884a1e14' +Xbegin 644 kUtil.a.ar-script.gnu +XM0U)%051%("XO:U5T:6PN80I!1$1-3T0@+B]M9#4N;PI!1$1-3T0@+B]C./md5.o.uu << '1f069cc1637871cdba87acd410259ce4' +Xbegin 644 md5.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````*@=```` +XM`````````$```````$``&``5`,<'`2-%9\='!(FKS>_'1PC^W+J8QT<,=E0R +XM$,='$`````#'1Q0`````PV9FD&9FD$%71(M'#(M/"$2+3P1!5D%505154XL? +XMBP9$BWX41(MF'(MN($2+;BA$BUXPB40DX(V4`WBD:M=$B<`QR(M>"$2+=C1$ +XM($$$!P(G00<'(%$0QR$$!T(E<)/!$( +XM/`'"1(G(P]D2)R#'(1"'`,<@!PHM$)/3! +XMRAM$`:AV$0QR$$!P$'!R!=!`=!$B<`QT$0AR#'0`<&+1"3PP)R$0QP"'01#'`00'!BT0D^$'!R0Q!`$A1(G(,- +XMC!$,..7]1#'``<%$B<#!R1`QT$0!P3'(00'!BT0DY$'!R0E!`2T2)R#'(0HV,(6!+N_8QT$$! +XMP(G00<'(%40QR$>-C"EPO+^^00'01#'``<%$B<#!R1`QT$*-E#+&?ILH1`'! +XM,AZD2)R#'( +XM,=!!`<"+1"3L0<'(%4$!T(V,`84P[]2)T$0QR$0QP`'!BT0D],')$$0!P46- +XMC`$%'8@$1(G`,=`QR$$!P8M$)/A!P-C#DYH)/\0<'(%O?000'01`G`,=`!P8G00HV4&L-96V7!R1'W +XMT$0!P0G(1#'`00'!1(G`0<')"_?000')1`G(,<@!PHM$).S!RAI$`1`%'#$'!R0M!7T0!R(E'!,-F9F:09F:09F:09F:02(E<).A(B6PD +XM\$B-;AA,B60D^$B#[!B+5A!)B?Q(B?/!Z@.#XC^)T$B-1`4`Q@"`2(UX`;@_ +XM````*="#^`=W8XG",?;H`````$B)WTB)[N@`````_+D'````,_S2*N+ +XM0Q!(B>Y(B=^)13B+0Q2)13SH`````$B+`TB+;"0(28D$)$B+0PA)B40D"$C' +XM`P````!,BV0D$$B+'"1(@\08PXU0^#'VZ`````#KLY!!5T%628G^055!B=5! +XM5%5(B?532(/L"(M7$$*-!.HYPHE'$'8$@T<4`42)Z,'J`TV-9AC!Z!U!`484 +XM@^(_#X2=````0;]`````B=!(B>Y!*==)C3P$1(GJ13G]#X*.````1(G[2(GN +XM12G]2(G:2`'=Z`````!,B>9,B??H`````$&#_3]V8$B+10!,B>9,B?=!@^U` +XM28E&&$B+10A)B40D"$B+11!)B40D$$B+11A)B40D&$B+12!)B40D($B+12A) +XMB40D*$B+13!)B40D,$B+13A(@\5`28E$)#CH`````$&#_3]WH$2)ZDB)[DR) +XMYTB#Q`A;74%<05U!7D%?Z0````````$1`24.$PL##A$!$@$0!@```B0`"PL^ +XM"P,.```#)``+"SX+`P@```06``,..@L["TD3```%)``+"SX+```&$P$##@L+ +XM.@L["P$3```'#0`#"#H+.PM)$S@*```(#0`##CH+.PM)$S@*```)`0%)$P$3 +XM```*(0!)$R\+```++@$_#`,..@L["R<,$0$2`4`*`1,```P%``,(.@L["TD3 +XM`@H```T/``L+21,```XN`3\,`PXZ"SL+)PP1`1(!0`8!$P``#P4``P@Z"SL+ +XM21,"!@``$#0``P@Z"SL+21,"!@``$04``PXZ"SL+21,"!@``$C0``PXZ"SL+ +XM21,"!@``$PL!$0$2`0``%"8`21,```",`@```@``````"`$``````0`````` +XM``````````````````````````(!!@`````"`0@``````@(%``````("!P`` +XM```#!`5I;G0`!``````".%<````"!`<``````@@%``````((!P`````""`0` +XM`````@0$``````4(!P(!!@`````""`4`````!``````#7DP````&`````%@$ +XM!LP````'8G5F``0'S`````(C``@`````!`C<`````B,0!VEN``0)[`````(C +XM&``)BP```-P````*>@````,`"8L```#L````"GH````!``DP````_`````IZ +XM````/P`+`0`````!-P$``````````````````````G<(*@$```QC='@``38J +XM`0```54`#0B6````#@$``````;$!``````````````````````````"A`0`` +XM#&)U9@`!L*$!```!50]I;@`!L*$!````````$&$``;*+`````````!!B``&R +XMBP`````````08P`!LHL`````````$&0``;*+```````````-"(L````.`0`` +XM```!=@$```````````````````````````,"```1``````%U`P(````````/ +XM8W1X``%U*@$````````2``````%W5P`````````0<``!>`,"``````````T( +XM,`````X!``````%&`0``````````````````````````A`(```]C='@``44J +XM`0````````]B=68``46$`@````````]L96X``457`````````!!T``%'BP`` +XM```````3`````````````````````!!P``%5`P(```````````T(B@(``!0P +XM`````&8"```"`)$````!`?L."@`!`0$!`````2]UF,\6"I% +XM2BAF`_5^TP,)FP-W1Y(T:&=R='17CZS;/&`Z95<[4\9R`W33`[9_Q0AH.JI( +XM.V]WD&$O-S=+.)%G-3PV5Z]D265#`CX21%=2`PICCM("!0`!`0```!0```#_ +XM____`0`!>!`,!PB0`0```````!0````````````````````J`````````#0` +XM``````````````````!C!P```````$(.$$T.&$(.($(.*$$.,$$..(,'A@:, +XM!8T$C@./`@``)````````````````````*\`````````2H8#@P1-#B",`@`` +XM`````#P````````````````````"`0```````$(.$$(.&(X#CP)%#B"-!$4. +XM*$$.,(8&C`5$#CA$#D"#!P`````````4``````````%Z4@`!>!`!`PP'")`! +XM```4````'``````````J```````````````L````-`````````!C!P```$(. +XM$$T.&$(.($(.*$$.,$$..(,'A@:,!8T$C@./`@`<````9`````````"O```` +XM`$J&`X,$30X@C`(``````#0```"$``````````(!````0@X00@X8C@./`D4. +XM((T$10XH00XPA@:,!40..$0.0(,'````````,``````````R``````````(` +XM=P@R`````````#\``````````@!W$#\`````````00`````````"`'<800`` +XM``````!#``````````(`=R!#`````````$0``````````@!W*$0````````` +XM10`````````"`'!````````#D%`````````0!90P4```````"A!0````````$` +XM6:L%````````]@4````````!`%D@!@```````'X&`````````0!9D08````` +XM``#8!@````````$`6?H&````````4P<````````!`%E[!P```````),'```` +XM`````0!9`````````````````````#D`````````J``````````!`%+&```` +XM`````#@!`````````0!230$```````"<`0````````$`4K,!````````#P(` +XM```````!`%(N`@```````(\"`````````0!2FP(```````#Q`@````````$` +XM4@H#````````=`,````````!`%*(`P```````-<#`````````0!2^`,````` +XM``!+!`````````$`4ET$````````J`0````````!`%+&!````````!T%```` +XM`````0!2)P4```````!V!0````````$`4H\%````````VP4````````!`%(& +XM!@```````$\&`````````0!2;`8```````"Y!@````````$`4N@&```````` +XM2`<````````!`%)"`````````(`=R!>"``` +XM`````%\(`````````@!W*%\(````````8P@````````"`' /dev/null 2>&1 +echo c - ./kmkbuiltin +mkdir -p ./kmkbuiltin > /dev/null 2>&1 +echo x - ./kmkbuiltin/kbuild_protection.o.uu +sed 's/^X//' >./kmkbuiltin/kbuild_protection.o.uu << 'ba9c783b814204367d9452f4eebce68e' +Xbegin 644 ./kbuild_protection.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````-@J```` +XM`````````$```````$``'``9`,<'`!$1`,9'"0#&1P@!QT<$`@```,-F9F:0 +XM9F:09F:0QP<`````PV9FD&9FD&9FD+@"````PV9F9I!F9I!F9I!(B5PD\$B) +XM;"3X2(/L&($_`!$1`$B)^XGU=!FY`````+KW````O@````"_`````.@````` +XM@_T!=AFY`````+KX````O@````"_`````.@`````B>B`9`,(_DB+7"0(2(ML +XM)!!(@\08PV9F9I!F9F:02(E<)/!(B6PD^$B#[!B!/P`1$0!(B?N)]709N0`` +XM``"Z[P```+X`````OP````#H`````(/]`789N0````"Z\````+X`````OP`` +XM``#H`````(GH@$P#"`%(BUPD"$B+;"002(/$&,-F9F:09F9FD%5%,E(@_D"=")( +XM@^D!=$I!@\`!A,!(C6H!=#$/MG4`0(#^+W6]2(/%`>OP0(#^+G7>@'T!+G78 +XM187`9F9FD'[308/H`83`2(UJ`77/2('$"!```$2)P%M=PT"`_BYUL.NR0(#_ +XM+@^%7/___X!^`2X/A5+___]%A<`/CDW___]!@^@!Z43___]F9F:09F:00(#_ +XM+@^%+____V9FD&9FD.DH____O@````"_`0```.@`````0;C_____ZY)F9F:0 +XM2(E<).A(B6PD\$B)^TR)9"3X2(/L&($_`!$1`(GU28G4=!FY`````+I6`0`` +XMO@````"_`````.@`````@_T!=AFY`````+I7`0``O@````"_`````.@````` +XMB>CV1`,(`W4&]D,)`W063(GGZ!_^__^%P+K_____>`<[0P1V%S'22(L<)$B+ +XM;"0(B=!,BV0D$$B#Q!C#3(GBO@````"_`0```#'`Z`````"Z_____^O09F9F +XMD&9F9I!F9F:09F:054B)_5-(B?-(@^P8#[X6A=)X+(LU`````#GR?2)(BPT` +XM````ZP](@\,!#[X3A=)X#CGR?0I(8\+V1,%!0'7G@_I_=PU(8\+V!,4````` +XM!'4<2(G?Z'?]__^%P(E%!`^$HP```$B#Q!@QP%M=P[X`````2(G?Z`````!( +XMA-``# +XM#CH+.PM)$P``'S0``P@Z"SL+21,``"`N`0,..@L["R<,21,1`1(!0`8!$P`` +XM(30``PXZ"SL+21,"!@``(@L!508!$P``(S0``PXZ"SL+21,""@``)!T!,1-5 +XM!E@+60L``"4%`#$3```F"P%5!@``)S0`,1,"!@``*#0`,1,``"DA`$D3+P4` +XM`"HN`3\,`PXZ"SL%)PQ)$Q$!$@%`!@$3```K!0`##CH+.P5)$P(&```L-``# +XM#CH+.P5)$P(&```M'0$Q$U4&6`M9!0$3```N!0`Q$P(&```O'0$Q$Q$!$@%8 +XM"UD%`1,``#`+`1$!$@$``#$=`3$35098"UD%```R-``#"#H+.P5)$P(&```S +XM-``##CH+.P5)$P``-#0``PXZ"SL+21,_##P,````<0@```(```````@!```` +XM``$````````````````````````````````"`08``````@$(``````("!0`` +XM```"`@<``````P0%:6YT``($!P`````""`4`````!``````#.F4````""`<` +XM`````@@$``````($!``````$``````-26@````4(!P8(!``````$5D4````$ +XM``````17B@````(!!@`````'"*`````'"+,````(H`````0`````!>AZ```` +XM`@@%``````D8!C0+`0``"@`````&-94````"(P`*``````8VE0````(C!`H` +XM````!C>5`````B,("@`````&.`L!```"(Q``!PAE````!``````&.@````]3`@````<(K0`` +XM``<(.0(```X!10```'X"```/E0````^G````#WH````/?@(````'"*<````' +XM"%\"```,90```)H"```-A0```/\`#)4```"J`@``#84```#_``0`````!E=2 +XM`0``$`0'(M8"```1```````1```````1``````$1``````(`!``````')[4" +XM```2``````P'+Q@#```*``````8H````47V8``GEE````%0`3``````*``44````#S0,``!1?8P`"?XH` +XM```47V8``G]E`````!8!``````':`0`````````````````````"=PC[`P`` +XM%P`````!V3,#```!50`6`0`````!Z`$``````````````````````G<(*00` +XM`!<``````>!```&@`````!]3,# +XM````````&@`````!]=8"````````&P`````]"````0D#````````````&0$` +XM`````>X!``````````````````````````#R!```&@`````![3,#```````` +XM&@`````![=8"````````&P`````H"````0D#````````````$P`````!1`%% +XM`````3(%```<``````%#K0```!P``````4-%````'1X``````4>M````'V-C +XM:``!2+@``````"```````74!10``````````````````````````````W@4` +XM`!H``````72M`````````"$``````79%`````````"(`````MP4``",````` +XM`<'>!0```Y'@7R3R!`````````'')0X%```E`P4``"8`````)QH%```````` +XM*"4%```````D\@0````````!T"4.!0``)0,%```F`````"@:!0``*"4%```` +XM```,H````.\%```IA0```/\/`"H!``````%5`0%%```````````````````` +XM``````````!T!@``*P`````!5`%$`P```````"L``````50!U@(````````K +XM``````%4`:T`````````(@````!?!@``+``````!7P%%```````````;```` +XM`$((```!"0,````````````J`0`````!!0$!10`````````````````````` +XM````````:@<``"L``````00!,P,````````K``````$$`:T`````````+8`# +XM`````````0R5U`P``+FL#```` +XM```````OIP,````````````````````````!"P$6!P``)<(#```EN`,````P +XM`````````````````````"P``````0\!IP`````````Q@`,````````!%`$E +XMFP,``"61`P``)%H#`````````GLE=0,``"YK`P`````````````J`0`````! +XM*P$!10``````````````````````````````$P@``"L``````2H!,P,````` +XM```K``````$J`7X"````````*P`````!*@&M`````````#)I``$L`4P````` +XM````+``````!+0$3"````````"8`````+``````!,0&M`````````#`````` +XM````````````````,P`````!-P&M````````"+@````,H````"@(```-A0`` +XM`!8`"!@(```,H````#T(```-A0```!<`""T(```(+0@``#0``````EI%```` +XM`0$T``````9;J@(```$!-``````&7&X(```!`0<(J@(````F`@```@#K```` +XM`0'[#@H``0$!`0````$O=7-R+W!O7,``&MB=6EL9%]P +XM7!E+F@``@``7W1Y<&5S+F@``P``7W1Y<&5S +XM+F@`!```='EP97,N:``$``!R=6YE='EP92YH``(``&MB=6EL9%]P.C`0"`]I^.00!`ZD!1PB2 +XM"#L##0A'_S=E5S<["((('T@((P@>@`@>`W%_`Q*D#"0B;"%8" +XM"P`!`7!4:&ES+3YU36%G:6,@/3T@2T)524Q$7U!23U1%0U1)3TY?34%'24,` +XM`````````"]U7!E(#P@2T)524Q$4%)/5$5#5$E/3E194$5?34%8("8F(&5N +XM;51Y<&4@/CT@2T)524Q$4%)/5$5#5$E/3E194$5?1DE24U0`9V5T8W=D`"5S +XM.B!P``````````$`4YX````` +XM````J``````````!`%4`````````````````````0`````````!;```````` +XM``$`5%L`````````E``````````!`%:4`````````*@``````````0!0```` +XM`````````````````+``````````O@`````````"`'<(O@`````````8`0`` +XM``````(`=R``````````````````````L`````````#+``````````$`5T!````````_0$````````!`%$> +XM`@```````"L"`````````0!1,P(```````!Z`@````````$`5``````````` +XM``````````"0`@```````*8"`````````@!W"*8"````````00,````````" +XM`'<@`````````````````````)`"````````QP(````````!`%7'`@`````` +XM`!4#`````````0!3%0,````````F`P````````$`528#````````00,````` +XM```!`%,`````````````````````D`(```````"S`@````````$`5+,"```` +XM````[`(````````!`%;L`@````````$#`````````0!0#P,````````<`P`` +XM``````$`4`````````````````````"0`@```````+,"`````````0!1LP(` +XM```````A`P````````$`7"8#````````00,````````!`%P````````````` +XM`````````P,````````<`P````````$`4"8#````````-0,````````!`%`` +XM````````````````````4`,```````!1`P````````(`=PA1`P```````%4# +XM`````````@!W$%4#````````7`,````````"`'<87`,```````!R!``````` +XM``(`=S``````````````````````4`,```````!C`P````````$`56,#```` +XM````O`,````````!`%:]`P```````'$$`````````0!6```````````````` +XM`````%`#````````:0,````````!`%1I`P```````+L#`````````0!3O0,` +XM``````!P!`````````$`4P````````````````````!?`P```````'8#```` +XM`````0!1=@,```````!]`P````````$`4'T#````````B`,````````!`%&( +XM`P```````(\#`````````0!0CP,```````"7`P````````$`49<#```````` +XMJ0,````````!`%"]`P```````,H#`````````0!0```````````````````` +XM`+0#````````O0,````````!`%'B`P```````/L#`````````@"18/L#```` +XM````'@0````````!`%$>!````````"T$`````````0!2+00````````]!``` +XM``````$`43T$````````200````````!`%))!````````%<$`````````0!1 +XM5P0```````!R!`````````(`D6``````````````````````M`,```````"Z +XM`P````````$`4/X#````````%00````````!`%`5!````````#D$```````` +XM`0!0.00```````!`!`````````$`4$D$````````9@0````````!`%`````` +XM````````````````@`0```````""!`````````(`=PB"!````````(<$```` +XM`````@!W$(<$````````C`0````````"`'<8C`0```````".!`````````(` +XM=R".!````````)4$`````````@!W*)4$````````E@0````````"`'7!E`'!A<'-Z +XM16YV`$M"54E,1%!23U1%0U1)3TY465!%7T9)4E-4`&QO;F<@:6YT`%]?;6%P +XM;&]W97(`2T)524Q$4%)/5$5#5$E/3E194$5?1E5,3`!P7!E`'!S>E9A<@!?0W5R0!C8VA0E9A;`!+0E5)3$104D]414-424].5%E015]-05@` +XM=6YS:6=N960@8VAA<@!?4G5N95)A;F=E`%]?E!R +XM969I>`!'3E4@0R`T+C(N,2`R,#`W,#7!E7V5X=`!?7VUA<`!? +XM7VUA>```1T-#.B`H1TY5*2`T+C(N,2`R,#`W,#'0`+F1A=&$`+F)S +XM`!K0G5I;&10`````````%L` +XM````````"@```!4```"A`@```````&@`````````"@```!4```"A`0`````` +XM`&\`````````"@```!4````5`0```````'8`````````"@```!4```"L`@`` +XM`````'L`````````"@```!4```!B`0```````(L`````````"@```!4````/ +XM!````````)8`````````"@```!4```!L`````````*,`````````"@```!4` +XM``!:`P```````+D`````````"@```!4```!$`````````,8`````````"@`` +XM`!4```"*`````````-,`````````"@```!4````^`````````.$````````` +XM"@```!4```"!@```````#P'````````"@`` +XM`!0```"``0```````%('````````"@```!0```#``0```````&('```````` +XM"@```!$````(!P```````&P'````````"@```!4```!?`P```````'@'```` +XM`````0````(```"`!````````(`'`````````0````(```"$!0```````(@' +XM````````"@```!$```!W!P```````)$'````````"@```!4```#V`P`````` +XM`)P'````````"@```!$````H"````````*$'````````"@```!4```"Z```` +XM`````*P'````````"@```!$```!Q"````````+$'````````"@```!4````P +XM`P```````+P'````````"@```!$```"Z"````````,H'````````"@```!$` +XM```#"0```````,\'````````"@```!4```!'`@```````-H'````````"@`` +XM`!$```"8"0```````-\'````````"@```!0``````@```````.0'```````` +XM"@```!4````F`0```````.\'````````"@```!$```#."0```````/0'```` +XM`````0````(```!(!0```````/P'`````````0````(```!C!0````````4( +XM````````"@```!4```"[`@```````$@(````````"@```!4```!4`0`````` +XM`%4(````````"@```!4````)`P```````&((````````"@```!4````M`0`` +XM`````/@``````````0````(``````````````!P`````````"@````\````` +XM`````````"```````````0````(``````````````#0`````````"@````\` +XM`````````````#@``````````0````(````@`````````$P`````````"@`` +XM``\``````````````%```````````0````(````P`````````&0````````` +XM"@````\``````````````&@``````````0````(```!``````````(0````` +XM````"@````\``````````````(@``````````0````(```"P`````````*0` +XM````````"@````\``````````````*@``````````0````(````@`0`````` +XM`,P`````````"@````\``````````````-```````````0````(```"0`@`` +XM`````/0`````````"@````\``````````````/@``````````0````(```!0 +XM`P```````!P!````````"@````\``````````````"`!`````````0````(` +XM``"`!````````"``````````"@````(``````````````#@`````````"@`` +XM``(````@`````````%``````````"@````(````P`````````&@````````` +XM"@````(```!``````````(``````````"@````(```"P`````````)@````` +XM````"@````(````@`0```````+@`````````"@````(```"0`@```````-@` +XM````````"@````(```!0`P```````/@`````````"@````(```"`!``````` +XM``8`````````"@````8```````````````8`````````"@````8````````` +X<`````!```````````0````(````````````````` +X` +Xend +ba9c783b814204367d9452f4eebce68e +echo x - ./kmkbuiltin/err.o.uu +sed 's/^X//' >./kmkbuiltin/err.o.uu << '0e59f08b905695fcc4fe4d89f926df6c' +Xbegin 644 ./err.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````.@3```` +XM`````````$```````$``&@`7`%-(B?M(@>S0````2(E4)#`/MM!(B4PD.$B- +XM!)4`````N@````!,B40D0$R)3"1(2(ET)"A(*<)(C80DSP```/_B#REX\0\I +XM<.$/*6C1#RE@P0\I6+$/*5"A#RE(D0\I0('H`````$B+%0````!(BST````` +XMO@`````QP.@`````2(V$).````!(BST`````2(GB2(G>QP0D"````,=$)`0P +XM````2(E$)`A(C40D($B)1"00Z`````!(BS4`````OPH```#H`````$B!Q-`` +XM``!;PV9F9I!F9F:09F:09F:0051!B?Q32(GSO@````!(@>S8````2(E4)#`/ +XMMM!(B4PD.$B-!)4`````N@````!,B40D0$R)3"1(2"G"2(V$),\```#_X@\I +XM>/$/*7#A#REHT0\I8,$/*5BQ#RE0H0\I2)$/*4"!2(L5`````#'`2(L]```` +XM`.@`````2(V$)/````!(BST`````2(GB2(G>QP0D$````,=$)`0P````2(E$ +XM)`A(C40D($B)1"00Z`````!(BS4`````OPH```#H`````$B!Q-@```!$B>!; +XM05S#9F9FD&9F9I!F9I!F9I!!5%-(B?M(@>S8````2(E4)#`/MM!(B4PD.$B- +XM!)4`````N@````!,B40D0$R)3"1(2(ET)"A(*<)(C80DSP```/_B#REX\0\I +XM<.$/*6C1#RE@P0\I6+$/*5"A#RE(D0\I0('H`````$B+%0````!(BST````` +XMO@````!$BR`QP.@`````2(V$)/````!(BST`````2(GB2(G>QP0D"````,=$ +XM)`0P````2(E$)`A(C40D($B)1"00Z`````!$B>?H`````$B+/0````!(B<*^ +XM`````#'`Z`````!(@<38````6T%SH````08G]2(E4)#`/MM!(B4PD.$B-!)4`````N@````!,B40D +XM0$R)3"1(2"G"2(V$),\```#_X@\I>/$/*7#A#REHT0\I8,$/*5BQ#RE0H0\I +XM2)$/*4"!Z`````!(BQ4`````2(L]`````+X`````1(L@,<#H`````$B-A"3P +XM````2(L]`````$B)XDB)WL<$)!````#'1"0$,````$B)1"0(2(U$)"!(B40D +XM$.@`````1(GGZ`````!(BST`````2(G"O@`````QP.@`````1(GH2(N<)-`` +XM``!,BZ0DV````$R+K"3@````2('$Z````,,```````````$1`24.$PL##A$! +XM$@$0!@```B0`"PL^"P,.```#)``+"SX+`P@```06``,..@L["TD3```%`0%) +XM$P$3```&(0!)$R\+```')``+"SX+```($P$##@L+.@L["P$3```)#0`##CH+ +XM.PM)$S@*```*#P`+"P``"Q$$! +XM```"(U@/7W5P``5Y:@$```(C:`]?=7(`!7I%`````B-P"0`````%?6<#```" +XM(W0)``````5^=P,```(C=P]?;&(`!8%!`0```B-X"0`````%A$4````#(X@! +XM"0`````%A2L!```#(Y`!"0`````%AXT#```#(Y@!"0`````%B)D#```#(Z`! +XM"0`````%B44````#(Z@!"0`````%BD4````#(ZP!"0`````%BR`!```#([`! +XM`!`!10```/`"```1W0`````-".`"```0`44````0`P``$=T````1$`,``!%% +XM``````T(&0$```T(]@(``!`!*P$``#8#```1W0```!$K`0``$44`````#0@< +XM`P``$`%%````5@,``!'=````$58#```110`````-"%P#```2&0$```T(/`,` +XM``4P````=P,```:5`````@`%,````(<#```&E0``````$P`````!#0B'`P`` +XM$P`````!#0B3`P``!``````%C'`!```4`0`````!3`$````````````````` +XM`````````/8#```59FUT``%+5@,````````6%V5R<@`!344````8``````%. +XM-@$```.1H'X`&0$``````34!10``````````````````````````````2@0` +XM`!H``````31%`````````!5F;70``316`P```````!88``````$V-@$```.1 +XMD'X`%`$``````4$!``````````````````````````":!```%69M=``!0%8# +XM````````%AL``````4)%`````````!@``````4,V`0```Y&0?@`<`65R<@`! +XM)P%%``````````````````````````````#]!```&@`````!)D4````````` +XM%69M=``!)E8#````````%A@``````2@V`0```Y&0?AL``````2E%```````` +XM```=``````62"@4```$!#0B?`P``'@`````!(U8#```!"0,````````````C +XM`0```@"Z`````0'[#@H``0$!`0````$O=7-R+W!O7!EE(``7@0`0,,!PB0`0``'````!P`````````T@````!!#A"# +XM`DH.X`$````````<````/`````````#2`````$(.$(P"1`X8@P-/#O`!`!P` +XM``!<`````````.8`````0@X000X8@P.,`DH.\`$`'````'P`````````"`$` +XM``!*C`.#!$\.\`&-`@````````````````$``````````@!W"`$````````` +XM"P`````````"`'<0"P````````#2``````````,`=^`!```````````````` +XM````````````````9@`````````!`%5F`````````-$``````````0!3```` +XM`````````````````.``````````X@`````````"`'<(X@````````#F```` +XM``````(`=Q#F`````````/4``````````@!W&/4`````````L@$````````# +XM`'?P`0````````````````````#@`````````%8!`````````0!55@$````` +XM``"Q`0````````$`7`````````````````````#@`````````.X````````` +XM`0!4[@````````"O`0````````$`4P````````````````````#``0`````` +XM`,(!`````````@!W",(!````````PP$````````"`'<0PP$```````#-`0`` +XM``````(`=QC-`0```````*8"`````````P!W\`$````````````````````` +XMP`$````````H`@````````$`52@"````````HP(````````!`%,````````` +XM````````````/@(```````"E`@````````$`7`````````````````````"P +XM`@```````,D"`````````@!W",D"````````N`,````````#`'?P`0`````` +XM``````````````"P`@```````"(#`````````0!5(@,```````"P`P`````` +XM``$`70````````````````````"P`@```````"(#`````````0!4(@,````` +XM``"@`P````````$`4P`````````````````````X`P```````*@#```````` +XM`0!<`````````````````````$$````"```````G!0``J@,``'=AF4`9W!?;V9F`!?;W)I96YT871I;VX`7W5B=68` +XM7W-I>F4`7U]S1DE,10``1T-#.B`H1TY5*2`T+C(N,2`R,#`W,#'0` +XM+G)E;&$N9&%T80`N8G-S`"YD96)U9U]A8F)R978`+G)E;&$N9&5B=6=?:6YF +XM;P`N`!?7V5R +XM`!W87)N`'-T`P````````(````1```` +XM_/________\E`P````````(````2````_/________\L`P````````(````3 +XM````_/________\Q`P````````H````(```````````````[`P````````(` +XM```4````_/________]*`P````````(````3````_/________]S`P`````` +XM``(````5````_/________][`P````````(````9````_/________^"`P`` +XM``````(````3````_/________^*`P````````H````(````!0````````"1 +XM`P````````(````4````_/________\```````````$````(````"P`````` +XM```&``````````H````%```````````````,``````````H````.````GP`` +XM```````1``````````H````.````1`$````````5``````````$````"```` +XM```````````=``````````$````"````N`,````````E``````````H````' +XM```````````````L``````````H````.````(0$````````S``````````H` +XM```.````"`$````````Z``````````H````.````.`````````!!```````` +XM``H````.````C`$```````!/``````````H````.````-P$```````!4```` +XM``````H````.````T@````````!A``````````H````.````R0````````!H +XM``````````H````.````V`$```````!O``````````H````.````Z@$````` +XM``!V``````````H````.````D`````````![``````````H````.````OP`` +XM``````"9``````````H````.````:`````````"E``````````H````.```` +XM[P````````"S``````````H````.````W`````````#!``````````H````. +XM````\0$```````#/``````````H````.````GP$```````#@``````````H` +XM```.`````P(```````#S``````````H````.````S0$```````#^```````` +XM``H````.````+0$````````<`0````````H````.````O`$````````A`0`` +XM``````H````.````"P`````````L`0````````H````.````Q@$````````W +XM`0````````H````.````6`````````!"`0````````H````.````)P`````` +XM``!.`0````````H````.````K0$```````!<`0````````H````.````2`(` +XM``````!Q`0````````H````.````3@(```````"E`0````````H````.```` +XM2@````````"S`0````````H````.````'P(```````#/`0````````H````. +XM````LP$```````#=`0````````H````.``````$```````#K`0````````H` +XM```.````^0````````#Y`0````````H````.````%@$````````'`@`````` +XM``H````.````&0(````````5`@````````H````.````40````````!-`@`` +XM``````H````.````0@(```````!;`@````````H````.````@`````````!W +XM`@````````H````.````Y@````````"&`@````````H````.````0@`````` +XM``"5`@````````H````.````+@````````"D`@````````H````.````%P`` +XM``````"S`@````````H````.````A@````````#"`@````````H````.```` +XM-0(```````#1`@````````H````.````E@````````"(`P````````H````. +XM````"P(```````"4`P````````H````.````8`````````"@`P````````H` +XM```.````*P(```````"L`P````````H````.````(0````````"S`P`````` +XM``$````"``````````````"[`P````````$````"````T@````````##`P`` +XM``````H````+``````````````#6`P````````H````+````30````````#G +XM`P````````H````.````AP$```````#X`P````````H````.````,`(````` +XM```#!`````````$````"````X``````````+!`````````$````"````L@$` +XM```````3!`````````H````+````@P`````````0(```````#?!`````````H````.````AP$```````#N!`````````H` +XM```.````)0(```````#X!`````````H````+````KP(```````#^!``````` +XM``H````.````=@`````````1!0````````H````.```````````````>!0`` +XM``````$````2``````````````#'``````````$````"```````````````< +XM``````````H````)```````````````@``````````$````"```````````` +XM``!$``````````H````)``````````````!(``````````$````"````X``` +XM``````!L``````````H````)``````````````!P``````````$````"```` +XMP`$```````"4``````````H````)``````````````"8``````````$````" +XM````L`(````````@``````````H````"``````````````!```````````H` +XM```"````X`````````!@``````````H````"````P`$```````"````````` +XM``H````"````L`(````````&``````````H````&```````````````&```` +XL``````H````&```````````````0``````````$````"```````````````` +X` +Xend +0e59f08b905695fcc4fe4d89f926df6c +echo x - ./kmkbuiltin/setmode.o.uu +sed 's/^X//' >./kmkbuiltin/setmode.o.uu << '045cd6eee6e4feeb0303b319509b422a' +Xbegin 644 ./setmode.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````'@Q```` +XM`````````$```````$``'0`:`$%42(7_08GT58GU4TB)^P^$.`$``$B-2P1% +XMB>*)[D&!XDE````/MD'\/&`&9B-!_O?0 +XM(<;VP@1T#XT$_0````!F(T'^]]`AQO;""`^$9O___V8C>?[WUR'^Z5G___]% +XMA=)TBF8+%M=05Q!74%>05_#2(U<)%!,C60D0$B)W^@`````2(G>3(GB +XMOP$```#H`````#'_Z`````")PP^W^.@`````]],QTDR)YK\#````9HE<)##H +XM`````+\@````Z`````!(A;__?__13'_QT0D +XM(`````")1"0(9F9FD&9FD`^V10"#Z%@\('9U187_#X7X`0``08#]/0^$:00` +XM`&:0BT0D((7`=#!(.UPD$`^#2P4``$B%VP^$(0<``,8#6`^W1"0P187V00]% +XMQF8C1"0@9HE#`DB#PP1$#[9M`$6$[0^$5P<``$&`_2P/A4#___](@\4!Z1/_ +XM__]F9F:09F:0#[;`_R3%`````$&#STEFD$B#Q0'I9____T&`SY)F9I#K[D6% +XM]G0+0??&^/___V:0=-Y!@;H`````$B%P$B)P@^$N?S__TB)V$@K1"0H38UD%/A(B50D +XM*$R)9"002(T<$.F$_O__08#];P^$0@(``$&`_74/A7/\__]!@<[`"0``2(/% +XM`40/MFT`08#]9P^%1_S__T&!SC@$``#KY,=$)!P!````QD0D#P#I,/[__T&` +XM_6]T"D&`_74/A>3^__]%A?9$B"L/A$@#``!$B?!$B?)FQT,"__\E``$``(/X +XM`42)\!G)@^`@]]"#^`$9P(/B!/?0@^`$@_H!&=()R/?2@^(("="(0P%! +XM@_\K#X1?`P``08/_+0^$F@,``$&#_ST/A7O^__^`2P$#D.EQ_O__08#\6`^% +XM]_W__T2)X(@##[=$)#!%A?9!#T7&9B-$)`AFB4,"Z=C]__]%A?:X_PT``,8# +XM+4$/1<9FB4,"2(/#!+@K````Z\:#1"0D!$B+?"0H2&-$)"1,C22%`````$R) +XMYN@`````2(7`2(G"#X1;^___2(G82"M$)"A-C604^$B)5"0H3(ED)!!(C1P0 +XMZ9K]__^+5"0;H`````$B%P$B)QP^$&?K__TB)V$@K1"0H38UD//A(B7PD*$R) +XM9"002(T<..EJ^O__@T0D)`1(BWPD*$AC1"0D3(TDA0````!,B>;H`````$B% +XMP$B)QP^$SOG__TB)V$@K1"0H3HUD)_A(B7PD*$R)9"002(T<..GB^O__187V +XMN/\-``#&`RU!#T7&9HE#`DB#PP2X*P```(@##[=$)#!%A?9!#T7&1"'X9HE# +XM`NG\^O__08#]6`^%\OK__P^V1"0(Z]5!@/TMD`^$)P$``$&`_3T/A8;[__^` +XM2P$#Z7W[___&0P$<#[=$)#!FB4,"Z3_\__^#1"0D!$B+?"0H2&-$)"1,C22% +XM`````$R)YN@`````2(7`2(G"#X0,^?__2(G82"M$)"A-C604^$B)5"0H3(ED +XM)!!(C1P0Z9_Z___&0P$<#[=$)#!FB4,"Z>7\__^Y`````+J``0``O@````"_ +XM`````.@`````Z;7Z__^Y`````+J``0``O@````"_`````.@`````Z0;[___& +XM0P$<#[=$)#!FB4,"Z0K^__^`2P$"Z2?[__^Y`````+J``0``O@````"_```` +XM`.@`````Z:+Y__^Y`````+J``0``O@````"_`````.@`````Z<'X__^`2P$! +XMZ>+Z__^`2P$"Z;GY__^`2P$!Z6#Z__^Y`````+J``0``O@````"_`````.@` +XM````ZCI#_;__TB-="1HN@@```!(B>_H +XM`````$B)PDB+1"1H@#@`=3SVQO")U74U2#M<)!!)B=QS6$B%VW1M2(U#!&:! +XMY?\/Q@,M9L=#`O\/QD,$*V:):`+&0`0`3(G@Z;3U__](B=_H`````#'`Z:7U +XM__^Y`````+K*`0``O@````"_`````.@`````Z6W^__^^,````$B)W^@````` +XM2(7`=,%(B<-)B<3KCKD`````NH`!``"^`````+\`````Z`````#I=?___P`` +XM``$1`24.$PL##A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+.PM)$P``!"0` +XM"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8`21,```D3`0,. +XM"PLZ"SL+`1,```H-``,..@L["TD3.`H```L!`4D3`1,```PA`$D3+PL```T3 +XM`0L+.@L["P$3```.$P$+!3H+.PL!$P``#Q4!)PQ)$P$3```0!0!)$P``$0T` +XM`P@Z"SL+21,X"@``$BX!/PP##CH+.PLG#$D3$0$2`4`&`1,``!,%``,..@L[ +XM"TD3`@8``!0T``,(.@L["TD3```5-``##CH+.PM)$P(&```6"@`##CH+.PL1 +XM`0``%S0``PY)$S0,`@H``!@F````&2X!`PXZ"SL+)PQ)$R`+`1,``!H%``,( +XM.@L["TD3```;+@$##CH+.P4G#$D3(`L!$P``'`4``P@Z"SL%21,``!T%``,. +XM.@L[!4D3```>+@$##CH+.P4G#"`+`1,``!\T``,..@L[!4D3```@-``#"#H+ +XM.P5)$P``(04``P@Z"SL+21,"!@``(C0``P@Z"SL+21,"!@``(S0``PXZ"SL+ +XM21,""@``)`H``PXZ"SL%```E"@`##CH+.P41`0``)AT!,1,1`1(!6`M9"P$3 +XM```G!0`Q$P``*`4`,1,"!@``*0L!508!$P``*AT!,1-5!E@+604!$P``*PL! +XM$0$2`0$3```L"P%5!@``+30`,1,``"XT`#$3`@8``"\T``,..@L["TD3```P +XM'0$Q$U4&6`M9"P``,30``PXZ"SL+21,_##P,````?P@```(```````@!```` +XM``$````````````````````````````````"`08``````@$(``````("!0`` +XM```#``````,V20````("!P`````$!`5I;G0``P`````#.&(````"!`<````` +XM`@@%``````,``````SI[`````@@'``````((!``````"!`0``````P`````# +XM4G`````%"`<&"`,`````!#$^`````P`````$5E`````#``````17JP````(! +XM!@`````#``````4T8@````<(P0````<(WP````C!`````P`````%RZ`````) +XM`````!`&,PH!```*``````8T"@$```(C```+5P```!H!```,FP````,``P`` +XM```&->\````#``````V`````B,("@`````(.'$!```"(Q``!PA[```` +XM`P`````(.3`!```-$`@[IP$```H`````"#Q0`````B,`"@`````(/:P`````#```,FP```/\`"[8````0`P``#)L` +XM``#_``,`````"%>X`0```@@%``````D`````!`%'60,``!%C;60``4C!```` +XM`B,`"@`````!2<$````"(P$*``````%*Y`````(C`@`#``````%+(@,``!(! +XM``````%O`>0```````````````````````````````,$```3``````%M`P0` +XM```````3``````%NY``````````4@&=!```'&]P``%\`5`````<=VAO``%[`5`````=```` +XM``%[`5`````=``````%]`<@````7`````%`(```!"0,````````````'"%D# +XM```>``````'&`0$!#04``!QS970``<4!G00``!\``````<`9T$````*CL$`````````4\!?@8` +XM`"=\!```)W`$```G9`0``"=9!```)TT$````*CL$`````````5X!J`8``"=\ +XM!```)W`$```G9`0``"=9!```)TT$````*CL$`````````48!T@8``"=\!``` +XM)W`$```G9`0``"=9!```)TT$````*CL$`````````4P!_`8``"=\!```)W`$ +XM```G9`0``"=9!```)TT$````*CL$`````````5H!)@<``"=\!```)W`$```G +XM9`0``"=9!```)TT$````*P````````````````````!(!P``'P`````!3P&= +XM!````"L`````````````````````:@<``!\``````5H!G00````K```````` +XM`````````````(P'```?``````%&`9T$````*P````````````````````"N +XM!P``'P`````!3`&=!````"JC!`````````%P`>L'```GL00``"P`````+;T$ +XM```NR00````````MU00``"WA!```+NT$```````````I```````(```O```` +XM``'WG00````P.P0````````!]R=\!```)W`$```G9`0``"=9!```)TT$```` +XM``A_`@``"\$````["```#)L````-``@K"```"\$```!0"```#)L````&``A` +XM"```,0`````"6E`````!`3$`````"%L0`P```0$Q``````A7!E7!E7!E+F@``@`````)`@```````````^X``2\U<3T#,V,#4N\#.0(I +XM`0-V1P,*.0-'';\#"=,#"N]65KA6U%8##G\#44<#$;="O%;Q5L96XHX#%<56 +XM`V%C`QK3`U'%`]4``B,!`PO]`Z(!52P#YW[A5E2`\?XMF5=:"$J3!`(#D']' +XM!`$#^``(1P,*"$<#=E4#"CD#$@BI`\D`"!T#NW_]`_4`?P.'?T=.`_(`"!T# +XMD'^I`SFI"$V``R*I`PV-.@,9"$<#OG]'U9T#M7_O`QV;`V)C`QB-`WJ-\'(# +XM=HWP`WB-`R6-5@,ZQ8\#)0)'`0.B?W&=""P#-*D##8TZ`QG]`V=_`QE'`ZA_ +XM1P,QJ0-/.0,Q564#)0([`0.Q?PA5G0,FJ8\#)0(\`0-;C0,3[S@Z9&9@`PD" +XM,P&J`Z]_C0.T?P)+`0@^`WIQ2.D#/HT#.0@=`Q/O.#ID9F`#"0(S`9V=G`-> +XMFP,+Q2P#=PB-?CJ``U2I`DL,N`,JQ0,+Q2P#=PAQ?CJ`I0,3[S@Z9&9@`PD" +XM,P&=G9P#X7Z-`PG3`]``C0-H`DL!`S\"2P%^.H"4+`-T"'$#'_VKG`-WC4@# +XML'_3`\\``DL!2`-DTP,;`CP!2-<#8(T#(@(\`8N/`UZ-`R((Q0-(C58#WP`Y +XMNPAD@#CB8L0#"PB;2T@#=K=($#K7X(Q0.)`0B-`AX``0%B +XM8F]X("$]($Y53$P`!`,!PB0`0```````"0```````````````````!K`0```````$(.$(P" +XM1PX8A@-##B"#!``\````````````````````R0H```````!"#A!"#AA"#B!" +XM#BA!#C"&!HP%C02.`X\"1`XX1`ZP`8,'````````%``````````!>E(``7@0 +XM`0,,!PB0`0``'````!P`````````:P$```!"#A",`D<.&(8#0PX@@P0T```` +XM/`````````#)"@```$(.$$(.&$(.($(.*$$.,(8&C`6-!(X#CP)$#CA$#K`! +XM@P<``````````````````@`````````"`'<(`@`````````)``````````(` +XM=Q`)``````````P``````````@!W&`P`````````:P$````````"`'<@```` +XM````````````````````````````%0`````````!`%45`````````$\````` +XM`````0!33P````````!6``````````$`558`````````:P$````````!`%,` +XM```````````````````````````````5``````````$`5!4`````````4``` +XM```````!`%96`````````&L!`````````0!6`````````````````````#$` +XM````````XP`````````!`%7C`````````.L``````````0!5ZP`````````> +XM`0````````$`51X!````````(`$````````!`%4@`0```````$T!```````` +XM`0!5`````````````````````!X`````````50`````````!`%15```````` +XM`%4``````````0!05@````````!D``````````$`5'``````````E@`````` +XM```!`%26`````````,P``````````0!4VP````````#]``````````$`5/T` +XM````````30$````````!`%0`````````````````````,0````````!L```` +XM``````$`6'``````````LP`````````!`%BS`````````-(``````````0!8 +XMVP`````````U`0````````$`6#4!````````.0$````````!`%@Y`0`````` +XM`$T!`````````0!8`````````````````````'`!````````<@$````````" +XM`'<(<@$```````!T`0````````(`=Q!T`0```````'8!`````````@!W&'8! +XM````````>`$````````"`'<@>`$```````!Y`0````````(`=RAY`0`````` +XM`'T!`````````@!W,'T!````````@0$````````"`'B@(```````!Y"P````````$` +XM7N,+`````````0P````````!`%X`````````````````````B`$```````"7 +XM`0````````,`D;A_DPL```````"8"P````````,`D;A_F`L```````"I"P`` +XM``````$`4*D+````````XPL````````#`)&X?P$,````````#@P````````! +XM`%`.#````````#D,`````````P"1N'\`````````````````````B`$````` +XM``"-`0````````$`4_4!````````F`H````````!`%/""@```````#<+```` +XM`````0!32PL```````!Q"P````````$`4WD+````````L@L````````!`%.R +XM"P```````,\+`````````0!0SPL````````Y#`````````$`4P`````````` +XM``````````"(`0```````)`!`````````0!0L````````# +XM`)'X?J<+````````XPL````````!`%SC"P````````$,`````````0!6`0P` +XM```````Y#`````````$`7`````````````````````"(`0```````)!P```````&<'`````````0!09P<```````#A"`````````,` +XMD8!_X0@```````#J"`````````$`4.H(````````.0P````````#`)&`?P`` +XM``````````````````"(`0```````)`@````````#`)'T?G@(````````B`@````````!`%"T"``````` +XM`#H)`````````P"1]'XZ"0```````$H)`````````0!0=@D```````!Y"P`` +XM``````,`D?1^XPL````````!#`````````,`D?1^```````````````````` +XM``("````````"0(````````!`%`)`@```````&P"`````````0!00L```````"+"P````````$`4`````````````````````"(`0`` +XM`````)0!?7VEN=F%L:61?7!E7V5X +XM=`!"251#340`7U]M87!U<'!E'0`8VQR8FET0!?7VUA>`!?7W-P=71R=6YE`%]? +XM;6%P;&]W97)?97AT`&QO;F<@=6YS:6=N960@:6YT`&1O=6)L90!C;VUM;VX` +XM7U)U;F5,;V-A;&4`;6%S:P!B8F]X`'-I9W-E=%]T`'!E6UT86(`+G-T%(````````8`````````!L````3````"``` +XM```````8`````````-(````!`````````````````````````)8I```````` +XM,`````````````````````$```````````````````#-````!``````````` +XM``````````````"04@```````#``````````&P```!4````(`````````!@` +XM````````X0````$`````````````````````````QBD````````0`P`````` +XM`````````````0```````````````````.\````!````,``````````````` +XM`````-8L`````````@`````` +XM`%("````````"@```!0````B`@```````&$"````````"@```!0```#5`0`` +XM`````'`"````````"@```!0````4`````````!$#````````"@```!0```#- +XM`@```````!X#````````"@```!0````W`0```````",#````````"@```!0` +XM``#@`0```````#T#````````"@```!0````'`@```````$L#````````"@`` +XM`!0```!%`0```````%H#````````"@```!0````;`@```````&8#```````` +XM"@```!0```#W`@```````'$#`````````0````(``````````````'D#```` +XM`````0````(```!K`0```````($#````````"@```!```````````````(H# +XM````````"@```!0```#>`@```````)0#````````"@```!````!@```````` +XM`)D#````````"@```!0```#M`0```````*,#````````"@```!````"\```` +XM`````+,#````````"@```!0```"E`````````+T#````````"@```!`````% +XM`0```````,(#````````"@```!0```"L`````````,P#````````"@```!`` +XM``!T`0```````-$#````````"@```!0```"?`````````-L#````````"@`` +XM`!`````)`@```````.`#````````"@```!0```#&`@```````.8#```````` +XM`0````(```!P`````````.\#````````"@```!0```#^`0```````/H#```` +XM`````0````L````=`0```````!8$````````"@```!0````Q`P```````#P$ +XM````````"@```!0```!G`@```````'$$````````"@```!0````C```````` +XM`'T$````````"@```!0```#9`@```````(D$````````"@```!0```#^`0`` +XM`````)0$`````````0````L````(`0```````*0$````````"@```!0````& +XM`````````+X$````````"@```!0````?`0```````,H$````````"@```!0` +XM```U`````````-8$````````"@```!0````Q`@```````.($````````"@`` +XM`!0```#G`0```````/D$````````"@```!0```#^`0````````0%```````` +XM`0````L````/`0````````\%````````"@```!0```#_`@```````!H%```` +XM`````0````(```!P`0```````"(%`````````0````(````Y#````````"H% +XM````````"@```!````"+`@```````#L%````````"@```!`````\`P`````` +XM`$`%````````"@```!0```#L`@```````$H%````````"@```!````"^`P`` +XM`````%D%````````"@```!````!`!````````'$%````````"@```!````"O +XM!````````(`%````````"@```!`````Y!0```````(4%````````"@```!0` +XM```A`P```````(\%````````"@```!````#.!0```````)0%````````"@`` +XM`!0```"T`````````)X%````````"@```!````#T!@```````*,%```````` +XM"@```!0````I`P```````+(%````````"@```!0```"-`````````,$%```` +XM````"@```!0```#9`@```````,L%````````"@```!`````N!P```````-`% +XM````````"@```!0```#$`````````-H%````````"@```!````"D"``````` +XM`-\%````````"@```!0```!B`````````.D%````````"@```!````#S"``` +XM`````.X%````````"@```!0````:`P```````/@%````````"@```!````!" +XM"0```````/T%````````"@```!0```!B`P````````4&````````"@```!0` +XM``!S`0````````P&`````````0````(```#X`@```````!D&`````````0`` +XM``(````"`@```````"$&`````````0````(````7`@```````#D&```````` +XM"@```!````!9"@```````#\&````````"@```!,``````````````$@&```` +XM````"@```!0```!%`P```````%D&````````"@```!,````P`````````(,& +XM````````"@```!,```#0`````````*T&````````"@```!,````0`0`````` +XM`-<&````````"@```!,```"0`0````````$'````````"@```!,```#``0`` +XM`````"<'`````````0````(```!^!0```````"\'`````````0````(```#) +XM!0```````#P'````````"@```!0```!%`P```````$D'`````````0````(` +XM``#./kmkbuiltin/strmode.o.uu << '665ec2e03604b3bfba9eb90e1fba7d44' +Xbegin 644 ./strmode.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````)`-```` +XM`````````$```````$``&P`8`%6)_5-(B?-(@^P(2(7V#X00`P``#[?-B<@E +XM`/```#T`8```#X37`@``#X[T````/0"@```/A+8"``!F9I!F9I`/CNH!```] +XM`,```&9FD&:0#X2V`@``/0#@``!F9I!FD`^%X````/;%`<8#=TB-0P$/A>,` +XM``#&`"U(@\`!A,D/B.,```#&`"U(C5`!B<@E0`@``(/X0`^%XP```,8">$B# +XMP@'VP2`/A>T```!F9F:0]L$0Q@(M2(U"`0^%Z0```,8`+4B-4`&)R"4(!``` +XM@_@(#X7I````Q@)X2(/"`?;!!`^%\P```/;!`L8"+4B-0@$/A?,```#&`"U( +XMC5`!B<@E`0(``(/X`0^%\P```,8">$B#P@'&`B#&0@$`2(/$"%M=PST`(``` +XM#X3J`0``/0!````/A`X!```]`!```&:0#X2<`0``2(U#`<8#/V9FD/;%`0^$ +XM'?___\8`````/0$"``!U!\8"=$B#P@'&`B#&0@$`2(/$"%M=PV:0/0"````/ +XMA0O___](C4,!Q@,MZ0G___](C4,!Q@-DZ?W^__\]``0``'0[/0@$``"0#X5K +XM____Q@)S2(/"`69FD.E<____/0`(``!T)3U`"```#X4)____Q@)S2(/"`6:0 +XMZ?O^___&`E-(@\(!Z3#____&`E-(@\(!Z>/^__]F9I#&`E1(@\(!Q@(@QD(! +XM`$B#Q`A;7<.%P`^%4____\8"+4B#P@'&`B#&0@$`2(/$"%M=PTB-0P'&`W#I +XM8O[__V:02(U#`<8#;.E4_O__9F9FD$B-0P'&`V+I1/[__TB-0P'&`W/I./[_ +XM_TB-0P'&`V/I+/[__[D`````NCX```"^`````+\`````Z`````#ITOS__P`` +XM`1$!)0X3"P,.$0$2`1`&```")``+"SX+`PX```,6``,..@L["TD3```$)``+ +XM"SX+`P@```4D``L+/@L```8/``L+21,```@````<`#?$`````4`$```(`HP````$!^PX*``$!`0$````!+W5S +XM7,``'-T7!E+<"'@`!`7`@ +XM(3T@3E5,3```````````+W5SE(``7@0`0,,!PB0 +XM`0``'````!P`````````0@,```!!#A"&`D,.&(,#1PX@``````````````$` +XM`````````@!W"`$`````````!``````````"`'<0!``````````+```````` +XM``(`=Q@+`````````$(#`````````@!W(``````````````````````````` +XM`````!0``````````0!5%``````````B`0````````$`5B(!````````(P$` +XM```````!`%4C`0```````"T"`````````0!6+0(````````N`@````````$` +XM52X"````````Q`(````````!`%;$`@```````,4"`````````0!5Q0(````` +XM``#A`@````````$`5N$"````````X@(````````!`%7B`@```````$(#```` +XM`````0!6````````````````````````````````%``````````!`%04```` +XM`````'```````````0!3<`````````",``````````$`4(P`````````N@`` +XM```````!`%&Z`````````,<``````````0!0QP````````#Q``````````$` +XM4?$`````````_@`````````!`%#^`````````",!`````````0!1(P$````` +XM``!*`0````````$`4TH!````````30$````````!`%!-`0```````%D!```` +XM`````0!360$```````!O`0````````$`4&\!````````HP$````````!`%&C +XM`0```````+`!`````````0!0L`$```````#D`0````````$`4>0!```````` +XM\0$````````!`%#Q`0```````"X"`````````0!1+@(````````_`@`````` +XM``$`4S\"````````1P(````````!`%!'`@```````$L"`````````0!32P(` +XM``````!3`@````````$`4%,"````````X@(````````!`%'B`@```````.8" +XM`````````0!3Y@(```````#N`@````````$`4.X"````````]`(````````! +XM`%/T`@```````/P"`````````0!0_`(````````$`P````````$`4P0#```` +XM````#`,````````!`%`,`P```````!`#`````````0!3$`,````````8`P`` +XM``````$`4!@#````````'`,````````!`%,<`P```````"0#`````````0!0 +XM)`,````````S`P````````$`5#,#````````0@,````````!`%,````````` +XM````````````&@````(```````6UT86(`+G-T!8```````!@`````````!D````! +XM````"``````````8`````````"8````!`````P```````````````````(0# +XM``````````````````````````````0````````````````````L````"``` +XM``,```````````````````"$`P`````````````````````````````$```` +XM````````````````,0````$`````````````````````````A`,```````"@ +XM`````````````````````0```````````````````$0````!```````````` +XM`````````````"0$````````!P$```````````````````$````````````` +XM```````_````!`````````````````````````#8%@```````*`"```````` +XM&0````8````(`````````!@`````````50````$````````````````````` +XM````*P4```````!4`0```````````````````0```````````````````%`` +XM```$`````````````````````````'@9````````&``````````9````"``` +XM``@`````````&`````````!A`````0```#(```````````````````!_!@`` +XM``````H````````````````````!``````````$`````````<`````$````R +XM````````````````````D`8```````!'````````````````````"``````` +XM```!`````````'\````!`````@```````````````````-<&````````"``` +XM``````````````````$```````````````````",`````0`````````````` +XM``````````#@!@```````$`````````````````````(```````````````` +XM````AP````0`````````````````````````D!D````````P`````````!D` +XM```-````"``````````8`````````)X````!`````@`````````````````` +XM`"`'````````.`````````````````````@```````````````````"9```` +XM!`````````````````````````#`&0```````!@`````````&0````\````( +XM`````````!@`````````J`````$`````````````````````````6`<````` +XM``#$`P```````````````````0```````````````````+@````!```````` +XM`````````````````!P+````````'@````````````````````$````````` +XM``````````"S````!`````````````````````````#8&0```````!@````` +XM````&0```!(````(`````````!@`````````S0````$````````````````` +XM````````.@L````````P`````````````````````0`````````````````` +XM`,@````$`````````````````````````/`9````````,``````````9```` +XM%`````@`````````&`````````#<`````0```#````````````````````!J +XM"P````````D!```````````````````!``````````$`````````YP````$` +XM`````````````````````````````````#H`````````"@```!$```#V`````````#\`````````"@`` +XM`!$```"3`````````$P`````````"@```!$```#(`````````%H````````` +XM"@```!$``````````````&$`````````"@```!$```"Q`````````&@````` +XM````"@```!$````R`````````&\`````````"@```!$```"Z`````````'8` +XM````````"@```!$```#P`````````'X`````````"@```!$```#G```````` +XM`(L`````````"@```!$```"L`````````)8`````````"@```!$```#!```` +XM`````*(`````````"@```!$```!$`````````*@``````````0````(````` +XM`````````+```````````0````(```!"`P```````+@`````````"@````X` +XM`````````````,$`````````"@```!$````M`````````,L`````````"@`` +XM``X```!@`````````-@`````````"@````X````N`0```````-T````````` +XM"@```!$``````0```````.@``````````0````L``````````````+`````` +XM`````0````(``````````````!P`````````"@````P``````````````"`` +XM`````````0````(``````````````"``````````"@````(````````````` +XM``8`````````"@````8```````````````8`````````"@````8````````` +X<`````!```````````0````(````````````````` +X` +Xend +665ec2e03604b3bfba9eb90e1fba7d44 +echo x - ./kmkbuiltin/kbuild_version.o.uu +sed 's/^X//' >./kmkbuiltin/kbuild_version.o.uu << '7a5d72540cc986f1046b76957afa7b12' +Xbegin 644 ./kbuild_version.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````'`&```` +XM`````````$```````$``&@`7`%.^`````$B)^TB#[!#H`````$B%P'062(U8 +XM`;X`````2(G?Z`````!(A!`!`PP'")`!```<````'`````````!]`````$$.$(,"3`X@```````````` +XM`````````0`````````"`'<(`0`````````-``````````(`=Q`-```````` +XM`'T``````````@!W(````````````````````````````````!(````````` +XM`0!5$@````````!P``````````$`4W$`````````?0`````````!`%,````` +XM````````````````%0`````````H``````````$`4"L`````````.@`````` +XM```!`%`]`````````%T``````````0!0<0````````![``````````$`4``` +XM```````````````````A`````@``````Q0```(0```!K8G5I;&1?=F5R6UT86(`+G-T /dev/null 2>&1 +echo x - ./glob/glob.o.uu +sed 's/^X//' >./glob/glob.o.uu << '08f54ce57ae16ee49e80e07b25b53cad' +Xbegin 644 ./glob.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````*!V```` +XM`````````$```````$``'``9``^V!X3`=":%]G5'2(U7`3')/%MT,W\:/"IT +XM)SP_9F:0="`/M@)(@\(!A,!UY#'`D,,\7'3M/%UUZ87)9F:09I!TX+@!```` +XMPP^V`KD!````Z],QTCQ;=!M_)SPJ9F9FD'3@/#]TW$B#QP$/M@>$P'7CZ[I( +XM@\M%9F9FD&9FD$R)XDR) +XM_DB)Q^@`````0L8$(R])BW3M`$F-?!P!3(GRZ`````!)BWSM`.@`````28E< +XM[0!(@\4!2#LL)'1428M\[0#H`````$F-?`0"3(UP`>@`````2(7`2(G#=:)( +XMA>UT&TF-7.T`2(M[^$B#[0%(@^L(Z`````!(A>UUZDB#Q`BX`0```%M=05Q! +XM74%>05_#2(/$"#'`6UU!7$%=05Y!7\-%,>1!@#\O00^5Q.DW____9F9FD&9F +XMD&9FD&9FD$B+/TB+-C'`2#GW=`=(A?^P`74"\\-(A?:X_____W3TZ0````!F +XM9F:09F9FD&9FD%5(B>5!5T%628GV055!5$F)S%.)TX/C0$B![+@```!(B;TP +XM____B94L____3(F%(/___P^V!X3`=#&%VP^$604``$B)^C')/#\/A-$```"0 +XM#X^R````/"H/A,(```!FD$B#P@$/M@*$P'7<]X4L____$`@```^$?P0``(.- +XM+/___Q!(QX4X____`````/:%+/___Q!(QX5`____``````^$V0(``$B+O3#_ +XM___H`````$B#["!(C7@!2(G#3(U\)`])@^?P2<<'`````.@`````2(7`28E' +XM"`^$&`,``$B+M3#___](B=I(B%0/___P$```#I +XMBP$``#Q;#X3#`@``/%T/A4C___^%R0^$0/____>%+/___P`"```/A:T"``!, +XMB??H`````$B)A3C___](@[TX____``^$<@,```^VA2S___](QX5`____```` +XM`(/@@#P!&<"#X`2#^P%%&?:!C2S___\``0``13'_BYTL____0??608/F`D$) +XMQH'C``(``(F=3/___XN53/___X72#X3*````2(N5(/___TB+O3C_____4BA( +XMA<`/A,4```!,C6`(2(N],/___T2)\DR)YN@`````A-,C6PD +XM#TF#Y?"+`TB#PP2-D/_^_O[WT"'"@>*`@("`=.B)T,'H$/?"@(````]$T$B- +XM0P)(#T38`-)(@]L#3"GC2(U[`>@`````2(7`2(G'28E%"`^$S@$``$B)VDR) +XMYN@`````28M%",8$&`"+E4S___](@X5`____`4V)?0!-B>^%T@^%//___V9F +XMD&9FD$B+O3C____H`````$B%P`^%.____TB#O4#___\`#X3Z_?__2(N=(/__ +XM_TB+`XN=+/___X/C"`^$X@$``$B+C2#___](BU$02(MY"$B+C4#___](C40! +XM`4@!T,'@`TB%_P^$Q@$``(G&Z`````!(B<9(BX4@____2(7V2(EP"`^$M`$` +XM`(7;#X1P`0``2(N-(/___TB+G2#___](BQ%(.U,02(G1;^__](B[TX____2(N-(/__ +XM__]1(.N72(N-(/___S'2Z1O^__^)Q^@`````Z37^__^+E2S___^!X@`"``") +XME4S____I2?___^@`````@S@4#X2U^___387D=!'H`````$R)]XLP0?_4A_H`````$'&1!T` +XM+TB+M3#___]*C7PK`4F-5"0!Z`````#WA2S___\``@``="9(BY4@____2(VU +XM4/___TR)[_]20(7`#Y3`A,`/A`+[___I]OK__TB-M5#___],B>_H`````(7` +XM#Y3`Z]U(BY4P____,"%R69F9I!TV.DY^___2(/"`8`Z`&:0 +XM=5!5TF)ST%6055)B?U!5%-(@>R(`0``2(7_ +XMB;5P_O__2(F5:/[__W0-2(7)=`B!Y@"!__]T*F9F9I!F9I#H`````$&\____ +XM_\<`%@```$B-9=A$B>!;05Q!74%>05_)P_>%P`` +XM`.@`````2(7`28G$#X0G`0``2(FE>/[__TR)[TR)X^@`````2(/`'4PIZTR) +XM[DB#X/!(B=I(*<1,C70D#TF#YO!,B?=)C1P>Z`````!)C40D`4B)G9#^__\Q +XMTDB)A?#^__]!#[9$)`%(BYWP_O__A=(/A.(#``"$P'1H/'UU"H/J`69F9I!F +XM9I!(@\,!#[8#A,!T3SQ]=?&%TG7C2(7;2(G:=#\\?69FD`^$10T``$B#P@$Q +XMR0^V`H7)#X1<"```A,!T'SQ]=0.#Z0%(@\(!#[8"A,!T#3Q]=?&%R77J2(72 +XM=<&!I7#^____^___2(N5:/[__TR)^8NU/[_ +XM_^G&_O__2&.%X/[__T4QY$DY!W7E]X5P_O__$`@``$&T`W362(NE>/[__[XO +XM````3(GOZ`````!(AY-*>Y)C48?3(GR2(/@\$@IQ$B-7"0/2(/C\$B)WTF)W>@`````0L8$ +XM,P!(@X6`_O__`4B+A8#^__^`.``/A9T!``!)@_X!#X:3`0``B[5P_O__2(N5 +XM:/[__TR)^4B)WX/.`N@`````A,`4``` +XM]H5P_O__('4/2<<'`````$G'1P@`````28L'A=M(B86(_O__=`M!@'T`?@^$ +XMFP0``$B#O8#^__\`#X1S`@``00^V10"+E7#^__^#XD"$P'0NA=(/A$D-``!, +XMB>HQR3P_#X3W````#X_5````/"H/A.D```!(@\(!#[8"A,!UWTB+C6C^__^+ +XME7#^__]-B?A(B[V`_O__3(GNZ,_V__^%P$&)Q`^%%?W__TV%]@^$?P,``/:% +XM](*<+H +XM6/7__X7`#X1$`P``28M7"$B%T@^$'0D``$F#/P!T'3';2(L\VDB%_W0)Z``` +XM``!)BU<(2(/#`4DY'W?E2(G70;P!````Z`````#ICOS__XN=$2+ +XMM7#^__]%,>1!@^;.08/.($B+18A(BXUH_O__38GX2(N]@/[__T2)\DV++TJ+ +XM-.#HI/7__X/X`XG#="Z%P`^%+00``$F+%TB+18A)8_5(*?)(P>8#20-W"$J+ +XM/.#H1_3__X7`#X6*!```2(M=@$F#Q`%,.>-WFH&-P^4PDB#PP$/M@/IZ_O__[D!````Z0+^__^+G7#^ +XM__^!XP!0``!T'4&`?0!^=19,B>_H`````$F)QNEI_?__9F:09F:03(FM@/[_ +XM_T4Q]D&]`````.E._?__]H5P_O__$`^$O@```(N= +XM,=M(BSS82(7_=`GH`````$B+18A(@\,!2#E=@'?D2(G'Z`````#VA7#^__\" +XM#X1R`0``2(N%B/[__TDY!P^&8@$``$2+M7#^__](B<-)B<1(P>,#08'F``(` +XM`.M$28M'"$B-M0#___](BSP#0?]70(7`#Y3`A,!T%P^WA0C___\E`/```#T` +XM0```#X23`@``28/$`4B#PPA-.2_H`````$B%P$B)A:C^__]T.4B)PTB+M;#^__],*>M(C4,>2(G: +XM2(/@\$@IQ$R-9"0/28/D\$R)Y^@`````0<9$'/\`3(FEL/[__TB+O;#^___H +XM`````$B%P`^%"`4``/>%,=M(BSS82(7_=`GH`````$B+18A(@\,!2#E=@'?D2(G' +XM0;P!````Z`````#I#OC__T4QY/:%1(*?Y(P><#20-_ +XM".@`````Z;GW__](@WV(`'0V2(-]@``/A#L$``!(BT6(13'D2HL\X$B%_W0) +XMZ`````!(BT6(28/$`4PY98!WY$B)Q^@`````28M7"$&)W$B%T@^$;/?__TF# +XM/P!T($4QY&:02HL\XDB%_W0)Z`````!)BU<(28/$`4TY)W?E2(G708G@````` +XM2(M%B$B#PP%(.5V`=^1(B`#2(7_#X1W`@``B<;H`````$B%P$F)1P@/A(G]__]%A>UT+4F+#TDY +XM3Q!V)$B--,T`````2(G"2(/!`4C'!!8`````2(/&"$DY3Q!)B0]WYTB#?8`` +XM#X2C^___BX5P_O__13'M)0`"``")A=S^___K,TB-M0#___],B>=!_U=`A%H/[__P````!(BX6P +XM_O__3(NMH/[__X`X``^$H/;__TR)[^@`````28G$28U$!AY,B>Y,B>)(@^#P +XM2"G$2(U<)`](@^/P2(G?28G=Z`````!(B[6P_O__2HT\(TR)\N@`````Z5?V +XM__])BU<0Z?#X__])BQ=F9F:09F:0Z4'Y__](C;4`____3(GOZ`````"%P`^$ +XMFOG__^DD^/__28M7$.F<_?__0;P!````Z9SS__^)Q^@`````9F9FD.G`^/__ +XMBC^__])C3P$Z`````!(BY5H_O__B[7\ +XM_O__3(GY3(GWZ`````"%P$&)Q'1.@_@#=$F+M73^__^%]@^%2?+__TF#?P@` +XM#X0^\O__28,_``^$Q@```$F+5P@QVTB+/-I(A?]T">@`````28M7"$B#PP%) +XM.1]WY>FD````@#M]#X01\O__#[93`4R-0P$QP$R)P87`=#6$TG14@/I]=0.# +XMZ`%(@\$!#[81A-)T08#Z?77PAND,=NY`````+KL`0`` +XMO@````"_`````$R)A5C^___H`````$R+A5C^___IO?[__TF+5PA(B=?H```` +XM`.E=\?__28M7".F%\___2(M%B)#I]?W__TR)ZC')/%MT*&:0?RL\*@^$IO/_ +XM_SP_9F9FD`^$FO/__TB#P@$/M@*$P'79Z:SR__^Y`0```.OI/%R0=!,\777@ +XMA\````"@`````$"`$D`0``"P`````0!2X!`@``#``` +XM```%+\$!```"(P`,``````4PB@````(C"``+`````'@&@_P"```,``````:$ +XM+P$```(C``P`````!H6*`0```B,$#``````&AI4!```"(P@,``````:'H`$` +XM``(C"@P`````!HC,`0```B,,#``````&B7\!```"(Q`,``````:*+P$```(C +XM%`P`````!HS8`0```B,8#``````&C=@!```"(R@,``````:.V`$```(C.`P` +XM````!I>K`0```B-(#``````&F&D!```"(U`,``````:97@$```(C6`P````` +XM!IIT`0```B-<#``````&FVT````"(V`,``````:<6P````(C9`P`````!I[8 +XM`0```B-H``L`````4`=THP,```P`````!W5-`0```B,`#``````'=DT!```" +XM(P@,``````=WS`$```(C$`P`````!WA_`0```B,4#``````'><$!```"(Q@, +XM``````=Z30$```(C(`P`````!WM-`0```B,H#``````'?$T!```"(S`,```` +XM``=]30$```(C.`P`````!W[!`0```B-`#``````'?V8````"(T@`#0`````( +XM`0@R]P,```P`````"#-M`````B,`#``````(-$D````"(P0,``````@U,``` +XM``(C!@P`````"#8P`````B,'#``````(.?<#```"(P@`#CH!```'!```#\<` +XM``#_``L`````4`E"H`0```P`````"4-F`````B,`#``````)1(H````"(P@, +XM``````E%B@````(C$`P`````"49-`0```B,8#``````)1V8````"(R`,```` +XM``E(B@````(C*`P`````"4F*`````B,P#``````)2F8````"(S@,``````E+ +XM00$```(C0`P`````"4RF!````B-(``@``````0<(H`0```((!0`````02`IY +XM.@4```P`````"GJV`0```B,`#``````*>SH%```"(P@,``````I\M@$```(C +XM$`P`````"GUF`````B,8#``````*@4P%```"(R`,``````J":`4```(C*`P` +XM````"H-^!0```B,P#``````*A)\%```"(S@,``````J(GP4```(C0``'"$T! +XM```1`4P%```2R@`````'"$`%```3`6(%``!B!0``$LH`````!PBC`P``!PA2 +XM!0``$P'*````?@4``!)3`0````<(;@4``!,!9@```)D%```24P$``!*9!0`` +XM``<(`0(```<(A`4```,`````"HJS!```%`$``````98$`68````!\@4``!4` +XM`````90$4P$``!4``````94$9@```!9P``&7!%,!```7``````&8!&8````` +XM&+`%`````````````````````````G<(,08``!G#!0```````!K/!0```50; +XMVP4````````;Y04`````````'`$``````2L$`0%9!@``%0`````!*@19!@`` +XM'19I``$N!+8!``````<(I04``!XQ!@````````````````````````````"5 +XM!@``&4`&````````'P`````;308``````````"```````5,$`68````````` +XM`````````````````````"T'```A``````%0!%,!````````(0`````!400Z +XM!0```````")N``%2!+8!````````(VD``50$M@$````````D``````%5!+8! +XM````````'P`````D``````%R!+8!````````(VYE=P`!$$M@$``"0``````>($M@$````````D +XM``````'C!$T!`````````"\`````1@D``"-L96X``5`%M@$`````````,0`` +XM``````````````````"^"0``)``````!%P5F`````````#(````````````` +XM````````)``````!(@53`0```````"-L96X``2,%M@$````````C9``!)`5B +XM!0```````!\`````%FYE=P`!.`4/"@``````+)@'`````````6$%W0D``!FQ +XM!P```````"VH!P```!\`````)``````!@P5F````````````$P%F````"0H` +XM`!)3`0``$F8`````!PCT"0``!PA`"```,P`````!/0$!4P$```-+"@``%0`` +XM```!/`%3`0``%P`````!/@%X````%F-P``$_`5,!````-`$``````6\!`68` +XM`````````````````````````````*D1```A``````%K`5,!````````(0`` +XM```!;`%F`````````"$``````6T!"0H````````A``````%N`5D&```````` +XM)``````!<`%3`0```````"0``````7$!4P$````````D``````%R`;8!```` +XM````)``````!@\``!FQ!P`` +XM`````"VH!P```#8Q!@````````````````````````&L`RU\!@``,@`````` +XM```````````````;308````````````V,08````````````````````````! +XMY0,M?`8``#(`````````````````````&TT&````````````+P`````($``` +XM)``````!&01F```````````O`````#P0```P0"N!$`````````,0````````````````````"S$```)``````!U@)- +XM`0`````````R`````````````````````"0``````0<#30$````````D```` +XM``$(`[8!````````)``````!"0.V`0``````````+P````"4$0``)``````! +XM;0)3`0```````#$`````````````````````11$``"0``````;X"30$````` +XM```D``````&_`K8!`````````#(`````````````````````%P`````!?@)F +XM````)``````!?P)-`0```````#(`````````````````````(W```8\"N!$` +XM```````````Y`````,X1```!"0,````````````..@$``+@1```ZQP`````' +XM"/P"```..@$``,X1```/QP````0`";X1````704```(`[P````$!^PX*``$! +XM`0$````!+W5S7,`+W5S$#&RL#4JD# +XM8`BW.CMS=BB=`_T`[P,1""L#;U5Q`U<(.0@Z`Q`(?P-O1P,]<0,<[P.7`7$# +XM1*D(<[E)0SN.-`Q/3`^EV`CH!CP.5"7&A +XM`WHY36:``B00"(Q(."Y6J#JH6<.!/%9^+"WP"!-7?2T#$E4#BG[A`^X`FP/, +XM``A_`RX('7*>N%0A_ +XM")0#>3G,"%<#K`7]`]AZ"!WQG#@Z`PO%`P\Y`W$Y`P^-`W%C`P]'`W$Y`P^W +XM.D9;4'8#I'\(50,,?TE(G$,#T0#A`Q0Y`VPY`PLKJP.6?XT##'])2#I#`]\` +XMX5L#P@`")0&T=#98"%L#"<4#=SD#"7$#&6,#"L4#''$#9#D#&#E+-?,\-E98 +XM@0,)"(T(G*H#3@BW`S@(X8]R@CPH=`.]`<4#^0+3`[I]50/&`HW^`Q`(50-O +XM1P//?G$(U*R2"((#-PC]R(".BY`#F'P(*P/1!/T#$.\#L7VW`B(3KP,3")L( +XM<#J1-2\OAP-=`B8!`RW%H?(#@@'%`Z=ZJ0C7`](&MP/N>IL(2@/)``A5`]$! +XM"$?+`YY[`B,!CP/G!'$#>3E.9H#P[D@X60,*"#D#=D<#"CG82#BJ`UOA`[$! +XM`D(!XIX#[WF;CP.2!G%6`\T`1Y".CHN>`TU_R@(J$`(S#OX#X7P(X0/H``CA +XMR35U,#YL=C3T@&4#'G&Y`Q>-`Y8""$?(N(Z+G@-D""OT;V5DG0,.`B@!=`@> +XMCHN>`WI_\JJ.BY`#>N]T_HZ+G@-Z?\BXCHN0`Y-Z?P(B$P/!!;<#P'D(.0/` +XM!CD#P'G%90/`!L62U`.,?\6\;*X#IWH(FX\#W@5Q`WDY3FE6"#KN2#@N"/4# +XM>@(E`=6`@F`\"(4(JT4[`PWOJO`")A(#F7V-`P^;`W$Y`P]Q`P]Q5P,<58%6 +XMK-4#"0B;"&BJ6E[T/#96`^8`"'$#>@AQ`_T`"*D#^P"-`ZUYJ0/D!@(P`0/1 +XM?8U,-'9F@'XZ".)VE@AV@`@@-E8#GG^;`YQ\"$<#Y`:WF`@2\(Z+T'3^CHN> +XM`WJWD+B.BP.*>],(S0@3\#7'$#_7[3")$#HP&-`\8$`C(!"%(#ZP";5@BH\`,0 +XM[P-WX0(2``$!;F5X="`A/2!.54Q,`"\`+@!(3TU%`'X`+W5S-!8X$38,'C`8````4``````````%Z4@`!>!`!`PP'")`!```4```` +XM'`````````"C```````````````<````-`````````!1`````$$.$(8"1`X8 +XM1`X@@P,``#0```!4`````````/,`````0@X0CP)%#AA"#B"-!(X#10XH00XP +XM00XX1`Y`@P>&!HP%````````%````(P`````````)0``````````````)``` +XM`*0`````````]P4```!!#A"&`D,-!D2.!(\#1XP&C05$@P<``"0```#,```` +XM`````)<0````00X0A@)##09"CP-'C06.!$V#!XP&`````````````&H````` +XM`````0!5X@$```````#P`0````````$`7@````````````````````!9`0`` +XM`````%X!`````````0!5`````````````````````!`"````````$P(````` +XM```!`%4`````````````````````$`(````````6`@````````$`5``````` +XM```````````````3`@```````#4"`````````0!5```````````````````` +XM`!8"````````-0(````````!`%0`````````````````````0`(```````!! +XM`@````````(`=PA!`@```````$0"`````````@!W$$0"````````-P@````` +XM```"`'80`````````````````````$`"````````AP(````````!`%6'`@`` +XM`````+L"`````````0!1NP(```````!(`P````````,`=K!^2`,```````!X +XM`P````````$`47@#````````$P8````````#`':P?A,&````````*@8````` +XM```!`%$J!@```````#H'`````````P!VL'XZ!P```````$8'`````````0!1 +XM1@<```````#;!P````````,`=K!^VP<```````#D!P````````$`5>0'```` +XM````-P@````````!`%$`````````````````````0`(```````!Z`@`````` +XM``$`5'H"````````KP,````````!`%[3!`````````\&`````````0!>$P8` +XM``````"7!@````````$`7IL&````````-P@````````!`%X````````````` +XM````````0`(```````!Z`@````````$`47H"````````Y0(````````#`':L +XM?D@#````````-@8````````#`':L?D@&````````-P@````````#`':L?@`` +XM``````````````````!``@```````'H"`````````0!2>@(````````$!``` +XM``````$`7*H$````````"P8````````!`%P3!@```````),&`````````0!< +XMFP8```````!,!P````````$`7-L'````````-P@````````!`%P````````` +XM````````````0`(```````!Z`@````````$`6'H"````````-P@````````# +XM`':@?@````````````````````#"`@```````$@#`````````P!VN'Y_`P`` +XM`````!,&`````````P!VN'XQ!@```````#H'`````````P!VN'X````````` +XM````````````S0(```````!(`P````````$`7[P#````````$08````````! +XM`%\V!@```````)D&`````````0!?FP8```````#_!@````````$`7P`````` +XM``````````````#-`@```````$@#`````````P!VP'Z?`P```````!,&```` +XM`````P!VP'XV!@```````/\&`````````P!VP'X````````````````````` +XMS04````````)!@````````$`4YL&````````K`8````````!`%,````````` +XM````````````AP(```````#Q`@````````$`4D@#````````>`,````````! +XM`%*^!0```````,,%`````````0!2$P8````````8!@````````$`4A@&```` +XM````)`8````````!`%(Z!P```````$8'`````````0!2Y`<````````/"``` +XM``````$`4@\(````````-P@````````!`%(`````````````````````7P<` +XM``````!W!P````````$`40````````````````````!R!P```````'<'```` +XM`````0!5L`<```````"S!P````````$`5<\'````````U`<````````!`%4` +XM````````````````````^0(```````#\`@````````$`4/P"````````2`,` +XM```````!`%/3!````````-H$`````````0!3-@8```````!/!@````````$` +XM4P````````````````````#-`@```````$@#`````````0!>KP,````````/ +XM!@````````$`7C8&````````EP8````````!`%Z;!@```````/\&```````` +XM`0!>`````````````````````,T"````````2`,````````!`%S8`P`````` +XM``L&`````````0!<-@8```````"3!@````````$`7)L&````````_P8````` +XM```!`%P`````````````````````S0(```````#\`@````````$`4]@#```` +XM````V@0````````!`%.^!0```````,T%`````````0!32`8```````!/!@`` +XM``````$`4P````````````````````#-`@```````/$"`````````0!0^@,` +XM```````6!`````````$`4+\$````````W00````````!`%"^!0```````,,% +XM`````````0!0``````````````````````T%````````&`4````````!`%`8 +XM!0```````!T%`````````0!4W`8```````#>!@````````$`4-X&```````` +XMXP8````````!`%4`````````````````````3P8```````"1!@````````$` +XM4[L&````````S@8````````!`%,`````````````````````0`@```````!! +XM"`````````(`=PA!"````````$0(`````````@!W$$0(````````UQ@````` +XM```"`'80`````````````````````$`(````````A0@````````!`%6%"``` +XM`````)T(`````````0!=HP@```````"]"`````````$`5;T(````````1`H` +XM```````!`%U$"@```````$D*`````````0!4LPH```````#'"@````````$` +XM7=,*`````````PP````````!`%T4#````````),,`````````0!=W@P````` +XM``"`#0````````$`784-````````D@X````````!`%W.#@```````#L0```` +XM`````0!=W@P````````0#0````````$`7CL-```````` +XM10T````````!`%YE#0```````&H-`````````0!>>@T````````H#P`````` +XM``$`7I\/````````V!`````````!`%Y<$@````````43`````````0!>.!,` +XM``````!1$P````````$`7N<3````````!14````````!`%X5%0```````"45 +XM`````````0!>+A4```````#K%0````````$`7G48````````UQ@````````! +XM`%X`````````````````````D0@```````"8"`````````$`4)@(```````` +XMF0@````````!`%-V"P````````,,`````````0!05PP```````"A#``````` +XM``$`4*$,````````JPP````````!`%.K#````````+(,`````````0!0L@P` +XM``````#5#`````````$`4]X,````````$`T````````!`%"2#@```````)\/ +XM`````````0!0.Q````````#N$`````````$`4.X0````````H4````````]10````````!`%$/%0```````!45`````````0!1]14` +XM```````4%@````````$`46(8````````9A@````````!`%$````````````` +XM````````D0@```````"9"`````````$`4_`+`````````PP````````!`%,6 +XM%@```````#86`````````0!3`````````````````````"42````````+1(` +XM```````!`%`M$@```````#42`````````0!4!14````````'%0````````$` +XM4`<5````````#!4````````!`%4`````````````````````D0@```````"= +XM"`````````$`7?`+`````````PP````````!`%UP#````````.L,```````` +XM`0!1`````````!`%R#$``` +XM`````-@0`````````0!=V!````````#Q$`````````$`7`T1````````'!$` +XM```````!`%Q;$0```````-,1`````````0!<`1(````````)$@````````$` +XM7?@2````````YQ,````````!`%WJ%````````/`4`````````0!<\!0````` +XM``#U%`````````$`7245````````+A4````````!`%S?%0```````.L5```` +XM`````0!=ZQ4```````#U%0````````$`7#86````````JQ8````````!`%UK +XM&````````'48`````````0!=`````````````````````/$0````````'!$` +XM```````!`%P`````````````````````+A$```````!1$0````````$`7``` +XM``````````````````"1"````````)D(`````````0!3A(```````#G$P`` +XM``````,`=LA]X10```````#U%`````````,`=LA]!14````````E%0`````` +XM``,`=LA]WQ4```````#K%0````````,`=LA]]14```````"K%@````````,` +XM=LA]8A@```````!U&`````````,`=LA]`````````````````````/`+```` +XM````^0L````````!`%R2#@```````"X/`````````0!<@Q````````"&$``` +XM``````$`7`43````````YQ,````````!`%SJ%````````/`4`````````0!< +XMWQ4```````#K%0````````$`7#86````````JQ8````````!`%QK&``````` +XM`'48`````````0!<`````````````````````)$(````````GP@````````! +XM`%[P"P````````,,`````````0!>D@X````````H#P````````$`7H,0```` +XM````V!`````````!`%X%$P```````.<3`````````0!>ZA0```````#U%``` +XM``````$`7M\5````````ZQ4````````!`%XV%@```````*L6`````````0!> +XM:Q@```````!U&`````````$`7@````````````````````"1"````````)D( +XM`````````0!3\`L````````##`````````$`4XL6````````JQ8````````! +XM`%,`````````````````````D0@```````"9"`````````$`4_`+```````` +XM`PP````````!`%/J%````````/44`````````0!33A8```````"+%@`````` +XM``$`4P````````````````````"5$@```````*`2`````````0!0H!(````` +XM``"E$@````````$`5!45````````%Q4````````!`%`7%0```````!P5```` +XM`````0!5`````````````````````+4.````````P`X````````!`%#`#@`` +XM`````,4.`````````0!4WQ4```````#A%0````````$`4.$5````````YA4` +XM```````!`%4`````````````````````D0@```````"9"`````````$`4U00 +XM````````@Q`````````!`%,`````````````````````D0@```````"9"``` +XM``````$`4^`.````````*P\````````!`%.#$````````-@0`````````0!3 +XM`````````````````````*`0````````P!`````````!`%$````````````` +XM````````M0T```````#`#0````````$`4,`-````````Q0T````````!`%3U +XM%````````/<4`````````0!0]Q0```````#\%`````````$`50`````````` +XM``````````"1"````````*,(`````````P!VJ'T$"P````````,,```````` +XM`P!VJ'T4#````````!`-`````````P!VJ'T[#0```````$4-`````````P!V +XMJ'V%#0```````)\/`````````P!VJ'W6#P```````-,1`````````P!VJ'T! +XM$@```````.<3`````````P!VJ'VM%````````,H5`````````P!VJ'W?%0`` +XM`````*L6`````````P!VJ'UB&````````-<8`````````P!VJ'T````````` +XM````````````D0@```````"C"`````````,`=K!]!`L````````##``````` +XM``,`=K!]%`P````````0#0````````,`=K!].PT```````!%#0````````,` +XM=K!]A0T```````"?#P````````,`=K!]J@\```````#3$0````````,`=K!] +XM`1(```````"K%@````````,`=K!]8A@```````#7&`````````,`=K!]```` +XM`````````````````)$(````````HP@````````#`':X?00+`````````PP` +XM```````#`':X?10,````````$`T````````#`':X?3L-````````10T````` +XM```#`':X?84-````````GP\````````#`':X?280````````TQ$````````# +XM`':X?0$2````````YQ,````````#`':X?:T4````````+A4````````#`':X +XM?3P5````````114````````#`':X?445````````2A4````````!`%6#%0`` +XM`````,H5`````````P!VN'W?%0```````*L6`````````P!VN'UB&``````` +XM`-<8`````````P!VN'T`````````````````````D0@```````"8"``````` +XM``$`4`0+````````%PL````````!`%`%#0```````!`-`````````0!0A0T` +XM``````";#0````````$`4%`.````````;@X````````!`%`@$````````#L0 +XM`````````0!0Q10```````#4%`````````$`4"X5````````,A4````````! +XM`%``````````````````````_P\````````$$`````````$`50`````````` +XM``````````"A%0```````*85`````````0!5`````````````````````%45 +XM````````NQ4````````!`%T`````````````````````D0@```````"C"``` +XM``````,`=L!]!`L````````##`````````,`=L!]%`P````````0#0`````` +XM``,`=L!].PT```````!%#0````````,`=L!]A0T```````"?#P````````,` +XM=L!].Q````````#3$0````````,`=L!]`1(```````#G$P````````,`=L!] +XMK10````````N%0````````,`=L!]8!4```````#*%0````````,`=L!]WQ4` +XM``````"K%@````````,`=L!]8A@```````#7&`````````,`=L!]```````` +XM`````````````)$(````````HP@````````#`':@?00+`````````PP````` +XM```#`':@?10,````````$`T````````#`':@?3L-````````10T````````# +XM`':@?84-````````GP\````````#`':@?3L0````````TQ$````````#`':@ +XM?0$2````````YQ,````````#`':@??L3````````9Q0````````#`':@?6<4 +XM````````;!0````````!`%5W%````````)44`````````0!4K10````````N +XM%0````````,`=J!]RA4```````"K%@````````,`=J!]8A@```````#7&``` +XM``````,`=J!]`````````````````````(T4````````E10````````!`%4` +XM````````````````````>A0```````"5%`````````$`40`````````````` +XM``````"1"````````)@(`````````0!0!0T````````0#0````````$`4`H4 +XM````````%!0````````!`%`D%````````%04`````````0!0RA4```````#1 +XM%0````````$`4`````````````````````"1"````````)@(`````````0!0 +XM!0T````````0#0````````$`4!<4````````'10````````!`%`D%``````` +XM`%04`````````0!0RA4```````#1%0````````$`4``````````````````` +XM```Y`````@``````U!$``/(%``!?7V=L;V)?<&%T=&5R;E]P`%\&``!G;&]B +XM9G)E90!+"@``9VQO8@``````+`````(```````@`````````````````UQ@` +XM````````````````````````````P@````````#L`````````/4````````` +XM^@````````#P`````````/,``````````````````````````````%`!```` +XM````A`$```````".`0```````,X!`````````````````````````````'," +XM````````JP(```````#;!P```````#<(````````$P8````````=!@`````` +XM`$@#````````8`,`````````````````````````````F4``!P=U]S:&5L;`!?7VEN +XM;U]T`'!W7W!AF5?=`!?7V)L:W-I>F5?=`!M>5]R +XM96%L;&]C`&9IF5?=`!?7W1I;65?=`!S=%]S:7IE`'-T7W5I9`!?7V]F9E]T +XM`'-T7V1E=@!S:6=N960@8VAA<@!M;V1E7W0`;V9F7W0`'0` +XM+F1A=&$`+F)S`````0````(```````````````````"@-````````/`````` +XM```````````````(````````````````````F0````0````````````````` +XM````````$+(```````"0`````````!H````/````"``````````8```````` +XM`*@````!`````````````````````````)`U````````'2X````````````` +XM``````$```````````````````"X`````0````````````````````````"M +XM8P```````#T````````````````````!````````````````````LP````0` +XM````````````````````````H+(````````8`````````!H````2````"``` +XM```````8`````````,T````!`````````````````````````.IC```````` +XM,`````````````````````$```````````````````#(````!``````````` +XM``````````````"XL@```````#``````````&@```!0````(`````````!@` +XM````````W`````$`````````````````````````&F0```````"0"P`````` +XM`````````````0```````````````````.H````!````,``````````````` +XM`````*IO````````T`4```````````````````$``````````0````````#U +XM`````0````````````````````````!Z=0```````"8````````````````` +XM```!````````````````````$0````,`````````````````````````H'4` +XM``````#^`````````````````````0````````````````````$````"```` +XM`````````````````````*!]````````4`0````````;````%P````@````` +XM````&``````````)`````P````````````````````````#P@0```````/4` +XM```````````````````!```````````````````````````````````````` +XM`````````````0````0`\?\```````````````````````````,``0`````` +XM``````````````````````,``P````````````````````````````,`!``` +XM``````````````````````````,`!0````````````````````````````,` +XM!@````````````````````````````,`"```````````````````````"``` +XM``(``0`0`0```````/,`````````%0````(``0`0`@```````"4````````` +XM)@````(``0!``@```````/<%``````````````,`"@`````````````````` +XM``````````,`"P``````````````````````,@````$`#`````````````4` +XM``````````````,`#`````````````````````````````,`#0`````````` +XM``````````````````,`#P````````````````````````````,`$0`````` +XM``````````````````````,`$@````````````````````````````,`%``` +XM``````````````````````````,`%@````````````````````````````,` +XM%P````````````````````````````,`&```````````````````````0``` +XM`!(``0```````````*,`````````40```!(``0"P`````````%$````````` +XM6@```!``````````````````````````7P```!`````````````````````` +XM````9@```!``````````````````````````;0```!`````````````````` +XM````````=````!``````````````````````````?````!`````````````` +XM````````````A````!``````````````````````````C````!`````````` +XM````````````````E````!``````````````````````````G````!`````` +XM````````````````````I````!``````````````````````````K0```!`` +XM````````````````````````L@```!(``0!`"````````)<0````````MP`` +XM`!``````````````````````````O@```!`````````````````````````` +XMQ@```!``````````````````````````S0```!`````````````````````` +XM````U@```!``````````````````````````W````!`````````````````` +XM````````XP```!``````````````````````````[````!`````````````` +XM`````````````&=L;V(N8P!P````_/__ +XM______\2!`````````(````?````_/________]F!`````````(````<```` +XM_/________^!!`````````(````;````_/________^X!`````````(````@ +XM````_/________\9!0````````(````A````_/________^_!0````````(` +XM```B````_/_________Q!0````````(````B````_/________])!@`````` +XM``(````B````_/________]A!@````````(````C````_/________]F!@`` +XM``````(````B````_/________][!@````````(````9````_/________^C +XM!@````````(````C````_/_________?!@````````(````<````_/______ +XM__\`!P````````(````B````_/________\3!P````````(````B````_/__ +XM______]"!P````````(````:````_/________]-!P````````(````:```` +XM_/________]S!P````````(````;````_/________^/!P````````(````; +XM````_/_________0!P````````(````D````_/________^!"`````````(` +XM```B````_/________^Y"`````````(````F````_/_________7"``````` +XM``(````:````_/________\`"0````````(````;````_/________^X"0`` +XM``````(````E````_/_________Y"0````````(````G````_/________]% +XM"@````````(````;````_/________^'"@````````(````E````_/______ +XM___#"@````````H````+````#0````````#?"P````````(````9````_/__ +XM_______Z"P````````(````9````_/________].#`````````(````E```` +XM_/________]>#0````````(````:````_/________]\#0````````H````+ +XM````#P````````#!#0````````(````A````_/________\6#@````````(` +XM```H````_/_________!#@````````(````A````_/_________J#@`````` +XM``(````9````_/________\`#P````````(````9````_/________^4#P`` +XM``````(````D````_/_________(#P````````(````F````_/________\` +XM$`````````(````;````_/________\9$`````````(````I````_/______ +XM__]>$`````````(````9````_/________]Z$`````````(````9````_/__ +XM______^W$`````````H````"````$`(```````#/$`````````(````J```` +XM_/_________[$`````````(````9````_/________\1$0````````(````9 +XM````_/________\Z$0````````(````9````_/________]2$0````````(` +XM```9````_/________]]$0````````(````9````_/________^3$0`````` +XM``(````9````_/________^Z$0````````(````9````_/________\-$@`` +XM``````(````:````_/________\Q$@````````(````A````_/________]D +XM$@````````(````:````_/________^A$@````````(````A````_/______ +XM__]$$P````````(````:````_/________]@$P````````(````D````_/__ +XM______^"$P````````(````<````_/________^D$P````````(````;```` +XM_/_________:$P````````(````;````_/_________H$P````````H````+ +XM````$0````````#M$P````````(````K````_/________\#%`````````(` +XM```L````_/________\0%`````````(````I````_/________])%``````` +XM``L````+````%@````````!H%`````````(````:````_/________^1%``` +XM``````(````;````_/________^D%`````````(````;````_/_________0 +XM%`````````(````D````_/_________X%`````````(````<````_/______ +XM__\(%0````````(````<````_/________\8%0````````(````<````_/__ +XM______]&%0````````(````:````_/________]J%0````````(````:```` +XM_/________^B%0````````(````;````_/________^\%0````````(````; +XM````_/_________B%0````````(````<````_/________\@%@````````(` +XM```9````_/________]8%@````````(````9````_/________]N%@`````` +XM``(````9````_/________^5%@````````(````9````_/________^Z%@`` +XM``````(````:````_/________\B%P````````(````;````_/________]` +XM%P````````(````;````_/________]8%P````````(````E````_/______ +XM__^;%P````````(````9````_/________\F&`````````H````+```````` +XM```````P&`````````H````,```````````````U&`````````H````.```` +XM``````````!!&`````````(````M````_/________]9&`````````(````9 +XM````_/_________V``````````(````9````_/________\Q`@````````(` +XM```=````_/________\&``````````H````%```````````````,```````` +XM``H````5````6@4````````1``````````H````5````P`$````````5```` +XM``````$````"```````````````=``````````$````"````UQ@````````E +XM``````````H````'```````````````L``````````H````5````%@4````` +XM```Q``````````H````5````(@0````````^``````````H````5````O00` +XM``````!%``````````H````5````G`,```````!*``````````H````5```` +XM60$```````!7``````````H````5````+P4```````!<``````````H````5 +XM````=P````````!N``````````H````5````RP0```````![``````````H` +XM```5````/P````````"```````````H````5````00,```````"-```````` +XM``H````5````QP,```````"2``````````H````5````(@(```````"?```` +XM``````H````5````;@0```````"F``````````H````5````>@4```````"M +XM``````````H````5````!0$```````"R``````````H````5````YP,````` +XM``"]``````````H````5````[P0```````#-``````````H````5````\`,` +XM``````#8``````````H````5````@04```````#C``````````H````5```` +XMJP4```````#N``````````H````5````2P,```````#Y``````````H````5 +XM````T@`````````$`0````````H````5````L`$````````/`0````````H` +XM```5````BP`````````:`0````````H````5````!P4````````E`0`````` +XM``H````5````&@0````````P`0````````H````5````X`(````````]`0`` +XM``````H````5````3P(```````!(`0````````H````5````NP````````!? +XM`0````````H````5````Y00```````!J`0````````H````5````5`(````` +XM``!U`0````````H````5````F@$```````"``0````````H````5````;`,` +XM``````"+`0````````H````5````Y`````````"6`0````````H````5```` +XM(@4```````"A`0````````H````5````M00```````"L`0````````H````5 +XM````*04```````"W`0````````H````5````DP$```````#"`0````````H` +XM```5````B@(```````#-`0````````H````5````A`,```````#9`0`````` +XM``H````5````1@(```````#E`0````````H````5````9P0```````#S`0`` +XM``````H````5````BP$````````"`@````````H````5````?P$````````. +XM`@````````H````5````#P4````````<`@````````H````5````H`(````` +XM```J`@````````H````5````%`(````````X`@````````H````5````+0(` +XM``````!&`@````````H````5``````4```````!4`@````````H````5```` +XM#0(```````!B`@````````H````5````HP4```````!P`@````````H````5 +XM````+`0```````!^`@````````H````5````Z@````````",`@````````H` +XM```5````HP$```````":`@````````H````5````^`0```````"H`@`````` +XM``H````5````,@$```````"V`@````````H````5````60````````#$`@`` +XM``````H````5````]@(```````#2`@````````H````5````9`````````#@ +XM`@````````H````5````@0````````#N`@````````H````5````@`0````` +XM``#]`@````````H````5````-@(````````)`P````````H````5````40`` +XM```````7`P````````H````5````V@`````````E`P````````H````5```` +XM)P`````````S`P````````H````5````L`(```````!!`P````````H````5 +XM````;P(```````!/`P````````H````5````404```````!=`P````````H` +XM```5````'@````````!K`P````````H````5````A`$```````!Y`P`````` +XM``H````5````R0````````"'`P````````H````5````_P(```````"5`P`` +XM``````H````5````*`$```````"D`P````````H````5````90,```````"Q +XM`P````````H````5````4P,```````"_`P````````H````5````2@$````` +XM``#-`P````````H````5````N0$```````#;`P````````H````5````M@4` +XM``````#I`P````````H````5````IP`````````(!`````````H````5```` +XMC`4````````4!`````````H````5````4P$````````B!`````````H````5 +XM````/`$````````P!`````````H````5````U@,````````^!`````````H` +XM```5````I@,```````!,!`````````H````5````-`,```````!:!``````` +XM``H````5````5@0```````!H!`````````H````5````@`(```````!V!``` +XM``````H````5````]P````````"$!`````````H````5````(@,```````"2 +XM!`````````H````5````Q0(```````"A!`````````H````5````>P,````` +XM``"O!`````````H````5````MP(```````"\!`````````H````5````IP(` +XM``````#*!`````````H````5````UP(```````#8!`````````H````5```` +XM[@(```````#F!`````````H````5````W@,```````#T!`````````H````5 +XM````:P`````````"!0````````H````5````$P`````````0!0````````H` +XM```5````1@0````````>!0````````H````5````K`0````````L!0`````` +XM``H````5````+@````````"F!0````````H````5````RP(```````"R!0`` +XM``````H````5````FP0```````#$!0````````H````5````U@0```````#0 +XM!0````````H````5````T`,```````#F!0````````H````5````400````` +XM``#W!0````````$````"``````````````#_!0````````$````"````HP`` +XM```````3!@````````H````1```````````````C!@````````H````1```` +XM20`````````L!@````````H````1````D@`````````S!@````````H````5 +XM````E04```````!!!@````````H````5````#P,```````!D!@````````$` +XM```"````L`````````!L!@````````$````"`````0$```````!T!@`````` +XM``H````1````.@$```````"!!@````````H````1````F@$```````"&!@`` +XM``````H````4``````````````"/!@````````H````1````XP$```````"6 +XM!@````````H````5````F@````````"B!@````````$````"````$`$````` +XM``"J!@````````$````"`````P(```````"R!@````````H````1````!@(` +XM``````"[!@````````H````5````;@$```````#&!@````````H````1```` +XMMP(```````#+!@````````H````5````.P,```````#6!@````````H````1 +XM````$P,```````#D!@````````H````1````;P,```````#R!@````````H` +XM```1````I@,```````#W!@````````H````5````#``````````"!P`````` +XM``H````1````W`,````````'!P````````H````4````0``````````,!P`` +XM``````H````5````D0(````````7!P````````H````1````.`0````````G +XM!P````````H````1````;@0````````N!P````````H````5````M@,````` +XM```Z!P````````$````"````$`(```````!"!P````````$````"````-0(` +XM``````!;!P````````H````1````D00```````!I!P````````H````1```` +XMM`0```````!X!P````````H````1````UP0```````"'!P````````H````1 +XM````^@0```````"9!P````````H````5````_`,```````"\!P````````H` +XM```5````#@0```````#(!P````````$````"````0`(```````#0!P`````` +XM``$````"````-P@```````#8!P````````H````1````'04```````#A!P`` +XM``````H````5````U@0```````#L!P````````H````1````:04```````#Q +XM!P````````H````5````*@,```````#\!P````````H````1````4@8````` +XM```!"`````````H````5````'`(````````,"`````````H````1````P08` +XM```````1"`````````H````5````B@,````````<"`````````H````1```` +XM(P<````````A"`````````H````5````#P,````````L"`````````H````1 +XM````I0<````````Q"`````````H````5````R04````````\"`````````H` +XM```1````W0<```````!!"`````````H````5````9@(```````!."``````` +XM``H````5````3`````````!="`````````H````5````.00```````!M"``` +XM``````H````5````"0,```````!X"`````````H````1````+`@```````!] +XM"`````````H````5````0P$```````"("`````````H````1````B`@````` +XM``"-"`````````H````5````"P$```````"9"`````````H````5````E0`` +XM``````"D"`````````H````1````UP@```````"I"`````````H````5```` +XMK@````````"P"`````````$````"````2`8```````"]"`````````H````4 +XM````<`````````#3"`````````H````4````P`````````#A"`````````H` +XM```1````#0D```````#H"`````````H````4````$`$`````````"0`````` +XM``H````5```````````````,"0````````H````5````#``````````7"0`` +XM``````H````1````M0D````````<"0````````H````5````<@,````````G +XM"0````````H````1````V`D````````M"0````````H````4````0`$````` +XM``!!"0````````H````1````(0H```````!'"0````````$````"````C0,` +XM``````!/"0````````$````"````Q00```````!<"0````````H````5```` +XMD@,```````!G"0````````H````1````?0H```````!L"0````````$````" +XM````V`,```````!T"0````````$````"````Q00```````!]"0````````H` +XM```5````.00```````"("0````````H````1````V0H```````"8"0`````` +XM``H````1````-0L```````"F"0````````H````1````D0L```````"K"0`` +XM``````H````4````<`$```````##"0````````H````4````H`$```````#3 +XM"0````````H````1````[0L```````#>"0````````H````4````T`$````` +XM``#C"0````````H````5````E0````````#N"0````````H````1````20P` +XM```````6"@````````H````5````_@$````````H"@````````H````5```` +XM0@4````````T"@````````H````5````Z`(```````!-"@````````H````5 +XM``````$```````!9"@````````$````"````0`@```````!A"@````````$` +XM```"````UQ@```````!I"@````````H````1````?PP```````!R"@`````` +XM``H````5````U@0```````!]"@````````H````1````RPP```````"""@`` +XM``````H````5````'`(```````"-"@````````H````1````:@X```````"2 +XM"@````````H````5````B@,```````"="@````````H````1````B0\````` +XM``"B"@````````H````5````#P,```````"M"@````````H````1````P0\` +XM``````"R"@````````H````5````70(```````"]"@````````H````1```` +XM0Q````````#""@````````H````5````;@$```````#-"@````````H````1 +XM````O!````````#2"@````````H````5````#`````````#="@````````H` +XM```1````6Q(```````#B"@````````H````5````>0(```````#M"@`````` +XM``H````1````=1,```````#R"@````````H````5````7@0```````#]"@`` +XM``````H````1````%!4````````""P````````H````4````$`(````````+ +XM"P````````H````5````0@4````````7"P````````H````4````8`(````` +XM```<"P````````H````5````!P0````````H"P````````H````5````%P$` +XM```````S"P````````H````1````S!4```````!!"P````````H````1```` +XM!A8```````!&"P````````H````5````3`````````!1"P````````H````1 +XM````8A8```````!6"P````````H````5````G@4```````!A"P````````H` +XM```1````M!<```````!F"P````````H````5````K0,```````!Q"P`````` +XM``H````1````CA@```````!V"P````````H````5````W@0```````"&"P`` +XM``````H````4````L`(```````"7"P````````H````4````X`(```````"@ +XM"P````````H````1````!QD```````"P"P````````H````4````$`,````` +XM``#!"P````````H````4````0`,```````#*"P````````H````1````8QD` +XM``````#6"P````````H````4````<`,```````#;"P````````H````5```` +XM(0$```````#F"P````````H````1````OQD```````#O"P````````H````4 +XM````H`,`````````#`````````H````4````T`,````````)#`````````H` +XM```1````O1L````````9#`````````H````4``````0````````F#``````` +XM``H````4````,`0````````O#`````````H````1````!AP````````Y#``` +XM``````H````4````8`0```````!"#`````````H````5````!P````````!- +XM#`````````H````1````8AP```````!2#`````````H````4````H`0````` +XM``!B#`````````H````1````A1P```````!M#`````````H````4````T`0` +XM``````"##`````````H````4````,`4```````"1#`````````H````1```` +XMNQP```````"8#`````````$````"````A0L```````"@#`````````$````" +XM````\`L```````"M#`````````H````5````$`$```````"X#`````````H` +XM```1````/1T```````#!#`````````$````"````P`L```````#)#``````` +XM``$````"````\`L```````#:#`````````$````"````S0L```````#B#``` +XM``````$````"````\`L```````#O#`````````H````1````8!T```````#W +XM#`````````H````4````D`4````````)#0````````H````1````EAT````` +XM```=#0````````H````4````\`4````````M#0````````H````1````/AX` +XM```````]#0````````H````1````HAX```````!�````````H````4```` +XM0`8```````!7#0````````H````4````<`8```````!@#0````````H````1 +XM````71\```````!K#0````````H````4````H`8```````!W#0````````H` +XM```1````IA\```````"$#0````````H````4````X`8```````"-#0`````` +XM``H````5````T@(```````"F#0````````H````1`````B````````"K#0`` +XM``````H````4````D`<```````"T#0````````H````5````9`$```````#$ +XM#0````````H````4````X`<```````#5#0````````H````4````$`@````` +XM``#>#0````````H````1````:"$```````#I#0````````$````"````%1$` +XM``````#Q#0````````$````"````6Q$````````&#@````````$````"```` +XM)1$````````.#@````````$````"````6Q$````````;#@````````H````1 +XM````BR$````````F#@````````H````4````0`@````````W#@````````H` +XM```4````<`@```````!`#@````````H````1````KB$```````!+#@`````` +XM``$````"````EQ$```````!3#@````````$````"````TQ$```````!D#@`` +XM``````$````"````I!$```````!L#@````````$````"````TQ$```````!Y +XM#@````````H````1````'2(```````"!#@````````H````4````H`@````` +XM``"*#@````````H````5````%0,```````"5#@````````H````1````9B(` +XM``````":#@````````H````5````OP4```````"U#@````````H````4```` +XM,`D```````#)#@````````H````1````72,```````#.#@````````H````5 +XM````F`(```````#9#@````````H````1````!20```````#B#@````````$` +XM```"````=A8```````#J#@````````$````"````JQ8```````#_#@`````` +XM``$````"````?Q8````````'#P````````$````"````JQ8````````4#P`` +XM``````H````1````P"0````````?#P````````H````4````@`D````````L +XM#P````````H````4````L`D````````U#P````````H````1````"24````` +XM``!!#P````````H````4````X`D```````!1#P````````H````1````924` +XM``````!@#P````````H````4````$`H```````!P#P````````H````1```` +XMP24```````!_#P````````$````"````.Q````````"'#P````````$````" +XM````@Q````````"8#P````````$````"````2!````````"@#P````````$` +XM```"````@Q````````"M#P````````H````1````'28```````"Y#P`````` +XM``$````"````S@X```````#!#P````````$````"````!`\```````#2#P`` +XM``````$````"````UPX```````#:#P````````$````"````!`\```````#G +XM#P````````H````1````4R8```````#O#P````````H````4````0`H````` +XM``#X#P````````H````5````7`,````````#$`````````H````1````G"8` +XM```````)$`````````H````4````@`H````````E$`````````H````4```` +XMP`H````````Q$`````````H````1````OR8````````]$`````````H````4 +XM````\`H```````!&$`````````H````5````-@````````!1$`````````H` +XM```1````&R<```````!6$`````````H````5````D00```````!A$``````` +XM``H````1````_2<```````!F$`````````H````5````/0(```````!Q$``` +XM``````H````1````M2@```````!V$`````````H````4````(`L```````"( +XM$`````````H````1````U"D```````".$`````````$````"````V`\````` +XM``"6$`````````$````"````$1````````"C$`````````H````5````!P`` +XM``````"N$`````````H````1````?"H```````"T$`````````$````"```` +XM0A4```````"\$`````````$````"````RA4```````#%$`````````H````5 +XM````!P````````#0$`````````H````1````GRH```````#5$`````````H` +XM```5````=@$```````#@$`````````H````1````PBH```````#E$``````` +XM``H````5````K0,```````#P$`````````H````1````Y2H```````#W$``` +XM``````H````4````8`L`````````$0````````H````5````/0(````````+ +XM$0````````H````1````W"L````````0$0````````$````"````9!0````` +XM```8$0````````$````"````K10````````E$0````````H````5````!P`` +XM```````P$0````````H````1````^2P````````U$0````````H````5```` +XM=@$```````!`$0````````H````1````'"T```````!&$0````````$````" +XM`````A0```````!.$0````````$````"````)!0```````!7$0````````H` +XM```5````/@0```````!C$0````````H````5````.00```````!N$0`````` +XM``H````1````/RT```````!S$0````````$````"````#!0```````![$0`` +XM``````$````"````)!0```````"-$0````````H````1````KBT```````"5 +XM$0````````H````5````2`4```````"@$0````````$````.```````````` +XM``#\``````````$````"```````````````<``````````H````/```````` +XM```````@``````````$````"```````````````T``````````H````/```` +XM```````````X``````````$````"````L`````````!<``````````H````/ +XM``````````````!@``````````$````"````$`$```````"<``````````H` +XM```/``````````````"@``````````$````"````$`(```````"T```````` +XM``H````/``````````````"X``````````$````"````0`(```````#D```` +XM``````H````/``````````````#H``````````$````"````0`@````````@ +XM``````````H````"```````````````X``````````H````"````L``````` +XM``!8``````````H````"````$`$```````"0``````````H````"````$`(` +XM``````"H``````````H````"````0`(```````#0``````````H````"```` +XM0`@````````&``````````H````&```````````````&``````````H````& +XC```````````````0``````````$````"```````````````` +X` +Xend +08f54ce57ae16ee49e80e07b25b53cad +echo x - ./glob/fnmatch.o.uu +sed 's/^X//' >./glob/fnmatch.o.uu << 'b483319a2b8624af2d41c47d4e321b7b' +Xbegin 644 ./fnmatch.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````(A2```` +XM`````````$```````$``&@`7`$%7059!54%455-(@^Q(2(ET)!B)5"04B4PD +XM$`^V!X3`#X3R!P``08G-08G.2(GS@^$"2(UO`4R-?"0P08/E$$&#Y@&)3"0D +XM2(/#`4F)]&:0187M=&L/MM`[%0````!]$DB+-0````!(8\IF@WS.0`!X0CP_ +XM=%$/AX0````\*F:0#X0#`@``187M9F9FD&9FD`^%5`,```^V0_\YT'1"9I"X +XM`0```$B#Q$A;74%<05U!7D%?PP^VA(Y`"```9F9FD#P_#[;0=:\/MD/_A,!T +XMT3PO#X31`P``/"X/A*8#``"0#[9%`$F#Q`%(@\,!A,`/A"<'``!(@\4!Z5/_ +XM__]F9I`\6W1L/%P/A7K___^+1"0DOEP```"%P'4Y#[9%`(3`#X1[____187M +XM="$/MM`[%0````!]%DB+#0````!(8])F@WS10``/B"8'``!(@\4!#[;P187M +XM#X7!`@``#[9#_SGP#X1Y____Z33___]F9F:01(L%`````$6%P`^$=@4``$0/ +XMMD/_183`#X02____08#X+@^$'@,``$&`^"\/A#L#```/MD4`/"$/A)\%``"+ +XM-0````"%]@^(B04``,=$)"P`````BTPD)$B#Q0%%#[;0B<)-8]J%R4$/E,%F +XM9I!FD$6%[42)QG0H1#L5`````'T?2(L%`````&9"@WS80`!Y#T(/MK280`@` +XM`&9FD&9FD(#Z7`^$W@(``(#Z6P^$/@,``(32#X1V_O__#[;"187M="*%P'@> +XM.P4`````?19(BST`````2&/(9H-\ST``#XA#!0``0`^V]CGP#X3J"0``#[9% +XM`$B#Q0$\+8A$)`\/A/P#``"`?"0/70^$9@0```^V5"0/Z5?___]!#[84)(#Z +XM+@^$?00```^V70!(@\4!@/L_#Y3`#X6C`0``187V#X3X"P``@/HO#X3C_?__ +XMA,"0=`R$T@^$UOW__TF#Q`$/MET`2(/%`8#[/P^4P`^$_@```(#[*@^$]0`` +XM`(3;#X1L`0``1(GV3(GG18GW]]Z#YB_H`````$B%P$F)Q@^$;@D``(#[6P^$ +XM8P4``(#[+V:0#X3:"```BT0D$$6$_XE$)"@/A&P$``"`^UP/A!4)``!%A>T/ +XMA?<$``!(@^T!33GF#X9*_?__187M#[;;#X2E"0``1(M<)!1%A=L/A"()``!% +XMA/]T&.F["@``9F:09F:028/$`4TY]`^$$_W__T$/M@0D.04`````?AE(BPT` +XM````2&/09H-\T4``>0>+A)%`"```.=AUR3'23#MD)!B+3"0H3(GF2(GO#Y3" +XMZ##\__^%P'6L,<#IROS__V9FD&:000^V%"3IRO[__P^V0_\[!0`````/C:#\ +XM__](BS4`````2&/(9H-\SD``#XF*_/__BX2.0`@``.E^_/__#[9#_SL%```` +XM``^-,_W__TB+#0````!(8]!F@WS10``/B1W]__^+A)%`"```Z1']__^`^RH/ +XMA%3^__^$VP^%E/[__S'`187V#X0[_/__OB\```!,B>?H`````$B%P`^5P`^V +XMP.D@_/__BT0D%(7`#X1/_/__3#MD)!@/A`3\__]!@'PD_R\/A3C\__]%A?8/ +XMA"_\___IZOO__XM\)!2%_V9F9I`/A-S\__],.V0D&`^$S_O__T&`?"3_+P^% +XMQ?S__T6%]@^%NOO__P^V10`\(0^%O/S__^E6`@``183)#X0J_?__#[9%`(3` +XM#X24^___187MB$0D#W0@#[;`.P4`````?15(BQ4`````2)AF@WS"0``/B"T" +XM``!(@\4!0#IT)`\/A3#]__^`?"0/70^$&P<``(!\)`\`#X5M`@``Z4'[__^0 +XM@'T`.@^%P/S__P^V30%(C7T!@/DZB$PD#P^$:@,```^V1"0/@^AA/!@/A]4` +XM```/MD0D#TB#QP&(1"0P#[8/@/DZB$PD#P^$W`4```^V1"0/@^AA/!@/AZ@` +XM```/MD0D#TB#QP&(1"0Q#[8/@/DZB$PD#P^$QP4```^V1"0/@^AA/!AW?P^V +XM1"0/2(/'`8A$)#(/M@^`^3J(3"0/#X2S!0``#[9$)`^#Z&$\&'=6#[9$)`]( +XM@\T/ML%T)`^VP3L%`````'T92(L-`````$ACT&:#?-%``'D'BX210`@``#GP +XM#XWY````#[95`$B#Q0&(5"0/@'PD#UT/A9K[__^+5"0LA=(/A>_Y___IJOG_ +XM_[\`````Z`````!(@_@!&<"#R`&)!0````#I;/K__XM$)!2%P`^$=_O__TP[ +XM9"08#X1U^?__08!\)/\O#X5@^___187V#X17^___Z5OY__\\7@^%;_K__TB# +XMQ0$/MD4`QT0D+`$```#I8OK__P^VA()`"```2(/%`8A$)`]`.G0D#P^%]_K_ +XM_^G"_?__/%P/A0'___\/MDT`2(/%`>GT_O__BX2/0`@``.FQ^O__BU0D$(/B +XM^XE4)"CIA/O__SQ;=#$\70^$JP0``(3`#X39^/__#[9%`$B#Q0%%A,ETWSQ< +XM==N`?0``#X2^^/__2(/%`>O7@'T`.F9F9I!US0^V10&$P`^$HOC__TB#Q0$\ +XM.G7L#[9%`3Q==.A(@\4"#[9%`.N?28GT00^V!"2$P`^$K/O___9$)!`(#X1M +XM^/__/"\/E<`/ML#I9?C__P^VPSL%``````^-^OK__TB+%0````!(F&:#?,)` +XM``^)Y?K__P^VG()`"```Z=CZ__\/MH210`@``.G-^/__BT0D$$2+;"002(U= +XM_X/@^T6$_T0/1.A-.>8/A@+X__^+1"04A<`/A%0&``!%A/]T%Y#IO`4``$F# +XMQ`%-.?1F9F:0#X3:]___,=),.V0D&$2)Z4R)YDB)WP^4PN@B]___AN_B%0D#V:0Z>_X__^+1"0DA<`/A=_V__\/MET`Z=;V +XM__^+1"0LA<`/A&KT___I)?3__V9FD&:0,?9,B>?H`````$F)QNF`]O__183_ +XM=3A!#[8$)#D%`````'X92(L-`````$ACT&:#?-%``'D'BX210`@``#G8='!) +XM@\0!33GT=0>+ +XMA)%`"```.=AT6$F#Q`%-.?1US>F9\___183_#X68````1(M4)!1%A=)T=T$/ +XMM@0D.<-T2DF#Q`%-.?1U[NEO\___BTPD*#'23(GF2(GOZ+[R__^%P`^%=___ +XM_S'`Z53S__^+3"0H,=),B>9(B>_HGO+__X7`=9,QP.DX\___,=),.V0D&(M, +XM)"A,B>9(B>\/E,+H>O+__X7`=9DQP.D4\___00^V!"0YV'0O28/$`4TY]'7N +XMZ?CR__]$BTPD%$6%R71E00^V!"0YPW0J28/$`4TY]'7NZ=?R__^+3"0H,=), +XMB>9(B>_H)O+__X7`=;PQP.G`\O__3#MD)!BZ`0```)!T"S'208!\)/\O#Y3" +XMBTPD*$R)YDB)[^CT\?__AB0Z6OR__]!#[8$)#D%`````'X92(L-`````$ACT&:#?-%``'D'BX21 +XM0`@``#G8#X3&````28/$`4TY]'7)Z2_R__],.V0D&+H!````=`LQTD&`?"3_ +XM+P^4PD2)Z4R)YDB)W^AJ\?__A<`/A#;U__])@\0!33GT= +XM-``##CH+.P5)$P(&```?'0$Q$Q$!$@%8"UD%`1,``"`%`#$3```A'0$Q$Q$! +XM$@%8"UD+```B'0$Q$U4&6`M9!0``(P4`,1,"!@``)#0``P@Z"SL%21,""@`` +XM)1T!,1,1`1(!6`M9!0``)AT!,1,1`1(!6`M9"P$3```G'0$Q$U4&6`M9!0$3 +XM```H'0$Q$U4&6`M9"P$3```I-``##CH+.PM)$P(&```J-``Q$P(&```K'0$Q +XM$U4&6`M9"P``+#0``PXZ"SL%21,""@``+2X!/PP##CH+.P4G#$D3$0$2`4`* +XM`1,``"X%``,..@L[!4D3`@8``"\T``,..@L["TD3/PP\#````$<,```"```` +XM```(`0`````!`````````````````````````````````@$&``````(!"``` +XM```"`@4``````@('``````,$!6EN=``"!`<``````@@%``````0``````SIE +XM`````@@'``````((!``````"!`0`````!``````#4EH````%"`<&"`0````` +XM!%9%````!``````$5XH````"`08`````!Q@%-.@````(``````4UE0````(C +XM``@`````!3:5`````B,$"``````%-Y4````"(P@(``````4XZ`````(C$``) +XM"&4````$``````4YIP````<0!3L>`0``"``````%/$4````"(P`(``````4] +XM'@$```(C"``)".X````$``````4^^0````J`$`5`]@$```@`````!4'V`0`` +XM`B,`"``````%0@8"```"(P@(``````5$00(```(C*`@`````!45R`@```B,P +XM"``````%1I4````"(S@(``````5(>`(```(C0`@`````!4F(`@```R/`$`@` +XM````!4J(`@```R/`&`@`````!5$D`0```R/`(`@`````!5(D`0```R/0(`@` +XM````!5,D`0```R/@(`@`````!56(`````R/P(`@`````!59%`````R/X(``+ +XMH`````8"```,A0````<`"Z`````6`@``#(4````?``T!E0```#`"```.,`(` +XM``YZ````#CL"````"0@V`@``#Z`````)"#`"```)"!8"```-`44```!F`@`` +XM#I4````.9@(```YZ````#FP"````"0B@````"0AF`@``"0A'`@``"V4```"( +XM`@``#(4```#_``N5````F`(```R%````_P`$``````57+P$```0`````!B1Z +XM`````@@%`````!```````FT!10````/;`@``$5]C``)LB@```!%?9@`";&4` +XM````$``````">@%%`````P(#```17V,``GF*````$5]F``)Y90```!(`$``` +XM```"G`&*`````QX#```17V,``IN*`````!```````H`!10````-$`P``$5]C +XM``)_B@```!%?9@`"?V4`````$P`````!B68"```!<@,``!%S``&',`(``!%C +XM``&(10```!0``````8IF`@```!4``````:,!10`````````````````````` +XM````````MPL``!8``````9\P`@```````!8``````:`P`@```````!8````` +XM`:%%`````````!8``````:)%`````````!=P``&D,`(````````7;@`!I#`" +XM````````%V,``:4P`````````!@``````:L!&0`````!C`$``````````!H` +XM````2PD``!MN;W0``28!10`````````<``````$G`:`````=`````!MF;@`! +XM0`$P`````````!H`````PP0``!X``````98!,``````````?VP(````````` +XM```````````````!G`&L!```(/8"```@[`(``"&U`@`````````````````` +XM``````)[(-`"```@Q@(`````(@(#`````````9P!(Q,#```````````?VP(` +XM```````````````````````!C0$,!0``(/8"```@[`(``"&U`@`````````` +XM``````````````)[(-`"```@Q@(`````']L"```````````````````````` +XM`4`!504``"#V`@``(.P"```AM0(````````````````````````">R#0`@`` +XM(,8"`````!H`````W@@``"1S='(``4\!MPL```.1L'\;8S$``5`!HP(````` +XM```<``````%4`3`"```?VP(````````````````````````!>`'6!0``(/8" +XM```@[`(``"&U`@````````````````````````)[(-`"```CQ@(````````` +XM`!_;`@````````````````````````%X`2,&```@]@(``"#L`@``(;4"```` +XM`````````````````````GL@T`(``"/&`@``````````']L"```````````` +XM`````````````7@!<`8``"#V`@``(.P"```AM0(````````````````````` +XM```">R#0`@``(\8"```````````?VP(````````````````````````!>`&] +XM!@``(/8"```@[`(``"&U`@````````````````````````)[(-`"```CQ@(` +XM`````````!\>`P````````````````````````%X`>@&```@.0,``",O`P`` +XM```````?VP(````````````````````````!>`$U!P``(/8"```@[`(``"&U +XM`@````````````````````````)[(-`"```CQ@(``````````!_;`@`````` +XM``````````````````%X`8('```@]@(``"#L`@``(;4"```````````````` +XM`````````GL@T`(``"/&`@``````````']L"```````````````````````` +XM`7@!SP<``"#V`@``(.P"```AM0(````````````````````````">R#0`@`` +XM(\8"```````````?VP(````````````````````````!>`$<"```(/8"```@ +XM[`(``"&U`@````````````````````````)[(-`"```CQ@(``````````!_; +XM`@````````````````````````%X`6D(```@]@(``"#L`@``(;4"```````` +XM`````````````````GL@T`(``"/&`@``````````']L"```````````````` +XM`````````7@!M@@``"#V`@``(.P"```AM0(````````````````````````" +XM>R#0`@``(\8"```````````E'@,````````````````````````!>`$@.0,` +XM`",O`P``````````']L"`````````````````````````48!)PD``"#V`@`` +XM(.P"```AM0(````````````````````````">R#0`@``(,8"`````"4"`P`` +XM``````````````````````&-`2,3`P```````````";;`@`````````````` +XM``````````&PDPD``"#V`@``(.P"```AM0(````````````````````````" +XM>R#0`@``(,8"`````"<"`P````````'+`:T)```C$P,`````````)ML"```` +XM`````````````````````<;U"0``(/8"```@[`(``"&U`@`````````````` +XM``````````)[(-`"```@Q@(`````*`(#`````````<@."@``(Q,#```````` +XM`!H`````#PL``!0``````>TP`@``&@`````["@``*0`````!\T4````````` +XM`"A$`P````````'O:`H``"-=`P```````"!4`P``'0`````J9@,````````` +XM`!T`````'@`````!#`%%`````````!_;`@````````````````````````$1 +XM`<8*```@]@(``"#L`@``(;4"`````````````````````````GL@T`(``"#& +XM`@`````G`@,````````!$P'@"@``(Q,#`````````"+;`@````````$3`2#V +XM`@``(.P"```KM0(````````">R#0`@``(,8"````````']L"```````````` +XM`````````````R#0`@``(,8"`````";;`@````````````````````````'(H`L``"#V +XM`@``(.P"```AM0(````````````````````````">R#0`@``(,8"`````"P` +XM`````24!10````D#````````````"Z````#'"P``#(4````&`"T!``````'D +XM`0%%``````````````````````````)W"!T,```N``````'A`3`"```````` +XM+@`````!X@$P`@```````"X``````>,!10``````````+P`````"6D4````! +XM`2\`````!5N8`@```0$O``````5<1`P```$!"0B8`@```)P$```"`,8````! +XM`?L."@`!`0$!`````2]U7!E+F@` +XM`@``&Y +XM*3LN@8$#=8T#H0)'`]]]1PAU`PZWQTB"!`(#J']_!`$#V`#AW7<#X0`(Q?+6 +XMH9\(CX&"1"XVK`0"`ZY^?P0!`](![PAS`PJ-`SN-KP0"`^%]500!`Y\"""L( +XMGX$I20,08ZH#J7Z;V`BYD%B&`W%'`Q,(MP,*?P.;?SD#Y0`Y`YM_?U8X.@/F +XM`&,#$(T##*G_CXX"1!`$`@/;?E4$`0.E`>$$`@.*?ZD$`0/V`'$#P@$([P/] +XM?;<#^0&;!`(#HWU'!`$#W0((*P0"`])]X00!`RNW!`(#IG]'!`$#V@`(*P0" +XM`U7A!`$#-;<#$XV#`U`")@$#]@`",0$")Q61`PG]C[D$`@.H?K<$`0/8`>'4 +XM20/D`*FK`YU__0,1FX`X2&CW`W)5`PY'`W)'.CA(:/<#9=:Y +XMN$@#$(W(`[Q^"'$$`@/=?CD$`0.C`0@K`[5_")L#+L6/19T",1`#W@$(J0.) +XM?W$##\4#"U4#:%4#&$<$`@/V?0@Y!`$#B@)_!`(#]GT",0$$`0.*`G\$`@/V +XM?0(N`00!`XH"?P0"`_9]`BX!!`$#B@)_!`(#B7X"+@$$`0/W`0A'!`(#]GT( +XM?P0!`XH"?P0"`_9]`BX!!`$#B@)_!`(#]GT"+@$$`0.*`G\$`@/V?0(N`00! +XM`XH"?P0"`_9]`BX!!`$#B@)_!`(#]GT"+@$$`0.*`G\$`@.)?@(S`00!`]T! +XM",4#HW\">`&/CP(N#4@#B0%C`X)_J;@#M0&-`\=]"%4#A@$('58$`@/;?E4$ +XM`0.E`>$$`@.*?ZD$`0/V`'%&U`0"`]M^500!`Z4!X00"`XI_J00!`_8`<48( +XM\(S4`\(!"'\#OGYQ`\(!"$<#OGYQ`\(!"+<#OGYQC`ARC-0#P@$(1P.^?G$# +XMP@$"*P$#OGYQX.($`@/;?E4$`0.E`>$$`@.*?ZD$`0/V`'%^`V73`BT.`V'3 +XM9H8#<4<#P0`(X0/"`0A_`Z%^<58(<`,=TP/"`0(N`0.B?G$(<`/N`0B-+`(( +XM``$!4$]325A,65]#3U)214-4`&%L;G5M`&%L<&AA`&)L86YK`&-N=')L`&1I +XM9VET`&=R87!H`&QO=V5R`'!R:6YT`'!U;F-T`'-P86-E`'5P<&5R`'AD:6=I +XM=```````%````/____\!``%X$`P'")`!````````/``````````````````` +XM`(4/````````0@X00@X80@X@0@XH00XP00XX1`Z``8,'A@:,!8T$C@./`@`` +XM`````!0````````````````````*`````````!0``````````7I2``%X$`$# +XM#`<(D`$``#0````<`````````(4/````0@X00@X80@X@0@XH00XP00XX1`Z` +XM`8,'A@:,!8T$C@./`@``````%````%0`````````"@`````````````````` +XM```````"``````````(`=P@"``````````0``````````@!W$`0````````` +XM!@`````````"`'<8!@`````````(``````````(`=R`(``````````D````` +XM`````@!W*`D`````````"@`````````"`'PP````````!`%6L#@```````-X.`````````0!5```` +XM````````````````````````````)@`````````!`%0F`````````$X````` +XM`````P"1F'].`````````&<``````````0!49P````````"%#P````````,` +XMD9A_````````````````````````````````)@`````````!`%$F```````` +XM`(4/`````````P"1E'\````````````````````````````````F```````` +XM``$`4B8`````````,@`````````#`)&0?S(`````````G@`````````!`%*> +XM`````````+0``````````P"1D'^T`````````#P!`````````0!22P$````` +XM``#(`0````````$`4HD"````````!@,````````!`%(J`P```````-L#```` +XM`````P"1D'_;`P````````0$`````````0!2'`0````````S!`````````$` +XM4DX$````````=P0````````!`%*%!````````/<$`````````0!2]@8````` +XM````!P````````$`4A0'````````8@<````````!`%*C!P```````+,'```` +XM`````P"1D'\8"````````!L(`````````P"1D'\;"````````#,(```````` +XM`0!20`@```````!Q"`````````,`D9!_@@@```````#I"`````````,`D9!_ +XM'@P````````_#`````````,`D9!_50P```````!J#`````````,`D9!_D@P` +XM``````"L#@````````,`D9!_K`X```````#>#@````````$`4MX.```````` +XMA0\````````#`)&0?P`````````````````````V`````````)X````````` +XM`0!6G@````````"E``````````$`4Z4`````````JP`````````!`%:K```` +XM`````+0``````````0!5M`````````!R!0````````$`5G(%````````;@8` +XM```````!`%5N!@```````!@(`````````0!6&P@```````"+"`````````$` +XM5HL(````````Z0@````````!`%/I"`````````0)`````````0!5!`D````` +XM``"("P````````$`5H@+````````^0L````````!`%7Y"P```````'$.```` +XM`````0!6<0X```````"L#@````````$`4ZP.````````_@X````````!`%;^ +XM#@```````"D/`````````0!3*0\```````!>#P````````$`5EX/```````` +XMA0\````````!`%,`````````````````````3@````````"M``````````$` +XM7+0`````````&`@````````!`%P;"````````(4/`````````0!<```````` +XM`````````````$X`````````8``````````#`)&/?V``````````F@`````` +XM```!`%":`````````)X``````````P"1CW^>`````````*H``````````0!3 +XMJ@````````"T``````````,`D8]_M`````````#+``````````$`4,L````` +XM````_0`````````#`)&/?_T`````````$`$````````!`%`0`0```````#4! +XM`````````P"1CW\U`0```````%(!`````````0!04@$```````!L`0`````` +XM``,`D8]_;`$```````"``0````````$`4(`!````````T@$````````#`)&/ +XM?](!````````+0(````````!`%$M`@```````(D"`````````P"1CW^)`@`` +XM`````)<"`````````0!0EP(```````";`@````````,`D8]_FP(```````!< +XM`P````````$`4]0#````````VP,````````#`)&/?]L#````````Z@,````` +XM```!`%/J`P```````.X#`````````0!0[@,```````!.!`````````,`D8]_ +XM3@0```````"%!`````````$`4X4$````````]P0````````#`)&/?_<$```` +XM````$P4````````!`%$3!0```````%\%`````````P"1CW]?!0```````'D% +XM`````````0!1>04```````"6!@````````,`D8]_E@8```````"@!@`````` +XM``$`4,X&````````V@8````````!`%#:!@```````/8&`````````P"1CW_V +XM!@`````````'`````````0!0``<````````4!P````````,`D8]_%`<````` +XM```8!P````````$`4!@'````````HP<````````#`)&/?Z,'````````LP<` +XM```````!`%.S!P```````,<'`````````0!0QP<```````#+!P````````,` +XMD8]_RP<```````#V!P````````$`4!8(````````&`@````````!`%`;"``` +XM`````$`(`````````P"1CW]`"````````'$(`````````0!3<0@```````!^ +XM"`````````$`4'X(````````BP@````````!`%/I"````````/D+```````` +XM`P"1CW_Y"P```````$H,`````````0!32@P```````!5#`````````,`D8]_ +XM50P```````!J#`````````$`4VH,````````;@P````````!`%!N#``````` +XM`'L,`````````P"1CW][#````````)(,`````````0!3K`X```````#>#@`` +XM``````$`4P````````````````````!.`````````!@(`````````P"1K'\; +XM"````````(4/`````````P"1K'\`````````````````````3@````````!G +XM``````````$`5'(`````````M``````````!`%2\`````````!4!```````` +XM`0!4;`$```````"T`0````````$`5,0!````````6`(````````!`%1T`@`` +XM`````/8"`````````0!4U`,````````!!`````````$`5$X$````````;P0` +XM```````!`%2%!````````&X&`````````0!4Y08`````````!P````````$` +XM5!0'````````10<````````!`%1-!P```````(('`````````0!4EP<````` +XM``"C!P````````$`5+,'````````&`@````````!`%0;"````````$`(```` +XM`````0!4Z0@````````-"0````````$`5(@+````````^0L````````!`%1J +XM#````````'L,`````````0!4K`X```````#>#@````````$`5``````````` +XM``````````!.`````````&H``````````0!2<@````````"T``````````$` +XM4KP`````````/`$````````!`%)+`0```````,@!`````````0!2VP$````` +XM``!(`@````````$`4E0"````````!@,````````!`%+4`P```````#,$```` +XM`````0!23@0```````!W!`````````$`4H4$````````;@4````````!`%)N +XM!@```````+0&`````````0!2Q@8`````````!P````````$`4A0'```````` +XMB@<````````!`%**!P```````(X'`````````0!0C@<```````"7!P`````` +XM``$`4K,'````````&`@````````!`%(;"````````$`(`````````0!22@P` +XM``````!5#`````````$`4FH,````````>PP````````!`%*L#@```````-X. +XM`````````0!2`````````````````````$X`````````6``````````!`%&> +XM`````````+0``````````0!1O`````````#%``````````$`4=\````````` +XMY``````````!`%#D`````````/T``````````0!1VP$```````#X`0`````` +XM``$`4`H"````````+0(````````!`%!_`@```````(D"`````````0!0U`,` +XM``````#;`P````````$`4?<$````````!`4````````!`%!?!0```````(0% +XM`````````0!0H`8```````"W!@````````$`4+<&````````Q@8````````! +XM`%'&!@```````/8&`````````0!0LP<````````8"`````````$`41L(```` +XM````0`@````````!`%'I"````````.L(`````````0!0:@P```````![#``` +XM``````$`40````````````````````!_!0```````(0%`````````0!0K`4` +XM``````"Q!0````````$`4-D%````````W@4````````!`%`"!@````````<& +XM`````````0!0*P8````````P!@````````$`4.L(``````````D````````! +XM`%"1"P```````)P+`````````0!0J0L```````"U"P````````$`4+X+```` +XM````RPL````````!`%#9"P```````.4+`````````0!0]`L```````#Y"P`` +XM``````$`4`````````````````````!.`````````(0"`````````0!1B0(` +XM```````8"`````````$`41L(````````&`D````````!`%$8"0```````",) +XM`````````0!0(PD```````!<"0````````$`46X)````````D@D````````! +XM`%&D"0```````,@)`````````0!1V@D````````L"@````````$`43X*```` +XM````8@H````````!`%%T"@```````)@*`````````0!1J@H```````#."@`` +XM``````$`4>`*````````!`L````````!`%$6"P```````#H+`````````0!1 +XM30L```````"%#P````````$`40````````````````````!.`````````%@` +XM`````````0!1G@````````"T``````````$`4;P`````````Q0`````````! +XM`%'?`````````/T``````````0!1?P(```````"$`@````````$`4=0#```` +XM````VP,````````!`%&S!P```````!@(`````````0!1&P@```````!`"``` +XM``````$`45$)````````7`D````````!`%!<"0```````)()`````````0!1 +XMI`D```````#("0````````$`4=H)````````+`H````````!`%$^"@`````` +XM`&(*`````````0!1=`H```````"8"@````````$`4:H*````````S@H````` +XM```!`%'@"@````````0+`````````0!1%@L````````Z"P````````$`44T+ +XM````````B`L````````!`%%J#````````'L,`````````0!1```````````` +XM`````````$X`````````6``````````!`%&>`````````+0``````````0!1 +XMO`````````#%``````````$`4=\`````````_0`````````!`%%_`@`````` +XM`(0"`````````0!1U`,```````#;`P````````$`4;,'````````&`@````` +XM```!`%$;"````````$`(`````````0!1APD```````"2"0````````$`4)() +XM````````R`D````````!`%':"0```````"P*`````````0!1/@H```````!B +XM"@````````$`470*````````F`H````````!`%&J"@```````,X*```````` +XM`0!1X`H````````$"P````````$`418+````````.@L````````!`%%-"P`` +XM`````(@+`````````0!1:@P```````![#`````````$`40`````````````` +XM``````!.`````````%@``````````0!1G@````````"T``````````$`4;P` +XM````````Q0`````````!`%'?`````````/T``````````0!1?P(```````"$ +XM`@````````$`4=0#````````VP,````````!`%&S!P```````!@(```````` +XM`0!1&P@```````!`"`````````$`4;T)````````R`D````````!`%#("0`` +XM`````"P*`````````0!1/@H```````!B"@````````$`470*````````F`H` +XM```````!`%&J"@```````,X*`````````0!1X`H````````$"P````````$` +XM418+````````.@L````````!`%%-"P```````(@+`````````0!1:@P````` +XM``![#`````````$`40````````````````````#'!P```````,L'```````` +XM`0!0\PD```````#Z"0````````$`4/H)````````#0H````````!`%`````` +XM````````````````3@````````!8``````````$`49X`````````M``````` +XM```!`%&\`````````,4``````````0!1WP````````#]``````````$`47\" +XM````````A`(````````!`%'4`P```````-L#`````````0!1LP<````````8 +XM"`````````$`41L(````````0`@````````!`%$A"@```````"P*```````` +XM`0!0+`H```````!B"@````````$`470*````````F`H````````!`%&J"@`` +XM`````,X*`````````0!1X`H````````$"P````````$`418+````````.@L` +XM```````!`%%-"P```````(@+`````````0!1:@P```````![#`````````$` +XM40````````````````````!.`````````%@``````````0!1G@````````"T +XM``````````$`4;P`````````Q0`````````!`%'?`````````/T````````` +XM`0!1?P(```````"$`@````````$`4=0#````````VP,````````!`%&S!P`` +XM`````!@(`````````0!1&P@```````!`"`````````$`45<*````````8@H` +XM```````!`%!B"@```````)@*`````````0!1J@H```````#."@````````$` +XM4>`*````````!`L````````!`%$6"P```````#H+`````````0!130L````` +XM``"("P````````$`46H,````````>PP````````!`%$````````````````` +XM````3@````````!8``````````$`49X`````````M``````````!`%&\```` +XM`````,4``````````0!1WP````````#]``````````$`47\"````````A`(` +XM```````!`%'4`P```````-L#`````````0!1LP<````````8"`````````$` +XM41L(````````0`@````````!`%&-"@```````)@*`````````0!0F`H````` +XM``#."@````````$`4>`*````````!`L````````!`%$6"P```````#H+```` +XM`````0!130L```````"("P````````$`46H,````````>PP````````!`%$` +XM````````````````````3@````````!8``````````$`49X`````````M``` +XM```````!`%&\`````````,4``````````0!1WP````````#]``````````$` +XM47\"````````A`(````````!`%'4`P```````-L#`````````0!1LP<````` +XM```8"`````````$`41L(````````0`@````````!`%'#"@```````,X*```` +XM`````0!0S@H````````$"P````````$`418+````````.@L````````!`%%- +XM"P```````(@+`````````0!1:@P```````![#`````````$`40`````````` +XM``````````!.`````````%@``````````0!1G@````````"T``````````$` +XM4;P`````````Q0`````````!`%'?`````````/T``````````0!1?P(````` +XM``"$`@````````$`4=0#````````VP,````````!`%&S!P```````!@(```` +XM`````0!1&P@```````!`"`````````$`4?D*````````!`L````````!`%`$ +XM"P```````#H+`````````0!130L```````"("P````````$`46H,```````` +XM>PP````````!`%$`````````````````````3@````````!8``````````$` +XM49X`````````M``````````!`%&\`````````,4``````````0!1WP`````` +XM``#]``````````$`47\"````````A`(````````!`%'4`P```````-L#```` +XM`````0!1LP<````````8"`````````$`41L(````````0`@````````!`%$O +XM"P```````#H+`````````0!0.@L```````"("P````````$`46H,```````` +XM>PP````````!`%$`````````````````````G@````````"E``````````$` +XM4-L!````````^`$````````!`%`*`@```````"T"`````````0!0?P(````` +XM``")`@````````$`4/<$````````!`4````````!`%!?!0```````(0%```` +XM`````0!0QP<```````#+!P````````$`4.D(````````ZP@````````!`%!J +XM"P```````'4+`````````0!0=0L```````"("P````````$`4``````````` +XM``````````!.`````````&H``````````0!2<@````````"T``````````$` +XM4KP`````````/`$````````!`%)+`0```````,@!`````````0!2VP$````` +XM```M`@````````$`4BT"````````2`(````````!`%!(`@```````%0"```` +XM`````0!25`(```````!D`@````````$`4&0"````````!@,````````!`%+4 +XM`P```````#,$`````````0!23@0```````!W!`````````$`4H4$```````` +XM;@4````````!`%)I!@```````&X&`````````0!0;@8```````"%!@`````` +XM``$`4N4&``````````<````````!`%(4!P```````(('`````````0!2EP<` +XM``````">!P````````$`4IX'````````HP<````````!`%"S!P```````!@( +XM`````````0!2&P@```````!`"`````````$`4DH,````````50P````````! +XM`%!J#````````'L,`````````0!2K`X```````#>#@````````$`4@`````` +XM``````````````!.`````````&H``````````0!2<@````````":```````` +XM``$`4IH`````````G@`````````!`%">`````````+0``````````0!2O``` +XM```````\`0````````$`4DL!````````R`$````````!`%*)`@````````8# +XM`````````0!2U`,```````#N`P````````$`4NX#````````!`0````````! +XM`%`$!````````!<$`````````0!2%P0````````#P```````(4/`````````0!=```````````````` +XM`````/8"````````!@,````````!`%0`````````````````````G@`````` +XM``"Q``````````$`7@D#````````#`,````````!`%`,`P```````-L#```` +XM`````0!>HP<```````"S!P````````$`7D`(````````<0@````````!`%Y^ +XM"````````.D(`````````0!>^0L```````!*#`````````$`7E4,```````` +XM:@P````````!`%Y[#````````*P.`````````0!>W@X```````"%#P`````` +XM``$`7@````````````````````">`````````+0``````````P"1J'\Q`P`` +XM`````-L#`````````P"1J'^C!P```````+,'`````````P"1J']`"``````` +XM`'$(`````````P"1J']5#````````&H,`````````P"1J'^2#````````'$. +XM`````````P"1J'_>#@```````/X.`````````P"1J'\I#P```````%X/```` +XM`````P"1J'\`````````````````````G@````````"E``````````$`4*4` +XM````````M``````````!`%%Z`P```````*0#`````````0!0I`,```````"S +XM`P````````$`4;,#````````T`,````````!`%"7#````````*X,```````` +XM`0!0K@P```````"]#`````````$`4;T,````````Y@P````````!`%#F#``` +XM`````/4,`````````0!1]0P````````'#0````````$`4#$-````````0@T` +XM```````!`%!1#0```````&(-`````````0!0-0X```````!,#@````````$` +XM4$P.````````6PX````````!`%%;#@```````'$.`````````0!0*0\````` +XM``!/#P````````$`4`````````````````````"0#P```````)H/```````` +XM`0!5`````````````````````)`/````````F@\````````!`%0````````` +XM````````````D`\```````"5#P````````$`494/````````F@\````````! +XM`%(`````````````````````&@````(``````$L,``#'"P``9FYM871C:``` +XM````+`````(```````@`````````````````F@\````````````````````` +XM````````-@`````````[`````````&H,````````@`P```````!*#``````` +XM`%4,````````Z0@`````````#````````+,'````````&P@```````!%!P`` +XM`````*,'````````M@0````````4!P```````'`!````````B0(````````` +XM````````````````````-@`````````[`````````$H,````````50P````` +XM``#I"``````````,````````8@<```````"C!P```````&`%````````Y08` +XM``````#W!````````$0%````````X`$```````")`@```````-(!```````` +XMU0$```````#,`0```````-`!`````````````````````````````'P&```` +XM````V@8```````""!P```````)<'`````````````````````````````)T& +XM````````H`8```````"_!@```````,8&```````````````````````````` +XM`#8`````````.P````````#I"``````````,````````:@4```````!D!@`` +XM``````````````````````````"6`````````)H`````````$`0````````< +XM!`````````````````````````````!;`0```````%\!````````0@0````` +XM``!.!`````````````````````````````#S`@```````-0#````````7@\` +XM``````"%#P```````/X.````````5P\```````#>#@```````/<.```````` +XM%PX```````"L#@```````.4-````````$`X```````"1#0```````-X-```` +XM````;0T```````"*#0```````%$-````````9@T```````"`#````````$H- +XM````````50P```````!J#``````````,````````2@P```````!^"``````` +XM`.((````````0`@```````!Q"````````*,'````````LP<````````````` +XM````````````````?@@```````#B"````````%X/````````A0\```````#^ +XM#@```````"D/````````<0X```````"L#@`````````````````````````` +XM``#V`@```````/D"````````@`P```````"2#`````````$#````````$@,` +XM````````````````````````````!@,````````)`P````````P#```````` +XM$@,`````````````````````````````)@,```````#4`P```````"D/```` +XM````5P\```````#>#@```````/<.````````%PX```````!Q#@```````.4- +XM````````$`X```````"1#0```````-X-````````;0T```````"*#0`````` +XM`%$-````````9@T```````"2#````````$H-````````50P```````!J#``` +XM`````$`(````````<0@```````"C!P```````+,'```````````````````` +XM`````````*P#````````LP,```````!4#@```````%L.````````[@P````` +XM``#U#````````+8,````````O0P`````````````````````````````D@,` +XM``````"A`P```````#H.````````20X```````#4#````````.,,```````` +XMG`P```````"K#`````````````````````````````"2`P```````*$#```` +XM````.@X```````!)#@```````-0,````````XPP```````"<#````````*L, +XM`````````````````````````````')E'0`+F1A=&$`+F)S````````H`0```````````````````$` +XM``````````````````!0````!`````````````````````````#P=0`````` +XM`!@`````````&`````@````(`````````!@`````````80````$````R```` +XM````````````````*R,```````!9`````````````````````0`````````! +XM`````````'4````!`````````````````````````(@C````````<``````` +XM``````````````@```````````````````!P````!``````````````````` +XM```````(=@```````&``````````&`````L````(`````````!@````````` +XMAP````$````"````````````````````^",```````!H```````````````` +XM````"````````````````````((````$`````````````````````````&AV +XM````````,``````````8````#0````@`````````&`````````"1`````0`` +XM``````````````````````!@)````````!XD```````````````````!```` +XM````````````````H0````$`````````````````````````?D@````````> +XM`````````````````````0```````````````````)P````$```````````` +XM`````````````)AV````````&``````````8````$`````@`````````&``` +XM``````"V`````0````````````````````````"<2````````#`````````` +XM```````````!````````````````````L0````0````````````````````` +XM````L'8````````P`````````!@````2````"``````````8`````````,4` +XM```!`````````````````````````,Q(````````L`4````````````````` +XM``$```````````````````#3`````0```#````````````````````!\3@`` +XM`````/@"```````````````````!``````````$`````````W@````$````` +XM````````````````````=%$````````F`````````````````````0`````` +XM`````````````!$````#`````````````````````````)I1````````YP`` +XM``````````````````$````````````````````!`````@`````````````` +XM```````````(60```````%@"````````&0```!,````(`````````!@````` +XM````"0````,`````````````````````````8%L```````![```````````` +XM`````````0`````````````````````````````````````````````````` +XM``$````$`/'_```````````````````````````#``$````````````````` +XM```````````#``,````````````````````````````#``0````````````` +XM```````````````#``4````````````````````````````#``8````````` +XM```````````````````#``@````````````````````````````#``H````` +XM``````````````````L````"``$```````````"%#P```````!P````!``0` +XM```````````$```````````````#``L````````````````````````````# +XM``T````````````````````````````#``\````````````````````````` +XM```#`!`````````````````````````````#`!(````````````````````` +XM```````#`!0````````````````````````````#`!4````````````````` +XM```````````#`!8``````````````````````#$````0```````````````` +XM`````````#\````0`````````````````````````%(````0```````````` +XM`````````````%D````0`````````````````````````&`````0```````` +XM`````````````````',````2``$`D`\````````*``````````!F;FUA=&-H +XM+F,`:6YT97)N86Q?9FYM871C:`!P;W-I>&QY7V-O@H````````*```` +XM"````#H`````````CPH````````"````$P```/S_________FPH````````" +XM````%````/S_________L`H````````*````"````$``````````Q0H````` +XM```"````$P```/S_________T0H````````"````%````/S_________Y@H` +XM```````*````"````$8`````````^PH````````"````$P```/S_________ +XM!PL````````"````%````/S_________'`L````````*````"````$P````` +XM````,0L````````"````$P```/S_________/0L````````"````%````/S_ +XM________4PL````````*````"````%(`````````>`L````````+````%P`` +XM`$(`````````A@P````````"````%0```/S_________G@P````````"```` +XM$P```/S_________IPP````````"````%````/S_________U@P````````" +XM````$P```/S_________WPP````````"````%````/S_________/`X````` +XM```"````$P```/S_________10X````````"````%````/S_________!@`` +XM```````*````!0``````````````#``````````*````$0```,H````````` +XM$0`````````*````$0````8!````````%0`````````!`````@`````````` +XM````'0`````````!`````@```)H/````````)0`````````*````!P`````` +XM````````+``````````*````$0```)0!````````,P`````````*````$0`` +XM`'@!````````.@`````````*````$0```#$`````````00`````````*```` +XM$0```.X!````````3P`````````*````$0```+4!````````5@`````````* +XM````$0```.H`````````6P`````````*````$0```"L"````````:``````` +XM```*````$0```&L"````````;P`````````*````$0```'T"````````=@`` +XM```````*````$0```+8`````````>P`````````*````$0```!4"```````` +XMBP`````````*````$0```&P!````````E@`````````*````$0```(D````` +XM````HP`````````*````$0```!`"````````L``````````*````$0```)L" +XM````````O@`````````*````$0```$L"````````S``````````*````$0`` +XM`&8!````````V@`````````*````$0```*D"````````[P`````````*```` +XM$0```$`"`````````@$````````*````$0```,8"````````$`$````````* +XM````$0```$(`````````)0$````````*````$0```.,!````````.0$````` +XM```*````$0```)T`````````1P$````````*````$0```-L"````````50$` +XM```````*````$0```-`"````````8P$````````*````$0```%$"```````` +XM<0$````````*````$0```$04````````*````#0```(0.```````` +XM?@4````````*````$0```,T!````````C@4````````!`````@```!@)```` +XM````E@4````````!`````@```"`)````````M`4````````!`````@```!@) +XM````````O`4````````!`````@```"`)````````T`4````````*````#0`` +XM`&4/````````VP4````````!`````@```%$)````````XP4````````!```` +XM`@```%D)`````````08````````!`````@```%$)````````"08````````! +XM`````@```%D)````````'08````````*````#0```'\0````````*`8````` +XM```!`````@```(<)````````,`8````````!`````@```(\)````````3@8` +XM```````!`````@```(<)````````5@8````````!`````@```(\)```````` +XM:@8````````*````#0```/@1````````=08````````!`````@```+T)```` +XM````?08````````!`````@```,4)````````FP8````````!`````@```+T) +XM````````HP8````````!`````@```,4)````````MP8````````*````#0`` +XM`%X3````````P@8````````!`````@```/,)````````R@8````````!```` +XM`@````@*````````XP8````````*````#0```+$4````````[08````````! +XM`````@```"$*````````]08````````!`````@```"D*````````$P<````` +XM```!`````@```"$*````````&P<````````!`````@```"D*````````+P<` +XM```````*````#0```/H4````````.@<````````!`````@```%<*```````` +XM0@<````````!`````@```%\*````````8`<````````!`````@```%<*```` +XM````:`<````````!`````@```%\*````````?`<````````*````#0```#H6 +XM````````AP<````````!`````@```(T*````````CP<````````!`````@`` +XM`)4*````````K0<````````!`````@```(T*````````M0<````````!```` +XM`@```)4*````````R0<````````*````#0```&<7````````U`<````````! +XM`````@```,,*````````W`<````````!`````@```,L*````````^@<````` +XM```!`````@```,,*`````````@@````````!`````@```,L*````````%@@` +XM```````*````#0```($8````````(0@````````!`````@```/D*```````` +XM*0@````````!`````@````$+````````1P@````````!`````@```/D*```` +XM````3P@````````!`````@````$+````````8P@````````*````#0```(@9 +XM````````;@@````````!`````@```"\+````````=@@````````!`````@`` +XM`#<+````````E`@````````!`````@```"\+````````G`@````````!```` +XM`@```#<+````````L`@````````*````#0```'P:````````NP@````````! +XM`````@```&H+````````PP@````````!`````@```(@+````````V`@````` +XM```*````#0```%T;````````XP@````````!`````@```!@%````````ZP@` +XM```````!`````@```"<%````````"0D````````!`````@```!@%```````` +XM$0D````````!`````@```"<%````````+`D````````!`````@```)<'```` +XM````-`D````````!`````@```*,'````````1`D````````*````#0```"L< +XM````````4`D````````!`````@```%@`````````6`D````````!`````@`` +XM`&<`````````=0D````````!`````@```%@`````````?0D````````!```` +XM`@```&<`````````F`D````````*````$````-`!````````J`D````````* +XM````#0```/`=````````L@D````````!`````@```"T!````````N@D````` +XM```!`````@```#P!````````UPD````````!`````@```"T!````````WPD` +XM```````!`````@```#P!````````^@D````````*````$``````"```````` +XM"0H````````*````#0```%8?````````#PH````````*````$````#`"```` +XM````&`H````````*````$0```(0`````````(PH````````*````$````#`# +XM````````+`H````````*````$0```$L`````````-@H````````*````#0`` +XM`#<@````````0`H````````*````$````(`#````````3PH````````*```` +XM#0```+D@````````60H````````*````$````,`#````````8@H````````* +XM````#0```-P@````````:0H````````*````$````/`#````````;@H````` +XM```*````$0```$L`````````>0H````````*````#0```*HA````````@@H` +XM```````!`````@```$,(````````B@H````````!`````@```%8(```````` +XMJ`H````````!`````@```$,(````````L`H````````!`````@```%8(```` +XM````RPH````````*````$````,`$````````VPH````````*````#0```&(B +XM````````Y0H````````*````$````!`%````````^PH````````*````$``` +XM`&`%````````%`L````````!`````@```.X#````````'`L````````!```` +XM`@````$$````````.@L````````!`````@```.X#````````0@L````````! +XM`````@````$$````````70L````````!`````@```"`$````````90L````` +XM```!`````@```#,$````````@@L````````!`````@```"`$````````B@L` +XM```````!`````@```#,$````````H0L````````*````$0```%8!```````` +XMK@L````````!````!```````````````R0L````````*````$0```*$"```` +XM````U0L````````!`````@```)`/````````W0L````````!`````@```)H/ +XM````````[0L````````*````$0```!H`````````^`L````````*````#0`` +XM`*(C````````_0L````````*````$0```/,`````````"`P````````*```` +XM#0```,4C````````#0P````````*````$0```*`!````````&`P````````* +XM````#0```.@C````````'@P````````*````$0```(8!````````*PP````` +XM```*````$0````<`````````.`P````````*````$0```&4`````````TP`` +XM```````!`````@``````````````'``````````*````"P`````````````` +XM(``````````!`````@``````````````7``````````*````"P`````````` +XM````8``````````!`````@```)`/````````(``````````*`````@`````` +XM````````6``````````*`````@```)`/````````!@`````````*````!@`` +XM````````````!@`````````*````!@``````````````$``````````!```` +X,`@`````````````` +X` +Xend +b483319a2b8624af2d41c47d4e321b7b +echo x - ./kmkmissing.a.ar-script.bsd.uu +sed 's/^X//' >./kmkmissing.a.ar-script.bsd.uu << 'fa712d1134c6f057fe43287b8ef97632' +Xbegin 644 ./kmkmissing.a.ar-script.bsd +XM0U)%051%(&MM:VUI./kmkmissing.a.ar-script.gnu.uu << '88a4bce8c229186f85a9fbea1abe4663' +Xbegin 644 ./kmkmissing.a.ar-script.gnu +XM0U)%051%(&MM:VUI./getopt1.o.uu << '7f9a18e3e97f698c8a70c0f5493cdc24' +Xbegin 644 ./getopt1.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````-`'```` +XM`````````$```````$``&``5`$&Y`0```.D`````9F:09I!%,0````!`,!PB0`0```````!0````````````````````+```` +XM`````!0````````````````````(`````````!0``````````7I2``%X$`$# +XM#`<(D`$``!0````<``````````L``````````````!0````T``````````@` +XM````````````````````````"P`````````!`%4````````````````````` +XM```````````+``````````$`5`````````````````````````````````L` +XM`````````0!1````````````````````````````````"P`````````!`%(` +XM```````````````````````````````+``````````$`6``````````````` +XM```````0`````````!@``````````0!5`````````````````````!`````` +XM````&``````````!`%0`````````````````````$``````````8```````` +XM``$`40`````````````````````0`````````!@``````````0!2```````` +XM`````````````!``````````&``````````!`%@````````````````````` +XM,P````(``````,P!``#5````9V5T;W!T7VQO;F=?;VYL>0!?`0``9V5T;W!T +XM7VQO;F<``````"P````"```````(`````````````````!@````````````` +XM`````````````````&]P=%]I;F1E>`!'3E4@0R`T+C(N,2`R,#`W,#0!O<'1I;VYS``!' +XM0T,Z("A'3E4I(#0N,BXQ(#(P,#6UT86(` +XM+G-T./getopt.o.uu << 'e91f2be53ccef7c31a70c80e46567ff3' +Xbegin 644 ./getopt.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````+!$```` +XM`````````$```````$``&P`8`$%7059!54%455-(@^QXBP4`````2,<%```` +XM``````")?"1`2(ET)#A(B50D,$B)3"0HA +XM!P``N/____](@\1X6UU!7$%=05Y!7\-!@#DM#X5A`P``00^V40%)C4D!A-(/ +XMA%`#```QP$B#?"0H`'0)@/HM#Y3`@^`!3(TT"$R)-0````!(@WPD*`!T-XL5 +XM`````$B+3"0X2&/"B50D<$B+!,%(B40D:`^V0`$\+8A$)'Y( +XMBU0D,`^$EP0``$B+5"0PZPL/OL`YQ0^$A00``$B#P@$/M@*$P'7J,?:X`0`` +XM`(`Y`8L5`````(/2`(3`B14`````#X7Y`P``0(#_.@^$[P,``(`^5P^$T@4` +XM``^V?@%`@/\ZB>@/A>G^__^`?@(Z#X0N"0``@#D`#X1@"```@P4``````4B) +XM#0````")Z$C'!0``````````Z;;^___'!0`````!````Z3[]__](BU0D:(!Z +XM`@!U/$B+3"0P#[8!A,!T,$B)R@^^3"1W#[[P.?$/A#4&``!(BU0D,.L+#[[` +XM.<$/A",&``!(@\(!#[8"A,!UZD$/M@:$P(A$)$8/A,\$```\/4V)]`^$Q`0` +XM`$F#Q`%!#[8$)(3`#X7=`0``2(M4)"A(BQI(A=L/A#L&``!-B>=$B>%(B=5$ +XM*?%-*?=%,>U(QT0D2`````#'1"10`````,=$)%3_____B4PD#.L12(/%($B+ +XM70!(A=MT24&#Q0%,B?I,B?9(B=_H`````(7`==U(B=_H`````#E$)`P/A&L# +XM``!(@WPD2``/A.\"``!(@\4@QT0D4`$```!(BUT`2(7;=;>+1"10A<`/A$@# +XM``!$BST`````187_#X4"`P``3(GWZ`````!)`<:#!0`````!QP4````````` +XM`$R)-0````!(@\1XN#\```!;74%<05U!7D%?PTB#P0''!0`````"````2(E, +XM)##I(?S__SG008G%B=,/A(L#``!!.=-T-$&)Q$ACPDB+5"0X1(G=3(T\PF9F +XMD&9FD#G=#X]3`0``0XU$'0!$B1T`````*=B)!0````!$.5PD0$B+3"0X26/# +XM2(T4P7\@'@! +XM`'381(L=`````$2)%0````#I]/O__TB#1"0P`<<%``````````#I=OO__T6% +XM]@^$>/S__T&-0P%,B0T`````B04`````2(/$>+@!````6UU!7$%=05Y!7\.0 +XM/#T/A0K^___I%O[__V9FD$0YTP^-!?S__T6)V$6)T44IT$$IV44YR'Y'187) +XM#XZ>`0``2(M4)#A(8\-%*05_# +XM2(EL)$A$B6PD5.G!_/__2(722(G6#Y3`Z7_[__]$BUPD0$2)%0````#I[?G_ +XM_T&)[8DM`````.ED^O__12G+Z3SZ__](BT0D.$B+3"1HO@````!(BST````` +XM2(L0,<#H`````$R+-0````#ITOS__TB);"1(1(EL)%1(@WPD2``/A%0"``"+ +XM1"1P@\`!B04`````08`\)``/A*L```!(BU0D2$2+:@A%A>T/A8L#``!$BR4` +XM````187D=$-(BTPD.$B82(M$P?B`>`$M#X07`P``2(M4)$@/O@B^`````$B+ +XM1"0X2(L]`````$R+`DB+$#'`Z`````!,BS4`````3(GWZ`````!(BU0D2$D! +XMQDR)-0````"+0AB)!0````"X/P```.F9^?__03G#BP4`````00]%PXD%```` +XM`.F6_/__38GTZ47[__](BTPD2(-Y"`$/A/$!``!,B??H`````$D!QDB#?"0@ +XM`$R)-0````!T"XM4)%1(BT0D((D02(M,)$A(BU$02(72#X3D`0``BT$8B0(Q +XMP.DG^?__#[9^`4"`_SL/A23Z__^`.0`/A(@#``"#!0`````!2(D-`````$R+ +XM-0````!,B34`````00^V!H3`#Y5$)$F^`````$B+$#'`Z`````#I&/W__T2+ +XM+0````#IUO?__XM<)!R%VP^%F0$``$2+'0````!%A=MT,8!\)'??__SE$)$!^,4B+5"0X2)A( +XMBP3"2(D%`````(M$)'"#P`*)!0````#IY?W__TB+5"1(BT(8Z4+W__^++0`` +XM``"%[70I2(M4)#A(F$B+/0````"^`````$B+3,+X2(L2,<#H`````$R+-0`` +XM``!,B??H`````$B+5"1(20'&2(M,)#!,B34`````BT(8B04`````,<"`.3H/ +XME<"-1(`ZZ=GV__](BT0D2$B+/0````"^`````$B+"$B+1"0X2(L0,<#H```` +XM`$R+-0````#IY_S__TB+1"0X2(L]`````$R)\;X`````2(L0,<#H`````.GH +XM_O__28U$)`%(B04`````Z0S]__^+#0`````[3"1`#X3'`0``2(M4)#A(8\%( +XMBP3"2(D%`````(U!`8D%`````(GHZ7WW__^`?"1W+0^$7/[__TB+3"0P#[8! +XMA,`/A$S^__\/ODPD1@^^\$B+5"0P.?%T&TB+5"0P2(/"`0^V`H3`#X0G_O__ +XM#[[`.<%UZDB%T@^%M/W__^D2_O__9F9FD&9FD#P]3(GU#X3Y_/__2(/%`0^V +XM10"$P`^51"1'#X3G_/__/#UUY^G>_/__38GE1(E\)%SI$OW__X`Y``^$C@`` +XM`(,%``````%(B0T`````B>A(QP4``````````.F(]?__.U0D0'1X2(M,)#A( +XM8\)(BP3!2(D%`````(U"`8D%`````.E?_/__1(M$)%A%A<`/A)8```"+/0`` +XM``"%_P^%Z0```$B+'0````!(B=_H`````(,%``````%,C30#N#\```!,B34` +XM````Z1KU__](QP4``````````.EP____1(L-`````$6%R70=2(M$)#A(BST` +XM````B>F^`````$B+$#'`Z`````")+0````!(BU0D,#'`@#HZ#Y7`C42`.NG% +XM]/__38GE1(E\)%Q-A>T/A8,```"X5P```$C'!0``````````Z9_T__^+!0`` +XM``"%P'0=2(M$)#A(BST`````B>F^`````$B+$#'`Z`````!(BU0D,#'`B2T` +XM````@#HZ#Y7`C42`.NF6]?__2&,%`````$B+5"0XO@````!(BST`````2(L, +XMPDB+$C'`Z`````#I[/[__X!\)$<`#X2;````08MU"(7V=4V+#0````"%R70? +XM2(M$)#A)BTT`O@````!(BST`````2(L0,<#H`````$B+'0````!(B=_H```` +XM`$R--`.X/P```$R)-0````#IT?/__TB-10%(B04`````3(GWZ`````!)`<9( +XM@WPD(`!,B34`````=`N+1"1<2(M,)"")`4F+51!(A=)T/D&+11B)`C'`Z8OS +XM__]!@WT(`76^BPT`````.4PD0'XG2(M4)#A(8\%(BP3"2(D%`````(U!`8D% +XM`````.N408M%&.E1\___BQ4`````A=)T(TB+5"0X2&/!2(L]`````+X````` +XM2(M,POA(BQ(QP.@`````2(L=`````$B)W^@`````3(TT`TR)-0````#I*O[_ +XM_V9F9I!F9F:09F:09F:013')13'`,"P$``!\N +XM`3\,`PXZ"SL%)PQ)$Q$!$@%`!@$3```@!0`##CH+.P5)$P(&```A'0$Q$U4& +XM6`M9!0$3```B!0`Q$P``(PL!508``"0T`#$3`@8``"4T`#$3```F"P%5!@$3 +XM```G-``#"#H+.P5)$P(&```H-``##CH+.P5)$P(&```I!0`Q$P(&```J'0$Q +XM$U4&6`M9!0``*R8``PY)$P``+"X!/PP##CH+.P4G#$D3$0$2`4`*`1,``"TT +XM``,..@L["TD3`@H``"XT``,..@L["TD3/PP\#```+S0``PXZ"SL+21,_#`(* +XM````N`@```(```````@!``````$````````````````````````````````" +XM`08``````@$(``````("!0`````"`@<``````P0%:6YT``($!P`````$```` +XM``(Y7@````((!0`````""`<``````@@$``````($!``````%"`<&"`0````` +XM`S13````!X`#8ZD````(``````-DJ0````@``````V53``````FY````N0`` +XM``IZ````?P`"`08`````!``````#9HH````$``````0O?P````L`````$`1& +XM_P````P`````!$?_`````B,`#``````$2$4````"(P@`#0@P````#@`````P +XM`01G=0(```]?<``$:/\````"(P`/7W(`!&E%`````B,(#U]W``1J10````(C +XM#`P`````!&LW`````B,0#``````$;#<````"(Q(/7V)F``1MU@````(C&`P` +XM````!&Y%`````B,H#``````$<7T````"(S`,``````1RA0(```(C.`P````` +XM!'.K`@```B-`#``````$=,L"```"(T@,``````1U]@(```(C4`]?=6(`!'C6 +XM`````B-8#U]U<``$>?\````"(V@/7W5R``1Z10````(C<`P`````!'W\`@`` +XM`B-T#``````$?@P#```"(W`P`````!(1%`````R.( +XM`0P`````!(7+`````R.0`0P`````!(@````(`"3`````<`P``"GH``````!,``````0T('`,` +XM`!,``````0T(*`,```0`````!(P%`0``"P`````@!5*$`P``#``````%5.L" +XM```"(P`,``````5:10````(C"`P`````!5N$`P```B,0#W9A;``%7$4````" +XM(Q@`#0A%````%`0!MZ4#```5```````5``````$5``````(`%@`````!U@&E +XM`@```L"```! +XM!`0``!D``````8`!10```!D``````8`!!`0``!D``````8`!ZP(````-"`H$ +XM```2I0(``!H``````2T!`0&.!```&0`````!+`&.!```&P`````!+@%%```` +XM&P`````!+P%%````''1O<``!,`%%````''1E;0`!,0&E`@``'74$```<;&5N +XM``%3`44````<:0`!5`%%`````!X<;&5N``%D`44````<:0`!90%%```````- +XM"*4"```?`0`````!^0$!10``````````````````````````````;`<``"`` +XM`````?!``` +XM)&H$``````````````T(<@<``"L`````/P,``"P!``````&Y`P%%```````` +XM``````````````````)W"-$'```@``````&X`T4`````````(``````!N`,$ +XM!````````"```````;@#ZP(`````````+0`````!C*4"```)`P`````````` +XM+0`````!N8H#```)`P``````````+0`````!O*4"```)`P``````````+0`` +XM```!]$4````)`P``````````+0`````!]44````)`P``````````+@`````$ +XMDD<(```!`0T(-`,``"\``````6ZE`@```0D#```````````O``````%]10`` +XM``$)`P``````````+P`````!D44````!"0,``````````"\``````9=%```` +XM`0D#```````````O`````` ````$)`P```````````(D#```"`+`````! +XM`?L."@`!`0$!`````2]U7!E7!E$#"PB;`Q,(Q0/K?`(_`0.T=SQG"K0P.A!-.Y +XM*64#$.\#^0"-2;D##YN2;G0#%2L#SWSO`^T`X0/K?*D#E0/A`^U\50.3`ZD# +XM[7QQJT,#H0-Q`BP4"#PV/#8(UF#^"!\#"0@=`W2W`PQ'`W1_`Q>-N?*J&/`^,"_0.=?4<#XP)5`\-]MP/6?>^/"!8#$8T# +XM<0BW.C8\.C4#$0@=`V]5`Q/].C8\.C7-`UY_CP@6`Q&-`W$(<3HV/#HU`Q$( +XM'0-O50,3"#DZ-CPZ-ZD#A`3O`_Y[50." +XM!+<#@'Q50ZL#@@1Q`]@`"$<#$`(I`0/'`,60<'8#BW\('0,28P,?"._5UN)P +XM2%0#/K<#CG_ON@BZ`]$`8P-?"%6!`RR-`QT(1YX(O'!D`ZE_X0,)`BL!K8.< +XM"-<#>`(D`0,:J:IBF5D(&]P=&EO;B!@)6,EQ^```````````````` +XM`````&X!````````O`$````````!`%-M!0```````)L%`````````0!3FP4` +XM``````"G!0````````$`4-$%````````W@4````````!`%/>!0```````.T% +XM`````````0!0`P8````````+!@````````$`4S$'````````.0<````````! +XM`%.0"0```````*$)`````````0!3`````````````````````$\!```````` +XM=0$````````!`%9U`0```````)4!`````````0!;E0$```````"]`0`````` +XM``$`5KT!````````Q@$````````!`%MM!0```````*<%`````````0!;IP4` +XM``````"V!0````````$`4-$%````````"P8````````!`%LC!P```````#$' +XM`````````0!6,0<````````Y!P````````$`6Y`)````````H0D````````! +XM`%8`````````````````````=0$```````#&`0````````$`46T%```````` +XMF`4````````!`%&S!0````````L&`````````0!1,0<````````Y!P`````` +XM``$`49`)````````H0D````````!`%$`````````````````````=0$````` +XM``#&`0````````$`56T%````````H`4````````!`%71!0```````.`%```` +XM`````0!5X`4```````#P!0````````$`5?`%````````"P8````````!`%4Q +XM!P```````#D'`````````0!5D`D```````"A"0````````$`50`````````` +XM``````````!U`0```````,8!`````````0!5;04```````"@!0````````$` +XM5:`%````````N04````````!`%6Y!0```````.`%`````````0!5`P8````` +XM```+!@````````$`53$'````````.0<````````!`%60"0```````*$)```` +XM`````0!5`````````````````````+ +XM"`````````$`5CX(````````D`@````````!`%9X"0```````(L)```````` +XM`0!6SPD```````!["@````````$`5MX*````````00L````````!`%9T"P`` +XM`````,D+`````````0!6`````````````````````+"``````` +XM``,`D:1_/@@```````!G"0````````,`D:1_>`D```````"0"0````````,` +XMD:1_H0D```````##"0````````,`D:1_SPD```````"R#@````````,`D:1_ +XM`````````````````````+`D```````"0"0`` +XM``````$`7:$)````````PPD````````!`%W/"0```````-X*`````````0!= +XM#0L````````P"P````````$`74$+````````^0L````````!`%T&#``````` +XM`%8,`````````0!=G0P```````#R#`````````$`70,-````````6PT````` +XM```!`%T`````````````````````MP$```````#&`0````````$`4G@)```` +XM````@`D````````!`%+;"0````````X*`````````0!2&`H````````^"@`` +XM``````$`4@T+````````'`L````````!`%*4"P```````,D+`````````0!2 +XM`````````````````````!`!````````=0$````````!`%R5`0```````+\! +XM`````````0!08````````!`%5Y!@`` +XM`````(D&`````````0!5B08```````"D!@````````$`51('````````(P<` +XM```````!`%5G"0```````&\)`````````0!5D`D```````"A"0````````$` +XM5<,)````````SPD````````!`%4`````````````````````$`$````````H +XM`0````````$`5:4!````````Q@$````````!`%6J!````````!P%```````` +XM`0!5"P8````````[!@````````$`53L&````````3P8````````!`%5/!@`` +XM`````'D&`````````0!5G`8```````"D!@````````$`51('````````(P<` +XM```````!`%5G"0```````&\)`````````0!5D`D```````"A"0````````$` +XM5<,)````````SPD````````!`%4`````````````````````P`X```````#- +XM#@````````$`50````````````````````#`#@```````,T.`````````0!4 +XM`````````````````````,`.````````S0X````````!`%$````````````` +XM````````F5D```````L`````@`````` +XM"`````````````````#-#@````````````````````````````!.```````` +XM`*<`````````'`4````````Q!0```````&X$````````A@0````````````` +XM````````````````8P$```````!K`0```````#$'````````.0<```````!P +XM!0````````L&````````<0$```````"5`0`````````````````````````` +XM``!C`0```````&L!````````,0<````````Y!P```````'`%````````"P8` +XM``````!Q`0```````)4!`````````````````````````````),%```````` +XML`4```````#G!0````````L&````````T04```````#6!0`````````````` +XM``````````````!C`0```````&L!````````,0<````````Y!P```````-8% +XM````````YP4```````"P!0```````-$%````````B@4```````"3!0`````` +XM`'$!````````=0$`````````````````````````````L@$```````"W`0`` +XM`````-`+````````L@X```````!!"P```````'0+````````H0D```````#/ +XM"0```````'@)````````D`D```````"0"````````&<)````````!`<````` +XM```7!P```````.4&````````Z@8```````"D!@```````.$&````````/@(` +XM```````!`P`````````````````````````````^`@```````$,"```````` +XM!`<````````7!P```````%D"````````D0(```````!2`@```````%4"```` +XM`````````````````````````+X"````````P@(```````!;#0```````+(. +XM````````K0P````````8#0```````"\,````````G0P```````#0"P`````` +XM``8,````````G@@```````!G"0`````````````````````````````;`P`` +XM`````"H#````````00,```````!7`P```````"\#````````.@,````````` +XM````````````````````5P,```````!:!````````'0+````````T`L````` +XM``#/"0```````$$+````````-@@```````"0"````````#D'````````'@@` +XM``````#U!@````````0'````````8`4```````!P!0```````%X$```````` +XM8P0`````````````````````````````?PL```````"/"P```````*4+```` +XM````NPL```````"4"P```````*`+`````````````````````````````)L$ +XM````````HP0```````!G"0```````&\)````````"P8```````"D!@`````` +XM`*8$````````S`0`````````````````````````````FP0```````"C!``` +XM`````&<)````````;PD````````+!@```````*0&````````I@0```````#, +XM!``````````````````````````````N!@```````$8&````````@`8````` +XM``"D!@```````&<&````````;`8`````````````````````````````FP0` +XM``````"C!````````&<)````````;PD```````!L!@```````(`&```````` +XM1@8```````!G!@```````"4&````````+@8```````"F!````````+`$```` +XM`````````````````````````&]P=&EN9`!O<'1A`!E +XM>&-H86YG90!S:&]R="!I;G0`7V]F9G-E=`!?9FQA9W,`7W=R:71E`'!T:')E +XM860`7U]S=&1E0!?7VUB`!N86UE96YD +XM`&UY7VEN9&5X`'!T:')E861?;75T97@`7W-E96L`<&9O=6YD`%]F:6QE`'!O +XM6UT86(`+G-T5]C +XM;W)R96-T`&]R9&5R:6YG`%]G971O<'1?:6YT97)N86P`;W!T:6YD`&]P=&%R +XM9P!?7V=E=&]P=%]I;FET:6%L:7IE9`!G971E;G8`````_/________\[!`````````(````=````_/________]$!``````` +XM``(````8````^_________]+!`````````(````?````^/________]6!``` +XM``````(````$````#`````````!T!`````````(````$````$`````````#` +XM!`````````(````$````*`````````#(!`````````(````$````)``````` +XM``#Q!`````````(````8````_/________\,!0````````(````8````_/__ +XM______\3!0````````(````$````*``````````D!0````````(````$```` +XM$`````````!!!0````````(````9````_/________]'!0````````(````8 +XM````_/________^G!@````````(````>````_/________^S!@````````(` +XM```$````&P````````#&!@````````(````@````_/_________-!@`````` +XM``H````(````,@````````#7!@````````(````A````_/_________=!@`` +XM``````(````?````_/________\:!P````````(````$````*``````````H +XM!P````````(````$````)`````````!$!P````````H````(````$P`````` +XM``!+!P````````(````@````_/________]5!P````````(````A````_/__ +XM______]````_/_________0!P````````H````) +XM````,`````````# +XM"0````````(````>````_/________\""@````````(````@````_/______ +XM__\'"@````````H````)````J``````````4"@````````(````A````_/__ +XM______\:"@````````(````8````^_________\G"@````````(````$```` +XM"``````````K"@````````L````(````,0`````````Q"@````````(````? +XM````^/________]2"@````````(````9````_/________]?"@````````(` +XM```8````_/________]W"@````````(````>````_/________^)"@`````` +XM``(````@````_/________^."@````````H````)````8`````````"="@`` +XM``````(````A````_/________^D"@````````(````$````#`````````"L +XM"@````````(````=````_/_________`"@````````(````$````#``````` +XM``#)"@````````(````?````_/_________F"@````````(````@````_/__ +XM_______K"@````````H````)``````````````#]"@````````(````A```` +XM_/________\$"P````````(````$````#``````````5"P````````(````@ +XM````_/________\="P````````H````)````B``````````G"P````````(` +XM```A````_/________\X"P````````(````9````_/________]#"P`````` +XM``(````8````_/________]@"P````````(````9````_/________]I"P`` +XM``````(````8````_/________\1#`````````(````8````^_________\9 +XM#`````````(````9````_/________\B#`````````(````$````"``````` +XM``!$#`````````(````9````_/________]-#`````````(````8````_/__ +XM______]F#`````````(````>````_/________]U#`````````(````$```` +XM#`````````!]#`````````(````=````_/________^##`````````(````8 +XM````^_________^4#`````````(````$````#`````````"@#`````````(` +XM```9````^/________^P#`````````(````>````_/_________!#``````` +XM``(````@````_/_________(#`````````H````)````R`````````#2#``` +XM``````(````A````_/_________8#`````````(````?````_/________\+ +XM#0````````(````$````"``````````:#0````````(````>````_/______ +XM__\J#0````````(````@````_/________\Q#0````````H````)````R``` +XM```````[#0````````(````A````_/________](#0````````(````?```` +XM_/________]>#0````````(````8````_/________]H#0````````H````) +XM````\`````````!O#0````````(````@````_/________]]#0````````(` +XM```A````_/________^;#0````````(````>````_/________^M#0`````` +XM``H````)````&`$```````"T#0````````(````@````_/________^^#0`` +XM``````(````A````_/_________%#0````````(````$````#`````````#- +XM#0````````(````=````_/_________=#0````````(````$````#``````` +XM``#M#0````````(````9````_/_________U#0````````(````=````_/__ +XM______\%#@````````(````$````#``````````U#@````````(````8```` +XM_/________].#@````````(````9````_/________]7#@````````(````8 +XM````_/________]H#@````````(````>````_/________][#@````````(` +XM```@````_/________^`#@````````H````)````8`````````"/#@`````` +XM``(````A````_/________^6#@````````(````$````#`````````">#@`` +XM``````(````=````_/________^I#@````````(````$````#`````````#) +XM#@````````(````7````_/________\&``````````H````%```````````` +XM```,``````````H````5````&P$````````1``````````H````5````@0`` +XM```````5``````````$````"```````````````=``````````$````"```` +XMS0X````````E``````````H````'```````````````L``````````H````5 +XM````Q`$````````S``````````H````5````CP$````````Z``````````H` +XM```5````3P````````!!``````````H````5````$`(```````!/```````` +XM``H````5````ZP$```````!4``````````H````5````1`$```````!A```` +XM``````H````5````.P$```````!H``````````H````5````B`(```````!O +XM``````````H````5````F@(```````!V``````````H````5````_P`````` +XM``"```````````H````5````H0(```````"3``````````H````5````?0(` +XM``````">``````````H````5````X0$```````"\``````````H````5```` +XM0P(```````#!``````````H````5````%@````````#,``````````H````5 +XM````90(```````#7``````````H````5````-0````````#C``````````H` +XM```5````-`(```````#Q``````````H````5````'`,````````&`0`````` +XM``H````5````(@,````````Z`0````````H````5````80````````!(`0`` +XM``````H````5````X@(```````!D`0````````H````5````.@(```````!R +XM`0````````H````5````+`(```````"``0````````H````5````?@$````` +XM``".`0````````H````5````L`$```````"<`0````````H````5````U0(` +XM``````"J`0````````H````5````:`````````#B`0````````H````5```` +XM%@,```````#P`0````````H````5````P@`````````,`@````````H````5 +XM````8P$````````;`@````````H````5````60`````````J`@````````H` +XM```5````/``````````Y`@````````H````5````(@````````!(`@`````` +XM``H````5````]0````````!7`@````````H````5````"0,```````!F`@`` +XM``````H````5````!0$````````=`P````````H````5````QP(````````I +XM`P````````H````5````;P`````````U`P````````H````5````!`,````` +XM``!``P````````H````5````T`````````!,`P````````H````5````B@$` +XM``````!:`P````````H````5````$P$```````!H`P````````H````5```` +XM^`(```````"3`P````````H````5````YP````````"9`P````````H````5 +XM````#@````````"?`P````````H````5````50(```````"F`P````````H` +XM```5````O@(```````#.`P````````H````5````G0$```````#@`P`````` +XM``H````5````M@$```````#L`P````````H````5````A0$```````#X`P`` +XM``````H````5````^`$````````0!`````````H````5````1@`````````> +XM!`````````H````5````A0$````````J!`````````H````5````X``````` +XM```V!`````````H````5````;`(```````"6!`````````H````5````T`$` +XM``````"B!`````````$````"``````````````"J!`````````$````"```` +XML@X```````"R!`````````H````1``````````````"[!`````````H````5 +XM````M@$```````#&!`````````H````1````L0````````#+!`````````H` +XM```5````A0$```````#6!`````````H````1````Z0````````#;!``````` +XM``H````5````^`$```````#F!`````````H````1````(0$```````#K!``` +XM``````H````5````(P(```````#V!`````````H````1````<0(```````#[ +XM!`````````H````5````R``````````&!0````````H````1````J0(````` +XM```+!0````````H````5````!0````````H````1````S@@```````#I!0````````H````4```` +XMD`(```````#N!0````````H````5````M@(```````#Y!0````````H````1 +XM````*@D````````'!@````````H````1````OPD````````,!@````````H` +XM```5````VP(````````7!@````````H````1````00H````````!@````````H````4``````,` +XM``````!N!@````````H````1````=`P```````!Y!@````````H````4```` +XM0`,```````""!@````````H````5````M@(```````"-!@````````H````1 +XM````+PT```````";!@````````H````1````]`X```````"@!@````````H` +XM```5````VP(```````"K!@````````H````1````KP\```````"P!@`````` +XM``H````5````O`````````"\!@````````H````5````;`$```````#'!@`` +XM``````H````1````?!````````#,!@````````H````5````NP$```````#7 +XM!@````````H````1````21$```````#!P````````$````$````$`````````#G!P`````` +XM``H````5````+`````````#S!P````````$````$````&`````````#\!P`` +XM``````H````5````Z`(````````("`````````$````$````(``````````1 +XM"`````````H````5````2`(````````="`````````$````$````*``````` +XM```F"`````````H````5````<@$````````R"`````````$````$````+``` +XM```````["`````````H````5````=P````````!."`````````H````5```` +XM!P````````!;"`````````$````9``````````````!D"`````````H````5 +XM``````````````!Q"`````````$````8``````````````!Z"`````````H` +XM```5`````@(```````"'"`````````$````>``````````````"0"``````` +XM``H````5````_0(```````"="`````````$````?``````````````"F"``` +XM``````H````5````3@$```````"S"`````````$````:``````````````"] +XM``````````$````"```````````````<``````````H````/```````````` +XM```@``````````$````"``````````````!<``````````H````/```````` +XM``````!@``````````$````"````P`X````````@``````````H````"```` +XM``````````!8``````````H````"````P`X````````&``````````H````& +XM```````````````&``````````H````&```````````````0``````````$` +X.```"```````````````` +X` +Xend +e91f2be53ccef7c31a70c80e46567ff3 +echo x - ./electric.o.uu +sed 's/^X//' >./electric.o.uu << '4c9616b2b1efe66bd65b3a3736cfd629' +Xbegin 644 ./electric.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````.`````` +XM`````````$```````$``"P`(```6`````@`0`````0'[#@H``0$!`0````$` +XM``!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6UT +XM86(`+G-T'0`+F1A=&$`+F)S`0````````,```` +XM`````````````````0`````````````````````````````````````````` +XM``````````$````$`/'_```````````````````````````#``$````````` +XM```````````````````#``(````````````````````````````#``,````` +XM```````````````````````#``0````````````````````````````#``4` +XM```````````````````````````#``8````````````````````````````# +X?``<```````````````````````!E;&5C=')I8RYC```` +X` +Xend +4c9616b2b1efe66bd65b3a3736cfd629 +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.err b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.eval b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.sh b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.sh new file mode 100755 index 0000000000..b30acd40c3 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/arscript-4.sh @@ -0,0 +1,6 @@ +# $Id: arscript-4.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest arscript-4 tc/arscript-4 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} -M < liba.script.bsd" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/in/arscript-4.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/in/arscript-4.in.shar new file mode 100644 index 0000000000..4abff32011 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/arscript-4/in/arscript-4.in.shar @@ -0,0 +1,123 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./liba.script.gnu.uu +# ./liba.script.bsd.uu +# ./liba.a.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./liba.script.gnu.uu +sed 's/^X//' >./liba.script.gnu.uu << 'ab91cf74d50fd10bcd49f7bc6f94d47a' +Xbegin 644 ./liba.script.gnu +XM9&ER96-T;W)Y(&QI8F$N80IO<&5N(&QI8F$N80ID:7)E8W1O2!L:6)A+F$@*&$T+F\@83(N;RD@ +XA;W5T<'5T+F1A=`IE>'1R86-T(&$S+F\@830N;PIE;F0* +X` +Xend +ab91cf74d50fd10bcd49f7bc6f94d47a +echo x - ./liba.script.bsd.uu +sed 's/^X//' >./liba.script.bsd.uu << '4ca6d98e1563a067085e73394a418d6c' +Xbegin 644 ./liba.script.bsd +XM9&ER96-T;W)Y(&QI8F$N80IO<&5N(&QI8F$N80ID:7)E8W1O2!L:6)A+F$@*&$R+F\@830N;RD@ +XA;W5T<'5T+F1A=`IE>'1R86-T(&$S+F\@830N;PIE;F0* +X` +Xend +4ca6d98e1563a067085e73394a418d6c +echo x - ./liba.a.uu +sed 's/^X//' >./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M /dev/null 2>&1 +echo x - ./liba.script.gnu.uu +sed 's/^X//' >./liba.script.gnu.uu << 'ab91cf74d50fd10bcd49f7bc6f94d47a' +Xbegin 644 ./liba.script.gnu +XM;W!E;B!L:6)A+F$*97AT./liba.script.bsd.uu << '4ca6d98e1563a067085e73394a418d6c' +Xbegin 644 ./liba.script.bsd +XM;W!E;B!L:6)A+F$*97AT./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M /dev/null 2>&1 +echo x - ./liblong.a.uu +sed 's/^X//' >./liblong.a.uu << '1413ebc840040523373ed6a077bf0d85' +Xbegin 644 ./liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71M./liba.script.gnu.uu << 'ab91cf74d50fd10bcd49f7bc6f94d47a' +Xbegin 644 ./liba.script.gnu +XM;W!E;B!L:6)L;VYG+F$*861D;&EB(&QI8F$N82`H83$N;R!A,BYO(&$S+F\@ +XM830N;RD*./liba.script.bsd.uu << '4ca6d98e1563a067085e73394a418d6c' +Xbegin 644 ./liba.script.bsd +XM;W!E;B!L:6)A+F$*861D;&EB(&QI8FQO;F./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M /dev/null 2>&1 +echo x - ./liblong.a.uu +sed 's/^X//' >./liblong.a.uu << '1413ebc840040523373ed6a077bf0d85' +Xbegin 644 ./liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71M./liba.script.gnu.uu << 'ab91cf74d50fd10bcd49f7bc6f94d47a' +Xbegin 644 ./liba.script.gnu +XM;W!E;B!L:6)L;VYG+F$*861D;&EB(&QI8F$N82`H83$N;R!A,BYO(&$S+F\@ +XM830N;RD*./liba.script.bsd.uu << '4ca6d98e1563a067085e73394a418d6c' +Xbegin 644 ./liba.script.bsd +XM;W!E;B!L:6)A+F$*861D;&EB(&QI8FQO;F./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M /dev/null 2>&1 +echo x - ./liblong.a.uu +sed 's/^X//' >./liblong.a.uu << '1413ebc840040523373ed6a077bf0d85' +Xbegin 644 ./liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71M./liba.script.gnu.uu << 'ab91cf74d50fd10bcd49f7bc6f94d47a' +Xbegin 644 ./liba.script.gnu +XM;W!E;B!L:6)A+F$*861D;&EB(&QI8FQO;F./liba.script.bsd.uu << '4ca6d98e1563a067085e73394a418d6c' +Xbegin 644 ./liba.script.bsd +XF;W!E;B!L:6)L;VYG+F$*861D;&EB(&QI8F$N80IS879E"F5N9`H` +X` +Xend +4ca6d98e1563a067085e73394a418d6c +echo x - ./liba.a.uu +sed 's/^X//' >./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA0``83$N;R\@("`@ +XM("`@("`@(#$Q.30U,#DS-#D@(#$P,#$@(#`@("`@(#$P,#8T-"`@-S$R("`@ +XM("`@(&`*?T5,1@$!`0D```````````$``P`!``````````````#````````` +XM`#0``````"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@! +XMPJ$`````#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A +XM=&$`+F)S6#[`C'1"0$```` +XM`,<$)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T +XM6UT86(`+G-T````!4````````` +XM``````$`````````.`````$``````````````(T````F```````````````! +XM`````````!$````#``````````````"S````00```````````````0`````` +XM```!`````@``````````````A`(``+`````)````!P````0````0````"0`` +XM``,``````````````#0#```A```````````````!```````````````````` +XM```````````!```````````````$`/'_`````````````````P`!```````` +XM``````````,``P`````````````````#``0``````````````````P`%```` +XM``````````````,`!@`&``````````D````1``,`"P````D````)````$0`# +XM`!``````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M +XM`!Y``4````!!P``#P`` +X5``$(```9`````0<``"<````!"``` +X` +Xend +a786d1a9b733e5206b0b9bedb49c8298 +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.err b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.eval b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.sh b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.sh new file mode 100644 index 0000000000..5cfb67e281 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/bsd-archive-liba32.sh @@ -0,0 +1,10 @@ +# $Id: bsd-archive-liba32.sh 2078 2011-10-27 04:04:27Z jkoshy $ +if ! uname -m | grep -q 64; then + inittest bsd-archive-liba32 tc/bsd-archive-liba32 + extshar ${TESTDIR} + extshar ${RLTDIR} + runcmd "${AR} cru --flavor bsd liba.a a1.o a2.o a3.o a4.o" work true + rundiff false + runcmd "plugin/teraser -c -t bsd-archive-liba32 liba.a" work false + runcmd "plugin/ardiff -cnlt bsd-archive-liba32 ${RLTDIR}/liba.a liba.a" work false +fi diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/in/bsd-archive-liba32.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/in/bsd-archive-liba32.in.shar new file mode 100644 index 0000000000..6ac4bef2f8 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-liba32/in/bsd-archive-liba32.in.shar @@ -0,0 +1,114 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./a4.o.uu +# ./a3.o.uu +# ./a2.o.uu +# ./a1.o.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./a4.o.uu +sed 's/^X//' >./a4.o.uu << 'deb5d4d127ac38de8c0d1ea9ac8c5730' +Xbegin 644 ./a4.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71M./a3.o.uu << '3fff05c17767873ca1d611a677ec9310' +Xbegin 644 ./a3.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +3fff05c17767873ca1d611a677ec9310 +echo x - ./a2.o.uu +sed 's/^X//' >./a2.o.uu << '231e338f0580059987136ed236efeb57' +Xbegin 644 ./a2.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)S./a1.o.uu << '56a3926c746858fb21a06cfcde8816f4' +Xbegin 644 ./a1.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XM /dev/null 2>&1 +echo x - ./ne4_very_very_very_long.uu +sed 's/^X//' >./ne4_very_very_very_long.uu << '38e9cb51d72527a87fe0e0e66470b9e5' +Xbegin 644 ./ne4_very_very_very_long +XM1T='1T='1T='1T='2$A(2$A(2$A(2$A(2$A(2$A("DI*2DI*2DI*2DI*2DI* +X12DI*2DI*2DI*2DI*2DI*2@H` +X` +Xend +38e9cb51d72527a87fe0e0e66470b9e5 +echo x - ./ne3_long_name_16.uu +sed 's/^X//' >./ne3_long_name_16.uu << 'b1fdd644021ba83d965d875119c22965' +Xbegin 644 ./ne3_long_name_16 +X)145%149&1D8* +X` +Xend +b1fdd644021ba83d965d875119c22965 +echo x - ./ne2_long_name15.uu +sed 's/^X//' >./ne2_long_name15.uu << '6b25863a7f0f9097fe6d88ce7adbcd9b' +Xbegin 644 ./ne2_long_name15 +X)0T-#0T1$1$0* +X` +Xend +6b25863a7f0f9097fe6d88ce7adbcd9b +echo x - ./ne1.uu +sed 's/^X//' >./ne1.uu << '27d76f04a0fca7543fae879698386b4c' +Xbegin 644 ./ne1 +X-04%!04%!0D)"0D)""@`` +X` +Xend +27d76f04a0fca7543fae879698386b4c +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.err b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.eval b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.sh b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.sh new file mode 100755 index 0000000000..a5eefce424 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/bsd-archive-libnonelf.sh @@ -0,0 +1,8 @@ +# $Id: bsd-archive-libnonelf.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest bsd-archive-libnonelf tc/bsd-archive-libnonelf +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} cruF bsd libnonelf.a ne1 ne2 ne3 ne4" work true +rundiff false +runcmd "plugin/teraser -c -t bsd-archive-libnonelf libnonelf.a" work false +runcmd "plugin/ardiff -cnlt bsd-archive-libnonelf ${RLTDIR}/libnonelf.a libnonelf.a" work false diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/in/bsd-archive-libnonelf.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/in/bsd-archive-libnonelf.in.shar new file mode 100644 index 0000000000..4208fdcc82 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-archive-libnonelf/in/bsd-archive-libnonelf.in.shar @@ -0,0 +1,46 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./ne4.uu +# ./ne3.uu +# ./ne2.uu +# ./ne1.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./ne4.uu +sed 's/^X//' >./ne4.uu << '44ca5310aca07067daa8d5304194531f' +Xbegin 644 ./ne4 +XM1T='1T='1T='1T='2$A(2$A(2$A(2$A(2$A(2$A("DI*2DI*2DI*2DI*2DI* +X12DI*2DI*2DI*2DI*2DI*2@H` +X` +Xend +44ca5310aca07067daa8d5304194531f +echo x - ./ne3.uu +sed 's/^X//' >./ne3.uu << 'b840d8f043d79804f9edcd5a741a9f42' +Xbegin 644 ./ne3 +X)145%149&1D8* +X` +Xend +b840d8f043d79804f9edcd5a741a9f42 +echo x - ./ne2.uu +sed 's/^X//' >./ne2.uu << 'c343785f5b3ea9d2019b9db76eafd76c' +Xbegin 644 ./ne2 +X)0T-#0T1$1$0* +X` +Xend +c343785f5b3ea9d2019b9db76eafd76c +echo x - ./ne1.uu +sed 's/^X//' >./ne1.uu << '27d76f04a0fca7543fae879698386b4c' +Xbegin 644 ./ne1 +X-04%!04%!0D)"0D)""@`` +X` +Xend +27d76f04a0fca7543fae879698386b4c +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.err b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.eval b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.sh b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.sh new file mode 100644 index 0000000000..394e605925 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/bsd-extract-liba32-v.sh @@ -0,0 +1,6 @@ +# $Id: bsd-extract-liba32-v.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest bsd-extract-liba32-v tc/bsd-extract-liba32-v +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} xv liba.a" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/in/bsd-extract-liba32-v.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/in/bsd-extract-liba32-v.in.shar new file mode 100644 index 0000000000..29c477594b --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liba32-v/in/bsd-extract-liba32-v.in.shar @@ -0,0 +1,102 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./liba.a.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./liba.a.uu +sed 's/^X//' >./liba.a.uu << 'a786d1a9b733e5206b0b9bedb49c8298' +Xbegin 644 ./liba.a +XM(3QA'0`+F1A=&$`+F)S7'!0`````!````QP4``````@```(L5 +XM`````(M%"(G!*=&)RJ$`````B=$IP8G(7<,``$=#0SH@*$=.52D@-"XR+C$@ +XM,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S0`%`````0<```\````!"```&0````$'```G```` +XM`0@``&$T+F\@("`@("`@("`@("`Q,CDS,C$Q,SDU("`Q,#`Q("`P("`@("`Q +XM,#`V-#0@(#@X."`@("`@("!@"G]%3$8!`0$)```````````!``,``0`````` +XM````````]``````````T```````H``H`!P````````````````!5B>6#[!C' +XM1"0(`````,=$)`0`````QP0D`````.C\____R<-M97-S86=E,0!M97-S86=E +XM,@```&US9S$@/2`E6UT86(`+G-T +X'`````@H````` +X` +Xend +a786d1a9b733e5206b0b9bedb49c8298 +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.err b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.eval b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.sh b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.sh new file mode 100644 index 0000000000..2587447a90 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/bsd-extract-liblong-v.sh @@ -0,0 +1,6 @@ +# $Id: bsd-extract-liblong-v.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest bsd-extract-liblong-v tc/bsd-extract-liblong-v +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} xv liblong.a" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/in/bsd-extract-liblong-v.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/in/bsd-extract-liblong-v.in.shar new file mode 100644 index 0000000000..ff4665b1f9 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/bsd-extract-liblong-v/in/bsd-extract-liblong-v.in.shar @@ -0,0 +1,29 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# . +# ./liblong.a.uu +# +echo c - . +mkdir -p . > /dev/null 2>&1 +echo x - ./liblong.a.uu +sed 's/^X//' >./liblong.a.uu << '1413ebc840040523373ed6a077bf0d85' +Xbegin 644 ./liblong.a +XM(3QA5]V97)Y7VQO;F='1T='1T='1T=' +XM1T=(2$A(2$A(2$A(2$A(2$A(2$@*2DI*2DI*2DI*2DI*2DI*2DI*2DI*2DI* +X(2DI*2DI*"@H` +X` +Xend +1413ebc840040523373ed6a077bf0d85 +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.err b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.eval b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.sh b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.sh new file mode 100644 index 0000000000..50208d665b --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/compbase-liba-v.sh @@ -0,0 +1,8 @@ +# $Id: compbase-liba-v.sh 2078 2011-10-27 04:04:27Z jkoshy $ +inittest compbase-liba-v tc/compbase-liba-v +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} mv liba.a ./a1.o" work true +runcmd "plugin/teraser -ce -t compbase-liba-v liba.a" work false +runcmd "plugin/teraser -e liba.a" result false +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/in/compbase-liba-v.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/in/compbase-liba-v.in.shar new file mode 100644 index 0000000000..eacc1e4b96 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/compbase-liba-v/in/compbase-liba-v.in.shar @@ -0,0 +1,98 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# liba.a.uu +# +echo x - liba.a.uu +sed 's/^X//' >liba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliblong.a.uu << 'END-of-liblong.a.uu' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliblong.a.uu << 'END-of-liblong.a.uu' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mlibnonelf.a.uu << 'END-of-libnonelf.a.uu' +Xbegin 644 libnonelf.a +XM(3QA. +# Source directory was '/home/jkoshy/Work/Elftoolchain/trunk/test/ar/tc/extract-nonexistent/in'. +# +# Existing files will *not* be overwritten, unless '-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 80 -rw-rw-r-- valid.a +# +if test "X$1" = "X-c" +then keep_file='' +else keep_file=true +fi +echo=echo +shar_tty= +shar_n= +shar_c='\n' +if test ! -d ${lock_dir} ; then : +else ${echo} "lock directory ${lock_dir} exists" + exit 1 +fi +if mkdir ${lock_dir} ; then : +else ${echo} "failed to create ${lock_dir} lock directory" + exit 1 +fi +# ============= valid.a ============== +if test -n "${keep_file}" && test -f 'valid.a' +then +${echo} "x - SKIPPING valid.a (file already exists)" + +else +${echo} "x - extracting valid.a (text)" + sed 's/^X//' << 'SHAR_EOF' > 'valid.a' && +X! +Xs1/ 0 0 0 644 12 ` +Xs1-contents +SHAR_EOF +: +if test $? -ne 0 +then ${echo} "restore of valid.a failed" +fi +fi +if rm -fr ${lock_dir} +then ${echo} "x - removed lock directory ${lock_dir}." +else ${echo} "x - failed to remove lock directory ${lock_dir}." + exit 1 +fi +exit 0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.err b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.err new file mode 100644 index 0000000000..4d22e623f4 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.err @@ -0,0 +1 @@ +ar: warning: ignoring entry: a/s1 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.eval b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.sh b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.sh new file mode 100644 index 0000000000..671833867f --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/extract-nonleaf.sh @@ -0,0 +1,6 @@ +# $Id$ +inittest extract-nonleaf tc/extract-nonleaf +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} xv invalid.a" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/in/invalid.shar b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/in/invalid.shar new file mode 100644 index 0000000000..7e718a8192 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/extract-nonleaf/in/invalid.shar @@ -0,0 +1,54 @@ +#!/bin/sh +# This is invalid, a shell archive (produced by GNU sharutils 4.15.2). +# To extract the files from this archive, save it to some FILE, remove +# everything before the '#!/bin/sh' line above, then type 'sh FILE'. +# +lock_dir=_sh29263 +# Existing files will *not* be overwritten, unless '-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 152 -rw-rw-r-- invalid.a +# +if test "X$1" = "X-c" +then keep_file='' +else keep_file=true +fi +echo=echo +shar_tty= +shar_n= +shar_c='\n' +if test ! -d ${lock_dir} ; then : +else ${echo} "lock directory ${lock_dir} exists" + exit 1 +fi +if mkdir ${lock_dir} ; then : +else ${echo} "failed to create ${lock_dir} lock directory" + exit 1 +fi +# ============= invalid.a ============== +if test -n "${keep_file}" && test -f 'invalid.a' +then +${echo} "x - SKIPPING invalid.a (file already exists)" + +else +${echo} "x - extracting invalid.a (text)" + sed 's/^X//' << 'SHAR_EOF' > 'invalid.a' && +X! +Xa/s1/ 0 0 0 644 12 ` +Xs1-contents +Xs1/ 0 0 0 644 12 ` +Xs1-contents +SHAR_EOF +: +if test $? -ne 0 +then ${echo} "restore of invalid.a failed" +fi +fi +if rm -fr ${lock_dir} +then ${echo} "x - removed lock directory ${lock_dir}." +else ${echo} "x - failed to remove lock directory ${lock_dir}." + exit 1 +fi +exit 0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/list-lib65536/in/list-lib65536.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/list-lib65536/in/list-lib65536.in.shar new file mode 100644 index 0000000000..2ca6013861 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/list-lib65536/in/list-lib65536.in.shar @@ -0,0 +1,2669 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# lib65536.a.uu +# +echo x - lib65536.a.uu +sed 's/^X//' >lib65536.a.uu << 'END-of-lib65536.a.uu' +Xbegin 644 lib65536.a +XM(3QAliblong.a.uu << 'END-of-liblong.a.uu' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71MlibaS.a.uu << 'END-of-libaS.a.uu' +Xbegin 644 libaS.a +XM(3QA'0`+F1A +XM=&$`+F)S7' +XM!0`````!````QP4``````@```(L5`````(M%"(G!*=&)RJ$`````B=$IP8G( +XM7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S0`%`````0<` +XM``\````!"```&0````$'```G`````0@``&$T+F\O("`@("`@("`@("`Q,C`Q +XM.3$Y,#$P("`Q,#`Q("`P("`@("`Q,#`V-#0@(#@X."`@("`@("!@"G]%3$8! +XM`0$)```````````!``,``0``````````````]``````````T```````H``H` +XM!P````````````````!5B>6#[!C'1"0(`````,=$)`0`````QP0D`````.C\ +XM____R<-M97-S86=E,0!M97-S86=E,@```&US9S$@/2`E6UT +XM86(`+G-T`````@H````` +X` +Xend +END-of-libaS.a.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.err b/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.eval b/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.sh b/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.sh new file mode 100644 index 0000000000..d66e76ac7f --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/list_s-libaS/list_s-libaS.sh @@ -0,0 +1,8 @@ +# $Id: list_s-libaS.sh 2079 2011-10-27 04:10:55Z jkoshy $ +inittest list_s-libaS tc/list_s-libaS +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${AR} ts libaS.a" work true +runcmd "plugin/teraser -ce -t list_s-libaS libaS.a" work false +runcmd "plugin/teraser -e libaS.a" result false +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/moveafter-liba-v/in/moveafter-liba-v.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/moveafter-liba-v/in/moveafter-liba-v.in.shar new file mode 100644 index 0000000000..eacc1e4b96 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/moveafter-liba-v/in/moveafter-liba-v.in.shar @@ -0,0 +1,98 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# liba.a.uu +# +echo x - liba.a.uu +sed 's/^X//' >liba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mliba.a.uu << 'END-of-liba.a.uu' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1.o.uu << 'END-of-a1.o.uu' +Xbegin 644 a1.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2.o.uu << 'END-of-a2.o.uu' +Xbegin 644 a2.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)Sa3.o.uu << 'END-of-a3.o.uu' +Xbegin 644 a3.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +END-of-a3.o.uu +echo x - a4.o.uu +sed 's/^X//' >a4.o.uu << 'END-of-a4.o.uu' +Xbegin 644 a4.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mliblong.a.uu << 'END-of-liblong.a.uu' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Mliblong.a.uu << 'END-of-liblong.a.uu' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Mlibmix.a.uu << 'END-of-libmix.a.uu' +Xbegin 644 libmix.a +XM(3QA'0` +XM+F1A=&$`+F)S'0`+F1A=&$` +XM+F)S`````````````````````0`````````,``` +XM``$````"`````````'@````5```````````````!`````````#@````!```` +XM``````````"-````)@```````````````0`````````1`````P`````````` +XM````LP```$$```````````````$``````````0````(``````````````(0" +XM``"P````"0````<````$````$`````D````#```````````````T`P``(0`` +XM`````````````0```````````````````````````````0`````````````` +XM!`#Q_P````````````````,``0`````````````````#``,````````````` +XM`````P`$``````````````````,`!0`````````````````#``8`!@`````` +XM```)````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`` +XM````````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Ma1.o.uu << 'END-of-a1.o.uu' +Xbegin 644 a1.o +XM?T5,1@$!`0D```````````$``P`!``````````````#``````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````4```"+10R+50@!PJ$````` +XM#Z_"7<,``$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M&'0`+F1A=&$`+F)S +XMa2.o.uu << 'END-of-a2.o.uu' +Xbegin 644 a2.o +XM?T5,1@$!`0D```````````$``P`!``````````````#<`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L",=$)`0`````QP0D`````.C\____ +XMR<-H96QL;RP@=V]R;&0`````;7-G.B`E'0`+F1A=&$`+F)Sa3.o.uu << 'END-of-a3.o.uu' +Xbegin 644 a3.o +XM?T5,1@$!`0D```````````$``P`!``````````````#4`````````#0````` +XM`"@`"0`&`````````````````%6)Y<<%``````$```#'!0`````"````BQ4` +XM````BT4(B<$IT8G*H0````")T2G!B`!Y``4````!!P``#P````$(```9`````0<``"<````! +X#"``` +X` +Xend +END-of-a3.o.uu +echo x - a4.o.uu +sed 's/^X//' >a4.o.uu << 'END-of-a4.o.uu' +Xbegin 644 a4.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&,=$)`@`````QT0D!`````#'!"0` +XM````Z/S____)PVUE'0`+F1A=&$`+F)S +XM`````````````````````0`````````,`````$` +XM```"`````````'@````5```````````````!`````````#@````!```````` +XM``````"-````)@```````````````0`````````1`````P`````````````` +XMLP```$$```````````````$``````````0````(``````````````(0"``"P +XM````"0````<````$````$`````D````#```````````````T`P``(0`````` +XM`````````0```````````````````````````````0``````````````!`#Q +XM_P````````````````,``0`````````````````#``,````````````````` +XM`P`$``````````````````,`!0`````````````````#``8`!@`````````) +XM````$0`#``L````)````"0```!$``P`0`````````"0````2``$`&@`````` +XM````````$`````!A-"YC`&US9S$`;7-G,@!O=71P=71Msbrk.o.uu << 'END-of-sbrk.o.uu' +Xbegin 644 sbrk.o +XM?T5,1@$!`0D```````````$``P`!``````````````#T`````````#0````` +XM`"@`"@`'`(M,)`2A`````(7)=!@!1"0$N!$```#-@'(,H0`````!#0````## +XMZ?S___\`````````````)$9R965"4T0Z('-R8R]L:6(O;&EB8R]I,S@V+W-Y +XM7,O [options] archive file... + Manage archives. + + Where is one of: + -d Delete members from the archive. + -m Move archive members within the archive. + -p Write the contents of members to standard output. + -q Append files to an archive. + -r Replace (add) files to an archive. + -s Add an archive symbol to an archive. + -t List files in an archive. + -x Extract members from an archive. + -M Execute MRI librarian commands. + -V Print a version identifier and exit. + + Options: + -a MEMBER Add members after the specified member. + -b MEMBER | -i MEMBER + Add members before the specified member. + -c Do not print a message when creating a new archive. + -f | -T Only use the first fifteen characters of the member name. + -j (This option is accepted, but is ignored). + -l (This option is accepted, but is ignored). + -o Preserve modification times when extracting members. + -u Conditionally update or extract members. + -v Be verbose. + -z (This option is accepted, but is ignored). + -C Do not overwrite existing files in the file system. + -D Use fixed metadata, for consistent archive checksums. + -F FORMAT | --flavor=FORMAT + Create archives with the specified format. + -S Do not generate an archive symbol table. + -U Use original metadata for archive members. diff --git a/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.eval b/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.eval new file mode 100644 index 0000000000..900731ffd5 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.eval @@ -0,0 +1 @@ +64 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.sh b/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.sh new file mode 100644 index 0000000000..1975dcd167 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/usage-bi/usage-bi.sh @@ -0,0 +1,4 @@ +# $Id: usage-bi.sh 2079 2011-10-27 04:10:55Z jkoshy $ +inittest usage-bi tc/usage-bi +runcmd "${AR} bi bar.o foo.a bar2.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.err b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.err new file mode 100644 index 0000000000..fe88f76c99 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.err @@ -0,0 +1 @@ +ar: fatal: Can't specify both -x and -t diff --git a/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.eval b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.eval new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.eval @@ -0,0 +1 @@ +1 diff --git a/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.sh b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.sh new file mode 100644 index 0000000000..01cf28141d --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/usage-tx/usage-tx.sh @@ -0,0 +1,4 @@ +# $Id: usage-tx.sh 2079 2011-10-27 04:10:55Z jkoshy $ +inittest usage-tx tc/usage-tx +runcmd "${AR} tx foo.a" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/ar/tc/weaksymbol-libweak/in/weaksymbol-libweak.in.shar b/contrib/elftoolchain/tests/custom/ar/tc/weaksymbol-libweak/in/weaksymbol-libweak.in.shar new file mode 100644 index 0000000000..ec75b775c7 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/ar/tc/weaksymbol-libweak/in/weaksymbol-libweak.in.shar @@ -0,0 +1,40 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# quotactl.o.uu +# +echo x - quotactl.o.uu +sed 's/^X//' >quotactl.o.uu << 'END-of-quotactl.o.uu' +Xbegin 644 quotactl.o +XM?T5,1@$!`0D```````````$``P`!``````````````!X`````````#0````` +XM`"@`"``%`.G\____C78`N)0```#-@'+OPP```"YS>6UT86(`+G-T7,O8V1E9G,N:``O=7-R+V]B +XM:B]U7,O ${OPATH}/${1}/$TC.${1}.shar + elif [ "${USE_UUENCODE}" = yes ]; then + cp -R ${WORKDIR}.uu.${1}/* ${OPATH}/${1} + else + cp -R ${WORKDIR}/* ${OPATH}/${1} + fi + fi +} + +THISDIR=`/bin/pwd` + +# Check the command line options. +# +while getopts "nsui:o:c:g:" COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + n) + NODIFFRLT=yes; + ;; + s) + USE_SHAR=yes; + USE_UUENCODE=yes; + ;; + u) + USE_UUENCODE=yes; + ;; + i) + IPATH=${OPTARG} + ;; + o) + OPATH=${OPTARG} + ;; + g) + GCMD=${OPTARG} + ;; + c) + RCMD=${OPTARG} + ;; + *) + usage + exit 1 + ;; + esac +done + +if [ $# -ne $OPTIND ]; then + usage + exit 1 +fi +eval TC=$"{${OPTIND}}" + +if [ -z "${OPATH}" ]; then + OPATH=${TC}; +fi +mkdir -p ${OPATH} || exit 1 + +if [ -z "${RCMD}" ]; then + RCMD=":" +fi + +if [ -z "${GCMD}" ]; then + GCMD=${RCMD} +fi + +# Convert to absolute pathnames. +# +if [ -n "${IPATH}" ]; then + IPATH=`cd ${IPATH} 2>/dev/null && /bin/pwd \ + || echo "can't locate ${IPATH}" && exit 1` +fi + +ROPATH=${OPATH} # backup relative opath for later use. +OPATH=`cd ${OPATH} 2>/dev/null && /bin/pwd \ + || echo "can't locate ${OPATH}" && exit 1` + +# Prefix $GCMD with absolute pathnames. +# +executable=`echo ${GCMD} | cut -f 1 -d ' '` +relapath=`dirname ${executable}` +cd ${THISDIR} +absolpath=`cd ${relapath} && /bin/pwd` +GCMD=${absolpath}/`basename ${executable}`" "`echo ${GCMD} | cut -f 2- -d ' '` + +# Set up temporary directories. +# +WORKDIR=/tmp/bsdar-tcgen-work +rm -rf ${WORKDIR} +rm -rf ${WORKDIR}.uu.in +rm -rf ${WORKDIR}.uu.out +mkdir -p ${WORKDIR} || exit 1 +mkdir -p ${WORKDIR}.uu.in || exit 1 # Keep encoded input files +mkdir -p ${WORKDIR}.uu.out || exit 1 # Keep encoded output files + +if [ -n "${IPATH}" ]; then + cp -R ${IPATH}/* ${WORKDIR} 2>/dev/null +fi + +# Keep a record of input state. +# +recstate "in" + +# Execute the cmd, record stdout, stderr and exit value. +# +redirin=`echo ${GCMD} | cut -f 2- -d '<'` +if [ "${redirin}" != "${GCMD}" ]; then + GCMD=`echo ${GCMD} | cut -f 1 -d '<'` + redirin=`echo ${redirin} | sed 's/^ *\(.*\) *$/\1/'` +fi + +cd ${WORKDIR} || exit 1 +if [ "${redirin}" != "${GCMD}" ]; then + ${GCMD} < ${redirin} > ${OPATH}/$TC.out 2> ${OPATH}/$TC.err +else + ${GCMD} > ${OPATH}/$TC.out 2> ${OPATH}/$TC.err +fi +echo $? > ${OPATH}/$TC.eval + +# Keep a record of output state. +# +recstate "out" + +# Generate test script. +# +echo "inittest ${TC} ${ROPATH}" > ${OPATH}/${TC}.sh +if [ "${USE_SHAR}" = yes ]; then + echo 'extshar ${TESTDIR}' >> ${OPATH}/${TC}.sh + echo 'extshar ${RLTDIR}' >> ${OPATH}/${TC}.sh +elif [ "${USE_UUENCODE}" = yes ]; then + echo 'udecode ${TESTDIR}' >> ${OPATH}/${TC}.sh + echo 'udecode ${RLTDIR}' >> ${OPATH}/${TC}.sh +fi +echo "runcmd \"${RCMD}\" work true" >> ${OPATH}/${TC}.sh +if [ "${NODIFFRLT}" = yes ]; then + echo "rundiff false" >> ${OPATH}/${TC}.sh +else + echo "rundiff true" >> ${OPATH}/${TC}.sh +fi + +cd ${THISDIR} || exit 1 +echo "done." diff --git a/contrib/elftoolchain/tests/custom/elfcopy/Makefile b/contrib/elftoolchain/tests/custom/elfcopy/Makefile new file mode 100644 index 0000000000..f88e178fdb --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/Makefile @@ -0,0 +1,21 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. + +ELFCOPY= ${TOP}/elfcopy/elfcopy + +TEST_LOG= test.log + +.MAIN: all + +.PHONY: clobber execute test + +execute test: ${ELFCOPY} + /bin/sh run.sh + +clean clobber: + rm -f ${TEST_LOG} + +SUBDIR= plugin + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/custom/elfcopy/func.sh b/contrib/elftoolchain/tests/custom/elfcopy/func.sh new file mode 100644 index 0000000000..70a984e912 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/func.sh @@ -0,0 +1,210 @@ +# $Id: func.sh 4036 2024-01-17 10:07:08Z jkoshy $ +# +# `init' initializes test engine global data. +# +init() { + THISDIR=`/bin/pwd` + TOPDIR=${THISDIR}/../../.. + ELFCOPY=${TOPDIR}/elfcopy/elfcopy + STRIP=${TOPDIR}/elfcopy/strip + MCS=${TOPDIR}/elfcopy/mcs + + # keep a record of total tests and number of tests passed. + TOTALCT=/tmp/elfcopy-test-total + PASSEDCT=/tmp/elfcopy-test-passed + echo 0 > ${TOTALCT} + echo 0 > ${PASSEDCT} +} + +# `inittest' initializes individual test process. (set up temp dirs, +# make copies of files used in the test if necessary, etc.) +# +inittest() { + if [ $# -ne 2 ]; then + echo "usage: inittest tcname tcdir" + exit 1 + fi + + TC=$1 + TCDIR=$2 + TESTDIR=/tmp/${TC} + OUTDIR=/tmp/${TC}-out + RLTDIR=/tmp/${TC}-rlt + rm -rf ${TESTDIR} + rm -rf ${OUTDIR} + rm -rf ${RLTDIR} + mkdir -p ${TESTDIR} || exit 1 + mkdir -p ${OUTDIR} || exit 1 + mkdir -p ${RLTDIR} || exit 1 + + if [ -d "${TCDIR}/in" ]; then + cp -R ${TCDIR}/in/* ${TESTDIR} || exit 1 + fi + + if [ -d "${TCDIR}/out" ]; then + cp -R ${TCDIR}/out/* ${RLTDIR} || exit 1 + fi +} + +# `extshar' extracts shar file in the specific dir, +# then uudecode the resulting file(s). +# +extshar() { + if [ $# -ne 1 ]; then + echo "usage: extshar dir" + exit 1 + fi + + cd $1 || exit 1 + for f in *.shar; do + sh $f > /dev/null 2>&1 || exit 1 + rm -rf $f + done + + udecode $1 +} + +# `udecode' calls uudecode to decode files encoded by +# uuencode in the specific dir. +# +udecode() { + if [ $# -ne 1 ]; then + echo "usage: uudecode dir" + exit 1 + fi + + cd $1 || exit 1 + for f in *.uu; do + uudecode $f || exit 1 + rm -rf $f + done +} + +# `runcmd' runs `cmd' on the work/result dir. +# +# cmd: command to execute +# loc: work/result +# rec: true (keep a record of the stdout and stderr) +# false (do not record) +# +runcmd() { + if [ $# -ne 3 ]; then + echo "usage: dotest cmd loc rec" + exit 1 + fi + + # prefix executable with abolute pathname. + executable=`echo $1 | cut -f 1 -d ' '` + relapath=`dirname ${executable}` + cd ${THISDIR} + absolpath=`cd ${relapath} && /bin/pwd` + newcmd=${absolpath}/`basename ${executable}`" "`echo $1 | cut -f 2- -d ' '` + + if [ "$2" = work ]; then + cd ${TESTDIR} || exit 1 + elif [ "$2" = result ]; then + cd ${RLTDIR} || exit 1 + else + echo "loc must be work or result." + exit 1 + fi + + if [ "$3" = true ]; then + ${newcmd} > ${OUTDIR}/${TC}.out 2> ${OUTDIR}/${TC}.err + echo $? > ${OUTDIR}/${TC}.eval + elif [ "$3" = false ]; then + ${newcmd} + else + echo "rec must be true of false." + exit 1 + fi + + cd ${THISDIR} +} + +# `rundiff' performs standard diff to compare exit value, +# stdout output, stderr output and resulting files with +# "standard answers". +# +rundiff() { + # $1 indicates whether we should compare resulting files. + if [ $# -ne 1 ]; then + echo "usage: rundiff [true|false]" + exit 1 + fi + cd ${THISDIR} || exit 1 + if [ -f ${TCDIR}/${TC}.eval ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.eval ${OUTDIR}/${TC}.eval + if [ $? -eq 0 ]; then + echo "${TC} exit value - ok" + incct ${PASSEDCT} + else + echo "${TC} exit value - not ok" + fi + fi + + if [ -f ${TCDIR}/${TC}.out ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.out ${OUTDIR}/${TC}.out + if [ $? -eq 0 ]; then + echo "${TC} stdout - ok" + incct ${PASSEDCT} + else + echo "${TC} stdout - not ok" + fi + fi + + if [ -f ${TCDIR}/${TC}.err ]; then + incct ${TOTALCT} + diff -urN ${TCDIR}/${TC}.err ${OUTDIR}/${TC}.err + if [ $? -eq 0 ]; then + echo "${TC} stderr - ok" + incct ${PASSEDCT} + else + echo "${TC} stderr - not ok" + fi + fi + + if [ "$1" = true ]; then + incct ${TOTALCT} + diff -urN ${RLTDIR} ${TESTDIR} + if [ $? -eq 0 ]; then + echo "${TC} resulting files - ok" + incct ${PASSEDCT} + else + echo "${TC} resulting files - not ok" + fi + fi +} + +# `innct' increase specified counter by 1. +incct() { + if [ $# -ne 1 ]; then + echo "usage: incct counterfile" + exit 1 + fi + if [ -f $1 ]; then + exec 3< $1 + read val <&3 + exec 3<&- + newval=`expr ${val} + 1` + echo ${newval} > $1 + else + echo "$1 not exist" + exit 1 + fi +} + +# `statistic' shows number of test passed. +# +statistic() { + exec 3< ${TOTALCT} + read tval <&3 + exec 3<&- + exec 3< ${PASSEDCT} + read pval <&3 + exec 3<&- + + echo "${pval} out of ${tval} passed." +} diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile new file mode 100644 index 0000000000..5585ec7366 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile @@ -0,0 +1,17 @@ +# $Id: Makefile 3380 2016-01-29 07:53:10Z jkoshy $ + +PLUGINS= ardiff teraser + +all: ${PLUGINS} + +${PLUGINS}: +.for plugin in ${.TARGET} + ${MAKE} -f Makefile.${plugin} +.endfor + +test: .PHONY + +clean cleandepend clobber depend: .PHONY +.for plugin in ${PLUGINS} + ${MAKE} -f Makefile.${plugin} ${.TARGET} +.endfor diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.ardiff b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.ardiff new file mode 100644 index 0000000000..0baf13431d --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.ardiff @@ -0,0 +1,18 @@ +# $Id: Makefile.ardiff 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. + +PROG= ardiff + +NOMAN= + +WARNS?= 6 + +DPADD= ${LIBARCHIVE} +LDADD= -larchive + +.include "${TOP}/mk/elftoolchain.prog.mk" + +.if ${OS_HOST} == "DragonFly" +LDADD+= -lbz2 +.endif diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.teraser b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.teraser new file mode 100644 index 0000000000..50faea14f5 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/Makefile.teraser @@ -0,0 +1,11 @@ +# $Id: Makefile.teraser 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. + +PROG= teraser + +NOMAN= + +WARNS?= 6 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/ardiff.c b/contrib/elftoolchain/tests/custom/elfcopy/plugin/ardiff.c new file mode 100644 index 0000000000..2dd036845b --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/ardiff.c @@ -0,0 +1,256 @@ +/** + * Selectively compare two ar archives. + * Usage: + * ardiff [-ni] [-t name] ar1 ar2 + * Options: + * -c compare member content. (This implies -s) + * -n compare member name. + * -i compare member mtime. + * -l compare archive length (member count). + * -s compare member size. + * -t specify the test name. + * + * By default, it compares nothing and consider the test "not ok" + * iff it encounters errors while reading archive. + * + * $Id: ardiff.c 4025 2023-12-16 22:33:13Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define COUNTER "/tmp/bsdar-test-total" +#define PASSED "/tmp/bsdar-test-passed" + +static void usage(void); +static void filediff(const char *tc, const char *msg, const char *e); +static void filesame(const char *tc); +static void incct(const char *pathname); + +int +main(int argc, char **argv) +{ + struct archive *a1; + struct archive *a2; + struct archive_entry *e1; + struct archive_entry *e2; + const char *tc; + char *buf1; + char *buf2; + char checkcont; + char checklen; + char checkname; + char checksize; + char checktime; + char a1end; + size_t size1; + size_t size2; + int opt, r; + + /* + * Parse command line options. + */ + checkcont = 0; + checklen = 0; + checkname = 0; + checksize = 0; + checktime = 0; + tc = NULL; + while ((opt = getopt(argc, argv, "cilnst:")) != -1) { + switch(opt) { + case 'c': + checkcont = 1; + break; + case 'i': + checktime = 1; + break; + case 'l': + checklen = 1; + break; + case 'n': + checkname = 1; + break; + case 's': + checksize = 1; + break; + case 't': + tc = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + usage(); + + /* Open file 1 */ + a1 = archive_read_new(); + archive_read_support_format_ar(a1); + if (archive_read_open_filename(a1, argv[0], + 1024*10)) { + warnx("%s", archive_error_string(a1)); + filediff(tc, "archive open failed", NULL); + } + + /* Open file 2 */ + a2 = archive_read_new(); + archive_read_support_format_ar(a2); + if (archive_read_open_filename(a2, argv[1], + 1024*10)) { + warnx("%s", archive_error_string(a2)); + filediff(tc, "archive open failed", NULL); + } + + /* Main loop */ + a1end = 0; + size1 = 0; + size2 = 0; + for (;;) { + /* + * Read header from each archive, compare length. + */ + r = archive_read_next_header(a1, &e1); + if (r == ARCHIVE_EOF) + a1end = 1; + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) { + warnx("%s", archive_error_string(a1)); + filediff(tc, "archive data error", NULL); + } + r = archive_read_next_header(a2, &e2); + if (r == ARCHIVE_EOF) { + if (a1end > 0) + break; + else { + if (checklen) + filediff(tc, "length differ", NULL); + break; + } + } + if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || + r == ARCHIVE_FATAL) { + warnx("%s", archive_error_string(a2)); + filediff(tc, "archive data error", NULL); + } + if (a1end > 0) { + if (checklen) + filediff(tc, "length differ", NULL); + break; + } + + /* + * Check member name if required. + */ + if (checkname) { + if (strcmp(archive_entry_pathname(e1), + archive_entry_pathname(e2)) != 0) + filediff(tc, "member name differ", + archive_entry_pathname(e1)); + } + + /* + * Compare time if required. + */ + if (checktime) { + if (archive_entry_mtime(e1) != + archive_entry_mtime(e2)) + filediff(tc, "member mtime differ", + archive_entry_pathname(e1)); + } + + /* + * Compare member size if required. + */ + if (checksize || checkcont) { + size1 = (size_t) archive_entry_size(e1); + size2 = (size_t) archive_entry_size(e2); + if (size1 != size2) + filediff(tc, "member size differ", + archive_entry_pathname(e1)); + } + + /* + * Compare member content if required. + */ + if (checkcont) { + if ((buf1 = malloc(size1)) == NULL) + filediff(tc, "not enough memory", NULL); + if ((buf2 = malloc(size2)) == NULL) + filediff(tc, "not enough memory", NULL); + if ((size_t) archive_read_data(a1, buf1, size1) != + size1) + filediff(tc, "archive_read_data failed", + archive_entry_pathname(e1)); + if ((size_t) archive_read_data(a2, buf2, size2) != + size2) + filediff(tc, "archive_read_data failed", + archive_entry_pathname(e1)); + if (memcmp(buf1, buf2, size1) != 0) + filediff(tc, "member content differ", + archive_entry_pathname(e1)); + free(buf1); + free(buf2); + } + + /* Proceed to next header. */ + } + + /* Passed! */ + filesame(tc); + exit(EXIT_SUCCESS); +} + +static void +filediff(const char *tc, const char *msg, const char *e) +{ + if (e != NULL) + fprintf(stdout, "%s - archive diff not ok (%s (entry: %s))\n", + tc, msg, e); + else + fprintf(stdout, "%s - archive diff not ok (%s)\n", tc, msg); + + incct(COUNTER); + exit(EXIT_SUCCESS); +} + +static void +filesame(const char *tc) +{ + fprintf(stdout, "%s - archive diff ok\n", tc); + incct(COUNTER); + incct(PASSED); +} + +static void +incct(const char *pathname) +{ + FILE *fp; + char buf[16]; + + if ((fp = fopen(pathname, "r")) != NULL) { + if (fgets(buf, 10, fp) != buf) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", atoi(buf) + 1); + fclose(fp); + } + if ((fp = fopen(pathname, "w")) != NULL) { + fputs(buf, fp); + fclose(fp); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: ardiff archive1 archive2\n"); + exit(EXIT_FAILURE); +} diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/os.FreeBSD.mk b/contrib/elftoolchain/tests/custom/elfcopy/plugin/os.FreeBSD.mk new file mode 100644 index 0000000000..c29af70518 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/os.FreeBSD.mk @@ -0,0 +1,2 @@ +DPADD+= ${LIBBZ2} +LDADD+= -lbz2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/plugin/teraser.c b/contrib/elftoolchain/tests/custom/elfcopy/plugin/teraser.c new file mode 100644 index 0000000000..be2beadfcd --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/plugin/teraser.c @@ -0,0 +1,154 @@ +/** + * 1. Erase archive symbol table's timestamp from ar archives, + * make it easy to `diff'. (option -e) + * 2. Check the sanity of timestamp. (option -c) + * + * $Id: teraser.c 4025 2023-12-16 22:33:13Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSPOS 24 /* position of timestamp */ +#define TSLEN 10 /* length of timstamp string */ +#define BUFLEN 16 /* size of a temporary buffer */ +#define TDELAY 3 /* max delay allowed */ +#define COUNTER "/tmp/bsdar-test-total" +#define PASSED "/tmp/bsdar-test-passed" + +#if BUFLEN < TSLEN +#error Temporary buffer size too small +#endif + +static void usage(void); + +int +main(int argc, char **argv) +{ + int opt; + char checktime; + char erasetime; + char buf[BUFLEN]; + char *tc; + int fd; + int ts; + time_t now; + FILE *ct, *ps; + + + checktime = 0; + erasetime = 0; + tc = NULL; + while ((opt = getopt(argc, argv, "cet:")) != -1) { + switch(opt) { + case 'c': + checktime = 1; + break; + case 'e': + erasetime = 1; + break; + case 't': + tc = optarg; + break; + default: + usage(); + } + } + + argv += optind; + if (*argv == NULL) + usage(); + + for (; *argv != NULL; argv++) { + if (checktime) { + if ((fd = open(*argv, O_RDONLY)) == -1) { + fprintf(stderr, + "open %s failed(%s), skipping time check...\n,", + *argv, strerror(errno)); + goto ctend; + } + if ((lseek(fd, TSPOS, SEEK_SET)) == -1) { + fprintf(stderr, + "lseek %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + goto ctend; + } + if ((read(fd, buf, TSLEN)) != TSLEN) { + fprintf(stderr, + "read %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + goto ctend; + } + buf[TSLEN] = '\0'; + ts = atoi(buf); + now = time(NULL); + if (ts <= now && ts >= now - TDELAY) { + fprintf(stderr, "%s - timestamp ok\n", tc); + if ((ps = fopen(PASSED, "r")) != NULL) { + if (fgets(buf, TSLEN, ps) != buf) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", + atoi(buf) + 1); + fclose(ps); + } + if ((ps = fopen(PASSED, "w")) != NULL) { + fputs(buf, ps); + fclose(ps); + } + } else { + fprintf(stderr, "%s - timestamp not ok\n", tc); + } + if ((ct = fopen(COUNTER, "r")) != NULL) { + if (fgets(buf, TSLEN, ct) != NULL) + perror("fgets"); + snprintf(buf, sizeof buf, "%d\n", + atoi(buf) + 1); + fclose(ct); + } + if ((ct = fopen(COUNTER, "w")) != NULL) { + fputs(buf, ct); + fclose(ct); + } + + ctend: + close(fd); + } + + if (erasetime) { + if ((fd = open(*argv, O_RDWR)) == -1) { + fprintf(stderr, + "open %s failed(%s), skipping time check...\n,", + *argv, strerror(errno)); + goto etend; + } + if ((lseek(fd, TSPOS, SEEK_SET)) == -1) { + fprintf(stderr, "lseek %s failed(%s), skipping...,", + *argv, strerror(errno)); + goto etend; + } + memset(buf, 32, TSLEN); + if ((write(fd, buf, TSLEN)) != TSLEN) + fprintf(stderr, + "read %s failed(%s), skipping...\n,", + *argv, strerror(errno)); + + etend: + close(fd); + } + } + + exit(EXIT_SUCCESS); +} + +static void +usage(void) +{ + fprintf(stderr, "usage: teraser [-ce] [-t name] archive ...\n"); + exit(EXIT_FAILURE); +} diff --git a/contrib/elftoolchain/tests/custom/elfcopy/run.sh b/contrib/elftoolchain/tests/custom/elfcopy/run.sh new file mode 100644 index 0000000000..bff7c4ddee --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/run.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# $Id: run.sh 3816 2020-02-08 15:00:18Z jkoshy $ +# +# Run all the tests. + +test_log=test.log + +# setup cleanup trap +trap 'rm -rf /tmp/elfcopy-*; rm -rf /tmp/strip-*' 0 2 3 15 + +# load functions. +. ./func.sh + +# global initialization. +init + +exec 4>&1 # Save stdout for later use. + +exec >${test_log} 2>&1 +echo @TEST-RUN: `date` + +# run tests. +for f in tc/*; do + if [ -d $f ]; then + . $f/`basename $f`.sh + fi +done + +# show statistics. +echo @RESULT: `statistic` + +# Exit with an error if any test had failed. +if grep 'not ok' ${test_log} >&4; then + status=1 + exit 1 +fi diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.sh new file mode 100755 index 0000000000..56d725a468 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/elfcopy-L-1.sh @@ -0,0 +1,6 @@ +# $Id: elfcopy-L-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-L-1 tc/elfcopy-L-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} -L bar -L foo2 sym.o sym.o.1" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/in/elfcopy-L-1.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/in/elfcopy-L-1.in.shar new file mode 100644 index 0000000000..c0e329c7ee --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-L-1/in/elfcopy-L-1.in.shar @@ -0,0 +1,34 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# sym.o.uu +# +echo x - sym.o.uu +sed 's/^X//' >sym.o.uu << '07b26866a0eaf5d2a40d8f75b1109c67' +Xbegin 644 sym.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-Ta.out.uu << 'debc64a5f6aece67b22914f9f4be2988' +Xbegin 755 a.out +XM?T5,1@(!`0D```````````(`/@`!````L`1```````!``````````'@+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````-0&````````U`8````````` +XM`!````````$````&````V`8```````#8!E```````-@&4```````H`(````` +XM``"P`@``````````$````````@````8```"P!P```````+`'4```````L`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````S`8```````#,!D```````,P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``9-0P``P````H````)````"`````4```````````````$````````` +XM`P````0````"````!@````<````````````````````````````````````` +XM`````````"8````2````7`1```````#2`````````#X````2````;`1````` +XM```"`````````"L````1`!8`@`E0```````(`````````#,````1``\`V`90 +XM```````(`````````!\````2````?`1```````"B`````````$H````2```` +XMC`1````````O`````````$\````0`/'_B`E0`````````````````$@````2 +XM````G`1````````O``````````$````@``````````````````````````!? +XM2G9?4F5G:7-T97)#;&%SX$$`#_)?`$$`"0D)"0_R7N!!``:``` +XM``#IX/____\EY@00`&@!````Z=#_____)=X$$`!H`@```.G`_____R76!!`` +XM:`,```#IL/____\ES@00`&@$````Z:#___\`````051,C6<(55.+'TACPX7; +XM2(ULQQ!(B2VU!!``?CI(BU<(2(72=#%(B17[`1``#[8"A,!T(TB#P@$\+TB+ +XM!>?___^@0____B=](B>I,B>;HBP```(G'Z%#____H*____^O6D)"0 +XMD)"0D)"0D)"0D$B#[`B`/1T$$```=!#K))!(@\`(2(D%?0$0`/_22(L%=`$0 +XM`$B+$$B%TG7DQ@7U`Q```4B#Q`C#9F9FD&9F9I!(@SV8`Q```'06N`````!( +XMA'`@)````1O__R``$```````)@9` +XM`````````````````"@)4```````%``````````!>E(``7@0`0,,!PB0`0`` +XM'````!P```"P!$``DP````!"#A",`D4.&$$.((,$A@,4````/````%`%0``X +XM`````$0.$``````4````5````)`%0``B```````````````<````;````,`% +XM0``M`````$$.$(8"0PT&```````````````8``````````%Z4@`!>!`!`PP' +XM")`!````````%````"````#P!4``)0````!(#A"#`@```0`````````5```` +XM``````P`````````.`1````````-`````````!@&0```````!`````````#X +XM`4````````4`````````*`-````````&`````````#@"0```````"@`````` +XM``!=``````````L`````````&``````````5`````````````````````P`` +XM```````X"5````````(`````````>``````````4``````````<````````` +XM%P````````#``T```````/[__V\`````H`-```````#___]O``````$````` +XM````\/__;P````"&`T`````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````````/__________``````````#_____ +XM_____P````````````````````"P!U````````````````````````````!B +XM!$```````'($0```````@@1```````"2!$```````*($0````````"1&'`@)``D1G)E94)31#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6UT86(`+G-T``````````$````"@````@`````````&``````` +XM``!M`````0````8`````````.`1````````X!````````!,````````````` +XM```````$````````````````````:`````$````&`````````$P$0``````` +XM3`0```````!@````````````````````!``````````0`````````',````! +XM````!@````````"P!$```````+`$````````:`$``````````````````!`` +XM``````````````````!Y`````0````8`````````&`9````````8!@`````` +XM``X````````````````````$````````````````````?P````$````"```` +XM`````"8&0```````)@8```````"E`````````````````````0`````````` +XM`````````(<````!`````@````````#,!D```````,P&````````"``````` +XM``````````````0```````````````````"5`````0````,`````````V`90 +XM``````#8!@```````!@````````````````````(```````````````````` +XMFP````$````"`````````/`&4```````\`8```````#````````````````` +XM````"````````````````````*4````&`````P````````"P!U```````+`' +XM````````8`$````````%``````````@`````````$`````````"N`````0`` +XM``,`````````$`E0```````0"0```````!`````````````````````(```` +XM````````````````M0````$````#`````````"`)4```````(`D````````0 +XM````````````````````"````````````````````+P````!`````P`````` +XM```P"5```````#`)````````"`````````````````````@````````````` +XM``````#!`````0````,`````````.`E0```````X"0```````$`````````` +XM```````````(``````````@`````````Q@````@````#`````````'@)4``` +XM````>`D````````0````````````````````"````````````````````,L` +XM```!`````````````````````````'@)````````+`$````````````````` +XM``$````````````````````1`````P````````````````````````"D"@`` +XM`````-0````````````````````!`````````````````````0````(````` +XM````````````````````.!(```````"0!@```````!H````T````"``````` +XM```8``````````D````#`````````````````````````,@8````````^0$` +XM``````````````````$````````````````````````````````````````` +XM`````````````````P`!`,@!0````````````````````````P`"`.`!0``` +XM`````````````````````P`#`/@!0````````````````````````P`$`#@" +XM0````````````````````````P`%`"@#0````````````````````````P`& +XM`(8#0````````````````````````P`'`*`#0``````````````````````` +XM`P`(`,`#0````````````````````````P`)`#@$0``````````````````` +XM`````P`*`$P$0````````````````````````P`+`+`$0``````````````` +XM`````````P`,`!@&0````````````````````````P`-`"8&0``````````` +XM`````````````P`.`,P&0````````````````````````P`/`-@&4``````` +XM`````````````````P`0`/`&4````````````````````````P`1`+`'4``` +XM`````````````````````P`2`!`)4````````````````````````P`3`"`) +XM4````````````````````````P`4`#`)4````````````````````````P`5 +XM`#@)4````````````````````````P`6`'@)4``````````````````````` +XM`P`7`````````````````````````````P`8```````````````````````` +XM`````P`9`````````````````````````````P`:```````````````````` +XM```!````!`#Q_P`````````````````````(`````0`"`.`!0```````&``` +XM```````/````!`#Q_P`````````````````````M````!`#Q_P`````````` +XM```````````\````!`#Q_P`````````````````````/````!`#Q_P`````` +XM``````````````!'````!`#Q_P````````````````````!2`````0`2`!`) +XM4`````````````````!@`````0`3`"`)4`````````````````!N`````0`4 +XM`#`)4`````````````````![`````@`+`%`%0`````````````````"1```` +XM`0`6`'@)4````````0````````"@`````0`/`.@&4`````````````````"G +XM`````@`+`)`%0`````````````````!'````!`#Q_P`````````````````` +XM``"S`````0`2`!@)4`````````````````#``````0`3`"@)4``````````` +XM``````#-`````0`0`'@'4`````````````````#;`````0`4`#`)4``````` +XM``````````#G`````@`+`/`%0`````````````````#]````!`#Q_P`````` +XM```````````````M````!`#Q_P`````````````````````\````!`#Q_P`` +XM``````````````````#]````!`#Q_P`````````````````````;`0``!`#Q +XM_P`````````````````````B`0``$@```%P$0```````T@`````````Q`0`` +XM$0`1`+`'4``````````````````Z`0``$0(/`.`&4`````````````````!' +XM`0``$@```&P$0````````@````````!;`0``$@`)`#@$0``````````````` +XM``!A`0``$0`6`(`)4```````"`````````!I`0``$0`/`-@&4```````"``` +XM``````!T`0``$@`+`+`$0```````DP````````![`0``$@```'P$0``````` +XMH@````````",`0``$`#Q_W@)4`````````````````"8`0``$@`+`,`%0``` +XM````+0````````"=`0``$@`,`!@&0`````````````````"C`0``$@```(P$ +XM0```````+P````````"R`0``$`#Q_W@)4`````````````````"Y`0``$0`5 +XM`#@)4`````````````````#/`0``$`#Q_X@)4`````````````````#4`0`` +XM$@```)P$0```````+P````````#E`0``(``````````````````````````` +XM8W)T,2YC`&%B:71A9P`O=7-R+W-R8R]L:6(O8W-U+V%M9#8T+V-R=&DN4P`\ +XM8V]M;6%N9"UL:6YE/@`\8G5I;'0M:6X^`&-R='-T=69F+F,`7U]#5$]27TQ) +XM4U1?7P!?7T143U)?3$E35%]?`%]?2D-27TQ)4U1?7P!?7V1O7V=L;V)A;%]D +XM=&]Rsym.o.uu << 'END-of-sym.o.uu' +Xbegin 644 sym.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-Tdup.o.uu << 'END-of-dup.o.uu' +Xbegin 644 dup.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-T. +# Source directory was '/home/jkoshy/Work/elftoolchain/sourceforge/trunk/test/elfcopy/tc/elfcopy-keep-global-symbols/in'. +# +# Existing files will *not* be overwritten, unless '-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 2030 -rw-rw-r-- a.o.uu +# 4 -rw-rw-r-- syms +# +MD5SUM=${MD5SUM-md5sum} +f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'` +test -n "${f}" && md5check=true || md5check=false +${md5check} || \ + echo 'Note: not verifying md5sums. Consider installing GNU coreutils.' +if test "X$1" = "X-c" +then keep_file='' +else keep_file=true +fi +echo=echo +save_IFS="${IFS}" +IFS="${IFS}:" +gettext_dir= +locale_dir= +set_echo=false + +for dir in $PATH +do + if test -f $dir/gettext \ + && ($dir/gettext --version >/dev/null 2>&1) + then + case `$dir/gettext --version 2>&1 | sed 1q` in + *GNU*) gettext_dir=$dir + set_echo=true + break ;; + esac + fi +done + +if ${set_echo} +then + set_echo=false + for dir in $PATH + do + if test -f $dir/shar \ + && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) + then + locale_dir=`$dir/shar --print-text-domain-dir` + set_echo=true + break + fi + done + + if ${set_echo} + then + TEXTDOMAINDIR=$locale_dir + export TEXTDOMAINDIR + TEXTDOMAIN=sharutils + export TEXTDOMAIN + echo="$gettext_dir/gettext -s" + fi +fi +IFS="$save_IFS" +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null +then if (echo -n test; echo 1,2,3) | grep n >/dev/null + then shar_n= shar_c=' +' + else shar_n=-n shar_c= ; fi +else shar_n= shar_c='\c' ; fi +f=shar-touch.$$ +st1=200112312359.59 +st2=123123592001.59 +st2tr=123123592001.5 # old SysV 14-char limit +st3=1231235901 + +if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \ + test ! -f ${st1} && test -f ${f}; then + shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"' + +elif touch -am ${st2} ${f} >/dev/null 2>&1 && \ + test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then + shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"' + +elif touch -am ${st3} ${f} >/dev/null 2>&1 && \ + test ! -f ${st3} && test -f ${f}; then + shar_touch='touch -am $3$4$5$6$2 "$8"' + +else + shar_touch=: + echo + ${echo} 'WARNING: not restoring timestamps. Consider getting and +installing GNU '\''touch'\'', distributed in GNU coreutils...' + echo +fi +rm -f ${st1} ${st2} ${st2tr} ${st3} ${f} +# +if test ! -d ${lock_dir} ; then : +else ${echo} "lock directory ${lock_dir} exists" + exit 1 +fi +if mkdir ${lock_dir} +then ${echo} "x - created lock directory ${lock_dir}." +else ${echo} "x - failed to create lock directory ${lock_dir}." + exit 1 +fi +# ============= a.o.uu ============== +if test -n "${keep_file}" && test -f 'a.o.uu' +then +${echo} "x - SKIPPING a.o.uu (file already exists)" + +else +${echo} "x - extracting a.o.uu (text)" + sed 's/^X//' << 'SHAR_EOF' > 'a.o.uu' && +begin 664 a.o +M?T5,1@(!`0````````````$`/@`!`````````````````````````+`"```` +M`````````$```````$``#``+`/,/'OI52(GED%W#\P\>^E5(B>607<,`1T-# +M.B`H56)U;G1U(#DN-"XP+3%U8G5N='4Q?C(P+C`T+C$I(#DN-"XP```````` +M``0````0````!0```$=.50`"``#`!`````,`````````%``````````!>E(` +M`7@0`1L,!PB0`0``'````!P`````````"P````!%#A"&`D,-!D(,!P@````< +M````/``````````+`````$4.$(8"0PT&0@P'"``````````````````````` +M```````````````````$`/'_```````````````````````````#``$````` +M```````````````````````#``(````````````````````````````#``,` +M```````````````````````````#``4````````````````````````````# +M``8````````````````````````````#``<````````````````````````` +M```#``0```````````````````````$````2``$````````````+```````` +M``4````2``$`"P`````````+``````````!A8F,`>'EZ```````````@```` +M``````(````"``````````````!```````````(````"````"P`````````` +M+G-Y;71A8@`N/dev/null 2>&1 || ${echo} 'a.o.uu': 'MD5 check failed' + ) << \SHAR_EOF +0716a4cd35629c864d49d2a262b2ec61 a.o.uu +SHAR_EOF + +else +test `LC_ALL=C wc -c < 'a.o.uu'` -ne 2030 && \ + ${echo} "restoration warning: size of 'a.o.uu' is not 2030" + fi +fi +# ============= syms ============== +if test -n "${keep_file}" && test -f 'syms' +then +${echo} "x - SKIPPING syms (file already exists)" + +else +${echo} "x - extracting syms (text)" + sed 's/^X//' << 'SHAR_EOF' > 'syms' && +xyz +SHAR_EOF + (set 20 22 04 23 10 52 43 'syms' + eval "${shar_touch}") && \ + chmod 0664 'syms' +if test $? -ne 0 +then ${echo} "restore of syms failed" +fi + if ${md5check} + then ( + ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'syms': 'MD5 check failed' + ) << \SHAR_EOF +b6273b589df2dfdbd8fe35b1011e3183 syms +SHAR_EOF + +else +test `LC_ALL=C wc -c < 'syms'` -ne 4 && \ + ${echo} "restoration warning: size of 'syms' is not 4" + fi +fi +if rm -fr ${lock_dir} +then ${echo} "x - removed lock directory ${lock_dir}." +else ${echo} "x - failed to remove lock directory ${lock_dir}." + exit 1 +fi +exit 0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.sh new file mode 100644 index 0000000000..d8b3d391b2 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/elfcopy-noops-1.sh @@ -0,0 +1,6 @@ +# $Id: elfcopy-noops-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-noops-1 tc/elfcopy-noops-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} pkill pkill.new" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/in/elfcopy-noops-1.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/in/elfcopy-noops-1.in.shar new file mode 100644 index 0000000000..7293a5b2b4 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-1/in/elfcopy-noops-1.in.shar @@ -0,0 +1,398 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# pkill.uu +# +echo x - pkill.uu +sed 's/^X//' >pkill.uu << 'END-of-pkill.uu' +Xbegin 755 pkill +XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```#T+@```````#0`(``& +XM`"@`&P`8``8````T````-(`$"#2`!`C`````P`````4````$`````P```/0` +XM``#T@`0(](`$"!4````5````!`````$````!``````````"`!`@`@`0(YBH` +XM`.8J```%`````!````$```#H*@``Z+H$".BZ!`C$`0``R`(```8`````$``` +XM`@````0K```$NP0(!+L$"-````#0````!@````0````$````#`$```R!!`@, +XM@00(&````!@````$````!````"]L:6)E>&5C+VQD+65L9BYS;RXQ``````@` +XM```$`````0```$9R965"4T0`%C4,`"4```!"`````````$`````%```````` +XM``D````W````$````"\````4````!P```"4````H````*P```"(````D```` +XM-``````````]````,````#D````;`````````#4````N````$@```#,````6 +XM````(0`````````_````*@```#(````8`````0`````````Q````00`````` +XM`````````````````````````````````````````@````8````````````` +XM````````````#0`````````````````````````+```````````````````` +XM```````````,```````````````9````'````````````````````!$````` +XM`````P```!H````.`````````",````$````'P````\`````````'@```"D` +XM```(````)P```!4````L`````````"8````=`````````!,`````````%P`` +XM`#8````X````+0```#L````*````(````#P````^````.@`````````````` +XM```````````P`0```````#0````2````ZP$```````!6`0``$@````T````$ +XMNP0(`````!$`\?\X`0`````````````2````S`$```````"A````$@```-$! +XM````````'0```!(```#;`````````&H````2````70$```````"_````$@`` +XM`*0!````````!0```!(````-`0```````,H````2````%@```(R+!`@````` +XM$@`*`%P$```````#*#``` +XM$@```-H!````````*P```!(```"Z```````````````2````$`(````````` +XM````$@```$\`````````M@```!(````@`0`````````````2````70`````` +XM````````(````.X`````````&````!(```#'`````````(0````2````<0`` +XM``````!J!```$@````!L:6)K=FTN@<```(`/`(```````"PO`0( +XM!1```#"]!`@%$@``-+T$"`47```XO00(!2(``#R]!`@%(P``0+T$"`4G``!$ +XMO00(!2@``$B]!`@%-0``3+T$"`4V``#TNP0(!P$``/B[!`@'`@``_+L$"`<$ +XM````O`0(!P4```2\!`@'!@``"+P$"`<'```,O`0(!P@``!"\!`@'"0``%+P$ +XM"`<*```8O`0(!PP``!R\!`@'#0``(+P$"`<.```DO`0(!Q$``"B\!`@'$P`` +XM++P$"`<5```PO`0(!Q8``#2\!`@'&```.+P$"`<9```\O`0(!QH``$"\!`@' +XM&P``1+P$"`<<``!(O`0(!QT``$R\!`@''P``4+P$"`<@``!4O`0(!R$``%B\ +XM!`@')```7+P$"`#_____)?B[!`AH +XM"````.G0_____R7\NP0(:!````#IP/____\E`+P$"&@8````Z;#_____)02\ +XM!`AH(````.F@_____R4(O`0(:"@```#ID/____\E#+P$"&@P````Z8#_____ +XM)1"\!`AH.````.EP_____R44O`0(:$````#I8/____\E&+P$"&A(````Z5#_ +XM____)1R\!`AH4````.E`_____R4@O`0(:%@```#I,/____\E)+P$"&A@```` +XMZ2#_____)2B\!`AH:````.D0_____R4LO`0(:'````#I`/____\E,+P$"&AX +XM````Z?#^____)32\!`AH@````.G@_O___R4XO`0(:(@```#IT/[___\E/+P$ +XM"&B0````Z<#^____)4"\!`AHF````.FP_O___R5$O`0(:*````#IH/[___\E +XM2+P$"&BH````Z9#^____)4R\!`AHL````.F`_O___R50O`0(:+@```#I+P$"&@(`0``Z=#]____)7R\!`AH$`$``.G`_?___R6` +XMO`0(:!@!``#IL/W___\EA+P$"&@@`0``Z:#]____)8B\!`AH*`$``.F0_?__ +XM_R6,O`0(:#`!``#I@/W___\ED+P$"&@X`0``Z7#]____)92\!`AH0`$``.E@ +XM_?___R68O`0(:$@!``#I4/W___\EG+P$"&A0`0``Z4#]____):"\!`AH6`$` +XM`.DP_?___R6DO`0(:&`!``#I(/W___\EJ+P$"&AH`0``Z1#]__]5B>564X/L +XM$(/D\(M=!(G1C72=#(7;B36LO00(?C:+10B%P'0OH^BZ!`@/MA"$TG0C@\`! +XMZPH/MA"#P`&$TG04@/HO=?&CZ+H$"`^V$(/``832=>RX!+L$"(7`=#2)#"3H +XM&____\<$)(RE!`CH#____^B&_/__C44(B70D"(E$)`2)'"3HEP0``(D$).A_ +XM_O__Z/K\___KS9"0D)"0D)"058GE@^P(@#U0O00(`'0,ZQR#P`2C\+H$"/_2 +XMH?"Z!`B+$(72=>O&!5"]!`@!R<.058GE@^P(H>2[!`B%P'02N`````"%P'0) +XMQP0DY+L$"/_0R<.0D)"0D)"0D)"0D)"058GE4[OBI00(@^P4H8"]!`B%P'4% +XMN_JE!`CHL?[__XE<)`S'1"0$#*@$"(E$)`BA2+T$"(D$).CD^___QP0D`@`` +XM`.C(_?__D(VT)@````!5B>575KX!````4X'LG`0``(F%=/O__XF5%?/O__Q"F!`B-=@"-E8#[___'1"0$V:8$"(D4).@J_?__A<")PP^$ +XM@`(``(`[``^$BP```,<$)`@```#H:_W__X7`B85L^___#X1P`@``BY5T^___ +XMB[UL^___BP*)!XU%\(DZQT0D"`````")1"0$B1PDZ$3\__^)1P2)PHM%\(`X +XM`'4?@[UP^___!`^$.@$``'%>/O__W"F!`@/E\(/DL`XP@^%R0```(N5?/O_ +XM_XV]D/O__XN%>/O__\=$)`B!I@0(QT0D!``$``")5"0,B40D$(D\).C(^O__ +XMC460B40D!(D\).@Y^O__@\`!#X3R````]D69(`^$"@$``(M%I#'VBY5L^___ +XMB4($Z9/]__^XP*8$"+D$````_(G>B7UW#QT0D"`@```#'1"0$ +XM%J8$",<$)`,```#HX?K__[A]I@0(N0,```")G7C[__^)WHG'\Z8/A!O____' +XMA7S[__]XI@0(Z0S___^)7"0(QT0D!$:F!`C'!"0"````Z"[Y__^)7"0(QT0D +XM!#"F!`C'!"0"````Z!;Y__^)7"0(QT0D!%BF!`C'!"0"````Z/[X___H>?G_ +XM_X,X`G4PB5PD",=$)`2&I@0(QP0D`@```.C<^/__B5PD",=$)`2KI@0(QP0D +XM`@```.C$^/__B5PD",=$)`28I@0(QP0D`P```.@<^O__C;8`````C;\````` +XMC4PD!(/D\/]Q_%6)Y5>_VZ8$"%9348'LJ`P``(L9BTD$QT0D!+^G!`C'!"0` +XM````B8UP\___Z.7Y___H%=//__P`````Q]L>%>//__^6F!`C'A7SS___EI@0(QX6` +XM\___`````,>%B//__P````"+E7#S___'1"0(L*@$"(D<)(E4)`3H'OC__X/X +XM_P^$I`(``(/H1(/X-'8%Z!C[____)(7(J00(QP6FY_?__BX5P\___BY5P\___@\`$@_L!B86T\___BW($QX6, +XM\___X*,$"`^.6OW__X`^+0^%4?W__XU%[(U^`<=$)`@*````B40D!(D\).CC +XM]?__B<*+1>R`.``/A5<&``"+C;3S__^#ZP&)%?2Z!`C'A8SS___@HP0(B8UP +XM\___Z07]__^+/4R]!`@I^XF=O//__P^$'0$``(L=A+T$"(7;#X7M````BY5T +XM\___A=(/A%X!``"+C73S___'1"0$[Z8$"(D,).CK]?__A<")PP^$DPH``(N% +XMB//__X7`=#>A,+T$"(7`#X5[!@``#[]##L=$)`0&````B00DZ+;T__^%P`^$ +XM.@H``.@Y]?__@S@C#X6."@``C;7(^___B5PD",=$)`0`!```B30DZ*;T__^% +XMP`^$E@```(D<).@6]O__C47HQT0D"`H```")1"0$B30DZ-_T__^)P8M%Z`^V +XM`(3`#X0?!0``#[;0.Q4XO00(#XP`!0``BXUT\___QT0D!%:G!`C'!"0#```` +XMB4PD".@R]/__BPV(O00(A,'```/OT,,P>@%@^`! +XMA,`/A"\)``")'"3H8?7__XN%=//__\=$)`1`IP0(QP0D`P```(E$)`CHL_/_ +XM_XN%B//__\>%A//_______^%P`^%F@@``.AF]?__BXU\\___C97(\___B50D +XM$,=$)`P`````QT0D"`````")3"0$HZB]!`B+A7CS__^)!"3H3_7__X7`HZ2] +XM!`@/A(H(``#'1"0,?+T$",=$)`@`````QT0D!`@```")!"3H8O7__X7`HW2] +XM!`@/A#@(``"A?+T$"(D$).AX]/__A<")PJ-XO00(#X0%"0``BXUP\___H7R] +XM!`B)%"3'1"0$`````(T\N8F]N//__XE$)`CH0?/__XN%N//__XL0A=(/A&X" +XM``"A_+H$"(E4)`2-5=B)%"2)1"0(Z>__^%P`^%AP4``*%\O00(BSUTO00( +XMA<`/CAD"``#'A9SS__\`````ZV&)]O:'*`$```1T:HNU@//__X7V?BV-AV\! +XM``")1"00BX>(````B50D",=$)`2JIP0(B40D#*%(O00(B00DZ+#Q__^#A9SS +XM__\!BX6<\___.05\O00(#XZR`0``@<<``P``BU+E83S__^%TG@(.86$\___=:2A7+T$"(7`#X0=`0``BY.,````.U`$=1/I +XM#0$``)"-="8`.5`$#X3_````BP"%P(UV`'7NBY68\___QD0Z_P"+-7R]!`CI +XM:____XD<).A0\?__,T70"T74#X6D_?__H7B]!`B+E9SS___&!`(!Z9#]__^A +XM1+T$"/9$D#5`#X3P^O__C4'[/9J&`0")C83S__\/AI'[__^+A73S___'1"0$ +XM5J<$",<$)`,```")1"0(Z`[O___'1"0(`P```,=$)`3AI@0(B3PDZ-;N__^% +XMP'4#C7X$O@$```#K#(/&`8/^(`^$<0,``(L$M;"\!`B)?"0$B00DZ(GN__^% +XMP'7=@_X@#X11`P``BX6T\___@^L!B37TN@0(QX6,\___X*,$"(F%%E//__P````")C:SS__\QR>L_BX6L\___AN/C8W(\___C578B4PD"(E4)`3'1"0,``@``(D$).AY[/__BY6X +XM\___C8W(\___B4PD#(L"QT0D!'"I!`C'!"0"````B40D".C?[/__BX6H\___ +XMBX`8`0``B85L\___Z2W___^)="0(QT0D!`````")'"3H%.W__X/__W0)H7B] +XM!`C&!#@!BQ5\O00(N`$```"+'72]!`B%TGYG,?8Q_^LFBPV0O00(ANP,<"%_P^4P(D$).AR +XM[?__BX6H\___BY60\___.Y`<`0``#YS`Z<[^__^)'"3HL.O__X7`#Y7`Z17X +XM__^A8+T$"(7`="*+4S`[4`1U"NL8C78`.5`$=!"+`(7`=?60C70F`.E6_?__ +XMH6R]!`B%P'48B?;K)3E31'0@BP"%P)"-="8`#X2,^___BU`$@_K_=>3V@R@! +XM```"==NA:+T$"(7`=#6+4S@[4`1U#>LKC;8`````.5`$=""+`(7`=?60C70F +XM`.G=^___QX6,\___X*,$")#I'_/__XL59+T$"(72="R+BP`"``"+0@0YP746 +XMZQV)]HL2A=(/A,'\__^+0@0YR)!T"87)?NJ#P`%UY8N%O//__X7`#X4*^___ +XMBX68\___QD0X_P&+-7R]!`CI]/K__\=$)`0@J00(QP0D`P```.CMZO__H:2] +XM!`B)!"3H<.O__\=$)`2-IP0(QP0D`P```(E$)`CHR.K__XV5R//__XE4)`C' +XM1"0$;Z<$",<$)`,```#HJNK__XD<).@R[/__BY5T\___QT0D!`"I!`C'!"0# +XM````B50D".CTZ___B1PDZ`SL__^+E73S___'1"0$"J<$",<$)`,```")5"0( +XMZ%[J__^+A73S___'1"0$\:8$",<$)`,```")1"0(Z+#K__^A>+T$"(ET)`C' +XM1"0$`````(D$).B'ZO__Z7S]__^+C73S___'1"0$(J<$",<$)`,```")3"0( +XMZ`3J__^A?+T$",=$)`1(J00(QP0D`P```(E$)`CH5^O__XVT)@````!5B>56 +XMB<93@^P0H92]!`B%P'4-BQV`O00(A=MU0XUV`(L-F+T$"(7)=5:AE+T$"(7` +XM="2-AF\!``")1"0(BT8HQP0DZ:<$"(E$)`3H0.K__X/$$%M>7<.A@+T$"(7` +XM=-.+1BC'!"0'J`0(B40D!.@=ZO__@\006UY=PXVV`````*&DO00(QT0D"``` +XM``")="0$B00DZ&?J__^%P(G#=(N+1BC'!"3EIP0(B40D!.C>Z?__BP.%P'28 +XM@\,$B40D!,<$).RG!`CHQ>G__XL3A=)TX:$PO00(A#.+`L8`((/``8D"BP.%P'6[Z4[___^A0+T$",<$)"````")1"0$ +XMZ%GH___KF8VT)@`````[0AA]R(E4)`3'!"0@````Z-OI___I>/___XVV```` +XM`%6)Y8/L"(M%".BR_O__H?BZ!`C'!"3LIP0(B40D!.@MZ?__N`$```#)PXVV +XM`````%6)Y593@^P0H8R]!`B+=0B%P`^$N````,<$).^G!`CH_.C__XGPZ&7^ +XM___'!"3UIP0(Z.GH__^A0+T$"(D$).A,Z/__H3"]!`B%P`^%^````*$\O00( +XMBU`$@^H!A=*)4`0/B/8```"+%3R]!`B+`@^V&(/``8D"B=F-M"8`````@_D* +XM=#N#P0%T-J$PO00(A70+@_M9=1^-M@````"A]+H$"(E$)`2+1BB) +XM!"3H#.?__X/``70VN@$```"#Q!")T%M>7<.A/+T$"(D$).B,Z?__B<'I=?__ +XM_Z$\O00(B00DZ/CH__^)P>EA____Z,SG__\QTH,X`W3#BT8HQP0D^*<$"(E$ +XM)`3H`NC__X/$$#'26XG07EW#H3R]!`B)!"3H.NG__XG#Z1K___^A/+T$"(D$ +XM).BFZ/__B'`@)`!;+4Q39FEL;F]V>%T@6RUD(&1E;&EM +XM70!;+7-I9VYA;%T@6RU)3&9I;F]V>%T`+V1E=B\`0V%N;F]T(&%L;&]C871E +XM("5Z=2!B>71E0`E0!);G9A;&ED('!I +XM9"!I;B!F:6QE(&`E7-T +XM96U="B`@("`@("`@("`@("!;+5`@<'!I9%T@6RU5('5I9%T@6RUG('!G'!R97-S:6]N(&`E'`@ +XM)````+^G!`@`````X+L$"`\```"^IP0(`0`````````!`````0````$```!^ +XM````#````(R+!`@-````C*4$"`0````D@00(!0```.B&!`@&````R(($"`H` +XM``!%`@``"P```!`````5``````````,```#HNP0(`@```'`!```4````$0`` +XM`!<````'`@)``D1G)E94)3 +XM1#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#

6%R($5X<"`D`$=#0SH@*$=. +XM52D@-"XR+C$@,C`P-S`W,3D@(%M&6YS +XM='(`+F=N=2YV97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R`$``````````````0`````````1`````P``````````````)"X``,X````` +XM``````````$``````````0````(``````````````"PS``!@"0``&@```%(` +XM```$````$`````D````#``````````````",/```9@8``````````````0`` +XM`````````````````````````````````/2`!`@``````P`!```````,@00( +XM``````,``@``````)($$"``````#``,``````,B"!`@``````P`$``````#H +XMA@0(``````,`!0``````+HD$"``````#``8``````+2)!`@``````P`'```` +XM``#4B00(``````,`"```````'(H$"``````#``D``````(R+!`@``````P`* +XM``````"@BP0(``````,`"P``````D(X$"``````#``P``````(RE!`@````` +XM`P`-``````"8I00(``````,`#@``````Z+H$"``````#``\```````"[!`@` +XM`````P`0```````$NP0(``````,`$0``````U+L$"``````#`!(``````-R[ +XM!`@``````P`3``````#DNP0(``````,`%```````Z+L$"``````#`!4````` +XM`*R\!`@``````P`6``````````````````,`%P`````````````````#`!@` +XM`````````````````P`9``````````````````,`&@`!```````````````$ +XM`/'_"`````R!!`@8`````0`"``\```````````````0`\?\P```````````` +XM```$`/'_/P``````````````!`#Q_P\```````````````0`\?]*```````` +XM```````$`/'_50```-2[!`@``````0`2`&,```#````Y+L$"``````!`!0`Z@```&"E!`@``````@`,```!```````` +XM``````0`\?\P```````````````$`/'_/P``````````````!`#Q_P`!```` +XM``````````0`\?\A`0`````````````$`/'_*0$``)"/!`A(`````@`,`"\! +XM``"`O00(!`````$`%@`U`0``X(\$",0#```"``P`/@$``*B]!`@$`````0`6 +XM`$0!``"PHP0(*@````(`#`!,`0``G+T$"`0````!`!8`5@$``)"]!`@$```` +XM`0`6`%X!``!PO00(!`````$`%@!G`0``;+T$"`0````!`!8`<`$``&B]!`@$ +XM`````0`6`'@!``"(O00(!`````$`%@!_`0``A+T$"`0````!`!8`A@$``)2] +XM!`@$`````0`6`(X!``!DO00(!`````$`%@"6`0``_+H$"`0````!``\`G0$` +XM`&"]!`@$`````0`6`*8!``"8O00(!`````$`%@"P`0``^+H$"`0````!``\` +XMM@$``%R]!`@$`````0`6`+\!``"@O00(!`````$`%@#(`0``6+T$"`0````! +XM`!8`T0$``(R]!`@$`````0`6`-T!``!4O00(!`````$`%@#F`0``X*,$"'$! +XM```"``P`[@$``/2Z!`@$`````0`/`/4!``"DO00(!`````$`%@#X`0``?+T$ +XM"`0````!`!8`_@$``'2]!`@$`````0`6``0"``!XO00(!`````$`%@`-`@`` +XM<*($"#H!```"``P`&@(````````T````$@```"P"````````5@$``!(````_ +XM`@``!+L$"``````1`/'_2`(`````````````$@```%<"````````H0```!(` +XM``!F`@```````!T````2````>0(```````!J````$@```(@"``#LN@0(```` +XM`!$"#P"5`@```````+\````2````J@(````````%````$@```+X"```````` +XMR@```!(```#4`@``C(L$"``````2``H`V@(`````````````$@```.H"```` +XM````+@```!(```#Y`@```````)(!```2````"0,``*R]!`@$````$0`6`!$# +XM``"PO`0(@````!$`%@`G`P```````)`````2````.`,``#"]!`@$````$0`6 +XM`$\#````````90(``!(```!@`P``Z+H$"`0````1``\`:P,``)".!`B8```` +XM$@`,`'(#`````````````!(```"!`P```````%(7```2````DP,``#2]!`@$ +XM````$0`6`*0#`````````````!(```"U`P```````!T"```2````Q@,````` +XM```6````$@```-@#````````"P```!(```#C`P```````!T````2````]@,` +XM```````Y````$@````<$``"LO`0(`````!``\?\3!```L),$"+D.```2``P` +XM&`0```````#?````$@```"L$````````00```!(````Z!``````````````2 +XM````2P0``#B]!`@$````$0`6`&,$```\O00(!````!$`%@!V!````````-,` +XM```2````A@0```````!?````$@```)<$``",I00(`````!(`#0"=!```0+T$ +XM"`0````1`!8`L00``$2]!`@$````$0`6`,X$````````8@```!(```#?!``` +XM`````"8"```2````ZP0```````#+````$@```/T$````````^@```!(````/ +XM!0```````$,````2````'@4```````##````$@```"\%````````/@```!(` +XM```]!0``K+P$"``````0`/'_1`4``.B[!`@`````$0#Q_UH%``"PO00(```` +XM`!``\?]?!0```````&(#```2````&5C0$!&0E-$7S$N,`!O<'1Als.uu << 'END-of-ls.uu' +Xbegin 755 ls +XM?T5,1@$!`0D```````````(``P`!````D),$"#0```!T7@```````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(<%@` +XM`'!8```%`````!````$```!P6```<.@$"'#H!`AH`@``V`,```8`````$``` +XM`@```-!8``#0Z`0(T.@$"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&1<6```7-@$"%S8!`@4````%`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`0P```%4````]````40```!8`````````.P```%`````````` +XM.@```#@```!.````0P```!4`````````/@```#8```!!````2P`````````L +XM`````````!<````%````2@```%(```!%`````````!P````M````)P```$8` +XM`````````````#,`````````4P```"@`````````"0````@````````````` +XM```````,````/````#4```!/````"P```"````!4````,0```"$````````` +XM`````$T````?````1P```$P``````````````#\`````````20```$`````` +XM````,````#0````````````````````````````````````````````````` +XM```!`````````````````````````````````````P``````````````"@`` +XM``T````````````````````&```````````````2```````````````````` +XM`````````````````````!$````````````````````B`````````!L````9 +XM``````````(````3```````````````E````#@```!`````/````!P```!H` +XM```4````````````````````)@```"\````C```````````````D````&``` +XM```````Y````,@``````````````'@```"D````J`````````#<````$```` +XM2````$(`````````'0```$0`````````+@`````````K```````````````` +XM``````````````!N`0```````*,````2````T`(```````#&````$@```)D! +XM````````-````!(```"3`@```````#,````2````=0(```````!#````$@`` +XM`"T!````````2````!(```![`@`````````````2````]@````````!K`0`` +XM$@````X```#0Z`0(`````!$`\?^A`0`````````````2````%P````````!L +XM!```$@```&T`````````U`,``!(```!2`@```````*$````2````$`(````` +XM``!:````$@```!0`````````A!@`` +XM$@```,P!````````>````!(````M````W-,$"``````2``T`I@$```````", +XM`@``$@```.@(````` +XM``"Q````$@```/8!``#LZ@0(!````!$`%P"*`@```````,\!```2````2@(` +XM``````#+````$@```%D"````````0P```!(````\`0```````,,````2```` +XM80$````````J````$@```#P"````````/@```!(```#G`@``V.H$"``````0 +XM`/'_0P$````````S````$@```#,```"\Z00(`````!$`\?_Z`@``2.P$"``` +XM```0`/'_7@(```````!B`P``$@````T!``#PZ@0(!````!$`%P`!`0`````` +XM`),````2````L@$``/3J!`@$````$0`7`#4!`````````````!(```!7`@`` +XM`````"L````2````@0(````````I````$@````8!`````````````!(```"R +XM`@`````````````2````H0``````````````$@```$D``````````````"`` +XM```D`0`````````````2````@0`````````4`0``$@```,8`````````6P`` +XM`!(`````;&EB=71I;"YS;RXW`%]$64Y!34E#`&AU;6%N:7IE7VYU;6)E<@!? +XM:6YI=`!?9FEN:0!?1TQ/0D%,7T]&1E-%5%]404),15\`7TIV7U)E9VES=&5R +XM0VQA0!?7W-T9&]U +XM='``=V%R;G@`:6]C=&P`0!A8VQ?9V5T7V5N=')Y`&9T7!E`'-T#I!`AH,````.F`_____R7DZ00(:#@```#ISI!`AH2````.E0_____R7PZ00(:%````#I0/____\E].D$"&A8```` +XMZ3#_____)?CI!`AH8````.D@_____R7\Z00(:&@```#I$/____\E`.H$"&AP +XM````Z0#_____)03J!`AH>````.GP_O___R4(Z@0(:(````#IX/[___\E#.H$ +XM"&B(````Z=#^____)1#J!`AHD````.G`_O___R44Z@0(:)@```#IL/[___\E +XM&.H$"&B@````Z:#^____)1SJ!`AHJ````.F0_O___R4@Z@0(:+````#I@/[_ +XM__\E).H$"&BX````Z7#^____)2CJ!`AHP````.E@_O___R4LZ@0(:,@```#I +XM4/[___\E,.H$"&C0````Z4#^____)33J!`AHV````.DP_O___R4XZ@0(:.`` +XM``#I(/[___\E/.H$"&CH````Z1#^____)4#J!`AH\````.D`_O___R5$Z@0( +XM:/@```#I\/W___\E2.H$"&@``0``Z>#]____)4SJ!`AH"`$``.G0_?___R50 +XMZ@0(:!`!``#IP/W___\E5.H$"&@8`0``Z;#]____)5CJ!`AH(`$``.F@_?__ +XM_R5.H$"&A@`0``Z2#]____)7SJ!`AH +XM:`$``.D0_?___R6`Z@0(:'`!``#I`/W___\EA.H$"&AX`0``Z?#\____)8CJ +XM!`AH@`$``.G@_/___R6,Z@0(:(@!``#IT/S___\ED.H$"&B0`0``Z<#\____ +XM)93J!`AHF`$``.FP_/___R68Z@0(:*`!``#IH/S___\EG.H$"&BH`0``Z9#\ +XM____):#J!`AHL`$``.F`_/___R6DZ@0(:+@!``#I3K!`A^-HM% +XM"(7`="^C<.@$"`^V$(32=".#P`'K"@^V$(/``832=!2`^B]U\:-PZ`0(#[80 +XM@\`!A-)U[+C0Z`0(A6#[`B` +XM/?CJ!`@`=`SK'(/`!*-XZ`0(_]*A>.@$"(L0A=)UZ\8%^.H$"`')PY!5B>6# +XM[`BAN.D$"(7`=!*X`````(7`=`G'!"2XZ00(_]#)PY"0D)"0D)"0D)"0D)!5 +XMB>6#[`R)'"2)="0$B7PD"(MU#(M]"(M&/(M8-(M(,(M'/(M0-(M`,#G3?12X +XM_____XL<)(MT)`2+?"0(B>Q=PWX-N`$```#KZ(VV`````#G!=^\YTWX?BT9` +XMB44,BT=`B44(BQPDBW0D!(M\)`B)[%WI/?S__WRT.<%SVXUV`.NKC;0F```` +XM`(V\)P````!5B>6+50R+10B)50B)10Q=Z5O___^-="8`C;PG`````%6)Y8/L +XM"(D<)(ET)`2+=0B+70R+5CR+2SR+0B@Y02A^$+@!````BQPDBW0D!(GL7<-\ +XM#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0T")10R+1D")10B+'"2+="0$B>Q= +XMZ:#[__^-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z7O___^-="8`C;PG +XM`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+2SR+0E`Y05!^$+@!````BQPD +XMBW0D!(GL7<-\#XM"5#E!5'_FD(UT)@!]![C_____Z]V+0T")10R+1D")10B+ +XM'"2+="0$B>Q=Z1#[__^-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z7O_ +XM__^-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+2SR+0A@Y01A^ +XM$+@!````BQPDBW0D!(GL7<-\#XM"'#E!''_FD(UT)@!]![C_____Z]V+0T") +XM10R+1D")10B+'"2+="0$B>Q=Z8#Z__^-M@````"-OP````!5B>6+50R+10B) +XM50B)10Q=Z7O___^-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+ +XM2SR+0B`Y02!^$+@!````BQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_ +XM____Z]V+0T")10R+1D")10B+'"2+="0$B>Q=Z?#Y__^-M@````"-OP````!5 +XMB>6+50R+10B)50B)10Q=Z7O___^-="8`C;PG`````%6)Y8M%"(M5#(M`0(E% +XM#(M"0(E%"%WIJ?G__Y"-="8`58GEBT4,BT!`B44,BT4(BT!`B44(7>F)^?__ +XMD)"0D)!5B>6#[`R)'"2)="0$B7PD"(M%"(M5#(LP#[=&-&:#^`DW____C;0F```` +XM`#'2BQPDB="+="0$BWPD"(GL7<.-M@````"-O"<`````58GE5U93@>PL!0`` +XMBST\[`0(B848^___B944^___B8T0^___A?_'1%//O__P$```#'!"0RU`0(Z-'V___'1<``````QT7$`````,=%V``` +XM``#'1=0`````QT70`````(7`B``````QT7D`````,=%Z`````#'1>P` +XM````QT7<`````'0)@#@`#X6"!@``BYT4^___A=L/A!8&``"+A1#[__^+O13[ +XM___'A2S[__\`````QX4P^___`````(/@`L>%3/O__P````#'A4C[__\````` +XMB84,^___Z9P"``!F@_@*#X2@`@``BXT8^___A2A(.P$"(7`=0FA[.L$"(7`=!L/MT2+A3S[__^%P`^$(P(``(M7/(G0B94H^___BT@\BT7L +XMBU(XB<;!_A\Y\7P)?P0YPG8#B57LBY4H^___BT($.T7H=@.)1>B+C2C[__\/ +XMMT$*.T7@=@.)1>"+C2C[__^+430[5<2+03!\#7\%.T7`=@:)1<")5<2+A2C[ +XM__^+0#@!A2S[__^A0.P$"(7`#X2@`0``H1CK!`B%P`^$MP(``(N5*/O__XUU +XMIHU=LXM"#,=$)`A-U`0(QT0D!`T```")-"2)1"0,Z$;W__^+C2C[__^+01#' +XM1"0(3=0$",=$)`0-````B1PDB40D#.@A]___B;5`^___B9U$^___BX5`^___ +XMB00DZ$?X__\[1=")A3C[__]V`XE%T(N51/O__XD4).@K^/__.T74B<-V`XE% +XMU(LU..P$",>%-/O__P````"%]@^%E0(``(L-!.P$"#'2QT7,`````(7)#X7I +XM`@``B[4X^___BXTT^___`=Z-1#$8`=")!"3H-O?__X7`B<,/A/,'``"-0!") +XM`XN50/O__XD$)(E4)`3HQ??__XN-./O__XU$&1&)0P2+E43[__^)!"2)5"0$ +XMZ*;W__^+C2C[__\/MT$()0#P```]`"````^$Q0$``#T`8```#X2Z`0``H3CL +XM!`B%P`^%Q`$``*$$[`0(A\O__@\`!#X1[ +XM!```9H-_,@`/A=X```"+1T"-M5?[___'1"0(2M0$",=$)`0!!```B30DB40D +XM#.B%\___BY4,^___A=)T6XM%R(DT)(E$)`3H'/3__X/``71;C47,B40D!(M% +XMR(D$).C%\?__@\`!=$2+1U`0(B40D!.C_\O__BT7(B00DZ`3R__^+1%,/O__P````#'A2S[__\` +XM````H4#L!`B%P'4-H?3K!`B%P`^$8OW__XN]&/O__X7_#X7<_/__Z4_]__\Q +XMP(,]].L$"``/E<")A3S[___I'?G__XD$).AR\___C40``HD$).C&\O__A<") +XMA1S[__\/A'\#```/M@,\.@^$B`,``(N5'/O__XG1B`*#P0'&0@$`#[9#`83` +XM=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&`3`/MD(!B$$! +XM@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$50,``(U%W(N-'/O__XE$)"B-1>2) +XM1"0DC47`B40D((U%V(E$)!R-1=2)1"08C470B40D%(U%X(E$)!"-1>R)1"0, +XMC47HB40D",=$)`3HU`0(B0PDZ/CP___'!13L!`@!````@_@(#X8M`@``BW7H +XM,<"%]G0=N0$```"X"@```/?A@^X!B<%U\L=%Z`````"-0/^+?>R)1>@QP(7_ +XM?C*)_KD!````,=MKTPJX"@```(F5!/O___?AB=.)P0.=!/O__X/N`77AQT7L +XM`````(U`_XMUX(E%[#'`A?9T';D!````N`H```#WX8/N`8G!=?+'1>`````` +XMC4#_BTW$BU7`B47@@_D`B94@^___B8TD^___#XZ)`0``BXT@^___O@$````Q +XM_XN=)/O__VO'"HF%!/O__[@*````]^:)UXG&`[T$^___@\'_@]/_B=H)RG7: +XMB?")^H/`_\=%P`````"#TO_'1<0`````BXT<^___B47`B57$B0PDZ"7Q___I +XM=/?__XN%+/O__XU=CHN-,/O__\=$)`ARU`0(QT0D!!@```")A5S___^+1>R) +XMC6#___^)'"2)1"0,Z/;O__^)'"3H+O'__\=$)`ARU`0(QT0D!!@```")'"2) +XMA6S___^+1=B)A7#___^+1=R)A73___^+1=2)A7C___^+1>B)1"0,Z*[O__^) +XM'"3HYO#__\=$)`ARU`0(QT0D!!@```")'"2)A7S___^+1>")1"0,Z('O__^) +XM'"3HN?#__XM5Q,=$)`AVU`0(QT0D!!@```")'"2)5"00B46`BT7`B40D#.A0 +XM[___B1PDZ(CP__^)182+1=")18CI[_G__XM'0(E$)`B+1P2+0!C'!"1>U`0( +XMB40D!.@M[___Z=/[____)(5$U00(?!&#^@"0C;0F``````^'9/[__S'`,=+I +XMK/[__\=%Z`````#'1>P`````QT7@`````,=%T`````#'1=0`````QT78```` +XM`,=%P`````#'1<0`````QT7D`````(,]&.P$"`''1=P`````&<#WT"$%%.P$ +XM".E4_?__QT0D!#_4!`C'!"0!````Z$7O__^+A1S[__^)P8/!`F;'`#`ZQD`" +XM`.EP_/__QT0D!%+4!`C'!"0!````Z!CO__]FQP$P`.FA_/__C78`C;PG```` +XM`%6)Y5=64X/L'(,]%.L$"`&)1>R)3>@9P"7`EP0(B40D"(E,)`2)%"3H!^W_ +XM_X7`B<CJ!`B+ +XM0@B#Z`&%P(E""`^(;P$``(L"Q@`*@\`!B0*+0QB)!"3H*Q```,<$)*#4!`CH +XMD^K__XM%\(D\)(E$)`3H-.S__XM-Z(G"B<:)V.BR\___H1SK!`B%P`^%1?__ +XM_X7V#X0]____B5PD!,=$)`@$````B3PDZ#WK__^)/"3HE>O__X7`B<,/A2G_ +XM___HENS__XL`A<`/A?T```"#Q!Q;7E]=PV:#^`1T"F:#^`O__XE$)`B+0T#'!"1&U`0(B40D!.@2[/__QP4XZP0(`0```.F__O__ +XMBT-`QP0D@]0$"(E$)`3H\.O__^FG_O__C;0F`````(-][`$/CB?___^+0QB) +XM!"3H.P\``,<$)*#4!`CHH^G__\<%/.L$"`$```#I`?___Z$$[`0(A<`/A5;^ +XM___V1>@(QT7P``$```^%4O[__^E`_O__H>CJ!`C'!"0*````B40D!.C\Z?__ +XMZ:W^__^A#.L$"(7`#X0F_O__Z6#^__^)5"0$QP0D"@```.A5[/__D.F%_O__ +XMQT0D!*+4!`C'!"0!````Z'OL___'1"0$>M0$",<$)`$```#H9^S__XUV`(U, +XM)`2#Y/#_575E-1@>PH!@``BQF+202-A>#]__^)1>C'1"0$*]<$",<$ +XM)`````")C=SY___H1>S__\<$)`$```#H*>S__X7`#X24````QP5\Z`0(4``` +XM`,<$)*O4!`CH^^C__X7`=`F`.``/A=@'``"-1>")1"0(QT0D!&AT"$#'!"0! +XM````Z)/I__^#P`%T$0^W1>)FA +XM``#KS\<%).L$"`$```#'!"2KU`0(Z&?H__^%P'2PB00DZ!OH__^C?.@$".NA +XM_R2%:-4$"(L5#.L$"(L]].H$"(72#X1X!0``QP0DL]0$".@MZ/__AO__X7`#X2D`0``QP0DR]0$".@)Z/__B40D!(V%X/G__XD$).A7 +XMZO__@^@!#X0B!@``H1CL!`B%P'1&QP44[`0(`0```,=$)`30KP0(QP0D`@`` +XM`.@WZO__QT0D!-"O!`C'!"0#````Z"/J___'!"3?U`0(Z*?G__^)!"3H*P@` +XM`*$\[`0(A<`/A,8```"A0.P$"(7`=1B+%0CK!`B%TG4.BPTL[`0(ASK!`@`````Z5/\___'!1SL +XM!`@!````Z43\___'!3#K!`@!````QP4LZP0(`````.DK_/__QP4GO^___QT0D"`$```#'1"0$*]<$",<$)+/4!`CH$>?__^G.^___QP40[`0( +XM`0```,<%+.P$"`$```#IM?O__\<%..P$"`$```#IIOO__\<%&.L$"`$```#I +XME_O__\<%*.L$"`$```#'!23K!`@`````QP5`[`0(`````.ET^___QP5`[`0( +XM`0```,<%).L$"`````#'!2CK!`@`````Z5'[___'!?CK!`@`````QP4$ZP0( +XM`0```.DX^___QP4\[`0(`0```.DI^___QP7XZP0(`0```.D:^___QP44ZP0( +XM`0```.D+^___QP4(ZP0(`0```,<%'.L$"`````#I\OK__\<%Z.L$"`$```#' +XM!0#L!`@`````QP4T[`0(`````.G/^O__QP4([`0(`````,<%(.P$"`````#' +XM!>SK!`@!````Z:SZ___'!03L!`@!````Z9WZ___'!33K!`@!````Z8[Z___' +XM!33L!`@!````QP4`[`0(`````,<%Z.L$"`````#I:_K__XGQNH#H!`BX`0`` +XM`.@$]___Z2K\__^A0.P$"(7`#X2M````QP7\Z@0(X+X$".GT^___H2SK!`B% +XMP'5&BPTPZP0(AS' +XM1"0$#.P$"(D$).C.Y/__BQ4,[`0(B=#!^!_!Z!CZ___'!0#K!`B@EP0(Z=GZ__^#S@'I:OK__\<%_.H$"&"Z +XM!`CIV?K__XU-Z(E,)`3'!"30U`0(Z&GE___'!"33U`0(H_#K!`B-1>B)1"0$ +XMZ%'E__^-3>B)3"0$QP0DUM0$"*,H[`0(Z#GE___'!"39U`0(HT3L!`B-1>B) +XM1"0$Z"'E__^-3>B)3"0$QP0DW-0$"*,D[`0(Z`GE__^%P*/\ZP0(#X30```` +XMH?#K!`B%P`^$4?G__Z$H[`0(A<`/A$3Y__^A_.L$"(7`#X0W^?__QP48[`0( +XM`0```.DQ^?__B00DZ,[@___'!0CL!`@!````HWSH!`CI1_C__Z$T[`0(A6#[!B%P'0]H?SK!`C'1"0($+`$ +XM",=$)`0!````B00DZ/WA__^X$+`$"(E$)`BA1.P$",=$)`0!````B00DZ-_A +XM___)PZ'\ZP0(QT0D"""U!`C'1"0$`0```(D$).C`X?__N""U!`CKP9"-="8` +XM58GE4X/L%(M="(G8Z'____^)'"3'1"0$`````.@SXO__Z"[C__^)7"0$B00D +XMZ,+?__^#Q!1;7<.0C;0F`````%6)Y8/L*(M%",=$)`@!````QP0D`0```(A% +XM_XU%_XE$)`3H;=___S'`R<.0C70F`%6)Y5=64X/L+(M%"(7`#X1``0``BT4( +XM,?^)!"3HT^+__XL5O-<$"&;'1=H``,=%W`````")5>")1=3K/(UT)@`/OL*# +XMZ#")`V:#?=H`#X2N````9L=%V@$`@\8!@\,$@_X"=46#QP=P,@T7@`H/_ +XM"P^$U````(M%W,>`:.L$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.- +XM!'\Q]HT3J!`A]#*'LZ@0(BXR( +XM-`0``(/Y>'03#[["B40D!,<$))#7!`CH\]___\<#_____^D-____@\0L6UY? +XM7564XG#C31`@^P0BQ2U:.L$"(72#X64````BP2U +XM8.L$"(/X_W0XB40D"*'PZP0(QT0D!`````")!"3H`][__X7`=!O'1"0((+4$ +XM",=$)`0!````B00DZ(??__^-=@"-!%N+!(5DZP0(@_C_=#6)1"0(H2CL!`C' +XM1"0$`````(D$).B\W?__A7<.0C70F`*$D[`0(QT0D"""U!`C'1"0$`0```(D$).@7W___Z4K___^- +XMM"8`````C;PG``````^WP(G"58'B`/```(GE@^P(@?H`0```#X3&````?E&! +XM^@"@```/A'T```"!^@#```!T8H'Z`&````^$?````#'2J$ET7_;$"`^%X@`` +XM`/;$!`^$MP```+@(````C70F`.B[_O__N@$```#K.(UT)@"!^@`0``!T6('Z +XM`"```(GV=;VX!@```.B4_O__N@$```#)B=##N`(```#H@?[__[H!````R8G0 +XMP[@!````Z&[^__^Z`0```,F)T,.X!0```.A;_O__N@$```#)B=##B?:X`P`` +XM`.A&_O__N@$```#)B=##J`)T./;$`G01N`D```#H*O[__[H!````ZZ>X"@`` +XM`.@9_O__N@$```#KEK@$````Z`C^__^Z`0```.N%,<#H^OW__[H!````Z73_ +XM__^X!P```.CF_?__N@$```"0Z5____^-="8`C;PG`````%6)Y5.#[&2)1:BA +XMD.@$"(7`#XC9````H43K!`B%P`^$L@```*$<[`0(A\`.=!_ +XM'8L-D.@$"+NVU@0(A-M"8`````C8(`\>\`.<%]V:&0Z`0( +XMNZ+6!`B%P`^%=/___[NLU@0(Z6K____'!"0`````Z-+:__^C1.L$".DX____ +XMC70F`,<$)#D```#H:-W__X`X9`^4P`^VP*.0Z`0(Z0C___^0BQ4@[`0(58GE +XMBT4(A=)U"HL-[.L$"(7)=`F)10A=Z;T7``"+%0CL!`B%TG0)B44(7>E:$@`` +XMB44(7>EA%0``D%6)Y8/L"*'@Z@0(BTT(A"*+`H@(@\`!B0+),<##H>CJ!`B)#"2)1"0$Z)':__\QP,G#.T(8?`:`^0J0 +XM==.)5"0$B0PDZ/;<___KSE6)Y8/L"(L-$.P$"(7)=!`E`/```#T`0```='3) +XM,<##B<*!X@#P``"!^@"@```/A-\````/AXP```"!^@`0```/A%,!``"!^@!` +XM``"-="8`=#ZH273&H>#J!`B%P`^%AP$``(L5Z.H$"(M""(/H`87`B4((#XAX +XM`@``BP+&`"J#P`&)`K@!````R<.0C70F`(L5X.H$"(72#X6J````BQ7HZ@0( +XMBT((@^@!A<")0@@/B!4!``"+`L8`+X/``8D"N`$```#)PX'Z`,````^$D@`` +XM`('Z`.````^%=/___Z'@Z@0(A<`/A9CJ!`B+0@B#Z`&%P(E""`^( +XM8`$``(L"Q@`E@\`!B0*X`0```,G#H>#J!`B%P`^%?@$``(L5Z.H$"(M""(/H +XM`87`B4((#XC/````BP+&`$"#P`&)`K@!````R<.AZ.H$",<$)"\```")1"0$ +XMZ!?9__^X`0```,G#H>#J!`B%P`^%90$``(L5Z.H$"(M""(/H`87`B4((#XBZ +XM````BP+&`#V#P`&)`K@!````R<.AX.H$"(7`#X44`0``BQ7HZ@0(BT((@^@! +XMA<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8#XWB_O__B50D!,<$)"\```#H +XM$=O__[@!````R<.AZ.H$",<$)"H```")1"0$Z'78__^X`0```,G#.T(8#XTH +XM____B50D!,<$)$````#HU=K__[@!````R<,[0AA]CHE4)`3'!"1\````Z+G: +XM__^X`0```,G#.T(8#XT]____B50D!,<$)#T```#HF=K__[@!````R<,[0A@/ +XMC9?^__^)5"0$QP0D)0```.AYVO__N`$```#)PZ'HZ@0(QP0D)0```(E$)`3H +XMW=?__[@!````R<.AZ.H$",<$)$````")1"0$Z,'7__^X`0```,G#H>CJ!`C' +XM!"1\````B40D!.BEU___N`$```#)PZ'HZ@0(QP0D/0```(E$)`3HB=?__[@! +XM````R<,[0A@/C7_]__^)5"0$QP0D*@```.CIV?__N`$```#)PXVT)@````"- +XMO"<`````58GE@^PXB5WTB<.)??R)SXEU^(MP/*$\[`0(QT7L`````(7`#X7> +XM````H?3K!`B%P'5RH1CL!`B%P'1)#[=&".B;^?__B<>+0T")!"3H[OO__XM- +XM[(T<"*$8[`0(AQ=PXM#0(D$).BP^___BU7LC1P0Z\F%_W3%,<#H'?;__^N\H0SL!`B#Z`&) +XMPL'Z'XE%X(E5Y(M&.(M6/`%%X*$,[`0($57DBTWDB<+!^A^)5"0,BU7@B4PD +XM!(E$)`B)%"3HF!@``(E\)`3'!"04UP0(B40D"(E4)`SH--C__P%%[.DK____ +XMBT8$B50D!,<$),S6!`B)1"0(Z!78__^)1>SI`____XGVC;PG`````%6)Y593 +XM@^P0BW4(BQZ%VW4FZUR+%>CJ!`B+0@B#Z`&%P(E""'A0BP+&``J#P`&)`HM; +XM"(7;=#B#>PP!=/.+3A2)V(M6).B&_O__H>#J!`B%P'3`H>CJ!`C'!"0*```` +XMB40D!.B\U?__BUL(A=MUR(/$$%M>7<.)5"0$QP0D"@```.@>V/__ZZB0C;0F +XM`````%6)Y5=64X/L/(M%"(,]%.P$"`$9TH/B!X/"`8E%T(E5Z(M`##L%C.@$ +XM"`^/O@(``(M=T(L#QT7<`````(7`=!^+%4#K!`B#>`P!=`R+3=R)!(J#P0&) +XM3=R+0`B%P'7GH3SL!`B+7="%P(M3$'0(BT,D@\`!`<*+#?3K!`B%R70+BUW0 +XMBT,4@\`!`<*#/2SL!`@!BT7H@]K_`U7H]]B)1=0APHE5\(M%\(L5?.@$"`'` +XM.=`/CR0"``")T,'Z'_=]\(M5W(E%S(G0P?H?]WW,@_H!BU70@]C_B47@BP*% +XMP`^$N0$``&:#>#(`#X6N`0``BW7@A?8/CG(!``#'1=@`````QT7D`````(L= +XM,.P$"(7;=0:+5>2)5=B+3P/C:D```"+%>#J +XM!`B%TG5.BPWHZ@0(@ST4[`0(`8M!"!G2@^+I@\(@@^@!A<")00AX48L!B=Z( +XM$(/``8D!BU7HC1P6(UW4.?M^IHM-S#E-['1=@T7L`0-]\.E*____@ST4[`0( +XM`8G>BQ7HZ@0(&<"#X.F#P"")5"0$B00DZ(S3___KNCM!&'P%@/H*=:6)3"0$ +XMB=Z)%"3H\M7__^N@BU7@`578BTW<.4W8#XPR____H>#J!`B%P'4UBQ7HZ@0( +XMBT((@^@!A<")0@AX.8L"Q@`*@\`!B0*#1>0!BUW@.5WD#X6<_O__@\0\6UY? +XM7<.AZ.H$",<$)`H```")1"0$Z`O3___KT8E4)`3'!"0*````Z'G5___KOXL] +XM0.P$"(7_=0B%R0^$0/[__XM-T(L=#.P$"(M1!,<$)-+6!`B#Z@&-#!HQTHG( +XM]_.)1"0$Z)W4___I$_[__XM5T(E5"(/$/%M>7UWI@OS__\'@`HE$)`2A0.L$ +XM"(D$).ART___A<")PG06BTW0BT$,B15`ZP0(HXSH!`CI$OW__\<$)`````#H +XM>M3__XM=T(E=".NPC;0F`````(V\)P````!5B>575E.#[`R+=0B+'H7;#X2^ +XM````,?_K'(VV`````,<$)-W6!`B#QP+H!=3__XM;"(7;='2#>PP!=/.+0T") +XM!"3H3=7__X-["`$9TO?2@^("C00'`=`[!7SH!`AR,:'@Z@0(A+0PB%P`^%=O___X7_=":AX.H$"(7`=3Z+%>CJ!`B+0@B#Z`&%P(E" +XM"'A?BP+&``J#P`&)`H/$#%M>7UW#H>CJ!`@Q_\<$)`H```")1"0$Z&'1___K +XMFZ'HZ@0(QP0D"@```(E$)`3H2M'__X/$#%M>7UW#B50D!#'_QP0D"@```.BP +XMT___Z6?___^)5"0$QP0D"@```.B;T___ZYF0C70F`%6)Y5=64X'L7`@``(M% +XM"(LXA?\/A#,#``!F@W\R``^%*`,``,>%Q/?__P````#'A%T/?__P$```"# +XMZ`$/A+\%``")'"3H-=/__\>%R/?__P$```"-M"8`````BP:)A+\__\/ML2)5"0(B40D +XM!,<$)`?7!`CH.K^__\/C)````#'A8KZ0SZ +XM__^)5"0$QP0D"@```.B9S/__Z;3[___HS\O__X,X%@^$8O___XV=V_O__XE< +XM)`3'!"1*U`0(Z`#,___IY_G__X.]T/?__P,/CL'Y___KJI"0D)"0D)"058GE +XM@^P8H?#J!`C'1"0(/@```,=$)`0!````QP0DP-<$"(E$)`SH"A?]UIXN%8/___X'$K``` +XM`%M>7UW#C;8`````BX5@____C028B85@____Z]*)%"3H"\G__^NZD(UT)@"- +XMA7#___^#Q@&#A6#___\$@^\!QT0D"(````#'1"0$`````(D$).A)RO__ZYB+ +XMA6#___^-!+B)A6#____KBXGV58GE5U93@>RL````C85P____QT0D"(````#' +XM1"0$`````(D$).@*RO__QX5@____`````(M5"(V%'>+`H@(@\`!B0*#Q@$Y]W0HH>#J +XM!`B%P'3-H>CJ!`B+50B)1"0$#[8$%H/&`8D$).B4Q___.?=UV(M=\#'`A=MT +XM*('[_P````^'@0$``*'LZ@0(BT28-(G"@>(```#@#X18`0``B=#!Z!X!?0@! +XMA6#____I`?___SM"&`^VV7P)@/L*#X5X____B50D!(D<).BTR?__Z7#___^+ +XM%>#J!`B%T@^%F@```(L5Z.H$"(M""(/H`87`B4((#X@=`0``BP+&`#^#P`&) +XM`@%]"(.%8/___P'IH?[__XL=X.H$"(7;#X6]````BQ7HZ@0(BT((@^@!A<") +XM0@@/B/T```"+`L8`/X/``8D"C95P____@T4(`8.%8/___P''1"0(@````,=$ +XM)`0`````B10DZ$G(___I1/[__XD<).C,QO__Z9+^__^AZ.H$",<$)#\```") +XM1"0$Z'+&___I;?___XL-X.H$"(7)#X6N````BQ7HZ@0(BT((@^@!A<")0@@/ +XMB+$```"+`L8`/X/``8D"@X5@____`8N%8/___X'$K````%M>7UW#H>CJ!`C' +XM!"0_````B40D!.@1QO__Z4K___\E```$`(/X`1G`@\@!Z9O^__^)'"3H,L;_ +XM_^E[_O__.T(8#XW:_O__B50D!,<$)#\```#H5,C__^G/_O__.T(8#XWZ_O__ +XMB50D!,<$)#\```#H-LC__^GO_O__H>CJ!`C'!"0_````B40D!.B%8/___P````"+ +XM50B-A7#___^)1"0,C47PQT0D"`8```")!"2)5"0$Z+S$__^%P(GR`0`` +XM@_[^#X10`0``@_[_B?8/A.P````QVX7V?S2-="8`ZU>+10B+%>CJ!`@/M@P# +XMBT((@^@!A<")0@@/B)0```"+`H@(@\`!B0*#PP$YWG0IBSW@Z@0(A?]TR*'H +XMZ@0(BU4(B40D!`^V!!.#PP&)!"3HG\3__SG>==>+7?`!=0B!^_\```!W<*'L +XMZ@0(BT28-*D```0`#X0Y____,<"%VW0H@?O_````#X?J````H>SJ!`B+1)@T +XMB<*!X@```.`/A,$```")T,'H'@&%8/___^D`____.T(8#[;Y?`J)^#P*#X5: +XM____B50D!(D\).BBQO__Z5+___^)'"3H5<3__Y#KCHV%XM%"(L5Z.H$"`^V"(M""(/H`87` +XMB4((>'N+`H@(@\`!B0*#10@!@X5@____`>EY_O__BU4(QP0D2M0$"(E4)`3H +XMAL7__P&%8/___XN%8/___X'$K````%M>7UW#)0``!`"#^`$9P(/(`>DR____ +XMB1PDZ+7#___I$O___Z'HZ@0(BU4(B40D!`^V`HD$).A9P___ZXX[0A@/MME\ +XM"8#["@^%=/___XE4)`2)'"3HNL7__^EL____D%6)Y5=64X'LK````(V%%8/___P````"+50B-A7#___^) +XM1"0,C47PQT0D"`8```")!"2)5"0$Z'S"__^%P(F%7/___P^$;@,``(N%7/__ +XM_X/``H/X`0^&`0$``(M=\('[_P````^'D`,``*'LZ@0(BT28-*D```0`#X0$ +XM`P``@_LB#X3[`@``@_M<#X3R`@``B[U<____A?]^9C';ZS*+10B+%>CJ!`@/ +XMM@P#BT((@^@!A<")0@@/B!L#``"+`H@(@\`!B0*#PP$[G5S___]T+8LUX.H$ +XM"(7V=,2AZ.H$"(M5"(E$)`0/M@03@\,!B00DZ"+"__\[G5S___]UTXM=\#'` +XMA=MT*('[_P````^'N0,``*'LZ@0(BT28-(G"@>(```#@#X2*`P``B=#!Z!X! +XMA6#___^#O5S____^#X1V`@``@[U<_____P^$N@(``(N57/___P%5".F[_O__ +XM@[U<_____P^%7P(``+\!````,?;IV````(L5Z.H$"(M""(/H`87`B4((#XB7 +XM`0``BP+&`%R#P`&)`J'@Z@0(A<`/A>````"+%>CJ!`B)V,#H!@^VP(U(,(M" +XM"(/H`87`B4((#X@^`0``BP*("(/``8D"H>#J!`B%P`^%V````(L5Z.H$"(G8 +XMP.@#@^`'C4@PBT((@^@!A<")0@@/B$8!``"+`H@(@\`!B0*AX.H$"(7`#X70 +XM````BQ7HZ@0(B=B#X`>-2#"+0@B#Z`&%P(E""`^(,0$``(L"B`B#P`&)`H/& +XM`8.%8/___P0Y_@^-Y_[__Z'@Z@0(BU4(A<`/MAP6#X04____H>CJ!`C'!"1< +XM````B40D!.BAP/__H>#J!`B%P`^$(/___Z'HZ@0(B40D!(G8P.@&#[;`@\`P +XMB00DZ'C`__^AX.H$"(7`#X0O____C;0F`````*'HZ@0(B40D!(G8P.@#@^`' +XM@\`PB00DZ$C`__^AX.H$"(7`#X0W____C;0F`````*'HZ@0(B40D!(G8@^`' +XM@\`PB00DZ!O`___I.O___XGV.T(8?`F`^0H/A;3^__^)5"0$B0PDZ'K"___I +XMK/[__Y`[0A@/C6#^__^)5"0$QP0D7````.A;PO__Z57^__^)]CM"&'P)@/D* +XM#X6L_O__B50D!(D,).@ZPO__Z:3^__^0.T(8?`F`^0H/A<'^__^)5"0$B0PD +XMZ!K"___IN?[__XL-[.L$"(7)=!"%VW@,@?O_````#XZ3````B[U<____A?\/ +XMC\3]__^#O5S____^#X6*_?__BX5@____@<2L````6UY?7<.+10B)!"3HA,+_ +XM_XG'Z\L[0A@/MO%\"HGP/`H/A=/\__^)5"0$B30DZ*+!___IR_S__XD<).A5 +XMO___D.EK_/__C85P____QT0D"(````#'1"0$`````(D$).BAP/__@T4(`>GH +XM^___#[[#B40D!,<$)/_7!`CH%<#__X7`B<,/A%#___^+%>#J!`B%T@^%E0`` +XM`(L5Z.H$"(M""(/H`87`B4((#XBR````BP+&`%R#P`&)`J'@Z@0(ACJ!`C'!"1<````B40D!.@3OO__Z7+___\[41A\ +XM!SP*C78`=8F)3"0$B1PDZ';`___KA#M"&`^-1?___XE4)`3'!"1<````Z%O` +XM___I.O___Y"058GE5U:#[#"+50R+10B+=1"+?12)5=R+3=R)1=C'1=`````` +XMB?#'1=0`````B?J%R<=%Y``````/B*0```"%_P^(N@```(G7B<:+5=B)P8M% +XMW(7_B57PB47L=10YQG9!B="+5>SW]HG!,<#K$XUV`#M]['9/,R)^O?QB<:+1?#W\8G!B?#KO`^]QX/P'XE%Z'5$.7WL=P4Y=?!R +XMG+D!````,<#KGO==V(-5W`#W7=R%_\=%Y/____\/B4O___^0C70F`(GPB?KW +XMV(/2`/?:]U7DZ3/___^X(````(GR*T7HB<'3Z@^V3>B)1?2)^(G7BU7LT^`) +XMQXM%\-/F#[9-]-/H#[9-Z-/B#[9-]`G0BU7LB47,T^KW]XE5S(G']^8Y5'`@)`!, +XM4U]#3TQ724142%,`;6%L;&]C`"5S.B`EC!`@^HP0(D:D$""VG +XM!`@MIP0(+:<$""VG!`@MIP0(+:<$""VG!`@MIP0(+:<$""VG!`@MIP0(+:<$ +XM""VG!`@MIP0(+:<$"%^I!`ANJ00(S:D$""VG!`@MIP0(M*D$"!>K!`@/JP0( +XM`*L$""VG!`@MIP0(]:H$""VG!`@MIP0(+:<$".JJ!`@MIP0(VZH$",*J!`BS +XMJ@0(>*P$""VG!`AIK`0(+:<$""VG!`A:K`0(+:<$""VG!`@MIP0(+:<$""VG +XM!`@MIP0(7*D$"#>L!`@4K`0(^ZL$""VG!`CLJP0(!J<$"-VK!`C.JP0(+:<$ +XM"+6K!`B2JP0(;ZL$"&"K!`A1JP0(.*L$")"J!`B!J@0("4P +XM.'@@`"4S9"P@)3-D(``E*G,E*FID(``E-7,@``IL&1X8GAE9V5D86)A9V%C860`3%-#3TQ/4E,@I$$"(J1 +XM!`B:D00(JI$$"+J1!`C*D00(VI$$".J1!`CZD00("I($"!J2!`@JD@0(.I($ +XM"$J2!`A:D@0(:I($"'J2!`B*D@0(FI($"*J2!`BZD@0(RI($"-J2!`CJD@0( +XM^I($"`J3!`@:DP0(*I,$"#J3!`A*DP0(6I,$"&J3!`AZDP0(```````````` +XM)$9R965"4T0Z('-R8R]L:6(O8W-U+V-O;6UO;B]C'`@)`!'0T,Z("A'3E4I(#0N +XM,BXQ(#(P,#6YA;6EC`"YC=&]Rps.uu << 'END-of-ps.uu' +Xbegin 755 ps +XM?T5,1@$!`0D```````````(``P`!````T)0$"#0````(>````````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(!&`` +XM``1@```%`````!````$````@8```(/`$""#P!`BX$P``C"````8`````$``` +XM`@```+QQ``"\`04(O`$%"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&3H7P``Z-\$".C?!`@<````'`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`0P```%L````*````50```!,````O````1@```%0````L```` +XM/0```#L`````````1P```!H```!#````00`````````Q````3P`````````+ +XM`````````!0```!:````3@````````!)`````````!@````N````)P```$H` +XM``!6`````````#8````_`````````!<`````````4````"D`````````4P`` +XM`%D``````````````!$```!8`````````#<````A````-````!\````K```` +XM````````````````2P```%$``````````````$0`````````30```$4````` +XM````,P```%<````````````````````````````````````````````````` +XM```````````````````%````````````````````````````````````#@`` +XM``````````````````P````&````"``````````2```````````````-```` +XM`````!P````````````````````````````````````B`````````"0````' +XM`````````"H``````````````!D````6````!````"4````F````#P`````` +XM```!`````````!X`````````&P```#`````0````.@```#(````````````` +XM`"T`````````````````````````'0```"`````C````-0```#D````H```` +XM`````#X````\`````@```$P````)````2`````````!````````````````X +XM````%0```%(```!"`````P````````````````````````"U`0```````#0` +XM```2````OP(````````S````$@```*$"````````0P```!(```"F`0`````` +XM`&$````2````6P$`````````````$@```(H"````````*@```!(```#L```` +XM`````&L!```2````$`$```````#]"```$@```#,```"\`04(`````!$`\?\Z +XM`@```````)@````2````0@(```````"A````$@````0!````````?P```!(` +XM``!?`@```````!T````2````\P$`````````````$@````,"````````6@`` +XM`!(```#C`````````!T````2````T@(````````S````$@```,4````````` +XM`````!(```#L`@```````.T````2````G0(```````#G`0``$@```"@"```` +XM````!0```!(````\````=)$$"#D````2````^P$```````#=`P``$@```$@` +XM```0D`0(`````!(`"@"8`0``(*\$"$8````2``P`00$````````N````$@`` +XM`!X"````````,P$``!(```#+```````````````2````I@````````"C```` +XM$@```*T!``!X$`4(!````!$`%P#[`````````#T````2````Y0(````````` +XM````$@```-(`````````Q@0``!(````*`@``V`,%"`0````1`!<`8@$````` +XM```5`@``$@`````#````````G@```!(````7`@```````&4"```2````G@$` +XM````````````$@```-@!```@\`0(!````!$`$`"_`````````"T````2```` +XML0(`````````````$@```%0!``#<`P4(!````!$`%P"%`0``X`,%"%0,```1 +XM`!<`3@(```````#,````$@```'X!````````'0(``!(```#C`0```````!8` +XM```2````3@`````````+````$@```+8"````````'0```!(```!'`@`````` +XM```````2````M@$````````Y````$@```,0"````````[0```!(````4`P`` +XMV`,%"``````0`/'_V@````````#?````$@```/L"````````00```!(````+ +XM```````````````2````E@(```````!?````$@```/,`````````;0```!(` +XM``!9````+-8$"``````2``T`Q0$```````",`@``$@```%8"````````'0`` +XM`!(```"U````-!`%"`0````1`!<`#P``````````````$@```*8"```````` +XM30$``!(```!?````=),$""8"```2````,@(```````#+````$@```!8!```` +XM````+0```!(```!H`@````````,!```2`````(````` +XM``"\````$@```'$"````````*P```!(```#>`@`````````````2````@0`` +XM``````"V````$@```*X``````````````!(````3```````````````@```` +XM:0(```````"\````$@```'(!````````&````!(```!J`0```````)<````2 +XM````CP````````!J!```$@```.L!````````1````!(`````;&EB;2YS;RXU +XM`&QO9P!E>'``7TIV7U)E9VES=&5R0VQA7-C;VYF`'-N<')I;G1F`&=E=&=R9VED +XM`&=E=&5N=@!B6YA +XM;64`9V5T<'=U:60`9V5T<'=N86T`87-P&ET`'-T7-C=&QB +XM>6YA;64`7V5D871A`%]?8G-S7W-T87)T`%]E;F0`1D)31%\Q+C`````"``(` +XM`@`"``(``@`"``(``0`"``(``@`"``(``@`"``(``@`"``(``@````(``0`! +XM``(``@`"``(``0`"``(``@`"``(``@`"``(``0`"``(``@`"``(``@`"```` +XM`@`"``(``@`!``(``@`#``(``@`!``(``@`"``,``@````(``@`"``(``@`" +XM``$``@`!``$``@`"``(``@`"``(``@`"`````@````(``@`"`````@`!``$` +XM`0```!`````@````L"AZ!P```P`E`P````````$``0"<````$`````````"P +XM*'H'```"`"4#````````V`,%"`4B``#<`P4(!2H``.`#!0@%*P``-!`%"`4] +XM```X$`4(!4P``#P0!0@%3@``M`(%"`0"!0AH8````.D@_____R7H`@4(:&@` +XM``#I$/____\E[`(%"&AP````Z0#_____)?`"!0AH>````.GP_O___R7T`@4( +XM:(````#IX/[___\E^`(%"&B(````Z=#^____)?P"!0AHD````.G`_O___R4` +XM`P4(:)@```#IL/[___\E!`,%"&B@````Z:#^____)0@#!0AHJ````.F0_O__ +XM_R4,`P4(:+````#I@/[___\E$`,%"&BX````Z7#^____)10#!0AHP````.E@ +XM_O___R48`P4(:,@```#I4/[___\E'`,%"&C0````Z4#^____)2`#!0AHV``` +XM`.DP_O___R4D`P4(:.````#I(/[___\E*`,%"&CH````Z1#^____)2P#!0AH +XM\````.D`_O___R4P`P4(:/@```#I\/W___\E-`,%"&@``0``Z>#]____)3@# +XM!0AH"`$``.G0_?___R4\`P4(:!`!``#IP/W___\E0`,%"&@8`0``Z;#]____ +XM)40#!0AH(`$``.F@_?___R5(`P4(:"@!``#ID/W___\E3`,%"&@P`0``Z8#] +XM____)5`#!0AH.`$``.EP_?___R54`P4(:$`!``#I8/W___\E6`,%"&A(`0`` +XMZ5#]____)5P#!0AH4`$``.E`_?___R5@`P4(:%@!``#I,/W___\E9`,%"&A@ +XM`0``Z2#]____)6@#!0AH:`$``.D0_?___R5L`P4(:'`!``#I`/W___\E<`,% +XM"&AX`0``Z?#\____)70#!0AH@`$``.G@_/___R5X`P4(:(@!``#IT/S___\E +XM?`,%"&B0`0``Z<#\____)8`#!0AHF`$``.FP_/___R6$`P4(:*`!``#IH/S_ +XM__\EB`,%"&BH`0``Z9#\____)8P#!0AHL`$``.F`_/___R60`P4(:+@!``#I +XM!`% +XM"'XVBT4(AL*#[80@\`!A-)T%(#Z+W7QHR#P +XM!`@/MA"#P`&$TG7LN+P!!0B%P'0TB0PDZ/_^___'!"0LU@0(Z//^___HROK_ +XM_XU%"(ET)`B)1"0$B1PDZ'`2#P`2)1?"%_P^$A0```(`_ +XM`'3GBQU($`4(*?''1"0,$@```(D\)(/K`0'+Z/[]___!ZP*)PHG8.=-V`HG0 +XMB40D"(E\)`2)-"3H,?[__X`^`'0(@\8!@#X`=?B+#400!0BA2!`%"(G*@^@! +XM*?(!T(/X`W:'Q@8@BT7P@\8!BPU$$`4(BW@$@\`$B47PA?\/A7O___\Y\8E- +XM['0+,<"`?O\@#Y3`*<;&!@"+5>R)%"3H>_W__XM5$(U$`@2)!"3H[/S__X7` +XMB<8/A`\!``"+1>R%P`^$E````(M%"(L8QT0D!"\```")'"3H,OO__X7`=`.- +XM6`&+51"+10R)'"2)5"0(B40D!.C5^?__A7UW#BT7LB30DB40D!.@#_?__ +XMZ^6+30RXSML$"(7)=-N+11#'1>P`````@\`#Z4____^+10R+51#'1"0$J]8$ +XM"(DT)(E$)`R)5"0(Z-7\___KI\<$)`$```#H1_K__X/X_W1G/?[__Q]_3(T$ +XMA0$```"C2!`%"(D$).CW^___A<")1>RC1!`%"'08BU4(BSJ%_P^%&?[__XM% +XM[,8``.G-_O__QT0D!)W6!`C'!"0!````Z(_Y___'1"0$O-8$",<$)`$```#H +XM>_G__\=$)`2"U@0(QP0D`0```.AG^?__D)"058GEBT4,BP")10R+10B+`(E% +XM"%WI:_K__XVT)@````!5B>575E.#[!R+'4#P!`B`.P!T8\=%\`````"_SML$ +XM"#'VB1PDZ,K[__^+%:@0!0B%TG07UW#D(UT)@!5B>575E.#[$R+10B)!"3H$/C__XE% +XMO(E%\(VV`````(M=\(7;#X3P````@#L`#X3G````QT0D!.K6!`B)'"3H`/O_ +XM_X`\`ST/A>D```#'1?``````QT0D!#T```")'"3HG_C__X7`B<9T!L8``(/& +XM`8U5Q(E=Q,=$)!`PF`0(QT0D#"P```#'1"0(60```,=$)`1`\`0(B10DZ*7Y +XM__^%P(G'#X3)````BT`(A<`/A/H```"%]@^$H@```(D$).B@^O__B30DB7<.)]HV\)P````!5B>53 +XM@^PDBT4,BU@(C47TQT7X`````(D$).BE]O__@\`!='^+1?2)1"0$BU4(BP*+ +XM0"B)!"3H>?/__X7`=$&+1?2)!"3HNO3__XM%^(7`=&6)1"0(#[]#&,<$)(': +XM!`B)1"0$Z(OU__^+1?B)!"3HP/;__X/$)%M=PXVV`````(U%^(E$)`2+1?2) +XM!"3HPO/__X/``0^4P`^VP(/H`2%%^.N6#[!B+10S'1"0(B-H$"(M`"`^_0!C'!"2*V@0( +XMB40D!.BL]/__R<.-M@````!5B>6#[!B+10R+30B+4`@QP(-Y#`!T"(L!BX`T +XM`@``B40D"`^_0AC'!"2.V@0(B40D!.AM]/__R<.-M"8`````58GE@^P8BT4( +XMBP"+@.````#!Z`J)1"0(BT4,BT`(#[]`&,<$))/:!`B)1"0$Z#+T___)PXVV +XM`````(V_`````%6)Y8/L&(M%#(M("(M%"(L`BU`DA=)T2("X2P$```!T(P^_ +XM41@%2P$``(E$)`R)5"0(B50D!,<$))C:!`CHXO/__\G#B50D"`^_01C'!"2? +XMV@0(B40D!.C(\___R<.)]O:`+`$```1T,H"X9@$```!T"P^_41@%9@$``.NM +XMQT0D"*7:!`@/OT$8QP0D@=H$"(E$)`3HB_/__\G#QT0D"(C:!`@/OT$8QP0D +XM@=H$"(E$)`3H;?/__\G#C;0F`````%6)Y8/L&(M%#(M0"(M%"(L`BT`DA6#[!B+10R+4`B+10B+`/:`+`$```1T2H"X9@$```!T(P^_4A@% +XM9@$``(E$)`S'!"28V@0(B50D"(E4)`3H4/+__\G#QT0D"*7:!`@/OT(8QP0D +XM@=H$"(E$)`3H,O+__\G#QT0D"(C:!`@/OT(8QP0D@=H$"(E$)`3H%/+__\G# +XMC;0F`````(V\)P````!5B>6#[!B+10B+``^V@`\"``"#Z%2)1"0(BT4,BT`( +XM#[]`&,<$)*_:!`B)1"0$Z-'Q___)PXUT)@"-O"<`````58GE@^P8BT4(BP`/ +XMMH`-`@``@^A4B40D"(M%#(M`"`^_0!C'!"2OV@0(B40D!.B1\?__R<.-="8` +XMC;PG`````%6)Y593@^P@BT4,BW`(BT4(BPB`N30!```'BYDH`0``BY'\`@`` +XM#X:X````QD7H/_?#````$(U5Z74'QD7I5XU5ZH"Y-0$````/C*,```!^!L8" +XM3H/"`?;'"'0&Q@)8@\(!]L<@=`^`N30!```%=`;&`D6#P@'VPQ!T!L8"5H/" +XM`?;'`G4)@+DV`0```'X&Q@),@\(!]H$L`0```G0&Q@)S@\(!]L,"=`B+03`[ +XM031T3X'C`````70&Q@)*@\(!C47HQ@(`B40D"`^_1AC'!"2!V@0(B40D!.BG +XM\/__@\0@6UY=PP^V@30!``#_)(58VP0(Q@(\@\(!Z5K___^-=@#&`BN#P@'K +XMJ<9%Z%KI'____\9%Z%?I%O___\9%Z$R)]ND+____@^((="F#N00!```4&<"# +XMX`J#P$F(1>CI[_[__\9%Z%3IYO[__\9%Z%+IW?[__\9%Z$3IU/[__XUT)@!5 +XMNHC:!`B)Y8/L&(M%#(M("(M%"(L`@+A4`0```'0&C9!4`0``B50D"`^_01C' +XM!"2!V@0(B40D!.CG[___R<.058GE@^P8BT4,BU`(H8P0!0B%P'0MBTT(BP&# +XMN`0"```!?A\%.@$``(E$)`@/OT(8QP0D@=H$"(E$)`3HI.___\G#QT0D"+/: +XM!`@/OT(8QP0D@=H$"(E$)`3HAN___\G#58GE4X/L%(M%#(M="(L(BU`(A56B<93 +XMB=.#[!"XP?\$"(M2)/9##`)T#HG(N@*ZZF0 +XM58GE@^P8BT4,BTT(BU`(BT$,A6+10R+30A= +XMBU`(BT(<`P'IV?[__XGVC;PG`````%6)Y5=64X'LK````(M%#(L-D!`%"(MX +XM"(M%"(L0*XH8`0``N@=%+L*)R/?JC30*B6#[#B+10R)7?B)=?R+<`B+10B+`(M01(/Z_W11B=`P +XM](U=Z(E$)!`/ML:)'"2)1"0,QT0D".':!`C'1"0$$````.AK[/__B5PD"`^_ +XM1AC'!"2*V@0(B40D!.@S[/__BUWXBW7\B>Q=PY"-="8`QT0D"*;:!`@/OT88 +XMQP0DBMH$"(E$)`3H".S__XM=^(MU_(GL7<.-=@"-O"<`````58GE5E.#[#"+ +XM10R+6`B+10B+``^VD`P"```/MH`-`@``@/H"#X29````=U>`^@$/A+(```") +XM1"00C77P#[;"B40D#,=$)`C_V@0(QT0D!`@```")-"3HN>O__Y"-="8`B70D +XM",9%]P`/OT,8QP0DBMH$"(E$)`3H>.O__X/$,%M>7<.`^@-T*(#Z!'6HC77P +XMB40D#,=$)`CWV@0(QT0D!`@```")-"3H:.O__^NRB?:-=?#'1?!N;W)MQT7T +XM86P``.N=C77PB40D#,=$)`COV@0(QT0D!`@```")-"3H,NO__^EY____C77P +XMB40D#,=$)`CGV@0(QT0D!`@```")-"3H#NO__^E5____D(UT)@!5B>53@^P4 +XMBT4,BU@(H7P0!0B%P'1:H4P0!0B%P'4QBU4(BP+V@"L!```0="/;@.0````Q +XMTJ&($`4(4E#?+"2#Q`C>^=@-H-L$".L&C70F`-GNW5PD"`^_0QC'!"0%VP0( +XMB40D!.AZZO__@\046UW#Z`OS__^C3!`%".N:C70F`%6)Y5.#[!2+'7P0!0B% +XMVW1?BPU0$`4(A\=T<).CNZ?__,=)24]\L)(/$"-[) +XMW1PDZ"KJ___<+:C;!`C=1?#>\>N,B?:-O"<`````58GE4X/L%(M%#(M8"(M% +XM"(D$).@(____W5PD"`^_0QC'!"0%VP0(B40D!.A4Z?__@\046UW#C78`C;PG +XM`````%6)Y5=64X'LK````(M="(`]5!`%"``/A$0!``"+10R+0`B)A6S___^+ +XM>PR%_P^$)`$``(L[B[<4`0``BY\0`0``QT0D"$!"#P#'1"0,`````(ET)`2) +XM'"3HTRH``(ET)`3'1"0(0$(/`,=$)`P`````B1PDB85P____Z$$I``"+-9@0 +XM!0B%]@^%LP```(V(B!,``+NMB]MHBQ=PXL"C5V0BX`8`0``B47TC47TB00DZ$;F__^)'"3'1"0(4-L$",=$ +XM)`1D````B40D#.C:Y?__B5PD"`^_1AC'!"2!V@0(B40D!.@RY___BUWXBW7\ +XMB>Q=PXUT)@!5B>564X/$@(M%#(M="(MP"(M##(7`#X2J````H>#_!`B%P`^( +XM^P```(L#BX`8`0``B47TC47TB00DZ,7E__^+%9`0!0B)P8L#*Y`8`0``@?I_ +XM40$`?EF!^G\Z"0`/CYT```"+%>#_!`BX+=L$"(72='Z-79")3"0,B40D",=$ +XM)`1D````B1PDZ"?E__^)7"0(#[]&&,<$)(':!`B)1"0$Z'_F__^#[(!;7EW# +XMC70F`(L=X/\$"+@=VP0(A=MUL[@EVP0(ZZS'1"0(B-H$"`^_1AC'!"2!V@0( +XMB40D!.A"YO__@^R`6UY=PXVT)@````"X--L$".EX____C;8`````C5V0B4PD +XM#,=$)`@[VP0(QT0D!&0```")'"3HE>3__^EI____QP0D!````.ADYO__@#@` +XM#Y7`#[;`H^#_!`CIYO[__XVV`````(V\)P````!5B>53@^P4BT4,BU@(BT4( +XMBP"+0$2#^/]T-L=$)`0`(```B00DZ+KF__^%P'0BB40D"`^_0QC'!"2!V@0( +XMB40D!.B.Y?__@\046UW#C70F`,=$)`BFV@0(#[]#&,<$)(':!`B)1"0$Z&CE +XM__^#Q!1;7<.-M"8`````C;PG`````%6)Y8/L*(M%#(M5"(E=](EU^(E]_(M8 +XM"(L"BT!$@_C_#X2,````QT0D!``@``")!"3H+N;__X7`B47P='6+=?"X`P`` +XM`+\Q=PXGVBW7PN`,```"_1]L$"(G!\Z8/A6+____I +XM6?___XUT)@!5B>6#[`C'1"0$`````(M%"(L`BX",````B00DZ$/D__^)10C) +XMZ:KE__^-M@````!5B>53@^P4BT4,BU@(BT4(QT0D!`````"+`(N`C````(D$ +XM).@,Y/__B40D"`^_0QC'!"2!V@0(B40D!.CDX___@\046UW#C78`C;PG```` +XM`%6)Y8/L",=$)`0`````BT4(BP"+@(@```")!"3HP^/__XE%",GI*N7__XVV +XM`````%6)Y5.#[!2+10R+6`B+10C'1"0$`````(L`BX"(````B00DZ(SC__^) +XM1"0(#[]#&,<$)(':!`B)1"0$Z&3C__^#Q!1;7<.-=@"-O"<`````58GE@^P( +XMQT0D!`````"+10B+`(N`E````(D$).BSX?__B44(R>FJY/__C;8`````58GE +XM4X/L%(M%#(M8"(M%",=$)`0`````BP"+@)0```")!"3H?.'__XE$)`@/OT,8 +XMQP0D@=H$"(E$)`3HY.+__X/$%%M=PXUV`(V\)P````!5B>53@^P4BQT```4( +XMA=MT'8M+!(G:@#D`=`WK'F+`L8`"H/``8D"@\046UW#H300!0C'!"0@```` +XMB40D!.C=W___BQOKC8E,)`3'!"3+W`0(Z,GA___I1O___SM"&`^-8____XE4 +XM)`3'!"0@````Z&OB__^+&^E8____H300!0C'!"0*````B40D!.B/W___@\04 +XM6UW#B50D!,<$)`H```#H.>+__^G._O__58GE5U93@^P+__XT$A0$```")!"3H"N+__X7`B47L +XM#X2<`@``QT0D"%@```"+0P2)1"0$BT7LB00DZ(7>__^+0PC'1?``````AS'!"28V@0(B40D"(E4)`R) +XM1"0$Z';@__^+3>R)#"3HJ^'__XM-\(7)#X0Q____BT7PB44(@\0<6UY?7>F. +XMX?__BQ6H$`4(A=)U?HM%\(7`=!.+3?#'!"13VP0(B4PD!.@JX/__BT7LQP0D +XMR]P$"(E$)`3H%^#__^N?D(L#QP0DR]P$"`5O`0``B40D!.C]W___H8P0!0B% +XMP`^$P?[__XL#@[@$`@```0^.LO[__P4Z`0``B44,QT4(NMH$"(/$'%M>7UWI +XMQM___P^_7QB)V"L%G!`%"`'0ALDBQ4T$`4(#[[YBT((@^@!A<")0@AX0XL"B?F("(/``8D"@\8!@^L! +XM#XAM_O__#[9._X3)#X1A_O__BSW8`P4(A?]TO:$T$`4(B40D!`^^P8D$).BY +XMW/__Z\@[0AA\!8#Y"G6SB50D!(D\).AAW___Z[`[0AA\#(#Y"HUV``^%"?__ +XM_XE4)`2)/"3H0M___^D#____H300!0C'!"0@````B40D!.AHW/__Z4O____' +XM1"0$G=8$",<$)`$```#H']W__SM"&`^-)/___XE4)`3'!"0@````Z/;>___I +XM&?___XVV`````(V\)P````!5B>575E.#[!R+70B+=0R+0P2+?@B)!"3HA]__ +XM_XT$A0$```")!"3H^-[__X7`B47P#X0!`0``QT0D"%@```"+0P2)1"0$BT7P +XMB00DZ'/;__^+!H7`=#$/OT<8BU7PQP0DF-H$"(E$)`B)5"0,B40D!.BNW?__ +XMBTWPB4T(@\0<6UY?7>GLDBQ4T$`4(#[[YBT((@^@!A<")0@AX.XL"B?F("(/` +XM`8D"@\,!@^X!>)L/MDO_A,ETDXL]V`,%"(7_=,6A-!`%"(E$)`0/OL&)!"3H +XM(]O__^O0.T(8?`J`^0J0C70F`'6VB50D!(D\).C&W?__Z[.+5?#'!"3+W`0( +XMB50D!.CQW/__Z3[____'1"0$G=8$",<$)`$```#HJ-O__Y"0D)!5B>6)4`R+ +XM50A=QT`$`````,<``````(E("(E0$,=`%`````##C70F`(V\)P````"A7!`% +XM"%6)Y5:+50B#^`*+=0Q3="N#Z`%T2(L*BQ:+642+0D0YPW5JBT(H.4$H=$`/ +XMG<`/MM"-5!+_6XG07EW#W480W4(0V=BZZ____ +XM_Y#KV(M"&#E&&'7&ZZZ-="8`BX((`@``,=(Y@0@"``!UL.NXW=C=V.N2N@$` +XM``"-=@#KJ(/[_[K_____=)Z#^/^Z`0```'24.<,9TH/*`>N+D%6)Y593@^P0 +XMBQT```4(A=MT*8M%"(LPZPV-M"8`````BQN%VW05BT,(BP")="0$B00DZ*W; +XM__^%P'7E@\00B=A;7EW#C;8`````C;\`````58GE@^P8H3@0!0C'1"04L-L$ +XM",=$)!!\W00(QT0D#,#=!`C'1"0(X-T$",=$)`2_VP0(B00DZ-G8___'!"0! +XM````Z$W<__^)]HV\)P````!5B>575HG64X'L'`0``(F%[/O__P^V`H3`#X2N +XM`0``D`^^V(E<)`3'!"3,VP0(Z$':__^%P'0,@\8!#[8&A,!UWS';B5PD!(V= +XM]/O__\<$)-';!`CH&]K__X7`='C&`P"+E>S[__^-A?3[__^)1"0$B10D_U(, +XMZQH/OMB)7"0$QP0DS-L$".CIV?__AVZ43___^+A>S[ +XM__^)="0$B00D_U`,#[8&A,`/A5C^___IT/[__XN5[/O__XV%]/O__XE$)`2) +XM%"3_4@P/M@:$P`^%,O[__^FJ_O__C;8`````C;PG`````%6)Y5.)RX/L%(L- +XMJ!`%"(E,)`B+$HE4)`2+%6`0!0B)%"3_T(M5"(E<)`2)5"0(B00DZ"G<__^# +XMQ!1;7<.-=@!5B>53B<.#[`3'0`0`````QT`(`````,<``````(M`%(7`=`B) +XM!"3H*-K__\=##`````#'0Q``````QT,4`````(/$!%M=PXGVC;PG`````%6) +XMY8/L&(E=^(G#B77\BT`$@\`!C30`B?`/KT,(B40D!(M#%(D$).A8U___A575E.!['P,``"+70S&A93W__\`QH64 +XM\___``^V`SPO#X1(`@``/&,/A!("``"-A93[__^_%]P$",=$)`@`!```QT0D +XM!!'N0,```#SIKX$W`0(C7V4#Y?"#Y+`.,(/ +XMA"W^___IQ/W__XUT)@"%VW26# +XM["B)7?2+70R)=?B+=0B)??R`.P!U)L<$)$C>!`CHCM/__S'`QP5T$`4(`0`` +XM`(M=](MU^(M]_(GL7<.0Z*_3___'``````"-1?#'1"0("@```(E$)`2)'"3H +XM@M/__XG'BT7P@#@`=$6)7"0(BT80QP0DKMP$"(E$)`3H,=/__^ALT___QP`B +XM````Z&'3__^#.")T:(L6.U8$?7*+1A2)/)"-0@&)!K@!````ZX&%_WBW.<-T +XMLXVT)@````#H+]/__XL0A=)U"('_GX8!`'Z[B5PD"(M&$,<$)+W6#[#B)=?B+=0R)??R+?0B)7?2`/@!T)HDT).AR +XMU/__@_@0=DF)="0(BT<0QP0D:MP$"(E$)`3H5M+__^L3BT<0QP0D3-P$"(E$ +XM)`3H0=+__\<%=!`%"`$````QP(M=](MU^(M]_(GL7<.-="8`Z%_2___'```` +XM``"-1?#'1"0("@```(E$)`2)-"3HPM'__XG#Z#O2__^+"(7)=0B+1?"`.`!T +XM/,=%X.')^.AQ^?__BP_KX(D<).AYT/__QT7@SMP$"(7`B<-UQ.NTBT7@B70D +XM#(E$)`B+1Q#'!"3GW`0(B40D!.A\T?__Z3;___^-=@"-3"0$@^3P_W'\58GE +XM5U9348'L"`L``(L!BTD$QT0D!,[;!`C'!"0`````B844]?__B8T0]?__Z.C2 +XM___'!"20$`4(Z#S/___'!"3UW`0(Z'#/__^%P'0)@#@`#X6U"P``C5WDB5PD +XM",=$)`1H=`A`QP0D`0```.CHS___@\`!#X3/#0``#[=%YF:%P`^%E0(``,<% +XMJ!`%"$\```"#O13U__\!#XXG`0``BY40]?__BXT0]?__B[T0]?__@\($B948 +XM]?__BTD(B8T<]?__BW<$#[8^B?B$P'0UB?*0C70F``^^P(G3B40D!,<$)&S> +XM!`CH']#__X7`=`J`>`$Z#X2$"@``#[9#`8U3`83`==(QVXDT).A%+/7__P`` +XM``#'A3#U__\`````QX5`]?__`````,>%1/7__P````#'A4SU__\`````QX4D +XM]?__(=T$",>%2/7_______^)]HN5$/7__XN-%/7__\=$)`ALW@0(B50D!(D, +XM).A$SO__@_C_#X1@`P``@^A!/#=V%^@K\___Z\D/M\"#Z`&CJ!`%".EE_?__ +XM#[;`_R2%O-X$"(.%0/7__P''A2SU__\!````QX5(]?__`0```.N2QP0D```` +XM`.@JSO__A<"CW`,%"`^$8PP``(L5W`,%"(V%5/___^@8\___@X5`]?__`<>% +XM3/7__P$```#I4O___\=$)`0`````QP0DP``%".A>U/__QP5<$`4(`@```,8% +XMP``%"`#'A3#U__\!````Z1[___^%VP^$3@@``,<%J!`%"`````"#PP'I!/__ +XM_\=$)`0`````QP0D``$%".@0U/__QP5<$`4(`0```,8%``$%"`#'A3#U__\! +XM````Z=#^___'!5P0!0@"````Z<'^__^+%=P#!0B-19SH8_+__X.%0/7__P'I +XMI_[__Z'<`P4(QT0D!`$```")!"3HLM/__\>%,/7__P$```#I@_[__\<%7!`% +XM"`$```#I=/[__\=$)`0`````QP0D8``%".B`T___Q@5@``4(`,>%,/7__P$` +XM``#I2O[__\=$)`0`````QP0D(``%".A6T___Q@4@``4(`,>%,/7__P$```#I +XM(/[__P^W1>3'A43U__\6````9H/X!0^&"/[__P^WP(F%1/7__^GZ_?__Z$G. +XM__^%P`^%T@@``,<%6!`%"`$```#IWOW__\<%;!`%"`$```#IS_W__\<%E!`% +XM"`$```#IP/W__X.%0/7__P''A2SU__\!````Z:K]___'1"0$`````,<$)#\! +XM!0CHMM+__\8%/P$%"`#IBOW__\>%2/7__P````#I>_W__XL5W`,%"(V%//__ +XM_^@:\?__@X5`]?__`<>%3/7__P$```#I5/W__\<%F!`%"`$```#I1?W__\=$ +XM)`0!````QP0DGP`%".A1TO__H=P#!0C'1"0$`0```(D$).@\TO__QT0D!`$` +XM``#'!"2C``4(Z"C2___&!:,`!0@`Q@6?``4(`,>%,/7__P$```#IZ_S__Z'< +XM`P4(B84D]?__Z=O\__^+/=P#!0B)O2CU___IROS__^A5T?__QP0D`````.BM +XMS/__QP6,$`4($````.FJ_/__BQ7<`P4(C47,Z$SP__^#A4#U__\!QX5,]?__ +XM`0```.F&_/__QP6@$`4(`0```.EW_/__H3P0!0B+O1#U__^#/6P0!0@!C02' +XMB84(]?__#X07"```BX4(]?__BQB%VW1/#[8#@_A_#X=5"P``]@2%%00%"`2+ +XMM0CU__]U(NE`"P``#[8#@_A_#XR)1"0,H6`0!0C'1>S_____B50D"(E, +XM)`2)!"3HU,O__X7`B84@]?__#X21`P``BT7L@_@`#XPW!0``#XZ*`P``:\`< +XMB00DZ,G*__^%P*-D$`4(#X0[`P``BT7LB84T]?__@^@!#XA@`P``QX4\]?__ +XM`````,>%7/7__P````")]HM=G(7;?AZ+E2#U__\QP(M**(M5L#L,@@^$6@$` +XM`(/``3G8=?"+A4CU__^%P'4=BXT@]?__@WE$_P^$$0$``/:!*`$```(/A`0! +XM``"+A4#U__^%P`^$'@$``(M=S(7;?B&+O2#U__\QP(M5X(N/E````#D,@@^$ +XM_0```(/``3G8=?"+7;2%VWX>BX4@]?__BU7(BT@P,<`Y#((/A-@```"#P`$Y +XMV'7PBUV$A=M^(HN5(/7__S'`BXJ,````BU68D#L,@@^$KP```(/``3G8=?"+ +XMG6S___^%VWX>B[T@]?__,<"+58"+3S@[#((/A(<```"#P`$YV'7PBYU4____ +XMA=M^'8N%(/7__XN5:/___XM(1#'`.0R"=&"#P`$YV'7TBYT\____A=M^)XN5 +XM(/7__S'`BXJ(````BY50____.PR"=#:#P`$YV'7TC;0F`````(.%7/7__P&+ +XMC33U__\YC5SU__\/A.L!``"!A2#U__\``P``Z8C^__]KO3SU__\[__XD$).BYQ?__B4<$BU\$A=L/A.H```"+#6P0!0B%R0^%F````,=' +XM"`````")]HLU```%"(7V=0SK0HUT)@"+-H7V=#B+7@CV0PP(C78`=.Z)/"3_ +XM4Q0/MU,8B<$/O\(YP7X&B%0/7__P````#I +XMG?K__XET)`2)/"3H2,;__^EQ]/__H6`0!0B)!"3H9L3__\=$)`3+W`0(QP0D +XM`0```(E$)`CH3L/__\<$)`0```#H%0/7__P````#IN_?__SM"&`^-7/___XE4)`3'!"0@````Z'G" +XM___I4?___Z'8`P4(A<`/A10!``"+%300!0B+0@B#Z`&%P(E""`^(<@$``(L" +XMQ@`*@\`!B0*+A43U__^%P'09BY4,]?__.94X]?__#X3Q````@X4X]?__`8/' +XM`8/&'#N]//7__P^%N?[__XU%S.@UZ/__C46C__XU%A.@= +XMZ/__C85L____Z!+H__^-A53____H!^C__XV%//___^C\Y___H:00!0B)!"3H +XM\\'__XV";P$``(E$)`B-1P3'1"0$6-T$"(D$).C&P?__Z6OY__^)P8M%L(/) +XM`8L0QX5`]?__`````.FQ]O__B<&+18"#R0.+$,>%0/7__P````#IF/;__XG! +XMBX5H____@\D$BQ#'A4#U__\`````Z7SV__^A-!`%",<$)`H```")1"0$Z'Z^ +XM___I\_[__XL=V`,%"(7;#X6_````BQ4T$`4(BT((@^@!A<")0@@/B),```"+ +XM`L8`"H/``8D"Z''=___'A3CU__\`````Z=/^__^)7"0(QT0D!,O]___I2/___Y"0D)"0D)"0D)"0D)"058GE5U:#[#"+11"+512+=0B+ +XM?0R)1>R)P8E5Z(M%Z,=%T`````#'1=0`````B?J)=>2%P(EU\(E]X'44.?EV +XM8(GP]_&)5=#'1=0`````ZQ"+3>`Y3>AV&(EUT(E]U(GVBT70BU74@\0P7E]= +XMPXUV``^]1>B#\!^)1=AU1HM%Z#E%X`^'R0```(M-[#E-Y`^#O0```(M-\(E5 +XMU(E-T.O!D(M%[(7`=0RX`0```#'2]W7LB<&+1>"+5>CW\8M%Y/?QZX*X(``` +XM`(M5["M%V(MU[(M]Y(G!B47@/MDW8T^`)PHM%Y-/F#[9-W(E5](M5 +XMX-/H#[9-V-/B"="+5>#3YP^V3=S3ZO=U](E5S/?F.57,575H/L((M% +XM$(M5%,=%X`````"+=0S'1>0`````B47TB<&+10B%THG7B47L=2,Y\0^&F``` +XM`(GR]_&)P3'`B4W@B47DBT7@BU7D@\0@7E]=PSGR#X>U````#[W"@_`?B47H +XM#X26````N"````"+5?0K1>B)P=/J#[9-Z(E%\(GXBWWTT^`)PHM%[-/G#[9- +XM\(E5W(GRT^@/MDWHT^(/MDWP"=#3[HGR]W7P/MDWHT^`YQG:'BTW8,<"#Z0'I^O[_ +XM_Y"0D)"0D)"0D)!5B>53@^P$H90"!0B#^/]T$C';_]"+@Y`"!0B#ZP2#^/]U +XM\(/$!%M=PY"0D(/L#.@\O___@\0,PR1&@!64UH`>'-T870`6%-4050```!N;R!V86QI9"!K97EW +XM;W)DF5R;RUL96YG=&@I("5S(&YA;64`)7,@;F%M92!T;V\@ +XM;&]N9SH@)7,`3F\@)7,@;F%M960@)R5S)P!.;R`E`````4```"C +XMV@0(`````)C7!`AAV00(``````````#@I`0(``````@```!H````!0```*/: +XM!`@`````2-<$"&G9!`@``````````."D!`@`````"````%@````%````H]H$ +XM"`````!QV00(=-D$"``````0````X*0$"``````#````!`$```4```#,V@0( +XM``````?8!`@-V`0(``````8```"@JP0(``````<````````````````````` +XM````$]H$",[;!`AWV00(```````````````````````````````````````` +XM``!WV00(&=H$"```````````0*$$"``````$```````````````````````` +XM`'W9!`B#V00(``````````#@I`0(``````4```"8````!0```/W:!`@````` +XMB=D$"(_9!`@``````````."D!`@`````!0```)`````%````_=H$"`````"5 +XMV00(FMD$"```````````,*8$"``````$`````````````````````````)_9 +XM!`BEV00(``````(```#@H@0(`````!,`````````````````````````>]<$ +XM"*O9!`@`````!````("I!`@`````"0````````````````````````"PV00( +XMMMD$"```````````X*0$"``````$````-`````4```#,V@0(`````+S9!`C! +XMV00(``````````#@I`0(``````4````\````!0```,S:!`@`````QMD$",O9 +XM!`@``````````."D!`@`````!````.P````)````D-H$"`````#0V00(T]D$ +XM"```````````<*T$"``````$`````````````````````````!SBPE8W!U+"5M +XM96TL8V]M;6%N9`!L86)E;`!P:60L='0LI($"(J2!`B:D@0( +XMJI($"+J2!`C*D@0(VI($".J2!`CZD@0("I,$"!J3!`@JDP0(.I,$"$J3!`A: +XMDP0(:I,$"'J3!`B*DP0(FI,$"*J3!`BZDP0(RI,$"-J3!`CJDP0(^I,$"`J4 +XM!`@:E`0(*I0$"#J4!`A*E`0(6I0$"&J4!`AZE`0(BI0$")J4!`BJE`0(NI0$ +XM"``D1G)E94)31#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#

7=O6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O +XM9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]Fvi.uu << 'END-of-vi.uu' +Xbegin 755 vi +XM?T5,1@$!`0D```````````(``P`!````X*0$"#0````8IP0``````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(@(\$ +XM`("/!``%`````!````$`````D`0``!`)"``0"0B$!```@!$```8`````$``` +XM`@```%"1!`!0$0D(4!$)"-````#0````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&1LCP0`;`\)"&P/"0@4````%`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`@P```*@````Q```````````````W`````````&<```!4```` +XMH@````````"(`````````'<```"9````3@```&X````_``````````````"0 +XM````@@``````````````I0```*<```"/`````````(````!6````G0```)$` +XM``"*`````````)L```!2``````````4`````````F````&$````T````>@`` +XM``````"+````G````)X````-`````````'\``````````````'D````````` +XM)P```$,````8````:@````````!T````H0````````"$`````````$P````X +XM````H``````````?````E0```#``````````8P`````````6`````````#T` +XM``!F````E@``````````````EP```!$```!:``````````````!B````@P`` +XM`($```!7````7````)0`````````%P```'4````N````?0````````!H```` +XM`````(P``````````````'````"'````F@```*0```!)````<@```*8````` +XM````4`````````!8````>P```)(`````````HP```````````````````)\` +XM```\````;P```%4```!^`````````(D```!?````60```(4````Z```````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````````0```````````````````!(````` +XM````````````````````!`````(````````````````````.````#``````` +XM```5`````````!0````(````````````````````````````````````*0`` +XM````````````(P````D``````````````"H````E````+P`````````````` +XM"@`````````````````````````L```````````````<```````````````9 +XM`````````"@````D`````````$(``````````P`````````V`````````$H` +XM```Y````,P`````````;`````````$$````````````````````+````-0`` +XM`````````````````!T````0````&@````\````'````70`````````````` +XM`````#X```!$`````````!X````A````:0``````````````(````&0````` +XM````````````````````$P````````!1````````````````````10```$\` +XM```R````!@```#L``````````````&P```!(`````````$<````````````` +XM`',```!`````````````````````6P````````!@````)@```(T```!+```` +XM`````%X```!Q`````````'P```!-````C@```'@```!M`````````"(```"& +XM`````````&L```!&`````````%,````M````DP```'8````K````90`````` +XM``````````````````!\!````````,8````2````VP$````````R`@``$@`` +XM`*P"````````-````!(```!3!````````#,````2````N@(```````!#```` +XM$@```!($````````5@$``!(````]!``````````````2````K@,````````R +XM````$@```#8$````````H0```!(```!0`0```````'(#```2````+P$````` +XM``""`0``$@```+\"`````````````!(```"C`0```````&L!```2````R`$` +XM``````#]"```$@```!$```!0$0D(`````!$`\?^T`@`````````````2```` +XM.0(`````````````$@```!H`````````U`,``!(```"1!``````````````2 +XM````-P0```````"A````$@```/\"`````````````!(```!/`P```````%H` +XM```2````50(```````!7````$@```$(!````````.0```!(````P!``````` +XM```````2````!@(```````!J````$@```"``````````30```!(````G```` +XM`````/8#```2````>P0```````":````$@```"0$`````````````!(````O +XM`````````!D````2````XP$```````#!````$@```/,!`````````````!(` +XM``">`P```````%T````2````2@$`````````````$@```&X!````````3P`` +XM`!(```",`P````````4````2````S`(`````````````$@```.`#```````` +XM3@4``!(````5`P```````-T#```2````:@(```````#8````$@```#<```"@ +XMFP0(`````!(`"@`@`@```````.H````2````=P(`````````````$@```%X# +XM`````````````!(```#M`@`````````````2````S@$```````"2`0``$@`` +XM`)`0```````#,````2````3``` +XM``````"2````$@```'$#``"@%`D(!````!$`%P!5`````````"0````2```` +XM*@(````````5`@``$@```'X#````````90(``!(```"/`@`````````````2 +XM````,`,````````T````$@```-,"````$`D(!````!$`$`!:`````````-T` +XM```2````9`````````!"````$@```&L`````````;@```!(```!U```````` +XM`-P#```2````0P0`````````````$@```*<"`````````````!(```"X`P`` +XM`````%(7```2````&0(``*04"0@$````$0`7`,`#````````*P```!(````^ +XM`P```````,T````2````?`(``*@4"0A4#```$0`7`(4#`````````````!(` +XM``#/`P```````,P````2````90(```````"A````$@```'L`````````)``` +XM`!(```"0`0```````#````!(```";````'(H("``````2 +XM``T`,0$```````"8````$@```-<#````````'0```!(```"7!````````.T` +XM```2````.`$```0A"0@$````$0`7`*H!`````````````!(````\!``````` +XM`+$````2````&P0````````D````$@```#0"`````````````!(````=`P`` +XM""$)"`0````1`!<`8@$````````E````$@```'\!`````````````!(```"A +XM`````````#D````2````7P0`````````````$@```%@$````````8@```!(` +XM``"6`P```````,L````2````@00`````````````$@```*L````,(0D(!``` +XM`!$`%P!L!````````/H````2````8`0```````!#````$@```*$$```````` +XM`````!(````+`@```````,,````2````KP0``(04"0@`````$`#Q_Z<$```` +XM````/0```!(````2`@```````#,````2````U`$`````````````$@```+(` +XM```T$@D(`````!$`\?_M`P```````($````2````P@0``(`A"0@`````$`#Q +XM_P@$````````8@,``!(```"K`0`````````````2````R`````````!T```` +XM$@```$`"````````80```!(```"G`P````````,!```2````Z0$``!`A"0@$ +XM````$0`7`&\$````````DP```!(```#%`@``%"$)"`0````1`!<`^`$````` +XM````````$@```,T`````````H@```!(```"Q`0```````$4````2````5@,` +XM``````#*#```$@````$$````````*P```!(```#6````&"$)"`0````1`!<` +XM7P(`````````````$@```,$!`````````````!(```#=`````````+4````2 +XM````YP`````````%`0``$@```#("````````[````!(```!E!``````````` +XM```2````(P0`````````````$@```'0!S971V8G5F`&5X96-L`%]?7-T96T`9F5O9@!M86QL;V,`:7-A='1Y`&]P=&%R9P!V&5C +XM`&]P96YD:7(`6YA;64`9V5T<'=U:60`9V5T8W=D`&9G971C +XM`&=E=&AO&ET`'-E=&QO8V%L90!R96=E&ET`'-T@<` +XM``(`QP0```````"@%`D(!3P``*04"0@%2@``J!0)"`5-``#\(`D(!6(````A +XM"0@%9P``!"$)"`5Q```((0D(!78```PA"0@%?@``$"$)"`6/```4(0D(!9$` +XM`!@A"0@%EP``'"$)"`6C``!`$@D(!P$``$02"0@'`@``2!()"`<#``!,$@D( +XM!P0``%`2"0@'!0``5!()"`<&``!8$@D(!P<``%P2"0@'"```8!()"`<)``!D +XM$@D(!PH``&@2"0@'"P``;!()"`<,``!P$@D(!PT``'02"0@'#@``>!()"`<0 +XM``!\$@D(!Q$``(`2"0@'$@``A!()"`<3``"($@D(!Q0``(P2"0@'%0``D!() +XM"`<6``"4$@D(!Q<``)@2"0@'&```G!()"`<9``"@$@D(!QH``*02"0@'&P`` +XMJ!()"`<<``"L$@D(!QT``+`2"0@''@``M!()"````[!,)"`=Y``#P$PD(!WH``/03"0@'>P``^!,) +XM"`=\``#\$PD(!WT````4"0@'?P``!!0)"`>````(%`D(!X$```P4"0@'@@`` +XM$!0)"`>$```4%`D(!X4``!@4"0@'A@``'!0)"`>(```@%`D(!XH``"04"0@' +XMBP``*!0)"`>,```L%`D(!XT``#`4"0@'C@``-!0)"`>0```X%`D(!Y(``#P4 +XM"0@'DP``0!0)"`>4``!$%`D(!Y4``$@4"0@'E@``3!0)"`>8``!0%`D(!YD` +XM`%04"0@'F@``6!0)"`>;``!<%`D(!YP``&`4"0@'G0``9!0)"`>>``!H%`D( +XM!Y\``&P4"0@'H```A``!T%`D(!Z(``'@4"0@'I0``?!0)"`>F``"` +XM%`D(!Z<``(/L#.@("@``Z$/N`P"#Q`S#````_S4X$@D(_R4\$@D(`````/\E +XM0!()"&@`````Z>#_____)402"0AH"````.G0_____R5($@D(:!````#IP/__ +XM__\E3!()"&@8````Z;#_____)5`2"0AH(````.F@_____R54$@D(:"@```#I +XMD/____\E6!()"&@P````Z8#_____)5P2"0AH.````.EP_____R5@$@D(:$`` +XM``#I8/____\E9!()"&A(````Z5#_____)6@2"0AH4````.E`_____R5L$@D( +XM:%@```#I,/____\E`2"0AH0`$``.E@_?___R7D$@D(:$@!``#I4/W___\EZ!() +XM"&A0`0``Z4#]____)>P2"0AH6`$``.DP_?___R7P$@D(:&`!``#I(/W___\E +XM]!()"&AH`0``Z1#]____)?@2"0AH<`$``.D`_?___R7\$@D(:'@!``#I\/S_ +XM__\E`!,)"&B``0``Z>#\____)003"0AHB`$``.G0_/___R4($PD(:)`!``#I +XMP/S___\E#!,)"&B8`0``Z;#\____)1`3"0AHH`$``.F@_/___R44$PD(:*@! +XM``#ID/S___\E&!,)"&BP`0``Z8#\____)1P3"0AHN`$``.EP_/___R4@$PD( +XM:,`!``#I8/S___\E)!,)"&C(`0``Z5#\____)2@3"0AHT`$``.E`_/___R4L +XM$PD(:-@!``#I,/S___\E,!,)"&C@`0``Z2#\____)303"0AHZ`$``.D0_/__ +XM_R4X$PD(:/`!``#I`/S___\E/!,)"&CX`0``Z?#[____)4`3"0AH``(``.G@ +XM^____R5$$PD(:`@"``#IT/O___\E2!,)"&@0`@``Z<#[____)4P3"0AH&`(` +XM`.FP^____R50$PD(:"`"``#IH/O___\E5!,)"&@H`@``Z9#[____)5@3"0AH +XM,`(``.F`^____R5<$PD(:#@"``#I!,)"&AP`@``Z0#[ +XM____)7P3"0AH>`(``.GP^O___R6`$PD(:(`"``#IX/K___\EA!,)"&B(`@`` +XMZ=#Z____)8@3"0AHD`(``.G`^O___R6,$PD(:)@"``#IL/K___\ED!,)"&B@ +XM`@``Z:#Z____)903"0AHJ`(``.F0^O___R68$PD(:+`"``#I@/K___\EG!,) +XM"&BX`@``Z7#Z____):`3"0AHP`(``.E@^O___R6D$PD(:,@"``#I4/K___\E +XMJ!,)"&C0`@``Z4#Z____):P3"0AHV`(``.DP^O___R6P$PD(:.`"``#I(/K_ +XM__\EM!,)"&CH`@``Z1#Z____);@3"0AH\`(``.D`^O___R6\$PD(:/@"``#I +XM\/G___\EP!,)"&@``P``Z>#Y____)<03"0AH"`,``.G0^?___R7($PD(:!`# +XM``#IP/G___\ES!,)"&@8`P``Z;#Y____)=`3"0AH(`,``.F@^?___R74$PD( +XM:"@#``#ID/G___\EV!,)"&@P`P``Z8#Y____)=P3"0AH.`,``.EP^?___R7@ +XM$PD(:$`#``#I8/G___\EY!,)"&A(`P``Z5#Y____)>@3"0AH4`,``.E`^?__ +XM_R7L$PD(:%@#``#I,/G___\E\!,)"&A@`P``Z2#Y____)?03"0AH:`,``.D0 +XM^?___R7X$PD(:'`#``#I`/G___\E_!,)"&AX`P``Z?#X____)0`4"0AH@`,` +XM`.G@^/___R4$%`D(:(@#``#IT/C___\E"!0)"&B0`P``Z<#X____)0P4"0AH +XMF`,``.FP^/___R40%`D(:*`#``#IH/C___\E%!0)"&BH`P``Z9#X____)1@4 +XM"0AHL`,``.F`^/___R4<%`D(:+@#``#I#V__\```````````````!5B>564X/L$(/D +XM\(M=!(G1C72=#(7;B35H(0D(?C:+10B%P'0OHP`0"0@/MA"$TG0C@\`!ZPH/ +XMMA"#P`&$TG04@/HO=?&C`!`)"`^V$(/``832=>RX4!$)"(7`=#2)#"3HG_[_ +XM_\<$)!R*"`CHD_[__^A*]O__C44(B70D"(E$)`2)'"3H5P\``(D$).AC_?__ +XMZ'[X___KS9"0D)"0D)"058GE@^P(@#T@(0D(`'0,ZQR#P`2C"!`)"/_2H0@0 +XM"0B+$(72=>O&!2`A"0@!R<.058GE@^P(H3`2"0B%P'02N`````"%P'0)QP0D +XM,!()"/_0R<.0D)"0D)"0D)"0D)"0H0PA"0BZ_____U6)Y8M-#(7`=`,/OQ") +XM$:$,(0D(NO____^%P'0$#[]0`HM%$(D0BT4(BT!(*0$QP%W#C70F`%6)Y8M% +XM"(M5#(M-%(M`$(/Z`8M`)'0Y6#[!BA$"$)",=$)`B`````QT0D!`$```#' +XM!"2,B@@(B40D#.AI^___R<.-=@!5B>6#[!B+10B)7?2)=?B)??R+0!"+4"2) +XM5?"+<%R+11"%P'0;BYH0`@``]L,$=46+7?0QP(MU^(M]_(GL7<.0BTWPBX$0 +XM`@``J`)TXX/@_8F!$`(``(ET)`3'!"0UBP@(Z,[Y__^A!"$)"(D$).CA]___ +XMZ[NX!0```+\OBP@(_(G!\Z9UJHM%\(/+`HF8$`(``(M5#(E4)`3KOY"-="8` +XM53'2B>6#[`B+10B+0!"+0"2+B*0!``"%R74@*A +XM'"$)"(D4),=$)`@`````@^@!B40D!.@(^?__H0PA"0B)!"3H6_;__Z$,(0D( +XMQT0D!`````")!"3H)O?__\=$)`@`````QT0D!`````")-"3H*O[__^BY]/__ +XMC8,$`0``B40D",=$)`01````QP0D`````.A+^?__QT0D!!(```#'!"0````` +XMZ-?S__^+@Z0!``"%P'0Y@Z,0`@``YS'2BUWTB="+=?B+??R)[%W#D(U%Q(E$ +XM)`C'1"0$$0```,<$)`````#H^?C__S'2Z]&0QT0D"`$```"+1B"+0`B)-"2) +XM1"0$Z);]__^A#"$)",=$)`0!````B00DZ&7V__^+1<")?"0(B40D!*$,(0D( +XMB00DZ`WX___'1"0$`0```(DT).CY_?__C47PB40D$,=$)`P`````QT0D"``` +XM``#'1"0$`0```(DT).AB(0``N@$```"%P`^%1?___XM=\(7;#X1R_O__BT80 +XM,-*+0"2!B!`"`````0``Z2/___^-=@"-1<2)1"0$QP0D`````.AA\O__C8,$ +XM`0``B40D",=$)`01````QP0D`````.@3^/__Z0'^__^-=@"-O"<`````58GE +XM@^PHB5WTBUT(B77XBW40B7W\BWT,B70D"(GX`T-(B40D!*$,(0D(B00DZ#+W +XM__\QTH/``70/BUWTB="+=?B+??R)[%W#BT-(B70D$(E\)`S'1"0($(L("(E$ +XM)!3'1"0$`P```(D<).@1H@``N@$```#KPXUV`(V\)P````!5B>6#[`BA#"$) +XM",=$)`0!````B00DZ!GU___)@\`!#Y3`#[;`PXUV`(V\)P````!5B>6#["B+ +XM50B)7?2)=?B)??SV@JP$```0BT(0#X64````@\`(.0(/A,,```"+#0PA"0B_ +XM_____[[_____A0(/OS&+0D"+6DB+4C0YT`^#B`````'8QT0D"``` +XM``")1"0$B0PDZ$7V__^#P`%T+:$,(0D(QT0D$`````#'1"0,`````,=$)`@` +XM````QT0D!/____^)!"3HT_C__Z$,(0D(B7PD"(ET)`2)!"3H_O7__Z$,(0D( +XMQT0D!/____^)!"3H.?3__XM=](MU^(M]_(/``0^4P(GL70^VP,.-0O_I`" +XM`T(0BT`XA<`/E<"$P'7___S'`R<.)]HV\)P````!5B>6#[`B+10B+0!"+0"0%!`$``(D$).A8 +XM]/__/98```!T378Q/2P!``"-M@````!T/G9,/5@"``"-M"8`````="X]L`0` +XM`'4^BT4,QP"P!```,<#)PX/X2W05=C>#^&YT#CV&````=1Z-M"8`````BT4, +XMQP!8`@``,<#)PXUV`#W(````=.F+10S'`(`E```QP,G#@_@R=>[KU9"-="8` +XM58GE4X/L%(M-"(M5#(M!$(72BU@D=5F+51"%T@^%S@```(N##`(``(7`#X20 +XM````BX.@`0``QX,,`@```````(7`#X0[`0``QT0D"(#*!`C'1"0$`0```(D$ +XM).AD\O__H00A"0B)!"3HI_'__^M1D(/J`70+Z+KP__^-M@````#V@:P$```1 +XM=$R+DY@!``"X`0```(72=%*+11"%P`^$E````,=$)`B`R@0(QT0D!`$```") +XM%"3H"?+__Y"-="8`H00A"0B)!"3H1_'__X/$%#'`6UW#BT40A?KB(GV58GE4X/L +XM%(M%"(M5#(M`$(72BU@D=#"#Z@%T!>BC[O__BX.0`0``A<`/A'(!``#'1"0( +XM@,H$",=$)`0!````B00DZ`WP__^+@X@!``"%P'1GH:`4"0B%P'5'BQ4$(0D( +XMBT((@^@!A<")0@@/B%\!``"+`L8`#8/``8D"QT0D"(#*!`C'1"0$`0```(N# +XMB`$``(D$).B[[___@\04,6+0"2# +XMB!`"```@QX"D`0```0```%W#B?:A?"$)"%6)Y8M`)(.($`(``$!=PXVV```` +XM`(V_`````*%\(0D(58GEBT`D@8@0`@``@````,>`I`$```\```!=P^L-D)"0 +XMD)"0D)"0D)"0D*%\(0D(58GEBT`D@8@0`@````$``%W#B?:-O"<`````58GE +XM4XG3@^P4B40D"*$0(0D(QT0D!$F+"`B)!"3H4NG__X7;=!FA$"$)"(E<)`C' +XM1"0$28L("(D$).@UZ?__Z-#M__^+`(D$).@FZ___QT0D!'WI"`B)1"0(H1`A +XM"0B)!"3H#>G__\<$)`$```#H\>___XVV`````(V\)P````!5B>6#[#B)7?2- +XM7=R)=?B)UHE]_(G'C47DB4W[__XM=](MU^(M]_(GL7<.0C;0F`````%6)Y8/L&(EU^(MU#(E]_(M]"(E= +XM](7VBU\D='8QTKG@L00(N`$```#H@____X7`="?'1"0(38L(",=$)`0%```` +XMB30DZ/>8```QP(M=](MU^(M]_(GL7<,QTKD`L@0(L`+H2O___X7`=<"Q!`BP`>CH_O__ +XMAC__X7` +XM==6-D\`!``"Y`+($"+`"Z*?^__^%P'6_QT0D!`\```#'!"1L(0D(Z+/H__^% +XMP'6GC9/8`0``N2"R!`BP#^AY_O__A575E-1@^PXBP&+202)1=2A)"$)"(E-T(/``:,D +XM(0D(@^@!#X5F`P``BT70BQC'1"0$+P```(D<).AJZO__AB35\(0D(QT0D!!0"``#'!"0! +XM````Z"GL__^%P(G'#X3J`@``B7XDQP0D`````.BP[?__A<`/A7@!``"#CE0( +XM```0]H<1`@```@^$>P$``(V'!`$``(E$)`3'!"0`````Z)[F__^#P`$/A*&8`@``&"L!`C'AF0(``#@JP0(QX9H +XM"````````,>&;`@``,"K!`C'AG`(``#@I00(QX9T"```L*H$",>&>`@``)"Y +XM!`C'AGP(``!PKP0(QX:`"```L-`$",>&B`@``("J!`C'AH0(```@I@0(QX:0 +XM"````*H$",>&E`@```````#'AHP(``#0S@0(QX:8"```8*<$",>&G`@``,"F +XM!`C'AJ`(``!`PP0(QX:D"```P*<$",>&J`@``)"F!`C'!"1MBP@(Z`?F__^% +XMP(E%W`^$G0$``(U%Y(L>B40D"(M%W,=$)`0!````B00DZ-#K__^+1>2#^/\/ +XMA%`!``"%P`^%J````(M%W(E<)`C'1"0$E(L("(E$)`RA$"$)"(D$).@,Y?__ +XMQP0D`0```.CPZ___@8\0`@````(``/:'$0(```(/A87^___'1"0(`````,=$ +XM)`0`````QP0D6HL(".@MZ___@_C_B<,/A'W^__^-AP0!``")1"0$B1PDZ`#E +XM__^#P`%T#8D<).C3Z?__Z5G^__^+!KICBP@(Z![[___'!"0!````Z';K__^) +XM]HM%W(D$).B9Y?__A<")1ER)1F`/A-0```"-1>B)1"0,C47LQT0D$`````") +XM1"0(QT0D!`````#'!"0`````Z$T3``"%P'5+BT7LQT0D#`````#'1"0(```` +XM`,=$)`0`````B49(B49$BT7HB48\B48XH00A"0B)!"3H]N/__\=$)`0````` +XMB30DZ%+[__^%P'1NQP0D`0```.C6ZO__B?:A$"$)"(E<)`C'1"0$=(L("(D$ +XM).C+X___QP0D`0```.BOZO__QT7____Z-3E__^+1=")-"2)1"0(BT74 +XMB40D!.C*=P``BUXDQT0D!`````#'!"0!````B478C8.H`0``B40D".CJZ/__ +XMC8/``0``B40D",=$)`0`````QP0D`@```.C,Z/__C8/8`0``@]H<0`@```G5=BX>D`0``A?__Z$$(0D(B00DZ(CE___K@9"058GE5U93@>PL!0``BU4(BTT4BT(0BT`D +XMB87P^O__N---8A#W;12+113!^@;!^!\IPFG"Z`,``(F5Z/K__RG!:<'H`P`` +XM]D40`8F%[/K__P^%C@4``(N5\/K__XN"$`(``*A`#X5:!0``J:`!``!T&:@@ +XM#X6,!0``A,`/B)4%``#VQ`$/A5\"``"+310QTH7)=!6+E>CZ__^+C>SZ__^) +XM5>"-5>")3>2+10B+0!")A?SZ__^+2"2X(````(F-`/O___:!$0(```(/A'`! +XM``")]L>$A03___\`````@^@!=?"%TG1'@XT(____`8E4)!"-E0C____'1"0, +XM`````,=$)`@`````B50D!,<$)`$```#H#^+__X/X_P^$4P$``(7`NP0````/ +XMA#\!``#V11`PD`^%GP,``,>%^/K__P````"+C?SZ__^X(````(N5_/K__X/! +XM"(F-Y/K___:"5`@``"`/A.X"``"%P`^%O````(N-_/K__[`!@XT(____`8MQ +XM"#NUY/K__W1(,?^0C70F`(M%"/:`KP0```%T*(N8@````+@!````BTL$B+-CNUY/K__W7"C4%^/K__P````#H=.3__[L#````@S@$=!W'1"0( +XM=+P("+,"QT0D!`4```"+10B)!"3H29```(N%^/K__X7`#X6``0``@_L$=K#H +XMY>'__XN%]/K__XN-\/K__XM5#(E"%#'`B4H0QT(("0```('$+`4``%M>7UW# +XMBY7P^O__@.3^C4WHB8(0`@``C47LB40D#(U%\(E,)!")1"0(QT0D!`$```"+ +XM50B)%"3H00X``(7`#X7_`@``BUWHA=L/A%?]__^-18B+=>R)A0C___^-1;2) +XMA0S___^+1?"-G0C[__^)78C'1;0`````QT6\`````,=%D`````")1"0,QT0D +XM"+.+"`C'1"0$``0``(D<).@0Y/__B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!T +XMZ??"@(```'4&P>H0@\$"`-*#V0,IV8E-D(V-"/___\=$)`@`````B4PD!(M% +XM"(D$).CNI```A<`/A%8"``"+10S'0`@+````,<#I\O[__Y"-="8`BU4,,<#' +XM0@@#````@<0L!0``6UY?7<.+10S'0`@"````@<0L!0``,7UW#C46TB40D",=$)`01````QP0D`````.@DY/__ +XMZ6#^___'1"0(_P```(N%\/K__\<$)`````")1"0$Z('F__^#^/^)P@^$_?W_ +XM_X7`#X2B````BTT(]H&L!````70FBX7P^O__@'P"_PIT&8N-`/O__P^V@10! +XM``"+C?#Z__^(!!&#P@&+A0#[__\QV\>```$```````")E?3Z___ITOW__XU% +XMM(E$)`3'!"0`````Z+S=__^%P`^%1OS___9%$!!U=8N%`/O__P5<`0``B40D +XM",=$)`01````QP0D`````.A;X___QX7X^O__`0```.D8_/__BY4`^___NP$` +XM``"+@@`!``"#P`&#^#&)@@`!```/CUS]__\/MH(4`0``,-N+C?#Z__^(`<>% +XM]/K__P$```#I//W__XM%M(E%B(M%N(%EB/_Y__^)18R+1;R)19"+1<")192+ +XM1<2!991_____B468BT7(B46*`@("`=.GWPH"```!U +XM!L'J$(/!`@#2@]D#*=F-E0C___^)39#'1"0(`````(E4)`2+30B)#"3H)J(` +XM`.D[_?__D%6)Y8/L&(M%#(E=^(EU_(D$).A=X/__A<")PW01@_C_=`R)!"3H +XMZN/__X7`=1(QP(M=^(MU_(GL7<.-M@````"-<`&)-"3H>>+__XM5$(7`B0)T +XM'(ET)`B)7"0$B00DZ-#A__^+7?@QP(MU_(GL7C;0F`````(V\)P````!5B>53B<.#[`2+@(@! +XM``"%P'02B00DZ*GB___'@X@!````````BX.,`0``A+__\>#D`$```````"+@Y0!``"%P'02 +XMB00DZ%7B___'@Y0!````````BX.8`0``A6#[!B)=?B+=0B)??PQ_XE=](M>)/:#$`(``!AU$(GXBUWT +XMBW7XBWW\B>Q=PY")-"3HR`X``(7`#Y7`#[;XBX,0`@``)1`"```]$`(``'0Y +XMBX,0`@``)0@"```]"`(``'0YC8,$`0``B40D",=$)`01````QP0D`````.AB +XMW___@Z,0`@``Y^N5B?#HOO[__X7`=+R_`0```.NUBT8DZ`O^___KO8GVC;PG +XM`````%6)Y8/L2(72B77\B<:)7?AT'L=$)`@!````B50D!(D$).CNWO__BUWX +XMBW7\B>Q=PXU=T(E,)`R)'"3'1"0(^I8(",=$)`0H````Z`7>__^)7"0$B30D +XMQT0D"`$```#HL=[__XM=^(MU_(GL7<.-=@!5B>575E.#["R+=0B+7A"+0R2) +XM1>2`NU0(````#XB^`0``#[95#(/B`8G7#X0_`0``BX:L!```J`0/A5$!``#V +XM10P"=`BH"`^%0P$``*@$D'0)@^#[B8:L!```J`AT:X/@]XF&K`0``(U#"#D& +XM="S'1"0(`````(M&2`-&-(E$)`2A#"$)"(D$).B6W?__H0PA"0B)!"3HN=O_ +XM_\=$)`@`````BT8T`T9(@^@!B40D!*$,(0D(B00DZ&?=__^A#"$)"(D$).BZ +XMVO__B?B$P`^$S````(M&$(M8)(N#$`(``*@(#X75!```]L0"#X4Q`P``BU7D +XM@XH0`@``"?:&K`0```$/A(@```"+1>2+D(P!``"%TG1[]H8@`@```0^$`@4` +XM`(N&&`(``(T$0,'@`@-&$(M`.(/H`8D4)(E$)`C'1"0$`````.@YV/__QT0D +XM"(#*!`C'1"0$`0```(D$).@AV___@\0L,)-"3'1"0('(P(",=$)`0#````Z&^'``"#Q"RX +XM`0```%M>7UW#B?:)'"3H^/S__X7`#X7``P``@:-4"```?____^DC_O__D,<$ +XM)`$```#HR-W__X7`=*G'1"0(`````,=$)`0_````B30DZ!B0``"%P`^%@`,` +XM`/:&]`,```$/A"P$``"+ANP#``"-!$#!X`(#1A"+6#C'!"1MBP@(Z.G6__\Q +XMR8G:B47HN&V+"`CH)/W__\<$)/2+"`CHS-;__XE%[/:&(`(```$/A/<#``"+ +XMAA@"``"-!$#!X`(#1A"+2#@QTKCTBP@(Z.K\___'!"3ZBP@(Z)+6__^)1?#V +XMAF`!```!#X2R`P``BX98`0``C01`P>`"`T80BT@X,=*X^HL(".BP_/__Z%_: +XM___'``````"A`"$)"(D<)(E$)`BA!"$)"(E$)`3H']?__X7`#X2:`P``BTWH +XMAR%T@^$UP,``(M%\(7`#X2[`P``B70D!(M&$(V?7`$``(D$ +XM).B][/__Z,S9___HM]C__XUV`.B_VO__H0PA"0C'1"0$`0```(D$).CZU___ +XMH0PA"0C'1"0$`0```(D$).CEV/__QX<,`@```0```,=$)`0`````QP0D$@`` +XM`.CWVO__B5PD!,<$)`````#H1]7__X7`#X75`@``BX<$`0``]L0"=`J!CUP! +XM`````@``]L0$=`J!CUP!````!```@8]H`0``@````,:'=P$``/_&AW4!``#_ +XMQH=V`0``_\:'>P$``/_&AWH!``#_QH=^`0``_XDT).@+"@``A<`/A?4!``#I +XMK@$``(V#C`$``(E$)`C'1"0$18L("(DT).BT^/__C8.8`0``B40D",=$)`3@ +XMBP@(B30DZ)KX__^-@Y0!``")1"0(QT0D!.6+"`B)-"3H@/C__XV#B`$``(E$ +XM)`C'1"0$N8P("(DT).AF^/__C8.0`0``B40D",=$)`27C0@(B30DZ$SX__^+ +XM@Y@!``"%P`^$D@$``(N3E`$``(72#X1R`0``BX,$`0``BY,(`0``B8,P`0`` +XMBX,,`0``@\H#@8LP`0````$``(F#.`$``(N#$`$``(F3-`$``(F#/`$``(N# +XM%`$``(&+/`$``,\%``")@T`!``"+@Q@!``")@T0!``"+@QP!``")@T@!``"+ +XM@R`!``")@TP!``"+@R0!``")@U`!``"+@R@!``")@U0!``"+@RP!``")@U@! +XM``"!PS`!``")7"0(QT0D!!$```#'!"0`````Z$O9__^%P`^$7UW#@\0L +XMN`$```!;7E]=PX'#,`$``.NTO__Z1C\__^)7"0,QT0D"`*,"`C'1"0$ +XM`P```(DT).@9@@``N`$```#I8?K__Y"0D)"0D)"0D)"0D)"0D%6)Y8/L"*&@ +XM%`D(BU4(A"N+`8@0@\`!#[;2B0')B=## +XMH00A"0B)%"2)1"0$Z![2___)B<*)T,.-="8`.T$8?`6`^@IURXD4)(E,)`3H +XMOM?__XG"Z\>-M@````!5B>575E.#["R+=1B%]G0&QP8!````C47LB40D",=$ +XM)`1H=`A`QP0D`@```.BSTO__@\`!#X2&`0``#[=][`^W1>Z%_P^4PX7`B47< +XM#Y1%XXM%#(7`=!R$VP^$Y````(7V=`;'!@````"#Q"PQP%M>7UW#A-L/A+D` +XM``#'!"1MBP@(Z`W1__^%P'05A-L/A8P!``"`?>,`#X51`0``C78`A?]U!&:_ +XM&`"+7=R%VW4'QT7<4````,<$)/2+"`CHTM#__X7`=!K'1"0("@```,=$)`0` +XM````B00DZ*;4__^)Q\<$)/J+"`CHJ-#__X7`=!O'1"0("@```,=$)`0````` +XMB00DZ'S4__^)1=R+31"%R70%BU40B3J+512%T@^$1____XM%%(M5W(D0@\0L +XM,,!Z7G^__^+@A@"``"-!$#! +XMX`(#0A"+0#CI>____\<$)&R,"`CHRM;__X7`>#B)1=SIFO[__XG"BX!8`0`` +XMC01`P>`"`T(0BT`XZ6?____'!"1'@QP(/$<%M>7<.-M"8`````#[=%H(D<)"7O_P`` +XMB40D!.@_U?__A +XM7<.%]G0FB5PD#,=$)`BXC0@(QT0D!`4```")-"3H^'T``+@!````Z6#___^# +XMQ'"X`0```%M>7<.)]H7V=.Z)7"0,B30DQT0D")^M"`C'1"0$!0```.C`?0`` +XM@\1PN`$```!;7EW#C70F`%6)Y5.#[!2+70B+50R+0Q"#^AZ+2"1T>WX6@_H_ +XM="&#^DIT-8/$%#'`6UW#C70F`(/Z"'0+@_H8=>J-M@````"!B%0(``"````` +XM,<"#HZP$``#S@\046UW#BT44BP"%P'56@XD0`@``!(M#((7`=+2+0`B%P'2M +XMB1PDQT0D"`$```")1"0$Z&77__^#Q!0QP%M=PXM%%(L0B1PDB4PD!(72#Y3` +XM#[;`B40D".CP_?__@\04,Q=Z9_^__^+7?0QP(MU^(M]_(GL7<-5B>53@^P$BT4(BX!$`0``A@`````B?:+5>B+@B"."`B)!"3H$\__ +XM_X7`B<B+@CB."`B#PA")5>B%P`^%3?___XL=2(\("(7;#X3+````QT7D +XM`````(MUY(N&0(\("(D$).A+SO__A<")1?`/A)$```"#P`$/A(@````/MH9, +XMCP@(OR`0"0@Y!2`0"0AT"X/'"#D'=?F%_W1IBT7DBU7PBX!(CP@(B470B10D +XMZ*'1__^+==")-"2)P^B4T?__C5<$QT0D(`8```#'1"0<`@```,=$)!@!```` +XMB50D%(E<)!"+5?")1"0(B70D!(E4)`R+=0B)-"3HX\\``(7`#X5E`0``BU7D +XMBX)8CP@(@\(0B57DA<`/A3S___^+#6B/"`B%R0^$30$``,=%X`````#ID0`` +XM`(M5X(MU[(N2:(\("(E5U(DT).@'T?__B478BT7$B00DZ/G0__^+5=2)%"2) +XMP^CLT/__QT0D(`8```#'1"0<`@```(MUV(ET)!B+5>R)7"00B50D%(MUQ(E$ +XM)`B)="0,BT74B40D!(M5"(D4).@YSP``A<`/A;L```"0BW7@BX9XCP@(@\80 +XMB77@A<`/A+````"+=>"+AF"/"`B)!"3HW,S__X7`B47$=-&#^/]TS/R_C8P( +XM"+D"````B<;SIG2[BT7@BX!DCP@(A<")1>P/A2W___^+=<2+5>")-"2+NFB/ +XM"`CH-]#__XD\)(G#Z"W0___'1"0@!@```,=$)!P"````QT0D&`````#'1"04 +XM`````(E<)!")="0,B40D"(E\)`2+10B)!"3H?LX``(7`#X1&____@\1____XL3A=)T!HM#!(E"!(M#!(D0B1PDZ`;.__^+GD`!``"%VW7-C88L +XM`0``.88L`0``=`Z)10B#Q!!;7EWI//___X/$$%M>7<.0C70F`%6)Y5.#[`2+ +XM0!"+D$`!``"%TG1*,=L/MD(0@^@Q/`AW#P^VP/\DA;"/"`B)TXUV`(L2A=)U +XMX(7;="2+$X72=`:+0P2)0@2+0P2)$(U#"(D$).C:_O__B1PDZ';-__^#Q`1; +XM7QD(0->N8QD(0-(UT)@#KCHVT)@````"-O"<`````58GE@^P8QT0D!#P` +XM``")7?2)=?B+=12)??S'!"0!````Z-[*__^%P(G##X2#````A?:)QXEP#'47 +XMBT40B4,0B?B+7?2+=?B+??R)[%W#B?:)-"3H+,S__X7`B4,(=":+30R%R733 +XMBU40A=)TS(M5$(D$)(E4)`B+50R)5"0$Z#',___KM(M5",=$)`@`````QT0D +XM!`4```")%"3H<'4``(M#"(7`=;B)'"0Q_^ASS/__ZXR+10@Q_\=$)`@````` +XMQT0D!`4```")!"3H0'4``.EJ____C70F`(V\)P````!5B>564X/L,(M="(U% +XM](MU&(E$)!"-1?")1"0,QT0D"`$```"+10R)'"2)1"0$Z*U```"%P'0,@\0P +XMN`$```!;7EW#BT7TB1PDQT0D"`````#'1"0$`````(E$)`SHOO[__X7`B<-T +XMSXM%](7`="R+512%TG1,BU7PBT,(`540BU44B50D"(M5$(D$)(E4)`3H/\O_ +XM_XM%%(E#$(U6"(D3BT8,B4,$.U8(=!^+1@R)&(E>#(M#$`%&%(/$,%LQP%Y= +XMPRM%$(E%%.NLB5X(Z^&058GE5U93@^PLBT4,BWT(A<`/A,X"```/M@#V11@$ +XMB$7K#X4-`0``]D48`@^%^0```,=%[``````/ME7K,N+1Q"+L$`!``"%]G4/Z9`"``"+-H7V#X2&`@``.E80=?&% +XM]@^$>0(``(7)B?8/A(X!``#V11@!#X2'````@$X8`8M5$(M-%(L:.QEV$^D@ +XM`0``BT44@\,!.1@/@A(!``")="00QT0D#`````#'1"0(`````(E<)`2)/"3H +XM+?[__X7`=,Z-1@B)!"3HOOO__[@!````QT84`````,9&&`"#Q"Q;7E]=P_9% +XM&`$/A(X!``")^.AE_/__QT7L`0```.GQ_O__BTT0,<"+$8M-%#L1#X0E`0`` +XMBTT0B70D$(E$)`R+002)5"0$B3PDB40D".BY_?__ALQQT7L`````,=% +XM\`````#I0?W__\=$)`0<````QP0D`0```.@;QO__A<`/A)````")Q@^V1>N( +XM1A"-1@B)1@B)1@R+5Q"+@D`!``"%P(D&=`R+@D`!``")<`2+5Q")LD`!``"+ +XM1Q`%0`$``(E&!.DR_?__,<"#?>P`#Y3`B47P#[:4DS0$``"(5>L/MM+IP_S_ +XM_XM5$(M-%(L".P$/A4W___^+=Q`QR<=%[`````#'1?``````@<8D`0``Z=/\ +XM___'1"0(`````,=$)`0%````B3PDZ'=P``"X`0```.DO_?__D)"0D)"0D)"0 +XMD)"0D%6)Y5=64X/L/(M=%(MU"(M]#(7;#X2D````BT40BPB)3?")RCD/=FOI +XMA0```(UV`(-&9`&Z'X7K48M-\(G(]^+!Z@5KTF0YT74_BT80]H!4"```!'5< +XMQT0D#`$```#'1"0(`````,=$)`0`````B30DZ!HT``"%P'4,BT80]H!4"``` +XM!'4LBTWPC5'_B57P.1=W'XE4)`2)-"3H040``(7`=(V[`0```(/$/(G86UY? +XM7<,QVX/$/(G86UY?7<.-1?")1"0$B30DZ(,]``"%P'72BTT0BQ$[5?`/@M4` +XM``"0#X23````B57P.Q=W=XUV`.DF`P``@T9D`;H?A>M1BTWPB+1A#V@%0(```$#X7\`@``QT0D#`$```#'1"0(`````,=$)`0````` +XMB30DZ%$S``"%P'40BT80]H!4"```!`^%R`(``(M-\(U1_XE5\#D7#X.W`@`` +XMB50D!(DT).AP0P``ADJ____C47HC5WDB40D$(E<)`S'1"0(`0```(E4 +XM)`2)-"3H=3H``(7`#X4`____BU40BT($.T7H#X-%!0``BQ*+!SG0#X22`P`` +XMBU\$QT7@`````(7;B5W<#X20````C57DQT0D$`````")5"0,QT0D"`$```") +XM1"0$B30DZ!HZ``"%P`^%I?[__X7V#X3^`@``BUX0A=L/A/,"``#V@U4(```! +XM#X7F`@``BT7"+0WB)1>R!BU0(`````0`` +XMBUW")!"3HIL3__XM-$(L1C47HC5WDB40D$(E<)`S' +XM1"0(`0```(E4)`2)-"3HBSD``(7`#X57`0``BU7HA=(/A)@```"+11"+0`2) +XM1=2-0O\Y1=0/A(,```"+3=R-1!'_*T74.<$/AQ8$``"+3=R%R0^%MP,``(7V +XM=!2+7A"%VW0-]H-5"````0^$*00``(7`QT7L`````,=%X``````/A08%``"+ +XM1>2+7>`K5=0#7=R#P`$#1=2#Z@&)5"0(B1PDB40D!.CGP___BU40BT7H`47< +XM@VW<`8M2!"E5W(M-W(E,)`R+7>")7"0(BP>)-"2)1"0$Z'0]``"%P`^%D``` +XM`(M5$(L"B47P.0=R=.E5`0``@T9D`;H?A>M1BTWPB+ +XM1A#V@%0(```$#X4K`0``QT0D#`$```#'1"0(`````,=$)`0`````B30DZ.$P +XM``"%P'40BT80]H!4"```!`^%]P```(M-\(U!_XE%\#D'#X/F````B40D!(DT +XM).@`00``AP___Z8W\__^-1>B)1"00C47DB40D#,=$)`@!````BP>) +XM-"2)1"0$Z-$W``"%P`^%7/S__X7V=':+7A"%VW1O]H-5"````75FBT<$.T-X +XM#X?4`@``BU-TB57@BT-XB47L@8M4"`````$``(M'!(E$)`B+1>2)1"0$BTW@ +XMB0PDZ&["__^+1P2)1"0,BUW@B5PD"(L'B30DB40D!.@./```A<`/A>G[__\Q +XMV^DH____QT7L`````(M'!,=%X`````"%P'2JB40D#(U%[(E$)`C'1"0$```` +XM`(DT).@/X```A<`/A*K[__^)1>"+1P3I?/___XM%W,=%[`````#'1>`````` +XM!0`!```/A"7]__^)1"0,C47LB40D",=$)`0`````B30DZ,7?``"%P(E%X`^% +XM__S__^E8^___D(UT)@"-1>B)1"00C47DB40D#,=$)`@!````B50D!(DT).B> +XM-@``A<`/A2G[__^%]@^$NP```(M>$(7;#X2P````]H-5"````0^%HP```(M% +XMZ#E#>`^"+@(``(M3=(E5X(M#>(E%[(&+5`@````!``"+1P2%P`^%G@$``(M= +XM$(M%Y(M;!(/``8E=V(M5V(M=X`-?!`-%V/?2`U7HB40D!(D<)(E4)`CH#<'_ +XM_XM'!(M5$`-%Z(/H`2M"!(E$)`R+3>")3"0(BP>)-"2)1"0$Z*$Z``"%P`^% +XMO?W__S';Z;O]__^!H%0(``#__O__Z6OZ__^+1>C'1>P`````QT7@`````(7` +XM#X1F____B40D#(U%[(E$)`C'1"0$`````(DT).B/W@``A<")1>`/A4#____I +XM(OK__S';A?9T>HM>$(7;='.+3>`Y2W1T:SM%[`^&6?S__XE$)`R-1>R)1"0( +XMBTW@B30DB4PD!.A'W@``A<`/A.+Y__^+71")1>"+5>B+6P2)7=3I(_S__\=$ +XM)`C4CP@(NP$```#'1"0$`P```(DT).AN:0``Z?+\__^+71"+$^GE^?__@:-4 +XM"```__[__SM#>`^'E@```(M#=(E%X(M#>(E%[(&+5`@````!``"+51"+4@2) +XM5=2+5>CIO?O__XE$)`R-0WB)1"0(BT-TB30DB40D!.BKW0``A<`/A$;Y__^) +XM0W3I`OW__XE$)`B+1>2)1"0$BTW@B0PDZ(F____I1_[__XE$)`R-0WB)1"0( +XMBT-TB30DB40D!.AFW0``A<`/A`'Y__^)0W3IA?K__XE$)`R-0WB)1"0(BT-T +XMB30DB40D!.@\W0``A<`/A-?X__^)0W3I0/___XE$)`R-0WB)1"0(BT-TB30D +XMB40D!.@2W0``A<`/A*WX__^)0W3IJ/W__XE$)`R-1>R)1"0(QT0D!`````") +XM-"3HY]P``(7`#X6@_O__Z7WX__^0D)"0D)"0D)"058GE@^P8BU4(]H)$`@`` +XM`70DBX(\`@``C01`P>`"`T(0BU`XA=*Z`0````^4P(3`=!C)B=##BX(\`@`` +XMN@$```"%P`^4P(3`=>CHY;O__\<``````,=$)`0&````BT44B00DZ+RY__^% +XMP'4DQT0D"`$```#'1"0$`@```(M%%(D$).C]M___N@$```#)B=##Z)^[__^# +XM."-T%HVV`````.B/N___,=*#."-UAHUT)@#)N@(```")T,.-M"8`````58GE +XM@^P8B5WXBUT(B77\BW4,BX.D````AQ=PXD<),=$ +XM)`@`````QT0D!`4```#H`&<``(M=^(MU_(GL7<.-M@````!5B>6#[!B+30B+ +XM41R%TG0.BT$@]D`80'0%@SH!?@3),<##BT4,ABX48VO__A%#-K__P````"%P`^$/@$``(M%&(/@`H/X`1G2@>+X`P``@<()`@`` +XMB84(VO__B94`"`T(0BW`XZ*6X___'```` +XM``#'1"0(`````,=$)`0`````BY5`VO__B10DZ$&Z__^%P(F%*-K__P^(L@4` +XM`(V=C/[__S'_B5PD!(M%"(D$).A8)P$`QT0D&`````#'1"04`````,=$)!`` +XM````QT0D#`````#'1"0(`````,=$)`0`````B1PDZ!`R`@"`/DX/A`<%``") +XM-"3HT[O__XET)`B)7"0$B40D#(M5"(D4).B(-0$`A<`/A*`#``"`O0;:__\` +XM#X2&`0``N`$```"!Q!PF``!;7E]=PXUV`("]!]K__P`/A#,#``"%VP^%*P,` +XM`(N5$-K___9"6`$/A?0&``"+E1#:__^+19`[0D0/A`D#``#V11@0N"R1"`AU +XM!;ATD0@(B40D#(N%0-K__\=$)`0#````B40D"(M5"(D4).AX:```N`$```#I +XM@/___XM5"/:"^`(```$/A#X#``"+@O`"``"-!$#!X`(#0A"+6#B%VP^5P(3` +XM#X1:_?__]D48$+ATD`@(=06XJ)`("(E$)`C'1"0$`P```(M5"(D4).@(8P`` +XM@<0<)@``N`$```!;7E]=PXM5&(F=0-K__\>%&-K__P````#&A0?:__\`@^($ +XMB94`VO__#Y2%!MK__^D%_?__B<*+@*`$``"-!$#!X`(#0A"+4#B%T@^4P.D1 +XM_?__BX4DVO__B00DZ#&W__^%P`^%D@D``(N%.-K__X7`="Z+10B%P'09BU4( +XMBT(0A#91@#@WT8`0^$E@4``(U%Z(E$)`B+A4#:__^)1"0$ +XMBU4(B10DZ.A4``"+G0S:__^%VXF%(-K__P^%+00``,=$)`@`````QT0D!$R2 +XM"`B+10B-O4SZ__^)!"3H,U<``(M5[(E4)!2+5?")5"00BY4@VO__B40D",=$ +XM)`1`!```B3PDB50D#.BKM?__B?F)PXM%"(MP.#GS#X-5!@``B4PD#,=$)`B? +XMK0@(QT0D!`0```"+10B)!"3HUF```(M5Z#'`A=(/A.O\__^+10B%P'09BU4( +XMBT(0AWZ__^-E7#___^) +XM5"0$BX5`VO__B00DZ%"R__^%P`^%F`0``(N5$-K__X!*6`&+A7#___^)0CR+ +XMA73___^)0D"+19")0D3I&/W__^B\LO__@S@"#X12_/__B[5`VO__QX4PVO__ +XM`````,>%.-K__P````#'A23:________@[THVO___W0.BY4HVO__B10DZ`BS +XM__^#O23:____=!R+A3#:__^)!"3HL;#__XN5)-K__XD4).CCLO__A?9T'\=$ +XM)`R?K0@(B70D",=$)`0%````BT4(B00DZ#QC``"+O3C:__^%_P^$+OK__XMU +XM"(7V=!F+50B+0A"%P'0/BY4XVO__.5!T#X0&!0``BX4XVO__B00DZ`2U___I +XM^_G__X7_#X13`0``BT4(A<`/A*(#``"+10B+6!"%VP^$E`,``/:#50@```$/ +XMA8<#``"+A0#___^+`(M`"(U$`#([0W@/A[\%``"+4W2)E3C:__^+0WB)1>2! +XMBU0(`````0``BX4`____BXTXVO__BQ"#P0&+`@^V$(32#X3Y!```BYTXVO__ +XMC4@!QX4TVO__`````.L@@/HO#X17`0``#[9!_X@##[81@\,!@\$!A-(/A,@! +XM``"`^B5UVX`Y)73?Q@,E@\,!Z]>#O0S:__\!=$+HS:[__XU=T,=%V`$```#' +XM1=P`````B5PD!(M5"(D4).CI*@``A<`/A0[Y__^-1=C'1=0`````B44,B5T0 +XMZ>OZ__^+C0C:__^X>)(("(7)=06XI)((",=$)`@`````B40D!.ES^___BX5P +XM____.T(\#X4/^?__BX5T____.T)`#X4`^?__Z>GX__^-="8`BX4`____BP"+ +XM`,>%.-K__P````")A3#:__^-A1#___^)1"0$BY4PVO__B10DZ,*O__^Z`0H` +XM`(7`#X7/`@``#[>%&/___R4`\```/0"````/A'0#``#'1"0,190("(ET)`@Q +XM]L=$)`0#````BT4(B00DZ"EA``#'A23:________Z7_]__^!H%0(``#__O__ +XM,<#I&_C__XF=--K__^F>_O__BY40VO__@&)8^XN5%-K__P^W0AB$P`^)3OK_ +XM_X"]!]K__P`/A#X#``"#R$!FB4(8Z37Z___HN*___X,X#9!U#HN=`-K__X7; +XM#X5]`P``QT0D#)^M"`B+A4#:___'1"0$!0```(E$)`B+50B)%"3HBV```+@! +XM````Z9/W___&`R7&0P%DQD,"`(N%--K__X7`#X3U`@``BY4TVO__Q@(`BX4X +XMVO__B00DZ,6N__^+E33:___&`B^#P@&)E3S:__^)QX7_#X0\`@``QX4LVO__ +XM`````(D\).@'LO__A<`/A$0!``"-5>"#P`B)5"0(BY4\VO__B00DB50D!.B# +XMKO__@^@!=<^+1>`YA2S:__]]Q(F%+-K__^N\QT0D#)^M"`B+E4#:___'1"0$ +XM!0```(E4)`B+10B)!"3HPE\``(D<).@^K___N`$```#IPO;__XN5(-K__XD4 +XM).A6LO__C4[]C10'B?@YUW(0ZQJ-="8`@\`!.<)V#X/K`8`X+XUV`'7N.%.-K__P````"-1``R +XMA<`/A([\__^)1"0,C47DB40D",=$)`0`````BU4(B10DZ(O.``"%P`^$)@(` +XM`(F%.-K__XN%`/___XN-.-K__XL0@\$!Z4S\__^)/"3HL['__XN%+-K__\=$ +XM)`A:W@@(@\`!B40D#(N%.-K__P-%Y(D<)"G8B40D!.@WKO__BX4XVO__B84P +XMVO__Z0S]___'1"0(@`$``(E4)`2+E3#:__^)%"3H+*___X7`B84DVO__#XC/ +XM^O__C95,VO__QT0D"``@``")5"0$BX4HVO__B00DZ#ZQ__^#^`")QP^.EP$` +XM`#';ZP8IQW3-`<.-A4S:__\!V(E\)`B)1"0$BX4DVO__B00DZ*NH__^%P'G8 +XMB[4PVO__Z6WZ__^!H%0(``#__O__Z?GT__^+A0#___^+`(LPQX4PVO__```` +XM`,>%)-K________I._K__XN='/___^C?K___.<-T%)-K________I_/G__XN5%-K__X/@OV:) +XM0ACI\?;__XN%.-K__\8`)8G#Q@%DQD$!`,<$)$'Q"`CHVZO__XG'BX4XVO__ +XMB84\VO__Z1?]__\/MX48____N@$$``"H-@^$KO[__\=$)`S4D0@(Z?'[__^- +XMA1#___^)1"0$BY5`VO__B10DZ&^K__^%P'41#[>U&/___XGPA,`/B8$```#H +XM]:O__\<`#0```.E&_/__B40D#(U#>(E$)`B+0W2)1"0$BT4(B00DZ&G,``"% +XMP'0(B4-TZ1CZ__\Q]L>%,-K__P````#'A3C:__\`````QX4DVO_______^D- +XM^?__?!:+E2C:__^)%"3H'*S__X7`#X35]/__B[5`VO__Z>KX__^+G1S____H +XMCJ[__SG##X5L____9H'.@``/M\:)1"0$BY5`VO__B10DZ!RN__^%P`^%2O__ +XM_\=$)`BV`0``BX4___\G#C;0F`````(N"\`(``(7`#Y7`ZX&-=@!5,G"[O__B?:+@QP! +XM``"-!$#!X`(#0Q"+0#B%P`^5P(3`=____Y"-M"8`````58GE5U93@>R\"``` +XMBU4,#[="&*@@="&#X-]FB4(8B50D!(M-"(D,).BCK@``@<2\"```6UY?7<.+ +XM50R#X`%FB4(8QT0D!%P```#'!"0!````Z!ZF__^%P(F%5/?__P^$UP8``(N% +XM5/?__X!(6`+'0!0`````QT`0`````,=`2/_____'0%3_____BU4,BU((A=*) +XME5SW__\/A!@"``"+C5SW__\/M@$\+P^$)P,``#PN#X0#`P``C95L____B50D +XM!(N-7/?__XD,).@5I/__N@$```"%P`^$Z0```(M%"/:`U`(```$/A-P&``") +XMPHN`S`(``(T$0,'@`@-"$(M0.(UR`>L-A-L/A&,&``")\H/&`0^V7O^`^SIT +XM!(3;=?"-1OXYPG/?QD;_`(N%7/?__XV];/?__XE4)`S'1"0(N90(",=$)`0` +XM!```B40D$(D\).C.I/__C95L____B85@]___B%[_B50D!(D\).ASH___A)UL'_'XG_P?\? +XMB?Z)_L'N%C'_`<81UP^L_@K!_PJ#_@IW#(7V9KL`!`^%E@4``(N%5/?__X!( +XM6`&+A6S___^+E53W__^)0CR+A7#___^)0D"+18R)0D0/MX5T____)0#P```] +XM`(````^$)`(``,=$)`RXDP@(BXU8]___QT0D!`,```")3"0(BT4(B00DZ-]3 +XM``#I^@$``(MU%(/F"(UT)@#'1"0(`````,=$)`0*````BU4(B10DZ*57``"% +XMP`^$%P$``(M5#(M""(7`=!*)!"3HGZ7__XM-#,=!"`````"+50PQVXM"#(7` +XM="")!"3HP:#__XM-#(M!#(D$).ASI?__BT4,QT`,`````(N55/?___9"6$`/ +XMA24$``"+C53W__^+04R%P'05B00DZ$2E__^+A53W___'0$P`````BY54]___ +XMBT($A7UW##[9! +XM`3PO=!0\+@^%[?S__X!Y`B^)]@^%X?S__XV%;/___XE$)`2+A5SW__^)!"3H +XM]J#__S'2A<`/E,+IR_W__XM-"/:!>`$```$/A+`#``"+@7`!``"-!$#!X`(# +XM01"+0#B-G6S[__^)1"0,QT0D"+^4"`C'1"0$``0``(D<).CFH?__B1PDZ.ZB +XM__^#^/\/A-4#``")!"3HO:'__XM%#(M0"(72#X0L!```B1PDZ)>=__^+50R% +XMP(E"#`^$[@,``(M""(7`#X2^`P``BU4,A?:+4@R)E5CW__\/A#P#``"+A53W +XM__^[``0``(/`1(D$).A4G/__BU4(QT7,`````,=%X`````#'1=``````QT78 +XM`````,=%W`````#'1>0`````QD7@"HE=U(M"$(N`5`@``(/@0(/X`1G`]]"# +XMX`2)12+A53W__\QTH!(6`2-1Z``"%P'4,BY54]___BT),B47DBY58]___Z0_] +XM___'1"0(E),(",=$)`0%````BTT(B0PDZ$%)``#IG_K__XD<).BXF?__BTT, +XMA<")00@/A2S\__^+00R%P'0(B00DZ"N@___'1"0(`````,=$)`0%````BT4( +XMB00DZ/Q(``")'"3H2)O__^E2^O__9H%(&(``Z__^%P'5WBU4,9H%*&``!Z1/[__^[`0```(U][(UUZ.L1C;0F```` +XM`(M%[(7`=2:#PP&)?"00B70D#,=$)`@`````B5PD!(M%"(D$).CG$0``AR%P'0(BT7H@#@C=,N+30B)64R[`0```.GK^O__#[9``3PJ +XM=&P\+P^%8?___XM5"(&*K`0````!``"#1>@"@VWL`NL*@T7H`8/H`8E%[(M% +XM[(/X`780BU7H@#HO=>:`>@$O=>#KIX/#`8E\)!")="0,QT0D"`````")7"0$ +XMBT4(B00DZ,L0``"%P'3"Z?W^__^+50B!BJP$`````0``ZPV-=@"#1>@!@^@! +XMB47LBT7L@_@!=A.+5>B`.BIUYH!Z`2]UX.E%____@\,!B7PD$(ET)`S'1"0( +XM`````(E<)`2+10B)!"3H:1```(7`=+_IF_[__U6)Y5:)UE.#[""+6!"-5?") +XM5"0,C57WB50D"(E,)`2)!"3_DX0(``"%P'54BT7PA53BUT(#[9-#/:#X`(```$/A!P!``"+@]@"``"-!$#!X`(# +XM0Q"+0#B%P'0]#[80A-)U$.LT#[90`832C78`="F#P`$XT77NB(N(````N`$` +XM``")@Y````#&A!B(`````(V#B````%M=P_:#C`(```$/A<<```"+@X0"``"% +XMP`^$TP````^V$(32=13IQP````^V4`&$T@^$NP```(/``3C1=>T/MM$[%?P@ +XM"0A]$*$((0D(]D20-0(/A0H!``#V@Z0"```!#X3M````BX.<`@``C01`P>`" +XM`T,0BT`XA<`/E<"$P`^$D0```,'J!@^V@CR6"`C&@X@```!`"`T,0BT`XA<`/A2W___\/MM$[%?P@ +XM"0@/C4#___^A""$)"/9$D#8$#X0P____Z +XM=`.-04"(@XD```"X`@```.E8_O__C70F`%6)Y5.#[`B+70B+10R)'"2)1"0$ +XMZ.?]__^+@Y````"#Q`A;7<.-="8`C;PG`````%6)Y5=6,?93@^P,BT4(BW@0 +XMB7WPBU4(B70D!(D4).BM_?__BU4(B<.+@I````"(AUT!```/ML"-2/^#^?]T +XM)(M%\(T4=HV44%@!``"-="8`#[8#@^D!@\,!B`*#P@&#^?]U[8/&`8/'!H'^ +XM_P```'6C@\0,6UY?7<.-M"8`````58GEBT4(5XM]#%8Q]E.+2!#K#\>!'`$` +XM``````"^`0```(N9&`$``(7;="QKD1P!```53@^P4BUT,BU4(@WL(#'8%Z'R2__^+0PC_)(7H +XME0@(QT0D",N5"`C'1"0$`P```(D4).BF0```C;8`````BT,,A6# +XM["B+10S'1"00@`L%",=$)`P(````QT0D!"`0"0B(1?RAZ!`)"(E$)`B-1?B) +XM!"3H+)3__S'2A`` +XM``"+BQ0!```Y310/A]<```"-="8`BTT4`8L8`0``BY,0`0``A7UW#BY,8`0``A=(/A$?___\K112)@QP!``#I.?___XN[&`$` +XM`(N+%`$``(M5%(U$`AZ-%#@YRG-'A?]U:K@>````QX,<`0``'@```.D'____ +XMBU4(BT(0,=*`N%('``#_#X5X____BTT(QT0D!/\```")#"3H/_[__XG"Z5[_ +XM__^#^D!S!;I`````BT4(Z+;]__^Z`0```(7`#X5:____B[L8`0``ZY)KQQR+ +XMDQ`!``")1"0(:X,<`0``'(T$`HE$)`1K110@0"0C'1"0,@`L% +XM",=$)`@(````QP0D(!`)"(E$)`3HA(S__\:&4@<```"+'>@0"0B%VW0^,575E.#[&R+10B+>!"+10R%P`^$WP4``(M-%(M%%(/A0(/@08E- +XML(E%K(N'&`$``(7`="J+1;"%P`^%L04``(M%K,=%R`````#'1<0`````A<`/ +XMA#0!``"-M@````#VAU0(```@#X6F`P``QT7(`````(M-$(E,)`R+112#X#&) +XM1"0(BT4,B40D!(M5"(D4)/^7>`@``(7`#X7P`@``BTT,BT$(C5#]@_H'=R3_ +XM))40@)#X3?`@``BTT,BP&)`HM!!(E"!(M!"(E" +XM"(M!#(E"#(M!$(E"$(M!%(E"%(M!&(E"&,=%Q`````"+3:R%R0^%9`0``(M% +XM%(M5%(/@!H/B`HE%N(E5M&NW'`$``!P#MQ`!``"#?@@!#X6 +XM_?__BT4(]H`<`P```0^%S0(``(M%"(N`%`,``(7`#Y7`A,`/A!`#``"#1<@! +XM@WW(`70?BT7(NF=F9F;WZHM%R,'Z`L'X'RG"C122`=(Y57UW#QT7$`0```.G:_?__@_@( +XM#Y7`#[;PBT4(@\8&BT`0B47,BU@(B<>#QP@Y^W08C;8`````B1PDB70D!.AD +XMI```BQLY^W7NBU7,BUH0B=>#QQ`Y^W2?B1PDB70D!.A#I```BQLY^W7NZXN+ +XM0Q@!AQP!``#IL/[__XM5"(D4).AB?P$`A<`/A$?\___I9?___Y"-="8`BUW0 +XMBT$0A=MT?XG&BT70C5H<`?")1;SK)XVT)@````"+30@/ML"+41`/MI0"4P<` +XM`(E3],9#^`"#PQP[=;QT2<=#[`$````/M@:#Q@$\_XA#\'7,BU4(BT(0,=*` +XMN%('``#_=''`$```````#IZOW__XG!BX`4`P``C01`P>`"`T$0BT`XA<`/E<#I(_W_ +XM__9%%`ATBXM-##'`QD$,8<=!$`````#'00@!````QD$4`(/$;%M>7UW#,<#I +XMG/W__XU5U(E5#.D6^O__QT0D$`8```"+0R")5"0(QT0D!`````")1"0,BU4( +XMB10DZ,;V__^%P`^%7OW__P^V5@R#^G]WCI"-="8`Z0O___^#AQP!```!,<#I +XM0OW__XL&BTT,B0&+1@2)002+1@B)00B+1@R)00R+1A")01"+1A2)012+1AB) +XM01CI`O___XM5"/:"&`0```%T58N"$`0``(T$0,'@`@-"$(M`.(7`#Y7`A,#' +XM11``````#X2_^?__@WX0"71+BT4(]H`(`@```70MB<*+@``"``"-!$#!X`(# +XM0A!K0#ADB440Z9#Y__^+30B+@1`$``"%P`^5P.NRBTT(:XD``@``9(E-$.EN +XM^?__BT4(]H"0`0```70HB<*+@(@!``#KLXM-"(M!$(.(5`@```2+10S'0`@$ +XM````,<#I6_S__XM-"&N)B`$``&2)31#I*/G__Y"0D)!5B>6#[!B+10S'1"0( +XM6)8(",=$)`0#````B40D#(M%"(D$).A8-```R<.-M@````!5B>6#[#B+50R) +XM??R+?1B)7?2)=?B%T@^$PP```(M%"(M8'(7;#X0X`0``]D40`G5"BT4(]H"O +XM!```"'0CBTAXBT!\BW$4B47@BT`4.?*)1=P/@]L````[5=P/AR`!``"+0Q`[ +XM10P/A+H```#'0Q``````C44,B47DC47LQT7H!````(M3!(E$)`B-1>3'1"0, +XM`````(E$)`2)%"3_4@R#^/]T;H/H`70WBT4,A?^)0Q"+1?")0PR+1>R)0PAT +XM!8M%\(D'BT44A<`/A+\```"+0PB+512)`C'`ZRJ0C70F`/9%$`%U+(7_=`;' +XM!P````"+512X`0```(72=`F+513'`@````"+7?2+=?B+??R)[%W#BT4,B40D +XM!(M%"(D$).BL_O__Z\"%_W2:BT,,B0>0ZY(YPG=*.?)T#8VV`````(L).U$4 +XM=?F%_W0%BT$0B0>+712%VW0WBT$(BU44B0(QP.NBQT0D"`0```#'1"0$```` +XM`(D$).CU_0$`Z6;___\I==PK5=R)50SITO[__S'`Z7#___^-="8`C;PG```` +XM`%6)Y5.#[!2+30B+70R+41R%TG1A,<"%VW0CBU(4A=)T(O:!KP0```AT#(M! +XM?`-0%(M!>"M0%#'`.=H/D\"#Q!1;7<.)7"0$QT0D$`````#'1"0,`````,=$ +XM)`@`````B0PDZ/G]__^%P`^4P(/$%%L/ML!=P\=$)`@$````QT0D!`````") +XM#"3H0_T!`+@!````ZZF-M@````"-OP````!5B>6#[$B)=?B+=0B)??R+?0R) +XM7?2+7AR%VP^$NP```(M3%(72="J)%S'`]H:O!```"'00BT9\`U`4BT9X*U`4 +XM,<")%XM=](MU^(M]_(GL7<.-1?")1>"-1>C'1>0$````BU,$B40D"(U%X,=$ +XM)`P&````B40D!(D4)/]2%(/X_W0Q@^@!=':+1>"+`(E%\(E#$(E#%(M%[(E# +XM#(M%Z(E#"/:&KP0```AU8(M%\(D',<#KD<=$)`C%E@@(QT0D!`4```")-"3H +XM13$``+@!````QP<`````Z6G____'1"0(!````,=$)`0`````B30DZ#W\`0"X +XM`0```.E'____,<#'!P````#I.O___XM&?(M`%#M%\'>8ZY.)]HV\)P````!5 +XMB>6#[#B)=?B+=1B)7?2+70R)??R+?0B%]G0&QP8`````BT44QT0D"`````") +XM7"0$B3PDB40D$(M%$(E$)`SH7/S__S'2ASVAJP$```!=4N+?AR#/P%T2XM&$(M8"(/`"#G#=0[K +XM/(M&$(L;@\`(.=AT,#G>=/`Y>QQUZXM%[(E$)`B+1?")'"2)1"0$Z.))`P"% +XMP'31N`$```"#Q!Q;7E]=PXM5"#'`A=)T[XM%[(E$)`B+1?")-"2)1"0$Z+)) +XM`P"#Q!Q;7E]=PXUV`(V\)P````!5B>564X/L((MU"(M>'(7;#X2\````QT0D +XM"`<```"+10R)-"2)1"0$Z),/``"-10R)1>B+11#'1>P$````B47PBT44B47T +XMBU,$C47PB40D"(U%Z,=$)`P`````B40D!(D4)/]2$(/``0^$B````(M#$#M% +XM#'1*]D-8`G4X@$M8!,=$)`@&````BT4,B30DB40D!.@I#P``BU4,B?"Y`P`` +XM`,<$)`$```#HL_[__X/$(%M>7<.)-"3H-)X``.N^B?;V0U@"QT,0`````'2O +XMC78`Z^*)-"3'1"0(!````,=$)`0`````Z-;Y`0"#Q""X`0```%M>7<.+10R) +XM-"3'1"0(X98(",=$)`0%````B40D#.B++@``@\0@N`$```!;7EW#ZPV0D)"0 +XMD)"0D)"0D)"058GE5U93@^PLBW4(BUX2+11#'1>@$ +XM````B47LBT44B47PBU,$C47LB40D"(U%Y,=$)`P%````B40D!(D4)/]2$(/` +XM`0^$Z````(M#$#M%#'<'QT,0`````(M#%(7`=`:#P`&)0Q3V0U@"#X6'```` +XM@$M8!+\!````QT0D"`4```"+10R)-"2)1"0$Z/(-``"+10S'1"0$`@```(DT +XM)(E$)`CH6QT``(G#BT4,QT0D!`(```")-"2)1"0(Z&(X`0"%P'4(A=L/E<`/ +XMMOB+50RY`@```(GPQP0D`0```.A`_?__N@$```"%P'4"B?J#Q"R)T%M>7UW# +XMB30DZ+.<``#I;/___XDT),=$)`@$````QT0D!`````#H9O@!`(/$++H!```` +XM6XG07E]=PXVT)@````"+10R)-"3'1"0(@)8(",=$)`0%````B40D#.@1+0`` +XM@\0LN@$```!;B=!>7UW#B?95B>575E.#["R+=0B+7AR%VP^$"0$``(U%$(E% +XMY(M%%,=%Z`0```")1>R+11B)1?"+4P2-1>R)1"0(C47DQT0D#`0```")1"0$ +XMB10D_U(0@\`!#X3O````BT,0.T40=@?'0Q``````BT,4A7UW#C70F`(V\)P````!5B>56 +XM4X/L((MU"(M>'(7;#X3*````BT4,QT0D!`$```")-"2)1"0(Z/,:``"%P'0/ +XMN`$```"#Q"!;7EW#C78`BT4,QT0D!`$```")-"2)1"0(Z.DU`0"%P'76QT0D +XM"`0```"+10R)-"2)1"0$Z"X+``"-10R)1?"-1?#'1?0$````BU,$QT0D"``` +XM``")1"0$B10D_U((@^@!='*+0Q`[10QR!\=#$`````"+0Q2%P'0&@^@!B4,4 +XM]D-8`G5&@$M8!(GPBU4,N0$```#'!"0!````Z&CZ__^#Q"!;7EW#D(DT),=$ +XM)`@$````QT0D!`````#HJ/4!`(/$(+@!````6UY=PXDT).C$F0``Z["+10S' +XM1"0(_I8(",=$)`0%````B30DB40D#.A3*@``N`$```#I__[__Y"0D)"0D)"0 +XMD%6)Y5.#[`2+70R+0QB%P'0-B00D_U`$QT,8`````(M#'(7`=`^)!"3H)X'_ +XM_\=#'`````#'0R``````,<#'0RP!````QT,P`````,=#*`$```#'0R0!```` +XM@\0$6UW#D%6)Y5.#[!2+70S'0QP`````QT,@`````,=#+`$```#'0S`````` +XMQT,H`0```,=#)`$```#'1"00`````,=$)`P"````QT0D"(`!``#'1"0$!@(` +XM`,<$)`````#H-('__S'2A<")0QAT"(/$%(G06UW#QT0D"!R7"`C'1"0$!0`` +XM`(M%"(D$).A4*0``N@$```"`2U@0@\046XG07<.-=@!5B>56B<93B7<.058GE5U93@^Q,BWT(BW<<#[966/;"$`^%Z`$``(M&*#M&)`^$ +XM`0(``(/*$(U&*(A66(E%Z,=%[`0```#'1<``````BT88C57@@T8H`8E4)`B- +XM5>C'1"0,`````(E4)`2)!"3_4`R%P`^%X0$``(M=X(`["'8+Z`IZ__^-M@`` +XM```/M@/_)(5\F`@(C57$C4,!B10DQT0D"!0```")1"0$Z!!^__^+1C'1>P$````B?:+1AB-5>"# +XM;B@!B50D"(U5Z,=$)`P`````B50D!(D$)/]0#(7`#X5W`0``BUW@@#L(=@7H +XMC'?__P^V`_\DA:"8"`B-0P&)1"0$C478QT0D"`@```")!"3HF'O__XM5"(M% +XMV#M"3'29@T8H`8!F6.\QP(/$3%M>7UW#C7L!C47$QT0D"!0```")?"0$B00D +XMZ&%[__^+1___BT4(BU!,.U7P='R+50B+1?`Y0E@/A'3___^#0F`!B4)8Z6C___^- +XM0P&)1"0$C478QT0D"`@```")!"3HQGK__XM5"(M%V#M"3`^%+O___X-^*`$/ +XMA;G^___I'____XUT)@")!"3'1"0(%)@(",=$)`0#````Z*@D``"#Q$RX`0`` +XM`%M>7UW#BT7DB50D!(/H!8E$)`R-0P6)1"0(BU4(B10DZ-OT__^%P`^$7/__ +XM_^DG____BT4(N>\!``"ZP)<(".@<^___N`$```#IL_[__XGV58GE5U93@^Q, +XMBWT(BW<<#[9&6*@0#X7=`0``@WXH`0^$^`$``(/($(A&6(U&*(E%Z,=%[`0` +XM``#'1<``````D(M&&(U5X(-N*`&)5"0(C57HQT0D#`````")5"0$B00D_U`, +XMA<`/A="`.PAV!>B,=?__#[8#_R2%Q)@("(U5Q(U#`8D4),=$)`@4 +XM````B40D!.B8>?__BT7,B478BT70B472#Z`6)1"0,C4,%B40D"(M%\(D\)(E$)`3HF_/__X7` +XM#X4]`0``BT7P.4=8=*J#1V`!B4=8QT7``0```.D(____C4,!B40D!(U%\,=$ +XM)`@$````B00DZ.)X__^+1>2#Z`6)1"0,C4,%B40D"(M%\(D\)(E$)`3H;O3_ +XM_X7`#X7@````@T=<`<=%P`$```#IMO[__XU#`8E$)`2-1?#'1"0(!````(D$ +XM).B0>/__BT7PB3PDB40D!.@=]___A<`/A9\```"#1V0!QT7``0```.EU_O__ +XMBU7`A=(/A&K^__^-0P''1"0("````(E$)`2+10R)!"3H1'C__S'`@&98[^L= +XMQT0D"$B8"`C'1"0$`P```(D\).A`(@``N`$```"#Q$Q;7E]=PXD\),=$)`AL +XMEP@(QT0D!`(```#H&R(``(/$3+@!````6UY?7<.)^+F(`0``NL"7"`CHO?C_ +XM_[@!````Z[N`9ECON`$```#KL(UT)@"-O"<`````58GE5XG75HG&4X/L+(M8 +XM'(-[(`AW*HU#(,=$)`P)````B40D"(M#'(DT)(E$)`3H3)8``+H!````ABT,H,=*#P`&)0RB)0R2#Q"R)T%M>7UW#C;8`````B?"Z +XMP)<("+G#````Z,_W__^#Q"RZ`0```%N)T%Y?7<-5,<")Y593@^P@BW4(BUX< +XM]D-8$`^%J0```(M++(7)#X6K````@WL@%'B+1?2#P`6)1>R+4QB-1>B)1"0(C47@QT0D#`````")1"0$ +XMB10D_U(0@\`!#X2-````BT,H@\`!B4,HB4,D,<"#Q$!;7EW#N@$```")\.C$ +XM_/__A7<.0C47TB40D +XM$(U%\(E$)`S'1"0(`@```(M%#(DT)(E$)`3H"^K__X7`#X38_O__BT4,@_@! +XM="Z)1"0$B30DZ+_I__^X`0```.N!B?"Y$0$``+K`EP@(Z.?T__^X`0```.EF +XM____QT7T`````,=%\$^-"`CIC_[__XUV`(V\)P````!5B>6+30B+41SV0E@0 +XM=1.+0BR%P'00BT%,B4(LBT%0B4(P73'`PXM!3(E"+(M!4(E",+H"````B'[__^058GE5E.#[""+=0B+1AB%P'0CQT0D"`$```#'1"0$`````(D$).AF +XMR/__BT88B00DZ'M>``"+1@B-7@@YV'00D(D$).AH7@``BT8(.=AU\8M&$(U> +XM$#G8=!:-M"8`````B00DZ$A>``"+1A`YV'7Q]H94"````G10ZUR-M@````"# +XM>P@#N>B8"`B+4PR+0Q!T!;E/C0@(B40D#*$0(0D(B50D$(E,)`C'1"0$\)@( +XM"(D$).AM;/__BQ.%TG0&BT,$B4($BT,$B1"+7FR%VW6Q@\0@6UY=PZ$0(0D( +XMQP0D!P```(E$)`3HF6S__^O;C78`58GE5HG64XG+@^P0BQ40(0D(B00DB50D +XM!.BF;?__A=MT&:$0(0D(B5PD",=$)`2=K0@(B00DZ/EK__^%]G0HZ)!P__^+ +XM`(D$).CF;?__QT0D!)VM"`B)1"0(H1`A"0B)!"3HS6O__Z$0(0D(QP0D"@`` +XM`(E$)`3H&&S__X/$$%M>7<.-M@````"-O"<`````58GE5U93@>R<`0``BT4( +XMBYAH"```A=L/A'L#``"+50B+BI0(``"%R0^$A0,``(M="+_XF`@(BTT(_(G8 +XM@\$(@\`0B8U\_O__BS.)0Q")0Q2#P'")0WR#Z`2)@X0```"#Z$R)0S")0S0% +XM_````(E+"(E+#+D#````QX.``````````,9#<`&)@RP!``")@S`!``#'@T`! +XM````````QX-$`0```````(FU@/[___.F#X6;`@``QX6(_O__`0```,>%E/[_ +XM_P````"+71"0C70F`(/#!(L3A=*)E7C^__]T9OR_`9D("+D#````B=;SIG15 +XMBY5X_O__#[8"/"L/A,\````\+77+B[5X_O__#[9&`83`#X0I`0``/&-T##Q4 +XM=`@\='0$/'=UJ8N%>/[__X!X`@!UG8/#!(/#!(L3A=*)E7C^__]UFHM%"#'_ +XM,=LQ]H.(5`@``$#'A8S^__\`````QX68_O__`````,>%G/[__P````#'A9#^ +XM__\`````C78`QT0D"`29"`B+31")3"0$BT4,B00DZ(IM__^#^/\/A!\"``"# +XMZ$:#^#$/AK4```"+50B[`0```/^2J`@``('$G`$``(G86UY?7<.-M@````") +XMUX/'`8!Z`0!U)<<$)`0```#HS7#__X7`B0,/A'H"``#'`"UC)`#IU/[__XUT +XM)@"+C7C^__^)#"3H]G'__X/``HD$).B;%D/[__P$```#I7O[__\>%E/[__P$```#I3_[__\>%F/[__P$` +XM``#I0/[__XM-"(.A5`@``+_I,?[__XNU@/[__[_WF`@(N00```#SI@^$3?W_ +XM_XNU@/[__[_[F`@(N08```#SI@^%J`0``,>%B/[__P(```#'A93^__\!```` +XMZ3#]___'@&@(```0,@@(BU4(BXJ4"```A7UW#BT7P@XBL!``` +XM`8M="(M%\(M3"(D0BY5\_O__BT7PB5`$.U,,#X1G`P``BTT(BT7PBU$(B4($ +XMBU7PBUT(B5,(B10DZ`?:__^%P'68BX6,_O__A<`/A#`#``#'1<`9````C47( +XMQT7$-P```(N=E/[__X7;=`G'`"H```"#P`2+C9C^__^%R70)QP`2````@\`$ +XMBY60_O__A=)T"<<`,P```(/`!,<`_____XU%P(E$)`2+1?")!"3H8S8``(7` +XM#X4@____A?8/A(H```"-G:3^__^)="0,QT0D"!29"`C'1"0$``$``(D<).@% +XM:___B=F)7=2+`8/!!(V0__[^_O?0(<*!XH"`@(!TZ??"@(```'4&P>H0@\$" +XM`-*-1=2#V0.)1>0IV8U%Y(U5P(E-W,=%P`````#'1<@`````B57HQT0D"``` +XM``")1"0$BT7PB00DZ,DK``"+A:#^__^%P`^%M`(``(M5\/:"(`(```$/A(D" +XM``"+@A@"``"-!$#!X`(#0A"+0#B)0C2+5?#V@F`!```!#X19`@``BX)8`0`` +XMC01`P>`"`T(0BT`XB4(XBX6@_O__A<`/A/;]__^+5?"+C83^__^#_W*+=1"- +XM'(X/A`(#``#V@FP$```!#X0G`@``BX)D!```C01`P>`"`T(0BT`X@\`!T>B) +XM@H0```"+10B+@`P!``"%P`^$^P(``(N%G/[__X7`=!V+E9S^__^)5"0$BT7P +XMB00DZ)'.`0"%P`^%KOW__XLSA?9T;(M5\(M"((7`=#V+0`B#ZP2)!"3HOVS_ +XM_X/``8D$).AD:___A<")PHD##X3.`P``BT7PBT`@BT`(B10DB40D!.CC;/__ +XMBU7PB5HHB5HDBT7P@8BL!````"```(/_3\__^-1>R)%"2-7:2)1"0(QT0D!`,```#H^@@``(M5[,<$)`$```") +XM5"0(B40D!.B78?__ZQ2#^`QT2XM%\(D$)(M5"/^29`@``,=$)`P`````QT0D +XM"`````")7"0$BT7PB00DZ.[5__^%P`^%2_K__XM%K(/X!'0-@^@!=;V+1;2# +XM^`AUL(M5\.D-_?__BT(DA564XM`'(G3BU`XA=)T'P^V2A`Q]HG0 +XM.L9D`^V2!`YV7,.B<*+`H7`=?!;B=!>7<.)UCG9=`*)\%N)PEZ)T%W# +XMC78`C;PG`````%6)Y593@^P@BT4,BW40@_@!=%US"^CZ8?__C;8`````@_@" +XM=`LQTH/$((G06UY=PXM5",=$)`0"````B10DZ&W=__^%P'10BU4(BT(WKO(VT)@````"+50B+0AR+6#B%VW2H +XMC78`BT,(.?!R"'0\@^@!B4,(BQN%VW7KZXZ-1?2)1"0$BT4(B00DZ*?=__^Z +XM`0```(7`#X5Q____@WWT`76+C70F`.E@____@$L1`8M%"(E<)`2)!"3HB.[_ +XM_^NUC;8`````58GE5U93@^P,BW4,BWT(@_Y@#X2(````B?*)^.BO_O__A<") +XMPW0/#[9($`^VP3GP#X1Z````QP0D%````.BR9?__A<")P@^$S0```(7;#X2? +XM````BP.%P(D"=`6+`XE0!(D3B5H$BTT0B=.+`8E""(M!!(E"#(GPB$(0BTT4 +XM,<"%R74/B$,1,=*#Q`R)T%M>7UW#B=.X`@```.OHC70F`&:^)P#I;____XVT +XM)@````"+112%P'4I#[9#$3'2@^`#@_@"=,2+51"+`HE#"(M"!(A+$(E###'` +XMZZJ-M@````"+51"+`HE#"(M"!(A+$(E##.NBBT\6#["B)7?2+70R)=?B)??R#^V!T;8M%"(G:Z&_] +XM__^%P(G&=`X/MD`0#[;X.=^(1?-T4X#[_P^$XP```(M5"`^VPXT$0(V$`%`! +XM```#0A"#P`B)1"0,QT0D"(":"`B+10B+512)!"2)5"0$Z,X-``"X`0```(M= +XM](MU^(M]_(GL7<.S)^N/]D81`70R@'WS_P^$G0```(M5"(T$?XV$`%`!```# +XM0A"#P`B)1"0,QT0D")B:"`CKIXVT)@````"+1@B#^`%U!XM>#(7;=$"+50B) +XM1"0$B10DZ++:__^%P'4J@'WS_W1ABU4(C01_C80`4`$```-"$(/`"(E$)`S' +XM1"0(O)H(".E4____BT8(BU40B0*+1@R)0@0QP.E6____BT4(B5PD!(D$).@` +XMR?__Z1____^+10B)?"0$B00DZ.S(___I8O___XM%"(E\)`2)!"3HV,C__^NA +XMC;8`````58GE4X/L!(M=#(M3.(72=""+"H7)=`:+0@2)002+0@2)"(D4).C* +XM8___BU,XA=)UX(/$!#'`6UW#D)"0D)"0D%6)Y8M%"(M`:(7`=`F)10B+2`1= +XM_^%=PY"-M"8`````58GE5U93@^PLBW40QP8`````BU4,#[8"A,!T00^^P(7` +XM>$N+'?P@"0@YV'U!BPT((0D(]D2!-@1U&^LRC70F``^^P(7`>"`Y4'0/A`X!``"+1>`Q]HD$).AZ8O__BU4(@47<``$``(72#X5;____BU7< +XMB10DZ+UA__^%P'5*QT7@3XT(".D<____BT7#I +XM-____XM=X(G7.?,/@T?___\\_W0]BU4(#[;`C01`C80`4`$```-"$(/`"#G> +XM#[80#Y?!A-)U0`^V1P&#QP&$P`^$%?___X3)#X0-____//]UPXM%",=$)`3_ +XM____B00DZ(+&__\YW@^7P0^V$(32=,:-M@````"$R72\B!,/ME`!@\,!.=X/ +XME\&#P`&$TG7GZZ6!H%0(``#__O__,?;I[O[__XE$)`R-0WB+50B)1"0(BT-T +XMB10DB40D!.C7?@``A<`/A.K^__^)0W3I5?[__XM5X#'VB10DZ"YA___IK_[_ +XM_\8#`.GP_?__C;8`````C;PG`````%6)Y8/L.(E=^(M=#(EU_(MU$`^^`X/X +XM?W<*]@2%W10)"`1U'(7V=`J)'"3HE&'__XD&B=B+=?R+7?B)[%W#B?8/OD,! +XM@_A_=]OV!(7=%`D(!'31#[Y#`H/X?W?(]@2%W10)"`1TOH![`WQUN(U%](E% +XMY,=%Z`0```")'"3H\UC__XE%](M%"(7`=%6+50B+0A"%P'1+BU!HA=)T1(U% +XM[(E$)`B-1>3'1"0,`````(E$)`2)%"3_4@R%P'4DBU7PA=)T'87V=`6-0O^) +XM!HM%[,9$`O\`BUWLZ5;___^-="8`@\,$Z3S___^0C;0F`````%6)Y8/L"(M% +XM#(M-"(M5$(/X!78,Z*M:__^-M"8`````_R2%')T("(E5$,=%#,2<"`B)30C) +XMZ=;^__^)51#'10SJF@@(B4T(R>G#_O__B540QT4,9)P("(E-",GIL/[__XE5 +XM$,=%#(2<"`B)30C)Z9W^__^)51#'10S]F@@(B4T(R>F*_O__B540QT4,&YL( +XM"(E-",GI=_[__XVT)@````!5B>575E.#["R+10B+<""+1@B)!"3H&F#__XM= +XM"(7;B47H#X3M````BU4(BUH0A=L/A-\```#V@U4(```!#X72````C02%@``` +XM`#M#>`^'9`4``(M+=(E-X(M#>(E%[(&+5`@````!``"+10B+<""+5@B+?>`/ +XMM@*$P`^$Y@```(G6ZU>+50@/ML"-!$`!P`-"$`^VF%T!``")7>@/M@8\_W1= +XMBU4(#[;`C01`C80`4`$```-"$(/`"(D\)(E<)`B)1"0$Z$M>__\/MD8!@\8! +XM`WWHA,`/A(L````\_W6EQT0D!/____^+30B)#"3H;L7__XG#B5WH#[8&//]U +XMI8GVQT0D!/____^+30B)#"3H3`"`T$0BT`XA<`/E<"$P`^%"0(``,8".HUR +XM`L9"`2#V11`!#X0K`0``C47PB40D!(M%"(D$).BMT___A<`/A0D!``"+1?"% +XMP`^%C0(``(U5Z(E4)`C'1"0$CYL("(M-"(D,).B0^___BU7HB30DB50D"(E$ +XM)`3H(5S__XGP`T7HZ0B)%"2)3"0(QT0D!%F;"`CH7/O__XG"Z1O_ +XM__^-5>B)5"0(QT0D!$B;"`B+30B)#"3H._O__XM5Z(D<)(E4)`B)1"0$Z,Q; +XM__^)V`-%Z,8`+(U8`L9``2"+50B+0ASV0%@$#X2S_O__ZY2+=>"+30B)#"3H +XM*34!`(M%"(M0$(M%Z(ET)`C'1"0$!````(E$)`R+30B)#"3_DI0(``"+10B% +XMP'06BU4(BT(0AB)1"0(QT0D!+J;"`B+50B)%"3HBOK__XM-#(DT)(E,)`B)1"0$Z)M<__^) +XM-"3H,US__XT$!HU(`<8`"HG(*T7@]D40`HE%Z`^$3?___XM5"(MR.#GP#X8_ +XM____BU7@C5[].?IR+#G7=#>-C&0@$@C5H"B0PDB40D",=$)`1UFP@(Z'CY__^+5>B)'"2)5"0(B40D!.@) +XM6O__B=H#5>CI2?W__X/@[V:)01B-3>B)3"0(QT0D!#N;"`B+10B)!"3H.OG_ +XM_XM5Z(D<)(E4)`B)1"0$Z,M9__^)V@-5Z.G[_/__C47HB40D",=$)`2>FP@( +XMBU4(B10DZ`/Y__\QTHE$)`2+3?!K70QDB4PD#(G8]_&)1"00BTT,B30DB4PD +XM".C_6O__B30DZ)=:__^-!`;I7_[__X&@5`@``/_^__^#Q"Q;7E]=PXE$)`R- +XM0WB)1"0(BT-TB40D!(M5"(D4).@\=P``A<`/A.C]__^)0W3I;_K__XVV```` +XM`(V_`````%6)Y5=64X/L/(MU"/:&K@0```0/A;"`C'1"0$&0```(E$)`SH-%;__XU5[(E%U`'#B47L,<")5"0(@WR^7`&) +XM-"0/E<"+!(50G0@(B40D!.AD]___BU7LB1PDB50D"(E$)`3H]5?__XM%[(U5 +XM[`'#B47@Q@,@BP2]6)T("(/#`8E4)`B)-"2)1"0$Z"GW__^+5>R)'"2)5"0( +XMB40D!.BZ5___BT7LBU7@`<.-1!`!`T78`T74B478,<#'1+Y<`````(/'`8/_ +XM!P^%'?___\8#"HDT).@0,0$`BT78BU80@\`!B40D#(M%W,=$)`0$````B30D +XMB40D"/^2E`@``(7V=`^+1A"%P'0(BU7<.5!T=&B+1=R)!"3HL5?__X/$/%M> +XM7UW#BX8@`P``C01`P>`"`T80BT@XZ3'^__\PP,=$AEP`````@\`!@_@'=?"# +XMQ#Q;7E]=PX%[>+P"``!V)XM#=(E%W(M#>(E%\(&+5`@````!``#I8?[__X&@ +XM5`@``/_^___KEXU#>,=$)`R]`@``B40D"(M#=(DT)(E$)`3HMG0``(7`#X1Q +XM____B4-TZZZ)]HV\)P````!5B>575E.#[#R+?0B%_P^$9`0``(M%"(-]#`:+ +XM0!")1=AV!>B,4?__BU4,_R25-)T(",=%#`,```"A*"$)"(/``:,H(0D(@^@! +XM=$:#Q#Q;7E]=PXM%"/:`,`0```$/A#@$``"+@"@$``"+5=B-!$"+3((XA+1>R- +XM'`8[7?!W'(!]UP"--`$`0`` +XMBU-TB57@BT-XB47P@8M4"`````$``(-]#`4/A`L!``"#?0P##X7R_O__BWW@ +XM,?;&1=<`BT4(A<`/A.?^__^+1=B%P`^$W/[__XM%V(N0!`$``(72#X3+_O__ +XM#[8"A,`/A$P!``")T^M5C78`BU4(#[;`C01`C80`4`$```-"$(/`"(E$)`S' +XM1"0(GZT("(M%\(D\)"GPB40D!.B!4O__`<8[=?")1>P/A^_^__\!QP^V0P&# +XMPP&$P`^$\P```#S_=:K'1"0$_____XM%"(D$).B7N?__ZZN0C70F`(M%W,=% +XM\`````#'1>``````A<`/A"'___^+1=R-5?")5"0(QT0D!`````")1"0,BT4( +XMB00DZ`9R``"%P`^$A@$``(-]#`6)1>`/A?7^__^-1>R)1"0(QT0D!,R;"`B+ +XM10B)!"3H-_/__XM5[#E5\`^"2_[__XE4)`B)1"0$BU7@B10DZ+Q3__^+=>R+ +XM?>#&1=(E4)`R)1"0(BT-TB40D +XM!(M%"(D$).A[<0``A<`/A/L```")0W3I3_[__XM5V(N""`$``,=$)`C8FP@( +XMB40D#(M%\(D\)"GPB40D!.A)4?__`<8[=?")1>P/A[?]__\!Q^DY_?__Z(]0 +XM__^+`(D$).CE3?__QT0D")VM"`B)1"0,BT7PB30D*=B)1"0$Z`A1__\!PSM= +XM\(E%[`^'=OW__P'&@\,!.UWPQT4,`P````^'8?W__\8&"HM]"(7_=`N+10B) +XM!"3H7"P!`(MUV(7V#X3Y````B5PD#(M5X(E4)`B+10R)1"0$BU4(B10DBT78 +XM_Y"4"```BTT(A`Y4'0/A.````"+1>")!"3H[%+_ +XM_\<%*"$)"`````"#Q#Q;7E]=PXM%"/:`K`0```(/A.C[___V@#`$```!=6Z+ +XM10B+F"@$``"%VP^4P(3`#X3)^___BU78@XI4"````NG3^___@WT,`G0P@WT, +XM!L=%V``````/A:K[___'10P$````Z9[[__^+10B+D"@$``"%T@^4P.G*^___ +XMQT4,`P```,=%V`````#I>/O__XN`*`0``(M5V(T$0(MT@CB%]@^4P.N)BU7@ +XMH1`A"0B)7"0(QT0D!/*8"`B)5"0,B00DZ&Q*___I`____X&@5`@``/_^___I +XM'/___XUT)@!5B>6#[#B)=?B+=1")??R+?0B)7?2%]G1IZ-9.__^+&(U%\(ET +XM)`2)1"0(B3PDZ#WN__^)QNBZ3O__B1B+112)="0,B3PDB40D"(M%#(E$)`3H +XMFOK__XM%\(7`=!B%_W0,BT<0A"-1>C'1>0$````QT7P`0```(E$)`B- +XM1>#'1"0,`````(E$)`2)'"3_4PR%P'4*@WWL$@^$`P$``(D<)/]3!*'L$`D( +XMA<`/A+L```#'!>P0"0@`````N`$```"!Q#P$``!;7E]=PZ'L$`D(A7UW#QP0DWYL(".@H2?__ABX\)L("+D2````_(G'\Z8/A>7^ +XM__^+10C'!>P0"0@`````BU`0BT)HA575C'V4X/L#(M]"(G[ZQ*#QA"#PPR!_O`$```/A+P```"#OFBC +XM"`@#=>7VAFRC"`@!==P/MI,``0``@^(!#X2B````BX/X````C01`P>`"`T<0 +XMBT`XA<`/E<"$P'0LA-(/A*0```"+@_@```"-!$#!X`(#1Q"+0#B)!"3HX4[_ +XM_P^VDP`!``"#X@&$TG1GBX/X````C01`P>`"`T<0BT@\A7UW#BX/X````A<`/E<#I9?___XN#_````(7`#Y7`ZZ.+@_P` +XM``#KN8N#^````.EC____D(VT)@````!5B>6#[!B+10S'1"0,=)T(",=$)`0# +XM````B40D"(M%"(D$).@8_/__R<.-M@````!5B>53@^P4BTT,BUT(C01)C02# +XM]H```0```70TBX#X````C01`P>`"`T,0BU`XA=)T!S'`@#H`=0R+51"X`0`` +XM`(72=!.#Q!1;7<.0C70F`(N0^````.O6P>$$BX%@HP@(B1PDQT0D#+"="`C' +XM1"0$`P```(E$)`CHD_O__X/$%+@!````6UW#D(VT)@````!5B>6#[%B)7?2+ +XM70B-1>R)=?B)??S'1"000%<%"(E=[,=$)`P(````QT0D""8```#'1"0$8*@( +XM"(D$).AD2___AQ=PXU%W(E=W,=$ +XM)!`@5P4(QT0D#!````#'1"0(3P```,=$)`1@HP@(B00DZ!I+__^%P'7!B1PD +XMZ)Y-__^+-6"C"`B%]HE%R'19#[8#QT708*,(",=%Q`````"(1<_K%(VT)@`` +XM``"#1=`0BT70BS"%]G0G#[9%SS@&?.M_'8M%R(G?_#G`B<'SIG7;BTW$A`"`T80BU`XBP.)5"0,QT0D!':?"`B)-"2)1"0(Z/XD +XM`0")PNGZ_O__C;0F`````(N`^````(T$0,'@`@-&$(M`.(7`#Y3`ZY:-M"8` +XM````BX#X````C01`P>`"`T80BT`XZ3+___^+@/@```"-!$#!X`(#1A"+0#B% +XMP`^5P.G/_O__C01)BY2&^````.EV____C;0F`````(V\)P````!5B>575E.! +XM[,P"``"+10B+2#C'A53]__\*````C70F`#'2B#'A43]__\`````QX50_?__`````,>%7/W__P````"#Z@*)E3S]__^) +XMC3C]__^+E5S]__\/MH)LHP@(J`0/A1`!``")U\'_!(-]#`)T%8-]#`,/A&(" +XM``"#?0P!=%'H7$3__Z@!=4B+C5S]__^+@6BC"`B#^`(/A\\#``"+50B-!'^- +XM!(+V@``!```!#X2=!```BX#X````C01`P>`"`T(0BU`XBT`\.<(/A*0```"+ +XM50B-!'^--(*-AO`````/ME@0@^/]B%@0BXU<_?__BX%@HP@(B00DZ/-)__^+ +XME5S]__^)A4S]__^+@FBC"`B#^`(/A'D"```/@]8!``"#XP$/A%H"``"+AO@` +XM``"+30B-!$#!X`(#01"+0#B%P`^4P(3`=`>#A4S]__\"BX4\_?__.85,_?__ +XM#X\(`@``BY50_?__B;R5:/W__X/"`8F54/W__XN57/W__XN"<*,("(/"$(F5 +XM7/W__X7`#X6^_O__BY50_?__A=(/CNX```"+C5#]__\YC53]__\/C#L#``#' +XMA5C]__\!````QX5`_?__`````,>%8/W__P````"+A53]__^%P'Y[BX58_?__ +XM,?8QVXN50/W__XT\$.LXBX5(_?__@\8!BTT(QT0D#$^-"`C'1"0$?I\(""G0 +XMB40D"(D,).@D(@$``YU8_?__.[54_?__="Z+E4#]__^-!!.+E(5H_?__BT4( +XMP>($@<)@HP@(Z,7[__^)PHT$'SF%4/W__W^:@X5@_?__`8N%8/W__SF%6/W_ +XM_P^/'0,``(.]1/W__P`/A+(!``"+50C'1"0$)KH("(D4).@?(0$`BX5$_?__ +XM,=N-M:3^__^%P`^.B0$``(L4GH/#`8M%",'B!('"8*,(".A2^___.YU$_?__ +XM#X1F`0``BTT(QT0D!":Z"`B)#"3HTR`!`.O(BTT(C01_]H2!``$```(/A(7^ +XM___IW/W__X/X`P^%3_[__XG:@^(!#X1"`0``BTT(C01_BX2!^````(T$0,'@ +XM`@-!$(M8.(7;#Y7`A,!T(X32#X7O`0``BTT(C01_BX2!^````(D$).BI1___ +XM`85,_?__@X5,_?__`XN%//W__SF%3/W__P^.^/W__XN-1/W__XF\C:3^__^# +XMP0&)C43]___I\_W__XNV^````(7V#Y3`Z;#]__^#XP$/A,<```"+AO@```"+ +XM50B-!$#!X`(#0A"+0#B-3>")#"2)1"0,QT0D"+.@"`C'1"0$%````.@"1/__ +XMC4W@BP&#P02-D/_^_O[WT"'"@>*`@("`=.GWPH"````/A"(!````TH/9`RN- +XM./W__P&-3/W__^E"_?__@\`&,=*#X/J)A4C]__^)R/>U2/W__XF%5/W__^GA +XM^___D(M%",=$)`0FN@@(B00DZ&T?`0"!Q,P"``!;7E]=PXM-"(T$?XN,@?@` +XM``"%R0^5P.G%_O__BX;X````Z4/___^#^`,/A5O\__^+30B-!'^-!($/MH@` +XM`0``@^$!#X2Q````BX#X````BU4(C01`P>`"`T(0BU`XBT`\.<(/A,;\__^$ +XMR0^%JP```(M5"(T$?XT$@HN0_````(72#X0#_/__BX#X````B50D!(D$).BQ +XM0O__A<`/A(W\___IY/O__XN54/W__XG0P?H?][U4_?__@_H!@]C_A<")A5C] +XM__\/CZK\___I=_W__\'J$(/!`NG3_O__BU4(C01_BX2"^````(T$0,'@`@-" +XM$(M`..D`_O__BY#X````BX#\````Z5;___^+D/@```"+@/P```#I9_O__XM- +XM"(T$?XN$@?@```"-!$#!X`(#01"+4#R%T@^$3OO__XM`..E)____BU4(QT0D +XM!":Z"`B)%"3H#QX!`(N-8/W__XF-0/W__^DA_/__C;0F`````(V\)P````!5 +XMB>6#[!B+10R)??R+?0B)7?2)=?B+=1"-!$#!X`*-%#CV@@`!```!C9P'^``` +XM`'06BX+X````C01`C02%,`````-'$(U8"/?&"````'5Q]\8!````=#[WQ@P` +XM```/A)T```"#Y@)U&(M#!(7`C78`=`Z)!"3H"D3__XVV`````(M5%#'`B5,$ +XMBUWTBW7XBWW\B>Q=P_?&#````'18@^8"=0Z+`X7`=`B)!"3HU$/__XM5%#'` +XMB1/KSXVT)@````"+112)!"3H*3W__X7`B444#X5Y____QT0D"`````#'1"0$ +XM!0```(D\).B"[/__N`$```#KDXM%&(D#,<#KBHGVBT48B4,$,<#I>____XUV +XM`%6)Y57VAVRC"`@!==R+1?"%P`^%'`$``/:#``$```$/A`$!``"+@_@```"+50R- +XM!$#!X`(#0A"+0#B%P`^$\@```(M5#,=$)!``````B40D#,=$)`@*````B70D +XM!(D4).@T_O__A<`/A2H!```/MI,``0``@^(!#X0*`0``BX/X````BTT,C01` +XMP>`"`T$0BT`\A<`/E<"$P`^$2O___X32#X0<`0``BX/X````BU4,C01`P>`" +XM`T(0BT`\BTT,QT0D$`````")1"0,QT0D"`L```")="0$B0PDZ+K]__^%P`^$ +XM`O___XM%"(/&`8/'$,=$)`@`````@\,,QT0D!`4```")!"3H_NK__X/^3\=% +XM\`$````/A>#^__^+1?"#Q!Q;7E]=PXN#^````(7`#X4.____BTT,QT0D$``` +XM``#'1"0,`````,=$)`@&````B70D!(D,).@^_?__BT4,QT0D$`````#'1"0, +XM`````,=$)`@'````B70D!(D$).@7_?__Z6+^__^+@_P```"%P`^5P.D`____ +XMBTT,QT0D$`````#'1"0,`````,=$)`@'````B70D!(D,).C;_/__Z23___^+ +XM@_P```#I[O[__XUT)@"-O"<`````58GE5U93@^Q\Z8/A&4YV9`/A%H(``"`^CW'1<0!````QT7(`````'0.QT7$```` +XM`,=%R`$```"%R<=%[`````#'1=``````=`G&`0"#P0&)3=")'"3H]O+__X7` +XMB<P/MD<, +XMA=(/E<&H(`^%`0(``*@0#X57`@``BU7$A=(/A3H%``"+5R%P`^%#`,``(M%R(7`#X1V`0``BT6X +XMA_O__]D<,`G5@BTT(C01;C02!#[:0``$``(/B`0^$ +XM&00``(N`^````(T$0,'@`@-!$(MP.(7V#Y7`A,!T+(32#X6)!```BTT(C01; +XMBX2!^````(M5T(D$)(E4)`3HPSO__X7`#X33_O__BT<$A/[__X3)#X3W_?__QT0D#-"= +XM"`B+10B)="0(QT0D!`,```")!"3HY>O__\=%S`$```#I1?[__X![`6\/A8C^ +XM__^-P!````B30DZ#WP__^%P(G'#X5'_?__Z6?^__^%T@^%H?W__\=$ +XM)`P`G@@(Z9,!``"+1<2%P`^$?_[__XM5T`^^`H/X?P^'GP```/8$A=T4"0@$ +XM#X21````C47@C4WPQT0D#`H```")1"0(B50D!(D,).CS6```B46\@^@!#X25 +XM`P``BU4(C47HB70D!(E$)`B)%"3HH=G__XM5"(U-Y(E,)`B)%"2)PXM%T(E$ +XM)`3HAMG__X-]O`&)Q@^#-P4``(M-"(E$)!")7"0,QT0D")"?"`C'1"0$!0`` +XM`(D,).C7Y?__ZUN0C70F`(M5"(U%Z(ET)`2)1"0(B10DZ#K9__^+50B-3>2) +XM3"0(B10DB<.+1=")1"0$Z!_9__^+30B)7"0,QT0D"*B>"`C'1"0$`P```(D, +XM)(G&B40D$.AZY?__BT7HA2%VP^$/O[__XM-"(7)=!.+30B+01"%P'0).W!T#X1#!``` +XMB30DZ#@\___'1`/M@"$P'0G#[[0A=(/B+W\__\[%?P@ +XM"0@/C;'\__^A""$)"/9$D#8"#X2A_/__#[9'#*A`=`N+5?"%T@^$VP$``*@" +XM=3&+50B-!%N-!(+V@``!```!#X3.`0``BX#X````C01`P>`"`T(0BT`X.T7P +XM#X2E^?__BT<$ASIM/S__XNP^````(7V#Y3`Z6O\__^!H%0( +XM``#__O__Z9C[__^!H%0(``#__O__QT7,`0```.E/^/__BY#X````A=(/E<#I +XM-OS__X-]O`)T$H-]O`,/A3G[__^-=@#ID?C__XE$)!"+10B)7"0,QT0D"("> +XM"`C'1"0$`P```(D$).B(X/__Z0G[___'1"0,U)X(".F*^?__BX#X````Z3G^ +XM__^+10C'1"00`0```,=$)`P`````QT0D"`````")7"0$B00DZ-3R___IN_?_ +XM_^L-D)"0D)"0D)"0D)"0D%6)Y8'L6`0``(EU^(MU"(U%V(E=](V=R/O__XE% +XMZ(U%R(E]_(G?B5W8QT7(`````,=%T`````#'1>``````B47LQT0D$`,```#' +XM1"0,`````,=$)`@`````QT0D!#\```")-"3H5_+__X7`=3.`CO0#```!QT0D +XM$`$```#'1"0,`````,=$)`@`````QT0D!!@```")-"3H)/+__X7`=$#!XP2+ +XM@V"C"`C'1"0(2)\(",=$)`0#````B30DB40D#.AKW___N@$```"+7?2)T(MU +XM^(M]_(GL7<.-M"8`````@(X@`@```<=$)!``````QT0D#`````#'1"0(```` +XM`,=$)`0(````B30DZ+'Q__^%P'6-@(Y@`0```<=$)!`"````QT0D#`````#' +XM1"0(`````,=$)`0S````B30DZ'[Q__^%P`^%5O___X".9`,```''!"2GGP@( +XMZ-*`@("`=.GWPH"```!U!L'J$(/!`@#2NPH```"#V0,I +XM^8U5Z(E-X,=$)`@`````B50D!(DT).BL\___A<`/A43^__^!_]*?"`B)^W0E +XMQX7(^___97-C8<>%S/O__W!E=&G'A=#[__]M93TVQH74^___`(G9BP&#P02- +XMD/_^_O[WT"'"@>*`@("`=.GWPH"```!U!L'J$(/!`@#2@]D#*?F-1>B)3>#' +XM1"0(`````(E$)`2)-"3H+?/__X7`=!2[#````.F__?__N"'5"`CI>O[__X'_ +XMWY\("'0=QX7(^___:V5Y=,>%S/O__VEM93UFQX70^___-@")^8L!@\$$C9#_ +XM_O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TH/9`RG9C57HB4W@QT0D +XM"`````")5"0$B30DZ*CR__^%P'04NQ8```#I.OW__[B_GP@(Z7O^__^!^^F? +XM"`AT'L>%R/O__VUA=&/'A*`@("`=.GWPH"```!U!L'J$(/!`@#2@]D#*=F-1>B)3>#'1"0( +XM`````(E$)`2)-"3H(O+__X7`=`J['0```.FT_/__QT0D#/6?"`C'1"0(#*`( +XM",=$)`0`!```B1PDZ,@P__^)V8L!@\$$C9#__O[^]]`APH'B@("`@'3I]\*` +XM@```=0;!ZA"#P0(`TH/9`RG9C57HB4W@QT0D"`````")5"0$B30DZ*SQ__^% +XMP'0*NR````#I/OS__X'[%J`("(G?=!O'A%S/O__V=R87#'A=#[__]H% +XMV/O__U!14%#'A=S[__\@3$EPQX7@^___<&QP:<>%Y/O__W!B<`")V8L!@\$$ +XMC9#__O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TKLF````@]D#*?F- +XM5>B)3>#'1"0(`````(E4)`2)-"3HA/#__X7`#X4<^___QT0D#$^-"`C'1"0( +XML)\(",=$)`0`!```B3PDZ#`O__^)^8L!@\$$C9#__O[^]]`APH'B@("`@'3I +XM]\*`@```=0;!ZA"#P0(`TKLG````@]D#*?F-1>B)3>#'1"0(`````(E$)`2) +XM-"3H#_#__X7`#X6G^O__QT0D#!^@"`C'1"0(,Z`(",=$)`0`!```B3PDZ+LN +XM__^)^8L!@\$$C9#__O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TKLK +XM````@]D#*?F-5>B)3>#'1"0(`````(E4)`2)-"3HFN___X7`#X4R^O__@?\] +XMH`@(B?MT.\>%R/O__W-E8W3'A%U/O__TA( +XM($C'A=C[__]5;FAS9L>%W/O__V@`B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!T +XMZ??"@(```'4&P>H0@\$"`-*#V0,I^8U%Z(E-X,=$)`@`````B40D!(DT).@% +XM[___A%S/O__VQM973'A=#[__]A/7Y[QX74^___6RH_),>% +XMV/O__V`G(ES&A=S[__\`C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2@]D#*=F-1>B)3>#'1"0(`````(E$)`2)-"3HS.W_ +XM_X7`=`J[-0```.E>^/__@?M_H`@(="7'A% +XMT/O__W1H/3C&A=3[__\`B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!TZ??"@(`` +XM`'4&P>H0@\$"`-*[-@```(/9`RN-O/O__XU5Z,=$)`@`````B4W@B50D!(DT +XM).A`[?__A<`/A=CW__^!O;S[__^,H`@(="?'A%T/O__VQL/3%FQX74^___-@"-CH0@\$"`-*[.0```(/9`RN-O/O__XU%Z,=$)`@````` +XMB4W@B40D!(DT).BP[/__A<`/A4CW__^!O;S[__^:H`@(=!W'A")5"0$B30DZ"KL__^%P`^%PO;__XV%R/O__\=$)`Q@P0@(QT0D"*2@"`C' +XM1"0$``0``(D$).C0*O__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2NSX```"#V0,KC;S[__^-5>C'1"0(`````(E-X(E4 +XM)`2)-"3HI^O__X7`#X4_]O__]H8@`@```0^$QP$``(N&&`(``(T$0,'@`@-& +XM$(M`.(/H`='HA<")1?!U!\=%\`$```"+1?#'1"0(K*`(",=$)`0`!```B40D +XM#(V%R/O__XD$).@<*O__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2NS````"#V0,KC;S[__^-5>C'1"0(`````(E-X(E4 +XM)`2)-"3H\^K__X7`#X6+]?__BT80C57PB50D!(DT)/^08`@``+H!````A<`/ +XMA97U__^+1?`]6`(```^'U````,=%\`@```"+1?#'1"0(MZ`(",=$)`0`!``` +XMB40D#(V%R/O__XD$).AE*?__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("` +XM=.GWPH"```!U!L'J$(/!`@#2NTD```"#V0,KC;S[__^-5>C'1"0(`````(E- +XMX(E4)`2)-"3H/.K__X7`#X74]/__H6"C"`B%P`^$L`$``(GS,?^)^,'@!(F% +XMP/O__XN`:*,("(/X`0^$9`$```^"L0```(/X`@^$`@$``(/X`XVT)@````!T +XM,^C-)?__/;`$``"-="8`#X>\````QT7P$````(UV`.D5____BX88`@``@^@! +XMT>CI0/[__P^VDP`!``"#X@$/A(````"+@_@```"-!$#!X`(#1A"+0#B%P`^5 +XMP(3`=#Z$TG19BX/X````C01`P>`"`T80BT`XQT0D$`````")1"0,QT0D"`L` +XM``")?"0$B30DZ!KF__^%P`^%\O/__XN%P/O__X/##(N`<*,("(7`#X3$```` +XM@\O___S'2Z:3R__^+&^ES\O__ +XMC78`58GE5U93@^PLBQ5@HP@(BWT,A=(/A)L"``#'1?``````Z8(```"+3>2- +XM!$F+30B-!('V@``!```!#X1>`@``BX#X````C01`P>`"`T$0BT`XA<`/E<"$ +XMP`^$%@(``(E4)`C'1"0$PJ`("(D\).CR(/__H:`4"0B%P`^%<0$```^_1PS! +XMZ`:#X`&$P`^%=`$``(M-\(N1<*,("(/!$(E-\(72#X0-`@``BT7P]H!LHP@( +XM"'7=BTWPP?@$B47DBX%HHP@(@_@"#X1D`0``#X)4____@_@#=9N+5>2+30B- +XM!%*-!('V@``!```!#X2=`0``BX#X````C01`P>`"`T$0BT`XA<`/E,"$P`^% +XM8____XE\)`S'1"0(!````,=$)`0!````QP0DXJ`(".AU)O__BU7PBX)@HP@( +XM#[8PB?&$R0^$L`$```^^V8E%[.MTC78`H0@A"0CV1)@V`G1QH:`4"0B%P`^% +XM=P$``(M'"(/H`87`B4<(#XC4`@``BP?&`%R#P`&)!Z&@%`D(A(&(/``8D'BTWL#[9Q`8/!`8E-[(GPA,`/A#2-!$F+30B-!('V@``!```!=&B+ +XM@/@```"-!$#!X`(#01"+0#B)1"0,B50D",=$)`34H`@(B3PDZ/4>___I_OW_ +XM_XE4)`C'1"0$RJ`("(D\).C<'O__Z>7]__^+@/@```"%P`^4P.EJ_O__BX#X +XM````A<`/E<#IJ?W__XN`^````.NB@\0L,CK;8GVH0@A"0CV1)@V`G1KBPV@%`D(A+%:`4"0B%TG5)BT<(@^@!A<")1PAX2HL' +XMB!B#P`&)!XM5Z`^V<@&#P@&)5>B)\83)=%T/OMF%VW@(.1W\(`D(?XF)\8#Y +XM7'2.BQ6@%`D(A=)TMXE\)`2)'"3H)\#P*D'6JB7PD!(D< +XM).@6)/__ZZ6)?"0$QP0D7````.A$'O__Z7#___^AH!0)"(7`=6>+1PB#Z`&% +XMP(E'"`^(G@```(L'Q@`*@\`!B0?I)/S__SM'&`^-(_W__XE\)`3'!"1<```` +XMZ+TC___I&/W__SM'&`^-%O___XE\)`3'!"1<````Z)\C___I"____XN`^``` +XM`.FT_O__B7PD!,<$)`H```#HOQW__^G(^___B7PD!,<$)#T```#HJAW__^E? +XM_O__.T<8#XU,_O__B7PD!,<$)#T```#H3"/__^E!_O__B7PD!,<$)`H```#H +XM-R/__XUV`.E]^___D)"0D)"0D)"0D)!5B>6+112+50B+`(7`=!&!HJP$``#_ +XM_]__,6+10B#B*P$```@,Q=PXN1&`(``(U"_^O+C012P>`"`T$0 +XMBT`X@^@!Z\>-M"8`````C;PG`````%6)Y5.#["2+70B-5?B+0Q")5"0$B1PD +XM_Y!@"```N@$```"%P'4+,-*!??C`$@``=P^#Q"2)T%M=PXVT)@````"+112) +XM1"0,BT40B40D"(M%#(D<)(E$)`3H$____X/$)%M=B<*)T,.)]HV\)P````!5 +XMB>53@^PDBUT(C57XBT,0B50D!(D<)/^08`@``+H!````A6#[!B+112+"(7)=2N+10C'1"00`````,=$ +XM)`P`````QT0D"`````#'1"0$0P```(D$).CFW/__R3'`PXGV58GE@^P8BT40 +XMB00DZ`,B__\QTJ@!=""+10C'1"0(F*D(",=$)`0#````B00DZ![*__^Z`0`` +XM`,F)T,.0C70F`%6)Y8/L&(M%$(D$).C#(?__,=*H`70@BT4(QT0D"-"I"`C' +XM1"0$`P```(D$).C>R?__N@$```#)B=##D(UT)@!5B>6#[!B+10C'1"0(#*H( +XM",=$)`0#````B00DZ*_)__\QP,G#C70F`(V\)P````!5B>6#["B)=?B+=12) +XM7?2+70B)??R+!H7`#X01`0``/?0!``!V,L=$)`ST`0``QT0D"&"J"`C'1"0$ +XM`P```(D<).A:R?__N`$```"+7?2+=?B+??R)[%W#B40D$,=$)`P`````QT0D +XM"`````#'1"0$&````(D<).BTV___BP:#^`$/A/D```"#Z`'1Z(F#A`````^V +XM@VP$``"#X`&)QP^%O````(N+9`0``(N#:`0``(G*.<$/A%L!``")^(3`=`R- +XM!%+!X`(#0Q"+4#B+!CG"#X8:`0``@^@!B40D$,=$)`P`````QT0D"`````#' +XM1"0$20```(D<).@SV___BP:#Z`&)1"00QT0D#`````#'1"0(`0```,=$)`1) +XM````B1PDZ`K;__\QP.D>____C78`QT0D#`$```#'1"0(-*H(",=$)`0#```` +XMB1PDZ%#(__^X`0```.GQ_O__C;8`````BY-D!```C012P>`"`T,0BT@XBT`\ +XMZ3C___^-M@`````/MH-L!```QX.$`````0```(/@`8G'=%^+DV0$``"-!%+! +XMX`(#0Q"+2#B+0#PYP70*B?B$P'50.Q9V-<=$)!`!````QT0D#`````#'1"0( +XM`````,=$)`1)````B1PDZ$W:___'1"00`0```.D6____,<#I5/[__XN+9`0` +XM`(N#:`0``(G*ZZ:-!%+!X`(#0Q"+4#CKHHL&Z;K^__^-="8`58GE@^P8BT44 +XMBP"#^!-V0#'2/?0!``!W!\F)T,.-=@#'1"0,]`$``,=$)`BXJ@@(QT0D!`,` +XM``"+10B)!"3H/53@^P$BUT( +XMB1PDZ*Z$__\QP(.+K`0``""#Q`1;76#[`B+ +XM11")1"0$BT4(B00DZ!C,__\QP,G#D)"0D%6)Y5=64X/L3(MU#(M]"(7V#X3I +XM`@``BU44BUX(@SH!#X1B`P``]D88`0^$G0```(M%'(7`=6*+312+`8/H`8M5 +XM&(/&"(E%\(/``3GSB0)U$.M-@T7P`8-'7`&+&SGS=#^+0Q")1"00BT,(B40D +XM#(M%\,=$)`0!````B3PDB40D".C*F/__A2)1"0,QT0D"`$```")5"0$B3PDZ`F1 +XM__^%P'6/A?\/A/,"``"+5Q"%THE5T`^$Y0(``/:"50@```$/A=@"``"+1>B+ +XM3=`#0Q"#P`$[07@/A[T#``"+3="+5="+272)3R!BE0(`````0`` +XMB4W4BT7HA`[`P^$\`(``(M5\(M#$(E$)!"+0PB)5"0( +XMQT0D!`$```")/"2)1"0,Z(66__^%P'3"NP$```"%_W03BT<0A#X1\ +XM`@``BT,0B40D$(M#"(E$)`R+1?#'1"0$`0```(D\)(E$)`CH8Y7__X7`=,7I +XME/S__XM%Z,=%[``````#0Q#'1<@`````QT74`````(/``0^$./W__XE$)`R- +XM1>R)1"0(QT0D!`````")/"3HNS8``(7`B47(B474#X4/_?__Z4+\__^!IE0( +XM``#__O__BU7`BT7$`T(0.T9X=V:+3G2)3R!CE0(`````0``B4W4 +XMZ:#]__\QP(-[$``/E<#I-_W__P^VA)`T!```Z9;^__^)1"0,C47LB40D"(M- +XMR(D\)(E,)`3H/38``(7`#X3/^___B47(B474Z5C]__^)1"0,C49XB40D"(M& +XM=(D\)(E$)`3H$#8``(7`#X2B^___B49TZ7#___^)1"0,B2)1"0$BT7(B00DZ,,6__^+5=B+3<@!5>0! +XMT8E-S.DS^___BTT8,=O'`0$```#'000`````Z33Z__^!H%0(``#__O__Z27Z +XM___'1"0$_P```(D\).C&>___Z>/\__^+5<2)5"0(BT7DB40D!(M-S(D,).A< +XM%O__BT7$`47,BU7PZ3/___^0D)"0D)"0D)"058GEBT4(5U93BT@0BU$(C7D( +XM.?IT"CG0=3N+$CG7=4"+41"-<1`Y\G1`BQHYWG1,BT($B4,$BT($.<9T.HD8 +XMBT$(B7H$B0(Y>0QT)HM!"(E0!(E1"%N)T%Y?7<.-="8`.=!U\3G0=/CKZS'2 +XMC70F`.OCB5$,Z]N)61#KPXM"!(E!%(L:Z["-=@"-O"<`````58GE5S'_5E.# +XM[`R+=0B+1@R#Z`&%P(E&#`^%'`$``(L6A=)T)(M>$(U#"#G"#X1&`0``BT8$ +XMB4($BTX$C4,(.<$/A$L!``")$8.FK`0``/._`0```(DT).B3P`$`B30DBN?C8;(````B00DZ.<3__^+AN`` +XM``"%P'6:ZZ"+1@2)0PR+7A"+3@2+%HU#"#G!#X6U_O__B5,(Z:_^__^-M@`` +XM``!5B>575E.#[`R+11"+=0B+?0S'``````#'1"0$L`0``,<$)`$```#H.!+_ +XM_X7`B<,/A%0"``"+11")&(M&!(/``87_B48$B4,(C4-XQT,,`0```(ES$,=# +XM+`(```")0WB)0WP/A.1H````@8NL!````(```(B#J````(N7P````#'` +XM@[^L``````^5P(72B8.L````="2+A\0```")5"0$B1PDB40D".C$+P``A<") +XM@\`````/A$8!``"+E]@```"+A\0```"%THF#Q````'0DBX?<````B50D!(D< +XM)(E$)`CHBB\``(7`B8/8````#X0,`0``BY?@````BX?<````A=*)@]P```!T +XM)(N'Y````(E4)`2)'"2)1"0(Z%`O``"%P(F#X`````^$T@```(N'Y````(F# +XMY````(N'[````(7`=$V--(4`````B30DZ&$2__^%P(F#Z````'1XBX?L```` +XMBY/H````B8/L````BX?P````B8/P````BX?H````B70D"(D4)(E$)`3H4Q+_ +XM_XE<)`2)/"3H0\___X7`=1^+AZP$``")7"0$B3PD@^`#"8.L!```Z(36``"% +XMP'1ZB1PDZ&C\__^X`0```(/$#%M>7UW#QT0D"`````#'1"0$!0```(D<).A3 +XMN___BY/H````A=(/A6+___^0C70F`,=$)`@`````QT0D!`4```")/"3H*+O_ +XM_^NFC;8`````QX.L`````````(E<)`2)/"3H"M8``(7`=8:)7"0$B3PDZ%J] +XM`0"%P`^%`/MDL!.,@/A`0!``"#[@$/A"`"```/OM`XP8E5V(M5X(G3=%*+5>") +XMT^LCC70F``^V"H/"`8@+@\,!@^X!#X35`0``#[8*#[[!.T78="B#_@%VW(#Y +XM7'77C4(!B47<#[9*`0^^P3M%V`^$2P$```^V"HM5W.N_B=Z#P@$K=>"+10R% +XMP'0%BT4,B1"+7>")]HM%$`^V51"+31")="0(@^`0@_@!&<"#XH"#X`2#P`*` +XM^@$9TH/A`??2"N!```0'59 +XMBT40QT0D$`````#'1"0,`````(/@$(/X`1G`@^`$@\`"B40D&(V'L````(E$ +XM)!2+A\0```")5"0$B3PDB40D".BT(`$`A7UW#C;0F`````(/$/#'`6UY?7<.#[@&# +XMP@+I*W7@Z5S^__^)^+("Z-3\__^X`0```.G3_O__BU7@Z4'^__^)]E6Z`@`` +XM`(GE5U93@^QLBT4@BW4(B40D"(M%'(E$)`2+11B)!"2+312)\.A1_?__A<`/ +XMA>````#V12`(#X3E````BU4,BP*)1>R+2@2#P0&)3<2+12"[9````#'_QT7` +XM`0```(/@$(E%K.M8D(UT)@"+AI0$``"-!$#!X`(#1A"+0#B%P`^4P(3`#X4N +XM`P``C47LB40D!(DT).BBA/__A<`/A<\"``"+1>R%P'1@@\`!OP$```")1>R# +XM;>P!QT7$`````(/K`8/[_P^$D0$``(7_=`Z+50R+`CM%[`^'OP(``(M5[(72 +XM=6B%_P^%L`(``/:&G`0```$/A7/___^+AI0$``"%P`^4P.EZ____]D4@$`^% +XMW@(``+L!````@\1LB=A;7E]=PXM5#(MZ!(7_#X6I`0``BQ*#^@$/A-`"``"- +XM0O^)1>SIFP$``(VV`````(U-Z(U%Y(E,)!")1"0,QT0D"`````")5"0$B30D +XMZ(Z!__^%P`^%^P$``(M%Z(V6L````(U-U,=%U`````#'1=@`````B47 +XM`0``BTW$QT6T`````(E-L(M%U(M5V(M-Z(E%R(/``8E5S(/2`#';@_H`B474 +XMB578#X[)````BT7LBTT0BU7(B0'V12`"#X7#`0``BT7H.<(/@K@!``"#^`&- +XM4/\9P/?0,=LAPHE1!.D:`0``BT80]H!4"```!`^%!0$``,=$)`P!````QT0D +XM"`````#'1"0$`````(DT).CP>/__A")1"00B50D#,=$)`@!````BT7DB40D!(M-O(D,).B2 +XM!___@_@!#X3O_O__A<`/A10!``"+1<2%P`^$MO[__X-]V``/C*S^__\/C\S^ +XM__^+3;`Y3=0/@IK^__^-M@````#IM?[__[L!````]D4@$(GV#X26_?__B30D +XMQT0D!`(```#H^OC__X/$;(G86UY?7575E.#[$R+12")1"0(BT4R)1"0,QT0D"`````")="0$BU4(B10DZ+E]__^%P`^$ +XM-0$``(M%T(7`#X7!````BTT(]H&R-??")?"00B50D#,=$)`@!````BTT,BP&)1"0$BT4(B00D +XMZ*)\__^%P'7#BU4,]D4@"(LR#X0=`0``BUH$A=L/A&K^__^#ZP'I8O[__XM5 +XM\(72=`2!P;````")3@`````B5W< +XMQT7@`````(E$)!"-1=R)1"0,QT0D"`$```"+1>R)#"2)1"0$Z.@#__^#^`%U +XM?8/&`3';Z:S^__^0C70F`(M%"(N`E`0``(7`#Y3`A,`/A(/^___V12`0#X05 +XM____BT4(N@$```#HH_7__^L-BT4(N@,```#HE/7__[L!````QT0D!`(```"+ +XM10B)!"3H3/7__X/$3(G86UY?7<.[`0```/9%(!!UV.G,_O__A<`/A+L```#V +XM12`0C;8`````#X3^````BU7(B40D!(E4)`B+30B)#"3HI!BT4,BU@$ +XM@\,!.UWP#X)&_?__@\8!,=N-5>R)?"00B50D#,=$)`@`````B70D!(M-"(D, +XM).@Y>___A<`/A!?]__^+10CV@)P$```!#X2N````B<*+@)0$``"-!$#!X`(# +XM0A"+2#B%R0^4P(3`#X3?_/__]D4@$`^$&_[__XM%"+H!````NP$```#HI/3_ +XM_^D)_O__BT70AP/A)\!``"+ +XM1>R+50PY4`AUY?9`)`%UWXMP&+L&````BW@4A?9^>##;ZS.-="8`BU4(#[;` +XMC01`C80`4`$```-"$(/`"(M5"(E$)`2)%"3H6]X```'#@^X!=!^#QP$/M@<\ +XM_W7*BT4(QT0D!/\```")!"3HIVG__^O+B=BZJZJJ*O?JB=C!^!\IPHT44@'2 +XM*=J-6@:%VWX@C;0F`````(M5",=$)`32U`@(B10DZ/W=```IPX7;?^>+1>R+ +XMR+$H72 +XMB57L#X5A_O__BT7P@\0<6UY?7<.+50@/ML"-!$"-A`!0`0```T(0@\`(BU4( +XMB40D!(D4).C9W```@^L!=*2#Q@$/M@8\_W7,BT4(QT0D!/\```")!"3H)VC_ +XM_^O-D(UT)@!5B>564X/L$(MU"(N>1`$``(7;=%"+0PR%P'0(B00DZ"`#__^+ +XM0Q2%P'0(B00DZ!$#__^+0QR%P'0(B00DZ`(#__^+$X72=`:+0P2)0@2+0P2) +XM$(D<).CI`O__BYY$`0``A=MUL(/$$%M>7<.-="8`58GE4X/L!(M="(L3A=)T +XM!HM#!(E"!(M#!(D0BT,,A(```"+ +XM31"+4Q0/MD$,.`(/A]````!R"(M]'#E["'1?BP.)7?"%P`^$T````(G#BT40 +XMA?````+31PY2PAUS_9#)`%UR8M+&(M%&#G( +XM=@*)R(M]%#G`B<'\\Z8/DL`/E\(HP@^^PNLHD(UT)@#V0R0!=9N+2QB+11@Y +XMR'=JB40D"(M%$(D4)(E$)`3HW?O__X/X`'\_#XQS____BU48.U,8D%_O__D(UT +XM)@#)N`$```##B?:-O"<`````58GE@^PXBT4DB77XBU44BW48B5WTB40D%(U% +XM\(E$)`2+10B)??R+?2#'1"08`````(ET)!")5"0,QT0D"`````")!"3H!_[_ +XM_X7`B<-T9?9%*`)U6XM%'(7`=$J%_XGV=$2+51R+10B)?"0(B50D!(D$).AH +XM'```A<")Q@^$I0$``(M#'(7`=`B)!"3H,P#__XE[(#'`B7,Q=PS'_,?;KUHUT)@`QP.OEQT0D!"@```#'!"0!````Z-S]_O^%P(G##X0Z +XM`0``BT4,A____QT,,`````(M5$(E3$(M%%(M5"(ET)`B)1"0$ +XMB10DZ((;``"%P(E#%`^$!`$``(ES&(M%'(7`#X2*````BT4____Z$+[_O^+,(M##(7`#X2(_O__B00DZ#W^_O_I>_[__XUT)@#H +XM'_O^_XLPBT,4B00DZ"+^_O_KT(VV`````(V_`````%6)Y5=64X/L'(M5"(MU +XM#(M"$(N`1`$``(7`B47D=17I3@(``(M%Y(L`A<")1>0/A#X"``"+1>2+510Y +XM4`AUY?9`)`ATWXM%$(7`=`^+11")="0$B00DZ)GW_O^+5>2+1>2+4A2)5>"+ +XM0!B%P(E%Z'5DZ<8```"#^WQT<#L=_"`)"'T,H0@A"0CV1)@V`G5%R+!HGZB!"#P`&)!H-MZ`%T9XM5X`^V.H/"`8E5X(GX#[;8@_L6=8NAH!0) +XM"(7`#X6(`0``BT8(@^@!A<")1@@/B#<"``"+!L8`%H/``8D&BT8(@^@!A<") +XM1@AYI#M&&'P%@/L*=9J)="0$B1PDZ.[[_O^#;>@!=9FAH!0)"(7`#X5(`@`` +XMBT8(@^@!A<")1@@/B$P"``"+!L8`((/``8D&BT7DBT`P/A,0```"+ +XM5>2+4B"%THE5\'50Z;(```"#^WQT7(#"`9`/A'L!``"+50B+0A"`O`-3!P`` +XM#'1"BPV@%`D(A+1>P/MCB#P`&)1>R)^@^VVH/[%G6?H:`4"0B%P`^%ZP```(M&"(/H`87` +XMB48(#XA8`0``BP;&`!:#P`&)!HM&"(/H`87`B48(>:0[1AA\!8#["G6:B70D +XM!(D<).CQ^O[_@VWP`769BQ6@%`D(A=(/A34!``"+1@B#Z`&%P(E&"`^(;`$` +XM`(L&Q@`*@\`!B0:+1>2+`(7`B47D#X7"_?__@\0<,% +XM://__P````#'A7#S__\`````QX5X\___`````(F%@//__\>%?//________' +XMA8SS__\`````QX60\___`````(F58//__XN%9//__XD$).C3^/[_A<`/A!0! +XM``"-6`B_<:P("/RY"````(G>\Z9UUHE<)!"+A8CS__^-E93S__^)%"3'1"0( +XMN90(",=$)`0`!```B40D#.@[]O[_C864\___QT0D"`````#'1"0$`@```(D$ +XM).@]]_[_@_C_B85L\___=(''1"00`0```(E$)`S'1"0(`````,=$)`0````` +XMBU4(B10DZ!//__P%^&\=$)`CXK0@(QT0D!`0```"+10B)!"3H>:#__XN5>//__SF5 +XM%=//__P$```#I;?[__XN5C//__XD4).BA +XM]O[_BX60\___B00DZ)/V_O^+E7SS__^)%"3H!?3^_X'$K`P``+H!````6XG0 +XM7E]=PXV5E/O__\=$)`0*````B10DZ+WQ_O^%P(F%A//__P^$0/[__XN-;//_ +XM_XV%E/?__[H`!```B85<\___Z/_[__^%P`^$'/[__XNU7//__[\TK`@(N1,` +XM``#\\Z8/A0/^__^-E93W___'1"0$"@```(D4).A<\?[_A<`/A.7]___&``"+ +XMA83S__^-=93&``"#A7#S__\!Z,GR_O_'``````"-A:?W__^)="0$B00DZ!'R +XM_O^%P'0/Z*CR_O^#.`*0#X1(`0``BY6`\___C86G^___B00DB50D!.CF\O[_ +XMA<`/A:3]__^#A7CS__\!B70D!(N%;//__XD$).BE]O[_BX6,\___A[_[_Z6_\ +XM___'1"0(`````,=$)`0%````BU4(B10DZ"J=___I3_S__\=$)`@`````QT0D +XM!`4```"+50B)%"3H"IW__XD<).@6]/[_Z2?\__^-M@````"-O"<`````58GE +XM5U93@>R,"```QT0D"`````#'1"0$*P```(M%"(D$).C)I?__N@$```"%P`^% +XM<@(``(M5"/:"!`,```$/A6\"``"+?0B+M_P"``")-"3HC^S^_X7`#X5X`@`` +XMQP0D0?$(".@+\/[_A<")A8CW__\/A%X"``"-A93[__^-E93W___'A8SW__\` +XM````B86$]___B96`]___C;0F`````(N5B/?__XD4).@V\_[_A<`/A,H!``"- +XM6`B_<:P("/RY"````(G>\Z9UUL=$)`13K`@(B1PDZ"KQ_O^%P(F%?/?__W2\ +XMBQ6@%`D(A=(/A5D"```/OT`.QT0D$`$```")1"0,QT0D"`````#'1"0$```` +XM`(M5"(D4).BC,___@_@"#X02`@``BX5\]___C964^___QT0D!``$``")%"2) +XM1"0(Z*[M_O^%P`^$N`$``(NUA/?__[@@K`@(N1,```#\B0$``(N5?/?__XV]E/?_ +XM_\=$)`0`!```B3PDB50D".A'[?[_A<`/A%$!``"+M8#W__^X-*P("+D3```` +XM_(G'\Z8/A38!``"-A93W___'1"0$"@```(D$).A^[?[_A<`/A!@!``#&``"+ +XMO9#W__^-=93&!P#H\N[^_\<``````(V%I_?__XET)`2)!"3H.N[^_X7`#X4\ +XM`0``H:`4"0B%P`^%1P$``(N5?/?__P^_0@Z)="0$B00DZ._R_O^-1;2)!"3H +XM!.W^_XV5I_O__XE4)`C'!"16K`@(B40D!.CZ[O[_QX6,]___`0```.FL```` +XMC;0F`````(N%C/?__X7`=0S'!"1AK`@(Z)[I_O^+O8CW__^)/"3H0/+^_S'2 +XM@<2,"```B=!;7E]=PXN"_`(``(T$0,'@`@-"$(MP.(DT).@7ZO[_A<`/A(C] +XM__^)="0(QT0D#$BL"`C'1"0$!0```(M]"(D\).@,G___@<2,"```N@$```!; +XMB=!>7UW#QT0D#&BN"`B)7"0(QT0D!`,```"+50B)%"3HVY[__XN%?/?__XD$ +XM).C!\/[_Z6C]__^+O7SW__^)/"3HKO#^_^E5_?__BX5\]___B00DZ*OO_O_I +XMF/W__^B1[?[_@S@"#X6V_O__B1PDZ-#K_O_KKXN]?/?__XD\).B`[_[_Z;#^ +XM__^-M"8`````58GE@>RH"```B77\B<:-19B)7?B)TXE$)`3'!"1ZK`@(Z)[L +XM_O^%P'0JB30DQT0D#(VL"`C'1"0(>JP(",=$)`0%````Z":>__^+7?B+=?R) +XM[%W#B5PD$(V=A/?__XD<),=$)`QZK`@(QT0D"*>L"`C'1"0$%`@``.B&[?[_ +XMB1PDZ%[K_O^+7?B+=?R)[%W#58GE@^PHB10DB5WTB=.)=?B)??R)SXE%\.AF +XM[O[_@_C_B<9T'P^W10B)'"2)1"0$Z&_O_O^)\(M=](MU^(M]_(GL7<.+1?#' +XM1"0,GZT("(E\)`C'1"0$!0```(D$).A]G?__Z]"-="8`C;PG`````%6)Y5>) +XMQU93BK^_[@!````@<1\%0``6UY? +XM7<.+A_P"``"-!$#!X`(#1Q"+<#CI-?[__XVV`````('$?!4``+@!````6UY? +XM7<.+E=3J__^+A7UW#BX7,ZO__BY70ZO__BQB-1?"+,HD$).B5Y_[_ +XMBY78ZO__QT0D1`:M"`B)7"1`QT0D/`NM"`B)5"1(C97P_O__B5PD.,=$)#08 +XMKP@(QT0D,$"O"`C'1"0L=*\("(E4)"C'1"0D$*T("(N5V.K__XE$)!"-A?#J +XM___'1"0<(:T("(ET)!B)5"0@QT0D%#RM"`C'1"0,2*T(",=$)`B8KP@(QT0D +XM!``0``")!"3H0>G^_SW_#P``B87@ZO__#X<+_O__A<"-M?#J__]U0>FN```` +XMQ@(*@\(!B=,I\XF5W.K__XE<)`B)="0$BY74ZO__B10DZ/OC_O\YPP^%G_[_ +XM_RF=X.K__XNUW.K__W1RBX7@ZO__@_@\C50P_W:UQT0D!`H```")-"3HEN;^ +XM_XG"*?"#^#Q^G#GR=IB)T.L(D(/J`3GR=A:`.B!U](G0*?"#^#P/CGK___^) +XMT.OCB<+I;____\=$)`@`````QT0D!`4```")/"3HU)/__^E%_O__BYW$ZO__ +XMA=MU!S'`Z7;]__^-E?#Z__^)^.A1^O__BX74ZO__B00DZ#?H_O^%P`^%Z_W_ +XM_S'`Z4S]__^-="8`58GE@>PH)```B7W\BWT(B5WTB77XBU\Q= +XMPY`Q]NOLBT,$QT0D!`L```")!"3_4!B%P`^%Y0$``/9%#`1T!(!+6"#V10P! +XM=*N+4U")^.BI^?__ZY^-M"8`````QT0D"`````#'1"0$*P```(D\).CHF___ +XMA<`/A9`!``#VAP0#```!#X7"`0``B[?\`@``C87T^___B70D#,=$)`AYK0@( +XMQT0D!``$``")!"3H3^?^_XGQB?B-E?3[___'!"2``0``Z,7Y__^)A>C;__^# +XMP`$/A#8!``"+1Q#'1"0(`0```,=$)`3DKP@(B3PD_Y!H"```BUM,QT0D"``` +XM``#'1"0$`````(F=[-O__XD<).@-Z/[_B87PV___@\`!=%>-A?3;__^)1"0$ +XMBX7PV___QT0D"``@``")!"3H(NK^_X/X`(G##XX9`0``,?;K!BG#=,T!QHV% +XM]-O__P'PB40D!(N%Z-O__XE<)`B)!"3HC^'^_X7`>=B+A>S;___'1"0,GZT( +XM",=$)`0%````B3PDB40D".C5EO__C87T^___O@$```")!"3H!N3^_XN%Z-O_ +XM_XD$).@XYO[_BT<0QT0D"`(```#'1"0$`````(D\)/^0:`@``.DC_O__C78` +XMQT0D"`$```#'1"0$`````(D\).@X//__A<`/A!#^__^^`0```.D&_O__C;8` +XM````]D4,`KX!````#X3Q_?__D.N^@&-8G[X!````QT0D#%ZM"`B+0TS'1"0$ +XM!0```(D\)(E$)`CH)I;__^G!_?__BX?\`@``C01`P>`"`T<0BW`XZ2W^__\/ +XMA0W___^+A>C;__^)!"3H>N7^_X7`#X49____C8WT^___N@$```")^#'VZ&KX +XM__^%P`^$'O___^GX_O__C;8`````C;PG`````%4QR8GE@^PHB77\BW4(B5WX +XMBUX<#[936(G0@^#]J$"(0UAT)HM#4(/BO8A36(7`="7'1"0$@`$``(M#3(D$ +XM).A`Y_[_,Q\!``` +XMBW4(QT0D"`````#'1"0$*P```(DT).A)F/__A'^__^058GE4X/L%(M=".BUX?[_QP``````BT44B40D"(M% +XM$(E$)`2+10R)!"3HAN'^_XD#Z(_A_O^Z`0```(L`A'^_\<``````(M%%(E$)`B+11")1"0$BT4,B00DZ/;?_O^)`^@?X?[_ +XMN@$```"+"(7)=0B#Q!2)T%M=P^@'X?[_@S@B=`Z#Q!0QTEN)T%W#C70F`(,[ +XM_[H"````=>B#Q!2)T%M=PXVT)@````"-O"<`````58GE@^P8B77\BW40B5WX +XMC48!B00DZ"KC_O^%P'0EB<.+10R)="0(B1PDB40D!.A!X_[_Q@0S`(G8BW7\ +XMBUWXB>Q=PXM%"#';QT0D"`````#'1"0$!0```(D$).APC/__Z]6-M"8````` +XMC;PG`````%6)Y5.#[!2+70C'1"0$+P```(D<).@ZW_[_A7UW# +XMBT7LAQT*0^V`SP@=.8\"73BB0^#Q"PQP%M>7UW# +XMC;8`````@\0L,6#[!B+ +XM112)7?2+70R)??R+?1")=?B%P'54/0`!``"+%W)8A=N--`)T78D<)(ET)`3H +XMS-S^_XG#A=MT5XL'B?+'1"0$`````"G"`=B)5"0(B00DZ*K>_O^)-XG8BW7X +XMBUWTBWW\B>Q=PY"-="8`BQ53@^PDBT44BUT(@_@"=&Z#^`-T287`=27'1"0(`````,=$)`0% +XM````B1PDZ&V*__^#Q"1;7<.-M"8`````BTL)___I-?___^A1V_[_C47XB40D +XM!(D<).A^5___A<`/A1G___^+1?B%P`^$>?___XE$)`S'1"0(`+((",=$)`0# +XM````B1PDZ%^)___I[?[__XM5##'`A=)T!8M5#(L"QT0D"`0```")1"0$B1PD +XMZ%A4`0#IQO[__XUV`%6)Y5=64X/L#(L]P,P("(E%\(E5[(7_=$( +XM1>NXP,P("#A5ZWT6ZS*)]HM[&(7_="D/MA>-0Q@X5>M\'CA5ZXG#=>>+3>R+ +XM=?#\.Q`/MC>-1MP\.`^&)@$``(M# +XM%(7`#X01`0``BTL0#[8QB?`/OM"%TGA#.17\(`D(?R_K.8M#%(U1`8E3$(/H +XM`87`B4,4#X3A````#[8RB=&)\`^^T(72>!0[%?P@"0A]#*$((0D(]D20-@)U +XMQX/Z?P^'R@```/8$E=T4"0@$#X2\````BTT(BS&%]G47QP$!````BU7=='I)/___X-K%`&ZT)D%"(E+$(`Y+W0%NC"5!0B+3=R+ +XM04R+3=B)`8M-W(M!4(M-V(E!!(N#@````"4````!@_@!&<`PP`5P`0``B40D +XM&(U%[(E$)!2+0Q2)1"00BT,0B4PD"(E,)`2)1"0,BT7Q0!#X:R````BU,0#[Y"`8/X?P^'H@```/8$A=T4 +XM"0@$#X24````Q@(KZ7?]__^+50C'`@$```"!BX````````0`@WL4`0^$,@,` +XM`,=$)`P#````BU78B50D"(M#$`^^0`&)1"0$BTWS'`@$` +XM``"!BX````````0`QT0D#`H```")1"0(BT,0B40D!(U%\(D$).CN]O__@_@! +XM#X6L````BT7PBU78B0+'0@0`````BU7LB=`K0Q`I0Q2)4Q#I?_S__[K0F04( +XMZ=O]__^#^G\/AZ0```#V!)7=%`D(!`^$E@```(#Y+0^$'0$``#'_@/E>#X02 +XM`0``C47LC57PQT0D#`H```")1"0(B70D!(D4).AP]O__@_@!=3*#?>``#XR@ +XM````D`^.L````(M5\(72D(UT)@!^$+C___]_*T7@.=`/@Y0```"X`@```(E$ +XM)`S'1"0(`P```,=$)`0`````BTW`%%X(-#$`&-1_^)0Q3I(OS__XM5\(72>1"X````@"M%X#G" +XM#XT!`0``A?]T1HM%\/?8BU7L`47@B=`K0Q`I0Q2)4Q#I[/O___8$E=T4"0@$ +XM=(WIVO[__X-K%`&_`0```(U&`8G&B4,0Z=C^__^-M@````"+1?#KNK@!```` +XMZX&+3=B+1>"+$??8.=`/A@_\___'1"0(C+((",=$)`0#````BT7" +XM__^+50S'`@$```#I\?O__X/$/+@!````6UY?7<.+>Q`/MC?'!"0*L0@(B?(/ +XMOL*)1"0$Z"75_O^%P`^$FOK__\=$)`P!````QT0D"`$```#'1"0$`````(M- +XMW(D,).CF]___BT4,QP`!````,<#ID/O__X-#$`*#:Q0"Z67Z__^X`P```.EF +XM_O__QT0D#`(```#'1"0(`P```,=$)`0`````BT7575KX"````4X/L+(M=#(M%$(M]",<``````,=#8``` +XM``"+0Q2%P'1_BTL0#[81C4+W/#(/AJ0```"+11"-3>B)VHE$)`2-1?")!"2) +XM^.@K^?__A<`/A4<"``"+11"+`(7`=6J+1?"%P'0]A?8/A#D"``"+0V"#^`$/ +XMA)H!``"#^`(/A'(!```Q]H7`=92+1>B+5>S'0V`!````B4-DBT,4B5-HAG<_O__]H.#````!`^%>____XM7'(72#X01 +XM`0``A?8/A$8!``"-0VR)1"0$B3PDZ$E.__^%P`^%)0$``#'`@WML`,=#<``` +XM``#'0V@`````#Y7`,?:#0Q`!@VL4`8E#9,=#8`(```#I=?[__Y"+0V"#^`%T +XM?8/X`@^$D@```(7`#X5M____C;0F`````.BOT?[_BU-LBT-PB5-DB4-HBT=, +XMB4-LBT=0QT-@`@```(E#<`^V$>DU____BU-L,?:+0W")4V2)0VB+1>B+5>R) +XM0VR)4W#I"?[__XM%Z#'VBU7LQT-@`@```(E#;(E3<.GO_?__BT-DO@$```") +XM1TR+0VB)1U"#0Q`!@VL4`>G1_?__BT-LO@$```")1TR+0W")1U"#0Q`!@VL4 +XM`>FS_?__QT0D#`$```#'1"0(`0```(D\),=$)`0`````Z)_T__^+11#'``$` +XM``"#Q"PQP%M>7UW#N`$```#I)/[__\=$)`P!````QT0D"`````#KP8M#8(/X +XM`71<@_@"=$N%P)`/A>G]__^+1TR)0V2+1U#'0V`!````B4-H,<#IXOW__\=$ +XM)`BXL@@(QT0D!`,```")/"3HR'[__XM%$,<``0```#'`Z;K]__^+4VR+0W") +XM4V2)0VB+1TR)0VR+1U#'0V`"````B4-PZ8C]__^-="8`58GE5U93@>R,```` +XMBT4(BU4(BTT(BT`0@\%,B464BY*8````B560BUA\B4V$BT,(A%"+1:`[!?P@"0A]1:$((0D(BU6@]D20 +XM-@)T-KX!````BTL4@T,0`8/I`87)B4L4=#&+0Q`/M@`/OM`\"HE5H'6YBTV4 +XM@X$(`0```8-##`'KSX7)=`J#?:`Z#X0[`0``BTL4A0`````Z?$%``"0BTL4@^D!A2)3"0(B5PD!(DT).C)^?__A<`/A5H%``"+5>2%T@^%D0X` +XM`(M#%(7`=$*+>Q`/MA!0[!?P@"0A]#*$((0D(]D2P-@)U +XM"8#Z.@^%Y@,``(U'`8E#$(M#%(/H`87`B4,4=;['0R!0T`@(BW60BT8H"8.` +XM````BT-@A`P`` +XMQT6L`0```.G2`P``H0@A"0B+?:#V1+@V`@^$UOW__XM+%(U"`8E#$(/I`87) +XMB4L4#X0__/__B<(/O@"%P(E%H`^(K_W__SL%_"`)"'R^Z:+]__^)]HM#%(/H +XM`87`B4,4#X2Z`0``BU,0C4(!B4,0@'H!"G7@@8N```````"``(-#$`&#:Q0! +XMBTV4BUE\Z=#Z__^+182+50B)1"0$B10DZ!%'__^%P`^%X@(``(M-",=!4``` +XM``"+@X`````E__^__XF#@````.G#^O__BU9(BT9,B580C0P"B10DB40D"(E, +XM)`3H@<_^_XM&3(E&%(M'"(M5"(E"3(E&1(/``8E'"`^V1E"H#`^$>_S__XM% +XM"(&(K`0``````@"+592+6GR+2Q2%R0^%./K__^EI_/__C;8`````BW,4A?:) +XM\0^$>P(``(M]C`^V%X#Z(0^$EA0```^^\H7V>!0Y-?P@"0A^#*$((0D(]D2P +XM-@)U38#Z*P^$G!0``(MS%,=%G`````#'19@`````QT6P`````.E<_O__#[X7 +XMA=(/B.$1```[%?P@"0@/C=41``"A""$)"/9$D#8"#X3%$0``BWL0C4'_B4,4 +XMB<&#QP&%P(E[$'7$,?:+>Q")\,=%K`````#'19@`````QT6<`````,=%L``` +XM``#IZ`$``(M3(.DE_?__@:.`````___^_^GR_/__BTT(B[F0`@``A?\/E<#I +XMQ_S__XM#$(`X"@^$2?[__XMUE(M>?.DK^?__BT4(]H"L!````@^%-OK__XN3 +XM@````/;&"`^$I?O__^DB^O__@/I\#X0D_/__@/H*#X0;_/__BT6@QP0D5;$( +XM"(E$)`3HN-2KN`^1\/ +XMABP4```Q]HM5J(GXZ.'M__^%P(E#(`^$0QP``(M3(('Z.-,("(G1#X2.&P`` +XMA?8/A#$6```/MT$(]L0!#X4K%@``@?E0T`@(#X06%@``@?F8T`@(#X0*%@`` +XM#[8/#[[1A=)X%#L5_"`)"'T,H0@A"0B+E)`T"```B!?I_1L``(UV`(M#2(D$ +XM).BIS?[_BQ.%TG0&BT,$B4($BT,$B1")'"3HD,W^_XM>?#E=P`^%7@H``,=# +XM%`````"+50C'1"0$`@```(D4).CV-/__A7UW#BWV,,<#'19P`````QT6L`````,=%F`````#'1;`````` +XMA<`/A'0@``")^.L\B?*`^A9T9(-]H`H/A,4```"#?:!\#X2[````#[9-H(@/ +XMBT,0@VL4`8M3%(/``8E#$(72#X2\````@\Q0!=I:+0Q`/OD`!@_@* +XMB47D=6J+=92#A@@!```!@T,,`8-%G`&#:Q0!@T,0`8M%Y(E%H.EV____BU4( +XMBT(0@+A2!P``_P^%3____XM-H(D4)(E,)`3HY#7__X/X$G2?@WV@"@^%.___ +XM_XGR@/H*#X1#$```@VL4`8MS%.L-@_A\#X4H____ZYDQ]HM#$(M3&(ES'(/` +XM`8E#&"G0B5,0*T6<@^@!@7L@H-$("(E#%`^$L0X``(N#@````(G"@^(/@_H" +XM#X0<#@``#X?`````@^H!#X7-````BU-@A=*)]@^%=!````T```@`J"#'0V`! +XM````B8.`````#X5V&P``BU4(BT),B4-DBTT(@7L@P,P("(M!4(E#:`^%GP`` +XM`,=#8`(```"+50B+0DR#P`&)0V2+30CV@4`#```!BU%,#X4V$```BW4(BX8X +XM`P```=")0VR+?0B+1U")0W")0VB-1?")1"0$B3PDZ/)!__^%P`^%!0<``(M% +XM\(7`=$$[1TQV/#M#;',WB4-LZS*-="8`@_H$#X3F`@``@_H(C70F``^$7@,` +XM`(MS8(7V#X6E!@``@7L@P,P("`^$8?___XM#(,=#7`````"+>`P/MC>)\(3` +XM#X26&@``BTL4B?*`^B$/A'$$``"%R71GBT,0#[X0A=(/B,4#```Y%?P@"0@/ +XMCKD#``"A""$)"/9$D#8"=2SIJ`,```^^$H72#XB:`P``.Q7\(`D(#XV.`P`` +XMH0@A"0CV1)`V`@^$?@,``(M3$(U!_XE#%(G!@\(!A<")4Q!UQ,=$)`2WL0@( +XMB3PDZ)/)_O^%P`^%[04``(M#8(/X`0^$P`0``(/X`@^$,@L``(M-"(N#@``` +XM`(N1K`0``/;"`@^%?P,``/;$0`^%=@,``*D```0`#X59#0``@^(!C78`=`>+ +XM10B#0"P!BU4(BTH((``"+ +XM30CV@:X$```"#X72"```]H$8`0```0^%P1<``(MU"(N&$`$``(7`#Y7`A,`/ +XMA*\(``#V@X````!`#X2B"```N@`0``#IG`@``,=#8`$```"+1TR#P`&)0V2+ +XM1U")0VCIWO7__XM38(72#X6%````#0``"`")@X````#'0V`"````BW4(BT8< +XMA<`/A+$3``"+?0B-0VR)1"0$B3PDZ*0^__^%P`^%MP,``/:#@````"`/A)$1 +XM``"+0VR%P`^%AA$``(.+@````!#'0V0`````@XN`````!,=#<`````#'0V@` +XM````Z:W\__^+4V"%T@^$HOS__X/J`0^%F?S__XM39(M#:,=#8`(```")4VR) +XM0W#I@?S__XMS%(M]C(7VB?`/A'$2``")^<=%G`````#K+(#Z"@^$UO?__P^V +XM1:"(`8M[$(-K%`&+Q"%]HGP#X0`^O__@\$!#[87#[["@/IL!```Z3'[__\/ML#_)(5(M@@(9H-+?""#:Q0!@T,0 +XM`8MS%(7VB?$/A.?^__^+0Q`/M@`\+@^$XPT```^/*P@``#PK#X3?#0``/"V) +XM]G3$B?'IOO[__SPCD(UT)@!U\(&C@````/___O]F@4M\``*+39"!22@``@`` +XM@VL4`8-#$`&+O$B4PD#(M-"(M#$(E<)`2)#"2)1"0(Z"XN``"%P'55 +XM#[9'`8U7`3Q.#X0T^O__#[[`@^@PB47D@'H!;P^$4`L``(MUD(M6)#G0#X03 +XM^O__BT,@BW4(BT`0QT0D"+JQ"`C'1"0$`P```(DT)(E$)`SH]6S__XM['(7_ +XM#X6C````BW,4A?9U+XUV`.F"````@/H6=%>#_@J-=@`/A!H/``"#_GP/A!$/ +XM``"+0Q2#Z`&%P(E#%'14BT,0#[80@\`!]H."`````HE#$`^^\G7!B?`\_P^$ +XM7`8``(M]"`^VP(M7$("\`E,'```2=:F+0Q2#^`%VH8/H`8E#%(M#%(-#$`&# +XMZ`&%P(E#%'6LBTL?(V&@````(E%P#G##X2B]?__]D-0 +XM#P^$<_7__XM3/(U[/#GZ=2?I6?7__XM"!(E!!(M"!#G'="J)"(D4).CVPO[_ +XMBU,\.=2%T@^%;O[__XM%Z(7`#X3& +XM%0``BT74A<`/A<R)!"3H!]W__X/X`0^%VQ0``(M-[(7)#X02$0``BT7@*T,0*4,4BT7@ +XMB4,0@#]A#X35$0``BT7LB4-89H-+?`2+2Q3I?_O__XM#$`^V,(GR@/HK#X0K +XM"0``@/HM#X0B"0``@/I>#X09"0``@/HCB?8/A`X)``")\0^^P8/X?W<.]@2% +XMW10)"`0/A>+Z__^#:Q0!B?"#0Q`!9H-+?`&+2Q2(0U'I'_O__XM[$(E]R(E] +XMX(M#%(7`#X3R````@\(7V>!@[-?P@"0A]$*$((0D(]D2P +XM-@(/A;L```"+5<2)^(A"_X-K%`�Q`!@T7$`8M#%(7`#X2J````BT7$B47( +XM@^@!B47,BT,0]H."`````@^V.(GZ#[[R=:")\#S_#X2'"```BTT(#[;`BU$0 +XM@+P"4P<``!)UB(M#%(/X`7:`BU,0@^@!B4,4C4(!B4,0#[9"`8M-Q(A!_^N) +XM,<"!>R#8S`@(B4PD#(M-"`^4P(E$)!"+0Q")7"0$B0PDB40D".AB,P``A<`/ +XMA#/V___I0/S__Y"-="8`@T,0`8-K%`&+=`I1Q")?8P/O@>% +XMP(E%H`^(W`D``#D%_"`)"`^.T`D``*$((0D(BU6@]D20-@)U,NF\"0``#[X" +XMA<")1:`/B*L)```[!?P@"0@/C9\)``"A""$)"(MUH/9$L#8"#X2,"0``BU,0 +XMC4'_B4,4B<&#P@&%P(E3$'6^Z5K[__^%TG0KBWT(BT=,QT78`````(E4)!") +XM7"0$B474C474B40D#(E$)`B)/"3H)9\``(M%F(7`=%GV@X(````"#X1.`P`` +XMBT68BU6P@'P0_Q8/E,"$P'01BU,8C4+_B4,8QD+_%H-#'`&+39@I2Q@!2QR+ +XM0QB+=;")3"0(B00DB70D!.B3OO[_@8N```````!``(M#&(E#$(M#'(E#%(M] +XM"(N7K`0``/;&'G5BBT64BUA\Z5WI__^+0VR%P`^%/?G__XN#@````*@0#X5L +XM^?__BWT(]H>L!````74+J0````(/A57Y___'1"0,`0```,=$)`@$````BT,@ +XMB40D!(M%"(D$).C.W/__Z73Z__^+30B+01"+6'R%VW15,?\Q]H![4`AV!>@! +XMN?[_#[9#4/\DA62W"`B%_W4@BWT(QT0D"*RS"`C'1"0$`P```(D\)+\!```` +XMZ!YG__^+&X7;=<`)]P^%R?K__XM-"(N1K`0``(#F%@^$9>___^G,ZO__A?9U +XMUXM%"&:^`0#'1"0(Y+,(",=$)`0#````B00DZ-9F__^+&X7;#X5T____Z[*+ +XM30B+D:P$``#VP@%U"ZD````"#X7.\___QT0D#`$```"+=0C'1"0(!````(M# +XM((DT)(E$)`3H[]O__^F5^?__BU-@A=(/A1[V__\-```(`,=#8`(```")@X`` +XM``"+30B+44R#^@$/A,X$``")4VR)4V2+?0B+1U")0W")0VCIB/+__P^V%X#Z +XM*P^%Z^W__^F"`@``BU4(BT(0@+A2!P``_P^%3?G__XET)`2)%"3HYR;__X/X +XM$@^%./G__^F*^?__A<"-M"8`````=1?I/_'__X/H`8VV``````^$,/'__X/" +XM`8`Z7(UT)@!UY<8"%NO@BWT(B40D!(D\).@:,___A<`/A"4/``"+EZP$``"+ +XM@X````#ISO+__SP]#X2_!0``/%X/A=/W__]F@TM\`NF2]___/&R0C70F``^$ +XMOP4``#QP#X6T]___9H%+?``0BT60@4@H`!```.G)]___BWT(BT=,B474BT=0 +XMB478C474@:.`````___[_\=$)`P!````B40D",=$)`0G````B3PDZ+55__^% +XMP`^%./C__XN7K`0``.E<\O__B10DZ)IB___I'//__XM-"(E$)`2)#"3H5C+_ +XM_X7`#X2U!P``BT9$BWT(B4=,Z63H__^)%"3HZ$;__^E#\O__BTV8BW6P#[9$ +XM,?\\_P^$"P,``(M]"`^VP(M7$("\`E,'```2#Y3`Z93\__^!BX```````(`` +XMZ:[O__^+4VR+=0B%THG0BTY,=06X`0```#G!#X1<]?__A=)U`K(!BWT(B?B) +XM5TR#P%#'1U``````B40D"(E4)`2)/"3H--C__^DO]?__BU-DBT4(A=*+2$R) +XMT'4%N`$````YP0^$$_7__X72=0*R`8M-"(G(B5%,@\!0QT%0`````(E$)`B) +XM5"0$B0PDZ.O7___IYO3__X/Z`@^%3O#__XM3;(M#<,=#8`$```")4V2)0VCI +XM-O#__XN!.`,``(T$0,'@`@-!$(M`..F\[___@VL4`8MS%(U'`6:!2WP``8E# +XM$(7VB?&)0Q@/A,GK__\/MA")Q^E`Z___BT,4@\!Z+1:`[!?P@"0A]$Z$((0D(BU6@ +XM]D20-@(/A5`#```/MDV@B`Z+0Q"#:Q0!BU,4@\`!B4,0A=(/A#(#``"#Q@$/ +XMM@`/OM")5:#V@X(````"=:0/MD6@//\/A#H"``"+30@/ML"+41"`O`)3!P`` +XM$G6)BT,4@_@!=HP!@^@!BU,0B4,4C4(!B4,0#[Y2`8E5H.N*N`$```#3 +XMX*D#B@(`#X5%!0``A<`/B;KK__^+%7#."`B)^8E5X`^V!SH"=1"#P0&#P@&) +XM5>`/M@$Z`G3P/&QT&SQP=!<\*W03/"UT#SQ>C78`=`@\(P^%>>O__XM#$#'V +XMB4L0*<@!0Q2A<,X("(E#)*%TS@@(B4,HH7C."`B)0RRA?,X("(E#,*&`S@@( +XMQT,P>;$("(E#-*&$S@@(B4,XC4,DB4,@Z4'K__^+0Q"`.`0/A(SF__^`YG^) +XMDX````#I?N;__ZD````"=0V!>R#`S`@(#X6G[___BWT(BU64QT0D!`$```") +XM/"3_DGP(``#IB^___X`_*P^%E/+__SPKB?8/A/+V__\\+0^%@O+__V:#2WP( +XMZ?#V__^+?9"+5R2%T@^$P^[__^FC]/__BU4(BT(0@+A2!P``_P^%I/G__\=$ +XM)`3_____B10DZ'(B__^#^!(/A8OY___I=?G__XUT)@"H(`^$*OO__XU%\(E$ +XM)`2)#"3H:2___X7`#X5\]/__BWWPA?\/A9L*``"#BX`````0QT-L`````,=# +XM9`````#I]/K__\=$)`0Q````B3PDZ+"S_O^%P`^%U/'__^G5]O__BT,4A<`/ +XMA`7N__^-="8`Z0'T__^+50B+0A"`N%('``#_#X4!]___B70D!(D4).C,(?__ +XM@_@2#X7L]O__Z5_W__^+50B+0A"`N%('``#_#X5/_?__BTV@B10DB4PD!.B< +XM(?__@_@2#X4W_?__Z:G]__\Q]HM3(`^W0@CVQ`)T+XM5"/:"9`,```$/A)<# +XM``"+@EP#``"-!$#!X`(#0A"+0#B%P`^5P(3`#X71"@``@?DXS0@(#X0O!0`` +XM@?EHS0@(#X1N!@``@?GPS`@(#X2"!@``@?F0SP@(#X1F!@``@?E0T`@(#X0T +XM!P``@:.`````_____>DOY?__@VL4`8/``6:!2WP``8M+%(E#$.D5\?__,?;I +XMO^+__XM#$(G&*?Z)=9B+0`````BW,4A?8/A'P```"+0Q`/O@"%P(E%H`^(E3`0``C78`#[X`A<")1:`/ +XMB$(!```[!?P@"0@/C38!``"A""$)"(M-H/9$B#8"#X0C`0``QT7D`0```(M# +XM$(-K%`&+"+0Q2%P'4FZ9T```")\H#Z%G1,B?"(!X-K +XM%`&#QP&+0Q2#0Q`!A<`/A'P```"+0Q`/MC")\`^^P(E%H/:#@@````)UR`^V +XM1:`\_W0RBTT(#[;`BU$0@+P"4P<``!)UM(M#%(/X`7:LBU,0@^@!B4,4C4(! +XMB4,0#[9"`8@'ZYF+50B+0A"`N%('``#_=8:+3:")%"2)3"0$Z"T?__^#^!(/ +XMA6[____KN(GVBT7@BU4(B5PD!"G'B7PD#(E$)`B)%"3HA"$``(7`#X0EZ___ +XMZ3+Q__^-M"8`````A?:)\`^$[O[__X-]H"&)]@^%XO[__X%[(/C0"`AT"XM] +XMY(7_#X3._O__A?8/A"\(``"+>Q`/MA>`^@IU$8UV`.F.Y?__@#\*#X0T!0`` +XMBWL0@^@!B4,4@\Q!UY,=%G`````#IM^?__XUV`(-[%`$/AD;Q___' +XM0QP!````Z5/Q__\/OM*%TG@4.Q7\(`D(?0RA""$)"(N4D#0$``"^`0```(@7 +XMZ5CF__^)T/?8.4%,#X>TZ___QT0D"&2S"`C'1"0$`P```(D,).A.7?__Z53P +XM__^+182+50B)1"0$B10DZ"3__P^V!SP\#X7V^O__#[[`B46@BTL4A +XM``"%P`^%UNW__XM+(.E:^O__#[8/@/EK#X1]`0``@/ES#X2N`@``A?8/A>'C +XM__^+10B%P)`/A#("``"+50B+P_O^+=;R+?0C'1"0,?[$(",=$)`0#````B70D"(D\).@Q7___ +XMBWT(BT<0AQ"+0Q3'19P`````Z:7C__^`/S`/A.7N +XM__^+?0C'1"0(G;$(",=$)`0#````B3PDZ'U9___I@^S__XN!$`$``(T$0,'@ +XM`@-!$(M`.(7`#Y7`Z3'H__^+30C'1"0$_____XD,).@Y%?__Z;SI__]F@TM\ +XM$.E2[O__@WVH`HVV``````^%?/[__X-K$`&Y>,\("(-#%`''0R!XSP@(Z1SB +XM__^+39#'02@`$```Z;WX__^+2Q3I`>K__XMU"(U%\(E$)`2)-"3HV";__X7` +XM#X7KZ___BT7PAR)0VSI%^[__XM]"(M'3(E#9.DWY/__N@H```")QL=%G`````#I1>#_ +XM_XL"QT0D".RR"`C'1"0$`P```(D\)(E$)`SH;5C__^ESZ___BT6HQT7<```` +XM`,=%O`````"#P`$/A>L"``"+5:B+1;S&!!``B50D"(E\)`2)!"3HV*[^_XMU +XM"(M-O,=$)`Q_L0@(QT0D!`,```")-"2)3"0(Z")=__^%]@^%Z?W__^GZ_?__ +XMD(UT)@"#?:@!="B+1:@QTH/H`8E%B`^V1#H!/&-T##QG=`@\<@^%+/W__X/" +XM`3M5B'7CBT,0@\`!*T6HB4,0BT,4@^@!`T6HB4,4H7#1"`B)0R2A=-$("(E# +XM**%XT0@(QT,H4-T&"(E#+*%\T0@(B4,PH8#1"`B)0S2AA-$("(E#.(U#)(E# +XM(.ERX/__BU,4C4$!B4,0@^H!A=*)4Q3'1:0"````#X3E````BTL0#[8!/%QT +XM+P^^P#G'#Y3`#[;`*46D@VL4`8MS%(-#$`&%]HGR#X0%^/__BTVDA(E$)`B+1G2) +XM1"0$BT4(B00DZ-7*__^%P`^$..G__XE&=.FU^___BW4(QT0D#`$```#'1"0( +XM`@```,=$)`0`````B30DZ&++___I".G__XM3$(E5C.D"^___@:!4"```__[_ +XM_^GNZ/__BW4(B40D#,=$)`@#````QT0D!`````")-"3H),O__^G*Z/__BWL0 +XMQT6<`````.FTW___QT0D"`@```"+50B+`8D4)(E$)`3HMR`!`.F=Z/__QT0D +XM#!BS"`B+=0B+0Q#'1"0$`P```(DT)(E$)`CH@%K__^EVZ/__BW,4Z7_@__^+ +XM30B)1"0,C47575E.#[!R+10B)1?"+,(M^$(DT).C$'@$`A4"```BQ.%TG0&BT,$B4($BT,$ +XMB1"+0PR)!"3HM:O^_XD<).BMJ_[_BU]LA=MUM_:'5`@``!`/A9,"``"-5GB[ +XM(`H``(V'D````(E5[(E%Z.FH`0``BX8T`0``BU80C01`BTR".(7)#Y7`A,!T +XM`X/+0/:&[`(```$/A.,!``"+AN0"``"-!$"+1((XA<`/E<"$P'0&@'D````-+4"`C'AY0````!````QX<``0```(`` +XM`(DT).C:U/__A,`````8N&K`0` +XM`*D````"=!&I```$`'1W@::L!```_____8DT).C.@@``]H8\`0```0^%)?[_ +XM_XN&-`$``(M6$(7`#Y7`Z2?^___'1"0$)KH("(DT).CN@@``B30DZ):"``#K +XMF8UT)@"+AN0"``"%P`^5P.D?_O__BT((B8>0````BT(0B8>4````Z;W^___' +XM1"0(`````(M&3(DT)(E$)`3HLDG__^EM____@>(`!```B50D",=$)`0````` +XMB30DZ-/\_O^%P'0U@\0'C`````$```#'AX@```#(L0@( +XMZ53]__^+5?`QP(DR@\0<6UY?7<.)-"3H(I+__XM5\(D"B74(@\0<6UY?7>F> +XMDO__D)"0D)"0D)"0D)"0D)!5B>564X/L$(M%#(MU"(M`=(L8BT80]H!4"``` +XM`70CQT0D#`````"+0PB)1"0(BP.)-"2)1"0$Z%2G__\QTH7`="/'1"0,B+<( +XM"(L#QT0D!`,```")-"2)1"0(Z%!6__^Z`0```(/$$(G06UY=PXGV58GE5U93 +XM@^P\BT4,BU!XA=)U+\=$)`@`````QT0D!`````"+10B)!"3HHJ+__S'2A<`/ +XMA&L!``"#Q#R)T%M>7UW#@_H"=`7HF*+^_XM`=(E%X(L`BSB)?>B+0`B)1>0/ +XMMDP'_P^VT3L5_"`)"`^-_0```*$((0D(]T20-``%```/A.H```"+1>@/M@B$ +XMR70NBQW\(`D(B@/ML`YV'T+]D2&-@(/A80!```/MD(!@\(! +XMA,!UXX-]Y`(/A@(!``"+=>2#[@(/A/8```"+/?P@"0BA""$)"(M5Z(E]W(E% +XM[.L2C;8`````@\(!@^X!#X3.````#[;!.T7S&1?,!]T2#-``%``!U +XM!X#Y7P^41?,/MDH!#[;!.47R[`0```/=$AS0`!0``=0R-M@````"` +XM^5\/E,,Z7?-TI<=$)`@PN`@(QT0D!`,```"+10B)!"3HRD___[H!````Z"+4P3'1"0@"````,=$)!P`````BT((B40D&(L"B40D%(M]Y(E\)!"+ +XM1>C'1"0(`````,=$)`0`````B40D#(M5"(D4).AJI?__N@$```"%P`^%%?[_ +XM_XM="##2BT,0@XA4"````>D!_O__QT0D"/RW"`C'1"0$`P```(M="(D<).C> +XM3O__N@$```#IW/W__Y"0D)!5B>575E.#[#R)1=R)5=B+5=R+0!")1>"+0AR% +XMP`^$L`,``(M%V(M5W(MX9(U!_X/X`8EZ3`^&>`$``(/I`0^$?@$``(M-V(MQ +XM'(7V=&N+41B)TX`["@^$Y`$``(/#`8/N`77OBT7<]H"N!````@^$ZP$``(G8 +XM*="#^`$/A.`"`T$0 +XMBW`XA?8/E<"$P+H0$!``=06Z`!`0`(M-W/:!/`$```$/A=0!``"+1=R+@#0! +XM``"%P`^5P(3`=`.#RD"-=>R)=>R)=?")5"0,QT0D"`````")="0$BU7DR0C70F``^$E0```#'` +XM@\0\6UY?7<,YTP^%'/[__X7V#X04_O__@^X!=#^#PP&)VNGT_?__B=@IT.D9 +XM_O__@#HN#X40_O__A?8/A#K^__^#[@&-="8`#X0M_O__BU78C4,!B4(8Z1_^ +XM___'1"00`````,=$)`Q/C0@(B7PD",=$)`0!````BTWGH_?__QT0D!`$```")%"3H11G__X7`#X13____BTW<,<#'04P! +XM````@\0\6UY?7<.+@30!``"-!$#!X`(#01"+2#B%R0^5P.D>_O__BT7$P/A17____'1"0$`0```(D$).CO&/__A<`/A/W^__^+5=PQP,="3`$```#I +XM[O[__\=$)`0!````BT7P``Z3S___^-M@````!5N0(` +XM``")Y8M%"(M5#%WIG/O__XVV`````(V_`````%6Y`0```(GEBT4(BU4,7>E\ +XM^___C;8`````C;\`````53')B>6+10B+50Q=Z5_[__^0D)"0D)"0D)"0D)"0 +XMD)!5N`(```")Y5=64X/L'(M=#(M]"(7;=`:+0WB#P`''1"0$!````(D$).CF +XMGO[_A<`/A)$```"%VXE%\'1-BTMTBW7PBP&+4`B%TG1JB) +XMUH/&!,<&`````(M%\(/$'%M>7UW#QT0D"`````#'1"0$!0```(D\).A!2?__ +XMQT7P`````.O4D(VT)@````!5B>575E.#["R+?0B+7R2%VP^$1`$``(L#A<`/ +XMA"`!``#'1>@!````QT7L`````,=%\`````#IGP```)"-="8`@WWH`70:QT0D +XM!-+4"`B)/"3H6GD``(M/*,=%\`$````YRP^$R````(L3N4^-"`B)R(E$)!") +XM5"0,B4PD",=$)`2RN`@(B3PDZ+-Y``"+1Q#V@%0(```$#X6D````QT0D#`$` +XM``#'1"0(`````,=$)`0`````B3PDZ*,,__^%P'4,BT<0]H!4"```!'5T@\,$ +XMBP.%P'1K@T7H`8D$).@2H/[_BT\H,=(YV0^4P@-%\(TT4`%U[(M'.(/H`3E% +XM[`^"//___\=$)`0FN@@(B3PDZ)QX``"+3RB)=>S'1?``````.```@\0L,56 +XM4X/L$(M="(MU#(M#)(7`#X2(````QT0D"!$````/MT9\B1PD)0`!``")1"0$ +XMZ&KQ_O^%P'0,@\00N`$```!;7EW#BT,DB4,HBP")'"2)1"0$Z%;T_O^%P(G" +XM=-H/MT9\QT0D"`````")5"0$B1PD)0`!``"#^`$9P(/@_(/`)(E$)`SHI/7^ +XM_X7`=:J!BZP$````"``$@\006UY=PXD<),=$)`CTN`@(QT0D!`,```#H]T;_ +XM_X/$$+@!````6UY=PXUT)@"-O"<`````58GE@^PHB77XBW4(B7W\BWT,B5WT +XMBT8H.T8D#X3>````]H>!`````74VQT0D"!$````/MT=\B30D)0`!``")1"0$ +XMZ(GP_O^%P'15N`$```"+7?2+=?B+??R)[%W#C78`BUC\B1PDZ#F>_O^)7"0( +XMB7PD!(DT)(E$)`SHL0D``(7`=(72=1:+1RB%P`^$GP$` +XM`(M(!(7)#X24`0``BTT,]H&!`````71XA=)T-(U%\(E$)`B)?"0$BT<0B00D +XMZ.Z'__^Z`0```(7`#X2(`0``@\0LB=!;7E]=PXVT)@````"+1RB+6`2)'"3H +XM]IS^_XE<)`B)1"0,BT4,B3PDB40D!.AK"```A<`/A`0!``"#Q"RZ`0```%N) +XMT%Y?7<.-="8`QT0D"!$```"+50P/MT)\B3PD)0`!``")1"0$Z-#N_O^%P'7) +XMBTT,BU%XA=(/A"`"``#VAZT$```@=3*+5R2%TG0KBP*%P'0=B=.-M@````") +XM!"3HO)O^_XM#!(/#!(7`=>Z+5R2)%"3HIYO^_X&GK`0``/^?___'1R@````` +XMQT0D!`0```"+50R+0GB#P`&)!"3H79G^_X7`B<:)1R0/A"8"``"+10R+2'2+ +XM`8M0"(72#X0;`0``B +XM7UV)PHG0PXUT)@")/"3'1"0(U[@(",=$)`0#````Z-A#__^#Q"RZ`0```%N) +XMT%Y?70O__N@$```#IP_S__Y"0D)!5B>57 +XM5E.#[`R+10B+F)@```"+4QR%TG1,BT,@A) +XM%"3HOYC^_\=#'``````QP,=#(`````#'0R0`````@\0,6UY?7<.-M@````"- +XMOP````!5B>575E.#[!R)1>R)5>B+L)@```"+1B2)1?"+3B"%R70,B<*#P@*- +XM0?\YPGQ/BU8((M]\,'G +XM`HG[`UXB#P`$Y0P1S(XL3B4,$ +XMA=)T8HE$)`2)%"3H99+^_X7`B0,/A!$!``"`2PP!BT7P@\`!B2) +XM^P->'(L+A6_O^-=@#KG<=$)`00````QP0D`0```.@^E?[_ +XMA<")`P^$U0```(M&'(M5\(L4D(72#X5$____BU7LQT0D"`````#'1"0$!0`` +XM`(D4).@40/__N`$```#KAL=$)`00````QP0D`0```.CME/[_A<")`P^$I``` +XM`(M&'(M5Y(L4D(72#X5+____ZZV+5>S'1"0(`````,=$)`0%````B10DZ,$_ +XM__^+5AR%T@^%DO[__XM%[(D$).B;_?__Z7?___^+1>S'1"0(`````,=$)`0% +XM````B00DZ(L___^+.X7_#X7*_O__@&,,_L<#`````,=#!`````#I//___XM5 +XM[,=$)`@`````QT0D!`4```")%"3H4#___^D+____BU7LQT0D"`````#'1"0$ +XM!0```(D4).@P/___Z3S___^-="8`C;PG`````%6)Y5=64X/L'(M%"(MU%(N` +XMF````(7VB47D=#:+#?P@"0B+%0@A"0B+?1#K!HUV`(/'`0^^!X7`>#0YR'TP +XM]D2"-@(/A+T!``"#[@&-="8`==Z+5>2+30R+0AR)072+0B2)07B#Q!PQP%M> +XM7UW#A?9TX(E]$,=%\`````#K+8GV/!9T6(7;>!8['?P@"0B)]GT,H0@A"0CV +XM1)@V`G57@T40`8-%\`&#[@%T2HM5$(M-#`^V`O:!@@````(/OMAUP(#[_P^$ +XMN@```(M-"`^VPXM1$("\`E,'```2=:B#_@%VHX-%$`&#[@ `!@T7P`8/N +XM`76VBU7PBT4(Z*#\__^+3>2+422+01R+3?"+!)")2`B+3>2+7?"+01R%VXL$ +XMD(L`B47L#X3!````BT7PB?N+?>R)1>CK(H`[%@^4P(3`=`.#PP$/M@.(!X/' +XM`8-MZ`$/A(D```"#PP&+50SV@H(````"==(/M@,\_W1#BTT(#[;`BU$0@+P" +XM4P<``!(/E,#KNXM5"(M"$("X4@<``/\/A>[^__^)7"0$B10DZ$[^_O^#^!(/ +XMA=G^___I+/___XM5"(M"$("X4@<``/]UAL=$)`3_____B10DZ"'^_O^#^!(/ +XMA6W____I9?___XUV`(M%[(M-\(T$`8E%[(M5[,8"`(M-Y(-!)`&%]@^%&_[_ +XM_^E,_O__A?:)?1#'1?``````#X5:_O__Z=C^__^-=@!5N@$```")Y8/L"(M% +XM"(ET)`2+=0R)'"2+F)@```#'0R0`````Z%;[__^+0QR)1G2+0R2)1GB+'"0Q +XMP(MT)`2)[%W#C;8`````C;PG`````%6)Y8/L&(M%"(EU^(MU%(E]_(M]#(E= +XM](N8F````(GRZ`O[__^+4R2+0QR+!)"+$(M%$(ET)`B)%"2)1"0$Z!&3_O^+ +XM4R2+0QR+!)"+`,8$,`"+4R2+0QR+!)")<`B+0QR#0R0!B4=TBT,DB4=XBUWT +XM,<"+=?B+??R)[%W#C78`58GE5U93@^Q,BWT,B47`BT44B56\BU48B4VXBTT0 +XMBP")1>"+`HM5"(E%\(L)A=*)37UW#BTW`BT$@ +XMBT`(A<")1<@/A&H#``"+7`^''@$``(M#>(MS=(E%\(&+5`@` +XM```!``#I;?___XU-\(E4)`R)3"0(BUW@B5PD!(M%P(D$).@'K?__A<`/A*P! +XM``")P>FJ_/__C4-XB4PD#(E$)`B+0W2)1"0$BT7`B00DZ-NL__^%P`^$@`$` +XM`(E#=.D1_?__@:-4"```__[__XM-S#M+>`^'$`$``(M#>(MS=(E%\(&+5`@` +XM```!``#I8_W__XU-\(E4)`R)3"0(B70D!(M%P(D$).B#K/__A<`/A"@!``") +XMQNDS_O__C5WPB4PD#(E<)`B)="0$BU7`B10DZ%JL__^%P`^$_P```(G&Z93^ +XM__^-0WB)3"0,B40D"(M#=(E$)`2+1<")!"3H+JS__X7`#X33````B4-TZ;3^ +XM__^)1"0,C4-XB40D"(M#=(E$)`2+5<")%"3H`:S__X7`#X2F````B4-TZ;7^ +XM__^!HU0(``#__O__.W-X=V:+0WB+4W2)1?"!BU0(`````0``Z0C]__^-3?") +XM5"0,B4PD"(ET)`2+1<")!"3HL*O__X7`=%F)QNEK_/__C4-XB4PD#(E$)`B+ +XM0W2)1"0$BT7`B00DZ(BK__^%P'0QB4-TZ7UW#QT0D"#RY"`C'1"0$ +XM`P```(D,).AF-O__@\1,N`$```!;7E]=PXU%\(ET)`R)1"0(B50D!(M%P(D$ +XM).C?JO__A*_O^-=@!5B>575E.#[#R+?0B%_W04BU\0A=MT#?:#50@```$/A$P! +XM``#'1>@`````C5WPQT7P`````,=$)`P``@``B5PD",=$)`0`````B3PDZ"^J +XM__^%P`^$D`$``(E%Z(M%&,=%[`````")7"00B40D%(U%Z(E$)`R-1>R)1"0( +XMBT7HB40D!(M5%(GXB10DBTT0BU4,Z!KY__^%P`^%H@```(M%[(7`B47<=&B+ +XM5>B)T0'!.`/@]T````/O@*%P`^(T@```(LU_"`)"#G&#X[$````BQT( +XM(0D(]D2#-@)U(^FR````#[X"A<`/B+`````YQ@^.J````/9$@S8"#X2=```` +XM@\(!.7UW#C70F`(7_=!.+5Q"%TG0,BT)T.T7H#X2O````BT7HB00D +XMZ)*+_O^X`0```(/$/%M>7UW#D(%[>/\!``!V28M#=(E%Z(M#>(E%\(&+5`@` +XM```!``"-7?#IQ?[__SE-X`^$")5"0(BT4,B3PDB40D +XM!.AS]___Z4[___^-0WC'1"0,``(``(E$)`B+0W2)/"2)1"0$Z*"H__^%P'0% +XMB4-TZY"X`0```(GVZ7+___^!HE0(``#__O__,<#I8?___X&B5`@``/_^__^X +XM`0```.E-____C;8`````58GE5U93@^Q,B47(B57$B4W`]H!D`P```0^$D0(` +XM`(G"BX!<`P``C01`P>`"`T(0BT`XA<`/E<"$P`^%A@(``(M%R/:`<`,```$/ +XMA9X"``"+1#'1"0$+P```(M5X(D4).A%AO[_BU7@B57S'1?#_____QT7L_____XE5U(D$).CL +XMA/[_A<`/B-8#``#'1"0$D+X("(M%[(D$).B!A_[_A<")1

7UW# +XMB<*+@&@#``"-!$#!X`(#0A"+0#B)1>#I4OW__\=$)`0!````BT7PB00DZ->! +XM_O^+1>R)!"3H+(7^_XM%\(D$).@AA?[_QP0D`@```.@5A?[_QT0D$`````"+ +XM1=C'1"0(V[D("(E$)`R+5=R)5"0$BT7@B00DZ'R!_O_'1"0,WKD("(M5X,=$ +XM)`0%````B50D"(M%R(D$).A&-?__QP0D?P```.@NAO[_@:-4"```__[__XM5 +XMP(L"`<`[0WAW8(M3=(E5V(M5P(M#>(D"@8M4"`````$``(L"Z9C]__^)5"0, +XMBT7`B40D"(M5V(E4)`2+1*3__X7`#X1*`0``BU7`B478BP+I9OW_ +XM_XD4).C_AO[_B<;I%?W__XE$)`R-0WB)1"0(BT-TB40D!(M%R(D$).@WI/__ +XMA<`/A`D!``")0W3I<____\=$)`C5N0@(QT0D!`4```"+5 +XM7UW#QT0D"%;?"`C'1"0$!0```(M%R(D$).@?+___@\1,N`$```!;7E]=P\=$ +XM)`SSN0@(BT7<,?;'1"0$`P```(E$)`B+5@/A)X! +XM``"+1>B)!"3HKX3^_X/$;(GP6UY?7<.0@7YX_P$```^&CP$``(M&=(E%Z(M& +XM>(E%\(&.5`@````!``#I5/___\=$)`@!````QT0D!#0```")'"3H4#;__X7` +XM="V+1>R+5>B#Z`6#P@6)1>R)1"0,B50D"(M5#(D<)(E4)`3H!N[__XG&Z6+_ +XM___'1"0(`0```,=$)`0U````B1PDZ`)1:2#[P4/ME$%A-(/A,(```"%_W4%_P^$\_[_ +XM_X/O`0^$"P$``(U%[(D$)(U-\(G8C57HZ&/X__^%P`^%6?[__XM%[(E$)`R+ +XM1>B)1"0(Z=/^__^!HE0(``#__O__B?"#Q&Q;7E]=PXU&>,=$)`P``@``B40D +XM"(M&=(D<)(E$)`3H=J#__X7`=`B)1G3I1_[__[X!````D(UT)@#I(/[__X7_ +XM#X1G_O__H?P@"0@Q]HL-""$)"(E%K(E-L.L(BT78#[94!@6+1=B-1#`%B47< +XMBT6D*?"#Z`6)1=0/OL*%P'@:.T6L?16+5;#V1((V`G4>]T2"-``%``!U%)") +XM1"0$BTVHB0PDZ,5]_O^%P'4:@\8!.?=UJ.GU_?__BX-T`P``B46HZ5+^__^+ +XM?=3IY/[__XM-W(`Y*@^%Z?[__\8!`(M%Z(/`!8E%M(N3F````(E5S,=$)`0O +XM````B00DZ.Y]_O^%P(G`0``.46T#X2_`0``Q@``BT6TB00DZ)V"_O^) +XM1<"#Q@&)=>"+5>")%"3HB8+^_XM-M(E%N(D,).@[?O[_A<")1<@/A+T!``"+ +XM5`@ND'3; +XM@\`(B470B00DZ#2"_O^)1;R+?;R)V`-]P(U7`NC=Z/__BT7,BU`DBT`?[_Z>K[__^#P`B)1=")!"3H +XM78'^_SE%N(E%O`^'ZO[__XM-N(MUT(M]X/PYR?.F#X76_O__Z0?___^+1<") +XM1"0(BU6TB30DB50D!.@"@/[_`W7`@WW``799Q@8O@\8!Z0;____'1"0(!;H( +XM"+X!````QT0D!`,```")'"3H+2G__^EK^___QT7``0```,=%M`J@"`CI/_[_ +XM_XM-M,=%P`````#'1;1!\0@(B4W@Z2S^__^+3;2`.2]UG^FK_O__QT0D#)^M +XM"`B+1;2^`0```,=$)`0%````B1PDB40D".C;+?__Z0G[__^0D)"0D)!5B>57 +XM5E.#[!R+?0SV1WP!=`X/ME=1@/I`=`6`^BIU&XM%"&:#N*P$````#XGB`0`` +XMBTT(#[:1J````(M="`^VRH&+K`0```"```"(DZ@````[#?P@"0@/C&4!``") +XMT(M="(MS$(N>0`$``(7;=0_I;`$``(L;A=L/A&(!```Z0Q!U\<=$)`2$```` +XMQP0D`0```.@=??[_A<")1?`/A*4!``"+=?"+1?"#QCR)<#R)<$#'1"0$$``` +XM`,<$)`$```#H[WS^_X7`B<(/A+H!``"+1V2)0@CVAX(````(#X56`0``BT=L +XMB4(,BT7P@$A0`8M-\(M!/(ER!(D".W%`#X1^`0``B5`$BT7PC7L(,?:)4#R+ +XM4PPQP#G7=!B-M@````"+0A"+4@2#P`$!QCG7=?&-!#:)!"3H^GW^_XM5\(7` +XMB4(0#X3_````BU7PB4)(B7),Q@0P`(M;##G?="P!QHGVBT,(BU,0B30DB40D +XM!(E4)`CH[GW^_XGP`T,0Q@`*BUL$C7`!.=]UV(M-"(M=\(M1$(M"?(7`B0-T +XM"8M"?(E8!(M1$(M%\(E"?(M5"(M-\(M"$(/`?(E!!(/$'#'`6UY?7<.A""$) +XM"&:#?(@T``^)BO[__P^VA(@T!```Z7_^__^-!$F`P@&-A$98`0``='J)1"0$ +XMQT0D"`````"+50B)%"3HVO$``+@!````@\0<6UY?7<.)!"3'1"0(!0```,=$ +XM)`0`````Z+7Q``"#Q!RX`0```%M>7UW#B4(,BTWP@$E0`NFH_O__QT0D"``` +XM``#'1"0$!0```(M-"(D,).A>)O__N`$```#KHL=$)`3_````BT4(B00DZ#3B +XM_O_I;O___XE10.E]_O__QT0D"`````#'1"0$!0```(M5"(D4).@<)O__N`$` +XM``#I7?___Y"058GE5U93@^P\BWT,BW4(BT=TBP")1>"+0`B%P`^$K@$``(N> +XMF````(M#&(7`=`B)!"3H[7S^_XM5X(L"B00DZ%!V_O^%P(E#&`^$3`(``/:' +XM@@```"!T+HN&K`0``*D```0`=2&H`@^$^`$``(M5X(L"QT0D!-7:"`B)-"2) +XM1"0(Z+H)`@"+1V"%P`^%L@```(M&'(7`=&CV0%@$=&+VAB0!```!#X3@`0`` +XMBX8<`0``C01`P>`"`T80BT`XA<`/E<"$P`^%(@(``/:&8`0```$/A.8!``"+ +XMAE@$``"-!$#!X`(#1A"+0#B%P`^5P(3`=`[VAJX$```$#X3.`0``D#'2,<#V +XMAJP$```1B50D#`^4P(E$)!"+5>"+`HE\)`2)-"2)1"0(Z/6```#WAJP$```" +XM``0`='TQTH/$/(G06UY?7<.+3AR%R0^$NP$``(./@````$"#?V0!#X2A```` +XM,<")1"08BU7@BP*)?"0$B30DB40D%(U%Z(E$)!"-1VR)1"0,C4=DB40D".B! +XM)P``BU7H]H:L!````HE63`^%I````(M%[/>&K`0```(`!`")1E!U@XDT),=$ +XM)`0EN@@(Z,Q4``"#Q#PQTEN)T%Y?7P<"```BU4(BUT,BT(<]D!8!'0Y]D-] +XM`74SBT(@BT`(@#@O="C'1"0(3+H(",=$)`0#````B10DZ)PB__^!Q!P(``"X +XM`0```%M>7UW#BT-XA<`/A:,```#'!"2_N@@(Z'ER_O^%P(F%\/?__P^$HP$` +XM`(N5\/?__XD4).A-`"`T(0BU`XC7(!ZPB`^SIT"X/&`0^V7O^$VW7PC4;^.<)R:X3;="") +XM\NOF@^@!=$SHB'/^_X!Y`2YUJ`^V00(\+W0$A,!UG,=$)`R?K0@(BX7P]___ +XMQT0D!`4```")1"0(BU4(B10DZ*TF__^X`0```('$'`@``%M>7UW#BT-TBP"+ +XM`(F%\/?__^D4____QD;_`(N%\/?__XV]]/?__XE4)`S'1"0(N90(",=$)`0` +XM"```B40D$(D\).CO=?[_B%[_B3PDZ#1Q_O^%P'0R#[9>_^E-____@<0<"``` +XM,7<.0QX:L`````0```.O*C70F`(M5#(M"%(DT),=$ +XM)`0"````B40D".AFNP``@\0PN`$```!;7EW#BT,575KX!````4X/L'(M]"(N'F````(M8$(7;=#>)]HM# +XM$(E$)!"+0PB)="0(@\8!QT0D!%C4"`B)/"2)1"0,Z"M0``"+&X7;==6#Q!PQ +XMP%M>7UW#B3PDQT0D!$#4"`CH"U```(/$'#'`6UY?7<.058GE4X'L-`@``(F% +XMZ/?__XU%](F5Y/?__XF-X/?__\=%[/_____'1?C_____QT7T_____XD$).B( +XMR)!"3H=7#^_X7`#XCY````Z&AV_O^+E>3W__^#^/^) +XM0A`/A+@!``"%P`^%2P$``,=$)`0`````BT7TC9WL]___B00DZ)5O_O_'1"0$ +XM`0```(M%\(D$).B";_[_QT0D!`(```"+1?")!"3H;V_^_XM%^(D$).C$#W__^)5"00BY7D]___BT((QT0D"*S5"`C'1"0$``@` +XM`(D<)(E$)`SHFG+^_\=$)!``````B5PD#,=$)`C;N0@(QT0D!%Z@"`C'!"19 +XMH`@(Z/)N_O_'1"0,Z;D("(E<)`C'1"0$!0```(N%Z/?__XD$).B\(O__QP0D +XM?P```.BD<_[_QT0D"%;?"`C'1"0$!0```(N%Z/?__XD$).B"'?__BT7T@_C_ +XM=`B)!"3H!G+^_XM%^(/X_W0(B00DZ/9Q_O^+1>R#^/]T"(D$).CF3W__^)0AB!Q#0(```QP%M=P\=$ +XM)`C5N0@(QT0D!`4```"+A>CW__^)!"3HK!S__^DE____C;0F`````%6)Y5.) +XMTX/L)(7;BY"8````='V+0QB%P'0(B00DZ()S_O^+0R"%P'0(B00DZ'-S_O^- +XM1?C'1"0(`````(E$)`2+0Q")!"3H^6S^_XL3A=)T!HM#!(E"!(M#!(D0BT,L +XMA +XM7UW#D(UT)@!5B>57B<=64X/L#(D$).BAB70D"(E$)`2)/"3H)FK^_X7`=>.#Q`R)V%M>7UW#,=N#Q`R) +XMV%M>7UW#D(VT)@````!5B>575HG&4XG3@^PDH``(L5(-@("(72=#4QVXN#*-@("(E4)`S'1"0(!0```,=$)`22U`@( +XMB40D$(DT).A(2@``BY,PV`@(@\,0A=)US3'`@\0<6UY?7<.)T.@J____A<") +XMQW0^BT`(B40D#(L'B30DQT0D!&[4"`B)1"0(Z`=*``"+1PR)-"3'1"0$7ND( +XM"(E$)`CH\$D``(/$'#'`6UY?7<.)7"0(QT0D!/#5"`B)-"3HTDD``+@!```` +XMZY*-="8`C;PG`````%6)Y8M%"(M5$%WI$?___Y!5B>575E.![.P,``"+10B+ +XM71"+@)@```")A33S__^+0!"%P`^$8`$``(N--//__\>%///__P````#'A4#S +XM__\`````.0D/A&,!``"%VW0]#[8##[[0A=)X+XLU_"`)"#G6?B6+#0@A"0CK +XM%I"-="8`@\,!#[8##[[0A=)X"SGR?0?V1)$V`G7HA,!U38M%"+JGU`@(Z'?^ +XM__^+A3SS__^%P'0.BX4\\___B00DZ`-O_O^+A4#S__^%P'0.BY5`\___B10D +XMZ.MN_O^X`0```('$[`P``%M>7UW#C5,!B95<\___#[9[`8GY#[[1A=)XG8LU +XM_"`)"#GR?9.+#0@A"0B)C5CS___V1)$V`G2`/'/'A4SS__\`````#X0<`0`` +XMN9W4"`CK$H.%3//__P&#P0$XP@^$`P$```^V40&$TG7F//\/A#$!``"+50@/ +XMML"-!$"-A`!0`0```T(0@\`(BWT(QT0D$)W4"`B)1"0,QT0D"#S6"`C'1"0$ +XM`P```(D\).@<%___Z1#___^+50C'1"0(&-8(",=$)`0#````B10DZ/P6__^X +XM`0```.D@____QT0D!"````#'!"0!````Z-)K_O^%P(F%///__P^$^?[__XN] +XM///__XG&@\8(B7<(B7<,QT0D!"P```#'!"0!````Z)]K_O^%P(F%0//__P^$ +XMEO[__XM'"(N50//__XD"B7($.W<,#X2\!@``BXU`\___B4@$BX5`\___B[T\ +XM\___B4<(B4<0Z1'^__^)^(3`=1_I1_[__P^^PH7`>$0YQHGV?CZ+C5CS___V +XM1($V`G0Q@X5<\___`8N%7//__P^V$(32==+I%/[__XM-",=$)`3_____B0PD +XMZ`72_O_IS?[__X#Z(@^%*`8``(N]7//__P^V5P&$T@^$%@8``(!_`@`/A0P& +XM```/OL*%P'@<.<:)]GX6BXU8\___9H-\@30`>0@/MI2!-`0``(M]"(M'$(N` +XM0`$``(7`=1+IU`4``(UV`(L`A<`/A,<%```Z4!"-=@!U[HM`"(M("(F-7//_ +XM_XMP$(U&(XE$)`3'!"0!````Z'!J_O^%P(F%9//__P^$*@<``(N]9//__XN- +XM9//__XGZ@\$(@\(=B8U@\___B4\(B4\,B5<4#[8#B$<=C48"QD(!((E'&(M' +XM%(N57//__XET)`B#P`*)5"0$B00DZ,-K_O^+1Q3&1`8"`(!/'`&+30B+?0B+ +XM10B+22")C3CS__^+?TR)O43S__^+0%#'A5#S__\`````B85(\___@'D8`'D7 +XMBU4,BY*`````P>H(]]*#X@&)E5#S__^+C33S__^+21"%R8F-+//__P^$E08` +XM`,>%5//__P````"+O2SS__^+E63S__^+C4SS__^+/XF],//__XM"%(N]+//_ +XM_XE,)`C'1"0$K-0("(/``HE$)`R+1R")!"3HRF/^_XM'((D$).CO9O[_ZW^- +XM1>R-E8CS__^-??*)?"0,B40D",=$)`2RU`@(B10DZ,EG_O^#^`(/A#$#``"- +XMC8CS___'1"0$"@```(D,).B*9O[_A<")1>AT`\8``(N5+//__XV]B//__XE\ +XM)!"+30B+0@C'1"0(R-0(",=$)`0#````B0PDB40D#.C:$___BY4L\___C8V( +XM\___BT(8QT0D!``(``")#"2)1"0(Z+ME_O^%P`^%5O___XL=H!0)"(7;#X43 +XM!0``BY4L\___BT(8#[]`#,'H!8/@`83`=`OHB6?^_\<`!0```(N]+//__XM' +XM",=$)`B?K0@(QT0D!`4```")1"0,BT4(B00DZ&<8__^+10@QR8GZZ*OV__^+ +XMC3SS__^%R70.BY4\\___B10DZ$=J_O^+C63S__^+?0B)3"0$B3PDZ"ZL``"X +XM`0```.E"^___@_L"#X09`P``@_\"B?L/CK`"``"#^P,/A?P!``"+5>B%THF5 +XM://__P^$ZP$``(7V#X3C`0``B10DZ)IJ_O^+C2SS__^)A7CS__^+62B+`X7` +XM#X1*!```C76(ZPV#PP2+`X7`#X0X!```B[UL\___B40D#(V%B/O__\=$)`BY +XME`@(QT0D!``$``")?"00B00DZ"-G_O^-E8C[__^)="0$B10DZ-%E_O^%P'6Q +XMBQN)G7#S__^)'"3H'6K^_XN-+//__XF%*//__XM%J#M!%`^%://__P````"+E2CS__^+C7SS +XM___'!"0!````C40*,`.%>//__XE$)`3HYV;^_X7`B<,/A.\#``"-0"B)0Q2+ +XMO2CS__^%_W0RBY4H\___BXUP\___B00DB50D"(E,)`3H86C^_XN]*//__XM# +XM%,8$."^#QP&)O2CS__^+A7SS__^+E2CS__\#4Q2#P`&)1"0(BX5L\___B10D +XMB40D!.@C:/[_BX4H\___`X5\\___B4,8BY6`\___B5,//__XE+)(N]://__XG(@\`!B40D"(D4)(E\)`3HU&?^_XN% +XM8//__XD#BY5D\___BT(,B4,$BXU@\___.TH(#X3I`@``B1B+O63S__^)7PR# +XMA53S__\!BT7L@^@!B47L@\`!#X0V`0``B[TL\___BT<8QT0D!``(``")1"0( +XMC86(\___B00DZ,IB_O^%P`^$#_W__XV5B//__\=$)`0*````B10DZ!QC_O^% +XMP(E%Z`^$C0```(V-B//__[\!````Q@``B4WHC47HQT0D!-'4"`B-7_^)!"3H +XMFF7^_X7`B<8/A&S]__^%VP^%4/W__XDT).@@:/[_B;5L\___B85\\___@\C\__^+A5SS__^)!"3HE6?^_XG&Z3OZ__^)5PSI +XM1?G__XM!&(D$).C[9O[_B<'KD8N5+//__XM%".CU\___BX4P\___A<")A2SS +XM__\/A>KZ__^+E53S__^%T@^$9P$``(N-9//__XM1"(E1$(M]#`^W1WPE``$` +XM`/:'@0````$/A/$!``")1"0(BT4(B50D!(D$).@KM```A<`/A3SW__^+50B+ +XM4A2)50B+BI@```")C33S__^+A33S__^+E33S__^+&#G3B=@/A&\!``"+O63S +XM__^)!XE7!(N%-//__SM`!`^$30$``(N5-//__XN-9//__XL"B4@$BX5D\___ +XMB[TT\___B0>+E63S__^+30B+0A")5"0$B0PDB40D".A1[O__BX50\___A<`/ +XMA-D```"+?0B+4Q"+1R")0@B+4Q"+1TR)0@R+1U"+4Q")0A`QP.F\]O__BXTL +XM\___BT$8B00DZ$%?_O^%P`^5P.GE^O__QX4H\___`````.DI_/__B[5H\___ +XMN-34"`BY"@```/R)Q_.F#X4P_/__Z1?\__^+50C'1"0(`````,=$)`0%```` +XMB10DZ"D.___I'?;__XE:".D1_?__BT4(QT0D"-[4"`C'1"0$!````(D$).@! +XM#O__,<#I*/;__XM]",=$)`@`````QT0D!`4```")/"3HWPW__^F/^O__BT,0 +XMBY4X\___B5`(BT,0BXU$\___B4@,BT,0B[U(\___B7@0,<#IW?7__XEX!.F\ +XM_O__BY4\\___B1J+C3SS__^)VHE9!#M;!'1"BP.+O3SS__^)>`2+C3SS__^+ +XMA33S__^)RXD(B>(D\).C29/[_BU4(B7PD"(ET)`2)%"2)1"0,Z(?>__^Z +XM`0```(7`=2Z+5G@YV@^$QP$``(U#`3G"="R+10C'1"0(`0```(E\)`2)!"3H +XMY=<``+H!````BUWTB="+=?B+??R)[%W#D(M&=(U]E(L$F(LPB7PD!(DT).C] +XM7_[_A<`/A3`"```/MT6<)0#P```]`$````^$/0(``,=$)`0O````B30DZ&%? +XM_O^%P(F%+//__W0,Q@``@\`!B84L\___B30DZ!-D_O_'!"0!````B<.-0#B) +XM1"0$Z"YA_O^%P(G'#X19`@``C4`TB4<(B5\,B5PD"(ET)`2)!"3HNV+^_XM% +XMM(E'%,=$)!`&U0@(BT<(QT0D"+F4"`C'1"0$``@``(E$)`R-A33S__^)!"3H +XMB&#^_XV%-/___XV5-//__XE$)`2)%"3H,%_^_X7`#X2_````BT<(B00DZ#U< +XM_O^%P(E'+`^$Y`$``,=$)`0$````QP0D`@```.B.8/[_A<")PHE'*`^$XP$` +XM`(M'+(D"BXTL\___B?J+10CHB.S__X7`#X7]````BY4H\___BT(0A<")!W0& +XMBT(0B7@$BX4H\___B?J)>!"+A2CS__^#P!")1P2+10CHC.___S'2A<`/A'+^ +XM__^+10B)^C')Z(;N__^Z`0```.E<_O__BT4(NO?4"`CH?_'__[H!````Z47^ +XM__^+M63___^-1@&)!"3H:&'^_X7`B4%+//___O4"`B%P`^$H?W_ +XM_XM%"(E<)`C'1"0$!0```(D$).CA"?__N@$```#I%_W__\=$)`@`````Z6W_ +XM__^+10C'1"0(`````,=$)`0%````B00DZ*\)___I-____XM'+(7`#X0L____ +XMB00DZ*M@_O_'1RP`````Z1C___^)'"3H%U[^_XM'++D!````BY4P\___Q@00 +XM`(M'+`^V$(32="6#P`$PR>L*#[80A-)T%(/``8#Z.G7Q#[80A-)T!8/!`>OL +XM@\$!QT0D!`0```")#"3H)E[^_X7`B<.)1R@/A'O____'1"0$(=4("(M'+(D$ +XM).@67/[_A<`/A(+]__^)`X/#!,=$)`0AU0@(QP0D`````.CU6_[_A575E.#[#R+10B+L)@```#VAC@$```!#X0X`0`` +XM@(XX!````8M5#(M"=(L`BU`(BS"%TGYC#[X&A7'1"0(:-8( +XM",=$)`0#````BT4(B00DZ",(__^X`0```(/$/%M>7UW#A=)TU(72#XX2`@`` +XMBSW\(`D(B?.A""$)"(E]U(E%X(VT)@`````/M@L/OL&%P'@/.T74?0J+?>#V +XM1(#"+#?P@ +XM"0@YR'TFBQ4((0D(ZQ>)]H/#`0^V`X3`=!(/OL"%P'@+.<%^!_9$@C5`=>2) +XM\.B-[?__A<`/A#?___^)7"0(BU4,B50D!(M]"(D\)/]0!(/$/%M>7UW#QP0D +XM$]4(".A15_[_A<")QP^$LO[__XD$).C_7O[_B47%W^_XM]V(E] +XM[,=$)`0?U0@(B1PDZ.);_O^%P'0=@#@`=.>)1"0(BT4,B40D!(M5"(D4).A? +XM^?__Z\^+10B%P'06BWT(BT<0AO__A<")1=@/A3O___^X`0```.D#_O__B40D#(U# +XM>(E$)`B+0W2)1"0$BU4(B10DZ*1Z__^%P'35B4-TZ?+^__\/M@Z)\XUV`.D? +XM_O__@:!4"```__[__^E+_?__D)"0D)"0D)"0D)"058GE@^PXB77XBW4(B5WT +XMBUT,B7W\BT8`/MT-\C5-1C7MDQT0D$`$```")?"0( +XM@^`!]]@APHM%X(E4)`2)-"2)1"0,Z!J1_O^%P'06N`$```"+7?2+=?B+??R) +XM[%W#C70F`(M%X,=$)`P!````B7PD!(DT)(E$)`CHY93^_X7`=57OX#8"`A6B=93B<.# +XM[!R+4!#V1A@!=06_C=@("(7)#X3R````B7PD#(E,)`C'1"0$G]@("(D<).C` +XM-0``BT8(@\8(B77L.?")1?`/A+X```"+5?"+>A"+0@B%_XE%Z`^$AP```#'V +XMZV:-="8`#[;`C01`C80`4`$```-#$(/`"(E$)`2)'"3HX30``(M#$/:`5`@` +XM``1U=\=$)`P!````QT0D"`````#'1"0$`````(D<).AER/[_A@/M@06//]UD\=$)`3_````B1PDZ/.__O_KE,=$ +XM)`0FN@@(B1PDZ'$T``"+1?"+5>R+`#G0B47P#X5"____@\0<6UY?7<,/MD80 +XM//]T$@^VP(T$0(V,0E@!``#I]/[__\=$)`3_````B1PDZ)R__O^)P>G=_O__ +XMD(UT)@!5B>6#["B+50R+10B)7?2)=?B)??R)1>R)5?"+0G2+`(L8#[83@/IC +XM#X2W````=T*`^F(/A.<```"-M"8`````QT0D"`H```"+5?"+0B"+0!")1"0$ +XMBWWLB3PDZ&#.``"X`0```(M=](MU^(M]_(GL7<.`^G-T.8#Z='7$BT`(@_@$ +XM=[RZ8,$("#G`_(G>B=>)P?.F=:J+1>R+7?2+=?B+??R)10B)[%WIPZ$``(UV +XM`(M`"(/X!W>(NA_N"`@YP/R)WHG7B<'SI@^%GK10``BT`(@_@+#X=/____NN78"`@YP/R)WHG7B<'SI@^%.?___XM% +XM[(M=](MU^(M]_(E%"(GL7>DBX___B?:+0`B#^` +XMB=>)P?.F#X7^_O__BU7LBT(0BYA``0``A=L/A"$!```/MD,0@_A_=PKV!(7= +XM%`D(!'5>C4,(.4,(=`R+1>PQR8G:Z#/]__^+5>R+0A#V@%0(```$#X7@```` +XMQT0D#`$```#'1"0(`````,=$)`0`````B10DZ"#&_O^%P'43BWWLBT<0]H!4 +XM"```!`^%J0```(L;A=MUB8M5[(M"$(NP0`$``(7V='6-=@`/MD80@_A_=UWV +XM!(7=%`D(!'13C48(.48(=`R+1>PQR8GRZ*G\__^+?>R+1Q#V@%0(```$=5K' +XM1"0,`0```,=$)`@`````QT0D!`````")/"3HFL7^_X7`=0R+1Q#V@%0(```$ +XM=2J+-H7V=92+5>R+0A"+D"`!``"%TG04BT7LN=;8"`CH1_S__S'`Z?7]__\Q +XMP.GN_?__BY`@`0``A=)UV\=$)`BXV`@(QT0D!`0```"+?>R)/"3H!`'__S'` +XMZ<+]__^0D)"0D)"0D)"0D)"058GE@^PXB5WTBUT,B77XBW4(B7W\BT-XA#' +XM1"0(`````(E\)`0E``$``/?:@^(@@_@!&<#WT(/@!`G0B40D#(DT).A'KO[_ +XMA+0&2) +XM1?B+1?C'1"0$\=@("(D<)(E$)`CH5B\``#'2@\0DB=!;7<.-1?B)1"0$B1PD +XMZ!W,_O^Z`0```(7`=,?KWL=$)`@$````BT`@BP")'"2)1"0$Z"G)``"Z`0`` +XM`.N^D)!5B>6#[!B)7?2+70B)=?B+50R)??R+0QR%P`^$O0```(M">(7`=2G' +XM1"0(`0```(M#3(D<)(E$)`3H4O7^_S'`BUWTBW7XBWW\B>Q=PXUV`(/H`70+ +XMZ%I/_O^-M@````"+0G2+#_____QT7<_____\=%Z/_____'1>3_ +XM____=!.-1>2)!"3H84[^_X7`#XCP!```C47") +XM!"3H0TW^_\=$)`0"````BT7@B00DZ#!-_O^+1>2#^/]T"(D$).B`4/[_BT7H +XM@_C_=`B)!"3H<%#^_XM%W(D$).AE4/[_BT7@B00DZ%I0_O^+10@/MIAP`P`` +XM@^,!#X2/`P``B<*+@&@#``"-!$#!X`(#0A"+0#C'1"0$+P```(D$).B#3O[_ +XMA<"-4`$/A-8$``"$VP^$2@,``(M-"(N!:`,``(T$0,'@`@-!$(M`.,=$)!`` +XM````BTT`"`T(0BT`XQT0D#.FY"`B)1"0(QT0D!`4```"+10B) +XM!"3H$0#__\<$)'\```#H^5#^_Y"-="8`N@$```"#Q$R)T%M>7UW#D(M%Y(/X +XM_W0(B00DZ&1/_O^+1>")!"3H64_^_XM%((/H`8/X`0^&H`(``(M-"(M!'(!( +XM6`CHJTO^_X/X_XG'#X2S`P``A<`/A"8#``"+1>B)!"3H'4_^_X-](`,/A?,# +XM``"+50B+LI@```"-1>R)1"0(BU70B50D!(M-"(D,).CMQ@``AR)1"0(BT8LB40D +XM!(M-"(D,).B.+P``A<`/A'#___^+%:`4"0B%T@^%%`0``(M5T`^_0@S!Z`:# +XMX`&$P`^%WP,``(M5T#'VB10DZ+I0_O_'1"00`0```,=$)`P`````QT0D"`G9 +XM"`B)?"0$BT4(B00DZ`]3``"%P`^$00,``+X!````BU48BP*#^`%V&8E$)`2+ +XM30B)#"3HN<;^_X7`=0:+11B#*`&+50B+0AR`8%CW@WT@`@^$G`$``#'`QT0D +XM$`````")1"0,BT4B#^/]T"(D$).AB3?[_BUW0A=MT+HM-T(D,).C` +XM3_[_BT7@@_C_#X3`_?__B00DZ#Q-_O^#Q$RZ`0```%N)T%Y?7<.+1=R#^/]T +XMU8D$).@=3?[_Z\N-M"8`````QT0D"-6Y"`C'1"0$!0```(M5"(D4).AE^/[_ +XMZ7+____'1"0(SKD(",=$)`0%````BT4(B00DZ$7X_O_I4O___XM-"(N!:`,` +XM`.D2_?__BTT(BX%H`P``Z;W\__^+30B+@6@#``#I=_S__X-](`$/A-````"- +XM1?#'1"04`0```(E$)!"+31")3"0,BT70QT0D!/;8"`B)1"0(BU4(B10DZ*PR +XM``"+30B%P`^5P`^V\(M%\`%!7(-](`(/A7;^__^+51"+"H7)#X7&`0``BTT8 +XMB0&+30BX`0```/:!K`0```(/A5'^___I2O[__\=$)`A6WP@(QT0D!`4```"+ +XM50B)%"3H>O?^_\=%T`````#I@/[__XM%W(D$).CW2_[_QT0D!!KW"`B+1>B) +XM!"3HU$O^_X7`#X7#`0``QP0D`0```.A`3?[_BT7HB00DZ,5+_O^-1?#'1"04 +XM`0```(E$)!"+51")5"0,BTW0QT0D!/;8"`B)3"0(BT4(B00DZ-$Q``"+50B% +XMP`^5P`^V\(M%\`%"7#'`Z:#]___'1"0(UKD("+X!````QT0D!`4```"+10B) +XM!"3HR?;^_XM%Z(D$).A22_[_BT7`"`T(0BU`XZ0C[__^-1?#'1"04`0```(E$)!"+312)3"0, +XMBT70QT0D!/;8"`B)1"0(BU4(B10DZ"PQ``"+30B%P`^5P`^V\(M%\`%!7.F0 +XM_/__A?8/A;S\__^+12"%P`^%L?S__\=$)!`!````BU44B50D#(M-$,=$)`0` +XM````B4PD"(M%"(D$).BJ@?[_AR)5>B+5?`/MD)0J`UT1(M:/(UZ/#G?=#&+,XM###M%$(GQ +XMR)0@B+0PR#P`&)0@R+1>B)6@2)0PR+`XD"BP,Y +XMQW0=B5`$B1.)\^E@____@VL,`8U"_XE#"(GSZ4____^+1?")4$")$^O>BT7P +XMB4@\ZX>+0P2+5?")0D"+"^EN____QT0D"`````#'1"0$!0```(M5"(D4).C0 +XM\_[_@\057B<=64X/L +XM;(E5M(E-L(MP'(7V#X1?`0``]H"N!````@^%(0$``(M-M(M9>(7;#X3I```` +XMBT%TBS7\(`D(BP"+"`^V$0^VVCGS?1NA""$)".L-@\$!#[81#[;:.?-]!_9$ +XMF#8"=>R$T@^$KP```#D=_"`)"`^/CP```(#Z7`^$F@```(#Z?`^$D0```(#Z +XM"@^$B````(U!`8E%S`^V40&$T@^$;@$``(MUS`^VPCG#B?%U*^GR````D(UT +XM)@`/MA:#Q@&($0^V%H/!`832#X1'`0``#[;".<,/A-$```"`^EQUVHU&`8E% +XMT`^V5@$/ML(YPP^$J@```(#Z7`^$EP````^V%HMUT.NZH0@A"0CW1)@T``4` +XM``^$7O___Y#'1"0("@```(MUM(M&((M`$(D\)(E$)`3HD[T``+@!````@\1L +XM6UY?7<.+5;2+0B"+`(D\),=$)`@8V0@(QT0D!`,```")1"0,Z$+R_O^#Q&RX +XM`0```%M>7UW#QT0D"`0```"+0B"+`(D\)(E$)`3H/+T``+@!````ZZ?&`5P/ +XMME8!@\$!@\8"Z1G___^+=N!```0`^$&@,``(M'3(E%Y(M'4(E%Z(U%Y,=$)`P!````B40D +XM",=$)`0G````B3PDZ";B_O^%P'08N`$```#I*O___XMUS(GQ#[;".<-UD>N, +XMQT0D!(0```#'!"0!````Z&I&_O^%P(E%N`^$^0(``(M-N(M%N(/!/(E-O(E( +XM/(E(0(M5M(M"=(GRBP`K$(M`""G0A<")1?!U#+Y+C0@(QT7P`0```(M%\`'` +XMB00DZ)Q'_O^+3;B%P(E!$`^$J`(``(M5N(E"2(M%\(E"3(M-N(G"`U$0B70D +XM!(E$)`B)%"3HFD?^_XMUN,=&1`````"#?;`!&<"#X/R#P`@(1E"+1Q"+4'R% +XMTHD6=`F+0'R)<`2+1Q"+5;B)4'R+1Q"#P'R)0@2+3;2+662+<6PY\XEUQ`^' +XM?P(``,=%P`$```#'1R)5"00B4PD#,=$)`@!````B5PD!(D\).A+N_[_ +XMA<`/A?']__^+=?"-1=3'1=0`````QT78`````,=%X`````")==R-M[````#' +XM1"00!````(E$)`S'1"0(`````(M%[(DT)(E$)`3HP$+^_X7`#X2O_O__@_@! +XM=!6)="0(B40D!(D\).@/5P``Z9O^__^+5;"%T@^$Z_[__^F+_O__B5H,Z=[^ +XM__^)03SIT/[__XV'L````(E$)!2-A\0```")1"00C8?`````QT0D&`(```") +XM1"0,*TW,B4PD"(M5S(D\)(E4)`3H;E<``(7`#X4D_?__QX>L`````0```.GF +XM_/__C8>P````QT0D&`(```")1"04QT0D$`````#'1"0,`````(N'Q````(E4 +XM)`2)/"2)1"0(Z!]7``"%P`^$IOS__^G0_/__QT0D"`````#'1"0$!0```(D\ +XM).A:[O[_N`$```#IXOO__XM%N(L0A=)T!HM`!(E"!(MUN(M&!(D0BT80B00D +XMZ$)%_O^)-"3H.D7^_\=$)`0"````B3PDZ%8S__\QP.FA^___QT0D"`8```#' +XM1"0$`````(D\).@7N0``N`$```#I?_O__XVV`````(V\)P````!5N0$```") +XMY8M%"(M5#%WI'/K__XVV`````(V_`````%6)Y8M5#(M%"%T/MDI]@^$!Z?KY +XM__^0D)"0D)"0D)"058GE@^P8BT4(B5WTB7W\BWT,B77XBW`0BT9\C9Z````` +XMBU`4A=(/A80```"#?1@!&<#WT"4`:`(`B8.`````BT4Q=PS'`QT,(```` +XM`.OHD(UT)@#'1"0$A````,<$)`$```#HT$'^_X7`=$V)PXM&?(7`B0-T!HM& +XM?(E8!(U&?(E>?(E#!.E%____BT44B40D"(M%$(E$)`2+10B)!"3HT%___X7` +XMB4,0#X5%____N`$```#I?O___XM%",=$)`@`````QT0D!`4```")!"3H<.S^ +XM_[@!````Z5G___^-M@````!5B>6![#@$``")5"0$B5WTB=.)=?B)SHE]_(G' +XMB0PDZ*`__O\QTH7`=!:+7?2)T(MU^(M]_(GL7<.-M"8`````Z/]#_O^+50B% +XMT@^$Q@```(M+#(7)#X6[````#[=#"+H"````J!)TPKL"````C47PB40D"(ET +XM)`2)/"3H8-_^_\=$)`0O````B30DB87@^___Z#X^_O^%P`^$!`$``(/[`0^$ +XMP`````^"DP```(/[`G4BBY7@^___QT0D"%C:"`C'1"0$`P```(D\)(E4)`SH +XMC.O^_XM-\+H!````A_O__C47LB70D!(E$)`B)/"3H#=[^_X/[`8G^```` +XM#[__^)="0,QT0D"%S9"`C'1"0$`P```(E$)!")/"3H6NK^_XM=[(7; +XM#X3#_O__A?]T#8M'$(7`=`8[<'20=&*)-"3H2D'^_^FE_O__@_L"==*+A>#[ +XM__^)="0,QT0D"+S9"`C'1"0$`P```(E$)!")/"3H!NK^_^NJBY7@^___B40D +XM#,=$)`B0V0@(QT0D!`,```")5"00B3PDZ-[I_O_K@H&@5`@``/_^___I0?[_ +XM_XVV`````(V\)P````!5B>6![,@```")7?2-G5C___^)=?B)UHE]_(G'C47L +XMB40D&(D<),=$)!0`````QT0D$`````#'1"0,`````,=$)`@`````QT0D!#8` +XM``#H7;<``(DT).@I0?[_B70D"(D<)(E$)`R-1=R)1"0$Z.ZR``")7"0$B3PD +XMZ")/``"+7?2+=?B+??R)[%W#D(UT)@!5N9;:"`B)Y8'LZ`0``(EU^(MU"(E] +XM_(U]E(GZB5WTB?#'1"0$`````,<$)`$```#HF_S__X/X`@^$4@$``(M&$(M` +XM?(M`%(7`#X5B`0``]X:L!`````8``'05,<"+7?2+=?B+??R)[%W#C;8````` +XMQP0DH]H(".BX./[_A<")PP^$50$``(D$).AF0/[_QT0D%`````#'1"00`0`` +XM`(E<)`C'1"0$H]H("(DT)(E$)`SHVOK__X7`#X7(````BT80BT!\BT`4A<`/ +XMA>\```#WAJP$````!@``=8#VAJ@!```!#X3C````BX:@`0``C01`P>`"`T80 +XMBW@XA?\/E<"$P`^$5/___XV=-/___[FKV@@(B=J)\,=$)`0`````QP0D```` +XM`.BF^___A<`/A?P```"YG=H("(G:B?#'1"0$`````,<$)`````#H@?O__X/X +XM`@^%VP```(N%-/___SM%E'4/BX4X____.T68#X3!````NIW:"`B)\.CR_?__ +XMA<`/A*T```"X`0```.G-_O__NI;:"`B)\.C4_?__A_O__B30DZ.=H___ID?[__XDT).C::/__Z03___^+GJ`!``"%VP^5P.DD +XM____QP0DI-H(".A--_[_A<")PP^$C0```(D$).C[/O[_QT0D%`````#'1"00 +XM`0```(E<)`C'1"0$I-H("(DT)(E$)`SH;_G__X7`#X25_O__Z5C___^#^`)T +XM((M&$(M`?(M(%(7)#X07_O__B30DZ%1H__\QP.D*_O__BX4T____.T64=0N+ +XMA3C___\[19ATRKJKV@@(B?#H^_S__X7`=+KI"/___\<$)+^Z"`CHJC;^_X7` +XMB<,/A"K^__^`.``/A"'^__^)1"0,C84T^___QT0D$*O:"`C'1"0(N90(",=$ +XM)`0`!```B00DZ`T[_O^-C33[__^)^HGPQT0D!`$```#'!"0`````Z.OY__^% +XMP'5(C84T^___QT0D$)W:"`B)7"0,QT0D"+F4"`C'1"0$``0``(D$).C!.O[_ +XMC8TT^___B?J)\,=$)`0!````QP0D`````.B?^?__@_@"#X6$_?__C94T^___ +XMB?#H*?S__X7`#X1O_?__Z3+^__^-M@````"-OP````!5B>6#?0P^BT40=`1= +XM,<##B44,7>D7@```C;0F`````%6)Y8/L&(EU^(MU"(E]_#'_B5WTBYZ8```` +XMA=MT4_:&KP0```%U:3'_B30DZ&^C__^%P'52BT,LA)]HDT)&:_`0#H9"L``(7`=8GK +XMA8VT)@````"-O"<`````58GE@^P8QT0D!#P$``")7?2)=?B+=0B)??R+?0S' +XM!"0!````Z,LY_O^%P(G#=&*)AY@```")`XE#!,=`"`````"-0`B)0PPQP(7V +XMQT,0`````'0PBX:8````BT`8AQ=P\=$)`@`````QT0D!`4```")-"3H +XM5^3^_[@!````Z]3'1"0(`````,=$)`0%````B3PDZ#CD_O^X`0```.NUD%6) +XMY5=64X/L3(M%"(M`'(7`#X1Z!0``BW4,BT9D@\`!B40D!(M%"(D$).A1L?[_ +XMA<`/A,P$``"+10B%P'07BTT(BUD0A=MT#?:#50@```$/A.<$``"-1?#'1?`` +XM````QT0D#``!``")1"0(QT0D!`````"+=0B)-"3H4EC__X7`B478#X1"!0`` +XMBTT,]D%\!'0$@T%L`8MU#(M&9(M6;(G'.=")5>`/A!$%```Y1>#'1=0!```` +XM#X*F`0``QT7(`````,=%S`````"-M@````"-1>R-5>B)1"00B50D#,=$)`@` +XM````B7PD!(M-"(D,).CKKO[_A<`/A2X$``"+1>R%P`^$2`$``(M5S#';C50" +XM`HM%"(E5S(7`#X2T`0``BTT(BUD0A=L/A*8!``"+1=@Y0W0/A)H!``"+5R%]HEU +XMQ(EUO'1EBTWH#[X!B`/AG3^__^+=0R+1F2+50B)0DR+30R+<62+66PYWG(6Z3<" +XM``"-M@````"#ZP$YW@^#)@(``(E<)`2+10B)!"3H%K;^_X7`=.*+50B%TG06 +XMBU4(BT(0AR+30@IT(/H`8E!4#M]X,=%U``````/AJ+] +XM___I*?___XM-Z(E$)`B)3"0$BT7R+5>@!1=P!1<@/OG00 +XM_^G(_O__BTWH@#DI#X2E_O__B70D!,<$)-/:"`CH*3/^_\=%T`````"%P'07 +XMBT7R#P@<@!B57_/__ +XMC4-XB50D#(E$)`B+0W2)1"0$BTT(B0PDZ$Q4__^%P`^$/P$``(E#=.E5_O__ +XMB57$QT70`````(M%Q.F0_O__B57$BT7$Z87^__^+3=2%R0^$J````(M%"(7` +XM=!:+50B+0A"%P'0,BTW8.4AT#X0]`0``BW78B30DZ&`V_O^+50R+30B+0FP# +XM06B#P`$K0F2)06B#Q$PQP%M>7UW#QT0D"+3:"`C'1"0$`P```(M5"(D4).@2 +XMW_[_@\1,N`$```!;7E]=PXMU#(U'_XE&;(M&9.DF_?__@7MX_P````^&C``` +XM`(M3=(E5V(M#>(E%\(&+5`@````!``#I)?O__XM5V"E5W(M-W(ET)`2)5"0( +XMB4PD#(MU"(DT).@,K_[_A<`/A##____I#?W__\=$)`@$````BU4,BT(@BP") +XM1"0$BTT(B0PDZ*"I``"#Q$RX`0```%M>7UW#C4@!B4W@B4YLZ>'Z__^X`0`` +XM`.GV_/__C4-XQT0D#``!``")1"0(BT-TB40D!(M%"(D$).C:4O__AR+`8E%\`^V.(GZ@/HC#X2@````@_L!=$Z+ +XM5@3'1"0@"````(E<)!R+0@B)1"08BP*+50B)1"04BP:+0`B)%"3'1"0(```` +XM`,=$)`0`````B40D$(M%\(E$)`SHUC+__XG"Z6[___^+1?"`>`$`=:F)^H#" +XM`0^$A`$``(M-"(M1$(GY#[;!#[:,`E,'``"#^0P/AQ0!``"X`0```-/@J8`2 +XM```/A0T!``"+30R+<73I9?___XM-\`^V40&#^G\/AU#____V!)7=%`D(!`^$ +XM0O___P^V00(/MM"#^G]V%^L?C;8`````#[9!`P^VT(/Z?W<-@\$!]@25W10) +XM"`1UYX3`#X4-____BU8$QT0D(`D```"+3?")7"0?[__XM5"(M"$#'2B["`"```A?8/A&/^__^+10R+2'2+402+0@B)1"04 +XMBP*+5?")1"00BP&+30B+0`B)5"0(B5PD!(D,)(E$)`S_UHG"Z2K^__^+50R+ +XM@@! +XM="/'1"0(6-L(",=$)`0#````B1PDZ&G:_O^X`0```(/$%%M=PXU!9,=$)`P! +XM````B40D"(L"#[8`B1PDB40D!.B^RO[_@\046UW#QT0D"`0```"+02"+`(D< +XM)(E$)`3H/Z4``+@!````Z[20D)"0D)"0D%6)Y8'LB````(E=](M=#(EU^(E] +XM_(M#>,=%D)W:"`B%P'0F@^@!=`CHERO^_XUV`(M#=(L`BP")19")1"0$BT4( +XMB00DZ%=R_O_V0WT!=1J-192)1"0$BT60B00DZ!,M_O^%P`^$D0$``(M%D,=$ +XM)`BD`0``QT0D!`$&``")!"3H4"_^_X7`B<,/B#@!``#'1"0$&O<("(D$).CV +XM+?[_A<")QP^$>P$``(E$)`2+10C'1"0,`````,=$)`B"VP@(B00DZ$DR__^% +XMP`^%X0```(L=H!0)"(7;#X7#````]D<,0`^%R0```(M%",=$)`P!````QT0D +XM"([;"`B)?"0$B00DZ`HR__^%P`^%H@```(L-H!0)"(7)#X48`0``]D<,0`^% +XMB@```(M%",=$)`P"````QT0D")/;"`B)?"0$B00DZ,LQ__^%P'5GBQ6@%`D( +XMA=(/A?0```#V1PQ`=5.+10B)?"0$B00DZ*0&__^%P'5`H:`4"0B%P`^%Z``` +XM`/9'#$!U+8D\).B)+_[_A<`/A.@```#H?"S^_XLPZR.-="8`B3PDZ*PM_O^% +XMP`^$-____^A?+/[_BS")/"3H52_^_^A0+/[_B3"+19#'1"0,GZT(",=$)`0% +XM````B40D"(M%"(D$).@XW?[_N`$```"+7?2+=?B+??R)[%W#BT60QT0D#+#; +XM"`C'1"0$`P```(E$)`B+10B)!"3H!-W^_[@!````Z\KH["O^_XLPB1PDZ'(L +XM_O_KBXD\).@8+?[_A<")]@^%:O___^G;_O__B3PDB?;H_RS^_X7`#X53____ +XMC78`Z?C^__^)/"3HYRS^_X7`D`^%.O___^D(____BT60QT0D#)G;"`C'1"0$ +XM!````(E$)`B+10B)!"3H@]S^_S'`Z4G___^0D)"0D)"0D)"0D)!5B>575E.# +XM[$R+30B+10R+41R%T@^$:`,``(M(;(MP9(E-V(M`5#GPB47<#X.S`0``BUHX +XMQT74`````(7;=0CK/8L;A=MT-X![$">0C70F`'3OBT,(.?!RZ#E%W'+C@&,1 +XM_8E<)`2+50B)%"3H[[7^_\=%U`$```"+&X7;=7UW#.<@/AT7^___'1"0(X-L(",=$ +XM)`0#````BT4(B00DZ%G5_O^#Q$RX`0```%M>7UW#B?.+==R)3>"-="8`@VW@ +XM`8-]X/\/A`P"``"-3>R-1>B)3"00B40D#,=$)`@!````B5PD!(M5"(D4).B] +XMH/[_A4_?__Z<#^__^-0WC'1"0,``$` +XM`(E$)`B+0W2)1"0$BU4(B10DZ(M(__^%P`^$6O[__XE#=.NFQT0D"`0```"+ +XM0""+`(D,)(E$)`3HY9X``+@!````Z3?^__^+1=R+5=PK1*O[_BT4(BU77UW#BU4,@$W@`8M"5,=%Z`````")1>2-1>R) +XM1"00C47DB40D#(U%R,=$)!0!````QT0D"`````")1"0$B3PDZ,<+__^%P'6A +XM`W7L,=LK=<#'1U``````B7=,ZY+'1"0(!````(M5#+L!````BT(@BP")/"2) +XM1"0$Z/Z<``"#Q$R)V%M>7UW#D)"0D%6)Y8/L&(M5"/:"L`(```%T/HN"J`(` +XM`(T$0,'@`@-"$(M(.(7)#Y3`A,!T,L=$)`@,W`@(QT0D!`,```")%"3HB]'^ +XM_[@!````R<.-="8`BX*H`@``A<`/E,"$P'7.QT0D"$C<"`C'1"0$`P```(D4 +XM).A9T?[_N`$```#)PY"058GE@^PHB77XBW4,B7W\BWT(B5WTBT9TBQB+`XD\ +XM)(E$)`3HN&G^_P^W1GR)/"0E``$``(E$)`3HD(VT)@````!5B>53@^PDBUT(BT,_O^%P'00N`$```"#Q"1;7<.0C70F +XM`,=$)`0(````B1PDZ+`\__^%P'757,?]64X/L#(MU#(M% +XM"(`^`(N8F````'1IQT7P`````.LEBX,T!```#[84-XA4#P`&`^@J)@S0$ +XM``!T(H/'`8`\-P!T*8&[-`0````$``!VSXM%"(D$).A/____Z\*#QP''1?`! +XM````@#PW`'77BT7PA6#[#B+ +XM10B)??R)7?2)=?B+L)@```"-11")1?"+GC0$``")1"0,BT4,B40D"+@`!``` +XM*=B)1"0$C40>-(D$).AN(/[_B<>-!!B`?#`S"HF&-`0``'0'/0`"``!V"XM% +XM"(D$).BV_O__B?B+7?2+=?B+??R)[%W#C;0F`````%6)Y5=6B<93@^PLB4W@ +XMBTT,B57D]H`X`@```0^$`0(``(M0$(N`,`(``(T$0(M$@CB%P`^5P(3`=`.` +XMS03VAM`#```!#X3*`0``BX;(`P``C01`BT2".(E%\(M5X('A``0``(L:B4W< +XM@VT(`8-]"/\/A(\!``"+3>0/M@$\"0^$\P```#S_#X2I`0``BU80#[;`C01` +XM`<"-C`)8`0``B4WH#[:4`ET!``")5>R+31"%R74.BWWL`=\[?C@/@IP```"+ +XM5>PQ_X72=7?IGP```)"+11"%P'4'BU7H#[8$%XE$)`C'1"0$BNP("(DT).B. +XM_O__BT80]H!4"```!`^%`P$``,=$)`P!````QT0D"`````#'1"0$`````(DT +XM).A^D?[_AQT+3E>.'6*QT0D +XM!":Z"`@QVXDT).B8_?__Z7/___^+1>B)^XDT)(E$)`3H@OW__X-%Y`'I\?[_ +XM_XM]W(7_#X4*____.UXX<^`QP(D9@\0L6UY?7<.+AL@#``")1?#I./[__XN`,`(``(M6 +XM$(7`#Y7`Z0'^___'1"0$_P```(DT).@;B/[_QT0D!/\```")-"2)1>CH"(K^ +XM_XE%[.E,_O__58GE5U93@^PLBUT(QT7L`````(MU#/:#F`(```$/A($```"+ +XM@Y`"``"-!$#!X`(#0Q"+0#B%P`^5P(3`=#&-3>RZLMP("(G8QT7PLMP(",=$ +XM)`@`````QT0D!`````#'!"0(````Z#7]__^%P'4HC57PC47HB40D$(E4)`S' +XM1"0(`0```(L&B1PDB40D!.@ME_[_AS'1"0$`````(M&!(GYB00DB=CHROS__X7` +XM=;V+5?"+11`#5@2)5?"+2`2+1@2^`0```#G!=`2)SBG&B?F)V,=$)`A>```` +XMQT0D!`````")-"3HB_S__X7`#X5Z____BT,0]H!4"```!`^%:O___\=$)`P! +XM````QT0D"`````#'1"0$`````(D<).CSCO[_A____\=$)`0FN@@(B1PDZ"KZ__\QP.EF____ +XMC78`QT0D"`````"+11B-312)%"0E``0``(E$)`2+50R)V.@,^___A<`/A"G_ +XM__^#Q!2X`0```%M=PXM#$/:`5`@```0/A1K____I3/___XE$)`2-312Z+?`( +XM"(G8QT0D"`````#'!"0!````Z,+Z__^%P`^$,/___^NTD(VT)@````!5B>57 +XM5E.#[#R+=0B+?1B+1AR%P`^$@P$``(M%$(M5%(L8BQ(YTXE5S`^'5P$``(GX +XM)0`"``")1=#IX````(GVQT7HPMP("(M5Z(U-\(GPQT0D"`````#'1"0$```` +XM`,<$)`@```#H1?K__X7`#X4=`0``C47LB40D$(U%Z(E$)`S'1"0(`0```(E< +XM)`2)-"3H.Y3^_X7`#X7S````BU7LA=)U#/?'``0```^$M@```(E\)!"+1?") +XM5"0(B40D#(M%Z(DT)(E$)`3H\OW__X7`#X6Z````BT80]H!4"```!`^%H``` +XM`,=$)`P!````QT0D"`````#'1"0$`````(DT).A*C/[_A +XMB5PD#,=$)`B[W`@(QT0D!`H```")%"3H:1S^_XU%WHE%Z.GA_O__QT0D!":Z +XM"`B)-"3H*OC__XM&$/:`5`@```0/A&#___^#Q#PQP%M>7UW#N`$```"#Q#Q; +XM7E]=P\=$)`@$````BU4,BT(@BP")-"2)1"0$Z(>2``"X`0```.O558GE5E.# +XM[""+70R+=0@/MT-\B5PD!(DT)(E$)!"-0VR)1"0,C4-DB40D".@0_O__N@$` +XM``"%P'4.BT-L,-*)1DR+0W")1E"#Q"")T%M>7<-5B>564X/L((M=#(MU"`^W +XM0WR)7"0$B30D@,P"#[?`B40D$(U#;(E$)`R-0V2)1"0(Z+K]__^Z`0```(7` +XM=0Z+0VPPTHE&3(M#<(E&4(/$((G06UY=PXUV`(V\)P````!5B>564X/L((M= +XM#(MU"`^W0WR)7"0$B30D@,P$#[?`B40D$(U#;(E$)`R-0V2)1"0(Z%K]__^Z +XM`0```(7`=0Z+0VPPTHE&3(M#<(E&4(/$((G06UY=PY"0D)"0D)"0D)!5B>53 +XM@^PTBUT(BTT,BT,575E.#[#R+?0B+1Q")1=2+112+EY@```")5="+ +XM,,=%V`````#'1=P`````QT7@R]P(".G/````C;8`````BUW8NA^%ZU&#PP&) +XMV/?BP>H%:])D.=-U=XM'$/:`5`@```0/A;X```#'1"0,`0```,=$)`@````` +XMQT0D!`````")/"3HUXC^_X7`=1"+1Q#V@%0(```$#X6*````BT4")/"2)1"0$_]+'1>``````BT7P +XMBU70B40D$(M"+(ET)`C'1"0$`0```(D\)(E$)`SH.Y?^_X7`#X7L````BT7P +XM@\8!`47R)1"0(BT4,B3PDB40D!.@IM_[_ +XMBU7R%TG08A?]T#(M'$(7`=`4[6'1T>XD<).AR&O[_,=OK28M%$(D$).B3&/[_ +XMA<`/A%G___^+50R[`0```,=$)`R?K0@(QT0D!`4```")/"2)5"0(Z#/(_O^+ +XM11")!"3H'!K^_XM%'(7`=1R+5=3'1"0(`@```,=$)`0`````B3PD_Y)H"``` +XM@\0\B=A;7E]=PX&@5`@``/_^__\QV^O,C;8`````C;PG`````%6)Y8'LJ``` +XM`(E]_(M]"(E=](M5##';B77XBT<0B85X____BT)XAL +XM!```J`(/A:D"``"+10SV@((````@#X0C`P``BT!TBP28BP#'1"0$(+H("(D\ +XM)(E$)`CHW_'__XD\).CW\/__BX>L!```J!!U"PT```@`B8>L!```J`)T)HN5 +XM>/___\=$)`0!````B3PD_Y*@"```A<`/A2$#``"#CZP$```4BU4,QT0D&`(` +XM``"+0G2+E73___^+!`*+`,=$)`P`````B3PDB40D%(U%Z(E$)!"+10R#P&2) +XM1"0(BT4,B40D!.A#P___A<`/A1,!``"+50PQR8.*@````$"+5>CVAZP$```" +XMB5=,#X2M````QT=0`````(U'4(E$)`B)5"0$B3PDZ-(S__\QR>F,````BX5\ +XM____BU4,B70D"(D\)(E$)`R)5"0$Z&Z1__^%P`^%K@```(M5#(M">(7`>!*# +XM^`$/CB+]__^#^`(/A)\!``"+50S'1"0(`0```(M"=(L`BP")/"2)1"0$Z+R* +XM``"Y`0```.LFD(UT)@#'1"0,GZT("(ET)`C'1"0$!0```(D\).B$Q/[_N0$` +XM``"+7?2)R(MU^(M]_(GL7_S__XM5#(M"9`-%\(E'3.D`____BX=<`P``BY5X____ +XMC01`BT2".(7`#Y7`Z>7[__^+50SV@H(````@#X2!_?__BT)TBP28BP#'1"0$ +XMU=H("(D\)(E$)`CH5J(!`(N'K`0``.E:_?__BU4,BT)TBU`$BT<@BS(/MT`8 +XM)80```"#P(`/A*````")="0$B3PDZ']6_O_INOO__XD<).CV$_[_B?;IS/[_ +XM_XM5#,=$)`@)````BT(@Z1[^___'1"0$);H("(D\).@X[O__Z>3\__^)="0, +XMQT0D"#3="`C'1"0$`P```(D\).B7O?[_Z;#^___'1"0("@```(M"((M`$(D\ +XM)(E$)`3HF(@``+D!````Z?_]__^+50S'1"0(`P```(M"(.FQ_?__BT((B70D +XM!(D\)(E$)`CH>##__X7`B<-T%(M'((M`"(D$).A(%/[_BT<@B5@(BT<@9H%@ +XM&#__BT<@9H-(&`R+5Q#'1"0(`0```(M'((M`"(D\)(E$)`3_DIP(``#IROK_ +XM_\=$)`@`````QT0D!`4```")/"3HXKS^_[D!````Z6G]__^0D)"0D)"0D%6) +XMY5=64X/L+(M]"(M'$(MP$(U0$(E5Y#G6#X39````QT7H`0```,=%[`````#' +XM1?``````ZT&#?>@!=!?'1"0$TM0("(D\).@#[?__QT7P`0```(M&((M`"(D\ +XM)(E$)`3HZNS__XLV.77D#X2O````@T7H`8M'$/:`5`@```0/A8P```#'1"0, +XM`0```,=$)`@`````QT0D!`````")/"3H6X#^_X7`=0R+1Q#V@%0(```$=5R+ +XM1B"+0`B)!"3HT1/^_XM=\`'#`5WLBT7UW#C78`C;PG`````%6)Y5.#[!2+30R+70@/MT%\@^`<@_@, +XM=%>#^!1T,H/X!+H"````="W'1"0("@```(M!((M`$(D<)(E$)`3H+H8``(/$ +XM%+@!````6UW#C78`N@$```")5"0(BT%8B1PDB40D!.A(Z@$`@\046UW#B?8Q +XMTNOAC;8`````C;\`````53'`B>564X/L((M5#(MU"(N:@````(M*>('C``$` +XM`(7)=`>+0G2+`(L`B40D"(U%](E<)`R)1"0$B30DZ-_T`0"Z`0```(7`=18P +XMTH7;=!"+1?2!CJP$````$```B484@\0@B=!;7EW#C;0F`````%6)Y5WIQ^\! +XM`)"0D)"0D)!5B>56B=93BY"`````B0` +XM````BU@(N`$````Y^W1),?;V@Z\$```!=#6+@X````"+2`2X`0```(G*@^$? +XMP>H%T^`)A)58____BX.`````BT`$.?!^"8G&C;0F`````(L;.?MUO(U&`8U5 +XMX(E4)!"-E5C____'1"0,`````,=$)`@`````B50D!(D$).C"!_[_@_C_=!&% +XMP'4U,<"!Q%P!``!;7E]=PXD<),=$)`B*W0@(QT0D!`4```#H8+?^_X'$7`$` +XM`+@!````6UY?7<.+A;S^__^+<`@Y_@^$"O____:&KP0```$/A`H!``"+AH`` +XM``"+2`2)R(/A'\'H!8N$A5C____3Z*@!#X3H````C57PB50D!(DT).CQA/[_ +XMA<`/A<<```"%]@^$V````(M>$(7;#X3-````]H-5"````0^%P````(%[>/\# +XM```/AFX#``"+0W2)A<#^__^+0WB)1>R!BU0(`````0``BYW`_O__BY:````` +XMB=B#P`&)ES'1"0,``0``(E$)`C'1"0$`````(DT).B3*O__ +XMAS'1"0$_P```(DT).C0=?[_@_@(#Y3"@_@,#Y3`Z[['1"0(A-T("+L!```` +XMQT0D!`4```")-"3HU;3^_^ER_O__.=@/AAL!```IV(G:B87$_O__C47HB00D +XMBXW$_O__B?#H6_K__X7`=`N+3>B%R0^$J0```,=%V`````"X(````,=%W*"& +XM`0#'A(74_O__`````(/H`77PBY7(_O__N`$```"+2@2)RH/A'\'J!=/@"825 +XMV/[__XU%V(E$)!"-A=C^___'1"0,`````,=$)`@`````B40D!(N5R/[__XM" +XM!(/``8D$).A9!/[_@^@!=2V+A<3^__^)7"0$B40D"(N5P/[__XD4).CH"?[_ +XMBYW`_O__`YW$_O__Z5W]__^+C<3^__^)VHGPZ/3Z__^%P`^%JOW__XM%\(U0 +XM`8E5\(N5Q/[__XE<)`R)1"0(QT0D!`$```")5"00B30DZ+&&_O^%P'4VBT7P +XMB49,BY7$_O__@^H!@[W$_O__`1G`]]`APHE64,=$)`0!````B30DZ%ZV`0") +XMP^D9_?__NP$```#I#_W__X&@5`@``/_^___I*/W__XU#>,=$)`P`!```B40D +XM"(M#=(DT)(E$)`3HX"?__X7`#X0&_?__B4-TZ63\__]5B>6#[$B)=?B+=0B- +XM1?")7?2)??R)1"0$B30DZ/^`_O^%P'0;NP$```")V(MU^(M=](M]_(GL7<.- +XMM"8`````C47DB40D$(M%\(U]V(E\)`S'1"0(`0```(DT)(E$)`3H>W[^_X7` +XM=;R+3>2-1>"+5=B)!"2)\.AD^/__A$(7; +XM#X3<````]H-5"````0^%SP```(M%Y(/H@#M#>`^'E0$``(M3=(E5T(M#>(E% +XM[(&+5`@````!``"+1>2)1"0(BT78B40D!(M%T(D$).@O"/[_QT7,`0```.L) +XMB?;'1")!"2)\.@%]___AB+1>B+OH`` +XM``")1"0(BT78B40D!(M'!(D$).C``/[_.T7HB<-T9X7;=%;'1"0(A-T(",=$ +XM)`0%````B30DZ/FP_O_I`____X&@5`@``/_^___IW_W__XE$)`R-0WB)1"0( +XMBT-TB30DB40D!.AK)?__A<`/A+C]__^)0W3I0?[__^BZ!/[_QP`%````ZYW' +XM1"0(`0```,=$)`0FN@@(BT<$B00DZ#<`_O^#Z`$/A77___^+?$(7;=%N+5=`Y4W1T4XM%Y`-%Z#M%['=UBT7H,=N)1"0(BT78 +XMB40D!(M%T`-%Y(D$).@E!O[_BT7D`T7HB30DB40D#(M%T(E$)`B+1?")1"0$ +XMZ(&`_O^%P`^5P^DV_O__@:-4"```__[__XM%Y`-%Z#M#>'="BT-TB470BT-X +XMB47L@8M4"`````$``.N+BU70B40D#(U%[(E$)`B)-"2)5"0$Z'`D__^%P`^$ +XMO?S__XE%T.EA____B40D#(U#>(E$)`B+0W2)-"2)1"0$Z$8D__^%P`^$D_S_ +XM_XE#=.N7B?:-O"<`````58GE5U93@>S,!```BU4(BT4,]H*L!````@^$"@(` +XM`(M0>(72=!.)1"0$BTT(B0PDZ&NN__^%P'4?QT0D"`````#'1"0$-````(M% +XM"(D$).@\N/[_A% +XM8/O__ZO="`BX<````+^QW0@(HO@0"0CI@P```,8%]1`)"'3H8`7^_XN55/O_ +XM_\<$)/`0"0B)5"0(B40D!.B6!?[_QT0D!)`!``#'!"3P$`D(Z.($_O_'!"3P +XM$`D(Z,8"_O_'1"0(`````,=$)`0"````QP0D\!`)".BJ`_[_@_C_B<8/A2(! +XM``")'"3H9P+^_P^V!X/'`83`#X3A````Q@7U$`D(<`^V1__'1"0(`````,=$ +XM)`0"````QP0D\!`)"*+Y$`D(Z%T#_O^#^/^)PP^%1O___^B-`?[_@S@"=;'' +XM1"0(7`H)",=$)`0%````BT4(B00DZ&FM_O_K0\=$)`@`W@@(QT0D!`,```") +XM%"3H3ZW^_X'$S`0``+@!````6UY?77UW#BXU@^___#[9!`8/!`8F-8/O__X3` +XM#X5R_O__Z,@`_O_'``(```#I-?___XN-3/O__XE!"(G(@\`4B5D$=!#'1"0$ +XM\!`)"(D$).BJ!/[_BX50^___A`'^_\=$)`@!````QT0D!,?="`C'!"3.W0@(Z%P!_O_'1"0(`0```,=$ +XM)`3-H0@(QP0DUMT(".A``?[_Z`L"_O_'1"0(`````,=$)`1A=``@BXU,^___ +XMBT$(B00DZ`K]_?^+E4S[__^+0@2)!"3H.0#^_\=$)`0`````BXU,^___BT$( +XMB00DZ,#\_?_'1"0$`0```(N53/O__XM""(D$).BG_/W_QT0D!`(```"+C4S[ +XM__^+00B)!"3HCOS]_XN53/O__XM""(D$).C=__W_BTT(]H%P`P```0^$V@$` +XM`(N!:`,``(T$0,'@`@-!$(M8.,=$)`0O````B1PDZ`O^_?^)VH7`=`.-4`&) +XM5"0$QT0D#`````#'1"0(G-X("(D<).@6_/W_QT0D#.FY"`B)7"0(QT0D!`4` +XM``"+50B)%"3HXZ_^_\<$)'\```#HRP#^_\=$)`@`````QT0D!`4```"+50B) +XM%"3HK*K^_[@!````Z6_[__\QP(VU:/___\=$AGP`````@^@!@_C@=?"+30BX +XM`0```,=%Z`4```#'1>P`````BXF`````B8U8^___BTD$BB)5"00QT0D#`````#'1"0(`````(ET)`2+C5C[__^+002#P`&) +XM!"3H6?K]_X/X_P^$Z````(7`#X3#````C85H^___B85$^___B<.+A43[__^) +XM7"0$*=@%``0``(E$)`B+E5C[__^+0@2)!"3HY`'^_X/X_P^$KP$``(7`#X6[ +XM````QT0D".W="`C'1"0$`P```(M-"(D,).BTJ?[_BT4(B00DZ/GO__^X`0`` +XM`.EL^O__QT0D"&.+"`C'1"0$!0```(M%"(D$).B$J?[_Z5O\___'1"0(UKD( +XM",=$)`0%````BU4(B10DZ&2I_O_I._S__XM%"(N8:`,``.DJ_O__QT0D"-S= +XM"`C'1"0$`P```(M-"(D,).@VJ?[_ZX#'1"0(BMT(",=$)`0%````BU4(B10D +XMZ!FI_O_I8/___P'#.9U$^___#X,Q`0``C95H^___C;UI^___B95<^___ZV:- +XM3?")3"0$BT4(B00DZ-!V_O^%P`^%)/___XU'_RN%7/O__XE$)!"+E5S[__^) +XM5"0,BT7PQT0D!`````")1"0(BTT(B0PDZ*=[_O^%P`^%Z_[__XF]7/O__XGX +XM@\EC____BU4(BT(0@+A2!P``_W6MB10DQT0D!/\` +XM``#H!FG^_X/X"`^4PH/X#`^4P.O"QT0D"(3="`C'1"0$!0```(M%"(D$).@- +XMJ/[_Z53^__\YA43[__]S*RN=7/O__XV5:/O__XE<)`B+A5S[__^)%"2)1"0$ +XMZ,+]_?^-C6C[__^-'!DYG43[__\/A,/]__^-1>C'1>@`````QT7LH(8!`(E$ +XM)!#'1"0,`````,=$)`@`````B70D!(N56/O__XM"!(/``8D$).C`]_W_@_C_ +XM#X23````@^@!#X1T_?__C47PB40D!(M%"(D$).A8=?[_A<`/A:S]__\KG43[ +XM__^-E6C[__^)5"0,B5PD$(M%\,=$)`0`````B40D"(M-"(D,).@R>O[_A<`/ +XMA7;]__^+10B)V8V5:/O__^@J[O__A<`/A=KW__^+50B+0A"!BJP$```````! +XM@XA4"```(#'`Z<'W__^-="8`QT0D"(K="`C'1"0$!0```(M-"(D,).C5IO[_ +XMZ1S]__]5B>6#[!B+50R+30B+0GB%P'44QT0D!`(```")#"3H/;/^_S'`R<.+ +XM0B"+0!")1"0(BT)TB0PDB40D!.A@O/[_R87`#Y7`#[;`PY"0D)"0D%6)Y5=6 +XM4X/L/(M]#(M=$(UU[.AM^OW_QP``````QT0D"`````")="0$B3PDZ//V_?^# +XMP`%U-.A)^OW_@S@$B?9TT,=$)`@TW@@(QT0D!`4```"+10B)!"3H(Z;^_[@! +XM````@\0\6UY?7<.+5>R)T(/@?X/X?P^$O0$``(7`#X3^````BWT8A?]T#(/X +XM#8UV``^$H@$```^V`SP@#X2'`0``/`D/A'\!``"-1?"_/-X("(E<)`2)1"0( +XMBU4(B10DZ#R9_O^)!"2)P^AV_?W_B<:+1>R$P'@%OT^-"`B)PKB@X`@(@^)_ +XMZPX]F.$("`^$3P$``(/`"#L0=>Z+0`2#_A2Z/O$("'<%ND^-"`B#_A2)1"08 +XMB?")?"0EF_O__@\,!Z5____^#Q#PQP%M>7UW#B50D#,=$)`A*W@@( +XMQT0D!"@```#'!"1`(0D(Z,+X_?^X0"$)".F1_O__N4^-"`CI9?___X&@5`@` +XM`/_^__^X`0```.G8_?__C;8`````58GE4X/L%(M%"(M8$,=$)`@`````QT0D +XM!#0```")!"3HRZS^_[H!````A<`/A58!``"+50CV@JP$```"#X5.`0``BT48 +XMA<`/A80!``"+112%P'0EBU44B50D!(M-"(D,).@*U/__QT0D!":Z"`B+10B) +XM!"3H]]/__XM5"(D4).B]OW_A<"-4`$/ +XMA+H!``"$VP^$I`$``(M-"(N!:`,``(T$0,'@`@-!$(M`.,=$)!``````BTT0 +XMQT0D"-NY"`B)5"0$B00DB4PD#.@#]/W_BT4(]H!P`P```0^$3@$``(G"BX!H +XM`P``C01`P>`"`T(0BT`XQT0D#.FY"`B)1"0(QT0D!`4```"+10B)!"3HK*?^ +XM_\<$)'\```#HE/C]_\=$)!``````QT0D#`````"+51")1"0$B50D"(M-"(D, +XM).CJ^___B<*#Q!2)T%M=P\=$)`0!````B10D_Y.@"```A\=$)`@"```` +XMBTT,BT$@BP")1"0$BT4(B00DZ$QM``"#Q!2Z`0```%N)T%W#QT0D!":Z"`B+ +XM10B)!"3HC-+__XM%%(7`#X5E_O__Z87^___'1"0(U;D(",=$)`0%````BTT( +XMB0PDZ.&A_O^#Q!2Z`0```%N)T%W#C70F`,=$)`@`````QT0D!`````"+50B) +XM%"3_DUP(``"+30B#B:P$```4BT48A<`/A/S]___I>____XG"BX!H`P``C01` +XMP>`"`T(0BT`XZ4?^__^+30B+@6@#``#IN/[__XM-"(N!:`,``.EC_O__A-MT +XM'(M5"(N":`,``(T$0,'@`@-"$(M`.(G"Z2;^__^+30B+@6@#``")PND6_O__ +XMD(UT)@!5B>564[L!````@>P@!```BW4(QT0D"`````#'1"0$-````(DT).@% +XMJO[_A<`/A:D```#VAG`#```!#X6H````BX9H`P``C9WX^___B1PDB40D#,=$ +XM)`B9W@@(QT0D!``$``#H;/7]_XM&$,=$)`@`````QT0D!`````")-"3_D)P( +XM``"+AJP$``")7"0(QT0D#`````")-"2#\!#!Z`2#X`&)1"00BT4,B40D!.B. +XM_/__BU80QT0D"`$```")PXM&((M`"(DT)(E$)`3_DIP(``"!CJP$``````@` +XM@<0@!```B=A;7EW#BX9H`P``C01`P>`"`T80BT`XZ4?___^058GE5XG'5E.# +XM[%R)5<")3;R+6!R%VP^$$`4``/:`B`,```%U,8N0@`,``(72#Y3`A,!T/<=$ +XM)`B@X0@(QT0D!`0```")/"3HY)_^_S'`@\1<6UY?7<.+@(`#``"-!$#!X`(# +XM1Q"+2#B%R0^4P(3`=WC_````#X9^!```BW-TB77@QR<=%T`````")1;CK,HN'R`,``(T$0,'@ +XM`@-'$(M0.(T$"HG6B46T,=*)R/?VBTVT@T70`2G1.5W0#X2[````BU70BW6X +XM#[8$,CP@#X29````/`D/A:$```#VA]`#```!=:N+E\@#``#KM<=%\`````"- +XM1?#'1"0,``$``(E$)`C'1"0$`````(D\).BZ$O__A<")1=P/A>[^__^#Q%RX +XM`0```%M>7UW#QT74`````(N/@`,``(T<2?:'B`,```&)R'0-C02=``````-' +XM$(M`.(/"`0%%U(E5Z`^V`CP^=-@\/`^%7O[__^O.@T70`8/!`3E=T`^%1?__ +XM_X-]O`$/A.8!``")SBMUU#M-U!G`]]`AQCGQ#X3;`0``A?_'1>``````#X2& +XM`0``BT<0A<")1>`/A'@!``"+5=PY4'0/A&P!``"-!!X[1?`/A[X!```/MH_0 +XM`P``BY?(`P``BUWPK7=R)7"0,BW7"+5>"+0'2)1=R+0GB)1?"!BE0(`````0``Z67^ +XM__^+1=2--`'I)?[__XM5Q#E73`^%M_S__\=%V`$```#IJ_S__XE$)`R-1?") +XM1"0(BU7(E$ +XM)`B+0G2)/"2)1"0$Z/,=$ +XM)`P``0``B40D"(M#=(D\)(E$)`3H.P___X7`#X2$_/__B4-TZ53[__^!H%0( +XM``#__O__N`$```#IE?K__X&@5`@``/_^___I-/[__Y"-M"8`````5;D!```` +XMB>6+10B+50Q=Z1SZ__^-M@````"-OP````!5,"N-192)1"0$B1PDZ!OR_?^%P'48 +XMBU7(BT7$@_H`?$A^/.C%[?W_QP`,````BU4(QT0D#)^M"`B)="0(QT0D!`4` +XM``")%"3HK)[^_[@!````BUWTBW7XBWW\B>Q=PST``!``=[V-=@"#P`&)!"3H +XMZ>_]_X7`B460=&F+59"+1<3&!!``B50D!(E$)`B)'"3H6/']_XD<)(G'Z-[M +XM_?^#__]T+HM5R(G[BT7$P?L?,=HQ^`G"=%KH,>W]_\<`!0```(M%D(D$).@P +XM\/W_Z5S___^+5N?]_XD$ +XM)(G&Z%#N_?^%P(G#=$J)="0,B7PD!(E$)`B+1>R)!"3H4^?]_XE<)`S'1"0( +XMO^$(",=$)`0#````BT7PB00DZ*"7_O^+=?B)70B+??R+7?2)[%WIH.[]_XM% +XM\,=%$`````"+7?3'10P%````BW7XBWW\B44(B>Q=Z6>7_O^-M"8`````58GE +XM5U93@^P\]D4@$<=%V``````/A;P```"+10CV@+0!```!#X55!```BTT(BX&L +XM`0``A<`/E<"+70@/ML")1=CV@_P!```!#X1B!```BX/T`0``C01`P>`"`T,0 +XMBT`XA<`/E<"$P'0$@TW8`HM%"/:`\`$```$/A"`$``")PHN`Z`$``(T$0,'@ +XM`@-"$(M`.(7`#Y7`A,!T/(MU$(7V=#&+'?P@"0B+-0@A"0B+31"+50SK`X/" +XM`0^^`H7`>`PYV'T(9H-\AC0`>`N#Z0&)]G7C@TW8`HM=((/C`HE=T'00BWT( +XM]H>N!```0`^%>@4``(M%((/@"(E%U'00BU4(]H*N!```@`^%?04``(M=%(7; +XM#X01`@``]D4@`0^$6@(``(M-$+@W````A+?0B+7Q"%VW0-]H-5"``` +XM`0^$.`4``(7`QT7P``````^%HP<``,=%X`````"P`;X:````BUW@Q@->QP`H +XM6R`)QT`$77PO7,=`""HH6U['0`PJ77QMXD(UT)@`/OL.)1"0$QP0DS.$(".CQY_W_A@\8!@VT0`71%@T4,`8M]#`^V'X#[('7#QP8H6R`)QT8$77PO7,=&""HH +XM6U['1@PJ77QO]_XM-%(L!Q@0X`(7V="B+70B%VW06BUT(BT,0A7UW#]D4@$`^$/@$``(M% +XM"(7`#X1R`P``BTT(BUD0A=L/A&0#``#V@U4(```!#X57`P``BT40`<`[0W@/ +XMAP\(``"+0W2)1>"+0WB)1?"!BU0(`````0``BT40A<`/A?4$``"+50P/M@+' +XM1=P`````/%Z+=>`/A%H&``"+11"%P'5T#``")]@^V00&)SX/'`3PO#X2_ +XM`P``/#\/A+<#``"-M"8`````#[[#B40D!,<$)-OA"`CHH>7]_X7`=`S&!ER+ +XM10R#Q@$/MAB('H/&`8-M$`$/A)D#``")?0R+30P/MAF`^UQTH(M]#(/'`>NX +XM]D4@!`^$V0$``(/$/+@!````6UY?7<.)PHN`K`$``(T$0,'@`@-"$(M`.(7` +XM#Y7`Z9O[__^+30B+N>@!``"%_P^5P.GF^___BWT(BX?T`0``A<`/E<#IHOO_ +XM_XM%$#'VNP$```"%P`^$:P$``(M5$##;BTT,ZQR0/"H/A.T````\+@^$Y0`` +XM`(/&`8/J`71:@\$!#[8!/%L/A,\```!^V#Q<#X2`````/'YUW(M]"/:'4`(` +XM``$/A.D```"+AT@"``"-!$#!X`(#1Q"+0#B%P`^5P(3`=+2+70@#L^0```"# +XMZ@&[`0```'6FA=L/A)L!``"+70B%VW07BU4(BUH0A=MT#?:#50@```$/A$(% +XM```Q_X7VQT7P``````^%$@8``(G[Z>D!``"#^@$/AE?___^#P0&#Z@$/M@$\ +XM/'0@#XXL`0``/%L/A``$```\?@^$GP,``#P^B?8/A2(!``"#Q@B[`0```(GV +XMZ1[___^+?0CVAU`"```!=#^+AT@"``"-!$#!X`(#1Q"+0#B%P`^4P(3`#X3S +XM_O__@\8"NP$```#IYO[__XM%"(N`2`(``(7`#Y7`Z1O___^+10B+N$@"``"% +XM_P^4P.O(*?N^`0```(E=$(/#`8E]#(M]#(E]X.E$_/__B7PD"(E$)`2+10B) +XM!"3HXOC__X/$/+@!````6UY?7<.)^`6P````B00DZ"KG_?^!IZP$``#__[__ +XMZ6CZ__^)T`7(````B00DZ`SG_?^+30B!H:P$``#__W__Z6+Z__\Y0W@/@C0$ +XM``"+2W2)3>"+0WB)SH/&&HE%\(G(@8M4"`````$``(/``>FW^O__/"H/A-0" +XM```\+@^$S`(``(/&`I"-="8`Z?[]__^+71`Q]H/#`>D^____BT40QT7P```` +XM`,=%X``````!P`^$M/S__XE$)`R-1?")1"0(QT0D!`````"+70B)'"3HQP3_ +XM_X7`B47@#X6+_/__Z2G]__^-M"8`````@/HJ#X07`0``@/HNC70F``^$"@$` +XM`(@3@\,!@VT0`0^$N_[__X-%#`&+10P/MA"`^EL/A.@```!^QH#Z7'1^@/I^ +XM==*+30CV@5`"```!#X0(`0``BX%(`@``C01`P>`"`T$0BT`XA<`/E<"$P`^% +XM+0(``,8#?H/#`>N@D(UT)@"+?0R)PX-M$`&('H/&`8/'`H-M$`$/A6?\__^+ +XM1=R%P'0&Q@8D@\8!*W7@B?.)=1"#PP&^`0```.F"^O__@WT0`0^&<@(``(-% +XM#`&+30R#;1`!#[81@/H\#X0_`P``#X_I`0``@/HJ=`V`^BZ-="8`#X7R`0`` +XMBTT(]H%0`@```0^$L@,``(N!2`(``(T$0,'@`@-!$(M`.(7`#Y7`ZR20BTT( +XM]H%0`@```71#BX%(`@``C01`P>`"`T$0BT`XA<`/E,"$P`^$R_[__\8#7(M- +XM#(/#`0^V$>FZ_O__BT4(BX!(`@``A<`/E<#I_/[__XM%"(N`2`(``(7`#Y3` +XMZ\2+30R+71"+50P/MD09_X/J`3PO#X2)`0``/#\/A($!```\),=%W``````/ +XMA(8"``"+?0P/M@<\+W0(/#\/A=;Z__^#10P!BU4,@VT0`0^V`NG#^O__B40D +XM#(U%\(E$)`C'1"0$`````(M%"(D$).B^`O__A<`/A"C[__^)1>"+=>"#P`&# +XMQAKI-/C__XM]"/:'4`(```$/A#P!``"+AT@"``"-!$#!X`(#1Q"+>#B%_P^4 +XMP.FT^___QT0D"`````#'1"0$!0```(M-"(D,).B^C?[_BUT4BP.%P`^%'OG_ +XM_^DX^?__BWT(]H=0`@```0^$T````(N'2`(``(T$0,'@`@-'$(M`.(7`#Y3` +XMA,`/A!#[__^#Q@&[`0```.D#^___BTT(BY'@````BX'D````B1PDB50D!(E$ +XM)`CH]>/]_XM%"`.8Y````.E._?__@/I;#X0@_O__@/I^#X3]````@/H^#X3< +XM````Q@-"#10P!@VT0`8/&`>F0^?__ +XM@:!4"```__[__^FG^/__@VT0`75DBWT,#[8'QT7<`````.E>^?__Q@-<@\,! +XMZ=?\__^+10B+@$@"``"%P`^4P.DT____BT4(BX!(`@``A<`/E,#I@?K__SMS +XM>`^'6`$``(M#>(M[=(E%\(&+5`@````!``#IKOK__XM-$`^V!!'I"?[__XE$ +XM)`R-0WB)1"0(BT-TB40D!(M5"(D4).C\`/__A<`/A&;Y__^)0W3IG_O__\<# +XM6ULZ/F;'0P0Z7<9#!EV#PP?I/_S__XM%"/:`4`(```$/A+D```")PHN`2`(` +XM`(T$0,'@`@-"$(M(.(7)#Y7`A,`/A6;\__^+10B+D.````")P>F,_O__QP-; +XM6SH\9L=#!#I=QD,&78/#!^GF^___@VT0`0^$N0```,=%W`$```#I9/W__XU% +XM\(ET)`R)1"0(QT0D!`````"+30B)#"3H1P#__X7`B<%N/[__P````#'A;S^__\`````QX7`_O__`````,>% +XMQ/[__P````"#Y@&)C93^__^#Z`D\:793BY6@_O__NP$```#'1"0("@```(M" +XM((M`$(D\)(E$)`3H/E4``('$?`$``(G86UY?7<.+AWP!``"-!$#!X`(#1Q"+ +XM6#B%VP^4P.E$____D(UT)@`/ML#_)(6TX@@(A?8/A2`5``#VAZX$``!`#X0U +XM%0``BXV4_O__QX7$_O__`0```(E-"(N%$/___X/``8F%$/___P^V`(3`#X5: +XM____BY7$_O__A=(/A*80``#VAZP$```"="&`O_0`````=!B+A;S^__\+A;C^ +XM__\+A<#^__\/A2T2``"+C:#^___'1?``````BX6@_O__BTEDB8T,____BT!L +XM.<&)A:3^__\/A_\4``"+1Q#V@%0(```$#X7O%```BY6\_O__BXW`_O__"Y6X +XM_O__QX70_O__`````,>%U/[__P`````)RL>%V/[__P````#'A0C___\````` +XMQX4$____`````(F5F/[__\=$)`P!````QT0D"`````#'1"0$`````(D\).CS +XM3/[_A\.``"+C0S___^-1>R-E1#___^)1"00B50D +XM#,=$)`@!````B4PD!(D\).@T5/[_A<`/A7,%``"`O_0`````=&:+A=C^__^% +XMP`^$BA(``#';A?\/A'H/``"+7Q"%VP^$;P\``(N5V/[__SE3=`^$8`\``(M5 +XM[#M5\`^'PQ```(E4)`B+A1#___^+E=C^__^)1"0$B10DZ+W>_?^+C=C^__^) +XMC1#___^+1>R[`0```#'VQX6P_O__`````,>%R/[__P$```#'A%&/___P````#' +XMA1S___\`````B8T@____BTT(B40D$(N%L/[__P.%$/___\>%)/___P````") +XM5"0,QT0D"`H```")1"0$B0PDZ.C:_?^#^`$/A$$#``"%P`^%%!4``(.-S/[_ +XM_P&%VP^%!`(``(N%&/___PN%'/___P^%\@$``(N%(/___PN%)/___P^%X`$` +XM`(N%K/[__X7`#X1M#P``BYT`____@\,!.YT(____=DF!^P`!``")V',%N``! +XM```!A0C___^+A03___^%P`^$O!0``(N%"/___XN5!/___XE$)`2)%"3H>MC] +XM_X7`#X1`$0``B84$____BX6P_O__`X40____BXT`____BY4$____#[8`B`01 +XM@X6P_O__`8.MK/[__P&)G0#___^[`0```,>%T/[__P$```#IK?[__\>%P/[_ +XM_P$```#IM?S__\>%N/[__P$```#IIOS__X"_]0`````/E(?U````Z9/\__^` +XMO_0`````#Y2']````/:'K`0```$/A'C\__^-1=2)1=2)1=CI:OS__X72#X7= +XM^___Z!_:_?_'``````"-A1#___^)1"0$BX40____QT0D"`H```")!"3HR=C] +XM_XG#BX40____@#@`=0F#Z`&)A1#____HWMG]_X,X(@^$5Q$``(N5H/[__XM" +XM;(E"9(/H`0'8B4)LB40D!(D\).@!4_[_AC[__^+C:#^__^#:5P! +XMZ=G[__^+A:#^__^#0%P!ZB+A;#^__\#A2#___^)3=R)3>2)1>"+1>R% +XMP'4.QT7@`````,=%Z`````#VAZP$```"#X1&`@``BU7L.57@<@:-0O^)1>`Y +XM5>AR!HU"_XE%Z(M%Y,=$)`0!````B3PDB4=,BT7HB4=0Z**'`0"%P`^%L0$` +XM`,=$)`@`````C5VXQT0D!`GB"`B)/"3HGWK^_\=$)`@`````B3PDB40D!.B[ +XM:`$`QT0D#`````#'1"0(`````(E<)`2)/"3HGTC^_X7`#X5>`0``BT7`@_@! +XM#X0H`@``<@6#^`1V#(E<)`2)/"3H:$/^_XM'$(.(5`@```3'A=#^__\!```` +XMQX74_O__`0```(7V#X1-"@``BYVL_O__A=L/A)<```"+G0#___\#G:S^__\[ +XMG0C___]V28'[``$``(G8_O__C474QT0D#``(``#'1"0(`````(E$)`2)/"3H)ST``(7` +XM#X4V____BT74BT`(#[8`B$7$#[9%Q#QQ#X3?_?__/'D/A:\)``"+A0S___\Q +XMTHNU&/___XN-"/___XE'3(N%`/___P.%&/___Q.5'/___XEW4(/Z`'P.#X]0 +XM`P``.<@/AT@#``"+E0#___^+A;#^__\#E03___\#A1#___^)="0(B10DB40D +XM!.AS^__\/A&,#```\7`^$$P,```^VM>S^__^)\8#Y +XM_P^$O@(```^VT8M'$`^VA`)3!P``@_@(#Y3"@_@,#Y3`A,!U"(32#X2H`@`` +XMBX?L````.X?P````#X0D!0``BX?P````BY?H````BXT`____B0R"@\`!B8?P +XM````BYT`____@\,!.9T(____OW__X.]^/[__P(/A.L"```/AS(#``"#O?C^__\! +XM#X3B`@``Z+;/_?^+C?3^__^^7````+I<````AS^__\/AHT"``"#A?#^__\!Z:7\___VAU`"```! +XM#X2*`0``BX=(`@``C01`P>`"`T<0BW`XA?8/E<"$P(V5&/___P^$<_S__XL: +XMBW($B=@A\(/``0^$8?S__XM*#(M2"(G0(C^__^+E>C^__^)\(@" +XM@\(!.YV<_O__B97H_O__#X0O_/__@X7D_O__`8N%Y/[__P^V,(GR@,(!#X4> +XM____BT<0@+A2!P``_P^%#O___\=$)`3_````B3PDZ/@\_O_I^?[__XN?2`(` +XM`(7;#Y7`Z7W^___'A;C^__\`````QX6\_O__`````,>%P/[__P````#I6O+_ +XM_X.]^/[__P,/A($"``"#O?C^__\$#X7/_?__B?(/ML([!?P@"0@/C>7^__^+ +XM%0@A"0CV1((U$`^$U/[__P^VM((T"```Z_[_BX?H````A<`/A8+Z__^[`0```,>'[`````````#I +XM-?C__P^VP/\DA5SD"`C'A?C^__\`````B?(/ML([!?P@"0@/C6?Z__^+%0@A +XM"0AF@WR"-``/B57Z__\/MK2"-`0``.E(^O__BX4(____B00DZ%O1_?_I@?K_ +XM_X.]^/[__P,/A"L"``"#O?C^__\$#X7!_/__B?$/ML$[!?P@"0@/C0KZ__^+ +XM%0@A"0CV1((U$`^$^?G__P^VM((T"```Z>SY__\IE0#___^)T,>'\``````` +XM``"+E0#___^+C0S___\#A03___^)/"2)5"0,B40D"(E,)`3HP4K^_X7`#X50 +XM]___BX4,____.4=8=`>#1V`!B4=8BX68_O__A@`````A<")5=R)5>0/A2,(``"+A;S^__^%P`^%Z`<``(NUP/[_ +XM_X7V="B+E:#^__^-1=R)1"0,C47DQT0D$``0``")1"0(B50D!(D\).BUL/__ +XMBYW4_O__@X4,____`87;#X0E`0``@+_T`````'4SBX6H_O__.4=,=0N+E;3^ +XM__\Y5U!T'8U'4(E$)`B+1TS'1U``````B3PDB40D!.A4[?[_BXW0_O__A%^/[__P````#I??W__\>%^/[_ +XM_P````#I1/S__\=$)`@$````BT(@NP$```"+`(D\)(E$)`3H1D0``.D#[___ +XMBXT(____B0PDZ(?/_?_I=/S__\>%P/[__P````#'A;C^__\`````QX6\_O__ +XM`````/9%#`(/A%#O___IGN[__X&C5`@``/_^__^+1>PY0W@/@JX!``"+2W2) +XMC=C^__^+0WB)1?"!BU0(`````0``BU7LZ77P___'A?C^__\`````Z=/]__^+ +XMC0S___\YC:3^__\/@LG^__^+1Q#V@%0(```$#X26[___Z;3^__^-="8`BX4` +XM____,=(#A2#___\3E23___^+C0C___^#^@!\27\$.0(``,>%T/[__P$```#I?//__XVV`````,=$)`3_````B3PDZ&`X_O^#^`@/ +XME,*#^`P/E,#IEO;__P^VM((T!```Z9+Z__^-1?")1"0(BX78_O__B50D#(D\ +XM)(E$)`3H]>O^_X7`#X3M\?__BU7LB878_O__Z0KO___'1"0(;.(("+L!```` +XMQT0D!`,```")/"3H(G?^_^G_[/__B40D#(U#>(E$)`B+0W2)/"2)1"0$Z*/K +XM_O^%P`^$F_'__XE#=.DH_O__@X7P_O__`<>%^/[__P````#I@_7__XN%[/[_ +XM_X.%\/[__P'!X`2-E"@8_/__Z3GY__^#A?#^__\!]H=0`@```0^$WP$``(N' +XM2`(``(T$0,'@`@-'$(M0.(72#Y3`Z?OX__^#A?#^__\!QX7X_O__`P```.DA +XM]?__@X7P_O__`<>%^/[__P0```#I"_7__X.%\/[__P''A?C^__\!````Z?7T +XM__^#A?#^__\!QX7X_O__`@```.G?]/__@:!4"```__[__^E8\___QT0D""'B +XM"`B[`0```,=$)`0#````B3PDZ`UV_O_I!//__\'@`HD$).AQS/W_Z7?Z__]\ +XM##T``0``D`^#8/?__[@``0``D(UT)@#I4??__X7_#X3+````BU\0A=L/A,`` +XM``#V@U4(```!#X6S````BT7L.4-X#X)G!```BT-TB878_O__BT-XB47P@8M4 +XM"`````$``(M5[.E9[?__QT0D"`````"[`0```,=$)`0%````B3PDZ'%U_O_I +XM3NO__XN5"/___XD4).C2R_W_Z?OV___'1"0(`````,=$)`0%````B3PDZ$%U +XM_O_I,_+__XN%R/[__X7`#X1Y_?__BX6L_O__,=N%P`^%C>[__X.-S/[__P+' +XMAS'1?``````A=(/A,'L__^-1?")5"0,B40D",=$ +XM)`0`````B3PDZ'OI_O^%P`^%AOW__^EN[___BX=(`@``A<`/E,#I*/?__\=$ +XM)`@TX@@(NP$```#'1"0$`P```(D\).BA=/[_Z7[J___'1"0(!@```+L!```` +XMQT0D!`````")/"3HGS\``.E%T/[__P````#' +XMA=C^__\`````QX4$____`````.E=^O__BX4`____*97\_O__QX?P```````` +XM`"G0B86P_O__B="+E?S^__^+C0S___\#A=S^__^)/"2)5"0,B40D"(E,)`3H +XM-T3^_X7`#X7&\/__BXT,____C47LC940____B40D$(E4)`S'1"0(`0```(E, +XM)`2)/"3H5#_^_X7`#X63\/__,=N%_P^$S0$``(M?$(7;#X3"`0``BX78_O__ +XM.4-T#X2S`0``BU7L.U7P#X>R`@``B50D"(N%$/___XN5V/[__XE$)`2)%"3H +XM],G]_XN-V/[__XN%"/___SF%L/[__XM=[(F-$/___W9,BX6P_O__/0`!``!S +XM!;@``0```84(____BX7<_O__A<`/A$`"``"+C0C___^+A=S^__^)3"0$B00D +XMZ)G$_?^%P`^$7_W__XF%!/___XN5L/[__XN%$/___XN-!/___RN=L/[__XE4 +XM)`B)1"0$B9VL_O__B0PDZ%W)_?^+AP$``(N5L/[__S';O@$```")E0#____I\.O__XN-N/[__PF-O/[__XN% +XMO/[__PN%P/[__P^%^OC__XN5H/[__S';@XJ`````0.E+[___BU4(NP$```") +XM1"0$B3PDB50D".@7VO__Z2[O__^+C0C___^)#"3HF,C]_^E)Z___C47`^".P$``(M3=(F5V/[__XM#>(E%\(&+5`@````!``"+5>SI +XM(O[__XN-"/___XD,).CTQ_W_Z;;M__]\#ST``0``C70F``^#*/G__[@``0`` +XMD(UT)@#I&?G__XN%"/___XD$).C!Q_W_Z3+Y__^)1"0,C4-XB40D"(M#=(D\ +XM)(E$)`3HSN7^_X7`#X3&Z___B4-TZ6_[__^+E;#^__\QV[X!````@XW,_O__ +XM`L>%R/[__P````")E:S^__^)E0#____I7NK__\=$)`CBX0@(NP$```#'1"0$ +XM`P```(D\).C2O__XM5[(F%V/[__^D;_?__BXT( +XM____B0PDZ.W&_?_I`O'__XE$)`R-0WB)1"0(BT-TB3PDB40D!.CZY/[_A<`/ +XMA/+J__^)0W3IF_[__XN-L/[__XN%!/___XF-`/___XF%W/[__XN5W/[__\>% +XMT/[__P$```")E03____I]>O__XVT)@````!5B>6#["B)7?2+70B)=?B+=0R) +XM??R+D\````"%T@^$E0```/:#K@0``$"-N[````!T/HM&>#')AQ=Z;;D__^-M@````"+1G2+`(L(Z]*-M"8` +XM````QT0D&`(```")?"04QT0D$`````#'1"0,`````(N#Q````(E4)`2)'"2) +XM1"0(Z`[8__^%P'2,BUWTN`$```"+=?B+??R)[%W#QT0D"`8```#'1"0$```` +XM`(D<).A@.@``Z]2-M"8`````C;PG`````%6)Y8/L*(E=](M="(EU^(MU#(E] +XM_(N3V````(72#X25````]H.N!```@(V[R````'0^BT9X,7UW#@\`!.3W\(`D(B47!Y``` +XM``````"+5=2)V8E4)`2+10@%L````(D$)(M5#(M%".C[X/__@\1,6UY?7<.) +XMSBMUW,=$)!@"````BT4(!;````")1"04BT4(!<0```")1"00BT4(B70D"`7` +XM````B40D#(M%W(E$)`2+50B)%"3H3-3__X7`=`JX`0```.G-_?__QT0D&`@` +XM``"+10@%R````(E$)!2+10@%W````(E$)!"+10B)="0(!=@```")1"0,BTW< +XMB4PD!(M%"(D$).C\T___A"K`````$```#'1=0!````Z7O^__^# +XMPP'I\?[__XM%"(7`#X0L`@``BU4(BW(0A?8/A!X"``#VAE4(```!#X41`@`` +XMBU70.59X#X(G`P``BT9TB478BT9XB47P@8Y4"`````$``(MUV,=%X``````/ +XMMA.$TG0P#[[".?@/A","``"`^EP/A*4```"`^GX/A/<```"#PP&(%H/&`8-% +XMX`$/MA.$TG70A?\/A/8!``"+1>"+30B%P(F!Y````'1$BX'@````A`"`T$0 +XMBT`XA<`/E<"$P`^$V/[__XM5"(/#`8N"X````(N2Y````(DT)(E$)`2)5"0( +XMZ!O`_?^+50B+@N0````!1>`!QNE__O__!;````#'1"08`@```(E$)!3'1"00 +XM`````,=$)`P`````BTT(BX'$````B50D!(D,)(E$)`CHRM'__X7`#X17_/__ +XMZ77]__^+10B+@$@"``"%P`^5P.EI____@\,!B`!#[83 +XM@\,!Z=7]__\/ME,!C4L!A-)T2@^^PCGX#X7;^___C4L"BS,``+@!````Z8#Z__^+30B+D4@"``"%T@^4P.EC +XM_O__A?]TO8G+Z1G\__^!H%0(``#__O__Z0K\___'1"0(`````,=$)`0%```` +XMB0PDZ`QH_O^+10B%P'02BU4(BT(0A=G,/MA.`^@ET:X#Z(+C_____=&%;7E]=PSGR +XM"(NX +XMF````#G:=2#K18M"!(E!!(M"!#G8=":)"(D4).C,O?W_BU8(.=IT)XL*.=EU +XMW(M"!(E&#(M"!(L*.=AUVHE."(D4).BEO?W_BU8(.=IUV8L6A=)T#SGZ=!V+ +XM1@2)0@2+1@2)$(DT).B!O?W_@\0,,53B=.#[`2+$HN(F````(72="N+0P2)0@2+0P2)$(M#"(D$).@YO?W_ +XMB1PDZ#&]_?^#Q`0QP%M=PY"-="8`BT,$B4$,BQ/KT8VV`````%6)Y593@^P0 +XMBW4(BYZ8````BP,YV'0@B40D!(DT).CM_O__BP,YV'7NBU,(A=)T#HGPZ'G_ +XM__^+4PB%TG7RBT,4AR+4`B% +XMTG7NC7L!B5WPZTV-M@````")="0(BU7PB00DB50D!.CQN_W_BT,(Q@0P`,9# +XM$`#'`P````"+5>R+0@R)0P2+0@R)&(E:#`^V3_^$R0^$EP```(E]\(/'`0^V +XM3_^$R70A#[[1A=)X[CL5_"`)"'WFH0@A"0CV1)`V`G3:C;8`````C7?_*W7P +XM@_X!=K['!"04````Z$V[_?^%P(G#=%6-1@&)!"3H/+O]_X7`B4,(#X5=____ +XMQT0D"`````#'1"0$!0```(M%"(D$).BB9/[_BT,(A<`/A3?___^)'"3HH[O] +XM_[@!````ZP(QP(/$'%M>7UW#QT0D"`````#'1"0$!0```(M5"(D4).AC9/[_ +XM@\0B+1?")7"0(B4PD!(D$).@"NOW_BU7PBTWP@\(( +XMB57LB5$(B5$,QT$0`````(M%Z(MP%(7V=`B)R(/`'8E!%(M5Z(MR"(/""(E5 +XMW#G6=2_IN````(M-[(D+BU7PBT(,B4,$.TH(#X2-````B1B+3?")60R+-CMU +XMW`^$C@```(M>%+\L````A=MT!HM^&(/'+8M.((7)=`B+1B2#P`$!QXD\).@_ +XMN?W_A<")PP^$$@$``(E\)`B)="0$B00DZ%6Y_?^+5A2%TG0&C4,HB4,4BT8@ +XMA2+1?")$(M"!(M-\(E!!#L2#X3&````BU7DBTWP +XMBT($B0B+1>2+5?")4`2+3>B+1>"+"3G!B4WH#X6*_O__BU7@BW((A?9U6^FY +XM````C;0F`````(L&B0.+1@2)0P2+1@B)0PB+1@R)0PR+1A")0Q"+1@B)!"3H +XM;;+]_X7`B4,(#X2@````QP,`````BU7DBT(,B4,$BT(,B1B)6@R+-H7V=&/' +XM!"04````Z"FX_?^%P(G#=9^+30S'1"0(`````,=$)`0%````B0PDZ)1A_O^X +XM`0```(/$+%M>7UW#B0KI/O___XM5#,=$)`@`````QT0D!`4```")%"3H96'^ +XM_[@!````Z\^+3>"+012%P'02B00DZ-"Q_?^+5>2%P(E"%'23,<#KK[`!ZZN- +XM=@"-O"<`````58GE5U93@^PLBT4(BX"8````B47HBS@YQP^$-P(``(M%"(-X +XM."(/A@4"``"+0!#'1>P!````]H!4"```!`^%"0(``,=$)`P!````QT0D"``` +XM``#'1"0$`````(M%"(D$).CZ)/[_A@/A,8!``"+=PB-5PB)5>0YU@^$@`$``(GPZV.0C70F`(U$`^:)1"00QT0D +XM#!H```#'1"0(&@```,=$)`0.YP@(BU4(B10DZ'61__\Y=Q`/A)0````Y=P@/ +XMA*<```#'1"0$)KH("(M%"(D$).A0D?__BS8[=>0/A!P!``"+1P@YQ@^$\@`` +XM`,=$)`2WW`@(BT4(B00DZ">1__^+1@B%P`^$S````(M8"(D<).C%M_W_@_@> +XM#X=H____B5PD$,=$)`P>````QT0D"!X```#'1"0$&^<("(M%"(D$).CAD/__ +XM.7<0#X5L____QT0D!.#A"`B+50B)%"3HQ9#__SEW"`^%6?___XM?%(7;#X1. +XM____BT4(BT`XB47P@^@>@_@8#X8Y____B1PDZ$BW_?^YMMP("#MW$(G"=`6Y +XMM=P("(E<)!"+1?"#Z",YT'8"B=")1"0,B4PD",=$)`3PF`@(BU4(B10DZ%B0 +XM___I\/[__XUV`(M>%.DO____BT7LQT0D!`GG"`B)1"0(BU4(B10DZ"Z0___I +XM`O___XM5"(L_BT(0]H!4"```!'4D@T7L`>D2_O__QT0D"/+F"`C'1"0$`P`` +XM`(M%"(D$).CD7O[_@\0L, +XM7UW#BU,(BT,,B4(0BT,0BU,(B4(4BT8@9H-(&`''1"0,(````,=$)`@````` +XMBT,(B30DB40D!.BM#/[_A$``0``7>GM_O__B1PDQT0D"`````#'1"0$`0```.@U +XM^?__@\04N`$```!;7<.-=@"-O"<`````58GE5U93@^PLBT4(B[B8````BQ(7`=1V+10P/MTA\BT4(@>$``0``Z(7^__^#Q"Q;7E]= +XMPX/H`70%Z->N_?^+072+`(L`QT0D"`H```")1=R-1?")1"0$BT7+5>`/A9+^__\QP.F@_O__D(UT)@!5B>564X/L$(MU +XM#(M="(M&"(7`='(QTCE#('0@QT0D"!$```"+11")'"2)1"0$Z(T%_O^%P'0. +XMN@$```"#Q!")T%M>77<.+1A2)'"2)1"0$ +XMZ#H(_O^%P(E&"`^%=/___^N4C;8`````C;PG`````%6)Y8/L.(E]_(M]#(EU +XM^(MU"(E=](M'"(7`#X0``0``C47PB40D"(ET)`2+1A")!"3H>IW^_X7`=!:X +XM`0```(M=](MU^(M]_(GL7<.-="8`BT7PQT0D"`````")-"2)1"0$Z!F1`0"% +XMP`^%T0```(M'"#M&(`^$]0```(M5$(E$)`2+1?#'1"0(`````(E4)`R)!"3H +XM!PG^_X7`=52+1PB+7?"+0`C'1"0$`````(DT)(E$)`CH1A#__XE#)(E#*(M% +XM\(&@K`0``/_^__^+1?"!B*P$``"`````BT7P@8ZL!````!```(E&%#'`Z4[_ +XM__^+1?#'1"0$`````(D$).@IO[_A<`/A88```"+@ZP```"%P'0OBU7LC4-0 +XMQT-0`````(E$)`B)'"2)4TR)5"0$Z*S,_O\QP(M=](MU^(M]_(GL7R)1"0$Z/DE_O^%P'6IBT4(QT0D!``` +XM``")'"2)1"0(Z#[T__^X`0```.NMC;0F`````,=$)`0H````B30DZ&2K_?^% +XMP'0R*?#'1"08A````,=$)!0`````B40D$(ET)`R)?"0(B7PD!(D<).B2I?[_ +XMA<`/A#3___^+10C'1"0$`@```(D<)(E$)`CHT_/__[@!````Z3____^)]HV\ +XM)P````!5B>6#[!B)??R+?0B)7?2)=?B+AY@```"+&#G##X24````BT,0BW`$ +XMC4,(.<9T:(M5#`^W0GR)="0$B3PD)0`!``")1"0(Z/7[__^Z`0```(7`=1SV +XM0QP!B7,0=".)="0(B5PD!(D\).@S-___,=*0BUWTB="+=?B+??R)[%W#D(M# +XM%(M6((M.)(D$)(GXZ`W^__\QTNO9QT0D"(#F"`C'1"0$`P```(D\).AA5_[_ +XMN@$```#KNL=$)`@`````QT0D!`$```")/"3H\O+__S'2ZYZ-M"8`````C;PG +XM`````%6)Y8/L&(E]_(M]"(E=](EU^(N'F````(L8.<,/A)0```"+0Q"+,(U# +XM"#G&=&F+50P/MT)\B70D!(D\)"4``0``B40D".@6^___N@$```"%P'4=]D,< +XM`8ES$'0DB70D"(E<)`2)/"3H5#;__S'2B?:+7?2)T(MU^(M]_(GL7<.0BT,4 +XMBU8@BTXDB00DB?CH+?W__S'2Z]G'1"0(K.8(",=$)`0#````B3PDZ(%6_O^Z +XM`0```.NZQT0D"`````#'1"0$`0```(D\).@2\O__N@$```#KFXUT)@"-O"<` +XM````58GE5U93@>R<#```BT4(BU4,BX"8````B86(\___BT)XA<`/A5,#``"+ +XME8CS__^+C[__^) +XM1"0,QT0D"$/G"`C'1"0$``0``(E4)!")'"3HRJG]_\=$)`20O@@(B1PDZ.JD +XM_?^-C>CW__^)C7SS__^%P(F%I//__P^$QP```(N%I//__XV5Z/?__\=$)`0` +XM!```B10DB40D".C@IOW_A<`/A)$```"-C>CW__^+`8/!!(V0__[^_O?0(<*! +XMXH"`@(!TZ??"@(```'4&P>H0@\$"`-*#V0,KC7SS__^-0?^`O`7H]___"@^% +XMUP@``,:$!>CW__\`#[:%Z/?__X3`=#.+#?P@"0B-E>CW__^+'0@A"0@/OL"% +XMP'@/.%G//__P````"`>A@`#XE0!```BU4,]H*!`````0^%4PD``(M5#`^W +XM0GS'A9SS__\!````)0`!``")1"0(BXV0\___BT$(B40D!(M%"(D$).BS]___ +XMA<`/A4,$``"+E8CS__^+&CG3B=@/A#P*``"+M9#S__^)!HE6!(N%B//__SM` +XM!`^$&@H``(N5B//__XN-D//__XL"B4@$BX60\___B[6(\___B0:+E9#S__^+ +XMM9#S__^+0A"+2"2+4""+1A2)!"2+10CHG?G__XN%G//__X7`#X1D"```BTT( +XMBU,0BT$@B4((BU,0BT%,B4(,BU,0BT%0B4(0@<2<#```,`"`T80BU@XA=L/E<"$P`^%M_S__XNUB//_ +XM_XM%"(MV%(FUV//__XN`F````(F%L//__XDT).A%JOW_QP0D`0```(G#C4`A +XMB40D!.A@I_W_A<")A8#S__\/A(X'``")A9#S__^+E9#S__^#P`B)ACW__^)="0$ +XMBX7`\___B00DZ/>I_?^%P`^%N`(``,=$)!0`````QT0D&`````"+E<#S___' +XM1"0,`@```,=$)`@#````B50D$(N%&/C__\<$)`````")1"0$Z"^E_?^)A=3S +XM__^#P`$/A&D"``"+A=3S__\#A1CX__^+G=3S__^)PBN5U//__XF%X//__XG0 +XMP>@?`=#1^`'#.9W@\___=Q7K'8VT)@`````[G>#S__\/A#8*```/M@.#PP$\ +XM"G7J.9W@\___#X0@"@``B[W4\___B[7@\___BX78\___B?&)VNA3Z?__@^@! +XM#X3@`0``B=Z)\BGZB=#!Z!\!T-'XC1PX.=YW".L0B?8Y\W0.#[8#@\,!/`IU +XM\CG>=;PYO>#S__]V.HN-X//__XGZBX78\___Z`/I__^#^/]T(H7`#X3*`0`` +XM.[W@\___#QP$\"G3&.[W@\___=>Z+A1CX__^)1"0$B[74\___B30D +XMZ&BB_?^%P`^%=@0``(N5P//__XD4).C2I/W_A<`/A4`$``"+E=SS__^`8A#\ +XMBX7<\___BP"%P(F%W//__P^%'/[__XN5@//__XM""#F%S//__P^$,0<``(NU +XM@//__XE&$.G<^___BXV(\___BT$4A7UW#B=_I&_[__^CR +XMHOW_BXW<\___BP")00R+M<#S__^)-"3H::/]_XNUW//__X!.$`''A:SS__\! +XM````Z9#^__^%_P^$2/[__SN]X//__XE]Z',A@#\*=!R)^.L%@#@*="&#P`$[ +XMA>#S__^)1>AU[>D<_O__.[W@\___#X00_O__B?B`.`H/A07^___&``"+5>B) +XM?>B_`0```(F5T//__XU-Z,=$)`31U`@(C5__B0PDZ&NC_?^%P(G&=!^%VW4+ +XMB;6\\___@\B%_W0:A?9T%HD\ +XM).C.I?W_A<")A<3S__\/A0$!``"-=?")="0(BX78\___B40D!(M5"(D4).A@ +XM0?[_B47HC47LB40D"(N-W//__XM!"(E$)`2+=0B)-"3H/D'^_XE$)!")PXM% +XMZ,=$)`AIYP@(QT0D!`,```")-"2)1"0,Z)E-_O^+5?"%TG0>A?9T#XM6$(72 +XM=`B+0G0[1>AT5XM%Z(D$).B(I/W_BT7LAF-_O__B30DZ/VD_?^)M;3S__^)A@/H?W_BXW<\___BP") +XM00SI)O[__XN-O//__XE,)`2+M=CS__^)-"3H1Z']_X7`#X5O_/__BX6T\___ +XM@#@O=!J-E>C[__^)5"0$B00DZ"*@_?^%P`^%20$``#'VBY7(\___BXW$\___ +XMQP0D`0```(U$"C`!\(E$)`3HAJ']_X7`B<,/A!S\__^-0"B%]HE#%`^%N@$` +XM`(N%R//__XGR`U,4@\`!B40D"(N-M//__XD4)(E,)`3H^J+]_XN5R//__XT$ +XM%HE#&`-#%(/``8E#((N-Q//__XG*B4LD@\(!B50D"(E\)`2)!"3HQZ+]_XNU +XMS//__XDSBY6`\___BT(,B4,$.W((#X2<`0``B1B+C8#S__^)60SII_[__\=$ +XM)`B0E`@(QT0D!`4```"+30B)#"3HVTO^_^F@^___QT0D"(7G"`C'1"0$!0`` +XM`(M%"(D$).B[2_[_Z6K[__^+M:3S__^)-"3H[)_]_X/X"G7MZ1GW__^+@=0# +XM``"-!$#!X`(#01"+<#CIY_O__XM%"(M`%(E%"(N0F````(F5B//__^GR]___ +XMQT0D!"\```"+C=SS__^+00B)!"3H2)[]_X7`B<8/A)3^___&``"+A;3S__^- +XMG>CS__^)1"00BY7<\___BT((QT0D"+F4"`C'1"0$``0``(D<)(E$)`SHMI_] +XM_XV-Z/O__\8&+XE,)`2)'"3H89[]_X7`#X4__O__B[7<\___BW8(B;6X\___ +XMB30DZ**B_?^)QNDC_O__C;0F`````('$G`P``+@!````6UY?7<.)="0(BY6X +XM\___B00DB50D!.A.H?W_BT,4Q@0P+X/&`>DA_O__BT,0B[6,\___B7`(BT,0 +XMBY64\___B5`,BT,0BXV8\___B4@0@<2<#```,_O__BTT, +XM#[=!?,>%G//__P`````E``$``.GK^O__#[9"`8UR`<8"`(3`=2+I[?7__XUT +XM)@`YP7X<]D2#-4!T%8/&`0^V!H3`#X30]?__#[[`A_?^%P(G< +XM^O__C5@(B5X(B5X,QT0D!"P```#'!"0!````Z%*>_?^%P(G'#X0<^O__BT8( +XMB5\$B0<[7@P/A%T"``")>`2)?@B)?A#I,/7__XEP!.GO]?__B1Z)VHE>!#M; +XM!`^$)`(``(L#B7`$BXV(\___B?.)\(DQZ9[U___'1"0,4^<("(N%H//__\=$ +XM)`0#````B40D"(M5"(D4).CR3?[_B30DZ.Z?_?^X`0```.G+^?__QT0D#%/G +XM"`B+C=CS___'1"0$`P```(E,)`B+=0B)-"3HNTW^_XN%K//__X7`=%6+A;#S +XM__^+6`B%VW4*ZT:)]HL;A=MT/@^V0Q"#X`.#Z`%U[NA]G/W_BU,,B1#'1"0, +XMGZT("(M#",=$)`0%````B40D"(M5"(D4).AB3?[_@$L0`NN\BXV`\___B0PD +XMZ%*?_?^X`0```.DO^?__#[9"`8UZ`<8"`(3`#X3;\___#[[`A<`/B$0!``"+ +XM#?P@"0@YP0^.&`$``(L=""$)".L9@\")^NL2#[9"`8/"`83`#X2'\___#[[`A;V1(,U0'3? +XMQ@(`@+WH]___``^$9?/__X`^``^$7//__X`_``^$4_/__XDT).@&E_W_A<`/ +XMCD/S__^)/"3H1I_]_XDT)(G#Z#R?_?_'!"0!````C40#+HE$)`3H6)S]_X7` +XMB<,/A(K\__^-0"B)0Q2)?"0$B00DZ%R?_?^)/"3H!)_]_XE#&`-#%(/``8E# +XM((ET)`2)!"3H/)_]_XN%J//__XD#BY6$\___BT(,B4,$BXVH\___.TH(=$>) +XM&(NUA//__XE>#.G]\?__B7,$Z=G]__^+'0@A"0CI!?___XE^#.F>_?__B[W4 +XM\___Z27V__^+#?P@"0B+'0@A"0CIX?[__XE:".NVC;8`````C;PG`````%6) +XMY8M%#(&(@`````````B)10Q=Z4?P__^-M"8`````58GE@>S(````B77XBW4, +XMC47LB5WTC9U8____B7W\BWT(B40D&,=$)!0`````QT0D$`````#'1"0,```` +XM`,=$)`@`````QT0D!#H```")'"3H*Q0``(DT).CWG?W_B70D"(D<)(E$)`R- +XM1=R)1"0$Z+P/``")7"0$B3PDZ,#O__^%P'41BX>L!```@.3^#(")AZP$``"+ +XM7?0QP(MU^(M]_(GL7<.0D)"0D)"0D)"0D)!5B>6#[!B)7?2+70B)=?B)QHE] +XM_(G7]\,``$``#X6.````]\,``!``=!CVAI@"```!=4V+AI`"``"%P`^5P(3` +XM=5F#XQ!T&HM'"(E$)`B+1QS'!"3RF`@(B40D!.CSF?W_H00A"0B+7?2+=?B+ +XM??R)10B)[%WI^I?]_XVV`````(N&D`(``(T$0,'@`@-&$(M0.(72#Y7`A,!T +XMIXM'%,<$)+O<"`B)1"0$Z*:9_?_KDHD,).A575E.! +XM[,P```"+?0R+=12+'SG[=!`Y.P^$%0(``(D\).AHS?W_QT0D#"````#'1"0( +XM`````,=$)`0`````BT4(B00DZ,7._?^%P(G##X0K`0``BP>)>P2)`SE_!`^$ +XM,@,``(L'B5@$B1^+50B+0DR#P`&)0Q2+2A")C53____V@50(```0#X2B```` +XM@^;OB?&)\(/A0"4``@``QX5<____`````(F-4/___XF%3/___XU5V,=$)`P` +XM````QT0D"`````")5"0$BTT(B0PDZ'L(_O^%P`^%HP```(-]X`L/AJL```"- +XM1=@Q]HE$)`2+50B)%"3H10/^_XL3.?H/A+$```"+0P2)0@2+0P0Y^`^$LP`` +XM`(D0B1PDZ$#,_?^!Q,P```")\%M>7UW#C78`]\80````=#")7"00QT0D#``` +XM``#'1"0(`````(M5"(M"3(D4)(E$)`3H$HX``(7`=1Z!S@!```")-"2+31") +XMVHM%".C(_?__Z13___^-=@"^`0```('$S````(GP6UY?7<.+1>#_)(6,YP@( +XMBT,(@'P"_RX/A1D!``"+$S'V.?H/A4____^+0P2)1P2+0P2+$SGX#X5-____ +XMB1?I2/___[X!````Z2'___^+0Q"#P`$[0PQWBX50____A0[%?P@"0A]&J$((0D(]D20-0)T#H/Y"G0)@_D/#X66_O__BT,0#[95 +XMY(M+"(@4`8/``8E#$.E^_O__@WL,'P^&X?W__\=#$`````#I(?[__Y"-="8` +XM_R2-O.<("(E$)`R-0PR)1"0(BT,(B40D!(M-"(D,).A,M_[_A<`/A`3___^) +XM0PCI8?____9%[`(/A%_____WQB`````/A04!``#WQ@`(```/A84$``#WQ@`0 +XM``"-="8`=!&+0QR+4Q"#P`$YP@^$V?[__\=$)`P@````QT0D"`````#'1"0$ +XM`````(M%"(D$).@JS/W_A<")A5C___\/A(S^__^+0Q2+E5C___^#P`'WQA`` +XM``")0A1T1X.]7/___P(/A,@"``"+A5C___^)1"00BT,0B5PD",=$)`0````` +XMB40D#(M5"(D4).@PC```A<`/A3C^___'A5S___\`````B30DBTT0BT4(BY58 +XM____Z-K[__^+C5C___^).8M'!(E!!#D_#X2K`@``BT<$BY58____B1"+C5C_ +XM__^)RXE/!.D<_?__B5\$Z2+E43___^( +XM`HM#",9``0"AH!0)"(7`#X7=`P``BQ4$(0D(BT((@^@!A<")0@@/B.(#``"+ +XM`C'VQ@`*@\`!B0+I2OS__XM#$#M#'`^'"_W___?&$`````^$__S__\>%7/__ +XM_P$```#I\/S___?&$`````^$JOO__XM+$(7)B4V`#X2<^___@[U<____`0^$ +XM'`$```^#!`$``(M%@#M#'`^'??O__XM5"/:"T`,```$/A/,"``"+@L@#``"- +XM!$#!X`(#0A"+0#B)A7#___^+10CV@(@#```!#X2W`@``B<*+@(`#``"-!$#! +XMX`(#0A"+0#B)A73___^+0P@QTL=%D`````")A7S____K%XUT)@"#P@`! +XMBT6`.460#X2)`0``BTV0BX5\____@#P!"77>BXUP____B=`!T3'2][5P____ +XMB8U(____*=&)RNO#B50D$(M%N,=$)`0`````B40D#(U%G(E$)`B+30B)#"3H +XM:XD``(7`#X5S^___BT6DB00DZ!R6_?_'A5S___\`````Z2O]__^)#^E9_?__ +XM@[U<____`P^$U0```.B4D/W_BT,<@\`!.46`#X=D^O__BU,E?W_BT,%7/___P````#KCHM3"#'VBT,0Q@0"`.GD^?__ +XM@^H!B95(____B=`QTO>U=/___S'`BXU(____QX5H____`````"G1.8UP____ +XMB4V,=S.+A7#___^)18CK`XE-B(M%B#'2][5P____BTV(`XUP____@X5H____ +XM`2G1.4V,<]N+18B+58PIPHF5;/___P.5:/___XG0B95X____@\`!.T,,#X>' +XM````BY5X____QT,0`````(E3'(N%:/___X7`=!F+0Q"+4PC&!`()@\`!B4,0 +XM@ZUH____`77GBX5L____A<`/A-K^__^+0Q"+4PC&!`(@@\`!B4,0@ZUL____ +XM`77GZ;S^__^+30B+B8`#``")C73____I3_W__XM-"(N)R`,``(F-$:#R("(0UC'0S0!````B7PD!(DT).BK%_[_AR)1DR+1?")1E`QP.L%N`$```"+7?2+=?B+??R)[%W#BT,T@_@! +XM=+]S"8UT)@#H;XW]_X/X`G7&B7PD!(DT).C:$O[_A53@^P4BUT(QT0D!!#H"`B)'"3H]FO__XD<),=$)`1( +XMZ`@(Z.9K__^)'"3'1"0$@.@(".C6:___B1PDQT0D!,#H"`CHQFO__XD<),=$ +XM)`0?Z0@(Z+9K__^#Q!0QP%M=PXVT)@````"-O"<`````58GE5U93@^Q,BU4, +XMBT)XA<`/A0@!``"+'<#,"`B%VP^$\````(M5"+O`S`@(C77CBT(0]H!4"``` +XM!`^%U0```,=$)`P!````QT0D"`````#'1"0$`````(M%"(D$).CM_OW_A!0[%?P@"0A]#*$((0D(BY20-`@``(A5Y`^V`3'2QD7F78A% +XMY0^V1`H!B$0R!(/"`83`=?")\HM#%(/#&(E4)`S'1"0(#````,=$)`24U`@( +XMB40D$(M%"(D$).@T:___BP.%P'03BU4(BT(0]H!4"```!`^$*____X/$3#'` +XM6UY?7<.#Z`%T!>BKB_W_BT)TBP")1D( +XM"(E$)`B+10B)!"3HGFG__X/$3#'`6UY?7<.-="8`58GE5U93@^PC;0F`````(N&!`0``(7`=(NX8`L)".N&@^@!=`7H28G]_XM"=(L` +XM@W@(`70GQT0D"`H```"+0B"+0!")-"2)1"0$Z)`"``"#Q!RX`0```%M>7UW# +XMBP`/MA@/MM.#^GY_=X/Z6W1J@_I==&6`^WX/A)$```")T,'@!`4`_`@(BW@( +XMA?]T4XM(#`^^$872>!D[%?P@"0A]$:$((0D(NT^-"`CV1)`V`G4%N]+4"`B) +XM?"00B4PD#(E<)`C'1"0$:^D("(DT).C^9___,<#I`O___P^V0`$YT'23C012 +XM@,,!C81!6`$``'1&B30DB40D",=$)`3\Z`@(Z,QG__^#Q!PQP%M>7UW#]H8, +XM!````70MBX8$!```C01`BT2!.(7`#X11____N&`+"0CI4?___XE4)`2)-"3H +XM;O+]_^NLBX8$!```A(M1=(/``8E!>,<$@@````!;7<.-M@`` +XM``"-OP````!5B>564X/L$(M="(MS$,=$)`0!````B1PD_Y:@"```N@$```"% +XMP'0)@\00B=!;7EW#QT0D"`````#'1"0$`````(D<)/^67`@``/:#(`(```%T +XM4(N#&`(``(T$0,'@`@-#$/:#8`$```&+0#B)0S1T1(N#6`$``(T$0,'@`@-# +XM$(M`.(E#.(N#K`0``#'2@^#]@\@%B8.L!```@\00B=!;7EW#BX,8`@``]H-@ +XM`0```8E#-'6\BX-8`0``Z\:-=@!5B>53@^P4BT4,BUT(AGQ,_[_QT40\.H(",=%#`,```")30C) +XMZ=HS_O_'11`4ZP@(QT4,`P```(E-",GIPS/^_XE4)`S'1"0(/.L(",=$)`0# +XM````B0PDZ*EP,_[_58GE5S'_5E.#[!R+10B+=0R+@)@```") +XM1?#H58?]_\<``````(M5\(M:+(/",(E5[(M5\(M",#G'<@^-5P$YT')3BT7P +XMB?L#6"RAH!0)"(7`=6Z+1@2#Z`&%P(E&!`^(W0```(L&#[80@\`!B0:#^O]T +XM78/Z"@^$U````(@3BU7P@\(/]_^GP_O__B30DZ&N)_?^)PND>____BU40 +XM,<").H/$'%M>7UW#D%6)Y8/L&(E=](M=#(EU^(MU"(E]_(M](,=$)`B$```` +XMC1Q;C1S=P,P(",=$)`0`````B30DZ'J%_?^)7B"+11")1F"+112)1F2+11C' +XM1G`!````QT9H`0```(E&;(M%'(7`=`9F@4Y\``&%_\=&>`````")?G1T!L<' +XM`````(M=](MU^(M]_(GL7<.0D)"0D%6)Y8/L&(M%",=$)`CXZP@(QT0D!`0` +XM``")!"3H7S'^_S'`R<.0D)"0D)"0D)"0D%6)Y5=64X'L+`$``(M="(M]#/:# +XML`(```$/A)$```"+@Z@"``"-!$#!X`(#0Q"+4#B%T@^4P(3`#X6%````BU=D +XMA=(/A*<```")4TP/MT]\B<@E8@@``(/X(`^$X`````^/D0```(/X`@^%G``` +XM`(/A!+Y>````#X71````C78`B70D$(VU\/[__XE4)`S'1"0(ANP(",=$)`0` +XM`0``B30DZ$Z%_?_IT````)"-="8`BX.H`@``A<`/E,"$P`^$>____\=$)`A` +XM[`@(QT0D!`,```")'"3H=3#^_[@!````@<0L`0``6UY?7<.0C70F`+(!Z5+_ +XM__^#^$`/A!4!```]``@```^$<@$``(M#((E0$(M#(,=`%`````"-0U")1"0( +XMBT-,B1PDB40D!.COH_[_BT,@9H-(&`'IH@```(GVOBT```"#X00/A#+___^+ +XM1UB)="00C;7P_O__B50D#,=$)`A\[`@(B40D%,=$)`0``0``B30DZ'F$_?_' +XM1"00#````(E$)`R)="0(QT0D!`````")'"3HU?#]_P^W1WPE`!8``#T``@`` +XM#X2A````/0`$``!U*L=$)!`!````QT0D#`````#'1"0(`````,=$)`0:```` +XMB1PDZ`)"_O^)]HN#K`0``*@0=0L-```(`(F#K`0``*D```(`=22#X/J#R`*) +XM@ZP$``"!Q"P!```QP%M>7UW#OBX```#I)O___Y"+0QR#0PP!@P`!C47PB5WP +XMB00DZ"CG``"%P'1+@<0L`0``N`$```!;7E]=PXUT)@#'1"00`0```,=$)`P` +XM````QT0D"`````#'1"0$(@```(D<).AH0?[_Z6/___^^*P```.F^_O__B1PD +XMC;8`````Z)OX__^%P'6CQT0D!":Z"`B)'"3H)U___S'`Z3#^__]5B>575E.! +XM[)P```"+10B+?1"+0!")A7#___^+112+,(M%&(L`B85X____BT4/___X7`#X1S`@``.[5X____#X=G`@``QX5T +XM____`````,>%?/___P````#'18"-[`@(ZSR0C70F`(M'"(/H`87`B4<(#X@9 +XM`@``BP?&``J#P`&)!X.%=/___P&#Q@$YM7C___\/@H0"``")G7S___^+G7S_ +XM__^Z'X7K48/#`8G8]^+!Z@5KTF0YTP^%@P```(M5"(M"$/:`5`@```0/A>T` +XM``#'1"0,`0```,=$)`@`````QT0D!`````")%"3HQO']_X7`=1.+50B+0A#V +XM@%0(```$#X6V````BT4DA%?/___P`` +XM``")/"3H4W[]_X7`#X7Z_O__Z4/___^+10S'1"0,GZT(",=$)`0%````B10D +XMB40D".BC,/[_Z>'^__^+#:`4"0B%R75##[]'#HD$).@L?/W_A<`/A;/^___I +XM-?___XF=?/___XD\).CQ??W_A<`/A9C^___IX?[__XD\).A<@?W_B<+IY/[_ +XM_XD\).A-@?W_Z[>-M"8`````58GE5XG75E.#[#R)1=B)3=2+!T5HM'=(L`BQ@/M@.$P'0U +XM#[[`A2#?=0"=0V`.R$/A+P```"-="8`@W]D`0^&7`(``(M%X(7`D'0; +XM@WW4`W0)@#L^#X2O`0``BT7@A7UW#B1PDZ`*"_?^+5=B)7"0(B7PD +XM!(D4)(E$)`SHM_O^_X7`#X4,`@``BT=XA!K`0` +XM``(`!``/A:#^___'1"0$);H("(D,).A>6?__,<#IB?[__XVT)@````"`>P$^ +XM#X5'_O__@\,"@\X"#[8#A,`/A#;^__\/OL"%P`^(*_[__XL-_"`)"#G!#XX= +XM_O__BQ4((0D(ZR6-="8`@\,!#[8#A,`/A`/^__\/OL"%P`^(^/W__SG!#X[P +XM_?__]D2"-@)UV.GD_?__C78`QT0D"`0```"+0B"+`(E$)`2+1=B)!"3H9//_ +XM_[@!````Z>S]__^+1VR#P`&)1"0$BT78B00DZ'7U_?^%P'4=BT]X@\X!B4W@ +XMZ7W]__^X`0```.F[_?__Z+AY_?^+5WB)5>#I8_W__XN!7`,``(T$0,'@`@-! +XM$(M(.(7)#Y7`Z1/^__^+1W2+3=B+4`2+02"+&@^W0!@EA````(/`@`^$@@`` +XM`(M%V(E<)`2)!"3H/L#]_XM-V(U';(E$)`B-1V2)="00B5PD#(E$)`2)#"3H +XM3<']_^DZ_?__BT<@QT0D"`H```"+3=B+0!")#"2)1"0$Z(OR__^X`0```.D3 +XM_?__BT<@QT0D"`D```"+5=B+`(D4)(E$)`3H9?+__[@!````Z>W\__^+0@B) +XM7"0$B0PDB40D".A8FO[_A<")1=QT'8M5V(M"((M`"(D$).@D?OW_BTW8BU7< +XMBT$@B5`(BTW8BT$@9H%@&#__BT$@9H-(&`R+41#'1"0(`0```(M!((M`"(D, +XM)(E$)`3_DIP(``#I'____XVV`````(V\)P````!5B>564X/L$(MU"(M&'(7` +XM='GV0%@$=!.+50RY`P```(GPZ&G[__^%P'44QT0D!`````")-"3HE;_]_X7` +XM=!&X`0```(/$$%M>7<.0C70F`(M%#`^W6'R)-"2!XP`!``")7"0$Z/?P__^% +XMP'72@_L!&<`E`/[__P4`!```"8:L!```@\006S'`7EW#QT0D"`0```"+50R+ +XM0B"+`(DT)(E$)`3H.?'__[@!````ZY:)]E6Y`@```(GEBT4(BU4,7>G,^O__ +XMC;8`````C;\`````5;D!````B>6#[!B)=?R+=0B+50R)7?B)\.BB^O__AQ=P\=$)`0`````B30DZ+^^_?^%P'7=BT4,#[=8?(DT +XM)('C``$``(E<)`3H,O#__X7`=<"#^P$9P"4`_O__!0`$```)AJP$```QP(M= +XM^(MU_(GL7<.-M@````"-O"<`````53')B>6#[!B)7?B+70R)=?R+=0B)VHGP +XMZ!/Z__^%P'0/BUWXN`$```"+=?R)[%W#QT0D!`````")-"3H,+[]_X7`==W' +XM0W@`````B5T,BUWXB74(BW7\B>Q=Z5'?_O^058GE4X/L%(M="(M-#(M#'(7` +XM=#8/MT%\C5%1QT0D$`$```")'"2#X`'WV"'"C4%LB40D#(U!9(E$)`B)5"0$ +XMZ%RP_?^#Q!1;7+B +XM"```@_I`B47P#X2+`0``#X^5````@_H"#X1-`0``@_H@#X0A`0``]H."```` +XM"'0&@\`!B47PBT7PB4-DBT7P@^@!```````C47PB40D!(DT).C- +XM\?W_A<`/A<4```"+1?`Y0VQV`XE#;(E<)`2)-"3H7ES__X7`#X6F````BU7@ +XMA=)T"(M%X(E&3#'`@\0L6UY?7<.+2UCI5____XVT)@````"!^H````!T$X'Z +XM``@``(GV#X5G____Z7'___^->?^Z`0```-'O.?AV!(G"*?J)4V2+1?"#Z`&) +XM0VR)7"0$B30DZ.M;__^%P'4WQT0D!)SL"`B)-"3HMU/__XM%\(E%X(E#9(E# +XM;(E<)`2)-"3HOUO__X7`#X3Z````C;0F`````(/$++@!````6UY?7<.-=@"+ +XMCF0$``"#Z0'ILO[__SG!N@$```!S!8U0`2G*B5-DBT7PB4-LQT7@`````.D% +XM____C10).=`/AIL```"#P`$IT(E#9(M#9(/H`0'(B4-LQT7@`````.FY_O__ +XMD(UT)@"-4?^Y`0```-'J.=!V!(G!*=&)2V2)T`-%\(E#;(M&3(E%Z(M&4(E% +XM[(U%Z,=$)`P!````B40D",=$)`0G````B30DZ-@2_O_'1>``````Z6#^___' +XM1"0(!````(M#((L`B30DB40D!.A3[?__N`$```#I@O[__\=#9`$```#I8?__ +XM_\=$)`2<[`@(B30DZ(U2__^+1?"#P`&)0V2+1?"#Z`$!^(E#;.D(_O__D)"0 +XMD%6)Y8/L&(M%",=$)`C([`@(QT0D!`,```")!"3HSR'^_[@!````R<.0D)"0 +XMD)"0D%6)Y8/L&(M%",=$)`CX[`@(QT0D!`,```")!"3HGR'^_[@!````R<.0 +XMD)"0D)"0D%6)Y5.#[!2+70R#>Q0$=@7H+W/]_XM#%/\DA2CM"`B0,<"#Q!1; +XM7<.+`X/X`71QC5#_C4,,B1.)1"00C4,(B40D#,=$)`@!````B50D!(M%"(D$ +XM).CG[/W_A____C;8`````58GE5E.#[#"+70R-1?2+=0B)1"00 +XMC4,,B40D#(U#"(E$)`B+`XDT)(E$)`3H;^[]_X7`=!.+5?2X`0```(72=26# +XMQ#!;7EW#BT,,A7<.X`0```.ORC;8`````C;\`````58GE +XM5E.#[!"+=0B+70R)]HE<)`2)-"3HQ/S__X7`=3.+0Q2#^`-TZ(/X`73CA<"0 +XM=1@/ME,0.Q7\(`D(?0RA""$)"/9$D#8"=<:#Q!`QP%M>7<.#Q!"X`0```%M> +XM7<.058GE5E.#[!"+=0B+70R)]HE<)`2)-"3H=/W__X7`=3.+0Q2#^`-TZ(/X +XM`73CA<"0=1@/ME,0.Q7\(`D(?0RA""$)"/9$D#8"=<:#Q!`QP%M>7<.#Q!"X +XM`0```%M>7<.058GE5U93@^P\BT4,]D`Q`G0.#[90`8#Z0'0%@/HJ=1N+50AF +XM@[JL!`````^)0P$``(M="`^VDZ@```"+10@/MLJ!B*P$````@```.PW\(`D( +XM#XS(````B="+70B+7UW#QT0D"`4```#'1"0$`````(D4).A$Y___ +XM@\0\N`$```!;7E]=PXM5##'`]D(Q"`^$;____XM"!(U=X(D<),=$)`CZE@@( +XMQT0D!!0```")1"0,Z(IP_?_'1"00`````(E<)`C'1"0$`````(E$)`R+70B) +XM'"3HX]S]_X7`#Y7`#[;`Z1W____'1"0$_P```(M%"(D$).B3U_W_Z3[___^0 +XMD)"0D)"0D)"0D)"0D%6)Y5.)PX/L%(#Z_W0U#[;"C01`C80`4`$```-#$(/` +XM"(D<)(E$)`S'1"0(2^T(",=$)`0"````Z%,;_O^#Q!1;7<.)5"0$B1PDZ#'7 +XM_?_KT.L-D)"0D)"0D)"0D)"0D%6)Y5=64X/L+(M]#`^V5P+V1S$@#[;:=0^+ +XM30B+@9P```"(D(0!``"+50B+@IP```#'@(@!```!````C47LB40D$(U%\(E$ +XM)`R-1>B)1"0(BT7UW#BT7PAAS!P^^`CG8=>PYT77B)5T2)1T")1TB+1RR%P'0.]D`&('0(@V\X`3'`ZX0Q +XMP.N`B?95B>6#[!B)7?B+70R)=?R+=0B)7"0$B30DZ.+^__^Z`0```(7`=22+ +XM0T"+4SR#P`&)4T0QTHE#0(E#2(N&G````,>`B`$```,```"+7?B)T(MU_(GL +XM7<.)]HV\)P````!5B>575E.#["R+?0P/ME<"]DC]_X7`=".+3>RX`0```(7)=`^+10B)VNC'_?__N`$` +XM``"#Q"Q;7E]=PXM%\(7`=.*+3>B^`0```(E-X`'!BT7@`TAV!P^^`CG8=>PYT77@ZYV+=P3K +XMV8M'+(M5Z"M5X(7`B5=`=`;V0`8@=0V+1SR)5TB)1T0QP.N$BT`B`$```0` +XM``"+7?B)T(MU_(GL7<.0C70F`(M#/(E32(E#1.O2D(UT)@!5B>6#[!C'1"0( +XM7.T(",=$)`0"````B00DZ#(8_O_)PU6)Y8/L&(EU_(MU"(E=^(M5#(N&G``` +XM``^V@(0!``"(0@*+AIP```"+F(@!``"#^P1V!>BL:?W__R2=@.T("(E4)`2) +XM-"3HM?W__XG"C78`BX:<````B9B(`0``BUWXB="+=?R)[%W#B?#HR)T%W#B50D!(DT).C4_?__B<+KP(E4)`2)-"3H9/S__XG" +XMZ[")5"0$B30DZ,3^__^)PNN@58GE@^P(BU4(BTT,BX*<````#[:`A`$``(A! +XM`HN"G````(.XB`$```1V!>@$:?W_BX"(`0``_R2%E.T("(E-#(E5",GI=_[_ +XM_XG0Z.#^__^X`0```,G#B4T,B54(R>GM^___B4T,B54(R>E!_?__B4T,B54( +XMR>G5_/__D)"0D)!5B>575E.#["R+10R+?0R+70R+2#")SHG(P>X#@^`"@^8! +XM@_@!BT4,&=*!X0`"``"#XOZ#QS2#P@2#PP&#P#R#^0&)1>`9P`GR]]`APXM% +XM"(E4)!"+5>")?"0(B5PD!(D$)(E4)`SH-:+]_X7`=!&X`0```(/$+%M>7UW# +XMC70F`(M5X(M%"(ET)`R)?"0$B50D"(D$).@&IOW_AR)7"00QT0D#`````#'1"0(`````(M" +XM1(E$)`2+10B)!"3HRN']_X7`#X63````BT4,BT@P]L$(=1>!X0_^__^#R2") +XM2#"+50R+1>PY0DAS73'`]L$$#X19____BU4,@>$/_O__@\E`B4HPZ47___^0 +XMBU4(C47PB40D!(D4).BNX_W_A<`/A27___^+1?"%P`^%9?___XM%#,=`1`$` +XM``#'0$@`````,<#I!____X/X`8U0_QG`]]`APHM%#(E02.N/BT7PBU4(B5PD +XM$,=$)`P`````QT0D"`$```")1"0$B10DZ`GA_?^%P`^%P/[__XM%\(M5#(E" +XM1.DQ____D)"058GE4X/L-(M="(U%^(E$)!"-1?2)1"0,QT0D"`````"+0TR) +XM'"2)1"0$Z,'@_?^%P'0&@WM,`71\BT7XA<")]G1.QT0D%`````#'1"00```` +XM`(E$)`R+1?3'1"0$`````(D<)(E$)`CH,R?__[H!````A6#["B)7?2)PXE]_(EU^(MP$,=$)`0`````B00DZ#S!_?^% +XMP(G'=!>-1AB)1"0(B5PD!(DT).BS5O[_AQ= +XMP\=$)`P`````QT0D"`````")?"0$BT88B00DZ&["_?^%P'4.BT88BT`<@&!8 +XMOS'`Z\*+1AB)!"3HP53^_[@!````Z["-=@"-O"<`````58GE@^PXB5WTB<.) +XM??R)UXEU^(M`$(M`&(7`=&6+7<.+1?0Y0U!RU8/X`8U0_QG`]]`A +XMPHE34.O$58GE@^P8B5WTB<.+02")=?B)UHE]_(E,)`2)'"3_4`2)\HG'B=CH +XM5?___[H!````A57 +XM5E.#["R+70B+>Q#'1>``````Z>,```"0C70F`(N#3`$``(T$0,'@`@-#$(M` +XM.(7`#Y7`A,!T$8GRB=CH3/[__X7`#X6.`0``QT0D%`$```#'1"00`````(M& +XM$(E$)`R+1@C'1"0$`````(D<)(E$)`CH-B3__X7`#X58`0``B1PDZ$;H``#V +XM@ZP$```0="ZAH!0)"(7`#X7#````BQ4$(0D(BT((@^@!A<")0@@/B#`!``"+ +XM`L8`"H/``8D"B1PDZ/>2_O^)'"3HKT'__XU%\(E$)`2)'"3H0/,``(7`#X7R +XM````BT7PA<`/A(H```"#0RP!QT7@`0```(M'?(M`%(7`#X5V____BT4,QT0D +XM#(`!00#'1"0(.@```(D<)(E$)`3H!:(``(7`#X6G````BW-XBT8X@_@!#X2Z +XM````A7UW#B50D!,<$)`H```#H +XM?6;]_^G%_O__@WX0`78-B?*)V.B%_/__AS'1"0( +XM`0```(D<)(E$)`3H@$8!`(7`=".+1>R)!"3H`5'^_[@!````ZYF)V.BC^___ +XMA<"0=8CI;/___XM&&(M0'(M%[(E0'(M%[(M`'(,``8M&&(M0((M%[(E0((M% +XM[(M0((M#(`^W0!AFB4(8BU7LC4),B10DB40D!.BEW?W_BT7LBU!,A=)U"L=` +XM3`$```"+1>R!B*P$``````$`B5L8BT7L@8NL!````!```(E#%#'`Z0S___^- +XMM@````"-O"<`````58GE4X'LM````(V=>/___XD<),=$)!@`````QT0D%``` +XM``#'1"00`````,=$)`P`````QT0D"`````#'1"0$/````.@8W?__BU4,B=F+ +XM10CH>_S__X'$M````%M=PXGV58GE5E.![+````"+=0R+1C3V1C$(C4@!=`R+ +XM5@2#^@)V!(U,`O^-G73___^)3"00B40D#(D<),=$)!@`````QT0D%`````#' +XM1"0(`@```,=$)`0<````Z*3<__^+10B)V8GRZ`C\__^!Q+````!;7EW#C;0F +XM`````(V\)P````!5B>6![+@```")=?R+=0R)7?B+1A2#^`5T"H/X#'19Z"!@ +XM_?^-G73____'1"08`````,=$)!0`````QT0D$`````#'1"0,`````,=$)`@` +XM````QT0D!"P```")'"3H'MS__XM%"(G9B?+H@OO__XM=^(MU_(GL7<.-G73_ +XM___'1"08`````,=$)!0`````QT0D$`````#'1"0,`````,=$)`@`````QT0D +XM!$@```")'"3HRMO__^NJD(VT)@````!5B>6![+@```")=?B+=0R)??R+?0B) +XM7?3V1C$@=6*+1BP]X``)"'18/>`""0AT4<=$)`R`B$$`QT0D""$```")="0$ +XMB3PDZ&6>``"%P`^%G@```(M?>(-[.`0/A,(```"+1TR)1D2+1U")1D@QP(GV +XMBUWTBW7XBWW\B>Q=PXUV`,=$)!@`````C9UP____QT0D%`````"+1CR)1"00 +XMBT8TQT0D"`(```#'1"0$`0```(D<)(E$)`SH!-O__XN'F````,=`)`````#' +XM1"00`0```,=$)`P!````QT0D"-7:"`B)7"0$B3PDZ`/7_O^%P'0/N`$```#I +XM=?___Y"-="8`BX>8````B=F+4"2)5>B+0!R)\HE%Y(GXZ!/Z___I3O___XD\ +XM).@FXP``QT0D&`````#'1"04`````(M&/(E$)!"+1C3'1"0(`@```,=$)`0! +XM````B40D#(V%8````QT`D`````,=$)!`!````BT,0 +XM@^@!B40D#(M#"(D\)(/``8E$)`B-A7#___^)1"0$Z$_6_O^%P`^%2/___XN' +XMF````(V-R-O5C___^)1"08QT0D%`````#'1"00`````,=$)`P` +XM````QT0D"`````#'1"0$.@```(D\).ASV?__BX:<````BY@P`0``B1PDZ#-C +XM_?^)7"0(B3PDB40D#(U%W(E$)`3H^-3__XM5#(GYB?#HK/C__XM=](MU^(M] +XM_(GL7<.+EM`!``"%T@^$____D%6)Y5.![,0```"-G6#___^-1?2)1"08B1PDQT0D%`````#' +XM1"00`````,=$)`P`````QT0D"`````#'1"0$-P```.B)V/__C47DB40D!(D< +XM),=$)`P'````QT0D"'[`"`CH&M3__XM5#(G9BT4(Z,WW__^!Q,0```!;7<.- +XM="8`58GE5E.![,````"+=0R-1?")1"08C9U<____QT0D%`````"+1CR)1"00 +XMBT8TB1PDQT0D"`(```#'1"0$!P```(E$)`SH!]C__XU%X(E$)`2)'"3'1"0, +XM`0```,=$)`B9[P@(Z)C3__^+10B)V8GRZ$SW__^!Q,````!;7EW#B?95B>56 +XM4X'LP````(MU#(U%\(E$)!B-G5S____'1"04`````(M&/(E$)!"+1C2)'"3' +XM1"0(`@```,=$)`0%````B40D#.B'U___C47@B40D!(D<),=$)`P!````QT0D +XM"':["`CH&-/__XM%"(G9B?+HS/;__X'$P````%M>7<.)]E6)Y593@>S````` +XMBW4,C9U<____C47PBU8TB40D&(D<),=$)!0!````B50D$(E4)`S'1"0(`@`` +XM`,=$)`0#````Z`K7__^-1>")1"0$B1PDQT0D#`$```#'1"0(3XT(".B;TO__ +XMBT4(B=F)\NA/]O__@<3`````6UY=PY"-="8`58GE@>S(````B7W\BWT(B5WT +XMB77XB[>D````A?8/A)T```#'1"0(`0```,=$)`0`````B3PDZ)6R_?^Z`0`` +XM`(7`=`^+7?2)T(MU^(M]_(GL7<.-1>R-G5C___^)1"08QT0D%`````#'1"00 +XM`````,=$)`P`````QT0D"`````#'1"0$%````(D<).A`UO__B30DZ`Q@_?^) +XM="0(B1PDB40D#(U%W(E$)`3HT='__XM5#(G9B?CHA?7__XG"ZX60QT0D"`T$ +XM"0C'1"0$`P```(D\).@("/[_N@$```#I8O___XVT)@````"-O"<`````58GE +XM5E.#[!"+70B+7<.)'"3'1"0(`````,=$)`0`````_Y9< +XM"```BU,@BT-,B4(0BT-0BU,@B4(4BT,@9H-(&`&+@ZP$``"#X/6#R`&)@ZP$ +XM``")'"3'1"0$)KH(".C4-___@\00,6#[!B# +XM^@)T-8/Z`W05@^H!=`+)PXGVC;PG`````.C/6/W_QT0D"(0$"0C'1"0$`P`` +XM`(D$).@#!_[_R<.0QT0D"&0$"0C'1"0$`P```(D$).CH!O[_R<.-M@````!5 +XMB>575E.![+P```"+50P/MD("/"-T.CPK=#H\+70VQT0D"`8```"+30R[`0`` +XM`(M!*(M`"(E$)`2+=0B)-"3HC)T``('$O````(G86UY?72+0#@Y^(F%7/__ +XM_W-XBU7'@Y +XM\'UT@\(!]D2!-4!T:H/#`3G[=>/K"XM=X(7;#X1X`0``QT0D"+\$"0B[`0`` +XM`,=$)`0#````BTT(B0PDZ)`%_O^!Q+P```")V%M>7UW#QX58____`0```.D' +XM____BT4(N@(```"[`0```.@B_O__Z]"+G5S___\[G5S___\/A,`!``"+30B) +XM65#'1"0$`````(D,).@8"`$`BW7%9/___P````"#P#(/ +XMA(P!``")1"0,C47HB40D",=$)`0`````BU4(B10DZ.9X_O^%P(F%9/___P^% +XM8`$``+L!````@<2\````B=A;7E]=PX/X`G8JB[5L____#[94%@&`^EB(E4__ +XM__\/E(57____#X3P`0``@/IX#X3G`0``A,D/A//^__^#^`$/ANK^__^+M5S_ +XM__^+C5#___^#Q@$/MA0Q#[["@_A_#X?3_O__]@2%W10)"`0/A,7^__^`^C@/ +XMA+S^__^`^CG'A6C___^S!`D(QX5@____"`````^%T_[__^F:_O__B9UL____ +XMB9U<____Z5W^__\/MD,!#[[0@_I_#X;#`0``@^@X/`%W0\>%:/___[.@"`C' +XMA6#___\*````@\,!Z9+^__\/OD,!@_A_=PKV!(7=%`D(!'7EB40D!,<$)-H$ +XM"0CHFU7]_X7`==&+30B%R0^$E_[__XM%"(M8$(7;#X2)_O__]H-5"````0^% +XM?/[__XU',CM#>`^'8`,``(M#=(F%9/___XM#>(E%Z(&+5`@````!``")\BN5 +XM7/___SMUY(F5%8/___Q````#IZOS___8$E=T4"0@$#X0O_O__/#@/ +XMA"[^__\\.0^%.O[__^DA_O__@/LKC70F`'0)@/LM#X6!_/__B[5<____BY50 +XM____QX5H____N@0)"(/&`0^^!#*#^'\/AY_[___IS'1"0, +XM"@```,=$)`@`````B00DZ&MS_O^#^`$/A:'^__^+30R+E5C___^`>0(M=0+W +XMVHM-[(7)#X[4`0``A=(/CLP!``"X____?RG(.=`/@[T!``"X`@```.ED_O__ +XMBT4,@'@"*P^$@P$``(M%\#F%6/___P^'+@$``"N%6/___XE%\(.]8/___Q"+ +XME7#___]U`X/J`HM%\(V->/___XE4)`R)1"00BY5H____QT0D!&0```")#"2) +XM5"0(Z"=5_?^)QXN%7/___XE$)`B+1=R)1"0$BY5D____B10DZ$96_?^+G63_ +XM__^-C7C___\#G6S___^)3"0$B7PD"(D<)`'[Z")6_?^+1>0KA5S___\KA7#_ +XM__^)1"0(`W72)1"0,B[5D____ +XMB70D"(M5#(M"-(E$)`2+30B)#"3H2]#]_XG#Z7+]__^)5"0(BX5L____`T7< +XMB40D!(N-9/___XD,).BI5?W_BX5D____BY5P____Q@00`(N%9/___^GR_/__ +XMA=)Y>+@```"`*<@YPGUMN`,```#I$/W__XE$)`R-0WB)1"0(BT-TB40D!(M- +XM"(D,).@4=/[_A<`/A#3[__^)0W3I<_S__X&@5`@``/_^___IQ?G__XM5\(G0 +XM]]`[A5C___\/@E/^__^+A5C___\!T(E%\.ER_O__AD?&@`` +XMBX'``@``C01`P>`"`T$0BT`XB5T0B4T(B44,6UWI_1D``(N!4`,``(T$0,'@ +XM`@-!$(M`.(E=#(E-"(E%$%M=Z=L9``"-="8`C;PG`````%6)Y593@^P0BW4( +XMBYZ<````A=MT8(N#,`$``(7`=`B)!"3H#57]_XN#1`$``(7`=`B)!"3H^U3] +XM_XN#?`$``(7`=`B)!"3HZ53]_XN&G````(N`C`$``(7`=`B)!"3HT53]_XD< +XM).C)5/W_QX:<`````````(/$$#'`6UY=PXGV58GE@^P8QT0D!,P!``")7?2+ +XM70B)=?B)??S'!"0!````Z&Y2_?^%P(G6````BT4,A=N)L)P```#'AJP! +XM````````#X3:````B[N<````BX=(`0``A$`0``,=*( +XMAH0!``"+AX@!``")AH@!``"+A[0!``")AK0!``"+7?2)T(MU^(M]_(GL7<.) +XM!"3H1U/]_X7`B<*)AD0!``!T+8N'2`$``(E$)`B+AT0!``")%"2)1"0$Z(]2 +XM_?^+AT@!``")AD@!``#I5?___\=$)`@`````QT0D!`4```")'"3H@OS]_[H! +XM````ZY$QTL>&B`$```````#K@Y"0D)"0D)"0D)"0D)!5B>575HG.4XMZ,('. +XM`(2$!(G#]\<`(```=`B)SH'.`(2$!O:#``$```$/A*`!``"+@_@```"-!$#! +XMX`(#0Q"+0#B%P`^5P(3`=`.#S@3V@PP!```!#X1E`0``BX,$`0``C01`P>`" +XM`T,0BT`XA<`/E<"$P'0#@\X0]H,\`0```0^$*@$``(N#-`$``(T$0,'@`@-# +XM$(M(.(7)#Y7`A,!T`X/.0/:#E`,```$/A.\```"+@XP#``"-!$#!X`(#0Q"+ +XM0#B%P`^5P(3`=`:!S@```!#V@Z\$```!=`:!S@`(``#V@R0$```!#X2B```` +XMBX,`"`T,0BT`XA<`/E<"$P'0&@'E`````$```")QHU%[(E$)!"-1?")1"0,C47HB40D"(M#-(D\)(E$ +XM)`3HYLC]_X7`=!J+5>R%T@^$!P$``(/.",=%\`````")=>#K%(M%\(7`#X3A +XM````@B%P`^$O0```(M#,(U3`8US/,=$)!``````B70D#"4``@`` +XM@_@!&<#WT"'"C4,TB40D"(E4)`2)/"3HVH3]_X7`=7:+1>#'1"0<`0```,=$ +XM)!@`````QT0D%`````")1"0@BT7PB40D$(M%Z(ET)`B)7"0$B3PDB40D#.BY +XM4P``@\0\6UY?7<.0B5-`Z6W___^+4P2#Z@&-!`*)0T"+5?"#Z@$YT`^&4___ +XM_^O<@\X(Z1?___^-="8`@\0\N`$```!;7E]=PXUS/.EU____C70F`(V\)P`` +XM``!5,'E`````0```")QHU%[(E$ +XM)!"-1?")1"0,C47HB40D"(M#-(D\)(E$)`3H9L?]_X7`=!B+5>RX`0```(72 +XM='B#S@C'1?``````ZQ"+3?"%R74#@\X(@B)1"0(B50D!(DT).B#QOW_A7UW# +XMBU7PA=)UKX/+".NJD(M'!.NOC70F`(V\)P````!5,&E`````````"+5S2)5DR)PXU%[(E$)!"-1?")1"0,C47H +XMB40D"(E4)`2)-"3HL\7]_X7`=&6+5>RX`0```(72=%$QTH/+",=%\`````#V +XM1S$(N`$```!T`XM'!(E$)!R+1>B)7"0@QT0D&`````#'1"04`````(E4)!") +XM1"0,QT0D"`````")?"0$B30DZ`)1``"#Q#Q;7E]=PXM5\(72=!.+1E"#P`$Y +XMPG0.B490ZYV-="8`@\L(ZY2#RPB)5E#KC(UV`%6)Y8/L&(E=^(M="(EU_(MU +XM#(U#4,=#4`````")1"0(BT8TB1PDB40D!.BQ:?[_AQ= +XMZ>#]__^+7?BX`0```(MU_(GL7<.058GE5E.#[#"+=0R-1?2+70B)1"00QT0D +XM#`````#'1"0(`````(M&-(D<)(E$)`3H#,']_X7`=1*+1?2#^`&-4/\9P/?0 +XM(<*)4U"+0Q"+D!@!``"%TG04BY`0`0``:X`<`0``'/9$`A0"=0B)'"3H'=?] +XM_XET)`2)'"3H(?[__X/$,%M>7<.-=@"-O"<`````58GE5U93@^Q,BUT,BW4( +XMBT,PBU,T)0_^__^#R"`[4SR)0S`/A!<"```QR8G:B?#H;/C__XE%T,>&E``` +XM``$```"+0S#!Z`.)QX/G`70SQT,X`````/:&#`$```$/A!X"``"+A@0!``"- +XM!$#!X`(#1A"+0#B%P`^5P(3`#X42`@``BT,TB49,BT,XB490BT80BY`8`0`` +XMA=)T%(N0$`$``&N`'`$``!SV1`(4`G4(B30DZ$K6_?^%_W4,BT,T.T,\#X0* +XM`@``C4,\C5,TB57R-1>B)1"00C47LB40D#(U%Y(E$)`B+0S2)-"2)1"0$Z'#"_?^%P`^% +XM#@$``(M5[#E3.'($@TW0"/9#,0BX`0```'0#BT,$BTW0B40D',=$)!@````` +XMQT0D%`````")3"0@B50D$(M%Y(E<)`3'1"0(`````(DT)(E$)`SHQ$T``(M- +XMU(7)B<-T,87V=!.+1A"%P'0,BU74.5!T#X0E`@``BTW4B0PDZ.U)_?^#Q$R) +XMV%M>7UW#NP$```"#Q$R)V%M>7UW#C47HB40D$(U%[(E$)`R-1>2)1"0(B50D +XM!(DT).BOP?W_A<`/A,#]__^+1>B%P'3!B5PD!(DT).B4^___BP`````Z>'^__^0BT,PC5,!C7L\QT0D$``` +XM``")?"0,)0`"``"#^`$9P/?0(<*-0S2)1"0(B50D!(DT).B:??W_A<`/A2/_ +XM__^+1>R%P'4$@TW0"/9#,0BZ`0````^%T0```(%-T``@(`"+3=")5"0B)1"0,QT0D"`$```")5"0$B1PDZ`6[_?^%P`^% +XM6____XM33(/J`?9',0BX`0```'0#BT<$BTW@B40D'(E4)!C'1"04`````(E, +XM)""+1>R)1"00BT7HB7PD!(D<),=$)`@`````B40D#.C`20``@\0\6UY?7<.- +XM1?")1"0$B1PDZ-F\_?^%P`^%[_[__XM-\(7)#X6&_O__,=+'1>@`````QT7L +XM`````.EZ____D%4QR8GEBT4(BU4,7>DO_O__ZPV0D)"0D)"0D)"0D)"05;D! +XM````B>6+10B+50Q=Z0S^__^0D)"0D)"0D)"0D)!5B>6#[`B+30R+02R%P'0& +XM]D`&('4JA<#'04``````=`KV0`8@=`2#:3@!BT%`BU$\B4%(,<")443)PY"- +XM="8`BU$XA=)USXM%"(D$).C^A0``N`$```#)PXVT)@````!5B>6#[`B+30R+ +XM03B%P'10]D$Q"+H!````=34YPG(HQT%``````(M!+(7`=`KV0`8@=`2#:3@! +XMBT%`BU$\B4%(,<")443)PRG0B4%`Z]B)]HM1!#G"<\CK[HVT)@````"+10B) +XM!"3HA84``+@!````R<.-M"8`````C;PG`````%6)Y5.#[!2+70SV0S$(='"+ +XM0P2#^`%V:(/H`8E#!(E$)`B+0S2)1"0$BT4(B00DZ,SR``")P8E#0(M#+(7` +XM=`KV0`8@#X66````BU,X.=%V1H7`#X2D````]D`&((UV``^$EP```(U!_XE# +XM0(M#-(E32(E#1#'`ZS:-M"8`````BT,LA-M"8`````A!W5`^$*`$``(M+.(/N`8E+2(E[1`^$D0```(M#/#E#-',+ +XMBU-`A=(/A(4```"#:T`!,<#I0____XM#0(M3/(E#2#'`B5-$Z3#___^+4SR+ +XM>S2)5>#KIXM30(M+.(G(B=&)4SB+5>")>SR)0T")UXE3-.N8@TLP"+X!```` +XMZ37___^+4T"+2S@YR@^$KP```#G1#X9T____Z\.%T@^$.?___Y"-="8`Z>O^ +XM__\QP.G)_O__@^@!B4,\C77PB40D!(M%W(ET)!#'1"0,`````,=$)`@!```` +XMB00DZ'BT_?^%P`^%D/[__XM%\(ET)`C'1?``````@_@!C5#_&<#WT"'"BT,T +XMB5-`BU7EO_?__ZPV0 +XMD)"0D)"0D)"0D)"058GE@^P8BU4,QT0D#`$```"-0C2)1"0(#[9"`HE$)`2+ +XM10B)!"3H9=C]_\G#D)"058GE5U93@^Q,BTT,C47HBW4(B40D$(U5Y(U%[(E$ +XM)`R)5"0(BT$TB30DB40D!.B]MOW_A7UW#BT4,BUWLBT@X.=ESRXG*`U7D +XM#[8"#[[P/#Z)=<`/A`0"``!_)SPI#X0M`@``/#P/A!0"```\*(UV``^$^`$` +XM`(/!`8/"`3G9=-(E.0#G##X.C`0``BW4,BU8L +XMA=(/A+P!``#V0@8@#X2R`0``BT8XB5Y$B49(A=(/A*````#V0@8@#X26```` +XMBW4,B=J+1CPYPP^$A@````^#CP$``(GS@\,TBTL$AP/A-\````/M@(\ +XM(`^$O0```#P)#X2U````,<")]NDY_O__#[9%W#M%P'07.46\#X7*_O__@^X! +XM#X7!_O__Z?'^__^#Q@'IM/[__SQ[D'09/'T/A4S^__^[\"H'",=%O'L```#I +XM:_[__[L`+`<(QT6\?0```.E:_O__N_`J!PC'1;Q;````Z4G^__^[\"H'",=% +XMO#P```#I./[__[L`+`<(QT6\*0```.DG_O__NP`L!PC'1;P^````Z1;^__^[ +XM\"H'",=%O"@```#I!?[__XM%[(/"`8E5Y(/H`87`B47L#X4A____BTT,,<"# +XM23`(Z6C]__\/A(8```"+50R)2DB)0D2+30R+42SI9/[__\=$)`@,!0D(Z2G] +XM__^+=0R)3DB)1D3I2?[__XM=#(/#/.EK_O__BUT,@\,TZ7G^__^-1?#'1?`` +XM````B40D"(L#B40D!(M%"(D$).A06/[_A<`/A?'\__^+0P0[1?`/AZC^__^+ +XM30R+432+03SI*O[__SM..`^&R+@'P!``"%P'0(B00DZ-@Z_?^%_W03BT7HB7PD!(D< +XM)(E$)`CHD3G]_XM%$(7`=!R+51"-1@&)1"0(B50D!(M5\(T$$XD$).AN.?W_ +XMBT7LB9A\`0``,<#I-(7`=`;V0`8@=52)V(/X +XM`78IBT4(C57PC4WLB50D$(E,)`S'1"0(`````(E<)`2)!"3HN*[]_X7`=$2[ +XM`0```(E>/#'`QT9``````,=&2`````")7D2#Q#Q;7E]=PY"+1CB%P`^%50$` +XM`(/[`0^$T0$``(-.,`B-0_^)1C3KCL=%W`(```#V1C$(#X4_`0``BT7PA<`/ +XMA70!``#'1=@!````BT4(@^L!C57PC4WLB50D$(E,)`S'1"0(`````(E<)`2) +XM!"3H):[]_X7`#X5I____BTW8A0'K$HUV``^V0@*#P@*$P`^$ +XM5/___XGY.,AUZP^V0@$\(`^$``$``(M-U#I!`G77@VW<`771D.G,_O__@WW8 +XM`8VT)@````!T!>AM,_W_BT7PA<`/A!'___^)1"0$BT7LB00DZ!]X``"%P`^% +XM^O[__X-MW`$/A([^___'1=@`````Z>3^__^0@^@!B48XB=CI0?[__XUV`(M& +XM!`'`B47`"#X7V_O__D(UT)@#I]/[__XUT)@"-O"<`````58GE5U93 +XM@^P\BWT,BTB) +XM3=2)1"00B50D#,=$)`@`````B5PD!(M%"(D$).C"J_W_A@8,?W_C70F`(M-\(7)#X05____B4PD +XM!(M%Z(D$).C&=0``A<`/A6W___^#;=@!='.+3?#'1=``````Z>G^__^+3?"# +XM^0$/AMW^__^+50B+@IP```"+@'P!``")1

.+ +XM5-U[`^V0@$\(`^$F`$``#I&`G7; +XM@VW8`775BT7UW#@?M``@D(#X7, +XM_O__BTB)!"3H%70``(7`#X2F +XM_?__Z9#]__^#;=@!C70F``^%J?W__^FP_O__D(UT)@"+3?"-<_^#^0$9P(U1 +XM__?0(<(Y5S@/A:+]___'1"0$`````(M%"(D$).AB=@``N`$```#IP?W__X/Y +XM`@^%7_[__^E?_O__N`$```"0C70F`.FD_?__BTWPZ#[;` +XM_R2%,`4)"+DY````BX.<````B$H!B(B9````6UW#N3(```#KY[DS````Z^"Y +XM-````.O9N34```"-="8`Z\ZY-@```.O'N3<```")]NN^N3@```#KMXVT)@`` +XM``!5B>575E.#["R+70R+?0B+0S#VQ"`/A<(```#VQ`B^`0```'0#BW,$C4,! +XMB47PC4-$B47L@^X!@_[_#X2N````BT,P)0`"``"#^`$9TO?2(U7PQT0D%`$` +XM``"+1>S'1"0$`````(E4)`B)/"2)1"00C4,TB40D#.BT%?[_A<````B46TC47LB40D$(U%Z(E$)`S' +XM1"0(`0```(M&-(D\)(E$)`3HTZ7]_X7`#X6A`0``BT7LA<`/A$,!``#'1;@! +XM````]D8Q"'0&BU8$B56XBT8TB48\BT8X@^@!`T6XB49`BU7L@^H!.=`/A[4! +XM``#'1;P`````]D8Q(`^$)@$``(7_#X19`0``BU\0A=L/A$X!``#V@U4(```! +XM#X5!`0``BT7L.4-X#X(@/A$\!``"+ +XM5;2+@D`!``"#^`P/A$\!``"+3;2+5<`#5C@/MH$\`0``BTVXB10DB40D!(E, +XM)`CHR"S]_XM%[(E$)`R+1<")1"0(BT8TB3PDB40D!.AGJ?W_B<.%_W03BT<0 +XMA' +XME`````0```"-77UW#BT7LQT7P`````,=%P`````"%P`^$TO[__XE$)`R-1?") +XM1"0(QT0D!`````")/"3HUTS^_X7`=+F)1<"+1>SIJ/[__XU&-+L!````B40D +XM!(D\).B4<```@\1QT6/:'#`$```$/A$,"``"+AP0!``"- +XM!$#!X`(#1Q"+0#B%P`^5P(3`B=%T+HM=Z`^^$X72>"<[%?P@"0A]'Z$((0D( +XM]D20-@)T$XU!_X-%Z`&%P(G!B47L==*+7>B+1>R)7"0$B3PDB40D#(E$)`CH +XM*&']_X7`B<-T_?_IZ?S__\=$)`@'````,=O'1"0$`````(D\).C$;``` +XMZ1_]__^)7"0$B3PDZ,/#``"%P`^$(____^D\_?__@_@)C78`=60QV^GW_/__ +XM@8^L!`````0``+L!````Z>/\__^!H%0(``#__O__Z:'\__^)1"0,C4-XB40D +XM"(M#=(D\)(E$)`3H"DK^_X7`#X3H_/__B4-TZ;K[__^+GP0!``"%VP^5P.G$ +XM_?__#[9%V(M-M(B!/`$``(M%W(F!0`$``.EC^___D)"0D)"0D)"0D)"0D)"0 +XM58GE5E.#[#"+70R+=0CV0S$(=%R#>P0!=%:-0T#'0T``````B40D"(M#-(DT +XM)(E$)`3HN4C^_X7`#X7"````BT,LA7<.+1?2%P'3)C5#_ +XMBT,LB5-`A7<.- +XM=@"#Q#`QP%M>7<.-M"8`````BT,\B5-(B4-$@\0P,6#[#B)7?2+70R-1>R)1"00C47PB77XBW4(B7W\B40D#,=$)`@` +XM````BT,TB30DB40D!.BVHOW_A6#[`B)'"2)="0$BT@\BW!`B4A$B7!(BT`LA/KV(GVC;PG`````%6X`0```(GE4X/L%(M=#/9#,0AT +XM`XM#!(E$)`B-0SR)1"0$BT4(QT0D#`(```")!"3HJO0``+H!````AR+61"-0P@Y`0^$D`````^V@6P$ +XM``"+<4"#X`&(1?-U7HN19`0``(G0.?!V8XGRBT7L#Z_"N@$```"#^`)V`XU0 +XM_HU'/(E4)`C'1"0,`````(E$)`2)#"3HHO,``+H!````AR+61"- +XM0P@Y`0^$D`````^V@6P$``"+<4"#X`&(1?-U7HN19`0``(G0.?!V8XGRBT7L +XM#Z_"N@$```"#^`)V`XU0_HU'/(E4)`C'1"0,`P```(E$)`2)#"3HLO(``+H! +XM````AED&O__C70F +XM`(E-#(E5"%WI-/___XUT)@!=Z3JX__^-=@"-O"<`````5;H!````B>6#[`B+ +XM30SV03$(=`.+402+030YPG,4*=")PHE!/(M!0(E11(E!2#'`R<.-032)1"0$ +XMBT4(B00DZ"QE``"X`0```,G#D(UT)@!5,<")Y5.#[!2+70SV0S$(=`:+0P2# +XMZ`&)1"0(C4,\B40D!(M%",=$)`P`````B00DZ+KA``"Z`0```(7`=0F)V.BZ +XM^O__,=*#Q!2)T%M=PU6)Y5.#[!2+70S'1"0,`@```,=$)`@`````C4,\B40D +XM!(M%"(D$).ATX0``N@$```"%P'4)B=CH=/K__S'2@\04B=!;7<.-=@"-O"<` +XM````53'`B>53@^P4BUT,]D,Q"'0&BT,$@^@!B40D"(U#/(E$)`2+10C'1"0, +XM`P```(D$).@:X0``N@$```"%P'4)B=CH&OK__S'2@\04B=!;7<-5B>564X/L +XM((M=#(MU"/9#,0AT+(M#!(DT)(E$)`3H79G]_X7`=#N+0P2)0SR)V.C<^?__ +XM,<"#Q"!;7EW#C78`C47TB40D!(DT).C1F?W_A9_?^%P'0/C78`@\0@N`$```!;7EW#BU7TA=)UM>N!D)"0D)"0 +XMD)"0D)!5B>6#[#B)7?2+70R)??R+?1")=?B+2S2+Q=PXGV==,[4T!VSHGVC;PG`````.NP +XMBU-`A=)UTH/H`8E#/(UU\(E$)`2+10B)="00QT0D#`````#'1"0(`0```(D$ +XM).AKEOW_A6#[#B)7?2)TXE-\(M-#(EU +XM^(G&BT,LB7W\BWT0BW2)1?"!BU0(`````0``QT0D%'T&"0B+AIP```"+@#`!``#' +XM1"0,A08)",=$)`BRN`@(B40D$(M%\(D\)(E$)`3H^AS]_XGYQT0D"`$```#' +XM1"0$0````(D$)(M5#(GPZ!?^__^)P^MFC78`,?^%TL=%\`````!U=,=$)!1] +XM!@D(BX`P`0``QT0D#(4&"0C'1"0(LK@("(E$)!"+1?")/"2)1"0$Z)8<_?^) +XM^<=$)`@!````QT0D!$````")!"2+50R)\.BS_?__A?:)PW0,BT80A_?^#Q"R)V%M>7UW#C47PB50D#(E$)`C'1"0$`````(DT).@T +XM//[_A(E4)`R)1"0(BT-TB30DB40D!.CR._[_AZ`0`` +XM`(GVB50D"(M5##')QT0D!"````#'!"0`````Z*/\___)PY"Z`@```.O9B?:- +XMO"<`````58GE5XG75HG&4X/L3/9",2`/A1D"``#V@$P#```!#X7<`0``BX!$ +XM`P``A<`/E<`\`1G`,=(E````^`6`B$`(@_D"#Y3"@^H!@^+P@\(_B40D#(E4 +XM)`B)?"0$B30DZ"Y7``"%P`^%M@$``(M6>(M".(7`#X2H`0``@_@%#X31`0`` +XMBT((BUX0B8.0````BT(0QX,``0``````!(F#E````(M&$(N`&`$``(7`=0K' +XM@P`!```````%BT9,B47$BT90B47,C47PB40D"(V#@````(E$)`2)-"3H!$3^ +XM_X7`#X4\`0``BX.0````B470BX.4````B47(QX.4`````````(M%\(7`#X75 +XM````BX/@````@_@!#X2B`0``@_@"#X2"`0``BT<\B30DB40D!.C.DOW_A<`/ +XMA#X!``"+1RR%P'0*]D`&(`^%T`$``(N+``$``(M=R(7;#X20`0``BT70@#AZ +XM=5V+7LA@^L!#X2O`0``@\(! +XM#[8*#[[!@_A_=PKV!(7=%`D(!'7?C4'3/`$/AE8"``"`^2L/A$T"``"`^5X/ +XMA$0"``#'1"0(/`8)",=$)`0#````B30DZ-?$_?^-M"8`````BT7$B4=$BT7, +XMB4=(@\1,N`$```!;7E]=PXVT)@````"+@$0#``"-!$#!X`(#1A"+0#B%P`^5 +XMP.D3_O__C70F`+@!````@\1,6UY?7<.-=@")3"0(,7UW#BT9,B4<\BT$``!``B5=$#X0?____BTK^___'1"00#````,=$)`P!````QT0D"#\- +XM"0C'1"0$`````(DT).AMA/W_A<`/A;7^___'1"00#````(M%R(E$)`R+1=#' +XM1"0$`````(DT)(E$)`CH/X3]_X7`#X6'_O__BT<\C5W6+10B+50Q=Z"+5>"X`0```(72#X3N````BT4,]D`Q"`^%40$``,=%W`$```"# +XM[@&-5?"-3>R)5"00B4PD#,=$)`@`````B70D!(M="(D<).B`C?W_A<`/A>T` +XM``"+3?"%R73)BUWLB5W8#[8#/'L/A+0````\#`^$K````#PN=:R#^0&0=J:+ +XM5>`/M@*$P'2L+#[9"`H/"`H3`=(B)^SC8=>\/MD(!/"`/A'X` +XM``"+7=@Z0P)UVX-MW`%UU8M%#(EP/,=`0`````"+50R+0CB%P`^%B0```(M" +XM,(-J-`$E#_[__X/(0(E",(-*,`B+70R+0T"+4SR)0T@QP(E31(/$/%M>7UW# +XMBX%0`P``C01`P>`"`T$0BT`XB47@Z>#^__^#;=P!#X7Z_O__ZY"#^0(/A7G_ +XM__^-M"8`````Z77___^+10S'0#P!````QT!``````(M5#(M".(7`#X1W____ +XMBTT,@^@!B4$XZ7____^+50R+4@2)5=SIJ/[__\=$)`0`````BU4(B10DZ(U8 +XM``"#Q#RX`0```%M>7UW#58GE5U93@^P\BT4(]H!8`P```0^$%P(``(G"BX!0 +XM`P``C01`P>`"`T(0BT`XB478!``"+50R+6C2#PP&- +XM5?"-3>R)5"00B4PD#,=$)`@`````B5PD!(M%"(D$).B4B_W_A<`/A?X```"+ +XM3?"%R73)BW7L#[8&/'MT?8M5#(MZ+(7_=!'V1P8@=`L\?71IC;0F`````#P, +XM#X2D````/"YUF(/Y`9!VDHM5W`^V`H3`=(@/ME8!B%7CBU7-U[`^V0@$\('1T.D8"==^#;=@!C78`==:%_W0F]D<&('0@ +XM@^L!D.M_@VW8`0^%./___SQ[B?8/A',!``"+30R+>2R+10R%_XE8/,=`0``` +XM```/A9T```"+10R+4#R)P8M`0(E11(E!2(/$/#'`6UY?7<.#;=@!#X7N_O__ +XMZYJ#^0*0C70F`'6"@VW8`0^%7/___XUT)@#K@(M5#(/K`3E:-`^$[@```(U% +XM\(E$)!#'1"0,`````,=$)`@!````B5PD!(M5"(D4).A9BOW_A +XM_O__D)"0D)"0D)"0D)"058GE5U93@^P\BU4,C7W8BT(TB478BT(XB47R#^`$/ +XMA,T!``"%P`^$I0$``+L!````B7PD!(M-"(D,).C$G/__A<`/A4R# +XM^`(/A.N#@_L"C;8`````=`B%VP^%_O[_ +XM_X/N`8UV``^%\O[__XE\)`2+70B)'"3HNYO__X7`=4*+=>R%]@^%9?___P^V +XM5>@[%?P@"0@/C57___^A""$)"/9$D#8"#X1%____B7PD!(M%"(D$).CMG?__ +XMA<`/A"[___^X`0```(/$/%M>7UW#@_X!#X08____B7PD!(M5"(D4).C`G?__ +XMA7UW##[95Z#L5_"`)"'T,H0@A"0CV1)`V`G47B5PD!(DT +XM).A+F/__AR%P'4K#[9%Z#PI=-T\7739/")TU3PG +XM=-$/MM`[%?P@"0A](*$((0D(]D20-@)T%(E<)`2)-"3HRYK__X7`#X7'_O__ +XMBU78.5R#^`-TY(7`#X6\````#[95Z#L5_"`)"'T,H0@A"0CV1)`V`G7$BT7$@T7, +XM`8E%V(M%R(E%W.F:_O__@/H_#X7?_O__BT70A<`/A(W^__^#;7UW#B5PD!(DT).B:F?__A<`/A#+^___I\?W__XE<)`2)-"3H89;_ +XM_X7`#X7=_?__@WWL`W3FC78`Z0O^__^#Z`$/A5/___^+5=B+1RR)5SR+5=R% +XMP(E70'1B]D`&('1#0!#X0N`0``BX*0`0``BP")@I0!``"+@9P```"+ +XM@)`!``"+0`B)@IP!``"+@9P```"+@)`!``"+0`2)@I@!``"+04")@J`!``"+ +XM042)@J0!``"+03R)@J@!``"+04`Y040/A-4```"+F9P```"-!$"+DXP!``"# +XMZAB--,*+DY`!```YUG90BP*#P`&)0AB+@9P```"+D)`!``"+@(P!``"+0`2) +XM0AR+@9P```"+@)`!``#'0"`!````BX&<````@X"0`0``&(N9G````(N3D`$` +XM`#G6=["+DY`!``"+`H/``8E"&(N!G````(N`D`$``,=`(`$```"+@9P```"+ +XM@)`!``#'0!P`````BX&<````BX"0`0``QD`N`(N!G````(.`D`$``!B+04"# +XMP`&)04")042)03Q;,7<.+F9P```#KDHVV`````(V\)P````!5B>575E.# +XM["R+11"%P`^$"`$``(M`"(E%\(M-%(M]\(7)#X2:````#[X'A<`/B(\```"+ +XM-?P@"0@YQ@^.@0```(L=""$)"(GZ]D2#-@)U&>MP#[X"A(M5&(E""(M-&(M1$(72=)2+31B+00B)5"0(B40D!`'8B00DZ'T* +XM_?_I=____XM%#(7`=12+11C'0!P`````@\0L,575E.)PX/L/(E5U(E-T,#B+5=2+3=B+4@B%R8E5Z`^$80$` +XM``^V$@^^PH7`#XA3`0``BS7\(`D(.?")=>P/C4(!``"+#0@A"0B)3?#V1($V +XM`@^$+@$``(MUZ#';BT78QT7<`````,=%X`````"-!`:)1#@[1>Q],XM-\/9$@38"="F`^@EUTX7;=`?'1>`! +XM````BU70`````=QR)^^L"B#1>0!C0P[*=$[3=QV +XMZHG8BWW)\"M%Z(T4#SG0=&HI1=B)PXM%V"G3B70D!"G>B30DB40D +XM".B*"/W_BU74*5H0*5H8BUWDBTW4@^L!@_O_BU$(=!J+=>2)T(T,%HUT)@#& +XM``F#P`$YR'7VC50:`87_=`V-!#K&`B"#P@$YPG7VBT70QP`!````@\0\6UY? +XM76#[!C'1"0(Y`<)",=$)`0"````B00DZ`*R_?_)PU6)Y5>)QU:) +XMUE.#[#SV10L!B4W8#X1>`0``BT(HA<`/A`L!``"#Z`&)0BB0C70F`(M=V(M& +XM&(M."`^V$X@4`8/``8E&&#'`@\0\6UY?7<.)T0-.$#M.#'8KC48,B40D"(M& +XM"(E,)`R)/"2)1"0$Z"TF_O^%P`^$U0(``(E&"(M5[(M%Z"G"BT8HB57['1>@`````BT7@A``````ZTT\_P^$Q@````^VP(T$0`'``T<0#[:`70$``(E%[(M5[(M%Z#G" +XM#X0)____#X-,_O__*="#1>`!A<")1>@/A/G^__^+1BB%P`^$[O[__X/H`8M6 +XM"(E&*(M%\`^V!`(\"76?C47LB40D$(M&%(E<)`R)5"0$B3PDB40D".@_N``` +XMZYR)1"0,C48,B40D"(M&"(D\)(E$)`3H,R3^_X7`#X3;````BU8@@T80`8E& +XM"(72#X2I_?__Z<+^__^+3@B+5A@/M@01B$01`>F1_?__D,=$)`3_____B3PD +XMZ$!M_?_I-____\=$)`3_````B3PDZ"MM_?_IX_[__XM%W(7`#X0Q_O__,<#& +XM1!`!((/``3M%W'7SZ1W^__^)T`-&"`^V&,8`"8U%Z(E$)!"-1?")1"0,BT84 +XMB3PDB40D"(M&"(E$)`3H>+<``(M6"(M%\(@<`NF*_O__BT7PBU8HBUW@`T8( +XM`U8@`U7@B00DB50D"(T4&(E4)`3HF03]_^G5_?__N`$```#I[?S__\=$)`3_ +XM____B3PDZ(9J_?^+3@B)PNEN_?__C;8`````C;\`````58GE5U:)UE.#[$R) +XM1#B+5`"`T(0BT`XB47,BUX8,)^"G0`47@.5X8=]^+5>`QVSE5 +XMU,=%V`````!V'8G3B=`QT@'[]_>+1>`ITSE=U`^#O````(M=U"G#BT7-=@"+1BB+?C2%P(E^$'1#@R'WBPLYT715 +XMBT,$B4$$BT,$B0B)'"3H=S/]_\=$)`@!````BT84@\`!B40D!(M%\(D$).@: +XMQ0``@_@!&=LA\^N%D(M&((7`=;:+1@C&!#@@@T8@`8-&$`&#"0CKI8M#!(E! +XM!(L+ZZ>-="8`C;PG`````%6)Y5=64X/L7(E%U(M%#(E5T(E-S,<``````(M" +XM&(M2)#G0B578#X1,`0``BUW0C4C_BW,(`"+7<"#Z0$I +XM^X/'`3M-V'12BW7`B?CWV`^V%#`/ML([1>!]#8MUR/=$AC0`!0``=3*`^E]T +XM+3M%X'W&BU7(]D2"-@)TO.L7UW#B7PD +XM!(D<).C2(/[_A<`/A+<```"+11#'``$```"#Q%PQP%M>7UW#QT0D$`$```"+ +XM0R")1"0,BT,7UW#BUW(]T2#-``%```/A%+^__^A_"`) +XM"+\!````BUW`B47<@^D!@^L!@\B+2AB+0QR#Z0&) +XMR@-3"(E%Y*$((0D(B7WLB47PZPLY2R1T)(/J`8/I`0^^`H7`>`\[1>Q]"HM] +XM\/9$AS8"=32#Q@$[3>1UUXET)`2)%"3H%Q_^_X7`=0Z+?>B##P2#Q!Q;7E]= +XMPXM%Z(,@^X/$'%M>7UW#@\(!.4WD=,PY2R1UU^O%D(VT)@````!5B>57B==6 +XM4X/L'(M"&`-""`^V$(A5\\8``(M'&(/H`8G#`U\(@#L8=#"+3QPYP70IBUNBT<8BU<(#[9-\X@,`HM' +XM""EW&(M7&"EW$(A<`O^+5RB%TG4HBU<@A=)TD(M'&`-'"`-'*(E4)`B-%#") +XM5"0$B00DZ)'\_/_I;____XM'&`-'"(E4)`B-%#")5"0$B00DZ'/\_/_KO8VV +XM`````(V\)P````!5B>575HG&4X/L#(NXG````(-X-`&)^0^$TP```(N7J`$` +XM`(E0/(N'I`$``(E&1(N'H`$``#M&1(E&0`^$Y````#G0B=-R,HM&$(E<)`2# +XMPP''1"0(`````(DT)/^0D`@``(M&$(DT)/^0;`@``#E>0'/4BXZ<````BT8\ +XMBY&,`0``C01`@^H8C03"B8&0`0``]H84`@```75RBXX,`@``AL`0`````` +XM`(/$#%M>7UW#BX8,`@``C01`P>`"`T80BU@XA=L/E,#K@(.OD`$``!CI8/__ +XM_^L-D)"0D)"0D)"0D)"0D%6)Y5=64X'LO`(``(M%"(M5"(M-"(MU%(M`$(F% +XMB/W__XN2G````(F5?/W__X&)K`0```````B#P7B+70B)C8S]__^+6W@YRXF= +XM8/W__P^$6A$``#D+#X1;"```BUT8@\,@BX6,_?__B00DZ$`M_?^)7"0,BWT8 +XMB70D!(E\)`B+10B)!"3HIB[]_X7`B85@_?__#X3H!P``BU4(BXU@_?__BT)X +XMB0&+G8S]__^)600Y6GP/A$$/``"+=0B+O6#]__^+1GB)>`2+E6#]__^+10B) +XM4'B+C6#]___'03@$````BUT(BT-,B4$4BU-0B5$8BUT8A=L/A#]``"%P`^%3P8``(M%**@0=$B+ +XM52"%TG1!B[U@_?__QT0D#`````#'1"0(`````(E\)!"+12")1"0$BU4(B10D +XMZ"7M__^%P`^%#08``(M''(E'&.L9D(UT)@"H`@^%"`8``(N=8/W__XM#&(E# +XM)/9%*D!T(8NU8/W__P^V31R+1AB+5@B(#`*#P`A`!@T8D`8E&&/9%*`@/ +XMA6(&``#V12M`QX6@_?__`````'0OBWT(]H>0!````0^%>08``(M5"(N"B`0` +XM`(7`#X2"!@``BTT(BTDX*<&)C:#]__^+O8C]___'1=P`````]H=4"````0^$ +XMB@4``/9%*@3'A9#]__\"````#X1V!0``BU4H]\(````"=!:)T"7__W__B44H +XMB<+'A9#]__\`````B="+30@E````"(/X`1G`@>(```0`]]"#X`.#^@&+E6#] +XM__^(A:C]__\9P/?0@^`$B47@BT(4B4%,BT(8B4%0QT0D!`$```")#"3H?J0` +XM`(7`#X76!```BUT,]D,Q(`^$QP@``,>%F/W__P````#'A%I/W__P````#'A=3]__\`````QX64_?__`````,>%P/W__P`` +XM``#'A)O83]__^+M=3]__^%]G0:BY6$_?__@'H,(`^$ +XM!Q\``,>%U/W__P````"+C83]___V010(#X68"P``@[V8_?__`@^4PH.]F/W_ +XM_P0/E,&$TG4$A,ET3(M%X(/@[_9%*@2)1>!T!H/(!(E%X(32=!6+G83]__^+ +XM0Q"#Z!"#^`$/AM8B``"$R700BX6$_?__@W@0#`^%8R,``,>%F/W__P````"# +XMO%`D(`74@BY5@_?__BT4(Z)7X +XM__^%P`^%$`<``,>%R/W__P````"+G83]__^+2Q"#^10/AD@'``#V12A`#X32 +XM"@``BX6$_?__#[90##L5_"`)"`^-:0T``*$((0D(]D20-0(/A%D-``"#^0H/ +XMA%`-``"#^0\/A$<-``#'1"0(<`@)",=$)`0"````BU4(B10DZ+2?_?_V12L" +XM#X65#```BXV@_?__A%S/W__P````"+A7S]__^+@%P!``"% +XMP`^$@@P``(M-"/:!KP0``!!U*HN%Q/W__X7`=2#'1"0(`````,=$)`0````` +XMB0PDZ'1X``"%P`^%+`(``(N%H/W__X7`=1"+70B+0Q"+@!@!``"%P'4UB[5@ +XM_?__BWT(BT84B4=,BT88B4=0,<"#O:#]__\`B3PD#Y7`B40D!.B%H0``A<`/ +XMA=T!```/MH6H_?__J`*)A5S^__\/A/T```"+50B#>C0!#X3I````BXU@_?__ +XMBTD8@_D!B8TX_O__#X;<&P``B[5@_?__BUX(B[4X_O__#[9$'O\\7(B%/_[_ +XM_P^$#AL``(M5"/:"?`,```$/A+<:``"+@G0#``"-!$#!X`(#0A"+4#@/OH4_ +XM_O__B10DB40D!.B`\/S_A"(MV&(FU./[__P^V1![_B(4__O__#[:5 +XM/_[__SH3#X6O&```@[TX_O__`G0+@'P>_EP/A)L8``"+30R+432+03B)442) +XM04B`I:C]___]]D4K`@^%4OS__^D=!0``#[:%#/___SGP#X0N&@``.<,/A0(7 +XM``"#K2#^__\!#X7U%@``BY7\_O__.Y5X_O__#X(&_O__#X6;)@``BX4`____ +XM.X5\_O__#X+N_?__BTT(B5%,B4%0QT0D!`$```")#"3H]9\``(7`=5&+70CV +XM@UP"```!#X1-)@``BX-4`@``C01`P>`"`T,0:T`X9,=$)`Q`````B40D",=$ +XM)`0`````BWT(B3PDZ/]@_?^%P`^$A_W__XVT)@````"X`0```('$O`(``%M> +XM7UW#BXU@_?__BT$8QT$D`````(E!'.GL^?__QX60_?__`````.E[^O__BUT8 +XMB[U@_?__@\,@.5\,#X*6]___BY5@_?__A?;'0B@`````QT(D`````,="(``` +XM``#'0AP`````#X3#"```BTT8B4H0B4PD"(ET)`2+0@B)!"3H%?+\_^F_]___ +XMBT48B[U@_?__*=")1R#I]_?__XN=8/W__XM#"(M3&,8$$""#0Q`!@T,@`<=$ +XM)`@#````BT,4B40D!(MU"(DT).CGM0``Z6?Y__^+AX@$``"-!$#!X`(#1Q"+ +XM0#B%P`^%?OG__XM="/:#A`0```$/A!((``"+@WP$``"-!$#!X`(#0Q"+0#B) +XMA:#]___I7_G__XN]8/W__XM'&`-'"(T,&(M%"/:`#`$```$/A/4=``")PHN` +XM!`$``(T$0,'@`@-"$(M0.(72#Y7`A,!T08N%G/W__X7`=##O93]__\"#X15(```B70D +XM$(N-8/W__XM!&(E,)`C'1"0$`````(E$)`R+70B)'"3HPN3__X7`#X5-`0`` +XMQX64_?__`````(M&'(E&&(N%T/W__X7`#X3(````BX5@_O__A$(N-8/[__P%.&(N=,/[__XE>*(N]+/[__XE^(,>%T/W_ +XM_P````"+?BB%_W4LBUX@A=MU)8M&$(/``3M&#`^'("```(--*`B+5@B+1AC& +XM!`(@@T8@`8-&$`''1"0(`@```(M&%(E$)`2+50B)%"3H-[,``(N-8/[__XFU +XM8/W__XF--/[__X7`#X1S^?__BU4(BT)XBU@4ZPF)]H7;=!J#ZP&)7"0$BTT( +XMB0PDZ$IF_?^%P'3FA=MU!;L!````BW4(N`$```"#CJP$``!`B5Y,QT90```` +XM`('$O`(``%M>7UW#_R2-J`@)"(UUM,>%F/W__P````#'A%I/W__P````#'A=3]__\`````B;6$_?__QX64_?__`````,>% +XMP/W__P````#'A`7`$```````#'@%@!````````QX!4`0`` +XM`````(E<)`2+50B)%"3HM(4``,=$)`0!````BTT(B0PDZ(&:``#'A<3]__\` +XM````B[V$_?__@W\("P^&UP,``(N=A/W__XE<)`2+=0B)-"3HDE;]_X.]D/W_ +XM_P(/A!,+``#V1>`$=`KV12H"#X7-!0``]D4H")!T$8N]8/W__XM/((7)#X7P +XM!```]D4K`0^$R@```(N%8/W__XMP*(7V#X3^````BU4(,=N+2GB)RNL2BT(0 +XM`T(LBQ(!PSF5C/W__W03.Y5@_?__=>:+O6#]__^+1QCKX3E=&`^&C````(U% +XMT,=$)!``````B40D#,=$)`@#````BT$4B40D!(M%"(D$).AO8OW_A(F%$/[__P^% +XMCP0``,=%T`````"+0Q")1"0,BT,(B40D"(M#%(E$)`2+30B)#"3H.F;]_X7` +XM#X6U_/__BU70A=(/A3,0``"+`$=!?V12H"=!&+E6#]__^-3>"+10CH;NS__XN%D/W__X7`="R+O83]__\/ +XMMD\,#[;1.Q7\(`D(#XS)`0``@/E?QX60_?__`0````^$R0$``(M%*(G9B00D +XMBY5@_?__BT4(Z&+B__^%P`^%/?O__X.]F/W__P,/A``)``"+O>[__X-O$`&#;R`!Z0/[__^)P2G1Z4KZ___'1"0(!P```,=$)`0````` +XMBTT(B0PDZ`PI``#II?K__XET)`2+50B)%"3H"(```(7`#X2G^?__Z3OU__^+ +XM10B!B*P$````!```N`$```#I*?7__XN-I/W__X7)#X5E!P``BT4HJ0````(/ +XMA5<'``"+O83]__^`?PP`#X5'!P``BY5\_?__BY)$`0``A=(/A(_^__\E__]_ +XM_PT````"B44HQX60_?__`````.E9\/__BY5@_?__C4W@BT4(Z#?I___I'?K_ +XM_XM%"(U-T(G:Z#7=___I9OO__XE$)`R)T(/`#(E$)`B+0@B)1"0$BTT(B0PD +XMZ.$%_O^%P`^$'/C__XN=8/W__XE#".G+_?__B[5@_?__BT88.T8<#X<(\?__ +XM]D4H$`^$_O#__\>%E/W__P,```#I[_#___9%*00/A.7P__^+E6#]__^Y`0`` +XM`(M%".ACXO__A<`/A;[W___IM?S___9%*!")]@^$N?#__XN]8/W__XM?&(7; +XM#X0/\?__@[V4_?__`0^$LA,```^#.A$``(NU8/W__XM&'(7`#X2$\/__`T8D +XM.<,/AWGP__^+10@QR8GRZ/[A___IS_#__XN=8/W__XM#&#M#'`^'5O#___9% +XM*!`/A$SP___'A93]__\!````Z3WP__^+O6#]__^+7QB%VXG9#X3?"@``BX5@ +XM_?__.4@D#X.D!0``BY5@_?__BT("-7PS'A9C]__\#````@\@0@^#[B47@ +XMZ8#Z__^+C6#]__^+41B%T@^$MPD``(N=8/W__SM3)`^&4`0``(NU8/W__XM& +XM'(7`=`8YPHG!=Q"+O6#]__^+3R3'1QP`````BY5@_?__BT(H`T(8*E!____B[U@_?__BT<8BU%S/W__P$```#I&>[__XM%*&:%P`^)#>[__X-] +XM)`$/AA\5```E__]__PT````"@VTD`:@!B44H#X7A%```J0````%T&HNU8/W_ +XM_XM&*,=&*`````")1B"!92C____^QX60_?__`````,>%I/W__P````#IDNS_ +XM_XNU-/[__XFU8/[__XM5*/;&"`^$F@4``('B```"``^%Z0H``(M5"/:"KP0` +XM``$/A?0-``"+C6#]__^+01@[021W!\=!.`(```#VA:C]__\"#X3^!P``BYU@ +XM_?__BT,D@\`!.4,8#X+I!P``QT,X!0```(NU8/[__XFU-/[__^G,]?__QX7( +XM_?__`0```.GZ]___BY5@_?__BT4(Z('E__^%P`^%_//__\>%R/W__P````#I +XMV_C__\=$)`@#````BT,4B3PDB40D!.CSI@``A<`/A'KW___IR?/__XVV```` +XM`(G(@\`,B50D#(E$)`B+00B)1"0$BW4(B30DZ&$!_O^%P`^$^>___XN]8/W_ +XM_XE'"(M%T.GSZ/__BXU@_?__BT74`T$(B50D"(/``8E$)`0!V(D$).AKXOS_ +XMZ>+H__^-!!.%VXE%U`^$,^G__XGPC1P>Q@`@@\`!.=AU]ND?Z?__B[6$_?__ +XMC5X,Z:3W__^+52CWP@````(/A=[T__^+G8C]___V@U0(```!#X3+]/__BYV$ +XM_?__C47<@>(```(`B40D"(U%V(E$)`2)%"2+E6#]__^+10B#PPR)V>@@X?__ +XMA<`/A=OR__^+1=B%P`^$B/3___9%*H`/A#GL__^+M:3]__\IQHGP@^@!B86D +XM_?__Z2'L__^+52CWP@````(/A=/V__^+A8C]___V@%0(```!#X3`]O__C47< +XM@>(```(`B40D"(U%V(G9B40D!(D4)(N58/W__XM%".BBX/__A<`/A5WR__^+ +XM1=B%P`^$AO;___9%*H`/A+OK__^+E:3]__\IPHG0@^@!B86D_?__Z:/K__^+ +XMA6#]__^#:!@!@T`H`>GM]O__C47DB40D!(M5"(D4).C(CP``A<`/A0/R__^+ +XMC:#]__\[3>0/A_#V__^+72B+M6#]__^+O6#]__^A""$)"(F=%/[__XMV&(GQ +XM@^D!B;4<_O__B!4Y\'T1B[T8_O__]D2'-@(/A>,.``"+O6#]__\Y +XM3QQUQ,=%V`````#I9_;___9%*P(/A=3J__^+10CH5MC__^G'ZO__B[V8_?__ +XMA?\/A?$```"+32CVQ0$/A)($``"+70@/MI-4`0``@^(!#X2&"```BX-,`0`` +XMC01`P>`"`T,0BW`XA?8/E<"$P`^$8`0``(32#X1B#```BWT(BX=,`0``C01` +XMP>`"`T<0BT`XBYV$_?__#[X`#[93##';.=`/E,.!X0```0`/A!P$``"+=0@/ +XMMI;``0``@^(!#X0$"```BX:X`0``C01`P>`"`T80BT`XA<`/E<"$P`^$Z@,` +XM`(32#X3E"P``BU4(BX*X`0``C01`P>`"`T(0BT`XB[6$_?__#[X`#[96##G0 +XM#Y3`#[;0@^L!#X1A!@``@^H!#X3[!P``BY6$_?__]D(4`0^$AP,``(.%P/W_ +XM_P&!O<#]__\``0``#X^@!P``]D4J@`^$$NC__XN=I/W__XNU?/W__X/#`6O# +XM'#N&2`$```^'4PD``(NUA/W__XN%?/W__VN5I/W__QR+B$0!``"+!HD$"HM& +XM!(E$"@2+1@B)1`H(BT8,B40*#(M&$(E$"A"+1A2)1`H4BT88B40*&(F=I/W_ +XM_^FAY___QT0D!/____^+10B)!"3HK4;]_^GAY/__A<`/A$0%```YT`^&(/[_ +XM_XU0_XN%8/W__XE0&`^VC:C]__^#X0)T#8N=8/W__XM#",8$$""+M6#]__^+ +XM1AR#1B@!.488C__^DR^?__QT0D!/____^+30B)#"3H +XM.T3]_XG!Z>?D__^)1"0,B="#P`R)1"0(BT((B40D!(M-"(D,).C%_/W_A<`/ +XMA`#O__^+G6#]__^)0PCI"/3__X.]D/W__P(/A(\%``"+G9#]__^%VP^%:P0` +XM`/9%X`1T"O9%*@(/A04*``#V12@(=!6+G6#]__^+2R"%R70(@VL0`8-K(`&+ +XMM6#]__^+1A")1C2+1AB)1C")1A#'1"0(`P```(M&%(E$)`2+?0B)/"3HFJ$` +XM`(7`#X5U[O__BT8@QT8L`````(M>*/9%*P&)A9S]__\/A-KK__^%VP^$TNO_ +XM_XM.&`-."`^^$872#XA`[/__.17\(`D(?S+I,^S__XN58/W__X/!`8-"+`&# +XMZP$/A,4)```/OA&%T@^($NS__SL5_"`)"`^-!NS__Z$((0D(]D20-@)UQ^GU +XMZ___D(NU8/W__XM&%(E#3(M&&(E#4,=$)`0!````B1PDZ,Z)``"%P`^%)NK_ +XM_XV%>/[__\=$)`P#````QT0D"`````")1"0$B1PDZ)2;``"%P`^%_.G__XM& +XM%(V]_/[__XF%_/[__XM&&(/H`8F%`/___XE\)`2)'"3H!6?__X7`#X7-Z?__ +XM#[:%#/___S';QX4@_O__`0```#PI#[;P#Y7#@^L!@^.MB(4G_O__@\-[C97\ +XM_O__B50D!(M-"(D,).B^9/__A<`/A8;I__^+A1#___^%P`^$O.C__X/X`G0% +XM@_@$=%F/W__P(```#I,>;__\>% +XMP/W__P````#I@?S__S'2Z4'\__\QV^G*^___BT4(@:"L!```____]^E<\O__ +XMBX5@_?__BW`DBT@8QT`<`````.F#]?__QT0D"`,```"+0Q2)1"0$BW4(B30D +XMZ'J?``"%P`^%5>S__^FF[___BXU@_O__B8TT_O__Z>KM__^-12B)^8D$)(N5 +XMC/W__XM%".B6V?__A<`/A"'L__^+2!B)A6#]___I]?3__XU%*(D$)(N5C/W_ +XM_XM%".ALV?__A<`/A/?K__^+4!B)A6#]___I'_;__XM]"(NU8/W__XN'G``` +XM`(M>%&:!B,@!``"``(GX@:>L!```____Y^A:WO__A<`/A1+H___VA5S^__\! +XM#X1W!0``BT4,BU`TBT`XB95X_O__B85\_O__N$````"+O6#]__^+5PB`.B\/ +XMA&D(``")1"08QT0D%`````"+C6#]__^+01B#Z`&)1"00C4(!B40D#(M%#(/` +XM1(E$)`B-A7C^__^)1"0$BW4(B30DZ`?-_?^%P`^4P(3`#X3P!```BWT,BU4( +XMBT=$B4),BT=(B4)0@*6H_?___HM"$(NX&`$``(7_#X2N"@``BT4(Z`C-__^% +XMP`^%4.?__XM-"(N!G````&:!H,@!``!__XN!G````(&)K`0``````!B+M6#] +XM__^+@)`!``"+`(E&%(N!G````(N`D`$``#D8#X0^YO__QT0D#`````#'1"0( +XM`````(E$)`2)#"3HO4L``(7`#X7EYO__BWT(BT<0QT0D!`````")/"3_D)@( +XM``#I_N7__\>%D/W__P$```#IAOO__XM-"(N1=`,``.E-Y?__C44HB00DBXU@ +XM_?__BY6,_?__BT4(Z*+7__^%P(F%8/W__P^%FN/__^DBZO__@X4@_O__`>G0 +XM_/__@_X"#X2?Y?__@'P>_EP/A93E___IV>3__X72=!*+O6#]__^+1Q@[1R0/ +XMA8GY__^+A6#]___'0#@!````Z8#K__^H!`^%NP,```^VE:C]__^+A6#]__^# +XMX@*+2!B)E4#^__\YS@^"_0,```^VA:C]__^#X`*)A4#^___I>O/__\=$)`@# +XM````B[U@_?__BT<4B40D!(M%"(D$).B4G```A<`/A6_I___I^O3__XM=#(M3 +XM-(M#.(E31(E#2.GHY/__]\(````"#X7>_O__B[V(_?__]H=4"````0^$R_[_ +XM_XN=A/W__XU%W('B```"`(E$)`B-1=B)1"0$B10DBY5@_?__BT4(@\,,B=GH +XM1-?__X7`#X7_Z/__BT78A<`/A(C^__^+E6#^___V12J`B94T_O__#X11XO__ +XMBXVD_?__*<&)R(/H`8F%I/W__^DYXO__C78`QX74_?__`````.DGXO__BWT( +XMBX>X`0``A<`/E<#I`/C__XMU"(N>3`$``(7;#Y7`Z7[W___'1"0$`0```(M- +XM"(D,).@X0/W_A<`/A2,'``#V12L"QX7`_?__``````^%9^[__^G-X?__BY5@ +XM_?__BUH8QX7<_?__`````,>%Q/W__P````"#^P$/A,H&``"+M6#]__^+/?P@ +XM"0BA""$)"(MV"(F]9/W__XF%V/W__\>%6/[__P````"-3![_B;5T_O__ZP@Y +XM1R1T0(/I`0^^$8G8*X58_O__@^@!A=)X&3N59/W__WT1B[78_?__]D26-@(/ +XMA9,'``"+O6#]__^#A5C^__\!.4<<=;N)RRN==/[__XN58/W__XM"$(/``3M" +XM#'8SB40D#(G0@\`,B40D"(N-=/[__XE,)`2+=0B)-"3H._7]_X7`#X1VY___ +XMB[U@_?__B4<(BX5@_?__`U@(B9UP_O__`YU8_O__B9UL_O__#[8SQ@,JC9UX +XM_O__QT0D&`````#'1"04`````,=$)!``````QT0D#`````#'1"0(`````,=$ +XM)`0`````B1PDZ!M.__^)7"0$BU4(B10DZ!Q#_O^%P`^%]^;__XN%6/[__X/` +XM`8E$)`R+C7#^__^)7"0$B4PD"(M="(D<).A^4?[_A<`/A#0'``"+E6S^__^) +XM\(@"Z2W@__^-M"8`````B40D#(GP!4@!``")1"0(BX9$`0``B40D!(M]"(D\ +XM).A,]/W_A<`/A(?F__^)AD0!``#I=O;__\=$)!`$````QT0D#`$```#'1"0( +XME@@)",=$)`0`````B10DZ)%`_?_IW_'__X.]E/W__P,/A'4#``#H#M'\_X"- +XMJ/W__P'I+OO__XMU#(M&2(M61(F%?/[__[A(````B95X_O__Z83Z__^-4?^+ +XMC6#]__^#02@!B5$8#[:=J/W__X/C`HF=0/[__W0'BT$(Q@00((N]8/W__XM/ +XM&(M'"`^^5`'_A=(/B!S\__\[%?P@"0@/C1#\__^A""$)"/9$D#8"#X4GW___ +XMZ?O[__^+E6#]__^+0@@/MEP!_P^^TX72>!P[%?P@"0A]%*$((0D(N0$```#W +XM1)`T``4``'4(,"+10CHCM7__^GE]?__BTT(BX&X +XM`0``Z2+T__^+50B+@DP!``#II?/__XNU8/W__X-N&`B@!B[V$_?__QX68 +XM_?__`````(U?#.D/Z?__BUT(BX,$`0``A<`/E<#I$>+__XNUG/W__X7V#X1( +XMXO__#[X1A=(/B#_B__\Y%?P@"0A_-NDRXO__B[5@_?__@\$!@T8L`8.MG/W_ +XM_P$/A!;B__\/OA&%T@^(#>+__SL5_"`)"`^-`>+__Z$((0D(]D20-@)UP^GP +XMX?__C5@,QX68_?__`````.F"Z/__BX5@_?__BU`%:/___P````")5"0, +XMB40D",=$)`0`````BWT(B3PDZ#[Q_?^%P(G"#X1WX___B85D____BT8%E/W__P(```"+7AB)A6S___^)A7C___^+ +XMC6#]__^+00C&1`/_((M!*`-!&"M!),=!'`````")02B+022)01CIAMS__XE$ +XM)!C'1"04`````(M'&(/H`8E$)!"-0@&)1"0,BT4,@\!$B40D"(V%>/[__XE$ +XM)`2+10B)!"3H1,G]_X7`#Y3`Z9CW__^+E6#]__^+0AR%P`^$R-O__P-")(/` +XM`3G##X>ZV___QX64_?__`````.E@____]H44_O__"(U"`8F%*/[__P^$WP$` +XM`(N%8/W__XN]8/[__XM8((/K`8F=+/[__XMP*"F]'/[__XN='/[__XFU,/[_ +XM_XE8&(NU8/W__XM&$(/``2M&("M&*,=&(`$````I^(E&$(N%8/W__\=`*``` +XM```/OAJ%VWAP.1W\(`D(?FBA""$)"/9$F#8"=%R+G6#]__^#:Q@!@VL0`3M+ +XM''1)B[5@_?__B=,[3B1U-.LZ.Q7\(`D(?3*A""$)"/9$D#8"=":+O6#]__^# +XMZ0&#;Q@!@V\0`3E/''00@^L!.4\D=`@/OE/_A=)YQHN%A/W__\=%V`$````/ +XMME`,.Q7\(`D(?26A""$)"/9$D#8"=!G'A=#]__\!````QX74_?__`0```.GA +XM[/__QX70_?__`0```.G2[/__BTH(,-O'A5C^__\`````B8UT_O__Z9_Y___' +XM1"0(,`@)",=$)`0#````BUT(B1PDZ%)Z_?_IO?C__XER>.EWW___B70D$(N% +XM>/___\=$)`0`````B3PDB40D#(V%7/___XE$)`CH;<3__X7`#X7XX/__A?\/ +XMA(P#``"+5Q"%T@^$@0,``(N%9/___SM"=`^$60,``(D$).C_T/S_QX64_?__ +XM`````.E\W___#[:5J/W__X/B`HF50/[__^F-ZO__B[U@_?__BX5@_?__BYU@ +XM_O__B[5@_?__BW\@B;TL_O__BT`H*9T<_O__B[T<_O__B84P_O__B7X8BX4L +XM_O__QT8@`````/?8*T8H*=@!1A#I&O[__\=$)`0`````B10DZ$)\``"%P`^$ +XM.O7__^F5W/__C5D!*YUT_O__Z7GX__^)1"0,C48,B40D"(M&"(E$)`2+10B) +XM!"3HRNW]_X7`#X0%X/__B48(Z;/?__^+G33^___'A:3]__\`````QX60_?__ +XM`````(F=8/[__^E`Z___B[U@_?__BT<8.T'__XN58/W__XM")(/``3E"&`^"3.'__\=".`4```#I0.'__XN-\/[__XGP +XMBYWL_O__BY5L_O__A#]__^)G03^__^(`G4BBX7<_?__A<`/A=38__^+ +XM30B+01")#"3_D&0(``#IP-C__X/I`0^$_P$``(M5"(N-!/[__XM2$(F5`/[_ +XM_XL!BP")A4C^___'1"0$+P```(D$).@IR_S_A<`/A+#]__\KA4C^ +XM__^#ZP&#P`&%VXF%[/W__XF=#]__\QVX/J`HF5:/W__^LDC70F`#N=:/W__W0]BXT$_O__B[7L_?__BT29 +XM"(/#`3MP"'<;B[WL_?__BS"+C>S]___\.?^+O4C^___SIG3%QX7L_?__```` +XM`(N%X/W__XN-!/[__\>%3/[__P8```"%P`^.6`0``(NUX/W__XF-5/[__\>% +XM:/[__P````"+E>S]__\#E4C^__\/M@*$P'1XB=/'A?3]__\`````ZR:+50@/ +XMML"-!$`!P`-"$`^V@%T!```!A?3]__\/MD,!@\,!A,!T,#S_==;'1"0$_P`` +XM`(M-"(D,).CY-/W_Z]:)="0$BW4(B30DZ.@R_?_IY?#__XUV`(N=]/W__SF= +XM:/[__W,&B9UH_O__@^X!#X2"`P``B[U4_O__BT<$@\<$BP")O53^__^)A4C^ +XM___I3?___XMU"&N&5`(``&3IM]G__XN%`/___^ELV?__@:)4"```__[__\>% +XME/W__P````#I(=S__XN%9/___^F#_/__BX7@_?__@^@!B85P_?__Z;W^__^+ +XMA>S^__^+`(L`B85$_O__B00DZ`[._/\YA5C^__^)PP^$P````(N%6/[__XNU +XM1/[__X7`#Y7`#X6&````A=MT1XN-8/W__XM!*(7`=1/I`0$``(MX*(/&`87_ +XM#X3S````#[8&B[UP_O__B`>+A6#]__^#QP&)O7#^__^#:"@!@T`8`8/K`77+ +XMB[5P_O__B;5L_O__Z6P!```/M@:#ZP&#Q@&+O7#^__^(!X/'`8.M6/[__P&) +XMO7#^__\/E<`/A'K___^%VW72A,`/A&[___^+A6#]__^+E5C^__\I4!@!4"CI +XM5____XNU1/[__SG`B<&+O7#^___\\Z8/A2?___^+A=S]__^%P`^%J]7__XV% +XM_/[__XE$)`2+A43^__^)!"3HH3]__^-7#,!B9UL_O__@[W@_?__`0^%IM3__XV%_/[__XE$)`2+ +XMA>S^__^+`(L`B00DZ)C'_/^%P`^%@M3__P^WA03___\E`/```#T`0```#X5K +XMU/__B[U@_?__BT%W/W__P$```#I +XM//+__XE$)`R)^(/`#(E$)`B)7"0$BT4(B00DZ!'H_?^%P`^$3-K__XG"B4<( +XMZ6O___^+M6#]__^#Z`&)1BCKGXN%X/W__XN5!/[__XT,@HN%:/[__[JKJJJJ +XM]^+!Z@*-%%*-5!(&B95,_O__BUT(BY.L!```QX7H_?__`````/?"````$'06 +XM@>+____OB9.L!```QX7H_?__`0```(MU"(M&.#F%3/[__P^'Q0$``(/H`3'2 +XMB[W@_?__][5,_O__.?B)A7C]__\/@@@#``#'A?#]__\!````BY7P_?__,<#' +XMA?S]__\`````P>("B95L_?__BY5X_?__A=(/A"T!``"+G?#]__^+O03^___' +XMA?C]__\``````<.--(>)G5#^___ID@```(D<).AVR?S_BX4`_O__]H!4"``` +XM!`^%U@$``(N54/[__SF5X/W__P^&V@```,=$)`Q/C0@(BX5,_O__*X4(_O__ +XMQT0D!'Z?"`B)1"0(BTT(B0PDZ"*C_O^+G0#^___V@U0(```$#X6&`0``@X7X +XM_?__`8N]\/W__XN%>/W__P&]4/[__P.U;/W__SF%^/W__W1UC570B50D"(L& +XMBP`#A>S]__^)1"0$BTT(B0PDZ#AE_?_'1"0$GZT("(E$)`B+?0B)PXD\).BO +XMHO[_BTW0A#]__^%P'XY +XMBYW@_?__ZPN-M@````"#ZP%T)HET)`C'1"0$?>D("(M5"(D4).C4H?[_BXT` +XM_O__]H%4"```!'35BWW0A?]T(HM="(7;=!.+70B+0Q"%P'0).7!T#X1C`0`` +XMB30DZ*#'_/^+M0#^___VAE0(```$#X0&`0``BYT`_O__@Z-4"```^XN%Z/W_ +XM_X7`=`V+=0B!CJP$```````0BX7L_O__B[W@_?__BQ"--+B+6@B+$HF5=/W_ +XM_XN5L:C70F`(N]=/W__P^V!!,Z!#MU!X/#`3G+=>J+A7#]__^#[@2# +XMZ`&)A7#]___KG8N-=/W__\>%Q/W__P$```")C43^___I?_G__XN%X/W__S'2 +XM][5X_?__@_H!@]C_A<")A?#]__\/A>#\___'1"0$)KH("(M%"(D$).@&H/[_ +XMBY4`_O__]H)4"```!`^%^O[__XM-"(D,).B8G_[_Z??^__^)1"0,BL```"+@YP```"+@)`!``"+`(&+K`0``````!#'0U``````B4-,BU44 +XM@)QU:)SE.#["R%P(E5W`^$Y@```(M8$(7;#X3;````]H-5"``` +XM`0^%S@```(M5"#E3>`^"3@$``(M+=(E-X(M#>(E%\(&+5`@````!``"+10B) +XM="0$B40D"(M5X(D4).@\P_S_BTW@BT40BU7@`U4,C5P!`3G:7UW#BT4(QT7P`````,=% +XMX`````"%P`^$.____XM%",=$)`0`````B3PDB40D#(U%\(E$)`CH*^']_X7` +XMB47@#X42____NP$```#KK8M5"+L!````B50D#(M-X(E,)`B+1=R)/"2)1"0$ +XMZ+<\_?^%P`^%8?___^E:____@:!4"```__[__X/$+(G86UY?7<.-0WB)5"0, +XMB40D"(M#=(D\)(E$)`3HO.#]_X7`=)B)0W3IC/[__U6)Y5=64X/L+(MU#(M> +XM-)"-1>R)1"00C47PB40D#,=$)`@!````B5PD!(M%"(D$).B+-_W_A575E.#["R+10SV0#$(BW@TBW`X#X7`````QT7@`0`` +XM`(U%\(U-[(E$)!")3"0,QT0D"`````")?"0$BT4(B00DZ-@V_?^%P`^%H``` +XM`(M5\(72=1F+10S'0$@`````@VW@`71%,?;KN)"-="8`BT7@`?`YPG='BTT, +XMC5K_B=`I\"E%X(E92(M-[(D4)(GZB5PD"(ET)`2+10CH#_W__X7`=56+5>"% +XMTG4FBT4,B7A$,<"#Q"Q;7E]=PXUT)@"+30R-6/^)04C'1>``````Z[>#QP$Q +XM]NE'____BTT,BTD$A`/A3;____KO9"#_P%T$H/O`>NR@\0LN`$```!; +XM7E]=P\=$)`@!````QT0D!`````"+30B)#"3H/@$``+@!````ZXN0D)"0D)"0 +XM58GE4X/L!(M-"(M=#(N1G````(M!+(F"@`$``(M1'`^V0EB$P'@@@\B`B$)8 +XMQT(T`@```(U#1(E%#(E-"(/$!%M=Z:E%_?_V0S$@=0\QP(-Z-`(/E<"#P`&) +XM0C2+0C2#^`%T"H/X`G3+Z(:[_/^-0T2)10R)30B#Q`1;7>GO0/W_ZPV0D)"0 +XMD)"0D)"0D)"058GEBU4(BT4,QT!(`````(M"'(!(6("+0AS'0#0"````B54( +XM7>DV0_W_D)"0D)"058GE5E.+30R+50B#Z0&#^?]T00^^`H7`>$.+-?P@"0@Y +XM\'TYBQT((0D(]D2#-@)U&^LJ#[Y"`87`>"(Y\(UV`'T;@\(!]D2#-@)T$8/I +XM`8/Y_W7?6[@!````7EW#6S'`7EW#C;8`````C;PG`````%6)Y8/L&(M%$(M5 +XM"(M-#(/X!W8"RFN:/W_QT40 +XM8`H)",=%#`(```")50C)Z9=H_?_'11!["@D(QT4,`@```(E5",GI@&C]_X/X +XM!0^5P`^VP(/``HE,)`S'1"0(E@H)"(E$)`2)%"3H7&C]_\G#B4PD#,=$)`BP +XM"@D(QT0D!`,```")%"3H/FC]_\G#C;8`````C;\`````58GE@^P8BT4(QT0D +XM"(P)"0C'1"0$`@```(D$).@/:/W_R<.-M@````"-O"<`````58GE@^P8BT4, +XMAQT0D"-@)"0C'1"0$`@```(M%"(D$).C39_W_R<.0QT0D"*P) +XM"0C'1"0$`@```(M%"(D$).BU9_W_R<.-=@!5B>6#[!B+10C'1"0(O@H)",=$ +XM)`0"````B00DZ(]G_?_)PXVV`````(V\)P````!5B>6#[#B)7?B+70R)=?R+ +XM=0B%VW1:C47TB40D$,=$)`P`````QT0D"`$```"+`XDT)(E$)`3H]3+]_X7` +XM=2.+1?2#Z`$Y0P1T)L=$)`@$"@D(QT0D!`(```")-"3H'F?]_XM=^(MU_(GL +XM7<.-="8`B30DQT0D"`,```#'1"0$`````.CH_?__BUWXBW7\B>Q=PXVT)@`` +XM``"-O"<`````58GE@^PHB5WXBUT,B77\BW4(A=MT&HU%](E$)`2)-"3HJS3] +XM_X7`=1^+`SM%]'(BQT0D"`(```#'1"0$`````(DT).B(_?__BUWXBW7\B>Q= +XMPXDT),=$)`@H"@D(QT0D!`(```#H=F;]_XM=^(MU_(GL7<.0D)"0D)"0D)"0 +XMD)!5B>575HG&4XG+@^P\B57,QT70`0```/9",0AT!HM"!(E%T(M5S(U-W(M" +XM-(E%W(M".(E%X(E,)`2)-"3HCT;__X7`#X47`0``BT7PAP[%?P@ +XM"0@/C0T!``"A""$)"/9$D#8"#X3]````C57#??`$=9"+3"+3"+??"%_P^%Y?[__P^V5>P[%?P@ +XM"0@/C>S^__^A""$)"/9$D#8"#X3<_O__Z<#^__^A""$)"&8Q__=$D#0`!0`` +XM=0Z`^5\/E<`/MOB0C70F`(U-W(E,)`2)-"3H\4+__X7`#X5Y____BUWP@_L$ +XM#X0,____A=MU/P^V3>P/MM$[%?P@"0A]#*$((0D(]D20-@)U)(7_#X6F```` +XM.Q7\(`D(?0^A""$)"/=$D#0`!0``=9^`^5]TFHM%T(7`#X0"____A=MU&`^V +XM5>P[%?P@"0A]+:$((0D(]D20-@)T(8U5W(E4)`2)-"3HA$7__X7`#X7L_O__ +XM@WWP!`^$@?[__X-MT`&#?=#_#X1S_O__BU7POP$```"%T@^%-/___P^V3>P/ +XMMM$[%?P@"0@/C`'___^`^5\/E<`/MOCI$____XUV`#L5_"`)"'T3H0@A"0CW +XM1)`T``4```^%6____X#Y7P^%[/[__^E-____BT7@.T$XD`^%&_[__XG(@\`T +XMB40D!(DT).A9^___N`$```#I5/[__S'`Z4W^__^%R0^%W_W__^DB_O__C70F +XM`(V\)P````!5N0$```")Y8M%"(M5#%WIO/S__XVV`````(V_`````%4QR8GE +XMBT4(BU4,7>F?_/__ZPV0D)"0D)"0D)"0D)"058GE5XG75HG&4XG+@^P\QT70 +XM`0```/9",0AT!HM"!(E%T(M'-(E%W(M7.(U%W(E5X(E$)`2)-"3H(T/__X7` +XM#X4+`0``BU7PA=)U(`^V5>P[%?P@"0@/C0$!``"A""$)"/9$D#8"#X3Q```` +XMC47P[%?P@"0A]T:$( +XM(0D(]D20-@)TQ8M%T(7`#X1+`@``C47"+1?"%P`^%\?[_ +XM_P^V5>P[%?P@"0@/C?C^__^A""$)"/9$D#8"#X3H_O__Z/___XM=\(/[`@^$$/___X7;=4(/MDWL#[;1.Q7\(`D(?0RA""$)"/9$D#8" +XM=2>+1+1="% +XMP`^$`O___X7;=1@/ME7L.Q7\(`D(?2VA""$)"/9$D#8"="&-1=R)1"0$B30D +XMZ(!"__^%P`^%Z/[__X-]\`(/A(+^__^#;=`!@WW0_P^$=/[__XM%\,=%S`$` +XM``"%P`^%+____P^V3>P/MM$[%?P@"0@/C/O^__\QP(#Y7P^5P(E%S.D,____ +XM.Q7\(`D(?1.A""$)"/=$D#0`!0``#X5:____@/E?#X7H_O__Z4S___^+1=P[ +XM1S1T&XM5X.DA_O__BT<\B5=(B4=$@\0\,FL_/__C;8`````C;\`````53')B>6+10B+ +XM50Q=Z8_\___K#9"0D)"0D)"0D)"0D)!5B>575HG&4XG+@^P\B57,QT70`0`` +XM`/9",0AT!HM"!(E%T(M5S(U-W(M"-(E%W(M".(E%X(E,)`2)-"3HGS___X7` +XM#X6;`0``BU7P@_H!#X0O`0``A=)U$`^V3>P[#?P@"0@/C`L!``"%VP^%70(` +XM`(-MT`&#?=#_#X1\````D(U=W(E<)`2)-"3H83[__X7`#X5-`0``BT7P@_@" +XM=%R%P'48#[95[#L5_"`)"'W1H0@A"0CV1)`V`G3%BT70AP/MM$[%?P@"0A]#*$((0D(]D20-@)U)(7_#X7:````.Q7\(`D(?0^A +XM""$)"/=$D#0`!0``=:.`^5]TGHM]T(7_=1B+1`[0S@/A9K]__^)V(/`-(E$)`2)-"3H +XM\O3__[@!````Z4'^__^!^D`""0@/A!G^__^!^I`#"0@/A4W]___I"/[__XUT +XM)@"-O"<`````5;D!````B>6+10B+50Q=Z1S\__^-M@````"-OP````!5,"+0S"-4P&->S3'1"00`````(E\ +XM)`@E``(``(/X`1G`]]`APHM%X(E4)`2)-"2)1"0,Z#?E_/^%P'4CBT7@QT0D +XM#`````")?"0$B30DB40D".@8Z?S_Z6G___^-=@"X`0```.E<____C;8````` +XMB4-`BT,X@_@!C5#_&<#WT"'"B5-(Z7/___^0D)"0D)!5B>564X/L,(M=#(MU +XM"(M3,(U+`8DT)(G0)0`"``"#^`$9P/?0(<'!Z@.-0SR#X@&)1"0,C4,TB50D +XM$(E$)`B)3"0$Z)CD_/^%P'0,@\0PN`$```!;7EW#BT,\`T9T@\`!*T,TB49T +XMC47TB40D$,=$)`P`````QT0D"`$```"+0T2)-"2)1"0$Z&,D_?^%P'6[BT,P +XMJ`AU*R4/_O__@\@@B4,PBT7T.4-( +XM7<.#Q#`QP%M>7<.0D)"058GEBT4,4XM="(E#/(E#1(M#-(/H`3E#/'8&B4,\ +XMB4-$BXN<````BT,\BY&,`0``C01`@^H8C03"B8&0`0``,<"#BZP$``!`6UW# +XMD(UT)@!5B>6#[#B)7?2+70R)=?B+=0B)??SV0S$(#X51`0``BT,TB47PBT7P +XM]D,Q$(E#1(M#.(E#2'1>BU,(A=)T5P^VAFP$``"#X`&)QP^%5@$``(N.9`0` +XM`(G(.=!S%XGXA,!T#(T$2<'@`@-&$(M(.(G*B4L(B50D!(DT).@Q____AQ=PP^V4P*`^BT/A+0!``!V8X#Z+@^$1`$``(#Z +XM7G5>]D,Q"`^$J@$``(M%\,=$)`@`````B30DB40D!.B-:```AQ=PXVV +XM`````(M#"/\DA1@+"0B)7"0$B30DZ%I"``"%P'2AN`,```#KS(-[$!)U++@0 +XM````C70F`.N)BT80B30D_Y!D"```N`0```#KJ(M5\+@"````A=)TCNN:N`4` +XM``#KDXVV`````%6)Y5=6B<93@^P\B%7D#[;2C5K0C7W8B4W0ZP:-="8`B<,Q +XMTHGYB?#'!"0*````Z`S___^#^`5U:`^V5>2#^G]W;/8$E=T4"0@$=&*-!)N- +XM1$+0.=ASR3'2B?F)\,<$)`H```#HU_[__X/X!74S#[9%Y(/X?W<*]@2%W10) +XM"`1UUL=$)`S_____QT0D"'`+"0C'1"0$`P```(DT).AO4_W_@\0\N`$```!; +XM7E]=PXM%T(D8@\0\,`)B46P#X0\`0``]D7D`G0)BT40QP`!````BTT(#[9]W(7) +XM#X2F`0``B?J`^B(/A.8```")^0^VT8/Z?W<.]@25W10)"`0/A8\!``"+50S' +XM`@````")^8#Y(@^$=@(``(GX/'X/APD!``")^(GZB`,/ML#!X`0%`/P("(#Z +XM1(E%M`^$'0,``(M%M(L`A<`/A,0$``")^8#Y?@^$*P,``(M%M(E#*(L`A<`/ +XMA-8$``"+1;2+0`2)1;B+0S#VQ`@/A$D"``#W1;@```0`#X4\`@``BT4(A<`/ +XMA`$&``"+?0@/MA>`^GX/A%P&```/ML+!X`2+@`C\"`C'1"0(!@```(E$)`2+ +XM1:R)!"3HM^C__S'V@\1\B?!;7E]=PXM5"(72#X0-`0``QT0D"``````Q]L=$ +XM)`0`````BTVLB0PDZ(/H___IG?[__XM-L(7)=6''1"0(O0L)"+X!````QT0D +XM!`(```"+3:R)#"3H9U']_^EQ_O__//\/A$D$``"+5:P/ML"-!$"-A`!0`0`` +XM`T(0@\`(QT0D"`0````Q]HE$)`2+?:R)/"3H&^C__^DU_O__@WVP`@^%5?__ +XM_XM]K#'VBT<0B3PD_Y!D"```Z4'____'1;`"````Z4[^__^`^3"-M"8````` +XM#X1A_O__BT6LC4L$Z,_\__^%P`^%$/___X%+,``(```QTHM]#(U-T,<'`0`` +XM`,<$)`(```"+1:SHX_O__X/X!0^$B0```(G&Z;+]___'!"0`````BT6L,=*- +XM3=#HO_O__X/X!77@@WW@"0^$N?[___9%Y`)T"8M]$,<'`0````^V1=PQTH%+ +XM,``"``"-3="(0P''!"0"````BT6LZ'_[__^#^`5UH(-]X`D/A'G^___V1>0" +XM=`F+11#'``$````/MGW`)#X3@_/__ +XM]D7D`HUV`'0)BTT0QP$!````#[9]W`^V`XGZ.-`/A8#\___IW?[__\=$)`@8 +XM#`D(QT0D!`,```"+?:PQ]HD\).AB3OW_Z9C\___W1;@```(`#X7%!0``BTVT +XM]D$&$`^$4OO__XU%\(E$)!"-1>R)1"0,QT0D"`$```"+?:R+1TR)/"2)1"0$ +XMZ,L9_?^%P`^%3/S__XM?4(M%\#G8B46@=F>+3>P/O@09A<`/B,(#``"+%?P@ +XM"0@YPHE5G`^.N0,``(L]""$)"(E]I/9$AS5`#X2)!0``C10+ZR8/OD(!A<`/ +XMB+($```[19P/C:D$``"+3:2#P@'V1($U0`^$F`0``(/#`3M=H'72QT0D"*0+ +XM"0@Q]L=$)`0"````BWVLB3PDZ()-_?_IC/K__P^V`SQ$#X0/`P``B?8/AWT! +XM```\0P^$\P(``(M%M(7`#X46^___,?;IB_O__XGZ@/HN#X3M`0``,=N#?>`) +XM#Y3#@\,$@/K_#X3Q`P``BTVL#[;"C01`C80`4`$```-!$(/`"(E<)`CI._O_ +XM_\=$)`3_````BTVLB0PDZ.X(_?_IM?O__XM-K(N!!`0``(7`#Y7`Z03^___W +XM1;@``(``=0GVQ`(/A=P```#W1;@````!#X0*_?__QP0D`````(M%K#'2C4W0 +XMZ./W__^#^`4/A0#\__^#?>`)#X39^O__]D7D`G0)BU40QP(!````#[9%W(%+ +XM,``"``"(0P'IP?S__\<$)`````"+1:PQTHU-T.B:]___@_@%#X6W^___@WW@ +XM"0^$D/K___9%Y`*-=@!T"8M5$,<"`0````^V1=PQTH%+,``"``"-3="(0P'' +XM!"0"````BT6LZ%/W__^#^`4/A7#[__^#?>`)#X1)^O__]D7D`G0)BTT0QP$! +XM````#[9]W.F#^?__BTVTBT$(Z0_Z__\\4P^$C@$``#Q9C78`#X5X_O__QD7P +XM7\8#>8U%\,=$)!`,````QT0D#`$```")1"0(QT0D!`````"+5:R)%"3HR0S] +XM_X7`#X7:^?__#[8#P>`$!0#\"`B)1;3I+/[__XM%K/:`#`0```$/A#,!``") +XMP8N`!`0``(T$0,'@`@-!$(M`.(7`#X1X^?__H6@+"0CI>OG__XM-J(7)#X1) +XM^?__BU6LBX*<````BX"``0``.T(L#X53`@``@4LP`"```,=#*%`#"0CI,?C_ +XM_\<$)`````"+1:PQTHU-T.@^]O__@_@%#X5;^O__@WW@"0^$-/G___9%Y`)T +XM"8M5$,<"`0````^V1=P/MM"#^G^(0P(/AS_[___V!)7=%`D(!`^$,?O__XM% +XMK(U+".BP]O__A<`/A?'X__^!2S``$```,=*-3=#'!"0`````BT6LZ,WU__^# +XM^`4/A>KY__^#?>`)#X3#^/__]D7D`G0)BTT0QP$!````#[9%W(A#`NG5^O__ +XMQD7P),8#8^F0_O__QD7P),8#9.F$_O__QD7P7\8#8^EX_O__BWVLBX<$!``` +XMA<`/A%#X___IT_[__Z'\(`D(B46<#[84"P^^PH7`#XC"````BST((0D(B7VD +XM.P7\(`D(#XVU````BWVD]T2'-``%```/A*0```#'1;P!````C3P9B=F#P0$[ +XM3:!S/@^V5P&(59L/OM*%TG@9.U6R)7"0$BXR)5:"+/?P@"0B)?9SIM?[__XM-J(M1,/;& +XM(`^$S````(M#,/;$"'05BT6H@,X(B5`PBT,$BU6HB4($BT,P]L0"=`H/MD,! +XMBTVHB$$!QT0D"$P```"+?:B)'"2)?"0$Z#2?_/_IFO7__\<$)`````"+1:PQ +XMTHU-T.BG\___@_@%#X7$]___@WW@"0^$G?;___9%Y`)T"8M5$,<"`0````^V +XM1=R(0P+I^?G__P^V%`L/OL+I*/[__XE$)`R-AS0!``")1"0(BXS\````BT4(BS"-18R+5A#'1"0(3````,=$)`0` +XM````B00DB948____Z%^;_/^#3;P@BUX0B[Z<````QT0D!`(```")-"3_DZ`( +XM``"%P'00N`$```"!Q/P```!;7E]=P\=$)`@!````QT0D!`````")-"3_DUP( +XM``"+AJP$``"#X/J#R`+VAB`"```!B8:L!```#X0I!P``BX88`@``C01`P>`" +XM`T80BT`XB8>T`0``]H9@`0```8E&-`^$]@8``(N&6`$``(T$0,'@`@-&$(M` +XM./:&;`0```&)1C@/A+`&``"+AF0$``"+5C2-!$#!X`(#1A"#^@&+0#B)1D2) +XM1CP/A*0&``"#Z@$YT`^'E0D``(M&-(/H`8E&0(N>G````,=&2`````#'1"0$ +XM&````(N#M`$``(/``8D$).B=F_S_A<")@XP!```/A"<*``"+CIP```"+1CR+ +XMD8P!``"-!$"#ZAB-!,*)@9`!``"+AIP```"+D(P!``"+1DR)`HN&G````(N` +XMC`$``,=`!`````"+AIP```"+@(P!``#'0`@!````@8ZL!```H````&:#C\@! +XM```%BU80QT0D"`$```"+1B"+0`B)-"2)1"0$_Y*<"```BYZ<````BT80BX@8 +XM`0``AB% +XM_W5;BX:<````C56,QT0D"$P```")5"0$!9@```")!"3HJ)O\_XN&G````(&( +XMR``````@``#V1;T$=!"+AIP```"!B,@`````"```BX:<````@:#(`````/[_ +XM_XM%O"7P`0``@_@@#X0"!```#X8Q!0``/8`````/A.D#```]``$``(VT)@`` +XM``!T$(/X0`^%(`4``,=%U`````"-1=2)1"0(BT70B30DB40D!.A(N/W_A<`/ +XMA+4#``#'1"0$`@```(DT).@``_W_A<`/A7@#``"+1A#V@%0(```$#X0H`P`` +XM@Z!4"```^\=$)`0"````B30DZ-$"_?^%P`^$^@$``,=$)`C0#`D(QT0D!`,` +XM``")-"3H$43]_XN&K`0``/;$$`^%^@$``/;$"`^%60(``(N%&/___X"X5`@` +XM``!X#?:&K`0```$/A,W]__^+50B),HM^$(M?"(U'"(U7$(F%+/___\>%*/__ +XM_P`````YPXF5%/___W5-Z9$&``"+0P2)0@2+0P0YA2S___]T?(D0BY44____ +XMB1.+1Q2)0P0[5Q`/A#@&``"+1Q2)&(E?%(.%*/___P&+7P@YG2S___\/A$D& +XM``"+@YP```"+@(P!``"%P'08B00DZ&&:_/^+@YP```#'@(P!````````BQ,Y +XME2S___]UAHM#!(E'#(M#!#F%+/___XL3=82)5PCK@8DT).@3)?W_A<"0#X6: +XM_O__BY48____QT7H`````(M"?(M`%(7`#X6+_?__C46,QT0D"$P```"-?>C' +XM1"0$`````(D$).AUEOS_BY:<````C47LB40D!(U-C(GPB7PD",<$)`````"! +XMPI@```#H6>___X/X!`^&0@(``(M-M/9!!P(/A%P#``#VAF0#```!#X1+!P`` +XMBX9<`P``C01`P>`"`T80BT`XA<`/E<"$P`^$,`,```^V18P\_P^$=0@```^V +XMP(T$0(V$`%`!```#1A"#P`C'1"0("````(E$)`2)-"3H5`W__^F__?__QT0D +XM"-D+"0C'1"0$`P```(DT).@70OW_BX:L!```]L00#X0&_O__@.3O#0````*) +XMAJP$``"+=A2+GIP```"+5A#'1"0(`0```(M&((M`"(DT)(E$)`3_DIP(``!F +XM@XO(`0```<=$)`0!````B30DZ)M$``"%P`^%&OK__XN&K`0``/;$"`^$J_W_ +XM_XUT)@"`Y/>)AJP$``"+1A#'1"0(`0```(M6((M2"(DT)(E4)`3_D)P(``#I +XM>_W__XUT)@#'AI0````"````QT0D!`````")-"3H-D0``(7`#X6U^?__]T6\ +XM8`$```^$F?O__Y!F@Z/(`0``OXU&5(E$)`2)-"3HR44``.E\^___C70F`,=$ +XM)`P!````QT0D"`````#'1"0$`````(DT).@P!?W_A<`/A>?\__^+1A#V@%0( +XM```$#X37_/__Z9O\__^-=@#'1"0(H`P)",=$)`0"````B30DZ,A`_?_I:_S_ +XM_V:#B\@!``!`BU70B59,BTW4B4Y0BT6\]L1`=1VI```!``^%,0$``&:%P`^) +XM._S__SM5V`^$-`4``(U5V,=$)`P!````B50D",=$)`0G````B30DZ.LP_?^% +XMP`^$"_S__^GN^____R2%3`L)"(M6-(N&9`0``(/Z`8E&1(E&/`^%7/G__\=& +XM0`$```#I9/G__XN&6`$``.D1^?__BX88`@``Z=[X__\E``0``(E$)`C'1"0$ +XM`````(DT).C4ZOS_A<`/A6/X__^-7?")7"0$B30DZ.US``"%P`^%3/C__XM% +XM\(7`#X2(`P``BT7PBU4(B0*)-"3HNH#]_X7`#X4I^/__BW7PA?8/A&\$``"+ +XMGIP```"+1A#'1"0(`0```(M6((M2"(DT)(E4)`3_D)P(``!F@XO(`0```>EV +XM^?__A<`/A,/^__^#^!`/A-P"``"0C70F`.@?D?S_.U78#X78_O__B?;IO_[_ +XM_XU5C(E4)`2)-"3HO##__X7`#X74^O__Z?GY__^+1A#I[_K__XM5O/;&()!T +XM%XM%[(7`=!"+AIP```#'@.@````!````B=`+002I`,`!`(E%O'0,BT9,B478 +XMBT90B47`S`2)1;P/MD6,.H5`____#X3>`P``BT6TQX4<____```` +XM`#U@"PD(B85L____#X2J`P``BT6\B<*!XO`!``"H((F5(/___W0,@\H0@^+? +XMB94@____BY5H____)0_^__^)1;R+0@0E#_[__PF%0```")!"3H))+\_XN5 +XM)/___XN%,/___XF0Z````(M%O"4("```/0@(``!T48-&+`'I^?7__SM-W`^% +XMP_K__^GP]O__,<"-M@````#II_/__XN&7`,``(7`#Y7`Z;SX__^)=PCI3O[_ +XM_XE7$.DD_O__BT8$B4<4BQ;I!O[__XM%D`-%R(/H`8E%R.NAC95`____B10D +XMQT0D"$P```#'1"0$`````.B&COS_C47@,=*)1"0$C46,B00DC8U`____B?") +XM?"0(Z'+G__^#^`4/A1_]___I)OS__XM%R(DT)(E$)`3H]0?]_X7`#X5S_O__ +XM@WW(`745#[9%C#QCD`^$6?[__SPA#X11_O__QT0D"`$```#'1"0$`````(DT +XM).A:T?__Z0#5DR)1"00QT0D#`````"#Z@&)52#^`&-4/\9P/?0(<*)5/___SM-@`^&R/W__^O$ +XMD)"0D)"0D)"0D)"0D)"058GE5U93@^P\BW4(]H:O!```$(M^$(N&G````'0* +XM@\0\,*)!"3H%8W\_XDT)(E$)`B-1>*)1"0$_Y=8"```BY:<````@\,8 +XM.9J0`0``0"```@\0\,%2/___P````#WP@`` +XM`!!U&8N`G````(.X7`$```$/E\`/ML")A4C___^#XA!T.8M="(N#G````(M3 +XM0(N(C`$``(M#-#G"#X.B)1"0$BUT(B1PD_Y%P"```QT0D"`````"+@YP```"+50PKD(P!``")'"2) +XMT,'X`VG`JZJJJHE$)`2+C23_____D9`(``"-1?")1"00C47DB40D#,=$)`@` +XM````BUT,BP.)1"0$BT4(B00DZ(4"_?^+50B+30B+4CB)QHF5+/____:!%`(` +XM``$/A68$``"+70B+@PP"``"%P`^5P(3`#X1O!```BT4,BUT(BT`$QX4\____ +XM`````(F%./____:#.`(```$/A'4$``"+@S`"``"-!$#!X`(#0Q"+0#B)A4S_ +XM__^+50C'A5#___\`````]H*O!```$'51]H*8`@```0^$504``(N"D`(``(T$ +XM0,'@`@-"$(M`.(7`#Y7`A,!T'8.M+/___PB%]@^%+`0``(N=./___X7;#X2* +XM"```BY5,____B950____A?8/A20$``"+3?"%R0^$&00``(N%./___X7`#X4# +XM!0``BU4,QT(,`````,9"%`#'A3#___\`````QX4T____`````(M%$(7`=!&+ +XM50R+30B+`CM!3`^$>PD``(N=2/___\>%*/___P`````)^P^%"P,``(N5-/__ +XM_SM5\`^#?@L```N]2/___XV=9/___XU%XXF]5/___XG?QX5<____`````,>% +XM1/___P````")G1S___^)A2#___^-=@"+1>0/MA"#P`&)1>0/MLJ`^@F(E6/_ +XM__^)C4#___\/A,P$``"`O6/_____#X2M!0``BY5`____BTT(C012`<`#01`/ +XMMH!=`0``B<8QTBNU,/___P&U7/___XN-7/___SF-+/___W=4@_H!#X1.!0`` +XMBT4,B?.(6!:+A5S___\KA2S___^+70PIQHGQB$L5BX5<____.84L____<#``"+70B+30R+ +XM@YP```"+71`KB(P!``")R,'X`VG`JZJJJHD#BT4(]H"O!```"`^$5@4``(N% +XM7/___XM-%"GPB0&+10CV@)@"```!#X0F!0``B<&+@)`"``"-!$#!X`(#01"+ +XM0#B%P`^5P(3`=!J+10CV@*\$```0=0Z+C3C___^%R0^$5@,``(N%5/___X7` +XM#X4^`0``A=(/A+@#``"%]G15,=OK#8/#`<8'((/'`3GS=$0[O2#___]RZ\8' +XM`(V%9/___X/#`2N]'/___XE$)`2)?"0(BU4(C;UD____B10DBXTD_____Y%8 +XM"```Q@<@@\# +XMQP&#^?]U[8N%7/___X/``3F%+/___W82BU4(B10DBXTD_____Y%L"```.;T< +XM____#X()!@``BT7LB40D"(M%Z(E$)`2+30B)#"2+G23_____DY`(``"!Q.P` +XM```QP%M>7UW#BX$,`@``C01`P>`"`T$0BT`XA<`/E<"$P`^%D?O__XM5#(M= +XM"(M*"(/I`8F-//___P^OC2S___^)C3C____V@S@"```!#X6+^___BT4(BX`P +XM`@``B85,____Z8_[__^-4/_I7/K__XN=3/___XM%#(F=4/___X,X`0^$O/O_ +XM_XGVBU40A=)T$8M-#(M="(L!.T-,#X1P`@``"[U(____#X4N____BUT,QT,0 +XM`````,=##`````#&0Q4`QD,4`(N%./___X7`=4J%]@^$S`(``(,[`;I^```` +XM#X2^`@``BTT(C112`=*+01`/MHP070$``(V$$%@!``")1"0$B4PD"(M="(D< +XM)(N5)/____^26`@``(M-"(D,)(N=)/____^3;`@``(M%[(E$)`B+1>B)1"0$ +XMBT4(B00D_Y.0"```@<3L````,^?__@<3L```` +XM,2)G3#____V@!0"```!#X5=!```BTT(BX$,`@``A`"`T,0BT@XBX5<____,=*)SO?Q*=:Z +XM`0```"NU,/___P&U7/___^D5^___C1PW.9T@____#X;4````@+UC_____P^$ +XM0P$``(N-0/___XM="(T$28V$`%`!```#0Q"#P`B-3O^)C5C___^#P0$/A%K\ +XM__^+G3#___^)^8T4&(T<-XVT)@`````/M@*#P@&(`8/!`3G9=?&+A5C___^- +XM?#@!Z2?\__^+G2S___\IV2G.BTT,B?"(016(01:)G5S____IR/K__XN=0/__ +XM_XE<)`2+10B)!"3H/>W\_^E1^O__BX.<````BU40*XB,`0``B0/MA"#P`&) +XM1>0/MLJ`^@F)C4#___]UH8N53/___X72=:"+10CV@-`#```!#X0J`@``B<*+ +XM@,@#``"-!$#!X`(#0A"+2#B)V#'2]_&)R"G0ZXB+50R-G63___^+`HD<),=$ +XM)`@K#0D(QT0D!(````")1"0,Z/N!_/^)7"0$B40D"(M-"(D,)(N=)/____^3 +XM6`@``(N%3/___XF%4/___^DP]___@,(!#X0V`0``BY5`____BTT(C012`<`# +XM01`/MH!=`0```<,[G2S___]R'XM-""N=+/___XM).(.M//___P&)C2S___\/ +XMA#P!``"#A33___\!BY4T____.57P#X8F`0``BT7D#[80@\`!B47D#[;*@/H) +XMB8U`____=8:+A4S___^%P'6%BT4(]H#0`P```0^$%@$``(G"BX#(`P``C01` +XMP>`"`T(0BT@XB=@QTO?QB<@IT.EJ____Q@<`C9UD____*[T<____B5PD!(E\ +XM)`B+10B)!"2+E23_____DE@(``#IR?G__XG"BX`,`@``C01`P>`"`T(0BT`X +XMA<`/A:;[___IC_O__XM14#F5-/___P^'=O;__XN%-/___P.%+/___SG"#X=B +XM]O__BX4T____@\(!*<*)E2C____I9/;__XN%0/___XE$)`2+50B)%"3HR.G\ +XM_^G(_O__BX5`____B40D!(M5"(D4).BNZ?S_ZG)]?__BT4( +XMBXC(`P``Z?#^__^+10B+B,@#``#IW/W__XM%"(M`.(F%+/___XN%-/___XM= +XM#(E##,9#%/_'A3#___\`````Z8+U__^#A33___\!BYTT____BTT,B5D,QD$4 +XM`,>%,/___P````#I7/7__XM5"(N--/___SM-\(M2.(F5+/___W.D.YTX____ +XM#X0B`0``BXTT____BU4,B4H,*YTX____*=B)A3#___^(0A2#;>0!Z1/U___& +XM!P"-E63___\KO1S___^)5"0$B7PD"(M-"(V]9/___XD,)(N=)/____^36`@` +XM`(M%"(M8$.G$]___BX5`____B40D!(M5"(D4).AMZ/S_Z7/W__\/MD(5.,$/ +XMA,(```"+4A`/ML")A3#___\/MH4P____B94T____BXTT____BU4,B4H,B$(4 +XMBUT(`4WD]H,4`@```716BX,,`@``C01`P>`"`T,0BT`XA%,/___P````#I\?/__XM2$#'`QX4P____`````(/"`8F5-/___^DZ +XM____D)"0D)"0D)"0D)"0D%6)Y5.#[!2+70B+0Q"+4S2+B)`(``"+0T`YT'(# +XMC4+_B1PDQT0D"`````")1"0$_]&+0Q")'"3'1"0$`````/^0F`@``(/$%%M= +XMPY"-="8`58GE5U93B<.#[#R)5=")3S0!#X1/`0``@WW,`0^$!0$```^# +XML````(U%\(E$)`C'1"0$`0```(D<).BQ'_W_B<*+1?")5"0$B1PDB40D"/^6 +XM6`@``(.'7`$```''AU0!````````C7W4B1PD_Y9L"```QT0D!`````")'"3_ +XMEI@(``"+5="%TG0ABT70QP``````ZQ:+1=R#^`%T48/X!'1!B1PD_Y9D"``` +XMQT0D#`````#'1"0(`````(E\)`2)'"3H:>S\_X7`=,J0C70F`(/$/%M>7UW# +XM@WW,`G0KZ-%Y_/_&1>!Q@XY4"```!(-]S`%T48-]S`)UUH!]X'%UT(..5`@` +XM``3KQXU%\(E$)`C'1"0$!0```(D<).C0'OW_B<+I&O___XU%\(E$)`C'1"0$ +XM`@```(D<).BR'OW_B<+I_/[__X!]X#IUA8M%T(7`#X1Z____BT70QP`!```` +XM@\0\6UY?7<.-1?")1"0(QT0D!`0```")'"3H@"=#&+3>B)V(M5[(M=](MU^(M]_(GL7>F3_?__C78` +XMBU-`.=!V*2G*ZX60C70F`(U"_^NOBU7PBX)4`0``.T-`<\&+7?2+=?B+??R) +XM[%W#C5#_*L!```"`^$ +XM;0$``(M#$(E$)`R+0PR)1"0(BT,(B3PDB40D!/^6E`@``(L3A=)T!HM#!(E" +XM!(M#!(D0BT,,B00DZ.)\_/^)'"3HVGS\_XM>;(7;=;>+1+1<#'@%P!````````QX!8`0```````,>`5`$```````"+ +XM1>R+50R)1"0(BT7PB10DB40D!/^6D`@``#'2@\1,B=!;7E]=PX/H`71F,"7`$```````#'@E@!````````QX)4`0```````(E$)`2)/"3H +XM^A(``.EO____BTT0AL +XM!```QT0D"`(```"+1TR)/"2)1"0$Z$<<_?_ICO[__X/@_8F&5`@``(D\)/^6 +XM9`@``.EF_O__QT0D!`$```")/"3H:R<``+H!````A<`/A+C^___I#____XG! +XM*='I0/___XE]#.D+_O__,S<````B85`____B94\____BY5`____B8TX____BT`0B85$____BT4(BY*< +XM````B8U4____A<")E4C___\/CI8#``"-C7#___^-7>^)C3#___^)G33___^+ +XM70B+M3C____'1"0$"@```(E<)`B)-"3H6'7\_XF=4/___XF%5/___XN%5/__ +XM_X7`=!"+E53___\I\HF54/___XG3BXU(____B[5`____BY%8`0``BTXXC003 +XM.7UW#B[5`____BYU,____B30DB5PD!.@OWOS_ +XMB<;I"?[__XN-0/___XNU1/___XM!0(M)-(N>D`@``#G(<@.-0?^)1"0$BX5` +XM____B50D"(D$)/_3@[T\____`P^%7/W__XN50/___XN-1/___\=$)`@!```` +XMQT0D!`$```")%"3_D5P(``#I,OW__XN-0/___XN=1/___\=$)`@`````QT0D +XM!`$```")#"3_DUP(``#IX?[__XN%0/___[D"````,=+H(_C__^E*_/__BY5( +XM____BX)<`0``Z3'\__^+E4C____V@L@!```"#X0>_/__@ZI4`0```8/H`6:# +XMHL@!``#]B8)<`0``Z0'\__^+M4#___^+G43___^+1D"+BY`(```YP@^&Q0`` +XM`(/H`8E$)`2+A4#____'1"0(`````(D$)/_1BY5`____BXU$____B10D_Y%L +XM"```BYU`____BW,X@_X/=@6^#P```(N%0/___XM8$,=$)`@!````QT0D!`$` +XM``")!"3_DUP(``"+E4#___^)="0(QT0D!#$-"0B)%"3_DU@(``"+C4#____' +XM1"0(`````,=$)`0!````B0PD_Y-<"```BYU(____@X-<`0```6:#B\@!```" +XM@X-4`0```8N#7`$``.D0^___C4+^Z3;___^+A4C___^+M4#___^+E43___\% +XM6`$``(E$)`B-1?")1"0$B30D_Y)P"```Z=']__^-=@!5B>575E.#[#R+=0B+ +XM?0R+1A")1="+GIP```#'!P````"+@U@!``!F@XO(`0```87`#X5)`0``BY:L +XM!```]L(0#X40`0``]\(``!``=0V#NUP!```!#X:X`0``B=`E___O_X'B```( +XM`(F&K`0``'40BT80]H!4"```!`^$,@$``/:&K`0``!`/A;4```"+1A"#P`@Y +XM!G0'@XZL!```0/:#R`$```@/A8L```#'1"0(`0```,=$)`0`````B30DBU70 +XM_Y)<"```@::L!```[__W_X.[7`$```$/AD@!``#'1>`&````BY-<`0``N0$` +XM``"+1C0YPG)9B47LC478B4WDQX-<`0```````,>#6`$```````#'@U0!```` +XM````B40D!(DT).@&"P``,=*#Q#R)T%M>7UW#@XZL!```(.EI____9H.+R`$` +XM``3I/O___Y")P2G1ZZ&+1A#'1"0$`@```(DT)/^0H`@``+H!````A#4`$```$```#IA?[__\=$)`P!````QT0D"`````#'1"0$`````(DT).B. +XMX/S_A7UW#B?J)\.BG +XM\O__ZZ>0C70F`%6)Y5=64X/L+(MU"(M=#/:&K`0``!"+?A!T-8M5$(72#X0L +XM`0``A=N)V`^$&`$``(E4)`R)1"0(QT0D!'WI"`B)-"3HF$S^_XDT).BP2_[_ +XMC47PB40D"(U%[(E$)`2)-"3_EW`(``"+1D"+5C2+CY`(```YT'(#C4+_QT0D +XM"`````")1"0$B30D_]&)-"3_EVP(``"%V\=%X`````!T+HD<).CM'````BT7@B40D"(E<)`2)-"3_EU@(``"+51"%TG0PBT40 +XMB00DZ+5R_/^+7CB+5>")P0'"C4/^.<)W1(M%$(E,)`B)-"2)1"0$_Y=8"``` +XMBT7PB30DB40D"(M%[(E$)`3_EY`(``")-"3'1"0$`````/^7F`@``(/$+%M> +XM7UW#*UW@C4O^Z[2-="8`B47@Z73___^X3XT(".G>_O__ND^-"`CIRO[__XUT +XM)@!5B>6#[#B)=?B+=0B)7?2+11")??SVAJP$```1=3.#^`*+?A"+GIP```!T +XM-(/X`P^$JP$``(/H`0^$D@```(GVQT0D!`````")-"3_EY@(``"+7?2+=?B+ +XM??R)[%W#B?:+@V`!``"%P'36BY-<`0``@^@!B8-@`0``A=)U,87`=2V+1D"+ +XM5C2+CY`(```YT'(#C4+_QT0D"`````")1"0$B30D_]&)-"3_EVP(``"+@W`! +XM``")1"0(BX-L`0``B30DB40D!/^7D`@``.EP____BX-@`0``BXM<`0``@\`! +XMA`$``&G`0$(/``'"@?I'Z`$`#XX<_O__BT7DBU7H@[MD`0``!(F#=`$` +XM`(F3>`$```^$A0```(N'D`@``(E%W(M&0(M6-(N+:`$``#G0<@.-0O^)3"0( +XMB40D!(DT)/]5W(N39`$``(N'6`@``(U*`8'"1PT)"(F+9`$``(E4)`3'1"0( +XM`0```(DT)/_0BX>0"```B47@BU9`BTXTBX-H`0``.7UW#BTW<@Z%4"```_8M%"(D$)/^19`@``.GB_O__J!`/A.T"``"+ +XM50B+0A#'1"0$`0```(D4)/^0H`@``(7`#X37_O__Z2;___^-1?")1"0(C47L +XMB40D!(M-"(D,)(M5W/^2<`@``(-]#`$/A`$"``"+512+11"+30B`?!#_"@^4 +XMP`^VP"G"B544@WDT`0^$?`,``,=%Z`````"+5>B+10B#P@*)5>B+2#B#Z0&) +XM3>"+3=B+@5@!``"%P'0IC00"`T44.47@#X/U`@``BY%0`0``N574"`C'!"0" +XM````BT4(Z/[P__^+30R+5=B)BE`!``"+112+71"%P'4FZ8L-B?8Y^'T2]D2&-@)T"X/I`0^^0?^%P'GJB=:)\"G8*444#X7P```` +XMB<@IV(/X`7X+@'P8_RX/A`P!``")!"2+50R)V8M%".C7[___BTT(BT$0]H!4 +XM"```!'5LQT0D#`$```#'1"0(`````,=$)`0`````B0PDZ"C8_/^%P'4/BU4( +XMBT(0]H!4"```!'4YB?/IP?[__XM!$,=$)`0"````B0PD_Y"@"```@\0L6UY? +XM7<.+312Z`0```(D,)(M-$(M%".A<[___BT7PB40D"(M%[(E$)`2+30B)#"2+ +XM5=S_DI`(``#'1"0$`````(M-"(D,)(M5W/^2F`@``(/$+%M>7UW#BU44C303 +XMB?")\2G8*444#X00____*=F)#"2+50R)V8M%".CY[O__N2:Z"`BZ`0```,<$ +XM)`$```"+10CHX.[__^D$____C4'_*=CIZO[__XM-"(D,).CVW/[_A<`/A/;[ +XM___I1?S__\=$)`@!````QT0D!`$```"+10B)!"2+5=S_DEP(``"+31")3"0( +XMBT44QP0D\I@("(E$)`3H1&?\_\=$)`@`````QT0D!`$```"+50B)%"2+3=S_ +XMD5P(``#IO/O__XG1B=;I2_[__XD<).BO:?S_BT40B40D#*$0(0D(BU44QT0D +XM!$$-"0B)!"2)5"0(Z-QA_/_IK_O__XM%V+E8\0@(BY!0`0``QP0D`0```(M% +XM".@&[O__N=+4"`BZ`0```,<$)`$```"+10CH[>W__^GJ_/__QP,`````B5AL +XM@\!LB4,$Z6#[__^-1>B)1"0(QT0D!`0```")#"3H_0C]_^EO_/__D)"0D)"0 +XMD)!5B>564X/L$(M=#(MU"(M3##M3%'80ZU.+4PR#P@$Y4Q2)4PQR18N&G``` +XM`(T44L'B`P.0C`$``(/J&,9"%@#'1"0,`````,=$)`@`````B50D!(DT).BU +XMV?__ARL````B95P____BT`0B85X____BY:<````B95\____B='VAJP$```@ +XM='7'@JP!````````BX:L!```]L0!#X6/!P``A,!Y+\=$)`@"````BT9,B30D +XMB40D!.A8(@``A7UW#QT0D"`,```#'1"0$ +XM`````(DT).@H(@``A2)?"0,B40D"(E<)`2)-"3HH=?__X7`#X5Y +XM_O__@WWD_W3&BY5\____BX+$`0``A``"Z`0```(G#BT9`@_@!=`2)PM'J.=H/@OD'``"%VP^$?@```#M& +XM/'4'ZW`"`T80BT`XA<`/E<"$P`^%.@<``(N-?/___\=%Y/_____'@<0!```````` +XMBX:<````.9B0`0``#X+J"0``BP,[1DP/A=\)``"-N<`!``#K(9"+AIP```"# +XMPQ@YF)`!```/@MH&``"+`SM&3`^%SP8``(U%Y(E\)`R)1"0(B5PD!(DT).C) +XMU/__A<`/A:'[__^#?>3_=+N+E7S___^)FL0!```QTL=%B`````#K&O:&K`0` +XM`$!T#(M&0#E&1`^%?0<``+H!````BXU\____BYG$`0``A=L/A$P)``"+1E"+ +XMC7S___^)@;P!``"+1DR)@;@!``#VAI@"```!#X4=`0``BX:0`@``A<`/E<"$ +XMP'07BX5\____]H#(`0``('0(A=(/A"<#``"+18B%P'0'@XUP____`XN5_K)`^VP(T$0`'``T80#[:`70$```%%D#M]D`^"P@@``(M& +XM((M`"(/K`3G8#X-L!P``#[8#/"\/A%X'```\_W7"QT0D!/____^)-"3H%LG\ +XM_^O"BX:0`@``C01`P>`"`T80BT@XAF)5"0(B5PD!(E,)`R)-"3H&QD``(M6/(/Z +XM`8G#N`$```!T!(G0T>@YV`^'>P@``,=%J`$```"+AIP```"#^@&+@(P!``#' +XM1;`!````BT`$B46LN`$```!T!(G0T>B)1"0,BT9,B30DB40D"(U%J(E$)`3H +XMN!@``(M6/+D!````@_H!=`2)T='I.<$/AQ0)``"+5DS'1"0(`@```(E4)`2) +XM-"3H^!H``(7`#X6@^/__@XZL!```0.GX^/__QT0D"`,```#I/X__^+0@@YQP^&V/C_ +XM_XM./+L!````@_D!=`2)R]'KB?DIP3G+#X)_"@``B30DZ"(B``"%P`^%^O?_ +XM_XN&G````(N`D`$``#MX"'??Z97X__^)-"3H;,___X7`#X3)_/__C70F`.G+ +XM]___QT60`````#M&!)`/A3/]__^)-"2+593_DFP(``"+7CB#ZP'VAC0#```! +XM#X3?!@``BX8L`P``C01`P>`"`T80BT`XA<`/E<"$P`^%+0<``(M]D(/'`O:& +XMH`,```$/A)T&``"+AI@#``"-!$#!X`(#1A"+0#B%P`^5P(3`=#:+1AP/MD!8 +XM@^`$@_@!C474@]/_B40D"(N&E````(DT)(L$A9`-"0B)1"0$Z"[^_/\K7=2) +XM18PY^W9TBT64BU8TBXB0"```BT9`.=!R`XU"_XE<)`B)1"0$B30D_]'VAJ`# +XM```!#X1>!P``BX:8`P``C01`P>`"`T80BU@XA=L/E<"$P'0IBT8<]D!8!`^% +XM00H``(M%U(E$)`B+38R)-"2)3"0$BU64_Y)8"```B?;VA7#___\!#X5=`0`` +XMBX5T____A<`/A2/____^2D`@``(DT)(N->/__ +XM__^1;`@``(N&G````(-N/`&#J)`!```8BT8\.T9$=Z+'1"0(`0```(M&3(E$ +XM)`2)-"3HRQ<``(7`#X33_/__Z6[U__^+A@P"``"%P`^5P.DY^?__BXU\____ +XM#[>!R`$``(DT)(/@!(E$)`2+E7C_____DI@(``#IL?[__XN-?/___XN!P`$` +XM`(E$)`B+1>2)-"2)1"0$BY5X_____Y*0"```BU6(A=(/A'+^__^-1E2)1"0$ +XMB30DZ*8*``#I7O[__S'2QT6(`````.EY^?__C490QT0D$`````")1"0,B50D +XM",=$)`0`````B30DZ&`.``")1:`/MHZ8`@``@^$!#X6?````BY:0`@``A=(/ +XME<"$P'0*@WV@!W8$@VV@"(M[!#E]H`^'WP```(N6I`,```^VCJP#``"-!%*# +XMX0&)A6S___^$R8G0=`^+A6S____!X`(#1A"+0#@YQP^"I@,``(3)B=!T#XN% +XM;/___\'@`@-&$(M`."G'.7V@=L?VAJ\$```0#X3>`0``B7L$BX:<````BXB0 +XM`0``QT6(`````.D+]?__BY:0`@``C012P>`"`T80BT`XA<`/E<#I4/___XM> +XM/#G8#X)X^/__C;0F`````(E<)`2#PP''1"0(`````(DT)(N->/____^1D`@` +XM`(DT)(N5>/____^2;`@``#E>0'/.Z3KX__^%_XVT)@`````/A?$!``"$R0^$ +XM.0,``(T$4L'@`@-&$(M`.(7`#Y7`A,`/A!,#``"+5CB)T(E5G(/H"#E%H`^& +XMSP$``(N&I`,```^VCJP#``"-%$"#X0&)A63___^)E6C___^%R8N%9/___W0/ +XMBX5H____P>`"`T80BT`XBU6<`<>-!!@2+AIP```"#PAB+B)`!```YT7/JQT6(`0```.D'\___@XZL!```((GP +XMBY5P____Z(;Q___I]O'__XM&4#N!O`$```^$W0(``(U%X(E$)!"-1>R)1"0, +XMC47B)1"0(C47DB40D!(DT)(N5>/____^2<`@``#'2QT6(`````.EP\___BX5\ +XM____BY"\`0``.590#X-A`0``B=<#?=R)?=R+@+P!```[1>R+3E`/@S?V__^- +XM4`$IRHN-?/___XN!P`$``(/`!3G"#X<;]O__C5K_@_O_QT6`_____P^$#/__ +XM_P^V%XU'_XE%W(#Z"0^$]O7__P^VPC'_B46$ZSN+582-!%(!P`-&$`^V@%T! +XM``"#ZP$!QX/[_P^$RO[__XM%W`^V$(/H`8E%W(#Z"0^$M_7__P^VRHE-A(#" +XM`77`BTV$B30DB4PD!.@1O?S_Z\''1"0$_____XDT).C_NOS_Z6#[__^)>0C' +XM1"0(`P```,=$)`0`````B30DZ"\0``"+1DR#CJP$``!`BY:<````Z8KU__^+ +XM?9"#QP*-!#HYPP^&[_W__\=$)`@"````QT0D!+C<"`B)-"2+593_DE@(``"+ +XM1=2+39"#P`*-?`$"Z<']__^)>@C'1"0(`````,=$)`0`````B30DZ,`/``"# +XMCJP$``!`Z17N__^+1=R+C7S___^#P`$!T(E%W(M>4(NYP`$``"N9O`$``.LE +XMBX:0`@``C01`P>`"`T80BT`XA<`/E<"$P'16BT8X@^@(.?AV7X/K`8/[_W17 +XMBT7<#[80@\`!B47<@/H)#X2,]/__#[;"@,(!="R-!$`!P`-&$`^V@%T!```! +XMQ_:&F`(```%UG(N.D`(``(7)#Y7`ZZ:+1CCKJXE$)`2)-"3HP+O\_^O5BX5\ +XM____B;C``0``]H:8`@```71;BX:0`@``C01`P>`"`T80BU`XA=(/E<"$P'0[ +XMBT8X@^@(.<GD_/__58GE5U93@^P< +XMBWT(BT<0B47L]H>L!```0`^%%@$``(M8"(UP"/:'F`(```$/A#T!``"+AY`" +XM``"+5>R-!$"+1((XA<`/E<`\`1G`@^#@@\`Q.=Z)1?!U0NM;C;8`````BY.< +XM````#[>"R`$``(5%\'0B#[>2R`$``(G8@^(!@\H"Z!KK__^+AYP```!F@XC( +XM`0```8L;.?-T&SG[=/:+@ZP$``#VQ`9UZZA@=+.+DYP```#KO8M=#(7;=0WV +XMAZP$```(#X6V````N@,```")^.C+ZO__N@$```"%P'5-BU7LBUH(.?-U#NLX +XMC;8`````BQLY\W0H]H.O!````G3QB1PDQT0D"`````")?"0$Z(W5__^+&[@! +XM````.?-UV(7`=7B#CZP$```(,=*#Q!R)T%M>7UW#BU7LBUH(B=:#Q@@Y\P^$ +XMW?[__SG[=`J!BZP$``!````"BQLY\W7LBT7L]H>8`@```8M8"`^%P_[__XN' +XMD`(``(7`#Y7`ZS' +XM1"0$`````(D\)/^2F`@``#'2@X^L!```".EO____D)"0D%6)Y8M-"%/V@10" +XM```!BY&<````=&*+@0P"``"-!$#!X`(#01"+0#B%P`^5P(3`=%:+@L0!``#V +XM@9@"```!BY+``0``BU@$=%V+@9`"``"-!$#!X`(#01"+2#B%R0^5P,'@'\'X +XM'X/@"(T4$RG"BT4,B1`QP%M=PXN9#`(``(7;#Y7`A,!UJHN"Q`$``(N2P`$` +XM`(M8"(/K`0^O63CV@9@"```!=:.+@9`"``"%P`^5P.NMC;8`````C;PG```` +XM`%6)Y5=64X/L3(U%\(E$)!"-1>R)1"0,QT0D"`````"+10R)1"0$BT4(B00D +XMZ!_&_/^+=>R%]@^$A0$``(M=\(7;#X1Z`0``BU4(]H(X`@```0^%\````(M- +XM"(M%"(N),`(``(E-W/:`%`(```$/A/D```")PHN`#`(``(T$0,'@`@-"$(M` +XM.(E%V(M-"#'2,?^+11#W<3B)5/^__\Q_^G<_O__ +XM@\1,,/_#[9%XW1W +XMBU4(C01``<`#0A`/MH!=`0```<,)=&:#ZP$I3D#____BT7`"`T(0BT@XZ\R)^#'2]_''1`"`T(0BT`XB474,?^%VP^$$@$``(L[B77@QT70`````.M7@/O_#[;# +XM#X1]`0``BU4(C01``<`#0A`/MH!=`0```470C30PBT74A`" +XM`T(0BT@XBT70,=+W\8G(*=#I>____XM%"(N0D`(``(72#Y7`Z=C^__^-=@"` +XM^_\/ML,/A!"+51B%TG0)BU48B?`IV(D"@\0\B?!;7E]=PXM%"(N(R`,``.G+_O__ +XMB?`QTO?QQT70`````"G6Z6W^__^)1"0$BT4(B00DZ,ZR_/_IY_[__XG"BX#( +XM`P``C01`P>`"`T(0BT@XZ3C___^+3=B%R720BU4(BT(0#[:`-0(```'&Z7S_ +XM__^)R#'2]W7,,?\IT>G(_O__C47PBU4(B40D$(U%#(E$)`R+11#'1"0(```` +XM`(D4)(E$)`3H'<#\_XM%\(7`=1F+11B%P`^$0O___XM5&,<"`````.DT____ +XMBT4,A<")1=P/A1W]___KUXVV`````(V\)P````!5B>564X/L((M="(MU$/:# +XM%`(```$/A)@```"+@PP"``"-!$#!X`(#0Q"+0#B%P`^5P(3`=6^%]@^$A0`` +XM`(L&A7<.Z`0```(/$((G06UY=PXN##`(``(7`#Y7`Z6____^+ +XM@YP```"+50PYD*P!```/A6S___^+D+`!``#KRE6)Y5=64XG#@^PLB57@BW`0 +XM@W@T`71_C47LB40D"(U%\(E$)`2)'"3_EG`(``"+1>"%P'17,?^)'"3_EG0( +XM``"+0T"+4S2+CI`(```YT'(#C4+_QT0D"`````"#QP&)1"0$B1PD_]&)'"3_ +XMEH@(``"+1>R)1"0(BT7PB1PDB40D!/^6D`@``#M]X'6K@\0L,R)'"2)1"0(BT7PB40D!/^6D`@``(D<)/^6B`@``#M] +XMX'0WBU-`BT,TBXZ0"```.<)RJX/H`NNIQT0D"`````#'1"0$`````(D$)/^6 +XMD`@``(D<)/^6;`@``(/$+#'`6UY?7<.)]HV\)P````!5B>575E.#[`R+?0B+ +XM=0SVAQ0"```!=#B+APP"``"-!$#!X`(#1Q"+6#B%VP^5P(3`="R+!CM%$'=S +XMBW40*<:#Q`R)\%M>7UW#C;0F`````(N/#`(``(7)#Y7`A,!UU(L>.UT0=%8Y +XM71!S88MV"(/K`8/N`3E=$'?&.W44=@?KOSEU%'*ZB5PD!(/K`<=$)`@````` +XMB3PDZ&3\__\!QCE=$';=@\0,B?!;7E]=PXG&*W40@\0,6XGP7E]=PXMV"(/$ +XM#%N#[@&)\%Y?7<.)7"0$@\,!QT0D"`````")/"3H'?S__RM&"#E=$(UP`753@^P4BU4(BUT0BTT,QD,6`/:"%`(```%T-HN"#`(``(T$0,'@ +XM`@-"$(M`.(7`#Y7`A,!T*HL!@^@!B0.+002)0P0QP(,[``^4P(/$%%M=PXN" +XM#`(``(7`#Y7`A,!UUH-Y"`%T&XL!B0.+00B#Z`&)0P@QP(,[``^4P(/$%%M= +XMPXL!@^@!B0/'1"0(`````(E$)`2)%"3H0OO__XE#".NBC;8`````C;PG```` +XM`%6)Y593@^P0BU4(BUT0BW4,QD,6`/:"%`(```%T,HN"#`(``(T$0,'@`@-" +XM$(M`.(7`#Y7`A,!T)HL&@\`!B0.+1@2)0P2#Q!`QP%M>7<.0BX(,`@``A<`/ +XME<"$P'7:QT0D"`````"+!HD4)(E$)`3HN_K__SM&"'06BP:)`XM&"(/``8E# +XM"(/$$#'`6UY=PXL&QT,(`0```(/``8D#ZZ95B>575E.#[#R+?0B+=0R+71"+ +XM3SR+AYP```"%R8N`C`$``'00,=*#P@'&0!8`@\`8.<````BX*0`0``ZPV0C70F`(N7G````(G8.X*,`0``#X8-`0``C5CHB5PD +XM"(E$)`2)/"3H"?[__X7`=-6^`0```(N'G````(N`C`$``(DPBX><````BX", +XM`0``QT`$`````(N'G````(N`C`$``,=`"`$```"+AYP```"+7SR+@(P!``#K +XM`HGP@^L!#X2A````C7`8B70D"(E$)`2)/"3H3?[__X7`=-Z+AYP```"+@(P! +XM``#'``$```"+AYP```"+@(P!``#'0`0`````BX><````BX",`0``QT`(`0`` +XM`(N7G````(N"C`$``.L+C78`BY><````B=@[@I`!``!S,8U8&(E<)`B)1"0$ +XMB3PDZ-W]__^%P'39@\0\N`$```!;7E]=PX7V#X44____Z4/___^#Q#PQP%M> +XM7UW#QT7<`0```+H!````QT7@`````,=%Y`$```"+1SR#^`%T!(G"T>J-7=R) +XM5"0,B70D"(E<)`2)/"3HJ/O__XM7/+D!````@_H!=`2)T='I.<$/@ZK^__^) +XM7"0$B3PDZ*.Z_/^%P`^%<````BY"0`0``BT7")0@2+AYP```"+D)`!``"+1>2)0@CIO_W__XN'G````(N` +XMD`$``(DPBX><````BX"0`0``QT`$`````(N'G````(N8D`$``,=$)`@````` +XMB70D!(D\).BA]___B4,(Z7;]__^+3SR+EYP```#1Z8T$2<'@`P."C`$``(DP +XMQT`$`````,=`"`$```#K`HG8BY><````BXJ,`0``.L(BY><````B=@[@I`!```/ +XM@S+^__^-6!B)7"0(B40D!(D\).C>^___AF,_?__D(UT)@!5B>6#[#B+ +XM112)=?B+=1")??R+?0B)7?2#^`(/A+\```"#^`-T4H7`=4F+AYP```"+D)`! +XM``")T2N(C`$``(G(P?@#:<"KJJJJ.<8/A@4!``#'1"0(R`T)",=$)`0"```` +XMB3PDZ,?J_/^X`0```.G6````Z&P\_/^+AYP```"+D(P!``"+@)`!```IT,'X +XM`VG`JZJJJCGP-!':%]HT@?`=#1^`'PC01`C1S!@'L6``^$!@$``(L#BTT,B0&+ +XM0PR)000QP(M=](MU^(M]_(GL7<.-!':)T\'@`RG#B47@BP.)/"2)1"0$Z`^W +XM_/^%P'6[C47PB40D!(D\).B@?`=#1^(T$0,'@`RG#Z?;^__^-M@````#'1"0,`````,=$)`@````` +XMB5PD!(D\).CDL/__A<`/A-;^__^X`0```.G;_O__BX",`0``ZYF+AYP```"+ +XM@(P!``#I*?___XGVC;PG`````%6)Y593@^P0BW4(BX:<````BU9,BYB,`0`` +XMBPLYRG(@BX"0`0``.Q!W%CG*=%F)]H/#&#L3=?DYV'-0D(UT)@"#Q!"X`0`` +XM`%M>7<.-="8`QT0D#`````#'1"0(`````(E<)`2)-"3H1+#__X7`=="+0Q`[ +XM1E!S+(N&G````(/#&(N`D`$``#G87<.-M"8`````C;PG`````%6)Y5.#[!2+70B+0Q#' +XM1"0(`````,=$)`0`````B1PD_Y"0"```N@$```")V.BN]?__A<`/A88```"+ +XM2S2#^0$/A(H```"+@YP```"+D(P!``"-!$F-!,7H____B40D"(E4)`2#PAB) +XM%"3H53W\_XN#G````(N`C`$``(E$)`B#P!B)1"0$B1PDZ$+W__^%P'4NQT0D +XM#`````#'1"0(`````(N#G````(N`C`$``(D<)(E$)`3H-J___X/$%%M=PX/$ +XM%+@!````6UW#D(UT)@"+@YP```"+@(P!``")1"0(ZZ"-M"8`````C;PG```` +XM`%6)Y5.#[!2+70B+0Q#'1"0(`````,=$)`0`````B1PD_Y"0"```N@$```") +XMV.AN\___A<`/A88```"+2S2#^0$/A(H```"+@YP```"+D(P!``"-!$F-!,7H +XM____B40D"(U"&(E$)`2)%"3H93S\_XN#G````(N`D`$``(E$)`B#Z!B)1"0$ +XMB1PDZ`+W__^%P'4NQT0D#`````#'1"0(`````(N#G````(N`D`$``(D<)(E$ +XM)`3H1J[__X/$%%M=PX/$%+@!````6UW#D(UT)@"+@YP```"+@)`!``")1"0( +XMZZ"-M"8`````C;PG`````%6)Y5=64X/L/(M%"(M=$(M]#(N`G````(7;#Y3" +XMB=:)1=!U3(7_=4C'1"0$`@```(M-"(D,).@5L_S_A^@*-_S_C;8`````BT4(BY"<````Z[V0C70F`(/_`76PZ5[___^-M@````"+ +XM==!F@X[(`0``$,>&K`$```````"+10@Y>$P/A'\!``"+50B+@JP$``"I```` +XM$'5UJ!!T8HM-T#'`9H.)R`$```B#Q#Q;7E]=PXVV`````(/[`@^%-____XMU +XM"(M./(7)=`\QTH/"`8,``8/`&#G*=?.+50B+0DPYQW<&@\`!B4),BTW0,7UW#BX*<````@[A<`0```7>/BW4(C57LBT80B50D"(U5 +XM\(E4)`2)-"3_D'`(``"#^P(/A!H!``"#^P,/A&L!``"#ZP$/A??^__^+EIP` +XM``"+BHP!```[.8G+=`>#PQ@[.W7YBT4(]H`4`@```0^$M0$``(G&BX`,`@`` +XMC01`P>`"`T80BT`XA<`/E<"$P`^%B@$``(N2D`$``(U#&#G0#X=Y`0``.WL8 +XM#X5P`0``O@$```#K"XVT)@`````[.'4*@\`8@\8!.=!V\HM5"#MR/`^"C0(` +XM`(.*K`0``""+==!F@X[(`0``((MU"(M5[(M&$(E4)`B+5?")-"2)5"0$_Y"0 +XM"```,<#I\OW__V:#CL@!```!Z73^__^+=0B+3CR%R706,=*-M"8`````@\(! +XM@R@!@\`8.G_O__@^@!B4),Z9S^__^+50B+@IP```"+ +XMF(P!``"+2P2)3=0[.W0(D(/#&#L[=?G'1"0(`````(E\)`2+=0B)-"3HXN[_ +XM_SM&/(G!#X+J`@``@XZL!```((M-T&:#B<@!```@Z3S___^+=0B+EIP```"+ +XMLHP!```[/G0'@\88.SYU^8M%"/:`%`(```$/A'H!``")P8N`#`(``(T$0,'@ +XM`@-!$(M8.(7;#Y7`A,`/A`H!``")\\=%X`$```#'1=@!````BTT(BT7@.T$\ +XM`!.=AS\<=$)`@`````B7PD!(M5"(D4).@D[?__B478 +XMZ;?^__^+10B+B`P"``"%R0^5P.F,_O__BU4(BT(0B=HIRL'Z`VG2JZJJJL=$ +XM)`@`````B50D!(M-"(D,)/^0D`@``(M%"(GRZ+3M__^%P`^%(O___XM5"(T$ +XM=HT\Q0````"+@IP```"+@)`!``")'"0IV,'X`VG`JZJJJH/``2GPC01`P>`# +XMB40D"(T$'XE$)`3HGC;\_XM-"(N!G````(N0D`$``(G0*?@YV'(=@RL!@\,8 +XM.=AS]HMU"(N&G````(N0D`$``(G0*?B-6!B-0^B)WCG0`#B40D".A;-?S_BU4(BX*<````.["0`0``=Q>#!@&# +XMQAB+30B+@9P````YL)`!``!SZ8MUW(7V#X1$_/__O@$```#K#X/&`3MUW`^' +XM,?S__X/#&(D[BT74B7,(QD,6`(E#!,=$)`P`````QT0D"`````")7"0$BU4( +XMB10DZ!"G__^%P'2_Z1W]__^+30B+@9P```"+@)`!``")="0$*?#!^`-IP*NJ +XMJJJ#P`$IV(T$0,'@`XE$)`B-!%N-!,:)!"3HH#3\_XM%V(7`#X3]^O__BU4( +XMBX*<````.["0`0``#X?H^O__NP$```#K*9"-="8`.UW8#X33^O__BU4(@\88 +XMBX*<````.;"0`0``#X*[^O__@\,!B3Z)7@C&1A8`QT0D#`````#'1"0(```` +XM`(ET)`2+30B)#"3H5*;__X7`=+#I8?S__XM-"(M=X"M=V(M1$,=$)`@````` +XMBX&<````B?$KB(P!``")R,'X`VG`JZJJJHE$)`2+10B)!"3_DI`(``"+10B) +XMVNBDZO__A<`/A1+\__^+50B-!%O!X`.)1`#B40D"(M%S(DT)`'PB40D!.B-,_S_BT78A",9&%@#'1"0,`````,=$)`@`````B70D!(M-"(D, +XM).A]I?__A<`/A8O[__\[7=AUQ8MU"(N&G````(N0D`$``(G0*T7,C7`8C4;H +XMB?,YT',;B70D"(E$)`2+10B)!"3HS>W__X7`#X5+^___QT0D#`````#'1"0( +XM`````(ET)`2+50B)%"3H%J7__X7`#X4D^___BTT(@\88BX&<````BY"0`0`` +XM.=IUG^DO^?__B?/'1>``````Z6K[__^0C70F`%6)Y5=64X/L?(M]"(MU$(N' +XMG````&:#B,@!```!C47PB40D!(D\).@$]/__A<`/A7P!``"#?10'=@N-M@`` +XM``#H/R[\_P^V312P`=/@J(X/A6@!``"H<73ABX><````BUWPBY",`0``BPJ# +XM^0$/A-$#``"+1T`Y1T0/A!\$```YQ@^"NP(``(L"B46\BT($B47`BT((B47$ +XMBT(,B47(BT(0B47,BT(4B470B?CH?^G__X7`#X7W````A?9T?3';D.LKBT78 +XM@\,!BTW4.?.)1<"+1=R)3;R)1<2+1>")12)1B)1=!T4(U%U(U5 +XMO(E$)`B)5"0$B3PDZ+WK__^%P`^%I0```(-]U`%UL?:'%`(```$/A!8&``"+ +XMAPP"``"-!$#!X`(#1Q"+0#B%P'4&@WW<`76(BTW4BX><````BY",`0``B0J+ +XM1=B)0@2+1=R)0@B+1>")0@R+1>2)0A"+1>B)0A3'1"0(`P```,=$)`0````` +XMB3PDZ(_L__^%P'4KQT0D#`````#'1"0(`````(M-#(D\)(E,)`3H_.___X7` +XM#X1@`@``C70F`+@!````@\1\6UY?7<.+3?"-1=2)39R)1"0(BX><````BX"0 +XM`0``B3PDB40D!.B.Z___A<````BX"0`0``B3PDB40D!.@[ZO__A<`/A"/_ +XM___I;O[__XM%%(7`#X0Z_?__@WT4!0^$X0```(U%[(E$)`2)/"3HRO#__\=% +XMF`````"%P`^%PP```(7V='2+1SP[1T!U2.MJBX<,`@``C01`P>`"`T<0BT`X +XMAR+30R+$(D1BT`,B4$$A?8/A0(#``"#?10%#Y5%JX!]JP!T%(-] +XM%`)T#HM-#(M!!(7`#X2\`@``@\1\,_[___'1"0$`````(D\).@\<````BYB,`0``QT6P`0```.F9_O__BX><````BY"0 +XM`0``BP*)1=2+0@2)1=B+0@B)1=R+0@R)1>"+0A")1>2+0A2)1>B)^.C+X___ +XMA<`/A4/[__^%]@^$20,``#';ZU*-M"8`````BT6\.T74=!2)1"0$B3PDZ(RC +XM_/^%P`^$(@,``(M%P(/#`8M-O#GSB478BT7$B4W4B47R+30R+$(D1BT`,B4$$A?8/A!#\ +XM__\QV\=%H`````#K$X-]%`<```` +XMBX"0`0``B3PDB40D!.@WY?__A<`/A6_Y__^+AYP```"+5=2+@)`!```Y$'04 +XMB50D!(D\).C`H?S_A<`/A"H!``")/"3H<.W__X7`#X4X^?__@WT4`G6)BX>< +XM````BU6<.Y",`0``=S#'1:`!````Z7;___^%VW0IBX><````BTV<.XB,`0`` +XM#X9=____@^D8B4V<````BU6<.Y"0`0``=1OK.(UV`(/N`70P +XMBX><````BTV<.8B0`0``=!^+79R#19P8BU6`#*<.)7:SI?/O__XM% +XME(7`#X2;^?__BP.+30R)`?:'%`(```$/A&@!``"+APP"``"-!$#!X`(#1Q"+ +XM0#B%P`^5P(3`#X0Y`0``BTL$BT=4,=+W=SB-%!&)5"0(BP.)/"2)1"0$Z&37 +XM__^+50R)0@3I/?G__\=$)`P`````QT0D"`````")3"0$B3PDZ.V9__^%P`^$ +XM_/K__^FP]O__@WT4`P^$@P```(-]%`>)]@^%)/7__^E*_O__BT6@A<`/A.;X +XM__^+39R+50R+`8D"]H<4`@```0^$V@```(N'#`(``(T$0,'@`@-'$(M`.(7` +XM#Y7`A,`/A*D```"+19R+2`2+1U0QTO=W.(T4$8E4)`B+39R+`8D\)(E$)`3H +XMKM;__XM5#(E"!.E_^/__A?8/A87]__^+AYP```"+@(P!``")19SIO/W__\=$ +XM)`P`````QT0D"`````")3"0$B3PDZ!N9__^%P`^$I?W__^G>]?__QT64```` +XM`(VT)@````#IA?G__XM+"(/I`0^O3SB0Z;K^__^+MPP"``"%]@^5P.F?_O__ +XMBU6R+3P2#P`@YP0^$ +XM0`$``(GRB?LQP`%32"ES-`%!2(M!1`%Q-`%Q/#M!0`^$\0```(N1G````(T$ +XM=@%Q0(T\Q0`````!NI`!``"+0T"!B:P$```@```"*7,\*?`[0T2)0T!S`XE# +XM1(N#G````"FXD`$``#'`@8NL!```(````NLEQT0D#`$```#'1"0(+`X)",=$ +XM)`0"````B3PDZ*_/_/^X`0```(M=](MU^(M]_(GL7<,QP.OO*=:-M"8````` +XMBU7LBQ^#P@@YTW0(C48!.4-`)\(G[]]@QTNFN_O__D(VT)@````!5B>57 +XM5E.#[`R%THE5\(M`$'1_BW`0C7@0.?=T?XGSZP:+&SG?="^+0R"+5?"+0`B) +XM5"0$B00DZ`@C_/^%P'7A@\0,B=A;7E]=PXVV`````(LV.?=T1HM&((M8",=$ +XM)`0O````B1PDZ&@A_/^%P'0#C5@!BT7PB1PDB40D!.C"(OS_A+ +XM1TR)0A"+1U"+5R")0A2+1R!F@T@8`8N'G````(&/K`0````0``"+EIP```") +XM=Q2+@+0!``")@K0!``"+1SB)1CB+1S2)1C2+1TB)1DB+1D0[1D`/A#,!``#V +XMAFP$```!#X7[````BX9D!```BU=`B48\.=")1D0/A@G````-'HB8:$````QT0D!!@```"+@[0!``"#P`&)!"3H/2+\_X7` +XMB8.,`0``#X3@````BXZ<````BT8\BY&,`0``C01`@^H8C03"B8&0`0``QT0D +XM"`$```"+1DR)-"2)1"0$Z$;>__^Z`0```(7`=5F+3?"+%H/!$#G*#X3/```` +XMBT8$B4($BT8$.<$/A+,```")$(L'B7X$B0:+1?"+%X/`"#G"#X2/````B7($ +XMBX:<````,=*)-V:#B,@!```!@8ZL!```0````H/$'(G06UY?7<.+AF0$``"+ +XM5T"-!$#!X`(#1A"+0#@YT(E&/(E&1`^'^?[__XM&0.GW_O__BT8T@^@!B49$ +XMB49`B48\Z>O^__^)-"3'1"0(`````,=$)`0%````Z$/,_/^#Q!RZ`0```%N) +XMT%Y?7<.+5?")<@SI:?___XM%\(E0$.E$____BU7PBT8$B4(4BQ;I)____XVT +XM)@````"-O"<`````58GE5U93@^P%]@^$KP```(M&1#M&0`^$R0```(M&-(N6G````(/H`8E&0-'HB8:$ +XM````BT8\BXJ0`0``C01`P>`#`X*,`0``BQ&-6.B)4.B+002)0P2+00B)0PB+ +XM00R)0PR+01")0Q"+012)0Q2+CIP```"+1CR+D8P!``"-!$"#ZAB-!,*)@9`! +XM``"#??`!=#>#??`"=`7HS!S\_\=$)`@`````QT0D!`````")-"3H0-S__X&. +XMK`0```````*#Q!PQP%M>7UW#QT0D"`,```#'1"0$`````(DT).@4W/__Z]*) +XM]HM&-(/H`8E&1(E&/.DF____BQDQ]CG:#X0`____BT%(B=Z)0TB+030!0S3' +XM1?`"````Z>;^__^)]HV\)P````!5B>564X/L((M="(U%](MS$(E$)`2)'"3H +XM<_[__[H!````A`C`$```````"+1?2!BZP$````$```B4,4@\0@B=!;7EW# +XMBT,$B48,BT,$BQ,YP768D(E6"(U6$(D3BT84B4,$.U80=9:)7A#KEL=$)`A8 +XM#@D(QT0D!`,```")'"3HL,G\_[H!````Z[")]HV\)P````!5B>575E.#[#R+ +XM=0B+?0R+1A")1>"#?C0#=RW'1"0,`P```,=$)`B0#@D(QT0D!`,```")-"3H +XM9@2)/C';BT8TN@$```"# +XM^`%T`XU0_XM/-(E60+H!````@_D!=`.-4?^)5T"+5=PY5=@/A.(!``"%VW0# +XM*4X\BT9`.48\=@.)1CPY1D1V`XE&1/:&;`0```$/A=X```"+AF0$``")1SR) +XM1T2+1T`Y1SQV`XE'/#M'1',#B4=$@WXT`8N.G`````^$?`$``(N1C`$``(M& +XM/(/J&(T$0(T$PHF!D`$``(N/G````(-_-`$/A$@!``"+D8P!``"+1SR#ZAB- +XM!$"-!,*)@9`!``"+1D#1Z(7`B8:$````=0K'AH0````!````BT=`T>B%P(F' +XMA````'4*QX>$`````0```(N'K`0``(N6K`0```T@```"@^(/"=")AZP$``"# +XMQ#PQP%M>7UW#C70F`(/[!@^&"_[__[L&````Z0'^__^+AF0$``"-!$#!X`(# +XM1A"+0#CI$?___XVV`````(U%\(E$)`2)-"3H8=[__S'2A-(M/ +XM-(E'2(M&!`%.2(E'!(M%X(M6!(/`"#G"#X3<````B3J+AIP```"[`0```(E^ +XM!(N0C`$``(M&0(D4)"G(C01`P>`#B40D"(T$28T$PHE$)`3H51S\_^D(_O__ +XMBX&,`0``Z;_^__^0BX&,`0``Z8O^__^0C70F`(/X`;H!````=`.-4/_VAFP$ +XM```!B58\B59$=#R+AF0$``"-!$#!X`(#1A"+0#B)1SR)1T2-0?\Y1SP/AB3^ +XM__^#Z0%T.(E'/.D4_O__BU7@B7H,Z9#]__^+AF0$``#KSL=$)`@`````QT0D +XM!`4```")-"3HV,7\_^G@_/__N`$```#KP8M%X(EX"(M/-(UV`.D5____C70F +XM`(V\)P````!5B>575E.#["R+112+=0B+?1"%P(M>$'1KB?J)\.BN]O__BU4, +XMB47PBT7PA<")`G1[BWT4A?\/A:4```"+%HU+"#G*#X0&`0``BT8$B4($BT8$ +XM.<$/A!D!``")$(U3$(D6BT,4B48$.U,0#X3[````BT,4B3")SW]HG!,<#K$XUV`#M]['9/,2)1=2+1="+5=2%R70']]B#T@#WVH/$,%Y?7<.%]G4+N`$````QTO?VB<&+ +XM1>R)^O?QB<:+1?#W\8G!B?#KO`^]QX/P'XE%Z'5$.7WL=P4Y=?!RG+D!```` +XM,<#KGO==V(-5W`#W7=R%_\=%Y/____\/B4O___^0C70F`(GPB?KWV(/2`/?: +XM]U7DZ3/___^X(````(GR*T7HB<'3Z@^V3>B)1?2)^(G7BU7LT^`)QXM%\-/F +XM#[9-]-/H#[9-Z-/B#[9-]`G0BU7LB47,T^KW]XE5S(G']^8Y5'`@)````'5S86=E.B!E>"!;+65&4G)3F5= +XM(%MF:6QE("XN+ET*`````$5R7!E"@!L +XM:6YE]!`B`O00(Y;D$"*Z]!`AS +XM;7-O`')MC0@(`````&"<"`AHC0@(:XT( +XM"`````"#C0@(+_8("(F-"`@`````EHT("!+V"`B&ET('=I;&P@9&ES8V%R +XM9"!M;V1I9FEC871I;VYS`````#(V-'Q&:6QE(&UO9&EF:65D('-I;F-E(&QA +XM2!T:&%N('1H:7,@8V]P>0``,C4X?"5S +XM(&5X<&%N9&5D(&EN=&\@=&]O(&UA;GD@9FEL92!N86UE6]U`#(T,'PE +XMF4@979E;G0`,C@W?%5N97AP96-T960@=W)I=&4@979E;G0` +XM``"S"P4(]`L%",$,!0BS"P4(APP%"*0,!0@9#`4(LPL%"+,+!0@S#`4(30P% +XM"&H,!0C""P4(610%"&41!0B"$04(@A$%"%D4!0A9%`4(@A$%"$T4!0@P,3(S +XM-#4V-P`P,3(S-#4V-S@Y86)C9&5F````,#`X?$5R"]V:3H@`"5S)2XJ2!O;F4@=&%G(&9I;&4@;6%Y(&)E('-P96-I9FEE9"X`+7,@ +XM;W!T:6]N(&ES(&]N;'D@87!P;&EC86)L92!T;R!E>"X`@#,%"'$S!0CO,04( +XM[S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04(8C,%"%,S!0CO +XM,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q +XM!0CO,04([S$%".\Q!0@O,P4([S$%"!PS!0CO,04([S$%".\Q!0CO,04([S$% +XM".\Q!0@-,P4([S$%".\Q!0CO,04([S$%".\Q!0CZ,@4(\#(%",DR!0CO,04( +XMMC(%"*LR!0@P,3=\36%R:R`E&ES=',`,C8X?&-O;F9I2!K97D@=&\@8V]N=&EN=64Z(``R-S!\4')E2!T;R!C;VYT:6YU92!;.B!T;R!E;G1E2!K97D@=&\@8V]N=&EN=64@6W$@=&\@<75I=%TZ +XM(``P,S!\5&AE(&9I;&4@)7,@:7,@;F]T(&$@;65S3TEULJ/R1@)R)<`'-H:69T=VED=&@].`!S:61EA"`@``````P````````##]0@(`(4%"`(````(````+:$("``` +XM`````````````*>\"`@``````P`````````UH0@(````````````````0J$( +XM"``````"`````````$VA"`@```````````````">V@@(```````````````` +XM6*$("'"%!0@``````````&&A"`@``````P````````!GH0@(``````$````` +XM````;:$("````````````````'>A"`@``````@````````"`H0@(<(4%"``` +XM````````B*$("'"%!0@``````````).A"`@``````@````````";H0@(L'\% +XM"```````````7(P(".""!0@"````"````*6A"`BP@@4(``````@```!8O`@( +XML'\%"```````````L=X("``````!`````````*JA"`@``````0````````"P +XMH0@(``````(`````````NJ$("``````!`````````+^A"`@``````````!`` +XM``#(H0@($(8%"`,`````````SZ$("."%!0@#`````````-,$"0BP?P4(```` +XM``````#7H0@(X(4%"```````````T+D("``````!`````````-VA"`@````` +XM`0````````#FH0@(<((%"`,`````````(J$("``````#`````````-&A"`C@ +XMA04(`P````````#QH0@(``````$`````````AIL("(!_!0@``````@```/BA +XM"`@``````P````````#_H0@(````````````````!J(("``````!```````` +XM``RB"`@``````@`````````3H@@(````````````````8*(("``````"```` +XM`````!FB"`@````````````````DH@@(,((%"`,`````````+:(("``````` +XM````(````(3="`@``````P`````````TH@@(``````,`````````/J(("``` +XM```"````0````$FB"`@```````````````!3H@@(````````````````7*(( +XM"``````"````0````&>B"`@```````````````!PH@@(```````````0```` +XM>J(("+!_!0@"````0````(*B"`@``````@````````!@P0@(``````,````` +XM````,(L("``````#````"0```(RB"`@```````````````"2H@@(```````` +XM````````FJ(("``````!`````````**B"`BP@04(``````````"LH@@(```` +XM````````````M*(("-"`!0@"````#````+JB"`A`@04(`@````P```"_H@@( +XM8(`%"`(````,````Q:(("``````!`````````,JB"`C0?P4(`@````````#1 +XMH@@(````````````````W*(("``````"`````````.2B"`@``````@`````` +XM``#OH@@(``````$`````````^*(("``````````````````````````````` +XM```````!HP@(`0````FB"`@"`````Z(("`,````$HP@(!0````>C"`@(```` +XM^Z$("`H````*HP@(#0```!V<"`@+````^)@("`X````-HP@($@```).-"`@3 +XM````K:$("!4````0HP@(&````!.C"`@?````':,(""(````@HP@()0```"2C +XM"`@F````,:((""P```"TL0@(*@```"FC"`@P````+:,("#(```!>H`@(-``` +XM`#*C"`@Z````-Z,("#<````ZHP@(.````#ZC"`@V````/<$("#X```!!HP@( +XM/0```$2C"`A"````1Z,("#P```!?BP@(/P```$JC"`@_````&O<("$D```!2 +XMHP@(3@```%6C"`A)````6*,("$L```!;HP@(3````+^_"`A-```````````` +XM```P-#E\5&AE('-E8W1I;VX@;W!T:6]N(&UU2!0A8+79I+7)E8V]V97(M9FEL93H@`%@M=FDM +XM2!F:6QE`````$9R;VTZ(')O +XM;W0@*$YV:2!R96-O=F5R>2!P2X@```E2`O(&]R +XM(#\`!"$C)BH\/3Y`?@`P.#!\56YK;F]W;B!C;VUM86YD(&YA;64`,6)C83$` +XM,#DX?%1H92`E2!N +XM;W0@8F4@>F5R;P!L<@`P.#9\57-A9V4Z("5S`'-C2`E;'4@;&EN97,@:6X@=&AE(&9I;&4`,3`S +XM?$EL;&5G86P@861D"!M;V1E +XM`````#`X-'PE"!T86)L92!E"!C;VUM86YD(&9A:6QE9#H@<&5N9&EN9R!C;VUM86YDP@4(N,(%"%W'!0A\Q`4(?,0%"`7'!0A\ +XMQ`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0BOQ@4(_<<%")['!0B>QP4(GL<%")[' +XM!0B>QP4(GL<%")['!0B>QP4(GL<%")['!0A\Q`4(?,0%"'S$!0A\Q`4(?,0% +XM"-W%!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4( +XM?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\ +XMQ`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(9\8%".O+!0CLR@4([,H%".S* +XM!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H% +XM".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4(Z\L%".S*!0CLR@4( +XM[,H%".S*!0CXRP4([,H%".S*!0CLR@4([,H%".S*!0CLR@4(FLL%".S*!0CL +XMR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S* +XM!0CLR@4(H\L%".3>!0B#W@4(@]X%"-C$%"-C&-E<'0@870@=&AE(&5N9``R-S-\16YT97)I;F<@ +XM97@@:6YP=70@;6]D92X`,3$T?$YO(&9I;&4@;&ES="!T;R!D:7-P;&%Y`"5S +XM)7,E'!A;G-I;VX@9F%I +XM;&5D`"$E3H@)7,`&5C=71E(&$@8G5F9F5R`#P`2!L:6YE(&YU;6)E<@!S +XM:&EF="!L:6YE5T`8V]P>0!C'5S86=E`%ME>'5=')C +XM(&9I;&4`(69.`%ML:6YE72!O6W!E;ET@6R]212]=(%MF;&%G2!L:6YEF4@6RLM +XM77)O=W,`5T@;&EN92!;9FQA9W-= +XM``!C;W!Y(&QI;F5S(&5L2!B6W5F9F5R2!S970I(&9I;&4@;F%M +XM90``8G)I;F<@82!B86-K9W)O=6YD960@72!;=VEN +XM9&]W7W-I>F5=(%MF;&%G2!D:69F97)E;G0@,,( +XM")S#"`C3O`@(T$,&"`````#:O`@(W;P(",##"`@1"PD(L$8&"$(```!ZL0@( +XM[,,("/6\"`C.V`@(X$@&"`````#+P0@(),0("%S$"`@E!`D(D$L&"``!``!^ +XMO`@($+T(""N]"`CXF`@(D$L&"``!``!^O`@(1KT(""N]"`A=O0@(8!$'"``` +XM``#;OP@(9;T("(S$"`B;T("+#$"`B'O0@(L)$& +XM"``%``!^O`@(BKT("-C$"`B7O0@(P%X&"`0```#:O`@(",4("#S%"`B>O0@( +XM\!`'"`````!/C0@(H[T("*J]"`C!O0@(``(&"#$```#5V@@(R+T("-N]"`CV +XMO0@(4&@&"$(```#[O0@(<,4("`"^"`@2]@@(X'$&"`$```#+P0@('KX(""N^ +XM"`A8O`@(T(4&"((```#\O0@(G,4(",#%"`B#E`@(('4&"$(````O]@@(0+X( +XM".C%"`C3]`@(X'$&"`$```#+P0@(6[X(""N^"`@(H@@(`&\&"`````!MO@@( +XM<+X("`S&"`B&O@@(<'(&"`````"-O@@(DKX("*&^"`C)P`@(T`8&"``!``"T +XMO@@(.,8("%C&"`C3!`D(<(4&"((```#\O0@(A,8("*C&"`C0N0@(L'H&"`$` +XM``#;O`@(N+X(",C&"`C1H0@(((4&"((```#\O0@([,8("-6^"`CCO@@(P"H' +XM"#0"``#;O`@(Z+X("!#'"`CSO@@(P"H'"#0"``#;O`@(^KX("#S'"`@'OP@( +XMX'L&"`````!/C0@($+\("'3'"`@;OP@(H`4&"``!``#5V@@()+\(")S'"`AV +XMO`@(,(8&"'$```#_]`@(-;\("-#'"`A+OP@(T(8&"`````#5V@@(4+\("%J_ +XM"`@$V0@(L(D&"#$```#;O`@(9;\("/#'"`@KH`@(,'L&"`````"-O@@(@[\( +XM")._"`BHOP@(,)$&"``$``"OOP@(LK\(""#("`C"OP@(T`0&"`````#5V@@( +XMR;\("$3("`C5OP@(T`4'"``!``#:OP@(W[\("'3("`C;O`@(,-X&"`(```#; +XMO`@(F,@("-3("`C(L0@(\)P&"``"``!]O`@(];\("`C`"`B1F@@(L*4&"``` +XM```@P`@(^,@("#C)"`B$W0@(4*L&"``"``!/C0@((\`("&C)"`@KP`@(8+(& +XM"`````".O@@(,L`("$#`"`A]H@@(X+,&"``"``#5V@@(6\`("&7`"`A^P`@( +XMX+,&"``"``#5V@@(AL`("&7`"`C-H0@(@'D&"$(````9C0@(D\`(")S#"`@] +XMP0@(,/8&"``!``#:OP@(L<`("'3("`C&P`@(4/4&"`````#5V@@(SL`("-O` +XM"`CPP`@($.\&"`````#:OP@(]\`("(C)"`@3P0@(L0@(<-P&"`(```#;O`@( +XM7,P("(3,"`@```````````````````````````````!.;R!C0!A9&0`8W-C;W!E +XM+F]U=`!C&5C(&-S8V]P92`M9&P@+68@)7,`````,S$R?"5D.B!N;R!S=6-H(&-S +XM8V]P92!S97-S:6]N```E2!C7!E.B!U2!Y;W4@;W(@2!Y;W4````Q,S!\)7,Z(&YO="!S;W5R8V5D.B!W2!M87!P960`,3,T +XM?%1H92`E2!B92!R96%D```Q-#9\)7,Z(')E860@;&]C +XM:R!W87,@=6YA=F%I;&%B;&4````Q-#E\3F\@8F%C:V=R;W5N9"!S8W)E96YS +XM('1O(&1I&5C=71E`'!Q&ET960`0V]N=&EN=65D`$5- +XM5"!T'!IF4@;&EM:70@97AC965D960````````` +XM```````&````G]X("`X```"JW@@("@```+;>"`@4````P-X("!,```#-W@@( +XM!P```-?>"`@(````X-X("`$```#YW@@(!`````#?"`@=````%-\("`(````H +XMWP@(%P```#+?"`@&````/]\("`D```!(WP@(#0```$_?"`@;````6]\("`,` +XM``!SWP@("P```'C?"`@1````B]\("`P```">WP@(#P```*[?"`@%````N=\( +XM"!(```#(WP@(%0```-+?"`@6````YM\("!````#[WP@('@```!#@"`@?```` +XM)N`("!H````\X`@('````%+@"`@8````9N`("!D```!]X`@(,34R?'-H:69T +XM=VED=&@@;W!T:6]N('-E="!T;R`P`%)%(&5R+EM=)"H`,34S?$-O=6YT(&]V97)F;&]W`#$U-'Q#;W5N="!U;F1E +XM2!N +XM;W0@8F4@8V]M8FEN960@=VET:"!T:&4@8R!F;&%G(&EN('9I(&UO9&4`PL(& +XM"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8( +XM/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@C" +XMP@8(/<(&"#W"!@CXQ@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&".G& +XM!@@]P@8(VL8&"#W"!@@]P@8(6,8&"%C&!@A8Q@8(6,8&"%C&!@A8Q@8(6,8& +XM"%C&!@A8Q@8(6,8&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8( +XM/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@] +XMP@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W" +XM!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(+\8& +XM"#W"!@@]P@8(/<(&"!S&!@@]P@8(/<(&"#W"!@@]P@8(#<8&"#W"!@@]P@8( +XM/<(&"/[%!@@]P@8(FL(&"+_5!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZ +XMS@8(NLX&"+K.!@BCU08(H]4&"*/5!@BCU08(H]4&"*/5!@BCU08(H]4&"*/5 +XM!@BCU08(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX& +XM"+K.!@B-U08(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(&]8&"+K.!@BZS@8( +XMNLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(!=8&"+K.!@BZS@8(NLX&"+K.!@BZ +XMS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"(W5 +XM!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@@QU@8(NLX&"+K.!@BZS@8(NLX& +XM"+K.!@BZS@8(NLX&"+K.!@COU08(,38T?"5S.B!T:&4@=&%G)W,@;&EN92!N +XM=6UB97(@:7,@<&%S="!T:&4@96YD(&]F('1H92!F:6QE````,38V?"5S.B!S +XM96%R8V@@<&%T=&5R;B!N;W0@9F]U;F0`````,34Y?$QE2!A="!T:&4@;&%S +XM="!T86<@;V8@=&AI'5S86=E +XM(%MC;61=/$-2/B(*````1F]R(&$@=FD@:V5Y('5S86=E('-T871E;65N="!E +XM;G1E5T\0U(^(@H`````5&AE("5S(&ME>2!H87,@ +XM;F\@8W5R&ET+"!E;G1E0`Q-S1\57-A9V4Z("5S +XM`#$T-'PE2!F:6QE(&YA;65S```` +XM,C@S?%1H92`E"!T97)M:6YA;"!I +XM;G1E"!T97)M:6YA;"!I;G1E2!O9B!#86QI9F]R;FEA+"!" +XM97)K96QE>2X````Q-S5\5&AE('9IB5C`#(U +XM,WQ72!S8W)E96YS`%Y#`%MC;W5N=%U>1`!;8V]U;G1=7D4`7D4@2!C:&%R86-T97)S`%MC;W5N=%U>2@!>2B!M;W9E(&1O=VX@8GD@;&EN97,` +XM7DP`7DP@2!L:6YE2!L:6YE +XM4@!>4B!R961R87<@5@!>5B!I;G!U="!A(&QI +XM=&5R86P@8VAA"!M;V1E`%Y=`%Y= +XM('1A9R!P=7-H(&-U`%Y>('-W:71C:"!T;R!P&ET`%M;`%M;(&UO=F4@8F%C:R!S96-T:6]N`%U=(&UO=F4@ +XM9F]R=V%R9"!S96-T:6]N`"!>(&UO=F4@=&\@9FER2!C;VQU;6YS`&U;82UZ70`@;2!S970@;6%R:P`@;B!R97!E870@ +XM;&%S="!S96%R8V@`6V-O=6YT76\`(&\@87!P96YD(&%F=&5R(&QI;F4`6V)U +XM9F9EB!R97!O02!S96%R8V@@9F]R=V%R9"!F;W(@8W5R +XM0R!I;G1E2!L:6YE2!L:6YE2!L +XM:6YE2!T +XM97AT('1O(&UO=&EO;B!I;G1O(&$@8W5T(&)U9F9E<@````!;;&EN95UZ6W=I +XM;F1O=U]S:7IE75LM?"Y\*WQ>?#Q#4CY=```````````````````````````` +XM````````````H(,'"")`5`"H[0@(!/@(")![!P@@``0`LNT("+SM"`@````` +XM`````-3M"`@H^`@(<'T'""``!`#7[0@(8/@("-!Z!P@```0`X>T(".OM"`B` +XM?`<((``$``/N"`@-[@@(0)4'"``````G[@@(*NX("&!>!P@@`$0`.>X("$/N +XM"`@`````````````````````,'X'"!@`1`!>[@@(:.X("``````````````` +XM````````<@<(`````'[N"`B![@@(P'X'"$@`1`"2[@@(D/@("#!^!P@8`$0` +XMG.X("*;N"`@`````````````````````$'\'"!@`1`"\[@@(QNX("``````` +XM````````````````<@<(`````-KN"`C=[@@(`````````````````````!`] +XM!P@@0```[NX("/'N"`C0?0<((``$`/SN"`@&[P@(```````````B[P@()>\( +XM"-!Y!P@`````0N\("$7O"`@`````````````````````,'L'"```!`!<[P@( +XM9N\("*!!!P@````">N\("'WO"`@``````````(_O"`B\^`@(D$0'"`````"; +XM[P@(GN\("(!`!P@@0!``M.\("+?O"`B@0P<(`````,_O"`C2[P@(```````` +XM`````````````*!X!P@@`$0`[>\("/3X"`BP/@<((``L`ACY"`@\^0@(```` +XM`````````````````*!%!P@@``X`^.\("`?P"`A@=P<(@`!$`"7P"`@O\`@( +XMH&0'"")`1`!&\`@(2/`(""!#!P@`````/+L("%GP"`@P9`<(*`!#`'#P"`AD +XM^0@($)('"")`1`!X\`@(@?`("-".!P@B0$0`E_`("*#P"`@````````````` +XM````````,'X'"$@`1`"Y\`@(C/D("%`T!P@@`$0`PO`("+CY"`@0?P<(2`!$ +XM`,OP"`C<^0@(``````````!!\0@(U/`("/")!P@B@$``[_`("/WP"`@`7@<( +XM(`!``+BB"`@/\0@(```````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM````````````````````````````,#H'"``````J\0@(0_$("``U!P@@`$0` +XM4?$("`CZ"`B@0@<((``L`%KQ"`AP\0@(`````````````````````"!"!P@@ +XM`"P`CO$(""SZ"`@0B@<((H!``*3Q"`BR\0@(T"X'""``!`'%\0@(S?$("/!6 +XM!P@@``P`W_$(".CQ"`APZ0<((`!$`/[Q"`@'\@@(```````````<\@@(+?(( +XM"```````````1O(("%#R"`CP[`<((`!$`&GR"`AR\@@(4#$'""``1@",\@@( +XM3/H("%"`!PA(`$4`G_(("*CR"`@`@`<("`%%`+CR"`AT^@@(<%8'""``#`#! +XM\@@(G/H("'`]!P@@``P`RO(("-/R"`@`````````````````````8'\'"`@! +XM10#A\@@(ZO(("+!_!P@(`44`<(L("`/S"`B`A0<((H!``/:B"`@<\P@(X%T' +XM""``#``S\P@(//,("`!Q!P@@`(P`4?,("+SZ"`B01`<(`````%OS"`A=\P@( +XMX%,'""``#`!R\P@(>_,("```````````D?,("*+S"`A0,@<((`!&`,#S"`C@ +XM^@@(T.('""`````$[P@(T_,("```````````````````````\0<((`!$`._S +XM"`CX\P@((/$'""``C``0]`@(#/L("```````````(?0("#+T"`@@]P<(```` +XM`#_T"`A"]`@(,(H'""!`1`!8]`@(6_0("```````````````````````C`<( +XM($!$`(H&"0AP]`@(\%\'""``1``!P@@`$0` +XMJO4("+/U"`C`5`<((``,`,OU"`C4]0@(,'X'"!@`1`#L]0@(]?4("!!_!P@8 +XM`$0`"_8("!3V"`B@>`<((`!$`"CV"`@Q]@@(<&0'"````@!*]@@(4?8("%"% +XM!P@B@$``]J(("%WV"`C`70<((``,`'/V"`A\]@@(`'`'""``C`"1]@@(5/L( +XM"``````````````````````@<@<((``,`)OV"`BN]@@(8%('""``C`##]@@( +XMU/8(",`S!P@@`$8`[/8("'C["`A`X@<((````/R6"`C_]@@(```````````` +XM`````````.#P!P@@`$0`$_<("!SW"`@0\@<((`",`#'W"`A"]P@(0/,'""`` +XMK`!6]P@(I/L("&#T!PA```4`T/L("'3W"`@P:0<((D!$`(WW"`B6]P@(X%X' +XM""``1`"M]P@(MO<(",!K!P@B0$0`R/<("-'W"`@0X0<((``,`.OW"`CT]P@( +XM,S`W?$YO(&5X(&-O;6UA;F0@=&\@97AE8W5T90`Q.#!\3F\@<')E=FEO=7,@ +XM9FEL92!T;R!E9&ET````,C`W?%1H92!1(&-O;6UA;F0@/!P@HCP<(*(\'""B/!P@HCP<(=X\'""B/!PAWCP<(*(\'""B/ +XM!P@HCP<(*(\'"(*/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\' +XM""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(@H\'""B/!P@HCP<( +XM*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@H +XMCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/ +XM!P@HCP<(*(\'""B/!P@HCP<(=X\'"#$Y-'Q.;R!M;W)E(&-H87)A8W1E\!PBJNP<(;ZP'"("[!PAOK`<(;ZP'"+^^!PA6O@<(;ZP'"$*_!PB_O@<( +XM/;X'"#V^!PAOK`<($[X'"(B]!PA@O0<(,KP'"%6[!PCYM`<(G+H'"(6Z!PB% +XMN@<(#K4'"/FT!PAIN@<(^;0'"/FT!PCYM`<(^;0'"$FZ!P@R,#%\0G5F9F5R +XM2!I;B!T:&4@9FER,'"#(P-GQ.;R!C:&%R86-T97)S('1O(&1E;&5T90#O]P<(,?@'""KX!P@J +XM^`<(0O@'"%7X!P@:^`<([_<'"._W!PCO]P<([_<'"/OW!PA5^`<($`@(""@( +XM"`@E#0@(YP0("$$-"`APX`<((``L`.D+"0C_"PD(,C,U?$YU;6)E2!I;B!C;VUM86YD(&UO9&4` +XM,C,V?$EN=&5R7,@9&ES8V%R9&5D`````#(S,7Q);G1E7,@9&ES8V%R9&5D```E9"!S8W)E96YS(&)A8VMG6]U'`@)````1L#.Z0!```!````]'C__\`!```````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````````````$^-"`@`````+!()"``````` +XM`````````````````````0```%P````"````7@````,````$````!````!(` +XM```%````%`````8````:````!P```#H````(````#0````D````;````"@`` +XM``P````+````&`````P````*````#0```'T````.````*0````\````)```` +XM$`````@````1````%0```!(````1````$@```!8````3````%P```!0````P +XM```````````````````````````````````````````````5`````0```"]D +XM978O<'1Y6%@``"SS"`@``````````````````````````!0``````````7I2 +XM``%\"`$;#`0$B`$``!P````<````+'?__X)`$"`8```#XA00("@```-`$```+````$````!4``````````P```#02 +XM"0@"````B`0``!0````1````%P```!B7!`@1````N)8$"!(```!@````$P`` +XM``@```#^__]OF)8$"/___V\!````\/__;TB5!`@````````````````````` +XM``````````````````````````````````````````#_____`````/____\` +XM`````````%`1"0@``````````,J;!`C:FP0(ZIL$"/J;!`@*G`0(&IP$""J< +XM!`@ZG`0(2IP$"%JIP$"(J!`@:G@0(*IX$"#J>!`A* +XMG@0(6IX$"&J>!`AZG@0(BIX$")J>!`BJG@0(NIX$",J>!`C:G@0(ZIX$"/J> +XM!`@*GP0(&I\$""J?!`@ZGP0(2I\$"%J?!`AJGP0(>I\$"(J?!`B:GP0(JI\$ +XM"+J?!`C*GP0(VI\$".J?!`CZGP0("J`$"!J@!`@JH`0(.J`$"$J@!`A:H`0( +XM:J`$"'J@!`B*H`0(FJ`$"*J@!`BZH`0(RJ`$"-J@!`CJH`0(^J`$"`JA!`@: +XMH00(*J$$"#JA!`A*H00(6J$$"&JA!`AZH00(BJ$$")JA!`BJH00(NJ$$",JA +XM!`C:H00(ZJ$$"/JA!`@*H@0(&J($""JB!`@ZH@0(2J($"%JB!`AJH@0(>J($ +XM"(JB!`B:H@0(JJ($"+JB!`C*H@0(VJ($".JB!`CZH@0("J,$"!JC!`@JHP0( +XM.J,$"$JC!`A:HP0(:J,$"'JC!`B*HP0(FJ,$"*JC!`BZHP0(RJ,$"-JC!`CJ +XMHP0(^J,$"`JD!`@:I`0(*J0$"#JD!`A*I`0(6J0$"&JD!`AZI`0(BJ0$")JD +XM!`BJI`0(NJ0$",JD!`@``````````````````````````````````````"1& +XM'`@)``D1G)E94)31#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6YA +XM;6EC`"YC=&]R!```-`$```` +XM``````````$`````````-P```/___V\"````2)4$"$@5``!0`0``!``````` +XM```"`````@```$0```#^__]O`@```)B6!`B8%@``(`````4````!````!``` +XM``````!3````"0````(```"XE@0(N!8``&`````$``````````0````(```` +XM7`````D````"````&)<$"!@7``"(!```!`````L````$````"````&4````! +XM````!@```*";!`B@&P``$0``````````````!`````````!@`````0````8` +XM``"TFP0(M!L``"`)``````````````0````$````:P````$````&````X*0$ +XM".`D```\Y0,````````````0`````````'$````!````!@```!R*"`@<"@0` +XM#```````````````!`````````!W`````0````(```!`B@@(0`H$`"N%```` +XM`````````"``````````?P````$````"````;`\)"&R/!``4```````````` +XM```$`````````(T````!`````P`````0"0@`D`0`%`$`````````````(``` +XM``````"3`````0````(````4$0D(%)$$`#P```````````````0````````` +XMG0````8````#````4!$)"%"1!`#0````!0`````````$````"````*8````! +XM`````P```"`2"0@@D@0`"```````````````!`````````"M`````0````,` +XM```H$@D(*)($``@```````````````0`````````M`````$````#````,!() +XM"#"2!``$```````````````$`````````+D````!`````P```#02"0@TD@0` +XM4`(`````````````!`````0```"^````"`````,```"@%`D(H)0$`.`,```` +XM`````````"``````````PP````$``````````````*"4!`"I$0`````````` +XM```!``````````$````#``````````````!)I@0`S````````````````0`` +X%```````` +X` +Xend +END-of-vi.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.sh new file mode 100644 index 0000000000..82933e372d --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/elfcopy-noops-5.sh @@ -0,0 +1,6 @@ +# $Id: elfcopy-noops-5.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-noops-5 tc/elfcopy-noops-5 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} tcsh tcsh.new" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/in/elfcopy-noops-5.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/in/elfcopy-noops-5.in.shar new file mode 100644 index 0000000000..f7b6173e4c --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-5/in/elfcopy-noops-5.in.shar @@ -0,0 +1,7116 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# tcsh.uu +# +echo x - tcsh.uu +sed 's/^X//' >tcsh.uu << 'END-of-tcsh.uu' +Xbegin 755 tcsh +XM?T5,1@$!`0D```````````(``P`!````(*0$"#0```"HVP0``````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(7)\$ +XM`%R?!``%`````!````$`````H`0``"`)"``@"0AT,0``](P"``8`````$``` +XM`@```$#.!`!`3@D(0$X)"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&0PGP0`,!\)"#`?"0@L````+`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`@P```*`````(``````````````"9````.0````````!1```` +XME@````````"#````G````',```",````2@```%X`````````4@````````") +XM````E```````````````<@```)\```!G`````````'H```!F````C@```$X` +XM``"'````%`````0`````````1`````,`````````#@```$(```"&````=P`` +XM````````````%P```)L```"-````-`````````!D`````````)X````````` +XM*P````````!V````;`````````!-````DP````````!%````?@```#L````` +XM````D0`````````W````````````````````)0````````!P`````````#`` +XM``!A````BP`````````V````20````````!M````E0````````!?````?0`` +XM`&D`````````:P````````!0````8@```'\````M````>``````````````` +XM``````````!6`````````&\```""````:@```)@```!&````,@````````!U +XM````6P````````":````3````(H````*````A0```````````````````)`` +XM``!8````;@```)T````8`````````(0```"2````5P```(`````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM````$0````8```````````````````````````````$``````````@`````` +XM```>````````````````````#```````````````)@````<````I```````` +XM```````G`````````"X````<`````````"`````C```````````````-```` +XM+P`````````D````%@``````````````````````````````/0````4````H +XM`````````#4````9````00``````````````````````````````$P```$@` +XM`````````````````````````````````````````````#H````````````` +XM`$`````X`````````!`````)````7````"(````_````&@````````!@```` +XM`````````````````````&@`````````5````"$```!9`````````!(````` +XM```````````````=``````````\````;````+`````````!Q`````````$<` +XM```Q``````````````!Y````8P``````````````6@```!4```!\````*@`` +XM````````````B````$L`````````=`````L```"!`````````!\```!#```` +XM,P```&4```![`````````$\```!3````70```#P`````````CP````````"7 +XM````50```#X`````````````````````````I`0````````S````$@```)$$ +XM````````,P```!(```"T`@```````$,````2````$0````````"U````$@`` +XM`(P"`````````````!(```"2`@```````"L````2````RP,````````R```` +XM$@```&\!````````*````!(```"Y`@`````````````2````2@$````````` +XM````$@```#0!````````:P$``!(```#K!````````#@````2````:0$````` +XM``#]"```$@```!D```!`3@D(`````!$`\?_W`@`````````````2````I0(` +XM````````````$@```"(`````````U`,``!(```"#`0```````#,````2```` +XMU`0`````````````$@```'L"````````(P```!(````+!0`````````````2 +XM````$@0````````=````$@```#0#`````````````!(````K`0```````!T` +XM```2````B@0`````````````$@````,"````````5P```!(```#(```````` +XM`#D````2````?@$``,"N!@C>!```$@`,`"`#````````E````!(```#(`@`` +XM`````#D````2````100`````````````$@```"@`````````E@```!(```"2 +XM`0`````````````2````80(```````!S````$@```.$!``"`40D(!````!$` +XM%P#:```````````````2````?0,````````<````$@```#L!```````````` +XM`!(````'!``````````````2````!P$```````!/````$@```.0$```````` +XM<@```!(```#!`P````````4````2````"P0```````!.!0``$@```%P#```` +XM````W0,``!(```#!```````````````2````(@(```````#8````$@```#$` +XM```(FP0(`````!(`"@!)`@`````````````2````HP,`````````````$@`` +XM`+`#````````,P$``!(````-`@`````````````2````M@$````````+```` +XM$@```&\$````````*@```!(```";```````````````2````X``````````` +XM````$@```)<"``#8=0D(!````!$`%P!#`P```````$T````2````2P,````` +XM````````$@```+,"````````*P```!(```#$!``````````````2````YP`` +XM``````#&!```$@```"P#````````(0(``!(```#9`0```````!4"```2```` +XM`P`````````````2````9@0```````!9 +XM````$@```%(#`````````````!(```"0`P`````````````2````=P,````` +XM```[````$@```!0#````````>````!(```#"`0```````$P````2````10`` +XM`/RP"`@`````$@`-`,X"````````C`(``!(```#:`@```````!`````2```` +XM_0(````````E`0``$@```/X#````````'0```!(```#:!````````.T````2 +XM````0@$`````````````$@```#X#`````````````!(```!D`P``X%T)"`0` +XM```1`!<`^P`````````E````$@```",!`````````````!(````\`@`````` +XM`&<````2````[@$```````!?````$@```)X$`````````````!(```!*!``` +XM,*<&"&,````2``P`%0(````````_````$@```)\$````````0P```!(```"H +XM`0```````,,````2````J@(```````!4````$@```!<%``!T40D(`````!`` +XM\?_0```````````````2````EP,```````!#````$@```*\!````````,P`` +XM`!(```!W`0`````````````2````2P```"Q/"0@`````$0#Q_QL$```````` +XM@0```!(````J!0``]*P+"``````0`/'_``4`````````````$@```(`$```` +XM````5P```!(````N!````````&(#```2````]0$```````!A````$@```$X$ +XM````````DP```!(```"7`0`````````````2````)P0````````K````$@`` +XM`&(!`````````````!(```"K!````````!P````2````M`0````````````` +XM$@```$0$`````````````!(````;`0`````````````2````RP0```````"C +XM````$@```.<#````````4@```!(````;`P`````````````2````>`0````` +XM````````$@```!`!````````B@```!(```"Z```````````````2````4P0` +XM``````#($0``$@```&$``````````````"````#+`0```````(H````2```` +XMOP(```````!,````$@```(D!`````````````!(````\`P```````"@````2 +XM````=0`````````4`0``$@```(("`````````````!(```"?`@`````````` +XM```2`````&QI8FYC=7)S97,N@<```(`+P4```````"`40D(!2,``(A1"0@%20`` +XMW%T)"`5?``#@70D(!7(``#A/"0@'`0``/$\)"`<"``!`3PD(!P,``$1/"0@' +XM!```2$\)"`<%``!,3PD(!P8``%!/"0@'!P``5$\)"`<(``!83PD(!PD``%Q/ +XM"0@'"@``8$\)"`<+``!D3PD(!PP``&A/"0@'#0``;$\)"`$\)"`<2``!\3PD(!Q,``(!/"0@'%```A$\)"`<5``"(3PD( +XM!Q8``(Q/"0@'%P``D$\)"`<8``"43PD(!QD``)A/"0@'&@``G$\)"`<;``"@ +XM3PD(!QT``*1/"0@''@``J$\)"```"04`D(!V```)10"0@'80`` +XMF%`)"`=B``"<4`D(!V,``*!0"0@'9```I%`)"`=E``"H4`D(!V8``*Q0"0@' +XM9P``L%`)"`=H``"T4`D(!VD``+A0"0@':P``O%`)"`=L``#`4`D(!VT``,10 +XM"0@';@``R%`)"`=O``#,4`D(!W```-!0"0@'<0``U%`)"`=S``#84`D(!W0` +XM`-Q0"0@'=0``X%`)"`=V``#D4`D(!W<``.A0"0@'>0``[%`)"`=Z``#P4`D( +XM!WL``/10"0@'?```^%`)"`=^``#\4`D(!W\```!1"0@'@```!%$)"`>!```( +XM40D(!X,```Q1"0@'A0``$%$)"`>&```440D(!X<``!A1"0@'B```'%$)"`>) +XM```@40D(!XH``"11"0@'BP``*%$)"`>,```L40D(!XT``#!1"0@'C@``-%$) +XM"`>/```X40D(!Y```#Q1"0@'D0``0%$)"`>2``!$40D(!Y,``$A1"0@'E``` +XM3%$)"`>5``!040D(!Y8``%11"0@'EP``6%$)"`>9``!<40D(!YH``&!1"0@' +XMFP``9%$)"`><``!H40D(!YT``&Q1"0@'G@``<%$)"`>?``"#[`SHX`D``.B[ +XM%00`@\0,PP```/\U,$\)"/\E-$\)"`````#_)3A/"0AH`````.G@_____R4\ +XM3PD(:`@```#IT/____\E0$\)"&@0````Z<#_____)41/"0AH&````.FP____ +XM_R5(3PD(:"````#IH/____\E3$\)"&@H````Z9#_____)5!/"0AH,````.F` +XM_____R543PD(:#@```#I````.GP_O___R5X3PD(:(````#IX/[___\E?$\)"&B(````Z=#^____ +XM)8!/"0AHD````.G`_O___R6$3PD(:)@```#IL/[___\EB$\)"&B@````Z:#^ +XM____)8Q/"0AHJ````.F0_O___R603PD(:+````#I@/[___\EE$\)"&BX```` +XMZ7#^____)9A/"0AHP````.E@_O___R6<3PD(:,@```#I4/[___\EH$\)"&C0 +XM````Z4#^____):1/"0AHV````.DP_O___R6H3PD(:.````#I(/[___\EK$\) +XM"&CH````Z1#^____);!/"0AH\````.D`_O___R6T3PD(:/@```#I\/W___\E +XMN$\)"&@``0``Z>#]____);Q/"0AH"`$``.G0_?___R7`3PD(:!`!``#IP/W_ +XM__\EQ$\)"&@8`0``Z;#]____)!/"0AH4`$``.E`_?___R7D3PD( +XM:%@!``#I,/W___\EZ$\)"&A@`0``Z2#]____)>Q/"0AH:`$``.D0_?___R7P +XM3PD(:'`!``#I`/W___\E]$\)"&AX`0``Z?#\____)?A/"0AH@`$``.G@_/__ +XM_R7\3PD(:(@!``#IT/S___\E`%`)"&B0`0``Z<#\____)010"0AHF`$``.FP +XM_/___R4(4`D(:*`!``#IH/S___\E#%`)"&BH`0``Z9#\____)1!0"0AHL`$` +XM`.F`_/___R444`D(:+@!``#I%`)"&B``@``Z>#Z____)7Q0"0AHB`(``.G0^O___R6`4`D(:)`"``#I +XMP/K___\EA%`)"&B8`@``Z;#Z____)8A0"0AHH`(``.F@^O___R6,4`D(:*@" +XM``#ID/K___\ED%`)"&BP`@``Z8#Z____)910"0AHN`(``.EP^O___R684`D( +XM:,`"``#I8/K___\EG%`)"&C(`@``Z5#Z____):!0"0AHT`(``.E`^O___R6D +XM4`D(:-@"``#I,/K___\EJ%`)"&C@`@``Z2#Z____):Q0"0AHZ`(``.D0^O__ +XM_R6P4`D(:/`"``#I`/K___\EM%`)"&CX`@``Z?#Y____);A0"0AH``,``.G@ +XM^?___R6\4`D(:`@#``#IT/G___\EP%`)"&@0`P``Z<#Y____)<10"0AH&`,` +XM`.FP^?___R7(4`D(:"`#``#IH/G___\ES%`)"&@H`P``Z9#Y____)=!0"0AH +XM,`,``.F`^?___R744`D(:#@#``#IA0"0AH8`,``.D@^?___R7L4`D(:&@#``#I$/G___\E\%`)"&AP`P``Z0#Y +XM____)?10"0AH>`,``.GP^/___R7X4`D(:(`#``#IX/C___\E_%`)"&B(`P`` +XMZ=#X____)0!1"0AHD`,``.G`^/___R4$40D(:)@#``#IL/C___\E"%$)"&B@ +XM`P``Z:#X____)0Q1"0AHJ`,``.F0^/___R4040D(:+`#``#I@/C___\E%%$) +XM"&BX`P``Z7#X____)1A1"0AHP`,``.E@^/___R4<40D(:,@#``#I4/C___\E +XM(%$)"&C0`P``Z4#X____)211"0AHV`,``.DP^/___R4H40D(:.`#``#I(/C_ +XM__\E+%$)"&CH`P``Z1#X____)3!1"0AH\`,``.D`^/___R4T40D(:/@#``#I +XM\/?___\E.%$)"&@`!```Z>#W____)3Q1"0AH"`0``.G0]____R5`40D(:!`$ +XM``#IP/?___\E1%$)"&@8!```Z;#W____)4A1"0AH(`0``.F@]____R5,40D( +XM:"@$``#ID/?___\E4%$)"&@P!```Z8#W____)511"0AH.`0``.EP]____R58 +XM40D(:$`$``#I8/?___\E7%$)"&A(!```Z5#W____)6!1"0AH4`0``.E`]___ +XM_R5D40D(:%@$``#I,/?___\E:%$)"&A@!```Z2#W____)6Q1"0AH:`0``.D0 +XM]____R5P40D(:'`$``#I`/?__P````!5B>564X/L$(/D\(M=!(G1C72=#(7; +XMB378=0D(?C:+10B%P'0OHP`@"0@/MA"$TG0C@\`!ZPH/MA"#P`&$TG04@/HO +XM=?&C`"`)"`^V$(/``832=>RX0$X)"(7`=#2)#"3H5_[__\<$)/RP"`CH2_[_ +XM_^AR]O__C44(B70D"(E$)`2)'"3HYQL``(D$).A+_?__Z-;X___KS9"0D)"0 +XMD)"058GE@^P(@#WD70D(`'0,ZQR#P`2C""`)"/_2H0@@"0B+$(72=>O&!>1= +XM"0@!R<.058GE@^P(H2A/"0B%P'02N`````"%P'0)QP0D*$\)"/_0R<.0D)"0 +XMD)"0D)"0D)"058GE@^P8Z%77``#'!>AV"@@`````QT0D!!````#'!"0````` +XMZ->``0"CM'8*",=$)`@!````QT0D!`(```")!"3HUO;__\=$)`01````QP0D +XM`0```.BF@`$`H\R7"@C'1"0(`0```,=$)`0"````B00DZ*7V___'1"0$$@`` +XM`,<$)`(```#H=8`!`*,$=@H(QT0D"`$```#'1"0$`@```(D$).AT]O__QT0D +XM!!,```"AM'8*"(D$).A#@`$`HT29"PC'1"0(`0```,=$)`0"````B00DZ$+V +XM__^A!'8*"(D$).A%_/__H_R9"PBAS)<*"(D$).@S_/__H^!U"0C)Z3S7``"- +XMM@````"-OP````!5B>6#[`B+10B+$(72=23'1"0$Q)@*",<$))`O"0CHO>`! +XM`#WX;PD(=!6)10C)Z0WP`P")!"3HY9\#`(7`=>O),<##C;8`````C;PG```` +XM`%6)Y5=64X/L'(MU"(-^"/\/A%@!``"+/;AW"@BAO'<*",<%N'<*"`````#' +XM!;QW"@@`````A?^)1?!^&3';B?:+5?"+!)J#PP&)!"3H7X,#`#G[=>N+1?") +XM!"3H4(,#`(U&3,=$)`@D(```B40D!,<$)*!W"@CH8?O__Z&T=@H(B00DZ!A[ +XM`0"+!J/\70D(BT8(H[1V"@B#?@3_=!6A1)D+"(D$).CV>@$`BT8$HT29"PB# +XM?@S_=!6AS)<*"(D$).C;>@$`BT8,H\R7"@B#?A#_=!6A!'8*"(D$).C`>@$` +XMBT80HP1V"@B+1B"CD'8*"(M&-*.\F`H(BT8DHTB:"PB+1BBC2'<*"(M&+*.T +XMF`H(BT8PHS"9"PB+1A2CP'8*"(M&&*/@F0L(BT87UW#HXR8"@CKNHM&0(7`=.J+"(7)=.3'1"0$Q)@*",<$ +XM)"0V"0CHDMX!`(7`=,S'10@D-@D(@\0<6UY?7>EKX`$`C70F`(V\)P````!5 +XMB>575E.!["P!``"A+)H+"(L5*)H+"(F%'/___Z$DF@L(B948____BQ4@F@L( +XMB844____H1R:"PB)E1#___^+%1B:"PB)A0S___^A%)H+"(F5"/___XL5$)H+ +XM"(F%!/___Z$,F@L(B94`____BQ4(F@L(B87\_O__H02:"PB)E?C^__^+%0": +XM"PB)A?3^__^)E?#^___H-7,``(,%`%X)"`&)A>3^___'!"0`F@L(Z,CT___H +XM=YP!`*'L70D(HW!V"@BAP)@*"(7`=!R+10B%P`^$V@$``,<%P)@*"`````#H +XMJGT!`.O`H?R8"@B%P`^%^P,``*&,=@H(A"0B% +XMP'02B00DZ*F``P#'!8!>"0@`````H91W"@B%P`^%8@(``,<$)'AV"@CHMFT! +XM`(G#H91W"@B%P`^%-P(``,=$)`20Z04(QP0D>'8*".CC=0``A=MT#:&`7@D( +XMA<`/A!,#``#'1"0$Q)@*",<$)&`R"0CHOMP!`(7`=#N+'>AV"@C'!<"8"@@! +XM````QP7H=@H(`````,<$)'AV"@CH9%$!`.C/C@$`QP7`F`H(`````(D=Z'8* +XM",<$)`````#H?_?__Z'L70D(QP7(K`L(`0```(7`#X5L`0``BTT(A"9"PB%_P^$*@$``(`]B)@*"`!T#X,]@%X)"`$9P"`%B)@* +XM"(L-[%T)"(7)=1N+%8!>"0B%TG01QP0D````0.@5<@``D(UT)@"A<'8*"(7` +XM=2>A\%T)"(7`#X1*`0``QT0D!`````#'!"1X=@H(Z,:6``"-M@````#'!"1X +XM=@H(Z"1T``#I]_W__XN%Y/[__\<%_)@*"`````")!"3HMW,``(N5'/___XN% +XM&/___XD5+)H+"(N5%/___Z,HF@L(BX40____B14DF@L(BY4,____HR":"PB+ +XMA0C___^)%1R:"PB+E03___^C&)H+"(N%`/___XD5%)H+"(N5_/[__Z,0F@L( +XMBX7X_O__B14,F@L(BY7T_O__HPB:"PB+A?#^__^)%02:"PBC`)H+".@(<0`` +XMZ7K]__^+-?!="0B%]@^%R/[__XL=3)H+"(7;#X6Z_O__C;0F`````(/H`0^? +XMP`^VP(E$)`3'!"1X=@H(Z/0#`.F._?__QP0D>'8*".A4C`$`H80@ +XM"0B%P`^%Z`$``*&`=@H(QT0D"`````#'1"0$>'8*"(D$).BZB`$`QT0D!$`K +XM!@B)PXD$).A8"0B%P'0,QP0D````0.A3<```Z!ZN`P"AU)<*"#'2 +XMQT0D$`$```#'1"0,`````,=$)`@`````A<`/G\*#Z@$)T(E$)`2)'"3H";T! +XM`*&TF0L(A<`/A4P!``"+10B%P'05BSW`=@H(A?\/A1L!``"-M"8`````QT0D +XM"`8```#'1"0$`'8)",<$)'0O"0CH%.,!`.GO_?__BSW`=@H(A?\/A-_\__^+ +XM-?!="0B%]@^%T?S__X`]B)@*"``/A<3\__^+'>"9"PB%VP^%MOS__^G)_/__ +XMC78`BY7D_O__QP7\F`H(`````(,M`%X)"`&)%"3H<7$``(N%'/___XN5&/__ +XM_Z,LF@L(BX44____B14HF@L(BY40____HR2:"PB+A0S___^)%2":"PB+E0C_ +XM__^C')H+"(N%!/___XD5&)H+"(N5`/___Z,4F@L(BX7\_O__B140F@L(BY7X +XM_O__HPR:"PB+A?3^__^)%0B:"PB+E?#^__^C!)H+"(D5`)H+"('$+`$``%M> +XM7UW#BS7@F0L(A?8/A=[^__^+'?!="0B%VP^%T/[__\<$)`````#HI/L"`.F_ +XM_O__QP0D>'8*".CCF0,`H80@"0B%P`^$__W__\<$)'AV"@CH*IX#`.GN_?__ +XMQP4X=PH(`````,=$)`3$F`H(QP0DJ$`)".A7V`$`A<")PP^$=0(``(L0A=(/ +XMA&L"``"-1>R)!"3HU.S__XL;B1PDZ$YO`0"%P(F%[/[__P^%T@(``+A8`@`` +XM`P4,7@D(.T7L#X\T`@``BP.%P`^$(@(``(G?Z;$```"+1;P+1<`/A)<```"+ +XM1:0YP@^,C````(L-#%X)"#G(?P0YRGY^H329"PB%P`^%N0(``(7;N$7)"`@/ +XMA;0"``")!"3HU'@!`,=$)`0P*@@(B<.)!"3HHG```(.][/[__P$/A.T"``"A +XM@)@*",=$)`RDL0@(QT0D"`<```#'1"0$"P```(D$).@@SP``B70D"(E<)`2) +XM!"3HL,@#`(D<).BX;P``BT<$@\<$A<`/A&H!``")!"3H(ND#`(U5C(E4)`2) +XMQHD$).BM[___A"0B#P`$Y +XMT`^-2P$``*$TF0L(A<`/A38!``")#"3H(^___XN5(/___XD4)(G#Z`=Z`P"% +XMVP^$)____XD<).AS\O__A<`/A!?___^)'"3H8_+__\>%Z/[__P````"%P'40 +XMZ?S^__^-="8`@X7H_O__`8D<).@]\O__AC^__^)="0(B50D!(D$).@WQP,`Z8K^__^)]HM%[*,,7@D(QP0D```` +XM`.@L[P,`Z&?8`P#HHJ8#`(GVZ'NJ`P"+%:1W"@B+#;1W"@BAH'<*"#,%L'<* +XM"#'1"<%T%NC9AP$`QP0D`0```.A-G@,`Z4[X__^#/=`D"0@"=>''1"0$```` +XM`,<$)`````#HZ]4#`.O+A=L/A<+^__^+A2#___^)!"3HTW@#`.GV_?__BP.) +XM!"3H9'@!`(7`B?8/A!K]__^#K>S^__\!BP.#PP2)!"3HEM,!`(7`#X\#_?__ +XMN`$```#I^?S__XUT)@"%VP^$L/W__Z&`F`H(QT0D#(VQ"`C'1"0(!@```,=$ +XM)`0+````B00DZ)/,``#I(OW__XU5C#';C84L____B10DQT0D"&````")1"0$ +XMZ&OP__^+5:P[%:B9"PB+C2#___\/G\/I[/W__Z&`F`H(QT0D#)*Q"`C'1"0( +XM!0```,=$)`0+````B00DZ#/,``")7"0$B00DZ,?%`P#I$OW__Z&`F`H(QT0D +XM#'&Q"`C'1"0(`P```,=$)`0+````B00DZ/W+``"+E>C^__^)5"0$B00DZ(O% +XM`P#IWOS__XVV`````%6)Y5>)SU:)UE.![%PA``#'1"0$`````(D$).A@;0$` +XM,=*#^/\/A`\#``"-7?")1?")'"3'1"0$0!X%".CO;```BT7PQT0D!/____^) +XM!"3HG',!`(D<)(E%\.B!;```B1PDZ"EL``"+1?#'1"0(`0```,=$)`0"```` +XMB00DZ#KI__^+7?"Z`0```(7;#XBH`@``A?;'A________=!>-19")1"0$ +XMB1PDZ-WP__^%P`^(A00``(V%P-[__\=$)`2`I@0(B00DZ&-L``"+#91W"@B% +XMR0^%!00``*'\70D(BQ7H=@H(QX70WO_______\>%S-[_______^)A<#>__^A +XMM'8*"(72QX7$WO_______XF%R-[__P^%.@(``*'`=@H(A?^)A=3>__^AX)D+ +XM"(F%V-[__Z%0=PH(B87#>__^A2)H+"(F%Y-[__Z%(=PH( +XMB87HWO__H;28"@B)A>S>__^A,)D+"(F%\-[__Z&\F`H(B87TWO__H>Q="0B) +XMA?C>__\/A;0!``#'A03?__\`````H>R9"PC'1"0()"```,=$)`2@=PH(B84( +XMW___C84,W___B00DZ!;N__^+10B%P'1JBU4(BP*%P'1AQT0D!,28"@C'!"0D +XM-@D(Z$;2`0"%P`^$#@,``(L`A<`/A`0#``")!"3H[',!`(F%_-[__XM%"(D$ +XM).C;%_-[_ +XM_P````"+50B)';1V"@C'!;QW"@@`````QP6X=PH(`````(F5`-___\<%L'<* +XM"`````#'!;1W"@@`````QP6@=PH(`````,<%I'<*"`````#H3S,!`*&T=@H( +XMQP60=@H(`````,<%O)@*"`````")!"3H&NW__X/_`<<%X)D+"`````#'!5!W +XM"@@`````QP5(=PH(`````,<%2)H+"`````#'!3"9"P@`````H\!V"@@9P"$% +XMC)@*"*&4=PH(QP6TF`H(`````(D][%T)",<%_%T)"`$```"%P`^%]0$``,<$ +XM)`````#HF?+__XV%P-[__XD$).A;:0``N@$```"!Q%PA``")T%M>7UW#H8R8 +XM"@B)A03?___I1O[__XUUD(ET)`3'!"0`````Z"+N__^#P`%T9XV%,/___XE$ +XM)`2A1)D+"(D$).@&[O__@\`!=$N+190[A33___\/A-P!``"A1)D+",=$)`3_ +XM____QP0D`````(F%Q-[__^@W<`$`QT0D"`$```#'1"0$`@```*-$F0L(B00D +XMZ.;E__^)="0$QP0D`0```.BF[?__@\`!=&>-A3#___^)1"0$H___HNV\!`,=$)`@!````QT0D!`(```"CS)<*"(D$).AJY?__B70D!,<$ +XM)`(```#H*NW__X/``71IC84P____B40D!*$$=@H(B00DZ`[M__^#P`%T38M% +XME#N%-/___P^$O````*$$=@H(QT0D!/_____'!"0"````B870WO__Z#]O`0#' +XM1"0(`0```,=$)`0"````HP1V"@B)!"3H[N3__XGVZ`MK`0#I0_S__XVV```` +XM`(,%Q*P+"`''1"0$L)`(",<$),2L"PCH-6@``.G;^___QX7\WO__`````.G[ +XM_/__D,<$),2L"PCH=&<``(,%Q*P+"`''1"0$L)`(",<$),2L"PCH^6<``.G? +XM_?__B1PDZ%QJ`0"Z`0```.GL_?__BT60.X4P____#X4U____Z6[___^+19`[ +XMA3#___\/A:7^___IW/[__XM%D#N%,/___P^%%?[__^E,_O__C;8`````58GE +XM5U93@^PD<9@`` +XMQT7P`````.E7____QT0D!#PT"0B)'"3HC./__X7`=>"+7@B-?@C'1?`"```` +XMA=L/A2[____'!"2!```0Z(MC``"+7@C'1?`"````Z1/____'!"1%```0Z'!C +XM``"+7@C'1?`!````Z?C^__^058GE4X/L%*&4=PH(BUT(AGW8@``C;0F`````*'`=@H( +XMA"0@`QP0D``````^4PC')Z+/W__^)'"2)QN@Y9```@\00B?!;7EW#BT@$ +XMAR+-S'`A?9T5HU?!,=%\`````#K#Y") +XMW\=#_#H```"+,X/#!(/^.G0$A?9U\L=#_`````"+!X7`=06_C#,)"(D\).A/ +XMV@,`BU7PBTWLB021@\(!A?:)5?!UO(G0P>`"BU7LQP0"`````(D4),=$)`3P +XM(P8(Z%UC``#'1"0,`@```,=$)`C$F`H(BTWLQP0DE#()"(E,)`3H^L\!`(M% +XM[(D$).C?8@``BU7LB54(@\0<6UY?7>E]8@``C;8`````C;PG`````%6)Y8/L +XM"*'4EPH(AA<____H>1U"0B%P'0HBT4(B00DZ(3D___' +XM1"0$$P```(M#'(D$).C1Y/__BS:%]HGS=9'KRN@&OP``C;8`````Z\N-M"8` +XM````C;PG`````%6)Y593@^P0H329"PB%P`^%B@```.AV_?__BS4`F`H(A?9T +XM2XGSBU,,]L8!=#*+0QP[!=R9"PAT)X'B___]_XE3#,=$)`0!````BT,7B)!"3HQEX``.BA +XM_O__@\0D6UW#QT0D!,28"@C'!"0`+@D(Z)?&`0"%P'1-,575E-1@>R8`0``BP&+203'1>P` +XM````QT7H`````(F%>/[__XF-=/[__\=%Y`````#'1"0$14!`)#K!8/X`G\^QT0D +XM!`````#'!"3,L0@(Z.5>`0"#^/]UXL=$)`0`````QP0D4\<(".C,7@$`@_C_ +XM=0<``(D$)+]P +XMN0@(Z#=F`0"Y!0```/RC#'8*"(G&\Z8/E,`/ML"CE)@*",<$)-:Q"`CH`=D# +XM`(D$).BIU`,`HZ28"@C'!"3>L0@(Z.C8`P")!"3HD-0#`*-T=PH(H=AU"0B) +XM!"3H/MD#`*/0EPH(B00DZ%'7`P"CV'4)",<$).>Q"`CHL-@#`(D$).A8U`,` +XMQP6,F`H((0```,<%1)H+"%X```#'!32:"P@^````QP6,=PH((P```,<%;'<* +XM"`````"CU)D+"*-,=PH(QP0D\;$(".A@V`,`QT0D"`(```#'!"2@,PD(B40D +XM!.B(S0$`BXUT_O__BP&)!"3H.-@#`(D$).C@TP,`QP7X70D(`````*/T70D( +XMQT0D!*0N"0B)!"3H[=G__X7`#Y3`#[;`B86$_O__Z`K@__^CA'8*".B`V___ +XMH\QV"@CH5N#__Z,LF0L(Z)S>__^+M73^__^CZ)@*"(L&@#@M#X3`$0``@[UX +XM_O__`@^$DQ$``,<%-)D+"`````#'!6"9"P@!````NX````#'!"3UL0@(Z*38 +XM__^%P`^5P`^VP*/`I0L(QT0D!$7)"`C'!"0`````Z%/?___'1"0$1BT2>-*D```0`=2R#PP&!^_\```!_(??#```` +XM0'7M@?O_````=MJ)'"2)]N@WV?__J0``!`!TU(,]@%$)"`$/E,(QP('[_P`` +XM``^?P"'0HV"9"PBA/&0)"(7`=`VA0&0)"(7`#X1>$0``Z'T5`P#'!"1T=@H( +XMZ&W7___HG-H#`.@WX?__H;1V"@B)!"3H=MO__X7`B<,/A$P1``")QK@%```` +XM_+_^L0@(B<'SI@^$^`0``(D<).BAU@,`B00DZ$G2`P#'1"0(`@```,<$)+PN +XM"0B)1"0$B6`$`QT0D"`(```#'!"2X+PD(B40D!.BFR0$`C9V<_O__QT0D +XM!``!``")'"3H/-S__X7`#X@]#@``QD6;`(D<).A\U`,`QP0DE#`)"(E$)`3H +XM7,L``.BG=@,`QP0D++((".AGU?__A<")PP^$Z0X``(D$)(G>OQZR"`CH0M0# +XM`(D$).CJSP,`B00DZ!)8`0#'1"0(`@```,<$)-`O"0B)1"0$Z!K)`0"Y"``` +XM`/SSI@^%P0P``,>%?/[__P$```"+M7S^__^_/K(("+D&````_(DUB'<*"(G> +XM\Z8/A3L"```QP*/DF0L(BSWDF0L(A?\/AL@@(Z&S4 +XM__^%P(G#="Z)!"3HGMO__X/X!(F%O[NR"`BY!P```/.F#X2,#0``B[5X_O__@^X!A?8/CD,.``"+E8C^ +XM__^+`H`X+0^%,@X``(U0`0^V0`&$P`^$(PX``,>%@/[__P`````Q_XG3ZS*A +XM#'8*",<%D)@*"`$```")7"0$QP0D?````(E$)`CHV%,```^V0P&#PP&$P`^$ +XM`0$``#QX=\H/ML#_)(6,MP@(N'"Y"`CI??C__XU#!8D$).D`^___B=Z_1+(( +XM"+D#````\Z8/A+']__^+A7S^__^#\`'II?W__XUT)@"#_@$/A%L'``"#A8C^ +XM__\$BXV(_O__BP&)!"3H8-$#`(D$).@(S0,`A<"CD'8*"'0HB00DZ/?,`P") +XM!"3H'U4!`,=$)`@"````QP0D0#8)"(E$)`3H)\8!`*&0=@H(B00DZ*K'`P"+ +XM#9!V"@@YP7,G@WC\7(U0_'4>,<#K"XUV`(/J!(,Z7'4'@\`!.=%R\:@!#X6. +XM!@``@^X!QP6$(`D(`````+\!````#[9#`8/#`83`#X7__O__@^X!@X6(_O__ +XM!(7V?B:+E8C^__^+`H`X+749C5`!#[9``83`=`Z+C8#^__^%R0^$E?[__X7_ +XM#Y3#BX6$_O__A<`/A<4'``"$VP^$J0```(7V#XZA````QT0D!`````"+C8C^ +XM__^+`8D$).B950$`A<")PP^(&0X``*'T70D(B00DZ+)?`P"+E8C^___'!?A= +XM"0@!````BP*)!"3H*-`#`(D$).C0RP,`H_1="0C'1"0$$````(D<).B[6P$` +XMA<"CM'8*"`^(7PT``,=$)`@!````QT0D!`(```"AM'8*"(D$).A=T?__@X6( +XM_O__!,<%A"`)"`````#HVUL!`*&T=@H(B00DZ$K7__^%P*/`=@H(#X3"!@`` +XMH!V"@B)1=RA +XMY'8*"(E%X.@E3@``QP0D`)H+".C%S___@P4`7@D(`<<%P)@*"`````"%P`^5 +XMP`^VP`L%"%X)"`^$`00``(N%C/[__XLUP'8*"(,M`%X)"`&CE'<*"(M%S(7V +XMH]!V"@B+1="CU'8*"(M%U*/8=@H(BT78H]QV"@B+1=RCX'8*"(M%X*/D=@H( +XM=`Z+'9!V"@B%VP^$^`D``(M%Z(7`#X7%!```BT7LA<`/A:D$``"AE'<*"(D$ +XM).BGV?__BPW`=@H(A%A/[__P$```#IUOG__\<%*'<*"`$` +XM``#IQ_G__\<%!%X)"`$```#IN/G__[\!````QP4DF0L(`0```.FD^?__QP4( +XM7@D(`0```.F5^?__QP60F`H(`0```.F&^?__QT7D`0```.EZ^?__QX6`_O__ +XM`0```.EK^?__QP7H70D(`0```.E<^?__OP$```#'!80@"0@`````QP64=PH( +XM`0```.D_^O__QP0D@#()".BJP`$`Z2WY___'!"1@,@D(Z)G``0#I'/G__\=% +XM[`$```#I$/G__\=%Z`$```"0Z0/Y__^_`0```,<%O)@*"`(```#'!80@"0@` +XM````Z>7X__^+E7#^__^_XK$("+D%````_(U$$_R)QO.F#X5R]___B1PDZ);* +XM`P")!"3H/L8#`(D$).AF3@$`QT0D"`(```#'!"0H,@D(B40D!.ANOP$`BYUP +XM_O__A=L/A5'W___I+_?__\<%D)@*"`$```#'!"0I````Z$5,``#I5_G__Z', +XMEPH(B00DZ+_1__^%P`^$Z_K__\<%E'<*"`$```#IW/K__\<$)`````#H0.S_ +XM_^F4^/__QP4(7@D(`0```.E&]/__H]'__X7`#X1;^O__BX6` +XM_O__A<`/A4WZ__^AA'8*"#L%+)D+"`^$/@0``.B_SO__QP`-````QP7D=0D( +XM`0```.BJSO__BP")!"3H4,S__XE$)`BA#'8*",<$)#8```")1"0$Z(M+``#I +XM^OG__XN%=/[__X/`!(F%B/[__^DV]___A=L/A`0&``")'"3H8LD#`(D$).@* +XMQ0,`B00DZ#)-`0#'1"0(`@```,<$)*0O"0B)1"0$Z#J^`0#'1"0$Q)@*",<$ +XM)*0O"0CH=K4!`,<$)*`_"0B)1"0$Z`;```#I)_3__\<$)+6R"`CH1:8#`.DH +XM_?__QP0D@#$)".B4O@$`Z2/U___'1"0$Q)@*",<$)(`Q"0CHR[0!`(7`=`S' +XM!"2`,0D(Z*NV`0#'!>29"P@`````Z0OY___'1"0$`````,<$)`,```#H],[_ +XM_^DB^/__@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".AX30``,2%P`^$^?K__\<$ +XM)`````#HD0L``)#IY_K__\<$)(`R"0CH'[T!`.E&^___QP0D8#()".@.O0$` +XMZ2K[__^-1`/[OV2R"`C\N08```")QO.F#X2R_/__Z0CT__^)WK\QL@@(N04` +XM``#SI@^$*_/__XG>OS:R"`BY"````/.F#Y3`#[;`B85\_O__Z1;S___'1"0( +XM`@```,=$)`3H-@D(QP0DJ#()".@\O`$`Z1[X___'1"0$+P```(G>B1PDZ,'' +XM__^%P'0#C7`$QT0D"`,```#'1"0$O"X)"(DT).@"R___A/[__P&%P`^$_NW__\<$)`Q> +XM"0CH,<;__\<$).`U"0CH.;L!`.GA[?__Z,^C`@#IF.[__Z',=@H(.P7HF`H( +XM#X6Q^___Z>CU___'!"1%R0@(Z<+N___'!8AW"@@`````QP0D1[((".A>QO__ +XMN@$```"%P'05_(G&OUH;"0BY`@```/.F#Y7`#[;0B17DF0L(Z4_Q__^AS'8* +XM"(D$).B<2P$`A<`/A!@#``"+`(D$).@*Q0,`QT0D"`(```#'!"2X+PD(B40D +XM!.@RN@$`QT0D!,28"@C'!"2X+PD(Z"ZQ`0#'!"3@/PD(B40D!.B^NP``Z2/P +XM___'!"10L@@(Z+W$`P")!"3HA>7__^E$\?__QT0D!,28"@C'!"0`,`D(Z.RP +XM`0#'!"1^L@@(B40D!.C,H0,`QT0D#.BR"`C'1"0("````,=$)`0+````H8"8 +XM"@B)!"3H!Z@``(D$).B?H0,`QP0D`````.B#YO__Z1+R___'1"0$Q)@*",<$ +XM)``P"0CHBK`!`,<$)!$7"0B)1"0$Z&JA`P#'!"0`````Z$[F__^+A73^__^+ +XM6`3IO_'__\=$)`0!````QP0D`P```.A(RO__Z9OU___'!91W"@@!````Z:;V +XM__^[`0```,>%@/[__P````#I1?/__\=$)`3$F`H(QP0DD"\)".@0L`$`ND!! +XM"0CH=N/__XL]-)D+"(7_#X4+_/__Z?O[___'1"0$Q)@*",<$))`O"0CHWZ\! +XM`+H@00D(Z$7C___IJOO__\<$)``````QR3'2N*:R"`CH*]O__^DB^___H81V +XM"@B)!"3H.4D!`(7`#X3@`@``BP")!"3H1\,#`,=$)`@"````QP0DI"\)"(E$ +XM)`3H;[@!`,=$)`3$F`H(QP0DI"\)".AKKP$`QP0DP#\)"(E$)`3H^[D``.G, +XM^?__H;R8"@B%P`^%,/O__Z%`F0L(A<`/A2/[___'1"0$`````,<$)`````#H +XM>&\``.D*^___BQ6\F`H(A=(/A73Z__^A0)D+"(7`#X5G^O__QT0D!`````#' +XM!"0`````Z$1O``#I3OK__X/[`70G@_L"C;0F``````^$50(``(7;#X4=`@`` +XMQP6T=@H($````.EU\O__QP6T=@H($0```.EF\O__H>29"PB)!"3HU\P"`.D\ +XM]?__Z'W0`@#'!"0!````C;8`````Z"O1`@#I[/7__\<%Y'4)"`$```#H(\?_ +XM_XL`B00DZ,G$__^)1"0(B[6(_O__BP;'!"0V````B40D!.@!1```Z:WQ___' +XM!"0>L@@(Z>'\__^)%"3H],/__^E"^___QT0D!`$```"[$@```,<$)!(```#H +XM%LC__\=$)`0!````QP0D%0```.@"R/__QT0D!`$```#'!"06````Z.['___' +XM!"02````Z"+)__^%P`^$D0$``(UUG.MD.P753BU4(A=)X-(L=(%X)"(G(ZPF0 +XMC70F`#G(=!R#Z@&#^O]T)XM`!#T<7@D(=>J)V#G(=>B-="8`6S'`7<.+`3T< +XM7@D(=06A'%X)"(M`#%M=PXVT)@````!5B>5=QP447@D(`````,.058GE4X/L +XM!(M="(M#"(7`=!/'0P0`````QP,`````@\0$6UW#BT,,B00DZ)%-`P")70B# +XMQ`1;7>F$30,`C70F`%6)Y5=64X/L+(M5"(72#Y3`=0^+70R%VW4(@\0L6UY? +XM7<.$P,=%Z`````#'1>P`````QT7P``````^%80$``,=$)`0`````B10DZ('O +XM``")1>#'1"0$,"H("(M%X(D$).B;0@``BT7@B00DZ'"[`P#'1"0$@`$``(D$ +XM).A@1`$`B470@\`!#X3_````QT0D!,28"@C'!"2@-0D(Z,"I`0`]^&\)"'0* +XMBPB%R0^%&@$``+[_____H>AV"@B-?>C'!>AV"@@`````B478H!^QQ>"0AT\HM5W(72=+B+0PR#[@&)/"2)1"0$Z"9&`0#' +XM!"1\N0@(B40D!.CFF0,`@_[_=;^0BT70B00DZ/5#`0"+1=2CS)<*"(M%V*/H +XM=@H(BT7@B00DZ,I```"#Q"Q;7E]=PXGVQT0D!,28"@C'!"1@-0D(Z*RH`0`] +XM^&\)"'0GB00DZ/VW`P")1>#IA_[__XD$).@-N@,`B00DZ+&\__^)QNG4_O__ +XMQT0D!,28"@C'!"20+PD(Z&JH`0#'1"0$)#4)"(D$).@JMP,`B47@Z43^__^) +XM]E6)Y5.#[!2+70C'!11>"0@!````QT0D!&#"0AT%C#2BT`$@\(!/1Q>"0AU\XT4E00```")%"3H +XM7$L#`(L=(%X)"('['%X)"(G'B<9T&XM##(D$).BOM@,`B0:+6P2#Q@2!^QQ> +XM"0AUY<<&`````,=$)`3P(P8(B3PDZ,D_``#'1"0,`@```,=$)`C$F`H(B7PD +XM!,<$)``V"0CH::P!`(D\).A1/P``B3PDZ/D^``"#Q!Q;7E]=PY!5B>564X/L +XM$,=$)`3$F`H(QP0D`#8)".ATI@$`A<")PP^$S0```(L`A<`/A,,```"+#2!> +XM"0B!^1Q>"0AT*XL!BU$$B5`$BU$$B0([#629"PATW8D,).CU^___BPT@7@D( +XM@?D<7@D(==6A9)D+"*,<7@D(HR!>"0C'`!Q>"0C'0`0<7@D(BS.%]G57ZUN- +XM=@"+`(7`=%+'1"0$`0```,<$)!````#HQDD#`(G#BP:)!"3HFK4#`(/&!,=# +XM"`````")0PRA9)D+"(E#!*%DF0L(BP")`Z%DF0L(B1B+`XE8!'0&BP:%P'6H +XM@\006UY=Z3W^__^#Q!!;7EW#C;8`````58GE5[\`!```5E.#[`S'!"0`!``` +XMZ,9)`P")P^L>B?;H=[[__XLP@_XB=4D!_XD<)(E\)`3H]DD#`(G#B7PD!(D< +XM).@TO/__AY`P")!"3H[[0#`(D<)(G&Z*5(`P"#Q`R) +XM\%M>7UW#B1PDZ)-(`P#H&K[__XDP,?:#Q`R)\%M>7UW#B1PD,?;H=D@#`.O/ +XMC70F`%6)Y5=64X'LC````(M%"(M=#(D$).ARN___BU4(@SHOB<+1(H$@\$!A<")1(L$=?&+%HGW +XMA=)U5(GWC4;\.T4(=`_'1OP`````B?N+`X7`=;G'1"0$Q)@*",<$))`O"0CH +XM%:0!`(D$)(G#Z$>Z__^%VXG&=`F#.R\/A*X"``"+10B!Q(P```!;7E]=PX/' +XM!(L'A`0K?0B)#"3H#;G__XG#BT6`B00DZ`"Y__^-5`,!B?C!^`*-!`+!X`*)!"3H +XMG48#`(M5"(G&B<&+`H/"!(D!@\$$A^+58")V8L"@\($B4'\@\$$A^)V8GZBP*# +XMP@2)0?R#P02%P'7QBTV,C7PQ_(M5"(G[B10DZ'9$`P")=0CI'_W__XE$)`B+ +XM30B)'"2)3"0$Z">Y__^%P'47BU4(BP2R@_@O#X0L_?__A<`/A"3]__\['1A> +XM"0AT,HD<).B0L@,`C564B50D!(D$).@=N?__@\`!=!:+192)'1A>"0BCG"`) +XM"(M%F*.@(`D(BTT(C7V4B0PDZ#BP`P")QHL&A)QNF0_O__QT;\+P```(-M@`2+58"#.B]U +XM](M-A(7)=%\QTHM$EP2+38")1)$$@\(!A575HG&4XG#@^P,@S@O='.A +XM9)D+"(M`#(D$).A:M?__B30DB<,QP(/[`0^4P(/H`2'#Z$.U__^-!`.-!(4( +XM````B00DZ.5"`P")QZ%DF0L(B?F+4`R+`H/"!(D!@\$$AB)1>R+`(U(!(E-\(M0!(72#X35```` +XM@SHM#X78````,?_K'('/@````(-%\`2+1?"+$(72#X23````@SHM=5Z+0@2) +XMTX7`=1?KV2GQN`$```#3X`G'BT,(@\,$AR#X`Z%P(D1=`.#SP&#Q!R)^%M>7UW#BT7P,?^+3>R)`>OJ +XMBTWP,?^+5>R)"NO>ZPV0D)"0D)"0D)"0D)"058GE@^P8B5WXB77\@S@K=`XQ +XMVXG8BW7\BUWXB>Q=PXM0!(U(!/?"````0'4G@_I_=ACK((M0"/?"````0(UV +XM`'42@_I_=PV#P`3V!)6]40D(!'7@A=)UN8D,).@`FP$`A<")QGZKBQUDF0L( +XMZPT['629"PAT&(/N`728BUL$@?L<7@D(=>B+'2!>"0CKX,<$)!H``!#H9C(` +XM`.O:C70F`%6)Y5.)PX/L%,=$)`3$F`H(QP0D9#,)".B3G`$`QT0D"`8```#' +XM!"1T,PD(B40D!.AKI0$`B5PD!,=$)`@&````QP0D9#,)".A3I0$`B5PD!,<$ +XM)/@Z"0CH\Z8``(/$%%M=PXVV`````(V\)P````!5B>53@^P4BQUDF0L(C78` +XM@?L<7@D(=!;'1"0$^&\)"(M##(D$).C%]O__B4,,BUL$.QUDF0L(==>+0PR# +XMQ!1;7>E*____C78`C;PG`````%6)Y8/L&(U%"(D$).CO5P,`A<")PG09BT4( +XMB50D!,<$)(ZY"`B)1"0(Z+*,`P#)PXM%",<$))*Y"`B)1"0$Z)V,`P#)PXUT +XM)@"-O"<`````58GE5U93@^P\BS5DF0L(B478@^`$B474BT78QT7<`````,=% +XMX`````"#X`*)1=#ICP```(U%\(D$).AQ5P,`A<")QP^$G````(D$).B+L?__ +XMB<.+1?")!"3H?K'__XU<`P(!7>#V1=@(=!:+%>"7"@B-0O\Y1>!\"#G3#XRY +XM````A?]T$(E\)`3'!"29N0@(Z/N+`P"#?=0!QP0DG;D("!G`@^`6@\`*B40D +XM"(M%\(E$)`3HV(L#`(MV!#LU9)D+"'1=@?X<7@D(=.V+1=2%P'4FBT8,,?^) +XM1?"+1="%P`^$3____XM%\(D$).CLL/__C5@!Z6K___^+1=R+7=S'!"25N0@( +XMB40D!.B"BP,`@\,!B5W#I,____XGV58GE5XG75HG&4X/L#,=$ +XM)`3$F`H(QP0DX#D)".C/F0$`A"0AUVXDU9)D+"(M&#.@Z_?__Z"7R +XM__^+'2Q>"0C'1"0$Q)@*",<$)&`Y"0CH:YD!`(/X`1G`("0B%P'4$A=MU#(/$#%M>7UWI/FP#`(GXZ/?]__^#Q`Q;7E]=Z2ML +XM`P"+`XM3!(E0!(M3!(D"B1PDZ-;N___I>?___Y!5N:.Y"`B)Y;JMN0@(@^PH +XMC44(B5WTB77XB7W\Z-_Z___'!2Q>"0@!````B<.)QH'C@`````^%A0```(M% +XM"(L0A=(/A)@```"%VW4DBT4(BT`$AP0<7@D(=&8Q_SL=9)D+"`^$?0`` +XM`(M#!(L3B1"+$XE"!(D<).@D[O__.QUDF0L(=%*)\.@5_?__ZZ6-=@#'1"0$ +XMQ)@*",<$)'0S"0CHG)@!`(G"A=(/A6K___^)]HL=9)D+"(%[!!Q>"0AUFY"! +XM.QQ>"0AUDL<$)$(``!#H'"X``.N$B?*)^.@1_O__D.E-____BWL$@?\<7@D( +XM=%J+1PR)!"3HQ:D#`(E%\(D$).C6K/__A<`/B5K____HV;#__XL`B00DZ'^N +XM___'!"0V````B40D"(M%\(E$)`3HO"T``.DO____QP0D0P``$.BK+0``Z0?_ +XM__^+/2!>"0CKGHVT)@````"-O"<`````5;E%R0@(B>6Z][D("%93@^P0C44( +XMZ%;Y__^H0(G&=$*A9)D+"(L`.P5DF0L(=!R0/1Q>"0B+&'0(B00DZ/_L__^) +XMV#L%9)D+"'7EHR!>"0BC'%X)",=`!!Q>"0C'`!Q>"0CWQB`````/A8T```#W +XMQA````!U:XM5"(L*A575E.#['R+30R%R0^$=`$` +XM`(M%"#';QT7H`````,=%[`````#'1?``````ZP.#P`2+$(72="Z+2`2%R70G +XM@_HN=>N#^2YUYHM0"(72D`^%2P$``#M%"'0'@WC\+Y!USH/#`>O)A=L/A!D! +XM``"A9)D+"(M`#(D$).B-K/__C02%#````(D$).@R.@,`B46`H629"PB+0`R) +XM1"0$BU6`B10DZ&2K__^+=0B#/B\/A#P"``"+70C'1>P`````BQ,Q_X72=$&# +XM^BZ-H0,`A?]_#>LB@^\!QP`````` +XM=!?'1"0$+P```(M%@(D$).@FJO__AR%P`^%!P$``(MU@(L^A?\/A;4```"+,X7V#X5%____BT7HB00DZ',X +XM`P"+18"#Q'Q;7E]=PXM%"(D$).B=I`,`B46`BT6`@\1\6UY?7<.#^B\/A8;^ +XM___II_[__Y`[70AT$8-[_"^-M"8`````#X4?____A<`/A#'___^-6#[#C'1"0$`````(E= +XM](EU^(E]_(D$).@AV0``QT0D!#`J"`B)QHD$).@_+```,<"#/=B7"@@"B30D +XM#Y3`B40D!.BW_/__B<.)!"3H_:0#`(D$).@1J/__A!F)-"3H?"L``(DT).@D*P``B?#HW?/__^NYZ,*K__^#.`*-=@!T.^BU +XMJ___@S@4=#&-="8`Z*>K__^+`(D$).A-J?__B30DB"2)-"3H>"H``(D<).C0H0,`QP4L7@D(`0```.@A\___Z?K^__^+'11> +XM"0B%VP^$/@$``(DT).A&*@``,<#IW?[__XET)`3'!"3,.`D(Z.\I`0"%P`^% +XM=____\=$)`3$F`H(QP0DW#@)".BSD0$`A<`/A%O___^+$(72#X11____QT7H +XM`````,=%[`````#'1?``````BQB+`X7`=2KI_0```(DT).A7HP,`B00DZ&NF +XM__^%P`^)]0```(/#!(L[A?\/A-@```#'1>P`````BP.)1"0$C47HB00DZ)*? +XM`P"-1>B)!"3'1"0$+P```.@/G0,`C47HB00DB70D!.APGP,`C47HB00DZ%6= +XM`P"AV)<*"(/H`H/X`0^6P`^VP(E$)`2+1>B)!"3HA?K__XG'B00DZ,NB`P") +XM!"3HWZ7__X7`#XA<____BT7HQP4L7@D(`0```(D$).A&-`,`B30DZ!XI``") +XM^.C7\?__Z;#]__^)]HM%X(D$).AAI___B30DBZ(#`(E<)`C'!"0V```` +XMB40D!.B7)@``Z93^__^+1>B)!"3H]S,#`.DB_O__B3PDQP4L7@D(`0```.C@ +XM,P,`BT7HB00DZ-4S`P#I?/W__U6YM[D("(GENJVY"`B#[!B-10B)=?B)??R) +XM7?3H'_+__\<%+%X)"`$```")QHG'@>:`````#X6Y````BT4(BQB%VP^$QP`` +XM`(7V=22+10B+2`2%R70:QP0D#P``$.C^)0``BUWTBW7XBWW\B>Q=PY")V.CI +XM\O__A<")Q@^$_P```(M`#(D$).BDH0,`B<.)!"3HMJ3__X7`#X@U`0``QT0D +XM!,28"@C'!"2@.0D(Z)Z/`0"%P'0P.S5DF0L(="B+%HM&!(E"!(M&!(D0H629 +XM"PB+$(D6H629"PB)1@2)<@2A9)D+"(DPB?J)\.AQ]?__Z6[____'1"0$Q)@* +XM",<$)'0S"0CHJ(\!`(G#Z3'____'1"0$Q)@*",<$)"`Y"0CH+8\!`(7`#X30 +XM````QT0D!,28"@C'!"20+PD(Z'&/`0`]^&\)"(G#=`:+,(7V=0S'!"0B```0 +XMZ`8E``")'"3HSJ`#`(D$).CBH___A:`````#X6:````BT4(BQB%VP^$#P$``(7V +XM=22+10B+0`2%P'0:QP0D#P``$.A>(P``BUWTBW7XBWW\B>Q=PY")V.A)\/__ +XMA<")QG1SQP4L7@D(`0```(M`#(D$).C^G@,`B<.)!"3H$*+__X7`#X@'`0`` +XMH629"PB+4`2+`(D"H629"PB+$(M`!(E"!*%DF0L(B00DZ*;B__^)^HGPZ.WR +XM___KC<=$)`3$F`H(QP0D=#,)".@GC0$`B6#[!B)7?B)PZ&`F`H(B77\BS4,=@H(QT0D +XM#-BY"`C'1"0(`0```,=$)`0,````B00DZ#>#``")7"0(B70D!(D$).C'?`,` +XMBUWXBW7\B>Q=PXVV`````(V\)P````!5B>575E.![,P```"+=0CHO.7__X7` +XMB<,/A!(!``")!"3H&IT#`(U5E(E4)`2)!"3HIZ/__X7`#Y3`B<=U4H7V=`J+ +XM!H7`#X54`0``B?B$P'0^QP0DT;D(".@>H/__A<")QG0LC84T____B40D!(DT +XM).AFH___@\`!=!6+190[A33___\/A&8!``"-M@````#'1"0$,"H("(D<).C` +XM(P``QT0D!/AO"0B)'"3HP.7__XD<)(G&Z%8C``")'"3H_B(``,=$)`0!```` +XMQP0D$````.AJ+@,`,=*)<`R)P\=`"`````"C(%X)"*,<7@D(QT`$'%X)",<` +XM'%X)",<%+%X)"`````#H9O#__\=$)`@&````BT,,QP0D`#8)"(E$)`3HBY,! +XM`('$S````%M>7UW#Z#>C__^+`(D$).C=H/__QP0DAKD("(E$)`BA#'8*"(E$ +XM)`3H6'L#`(7V=`J+!H7`#X7`````N%/'"`CH,/[__\<$)%/'"`CHX)[__X/` +XM`0^$V````,<$)%/'"`CHWYT#`(D$).B'F0,`B<;I(O___XDT).B8FP,`C94T +XM____B50D!(D$).@BHO__@\`!#X2)_O__BT64.X4T____#X5Z_O__BT68.X4X +XM____#X5K_O__B30DZ#>9`P")QNG2_O__BT68.X4X____#X61_O__B30DZ&F= +XM`P")!"3H$9D#`,=$)`0P*@@(B<.)!"3H/R(``.EJ_O__B30DZ!*;`P")P^AK +XM_?__B1PDZ!^>__^#P`$/A"#___^)-"3HTI@#`(7`B<8/A6K^___I"?___\<$ +XM)`$```#H-[___^D7____D)!5B>5=HTA>"0C#C;8`````H4A>"0A5B>6%P'0, +XM7<<%2%X)"`````##H4Q>"0B%P'07BQ"#P`2C3%X)"(72=`E=B=`E____?\.A +XM4%X)"(L0A=)T%5V#P`2C4%X)"+@@````B15,7@D(PUVX_____\<%3%X)"``` +XM``##C;0F`````%6)Y8M%"(7`>":I````0'4?@_A_?QH/ML`/MX0`X"`)"*A# +XM=`O'!71>"0@!````D%W#C;0F`````(V\)P````!5B>5=QP7$EPH(`````,.0 +XM58GE@^P(B00DZ/*9`P#'!"0K```0HR!W"@CH$1X``,G#ZPV0D)"0D)"0D)"0 +XMD)"058GE5U93@^P\BQ5D7@D(A=)T"HL];%X)"(7_=0VC5%X)"(/$/%M>7UW# +XMB00DZ'Z7`P"+-61>"0B%]HE%[`^$[P(``,=%\`````"-M@````"+??"+%6!> +XM"0C!YP*+!#K'1=``````@_AS#X58`@``BUWP@\,!BQ2:A=*)5=0/A/\"``"! +XMX@```$!U0P^V5=2!^O\````/A\T"``"AX%T)"(M$D#3VQ`$/A=4"``"#?=1? +XM#X3+`@``@WW4?W<1BT74]@2%O5$)"`0/A;0"``"+5=3'!"3_N0@(B50D!.C_ +XM'0$`A<`/A9D"``"+#6!>"0B-``````C02QB4W$B<&)1=@Y$'0O +XMBT7$C7,"C0RPBQ&%TG0@C40X#.L/BU`$@\$$@\8!B;'`0````"+%6!>"0B-3@&)3?#!X0*+1=2)3>C'1>0``````=&)3=R)RSD! +XM=$2-3@*)3?#!X0*-'`J)3>B+"X7)="^-!+4(`````<+K%H-%\`&#P`2#PP2) +XM1>B+2@2)VH7)=`Z#1>0!B=,Y3=2)1>AUW,<#`````(M%V(D$).CT'0$`BU7L +XMB10DZ.D=`0"+3>"+1>S'1=``````P>$"B4W,ZQ2-="8`BT7(QT70`0```(EU +XM[(/`!(M5V(D$)(E4)`3HL9`#`(7`B<R)^XD,).AVG/__BU7D +XM*U7@C50"`<'B`HD4).@5*@,`*UWLP?L"B5PD"(G&BT7LB30DB40D!.A&HO__ +XMBTWB57(B10DB4PD!.@QF___BU7,C007B40D!`-=Y(T"0B%VP^%5/___XEU[,=%T`$```"+5=2+3=RA8%X) +XM"`%%Z(E1_(M%Z(D0BU70A=)T;.M6H6!>"0B+!`?'1=`!````B5WLB40D!(M5 +XM[(D4).AJ]P``A<")PW30B40D!(M-[(D,).CQFO__A<`/A((```"+5>R)%"3H +XMRA;%X)"#W___]_=`B#Z`&C;%X)"(-%\`&+3?`Y +XM#61>"0@/AQ[]__^+1>R)!"3H@_@``*&`7@D(QP547@D(^&\)"(7`#X3._/__ +XMQP0D````0.B@&@``@\0\6UY?7<.)%"3HG)K__^DO_?__BT7LB00DZ/`G`P#K +XMAL<$)%@```#H`AH``(GVZZ"-M"8`````C;PG`````%6)Y5=64X/L7(E%L(UT +XM)@"+#41>"0B%R0^%*@(``(L5F'<*"#D5?)P+"`^'2PH``*%47@D(A<`/A"," +XM``"+"(/`!*-47@D(@>'___]_A"0B%R0^/?`L``,<%5%X) +XM"`````#H_OK__X/X)(G!=`J#Q%R)R%M>7UW#BT6PA +XM"0@`````QP5D7@D(`````.@I____B47(@\`!#X2M`0``BUW(@_M[#X1,!0`` +XMB=@E____/X/X(P^$&04``(/[/P^$H04``(/[)0^$NP4``,=%O`````#'1;@` +XM````QT6T`````(/[(0^$H00```^/D@```(/[_P^$IP,``(/["@^$G@,``(G8 +XM)0```$")]G4)@_M_#X9,"```@_O_B?9T+X7`=2L/MM.!^O\```"0#X?F"@`` +XMH>!="0B+1)`T]L0%#X48!P``@_M?#X0/!P``BT6\OB0V"0B%P'40BT6XA<`/ +XMA.<&``"^]"X)"(U%V(ET)`2)!"3HY)`#`(U5V(D4).E/`P``@_LJ#X2R`@`` +XM@?L\``!`#X3%````@_LDD`^%8?___XM5O`E5N(M-N`M-M`^%-@D``*&\F0L( +XMZ%[Z__^-1=B)!"3HHQH``(-]R'L/A?G]___H5/G__X/X?9`/A.K]___'1"0$ +XM?0```,<$)#(```#H)A@``(L-1%X)"(7)#X36_?__QP5$7@D(`````(/$7(G( +XM6UY?7<.-="8`BQ5<7@D(A=(/CO_]__^+%5A>"0B+`H/"!(D56%X)".C<^?__ +XM@RU<7@D(`>F`_?__QP0D`````.C$%P``Z6_]__^+1;B%P`^%:0@``(M%O(7` +XM#X4S"```BT6TA<`/A0\(```Q]HU]YL<%.%X)"`````#K'HM%[#'V@_@*#X29 +XM````B40D!,<$)#1>"0CH/XT#`(U5\(D4).@DBP,`C00WB40D!*%$F0L(QT0D +XM"`$```")!"3H.!H!`(U-\(D,)(G#Z(L9``"#ZP%U4(/&`8U%[(ET)`B)?"0$ +XMB00DZ#"4`P"#^/\/A,<```"%P`^.\````#GZ____*<:-!`>)="0(B40D +XM!(D\).C>F___BT7L@_@*#X5G____A?:-7>QU(.M@BT7L,?:#^`IT5HE$)`3' +XM!"0T7@D(Z).,`P"%]G1"B70D"(E\)`2)'"3HOY,#`(/X_P^$E@```(7`#XZV +XM````.?!TO2G&C00'B70D"(E$)`2)/"3H<9O__XM%[(/X"G6JQP0D-%X)".BA +XMC`,`Z'P.``"A-%X)".AB^/__C578B10DZ*<8``#I__W__XGVQT0D"`````#' +XM1"0$`````,<$)`````#H\);__X/^!0^&O/[__P^V1>8-```@`(E%[+@!```` +XMZ0;___^0C70F`,=$)`@`````QT0D!`````#'!"0`````Z+"6__\/MD7F#0`` +XM(`")1>RX`0```.E`____C4W8O_____^)#"3'1"0$)#8)".@&C@,`C478B00D +XMZ.N+`P#'1"0$Q)@*",<$)"0V"0CHEW\!`(G&BT6XA"0B-5=B)%"3HT!<``.DH_?__BT6\OB0V"0B%P'40BWVXA?\/A((# +XM``"^]"X)"(U5V(ET)`2)%"3HD(T#`(U-V(D,).AUBP,`O_____^)-"3'1"0$ +XMQ)@*".@@?P$`B<:)V.@G]O__A?8/A*X!``"+!H7`#X2D`0``C478B00DZ%H7 +XM```QP.BC^O__B<.+!HD$).@'%@$`BU6\"?J)14__\!1,`P"C,%X)".@=]?__ +XMZ<7Z__^AY*P+"(L-X*P+"(E%W*'HK`L(B4W8B47@C478QT0D!+"1"`B)!"3H +XMW!4``.L4@_C_="6-5=B)7"0$B10DZ*:(`P"X`0```.AL^/__@_A=B<-T%X/X +XM"G76QP0D!0```.BT$@``C70F`.O)C4W8B0PDZ-.(`P"A5%X)"(M=V(7`#X1B +XM`@``QP0D!@```.B'$@``BQ.%T@^$9`(``/?"````0`^$)0$``,=%T`$```"# +XM^BH/A&<"``"#^BT/A$T#``#'1"0$+0```,<$)#(```#H1!(``(M%T(7`=1*+ +XM1<"%P`^%.P0``,=%P/____^+.X7_#X7,`P``C578B10DZ&84``"+?<#I2OW_ +XM_XM%T(U?`2M=T,'@`HE%Q.@*"@``BP:)'5Q>"0B#Z`0#1<2C6%X)".F/^?__ +XMQP0D`````.C6$0``Z;CX___'!"0?````Z,41``"0C70F`(U-V(E<)`2)#"3H +XM@8<#`#'`Z$KW__^#^/^)PW0IJ0```$!U(@^VT('Z_P````^'FP$``*'@70D( +XMBT20-/;$!76_@_M?=+J-1=@Q_XD$).B=AP,`B=CH9O+__\=$)`3$F`H(BT78 +XMB00DZ$-[`0")QNFG^___@_I_#X?2_O__]@25O5$)"`3'1=``````=13IO/[_ +XM_X/Z?W"0CIT_?__XL]7%X)"(7_#X60_?__BQ.% +XMT@^%G/W__\<$)`````#H#1```(L3]\(```!`#X6._?__Z:[^__^#PP3IKOW_ +XM_XD4).CVC___Z6'^__^A>)P+"(L,D(U"`:.8=PH(@>'___]_A7UW#QP0D`````.A)#@``Z2/\__^-="8`Z$OO__^#^'V)PW04QT0D +XM!'T```#'!"0R````Z"`.``")V.@9[___Z67Y__^+1=B)!"3H214!`.GO^/__ +XMB10DZ`B.___I%O7__XU%V(D$).@\$```BT8$Z+3O___IC_/__XM%V(D$).BD +XMB0,`B00DZ-B,__^Z$"\)"(7`#X4I^/__Z2GX__^+%?1="0B%T@^$B@```(M% +XMM(7`=%ZA]%T)"(D$).@DCO__B00DZ(!X`0")!"3H2.L``.GX]___QT0D!,28 +XM"@C'!"0D-@D(Z%]W`0"%P(G`]___C4W8OJ0@"0B)#"0QV^BC#P``QT7$ +XM!````.E(^___Z%(%``"A]%T)".@X[___Z:CW___'!"0K````Z"<-``#IOOS_ +XM_\<$)`0```#H%@T``(VV`````.E?____C70F`(V\)P````!5B>575E.![%R` +XM``"-?>3'1=@`````QT7<`````,=%X`````#'1CO__@\`! +XM=:;'1"0$`````(D\).B)C?__H0AV"@B)!"3HP!D#`(MUY(M=Z.AQDO__,?,Q +XMPX'C____`(D<).@C=P$`QP0D0#()"(G#B40D!.A!A0,`B1PDHPAV"@CHA!D# +XM`.E(____B1PDZ+.-___H_H[__XDPZ/>.__^+`(D$).B=C/__B5PD!,<$)#8` +XM``")1"0(Z-T+``")'"2-GXW__XM%"(U5[(F5M'___XD4),=%\``` +XM``")1>S'!71>"0@`````Z$>F``"-5>R)%"3'1"0$0/X$".CTI0``H71>"0C' +XM1<@`````QP7$EPH(`0```,=$)`2`_@0(B86\?___QP0DQ)<*".A4#@``C578 +XMB10DQT0D!+"1"`CH00X``(U%S,=$)`2PD0@(B00DZ"X.``"-5"0B)%5!>"0C'1=``````N`$```#H +XM2?#__X/X_W0QB<:!YO___S]TYX/^7`^$V`$``(U%S(D$)(ET)`3H4H`#`+@! +XM````Z!CP__^#^/]USXU5S(D4).B8@`,`BW7,QT0D!&````")-"3H@8[__X7` +XM#X3"`0``QT0D!`$```")-"3H+;$``(F%P'___XN%P'___XL0B<>%TG1$BP*) +XMUH7`=!V0)?___S^)`X/#!#F=N'___W1XBT8$@\8$A"0C___]_,<#H7NW__XG#@_MG#X23````@_MA +XM#X2^`0``@_MS#X2M````B5PD!,<$)!ZZ"`CH<0@!`(7`#X1Y`0``B5PD!,<$ +XM)&!>"0CH27T#`(/[<0^$=0$``#'`Z`GM__^#^#J)PP^%/P$``#'`Z/?L___' +XM!6Q>"0@!````QP5P7@D(`````(/X9XG##X1I____@_AA#X5S____QP5P7@D( +XM`0```.E;____@3UL7@D(____?P^$;____\<%;%X)"/___W\QP.B?[/__B<.# +XM^W,/A5/___\QP.B-[/__QT0D!',```#'!"1@7@D(B!="0B+1)`T]L0!=6F#_U]T9(/_?W<*]@2]O5$)"`1U58E\)`3'!"3_N0@( +XMZ%`'`0"%P'5!O@(```#K))"-="8`B5PD!,<$)&!>"0CH('P#`#'`.=\/E,`I +XMQ@^$T?[__S'`Z-KK__^#^/^)PW73A?8/A+O^___'!"18````Z*\%``"#Q`R) +XMV%M>7UWI$>?__Y")7"0$QP0D!P```.@`!@``Z7+^___'!6Q>"0C___]_Z7S^ +XM__^A<%X)"(7`#X4^_O__QP5P7@D(`0```.G*_O__B10DZ-2%___I*O___XUV +XM`%6)Y5.)PX/L%.LWD(UT)@"#^O]T8872>!WWP@```$"0=12#^G]_#P^VP@^W +XMA`#@(`D(J`]U58E4)`2)'"3H3GL#`+@!````Z!3K__^#^%R)PG6],<#H!NO_ +XM_X/X_W0<@_@*NB````!TOHG"@575E.#["RC4%X)"#'`QT7H +XM`````,=%[`````#'1?``````QP5,7@D(^&\)",<%1%X)"`````#HXN7__XU% +XMZ,<%5%X)"`````#'!5Q>"0@`````QT0D!/"1"`B)!"3HJP<``(U%W#';QT7< +XM`````,=%X`````#'1>0`````QT0D!+"1"`B)!"3H@0<``)"X`0```.@FZO__ +XM@_@GB<9T=']0@_@@=.B0C;0F``````^/_P$``(/X"8VT)@````!TSH/X"@^$ +XM]@```(/X_XGV#X3&`0``B35$7@D(C470,`@_XB#Y3`#[;XB?:) +XM^.B9Z?__.<:)PW1H@_@*#X3`````@_C_#X2W````B=@E____?ST*``!`#X3' +XM````@_XG#X3M````@_Y@#X3^````@_XB=;B#^V"X8````'0'B=@-````0(E$ +XM)`2-1=R)!"3H:'D#`(GXZ#'I__\YQHG#=9B#_F`/A3[___^-1=R)!"3'1"0$ +XM8````.@_>0,`C47B)!"3HSWH#`.EO_O__B70D!,<$)#,```#H +XM&@,``(G8)?___W\]"@``0`^%.?___XM5X(72#X0N____BT7`,` +XMZ;_^__^-1=R)7"0$B00DZ(!X`P#IJ_[__S'`Z$3H__^#^`J0#X0*_O__@_C_ +XM#X0!_O__B<:!S@```$#I.O[__X7;B?9T([C_____Z'3C__^-="8`Z0S___^# +XM^"(/A1C^__^)]NE0_O__C47B)!"3HFGD#`(/$+%M>7UW#B?95B>6#["B)=?PQ]HE=^(L- +XM*'<*"(7)=`R)\(M=^(MU_(GL7<.+10C'1?0`````B47PC47PZ,?\__^)PXL` +XMAP,`B1PDB<;H8`@!`(GPBUWXBW7\B>Q=PXUT)@!5B>53@^P$ +XMBQTH=PH(A=MU3XM%"(M($(G+C;0F`````(L1A=)T.HL"@\$$A!VI +XM````0'46@_A_C78`?PX/ML#VA`#@(`D(PW47D(M"!(/"!(7`==6+$872=<:# +XMQ`1;7<.)V.@#_/__BU4(B<.+0A")!"3HTP5=PXUT)@"-O"<`````58GE@^P(H`#`P6\8`D(BQ")%"3_4`2AP&`)"#L%Q&`)"'?:R<.0C70F`%6AQ&`)"(L5 +XMP&`)"(GE78D5Q&`)",.-=@"-O"<`````58GEBT4(BP")10A=Z>\-`P#K#9"0 +XMD)"0D)"0D)"0D)!5B>6#[!BA@%X)"(7`=`+)PX%]"(8```"-10R)1?QV!\=% +XM"(4```")1"0$BU4(BP25H%X)"(D$).AS6@,`HX!>"0C)PXVV`````(V_```` +XM`%6)Y8/L".@E____QT0D!`$```#'!"0`F@L(Z'V!__^058GE5U93@^P<```!`=`Z+-8!>"0B%]@^$M````(G>@>;_ +XM__\/@?Z&````=@6^A0```.CB&P$`]\,````@QP7`F`H(`0````^$C````*&` +XM7@D(A<<$)`$```#HAY___^@RS```QT0D"`(```#'1"0$&"\)",<$ +XM)/0N"0CH=G(!`*'4EPH(A +XM7UW#@>,````0=5B%_W0IH8!>"0C'!"2F&`D(B40D!.@O6@,`Z4[___^+%>1U +XM"0B%TG2)Z7C___^+1?")1"0$BP2UH%X)"(D$).CE60,`QP0D;\<(".CY60,` +XMZ1C___^-="8`H2!W"@C'!"0HN@@(B40D!.C;60,`ZY&)]HV\)P````!5B>5= +XMZ:<#`0"-M"8`````58GEBT4(BP")10A=Z<\#`0#K#9"0D)"0D)"0D)"0D)!5 +XMB>6#[!B+10C'1"0(`````,<$)`,```")1"0$Z-M]___)PXVV`````(V\)P`` +XM``!5B>6#[!B+10C'1"0(`````,<$)`(```")1"0$Z.N!___)PXVV`````(V\ +XM)P````!5B>53@^P4BUT(.1W`8`D(7<.-=@#H=W[__XUT)@"-O"<`````58GE4X/L!(L5O&`)"*'` +XM8`D(BUT(C0S".6#[`B+#`#B40D!*&\8`D(B00DZ$,+`P"+#"0BA@)@* +XM"(D$).B`70``B00DZ.@&`0#'1"0,7[H(",=$)`@#````QT0D!`$```"CI%X) +XM"*&`F`H(B00DZ$Y=``")!"3HM@8!`,=$)`QMN@@(QT0D"`0```#'1"0$`0`` +XM`*.H7@D(H8"8"@B)!"3H'%T``(D$).B$!@$`QT0D#'ZZ"`C'1"0(!0```,=$ +XM)`0!````HZQ>"0BA@)@*"(D$).CJ7```B00DZ%(&`0#'1"0,C;H(",=$)`@& +XM````QT0D!`$```"CL%X)"*&`F`H(B00DZ+A<``")!"3H(`8!`,=$)`RDN@@( +XMQT0D"`<```#'1"0$`0```*.T7@D(H8"8"@B)!"3HAEP``(D$).CN!0$`QT0D +XM#,*Z"`C'1"0("````,=$)`0!````H[A>"0BA@)@*"(D$).A47```B00DZ+P% +XM`0#'1"0,V[H(",=$)`@)````QT0D!`$```"CO%X)"*&`F`H(B00DZ")<``") +XM!"3HB@4!`,=$)`SKN@@(QT0D"`H```#'1"0$`0```*/`7@D(H8"8"@B)!"3H +XM\%L``(D$).A8!0$`QT0D#/^Z"`C'1"0("P```,=$)`0!````H\1>"0BA@)@* +XM"(D$).B^6P``B00DZ"8%`0#'1"0,#;L(",=$)`@,````QT0D!`$```"CR%X) +XM"*&`F`H(B00DZ(Q;``")!"3H]`0!`,=$)`P?NP@(QT0D"`T```#'1"0$`0`` +XM`*/,7@D(H8"8"@B)!"3H6EL``(D$).C"!`$`QT0D##.["`C'1"0(#@```,=$ +XM)`0!````H]!>"0BA@)@*"(D$).@H6P``B00DZ)`$`0#'1"0,1;L(",=$)`@/ +XM````QT0D!`$```"CU%X)"*&`F`H(B00DZ/9:``")!"3H7@0!`,=$)`Q7NP@( +XMQT0D"!````#'1"0$`0```*/87@D(H8"8"@B)!"3HQ%H``(D$).@L!`$`QT0D +XM#&J["`C'1"0($0```,=$)`0!````H]Q>"0BA@)@*"(D$).B26@``B00DZ/H# +XM`0#'1"0,AKL(",=$)`@2````QT0D!`$```"CX%X)"*&`F`H(B00DZ&!:``") +XM!"3HR`,!`,=$)`R/NP@(QT0D"!,```#'1"0$`0```*/D7@D(H8"8"@B)!"3H +XM+EH``(D$).B6`P$`QT0D#)V["`C'1"0(%````,=$)`0!````H^A>"0BA@)@* +XM"(D$).C\60``B00DZ&0#`0#'1"0,M;L(",=$)`@5````QT0D!`$```"C[%X) +XM"*&`F`H(B00DZ,I9``")!"3H,@,!`,=$)`S"NP@(QT0D"!8```#'1"0$`0`` +XM`*/P7@D(H8"8"@B)!"3HF%D``(D$).@``P$`QT0D#-"["`C'1"0(%P```,=$ +XM)`0!````H_1>"0BA@)@*"(D$).AF60``B00DZ,X"`0#'1"0,WKL(",=$)`@8 +XM````QT0D!`$```"C^%X)"*&`F`H(B00DZ#19``")!"3HG`(!`,=$)`S,P@@( +XMQT0D"!D```#'1"0$`0```*/\7@D(H8"8"@B)!"3H`ED``(D$).AJ`@$`QT0D +XM#/&["`C'1"0(&@```,=$)`0!````HP!?"0BA@)@*"(D$).C06```B00DZ#@" +XM`0#'1"0,!+P(",=$)`@;````QT0D!`$```"C!%\)"*&`F`H(B00DZ)Y8``") +XM!"3H!@(!`,=$)`PBO`@(QT0D"!P```#'1"0$`0```*,(7PD(H8"8"@B)!"3H +XM;%@``(D$).C4`0$`QT0D#/#""`C'1"0('0```,=$)`0!````HPQ?"0BA@)@* +XM"(D$).@Z6```B00DZ*(!`0#'1"0,&,,(",=$)`@>````QT0D!`$```"C$%\) +XM"*&`F`H(B00DZ`A8``")!"3H<`$!`,=$)`PTO`@(QT0D"!\```#'1"0$`0`` +XM`*,47PD(H8"8"@B)!"3HUE<``(D$).@^`0$`QT0D#$##"`C'1"0((````,=$ +XM)`0!````HQA?"0BA@)@*"(D$).BD5P``B00DZ`P!`0#'1"0,2[P(",=$)`@A +XM````QT0D!`$```"C'%\)"*&`F`H(B00DZ')7``")!"3HV@`!`,=$)`QHO`@( +XMQT0D""(```#'1"0$`0```*,@7PD(H8"8"@B)!"3H0%<``(D$).BH``$`QT0D +XM#'J\"`C'1"0((P```,=$)`0!````HR1?"0BA@)@*"(D$).@.5P``B00DZ'8` +XM`0#'1"0,=,,(",=$)`@D````QT0D!`$```"C*%\)"*&`F`H(B00DZ-Q6``") +XM!"3H1``!`,=$)`R,O`@(QT0D""4```#'1"0$`0```*,L7PD(H8"8"@B)!"3H +XMJE8``(D$).@2``$`QT0D#*&\"`C'1"0()@```,=$)`0!````HS!?"0BA@)@* +XM"(D$).AX5@``B00DZ.#_``#'1"0,O[P(",=$)`@G````QT0D!`$```"C-%\) +XM"*&`F`H(B00DZ$96``")!"3HKO\``,=$)`S0O`@(QT0D""@```#'1"0$`0`` +XM`*,X7PD(H8"8"@B)!"3H%%8``(D$).A\_P``QT0D#-J\"`C'1"0(*0```,=$ +XM)`0!````HSQ?"0BA@)@*"(D$).CB50``B00DZ$K_``#'1"0,E,,(",=$)`@J +XM````QT0D!`$```"C0%\)"*&`F`H(B00DZ+!5``")!"3H&/\``,=$)`SJO`@( +XMQT0D""L```#'1"0$`0```*-$7PD(H8"8"@B)!"3H?E4``(D$).CF_@``QT0D +XM#/:\"`C'1"0(+````,=$)`0!````HTA?"0BA@)@*"(D$).A,50``B00DZ+3^ +XM``#'1"0,#;T(",=$)`@M````QT0D!`$```"C3%\)"*&`F`H(B00DZ!I5``") +XM!"3H@OX``,=$)`P;O0@(QT0D""X```#'1"0$`0```*-07PD(H8"8"@B)!"3H +XMZ%0``(D$).A0_@``QT0D#">]"`C'1"0(+P```,=$)`0!````HU1?"0BA@)@* +XM"(D$).BV5```B00DZ![^``#'1"0,.[T(",=$)`@P````QT0D!`$```"C6%\) +XM"*&`F`H(B00DZ(14``")!"3H[/T``,=$)`Q0O0@(QT0D"#$```#'1"0$`0`` +XM`*-<7PD(H8"8"@B)!"3H4E0``(D$).BZ_0``QT0D#&*]"`C'1"0(,@```,=$ +XM)`0!````HV!?"0BA@)@*"(D$).@@5```B00DZ(C]``#'1"0,:[T(",=$)`@S +XM````QT0D!`$```"C9%\)"*&`F`H(B00DZ.Y3``")!"3H5OT``,=$)`QVO0@( +XMQT0D"#0```#'1"0$`0```*-H7PD(H8"8"@B)!"3HO%,``(D$).@D_0``QT0D +XM#(.]"`C'1"0(-0```,=$)`0!````HVQ?"0BA@)@*"(D$).B*4P``B00DZ/+\ +XM``#'1"0,D;T(",=$)`@V````QT0D!`$```"C<%\)"*&`F`H(B00DZ%A3``") +XM!"3HP/P``,=$)`RAO0@(QT0D"#<```#'1"0$`0```*-T7PD(H8"8"@B)!"3H +XM)E,``(D$).B._```QT0D#/O>"`C'1"0(.````,=$)`0!````HWA?"0BA@)@* +XM"(D$).CT4@``B00DZ%S\``#'1"0,J+T(",=$)`@Y````QT0D!`$```"C?%\) +XM"*&`F`H(B00DZ,)2``")!"3H*OP``,=$)`RXPP@(QT0D"#H```#'1"0$`0`` +XM`*.`7PD(H8"8"@B)!"3HD%(``(D$).CX^P``QT0D#+N]"`C'1"0(.P```,=$ +XM)`0!````HX1?"0BA@)@*"(D$).A>4@``B00DZ,;[``#'1"0,RKT(",=$)`@\ +XM````QT0D!`$```"CB%\)"*&`F`H(B00DZ"Q2``")!"3HE/L``,=$)`S:O0@( +XMQT0D"#T```#'1"0$`0```*.,7PD(H8"8"@B)!"3H^E$``(D$).AB^P``QT0D +XM#.3#"`C'1"0(/@```,=$)`0!````HY!?"0BA@)@*"(D$).C(40``B00DZ##[ +XM``#'1"0,\;T(",=$)`@_````QT0D!`$```"CE%\)"*&`F`H(B00DZ)91``") +XM!"3H_OH``,=$)`P(Q`@(QT0D"$````#'1"0$`0```*.87PD(H8"8"@B)!"3H +XM9%$``(D$).C,^@``QT0D#`V^"`C'1"0(00```,=$)`0!````HYQ?"0BA@)@* +XM"(D$).@R40``B00DZ)KZ``#'1"0,*+X(",=$)`A#````QT0D!`$```"CH%\) +XM"*&`F`H(B00DZ`!1``")!"3H:/H``,=$)`P[O@@(QT0D"$0```#'1"0$`0`` +XM`*.D7PD(H8"8"@B)!"3HSE```(D$).@V^@``QT0D#%&^"`C'1"0(10```,=$ +XM)`0!````HZA?"0BA@)@*"(D$).B<4```B00DZ`3Z``#'1"0,7[X(",=$)`A& +XM````QT0D!`$```"CK%\)"*&`F`H(B00DZ&I0``")!"3HTOD``,=$)`QQO@@( +XMQT0D"$<```#'1"0$`0```*.P7PD(H8"8"@B)!"3H.%```(D$).B@^0``QT0D +XM#(B^"`C'1"0(2````,=$)`0!````H[1?"0BA@)@*"(D$).@&4```B00DZ&[Y +XM``#'1"0,FKX(",=$)`A)````QT0D!`$```"CN%\)"*&`F`H(B00DZ-1/``") +XM!"3H//D``,=$)`RHO@@(QT0D"$H```#'1"0$`0```*.\7PD(H8"8"@B)!"3H +XMHD\``(D$).@*^0``QT0D#"S$"`C'1"0(2P```,=$)`0!````H\!?"0BA@)@* +XM"(D$).AP3P``B00DZ-CX``#'1"0,3,0(",=$)`A,````QT0D!`$```"CQ%\) +XM"*&`F`H(B00DZ#Y/``")!"3HIO@``,=$)`RQO@@(QT0D"$T```#'1"0$`0`` +XM`*/(7PD(H8"8"@B)!"3H#$\``(D$).AT^```QT0D#,*^"`C'1"0(3@```,=$ +XM)`0!````H\Q?"0BA@)@*"(D$).C:3@``B00DZ$+X``#'1"0,<,0(",=$)`A/ +XM````QT0D!`$```"CT%\)"*&`F`H(B00DZ*A.``")!"3H$/@``,=$)`R]P``QT0D +XM#-B^"`C'1"0(40```,=$)`0!````H]A?"0BA@)@*"(D$).A$3@``B00DZ*SW +XM``#'1"0,\;X(",=$)`A2````QT0D!`$```"CW%\)"*&`F`H(B00DZ!).``") +XM!"3H>O<``,=$)`S`Q`@(QT0D"%,```#'1"0$`0```*/@7PD(H8"8"@B)!"3H +XMX$T``(D$).A(]P``QT0D#`V_"`C'1"0(5````,=$)`0!````H^1?"0BA@)@* +XM"(D$).BN30``B00DZ!;W``#'1"0,([\(",=$)`A5````QT0D!`$```"CZ%\) +XM"*&`F`H(B00DZ'Q-``")!"3HY/8``,=$)`P]OP@(QT0D"%8```#'1"0$`0`` +XM`*/L7PD(H8"8"@B)!"3H2DT``(D$).BR]@``QT0D#%>_"`C'1"0(5P```,=$ +XM)`0!````H_!?"0BA@)@*"(D$).@830``B00DZ(#V``#'1"0,9[\(",=$)`A8 +XM````QT0D!`$```"C]%\)"*&`F`H(B00DZ.9,``")!"3H3O8``,=$)`QROP@( +XMQT0D"%D```#'1"0$`0```*/X7PD(H8"8"@B)!"3HM$P``(D$).@<]@``QT0D +XM#(F_"`C'1"0(6@```,=$)`0!````H_Q?"0BA@)@*"(D$).B"3```B00DZ.KU +XM``#'1"0,F+\(",=$)`A;````QT0D!`$```"C`&`)"*&`F`H(B00DZ%!,``") +XM!"3HN/4``,=$)`RSOP@(QT0D"%P```#'1"0$`0```*,$8`D(H8"8"@B)!"3H +XM'DP``(D$).B&]0``QT0D#,R_"`C'1"0(70```,=$)`0!````HPA@"0BA@)@* +XM"(D$).CL2P``B00DZ%3U``#'1"0,W[\(",=$)`A>````QT0D!`$```"C#&`) +XM"*&`F`H(B00DZ+I+``")!"3H(O4``,=$)`SOOP@(QT0D"%\```#'1"0$`0`` +XM`*,08`D(H8"8"@B)!"3HB$L``(D$).CP]```QT0D#`S`"`C'1"0(8````,=$ +XM)`0!````HQ1@"0BA@)@*"(D$).A62P``B00DZ+[T``#'1"0,'\`(",=$)`AA +XM````QT0D!`$```"C&&`)"*&`F`H(B00DZ"1+``")!"3HC/0``,=$)`PNP`@( +XMQT0D"&(```#'1"0$`0```*,<8`D(H8"8"@B)!"3H\DH``(D$).A:]```QT0D +XM#$+`"`C'1"0(8P```,=$)`0!````HR!@"0BA@)@*"(D$).C`2@``B00DZ"CT +XM``#'1"0,3\`(",=$)`AD````QT0D!`$```"C)&`)"*&`F`H(B00DZ(Y*``") +XM!"3H]O,``,=$)`Q````,=$)`0!````HW1@"0BA@)@* +XM"(D$).BF1@``B00DZ`[P``#'1"0,K,4(",=$)`AY````QT0D!`$```"C>&`) +XM"*&`F`H(B00DZ'1&``")!"3HW.\``,=$)`SP```,=$ +XM)`0!````HX!@"0BA@)@*"(D$).@01@``B00DZ'CO``#'1"0,ML$(",=$)`A\ +XM````QT0D!`$```"CA&`)"*&`F`H(B00DZ-Y%``")!"3H1N\``,=$)`S-P0@( +XMQT0D"'T```#'1"0$`0```*.(8`D(H8"8"@B)!"3HK$4``(D$).@4[P``QT0D +XM#`#&"`C'1"0(@````,=$)`0!````HXQ@"0BA@)@*"(D$).AZ10``B00DZ.+N +XM``#'1"0,W\$(",=$)`B!````QT0D!`$```"CD&`)"*&`F`H(B00DZ$A%``") +XM!"3HL.X``,=$)`SYP0@(QT0D"((```#'1"0$`0```*.48`D(H8"8"@B)!"3H +XM%D4``(D$).A^[@``QT0D#$C&"`C'1"0(@P```,=$)`0!````HYA@"0BA@)@* +XM"(D$).CD1```B00DZ$SN``#'1"0,"\((",=$)`B$````QT0D!`$```"CG&`) +XM"*&`F`H(B00DZ+)$``")!"3H&NX``,=$)`P@P@@(QT0D"(4```#'1"0$`0`` +XM`*.@8`D(H8"8"@B)!"3H@$0``(D$).CH[0``QT0D##?""`C'1"0(A@```,=$ +XM)`0!````HZ1@"0BA@)@*"(D$).A.1```B00DZ+;M``#'1"0,5<((",=$)`B' +XM````QT0D!`$```"CJ&`)"*&`F`H(B00DZ!Q$``")!"3HA.T``,=$)`QFP@@( +XMQT0D"(@```#'1"0$`0```*.L8`D(H8"8"@B)!"3HZD,``(D$).A2[0``QT0D +XM#'#&"`C'1"0(B0```,=$)`0!````H[!@"0BA@)@*"(D$).BX0P``B00DZ"#M +XM``"CN&`)"(/$%%M=PY"0D)"053'`B>6+50A75E.+"H7)="B+-=A@"0B)UXVT +XM)@````!IP/$````QTHT$`8M/!(/'!/?VA6#["BA0)D+"(E=](EU^(E]_(7`=`J+'=A@"0B%VW5RBQW4 +XM8`D(A=L/A;````"+'?!@"0B+->Q@"0B)WP'W=$6A@)@*",=$)`P!QP@(QT0D +XM"`0```#'1"0$#0```(D$).CI0@``:\YDB5PD"(ET)`2)RL'Z'XD$)(G(]_^) +XM1"0,Z&D\`P"+7?2+=?B+??R)[%W#BS7,8`D(A?9TA*&`F`H(QT0D#*3&"`C' +XM1"0(`@```,=$)`0-````B00DZ(U"``"-%/4`````B50D"(E<)`2)!"3H%CP# +XM`.E#____D*&`F`H(QT0D#.S&"`C'1"0(`P```,=$)`0-````B00DZ$M"``") +XM7"0$B00DZ-\[`P#I&O___XUV`(V\)P````!5B>6#[`BAT&`)",<%0)D+"``` +XM``")!"3HX^T"`,<%T&`)"`````#)PXVT)@````!5B>53@^P4QT0D!,28"@C' +XM!"2`,@D(Z#5*`0"%P'1+BQWH=@H(Z&;\``"+10C'!<"8"@@!````QP7H=@H( +XM`````(D$).BG[```QP0D"@```.AK_@``Z#;\``")'>AV"@C'!<"8"@@````` +XM@\046UW#58GE5E.#['"+10B%P'0&BPB%R75KBT4,B00DZ*!;`P")QHU%F(E$ +XM)`2)-"3H*V+__X/``70@BU40A=)U(P^W3:")RH'B`/```('Z`(```'4%@^%) +XM=5*#Q'`QP%M>7<.0#[=-H+@!````B7<.+ +XM50R)!"2)5"0$Z(%8`P")PXD$).@G6P,`B1PDB<;HO>P"`.EZ____B30DQT0D +XM!`$```#HA&'__X7`#Y3`@\1P6P^VP%Y=PXGVC;PG`````%6)Y5=64X/L+(M% +XM#(M]"(7`#X5A`@``QT7P`````*$@)`D(P>`$!>#2"`@]X-(("'9YN_#2"`B+ +XM0_")!"3HWEP#`(D\)(E$)`3HKE[__X7`=4.+10R%P`^$Z@$``*&`F`H(QT0D +XM#"W'"`C'1"0("0```,=$)`0-````B00DZ#Y```")?"0$B00DZ-(Y`P#'1?`! +XM````H2`D"0B)VH/#$,'@!`7@T@@(.=!WC,=$)`3$F`H(QP0DE#()".A12`$` +XMA<")PP^$/P$``*%`F0L(QT7H`````(7`#X5C`@``B7PD!,<$)+@X"0CH4U<# +XM`(E%Y,=$)`0P*@@(B00DZ!#A__^+&X7;#X3S````BS.%]@^$Z0```(M%Z(M5 +XMZ,=%[``````!P,'B`HE%W(E5X.LFB?;V!=1@"0@"#X76````@\,$#X2W```` +XMBS.%]@^$K0```(-%[`&A0)D+"(7`=$C'1"0$C#,)"(DT).B/7?__A"+3>R+!`*#X1_3Z(/P`8/@ +XM`83`=9C'1"0(`````(M%Y(DT)(E$)`3H=/W__X7`#X1L____BW4,A?9T?(L# +XMQP0D4<<("(E$)`3H@S@#`(E\)`3'!"01%PD(Z',X`P"#PP3'1?`!````#X5) +XM____BU7DB10DZ&C?__^+1?"#Q"Q;7E]=PZ&`F`H(QT0D#$7'"`C'1"0("@`` +XM`,=$)`0-````B00DZ(@^``")!"3H(#@#`(MU#(7V=83'1?`!````BT7P@\0L +XM6UY?7<.AT&`)"(M5Z(M-[`^V!!"#X0?3Z(/P`8/@`>DI____B3PDZ'!8`P#' +XM1"0$+P```(D$).APW0``A<`/A;@```#'1"0$E'8*"(D\).AH1@$`A<`/A&?] +XM___'1"0$E'8*"(D\).A01@$`A<")PP^$3?W__Z&`F`H(QT0D#!O'"`C'1"0( +XM"````,=$)`0-````B00DZ-$]``")?"0$B00DZ&4W`P"+`X7`=`B)!"3HI^@` +XM`,<$)`H```#H:_H``,=%\`$```#I_?S__Z'08`D(BU77UW# +XMD%6)Y593@^P0BU4(BT($A575E.#[$R+10B+>`C'1"0$E'8* +XM"(L'B00DZ.]$`0#'1<0`````A#2"`@/AKP```"^ +XM\-((".L:H2`D"0B)\H/&$,'@!`7@T@@(.=`/AIL```"+1O")!"3H*U@#`(L? +XMB1PDB40D!.CY6?__A7UW#C;0F`````#G(#X18____#0```$")`X/# +XM!(/"!(L"A)!"3H28D``(D'B00DQT0D!#`J"`CH9]S__XL7 +XMB57(B10DZ#I5`P#'1"0$+P```(D$).@ZV@``B474QT0D!,28"@C'!"24,@D( +XMZ#-#`0"%P'00BS"%]G0*BP:%P`^%#0(``+[`(`D(BT7(QP0DN#@)"(E$)`3H +XM-U(#`,=%T`````")1=BA0)D+"(7`#X6?`@``BT70BU70BQ['1")5=SK/XL#A<`/A8$```#'1"0(`````(M%R,<$)`````")1"0$Z,_X +XM__^%P`^%E0```(M>!(/&!(7;#X1+`0``@T7,`8M%U(7`=;J+`X/X+W6UBPU` +XMF0L(A[`0```,<$),`X"0B)1"0$Z+-0`P")!XD$),=$)`0P*@@( +XMZ'':__^+50B)%"3H-K8``(L'B00DZ+S9___K,X/"!(D7BPKIL_S__XM%V(D$ +XM).C#Y`(`BT4,A<`/A)T```"+!S';B00DZ.Q0`P"+50R)`HU%[(D$).A\V?__ +XM@\1,B=A;7E]=PXM%U(7`#X3M_?__Z>/]__^AT&`)"(M5T(M-S`^V!!"#X0?3 +XMZ(/P`8/@`>F6_O__BT7$A<`/A;D```"A@)@*"(L?QT0D#%7'"`C'1"0(!0`` +XM`,=$)`0-````B00DZ&$X``")7"0$B00DZ/4Q`P#HX/(``.FJ_/__BT7$A<`/ +XMA8$```"A@)@*"(L?QT0D#'+'"`C'1"0(!@```,=$)`0-````B00DZ!DX``") +XM7"0$,=N)!"3HJS$#`.B6\@``Z2K___^+5"+3

3@,`B0>)'"3H).,"`,=$)`0P*@@(BP>)!"3HDMC__XM5#(72=".+!XD$ +XM).A!3P,`BU4,B0*+![L!````B00DZ,W7___I0?[__XM5"(D4).@MM```Z]^- +XM="8`C;PG`````%6)Y5=64X/L+(M=",=$)`3$F`H(QP0DE#()".@P/P$`A=N) +XMQG1BBT,$A`$`A?;'!4"9"P@!````#X1R`0``BS:%]@^$:`$` +XM`(L&A<`/A%X!``#'1?``````ZQB#Q@0/A$P!``"+!H7`D`^$00$``(-%\`&# +XM."]UXXD$).B93P,`B00DZ#U6__^%P(G'=,V)!"3'1"0$,!X%".B;UO__BT7P +XMBU7P@^`?@^(/B47HB57DB3PDZ'U9__^%P(G"#X3=````BPJ%R73H@'H(+G4; +XM@'H)`'3B-%(4`````N`$````#%=!@ +XM"0C3X`D"]@748`D(`0^$=?___XD<).@&40,`B00DZ/[P___'1"0,BL<(",=$ +XM)`@!````QT0D!`T```")1>RA@)@*"(D$).AV-```BU7PBTWLB5PD#(E4)`B) +XM3"0$B00DZ/PM`P")/"3HH%C__X7`B<(/A2/___^)/"3H\M3__X/&!`^%M/[_ +XM_X/$+%M>7UW#BTWP`P708`D(@^$'T^(($.EA____H2-%`"X`0````,5T&`)"-/@9@D"Z3C____'!53@^P4BUT(QT0D +XM"`````#'!"0"````C4,DB40D!.C75?__C4,\QT0D"`````")1"0$QP0D`P`` +XM`.B\5?__C4-4QT0D"`````")1"0$QP0D#P```.BA5?__QP7\F`H(`````(M# +XM(*/H=@H(H;1V"@B)!"3H!M<``*',EPH(B00DZ/G6``"A!'8*"(D$).CLU@`` +XMH429"PB)!"3HW]8``(M#$(E$)`2+`XD$).@>VP``QT0D"`$```#'1"0$`@`` +XM`(D$)*.T=@H(Z,U0__^+0Q2)1"0$BT,$B00DZ._:``#'1"0(`0```,=$)`0" +XM````B00DH\R7"@CHGE#__XM#&(E$)`2+0PB)!"3HP-H``,=$)`@!````QT0D +XM!`(```")!"2C!'8*".AO4/__BT,A@"0B)!"3H[=T" +XM`,<%Z&`)"`````"AY&`)"(7`=!")1"0$QP0D-P``$.A:T/__QP0D#0``$.A. +XMT/__R57B==64X/L+(E%V(D4).BZ3`,`B<.+1=B) +XM!"3H[4L#`(D=7)D+"(G&Z`Q3___'``````")7"0$B30DZ#I4___'!5R9"P@` +XM````B1PDZ*S6``#HXU+__XL`@_@(=%"#^`QT&X/X`G0-H>1@"0B%P`^$N@$` +XM`(/$+%M>7UW#D.BW4O__BP")!"3H75#__XET)`3'!"0V````B40D".B=S___ +XM@\0L6UY?7<.0C70F`,=$)`0`````B30DZ,#2``")1>"#P`%T+XU%\L=$)`@" +XM````B40D!(M%X(D$).A.T@``@_@"#X2!`0``A)!XE\)`2+1=R)!"3H(=<``(DWB<.+.(D$ +XM).AS2P,`B3PDB<;HJ4H#`(D<)(G'Z#_<`@"+1=R)!"3HA-4``(ET)`2)/"2) +XM-5R9"PCH[E+__XDT),<%7)D+"`````#H8-4``.B74?__BP")!"3H/4___XE\ +XM)`3'!"0V````B40D".A]SO__@\0L6UY?7<.0C70F`,=$)`3$F`H(QP0D*#() +XM".A,.`$`A<`/A-T```#'1"0$Q)@*",<$)"@R"0CHD#@!`(-]X/^)1>AT#H!] +XM\B-T"*&DF`H(B47HQT7L`````(U%Z(D$).C'V0``B47")!"3H^-(``(D<).@\3O__B70D!,<$)'@```")1"0( +XMZ'S-___I+O[__Z%T=PH(Z2W___^-M@````"-O"<`````58GE5U93@^Q,BWT( +XMC5WLBT<0BP#'1?``````B47LBT4,A%P`^$Y0$``(L(AO__\<%M'8*"``` +XM``#'!QT70``````'2P>`"B56XB46\ZRJ)]HL#AQ@"0@!QP5,F0L(`````(D4 +XM).B4UP(`Z&_Y__^#Q$Q;7E]=PXM%R(7`#X2I_O__Z9_^__^+!XD$).C]Y___ +XMB47,Z<#^__^AT&`)"(M5S(M-T`^V!!"#X0?3Z(/P`8/@`>DU____B40D!(D< +XM).A:>```A<")Q@^%G_S__XM%[(D$).B%10,`QP0D,0``$*,@=PH(Z*3)___I +XM?OS__XD<)(E$)`3H(W@``(7`B<,/A03]__^AZ&`)"(D$).A,10,`QP0D,0`` +XM$*,@=PH(Z&O)___IX?S__XVV`````*'H8`D(BQ"#^B\/A(G\__^#^BX/A(#\ +XM___HDOC__Z'H8`D(Z7'\__^AT&`)"(M5N(M-T`^W!`*#X0_3Z(/P`8/@`>EX +XM_O__B?:-O"<`````58GE5E.#Q("AC'8*"(MU#(7`=0VAE'<*"(7`#X5/`@`` +XMQT0D!,28"@B-78S'!"1@-@D(Z,@R`0#'!"0`````A<`/E<`/ML")1"0$Z$"$ +XM``"-1;")1"0(QT0D!-!V"@C'!"0"````Z(%,__^-1")1"0(QT0D!%1W"@C'!"0/````Z$M,__^AZ'8*"(L5 +XMM'8*",=$)`3_____B46LHAV"@@` +XM````Z+O)___'!"3_____Z!_O`@")-"3'1"0$`0```.A/^?__B1PDZ/?(__^# +XM[(!;7EW#QP0D`````.ADZ@``Z:#]__^0D)"0D)"0D)"0D)"0D)!5A<")Y5.) +XMTP^$`@$``(L(A='N#^2)T=HUT +XM)@"#XPAT8(/Y/+@$````C78`=`>#^3ZP`G5,6UW#C70F`(M`"(7`==GVPQ!T +XM%H/Y?)!T.(/Y/'1N@_D^=0:#^CZ0=##VPP1TN8/Y/70_@_DAD'6N@_H]N`8` +XM``!TO8/Z?K`(=9WKM%LQP%W#@_HFC78`==!;N`$```!=PXVV`````(G06UW! +XMZ`2#X`'#@_H]=.*#^GZX!P````^%8O___XGVZ73___^#^CQUF(VV`````.O` +XMC;0F`````(V\)P````!5B>6#['B)!"2)7?2)=?B)UHE]_.CG0`,`@#@`B<-T +XM(8U&_X/X`78@B70D!(D<).A(1___BUWTBW7XBWW\B>Q=P[@!````Z^R-192) +XM1"0$B1PDZ$5'__^#P`%TY8ET)`2)'"3H%$?__X7`#X2"````BT6@.P4LF0L( +XM#X26````BT6D.P7HF`H(=%7'!"0$````Z'9&__^#^/^)QP^$H0```(7`#XZH +XM````C12%`````(D4).BXT@(`B3PDB<.)1"0$Z`9'__^+?:2-#(.)PHGV@^H! +XM>&.+0?R#Z00Y^'7Q#[=5G,'F`S'`A=8/E,#I0O___P^W59R)T"4`\```/0!` +XM``!T&H/^`70B@_X"="2)]N@G1?__#[=5G,'F!NO(9C'`@_X!=>/I"?___[Y) +XM````Z[1FOI(`ZZX/MU6575E.! +XM[/P```"+?0B)^X/#!(L#QP0DIL<("(E$)`3H:L0``(7`=>>+`X7`=0V#>_Q, +XMC5/\#X0``P``B40D!,<$)+W'"`CH0\0``(7`=7O'A13______P``QX48____ +XM`````,>%(/___Q`O"0B+`X7`#X6P````C4<$.=@/A*4```"+10RZ'P```(L8 +XMBS.)\.B9_/__A<`/A4D"``"+50R-0P2)`O9%$`$/A(D```#'!"3X;PD(Z*,\ +XM`P")QX'$_````(GX6UY?7<.+,X/#!,>%%/______``#'A2#___]L+PD(@_Y& +XM=!.#_E#'A2#___\@+PD(#X1)`@``QT0D!&PO"0B)'"3H?T+__X7`#X3^`0`` +XMQX48____`````(L#A<`/A%#____'!"1Z```0Z'O"___I2O___XDT)#'VQT0D +XM!`(```#H)'(``(F%'/___XD$),=$)`0P*@@(Z#[%__^+5P2-1P3'A1#___\` +XM````,?^)PXU"J(/X('9"A=(/B-8````Y%=Q="0@/CLH```"AX%T)"(N$D#0$ +XM``"#^&P/A,````"%_P^$ZP0``(U"OX/X.7#PP2%]G6)BY4<____B10D +XMZ`7$__^)-"3HG2P!`('$_````%M>B<>)^%]=P[H"````Z[.+E1S___^)%"3H +XM63T#`(D$).C]/___B00DZ`5'__^)QNNDN@0```#KBL=$)`0`````BX4<____ +XMB00DZ#CB__^)QNN#B="#^&P/A4#___^+A1#___^%P`^$500``(/Z3`^%,?__ +XM_XN]$/___XM3!(U#!+X!````A=(/A=W^__^+E1S___^)%"3HVSP#`(D$).CC +XMQ@``B[4@____A<")PW0*B00DZ.\^`P")QHD<).A5S@(`BX4<____B00DZ"?# +XM__^)-"3H?SH#`(G'Z=?]__^)-"3HD#P#`(U5B(E4)`2)!"3H'4/__X7`#X6C +XM````BU4,BQJ+,^F,_?__B70D!,<$),K'"`CH;<$``(7`#X3J_?__@\,$QX48 +XM____`0```.DR_?__B=.P3.GW_/__BP.#^"\/CJS]__^#^#QX4@____("\)".E:_?__,?;I-?[__\<$)`L``!#H^K___XM% +XM#(L8BS/IW?S__X/Z00^$=P,``(/Z30^$G`,``(MW*(N5&/___XEU\(72#X3W +XM_?__C47PB00DZ'E!__^)!"3HM3T#`,=$)`0*````B00DBF-?>B)\R7_#0``(X44____QT0D"-''"`C'1"0$!P```(E$)`R)-"3HPAD# +XM`(N%&/___X7`=`R`?>DP=`;&1>@PB?N+E1S___^)%"3HCL#__XD<).@V/`,` +XMB00DZ-XW`P")Q^DV^___BWC[__\/MT<()0#P```] +XM`"````^4P`^V\.G/^___#[='""4`\```/0!````/E,`/MO#IMOO__[X!```` +XMZ:S[__\/MT<()0#P```]`(````^4P`^V\.F3^___#[=W",'N"H/F`>F$^___ +XM#[=W",'N"8/F`>EU^___BY40____#[="""4`\```/0"@```/E,`/MO#I5OO_ +XM_XMW!.E.^___#[=W"NE%^___BY4<____B10DZ-@X`P"-58B)5"0$B00DZ&4_ +XM__^#P`$/A+@```"+$XU]B.GE^O__BX4<____B00DZ*@X`P"-E2C___^)5"0$ +XMB00DZ`(\__^#P`$/A*@```"+$XV%*/___XF%$/___^EO^___BT<0B00DZ!_! +XM``"%P(GX_?__BY4<____B10DZ->^__^+!HD$).A].@,`B00DZ"4V`P") +XMQ^E]^?__BW<8Z8W\__^+1PR)!"3H.\```(7`B<8/A+3]__^+A1S___^)!"3K +XMNHVV`````(MW(.E?_/__BX4<____B00DZ'J^__^+E2#___^)%"3HS#4#`(G' +XMZ23Y__^+E1S___^)%"3H5[[__XN%(/___XD$).BI-0,`B57B<=64X/L'(E5 +XMZ.@M"@``B47PB00DQT0D!#`J"`CH:K[__XL?N@0```"+`^CL]/__A<")Q@^$ +XMH@```(U#!(D'C4;YBUWH@_@!#X;>````B=J)^.CE"0``B47LQT0D!#`J"`B) +XM!"3H(K[__X/C`74?@_X5````C70F`'YN@_X'#X2M````@_X(B?9T?XM% +XM\(D$).A3O?__BQ^+`X7`=!3'1"0$,#L)"(D$).C'.O__AR)1"0$BT7P +XMB00DZ)UP``"%P`^4P`^V\.EB____@\L"Z1K___^+1>R)1"0$BT7PB00DZ'9P +XM``")QNE!____BT7LB40D!(M%\(D$).@9.O__A<`/E<`/MO#I(O___U6)Y8/L +XM&(E=](G#B77XB7W\B57PZ'?^__^+.XG&BP>%P'04QT0D!"@["0B)!"3HV3G_ +XM_X7`=`^)\(M=](MU^(M]_(GL7<.+5?"-1P2)`XG8Z*O___\QQNO>C;0F```` +XM`%6)Y8/L&(E=](G#B77XB7W\B57PZ(?___^+.XG&BP>%P'04QT0D!"`["0B) +XM!"3H>3G__X7`=`^)\(M=](MU^(M]_(GL7<.+5?"-1P2)`XG8Z*O___\)QNO> +XMC;0F`````%6)Y8/L&(E=](G3B77XB<:)??SHB/___XG'BP:)1?"+`(7`=!3' +XM1"0$%#L)"(D$).@7.?__AQ=PXM%\(/`!(7_B08/ +XME,`)PXGP@^,!B=KHG?___X7_#Y7"A<`/E<`/MO@AU^O%C;8`````C;\````` +XM58GE@^P8B5WTBUT,BT4(B77XB7W\B=KH9/___XG&BT4(BSB+!X7`=!3'1"0$ +XM"#L)"(D$).B3./__AQ=PXUT)@"+50B#XP$)\XU' +XM!(D"#Y7`#[;`B40D!(D4).B1____"?`/E<`/MO#KQ(VT)@````!5B>57B<=6 +XM4X/L3(E5O(L8BS.%]@^$&P(``,=$)`1`.PD(B30DZ"(X__^%P'5)@\,$B?B) +XM'XM5O.C#____QT0D!#`J"`B)PXD$).@1N___B=CH*OS__XD<)(G&Z&"Z__\Q +XMP(7V#Y3`B00DZ/$B`0"#Q$Q;7E]=P\=$)`1(.PD(B30DZ,4W__^%P'5%@\,$ +XMB?B)'XM5O.AF____QT0D!#`J"`B)QHD$).BTNO__B?#HS?O__XDT)(G#]]/H +XM`;K__XD<).B9(@$`@\1,6UY?7<.0QT0D!%`["0B)-"3H;#?__X7`=4R#PP2) +XM'XM%O(D\)(E$)`3HB/[__XG&BP>+$(72=`6#.BET#L<$)"$``!#H7;?__XL' +XMC5@$B1^)-"3H/B(!`(/$3%M>7UW#C;8`````QT0D!%@["0B)-"3H##?__X7` +XM#X4?`0``B=Z#Q@2-1>R)7<")\\9%R`''1# +XM/BT/A$L!``#V1;P"#X0L`0``B30DZ(DO`P#IT_W__XL'C5C\B1_'0/P````` +XMQT0D"`(```#'1"0$$"\)",<$)/0N"0CHZB@!`(U%X(E%Z(G#B47DQT7@^&\) +XM"(L&AW__^A@%X)"(7`=`S'!"0```!`Z/*T___'1"00`0```,=$)`P` +XM````QT0D"`````#'1"0$_____XD<).BZ`0$`C47@B00DZ`^W___HFE;__^DI +XM_O__QT0D!`(```")-"3H960``.F?_/__BT8$QP0DIL<("(E$)`3H;;4``(7` +XM=1N+1@3'!"2]QP@(B40D!.A6M0``A<`/A(/^__^+1;R)?"0$B30DB40D".BK +XM\/__Z57\__^-M@````!5B>6#["B)7?2)PXEU^(E]_(G7Z,C[__^Z`@```(E% +XM\(LSBP:)1>SHI.W__X7`=":-1@3WQP(```")`W0IBU7PB10DZ'C!`@"+1>R) +XM!"3HK2T#`(E%\(M%\(M=](MU^(M]_(GL7<.+5?#'1"0$,"H("(D4).C'MO__ +XMB?J)V.A^____QT0D!#`J"`B)QHD$).BLMO__@^+5>R+`H/X*G1G@_@O +XM=$*#^"5T'8UV`#'VBT7PB00DZ..U__^)-"3H>QX!`(E%\.N,B?#HC_?__X7` +XMB<-T2XM%\.B!]___B<+!^A_W^XG6Z\B)\.AO]___A<")PW0[BT7PZ&'W__^) +XMPL'Z'_?[B<;KJ(M%\.A.]___B<.)\.A%]___B<8/K_/KD,<$)$@```#H(K/_ +XM_XGVZZ7'!"1'````Z!*S__^)]NNUC;0F`````(V\)P````!5B>6#["B)7?2) +XMPXEU^(E]_(G7Z)C^__^Z`0```(E%\(LSBP:)1>SH5.S__X7`=1"+1?"+7?2+ +XM=?B+??R)[%W#C48$B0.+5?#'1"0$,"H("(D4).B8M?__B?J)V.B?____QT0D +XM!#`J"`B)QHD$).A]M?__@^R+`H/X*W0?@_@M=#`QVXM%\(D$).B\ +XMM/__B1PDZ%0=`0")1?#KCXM%\.AG]O__B<.)\.A>]O__C1P8Z]*+1?#H4?;_ +XM_XG#B?#H2/;__RG#Z[V-="8`58GE@^P8B5WTB77XB<:)??R)5?#H%____XG' +XMBP:+&(7;=!V+`\<$)-3'"`B)1"0$Z-NR``"%P'0'BP,[0P1T$(GXBUWTBW7X +XMBWW\B>Q=PY"#!@3'1"0$,"H("(D\).B]M/__BU7PB?#HD____\=$)`0P*@@( +XMB<:)!"3HH;3__X,[/'0HB?CHM?7__XG#B?#HK/7__XG!T_N)/"3HX+/__XD< +XM).AX'`$`BBP/HMNK__X7` +XMB<R)\.B#____QT0D!#`J"`B) +XMQHD$).C!L___]D7L`74=@_\#='F-M@````!^-H/_!`^$@P```(/_!8GV=$:+ +XM1?")!"3H\[+__XD\).B+&P$`B47PBT7PBUWTBW7XBWW\B>Q=PX/_`G75BT7P +XMZ(OT__^)PXGPZ(+T__\YPP^?P`^V^.NZBT7PZ'#T__^)PXGPZ&?T__\YPP^> +XMP`^V^.N?BT7PZ%7T__^)PXGPZ$ST__\YPP^=P`^V^.N$BT7PZ#KT__^)PXGP +XMZ#'T__\YPP^Q=PXGVN@$```#&1=W_Z]20C70F`%4QP(GE7>N(D(VT)@`` +XM``!5B>6#[`B)'"2)="0$BW4(BUT,Z%0R___'``````"+`XE%#(L&B44(BQPD +XMBW0D!(GL7>GU,O__B?:-O"<`````5;@!````B>575E.![$PA``#H*O___XU% +XM\,=$)`1`;04(B00DZ/>Q__^-A3/?__^)1"0$H;1V"@C'1"0(`"```(D$).C8 +XML0``A<")1?`/CM8-``"-E3/?__^)%"3&A`4SW___`.C'+`,`BTT(B0PDB40D +XM!.A$+O__BT4(B00DZ#DO__^+50B)1?"+7(+\@^-_@_L*#X20#0``.T4,#X2' +XM#0``,<"#^QL/E,"%P(F%V-[__P^$U0<``(M%\(/[&XM-"(T$@8F%S-[__P^$ +XM4`@``(N%S-[__\<``````(M5"#F5S-[__XF%T-[__W9"BXW,WO__B8W0WO__ +XMZQ>0C70F`(.MT-[__P2+C=#>__\Y30AS'8N5T-[__XM"_,<$)&#)"`B)1"0$ +XMZ#$R__^%P'31BX70WO__QT7L`````,=%E`````#'19@`````QT6<`````(,X +XM?@^$4P<``(N5T-[__\=$)`0O````B10DZ)PL__^+C=#>__\QTHF-W-[__X7` +XM=!2#P`2)PBN5T-[__XF%W-[__\'Z`HN-T-[__XE4)`2)#"3HF"<#`,=$)`0P +XM*@@(B87@WO__B00DZ&*P__^+A>#>__^#.'X/A$@&``")!"3H"R<#`(F%Y-[_ +XM_XN=Y-[__X7;#X1Z!@``BXWDWO__QT0D!#`J"`B)#"3H(;#__XN5Y-[__[B2 +XM'0D(BPJ%R0^%E0@``(D$).B0+___A<")A?S>__\/A!@,``#'A?C>__\````` +XMBXW__^)!"3HK*___\>%[-[__P$```#'A>C>__\`````B[7XWO__ +XMA?8/A.D$``#HT3+__X7`#X2M````BP")!"3H@RH#`(G'A?^)^8N5W-[__W4/ +XMZ9`````[`77$@\($@\$$BP*%P'7PBX7TWO__AR+ +XM`H7`#X13"P``.PL(.P2/C78`=0R#P@2#P0&+`H7`=>S'`@`` +XM```[C?3>__\/A3C___^+G>S>__^%VW0+BTV8A__^%P`^$ +XM0P<``(M%F(7`#X1H!```@[W8WO__`0^%2@<``(N%T-[__RM%"(M5#,'X`BG" +XMBX7XWO__C5K_A<`/A*,*``"+C=#>___'1"0(`@```,=$)`1(.PD(B0PDZ`5: +XM`0"+1>R+C=#>__^)7"0(B40D!(D,).B,60$`BX7@WO__B00DZ(ZM__^+79C' +XM!"0(````Z-_(``#'!"0(````Z-/(``"+C__^)#"3HH2O__X7`#X5B!@`` +XMQP0D(````.BQR```QP0D(````.BER```QP0D"````.B9R```QP0D"````.B- +XMR```Z`C'``"-C33___^#ZP&)C<#>__]T*,=$)`3$F`H(QP0D\$4)".BC%`$` +XMC94T____B97`WO__A<`/A/D)``"+10C'1"0$"0```(D$).BX+O__QX74WO__ +XM`````(7`#X3J````@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".A/K?__BY7$WO__ +XMH__^#992_B47`BT68B4PD"(-EF/V) +XM1<2+19S'1"0$`````(E%R(M%H(E%S(M%I(E%T(M%J(E%U(M%K(E%V(M%L(E% +XMW(M%M(E%X(M%N(E%Y(M%O(E%Z*',EPH(B00DZ'^L``"AS)<*",=$)`@!```` +XMQT0D!$;)"`B)!"3H$JP``(U%P(E$)`BAS)<*",=$)`0`````B00DZ$:L``#' +XM!"3$K`L(Z.JK___'A=3>__\!````BXW8WO__A__^%TG04 +XMQT0D!`````#'!"0`````Z-03`P"#!<2L"P@!QT0D!+"0"`C'!"3$K`L(Z#FL +XM__^+E<3>__^AS)<*"(E4)`2)!"3H_B?__XM%E(N-Q-[__\=$)`0`````B84T +XM____BT68B4PD"(F%./___XM%G(F%//___XM%H(-EH(")A4#___^+1:2)A43_ +XM__^+1:B)A4C___^+1:R)A4S___^+1;")A5#___^+1;2)A53___^+1;B)A5C_ +XM__^+1;R)A5S___^AS)<*"(D$).A,JP``BU4(BP*%P'12B=__^%P`^$$?G__XN5P-[__Z', +XMEPH(B50D!(D$).C-)O__BXW`WO__H%Z-[_ +XM_P````"+A?S>__^)!"3HCRW__X7`#X2[^___@\`(B00DZ)`E`P")Q^D(^___ +XMBY7HWO__A=(/CK#[__^+A?C>__^%P'2>Z,@L___'A>S>__\`````QX7HWO__ +XM`````.FK^O__C464B87$WO__BX7@WO__B00DZ(RI__^-E33___^+79B#O=C> +XM__\!B97`WO__#X6!_/__Z>#[__^+E>#>__^+G>#>__^+0@2#PP2%P`^%S@$` +XM`,=$)`3$F`H(QP0DD"\)".@]$0$`B5PD!(D$).@!(`,`B87DWO__BYWDWO__ +XMA=L/A8;Y__^-592)E<3>___I=?___XD\).AG(`,`C564B10DB40D!.A('@,` +XMZ?OY___'!"0*````Z/?$``#I&OC__\>%U-[__P$```#I"_W__\=$)`0O```` +XMB00DZ)\J__^%P`^%E?C__^C"*___BY70WO__QT0D!#`J"`C'!"0`````@\($ +XMB97__\`````QX7DWO__`````,>%^-[__P$```#'A>#> +XM__\`````Z1KY__^-M@````"#Z`2)A___IHO?__\=$)`3$F`H(QP0D($() +XM".C>#P$`A<`/A+7Y__^+`(7`#X2K^?__BPB%R8F-\-[__P^$F_G__XF%'-__ +XM_XGYBP&#P02%P'7WBY7PWO__BP*#P@2%P'7W.97PWO__#X0Y`0``.?ET+8UR +XM_(M2_#M1_(U!_(G#=1T[M?#>__\/A!D!```Y^W0-BT/\@^X$@^L$.09TXXN% +XM'-___XM`!(.%'-___P2%P(F%\-[__W6/BT68@\`!B468@^@!#X4D^?__B3PD +XMZ.L>`P")1>SIB_C__X/X+P^$*?[__XG>@\8$BP:%P'51.=X/A!;^__^)\"G8 +XMP?@"B1PDB40D!.@4'P,`B<.)!"3HRB`#`(D$).@BJ0``B1PDB___'!"22N0@(B50D!.C,_P(` +XMZ:KY__^)%"3H3R`#`.E>]___BXW\WO__B0PDZ(RI``#IJOC__X.%Z-[__P'I +XML_?__XE$)`2+193'1"0,4&T%",=$)`@$````B00DZ&@C__^+A>3>__^#O?C> +XM__\!BU68BWV4&]%-___X7`B<*)A03?__]U#\>%!-___P$```"Z`0```(N-`-__ +XM_XU$"O^)T3'2]_&)A__^-A33___^)A<#>__^+A__^%P`^.Q`$``(N- +XMR-[__XN%!-___XF](-___\>%"-___P````#!X0*#Z`&)C;S>__^)A;C>__^+ +XMG03?__^%VP^.4`$``(N-(-___S'VB[T(W___B8T8W___ZR*0BX6\WO__@\8! +XM`[W(WO__`848W___.[4$W___#X08`0``.;T`W___=M>+E1C?__^+`L<$))*Y +XM"`B)1"0$Z/_]`@"+A0S?__^Z(````(7`#X2+````BXT8W___BP&)1"0$BX4, +XMW___B00DZ+(;`P")PXD$).A8'@,`B1PDB840W___Z.JO`@"+C1#?__^-E33_ +XM__^)5"0$B0PDZ)XA__^%P'4X#[>-//___XG()0#P```]`*````^$R0```#T` +XMP```NCT```!T&#T`0```LB]T#X/A2;HJ````=06Z(````(D4).AYP```.;6X +XMWO__#XX-____BXT8W___BP&)!"3HB2+__XU8`3N=%-___P^-[O[__\<$)"`` +XM``"#PP'H/\```#N=%-___WSIZ=+^__]FQT7"4`#IW?W__\<$)`T```#H&\`` +XM`,<$)`H```#H#\```(.%"-___P&+E0C?__^#A2#?__\$.97(WO__#X5J_O__ +XMBY7@WO__B10DZ-&C___IW?;__XN5$-___XV%-/___XE$)`2)%"3HT"/__X7` +XM=1P/MX4\____NCX````E`/```#T`0```#X0C____ND````#I&?___XN%S-[_ +XM_\<$))*Y"`B)1"0$Z&3\`@#'!"0@````Z,B^``#'!"0(````Z+R^``#I*O;_ +XM_XU-\(D,).A,H___BT7P@<1,(0``6UY?7<.-392)C<3>___IEOG__XN%X-[_ +XM_XN5T-[__XE<)`B)1"0$B10DZ&1/`0#I6O7__S')QP(`````.XWTWO__#X4# +XM]/__Z<;T__^AS)<*",=$)`@!````QT0D!$3)"`B)!"3HV:(``(V--/___XF- +XMP-[__^G9]?__D)"0D)"0D)!5B>5=PXUT)@"-O"<`````58GE7<<%=&$)"``` +XM``##D%6)Y5W'!=0D"0@!````PY!5B>53@^P$H0!A"0B#^/]T$XD$)/\5\*P+ +XM",<%`&$)"/____^+'8"8"@B#^_]T,\<%@)@*"/_____K&I"-="8`Z/575E.#["R+11"+712)1"0(BT4,B5PD#(E$)`2+10B)!"3H9_[_ +XM_X,]`&$)"/^)QP^$V````#G##X30````B47LB00DZ&$D__^+#?Q@"0B%R8G" +XMC4`!B47H#X2Y````H?Q@"0B-=>2-7?")1?"0BT7HA<`/A(H```"A^&`)"`,% +XM_&`)""M%\(ET)!")7"0,B47DC47HB40D"(U%[(E$)`2A`&$)"(D$)/\5[*P+ +XM"(/``76[Z*(@__^#.`>-=@!U3J'X8`D(`<")1"0$H?Q@"0B)!"3H%JP"`(7` +XMB<)T,(M%\"L%_&`)"-$E^&`)"`'0B47PBT7HB17\8`D(A<`/A7;___^+/?Q@ +XM"0B0C70F`(/$+(GX6UY?7<.-0B&C^&`)"(D$).AVJP(`A<"C_&`)"`^%*O__ +XM_^O7C;0F`````%6)Y5=64X/L+,=$)`1P?`4(QP74)`D(`````,<$)-0D"0CH +XMZ9___Z$@)`D(QT7H`0```(E%\,'@!(VXX-(("('_X-(("'8DN^#2"`@Q]HL# +XMB00DZ!0C__\YQG,"B<:#PQ`Y^W+I@\8!B77HH>"7"@@QTL=%Y`$```#'1>P` +XM````@\`!]W7HA1T +XM6Z$@)`D(P>`$!>#2"`@[1=QVYHM%W(L8B1PDZ'4B__^)7"0$QP0D^]X("(G& +XMZ%?W`@`Y?>Q^&3MUZ',4QP0D(````(/&`>A>N@``.W7H=>R#1=P0@\`Y1=1^%HL]8&0)"(7_=5;'!"0*````Z"^Z``"#1>`!BT78.47@#X5? +XM____BQU@9`D(A=MT#,<$)`T```#H";H``,<$)`H```#H_;D``,<$)-0D"0CH +XMX9W__X/$+%M>7UWIM;<``,<$)`T```#HV;D``.NAV"@B)1=BAS)<*"(E%[*$$=@H(B47PZ.ZC``#'1"0(`0`` +XM`,=$)`0"````B477UW#B1PDB40D!.BR1P``A<") +XMPW0AQT0D!/`C!@B)WXD<).CZF___B1PDZ/*@``")QNDI_O__QP0D,0```.CO +XMF/__Z]&-M@````"-O"<`````58GE4X/L%(M="(L#HTAW"@B+0P3'!?R8"@@` +XM````HTB:"PB+0PBCZ'8*"*&T=@H(B00DZ`B>``"AS)<*"(D$).C[G0``H01V +XM"@B)!"3H[IT``(M#&(E$)`2+0PR)!"3H+*(``,=$)`@!````QT0D!`(```") +XM!"2CM'8*".C;%___BT,6#[`BAP'8*"(7`=3&AE'<*"(7` +XM=`C)PXVV`````,=$)`0!````QP0D`0```.BX&___QP7,K`L(`0```,G#QP0D +XM+@``$.A4E___Z\&)]E6)Y593@^PPH329"PB%P`^%50$``(UUX.@3-___B70D +XM",=$)`0`````QP0D$@```.CW&O__QT0D!`````#'!"02````Z%,;___'1"0$ +XM$@```,<$)`````#H/Q;__\=$)`@`````B70D!,<$)!(```#HMQK__X,]U)<* +XM"/]U:>G4````.QWP=@H(#X2>````B70D",=$)`0`````QP0D%0```.B%&O__ +XMQT0D!`````#'!"05````Z.$:___'1"0$%0```,<$)`````#HS17__\=$)`@` +XM````B70D!,<$)!4```#H11K__\<$)`\```#H&1G__X/X_XG#=8GH31G__XL` +XMB00DZ/,6___'1"0$ILD(",<$)#8```")1"0(Z"^6__\['?!V"@@/A6+___^A +XMW)D+",<$)`````")1"0$Z%H7__^AW)D+",<$)`\```")1"0$Z!45___'!"0/ +XM````Z*VT`@"#Q#!;7EW#QP0D2@```.C:E?__Z9K^__^0C70F`%6)Y5>)QU93 +XM@^P,BQ7@(@D(A=)X4+O@(@D(,?:-="8`BT,$B00DZ*43`P")/"2)1"0$Z*F7 +XM``"%P'02A?9T#,<$)"<``!#HA97__XG>BT,0@\,0A +XM7UW#QP0D%@``$#'VZ%V5___KYHUT)@"-O"<`````58GE@^Q(B7W\B<>-1>2) +XM7?2+70B)=?B+=0R)5=2)1"0$BP>)!"3HD1K__XM%U(7`=#Z+5>B)=?"+1>0[ +XM5?")7>Q]3HU5Y(E4)`2+!XD$).@X'/__,=*%P'A?BUWTB="+=?B+??R)[%W# +XMC;0F`````(GRB=B!\O___W_WT`G"="*)=>B+5>@[5?")7>2+1>1\LG\%.T7L +XM=JN)1>R)5?")]NNAH2R9"PB%P'35BT7LBU7PB47DB57HZXKHCA?__XGR@?+_ +XM__]_BP")1=R)V/?0"<(/A-\```"A@)@*",=$)`S4O@@(QT0D"`,```#'1"0$ +XM#P```(D$).CT]?__B00DZ%R?``#'1"0$,"H("(E%X(D$).@IE___BTW4N$7) +XM"`B%R0^%N0```(D$).@QGP``QT0D!#`J"`B)QHD$).C_EO__BT7")7"04B70D$(E\)`B)5"0,BU78B00DB50D!.CO[@(`BT7@ +XMB00DZ/25__^Z_____^FD_O__H8"8"@C'1"0,L,D(",=$)`@"````QT0D!`\` +XM``")!"3H%?7__^D<____H8"8"@C'1"0,M\D(",=$)`@$````QT0D!`\```") +XM!"3HZ_3__^D=____C;8`````58GE5S'_5E.#[`R+=0C'1?``````@\8$BQZ% +XMVW0T@SLM#X6*````@\,$BP.%P'3E@_AF#X3&````@_AH#X2S````QP0D@@`` +XM`.CRDO__B?;KU:'@(@D(,?:[X"()"(7`>$>)V(GZQP0D_____\=$)`3___]_ +XMZ';]__\]````@(/>_X/#$(L#A%]G03QT4(````((/$#%M> +XM7UWIEY+__X/$#%M>7UW#B=B)\^L*BT,$@\,$A=>+1?"%P'70QP0D````(.A-DO__Z\*_`0```.DH +XM____QT7P`0```.D<____D(UT)@!5B>56B<93@^P0H:`C"0B%P'0K,=OK#HL$ +XMG:0C"0B#PP&%P'09B40D!(DT).C;$?__A+`XE%\`^^$(L!*=!UVHM%\(D$).AI#P,`BTT(B0PD +XMB40D!.@V$?__AZ[F-M@````"-OP````!5B>6#[#B)7?2) +XMTXEU^(G&B7W\BW@(BT`$QP0DOB+5>R)1=B)5=R+5=R+1=B!\O___W_WT`G"#X2,```` +XMBPZ%R71WBT8,BU7PC' +XM1=0!````A?8/A6;____'1=P!````BS7@(@D(N^`B"0B%]G@3BU77UW#QP0D&```$.@IC___V478V`4@S@@(V04XS@@( +XMV=C[=V,=%R/_____'17UWIT8[__]E]Z@^W1>JT#&:)1>C9;>C? +XM?KKNHM5U(GP@\0\6UY?7>EH_?__VT8(V$W8V7WJ#[=%ZM@%(,X("+0, +XM9HE%Z-EMZ-]]R-EMZNN%BSZ%_P^$1?___[K^R0@(B=CH_O+__]E%V-@--,X( +XM"-E=V.DT____BP:%P`^%'O___[K7R0@(B=CHU_+__]E%V-@-*,X("-E=V.D- +XM____BP:%P`^$]_[__[KWR0@(B=CHL/+__]E%V-@-,,X("-E=V.GF_O__BP:% +XMP`^%Q````+K=R0@(B=CHB?+__]E%V-@-),X("-E=V.F__O__BP:%P`^%J?[_ +XM_]GNV478VNG?X,=%R`````#'1K>P;0,9HE%Z-EMZ-]]R-EMZNF&_O__ +XMBP:%P`^%1O[__[KOR0@(B=CH__'__^E!_O__NL;)"`B)V.CN\?__QT7(____ +XM_\=%S/___W_I3/[__XL&A<`/A`S^___'`VT```"ZYE7$/__A,EUX('[_P$``'_8B54(@\0$6UWI/A#__\<$)`````#H +XM,A#__P^WV(D<).@G$/__B5T,QT4(!575E.#[!R+10B) +XM1>RAT)<*"(E%\(L(AQT">L6@\($.P%U +XM#XM"!(/!!(7`=>^#.3UT%HM+!(/#!(7)=`2)S^O/@\0<6UY?7<.-0P3'`P`` +XM``")1"0$H="7"@B)!"3HAI,``*/0EPH(H=AU"0B)!"3H!)(``*'0EPH(B00D +XMZ,<'`P"CV'4)"(D[B3PDZ)B8`@"+1?")10B#Q!Q;7E]=Z8:8`@"-M@````!5 +XMB>575E.#[!RAT)<*"(E%X(L(A564X/L((M%"(M`!(7`=%:)!"3H=C@! +XM`(7`B<8/A+P```"A<&$)"(U=],<%<&$)"`$```")1?2)'"3'1"0$T#@&".AG +XMC/__B70D!,<$)!$7"0CHI^0"`(D<).BOB___@\0@6UY=P\<%=&$)"`$```#' +XM1"0$8'P%",<$)'1A"0CH*HS__XL=T)<*"(L#A)UU93@^Q,QT0D!,28"@B)1BQB%VW08QT0D!*PZ"0B)'"3H2@C__X7` +XM#X5[`@``QT70`0```(M7!#';N`$```"-=P2%T@^$LP```*&4=PH(A<`/A=@` +XM``")-"3HE3<``(G'A?]T$,=$)`3P(P8(B3PDZ`^+___V1=`!=`J#?<@@#X2_ +XM`0``BS>)^L=%S`````"+1=")5=31Z(A%N(7V=%2AE'<*"(7`=!GIU@$``(VT +XM)@`````-````0(D$).CCIP``BP:%P`^$3@$``(/&!(/X7'7A@'VX`'3;BQZ# +XMQ@2#^W9V<<<$)%P``$#H!:8``(G8Z\&+32)'"3H +XM&OL"`(DT).BR-@``B1PDB)^X7V#X2X_O__QT0D!,`["0B)-"3H$`;__XGZQT7,`````(7`#X4?_O__ +XMBW<$C5<$QT7,`0```.D-_O__C5WDB1PDZ,;Y`@")'"3H3HC__^DF_O__B=`- +XM````0(GVZ1#^___'1"0$O#H)"(D<).BW!?__QT70`@```(7`#X1M_?__QT0D +XM!-`Z"0B)'"3HF`7__\=%T`,```"%P`^$3OW__\=$)`3D.@D(B1PDZ'D%__^% +XMP`^5P`^VP(E%T.DN_?__C;8`````C;PG`````%4QP(GE@^P(BU4(Z,#\___) +XMZ9JA``"-=@"-O"<`````5;@@````B>6+50A=Z9_\___K#9"0D)"0D)"0D)"0 +XMD)!5B>575E.#["R-1>")!"3HK%,``*'@F0L(A"9 +XM"PAT+HG8BU`0BU@LA=)TY3L0=>$[5>!UW(/Z`G0QT!\=` +XM!`````#'!"0!````,?8Q_^C96```B<.-M"8`````@_L@#X2W````@_L)#X2N +XM````@_LC#X2X````@_O_B?8/A`D!``"#^PH/A`0"``")'"3HR4\``,=%\`$` +XM``")]L<$)`$```#HA%@``(/X7(G##X3^````@_LG#X3`````@_LB#X2W```` +XM@_O_C70F``^$N0```(/[*`^4P(G&BT7LAR)!"3HK/D"`(M% +XM\`GX=5J)\(3`=%2+3>R%R0^%OP$``(/[(+X!````#X5/____C;8`````QP0D +XM`0```.@$6```B7UW#,<`YWP^4 +XMP(/H`2''Z13____'!"0!````Z&]7``"#^`J)PP^%Z_[__[,@,?;I"?___Z$$ +XM80D(_R2%C,T(",=$)`0)R@@(,?;'!"04```0Z-F"__^#Q!R)\%M>7UW#H0AA +XM"0@Q]HD$).B0_@(`QT0D!!K*"`C'!"04```0HR!W"@CHIX+__X/$'(GP6UY? +XM7"__^#Q!R)\%M>7UW#QT0D!.(&"0@Q]L<$)!0``!#H1X+__X/$ +XM'(GP6UY?7<.+1>R%P`^$^O[__\<$)`H```#HMDT``(7V#X3H_O__BT7L@V@$ +XM`8D$).@_^`(`@\0) +XMQU:)UE.#[#R#_PJ)3@`````QT7L`````,=%\`````"C!&$)"(D-"&$) +XM"`^$Y@,``(U=Z,=$)`2PD0@(B1PDZ)2$___'1=``````H9B)'"3H?8/__X/$/%M>7UW#D(UT)@#_)(7,S0@(B=CH@0_/__ +XMA?8/B0O____I;O___X/_"W3D@_\$=-\QP.CR^___A?8/B>W^___I4/___Y"- +XM="8`@_\!#X1'`@``@_\!@]X`,<"#;=`!Z,;[__^%]@^)P?[__^DD____A?:- +XMM"8`````#X4*____@_\+C;0F``````^$!?___S'`Z)/[__^%]I`/B8W^___I +XM\/[__Y"-="8`@_\/#X77_O__A?:0C70F``^%RO[__S'`Z&/[__^-=@#IQO[_ +XM_X/_#P^%LO[__X7V#X6J_O__B=CH0_O__XM%[(7`#X7@`0``BU7HB10DZ*U] +XM__^)!"3H=8$``,=$)`0P*@@(B47,B00DZ**"__^+1B#?(+\.@^%,OW__X/H`8/_"HE%[,<$ +XM@@`````/A+````"#_P\/A1/]__^+1>C'1"0$H#L)"(D$).@<_O[_A<`/A?C\ +XM___I*?[__XUV`(M%T(7`#X6T_?__BQ7@F0L(A=(/A*;]__^+0BRCX)D+"(G0 +XMZ/CQ___IDOW__XL5Q",)".D/____BU7H@WR"_#H/A17^__^#Z`&)1>S'!((` +XM````Z0#^__^+`.DI____C478QT78`@```,=%W`````#'1>``````B00DZ&%- +XM``#I]?O__XM%R(E$)`2+1>B)!"3H=OW^_X7`#X52_/__Z8/]__^-M@````"- +XMO"<`````58GE@^P(BQ7@F0L(@WH0`G01C4(0B00DZ!--``#)Z1WX__^+0A0+ +XM0AAUYS'),=(QP.A:^___H>"9"PB#P!")!"3HNDL``*'@F0L(@T`4_X-0&/_) +XMZ>?W__^-M"8`````58GE@^P(H>"9"PB%P'07H2AW"@B%P'0(R<.-M@````#) +XMZ7K____'!"0O```0C78`Z.M\___KV(GVC;PG`````(L5*'<*"%6)Y872=`-= +XMPY!=,"9"PC'0!``````H91W"@B%P'4U +XM, +XM?O__H2AW"@B%P'4.B=DQTK@/````Z.?Y__^)70B#Q!!;7EWI&7[__XU3!+[X +XM;PD(ZYWK#9"0D)"0D)"0D)"0D)!5B>564X/L$(L=X)D+"(MU",<%Q",)"`H` +XM``"%VW44ZSV-0Q")!"3H-$L``(M;+(7;="N#>Q`"=>B+0Q0+0QAUX#'),=(Q +XMP.AT^?__C4,0B00DZ-E)``"+6RR%VW75B?$QTK@*````Z%3Y__^#Q!!;7EWI +XM^?7__XGVC;PG`````%6)Y5.#[!3'1"0$`````(M%"(M`!(D$).C3*@``QT0D +XM!#`J"`B)PXD$).CQ??__H2AW"@B%P'4(B1PDZ$#___^)70B#Q!1;7>DS??__ +XMC78`H2AW"@A5B>6%P'0$7<.)]ETQR3'2N`0```#IT?C__Y!5B>6#[!B+%>"9 +XM"PB+0BB%P'1CBT(@@W@$`(U(!'1!BP")2B")!"3H1/0"`(D$).AL?```QT0D +XM"`(```")1"0$H>"9"PB+0"B)!"3H<.T``*'@F0L(B00DZ!-*``#)PY#'1"0$ +XM`````,<$)`````#H+/W__\G#B10DZ/))``#)D,/K#9"0D)"0D)"0D)"0D)!5 +XMB>6#[`B+#>"9"PB%R706BQ4H=PH(A=)T!LG#C70F`,GI2O___\<$)"\``!"- +XM=@#H^WG__^O9B?:-O"<`````58GE@^P(H>"9"PB%P'0GH>"9"PB#P!")!"3H +XM44@``*$H=PH(AGZ_O__QP0D+P``$(UV`.BK>?__Z\B) +XM]HV\)P````!5B>564X/L$(L=X)D+"(7;=`Z+`SL%[)@*"`^$@@```#';BQ4H +XM=PH(,?:#10@$A=)U'J'`=@H(A7 +XM7<.%VW6VC44(QT0D!`$```")!"3H&,#__X7`#Y3`#[;PZZZ+4PB+#?28"@B+ +XM0P0S!?"8"@@QT0G!#X5B____BT,,.P7XF`H(#X53____BTLHA"9"PB) +XM4"RCX)D+"*'`=@H(QP7$(PD($@```(7`#X09____Z(K[___HA?W__Y"-="8` +XMZ0G____'!"0A```0C70F`.@K>/__Z>S^__^-M@````!5B>6#[`BAC'8*"(7` +XM=0FAE'<*"(7`=1FA-)D+"(7`=`+)P\<$)$8```#H\7?__\G#QP0D`````.BS +XMFP``H329"PB%P'7;Z]N0C;0F`````%6)Y8/L&*&,=@H(A575KX!````4X/L#(M="(M%#(U[!(E%\(VV`````(L'B00D +XMZ`;?``#'1"0$`@```(D<)`^O\.CS?```BP.%P'04QT0D!&A-"0B)!"3H6?;^ +XM_X7`=,FA*'<*"(7`=`6^`0```*&4=PH(AQP0DQ*P+".B`>/__@\0,6UY?7>G$>P`` +XMQP0DQ*P+".AH>/__@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".CM>/__ZZ^#!<2L +XM"P@!QT0D!+"0"`C'!"3$K`L(Z-!X___I>?___XUT)@"-O"<`````58GE5KX! +XM````4X/L$*$H=PH(@T4(!(7`#X29````BUT(BP.%P`^$G@```,=$)`0@2`D( +XMB00DZ''U_O^%P'4QBT,$A7<.)]H7V=/.+50R+0A`IP\'[`HE<)`2)!"3HI7L``(M% +XM#(D$).@:_O__Z-5Z``"#Q!!;7EW#,53@^P4 +XMBT4(B00DZ&[Q`@#'1"0$\",&"(G#B00DZ+QW___HI_S__\=$)`3$F`H(QP0D +XM8#8)".BCW@``QP0D`````(7`#Y7`#[;`B40D!.@;,```QT0D"`````#'1"0$ +XM5'<*",<$)`\```#H6_C^_XE<)`3'!"0DR@@(Z*OX_O^)7"0$QP0D(,H(".B; +XM^/[_B1PDZ*=V___H,A3__\=%"`$```"#Q!1;7>EQ%/__D%6)Y8/L".@5_/__ +XMQT4,`````,=%"`````#)Z4$6__^058GE@^P(QT0D!)1V"@B+10B)!"3H=^`` +XM`,GI<1@!`)!5B>6#[`C'1"0$_____\<$),28"@CH9ML``,G#C70F`%6)Y593 +XM@^P0BT4(BW`$A?8/A-,```"+4`B-6`B%T@^$@@```,=$)`2@-PD(B30DZ(CS +XM_O^%P'58B30DZ'#O`@#'!"00```0HR!W"@CHCW/__XD<).@W?P``B30DB7>E7 +XMD0``QT4,_____\=%")1V"@B#Q!!;7EWI7MH``(/$$%M>7<.-M"8`````58GE +XM5U93@^PLBUT(BWL$@S\M=`S'!"1Z```0Z+!R__^-0PB)!"3H!2(``,=$)`3P +XM(P8(B47@B00DZ()U__^+=>")=?"+#H7)=%^-1?"#Q@3'1"0(`````(E$)`2) +XM/"3HO*[__\=$)`0P*@@(B<.)!"3H2G7__XE<)`3'!"22N0@(Z(K-`@")'"3H +XMDG3__XL>A=MTK<<$)!W<"`CH<,T"`(EU\(L.AE+Y0(`H91W +XM"@B%P'4DQT0D!`````#'!"0"````Z&KU_O_'!5!W"@@`````@\046UW#QT0D +XM!,"/"`C'!"0"````Z`KE`@#KVI"-M"8`````58GE@^P8B77XBW4(B5WTB7W\ +XMBWT,BT80B00DZ'"0__^+!Z,@=PH(BT80B00DZ,YQ``"-6/\[7PA\*SM?#'X, +XMQP0D#P``$.BEQ=_^''!"0.```0 +XMZ']P___KQXVV`````(V\)P````!5B>575E.#[`R+70B+0Q"+`(E%\(G"BP"I +XM````0`^%BP```(/X.G09B10DZ*!Q``"#^#H/A*(```"+5?"#.B5T>:$@)`D( +XMP>`$C;#@T@@(@?[@T@@(=E>_X-((".L-B?:%P'A$C7L0.?YV0XGP*?C!^`7! +XMX`2-'#B+1?"+"P^^$`^^`2G"B=!UUXD,).C?[0(`BU7PB10DB40D!.B@'0$` +XMA;R)WCG^=[TQVX/$#(G86UY?7<.+0P2H`70Q@^#^B4,$N\@C"0B) +XM%"3H;.L"`*/((PD(Z]6+1?"[Z",)"(D$).A5ZP(`H^@C"0CKOHM%\+O8(PD( +XMB00DZ#[K`@"CV",)".NGC;0F`````%6)Y5=6,?93@^P,BT4(B47PH="7"@B+ +XM&(7;#X24`@``BQ.%T@^$N0```#')@_H]#X2N````@\$!BQ2+A=(/A?X````Y +XMSGT"BV!^_\```!VVHD<))"-="8`Z&?M_O^I +XM```$`'31@SV`40D(`<<%0&0)"``````/E,(QP('[_P````^?P"'0HV"9"PCH +XM6?D!`*$\9`D(A<`/A$?^__^A0&0)"(7`#X4Z_O__Z$K)`0#I,/[__\=$)`2@ +XM3`D(B3PDZ-'L_O^%P'4-B1PDZ`EO`0#I#_[__\=$)`3@-`D(B3PDZ+#L_O^% +XMP`^%]_W__^B'S/__Z&+-__^)]NGF_?__B7T(@\0,6UY?7>G\;O__N`0```#I +XMG/W__XGV58GE5U93@^P,BT4(BW`$C7@$A?8/A)4"``"+!H7`="F)\^L*BT,$ +XM@\,$A)!"3H&F___XE\)`2)-"3H#N'_ +XM_\=$)`2(.PD(B30DZ.KK_O^%P`^$^````(GPZ,_9__^%P`^$%`$``,=$)`1% +XMR0@(NX````#'!"0`````Z+KQ_O_'1"0$1!="0CK'HM$GC2I```$`'4L@\,!@?O_````?R'WPP```$!U[8'[ +XM_P```';:B1PDB?;H9^O^_ZD```0`=-2#/8!1"0@!QP5`9`D(``````^4PC'` +XM@?O_````#Y_`(="C8)D+".A9]P$`BQT\9`D(A=MT+8L-0&0)"(7)=2/H4,7UWI,VW_ +XM_\=$)`3@-`D(B30DZ*_J_O^%P`^$O````,=$)`3`2PD(B30DZ)?J_O^%P'1V +XMQT0D!"A`"0B)-"3H@^K^_X7`#X7!````B3PDZ'=L``#'1"0(`@```,<$)-`O +XM"0B)1"0$Z'_=``")/"3H%VW__XD\).B_;/__B3PDZ#?F`@"+%8AW"@B%THG# +XM#X4\`0``QP5@90D(`````(/$#%M>7UWIR`$`B7T(@\0,6UY?7>E?;/__Z,K)___HI7UWI'N#__\=$)`0\0`D( +XMB30DZ*KI_O^%P'1%QT0D!!A*"0B)-"3HENG^_X7`#X7I````B3PDZ(IK``#' +XM1"0(`@```,<$)`!*"0B)1"0$Z)+<``")/"3H*FS__^F3_O__B7PD!(D\).AY +XM+O__B3PDB +XM7UWI*S?__[@(````OQZR"`C\B=Z)P?.F#X2M_O__N`4```"_,;(("(G>B<'S +XMI@^$E_[__\<$)(`Q"0C'!>29"P@!````QP6(=PH(`````.ANW```Z7+^___' +XM1"0$H#\)"(DT).B5Z/[_AY_[_A7UWI +XMT_0!`,=$)`0`3`D(B30DZ*_G_O^%P'31QT0D!"!,"0B)-"3HF^?^_X7`=+W' +XM1"0$Y$L)"(DT).B'Y_[_A!="0B+1)`T]L0!=1.#^U]T&L<$ +XM)!T``!#H*6?__XL>A=MT4_?#````0'4_BSW@70D(ZR.-=@"+1(!(7;="N#Q@3WPP```$!U%`^VPSW_````=M:)!"3HZN;^_^O0QP0D +XM'P``$.C09O__BT7PB<.+.(M`!(/#!(,X*`^$TP```,<$)!,``!#HKF;__X/# +XM!(D<).AS`0``A<`/A(````")1"0$B1PDZ!\5``"%P(G\````QT0D!#`` +XM``#'!"0!````Z$%T`@")<"2)PXEP((D$).CA-```B3PDZ`G@`@")0RBAX)D+ +XM",=#$`(```")0RR+/"9"PC'!<0C"0@)````A?]U/XLU*'<*"(7V +XM="F#Q`Q;7E]=PXD<).C#<0``B<:)!"3HJ0```.N"B10DZ`OF_O_IN_[__X/$ +XM#%M>7UWI+NO__^@IZ?__Z[J)'"2-="8`Z.MF``"+1(/\@S@I#X44____Z1O_ +XM__^A*'<*"(7`#X4W____QP0D,0``$.BP9?__Z2;___^0D)"0D)"0D)"0D%6) +XMY593@^P0BUT(ZPF-=@"+$(72=1"+`X/#!(7`=?&#Q!!;7EW#B<:)%"3_50R+ +XM5@2#Q@2%TG3>Z^Z-M@````!5B>6+30B+$8/!!(72=!*+`H7`=/$E____/XD" +XM@\($Z^Y=PXVV`````(V\)P````!5B>575E.#[`BAV)<*",=%\`````")1>R+ +XM50B+`H7`#X3I````@T4(!(L0@_I^#X1^````@_H]='F#^GL/A*````"%TG32 +XMBU@$C4@$ZS:)]H/Z>W0YA=)X._?"````0)!U,H/Z?W\M#[;"]H0`X"`)""!T +XM((--\`&#P02%VW29B=J+7@2#^F")SHUY_'7"@TWP`NOD@WWL`W7>A=N-="8` +XM#X1R____@_HN=`V#P02)]NO-@TWP`NN*@_LND(UT)@!UZ8M!!(7`=`6#^"]U +XMW8M5"#EZ_'0&@WGX+W7/@TWP`NO)BU@$A=L/A"O___^#^WT/A5/___^+2`B% +XMR0^%2/___XM5"(L"A<`/A1?___^+1?"#Q`A;7E]=PXVT)@````!5B>575E.# +XM[%R%THE%N(E5M(E-L(L`B47`#X2[`P``BQ*)5;R+1<"+`(7`B47$#X2``0`` +XMBWW`BU7$@SI[=12+0@2%P`^$6@$``(/X?0^$%P(``(M-Q,=$)`1[````B0PD +XMZ-;G_O^%P`^$-@$``(M%Q,=%Z`````#'1>P`````QT7P`````,=%W`````#' +XM1>``````QT7D`````,=%T`````"#.'MT$X/`!(,X>W7XB<,K7<3!^P*)7="- +XM<`2+0`2%P`^$%`$``(GSQT7,`````.L@@_A[#X3O````@_A]D`^$!P$``(/# +XM!(L#A<`/A.D```"#^%MUVX/#!(L#@_A=#X3M`@``A7^__\IPHG0P?@"@_AD`"B4VP +XMB40D!(D<).AQ<`(`BTVXB47`B0&+5<")^"G8@^#\C3P0BT6\*=B#X/P!T(E% +XMO.D!____BP:)!X/O!(DT).@;;P(`Z3K___^+0@B%P`^$+____^G9_?__BTW0 +XMC57HBT7$B10DB4PD"(E$)`3H/=D"`(U-W#G>B4VL#X>\````C47R)\"G(P?@"B40D".BWV`(`BTVHC47HB00DB4PD!.@EV0(`C57HB10D +XMZ`K7`@"+1>B)!"3H?]H"`(U-W(D,)(E$)`3H8-@"`(U.!(G..?,/@V3___^+ +XM7:R)'"3H&-@"`(G&BT7HB00DZ`MN`@"+1>"%P(E%R`^)I?W___?8Z8[]__^- +XMM@````"#1"L"PB+=?R)`Z'DK`L(B4,$H>BL"PB)0PB+ +XM7?B)[%W#C70F`(V\)P````!5B>575HG.4X'LK*```(F%<%___XM%"(F5;%__ +XM_X7`=1#'A7Q?__\`````]D$#0'0*QX5\7___````0(U%Y(U=[(E%W,9%S`'' +XM1=``0```QT74`````,=%V`````#'1>``````QT7D0#P)",=%Z`````#HR8$` +XM`(U%S(D$),=$)`1@/P8(Z"9B__^)'"3H3JH``(D<)(U=\,=$)`1`'@4(Z`MB +XM___'1"0$0!X%"(D<).C[8?__C57,QT0D!/____^)%"3H.)P``(7`#X4O`P`` +XMBT7LB00DZ$5D``"+1?#'1"0$`0```(D$).B":```H01V"@C'1"0$`@```(D$ +XM).AM:```Z!CG_O_HPV@``(DUD'8*"(L&A!.L.@_@-=#&+`X/#!(7` +XM=#$E____/XE#_,=$)`3$F`H(QP0DX#$)".AHR```A"0B%P'02B00DZ/]J`@#'!8!>"0@` +XM````QP0D>'8*".@96```QT0D!)#I!0C'!"1X=@H(Z%5@__^A@%X)"(7`=`S' +XM!"0```!`Z%!=___'!"1X=@H(Z/1X``"A@'8*",=$)`@`````QT0D!'AV"@B) +XM!"3H9W4``,=$)`1`*P8(B<.)!"3H!6#__Z&`7@D(A___'!"0`F@L(Z(#=_O^AP)@*",<%<'8* +XM"`````"%P`^$S?[__XN%@%___\<%_)@*"`````")!"3H55[__XN5O%___XN% +XMN%___XD5+)H+"(N5M%___Z,HF@L(BX6P7___B14DF@L(BY6L7___HR":"PB+ +XMA:A?__^)%1R:"PB+E:1?__^C&)H+"(N%H%___XD5%)H+"(N5G%___Z,0F@L( +XMBX687___B14,F@L(BY647___HPB:"PB+A9!?__^)%02:"PBC`)H+".BF6___ +XMZ2'^__^)'"2-G%A%___P````")G61?__^)E6A?__^%]@^$G````(N->%___X7)=4"+%X'B +XM____/XF5=%___P^%K0$``(U%[(D$).BA7?__Z`RB``"-17UW#C;8`````BX5T7___AB5PD!"G8B40D"(M%[(D$).BQ70``QX6,7___```` +XM`(7`#XY9`0``C3PP.;UD7___#X-V`0``C9W,W___B;W`7___QX6(7___```` +XM`.L-`<.#A8A?__\!.?MS0(NUP%___XN5B%___XE<)`0IWHV$E%B%___P````#I_O[__XUV`%6)Y5=64X/L+(MU"(U%W(D$),=%Z`````#' +XM1>P`````QT7P`````,=%W`````#'1>``````QT7D`````,=$)`3PD0@(Z+=; +XM__^-1>B)!"3'1"0$L)$(".BD6___BP:%P`^%F````(GS,<")1"0(C47HB70D +XM!(D$).A3T`(`BPN%R0^$X@```(M#!(U[!(7`#X67````B?XQTH7`=1O'1"0$ +XM8````,<$)#,```#H7UC__XGR*?K!^@*)5"0$@\8$B3PDZ%G2`@#'1"0$,"H( +XM"(G#B00DZ"=;__^+10R)V8U5Z(D$)(U%W.AD^/__B1PDZ&Q:__^+!H7`#X1H +XM____@_A@B?,/A%W___^-M"8`````@\,$BP.%P'4,B=@I\,'X`NE%____@_A@ +XM=>;K[8/X8(G^#X1>____@_A<=!^#Q@2+!H7`=0R)\BGZP?H"Z4C___^#^&!T +XM[X/X7'7A@\8$BQ:%TG78Z33___^+1>R%P'0+C57HC47- +XM153@^P4 +XMBTT(BT$$@_@M='FI````0'5J@_A_=V7V!(6]40D(!'1;BU$(@^@PC5D(]\(` +XM``!`="7K*)"-="8`]@25O5$)"`1T&8/#!(T$@(U$0M"+$_?"````0'4%@_I_ +XM=MV%TG5YB00DZ-$4__\QR87`=`Z)7"0$B00DZ)_.`@")P8/$%(G(6UW#BU$( +XMC5D(A=)U6,=$)`3$F`H(QP0D=#,)".BGOP``A<")PG1)BP"%P'1#BPUDF0L( +XMBP&+0`R%P'4TBT$$BT@,A*)/"3HLF$"`,<#`````(M-X(MQ +XM!(/!!(E-X(7V=9*+1,"B5PD!(D4)(E-U.@E8@(`BU70C9P#`2#P`2)1=R%_W0ZBP>#^#UUX(D\).@[_?__A<")PP^$:P$``#G'=-.)/"3H +XME6`"`(M-W(D9BT7OHQT0D!,28"@C'!"0`/`D(Z.B[``"%P'0*B30DZ#Q4 +XM___KGXL&A%]G4&]D7P`74ZB1PDZ*[K__^) +XMV(MU^(M=](M]_(GL7<.)V(GRZ`;\__^)PXG'Z]")70B+=?B+7?2+??R)[%WI +XMC%P``(D<),=$)`3P(P8(Z+Q3__^)V.AE^?__.<>)PW0*B3PDZ`=3___KIXD$ +XM).A-4___Z^R-="8`C;PG`````%6)Y5.#[!2+70B)'"3H7NO__X7`=!J)'"2) +XM1"0$Z`[___^%P(G#="*)V(/$%%M=PXD<).@87```B<.)!"3H_NK__XG8@\04 +XM6UW#QP0D,0``$.A*4/__Z]"0C;0F`````%6)Y5=64X/L+,=$)`3$F`H(C7WL +XMQP0DU#L)".@0N@``QT7P`````(G#BT4(B47LB3PDZ-GJ__^%P(GS```` +XMA=L/E<#WQ@(````/MMAU+H7;=0F#Y@$/A>P```"+10B)!"3HA\D"`(D$).A_ +XM40``B44(BT4(@\0L6UY?7<.)^(G:Z,CZ__^%VXG'#X2#````B7W8BU78BP*% +XMP`^$I0$``(M5V(MR!(7V#X2S`0``@WT,`0^$:@$``(-]#`(/A+P```"+30R% +XMR76IBT4(B00DZ#K+`@"+5=B)%"2C('<*".@:5@``QP0D)P``$.A.3___ZX"+ +XM50B)%"3H\<@"`(D$).CI4```B44(BT4(@\0L6UY?7<.#Y@$/A'3___^)!"3' +XM1"0$\",&".@"4O__B?CHJ_?__SG'B478#X1#`0``B3PDZ$A1___K"HGXZ(_W +XM__^)1=B+7=B%VP^%-O___XM5"(D4).BFR@(`QP0D,0``$*,@=PH(Z,5.___I +XM%?___XM5V(E5W(D$).@^S_[_BUW8@\,$C7@!ZP.+=>"+0P2#PP2)1>")-"3H +XM'\_^_XM5X(72C7P'`77AC02]`````(D$).BY7`(`B44(BT78BTT(BQ"%T@^$ +XMI````(L"A+___\_B57DBQ>#QP2!XO___S^#^C\/A/$```!_'(72=6.+11")&(-]Y`$9 +XMP/?0@\`"@\0L6UY?7<.#^EL/A-H```"+=12%]G5B@?K_````#X?"`0``H>!= +XM"0B+G)`T!```@7WD_P````^'F0$``*'@70D(BU7DBX20-`0``#G##Y7`ZRV# +XM^BIUN8L',?:%P'5$B1PDZ'[!`@"+51")`H/$++@"````6UY?7<,[5>0/E<"$ +XMP'5>@T7P!(M=\.DX____BT40BS#W`____S\/A!X!``"#PP2+112)1"0,BU40 +XMB7PD!(D<)(E4)`CH^/[__X/X`73-@_@"#X3F````A)UHU?!('F +XM____/\=%Z`````")WW0M@_Y==#R+1>B%P'53@SLM=%6#PP0QP#EUY`^4P(E% +XMZ(L7B=:)WX'F____/W73QT0D!%T```#'!"0R```0Z/Y+__^+1>@+1>1T@HM5 +XM[#E5Z`^%&/___S'`Z8W^__^-=@"+%X/#!.N[BT<$@\,$@_A==*,E____/\=$ +XM)`@`````B40D!(M%Y(D$).C"UP``A +XM7UW#A?8/A!O___^+51"X`0```(DRZ2K^__^+1>2)!"3HD2)-"2)5"0$Z%K7``"%P'^8QT7H`0`` +XM`.N/C;8`````C;PG`````%6)Y5=64X/L+(MU#(M%",=%W`$```")1?"#/EX/ +XMA!4!``#'!"0$````Z$)9`@#'!"20`0``B(M5"(D4).@]OP(`BQ>)QHL"QT7@`````(7`=#N)TXE$)`2+10B-5?#'1"0, +XM`0```(E4)`B)!"3HW/S__X7`=`V+1?"#3>`!.?!S`HG&BT,$@\,$A`/E,"#Q"Q;#[;`7E]=PXL7BP+'1>``````A57B==64X/L#(E%\(MP"(M:"(L#B40D!(L& +XMB00DZ/C(_O^%P'4/BW8(.W7PBUL(=`XY^W7=@\0,,Q=PY"+'0QA"0B%VW0TBT(8A/&!@"+1?")!"3HA54" +XM`.E0____58GE4XG#@^P$B00DZ(\4``"+0QB%P'0(B00DZ&!5`@")'"3H6%4" +XM`(/$!%M=PXGV58GE5U:)QE.)TX/L+/;"`71FH7!A"0B-??#'!7!A"0@!```` +XMB47PQT0D!-`X!@B)/"3HF4K__X/C0`^%WP```*$,80D(A<`/A,4```"+1AB% +XMP`^$N@```(E$)`3'!"01%PD(Z+BB`@")/"3HP$G__X/$+%M>7UW#QP0D2LX( +XM".A!T;XG/@^<(ZR"+!H/H`87_B09T/X7`>`J+5=R)V.AW_O__BUL< +XMA=MT2*&4=PH(A"%P'X*BU77UW#58GE5S'_ +XM5E.#[!R+=0C'1"0$Q)@*",<$)*`S"0CH+K```(D$).@VK@``A<`/A)\```"# +XMQ@2+'H7;=#"#.RUU*X/#!(L#A7UW#QT0D!,28"@C'!"2@,PD(Z.^N``")!"3H]ZP``(E%\.E1 +XM____ZPV0D)"0D)"0D)"0D)"058GE@^PHB5WTBUT(B77XBT4,B7W\A=L/E,*) +XMUG4$AP/A%@!``")\(3` +XM=#C'1"0$Q)@*",<$).`S"0CHQ=P\=$)`0`````B1PDZ*[S__^)Q\=$)`0P*@@(B3PDZ,Q& +XM__^+%>AV"@C'!>AV"@@`````B57PQT0D!,28"@C'!"1@-@D(Z*6M``"%P'0Q +XMBP"%P'0KBT`$AR+'E?1?__QT0D!,28"@C'!"20+PD(Z$NM +XM``#'1"0$A#0)"(D$).@+O`(`BP/A8;^___'1>Q`+PD(Z7K^__^-M@````!5B>575E.#[!S'1"0$ +XMQ)@*",<$),`S"0CHXZP``#WX;PD(B<8/A.8!``#'1"0$@$,)"+\`=PH(B00D +XMZ$W"_O^%P'0_QT0D!'!#"0B[`'<*"(DT).@TPO[_A<`/A9@!``"+6QR%VW1J +XMBT4,B=KH__C__X7`=.N#+029"@@!B=_K7XG?BU\`2+0P2)1P2+0P2)>`C'1Q@`````BT44QT7L`'<*"(7`=2*+-1QW"@B) +XM=QR+7>R)>QR#Q!R)^%M>7UW#C;8`````B77LBT7LBW`PYT`^%P0```(M%\(GZZ,_W__^% +XMP`^%O0```(M5\(M*'(7)=S'1?``````BW(R+@L^/__BWWPZ=3^__^+%1QW"@B% +XMTG2*BT4,Z.+V__^%P`^$>O___XL=''<*"(,M!)D*"`&%VXG?#X4R_O__Z1_^ +XM__^-M"8`````C;PG`````%6)Y593@^P0BUT(A=MT#HM#"(L`@S@*#X33```` +XMQT0D!,28"@C'!"2@,PD(Z`^J``"+$(72#X3'````]\(```!`#X6[````@_I_ +XM#X>R````,?:)P?8$E;U1"0@$=2?IGP```/?"````0`^%DP```(/Z?P^'B@`` +XM`(/!!/8$E;U1"0@$='V-!+:-=$+0BU$$A=)UT(7;="BA!)D*"(M5#,=$)`@! +XM````B5PD!(/``:,$F0H(B50D#(D$).B!_/__NP!W"@B+4QR%TG0EH029"@@K +XM0A`Y\'P@BT("0C70F`(/$$%M>7<.%]G3!P``BQTLFPL(A=L/ +XMA-$'``"+#32;"PB%R0^$!`@``(L5/)L+"(72#X0W"```H62;"PB%P'0&@\04 +XM6UW#H8"8"@C'1"0,8M$(",=$)`A!````QT0D!`(```")!"3'!6";"PA>T0@( +XMZ'&>__^)!"3HV4<``*-DFPL(@\046UW#H8"8"@C'!6B:"PCXS@@(QT0D#/S. +XM"`C'1"0(`@```,=$)`0"````B00DZ"^>__^)!"3HET<``*-LF@L(Z=S]__^A +XM@)@*",<%<)H+"`//"`C'1"0,!\\(",=$)`@#````QT0D!`(```")!"3H[IW_ +XM_XD$).A61P``HW2:"PCIJ?W__Z&`F`H(QP5XF@L($<\(",=$)`P6SP@(QT0D +XM"`0```#'1"0$`@```(D$).BMG?__B00DZ!5'``"C?)H+".EV_?__H8"8"@C' +XM!8":"PB`SP@(QT0D#!O/"`C'1"0(!0```,=$)`0"````B00DZ&R=__^)!"3H +XMU$8``*.$F@L(Z4/]__^A@)@*",<%B)H+""_/"`C'1"0,-,\(",=$)`@&```` +XMQT0D!`(```")!"3H*YW__XD$).B31@``HXR:"PCI#_W__Z&`F`H(QP60F@L( +XM0\\(",=$)`Q(SP@(QT0D"`<```#'1"0$`@```(D$).CJG/__B00DZ%)&``"% +XMP*.4F@L(#X78_/__H8"8"@C'!9":"PA.SP@(QT0D#%+/"`C'1"0("````,=$ +XM)`0"````B00DZ*:<__^)!"3H#D8``*.4F@L(Z9?\__^-="8`H8"8"@C'!9B: +XM"PA;SP@(QT0D#%_/"`C'1"0("P```,=$)`0"````B00DZ&&<__^)!"3HR44` +XM`*.B:"PAJT`@(QT0D#&_0"`C' +XM1"0(+@```,=$)`0"````B00DZ)*8__^)!"3H^D$``*/LF@L(Z5GY__^A@)@* +XM",<%\)H+"(+0"`C'1"0,A]`(",=$)`@P````QT0D!`(```")!"3H49C__XD$ +XM).BY00``H_2:"PCI)?G__Z&`F`H(QP7XF@L(D=`(",=$)`R6T`@(QT0D"#(` +XM``#'1"0$`@```(D$).@0F/__B00DZ'A!``"C_)H+".GQ^/__H8"8"@C'!0B; +XM"PB@T`@(QT0D#*70"`C'1"0(,P```,=$)`0"````B00DZ,^7__^)!"3H-T$` +XM`*,,FPL(Z;WX__^A@)@*",<%$)L+"+O0"`C'1"0,P-`(",=$)`@U````QT0D +XM!`(```")!"3HCI?__XD$).CV0```HQ2;"PCIB?C__Z&`F`H(QP5`FPL(U]`( +XM",=$)`S=T`@(QT0D"#@```#'1"0$`@```(D$).A-E___B00DZ+5```"C1)L+ +XM".E5^/__H8"8"@C'!2";"PCQT`@(QT0D#/;0"`C'1"0(.@```,=$)`0"```` +XMB00DZ`R7__^)!"3H=$```*,DFPL(Z2'X__^A@)@*",<%*)L+"`W1"`C'1"0, +XM$M$(",=$)`@[````QT0D!`(```")!"3HRY;__XD$).@S0```HRR;"PCI[O?_ +XM_Z&`F`H(QP4PFPL(*M$(",=$)`PQT0@(QT0D"#P```#'1"0$`@```(D$).B* +XMEO__B00DZ/(_``"C-)L+".F[]___H8"8"@C'!3B;"PA$T0@(QT0D#$G1"`C' +XM1"0(/0```,=$)`0"````B00DZ$F6__^)!"3HL3\``*,\FPL(Z8CW__^0D)"0 +XMD)"0587`B>5T!8,X"G0%HT!A"0A=PXVV`````(V\)P````!5B>6+10A=HQAA +XM"0C#C78`58GE@^PHBPV0=@H(B5WTB77XB7W\AR9"P@`````=`V+7?2+ +XM=?B+??R)[%W#BQ6\F`H(A=)UZ:'`=@H(A7<.0C70F`%6)Y5WI +XMM____XVT)@````!5B>564X/L$*&T=@H(QT0D#`(```#'1"0$`````,=$)`@` +XM````B00DZ`^V_O^AL'<*"(L5M'<*",<%T"0)"`(```#'!3"9"P@`````HZ!W +XM"@B)%:1W"@C'!;28"@@`````QP5(=PH(`````,<%2)H+"`````#H9JW__XLU +XM[)D+"(7V=0J+'>"9"PB%VW0'@\006UY=PXL5H'<*"(/J`8G0P?@?P>@3C300 +XMP?X-A?9^WC';H;QW"@B+!)B#PP&)!"3HRS\"`#GS=>F+%;QW"@B-!+*)%"2) +XM1"0$Z'(S``")\,'@#8G"P?H?*06@=PH(&16D=PH(*06P=PH(&16T=PH(*36X +XM=PH(@\006UY=PXUV`%6)Y5>)QU93@^P,H;AW"@@YQWQM@\`"QT0D!`0```") +XM!"3HN3\"`(G&H;QW"@B%P'09B40D!(DT).@",P``H;QW"@B)!"3H-3\"`(L= +XMN'<*"(DUO'<*",=$)`0$````QP0D`"```.AU/P(`C1R>B0.AN'<*"(/``3G' +XMH[AW"@A]DX/$#%M>7UW#C;0F`````%6)Y8/L*(E=](L=T"0)"(E]_(M]"(EU +XM^(/[`HD?='.#^P-T7(/[`70WH8"8"@C'1"0,@-<(",=$)`@'````QT0D!!`` +XM``")!"3HTI+__XE<)`2)!"3H9HP"`.@MLO[_D*$PF0L(B4<,H;28"@B)1P2+ +XM7?2+=?B+??R)[%W#C78`H4AW"@B)1PRA2)H+"(E'!.O>H>R9"PB%P'4:H:!W +XM"@B+%:1W"@B)1P2)5PC'1PP`````Z[N+%:1W"@B+':QW"@BAH'<*"(L-J'<* +XM"#G:?-9^2SL5M'<*"'_,C;8`````?`@[!;!W"@AWO(G&*N)3P2)7PCKCSG(6#[$B+50B)7?2)=?B)??R+&H/[`HD=T"0)"'1S@_L# +XM=%R#^P%T-Z&`F`H(QT0D#(#7"`C'1"0(!P```,=$)`00````B00DZ**1__^) +XM7"0$B00DZ#:+`@#H_;#^_Y"+0@RC,)D+"(M"!*.TF`H(BUWTBW7XBWW\B>Q= +XMPXUV`(M"#*-(=PH(BT($HTB:"PCKWJ'LF0L(BW($BWH(A<")-:!W"@B)/:1W +XM"@ATPXL5K'<*"*&H=PH(.=>)1>B)5>P/C,H````/CKD```"+#;1W"@B+%;!W +XM"@@Y3>R)3=R)5=@/CZD```!\"3E5Z`^'G@```(M-V"M-Z(E-X'1DBU7L,57 +XM5E.![$P@``"%R8F%S-___XF5R-___XF-Q-___\>%U-___P`````/A#(!``"! +XM^0$@```/AU<"``#'A=3?__\`````,=O'A=C?__\`````.9W$W___N@$```!V +XM"(N5Q-___RG:C00:/0`@```/AZ@```"-A?/?__\!V(E$)`2+A#?__\/A:T```#'A=S?__\`````BY7@W___.97- +XM-)"!Q\!W"@B+G>#?__^-A?/?__\KG=S?__\#A=S?__^)-"2)7"0(B40D!.BW +XMJ0(`@_C_=%2%P(G"#XZ.````BTT(A57 +XM5E.#[%R+/1AA"0B%_W1"QP4880D(`````(/$7(GX6UY?7<.A,)D+"(7`#X2D +XM````H3"9"PC'!4R:"P@!````BP"%P*.TF`H(='N#!3"9"P@$H;28"@C'!=`D +XM"0@"````A@$``.E;!0``D(UT)@"+%:1W"@B+/:QW"@BA +XMH'<*"(LUJ'<*"(E5M#GZB46P?`X/CZL#```Y\`^#HP,``*.P=PH(HZAW"@B) +XM1"0$H;1V"@B)%;1W"@B)%:QW"@C'1"0,`````(E4)`B)!"3H&JS^_Z&@=PH( +XMBQ6D=PH(BPVP=PH(BQVT=PH(BS6H=PH(BSVL=PH(B46PB56TBU6TBT6P,=HQ +XMR`G"#X1U`P``BQ6\=PH(BT6PBQ(I\(L\@H-%L`0`BT6PBU6THZ!W"@B) +XM%:1W"@B#__\/A>;^__^+10B%P`^%LP0``*&T=@H(C57$B50D!(D$).@^I_[_ +XMA<`/A;#^___V1=$!#X2F_O__BQ5P8PD(A=)T%:$<80D(@\`!.<*C'&$)"`^. +XMA_[__X,]U)<*"/\/A/K]___'!"0/````Z.2J_O^#^/^)PP^$X_W__Z'4EPH( +XM.<,/A-;]__^)1"0$QP0D#P```.@@3`<*)UH'F_Q\``,'Z#2G&B56HB=#H(?3__XM]O+@`(``` +XM*?`YQWX"B<>+1;R-%+4`````BTVXC1R]`````(MUJ,'@`BG!H;QW"@@#%+") +XM7"0(B4PD!(D4).B)J_[_B?HI?;R+1;S!^A\!/;!W"@@1%;1W"@B%P`^/=O__ +XM_^G<_O__Z+2W`0")1:R)1;SI2?___XL0A=(/A*OZ__^#P`1FOR``B16TF`H( +XMHS"9"PCI%?K__Z%(=PH(Z27[__^+';1W"@B+#;!W"@@YV@^,I?S__P^/0_S_ +XM_SG(#X:7_/__Z3;\___'!?R8"@@!````Z#@E__^A2'<*".GY^O__B^O__QP0D`0```.AS2```Z8WZ__^+10B%P`^%P``` +XM`(UV`.AKQO[_H9!V"@CI#_O__Z&\F`H(A<`/A8\```")^(E$)`3'!"1LG`L( +XMZ#*:`@#IVOC__X/`!&:_(`")%4B:"PBC2'<*".G#^/__H8"8"@B+'0QV"@C' +XM1"0,K-<(",=$)`@#````QT0D!!````")!"3HNX7__XE<)`2)!"3H3W\"`.E+ +XM^O__BSB#P`2CD'8*"(7_#X5U^/__H7P@"0AFOPH`HY!V"@CI8OC__X/H`:.\ +XMF`H(N`H```#I8?___[______Z4;X__^)]HV\)P````!5B>564X/L$(MU#(M= +XM"(U&FX/X$W8*,<"#Q!!;7EW#D/\DA6C8"`B)'"3H(9@"`(G"C4#\.<,/ARD! +XM``"+4OR#^B]U(ND<`0``C;0F`````(/H!#G##X<*`0``BQ"#^B\/A/\```"# +XM^BYUY8/^98GV#X3D````*=C!^`*)10R)70B#Q!!;7EWI1)T"`(D<).C\G@(` +XMQT0D!"\```")!"3H_",``(7`#X65````@_YT#X5C____B5T(@\006UY=Z:V< +XM`@#'1"0$`0```(D<).@=<0(`A7<.)'"3HBIP"`(L0A=(/A"C_ +XM__^)P>L;@_H)=!N!R@```$")$8M1!(/!!(72#X0)____@_H@=>"#_G%UZ(VT +XM)@````#KU\=$)`0`````B1PDZ+YP`@"%P`^$>____X/$$%M>753@^P4BQ68=PH(H7R<"PB+70C'!"0@80D(QP4D80D( +XM`````"G0P>("`Q5XG`L(B40D"(E4)`3HPID"`(E<)`3'!"1XG`L(QP5\G`L( +XM`````.@HF@(`QP0D>)P+".@,F`(`H21A"0C'!"1XG`L(B40D"*$@80D(B40D +XM!.A^F0(`B1PDZ"8O`@#'!9AW"@@`````@\046UW#C;8`````58GE5U93@^P, +XMBT4,BW4(BW@(QP0D#````.C"+P(`B<.)<`3'``````"+10B)0PB)6`2+!XE> +XM"(G>B00DZ`^;`@"+?PB)`X,X"G7'@\0,6UY?7<.-M@````"-O"<`````58GE +XM5E.#[!"+=0B+7@B+`XE$)`3'!"22N0@(Z&!\`@"+6P@Y\W07BP.#.`ITXL<$ +XM)"````#H9C\``(L#Z]*#Q!!;7EW#C70F`(V\)P````!5B>575E.#[!R+'1QW +XM"@B)1>R)5>B%VW0^BU,,BWL(A=)X+8L7BPJ#^0IT)(M%Z,=%\`````"%P'5? +XMBT7LZP>0@\`$@\($BPB%R70H.PIT\(M;'(7;=<*+1>PQVXD$).ASK!H/`!(/"!(L(AC'1>P`````P?@"QT7P +XM`````(E$)`B+1>")%"2)1"0$Z"27`@"+'6!A"0B+`X7`="2#^"9T;X/X7(US +XM!'12B40D!(GSC47HB00DZ`J5`@"+`X7`==R+1>R+50B)`J%,80D(C02'B40D +XM!(U%Z(D$).A5EP(`BU77UW#58G"B>6# +XMX@)7@^`!5E.#[#R)5=")1__^A.&$)"(7`=%*+4`BA-&$)"(D5 +XM.&$)"(/H`87`HS1A"0AX*8L"Z#_I__^+#3!A"0B%R0^$1O___\<%,&$)"``` +XM``"#Q#R)R%M>7UW#QP4X80D(`````.D5____QP0D`````.CR\?__@_@DB<%T +XM&SL-C)@*"'7,BUW0A=MTQ3'`Z`4+``#IY_[__XM=S(7;=-ZA,&$)",=%Z``` +XM``#'1>P`````QT7P`````(7`B474HT1A"0@/A.`"``#'!3!A"0@`````BU74 +XMQP0DQM<("(E4)`3H`AX``(7`#X24````BT74QP4P80D()```0*,\80D(Z7K^ +XM__^A>)P+"(L,D(U"`:.8=PH(AC__X/$/+D@````6XG(7E]=PXU5Z(D4),=$ +XM)`2PD0@(Z&,?__^-1>C'1"0$)````(D$).@PD@(`BUW4@_M[#X2U`@``@_LC +XM#X1L`@``@_L_#X1C`@``,?:#^R4/A%@"``"-5>B)7"0$B10DZ/B1`@"-0_:# +XM^#(/AM$!``#WPP```$!U/H/[?Y!W#O8$G;U1"0@$#X5\`0``#[;3@?K_```` +XM#X=V!```H>!="0B+1)`T]L0!#X6G````@_M?#X2>````A?8/A',"``"#;>P! +XMB1T\80D(C47HB00DZ%D>__^-5>B)%"3H_AW__XU%Z(D$).B3D0(`B00DZ%OY +XM___I#?W__\<%,&$)"`````#WPP```$`/A38"```/MM.!^O\````/A\4!``"A +XMX%T)"(M$D#3VQ`%U'(/[7W07@_M_#X<+`@``]@2=O5$)"`0/A/T!``"-5>B) +XM7"0$B10DZ`B1`@"+'3!A"0B%VXD=1&$)"'62N`(```#H?OS__X7`B<-UC(-] +XMU'N)'3QA"0@/A43___^A,&$)"(7`HT1A"0@/A`D%``#'!3!A"0@`````@_A] +XM#X3>!```HSQA"0C'1"0$?0```,<$)#(```#H6AK__^D!____D(UT)@#'!3!A +XM"0@`````]\,```!`#X5@`0``@_M_#X=7`0``]@2=O5$)"`0/A$D!``"-1>B) +XM7"0$B00DZ%20`@"+'3!A"0B%VXD=1&$)"'6TN`(```#HROO__X7`B<-UKNE' +XM____N`(```#HM?O__XE%U(GVZ1;]____)(6XV`@(A?:)]@^$=O[__\<$)%`` +XM``"-=@#HNQG__^EB_O__A?:-="8`#X16_O__QP0D3@```(UV`.B;&?__Z4+^ +XM__^#;>P!A?;'!3QA"0@*````#X4L_O__QP0D3P```.AT&?__Z1O^__^-1>B) +XM7"0$B00DZ*"/`@"+'3!A"0B%VXD=1&$)"'17QP4P80D(`````+X!````Z77] +XM__^)%"3HL)G^_^DW_O__C57HQT0D!'L```")%"3H7(\"`(L=,&$)"(7;B1U$ +XM80D(#X3H`0``QP4P80D(`````.D5_?__N`(```#HO_K__XG#ZZ7'!"12```` +XMZ-\8___IAOW__X/[6P^$W@(``(/[.@^%(/[__\=%W`````#'1>``````C47H +XMB5PD!(D$).CKC@(`BQTP80D(A=N)'41A"0@/A-@!``#'!3!A"0@`````@_MG +XM#Y3`#X2&`0``@_MA#X0J`@``BU7@A=)U"(3`#X6[`0``@_MA#X3Y`0``C57H +XMB5PD!(D4).B1C@(`@_MS#X7>````BSTP80D(A?^)/41A"0@/A.\!``"-1>C' +XM!3!A"0@`````B7PD!(D$).A;C@(`]\<```!`=3^)^`^VT('Z_P````^'\0$` +XM`*'@70D(BT20-/;$`0^%S@$``(/_7P^$Q0$``(/_?W<.]@2]O5$)"`0/A;(! +XM``")?"0$QP0D_[D(".@4&0``A<`/A9H!``#'1=@"````ZR['!3!A"0@````` +XM@_[_#X1U`@``C57HB70D!(D4).C1C0(`,<`Y_@^4P"E%V'0;BS4P80D(A?:) +XM-41A"0AUPC'`Z#[Y__^)QNO!B5PD!,<$),K7"`CHJA@``(7`#X3G`0``BQTP +XM80D(A=N)'41A"0@/A,8```#'!3!A"0@`````@_LZ#X1Q_O__Z7[\__^-M@`` +XM``"X`@```.CF^/__B<.-="8`Z2?[__^)%"3H?Y?^_XUV`.F#^___@T7@`8U5 +XMZ(E<)`2)%"3H*(T"`(L=,&$)"(7;B1U$80D(#X30````QP4P80D(`````(/[ +XM9P^4P.E'_O__N`(```#HA?C__XG#Z2'^__^#1>`!C47HB5PD!(D$).C;C`(` +XMBQTP80D(A=N)'41A"0@/A$H!``#'!3!A"0@`````Z1C^__^X`@```.@^^/__ +XMB)1"0$Z&J,`@"%_P^%!_[__\<$)%@```#H%A;__^EI +XM^___B10DZ(66_O_I"_[__[@"````Z,KW__^)P^DI____C47HQT0D!%L```") +XM!"3H((P"`.LKQP4P80D(`````(/["@^$X````(U5Z(E<)`2)%"3H_(L"`(/[ +XM70^$J0```(L=,&$)"(7;B1U$80D(=<6X`P```.AI]___BGY__^X`@```.@#]___ +XMB<.0Z/G__[@"````Z)+V__^)P^GJ^___C70F`(V\)P````!5B>6# +XM["B)??R)UXL5,&$)"(EU^(G&B5WTB4WLA=*)%41A"0@/A!8!``"#^BK'!3!A +XM"0@`````BQX/A!4!```/CIL```"#^BT/A+(!``"#^EX/A"$!``#WP@```$"- +XM=@`/A7H!``"#^G\/AW$!``#V!)6]40D(!,=%\`````!U-.E;`0``QP4P80D( +XM`````/?"````0`^%X0$``(/Z?XGV#X?6`0``]@25O5$)"`0/A,@!``"+3?"- +XM!(F-1$+0BQ4P80D(B47PA=*)%41A"0AUM#'`Z*CU__^)PNNSC70F`(/Z)`^$ +XM/P$``(/Z)8UT)@`/A6'___^A;&$)"(/X_W0CA=L/B"X!``")!XVV`````(7; +XM>'R+!SD&?PDY1>P/C:T```#'!"1>````Z($3__\QP(M=](MU^(M]_(GL7<.) +XM]C'`Z#GU__^+'HG"@_HJ#X7K_O__A=L/B/H```"+1>R)!SL&?:NX`0```,<' +XM`````,<&`0```.NYA=L/B,L```"%V\<'`0```'F*C;8`````BQTP80D(A=N) +XM'41A"0@/A)D```#'!3!A"0@`````B1PDZ/K>__^)7"0$QP0DU-<(".@Z%``` +XMA<`/A$;___^)]K@!````Z5?___^-M@````"%VP^(A````(M%[(/H`8D'B10D +XMZ+C>___I$____XUV`(7;>S'!@````#'!"0M````@^@!B0?HDM[__[@! +XM````Z0G___^%VW@YBTWLB0_IVO[__XD&Z\<%,&$)"``````/A($'``"C,&$)"*$$F0H(QP5L80D(_____Z/@F`H(BT6\ +XM.P5$F@L(=&F+'3!A"0B%VXD=1&$)"`^$*`<``,<%,&$)"``````['8R8"@AT +XM0XU#W8/X.W8T,?^)7"0$QP0DV-<(".BW$@``A<`/A!X)``")'"3H5]W__Z&, +XMF`H(HS!A"0B#Q$Q;7E]=P_\DA839"`B+%2"9"PB%THE5P`^$2@H``(M=P#L= +XM()D+",<%+&$)"`$````/A'P(``"+5<"+0@B+4@2+0`@YP@^$E`H``#'VBT`( +XM@\8!.<)U]HM=O#L=1)H+",=%\`````")=>P/A-P)``"+'3!A"0B%VXD=1&$) +XM"`^$V@<``,<%,&$)"`````")7"0$QP0DYM<(".C]$0``AR+5?"#P`$IT(/J`872HS1A"0B)5?!X%8M-P(U"_X7`B<*+20B)1?") +XM3ANS?__B47`H3!A"0B%P*-$80D(#X2%!```QP4P80D( +XM`````(/X.@^%#P0``(L],&$)",<%.&$)"`````"%_XD]1&$)"`^$1@0``,<% +XM,&$)"`````#'1<0`````C;0F`````(/_9[L!````=%N#_V%T48U'VH/X4G9[ +XM@_\*#X2'!@``B7PD!,<$)%L```#H(`___XL=,&$)"(7;B1U$80D(#X2'`P`` +XMQP4P80D(`````(/[.@^$<____^GR_O__C70F`+L"````BSTP80D(A?^)/41A +XM"0AT$L<%,&$)"``````)7<3I>?___S'`Z)+P__^)Q^OM_R2%=-H("*%880D( +XMA<`/A'\)``"A5&$)",<%3&$)"`````#'!"1(80D(B40D!.@[AP(`QP0D2&$) +XM".@?A0(`H4AA"0C'!5AA"0@`````QP0D5&$)"(E$)`3H$(<"`,<$)%1A"0CH +XM](0"`(L=-&$)"(7;B5W(#X28_O__BT7$C5W8QT7H`````,=%S`````"#X`&) +XM1;CK08VT)@````"-7>2)^L=%Y`````"-3>B)'"2+7<"+`^A4[O__B<:+1>B% +XMP'0'QT7,`0```/9%Q`)U>8M5T(DRBUW0@VW(`0^(_?W__\=$)`0,````QP0D +XM`0```.@('`(`C578B470B5`(QP``````B4,(B5@$BTW`BTD(B4W`BP&%P'2[ +XMBTVXAB%P'2#@?[X;PD(#X1W____C47DB?J)!"2-3>B)\.BC[?__B?.)7"0$B00D +XMB<;HCXW^_X7`=;^)'"3H%QL"`.E$____BS4P80D(A?:)-41A"0@/A(,"``#' +XM!3!A"0@`````]\8```!`=3^)\0^VT8'Z_P````^'@0(``*'@70D(BT20-/;$ +XM`0^%A`8``(/^7P^$>P8``(/^?W<.]@2UO5$)"`0/A6@&``")="0$QP0D_[D( +XM".@-#@``A<`/A5`&``#'!"1(80D(Z$F#`@#'!4QA"0@`````ZRR#^PK'!3!A +XM"0@`````=#LY\W1#@_M<#X07`0``B5PD!,<$)$AA"0CHL8("`(L=,&$)"(7; +XMB1U$80D(=<0QP.@J[O__B<.#^PIUQ<<$)`H```#H1]C__Z%,80D(A<`/A:\! +XM``"A2&$)"(L8A=L/A"`'``")!"3H'XW^_Z-,80D(QP5D80D(`````.LNB?:# +XM^PK'!3!A"0@`````=#LY\W1#@_M<#X3L````B5PD!,<$)&!A"0CH)(("`(L= +XM,&$)"(7;B1U$80D(=<0QP.B=[?__B<.#^PIUQ<<$)`H```#HNM?__\<$)&!A +XM"0CH3H("`.DJ_?__@TW$`>DA_?__BQTP80D(@P5P=@H(`87;B1U$80D(#X5Y +XM_/__,<#H3NW__XG#Z77\__^)!"3H;]?__^E*_/__BQTP80D(A=N)'41A"0@/ +XMA(D```#'!3!A"0@`````.?,/A,/^__^#^UP/A+K^___'1"0$7````,<$)$AA +XM"0CH9X$"`.FA_O__,<#HZ^S__XG'Z;;[__\QP.C=[/__Z7G[__^+'3!A"0B% +XMVXD=1&$)"'0]QP4P80D(`````#GS#X3R_O__QT0D!%P```#'!"1@80D(Z!*! +XM`@#IV?[__S'`Z);L__^)PXUT)@#I;____S'`Z(3L__^)PXGVZ\#'!"1<```` +XMZ*(*__^)]NG'^O__,<#H9.S__XG&B?;I=_W__\<$)$AA"0CH'X$"`.E<_O__ +XMB10DZ.Z*_O^)]NEY_?__,<#H-.S__XG#B?;ITOC__S'`Z"3L__^#^'N0#X5_ +XM^/__QT6\>P```.EX^/__QP0D2&$)".C2@`(`QP5,80D(`````.LLQP4P80D( +XM`````(/X"@^$PP(``(/X/P^$Q@(``(E$)`3'!"1(80D(Z#J``@"A,&$)"(7` +XMHT1A"0AUQC'`Z+7K___KQXL=,&$)"(7;B1U$80D(#X2%!```QP4P80D(```` +XM`+\!````Z43X__^+->"8"@@[-029"@B)'3!A"0@/A$,$``"+%1QW"@B%TG44 +XMZ2$!``"-="8`BU(0```.@S"?__Z>'W___'!3!A"0@J````B?&)^HU%\.AH]/__A<`/A,/W +XM__^+'3!A"0B%VXD=1&$)"`^$&P,``,<%,&$)"`````#IJ/C__S'`Z+;J__^) +XMP^DB^/__H3!A"0B%P*-$80D(#X2>`@``QP4P80D(`````(/X?0^$ROC__\<$ +XM)%8```#HK@C__^FY^/__QP0D"@```.B=U/__Z6CY__^+0PB+%828"@B+0`@Y +XMT`^$&`(``#'VBT`(@\8!.=!U]NE_]___B30DZ,MS``")PXD$).BAA`(`QP0D +XM8````(E$)`3H40C__XD<).@I%@(`@\1,6UY?7#^W^0=Q'V!)V]40D( +XM!(T$MHUT0]!U!;[_____B5PD!,<$)$AA"0CH^'T"`(L=,&$)"(7;B1U$80D( +XM=!2%V\<%,&$)"``````/B7'____KCS'`Z%WI__^)P^E=____B1PDZ'[3__^A +XM3&$)"(7`#X5<`0``H4AA"0B)!"3H8(C^_Z-,80D(H8R8"@BC,&$)".D#]O__ +XMQP0D"@```.A$T___H4QA"0B%P`^%]P```*%(80D(B00DZ":(_O^%P*-,80D( +XM#X1*`0``N@$```"A2&$)".B.YO__A<")P@^%COW__^F1_?__B1PDNSH```#' +XM!3!A"0AS````Z.C2___IGO;__XLU!)D*".DU_?__BSTP80D(A?^)/41A"0@/ +XMA(D!``#'!3!A"0@`````B3PDZ++2___WQP```$!U,XGX#[;0@?K_````#X=_ +XM`0``H>!="0B+1)`T]L0!=06#_U]U#\=%\`````")=>SI,O;__X/_)@^%XO7_ +XM_^OF,?;IP(`QP0D2&$)".@W?`(`H4AA"0B+%4QA +XM"0B)1"0$@\`$C125_/___XE4)`B)!"3HSHK^_Z%(80D(,=+'`"T```#I2/[_ +XM_XL-()D+"(7)B4W`#X4B]/__Z:?[__\QP.@3Y___B<.0Z7;[__\QP.@$Y___ +XMB<>)]NEQ_O__QP0D5P```.@?!?__Z?KU__^)%"3HCH7^_XGVZ7O^___'!"19 +XM````Z/\$___IVO7__XUV`(V\)P````!5B>575E.#[%RA[%T)",<%$&$)"``` +XM``#'!7"<"P@`````QP0D[)@*"(E%H.BOT___BU4(B5($B5((QP+X;PD(QP4L +XM80D(`````,<$)`````#H:MG__X/X('3O@_@)=.H[!42:"PAU#HL5P'8*"(72 +XM#X6/!0``B00DZ'+0__^+10B-?>C'1"0$D.D%"(D$).B\!___BUT(QP0D#``` +XM`.C]$@(`B46DB5@$QP``````BU4(B5`(B4($B4,(QT7H`````,=%[`````#' +XM1?``````QT0D!+"1"`B)/"3H<`?__XL=,&$)"(7;B1U$80D(#X1``@``QP4P +XM80D(`````(/[('3=@_L)=-B%VW@,]\,```!`#X0M`@``,?;'1:@#````A?9T +XM13GS#X24````@_M<#X2:````@_L*#X3!`P``D(E<)`2)/"3HY'D"`(L=,&$) +XM"(7;B1U$80D(=%:%]L<%,&$)"`````!UNX7;>-*)V,'H'H/P`8/[?P^>PH30 +XM=,`/ML,/MX0`X"`)"*A3=+&#^UP/A%(!``"H`P^$D@```#'`@_LB#Y3`B=Z# +XMP`*)1:CKCHM%J.@&Y?__B[^__^)'3!A"0B)/"3HH`7_ +XM_XD\).A(!?__B3PDZ.!X`@"+5:2)TXD"QT6@`````(,X"@^%$/[__XM%"(D$ +XM).AN!?__BU4(B10DZ!,%___'!"1LG`L(Z.=X`@"+%7"<"PB%TG04H6R<"PB# +XMZ`2-!)"#.`H/A#,#``"A+&$)",<%$&$)"`$```"#Q%Q;7E]=PS'`Z-OC___I +XM`O___XL=,&$)"(7;B1U$80D(#X1^`0``@_L*QP4P80D(``````^$?0$``#L= +XMC)@*"'00QT0D!%P```")/"3H!W@"`('+````0.D,_O__N`,```#H@N/__XG# +XMZ;G]__^#^W\/C\K]__\/ML,/MX0`X"`)"*A0#X2W_?__@_L[#X12`0``#X^X +XM````@_LF#X3-````C;0F``````^/*@$``(/["HVT)@`````/A"8!``"#^R.- +XMM"8`````#X5R_?__H)7+6X +XM@\8!@_L*#X3-````B5VPBQTP80D(A=N)'41A"0AUR#'`Z*;B__^)P^O'N`H` +XM`$#I\_W__X/[/I"-="8`=!0/C^<```"#^SR0C70F``^%TOS__XE<)`2)/"3H +XMWG8"`*$P80D(A<"C1&$)"`^$&P$``,<%,&$)"``````YV'1*HS!A"0CIW/W_ +XM_S'`Z#WB__^)PX/["@^%@_[__X,]O)@*"`$/A;W]___'!;R8"@@"````Z:[] +XM__^-M@````"-0]B#^`$/AUS\__^)7"0$B3PDZ&AV`@#IB_W__X!]KP!T&X-] +XMN"O'1>0`````B?8/A*@````QR8D-%&$)"(-]L%P/A.C[___KPHVV`````(ET +XM)`3'!"0S````Z.#__O_'!3!A"0@*````Z3G]__^#^UQT$8/[?`^%Z_O__XUV +XM`.D1____BQTP80D(A=N)'41A"0AT+\<%,&$)"`````"#^PH/A;T```"#/;R8 +XM"@@!#X5[^___QP6\F`H(`@```.EL^___,<#H1>'__XG#Z]"X`P```.@WX?__ +XMZ>#^__^+1;R%P`^$3?___P^VT(/Z?Y`/AT#___\QR3'V]@25O5$)"`1U)NDM +XM____C;0F``````^VT(/Z?P^'&O____8$E;U1"0@$#X0,____C02)@\8!C4Q" +XMT(M$M;R%P'74@_X*#X7Q_O__Z>[^___'``````#IPOS__^CF[/__C;8````` +XMZ6GZ__\['8R8"@AT$,=$)`1<````B3PDZ`-U`@"!RP```$#IX/K__Y"0D)"0 +XMD)"058GEBU4(BTT,A=)U!NL9D(/"`0^V`H3`=`X/OL`YR'7O7;@!````PUTQ +XMP,.-="8`53'`B>6+50B+"H7)=`R)]H/``8L,@H7)=?9=PXUT)@!5B>53BUT( +XMBTT,B=J-="8`BP&#P02)`H/"!(7`=?*)V%M=PXVV`````(V\)P````!5B>6+ +XM10B%P'08BQ"%TG4$ZQ")T(M(!(U0!(7)=?2+`%W#73'`PXUV`(V\)P````!5 +XM,=*)Y8M%"(7`=0?K#(GV@\`!@#@`=?B)PEV)T,.)]E6)Y8M-"(7)=!:)RHUT +XM)@"+`B7___\_B0*#P@2%P'7P78G(PXVV`````(V_`````%6)Y8M%"(7`=!F+ +XM$(72=!.)P8'*````0(D1@\$$BQ&%TG7O7<.-="8`C;PG`````%6)Y5.+70B+ +XM30SK"HUT)@"#PP2#P02+$X72=!J+`87`=`^!XO___S\E____/SG"=-];,575E.#[`R+?0R+=1"0Z+MP`@"+10B)="0(B7PD!(D$ +XM).@T?/[_@_C_B<-U"NAX@/[_@S@$=->#Q`R)V%M>7UW#C;8`````C;PG```` +XM`%6)Y5=64X/L#(M]#(MU$.L4Z$:`_O^#.`1U))"-="8`Z%MP`@"+10B)="0( +XMB7PD!(D$).C4@?[_@_C_B<-TTH/$#(G86UY?7<.-M"8`````58GE5U93@^P, +XMBWT,BW40D.@;<`(`BT4(B70D"(E\)`2)!"3HA(/^_X/X_XG#=0KHV'_^_X,X +XM!'37@\0,B=A;7E]=PXVV`````(V\)P````!5B>575E.#[!R+?0SWQP`"``!T +XM80^W=1"-112)1?#K%>B7?_[_@S@$=26-M@````#HJV\"`(ET)`B)?"0$BT4( +XMB00DZ$2!_O^#^/^)PW31@\056 +XM4X/L$(MU".B\?O[_QP``````ZQKHKW[^_X,X!'4>Z,EN`@#HH'[^_\<````` +XM`(DT).A">_[_A<")PW38@\00B=A;7EW#C;0F`````%6)Y593@^P0BW4(Z&Q^ +XM_O_'``````#K&NA??O[_@S@$=1[H>6X"`.A0?O[_QP``````B30DZ!)[_O^% +XMP(G#=-B#Q!")V%M>7<.-M"8`````58GE5U93@^P,BWT(#[=U#.L3Z!5^_O^# +XM.`1U'(UT)@#H*VX"`(ET)`2)/"3H:WK^_X/X_XG#=-J#Q`R)V%M>7UW#C;0F +XM`````(V\)P````!5B>53@^P$BUT(ZQF-="8`Z,=]_O^#.`1U&(VV`````.C; +XM;0(`B1PDZ"^!_O^#P`%TWH/$!%M=PY"-M"8`````58GE4X/L!(M="(7;>1?K +XM(NB'??[_@S@$=1B-M@````#HFVT"`(D<).@??O[_@\`!=-Z#Q`1;7<.0C;0F +XM`````%6)Y8/L",<$)`````#HKO___\<$)`$```#HHO___\<$)`(```#HEO__ +XM_\<%Z'8*"`````#)PXUV`(V\)P````!5B>575E.[`00``(/L#(M]",<$)`$$ +XM``#H0P@"`(G&ZQ&-'`")-"2)7"0$Z(`(`@")QHE<)`B)="0$B3PDZ.J`_O\Y +XMV'3;@_C_=!O&!`8`@\`!B40D!(DT).A2"`(`@\0,6UY?7#2+7?`Q]NL'@\8!.?YT$8/#!(D$).C8!@(`BP.%P'7HBT7PB5T,B44(@\0, +XM6UY?7>E]^O__BUWPZ^:0C;0F`````%6)Y593@^P0BW4(A?9T*(L&A53 +XM@^P$BUT(BP.)!"3HK/___XE="(/$!%M=Z4\&`@#K#9"0D)"0D)"0D)"0D)!5 +XMB>5=Z8?___^-M"8`````58GE@^P(BT4(B00DZ']T`@"C('<*",=%"!D``!#) +XMZ9WX_O^-M@````"-O"<`````58GE5E.#[!"+70R+=0C'1@0`````BQ.%TG0Z +XMD(UT)@"%TG@<]\(```!`=12#^G^0?PX/ML+VA`#@(`D(\W4GD(/#!(E4)`2) +XM-"3H$6X"`(L3A=)URXDT).AC;@(`BP:#Q!!;7EW#QT0D!%P```")-"3HZFT" +XM`(L3Z\:-M@````!5B>53@^P4BUT(B1PDZ`[Y___'1"0$!````(/``8D$).B[ +XM!0(`B5PD!(D$).@/^?__@\046UW#B?:-O"<`````58GE5U93@^P,BW4(BWT, +XMB30DZ,GX__^)/"2)P^B_^/__QT0D!`0```"-1!@!B00DZ&L%`@")="0$B<.) +XM!"3HO?C__XLSB=B%]G0.D(UT)@"#P`2+"(7)=?>)?"0$B00DZ)OX__^#Q`R) +XMV%M>7UW#D%6)Y5>)QU:)UE.#[`SK%I#H1WK^_X,X!'4>C;8`````Z%MJ`@") +XM="0$B3PDZ'MW_O^#^/^)PW38@\0,B=A;7E]=PXVT)@````"-O"<`````58GE +XM@^P8B5WXB=.)=?R)!"3HEG?^_X7`B<9X.X/[_W0E.=YT%8G:B?#HTO___XDT +XM)(G#Z#C\__^)WHGPBUWXBW7\B>Q=PX/X!7[6B?"+7?B+=?R)[%W#OO____^+ +XM7?B)\(MU_(GL7<.0C;0F`````%6)Y5.#[`2+10B+70PYV'06A!>) +XMVI"-="8`Z!O___^)V(/$!%M=PXUV`(/X!7_R@\0$B=I;7>E/____ZPV0D)"0 +XMD)"0D)"0D)"058GE@^P8B5WXBUT(B77\BW4,.?-T'X7;>!N%]G@CB?*)V.C) +XM_O__.=YT"HD<)(GSZ'O[__^)V(MU_(M=^(GL7<.)="0$B1PDZ&/___\YPXG& +XM==CKX(UT)@"-O"<`````58GE4S';@^P$Z*)5__^)]CL=M'8*"'0H.QW,EPH( +XM="`['01V"@AT&#L=1)D+"'00@_L/=`N)'"3H$_O__XUV`(/#`8/[0'7(@\0$ +XM6UWI/E;__XVT)@````"-O"<`````58GE@^PHB7W\BWT(B5WTB77XA?]T>HM% +XM#(7`=&.)/"3HMWO^_XG&BT4,B00DZ*I[_O^)1?"-1`8!B00DZ(\#`@")="0( +XMB7PD!(G#B00DZ-EZ_O^+1?"-%#.)%"2#P`&)1"0(BT4,B40D!.B]>O[_B=B+ +XM=?B+7?2+??R)[%W#B?;'10Q%R0@(ZY2-M"8`````OT7)"`CI?/___XVV```` +XM`%6)Y8/L&(EU^(MU"(E=](E]_(7V=#J)-"3H'GO^_XUX`8D\).@'`P(`B7PD +XM"(ET)`2)PXD$).A1>O[_B=B+=?B+7?2+??R)[%W#C;8`````OD7)"`CKOXGV +XMC;PG`````%6)Y8/L&(EU_(MU#(E=^(U&`8D$).BV`@(`B70D"(G#BT4(B1PD +XMB40D!.C]>?[_B=C&!#,`BUWXBW7\B>Q=PY!5,<")Y5=64X/L#(M="(7;=$>) +XM'"3H1O7__\=$)`0$````@\`!B00DZ/,!`@")QXL#AB?N-M"8````` +XMB00DZ+AM`@")`XM&!(/#!(/&!(7`=>F)^(/$#%M>7UW#ZPV0D)"0D)"0D)"0 +XMD)"058GE5E.#[""+70C'1>P`````C77LQT7P`````,=%]`````"+`^L2QT0D +XM!"````")-"3H>6D"`(L#A"%P%T/ +XME,`/ML##BT($J0```$!T!%TQP,.#^'^0=_;V!(6]40D(!'3L@\((BP+KGI"0 +XMD)"0D)"0D)"0D)!5B>5=QP4@F0L(`````,<%A)@*"`````#'!3"9"P@````` +XMPXVV`````(V\)P````!5B>564X/L$(MU"(7V#X2@````#[8&/`(/A(@```!W +XM$BP!=#:)=0B#Q!!;7EWI?O\!`#P&=^Z+1@B)!"3HO____XM&#(D$).BT____ +XMB74(@\006UY=Z5;_`0"+5A"+`H7`=!>)TXD$).A#_P$`BT,$@\,$A7>D*_P$` +XMBT84B00DZ$_____KSX/$$%M>7<.-M@````!5B>5=Z3?___^-M"8`````58GE +XM5U93NP$```"#[#PYT(E%V(E5U(E-T,=%[``````/A(4```")PXL#B00DZ%Y? +XM__^#^!*)P0^&90,``,=%[`````"+7=@Q_S'VZR*-=@"#^"@/A)<#``"+3>R% +XMR74$A?]U`X/&`8M;"#E=U'0PBP.+`(/X*0^$A`,``'[2@_@\=`6#^#YUT87_ +XM#X2``P``BT7LA3'1"0$!````(D<).AN_@$`BU7DB47HB4(0BTW4BP&#."D/ +XMA&,#``"+1=0Y1=@/A&H#``"+5=`Q_XM-T(M=V,=%W`````"#X@�+'1>`` +XM````QT7P`````(E5S(E-R.LO@_@H#X0N`0``A?\/A4T!``"+-8!>"0B%]@^$ +XM6`$``(-%\`&+6P@Y7=0/A-H```"+$XL"@_@I#X3!`0``?L*#^#P/A$@!``"# +XM^#Z-=@!UNH7_#X4'`0``@WH$/HGV#X3J`@``BT,(.T74#X3_`0``BS#'1"0$ +XM,#L)"(DT).BH;_[_A<`/A,(!``#'1"0$0#L)"(DT).B0;_[_A<`/A<<"``"+ +XM1>2!2`0``0``BUL(BW,(.W74#X2T`0``BP:)\XL`QP0DSML("(E$)`3H7?#_ +XM_X7`#X66`0``BT70@^`,@_@$=`Z+5>2+0@R%P`^$EP(``,<$)&4```#HX.[^ +XM_XM;"#E=U`^%)O___XM=W(7;=`N+3>R%R0^$_@```(M%\(7`#X06`@``BTWD +XMQ@$!BT7D@\0\6UY?7<.%_W4@BU7R%P`^$NO[__XLU@%X)"(7V#X6H_O__BP.)!"3H?&@"`(M- +XM\(M5Z(D$BNF0_O__A?]URX-Z!#P/A+P!``"+2+ +XM00B%P`^$M@$``,<$)&<```#HZNW^_^DK_O__D(UT)@"#[P$/A5C___^+1>R) +XM7>"%P`^$#_[__^E0____BU7PA=(/A5,!``"+3>3&`0*+5>"Y`0```(M%W.CS +XM!```BU7DB4(4BT7D@\0\6UY?7<.+3>2!202`````]D70#(M;"`^%C_[__XM# +XM"#M%U`^%`@$``,<$)&0```#H8^W^_^FD_?__N`$```#3X*D`ZP0`#X6,```` +XMJ!`/A('\__^+6P@[7=0/A6#\___IP!````Z?C[___'0@00````BT74.478#X66_/__QP0D)````.B5 +XM[/[_Z=G]__^+5>2#2@0"Z0K]__^+1>2!2`0``@``Z37^__^+2)00SIAOS__XL& +XMB00DZ%9F`@"+5>2)0@CI=>V+3>B)\H/$'(GX6UY?7>G#^O__C78`A=)US,=$)`08 +XM````QP0D`0```.CH^0$`BTWH@\D$B47PBT,(.?")1>QT7HL`@S@F=$"+1?") +XMVL8``XGXZ'_Z__^+5?")0@B+5>R+`H,X)G0S@TWH`HGRBT,(BTWHZ#[___^+ +XM5?")0@R#Q!R)T%M>7UW#BT7PBTWH@4@$@````(/)#.NNBUWLZ\B+5?")^,8" +XM`XG:Z"CZ__^+5?")0@CKL56)Y5>)UU93B<.#[!PYT(E-['0TB<8QR>L;C;8` +XM````@_@I#X27````@_@F=#*+=@@Y]W03BQ:+`H/X*'7BBW8(@\$!.?=U[8M- +XM[(GZ@\0EF____D(VT)@````!5 +XMB>57B==64XG#@^P<.=")3>QT-HG&,@1\=57B<=6B=93@^P<.=")3>P/A*(```")PS'2ZQV)]H/X +XM"G0F@_@H=0:#P@&-=@"+6P@YW@^$?P```(L#BP"#^"ET;'[:@_@[=>6%THUV +XM`'7>QT0D!!@```#'!"0!````Z&KW`0")VHE%\,8`!(M-[(GXZ,C^__^+5?") +XM0@B+1>R)="0$B40D"(M#"(D$).BL`0``BU7PA<")0@QT+XM%\(/$'%M>7UW# +XMC;0F`````(M;"(/J`3G>=8&+3>R)\H/$'(GX6UY?7>ES_O__BT((QT((```` +XM`(E"#.O"C70F`%6)Y5=64X/L'#G0B47PB57LB4WH#X3L````BQB)QC'_ZQR# +XM^"9T;X/X*'4$@\BP.#^"ET/G[;@_@^=`R#^'R0 +XM==Z#>P1\=-B+=@@[=>R)]@^$G````(L>QT0D!#`["0B)'"3HA&C^_X7`=+2+ +XM`X/X*77"@^\!>:C'!"1A````Z!SH_O_KFH7_=9:#>P0FB?9TCHM-Z(GRBT7P +XMZ''^__^)QP^V`#P$='L\!G1W/`5TR)-"2)1"0$Z&,```")0PSK)X7_ +XM=16+3>B+5>R+1?"#Q!Q;7E]=Z07^___'!"1B````,=OHA^?^_X/$'(G86UY? +XM7575E.#[`R+70B+=0R+?1`Y\W4)ZS&+6P@YWG0JBP.+`,<$),K;"`B) +XM1"0$Z&WH__^%P'7A@\0,B?F)\HG86UY?7>E7_O__@\0,,575HG64XG#@^PL.=`/A#D!``"+`(,X*`^$#P$``,=$)`24 +XM=@H(B00DZ"!1``"%P(G"#X04`0``BT,$B36$F`H(HR"9"PB+`L=$)`10*@8( +XMQP0D,)D+"*,PF0L(Z.WI_O^-1>B)1=B)!"3HC^'__XE%X,<$)#"9"PCH,.G^ +XM_XL-@%X)"(7)=!>-1>B)!"3H6[/__\<$)````$#HO^;^_XL#BQ"%T@^%T@`` +XM`(M%X(7`#X2T````BWL$D(UT)@"+`XD$).@&]`$`BUL(BT,$B00DZ/CS`0`Y +XMWG7DB7<(N`$```")?@2+5=@Y5?!T88M%[(M`!(E&!(M%[(M`!(EP"(M%\(EX +XM!(E'"(M%[(L`B00DZ+GS`0"+1>R)!"3HKO,!`(/$++@!````6UY?7<.+4@2+ +XM`H,X*741ZQV0C70F`(M2!(L"@S@I=`XYTW7R,<"#Q"Q;7E]=PXM#"#G0=._H +XM7````(/$+%M>7UW#BW,(BWL$.?,/A4;____I7?___XM5\(E5W(LZB00DB7PD +XM!.BI9?[_A<`/A1+___^)?"0$QP0D($,)".C57@(`BU7P/A,X```"+&(G&,?_K(I"#^"9T.X/X +XM*`^$G````(/X"G0MBW8(.77L#X26````BQZ+`X/X*71H?M:#^#Z-=@!T-(/X +XM?'0)@_@[==>-="8`A?]USXM%\(GRZ-+]__^Z`0```(7`=62+1@B+5>R#Q!Q; +XM7E]=ZWJ+=@@[=>QT1XL>QT0D!#`["0B)'"3HW&3^_X7`=(^+`X/X*76=D(UT +XM)@"#[P$/B7K____'!"1A````Z-OD_O_I:?___X/'`8UV`.E>____,=*%_W0* +XM@\07UWI2?W__XGVC;PG`````%6)Y5:)UE.) +XMPX/L$#G0=0GK+HM;"#G>=">+`XL`QP0DRML("(E$)`3H4^7__X7`=>&#Q!") +XM\HG86UY=Z<#^__^#Q!`QP%M>7<.-M"8`````58GE5E.[,@```(/L$(MU",<% +XM:)P+"`L```"-M@````"+1@B)\NB&____A&#Q!!;7EW#D)"0D)"0D)"0D)"058GEBT4(78L`HW!A +XM"0C#D%6)Y5W'!=@D"0B@G`L(PY!5B>6#[!BAV"0)"#V@G`L(#X2`````BPV$ +XM=PH(A&$) +XM"`$```"%TG5)BPWH=@H(N@$```"%R74&BQ7,EPH(+:"<"PB)1"0(QT0D!*"< +XM"PB)%"3HH^7__X/``71>QP78)`D(H)P+",<%>&$)"`````#)PXL-Z'8*"+H" +XM````A&$)"`````#'!=@D"0B@G`L(QP0D````(.@` +XMX_[_H=@D"0CI8?___XVV`````.CG9?[_BP"#^`ET'HUT)@!^*8/X&703B?:- +XMO"<`````?"&#Z$6#^`%W&<<$)`$```#HZH+^_^EG____@^@%@_@!=N?'!"0` +XM```@Z*'B_O^0Z4W___^-="8`C;PG`````%6)Y8/L"*'8)`D(BU4(@>+__S\` +XMB!"#P`$]EJ0+"*/8)`D(<@7HEO[__\FX`0```,/K#9"0D)"0D)"0D)"0D)!5 +XMB>53@^P$BPW`F`H(BUT(A#.-=@")'"3H.*4!`(E="(/$!%M=Z4O___^A?)@*"(7`#Y7`Z\*A_)D+"(7` +XM#Y7`Z[:-=@"!XW____>!RP````CKPNA]9@$`ZZN-="8`C;PG`````%6)Y593 +XM@^P0BT4(BQ5P80D(B<:)PX'F````/('C__\_0(72=5VI````0'56.QW<70D( +XM?2RAX%T)"/9$F#4"=!:#^W\/CA8!``"#/8!1"0@!#X0)`0``]D28-@1U&8UV +XM`(/[?P^.L@```(,]@%$)"`$/A*4````)WHDT).C0_O__ZR^+%<"8"@B!X___ +XM_S^%TG0^H>AV"@B%P'5EH?R9"PB%P`^5P(3`=3Z)'"3H7_[__XLUU"0)"(7V +XM=`N!X___/P"#^PIT2H/$$%M>7<.-=@"AZ'8*"(7`=!JA?)@*"(7`#Y7`A,!T +XMP@G>B30DZ/^C`0#KMJ'@=0D(A<`/E<#KII"A;)D+"(7`#Y7`ZYF-="8`@\00 +XM6UY=Z;7\__^)\(/(7(D$).C8_O__B=C!^`:#X`>#P#`)\(D$).C#_O__B=C! +XM^`.#X`>#P#`)\(D$).BN_O__B=B#X`>-6##I%____XU#]X/X`0^&"____XL- +XM=&$)"(7)=!J)\(/(7HD$).A^_O__@_M_=!*#RT#IY_[__X/[#77AZ=W^__^S +XM/Y"-="8`Z='^__^-="8`C;PG`````%6)Y5=64X/L'(M="(G8)?__/P")1"0$ +XMC47NB00DZ"Y:`@"%P(G'="")WC';@>8``,#_#[9$*^Z#PP$)\(D$).@,_O__ +XM.?MUZH/$'%M>7UW#58GE5U93@^PZ)!"3HWED" +XM`(7`B<=T((G>,=N!Y@``P/\/MD0K[H/#`0GPB00DZ`S]__\Y^W7J@\0<6UY? +XM7<-5ND#C12)`=(ITXE<)`B)3"0$ +XMZ&`Z`@"#Q!1;7<.-=@"-O"<`````5;AWFBX`B>564X/L$(MU"(GQP>D&]^&) +XMT\'K`H7;#X2,````B5PD!,<$)-C;"`CH'#H"`&G#0'X%`(GQ*<&X'X7K4??A +XMB=.ZB8B(B,'K!8G8]^J-!!K!^`7H8O___\<$)-K;"`CHYCD"`(G8NHF(B(CW +XMZ@':P?H%:](\*=.)V.@\____QP0DDAT)".C`.0(`B?"Z'X7K4??B@\006\'J +XM!6O29"G6B?!>7>D2____B?:X'X7K4??FQP0D/=P("(G3NHF(B(C!ZP6)V/?J +XM`=K!^@6)5"0$Z'8Y`@#K@HUT)@!5N,6SHI&)Y593@^P0BW4(]^:)T\'K"X7; +XM=&B)7"0$QP0DV-L(".A%.0(`:<,0#@``B?.ZB8B(B"G#B=CWZHT$&HG:P?@% +XMP?H?*=#HD/[__\<$)-K;"`CH%#D"`(G8NHF(B(CWZHG8P?@?@\00`=K!^@4I +XMPFO2/"G3B=A;7EWI7?[__XGPNHF(B(CWZHGPP?@?B?/'!"0]W`@(`?+!^@4I +XMPHE4)`3HQC@"`.NDD)"0D%6A@'<*"(GE7<<%@'<*"`````"CB'8*",.-M"8` +XM````5:&(=@H(B>5=QP6(=@H(`````*.`=PH(PXVT)@````!5B>564XG#H0"8 +XM"@B%P'1`BPT\=PH(,?;K#(VV`````(L`A7<.-M@````"-OP`````[!3QW +XM"@A5B>53B<-T$CL%<)D+"'0J6UW#C;0F`````*%PF0L(A6#[`B#/=27"@C_="*AU)<*"(7`=`C)PXVV`````,<$)#X```#H5-S^ +XM_\F-=@##QP0D(````.A#W/[_C78`Z\V-M"8`````C;PG`````%6)Y593@^P0 +XMBQT`F`H(BW4(QP6,=@H(`@```(7;="N0]D,,`G0>A?:X`;H("'4%N$7)"`B) +XM1"0$QP0D0````.CLV_[_BQN%VW76@\006UY=P^L-D)"0D)"0D)"0D)"0D%6) +XMY8/L6(E]_(M]"(E=](EU^(/_``^."@$``(U=U(UUY(D<).B#8/[_QT0D!!(` +XM``")'"3H@UO^_\=$)`05````B1PDZ'-;_O^)="0(B5PD!,<$)`$```#H#UO^ +XM_\=$)`1@'@4(B30DZ%/>_O^+10S'!"0`````B40D!.B<7/[_@\`!#X2G```` +XMA?]^=L<$)`\```#H\UW^_SE%#'1:C5V\B5PD",=$)`0`````QP0D%@```.CS +XM7O[_QT0D!`$```#'!"06````Z$]?_O^+10S'!"0/````B40D!.@,6O[_QT0D +XM"`````")7"0$QP0D%@```.BT7O[_C47DB00DZ!W=_O\QP(M=](,]U)<*"`"+ +XM=?B+??P/G\"#Z`$A!=27"@B)[%W##XU"____Z]:-=@#HQV#^_\<$)`````") +XM10R)1"0$Z-1;_O^#P`%T"(M]#.DT____Z')=_O^+`(D$).@86_[_QT0D!-S; +XM"`C'!"0V````B40D".A4VO[_QP0D`````.AX>O[_Z\.-M@````!5B>53B<.# +XM[!2+0!B%P'4(ZWZ+6P2+0Q@[0QQU]8G8Z#S]__\QP#L=@'<*"`^4P(/H`2$% +XM@'<*"(G8BU,4C78`@6`,_W___\=`&`````#'0!0`````BT`$.=AUY#L5,)H+ +XM"'0&@\046UW#H0"8"@@QR87`=`^+4!0YT7T"B=&+`(7`=?&)#3":"PB#Q!1; +XM7<.A@)@*",=$)`SLVP@(QT0D"`,```#'1"0$$0```(D$).@K.___B00DZ,,T +XM`@"#Q!1;7<.-M@````"-O"<`````58GE@^PHB77XBW4(B5WTB7W\A?9T"HM> +XM!(U^!(7;=2"+'3QW"@B%VW1HBQ4\=PH(BUWTB="+=?B+??R)[%W#D,=$)`3< +XM/0D(B30DZ/Q8_O^%P'3,QT0D!.@]"0B)-"3HZ%C^_X7`=+C'1"0$]#T)"(DT +XM).C46/[_AP`````ZPR+5?"+$H72B57P=&Z+ +XM5?"+0A@[0AQUZ8,_/W5&BU)XBP*%P'3;B=/K"HM#!(/#!(7`=,T[!G7RB5PD +XM!(DT).A1VO__ASKGHM5\(M" +XM>(D\)(E$)`3H(-K__X7`=(CKS8M5[(72D(UT)@`/A;K^__\QP(,_/P^4P(/H +XM`8/@\04\```0B00DZ-_7_O\QTNF8_O__QP0D.P``$.C,U_[_Z>'^__^)/"3H +XMCU,"`(D$).@S5O[_BQ4`F`H(A=*)P74(ZQB+$H72=!([2A1U]8M"&#M"''7M +XMZ5'^___'!"0M```0Z(77_O^0C70F`.G;_O__C70F`(V\)P````!5B>6#[`B+ +XM10B+0`2)!"3H[/W__X-(#"#)PXVV`````%6)Y593@^P0BS6`=PH(A?9T5/=& +XM#`(!``!T".M)C78`BW8$BT88.T8<=?6+1A2)\\<$)`?<"`B)1"0$Z%`R`@"+ +XM0QC'!"0\W`@(B40D!.@],@(`BUL$.=YUYL<$)`H```#H2O7__\<%@'<*"``` +XM``#'!8AV"@@`````@\006UY=P^L-D)"0D)"0D)"0D)"0D%6)Y5=64XG#@>RL +XM````B95D____BT`8.T,<=`^-="8`BUL$BT,8.T,<=?4Y6P0/A)`'``"+A63_ +XM__^)WHN59/___\>%=/_________'A7C___\`````@^`0B46`BX5D____@>*$ +XM````B56(BY5D____QX5P_________X/@`HE%A(N%9/___X/B`8F58/___X/@ +XM!(F%7/___XVT)@````"+1@R+E7C___^)QPG"@>%?/___R3<"`B%P'4*QX5\____^]X("#N]MP(".@# +XM,`(`C48@B40D#(U&*(E$)`B-1C")1"0$QP0DH&$)".AR6@``B?:+1@0YPW0) +XMB<;IC]___'!"0@````Z"+R___IK?[___:%9/__ +XM_P@/A8("``#VA63___]`#X2Y_O__H629"PB+0`R)1"0$BT,(BT`,B00DZ&53 +XM_O^%P`^$E_[__Z&`F`H(QT0D#'/<"`C'1"0("@```,=$)`01````B00DZ/PT +XM__^)!"3HE"X"`(M#"(M`#(D$).BFH?[_QP0D><((".AZ+@(`Z4O^__^0C70F +XM`#L=/'<*"+@K````=!0QP#L=<)D+"`^4P(/H`8/@\X/`+8M6%+D=W`@(@_H) +XM?@6Y12-1BB)1"0$B10DZ(-4``"+1>PY1>1UMHM%Z#M% +XM\`^?P.NNC47LQT0D#(!A"0B)1"0(B7PD!,<$)*!A"0CHT50``.FJ^O__BT,, +XM]L1`#X1D^/__@.2_@\A`B4,,Z5;X___'!"07W`@(Z!8J`@#I+/___Y!5B>56 +XM4X/L$(MU"(M=#(,%T*P+"`''1"0$L)`(",<$)-"L"PCHE]'^_XGPZQ"-=@"` +XMS@&)4`R+0`0Y\'0IBU`,]L(#=/&)T8/)`8G*@^+]A=N)4`QUVH'A_?[__XE( +XM#(M`!#GP==>%VW5#B?#H?_'__[H+````B?#HD_?__\=$)`03````BT8(D$).C,<$)(0``!")1"0$Z!W-_O^+5@2%TG6DC;8`````@\006UY= +XMPXGVC;PG`````%6)Y5=64X/L#(LUC'8*"(M5"(7V=`K'!8QV"@@"````C4($ +XMBU($OP<```"%TG08BU@$A=MT=,<$)#@```"_5P```.BYS/[_BPTPF@L(A7UW#B=CH&/+__^OD +XMQT0D!*PX"0AFOU<`B10DZ!Y,_O^%P'2%Z6____^)]HV\)P````!5B>53@^P4 +XMBQT`F`H(QP50F@L(`````(7;=0OK68UV`(L;A=MT4&:#>PP`D(UT)@!Y[H,% +XMT*P+"`''1"0$L)`(",<$)-"L"PCHT\[^_[H'````B=B!8PS_?___Z!#U__^H +XM`W08QP0DT*P+".@0SO[_BQN%VW6P@\046UW#B=CH;?'__^O?C70F`(V\)P`` +XM``!5B>575HG&4X/L+(7`B578="V+`(7`=">)\^L/C70F`(/#!'0:BP.%P'04 +XM@S@EB?9U[HD$).A&S?__@\,$=>:)-"3HN7K__\=$)`3P(P8(B<>)!"3H-\[^ +XM_X,%T*P+"`''1"0$L)`(",<$)-"L"PCH',[^_Z&4=PH(A<`/A08"``"%_P^$ +XM6`(``(L?A=L/A$X"``#'1=P`````QT7@`````.MG@_A_=W3V!(6]40D(!'1J +XMB1PDZ+9&`@"-5?#'1"0("@```(E4)`2)!"3HJTW^_XG#BT7P@#@`#X2!```` +XMQP0D.0``$.BURO[_@WW8#P^$+`$``(-]V`$/A"(!``"#QP1T+XL?A=MT*8L# +XM@_@E#X2.````J0```$!TAX/X+9!TD,<$)#D``!#H7UW#C;8`````BTW8B1PD +XMB4PD!.A]2?[_A<`/B73____H($W^_XL`B00DZ,9*_O^)7"0$QP0DJ=P("(E$ +XM)`CH1B4"`(-%X`'I7/___XD<).B%\/__B<:-=@"+4`P)5=R+0`0YQG7S@WW8 +XM%G<<#[9-V+@!````T^"I``!F`'1A]D7<`0^$R````(M%V(E$)`2+1AR)!"3H +XM*T_^_X7`#XCY````@WW8#W0*@WW8`0^%]O[__\=$)`03````BT8,<$ +XM)(0``!")1"0$Z![)_O_I>/[__X,%Q*P+"`''1"0$L)`(",<$),2L"PCH[LO^ +XM_^G:_?__H8"8"@C'1"0,BMP(",=$)`@,````QT0D!!$```")!"3H="K__XE< +XM)`2)!"3H""0"`(-%X`'I'O[__\<$)-"L"PCH`\O^_^E@_O__Z*5+_O^+`(D$ +XM).A+2?[_B5PD!,<$)*'<"`B)1"0(Z,LC`@"#1>`!Z=O^__^)]E6)Y5=64X/L +XM'(M5"(M"!(UZ!(7`=`6#."UT%KL/````B=J)^.BW_/__@\0<6UY?7<.-<`2+ +XM0`2#^&QT=X/XNIQP0D"@```.B[Y?__Z?_^__^+0@B-2@B%P'1AB<^)QND(____]@2%O5$) +XM"`0/A`S___^)-"3H_4("`(U5\,=$)`@`````B50D!(D$).@22?[_B<.+1?"` +XM.`!U#87;>`F#^Q\/CBK____'!"0;```0Z//&_O^-=@#I%O___\<$)`X``!#H +XMW\;^_^F?_O__C78`C;PG`````%6Z$0```(GEBT4(78/`!.D<^___C;8````` +XMC;\`````58GE@^P8B5WXB<.)=?R+`#L%($,)"'1YB1PDZ!Q'_O^)QJ%08PD( +XM@_A/=RT!\(/X3W8PQT0D!,@]"0BA5&,)"(D$).CT1?[_@P548PD($,<%4&,) +XM"%````"+7?B+=?R)[%W#B5PD!*%48PD(B00DZ,A%_O^-!+4``````3508PD( +XM`0548PD(BUWXBW7\B>Q=PX/#!.N"C78`C;PG`````%6%P(GE5HG&4P^$P0`` +XM``^V!CP"#X3M````=WHL`8GV#X2N````BU8$]L($C70F`'4EBT8(A!B+1@2#X`&#^`$9P"4``0``@\`!B4,,BU8$]L8@=`F`S$")0PR+5@3V +XMQD!T"H%+#````0"+5@1FA=)Y!X%+#````@")\,<%5&,)"`!B"0C'!5!C"0@` +XM````Z/O]__^A5&,)",<``````(/`!*-48PD(]D8$"'02BU,,B="`S`B)0PR` +XM?@0`>'N0QP0D`&()".B$/0(`B4-XH8!W"@B%P'1MQT,(`````*&`=PH(BT`4 +XMB4,4H8!W"@B)0P2A@'<*"(M`&(E#'(L5@'<*"(G1ZP*)PHM"!#G!=?>+#0"8 +XM"@B)6@2-0R")"XD=`)@*",=%#`````")10B#Q`Q;7E]=Z9)$_O^`S@R)4PSI +XM>____XD=@'<*"(E['(E;!*%DF0L(B4,(H629"PB#0`@"H3":"PB#^`A_+8L- +XM`)@*"(/``:,PF@L(B4,4BS4\=PH(A?9T28L5<)D+"(72=8B)'7"9"PCK@(L- +XM`)@*"+X!````ARA@)@*",=$)`S( +XMW`@(QT0D"`$```#'1"0$$0```(D$).A$'___B00DZ-P8`@"+6P0Y\W6_C5W( +XMB1PDC7VXZ&-"_O_'1"0$`@```(D<).AC/?[_QT0D!!0```")'"3H4SW^_XU% +XMV(E$)`B)7"0$QP0D`0```.CL//[_C478B00DQT0D!&`>!0CH+<#^_XM%V(E% +XMN(M%W(E%O(M%X(E%P(M%Y(E%Q,=$)`04````B3PDZ.%"_O^0C70F`.@K,`(` +XM,=N)\(VT)@`````+6`R+0`0Y\'7V]L,!=`J)/"3HI4+^_^O7C478B00DZ"R_ +XM_O^AU)<*"(7`?A")1"0$QP0D#P```.C?._[_]L-2#X3T`0``]L,"#X4E`0`` +XMNJ````")\.CEY?__]\,"(```=`Z+/91W"@B%_P^%C@$``(GR,=L/MD(0A,!T +XM$O="#!`@```/MMAT!H/(@`^VV(M2!#GR==^%VP^$@0```,=$)`3$F`H(QP0D +XMP#P)".@^)@``A7]___H>ES^_XGPZ%/@ +XM__^#Q%Q;7E]=PZ&`F`H(QT0D#+W<"`C'1"0(`@```,=$)`01````B00DZ`8< +XM__^)7"0$B00DZ)H5`@#I%?[__XGPZ`[@___I564X/L$(M=".A`W?__BT,$B=[K/L=#&``` +XM``#HJ3S^_XL`B00DZ$\Z_O^)1"0(BT-XQP0DA```$(E$)`3HC+G^_XM&!(7` +XM=#>+1@B#Q@2%P'0MB00DZ`/@___'1"0$`0```(G#B00DZ)'J__^%P'2DB1PD +XMZ%7[__^+1@2%P'7)@\006UY=PXVT)@````!5B>564X/L$(L=`)@*"(7;=%2^ +XM`)@*".L/C;0F`````(L8B<:%VW0^BTL8B=B%R77OBP.)!HM#>(D$).APQ@$` +XMBU,(A=)T#8M""(/H`H7`B4((=":)'"3H5,8!`(GPBQB)QH7;=<*A@'<*"(D$ +XM).C-^O__@\006UY=PXM#"(L0A=)UT8D$).AE>/[_Z\>-=@!5B>575E.#[&R- +XMM"8`````Z)<[_O_'``````"+-91W"@B%]@^$7@(``(L=P'8*"(7;=0Z+#?Q= +XM"0B%R0^$1@(``+@#````C56HB40D!(U%\(E4)`B)!"3H<#C^_XG"C4`!@_@! +XM#X8S`@``BS4`F`H(A?9U".N:BS:%]G24.U88D'7TBTX,B"$``(D$).CP,@(`B00DZ)0U_O\YPP^,]0`` +XM`(M'#(/(0(E'#`E%H(M_!#GW=8N+5@R)T(#D_CMV!(E&#`^$G@$``/=%H`$0 +XM```/A3S^__^)\XM##*@"=`:`S!")0PR+6P0Y\W7LBT,8.T,<=`N+6P2+0Q@[ +XM0QQU]8M]H(/G`@^$?`$``*$\=PH(A^__^)0P3'1"0(`0```,=$)`0"````B00DZ.@S +XM_O^+`X7`>!6+4P2%TG@&@\046UW#B00DZ+&Y__^+0P2%P'@(B00DZ**Y___' +XM10@U````@\046UWI,;3^_Y!5B>6#["C'1"0$Q)@*"(E=](G3B7W\B<>)=?C' +XM!"1@1@D(Z/D=``"%P`^$A@```(D<)(U=[.C6L?[_QT7P`````(D<)(E%[.BT +XM3O__ASH[<`!`.N;B1PDZ%.Q_O_'1"0$,"H("(G#B00DZ%&V_O_' +XM1"0$`````(D<).@18___B1PDB47LZ):U_O_I8?___XM%[(D$).@&+P(`HR!W +XM"@B+1>R)!"3HEL`!`,<$)#$``!#H&K/^_^E7____D(UT)@!5B>575E.![.P` +XM``"+?0B%_W1JBS70F0L(A?9T,XL=P'8*"(7;=0J+#229"PB%R70?BU4(BT(0 +XMABS7H=@H(A?9T"8MU"/9&!01T%8'$[````%M>7UW##[8!_R2%\-P( +XM".@9N/__@<3L````6UY?7<.+70B+0Q"+,(L&)?___W\]````0`^$I@\``(#F +XM!`^$*P\``(M5"(M"$(LPA?9TK(M2!/;""`^%A@(``(#F`@^%1`(``,=$)`@" +XM````QT0D!!`O"0C'!"3T+@D(Z$XE``"+50B`.@$/A90```"+30B+<1"+'L=$ +XM)`0,2`D(B1PDZ,8Q_O^%P`^%5@$``(M&!(7`#X2(!@``BP#'!"3JW`@(B40D +XM!.B1,_[_A<`/A+$!``"+3@B%R0^$8P8``(M=",<%('<*"/31"`B+0Q"+0`2) +XM!"3H]QD``(A#`<=$)`0"````BT,0B00DZ.&W__^!2P0`"```BU4(@#H!#X1L +XM____H2AW"@C'1?``````A<`/A;3^__^+1?"%P'0PBT7P@7@$`/D$"`^$50<` +XM`(M%\(%X!&#V!`@/A$4'``"+1?"!>`2@[00(#X0U!P``BT4(BW`$]\8`(``` +XM=1[WQA`````/A2H'``"+1?"%P'0+9O?&"9@/A!@'``"+50B`.@)T$X'F`00` +XM`'4+BT7PA<`/A,$*``"+10R%P'@-H5AC"0B%P`^$V`T``(M%#(E$)`2+30B) +XM#"3H]NW__X7`#X7""0``H5AC"0B%P`^%2PH``(M%"(MP!,>%'/___P$```#I +XMR@8``,=$)`3D1PD(B1PDZ%@P_O^%P'4JBU8$A=(/A!X%``"+30B!200`$``` +XMQT0D!`$```")-"3HL[;__^E`_O__QT0D!/Q'"0B)'"3H&C#^_X7`#X4&!@`` +XMBT8$A<`/A-P$``"+70B!2P0`@```QT0D!`$```")-"3H<;;__^G^_?__BT4( +XMQD`!!,=$)`0!````B30DZ%6V__^+50B!2@0`"```Z=C]___'!"0`````Z#JU +XM__^+50B+0@B)!"3HS*+^_XL=*'<*"(7;#X24_?__QP0D`````.@2M?__Z8/] +XM__^+712)'"3HPOK__XMU"(M6!.ED_?__BW4(@#X"=`^+11B)-"2)1"0$Z"#B +XM_O_'1"0$$P```,<$)`````#HS+C__\=$)`@!````QT0D!`(```"C1)D+"(D$ +XM).C++O[_QT0D!!$```#'!"0!````Z)NX___'1"0(`0```,=$)`0"````H\R7 +XM"@B)!"3HFB[^_Z',EPH(B00DZ)TT_O_'1"0$$@```,<$)`(```"CX'4)".A8 +XMN/__QT0D"`$```#'1"0$`@```*,$=@H(B00DZ%AV"@@`````BT$$ +XMBU$4@^`@"4($BT4,BUT8B10DQT0D#`````")1"0$B5PD$,=$)`@`````Z`C[ +XM___H\T_^_XMU"(U=Z(M."(M6!(M!!('BI0```(/("`G0B4$$BU48BT4,B5PD +XM#(E4)!"+=1")1"0$B0PDB70D".C%^O__BT4(BW4(BT@,BU8$BT$$@^(Y@\@$ +XM"=")002+51B+10R)5"00BW44B5PD"(E$)`2)#"2)="0,Z(KZ___I[_K__XM% +XM"(M("(7)=%"#XB`)402+10R+51B)#"3'1"0,`````(E$)`2)5"00QT0D"``` +XM``#H3_K__XM-"(M!"/9`!`%T&(M1#(72#X2B^O__]D($`745B?;HZ]7__XM= +XM"(M3#(72#X2'^O__BW4(BT8$@^`P"4($BT4,BU48QT0D#`````#'1"0(```` +XM`(E$)`2)5"00BT8,B00DZ.CY___I3?K__XM="(M+"(7)=%N#XB`)402+10R+ +XM=1B)#"3'1"0,`````(E$)`2)="00QT0D"`````#HK?G__\=$)`3$F`H(QP0D +XM]"X)".CY%@``B00DZ`$5``"%P`^4PH`[!@^4P#C"#X7[^?__BT4(BU`,A=(/ +XMA-KY__^+0`2#X#`)0@2+10R+71C'1"0,`````,=$)`@`````B40D!(E<)!") +XM%"3H0?G__^FF^?__B00DZ%2M__^#Z`&0#X5Z^?__BSTH=PH(A?\/A6SY__^+ +XM30B+01"+`(D$).B\80``A<")A2#___]T"8,X?@^$;PX``(N%(/___XD$).C+ +XM)P(`BY4@____B10DB%`20H@4(='R+1?"!>`3@H04(='"+1?"!>`30H@4(=&2+1?"! +XM>`1`M04(=%B+1?"!>`20H04(=$R+1?"!>`3PI@4(=$"+1?"!>`3PI04(=#2+ +XM1?"!>`3@GP4(="B+1?"!>`1@H`4(=!R+1?"!>`0@HP4(=!"+1?"!>`10?`4( +XM#X7J]___BUT(@#L!#X4J^?__BT7PA<`/A1_Y__^%T@^%%_G__Z'`=@H(A<`/ +XMA`KY__^)'"3H;.O__\=$)`0P*@@(B<.)!"3H.JW^_XD<).@2Y`$`B1PDZ(JL +XM_O_IV_C__Y"-="8`QT0D!'0\"0B)'"3H_"G^_X7`#X7)_O__BT8$A<`/A+[^ +XM__^+10B!2`0`(```QT0D!`$```")-"3H4[#__^G@]___BW4(@68$__?__^F\ +XM^/__BT7PA%'/___P````"AZ'8*"(7`#X4=`@`` +XM]\8`!```#X41`@``]\8``@``#X7<````BU4(BT((A<`/A.\)``"AM'8*",=$ +XM)`0`````B00DZ-JR__^AS)<*",=$)`0!````B00DZ,6R__^A!'8*",=$)`0" +XM````B00DZ+"R__^+30B+40B)R.@3]?__B<.)!"3H"24"`(D$).A!M/__B1PD +XMBL_O_'1"0$`````(D\).A'K/__A<")PP^( +XMI@H``(D\).A%J_[_QT0D!`,```")'"3H82C^_\=$)`0$````B1PDB40D".A- +XM*/[_QT0D!`````")'"3H<;+__XM%"(M0#(72#X2;!@``Z'[T__^)PXD$).AT +XM)`(`B00DZ*RS__^)'"2)Q^@"M@$`QT0D!#`J"`B)/"3HD```#'1"0$Q)@*",<$),`\"0CH0!$``(7`#X2B]/__QT0D!,28"@C' +XM!"3T+@D(Z(01``")!"3HC`\``(7`B<,/A'ST__^A@)@*",=$)`R]W`@(QT0D +XM"`(```#'1"0$$0```(D$).B="/__B5PD!(D$).@Q`@(`Z4;T__^+=0B+5@3V +XMP@%T"*-L=@H(BU8$BQWH=@H(A=MU)O;"!'0ABU40BP*)!"3H':S__XM-$(M! +XM!(D$).@/K/__BUT(BU,$]L((#X7Z\___H5AC"0B%P`^%2@0``(/B`0^%Y//_ +XM_^A%[?__D(UT)@#IU?/__^A62/[_C;8`````Z<7S__^+1?"!>`2P@04(#X6/ +XM_/__Z5_U___'1"0(`````,=$)`1@8PD(QP0D`P```.C6)?[_BUT(QP588PD( +XM`````(MS!,>%'/___P$```#I6?S__XM%#(7`>!B+/5AC"0B%_W4.BS4H=PH( +XMA?8/A"`(``"-7=B)'"3HS2K^_XD<),=$)`04````Z,TE_O^)'"3'1"0$`@`` +XM`.B])?[_C47(B5PD!(E$)`C'!"0!````Z%8E_O^AY'4)"(L5E'<*"(L-P)@* +XM"(L=Z'8*"(LUM'8*"(F%)/___Z',EPH(B94H____BQ4$=@H(B8TL____BPU$ +XMF0L(B9TP____BQW4EPH(B;4T____BS7@=0D(B84X____H?R9"PB)E3S___^+ +XM%6QC"0B)C4#___^+#6AC"0B)G43___^+'61C"0B)M4C___^+-6!C"0B)A4S_ +XM__^A6&,)"(F58/___XF=6/___XF-7/___XFU5/___Z-<8PD(QP7$=@H(```` +XM`,<%3)D+"`````"+'>A="0C'!;AV"@@`````QP51U"0@!A<`/A`T%``"%V\<% +XME'<*"``````/A!0'``#'1"0$`0```,<$)`(```#H;"C^_\=$)`0!````QP0D +XM`P```.A8*/[_BT4,A;Q__^- +XM7@2)'"3H+R/^_XDT)(E<)`2-!(4$````B40D".AX)_[_BW4(BU8$Z2WP__^A +XM!'8*"(D$).@0(_[_H?R9"PC'1"0(`````,=$)`0"````QP0D`@```*-LF0L( +XMZ,HA_O_IH?K__\=$)`@`````QT0D!&!C"0C'!"0#````Z,DA_O^+=0C'!5AC +XM"0@`````BU8$Z87[___WQ@@````/A"@"``#'!"0!````Z&"G__^+312+002) +XM!"3HCB+^_\<%?)@*"`````#I#_K__\=$)`0)````B3PDZ!.E__^#^/^)PP^% +XMR_G__^E\^?__C47(QT0D"`````")1"0$QP0D`P```.A$(?[_QP0D,````.B< +XMH?[_BX4D____BY4H____BXTL____B[4P____H^1U"0B+A33___^)%91W"@B+ +XME3C___^)#<"8"@B+C3S___^)->AV"@B+M4#___^CM'8*"(N%1/___XD5S)<* +XM"(N52/___XD-!'8*"(N-3/___XDU1)D+"(NU8/___Z/4EPH(BX5<____B17@ +XM=0D(BY58____B0W\F0L(BXU4____B35L8PD(HVAC"0BA7&,)"(D59&,)"(D- +XM8&,)"*-88PD(H4R9"PB)!"3H1:X!`*'$=@H(QP5,F0L(`````(D$).@NK@$` +XMH;AV"@C'!<1V"@@`````B00DZ!>N`0"A7)D+",<%N'8*"`````")!"3HP*?_ +XM_XMU",<%7)D+"`````")'"2)="0$Z.?;__^-1_G__\=$)`3$F`H(QP0DH$$)".@P"@``A<`/A/WW__^+ +XMA5#___^%P`^%)@(``(V%:/___XE$)`2)/"3HA"+^_X7`#XC5]___#[>%!U"0C'1"0(`````,=$)`0"````QP0D`0`` +XM`*-\F`H(Z"$?_O_IS/?___?&!`````^%S````/?&(````'0-@SW4EPH(_P^$ +XM30,``,<$)`````#HTZ3__Z%$F0L(B00DZ`(@_O_'1"0(`````,=$)`0"```` +XMQP0D`````.C&'O[_Z83V___HG"7^_XG#Z7?Z__^#/=27"@C_#X5_^___BU4( +XM]D($(`^$ +XM_O_II_;__\<$)`````#H'*3__XM=$(L#B00DZ$L?_O^+`XD$).@%I/__BT,$ +XMB00DZ/JC___IU/7__\=$)`0`````QP0D`0```.C-(O[_BT4(BW`$Z?/Z___' +XM1"0$`0```,<$)`$```#HKB+^_XM="(MS!.G+^O__Z$XA_O^+`(D$).CT'O[_ +XMB7PD!,<$)#8```")1"0(Z#2>_O_I,O7__\=$)`@`````QT0D!&!C"0C'!"0# +XM````Z*\=_O_'!5AC"0@`````Z5_Y___H^R#^_XL`B00DZ*$>_O^)?"0$QP0D +XM-@```(E$)`CHX9W^_^FR_?__C5W8B1PDZ*TB_O_'1"0$%````(D<).BM'?[_ +XMQT0D"&!C"0B)7"0$QP0D`0```.A%'?[_QP588PD(`0```.F>]___B<+'1<@` +XM````@\($QT7,`````,=%T`````"+0`2%P`^%F@```(G6QT0D!,28"@C'!"20 +XM+PD(Z*\'``")1"0$C47(B00DZ)`5`@"-7?X__^+10BS`?9`!"`/A7KX__^-="8` +XMZ4_X__^#^"\/A%W___^)UH/&!(L&AZZ7H8Q_^_XL`A<"-=@!U98M="(MS +XM!,>%'/___P$```#IA_+__P^VP(/(@.GC^/__Z&4B_O^)QNG8]___QP0D```` +XM`.B&H?__QT0D!`````#'!"3,L0@(Z%*?___I3//__XU%R(E\)`2)!"3H/A0" +XM`.EX____Z/`>_O^+`(D$).B6'/[_QT0D!+'<"`C'!"0V````B40D".C2F_[_ +XMBT4(BW`$QX4<____`0```.G[\?__C;8`````C;PG`````%6)Y8/L",<$)`$` +XM``#HNB#^_Y"0D)"0D)"0D)"0D)"058/X"8GE4XG#=A&ZSH#B=#H +XMY/___XG8NLW,S,R+#71C"0CWXHU!!,'J`XT4D@'2*=.-4S")$5M=HW1C"0C# +XMC70F`(V\)P````!5B>575E.)PX/L"(E-[.LFQT,8`0```+@!````C70F`(7` +XMBU7PB?L/E,`/ML`[1>P/A9H```"+>Q2%_P^$CP```#'`.5\0#Y3`.U7LB47P +XM=!^+0QB%P'2X@_@!="B#^/]UOC'`QT,8`````.NSC78`BT,8A12%P(E#$'0&BT$,B5@4B5D, +XMB4L4BT7PB4R'#(M!#,=`&`$```"X_____\=!&/_____I4O___XGV@\0(6UY? +XM7<.#^`%TA8/X_P^%.O___XMS#(M6&(72#X7_````BT80B7X4A<")0PQT!HM& +XM$(E8%(E>$(ES%(M%\(ETAPR+1A#'0!C_____N`$```#'1A@!````Z?'^__^# +XM^@$/A(,```"#P@$/A=_^__^+<0R+012+5A")1A2+0Q"%THE0#'0)BU80BT,0 +XMB4(4BT,0B480B7`4BT,4B7,0B484BT8,A<")0Q!T!HM&#(E8%(E>#(ES%(M% +XM\(ETAPPQP(M6#(-^&``/GL"#Z`&)0AB+1AB+5A#!Z!^)0A@QP,=&&`````#I +XM9?[__XM!#(EY%(7`B4,0=`:+00R)6!2)60R)2Q2+1?")3(<,BT$,QT`8```` +XM`#'`QT$8`````.DM_O__@_H!=$&#P@$/A1_^__^+1A")?A2%P(E##'0&BT80 +XMB5@4B5X0B7,4BT7PB72'#(M&$,=`&``````QP,=&&`````#IY_W__XM.$(M& +XM%(M1#(E!%(M##(72B5`0=`F+40R+0PR)0A2+0PR)00R)2!2+0Q2)2PR)012+ +XM01"%P(E##'0&BT$0B5@4B5D0B4L4BT7PB4R'##'`BU$,@WD8``^>P(/H`8E" +XM&(M!&(M1$,'H'XE"&#'`QT$8`````.EM_?__C;8`````C;PG`````%6)Y5=6 +XM4X/L'(M%"(M]#)")QHM`#(7`=?>+5A2%T@^$B@```(5^"'1?H91W"@B%P`^% +XM@````(L&B00DZ%"9__^)PXM&!,<$)`S="`B)1"0$Z&OS`0"#ZP%T=\<$)"@` +XM``#H>K;__XL&B00DZ*"D___'!"0I````Z&2V___'!"0*````Z%BV__^+1A"% +XMP'6!BT84.W`0=0J)QHM&%#MP$'3VB<:+5A2%T@^%=O___X/$'%M>7UW#C47P +XMB00DZ'\+`@"-1?")!"3H!)K^_^EE____BP:)!"3H-:3__^N?C78`58GE5E.# +XM[!"+70B%VP^$W````(L3@_HKB=`/A*`````Q]H/X+8G"=&WWP@```$`/A;8` +XM``"#^G\/AZT```")V3';]@25O5$)"`1U%^F:````@_I_=Q^#P03V!)6]40D( +XM!'02C02;C5Q"T(M1!/?"````0'36_O^+ +XM$^EI____BT,$,?:-2P2%P`^$6?___XG+Z4G____V!)6]40D(!&:^`0`/A57_ +XM___KO3';ZX;'!"0)```0Z*66_O_I$____U6)Y5.)TX/L!,<"`````(M(!(U0 +XM!,<``````(7)=$_WP0```$!U3(/Y?W=']@2-O5$)"`1T/8L#ZR*-M@````#W +XMP0```$!U*X/Y?Y"-="8`=R'V!(V]40D(!'07C02`@\($C41!T(D#BPJ%R772 +XMC5H$ZPB#^5V-6@1T#,<$)`@``!#H&9;^_XG8@\0$6UW#D%6)Y5=64X/L#(M% +XM#(M]"(M8#(7;="Z+-^L1C;8`````AR)5"0$ +XMB3PDZ*P5_O^%P'7<@\0,B=A;7E]=PXGVBUL,Z]*-="8`C;PG`````%6)Y8/L +XM"(M5"(M%#(72="*%P'0>B40D!(D4).B`____A6#[!C'1"0$Q)@*"(E=](EU^(G&B7W\B=>)!"3H +XM/?___X7`B<-T+87_?@Z+`XD$).A)EO__.<=^#,<$)"L``!#H*97^_XG8BW7X +XMBUWTBWW\B>Q=PXDT).A2G/__Z\E5B>53@^Q$BU4(C5W(B1UT8PD(A=)Y$8U% +XMS/?:QT7(+0```*-T8PD(B=#H4?G__Z%T8PD(QP``````B1PDZ'X.`@"#Q$1; +XM7<.0C;0F`````%6)Y5=6B<93@^P,BP")!"3H:YO__XM&!(D$).@0H@$`BTX0 +XMA +XM7UWI_/C__XM.#.O'BUX4.W,0#Y3`#[;XB4R[#.O)D(UT)@!5B>6#[!B)=?R+ +XM=0B)7?C'1"0$Q)@*"(DT).CQ_?__A<")PW00BW7\B=B+7?B)[%WI*____XDT +XM).@CF___Z^:058GE5HG&4X/L$(M:#(7;=0GK+XM;$(7;="B+2PR%R9!T#8G: +XMB?#HU?___X7`=16)="0$BT,$B00DZ,))__^%P'31B=B#Q!!;7EW#D(UT)@!5 +XMB>575E.#[`R+=0B+?0R+1@2%P'1*,=OK'(VV`````(M`!,<$)(,``!")1"0$ +XMZ%V3_O^+1@2)^NAS____AB$_O__@\,!D.OAA=MT$H/&!(M& +XM!(7`=;:#Q`Q;7E]=PXM&!(D$).CM#@(`HR!W"@CKW(VV`````%6)Y5=64X/L +XM#(M=",=$)`3$F`H(QP0DX$8)".C@_/__QT0D!,28"@C'!"2`,0D(BF5\?[_D(UT)@#'1"0$ +XMQ)@*",<$)(`Q"0CHS/K__X/X`1G`]]`A!8AW"@CKBZ'4F0L(HTQW"@CISO[_ +XM_\<%C)@*""$```#'!42:"PA>````Z1K^__^0C70F`,<%-)H+"#X```#'!8QW +XM"@@C````Z3G^__^-M"8`````Z-N5``#IR+.NL5A<`/G\`/ML")1?"+1(8,A2)>Q3'0Q@`````QT,0```` +XM`(E#"(GXQT,,`````(M5\.@O]/__BU7HB1.)50B#Q!Q;7E]=Z?LI__^)7"0$ +XMQP0D@P``$.A+C_[_Z63___^-M@````!5B>575E.#[#R+712+10B+50R+31") +XM7"+7=2+1(L$@\$! +XMB4W@A# +XM1>P!BTW@.4WL?3V+?>R%_W[MBUWLBT74BSR8ZZ;V1")UC'`@^D! +XMB4WDZQ&-6`$[7>`/C,(```"#Q@2)V#M%Y'SJBW7@,-=@"+7=2+ +XM!(N%P'0&B023@\(!@\$!.TW@=>@[5>!]%XM-U(T$D<<``````(/"`8/`!#M5 +XMX'7O@V7,GXM=S(M%T(M5U(M-V(E=%(E%$(E5#(E-"(/$/%M>7UWI=/W__XD4 +XM).B,*/__A<`/A)[^__^)1"0$BT74B00DZ#4\__^%P(G#=':+3=2)#"3H5)3_ +XM_XE=U.EV_O__B3PDZ/2:`0"+5=S'`@````#I__[__XE=\(EUZ(M^_(7_=!F+ +XM5>B+`H7`=!")?"0$B00DZ#`-_O^%P'06@T7P`8M-X(-%Z`0Y3?`/C03____K +XMRHD\).BBF@$`QT;\`````.O9BU74B10DZ-Z3___'!"0Q```0Z!*-_O_I;O__ +XM_XVV`````(V\)P````!5B>6#[!C'!"0(````Z"Z;`0"+50S'0`0`````B1"+ +XM51")1"0$BT4(QT0D",28"@B)5"0,B00DZ(3]___)PXGV58GE@^P8BT4,B5WT +XMB77XBW40B7W\BWT(B00DZ%`&`@#'1"0$,"H("(G#B00DZ'Z/_O^)="0(B5PD +XM!(D\).A^____B1PDZ!:/_O^+=?B)70B+??R+7?2)[%WILH[^_XGV58GE@^P8 +XMBT4(QT0D"`(```#'1"0$^&\)"(D$).A_____R<.-M@````"-O"<`````58GE +XM5XG'5E.#[!S'1"0$E#()"(D$).CQ"_[_A<`/A=,```#'1"0$Q)@*",<$))0R +XM"0CHZ?7__X7`#X1/`0``BP"-=>C'1>@`````QT7L`````,=%\`````"%P'1+ +XMBQ"%TG1%B7UW#QT0D!``_"0B)/"3H!@O^_X7`=2C'1"0$Q)@* +XM"(D\).AF]?__BQ")%8R8"@B+0`2C1)H+"(/$'%M>7UW#QT0D!$`_"0B)/"3H +XMR@K^_X7`="#'1"0$@#\)"(D\).BV"O[_A#^G]W4O8$E;U1"0@$=$BA<&,)"(/!!(T$@(U$0M"C<&,) +XM"'7-H7!C"0B%P`^/T?O__^LMQT0D!&!`"0B)/"3HH0;^_X7`=2C'!6QW"@@! +XM````Z:S[___'!7!C"0@`````QP5P8PD(&@```.F3^___QT0D!``V"0B)/"3H +XM90;^_X7`=0KHX$G^_^EU^___QT0D!.!&"0B)/"3H1P;^_X7`=0SHTBH``(GV +XMZ57[___'1"0$H$D)"(D\).@G!O[_A@#BP``C78`Z97Z___'1"0$P#0)"(D\).AG!?[_AA"Y?[_B?;H +XM&^;^_^EP^O__QT0D!,P^"0B)/"3H0@7^_X7`#X58^O__QP7T8`D(`0```.E) +XM^O__ZPV0D)"0D)"0D)"0D)"058GE5E.#[!"+10B+<`2%]G1.B30DZ-:&___' +XM1"0$Q)@*"(DT).@&[___A<")PW0WBP"%P'0QBP"%P'0[QT0D!`$```"+`XD$ +XM).A2B___@\00B?!;7EWIM?C__Y"-="8`OB0V"0CKLXDT).@1C/__BP.+`(7` +XM=<7'!"0*```0Z+V$_O_KMXUT)@"-O"<`````58GE@^PXB5WT@_@]C5W4B7W\ +XMB<^)=?B)7?`/A(````"+"H7)=6"-3=B)WHU5W(U=Z(/X/(E%Z,=%[`````") +XM'G12@_@^=$V).8U%\,<"`````(D$).A&U/[_B<.+1?"+`(7`=`S'!"0A```0 +XMZ#^$_O^)'"3H)^___XM=](MU^(M]_(GL7<.)5=2-==B-3=R-5>#KFHD9B=&# +XMP@3KJHUV`(U5V(G9ZZ")]HV\)P````!5B>6#[!B)=?R)UHE=^(L8A=MT((D$ +XM).B4_0$`BQ:)PXU"_(D&BT+\B00DZ$"1`0"+!HD8B30DZ+33_O^)!"3HK.[_ +XM_XM=^(MU_(GL7<.)]E6)Y8/L&(E=](G3B7W\B77XB4WPZ"?N___V0`@!B<=T +XM$XM`!,<$)(,``!")1"0$Z'R#_O^+!\'C`HMT`_S'1"0$,"H("(DT).A3AO[_ +XMBP?'1"0$`@```(/H!`'#BT7PB00DZ`DS__^)`XDT).B/A?[_BUWTBW7XBWW\ +XMB>Q=PXGV58GE5U93@^P\BT4(@\`$B44(BQ"#P`2)10B%THE5S`^%2@$``.GS +XM`@``C;8`````BT4(BQB%VP^$=`,``(/`!(E%"(L[A?\/A8,!``#'!"0E```0 +XMZ->"_O^-M"8`````BP.%P'4-BT4(BP"%P`^$5P,``(M%S(D$).AB_`$`QT0D +XM!#`J"`B)1=")!"3HCX7^_X/_/0^$0@(``(LSC5,$B57@QP0DZMP("(ET)`3H +XM7H/__X7`#X1S`@``.?YU!XM#!(7`=`S'!"0F```0Z%^"_O_'!"08+PD(Z`/\ +XM`0")P\=$)`0P*@@(B1PDZ#&%_O^+==2%]@^$A@$``(M5\(M%T.B[[/__B=F+ +XM$(M%\(M4@OR)^.AI_?__QT0D!#`J"`B)PXD$).CWA/[_BU7PB=F+1=#H2O[_ +XM_XD<).B2A/[_B1PDZ#J$_O^+1=#HLO7__XM-T(D,).@GA/[_BT4(BQ"%THE5 +XMS`^$O`$``(/`!(E%"(M-S(LY]\<```!`=2F)^`^VP#W_````B478#X?U`0`` +XMH>!="0B+5=B+1)`T]L0!=4"#_U]T.XMUS,<$)!T``!#H?('^_XL^QT74```` +XM`(/_6P^$H````(7_B?,/A&#^___'`P````"#PP3I@O[__XGVBPW@70D(B?N+ +XM=7UW#B7PD!,<$)-3'"`CHTX#__X7`="`Y_G00QP0D)@``$(UT)@#H +XMVW_^_\<$)````!#HSW_^_X/^/70,QP0D)@``$.B^?_[_BT7@C54(Z+/[__^) +XMP^E;_?__B00DZ+#__?^-="8`Z0;^__^+3=#'1"0(`@```(E<)`2)#"3HA/+_ +XM_^E?____B?/IE?S__XM-V(D,)(GVZ'?__?_I>/[__\<$)"4``!#H6G_^_^F8 +XM_/__D(UT)@!5B>575E.#[$R+10B+>`2-<`3'1=P"````QT7(`````,=%S``` +XM``"%_P^$?@```)")/"3'1"0$2#0)".CL_OW_B?HQ_X7`=1B#Q@2+%H72#X2' +XM````QT7<`0```&:_`0#'1"0$H#@)"(D4).B\_OW_"T7,=6.#Q@2+'L=%R`$` +XM``"%VXG:=""_`0```,=$)`2L.`D(B1PDZ)#^_?\+1"-M"8`````BP_WP0`` +XM`$")3=AU,`^VP3W_````B470#X>``@``H>!="0B+5="+1)`T]L0!#X7S```` +XM@WW87P^$Z0```(G^QP0D'0``$.@%?O[_BP8QVX/X6P^$_0$``(7`#X18`0`` +XMQP8`````@\8$BQ:%TG42BTW@BQ&%TG0)@SHH#X1,`@``@_@]#X4R`@``QT0D +XM!%`["0B)-"3HDOW]_X7`#X70````A=L/A0$"``"+7>"-=@#K`X/#!(LSA?8/ +XMA#P!``"#/BEU[L<#`````(M%X(D$).@KB?__BTW(A")^.@2\?__BT7@BSB% +XM_P^$I?[__X/`!(E%X.G:_O__BPW@70D(B?Z+7=B)3=3K)HM5U(M$@C3VQ`5U +XM"8/[7P^%RP```(/&!(L>]\,```!`#X6Z````#[;#/?\```!VT(D$).CN_/W_ +XMB?;KRX7;#X3P````B30DC78`Z'OV`0#'1"0$,"H("(G#B00DZ*E__O^+5?") +XMV8GXZ/WX__^)'"3H17_^_XD<).CM?O[_Z4____^+5>"+`H7`#X3%_O__QT0D +XM!#@["0B)!"3H5_S]_X7`#X6M_O__@T7@!(M-X(L!A<`/A)S^__^#P02)QHE- +XMX.F/_O__QT0D!"D```#'!"0R```0Z$%\_O^+,^FI_O__.?O````BU70BTW4BT21-/;$`0^%#?[__X-]V%\/A??]__^+!C';@_A; +XM#X4#_O__B?"S`8U5\.A/Y?__B<:+`.GN_?__B30DZ([U`0"+3<2)/"2)3"0( +XMB40D!.C+[O__Z7W^__^+5#I +XMI_W__XM-T(D,).AW^_W_Z4O___^0D)"0D)")P8L"50$!B>6+000#0@0]/T(/ +XM`(E!!'X*@P$!@6D$0$(/`%W#C70F`(V\)P````!5B>56BW4,4XM="(GRB=CH +XMO/___XU#"(U6".BQ____BT80.T,0?@.)0Q"+1A0!0Q2+1A@!0QB+1AP!0QR+ +XM1B`!0R"+1B0!0R2+1B@!0RB+1BP!0RR+1C`!0S"+1C0!0S2+1C@!0SB+1CP! +XM0SR+1D`!0T"+1D0!0T1;7EW#C70F`%6)Y8M5#(M-$%.+70B+`BL!B0.+0@0K +XM002%P(E#!'D*@RL!@4,$0$(/`%M=PXUV`%6)Y8/L*(E$)`2-1?B)5"0(B00D +XMZ+?___^+3?RZTTUB$,<$)!#="`B)R/?JBT7XP?D?P?H&*") +XM5=R+3@R)3="+0`PIP8G(]^^)3=#!?=`?BT8$B=&+5>#!^0PK3=")1="+4@0I +XMT(E%T/?OP7W0'XL&`T8(P?H,*U70C101BTW@*P$K00AKP&0!PHE5Y,=$)`3$ +XMF`H(QP0D=#P)".B9X___BU7AT'8L!AEDE___ +XMC70F`(/H1#PS=RD/ML#_)(54W0@(BTW@BT9`*T%`C;8`````B40D!,<$)";= +XM"`CH$-0!``^V0P&->P'KG8M-Y#'`AB->P&)!"3HAYG__P^V0P'I9/___XM5X(M&)"M").NCBU7@BT8L +XM*T(LZYB+5>0QP(72=(^+3>"+5A0#5AP#5A@K41PK410K41B)T,'Z'_=]Y.EM +XM____BU80B=#!Z!\!T-'XZ5S___^+3>"+1C`K03#I3O___XM5Z#'),<"%TG1# +XMVT7DNF=F9F;8#23>"`C9??(/MT7RVT7HWOFT#&:)1?#9;?#;7>S9;?*+3>R) +XMR/?JBP&)3"0(QP0D&MT(".@)TP$` +XM#[9#`>F6_O__BTW@BT8@*T$@Z=+^__^+1=2->P&+5=CH)/W__P^V0P'I"+1B@K0BCIE_[__XM]Y#'`A?\/ +XMA(K^__^+3>"+5A0K412)T,'Z'_=]Y.ET_O__BU7@BT9$*T)$Z6;^__^+5>"+ +XM1CPK0CSI6/[__XM5X(M&."M"..E*_O__BTW@BT8T*T$TZ3S^__^-M@````"- +XMOP````!5B>53@^P4BT4(BU@$C5`$N`0```"%VW0)BT($ARX````B5WXC5VH +XMB77\C;5@____B5PD!,<$)`````#H9/K]_XET)`3'!"3_____Z%3Z_?^)="0$ +XMC77PB1PDZ/GZ__^)-"3'1"0$`````.A%]_W_B70D"(E<)`3'1"0,J)D+",<$ +XM)"!V"@CHS?O__XM=^(MU_(GL7<.-=@!5B>53@^QDC5VTQT0D!`````#'!"2H +XMF0L(Z/[V_?_'1"0$('8*",<$)`````#HVOG]_XE<)`3'!"3_____Z,KY_?^) +XM7"0$QP0D('8*".AN^O__@\1D6UW#D)"0D)"0D)!5B>575E.#[`R+50B+0A"% +XMP'1(B=&+4@B+.87_="N-')`Q]NL#@\,$BP.%P'0.B00DZ,J"`0#'`P````"# +XMQ@$Y_G7BBU4(BT(0B00DZ*^"`0"+30C'01``````@\0,6UY?7<.-M@````"- +XMO"<`````58GE5U:)SE.)TX/L+(/Y!HE%X'8%O@8```"-?>Z-##>)^NL&@\(! +XM@\,".)7?2)=?B)1>R+0@@#`HT$A0@```") +XM1"0$BT(0B00DZ"&#`0")1?"+1Q"%P'0\BQ^+1?"+5>R)WH/#`0-W"(E'$(D4 +XM)(TTL.AY?___B0:+1?")'P-?",<$F`````"+7?2+=?B+??R)[%W#BT<(A*V+5?`QR8/!`<="_`````"#Z@0YR'7OP>`"*47P +XMZX^-M@````!5B>6+10R+`(E%#(M%"(L`B44(7>GC]?W_C;0F`````%4QP(GE +XM5E.#[""+70B+=0PY\W1=BU40A=)T78'[_P````^'Z0```*'@70D(BYR8-`0` +XM`('^_P````^'P0```*'@70D(B[2P-`0``(U%Z(E$)`2-1?")7?")=>C'1>P` +XM````QT7T`````(D$).@[]_W_@\0@6UY=PX'[_P```'=PH>!="0B+1)@T]L00 +XM=!N!_O\```!W2J'@70D(BU2P-&:%TK@!````>,B!^_\```!W;Z'@70D(BT28 +XM-&:%P'F,@?[_````=V.AX%T)"(M4L#2`YA"X_____P^$;?___^N1B30DZ!3S +XM_?^)PNNSC70F`(D<).@$\_W_ZX^-M@````")-"3H!/7]_XG&Z3S___^0B1PD +XMZ/3T_?^)P^D4____D(D<).C4\OW_ZY")-"3HRO+]_XG"ZYJ-=@"-O"<````` +XM58GE5U:)QE.)TX/L+#G*B4W8R)!"3H\.\!`&:!_S^`B47@="QF@?];@`^$@````&:!_RJ` +XM="F+1>P[1?!U%P-UX#E=V'>H,<"`/@`/E,#K5X`^`'7I@\0L,"-1>S'1"0(!@```(ET)`2)!"3H@>\!`(E%X(M% +XM"(G:B00DBTW8B?#H//___X7`=,BX`0```(/$+%M>7UW#@#X`=*$/MQ,/M\([ +XM10@/E,`/MOB%_P^%P@```,=%W`````#K"8VV``````^W$V:!^EV`#X2"```` +XMB=JY!@```(U%\.AS_/__C1Q#9H$[+8!T$8M%\#M%['71QT7<`0```.O(@\," +XMN08```")VHU%Z.A&_/__QT0D"`````"-'$.+1>R)1"0$BT7PB00DZ%G]__^% +XMP'^5QT0D"`````"+1>B)1"0$BT7LB00DZ#O]__^%P`^/<____^N@D+D&```` +XMB=J-1?#H\?O__SE]W`^$T_[__P-UX(T<0^FT_O__@\,"#[<3Z3/___^)]E6) +XMY5=6B<93@>R\````B95<____B8U8____#[<"ZQ60A?\/A1(!``!F@_@O=%2) +XMG5S___]FAHM6!&:#^"^)E6#___]T0#'_9H7`BYU<____>"4/OL"#PP*) +XM1"0$B30DZ"GG`0`/MP-FA8!`(N57/___P^W`F:#^"]TVF:%P'6&C5V( +XMB30DZ#+G`0")7"0$BP:)!"3H8._]_\=%A`````"%P'55BX58____]D`,"'0K +XMBQ:+1@2`?!#_+W0?#[=%D"4`\```/0!````/A,7UW#BX5@ +XM____B48$BY58____BT(,)0`0``"#^`$9P(/@PV8MHG]FB85H____B30DZ(3F +XM`0#H>_+]_\<``````(L&@#@`#X7&````QP0DDAT)".C>\?W_B<>%_P^$P@`` +XM`(M6!`^WA6C____'180`````B95D____B854____B3PDZ!_U_?^%P'1Q@'@( +XM+G4,BY5<____9H,Z+G7BBY5D____@\`(B58$B40D!(DT).CUYP$`B30DZ/WE +XM`0"+E53___^)V8N%9/___P,&B10DBY5<____Z"_\__\Y10ATGXM%"(G:B00D +XMBXU8____B?#HU?W__X7`B46$=(.)/"3H,O7]_XM%A('$O````%M>7UW#B00D +XMZ!SQ_?^)QX7_#X4^____BY58____BUH4A=MT(NB`\?W_BP")1"0$BP:)!"3_ +XMTX7`=`S'183^____Z:/^__^+A5C____'180`````]D`,!`^$C/[__^O;B5PD +XM!(D4).BN\/W_A<`/A5C^__\/MT60)0#P```]`$````^%1/[__\=$)`0O```` +XMB30DZ+;D`0")-"3H#N4!`.DG_O__B?:-O"<`````58GE5U93@^QLBT4(]D4, +XM`8E%O'4:BU44QP(`````QT(0`````/9%#`(/A`P#``"+10R+?12`Y/Z)1PR+ +XM11")1Q2+!XE%I(M'#,='!``````E`!```(/X`1G2@^+#9H'JHG^#^`&+10@9 +XM_X/GPX/'7F:)5:B)?<")!"3HS?/]_XU$``*)!"3HM7L!`(M5"(E%Q`^V.HGX +XM#[;(,<`[3<`/E,"%P(E%R'02@\(!B56\BU4(#[9Z`8GX#[;(BU4,@>(`(``` +XMB56@#X0!`@``B?J+7<2$T@^$F````(VT)@````")^HM%O`^VTHE5T(M5O,=$ +XM)`0&````@\`!B474B10DZ%CM_?^#^/^)Q@^$`@$``(/X`0^.#0$```^W?="- +XM0P(QTHU._V:).XE%S(VV`````(M]O`^V1#H!@,Q`9HE$4P*#P@$YRG7IBT74 +XMBU7,C40P_XU4`````` +XMQT7D`````&:#.@`/A0P"``"+512+`CM%I`^$-0(``/9%#"`/A/\```"+1<0Q +XMVXD$).AI>0$`@\1LB=A;7E]=P\=$)`0`````QP0D`````.@W[/W_B?@\7`^$ +XM&`$```^W?=!FB3N#PP*)7_XJ@`^$ +XM)/___V;'`RJ`@\,"Z1?___\/MP$/M_@[?NGB?B+7<2$P`^$E_[__XM5O(M= +XMQ&:)"P^V0@&#PP*#P@&$P`^VR'7LZ7C^__\Y1:0/A/C^__^+510K1:3'1"0, +XML*@&"(M]%,=$)`@$````B40D!(M2"`%5I(M%I,'@`@-'$(D$).CVZ?W_Z;_^ +XM___'0@@`````Z>C\__^+5=0/M@*#P@&)5=2$P`^$YP````^VP(#,0&:)`X/# +XM`HE=S.GL_?__A=(/A![___^+112-4P*!2`P``0``9L<#6X`[?<`/A-<````/ +XMMP'K"V:#^%UT1`^WP(G.9B7_`&:)`@^W!H/"`HU.`F:#^"UUWP^W7@*-3@)F +XM@_M==-@/ML-FQP(M@(U.!F:)0@(/MT8$@\($9H/X776\C5H"9L<"78#IDOW_ +XM_XM]R(U%W(M-%(D\).@1^?__B<.+1=R)!"3H9'+]___V10P0="6+3:"%R75'BU44BT4(Z`/U___IN/W__X-MU`&X +XM7$```.D1____]T4,``(```^$D_W___9"#0$/A8G]___KP@^W5:AFB5,"C5,$ +XMZ1G___^+?0B)/"3HR._]_X/``8D$).BQ=P$`#[87A-*)PXG!="J)^.L2#[80 +XM@\`!B!$/MA"#P0&$TG04@/I<=>F#P`$/MA"$TG7B@^@!Z]K&`0"+512)V.AO +XM]/__B1PDZ)=V`0#I'/W__Y"058GE5U93@>RL`@``BU4(BP*#^"`/A/8!``"- +XMM@````"#^`D/A.W'`@````"+A5C]__^+$(72#X1C`0``QT0D!)1V"@C' +XM!"3@00D(Z&/2__^%P`^$>0$``(L5+)H+"*$HF@L(B960_?__BQ4DF@L(B86, +XM_?__H2":"PB)E8C]__^+%1R:"PB)A83]__^A&)H+"(F5@/W__XL5%)H+"(F% +XM?/W__Z$0F@L(B95X_?__BQ4,F@L(B85T_?__H0B:"PB)E7#]__^+%02:"PB) +XMA6S]__^A`)H+"(F5:/W__XF%9/W__^@L9_[_QP0D`)H+"(F%7/W__^C&Z/W_ +XMA<`/A"@#``"+A5S]__^)!"3HM&G^_XN5D/W__XN%C/W__XD5+)H+"(N5B/W_ +XM_Z,HF@L(BX6$_?__B14DF@L(BY6`_?__HR":"PB+A7S]__^)%1R:"PB+E7C] +XM__^C&)H+"(N%=/W__XD5%)H+"(N5`0"+A5C]__^-5>B)%"2)1"0$Z!S>`0"+ +XM7>RX0]X(".L4B?:+!+7`W@@(@\8!A<`/A%?___^)7>R)!"3HL^,!`(E$)`2- +XM1>B)!"3HY-T!`(U5Z(D4).C)VP$`BT7HB00DZ%[A`0#'1"0$`````(D$).B^ +XM:/__H]PD"0B#P`%TI(U=L,=$)`1`'@4(C768QP0DW"0)".A*:/[_C46@QT68 +XMP+@&"(D$).@DZOW_B5PD",=%G`````")="0$QP0D`@```.@)Z?W_B1PDC5W8 +XMQT0D!)`>!0CH"FC^_XU%R(E<)`B)1"0$QP0D`@```.B?Y/W_B1PDC9V8_?__ +XMQT0D!&`>!0CHW6?^_^L5B40D"*',EPH(B5PD!(D$).@F9___H=PD"0C'1"0( +XM``(``(E<)`2)!"3HK6?__X7`?\['!"3<)`D(Z/UF_O_I?OW__X/X.@^%4_[_ +XM_^EA_O__BY58_?__QT0D!.!!"0C'!"0"````B50D".A\FP$`Z;7\__^+E5C] +XM___IS_O__\<"+@```(N%8/W__\=`!`````#I)/[__\<$)%3>"`CH2.(!`.F" +XM_?__H8"8"@C'1"0,+MX(",=$)`@!````QT0D!!T```")!"3HOL7^_XN56/W_ +XM_XE4)`2)!"3H3+\!`.G=_/__C;0F`````%6)Y8/L"*'<)`D(@_C_=`B)!"3H +XM2&G__\<%W"0)"/_____)PY"0D)"0D)"0D)"0D(G"58GEHXAC"0B+0@R%P'0) +XMB<*+0@R%P'7WBTH4A&,)"(M">(E$)`2+10B)!"3H3=L!`+@! +XM````@P5X8PD(`8/$$%M>7<.#P0$Y\7ZSB0UX8PD(@\00,&,)"#'`@\006UY=PXD5>&,)"`^V`83`=!R)RP^^P(E$)`2) +XM-"3H,=8!``^V0P&#PP&$P'7F@P5X8PD(`8/$$%NX`0```%Y=PXUV`%6)Y593 +XM@^P0H8!C"0B+=0B%P'0]BU`$A=)T-@^V`H3`=!R)TP^^P(E$)`2)-"3HW=4! +XM``^V0P&#PP&$P'7F@P6`8PD($(/$$%NX`0```%Y=PX/$$#'`6UY=PXVV```` +XM`%6)Y593@^P0H81C"0B+=0B%P'0\BQ"%TG0V#[8"A,!T'(G3#[[`B40D!(DT +XM).A^U0$`#[9#`8/#`83`=>:#!81C"0@,@\006[@!````7EW#@\00,6#[!B)7?2+71")=?B+ +XM=0R)??R+#8AC"0B+?0B%R704B5PD"(ET)`2)/"3H_OO__X7`=2J+%8QC"0@Q +XMP(72=!Z)71"+7?2)=0R+=?B)?0B+??R)[%WI-/___XUT)@"+7?2+=?B+??R) +XM[%W#C78`58GE@^P(BT4(A<"C?&,)"'0(B00DZ"+B_?_'1"0$Q)@*"(M%#(D$ +XM).ACR/__A<"CB&,)"'0:BP#'!8AC"0@`````HXQC"0C)PXVT)@````#'!8QC +XM"0@`````R<.-="8`58GE@^P(BT4(A<"C?&,)"'0(B00DZ,+A_?_'1"0$Q)@* +XM",<$)-PX"0CH`LC__X7`=`>+`*.,8PD(R<.0C70F`%6)Y8/L&(E]_(L]D&,) +XM"(E=](EU^(7_=#F+70B%VW0RH9AC"0B%P(E%\'0F,?:)]HLQ=PXVV```` +XM`(V\)P````!5B>57B==64XG#@^P,BT`0.T,(#X:2````B?@#0PPY0Q1V(HM# +XM#(M+"(L3P>`"`T,$B02*@\$!`7L,B4L(@\0,6UY?7<.+`"B40D!(L#B00DZ%1K`0#'!"3$K`L(B0/HIM`! +XM`.DZ____D%6XD&,)"(GE4X/L%(M="(M3!(/"`>@&____BQ.)5"0$B00DZ!3< +XM_?^#Q!1;7<.)]E6)Y5.)PX/L!(,%Q*P+"`&+`(7`=!R)!"3HTFD!`,<#```` +XM`,=#"`````#'0Q``````BT,$A575E.#[`R+10B+%7QC"0B+=0R+71")1?#HD/___X7`B<8` +XM``#V`Q`/A-T```"A?&,)"(7`="6#!<2L"P@!B00DZ,5?___'!7QC"0@````` +XMQP0DQ*P+".A_S@$`H8QC"0B%P`^$D0```(L`ASP$`B30DZ#;0`0"+1?"+%7QC"0B#Q`Q;7E]=Z;'^__^+#7QC"0B%R76G +XMC;0F`````(/$#(GX6UY?7<.-M@````!5B>575C'V4X/L#(L-R&,)"#L-L&,) +XM"(M]#`^",@$``(L5T&,)"(72=!*+10CH7O[__X7`B<8/A4(!``"AS&,)"(L8 +XMA=L/A#,!``"+%=!C"0B%TG0P@P7$K`L(`8D4).B,7O__QP708PD(`````,<$ +XM),2L"PCH1LT!`*',8PD(BQB%VW2;@SLO=`OK(8UT)@"#.R]U$X/`!(L8A=MU +XM\J/,8PD(Z7C___^CS&,)"(M%"(E<)`2)!"3H5-$!`,='!`````"+`X7`=`R# +XM^"YU.HM;!(7;=3/'!"22'0D(Z&O;_?^CT&,)"(M%$,<`$0```(D\)+X!```` +XMZ`3/`0"#!DSW_W_C;0F`````%6)Y5.#[!2#!<2L +XM"P@!Z!G;_?_'``````#K)9"-="8`Z`?;_?^#.`1U48VV`````.@;RP$`Z/+: +XM_?_'``````#H9]C]_X7`B<-TU<<$),2L"PCHRD,V_W_58GE7>G3V_W_C;0F```` +XM`%6)Y5.#[!2#!<2L"P@!Z)G=_?_'!"3$K`L(B53B<.#[!2)!"3H>]?]_XU0`KBH +XM8PD(Z%+Y__^)7"0$B00DZ&+6_?^#Q!1;7<-5B>575E.#["R+10B%P*-\8PD( +XM=`B)!"3H3]K]__8%P&,)"`$/A"4!``#V!#2"`AV,KOPT@@(BT/PA`$@\,0!>#2"`@YT'?3H#R`2C +XMP&,)"/8%P&,)"`@/A!\"``"AT&,)",<%R&,)"`````"%P'0E@P7$K`L(`8D$ +XM).@C6___QP708PD(`````,<$),2L"PCHW+0Q2%P'0HBT,$ABR_O__BT,0 +XMA:)%"3HUM`!`(D$).AZU_W_A<") +XM1>1TUHD$),=$)`0P'@4(Z-=7_O^+1=R%P'0EQT0D!+@X"0B+!XD$).CNS0$` +XMB47@QT0D!#`J"`B)!"3HJU?^_XM=Y(D<).BP`````QT7H`````(E=\.L' +XM@T7L`8EUZ(MUZ(/&`3MU\'-"BQVH8PD(C02U_/___XL\`XM$`P2)/"2)1"0$ +XMZ&K3_?^%P'3*BT7LAPI7?"+1?#'!"3$K`L( +XMH[!C"0CH'\57 +XM5E.#[`R+-<1C"0B%]G1_BP:%P'1YBSW@70D(ZQB+1(7UW#D)"0D%6)Y5=6 +XM4XM-"(M]#(LQA?9T0XL?ZP^+<02#QP2%]G0UBQ^#P02)\HG8@>+___\_)?__ +XM_S\YPG3>A=NX`0```'0;B?"!X____S\E____/RG86UY?7<.#/P$9P/?06UY? +XM753BTT(BUT,BU40BP&%P'0S@^H!A=)_"^LJ +XMC70F`(/J`70A@\$$BP&%P'7R@^H!A=)_&,53BUT(BTT,BU40ZP>0@\,$@\$$ +XM@^H!=`N+`87`B0-U[5M=P\<#`````%M=PY!5B>575E.#[`R+10B)!"3HJ-'] +XM_XLUT)<*"(7VB47P=%^+'H7;=%F)Q\'G`NL-B?:#Q@1T2XL>A=MT18D<).AY +XMT?W_.47P=^B-!#N#.#UUX,<``````(M%"(E$)`2+!HD$).B9_O__BQ;'!!<] +XM````A6+10R+`(E% +XM#(M%"(L`B44(7>F'=0$`C;0F`````%6)Y5=64X/L'(MU"(M]##G^#X*S```` +XMB?(QR9"-="8`,<"#.F`/E,"#Z@0!P3G7=N^#X0''1>P()0D(=0?'1>P,)0D( +XMQT7P`````.L*C78`@^X$.?=W18L>A=MT\XE<)`2+1>R)!"3H0-3]_X7`=#F# +XM?OQ@^X$.?=VN[@! +XM````@\0<6UY?7<.)7"0$QP0D["0)".CST_W_A<`/A(4```#'1?`!````ZX8Y +XM]XUT)@!SRHL&@_@F=$J#^"AUOH/N!(L6@_H@=`6#^@EU!#GW7UW#@WWP`0^%`/___S'` +XMZ4K___\/ML+VA`#A(`D(('2CZ3/___^-M"8`````58GE5E.#['"%P'17<.# +XMQ'`QP%M>757B<=64X/L;(7`B560=%['1"0$ +XMQ)@*",<$)`PR"0CH6KC__X7`=%6+`(7`=$^+&(7;=$F)QNL@C;8`````B5PD +XM!(D\).AD!/__A!(/&!(7;="7'1"0$A#,)"(D<).@"SOW_A7UW#BT60B3PDB40D!.@BQP$`B<.)!"3HR,D!`(D<)(U= +XME(G&Z%M;`0")7"0$B30DZ!O-_?^#P`%TN@^W39R)R"4`\```/0"@``!T1#T` +XMP```NCT```!TH3T`$```LGQTF#T`(```LB5TCST`8```LB-TACT`0```LB\/ +XMA'G___^#X4FR*@^%;O___^ED____QT0D!,28"@C'!"3@0@D(Z&"W__^%P'0P +XMB5PD!(DT).C,S_W_NB8```"#P`$/A#?___\/MT6````(D$).C_T/W_A<`/E<`/ML")1>2+3<0Q_X7)?DN+5<@Q]HL" +XMB00DZ!"=`0"+7-1@$Y1<2)QHT4@7X=BP*)TXD$ +XM).CEG`$`C5,$.?AST8U&`3E%Q(G&?^.#?<`!&<`QTO?0C7P'`J'@EPH(B7WP +XM]_>%P(G#=".+%>AV"@BX`0```(72#X3%`0``B00DZ,?1_?^%P`^%I0$``,=% +XMX`$```#'1>@`````BU7H`U7$QT78_____\=%W`````")T,'Z'_=]X(7`B46\ +XM#XX>`0``BT7@,?^+3=R%P(E-['\NZ>4```"#1=@!BTW$.4W8?#*+1>2%P`^% +XMS@```(M%O(/'`0%%[#M]X`^$O````(M%Y(7`=="+5>R+3<2)5=@Y3=A]SHM5 +XMR(M%V(T$@HE%T(L8B1PDZ"+,_?^)QHM%P(7`#X2_````C12U`````(U$$_R) +XM5=2+&,<``````(U&_XE$)`2)7"0(BTW0BP&)!"3HNTH``(M5T(M-U(L"B5P! +XM_#';.WWH#XUQ____BTW0BP&)!"3HEYL!`(T<&#E=\`^&6/___\<$)"````"# +XMPP'H?&G__SM=\'7LBT6\@\-M"8`````@_HD="N#P`2)10B)5"0$B1PDZ.F_`0"+10B+ +XM$(72=>")'"3H^+\!`(/$)%M=PXGVC44(QT0D"````$")1"0$B1PDZ%FF`0"% +XMP'6EBT7PB00DZ$I7`0"#Q"0QP%M=PXGV58GE5U93,=N#["R)5>B)3>2)1>R) +XM!"3H5/___XE%\,=$)`0P*@@(B00DZ)%,_O^+??"%_P^$!@$``(M%Z,=`!``` +XM``"+5?"+`H/X/0^$KP$``(/X?@^$&0$``(M-\(E,)`2+1>B)!"3HH\$!`(M5 +XMZ(D4).B(OP$`BTWHNHPS"0BAV)<*"(MQ!(7V=`6+3>B+$8/H`H/X`0^6P`^V +XMP(E$)`2)%"3HIQS^_X7`B<,/A(T```")!"3HY<0!`(D$).B)R_W_BU7DA<") +XM`G1TBU7PB10DZ$E+_O^+3>R+,87V=#J+1>B+4`2%TG0/B<&+`(-\D/PO#X1\ +XM`0``BU7HQT($`````(E<)`2)%"3H`<$!`(M%Z(D$).CFO@$`B1PDZ!Y6`0"# +XMQ"PQP%M>7UW#BT7H,=N)!"3HQ[X!`(VT)@````")'"3H^%4!`(-]"`9T#HL= +XMY&,)"(7;#X16`0``BTWPB0PDZ+E*_O^X_O___X/$+%M>7UW#BTWP@\($BT$$ +XMA<`/A.<```"#^"^)U@^$W````(/&!(L&A<`/A:,```")\"G0P?@"B10DB40D +XM!.@PP@$`B<.)!"3HAM']_XD<)(G'Z'Q5`0"%_P^$8/___XE\)`2+1>B)!"3H +XM-<`!`(D\).A=50$`BU7HBP*#."]T:(ET)`2+3>B)#"3H%,`!`.EL_O__BT7P +XMB00DZ,3Q_O^%P(G##X06____.47P#X0\_O__B40D!(M5Z(D4).CBOP$`B1PD +XMZ`I5`0#I,O[__Y"-="8`@_@O#X5'____C;0F`````.E(____@WH$`8VT)@`` +XM``!UBX,^+W6&@\8$ZX&)UC'`Z2_____'000`````B0PDB5PD!.B(OP$`BT7H +XMBU`$B<&+`(-\D/PO#X1R_O__QT0D!"\```")#"3H\[P!`.E=_O__Z!7*_?^# +XM.!2-M@`````/A(D```#H`S' +XM!"3OW@@(B4PD!.COH0$`BT7PQP6PF0L(`0```(D$).CJ2/[_N/_____I+/[_ +XM_XM]\(7_=,.+5?")5>SKNZ&`F`H(QT0D#-3>"`C'1"0("@```,=$)`0>```` +XMB00DZ/RG_O_KA:&`F`H(QT0D##N["`C'1"0("P```,=$)`0>````B00DZ-6G +XM_O_I6____U6)Y8/L&(/X$HE=](G3B77XBW4(B7W\=B_'0P0`````B30DZ.A' +XM__^)="0$B1PDZ#R^`0"+=?B)70B+??R+7?2)[%WI&+P!`/\DA4#?"`B0QT($ +XM`````(E,)`2)%"3H#;X!`.N[QT($`````,=$)`1^````B10DZ(2[`0#KHHGV +XMBSK'1"0$)````(D\).AZQ/W_A!?WP@```$!U#X/Z?P^.N@,``(VV`````(L6A=(/A#4!``")TX'C____ +XMOP^(R`$``(/[?P^/OP$```^VPP^WA`#@(`D(J$$/A*P!``"+1=C'1>````!` +XMA<`/E<(QR832=`D[7=@/A$X"``"+1>"%P'0-@WW8(HUV``^$I0(``(3)=4B$ +XMTHUT)@!U&87;>`F#^W\/CG,#```['42:"P@/A!,$``"+1=B%P'@4]T78```` +XM0'4+@WW8?Y`/COP````['8R8"@@/A`X!``"%_W08BU74BP*#P@2)5=0YV`^5 +XMP`^VP(/H`2''C47H@\8$B5PD!(D$).C0N0$`BT78A<`/B,7^__^+1=C!Z!Z# +XM\`&#X`&#?=A_#Y["A,`/A*K^__^$T@^$HO[__P^V1=CVA`#@(`D(0`^$D/[_ +XM_XM%T#E%U,=%V``````/@HG^__^+%C'_A=(/A7UW##[9%V/:$`.`@"0A`#X5C_O__Z3[^__\/MD78 +XM]H0`X"`)"$`/A?[^__\['8R8"@@/A?+^__^-5>C'1"0$7````(D4).C=N`$` +XMB5PD!.D:`0``C70F`(M%V('B````0`^4P8E5X(7`#Y7"A,D/A$G^__^$T@^$ +XM3O[__X7;#X@Y_O__@_M_D`^/+_[__P^VPP^WA`#@(`D(J/,/A!S^__^#^R,/ +XMA!/^__^#?=@B#X1R`@``BT78A<`/B,H!``#W1=@```!`B?8/A;L!``"#?=A_ +XM#X^Q`0``#[9%V/:$`.`@"0A`#X2?`0``BU7L@\8$BT7HB5R0_(M%V,'H'H/P +XM`8/@`8-]V'\/GL(Q_^EE_O__C;0F`````(M5[(72=!2+1>B#Z`2-!)"+5=@Y +XM$`^$LP$``(M5V(U%Z(D$)(E4)`3HX[B)7"0$B00DZ,&W`0"+5=B)5"0$C47H@\8$B00D,?_HJKB)%"2)7"0$Z$FW`0"- +XM1>C'1"0$(@```(D$).@VMP$`Z6S]__]\&_=%V````$"0C;0F`````'4*@WW8 +XM?P^.NP```(U5Z,=$)`0`````B10DZ`&W`0#IG/W__P^VP@^WA`#@(`D(J$$/ +XMA#G\__^+1=B%P'0).578#X4I_/__,578@T74!(E4)`2-5>B)%"3HP[8!`.F^ +XM^___#[;#]H0`X"`)"/,/A'S\__^#^R,/A;3]___I;OS__XM%V(U5Z(/&!(D4 +XM)(E$)`3HBK8!`(U%Z(D$)(E<)`3H>[8!`(L&A<`/A8P```"X`0```+H!```` +XM,?_'1=@`````Z:?\__\/MD78]H0`X"`)"$`/A>?\___I+O___\<`7````(U% +XMZ(/&!(E4)`0Q_XD$).@HM@$`N`$```"Z`0```,=%V`````#I8/S__XM%[(7` +XM#X07_?__Z=W[__^#^W\/CZG]__^H@HVT)@`````/A)K]___I>OO__XM5V(U% +XMZ#'_B00DB50D!.C1M0$`Z?S[__^-M@````"-OP````!5B>575E.#[%R)1;2) +XM5;"+`(L0A=)T#XD$).BAVO[_A<")1;AU"C'`@\1<6UY?7<.A+)H+"(E%\(L5 +XM*)H+"(E5[*$DF@L(B47HBQ4@F@L(B57DH1R:"PB)1>"+%1B:"PB)5=RA%)H+ +XM"(E%V(L5$)H+"(E5U*$,F@L(B470BQ4(F@L(B57,H02:"PB)1RC*)H+"(M5Z(D5))H+"(M%Y*,@F@L(BU7@B147UW#BT6XB40D!(M5M(L"B00DZ(OL_O^+5;2)`NFS +XM_O__BT6TBQCKR[C_____QP7`F`H(`````,<%L)D+"`$```#I!/[__XVV```` +XM`(V_`````%6)Y5=64X'L'`$``(F%_/[__Z$LF@L(B97X_O__BQ4HF@L(B8WT +XM_O__BPTDF@L(QT7P`````(E%E*$@F@L(B560BQ4/___XL5!)H+ +XM"(F-=/___XL-`)H+"(F%R+1?"%P`^(O0D``(M5$(M-#(E= +XMZ(F5`/___XD,).@VO?W_B=J)V8/B!(/A((F5%/___XF-#/___\=%W`````#' +XM1>``````B85,____B=B#X`*)A1C___^)V(/@0(F%"/___\=%Y`````#'1=`` +XM````QT74`````,=%V`````#'1>@`````QT0D!,28"@C'!"2`2`D(Z(.F___' +XMA23___\`````/?AO"0AU%>LJ@_IA=0O'A23___\"````D(/`!(L0A=)T$8/Z +XM077BQX4D____`0```.OFB=J#XQ"#X@&-3=")E1S___^)#"2)G1#____'1"0$ +XML)$(".B_/O[_C47%*/___P````#' +XMA2#___\`````QT6L`````(L$A>#@"`C'A03___\$````QX5(____`````,>% +XM9/___P````")19S'A43___\`````BX7T_O__C4WHC570QT74`````(E,)`B) +XM1"0$B10D_U6!(/&!(7;=;J+C43___\+ +XMC4C___^)C2S___\/A+(#``"+1="+50R)1;B+.H7_#X3R`P``BPW@70D(B<.) +XM5:B)C33___^+`XG^@>;___\_B84P____)?___S\YQHE%P`^$?P(``('^_P`` +XM`(FU./___P^'K@4``(N5-/___XM$LC1FA<")=;QY((&]./____\````/A^X& +XM``"+C33___^+C+$T!```B4V\BT7`/?\```")A3S___\/AW4%``"+3<"+A33_ +XM__^+5(@T9H72BT7`>2"!O3S_____````#X>8!@``BU7`BXTT____BX21-`0` +XM`#E%O`^$Z0$``(N%1/___X7`=4Z!Y____S^-1].#^`$/ABH%``"#_E]U-[HM +XM````B[TP____A?]T*#M5P'4:Z:\!```E____/SG+`0``.<(/A)H!``"# +XMPP2+`X7`=>*+A2C___^%P`^$B?W__XU-T(D,).@W._[_@[W\_O__!'4?Z?0$ +XM``"+0P2CX&,)"(L#B00DZ#=&`0")'"3H+T8!`(L=X&,)"(7;==R#O?S^__\& +XM#X2U!```B[4(____A?9T'(M=K(7;=16+C2#___^%R7X+BY4@____]]J)5:R+ +XM3:R)3?"+1>R)!"3H<3K^_XM%E(M5D(M-C*,LF@L(BT6(B14HF@L(BU6$B0TD +XMF@L(BTV`HR":"PB+A7S___^)%1R:"PB+E7C___^)#1B:"PB+C73___^C%)H+ +XM"(N%7UW#C;0F`````(.]^/[__Q(/A:'\__^#O23___\!#X2<`@``QX4H____ +XM`````(N=3/___X7;#X6&_/__BT70@S@N#X5Z_/__BXTD____AW^_X7`#X3W^___BT70BTT,B40D +XM!(D,).B#)0``.84$____B<,/C3@"``"#^`0/A<[[__^+1="+50R+C?3^__^) +XM1"0(B50D#(L!B40D!(M%"(D$).CW(P``A<`/A*'[__^+A1S___^%P`^%(@H` +XM`,>%!/___P,```#IA/O__XGVBU70BTT,B56XBQ&%TG1$BTVX@>+___\_BP&) +XMRXM-#"7___\_.<)T).E3_?__C78`BT,$@>+___\_@\,$@\$$)?___S\YP@^% +XM-/W__XM1!(72==V+C1S___^%R0^%9`,``(N5&/___X72#X4!!0``BX44____ +XMA<`/A2,%``"+A0S___^%P`^%104``(.]^/[__P$/E,.#O?C^__\##Y3`A-N) +XMQP^$6`,``(.]^/[__PL"``"+A2C___^#1:P!A<`/A,CY___I.OS__XM% +XMW(D$).@AU___A#^BX/A4/]__^+0`B%P`^4PH/X+P^4P`G"#[;2B94H____ +XMZ2_]___'A2C___\!````Z2#]__^+10@QV\=`!`````")!"3HV*H!`(F=!/__ +XM_^FK^___@_@$#X3(_?__BX4<____A53^_X7`#X1C^?__BTT(BT70QT$$`````(E$)`2)#"3HB*P! +XM`(M%"(D$).AMJ@$`A=MTD8F=!/___^DP^?__B30DZ#*T_?_I3_K__XD$).@E +XMM/W_B<+IB?K__X/^7P^$TOK__X/^+;I?````D`^$R/K__XGRZ<'Z__^+A03_ +XM__^)1:SI8_O__Z'H)`D(.85D____#X[;````@_C_#X32````@WVL`0^.`OO_ +XM_X/``0^,600``(NU9/___XT\M0````")/"3HXT$!`,=$)`0P*@@(B<.)!"3H +XM@3;^_XL-X&,)"(7)=">%]G@CC10?@ZUD____`8L!B4+\BTD$@^H$A>#'1"0,(,P&",=$)`@$````B70D!(D<).APLOW_BT4(QT`$```` +XM`*'H)`D(BU4(BP2#B10DB40D!.ACJP$`BTT(B0PDZ$BI`0")'"3H8#7^_\=% +XMK`$```#I1?K__XN=\/[__^DX]O__QP7H)`D(_____\>%(/___P````#'1:P` +XM````Z1KZ__^)!"3H[;3]_^EK^?__B30DZ."T_?^)1;R0Z1'Y__^+A1#___^+ +XM5;B+C?3^__^)1"0(B50D!(L!B00DZ*I2_O^%P`^%<_S__XN%*/___X7`#X0; +XM]___Z8WY__^$P`^%H/S__X.]^/[__P%T@^$ +XM\`4``(N-5/___X'B____/XL!)?___S\YP@^%U04``,>%4/___P````#K%XN- +XM5/___X'B____/XL!)?___S\YPG47@X50____`8/'!(.%5/___P2+%X72==+' +XM!P````"+50@K.L'_`HEZ!*'48PD(A<`/A(D$``"+A4C___^%P`^$3OC__XM5 +XM"(N-3/___SM*!`^&//C__\="!`````"+10R)%"2)1"0$Z&:I`0"+50B)%"3H +XM2Z@/X?__@_@O#X4?^O__QT0D!"\```")-"3H +XM5J4!`.D*^O__D,=$)`3$F`H(QP0D0$()".A+___\_)?___S\YT'36BT6DBW@$@\`$B46DA?\/ +XMA7K____I#?S__XM%"(L`B46PB<*+`(7`#X0$`0``BQ7@70D(BXU4____BWVP +XMQX50____`````(F56/___XE-M.F&````BY58____BT2:-&:%P'D=@;U<____ +XM_P````^'HP```(N-6/___XN;_ +XM__\_@?O_````#X95____B1PDZ&.M_?_I4O___XDT).A6K?W_ZXJ)'"3H7*_] +XM_XG#Z5O___^)-"3H3:_]_XG&ZXV+C53___^)U\>%4/___P````")3;2+1;2+ +XM$(72=26+A5#___^+E53___^+3;#!X`*)1"0(B50D!(D,).B)LOW_BT6TB854 +XM____Z67[__^#A2#___\!Z=/S___'1"0$Q)@*",<$)$!""0CHKY;__X7`#X5; +XM^___BX5(____A!C"0CIVOG_ +XM_XM5",="!`````")1"0$B10DZ"^D`0"+30B)#"3H%*(!`.F#^O__QX50____ +XM`````.E6^O__58GE5U93@^Q\BT48BWT0BP#'1=P`````QT7@`````,=%Y``` +XM``")19S'1=``````QT74`````,=%V`````#'1<0`````QT7(`````,=%S``` +XM``#'1>@`````Z&'/__^+50C'!=AC"0@`````BS+'1"0$+P```(DT).@NJOW_ +XMA<`/A.H#``"-6`2)'"0I\^CMI`$`P?L"C4W0B5PD"(ET)`2)#"2)1>SHY*(! +XM`(U%T(D$).A)H0$`C570B10DQT0D!+"1"`CH]BW^_XU%[(D$),=$)`0P'`4( +XMZ.,M_O^+30B+`8,X?@^$]0$``(M5[,=$)`0D````B56HB10DZ*NI_?^%P(G# +XM=!N+3:C'1"0$+P```(D,).CBKOW_A<`/A$X"``")^"4`$```B46@#X7>`0`` +XM,<")^X-]G``/E<"`Y^^)1:2-3=R)#"3HLJ`!`(U%W,=$)`2PD0@(B00DZ%\M +XM_O^#^P8/A#8"```/CM4```"#^Q$/A"<#``"!^_\/``"0#X0-`@``@_L-#X01 +XM`@``,<"+5:2%T@^$]````(/(((E%P(/_#`^/]````(/_"`^-)`(``(/_!`^$ +XM_0$``(UV``^/4@0``(/_`HVT)@`````/A.0!```/CR0%``"#_P&0#X3@```` +XMH8"8"@B+'0QV"@C'1"0,,.$(",=$)`@)````QT0D!!X```")!"3H7XO^_XE< +XM)`2)!"3H\X0!`,<%L)D+"`$```"^_____XUT)@"-3=")#"3HY2O^_X/$?(GP +XM6UY?7<.%V[[_____=.*#ZP$/A3C___^+50C'1"0$+P```(L"B00DZ)"M_?^% +XMP`^$\00``(M5I+\$````N!$```"%T@^%$____XVT)@````"#R$"#_PR)1<`/ +XMC@S___^#_Q,/A#`!```/CS<"``"#_Q`/C_4```"#_PZ-M@`````/C1(!``"+ +XM50B+`HD$).BMH@$`B46HB47LZ?H```")]L=$)`0O````B00DZ`RM_?^%P`^% +XM\_W__XM%[+\#````NP,```")1:CK=HVV`````(M5&(U-W(D,)(E4)`3H[J`! +XM`(M5X(72=!V+1=R#?)#\+W03C47__^%P(GX +XM_O__C5W$QT0D!+"1"`B)'"3HU2K^_XM%Z(M-P(M5J(D<)(E$)!"+11B)3"0, +XMC4W@/A&X&``"+5>"%TG0HBT7<@WR0_"]T'HU-W,=$)`0O````B0PDZ&&< +XM`0"-1=R)!"3HMIP!`('G_^___X/_!`^$?_[__P^/$00``(/_`0^$#@4``)"- +XMM"8`````Z&>G_?^%P`^.L_S__XD<).A[G`$`BT7$BTW0BU4(B00DB?CH".#_ +XM_Z'48PD(A<`/A8O\___'1"0$Q)@*",<$)*`Q"0CH!Y#__X7`#X1O_/__@_X! +XM#X5F_/__@WT<_XGV=#:+11R%P`^%E04``(M=Q(M-W(D<)(E-K.B2)___@_\3 +XM#X:$````,<")1"0$BT4(B00DZ)B;`0"+10B)!"3H[9L!`.D8_/__@_\. +XM_/__#X[F````BT4(BQB#?0P�/`0``BT7LB00DZ/\R`0")'"3H-Y\!`(E% +XMJ(E%[.F$_?__@?\2$```#X6&^___Z9C^__^!_P$0``"0C70F``^%B+1=")%"2-5=SHW]K__X7`B<8/A07[__^# +XM3<`"Z:3\___'!"0-````Z/!"___IBOW__XD<)#'VZ%&@`0")!"3HJ2C__X7` +XM#X71^O__D.G1_O__BT6@A<`/A03[___I&OK__\=$)`3$F`H(QP0DP$()".B7 +XMCO__/?AO"0@/A/L!``"+$(72#X3Q`0``]\(```!`#X7E`0``@_I_C78`#X?9 +XM`0``B<$QP/8$E;U1"0@$=3/IQ@$``(VT)@````#WP@```$`/A;,!``"#^G^0 +XM#X>I`0``@\$$]@25O5$)"`0/A)@!``"-!("-1$+0BU$$A=)URX7`#XZ"`0`` +XM.?`/C7H!``"+112%P`^$;P$``*&`F`H(QT0D#!O?"`C'1"0(!0```,=$)`0> +XM````B00DZ"N%_O^)=;R)!"3HD"[__\=$)`0P*@@(B<.)!"3H7B;^_Z&`F`H( +XMQT0D#&CA"`C'1"0(!P```,=$)`0>````B00DZ.F$_O^+5;R)7"0(B50D!(D$ +XM).AV?@$`B1PDZ'XE_O_H63___XU%\XE$)`2AM'8*",=$)`@!````B00DZ/TE +XM__\/OD7SQP0D`]\("(E$)`3H.7X!`*&`F`H(#[Y=\\=$)`P(WP@(QT0D"`T` +XM``#'1"0$'@```(D$).APA/[_B5PD!(D$).B0I/W_A<`/A"W[__^#_P]T,8VT +XM)@````#H.[___\=$)`P@S`8(QT0D"`0```")="0$B00DZ+NA_?^#_Q`/A#P! +XM``#H$;___\=$)`P!````B70D",<$)/AO"0B)1"0$Z#75___IT?K__X/_!0^$ +XMLOW__X/_$HUT)@`/A>+[__^#3<`$Z4GZ___'1"0$Q)@*",<$)(!""0CH?8S_ +XM_SWX;PD(#X1F____BQ"%T@^$7/____?"````0`^%4/___X/Z?P^'1____S'; +XMB<'V!)6]40D(!'4LZ33____WP@```$`/A2C___^#^G^0#X<>____@\$$]@25 +XMO5$)"`0/A`W___^-!)N-7$+0BU$$A=)URX7;#X7$````A=L/G\")=;R$P`^$ +XMY_[__SE=O`^.WO[__XM%%(7`#X33_O__BT6\A<`/A,C^__^A@)@*",=$)`S^ +XMW@@(QT0D"`8```#'1"0$'@```(D$).C_@O[_Z=+]__^+1>R)!"3HORX!`.E` +XM^/__Z-6]__^%]HG'D`^.J_G__S';ZQV-M@````"#PP''!"0*````Z($___\Y +XM\P^$BOG__XL$G\<$))*Y"`B)1"0$Z$9\`0"A8&0)"(7`=,W'!"0-````Z%$_ +XM___KOX/_$`^$,____XVV`````.AKO?__A?:Z`0```(E%L'XVQT6X`````,=% +XMM`````"+5;B+3;"+!)&)!"3H/*']_SE%M',#B46T@T6X`3EUN'7>BU6T@\(! +XMH>"7"@B)T3'2QT68`0```(/``??QA<")191T`XE%F(M%F(U4!O^)T,'Z'_=] +XMF(7;B46\#Y_`Z;/^__^+51R+30B)5"0$B0PDZ!R6`0#I?_K__X-]#`)T.)#H +XM-Z/]_XL`B00DZ-V@_?_'!"3WW@@(B40D"(M%W(E$)`3H6GL!`,<$)`&Z"`CH +XM3GL!`.E6]O__QP0D`;H(".@]>P$`Z/2B_?^+`(D$).B:H/W_QP0D]]X("(E$ +XM)`B+1=R)1"0$Z!=[`0#I'_;__XGV58GE5U93@>RL````BUT(BT4,QT70```` +XM`,=%U`````#'1=@`````C02#B85X____C470QT7P^&\)",=%[`````#'1"0$ +XML)$("(D$).AO(O[_.YUX____#X-H"0``BY5X____,?^)G7S____'A6C___\` +XM````QT6@`````(/J!,>%#;WP@```$!U+H/Z?W\I#[;"#[>$`.`@"0CVQ"!T +XM"8M-U(/!`8E-H*A`=`PYG6#___\/APP#``"-````B00DZ)A^_O^)7"0$B00DZ"QX`0#'180! +XM````C570B10DZ"H?_O^+182!Q*P```!;7E]=PX-]$`8/A%/___^+A6C___^# +XM?1`$B85L____#X0]____@WT0"W>#BT40_R2%W-\("(/Z?@^$&/[__XU-T(E4 +XM)`2)#"3H5)(!`(M-U(M%T(M4B/R%T@^).?[__XGV@\,$Z6S^__^+$X72>#+W +XMP@```$!U*H/Z?W\E#[;"#[>$`.`@"0BH0706A?]U"C'7@\,$Z6C^__\YUW3R +XMC70F`(/_)P^$,/W__X72D(UT)@`/B%W]___WP@```$"-="8`#X5-_?__@_I_ +XM#X]$_?__#[;"]H0`X"`)"`(/A`7]__^#=8@!#X6&````BX5P____@\,$BXUT +XM____B85H____BT6`B4V@B85\____B50D!(U5T(D4).B&D0$`Z>']__^+0P2- +XM7\__\-````0(E$)`2-1=")!"3H6Y$!`(U#"(GSB<;I-/W_ +XM_X/Z?P^/%OW__P^VPO:$`.`@"0B"#X72_O__Z0#]__^+1=2#PP2+C6C___^# +XMP`&)C7#___^+3:")A6C___^)1:"+A7S___^)G7S___^)C73___^)18#I8/__ +XM_\=%Q`````#'1<@`````QT7,`````,=$)`3$F`H(QP0D@$0)".CLA/__A<`/ +XMA%D%``"+C6S____'1"0$+P```,'A`HG+`UW0B4V!VI````0'46@_A_?Q$/ML#V +XMA`#@(`D((`^%3`<``(/"!#E5C'?5B5PD!(U=Q(D<).B[D@$`B1PDZ*.0`0#' +XM1"0$L)$("(D<).A3'?[_BT7LQT0D#`$```")="0(B1PDB40D%(M%\(E$)!"+ +XM11")1"0$Z&KN__^+E6S___^-3=")#"2)5=2)182+1<2)1"0$Z%R2`0"-1=") +XM!"3H09`!`(D<).A9'/[_@WV$_L<%Y&,)"``````/A,$%``"+1="+E63___^+ +XM')"%VP^$_/S__XM5F(T,$#'`A?\/E,")!"2+E7C___^+A7S____H0-3__X7` +XM#XG3_/__C4W0B0PDZ/T;_O_'183_____Z/__ +XM_P^4P(G9B00DBX5\____Z-#3__^%P`^(W@0``(D<).BP)@$`QT6$`0```.E/ +XM_/__H=B7"@B#Z`*#^`$/EL`/ML")1"0$BX5L____P>`"`T70B00DZ(OL_?^% +XMP(G#=9C'180`````Z13\__^-1>2)1"0$BX5L____P>`"`T70B00DZ"Y:`0"% +XMP`^$\`(``(M%Y(D$).@[)@$`QT6$`````.G:^___BX5L____C5W$QT7$```` +XM`,=%R`````#'1`"`T70B1PDB40D!.C/D`$`B1PDZ+>.`0#'1"0$ +XML)$("(D<).AG&_[_BT7LQT0D#`$```")="0(QT0D!`````")1"04BT7PB1PD +XMB40D$.A][/__BY5L____C4W0B0PDB574B46$BT7$B40D!.AOD`$`C470B00D +XMZ%2.`0")'"3H;!K^_^DR^___BXU\____.8UX____QT7$`````,=%R`````#' +XM1@/A&4!```QTH/^`0^4PHU%Z.CCUO__B<:+1=R)!"3H%AG^_XM%Z#G' +XM=!#'1"0$\",&"(D$).B?&?[_A?8/CH4```"#?1`'#X1"`@``BX5\____,=LI +XMA7C____!O7C___\"BY5X____B10DZ.H?``"+1>CK!X/#`3GS=$^+%)B%TG3R +XMBPJ%R73LB10DZ#D8__^+1>@QTHL,F#'`QP0D`````.C#T/__A<`/B-@"``#' +XM!"04/0D(Z$\W``"%P`^(Q`(``(M%Z.NMBT7H.<=T"(D$).AC&/[_B76$Z2;Y +XM__\Q_XF=?/___\>%:/___P````#'1:``````QT68`````.DN^/__,<"%_XM- +XMY`^4P(N5>/___XD$)(N%?/___^A(T/__AC'1"0,`````(ET)`C' +XM!"3X;PD(B40D!.@,Q___BT7HZ17^__^+58R)%"3HV8T!`,=$)`0P*@@(B460 +XMB00DZ`87_O^!?8SX;PD(=`F+38S'`0````"AX*P+"(D<)(E%Q*'DK`L(B47( +XMH>BL"PB)1,`0")'"3H_XD!`,=$)`2PD0@(B1PD +XMZ*\6_O^+1>R)="0$B1PDB40D#(M%\(E$)`CH50,``(E%A(/H`0^$B@```(M% +XMQ(N-;/___XE$)`2-1=")3=2)!"3HOHL!`(U5T(D4).BCB0$`BTV0B0PDZ+@5 +XM_O_I;OG__XM%Z#G'#X2@^?__B00DD(UT)@#HFQ7^_^F.^?__QP7D8PD(```` +XM`.FM^/__Z#*W__^)-"3HFHH!`(DT)(E%Z.B_%?[_B30DZ&<5_O^+=R)="0(B50D!(D<)(E$)!2+1?")1"00Z/#F__^)183I'____Y"0 +XMD)"0D)"058GE5U93@^P+!HG3B<&!X____S^!X?___S\YRW3>A=)U0XL.A-1P2)1>R+5P2%TG4CC48$B47PBT7PB40D!(M%[(D$).AMOO__N@,` +XM``"%P'6XZX>-1@2)1?"+1@2%P'36)?___S\YPW7-@>+___\_.=%UPXU&"(E$ +XM)`2-1PB)!"3H,+[__X7`=:WI1____XVT)@````!5B>575E.#[#R+10C'1>@` +XM````C77HQT7<`````,=%[`````#'1?``````BQC'1>``````QT7D`````,=$ +XM)`2PD0@(B30DZ/42_O^-5=S'1"0$L)$("(D4).CB$O[_BP.#^"\/A+0```"- +XMM"8`````A7UW#B30DN______HS1#^ +XM_X/$/(G86UY?7<.0D)!5B>57B<]6B<93@^P,BUH,A=MU$>M/BT,$@S@M=$*+ +XM6Q"%VW1`BT,,A+0P2)1"0$B30DZ$+$ +XM_O^%P'3,BP.%P'3&@\0,6UY?7<.#P`3KW8/$##'`6UY?7<.058GE5U93B<.# +XM[#R)1=R-?>B)5=B)3=3'1>@`````QT7L`````,=%\`````"+$X72="H[50QT +XM)8/Z)(US!'4)@WL$.HUS!'1HB50D!(D\).A\@P$`B?.+$X72==:)/"3HC(,! +XM`(M-##D+B<*-0P0/A`(!``")%"3H]!H!`(M%W(D$).A)B0$`B40D#(M5$(E4 +XM)`B+30S'!"1_````B4PD!.A;#?[_@\0\B=A;7E]=PY"-0PB)1>"+0PB#^"V) +XMP0^$OP```('A````0`^%>/___X/X+8G!#X2P````@_E_B?8/AV+____V!(V] +XM40D(!`^$5/___S')@_@M#X2=````BUW@@^@PBW7@BU,$@\8$]\(```!`="/K +XM)O8$E;U1"0@$=!R-5`+0@\8$C02`C01"BQ;WP@```$!U!8/Z?W;:AR+`HL8A=MT8HG&QT7P```` +XM`.LZD(UT)@"AX%T)"(M$F#3!Z`Z)QX/G`70-BT7PA&!^_\```!VN8D<).B]B_W_D.NW +XMQP0D)P```.@"*O__@T7L!(M%[(L(AR+ +XM$H72#X51____@\0,6UY?7<-5B>564X/L((M%"(MP!(7V=$.-4`B+0`B%P`^$ +XMP````(D4).CX%O__B30DBB* +XM_O__QP0D"@```.@>*?__BT,0ANID(UT)@")PXM#%#M8$'3VB7<.)-"3H_@O__S')NJ"D"PCH +XMTOO__X7`==#I%____XGVC;PG`````%6)Y5=64X/L#(7`=`6CZ&,)"(L]Z&,) +XM"(L'B?J%P`^$S0```*D```!`=4F+'>!="0CK)XM$@S3VQ$!T,H/'!(D]Z&,) +XM"(L'A<`/A*(```"I````0`^%HP```#W_````=M*)!"3HTXG]__;$0'7.BQ7H +XM8PD(BQJ)UHG8)0```$")1?!U%H'[_P```'=;H>!="0B+1)@T]L1`=6J%VW@B +XMBT7PA@\8$ +XMB37H8PD(BQZ%VW6ABP>%P'04@\0,B?A;7E]=PXD<).A-B?W_ZZ0Q_X/$#(GX +XM6UY?7<.)^NEP____C58$QP8`````B17H8PD(Z\*+/7P@"0CKP(UV`%6)Y5=6 +XM4X/L3(M="(MU%(D<).BI@@$`QT0D!#`J"`B)1B-!(4(````B00DZ`H7`0#'1"0$,"H("(G'B00DZ*@+_O^+17UW#.P5\(`D(=-XQR8/^ +XM`0^4P;J@I`L(Z`;Z__^Z!````,=%U`$```"%P(E%T'44Z:8"```[!7P@"0B- +XM5@1TJ8-%U`$QP(G6C1P7Z!/^__^+3=2%P(D$CW7;BPU\(`D(A8"C1PWZ0_____'1=@`````BTL$]\$```!`B4W< +XM#X79`@``@?G_````#X=O`@``H>!="0B+5=R+1)`T]L0@#X2X`@``H8"8"@B# +XMPPC'1"0,Z;T(",=$)`@#````QT0D!!L```")!"3H;6C^_XM-U(U5\(D4)(GZ +XMB40D"(M%W(E$)`2)V.BP^/__QT0D!#`J"`B)PXM%\(D$).B+"?[_BT7PBPB% +XMR0^$EP(``*&`F`H(QT0D#%+K"`C'1"0(!0```,=$)`0;````B00DZ`EH_O^+ +XM3=R)^HE,)`2+3=2)1"0(C47LB00DB=CH3/C__\=$)`0P*@@(B<.+1>R)!"3H +XM)PG^_XL3A=(/A((!```QP(M-&#E5W`^5P(/H`0G"B1&#?<0M=FWH'(?]_X-] +XMU`''1=@@)0D(#X;7_O__BU0^^(E5V.G+_O__@WW4`L=%V"`E"0@/AKK^__^+ +XM1#[TB478Z:[^__^+1=3'1=@@)0D(A<`/A)S^__^+3#[\B4W8Z9#^__^+5QC"0B+=>R%P'02B00DZ(82`0#'!>QC"0@`````BP8E____OX/H)(/X +XM5`^&9P$``(DT)+O_#P``Z+R``0#'!"1]````B40D!.C")!"3HSVS__SG##XX]____Z>7\__^)!"3HNFS__SG##Y3`#[;`Z1O___^+ +XM2`2%R0^%QO[__^D3____H8"8"@B^_P\``,=$)`R6X0@(QT0D"`(```#'1"0$ +XM&P```(D$).BS9?[_BTWP`^V +XMP.E@_O___R2%$.,("*&`F`H(QT0D#`>]"`C'1"0(!````,=$)`0;````B00D +XMZ`9E_O_KF(-]R&,/A3#^__^+30S!X`(!`8GVZ2'^__^[$0```(M&!"7___^_ +XM#X1<_O__@_@Z#X4V_O__C48(B00DZ-1\`0"+31"C[&,)"(D!B00DZ,($___I +XM,?[__[L"````Z\"[!P```)#KN+L2````Z[&["@```(GVZZ@QV^NDNPX```"0 +XMC70F`.N8NQ````#KD;L3````B?;KB+L$````ZX&["P```(GVZ77___^[!0`` +XM`.EK____NP$```#I8?___[L,````B?;I5?___[L)````Z4O___^)-"3H.7P! +XM`,=$)`1@````H^QC"0B#P`2)!"3HG8;]_X7`=`?'0`0`````H>AV"@B%P'4_ +XMH;1V"@C'1"0$`````(D$).BH"___HQC"0B[_P\``,=$)`0"````B00DZ,2Q_O^% +XMP(G�>_?__H>QC"0AFNPT`B00DZ%D/`0#'!>QC"0@`````B30DZ(=[`0"+ +XM51"C[&,)"(D"B30DZ#4/`0#IY/S__[L(````Z7#^__^[$A```)#I9?[__[L/ +XM````Z5O^__^[!!```.E1_O__NP40``")]NE%_O__NP$0``#I._[__XU&!(D$ +XM).@F>P$`BTT0H^QC"0B)PXD!QT0D!"D```")!"3HAH7]_X7`=`;'``````") +XM'"2[#0```.CS`O__Z6+\__^-1@2[!@```(D$).C>>@$`BU40H^QC"0B)`HD$ +XM).C,`O__Z3O\__^0D)"0D)"058GE5U93B<.#[!R+,*%P80D(C7WPQP5P80D( +XM`0```,=$)`30.`8(B3PDB47PZ,X#_O^+6P2%VW0:C;0F``````^^!H/&`8D$ +XM).@B'___@^L!=>V)/"3H!0/^_X/$'%M>7UW#C;8`````C;PG`````%6)Y5=6 +XM4X/L+(M%"(M]$(E%Y(M%#(E%X*'T8PD(A<`/A#L!``"AP)@*"(7`#X10`0`` +XMH>AV"@B%P`^%$@$``(LU_)D+"(7V#X03`0``C78`BT7DB00DZ!5\`0`#1>"# +XM_SJ)1>P/A',!``"#_S['1>A()0D(#X2&````,!R[8E4)`B+`XE$)`2+1>PI +XMT(D$).AM?_W_A+B8)@D(Z$[^ +XM__^)?0B#Q"Q;7E]=Z5\?__^A;)D+"(7`#X7R_O__B?:+1>3'!"22N0@(B40D +XM!.AM6@$`B7T(@\0L6UY?7>DN'___BQWH=@H(A=MT%(L-?)@*"(7)=,KIM?[_ +XM_Y"-="8`BQ7@=0D(A=)TMNFA_O__D+AH)@D(Z-;]__^X."8)".C,_?__N(`F +XM"0CHPOW__XE]"(/$+%M>7UWITQ[__\=%Z"`F"0CI%____XT$28/Y%(T$Q4@E +XM"0B)1>@/A0'____IJ_[__XVV`````(V_`````%6)Y5>)QU93@^PLBW4(B57@ +XMBQ^)3=R+$HE5\(L"A<`/A(,````E__\_`#GP='J#^#IU->MS@_A>=#.#P@2) +XM5?")1"0$B1PDZ*1X`0"+5?"-#!B+`H7`="DE__\_`#GP=""#^#IT&XG+@_A< +XM=`!``!U +XMW87VQP4`9`D(`````,<%^&,)"`````#'!?QC"0@`````#X32`0``B30DNQ`` +XM``#H]GW]_XEU\(L6A=*)Q[@0````="V)\;,!C;8`````@>+__S\`,<"#^CH/ +XME,"#P02)3?"+$0'#A=)UY(G8P>`$B<,!^(D$).AC"P$`B77PQP7\8PD(```` +XM`(T4&(D5`&0)"(E5[(E%Z*/X8PD(Z$W\_?_'!"0`F@L(B46LH2R:"PB)1=RA +XM*)H+"(E%V*$DF@L(B474H2":"PB)1="A')H+"(E%S*$8F@L(B47(H12:"PB) +XM1<2A$)H+"(E%P*$,F@L(B46\H0B:"PB)1;BA!)H+"(E%M*$`F@L(B46PZ(I] +XM_?^%P'5IBU7PBS*%]G1@B?.!X___/P"#^RH/A-X```"#^SH/A,H```"+0@2% +XMP(E%J'01BT(()?__/P"#^#T/A"N[D(UT)@`E__\_`(/X.G2L +XM@\($B57PBP*%P'7JBU7PBS*%]G6@BT6LB00DZ!;^_?^+1=RC+)H+"(M%V*,H +XMF@L(BT74HR2:"PB+1="C()H+"(M%S*,@K!?AC +XM"0C!^`2C_&,)"(/$7%M>7UW#C4($B47PZ0C___^+3>B-0@2)1?"-5?"-1>S' +XM!"0]````Z.?\__^%P'0*BT7HBT`$A``````)?__/P")1:3K#8-%X`&#QQB#?>`4=$"+CT0E"0@/ +XMO@$YPW7F#[Y!`3M%I'7=C4(,B47PBT7@C57PQP0D.@```(T,0(T,S4@E"0B- +XM1>SH-_S__^DX_O__BT6HB70D!,<$)(8```")1"0(Z*OZ_?_I/?___XVV```` +XM`%6)Y5=64X/L#,=$)`3$F`H(QP0D:$P)".AS9/__A<")QP^$J0```(L`A<`/ +XMA)\```"+`(7`='F+`(7`='/'!?!C"0@`````QP7T8PD(`````(L'BQB%VW1K +XMO@0```#K%L<%\&,)"`$```"+!XL<,(/&!(7;=$['1"0$R$P)"(D<).CV>?W_ +XMA7UW#D)"0D%6%P(GE=1''!7!W"@C`JPL(HSB:"PA=PX/X`77Y +XMQP5P=PH(P*0+"*,XF@L(Z^B)]E6+#31W"@B)Y5.+70C!XP*-!`L[!;"8"@AS +XM,3L-5)D+"'8CB<*+`8/I!(D"H529"PB#Z@0YR';MBQ50F0L(A=)T!#G"=PD! +XM'31W"@A;7<.-!!.C4)D+".OMC;0F`````(L5-'<*"%6+#529"PB)Y593BUT( +XMB=`IR,'X`CG8?@*)V(7`?E^+'7<,YRL<%/)H+"`(```"C0'<*"(D- +XMD'<*"'(WB7<.--)4`````B=@I\#L%-'<*",<%/)H+"`(```") +XM%4!W"@BCD'<*"'>GB<(QR8T575HG64XG#@^P$B4WPC4@$ +XMBT`$@_A>=#N#^"2_`0```'1!C5#0,<"#^@EW%)"#P02-!("-!$*+$8/J,(/Z +XM"7;MA?]X-8D&@\0$@^D$6XG(7E]=P\<"`0```(/$!(G(6UY?7<.#>P@M=!G' +XM`O___W^#Q`2)R%M>7UW#BU7P*<*)T.O"BT,,C4L,O______KDXVT)@````"- +XMO"<`````58GEBU4(A=)^#XT$E0!V"0@[!529"PAV!UW#D(UT)@!=Z3K^__^- +XM=@"-O"<`````58GEBU4(@^)_@_I_=S+V!)6]40D(!'0HH41W"@B%P'0FH7QW +XM"@@]0$(/`'\3C02`78U$0M"C?'<*"+@,````PUVX9````,-=C4+0HWQW"@BX +XM#````,<%1'<*"`$```##H9QW"@A5B>6#^`%^!:.HF`H(H31W"@B-4`3'``H` +XM``")%31W"@C'0`0`````N`$```!=PXVV`````(V_`````*$T=PH(58GEQP`` +XM````N`,```!=PXUT)@"-O"<`````H31W"@A5B>7'``````"X%````%W#C70F +XM`(V\)P````"A-'<*"%6)Y<<``````+@3````7<.-="8`C;PG`````*$T=PH( +XM58GEQP``````N!(```!=PXUT)@"-O"<`````H529"PB+%31W"@A5B>4YT',( +XM@\`$HU29"PC'`@````"X`P```%W#B?:-O"<`````H31W"@A5B>7'``````"X +XM"@```%W#C70F`(V\)P````"A-'<*"%6)Y<<``````+@-````7<.-="8`C;PG +XM`````*$T=PH(58GEQP``````N`8```!=PXUT)@"-O"<`````H31W"@A5B>7' +XM``````"X$````%W#C70F`(V\)P````"A-'<*"%6)Y<<``````+@5````7<.- +XM="8`C;PG`````*$T=PH(58GEQP``````N`\```!=PXUT)@"-O"<`````58GE +XM@^P$BQ4H)PD(A=)T%*%4F0L(BPU\=PH(*=#!^`(YR'T,R;AD````PY"-="8` +XMB0PDZ.C[__^X#@```,G#D%6X9````(GE@^P$@3U4F0L(`'8)"'<)R<.-M"8` +XM````H7QW"@B)!"3HL_O__[@.````R<.-M@````"-OP````!5B>6#[`2A5)D+ +XM"#L%-'<*"'0MH7QW"@B)!"3HD/K__XL5-'<*"+@.````.154F0L(=@:)%529 +XM"PC)PY"-="8`BQ7(F0L(A=)T%CT`=@D(=`^#Z`2C5)D+".NXD(UT)@#)N&0` +XM``##B?:-O"<`````BPU4F0L(58GE@?D`=@D(="^A-'<*"#T$=@D(=",YP7,) +XM@\$$B0U4F0L(BT'\BU'XB4'XN`X```")4?Q=PXUV`%VX9````,.)]HV\)P`` +XM``"+#529"PBX9````%6)Y8'Y!'8)"'81BT'\BU'XB4'XN`X```")4?Q=PXVT +XM)@````!5B>6#[`R#/0QD"0@!B7PD"(G'B1PDB70D!'0DH529"PB)/0QD"0BC +XM$&0)"+@,````BQPDBW0D!(M\)`B)[%W#BS4T=PH(QP4,9`D(`````,<%$&0) +XM"`````#'!4!W"@@`````@?X`=@D(=BJY`'8)"#';,=*+!)4`=@D(@\$$@\,! +XMB025()D*"(/"`3GQ4]0$(/`'\4P>`"L@S'!41W"@@!````HWQW"@A= +XMB=##C70F`%6X#````(GE7<<%$'8*"`$```##C;8`````C;\`````53'`B>7H +XM]O?__Z%4F0L(7<<%`)D*"`(```#'!3R:"P@$````HY!W"@@QP,<%0'<*"``` +XM``##C78`C;PG`````%4QP(GEZ+;W__^A5)D+"%W'!0"9"@@!````QP4\F@L( +XM!````*.0=PH(,<#'!4!W"@@`````PXUV`(V\)P````!5B>6#[`2A?'<*"(D$ +XM).C]]___,<#H9O?__[@.````RA&]___ +XMH529"PA=QP4\F@L(`0```*,H)PD(HY!W"@@QP,.)]HV\)P````!5,<")Y5W# +XMB?:-O"<`````,<"#/0"9"@@`58GE70^4P*,`F0H(,<##D(VT)@````!5,<") +XMY5W#B?:-O"<`````53'`B>5=PXGVC;PG`````%4QP(GE7<.)]HV\)P````!5 +XM,<")Y5W#B?:-O"<`````53'`B>5=PXGVC;PG`````%4QP(GE7<.)]HV\)P`` +XM``!5N`,```")Y>A3_?__70^^P,.-M"8`````C;PG`````%6X`0```(GEZ#/] +XM__]=#[[`PXVT)@````"-O"<`````58GE5U93@^P$H3R:"PB#^`(/A($```!_ +XM%X/H`0^$SP```+AD````@\0$6UY?7<.0@_@##X2X````@_@$=>2A0'<*"(7` +XM#X0\`0``BQV0=PH(B=XK-31W"@B)'529"PC!_@(YQ@^,%@$``(7V?ATQR8L4 +XMC2"9"@B+!(N)!(T@F0H(B12+@\$!.?%UY8/$!+@.````6UY?7<.A0'<*"(7` +XM#X3B````BQV0=PH(B00DB1U4F0L(Z,?U__^+#4!W"@B%R7X7,=*+!)4@F0H( +XMB023@\(!.15`=PH(?^O'!3R:"P@!````@\0$N`X```!;7E]=PXLU0'<*"(/^ +XM``^$AP```(L]D'<*"(G[?AF)^C')B?:+`H/"!(D$C2"9"@B#P0$Y\77MBQ4T +XM=PH(.==V">LED(LU0'<*"(L$LXD#BQ4T=PH(@\,$.=ISZ(LU0'<*"(L]D'<* +XM"(T$M0`````IPK@.````B3U4F0L(B14T=PH(QP4\F@L(`@```(/$!%M>7UW# +XMB<;IX_[__S'`Z9G^__^)]E6X9````(GE7<.-M@````!5N&0```")Y5W#C;8` +XM````5;AD````B>5=PXVV`````%6X9````(GE7<.-M@````!5N&0```")Y5W# +XMC;8`````5;AD````B>5=PXVV`````%6)Y8/L",=$)`0`=@D(QP0D\)D+",<% +XM])D+"`````#H+&8!`,<$)/"9"PCH$&0!`*$T=PH(Q@4D=PH(`2T`=@D(P?@" +XMH^B9"PBA5)D+""T`=@D(P?@"HS!W"@BAG'<*"*.HF`H(R<.)]HV\)P````!5 +XMB>6#[`CHA?___Z$T=PH(QP6HF`H(`````(U0!,<`"@```(D5-'<*",=`!``` +XM``"X`0```,G#B?:-O"<`````58GE@^P(H529"P@[!31W"@AT+:%\=PH(B00D +XMZ"#T__^+%31W"@BX#@```#D55)D+"'8&B154F0L(R<.0C70F`.C;DP``H31W +XM"@C'``````"X!````,G#B?:-O"<`````58GE@^P(Z.7^___'!9QW"@@````` +XMZ*:3``"A-'<*",<``````+@+````R<.-="8`58GE@^P(Z(63``"A-'<*",<` +XM`````+@%````R<.-=@!5B>6#[`CH99,``*$T=PH(QP``````N!$```#)PXUV +XM`%6)Y8/L".A%DP``H31W"@C'``````"X!````,G#C78`58GE@^P(Z"63``"A +XM-'<*",<``````+@)````R<.-=@!5B>6#[`CH!9,``*$T=PH(QP``````N`(` +XM``#)PXUV`%4QP(GE@^P(Z'/R__^A-'<*",<%/)H+"`$```"C5)D+"*,H)PD( +XMHY!W"@CHL*8``#'`R<.-M@````"-OP````!5,<")Y8/L".@S\O__H529"PB+ +XM%31W"@@YT',6@\`$.<*C5)D+"'(HZ'.F``"A5)D+"*,H)PD(HY!W"@@QP,<% +XM/)H+"`$```#)PXVV`````(D55)D+".O0D(VT)@````!5B>6#[`C'!529"P@` +XM=@D(QP4H)PD(`'8)",<%D'<*"`!V"0C'!3R:"P@!````Z`VF```QP.BF\?__ +XM,<#)PXGV58GE@^P(H5"9"PB+%529"PBC5)D+"(D54)D+".C?I0``,<#)PXUT +XM)@"-O"<`````58GE@^P(BQ60=PH(H529"PC'!2@G"0@`````QP4,9`D(```` +XM`,<%$&0)"``````YPL<%1'<*"`````!V*"G"P?H"B15`=PH(N`$```#'!0"9 +XM"@@`````Z!3Q___H;Z4``#'`R<,IT,'X`J-`=PH(Z]?K#9"0D)"0D)"0D)"0 +XMD)!5B>53@^P$]@4,9`D(`G5ABQ409`D(QP4,9`D(`````(72=#:A5)D+",<% +XM/)H+"`(````YPG))=R?'!"0!````NP$```#H-O'__Z%4F0L(B1U`=PH(HY!W +XM"@B#Q`1;7<.)TRG#P?L"B1PDZ!'Q___KV3'`Z'CP___KEHVV`````(G#*=/! +XM^P*)'"3HX?'__^B\I```Z[2-=@"-O"<`````58GE5HG6BQ4T=PH(4XG#H529 +XM"PB#[@&#_O]T%CD8=`@YT'/P.1AT[(/`!)"-="8`Z^XYPKYD````=B53B<.#[`2A5)D+"(GV +XM@^H!@_K_=!HY&'0/C70F`#T`=@D(=NDY&'3E@^@$B?;K[CT`=@D(<@IU$SD= +XM`'8)"'0+N&0```"#Q`1;7<,Y&'0F]@4,9`D(`:-4F0L(="*#P`2C5)D+".CC +XM_?__@\0$N`X```!;7<.%R736@\`$D.O0Z!FC```QP.N]D(UT)@!5NF0```") +XMY8/L"*$$9`D(A6#[`B+#529"PB+ +XM%31W"@@YT7,TH7QW"@B-!($YPJ-4F0L(6#[`B+ +XM%529"PB!^@!V"0AV/XL-?'<*"(G0+0!V"0C!^`(YR'PSC02-`````"G"H6#[`BA-'<*"*-4F0L(HB00DZ$YE_?_VQ$!UVO8%#&0)"`%T$>B/^O__ +XM@\00N`X```!;7EW#Z,Z?``"#Q!`QP%M>7<.0C70F`%6)Y5>)UU93@^PS_#X2-````.?YR&.OLC70F`(-^_%QT6(/&!#GW +XMD(UT)@!VUHL>BT4(B5PD!(D$).CI:/W_A575HG&4X/L'(M]"(E5[(E-Z(-MZ`&# +XM?>C_#X2'````BUWL.=YW&>F,````B?:#>_Q<=!Z#PP0YWI"-="8`=GB+`XD\ +XM)(E$)`3HO&?]_X7`==R)7?"+1?"Y`0```(GRB3PD@^@$Z&3^__^-6`0YWG,/ +XMZR.#>_Q<=!F#PP0YWG(6BP.)/"2)1"0$Z'QG_?^%P'7A.=YWO(-MZ`&#?>C_ +XMBW7P#X5Y____BT7L.?!S`HGP@\0<6UY?7<.)WNE3____ZPV0D)"0D)"0D)"0 +XMD)"05;AD````B>53@^P$BQU4F0L(@?L`=@D(=#&+#7QW"@BZ`'8)"(G8QP0D +XM,$T)".C]_O__]@4,9`D(`:-4F0L(=!#H*OC__[@.````@\0$6UW#Z&J=```Q +XMP.OQC;8`````58GE@^P8Z&6)``"-10B)1"0(QT0D!&5T`""AM'8*"(D$).CU +XM8OW_AH5"9"P@[!529"PAT$>BGAP``Z"*(``")]N@;F```H529 +XM"PC&!575E.#[`RAN)@*"(7`#X06`0``BPTXF0L( +XM*PU\=PH(A/>)#3B9"PB)RHG#P?H?BZ/__BQU4F0L(B30DZ`#G__^+%3B9"PBA*)D+"(L$T(L0 +XMA=)T#XD3BU`$@\,$@\`$A=)U\87_=&.A5)D+"(D=5)D+"*-0F0L(QT0D!,28 +XM"@C'!"0@20D(Z"5*__^%P'0)@#W,F0L(`'5'Q@7,F0L(`(/$#+@.````6UY? +XM7<.#Q`RX9````%M>7UW#B=._`0```"G#P?L"Z23___^)'5"9"PCKI8D<).C& +XMYO__Z5/___^0Z)N%``#H%H8``.NLC70F`%6)Y5.#[!2+#;B8"@B%R74/@\04 +XMN&0```!;7<.-="8`BQ4XF0L(H2B9"PB+!-")!"3H)F#]_XG"C02%``````,% +XM-'<*"#L%L)@*"'/$B10DBQU4F0L(Z/7E__^+%3B9"PBA*)D+"(L$T(L0A=)T +XM$)")$XM0!(/#!(/`!(72=?&#/7QW"@@!=#F)'5"9"PC'1"0$Q)@*",<$)"!) +XM"0CH'DG__X7`=`F`/6#[!B)7?B+'3!D"0B)=?R)QJ$T9`D(B70D +XM!(D<)(E$)`CH@V#]_[H!````A7UW#@\0,N&0```!; +XM7E]=PXL=5)D+"('[`'8)"',=Z^.)="0$B1PDZ*"3_O^%P'7#@^L$@?L`=@D( +XMNBC70F`(V\)P````!5B>564X/L$(LU +XM?'<*"(7V#XZ,````H1QW"@B%P`^$?P```(M(!(M1!(72='6+6`BX_____SG9 +XM=!,QP)"-="8`@\`!.<9_/H/H`8G1B40D",=$)`0`````BT$$B00DZ!TG`0") +XMPXD$).@#_O__A7<.#Q!"X9````%M>7<.)]E6)Y5=64X/L3(L=5)D+ +XM"(/K!('[`'8)"'8XBP.#^"!T,X/X"70NBQ6,F`H(.=")5;QU%.LWBP.#^"!T +XM&(/X"9!T$CM%O'0E@^L$@?L`=@D(=^.+`SD%C)@*"'0-Z'^2``"#Q$Q;7E]= +XMPXE%O(US!(EUX(M3!(/Z(`^$Z0$``(/Z"0^$X`$``(/X((G"="B#^`D/A`\% +XM``"!^P!V"0@/AA,"``"#ZP2+$X/Z(`^$!0(``(/Z"77AH529"PB)1<`Y5;QT +XM$CL=5)D+"',*@\,$BQ,Y5;QU[HU#_#T`=@D(#X+A`0``@WO\7`^%UP$``(U3 +XM^+D!````ZPJ+`H/J!(/X7'4+@\$!@?H`=@D(<^OVP0%U`X/#!#M=P`^#/___ +XM_XG*P>H?C001@^`!*="#Z`%UGXL5''<*"(72B570#X0;`0``BST$F0H(B=XQ +XMTH/'`8E]N(U&!(E%V(M&!(/X*@^$@P$``(/X7@^$R`(``(/X)`^$9`(``(72 +XM#X4,!0``@_@ZBWW8#X0*!```.46\#X2%`P``@_@@#X0J!```@_@)C78`#X0> +XM!```@_@Z#X05!```.WW`#X,,!```,#^"!T,(/X"70K@_@Z="8Y?#^"!UT(M5S(/O!(72#X6>`@``B?@I\(G&BT70P?X"A8``.@TH```B5W'+3@2)]XU!T(/X"78+@_DM=`:)^(GWZSZ#^20/A9$!``")^(GW@W@( +XM+71WN@$```")_NGM^___@_DM#X1K`0``@_DJD'0.@_DD=`F#^5X/A3$!``") +XM^(/Y)'3*@_E>=")1<#I^OK__X/O!#')Z?O^__^+4`R#^B\/CGW___^# +XM^CD/CW3___^+=="+5@2%T@^$:OS__XM2!(MV"#GR#X1<_/__,?^+4@2#QP$Y +XM\G7VA?\/A$C\__^#^2T/A?H```#'1?``````C5`$B578BU`$@_HM#X3````` +XM@_HJ#X2G````BU7PB478B57LA=(/B`S\__^+1>PYP@^/`?S__XM]T(E$)`B) +XM5"0$B3PDZ&,@`0"+==B#Q@2)1S___]_D.E2____BW78BU8$C4+0@_@)=B*#^B1T'8M5\(U'_XE%[.DQ____ +XMB?F-5?#H4-[__^G^_O__BT78C57LB?GH/M[__XM5\(E%V.D*____C78`58GE +XM@^P(H31W"@C'``````#HJOC__S'`R<.-M@````!5B>575E.#["RA8&0)"(7` +XMB47@#X6"````H;1V"@B-?>['1"0(`0```,=$)`0!N@@(B00DZ%?7_O^+10B) +XM/"0E__\_`(E$)`3H4T\!`(7`B<9T)3';C00?@\,!B40D"*&T=@H(QT0D!')T +XM`8")!"3H.%7]_SGS==V+3>"%R70&D.C;60``BT4(B00DZ'#R__^#Q"Q;7E]= +XM#[[`P^C`6```Z73___^-="8`C;PG`````%6)Y8/L".@EG```Z,!Z``"X#@`` +XM`,G#B?:-O"<`````58GE@^P(QP0D`````.BN50``N`X```#)PXVT)@````!5 +XMB>575E.#[`R+?0B%_P^$U0```(L=?'<*"(T$G0`````#!31W"@@[!;"8"@@/ +XM@[8```"#^P$/A+H```"+-0"9"@B%]G1-A=L/CCP!``"+-529"P@QR8L50'<* +XM"(UT)@"+!(Z#P0&)!)4@F0H(@\(!.=F)%4!W"@AUYHD<),<$E2"9"@@````` +XMZ*/:__^+'7QW"@B)'"3H-=K__Z%\=PH(@^@!@_C_HWQW"@AT)(G"D*%4F0L( +XM@^H!B3B#P`2#^O^C5)D+"'7IQP5\=PH(_____^BZB0``,<"#/0"9"@@"=%J# +XMQ`Q;7E]=PX/$#+AD````6UY?7<.A`)D*"(7`=5+'!"0!````Z,79__^A5)D+ +XM"(DX@\`$HU29"PC'!41W"@@`````QP0D`0```.@@C```,<"#/0"9"@@"=:;' +XM!"0`````Z.GG__^#Q`PQP%M>7UW#BQ54F0L(H4!W"@B+$L<$)`$```")%(4@ +XMF0H(C5`!B15`=PH(QP25()D*"`````#HJ]G__^EU____BQ5`=PH(Z>7^__^- +XM="8`C;PG`````%6)Y8/L"*$T=PH(QP``````Z/KU___'!"0@````Z#[^___) +XM#[[`PXGVC;PG`````%6)Y5.#["3HI%0``(U%"(D$),=$)`2P2@<(Z%'5_?^- +XM1?B)!"3H1F```(G#C44(B00DZ)G4_?^#ZP%T%<<$)`````#HZ.7__X/$)%M= +XM#[[`PXM%^(D$).C4_?__@\0D6UT/OL##C70F`(V\)P````!5B>5=Z>=3``"- +XMM"8`````58GE5U93@^P\BPVXF`H(B578*<+!^@*)1=R%R8E5U`^.:`$``,=$ +XM)`3$F`H(QP0DX$D)".@7//__/?AO"0B)PP^$R````*&XF`H(QT0D!(!#"0B) +XM'"2)P@,5/)D+"(E%T(U"_XG"P?H?]WW0B14XF0L(B=>)UNAA4?W_A<`/A30! +XM``"+5="%T@^.B````*$HF0L(BU74QT7L`````(E%S(M%T,'B`HE5Y(/H`8E% +XMR.L/BT7(`?")PL'Z'_=]T(G6BU7,C1SU`````(T\$XM5U(L'B50D"(E%X(M% +XMW(M5X(E$)`2)%"3H45/]_X7`=1&+1>"+5>2+!!"%P`^$*`$``(-%[`&+1=`Y +XM1>QUI>L(H;B8"@B)1="+==2+%3R9"PB+#;QV"@B#Q@$Y3=")%3B9"PA]"XM% +XMT(/``:.XF`H(C1S5`````(/"`8G0P?H?]_D#'2B9"PB)%3R9"P@[GN_O__BT7LBW\$A<")?>A_#>LZBQ4HF0L(B?Z)5____ +XM,<#H%]3__[@.````R<-5N`!V"0B)Y8/L"(L55)D+".BJ^___H529"P@M`'8) +XM",'X`HD$).AEU?__BQ50F0L(A=)T%J%4F0L(.<)V#2T`=@D(*<*)%5"9"PC) +XMN`X```##C;0F`````(V\)P````!5B>6#[`BA5)D+"(L5-'<*".A*^___H529 +XM"P@[!5"9"PBC-'<*"',%HU"9"PC&!6#[`BA5)D+"#L%-'<*"'0= +XMZ*AS``"A-'<*",<``````+@$````R<.-M@`````]`'8)"'76#[`BA5)D+"#L% +XM-'<*"'0MH7QW"@B)!"3H8-/__XL5-'<*"+@.````.154F0L(=@:)%529"PC) +XMPY"-="8`/0!V"0AT%^@4C^_[@"````R<.)]E6)Y8/L"*%4F0L(.P4T=PH(="VA +XM?'<*"(D$).C@TO__BQ4T=PH(N`X````Y%529"PAV!HD55)D+",G#D(UT)@"+ +XM%/__QP58F0L(`0```,<$)`!V"0CHNSX!`#T`=@D(HS1W"@AV(8-X +XM_`H/A(8```"A-'<*"(-X_"!T<8$]-'<*"`!V"0AR6:$T=PH(HU29"PB#Q!2X +XM#@```%M=PX/$%+AD````6UW#B10DZ#85`0#'1"0(`$```,<$)`!V"0B)PXE$ +XM)`3H7'C__XD<).@DUP``QP58F0L(`````.EN____QP4T=PH(`'8)".N;@^@$ +XMHS1W"@CKA8/H!*,T=PH(Z6W___^)]E6)Y5.#[!2+#9QW"@B%R75&H9B8"@B% +XMP`^$#`$``,=$)`@`0```B40D!,<$)`!V"0CHZG?__Z&/P*#X2#````@3TT=PH(`'8) +XM"',*QP4T=PH(`'8)"*$T=PH(HU29"PB#Q!2X#@```%M=PZ.<=PH(@\04N&0` +XM``!;7+!#.%P'01B?#H +XMV>C__X7`=`:+1>R)1?"A#&$)"(7`#X2(````BW\<@T7L`8M%[#D%G'<*"'\P +XMBW7PA?9U#J&8F`H(Z)_H__^%P'1PBT7PHYQW"@CH?OW__X/$'%M>7UT/OL## +XMC78`A?]TS(M'&(7`#X51____B3PDZ#D2`0")1QBA#&$)"(7`#X5&____B3PD +XMZ"$2`0#'1"0$,"H("(G&B00DZ)_)_?_I*O___XDT).CRR/W_B?;I:?___X/$ +XM'+AD````6UY?7<.-M"8`````C;PG`````%6)Y5=64X/L'*$T=PH(QP4,9`D( +XM`````,<%/)H+"`````#'``````"#/9QW"@@`#XQ6`0``#X0A`0``BS4<=PH( +XMA?8/A`8!``#HPOK__XL5G'<*",=%\`$```"%TGX:,<"#P`&+=APYT'7V@\(! +XMA?:)5?`/A-8```"+7AB%VW1LBPT,80D(AL`=@D(B=C!^`*)1"0(Z`I(_?^%P'4'BQ0[A=)T8XGXNP$```#H1^?_ +XM_X7`=%.A#&$)"(7`=%6%VW5=BW87UT/OL## +XM@\06#[`B+%31D"0B%TG07,<"#/2`G"0@5#Y3`@\`5Z(?___\/OL#)PXGV +XM5;AD````B>6#[`B+#31D"0B%R74"R<.A("<)".A?____R0^^P,.-=@"-O"<` +XM````58GE5U93@^PLC77DB478C5WPQT7D`````,=%Z`````#'1>P`````QT0D +XM!+"1"`B)-"3HV<;]_\<$)`!V"0CHC3T!`,=$)`0P*@@(B<>)!"3HN\;]_Z$T +XM=PH(B47#'1"0$*@```(DT).A[.0$`BT78QP4`=@D(`````,<% +XM-'<*"`!V"0C'!529"P@`=@D(HR`G"0C'!"0"````Z/G)__^+%529"P@QP,<" +XM"@```(-]V!4/E,"#Z`&#X/"#P#^)0@2#P@B)%529"PCHBGD``,=%\`````"- +XM=@")'"3H*%$``(/H`75:BT7P@_@-#X2N````?VN#^`B)]G1N@_@*#X2<```` +XMB40D!(DT).C9.`$`H529"PB+5?")$(/`!*-4F0L(HS1W"@CH+7D``,=%\``` +XM``")'"3HSE```(/H`72FB30DZ"'%_?_'!"0`````Z'76__^#Q"Q;7E]=#[[` +XMPX/X&W0\@_A_=9N#?>@!#X91`0``H529"PC'``````"#Z`2#;>@!HU29"PBC +XM-'<*".C%>```QT7P`````.DY____A<`/A#'___^)/"3HN<3]_X-]Z`$/A)P` +XM``#'1"0$*@```(DT).@?.`$`B30DZ'3'!31D"0@`````QP0D,&0) +XM"(E$)`3H:CH!`,<$)#!D"0CH3C@!`(DT).AFQ/W_#[9%V(-]V!7'!31W"@@` +XM=@D(QP54F0L(`'8)"*)(F0L(#X2$````QP0D`````.CC^?__/&0/E,"$P'5= +XM@WWP&[@.````#X2P````@\0L6UY?7<.+'31D"0B%VP^%R0```,<%`'8)"``` +XM``#'!31W"@@`=@D(QP54F0L(`'8)".C2=P``B30DZ-K#_?^#Q"RX9````%M> +XM7UW#Z+AW``"#Q"RX9````%M>7UW#QP0D`````.C?^O__/&0/E,#I=____\=$ +XM)`@`0```B7PD!,<$)`!V"0CHW6___XM%W*,T=PH(BT7@B30DHU29"PCH=1''!9QW"@@`````N&0```#)P^AK]O__ +XMR0^^P,.-M@````!5B>6#[`BA-'<*",<%/)H+"`````#'``````"AG'<*"(7` +XM="RA?'<*"`$%G'<*".@L]O__/&1U1.@C]O__C78`Z-MU``"X9````,G#C70F +XM`,<%G)@*"`````#'1"0$`'8)",<$))B8"@CHLC575E.#[!R+?0B%_P^.^@```#L]O'8* +XM"'1"QT0D!`@```")/"3H],P``(E%[*$HF0L(A0/A+P!``"+/029"@@I\\'[`HD] +XM+&0)"(DU(&0)",<%-&0)"`````")7"0(B70D!,<$)#!D"0CH+#0!`,<%*&0) +XM"`````#'!21D"0@`````QT7@`'8)",=%\``````Q_\=%Z`````#'1>P````` +XMZUJ+1>2#!2AD"0@!QP4D9`D(`````(7`#X3@````QT0D"/___W_'1"0$```` +XM`(M-Y(D,).@Q!@$`B47PB00DZ(8P`0"+3?")QHM%Y(M`'(E-X(E%Y(M%[(7` +XM=7O'!"1`30D(BU7@N0$```")\.CHU___.<:)PW2*BQ#WP@```$!U'H'Z_P`` +XM``^'K`$``*'@70D(BT20-/;$0`^%8O___XU#_+D!````B?*#!21D"0@!QP0D +XM0$T)".AMUO__*=C!^`*->`&A-&0)"#G'=TR+1>R)WH7`=(6+%529"PB-!+T` +XM````*Q4@9`D(`P4T=PH(*=`[!;"8"@@/@DD!``"+3?")#"3HH<@``(/$++AD +XM````6UY?7<.-="8`B40D"*$P9`D(B1PDB40D!.A'/?W_AZ0#___^+/029"@@[/2QD"0@/A3C^__\[ +XM-2!D"0@/A2S^__\['1QD"0@/A2#^__^A-&0)"(7`#X03_O__B40D"*$P9`D( +XMB70D!(D$).C5//W_A<`/A?;]__^+%2AD"0C'1>``=@D(QT7P`````(72=$N# +XM^@$/CQ2%T@^$,0$``,=$)`C___]_QT0D!`````"+1>2)!"3H>@0! +XM`(E%\(D$).C/+@$`BTWDBTD2)1>#'!"1`30D(BPTD9`D(B?"+ +XM5>#H-];__XG&Z<;]__^#Q"RX9````%M>7UW#C78`B10DZ`0Z_?_I4/[__\'Z +XM`HD4).A8P___B3PDZ&#`__^%_W0=,6A5)D+"*,<9`D(BT7PB00DZ!K'``"#Q"RX#@```%M>7UW#B10DZ*$Y +XM_?_IT?S__XL5(&0)"*%4F0L(*=#!^`(Y^`^%B/[__XE\)`B)WHE4)`2)'"3H +XMHCO]_X7`#X1Y_?__Z6G^__^+3>2%R8UT)@!T&K`!BTWD@\`!.<*+21R)3>0/ +XMCLC^__^%R77HQT7P`````.GL_?__D(VT)@````!5NF0```")Y5=64X/L#*%4 +XMF0L(BSTT=PH(.?@/A$L!``"+%7QW"@B-<`2AX%T)"(E5[(E%\(-M[`&#?>S_ +XM#X0(`0``.?YR(.FF````C70F`(M5\(M$@C3VQ$!T*(/&!#GW#X:+````BP:I +XM````0'5./?\```!VV8D$).BM./W_]L1`==B+!CW_````=G6)!"3HESC]_^MR +XMBU7PBT2:-/;$0'62@?O_````=S>+5?"+1)HT]L0%#X5Z____@\8$.?!="0B)1>R)5?"#;>P!@WWL_W1E.?YR%>OPBU7PBT2:-/;$0'5`@\8$ +XM.?=VW8L>]\,```!`=>^!^_\```!VVXD<).@\-_W_Z]B+5?"+1)HT]L1`=+6# +XMQ@0Y]W:NBQ[WPP```$!UI('[_P```';;B1PDZ`TW_?^0Z]53B<.#[`2I````0'00@_M?N`,` +XM``!T.X/$!%M=PSW_````=T6AX%T)"(M4F#2`YD"X`0```'7@@_M_=B&!^_\` +XM``!W,:'@70D(BT28-/;$`72[@\0$N`(```!;757B==6B<93@^P< +XMHB%P`^%_````*'@70D(BQ5,=PH(B47PB57L@VWH`8-]Z/\/A!4! +XM```Y_G([Z^R+5?"+1)HT]L0!#X6$````@_M_=PKV!)V]40D(!'5UB5PD!(M% +XM[(D$).C<.?W_A]\,```!`==2!^_\```!VL8D<).@^-?W_ +XMB?;KK(/K`74>B?:-O"<`````ZQ>+!NAG_O__@^@!C70F`'4'@\8$.?=WZ8-M +XMZ`&#?>C_=",Y_G,?BP;H0O[__XG#ZPN+!N@W_O__.<-UM8/&!#GW=^[KK(U& +XM_(/$'%M>7UW#.?>)^';R@\0C#R?__N`X```"#Q`1;7<.#P`2C5)D+ +XM"*'(F0L(A53@^P$ +XMBQU4F0L(BQ4T=PH(.=-T+HL-?'<*"(G8Z.?]__^C5)D+"*'(F0L(A53@^P$BQU4F0L(BQ4T=PH(.=-T18L-?'<*"(G8Z(?]__^)PHG#H529"PCH +XMF>'__RL=5)D+",'[`HD<).AHNO__BQ4T=PH(N`X````Y%529"PAV!HD55)D+ +XM"(/$!%M=PXGVC;PG`````%6)Y5=64X/L/(L5)"<)"(E%S*%4F0L(B574BQ4T +XM9`D(B470H9QW"@B)5>")1=BA-'<*"(/`&(T$D#L%L)@*"`^#8@0``(G0,=N+ +XM=@,``*$T=PH(QP`*````@\`$@_X5HS1W"@BXI.8("'0%N+3F"`B+ +XM$(72=!V)P8GVH31W"@B)$(/`!*,T=PH(BU$$@\$$A=)UYZ$T=PH(BQ4D)PD( +XMB1"#P`2+#3!D"0BC-'<*"*$T9`D(C5$$C02!.<)S+(/!"(M1_*$T=PH(B1"# +XMP`2)RJ,T=PH(H31D"0B#P03!X`(#!3!D"0@YPG+7H31W"@C'``````#'1"0$ +XMQ)@*",<$)"!)"0CH0AS__X7`=`V#/20G"0@Z#X1L`P``Z'QH``"-1?")!"3H +XM(4```(/H`0^%:@4``(M-\('Y``$``']#H7!W"@@/MM$/M@0"/!MT,P^'O`(` +XM`#P"="D\!)`/A<@"```Q_X,]-&0)"`''1=P!````=UKHTW@``,=%W`````#K +XM3*$T=PH(@\`$.P6PF`H(#X-7`@``B4PD!#'_QP0D,&0)".B$)P$`H31W"@B+ +XM5?")$(U0!(D5-'<*",=`!`````#HU6<``,=%W`````"A-'<*"#T`=@D(=Q?K +XM&L<``````(/H!#T`=@D(HS1W"@AV!8,X"G7FQP``````BTWV)1?"#^P$/AKH```"#??!;#X2P````A?]T"3EUS`^$T````,=$)`0J```` +XMQP0D,&0)".B^)@$`QP0D,&0)".@2)P$`H529"P@]`'8)"'(,.P4T=PH(#X:F +XM`@``B?"#_A6B2)D+"`^$)`(``,<$)`````#HKNC__SQD#X0D`@``@_X5N`!V +XM"0@/A&H"``"C5)D+"*$P9`D(B?*#P`3H9-+__XL5-&0)"*$P9`D(@^H!B14T +XM9`D(QP20`````,<%)"<)"#H```")\.CX_/__/&2)PW1'A-MT7(#[9`^4P(M5 +XMX(72#X3B````#[[#@\0\6UY?7<.#/20G"0@_#X0=`@``,<"#_A4/E<"-!,7\ +XM____`054F0L(Z0G___^#/20G"0@_#X4)`0``@WW4.@^%_P```#';BU74BT7@ +XMB14D)PD(BU78.16<=PH(HS1D"0AT$XD5G'<*".A+YO__/&0/A`H!``"+1="` +XM^V2C5)D+"`^$"`,``(M%W(7`#X5J____A-L/A6+___^A-&0)"(7`#X6&_/__ +XMQT0D!"H```#'!"0P9`D(QP4D)PD(.@```.A$)0$`Z6/\___H6G8``#'_QT7< +XM`````)#IS?W__X3`#X06____C78`Z5G___\\8710#X1,`0``B0T49`D(QP0D%&0)".BH +XM/@``NPX````Q_\=%W`$```#I9_W__[@!````Z:/^__^^%@```+\!````QT7< +XM`````.E'_?__H31D"0B#Z`&CV)D+".B#5```Z/Y4``#I>/S__X/$/+AD```` +XM6UY?7<.^%0```+\!````QT7<`````.D(_?__QP0D`````.@*Z/__/&0/A=S] +XM__^+%31D"0BA,&0)"(/J`8D5-&0)",<$D`````#H4G4``(M5V#D5G'<*"'02 +XMBU78B16<=PH(Z,GD__\\9'2,BT70QP4D)PD(/P```*-4F0L(Z<_]__^A-'<* +XM".F,_?__H3!D"0B)\H/`!.CUS___/&0/A8G]___I/OW__S'`@_X5#Y3`@^@! +XM)?___W^CG'<*".ANY/__/&0/A%4!``"#_A6X`'8)"`^$/0$``*-4F0L(Z53@^P4QP4T +XM9`D(`````,8%S)D+"`#H;OC__\=$)`3$F`H(QP0D($D)"(G#Z*@5__^%P'0) +XMH=B9"PB%P'43#[[#QP78F0L(`````(/$%%M=P\<%V)D+"`````#H25$``.C$ +XM40``Z+]A``#KTHVV`````(V\)P````!5B>57B==64X/L'(UP_*'(F0L(B4WH +XMA<`/A=D```"AX%T)"(L53'<*"(E%\(E5[(-MZ`&#?>C_#X0@`0``.?YS.^OL +XMBU7PBT2:-/;$`0^%A````(/[?W<*]@2=O5$)"`1U=8E<)`2+1>R)!"3H*R_] +XM_X7`=6*#[@0Y]W>SBQ[WPP```$!UW('[_P```':UB1PDZ.8J_?_KLHM5\(M$ +XMFC3VQ`%U)H/[?W<*]@2=O5$)"`1U%XE<)`2+1>R)!"3HVB[]_X7`#X1E____ +XM@^X$.?)PW?!@^X$.?=WNHL&Z'SS__\YPW3N@VWH`8-]Z/]U +XML(U&!(/$'%M>7UW#C58$B?@YUW/O@\053@^P$BQU4F0L(@?L` +XM=@D(=#.+#7QW"@BZ`'8)"(G8Z.3]__^C5)D+"*'(F0L(A53@^P$H529 +XM"P@]`'8)"'0TBPU\=PH(N@!V"0CHB/W__XL55)D+"(G#Z.O6__^A5)D+""G8 +XMP?@"B00DZ*FP__^Z#@```(/$!(G06UW#C;8`````C;\`````58GE5E.[`'8) +XM"(/L$*$`=@D(J0```$!U,8LUX%T)".L5BT2&-/;$0'0@@\,$BP.I````0'44 +XM/?\```!VY(D$).B'*/W_]L1`=>`['31W"@BX9````'0=@P5P=@H(`8`%B)@* +XM"`''!"0`````Z(_&__\/OL"#Q!!;7EW#D(UT)@!5N&0```")Y8/L&(EU_(LU +XM5)D+"#LU-'<*"(E=^'-GBQ[WPP```$!U1X'[_P```'=_H>!="0B+1)@T9H7` +XM>%&!^_\```!W?:'@70D(BT28-/;$$'0;@?O_````=WBAX%T)"(N$F#0(``#K +XM.9"-="8`C48$HU29"PC'!"0!````Z+Q@```QP(M=^(MU_(GL7<.!^_\```!W +XM(J'@70D(BX28-`0``(D&C48$HU29"PCKR(D<).B4)_W_ZX")'"3HFBG]_^O@ +XMB1PDZ(`G_?^-="8`Z7O___^)'"3H'R[]_XUV`.O"C;0F`````(V\)P````!5 +XMB>575E.#[`R+#7QW"@B+%31W"@BA5)D+".@1\?__BS54F0L(.?")QW9"D(UT +XM)@"+'O?#````0'4L@?O_````=TZAX%T)"(M$F#1FA!= +XM"0B+A)@T!```B0:#Q@0Y]W?#H31W"@B)/529"P@YQW8%HU29"PB#Q`RX#@`` +XM`%M>7UW#B?:)'"3HQ";]_^NQB1PDZ,HH_?_KP(VV`````(V_`````%6)Y5=6 +XM4X/L#(L-?'<*"(L5-'<*"*%4F0L(Z&'P__^+-529"P@Y\(G'#X:G````H>!= +XM"0B)1?#K'HVT)@````"+5?"+1)HT]L0!=2J#Q@0Y]P^&?P```(L>]\,```!` +XM=>N!^_\```!VUXD<).@[)OW_]L0!=-:!^_\````/AZ$```"+5?"+1)HT]L00 +XM#X5[````@\8$.?=V/8L>]\,```!`=>^!^_\```!W3*'@70D(BT28-&:%P'G9 +XM@?O_````=T"AX%T)"(N$F#0$``")!H/&!#GW=\.A-'<*"(D]5)D+"#G'=@6C +XM5)D+"(/$#+@.````6UY?7<.)'"3HK27]_^NSB1PDZ+,G_?^)!NO"@?O_```` +XM=QN+5?"+A)HT"```B0;KK(D<).B!)?W_Z5G___^)'"3H)"S]_XD&ZY.-="8` +XM58GE5U93@^P,BPU\=PH(BQ4T=PH(H529"PCH(>___XLU5)D+"#GPB<=V0I"- +XM="8`BQ[WPP```$!U+('[_P```'=.H>!="0B+1)@T]L00=!:!^_\```!W0J'@ +XM70D(BX28-`@``(D&@\8$.?=WPZ$T=PH(B3U4F0L(.<=V!:-4F0L(@\0,N`X` +XM``!;7E]=PXGVB1PDZ-0D_?_KL8D<).AZ*_W_Z\"0D)"0D)"0D)"0D)!5,<") +XMY5=64X/L+.L1C78`@\`!/0`!```/A(0```"`N,"K"P@>=>F^P*L+"(E%X(U% +XMX+N`````QT7H`````(U][(E%[,=%\`(```"0C70F``^V%#.-0O\\`78M@/HU +XM="B)V(/@?XE%Y`^V!#.)!"3HK)L``,=$)`@`````B3PDB40D!.@8GP``@\,! +XM@?L``0``=;V+1>#&!#`U@\0L6UY?7<-F,<#K"H/``3T``0``=!.`N,"D"P@> +XM=>V^P*0+".EH____BQ7(F0L(N!L```"^P*0+"(72#X50____Z4;____K#9"0 +XMD)"0D)"0D)"0D)!5B>564X/L$(L=8)D+"(7;=5^+#<"E"PB%R755BS7@70D( +XMNX````#K+(VT)@````"+1)XTJ0``!`!T!\:#P*L+"`*#PP&!^_\```!_&O?# +XM````0'7M@?O_````=M.)'"3H9R/]_^O-QP5`9`D(`0```(/$$%M>7<.0C;0F +XM`````%6)Y5.#[#2-1>B)1?3'1?@"````QP7(F0L(`````.B=GP``,=(/MH)` +XM*0D(QH+`I`L(`8B"P*L+"(/"`8'Z``$``'7AZ$?^__^-7?3H+____\=%Z!@` +XM``#'1?``````QT7L&````,<$)"L```#H/IH``(D<),=$)`@`````B40D!.BJ +XMG0``QT7L*@```,<$)$T```#H%YH``(D<),=$)`@`````B40D!.B#G0``QT7L +XM)````,<$)$X```#H\)D``(D<),=$)`@`````B40D!.AYD``(D< +XM),=$)`@`````B40D!.CGG```QT7L3@```,<$)&<```#H5)D``(D<),=$)`@` +XM````B40D!.C`G```QT7L/P```,<$)&\```#H+9D``(D<),=$)`@`````B40D +XM!.B9G```QT7L"0```,<$)&H```#H!ID``(D<),=$)`@`````B40D!.ARG``` +XMQT7L!````,<$)&L```#HWY@``(D<),=$)`@`````B40D!.A+G```Z.9=``#H +XM,7<``(/$-%M=PXUT)@"-O"<`````58GE@^P(H3QD"0B%P'0"RF?=@``ZPV0D)"0D)"0D)"0D)"058GE4S';@^P4C;0F```` +XM`(N#Z*4+"(/##(D$).C_K0``@?O0!0``=>>A@)@*",=$)`S2Y@@(QT0D"`$` +XM``#'1"0$`P```(D$),<%X*4+",3F"`C'!>2E"P@(````Z.X!_O^)!"3H5JO^ +XM_\=$)`S<\0@(QT0D"`(```#'1"0$`P```,<%[*4+".CF"`C'!?"E"P@$```` +XMH^BE"PBA@)@*"(D$).BH`?[_B00DZ!"K_O_'1"0,`/((",=$)`@#````QT0D +XM!`,```#'!?BE"PC]Y@@(QP7\I0L(&0```*/TI0L(H8"8"@B)!"3H8@'^_XD$ +XM).C*JO[_QT0D#$3R"`C'1"0(!````,=$)`0#````QP4$I@L($N<(",<%"*8+ +XM"!T```"C`*8+"*&`F`H(B00DZ!P!_O^)!"3HA*K^_\=$)`R`\@@(QT0D"`4` +XM``#'1"0$`P```,<%$*8+""7G"`C'!12F"P@.````HPRF"PBA@)@*"(D$).C6 +XM`/[_B00DZ#ZJ_O_'1"0,1><(",=$)`@&````QT0D!`,```#'!1RF"P@SYP@( +XMQP4@I@L(!P```*,8I@L(H8"8"@B)!"3HD`#^_XD$).CXJ?[_QT0D#*3R"`C' +XM1"0(!P```,=$)`0#````QP4HI@L(7^<(",<%+*8+"#@```"C)*8+"*&`F`H( +XMB00DZ$H`_O^)!"3HLJG^_\=$)`SD\@@(QT0D"`@```#'1"0$`P```,<%-*8+ +XM"&_G"`C'!3BF"PA0````HS"F"PBA@)@*"(D$).@$`/[_B00DZ&RI_O_'1"0, +XMD^<(",=$)`@)````QT0D!`,```#'!4"F"PA[YP@(QP5$I@L(1````*,\I@L( +XMH8"8"@B)!"3HOO_]_XD$).@FJ?[_QT0D#"CS"`C'1"0("@```,=$)`0#```` +XMQP5,I@L(K.<(",<%4*8+"!````"C2*8+"*&`F`H(B00DZ'C__?^)!"3HX*C^ +XM_\=$)`S'YP@(QT0D"`L```#'1"0$`P```,<%6*8+"+GG"`C'!5RF"P@1```` +XMHU2F"PBA@)@*"(D$).@R__W_B00DZ)JH_O_'1"0,[^<(",=$)`@,````QT0D +XM!`,```#'!62F"PC=YP@(QP5HI@L(;````*-@I@L(H8"8"@B)!"3H[/[]_XD$ +XM).A4J/[_QT0D#!SH"`C'1"0(#0```,=$)`0#````QP5PI@L(">@(",<%=*8+ +XM"&T```"C;*8+"*&`F`H(B00DZ*;^_?^)!"3H#JC^_\=$)`Q4\P@(QT0D"`X` +XM``#'1"0$`P```,<%?*8+"#?H"`C'!8"F"PAJ````HWBF"PBA@)@*"(D$).A@ +XM_OW_B00DZ,BG_O_'1"0,6.@(",=$)`@/````QT0D!`,```#'!8BF"PA)Z`@( +XMQP6,I@L(2P```*.$I@L(H8"8"@B)!"3H&O[]_XD$).B"I_[_QT0D#(SS"`C' +XM1"0($````,=$)`0#````QP64I@L(=.@(",<%F*8+"#(```"CD*8+"*&`F`H( +XMB00DZ-3]_?^)!"3H/*?^_\=$)`R\\P@(QT0D"!$```#'1"0$`P```,<%H*8+ +XM"(CH"`C'!:2F"PAP````HYRF"PBA@)@*"(D$).B._?W_B00DZ/:F_O_'1"0, +XME^@(",=$)`@2````QT0D!`,```#'!:RF"PCQY@@(QP6PI@L(!0```*.HI@L( +XMH8"8"@B)!"3H2/W]_XD$).BPIO[_QT0D#/#S"`C'1"0($P```,=$)`0#```` +XMQP6XI@L(M>@(",<%O*8+"&@```"CM*8+"*&`F`H(B00DZ`+]_?^)!"3H:J;^ +XM_\=$)`PX]`@(QT0D"!0```#'1"0$`P```,<%Q*8+",CH"`C'!I?[_QT0D#,3T"`C'1"0(%@```,=$)`0#````QP7RF"P@;````H^2F"PBA@)@*"(D$).CJ +XM^_W_B00DZ%*E_O_'1"0,#.D(",=$)`@8````QT0D!`,```#'!?2F"PC]Z`@( +XMQP7XI@L(,````*/PI@L(H8"8"@B)!"3HI/O]_XD$).@,I?[_QT0D#"?I"`C' +XM1"0(&0```,=$)`0#````QP4`IPL(QNL(",<%!*<+"!0```"C_*8+"*&`F`H( +XMB00DZ%[[_?^)!"3HQJ3^_\=$)`PL]0@(QT0D"!H```#'1"0$`P```,<%#*<+ +XM"$'I"`C'!1"G"P@W````HPBG"PBA@)@*"(D$).@8^_W_B00DZ("D_O_'1"0, +XM6^D(",=$)`@;````QT0D!`,```#'!1BG"PA/Z0@(QP4````QT0D +XM!`,```#'!3RG"PC`Z0@(QP5`IPL(30```*,XIPL(H8"8"@B)!"3H`/K]_XD$ +XM).AHH_[_QT0D#/;I"`C'1"0('P```,=$)`0#````QP5(IPL(Y^D(",<%3*<+ +XM"$<```"C1*<+"*&`F`H(B00DZ+KY_?^)!"3H(J/^_\=$)`QH]0@(QT0D""`` +XM``#'1"0$`P```,<%5*<+"`WJ"`C'!5BG"PA1````HU"G"PBA@)@*"(D$).AT +XM^?W_B00DZ-RB_O_'1"0,*NH(",=$)`@A````QT0D!`,```#'!6"G"P@9Z@@( +XMQP5DIPL(3@```*-*<+ +XM"&/J"`C'!7RG"P@/````HW2G"PBA@)@*"(D$).BB^/W_B00DZ`JB_O_'1"0, +XMM/4(",=$)`@D````QT0D!`,```#'!82G"PAPZ@@(QP6(IPL(,P```*.`IPL( +XMH8"8"@B)!"3H7/C]_XD$).C$H?[_QT0D#.3U"`C'1"0()0```,=$)`0#```` +XMQP60IPL(B.H(",<%E*<+"!4```"CC*<+"*&`F`H(B00DZ!;X_?^)!"3H?J'^ +XM_\=$)`P@]@@(QT0D""8```#'1"0$`P```,<%G*<+"*#J"`C'!:"G"P@6```` +XMHYBG"PBA@)@*"(D$).C0]_W_B00DZ#BA_O_'1"0,6/8(",=$)`@G````QT0D +XM!`,```#'!:BG"PBWZ@@(QP6LIPL(+````*.DIPL(H8"8"@B)!"3HBO?]_XD$ +XM).CRH/[_QT0D#,CJ"`C'1"0(*````,=$)`0#````QP6TIPL(;/`(",<%N*<+ +XM"&$```"CL*<+"*&`F`H(B00DZ$3W_?^)!"3HK*#^_\=$)`SCZ@@(QT0D""D` +XM``#'1"0$`P```,<%P*<+"$+P"`C'!<2G"PAB````H[RG"PBA@)@*"(D$).C^ +XM]OW_B00DZ&:@_O_'1"0,#>L(",=$)`@J````QT0D!`,```#'!BG"P@Q````H^"G"PBA@)@*"(D$).@L]OW_B00DZ)2?_O_'1"0, +XMY/8(",=$)`@M````QT0D!`,```#'!?"G"P@DZP@(QP7TIPL(/0```*/LIPL( +XMH8"8"@B)!"3HYO7]_XD$).A.G_[_QT0D#$'K"`C'1"0(+@```,=$)`0#```` +XMQP7\IPL(-.L(",<%`*@+"!@```"C^*<+"*&`F`H(B00DZ*#U_?^)!"3H")_^ +XM_\=$)`P0]P@(QT0D""\```#'1"0$`P```,<%"*@+"%WK"`C'!0RH"PAK```` +XMHP2H"PBA@)@*"(D$).A:]?W_B00DZ,*>_O_'1"0,4/<(",=$)`@P````QT0D +XM!`,```#'!12H"PANZP@(QP48J`L(1@```*,0J`L(H8"8"@B)!"3H%/7]_XD$ +XM).A\GO[_QT0D#'#W"`C'1"0(,0```,=$)`0#````QP4@J`L(Z^@(",<%)*@+ +XM"$4```"C'*@+"*&`F`H(B00DZ,[T_?^)!"3H-I[^_\=$)`RT]P@(QT0D"#(` +XM``#'1"0$`P```,<%+*@+"'CK"`C'!3"H"PA2````HRBH"PBA@)@*"(D$).B( +XM]/W_B00DZ/"=_O_'1"0,Y/<(",=$)`@S````QT0D!`,```#'!3BH"PB%ZP@( +XMQP4\J`L(2````*,TJ`L(H8"8"@B)!"3H0O3]_XD$).BJG?[_QT0D#)GK"`C' +XM1"0(-````,=$)`0#````QP5$J`L(D>L(",<%2*@+"`,```"C0*@+"*&`F`H( +XMB00DZ/SS_?^)!"3H9)W^_\=$)`P0^`@(QT0D"'H```#'1"0$`P```,<%4*@+ +XM"*GK"`C'!52H"PAX````HTRH"PBA@)@*"(D$).BV\_W_B00DZ!Z=_O_'1"0, +XM./@(",=$)`A[````QT0D!`,```#'!5RH"PBZZP@(QP5@J`L(>0```*-8J`L( +XMH8"8"@B)!"3H2H"P@J```` +XMH]RH"PBA@)@*"(D$).AN\/W_B00DZ-:9_O_'1"0,V/D(",=$)`A`````QT0D +XM!`,```#'!>RH"PBW[`@(QP7PJ`L($@```*/HJ`L(H8"8"@B)!"3H*/#]_XD$ +XM).B0F?[_QT0D#`#Z"`C'1"0(00```,=$)`0#````QP7XJ`L(PNP(",<%_*@+ +XM"$P```"C]*@+"*&`F`H(B00DZ.+O_?^)!"3H2IG^_\=$)`PD^@@(QT0D"$(` +XM``#'1"0$`P```,<%!*D+",WL"`C'!0BI"PAI````HP"I"PBA@)@*"(D$).B< +XM[_W_B00DZ`29_O_'1"0,3/H(",=$)`A#````QT0D!`,```#'!1"I"PC8[`@( +XMQP44J0L(3P```*,,J0L(H8"8"@B)!"3H5N_]_XD$).B^F/[_QT0D#(3Z"`C' +XM1"0(1````,=$)`0#````QP4.H(",<%(*D+""````"C&*D+"*&`F`H( +XMB00DZ!#O_?^)!"3H>)C^_\=$)`RT]0@(QT0D"$4```#'1"0$`P```,<%**D+ +XM"._L"`C'!2RI"P@S````HR2I"PBA@)@*"(D$).C*[OW_B00DZ#*8_O_'1"0, +XM"^T(",=$)`A&````QT0D!`,```#'!32I"P@![0@(QP4XJ0L((P```*,PJ0L( +XMH8"8"@B)!"3HA.[]_XD$).CLE_[_QT0D##KM"`C'1"0(1P```,=$)`0#```` +XMQP5`J0L(*>T(",<%1*D+""0```"C/*D+"*&`F`H(B00DZ#[N_?^)!"3HII?^ +XM_\=$)`QA[0@(QT0D"$@```#'1"0$`P```,<%3*D+"%7M"`C'!5"I"P@-```` +XMHTBI"PBA@)@*"(D$).CX[?W_B00DZ&"7_O_'1"0,A>T(",=$)`A)````QT0D +XM!`,```#'!5BI"PAY[0@(QP5X(",<%C*D+"`$```"CA*D+"*&`F`H( +XMB00DZ)KL_?^)!"3H`I;^_\=$)`S(^@@(QT0D"$X```#'1"0$`P```,<%E*D+ +XM"#_N"`C'!9BI"P@I````HY"I"PBA@)@*"(D$).A4[/W_B00DZ+R5_O_'1"0, +XM7>X(",=$)`A/````QT0D!`,```#'!:"I"PA2[@@(QP6DJ0L($P```*.^X(",<%L*D+"#8```"CJ*D+"*&`F`H(B00DZ,CK_?^)!"3H,)7^ +XM_\=$)`PP^P@(QT0D"%$```#'1"0$`P```,<%N*D+"(?N"`C'!;RI"P@\```` +XMH[2I"PBA@)@*"(D$).B"Z_W_B00DZ.J4_O_'1"0,5/L(",=$)`A2````QT0D +XM!`,```#'!<2I"PBA[@@(QP7(J0L(.@```*/`J0L(H8"8"@B)!"3H/.O]_XD$ +XM).BDE/[_QT0D#'S["`C'1"0(4P```,=$)`0#````QP70J0L(J.X(",<%U*D+ +XM"#L```"CS*D+"*&`F`H(B00DZ/;J_?^)!"3H7I3^_\=$)`SD\@@(QT0D"%0` +XM``#'1"0$`P```,<%W*D+"+;N"`C'!>"I"PA0````H]BI"PBA@)@*"(D$).BP +XMZOW_B00DZ!B4_O_'1"0,SNX(",=$)`A5````QT0D!`,```#'!>BI"PC"[@@( +XMQP7LJ0L(8````*/DJ0L(H8"8"@B)!"3H:NK]_XD$).C2D_[_QT0D#)/G"`C' +XM1"0(5@```,=$)`0#````QP7TJ0L(Y^X(",<%^*D+"$0```"C\*D+"*&`F`H( +XMB00DZ"3J_?^)!"3HC)/^_\=$)`R@^P@(QT0D"%<```#'1"0$`P```,<%`*H+ +XM"/7N"`C'!02J"P@N````H_RI"PBA@)@*"(D$).C>Z?W_B00DZ$:3_O_'1"0, +XMV/L(",=$)`A8````QT0D!`,```#'!0RJ"P@![P@(QP40J@L(2@```*,(J@L( +XMH8"8"@B)!"3HF.G]_XD$).@`D_[_QT0D#`#\"`C'1"0(60```,=$)`0#```` +XMQP48J@L(%N\(",<%'*H+"%,```"C%*H+"*&`F`H(B00DZ%+I_?^)!"3HNI+^ +XM_\=$)`PL[P@(QT0D"%H```#'1"0$`P```,<%)*H+""'O"`C'!2BJ"PA4```` +XMHR"J"PBA@)@*"(D$).@,Z?W_B00DZ'22_O_'1"0,+/P(",=$)`A;````QT0D +XM!`,```#'!3"J"PA%[P@(QP4TJ@L(5P```*,LJ@L(H8"8"@B)!"3HQNC]_XD$ +XM).@NDO[_QT0D#&3\"`C'1"0(7````,=$)`0#````QP4\J@L(4.\(",<%0*H+ +XM"%@```"C.*H+"*&`F`H(B00DZ(#H_?^)!"3HZ)'^_\=$)`R,_`@(QT0D"%T` +XM``#'1"0$`P```,<%2*H+"%GO"`C'!4RJ"PA?````HT2J"PBA@)@*"(D$).@Z +XMZ/W_B00DZ**1_O_'1"0,N/P(",=$)`A>````QT0D!`,```#'!52J"PAF[P@( +XMQP58J@L(7@```*-0J@L(H8"8"@B)!"3H].?]_XD$).A\(",=$)`AA````QT0D!`,```#'!7BJ"PB/[P@(QP5\J@L(+P```*-TJ@L( +XMH8"8"@B)!"3H(N?]_XD$).B*D/[_QT0D#$3]"`C'1"0(8@```,=$)`0#```` +XMQP6$J@L(KN\(",<%B*H+"#\```"C@*H+"*&`F`H(B00DZ-SF_?^)!"3H1)#^ +XM_\=$)`QP_0@(QT0D"&,```#'1"0$`P```,<%D*H+"+_O"`C'!92J"PAC```` +XMHXRJ"PBA@)@*"(D$).B6YOW_B00DZ/Z/_O_'1"0,L/T(",=$)`AD````QT0D +XM!`,```#'!9RJ"PC2[P@(QP6@J@L(9````*.8J@L(H8"8"@B)!"3H4.;]_XD$ +XM).BXC_[_QT0D#/3]"`C'1"0(90```,=$)`0#````QP6HJ@L(YN\(",<%K*H+ +XM"%P```"CI*H+"*&`F`H(B00DZ`KF_?^)!"3H?`(",=$)`AJ````QT0D!`,```#'!>2J"PAK\`@(QP7HJ@L(6P```*/@J@L( +XMH8"8"@B)!"3HK.3]_XD$).@4CO[_QT0D#*S^"`C'1"0(:P```,=$)`0#```` +XMQP7PJ@L(D_`(",<%]*H+"$,```"C[*H+"*&`F`H(B00DZ&;D_?^)!"3HSHW^ +XM_\=$)`RY\`@(QT0D"&P```#'1"0$`P```,<%_*H+"*;P"`C'!0"K"PA"```` +XMH_BJ"PBA@)@*"(D$).@@Y/W_B00DZ(B-_O_'1"0,W?`(",=$)`AM````QT0D +XM!`,```#'!0BK"PC0\`@(QP4,JPL(5@```*,$JPL(H8"8"@B)!"3HVN/]_XD$ +XM).A"C?[_QT0D#`;Q"`C'1"0(;@```,=$)`0#````QP44JPL(^O`(",<%&*L+ +XM"%4```"C$*L+"*&`F`H(B00DZ)3C_?^)!"3H_(S^_\=$)`PG\0@(QT0D"&\` +XM``#'1"0$`P```,<%(*L+"!_Q"`C'!22K"PA9````HQRK"PBA@)@*"(D$).A. +XMX_W_B00DZ+:,_O_'1"0,0_$(",=$)`AP````QT0D!`,```#'!2RK"P@[\0@( +XMQP4PJPL(.0```*,HJPL(H8"8"@B)!"3H"./]_XD$).APC/[_QT0D#.C^"`C' +XM1"0(<0```,=$)`0#````QP4XJPL(8?$(",<%/*L+""$```"C-*L+"*&`F`H( +XMB00DZ,+B_?^)!"3H*HS^_\=$)`P,_P@(QT0D"'(```#'1"0$`P```,<%1*L+ +XM"&_Q"`C'!4BK"P@B````HT"K"PBA@)@*"(D$).A\XOW_B00DZ.2+_O_'1"0, +XM,/\(",=$)`AS````QT0D!`,```#'!5"K"PAT\0@(QP54JPL(=P```*-,JPL( +XMH8"8"@B)!"3H-N+]_XD$).B>B_[_QT0D#&C_"`C'1"0(=````,=$)`0#```` +XMQP5AD"0BC*&4)"*'`+0D( +XM]]`C!0!E"0@+!;PM"0BC`&4)"*',+0D(]]`C!01E"0@+!<@M"0BC!&4)"*'8 +XM+0D(]]`C!0AE"0@+!=0M"0BC"&4)"*'D+0D(BPW\70D(]]`C!0QE"0@+!>`M +XM"0B%R:,,90D(=2JAM'8*",=$)`0`90D(B00DZ'*$``"#P`$/A`C____'!61D +XM"0@!````R<.A1)D+".O4C;8`````58GE4X'L)"```*%H9`D(QT7X`````(7` +XM=`B)!"3H_HD``(L58&0)"#'`QP5H9`D(`````(72=`F!Q"0@``!;7<.-1?B) +XM1"0(H;1V"@C'1"0$?V8$0(D$).B__/S_BT7XAB-==B) +XM'"3HC`#]_\=$)`0"````B1PDZ(S[_/^)="0(B5PD!,<$)`$```#H*/O\_\=$ +XM)`1@'@4(B30DZ&Q^_?^+#?Q="0B%R70ZH429"PC'1"0$@&0)"(D$).C]@@`` +XMB30DB2L)",<$),!D"0CH +XMOWX``(LU="T)"#')BQUX+0D(#[8]<&0)"+@!````T^"%QG45#[:1DBL)"#J1 +XM8"L)"'0&B)%@*PD(A<-T"(GXB(%@*PD(@\$!@_D9='^_XD$).@]W_[_B00DZ(6W__^+-?Q="0B%]@^$ +XM]@$``*%$F0L(QT0D!(!D"0B)!"3HHGX``(/``0^$+@(``*&`9`D(BPV<9`D( +XMBQ6D9`D(BQV@9`D(H\!D"0BAA&0)"(L]D&0)"(LUF&0)"(D-W&0)"*/$9`D( +XMH8AD"0B)%>1D"0B)'>!D"0B)/=!D"0BCR&0)"*&,9`D(B3789`D(B3T090D( +XMH\QD"0BAE&0)"*/49`D(H:AD"0BCZ&0)"*&`9`D(HP!E"0BAA&0)"*,$90D( +XMH8AD"0BC"&4)"*&,9`D(HPQE"0BAE&0)"*,490D(B34890D(H:AD"0B)#1QE +XM"0B)%21E"0B)'2!E"0BC*&4)",<$)(!D"0CH.WT``,<$)(!D"0BC:)D+".C: +XM?```QP0D@&0)"*+`F0L(Z.E\``"+70BC1"L)"*%(+0D(]]`C!8!D"0@+!40M +XM"0BC@&0)"*%4+0D(]]`C!81D"0@+!5`M"0BCA&0)"*%@+0D(]]`C!8AD"0@+ +XM!5PM"0BCB&0)"*%L+0D(]]`C!8QD"0@+!6@M"0B%VZ.,9`D(=7;'1"0$8"L) +XM",<$)(!D"0CHN7L``(U=Y,=$)`0`G@<(QP0D'````.A>^?S_B1PDZ.;Y_/_' +XM1"0$'````(D<).CF]/S_QT0D"`````")7"0$QP0D`@```.A^]/S_,<#'!6QD +XM"0@!````Z6S]__^AM'8*".D%_O__QP0D`&4)".@;?```AP``BPW\70D(A2L)"'0&B)!Y*PD(@\`!@_@7==\PP`^VD)(K"0@X +XMT70..HA@*PD(=`:(D&`K"0B#P`&#^!EUW^DF____C;8`````C;PG`````%6) +XMY8/L",<$)`$```#H#O7__\<%A'<*"`````#'!"0`````Z"C\__^#P`%T?:%@ +XM90D(AJ&$+0D(QT0D!'DK"0C'!"3`9`D(]]`C!0``R<.-="8`Z'M*``#I +XM?/___XVV`````%6)Y8/L&,=$)`2PD`@(@P7$K`L(`<<$),2L"PCHWW7]_XU% +XM^(E$)`2-1?R)!"3H;30``(7`=0>+10B%P'1"H81W"@B%P'11Z(08``#H_Q@` +XM`,<$)`````#HDT,``,<$)`````#H9T$``(M%^(E$)`2+1?R)!"3HI2\``.C0 +XM*```QP0DQ*P+",<%M)D+"`````#HRG3]_\G#BT7XB40D!(M%_(D$).AV+P`` +XMZ]20D)"058GEBT4(78L0B15(=PH(BT`$QP7\F`H(`````*-(F@L(PXVT)@`` +XM``"-O"<`````58GEBT4(7<<%-&4)"`$```"C,&4)",.)]HV\)P````!5B>57 +XM5E.#["R+/31E"0B+=0B%_W1%H3!E"0B_`0```,<%-&4)"`````")!H/$+(GX +XM6UY?7+__S\`@\`$B1:+%4`K"0B_`0```(D$C8"9"PB+!)6`F0L( +XMBPB%R76;C4+_HT`K"0B#Q"R)^%M>7UW#Z(CV__\Q_X7`#XAZ____H;29"PB% +XMP`^%P0```,=%X``````QVXU%[@'8B40D!*&T=@H(QT0D"`$```")!"3H&G3^ +XM_X/X_XG'=&.A8)D+"(7`#X6;````@\,!C47NB5PD"(E$)`2)-"3H$.X``(/` +XM`0^%$____\=$)`@`````QT0D!`````#'!"0`````Z)?Q_/\['8!1"0ARBP^V +XM1>X-```@`(D&Z=_^__^-=@"+5>"%TG5)Z+#S_/^+`(E$)`2AM'8*"(D$).AA +XME@``@\`!="S'1>`!````Z4C____'!"0`````Z'3]__^-="8`Z2K___\/MD7N +XMB0;IC/[__\<&`````.F!_O__D(UT)@!5B>6#[`B+50B%TG0*H4`K"0B#^`A^ +XM"^@T-P``R>ENC/[_@\`!HT`K"0B)%(6`F0L(R<.-M@````"-O"<`````58GE +XM@^P(H;"9"PB%P'04Z,P5``#H1Q8``,<%L)D+"`````#H."8``*$T=PH(QP5\ +XM=PH(`0```,<%1'<*"`````#'!>@D"0C_____R2T`=@D(P?@"PXUT)@"-O"<` +XM````58GE5U:^`0```%.[`'8)"(/L'(L]-'<*"(E%Z*%4F0L(QT7L`````(E% +XM\(L3A=)X,O?"````0'4J@_I_?R4/ML(/MX0`X"`)"*@0#X35````@_HC#X3, +XM````@\,$BQ.%TGG.B1U4F0L(BQ.)V872=$XYRW0&@WG\7'0UA=*-=@!X+O?" +XM````0'4F@_I_C78`?QX/ML(/MX0`X"`)"*@0=`6#^B-U*_;$('4FD(UT)@"# +XMP02)#529"PB+$872=;*A-'<*"#'VHU29"PB#>/P*=$NAC)@*"*/`*PD(H42: +XM"PBCQ"L)"(L#QP0DP"L)"(E$)`3H]?+\_X7`=#J%]HL=5)D+"`^%(O___XM% +XM\*-4F0L(BT7L@\0<6UY?7<.#Z`2C5)D+".NK]L0@#X4K____D.DN____BT7H +XMAT[__X/X_W0I@^@!=0?'1>P!````BQ4T=PH(.?IT##M= +XM\','B=`I^`%%\(G7Z5C___^#?>P!&<`)1>SKV(GV58GE5U93@>R,````H<27 +XM"@C'19@`````A<`/A/,$``#'1"0$Q)@*",<$),!$"0CHS-?^_\=$)`3$F`H( +XMQP0D($4)"(E%G.BUU_[_QT0D!,28"@C'!"1@1PD(B46@Z)[7_O^)PZ$\9`D( +XMA<`/A)@$``#HVA,``,<$)`````#HWN[__X,]A'<*"`$9P/?0"05`*PD(A=MT +XM*HL#AW\_X7`#X5X!```QP4`F0H(`````*%@ +XM9`D(AR!^O\````/C]<```"A<'<*"`^V +XM'`*`^S4/A-,```"$VP^4P#'2BPTXF@L(AC2$0`` +XMB?;H2Q(``.A&(@``QP5$=PH(`````,<%?'<*"`$```#HW3(``.@8B/[_QP7H +XM)`D(_____Z$T=PH(+0!V"0C!^`*)1;#IK@4``+L"````,<`QTNDT____C57L +XMB578C47@C578QT7<`0```(E$)`2)%"3H_&<``(/X`0^$(`$``(/X`G13A"$VP^4P(#[-0^4PNGO_O__/?___W\/A`C____HAN___\<%A'<*"``` +XM``#HAX?^_X'$C````(G86UY?7<,/ML#_)(7@`0D(Z$?L_/^+=>#'!"0*```` +XMZ(R)_O_'1=0`````B770C770Z#KO___'!81W"@@`````B30DZ-@%_O^%P`^% +XMI````(DT).CH^___QT0D!,28"@C'!"1`0PD(Z-G2_O^) +XM19CI\?K__\=$)`2@1PD(B1PDZ*WH_/^%P`^%>OO__\<%`)D*"`$```#I:_O_ +XM_XU%Z(E$)`BAM'8*",=%Z`````#'1"0$?V8$0(D$).@#Z?S_BW7HA?8/A53[ +XM___HI^W__S';A<`/B47[___I(?W__XM%F,<%Z"0)"/____^%P`^$7`8``(M5 +XMF(L"A<`/A$\&``"+,,=$)`1@0PD(B30DZ"#H_/^%P`^$S08``,=$)`1P0PD( +XMB30DZ`CH_/^%P`^$M08``,=$)`3`0PD(B30DZ/#G_/^%P`^%!08``(LU-'<* +XM"('^`'8)"'8B@W[\"G4?Q<=#:%THUT)@!X+O?"````0'4F@_I_ +XMC78`?QX/ML(/MX0`X"`)"*@0=`6#^B-U+_;$('4JD(UT)@"#P02)#529"PB+ +XM$872=;&A-'<*"#'_HU29"PB#>/P*#X2!!0``BP;'!"3`*PD(B40D!.@EZ_S_ +XMA<`/A.<%``"%_XLU5)D+"`^%)____XM%N+X!````QP748PD(`````*-4F0L( +XMH;"9"PB%P'04Z'X,``#H^0P``,<%L)D+"`````#HZAP``(/N`<<%?'<*"`$` +XM``#'!41W"@@`````#X6O^O__Z$@-``"A-'<*"(UP!,<`"@```(DU-'<*",=` +XM!`````"+-31W"@B)\H'J`'8)",'Z`HE5L.E?!```C70F`,=$)`@)````H529 +XM"PC'!"0`=@D(+0!V"0C!^`*)1"0$Z%M&__^%P`^.N0(``.C^]?__B46P@?O_ +XM__]_#X0O^?__Z9_Z___'!"0*````C78`Z%N$_O^A-'<*",=$)`@%````QP0D +XM`'8)""T`=@D(P?@"B40D!.@&1O__Z!$<``"A-'<*",<%?'<*"`$```#'!41W +XM"@@`````QP7H)`D(_____RT`=@D(P?@"B46PZX8QV\<%Z"0)"/_____I)?K_ +XM_XGZ@/H2#X3(`P``#X\,!@``@/H##X4V^O__BS4T=PH(QP7H)`D(_____\<% +XM+&4)"`````#'1:P"````B?*!Z@!V"0C!^@*)5;"+5;"+!)4`=@D(A`"`054F0L(B34T=PH(QT0D!,28"@C'!"1`1`D(Z)[. +XM_O^%P'0,QP0D`````.@^C___H529"PB+5:S'!"0`=@D(+0!V"0C!^`*)19") +XM5"0(B40D!.BG1/__A<`/A=,#``"+3:"%R70WBU6@BP*%P'0NBSC'1"0$8$4) +XM"(D\).@IY/S_A*$L90D(AX`=@D(B76PP7VP`NAZ&``` +XMQP5\=PH(`0```,<%1'<*"`````#I!OS__\=$)`@'````Z87^___'1"0("``` +XM`.F_^___Z,((``"+-31W"@C'1;``````B?.!ZP!V"0C!^P+'1"0$`````,<$ +XM)`$```#'!?!="0@`````QP6<=PH(`````.@RS```Z:+[__^+-31W"@C'!>@D +XM"0C_____QP4L90D(`````,=%K`,```")\"T`=@D(P?@"B46PZ4/\__^#Z`2C +XM5)D+".ER^O__]L0@#X7G^?__Z>OY___H*@@``,<$)`!V"0CH#ML``,=$)`0P +XM*@@(B<>)!"3H/&3]_Z$T=PH(BU68QT0D!&!#"0B)1:2+`HL`B00DZ`GA_/^% +XMP`^4P`^VP.A@\?__@^@!#X0\`@``B3PDZ%]C_?_I"/___\=$)`0`=@D(B30D +XMZ'H0__^%P`^$`?K__Z%4F0L(QT0D"`(```#'!"0`=@D(+0!V"0C!^`*)1"0$ +XMZ/U`__^%P`^.EP,``(/H`0^/2`,``(L5-'<*"#M5M'0-.W6X@D"0@!BS4T=PH(QP4L90D(`0```,=%K`0```#I^_G__Z'88PD( +XMA<`/A`G[__^+?:"%_P^$_OK__XM5H(L"A<`/A/'Z___'1"0$P$4)"(L`B00D +XMZ.?>_/^%P`^%U_K__^G-^O__@P7H)`D(`8LU-'<*",<%+&4)"`$```#'1:P$ +XM````Z93Y___HE@4``,<$)`!V"0CH>M@``,=$)`0P*@@(B<:)!"3HJ&']_\=$ +XM)`0*````B30DZ-3B_/_'``````"A-'<*",<%-'<*"`!V"0B)1:CH>R4``(DT +XM).A3V@``QP0D`@```(E$)`3HX\@``(DT).B[8/W_Z*84``"-1?.)1"0$H;1V +XM"@C'1"0(`0```(D$).@Z8?[_A<`/B-,!```/MD7S@_AYB47L='N#^"!T=HE\ +XM)`3'!"0`=@D(Z*W=_/^+1:2C-'<*"(M%[(/X90^$L@$``(/X80^$.P$``,=$ +XM)`RR`0D(QT0D"`4```"A@)@*",=$)`0&````B00DZ'^__?^)!"3H%[D``.@" +XM>O[_B?;IM/S__^BV)```C;8`````Z6_[__^+5:C'1"0,H`$)",=$)`@"```` +XMB14T=PH(ZZS'!>@D"0C_____Z6#Y___'1"0$P$4)"(D\).A=W?S_A<`/A4WY +XM___I0_G__\<%U&,)"`````"^`@```.@@!```H8"8"@C'1"0,RP$)",=$)`@' +XM````QT0D!`8```")!"3HV[[]_XD$).ASN```Z6+V___'!=1C"0@`````,?;H +XMW0,``*&`F`H(QT0D#+8!"0C'1"0(!@```,=$)`0&````B00DZ)B^_?^)!"3H +XM,+@``.D?]O__Q@7,F0L(`.B?`@``Z!H#``#H%1,``,8%S)D+"`'I[?S__Z&` +XMF`H(QT0D#*L!"0C'1"0(!````,=$)`0&````B00DZ$2^_?^)!"3HW+<``,<% +XM-'<*"`!V"0C'!529"P@`=@D(QT0D!`````#'!"0`````Z.3&``#HKQ(``(D\ +XM).BW7OW_QT6P`````.E[[___H8"8"@C'1"0,I0$)",=$)`@#````QT0D!`8` +XM``")!"3HUKW]_XD$).ANMP``H31W"@C'``````"-"7"@A_X(L]2&4)"(7;C02]`````(E%\*&P +XM=@H(BP2XB320=#R-2_^#P@&%R8E5[(D51&4)"'XIP>("H;!V"@B+=?"+!`;' +XM!!#___\'@\($@^D!=>:+5>R-1!K_HT1E"0B+%>"7"@@Y%41E"0A\)*&P=@H( +XMBTWPBP0!QP20`````(U'`<<%1&4)"`````"C2&4)"(/$"%M>7UW#C70F`(V\ +XM)P````!5B>575E.)TX/L"(MU#(E%[(M]"(7V?F&)R"G0.<9^!H7`?E6)QHM% +XM[(T,B(G*@^H$C02U`````"G"BT7LB4WPC1R8.=IR#XL"@^H$B4'\@^D$.=IS +XM\8M%\#G8QP``````=A:%]GX2BP>#[@&#QP2)`X/#!#E=\'?J@\0(6UY?753B<-T'XL"AE;7<-5B>53@^P$H=R7"@B%P'0_BQTX90D(A=MX+XVV +XM`````(D<)(/K`>CU*@``QP0D`````.C)*```H>"7"@B)!"3H3"(``(/[_W77 +XM@\0$6UW#H3AE"0B)!"3HQ"H``,<$)`T```#HB'?^_\<$)`H```#H?'?^_X/$ +XM!%M=PXVV`````%6)Y5.#[!2+%`"B40D",=$)`0`````B10DZ/W;_/\Y +XM'DZ=?[_C78`C;PG`````%6)Y5=64X/L+(7)B47DB")3?`/ +XMA:`!``"A/&4)"(7`B47B+1>"+#4!E"0B-5`,$BUWRCP*P+"(7;#X36`0``C47P.T7L#X38`0``BT7P)?____O!X`0!PJ$\ +XM90D(B57LB47@>C1P0P?L"@?O___\##X]*`0``BTWLAR)1"0$B=#!X`(#!<"L"PB)!"3H1=[\_XM5Z`$5/&4)"(L- +XM/&4)"(E-W(M%X(E$)`B+5>2)5"0$BT7

`"`P7`K`L(B00DZ!'>_/^+5>`# +XM%3QE"0B-#)4`````D(UT)@"AP*P+"(/"`<<$"`````"#P03VP@-UZ8G8B14\ +XM90D(#0````2#Q"Q;7E]=PZD````$#X6O````C57PQT7H`0```(E5[(L=/&4) +XM"(7;B5W<#XZ1_O__BSW`K`L(,=N+1>B+5>"--(R)!"3H%-G\_X7`==2+5>")="0$ +XMB50D"(M-Y(D,).CZV/S_A@>`=C!^`(- +XM````!.E+____@\0LN#\```!;7E]=PXL-P*P+""7____[P>`$`R)!"3H +XM^];\_XE%Z.D[____B?B#Q"S!^!_!Z!X!^%M>7UW!^`(-````!,.+%3QE"0B) +XM5=SI0/[__XL-/&4)"(E-W.DR_O__D%6)Y5=64X/L'(E%Z(L`B<$E__\_`('A +XM``#`_XE-\(E%[(E4)`2)!"3H$Z4``(G#C4`'@_@'=AF+3>B)VHL!Z`WZ__^# +XMQ!RX`0```%M>7UW#_R2%C`,)"+H!````N"````#HZOG___8%1&4)"`=UZ.O2 +XMBT7PN@$```"#R%SHS_G__XM%[+H!````P?@&@^`'@\`P"T7PZ+;Y__^+1>RZ +XM`0```,'X`X/@!X/`,`M%\.B=^?__N@$```"#9>P'BT7L@\`P"T7PZ(;Y__^# +XMQ!RX`0```%M>7UW#BT7PN@$```"#R%SH:?G__XM%\+H!````@\A5Z%GY__^+ +XM1?"Z`0```(/(*^A)^?__C03=`````/?8B<.#ZQP/B"C___^0C70F`(M%[(G9 +XMN@$```#3^(/@#P^^@'@#"0@+1?#H$OG__X/K!'G=@\0Z,GX__^#?>Q_#X2I````BT7LN@$````)1?"#3?!`BT7PZ*CX__^#Q!RX +XM`0```%M>7UW#BS5(90D(BQ5$90D(BSVP=@H(ZQJ-M"8`````C1RU`````(L$ +XM'X$\D/___P=U+X/J`7GH@^X!#XB`_O__BP2WC1RU`````(D$).BYU/S_C5#_ +XMBP0?@3R0____!W31A?8/B%?^__^-')4`````BT7HN@$````#'+>+"^C]^O__ +XMB0/I"?[__X--\#^Z`0```(M%\.@%^/__Z?/]__]5B>57B<=6B=93@^P,@_H! +XM?Q'K'[H!````N"````#HW?___XGP`P6XF0L(.P7@EPH(?^'WQP````0/A.\` +XM``")^H'B____^\'B!`,5P*P+"(L"AAN)D+"#L%X)<* +XM"'P_#[X%K)@*"(,%:'8*"`&#!3AE"0@!J`''!;B9"P@`````="2H`G08QP0D +XM(````.B6)QU93@^P, +XMA<")1?!T4(L'A%P'6V@\0, +XM6UY?7<,QTHGX.WWP#Y3"Z/?[__^--(>)]^O<58GE5U93@^Q\B56(B<*)18R) +XM382+`(7`#X0$!@``BTV(.P$/A?D%``")5?")3>CK!XM5Z#L"=1?`$BW7P +XM@T7H!(L&A?P@=!#K&I"-="8`BW68@W[\('4, +XM@VV8!(M%\#E%F'?KBU68QP(`````BTWHB0PDZ/?%``")19S'1"0$Q)@*",<$ +XM)"!)"0CH0+O^_X7`=`F`/@Y=9QV(HM%G(-X_"!T#8GVZQ6+ +XM59R#>OP@=0R#;9P$BTWH.4V<=^N+=9S'!@````"+1?"+`(7`B46\=0V+5>B+ +XM`H7`#X2"`@``BTV8BW6@(``(L!.P9T!Y"#P02#Q@2!.?___P=T +XM\HM%O(7`#X5X`@``B4VHB4VLB76TB76PBU7HBQ*%THE5['1R.TWP=FV+??#K +XM$9"-="8`@\<$.?EV7(L'B46\BT6\.47L=>PYSP^"X`(``(M=Z(GZQT7````` +XM`,=%Q`````"+1:PK1:C!^`([1<1]PXGX*T7PT7W`P?@".47`?K.)5:R+5>B) +XM?:B#QP0Y^8E=M(E5L'>DBT68B*T6L*W6TP?@"P?X" +XM*<:%_W4_AC!^@+!^P(YVGT,BT68BU6%6+18@I1=C!?=@"BU78B10DZ'4= +XM``"+3:`Y39@/A*(#``"+1>"%P'X2BW7@B70D!(M%M(D$).B@&P``BU7@*57< +XMBTW@/@WW]__^#Z02#[@2+ +XM`3L_?__Z6_]__\[=>@/AG_]__^+?>B)3:B)3:R)=;2)=;#K$)"-="8` +XM@\<$.?X/AFK]__^+1;P[!W7N.?=R0HM=\(GZQT7(`````,=%S`````"+1;0K +XM1;#!^`([1B)^CG>#X83_?__C;0F`````(/"!(/#!#G1=Q:)T"GXB47`P?@" +XMB47$Z0/]__^-="8`.=YVYHL".P-TUNO>BW6@BT6DB4W8QT7<`````(EUU(EU +XMJ(EUK(E%M(E%L(EUT,=%X`````#ITOW__X7)#XA4`0``BU6LBTVHB=.)5=`I +XMRXE-U(7VBWV@#X@F`0``BTVDB?HK5?")R"M%Z,'Z`L'X`CG"#XYO_?__BT68 +XMBTV)1:")3:3I7/W__XM%Z"M%B,'X`HD$).B4&P``BTVP.4V<#X3:`@`` +XM@'V3``^%S@$``(G[BWWDBW7H*UWDP><"`?Z)7"0$B30DZ((6``"+1?")V8GR +XM`?CH)/+__^F^_?__BT6LZ5?]__^+1>@K18C!^`*)!"3H-AL``(MUL#EUG`^$ +XM60(``(M%Y(E$)`2+5>B)%"3H:!D``(M-Y(M5\"M5C(E,)`2+=>B+#>"7"@C! +XM^@*)-"2+18R)_N@R\?__BT7DBUWH*W7DP>`"`<.)192)'"2)="0$Z/45``"+ +XM1?")V@-%E(GQZ);Q__^+7>3I#_W__XM-C(MUB(E-\(EUZ.D6^O__BTV8BW6< +XMB<^)3:")=:3IQ_[__XM%H#';BU6DB474B46HB46LB56TB56PB470Z9W^__^+ +XM38PI3=#!?=`"BW70C00SB00DZ&,:``"+1:`Y19@/A`L!``"+1>#WV(D$).A* +XM%```BU7B)^8M%\.B?\/__BUWDZ1C\__^+ +XM1=R)1"0$BU6TB10DZ-44``#I>_S__XMUY(ET)`2+1>B)!"3H[A<``(M5\"M5 +XMC(ET)`2+3>C!^@*)#"2+#>"7"@B+18SHO>___^GZ_?__BT6,C0RPBW6XC129 +XMC1RP.=IS#HL"@\($B0&#P00YVG+RQP,`````Z6'___^+19@K18R+%>"7"@C! +XM^`*--`,YUGX"B=:+1=R)1"0$BU6TB10DZ$(4``"+19PK18C!^`(IQHDT).B? +XM$@``Z6;[__^)?"0$BU7HB10DZ!L4``"+=8@I=9R+38PI39C!?9P"P7V8`HM% +XMG"E%F(M5F(D4).AF$@``Z9S[__^)?"0$BU7HB10DZ.(3``"+5>B)^8M%\(/$ +XM?%M>7UWI?N___XE\)`2+=>B)-"3HOQ,``(M%\(GYB?+H8^___^G]^O__C;0F +XM`````(V\)P````!5B>575E.#[!RAA'<*",<%1&4)"`````#'!81W"@@````` +XMQP5(90D(`````(E%\*%XF0L(Z.?V__^A1&4)",<%1&4)"`````"C3&4)"*%( +XM90D(QP5(90D(`````*-090D(H2QW"@CHM?;__X$]-'<*"`!V"0@/AB("``"[ +XM`'8)",=%Y/_____'1>@`````.QU4F0L(3_=1:A1&4)"(D=5)D+"(E% +XMY*%(90D(B47H,=*!^P!V"0@/E,*)V.C,\O__C1R#.1TT=PH(=[^#?>3_#X3$ +XM`0``BPU$90D(H4QE"0B+%>"7"@B%P'0.BQU090D(A=L/A%T!``#'!4QE"0@` +XM````QP5090D(`````*%(90D(N@$```")1>PQP.B\[/__BT7LQT7@`````(7` +XM>&Z+7>"AL'8*"(M-X,'C`HL4&*%`F@L(BP08Z%#V__^AL'8*"(LUX)<*"(L\ +XM&*%`F@L(A?:+%!A^)(L',`Y1>Q]DJ$X90D(.47L?4`[1>!\.XM=X,'C`J%` +XMF@L(NOAO"0B+3>"+!!CHUO7__Z%`F@L(BP08@\,$QP``````@T7@`8M%X#D% +XM.&4)"'W+BT7LHSAE"0B+1>B)!"3HHQ@``(M%Y(D$).AX%@``QP0D`````.C\ +XM"@``Z-=C_O^+1?"CA'<*"(/$'%M>7UW#,RA>)D+".B(]/__ +XMZ7/^__^A1&4)"(E%Y(G!H4AE"0B)1>CI*_[__XVV`````(V_`````%6)Y8/L +XM&(EU^(MU"(E=](E]_(L55)D+"#L5-'<*"'01BUWTBW7XBWW\B>Q=Z0_]__^+ +XM#4QE"0B%R702H>"7"@@K!;B9"P@IR(/X`G[3C02U`````(G7*</_ +XM_S\`@?\`=@D(#Y3`B40D!(D<).B9E0``@_C_=&B#^`$/A(0```"#^/QUEKH! +XM````N%P```#HA_+__XG8N@$```#!^`:#X`>#P##H#X`>#P##H6O+__XU#,+H!````Z$WR__^+7?2+=?B+??R)[%WI3&+^_[H! +XM````N%X```#H+?+__X/[?W1_@\M`N@$```")V.@9\O__Z\K'1"0$Q)@*",<$ +XM)"!)"0CHTZ_^_X7`=`F`/@Y!2QW"@@/E,"!XO__/P`/ML")%"2)1"0$Z/:3``"-4`>#^@9V +XM9@'&.?Y\O"G^@T7P`87;=;:[`'8)".L6C;0F``````'&.?Y\!H-%\`$I_H/# +XM!#L=5)D+"`^#H@```#'`@?L`=@D(#Y3`B40D!(L#)?__/P")!"3HEY,``(U0 +XM!X/Z!G>__R25K`,)"/\DE<@#"0B0@\8!]\8'````C;0F`````'2"@\8!]\8' +XM````=>.-=@#I;____X/&`??&!P```(GV=("#Q@'WQ@<```!UZ(UV`.EM____ +XM@T7P`3'VZ6+___^#Q@3I6O___P'`]]B-=`;]Z4W___^#Q@+I1?___XM%\(D$ +XM).C8%```B30DZ+`2``#'1"0$Q)@*",<$)"!)"0CHS*W^_X7`=`F`/PL0@``BU4,BTT(@_H!B=`/C@D$``"%R:.L;PD(B<@/CO`#```Y +XM%:QO"0BCH&\)"`^$#0$``*%`F@L(QP5`F@L(`````(D$).A<2?[_H;!V"@C' +XM!;!V"@@`````B00DZ$5)_O^AK&\)"+H```$`B<&CX)<*"(G0P?H?]_F-4`&- +XM!(4(````B17(=@H(B00DZ)50``"+%_(L5R'8*"(G8@\,!.<)_VL<$E@````"AR'8* +XM"(DU0)H+"(/``<'@`HD$).@Z4```BQ7(=@H(A=*)QGXKNP$```"AX)<*"(/` +XM`<'@`HD$).@64```B42>_(L5R'8*"(G8@\,!.<)_VL<$E@````")-;!V"@CH +XM\>?__X'$+$(``%M>7UW#.<@/A>O^___'!"3D`PD(Z)[`_/^%P'1'H:QO"0C' +XM1"0(`````,=$)`0`````B00DZ#%I``#'1"0$,"H("(G#B00DZ$]$_?^)7"0$ +XMQP0D`$P)".@_MOW_B1PDZ)=#_?_'!"3L`PD(Z$?`_/^%P'1'H:!O"0C'1"0( +XM`````,=$)`0`````B00DZ-IH``#'1"0$,"H("(G#B00DZ/A#_?^)7"0$QP0D +XMY$L)".CHM?W_B1PDZ$!#_?_'!"3R`PD(Z/"__/^%P`^$*?[__XD$).C4O@`` +XMQT0D"``(``")1"0$C87DWO__B87@O?__B00DZ$#'_/^-1>2-C>3>___'A>#^ +XM__\`````QT7D8P```,=%Z&\```#'1>PC````QT7P`````(E$)`2)#"3H*;4` +XM`(7`B<2)PXD,).CNP/S_C8WDO?__*YW@O?__B8W3>__^)7"0(B40D!.C!QOS_H:QO"0C'A)WDO?__`````(V2] +XM___'1"0(`````,=$)`0`````B00DZ,9G``")'"2)QHE$)`3H9+[\_XDT).A@ +XM30``QT0D!#H```")/"3H#,3\_XV-Y+W__XD,)(E$)`3H.K[\_XU%Y(V-Y+W_ +XM_\=%Y&P```#'1>AI````QT7L(P```,=%\`````")1"0$B0PDZ$VT``"%P(G& +XM#X3[````B<.-1>2)!"3H$L#\_XV-Y+W__RN=W+W__XE,)`3!^P(!PXV%Y-[_ +XM_XE<)`B)!"3HZ\7\_Z&@;PD(QX2=Y-[__P````#'1"0(`````,=$)`0````` +XMB00DZ/=F``"-C>3>__^)#"2)PXE$)`3HC[W\_XD<).B+3```QT0D!#H```") +XM-"3H-\/\_XE$)`2-A>3>__^)!"3H9;W\_XV-Y-[__\>%X/[__P````")3"0$ +XMQP0D($P)".C)L_W_Z2'\__^X&````.D&_/__N%````"0C70F`.GH^___C8WD +XMO?__C87DWO__B40D!(F-W+W__XD,).@IOOS_Z2]__^-C>3>__^) +XM1"0$B0PDZ`R^_/_KA8VT)@````"-O"<`````58GE5E.#[""+70RAK&\)"(MU +XM"(D#H:!O"0B)!HU%\(E$)`BAM'8*",=$)`1H=`A`B00DZ*2^_/^#P`%T%P^W +XM1?)FA7<.0 +XMC70F``^WP+H!````B0:AK&\)"#L#==^AH&\)"#'2.P8/E<*#Q"!;B=!>7<.0 +XMC;0F`````%6)Y8/L&(72B5WTB=.)=?B)QHE]_'0%@#H`=22+1@B)!"3H&4L` +XM`,=&"`````"+7?2+=?B+??R)[%W#D(UT)@")%"3HU,/\_XUX`8M&"(E\)`2) +XM!"3H!DP``(E\)`B)7"0$B48(B00DZ/_"_/_KOY!5B>6#[!B+%,````\.=,/A/@```"+#6AE"0B%R0^%^@```(G'B<8E````(('G +XM````"('F````$(E%\*&`;0D()0```!`Y\'0IA?8/A-X!``"AL&X)"(7`=!B` +XM.`!T$XL5O&X)"(72=`F`.@`/A9T"``"A@&T)""4````(.?AT+87_#X1J`0`` +XMH>QN"0B%P'0<@#@`=!>+%>!N"0B%TG0-@#H`#X4_`@``C70F`*&`;0D()0`` +XM`"`[1?!T48M%\(7`#X3N````H1!O"0B%P'0]@#@`=#B+%1QO"0B%TG0N@#H` +XM="G'1"0(,#H&",=$)`0!````B00DZ,V]_/^!#8!M"0@````@C;0F`````(M= +XM](MU^(M]_(GL7<.-=@"+#;QN"0B%R0^$^/[__X`Y``^$[_[___?"````$`^% +XM>`$``(G&@>8````0]\(````@#X5W`0``B=@E````((E%\('B````"'1"B=^! +XMYP````@/A8````0)0```"")1?#'1"0(,#H&",=$)`0!```` +XMB0PDZ"N]_/_'!8!M"0@`````B=^!YP````CIAO[__Z$<;PD(A<`/A$O___^` +XM.``/A$+____'1"0(,#H&",=$)`0!````B00DZ.:\_/^!)8!M"0C____?Z1O_ +XM__^AX&X)"(7`#X2N_O__@#@`#X2E_O__QT0D"#`Z!@C'1"0$`0```(D$).BI +XMO/S_@26`;0D(____]^E^_O__H;!N"0B%P`^$-O[__X`X``^$+?[__Z&\;@D( +XMA<`/A"#^__^`.``/A!?^___'1"0(,#H&",=$)`0!````B00DZ%:\_/_V!8-M +XM"0@(=!*AX&X)"(7`=`F`.``/A<\```#V!8-M"0@@=!*A'&\)"(7`=`F`.``/ +XMA8T```"!)8!M"0C____OZ;K]__^)QH'F````$`^$N/[__^E]_O__B=@E```` +XM((E%\`^%@_[__XG>@>8````0Z9[^___'1"0(,#H&",=$)`0!````B00DZ,F[ +XM_/^!#8!M"0@````(Z9[]___'1"0(,#H&",=$)`0!````B00DZ**[_/^!#8!M +XM"0@````0Z3S]___'1"0(,#H&",=$)`0!````B00DZ'N[_/^!)8!M"0C____? +XMZ4S____'1"0(,#H&",=$)`0!````B00DZ%2[_/^!)8!M"0C____WZ0K___^) +XM]HV\)P````!5B>6#[!CH%74``,=$)`3$F`H(QP0D\$4)".CAHO[_A7"7"@A_/*$T;PD(A7<.+%?QM"0B%TG3& +XM@#H`=,&A%&X)"(7`=`6`.`!U>*'\;0D(A7<.#Q!!;7EWI +XM=%+^_\=$)`@P.@8(QT0D!`$```")!"3H6+C\_^EK____C;0F`````%6)Y5=6 +XM4X/L+(MU#(M]"(7V?@@[->"7"@A^"(/$+%M>7UW#QT0D!,28"@C'!"0@20D( +XMZ-F?_O^%P`^$H`(``(L5+'<*",=%V`````"+&H7;=!2)T(/`!(L(A``````=#R+ +XM%5"9"PB+#529"PB)T#G*#X=Z`@``+0!V"0C!^`(#1=@YRHE%W(G0#X);`@`` +XM+0!V"0C!^`(#1=B)1>#'1"0$Q)@*",<$)"!)"0CH-9_^_X7`=%*A9&4)"(L= +XMX)<*"`^O'6AV"@@#';B9"PB%P`^$I````#M=X'P,Z`?X__^-M"8`````H61E +XM"0B%P'08H529"P@M`'8)",'X`@-%V#G8#X2(`0``BP<]____!W0XJ0````0/ +XMA(````")PH'B____^\'B!`,5P*P+"(L"AZ#!;B9"P@!@^X!=%N#QP3I0?___Z%4F0L(+0!V"0C!^`(#1=@!PHE% +XMW(E5X.DD____.UW<#XQD____.UW@#XU;____Z(;W__^-M@````#I2____XD$ +XM).BS5/[_@P6XF0L(`8/N`76EQT0D!,28"@C'!"0@20D(Z".>_O^%P'0-H61E +XM"0B%P`^%UP```*'@EPH(.06XF0L(#XP,_O__#[X5K)@*"/;"`0^$I@```(L- +XM:'8*",<%N)D+"`````"#P0&#X@*)#6AV"@@/A-K]__^A0)H+"(L$B(L`A<") +XM1?`/A*,```"-1?")!"3'1"0$`0```.B7_?__H6AV"@B+%;B9"PB-'(4````` +XM`QU`F@L(BP.!/)#___\'#X6+_?__C4H!C12-`````.L#@\$!B0VXF0L(BP.+ +XM!!"#P@0]____!W3HZ6+]___H4O;__XGVZ6S^__^#Z`&CN)D+"(/$+%M>7UW# +XMZ#;V___I'____\=%V`````#'1=P`````QT7@`````.G._?__QP0D(````.C+ +XM4/[_QP6XF0L(`0```.D'_?__B7>E9_/__BQ50;@D(A=)TP8`Z`'2\ +XMH5QN"0B%P`^$N````(`X``^$KP```(L5+&X)"(72#X2A````@#H`#X28```` +XMB00DQT0D"#`Z!@C'1"0$`0```.A1M/S_B5PD!(DT).CY^___H6AN"0B%P'0) +XM@#@`#X6B````H2QN"0C'1"0(,#H&",=$)`0!````B00DZ!:T_/^#Q!!;7EW# +XMQT0D"#`Z!@C'1"0$`0```(D$).CWL_S_QT0D!`$```")-"3HF_O__Z%H;@D( +XMA7>F53?[_QT0D"#`Z!@C' +XM1"0$`0```(D$).AYL_S_Z4'___^0C;0F`````%6)Y5=64X/L'(M]"(L5N)D+ +XM"#G7#X3$````.SW@EPH(#XVX````A?\/A+@```")^(G^@^`'P?X#B47LZS&- +XM=@"+1>P!\#G##Y_`A,!T;<<$)`T```#HED[^_S'2.SW@EPH(QP6XF0L(```` +XM`'UPB?LITXU#!(/X"'82H>1M"0B%P'0)@#@`#X5:`0``A=M_=/?;@_L$?A*A +XM6&\)"(7`=`F`.``/A?H```"`/<"9"P@`=8XYWP^7UW#QP0D#0```.C^3?[_ +XMQP6XF0L(`````(/$'%M>7UW#@_L$?A*A9&\)"(7`=`F`.``/A8@```"`/<"9 +XM"P@`#X2M````B=.)_H'C^````(/F^#GS#X3/````BQ5H=@H(B57PBPU`F@L( +XMBP21@3RP____!W0K.?-](8/#",<$)`D```#HA4W^_SG>?^VA:'8*"(E%\(L- +XM0)H+"(DUN)D+"*&XF0L(B?HIPHE4)`2+5?#!X`(#!)&)!"3H?_G__^LDB5PD +XM"(E<)`2)!"3HZ:[\_\=$)`@P.@8(B5PD!(D$).BEL?S_B3VXF0L(@\0<6UY? +XM7<.+%6AV"@B)5?"+#4":"PCKG8E\)`B)?"0$B00DZ*:N_/_'1"0(,#H&"(E\ +XM)`2)!"3H8K'\_^N[H6AV"@B)1?"+#4":"PCI9/___Y!5B>575E.#[`R+?0BA +XM:'8*"#G'#X3J````.SW(=@H(#X_>````B?LIPX7;#XX``0``]@6LF`H(`0^$ +XMB````(L5:'8*"*%`F@L(BP20BQ"%TG1TBQ7@EPH(B=&#Z0%T(X$\B/___P=U +XM&HT4D.L0C78`BT+X@^H$/?___P=U!8/I`77NB0PDZ%;]__^+%;B9"PBAX)<* +XM"(L-:'8*""G0B40D!*%`F@L(P>("`Q2(B10DZ$SX__^#ZP%T1/8%K)@*"`$/ +XMA7C___^#^P%^%:%`;PD(A`.@")]G5'H01O"0B% +XMP'2R@#@`=*V)WO?>,=N%]G\+ZZ&-="8`H01O"0B#PP''1"0(,#H&",=$)`0! +XM````B00DZ,RO_/\Y\W7@_X!?BF)="0(B70D!(D4).C:K/S_ +XMQT0D"#`Z!@B)="0$B00DZ):O_/_I0O___Z$$;PD(A0C70F +XM`%6)Y5.#["2A)"P)"(U=],=%^`,```#'1?0H+0D(B40D",=$)`0<+`D(B1PD +XMZ`\H``"A$"P)",=%]!@M"0C'1"0$""P)"(D<)(E$)`CH[R<``*%,+`D(QT7T +XM""T)",=$)`1$+`D(B1PDB40D".C/)P``H3@L"0C'1?3X+`D(QT0D!#`L"0B) +XM'"2)1"0(Z*\G``"A8"P)",=%].@L"0C'1"0$6"P)"(D<)(E$)`CHCR<``*%T +XM+`D(QT7TV"P)",=$)`1L+`D(B1PDB40D".AO)P``H20L"0C'1?3(+`D(QT0D +XM!!PL"0B)'"2)1"0(Z$\G``"A$"P)",=%]+@L"0C'1"0$""P)"(D<)(E$)`CH +XM+R<``*%,+`D(QT7TJ"P)",=$)`1$+`D(B1PDB40D".@/)P``H3@L"0C'1?28 +XM+`D(QT0D!#`L"0B)'"2)1"0(Z.\F``"A8"P)",=%](@L"0C'1"0$6"P)"(D< +XM)(E$)`CHSR8``*%T+`D(QT7T>"P)",=$)`1L+`D(B1PDB40D".BO)@``BPW( +XMF0L(A``````ZQ"#QP>`4@_\=```` +XMBU7@BX($+`D(C01`BQR%J&T)"(7;=-D/MC.)\(3`=-")'"3HI:<``(E%[(D$ +XM).@FJOS_BU7@BXH0+`D(B47P@_G_#X2?````@'L!`(GP#[;0=%*+7=B+==P! +XMTP^V`S@$%G1?/#5T6RP!=86+==B-5>R)5"0$B30DZ,`B``"+5>"+@A`L"0B% +XMP'5T#[:"""P)"(@#Z5C___^0C70F`(/$+%M>7UW#BUW8`=,/M@/KN,=%W$`I +XM"0C'1=C`JPL(Z1[___^-!+^-!(4(+`D(B40D!(U%[(E,)`B)!"3HWB,``,8# +XM->D)____BT78C77LB70D!(D$).A$(@``Z?+^__^)1"0(C02_C02%""P)"(UU +XM[(E$)`2)-"3HHB,``.G0_O__C;8`````C;PG`````%6)Y5=64X'L3`@``(U= +XMR(D<).AEK?S_B1PDQT0D!!P```#H9:C\_XU%V(E<)`2)1"0(QP0D`0```.C^ +XMI_S_C478B00DQT0D!&`>!0CH/RO]_XV%R/?__XE%\,<%8&4)"`$```#'!2!W +XM"@CZ`PD(QP0D++((".@RI_S_A<")PW0)@#@`#X6:`P``NS&R"`C'1"0$``@` +XM`,<$)(!E"0CHWC3^_XE<)`3'!"2`90D(Z+JK_/^%P`^.G`(``,<$)`[/"`CH +XM%JC\_X7`#X6>`P``,=*)%91O"0C'!"0*!`D(Z/JG_/^%P`^$9P,``+H!```` +XMB16X;PD(QP0D#00)".C;I_S_QP0D$`0)"*.(;PD(Z,JG_/_'!"03!`D(H\1O +XM"0CH&:;\_\<$)!8$"0BCK&\)".@(IOS_HZ!O"0BAH&T)"(7`="R[H&T)"(UU +XM\(VV`````(ET)`2)!"3H<*[\_XG"B=B#PPSH:.G__XL#A'<*"(7;=&Z`.P!T +XM::$<;PD(AB)1"0$C47LB00DZ%/G__^+ +XM1>B)1"0$BT7LB00DZ,'B__^-1=B)!"3H]B?]_^B!^___@<1,"```6UY?7<.A +XM4&X)"(7`=`F`.``/A0K___^+%4QO"0@QP(72#X3__O__,<"`.@`/E<#I\O[_ +XM_XL5-&\)"#'`A=(/A,+^__\QP(`Z``^5P.FU_O__@_C_#X27`0``A<`/A$$! +XM``"A@)@*"(L=#'8*",=$)`R4"`D(QT0D"!8```#'1"0$!P```(D$).BNAOW_ +XMB5PD!(D$).A"@```H:!M"0C'!:QO"0A0````QP6@;PD(`````,<%N&\)"``` +XM``"%P,<%E&\)"``````/A)O]__^[H&T)"(G8,=*#PPSH[.;__XL#A*#Q!`QP%M>7<.#Q!"P +XM`5M>7<-5B>575C'V4S';@^P,BT4(BSB+@P`L"0B)/"2)1"0$Z'BB_/^%P'08 +XM@\8!@\,4@_X&==^#Q`RX_____UM>7UW#BTT,BP&+402-#+:)!(T(+`D(B12- +XM#"P)"(M%$(D$C1`L"0B#Q`PQP%M>7UW#C78`58GE5U8Q]E,QVX/L#(M]".LV +XMBX80+`D(@_C_="")1"0(C02;C02%""P)"(E$)`2+A@`L"0B)!"3H@R```(/# +XM`8/&%(/[!G0JBT<$A53,=N#[!2-M"8`````BX.D;0D(@\,, +XMB00DZ!\O``"!^^`!``!UYV8QVXUT)@"+@X1O"0B#PPR)!"3H_RX``(/[5'7J +XMH8"8"@C'1"0,&00)",=$)`@!````QT0D!`0```")!"3'!:QM"0CX'`D(Z/N" +XM_?^)!"3H8RS^_\=$)`PO!`D(QT0D"`(```#'1"0$!````,<%N&T)""P$"0BC +XML&T)"*&`F`H(B00DZ+^"_?^)!"3H)RS^_\=$)`P\!`D(QT0D"`,```#'1"0$ +XM!````,<%Q&T)")_1"`BCO&T)"*&`F`H(B00DZ(."_?^)!"3HZRO^_\=$)`Q, +XM!`D(QT0D"`0```#'1"0$!````,<%T&T)",`%"0BCR&T)"*&`F`H(B00DZ$>" +XM_?^)!"3HKRO^_\=$)`QA!`D(QT0D"`4```#'1"0$!````,<%W&T)"$V]"`BC +XMU&T)"*&`F`H(B00DZ`N"_?^)!"3H!_?^)!"3HORK^_\=$)`RI!`D(QT0D"`D```#'1"0$ +XM!````,<%#&X)"*8$"0BC!&X)"*&`F`H(B00DZ!N!_?^)!"3H@RK^_\=$)`R[ +XM!`D(QT0D"`H```#'1"0$!````,<%&&X)"$T;"0BC$&X)"*&`F`H(B00DZ-^` +XM_?^)!"3H1RK^_\=$)`S.!`D(QT0D"`L```#'1"0$!````,<%)&X)",L$"0BC +XM'&X)"*&`F`H(B00DZ*.`_?^)!"3H"RK^_\=$)`SA!`D(QT0D"`P```#'1"0$ +XM!````,<%,&X)"-X$"0BC*&X)"*&`F`H(B00DZ&>`_?^)!"3HSRG^_\=$)`SY +XM!`D(QT0D"`T```#'1"0$!````,<%/&X)"+/1"`BC-&X)"*&`F`H(B00DZ"N` +XM_?^)!"3HDRG^_\=$)`P(!0D(QT0D"`X```#'1"0$!````,<%2&X)"`4%"0BC +XM0&X)"*&`F`H(B00DZ.]__?^)!"3H5RG^_\=$)`P +XM!0D(QT0D"!8```#'1"0$!````,<%M&X)"""_"`BCK&X)"*&`F`H(B00DZ`]^ +XM_?^)!"3H=R?^_\=$)`RM!0D(QT0D"!<```#'1"0$!````,<%S&X)"*;K"`BC +XMN&X)"*&`F`H(B00DZ--]_?^)!"3H.R?^_\=$)`S#!0D(QT0D"!@```#'1"0$ +XM!````,<%V&X)"'CG"`BCT&X)"*&`F`H(B00DZ)=]_?^)!"3H_R;^_\=$)`S0 +XM!0D(QT0D"!D```#'1"0$!````,<%Y&X)",0>"0BCW&X)"*&`F`H(B00DZ%M] +XM_?^)!"3HPR;^_\=$)`S?!0D(QT0D"!H```#'1"0$!````,<%\&X)"*/!"`BC +XMZ&X)"*&`F`H(B00DZ!]]_?^)!"3HAR;^_\=$)`SU!0D(QT0D"!L```#'1"0$ +XM!````,<%_&X)"(T%"0BC]&X)"*&`F`H(B00DZ.-\_?^)!"3H2R;^_\=$)`P# +XM!@D(QT0D"!P```#'1"0$!````,<%"&\)"->\"`BC`&\)"*&`F`H(B00DZ*=\ +XM_?^)!"3H#R;^_\=$)`P3!@D(QT0D"!T```#'1"0$!````,<%%&\)"$D;"0BC +XM#&\)"*&`F`H(B00DZ&M\_?^)!"3HTR7^_\=$)`PD!@D(QT0D"!X```#'1"0$ +XM!````,<%(&\)""$&"0BC&&\)"*&`F`H(B00DZ"]\_?^)!"3HER7^_\=$)`PT +XM!@D(QT0D"!\```#'1"0$!````,<%+&\)"#$&"0BC)&\)"*&`F`H(B00DZ/-[ +XM_?^)!"3H6R7^_\=$)`Q-!@D(QT0D""````#'1"0$!````,<%.&\)"$H&"0BC +XM,&\)"*&`F`H(B00DZ+=[_?^)!"3H'R7^_\=$)`QE!@D(QT0D""$```#'1"0$ +XM!````,<%1&\)"&(&"0BC/&\)"*&`F`H(B00DZ'M[_?^)!"3HXR3^_\=$)`Q^ +XM!@D(QT0D""(```#'1"0$!````,<%4&\)"'L&"0BC2&\)"*&`F`H(B00DZ#][ +XM_?^)!"3HIR3^_\=$)`R6!@D(QT0D"",```#'1"0$!````,<%7&\)"),&"0BC +XM5&\)"*&`F`H(B00DZ`-[_?^)!"3H:R3^_\=$)`RL!@D(QT0D""0```#'1"0$ +XM!````,<%:&\)"/G."`BC8&\)"*&`F`H(B00DZ,=Z_?^)!"3H+R3^_\=$)`S" +XM!@D(QT0D""L```#'1"0$!````,<%>&X)"+\&"0BC;&\)"*&`F`H(B00DZ(MZ +XM_?^)!"3H\R/^_\=$)`S6!@D(QT0D""P```#'1"0$!````,<%H&T)"-,&"0BC +XM?&X)"*&`F`H(B00DZ$]Z_?^)!"3HMR/^_\=$)`SI!@D(QT0D""T```#'1"0$ +XM!````,<%P&X)".8&"0BCI&T)"*&`F`H(B00DZ!-Z_?^)!"3H>R/^_\=$)`S] +XM!@D(QT0D""4```#'1"0$!````,<%=&\)"`````#'!7AO"0@`````H\1N"0BA +XM@)@*",<%@&\)"`T$"0B)!"3HPWG]_XD$).@K(_[_QT0D#!,'"0C'1"0()@`` +XM`,=$)`0$````QP6,;PD(#L\("*.$;PD(H8"8"@B)!"3HAWG]_XD$).CO(O[_ +XMQT0D#"D'"0C'1"0()P```,=$)`0$````QP68;PD(%@0)"*.0;PD(H8"8"@B) +XM!"3H2WG]_XD$).BS(O[_QT0D##D'"0C'1"0(*````,=$)`0$````QP6D;PD( +XM$P0)"*.<;PD(H8"8"@B)!"3H#WG]_XD$).AW(O[_QT0D#$L'"0C'1"0(*0`` +XM`,=$)`0$````QP6P;PD("@0)"*.H;PD(H8"8"@B)!"3HTWC]_XD$).@[(O[_ +XMQT0D#+@("0C'1"0(*@```,=$)`0$````QP6\;PD($`0)"*.T;PD(H8"8"@B) +XM!"3HEWC]_XD$).C_(?[_QP7(;PD(`````,<%S&\)"`````"CP&\)"(/$%%M= +XMPU6)Y8'L2`@``(V%\/?__XE%\(M%"(E=](EU^(E]_,<%('<*"+;1"`B)!"3H +XM`,;]_\=$)`3P(P8(B<.)!"3H?AG]_XL#A<`/A+0```"+$(72#X2J````@_HM +XM#X2V````B9W@]___QX78]___`````,>%W/?__P````")!"2_)`<)".@:D@`` +XMB00DZ%(A_O_'1"0$,"H("(F%S/?__XD$).@<&?W_B[7,]___N04```#\\Z8/ +XMA%W/?__P````!T(,<$)'<``!#H>A7]_\>%V/?__P````#'A=SW__\` +XM````C4,$B87@]___BT,$AG'1"0$`````,<$)"`+"0CHH&\``.F%_O__ +XMB[7,]___O_[>"`BY!0```/SSIG04B[7,]___OS,'"0BY!@```/.F=2^AH&\) +XM",<$)"`+"0B)1"0$Z%UO``#I0O[__XE4)`3'!"0D"PD(Z$AO``#I+?[__XNU +XMS/?__[\6!`D(N0,```#SIG2]B[7,]___OV$'"0BY!0```/SSI@^$40(``(NU +XMS/?__[\3!`D(N0,```#SI@^$.0(``*&@;0D(OJ!M"0B%P'42Z;`#``"#Q@R+ +XM!H7`#X2C`P``BY7,]___B00DB50D!.@(E_S_A#W__^+0@2%P'0R +XMBS"%]G0LBXW<]___A+A#W__^+0@2)!"3HCHP``(D$).@RC_S_B<>+1@2%P'0RBP"% +XMP'0LBX7<]___A<`/AG*_/__BX78]___ +XMA<`/A+S\__\/OL*)1"0$QP0D=```$.BN#_W_Z:3\__^)]HV\)P````!5B>57 +XM5E.#[!R+10R+70C'!2!W"@@UT@@(B47LH:!M"0B%P`^$`P$``+Z@;0D(ZPV# +XMQ@R+!H7`#X3O````B5PD!(D$).C3DOS_AT!``"+%4QO"0@Q +XMP(72=`@QP(`Z``^5P(L5!&\)"*/DF`H(A=)T"H`Z`+@!````=12+%7!O"0@Q +XMP(72=`@QP(`Z``^5P*-X=PH(@\0<6UY?7<.+%8!O"0C'1?"`;PD(A=*)5>AU +XM)HE=#,=%"',``!"#Q!Q;7E]=Z4H._?^#1?`,BT7PBP"%P(E%Z'3:B5PD!(M] +XMZ(D\).BGD?S_AR)/"3H9(S\_XM5\(E""(L5K&\)"*&@ +XM;PD(@7WPI&\)"(D5=)D+"*/$F0L(=`V!??"8;PD(#X4Z____B54,Z!N"0B%P`^$6?[__X`X``^$ +XM4/[__XE$)`2)'"3H[)#\_X7`#Y3`#[;`"05H90D(Z3'^__^+=>RX6`<)"+D$ +XM````_(G'\Z8/A9@```"+1?#'0`@!````H91O"0B#/<1O"0@!BPV(;PD(HL"9 +XM"PBAN&\)"*+(EPH(&<#WT(/@`H7)#Y7""="!??"`;PD(HJR8"@AT#8%]\+QO +XM"0@/A77^__^AK&\)"(E%#*&@;PD(B44(@\0<6UY?7>GER?__N`$```#I'?[_ +XM_XE$)`2)'"3H.Y#\_X7`#Y3`#[;`HVAE"0CI&____XMU[+B1Y`@(N0,```#\ +XMB575E.#[!RA@)@*",=$)`S8"`D(QT0D"`$```#'1"0$!P```(D$).CB +XM;?W_B00DZ'IG``"A@)@*",=$)`QF!PD(QT0D"`(```#'1"0$!P```(D$).BU +XM;?W_B00DZ$UG``"A@)@*"(L=H&\)"(LUK&\)",=$)`P`"0D(QT0D"`,```#' +XM1"0$!P```(D$).A\;?W_B5PD"(ET)`2)!"3H#&<``(`]R)<*"``/A+`"``"A +XM@)@*",=$)`S,[@@(QT0D"`4```#'1"0$!P```(D$).@Z;?W_B00DZ*(6_O_' +XM1"0$,"H("(G'B00DZ'`._?^A@)@*",=$)`R$!PD(QT0D"`0```#'1"0$!P`` +XM`(D$).C[;/W_B7PD!(D$).B/9@``N$7)"`B`/<"9"P@`#X2"`@``B00DZ$46 +XM_O_'1"0$,"H("(G#B00DZ!,._?^A@)@*",=$)`R>!PD(QT0D"`<```#'1"0$ +XM!P```(D$).B>;/W_B5PD!(D$).@R9@``]@6LF`H(`0^$K`$``*&`F`H(QT0D +XM#+('"0C'1"0("@```,=$)`0'````B00DZ&!L_?^)!"3HR!7^_\=$)`0P*@@( +XMB<.)!"3HE@W]_Z&`F`H(QT0D#,0'"0C'1"0("0```,=$)`0'````B00DZ"%L +XM_?^)7"0$B00DZ+5E```/O@6LF`H(J`%T>*@"#X5]`0``H8"8"@C'1"0,M@<) +XM",=$)`@+````QT0D!`<```")!"3HW6O]_XD$).A%%?[_QT0D!#`J"`B)PXD$ +XM).@3#?W_H8"8"@C'1"0,W@<)",=$)`@,````QT0D!`<```")!"3HGFO]_XE< +XM)`2)!"3H,F4``(L=H&T)"(7;#X2/````,?:)]HN&J&T)"(7`=`6`.`!U):&` +XMF`H(QT0D#/0'"0C'1"0(#0```,=$)`0'````B00DZ$QK_?^)!"3HM!3^_\=$ +XM)`0P*@@(B<.)!"3H@@S]_XN&H&T)"(E<)`S'!"3\!PD(B40D"(N&I&T)"(E$ +XM)`3HKF0``(D<).BV"_W_BX:L;0D(@\8,A<`/A77____'!"0*````Z*DG_O^) +XM/"3HD0O]_X/$'%M>7UW#H8"8"@C'1"0,M@<)",=$)`@+````QT0D!`<```") +XM!"3HM&K]_^E/_O__H8"8"@C'1"0,D>0(",=$)`@&````QT0D!`<```")!"3H +XMBFK]_^E+_?__H8"8"@C'1"0,L@<)",=$)`@*````QT0D!`<```")!"3H8&K] +XM_^E^_O__H8"8"@C'1"0,F0<)",=$)`@(````QT0D!`<```")!"3H-FK]_^E4 +XM_?__D%6)Y8M%"%VBX&\)"+C@;PD(PXVT)@````"-O"<`````58GEBT4(78M0 +XM!(L`B17<;PD(H]AO"0BXV&\)",.-=@!5B>53B<.#[`3'!"08````Z'L6``"+ +XM$XL2QT`$_____\=`"`````")$,=`#`````#'0!``````QT`4`````(/$!%M= +XMPXVV`````(V_`````%6)Y5.)PX/L!(7`=$N+0!"%P'0,Z.?____'0Q`````` +XMBT,4Z-C___^+0P2#^/]\"87`?AR#^`)^#(VT)@````#HQXC\_XM#"(D$).@@ +XM%0``B1PDZ!@5``"#Q`1;7<.)]E6)Y5=6B=93@^P,B47PBSJ+&(L7.1.)V74( +XMZQF-="8`B<&+012%P'0W.Q!U\X/!%(G#B4WPC4<$B0:+1@2#Z`&%P(E&!'0J +XMBU,0A=)T$HU#$(GRZ*C___^#Z`%T#8UV`(/$##'`6UY?7<.+0Q"%P'7OBT,4 +XMBU7PB0*)V,=#%`````#H&?___X/$#+@!````6UY?7<.-M@````"-OP````!5 +XMB>6#["B+10B+4`2+`(72B57\B47X=!V+#=1O"0@QP(7)=`^-5?BXU&\)".@O +XM____,<#)P\=$)`PH"PD(QT0D"`,```#'1"0$"0```*&`F`H(B00DZ$9H_?^) +XM!"3HWF$``+C_____R<.-M"8`````58GEBTT,BU4(BP$/M@"`/!`U=`)=PX'Z +XMP*L+"'0:@?K`I`L(=>Z`N,"K"P@U=.6)30A=Z5C___^`N,"D"P@U=>[KVXVV +XM`````(V\)P````!5B>57B<=6B=93B?N#[!R)3?"+`HL0.1=U".L8C70F`(G# +XMBT,4A<`/A,L````[$)!U[HG'BT8$@P8$@^@!A<")1@1U+(M'$(7`=`SH\/W_ +XM_\='$`````"+1P2#^/]\"87`?D>#^`)^,.C?AOS_C78`BU\0A=L/A*0```"+ +XM50B+1Q")%"2+3?")\NAR____@\0<,7<.)V.@5_/__H]1O"0CI>___ +XM_XUT)@"-O"<`````58GE@^PHB5WTB<.)=?B)SHE]_(G7BQ*+`#L"=#.+0Q2% +XMP'04B?KHU?___XM=](MU^(M]_(GL7<.X`0```,____ZX>-M@`` +XM``"-OP````!5H=1O"0B)Y8M5"(M-#%WI//___XVV`````(V_`````%6)Y8/L +XM"*'4;PD(Z'#[___'!=1O"0@`````R>D0UO__58GE5U93@^P-=@"!^_\````/AS0!``"AX%T)"(M$F#3VQ`)T/X/[ +XM?\8&7@^$)P$``(G8@\A`B$8!@\8"BU4(@T7P`8M%\#E"!`^.DP```(M5"(L" +XMBU7PBQR0B=^!YP```$!TIX/[7@^$T````(/[7`^$QP```(/[((GV=#Z%_P^% +XMA@```('[_P````^'TP```*'@70D(BT28-*D```0`=&J!^_\````/A\@```"A +XMX%T)"(M$F#3VQ$!U4('C__\_`(DT)(E<)`3HKGP``(M5"(-%\`$!QHM%\#E" +XM!`^/;?___XM%#(L0A=)T#(M`!(7`=`6(!H/&`<8&`(M%[(/$'%M>7UW#C;8` +XM````B=C!^`:#X`>#P#"(1@&)V,'X`X/@!X/`,(A&`HG8@^`'@\`PQ@97UW#C70F`'Q3@_L"?TZ#ZP&X +XM:#T)")!T!;AT/0D(B30DB40D!.B-_?__QT0D!#`J"`B)PXD$).C+`_W_H4@- +XM"0B)7"0$B00DZ`I<``")70B#Q!Q;7E]=Z0L#_?_HPH'\_Z&`F`H(QT0D#.$+ +XM"0C'1"0(!P```,=$)`0)````B00DZ#%B_?^)10RA2`T)"(E%"(/$'%M>7UWI +XMNEL``(UV`(V\)P````!5B>6#["B+10B)??R)7?2)=?B+&(U3!(E5[(MS!(GW +XM@>?__S\`#X2"`0``BPN)R"7__S\`@_AQ=PXUT)@"!__\```!W-Z'@70D(BT2X-/;$`70S@_\_ +XMQT7P?P```'3"@>:?````B77PZ[>-=@"-1]"#^$9W\/\DA2P,"0B)/"3HU7_\ +XM_^O(B7PD!,<$)`4,"0CH@X'\_X7`=;GK@L=%\`L```#I>?___\=%\`D```#I +XM;?___\=%\`T```")]NE?____QT7P"@```(UT)@#I3____\=%\`P```"-="8` +XMZ3_____'1?`;````C70F`.DO____QT7P"````(UT)@#I'____\=%\`<```"- +XM="8`Z0_____'1?!<````C70F`.G__O__BUWL,=(QR8/#!(/X!P^'T@```(M- +XM[(G"BT$$B6#[!B%THE=](G3B77XB<:)??P/A.@```")UX'G````0'4>@?K_ +XM````#X=0`0``H>!="0B+1)`T]L0"#X7B````@_M>#X1"`0``@_M<#X0'`0`` +XM@_L@=#Z%_XUT)@!U1('[_P````^'X0```*'@70D(BT28-*D```0`="B!^_\` +XM```/ARD!``"AX%T)"(M$F#3VQ$!U#HE<)`2)-"3H7',``.M0QT0D!%P```") +XM-"3H2G,``(G8P?@&@^`'@\`PB40D!(DT).@S#P#") +XM1"0$B30DZ!ES``"-0S")1"0$B30DZ`IS``"+7?2+=?B+??R)[%W#QT0D!%X` +XM``")!"3H[7(``,=$)`1`````B30DZ-UR``#KT<=$)`1>````B30DZ,MR``"# +XM^W\/A(<```"#RT")7"0$B30DZ+-R``#KIXD<).CE?/S_Z1O____'1"0$7``` +XM`(DT).B4<@``QT0D!%P```")-"3HA'(``.EU____B10DZ+-\_/_IK/[__\=$ +XM)`1<````B30DZ&)R``#'1"0$7@```(DT).A2<@``Z4/___^)'"3H@7S\_Y"- +XM="8`Z<[^___'1"0$/P```(DT).@K<@``Z1S___^-M@````!5B>6#[!B%THE= +XM](G3B77XB<:)??QT.8L2BW@$Z/_]__^+4Q"%TG0XB?#HT?___XM#%(7`=!J) +XM?@2+4Q2)\(M=](MU^(M]_(GL7>NTC70F`(M=](MU^(M]_(GL7<.-=@#'1"0$ +XM(@```(DT).BP<0``B30DZ`AR``"+0P2)1"0(C4,(B40D!(L&B00DZ##Z___K +XMG8VT)@````"-O"<`````58GE@^PHAR+2Q"#P`2)1>R+1@2#Z`&) +XM1?")^.BL____BUWTBW7XBWW\B>Q=PXGXB''1"0$(@```(D\).CA<```B3PDZ#EQ +XM``"+0P2)1"0(C4,(B40D!(L'B00DZ&'Y__\QP.N1C;8`````C;PG`````%6) +XMY593@^PPBU4(QT7D`````,=%Z`````#'1>P`````A=)T;(L"B47PBT($B47T +XMH=1O"0B%P'1(C77DQT0D!"(```")-"3H97```,=$)`2PD0@(B30DZ'7]_/^+ +XM#=1O"0B-5?")\.C%_O__@\`!?C")-"3HN/S\_X/$,%M>7<.0BT7TA7<.)]L=%\/AO"0C'1?0`````ZX^A@)@*"(M=\,=$)`P0#`D(QT0D"`0` +XM``#'1"0$"0```(D$).BX6_W_B5PD!(D$).A,50``ZYJ0D)"0D)"0D)"058GE +XMBT4(BU4,#[9(&(@*#[9(&8A*`0^V2!.(2@(/MD@5B$H##[9($(A*!`^V2!&( +XM2@4/MD@2B$H&#[9(%XA*"0^V2!R(2@H/MD@=B$H+#[9(%(A*#`^V2!J(2@T/ +XMMD@;B$H.#[9(%HA*#P^V2!^(2A`/MD@>B$H1#[9((HA*$@^V2""(2A#[9($HA*(@^V +XM2!>(2B`/MD`8B$(A7<.058GEBT4(78M`!(/P!,'H`H/@`<.-M@````"-OP`` +XM``!5B>6+10A=BT`()0`#```]``,```^4P`^VP,.0C70F`%6)Y8M%"%V+0`PE +XM``$``,-5B>53@^P$BUT(B1PDZ-IY_/^%P'0*@\0$6UW#C70F`(E="(/$!%M= +XMZ;][_/^-=@!5B>564X/L$(MU"(M=#.L*Z$=[_/^#."-U(HE<)`C'1"0$`0`` +XM`(DT).C2^OW_@\`!=-TQP(/$$%M>77`P``BU7@`````QT7L`````(E5S(E%R.MMNRT```"_`0```,9%TP&+5>R+LD`/"0B) +XM-"3HD7S\_XU\!P$!?>2+1>0[!>"7"@@/C<`"``"`?=,`#X2A`@``#[[#B70D +XM"(E$)`3'!"1E#0D(Z$Y1``"+5>R+@DP/"0B#P@R)5>R%P`^$P0(``(M5[(N" +XM2`\)"#M%X'1=C11`BT7(*T7,@WW@_XN$D$`M"0BZ`;H("`^$B@(``(E$)`B) +XM5"0$QP0D6PT)".CV4```BT7LBU7(*U7,BX!(#PD(B47@C01`BX2"0"T)"(D$ +XM).C>>_S_B47DB47HBU7LBT7@BXI$#PD(C11`BT7(*T7,C120B<@C@D0M"0B# +XM^`$9V_?3@^,KA8I(+0D(#X7R_O__A-L/E473=0N+1=B%P`^$-?___P^V?=/I +XMY/[__X/&!,=%W`(```#I+/[__X/&!,=%W`$```#I'?[__X-%V`&#Q@3I$?[_ +XM_\=%V`````#'1=P`````QP7H;PD(`0```(L6A=(/A$S^__^+1=R-?@3!X`*) +XM1<2+1=S!X`:)1<"+`H/X*P^$FP```(/X+<9%\P`/A(X```")%"2[0`\)".B$ +XM<```B<:A0`\)"(7`=1+K?XVT)@````"#PPR+`X7`=&^)="0$B00DZ`=X_/^% +XMP'7G@'WS*P^$F````(!]\RT/A,@```"+0PB+5<"+2P0K5<2-!$"-!(+WT2&( +XM1"T)""&(2"T)"(7_#X2.````BQ>%T@^$A````(L"@\<$@_@K#X5E____@\($ +XMB$7SZ6?___^A@)@*",=$)`QK#0D(QT0D"`(```#'1"0$"````(D$).BC5?W_ +XMB70D!,<$)#8``!")1"0(Z._S_/^`??,K#X5H____BT,(BU7`*U7$BTL$C01` +XMC02""8A$+0D(]]$AB$@M"0B%_P^%7UWI^_7\_XM# +XM"(M+!(M5P"M5Q(T$0(T$@HG*]]()B$@M"0@AD$0M"0CI,?___XET)`3'!"1G +XM#0D(Z+1.``#I8?W__\=$)`A%R0@(BU7HQP0D8`T)"(E4)`3HE$X``(M%[`-] +XMZ(E]Y(NP0`\)".D1_?__ND7)"`CI;/W__\<$)`H```#HBA'^_XM%U(E%"(/$ +XM3%M>7UWI:/7\_\=%V`````#'1=P`````Z5G\__^0D)"0D%6)Y8/L&,<$)``` +XM``")7?B)=?SHY';\_XLU]&\)",=$)`Q\$@D(QT0D"`P```#'1"0$$P```(G# +XMH_!O"0BA@)@*"(D$).A65/W_B=HI\HE<)`B)="0$B50D#(D$).C>30``BUWX +XMBW7\B>Q=PXUT)@!5B>6+10B%P'0)H>QO"0B%P'0"7<-=Z7%X_/^0C70F`%6X +XM`@```(GE@^P8BQ7H=@H(A=)U!:$$=@H(QT0D"`X```#'1"0$J1()"(D$).CJ +XM6#[!B)=?R+=0P/KW4(B5WXA?9U!&:^`0"+ +XM#?1O"0B%R70UB30DZ$]W_/^%P(G#="")="0(B1PDQT0D!`````#H=73\_XG8 +XMBW7\BUWXB>Q=P^AH____Z]G'!"0`````Z,9U_/^C]&\)".NXC78`58GE4X/L +XM!(M="(7;=0*S`:'T;PD(A6#[!B)7?B+70R)=?R+ +XM=0B%VW4"LP&A]&\)"(7`=$&%]G0>B5PD!(DT).@K;HJO[__XG8BW7\BUWXB>Q=P\<$)`````#H +XM_G3\_Z/T;PD(ZZR0D)"0D)"0D)"0D%6)Y8/L&*&`F`H(QT0D#+@2"0C'1"0( +XM#````,=$)`04````B00DZ&52_?^)!"3H_4L``*&`F`H(QT0D#.@2"0C'1"0( +XM#0```,=$)`04````B00DZ#A2_?^)!"3HT$L``*&`F`H(QT0D#!P3"0C'1"0( +XM#@```,=$)`04````B00DZ`M2_?^)!"3HHTL``*&`F`H(QT0D#%03"0C'1"0( +XM#P```,=$)`04````B00DZ-Y1_?^)!"3H=DL``*&`F`H(QT0D#)03"0C'1"0( +XM$````,=$)`04````B00DZ+%1_?^)!"3H24L``*&`F`H(QT0D#-03"0C'1"0( +XM$0```,=$)`04````B00DZ(11_?^)!"3H'$L``*&`F`H(QT0D#/P3"0C'1"0( +XM$@```,=$)`04````B00DZ%=1_?^)!"3H[TH``*&`F`H(QT0D#"@4"0C'1"0( +XM$P```,=$)`04````B00DZ"I1_?^)!"3HPDH``*&`F`H(QT0D#&`4"0C'1"0( +XM%````,=$)`04````B00DZ/U0_?^)!"3HE4H``*&`F`H(QT0D#)04"0C'1"0( +XM%0```,=$)`04````B00DZ-!0_?^)!"3H:$H``*&`F`H(QT0D#+04"0C'1"0( +XM%@```,=$)`04````B00DZ*-0_?^)!"3H.TH``*&`F`H(QT0D#.P4"0C'1"0( +XM%P```,=$)`04````B00DZ'90_?^)!"3H#DH``*&`F`H(QT0D#!P5"0C'1"0( +XM&````,=$)`04````B00DZ$E0_?^)!"3HX4D``,<$)`&Z"`CHU4D``*&`F`H( +XMQT0D#$P5"0C'1"0(&0```,=$)`04````B00DZ!!0_?^)!"3HJ$D``*&`F`H( +XMQT0D#'P5"0C'1"0(&@```,=$)`04````B00DZ.-/_?^)!"3H>TD``,G#B?:- +XMO"<`````58GE4XG#@^P4H8"8"@C'1"0,T!4)",=$)`@$````QT0D!!0```") +XM!"3HHD_]_XE<)`2)!"3H-DD``(/$%%M=PU6)Y5=64XG3@^P\B470C47LB47< +XMC47DB57LB4W,B474C47`!````QT78`0`` +XM`,=$)`1H/0D(B00DZ#[J___'1"0$,"H("(G'B00DZ'SP_/^+1=`/MA08@/H! +XM#X3O````H>"E"PB%P'0E#[;2ON"E"P@Y%>2E"PAT?K[@I0L(ZP4Y5@1T57B==6B<93@^PLQT7D```` +XM`,=%Z`````#'1>P`````BP"%P`^$L0```(U=Y,=$)`2PD0@(B1PDZ+'N_/^) +XM=?"+!H7`=%.-=?#K(XUV`(/X7G0EB40D!(D<).AO80``BT7P@\`$B47PBP"% +XMP'0K)?__/P"#^%QUUHDT).@.Z___@_C_=2)!"3H +XMQ?G__XD'BT7HB4<$@\0LB?A;7E]=PZ&`F`H(,?_'1"0,018)",=$)`@%```` +XMQT0D!!0```")!"3HG$S]_XD$).@T1@``@\0LB?A;7E]=PXUV`(V\)P````!5 +XMB>575E.#[%RA/&0)"(M]"(7`#X2+````C4<$B46TBU\$A=L/A,T#``"+`R7_ +XM_S\`@_@M#X6U`@``BT,$)?__/P"#^"T/A'T#``"-5PBY`0```,=%O,"K"PC' +XM1<``````QT7$`````,=%R`````#'1 +XM7UW#D(UT)@#_)(48%PD(Z`1'__^#Q%Q;7E]=P^CW2/__Z6O____'1<`"```` +XMBQJ#P0&)UH7;#X0S`P``BP,E__\_`(/X+0^%T@(``(M#!(U6!"7__S\`@_@M +XM=9*-40&-!)4`````C30'BQZ%VP^$_`(``(/"`8E5T(M%R(7`#X4=`@``BTW, +XMA*?````C478B50D!(D$).C\7@``C478B00DZ,'K_/^-5=B) +XM%"3H9NO\_XU-V(D,).@[7P``BT7<@\`!P>`"B40D!(M%V(D$).B#]___B47L +XMBT7R)!"3HQ^O\_XM%[(L0@?K_````B56X#X]T`0`` +XMBT7$A<`/A#(!``"+?R)!"3HF.'__XM% +XM[(D$).C=ZOS_Z2O^___'1<@!````D.E0_O__QT7$`0```(UT)@#I0/[__\=% +XMP`$```"-="8`Z3#^___H1D?__X/$7%M>7UW#QT6\P*0+".D7_O__QT7,`0`` +XM`.D+_O__BQ7@I0L(,=N%T@^$R?W__XVV`````(N#Z*4+"(E4)`3'!"1<%@D( +XMB40D".A&0P``BY/LI0L(@\,,A=)UV8/$7%M>7UW#QT6\P*L+",=%P`````#' +XM1<0`````QT7(`````,=%T`(```"-5>R)V.C$^___A<`/A=+^___I6OW__XD< +XM)(UT)@#HJ\3__X7`#X3:`@``BP:)!"3H26$``(E%[(D$).@::/S_B47PZ9S^ +XM__^+3="+1="+-(_!X`*%]@^$H`,``(M5M(L<`H7;#X3C`@``Z&_V__^+1>R) +XM!"3HI.G\_^GR_/__Z!KY__^+1>R)!"3HC^G\_^G=_/__@\$!B4W0Z5#]__^) +XMV.CX^/__C478B00DZ&WI_/_IN_S__[H"````L`C'1;S`JPL(QT7``````,=% +XMQ`````#'1<@`````QT7,`````.GW_/__H8"8"@@QV\=%V`````#'1=P````` +XMQT0D#&T6"0C'1"0(!@```,=$)`04````B00DZ%1(_?^)!"3H[$$``#'2#[:" +XMP*L+"#J#P*L+"'0/C4O_N,"K"PCHGOC__XG:@\,!@?L``0``==>Y_P```+C` +XMJPL(Z(+X__^A@)@*"&8QV\=$)`R$%@D(QT0D"`<```#'1"0$%````(D$).CJ +XM1_W_B00DZ()!```QT@^V@L"D"P@Z@\"D"PAT#XU+_[C`I`L(Z#3X__^)VH/# +XM`8'[``$``'77N?\```"XP*0+".@8^/__H8"8"@C'1"0,GA8)",=$)`@(```` +XMQT0D!!0```")!"3H@T?]_XD$).@;00``QP0D`````.COZO__H8"8"@C'1"0, +XMN!8)",=$)`@)````QT0D!!0```")!"3H2D?]_XD$).CB0```C478B00DZ$?# +XM___I-?O__X-[!"T/A5G^__^+0PB-@,``(U%V(D$),=$)`0;````Z.E:``"+!HU5V(D4 +XM)(E$)`3HV%H``.G7^___C578QT0D!!L```")%"3HP%H``(U-V(ET)`2)#"3H +XM(5T``.FP^___@_@_NG\````/A8O[___ICOO__Z&`F`H(BQ['1"0,S!8)",=$ +XM)`@!````QT0D!!0```")!"3H0D;]_XE<)`2)!"3HUC\``.GN_/__C47LB00D +XMZ";!___IZ?O__X-]P``/A>X```"+'>"E"PB_X*4+"(7;=17I?0$``(UV`(/' +XM#(L?A=L/A&T!``")-"3H&V```(E<)`2)!"3HNV?\_X7`==L/ME\$A-L/A)?[ +XM__^+5<@/ML.%T@^%A0(``(-]\`$/CJH"``")!"3H?]O__\=$)`@`````B40D +XM!(U%[(D$).CHWO__BT6\BU6XQ@00->E1^___BUV\`UVX@#LU#X0J`0``Q@,! +XMZ3K[__^+=R)!"3HS^C__^D2^___ +XMC4W8B70D!(D,).AK60``Z6KZ__^)-"3HFF/\_^D'^O__#XP;_O__@WW``@^/ +XM$?[__XU=Y(GPB=KH;??__X7`#X3-^O__QT0D!#`J"`B+1>2)!"3H0N;\_XM- +XMR(7)#X2L````B1PDZ,_:__^+3<")3"0(B40D!(U%[(D$).AIP/__@\`!#X0U +XM`0``BT7DB00DZ+7E_/^+5;R+3;C&!`HUBT7LB00DZ%#E_/_HV[C__^F9^/__ +XMC47LB00DZ)O`___I3OK__Z&`F`H(QT0D#/\6"0C'1"0(`P```,=$)`04```` +XMB00DZ&%$_?^)="0$B00DZ/4]``#I&/K__XU%[(D$).BEV___Q@,!B?;I`_K_ +XM_XD<).@CVO__BU7`B50D"(E$)`2-1>R)!"3H;=W__XM%N(M-O,8$`36+1>R) +XM!"3HN.3\_^D&^/__C47LQT0D!&@]"0B)!"3H\-[__\=$)`0P*@@(B<:)!"3H +XM+N7\_XL5X*4+"(72=#LQV^L-BY/LI0L(@\,,A=)T*HM%[(M-O(L`#[8$"#F# +XMY*4+"'7?B50D"(ET)`3'!"3C%@D(Z#L]``#KR8DT).A!Y/S_D.E3^?__H8"8 +XM"@B+7>S'1"0,[18)",=$)`@"````QT0D!!0```")!"3H8T/]_XE<)`2)!"3H +XM]SP``.F=_O__#("-3=B)1"0$B0PDZ'%7``#IR)!"3HPN/\_^EM_O__C47LB40D!(M-O(D, +XM).C+VO__BT6\BU6XB!P0Z;7X__^0D)"0D)"0D)"0D)"053'`B>5=PXGVC;PG +XM`````%4QP(GE7<<%_&\)"`````##D)"0D)"0D)"0D)"0D)"058M*"(GEB5`$ +XMB4@(B4((BU`(B4($7<.)]HV\)P````!5B>56B=93BPB)TX7)="60BQ.%TG0> +XM.=%T/(VV`````(/Y('0;@\`$BPB%R77RA_/^) +XMP^EX____C;8`````58GE5U93@>P<(0``C46TC5VLQT74`````,=%V`````#' +XM1=P`````QT6L`````(D$).AF9/S_QT6P`````,=$)`@`````B5PD!,<$)!0` +XM``#H1V/\_XU%X(D$).B`*O[_Z(=?_/^%P(G'#X4V`0``BT7@C5W$B00DZ*/D +XM_?_'1"0$H$$(",<$)`X```#H>V/\_XD<).@#9/S_B1PDQT0D!`X```#H`U_\ +XM_XE<)`2-G0S____'1"0(`````,<$)`(```#HE5[\_\<$)`(```#HZ6/\_XM% +XMY,=%[(````")7"0$B84`W___C47LB40D"*&T=@H(B00DZ/%A_/^#P`%T%P^V +XMA0W___\\'`^$H@$``#P"#X2:`0``Z*1G``"%P(G&='(/M@"$P'1K/#IT9\=$ +XM)`0Z````B30DZ$]@_/^%P(G#=`/&``")-"2)]^@\8?S_@\`!#X2E`0``B3PD +XMZ*MD_/^%P(G#=0OK*XVT)@`````!QXN%`-___XE<)`B)?"0$B00DZ(C@_?^% +XMP`^(8@$``"G#==S'!"0`````D(UT)@#H-V/\_XM%Y(V=#-___XD$).AJX_W_ +XMZQN%P`^$KP```(E$)`B-1=2)7"0$B00DZ%U6``"+1>#'1"0(`"```(E<)`2) +XM!"3HQN#]_X/X_W7)QT78`````,>%_-[__P$```"+1>"-=?")!"3H$N/]_^L5 +XMZ*=@_/^#.`1U*(VV`````.B[4```BX7\WO__B70D!(D\)(E$)`CH@5W\_X/X +XM_XG#=,Z-1=3'1"0$T)$("(D$).A;X/S_.=]T(HU%U(D$).BLW_S_@<0<(0`` +XM6UY?7__\`````ZX6+1?"H?W77P?@(AR_('`)",=$)!@"````QT0D +XM%`````#'1"00`````,=$)`P!!```QT0D""!P"0B)1"0$B1PDZ#]@_/_I9_[_ +XM_\<$)`$```#HWF'\_SG>#X2._O__C46,N0@```")A?C>__^+O?C>__\QP/S' +XM1>@`````\ZO'19``````QT64`0```,=%C`,```")-"3HR6+\_XG#Z(9>```Y +XMPP^#K0```(U%Z(E$)`R-18R)1"0(QT0D!`````")-"3H+&/\_X7`=$C'1>@` +XM````Z13^__^)1"0$B30DZ*3F_?_'1"0$`````(G#C47HB40D#(U%C(E$)`B) +XM'"3H\&+\_XD<)(/X`1G`(47HZ'3I__^+1>B%P`^$S?W__XM0%(72#X2R```` +XMB50D!+\@<`D(QT0D"`$$``#'!"0@<`D(Z&U=_/^+1>B)!"3H\F#\_^E:_?__ +XMC9T,W___QT0D!``!``")'"3H5V'\_X7`=:/&A0O@__\`QT0D!"X```")'"3H +XM7%W\_X7`B<=TAL=$)`0N````B30DZ$9=_/^%P`^$;O___X!X`0"-6`%T%(E$ +XM)`2)/"3HJ5[\_X7`#X45____QT0D!"X```")'"3H$5W\_X7`=<_I./___XD$ +XM).A@8/S_C70F`.G__/__C70F`(V\)P````!5B>6#[`C'!"0!````Z"I@_/^- +XMM"8`````C;PG`````%6)Y8/L&(M%"(E=](EU^(E]_(D$).BV5@``B00DZ.[E +XM_?^)QHM%#(D$).BA5@``B00DZ-GE_?^)P^B^7?S_QP``````B5PD!(DT).B< +XM7/S_BQ= +XMPY"-="8`B30DZ.CG__^)'"3HX.?__^AG7?S_BP")!"3H#5O\_\=$)`1(&`D( +XMQP0D-@```(E$)`CH2=K\_^NCC;0F`````%6)Y8/L&(M%#(/X!`^$@````(/X +XM(W0,@\`!=`?)N/_____#QT4,`````,=$)`@`````QT0D!`,```"+10B)!"3H +XM=UG\_X/X_W32@^#[B44,B40D",=$)`0$````BT4(B00DZ%59_/^#P`%TL(U% +XM#,=%#`````")1"0(QT0D!'YF!("+10B)!"3H'UK\_X/``72*R3'`PXUV`(V\ +XM)P````!5B>575E.#[!R+70B%VP^$U````(M%"(L`B47LQT0D!,28"@C'!"20 +XM+PD(Z,!#_O\]^&\)"(G#="&)!"3HZUG\_XE<)`2)1"0(BU7LB<:)%"3HAEO\ +XM_X7`=&NA`'`)"(7`B47P=%6+'21T"0@Q_XGVBW,(B70D"(M#!(E$)`2+1>R) +XM!"3H4UO\_X7`=2.+1>R-%+"+`H/X+W0$A7UW#BPT`<`D(A575E.#[!R+50B+`H/X*P^$I@```(/X+0^$G0```(L= +XM)'0)"(7;#X1F`0``H0!P"0B+-21T"0B-!$"-/(8Y_G-CBT4(BP")1?#K#HUV +XM`(7`>$R-7UW#C78`B=\Y_G*UBT4( +XMB00DZ(]1``")!"3HY]G]_X7`=1+'1>P`````BT7L@\0<6UY?7<.+0!R)!"3H +XMEE,``(D$).@^3P``A<")1>QTVXL=`'`)"(M5"(T<6\'C`HD4)`,=)'0)".@: +XM3P``B0.A`'`)"(M5[(L])'0)"(T$0(E4AP2+-0!P"0B)%"3HT57\_XT<=H/& +XM`<'C`HE$.PB)-0!P"0C'1"0,,$8(",=$)`@,````B70D!(D\).A"5/S_H0!P +XM"0@[!9A-"0@/A5G___^#P`JCF$T)"(T$0,'@`HE$)`2A)'0)"(D$).AVX___ +XMHR1T"0CI,/___\<$)'@```#H$./__Z,D=`D(Z83^__^-M@````!5B>575E.# +XM["S'1"0$Q)@*",<$)"`^"0CH\S[^_XE%W,=$)`3$F`H(QP0D8#X)".C#H4_/__PG#B47D="R+'0"8"@B%VW0B +XMB?:+0WB)-"2)1"0$Z#'6_?^%P'0'BT,4A+!H/X.W01.7T(=-^+ +XM?PB+-XL&@_@[=>^+?P@Y?0AUUX/$+%M>7UW#QP0DF#X)".@]5/S_B47HBP>) +XM!"3H,%3\_XE%[(T$A00```")1"0$QP0D`0```.A:X?__B47PBP>)1"0$BU7P +XMB10DZ`)3_/^+=>2%]@^$,P(``(L'B00DZ-'@___'1"0$%````,<$)`$```#H +XM'>'__XD'QT0D!(`R"0B)!"3HQU+\_\=$)`0,````QP0D`0```.CWX/__QT0D +XM!!@```#'!"0!````B<;HX>#__XD&QT0D!+0^"0B)!"3HBU+\_XGPB?KHYO'_ +XM_XL&BP"#^`IT$8/X.W0,BW8(BP:+`(/X"G7OQT0D!`P```#'!"0!````Z)C@ +XM___'1"0$"````,<$)`$```")P^B"X/__B0/'1"0$P#T)"(D$).@L4OS_BU8$ +XMB=CHAO'__\=$)`0,````QP0D`0```.A2X/__QT0D!`@```#'!"0!````B) +XM!"3HGM[__XM5[,<$)`$```"-!)4(````B40D!.CDWO__B0?'`"4```"+1?") +XM1"0$BP>#P`2)!"3HA%#\_XM?"(L+BP&#^#L/E<*#^`IT>X32='V#Q"Q;7E]=PXG?Z6'\__^-="8`58GE5U93@^P\QT0D +XM!,28"@C'!"3D2`D(Z#,Z_O^%P`^$[````(M%"(MX"(L'@S@[#X3C````.7T( +XM#X32````QT78`````,=%W`````#'1"0$`$D)"(L'B00DZ-U/_/^%P`^%XP$` +XM`(M7"(E5U(L2BP*#^"V)1>`/A+$```"#?>`MBW74#X3Z````BT78A`[#X2/`0``BWW4.7T(#X2#`0``BW\(BP>+`(/X.XE%X'08 +XM.7T(#X1N`0``BW\(BP>+`(/X.XE%X'7HBW\(.7T(#X4\____@\0\6UY?7<,Y +XM?0AT\XM_"(L'@S@[#X4*____Z^N+3=R%R0^%1/___XMUU(M%W(M*!(7`#Y3` +XMA)TX/Y:0^4PH/Y9HM+"`^4P`G0@^`!B47<#Y3`@\,$A"#?>`[#X5Q_O__BWW4@WW@.P^%FO[__^F2_O__A,`/A=;^__^0C70F`.GQ +XM_O__BP>+`(/X"G1Z@_@[='4Y?0AT<(G[ZPV#^#N0=#LY=0AT+XGSBU,$BT,( +XMB4((BT,(B5`$BP.)!"3H#MO__XMS"(D<).@#V___BPZ+`8/X"G7&@_@[=2:+ +XM#HM6!(M&"(E""(M&"(E0!(D,).C7<,YUG;CZ]20C70F`#'VZYS'!2AT"0C04`@(BQ.)QHM"!(7` +XM#X5/____ZX&0A?8/A'C___\IQHVV`````.EK____B<;'!2AT"0A040@(Z5K_ +XM__^-=@"-O"<`````58GE@^P(_Q4H=`D(QP0D`0```.BH_O__R<.-M@````!5 +XMB>6#[!C'!"16&`D(Z!XG``"AY)D+"(7`=`7H\$___Z&T=@H(B00DZ"/1_?_' +XM1"0(`@```,=$)`1@+@D(QP0D`"X)".CG/O[_QT0D!`````#'!"0`````QP7D +XM=0D(`0```,<%A'<*"`````#HGVW\_\G#C;8`````C;PG`````%6)Y5=64X/L +XM?*$LF0L(B00DZ#K/_?^%P(E%D`^$PP$``(MX!(7_#X2X`0``QP0D`````(UU +XM\^CE_?__QP0D"@```.B)Z?W_QT6,`````,=%M`$```"-1;R)!"3H[$_\_XU% +XMG,=%N`````")1"0(C46TB40D!,<$)`(```#HRT[\_XU%S(D$).C`3_S_C47, +XMQT0D!`(```")!"3HO4K\_XU%W(E$)`B-1!0CHE,W\_XU%W(D$),=$)`1@'@4(Z('-_/_HK$___\=$)`0" +XM````QP0D8Q@)".BXS?W_B47L@\`!#X7M````H;1V"@B)1>S'1"0$;!@)",<$ +XM)/O>"`CHD"4``.A[YOW_QP4P=`D(`````.L;#[9%\SP*="X/OL")1"0$QP0D +XM+'0)".C$0```QT0D"`$```")="0$BT7LB00DZ/W,_?^%P'_*QP0D+'0)".C] +XM0```C46TB00DZ$+,_/^+'2QT"0B)?"0$B1PDZ,Q,_/^)?"0$B00DZ%!-_/^% +XMP'1IBT60BQBA@)@*",=$)`QV&`D(QT0D"`(```#'1"0$%@```(D$).A&*_W_ +XMB5PD!(D$).C:)```@T6,`8-]C`4/A6K^___HE_W__X/$?%M>7UW#C47LQT0D +XM!$`>!0B)!"3H7,S\_^D#____B1PDZ*M/_/_'1"0$`````(D<)(E$)`CHUTO\ +XM_Z&$=PH(A2A*)H+"(E%X*$DF@L(B47"0B%P'02B00DZ/?5___'!8!>"0@`````QT7L^&\)",=$)`0,````QP0D +XM`0```.@RUO__B<:+10R)!"3H!4(``(D&@WT(`0^$``(``,=$)`0,````QP0D +XM`0```.@%UO__B<.+11")!"3HV$$``(ES!(EU](E=\(E>"(D#C47LB4,(B48$ +XMC5WLQT0D!)#I!0B)'"3H[LK\_\=$)`3$F`H(QP0D]"X)".@Z,O[_B00DZ$(P +XM_O^)'"2)1;#HA^/]_XM%],=$)`@`````B5PD!(D$).@`X/W_QT0D!$`K!@B) +XM1:R)!"3HGR)!"3HX\C\_^@^[_W_BT6PB00DZ',Q_O_'1"0(`@`` +XM`,<$)/0N"0B)1"0$Z&LY_O^#Q&!;7EW#C70F`.@K!```Z[OH!`4``*$\=`D( +XMAOIC47LB77PB77TB48$B48(Z23^__^0C70F`%6)Y8/L&(E=^(EU_(MU +XM"(,%Q*P+"`''1"0$L)`(",<$),2L"PCH]LC\_XL=0'0)"(7;=3.+#>"9"PC' +XM!4!T"0@!````AQ=Z1G(_/_' +XM1"0(U#<)",=$)`2`-PD(QP0D`@```.BM_/__QT0D#/08"0C'1"0(#@```,=$ +XM)`06````H8"8"@B)!"3H*"?]_XD$).C`(```ZY;'1"0$E'8*",<$)-0W"0CH +XM6B_^_X7`#X1Z____BQV`=PH(B70D",=$)`34-PD(QP0D`@```.A$_/__B1V` +XM=PH(Z5'___^)]HV\)P````!5B>53@^PDQT0D!+"0"`B#!<2L"P@!QP0DQ*P+ +XM".C^Q_S_H41T"0B%P'4UH>"9"PC'!41T"0@!````A"9"PC'!4QT"0@!````A6#[!C'1"0$L)`("(,%Q*P+"`''!"3$ +XMK`L(Z/_$_/^+#3QT"0B%R74LBQ7@F0L(QP4\=`D(`0```(72=&/'!"3$K`L( +XMQP4\=`D(`````.@KQ/S_R"+%0B:"PB)1=RA!)H+"(E5V(L5`)H+"(E%U*&$=PH( +XMB570BQ7`F`H(QP6$=PH(`````(E%R(E5Q.@MO_S_QP0D`)H+"(E%S.C*0/S_ +XMA<`/A)P```#'!"0!````Z&KR__^+52)%1B: +XM"PB+5>"C%)H+"(M%W(D5$)H+"(M5V*,,F@L(BT74B14(F@L(BU70HP2:"PB+ +XM1<2)%0":"PB+5?]_\<$)`````#H%43\ +XM_XM%",<%R*P+"`$```#'1"0$`0```(D$).@L\/W_A,<$)(0` +XM``")1"0$Z+6^_/_KNXUV`%6)Y8/L6(U%Z(E%Y(U5W(E%U(M%"(EU^(UUT(E= +XM](E]_(M]#(E5V(EU\(EUX(E5[,=%T/AO"0C'1>CH10D(QT0D!)1V"@B)!"3H +XM4BC^_X7`B<-T+(L`A564X/L$*%@90D(BUT(AB7E/__BT,$B00DZ/PX``") +XM!"3H-,C]_\=$)`0P*@@(B<:)!"3H`L#\_XM#"(D$).C7.```B00DZ`_(_?_' +XM1"0$,"H("(G#B00DZ-V__/^)7"0$B30DZ$&M__^)=0B#Q!!;7EWI([_\_XUV +XM`%6)Y5.#[`2A8&4)"(M="(7`=07H&)3__XU#!(E%"(/$!%M=Z=BE__^0C;0F +XM`````%6)Y8/L"*%@90D(ACLD___R>D6L/__C;8`````58GE5U93@>R< +XM````BT4(C5`$BT`$A<`/A(@%``")%"3HNVO]_XE%@(D$),=$)`3P(P8(Z#B_ +XM_/^+58"+`H7`="*#."T/A*T"``")T.L.B?:#P`2#.BT/A)L"``"+4`2%TG7M +XMQT7H`````(U-Z,=%[`````#'1?``````QT0D!+"1"`B)#"3HY;[\_XM%@(L0 +XMA=(/A`0&```Q_\>%=/___P````#'A7C___\!````ZV>)-"3HF#<``(U5B(E4 +XM)`2)!"3H)3[\_X/``0^$L@$```^W19"+G7C___\E`/```#T`0```#X2````` +XMB30DZ-Z]_/^+C73___^+18"+5(@$@\$!@X5X____`8F-=/___X72#X0Q!``` +XM,<"#/=B7"@@"B10D#Y3`B40D!.C1COS_QT0D!#`J"`B)QHD$).@OOOS_B30D +XMZ,/POC5#\#X5:____.=8/A%+____'0/P`````Z4;___\YO73___]T +XM,H7_#X4:!```QT0D#`````"+A73___\I^(E$)`B+58#'!"3X;PD(C02ZB40D +XM!.BL;?[_BY5T____A=)T%HM-@(M!!(7`=`S'!"0*````Z!S9_?^)="0$QP0D +XMJQ@)".CL%0``QT7L`````(L&AB+1>R#Z@2-!(*!."\``$`/A,@```"- +XM3>C'1"0$+P```(D,).@9,```C47HB00DZ&XP``"-5>C'1"04`````,=$)!#X +XM;PD(QT0D#`````#'1"0(_P\``,=$)`0`````B10DZ#N._O^+O7C___^)^^EH +XM_O__Z/4\_/\YO73___^+&'0RA?\/A7\#``#'1"0,`````(N%=/___RGXB40D +XM"(M-@,<$)/AO"0B-!+F)1"0$Z(UL_O^)'"3H83K\_XET)`3'!"2B&`D(B40D +XM".CA%```B[UX____B?OI_OW__\<`+P```.E+____H91W"@B%P`^%)0,``*&` +XM7@D(AB)4`B)1>R)%"3'1"0$D.D% +XM".C/NOS_C47HQT0D"`````")1"0$BT7PB00DZ`70_?_'1"0$0"L&"(G#B00D +XMZ*.Z_/^+-8!>"0B%]G0,QP0D````0.B=M_S_BQ74EPH(,<#'1"00`````,=$ +XM)`P`````QT0D"`````"%T@^?P(/H`0G"B50D!(D<).A7!/[_C57HB10DZ*RY +XM_/^+#91W"@B%R0^%2`$``(M%@(D$).B3N?S_@<2<````6UY?7<.-5>B)%"3H +XM?;G\_SG[=-N%_P^%+`$``"G[QT0D#`````")7"0(BTV`QP0D^&\)"(T$N8E$ +XM)`3HS6G^_^NMQP5$3`D(>````.D,_O__QP0D"@```.A`U?W_Z=7[__^-7>C' +XM1>@`````QT7L`````,=%\`````")'"3HZRP``(D<),=$)`2PD0@(Z)NY_/^) +XM'"3'1"04`````,=$)!#X;PD(QT0D#`````#'1"0(_P\``,=$)`0`````Z*N* +XM_O^)'"3HP[C\_X'$G````%M>7UW#QP0D"@```.B\U/W_Z7#\__^#!<2L"P@! +XMQT0D!+"0"`C'!"3$K`L(Z"RY_/_IN_S__\=$)`0,````QP0D`0```.CSP___ +XMQP0D@$P)"(G#Z,4O``")7PB)>P2)WXD#Z;#]___'!"3$K`L(Z$JX_/_II_[_ +XM_\<$)`H```#H2=3]_^G#_O__C57HB10DZ"FX_/_IAO[__XUT)@!5B>575E.# +XM["R+10C'1>@`````QT7L`````,=%\`````"%P`^$\````(MP"#G>```` +XMBT`$.?")1>`/A-<```#'1=@`````C7WHQT7<`````(M%##E%W'QXBU40.57< +XM?W"+'HL#ASKZ(U%Z(D$).B<*@``@\0L6UY?7<.-="8`58GE@^P8BT4(QT0D"/___W_' +XM1"0$`````(D$).BO_O__R<.-M@````"-O"<`````58GE5U93@^PLQP0DL!@) +XM".AG,_S_A<")1>0/A.8!``"+1>3'1"0$+P```(D$).A)-OS_AB+7>@/M@/'1?``````A,!T+HL5W%T)"(L-X%T)"(GV#[;`.=!] +XM!_9$@35`=1*#1?`!BW7PBUWH#[8$'H3`=>"+=>0/M@;'1>P`````A,!T+XL5 +XMW%T)"(L-X%T)"(UV``^VP#G0?0?V1($U0'42@T7L`8M=[(MUY`^V!#.$P'7@ +XMH3QW"@@QVX7`#X3=````BQT`F`H(A=L/A,\```#'1>``````ZPJ+&X7;#X2Y +XM````BT,8.T,<=>Z+0PPE'R```#T`(```=`J#^`)T!8/X$'75BT-XB00DZ/0N +XM``")QP^V`(GZA,!T)(L-W%T)"(LUX%T)"`^VP#G(?0?V1(8U0'4*@\(!#[8" +XMA,!UZ,8"`(G^QT0D!"\```")/"3H[#3\_X7`=`.-<`&+1>R+5>2)="0$B40D +XM"(D4).A_,OS_A"#Q"R)V%M>7UW#BT7PBU7HB70D!(E$)`B)%"3H,#+\_X7` +XM#X42____ZZO'1>1-&PD(C78`Z2C^___'1>B^&`D(Z5#^__^0D)"0D)"0D)"0 +XMD)"0D)!5N@$```")Y8/L"(M-"/?!```@`'4J,-*%R70D@?G_````=SRAX%T) +XM"(M$B#2)PH'B````X'0-P>H>C;8`````R8G0PR4```0`@_@!&<"#R`&)PL'Z +XM'\GWTB'"B=##B?:)#"3HY#'\_^O#C;8`````58GE5U93@^P,BT4(BQB%VP^$ +XMI0```(L]X%T)"(G&ZRKWPP```$!U&('[_P```'=CBT2?-/;$$'5GC;0F```` +XM`(M>!(/&!(7;='&+10R%P'3/]\,```!`=>>!^_\```"0=T^+1)\T9H7`>=6! +XM^_\```!W4HN7UW#B1PDZ$$Q +XM_/_VQ!!TH('[_P```'6#[!B)=?R+=0B)7?CWQ@`` +XM(`!T$;O\____B=B+=?R+7?B)[%W#B30DZ(#^__^%P(G##XZ[````]\8```!` +XM==J!_O\````/AYD```"AX%T)"(M$L#3VQ`)TP(GP)?__/P`]_P```'^R@?[_ +XM````#X>/````H>!="0B+1+`TJ0``!`!T!XM5#(72=(^!_O\````/AWP```"A +XMX%T)"(M$L#3VQ`)T#HGP)?__/P`]_P```'YP@?[___\`N_G___\/CU;___^! +XM_O__``"S^@^/2/___X'^_P```+/[#XXU____Z37___^)-"3H#3#\_Y#I8O__ +XM__?&````0'6XC78`Z67___^)-"3H[R_\_XUV`.EJ____B30DZ-\O_/^-=@#I +XM??___X/^"KO]____#X3I_O__,=N#_@D/E<.#ZP+IV?[__XVV`````(V\)P`` +XM``!5B>575C'V4X/L#(M5"(L"AH> +XM@\,$`=:%P'7<@\0,B?!;7E]=PY"-="8`B00DZ#0O_/_KSI"0D)"0D%6)Y5W# +XMD)"0D)"0D)"0D)"A4'0)"#D%5'0)"%6)Y700#[95"(@0@\`!7:-0=`D(P\8` +XM`%W#C70F`(V\)P````!5B>575E.)RX'LC````(E%A`^V`H3`#X0(`0``B56, +XMQT6L`````.LD#[;`"T6LB00D_U6$B5W0@T6,`8M5C`^V`H3`#X3;````BUW0 +XM/"5UV(-%C`&+58P/M@+'19P`````/"T/A',!```\,`^$O@```#PNQD6;(`^$ +XML@```#PJD`^$OP````^VT(/Z?W<.]@25O5$)"`0/A?T$``#'1:``````/"X/ +XMA+0```#'1:3___]_,?\\(P^$;@$``#'2/&P/A#P!```QR3QZ#X0A`0``#[;` +XM@_A3B464="6#^%%T(#L%W%T)"'T8H>!="0B+=91F@WRP-``/B$$!``"-="8` +XMBT64@^@E@_A3#X;&````@T6,`8M5C(E=T`^V`H3`#X4E____@<2,````6UY? +XM7<.#18P!BTV,#[8!QD6;,#PJ#X5!____BS.#PP2#18P!BU6,B76@#[8"/"X/ +XMA4S___^#18P!BTV,#[8!/"H/A'0$```/MM"#^G\/AR[____V!)6]40D(!`^$ +XM(/___XM%C(D$).C&*_S_BU6,B46D#[8"#[;0@_I_=A_I!O___XUT)@"#18P! +XMBTV,#[8!#[;0@_I_#X?L_O__]@25O5$)"`1UX.G=_O___R2%P!D)"(/"`8E5 +XMC`^V`L=%G`$```#I>/[__X-%C`&Q`8MUC`^V!NG._O__@T6,`8M5C`^V`KH! +XM````/&P/A:W^__^#18P!L@*+38P/M@'IG/[__X-%C`%FOP$`BW6,#[8&Z7_^ +XM__^+A+`T!```N@$```")193IK_[__XUS!(EUT(L;A=N)79`/A`$$``")'"3H +XM`"W\_XM]H"G'BT6FW^O__C477B85X____B47,B1PDB70D!,=$)`@*````QT0D +XM#`````#H738``(M-S(/`,(@!@\$!B1PDB70D!,=$)`@*````QT0D#`````") +XM3)A7C___^)QXD<)(ET)`3'1"0("@```,=$)`P````` +XMZ&XX``"#P#"(!X/'`8D<)(ET)`3'1"0("@```,=$)`P`````Z&HZ``"#^@") +XMPXG6?[=\!8/X`'>PBUVHA=N0C70F`'0&Q@/___W;IBT6/___XE5S(M5S(G8@^`'#ZSS`X/`,,'N`XGQB`*# +XMP@$)V8E5S'7@A?]T&8MUS,8&,(/&`8GP*X5X____B77,Z7/\__^)T"N%>/__ +XM_^EF_/__C5,$B570BP.)QHG#P?X?Z7K^__^-0P0Q]HE%T(L;Z1?\__^-2P2) +XM3="+`\=%J`````")QHG#P?X?A?8/B5S^___WVX/6`/?>QT6H`0```.E)_O__ +XMJ0```$`/A&OZ__^+A7S___^)!"3_583I6OK__XU-V.LA@\`PB$'_B4W,B?*) +XMV`^LT`2#P0'!Z@2)PXG0B=8)V'05B=B#X`^#^`E^U8/`5XA!_XE-S.O3A?]U +XM$XM%S(U5UXF5>/___RG0Z:3[__^+3/___^F"^___B6#[`B+10B+ +XM312+51"C4'0)"`-%#(/H`:-4=`D(N+!M"`CH%_;__Z%0=`D(Q@``@\`!HU!T +XM"0C)PY"-="8`5;@@.P8(B>6+50B+30Q=Z>SU__^-M@````"-OP````!5N"`[ +XM!@B)Y8/L&(M5"(U-#(E-_.C']?__R<.0C70F`%6)Y8/L&(M%"(U-%(M5$(E- +XM_*-0=`D(`T4,@^@!HU1T"0BXL&T(".B4]?__H5!T"0C&``"#P`&C4'0)",G# +XMD)!5B>5=QP6`=`D($!L)",<%A'0)"!0;"0C'!8AT"0@8&PD(QP6,=`D('!L) +XM",<%D'0)""`;"0C'!91T"0@D&PD(QP68=`D(*!L)",<%G'0)""P;"0C'!:!T +XM"0@P&PD(QP6D=`D(-!L)",<%J'0)"#@;"0C'!:QT"0@\&PD(QP6P=`D(0!L) +XM",<%M'0)"$0;"0C'!;AT"0A(&PD(QP6\=`D(3!L)",<%P'0)"%`;"0C'!<1T +XM"0A4&PD(QP7(=`D(6!L)",.-M@````"-O"<`````58GE5U8Q]E.#["R+10R+ +XM.(D\).@$)/S_C02%!````(D$).BIL?__QT7P`````(E%[.L6H>!="0B+1)`T +XM]L0%=06#^U]U4H/&`8M%[(/'!(T$L(E%X(L?BT7L@>/___\_A?:)'+!U!8/[ +XM>W06#[;3@?K_````=KR)%"3H'2/\_Y#KNH/'!(L?@>/___\_B1C'1?`!```` +XMZ]2+1>#'``````"+5?"%TG00BP2+1`$$A +XM7UW#@\<$Z3;___^+1>R)!"3HTU#^_X7`=#"+$(72=,:)PX/Z"G07@_H-=!*+ +XM10@+51")!"2)5"0$Z*L7``"+4P2#PP2%TG7:ZYR+10R).(M%[(D$).@OK___ +XM,<#KG8UT)@"-O"<`````58GE5XG'5HG.4XG3@^P<@#H`="^-1?")7"0$QT0D +XM"`8```")!"3H!1\``(D\)`'#B?`+1?")1"0$Z$(7``"`.P!UT8/$'%M>7UW# +XMD(UT)@!5B>575E.#[$R+10S'1>``````QT7D`````,=%Z`````")1?"-112) +XM!"3H;2+\_\=$)`2PD0@(B47`C47@B00DZ`ND_/^+5?"+`H7`#X28````QT6\ +XM`````.M.D(UT)@"#?0@"#X3Y````H029"@C'!"0]W`@(@\`!B40D!.B>^___ +XMB<.+3;R)VHU%X.@?____B1PDZ#>N__^+1?"-4`2)5?"+0`2%P'1!@_@E=&6# +XM^%P/A)P```"#^%X/A),````[!8R8"@ATF`M%O(U5X(E$)`2)%"3H5A8``(M% +XM\(U0!(E5\(M`!(7`=;^-1>")!"3H"Z/\_XU5X(D4).BPHOS_C47@B00DZ$46 +XM``"#Q$Q;7E]=PXM:!(U*!(7;=*.)3?"+6@2-0]^#^%UV4H/[80^$`0<``(M% +XMO(/()8E$)`2-1>")!"3HYQ4``(M%\(L`Z77___^-1?")!"3HDI___^EE____ +XMBT48QP0D:````(E$)`3H^E;]_XG#Z0?_____)(5D&PD(@66\____^XM%\(GV +XMZ0?___^!3;P````$BT7PD.GW_O__BU6\BT7`QT0D!`(```")5"0(NA^%ZU&+ +XM2!2)R/?JB")%"2)PXE$)`3HM1<` +XM`.FA_O__BU7`BTV\BT(0BQ2%@'0)"(U%X.BH_?__BT7PZ8S^__^!9;S____? +XMBT7PZ7W^__^!9;S____WBT7PZ6[^__^#?0@!#X1W"```QT0D!,28"@C'!"2D +XM+PD(Z&0)_O\]^&\)"'0DBQ"%TG0>B<,+5;R-1>")!"2)5"0$Z,,4``"+4P2# +XMPP2%TG7DBT7PZ1W^__^#?0@!#X0*"```QP0D7!L)"#'VZ-4=_/^)PX7;=3OK +XM0)"#?0@!=`0\+G0UC57LB5PD!,=$)`@&````B10DZ!\<```!PXM%O`M%[(E$ +XM)`2-1>")!"3H6!0```^V`X3`=<&%]G24B30DZ.6K__^+1?")]NFG_?__@WT( +XM`0^$>@<``,=$)`3$F`H(QP0DO"X)".B="/[_/?AO"0@/A%G___^+$(72#X1/ +XM____B<,+5;R-1>")!"2)5"0$Z/03``"+4P2#PP2%TG7DZ2S___^A`)@*"+K_ +XM____AO(@4V\````((M%\.F3 +XM_/__@4V\````"(M%\.F$_/__@WT(`@^$IP8``(M-$(7)#X1*_O__BTV\C47@ +XMBU40Z'7[__^+1?#I6?S__X-]"`$/A+@%``#'!"1<&PD(Z!,<_/^)PX7;=`V+ +XM3;R)VHU%X.A$^___@WT(`0^%`?[__^D6_/__@4V\````$(M%\.D2_/__BT7` +XMBU@(QT0D!,28"@C'!"1@/`D(Z*P&_O^%P`^$L@0``(/["P^.YP,``(/[#+]P +XM````C78`?@.#ZPR+5<"+0@2%P`^%L`,``(M%"`L%:'0)"`^$=P,``,=$)`3$ +XMF`H(QP0D0$8)".A:!O[_BU6\B1PDB50D"(/X`1G`]]"#X`*)1"0$Z`W$__^) +XMPXE$)`2-1>")!"3H?!0``(D<).BDJ?__BW6\C57@B10D@\XZB70D!.CO$0`` +XMBU7`BT6\QT0D!`(```")1"0(BT($B00DZ,+#__^)PXE$)`2-1>")!"3H,10` +XM`(D<).A9J?__BT7PBP"#^'`/A"P$``"#^%`/A",$``#'1"0$Q)@*",<$)&`\ +XM"0CHK@7^_X7`#X3K`P``B?H/OL(+1;R)1"0$C47@B00DZ&\1``"+1;R#R&WI +XM__K__\=$)`3$F`H(QP0D]"X)".C0!?[_/?AO"0@/A(S\__^+$(72#X2"_/__ +XMB<,+5;R-1>")!"2)5"0$Z"<1``"+4P2#PP2%TG7DZ5_\__^#^V,/A-D#``#' +XM1"0$Q)@*",<$)&0S"0CH>P7^_SWX;PD(B<)/6!T"0C'!"1@=`D(Z$+! +XM__^C9'0)"*%D=`D(AL.@_@O#Y3`@\8$#[;``<&+ +XM!H7`=>R$TG0*,<"#/R\/E<`!P8M%\,=%Q`````"#P`2#.#`/A/4!``"+5?"# +XMP@2)5="+`KH!````B47,@^@Q@_@(=PR+5OV__^-5>")%"2)="0$Z'`-``"+1;R+5<#'1"0$`@```(E$)`B+ +XM`HD$).A$O___B<.)1"0$C47@B00DZ+,/``")'"3HVZ3__^F4^___LRZ-="8` +XMZ1S\__^+51C'1"0$30```(D4).C((```B")!"3HQ@P``(M#!(/#!(7`=>3I7?S__XM5&,=$)`1L````B10D +XMZ%0@``")P^GQ]?__BT48QT0D!&T```")!"3H.B```(G&B") +XM%"2#R#R)1"0$Z!0,``"#?<@)#XZ!````BT6\@\@YB40D!(U%X(D$).CU"P`` +XMBT6\C57@B10D@\@KB40D!.C@"P``BT6\C57@B10D@\@^B40D!.C+"P``Z")!"3HI@L``(L$G0A#"0B%P'7@ +XMBT7PQP5H=`D(`0```.GU]/__BT7(@\`P"T6\B40D!(U%X(D$).AQ"P``ZX_K +XM#9"0D)"0D)"0D)"0D)!5B>575E.#[!R+=0B+?0S'!"0`````Z`$4_/^#_@*) +XM1?`/A)0!``"#_@,/A'8!``"#_@$/A+T```#'1"0$Q)@*",<$)*@R"0CHD__] +XM_X/^`8G##XZT````H2QW"@B)!"3HFZ+__\=$)!``````BT7PQP4L=PH(```` +XM`(E\)`B)7"0$B40D#,<$)`````#HGO/__XL]Y)D+"(7_HRQW"@AU,HL0A=)T +XM&XG#C;0F`````(D4).@XM?W_BU,$@\,$A=)U[L<$)`````#H$EC__^CML/W_ +XMH7B9"PB)!"3H(*+__X7VQP5XF0L(`````'0O@\0<6UY?77UWI&K#]_XL=<'0)"(7;=":+/6QT +XM"0CIG?[__\=$)`3$F`H(QP0D`#,)".@1_OW_B"0B%P'02B00DZ&^@___'!8!> +XM"0@`````BT7")6`B)0P2+=P2#QP2)7>"%]G7*B=B- +XM5>2)4`B+5=R)1>B+`J/,=`D(BT((B00DZ$29_?^+1=R)!"3HZ9___XU5Y(D4 +XM),=$)`20Z04(Z%:5_/^-1>2)!"3H"Z[]_XM%[(U5Y(E4)`3'1"0(`````(D$ +XM).B!JOW_QT0D!$`K!@B)PXD$).@?E?S_BPV`7@D(A_?^-1>2) +XM!"3H-I3\_XL5S'0)"(72B57<=`R+0@0[1?`/C+W^__^+%81W"@B%TG0)H3AW +XM"@B%P'0>QP4X=PH(`````,<$),2L"PCH])/\_X/$+%M>7UW#Z+<6___H4C?_ +XM_XGVZ,LW___HQD?__^O*C70F`.B;%?__H!(7;#X2C`@`` +XMC58(B57@BP.#^"T/A,@!``"+=@B%]@^$>0,``*D```!`#X0Y`0``@_@K=`S' +XM!"1L````Z`&1_/^#PP2^`0```(D<).C!#```B00DZ&4/_/^)QXL#AR)5"00B70D#(E$)`B+1=S'!"0#````B40D!.BU[/__B1PDB<;H +XM6Y#\_\=$)`0P*@@(B30DZ.N0_/^+!H7`=!>)\XUV`(D$).CXK?W_BT,$@\,$ +XMA5=QP74=`D(`0```,.058GE7<<%V'0)"`$```## +XMD%6)Y5W'!=QT"0@!````PY!5B>6+10A=BP"CQ*P+",.058GE@^P(HL& +XM@\`$@\$$BQ&%TG0/.Q!T\(L+A6+10B+`(E%"%WI;YC__^L-D)"0D)"0D)"0D)"0D%6)Y8M%"(L`B44( +XM7>E/F/__ZPV0D)"0D)"0D)"0D)"058GE5E.#[!"+=0B+7@2%VW07,=N+!HL$ +XMF(/#`8D$).@7>D'F/__C;0F`````%6)Y8/L +XM&(E=^(G#B77\BT`(B=8[0P1T&(M3!(L#B320BUWXBW7\B>Q=PXVV`````(7` +XM=1_'0PA`````BT,(P>`"B40D!(L#B00DZ-&8__^)`^O%`<")0PCKX8VV```` +XM`%6)Y5.#[`2+70B+50R)V.B,____@T,$`8/$!%M=PXGV58GE4X/L%(M=",=$ +XM)`0`````B1PDZ,;___^+0P3!X`*)1"0$BP.)!"3HDR____B?95B>6#[!B)7?B)PXEU_(M`"(G6.T,$ +XM=!B+$XGQBT,$B`P"BUWXBW7\B>Q=PXUT)@"%P'453@^P$BUT(#[Y5#(G8 +XMZ(O___^#0P0!@\0$6UW#D%6)Y5.#[!2+70C'1"0$`````(D<).C&____BT,$ +XMB40D!(L#B00DZ*67__^#Q!1;753@^P4BUT(B=CHC?___XM#!(/``<'@`HE$)`2+ +XM`XD$).CVEO__@\046UW#58GE4X/L!(M="(M5#(G8Z%S___^#0P0!@\0$6UW# +XMB?95B>564X/L$(M="(MU$(M3"(GP`T,$.<)S.H72=16#^$!FN@`!QT,(0``` +XM`'86ND````")\`'2`T,$B5,(.=!W\L'B`HE4)`2+`XD$).A^EO__B0.+0P2- +XM%+4`````P>`"`P.)5"0(BU4,B00DB50D!.AF#?S_`7,$@\006UY=PU6)Y5.# +XM[!2+70R)'"3H.@C\_XE<)`2)1"0(BT4(B00DZ%O___^#Q!1;7<.0C70F`%6) +XMY593@^P0BUT(BW40BU,(B?`#0P0YPG,UA=)U$X/X0+)`QT,(0````'83ND`` +XM``")\`'2`T,$B5,(.=!W\HE4)`2+`XD$).C3E?__B0.+4P2+10P#$XET)`B) +XM1"0$B10DZ,4,_/\!)\I"-="8`BP*# +XMP@2%P'7WN/S___\IV"GP`<@!T(D$).C2E/__B=J)QXG!BP*#P@2)`8/!!(7` +XM=?*)\HL"@\($B4'\@\$$A6#[!B)7?B+70R)=?R+=0CWPP``(`!T%H@>N@$```"+7?B)T(MU_(GL7<.- +XM=@")7"0$B30DZ'`*_/^#^/]TV87`N@$```!^UXM=^(G"BW7\B>R)T%W#D(VT +XM)@````!5,<")Y5=64X/L#(M]"(7_#X21````BS7D=`D(A?8/A,$```"+'>1T +XM"0B#QP2)W@,UX'0)".L#@\<$BT?\A=\NAX'0)"(/H@*/@=`D(@\`&B40D!*'D +XM=`D(B00DZ$.3__^)Q@,UX'0)"*/D=`D(C5Z`ZYC&`P"AY'0)"(/$#%M>7UW# +XMH>!T"0B#Z("CX'0)"(/`!HE$)`2AY'0)"(D$).@`D___B<8#->!T"0BCY'0) +XM"(U>@.EM____QP7@=`D(@````,<$)(8```#HA9+__Z/D=`D(Z1____^-="8` +XMC;PG`````%4QP(GE5U93@^P,BWT(A?]T>:'L=`D(A(L=['0)"(G>`S7H +XM=`D(ZPB0C70F`(/'!(L'AAT +XM"0B#Z("CZ'0)"(/`!HE$)`2A['0)"(D$).A/DO__B<8#->AT"0BC['0)"(U> +XM@.NMQ@,`H>QT"0B#Q`Q;7E]=P\<%Z'0)"(````#'!"2&````Z,>1__^C['0) +XM".EH____C;8`````C;PG`````%6X!````(GE5U93@^P,BUT(BPN%R70:,,"- +XMM"8`````@\`!BQ2#A=)U]HT$A00```")!"3H=Y'__XG'BP.)_H7`=!^)!"3H +XM]?[__XD$).@MCOW_B0:+0P2#Q@2#PP2%P'7AQP8`````B?B#Q`Q;7E]=PXVT +XM)@````"-O"<`````58GE@^PXBT40B77XBW4(B5WTB7W\B40D"(M%#(DT)(E$ +XM)`3HA`/\_X7`B<-^+(L&B40D!(U%[HE%X(D$).BZ!_S_.<-U#XMU##G;B=F+ +XM?>#\\Z9T!;O_____B=B+=?B+7?2+??R)[%W#C;0F`````%6)Y8/L&(E=^(M% +XM$(EU_(M=#(MU"(E$)`B)7"0$B30DZ&O___^#^/]T%X7`N@$```!^`HG"BUWX +XMB="+=?R)[%W#QT0D"`````#'1"0$`````,<$)`````#HWP+\_P^V`[H!```` +XM#0``(`")!HM=^(G0BW7\B>Q=PY"-M"8`````53'`B>564X/L((M="(7;=%'' +XM!?1T"0@`````@#L`=#&-=?2)7"0$QT0D"`8```")-"3H2?___\<$)/!T"0@! +XMPXM%](E$)`3HA/?__X`[`'72QP0D\'0)".C3]___H?!T"0B#Q"!;7EW#C;0F +XM`````%6X!````(GE5U93@^P,BUT(BSN%_W0:,,"-M"8`````@\`!BS2#A?9U +XM]HT$A00```")!"3HEX___XG'BP.)_H7`=!^)!"3H1?___XD$).CM^O__B0:+ +XM0P2#Q@2#PP2%P'7AQP8`````B?B#Q`Q;7E]=PXVT)@````"-O"<`````58GE +XM5U93@^P,BT4(BQB%VP^$FP```(L5X%T)"(G'B57PZS*+5?"!_O\```"+E)HT +XM!```B57L=TB+5?"+A+(T!```.47L=4:#10P$BU\$@\<$A=MT7(M%#(LP.?-T +XMZ8'[_P```':]B1PDZ+X"_/^!_O\```")1>QVOXVT)@````")-"3HI`+\_SE% +XM['2ZA=N0=#2%]KH!````="$Y1>R)]G0SBU7L@\0,6UY?72G"B=##BT4,,=*+ +XM`(7`=0J#Q`R)T%M>7UW#@\0,NO____];B=!>7UW#B=HI\NOAD)"0D)!5B>56 +XM4X/$@,<$)$`Q"0CH["[^_\<$)"0Q"0B)QNC>+O[_QP0D9#$)"(G#Z-`N_O^% +XMVP^$J`$``(7V#X21`0``A<`/A'\!``")7"0_/^)!"3H2?O__\=$)`3$F`H(QP0DO$@)"(G#Z"/G_?^%P'0. +XMBP"%P'0(BP"%P'0"B<.)="00BT9$QT0D"`````")7"0$QP0D`0```(E$)`SH +XMGMO__\=$)`0P*@@(B<:)!"3HW'_\_XL&AR\````@ST`=0D(`<=$)`2PD`@(QP0DQ*P+"`^4P(F%3/___X,%Q*P+"`'H +XM9W_\_\=$)`3$F`H(QP0DO$`)".A3YOW_A<`/A((```"+`(7`B850____=':+ +XM?0B%_P^$:0$``,>%4/___P`````QVXU%[(D$).BY^OO_BU7LB=`K!01U"0@Y +XMPW\NC85@____B14$=0D(B40D!,<$))0="0CH;O[[_X7`=#"+=0B%]@^$>@$` +XM`(UV`,<$),2L"PCH-'[\_X'$O````%M>7UW#BT4(A0C70F`(G>BQZ%VP^$Y0```(U%P(E$)`2-1BK'1"0("``` +XM`(D$).C&^OO_@_@`?-4/A<````"+7>@[7D1\AXGZA-*-=@`/A6`#``")7D3' +XM1D@"````Z6O___^+A5#___^[6`(``(D$).AH%?W_BY50____B10DZ,I[_?^H +XM`0^$>O[__XN54/___XL"B00DZ+*'_?^%P`^$8O[__XN54/___XL"@\($B950 +XM____B00DZ.'B_?]KV#SI0?[__\=$)`S('0D(QT0D"`$```"A@)@*",=$)`0: +XM````B00DZ/3;_/_'1"0$E!T)"(D$).B$U?__Z4_^___'1"0$3````,<$)`$` +XM``#H^X?__XU5P(E4)`3'1"0("````(G#C4`JB00DZ*O[^_^-1=B)1"0$C4,S +XMQT0D"!````")!"3HD?O[_XM%Z(E#1(!]R`!U&<=#2`(```"+1@2),XE#!(D8 +XMB5X$Z6#^__^-5_S_BT4(A<`/A:?]__^+A5#___^%P`^$F?W__XN]4/___X/'"(M' +XM^(7`#X2%_?__BQ"%T@^$>_W__XM?_(7;#X1P_?__BS.%]@^$9OW__\=$)`3D +XM+@D(B00DZ"+Y^__'A4C___\`````A<`/A'L!``"+-2!U"0B+!H7`=13IL0`` +XM`(UV`(LVBQZ%VP^$H@```/9&2`AU[HM?^,<$).0N"0B)7"0$Z-?X^_^%P'0? +XMC48(B00DZ.SV__^)7"0$B00DZ``O_?^%P`^$[0```(U&*HM?_(D$).C*]O__ +XMB5PD!(D$).C>+OW_A<`/A*L```"+1DBH$'01H01U"0B)1D2+1DB#X.^)1DBH +XM`G1>@'X(`'18BX5,____A<`/A/````"#3D@(QD8(`(LVBQZ%VP^%7O___XN- +XM2/___X/'"(7)#X3A_O__Z6S\__^+70B%VP^%8?S__\=$)`SP'0D(QT0D"`(` +XM``#IT_W__Z@!=0BH!`^$$/___XN%3/___X7`=&*-1AF)1"0$C48(B00DZ.#^ +XM^_^#3D@(Z>O^__^+1_S'!"3D+@D(B40D!.C4]_O_A<`/A=#^___I-?___XU& +XM&8M?^(D$).C=]?__B5PD!(D$).CQ+?W_A<`/A*G^___I[/[__XGPB?;H._K_ +XM_^N3QT0D!.0N"0B)'"3HA??[_X7`#Y3`#[;`B85(____Z6+^__^)\.@/^O__ +XMZ03___^-1@B)1"0$C47(QT0D"!````")!"3H+/?[_X7`=0^)7D3'1D@)```` +XMZ>W[__^-557,?]64X/L#,=$)`3$F`H(QP0DO"X)".@QX?W_B00DZ*GR +XM___'!"0!````B<;H&_K__XL=('4)"(L#AS/&0P@`BQN+`X7`==[HB/C__X/$#(GX6UY?7<.-M"8`````C;PG```` +XM`%6)Y5=64X/L+(M=#(MU"(U#LX/X(78IQP0D`P```.B=A/__B!= +XM"0AF@WR.-`!Y"`^VA(XT!```B`,/MD(!@\,!@\(!A,!UTL8#`.E2____C48J +XMB44(@\0L6UY?7>FA@/W_@'XS``^$&P$``(U>,XD<).C(^_O_@\`!B00DZ+&# +XM__^)QP^V1C,/MM"#^G\/AB\!``#'1>0N````A,")_G12BQ7<70D(B57H#[[` +XM.T7D#X2R````#[8#/#H/MM`/A(\````Y5>A^&XL-X%T)"&:#?)$T`'D-A=)X +XM!XN4D30$``")T(/#`8@&#[8#@\8!A,!UM\8&`.FG_O__BT9(@^`'@_@"#X0- +XM`0``@_@$#X3*````@^@!#X6__O__H8"8"@C'1"0,HAT)",=$)`@)````QT0D +XM!!H```")!"3H4M;\_^D-____C489Z07___^0C70F`+HZ````QT7D`````(UT +XM)@#I7/___XD<),=$)`0Z````Z$?V^_^%P(G##X4T____Z6S___^A@)@*",=$ +XM)`Q1#@D(QT0D"`P```#'1"0$&@```(D$).CGU?S_B44(@\0L6UY?7>E(?_W_ +XMC48(Z9#^___V!)6]40D(!,=%Y``````/A"0CHGO'__\<$)``Q"0B)1"0$Z'[H_/_'!"2P'@D(Z(+Q +XM___'!"0D,0D(B40D!.ABZ/S_QP0DJ!X)".AF\?__QP0D9#$)"(E$)`3H1NC\ +XM_\<$)+8>"0CH2O'__\<$)$`Q"0B)1"0$Z"KH_/_)PY"0D)"0D)"058GE@^P8 +XMB5WXBUT,B77\BQ7,=0D(BW4(A=)T)*'0=0D(A<`/A(P```")70R+7?B)=0B+ +XM#=1U"0B+=?R)[%W_X<<%S'4)"`$```#'1"0$`0$``,<$)+L>"0CH[OG[_X7` +XMH]!U"0AT3L=$)`3''@D(B00DZ"7T^_^CU'4)",=$)`32'@D(H=!U"0B)!"3H +XM"_3[_Z/LK`L(QT0D!-@>"0BAT'4)"(D$).CQ\_O_H_"L"PCI=/___XM=^+C_ +XM____BW7\B>Q=PY"0D)"0D)"0D)"0D%6)Y5=6@^PPBT40BU44BW4(BWT,B47L +XMB<&)5>B+1>C'1=``````QT74`````(GZB77DA<")=?")?>!U%#GY=F")\/?Q +XMB570QT74`````.L0BTW@.4WH=AB)==")?=2)]HM%T(M5U(/$,%Y?7<.-=@`/ +XMO47H@_`?B478=4:+1>@Y1>`/A\D```"+3>PY3>0/@[T```"+3?")5=2)3=#K +XMP9"+1>R%P'4,N`$````QTO=U[(G!BT7@BU7H]_&+1>3W\>N"N"````"+5>PK +XM1=B+=>R+?>2)P8E%W-/JBT7H#[9-V-/@"<*+1>33Y@^V3=R)5?2+5>#3Z`^V +XM3=C3X@G0BU7@T^"+1>0K1>P;5>B)1?#I+____SGX=K``````BW4,QT7D`````(E%](G!BT4(A=*)UXE%['4C.?$/AI@```")\O?Q +XMB<$QP(E-X(E%Y(M%X(M5Y(/$(%Y?7<,Y\@^'M0````^]PH/P'XE%Z`^$E@`` +XM`+@@````BU7T*T7HB<'3Z@^V3>B)1?")^(M]]-/@"<*+1>S3YP^V3?")5=R) +XM\M/H#[9-Z-/B#[9-\`G0T^Z)\O=UW(G1B778B478]^QS%(UT)@`QR3'`Z2?___^-M"8` +XM````N0$````QP.D4____BT7L#[9-Z-/@.<9VAXM-V#'`@^D!Z?K^__^0D)"0 +XMD)"0D)"058GE5U:#[%"+30R+512+11#'1;@`````A@]<`]]_I!O____?:@]$`]]G'1<#_____Z>C^__^X(````(M5W"M%R(G! +XMT^H/MDW(B474B?B)UXGRT^`)QXM%W-/@#[9-U(E%K(M%V-/H#[9-R-/B"="+ +XM5=C3X@^V3=2)5>2)\M/J]_>)UO=EK#G60IP1G6BG^__\[1>1VI2M%K!GZZYZ0D)"0 +XMD)"0D)"0D)"0D%6)Y5=6@^PPBU4,BT4(BW40BWT4B570`````#XBD````A?\/B+H```")UXG&BU78B<&+ +XM1=R%_XE5\(E%['44.<9V08G0BU7L]_:)P3'`ZQ.-=@`[?>QV3S'),<"-M"8` +XM````B4W0BTWDB474BT70BU74A7UW#A?9U"[@!```` +XM,=+W]HG!BT7LB?KW\8G&BT7P]_&)P8GPZ[P/O<>#\!^)1>AU1#E]['<%.77P +XM3_____#XE+____D(UT)@")\(GZ +XM]]B#T@#WVO=5Y.DS____N"````")\BM%Z(G!T^H/MDWHB47TB?B)UXM5[-/@ +XM"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>)553@^P$H1A/"0B#^/]T$C';_]"+@Q1/"0B#ZP2#^/]U\(/$!%M= +XMPY"0D(/L#.B\\_O_@\0,PP```````````````````````````````"1&'0@87)G=6UE;G0@"BUD"0EL;V%D(&1I2!S=&%C:R!F2D@"BUI"0EI;G1E6YT87@@;V8@=&AE(&9O;&QO=VEN9R!@9FEL92<@"BUQ"0EA8V-E<'0@ +XM4TE'455)5"!F;W(@&5C=71I +XM;VX@"BU8"0EL:6ME("UX(&)U="!I;F-L=61I;F<@8V]M;6%N9',@&ET(`H*4V5E('1H92!T8W-H*#$I(&UA;G5A +XM;"!P86=E(&9O2!I9@!);7!R;W!EF5D`"5S(&YO="!F;W5N9`!);7!R;W!E6YT87@`3F\@:&]M92!D:7)E8W1O0!$:7)E8W1O0!5`!%>'!A;G-I;VX@8G5F9F5R(&]V97)F;&]W`%9A`!"860@(2!F;W)M`$YO('!R979I;W5S('-U8G-T:71U=&4`0F%D('-U +XM8G-T:71U=&4`3F\@<')E=FEO=7,@;&5F="!H86YD('-I9&4`4FEG:'0@:&%N +XM9"!S:61E('1O;R!L;VYG`$)A9"`A(&UO9&EF:65R.B`E8P!-;V1I9FEE2`I)W,`5&]O(&UA;GD@*"=S`$)A9&QY('!L86-E9"`H`$UI0``07)G=6UE +XM;G0@9F]R("UC(&5N9',@:6X@8F%C:W-L87-H````07)G=6UE;G1S('-H;W5L +XM9"!B92!J;V)S(&]R('!R;V-E6YC(&9A=6QT.B!065T*0```%5S86=E.B!H:7-T +XM;W)Y(%LM)7-=(%LC(&YU;6)E2!A2!F:6QE(&YO="!E>&5C=71A8FQE``!5;FMN;W=N(&]P=&EO;CH@ +XM8"TE%@@72!;(&%R9W5M +XM96YT("XN+B!=```*36ES"4P.'@*`"5D(&AI=',L("5D(&UI!0CO6@4([UH%".]:!0CO6@4([UH%".]:!0CO +XM6@4([EX%"`=?!0@@7P4(.5\%"$-?!0A<7P4([UH%".]:!0CO6@4(:U\%"'I? +XM!0BS7`4([UH%"*%>!0BU7@4([UH%".]:!0C.7@4([UH%"-]>!0CO6@4([UH% +XM".]:!0CO6@4(ZUT%"%);!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4( +XMCEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B. +XM6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(2UL%"(Y:!0@I6P4(CEH%"(Y: +XM!0@B6P4(UUH%"`<`#0`````````````````````````````````@````)P`` +XM`"(````)````.P```"8````\````/@```"@````I````?````%X````E```` +XM`````'1CF4`=FUE;6]R>75S90!D97-CF4`)6IO8B`F`"5J;V(``"5S +XM.B`E6!0@ME@4(&98%"`^5!0@/ +XME@4(!98%"`^5!0@/E04(#Y4%"`^5!0@/E04(#Y4%"`^5!0C[E04(#Y4%"`^5 +XM!0@/E04(\94%"`^5!0CGE04(#Y4%"-V5!0ACF@4(0YH%"(B9!0B(F04((YH% +XM"(B9!0B(F04(B)D%"(B9!0B(F04(\9D%"-&9!0B(F04(B)D%"(B9!0A#F@4( +XM;)L%"&R;!0C%G`4(H)P%"&>;!0ALFP4(YYL%"&R;!0BG +XMFP4(@)T%"&R;!0ALFP4(2)T%"&R;!0ALFP4(YYL%"'1C&-E<'1I;VX`2TE,3`!+:6QL960`55-2 +XM,0!5&ET960`24\`07-Y;F-H&-E961E9`!81E-:`$9I;&5S:7IE(&QI;6ET(&5X +XM8V5E9&5D`%9404Q230!6:7)T=6%L('1I;64@86QA0!B&5C`&5X:70`9F<`9FEL +XM971E0!O;FEN='(`<&]P9`!P&5S +XM=6P`+20J`"@]?@!>*BTE)'M].B,`.EXD*BTE`````&YC:&%R^04(N@(&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``& +XM"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8( +XMI``&"*0`!@B:`@8(I``&"*0`!@B:`@8(I``&"*0`!@BD``8(I``&"*0`!@A\ +XM`@8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0` +XM!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@B:`@8(]1(&")42!@B5$@8(UPH& +XM"-<*!@C7"@8(UPH&")42!@C7"@8(UPH&"&T2!@C7"@8(UPH&"-<*!@C7"@8( +XMUPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@B5$@8(UPH&"-<*!@C7 +XM"@8(UPH&"!(2!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<* +XM!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH& +XM"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@B5$@8( +XMF0T&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7 +XM#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<- +XM!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT& +XM"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08( +XM%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7 +XM#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(T0T&"!<-!@@7#08(T0T&"!<- +XM!@@7#08(%PT&"-$-!@@7#08(%PT&"!<-!@BP$`8(IQ`&"-$-!@@>#P8(T0T& +XM"-$-!@@7#08(%PT&"*<0!@AW:61E7W)E860`.R8*`#P^*"D`)74E=0`E9#H` +XM"`A)W@@(3-X("$_>"`A%R0@(`````&YO="!A +XM(&1I0!U;G)E861A8FQE``HE4R`E0!"860@='=?8V]M;6%N9`H`:71E;7,`)7,Z($EN=&5R;F%L(&UA=&-H +XM(&5R!0<(G@4'"#P#!PB,`P<(QP,'"``````````` +XM````````````````@+X&"/#%!@C`NP8(H,4&"("^!@B`O@8((+X&"*#%!@A@ +XMNP8(D+L&","[!@C`NP8(`+L&"#"[!@C0N@8(H+H&"'"Z!@B`O@8(@+X&""#% +XM!@@`````````````````````P,`&",#`!@C`P`8(0,4&",#`!@C`P`8(P,`& +XM"$#%!@C`P`8(P,`&",#`!@C`P`8(P,`&",#`!@C`P`8(P,`&",#`!@C`P`8( +XMP,`&"(#$!@@`````````````````````T,$&"/#"!@BPO08(4,4&"-#!!@C0 +XMP08(L+T&"%#%!@BPO08(L+T&"."Y!@A`O08(X+P&"+#)!@B`O`8(\+L&"&"Y +XM!@C0P08(T,$&")#$!@@*)7,@:6YT97)N86P@97)R;W(Z($D@9&]N)W0@:VYO +XM=R!W:&%T($DG;2!L;V]K:6YG(&9OF4M=V]R9`!C:&%N9V4M +XM8V%S90!C:&%N9V4M=&EL;"UE;F0M;V8M;&EN90!6:2!C:&%N9V4@=&\@96YD +XM(&]F(&QI;F4`8VQE87(M&-H86YG +XM92UP;VEN="UA;F0M;6%R:P!%>&-H86YG92!T:&4@8W5R'!A;F0@=F%R:6%B;&5S`&9O2US96%R8V@M8F%C:W=A2US96%R8V@M9F]R=V%R9`!I;G-E"UM971A`'%U;W1E9"UI;G-E2!E=F5R +XM>71H:6YG`')U;BUF9RUE9&ET;W(`4F5S=&%R="!S=&]P<&5D(&5D:71O<@!R +XM=6XM:&5L<`!S96QF+6EN2!D96QA>65D +XM('-U2UF;'5S:"UO=71P=70`5'1Y(&9L=7-H +XM(&]U='!U="!C:&%R86-T97(`='1Y+7-I9VEN='(`5'1Y(&EN=&5R2US +XM:6=T'0M=V]R9`!V:2UA9&0`=FDM +XM861D+6%T+65O;`!V:2UC:&"!C;VUM86YD`'9I+65N9'=O6%N:P!Y86YK+7!O +XM<`!E7V-O<'E?=&]?8VQI<&)O87)D`&5?<&%S=&5?9G)O;5]C;&EP8F]A5]P`!$ +XM96QE=&4@8VAA2!L:6YE````1&ES<&QA>2!L;V%D(&%V97)A9V4@86YD(&-U +XM&5C=71E(&-O;6UA;F0@86YD(&ME97`@ +XM8W5R'0@:&ES=&]R>2!L:6YE````17AP86YD('!A=&AN86UE7!E9"!T;R!T:&4@;&EN92!V97)B871I;0```$QO;VL@9F]R +XM(&AE;'`@;VX@8W5R&EC86P@8W5R +XM7!E +XM9`!6:2!R97!L86-E(&-H87)A8W1E6%N:V5D('1E>'0@=VET:"!Y86YK(&9R;VT@96%R;&EE +XM2D@4&%S=&4@8VQI<&)O87)D +XM(&)U9F9E'0@=V]R9"!T;R`G7%PG```H5TE.,S(@;VYL +XM>2D@0V]N=F5R="!E86-H("`!K;0!A;0!X;@!C;P!L:0!A9&0@ +XM;F5W(&)L86YK(&QI;F4`8FP`875D:6)L92!B96QL`&-L96%R('1O(&)O='1O +XM;0!C;&5A7-I8V%L('1A8G,`3G5M8F5R(&]F(&QI;F5S`$YU;6)E0!Y97,`8F%U9`!C;VQS``EF;VQL;W=I;F<@8VAA +XM3H@3G5L;"!E>'1E;F1E9"UK97D@;F]T(&%L;&]W960N +XM"@!!9&18:V5Y.B!.=6QL(&5X=&5N9&5D+6ME>2!N;W0@86QL;W=E9"X*```` +XM`$%D9%AK97DZ('-E<75E;F-E+6QE860M:6X@8V]M;6%N9"!N;W0@86QL;W=E +XM9`H``$]C=&%L(&-O;G-T86YT(&1O97,@;F]T(&9I="!I;B!A(&-H87(N"@`E +XM+3$U4RT^(`!N;R!I;G!U=`!3;VUE=&AI;F<@;75S="!F;VQL;WUU]`%5N8F]U;F0@97AT96YD960@:V5Y("(E4R(*``"5'0@(E1T( +XM")4="`B5'0@(E1T(")4="`B5'0@(E1T("-@<"`C8'`@(V!P("-@<"`C8'`@( +XMV!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8 +XM'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@< +XM"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("(4="`C8'`@(V!P( +XM"-@<"`C8'`@(=1T("&4="`C8'`@(V!P("%4="`A%'0@(V!P("-@<"`C8'`@( +XMV!P("-@<"`C8'`@(V!P("#4="`C8'`@(V!P("-@<"`@G'0@(V!P("!L="`C8 +XM'`@(#QT(".D6"0A5;FMN;W=N('-W:71C:``E&%N>0!I>&]F9@!I;6%X8F5L`&ED +XM96QE=&4`;W!O'0`"5L>"!T;R`P>"5L>"`H)6QD*2X*`$]U="!O9B!M96UO +XM7,@=&\@96UA8W,@ +XM8FEN9&EN9W,*````("`@("UD("`@8FEN9"!A;&P@:V5Y4UA<%LE9%T@/3T@)60*`$-C06QT36%P6R5D +XM72`]/2`E9`H`3G5L;"!S=')I;F<@2!B:6YD:6YG,@@(7C(("%XR"`A>,@@(.#0("(HT +XM"`A>,@@(7C(("%XR"`A>,@@(7C(("$4T"`A5-`@(7C(("%XR"`AE-`@(Y#<( +XM"%@W"`A8-P@(O3<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("(8W"`A8-P@( +XM6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(73<("%@W"`A8 +XM-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`CD-P@(6#<("%@W +XM"`B]-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(AC<("%@W"`A8-P@(6#<( +XM"%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`A=-P@(2!A;&EA($("(M\"`B+?`@(BWP( +XM"(M\"`B+?`@(BWP("(M\"`B+?`@(BWP("(M\"`B+?`@(BWP("(M\"`B+?`@( +XMBWP(""R!"`CJ?P@(BWP("-M_"`AX@0@(S8(("(M\"`B+?`@(BWP("(M\"`B+ +XM?`@(BWP("(M\"`C`@@@(HW\("(M\"`B+?`@(ZG\("(M\"`AX?P@(:7\(".I_ +XM"`A:?P@(BWP("$!_"`B+?`@("'\("(M\"`B+?`@(BWP("(M\"`B+?`@(BWP( +XM"(M\"`B+?`@(^7X("'B!"`C9?@@(BWP("(M\"`B+?`@(98,("(M\"`BK?@@( +XMBWP("%5^"`C??0@(CGT("(M\"`CJ?P@(BWP("(M\"`A_?0@(ZG\("'!]"`B+ +XM?`@(4'T("(M\"`@%?0@(BWP("/5\"`B+?`@(Y'P("'B!"`@L9FEL96,`+&-O +XM;&]R`"QR:``L'`@)``` +XM``$;`SMP+@``!````#"+__^,+@``H(S__ZPN``#PC?__S"X``!"0___L+@`` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````````````````````!%R0@(`````"1/"0@````` +XM`````````````````````$`H(RD@0V]P>7)I9VAT("AC*2`Q.3DQ(%1H92!2 +XM96=E;G1S(&]F('1H92!5;FEV97)S:71Y(&]F($-A;&EF;W)N:6$N"B!!;&P@ +XM"0@D-@D(`@````````````````````````#X;PD( +XM``````````````````````````````````````!``$``0`!``$``0`!``$`` +XM0!1`&$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!` +XM`$`4``"``8`0@("``(`0H`&`$*`0@""``(``@`"``(``@``1`!$`$0`1`!$` +XM$0`1`!$`$0`1`(`0H!"``(`0@""``(``%@`6`!8`%@`6`!8`!@`&``8`!@`& +XM``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`&((!`@`"``(``@#*``!H` +XM&@`:`!H`&@`:``H`"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`* +XM``H`"B"`$*``@`"``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$`` +XM0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``(``@`"``(``@`"` +XM`(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(`` +XM@`"``(``@``&``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`& +XM``8`!@`&``8`@``&``8`!@`&``8`!@`&``H`"@`*``H`"@`*``H`"@`*``H` +XM"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`*`(``"@`*``H`"@`*``H`"@`* +XM`````"_*"`@!````[\D("`$````WR@@(``0``/?)"`@"````0,H("``$``#W +XMR0@(`P```$G*"`@`!```]\D("`0```!3R@@(``0``/?)"`@%````80("'#D"`@%````<.0("`4````F````YQP)"$7)"`@`````10("`(````]````Q!X)"'GD"`@%```` +XM>>0("`4````^````)/$("'GD"`@%````>>0("`4````C````?^0("(+D"`@% +XM````@N0("`4````E````G]$("(+D"`@%````@N0("`4````J````.K\("(CD +XM"`@%````B.0("`4`````````CN0("*^^"`@!````K[X("`$`````````D>0( +XM"*^^"`@!````K[X("`$`````````E.0("$7)"`@`````10("$7)"`@`````1!PA@3P<(`$\'"/`J!PAP,`<(8"D'",`O!PCP/`<( +XM("P'"#`L!PA`+`<(4"P'"&`L!PAP+`<(P"H'"*`Z!PAP,0<(<#\'""!0!PB@ +XM,0<(P"L'"&`F!PC@30<(H$T'"+`I!PBP40<(,%$'"&!W!PAP=0<(('8'"+`V +XM!PC0,`<(D#`'"!!H!PB03@<(,%$'"#`Q!PA0*P<($"L'".!.!PB0*P<(H$\' +XM",!/!PCP+P<(8$<'"!!*!P@`+`<(@"<'",!R!PC0)P<(\"<'"%`H!P@04@<( +XM@'0'"`!T!P@0.@<(<"@'"*`L!P@@90<(L#D'"(`X!PB@8P<(P"P'"'!`XX&@$/`1````7````"T````E```````` +XM`"(````G````8`````````````````````````````````````````#@3`D( +XM$0```````````````````-1,"0@5````````````````````]$P)"!,````` +XM```````````````(30D(%````````````````````)`O"0@2```````````` +XM````````($T)"``````````````````````;````3P```$8`````````&P`` +XM`$\```!(`````````!L```!/````1``````````;````3P```$,````````` +XM&P```$\```!"`````````!L```!/````00`````````;````6P```$8````` +XM````&P```%L```!(`````````!L```!;````1``````````;````6P```$,` +XM````````&P```%L```!"`````````!L```!;````00`````````````````` +XM`'P-"0@``0``P````(,-"0@#````0````(H-"0@``````````)$-"0C*!0`` +XM$`B`@)@-"0@``````````'P-"0A``0``@````(,-"0@#````0````(H-"0@` +XM`````````)$-"0B`````'`V`@)@-"0BP\;\!`````'P-"0@```````8``(,- +XM"0@``````````(H-"0@``````````)$-"0@`````@`0``)@-"0@````````` +XM`````````````````&P```!O````9P```&\```!U````=``````````````` +XM80```'4```!T````;P```&P```!O````9P```&\```!U````=``````````V +XM````,````````````````````&$```!U````=````&\```!M````80```'0` +XM``!I````8P````````!H````80```&X```!G````=0```'``````````80`` +XM`"X```!O````=0```'0`````````=````'0```!Y`````````"\```!P```` +XM=````',````O`````````&$```!N````>0````````!S````=````&$```!T +XM````=0```',`````````,``````````Q`````````"T````Q```````````` +XM````````````````````````,````'@````W````9@```&8```!F````9@`` +XM`&8```!F````9@`````````Z`````````%\`````````=````&,```!S```` +XM:`````````!H````;P```&T```!E`````````'4```!S````90```'(````` +XM````9P```'(```!O````=0```'``````````=````&4```!R````;0`````` +XM````````````````````````````````````````=@```&4```!R````0```````````````````````````````````&,```!A````=````&$` +XM``!L````;P```&<`````````3@```$P```!3````4````$$```!4````2``` +XM``````!N````;P```&L```!A````;@```&H```!I`````````'X````O```` +XM+@```&,```!S````:````&0```!I````<@```',````````````````````` +XM``````````````!D````:0```'(```!S````9@```&D```!L````90`````` +XM````````````````````````````````````````0```'P```!N````?````&4```!\````80```"D````_ +XM``!`(```````````````=0```&X```!A````;````&D```!A````````'0```!R````80```&,` +XM``!T``````````````````````````````````````````````!D````=0`` +XM`&X```!I````<0```'4```!E`````````',```!Y````;0```&P```!I```` +XM;@```&L```!S`````````&D```!G````;@```&\```!R````90````````!C +XM````:````&$```!S````90````````!E````>````'````!A````;@```&0` +XM````````````````````````90```&,```!H````;P```%\```!S````=``` +XM`'D```!L````90````````!B````P````````![````(````"X````N````+@```"````!]```` +XM`````'T`````````4````$$```!4````2```````````````9````&4```!F +XM````80```'4```!L````=``````````M````;@`````````M`````````&X` +XM``!O````9P```&P```!O````8@``````````````````````````````;@`` +XM`&\```!N````;P```&T```!A````=````&,```!H```````````````````` +XM`````````````````````&`````@````+@```"X````N````(````&`````` +XM````80```&T```!P````;0````````!T````:0```&T```!E`````````&X` +XM``!O````=````&D```!F````>0`````````````````````````````````` +XM````````````<````'(```!I````;@```'0```!E````>````&D```!T```` +XM=@```&$```!L````=0```&4`````````*````"``````````(````"D````` +XM````(``````````@````?````'P````@`````````"`````F````)@```"`` +XM````````(````'P````@`````````#L````@`````````#L`````````(@`` +XM`"(`````````6P```%T`````````(````#P````\````(``````````@```` +XM/````"``````````(````#X````^`````````"`````^`````````#X````` +XM````(````"X````N````+@`````````E````)0`````````E````*P`````` +XM```E````+0`````````E````(P`````````````````````````````````` +XM`&,```!O````;@```'0```!I````;@```'4```!E```````````````````` +XM``````````````````````````!C````;P```&X```!T````:0```&X```!U +XM````90```%\```!A````<@```&<```!S`````````%\```!P````80```'4` +XM``!S````90````````!@````<````'<```!D````8`````````!F````:0`` +XM`&P```!E````8P`````````````````````````````````````````````` +XM:````&D```!S````=````&,```!H````80```'(```!S```````````````` +XM`````````````````````````'````!R````;P```&T```!P````=````&,` +XM``!H````80```'(```!S``````````````````````````````!H````:0`` +XM`',```!T````;````&D```!T`````````%4```!3````10```%(````````` +XM````````````````3````$\```!'````3@```$$```!-````10````````!' +XM````4@```$\```!5````4````````````````````'<```!O````<@```&0` +XM``!C````:````&$```!R``````````` +XM``!L````:0```',```!T````;````&D```!N````:P```',`````````1``` +XM`$D```!.````1P```"$`````````````0``````````````````````````` +XM``````````!C````;P```'(```!R````90```&,```!T`````````&,```!M +XM````9`````````!A````;````&P`````````90```'(```!A````````1`````@````(```````` +XM``H````H;FEL*0```!0``````````7I2``%\"`$;#`0$B`$``!P````<```` +XMG%S__W`!````00X(A0)"#05%A@2'`P``'````#P```#L7?__1@$```!!#@B% +XM`D(-!46&!(<#```<````7````!Q?__\2`@```$$."(4"0@T%188$AP,``!P` +XM``!\````'&'__X!`@BG@0(,IX$"$*>!`A2G@0(8IX$"'*>!`B" +XMG@0(DIX$"**>!`BRG@0(PIX$"-*>!`CBG@0(\IX$"`*?!`@2GP0((I\$"#*? +XM!`A"GP0(4I\$"&*?!`ARGP0(@I\$")*?!`BBGP0(LI\$",*?!`C2GP0(XI\$ +XM"/*?!`@"H`0($J`$""*@!`@RH`0(0J`$"%*@!`ABH`0(6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I +XM;FD`+G)O9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`0```0````+````!`````@```!E```` +XM`0````8````(FP0("!L``!$```````````````0`````````8`````$````& +XM````')L$"!P;````"0`````````````$````!````&L````!````!@```""D +XM!`@@)```W`P$````````````$`````````!Q`````0````8```#\L`@(_#`$ +XM``P```````````````0`````````=P````$````"````(+$(""`Q!``.;@`` +XM```````````@`````````'\````!`````@```#`?"0@PGP0`+``````````` +XM````!`````````"-`````0````,`````(`D(`*`$`*0M`````````````"`` +XM````````DP````$````"````I$T)"*3-!`"<```````````````$```````` +XM`)T````&`````P```$!."0A`S@0`V`````4`````````!`````@```"F```` +XM`0````,````83PD(&,\$``@```````````````0`````````K0````$````# +XM````($\)""#/!``(```````````````$`````````+0````!`````P```"A/ +XM"0@HSP0`!```````````````!`````````"Y`````0````,````L3PD(+,\$ +XM`$@"``````````````0````$````O@````@````#````@%$)"(#1!`!T6P(` +XM```````````@`````````,,````!``````````````"`T00`60D````````` +XM`````0`````````!`````P``````````````V=H$`,P```````````````$` +X&```````` +X` +Xend +END-of-tcsh.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.sh new file mode 100644 index 0000000000..0456c165e8 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/elfcopy-noops-6.sh @@ -0,0 +1,6 @@ +# $Id: elfcopy-noops-6.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-noops-6 tc/elfcopy-noops-6 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} mcs.o mcs.o.1" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/in/elfcopy-noops-6.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/in/elfcopy-noops-6.in.shar new file mode 100644 index 0000000000..e3eb6cded2 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-6/in/elfcopy-noops-6.in.shar @@ -0,0 +1,107 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# mcs.o.uu +# +echo x - mcs.o.uu +sed 's/^X//' >mcs.o.uu << 'END-of-mcs.o.uu' +Xbegin 644 mcs.o +XM?T5,1@$!`0D```````````$``P`!``````````````!\"0```````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ +XM,=*%P'0),=*#>"``#Y7"R8G0PXUV`%6)Y8/L&(E4)`3'1"0(`````(D$).C\ +XM____,=*%P'0),=*#>!@`#Y7"R8G0PXUV`%6)Y8/L&,=$)`@`````B50D!(D$ +XM).C\____A575E.![/P```#'A1#___\`````QX44____`````(N%$/___XM5"(E$)`2+ +XM0AB)!"3H_/___X7`B840____#X0Z!@``BY40____C46TB40D!(D4).C\____ +XMA<`/A$D&``"+30B+1;2+24")A0S___^)C0C___^+C13___^%R0^%?P(``(M5 +XMS(F5%/___XM%N(/X"'2)A"C`````````#'@H@````` +XM`@``QP0D``(``.C\____BTT(A<")@80````/A$<%``"+A2C___^+E2C___^+ +XM0`B)A3#___\#0A0YA3#___^)A2#___\/@M$```#IZ0$``(M%"(NXC````(M- +XM"(N1B````(N-'/___XT$#SG0%6/___P````")1"0$B10DB8U4 +XM____Z/S___^%P`^$HO[__XN5)/___XM%".B"^O__A6UT86(`+G-T``!4!P```A8``%P'```!"```;`<` +XM``(7``!T!P```0@``(`'```"'@``C`<```(6``"4!P```0@``*0'```"%P`` +XML`<```(6``"X!P```0@``,@'```"%P``T`<```(6``#8!P```0@``.@'```" +X;%P``\`<```(6``#X!P```0@```@(```"%P`` +X` +Xend +END-of-mcs.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.sh new file mode 100644 index 0000000000..ceb7bce0b2 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/elfcopy-noops-7.sh @@ -0,0 +1,6 @@ +# $Id: elfcopy-noops-7.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-noops-7 tc/elfcopy-noops-7 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} sections.o.debug sections.o.debug.1" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/in/elfcopy-noops-7.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/in/elfcopy-noops-7.in.shar new file mode 100644 index 0000000000..959c4dce85 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-7/in/elfcopy-noops-7.in.shar @@ -0,0 +1,708 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# sections.o.debug.uu +# +echo x - sections.o.debug.uu +sed 's/^X//' >sections.o.debug.uu << 'END-of-sections.o.debug.uu' +Xbegin 644 sections.o.debug +XM?T5,1@$!`0D```````````$``P`!``````````````!86@```````#0````` +XM`"@`&0`6`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R +XM''<%.T$07@`````BT80BU84QT6X +XM`P```,=%O`````")1`````` +XMQT7<`````(M&"(D$).C\____A<")PP^$Z@```/9'3!`/A(\```"+1AB+5AR) +XM1=2-1;2)5=B)1"0$BT8(B00DZ/S___^%P`^$W@```,<#`0```,=#!`````"+ +XM1@R)0PB+1AB+5AS'0PP`````QT,0`````(E#%(E3&,=#'`$```#'0R`!```` +XMBT8(B00DZ/S___^)1"0$BT<8B00DZ/S___^%P`^$I0```(/$3%M>7UW#C70F +XM`(M&&(M6'(M.#(/`\(/2_XE&&(E6'(E$)`B-01")1"0$B0PDZ/S____I1/__ +XM_\<$)/_____H_/___\=$)`0`````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0>````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0W +XM````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`15````QP0D1@`` +XM`(E$)`CH_/___XUV`%6)Y5=64X/L3(MU"(M>?(7;='>-?;2)?"0$BT,(B00D +XMZ/S___^%P'1[BP.)1"0$BT9$B00DZ/S___^+5=R%THE%M'0LBT9\A7UW#QT7<`````.O,QP0D +XM_____^C\____QT0D!'(```#'!"1&````B40D".C\____QP0D_____^C\____ +XMQT0D!#<```#'!"1&````B40D".C\____B00DZ/S____'1"0$C@```,<$)$8` +XM``")1"0(Z/S___^-="8`58GE@^P8B77\B=:)7?B+6$2+0PR%P'08B70D!(D< +XM).C\____BUWXBW7\B>Q=PXGVQT0D!*4```")'"3H_/___\=$)`2F````B1PD +XMZ/S____'1"0$K@```(D<).C\____QT0D!+8```")'"3H_/___^NFC;0F```` +XM`(V\)P````!5B>575E.#[$R+10B+6'R%VW4)ZQB+6TB%VW01BS.Y"@```+^V +XM````_/.F=>B+50B+0B)64B)04R+0TR)"(U!2(E#3(D\).C\____A<")P@^$Q@```,<``0```,=` +XM!`````#'0`P`````QT`0`````(M&!(E""(M&",="&`````#'0AP!````QT(@ +XM`0```(E"%(U5M(E4)`2)/"3H_/___X7`#X27````QT6X`0```(M%"(L6Z$O^ +XM__^-1;2)1"0$B3PDZ/S___^%P`^$DP```(MV#(7V#X7I_O__@\1,6UY?7````QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`3E````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0W````QP0D1@```(E$)`CH_/___XVV`````(V\)P````!5B>56 +XM4X/L$(MU"(M>1(7;=`>+3@R%R71U,=OK4XUV`(M&"(D$).C\____A<")P0^$ +XMG0```(M61(72=5F+`XM3!(D!BT,,B5$$BU,0B4$,BT,(B5$0BU,8B4$(BT,< +XMB4$7564X'LD````(MU$(U%N(E$)`2+10R)!"3H_/__ +XM_X7`#X2E````C9UX____B5PD!(DT).C\____A<`/A*\```"+1;B+512)A7C_ +XM__^+1;R)A7S___^+1<")18"+1<2)182+1")1:"+1>2)1:2+1>B)1:B+1>R)1:R+1?")1;"+ +XM1?2)1;2+10CHG?O__XE<)`2)-"3H_/___X7`=%*!Q)````!;7EW#QP0D____ +XM_^C\____QT0D!!P!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D +XM!#H!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D!%@!``#'!"1& +XM````B40D".C\____C;0F`````%6)Y5=64X/L?(M%"(MX?(7_#X0N`0``QT6H +XM`````,=%K`````#I_````(VV`````(MW%#MUK(M?$`^"$0$``'<).UVH#X(& +XM`0``BT<\A<"0=4^+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2) +XM5"0$Z/S___^)59R+39R)19@/K\8/K\L!P8M%F/?CC301B4<0B7<4BUVHBW6L +XMBT=`A<`/A88```"+5S"+3S2)T(/P"`G(=!*)R`G0=`R+7Q"+=Q0#7Q@3=QR- +XM5;")5"0$BT<(B00DZ/S___^%P`^$P0```(M'$(M7%(E%R(E5S(M'&(M7'(E% +XMT(U%L(E5U(E$)`2+1PB)!"3H_/___X7`#X2S````BW](A?]T)8E=J(EUK(M% +XMK`M%J`^%_O[__XM?$(MW%`-?&!-W'(M_2(7_==N#Q'Q;7E]=PXUV`(M'/(7` +XM=4.+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2)5"0$Z/S___^) +XM592+392)19`/K\8/K\L!P8M%D.GV_O__QP0D`````.C\____ZZ_'!"3_____ +XMZ/S____'1"0$564X/L4(MU"(U%N(E$)`2+1A2)!"3H +XM_/___X7`#X2G````QT0D!%@```#'!"0!````Z/S___^%P(G##X31````BT7@ +XMBU7DB4,0B5,4BT9\N@$```"%P'06,-*-=@"#>$`!BT!(@](`A7LCBULLA=MT'(L#B30D +XMB40D!.C\____A!@`#Y7"R8G0PXUV`%6)Y8/L&,=$ +XM)`@`````B50D!(D$).C\____A575E.#[&S'1"0$6````,<$)`$```#H_/___XM5"(7` +XMB4)$#X1S`P``QP"V````QT`$`````,=`&`````#'0!P`````QT`H`0```,=` +XM+`````#'0#P`````QT`P`P```,=`-`````"+50B-1?")1"0$BT(4B00DZ/S_ +XM__^%P`^$+`,``,=%H`````#I$0$``(MUG+^F````N0@```#SI@^%K@$``(M% +XM"(-X2`$/A.\```#'1"0$6````,<$)`$```#H_/___X7`#X3.`@``B<.+19R) +XM`XM5H(E3!(M%R(M5S(E#$(E3%(M%T(M5U(E#&(E3'(M%X(M5Y(E#*(E3+(M% +XMM,=#-`````")0S"+50B)7"0$B10DZ/S___^)0SR+50B+0AB)!"3H_/___X7` +XMB4,(#X0=`@``BT6@B00DZ/S___^%P(E#.`^$*P(``(MUG+D*````O[8```#\ +XM\Z8/A_^__^+`XM5"(E$)`R+0PB) +XM1"0(BT,$B10DB40D!.C\____Z1#___^+=9R_K@```+D(````\Z8/A#W^__^+ +XM50B+0C2%P'4+BT(XA<`/A#7^__^+50B+19S'1"0(`````(D4)(E$)`3H_/__ +XM_XM5"(MZ-(7_=`^%P'0+BW`DA?8/A?'^__^+50B+6CB%VW03A<`/A-_^__^+ +XM2!R%R0^$U/[__XMUG+D*````O[8```#\\Z8/DL`/E\(HP@^^PH7`#X0H____ +XMZ;W]___H_/___X7`B?8/A=````"#Q&Q;7E]=P\<$)/_____H_/___\=$)`3^ +XM`0``QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0:`@``QP0D1@`` +XM`(E$)`CH_/___\<$)/_____H_/___\=$)`0P`@``QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`1&`@``QP0D1@```(E$)`CH_/___\=$)`2K`0`` +XMQP0D1@```.C\____QP0D_____^C\____QT0D!.,!``#'!"1&````B40D".C\ +XM____B00DZ/S____'1"0$C@```,<$)$8```")1"0(Z/S___^-=@"-O"<````` +XM58GE5U93C3P0@^P,.?AS;8G#ZS&A`````(7`=6B+%0````"+0@B#Z`&%P(E" +XM"`^(GP```(L"Q@`*@\`!B0*#PP$Y^W0X#[83A-)TR*$`````A$N+`8GR@\,!B!"#P`$Y^XD!=R,````BT4(BT!\A<")18!T5XU5Y(F5 +XM?/___^L-BTV`BTE(AF+&;^F````N0@```#\B=[S +XMIG4MBUT(]D-,0'7-B1PDZ/S___^#2TQ`BTV`BTE(A +XM7UW#OZX```"Y"````(G>\Z9TP_R_M@```+D*````B=[SIG2(BT4(@WA(`0^$ +XMF````(M%"(G:Z!WZ__^%P`^$-@,``#';QT60`````,=%H`````#K08UV`(M% +XMH`-#%(D$).C\____B460BW60A?8/A/0#``"+4PB+0Q2+39`#3:")5"0$B40D +XM"(D,).C\____BU,4`56@BTV`B5PD!(M!!(D$).C\____A<")PP^$EP```(M] +XMD(7_=9^+0Q2)!"3H_/___XE%D.N@BU6`BT(P@_`)"T(T#X56____C4VDB4PD +XM!(M"!(D$).C\____A<`/A+P%``"+70CV0TP0#X64`P``BT-\AC^___H_/___X7`#X5P!```BTV0A_S__XM=@(M%"(L3Z!KW__^%P`^$,O___^DA_O__BUV0BT64B7PD"(E< +XM)`2)!"3H_/___XM5H(M-G(T$%\8$"`"#P`&)1:#IO?[__XM%"(G:Z*7V__^% +XMP`^$[?[__^FS_/__D(VT)@````#H^_K__^E<____BU60BT6<`T6@B7PD"(E4 +XM)`2)!"3H_/___P%]H.F)_O__BU6`BTT(QT0D"`````"+`HD,)(E$)`3H_/__ +XM_XMP#(DT).C\____B70D!(G#B40D"(M%G`-%H(D$).C\____BT6<`UV@Q@0# +XM`(/#`8E=H.E*_O__BU6@BTV0BUVD< +XM_?__QT0D!($"``#'!"1&````Z/S___^A`````,<$)`H```")1"0$Z/S____I +XM%OO__XM-"(M%S(M1/#M".'0IBT6`BQCI@_O__XE4)`3'!"0*````Z/S____I +XMZ?K__XM-@(L9Z63[__\Q_\=%B`````#'180`````BUV$BU6`B5PD!(M"!(D$ +XM).C\____A<")180/A$4!``"+182-7>2)7"0(QT0D!`````")!"3H_/___SN% +XM?/___P^%^P```(M5"(M=\(M"0(M`!(D$).C\____BTT(B5PD"(E$)`2+012) +XM!"3H_/___X7`#X2E````BUT(B40D!(D<).C\____A<`/A''___^#>Q`!=#+' +XM!"1`````Z/S___^%P'1DB46(BU7HBTV(BT7DB5$$BU7PB0&+1>R)40R)00CI +XM.?___\<$)"````#H_/___X7`=#*)QXM%Y(D'BT7LB4<$Z1?___^)!"3H_/__ +XM_\=$)`0#`0``QP0D1@```(E$)`CH_/___\=$)`1S`@``QP0D1@```.C\____ +XMQP0D_____^C\____QT0D!!H"``#'!"1&````B40D".C\____QP0D_____^C\ +XM____QT0D!%P"``#'!"1&````B40D".C\____Z/S___^%P`^%=____XM-"(-Y +XM$`&)]G1[BU6(BT6`B5`,BTT(QT0D#`$```#'1"0(`````,=$)`0,````BT$8 +XMB00DZ/S___^+78#'0QP`````QT-$`0```(E#&(M%@(L8Z8KY__^+58"+&NF` +XM^?__QP0D_____^C\____QT0D!)$!``#'!"1&````B40D".C\____BUV`B7L, +XMZX8````!$0$E#A,+`PX;#A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+.PM) +XM$P``!"0`"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8`21,` +XM``D3`0,."PLZ"SL+`1,```H-``,..@L["TD3.`H```L-``,(.@L["TD3.`H` +XM``P5`2<,21,!$P``#04`21,```X3``,./`P```\!`4D3`1,``!`A`$D3+PL` +XM`!$3`0L+.@L["P$3```2%@`#"#H+.PM)$P``$P0!"PLZ"SL+`1,``!0H``,. +XM'`T``!4N`0,..@L["R<,$0$2`4`&`1,``!8%``,(.@L["TD3`@8``!4P````,W!@`` +XM!6-W````!P2B````!P3M````"*(````#Z`(```7DEP````/"`0```B^P```` +XM"94'```(`D8Q`0``"FX$```"1S$!```"(P`*4P````"(SP*O0@` +XM``)\VP(```(C0`IW"````GWK`@```B-#"U]L8@`"@`@!```"(T0*L`8```*# +XM3`````(C3`IJ`@```H3]`````B-0``P!3````&D"```-O@`````'!%D"```, +XM`4P```")`@``#;X````-X0````U,``````<$;P(```P!_0```*D"```-O@`` +XM``W]````#4P`````!P2/`@``#`%,````R0(```V^````#><````-3``````' +XM!*\"```."P````$'!,\"```/+````.L"```0NP````(`#RP```#[`@``$+L` +XM``````.5"````H4W`0```Z\'```&)LL````#G0````8JRP````\L````+`,` +XM`!"[````#P`1"`9Z40,```K/!0``!GL&`P```B,`"FD#```&?!$#```"(P0` +XM`WX$```&?2P#```#``````%B`,```(C"``#D04```>&"P4``!)%;&8` +XM""9&!0``#B$(```!`QX!```()U<%```.,@$```$3!`@V]@4``!0@!0```!2V +XM!````12!`P```A1?`P```Q1+!```!!2:"```!11P`P``!A0^````!Q13`P`` +XM"!2+`P``"10S!```"A1`!P``"Q0E!@``#!3=`@``#13F!```#A2K"```#Q0$ +XM`0``$!1Z`@``$13V`@``$A2*,&```"(P``"?D%```P"&BC +XM!@``"KD&```(;-8````"(P`*P00```AMO@````(C"`I0!@``"&[6`````B,, +XM"E$````(;]8````"(Q0*[P(```AP]@4```(C'`KE!@``"'%>`````B,@"NH` +XM```(=JD&```"(R0*<`<```AW7@````(C*`H4!```"'@!!@```B,L``<$&`8` +XM``<$3`4```-?!P``"'D8!@```^`````)+F`$```#N`$```DP``4```/&!0`` +XM"3(P!0``$00*)/(&```*&P8```HD&P<```(C```)5@0```@*(1L'```*EP8` +XM``HBYP````(C``IL`0``"B3;!@```B,$``<$\@8``!$$"C8X!P``"AL&```* +XM-NT'```"(P``";L%```P"BCM!P``"I<&```**><````"(P`*#`4```HJYP`` +XM``(C!`IS!0``"BOG`````B,("IX#```*+.<````"(PP+861D``HN3`````(C +XM$`K;`0``"B],`````B,4"OX#```*,$P````"(Q@*AP$```HQ3`````(C'`K@ +XM!0``"C),`````B,@"B0````*,TP````"(R0*#00```HT3`````(C*`JG!@`` +XM"C8A!P```B,L``<$.`<``!$$"C\*"```"AL&```*/T\(```"(P``"74!```0 +XM"CI/"```"I<&```*.^$````"(P`*:`<```H\X0````(C!`K'!```"CWR```` +XM`B,("A0````*/_,'```"(PP`!P0*"```$0@*4GH(```*\`````I25@D```(C +XM``J=`0``"E)<"0```B,$``F`!@``6`I#5@D```J7!@``"D3G`````B,`"VES +XM``I%J08```(C!`MOT!```("E^P"0``"L$&```*7U8)```"(P`*I@<` +XM``I?7`D```(C!``1!`I@QPD```H;!@``"F`V"@```B,```G`````,`I7-@H` +XM``MO9F8`"EC6`````B,`"V9S>@`*6=8````"(P@+;7-Z``I:U@````(C$`H0 +XM!P``"EO6`````B,8"B0````*74P````"(R`*?P<```I?APD```(C)`H)`P`` +XM"F"P"0```B,L``<$QPD``!,$"H1C"@``%*P#````%+8````!%)4$```"%)D" +XM```#%(@&```$`!$("IB("@``"@@"```*F#8*```"(P`*SP,```J8B`H```(C +XM!``'!#8*```1"`J9LPH```H(`@``"IGM!P```B,`"L\#```*F;,*```"(P0` +XM!P3M!P``$0@*FMX*```*"`(```J:3P@```(C``K/`P``"IK>"@```B,$``<$ +XM3P@``!$("IP)"P``"@@"```*G!L'```"(P`*SP,```J<"0L```(C!``'!!L' +XM```1"`J>-`L```H(`@``"IX;!P```B,`"L\#```*G@D+```"(P0`$0@*H%D+ +XM```*P08```J@5@D```(C``JF!P``"J!<"0```B,$`!$$"J)P"P``"E\%```* +XMHE8)```"(P``"3\"``"("F8�``"D0!```*9^<````"(P`*L`0```IJ3``` +XM``(C!`HX`@``"FM,`````B,("VEE8P`*;4P````"(PP+;V5C``IN3`````(C +XM$`ME:6X`"F\�```B,4"GL&```*<`8-```"(Q@*I0,```IR3`````(C'`HW +XM````"G-,`````B,@"E0(```*>4P````"(R0*_08```IZ3`````(C*`HN`P`` +XM"GM,`````B,L"J8!```*?$P````"(S`*FP4```I]3`````(C-`I(!0``"GY, +XM`````B,X"M8"```*@%8)```"(SP*)@@```J!5@D```(C0`H_!0``"H)6"0`` +XM`B-$"M\'```*BCP*```"(T@*$@,```J33`````(C3`H;!```"I8Q`0```B-0 +XM"AX````*F&,*```"(U0*7@0```J9C@H```(C7`K/`@``"IJY"@```B-D"B8! +XM```*G.0*```"(VP*60$```J>#PL```(C=`I_!P``"J`T"P```B-\"E@'```* +XMHED+```#(X0!``<$.P4``!5D"````9H!`````'0`````````3@T``!9E8W`` +XM`9E.#0``+````!9S96,``9E6"0``50```!=S``&;5@D```%1``<$<`L``!@! +XM,@4```$-`P&`````;0(``(D```"L#0``&65C<``!#`-.#0``M0```!IS``$. +XM`U8)``#K````&[<#```!#P.L#0``"0$``!QS:``!$`/%!@```Y&L?P`'!*\& +XM```8`2L````!WP(!<`(``'P#```]`0``)0X``!EE8W```=X"3@T``&D!```: +XM("3````.8!```=3@,```'B`DP`````'@L&```!T`(!@`,``/(#```$ +XM`@``;0X``!EE8W```<\"3@T``#`"```?EP8```'/`N<```!#`@``&G,``=$" +XM5@D``&P"````&`%`!@```9D"`0`$```#!@``B@(``.\.```996-P``&8`DX- +XM``"V`@``&G-A``&:`D\(``#6`@``&Z@````!FP)6"0``]`(``"!S``&;`E8) +XM```:;V0``9P"K`T``!(#```:;W,``9T"J08``#L#```<;W-H``&>`L4&```# +XMD:Q_`!@!?0$```%T`@$0!@``)@<``%D#``!&#P``&7,``7,"5@D``(4#```: +XM:60``74"K`T``-(#```:;V0``74"K`T``/L#```;J00```%V`DP````D!``` +XM`!@!\00```%@`@$P!P``:0@``$($``"_#P``&65C<``!7P).#0``;@0``!EI +XM@@````DR0$```%5`4P```!@ +XM#```E@P``(T(``!Q$0``%F5C<``!5$X-``"Y"```(I<&```!5.<```#,"``` +XM(W-A8P`!5NT'``#?"````"6Z!P```38!3`````&F$0``)F5C<``!-4X-```G +XMEP8```$UYP```"@I!(``#%?8P`"AP%,````,5]P +XM``*'`7@2````!P3[`@``'L,(```!'P(!H!```(@1``!X"@```1,``!ED``$> +XM`N<```"D"@``&7-Z``$>`O(```#-"@``&F,``2`"YP```/8*```R3Q(``"`` +XM```!)`+A$@``,VP2```4"P``+6$2````-$\2```X`````28",VP2```]"P`` +XM,V$2``!Q"P`````U$0$```%3`0$!I1,``#%E8W```5(!3@T``#%S``%2`58) +XM```@=``!5`%6"0``'9<&```!50'G````(&ES:``!5@'%!@``(')E;``!5P'0 +XM!@``'5D%```!6`&E$P``'?<&```!60&K$P``(&ED``%:`:P-```=J00```%; +XM`4P````@:0`!6P%,````';4%```!6P%,````(&-A<``!6P%,``````<$40,` +XM``<$,`4``"4C!P```7D!3`````'9$P``)F5C<``!>$X-```GEP8```%XYP`` +XM```UUP0```'7`0$!>A0``#%E8W```=8!3@T``#%S``'6`58)```@T'```=!P0```'9`?(````=`@(```'9`?(````@<``!V0'R````(&QE;@`! +XMV0'R````(&(``=H!X0```"!C``':`>$````@9``!V@'A````('-R8P`!V@'A +XM````(&5N9``!V@'A````'?D````!VP%,`````#![!0```4`"`;X````!SQ0` +XM`#%S``$_`E8)```VQP0```$_`L\4```@:60``4$"K`T``"!B``%"`N$````@ +XM<5```M&Q,``"T/$P``-Y`````O)1,``.8+```O +XM+Q,``!H,```X.Q,```.1G'\X1Q,```*17"]3$P``.`P``#A?$P```W6(?SAK +XM$P```W6$?R]V$P``Q`P``#F"$P``.8P3```YF!,`````,K$3```8`0```4,! +XM!A8``#/-$P``^`P``"W"$P```#+9$P``,`$```%$`:\6```M\Q,``"WG$P`` +XM-V`!```O_1,``!8-```O"10``#0-```Y%10``#DA%```+RL4``"1#0``.3<4 +XM```O010``/$-```O2Q0``#8.```Y510``#AA%````W6,?SEM%```-'H4``#P +XM`0```=T!+984```MC!0``#<0`@``+Z(4``"6#@``.:T4```YMQ0``"_"%``` +XM(@\````````ZU10``(L4``"W%````4@!X18``"WQ%```+>84```NI!0``+<4 +XM```O_!0``$L/`````#0(%0``0`(```%)`2T6%0``-W`"```O(!4``'0/```O +XM*Q4``+X/```T3Q(``+`"```!.P(S;!(``-P/```M81(````````[9`0```** +XM>!(```$!/$<"```"H`%,`````0$`<`0```(`N`````$!^PX*``$!`0$````! +XM+W5S7,``'-E8W1I;VYS+F,`````K?P\/`#00CAE0@L"!,(+`AT",IL#40BW9@@ZY0-L<68(.M<9@RPB=!`(#XGX(5;H$`0.9?P(N`;H#Y0#%`YM_J<>?""V.@`-V1P,DQ0-BJ0,* +XM[P@6`[U^Q0/2`P(G`?ZL"*H#=V,(JG(#\WWO`Q\('0B2QG((<`,)C;@#YP$( +XM*U8#B7]_"%T(=0@MD0@>9)HZ90@>ME>4-3WFSHX#"P@K`VF;`Q"@I(&9A:6QE9#H@)7,`-C8X(&=E;&9?9V5T6UT86(`+G-T@P```$`4```````````8`P``'H,```!`%(``````````'P, +XM``"(#````0!0D@P``)4,```!`%```````````*`,``"A#````@!T!*$,``"C +XM#````@!T"*,,``"6$````@!U"```````````H`P``,L,```"`)$`RPP``)80 +XM```"`'4(```````````R#0``6`\```$`4Y#P``K@\```$`4'80 +XM``!^$````0!0``````````!##@``1@X```$`4$4/``""#P```0!0```````` +XM``"@$```H1````(`=`2A$```HQ````(`=`BC$```B!$```(`=0@````````` +XM`*`0``"Y$````0!0Y1```/$0```!`%`=$0``)1$```$`4```````````H!`` +XM`+00```!`%+E$```Z!````$`4AT1```E$0```0!2``````````"R$```(1$` +XM``$`4R41``"($0```0!3``````````##$```Z!````$`4AT1```E$0```0!2 +XM%@```0!7MA8``,L6```!`%?7%@``KQ@```$`5]T8``#E&````0!7```` +XM``````#.%P``UA<```$`4%$8``!H&````0!0:Q@``(D8```!`%#=&```Y1@` +XM``$`4```````````/A(``$,2```!`%*&%0``BQ4```$`4@``````````ZA4` +XM`/(5```!`%!<%@``7!8```$`4```````````M!$``(P3```#`'6@?XP3``"4 +XM$P```0!2E!,``#T6```#`'6@?ST6``!`%@```0!20!8``&L6```#`'6@?VL6 +XM``!P%@```0!28%0``'Q8```$`5X06``"> +XM%@```0!7MA8``,L6```!`%?.%P``[A<```$`5P``````````M!$``-\3```# +XM`'60?]\3```"%````0!0`A0``*H5```#`'60?ZH5``"P%0```0!0L!4``.48 +XM```#`'60?P``````````M!$``-H1```!`%8`$@``"!(```$`5M,3```Y%0`` +XM`0!64Q4``($5```!`%:8%0``ZA4```$`5H06``">%@```0!6MA8``,L6```! +XM`%;.%P``[A<```$`5@``````````31(``-$2```!`%-1$P``Z!,```$`4_83 +XM```:%````0!3*Q0``$04```!`%-4%```@Q0```$`4SD5```\%0```0!34Q4` +XM`%85```!`%.J%0``^!4```$`4Q\6```H%@```0!3/18``&<6```!`%-P%@`` +XMA!8```$`4\X7```"&````0!3``````````!8$P``=Q,```$`4#D5```_%0`` +XM`0!0SA<``-87```!`%```````````+01``#'$0```0!0`!(```L2```!`%"F +XM%```KQ0```$`4```````````M!$``,T1```!`%,`$@``!Q(```$`4],4```Y +XM%0```0!3A!8``)X6```!`%.V%@``RQ8```$`4\X7``#N%P```0!3```````` +XM``#_%```"Q4```$`4,X7``#6%P```0!0``````````"T$0``[Q$```$`4@`2 +XM```^$@```0!2T1(``-02```!`%(9%0``.14```$`4K86``#&%@```0!2```` +XM``````"W`````@``````0Q<``%0-``!S971?5]S:&1R`+\/``!R97-Y;F-?$```%@``MA8``.,2``!1$P`` +XM``````````#U$@``41,``,48``#E&```D1@``+D8``!/&```:Q@``#(8``!* +XM&```#A@``"88``"X%P``SA<``(87``"L%P``;!<``'H7``!5%P``71<``"X7 +XM```Q%P``'Q<``"L7``#_%@``!1<``/H6``#\%@``U18``.46``">%@``MA8` +XM````````````.1(``&`2``"!%0``F!4`````````````8!(``-$2``#N%P`` +XM`A@``*H5``"$%@``.14``($5``!1$P``@!0`````````````8!(``-$2``#N +XM%P```A@``'`6``"$%@``^!4``#T6``#R%0``]A4``.<5``#J%0``JA4``,L5 +XM``!&%0``@14``&$4``"`%```/A0``%04```B%```*Q0``!<4```:%```LA,` +XM`!04``"9$P``J!,``)03``"6$P``@1,``(P3``!1$P``=!,````````````` +XM8!(``-$2``!P%@``A!8``%$3``!>$P````````````!Q$@``GA(``'`6``"$ +XM%@``5A,``%X3``"T$@``P1(``+`2``"R$@````````````"W%```.14``,X7 +XM``#N%P``MA8``-46``"$%@``GA8``)@5``"J%0````````````"W%```X!0` +XM`-87``#N%P``MA8``-46``"8%0``JA4``/T4```Y%0``]A0``/@4``#R%``` +XM]!0`````````````&14``#D5``"V%@``U18`````````````16QF-C1?061D +XM<@!?7W-&24Q%6`!S861D7VQI6U?5]D871A`&-O<'D`95]E;G1R>0!U:6YT,S)?=`!T +XM<65?<')E=@!S96-T:6]N0!C;VUP@!R96YA;64` +XM9%]N97AT`'9?F5? +XM=`!I7!E +XM`&1?=F5R7!E`'5N```"````!<````(````!`````@```!>`````0`` +XM````````````"C@``#````````````````$`````````9P````$````R```` +XM`````#HX``":`@`````````````!`````0```'8````!````,@````````#4 +XM.@``+0``````````````!`````$```")`````0``````````````!#L``.0! +XM``````````````0`````````A0````D``````````````&!X``#P````%P`` +XM``T````$````"````)8````!``````````````#H/```&Q`````````````` +XM`0````````"E`````0```````````````TT``+L```````````````$````` +XM````H0````D``````````````%!Y```(````%P```!`````$````"````+D` +XM```!``````````````"^30``(````````````````0````````"U````"0`` +XM````````````6'D``!`````7````$@````0````(````R`````$````````` +XM`````-Y-``#(`@`````````````!`````````-8````!````,`````````"F +XM4```S@@``````````````0````$````1`````P``````````````=%D``.$` +XM``````````````$``````````0````(``````````````$!>```P!```&``` +XM`!8````$````$`````D````#``````````````!P8@``8`(````````````` +XM`0```````````````````````````````0``````````````!`#Q_P`````` +XM``````````,``0`````````````````#``,``````````````````P`$```` +XM``````````````,`!0`````````````````#``8``````````````````P`( +XM``P`````````=`````(``0`````````````````#``L`'P```(`#``!R```` +XM`@`!``````````````````,`#``O````,`P``"T````"``$`0P```&`,```V +XM`````@`!`%4```"@$```Z`````(``0`````````````````#``T````````` +XM`````````P`/``````````````````,`$``````````````````#`!(````` +XM`````````````P`4``````````````````,`%0`````````````````#``H` +XM8````(````#M`0``$@`!`&T``````````````!````!Z```````````````0 +XM````A@``````````````$````)<``````````````!````"B```````````` +XM```0````L@``````````````$````+H``````````````!````#%```````` +XM```````0````R@```'`"```,`0``$@`!`-8``````````````!````#D```` +XM```````````0````[@``````````````$````/\`````!````P(``!(``0`/ +XM`0`````````````0````&@$`````````````$````"$!`````````````!`` +XM```E`0``$`8``!8!```2``$`+P$`````````````$````#L!```P!P``.0$` +XM`!(``0!%`0`````````````0````3P$``'`(``#P`0``$@`!`%\!```````` +XM`````!````!E`0``8`H``"@!```2``$`<@$`````````````$````'\!```` +XM`````````!````"*`0``D`L``)<````2``$`F0$`````````````$````*`! +XM`````````````!````"G`0``H`P``/8#```2``$`L@$`````````````$``` +XM`,(!`````````````!````#4`0`````````````0````X`$````````````` +XM$````.L!`````````````!````#X`0`````````````0`````@(````````` +XM````$`````<"`````````````!`````/`@``D!$``%4'```2``$`'`(````` +XM````````$````"H"`````````````!`````Q`@`````````````0````.`(` +XM````````````$````$`"`````````````!````!,`@`````````````0```` +XM`'-E8W1I;VYS+F,`:6YS97)T7W1O7W-E8U]L:7-T`&%D9%]T;U]S:'-T5]S:&1R`%]?=61I=F1I,P!R97-Y;F-?'1S8VX`96QF7W-T```)`@```AT``!$"```!"0``(0(```(>```M`@```AT``#4"```!"0`` +XM10(```(>``!1`@```AT``%D"```!"0``:0(```(>``"1`@```A<``*8"```" +XM(```TP(```(:``#K`@```AD``/L"```"(0``'`,```(=```D`P```0D``#0# +XM```"'@``0`,```(=``!(`P```0D``%@#```"'@``8`,```(=``!H`P```0D` +XM`'@#```"'@``H`,```(B``"T`P```0D``+P#```"(@``Q`,```$)``#,`P`` +XM`B(``-0#```!"0``W`,```(B``#D`P```0D``.P#```"(@``)`0```$)``!* +XM!````B0``&@$```")0``PP0```(8```8!0```A<``$`%```"&0``9P4```(= +XM``!O!0```0D``'\%```"'@``AP4```$)``"3!0```B8``)\%```"'0``IP4` +XM``$)``"W!0```AX``,,%```"'0``RP4```$)``#;!0```AX``.<%```"'0`` +XM[P4```$)``#_!0```AX``#<&```"&```BP8```(H``"6!@```B$``.H&```" +XM'0``\@8```$)```"!P```AX```H'```"'0``$@<```$)```B!P```AX``$P' +XM```"%P``9@<```(7``#K!P```AD```4(```"'0``#0@```$)```="````AX` +XM`"D(```"'0``,0@```$)``!!"````AX``$T(```"'0``50@```$)``!E"``` +XM`AX``.@(```"*@``2PD```(7``!]"0```AD``.T)```"*@``#0H```$+```2 +XM"@```BP``"`*```"'0``*`H```$)```X"@```AX``$0*```"'0``3`H```$) +XM``!<"@```AX``'D*```"+@``E0H```(E``#L"@```B\``#0+```"'0``/`L` +XM``$)``!,"P```AX``%@+```"'0``8`L```$)``!P"P```AX``'@+```!"0`` +XMA`L```(>``"Y"P```C$``-P+```",@``%PP```$)```C#````AX``$8,```" +XM,```=@P```(P``"Y#````B4``,T,```!"0``&@T```(T```V#0```0D``&0- +XM```")0``N0T```(U``#*#0```B0``.`-```"&@``^`T```$)```)#@```0D` +XM`"4.```!"0``5`X```(V``!Q#@```A<``)4.```"-P``K0X```$)``#L#@`` +XM`BD``/D.```!"0``-0\```(P``!X#P```0D``)@/```"(0``M@\```(=``"^ +XM#P```0D``,X/```"'@``V@\```(=``#B#P```0D``/(/```"'@``_@\```(= +XM```&$````0D``!80```"'@``(A````(=```J$````0D``#H0```"'@``0A`` +XM``$)``!.$````B8``%H0```"'0``8A````$)``!R$````AX``'H0```"'0`` +XM@A````$)``"2$````AX``+40```!.```OQ````$Y``#M$````3@``/<0```! +XM.0``)A$```$Y```V$0```CH``$$1```!.0``4!$```(Z``!J$0```CL``'\1 +XM```".P``SA$```$)``#K$0```CT```P2```!"0``'1(```$)``!J$@```C(` +XM`)02```"/@``K!(```(H``#($@```C(``/$2```"%P``4A,```(A``"0$P`` +XM`C(``!L4```"/P``-A0```(Q``"'%````B<``*`4```",```[A0```(H``#Y +XM%````B$```<5```!.```%14```$Y``!E%0```D```+\5```"0```XQ4```(P +XM``#N%0```C\```86```"0```-!8```(^``!5%@```C```&`6```"/P``=!8` +XM``$)``"`%@```B8``(46```!.0``E18```(Z``#"%@```CL``/86```"*``` +XM&Q<```)!```[%P```AH``%$7```"-P``:!<```)"``""%P```C(``+07```" +XM,@``TA<```(=``#:%P```0D``.H7```"'@``\A<```$)``#^%P```B8```H8 +XM```"'0``$A@```$)```B&````AX``"X8```"'0``-A@```$)``!&&````AX` +XM`$L8```"(0``C1@```(O``#!&````AT``,D8```!"0``V1@```(>```&```` +XM`04```P````!%```$0````$4```5`````10``!D````!`@``'0````$"```A +XM`````0<``"@````!%```+P````$4```V`````10``#L````!%```2`````$4 +XM``!4`````10``&$````!%```9@````$4``!S`````10``'@````!%```A0`` +XM``$4``",`````10``),````!%```F`````$4``"E`````10``*P````!%``` +XML0````$4``#!`````10``,P````!%```UP````$4``#S`````10``/X````! +XM%```"0$```$4```5`0```10``",!```!%```.`$```$4``!K`0```10``'D! +XM```!%```E0$```$4``"C`0```10``+$!```!%```OP$```$4``#-`0```10` +XM`-L!```!%```]P$```$4```3`@```10``"$"```!%```/0(```$4``!+`@`` +XM`10``-`"```!%```_`(```$4```'`P```10``!(#```!%```-0,```$4``!# +XM`P```10``%(#```!%```70,```$4``!H`P```10``',#```!%```?@,```$4 +XM``")`P```10``)P#```!%```J@,```$4``"X`P```10``,8#```!%```U`,` +XM``$4``#B`P```10``/`#```!%```_@,```$4```,!````10``!H$```!%``` +XM*`0```$4```V!````10``$0$```!%```4@0```$4``!A!````10``'0$```! +XM%```@@0```$4``"0!````10``)X$```!%```K`0```$4``"Z!````10``,@$ +XM```!%```U@0```$4``#D!````10``/($```!%````04```$4```4!0```10` +XM`"(%```!%```,04```$4``!'!0```10``$T%```!%```6`4```$4``!F!0`` +XM`10``&P%```!%```<@4```$4``!X!0```10``'X%```!%```A`4```$4``"* +XM!0```10``)`%```!%```E@4```$4``""````10``&P(```!%```>P@```$4``"'"````10``.8(```!%``` +XM]`@```$4```0"0```10``!X)```!%```+`D```$4```Z"0```10``$@)```! +XM%```:PD```$4``!Y"0```10``(@)```!%```E`D```$4``"B"0```10``+D) +XM```!%```R`D```$4``#^"0```10```P*```!%```&@H```$4```H"@```10` +XM`$4*```!%```2PH```$4``!1"@```10``%<*```!%```70H```$4``!L"@`` +XM`10``'H*```!%```EPH```$4``"E"@```10``,(*```!%```T`H```$4``#M +XM"@```10``/L*```!%```&`L```$4```F"P```10``#T+```!%```2PL```$4 +XM``!B"P```10``'$+```!%```?0L```$4``"+"P```10``)D+```!%```T0L` +XM``$4``#?"P```10``.T+```!%```^PL```$4```)#````10``!<,```!%``` +XM)0P```$4```S#````10``$$,```!%```3PP```$4``!=#````10``&L,```! +XM%```>0P```$4``"'#````10``)4,```!%```HPP```$4``"Q#````10``+\, +XM```!%```S0P```$4``#;#````10``.D,```!%```]PP```$4```-#0```10` +XM`!0-```!`@``&`T```$"```<#0```1```"\-```!$```/@T```$0``!6#0`` +XM`10``%X-```!`@``8@T```$"``!F#0```1```'H-```!$```B`T```$0``"- +XM#0```10``)@-```!$```M`T```$4``"\#0```0(``,`-```!`@``Q`T```$0 +XM``#8#0```1```.8-```!$```]`T```$0```)#@```10``!0.```!$```&0X` +XM``$4```F#@```10``"X.```!`@``,@X```$"```V#@```1```$H.```!$``` +XM3PX```$4``!:#@```1```&@.```!$```;PX```$4``!W#@```0(``'L.```! +XM`@``?PX```$0``"3#@```1```*(.```!$```IPX```$4``"R#@```1```,L. +XM```!$```V@X```$0``#Q#@```10``/D.```!`@``_0X```$"```!#P```1`` +XM`!,/```!$```(@\```$0```Q#P```1```#8/```!%```00\```$0``!(#P`` +XM`10``%`/```!`@``5`\```$"``!8#P```1```&P/```!$```>P\```$0``"* +XM#P```1```(\/```!%```F@\```$0``#!#P```10``,D/```!`@``S0\```$" +XM``#1#P```1```.4/```!$```\P\```$0```3$````1```!H0```!%```)1`` +XM``$"```I$````0(``"T0```!$```0!````$0``!.$````1```%,0```!%``` +XM7A````$0``!S$````10``'X0```!$```A1````$4``"0$````0(``)00```! +XM`@``F!````$0``"K$````1```+`0```!%```NA````$0``#)$````1```-@0 +XM```!$```WA````$4``#I$````0(``.T0```!`@``\1````$0```$$0```1`` +XM``D1```!%```$Q$```$0```B$0```1```"@1```!%```,Q$```$"```W$0`` +XM`0(``#L1```!$```3A$```$0``!3$0```10``%T1```!$```;!$```$0``!R +XM$0```10``(X1```!%```J!$```$4``"O$0```0(``+,1```!`@``MQ$```$0 +XM``#*$0```1```-<1```!$```W!$```$4``#F$0```1```/01```!$```"!(` +XM``$4```2$@```1```!<2```!%```(1(```$0```J$@```1,``#L2```!`@`` +XM/Q(```$"``!($@```1```%`2```!%```?Q(```$4``"'$@```0(``(L2```! +XM`@``CQ(```$0``"A$@```1```+`2```!$```OA(```$0``#'$@```1,``-<2 +XM```!$```YA(```$3``#R$@```1```/L2```!$````A,```$4```P$P```10` +XM`%03```!%```8!,```$4``!W$P```10``(T3```!%```LA,```$4``#.$P`` +XM`10``-H3```!%```"A0```$4```6%````10``&X4```!%```>Q0```$4``"7 +XM%````10``,,4```!%```UA0```$4``#R%````10```D5```!%```+!4```$4 +XM```Z%0```10``$(5```!`@``1A4```$"``!*%0```1```%X5```!$```=14` +XM``$3``"+%0```1,``)05```!$```G14```$0``"W%0```1```-(5```!$``` +XM[!4```$3``#\%0```1````L6```!$P``(18```$3```J%@```1```#,6```! +XM$```1A8```$0``!4%@```1```%T6```!$```>18```$3``"+%@```1,``)06 +XM```!$```IQ8```$0``"T%@```0(``+@6```!`@``SA8```$"``#2%@```0(` +XM`-L6```!$```YA8```$3``#S%@```1,``/P6```!$```!1<```$0```.%P`` +XM`1,``!H7```!$```*!<```$4```U%P```10``,4````!`@``&`````$/```< +XM`````0(``#@````!#P``/`````$"``!8`````0\``%P````!`@``>`````$/ +XM``!\`````0(``)@````!#P``G`````$"``"X`````0\``+P````!`@``V``` +XM``$/``#<`````0(``/@````!#P``_`````$"```8`0```0\``!P!```!`@`` +XM.`$```$/```\`0```0(``%@!```!#P``7`$```$"``!P`0```0\``'0!```! +XM`@``B`$```$/``",`0```0(``*@!```!#P``K`$```$"``#(`0```0\``,P! +X>```!`@``!@````$&```&`````08``!`````!`@`` +X` +Xend +END-of-sections.o.debug.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.sh new file mode 100755 index 0000000000..a79aa03c07 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/elfcopy-noops-archive-1.sh @@ -0,0 +1,8 @@ +# $Id: elfcopy-noops-archive-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest elfcopy-noops-archive-1 tc/elfcopy-noops-archive-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${ELFCOPY} liba.a liba.a.1" work true +rundiff false +runcmd "plugin/teraser -c -t elfcopy-noops-archive-1 liba.a.1" work false +runcmd "plugin/ardiff -cnlt elfcopy-noops-archive-1 ${RLTDIR}/liba.a.1 liba.a.1" work false diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/in/elfcopy-noops-archive-1.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/in/elfcopy-noops-archive-1.in.shar new file mode 100644 index 0000000000..2363a89755 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/elfcopy-noops-archive-1/in/elfcopy-noops-archive-1.in.shar @@ -0,0 +1,98 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# liba.a.uu +# +echo x - liba.a.uu +sed 's/^X//' >liba.a.uu << '610ec18d793cc5cecdc2a997e4eaf41c' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliblong.a.uu << 'bffcfa998f235061c92dda36112dc47a' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Msym.o.uu << '07b26866a0eaf5d2a40d8f75b1109c67' +Xbegin 644 sym.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-Ta64.out.uu << 'c7c93b6ab3d3a59eda1980affa7c397f' +Xbegin 755 a64.out +XM?T5,1@(!`0D```````````(`/@`!````8`1```````!``````````$`+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````)0&````````E`8````````` +XM`!````````$````&````F`8```````"8!E```````)@&4```````J`(````` +XM``"X`@``````````$````````@````8```"`!P```````(`'4```````@`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````C`8```````",!D```````(P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31`"HNPT``P````D````(````!P````0````````````````````"```` +XM`P````$````%````!@`````````````````````````````````````````Y +XM````$@```!P$0````````@`````````F````$0`6`$@)4```````"``````` +XM```N````$0`/`)@&4```````"``````````?````$@```"P$0```````H@`` +XM``````!%````$@```#P$0```````+P````````!*````$`#Q_U`)4``````` +XM``````````!#````$@```$P$0```````+P`````````!````(``````````` +XM````````````````7TIV7U)E9VES=&5R0VQA&ET`%]E;F0` +XM1D)31%\Q+C`````"``$``0`"``(``0`"`````````````0`!`!4````0```` +XM`````+`H>@<```(`3P`````````@"5````````<````!```````````````H +XM"5````````<````$```````````````P"5````````<````%```````````` +XM```X"5````````<````'``````````````!(@^P(Z#\!``#HF@$``$B#Q`C# +XM`/\U_@00`/\E``40`)"0D)#_)?X$$`!H`````.G@_____R7V!!``:`$```#I +XMT/____\E[@00`&@"````Z<#_____)>8$$`!H`P```.FP____`````%5(B>5! +XM54R-;PA!5%-(@^P(BQ](8\.%VTR-9,<03(DEQ`00`'XZ2(M7"$B%TG0Q2(D5 +XM`@(0``^V`H3`="-(@\(!/"](BP7N`1``2`]$PDB)!>,!$``/M@)(@\(!A,!U +XMX;B`!U``2(7`="M(B??H>O___[_(!4``Z'#____H%____XG?3(GB3(GNZ((` +XM``")Q^A'____Z"+____KUI"0D)!(@^P(@#TU!!```'00ZR202(/`"$B)!8T! +XM$`#_TDB+!80!$`!(BQ!(A=)UY,8%#000``%(@\0(PV9F9I!F9F:02(,]N`,0 +XM``!T%K@`````2(7`=`R_``E0`$F)PT'_XY#SPY"0D)"0D)"0D)"0D)"054B) +XMY4B+!34!$`!(@\`!#[8`#[[POSX&0`"X`````.B8_O__R<.0D)"0D)"0D)"0 +XM2(L%.0,0`%-(@_C_=!4QV__02(N#V`A0`$B#ZPA(@_C_=>U;PY"0D$B#[`CH +XM+____TB#Q`C#`"1&'`@)```+F1A=&$N +XM!`!`PP'")`! +XM````````%````"````"@!4``)0````!(#A"#`@```0`````````5```````` +XM``P`````````^`-````````-`````````,@%0```````!`````````#X`4`` +XM``````4`````````"`-````````&`````````#`"0```````"@````````!8 +XM``````````L`````````&``````````5`````````````````````P`````` +XM```("5````````(`````````8``````````4``````````<`````````%P`` +XM``````"8`T```````/[__V\`````>`-```````#___]O``````$````````` +XM\/__;P````!@`T`````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````/__________``````````#_________ +XM_P````````````````````"`!U`````````````````````````````B!$`` +XM`````#($0```````0@1```````!2!$`````````D1G)E94)31#H@6YS='(`+F=N=2YV +XM97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R0````$````&`````````,@%0```````R`4````````.```````````` +XM````````!````````````````````'\````!`````@````````#6!4`````` +XM`-8%````````M0````````````````````$```````````````````"'```` +XM`0````(`````````C`9```````",!@````````@````````````````````$ +XM````````````````````E0````$````#`````````)@&4```````F`8````` +XM```@````````````````````"````````````````````)L````!`````@`` +XM``````"X!E```````+@&````````R`````````````````````@````````` +XM``````````"E````!@````,`````````@`=0``````"`!P```````&`!```` +XM````!0`````````(`````````!``````````K@````$````#`````````.`( +XM4```````X`@````````0````````````````````"``````````````````` +XM`+4````!`````P````````#P"%```````/`(````````$``````````````` +XM``````@```````````````````"\`````0````,```````````E0```````` +XM"0````````@````````````````````(````````````````````P0````$` +XM```#``````````@)4```````"`D````````X````````````````````"``` +XM```````(`````````,8````(`````P````````!`"5```````$`)```````` +XM$`````````````````````@```````````````````#+`````0`````````` +XM``````````````!`"0```````"P!```````````````````!```````````` +XM````````$0````,`````````````````````````;`H```````#4```````` +XM`````````````0````````````````````$````"```````````````````` +XM```````2````````D`8````````:````-0````@`````````&``````````) +XM`````P````````````````````````"0&````````/T!```````````````` +XM```!```````````````````````````````````````````````````````` +XM``,``0#(`4````````````````````````,``@#@`4`````````````````` +XM``````,``P#X`4````````````````````````,`!``P`D`````````````` +XM``````````,`!0`(`T````````````````````````,`!@!@`T`````````` +XM``````````````,`!P!X`T````````````````````````,`"`"8`T`````` +XM``````````````````,`"0#X`T````````````````````````,`"@`,!$`` +XM``````````````````````,`"P!@!$````````````````````````,`#`#( +XM!4````````````````````````,`#0#6!4````````````````````````,` +XM#@",!D````````````````````````,`#P"8!E`````````````````````` +XM``,`$`"X!E````````````````````````,`$0"`!U`````````````````` +XM``````,`$@#@"%````````````````````````,`$P#P"%`````````````` +XM``````````,`%```"5````````````````````````,`%0`("5`````````` +XM``````````````,`%@!`"5````````````````````````,`%P`````````` +XM``````````````````,`&`````````````````````````````,`&0`````` +XM``````````````````````,`&@```````````````````````0````0`\?\` +XM````````````````````"`````$``@#@`4```````!@`````````#P````0` +XM\?\`````````````````````+0````0`\?\`````````````````````/``` +XM``0`\?\`````````````````````#P````0`\?\````````````````````` +XM1P````0`\?\`````````````````````4@````$`$@#@"%`````````````` +XM````8`````$`$P#P"%``````````````````;@````$`%```"5`````````` +XM````````>P````(`"P``!4``````````````````D0````$`%@!`"5`````` +XM``$`````````H`````$`#P"H!E``````````````````IP````(`"P!`!4`` +XM````````````````1P````0`\?\`````````````````````LP````$`$@#H +XM"%``````````````````P`````$`$P#X"%``````````````````S0````$` +XM$`!(!U``````````````````VP````$`%```"5``````````````````YP`` +XM``(`"P"@!4``````````````````_0````0`\?\````````````````````` +XM+0````0`\?\`````````````````````/`````0`\?\````````````````` +XM````_0````0`\?\`````````````````````&P$```0`\?\````````````` +XM````````)`$```$`#P"P!E````````@`````````-0$``!$`$0"`!U`````` +XM````````````/@$``!$"#P"@!E``````````````````2P$``!(`````$``!(` +XM"P!@!$```````)P`````````?P$``!(````L!$```````*(`````````D`$` +XM`!``\?]`"5``````````````````G`$``!(`"P!P!4```````"8````````` +XMH0$``!(`#`#(!4``````````````````IP$``!(````\!$```````"\````` +XM````M@$``!``\?]`"5``````````````````O0$``!$`%0`("5`````````` +XM````````TP$``!``\?]0"5``````````````````V`$``!(```!,!$`````` +XM`"\`````````Z0$``"```````````````````````````&-R=#$N8P!A8FET +XM86<`+W5S0!?7T-43U)?14Y$7U\` +XM7U]$5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G +XM;&]B86Q?8W1Oa64.out.uu << 'c7c93b6ab3d3a59eda1980affa7c397f' +Xbegin 755 a64.out +XM?T5,1@(!`0D```````````(`/@`!````8`1```````!``````````$`+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````)0&````````E`8````````` +XM`!````````$````&````F`8```````"8!E```````)@&4```````J`(````` +XM``"X`@``````````$````````@````8```"`!P```````(`'4```````@`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````C`8```````",!D```````(P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31`"HNPT``P````D````(````!P````0````````````````````"```` +XM`P````$````%````!@`````````````````````````````````````````Y +XM````$@```!P$0````````@`````````F````$0`6`$@)4```````"``````` +XM```N````$0`/`)@&4```````"``````````?````$@```"P$0```````H@`` +XM``````!%````$@```#P$0```````+P````````!*````$`#Q_U`)4``````` +XM``````````!#````$@```$P$0```````+P`````````!````(``````````` +XM````````````````7TIV7U)E9VES=&5R0VQA&ET`%]E;F0` +XM1D)31%\Q+C`````"``$``0`"``(``0`"`````````````0`!`!4````0```` +XM`````+`H>@<```(`3P`````````@"5````````<````!```````````````H +XM"5````````<````$```````````````P"5````````<````%```````````` +XM```X"5````````<````'``````````````!(@^P(Z#\!``#HF@$``$B#Q`C# +XM`/\U_@00`/\E``40`)"0D)#_)?X$$`!H`````.G@_____R7V!!``:`$```#I +XMT/____\E[@00`&@"````Z<#_____)>8$$`!H`P```.FP____`````%5(B>5! +XM54R-;PA!5%-(@^P(BQ](8\.%VTR-9,<03(DEQ`00`'XZ2(M7"$B%TG0Q2(D5 +XM`@(0``^V`H3`="-(@\(!/"](BP7N`1``2`]$PDB)!>,!$``/M@)(@\(!A,!U +XMX;B`!U``2(7`="M(B??H>O___[_(!4``Z'#____H%____XG?3(GB3(GNZ((` +XM``")Q^A'____Z"+____KUI"0D)!(@^P(@#TU!!```'00ZR202(/`"$B)!8T! +XM$`#_TDB+!80!$`!(BQ!(A=)UY,8%#000``%(@\0(PV9F9I!F9F:02(,]N`,0 +XM``!T%K@`````2(7`=`R_``E0`$F)PT'_XY#SPY"0D)"0D)"0D)"0D)"054B) +XMY4B+!34!$`!(@\`!#[8`#[[POSX&0`"X`````.B8_O__R<.0D)"0D)"0D)"0 +XM2(L%.0,0`%-(@_C_=!4QV__02(N#V`A0`$B#ZPA(@_C_=>U;PY"0D$B#[`CH +XM+____TB#Q`C#`"1&'`@)```+F1A=&$N +XM!`!`PP'")`! +XM````````%````"````"@!4``)0````!(#A"#`@```0`````````5```````` +XM``P`````````^`-````````-`````````,@%0```````!`````````#X`4`` +XM``````4`````````"`-````````&`````````#`"0```````"@````````!8 +XM``````````L`````````&``````````5`````````````````````P`````` +XM```("5````````(`````````8``````````4``````````<`````````%P`` +XM``````"8`T```````/[__V\`````>`-```````#___]O``````$````````` +XM\/__;P````!@`T`````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````/__________``````````#_________ +XM_P````````````````````"`!U`````````````````````````````B!$`` +XM`````#($0```````0@1```````!2!$`````````D1G)E94)31#H@6YS='(`+F=N=2YV +XM97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R0````$````&`````````,@%0```````R`4````````.```````````` +XM````````!````````````````````'\````!`````@````````#6!4`````` +XM`-8%````````M0````````````````````$```````````````````"'```` +XM`0````(`````````C`9```````",!@````````@````````````````````$ +XM````````````````````E0````$````#`````````)@&4```````F`8````` +XM```@````````````````````"````````````````````)L````!`````@`` +XM``````"X!E```````+@&````````R`````````````````````@````````` +XM``````````"E````!@````,`````````@`=0``````"`!P```````&`!```` +XM````!0`````````(`````````!``````````K@````$````#`````````.`( +XM4```````X`@````````0````````````````````"``````````````````` +XM`+4````!`````P````````#P"%```````/`(````````$``````````````` +XM``````@```````````````````"\`````0````,```````````E0```````` +XM"0````````@````````````````````(````````````````````P0````$` +XM```#``````````@)4```````"`D````````X````````````````````"``` +XM```````(`````````,8````(`````P````````!`"5```````$`)```````` +XM$`````````````````````@```````````````````#+`````0`````````` +XM``````````````!`"0```````"P!```````````````````!```````````` +XM````````$0````,`````````````````````````;`H```````#4```````` +XM`````````````0````````````````````$````"```````````````````` +XM```````2````````D`8````````:````-0````@`````````&``````````) +XM`````P````````````````````````"0&````````/T!```````````````` +XM```!```````````````````````````````````````````````````````` +XM``,``0#(`4````````````````````````,``@#@`4`````````````````` +XM``````,``P#X`4````````````````````````,`!``P`D`````````````` +XM``````````,`!0`(`T````````````````````````,`!@!@`T`````````` +XM``````````````,`!P!X`T````````````````````````,`"`"8`T`````` +XM``````````````````,`"0#X`T````````````````````````,`"@`,!$`` +XM``````````````````````,`"P!@!$````````````````````````,`#`#( +XM!4````````````````````````,`#0#6!4````````````````````````,` +XM#@",!D````````````````````````,`#P"8!E`````````````````````` +XM``,`$`"X!E````````````````````````,`$0"`!U`````````````````` +XM``````,`$@#@"%````````````````````````,`$P#P"%`````````````` +XM``````````,`%```"5````````````````````````,`%0`("5`````````` +XM``````````````,`%@!`"5````````````````````````,`%P`````````` +XM``````````````````,`&`````````````````````````````,`&0`````` +XM``````````````````````,`&@```````````````````````0````0`\?\` +XM````````````````````"`````$``@#@`4```````!@`````````#P````0` +XM\?\`````````````````````+0````0`\?\`````````````````````/``` +XM``0`\?\`````````````````````#P````0`\?\````````````````````` +XM1P````0`\?\`````````````````````4@````$`$@#@"%`````````````` +XM````8`````$`$P#P"%``````````````````;@````$`%```"5`````````` +XM````````>P````(`"P``!4``````````````````D0````$`%@!`"5`````` +XM``$`````````H`````$`#P"H!E``````````````````IP````(`"P!`!4`` +XM````````````````1P````0`\?\`````````````````````LP````$`$@#H +XM"%``````````````````P`````$`$P#X"%``````````````````S0````$` +XM$`!(!U``````````````````VP````$`%```"5``````````````````YP`` +XM``(`"P"@!4``````````````````_0````0`\?\````````````````````` +XM+0````0`\?\`````````````````````/`````0`\?\````````````````` +XM````_0````0`\?\`````````````````````&P$```0`\?\````````````` +XM````````)`$```$`#P"P!E````````@`````````-0$``!$`$0"`!U`````` +XM````````````/@$``!$"#P"@!E``````````````````2P$``!(`````$``!(` +XM"P!@!$```````)P`````````?P$``!(````L!$```````*(`````````D`$` +XM`!``\?]`"5``````````````````G`$``!(`"P!P!4```````"8````````` +XMH0$``!(`#`#(!4``````````````````IP$``!(````\!$```````"\````` +XM````M@$``!``\?]`"5``````````````````O0$``!$`%0`("5`````````` +XM````````TP$``!``\?]0"5``````````````````V`$``!(```!,!$`````` +XM`"\`````````Z0$``"```````````````````````````&-R=#$N8P!A8FET +XM86<`+W5S0!?7T-43U)?14Y$7U\` +XM7U]$5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G +XM;&]B86Q?8W1Oa64.out.uu << 'c7c93b6ab3d3a59eda1980affa7c397f' +Xbegin 755 a64.out +XM?T5,1@(!`0D```````````(`/@`!````8`1```````!``````````$`+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````)0&````````E`8````````` +XM`!````````$````&````F`8```````"8!E```````)@&4```````J`(````` +XM``"X`@``````````$````````@````8```"`!P```````(`'4```````@`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````C`8```````",!D```````(P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31`"HNPT``P````D````(````!P````0````````````````````"```` +XM`P````$````%````!@`````````````````````````````````````````Y +XM````$@```!P$0````````@`````````F````$0`6`$@)4```````"``````` +XM```N````$0`/`)@&4```````"``````````?````$@```"P$0```````H@`` +XM``````!%````$@```#P$0```````+P````````!*````$`#Q_U`)4``````` +XM``````````!#````$@```$P$0```````+P`````````!````(``````````` +XM````````````````7TIV7U)E9VES=&5R0VQA&ET`%]E;F0` +XM1D)31%\Q+C`````"``$``0`"``(``0`"`````````````0`!`!4````0```` +XM`````+`H>@<```(`3P`````````@"5````````<````!```````````````H +XM"5````````<````$```````````````P"5````````<````%```````````` +XM```X"5````````<````'``````````````!(@^P(Z#\!``#HF@$``$B#Q`C# +XM`/\U_@00`/\E``40`)"0D)#_)?X$$`!H`````.G@_____R7V!!``:`$```#I +XMT/____\E[@00`&@"````Z<#_____)>8$$`!H`P```.FP____`````%5(B>5! +XM54R-;PA!5%-(@^P(BQ](8\.%VTR-9,<03(DEQ`00`'XZ2(M7"$B%TG0Q2(D5 +XM`@(0``^V`H3`="-(@\(!/"](BP7N`1``2`]$PDB)!>,!$``/M@)(@\(!A,!U +XMX;B`!U``2(7`="M(B??H>O___[_(!4``Z'#____H%____XG?3(GB3(GNZ((` +XM``")Q^A'____Z"+____KUI"0D)!(@^P(@#TU!!```'00ZR202(/`"$B)!8T! +XM$`#_TDB+!80!$`!(BQ!(A=)UY,8%#000``%(@\0(PV9F9I!F9F:02(,]N`,0 +XM``!T%K@`````2(7`=`R_``E0`$F)PT'_XY#SPY"0D)"0D)"0D)"0D)"054B) +XMY4B+!34!$`!(@\`!#[8`#[[POSX&0`"X`````.B8_O__R<.0D)"0D)"0D)"0 +XM2(L%.0,0`%-(@_C_=!4QV__02(N#V`A0`$B#ZPA(@_C_=>U;PY"0D$B#[`CH +XM+____TB#Q`C#`"1&'`@)```+F1A=&$N +XM!`!`PP'")`! +XM````````%````"````"@!4``)0````!(#A"#`@```0`````````5```````` +XM``P`````````^`-````````-`````````,@%0```````!`````````#X`4`` +XM``````4`````````"`-````````&`````````#`"0```````"@````````!8 +XM``````````L`````````&``````````5`````````````````````P`````` +XM```("5````````(`````````8``````````4``````````<`````````%P`` +XM``````"8`T```````/[__V\`````>`-```````#___]O``````$````````` +XM\/__;P````!@`T`````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````/__________``````````#_________ +XM_P````````````````````"`!U`````````````````````````````B!$`` +XM`````#($0```````0@1```````!2!$`````````D1G)E94)31#H@6YS='(`+F=N=2YV +XM97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R0````$````&`````````,@%0```````R`4````````.```````````` +XM````````!````````````````````'\````!`````@````````#6!4`````` +XM`-8%````````M0````````````````````$```````````````````"'```` +XM`0````(`````````C`9```````",!@````````@````````````````````$ +XM````````````````````E0````$````#`````````)@&4```````F`8````` +XM```@````````````````````"````````````````````)L````!`````@`` +XM``````"X!E```````+@&````````R`````````````````````@````````` +XM``````````"E````!@````,`````````@`=0``````"`!P```````&`!```` +XM````!0`````````(`````````!``````````K@````$````#`````````.`( +XM4```````X`@````````0````````````````````"``````````````````` +XM`+4````!`````P````````#P"%```````/`(````````$``````````````` +XM``````@```````````````````"\`````0````,```````````E0```````` +XM"0````````@````````````````````(````````````````````P0````$` +XM```#``````````@)4```````"`D````````X````````````````````"``` +XM```````(`````````,8````(`````P````````!`"5```````$`)```````` +XM$`````````````````````@```````````````````#+`````0`````````` +XM``````````````!`"0```````"P!```````````````````!```````````` +XM````````$0````,`````````````````````````;`H```````#4```````` +XM`````````````0````````````````````$````"```````````````````` +XM```````2````````D`8````````:````-0````@`````````&``````````) +XM`````P````````````````````````"0&````````/T!```````````````` +XM```!```````````````````````````````````````````````````````` +XM``,``0#(`4````````````````````````,``@#@`4`````````````````` +XM``````,``P#X`4````````````````````````,`!``P`D`````````````` +XM``````````,`!0`(`T````````````````````````,`!@!@`T`````````` +XM``````````````,`!P!X`T````````````````````````,`"`"8`T`````` +XM``````````````````,`"0#X`T````````````````````````,`"@`,!$`` +XM``````````````````````,`"P!@!$````````````````````````,`#`#( +XM!4````````````````````````,`#0#6!4````````````````````````,` +XM#@",!D````````````````````````,`#P"8!E`````````````````````` +XM``,`$`"X!E````````````````````````,`$0"`!U`````````````````` +XM``````,`$@#@"%````````````````````````,`$P#P"%`````````````` +XM``````````,`%```"5````````````````````````,`%0`("5`````````` +XM``````````````,`%@!`"5````````````````````````,`%P`````````` +XM``````````````````,`&`````````````````````````````,`&0`````` +XM``````````````````````,`&@```````````````````````0````0`\?\` +XM````````````````````"`````$``@#@`4```````!@`````````#P````0` +XM\?\`````````````````````+0````0`\?\`````````````````````/``` +XM``0`\?\`````````````````````#P````0`\?\````````````````````` +XM1P````0`\?\`````````````````````4@````$`$@#@"%`````````````` +XM````8`````$`$P#P"%``````````````````;@````$`%```"5`````````` +XM````````>P````(`"P``!4``````````````````D0````$`%@!`"5`````` +XM``$`````````H`````$`#P"H!E``````````````````IP````(`"P!`!4`` +XM````````````````1P````0`\?\`````````````````````LP````$`$@#H +XM"%``````````````````P`````$`$P#X"%``````````````````S0````$` +XM$`!(!U``````````````````VP````$`%```"5``````````````````YP`` +XM``(`"P"@!4``````````````````_0````0`\?\````````````````````` +XM+0````0`\?\`````````````````````/`````0`\?\````````````````` +XM````_0````0`\?\`````````````````````&P$```0`\?\````````````` +XM````````)`$```$`#P"P!E````````@`````````-0$``!$`$0"`!U`````` +XM````````````/@$``!$"#P"@!E``````````````````2P$``!(`````$``!(` +XM"P!@!$```````)P`````````?P$``!(````L!$```````*(`````````D`$` +XM`!``\?]`"5``````````````````G`$``!(`"P!P!4```````"8````````` +XMH0$``!(`#`#(!4``````````````````IP$``!(````\!$```````"\````` +XM````M@$``!``\?]`"5``````````````````O0$``!$`%0`("5`````````` +XM````````TP$``!``\?]0"5``````````````````V`$``!(```!,!$`````` +XM`"\`````````Z0$``"```````````````````````````&-R=#$N8P!A8FET +XM86<`+W5S0!?7T-43U)?14Y$7U\` +XM7U]$5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G +XM;&]B86Q?8W1Oa64.out.uu << 'c7c93b6ab3d3a59eda1980affa7c397f' +Xbegin 755 a64.out +XM?T5,1@(!`0D```````````(`/@`!````8`1```````!``````````$`+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````)0&````````E`8````````` +XM`!````````$````&````F`8```````"8!E```````)@&4```````J`(````` +XM``"X`@``````````$````````@````8```"`!P```````(`'4```````@`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````C`8```````",!D```````(P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31`"HNPT``P````D````(````!P````0````````````````````"```` +XM`P````$````%````!@`````````````````````````````````````````Y +XM````$@```!P$0````````@`````````F````$0`6`$@)4```````"``````` +XM```N````$0`/`)@&4```````"``````````?````$@```"P$0```````H@`` +XM``````!%````$@```#P$0```````+P````````!*````$`#Q_U`)4``````` +XM``````````!#````$@```$P$0```````+P`````````!````(``````````` +XM````````````````7TIV7U)E9VES=&5R0VQA&ET`%]E;F0` +XM1D)31%\Q+C`````"``$``0`"``(``0`"`````````````0`!`!4````0```` +XM`````+`H>@<```(`3P`````````@"5````````<````!```````````````H +XM"5````````<````$```````````````P"5````````<````%```````````` +XM```X"5````````<````'``````````````!(@^P(Z#\!``#HF@$``$B#Q`C# +XM`/\U_@00`/\E``40`)"0D)#_)?X$$`!H`````.G@_____R7V!!``:`$```#I +XMT/____\E[@00`&@"````Z<#_____)>8$$`!H`P```.FP____`````%5(B>5! +XM54R-;PA!5%-(@^P(BQ](8\.%VTR-9,<03(DEQ`00`'XZ2(M7"$B%TG0Q2(D5 +XM`@(0``^V`H3`="-(@\(!/"](BP7N`1``2`]$PDB)!>,!$``/M@)(@\(!A,!U +XMX;B`!U``2(7`="M(B??H>O___[_(!4``Z'#____H%____XG?3(GB3(GNZ((` +XM``")Q^A'____Z"+____KUI"0D)!(@^P(@#TU!!```'00ZR202(/`"$B)!8T! +XM$`#_TDB+!80!$`!(BQ!(A=)UY,8%#000``%(@\0(PV9F9I!F9F:02(,]N`,0 +XM``!T%K@`````2(7`=`R_``E0`$F)PT'_XY#SPY"0D)"0D)"0D)"0D)"054B) +XMY4B+!34!$`!(@\`!#[8`#[[POSX&0`"X`````.B8_O__R<.0D)"0D)"0D)"0 +XM2(L%.0,0`%-(@_C_=!4QV__02(N#V`A0`$B#ZPA(@_C_=>U;PY"0D$B#[`CH +XM+____TB#Q`C#`"1&'`@)```+F1A=&$N +XM!`!`PP'")`! +XM````````%````"````"@!4``)0````!(#A"#`@```0`````````5```````` +XM``P`````````^`-````````-`````````,@%0```````!`````````#X`4`` +XM``````4`````````"`-````````&`````````#`"0```````"@````````!8 +XM``````````L`````````&``````````5`````````````````````P`````` +XM```("5````````(`````````8``````````4``````````<`````````%P`` +XM``````"8`T```````/[__V\`````>`-```````#___]O``````$````````` +XM\/__;P````!@`T`````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````/__________``````````#_________ +XM_P````````````````````"`!U`````````````````````````````B!$`` +XM`````#($0```````0@1```````!2!$`````````D1G)E94)31#H@6YS='(`+F=N=2YV +XM97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R0````$````&`````````,@%0```````R`4````````.```````````` +XM````````!````````````````````'\````!`````@````````#6!4`````` +XM`-8%````````M0````````````````````$```````````````````"'```` +XM`0````(`````````C`9```````",!@````````@````````````````````$ +XM````````````````````E0````$````#`````````)@&4```````F`8````` +XM```@````````````````````"````````````````````)L````!`````@`` +XM``````"X!E```````+@&````````R`````````````````````@````````` +XM``````````"E````!@````,`````````@`=0``````"`!P```````&`!```` +XM````!0`````````(`````````!``````````K@````$````#`````````.`( +XM4```````X`@````````0````````````````````"``````````````````` +XM`+4````!`````P````````#P"%```````/`(````````$``````````````` +XM``````@```````````````````"\`````0````,```````````E0```````` +XM"0````````@````````````````````(````````````````````P0````$` +XM```#``````````@)4```````"`D````````X````````````````````"``` +XM```````(`````````,8````(`````P````````!`"5```````$`)```````` +XM$`````````````````````@```````````````````#+`````0`````````` +XM``````````````!`"0```````"P!```````````````````!```````````` +XM````````$0````,`````````````````````````;`H```````#4```````` +XM`````````````0````````````````````$````"```````````````````` +XM```````2````````D`8````````:````-0````@`````````&``````````) +XM`````P````````````````````````"0&````````/T!```````````````` +XM```!```````````````````````````````````````````````````````` +XM``,``0#(`4````````````````````````,``@#@`4`````````````````` +XM``````,``P#X`4````````````````````````,`!``P`D`````````````` +XM``````````,`!0`(`T````````````````````````,`!@!@`T`````````` +XM``````````````,`!P!X`T````````````````````````,`"`"8`T`````` +XM``````````````````,`"0#X`T````````````````````````,`"@`,!$`` +XM``````````````````````,`"P!@!$````````````````````````,`#`#( +XM!4````````````````````````,`#0#6!4````````````````````````,` +XM#@",!D````````````````````````,`#P"8!E`````````````````````` +XM``,`$`"X!E````````````````````````,`$0"`!U`````````````````` +XM``````,`$@#@"%````````````````````````,`$P#P"%`````````````` +XM``````````,`%```"5````````````````````````,`%0`("5`````````` +XM``````````````,`%@!`"5````````````````````````,`%P`````````` +XM``````````````````,`&`````````````````````````````,`&0`````` +XM``````````````````````,`&@```````````````````````0````0`\?\` +XM````````````````````"`````$``@#@`4```````!@`````````#P````0` +XM\?\`````````````````````+0````0`\?\`````````````````````/``` +XM``0`\?\`````````````````````#P````0`\?\````````````````````` +XM1P````0`\?\`````````````````````4@````$`$@#@"%`````````````` +XM````8`````$`$P#P"%``````````````````;@````$`%```"5`````````` +XM````````>P````(`"P``!4``````````````````D0````$`%@!`"5`````` +XM``$`````````H`````$`#P"H!E``````````````````IP````(`"P!`!4`` +XM````````````````1P````0`\?\`````````````````````LP````$`$@#H +XM"%``````````````````P`````$`$P#X"%``````````````````S0````$` +XM$`!(!U``````````````````VP````$`%```"5``````````````````YP`` +XM``(`"P"@!4``````````````````_0````0`\?\````````````````````` +XM+0````0`\?\`````````````````````/`````0`\?\````````````````` +XM````_0````0`\?\`````````````````````&P$```0`\?\````````````` +XM````````)`$```$`#P"P!E````````@`````````-0$``!$`$0"`!U`````` +XM````````````/@$``!$"#P"@!E``````````````````2P$``!(`````$``!(` +XM"P!@!$```````)P`````````?P$``!(````L!$```````*(`````````D`$` +XM`!``\?]`"5``````````````````G`$``!(`"P!P!4```````"8````````` +XMH0$``!(`#`#(!4``````````````````IP$``!(````\!$```````"\````` +XM````M@$``!``\?]`"5``````````````````O0$``!$`%0`("5`````````` +XM````````TP$``!``\?]0"5``````````````````V`$``!(```!,!$`````` +XM`"\`````````Z0$``"```````````````````````````&-R=#$N8P!A8FET +XM86<`+W5S0!?7T-43U)?14Y$7U\` +XM7U]$5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G +XM;&]B86Q?8W1Oa64.out.uu << 'c7c93b6ab3d3a59eda1980affa7c397f' +Xbegin 755 a64.out +XM?T5,1@(!`0D```````````(`/@`!````8`1```````!``````````$`+```` +XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````)0&````````E`8````````` +XM`!````````$````&````F`8```````"8!E```````)@&4```````J`(````` +XM``"X`@``````````$````````@````8```"`!P```````(`'4```````@`=0 +XM``````!@`0```````&`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````C`8```````",!D```````(P&0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31`"HNPT``P````D````(````!P````0````````````````````"```` +XM`P````$````%````!@`````````````````````````````````````````Y +XM````$@```!P$0````````@`````````F````$0`6`$@)4```````"``````` +XM```N````$0`/`)@&4```````"``````````?````$@```"P$0```````H@`` +XM``````!%````$@```#P$0```````+P````````!*````$`#Q_U`)4``````` +XM``````````!#````$@```$P$0```````+P`````````!````(``````````` +XM````````````````7TIV7U)E9VES=&5R0VQA&ET`%]E;F0` +XM1D)31%\Q+C`````"``$``0`"``(``0`"`````````````0`!`!4````0```` +XM`````+`H>@<```(`3P`````````@"5````````<````!```````````````H +XM"5````````<````$```````````````P"5````````<````%```````````` +XM```X"5````````<````'``````````````!(@^P(Z#\!``#HF@$``$B#Q`C# +XM`/\U_@00`/\E``40`)"0D)#_)?X$$`!H`````.G@_____R7V!!``:`$```#I +XMT/____\E[@00`&@"````Z<#_____)>8$$`!H`P```.FP____`````%5(B>5! +XM54R-;PA!5%-(@^P(BQ](8\.%VTR-9,<03(DEQ`00`'XZ2(M7"$B%TG0Q2(D5 +XM`@(0``^V`H3`="-(@\(!/"](BP7N`1``2`]$PDB)!>,!$``/M@)(@\(!A,!U +XMX;B`!U``2(7`="M(B??H>O___[_(!4``Z'#____H%____XG?3(GB3(GNZ((` +XM``")Q^A'____Z"+____KUI"0D)!(@^P(@#TU!!```'00ZR202(/`"$B)!8T! +XM$`#_TDB+!80!$`!(BQ!(A=)UY,8%#000``%(@\0(PV9F9I!F9F:02(,]N`,0 +XM``!T%K@`````2(7`=`R_``E0`$F)PT'_XY#SPY"0D)"0D)"0D)"0D)"054B) +XMY4B+!34!$`!(@\`!#[8`#[[POSX&0`"X`````.B8_O__R<.0D)"0D)"0D)"0 +XM2(L%.0,0`%-(@_C_=!4QV__02(N#V`A0`$B#ZPA(@_C_=>U;PY"0D$B#[`CH +XM+____TB#Q`C#`"1&'`@)```+F1A=&$N +XM!`!`PP'")`! +XM````````%````"````"@!4``)0````!(#A"#`@```0`````````5```````` +XM``P`````````^`-````````-`````````,@%0```````!`````````#X`4`` +XM``````4`````````"`-````````&`````````#`"0```````"@````````!8 +XM``````````L`````````&``````````5`````````````````````P`````` +XM```("5````````(`````````8``````````4``````````<`````````%P`` +XM``````"8`T```````/[__V\`````>`-```````#___]O``````$````````` +XM\/__;P````!@`T`````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````/__________``````````#_________ +XM_P````````````````````"`!U`````````````````````````````B!$`` +XM`````#($0```````0@1```````!2!$`````````D1G)E94)31#H@6YS='(`+F=N=2YV +XM97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R0````$````&`````````,@%0```````R`4````````.```````````` +XM````````!````````````````````'\````!`````@````````#6!4`````` +XM`-8%````````M0````````````````````$```````````````````"'```` +XM`0````(`````````C`9```````",!@````````@````````````````````$ +XM````````````````````E0````$````#`````````)@&4```````F`8````` +XM```@````````````````````"````````````````````)L````!`````@`` +XM``````"X!E```````+@&````````R`````````````````````@````````` +XM``````````"E````!@````,`````````@`=0``````"`!P```````&`!```` +XM````!0`````````(`````````!``````````K@````$````#`````````.`( +XM4```````X`@````````0````````````````````"``````````````````` +XM`+4````!`````P````````#P"%```````/`(````````$``````````````` +XM``````@```````````````````"\`````0````,```````````E0```````` +XM"0````````@````````````````````(````````````````````P0````$` +XM```#``````````@)4```````"`D````````X````````````````````"``` +XM```````(`````````,8````(`````P````````!`"5```````$`)```````` +XM$`````````````````````@```````````````````#+`````0`````````` +XM``````````````!`"0```````"P!```````````````````!```````````` +XM````````$0````,`````````````````````````;`H```````#4```````` +XM`````````````0````````````````````$````"```````````````````` +XM```````2````````D`8````````:````-0````@`````````&``````````) +XM`````P````````````````````````"0&````````/T!```````````````` +XM```!```````````````````````````````````````````````````````` +XM``,``0#(`4````````````````````````,``@#@`4`````````````````` +XM``````,``P#X`4````````````````````````,`!``P`D`````````````` +XM``````````,`!0`(`T````````````````````````,`!@!@`T`````````` +XM``````````````,`!P!X`T````````````````````````,`"`"8`T`````` +XM``````````````````,`"0#X`T````````````````````````,`"@`,!$`` +XM``````````````````````,`"P!@!$````````````````````````,`#`#( +XM!4````````````````````````,`#0#6!4````````````````````````,` +XM#@",!D````````````````````````,`#P"8!E`````````````````````` +XM``,`$`"X!E````````````````````````,`$0"`!U`````````````````` +XM``````,`$@#@"%````````````````````````,`$P#P"%`````````````` +XM``````````,`%```"5````````````````````````,`%0`("5`````````` +XM``````````````,`%@!`"5````````````````````````,`%P`````````` +XM``````````````````,`&`````````````````````````````,`&0`````` +XM``````````````````````,`&@```````````````````````0````0`\?\` +XM````````````````````"`````$``@#@`4```````!@`````````#P````0` +XM\?\`````````````````````+0````0`\?\`````````````````````/``` +XM``0`\?\`````````````````````#P````0`\?\````````````````````` +XM1P````0`\?\`````````````````````4@````$`$@#@"%`````````````` +XM````8`````$`$P#P"%``````````````````;@````$`%```"5`````````` +XM````````>P````(`"P``!4``````````````````D0````$`%@!`"5`````` +XM``$`````````H`````$`#P"H!E``````````````````IP````(`"P!`!4`` +XM````````````````1P````0`\?\`````````````````````LP````$`$@#H +XM"%``````````````````P`````$`$P#X"%``````````````````S0````$` +XM$`!(!U``````````````````VP````$`%```"5``````````````````YP`` +XM``(`"P"@!4``````````````````_0````0`\?\````````````````````` +XM+0````0`\?\`````````````````````/`````0`\?\````````````````` +XM````_0````0`\?\`````````````````````&P$```0`\?\````````````` +XM````````)`$```$`#P"P!E````````@`````````-0$``!$`$0"`!U`````` +XM````````````/@$``!$"#P"@!E``````````````````2P$``!(`````$``!(` +XM"P!@!$```````)P`````````?P$``!(````L!$```````*(`````````D`$` +XM`!``\?]`"5``````````````````G`$``!(`"P!P!4```````"8````````` +XMH0$``!(`#`#(!4``````````````````IP$``!(````\!$```````"\````` +XM````M@$``!``\?]`"5``````````````````O0$``!$`%0`("5`````````` +XM````````TP$``!``\?]0"5``````````````````V`$``!(```!,!$`````` +XM`"\`````````Z0$``"```````````````````````````&-R=#$N8P!A8FET +XM86<`+W5S0!?7T-43U)?14Y$7U\` +XM7U]$5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G +XM;&]B86Q?8W1Osym.o.uu << 'END-of-sym.o.uu' +Xbegin 644 sym.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-Tsym.o.uu << 'END-of-sym.o.uu' +Xbegin 644 sym.o +XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# +XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I +XM(#0N,BXQ(#(P,#6UT86(`+G-Tls.uu << 'END-of-ls.uu' +Xbegin 755 ls +XM?T5,1@$!`0D```````````(``P`!````D),$"#0```!T7@```````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(<%@` +XM`'!8```%`````!````$```!P6```<.@$"'#H!`AH`@``V`,```8`````$``` +XM`@```-!8``#0Z`0(T.@$"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&1<6```7-@$"%S8!`@4````%`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`0P```%4````]````40```!8`````````.P```%`````````` +XM.@```#@```!.````0P```!4`````````/@```#8```!!````2P`````````L +XM`````````!<````%````2@```%(```!%`````````!P````M````)P```$8` +XM`````````````#,`````````4P```"@`````````"0````@````````````` +XM```````,````/````#4```!/````"P```"````!4````,0```"$````````` +XM`````$T````?````1P```$P``````````````#\`````````20```$`````` +XM````,````#0````````````````````````````````````````````````` +XM```!`````````````````````````````````````P``````````````"@`` +XM``T````````````````````&```````````````2```````````````````` +XM`````````````````````!$````````````````````B`````````!L````9 +XM``````````(````3```````````````E````#@```!`````/````!P```!H` +XM```4````````````````````)@```"\````C```````````````D````&``` +XM```````Y````,@``````````````'@```"D````J`````````#<````$```` +XM2````$(`````````'0```$0`````````+@`````````K```````````````` +XM``````````````!N`0```````*,````2````T`(```````#&````$@```)D! +XM````````-````!(```"3`@```````#,````2````=0(```````!#````$@`` +XM`"T!````````2````!(```![`@`````````````2````]@````````!K`0`` +XM$@````X```#0Z`0(`````!$`\?^A`0`````````````2````%P````````!L +XM!```$@```&T`````````U`,``!(```!2`@```````*$````2````$`(````` +XM``!:````$@```!0`````````A!@`` +XM$@```,P!````````>````!(````M````W-,$"``````2``T`I@$```````", +XM`@``$@```.@(````` +XM``"Q````$@```/8!``#LZ@0(!````!$`%P"*`@```````,\!```2````2@(` +XM``````#+````$@```%D"````````0P```!(````\`0```````,,````2```` +XM80$````````J````$@```#P"````````/@```!(```#G`@``V.H$"``````0 +XM`/'_0P$````````S````$@```#,```"\Z00(`````!$`\?_Z`@``2.P$"``` +XM```0`/'_7@(```````!B`P``$@````T!``#PZ@0(!````!$`%P`!`0`````` +XM`),````2````L@$``/3J!`@$````$0`7`#4!`````````````!(```!7`@`` +XM`````"L````2````@0(````````I````$@````8!`````````````!(```"R +XM`@`````````````2````H0``````````````$@```$D``````````````"`` +XM```D`0`````````````2````@0`````````4`0``$@```,8`````````6P`` +XM`!(`````;&EB=71I;"YS;RXW`%]$64Y!34E#`&AU;6%N:7IE7VYU;6)E<@!? +XM:6YI=`!?9FEN:0!?1TQ/0D%,7T]&1E-%5%]404),15\`7TIV7U)E9VES=&5R +XM0VQA0!?7W-T9&]U +XM='``=V%R;G@`:6]C=&P`0!A8VQ?9V5T7V5N=')Y`&9T7!E`'-T#I!`AH,````.F`_____R7DZ00(:#@```#ISI!`AH2````.E0_____R7PZ00(:%````#I0/____\E].D$"&A8```` +XMZ3#_____)?CI!`AH8````.D@_____R7\Z00(:&@```#I$/____\E`.H$"&AP +XM````Z0#_____)03J!`AH>````.GP_O___R4(Z@0(:(````#IX/[___\E#.H$ +XM"&B(````Z=#^____)1#J!`AHD````.G`_O___R44Z@0(:)@```#IL/[___\E +XM&.H$"&B@````Z:#^____)1SJ!`AHJ````.F0_O___R4@Z@0(:+````#I@/[_ +XM__\E).H$"&BX````Z7#^____)2CJ!`AHP````.E@_O___R4LZ@0(:,@```#I +XM4/[___\E,.H$"&C0````Z4#^____)33J!`AHV````.DP_O___R4XZ@0(:.`` +XM``#I(/[___\E/.H$"&CH````Z1#^____)4#J!`AH\````.D`_O___R5$Z@0( +XM:/@```#I\/W___\E2.H$"&@``0``Z>#]____)4SJ!`AH"`$``.G0_?___R50 +XMZ@0(:!`!``#IP/W___\E5.H$"&@8`0``Z;#]____)5CJ!`AH(`$``.F@_?__ +XM_R5.H$"&A@`0``Z2#]____)7SJ!`AH +XM:`$``.D0_?___R6`Z@0(:'`!``#I`/W___\EA.H$"&AX`0``Z?#\____)8CJ +XM!`AH@`$``.G@_/___R6,Z@0(:(@!``#IT/S___\ED.H$"&B0`0``Z<#\____ +XM)93J!`AHF`$``.FP_/___R68Z@0(:*`!``#IH/S___\EG.H$"&BH`0``Z9#\ +XM____):#J!`AHL`$``.F`_/___R6DZ@0(:+@!``#I3K!`A^-HM% +XM"(7`="^C<.@$"`^V$(32=".#P`'K"@^V$(/``832=!2`^B]U\:-PZ`0(#[80 +XM@\`!A-)U[+C0Z`0(A6#[`B` +XM/?CJ!`@`=`SK'(/`!*-XZ`0(_]*A>.@$"(L0A=)UZ\8%^.H$"`')PY!5B>6# +XM[`BAN.D$"(7`=!*X`````(7`=`G'!"2XZ00(_]#)PY"0D)"0D)"0D)"0D)!5 +XMB>6#[`R)'"2)="0$B7PD"(MU#(M]"(M&/(M8-(M(,(M'/(M0-(M`,#G3?12X +XM_____XL<)(MT)`2+?"0(B>Q=PWX-N`$```#KZ(VV`````#G!=^\YTWX?BT9` +XMB44,BT=`B44(BQPDBW0D!(M\)`B)[%WI/?S__WRT.<%SVXUV`.NKC;0F```` +XM`(V\)P````!5B>6+50R+10B)50B)10Q=Z5O___^-="8`C;PG`````%6)Y8/L +XM"(D<)(ET)`2+=0B+70R+5CR+2SR+0B@Y02A^$+@!````BQPDBW0D!(GL7<-\ +XM#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0T")10R+1D")10B+'"2+="0$B>Q= +XMZ:#[__^-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z7O___^-="8`C;PG +XM`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+2SR+0E`Y05!^$+@!````BQPD +XMBW0D!(GL7<-\#XM"5#E!5'_FD(UT)@!]![C_____Z]V+0T")10R+1D")10B+ +XM'"2+="0$B>Q=Z1#[__^-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z7O_ +XM__^-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+2SR+0A@Y01A^ +XM$+@!````BQPDBW0D!(GL7<-\#XM"'#E!''_FD(UT)@!]![C_____Z]V+0T") +XM10R+1D")10B+'"2+="0$B>Q=Z8#Z__^-M@````"-OP````!5B>6+50R+10B) +XM50B)10Q=Z7O___^-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5CR+ +XM2SR+0B`Y02!^$+@!````BQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_ +XM____Z]V+0T")10R+1D")10B+'"2+="0$B>Q=Z?#Y__^-M@````"-OP````!5 +XMB>6+50R+10B)50B)10Q=Z7O___^-="8`C;PG`````%6)Y8M%"(M5#(M`0(E% +XM#(M"0(E%"%WIJ?G__Y"-="8`58GEBT4,BT!`B44,BT4(BT!`B44(7>F)^?__ +XMD)"0D)!5B>6#[`R)'"2)="0$B7PD"(M%"(M5#(LP#[=&-&:#^`DW____C;0F```` +XM`#'2BQPDB="+="0$BWPD"(GL7<.-M@````"-O"<`````58GE5U93@>PL!0`` +XMBST\[`0(B848^___B944^___B8T0^___A?_'1%//O__P$```#'!"0RU`0(Z-'V___'1<``````QT7$`````,=%V``` +XM``#'1=0`````QT70`````(7`B``````QT7D`````,=%Z`````#'1>P` +XM````QT7<`````'0)@#@`#X6"!@``BYT4^___A=L/A!8&``"+A1#[__^+O13[ +XM___'A2S[__\`````QX4P^___`````(/@`L>%3/O__P````#'A4C[__\````` +XMB84,^___Z9P"``!F@_@*#X2@`@``BXT8^___A2A(.P$"(7`=0FA[.L$"(7`=!L/MT2+A3S[__^%P`^$(P(``(M7/(G0B94H^___BT@\BT7L +XMBU(XB<;!_A\Y\7P)?P0YPG8#B57LBY4H^___BT($.T7H=@.)1>B+C2C[__\/ +XMMT$*.T7@=@.)1>"+C2C[__^+430[5<2+03!\#7\%.T7`=@:)1<")5<2+A2C[ +XM__^+0#@!A2S[__^A0.P$"(7`#X2@`0``H1CK!`B%P`^$MP(``(N5*/O__XUU +XMIHU=LXM"#,=$)`A-U`0(QT0D!`T```")-"2)1"0,Z$;W__^+C2C[__^+01#' +XM1"0(3=0$",=$)`0-````B1PDB40D#.@A]___B;5`^___B9U$^___BX5`^___ +XMB00DZ$?X__\[1=")A3C[__]V`XE%T(N51/O__XD4).@K^/__.T74B<-V`XE% +XMU(LU..P$",>%-/O__P````"%]@^%E0(``(L-!.P$"#'2QT7,`````(7)#X7I +XM`@``B[4X^___BXTT^___`=Z-1#$8`=")!"3H-O?__X7`B<,/A/,'``"-0!") +XM`XN50/O__XD$)(E4)`3HQ??__XN-./O__XU$&1&)0P2+E43[__^)!"2)5"0$ +XMZ*;W__^+C2C[__\/MT$()0#P```]`"````^$Q0$``#T`8```#X2Z`0``H3CL +XM!`B%P`^%Q`$``*$$[`0(A\O__@\`!#X1[ +XM!```9H-_,@`/A=X```"+1T"-M5?[___'1"0(2M0$",=$)`0!!```B30DB40D +XM#.B%\___BY4,^___A=)T6XM%R(DT)(E$)`3H'/3__X/``71;C47,B40D!(M% +XMR(D$).C%\?__@\`!=$2+1U`0(B40D!.C_\O__BT7(B00DZ`3R__^+1%,/O__P````#'A2S[__\` +XM````H4#L!`B%P'4-H?3K!`B%P`^$8OW__XN]&/O__X7_#X7<_/__Z4_]__\Q +XMP(,]].L$"``/E<")A3S[___I'?G__XD$).AR\___C40``HD$).C&\O__A<") +XMA1S[__\/A'\#```/M@,\.@^$B`,``(N5'/O__XG1B`*#P0'&0@$`#[9#`83` +XM=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&`3`/MD(!B$$! +XM@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$50,``(U%W(N-'/O__XE$)"B-1>2) +XM1"0DC47`B40D((U%V(E$)!R-1=2)1"08C470B40D%(U%X(E$)!"-1>R)1"0, +XMC47HB40D",=$)`3HU`0(B0PDZ/CP___'!13L!`@!````@_@(#X8M`@``BW7H +XM,<"%]G0=N0$```"X"@```/?A@^X!B<%U\L=%Z`````"-0/^+?>R)1>@QP(7_ +XM?C*)_KD!````,=MKTPJX"@```(F5!/O___?AB=.)P0.=!/O__X/N`77AQT7L +XM`````(U`_XMUX(E%[#'`A?9T';D!````N`H```#WX8/N`8G!=?+'1>`````` +XMC4#_BTW$BU7`B47@@_D`B94@^___B8TD^___#XZ)`0``BXT@^___O@$````Q +XM_XN=)/O__VO'"HF%!/O__[@*````]^:)UXG&`[T$^___@\'_@]/_B=H)RG7: +XMB?")^H/`_\=%P`````"#TO_'1<0`````BXT<^___B47`B57$B0PDZ"7Q___I +XM=/?__XN%+/O__XU=CHN-,/O__\=$)`ARU`0(QT0D!!@```")A5S___^+1>R) +XMC6#___^)'"2)1"0,Z/;O__^)'"3H+O'__\=$)`ARU`0(QT0D!!@```")'"2) +XMA6S___^+1=B)A7#___^+1=R)A73___^+1=2)A7C___^+1>B)1"0,Z*[O__^) +XM'"3HYO#__\=$)`ARU`0(QT0D!!@```")'"2)A7S___^+1>")1"0,Z('O__^) +XM'"3HN?#__XM5Q,=$)`AVU`0(QT0D!!@```")'"2)5"00B46`BT7`B40D#.A0 +XM[___B1PDZ(CP__^)182+1=")18CI[_G__XM'0(E$)`B+1P2+0!C'!"1>U`0( +XMB40D!.@M[___Z=/[____)(5$U00(?!&#^@"0C;0F``````^'9/[__S'`,=+I +XMK/[__\=%Z`````#'1>P`````QT7@`````,=%T`````#'1=0`````QT78```` +XM`,=%P`````#'1<0`````QT7D`````(,]&.P$"`''1=P`````&<#WT"$%%.P$ +XM".E4_?__QT0D!#_4!`C'!"0!````Z$7O__^+A1S[__^)P8/!`F;'`#`ZQD`" +XM`.EP_/__QT0D!%+4!`C'!"0!````Z!CO__]FQP$P`.FA_/__C78`C;PG```` +XM`%6)Y5=64X/L'(,]%.L$"`&)1>R)3>@9P"7`EP0(B40D"(E,)`2)%"3H!^W_ +XM_X7`B<CJ!`B+ +XM0@B#Z`&%P(E""`^(;P$``(L"Q@`*@\`!B0*+0QB)!"3H*Q```,<$)*#4!`CH +XMD^K__XM%\(D\)(E$)`3H-.S__XM-Z(G"B<:)V.BR\___H1SK!`B%P`^%1?__ +XM_X7V#X0]____B5PD!,=$)`@$````B3PDZ#WK__^)/"3HE>O__X7`B<,/A2G_ +XM___HENS__XL`A<`/A?T```"#Q!Q;7E]=PV:#^`1T"F:#^`O__XE$)`B+0T#'!"1&U`0(B40D!.@2[/__QP4XZP0(`0```.F__O__ +XMBT-`QP0D@]0$"(E$)`3H\.O__^FG_O__C;0F`````(-][`$/CB?___^+0QB) +XM!"3H.P\``,<$)*#4!`CHH^G__\<%/.L$"`$```#I`?___Z$$[`0(A<`/A5;^ +XM___V1>@(QT7P``$```^%4O[__^E`_O__H>CJ!`C'!"0*````B40D!.C\Z?__ +XMZ:W^__^A#.L$"(7`#X0F_O__Z6#^__^)5"0$QP0D"@```.A5[/__D.F%_O__ +XMQT0D!*+4!`C'!"0!````Z'OL___'1"0$>M0$",<$)`$```#H9^S__XUV`(U, +XM)`2#Y/#_575E-1@>PH!@``BQF+202-A>#]__^)1>C'1"0$*]<$",<$ +XM)`````")C=SY___H1>S__\<$)`$```#H*>S__X7`#X24````QP5\Z`0(4``` +XM`,<$)*O4!`CH^^C__X7`=`F`.``/A=@'``"-1>")1"0(QT0D!&AT"$#'!"0! +XM````Z)/I__^#P`%T$0^W1>)FA +XM``#KS\<%).L$"`$```#'!"2KU`0(Z&?H__^%P'2PB00DZ!OH__^C?.@$".NA +XM_R2%:-4$"(L5#.L$"(L]].H$"(72#X1X!0``QP0DL]0$".@MZ/__AO__X7`#X2D`0``QP0DR]0$".@)Z/__B40D!(V%X/G__XD$).A7 +XMZO__@^@!#X0B!@``H1CL!`B%P'1&QP44[`0(`0```,=$)`30KP0(QP0D`@`` +XM`.@WZO__QT0D!-"O!`C'!"0#````Z"/J___'!"3?U`0(Z*?G__^)!"3H*P@` +XM`*$\[`0(A<`/A,8```"A0.P$"(7`=1B+%0CK!`B%TG4.BPTL[`0(ASK!`@`````Z5/\___'!1SL +XM!`@!````Z43\___'!3#K!`@!````QP4LZP0(`````.DK_/__QP4GO^___QT0D"`$```#'1"0$*]<$",<$)+/4!`CH$>?__^G.^___QP40[`0( +XM`0```,<%+.P$"`$```#IM?O__\<%..P$"`$```#IIOO__\<%&.L$"`$```#I +XME_O__\<%*.L$"`$```#'!23K!`@`````QP5`[`0(`````.ET^___QP5`[`0( +XM`0```,<%).L$"`````#'!2CK!`@`````Z5'[___'!?CK!`@`````QP4$ZP0( +XM`0```.DX^___QP4\[`0(`0```.DI^___QP7XZP0(`0```.D:^___QP44ZP0( +XM`0```.D+^___QP4(ZP0(`0```,<%'.L$"`````#I\OK__\<%Z.L$"`$```#' +XM!0#L!`@`````QP4T[`0(`````.G/^O__QP4([`0(`````,<%(.P$"`````#' +XM!>SK!`@!````Z:SZ___'!03L!`@!````Z9WZ___'!33K!`@!````Z8[Z___' +XM!33L!`@!````QP4`[`0(`````,<%Z.L$"`````#I:_K__XGQNH#H!`BX`0`` +XM`.@$]___Z2K\__^A0.P$"(7`#X2M````QP7\Z@0(X+X$".GT^___H2SK!`B% +XMP'5&BPTPZP0(AS' +XM1"0$#.P$"(D$).C.Y/__BQ4,[`0(B=#!^!_!Z!CZ___'!0#K!`B@EP0(Z=GZ__^#S@'I:OK__\<%_.H$"&"Z +XM!`CIV?K__XU-Z(E,)`3'!"30U`0(Z&GE___'!"33U`0(H_#K!`B-1>B)1"0$ +XMZ%'E__^-3>B)3"0$QP0DUM0$"*,H[`0(Z#GE___'!"39U`0(HT3L!`B-1>B) +XM1"0$Z"'E__^-3>B)3"0$QP0DW-0$"*,D[`0(Z`GE__^%P*/\ZP0(#X30```` +XMH?#K!`B%P`^$4?G__Z$H[`0(A<`/A$3Y__^A_.L$"(7`#X0W^?__QP48[`0( +XM`0```.DQ^?__B00DZ,[@___'!0CL!`@!````HWSH!`CI1_C__Z$T[`0(A6#[!B%P'0]H?SK!`C'1"0($+`$ +XM",=$)`0!````B00DZ/WA__^X$+`$"(E$)`BA1.P$",=$)`0!````B00DZ-_A +XM___)PZ'\ZP0(QT0D"""U!`C'1"0$`0```(D$).C`X?__N""U!`CKP9"-="8` +XM58GE4X/L%(M="(G8Z'____^)'"3'1"0$`````.@SXO__Z"[C__^)7"0$B00D +XMZ,+?__^#Q!1;7<.0C;0F`````%6)Y8/L*(M%",=$)`@!````QP0D`0```(A% +XM_XU%_XE$)`3H;=___S'`R<.0C70F`%6)Y5=64X/L+(M%"(7`#X1``0``BT4( +XM,?^)!"3HT^+__XL5O-<$"&;'1=H``,=%W`````")5>")1=3K/(UT)@`/OL*# +XMZ#")`V:#?=H`#X2N````9L=%V@$`@\8!@\,$@_X"=46#QP=P,@T7@`H/_ +XM"P^$U````(M%W,>`:.L$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.- +XM!'\Q]HT3J!`A]#*'LZ@0(BXR( +XM-`0``(/Y>'03#[["B40D!,<$))#7!`CH\]___\<#_____^D-____@\0L6UY? +XM7564XG#C31`@^P0BQ2U:.L$"(72#X64````BP2U +XM8.L$"(/X_W0XB40D"*'PZP0(QT0D!`````")!"3H`][__X7`=!O'1"0((+4$ +XM",=$)`0!````B00DZ(??__^-=@"-!%N+!(5DZP0(@_C_=#6)1"0(H2CL!`C' +XM1"0$`````(D$).B\W?__A7<.0C70F`*$D[`0(QT0D"""U!`C'1"0$`0```(D$).@7W___Z4K___^- +XMM"8`````C;PG``````^WP(G"58'B`/```(GE@^P(@?H`0```#X3&````?E&! +XM^@"@```/A'T```"!^@#```!T8H'Z`&````^$?````#'2J$ET7_;$"`^%X@`` +XM`/;$!`^$MP```+@(````C70F`.B[_O__N@$```#K.(UT)@"!^@`0``!T6('Z +XM`"```(GV=;VX!@```.B4_O__N@$```#)B=##N`(```#H@?[__[H!````R8G0 +XMP[@!````Z&[^__^Z`0```,F)T,.X!0```.A;_O__N@$```#)B=##B?:X`P`` +XM`.A&_O__N@$```#)B=##J`)T./;$`G01N`D```#H*O[__[H!````ZZ>X"@`` +XM`.@9_O__N@$```#KEK@$````Z`C^__^Z`0```.N%,<#H^OW__[H!````Z73_ +XM__^X!P```.CF_?__N@$```"0Z5____^-="8`C;PG`````%6)Y5.#[&2)1:BA +XMD.@$"(7`#XC9````H43K!`B%P`^$L@```*$<[`0(A\`.=!_ +XM'8L-D.@$"+NVU@0(A-M"8`````C8(`\>\`.<%]V:&0Z`0( +XMNZ+6!`B%P`^%=/___[NLU@0(Z6K____'!"0`````Z-+:__^C1.L$".DX____ +XMC70F`,<$)#D```#H:-W__X`X9`^4P`^VP*.0Z`0(Z0C___^0BQ4@[`0(58GE +XMBT4(A=)U"HL-[.L$"(7)=`F)10A=Z;T7``"+%0CL!`B%TG0)B44(7>E:$@`` +XMB44(7>EA%0``D%6)Y8/L"*'@Z@0(BTT(A"*+`H@(@\`!B0+),<##H>CJ!`B)#"2)1"0$Z)':__\QP,G#.T(8?`:`^0J0 +XM==.)5"0$B0PDZ/;<___KSE6)Y8/L"(L-$.P$"(7)=!`E`/```#T`0```='3) +XM,<##B<*!X@#P``"!^@"@```/A-\````/AXP```"!^@`0```/A%,!``"!^@!` +XM``"-="8`=#ZH273&H>#J!`B%P`^%AP$``(L5Z.H$"(M""(/H`87`B4((#XAX +XM`@``BP+&`"J#P`&)`K@!````R<.0C70F`(L5X.H$"(72#X6J````BQ7HZ@0( +XMBT((@^@!A<")0@@/B!4!``"+`L8`+X/``8D"N`$```#)PX'Z`,````^$D@`` +XM`('Z`.````^%=/___Z'@Z@0(A<`/A9CJ!`B+0@B#Z`&%P(E""`^( +XM8`$``(L"Q@`E@\`!B0*X`0```,G#H>#J!`B%P`^%?@$``(L5Z.H$"(M""(/H +XM`87`B4((#XC/````BP+&`$"#P`&)`K@!````R<.AZ.H$",<$)"\```")1"0$ +XMZ!?9__^X`0```,G#H>#J!`B%P`^%90$``(L5Z.H$"(M""(/H`87`B4((#XBZ +XM````BP+&`#V#P`&)`K@!````R<.AX.H$"(7`#X44`0``BQ7HZ@0(BT((@^@! +XMA<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8#XWB_O__B50D!,<$)"\```#H +XM$=O__[@!````R<.AZ.H$",<$)"H```")1"0$Z'78__^X`0```,G#.T(8#XTH +XM____B50D!,<$)$````#HU=K__[@!````R<,[0AA]CHE4)`3'!"1\````Z+G: +XM__^X`0```,G#.T(8#XT]____B50D!,<$)#T```#HF=K__[@!````R<,[0A@/ +XMC9?^__^)5"0$QP0D)0```.AYVO__N`$```#)PZ'HZ@0(QP0D)0```(E$)`3H +XMW=?__[@!````R<.AZ.H$",<$)$````")1"0$Z,'7__^X`0```,G#H>CJ!`C' +XM!"1\````B40D!.BEU___N`$```#)PZ'HZ@0(QP0D/0```(E$)`3HB=?__[@! +XM````R<,[0A@/C7_]__^)5"0$QP0D*@```.CIV?__N`$```#)PXVT)@````"- +XMO"<`````58GE@^PXB5WTB<.)??R)SXEU^(MP/*$\[`0(QT7L`````(7`#X7> +XM````H?3K!`B%P'5RH1CL!`B%P'1)#[=&".B;^?__B<>+0T")!"3H[OO__XM- +XM[(T<"*$8[`0(AQ=PXM#0(D$).BP^___BU7LC1P0Z\F%_W3%,<#H'?;__^N\H0SL!`B#Z`&) +XMPL'Z'XE%X(E5Y(M&.(M6/`%%X*$,[`0($57DBTWDB<+!^A^)5"0,BU7@B4PD +XM!(E$)`B)%"3HF!@``(E\)`3'!"04UP0(B40D"(E4)`SH--C__P%%[.DK____ +XMBT8$B50D!,<$),S6!`B)1"0(Z!78__^)1>SI`____XGVC;PG`````%6)Y593 +XM@^P0BW4(BQZ%VW4FZUR+%>CJ!`B+0@B#Z`&%P(E""'A0BP+&``J#P`&)`HM; +XM"(7;=#B#>PP!=/.+3A2)V(M6).B&_O__H>#J!`B%P'3`H>CJ!`C'!"0*```` +XMB40D!.B\U?__BUL(A=MUR(/$$%M>7<.)5"0$QP0D"@```.@>V/__ZZB0C;0F +XM`````%6)Y5=64X/L/(M%"(,]%.P$"`$9TH/B!X/"`8E%T(E5Z(M`##L%C.@$ +XM"`^/O@(``(M=T(L#QT7<`````(7`=!^+%4#K!`B#>`P!=`R+3=R)!(J#P0&) +XM3=R+0`B%P'7GH3SL!`B+7="%P(M3$'0(BT,D@\`!`<*+#?3K!`B%R70+BUW0 +XMBT,4@\`!`<*#/2SL!`@!BT7H@]K_`U7H]]B)1=0APHE5\(M%\(L5?.@$"`'` +XM.=`/CR0"``")T,'Z'_=]\(M5W(E%S(G0P?H?]WW,@_H!BU70@]C_B47@BP*% +XMP`^$N0$``&:#>#(`#X6N`0``BW7@A?8/CG(!``#'1=@`````QT7D`````(L= +XM,.P$"(7;=0:+5>2)5=B+3P/C:D```"+%>#J +XM!`B%TG5.BPWHZ@0(@ST4[`0(`8M!"!G2@^+I@\(@@^@!A<")00AX48L!B=Z( +XM$(/``8D!BU7HC1P6(UW4.?M^IHM-S#E-['1=@T7L`0-]\.E*____@ST4[`0( +XM`8G>BQ7HZ@0(&<"#X.F#P"")5"0$B00DZ(S3___KNCM!&'P%@/H*=:6)3"0$ +XMB=Z)%"3H\M7__^N@BU7@`578BTW<.4W8#XPR____H>#J!`B%P'4UBQ7HZ@0( +XMBT((@^@!A<")0@AX.8L"Q@`*@\`!B0*#1>0!BUW@.5WD#X6<_O__@\0\6UY? +XM7<.AZ.H$",<$)`H```")1"0$Z`O3___KT8E4)`3'!"0*````Z'G5___KOXL] +XM0.P$"(7_=0B%R0^$0/[__XM-T(L=#.P$"(M1!,<$)-+6!`B#Z@&-#!HQTHG( +XM]_.)1"0$Z)W4___I$_[__XM5T(E5"(/$/%M>7UWI@OS__\'@`HE$)`2A0.L$ +XM"(D$).ART___A<")PG06BTW0BT$,B15`ZP0(HXSH!`CI$OW__\<$)`````#H +XM>M3__XM=T(E=".NPC;0F`````(V\)P````!5B>575E.#[`R+=0B+'H7;#X2^ +XM````,?_K'(VV`````,<$)-W6!`B#QP+H!=3__XM;"(7;='2#>PP!=/.+0T") +XM!"3H3=7__X-["`$9TO?2@^("C00'`=`[!7SH!`AR,:'@Z@0(A+0PB%P`^%=O___X7_=":AX.H$"(7`=3Z+%>CJ!`B+0@B#Z`&%P(E" +XM"'A?BP+&``J#P`&)`H/$#%M>7UW#H>CJ!`@Q_\<$)`H```")1"0$Z&'1___K +XMFZ'HZ@0(QP0D"@```(E$)`3H2M'__X/$#%M>7UW#B50D!#'_QP0D"@```.BP +XMT___Z6?___^)5"0$QP0D"@```.B;T___ZYF0C70F`%6)Y5=64X'L7`@``(M% +XM"(LXA?\/A#,#``!F@W\R``^%*`,``,>%Q/?__P````#'A%T/?__P$```"# +XMZ`$/A+\%``")'"3H-=/__\>%R/?__P$```"-M"8`````BP:)A+\__\/ML2)5"0(B40D +XM!,<$)`?7!`CH.K^__\/C)````#'A8KZ0SZ +XM__^)5"0$QP0D"@```.B9S/__Z;3[___HS\O__X,X%@^$8O___XV=V_O__XE< +XM)`3'!"1*U`0(Z`#,___IY_G__X.]T/?__P,/CL'Y___KJI"0D)"0D)"058GE +XM@^P8H?#J!`C'1"0(/@```,=$)`0!````QP0DP-<$"(E$)`SH"A?]UIXN%8/___X'$K``` +XM`%M>7UW#C;8`````BX5@____C028B85@____Z]*)%"3H"\G__^NZD(UT)@"- +XMA7#___^#Q@&#A6#___\$@^\!QT0D"(````#'1"0$`````(D$).A)RO__ZYB+ +XMA6#___^-!+B)A6#____KBXGV58GE5U93@>RL````C85P____QT0D"(````#' +XM1"0$`````(D$).@*RO__QX5@____`````(M5"(V%'>+`H@(@\`!B0*#Q@$Y]W0HH>#J +XM!`B%P'3-H>CJ!`B+50B)1"0$#[8$%H/&`8D$).B4Q___.?=UV(M=\#'`A=MT +XM*('[_P````^'@0$``*'LZ@0(BT28-(G"@>(```#@#X18`0``B=#!Z!X!?0@! +XMA6#____I`?___SM"&`^VV7P)@/L*#X5X____B50D!(D<).BTR?__Z7#___^+ +XM%>#J!`B%T@^%F@```(L5Z.H$"(M""(/H`87`B4((#X@=`0``BP+&`#^#P`&) +XM`@%]"(.%8/___P'IH?[__XL=X.H$"(7;#X6]````BQ7HZ@0(BT((@^@!A<") +XM0@@/B/T```"+`L8`/X/``8D"C95P____@T4(`8.%8/___P''1"0(@````,=$ +XM)`0`````B10DZ$G(___I1/[__XD<).C,QO__Z9+^__^AZ.H$",<$)#\```") +XM1"0$Z'+&___I;?___XL-X.H$"(7)#X6N````BQ7HZ@0(BT((@^@!A<")0@@/ +XMB+$```"+`L8`/X/``8D"@X5@____`8N%8/___X'$K````%M>7UW#H>CJ!`C' +XM!"0_````B40D!.@1QO__Z4K___\E```$`(/X`1G`@\@!Z9O^__^)'"3H,L;_ +XM_^E[_O__.T(8#XW:_O__B50D!,<$)#\```#H5,C__^G/_O__.T(8#XWZ_O__ +XMB50D!,<$)#\```#H-LC__^GO_O__H>CJ!`C'!"0_````B40D!.B%8/___P````"+ +XM50B-A7#___^)1"0,C47PQT0D"`8```")!"2)5"0$Z+S$__^%P(GR`0`` +XM@_[^#X10`0``@_[_B?8/A.P````QVX7V?S2-="8`ZU>+10B+%>CJ!`@/M@P# +XMBT((@^@!A<")0@@/B)0```"+`H@(@\`!B0*#PP$YWG0IBSW@Z@0(A?]TR*'H +XMZ@0(BU4(B40D!`^V!!.#PP&)!"3HG\3__SG>==>+7?`!=0B!^_\```!W<*'L +XMZ@0(BT28-*D```0`#X0Y____,<"%VW0H@?O_````#X?J````H>SJ!`B+1)@T +XMB<*!X@```.`/A,$```")T,'H'@&%8/___^D`____.T(8#[;Y?`J)^#P*#X5: +XM____B50D!(D\).BBQO__Z5+___^)'"3H5<3__Y#KCHV%XM%"(L5Z.H$"`^V"(M""(/H`87` +XMB4((>'N+`H@(@\`!B0*#10@!@X5@____`>EY_O__BU4(QP0D2M0$"(E4)`3H +XMAL7__P&%8/___XN%8/___X'$K````%M>7UW#)0``!`"#^`$9P(/(`>DR____ +XMB1PDZ+7#___I$O___Z'HZ@0(BU4(B40D!`^V`HD$).A9P___ZXX[0A@/MME\ +XM"8#["@^%=/___XE4)`2)'"3HNL7__^EL____D%6)Y5=64X'LK````(V%%8/___P````"+50B-A7#___^) +XM1"0,C47PQT0D"`8```")!"2)5"0$Z'S"__^%P(F%7/___P^$;@,``(N%7/__ +XM_X/``H/X`0^&`0$``(M=\('[_P````^'D`,``*'LZ@0(BT28-*D```0`#X0$ +XM`P``@_LB#X3[`@``@_M<#X3R`@``B[U<____A?]^9C';ZS*+10B+%>CJ!`@/ +XMM@P#BT((@^@!A<")0@@/B!L#``"+`H@(@\`!B0*#PP$[G5S___]T+8LUX.H$ +XM"(7V=,2AZ.H$"(M5"(E$)`0/M@03@\,!B00DZ"+"__\[G5S___]UTXM=\#'` +XMA=MT*('[_P````^'N0,``*'LZ@0(BT28-(G"@>(```#@#X2*`P``B=#!Z!X! +XMA6#___^#O5S____^#X1V`@``@[U<_____P^$N@(``(N57/___P%5".F[_O__ +XM@[U<_____P^%7P(``+\!````,?;IV````(L5Z.H$"(M""(/H`87`B4((#XB7 +XM`0``BP+&`%R#P`&)`J'@Z@0(A<`/A>````"+%>CJ!`B)V,#H!@^VP(U(,(M" +XM"(/H`87`B4((#X@^`0``BP*("(/``8D"H>#J!`B%P`^%V````(L5Z.H$"(G8 +XMP.@#@^`'C4@PBT((@^@!A<")0@@/B$8!``"+`H@(@\`!B0*AX.H$"(7`#X70 +XM````BQ7HZ@0(B=B#X`>-2#"+0@B#Z`&%P(E""`^(,0$``(L"B`B#P`&)`H/& +XM`8.%8/___P0Y_@^-Y_[__Z'@Z@0(BU4(A<`/MAP6#X04____H>CJ!`C'!"1< +XM````B40D!.BAP/__H>#J!`B%P`^$(/___Z'HZ@0(B40D!(G8P.@&#[;`@\`P +XMB00DZ'C`__^AX.H$"(7`#X0O____C;0F`````*'HZ@0(B40D!(G8P.@#@^`' +XM@\`PB00DZ$C`__^AX.H$"(7`#X0W____C;0F`````*'HZ@0(B40D!(G8@^`' +XM@\`PB00DZ!O`___I.O___XGV.T(8?`F`^0H/A;3^__^)5"0$B0PDZ'K"___I +XMK/[__Y`[0A@/C6#^__^)5"0$QP0D7````.A;PO__Z57^__^)]CM"&'P)@/D* +XM#X6L_O__B50D!(D,).@ZPO__Z:3^__^0.T(8?`F`^0H/A<'^__^)5"0$B0PD +XMZ!K"___IN?[__XL-[.L$"(7)=!"%VW@,@?O_````#XZ3````B[U<____A?\/ +XMC\3]__^#O5S____^#X6*_?__BX5@____@<2L````6UY?7<.+10B)!"3HA,+_ +XM_XG'Z\L[0A@/MO%\"HGP/`H/A=/\__^)5"0$B30DZ*+!___IR_S__XD<).A5 +XMO___D.EK_/__C85P____QT0D"(````#'1"0$`````(D$).BAP/__@T4(`>GH +XM^___#[[#B40D!,<$)/_7!`CH%<#__X7`B<,/A%#___^+%>#J!`B%T@^%E0`` +XM`(L5Z.H$"(M""(/H`87`B4((#XBR````BP+&`%R#P`&)`J'@Z@0(ACJ!`C'!"1<````B40D!.@3OO__Z7+___\[41A\ +XM!SP*C78`=8F)3"0$B1PDZ';`___KA#M"&`^-1?___XE4)`3'!"1<````Z%O` +XM___I.O___Y"058GE5U:#[#"+50R+10B+=1"+?12)5=R+3=R)1=C'1=`````` +XMB?#'1=0`````B?J%R<=%Y``````/B*0```"%_P^(N@```(G7B<:+5=B)P8M% +XMW(7_B57PB47L=10YQG9!B="+5>SW]HG!,<#K$XUV`#M]['9/,R)^O?QB<:+1?#W\8G!B?#KO`^]QX/P'XE%Z'5$.7WL=P4Y=?!R +XMG+D!````,<#KGO==V(-5W`#W7=R%_\=%Y/____\/B4O___^0C70F`(GPB?KW +XMV(/2`/?:]U7DZ3/___^X(````(GR*T7HB<'3Z@^V3>B)1?2)^(G7BU7LT^`) +XMQXM%\-/F#[9-]-/H#[9-Z-/B#[9-]`G0BU7LB47,T^KW]XE5S(G']^8Y5'`@)`!, +XM4U]#3TQ724142%,`;6%L;&]C`"5S.B`EC!`@^HP0(D:D$""VG +XM!`@MIP0(+:<$""VG!`@MIP0(+:<$""VG!`@MIP0(+:<$""VG!`@MIP0(+:<$ +XM""VG!`@MIP0(+:<$"%^I!`ANJ00(S:D$""VG!`@MIP0(M*D$"!>K!`@/JP0( +XM`*L$""VG!`@MIP0(]:H$""VG!`@MIP0(+:<$".JJ!`@MIP0(VZH$",*J!`BS +XMJ@0(>*P$""VG!`AIK`0(+:<$""VG!`A:K`0(+:<$""VG!`@MIP0(+:<$""VG +XM!`@MIP0(7*D$"#>L!`@4K`0(^ZL$""VG!`CLJP0(!J<$"-VK!`C.JP0(+:<$ +XM"+6K!`B2JP0(;ZL$"&"K!`A1JP0(.*L$")"J!`B!J@0("4P +XM.'@@`"4S9"P@)3-D(``E*G,E*FID(``E-7,@``IL&1X8GAE9V5D86)A9V%C860`3%-#3TQ/4E,@I$$"(J1 +XM!`B:D00(JI$$"+J1!`C*D00(VI$$".J1!`CZD00("I($"!J2!`@JD@0(.I($ +XM"$J2!`A:D@0(:I($"'J2!`B*D@0(FI($"*J2!`BZD@0(RI($"-J2!`CJD@0( +XM^I($"`J3!`@:DP0(*I,$"#J3!`A*DP0(6I,$"&J3!`AZDP0(```````````` +XM)$9R965"4T0Z('-R8R]L:6(O8W-U+V-O;6UO;B]C'`@)`!'0T,Z("A'3E4I(#0N +XM,BXQ(#(P,#6YA;6EC`"YC=&]Rmake.uu << 'ed78d4936f2c86b3dc64cf5324ab8f8b' +Xbegin 644 make +XM?T5,1@(!`0````````````(`/@`!````$"A```````!``````````'BY`0`` +XM`````````$``.``*`$``&P`8``8````%````0`````````!``$```````$`` +XM0```````H`(```````"@`@````````@``````````P````0```#@`@`````` +XM`.`"0```````X`)````````3`````````!,``````````0`````````!```` +XM!0````````````````!``````````$```````-Z``0``````WH`!```````` +XM`!````````$````$````X(`!``````#@@%$``````."`40``````\"@````` +XM``#P*```````````$````````0````8`````L`$```````"P80```````+!A +XM``````#X!````````/@$```````````0```````!````!@```/BT`0`````` +XM^+1Q``````#XM'$``````)@#````````F`,``````````!````````$````& +XM````D+@!``````"0N($``````)"X@0`````````````````8)0`````````` +XM$````````@````8```"PLP$``````+"S80``````L+-A``````!``0`````` +XM`$`!````````"``````````$````!````/0"````````]`)```````#T`D`` +XM`````!@`````````&``````````$`````````%'E=&0&```````````````` +XM``````````````````````````````````````````@````````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````"]U``` +XM```````#````$@```$\```!D`````````````````````````%0````[```` +XM9@```'H````Y`````````!X```!7````5@```'<```!P````10````H````_ +XM````*0````````!B`````````%$```!0`````````'8```!?````90```#,` +XM``!T````<@```&D````P````;P````````!:````2P```!\`````````$P`` +XM``````!]````0`````````V```` +XM;@```"P`````````'0````````!5`````````$H```!>````70````````![ +XM````<0``````````````,0````````!)````-P``````````````0````%(` +XM```T````00`````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````0```````````````P````:``````````@````9 +XM``````````````````````````````````````````D````4`````````"@` +XM```-`````````"<````@`````````"4``````````````!8````J````(@`` +XM```````%`````0````(````D```````````````C````,@`````````````` +XM#@``````````````/@```"X```````````````````!&`````````$0````U +XM````!P`````````M````%P```#@`````````/````"\`````````3``````` +XM```1`````````"$``````````````$(`````````/0```"L````/````$``` +XM```````;``````````L`````````30````````!@````2``````````Z```` +XM````````````````;``````````5````:````"8````<````!@````````!# +XM````8P```%,```!'```````````````````````````````````````````` +XM```.````$@```)`A0```````A@`````````6````$@```*`A0``````````` +XM```````D````$@```+`A0```````U@`````````M````$@```,`A0``````` +XM!P````````!Z`P``$@```-`A0```````O@````````"^`@``$@```.`A0``` +XM````AP`````````U````$@```/`A0``````````````````\````$@`````B +XM0```````=0````````!/````$@```!`B0```````)`````````!8````$@`` +XM`"`B0```````8P$```````!A````$0`6`)"X@0``````0`````````!S```` +XM$0#Q_["S80````````````````!\````$@```#`B0```````"`````````"S +XM`P``$``5`)"X<0````````````````"$````$@```$`B0```````?P`````` +XM``"+````$@```%`B0```````0P````````"2````$@```&`B0``````````` +XM``````"9````$@```'`B0```````0@$```````"O````$@```(`B0``````` +XM-P````````"[````$@```)`B0```````Q`$```````#"````$@```*`B0``` +XM````\P````````!)`P``$@```+`B0```````^P````````#)````$@```,`B +XM0`````````````````#.````$@```-`B0```````40````````#3````$@`` +XM`.`B0```````$P$```````#:````$0`6`-"X@0``````"`````````#A```` +XM$@```/`B0`````````````````#H````$@`````C0```````4@````````#P +XM````$@```!`C0```````R@````````#W````$@```"`C0```````&``````` +XM``#]````$@```#`C0``````````````````%`0``$@```$`C0```````&P`` +XM```````0`0``$@```%`C0```````"P`````````A`0``$@```&`C0``````` +XM'P`````````O`0``$@```'`C0```````.0(````````V`0``$@```(`C0``` +XM```````````````[`0``$@```)`C0```````PP$```````!!`0``$@```*`C +XM0```````(0````````!)`0``$@```+`C0```````4`````````!6`0``$@`` +XM`,`C0```````AP$```````!=`0``$@```-`C0```````Q1,```````#<`@`` +XM$@```.`C0`````````````````"G`P``$``1`/BT<0````````````````!D +XM`0``$0`6``#<@0``````"`````````!Y`P``$@```/`C0```````I0`````` +XM``!L`0``$0`6`-BX@0``````"`````````!Z`0``$@`````D0``````````` +XM``````"``0``$@```!`D0```````!0````````"&`0``$0`6`."X@0`````` +XM!`````````"-`0``$@```"`D0```````)@````````"4`0``$@```#`D0``` +XM````%`````````"9`0``$0`-``"P80``````"`````````"D`0``$@```$`D +XM0`````````````````"J`0``$@```%`D0```````;0````````"Q`0``$@`` +XM`&`D0```````=0`````````!`@``$@```'`D0`````````````````"X`0`` +XM$@```(`D0```````J0$```````#!`0``$@```)`D0```````,P````````#) +XM`0``$@```*`D0``````````````````F````$@```+`D0```````_0$````` +XM``#0`0``$@```,`D0```````,@````````#:`0``$@```-`D0```````0P8` +XM``````#B`0``$@```.`D0```````*P````````#I`0``$0`6`/"X@0`````` +XMR`$```````#N`0``$@```/`D0`````````````````#S`0``$@`````E0``` +XM````&@````````#Y`0``$@```!`E0```````(P```````````@``$@```"`E +XM0```````#`$````````&`@``$@```#`E0```````KP<````````.`@``$@`` +XM`$`E0```````;P`````````F`@``$@```%`E0```````W``````````9`@`` +XM$0`6`+BZ@0``````!`````````#$`P``$`#Q_Y"X@0`````````````````L +XM`@``$@```&`E0```````"@`````````S`@``$@```'`E0```````;0`````` +XM```]`@``$@```(`E0```````'P````````!$`@``$@```)`E0```````W``` +XM``````!,`@``$@```*`E0```````"P$```````#0`P``$0`6`!#<@0`````` +XM``$```````!3`@``$@```+`E0```````)1$```````#6`@``$@```,`E0``` +XM````-`````````!;`@``$@```-`E0```````.0````````!C`@``$@```.`E +XM0```````.`````````!R`@``$@```/`E0```````3@````````!_`@``$@`` +XM```F0```````5P````````#&`@``$@```!`F0```````2P````````".`@`` +XM$@```"`F0```````'0````````"5`@``$@```#`F0```````=`````````"< +XM`@``$@```$`F0```````"0````````"C`@``$@```%`F0```````-``````` +XM``"K`@``$0`6`+RZ@0``````!`````````#C`P``$@`+`-"`00`````````` +XM``````"T`@``$@```&`F0```````*0$```````"]`@``$@```'`F0``````` +XM0P$```````#%`@``$@```(`F0```````40````````#+`@``$@```)`F0``` +XM````Y`$```````#2`@``$@```*`F0```````=@````````"E`0``$@```+`F +XM0`````````````````#;`@``$@```,`F0```````R0````````"]`P``$`#Q +XM_Y"X@0````````````````#B`@``$0#Q__BT<0````````````````"X`P`` +XM$`#Q_ZC=@0`````````````````;`P``$@```-`F0```````%@````````#X +XM`@``$0`6`,"Z@0``````"``````````&`P``$@```.`F0```````#``````` +XM```+`P``$0`6`,BZ@0``````"``````````3`P``$@```/`F0```````10`` +XM```````:`P``$@`````G0``````````````````@`P``$@```!`G0``````` +XM-``````````G`P``$@```"`G0```````'@`````````G`@``$@```#`G0``` +XM```````````````N`P``$@```$`G0```````-P`````````Y`P``$@```%`G +XM0```````>`````````!!`P``$@```&`G0```````(P````````!(`P``$@`` +XM`'`G0```````F`````````!.`P``$@```(`G0```````&@````````":`P`` +XM$``-``"P80````````````````!5`P``$@```)`G0```````C@````````!> +XM`P``(`````````````````````````!R`P``$@```+`G0``````````````` +XM``!-`@``$@```,`G0`````````````````!X`P``$@```-`G0```````6@`` +XM``````"!`P``$@```.`G0```````*``````````\`P``$@```/`G0``````` +XM\0````````".`P``$@`````H0```````````````````;&EB8RYS;RXV-2XP +XM`'!U=&-H87(`8VQO8VM?9V5T=&EM90!U;G-E=&5N=@!W86ET<&ED`'5T:6UE +XM&5C=G``8VQO``````````````#@M7$```````<````?``````````````#H +XMM7$```````<````@``````````````#PM7$```````<````A```````````` +XM``#XM7$```````<````B````````````````MG$```````<````C```````` +XM```````(MG$```````<````D```````````````0MG$```````<````E```` +XM```````````8MG$```````<````F```````````````@MG$```````<````G +XM```````````````HMG$```````<````H```````````````PMG$```````<` +XM```I```````````````XMG$```````<````J``````````````!`MG$````` +XM``<````M``````````````!(MG$```````<````O``````````````!0MG$` +XM``````<````P``````````````!8MG$```````<````R``````````````!@ +XMMG$```````<````S``````````````!HMG$```````<````U```````````` +XM``!PMG$```````<````V``````````````!XMG$```````<````W```````` +XM``````"`MG$```````<````X``````````````"(MG$```````<````Y```` +XM``````````"0MG$```````<````Z``````````````"8MG$```````<````[ +XM``````````````"@MG$```````<````\``````````````"HMG$```````<` +XM```]``````````````"PMG$```````<````^``````````````"XMG$````` +XM``<````_``````````````#`MG$```````<```!!``````````````#(MG$` +XM``````<```!"``````````````#0MG$```````<```!#``````````````#8 +XMMG$```````<```!$``````````````#@MG$```````<```!%```````````` +XM``#HMG$```````<```!&``````````````#PMG$```````<```!'```````` +XM``````#XMG$```````<```!*````````````````MW$```````<```!+```` +XM```````````(MW$```````<```!,```````````````0MW$```````<```!- +XM```````````````8MW$```````<```!.```````````````@MW$```````<` +XM``!0```````````````HMW$```````<```!1```````````````PMW$````` +XM``<```!2```````````````XMW$```````<```!3``````````````!`MW$` +XM``````<```!4``````````````!(MW$```````<```!5``````````````!0 +XMMW$```````<```!6``````````````!8MW$```````<```!7```````````` +XM``!@MW$```````<```!8``````````````!HMW$```````<```!9```````` +XM``````!PMW$```````<```!:``````````````!XMW$```````<```!=```` +XM``````````"`MW$```````<```!>``````````````"(MW$```````<```!? +XM``````````````"0MW$```````<```!@``````````````"8MW$```````<` +XM``!A``````````````"@MW$```````<```!B``````````````"HMW$````` +XM``<```!C``````````````"PMW$```````<```!G``````````````"XMW$` +XM``````<```!I``````````````#`MW$```````<```!K``````````````#( +XMMW$```````<```!L``````````````#0MW$```````<```!M```````````` +XM``#8MW$```````<```!N``````````````#@MW$```````<```!O```````` +XM``````#HMW$```````<```!P``````````````#PMW$```````<```!Q```` +XM``````````#XMW$```````<```!R````````````````N'$```````<```!S +XM```````````````(N'$```````<```!T```````````````0N'$```````<` +XM``!V```````````````8N'$```````<```!W```````````````@N'$````` +XM``<```!X```````````````HN'$```````<```!Y```````````````PN'$` +XM``````<```!Z```````````````XN'$```````<```![``````````````!` +XMN'$```````<```!\``````````````!(N'$```````<```!]```````````` +XM`````````````$B#[`CHYP<``$B#Q`C#``#_-7J3,0#_)7R3,0"0D)"0_R5Z +XMDS$`:`````#IX/____\E#^____ +XM)?*2,0!H$0```.G0_O___R7JDC$`:!(```#IP/[___\EXI(Q`&@3````Z;#^ +XM____)=J2,0!H%````.F@_O___R72DC$`:!4```#ID/[___\ERI(Q`&@6```` +XMZ8#^____)<*2,0!H%P```.EP_O___R6ZDC$`:!@```#I8/[___\ELI(Q`&@9 +XM````Z5#^____):J2,0!H&@```.E`_O___R6BDC$`:!L```#I,/[___\EFI(Q +XM`&@<````Z2#^____)9*2,0!H'0```.D0_O___R6*DC$`:!X```#I`/[___\E +XM@I(Q`&@?````Z?#]____)7J2,0!H(````.G@_?___R5RDC$`:"$```#IT/W_ +XM__\E:I(Q`&@B````Z<#]____)6*2,0!H(P```.FP_?___R5:DC$`:"0```#I +XMH/W___\E4I(Q`&@E````Z9#]____)4J2,0!H)@```.F`_?___R5"DC$`:"<` +XM``#IJ1,0!H,@```.G` +XM_/___R7BD3$`:#,```#IL/S___\EVI$Q`&@T````Z:#\____)=*1,0!H-0`` +XM`.F0_/___R7*D3$`:#8```#I@/S___\EPI$Q`&@W````Z7#\____);J1,0!H +XM.````.E@_/___R6RD3$`:#D```#I4/S___\EJI$Q`&@Z````Z4#\____):*1 +XM,0!H.P```.DP_/___R6:D3$`:#P```#I(/S___\EDI$Q`&@]````Z1#\____ +XM)8J1,0!H/@```.D`_/___R6"D3$`:#\```#I\/O___\E>I$Q`&A`````Z>#[ +XM____)7*1,0!H00```.G0^____R5JD3$`:$(```#IP/O___\E8I$Q`&A#```` +XMZ;#[____)5J1,0!H1````.F@^____R52D3$`:$4```#ID/O___\E2I$Q`&A& +XM````Z8#[____)4*1,0!H1P```.EP^____R4ZD3$`:$@```#I8/O___\E,I$Q +XM`&A)````Z5#[____)2J1,0!H2@```.E`^____R4BD3$`:$L```#I,/O___\E +XM&I$Q`&A,````Z2#[____)1*1,0!H30```.D0^____R4*D3$`:$X```#I`/O_ +XM__\E`I$Q`&A/````Z?#Z____)?J0,0!H4````.G@^O___R7RD#$`:%$```#I +XMT/K___\EZI`Q`&A2````Z<#Z____)>*0,0!H4P```.FP^O___R7:D#$`:%0` +XM``#IH/K___\ETI`Q`&A5````Z9#Z____)````Z0#Z____)8*0,0!H7P```.GP +XM^?___R5ZD#$`:&````#IX/G___\E534$B+!5./,0!(A$B)59!)B?=(B?M(B9UH____2(U]F+X``0``Z!`3``!(BP-(B470,%(B=](BW60Z'4B`0"%P`^$+`0``+D!````3(MUT.O23(E]@(7)="Z) +XMC7#___],B>=,B?9(BU60N0$```#HT"H!`$B)PTB)W^A%_/__2`'83(MUT.L, +XMB8UP____3(GP3(GC2(F=>/___TG_QDR)==!(*=A(B46(3(UEF.L5#Q]$``!, +XMBW709F9F+@\?A```````00^V!C'22#W_````38GW="\QTDB+#8Z/00#V1`@! +XM"$V)]W0<2?_&3(EUT.O##Q\`2?_'3(E]T&8/'X0``````$$/M@=(/?\```!T +XMY(3`#X11`P``/"ET/$B+#4F/00#V1`@!"'4F/"1UQDB-?=!(BW60Z'DA`0`Q +XMVX7`#X0_`P``N@$```!,BWW0Z[2$P`^$$0,``$TY_@^$/0,``(72B95T____ +XM3(GW3(G^#X3L````2(M5D+D!````Z,$I`0!)B<5,B>=(BW6(2(N5>/___^C+ +XM$```2(M%H$B+3:A(*<%(@_D!?PQ,B>?H4A```$B+1:!(C4@!2(E-H,8`*$R) +XM[^C[^O__3(GG2(G&3(GJZ(T0``!(BT6@2(M-J$@IP4B#^0%_#$R)Y^@4$``` +XM2(M%H$B-2`%(B4V@Q@`I2(M%H,8``$B+79A(B5W(3(GOOB0```#HZ?K__TB% +XMP`^$]0```$TI]TR)[TR)]DR)^NA/^/__A<`/A=P```!(B=\Q]KH!````Z$CP +XM``"`2!H@2(M]@$B)QN@H3P$`Z=,```#HSD```(7`3(MM@`^%SP```$R)YTB+ +XM=8A(BY5X____Z-\/``!(BT6@2(M-J$@IP4B#^0%_#$R)Y^AF#P``2(M%H$B- +XM2`%(B4V@Q@`H32GW3(GG3(G^3(GRZ*8/``!(BT6@2(M-J$@IP4B#^0%_#$R) +XMY^@M#P``2(M%H$B-2`%(B4V@Q@`I2(M%H,8``$B+?9@Q]KH!````Z)?O``"` +XM2!H@3(GO2(G&Z'A.`0!(BT682(E%H.DO`0``2(U]R$B+=8!(BU60Z)K\__\Q +XMVX7`#X10`0``2(M%F$B)1:#I"@$```]7P`\I1;!(BQ4%@R$`3(GW3(G^2(U= +XML$B)V>AC.@``2(G?Z`M/`0!(B<-(A=M,B[UX____#X3(````#Q^$``````!, +XMB>=(BW6(3(GZZ-$.``!(BT6@2(M-J$@IP4B#^0%_#$R)Y^A8#@``2(M%H$B- +XM2`%(B4V@Q@`H2(G?Z`'Y__],B>=(B<9(B=KHDPX``$B+1:!(BTVH2"G!2(/Y +XM`7\,3(GGZ!H.``!(BT6@2(U(`4B)3:#&`"E(B=_HD_G__TB+1:#&``!(BWV8 +XM,?:Z`0```.A\[@``@$@:($R)[TB)QNA=30$`2(M%F$B)1:!(C7VPZ#Q.`0!( +XMB<-(A=L/A4#___],B6V`38GU@[UT____``^$7/S__TR)[^@T^?__3(MUT.E; +XM_/__OT""40#HX?/__S';9F9F9F9F+@\?A```````2(M]F.@'^?__B=A(@\1X +XM6T%<05U!7D%?7<.#O7#___\`=!!(B[UX____Z.'X__],BW702?_&9BX/'X0` +XM`````$R)\$B)1=`/M@A(@?G_````=!),C7`!2(L5BHM!`/9$$0$(==M(BXUH +XM____2(D!NP$```#KBF8N#Q^$``````!52(GE05=!5D%505132('LB`0``$B) +XM^$B+#1*)00!(B4W02(NXL````$R+H+@```!(QX6P^___`````+XS@E$`Z*OU +XM__\QVTB%P`^$H`(``$B-?>^_(!1`+H#````Z(7S__^%P`^%N````$$/ +XMMD0D`T@]_P````^$I@```$B+#4R)00#V1`@!!`^$E````$F#Q`-,B>?H3?7_ +XM_XG#C4/_/?X#```/AYL```!,8^-,B?],B>:Z`0```$B+C6C[___H8_/__TB# +XM^`%U>_?;2&/S2(N]:/O__[H!````Z#?R__^%P'5A0L:$)<#[__\`]@5?JT$` +XM04R)^W0/OPN"40!(B=XPP.C/[___2(G?28G?2(NU8/O__^@-]/__A<`/A+0` +XM``!)_\5)@^7^2(N]:/O__TR)[KH!````Z-KQ__^%P`^$\OW__TB+O6C[___H +XM5O/__S';#Q]``$B%VW1;,?_H9//__TACR$B-O8#[__^^#````+HV@E$`,,#H +XMJ>___TB)WTC'QL3___^Z`0```.B%\?__AP````3(N_N````$C'A5C[__\`````3(G_OB\```#H5/#__TB)PTB-E5C[ +XM__^_,+N!`$R)]NA]\O__B84\^___OS"[@0")QNC+[___28G$2(7;2(U#`4D/ +XM1,=(B85(^___387D=`Q,B[5(^___Z<(```!(BX58^___2(F%L/O__TC'A:#[ +XM__\`````3(GWOC"140#HC_'__TB%P$&\`````'1D2(U]R+X(````N@$```!( +XMB<%(B850^___Z#?Q__](@_@!=1M(C7W(OO"`40"Z"````.B.\/__A<`/A#P! +XM``!(B[U0^___Z(KQ__]F+@\?A```````13'D9F9F9BX/'X0``````+@```"` +XM387D3(NU2/O__XNU//O__[H`````#X3"````OS"[@0!,B>+H4^___TC'A5C[ +XM__\`````2(V56/O__TR)YTR)]NAF\?__3(GGB<;HO.[__TB)PTB%VW4_2(N% +XM6/O__TPI\$B#^!%R;TF-1A!(B858^___2(V56/O__TR)YTR)]N@G\?__3(GG +XMB<;H?>[__TB)PTB%VW1`@3L```"`=3!(@WL(`'4I2(U[$#'VN@H```#HAN[_ +XM_XD#2,=#"``````]````@'4(2,=#"`$```!(BU,(BP/K![@```"`,=)(BXU` +XM^___B4$H2(E1,$B+!6F#00!(.T70#X41`P``BT$H2('$N`0``%M!7$%=05Y! +XM7UW#2(V5L/O__[\PL&$`3(GVZ*;L__](B<=)B<6^"````+H(L&$`Z-'O__], +XMC;W`^___9BX/'X0``````$B-O6#[__^^`0```+H\````2(N-4/O__^B#[___ +XM2(G#2(7;=2&#/0R%00``#X0S`@``2(N]4/O__^@2[?__A<`/A2P"``!(@_L\ +XM#X)"`@``2(V%FOO__V:!.&`*#X4P`@``2(V-D/O__V:+00AFB06$A4$`2(L! +XM2(D%^_(!1`+H#````Z#/N +XM__^%P`^%K````$$/MD8#2#W_````#X2;````2(L-^X-!`/9$"`$$#X2)```` +XM28/&`TR)]^C\[___C4C_@?G^`P``#XN@$```!(BXU0 +XM^___Z!/N__](@_@!#X7[````QH0=P/O__P#WVTAC\TB+O5#[__^Z`0```.C; +XM[/__A<`/A=4```#V!0BF00!!38G^=!B_`(%1`$R)^TB)WC#`Z'7J__])B=Y) +XMB=],B>],B?;H].O__XG#2,>%N/O__P````"_"+!A`$R)]DB-E;C[___H<^K_ +XM_TB-E7#[__^+2@B)2!A(BPI(B4@0QD`<`,<`````@$C'0`@`````3(GOB=Y( +XMB<+H\.O__TG_Q$F#Y/Y(B[U0^___3(GFN@$```#H->S__X7`#X2=_?__ZRU( +XMBX50^___]D`0('0@2(N]H/O__^CR[___2(N]4/O__^B6[?__38GLZ1[\__]( +XMB[U0^___Z(+M__],B>M(B=_HM^___TB+O:#[___HN^___TB)W^BS[___Z=[[ +XM___H">O__V8/'X0``````%5(B>5!5T%6055!5%-028G_28V'*`$``$B)1=!- +XMC7=@ZQ)F9F9F9BX/'X0``````$F#Q@A-BS9-A?8/A)H```!-BV800?9$)!H@ +XM=0I!@'PD!0!TW.MT28V\)"@!``"^*````.BH[O__2(G#2(7;=,!(_\-(B=^^ +XM*0```.B0[O__28G%08!\)`4`=*5-A>UTH$DIW4B)WTB+==!,B>KHGNO__X7` +XM=8I#@+PO*`$````/A7O___],B>?H\_G__T&)1RA)B5L\N`$```!\-8M'.#G!=1%(BUZ +XM"````.@XZO__28G'1(GWZ'WM__\QVTF#_PAU%$BX(3QA!U#8G82(/$&%M!7D%?7BAZ?__2(/X`75328L&2(T,&$B)3=`Q]DB%VWX@ +XM9@\?A```````@#@O=0K&``!(_\9(BTW02/_`2#G(05]=PV9F+@\?A```````54B)Y4%7059!54%44U!)B==) +XMB?9)B?Q)C48!38ML)`A)BUPD$$B)V4PIZ4@YP7-*28L\)$@I^TDI_4F-A@$! +XM``!F9F9F9F8N#Q^$``````!(`=M(B=E,*>E(.<%R\DB)WN@JD0``28D$)$D! +XMQ4V);"0(2`'828E$)!!,B>],B?Y,B?+H2.7__TT!="0(2(/$"%M!7$%=05Y! +XM7UW##Q]``%5(B>5!5E-)B?Y(A?:[``$``$@/1=Y(B=_H$I```$F)!DF)1@A( +XM`<-)B5X06T%>7<-F9F9F9F8N#Q^$``````!(BP=(BT\(2/_`ZPL/'T``2/_) +XM2(E/"$@YP78A#[91_TB!^O\```!T%$B+-?A\00#V1#(!"'0&@'G^7'73PY"0 +XM54B)Y4%7059!54%44TB![%@$``!)B?9(BP62>D$`2(E%T$G'!@````!(QX6P +XM^___Z()1`$C'A;C[___"@E$`2(F]P/O__TC'AN"40!!@_S_=1))B0Z__*A1`.B9CP`` +XMZ08!``!%A>0/A!P!``"+O:S[___H0.G__TR-O8C[__],B?^^``$``.C,_O__ +XM3(VMT/O__^L3#Q\`3(G_2(G&3(GJZ!+^__]FD(N]J/O__TR)[KH`!```Z*WE +XM__](A05]=PXN]J/O__^@DZ/__B[VL^___ +XM@_\!=!6^`0```.@/X___B[VL^___Z`3H__](C;6P^___O^."40#H,^7__[\! +XM````Z"GG___H=./__Y"0D)!52(GE05=!5E-028G^13'_,?_HV3P``(,]8IU! +XM``!U4$B+/8&=00#HE#@``$4Q_X/X!'4\ORV$40#HDN+__[\!````Z*CF__\/ +XM'X0``````$B!PR@!``"_5X-1`$B)WC#`Z(KA__]!_\GM +XM-P``9F9F9BX/'X0``````%5(B>5!5T%605132(GS28G_]@5TG$$`0'0F2(V# +XM*`$``$B%V[Z=D%$`2`]%\$F-ER@!``"_>X-1`##`Z-#@__]).=\/A$<"``!, +XMB?_H;^4``$B%VTV)_G063(G_2(G>Z,S^``"%P$F)W@^%(0(``$'V1AD(="E) +XMC46900``=1Q,B?_H"R,``#T```"`=1A,B?_H +XM_"(``$B%TG4+28UW*#'_Z`S>__])C4\X28U'*$&+5RA!BWE`+0``OP$```#H5N+__TF+G^````"_Y8-1`#'VZ#,'`0!( +XMB<9(@_L`=1:_[8-1`##`Z"[=__^_`0```.@DXO__28N/V````$F+E^````"_ +XMQ8-1`##`Z`K=__^_`0```.@`XO__54B)Y4%705934$F)_DR)\$B)PTB)7>`/ +XMM@M(@?G_````="E(C4,!2(L5RG5!`/9$$0$"==NX`@```(#Y+@^$[04``(#Y +XM.@^$Y`4``$B-=>!,B??HV.#__XG!N/W`#_Q(#Z_!2,'H)FO`08G**<),*?.X +XM`@```(/Z.W]D@_HR#X^;````@_HN#X_W````@_HD#X\P`0``@_H<#X]$`@`` +XM@\+U@_H-#X>%!0``_R358(11`+@"````@?E"'@``#X5M!0``2(/[!`^%8P4` +XM`$R)][Z$AE$`N@0```#I8P,``(/"Q(/Z`P^'104``/\DU4"$40"X`@```('Y +XMP@$```^%+04``$B#^P(/A2,%``!,B?>^9(91`+H"````Z?4!``"#^C,/A0@% +XM``"X`@```('Y*1X```^%]P0``$B#^P0/A>T$``!,B?>^5(91`+H$````Z&O> +XM__^)P;@"````A@<` +XM#X50!```2(/[!P^%1@0``$R)][Y$AE$`N@<```#HQ-W__XG!N`(```"%R0^% +XM)00``+A0A5$`13'_Z4<#``"X`@```('YF=X!``^%!P0``$B#^P8/A?T#``!, +XMB?>^.X91`+H&````Z'O=__^)P;@"````A'@`/A;X#``!(@_L(#X6T`P``3(GWOCF&40"Z"````.@RW?__ +XMB<&X`@```(7)#X63`P``N("%40!%,?_IM0(``('YI58'`'4G2(/[!W4A3(GW +XMOG2&40"Z!P```.CVW/__B<&X!0```(7)#X17`P``N`(```#I30,``(/Z'0^% +XM1`,``+@"````@?DR=P``#X4S`P``2(/[!0^%*0,``$R)][XJAE$`N@4```#H +XMI]S__XG!N`(```"%R0^%"`,``+@@A5$`13'_Z2H"``"#^B9U7+@"````@?D" +XM>0``#X7E`@``2(/[!0^%VP(``$R)][YAAE$`N@4```#H6=S__XG!N`(```"% +XMR0^%N@(``(L%1'-!`(7`#X1Z`@``_\B)!31S00"X`0```.F:`@``@_HI#X61 +XM`@``N`(```"!^9EZ>0`/A8`"``!(@_L)#X5V`@``3(GWOD*&40"Z"0```.CT +XMV___B<&X`@```(7)#X55`@``N)"%40!%,?_I=P$``+@!````@SW,`0``N`(```#IE`$``('Y,FD``'4G2(/[!74A +XM3(GWOF>&40"Z!0```.@$V___B<&X!````(7)#X1E`0``N`(```#I6P$``+@" +XM````@?DRW@$`#X5*`0``2(/[!@^%0`$``$R)][XRAE$`N@8```#HOMK__XG! +XMN`(```"%R0^%'P$``+@PA5$`13'_ZT2X`@```('Y,EX>``^%!`$``$B#^P@/ +XMA?H```!,B?>^,(91`+H(````Z'C:__^)P;@"````A& +XM40!,B?(PP.CT-0``N`(```#I^O[__V8N#Q^$``````!52(GE059308G^9@\? +XM1```1(GWZ&@-``")P[@)````@_L)=")$B??H)````(/X`W4-A=MTVS'_Z,3_ +XM___K!HD%"&0A`(G86T%>7<,/'T0``%5(B>5!5T%6055!5%-(@^QHB?M$BSWB +XM8R$`08/_"'5`3(LU`7)!`.L1#Q^``````$G_QDR)->YQ00!!#[X&@_@)=.T\ +XM('3I@_A[?R-!OP<```"#^`E_0X7`=7/I\`(``,<%DF,A``@```#IX0(``(/X +XM?'5:08!^`7QU"DG_QDR)-:-Q00!)_\9,B369<4$`0;\#````Z;8"``"#^"!_ +XM"X/X"@^$J`(``.LD@\#?@_@(=QS_),70A%$`2?_&3(DU97%!`$&_!````.F" +XM`@``3(GWOOF&40"Z!0```.A0U___A<`/A/D```!!O;"%40!FD$V%[0^$N`$` +XM`$F+=0!-BV4(3(GW3(GBZ"37__])@\48A9,B35, +XM<$$`Z=````!)C48%2(D%/'!!`$&\!````.L?3(DU+7!!`$V+9?A%,?]-A>0/ +XMA1L!``#IH0```$G_Q$.*1"8!A,`/A(H````\*'7L30'F2(U-N$R-1;1,B?VU!`$PI]DR)_TR)\NBEZ___2(L%9FU!`(`X(G4*2/_`2(D%5VU!`$B+A7C_ +XM___&``!(B[UP____,?:)VNAU`0$`28G&2(N]=':^_*A1`(7`NMJ&40!(#T76N1X````IP8/Y`4&X"8]1`$P/ +XM1,:_`0```+["AE$`,,#HF2\``(,]^ETA`!U_.+MHOH$`0;X=````#Q]$``!( +XMBTOX2(L3OR"Z@0"^Y(91`##`Z&C1__](@\/H0?_.1#LUPETA`'W8QP6V72$` +XM'@```%M!7EW#9@\?A```````54B)Y5-02(G[2/_+#Q]```^^5(B?A(BSA(BW`(,=+H*\D``$B)P4B%R70+N`$```#V01@'=0(Q +XMP%W##Q]``%5(B>5!5T%6055!5%-(@^QH08G5B76,28G_2(L%AVI!`.L49F9F +XM9BX/'X0``````$B)!7%J00!(_\`/MDC_2('Y_P````^$@P```$B+%99F00#V +XM1!$!"'77#[[)NXZ-40!!O)R'40"#^3YW;4BZ``````(``'!(#Z/*:P`N@LS/__00^^!"1!O0D```"#^#M_'H/X(0^%UP(``$&`?"0!/75>\@\0 +XM1;#R#\)%J`3K0X/X/'4B\@\01:CR#Q!-L$&`?"0!/0^%;0(``&8/+L$/D\#I +XMEP(``(/X/0^%7@(``$&`?"0!/749\@\01;#R#\)%J`!F00]^Q4&#Y0'I<0(` +XM`+\"````ONB'40#K8(7)=`A,B??HM='__T&*!"0\(70$/#UU/D&`?"0!/74V +XM3(EE@$B-?<`Q]N@"Y___B@N(C7____^`^2(/E,!$#[;P20'>@/DB="E,B7V0 +XM3(U]P.F[````OP(```"^:H=1`##`Z%HK``!!O0D```#I\P$``$R)?9!,C7W` +XM3(UEN.L1D$&*#DB-4`%(B57(B`A)_\9!B@8\6W\QA,`/A.P````\(@^$Y``` +XM`#PD=2Y,B?],B?8QTD2)Z4V)X.A"]P``A3(G_3(GV,=)$B>E,C46X +XMZ*'V``"%P'0&3`-UN.NG2(M%R$B+3=!(*<%(@_D!?X9,B?_HKN3__TB+1=,B?[H(,[__T&)Q$R)_^CES___187D#Y7` +XM1##H1`^VZ$@['6EF00!T!DR+?9#K;8"]?____R(/E<%!B@8\*4R+?9!U#H#Y +XM`74)3(DU0&9!`.M*A,!T,DG_QDR)-3!F00#K.F8/+L'K+8/X/G4O\@\01:CR +XM#Q!-L$&`?"0!/7429@\NR`^3P.L03(DU`69!`.L+9@\NR`^7P$0/MNB#?8P` +XM=`A,B?_H3L___T2)Z$B#Q&A;05Q!74%>05]=PV9F9BX/'X0``````%5(B>5! +XM5E-(@^P028GV@#\P=1N`?P%X=15(@\<",B`.``/E,`/ML#K>@\?1```2,'A!$ACPT@!P4C_QP^V +XM-S'`2('^_P```'1:0(3V=$9`#[[>]D06`01U-C'`0(#^_W1"#[;S,<#V1!8! +XM1'0VN&$```"`^_]T$0^VP_9$$`$!N&$```!!#T7`@\,**5!5E.)^^AR\O__B<&X"0```(/Y!W10@_D%=2J) +XMW^@*\O__08G&N`D```!!@_X)=#:)W^A%\O__@_@&N`D```!!#T3&ZR&#^02) +XMR'4:B=_HJ?___XG!,<"#^0%T"H7)N`$````/1<%;05Y=PY!(C4=(PV9F+@\? +XMA```````54B)Y;^@OH$`O@0```"Z8+!A`.C(RO__O^"^@0"^!````+J(L&$` +XMZ+3*__^_0*E1`+Y!J5$`Z"4```!(B05N@D$`2(7`=`)=PS#`O_F'40!=Z3HE +XM``!F+@\?A```````54B)Y4%7059!54%44TB#["A)B?Y(B77(2(U5R+^@OH$` +XM3(GVZ/?*__^)1;R_H+Z!`(G&Z$C(__](B<-(A=L/A3`!``!(C57(OV"P80!, +XMB?;HZ\;__TF)QD''!@````!)C5Y(]@4B@D$`!'09O^>(40!(B=XPP.B5QO__ +XMOXBY@0#HR\?__TB)W^B#RO__28G$387D#X3Y````28U>"$R)=?HAO[BP80!,B?9,B>KH&<;__TB)WT2)_DB) +XMPNB[Q___3(GGZ`/'__])B<9-A?9UBTR)Y^B#R___]@4X@4$`!'0*O_6(40#H +XMD,;__[^@OH$`BW6\2(M=P$B)VNA\Q____P-F+@\?A```````2(G82(/$*%M! +XM7$%=05Y!7UW#3(GWZ);+__\QV^OB9I!52(GE05=!5D%505132(/L*$B)3Y,B?I(B<%!N"\```#H])(``$B+?`%(A,,#H%<3__TB)G2#___]%A>0/A(@```!(@[WP_O__`'0@2(N%&/___TB+ +XMC2#___](*T$`!'0*OPF)40#H^<#__TR)][XO +XM````Z-S!__],B?=(B<;H\?C__TB)QDB%]@^$$`(``(,^`0^%^P$``$B+O?C^ +XM___H\!D!`.GV`0``28/$2$R)YS'VZ%W%__](BTVX3(GG2(G&2(N5&/___T&X +XM+P```.CQC0``28G&]@4C>T$`!`^$$0$``+]8B%$`3(GV,,#HDK___^G]```` +XM13'V]@7_>D$`!`^$[0```+\!B5$`Z%/`___ITP```/8%XWI!``1T#+^IB%$` +XM,,#H6;___T6%_W0?13'V]@7&>D$`!`^$M````+]0B5$`Z!K`___IF@```$B+ +XM=;A,B>!(B<=(BZ/_"__^_X+Z!`(G&Z%/`__](A +XM05]=PTB+A6#___](A<`/E,%$B[U8____08'_````@`^4PB#*#[;:2`'#]@7* +XM>4$`!'0=1(G_2(G>Z&'@``"_EHA1`$B)QDR)\C#`Z"^^__](QT70`````$B- +XM5="_X+Z!`$R)]N@FPO__08G$O^"^@0!$B>;H=K___TB%P`^$HP```$2).$B) +XM6`CI8?___TB+O?C^___H-1;W__T2).$B) +XM6`B_X+Z!`$2)YDB)PN@2O___Z9W^__]F9F9F+@\?A```````54B)Y5-02(G[ +XM2(GW2(G6Z/SU__](B<9(A?9T$X,^`7452(G?2(/$"%M=Z0$7`0!(@\0(6UW# +XM2(G?2(/$"%M=Z2P6`0!F9F8N#Q^$``````#_!TB)^,-F+@\?A```````54B) +XMY4%7059!5%-(@^P@2(GS28G_2(U]R#'VZ##8__],BR--A>1T;TR-=<@/'T`` +XM3(G_Z-C!__],B?=(B<9,B?KH:M?__TF+7"002(/#2$B)W^BYP?__3(GW2(G& +XM2(G:Z$O7__](BT702(M-V$@IP4B#^0%_#$R)]^C2UO__2(M%T$B-2`%(B4W0 +XMQ@`@38MD)`A-A>1UF4B+1=#&``!(BT7(2(/$(%M!7$%>05]=PY!52(GE4U!( +XMB?O_"W0'2(/$"%M=PTB-O!__]F9BX/'X0``````%5(B>5!5T%64U!)B?Y(BQ[K +XM$F9F9F9F+@\?A```````2(M;"$B%VW083(M[$$R)]TR)_NC8%`$`AL```"I```@`'073(GWZ$3,__\/'T``08G$2(G3Z\#__TB+%<1)(0!(B=](B<:Y`0```.A4]O__28G'387_ +XM=0M(B=_H]&8``$F)Q[_@OH$`3(G^Z$2\__^)A43___^_X+Z!`(G&Z!*\__]) +XMB<5-A>UT>O8%#W9!``1T'TF+=0A!BWT`Z*3<``"_QHA1`$B)QDR)^C#`Z'*Z +XM__]-BV4`28M="$R)[^B"P/__O^"^@0"+M43____H/___[@```"`3#'@=89(A=MU@3';2(/+`>EV____0;P```"` +XM,=OI:?___Y"0D)"0D)"0D%5(B>5!5T%6055!5%-(@^Q82(E-F$B)59!(B?-) +XMB?[V!09U00`$="5,B?=(B=[H'8\``$F)Q[]UH%$`3(G^,,#H:[G__TR)_^B# +XMO___2(G:3"GR3(GWOGL```#HH+O__TB%P'1;2+@!`"`````"`$R)\>L/9F9F +XM+@\?A```````2/_!0;1U!T6$_W61ZY](B=I)C70D +XM`DV-?"0!,<#K'F9F9F9F+@\?A```````2/_&9F9F9BX/'X0``````(I._X3) +XM#X3,`0``@/E]=0B%P'00_\CKV(#Y>W73_\!(_\;KW$V)YDB)TTB)7:!)*=Y( +XMB?=(B76XZ$.]__])C4P&`4B)3:A(_\!(B46P23G<#X6Z````9BX/'X0````` +XM`$V)_#'`,=OK%P\?@`````#_R$C_PV9F+@\?A```````08H,'(7`=1.`^2QT +XM)(#Y>W03,<"`^7UT&.L1@/E]=-"`^7MU!__`2/_#Z]1(_\/KSTB+1:A(C3P# +XMZ#)C``!)B<=(A=MT#TN-/#=,B>9(B=KH&[C__TJ-/#-,`?](BW6X2(M5L.@' +XMN/__2(U]P$R)_NA+$0$`38U\'`%!@#PWK%F8/'T0``$G_Q69F9F8N#Q^$``````!#B@PLA],B?Y,B?'HKN___TB+6PA(A=MUY4B-?<`Q]NA:$`$`Z9````!(BQOK +XM%DB+4Q!,B>=,B?Y,B?'H?N___TB+6PA(A=MUY>MN2(L5''!!`$R)YTR)_DR) +XM\>A>[___2(L;ZQ]F#Q^$``````!(BU,03(GG3(G^3(GQZ#[O__](BUL(2(7; +XM=##KXTB+&^LD9F9F9F8N#Q^$``````!(BU,03(GG3(G^3(GQZ`[O__](BUL( +XM2(7;=>5(@\086T%<05U!7D%?7<-F#Q]$``!(B?DPP+_CB%$`2(G.Z4ZT__]F +XM9F9F9BX/'X0``````#')13'`,=+K%P\?@`````!(_\=F9F9F+@\?A``````` +XM2#G^=&(/O@>#^#Y_!X/X*G1-Z]R#^%I_!X/X/W1!Z]"#^'I_"H/X6W492/_" +XMZS"#^'UU(S'`2(7)=$5(_\E(_\?KO8/X776H,<$B%VW1!38U\)'!F +XM9F8N#Q^$``````!,BVL03(G_3(GNZ,$+`0"%P'0428/%8$R)[TR)YNAN#`$` +XM0?]$)"!(BUL(2(7;=="XZ/_[_T$C1AA!"40D&$'V1A@0=`5!_TPD($F#O"3@ +XM`````'4>28N&V````$F+CN````!)B8PDX````$F)A"38````2(/$"%M!7$%= +XM05Y!7UW#O[J*40"^WP```+K9BE$`N>B*40#HU;3__P\?1```54B)Y4%64TF) +XM]DB)^_9#&`AT$TB!PR@!``"_B+F!`+Y@BE$`ZQI(@<,H`0``@ST@;4$``'0G +XMOXBY@0"^<(I1`+K@B5$`2(G9,,#HL;/__[^(N8$`6T%>7>G#LO__O^6#40`Q +XM]NAGVP``2(G!,,"_@XI1`+[@B5$`2(G:38GP6T%>74'_X&9F+@\?A``````` +XM54B)Y4%64TB#[!!(B?N+0QAFJ3A$#X4)`0``]L0!=2)(C9,H`0``OXBY@0"^ +XMEHI1`##`Z#BS__^_B+F!`.A.LO__@SV';$$```^%U0```(M#&*D``"``=`U( +XMB=_H?[[__^F^````J0``$`!T#4B)W^C[P?__Z:H```!(BT,02('#*`$``$B% +XMP$@/1=A(B=_HS-(``(/X_P^%AP```$B)W[X"`@``NK8!```PP.C_M?__08G& +XM187V>#Y(C77O1(GWN@$```#H)K/__TB#^`%U'42)]S'V,=+HQ+'__TB-=>]$ +XMB?>Z`0```.ASLO__1(GWZ$NV___K+>BTL/__BSCHC;#__[^(N8$`OJ"*40!( +XMB=I(B<$PP.A6LO__OXBY@0#H;+'__TB#Q!!;05Y=PP\?`$B-3BA,C45!5T%6 +XM055!5%-(@^Q(2(E]H$B+=W!(A?8/A!L"```Q_TR-=:B)^&8/'T0``$B+3A"+ +XM41AF]\(P$`^%N`$``/;"!W0,3(NIH````$V%[7423(VI*`$``$B+41!(A=), +XM#T7J2(EUF$B+5:#V0AD$=3N+42A(BW6@BW8H.=9U#$B+=:!(BW8P2#MQ,'P] +XMBS4;:T$`.?)U(TB+43!(.Q44:T$`?1Q!B`&%P'4-2(M%H$R)J,````#K?T&)_$&#_P)U +XM*TR)]S'VZ(S*__](BT6@2(N8P````$B)W^@YM/__3(GW2(G&2(G:Z,O)__]( +XMBT6P2(M-N$@IP4B#^0%_#$R)]^A2R?__2(M%L$B-2`%(B4VPQ@`@3(GOZ/NS +XM__],B?=(B<9,B>KHCL___2(G?2(G&3(GJZ/#(__]$B?A$B>=( +XMBW682(MV"$B%]@^%*?[__X/_`GP62(M-R,8!`$B+3]@5O:$$`0`^$"0$``+\I +XMBU$`,,#HX:S__^GX````]\$``!``=%1(B=_H[,3__X7`=$7V!3UH00!`=`R_ +XM-HM1`##`Z+.L__](B=_H.\3__[$!A?%J!^@```(!U*TB#>T`` +XM=20]````@'41N@```(!(@WLP`+X```"`=#6Z````@/;!!(G&=2E(BWM@OG!V +XM0`!(B=KH8P@!`#'`D$B#Q`A;7)QK@!````]@4K9T$` +XM0'3=.=9U"$B+0S!(.T-`?0>_>HM1`.LB@?X```"`=0=(@WLP`'0.O[.+40#K +XM#+]LBU$`ZP6_E(M1`##`Z&^K__^X`0```.N8#Q^$``````!(C4XH3(U'.(M6 +XM*(M'.#G0=0A(BT=`2#M&,'T.2(L12(M!"$F)0`A)B1###Q]$``!52(GE0593 +XM28GV2(G[OP(```"^`0```.BDK?__2(/X`70-OP(```!(B=[HD:W__[\!```` +XMO@$```#H@JW__TB#^`%T#;\!````2(G>Z&^M__^_`P```+X!````Z&"M__]( +XM@_@!=`V_`P```$B)WNA-K?__OP\```"^`0```.@^K?__2(/X`70-OP\```!( +XMB=[H*ZW__[\2````O@$```#H'*W__TB#^`%T#;\2````3(GVZ`FM__^_%@`` +XM`+X!````Z/JL__](@_@!=`V_%@```$R)]NCGK/__OQ4```"^`0```.C8K/__ +XM2(/X`70-OQ4```!,B?;HQ:S__[\<````O@$```#HMJS__TB#^`%T#;\<```` +XM3(GVZ*.L__^_$P```+X!````Z)2L__](@_@!=`V_$P```$R)]NB!K/__QP4_ +XM94$``````%M!7EW#9I"#_PY_#8/_`745_P4<94$`ZR6#_P]U*O\%%V5!`.L8 +XM@_\"=0C_!09E00#K"X/_`W40_P7Q9$$`QP7W9$$``0```,-F9F9F9BX/'X0` +XM`````%5(B>5!5T%64U!)B?])BY_H````2(7;=#E-C;?X````28''H````&8/ +XM'X0``````$B+>Q!,B?XQTNA"V@``3(GW2(G&Z%<#`0!(BUL(2(7;==Y(@\0( +XM6T%>05]=PP\?`%5(B>5!5T%6051328G^N`@```!-A?8/A*,```"X"````$'V +XM1AH"#X63````28N>Z````$V-IO@```!(A=MT,TV-OJ````!F+@\?A``````` +XM2(M[$$R)_C'2Z,+9``!,B>=(B<;HUP(!`$B+6PA(A=MUWD'&1@<"ZP\/'X`` +XM````2(G?Z,BN__],B>?HH`,!`$B)PTB%VW012(G?3(GV,=+H6P$``(7`===( +XMB=_HGZ[__X,]T&-!``!U#D$/OD8'6T%<05Y!7UW#3(GWZ&"F``"%P'4L@SW5 +XM8T$``'4C28N>H````$B)W^AD5@``@_C_=`^_F8Q1`$B)WC#`Z(`%``"#/7EC +XM00``=%R_`@```+X!````Z*BJ__^_#P```+X!````Z)FJ__^_`0```+X!```` +XMZ(JJ__^_`P```+X!````Z'NJ___'!3EC00``````QP4G8T$``````$B+/7!C +XM00#HF_[__[__````Z,&L__^054B)Y4%64TF)_D'&1@<"28V>^````&8N#Q^$ +XM``````!(B=_HF`(!`$B%P'092(,[``^4P0^VT4B)QTR)]NA.````A0BE,!2/_#@/K_ +XM=`H/MLKV1#$!"'7KAZ;__XLXZ%2F__^_/8Q1 +XM`$B)QC#`Z"4$```/'T0``$2)YTR)[C'2Z..E__^)PT0YXW0/@_O_=>?H0J;_ +XM_X,X!'3=,<"#/2QA00``#X6/````@_O_=*F+7=1!B=Q!@^1_="J_+XQ1`$2) +XMYC#`Z*ZE__]$B>/K,;_SBU$`2(G>,,#HZ@(``+@!````ZU3!ZP@QP('C_P`` +XM`'0_OQV,40")WC#`Z'BE__]%A?]T'$'&1@<$@SW;8$$``'0G6_O__OPZ,40`PP.@Z`P``2(G?1(G^Z.\```!F9F9F9F8N#Q^$```` +XM``!52(GEB@5&0D$`A,`/A;T```#&!6I"00`!Q@5]0D$``<8%M4)!``'&!9!" +XM00`!Q@530D$``<8%34)!``'&!9A"00`!Q@630D$``87_Q@5(0D$``<8%+$)! +XM``'&!3M"00`!Q@4V0D$``<8%&T)!``'&!2E"00`!Q@4^0D$``<8%.4)!``'& +XM!0]"00`!Q@7R04$``<8%)T)!``'&!1Q"00`!Q@7#04$``<8%LD%!``%T#+\P +XMB4``OC")0`#K![_P=T``,?;H"/G__\8%@4%!``%=PV9F9F9F9BX/'X0````` +XM`%5(B>5!5T%64TB![)@```"X3XQ1`(7VN<*"40!(#T7(2,>%8/___^."40!( +XMB8UH____2(F]Z)JH___H1:/_ +XM_TB+$X,X`G4;OR"Z@0"^4XQ1`##`Z.RD__^_`0```.CRI___2(G7Z(JC__^_ +XM`0```.C@I___54B)Y4B![-````!)B?J$P'0F#RF%8/___P\IC7#___\/*56` +XM#RE=D`\I9:`/*6VP#REUP`\I?=!,B8U8____3(F%4/___TB)C4C___](B95` +XM____2(FU./___TB+!0XY00!(B47X2(V%,/___TB)1?!(C4402(E%Z,=%Y#`` +XM``#'1>`(````2(U5X+\@NH$`3(G6Z!BH__^_"@```+X@NH$`Z+FF__](BP7" +XM.$$`2#M%^'4)2('$T````%W#Z&ZC__]F9F9F9BX/'X0``````%5(B>532('L +XMR````$B)^X3`="8/*85@____#RF-C'1>0P +XM````QT7@"````+_"C%$`O@8```"Z`0```+D@NH$`Z&JE__](C57@OR"Z@0!( +XMB=[H::;__[\*````OB"Z@0#H"J7__^BU$@``]@7*6T$`$'0*OP(```#H8J`` +XM`+\"````Z#BE__\/'X0``````%5(B>534(G[Z%,2``"%VW0;O^6#40`Q]N@# +XMR@``O\F,40!(B<8PP.A4_?__Z,\&``#V!71;00`0=`J_`@```.@,H```OP(` +XM``#HXJ3__V:054B)Y4%64TB![.````!)B?:)^X3`="P/*85`____#RF-4/__ +XM_P\IE6#___\/*9UP____#REE@`\I;9`/*76@#RE]L$R)C3C___],B84P____ +XM2(F-*/___TB)E2#___](BP4Z-D$`2(E%Z$B-A1#___](B47@2(U%$$B)1=C' +XM1=0P````QT70$````$B-?<#H7"\``$B+5-4$`2#M% +XMZ'4,2('$X````%M!7EW#Z$>@__^0D)"0D)"054B)Y4%7059!54%44U!(BP6C +XM-T$`9F8N#Q^$``````!)B?Q!#[8,)$B!^?\```!T#$F-?"0!]D0!`0AUX[]P +XM````Z#E*``!)B<9!QT8@`````$G'1A``````2<=&"`````!%,1(@_D"#X5Z +XM____@#]I#X5Q____@'\!;@^%9____T6%P`^$7@$``$4Q[4R)YS'V,=+HC\X` +XM`$F)Q/8%$EE!``1T7;\ZR8U1`.C/<@``2(G? +XM2(G&Z+3Z``!)_\5,B?_H"6X``$B%P'743(GGZ.RB__])8TX@2(/Y`7143(GH +XM,=)(]_%(A=)T1[\!````OC2-40#K&;\!````OO",40!F9F9F9F8N#Q^$```` +XM```PP.BI_/__13'V9@\?1```3(GP2(/$"%M!7$%=05Y!7UW#Z#DL``!)B498 +XM2<=&8`$```!)C7Y`,?;HXK?__^O0OP$```"^!(U1`.NT#Q]``%5(B>5!5T%6 +XM055!5%-028GV28G_38MG8$V%Y`^$/0$``$&`/BX/A=T```!)C48!3(LM`C5! +XM`&8N#Q^$``````!(B<,/M@M(@?G_````=`Q(C4,!0O9$*0$(=>5(B=^^D(U1 +XM`+H&````Z).>__^%P'5)#[9#!D@]_P```'0]0O9$*`$(=02$P'4Q]@4M5T$` +XM!'08OR"Z@0"^EXU1`$R)XC#`Z+J=__]-BV=@,534$B)^TB+0TC&``!(BT-`2(D#2(M+2$B# +XMP2!(*<%(B4LX2,=#&`````!(BWLHOI"'0`!(B=KH$?<``$B+>T#HF*#__TB- +XM>PB^X%9!`.BZ]0``2(U[*+[P)T``Z*SU``!(B=](@\0(6UWI;J#__V9F9F9F +XM+@\?A```````54B)Y4%705932(/L&$B)\TF)_DB#>Q@`=1U(BT,02(E#&$B+ +XM0TC&``!(BT-`2(D#QT-H`````/8%?U5!``1T)$B+0QA(BW@0Z//.``"_(+J! +XM`+Z\C5$`2(G"3(GQ,,#H_)O__TB+@6SP``@WMH`'0(2(L[Z,B?__](BT78Q@``2(M]T$B).\=#:`$` +XM``!(BT,82(L`2(E#&$B%P'4)2(MS6.B*&```2(/$&%M!7D%?7<.0D)"0D)"0 +XMD)"0D)"0D)!52(GE,?^^D-V!`.@@F?__Z#N2``#HUM'__^@17```Z'S1``#H +XM-['__UWI\8D``)!52(GE4U!(BQV+-T$`ZR&03(N(V````+]NCE$`,,#H7?;_ +XM_TB+6PAF#Q^$``````!(A=MT3$B+0Q"+"+Y`CE$`AZ+.;__]-BW\(387_=>KHQ9C__T2),(/[#G\:@_L! +XM=3;_!9Y300#'!:!300`!````Z9X```"-0_&#^`UW=_\DQ="-40#_!8)300#' +XM!7Q300`!````ZWV#^P)U$O\%9U-!`,<%95-!``$```#K9H/[`W5"_P5(4T$` +XMQP5.4T$``0```.M/_P5.4T$`ZQ[_!5)300#K%O\%.E-!`.L._P4^4T$`ZP;_ +XM!3)300#'!1Q300`!````Z$^8__^)QXG>Z/::__^)WS'VZ#V:___H")C__T2) +XM,$B#Q`A;05Y!7UW#9BX/'X0``````%5(B>7H!P```%WI80$``)!52(GE05=! +XM5D%505132(/L&$B#/105]=PP\?1```54B)Y4%64TB#[!"#/9HT +XM00``#X1\````2(UUZ+______N@$```#HY97__XE%[(7`?F),C77L2(U=Z&8/ +XM'T0``.B["```2(L]A#1!`+[`ED``3(GRZ`?R``!(AR_18]1`##` +XMZ`+S___K"XMUZ$B)Q^BE"@``O_____](B=ZZ`0```.B#E?__B47LA0BEH!2/_"A-MTUH#["70%@/L@=1"`>@$M=0Z`>@))#Y3` +XM#[;PA?9UV#'V@/MM==$Q]H!Z`6%UR8!Z`FMU-X!Z`V5U.$B#P@)F#Q^$```` +XM``"*6@)(_\*`^RU_$`^V\X#[('?M2`^C\7/GZQLQ]H#[+G7>ZXPQ]DC_PNN% +XM,?9(@\("Z7K___]!@\X"9D6)=Q!-A?\/A,`$``!,.25Q,D$`="_V!45/00`0 +XM=!])@<0H`0``OXBY@0"^(H]1`$R)XC#`Z,N5__]-BV<(3(DE0#)!`$B-73__^+..B0D___O[:.40!(B<8PP.@Q\O__ +XMOP$```"^9,"!`+JHP($`Z%V9___H2);__T&)QD6%]@^%^````,<%=C%!```` +XM``"+?<#H^IC__XM]Q+X!````Z.V3__^#^/]U&^A3D___BSCH+)/__[_9CE$` +XM2(G&,,#HS?'__XM]Q(/_`70%Z,"8__^+??HGS,``.FR`@``QP4D,$$``0```$6)-TG'AR@$````````BWW`O@(` +XM``"Z`0```##`Z'Z7__](BWW`08E_($C![R#H?9?__T&+?R"+'9,@(0!(BP4\ +XM,$$`2(7`=`0YWWYW@\,@P>L%C4\@P>D%.=ET74&)S$B)QTR)YKH$````Z'`^ +XM``!(B04),$$`B=E(C3R(1(G@*(",?;HX)3__TB+/?$O00!,B>:Z +XM!````.@\/@``2<'D`DB)!=DO00!,B27:+T$`08M_((D]$"`A`$&+?R"^!``` +XM`+H$````,,#HRY;__T&+1R"Z`0```(C!T^+!Z`5(BPV4+T$`"12!2<>'.`@` +XM``````"+?`IR$ACT$C!X@(Q +XM]NCND___2(L]_RY!`$R)YKH$````Z$H]``!)P>0"2(D%YRY!`$R))>@N00!! +XMB[\P!```B3T;'R$`08N_,`0``+X$````N@0````PP.C3E?__08N',`0``(C! +XMN@$```#3XL'H!4B+#9DN00`)%('_!5PN00"_@,"!`$R)_NC3Z0``0?9'$`)T +XM!\8%72Y!``&_!````.AK.P``1(DPOTC`@0!(B<;HJ^D``$B+!10N00!)B4<8 +XMOP,```"^J,"!`#'2Z*^5___V!?1*00`@=%Y)BT\(26/62('!*`$``+^(N8$` +XMO@N/40`PP.AWD?__28M'"$B+F.@```#K(V8N#Q^$``````!(BU,0OXBY@0"^ +XM'8]1`##`Z$N1__](BUL(2(7;=>*_B+F!`.A8D/__2(L%T25!`$@[1=AU#4B# +XMQ"!;05Q!7D%?79#__V8/'X0``````%5(B>6)/6XM00#'!6@M00`````` +XMQP5B+4$``````,<%7"U!``=`,@#'!58M00``````2,<%4RU!``````!(BSUD +XM2D$`]D<:`G4IO@0```#H+/G__^L49BX/'X0``````.@+]___Z&;X__^#/0LM +XM00``=>U=PV9F+@\?A```````L`&#/?\L00``=0^+!>LL00`[!>$L00`/G<"* +XM#?@L00`(P0^VP8/@`8/P`<,/'T``@SW%+$$```^4P`^VP,-FD%5(B>5(BSW5 +XM24$`]D<:`G5"@SVH+$$``'0.OY:.40`PP.A:Z___ZRN^!````.B.^/__ZQ9F +XM9F8N#Q^$``````#H:_;__^C&]___@SUK+$$``'7MBP5G+$$`7<,/'T0``%5( +XMB>7'!5HL00`#````ZPKH._;__^B6]___@ST[+$$``'7MQP4[+$$``````%W# +XMD%5(B>5!5E-(@^P0QP4C+$$``0```(,]$"Q!``!T0DB+'2LL00#K*V8/'X0` +XM`````$R+R______[H!````Z!V-__^%P'_I2(/$$%M!7EW#54B)Y>LJ +XM9BX/'X0``````,<%/__\/'X``````@SU! +XM2$$```^$S@$``,<%,4A!``````"#/2)(00``=$+'!19(00``````]@4[2$$` +XM('0@OXBY@0"^`I!1`+H"````,,#HQX[__[^(N8$`Z-V-__^_`0```+X"```` +XMZ)X*``"#/=-'00``=#_'!<='00``````]@7P1T$`('0@OXBY@0"^`I!1`+H! +XM````,,#H?([__[^(N8$`Z)*-__\Q_[X!````Z%8*``"#/8='00``=$;'!7M' +XM00``````]@6H1T$`('0@OXBY@0"^`I!1`+H#````,,#H-([__[^(N8$`Z$J- +XM__\Q_[X#````Z`X*```Q_^C'Z___@SU$1T$``'0_QP4X1T$``````/8%64=! +XM`"!T(+^(N8$`O@*040"Z#P```##`Z.6-__^_B+F!`.C[C/__,?^^#P```.B_ +XM"0``@ST(1T$``'09QP7\1D$``````+\2````OC")0`#H'8[__X,][D9!``!T +XM&<<%XD9!``````"_%@```+XPB4``Z/N-__^#/5!5T%6055!5%-0B?-(B?A,BW@0OX#`@0!(B<;H'.D``,=%U`$```"_`0`` +XM`+YDP($`NJC`@0#H\9#__TF+1QA(BW@0Z-20__])BW<8OTC`@0#HYN@``+\# +XM````OJC`@0`QTNC%D/___PT;*4$`0?9'$`)T!\8%*2E!``"Z*`$``$D#5PA) +XM8S=%,.2_7X]1`(G9,,#H9`,``$&)WD&#YG]!@_Y_=`Q%A?8/ANP$```"(P;H!````T^+WTL'H +XM!4B+#=4H00`A%(%,B?^^`0```+H!````Z-`#``!!B[\P!```Z.2/___'1=0` +XM````08M'((C!T^/WT\'H!4B+#9DH00`A'(%,B?\Q]KH!````Z)<#``!!BW\@ +XMZ*Z/__]%,.U%A?8/A?P```!!M0$QV_8%(D5!`"!!O@````#'1=0`````#X2[ +XM`0``Z=@```!!M`''1=0`````08G>08N',`0``+L!````B,&Z`0```-/B]]+! +XMZ`5(BPT@*$$`(12!3(G_O@$```"Z`0```.@;`P``08N_,`0``.@OC___08M' +XM((C!T^/WT\'H!4B+#>LG00`A'(%,B?\Q]KH!````Z.D"``!!BW\@Z`"/__]% +XM,.U%A.1U4DF+5PA(.Q6=)T$`="SV!7%$00`0=!Q(@<(H`0``OXBY@0"^(H]1 +XM`##`Z/J*__])BU<(2(D5;R=!`+^(N8$`OMV/40!$B?(PP.C;BO__Z=$```"Z +XM*`$``$D#5PA)8S>_B(]1`##`Z)X!``!%A.UT+_8%#D1!`"`/A*<```"Y*`$` +XM`$D#3PA)8Q>_B+F!`+ZXCU$`,,#HCXK__^F%````28M7"$@[%?\F00!T,/8% +XMTT-!`!!T'$B!PB@!``"_B+F!`+XBCU$`,,#H7(K__TF+5PA(B171)D$`28M7 +XM"(M"&(/@0,'H!KJXC%$`A<"Y_*A1`$@/1$` +XM`$R)_^B1C?__BP4#)D$`BSWU)4$`@SW20D$``'4>A?]T&H/X`G05QP7A)4$` +XM`0```(,]SB5!``!U).L/@_@!=1V+!;\E00"%P'432(/$"%M!7$%=05Y!7UWI +XM[.;__TB#Q`A;05Q!74%>05]=PV9F9F8N#Q^$``````!52(GE2('LT````$F) +XM^H3`="8/*85@____#RF-(TB)19!(B5W`38UT'B1( +XMB#Y!`!!T'DB!PB@!``!,B>^^(H]1`##` +XMZ`.%__](BT7`2(M0"$B)%70A00!(BT7`@$@0`4B%VW19#Q^``````$&*!@^^ +XM^(,]FQM!``!U(T&+50R-2O]!B4T,A=)_'D$[32A\!#P*=11,B>[H4(;__^L8 +XM3(GNZ,:&___K#DF+30!(C5$!28E5`(@!2?_&2/_+=:Y)BP0D2(7`=%Y(BTVH +XM@'P((PIT4X,].QM!``!T$;\*````OHBY@0#H@H;__^LYBP7^&4$`C4C_B0WU +XM&4$`A__])8W4`2(7V=*"_+)!1`##`Z%3Z__]! +XMBWT`B=[HB83__^N'187V=$6+!<`\00"%P'4[2(L]T3Q!`/9'&@)U+L<%F3Q! +XM```````Q]NBJZ___ZQ(/'X0``````.B+Z?__Z.;J__^#/8L?00``=>V)W^CV +XMA?__D)"0D)"054B)Y4%7059!5%-)B?9)B?](BS6X'T$`3(LF]@5+/$$`!'0; +XMOR"Z@0"^5Y!1`$R)^C#`Z-B"__](BS61'T$`O[C`@0#H=]X``$B#/7\?00`` +XM=$._,````.A3+```2(G#3(DC3(ES"$C'0Q``````3(E[&$R)>R!,B?_HP87_ +XM_TP!^$B)0RA(B1U#'T$`6T%<05Y!7UW#OV"040"^K0```+J!D%$`N9*040#H +XM,8/__Y!52(GE059328GV2(G[2(LU#!]!`$B%]G0*O[C`@0#H[=T``+\P```` +XMZ-,K``!(B1A(QT`8`````$C'0`@`````3(EP$$C'0"@`````2,=`(`````!( +XMB07%'D$`6T%>7<-52(GE4U!(BQVS'D$`2(7;=#M(BWL02(7_="&#/:8800`` +XM=`?HUX3__^L$#[]'$H7`=`E(BWL0Z'2#__](BWL8Z+N%__](B=_HLX7__[^X +XMP($`Z(G:``!(B05B'D$`2(7`#Y7`#[;`2(/$"%M=PV:054B)Y4%7059!5%-( +XM@^P@28G^2(L%-QY!`$R-?=!(C5W83(UER.L49@\?A```````2(L%&1Y!`$C_ +XM0`A(BT@@2#M(*'),2(MX$+C_____2(7_#X09`0``3(GFZ-&#__](BPWJ'4$` +XM2(E!($B+!=\=00!(BT@@2(7)#X0[`0``2`--R$B)2"A(BP7#'4$`2(M(($B- +XM40%(B5`@#[X!@_@N#X7+````Z1X!``!F#Q]$``!(C5$!2(E0(`^^`>FP```` +XM@_A<=75(BPV$'4$`2(M!($@[02AR1TB+>1!(A?\/A/P```!,B?[H18/__TB+ +XM#5X=00!(B4$@2(L%4QU!`$B+2"!(A +XM05]=PY!52(GE05=!5D%44TB#["!)B?=)B?Y)BP9)B48(2(L-+1Q!`$B+02!( +XM.T$H&D$`2(E!($B+!=,:00!(BT@@2(7)#X06____2`--T$B) +XM2"A(BPVW&D$`2(M!($B-4`%(B5$@#[X8@_L)=).#^R`/A?K^___KB$C'0"@` +XM````OP$```"^MY!1`$R)^C#`Z+S;__\QP.GI````2,=`*`````"[_____TF+ +XM1@A)BTX02"G!2(/Y`7\,3(GWZ/^5__])BT8(2(U(`4F)3@C&`%R#^UP/A9<` +XM``!)BT8(28M.$$@IP4B#^0%_#$R)]^C.E?__28M&"$B-2`%)B4X(Q@!<2(L% +XM"!I!`$B+2"!(.T@H`900!( +XMB4$@2(L%U1E!`$B+2"!(AT800!(BT@@2#M(*'))2(MX$$&______TB%_P^$$@$` +XM`$R)[NBH?O__2(L-P1A!`$B)02!(BP6V&$$`2(M(($B%R70M2`--N$B)2"A( +XMBP6>&$$`2(M(($B-40%(B5`@1`^^.>G+````9@\?A```````2,=`*`````!! +XMO______IKP```&9F9F8N#Q^$``````!(@_D!?PQ(B=_H`I3__TB+0PA(C4@! +XM2(E+",8`($B+#3P800!(_T$(ZPUF#Q]$``!(BPTI&$$`2(M!($@[02AR24B+ +XM>1!!O_____](A?]T4DR)]NCH??__2(L-`1A!`$B)02!(BP7V%T$`2(M(($B% +XMR0^$:?___T@#3;H;'W__TB+#84700!(B4$@2(L%>A=!`$B+2"!(A!!!O_____](A?\/A(;]__]( +XMC770Z(U\__](BPVF%D$`2(E!($B+!9L600!(BT@@2(7)=1-(QT`H`````$&_ +XM_____^E/_?__2`--T$B)2"A(BP5P%D$`2(M((.DG_?__2(L%8!9!`$C_0`A( +XM@\0H6T%<05U!7D%?7<-F9F9F+@\?A```````54B)Y4%7059!54%44TB#[%A) +XMB?Y,C6V@3(U]R.L-9I!(BP49%D$`2/]`"$F+!DF)1@A(BPT'%D$`2(M!($@[ +XM02AR2DB+>1`QP$B%_P^$K@4``$B-=8CHQ7O__TB+#=X500!(B4$@2(L%TQ5! +XM`$B+2"!(A1"^ +XM_____TB%_P^$70$``$B-=9#H1'O__TB+#5T500!(B4$@2(L%4A5!`$B+2"!( +XMA[H.7K__TB+#5(400!(B4$@2(L%1Q1!`$B+2"!(A1"^____ +XM_TB%_P^$70$``$B-=;CHI'C__TB+#;T200!(B4$@2(L%LA)!`$B+2"!(A1"[_____TB%_P^$"P$``$B-=<#H%'C__TB+#2T200!(B4$@2(L%(A)! +XM`$B+2"!(A@PP.CO;O__2(UUT$B-5Z#D!``!(BWW(Z)!T__](B=_HB'3__P\?A```````2(/$&%M!7$%= +XM05Y!7UW#3(UUU>LK9F8N#Q^$``````#&1=4M1(A]UL9%UP"_,)-1`#'V3(GR +XM,#^$]_&(/X0@^%L@```,<%@"E! +XM``$```!(_\OKTX/X9'\:@_A0=*F#^%,/A9````#'!4HI00``````ZY2#P)N# +XM^`]W?/\DQ4"140"_`0```.@;D```Z7;____'!20I00`!````Z6?____'!1$I +XM00`!````Z5C____'!0XI00`!````Z4G____'!0\I00`!````Z3K____&!9L, +XM00`!Z2[____'!?@H00`!````Z1_____'!=DH00`!````Z1#____HVPX``&9F +XM+@\?A```````54B)Y4%7059!54%44TB#[!A)B?5!B?['!2\$00`!````QP4! +XM!D$``0```$4QY+@!````3(U]U>L7#Q^``````/\%"@1!`(L%!`1!``\?0`!$ +XM.?`/C5P$``!%A>1U8$ACR$F+3,T`@#DM=2J*40&`^BUU%H!Y`@!U'/_`B07/ +XM`T$`0;P!````ZS6$TG4(_\")!;L#00!$B?=,B>ZZ1911`.@K440`PP.@WR___2&,%4`-!`$F+?,4` +XM2(L=3/L@`.A?&```2(G?2(G&Z#3&``#I'____X/[8W\B@_M5?S^#^T]_:(/[ +XM0@^%@````,<%A2=!``$```#IR@```(U#G(/X$`^'7`,``/\DQ<"140!(BQW> +XM`D$`2(G8Z<8!``"#^U8/A3T#``!(BS7&`D$`OQ#!@0#HS,4``$B+';4"00#& +XM1=4MQD765NG1`@``@_M0#X0T`0``@_M3#X4&`P``QP4`)T$``````.D<`0`` +XM@_M$#X4P`0``2(L]=P)!`$4QY#'VNE^440`QR>BVDP``2(L=7P)!`,9%U2W& +XM1=9$QD77`.E^`@``OP$```#HI(T``.G4````2(LU.`)!`+\`P8$`Z#[%``!% +XM,>3I;`(``,<%E"9!``$```#IK````,8%.0I!``%(BST)`D$`2(UUR#'2Z)YL +XM__^)!80F00!(BQWQ`4$`2(M5R$@YV@^$?@(``,9%U2W&1=9JZ0`"``#'!4$F +XM00`!````ZV!(BS7$`4$`2(L]W?D@`#'2Z):M__](BQVO`4$`QD75+<9%UFWI +XMRP$``,<%&"9!``$```#K*\<%'"9!``$```#K'\8%JPE!``'K%L<%"R9!``$` +XM``#K"L<%[R5!``$```#&1=4MB%W6QD77`$4QY+\PDU$`,?9,B?KIK`$``(/[ +XM20^%M0$``$B+/3X!00#H"1D``$B+'3(!00#&1=4MQD762>E.`0``#Q]$``#' +XM!9(E00#_____2/_`#Q\`#[X0A=(/A"8!``"#^DE_"X/Z00^%>P$``.O5@_I@ +XM?Q6#^DH/A6L!``"`#5TE00`02/_`Z\N-2I^#^14/AU,!``#_),U(DE$`@`T] +XM)4$``>G5````@`TQ)4$``DC_P.N@@`TE)4$`!$C_P.N4@`T:)4$`!$C_P.N( +XM2(U(`8I0`8#Z,@^%B@```(`-_21!`!!(B2_,)-1`#'V3(GZ,2_,)-1`#'V2(G:,Y(``(L%I?]``.F@^___Z!L*``!( +XM@\086T%<05U!7D%?7<._(+J!`+YAE%$`,,#HBVK__^CV"0``OR"Z@0"^C)11 +XM`##`Z'5J___HX`D``%5(B>5!5T%6055!5%-(@>Q8`0``2(FUF/[__XF]E/[_ +XM_[\[DU$`Z)5H__])B<=-A?]U&;\@P8$`Z--I__]!OR#%@0"#^/\/A.@&``"_ +XM0Y-1`.AJ:/__NS.440!(AU, +XM#T3K,?\Q]N@J;/__28G&387V#X2V!@``2(VU,/___TR)]^B/;/__@_C_#X3( +XM!@``OQV340#H#&C__TB)PTB%VW1"2(VUH/[__TB)W^AE;/__A9,B?)F9F9F9BX/'X0``````$B)P44QP.@U-0`` +XM28G&3(GWZ*H'``!(B<-,B??H_VS__^L:O^Z340#H0V?__TB%P'0G2(G'Z(8' +XM``!(B<-(B1WZ!84``"_(9-1`.@,9O__QP6V(4$``````,<%D"%!``````#'!8XA +XM00``````QP5X(4$``````,<%:B%!``````#'!8`A00``````Q@41!4$``,<% +XM8R%!``````#'!5$A00``````QP57(4$`!````,<%22%!``````#H7,S__TB+ +XM!ZC__TB+!:P$00"_Y8-1`#'V +XM2(G",AI-1`.CTJ?__2(M]P$B% +XM_W45OWN340"^=)-1`##`Z*K!__](BWW`OB#!0`"ZZ,"!`.BWOP``2(7`=!!( +XMBW`0O\>340`PP.B"P?__2(L]BP)!`$B%_W0FOB#!0`"ZZ,"!`.B'OP``2(7` +XM=$=(BW`0O\>340`PP.A2P?__ZS6_EY-1`+[HP($`Z'$"``"%P'4BOYJ340"^ +XMZ,"!`.A>`@``A\2``3(GV9F8N#Q^$``````!(B?/K#F9F+@\?A``` +XM````2/_#B@.$P'0$/#IU\TR)_TB)VN@HI?__2(US`8`[`'7/3(GWZ%=H___H +XMHCX``/8%IQU!``AT"K\!````Z#]B``!(BQU8`4$`2(7;=#A!O_RH40!!O@$` +XM```/'X``````2(M[$#'VZ.6+``!(ASP(`!(@SX`=`R_V,"!`.CT7@``ZPJ_V,"!`.@X)0``@STY'4$``'02 +XMO]C`@0#HM7___T&^`0```.LA@STF'4$``'4+BST:'4$`Z)G2__^_V,"!`.B? +XM!0``08G&]@7Q'$$`$'0*OP(```#HB6$``(,]\AQ!```/E,!%A?8/E,$(P0^V +XMP8/P`4B!Q%@!``!;05Q!74%>05]=PTB+'5``00!(B=\Q]NB^9O__O_F340"^ +XM`911`$B)VND<^O__OSF440#HXF'__[\"````Z`AF___H8V'__XLXZ#QA__^_ +XM(+J!`+X9E%$`2(G",,#H"&/__[\"````Z-YE___H.6'__XLXZ!)A__^_(+J! +XM`+XDE%$`3(GR2(G!,,#HVV+__[\"````Z+%E__^054B)Y4%7059!5%-)B?=) +XMB?Z^M)-1`.CE9/__A0/A0H!``!)BQ]) +XM.U\(#X2*````08`^+P^$@````$B)WS'VZ.=E__])B<=,B?1)B=Y!OP````!T(K^VDU$`,?9, +XMB?(QR>BMAP``3(GW3(GFZ$(.``!!OP$```!$B?A;05Q!7D%?7<-52(GE05=! +XM5E-(@>R8````2(G[2(VU6/___^@!9/__B<$QP(7)#X6,````N0#P```CC6#_ +XM__\QP('Y`$```'5W2(G?Z"AA__^%P'0GZ$]?__^+..@H7___OR"Z@0"^`I11 +XM`$B)VDB)P3#`Z/%@__\QP.M$@#LO=0I(B=_H\`H``.LU3(LUS_U``$R)]S'V +XMZ#UD__])B<=(B=\Q]N@P9/__3(GW3(G^2(G:2(G!0;@O````Z,DL``!(@<28 +XM````6T%>05]=PV9F+@\?A```````54B)Y;_@E%$`OJ````"Z`0```+D@NH$` +XMZ$-C__^_`@```.A)8___D)"0D)"0D)"0@SV=`D$```^4P`^VP,-FD%5(B>5! +XM5T%6051328G_08!_!P-T58,]E!E!``!U'$R)_^BZHO__/0```(!U&$R)_^BK +XMHO__2(72=0M)C70/A/P```!-C;P4`#X3#````]@7^&$$`0'032(VS*`$``+^! +XME5$`,,#H;5W__T'V1Q@P=19!@'\'`G4$QD,&`4B)WTR)_N@PK?__BT,@A8#Z&()``!(B04S`4$`BPTY`4$`C5$!B14P`4$`B0/A1C____V!2T800!`=`J_"@```.AE7/__38NW@````.L09F9F+@\? +XMA```````38MV"$V%]@^$CP```$F+7A"`>P4`=.F#>R``=>.`>P<`==TQTDB+ +XM/;P`00"+!<(`00!F9F9F9BX/'X0``````$B)T3G!D@.?!R(0'VB36!`$$`2,'F`^B8"```2(G'2(D]9@!! +XM`(L-;`!!`(U!`8D%8P!!`(G(2(D`$$``````+^@#P`` +XMZ'`'``!(B04!`$$`QP4/`$$`E@```,<%"0!!``````"_L`0``.A+!P``2(D% +XM[/]``+](QH$`O@H```"Z*+%A`.C@7O__]@7F%D$`(`^$K@```+^5EE$`,?;H +XM)X8``(D%"0!!`+^BEE$`,?;H%88``(7`="V_HI91`#'VZ"6%``!(B<B-7?__2(G#ZPDQ_^C! +XM7O__B<._(+J!`+Z[EE$`B=HPP.C<7/__B=_H55___TR)]^CM````BQTW%D$` +XMZ"(#``"#^P!T%^F]````#Q^$``````#H^\+__^@&`P``Z$',__^%P'3MZ$C, +XM__]!B<3'1=@`````2(UUW+](QH$`Z!!;__](B<-(A=MT44R-?=P/'T``BD,' +XM!/X\`G(KQT78`0```$B)W^@86@``2('#*`$``+^_E5$`2(G>2(G",,#H'UK_ +XM_T'_Q+](QH$`3(G^Z']?__](B<-(A=MUMTF+/DB-5=B^@,Q``.B&M@``N`$` +XM``!%A>1T$;_FE5$`,,#H`+C__[@!````2(/$$%M!7$%>05]=PV9F9F9F+@\? +XMA```````54B)Y4%705934$B+'TB%VP^$B@```(L5&/Y```\?0`!(BPT)_D`` +XM._]0`!(BSW@_4``2,'F`^CO!0``2(D% +XMT/U``(L-UOU``$B+W#H`OW__TB+#1O[0``Y#1G[0`!S=DC!Z2!(BP4`^T``Z3/___](BX.0```` +XM2(7`#X2!````ZP602(M`"$B%P'1U2(MP$(!^!0!T[8!^!P!UYXL%[1%!`*A` +XM=!E(@<8H`0``OT2640`PP.A:5O__BP70$4$`J$`/A.S^__^_\)91`.@B5___ +XMZ=W^__^--`F)-93Z0`!(BSV%^D``2,'F`^BD`@``2(D%=?I``(L->_I``.FB +XM_O__2(G?Z/HX``"+640`PP.BL5?__2(/#<$B)W^C@^___Z3O^__^%R70*O]F640#H;5;_ +XM_[@!````@ST1$4$``'492(G?Z(>E___&0P@!2(G?Z.N____I!O[__TB#Q`A; +XM7<-F9F9F9F8N#Q^$``````!52(GE4U!(B?N*0P<\`W4.2('#*`$``+]"@U$` +XMZU:#>R``=%R+#H7)=#['1?0!````/`=T2SP&=4Y(C;,H`0``O_R540`PP.A4 +XMLO__QD,'!TB+>W!(C57TOH#,0`#H?K$``,9#!P#K&$B!PR@!``"_5X-1`$B) +XMWC#`Z-)4__]FD$B#Q`A;75!5E-(B?-)B?Y!@'X%`'4Y0?9&&!!U,HMS"(M+ +XM##GQ7<.0D)"0D)"0D)"0D)"0D%5(B>534$B)^^A"5?__2(7`=`=(@\0(6UW# +XM2(G?Z`X```!F9F9F9BX/'X0``````%5(B>534$B)^^AB5/__BSCH.U3__[\@ +XMNH$`OC*740!(B<)(B=DPP.@$5O__OP(```#HVEC__V8N#Q^$``````!52(GE +XM05=!5E-028G^Z`Y9__](B<-(_\-(B=_HP%3__TF)QTV%_W0<3(G_3(GV2(G: +XMZ%I4__],B?A(@\0(6T%>05]=PTB)W^AT____#Q]``%5(B>534$B)\^AR5O__ +XM2(7`=`=(@\0(6UW#2(G?Z$[___]F9F9F9BX/'X0``````%5(B>5!5E-)B?9( +XMB?OH+E7__TB%P'0%6T%>7<-(B=],B?;H"0```&8/'X0``````%5(B>5!5E-) +XMB?9(B?OH;E/__XLXZ$=3__^_(+J!`+X7534$B)^[X!````Z&U4__](A_O__9F9F9F8N#Q^$``````!52(GEN@$```#H\E3__X7`=0)=P^AG +XM4O__BSCH0%+__[\@NH$`O@*740!(B<(PP.@,5/__OP(```#HXE;__V:054B) +XMY5-(@>R8````2(G[2(VU:/___^@U5/__B<&X_____X/Y_W0LN`#P```CA7#_ +XM__\]`$```'42Z`)2___'`!4```"X_____^L(2(G?Z%U4__](@<28````6UW# +XM#Q\`54B)Y4%64TB#[!!(B?M(C77LZ!E2__](AQ(B%?__TB) +XMWTR)]NB]5O__2(7`=>A(B=_H4%?__TB#Q!!;05Y=PY"0D)"0D)!(B?A(BSU. +XMX"``2(G&,=+I_)/__V9F9BX/'X0``````%5(B>5!5T%6055!5%-(@>SX```` +XM28GV2(G[2(V]2/___[X``0``Z'5L__](C;TP____O@`!``#H9&S__TB)WTR) +XM]NB)T/__ZQL/'X``````OP$```"^8)M1`$B)PC#`Z,RP__]%,>WK%P\?@``` +XM``"Z`0```.A6&0``9@\?1```2(V]2/___^@DV?__2(7`=0[HFM#__X7`=>;I +XMNQ$``(`X"75Z187M=*=(_\!(B1)C7[YZ)MR__^#^`8/AY<# +XM``")P/\DQ5"740!F#Q^$``````!(C;U(____Z`30__](A<`/A-O^__](BPU< +XMZ$``#Q]``$B)PP^V$TB!^O\```!T"TB-0P'V1`H!"'7F2(V],/___TB)WN@' +XM$0``2(7;#X2>_O__2(G'Z"9R__^%P`^$CO[__^N<28/&_$R)]^A0L/__2(G# +XM2(7;#X0)`P``#Q]``$B-O4C___^^38U1`.A_T?__2(7`#X2E`@``2(G?2(G& +XMZ)NR__^%P'772(G?Z`^T___I.O[__TF#QOY(BP6WYT``9F9F9F9F+@\?A``` +XM````3(GW#[87L?](@?K_````2(G^="),C75(B=^^*X=1`+H'````Z&-0 +XM__^%P'4+2(/#![H!````ZS1(B=^^^891`+H%````Z$)0__](C4L%A8\*$`/E,;K`T`P]D"$]D@/19`A/9(B?YU,^L29F9F+@\?A```````BD8!2/_&A,!T0#S_=/(/ +XMML!"]D0X`0ATY^LO#Q]$``"*`4B)SH3`="$\_W4(2/_&2(GQZ^L/MLA"]D0Y +XM`0AU"DB-3@$\*70+Z]9(B?'K!)!(_\$/M@%(/?\```!T"$+V1#@!"'7J@_H! +XM=0P/MI4H____P>((ZQR#^D!T"('Z@````'4/@+TH____`+D`````#T71A,!T +XM!#PC=02%TG46OP(```"^4)Y1`$R)\C#`Z&VL___K4.CV;@``Z;'[__^_`0`` +XM`+[+GE$`,,#H4*S__^LSN@$```"X/@```$R)]I`/O@XYP0^$2`@``$C_QH3) +XM=>Z_`@```+ZAGE$`B<(PP.@;K/__3(GGOG2&40"Z!P```.BI3O__AUT1HL%DO!``(7`=#(QR4B+%7GP0`!F#Q^$``````")SDB+-/)( +XM@[[H`````'0*@$X:0(L%8O!``/_!.<%RX,<%4O!```````!,B>?H'A8``$4Q +XM[87`#X7#^O__QP4U\$```````$R)Y[YWG%$`Z+Q/__\QR4&`/`0`=$%*C7P@ +XM`;X[````Z+10__](B<,QR4B%VW0H2(N](/___TPYYTB)V7062(G83"G@2`'' +XMOCL```#HB%#__TB)P<8#`$B)C2C___],B>$V-;@%! +XM@/\Z3(GK=0U)C5X"08!^`3I)#T7=#[8#2#W_````=!%"]D0@`0AU5H3`=%(/ +XM'T0``$B)W[X1GE$`Z&-.__^`/`,`=#I(C4P8`0^V1!@!2#W_````2(G+=-A" +XM]D0@`0A(BD3____183_#X2Q`P`` +XM08#_*`^%H@````]7P`\I19!(C7VH2(UUD#'2Z,I1__^%P`^$L@4``$B+79!( +XMA=MT8XL53^Y```\?`$B+#4'N0``YRG,-2,'I($B+!2KN0`#K)HTT"8DU)^Y` +XM`$B+/1CN0`!(P>8#Z*_U__](B04([D``BPT.[D``2(MS$(U1`8D5`>Y``(G) +XM2(DTR$B+6PA(A=MUIDB-?9`Q]NA+I```3(MUJ$R)=:#ITP$``$B+7:B`.P!, +XMC7VP#X2(`0``2(G?3(GVZ)*4__^%P'582(G?3(GVZ,,?``!)B<1-A>1U(DB) +XMWTR)]KH!````Z,M#``!)B<1!@&0D&OU-A>0/A$0!``!(BPUZ[4``.0UX[4`` +XM#X/\````2,'I($B+!5OM0`#I$@$```]7P`\I1<`/*46P2(G?3(GV2(U=P$B) +XMVDR)^>BFCO__2(G?OL!E0`#HF:,``.L7#Q^``````(U1`8D5(^U``(G)3(DD +XMR)!,B?_H**,``$B)PTB%VP^$A@```$B)W^AD3?__28G%20'=2(G?3(GNZ`,? +XM``!)B<1-A>1U'DB)WTR)[KH!````Z`M#``!)B<1!@&0D&OU-A>1TK4B+#;[L +XM0``Y#;SL0`!S#4C!Z2!(BP6C[$``ZX&--`F)-:#L0`!(BSV1[$``2,'F`^@H +XM]/__2(D%@>Q``(L-A^Q``.E6____3(G_,?;HW*(``.LUC30)B35I[$``2(L] +XM6NQ``$C!Y@/H\?/__TB)!4KL0`"+#5#L0`"-40&)%4?L0`")R4R)),A,BW6@ +XMZQ9F9F9F9F8N#Q^$``````!)_\9,B76@00^V!D@]_P```'0.2(L-'N!``/9$ +XM"`$(==],B76H00^V!DB#^#H/AVW\__](N0$````"```$2`^CP0^#6?S__S'; +XM13'_BP7:ZT``AM` +XM`$B+/-D/MD\$B0/E<$/MLD!P8/Y`@^,808``+\!````OLZ=40`PP.ALIO__,=N#/2_K0``` +XM0;XH`0``=#%F9BX/'X0``````$B+!0GK0`!(BSS83`'WOB"Z@0#HN$O__TC_ +XMPXL%^^I``$@YPW+:OPH```"^(+J!`.BK2O__QP7]ZD``'P```$4QY.DJ!P`` +XM@SW.ZD```'1`2(L%N>I``$B+&+@H`0``2`'#2(G?OGB=40#H$4K__X7`=!%( +XMB=^^@)U1`.@`2O__AM[ +XM28U\)`?K%&9F9F9F+@\?A```````BE\!2/_'L/^`^_](B?YT-@^VPT+V1#`! +XM"'7EA-N(V$B)_G4BOP$```"^%)Y1`+ITAE$`,,#H!J7__^E1]/__D(I&`4C_ +XMQCS_=/:$P`^$+O3__P^VP$+V1#`!"`^%'_3__^O=2(G!2/_!2(L%J-U``$F) +XMST$/MA=%,?9(@?K_````="!)C4\!13'V]D0"`0AUW^L09F9F9BX/'X0````` +XM`$'_QD0[-6+I0`!S&D2)\$B+#4KI0`!(C3S!1(GNZ#X(``"%P'7:3(E]B(L% +XM7.E``$&`/P!U'8/X%']6@_@%#X6U````QP6J_T```0```.FF````@_@:#X14 +XM`P``@_@0#X1+`P``@_@.#X6+````3(G_Z*K4___I-0,``+\!````OC>=40`P +XMP.@4I/__Z1\#``"#P.N#^`9W8/\DQ8B740!(C;UP____OE#G0`#HGZ```.M& +XM3(GWZ(4,``#I,//__TB+5:B_`0```+Y3G5$`,,#HRZ/__S'`Z23^___'!0K_ +XM0``!````ZQ''!2+_0``!````ZP7H)QH``(L%C>A``(/X&P^'-0$``+E`!"(( +XM#Z/!#X,G`0``2(M%B(`X``^$!P$``$B+#4[<0`#K%`\?0`!)_\=F9F9F+@\? +XMA```````00^V%TB!^O\```!TXX32=`?V1`H!"'38BPTNZ$``@_D:?Q>#^0E_ +XM)(/Y!G5\2(G'3(G^Z'@>``#K;X/Y&W5J2(G'3(G^Z/8<``#K78/Y"G4-2(G' +XM3(G^Z-0>``#K2X/Y$74-2(G'3(G^Z.(R``#K.8/Y%74T2(N=9( +XMB46(@#@`28G'#X46____2(V] +XMZPUF#Q]$``!(B76(28GW@#X`#X3V````2(L%$=M``.L*#Q^``````$G_QT$/ +XMM@](@?G_````=/"$R71&]D0!`0AU$X#Y*'7@23GW=MM!@'__)'4'Z]*`^2AU +XM)P]7P`\IA6#___],B?=(C9U@____2(G>,=+H#TK__X7`=7[IV@$``$2)YTR) +XM^NA;!P``28U'`4&`/P!)#T3'9F9F9F9F+@\?A```````2(L-@=I``&8/'X0` +XM`````$B)Q@^V%DB!^O\````/A#W___](C48!]D0*`0AUXNDM____9F9F9BX/ +XM'X0``````$@%*`$``$2)YTB)QC'2Z.T&``!(B=_H-9P``$B%P'7@2(M%B.N: +XM2(,]$N9```!U4#'`2(L-]^5``(L5_>5``.L29F9F9F9F+@\?A```````2/_` +XM.=!S*4B+-,'W1A@P(`0`=>R`?@0`=>9(B37/Y4``9F9F9F9F+@\?A``````` +XM2(N](/___^CD1O__0;T!````2(N5*/___TB%T@^$'O#__TC_PDB+!9S90``/ +XM'T``2(G7#[8/2('Y_P```'092(U7`?9$`0$(=>9!O0$```"$R0^$Z.___^BC +XM[/__28G&13'_0;T!````@SU,Y4````^$RN___V8N#Q^$``````!$B?A(BPTF +XMY4``2(LUT +XM+,<%\.1``!4```!%,>3I'0$``$B+58B_`0```+YZG%$`,,#HYY___^GR_O__ +XM08/\`75)2(L-E>1``$B+`0^V4`2#XC^)%;'D0`"#^AD/CY8```"#^@P/A9X` +XM``!(BPVDSB``2(,Y``^$P````,<%A.1```````#IL0```$6%Y`^$A@```+\! +XM````ONN=40`PP.AYG___,=N#/3SD0```0;XH`0``="X/'X0``````$B+!1GD +XM0`!(BSS83`'WOB"Z@0#HR$3__TC_PXL%"^1``$@YPW+:OPH```"^(+J!`.B[ +XM0___13'DZT>#^AIU/\<%?_I```$```#K,X/Z$'4;QP5R^D```0```.LBQP7F +XMXT```````$4QY.L6@_H3=0Y(QP75XT```````$B+`42+($B+1:#I-OG__T6% +XM[71+BP67XT``A05]=PV:054B) +XMY4%7059!5%-)B?9)B?],B?>^(P```.BB0___3#GP#X2Y````2(7`#X2D```` +XM28L'28E'"$V)].L*#Q]``$C_PTF)W$&*!"2$P'1C/"-T7SQ<=59)C5PD`4&* +XM1"0!/"-U0$R)YDPI]DR)_TR)\NBK6/__28M'"$F+3Q!(*<%(@_D!?PQ,B?_H +XM,EC__TF+1PA(C4@!28E/",8`(TV-="0"B@.$P$D/1-SKE$R)X^N/32GT3(G_ +XM3(GF3(GRZ%Y8__],B?_H-EG__TF+1PC&``!-BS=,B?!;05Q!7D%?7<._G)Q1 +XM`+XW!```NO">40"Y_YY1`.@G0/__#Q^``````%5(B>534$C'!0_B0``````` +XMQP7]X4``(````,<%]^%```````"_``$``.C!Z/__2(D%VN%``,<%\.%``(`` +XM``#'!>KA0```````OP`$``#HG.C__[L8````2(D%R.%``$B+NZB740!(BX.P +XMEU$`2(UT./^+D[B740"Y`0```.@-.```BHN\EU$`B$@$BXO`EU$`B0A(@\,@ +XM@?NX`P``=7>FAE@``,,"_ +XM@)M1`%M!7EWI(9O__UM!7EW#9F9F+@\?A```````54B)Y4%7059!54%44TB# +XM[!A(B7W(B?�=,BR=%BVPD&$2)Z(/@!SG!=`R%P'0(AZ/"4``"%P'08@SVAX$```'4+3(GO3(G^Z)B5 +XM``!!_T<@38MV"$V%]G7+QT,8!!```$F#Q%!,B>=(B=[H=94``$B+1/K`TR)XT$)]42):QBX`0```)!(@\086T%<05U!7D%?7<.) +XM\[\%````Z.7F__])B<=!]L4!=`A!Q@0`#HN9,``$R)+;+>0`!,B6W0Z7,! +XM``"#X#^#^!T/A2P"``#_!8_>0`#I$@(``(/X#'4U2(L]CL@@`$F!Q2@!``!, +XMB>[H=Y,``+]HQR4B#Q`A;05Q!74%>05]=Z2AC``!%A?9T!D4) +XM=1CK7(,](MY```!T4TV-96`QVV9F9F9F+@\?A```````B=A(BPWWW4``3(L\ +XMP4F-?W!,B>[H5Y(``(7`=!B#/0C>0```=0M,B>=,B?[H_Y(``$'_1R#_PSL= +XMS]U``'+!08M%&$R);="#X`>#^`0/A:<```!(BT703(MH4$V%[0^$E@```$6% +XM]G0G#Q^``````$F+11!$"7`838MM"$V%[77OZW=F9F9F+@\?A```````@SUU +XMW4```'1838ME$$V-="1@13'_9F8N#Q^$``````!$B?A(BPU&W4``2(LW!,B>;HII$``(7`=!>#/5?=0```=0M,B?=(B=[H3I(``/]#($'_QT0[/1W= +XM0`!ROTV+;0A-A>UUEHL%*-U``$R+9=!!B40D'$B+#1#=0``Y#0[=0`!S#4C! +XMZ2!(BP7UW$``ZR:--`F)-?+<0`!(BSWCW$``2,'F`^ABY/__2(D%T]Q``(L- +XMV=Q``(U1`8D5T-Q``(G)3(DDR(,]Q]Q```!T34V-M"20````13'_ZR-(B=]( +XM@^^`3(GFZ+&1``!,B?=(B=[HII$``$'_QXL5D=Q``$$YUW,81(GX2(L-=MQ` +XM`$B+',&+0QQ!.T0D''S`2(/$"%M!7$%=05Y!7UW#OYR<40"^M`$``+JZG%$` +XMN<6<40#H.#K__P\?A```````54B)Y4%7059!5%-!B=8QTC')Z/EJ``!)B<=% +XMA?9T+TR)_S'VZ*<\__](BQ4PQB``3(G_2(G&,05]=Z7NU +XM__\PP+\!````OD&>40!(B=I;05Q!7D%?7>F_E?__OP$```"^+YY1`$R)^C#` +XMZ*N5__],B?];05Q!7D%?7>F;.___3(GG,?;H`3O__TB+%4K$(`!,B>=(B<:Y +XM`0```.C:- +XM``!,BR7XS4``13'M9F9F9BX/'X0``````$F)QD$/M@Y(@?G_````=`Y)C48! +XM0O9$(0$(=>3K(K'_13'MZQMF9BX/'X0``````$&*#TV)_D&)Q0\?@`````!- +XMC7X!@/D]#X3/````#[[!@_@J?QZ#^"$/A?(```!$B>B#X`2#^`$9P/?01`GH +XM@\@$ZVR#^#]U%42)Z(/@"H/X`1G`]]!$">B#R`CK4H/X.G4<3(G_ONB"40"Z +XM`@```.@,-___AB# +XMR`+K$T2)Z(/@`8/X`1G`]]!$">B#R`&#^/]T;.E'____#Q^``````$G_QD&* +XM#D&]!````(3)#X0\____@/D]#X0S____Z^&038U^`4+V1"`!"'0/38G^00^V +XM!D@]_P```'7E0?;%"'0^2(M]P$B+=^ +XM)````.C[./__2(7`="M,B??H73G__^L/2(UUN$R)]^@_3___28G'2(MUN$B%]G0/OP(```!,B?(P +XMP.@TD___38G^0?;%`7111(LEU.Y``,<%RNY```````!(BWW`2(MUR.B]70`` +XMA@E6P``3(GW,?8QTNBY8P``28G&1(DEC^Y` +XM`$V)].L#13'D2(M]P$B+=05]=PY"0D)"0D%5(B>5!5T%6055!5%-0 +XM18G'28G,2(E5T$F)_DDIU$PI]D6%_P^5P`^VV$@!\TF-?!P!Z$G=__])B<5, +XMB>],B?9(B=KH.#+__TZ--"-%A?]T!4:(?"O_3`'K2(G?2(MUT$R)XN@8,O__ +XM0\9$-0``3(GH2(/$"%M!7$%=05Y!7UW#54B)Y4%7059!54%44TB#[!A)B=1( +XMB77`2(G[OY@!``#HV]S__^L,9@\?A```````2/_#B@N`^0ET]H#Y('3Q28G& +XM2(G?Z$8V__](_\!T#$B)Q^BIW/__28D$)#'`2(E%T$F+-"1%,,F_,@```$F) +XM\$R)\.L;9F8N#Q^$``````!(_\9(_\-F+@\?A```````1(HS00^^SH/Y6W\V +XM@_DG#X>"`0``2+H`!@```0```$@/H\IS;$6$R0^%:0$``$V%P`^%P0```$4Q +XMP$4PR4C_P^N^@_E<#X5,`0``2(U3`42*G+````@_EM#X^(````@_EF#X6V````0;8,Z:X```!(A05]=PV9F+@\?A```````2(L/2(L%OL=``&8/'T0``$F)R$$/MC!(@?[_ +XM````=!U)C4@!]D0&`0AUY3#),@$`2`]%T.O2@_@??P>#^`EUR.L%@_@@=0:$R70AZ[N#^")T!8/X)W6Q0#CQ +XM=`R$R70#0(C.0(CQZZ`PR>N<2(D73(G`PP\?1```54B)Y4%7059!54%44U!) +XMB<](B=-)B?9)B?Q(B5W03(UMT.L69F9F+@\?A```````2/_#2(E=T$G_Q$PY +XM^W1NB@N`^2H/A(4````QP$TYY@^$T0```(#Y/W36@/E<=19(_\-(B5W0,Y,B?KHKP```(G!,<"% +XMR0^$B0```$B+7=#KC3'`03H,)'5[ZX--.>8/E,`/ML#K;@\?A```````28U, +XM)`$QP$TY]$F)S'172/_#9F9F9F8N#Q^$``````"X`0```$DYWW0\B@-(_\,\ +XM*G3M2/_+/#]TQF8/'T0``#'`33GF=!],B>=,B?9(B=I,B?GHZ/[__XG!2?_$ +XMN`$```"%R73:2(/$"%M!7$%=05Y!7UW#9F8N#Q^$``````!52(GE2(L.2#G1 +XM#X2N````1(H!08#X(70&08#X7G4A2/_!2(D.0`^^_^C2____A<`/E,`/ML!= +XMPP\?A```````08#X7'442/_!2(D.,0$M=2U,C4D",5!5T%6 +XM055!5%-02(G328GU28G^08!]``!T0TB)7=!,B>^^)0```.@A,?__28G'387_ +XM=#=-B?3K"@\?0`!)_\5)_\1-.>]T*T&*!"1%,?:$P'1X13'V03I%`'5OZ]], +XMB??HIS#__TB)`^M@38GO38GTZPI!@'\!`'0_2?_'3(GC13'V9BX/'X0````` +XM`$R)_TB)WNAU+___ALA3"GC2(M%T$B)&$V)YNL2 +XM3(GGZ$PP__](BTW02(D!38GF3(GP2(/$"%M!7$%=05Y!7UW#54B)Y4%7059! +XM54%44U!)B^^)0```.A),/__2(G#2(7;=!=(B=Y,*>Y, +XMB?=,B>KHD$7__TC_PTF)W4R)]TR)YDR)^NA\1?__3(GOZ-0O__],B?=(B<9, +XMB>I(@\0(6T%<05U!7D%?7>E81?__#Q^$``````!52(GE05=!5E-02(GS28G^ +XM3"GS2(U[`>@$UO__28G'3(G_3(GV2(G:Z/,J__]!Q@0?`$R)^$B#Q`A;05Y! +XM7UW#54B)Y4%7059!54%44U!)B==)B?1(B?N_`0```$@IWTP!Y^BYU?__2(E% +XMT$F)Q>L*18AU`$G_Q4C_PTPYXW0Z1(HS08#^7'7H2/_#3#GC="%$BC-!#[[V +XM3(G_Z%$O__](A05]=PV9F9F9F9BX/'X0``````#'`2#GW=`X/OD;_2/_..=!U +XM[DB)\,.0D)"0D)"0D)"054B)Y5-02(UU]+](QX$`Z/PI__](A!`$R)]NC.+/__08G' +XMOPC'@0!$B?[H'BK__TF)Q$V%Y'4?2(MUV$R)]^A*(@``28G$OPC'@0!$B?Y, +XMB>+H9RK__TF#O"3H`````'0A28V<).@```!(B=\Q]NBZ@P``2,=#"`````!( +XMQP,`````28-\)'``=!Y)C5PD<$B)WS'VZ)2#``!(QT,(`````$C'`P````!! +XMQT0D&```!`!(BW70]D8($'020<9$)`152(M%R$F)A"0(`0``]@6%XT``@'08 +XM2(/&2$B+505]=PV9F9F9F +XM9BX/'X0``````%5(B>5!5T%6055!5%-(@^PH2(E-P$B)5;A(B?)(B57(2(G[ +XM,1(QT70`````.L0D$'!Q0)!#[Y&_T$QQ4G_SDDYW@^$XP```+](QX$` +XM3(GV1(GIZ.@G__],B?%(*=E(.PW3XD``#X^C````OTC'@0")QNB9*/__28G' +XM387_#X2+````0?9'"`@/A(````!-A?9,B?!U"TB)W^A2+/__2`'8,GH_";__[](QX$`B<;HP"?__TB)P3'`2(7)=#.* +XM00@D&$&\`````$P/1>&$P$@/11U=RT``,1T$TB+1;A,B2!(BT7`2(D8 +XMN`$```!(@\0H6T%<05U!7D%?7<,/'T``ZPYF9F9F9BX/'X0``````%5(B>5! +XM5T%605132(/L$$F)]DF)_TV%]G4.3(G_Z!XK__])B<9-`?XQR4TY_DR)\'0) +XM00^^3O])C4;_3#GX=!'!P0(/OE#_,=%(_\A).<=U[[](QX$`3(G^3(GRZ"\F +XM__]!B<2_2,>!`$2)YNCO)O__2(G#2(7;=6A,B7782(U5V+\`L6$`3(G^Z)(E +XM__](B<-(BT783"GX2(D#9L=#"```2,=#&`````!(QT,0`````$C'0T`````` +XM2,=#.`````!(QT,P`````$C'0R@`````OTC'@0!$B>9(B=KH[R;__P^W0PBH +XM"'4LBPVYRD``C5$!B16PRD``B4L@@\@(9HE#"$B+`T@[!7S@0`!V!TB)!7/@ +XM0`!(B=A(@\006T%<05Y!7UW#9F8N#Q^$``````!(BX<(`0``2#L%RLE```^4 +XMP4B%P$B-0!`/E,((RD@/105[LR``PV8N#Q^$``````!52(GE4U!(B?!(B?M( +XMA^_2,>!`$B)WDB)PNC/)/__OTC'@0") +XMQNB3)?__2(7`=`2`2`@!2(/$"%M=PP\?`%5(B>534$B)\$B)^TB%P'4+2(G? +XMZ$2(G"Z$\D__^_2,>!`(G&Z!,E__]( +XMA!``2(UX$'4,N@!E0`#H +XM!'\``.L%Z'UG__^_2,>!`$B)WNB@*/__2(7`=W`` +XM=%6*0P0D/SP5=$Q,C:LH`0``3(GOZ/C! +XM^O__A\Q]NA2)___3(GO2(G&Z'=M__^%P`^$ +XM=00``/8%)-U``(!T#[]LH%$`3(GN,,#HER'__TR)[TR)K6C____HV";__TB) +XMPTB%VP^$G@```$B+19!(C8P8*`$``$0/OJ0#)P$``$4Q[>L89I!(BT60#[Z$ +XM&"8!``!!P<0"03'$2/_+2(/[`7192(M%D$R-M!@G`0``OTC'@0!,B?9(B'HOR'__[](QX$`B<;H@R+__TB%P'01387M=`F+2"!!.TT@?0-) +XMB<5,B?E(BXPP.BZ(/__3(GO3(GVN@$```#HFE$``$B%P'44 +XMOZN@40!,B>XPP.B6(/__Z3L#```/5\`/*46P2(M-D/9!&B!)B<5T($B)1:A( +XMB4602(U]J$B-=;!,B?+HM2C__^D.`0``2?_%08I-`(#Y"73T@/D@=.](B460 +XM3(EMH`\?@`````!,B>[K&V9F+@\?A```````2/_&2(EUH&8/'X0```````^V +XM!D@]_P```'3EA,`/A)D```!(BPW^N$``]D0(`0AU,CPD=1%(B=],B?;H,$L` +XM`$B+=:#KRCQ<=;:`?@$`=`I(@\8"2(EUH.NV2/_&2(EUH.NM3(GON@$```#H +XMX!H``$C_1:!(C7VP2(G&Z,!Y``!,BVV@ZQ%F+@\?A```````2?_%3(EMH$$/ +XMMD4`2#W_````#X1(____2(L->;A``/9$"`$(#X0V____Z]1,.>Y,BW6(=#M, +XMB>^Z`0```.A^&@``2(U]L$B)QNAB>0``3(MUB.L<9F9F+@\?A```````0?]$ +XM)"!F9BX/'X0``````$B-1;!)B<5F#Q^$``````!,B>_H&'H``$B)PTB%VP^$ +XM@0```/8%@=I``(!T$TB-LR@!``"_$XM1`##`Z/`>__](BWV82(G>Z`1]``!( +XMA(P8#!_H#Y +XM`@^#;_____9#&#`/A77___\\`G4&0<9$)`8!3(GG2(G>Z'!N___I6____TB+ +XM?9#HHB3___8%]]E``(#I$P$``/8%Z]E``(!T$$F-=4B_AZ!1`##`Z%T>__]) +XM@\40#U?`#RE%P$B+G6C___](B=\Q]NC1(___2(G?2(G&3(GJ3(UMP$R)Z>A\ +XM9/__3(MUB.L69@\?1```0?]$)"!F9BX/'X0``````$R)[^@(>0``2(G#BP5[ +XMV4``N8`````AR$B%VP^$B@```(7`=`^_$XM1`$B)WC#`Z-P=__](B=\Q]KH! +XM````Z.T8``!(B<-(BWV82(G>Z-Y[``!(A(P8#!_H#Y`@^#:?____9#&#`/A6____\\`G4& +XM0<9$)`8!3(GG2(G>Z$IM___I5?___X7`3(NU>/___TB-7:!T"K\*````Z`P= +XM__]!_TPD($B+?9A(BW6(Z'I[``!(BX5P____2(7`2(GG^___2('$B``` +XM`%M!7$%=05Y!7UW##Q]$``!52(GE05=!5E-0Z($```!(BQT:PD``ZQ@/'X0` +XM`````$B#PPA)B=])BQ]F#Q]$``!(A=MT2DR+Z-YZ``!,B??H +XMMB+__TF+'^NQ2(/$"%M!7D%?7<-F#Q]$``!52(GE05=!5D%505132('LF``` +XM`$F)_TR)O7C___]!BT<8J0``@``/A<,$```-``"``$&)1QCV!;_70`"`=!=) +XMC;(P8#!_H#Y`@^#R0(``$'V1A@P +XM#X7!`@``/`)U!,9#!@%(B=],B?;H4VO__^FI`@``J0``$`!T5+](QX$`OKF? +XM40"ZNY]1`+FJ`0``Z.X;__^_2,>!`(G&Z+(<__](A<`/A$@"``!)B8<(`0`` +XM2(/`$$R)_TB)QNBC,O__2<>'J````/RH40#I@P,```]7P`\I19`/*46`28V_ +XM*`$``$B)O6#____H12#__TB%P`^$9@$``$F-C`+Y``$F)1A!- +XMB7X@2<=&&`````!!QT8H`````$B)W^A8Q?__28E&"$F#O^@`````=0M)@W]P +XM``^$D0$``/8%A-1``(`/A*8!``"_Z)]1`##`Z/88___IE0$``$G'AP@!```` +XM````28V'*`$``$F)AZ````!)QX>H````_*A1`.DX`0``_T,@28N&H````$B) +XM@Z````!)BX:H````2(F#J````$V+I@@!``!-A>1T'DF-AB@!``!(B8.X```` +XM2(N%'H.@P` +XM`(7`=1_V!4O30`"`=!9)@\1(OTJ@40!,B>9,B?HPP.BW%___2(N->/___XM! +XM&*@'=0:#R`&)01A!@$X:"&9F9F9F+@\?A```````2('$F````%M!7$%=05Y! +XM7UW#3(EUP$B-19!(B46X28M&$$B+>#A(C56XOO`700#H[',``/8%T=)``(!T +XM"K\PH5$`Z"D8__](B9U@____2(U]@$R)]NA&<0``38G\3(UMD$R-=#B^\!=!`$R)\NB39,BZ5@____38FFH````$F-AJ````!(B85( +XM____13'_,,E(A=NX`````$B)A6C___],B>!T:NM32(G'Z$`<___V!9710`"` +XM3(GX=!2_%J%1`.CJ%O__3(GX#Q^``````$B)PTB+0QA(A/___P^$E`$``$F+?PA-BW<@Z+D:__])@\9P +XM2&/`2(F%=(BY5P____Z+$7__^%P'6=2(N=_H +XM*AK__TB--!A)C10T,[H,A7__[](QX$`B<;H]A7__TB) +XMPTB%VP^$*O___TF+=Q!(C7LHZ(UR``!(A<`/A!3___^_,````.@:P/__28G& +XM3(NM6/___TR)[^AXP/__28D&28M'"$F)1@A)B5X038E^&$B+A5#___])B48@ +XM0<=&*`````!!_TZU9,B;5X____]@5+ST`` +XM@`^$7@$``+_MGU$`3(GF,,#HNA/__^E*`0``#Q]$``"_\,:!`$B)WNCS;``` +XM2(M;&$B%VW032(-[&`!T#.OA28G>3(NE8/___TC'A6C___\`````387V#X0( +XM`0``28M&($B%P'4328L^,?:Z`0```.A[#@``28E&($F+3A!-BVX8387M#X2L +XM````38UF$$V-?AA,B?/K%68/'X0``````$R-8Q!,C7L82(M#($B)B`@!``!) +XMBT4@2(7`=11)BWT`,?:Z`0```.@D#@``28E%($F+#"1)BU402(MS($B)Q^A, +XM!P``28M%($@[A7C___]T*H!(&H!)BWT(Z`*___])BTT@2(F!J````$F+12!( +XMC8@H`0``2(F(H````$F+'TB+2Q!,BVL8387M#X5Q____3(NE8/___TB+G7C_ +XM__](B8L(`0``2(M[$.BC&/__3(GGZ*N^__](B4,03(GV3(UMD.E]`0``2(N= +XM>/____9#&`=T1$B#>W``=0I(@[OH`````'0S,4B)Q^C2O?__2(N-2/___TB)`8"]1____P%U9TR+8Q!,B>?H +XMTQ;__TF+3Q`K`4B)BP@!``!,8_!'BCPT0\8$-`!,BV,03(GGOB\```#H*1/_ +XM_TB%P$B->`%)#T3\Z'F]__](B8.H````2(M#$$:(/#!(B[5H____ZT-(B[5H +XM____ZSI(QX,(`0```````$R+^+P```.C<$O__2(7`2(UX`4D/1/[H +XM++W__TB)@Z@```!(B[5H____2(7V=$F_\,:!`.@O:@``9F9F9F9F+@\?A``` +XM````3(UMD.LJ9BX/'X0``````$R-;9!,B>],B?;H\6X``$B)W^C)%O__9@\? +XMA```````38MU`$V%]G0O38UN"$F+7A"#>R@`=>E(BSOHH1;__TB+0QA(APCHCQ;__^NM_T@HZZA(C46`#Q]``$B+&$B%VW0K2(U#"$R+^_2,>!`$B) +XMWDB)PN@O$/__OTC'@0")QNCS$/__2(7`=!Y(BPVGM$``9H-A"/N`2`@$2(D% +XME[1``$B#Q`A;7<,PP+\"````OC^?40!(B=I(@\0(6UWI9F___V8/'T0``%5( +XMB>532(/L&+\(QX$`O@0```"Z*+%A`.B3$O__2,=%Z`````"[_*A1`$B-5>B_ +XM`+%A`+[\J%$`Z#,/__](BTWH2"G92(D(9L=`"```2,=`&`````!(QT`0```` +XM`$C'0$``````2,=`.`````!(QT`P`````$C'0"@`````2(D%U+-```^W2`B) +XMRH/*!&:)4`CVP0AU+(L57+1``(UR`8DU4[1``(E0((/)#&:)2`A(BPA(.PT? +XMRD``=@=(B0T6RD``2(LU5YT@`$B->!#HKE+__[](QX$`O@0```"Z`+%A`.C* +XM$?__QP4(M$```````$B-=?2_2,>!`.CR#O__2(7`="-(C5WT9@\?A``````` +XM@&`(][](QX$`2(G>Z(\3__](A_=I]1`.L6@_@"=0>_?I]1`.L* +XM@_@$=0R_G9!1`##`Z!$-__^%V[\I````00]%_+Z(N8$`Z*P1__^%VW6HOPH` +XM``"^B+F!`.B9$?__OX:?40`PP.C=#/__28U]*+X@%D$`Z)]I``"_"@```+Z( +XMN8$`Z'`1__^_C9]1`##`Z+0,__])C7TXOB`600#H=FD``+\*````OHBY@0#H +XM1Q'__[^6GU$`,,#HBPS__TF#Q1!,B>_H#U'__[\*````OHBY@0#H(!'__[]( +XMQX$`3(GVZ-,1__])B<5-A>T/A05]=PV9F9F9F +XM9BX/'X0``````$B-=T@PP+_CB%$`Z:`+__]52(GE05=!5D%505132(/L&$F) +XMS$B)5=!(B?-)B?Y-C6YP3(GOZ,9D``"%P'0Y2(U[8$R)]NAV90``BD,'B,&` +XMP?Z`^0)S'/9#&#!U&CP"=05!QD8&`4R)]TB)WN@?6___ZP1!_T8@BT,82(E= +XMR(/@!X/X!'5S2(M%R$B+6%#K$$B+6PAF9F8N#Q^$``````!(A=MT5$R+>Q!, +XMB>],B?[H3&0``(7`=-A)C7]@3(GVZ/QD``!!BD<'B,&`P?Z`^0)S'4'V1Q@P +XM=;<\`G4%0<9&!@%,B?=,B?[HHUK__^NA0?]&($B+6PCKITF#Q$A,B67`13'M +XM3(GG,?;H,A#__TF)QTB+7=!(@\-(2(E=T$B)WS'VZ!D0__],B>=,B?Y(B=I( +XMB<%%,<#HM=C__TF)Q+\(QX$`3(GFZ/4+__^_",>!`(G&Z,D+__])B<=,B>?H +XM;A#__TV%_W14]@6^Q4``@$B+7 +XMZ'QC``"_,````.@BM?__2(G#3(EMT$V+;PA,B>\Q]NC=#O__3(EUR$F)QDR) +XMYS'VZ,P.__],B>],B?9,B>)(B<%%,<#H:-?__TB)`TF+1PA(B4,(3(E[&$C' +XM0R``````2(M%T$B)0Q#'0R@`````0?]'*$B+1GQ8@``D%5(B>5!5T%6055!5%-028GW28G^13'D3(GP9@\?1```3(LH +XMLP%-A>UT%4F-10A-BV4008M,)"`PVT$[3R!\X?8%%L1``(!T%$&+5R!)C7=( +XMO\:@40`PP.B$"/__@/L!=2SV!?3#0`"`=`J_[Z!1`.A,"?__3(GW3(G^2(/$ +XM"%M!7$%=05Y!7UWI8V(``+B`````(P7$PT``08M4)"!!.U<@=1R%P'1+O_Z@ +XM40!(@\0(6T%<05U!7D%?7>D!"?__AY,B?I(@\0(6T%<05U!7D%?7>D^90``2(/$"%M!7$%=05Y!7UW#9F9F +XM9F9F+@\?A```````54B)Y4%7059!54%44TB#["A)B==)B?:)^P]7P`\I1!``=!](B<;HLDO__[](QX$`3(GFZ-4,__](A;H +XMD4K__TB)PTR)]S'V2(G:,F(``$B# +XMQ"A;05Q!74%>05]=PY"0D)"0D)"0D)"054B)Y;^0QX$`O@H```"Z*+%A`.AH +XM"O__OQBB40"^'J)1`+I:[@``N0$```#H/P(``$B)!9#"0`"!2!@`(`,`OQ^B +XM40"^(Z)1`+JL#@``N0$```#H&`(``$B)!6'"0`"!2!@`(`,`OR2B40"^+J)1 +XM`+K$EN8`N0$```#H\0$``$B)!2K"0`"!2!@`(`,`OR^B40"^-Z)1`+ITA@X` +XMN0$```#HR@$``$B)!0O"0`"!2!@`(`<`7<-F+@\?A```````54B)Y4%64TB# +XM[!!)B?Y(B77H2(U5Z+\HL6$`3(GVZ%T&__](B<-(QT,0`````$&`/BUU$$&` +XM?@%L=0G'0Q@``!``ZP?'0Q@`````QT,@`````,=#'`````#'0P0`````QT,H +XM````@$C'0S``````QT,X````@$C'0T``````2(V[H````$C'@Y@````````` +XM2,>#D`````````!(QX.(`````````$C'@X``````````2,=#>`````!(QT-P +XM`````$C'0V@`````2,=#8`````!(QT-8`````$C'0U``````Z-HG``!(QT-( +XM`````$C'@P@!````````2,>#``$```````!(QX/X`````````$C'@_`````` +XM````2,>#Z`````````!(QX/@`````````$C'@]@`````````2,>#(`$````` +XM``!(QX,8`0```````$B)FQ`!``#&0P@`2(G82(/$$%M!7EW##Q^$``````!5 +XM2(GE05932(/L$(G328G^2(EUZ$B-=>CH\PC__TB+=>A,B?>)PHG9Z!,```!( +XM@\006T%>7<-F+@\?A```````54B)Y4%7059!54%44U!!B&D`````````!)QX:(`````````$G'AH``````````2<=& +XM>`````!)QT9P`````$G'1F@`````2<=&8`````!)QT98`````$G'1E`````` +XMZ.(E``!)QT9(`````$G'A@@!````````2<>&``$```````!)QX;X```````` +XM`$G'AO``````````2<>&Z`````````!)QX;@`````````$G'AM@````````` +XM2<>&(`$```````!)QX88`0```````$V)MA`!``!!QD8(`+^0QX$`B=Y,B?+H +XMS`3__TR)\$B#Q`A;05Q!74%>05]=PV8N#Q^$``````!52(GE05=!5D%44TB# +XM[!!)B?],BR9-A>1T7DR-==AFD$F+7"002,=%V`````!(B=],B?;HR`;__TB+ +XM==A(B=^)PKD!````Z.7]__](B<-,B?](B=[HAUP``/9#&`1T#TB#PU!,B?]( +XMB=[HPEP``$V+9"0(387D=:A(@\006T%<05Y!7UW#9F8N#Q^$``````"#/;&] +XM0```=`:X`0```,.+1QC!Z`:#X`'##Q^``````(,]K;U```!T!K@!````PXM' +XM&,'H"(/@`<,/'X``````@SUIO4```'0&N`$```###[='&&:IA$`/E<`/ML## +XM9I!(B?DPP+\=CU$`2(G.Z5!5E.)^X/C +XM^`^$A0$``$&^(`````\?A```````B=H/O,I!#T3.N`$```#3X(G#]],ATSW_ +XM_Q\`?W(]__\/``^/B0```#W__P<`#X^@````/?\?```/C[0````]_P\```^/ +XMMP```#W_`P``#X^Z````/?\!```/C[T````]_P````^/P````(/X?P^/Q0`` +XM`(/X/P^/R@```(/X"`^%S0```+\XHE$`Z=D````]```@``^%U0```/8%?+Q` +XM``$/A,@```"_H*)1`.FW````/0``$``/A;,```#V!5J\0``!#X2F````OY&B +XM40#IE0```#T```@`#X61````]@4XO$```0^$A````+^7HE$`ZW8]`"```'5V +XMOX>B40#K:#T`$```=6B_>Z)1`.M:/0`$``!U6K]THE$`ZTP]``(``'5,OVVB +XM40#K/CT``0``=3Z_9*)1`.LP/8````!U,+]9HE$`ZR*#^$!U)+]0HE$`ZQ:# +XM^!!U![]#HE$`ZPJ#^"!U#+])HE$`,,#H,0#__X7;#X6)_O__6T%>7<,/'T`` +XM#[Y/!X/Y!7<,N*BB40#_),V(H5$`N,"B40##N+NB40##N.6640##N+"B40## +XMN)R#40##9F9F9BX/'X0``````%5(B>5!5E-(@^P0B?N_8*-1`.BI`/__2(UU +XM[+^0QX$`Z&L`__](AQFD$B)QXG>Z+8```"_D,>!`$R)]N@)!?__ +XM2(7`=>2_^ZA1`.AJ`/__OX"C40#H8`#__TB-=>R_D,>!`.@B`/__2(7`=%5( +XMC5WL9@\?A```````BT@8]L$'=2Z`>`0`=2CWP0```@!U($B+4!!(!2@!``!( +XMA=)(#T30O\VB40!(B<8PP.@J__[_OY#'@0!(B=[HC03__TB%P'6XZ',X``"_ +XM"@```.C)_O[_Z"3Q__](@\006T%>7<-F9BX/'X0``````%5(B>5!5T%64U") +XM\TF)_D'V1A@'#X2:`0``OU&C40#HK/_^_X/[`@^%DP```$&+=B"_V*)1`##` +XMZ+/^_O]!#[=&&&:I,`1U>$&+?BB!_P```(!U,4F+=C!(A?9U+$$/OD8'A<`/ +XMA%4!``"#^`5W#+ZHHE$`_R3%Z*%1`+[`HE$`Z8L!``!)BW8PZ((@``!!#[Y. +XM!X/Y!7<,NJBB40#_),VXH5$`NL"B40`/'X``````O^ZB40!(B<8PP.@Q_O[_ +XMD$F#?F``="Q-C7Y@OR*C40`PP.@9_O[_3(G_OB`E00#HW%H``+\*````OHBY +XM@0#HK0+__TF+=DA(A?9T$TB!QB@!``"_+J-1`##`Z.']_O])C;8H`0``OT2C +XM40`PP.C._?[_08M&&(/@!X/X!'4'OTVC40#K%H/X`G4'OTJC40#K"H/X`74, +XMOTZC40`PP.B>_?[_08M^&.C5^___28U^<+X@)4$`Z%=:``"_"@```+Z(N8$` +XMZ"@"__])C;[H````OO`?00#H-UH``+_[J%$`Z#W^_O]!]D88!'0:38MV4.L/ +XM28M^$(G>Z%7^__]-BW8(387V=>Q(@\0(6T%>05]=P[]3HU$`Z`?^_O_I\O[_ +XM_[J[HE$`Z=C^__^ZY991`.G._O__NK"B40#IQ/[__[J<@U$`Z;K^__^^NZ)1 +XM`.L3ON6640#K#+ZPHE$`ZP6^G(-1`+\&HU$`,,#HU/S^_^F?_O__9F9F9F9F +XM+@\?A```````N)#'@0##9BX/'X0``````$B-MR@!```PP+_CB%$`Z9W\_O^0 +XMD)"0D)"0D)"0D)"054B)Y5-02(GS2(D]@*)``$B)'8&B0`!(B=_HP0'__TB) +XM!7JB0`!(C7@"Z"&H__](B05RHD``2(L58Z)``$B)QTB)WN@(_?[_2(L%4:)` +XM`$B-2`%(B0U&HD``2(L-1Z)``,8$`2](BP4\HD``2(L-+:)``,8$"`!(@\0( +XM6UW#9I!52(GE05=!5D%44TF)_TR+-0NB0`!(BS4,HD``28V_*`$``$R)\NBE +XM_O[_A<`/A7P```!+C;PW*`$``#'V,=+H[/;__TF)QDV%]G1C28._Z`````!U +XM$TF-O^@```!)C;;H````Z`=6``!)BUYP2(7;=#U-C7=P9BX/'X0``````$R+ +XM8Q!,B?=,B>;HT50``(7`=!-)@\1@3(GG3(G^Z'Y5``!!_T<@2(M;"$B%VW71 +XM6T%<05Y!7UW##Q^$``````!52(GE05=!5D%505132('LF````$B)O4C___^* +XM!4^A0`"$P`^%40$``.AB_O__2(G#2(E=@$B-?8B^"@```+I0L6$`Z'C^_O]( +XMC77,2(G?Z*S[_O](B<-(A=L/A,P```!,C7V(3(UET`\?A```````2,=%T``` +XM``"`>P0`#X61````]T,8`$`"``^%A````$R-LR@!``!,B?>^+P```.A]_/[_ +XM2(7`2(UP`4D/1/9(B;,8`0``3(G_3(GBZ*#^_O]!B<5,B?]$B>[H\OO^_TF) +XMQDV%]G4P2(NS&`$``+]0L6$`3(GBZ);Z_O])B<9)QP8`````28E>"$R)_T2) +XM[DR)\N@J_/[_28L&2(F#(`$``$F)'DB+?8!(C77,Z*#__O](B<-(A=L/A43_ +XM__](C7V(2(UUS.C'^O[_2(7`=#5,C76(2(U=S&8N#Q^$``````!(BPA(BT`( +XM2#G(=`=(B8@@`0``3(GW2(G>Z%+__O](A0/A+<7``!(.8D0`0``#X6J +XM%P``]@42M4``0'0E2(V1*`$``$B)R[\@NH$`OJ.C40`PP.B8^_[_2(G93(NA +XM(`$``$DYS`^$6Q<``$B-@2@!``!(B85P____#Q^``````$B+A7#___^`."^Y +XM``````^%40$``$B+!5R?0`!(A0`"028U._[H!````28/^`0^$ +XMC````$*`?##^+TF)SG7B28G.ZYT\+W4&28/'`NN3,=NQ+NL;9F9F9BX/'X0` +XM`````$P!\(@,`T&*3!\!2/_#A,D/A$K___^`^2\/A$'___])C00>2(LUWH<@ +XM`$B-5OY(.=!V(T@!]DB)-D__](B04XGD``08H,'^NJ +XM2(L%*YY``.NA28G6Z1G___](BST:GD``Z!VD__](B<%,B:5`____28V$)"@! +XM``!(B85X____08"\)"@!```O#X4\`0``28G,2(L%XYU``$B%P'432(L]5X<@ +XM`.AJH___2(D%RYU``,8`+T&^`0```$R+O7C____K(9!(BP6QG4``3`'PB`P# +XM20'?38UT'@%F9BX/'X0``````$&*#X3)#X0'`0``ZPH/'P!!BD\!2?_'@/DN +XM=`DQVX#Y+W5KZ^M!BD))B<[KG3PO=09)@\<"ZY,QV[$NZQMF +XM9F9F+@\?A```````3`'PB`P#08I,'P%(_\.$R0^$2O___X#Y+P^$0?___TF- +XM!!Y(BS5NAB``2(U6_D@YT'8C2`'V2(DU6X8@`$B+/=2<0`#H)Z/__TB)!SK*F8N#Q^$``````!(BP71FT``3`'PB`P#20'<38UT'@%F9BX/'X0` +XM`````$&*#"2$R0^$ZP```.L*9I!!BDPD`4G_Q(#Y+G0),=N`^2]U>NOJ08I$ +XM)`$\+G5$08!\)`(O=49)@\0#2(L%=IM``&9F9F9F+@\?A```````28U._[H! +XM````28/^`0^$C````$*`?##^+TF)SG7B28G.ZXT\+W4&28/$`NN#,=NQ+NL; +XM9F9F9BX/'X0``````$P!\(@,`T&*3!P!2/_#A,D/A#K___^`^2\/A#'___]) +XMC00>2(LU?H0@`$B-5OY(.=!V(T@!]DB)-6N$(`!(BSWDFD``Z#>A__](B078 +XMFD``08H,'.NJ2(L%RYI``.NA28G6Z0G___])C4;_2(L-MII``$&`?`[^+W0- +XMQ@0!+TR+I7#____K.4R+I7#___])B<;K+69F9F8N#Q^$``````!(BP6!FD`` +XM3`'PB`P#20'<38UT'@%F9BX/'X0``````$&*#"2$R0^$ZP```.L*9I!!BDPD +XM`4G_Q(#Y+G0),=N`^2]U>NOJ08I$)`$\+G5$08!\)`(O=49)@\0#2(L%)II` +XM`&9F9F9F+@\?A```````28U._[H!````28/^`0^$C````$*`?##^+TF)SG7B +XM28G.ZXT\+W4&28/$`NN#,=NQ+NL;9F9F9BX/'X0``````$P!\(@,`T&*3!P! +XM2/_#A,D/A#K___^`^2\/A#'___])C00>2(LU+H,@`$B-5OY(.=!V(T@!]DB) +XM-1N#(`!(BSV4F4``Z.>?__](B06(F4``08H,'.NJ2(L%>YE``.NA28G6Z0G_ +XM__](BSUJF4``Z&V?__])B<9%A/]U-DR)]TB+78!(B=[H=O?^_T&)QTR)]^@[ +XM^?[_187_#X0*`P``2(E=@$4PY$R++0290`#I5@,``+H!````0;&80`#&`"]!O`$```#K+F9F9F9F+@\?A```````2(L%P9A``$P! +XMX(@,`TD!W4V-9!P!9F8N#Q^$``````!!BDT`A,D/A-P```#K"6:008I-`4G_ +XMQ8#Y+G0),=N`^2]U:^OK08I%`3PN=3=!@'T"+W4Z28/%`TB+!6F80`"028U, +XM)/^Z`0```$F#_`$/A(P```!"@'P@_B])B>__]( +XMB078ET``08I,'0#KJ4B+!/___^LW3(NM>/___TF)Q.LK9F8N#Q^$``````!(BP6! +XMET``3`'@B`P#20'=38UD'`%F9BX/'X0``````$&*30"$R0^$W````.L)9I!! +XMBDT!2?_%@/DN=`DQVX#Y+W5KZ^M!BD4!/"YU-T&`?0(O=3I)@\4#2(L%*9=` +XM`)!)C4PD_[H!````28/\`0^$C````$*`?"#^+TF)S'7A28G,ZYP\+W4&28/% +XM`NN2,=NQ+NL:9F9F+@\?A```````3`'@B`P#08I,'0%(_\.$R0^$2O___X#Y +XM+P^$0?___TF-!!Q(BS4^@"``2(U6_D@YT'8D2`'V2(DU*X`@`$B+/:260`#H +XM]YS__TB)!9B60`!!BDP=`.NI2(L%BI9``.N@28G4Z1C___](BSUYED``Z'R< +XM__])B<5,B?=,B>[HCO3^_XG#@[UD____`'0(3(GWZ$OV_O]!M`&%VW0I3(GO +XMZ#SV_O]!M`%,BRT2ED``183_=63IOP$``$4PY$&W`4B)78!)B=U-A>T/A4,- +XM``!,BRWKE4``08#_`70\183D#X63`0``2(N]:/___TB+78!(B5V`2(F]:/__ +XM_TB)WN@.]/[_QH5D____`(7`QH5C____`.G/`@``2(L%RI5``$B%P'432(L] +XM/G\@`.A1F___2(D%LI5``,8`+T&^`0```$V)[^LL9F9F+@\?A```````2(L% +XMD95``$P!\(@,`TD!WTV-=!X!9F8N#Q^$``````!!B@^$R0^$W````.L*#Q\` +XM08I/`4G_QX#Y+G0),=N`^2]U:^OK08I'`3PN=39!@'\"+W4Y28/'`TB+!3F5 +XM0`"028U._[H!````28/^`0^$C````$*`?##^+TF)SG7B28G.ZYT\+W4&28/' +XM`NN3,=NQ+NL;9F9F9BX/'X0``````$P!\(@,`T&*3!\!2/_#A,D/A$K___^` +XM^2\/A$'___])C00>2(LU3GX@`$B-5OY(.=!V(T@!]DB)-3M^(`!(BSVTE$`` +XMZ`>;__](B06HE$``08H,'^NJ2(L%FY1``.NA28G6Z1G___])C4;_2(L-AI1` +XM`$&`?`[^+W0CQ@0!+TR+O7#____K244Q_\:%9/___P!,B[5H____Z70!``!, +XMB[UP____28G&ZRF30`"028U._[H!````28/^`0^$C````$*` +XM?##^+TF)SG7B28G.ZYT\+W4&28/'`NN3,=NQ+NL;9F9F9BX/'X0``````$P! +XM\(@,`T&*3!\!2/_#A,D/A$K___^`^2\/A$'___])C00>2(LU_GP@`$B-5OY( +XM.=!V(T@!]DB)->M\(`!(BSUDDT``Z+>9__](B058DT``08H,'^NJ2(L%2Y-` +XM`.NA28G6Z1G___](BSTZDT``Z#V9__])B<9%A.1U.4R)]TB+78!(B=[H1O'^ +XM_T&)QTR)]^@+\_[_QH5C____`,:%9/___P%%A?])B=T/A=<"``#IR0(``$&_ +XM`0```,:%9/___P%(BP7@DD``2(7`=1-(BSU4?"``Z&>8__](B07(DD``Q@`O +XM0;P!````ZR4/'T0``$B+!;&20`!,`>"(#`-)`=U-C60<`69F+@\?A``````` +XM08I-`(3)#X3<````ZPEFD$&*30%)_\6`^2YT"3';@/DO=6OKZT&*10$\+G4W +XM08!]`B]U.DF#Q0-(BP59DD``D$F-3"3_N@$```!)@_P!#X2,````0H!\(/XO +XM28G,=>%)B"(#`-! +XMBDP=`4C_PX3)#X1*____@/DO#X1!____28T$'$B+-6Y[(`!(C5;^2#G0=B1( +XM`?9(B35;>R``2(L]U)%``.@GF/__2(D%R)%``$&*3!T`ZZE(BP6ZD4``ZZ!) +XMB=3I&/___TF-1"3_2(L-I)%``$&`?`S^+W0-Q@0!+TR+K7C____K-TR+K7C_ +XM__])B<3K*V9F+@\?A```````2(L%<9%``$P!X(@,`TD!W4V-9!P!9F8N#Q^$ +XM``````!!BDT`A,D/A-P```#K"6:008I-`4G_Q8#Y+G0),=N`^2]U:^OK08I% +XM`3PN=3=!@'T"+W4Z28/%`TB+!1F10`"028U,)/^Z`0```$F#_`$/A(P```!" +XM@'P@_B])B6__](B06(D$``08I,'0#KJ4B+!7J0 +XM0`#KH$F)U.D8____2(L]:9!``.ALEO__28G%3(GW3(GNZ'[N_O^)PT6%_W0( +XM3(GWZ#_P_O_&A6/___\!A=MT$4R)[^@L\/[_QH5C____`>L)387M#X5+!P`` +XM2(N]2/___^@NQ?__ZQ=F9F8N#Q^$``````!(BX50____2(/`"$B+`$4Q[4B% +XMP`^$%P<``$B+>!!(B850____Z#8B__])B<=!@#\O#X51`0``13'V@+UD____ +XM`4R+I6C___^X``````^%V0,``$B+!:Z/0`!(A"(#`-)`=U-C60<`69F+@\? +XMA```````08I-`(3)#X0N`@``ZPEFD$&*30%)_\6`^2YT"3';@/DO=6OKZT&* +XM10$\+G4W08!]`B]U.DF#Q0-(BP4ICT``D$F-3"3_N@$```!)@_P!#X2,```` +XM0H!\(/XO28G,=>%)B"(#`-!BDP=`4C_PX3)#X1*____@/DO#X1!____28T$'$B+-3YX(`!(C5;^ +XM2#G0=B1(`?9(B34K>"``2(L]I(Y``.CWE/__2(D%F(Y``$&*3!T`ZZE(BP6* +XMCD``ZZ!)B=3I&/___\>%7/___P````!,BR5/CD``@+UD____`4B+G6C___]! +XMO@````!,BVV`=1M,B?],B>9(BY5P____Z&L&``!(B<-!O@$```"`O6/___\! +XM3(EM@'4?3(G_3(GF2(N5>/___^A#!@``28G%QX5<____`0```$B)WTR)[N@K +XM[/[_08G$187V=`A(B=_HZ^W^_T6%Y'4+387M#X4.!0``ZQ&#O5S___\`=`A, +XMB>_HRNW^_\>%7/___P````!,BR69C4``@+UD____`4B+G6C___]!O@````!U +XM&TR)_TR)YDB+E7#____HP04``$B)PT&^`0```("]8____P%,BVV`=1],B?], +XMB>9(BY5X____Z)D%``!)B<7'A5S___\!````2(G?3(GNZ('K_O]!B<=%A?9T +XM"$B)W^A![?[_187_#X0G!```@[U<____``^%+00``.DF_?__28U$)/](BPTB +XMC4``08!\#/XO=`W&!`$O3(NM2__](B04(C$``08I,'0#KJ4B+!?J+0`#KH$F)U.D8____2(L]Z8M` +XM`.CLD?__28G$N`$```")A5S___^`O6/___\!3(MM@`^%B@(``$B+!;Z+0`!( +XMAB(#`-)`=]-C6P=`69F+@\?A```````08H/A,D/A-T```#K"@\?`$&*3P%) +XM_\>`^2YT"3';@/DO=6OKZT&*1P$\+G4V08!_`B]U.4F#QP-(BP4YBT``D$F- +XM3?^Z`0```$F#_0$/A(T```!"@'PH_B])BN=/"]U!DF#QP+KDS'; +XML2[K&V9F9F8N#Q^$``````!,`>B(#`-!BDP?`4C_PX3)#X1*____@/DO#X1! +XM____28U$'0!(BS5-="``2(U6_D@YT'8C2`'V2(DU.G0@`$B+/;.*0`#H!I'_ +XM_TB)!:>*0`!!B@P?ZZE(BP6:BD``ZZ!)B=7I&/___TF-1?](BPV%BD``08!\ +XM#?XO=`W&!`$O3(N]>/___^LX3(N]>/___TF)Q>LL9F9F+@\?A```````2(L% +XM48I``$P!Z(@,`TD!WTV-;!T!9F8N#Q^$``````!!B@^$R0^$W0```.L*#Q\` +XM08I/`4G_QX#Y+G0),=N`^2]U:^OK08I'`3PN=39!@'\"+W4Y28/'`TB+!?F) +XM0`"028U-_[H!````28/]`0^$C0```$*`?"C^+TF)S77B28G-ZYT\+W4&28/' +XM`NN3,=NQ+NL;9F9F9BX/'X0``````$P!Z(@,`T&*3!\!2/_#A,D/A$K___^` +XM^2\/A$'___])C40=`$B+-0US(`!(C5;^2#G0=B-(`?9(B37ZD8____2(L]28E``.A, +XMC___28G%0;X!````3(GG3(GNZ%CG_O^)PX.]7/___P!T"$R)Y^@5Z?[_A=MU +XM"DV%[74]Z0?Y__]%A?8/A/[X__],B>_H]NC^_^GQ^/__2(G'2(F]:/___TB) +XMWN@/Y_[_ABU +XMZ/[_387M=1KV!0:>0`!`=#N_(0```+X@NH$`Z"CG_O_K*DB+E4C___](BX(0 +XM`0``2(NU0/___TB+CA`!``!(B8H0`0``2(F&$`$``/8%PIU``$!T&+\@NH$` +XMON.(40!(BY5X____,,#H2^3^_TB+C4#___](BXD@`0``2(N%2/___T@YP4F) +XMS`^%NNC___8%@)U``$!T#[\*````OB"Z@0#HHN;^_TB!Q)@```!;05Q!74%> +XM05]=PTB)^69F9F8N#Q^$``````"X`0```$@Y\70.2(N)$`$``#'`2#GY=>C# +XM#Q^``````%5(B>5!5T%6055!5%-028G628GW28G]2(L%NH=``$B%P'432(L] +XM+G$@`.A!C?__2(D%HH=``,8`+T&\`0```.LO9F9F9F9F+@\?A```````2(L% +XM@8=``$P!X(@,`TD!W4V-9!P!9F8N#Q^$``````!!BDT`A,D/A-P```#K"6:0 +XM08I-`4G_Q8#Y+G0),=N`^2]U:^OK08I%`3PN=3=!@'T"+W4Z28/%`TB+!2F' +XM0`"028U,)/^Z`0```$F#_`$/A(P```!"@'P@_B])B,__](B068AD``08I,'0#KJ4B+!8J&0`#KH$F)U.D8____28U$)/](BPUT +XMAD``08!\#/XO=`;&!`$OZRY)B<3K*68/'X0``````$B+!5&&0`!,`>"(#`-) +XM`=]-C60<`69F+@\?A```````08H/A,D/A,P```#K"@\?`$&*3P%)_\>`^2YT +XM"3';@/DO=5OKZT&*1P$\+G4S08!_`B]U-DF#QP-(BP7YA4``D$F-3"3_N@$` +XM``!)@_P!=']"@'P@_B])B+__](B05XA4``08H,'^NJ2(L%:X5``.NA +XM28G4Z2G___])C40D_TB+#56%0`!!@'P,_B]T!L8$`2_K+TF)Q.LJ9BX/'X0` +XM`````$B+!3&%0`!,`>"(#`-)`=Y-C60<`69F+@\?A```````08H.A,D/A,P` +XM``#K"@\?`$&*3@%)_\:`^2YT"3';@/DO=5OKZT&*1@$\+G4S08!^`B]U-DF# +XMQ@-(BP79A$``D$F-3"3_N@$```!)@_P!=']"@'P@_B])BMM(`!(BSUDA$``Z+>*__](B058 +XMA$``08H,'NNJ2(L%2X1``.NA28G4Z2G___](BSTZA$``2(/$"%M!7$%=05Y! +XM7UWI+XK__Y"0D)"0D)"0D)"0D)"0D#'VZ0G>_O]F#Q^$``````!52(GE2(/L +XM$(E]_$B-??SH;.'^_[\`R($`OH````"ZM*-1`$B)P>B%XO[_Q@5=A$```+@` +XMR($`2(/$$%W#D)"0B3U.A$``PV8/'X0``````$C'1S``````2,='*`````!( +XMQT<@`````$C'1Q@`````2,='$`````!(QT<(`````$C'!P````###Q^$```` +XM``!52(GE05932(/L$(G328G^2(EUZ$B-=>A(C57DZ%\```"#^/]U,(M5Y$B+ +XM=>A,B??HFP,```M8&(E8&(/C2H/[0'4O2(/`'+\!````OLZE40!(B<+K%4AC +XMP$B+%,4PI5$`OP$```"^J*51`##`Z/X\__](@\006T%>7<,/'T0``%5(B>5! +XM5T%64U!)B==)B?9(B?OHZ.#^_T&)!XG`2&G(P=XQ-4C!Z21KR4V)PBG*28L. +XM2"G9@_I&?SZ#^C-_?H/Z&P^/N````(/"^X/Z#@^'Y@(``/\DU;"D40"`.RH/ +XMA=8"``"`>P%$#X7,`@``N`H```#ICP(``(/Z1P^%N0(``#V-C`X`#X6N`@`` +XM2(/Y"`^%I`(``$B)W[Z4J%$`N@@```#HZ-[^_XG!N`(```"0A_O^)P;@#````Z["#PN2#^@X/ARX"``#_)-4XI%$` +XM/;#@`P`/A1P"``!(@_D'#X42`@``2(G?OKVH40"Z!P```.A6WO[_B<$QP.EM +XM____@#LE#X7N`0``@'L!1`^%Y`$``+@.````Z:P%& +XM#X7'`0``N`T```#IB@$``(`[/`^%M`$``+@&````ZW^__^`.SX/ +XMA6X!``"X!0```.F%````@#L_#X5;`0``N`0```#K=8`[0`^%2P$``#'`ZVB` +XM.R$/A3X!``"X`@```.M8@#LE#X4N`0``N`,```#K2(`[(0^%'@$``(![`40/ +XMA10!``"X#````.G7````@#LA#X4!`0``@'L!1@^%]P```+@+````Z;H```"` +XM.RH/A>0```"X`0```$B#^0$/A=4```#IU0```(`[*@^%QP```(![`48/A;T` +XM``"X"0```.F`````/3N_`P`/A:@```!(@_D'#X6>````2(G?OHRH40"Z!P`` +XM`.CBW/[_B<&X!0```.GV_?__@#M`=7N`>P%$=76X"````.L[/5SF`P!U9TB# +XM^0=U84B)W[ZUJ%$`N@<```#HI=S^_XG!N`$```#IN?W__X`[0'4^@'L!1G4X +XMN`<```!(@_D"=#+K*ST%AP,`=21(@_D'=1Y(B=^^K:A1`+H'````Z&+<_O^) +XMP;@$````Z7;]__^X_____TB#Q`A;05Y!7UW#9@\?1```54B)Y4%7059!54%4 +XM4U")T$F)]$F)_[^(R($`3(G^3(GBB<'H^-G^_T&)QK^(R($`1(GVZ+C:_O]) +XMB<5-A>UU,$R)9=!(C570OX"Q80!,B?[H6]G^_TF)Q4''11@"````OXC(@0!$ +XMB?9,B>KH\-K^_T&+71CVPQ`/A9````"#/;!_0```=`R)V(/@!H/X!'4'ZWOV +XMPP)T=DF-?1SH4-G^_TF)QDV%]G0W]L,"=#=,B??H&][^_TF)QTF-=P%,B>_H +XM3/3^_TR)[TR)_DR)\NB>\_[_08M=&(/C_4&)71CK)X/+$.LE28M%`$F)10A, +XMB??HW-W^_TR)[TB)QDR)\NAN\_[_08M=&(/+&$&)71A,B>A(@\0(6T%<05U! +XM7D%?7<.054B)Y4%64TB#[!!(B?M(B77H2(UUZ$B-5>3HZ,C8_O]!B<:_B,B!`$2)]NB(V?[_2(G#2(7;=%6+0QB# +XM/;I^0```=`2H"'5%J`1U0;^(R($`1(GVZ`_<_O_V0Q@"=0A(BSOH`=[^_TB) +XMW^CYW?[_ZQQ(8\!(BQ3%,*51`+\!````OO.E40`PP.C;-___2(/$$%M!7EW# +XM9I!%,<#K"V9F+@\?A```````54B)Y4%7059!5%-(@^P018G'08G,28G62(G[ +XM2(EUV$B-==A(C574Z*3Z__^#^/\/A:$```"+5=1(BW782(G?Z-S]__](B532(/L&$B)^TB)=?!(C77P2(U5[.@C^?__@_C_ +XM=2^+5>Q(BW7P2(G?Z%_\__](B<.+0QAFJ<`!=&.H0'0P2(U3'+\!````OGRG +XM40#K/TACP$B+%,4PI5$`OP$```"^&:91`##`Z,,U__\QP.M!J`)T1$B-4QR_ +XM`0```+ZFIU$`9F9F9BX/'X0``````##`Z)DU__]F#Q^$```````QP/9#&`)U +XM"DB+0PC&``!(BP-(@\086UW#J(!TXTB+0PC&``!(BP.`.`!UU$B-4QR_`0`` +XM`+[+IU$`Z[0/'T``54B)Y5-(@^P82(G[2(EU\$B-=?!(C57LZ$/X__^#^/]U +XM/(M5[$B+=?!(B=_H?_O__TB)PXM+&/;!0'082(U3'+\!````OGRG40`PP.C_ +XM-/__BTL8N`$```#VP0)T`C'`2(/$&%M=PV8/'X0``````%5(B>5!5T%60513 +XM2(/L,$F)]TF)_DF+'DB)7W4@0;B074$`ZR],B67(2(/#`DB)7=#'1=@`````Z98```"_`0```+[_ +XMIE$`,,#H<33__T&X8%U!`$B#PP)(C77(2(G?3(GZ,5!5E-(@^P028G^2(U%[$B)]TB)UHG*3(G!28G`Z$L```!( +XMB<,QP+F`R($`2#G+="Y(B=_HM-C^_TR)]TB)QDB)VNA&[O[_N`$```"#?>P` +XM=`U(B=_H8]G^_[@!````2(/$$%M!7EW##Q]$``!52(GE05=!5D%505132(/L +XM:$R)1:A(B4V0B56D28GW28G\0<<``````$R)9=!-C70D`4$/OD0D`8/X*'0% +XM@_A[=1A!N&!=00"#^"AT/(/X>W4@0;B074$`ZR],B76X28U,)`)(B4W`QT7( +XM`````#';ZT>_`0```+[_IE$`,,#HS3+__T&X8%U!`$F-?"0"2(UUN#';3(GZ +XM,@?1`'P +XM@^#^1(GQ*<&#^0$/A6$!``#H`0``00]/QTC_PSG#?,U-C7PD'+\@NH$`OAZ/40!,B?HP +XMP.C$TO[_OV&G40!,B?XPP.BU+O__08M$)!A,BWV(@\@!08E$)!A(8P65=T`` +XM2#U=`0``?PA,B23%\,B!`/_`B05]=T``3(GO3(G^BU6DZ$],B?J+3:1,BT6HZ#,-``!)B<5-A>V+3:0/A8<` +XM``"X@,B!`(7)0;W(R($`3`]%Z$&#_O]T<$V%_W0Q08/^!WP/08U&^<'H'T6- +XM=`;Y0='^08/^!G4Q28M7.$F+=T"_1:91`##`Z,DM___K.DB+1:C'``$```!( +XMBW702(G?Z#&E__])B<7K'TF+3SA)BU=`26/&2(LTQ3"E40"_CZ91`##`Z+TL +XM__](C7VXZ*0H``!(BT702"G82(M-D$B)`4R)Z$B#Q&A;05Q!74%>05]=PZB` +XM#X3<_?__28M$)`C&``!)BP0D@#@`#X7'_?__28U4)!R_`0```+[+IU$`Z:/] +XM__\/'P!52(GE05=!5D%505132(/L.(G3B5VD2(EUJ$F)_DB-?<"^``$``.AU +XMZO[_Q@77=4```(7;#X0_`0``3(U]P.L@2(U(`4B)3____TR)YTB+=:B+5:1(C4VX3(U%M.@$^___ +XM28G%N(#(@0!).<5T"KC(R($`23G%=4R#/>:)0```=3=(BUVXB@4#=4``A,!U +XM%[\!````OL6F40!(B=I,B>$PP.@/+O__20'=$```4V)YNDM____3`-E +XMN$V)YNDA____2(M=N$R)[^@5T_[_3(G_2(G&3(GJZ*?H_O])`=R#?;0`38GF +XM#X3W_O__3(GOZ+_3_O]-B>;IY_[__TR-;9F9F9F8N#Q^$``````!,B?/K#F9F+@\?A``` +XM````2/_#B@.$P'0$/"1U\TB)WDPI]DR)[TR)\N@BZ/[_@#L`#X30````@'L! +XM)'4?2(M%R$B+3=!(*<%(@_D"?9),B>_HFN?^_TB+1X@,B!`$DYQW0%33GG=4F#/:6(0```=31(BT7(2(M- +XMT$@IP4B#^0%_#$R)[^A*Y_[_2(M%R(H+2/_#2(U0`4B)5#X0)____3(G_Z('2_O])B=[I^?[__TB+1;^_TB+!?IR0`#&``!(BSWH +XM_B,B!`$2)_NCIS/[_2(G#2(7;=2],B6W02(U5T+^`L6$` +XM3(GVZ(S+_O](B!(@\086T%< +XM05U!7D%?7<-FD$B+1R!(@\`5!5T%6055!5%-(@^Q828G/28GV2(E]J$B+ +XM6B!(C4,<2(E%D/9#&`)T.4R)_^B[S_[_38GT28G&28UV`4B)W^CIY?[_2(G? +XM3(GV38GF3(GZ3(E]H.@TY?[_@&,8_4B)79CK2DB+`TB)0PA,B?_H>\_^_TB) +XMWTB)79A(B<9,B?I,B7V@Z`7E_O_K(P\?`$TIYDB+?:A,B?9,B>+H[N3^_TR+ +XM==!F+@\?A```````38GTZPYF9BX/'X0``````$G_Q$&*!"2$P'0$/"1U\4R) +XMYDPI]DB+?:A,B?+HK^3^_T&`/"0`#X1;`0``38UT)`)%#[YL)`%!@_U[=`9! +XM@/TH=1BX8%U!`$&#_2AT6T&#_7MU/[B074$`ZTY!@/TD=!Q(BT601#HH=1-( +XMBT68@'@=`'4)2(M=H.GJ````2(M]J+X"````3(GBZ$+D_O_I7?___[\!```` +XMOO^F40`PP.A<*?__N&!=00!,B??_T$R)]DF)QDR)==!!BAZ`^R0/A`S___]- +XMB?=)*?=(BWV03(GZZ,K+_O^%P`^%\O[__TB+19A"@'PX'``/A>+^__^`^SI( +XMBUV@=6U(BT682HU$.!S'105]=Z;_B_O]F9F9F9F8N#Q^$``````!52(GE05=!5E-(@^P8 +XMOXC(@0"^"@```+J`L6$`Z`_+_O](QT78`````$B-==B_2IQ1`.BYR_[_3(M] +XMV+^(R($`ODJ<40!,B?J)P>@1R/[_08G&OXC(@0!$B?;HT"_@+%A`+Y*G%$`Z'+'_O](B05]=PV8N#Q^$ +XM``````!52(GE05932(/L$+_0J%$`Z&O'_O](C77LOXC(@0#H+7<,/'P!52(GE05=!5D%505132(/L*$F)_DB-?;B^``$``.A^ +XMX?[_2(UUU+^(R($`Z)#&_O](B<-(A=L/A"=(B<9,B>KHC.#^_TB+1?HP-_^_TB+1*#X#Y?'\0@/DZ=_$/MLE(#Z/(<^CK!8#Y?77A2(GXPV9F9F8N#Q^$```` +XM``!52(GE05=!5E-028GV2(G[]D,8`G0T3(GWZ#+)_O])B<=)C705]=PTB+0PA(BTL02"G!2(/Y +XM`7\,2(G?Z"W>_O](BT,(2(U(`4B)2PC&`"!,B??HULC^_TB)WTB)QDR)\DB# +XMQ`A;05Y!7UWI7M[^_Y"0D)"0D)"0D)"0D)"02,<%S7=``+"Q80!(QP7*=T`` +XMV+%A`$C'!>=W0```LF$`2,<%7'=``"BR80!(QP7!=T``4+)A`$C'!/___XF-9/___TB)E5C___](B;5P____ +XM28G_28L!N2D```"#?1`H2(E%H+I]````#T31B56,0;X!````3(UEP.L*13'V +XM2(M%H$V)[P^^"#M-C`^$@@(``(3)#X1Z`@``2/_`2(E%H/8%P7U```)T%@^^ +XM,+_GJ%$`3(GZ,,#H,,+^_TB+1:!(#[X`2(L$Q>#3@0!(A^)WDB-5'_59B)PTB+1;!$B#!-B?Y,B??H0)+__TB)1:A(AT```@^$Z?W__[\/J5$`3(GN +XM,,#H2L#^_^G5_?__2(MUH+_]J%$`,,#HA1W__TB+1:!(_\!F9F9F9BX/'X0` +XM`````$B)1:`/O@A(_\`[38QT!(3)=>U(_\A-A?]T&$B+C7C___^#.0!T#$R) +XM_^@1QO[_2(M%H$B+C7C____'`0````"*"$&_@,B!`(3)=`E(_\!(B46@ZQ"_ +XM'ZE1`##`Z`\=__](BT6@2(N-4/___TB)`4R)^$B!Q(@```!;05Q!74%>05]= +XMPV9F9BX/'X0``````%5(B>5!5T%6055!5%-(@^PX2(G[2(U]P#'VZ`';_O]( +XMB5VP3(UUL$R)]^B1D/__2(E%J$B%P'1+,=M,C7VH3(UEP&9F9F9F+@\?A``` +XM````2(M%L$2**,8``$R)_XG>3(GB,1T*$B+ +XM0PA(BTL02"G!2(/Y`7\,2(G?Z#79_O](BT,(2(U(`4B)2PC&`"!)BQ9)*==( +XMB=],B?[H==G^_^M!187D=!1(B=^^`@```+H_J5$`Z%S9_O_K*$B+0PA(BTL0 +XM2"G!2(/Y`7\,2(G?Z.'8_O](BT,(2(U(`4B)2PC&`"ZX`0```%M!7$%>05]= +XMPP\?0`!52(GE05=!5E-(@^PX2(G[2(U]T#'VZ*79_O](B5W`3(UUP$R)]^@U +XMC___2(E%N$B%P`^$DP```+$!3(U]T&:02(M%P(H8Q@``]L$!=2A(BT782(M- +XMX$@IP4B#^0%_#$R)_^A9V/[_2(M%V$B-2`%(B4W8Q@`@2(M]N$B+=<"Z+P`` +XM`.@HE/__2(MUP$B%P'4,2(M5N$@IUDR)_^L,2/_`2"G&3(G_2(G"Z'+8_O]( +XMBT7`B!A,B??HI([__TB)1;@PR4B%P`^%=?___TB+1=C&``!(BT702(/$.%M! +XM7D%?7<-F9F9F9F8N#Q^$``````!52(GE05932(G328G^A?9T*$B+0PA(BTL0 +XM2"G!2(/Y`7\,2(G?Z*;7_O](BT,(2(U(`4B)2PC&`"!)BSY)BW8(NB\```#H +XM=I/__TF+=@A(A5!5T%6055!5%-(@^Q(B],B6V0 +XMZQ$/'X``````2(U1`4B)5__1:3K#4V)[_]- +XMI'@NZP--B>](BTW(2(M5T$@IRDB#^@$/CPO___],B??HH]7^_T&*!TB+3 +XMZ'F0__])B48(28D&22L?28E>$$B+1.__](A534$B)^TB+.^C_O_[_2(M[&.CVO_[_2(G?2(/$ +XM"%M=Z>B__O\/'X0``````$B+%S'`@'H!:'4<#[YR`CG.=`@QP$"`_CIU#$B# +XMP@)(B1>XX-N!`,,/'X0``````%5(B>5!5E-(@^P02(G[2(UUZ.B)U?[_28G& +XM2(M]Z$B%_W0*2(G>,,#HLQ;__TR)\$B#Q!!;05Y=PP\?@`````!(QP55XX-N!`,-F#Q]$``!52(GE +XM05932(G[Z&&^_O])B<9)C7X!Z,5D__]-A?9T,TR)\4B)PF8N#Q^$``````!( +XM#[XS2(7V>`Q(BSW044``0(IT=P)`B#)(_\)(_\-(_\EUW4+&!#``6T%>7<,/ +XM'P!52(GE05932(G[Z`&^_O])B<9)C7X!Z&5D__]-A?9T,TR)\4B)PF8N#Q^$ +XM``````!(#[XS2(7V>`Q(BSV(3T``0(IT=P)`B#)(_\)(_\-(_\EUW4+&!#`` +XM6T%>7<,/'P!52(GE05932(G328G^A?9T*$B+0PA(BTL02"G!2(/Y`7\,2(G? +XMZ,;2_O](BT,(2(U(`4B)2PC&`"!)BSY)BW8(NBX```#HEH[__TB%P'0.28L6 +XM2"G02(G?2(G&ZPU)BQ9)BW8(2"G62(G?Z.'2_O^X`0```%M!7EW##Q^````` +XM`%5(B>5!5T%605132(G308GT28G^28L^28MV"+HN````Z#N.__])B<=-A?]T +XM2$6%Y'0H2(M#"$B+2Q!(*<%(@_D!?PQ(B=_H)=+^_TB+0PA(C4@!2(E+",8` +XM($G_QTF+=@A,*?Y(B=],B?KH8=+^_T&\`0```$2)X%M!7$%>05]=PV9F9F9F +XM9BX/'X0``````%5(B>5!5T%64U!!B5!5T%6055!5%-( +XM@>R8````2(G328G^2(MS"$B-O6#___^Z`0```.@QN?[_08G'187_=%M,C;5@ +XM____1(G_3(GV,=(QR>A#NO[_3&/@3(GGZ&AA__](B<-$B?],B?9(B=I,B>'H +XM)+K^_[^SBE$`OD*I40!(B=HPP.C0$O__2(G?Z)B[_O^[@,B!`.E>!```BX5H +XM_____\")18!(BTL82(E-D(M+*(E-F(7`?A.#^`M\&L=%@`H```"X"@```.L, +XMQT6``0```+@!````2&/X2,'G!.CF8/__2(E%B$B-?;@Q]NBGT/[_2(U]J$R) +XM=:CH.H;__TB)1:!(A<`/A,T#``!%,>WK6`\?A```````187D2(N=6/___P^% +XMOP```$B+1T/A3C___](BYU8____2(F=6/___TB-?;A(B=KH_L[^_T&\`0```$R+?9#I +XM?P```$2)]T2)K53___],C:U@____3(GN,=(QR>ARN/[_3&/X3(G_Z)=?__]( +XMB<-$B?=,B>Y$BZU4____2(G:3(GYZ$RX_O^_LXI1`+Z*J5$`2(G:,,#H^!#_ +XM_TB)W^C`N?[_2(N=6/___^GC`0``#Q]``$G_QV9F9F8N#Q^$``````!!B@>$ +XMP`^$JP$``#PF=3'&1=4FQD76`#'`#Q^``````#M%@'YNOUBI40!F#Q]$``!( +XMC775,,#HE1#__TG_Q^O`/%P/A>8```!!BD1U*4B+1`$2(M-B$R+-`%(BUP!"$F#_O]U$$B#^_]U"K]LJ5$` +XMZ7/___]$*?.%VP^.*/___T6%[70N187D=2E(BT7`2(M-R$@IP4B#^0%_#4B- +XM?;CH),W^_TB+14$/MDUT+D6%Y'4I2(M%P$B+3P/E<%$#[;I2(7`#X60 +XM_/__2(M%P,8``$B+7;A(C;U@____Z)FV_O](BWV(Z#"W_O](B=A(@<28```` +XM6T%<05U!7D%?7<-F9BX/'X0``````%5(B>5!5T%6055!5%-(@^PH18G'B4W$ +XM08G428GU28G^3(EUR+\P````Z()<__](B`/A!`!``!$.?@/A`_H9\G^_XH+2(M%R$B-4`%(B57(B`CK94V%]G06/"9U +XM$DF+5@A)BW803(GOZ)S)_O_K2DB+3](B=Y(BU6@BTVL3(U%L.C)VO__2(M%L$B- +XM7!C_#[Y#`4C_PX7`=`Y$.>!T"40Y^`^%!____TB+1%(BU60=`5$.?EU"$C_PTB)&NL82(D:2(M-F$C'`0`` +XM``!(B5!5T%6055!5%-( +XM@^PH2(G+28G608GU2(E]R$R+/TB+1PA,*?A(B4701(MC*$2)X(/@!H/X!@^$ +XM*P$``$'VQ`@/A(X```!(BW,(2(M3$$B)5,```!(BW,@2(7V#X14`P``187M="Q)BT8( +XM28M.$$@IP4B#^0%_#$R)]^AVQ_[_28M&"$B-2`%)B4X(Q@`@2(MS($B+4QA, +XMB??HM\?^_T2+8RBX`0```.D,`P``0?;$$`^$[@```$B+4Q!(BT7028G$22G4 +XM2"G02(E%P'AR30'\2(MS"$R)Y^A)K_[_A9F9F9F8N#Q^$``````"#R@2)4RA(B4W09@\? +XM1```A<`/A<$```!(BW,(3(G_Z/RM_O])B<2X`0```$V%Y'3?187M=$`QP$@K +XM0R!,B>%,*?E(.<%T,DF+1@A)BTX02"G!2(/Y`7\,3(GWZ-#%_O])BT8(2(U( +XM`4F)3@C&`"!(BT7(3(LX13'M3(GF3"G^3(GW3(GZZ`;&_O](BU,82(MS($R) +XM]^CVQ?[_3(G@2(M5R$@K`DB+2Q!-C3P,3(DZ2`'(2(MUT$B)\4@IP8M3*$@Y +XMQG0+,<#VP@$/A3'___^X`0```.DG____2(-]T`!T0T6%[70O28M&"$F+3A!( +XM*<%(@_D!?PQ,B??H,L7^_TF+1@A(C4@!28E.",8`($B+1T/E<$(P0^VP>F(_O__ +XM2(MS($B+1=!(C00&2#M%P'0]N`$```!%A>UT-DF+1@A)BTX02"G!2(/Y`7\, +XM3(GWZ+/$_O])BT8(2(U(`4F)3@C&`"!(BW,@N`$```#K`T2)Z$B+4QA,B?=! +XMB5!5E-)B?Y)BSY(B?KK'F9F9F9F+@\?A```````2(G"9F9F9BX/ +XM'X0``````$B)T$B-6`$/OE`!@_HZ=#NJ&I40#H +XM^7[__TF)'EM!7EW#D%5(B>5!5T%6055!5%-028G,2(G308GW28G^38LN28M& +XM"$B)1=!,B>B_>O__A05]=PP\?0`#IBZ[^_V9F +XM+@\?A```````54B)Y4%7059!54%44U!)B](BW703(GB2(G!Z`]Z__^%P'1%187_="A(BT,(2(M+ +XM$$@IP4B#^0%_#$B)W^B-PO[_2(M#"$B-2`%(B4L(Q@`@28L628MV"$@IUDB) +XMW^C,PO[_0;\!````1(GX2(/$"%M!7$%=05Y!7UW#D)"0D%5(B>5!5T%6055! +XM5%-(@^Q(38G%B4VD28G728GT28G^0?_52(G#@#LD#X6@````3(EMF$R)?;!, +XMB66H3(UEN$R)Y[X``0``Z`3#_O](B=Y,*?9,B>=,B?+H4\+^_X`[)'5*3(U] +XMN$2+;:1,BW689I!,B?](B=Y(BU6P1(GI3(U%T.B:T___3(MET$D!W$R)YT'_ +XMUDB)PTB)WDPIYDR)_TR)XN@)PO[_@#LD=,1(BT7`Q@``2(M%N$B+3:A(B0%( +XMBT7`2(E!",=!$`$```#K$DV)-"1)B5PD"$''1"00`````$B)V$B#Q$A;05Q! +XM74%>05]=PV9F9F8N#Q^$``````"#?Q``=`A(BS_ITJS^_\.054B)Y4%64TF) +XM]DB)^^B^!```2(7`=`0QP.L02(G?3(GVZ)H```"X`0```%M!7EW#54B)Y4%7 +XM05934$F)UTB)\TF)_DF+!DB%VW0Z2(7`=%Z_&````.@64O__3(EX$$B)&$B+ +XM2PA(B4@(2(E#"$B+2`A(A!!(QT`(`````$C'``````!)B48(28D&2(/$"%M!7D%?7<,/'X`` +XM````54B)Y4%64TF)]DB)^[\8````Z)E1__],B7`02(M+"$B)"$C'0`@````` +XM2(M+"$B%R70&2(E!".L#2(D#2(E#"%M!7EW#D)"0D)"0D)"0D)!52(GE05=! +XM5E-028G^2(L>2(7;=$9-BWX(#Q^``````+\8````Z#91__](BTL02(E($$V% +XM_W4%28D&ZP1)B4<(3(DX2(M;"$B%VTF)QW7128E&"$C'0`@`````2(/$"%M! +XM7D%?7<.0D)"0D)"0D)"02(L&2(7`="1(BT\(2(D(2(L&2(M/"$B%R70&2(E! +XM".L#2(D'2(M&"$B)1PC#D)"054B)Y5-02(GX2(LX,=M(A?]T)DB+3PA(BU\0 +XM2(D(2(7)=`E(QP$`````ZPA(QT`(`````.CGJO[_2(G82(/$"%M=PY"0D)"0 +XMD)"0D)"0D)!52(GE05=!5E-028GV2(L?387V="A(A=MT2F8/'T0``$R+>PA( +XMBWL00?_62(G?Z)VJ_O]-A?],B?MUY>LG2(7;=")F9F9F9BX/'X0``````$R+ +XMM,B?A( +XM@\0(6T%>05]=PY"0D)"0D)"0D)"0D)!52(GE05=!5E-028G628GW2(G[ZP]F +XM9BX/'X0``````$B+6P@QP$B%VW012(M[$$R)]D'_UX7`=>=(B=A(@\0(6T%> +XM05]=PY"0D)"0D)"0D%5(B>5!5T%64U!)B=9)B?=(B?OK&69F+@\?A``````` +XM2(M[$$R)]D'_UTB+6PA(A=MU[4B#Q`A;05Y!7UW#9I!52(GE059328GV2(L? +XMZPR02(M[$$'_UDB+6PA(A=MU\%M!7EW#9F8N#Q^$``````!52(GE05=!5E-0 +XM28G628GW2(G[9F9F9BX/'X0``````$B+&TB%VW012(G?3(GV0?_72(/#"(7` +XM=>=(@\0(6T%>05]=PY"0D)"0D)"0D)"0D%5(B>5!5T%64U!)B=9(B?-)B?]) +XMBP=(A=MT,$B%P'14OQ@```#H1D[__TR)L$2(E#"$B)`UM!7EW#D)"0D)"0 +XMD)"0D)"0D)!(BP\QP$B%R70-2(UY"$@Y<1!(B'1E;F1E9"!F;W)M870@96YT'1E;F1E9"!F;W)M870@96YTF5R;R!S=&%T +XM=7,`8"5S)R!I&%M:6YI;F<@)7,N+BX`=7!D871E('1I;64Z("5S"@`* +XM"E-T;W`@:6X@)7,@*&QI;F4@)6QU(&]F("5S*2X*`"Y#55)$25(`"@I3=&]P +XM(&EN("5S+@H`1W)A<&@@8WEC;&5S('1H2!N97-T +XM960@:68G0!396%R8VAI;F<@9F]R("5S+BXN +XM`&AE6EN9R!S=6)D:7)E8W1O2P@XQ1``````"#C%$````` +XM`(F,40``````CHQ1`````````````````"5S("5S*&EG;F]R960I"@`E'!A;F1S('1O(&5M<'1Y('-T +XM5]L:6YE +XM+A```````"'N$`````` +XM`%2Y0```````EKA```````!4N4```````%2Y0```````I;A```````"TN$`` +XM`````%2Y0```````P[A```````!"4%-I:VYQ5T@6RUJ(&UA>%]J;V)S72!;+6T@9&ER96-T;W)Y72!;+58@=F%R +XM:6%B;&5="@D@("`@6TY!344]=F%L=65=(%MT87)G970@+BXN70H`)7,M+3TE +XM9"``455%54E.1R``0VAI;&0@)7,@9&ES8V]V97)E9"!G6-L97,@ +XM=&AR;W5G:"`E65T+@H`)7,Z(&YO +XM="!Q=65U:6YG("@E9"!U;FUA9&4@8VAI;&1R96XI"@`EG4I"@`````````` +XM`````````$#10```````4-)```````#5U4```````+320```````!M-````` +XM``!STT```````*[30```````\-U```````!)WD```````"S>0```````2=Y` +XM```````XWD```````$G>0```````1-Y```````"3FU$```````8````````` +XMESL``,0````@`````````)F;40``````"`````````!]E0,`Q0```$`````` +XM````H9M1```````*`````````$?P.0!&``````````````"KFU$```````L` +XM````````%8#F`,@`````$````````+:;40``````!@`````````:.0``R0`` +XM```$````````O)M1```````&`````````,LX``!*``````````````#"FU$` +XM``````8`````````!3@``,L`````"````````,B;40``````!@`````````Z +XM.```3````````````````Y-1```````&`````````#DX``#-``````(````` +XM```PDU$```````L`````````7[3@`$X``````````````,Z;40``````"``` +XM``````!?A`,`3@``````````````UIM1```````)`````````#H>#@#/```` +XM`"````````#?FU$```````T`````````F`\9#E```````````````.R;40`` +XM````#`````````"8#X8#4```````````````^)M1```````&`````````*PY +XM``!1``````````````#^FU$```````H`````````:,\Y`-(````(```````` +XM``B<40``````!P````````"&Y@``4P``````````````#YQ1```````*```` +XM`````)@//P!4```````````````9G%$```````8`````````"#\``%4````` +XM`````````!^<40``````!P````````"1_P``U@````!`````````)IQ1```` +XM```*`````````+=@/@#7````@``````````PG%$```````L`````````36?^ +XM`,T``````@```````#N<40``````"``````````\\P,`V0`````!```````` +XM0YQ1```````-`````````"Q0S@]:``````````````!0G%$```````H````` +XM````A]@^`%L``````````````%J<40``````!0````````#9#P``W````!`` +XM````````7YQ1```````&`````````*`^``#=``````````````!EG%$````` +XM``<`````````!.P``.`````````"`````&R<40``````"P````````!-2^\` +XMX0````````0`````56YA"!O9B!S<&5C:6%L('1A"!F;W(@+G!O:7-O;CH@)7,`+FEN8VQU9&4@9FEL96YA +XM;64@;75S="!B92!D96QI;6ET960@8GD@)R(G(&]R("<\)P!5;F-L;W-E9"`N +XM:6YC;'5D92!F:6QE;F%M92X@)R5C)R!E>'!E8W1E9`!5;F5X<&5C=&5D(&5N +XM9"!O9B!F:6QE(&EN(&9O"!O;B`E6EN9R`E'!A;F1I;F<@(B5S(BXN+@!S=69F:7@@:7,@(B5S(BXN+@!% +XM>'!A;F1I;F<@(B5S(BXN+@!0&5S.@``````861D:6YG('-U9F9I>"!R=6QE````````````````````",J*BH@5')A;G-F +XM;W)M871I;VYS.@```,HA00``````Q2%!``````#+(4$``````-$A00`````` +XMUR%!``````#=(4$``````)`C00``````A"-!``````"N)$$``````+@D00`` +XM````PB1!``````#,)$$``````/`D00``````6R-!``````#6)$$``````-TD +XM00``````Y"1!``````#K)$$``````"Y"14=)3@`N14Y$`"Y)3E1%4E)54%0` +XM+D1%1D%53%0`+D]05$E/3D%,(``N55-%(``N15A%0R``+DE'3D]212``+E!2 +XM14-)3U53(``N4TE,14Y4(``N34%+12``+DI/24X@`"Y)3E9)4TE"3$4@`"Y. +XM3U1-04E.(``N3$E"(``N345-0D52(``N05)#2%8@`'5N:VYO=VX`97)R;W(@ +XM=VAE;B!M861E`&]T:&5R('-T871U&ES +XM=&5N="`H;6%Y8F4I.B`E6EN9R!T;R!P +XM;VES;VX@9'EN86UI8R!V87)I86)L92`D)7,`4&]I2!S970*`%1R>6EN9R!T;R!D96QE=&4@9'EN86UI8R!V +XM87)I86)L92`D)7,`5')Y:6YG('1O(&=E="!V86QU92!O9B!D>6YA;6EC('9A +XM6YA;6EC('9A0H`5')Y:6YG('1O("5S(&1Y;F%M +XM:6,@=F%R:6%B;&4@)"5S`&%P<&5N9"!T;P!4$$`````````````````<'E!``````!@>4$` +XM````````````````,'A!`````````````````,!X00``````8'E!```````` +XM`````````/!S00````````````````!`=$$``````.!G00`````````````` +XM``#`:T$``````-!K00````````````````#@9T$`````````````````@&I! +XM``````#P:D$`````````````````\"=``````````````````(!H00`````` +XM``````````"09$$```````````````````````````"`:$$````````````` +XM````X&)!````````````````````````````@&A!`````````````````/!I +XM00```````````````````````````(!H00````````````````!P:4$````` +XM``````````````````````"`:$$``````!!I00`````````````````````` +XM````````````````@&A!``````"P:$$````````````````````````````` +XM`````````!!H00``````0&A!````````````````````````````"B`))V`B +XM.R8\/B@I?"H_>WU;75PD(2->?@`````````!``````````$`````````!``` +XM```````0`T````````4`````````:!)````````&`````````)@&0``````` +XM"@````````#J`P````````L`````````&``````````5```````````````` +XM`````P````````#XM'$```````(`````````P`D````````4``````````<` +XM````````%P````````"H%T````````<`````````6!9````````(```````` +XM`%`!````````"0`````````8```````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM````````````````````````````````````````````````````L+-A```` +XM````````````````````````EB%```````"F(4```````+8A0```````QB%` +XM``````#6(4```````.8A0```````]B%````````&(D```````!8B0``````` +XM)B)````````V(D```````$8B0```````5B)```````!F(D```````'8B0``` +XM````AB)```````"6(D```````*8B0```````MB)```````#&(D```````-8B +XM0```````YB)```````#V(D````````8C0```````%B-````````F(T`````` +XM`#8C0```````1B-```````!6(T```````&8C0```````=B-```````"&(T`` +XM`````)8C0```````IB-```````"V(T```````,8C0```````UB-```````#F +XM(T```````/8C0```````!B1````````6)$```````"8D0```````-B1````` +XM``!&)$```````%8D0```````9B1```````!V)$```````(8D0```````EB1` +XM``````"F)$```````+8D0```````QB1```````#6)$```````.8D0``````` +XM]B1````````&)4```````!8E0```````)B5````````V)4```````$8E0``` +XM````5B5```````!F)4```````'8E0```````AB5```````"6)4```````*8E +XM0```````MB5```````#&)4```````-8E0```````YB5```````#V)4`````` +XM``8F0```````%B9````````F)D```````#8F0```````1B9```````!6)D`` +XM`````&8F0```````=B9```````"&)D```````)8F0```````IB9```````"V +XM)D```````,8F0```````UB9```````#F)D```````/8F0```````!B=````` +XM```6)T```````"8G0```````-B=```````!&)T```````%8G0```````9B=` +XM``````!V)T```````(8G0```````EB=```````"F)T```````+8G0``````` +XMQB=```````#6)T```````.8G0```````]B=````````&*$`````````````` +XM``````````````````````````````````````````````#__________P`` +XM```````````````````````````````N6YS='(`+G)E;&$N9'EN`"YR96QA+G!L=``N:6YI=``N=&5X=``N9FEN +XM:0`N#D````````:```` +XM"`$```@`````````&``````````)`````P````````````````````````"P +XM^0$``````*4>```````````````````!```````````````````````````` +XM``````````````````````````````,``0#@`D`````````````````````` +XM``,``@#T`D````````````````````````,``P`0`T`````````````````` +XM``````,`!`"8!D````````````````````````,`!0!H$D`````````````` +XM``````````,`!@!8%D````````````````````````,`!P"H%T`````````` +XM``````````````,`"`!P(4````````````````````````,`"0"`(4`````` +XM``````````````````,`"@`0*$````````````````````````,`"P#0@$$` +XM``````````````````````,`#`#@@%$```````````````````````,`#0`` +XML&$```````````````````````,`#@"LLV$```````````````````````,` +XM#P"PLV$```````````````````````,`$`#PM&$````````````````````` +XM``,`$0#XM'$```````````````````````,`$@#XM'$````````````````` +XM``````,`$P!XN'$```````````````````````,`%`"(N'$````````````` +XM``````````,`%0"0N'$```````````````````````,`%@"0N($````````` +XM``````````````,`%P````````````````````````````,`&``````````` +XM``````````````````,`&0````````````````````````````,`&@`````` +XM`````````````````0````0`\?\`````````````````````'@````(`"@"` +XM.D```````-(!````````+`````$`#0`PL&$``````"@`````````-@````$` +XM%@`PNX$``````$``````````/P````$`%@!PNX$``````"``````````40`` +XM``$`#0`(L&$``````"@`````````7@````0`\?\````````````````````` +XM>@````0`\?\`````````````````````FP````0`\?\````````````````` +XM````N@````(`"@#`0$```````!`$````````Q0````0`\?\````````````` +XM````````X@````(`"@#`6$```````,X`````````[0````(`"@#P4D`````` +XM``\`````````^P````(`"@!P4T```````$``````````"`$```(`"@``4T`` +XM`````&8`````````$P$```(`"@"P4T```````"P`````````(`$```(`"@`0 +XM3$```````$L`````````)@$```(`"@"064```````$P`````````+`$```(` +XM"@#@4T```````-0$````````00$```(`"@#@64```````&\`````````1P$` +XM``(`"@!@3$```````*P%````````40$```$`%@!XOH$```````@````````` +XM70$```$`%@"(OH$```````@`````````9@$```$`%@"`OH$```````0````` +XM````<0$```$`#0!D```````"$"````````UP(` +XM``$`%@`@OX$```````$`````````]`(```0`\?\````````````````````` +XM$@,```0`\?\`````````````````````+@,```(`"@"0AT```````-$````` +XM````-@,```0`\?\`````````````````````4P,```0`\?\````````````` +XM````````;P,```(`"@#`ED````````4`````````>0,```(`"@#@GT`````` +XM`/H`````````A@,```(`"@!@C$```````'<&````````CP,```(`"@"PBT`` +XM`````)T`````````H0,```$`%@!HP($```````0`````````J@,```$`%@"8 +XMP($```````@`````````M@,```(`"@#0FD```````,8`````````PP,```$` +XM%@!@P($```````0`````````R@,```$`%@`XP($``````!``````````U0,` +XM``$`%@!XP($```````$`````````Y0,```(`"@!0BD```````%L!```````` +XM_`,```(`"@"PE$````````T"````````#P0```(`"@"@FT```````$`$```` +XM````(00```$`%@!(P($``````!``````````*@0```$`#0#@L&$```````0` +XM````````-00```$`%@!PP($```````@`````````/@0```$`%@"@P($````` +XM``@`````````2`0```$`%@!8P($```````0`````````4`0```$`%@!P@```(`"@`@)4$``````!,`````````B0@```(`"@#@(D$` +XM`````"$"`````````08```$`%@"0QX$``````$``````````EP@```0`\?\` +XM````````````````````N0@```$`%@#XQX$```````@`````````P`@```$` +XM#0!XL6$```````@`````````R`@```$`%@#0QX$```````@`````````SP@` +XM``$`#0!0L6$``````"@`````````V@@```$`%@#HQX$```````@````````` +XMX@@```$`%@#PQX$```````$`````````"PD```$`%@#8QX$```````@````` +XM````$@D```$`%@#@QX$```````@`````````'0D```(`"@`@0$$``````+$# +XM````````+@D```0`\?\`````````````````````4`D```$`%@``R($````` +XM`(``````````8PD```0`\?\`````````````````````?PD```$`%@#)R($` +XM``````$`````````F0D```$`%@#PR($``````/`*````````I`D```$`%@"$ +XMR($```````0`````````L@D```(`"@``14$``````$H#````````OPD```$` +XM%@#HR($```````0`````````S0D```(`"@!02$$``````!\!````````W0D` +XM``(`"@"074$``````#,`````````Y@D```(`"@!@74$``````"8````````` +XM\@D```$`%@"(R($``````$```````````PH```$`%@#0R($``````!@````` +XM````$`H```$`%@#(R($```````$`````````&PH```(`"@#074$``````)(` +XM````````+`H```$`#0"`L6$``````"@`````````-0H```(`"@`P2D$````` +XM`(`!````````1`H```(`"@"064$``````'$`````````4@H```$`#``PI5$` +XM`````'@`````````6PH```0`\?\`````````````````````@`H```(`"@`@ +XM4$``````)P`````````GPH```(`"@#`>$$``````)P`````````J@H` +XM``(`"@#P:D$``````,$`````````LPH```$`#0"0LV$``````!H````````` +XMP0H```(`"@!P:4$``````'D`````````R0H```(`"@!`9T$``````)4````` +XM````U@H```(`"@!`=$$``````/`#````````Y`H```(`"@#P:4$``````($` +XM````````[@H```(`"@"09$$``````'D`````````]@H```(`"@"`:$$````` +XM`"H``````````@L```(`"@"`:D$``````&0`````````#@L```(`"@`0:$$` +XM`````"@`````````&@L```$`%@#@TX$````````(````````)0L```(`"@#@ +XM<$$``````#4$```````4````` +XM````A`L```(`"@#`:T$```````@`````````DPL```(`"@#P$$``````(\`````````L0L```(`"@`094$````` +XM`"T"````````P0L```$`#0"@LF$``````"@`````````R@L```$`#0!`LV$` +XM`````"@`````````U`L```$`#0"PL6$``````"@`````````W@L```$`#0#8 +XML6$``````"@`````````Z@L```$`#0!0LF$``````"@`````````]`L```$` +XM#0`HLF$``````"@```````````P```$`#0#PLF$``````"@`````````"0P` +XM``$`#0!HLV$``````"@`````````$PP```$`#0``LF$``````"@````````` +XM'0P```$`#0#(LF$``````"@`````````*`P```$`#`"HJ5$``````"@````` +XM````,0P```$`#0!XLF$``````"@`````````.@P```$`#0`8LV$``````"@` +XM````````1`P```0`\?\`````````````````````9`P```0`\?\````````` +XM````````````C@P```0`\?\`````````````````````N`P```0`\?\````` +XM````````````````X@P```0`\?\`````````````````````$PT```0`\?\` +XM````````````````````/@T```0`\?\`````````````````````:0T```0` +XM\?\`````````````````````D0T```0`\?\`````````````````````O0T` +XM``0`\?\`````````````````````[`T```0`\?\````````````````````` +XM%@X```0`\?\`````````````````````0`X```0`\?\````````````````` +XM````:@X```0`\?\`````````````````````E0X```0`\?\````````````` +XM````````P`X```0`\?\`````````````````````Z`X``!$`%@`LW8$````` +XM``0`````````]`X``!$`%@!PW8$```````@``````````P\``!(```"0(4`` +XM`````(8`````````"P\``!(`"@!@?D$``````#X`````````&P\``!(```"@ +XM(4``````````````````*0\``!(`"@`0>T$```````\`````````-@\``!(` +XM"@#P/T$``````"D`````````00\``!$`%@`8W8$```````0`````````30\` +XM`!$`#0"PL&$```````@`````````60\``!(```"P(4```````-8````````` +XM8@\``!(`"@!@@$$```````H`````````;@\``!$`%@!`W8$```````0````` +XM````>@\``!(```#`(4````````<`````````@@\``!(`"@"@PT```````$4" +XM````````C@\``!(`"@`P5T$``````%8"````````FP\``!$`%@!XW8$````` +XM``@`````````HP\``!(`"@!@HD```````/\!````````P0\``!(```#0(4`` +XM`````+X`````````R`\``!(```#@(4```````(<`````````SP\``!(`"@#` +XM2T$``````-P`````````V@\``!(`"@"0DT````````X`````````Y`\``!(` +XM"@!`;D```````*8`````````]@\``!(```#P(4``````````````````_0\` +XM`!(`````(D```````'4`````````$!```!(````0(D```````"0````````` +XM&1```!(`"@!P7D$``````(4`````````*Q```!(`"@!P@$$``````$D````` +XM````-Q```!(`"@!PB$```````"\`````````/!```!(`"@`0@T```````'P" +XM````````11```!(`"@"`SD```````"<`````````31```!$`%@"0W8$````` +XM`!``````````41```!(````@(D```````&,!````````6A```!(`"@!P]T`` +XM`````$``````````8Q```!(`"@#`94```````$4`````````;Q```!(`"@#P +XM;D```````/L`````````?A```!$`%@"0N($``````$``````````D!```!$` +XM\?^PLV$`````````````````F1```!(`"@`034$``````!P!````````IQ`` +XM`!(````P(D````````@`````````KQ```!(`"@#01$```````#8'```````` +XMN1```!(`"@`0LD```````%4`````````S!```!``%0"0N'$````````````` +XM````UA```!(`"@"@DT```````%L`````````X1```!(`"@"@Y$```````*<` +XM````````[!```!(```!`(D```````'\`````````\Q```!``\?\(```````` +XM````````````$!$``!(`"@#0?$```````-$`````````'1$``!(`"@!0^$`` +XM`````!8`````````)Q$``!(```!0(D```````$,`````````+A$``!(```!@ +XM(D``````````````````-1$``!(`"@#0'T$``````!X`````````0Q$``!(` +XM"@!P24$``````*X`````````3Q$``!(```!P(D```````$(!````````91$` +XM`!(`"@!@/$```````%4`````````<1$``!(`"@`04D```````)<````````` +XM>A$``!(`"@#05D$```````D`````````BA$``!(```"`(D```````#<````` +XM````EA$``!(```"0(D```````,0!````````G1$``!(`"@#PSD```````$\` +XM````````JQ$``!(`"@`09D```````$P`````````MA$``!$`%@!$W8$````` +XM``0`````````P!$``!(```"@(D```````/,`````````QQ$``!(```"P(D`` +XM`````/L`````````S!$``!(```#`(D``````````````````T1$``!(`"@!@ +XM[T```````"T`````````XA$``!(`"@``E$```````"\`````````ZQ$``!(` +XM"@"0A4```````'A,``!$` +XM%@!,W8$```````0`````````@!,``!(`"@"0?4$``````',`````````BA,` +XM`!(`"@#0^T````````(`````````FA,``!(`"@#`!$$``````(H````````` +XMJ!,``!(`"@"P9$```````$0`````````M!,``!(````@(T```````!@````` +XM````NA,``!(`"@"0PT````````X`````````QQ,``!(````P(T`````````` +XM````````SQ,``!(`"@"P2T$```````L`````````Y1,``!(```!`(T`````` +XM`!L`````````\!,``!(`"@!074```````%,'````````!10``!(```!0(T`` +XM``````L`````````%A0``!(`"@"P<4```````"L`````````)10``!(```!@ +XM(T```````!\`````````,Q0``!(`"@"@>$```````&\!````````/10``!(` +XM"@!@9D````````H`````````2Q0``!(```!P(T```````#D"````````4A0` +XM`!(`"@#0?D$``````$0`````````9Q0``!(`"@!@.4```````&T````````` +XM=A0``!(```"`(T``````````````````>Q0``!(`"@#`6T$``````)@!```` +XM````BA0``!(```"0(T```````,,!````````D!0``!(`"@!`BD````````\` +XM````````I!0``!(`"@#P?T```````,@`````````JA0``!$`%@"`W8$````` +XM``@`````````LQ0``!(`"@#`4D$``````-$"````````O10``!(`"@#`T$`` +XM`````-X2````````R!0``!(```"@(T```````"$`````````T!0``!$`#0#P +XML&$```````@`````````XA0``!(`"`!P(4``````````````````Z10``!(` +XM``"P(T```````%``````````]A0``!(```#`(T```````(!<``!(```#0)$```````$,&````````@!<``!$` +XM%@"(W8$```````@`````````BQ<``!(`"@#PQ4```````!("````````E!<` +XM`!(`"@"0S4```````"(`````````G!<``!(`"@#`@$```````-@````````` +XMH1<``!(```#@)$```````"L`````````J!<``!(`"@``'T$``````(4````` +XM````MA<``!$`%@#PN($``````,@!````````NQ<``!(```#P)$`````````` +XM````````P!<``!(`"@`0_4```````"8`````````T1<``!(`````)4`````` +XM`!H`````````UQ<``!(`"@!0C$````````0`````````X!<``!``\?^HW8$` +XM````````````````_A<``!(`"@!0Y4```````%0`````````#1@``!(````0 +XM)4```````",`````````%!@``!(````@)4````````P!````````&A@``!(` +XM"@!@/4```````#$`````````(Q@``!(`"@``94````````8`````````+Q@` +XM`!(`"@"0'T$``````!D`````````.Q@``!(`"@#0.4```````!0````````` +XM11@``!(`"@`P'4$``````,8!````````51@``!(````P)4```````*\'```` +XM````71@``!(`"@"P]T```````)$`````````:1@``!(```!`)4```````&\` +XM````````=!@``!(```!0)4```````-P`````````>A@``!$`%@"XNH$````` +XM``0`````````AQ@``!``\?^0N($`````````````````DQ@``!(```!@)4`` +XM``````H`````````FA@``!(```!P)4```````&T`````````I!@``!(```"` +XM)4```````!\`````````JQ@``!(`"@#@0T$```````<`````````M1@``!(` +XM"@"`N4```````)\'````````NA@``!(`"@!0>T$``````(D`````````Q1@` +XM`!(```"0)4```````-P`````````S1@``!(`"@!0T$```````$D````````` +XMUQ@``!(`"@!`1$$``````#@`````````Y1@``!(`"@#`@$$```````T````` +XM````[A@``!(`"@#0^$```````"$!````````!!D``!(```"@)4````````L! +XM````````"QD``!(`"@``SD```````$P`````````$QD``!$`%@`0W($````` +XM```!````````)AD``!(```"P)4```````"41````````+AD``!(```#`)4`` +XM`````#0`````````,QD``!(```#0)4```````#D`````````.QD``!(```#@ +XM)4```````#@`````````2AD``!(```#P)4```````$X`````````5QD``!$` +XM%@!HW8$```````@`````````7AD``!(`````)D```````%<`````````;1D` +XM`!(````0)D```````$L`````````T$``````#`````````` +XM?1D``!(`"@"`)D$``````'`9````````E!D``!(````@)D```````!T````` +XM````FQD``!$`#0#XL&$```````@`````````JQD``!(````P)D```````'0` +XM````````LAD``!(`"@#PH4```````&X`````````P1D``!(`"@"@?D$````` +XM`"4`````````RQD``!$`%@`TW8$```````0`````````V!D``!(`"@`@?T`` +XM`````,(`````````WAD``!(`"@`0?D$``````$<`````````ZQD``!(```!` +XM)D````````D`````````\AD``!(```!0)D```````#0`````````^AD``!$` +XM%@"\NH$```````0``````````QH``!(`"P#0@$$`````````````````"AH` +XM`!(```!@)D```````"D!````````$QH``!(`"@!`>$```````%T````````` +XM(QH``!(`"@`0\$```````(``````````+QH``!(```!P)D```````$,!```` +XM````-QH``!(`"@`@2D$```````4`````````2AH``!$`%@`HW8$```````0` +XM````````51H``!(`"@"@T$```````!0`````````:1H``!(`"@"PST`````` +XM`#X`````````<1H``!(`"@!PLD```````!4"````````@QH``!(`"@"@54$` +XM`````%L`````````CAH``!$`%@`0W8$```````@`````````DAH``!(```"` +XM)D```````%$`````````F!H``!(```"0)D```````.0!````````GQH``!(` +XM"@#@DD```````'4`````````J!H``!(`"@!`*$```````,0`````````L1H` +XM`!(`"@"@3D$``````!T$````````NQH``!(```"@)D```````'8````````` +XMQ!H``!(```"P)D``````````````````R1H``!(`"@"0H4```````&`````` +XM````V!H``!$`%@"@W8$```````0`````````Y!H``!(```#`)D```````,D` +XM````````ZQH``!$`%@!4W8$```````0`````````]1H``!(`"@#P(4$````` +XM`.4`````````!1L``!(`"@!PJD```````#`'````````&AL``!(`"@`P6T$` +XM`````(T`````````(QL``!``\?^0N($`````````````````*AL``!(`"@#P +XM;T```````(4`````````-AL``!$`\?_XM'$`````````````````3!L``!`` +XM\?^HW8$`````````````````41L``!(`"@"@?T$``````$(`````````71L` +XM`!$`%@"`R($```````$`````````9QL``!(`"@!@+T```````(P#```````` +XMD```````($`````````S!L``!(`"@"@@4`` +XM`````$X`````````TQL``!(`"@#P?T$``````!@`````````WAL``!(`"@"@ +XM=D```````$X!````````\!L``!(```#0)D```````!8`````````]1L``!(` +XM"@#P,D````````$``````````QP``!(`"@!`_D```````$H!````````*QP` +XM`!(`"@#`\T```````#4!````````2`0``!$`%@!D$````` +XM`/,`````````'AT``!(`"@!@7$```````/``````````+AT``!(`"@`0@$$` +XM`````$8`````````.1T``!(````@)T```````!X`````````0!T``!(````P +XM)T``````````````````11T``!(`"@`0($$``````)P!````````5!T``!(` +XM``!`)T```````#<`````````7QT``!(`"@"@L4```````!0`````````;QT` +XM`!(`"@!@I$```````.`"````````AAT``!(```!0)T```````'@````````` +XMCAT``!(`"@#`/$```````)P`````````FQT``!(```!@)T```````",````` +XM````HAT``!(`"@"P(4$``````#,`````````LQT``!(```!P)T```````)@` +XM````````N1T``!(```"`)T```````!H`````````P!T``!``#0``L&$````` +XM````````````S1T``!(`"@`PB4````````8!````````WAT``!(```"0)T`` +XM`````(X`````````YQT``!$`%@!@W8$```````0`````````\1T``"`````` +XM````````````````````!1X``!(`"@!@DT```````"P`````````$QX``!$` +XM%@`@QH$```````@`````````(!X``!(```"P)T``````````````````)AX` +XM`!(`"@#P]D```````'@`````````-!X``"(`"@`0*D````````$````````` +XM2AX``!(`"@#@<4```````(<"````````6!X``!(```#`)T`````````````` +XM````7AX``!(```#0)T```````%H`````````9QX``!(```#@)T```````"@` +XM````````=!X``!(`"@#@>T$``````$4`````````?AX``!$`%@!DW8$````` +XM``0`````````AQX``!(```#P)T```````/$`````````C!X``!(`"@`PE$`` +XM`````(``````````F1X``!(`````*$```````````````````"]U0!A&ES=',`0V]N9$1O36%K90!#;VYD +XM1&]487)G970`0V]N9$4`0V]N9$8`0V]N9$AA;F1L94-O;7!A'!R`&-O;F1);G9E'!A +XM;F0N8P!$:7)%>'!A;F17:6QD:0!$:7)0$IO8G,`;DIO8G,`;W-E=`!O=71P=71?;6%S:P!R96UO=F5? +XM:F]B`')U;FYI;F=*;V)S`'-E=``O=7-R+W-R8R]U2YC +XM`&5N;V-M96T`96YO;65M`"]U&5S`'1R86YS9F]R;7,`+W5S2YC`"]U0!S=')E0!3=69F7T%D9$EN8VQU9&5I`$UA +XM:V5?3T]$871E`&)R:U]S=')I;F<`:VQU9&=E7VQO;VM?:&%R9&5R7V9O&5S`&5U;FQI +XM;FL`5&%R9U].97='3FD`<')I;G1?97)R;W)S`%9A&5C=71E`%!A%]P871H`&5X96-V`$IO8E]-86ME`%]?41I<@!487)G7TEG;F]R90!!6U486)L95]);FET`$QS=%]3=6-C`%-U9F9?4&%R$QE;@!O:&%S:%]I;G1E0!F=W)I=&4`=&]U +XM8VA&;&%G`%1A5]N86UE`%-T49L86<`7TIV7U)E9VES=&5R0VQA0!F8VYT;`!3=')?4UE35E-U8G-T`%]?ps.uu << 'END-of-ps.uu' +Xbegin 755 ps +XM?T5,1@$!`0D```````````(``P`!````T)0$"#0````(>````````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(!&`` +XM``1@```%`````!````$````@8```(/`$""#P!`BX$P``C"````8`````$``` +XM`@```+QQ``"\`04(O`$%"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&3H7P``Z-\$".C?!`@<````'`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`0P```%L````*````50```!,````O````1@```%0````L```` +XM/0```#L`````````1P```!H```!#````00`````````Q````3P`````````+ +XM`````````!0```!:````3@````````!)`````````!@````N````)P```$H` +XM``!6`````````#8````_`````````!<`````````4````"D`````````4P`` +XM`%D``````````````!$```!8`````````#<````A````-````!\````K```` +XM````````````````2P```%$``````````````$0`````````30```$4````` +XM````,P```%<````````````````````````````````````````````````` +XM```````````````````%````````````````````````````````````#@`` +XM``````````````````P````&````"``````````2```````````````-```` +XM`````!P````````````````````````````````````B`````````"0````' +XM`````````"H``````````````!D````6````!````"4````F````#P`````` +XM```!`````````!X`````````&P```#`````0````.@```#(````````````` +XM`"T`````````````````````````'0```"`````C````-0```#D````H```` +XM`````#X````\`````@```$P````)````2`````````!````````````````X +XM````%0```%(```!"`````P````````````````````````"U`0```````#0` +XM```2````OP(````````S````$@```*$"````````0P```!(```"F`0`````` +XM`&$````2````6P$`````````````$@```(H"````````*@```!(```#L```` +XM`````&L!```2````$`$```````#]"```$@```#,```"\`04(`````!$`\?\Z +XM`@```````)@````2````0@(```````"A````$@````0!````````?P```!(` +XM``!?`@```````!T````2````\P$`````````````$@````,"````````6@`` +XM`!(```#C`````````!T````2````T@(````````S````$@```,4````````` +XM`````!(```#L`@```````.T````2````G0(```````#G`0``$@```"@"```` +XM````!0```!(````\````=)$$"#D````2````^P$```````#=`P``$@```$@` +XM```0D`0(`````!(`"@"8`0``(*\$"$8````2``P`00$````````N````$@`` +XM`!X"````````,P$``!(```#+```````````````2````I@````````"C```` +XM$@```*T!``!X$`4(!````!$`%P#[`````````#T````2````Y0(````````` +XM````$@```-(`````````Q@0``!(````*`@``V`,%"`0````1`!<`8@$````` +XM```5`@``$@`````#````````G@```!(````7`@```````&4"```2````G@$` +XM````````````$@```-@!```@\`0(!````!$`$`"_`````````"T````2```` +XML0(`````````````$@```%0!``#<`P4(!````!$`%P"%`0``X`,%"%0,```1 +XM`!<`3@(```````#,````$@```'X!````````'0(``!(```#C`0```````!8` +XM```2````3@`````````+````$@```+8"````````'0```!(```!'`@`````` +XM```````2````M@$````````Y````$@```,0"````````[0```!(````4`P`` +XMV`,%"``````0`/'_V@````````#?````$@```/L"````````00```!(````+ +XM```````````````2````E@(```````!?````$@```/,`````````;0```!(` +XM``!9````+-8$"``````2``T`Q0$```````",`@``$@```%8"````````'0`` +XM`!(```"U````-!`%"`0````1`!<`#P``````````````$@```*8"```````` +XM30$``!(```!?````=),$""8"```2````,@(```````#+````$@```!8!```` +XM````+0```!(```!H`@````````,!```2`````(````` +XM``"\````$@```'$"````````*P```!(```#>`@`````````````2````@0`` +XM``````"V````$@```*X``````````````!(````3```````````````@```` +XM:0(```````"\````$@```'(!````````&````!(```!J`0```````)<````2 +XM````CP````````!J!```$@```.L!````````1````!(`````;&EB;2YS;RXU +XM`&QO9P!E>'``7TIV7U)E9VES=&5R0VQA7-C;VYF`'-N<')I;G1F`&=E=&=R9VED +XM`&=E=&5N=@!B6YA +XM;64`9V5T<'=U:60`9V5T<'=N86T`87-P&ET`'-T7-C=&QB +XM>6YA;64`7V5D871A`%]?8G-S7W-T87)T`%]E;F0`1D)31%\Q+C`````"``(` +XM`@`"``(``@`"``(``0`"``(``@`"``(``@`"``(``@`"``(``@````(``0`! +XM``(``@`"``(``0`"``(``@`"``(``@`"``(``0`"``(``@`"``(``@`"```` +XM`@`"``(``@`!``(``@`#``(``@`!``(``@`"``,``@````(``@`"``(``@`" +XM``$``@`!``$``@`"``(``@`"``(``@`"`````@````(``@`"`````@`!``$` +XM`0```!`````@````L"AZ!P```P`E`P````````$``0"<````$`````````"P +XM*'H'```"`"4#````````V`,%"`4B``#<`P4(!2H``.`#!0@%*P``-!`%"`4] +XM```X$`4(!4P``#P0!0@%3@``M`(%"`0"!0AH8````.D@_____R7H`@4(:&@` +XM``#I$/____\E[`(%"&AP````Z0#_____)?`"!0AH>````.GP_O___R7T`@4( +XM:(````#IX/[___\E^`(%"&B(````Z=#^____)?P"!0AHD````.G`_O___R4` +XM`P4(:)@```#IL/[___\E!`,%"&B@````Z:#^____)0@#!0AHJ````.F0_O__ +XM_R4,`P4(:+````#I@/[___\E$`,%"&BX````Z7#^____)10#!0AHP````.E@ +XM_O___R48`P4(:,@```#I4/[___\E'`,%"&C0````Z4#^____)2`#!0AHV``` +XM`.DP_O___R4D`P4(:.````#I(/[___\E*`,%"&CH````Z1#^____)2P#!0AH +XM\````.D`_O___R4P`P4(:/@```#I\/W___\E-`,%"&@``0``Z>#]____)3@# +XM!0AH"`$``.G0_?___R4\`P4(:!`!``#IP/W___\E0`,%"&@8`0``Z;#]____ +XM)40#!0AH(`$``.F@_?___R5(`P4(:"@!``#ID/W___\E3`,%"&@P`0``Z8#] +XM____)5`#!0AH.`$``.EP_?___R54`P4(:$`!``#I8/W___\E6`,%"&A(`0`` +XMZ5#]____)5P#!0AH4`$``.E`_?___R5@`P4(:%@!``#I,/W___\E9`,%"&A@ +XM`0``Z2#]____)6@#!0AH:`$``.D0_?___R5L`P4(:'`!``#I`/W___\E<`,% +XM"&AX`0``Z?#\____)70#!0AH@`$``.G@_/___R5X`P4(:(@!``#IT/S___\E +XM?`,%"&B0`0``Z<#\____)8`#!0AHF`$``.FP_/___R6$`P4(:*`!``#IH/S_ +XM__\EB`,%"&BH`0``Z9#\____)8P#!0AHL`$``.F`_/___R60`P4(:+@!``#I +XM!`% +XM"'XVBT4(AL*#[80@\`!A-)T%(#Z+W7QHR#P +XM!`@/MA"#P`&$TG7LN+P!!0B%P'0TB0PDZ/_^___'!"0LU@0(Z//^___HROK_ +XM_XU%"(ET)`B)1"0$B1PDZ'`2#P`2)1?"%_P^$A0```(`_ +XM`'3GBQU($`4(*?''1"0,$@```(D\)(/K`0'+Z/[]___!ZP*)PHG8.=-V`HG0 +XMB40D"(E\)`2)-"3H,?[__X`^`'0(@\8!@#X`=?B+#400!0BA2!`%"(G*@^@! +XM*?(!T(/X`W:'Q@8@BT7P@\8!BPU$$`4(BW@$@\`$B47PA?\/A7O___\Y\8E- +XM['0+,<"`?O\@#Y3`*<;&!@"+5>R)%"3H>_W__XM5$(U$`@2)!"3H[/S__X7` +XMB<8/A`\!``"+1>R%P`^$E````(M%"(L8QT0D!"\```")'"3H,OO__X7`=`.- +XM6`&+51"+10R)'"2)5"0(B40D!.C5^?__A7UW#BT7LB30DB40D!.@#_?__ +XMZ^6+30RXSML$"(7)=-N+11#'1>P`````@\`#Z4____^+10R+51#'1"0$J]8$ +XM"(DT)(E$)`R)5"0(Z-7\___KI\<$)`$```#H1_K__X/X_W1G/?[__Q]_3(T$ +XMA0$```"C2!`%"(D$).CW^___A<")1>RC1!`%"'08BU4(BSJ%_P^%&?[__XM% +XM[,8``.G-_O__QT0D!)W6!`C'!"0!````Z(_Y___'1"0$O-8$",<$)`$```#H +XM>_G__\=$)`2"U@0(QP0D`0```.AG^?__D)"058GEBT4,BP")10R+10B+`(E% +XM"%WI:_K__XVT)@````!5B>575E.#[!R+'4#P!`B`.P!T8\=%\`````"_SML$ +XM"#'VB1PDZ,K[__^+%:@0!0B%TG07UW#D(UT)@!5B>575E.#[$R+10B)!"3H$/C__XE% +XMO(E%\(VV`````(M=\(7;#X3P````@#L`#X3G````QT0D!.K6!`B)'"3H`/O_ +XM_X`\`ST/A>D```#'1?``````QT0D!#T```")'"3HG_C__X7`B<9T!L8``(/& +XM`8U5Q(E=Q,=$)!`PF`0(QT0D#"P```#'1"0(60```,=$)`1`\`0(B10DZ*7Y +XM__^%P(G'#X3)````BT`(A<`/A/H```"%]@^$H@```(D$).B@^O__B30DB7<.)]HV\)P````!5B>53 +XM@^PDBT4,BU@(C47TQT7X`````(D$).BE]O__@\`!='^+1?2)1"0$BU4(BP*+ +XM0"B)!"3H>?/__X7`=$&+1?2)!"3HNO3__XM%^(7`=&6)1"0(#[]#&,<$)(': +XM!`B)1"0$Z(OU__^+1?B)!"3HP/;__X/$)%M=PXVV`````(U%^(E$)`2+1?2) +XM!"3HPO/__X/``0^4P`^VP(/H`2%%^.N6#[!B+10S'1"0(B-H$"(M`"`^_0!C'!"2*V@0( +XMB40D!.BL]/__R<.-M@````!5B>6#[!B+10R+30B+4`@QP(-Y#`!T"(L!BX`T +XM`@``B40D"`^_0AC'!"2.V@0(B40D!.AM]/__R<.-M"8`````58GE@^P8BT4( +XMBP"+@.````#!Z`J)1"0(BT4,BT`(#[]`&,<$))/:!`B)1"0$Z#+T___)PXVV +XM`````(V_`````%6)Y8/L&(M%#(M("(M%"(L`BU`DA=)T2("X2P$```!T(P^_ +XM41@%2P$``(E$)`R)5"0(B50D!,<$))C:!`CHXO/__\G#B50D"`^_01C'!"2? +XMV@0(B40D!.C(\___R<.)]O:`+`$```1T,H"X9@$```!T"P^_41@%9@$``.NM +XMQT0D"*7:!`@/OT$8QP0D@=H$"(E$)`3HB_/__\G#QT0D"(C:!`@/OT$8QP0D +XM@=H$"(E$)`3H;?/__\G#C;0F`````%6)Y8/L&(M%#(M0"(M%"(L`BT`DA6#[!B+10R+4`B+10B+`/:`+`$```1T2H"X9@$```!T(P^_4A@% +XM9@$``(E$)`S'!"28V@0(B50D"(E4)`3H4/+__\G#QT0D"*7:!`@/OT(8QP0D +XM@=H$"(E$)`3H,O+__\G#QT0D"(C:!`@/OT(8QP0D@=H$"(E$)`3H%/+__\G# +XMC;0F`````(V\)P````!5B>6#[!B+10B+``^V@`\"``"#Z%2)1"0(BT4,BT`( +XM#[]`&,<$)*_:!`B)1"0$Z-'Q___)PXUT)@"-O"<`````58GE@^P8BT4(BP`/ +XMMH`-`@``@^A4B40D"(M%#(M`"`^_0!C'!"2OV@0(B40D!.B1\?__R<.-="8` +XMC;PG`````%6)Y593@^P@BT4,BW`(BT4(BPB`N30!```'BYDH`0``BY'\`@`` +XM#X:X````QD7H/_?#````$(U5Z74'QD7I5XU5ZH"Y-0$````/C*,```!^!L8" +XM3H/"`?;'"'0&Q@)8@\(!]L<@=`^`N30!```%=`;&`D6#P@'VPQ!T!L8"5H/" +XM`?;'`G4)@+DV`0```'X&Q@),@\(!]H$L`0```G0&Q@)S@\(!]L,"=`B+03`[ +XM031T3X'C`````70&Q@)*@\(!C47HQ@(`B40D"`^_1AC'!"2!V@0(B40D!.BG +XM\/__@\0@6UY=PP^V@30!``#_)(58VP0(Q@(\@\(!Z5K___^-=@#&`BN#P@'K +XMJ<9%Z%KI'____\9%Z%?I%O___\9%Z$R)]ND+____@^((="F#N00!```4&<"# +XMX`J#P$F(1>CI[_[__\9%Z%3IYO[__\9%Z%+IW?[__\9%Z$3IU/[__XUT)@!5 +XMNHC:!`B)Y8/L&(M%#(M("(M%"(L`@+A4`0```'0&C9!4`0``B50D"`^_01C' +XM!"2!V@0(B40D!.CG[___R<.058GE@^P8BT4,BU`(H8P0!0B%P'0MBTT(BP&# +XMN`0"```!?A\%.@$``(E$)`@/OT(8QP0D@=H$"(E$)`3HI.___\G#QT0D"+/: +XM!`@/OT(8QP0D@=H$"(E$)`3HAN___\G#58GE4X/L%(M%#(M="(L(BU`(A56B<93 +XMB=.#[!"XP?\$"(M2)/9##`)T#HG(N@*ZZF0 +XM58GE@^P8BT4,BTT(BU`(BT$,A6+10R+30A= +XMBU`(BT(<`P'IV?[__XGVC;PG`````%6)Y5=64X'LK````(M%#(L-D!`%"(MX +XM"(M%"(L0*XH8`0``N@=%+L*)R/?JC30*B6#[#B+10R)7?B)=?R+<`B+10B+`(M01(/Z_W11B=`P +XM](U=Z(E$)!`/ML:)'"2)1"0,QT0D".':!`C'1"0$$````.AK[/__B5PD"`^_ +XM1AC'!"2*V@0(B40D!.@S[/__BUWXBW7\B>Q=PY"-="8`QT0D"*;:!`@/OT88 +XMQP0DBMH$"(E$)`3H".S__XM=^(MU_(GL7<.-=@"-O"<`````58GE5E.#[#"+ +XM10R+6`B+10B+``^VD`P"```/MH`-`@``@/H"#X29````=U>`^@$/A+(```") +XM1"00C77P#[;"B40D#,=$)`C_V@0(QT0D!`@```")-"3HN>O__Y"-="8`B70D +XM",9%]P`/OT,8QP0DBMH$"(E$)`3H>.O__X/$,%M>7<.`^@-T*(#Z!'6HC77P +XMB40D#,=$)`CWV@0(QT0D!`@```")-"3H:.O__^NRB?:-=?#'1?!N;W)MQT7T +XM86P``.N=C77PB40D#,=$)`COV@0(QT0D!`@```")-"3H,NO__^EY____C77P +XMB40D#,=$)`CGV@0(QT0D!`@```")-"3H#NO__^E5____D(UT)@!5B>53@^P4 +XMBT4,BU@(H7P0!0B%P'1:H4P0!0B%P'4QBU4(BP+V@"L!```0="/;@.0````Q +XMTJ&($`4(4E#?+"2#Q`C>^=@-H-L$".L&C70F`-GNW5PD"`^_0QC'!"0%VP0( +XMB40D!.AZZO__@\046UW#Z`OS__^C3!`%".N:C70F`%6)Y5.#[!2+'7P0!0B% +XMVW1?BPU0$`4(A\=T<).CNZ?__,=)24]\L)(/$"-[) +XMW1PDZ"KJ___<+:C;!`C=1?#>\>N,B?:-O"<`````58GE4X/L%(M%#(M8"(M% +XM"(D$).@(____W5PD"`^_0QC'!"0%VP0(B40D!.A4Z?__@\046UW#C78`C;PG +XM`````%6)Y5=64X'LK````(M="(`]5!`%"``/A$0!``"+10R+0`B)A6S___^+ +XM>PR%_P^$)`$``(L[B[<4`0``BY\0`0``QT0D"$!"#P#'1"0,`````(ET)`2) +XM'"3HTRH``(ET)`3'1"0(0$(/`,=$)`P`````B1PDB85P____Z$$I``"+-9@0 +XM!0B%]@^%LP```(V(B!,``+NMB]MHBQ=PXL"C5V0BX`8`0``B47TC47TB00DZ$;F__^)'"3'1"0(4-L$",=$ +XM)`1D````B40D#.C:Y?__B5PD"`^_1AC'!"2!V@0(B40D!.@RY___BUWXBW7\ +XMB>Q=PXUT)@!5B>564X/$@(M%#(M="(MP"(M##(7`#X2J````H>#_!`B%P`^( +XM^P```(L#BX`8`0``B47TC47TB00DZ,7E__^+%9`0!0B)P8L#*Y`8`0``@?I_ +XM40$`?EF!^G\Z"0`/CYT```"+%>#_!`BX+=L$"(72='Z-79")3"0,B40D",=$ +XM)`1D````B1PDZ"?E__^)7"0(#[]&&,<$)(':!`B)1"0$Z'_F__^#[(!;7EW# +XMC70F`(L=X/\$"+@=VP0(A=MUL[@EVP0(ZZS'1"0(B-H$"`^_1AC'!"2!V@0( +XMB40D!.A"YO__@^R`6UY=PXVT)@````"X--L$".EX____C;8`````C5V0B4PD +XM#,=$)`@[VP0(QT0D!&0```")'"3HE>3__^EI____QP0D!````.ADYO__@#@` +XM#Y7`#[;`H^#_!`CIYO[__XVV`````(V\)P````!5B>53@^P4BT4,BU@(BT4( +XMBP"+0$2#^/]T-L=$)`0`(```B00DZ+KF__^%P'0BB40D"`^_0QC'!"2!V@0( +XMB40D!.B.Y?__@\046UW#C70F`,=$)`BFV@0(#[]#&,<$)(':!`B)1"0$Z&CE +XM__^#Q!1;7<.-M"8`````C;PG`````%6)Y8/L*(M%#(M5"(E=](EU^(E]_(M8 +XM"(L"BT!$@_C_#X2,````QT0D!``@``")!"3H+N;__X7`B47P='6+=?"X`P`` +XM`+\Q=PXGVBW7PN`,```"_1]L$"(G!\Z8/A6+____I +XM6?___XUT)@!5B>6#[`C'1"0$`````(M%"(L`BX",````B00DZ$/D__^)10C) +XMZ:KE__^-M@````!5B>53@^P4BT4,BU@(BT4(QT0D!`````"+`(N`C````(D$ +XM).@,Y/__B40D"`^_0QC'!"2!V@0(B40D!.CDX___@\046UW#C78`C;PG```` +XM`%6)Y8/L",=$)`0`````BT4(BP"+@(@```")!"3HP^/__XE%",GI*N7__XVV +XM`````%6)Y5.#[!2+10R+6`B+10C'1"0$`````(L`BX"(````B00DZ(SC__^) +XM1"0(#[]#&,<$)(':!`B)1"0$Z&3C__^#Q!1;7<.-=@"-O"<`````58GE@^P( +XMQT0D!`````"+10B+`(N`E````(D$).BSX?__B44(R>FJY/__C;8`````58GE +XM4X/L%(M%#(M8"(M%",=$)`0`````BP"+@)0```")!"3H?.'__XE$)`@/OT,8 +XMQP0D@=H$"(E$)`3HY.+__X/$%%M=PXUV`(V\)P````!5B>53@^P4BQT```4( +XMA=MT'8M+!(G:@#D`=`WK'F+`L8`"H/``8D"@\046UW#H300!0C'!"0@```` +XMB40D!.C=W___BQOKC8E,)`3'!"3+W`0(Z,GA___I1O___SM"&`^-8____XE4 +XM)`3'!"0@````Z&OB__^+&^E8____H300!0C'!"0*````B40D!.B/W___@\04 +XM6UW#B50D!,<$)`H```#H.>+__^G._O__58GE5U93@^P+__XT$A0$```")!"3H"N+__X7`B47L +XM#X2<`@``QT0D"%@```"+0P2)1"0$BT7LB00DZ(7>__^+0PC'1?``````AS'!"28V@0(B40D"(E4)`R) +XM1"0$Z';@__^+3>R)#"3HJ^'__XM-\(7)#X0Q____BT7PB44(@\0<6UY?7>F. +XMX?__BQ6H$`4(A=)U?HM%\(7`=!.+3?#'!"13VP0(B4PD!.@JX/__BT7LQP0D +XMR]P$"(E$)`3H%^#__^N?D(L#QP0DR]P$"`5O`0``B40D!.C]W___H8P0!0B% +XMP`^$P?[__XL#@[@$`@```0^.LO[__P4Z`0``B44,QT4(NMH$"(/$'%M>7UWI +XMQM___P^_7QB)V"L%G!`%"`'0ALDBQ4T$`4(#[[YBT((@^@!A<")0@AX0XL"B?F("(/``8D"@\8!@^L! +XM#XAM_O__#[9._X3)#X1A_O__BSW8`P4(A?]TO:$T$`4(B40D!`^^P8D$).BY +XMW/__Z\@[0AA\!8#Y"G6SB50D!(D\).AAW___Z[`[0AA\#(#Y"HUV``^%"?__ +XM_XE4)`2)/"3H0M___^D#____H300!0C'!"0@````B40D!.AHW/__Z4O____' +XM1"0$G=8$",<$)`$```#H']W__SM"&`^-)/___XE4)`3'!"0@````Z/;>___I +XM&?___XVV`````(V\)P````!5B>575E.#[!R+70B+=0R+0P2+?@B)!"3HA]__ +XM_XT$A0$```")!"3H^-[__X7`B47P#X0!`0``QT0D"%@```"+0P2)1"0$BT7P +XMB00DZ'/;__^+!H7`=#$/OT<8BU7PQP0DF-H$"(E$)`B)5"0,B40D!.BNW?__ +XMBTWPB4T(@\0<6UY?7>GLDBQ4T$`4(#[[YBT((@^@!A<")0@AX.XL"B?F("(/` +XM`8D"@\,!@^X!>)L/MDO_A,ETDXL]V`,%"(7_=,6A-!`%"(E$)`0/OL&)!"3H +XM(]O__^O0.T(8?`J`^0J0C70F`'6VB50D!(D\).C&W?__Z[.+5?#'!"3+W`0( +XMB50D!.CQW/__Z3[____'1"0$G=8$",<$)`$```#HJ-O__Y"0D)!5B>6)4`R+ +XM50A=QT`$`````,<``````(E("(E0$,=`%`````##C70F`(V\)P````"A7!`% +XM"%6)Y5:+50B#^`*+=0Q3="N#Z`%T2(L*BQ:+642+0D0YPW5JBT(H.4$H=$`/ +XMG<`/MM"-5!+_6XG07EW#W480W4(0V=BZZ____ +XM_Y#KV(M"&#E&&'7&ZZZ-="8`BX((`@``,=(Y@0@"``!UL.NXW=C=V.N2N@$` +XM``"-=@#KJ(/[_[K_____=)Z#^/^Z`0```'24.<,9TH/*`>N+D%6)Y593@^P0 +XMBQT```4(A=MT*8M%"(LPZPV-M"8`````BQN%VW05BT,(BP")="0$B00DZ*W; +XM__^%P'7E@\00B=A;7EW#C;8`````C;\`````58GE@^P8H3@0!0C'1"04L-L$ +XM",=$)!!\W00(QT0D#,#=!`C'1"0(X-T$",=$)`2_VP0(B00DZ-G8___'!"0! +XM````Z$W<__^)]HV\)P````!5B>575HG64X'L'`0``(F%[/O__P^V`H3`#X2N +XM`0``D`^^V(E<)`3'!"3,VP0(Z$':__^%P'0,@\8!#[8&A,!UWS';B5PD!(V= +XM]/O__\<$)-';!`CH&]K__X7`='C&`P"+E>S[__^-A?3[__^)1"0$B10D_U(, +XMZQH/OMB)7"0$QP0DS-L$".CIV?__AVZ43___^+A>S[ +XM__^)="0$B00D_U`,#[8&A,`/A5C^___IT/[__XN5[/O__XV%]/O__XE$)`2) +XM%"3_4@P/M@:$P`^%,O[__^FJ_O__C;8`````C;PG`````%6)Y5.)RX/L%(L- +XMJ!`%"(E,)`B+$HE4)`2+%6`0!0B)%"3_T(M5"(E<)`2)5"0(B00DZ"G<__^# +XMQ!1;7<.-=@!5B>53B<.#[`3'0`0`````QT`(`````,<``````(M`%(7`=`B) +XM!"3H*-K__\=##`````#'0Q``````QT,4`````(/$!%M=PXGVC;PG`````%6) +XMY8/L&(E=^(G#B77\BT`$@\`!C30`B?`/KT,(B40D!(M#%(D$).A8U___A575E.!['P,``"+70S&A93W__\`QH64 +XM\___``^V`SPO#X1(`@``/&,/A!("``"-A93[__^_%]P$",=$)`@`!```QT0D +XM!!'N0,```#SIKX$W`0(C7V4#Y?"#Y+`.,(/ +XMA"W^___IQ/W__XUT)@"%VW26# +XM["B)7?2+70R)=?B+=0B)??R`.P!U)L<$)$C>!`CHCM/__S'`QP5T$`4(`0`` +XM`(M=](MU^(M]_(GL7<.0Z*_3___'``````"-1?#'1"0("@```(E$)`2)'"3H +XM@M/__XG'BT7P@#@`=$6)7"0(BT80QP0DKMP$"(E$)`3H,=/__^ALT___QP`B +XM````Z&'3__^#.")T:(L6.U8$?7*+1A2)/)"-0@&)!K@!````ZX&%_WBW.<-T +XMLXVT)@````#H+]/__XL0A=)U"('_GX8!`'Z[B5PD"(M&$,<$)+W6#[#B)=?B+=0R)??R+?0B)7?2`/@!T)HDT).AR +XMU/__@_@0=DF)="0(BT<0QP0D:MP$"(E$)`3H5M+__^L3BT<0QP0D3-P$"(E$ +XM)`3H0=+__\<%=!`%"`$````QP(M=](MU^(M]_(GL7<.-="8`Z%_2___'```` +XM``"-1?#'1"0("@```(E$)`2)-"3HPM'__XG#Z#O2__^+"(7)=0B+1?"`.`!T +XM/,=%X.')^.AQ^?__BP_KX(D<).AYT/__QT7@SMP$"(7`B<-UQ.NTBT7@B70D +XM#(E$)`B+1Q#'!"3GW`0(B40D!.A\T?__Z3;___^-=@"-3"0$@^3P_W'\58GE +XM5U9348'L"`L``(L!BTD$QT0D!,[;!`C'!"0`````B844]?__B8T0]?__Z.C2 +XM___'!"20$`4(Z#S/___'!"3UW`0(Z'#/__^%P'0)@#@`#X6U"P``C5WDB5PD +XM",=$)`1H=`A`QP0D`0```.CHS___@\`!#X3/#0``#[=%YF:%P`^%E0(``,<% +XMJ!`%"$\```"#O13U__\!#XXG`0``BY40]?__BXT0]?__B[T0]?__@\($B948 +XM]?__BTD(B8T<]?__BW<$#[8^B?B$P'0UB?*0C70F``^^P(G3B40D!,<$)&S> +XM!`CH']#__X7`=`J`>`$Z#X2$"@``#[9#`8U3`83`==(QVXDT).A%+/7__P`` +XM``#'A3#U__\`````QX5`]?__`````,>%1/7__P````#'A4SU__\`````QX4D +XM]?__(=T$",>%2/7_______^)]HN5$/7__XN-%/7__\=$)`ALW@0(B50D!(D, +XM).A$SO__@_C_#X1@`P``@^A!/#=V%^@K\___Z\D/M\"#Z`&CJ!`%".EE_?__ +XM#[;`_R2%O-X$"(.%0/7__P''A2SU__\!````QX5(]?__`0```.N2QP0D```` +XM`.@JSO__A<"CW`,%"`^$8PP``(L5W`,%"(V%5/___^@8\___@X5`]?__`<>% +XM3/7__P$```#I4O___\=$)`0`````QP0DP``%".A>U/__QP5<$`4(`@```,8% +XMP``%"`#'A3#U__\!````Z1[___^%VP^$3@@``,<%J!`%"`````"#PP'I!/__ +XM_\=$)`0`````QP0D``$%".@0U/__QP5<$`4(`0```,8%``$%"`#'A3#U__\! +XM````Z=#^___'!5P0!0@"````Z<'^__^+%=P#!0B-19SH8_+__X.%0/7__P'I +XMI_[__Z'<`P4(QT0D!`$```")!"3HLM/__\>%,/7__P$```#I@_[__\<%7!`% +XM"`$```#I=/[__\=$)`0`````QP0D8``%".B`T___Q@5@``4(`,>%,/7__P$` +XM``#I2O[__\=$)`0`````QP0D(``%".A6T___Q@4@``4(`,>%,/7__P$```#I +XM(/[__P^W1>3'A43U__\6````9H/X!0^&"/[__P^WP(F%1/7__^GZ_?__Z$G. +XM__^%P`^%T@@``,<%6!`%"`$```#IWOW__\<%;!`%"`$```#IS_W__\<%E!`% +XM"`$```#IP/W__X.%0/7__P''A2SU__\!````Z:K]___'1"0$`````,<$)#\! +XM!0CHMM+__\8%/P$%"`#IBOW__\>%2/7__P````#I>_W__XL5W`,%"(V%//__ +XM_^@:\?__@X5`]?__`<>%3/7__P$```#I5/W__\<%F!`%"`$```#I1?W__\=$ +XM)`0!````QP0DGP`%".A1TO__H=P#!0C'1"0$`0```(D$).@\TO__QT0D!`$` +XM``#'!"2C``4(Z"C2___&!:,`!0@`Q@6?``4(`,>%,/7__P$```#IZ_S__Z'< +XM`P4(B84D]?__Z=O\__^+/=P#!0B)O2CU___IROS__^A5T?__QP0D`````.BM +XMS/__QP6,$`4($````.FJ_/__BQ7<`P4(C47,Z$SP__^#A4#U__\!QX5,]?__ +XM`0```.F&_/__QP6@$`4(`0```.EW_/__H3P0!0B+O1#U__^#/6P0!0@!C02' +XMB84(]?__#X07"```BX4(]?__BQB%VW1/#[8#@_A_#X=5"P``]@2%%00%"`2+ +XMM0CU__]U(NE`"P``#[8#@_A_#XR)1"0,H6`0!0C'1>S_____B50D"(E, +XM)`2)!"3HU,O__X7`B84@]?__#X21`P``BT7L@_@`#XPW!0``#XZ*`P``:\`< +XMB00DZ,G*__^%P*-D$`4(#X0[`P``BT7LB84T]?__@^@!#XA@`P``QX4\]?__ +XM`````,>%7/7__P````")]HM=G(7;?AZ+E2#U__\QP(M**(M5L#L,@@^$6@$` +XM`(/``3G8=?"+A4CU__^%P'4=BXT@]?__@WE$_P^$$0$``/:!*`$```(/A`0! +XM``"+A4#U__^%P`^$'@$``(M=S(7;?B&+O2#U__\QP(M5X(N/E````#D,@@^$ +XM_0```(/``3G8=?"+7;2%VWX>BX4@]?__BU7(BT@P,<`Y#((/A-@```"#P`$Y +XMV'7PBUV$A=M^(HN5(/7__S'`BXJ,````BU68D#L,@@^$KP```(/``3G8=?"+ +XMG6S___^%VWX>B[T@]?__,<"+58"+3S@[#((/A(<```"#P`$YV'7PBYU4____ +XMA=M^'8N%(/7__XN5:/___XM(1#'`.0R"=&"#P`$YV'7TBYT\____A=M^)XN5 +XM(/7__S'`BXJ(````BY50____.PR"=#:#P`$YV'7TC;0F`````(.%7/7__P&+ +XMC33U__\YC5SU__\/A.L!``"!A2#U__\``P``Z8C^__]KO3SU__\[__XD$).BYQ?__B4<$BU\$A=L/A.H```"+#6P0!0B%R0^%F````,=' +XM"`````")]HLU```%"(7V=0SK0HUT)@"+-H7V=#B+7@CV0PP(C78`=.Z)/"3_ +XM4Q0/MU,8B<$/O\(YP7X&B%0/7__P````#I +XMG?K__XET)`2)/"3H2,;__^EQ]/__H6`0!0B)!"3H9L3__\=$)`3+W`0(QP0D +XM`0```(E$)`CH3L/__\<$)`0```#H%0/7__P````#IN_?__SM"&`^-7/___XE4)`3'!"0@````Z'G" +XM___I4?___Z'8`P4(A<`/A10!``"+%300!0B+0@B#Z`&%P(E""`^(<@$``(L" +XMQ@`*@\`!B0*+A43U__^%P'09BY4,]?__.94X]?__#X3Q````@X4X]?__`8/' +XM`8/&'#N]//7__P^%N?[__XU%S.@UZ/__C46C__XU%A.@= +XMZ/__C85L____Z!+H__^-A53____H!^C__XV%//___^C\Y___H:00!0B)!"3H +XM\\'__XV";P$``(E$)`B-1P3'1"0$6-T$"(D$).C&P?__Z6OY__^)P8M%L(/) +XM`8L0QX5`]?__`````.FQ]O__B<&+18"#R0.+$,>%0/7__P````#IF/;__XG! +XMBX5H____@\D$BQ#'A4#U__\`````Z7SV__^A-!`%",<$)`H```")1"0$Z'Z^ +XM___I\_[__XL=V`,%"(7;#X6_````BQ4T$`4(BT((@^@!A<")0@@/B),```"+ +XM`L8`"H/``8D"Z''=___'A3CU__\`````Z=/^__^)7"0(QT0D!,O]___I2/___Y"0D)"0D)"0D)"0D)"058GE5U:#[#"+11"+512+=0B+ +XM?0R)1>R)P8E5Z(M%Z,=%T`````#'1=0`````B?J)=>2%P(EU\(E]X'44.?EV +XM8(GP]_&)5=#'1=0`````ZQ"+3>`Y3>AV&(EUT(E]U(GVBT70BU74@\0P7E]= +XMPXUV``^]1>B#\!^)1=AU1HM%Z#E%X`^'R0```(M-[#E-Y`^#O0```(M-\(E5 +XMU(E-T.O!D(M%[(7`=0RX`0```#'2]W7LB<&+1>"+5>CW\8M%Y/?QZX*X(``` +XM`(M5["M%V(MU[(M]Y(G!B47@/MDW8T^`)PHM%Y-/F#[9-W(E5](M5 +XMX-/H#[9-V-/B"="+5>#3YP^V3=S3ZO=U](E5S/?F.57,575H/L((M% +XM$(M5%,=%X`````"+=0S'1>0`````B47TB<&+10B%THG7B47L=2,Y\0^&F``` +XM`(GR]_&)P3'`B4W@B47DBT7@BU7D@\0@7E]=PSGR#X>U````#[W"@_`?B47H +XM#X26````N"````"+5?0K1>B)P=/J#[9-Z(E%\(GXBWWTT^`)PHM%[-/G#[9- +XM\(E5W(GRT^@/MDWHT^(/MDWP"=#3[HGR]W7P/MDWHT^`YQG:'BTW8,<"#Z0'I^O[_ +XM_Y"0D)"0D)"0D)!5B>53@^P$H90"!0B#^/]T$C';_]"+@Y`"!0B#ZP2#^/]U +XM\(/$!%M=PY"0D(/L#.@\O___@\0,PR1&@!64UH`>'-T870`6%-4050```!N;R!V86QI9"!K97EW +XM;W)DF5R;RUL96YG=&@I("5S(&YA;64`)7,@;F%M92!T;V\@ +XM;&]N9SH@)7,`3F\@)7,@;F%M960@)R5S)P!.;R`E`````4```"C +XMV@0(`````)C7!`AAV00(``````````#@I`0(``````@```!H````!0```*/: +XM!`@`````2-<$"&G9!`@``````````."D!`@`````"````%@````%````H]H$ +XM"`````!QV00(=-D$"``````0````X*0$"``````#````!`$```4```#,V@0( +XM``````?8!`@-V`0(``````8```"@JP0(``````<````````````````````` +XM````$]H$",[;!`AWV00(```````````````````````````````````````` +XM``!WV00(&=H$"```````````0*$$"``````$```````````````````````` +XM`'W9!`B#V00(``````````#@I`0(``````4```"8````!0```/W:!`@````` +XMB=D$"(_9!`@``````````."D!`@`````!0```)`````%````_=H$"`````"5 +XMV00(FMD$"```````````,*8$"``````$`````````````````````````)_9 +XM!`BEV00(``````(```#@H@0(`````!,`````````````````````````>]<$ +XM"*O9!`@`````!````("I!`@`````"0````````````````````````"PV00( +XMMMD$"```````````X*0$"``````$````-`````4```#,V@0(`````+S9!`C! +XMV00(``````````#@I`0(``````4````\````!0```,S:!`@`````QMD$",O9 +XM!`@``````````."D!`@`````!````.P````)````D-H$"`````#0V00(T]D$ +XM"```````````<*T$"``````$`````````````````````````!SBPE8W!U+"5M +XM96TL8V]M;6%N9`!L86)E;`!P:60L='0LI($"(J2!`B:D@0( +XMJI($"+J2!`C*D@0(VI($".J2!`CZD@0("I,$"!J3!`@JDP0(.I,$"$J3!`A: +XMDP0(:I,$"'J3!`B*DP0(FI,$"*J3!`BZDP0(RI,$"-J3!`CJDP0(^I,$"`J4 +XM!`@:E`0(*I0$"#J4!`A*E`0(6I0$"&J4!`AZE`0(BI0$")J4!`BJE`0(NI0$ +XM"``D1G)E94)31#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#

7=O6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O +XM9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]Ftcsh.uu << 'END-of-tcsh.uu' +Xbegin 755 tcsh +XM?T5,1@$!`0D```````````(``P`!````(*0$"#0```"HVP0``````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(7)\$ +XM`%R?!``%`````!````$`````H`0``"`)"``@"0AT,0``](P"``8`````$``` +XM`@```$#.!`!`3@D(0$X)"-@```#8````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&0PGP0`,!\)"#`?"0@L````+`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`@P```*`````(``````````````"9````.0````````!1```` +XME@````````"#````G````',```",````2@```%X`````````4@````````") +XM````E```````````````<@```)\```!G`````````'H```!F````C@```$X` +XM``"'````%`````0`````````1`````,`````````#@```$(```"&````=P`` +XM````````````%P```)L```"-````-`````````!D`````````)X````````` +XM*P````````!V````;`````````!-````DP````````!%````?@```#L````` +XM````D0`````````W````````````````````)0````````!P`````````#`` +XM``!A````BP`````````V````20````````!M````E0````````!?````?0`` +XM`&D`````````:P````````!0````8@```'\````M````>``````````````` +XM``````````!6`````````&\```""````:@```)@```!&````,@````````!U +XM````6P````````":````3````(H````*````A0```````````````````)`` +XM``!8````;@```)T````8`````````(0```"2````5P```(`````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM````$0````8```````````````````````````````$``````````@`````` +XM```>````````````````````#```````````````)@````<````I```````` +XM```````G`````````"X````<`````````"`````C```````````````-```` +XM+P`````````D````%@``````````````````````````````/0````4````H +XM`````````#4````9````00``````````````````````````````$P```$@` +XM`````````````````````````````````````````````#H````````````` +XM`$`````X`````````!`````)````7````"(````_````&@````````!@```` +XM`````````````````````&@`````````5````"$```!9`````````!(````` +XM```````````````=``````````\````;````+`````````!Q`````````$<` +XM```Q``````````````!Y````8P``````````````6@```!4```!\````*@`` +XM````````````B````$L`````````=`````L```"!`````````!\```!#```` +XM,P```&4```![`````````$\```!3````70```#P`````````CP````````"7 +XM````50```#X`````````````````````````I`0````````S````$@```)$$ +XM````````,P```!(```"T`@```````$,````2````$0````````"U````$@`` +XM`(P"`````````````!(```"2`@```````"L````2````RP,````````R```` +XM$@```&\!````````*````!(```"Y`@`````````````2````2@$````````` +XM````$@```#0!````````:P$``!(```#K!````````#@````2````:0$````` +XM``#]"```$@```!D```!`3@D(`````!$`\?_W`@`````````````2````I0(` +XM````````````$@```"(`````````U`,``!(```"#`0```````#,````2```` +XMU`0`````````````$@```'L"````````(P```!(````+!0`````````````2 +XM````$@0````````=````$@```#0#`````````````!(````K`0```````!T` +XM```2````B@0`````````````$@````,"````````5P```!(```#(```````` +XM`#D````2````?@$``,"N!@C>!```$@`,`"`#````````E````!(```#(`@`` +XM`````#D````2````100`````````````$@```"@`````````E@```!(```"2 +XM`0`````````````2````80(```````!S````$@```.$!``"`40D(!````!$` +XM%P#:```````````````2````?0,````````<````$@```#L!```````````` +XM`!(````'!``````````````2````!P$```````!/````$@```.0$```````` +XM<@```!(```#!`P````````4````2````"P0```````!.!0``$@```%P#```` +XM````W0,``!(```#!```````````````2````(@(```````#8````$@```#$` +XM```(FP0(`````!(`"@!)`@`````````````2````HP,`````````````$@`` +XM`+`#````````,P$``!(````-`@`````````````2````M@$````````+```` +XM$@```&\$````````*@```!(```";```````````````2````X``````````` +XM````$@```)<"``#8=0D(!````!$`%P!#`P```````$T````2````2P,````` +XM````````$@```+,"````````*P```!(```#$!``````````````2````YP`` +XM``````#&!```$@```"P#````````(0(``!(```#9`0```````!4"```2```` +XM`P`````````````2````9@0```````!9 +XM````$@```%(#`````````````!(```"0`P`````````````2````=P,````` +XM```[````$@```!0#````````>````!(```#"`0```````$P````2````10`` +XM`/RP"`@`````$@`-`,X"````````C`(``!(```#:`@```````!`````2```` +XM_0(````````E`0``$@```/X#````````'0```!(```#:!````````.T````2 +XM````0@$`````````````$@```#X#`````````````!(```!D`P``X%T)"`0` +XM```1`!<`^P`````````E````$@```",!`````````````!(````\`@`````` +XM`&<````2````[@$```````!?````$@```)X$`````````````!(```!*!``` +XM,*<&"&,````2``P`%0(````````_````$@```)\$````````0P```!(```"H +XM`0```````,,````2````J@(```````!4````$@```!<%``!T40D(`````!`` +XM\?_0```````````````2````EP,```````!#````$@```*\!````````,P`` +XM`!(```!W`0`````````````2````2P```"Q/"0@`````$0#Q_QL$```````` +XM@0```!(````J!0``]*P+"``````0`/'_``4`````````````$@```(`$```` +XM````5P```!(````N!````````&(#```2````]0$```````!A````$@```$X$ +XM````````DP```!(```"7`0`````````````2````)P0````````K````$@`` +XM`&(!`````````````!(```"K!````````!P````2````M`0````````````` +XM$@```$0$`````````````!(````;`0`````````````2````RP0```````"C +XM````$@```.<#````````4@```!(````;`P`````````````2````>`0````` +XM````````$@```!`!````````B@```!(```"Z```````````````2````4P0` +XM``````#($0``$@```&$``````````````"````#+`0```````(H````2```` +XMOP(```````!,````$@```(D!`````````````!(````\`P```````"@````2 +XM````=0`````````4`0``$@```(("`````````````!(```"?`@`````````` +XM```2`````&QI8FYC=7)S97,N@<```(`+P4```````"`40D(!2,``(A1"0@%20`` +XMW%T)"`5?``#@70D(!7(``#A/"0@'`0``/$\)"`<"``!`3PD(!P,``$1/"0@' +XM!```2$\)"`<%``!,3PD(!P8``%!/"0@'!P``5$\)"`<(``!83PD(!PD``%Q/ +XM"0@'"@``8$\)"`<+``!D3PD(!PP``&A/"0@'#0``;$\)"`$\)"`<2``!\3PD(!Q,``(!/"0@'%```A$\)"`<5``"(3PD( +XM!Q8``(Q/"0@'%P``D$\)"`<8``"43PD(!QD``)A/"0@'&@``G$\)"`<;``"@ +XM3PD(!QT``*1/"0@''@``J$\)"```"04`D(!V```)10"0@'80`` +XMF%`)"`=B``"<4`D(!V,``*!0"0@'9```I%`)"`=E``"H4`D(!V8``*Q0"0@' +XM9P``L%`)"`=H``"T4`D(!VD``+A0"0@':P``O%`)"`=L``#`4`D(!VT``,10 +XM"0@';@``R%`)"`=O``#,4`D(!W```-!0"0@'<0``U%`)"`=S``#84`D(!W0` +XM`-Q0"0@'=0``X%`)"`=V``#D4`D(!W<``.A0"0@'>0``[%`)"`=Z``#P4`D( +XM!WL``/10"0@'?```^%`)"`=^``#\4`D(!W\```!1"0@'@```!%$)"`>!```( +XM40D(!X,```Q1"0@'A0``$%$)"`>&```440D(!X<``!A1"0@'B```'%$)"`>) +XM```@40D(!XH``"11"0@'BP``*%$)"`>,```L40D(!XT``#!1"0@'C@``-%$) +XM"`>/```X40D(!Y```#Q1"0@'D0``0%$)"`>2``!$40D(!Y,``$A1"0@'E``` +XM3%$)"`>5``!040D(!Y8``%11"0@'EP``6%$)"`>9``!<40D(!YH``&!1"0@' +XMFP``9%$)"`><``!H40D(!YT``&Q1"0@'G@``<%$)"`>?``"#[`SHX`D``.B[ +XM%00`@\0,PP```/\U,$\)"/\E-$\)"`````#_)3A/"0AH`````.G@_____R4\ +XM3PD(:`@```#IT/____\E0$\)"&@0````Z<#_____)41/"0AH&````.FP____ +XM_R5(3PD(:"````#IH/____\E3$\)"&@H````Z9#_____)5!/"0AH,````.F` +XM_____R543PD(:#@```#I````.GP_O___R5X3PD(:(````#IX/[___\E?$\)"&B(````Z=#^____ +XM)8!/"0AHD````.G`_O___R6$3PD(:)@```#IL/[___\EB$\)"&B@````Z:#^ +XM____)8Q/"0AHJ````.F0_O___R603PD(:+````#I@/[___\EE$\)"&BX```` +XMZ7#^____)9A/"0AHP````.E@_O___R6<3PD(:,@```#I4/[___\EH$\)"&C0 +XM````Z4#^____):1/"0AHV````.DP_O___R6H3PD(:.````#I(/[___\EK$\) +XM"&CH````Z1#^____);!/"0AH\````.D`_O___R6T3PD(:/@```#I\/W___\E +XMN$\)"&@``0``Z>#]____);Q/"0AH"`$``.G0_?___R7`3PD(:!`!``#IP/W_ +XM__\EQ$\)"&@8`0``Z;#]____)!/"0AH4`$``.E`_?___R7D3PD( +XM:%@!``#I,/W___\EZ$\)"&A@`0``Z2#]____)>Q/"0AH:`$``.D0_?___R7P +XM3PD(:'`!``#I`/W___\E]$\)"&AX`0``Z?#\____)?A/"0AH@`$``.G@_/__ +XM_R7\3PD(:(@!``#IT/S___\E`%`)"&B0`0``Z<#\____)010"0AHF`$``.FP +XM_/___R4(4`D(:*`!``#IH/S___\E#%`)"&BH`0``Z9#\____)1!0"0AHL`$` +XM`.F`_/___R444`D(:+@!``#I%`)"&B``@``Z>#Z____)7Q0"0AHB`(``.G0^O___R6`4`D(:)`"``#I +XMP/K___\EA%`)"&B8`@``Z;#Z____)8A0"0AHH`(``.F@^O___R6,4`D(:*@" +XM``#ID/K___\ED%`)"&BP`@``Z8#Z____)910"0AHN`(``.EP^O___R684`D( +XM:,`"``#I8/K___\EG%`)"&C(`@``Z5#Z____):!0"0AHT`(``.E`^O___R6D +XM4`D(:-@"``#I,/K___\EJ%`)"&C@`@``Z2#Z____):Q0"0AHZ`(``.D0^O__ +XM_R6P4`D(:/`"``#I`/K___\EM%`)"&CX`@``Z?#Y____);A0"0AH``,``.G@ +XM^?___R6\4`D(:`@#``#IT/G___\EP%`)"&@0`P``Z<#Y____)<10"0AH&`,` +XM`.FP^?___R7(4`D(:"`#``#IH/G___\ES%`)"&@H`P``Z9#Y____)=!0"0AH +XM,`,``.F`^?___R744`D(:#@#``#IA0"0AH8`,``.D@^?___R7L4`D(:&@#``#I$/G___\E\%`)"&AP`P``Z0#Y +XM____)?10"0AH>`,``.GP^/___R7X4`D(:(`#``#IX/C___\E_%`)"&B(`P`` +XMZ=#X____)0!1"0AHD`,``.G`^/___R4$40D(:)@#``#IL/C___\E"%$)"&B@ +XM`P``Z:#X____)0Q1"0AHJ`,``.F0^/___R4040D(:+`#``#I@/C___\E%%$) +XM"&BX`P``Z7#X____)1A1"0AHP`,``.E@^/___R4<40D(:,@#``#I4/C___\E +XM(%$)"&C0`P``Z4#X____)211"0AHV`,``.DP^/___R4H40D(:.`#``#I(/C_ +XM__\E+%$)"&CH`P``Z1#X____)3!1"0AH\`,``.D`^/___R4T40D(:/@#``#I +XM\/?___\E.%$)"&@`!```Z>#W____)3Q1"0AH"`0``.G0]____R5`40D(:!`$ +XM``#IP/?___\E1%$)"&@8!```Z;#W____)4A1"0AH(`0``.F@]____R5,40D( +XM:"@$``#ID/?___\E4%$)"&@P!```Z8#W____)511"0AH.`0``.EP]____R58 +XM40D(:$`$``#I8/?___\E7%$)"&A(!```Z5#W____)6!1"0AH4`0``.E`]___ +XM_R5D40D(:%@$``#I,/?___\E:%$)"&A@!```Z2#W____)6Q1"0AH:`0``.D0 +XM]____R5P40D(:'`$``#I`/?__P````!5B>564X/L$(/D\(M=!(G1C72=#(7; +XMB378=0D(?C:+10B%P'0OHP`@"0@/MA"$TG0C@\`!ZPH/MA"#P`&$TG04@/HO +XM=?&C`"`)"`^V$(/``832=>RX0$X)"(7`=#2)#"3H5_[__\<$)/RP"`CH2_[_ +XM_^AR]O__C44(B70D"(E$)`2)'"3HYQL``(D$).A+_?__Z-;X___KS9"0D)"0 +XMD)"058GE@^P(@#WD70D(`'0,ZQR#P`2C""`)"/_2H0@@"0B+$(72=>O&!>1= +XM"0@!R<.058GE@^P(H2A/"0B%P'02N`````"%P'0)QP0D*$\)"/_0R<.0D)"0 +XMD)"0D)"0D)"058GE@^P8Z%77``#'!>AV"@@`````QT0D!!````#'!"0````` +XMZ->``0"CM'8*",=$)`@!````QT0D!`(```")!"3HUO;__\=$)`01````QP0D +XM`0```.BF@`$`H\R7"@C'1"0(`0```,=$)`0"````B00DZ*7V___'1"0$$@`` +XM`,<$)`(```#H=8`!`*,$=@H(QT0D"`$```#'1"0$`@```(D$).AT]O__QT0D +XM!!,```"AM'8*"(D$).A#@`$`HT29"PC'1"0(`0```,=$)`0"````B00DZ$+V +XM__^A!'8*"(D$).A%_/__H_R9"PBAS)<*"(D$).@S_/__H^!U"0C)Z3S7``"- +XMM@````"-OP````!5B>6#[`B+10B+$(72=23'1"0$Q)@*",<$))`O"0CHO>`! +XM`#WX;PD(=!6)10C)Z0WP`P")!"3HY9\#`(7`=>O),<##C;8`````C;PG```` +XM`%6)Y5=64X/L'(MU"(-^"/\/A%@!``"+/;AW"@BAO'<*",<%N'<*"`````#' +XM!;QW"@@`````A?^)1?!^&3';B?:+5?"+!)J#PP&)!"3H7X,#`#G[=>N+1?") +XM!"3H4(,#`(U&3,=$)`@D(```B40D!,<$)*!W"@CH8?O__Z&T=@H(B00DZ!A[ +XM`0"+!J/\70D(BT8(H[1V"@B#?@3_=!6A1)D+"(D$).CV>@$`BT8$HT29"PB# +XM?@S_=!6AS)<*"(D$).C;>@$`BT8,H\R7"@B#?A#_=!6A!'8*"(D$).C`>@$` +XMBT80HP1V"@B+1B"CD'8*"(M&-*.\F`H(BT8DHTB:"PB+1BBC2'<*"(M&+*.T +XMF`H(BT8PHS"9"PB+1A2CP'8*"(M&&*/@F0L(BT87UW#HXR8"@CKNHM&0(7`=.J+"(7)=.3'1"0$Q)@*",<$ +XM)"0V"0CHDMX!`(7`=,S'10@D-@D(@\0<6UY?7>EKX`$`C70F`(V\)P````!5 +XMB>575E.!["P!``"A+)H+"(L5*)H+"(F%'/___Z$DF@L(B948____BQ4@F@L( +XMB844____H1R:"PB)E1#___^+%1B:"PB)A0S___^A%)H+"(F5"/___XL5$)H+ +XM"(F%!/___Z$,F@L(B94`____BQ4(F@L(B87\_O__H02:"PB)E?C^__^+%0": +XM"PB)A?3^__^)E?#^___H-7,``(,%`%X)"`&)A>3^___'!"0`F@L(Z,CT___H +XM=YP!`*'L70D(HW!V"@BAP)@*"(7`=!R+10B%P`^$V@$``,<%P)@*"`````#H +XMJGT!`.O`H?R8"@B%P`^%^P,``*&,=@H(A"0B% +XMP'02B00DZ*F``P#'!8!>"0@`````H91W"@B%P`^%8@(``,<$)'AV"@CHMFT! +XM`(G#H91W"@B%P`^%-P(``,=$)`20Z04(QP0D>'8*".CC=0``A=MT#:&`7@D( +XMA<`/A!,#``#'1"0$Q)@*",<$)&`R"0CHOMP!`(7`=#N+'>AV"@C'!<"8"@@! +XM````QP7H=@H(`````,<$)'AV"@CH9%$!`.C/C@$`QP7`F`H(`````(D=Z'8* +XM",<$)`````#H?_?__Z'L70D(QP7(K`L(`0```(7`#X5L`0``BTT(A"9"PB%_P^$*@$``(`]B)@*"`!T#X,]@%X)"`$9P"`%B)@* +XM"(L-[%T)"(7)=1N+%8!>"0B%TG01QP0D````0.@5<@``D(UT)@"A<'8*"(7` +XM=2>A\%T)"(7`#X1*`0``QT0D!`````#'!"1X=@H(Z,:6``"-M@````#'!"1X +XM=@H(Z"1T``#I]_W__XN%Y/[__\<%_)@*"`````")!"3HMW,``(N5'/___XN% +XM&/___XD5+)H+"(N5%/___Z,HF@L(BX40____B14DF@L(BY4,____HR":"PB+ +XMA0C___^)%1R:"PB+E03___^C&)H+"(N%`/___XD5%)H+"(N5_/[__Z,0F@L( +XMBX7X_O__B14,F@L(BY7T_O__HPB:"PB+A?#^__^)%02:"PBC`)H+".@(<0`` +XMZ7K]__^+-?!="0B%]@^%R/[__XL=3)H+"(7;#X6Z_O__C;0F`````(/H`0^? +XMP`^VP(E$)`3'!"1X=@H(Z/0#`.F._?__QP0D>'8*".A4C`$`H80@ +XM"0B%P`^%Z`$``*&`=@H(QT0D"`````#'1"0$>'8*"(D$).BZB`$`QT0D!$`K +XM!@B)PXD$).A8"0B%P'0,QP0D````0.A3<```Z!ZN`P"AU)<*"#'2 +XMQT0D$`$```#'1"0,`````,=$)`@`````A<`/G\*#Z@$)T(E$)`2)'"3H";T! +XM`*&TF0L(A<`/A4P!``"+10B%P'05BSW`=@H(A?\/A1L!``"-M"8`````QT0D +XM"`8```#'1"0$`'8)",<$)'0O"0CH%.,!`.GO_?__BSW`=@H(A?\/A-_\__^+ +XM-?!="0B%]@^%T?S__X`]B)@*"``/A<3\__^+'>"9"PB%VP^%MOS__^G)_/__ +XMC78`BY7D_O__QP7\F`H(`````(,M`%X)"`&)%"3H<7$``(N%'/___XN5&/__ +XM_Z,LF@L(BX44____B14HF@L(BY40____HR2:"PB+A0S___^)%2":"PB+E0C_ +XM__^C')H+"(N%!/___XD5&)H+"(N5`/___Z,4F@L(BX7\_O__B140F@L(BY7X +XM_O__HPR:"PB+A?3^__^)%0B:"PB+E?#^__^C!)H+"(D5`)H+"('$+`$``%M> +XM7UW#BS7@F0L(A?8/A=[^__^+'?!="0B%VP^%T/[__\<$)`````#HI/L"`.F_ +XM_O__QP0D>'8*".CCF0,`H80@"0B%P`^$__W__\<$)'AV"@CH*IX#`.GN_?__ +XMQP4X=PH(`````,=$)`3$F`H(QP0DJ$`)".A7V`$`A<")PP^$=0(``(L0A=(/ +XMA&L"``"-1>R)!"3HU.S__XL;B1PDZ$YO`0"%P(F%[/[__P^%T@(``+A8`@`` +XM`P4,7@D(.T7L#X\T`@``BP.%P`^$(@(``(G?Z;$```"+1;P+1<`/A)<```"+ +XM1:0YP@^,C````(L-#%X)"#G(?P0YRGY^H329"PB%P`^%N0(``(7;N$7)"`@/ +XMA;0"``")!"3HU'@!`,=$)`0P*@@(B<.)!"3HHG```(.][/[__P$/A.T"``"A +XM@)@*",=$)`RDL0@(QT0D"`<```#'1"0$"P```(D$).@@SP``B70D"(E<)`2) +XM!"3HL,@#`(D<).BX;P``BT<$@\<$A<`/A&H!``")!"3H(ND#`(U5C(E4)`2) +XMQHD$).BM[___A"0B#P`$Y +XMT`^-2P$``*$TF0L(A<`/A38!``")#"3H(^___XN5(/___XD4)(G#Z`=Z`P"% +XMVP^$)____XD<).AS\O__A<`/A!?___^)'"3H8_+__\>%Z/[__P````"%P'40 +XMZ?S^__^-="8`@X7H_O__`8D<).@]\O__AC^__^)="0(B50D!(D$).@WQP,`Z8K^__^)]HM%[*,,7@D(QP0D```` +XM`.@L[P,`Z&?8`P#HHJ8#`(GVZ'NJ`P"+%:1W"@B+#;1W"@BAH'<*"#,%L'<* +XM"#'1"<%T%NC9AP$`QP0D`0```.A-G@,`Z4[X__^#/=`D"0@"=>''1"0$```` +XM`,<$)`````#HZ]4#`.O+A=L/A<+^__^+A2#___^)!"3HTW@#`.GV_?__BP.) +XM!"3H9'@!`(7`B?8/A!K]__^#K>S^__\!BP.#PP2)!"3HEM,!`(7`#X\#_?__ +XMN`$```#I^?S__XUT)@"%VP^$L/W__Z&`F`H(QT0D#(VQ"`C'1"0(!@```,=$ +XM)`0+````B00DZ)/,``#I(OW__XU5C#';C84L____B10DQT0D"&````")1"0$ +XMZ&OP__^+5:P[%:B9"PB+C2#___\/G\/I[/W__Z&`F`H(QT0D#)*Q"`C'1"0( +XM!0```,=$)`0+````B00DZ#/,``")7"0$B00DZ,?%`P#I$OW__Z&`F`H(QT0D +XM#'&Q"`C'1"0(`P```,=$)`0+````B00DZ/W+``"+E>C^__^)5"0$B00DZ(O% +XM`P#IWOS__XVV`````%6)Y5>)SU:)UE.![%PA``#'1"0$`````(D$).A@;0$` +XM,=*#^/\/A`\#``"-7?")1?")'"3'1"0$0!X%".CO;```BT7PQT0D!/____^) +XM!"3HG',!`(D<)(E%\.B!;```B1PDZ"EL``"+1?#'1"0(`0```,=$)`0"```` +XMB00DZ#KI__^+7?"Z`0```(7;#XBH`@``A?;'A________=!>-19")1"0$ +XMB1PDZ-WP__^%P`^(A00``(V%P-[__\=$)`2`I@0(B00DZ&-L``"+#91W"@B% +XMR0^%!00``*'\70D(BQ7H=@H(QX70WO_______\>%S-[_______^)A<#>__^A +XMM'8*"(72QX7$WO_______XF%R-[__P^%.@(``*'`=@H(A?^)A=3>__^AX)D+ +XM"(F%V-[__Z%0=PH(B87#>__^A2)H+"(F%Y-[__Z%(=PH( +XMB87HWO__H;28"@B)A>S>__^A,)D+"(F%\-[__Z&\F`H(B87TWO__H>Q="0B) +XMA?C>__\/A;0!``#'A03?__\`````H>R9"PC'1"0()"```,=$)`2@=PH(B84( +XMW___C84,W___B00DZ!;N__^+10B%P'1JBU4(BP*%P'1AQT0D!,28"@C'!"0D +XM-@D(Z$;2`0"%P`^$#@,``(L`A<`/A`0#``")!"3H[',!`(F%_-[__XM%"(D$ +XM).C;%_-[_ +XM_P````"+50B)';1V"@C'!;QW"@@`````QP6X=PH(`````(F5`-___\<%L'<* +XM"`````#'!;1W"@@`````QP6@=PH(`````,<%I'<*"`````#H3S,!`*&T=@H( +XMQP60=@H(`````,<%O)@*"`````")!"3H&NW__X/_`<<%X)D+"`````#'!5!W +XM"@@`````QP5(=PH(`````,<%2)H+"`````#'!3"9"P@`````H\!V"@@9P"$% +XMC)@*"*&4=PH(QP6TF`H(`````(D][%T)",<%_%T)"`$```"%P`^%]0$``,<$ +XM)`````#HF?+__XV%P-[__XD$).A;:0``N@$```"!Q%PA``")T%M>7UW#H8R8 +XM"@B)A03?___I1O[__XUUD(ET)`3'!"0`````Z"+N__^#P`%T9XV%,/___XE$ +XM)`2A1)D+"(D$).@&[O__@\`!=$N+190[A33___\/A-P!``"A1)D+",=$)`3_ +XM____QP0D`````(F%Q-[__^@W<`$`QT0D"`$```#'1"0$`@```*-$F0L(B00D +XMZ.;E__^)="0$QP0D`0```.BF[?__@\`!=&>-A3#___^)1"0$H___HNV\!`,=$)`@!````QT0D!`(```"CS)<*"(D$).AJY?__B70D!,<$ +XM)`(```#H*NW__X/``71IC84P____B40D!*$$=@H(B00DZ`[M__^#P`%T38M% +XME#N%-/___P^$O````*$$=@H(QT0D!/_____'!"0"````B870WO__Z#]O`0#' +XM1"0(`0```,=$)`0"````HP1V"@B)!"3H[N3__XGVZ`MK`0#I0_S__XVV```` +XM`(,%Q*P+"`''1"0$L)`(",<$),2L"PCH-6@``.G;^___QX7\WO__`````.G[ +XM_/__D,<$),2L"PCH=&<``(,%Q*P+"`''1"0$L)`(",<$),2L"PCH^6<``.G? +XM_?__B1PDZ%QJ`0"Z`0```.GL_?__BT60.X4P____#X4U____Z6[___^+19`[ +XMA3#___\/A:7^___IW/[__XM%D#N%,/___P^%%?[__^E,_O__C;8`````58GE +XM5U93@^PD<9@`` +XMQT7P`````.E7____QT0D!#PT"0B)'"3HC./__X7`=>"+7@B-?@C'1?`"```` +XMA=L/A2[____'!"2!```0Z(MC``"+7@C'1?`"````Z1/____'!"1%```0Z'!C +XM``"+7@C'1?`!````Z?C^__^058GE4X/L%*&4=PH(BUT(AGW8@``C;0F`````*'`=@H( +XMA"0@`QP0D``````^4PC')Z+/W__^)'"2)QN@Y9```@\00B?!;7EW#BT@$ +XMAR+-S'`A?9T5HU?!,=%\`````#K#Y") +XMW\=#_#H```"+,X/#!(/^.G0$A?9U\L=#_`````"+!X7`=06_C#,)"(D\).A/ +XMV@,`BU7PBTWLB021@\(!A?:)5?!UO(G0P>`"BU7LQP0"`````(D4),=$)`3P +XM(P8(Z%UC``#'1"0,`@```,=$)`C$F`H(BTWLQP0DE#()"(E,)`3H^L\!`(M% +XM[(D$).C?8@``BU7LB54(@\0<6UY?7>E]8@``C;8`````C;PG`````%6)Y8/L +XM"*'4EPH(AA<____H>1U"0B%P'0HBT4(B00DZ(3D___' +XM1"0$$P```(M#'(D$).C1Y/__BS:%]HGS=9'KRN@&OP``C;8`````Z\N-M"8` +XM````C;PG`````%6)Y593@^P0H329"PB%P`^%B@```.AV_?__BS4`F`H(A?9T +XM2XGSBU,,]L8!=#*+0QP[!=R9"PAT)X'B___]_XE3#,=$)`0!````BT,7B)!"3HQEX``.BA +XM_O__@\0D6UW#QT0D!,28"@C'!"0`+@D(Z)?&`0"%P'1-,575E-1@>R8`0``BP&+203'1>P` +XM````QT7H`````(F%>/[__XF-=/[__\=%Y`````#'1"0$14!`)#K!8/X`G\^QT0D +XM!`````#'!"3,L0@(Z.5>`0"#^/]UXL=$)`0`````QP0D4\<(".C,7@$`@_C_ +XM=0<``(D$)+]P +XMN0@(Z#=F`0"Y!0```/RC#'8*"(G&\Z8/E,`/ML"CE)@*",<$)-:Q"`CH`=D# +XM`(D$).BIU`,`HZ28"@C'!"3>L0@(Z.C8`P")!"3HD-0#`*-T=PH(H=AU"0B) +XM!"3H/MD#`*/0EPH(B00DZ%'7`P"CV'4)",<$).>Q"`CHL-@#`(D$).A8U`,` +XMQP6,F`H((0```,<%1)H+"%X```#'!32:"P@^````QP6,=PH((P```,<%;'<* +XM"`````"CU)D+"*-,=PH(QP0D\;$(".A@V`,`QT0D"`(```#'!"2@,PD(B40D +XM!.B(S0$`BXUT_O__BP&)!"3H.-@#`(D$).C@TP,`QP7X70D(`````*/T70D( +XMQT0D!*0N"0B)!"3H[=G__X7`#Y3`#[;`B86$_O__Z`K@__^CA'8*".B`V___ +XMH\QV"@CH5N#__Z,LF0L(Z)S>__^+M73^__^CZ)@*"(L&@#@M#X3`$0``@[UX +XM_O__`@^$DQ$``,<%-)D+"`````#'!6"9"P@!````NX````#'!"3UL0@(Z*38 +XM__^%P`^5P`^VP*/`I0L(QT0D!$7)"`C'!"0`````Z%/?___'1"0$1BT2>-*D```0`=2R#PP&!^_\```!_(??#```` +XM0'7M@?O_````=MJ)'"2)]N@WV?__J0``!`!TU(,]@%$)"`$/E,(QP('[_P`` +XM``^?P"'0HV"9"PBA/&0)"(7`=`VA0&0)"(7`#X1>$0``Z'T5`P#'!"1T=@H( +XMZ&W7___HG-H#`.@WX?__H;1V"@B)!"3H=MO__X7`B<,/A$P1``")QK@%```` +XM_+_^L0@(B<'SI@^$^`0``(D<).BAU@,`B00DZ$G2`P#'1"0(`@```,<$)+PN +XM"0B)1"0$B6`$`QT0D"`(```#'!"2X+PD(B40D!.BFR0$`C9V<_O__QT0D +XM!``!``")'"3H/-S__X7`#X@]#@``QD6;`(D<).A\U`,`QP0DE#`)"(E$)`3H +XM7,L``.BG=@,`QP0D++((".AGU?__A<")PP^$Z0X``(D$)(G>OQZR"`CH0M0# +XM`(D$).CJSP,`B00DZ!)8`0#'1"0(`@```,<$)-`O"0B)1"0$Z!K)`0"Y"``` +XM`/SSI@^%P0P``,>%?/[__P$```"+M7S^__^_/K(("+D&````_(DUB'<*"(G> +XM\Z8/A3L"```QP*/DF0L(BSWDF0L(A?\/AL@@(Z&S4 +XM__^%P(G#="Z)!"3HGMO__X/X!(F%O[NR"`BY!P```/.F#X2,#0``B[5X_O__@^X!A?8/CD,.``"+E8C^ +XM__^+`H`X+0^%,@X``(U0`0^V0`&$P`^$(PX``,>%@/[__P`````Q_XG3ZS*A +XM#'8*",<%D)@*"`$```")7"0$QP0D?````(E$)`CHV%,```^V0P&#PP&$P`^$ +XM`0$``#QX=\H/ML#_)(6,MP@(N'"Y"`CI??C__XU#!8D$).D`^___B=Z_1+(( +XM"+D#````\Z8/A+']__^+A7S^__^#\`'II?W__XUT)@"#_@$/A%L'``"#A8C^ +XM__\$BXV(_O__BP&)!"3H8-$#`(D$).@(S0,`A<"CD'8*"'0HB00DZ/?,`P") +XM!"3H'U4!`,=$)`@"````QP0D0#8)"(E$)`3H)\8!`*&0=@H(B00DZ*K'`P"+ +XM#9!V"@@YP7,G@WC\7(U0_'4>,<#K"XUV`(/J!(,Z7'4'@\`!.=%R\:@!#X6. +XM!@``@^X!QP6$(`D(`````+\!````#[9#`8/#`83`#X7__O__@^X!@X6(_O__ +XM!(7V?B:+E8C^__^+`H`X+749C5`!#[9``83`=`Z+C8#^__^%R0^$E?[__X7_ +XM#Y3#BX6$_O__A<`/A<4'``"$VP^$J0```(7V#XZA````QT0D!`````"+C8C^ +XM__^+`8D$).B950$`A<")PP^(&0X``*'T70D(B00DZ+)?`P"+E8C^___'!?A= +XM"0@!````BP*)!"3H*-`#`(D$).C0RP,`H_1="0C'1"0$$````(D<).B[6P$` +XMA<"CM'8*"`^(7PT``,=$)`@!````QT0D!`(```"AM'8*"(D$).A=T?__@X6( +XM_O__!,<%A"`)"`````#HVUL!`*&T=@H(B00DZ$K7__^%P*/`=@H(#X3"!@`` +XMH!V"@B)1=RA +XMY'8*"(E%X.@E3@``QP0D`)H+".C%S___@P4`7@D(`<<%P)@*"`````"%P`^5 +XMP`^VP`L%"%X)"`^$`00``(N%C/[__XLUP'8*"(,M`%X)"`&CE'<*"(M%S(7V +XMH]!V"@B+1="CU'8*"(M%U*/8=@H(BT78H]QV"@B+1=RCX'8*"(M%X*/D=@H( +XM=`Z+'9!V"@B%VP^$^`D``(M%Z(7`#X7%!```BT7LA<`/A:D$``"AE'<*"(D$ +XM).BGV?__BPW`=@H(A%A/[__P$```#IUOG__\<%*'<*"`$` +XM``#IQ_G__\<%!%X)"`$```#IN/G__[\!````QP4DF0L(`0```.FD^?__QP4( +XM7@D(`0```.F5^?__QP60F`H(`0```.F&^?__QT7D`0```.EZ^?__QX6`_O__ +XM`0```.EK^?__QP7H70D(`0```.E<^?__OP$```#'!80@"0@`````QP64=PH( +XM`0```.D_^O__QP0D@#()".BJP`$`Z2WY___'!"1@,@D(Z)G``0#I'/G__\=% +XM[`$```#I$/G__\=%Z`$```"0Z0/Y__^_`0```,<%O)@*"`(```#'!80@"0@` +XM````Z>7X__^+E7#^__^_XK$("+D%````_(U$$_R)QO.F#X5R]___B1PDZ);* +XM`P")!"3H/L8#`(D$).AF3@$`QT0D"`(```#'!"0H,@D(B40D!.ANOP$`BYUP +XM_O__A=L/A5'W___I+_?__\<%D)@*"`$```#'!"0I````Z$5,``#I5_G__Z', +XMEPH(B00DZ+_1__^%P`^$Z_K__\<%E'<*"`$```#IW/K__\<$)`````#H0.S_ +XM_^F4^/__QP4(7@D(`0```.E&]/__H]'__X7`#X1;^O__BX6` +XM_O__A<`/A4WZ__^AA'8*"#L%+)D+"`^$/@0``.B_SO__QP`-````QP7D=0D( +XM`0```.BJSO__BP")!"3H4,S__XE$)`BA#'8*",<$)#8```")1"0$Z(M+``#I +XM^OG__XN%=/[__X/`!(F%B/[__^DV]___A=L/A`0&``")'"3H8LD#`(D$).@* +XMQ0,`B00DZ#)-`0#'1"0(`@```,<$)*0O"0B)1"0$Z#J^`0#'1"0$Q)@*",<$ +XM)*0O"0CH=K4!`,<$)*`_"0B)1"0$Z`;```#I)_3__\<$)+6R"`CH1:8#`.DH +XM_?__QP0D@#$)".B4O@$`Z2/U___'1"0$Q)@*",<$)(`Q"0CHR[0!`(7`=`S' +XM!"2`,0D(Z*NV`0#'!>29"P@`````Z0OY___'1"0$`````,<$)`,```#H],[_ +XM_^DB^/__@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".AX30``,2%P`^$^?K__\<$ +XM)`````#HD0L``)#IY_K__\<$)(`R"0CH'[T!`.E&^___QP0D8#()".@.O0$` +XMZ2K[__^-1`/[OV2R"`C\N08```")QO.F#X2R_/__Z0CT__^)WK\QL@@(N04` +XM``#SI@^$*_/__XG>OS:R"`BY"````/.F#Y3`#[;`B85\_O__Z1;S___'1"0( +XM`@```,=$)`3H-@D(QP0DJ#()".@\O`$`Z1[X___'1"0$+P```(G>B1PDZ,'' +XM__^%P'0#C7`$QT0D"`,```#'1"0$O"X)"(DT).@"R___A/[__P&%P`^$_NW__\<$)`Q> +XM"0CH,<;__\<$).`U"0CH.;L!`.GA[?__Z,^C`@#IF.[__Z',=@H(.P7HF`H( +XM#X6Q^___Z>CU___'!"1%R0@(Z<+N___'!8AW"@@`````QP0D1[((".A>QO__ +XMN@$```"%P'05_(G&OUH;"0BY`@```/.F#Y7`#[;0B17DF0L(Z4_Q__^AS'8* +XM"(D$).B<2P$`A<`/A!@#``"+`(D$).@*Q0,`QT0D"`(```#'!"2X+PD(B40D +XM!.@RN@$`QT0D!,28"@C'!"2X+PD(Z"ZQ`0#'!"3@/PD(B40D!.B^NP``Z2/P +XM___'!"10L@@(Z+W$`P")!"3HA>7__^E$\?__QT0D!,28"@C'!"0`,`D(Z.RP +XM`0#'!"1^L@@(B40D!.C,H0,`QT0D#.BR"`C'1"0("````,=$)`0+````H8"8 +XM"@B)!"3H!Z@``(D$).B?H0,`QP0D`````.B#YO__Z1+R___'1"0$Q)@*",<$ +XM)``P"0CHBK`!`,<$)!$7"0B)1"0$Z&JA`P#'!"0`````Z$[F__^+A73^__^+ +XM6`3IO_'__\=$)`0!````QP0D`P```.A(RO__Z9OU___'!91W"@@!````Z:;V +XM__^[`0```,>%@/[__P````#I1?/__\=$)`3$F`H(QP0DD"\)".@0L`$`ND!! +XM"0CH=N/__XL]-)D+"(7_#X4+_/__Z?O[___'1"0$Q)@*",<$))`O"0CHWZ\! +XM`+H@00D(Z$7C___IJOO__\<$)``````QR3'2N*:R"`CH*]O__^DB^___H81V +XM"@B)!"3H.4D!`(7`#X3@`@``BP")!"3H1\,#`,=$)`@"````QP0DI"\)"(E$ +XM)`3H;[@!`,=$)`3$F`H(QP0DI"\)".AKKP$`QP0DP#\)"(E$)`3H^[D``.G, +XM^?__H;R8"@B%P`^%,/O__Z%`F0L(A<`/A2/[___'1"0$`````,<$)`````#H +XM>&\``.D*^___BQ6\F`H(A=(/A73Z__^A0)D+"(7`#X5G^O__QT0D!`````#' +XM!"0`````Z$1O``#I3OK__X/[`70G@_L"C;0F``````^$50(``(7;#X4=`@`` +XMQP6T=@H($````.EU\O__QP6T=@H($0```.EF\O__H>29"PB)!"3HU\P"`.D\ +XM]?__Z'W0`@#'!"0!````C;8`````Z"O1`@#I[/7__\<%Y'4)"`$```#H(\?_ +XM_XL`B00DZ,G$__^)1"0(B[6(_O__BP;'!"0V````B40D!.@!1```Z:WQ___' +XM!"0>L@@(Z>'\__^)%"3H],/__^E"^___QT0D!`$```"[$@```,<$)!(```#H +XM%LC__\=$)`0!````QP0D%0```.@"R/__QT0D!`$```#'!"06````Z.['___' +XM!"02````Z"+)__^%P`^$D0$``(UUG.MD.P753BU4(A=)X-(L=(%X)"(G(ZPF0 +XMC70F`#G(=!R#Z@&#^O]T)XM`!#T<7@D(=>J)V#G(=>B-="8`6S'`7<.+`3T< +XM7@D(=06A'%X)"(M`#%M=PXVT)@````!5B>5=QP447@D(`````,.058GE4X/L +XM!(M="(M#"(7`=!/'0P0`````QP,`````@\0$6UW#BT,,B00DZ)%-`P")70B# +XMQ`1;7>F$30,`C70F`%6)Y5=64X/L+(M5"(72#Y3`=0^+70R%VW4(@\0L6UY? +XM7<.$P,=%Z`````#'1>P`````QT7P``````^%80$``,=$)`0`````B10DZ('O +XM``")1>#'1"0$,"H("(M%X(D$).B;0@``BT7@B00DZ'"[`P#'1"0$@`$``(D$ +XM).A@1`$`B470@\`!#X3_````QT0D!,28"@C'!"2@-0D(Z,"I`0`]^&\)"'0* +XMBPB%R0^%&@$``+[_____H>AV"@B-?>C'!>AV"@@`````B478H!^QQ>"0AT\HM5W(72=+B+0PR#[@&)/"2)1"0$Z"9&`0#' +XM!"1\N0@(B40D!.CFF0,`@_[_=;^0BT70B00DZ/5#`0"+1=2CS)<*"(M%V*/H +XM=@H(BT7@B00DZ,I```"#Q"Q;7E]=PXGVQT0D!,28"@C'!"1@-0D(Z*RH`0`] +XM^&\)"'0GB00DZ/VW`P")1>#IA_[__XD$).@-N@,`B00DZ+&\__^)QNG4_O__ +XMQT0D!,28"@C'!"20+PD(Z&JH`0#'1"0$)#4)"(D$).@JMP,`B47@Z43^__^) +XM]E6)Y5.#[!2+70C'!11>"0@!````QT0D!&#"0AT%C#2BT`$@\(!/1Q>"0AU\XT4E00```")%"3H +XM7$L#`(L=(%X)"('['%X)"(G'B<9T&XM##(D$).BOM@,`B0:+6P2#Q@2!^QQ> +XM"0AUY<<&`````,=$)`3P(P8(B3PDZ,D_``#'1"0,`@```,=$)`C$F`H(B7PD +XM!,<$)``V"0CH::P!`(D\).A1/P``B3PDZ/D^``"#Q!Q;7E]=PY!5B>564X/L +XM$,=$)`3$F`H(QP0D`#8)".ATI@$`A<")PP^$S0```(L`A<`/A,,```"+#2!> +XM"0B!^1Q>"0AT*XL!BU$$B5`$BU$$B0([#629"PATW8D,).CU^___BPT@7@D( +XM@?D<7@D(==6A9)D+"*,<7@D(HR!>"0C'`!Q>"0C'0`0<7@D(BS.%]G57ZUN- +XM=@"+`(7`=%+'1"0$`0```,<$)!````#HQDD#`(G#BP:)!"3HFK4#`(/&!,=# +XM"`````")0PRA9)D+"(E#!*%DF0L(BP")`Z%DF0L(B1B+`XE8!'0&BP:%P'6H +XM@\006UY=Z3W^__^#Q!!;7EW#C;8`````58GE5[\`!```5E.#[`S'!"0`!``` +XMZ,9)`P")P^L>B?;H=[[__XLP@_XB=4D!_XD<)(E\)`3H]DD#`(G#B7PD!(D< +XM).@TO/__AY`P")!"3H[[0#`(D<)(G&Z*5(`P"#Q`R) +XM\%M>7UW#B1PDZ)-(`P#H&K[__XDP,?:#Q`R)\%M>7UW#B1PD,?;H=D@#`.O/ +XMC70F`%6)Y5=64X'LC````(M%"(M=#(D$).ARN___BU4(@SHOB<+1(H$@\$!A<")1(L$=?&+%HGW +XMA=)U5(GWC4;\.T4(=`_'1OP`````B?N+`X7`=;G'1"0$Q)@*",<$))`O"0CH +XM%:0!`(D$)(G#Z$>Z__^%VXG&=`F#.R\/A*X"``"+10B!Q(P```!;7E]=PX/' +XM!(L'A`0K?0B)#"3H#;G__XG#BT6`B00DZ`"Y__^-5`,!B?C!^`*-!`+!X`*)!"3H +XMG48#`(M5"(G&B<&+`H/"!(D!@\$$A^+58")V8L"@\($B4'\@\$$A^)V8GZBP*# +XMP@2)0?R#P02%P'7QBTV,C7PQ_(M5"(G[B10DZ'9$`P")=0CI'_W__XE$)`B+ +XM30B)'"2)3"0$Z">Y__^%P'47BU4(BP2R@_@O#X0L_?__A<`/A"3]__\['1A> +XM"0AT,HD<).B0L@,`C564B50D!(D$).@=N?__@\`!=!:+192)'1A>"0BCG"`) +XM"(M%F*.@(`D(BTT(C7V4B0PDZ#BP`P")QHL&A)QNF0_O__QT;\+P```(-M@`2+58"#.B]U +XM](M-A(7)=%\QTHM$EP2+38")1)$$@\(!A575HG&4XG#@^P,@S@O='.A +XM9)D+"(M`#(D$).A:M?__B30DB<,QP(/[`0^4P(/H`2'#Z$.U__^-!`.-!(4( +XM````B00DZ.5"`P")QZ%DF0L(B?F+4`R+`H/"!(D!@\$$AB)1>R+`(U(!(E-\(M0!(72#X35```` +XM@SHM#X78````,?_K'('/@````(-%\`2+1?"+$(72#X23````@SHM=5Z+0@2) +XMTX7`=1?KV2GQN`$```#3X`G'BT,(@\,$AR#X`Z%P(D1=`.#SP&#Q!R)^%M>7UW#BT7P,?^+3>R)`>OJ +XMBTWP,?^+5>R)"NO>ZPV0D)"0D)"0D)"0D)"058GE@^P8B5WXB77\@S@K=`XQ +XMVXG8BW7\BUWXB>Q=PXM0!(U(!/?"````0'4G@_I_=ACK((M0"/?"````0(UV +XM`'42@_I_=PV#P`3V!)6]40D(!'7@A=)UN8D,).@`FP$`A<")QGZKBQUDF0L( +XMZPT['629"PAT&(/N`728BUL$@?L<7@D(=>B+'2!>"0CKX,<$)!H``!#H9C(` +XM`.O:C70F`%6)Y5.)PX/L%,=$)`3$F`H(QP0D9#,)".B3G`$`QT0D"`8```#' +XM!"1T,PD(B40D!.AKI0$`B5PD!,=$)`@&````QP0D9#,)".A3I0$`B5PD!,<$ +XM)/@Z"0CH\Z8``(/$%%M=PXVV`````(V\)P````!5B>53@^P4BQUDF0L(C78` +XM@?L<7@D(=!;'1"0$^&\)"(M##(D$).C%]O__B4,,BUL$.QUDF0L(==>+0PR# +XMQ!1;7>E*____C78`C;PG`````%6)Y8/L&(U%"(D$).CO5P,`A<")PG09BT4( +XMB50D!,<$)(ZY"`B)1"0(Z+*,`P#)PXM%",<$))*Y"`B)1"0$Z)V,`P#)PXUT +XM)@"-O"<`````58GE5U93@^P\BS5DF0L(B478@^`$B474BT78QT7<`````,=% +XMX`````"#X`*)1=#ICP```(U%\(D$).AQ5P,`A<")QP^$G````(D$).B+L?__ +XMB<.+1?")!"3H?K'__XU<`P(!7>#V1=@(=!:+%>"7"@B-0O\Y1>!\"#G3#XRY +XM````A?]T$(E\)`3'!"29N0@(Z/N+`P"#?=0!QP0DG;D("!G`@^`6@\`*B40D +XM"(M%\(E$)`3HV(L#`(MV!#LU9)D+"'1=@?X<7@D(=.V+1=2%P'4FBT8,,?^) +XM1?"+1="%P`^$3____XM%\(D$).CLL/__C5@!Z6K___^+1=R+7=S'!"25N0@( +XMB40D!.B"BP,`@\,!B5W#I,____XGV58GE5XG75HG&4X/L#,=$ +XM)`3$F`H(QP0DX#D)".C/F0$`A"0AUVXDU9)D+"(M&#.@Z_?__Z"7R +XM__^+'2Q>"0C'1"0$Q)@*",<$)&`Y"0CH:YD!`(/X`1G`("0B%P'4$A=MU#(/$#%M>7UWI/FP#`(GXZ/?]__^#Q`Q;7E]=Z2ML +XM`P"+`XM3!(E0!(M3!(D"B1PDZ-;N___I>?___Y!5N:.Y"`B)Y;JMN0@(@^PH +XMC44(B5WTB77XB7W\Z-_Z___'!2Q>"0@!````B<.)QH'C@`````^%A0```(M% +XM"(L0A=(/A)@```"%VW4DBT4(BT`$AP0<7@D(=&8Q_SL=9)D+"`^$?0`` +XM`(M#!(L3B1"+$XE"!(D<).@D[O__.QUDF0L(=%*)\.@5_?__ZZ6-=@#'1"0$ +XMQ)@*",<$)'0S"0CHG)@!`(G"A=(/A6K___^)]HL=9)D+"(%[!!Q>"0AUFY"! +XM.QQ>"0AUDL<$)$(``!#H'"X``.N$B?*)^.@1_O__D.E-____BWL$@?\<7@D( +XM=%J+1PR)!"3HQ:D#`(E%\(D$).C6K/__A<`/B5K____HV;#__XL`B00DZ'^N +XM___'!"0V````B40D"(M%\(E$)`3HO"T``.DO____QP0D0P``$.BK+0``Z0?_ +XM__^+/2!>"0CKGHVT)@````"-O"<`````5;E%R0@(B>6Z][D("%93@^P0C44( +XMZ%;Y__^H0(G&=$*A9)D+"(L`.P5DF0L(=!R0/1Q>"0B+&'0(B00DZ/_L__^) +XMV#L%9)D+"'7EHR!>"0BC'%X)",=`!!Q>"0C'`!Q>"0CWQB`````/A8T```#W +XMQA````!U:XM5"(L*A575E.#['R+30R%R0^$=`$` +XM`(M%"#';QT7H`````,=%[`````#'1?``````ZP.#P`2+$(72="Z+2`2%R70G +XM@_HN=>N#^2YUYHM0"(72D`^%2P$``#M%"'0'@WC\+Y!USH/#`>O)A=L/A!D! +XM``"A9)D+"(M`#(D$).B-K/__C02%#````(D$).@R.@,`B46`H629"PB+0`R) +XM1"0$BU6`B10DZ&2K__^+=0B#/B\/A#P"``"+70C'1>P`````BQ,Q_X72=$&# +XM^BZ-H0,`A?]_#>LB@^\!QP`````` +XM=!?'1"0$+P```(M%@(D$).@FJO__AR%P`^%!P$``(MU@(L^A?\/A;4```"+,X7V#X5%____BT7HB00DZ',X +XM`P"+18"#Q'Q;7E]=PXM%"(D$).B=I`,`B46`BT6`@\1\6UY?7<.#^B\/A8;^ +XM___II_[__Y`[70AT$8-[_"^-M"8`````#X4?____A<`/A#'___^-6#[#C'1"0$`````(E= +XM](EU^(E]_(D$).@AV0``QT0D!#`J"`B)QHD$).@_+```,<"#/=B7"@@"B30D +XM#Y3`B40D!.BW_/__B<.)!"3H_:0#`(D$).@1J/__A!F)-"3H?"L``(DT).@D*P``B?#HW?/__^NYZ,*K__^#.`*-=@!T.^BU +XMJ___@S@4=#&-="8`Z*>K__^+`(D$).A-J?__B30DB"2)-"3H>"H``(D<).C0H0,`QP4L7@D(`0```.@A\___Z?K^__^+'11> +XM"0B%VP^$/@$``(DT).A&*@``,<#IW?[__XET)`3'!"3,.`D(Z.\I`0"%P`^% +XM=____\=$)`3$F`H(QP0DW#@)".BSD0$`A<`/A%O___^+$(72#X11____QT7H +XM`````,=%[`````#'1?``````BQB+`X7`=2KI_0```(DT).A7HP,`B00DZ&NF +XM__^%P`^)]0```(/#!(L[A?\/A-@```#'1>P`````BP.)1"0$C47HB00DZ)*? +XM`P"-1>B)!"3'1"0$+P```.@/G0,`C47HB00DB70D!.APGP,`C47HB00DZ%6= +XM`P"AV)<*"(/H`H/X`0^6P`^VP(E$)`2+1>B)!"3HA?K__XG'B00DZ,NB`P") +XM!"3HWZ7__X7`#XA<____BT7HQP4L7@D(`0```(D$).A&-`,`B30DZ!XI``") +XM^.C7\?__Z;#]__^)]HM%X(D$).AAI___B30DBZ(#`(E<)`C'!"0V```` +XMB40D!.B7)@``Z93^__^+1>B)!"3H]S,#`.DB_O__B3PDQP4L7@D(`0```.C@ +XM,P,`BT7HB00DZ-4S`P#I?/W__U6YM[D("(GENJVY"`B#[!B-10B)=?B)??R) +XM7?3H'_+__\<%+%X)"`$```")QHG'@>:`````#X6Y````BT4(BQB%VP^$QP`` +XM`(7V=22+10B+2`2%R70:QP0D#P``$.C^)0``BUWTBW7XBWW\B>Q=PY")V.CI +XM\O__A<")Q@^$_P```(M`#(D$).BDH0,`B<.)!"3HMJ3__X7`#X@U`0``QT0D +XM!,28"@C'!"2@.0D(Z)Z/`0"%P'0P.S5DF0L(="B+%HM&!(E"!(M&!(D0H629 +XM"PB+$(D6H629"PB)1@2)<@2A9)D+"(DPB?J)\.AQ]?__Z6[____'1"0$Q)@* +XM",<$)'0S"0CHJ(\!`(G#Z3'____'1"0$Q)@*",<$)"`Y"0CH+8\!`(7`#X30 +XM````QT0D!,28"@C'!"20+PD(Z'&/`0`]^&\)"(G#=`:+,(7V=0S'!"0B```0 +XMZ`8E``")'"3HSJ`#`(D$).CBH___A:`````#X6:````BT4(BQB%VP^$#P$``(7V +XM=22+10B+0`2%P'0:QP0D#P``$.A>(P``BUWTBW7XBWW\B>Q=PY")V.A)\/__ +XMA<")QG1SQP4L7@D(`0```(M`#(D$).C^G@,`B<.)!"3H$*+__X7`#X@'`0`` +XMH629"PB+4`2+`(D"H629"PB+$(M`!(E"!*%DF0L(B00DZ*;B__^)^HGPZ.WR +XM___KC<=$)`3$F`H(QP0D=#,)".@GC0$`B6#[!B)7?B)PZ&`F`H(B77\BS4,=@H(QT0D +XM#-BY"`C'1"0(`0```,=$)`0,````B00DZ#>#``")7"0(B70D!(D$).C'?`,` +XMBUWXBW7\B>Q=PXVV`````(V\)P````!5B>575E.![,P```"+=0CHO.7__X7` +XMB<,/A!(!``")!"3H&IT#`(U5E(E4)`2)!"3HIZ/__X7`#Y3`B<=U4H7V=`J+ +XM!H7`#X54`0``B?B$P'0^QP0DT;D(".@>H/__A<")QG0LC84T____B40D!(DT +XM).AFH___@\`!=!6+190[A33___\/A&8!``"-M@````#'1"0$,"H("(D<).C` +XM(P``QT0D!/AO"0B)'"3HP.7__XD<)(G&Z%8C``")'"3H_B(``,=$)`0!```` +XMQP0D$````.AJ+@,`,=*)<`R)P\=`"`````"C(%X)"*,<7@D(QT`$'%X)",<` +XM'%X)",<%+%X)"`````#H9O#__\=$)`@&````BT,,QP0D`#8)"(E$)`3HBY,! +XM`('$S````%M>7UW#Z#>C__^+`(D$).C=H/__QP0DAKD("(E$)`BA#'8*"(E$ +XM)`3H6'L#`(7V=`J+!H7`#X7`````N%/'"`CH,/[__\<$)%/'"`CHX)[__X/` +XM`0^$V````,<$)%/'"`CHWYT#`(D$).B'F0,`B<;I(O___XDT).B8FP,`C94T +XM____B50D!(D$).@BHO__@\`!#X2)_O__BT64.X4T____#X5Z_O__BT68.X4X +XM____#X5K_O__B30DZ#>9`P")QNG2_O__BT68.X4X____#X61_O__B30DZ&F= +XM`P")!"3H$9D#`,=$)`0P*@@(B<.)!"3H/R(``.EJ_O__B30DZ!*;`P")P^AK +XM_?__B1PDZ!^>__^#P`$/A"#___^)-"3HTI@#`(7`B<8/A6K^___I"?___\<$ +XM)`$```#H-[___^D7____D)!5B>5=HTA>"0C#C;8`````H4A>"0A5B>6%P'0, +XM7<<%2%X)"`````##H4Q>"0B%P'07BQ"#P`2C3%X)"(72=`E=B=`E____?\.A +XM4%X)"(L0A=)T%5V#P`2C4%X)"+@@````B15,7@D(PUVX_____\<%3%X)"``` +XM``##C;0F`````%6)Y8M%"(7`>":I````0'4?@_A_?QH/ML`/MX0`X"`)"*A# +XM=`O'!71>"0@!````D%W#C;0F`````(V\)P````!5B>5=QP7$EPH(`````,.0 +XM58GE@^P(B00DZ/*9`P#'!"0K```0HR!W"@CH$1X``,G#ZPV0D)"0D)"0D)"0 +XMD)"058GE5U93@^P\BQ5D7@D(A=)T"HL];%X)"(7_=0VC5%X)"(/$/%M>7UW# +XMB00DZ'Z7`P"+-61>"0B%]HE%[`^$[P(``,=%\`````"-M@````"+??"+%6!> +XM"0C!YP*+!#K'1=``````@_AS#X58`@``BUWP@\,!BQ2:A=*)5=0/A/\"``"! +XMX@```$!U0P^V5=2!^O\````/A\T"``"AX%T)"(M$D#3VQ`$/A=4"``"#?=1? +XM#X3+`@``@WW4?W<1BT74]@2%O5$)"`0/A;0"``"+5=3'!"3_N0@(B50D!.C_ +XM'0$`A<`/A9D"``"+#6!>"0B-``````C02QB4W$B<&)1=@Y$'0O +XMBT7$C7,"C0RPBQ&%TG0@C40X#.L/BU`$@\$$@\8!B;'`0````"+%6!>"0B-3@&)3?#!X0*+1=2)3>C'1>0``````=&)3=R)RSD! +XM=$2-3@*)3?#!X0*-'`J)3>B+"X7)="^-!+4(`````<+K%H-%\`&#P`2#PP2) +XM1>B+2@2)VH7)=`Z#1>0!B=,Y3=2)1>AUW,<#`````(M%V(D$).CT'0$`BU7L +XMB10DZ.D=`0"+3>"+1>S'1=``````P>$"B4W,ZQ2-="8`BT7(QT70`0```(EU +XM[(/`!(M5V(D$)(E4)`3HL9`#`(7`B<R)^XD,).AVG/__BU7D +XM*U7@C50"`<'B`HD4).@5*@,`*UWLP?L"B5PD"(G&BT7LB30DB40D!.A&HO__ +XMBTWB57(B10DB4PD!.@QF___BU7,C007B40D!`-=Y(T"0B%VP^%5/___XEU[,=%T`$```"+5=2+3=RA8%X) +XM"`%%Z(E1_(M%Z(D0BU70A=)T;.M6H6!>"0B+!`?'1=`!````B5WLB40D!(M5 +XM[(D4).AJ]P``A<")PW30B40D!(M-[(D,).CQFO__A<`/A((```"+5>R)%"3H +XMRA;%X)"#W___]_=`B#Z`&C;%X)"(-%\`&+3?`Y +XM#61>"0@/AQ[]__^+1>R)!"3H@_@``*&`7@D(QP547@D(^&\)"(7`#X3._/__ +XMQP0D````0.B@&@``@\0\6UY?7<.)%"3HG)K__^DO_?__BT7LB00DZ/`G`P#K +XMAL<$)%@```#H`AH``(GVZZ"-M"8`````C;PG`````%6)Y5=64X/L7(E%L(UT +XM)@"+#41>"0B%R0^%*@(``(L5F'<*"#D5?)P+"`^'2PH``*%47@D(A<`/A"," +XM``"+"(/`!*-47@D(@>'___]_A"0B%R0^/?`L``,<%5%X) +XM"`````#H_OK__X/X)(G!=`J#Q%R)R%M>7UW#BT6PA +XM"0@`````QP5D7@D(`````.@I____B47(@\`!#X2M`0``BUW(@_M[#X1,!0`` +XMB=@E____/X/X(P^$&04``(/[/P^$H04``(/[)0^$NP4``,=%O`````#'1;@` +XM````QT6T`````(/[(0^$H00```^/D@```(/[_P^$IP,``(/["@^$G@,``(G8 +XM)0```$")]G4)@_M_#X9,"```@_O_B?9T+X7`=2L/MM.!^O\```"0#X?F"@`` +XMH>!="0B+1)`T]L0%#X48!P``@_M?#X0/!P``BT6\OB0V"0B%P'40BT6XA<`/ +XMA.<&``"^]"X)"(U%V(ET)`2)!"3HY)`#`(U5V(D4).E/`P``@_LJ#X2R`@`` +XM@?L\``!`#X3%````@_LDD`^%8?___XM5O`E5N(M-N`M-M`^%-@D``*&\F0L( +XMZ%[Z__^-1=B)!"3HHQH``(-]R'L/A?G]___H5/G__X/X?9`/A.K]___'1"0$ +XM?0```,<$)#(```#H)A@``(L-1%X)"(7)#X36_?__QP5$7@D(`````(/$7(G( +XM6UY?7<.-="8`BQ5<7@D(A=(/CO_]__^+%5A>"0B+`H/"!(D56%X)".C<^?__ +XM@RU<7@D(`>F`_?__QP0D`````.C$%P``Z6_]__^+1;B%P`^%:0@``(M%O(7` +XM#X4S"```BT6TA<`/A0\(```Q]HU]YL<%.%X)"`````#K'HM%[#'V@_@*#X29 +XM````B40D!,<$)#1>"0CH/XT#`(U5\(D4).@DBP,`C00WB40D!*%$F0L(QT0D +XM"`$```")!"3H.!H!`(U-\(D,)(G#Z(L9``"#ZP%U4(/&`8U%[(ET)`B)?"0$ +XMB00DZ#"4`P"#^/\/A,<```"%P`^.\````#GZ____*<:-!`>)="0(B40D +XM!(D\).C>F___BT7L@_@*#X5G____A?:-7>QU(.M@BT7L,?:#^`IT5HE$)`3' +XM!"0T7@D(Z).,`P"%]G1"B70D"(E\)`2)'"3HOY,#`(/X_P^$E@```(7`#XZV +XM````.?!TO2G&C00'B70D"(E$)`2)/"3H<9O__XM%[(/X"G6JQP0D-%X)".BA +XMC`,`Z'P.``"A-%X)".AB^/__C578B10DZ*<8``#I__W__XGVQT0D"`````#' +XM1"0$`````,<$)`````#H\);__X/^!0^&O/[__P^V1>8-```@`(E%[+@!```` +XMZ0;___^0C70F`,=$)`@`````QT0D!`````#'!"0`````Z+"6__\/MD7F#0`` +XM(`")1>RX`0```.E`____C4W8O_____^)#"3'1"0$)#8)".@&C@,`C478B00D +XMZ.N+`P#'1"0$Q)@*",<$)"0V"0CHEW\!`(G&BT6XA"0B-5=B)%"3HT!<``.DH_?__BT6\OB0V"0B%P'40BWVXA?\/A((# +XM``"^]"X)"(U5V(ET)`2)%"3HD(T#`(U-V(D,).AUBP,`O_____^)-"3'1"0$ +XMQ)@*".@@?P$`B<:)V.@G]O__A?8/A*X!``"+!H7`#X2D`0``C478B00DZ%H7 +XM```QP.BC^O__B<.+!HD$).@'%@$`BU6\"?J)14__\!1,`P"C,%X)".@=]?__ +XMZ<7Z__^AY*P+"(L-X*P+"(E%W*'HK`L(B4W8B47@C478QT0D!+"1"`B)!"3H +XMW!4``.L4@_C_="6-5=B)7"0$B10DZ*:(`P"X`0```.AL^/__@_A=B<-T%X/X +XM"G76QP0D!0```.BT$@``C70F`.O)C4W8B0PDZ-.(`P"A5%X)"(M=V(7`#X1B +XM`@``QP0D!@```.B'$@``BQ.%T@^$9`(``/?"````0`^$)0$``,=%T`$```"# +XM^BH/A&<"``"#^BT/A$T#``#'1"0$+0```,<$)#(```#H1!(``(M%T(7`=1*+ +XM1<"%P`^%.P0``,=%P/____^+.X7_#X7,`P``C578B10DZ&84``"+?<#I2OW_ +XM_XM%T(U?`2M=T,'@`HE%Q.@*"@``BP:)'5Q>"0B#Z`0#1<2C6%X)".F/^?__ +XMQP0D`````.C6$0``Z;CX___'!"0?````Z,41``"0C70F`(U-V(E<)`2)#"3H +XM@8<#`#'`Z$KW__^#^/^)PW0IJ0```$!U(@^VT('Z_P````^'FP$``*'@70D( +XMBT20-/;$!76_@_M?=+J-1=@Q_XD$).B=AP,`B=CH9O+__\=$)`3$F`H(BT78 +XMB00DZ$-[`0")QNFG^___@_I_#X?2_O__]@25O5$)"`3'1=``````=13IO/[_ +XM_X/Z?W"0CIT_?__XL]7%X)"(7_#X60_?__BQ.% +XMT@^%G/W__\<$)`````#H#1```(L3]\(```!`#X6._?__Z:[^__^#PP3IKOW_ +XM_XD4).CVC___Z6'^__^A>)P+"(L,D(U"`:.8=PH(@>'___]_A7UW#QP0D`````.A)#@``Z2/\__^-="8`Z$OO__^#^'V)PW04QT0D +XM!'T```#'!"0R````Z"`.``")V.@9[___Z67Y__^+1=B)!"3H214!`.GO^/__ +XMB10DZ`B.___I%O7__XU%V(D$).@\$```BT8$Z+3O___IC_/__XM%V(D$).BD +XMB0,`B00DZ-B,__^Z$"\)"(7`#X4I^/__Z2GX__^+%?1="0B%T@^$B@```(M% +XMM(7`=%ZA]%T)"(D$).@DCO__B00DZ(!X`0")!"3H2.L``.GX]___QT0D!,28 +XM"@C'!"0D-@D(Z%]W`0"%P(G`]___C4W8OJ0@"0B)#"0QV^BC#P``QT7$ +XM!````.E(^___Z%(%``"A]%T)".@X[___Z:CW___'!"0K````Z"<-``#IOOS_ +XM_\<$)`0```#H%@T``(VV`````.E?____C70F`(V\)P````!5B>575E.![%R` +XM``"-?>3'1=@`````QT7<`````,=%X`````#'1CO__@\`! +XM=:;'1"0$`````(D\).B)C?__H0AV"@B)!"3HP!D#`(MUY(M=Z.AQDO__,?,Q +XMPX'C____`(D<).@C=P$`QP0D0#()"(G#B40D!.A!A0,`B1PDHPAV"@CHA!D# +XM`.E(____B1PDZ+.-___H_H[__XDPZ/>.__^+`(D$).B=C/__B5PD!,<$)#8` +XM``")1"0(Z-T+``")'"2-GXW__XM%"(U5[(F5M'___XD4),=%\``` +XM``")1>S'!71>"0@`````Z$>F``"-5>R)%"3'1"0$0/X$".CTI0``H71>"0C' +XM1<@`````QP7$EPH(`0```,=$)`2`_@0(B86\?___QP0DQ)<*".A4#@``C578 +XMB10DQT0D!+"1"`CH00X``(U%S,=$)`2PD0@(B00DZ"X.``"-5"0B)%5!>"0C'1=``````N`$```#H +XM2?#__X/X_W0QB<:!YO___S]TYX/^7`^$V`$``(U%S(D$)(ET)`3H4H`#`+@! +XM````Z!CP__^#^/]USXU5S(D4).B8@`,`BW7,QT0D!&````")-"3H@8[__X7` +XM#X3"`0``QT0D!`$```")-"3H+;$``(F%P'___XN%P'___XL0B<>%TG1$BP*) +XMUH7`=!V0)?___S^)`X/#!#F=N'___W1XBT8$@\8$A"0C___]_,<#H7NW__XG#@_MG#X23````@_MA +XM#X2^`0``@_MS#X2M````B5PD!,<$)!ZZ"`CH<0@!`(7`#X1Y`0``B5PD!,<$ +XM)&!>"0CH27T#`(/[<0^$=0$``#'`Z`GM__^#^#J)PP^%/P$``#'`Z/?L___' +XM!6Q>"0@!````QP5P7@D(`````(/X9XG##X1I____@_AA#X5S____QP5P7@D( +XM`0```.E;____@3UL7@D(____?P^$;____\<%;%X)"/___W\QP.B?[/__B<.# +XM^W,/A5/___\QP.B-[/__QT0D!',```#'!"1@7@D(B!="0B+1)`T]L0!=6F#_U]T9(/_?W<*]@2]O5$)"`1U58E\)`3'!"3_N0@( +XMZ%`'`0"%P'5!O@(```#K))"-="8`B5PD!,<$)&!>"0CH('P#`#'`.=\/E,`I +XMQ@^$T?[__S'`Z-KK__^#^/^)PW73A?8/A+O^___'!"18````Z*\%``"#Q`R) +XMV%M>7UWI$>?__Y")7"0$QP0D!P```.@`!@``Z7+^___'!6Q>"0C___]_Z7S^ +XM__^A<%X)"(7`#X4^_O__QP5P7@D(`0```.G*_O__B10DZ-2%___I*O___XUV +XM`%6)Y5.)PX/L%.LWD(UT)@"#^O]T8872>!WWP@```$"0=12#^G]_#P^VP@^W +XMA`#@(`D(J`]U58E4)`2)'"3H3GL#`+@!````Z!3K__^#^%R)PG6],<#H!NO_ +XM_X/X_W0<@_@*NB````!TOHG"@575E.#["RC4%X)"#'`QT7H +XM`````,=%[`````#'1?``````QP5,7@D(^&\)",<%1%X)"`````#HXN7__XU% +XMZ,<%5%X)"`````#'!5Q>"0@`````QT0D!/"1"`B)!"3HJP<``(U%W#';QT7< +XM`````,=%X`````#'1>0`````QT0D!+"1"`B)!"3H@0<``)"X`0```.@FZO__ +XM@_@GB<9T=']0@_@@=.B0C;0F``````^/_P$``(/X"8VT)@````!TSH/X"@^$ +XM]@```(/X_XGV#X3&`0``B35$7@D(C470,`@_XB#Y3`#[;XB?:) +XM^.B9Z?__.<:)PW1H@_@*#X3`````@_C_#X2W````B=@E____?ST*``!`#X3' +XM````@_XG#X3M````@_Y@#X3^````@_XB=;B#^V"X8````'0'B=@-````0(E$ +XM)`2-1=R)!"3H:'D#`(GXZ#'I__\YQHG#=9B#_F`/A3[___^-1=R)!"3'1"0$ +XM8````.@_>0,`C47B)!"3HSWH#`.EO_O__B70D!,<$)#,```#H +XM&@,``(G8)?___W\]"@``0`^%.?___XM5X(72#X0N____BT7`,` +XMZ;_^__^-1=R)7"0$B00DZ(!X`P#IJ_[__S'`Z$3H__^#^`J0#X0*_O__@_C_ +XM#X0!_O__B<:!S@```$#I.O[__X7;B?9T([C_____Z'3C__^-="8`Z0S___^# +XM^"(/A1C^__^)]NE0_O__C47B)!"3HFGD#`(/$+%M>7UW#B?95B>6#["B)=?PQ]HE=^(L- +XM*'<*"(7)=`R)\(M=^(MU_(GL7<.+10C'1?0`````B47PC47PZ,?\__^)PXL` +XMAP,`B1PDB<;H8`@!`(GPBUWXBW7\B>Q=PXUT)@!5B>53@^P$ +XMBQTH=PH(A=MU3XM%"(M($(G+C;0F`````(L1A=)T.HL"@\$$A!VI +XM````0'46@_A_C78`?PX/ML#VA`#@(`D(PW47D(M"!(/"!(7`==6+$872=<:# +XMQ`1;7<.)V.@#_/__BU4(B<.+0A")!"3HTP5=PXUT)@"-O"<`````58GE@^P(H`#`P6\8`D(BQ")%"3_4`2AP&`)"#L%Q&`)"'?:R<.0C70F`%6AQ&`)"(L5 +XMP&`)"(GE78D5Q&`)",.-=@"-O"<`````58GEBT4(BP")10A=Z>\-`P#K#9"0 +XMD)"0D)"0D)"0D)!5B>6#[!BA@%X)"(7`=`+)PX%]"(8```"-10R)1?QV!\=% +XM"(4```")1"0$BU4(BP25H%X)"(D$).AS6@,`HX!>"0C)PXVV`````(V_```` +XM`%6)Y8/L".@E____QT0D!`$```#'!"0`F@L(Z'V!__^058GE5U93@^P<```!`=`Z+-8!>"0B%]@^$M````(G>@>;_ +XM__\/@?Z&````=@6^A0```.CB&P$`]\,````@QP7`F`H(`0````^$C````*&` +XM7@D(A<<$)`$```#HAY___^@RS```QT0D"`(```#'1"0$&"\)",<$ +XM)/0N"0CH=G(!`*'4EPH(A +XM7UW#@>,````0=5B%_W0IH8!>"0C'!"2F&`D(B40D!.@O6@,`Z4[___^+%>1U +XM"0B%TG2)Z7C___^+1?")1"0$BP2UH%X)"(D$).CE60,`QP0D;\<(".CY60,` +XMZ1C___^-="8`H2!W"@C'!"0HN@@(B40D!.C;60,`ZY&)]HV\)P````!5B>5= +XMZ:<#`0"-M"8`````58GEBT4(BP")10A=Z<\#`0#K#9"0D)"0D)"0D)"0D)!5 +XMB>6#[!B+10C'1"0(`````,<$)`,```")1"0$Z-M]___)PXVV`````(V\)P`` +XM``!5B>6#[!B+10C'1"0(`````,<$)`(```")1"0$Z.N!___)PXVV`````(V\ +XM)P````!5B>53@^P4BUT(.1W`8`D(7<.-=@#H=W[__XUT)@"-O"<`````58GE4X/L!(L5O&`)"*'` +XM8`D(BUT(C0S".6#[`B+#`#B40D!*&\8`D(B00DZ$,+`P"+#"0BA@)@* +XM"(D$).B`70``B00DZ.@&`0#'1"0,7[H(",=$)`@#````QT0D!`$```"CI%X) +XM"*&`F`H(B00DZ$Y=``")!"3HM@8!`,=$)`QMN@@(QT0D"`0```#'1"0$`0`` +XM`*.H7@D(H8"8"@B)!"3H'%T``(D$).B$!@$`QT0D#'ZZ"`C'1"0(!0```,=$ +XM)`0!````HZQ>"0BA@)@*"(D$).CJ7```B00DZ%(&`0#'1"0,C;H(",=$)`@& +XM````QT0D!`$```"CL%X)"*&`F`H(B00DZ+A<``")!"3H(`8!`,=$)`RDN@@( +XMQT0D"`<```#'1"0$`0```*.T7@D(H8"8"@B)!"3HAEP``(D$).CN!0$`QT0D +XM#,*Z"`C'1"0("````,=$)`0!````H[A>"0BA@)@*"(D$).A47```B00DZ+P% +XM`0#'1"0,V[H(",=$)`@)````QT0D!`$```"CO%X)"*&`F`H(B00DZ")<``") +XM!"3HB@4!`,=$)`SKN@@(QT0D"`H```#'1"0$`0```*/`7@D(H8"8"@B)!"3H +XM\%L``(D$).A8!0$`QT0D#/^Z"`C'1"0("P```,=$)`0!````H\1>"0BA@)@* +XM"(D$).B^6P``B00DZ"8%`0#'1"0,#;L(",=$)`@,````QT0D!`$```"CR%X) +XM"*&`F`H(B00DZ(Q;``")!"3H]`0!`,=$)`P?NP@(QT0D"`T```#'1"0$`0`` +XM`*/,7@D(H8"8"@B)!"3H6EL``(D$).C"!`$`QT0D##.["`C'1"0(#@```,=$ +XM)`0!````H]!>"0BA@)@*"(D$).@H6P``B00DZ)`$`0#'1"0,1;L(",=$)`@/ +XM````QT0D!`$```"CU%X)"*&`F`H(B00DZ/9:``")!"3H7@0!`,=$)`Q7NP@( +XMQT0D"!````#'1"0$`0```*/87@D(H8"8"@B)!"3HQ%H``(D$).@L!`$`QT0D +XM#&J["`C'1"0($0```,=$)`0!````H]Q>"0BA@)@*"(D$).B26@``B00DZ/H# +XM`0#'1"0,AKL(",=$)`@2````QT0D!`$```"CX%X)"*&`F`H(B00DZ&!:``") +XM!"3HR`,!`,=$)`R/NP@(QT0D"!,```#'1"0$`0```*/D7@D(H8"8"@B)!"3H +XM+EH``(D$).B6`P$`QT0D#)V["`C'1"0(%````,=$)`0!````H^A>"0BA@)@* +XM"(D$).C\60``B00DZ&0#`0#'1"0,M;L(",=$)`@5````QT0D!`$```"C[%X) +XM"*&`F`H(B00DZ,I9``")!"3H,@,!`,=$)`S"NP@(QT0D"!8```#'1"0$`0`` +XM`*/P7@D(H8"8"@B)!"3HF%D``(D$).@``P$`QT0D#-"["`C'1"0(%P```,=$ +XM)`0!````H_1>"0BA@)@*"(D$).AF60``B00DZ,X"`0#'1"0,WKL(",=$)`@8 +XM````QT0D!`$```"C^%X)"*&`F`H(B00DZ#19``")!"3HG`(!`,=$)`S,P@@( +XMQT0D"!D```#'1"0$`0```*/\7@D(H8"8"@B)!"3H`ED``(D$).AJ`@$`QT0D +XM#/&["`C'1"0(&@```,=$)`0!````HP!?"0BA@)@*"(D$).C06```B00DZ#@" +XM`0#'1"0,!+P(",=$)`@;````QT0D!`$```"C!%\)"*&`F`H(B00DZ)Y8``") +XM!"3H!@(!`,=$)`PBO`@(QT0D"!P```#'1"0$`0```*,(7PD(H8"8"@B)!"3H +XM;%@``(D$).C4`0$`QT0D#/#""`C'1"0('0```,=$)`0!````HPQ?"0BA@)@* +XM"(D$).@Z6```B00DZ*(!`0#'1"0,&,,(",=$)`@>````QT0D!`$```"C$%\) +XM"*&`F`H(B00DZ`A8``")!"3H<`$!`,=$)`PTO`@(QT0D"!\```#'1"0$`0`` +XM`*,47PD(H8"8"@B)!"3HUE<``(D$).@^`0$`QT0D#$##"`C'1"0((````,=$ +XM)`0!````HQA?"0BA@)@*"(D$).BD5P``B00DZ`P!`0#'1"0,2[P(",=$)`@A +XM````QT0D!`$```"C'%\)"*&`F`H(B00DZ')7``")!"3HV@`!`,=$)`QHO`@( +XMQT0D""(```#'1"0$`0```*,@7PD(H8"8"@B)!"3H0%<``(D$).BH``$`QT0D +XM#'J\"`C'1"0((P```,=$)`0!````HR1?"0BA@)@*"(D$).@.5P``B00DZ'8` +XM`0#'1"0,=,,(",=$)`@D````QT0D!`$```"C*%\)"*&`F`H(B00DZ-Q6``") +XM!"3H1``!`,=$)`R,O`@(QT0D""4```#'1"0$`0```*,L7PD(H8"8"@B)!"3H +XMJE8``(D$).@2``$`QT0D#*&\"`C'1"0()@```,=$)`0!````HS!?"0BA@)@* +XM"(D$).AX5@``B00DZ.#_``#'1"0,O[P(",=$)`@G````QT0D!`$```"C-%\) +XM"*&`F`H(B00DZ$96``")!"3HKO\``,=$)`S0O`@(QT0D""@```#'1"0$`0`` +XM`*,X7PD(H8"8"@B)!"3H%%8``(D$).A\_P``QT0D#-J\"`C'1"0(*0```,=$ +XM)`0!````HSQ?"0BA@)@*"(D$).CB50``B00DZ$K_``#'1"0,E,,(",=$)`@J +XM````QT0D!`$```"C0%\)"*&`F`H(B00DZ+!5``")!"3H&/\``,=$)`SJO`@( +XMQT0D""L```#'1"0$`0```*-$7PD(H8"8"@B)!"3H?E4``(D$).CF_@``QT0D +XM#/:\"`C'1"0(+````,=$)`0!````HTA?"0BA@)@*"(D$).A,50``B00DZ+3^ +XM``#'1"0,#;T(",=$)`@M````QT0D!`$```"C3%\)"*&`F`H(B00DZ!I5``") +XM!"3H@OX``,=$)`P;O0@(QT0D""X```#'1"0$`0```*-07PD(H8"8"@B)!"3H +XMZ%0``(D$).A0_@``QT0D#">]"`C'1"0(+P```,=$)`0!````HU1?"0BA@)@* +XM"(D$).BV5```B00DZ![^``#'1"0,.[T(",=$)`@P````QT0D!`$```"C6%\) +XM"*&`F`H(B00DZ(14``")!"3H[/T``,=$)`Q0O0@(QT0D"#$```#'1"0$`0`` +XM`*-<7PD(H8"8"@B)!"3H4E0``(D$).BZ_0``QT0D#&*]"`C'1"0(,@```,=$ +XM)`0!````HV!?"0BA@)@*"(D$).@@5```B00DZ(C]``#'1"0,:[T(",=$)`@S +XM````QT0D!`$```"C9%\)"*&`F`H(B00DZ.Y3``")!"3H5OT``,=$)`QVO0@( +XMQT0D"#0```#'1"0$`0```*-H7PD(H8"8"@B)!"3HO%,``(D$).@D_0``QT0D +XM#(.]"`C'1"0(-0```,=$)`0!````HVQ?"0BA@)@*"(D$).B*4P``B00DZ/+\ +XM``#'1"0,D;T(",=$)`@V````QT0D!`$```"C<%\)"*&`F`H(B00DZ%A3``") +XM!"3HP/P``,=$)`RAO0@(QT0D"#<```#'1"0$`0```*-T7PD(H8"8"@B)!"3H +XM)E,``(D$).B._```QT0D#/O>"`C'1"0(.````,=$)`0!````HWA?"0BA@)@* +XM"(D$).CT4@``B00DZ%S\``#'1"0,J+T(",=$)`@Y````QT0D!`$```"C?%\) +XM"*&`F`H(B00DZ,)2``")!"3H*OP``,=$)`RXPP@(QT0D"#H```#'1"0$`0`` +XM`*.`7PD(H8"8"@B)!"3HD%(``(D$).CX^P``QT0D#+N]"`C'1"0(.P```,=$ +XM)`0!````HX1?"0BA@)@*"(D$).A>4@``B00DZ,;[``#'1"0,RKT(",=$)`@\ +XM````QT0D!`$```"CB%\)"*&`F`H(B00DZ"Q2``")!"3HE/L``,=$)`S:O0@( +XMQT0D"#T```#'1"0$`0```*.,7PD(H8"8"@B)!"3H^E$``(D$).AB^P``QT0D +XM#.3#"`C'1"0(/@```,=$)`0!````HY!?"0BA@)@*"(D$).C(40``B00DZ##[ +XM``#'1"0,\;T(",=$)`@_````QT0D!`$```"CE%\)"*&`F`H(B00DZ)91``") +XM!"3H_OH``,=$)`P(Q`@(QT0D"$````#'1"0$`0```*.87PD(H8"8"@B)!"3H +XM9%$``(D$).C,^@``QT0D#`V^"`C'1"0(00```,=$)`0!````HYQ?"0BA@)@* +XM"(D$).@R40``B00DZ)KZ``#'1"0,*+X(",=$)`A#````QT0D!`$```"CH%\) +XM"*&`F`H(B00DZ`!1``")!"3H:/H``,=$)`P[O@@(QT0D"$0```#'1"0$`0`` +XM`*.D7PD(H8"8"@B)!"3HSE```(D$).@V^@``QT0D#%&^"`C'1"0(10```,=$ +XM)`0!````HZA?"0BA@)@*"(D$).B<4```B00DZ`3Z``#'1"0,7[X(",=$)`A& +XM````QT0D!`$```"CK%\)"*&`F`H(B00DZ&I0``")!"3HTOD``,=$)`QQO@@( +XMQT0D"$<```#'1"0$`0```*.P7PD(H8"8"@B)!"3H.%```(D$).B@^0``QT0D +XM#(B^"`C'1"0(2````,=$)`0!````H[1?"0BA@)@*"(D$).@&4```B00DZ&[Y +XM``#'1"0,FKX(",=$)`A)````QT0D!`$```"CN%\)"*&`F`H(B00DZ-1/``") +XM!"3H//D``,=$)`RHO@@(QT0D"$H```#'1"0$`0```*.\7PD(H8"8"@B)!"3H +XMHD\``(D$).@*^0``QT0D#"S$"`C'1"0(2P```,=$)`0!````H\!?"0BA@)@* +XM"(D$).AP3P``B00DZ-CX``#'1"0,3,0(",=$)`A,````QT0D!`$```"CQ%\) +XM"*&`F`H(B00DZ#Y/``")!"3HIO@``,=$)`RQO@@(QT0D"$T```#'1"0$`0`` +XM`*/(7PD(H8"8"@B)!"3H#$\``(D$).AT^```QT0D#,*^"`C'1"0(3@```,=$ +XM)`0!````H\Q?"0BA@)@*"(D$).C:3@``B00DZ$+X``#'1"0,<,0(",=$)`A/ +XM````QT0D!`$```"CT%\)"*&`F`H(B00DZ*A.``")!"3H$/@``,=$)`R]P``QT0D +XM#-B^"`C'1"0(40```,=$)`0!````H]A?"0BA@)@*"(D$).A$3@``B00DZ*SW +XM``#'1"0,\;X(",=$)`A2````QT0D!`$```"CW%\)"*&`F`H(B00DZ!).``") +XM!"3H>O<``,=$)`S`Q`@(QT0D"%,```#'1"0$`0```*/@7PD(H8"8"@B)!"3H +XMX$T``(D$).A(]P``QT0D#`V_"`C'1"0(5````,=$)`0!````H^1?"0BA@)@* +XM"(D$).BN30``B00DZ!;W``#'1"0,([\(",=$)`A5````QT0D!`$```"CZ%\) +XM"*&`F`H(B00DZ'Q-``")!"3HY/8``,=$)`P]OP@(QT0D"%8```#'1"0$`0`` +XM`*/L7PD(H8"8"@B)!"3H2DT``(D$).BR]@``QT0D#%>_"`C'1"0(5P```,=$ +XM)`0!````H_!?"0BA@)@*"(D$).@830``B00DZ(#V``#'1"0,9[\(",=$)`A8 +XM````QT0D!`$```"C]%\)"*&`F`H(B00DZ.9,``")!"3H3O8``,=$)`QROP@( +XMQT0D"%D```#'1"0$`0```*/X7PD(H8"8"@B)!"3HM$P``(D$).@<]@``QT0D +XM#(F_"`C'1"0(6@```,=$)`0!````H_Q?"0BA@)@*"(D$).B"3```B00DZ.KU +XM``#'1"0,F+\(",=$)`A;````QT0D!`$```"C`&`)"*&`F`H(B00DZ%!,``") +XM!"3HN/4``,=$)`RSOP@(QT0D"%P```#'1"0$`0```*,$8`D(H8"8"@B)!"3H +XM'DP``(D$).B&]0``QT0D#,R_"`C'1"0(70```,=$)`0!````HPA@"0BA@)@* +XM"(D$).CL2P``B00DZ%3U``#'1"0,W[\(",=$)`A>````QT0D!`$```"C#&`) +XM"*&`F`H(B00DZ+I+``")!"3H(O4``,=$)`SOOP@(QT0D"%\```#'1"0$`0`` +XM`*,08`D(H8"8"@B)!"3HB$L``(D$).CP]```QT0D#`S`"`C'1"0(8````,=$ +XM)`0!````HQ1@"0BA@)@*"(D$).A62P``B00DZ+[T``#'1"0,'\`(",=$)`AA +XM````QT0D!`$```"C&&`)"*&`F`H(B00DZ"1+``")!"3HC/0``,=$)`PNP`@( +XMQT0D"&(```#'1"0$`0```*,<8`D(H8"8"@B)!"3H\DH``(D$).A:]```QT0D +XM#$+`"`C'1"0(8P```,=$)`0!````HR!@"0BA@)@*"(D$).C`2@``B00DZ"CT +XM``#'1"0,3\`(",=$)`AD````QT0D!`$```"C)&`)"*&`F`H(B00DZ(Y*``") +XM!"3H]O,``,=$)`Q````,=$)`0!````HW1@"0BA@)@* +XM"(D$).BF1@``B00DZ`[P``#'1"0,K,4(",=$)`AY````QT0D!`$```"C>&`) +XM"*&`F`H(B00DZ'1&``")!"3HW.\``,=$)`SP```,=$ +XM)`0!````HX!@"0BA@)@*"(D$).@01@``B00DZ'CO``#'1"0,ML$(",=$)`A\ +XM````QT0D!`$```"CA&`)"*&`F`H(B00DZ-Y%``")!"3H1N\``,=$)`S-P0@( +XMQT0D"'T```#'1"0$`0```*.(8`D(H8"8"@B)!"3HK$4``(D$).@4[P``QT0D +XM#`#&"`C'1"0(@````,=$)`0!````HXQ@"0BA@)@*"(D$).AZ10``B00DZ.+N +XM``#'1"0,W\$(",=$)`B!````QT0D!`$```"CD&`)"*&`F`H(B00DZ$A%``") +XM!"3HL.X``,=$)`SYP0@(QT0D"((```#'1"0$`0```*.48`D(H8"8"@B)!"3H +XM%D4``(D$).A^[@``QT0D#$C&"`C'1"0(@P```,=$)`0!````HYA@"0BA@)@* +XM"(D$).CD1```B00DZ$SN``#'1"0,"\((",=$)`B$````QT0D!`$```"CG&`) +XM"*&`F`H(B00DZ+)$``")!"3H&NX``,=$)`P@P@@(QT0D"(4```#'1"0$`0`` +XM`*.@8`D(H8"8"@B)!"3H@$0``(D$).CH[0``QT0D##?""`C'1"0(A@```,=$ +XM)`0!````HZ1@"0BA@)@*"(D$).A.1```B00DZ+;M``#'1"0,5<((",=$)`B' +XM````QT0D!`$```"CJ&`)"*&`F`H(B00DZ!Q$``")!"3HA.T``,=$)`QFP@@( +XMQT0D"(@```#'1"0$`0```*.L8`D(H8"8"@B)!"3HZD,``(D$).A2[0``QT0D +XM#'#&"`C'1"0(B0```,=$)`0!````H[!@"0BA@)@*"(D$).BX0P``B00DZ"#M +XM``"CN&`)"(/$%%M=PY"0D)"053'`B>6+50A75E.+"H7)="B+-=A@"0B)UXVT +XM)@````!IP/$````QTHT$`8M/!(/'!/?VA6#["BA0)D+"(E=](EU^(E]_(7`=`J+'=A@"0B%VW5RBQW4 +XM8`D(A=L/A;````"+'?!@"0B+->Q@"0B)WP'W=$6A@)@*",=$)`P!QP@(QT0D +XM"`0```#'1"0$#0```(D$).CI0@``:\YDB5PD"(ET)`2)RL'Z'XD$)(G(]_^) +XM1"0,Z&D\`P"+7?2+=?B+??R)[%W#BS7,8`D(A?9TA*&`F`H(QT0D#*3&"`C' +XM1"0(`@```,=$)`0-````B00DZ(U"``"-%/4`````B50D"(E<)`2)!"3H%CP# +XM`.E#____D*&`F`H(QT0D#.S&"`C'1"0(`P```,=$)`0-````B00DZ$M"``") +XM7"0$B00DZ-\[`P#I&O___XUV`(V\)P````!5B>6#[`BAT&`)",<%0)D+"``` +XM``")!"3HX^T"`,<%T&`)"`````#)PXVT)@````!5B>53@^P4QT0D!,28"@C' +XM!"2`,@D(Z#5*`0"%P'1+BQWH=@H(Z&;\``"+10C'!<"8"@@!````QP7H=@H( +XM`````(D$).BG[```QP0D"@```.AK_@``Z#;\``")'>AV"@C'!<"8"@@````` +XM@\046UW#58GE5E.#['"+10B%P'0&BPB%R75KBT4,B00DZ*!;`P")QHU%F(E$ +XM)`2)-"3H*V+__X/``70@BU40A=)U(P^W3:")RH'B`/```('Z`(```'4%@^%) +XM=5*#Q'`QP%M>7<.0#[=-H+@!````B7<.+ +XM50R)!"2)5"0$Z(%8`P")PXD$).@G6P,`B1PDB<;HO>P"`.EZ____B30DQT0D +XM!`$```#HA&'__X7`#Y3`@\1P6P^VP%Y=PXGVC;PG`````%6)Y5=64X/L+(M% +XM#(M]"(7`#X5A`@``QT7P`````*$@)`D(P>`$!>#2"`@]X-(("'9YN_#2"`B+ +XM0_")!"3HWEP#`(D\)(E$)`3HKE[__X7`=4.+10R%P`^$Z@$``*&`F`H(QT0D +XM#"W'"`C'1"0("0```,=$)`0-````B00DZ#Y```")?"0$B00DZ-(Y`P#'1?`! +XM````H2`D"0B)VH/#$,'@!`7@T@@(.=!WC,=$)`3$F`H(QP0DE#()".A12`$` +XMA<")PP^$/P$``*%`F0L(QT7H`````(7`#X5C`@``B7PD!,<$)+@X"0CH4U<# +XM`(E%Y,=$)`0P*@@(B00DZ!#A__^+&X7;#X3S````BS.%]@^$Z0```(M%Z(M5 +XMZ,=%[``````!P,'B`HE%W(E5X.LFB?;V!=1@"0@"#X76````@\,$#X2W```` +XMBS.%]@^$K0```(-%[`&A0)D+"(7`=$C'1"0$C#,)"(DT).B/7?__A"+3>R+!`*#X1_3Z(/P`8/@ +XM`83`=9C'1"0(`````(M%Y(DT)(E$)`3H=/W__X7`#X1L____BW4,A?9T?(L# +XMQP0D4<<("(E$)`3H@S@#`(E\)`3'!"01%PD(Z',X`P"#PP3'1?`!````#X5) +XM____BU7DB10DZ&C?__^+1?"#Q"Q;7E]=PZ&`F`H(QT0D#$7'"`C'1"0("@`` +XM`,=$)`0-````B00DZ(@^``")!"3H(#@#`(MU#(7V=83'1?`!````BT7P@\0L +XM6UY?7<.AT&`)"(M5Z(M-[`^V!!"#X0?3Z(/P`8/@`>DI____B3PDZ'!8`P#' +XM1"0$+P```(D$).APW0``A<`/A;@```#'1"0$E'8*"(D\).AH1@$`A<`/A&?] +XM___'1"0$E'8*"(D\).A01@$`A<")PP^$3?W__Z&`F`H(QT0D#!O'"`C'1"0( +XM"````,=$)`0-````B00DZ-$]``")?"0$B00DZ&4W`P"+`X7`=`B)!"3HI^@` +XM`,<$)`H```#H:_H``,=%\`$```#I_?S__Z'08`D(BU77UW# +XMD%6)Y593@^P0BU4(BT($A575E.#[$R+10B+>`C'1"0$E'8* +XM"(L'B00DZ.]$`0#'1<0`````A#2"`@/AKP```"^ +XM\-((".L:H2`D"0B)\H/&$,'@!`7@T@@(.=`/AIL```"+1O")!"3H*U@#`(L? +XMB1PDB40D!.CY6?__A7UW#C;0F`````#G(#X18____#0```$")`X/# +XM!(/"!(L"A)!"3H28D``(D'B00DQT0D!#`J"`CH9]S__XL7 +XMB57(B10DZ#I5`P#'1"0$+P```(D$).@ZV@``B474QT0D!,28"@C'!"24,@D( +XMZ#-#`0"%P'00BS"%]G0*BP:%P`^%#0(``+[`(`D(BT7(QP0DN#@)"(E$)`3H +XM-U(#`,=%T`````")1=BA0)D+"(7`#X6?`@``BT70BU70BQ['1")5=SK/XL#A<`/A8$```#'1"0(`````(M%R,<$)`````")1"0$Z,_X +XM__^%P`^%E0```(M>!(/&!(7;#X1+`0``@T7,`8M%U(7`=;J+`X/X+W6UBPU` +XMF0L(A[`0```,<$),`X"0B)1"0$Z+-0`P")!XD$),=$)`0P*@@( +XMZ'':__^+50B)%"3H-K8``(L'B00DZ+S9___K,X/"!(D7BPKIL_S__XM%V(D$ +XM).C#Y`(`BT4,A<`/A)T```"+!S';B00DZ.Q0`P"+50R)`HU%[(D$).A\V?__ +XM@\1,B=A;7E]=PXM%U(7`#X3M_?__Z>/]__^AT&`)"(M5T(M-S`^V!!"#X0?3 +XMZ(/P`8/@`>F6_O__BT7$A<`/A;D```"A@)@*"(L?QT0D#%7'"`C'1"0(!0`` +XM`,=$)`0-````B00DZ&$X``")7"0$B00DZ/4Q`P#HX/(``.FJ_/__BT7$A<`/ +XMA8$```"A@)@*"(L?QT0D#'+'"`C'1"0(!@```,=$)`0-````B00DZ!DX``") +XM7"0$,=N)!"3HJS$#`.B6\@``Z2K___^+5"+3

3@,`B0>)'"3H).,"`,=$)`0P*@@(BP>)!"3HDMC__XM5#(72=".+!XD$ +XM).A!3P,`BU4,B0*+![L!````B00DZ,W7___I0?[__XM5"(D4).@MM```Z]^- +XM="8`C;PG`````%6)Y5=64X/L+(M=",=$)`3$F`H(QP0DE#()".@P/P$`A=N) +XMQG1BBT,$A`$`A?;'!4"9"P@!````#X1R`0``BS:%]@^$:`$` +XM`(L&A<`/A%X!``#'1?``````ZQB#Q@0/A$P!``"+!H7`D`^$00$``(-%\`&# +XM."]UXXD$).B93P,`B00DZ#U6__^%P(G'=,V)!"3'1"0$,!X%".B;UO__BT7P +XMBU7P@^`?@^(/B47HB57DB3PDZ'U9__^%P(G"#X3=````BPJ%R73H@'H(+G4; +XM@'H)`'3B-%(4`````N`$````#%=!@ +XM"0C3X`D"]@748`D(`0^$=?___XD<).@&40,`B00DZ/[P___'1"0,BL<(",=$ +XM)`@!````QT0D!`T```")1>RA@)@*"(D$).AV-```BU7PBTWLB5PD#(E4)`B) +XM3"0$B00DZ/PM`P")/"3HH%C__X7`B<(/A2/___^)/"3H\M3__X/&!`^%M/[_ +XM_X/$+%M>7UW#BTWP`P708`D(@^$'T^(($.EA____H2-%`"X`0````,5T&`)"-/@9@D"Z3C____'!53@^P4BUT(QT0D +XM"`````#'!"0"````C4,DB40D!.C75?__C4,\QT0D"`````")1"0$QP0D`P`` +XM`.B\5?__C4-4QT0D"`````")1"0$QP0D#P```.BA5?__QP7\F`H(`````(M# +XM(*/H=@H(H;1V"@B)!"3H!M<``*',EPH(B00DZ/G6``"A!'8*"(D$).CLU@`` +XMH429"PB)!"3HW]8``(M#$(E$)`2+`XD$).@>VP``QT0D"`$```#'1"0$`@`` +XM`(D$)*.T=@H(Z,U0__^+0Q2)1"0$BT,$B00DZ._:``#'1"0(`0```,=$)`0" +XM````B00DH\R7"@CHGE#__XM#&(E$)`2+0PB)!"3HP-H``,=$)`@!````QT0D +XM!`(```")!"2C!'8*".AO4/__BT,A@"0B)!"3H[=T" +XM`,<%Z&`)"`````"AY&`)"(7`=!")1"0$QP0D-P``$.A:T/__QP0D#0``$.A. +XMT/__R57B==64X/L+(E%V(D4).BZ3`,`B<.+1=B) +XM!"3H[4L#`(D=7)D+"(G&Z`Q3___'``````")7"0$B30DZ#I4___'!5R9"P@` +XM````B1PDZ*S6``#HXU+__XL`@_@(=%"#^`QT&X/X`G0-H>1@"0B%P`^$N@$` +XM`(/$+%M>7UW#D.BW4O__BP")!"3H75#__XET)`3'!"0V````B40D".B=S___ +XM@\0L6UY?7<.0C70F`,=$)`0`````B30DZ,#2``")1>"#P`%T+XU%\L=$)`@" +XM````B40D!(M%X(D$).A.T@``@_@"#X2!`0``A)!XE\)`2+1=R)!"3H(=<``(DWB<.+.(D$ +XM).AS2P,`B3PDB<;HJ4H#`(D<)(G'Z#_<`@"+1=R)!"3HA-4``(ET)`2)/"2) +XM-5R9"PCH[E+__XDT),<%7)D+"`````#H8-4``.B74?__BP")!"3H/4___XE\ +XM)`3'!"0V````B40D".A]SO__@\0L6UY?7<.0C70F`,=$)`3$F`H(QP0D*#() +XM".A,.`$`A<`/A-T```#'1"0$Q)@*",<$)"@R"0CHD#@!`(-]X/^)1>AT#H!] +XM\B-T"*&DF`H(B47HQT7L`````(U%Z(D$).C'V0``B47")!"3H^-(``(D<).@\3O__B70D!,<$)'@```")1"0( +XMZ'S-___I+O[__Z%T=PH(Z2W___^-M@````"-O"<`````58GE5U93@^Q,BWT( +XMC5WLBT<0BP#'1?``````B47LBT4,A%P`^$Y0$``(L(AO__\<%M'8*"``` +XM``#'!QT70``````'2P>`"B56XB46\ZRJ)]HL#AQ@"0@!QP5,F0L(`````(D4 +XM).B4UP(`Z&_Y__^#Q$Q;7E]=PXM%R(7`#X2I_O__Z9_^__^+!XD$).C]Y___ +XMB47,Z<#^__^AT&`)"(M5S(M-T`^V!!"#X0?3Z(/P`8/@`>DU____B40D!(D< +XM).A:>```A<")Q@^%G_S__XM%[(D$).B%10,`QP0D,0``$*,@=PH(Z*3)___I +XM?OS__XD<)(E$)`3H(W@``(7`B<,/A03]__^AZ&`)"(D$).A,10,`QP0D,0`` +XM$*,@=PH(Z&O)___IX?S__XVV`````*'H8`D(BQ"#^B\/A(G\__^#^BX/A(#\ +XM___HDOC__Z'H8`D(Z7'\__^AT&`)"(M5N(M-T`^W!`*#X0_3Z(/P`8/@`>EX +XM_O__B?:-O"<`````58GE5E.#Q("AC'8*"(MU#(7`=0VAE'<*"(7`#X5/`@`` +XMQT0D!,28"@B-78S'!"1@-@D(Z,@R`0#'!"0`````A<`/E<`/ML")1"0$Z$"$ +XM``"-1;")1"0(QT0D!-!V"@C'!"0"````Z(%,__^-1")1"0(QT0D!%1W"@C'!"0/````Z$M,__^AZ'8*"(L5 +XMM'8*",=$)`3_____B46LHAV"@@` +XM````Z+O)___'!"3_____Z!_O`@")-"3'1"0$`0```.A/^?__B1PDZ/?(__^# +XM[(!;7EW#QP0D`````.ADZ@``Z:#]__^0D)"0D)"0D)"0D)"0D)!5A<")Y5.) +XMTP^$`@$``(L(A='N#^2)T=HUT +XM)@"#XPAT8(/Y/+@$````C78`=`>#^3ZP`G5,6UW#C70F`(M`"(7`==GVPQ!T +XM%H/Y?)!T.(/Y/'1N@_D^=0:#^CZ0=##VPP1TN8/Y/70_@_DAD'6N@_H]N`8` +XM``!TO8/Z?K`(=9WKM%LQP%W#@_HFC78`==!;N`$```!=PXVV`````(G06UW! +XMZ`2#X`'#@_H]=.*#^GZX!P````^%8O___XGVZ73___^#^CQUF(VV`````.O` +XMC;0F`````(V\)P````!5B>6#['B)!"2)7?2)=?B)UHE]_.CG0`,`@#@`B<-T +XM(8U&_X/X`78@B70D!(D<).A(1___BUWTBW7XBWW\B>Q=P[@!````Z^R-192) +XM1"0$B1PDZ$5'__^#P`%TY8ET)`2)'"3H%$?__X7`#X2"````BT6@.P4LF0L( +XM#X26````BT6D.P7HF`H(=%7'!"0$````Z'9&__^#^/^)QP^$H0```(7`#XZH +XM````C12%`````(D4).BXT@(`B3PDB<.)1"0$Z`9'__^+?:2-#(.)PHGV@^H! +XM>&.+0?R#Z00Y^'7Q#[=5G,'F`S'`A=8/E,#I0O___P^W59R)T"4`\```/0!` +XM``!T&H/^`70B@_X"="2)]N@G1?__#[=5G,'F!NO(9C'`@_X!=>/I"?___[Y) +XM````Z[1FOI(`ZZX/MU6575E.! +XM[/P```"+?0B)^X/#!(L#QP0DIL<("(E$)`3H:L0``(7`=>>+`X7`=0V#>_Q, +XMC5/\#X0``P``B40D!,<$)+W'"`CH0\0``(7`=7O'A13______P``QX48____ +XM`````,>%(/___Q`O"0B+`X7`#X6P````C4<$.=@/A*4```"+10RZ'P```(L8 +XMBS.)\.B9_/__A<`/A4D"``"+50R-0P2)`O9%$`$/A(D```#'!"3X;PD(Z*,\ +XM`P")QX'$_````(GX6UY?7<.+,X/#!,>%%/______``#'A2#___]L+PD(@_Y& +XM=!.#_E#'A2#___\@+PD(#X1)`@``QT0D!&PO"0B)'"3H?T+__X7`#X3^`0`` +XMQX48____`````(L#A<`/A%#____'!"1Z```0Z'O"___I2O___XDT)#'VQT0D +XM!`(```#H)'(``(F%'/___XD$),=$)`0P*@@(Z#[%__^+5P2-1P3'A1#___\` +XM````,?^)PXU"J(/X('9"A=(/B-8````Y%=Q="0@/CLH```"AX%T)"(N$D#0$ +XM``"#^&P/A,````"%_P^$ZP0``(U"OX/X.7#PP2%]G6)BY4<____B10D +XMZ`7$__^)-"3HG2P!`('$_````%M>B<>)^%]=P[H"````Z[.+E1S___^)%"3H +XM63T#`(D$).C]/___B00DZ`5'__^)QNNDN@0```#KBL=$)`0`````BX4<____ +XMB00DZ#CB__^)QNN#B="#^&P/A4#___^+A1#___^%P`^$500``(/Z3`^%,?__ +XM_XN]$/___XM3!(U#!+X!````A=(/A=W^__^+E1S___^)%"3HVSP#`(D$).CC +XMQ@``B[4@____A<")PW0*B00DZ.\^`P")QHD<).A5S@(`BX4<____B00DZ"?# +XM__^)-"3H?SH#`(G'Z=?]__^)-"3HD#P#`(U5B(E4)`2)!"3H'4/__X7`#X6C +XM````BU4,BQJ+,^F,_?__B70D!,<$),K'"`CH;<$``(7`#X3J_?__@\,$QX48 +XM____`0```.DR_?__B=.P3.GW_/__BP.#^"\/CJS]__^#^#QX4@____("\)".E:_?__,?;I-?[__\<$)`L``!#H^K___XM% +XM#(L8BS/IW?S__X/Z00^$=P,``(/Z30^$G`,``(MW*(N5&/___XEU\(72#X3W +XM_?__C47PB00DZ'E!__^)!"3HM3T#`,=$)`0*````B00DBF-?>B)\R7_#0``(X44____QT0D"-''"`C'1"0$!P```(E$)`R)-"3HPAD# +XM`(N%&/___X7`=`R`?>DP=`;&1>@PB?N+E1S___^)%"3HCL#__XD<).@V/`,` +XMB00DZ-XW`P")Q^DV^___BWC[__\/MT<()0#P```] +XM`"````^4P`^V\.G/^___#[='""4`\```/0!````/E,`/MO#IMOO__[X!```` +XMZ:S[__\/MT<()0#P```]`(````^4P`^V\.F3^___#[=W",'N"H/F`>F$^___ +XM#[=W",'N"8/F`>EU^___BY40____#[="""4`\```/0"@```/E,`/MO#I5OO_ +XM_XMW!.E.^___#[=W"NE%^___BY4<____B10DZ-@X`P"-58B)5"0$B00DZ&4_ +XM__^#P`$/A+@```"+$XU]B.GE^O__BX4<____B00DZ*@X`P"-E2C___^)5"0$ +XMB00DZ`(\__^#P`$/A*@```"+$XV%*/___XF%$/___^EO^___BT<0B00DZ!_! +XM``"%P(GX_?__BY4<____B10DZ->^__^+!HD$).A].@,`B00DZ"4V`P") +XMQ^E]^?__BW<8Z8W\__^+1PR)!"3H.\```(7`B<8/A+3]__^+A1S___^)!"3K +XMNHVV`````(MW(.E?_/__BX4<____B00DZ'J^__^+E2#___^)%"3HS#4#`(G' +XMZ23Y__^+E1S___^)%"3H5[[__XN%(/___XD$).BI-0,`B57B<=64X/L'(E5 +XMZ.@M"@``B47PB00DQT0D!#`J"`CH:K[__XL?N@0```"+`^CL]/__A<")Q@^$ +XMH@```(U#!(D'C4;YBUWH@_@!#X;>````B=J)^.CE"0``B47LQT0D!#`J"`B) +XM!"3H(K[__X/C`74?@_X5````C70F`'YN@_X'#X2M````@_X(B?9T?XM% +XM\(D$).A3O?__BQ^+`X7`=!3'1"0$,#L)"(D$).C'.O__AR)1"0$BT7P +XMB00DZ)UP``"%P`^4P`^V\.EB____@\L"Z1K___^+1>R)1"0$BT7PB00DZ'9P +XM``")QNE!____BT7LB40D!(M%\(D$).@9.O__A<`/E<`/MO#I(O___U6)Y8/L +XM&(E=](G#B77XB7W\B57PZ'?^__^+.XG&BP>%P'04QT0D!"@["0B)!"3HV3G_ +XM_X7`=`^)\(M=](MU^(M]_(GL7<.+5?"-1P2)`XG8Z*O___\QQNO>C;0F```` +XM`%6)Y8/L&(E=](G#B77XB7W\B57PZ(?___^+.XG&BP>%P'04QT0D!"`["0B) +XM!"3H>3G__X7`=`^)\(M=](MU^(M]_(GL7<.+5?"-1P2)`XG8Z*O___\)QNO> +XMC;0F`````%6)Y8/L&(E=](G3B77XB<:)??SHB/___XG'BP:)1?"+`(7`=!3' +XM1"0$%#L)"(D$).@7.?__AQ=PXM%\(/`!(7_B08/ +XME,`)PXGP@^,!B=KHG?___X7_#Y7"A<`/E<`/MO@AU^O%C;8`````C;\````` +XM58GE@^P8B5WTBUT,BT4(B77XB7W\B=KH9/___XG&BT4(BSB+!X7`=!3'1"0$ +XM"#L)"(D$).B3./__AQ=PXUT)@"+50B#XP$)\XU' +XM!(D"#Y7`#[;`B40D!(D4).B1____"?`/E<`/MO#KQ(VT)@````!5B>57B<=6 +XM4X/L3(E5O(L8BS.%]@^$&P(``,=$)`1`.PD(B30DZ"(X__^%P'5)@\,$B?B) +XM'XM5O.C#____QT0D!#`J"`B)PXD$).@1N___B=CH*OS__XD<)(G&Z&"Z__\Q +XMP(7V#Y3`B00DZ/$B`0"#Q$Q;7E]=P\=$)`1(.PD(B30DZ,4W__^%P'5%@\,$ +XMB?B)'XM5O.AF____QT0D!#`J"`B)QHD$).BTNO__B?#HS?O__XDT)(G#]]/H +XM`;K__XD<).B9(@$`@\1,6UY?7<.0QT0D!%`["0B)-"3H;#?__X7`=4R#PP2) +XM'XM%O(D\)(E$)`3HB/[__XG&BP>+$(72=`6#.BET#L<$)"$``!#H7;?__XL' +XMC5@$B1^)-"3H/B(!`(/$3%M>7UW#C;8`````QT0D!%@["0B)-"3H##?__X7` +XM#X4?`0``B=Z#Q@2-1>R)7<")\\9%R`''1# +XM/BT/A$L!``#V1;P"#X0L`0``B30DZ(DO`P#IT_W__XL'C5C\B1_'0/P````` +XMQT0D"`(```#'1"0$$"\)",<$)/0N"0CHZB@!`(U%X(E%Z(G#B47DQT7@^&\) +XM"(L&AW__^A@%X)"(7`=`S'!"0```!`Z/*T___'1"00`0```,=$)`P` +XM````QT0D"`````#'1"0$_____XD<).BZ`0$`C47@B00DZ`^W___HFE;__^DI +XM_O__QT0D!`(```")-"3H960``.F?_/__BT8$QP0DIL<("(E$)`3H;;4``(7` +XM=1N+1@3'!"2]QP@(B40D!.A6M0``A<`/A(/^__^+1;R)?"0$B30DB40D".BK +XM\/__Z57\__^-M@````!5B>6#["B)7?2)PXEU^(E]_(G7Z,C[__^Z`@```(E% +XM\(LSBP:)1>SHI.W__X7`=":-1@3WQP(```")`W0IBU7PB10DZ'C!`@"+1>R) +XM!"3HK2T#`(E%\(M%\(M=](MU^(M]_(GL7<.+5?#'1"0$,"H("(D4).C'MO__ +XMB?J)V.A^____QT0D!#`J"`B)QHD$).BLMO__@^+5>R+`H/X*G1G@_@O +XM=$*#^"5T'8UV`#'VBT7PB00DZ..U__^)-"3H>QX!`(E%\.N,B?#HC_?__X7` +XMB<-T2XM%\.B!]___B<+!^A_W^XG6Z\B)\.AO]___A<")PW0[BT7PZ&'W__^) +XMPL'Z'_?[B<;KJ(M%\.A.]___B<.)\.A%]___B<8/K_/KD,<$)$@```#H(K/_ +XM_XGVZZ7'!"1'````Z!*S__^)]NNUC;0F`````(V\)P````!5B>6#["B)7?2) +XMPXEU^(E]_(G7Z)C^__^Z`0```(E%\(LSBP:)1>SH5.S__X7`=1"+1?"+7?2+ +XM=?B+??R)[%W#C48$B0.+5?#'1"0$,"H("(D4).B8M?__B?J)V.B?____QT0D +XM!#`J"`B)QHD$).A]M?__@^R+`H/X*W0?@_@M=#`QVXM%\(D$).B\ +XMM/__B1PDZ%0=`0")1?#KCXM%\.AG]O__B<.)\.A>]O__C1P8Z]*+1?#H4?;_ +XM_XG#B?#H2/;__RG#Z[V-="8`58GE@^P8B5WTB77XB<:)??R)5?#H%____XG' +XMBP:+&(7;=!V+`\<$)-3'"`B)1"0$Z-NR``"%P'0'BP,[0P1T$(GXBUWTBW7X +XMBWW\B>Q=PY"#!@3'1"0$,"H("(D\).B]M/__BU7PB?#HD____\=$)`0P*@@( +XMB<:)!"3HH;3__X,[/'0HB?CHM?7__XG#B?#HK/7__XG!T_N)/"3HX+/__XD< +XM).AX'`$`BBP/HMNK__X7` +XMB<R)\.B#____QT0D!#`J"`B) +XMQHD$).C!L___]D7L`74=@_\#='F-M@````!^-H/_!`^$@P```(/_!8GV=$:+ +XM1?")!"3H\[+__XD\).B+&P$`B47PBT7PBUWTBW7XBWW\B>Q=PX/_`G75BT7P +XMZ(OT__^)PXGPZ(+T__\YPP^?P`^V^.NZBT7PZ'#T__^)PXGPZ&?T__\YPP^> +XMP`^V^.N?BT7PZ%7T__^)PXGPZ$ST__\YPP^=P`^V^.N$BT7PZ#KT__^)PXGP +XMZ#'T__\YPP^Q=PXGVN@$```#&1=W_Z]20C70F`%4QP(GE7>N(D(VT)@`` +XM``!5B>6#[`B)'"2)="0$BW4(BUT,Z%0R___'``````"+`XE%#(L&B44(BQPD +XMBW0D!(GL7>GU,O__B?:-O"<`````5;@!````B>575E.![$PA``#H*O___XU% +XM\,=$)`1`;04(B00DZ/>Q__^-A3/?__^)1"0$H;1V"@C'1"0(`"```(D$).C8 +XML0``A<")1?`/CM8-``"-E3/?__^)%"3&A`4SW___`.C'+`,`BTT(B0PDB40D +XM!.A$+O__BT4(B00DZ#DO__^+50B)1?"+7(+\@^-_@_L*#X20#0``.T4,#X2' +XM#0``,<"#^QL/E,"%P(F%V-[__P^$U0<``(M%\(/[&XM-"(T$@8F%S-[__P^$ +XM4`@``(N%S-[__\<``````(M5"#F5S-[__XF%T-[__W9"BXW,WO__B8W0WO__ +XMZQ>0C70F`(.MT-[__P2+C=#>__\Y30AS'8N5T-[__XM"_,<$)&#)"`B)1"0$ +XMZ#$R__^%P'31BX70WO__QT7L`````,=%E`````#'19@`````QT6<`````(,X +XM?@^$4P<``(N5T-[__\=$)`0O````B10DZ)PL__^+C=#>__\QTHF-W-[__X7` +XM=!2#P`2)PBN5T-[__XF%W-[__\'Z`HN-T-[__XE4)`2)#"3HF"<#`,=$)`0P +XM*@@(B87@WO__B00DZ&*P__^+A>#>__^#.'X/A$@&``")!"3H"R<#`(F%Y-[_ +XM_XN=Y-[__X7;#X1Z!@``BXWDWO__QT0D!#`J"`B)#"3H(;#__XN5Y-[__[B2 +XM'0D(BPJ%R0^%E0@``(D$).B0+___A<")A?S>__\/A!@,``#'A?C>__\````` +XMBXW__^)!"3HK*___\>%[-[__P$```#'A>C>__\`````B[7XWO__ +XMA?8/A.D$``#HT3+__X7`#X2M````BP")!"3H@RH#`(G'A?^)^8N5W-[__W4/ +XMZ9`````[`77$@\($@\$$BP*%P'7PBX7TWO__AR+ +XM`H7`#X13"P``.PL(.P2/C78`=0R#P@2#P0&+`H7`=>S'`@`` +XM```[C?3>__\/A3C___^+G>S>__^%VW0+BTV8A__^%P`^$ +XM0P<``(M%F(7`#X1H!```@[W8WO__`0^%2@<``(N%T-[__RM%"(M5#,'X`BG" +XMBX7XWO__C5K_A<`/A*,*``"+C=#>___'1"0(`@```,=$)`1(.PD(B0PDZ`5: +XM`0"+1>R+C=#>__^)7"0(B40D!(D,).B,60$`BX7@WO__B00DZ(ZM__^+79C' +XM!"0(````Z-_(``#'!"0(````Z-/(``"+C__^)#"3HH2O__X7`#X5B!@`` +XMQP0D(````.BQR```QP0D(````.BER```QP0D"````.B9R```QP0D"````.B- +XMR```Z`C'``"-C33___^#ZP&)C<#>__]T*,=$)`3$F`H(QP0D\$4)".BC%`$` +XMC94T____B97`WO__A<`/A/D)``"+10C'1"0$"0```(D$).BX+O__QX74WO__ +XM`````(7`#X3J````@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".A/K?__BY7$WO__ +XMH__^#992_B47`BT68B4PD"(-EF/V) +XM1<2+19S'1"0$`````(E%R(M%H(E%S(M%I(E%T(M%J(E%U(M%K(E%V(M%L(E% +XMW(M%M(E%X(M%N(E%Y(M%O(E%Z*',EPH(B00DZ'^L``"AS)<*",=$)`@!```` +XMQT0D!$;)"`B)!"3H$JP``(U%P(E$)`BAS)<*",=$)`0`````B00DZ$:L``#' +XM!"3$K`L(Z.JK___'A=3>__\!````BXW8WO__A__^%TG04 +XMQT0D!`````#'!"0`````Z-03`P"#!<2L"P@!QT0D!+"0"`C'!"3$K`L(Z#FL +XM__^+E<3>__^AS)<*"(E4)`2)!"3H_B?__XM%E(N-Q-[__\=$)`0`````B84T +XM____BT68B4PD"(F%./___XM%G(F%//___XM%H(-EH(")A4#___^+1:2)A43_ +XM__^+1:B)A4C___^+1:R)A4S___^+1;")A5#___^+1;2)A53___^+1;B)A5C_ +XM__^+1;R)A5S___^AS)<*"(D$).A,JP``BU4(BP*%P'12B=__^%P`^$$?G__XN5P-[__Z', +XMEPH(B50D!(D$).C-)O__BXW`WO__H%Z-[_ +XM_P````"+A?S>__^)!"3HCRW__X7`#X2[^___@\`(B00DZ)`E`P")Q^D(^___ +XMBY7HWO__A=(/CK#[__^+A?C>__^%P'2>Z,@L___'A>S>__\`````QX7HWO__ +XM`````.FK^O__C464B87$WO__BX7@WO__B00DZ(RI__^-E33___^+79B#O=C> +XM__\!B97`WO__#X6!_/__Z>#[__^+E>#>__^+G>#>__^+0@2#PP2%P`^%S@$` +XM`,=$)`3$F`H(QP0DD"\)".@]$0$`B5PD!(D$).@!(`,`B87DWO__BYWDWO__ +XMA=L/A8;Y__^-592)E<3>___I=?___XD\).AG(`,`C564B10DB40D!.A('@,` +XMZ?OY___'!"0*````Z/?$``#I&OC__\>%U-[__P$```#I"_W__\=$)`0O```` +XMB00DZ)\J__^%P`^%E?C__^C"*___BY70WO__QT0D!#`J"`C'!"0`````@\($ +XMB97__\`````QX7DWO__`````,>%^-[__P$```#'A>#> +XM__\`````Z1KY__^-M@````"#Z`2)A___IHO?__\=$)`3$F`H(QP0D($() +XM".C>#P$`A<`/A+7Y__^+`(7`#X2K^?__BPB%R8F-\-[__P^$F_G__XF%'-__ +XM_XGYBP&#P02%P'7WBY7PWO__BP*#P@2%P'7W.97PWO__#X0Y`0``.?ET+8UR +XM_(M2_#M1_(U!_(G#=1T[M?#>__\/A!D!```Y^W0-BT/\@^X$@^L$.09TXXN% +XM'-___XM`!(.%'-___P2%P(F%\-[__W6/BT68@\`!B468@^@!#X4D^?__B3PD +XMZ.L>`P")1>SIB_C__X/X+P^$*?[__XG>@\8$BP:%P'51.=X/A!;^__^)\"G8 +XMP?@"B1PDB40D!.@4'P,`B<.)!"3HRB`#`(D$).@BJ0``B1PDB___'!"22N0@(B50D!.C,_P(` +XMZ:KY__^)%"3H3R`#`.E>]___BXW\WO__B0PDZ(RI``#IJOC__X.%Z-[__P'I +XML_?__XE$)`2+193'1"0,4&T%",=$)`@$````B00DZ&@C__^+A>3>__^#O?C> +XM__\!BU68BWV4&]%-___X7`B<*)A03?__]U#\>%!-___P$```"Z`0```(N-`-__ +XM_XU$"O^)T3'2]_&)A__^-A33___^)A<#>__^+A__^%P`^.Q`$``(N- +XMR-[__XN%!-___XF](-___\>%"-___P````#!X0*#Z`&)C;S>__^)A;C>__^+ +XMG03?__^%VP^.4`$``(N-(-___S'VB[T(W___B8T8W___ZR*0BX6\WO__@\8! +XM`[W(WO__`848W___.[4$W___#X08`0``.;T`W___=M>+E1C?__^+`L<$))*Y +XM"`B)1"0$Z/_]`@"+A0S?__^Z(````(7`#X2+````BXT8W___BP&)1"0$BX4, +XMW___B00DZ+(;`P")PXD$).A8'@,`B1PDB840W___Z.JO`@"+C1#?__^-E33_ +XM__^)5"0$B0PDZ)XA__^%P'4X#[>-//___XG()0#P```]`*````^$R0```#T` +XMP```NCT```!T&#T`0```LB]T#X/A2;HJ````=06Z(````(D4).AYP```.;6X +XMWO__#XX-____BXT8W___BP&)!"3HB2+__XU8`3N=%-___P^-[O[__\<$)"`` +XM``"#PP'H/\```#N=%-___WSIZ=+^__]FQT7"4`#IW?W__\<$)`T```#H&\`` +XM`,<$)`H```#H#\```(.%"-___P&+E0C?__^#A2#?__\$.97(WO__#X5J_O__ +XMBY7@WO__B10DZ-&C___IW?;__XN5$-___XV%-/___XE$)`2)%"3HT"/__X7` +XM=1P/MX4\____NCX````E`/```#T`0```#X0C____ND````#I&?___XN%S-[_ +XM_\<$))*Y"`B)1"0$Z&3\`@#'!"0@````Z,B^``#'!"0(````Z+R^``#I*O;_ +XM_XU-\(D,).A,H___BT7P@<1,(0``6UY?7<.-392)C<3>___IEOG__XN%X-[_ +XM_XN5T-[__XE<)`B)1"0$B10DZ&1/`0#I6O7__S')QP(`````.XWTWO__#X4# +XM]/__Z<;T__^AS)<*",=$)`@!````QT0D!$3)"`B)!"3HV:(``(V--/___XF- +XMP-[__^G9]?__D)"0D)"0D)!5B>5=PXUT)@"-O"<`````58GE7<<%=&$)"``` +XM``##D%6)Y5W'!=0D"0@!````PY!5B>53@^P$H0!A"0B#^/]T$XD$)/\5\*P+ +XM",<%`&$)"/____^+'8"8"@B#^_]T,\<%@)@*"/_____K&I"-="8`Z/575E.#["R+11"+712)1"0(BT4,B5PD#(E$)`2+10B)!"3H9_[_ +XM_X,]`&$)"/^)QP^$V````#G##X30````B47LB00DZ&$D__^+#?Q@"0B%R8G" +XMC4`!B47H#X2Y````H?Q@"0B-=>2-7?")1?"0BT7HA<`/A(H```"A^&`)"`,% +XM_&`)""M%\(ET)!")7"0,B47DC47HB40D"(U%[(E$)`2A`&$)"(D$)/\5[*P+ +XM"(/``76[Z*(@__^#.`>-=@!U3J'X8`D(`<")1"0$H?Q@"0B)!"3H%JP"`(7` +XMB<)T,(M%\"L%_&`)"-$E^&`)"`'0B47PBT7HB17\8`D(A<`/A7;___^+/?Q@ +XM"0B0C70F`(/$+(GX6UY?7<.-0B&C^&`)"(D$).AVJP(`A<"C_&`)"`^%*O__ +XM_^O7C;0F`````%6)Y5=64X/L+,=$)`1P?`4(QP74)`D(`````,<$)-0D"0CH +XMZ9___Z$@)`D(QT7H`0```(E%\,'@!(VXX-(("('_X-(("'8DN^#2"`@Q]HL# +XMB00DZ!0C__\YQG,"B<:#PQ`Y^W+I@\8!B77HH>"7"@@QTL=%Y`$```#'1>P` +XM````@\`!]W7HA1T +XM6Z$@)`D(P>`$!>#2"`@[1=QVYHM%W(L8B1PDZ'4B__^)7"0$QP0D^]X("(G& +XMZ%?W`@`Y?>Q^&3MUZ',4QP0D(````(/&`>A>N@``.W7H=>R#1=P0@\`Y1=1^%HL]8&0)"(7_=5;'!"0*````Z"^Z``"#1>`!BT78.47@#X5? +XM____BQU@9`D(A=MT#,<$)`T```#H";H``,<$)`H```#H_;D``,<$)-0D"0CH +XMX9W__X/$+%M>7UWIM;<``,<$)`T```#HV;D``.NAV"@B)1=BAS)<*"(E%[*$$=@H(B47PZ.ZC``#'1"0(`0`` +XM`,=$)`0"````B477UW#B1PDB40D!.BR1P``A<") +XMPW0AQT0D!/`C!@B)WXD<).CZF___B1PDZ/*@``")QNDI_O__QP0D,0```.CO +XMF/__Z]&-M@````"-O"<`````58GE4X/L%(M="(L#HTAW"@B+0P3'!?R8"@@` +XM````HTB:"PB+0PBCZ'8*"*&T=@H(B00DZ`B>``"AS)<*"(D$).C[G0``H01V +XM"@B)!"3H[IT``(M#&(E$)`2+0PR)!"3H+*(``,=$)`@!````QT0D!`(```") +XM!"2CM'8*".C;%___BT,6#[`BAP'8*"(7`=3&AE'<*"(7` +XM=`C)PXVV`````,=$)`0!````QP0D`0```.BX&___QP7,K`L(`0```,G#QP0D +XM+@``$.A4E___Z\&)]E6)Y593@^PPH329"PB%P`^%50$``(UUX.@3-___B70D +XM",=$)`0`````QP0D$@```.CW&O__QT0D!`````#'!"02````Z%,;___'1"0$ +XM$@```,<$)`````#H/Q;__\=$)`@`````B70D!,<$)!(```#HMQK__X,]U)<* +XM"/]U:>G4````.QWP=@H(#X2>````B70D",=$)`0`````QP0D%0```.B%&O__ +XMQT0D!`````#'!"05````Z.$:___'1"0$%0```,<$)`````#HS17__\=$)`@` +XM````B70D!,<$)!4```#H11K__\<$)`\```#H&1G__X/X_XG#=8GH31G__XL` +XMB00DZ/,6___'1"0$ILD(",<$)#8```")1"0(Z"^6__\['?!V"@@/A6+___^A +XMW)D+",<$)`````")1"0$Z%H7__^AW)D+",<$)`\```")1"0$Z!45___'!"0/ +XM````Z*VT`@"#Q#!;7EW#QP0D2@```.C:E?__Z9K^__^0C70F`%6)Y5>)QU93 +XM@^P,BQ7@(@D(A=)X4+O@(@D(,?:-="8`BT,$B00DZ*43`P")/"2)1"0$Z*F7 +XM``"%P'02A?9T#,<$)"<``!#HA97__XG>BT,0@\,0A +XM7UW#QP0D%@``$#'VZ%V5___KYHUT)@"-O"<`````58GE@^Q(B7W\B<>-1>2) +XM7?2+70B)=?B+=0R)5=2)1"0$BP>)!"3HD1K__XM%U(7`=#Z+5>B)=?"+1>0[ +XM5?")7>Q]3HU5Y(E4)`2+!XD$).@X'/__,=*%P'A?BUWTB="+=?B+??R)[%W# +XMC;0F`````(GRB=B!\O___W_WT`G"="*)=>B+5>@[5?")7>2+1>1\LG\%.T7L +XM=JN)1>R)5?")]NNAH2R9"PB%P'35BT7LBU7PB47DB57HZXKHCA?__XGR@?+_ +XM__]_BP")1=R)V/?0"<(/A-\```"A@)@*",=$)`S4O@@(QT0D"`,```#'1"0$ +XM#P```(D$).CT]?__B00DZ%R?``#'1"0$,"H("(E%X(D$).@IE___BTW4N$7) +XM"`B%R0^%N0```(D$).@QGP``QT0D!#`J"`B)QHD$).C_EO__BT7")7"04B70D$(E\)`B)5"0,BU78B00DB50D!.CO[@(`BT7@ +XMB00DZ/25__^Z_____^FD_O__H8"8"@C'1"0,L,D(",=$)`@"````QT0D!`\` +XM``")!"3H%?7__^D<____H8"8"@C'1"0,M\D(",=$)`@$````QT0D!`\```") +XM!"3HZ_3__^D=____C;8`````58GE5S'_5E.#[`R+=0C'1?``````@\8$BQZ% +XMVW0T@SLM#X6*````@\,$BP.%P'3E@_AF#X3&````@_AH#X2S````QP0D@@`` +XM`.CRDO__B?;KU:'@(@D(,?:[X"()"(7`>$>)V(GZQP0D_____\=$)`3___]_ +XMZ';]__\]````@(/>_X/#$(L#A%]G03QT4(````((/$#%M> +XM7UWIEY+__X/$#%M>7UW#B=B)\^L*BT,$@\,$A=>+1?"%P'70QP0D````(.A-DO__Z\*_`0```.DH +XM____QT7P`0```.D<____D(UT)@!5B>56B<93@^P0H:`C"0B%P'0K,=OK#HL$ +XMG:0C"0B#PP&%P'09B40D!(DT).C;$?__A+`XE%\`^^$(L!*=!UVHM%\(D$).AI#P,`BTT(B0PD +XMB40D!.@V$?__AZ[F-M@````"-OP````!5B>6#[#B)7?2) +XMTXEU^(G&B7W\BW@(BT`$QP0DOB+5>R)1=B)5=R+5=R+1=B!\O___W_WT`G"#X2,```` +XMBPZ%R71WBT8,BU7PC' +XM1=0!````A?8/A6;____'1=P!````BS7@(@D(N^`B"0B%]G@3BU77UW#QP0D&```$.@IC___V478V`4@S@@(V04XS@@( +XMV=C[=V,=%R/_____'17UWIT8[__]E]Z@^W1>JT#&:)1>C9;>C? +XM?KKNHM5U(GP@\0\6UY?7>EH_?__VT8(V$W8V7WJ#[=%ZM@%(,X("+0, +XM9HE%Z-EMZ-]]R-EMZNN%BSZ%_P^$1?___[K^R0@(B=CH_O+__]E%V-@--,X( +XM"-E=V.DT____BP:%P`^%'O___[K7R0@(B=CHU_+__]E%V-@-*,X("-E=V.D- +XM____BP:%P`^$]_[__[KWR0@(B=CHL/+__]E%V-@-,,X("-E=V.GF_O__BP:% +XMP`^%Q````+K=R0@(B=CHB?+__]E%V-@-),X("-E=V.F__O__BP:%P`^%J?[_ +XM_]GNV478VNG?X,=%R`````#'1K>P;0,9HE%Z-EMZ-]]R-EMZNF&_O__ +XMBP:%P`^%1O[__[KOR0@(B=CH__'__^E!_O__NL;)"`B)V.CN\?__QT7(____ +XM_\=%S/___W_I3/[__XL&A<`/A`S^___'`VT```"ZYE7$/__A,EUX('[_P$``'_8B54(@\0$6UWI/A#__\<$)`````#H +XM,A#__P^WV(D<).@G$/__B5T,QT4(!575E.#[!R+10B) +XM1>RAT)<*"(E%\(L(AQT">L6@\($.P%U +XM#XM"!(/!!(7`=>^#.3UT%HM+!(/#!(7)=`2)S^O/@\0<6UY?7<.-0P3'`P`` +XM``")1"0$H="7"@B)!"3HAI,``*/0EPH(H=AU"0B)!"3H!)(``*'0EPH(B00D +XMZ,<'`P"CV'4)"(D[B3PDZ)B8`@"+1?")10B#Q!Q;7E]=Z8:8`@"-M@````!5 +XMB>575E.#[!RAT)<*"(E%X(L(A564X/L((M%"(M`!(7`=%:)!"3H=C@! +XM`(7`B<8/A+P```"A<&$)"(U=],<%<&$)"`$```")1?2)'"3'1"0$T#@&".AG +XMC/__B70D!,<$)!$7"0CHI^0"`(D<).BOB___@\0@6UY=P\<%=&$)"`$```#' +XM1"0$8'P%",<$)'1A"0CH*HS__XL=T)<*"(L#A)UU93@^Q,QT0D!,28"@B)1BQB%VW08QT0D!*PZ"0B)'"3H2@C__X7` +XM#X5[`@``QT70`0```(M7!#';N`$```"-=P2%T@^$LP```*&4=PH(A<`/A=@` +XM``")-"3HE3<``(G'A?]T$,=$)`3P(P8(B3PDZ`^+___V1=`!=`J#?<@@#X2_ +XM`0``BS>)^L=%S`````"+1=")5=31Z(A%N(7V=%2AE'<*"(7`=!GIU@$``(VT +XM)@`````-````0(D$).CCIP``BP:%P`^$3@$``(/&!(/X7'7A@'VX`'3;BQZ# +XMQ@2#^W9V<<<$)%P``$#H!:8``(G8Z\&+32)'"3H +XM&OL"`(DT).BR-@``B1PDB)^X7V#X2X_O__QT0D!,`["0B)-"3H$`;__XGZQT7,`````(7`#X4?_O__ +XMBW<$C5<$QT7,`0```.D-_O__C5WDB1PDZ,;Y`@")'"3H3HC__^DF_O__B=`- +XM````0(GVZ1#^___'1"0$O#H)"(D<).BW!?__QT70`@```(7`#X1M_?__QT0D +XM!-`Z"0B)'"3HF`7__\=%T`,```"%P`^$3OW__\=$)`3D.@D(B1PDZ'D%__^% +XMP`^5P`^VP(E%T.DN_?__C;8`````C;PG`````%4QP(GE@^P(BU4(Z,#\___) +XMZ9JA``"-=@"-O"<`````5;@@````B>6+50A=Z9_\___K#9"0D)"0D)"0D)"0 +XMD)!5B>575E.#["R-1>")!"3HK%,``*'@F0L(A"9 +XM"PAT+HG8BU`0BU@LA=)TY3L0=>$[5>!UW(/Z`G0QT!\=` +XM!`````#'!"0!````,?8Q_^C96```B<.-M"8`````@_L@#X2W````@_L)#X2N +XM````@_LC#X2X````@_O_B?8/A`D!``"#^PH/A`0"``")'"3HR4\``,=%\`$` +XM``")]L<$)`$```#HA%@``(/X7(G##X3^````@_LG#X3`````@_LB#X2W```` +XM@_O_C70F``^$N0```(/[*`^4P(G&BT7LAR)!"3HK/D"`(M% +XM\`GX=5J)\(3`=%2+3>R%R0^%OP$``(/[(+X!````#X5/____C;8`````QP0D +XM`0```.@$6```B7UW#,<`YWP^4 +XMP(/H`2''Z13____'!"0!````Z&]7``"#^`J)PP^%Z_[__[,@,?;I"?___Z$$ +XM80D(_R2%C,T(",=$)`0)R@@(,?;'!"04```0Z-F"__^#Q!R)\%M>7UW#H0AA +XM"0@Q]HD$).B0_@(`QT0D!!K*"`C'!"04```0HR!W"@CHIX+__X/$'(GP6UY? +XM7"__^#Q!R)\%M>7UW#QT0D!.(&"0@Q]L<$)!0``!#H1X+__X/$ +XM'(GP6UY?7<.+1>R%P`^$^O[__\<$)`H```#HMDT``(7V#X3H_O__BT7L@V@$ +XM`8D$).@_^`(`@\0) +XMQU:)UE.#[#R#_PJ)3@`````QT7L`````,=%\`````"C!&$)"(D-"&$) +XM"`^$Y@,``(U=Z,=$)`2PD0@(B1PDZ)2$___'1=``````H9B)'"3H?8/__X/$/%M>7UW#D(UT)@#_)(7,S0@(B=CH@0_/__ +XMA?8/B0O____I;O___X/_"W3D@_\$=-\QP.CR^___A?8/B>W^___I4/___Y"- +XM="8`@_\!#X1'`@``@_\!@]X`,<"#;=`!Z,;[__^%]@^)P?[__^DD____A?:- +XMM"8`````#X4*____@_\+C;0F``````^$!?___S'`Z)/[__^%]I`/B8W^___I +XM\/[__Y"-="8`@_\/#X77_O__A?:0C70F``^%RO[__S'`Z&/[__^-=@#IQO[_ +XM_X/_#P^%LO[__X7V#X6J_O__B=CH0_O__XM%[(7`#X7@`0``BU7HB10DZ*U] +XM__^)!"3H=8$``,=$)`0P*@@(B47,B00DZ**"__^+1B#?(+\.@^%,OW__X/H`8/_"HE%[,<$ +XM@@`````/A+````"#_P\/A1/]__^+1>C'1"0$H#L)"(D$).@<_O[_A<`/A?C\ +XM___I*?[__XUV`(M%T(7`#X6T_?__BQ7@F0L(A=(/A*;]__^+0BRCX)D+"(G0 +XMZ/CQ___IDOW__XL5Q",)".D/____BU7H@WR"_#H/A17^__^#Z`&)1>S'!((` +XM````Z0#^__^+`.DI____C478QT78`@```,=%W`````#'1>``````B00DZ&%- +XM``#I]?O__XM%R(E$)`2+1>B)!"3H=OW^_X7`#X52_/__Z8/]__^-M@````"- +XMO"<`````58GE@^P(BQ7@F0L(@WH0`G01C4(0B00DZ!--``#)Z1WX__^+0A0+ +XM0AAUYS'),=(QP.A:^___H>"9"PB#P!")!"3HNDL``*'@F0L(@T`4_X-0&/_) +XMZ>?W__^-M"8`````58GE@^P(H>"9"PB%P'07H2AW"@B%P'0(R<.-M@````#) +XMZ7K____'!"0O```0C78`Z.M\___KV(GVC;PG`````(L5*'<*"%6)Y872=`-= +XMPY!=,"9"PC'0!``````H91W"@B%P'4U +XM, +XM?O__H2AW"@B%P'4.B=DQTK@/````Z.?Y__^)70B#Q!!;7EWI&7[__XU3!+[X +XM;PD(ZYWK#9"0D)"0D)"0D)"0D)!5B>564X/L$(L=X)D+"(MU",<%Q",)"`H` +XM``"%VW44ZSV-0Q")!"3H-$L``(M;+(7;="N#>Q`"=>B+0Q0+0QAUX#'),=(Q +XMP.AT^?__C4,0B00DZ-E)``"+6RR%VW75B?$QTK@*````Z%3Y__^#Q!!;7EWI +XM^?7__XGVC;PG`````%6)Y5.#[!3'1"0$`````(M%"(M`!(D$).C3*@``QT0D +XM!#`J"`B)PXD$).CQ??__H2AW"@B%P'4(B1PDZ$#___^)70B#Q!1;7>DS??__ +XMC78`H2AW"@A5B>6%P'0$7<.)]ETQR3'2N`0```#IT?C__Y!5B>6#[!B+%>"9 +XM"PB+0BB%P'1CBT(@@W@$`(U(!'1!BP")2B")!"3H1/0"`(D$).AL?```QT0D +XM"`(```")1"0$H>"9"PB+0"B)!"3H<.T``*'@F0L(B00DZ!-*``#)PY#'1"0$ +XM`````,<$)`````#H+/W__\G#B10DZ/))``#)D,/K#9"0D)"0D)"0D)"0D)!5 +XMB>6#[`B+#>"9"PB%R706BQ4H=PH(A=)T!LG#C70F`,GI2O___\<$)"\``!"- +XM=@#H^WG__^O9B?:-O"<`````58GE@^P(H>"9"PB%P'0GH>"9"PB#P!")!"3H +XM44@``*$H=PH(AGZ_O__QP0D+P``$(UV`.BK>?__Z\B) +XM]HV\)P````!5B>564X/L$(L=X)D+"(7;=`Z+`SL%[)@*"`^$@@```#';BQ4H +XM=PH(,?:#10@$A=)U'J'`=@H(A7 +XM7<.%VW6VC44(QT0D!`$```")!"3H&,#__X7`#Y3`#[;PZZZ+4PB+#?28"@B+ +XM0P0S!?"8"@@QT0G!#X5B____BT,,.P7XF`H(#X53____BTLHA"9"PB) +XM4"RCX)D+"*'`=@H(QP7$(PD($@```(7`#X09____Z(K[___HA?W__Y"-="8` +XMZ0G____'!"0A```0C70F`.@K>/__Z>S^__^-M@````!5B>6#[`BAC'8*"(7` +XM=0FAE'<*"(7`=1FA-)D+"(7`=`+)P\<$)$8```#H\7?__\G#QP0D`````.BS +XMFP``H329"PB%P'7;Z]N0C;0F`````%6)Y8/L&*&,=@H(A575KX!````4X/L#(M="(M%#(U[!(E%\(VV`````(L'B00D +XMZ`;?``#'1"0$`@```(D<)`^O\.CS?```BP.%P'04QT0D!&A-"0B)!"3H6?;^ +XM_X7`=,FA*'<*"(7`=`6^`0```*&4=PH(AQP0DQ*P+".B`>/__@\0,6UY?7>G$>P`` +XMQP0DQ*P+".AH>/__@P7$K`L(`<=$)`2PD`@(QP0DQ*P+".CM>/__ZZ^#!<2L +XM"P@!QT0D!+"0"`C'!"3$K`L(Z-!X___I>?___XUT)@"-O"<`````58GE5KX! +XM````4X/L$*$H=PH(@T4(!(7`#X29````BUT(BP.%P`^$G@```,=$)`0@2`D( +XMB00DZ''U_O^%P'4QBT,$A7<.)]H7V=/.+50R+0A`IP\'[`HE<)`2)!"3HI7L``(M% +XM#(D$).@:_O__Z-5Z``"#Q!!;7EW#,53@^P4 +XMBT4(B00DZ&[Q`@#'1"0$\",&"(G#B00DZ+QW___HI_S__\=$)`3$F`H(QP0D +XM8#8)".BCW@``QP0D`````(7`#Y7`#[;`B40D!.@;,```QT0D"`````#'1"0$ +XM5'<*",<$)`\```#H6_C^_XE<)`3'!"0DR@@(Z*OX_O^)7"0$QP0D(,H(".B; +XM^/[_B1PDZ*=V___H,A3__\=%"`$```"#Q!1;7>EQ%/__D%6)Y8/L".@5_/__ +XMQT4,`````,=%"`````#)Z4$6__^058GE@^P(QT0D!)1V"@B+10B)!"3H=^`` +XM`,GI<1@!`)!5B>6#[`C'1"0$_____\<$),28"@CH9ML``,G#C70F`%6)Y593 +XM@^P0BT4(BW`$A?8/A-,```"+4`B-6`B%T@^$@@```,=$)`2@-PD(B30DZ(CS +XM_O^%P'58B30DZ'#O`@#'!"00```0HR!W"@CHCW/__XD<).@W?P``B30DB7>E7 +XMD0``QT4,_____\=%")1V"@B#Q!!;7EWI7MH``(/$$%M>7<.-M"8`````58GE +XM5U93@^PLBUT(BWL$@S\M=`S'!"1Z```0Z+!R__^-0PB)!"3H!2(``,=$)`3P +XM(P8(B47@B00DZ()U__^+=>")=?"+#H7)=%^-1?"#Q@3'1"0(`````(E$)`2) +XM/"3HO*[__\=$)`0P*@@(B<.)!"3H2G7__XE<)`3'!"22N0@(Z(K-`@")'"3H +XMDG3__XL>A=MTK<<$)!W<"`CH<,T"`(EU\(L.AE+Y0(`H91W +XM"@B%P'4DQT0D!`````#'!"0"````Z&KU_O_'!5!W"@@`````@\046UW#QT0D +XM!,"/"`C'!"0"````Z`KE`@#KVI"-M"8`````58GE@^P8B77XBW4(B5WTB7W\ +XMBWT,BT80B00DZ'"0__^+!Z,@=PH(BT80B00DZ,YQ``"-6/\[7PA\*SM?#'X, +XMQP0D#P``$.BEQ=_^''!"0.```0 +XMZ']P___KQXVV`````(V\)P````!5B>575E.#[`R+70B+0Q"+`(E%\(G"BP"I +XM````0`^%BP```(/X.G09B10DZ*!Q``"#^#H/A*(```"+5?"#.B5T>:$@)`D( +XMP>`$C;#@T@@(@?[@T@@(=E>_X-((".L-B?:%P'A$C7L0.?YV0XGP*?C!^`7! +XMX`2-'#B+1?"+"P^^$`^^`2G"B=!UUXD,).C?[0(`BU7PB10DB40D!.B@'0$` +XMA;R)WCG^=[TQVX/$#(G86UY?7<.+0P2H`70Q@^#^B4,$N\@C"0B) +XM%"3H;.L"`*/((PD(Z]6+1?"[Z",)"(D$).A5ZP(`H^@C"0CKOHM%\+O8(PD( +XMB00DZ#[K`@"CV",)".NGC;0F`````%6)Y5=6,?93@^P,BT4(B47PH="7"@B+ +XM&(7;#X24`@``BQ.%T@^$N0```#')@_H]#X2N````@\$!BQ2+A=(/A?X````Y +XMSGT"BV!^_\```!VVHD<))"-="8`Z&?M_O^I +XM```$`'31@SV`40D(`<<%0&0)"``````/E,(QP('[_P````^?P"'0HV"9"PCH +XM6?D!`*$\9`D(A<`/A$?^__^A0&0)"(7`#X4Z_O__Z$K)`0#I,/[__\=$)`2@ +XM3`D(B3PDZ-'L_O^%P'4-B1PDZ`EO`0#I#_[__\=$)`3@-`D(B3PDZ+#L_O^% +XMP`^%]_W__^B'S/__Z&+-__^)]NGF_?__B7T(@\0,6UY?7>G\;O__N`0```#I +XMG/W__XGV58GE5U93@^P,BT4(BW`$C7@$A?8/A)4"``"+!H7`="F)\^L*BT,$ +XM@\,$A)!"3H&F___XE\)`2)-"3H#N'_ +XM_\=$)`2(.PD(B30DZ.KK_O^%P`^$^````(GPZ,_9__^%P`^$%`$``,=$)`1% +XMR0@(NX````#'!"0`````Z+KQ_O_'1"0$1!="0CK'HM$GC2I```$`'4L@\,!@?O_````?R'WPP```$!U[8'[ +XM_P```';:B1PDB?;H9^O^_ZD```0`=-2#/8!1"0@!QP5`9`D(``````^4PC'` +XM@?O_````#Y_`(="C8)D+".A9]P$`BQT\9`D(A=MT+8L-0&0)"(7)=2/H4,7UWI,VW_ +XM_\=$)`3@-`D(B30DZ*_J_O^%P`^$O````,=$)`3`2PD(B30DZ)?J_O^%P'1V +XMQT0D!"A`"0B)-"3H@^K^_X7`#X7!````B3PDZ'=L``#'1"0(`@```,<$)-`O +XM"0B)1"0$Z'_=``")/"3H%VW__XD\).B_;/__B3PDZ#?F`@"+%8AW"@B%THG# +XM#X4\`0``QP5@90D(`````(/$#%M>7UWIR`$`B7T(@\0,6UY?7>E?;/__Z,K)___HI7UWI'N#__\=$)`0\0`D( +XMB30DZ*KI_O^%P'1%QT0D!!A*"0B)-"3HENG^_X7`#X7I````B3PDZ(IK``#' +XM1"0(`@```,<$)`!*"0B)1"0$Z)+<``")/"3H*FS__^F3_O__B7PD!(D\).AY +XM+O__B3PDB +XM7UWI*S?__[@(````OQZR"`C\B=Z)P?.F#X2M_O__N`4```"_,;(("(G>B<'S +XMI@^$E_[__\<$)(`Q"0C'!>29"P@!````QP6(=PH(`````.ANW```Z7+^___' +XM1"0$H#\)"(DT).B5Z/[_AY_[_A7UWI +XMT_0!`,=$)`0`3`D(B30DZ*_G_O^%P'31QT0D!"!,"0B)-"3HF^?^_X7`=+W' +XM1"0$Y$L)"(DT).B'Y_[_A!="0B+1)`T]L0!=1.#^U]T&L<$ +XM)!T``!#H*6?__XL>A=MT4_?#````0'4_BSW@70D(ZR.-=@"+1(!(7;="N#Q@3WPP```$!U%`^VPSW_````=M:)!"3HZN;^_^O0QP0D +XM'P``$.C09O__BT7PB<.+.(M`!(/#!(,X*`^$TP```,<$)!,``!#HKF;__X/# +XM!(D<).AS`0``A<`/A(````")1"0$B1PDZ!\5``"%P(G\````QT0D!#`` +XM``#'!"0!````Z$%T`@")<"2)PXEP((D$).CA-```B3PDZ`G@`@")0RBAX)D+ +XM",=#$`(```")0RR+/"9"PC'!<0C"0@)````A?]U/XLU*'<*"(7V +XM="F#Q`Q;7E]=PXD<).C#<0``B<:)!"3HJ0```.N"B10DZ`OF_O_IN_[__X/$ +XM#%M>7UWI+NO__^@IZ?__Z[J)'"2-="8`Z.MF``"+1(/\@S@I#X44____Z1O_ +XM__^A*'<*"(7`#X4W____QP0D,0``$.BP9?__Z2;___^0D)"0D)"0D)"0D%6) +XMY593@^P0BUT(ZPF-=@"+$(72=1"+`X/#!(7`=?&#Q!!;7EW#B<:)%"3_50R+ +XM5@2#Q@2%TG3>Z^Z-M@````!5B>6+30B+$8/!!(72=!*+`H7`=/$E____/XD" +XM@\($Z^Y=PXVV`````(V\)P````!5B>575E.#[`BAV)<*",=%\`````")1>R+ +XM50B+`H7`#X3I````@T4(!(L0@_I^#X1^````@_H]='F#^GL/A*````"%TG32 +XMBU@$C4@$ZS:)]H/Z>W0YA=)X._?"````0)!U,H/Z?W\M#[;"]H0`X"`)""!T +XM((--\`&#P02%VW29B=J+7@2#^F")SHUY_'7"@TWP`NOD@WWL`W7>A=N-="8` +XM#X1R____@_HN=`V#P02)]NO-@TWP`NN*@_LND(UT)@!UZ8M!!(7`=`6#^"]U +XMW8M5"#EZ_'0&@WGX+W7/@TWP`NO)BU@$A=L/A"O___^#^WT/A5/___^+2`B% +XMR0^%2/___XM5"(L"A<`/A1?___^+1?"#Q`A;7E]=PXVT)@````!5B>575E.# +XM[%R%THE%N(E5M(E-L(L`B47`#X2[`P``BQ*)5;R+1<"+`(7`B47$#X2``0`` +XMBWW`BU7$@SI[=12+0@2%P`^$6@$``(/X?0^$%P(``(M-Q,=$)`1[````B0PD +XMZ-;G_O^%P`^$-@$``(M%Q,=%Z`````#'1>P`````QT7P`````,=%W`````#' +XM1>``````QT7D`````,=%T`````"#.'MT$X/`!(,X>W7XB<,K7<3!^P*)7="- +XM<`2+0`2%P`^$%`$``(GSQT7,`````.L@@_A[#X3O````@_A]D`^$!P$``(/# +XM!(L#A<`/A.D```"#^%MUVX/#!(L#@_A=#X3M`@``A7^__\IPHG0P?@"@_AD`"B4VP +XMB40D!(D<).AQ<`(`BTVXB47`B0&+5<")^"G8@^#\C3P0BT6\*=B#X/P!T(E% +XMO.D!____BP:)!X/O!(DT).@;;P(`Z3K___^+0@B%P`^$+____^G9_?__BTW0 +XMC57HBT7$B10DB4PD"(E$)`3H/=D"`(U-W#G>B4VL#X>\````C47R)\"G(P?@"B40D".BWV`(`BTVHC47HB00DB4PD!.@EV0(`C57HB10D +XMZ`K7`@"+1>B)!"3H?]H"`(U-W(D,)(E$)`3H8-@"`(U.!(G..?,/@V3___^+ +XM7:R)'"3H&-@"`(G&BT7HB00DZ`MN`@"+1>"%P(E%R`^)I?W___?8Z8[]__^- +XMM@````"#1"L"PB+=?R)`Z'DK`L(B4,$H>BL"PB)0PB+ +XM7?B)[%W#C70F`(V\)P````!5B>575HG.4X'LK*```(F%<%___XM%"(F5;%__ +XM_X7`=1#'A7Q?__\`````]D$#0'0*QX5\7___````0(U%Y(U=[(E%W,9%S`'' +XM1=``0```QT74`````,=%V`````#'1>``````QT7D0#P)",=%Z`````#HR8$` +XM`(U%S(D$),=$)`1@/P8(Z"9B__^)'"3H3JH``(D<)(U=\,=$)`1`'@4(Z`MB +XM___'1"0$0!X%"(D<).C[8?__C57,QT0D!/____^)%"3H.)P``(7`#X4O`P`` +XMBT7LB00DZ$5D``"+1?#'1"0$`0```(D$).B":```H01V"@C'1"0$`@```(D$ +XM).AM:```Z!CG_O_HPV@``(DUD'8*"(L&A!.L.@_@-=#&+`X/#!(7` +XM=#$E____/XE#_,=$)`3$F`H(QP0DX#$)".AHR```A"0B%P'02B00DZ/]J`@#'!8!>"0@` +XM````QP0D>'8*".@96```QT0D!)#I!0C'!"1X=@H(Z%5@__^A@%X)"(7`=`S' +XM!"0```!`Z%!=___'!"1X=@H(Z/1X``"A@'8*",=$)`@`````QT0D!'AV"@B) +XM!"3H9W4``,=$)`1`*P8(B<.)!"3H!6#__Z&`7@D(A___'!"0`F@L(Z(#=_O^AP)@*",<%<'8* +XM"`````"%P`^$S?[__XN%@%___\<%_)@*"`````")!"3H55[__XN5O%___XN% +XMN%___XD5+)H+"(N5M%___Z,HF@L(BX6P7___B14DF@L(BY6L7___HR":"PB+ +XMA:A?__^)%1R:"PB+E:1?__^C&)H+"(N%H%___XD5%)H+"(N5G%___Z,0F@L( +XMBX687___B14,F@L(BY647___HPB:"PB+A9!?__^)%02:"PBC`)H+".BF6___ +XMZ2'^__^)'"2-G%A%___P````")G61?__^)E6A?__^%]@^$G````(N->%___X7)=4"+%X'B +XM____/XF5=%___P^%K0$``(U%[(D$).BA7?__Z`RB``"-17UW#C;8`````BX5T7___AB5PD!"G8B40D"(M%[(D$).BQ70``QX6,7___```` +XM`(7`#XY9`0``C3PP.;UD7___#X-V`0``C9W,W___B;W`7___QX6(7___```` +XM`.L-`<.#A8A?__\!.?MS0(NUP%___XN5B%___XE<)`0IWHV$E%B%___P````#I_O[__XUV`%6)Y5=64X/L+(MU"(U%W(D$),=%Z`````#' +XM1>P`````QT7P`````,=%W`````#'1>``````QT7D`````,=$)`3PD0@(Z+=; +XM__^-1>B)!"3'1"0$L)$(".BD6___BP:%P`^%F````(GS,<")1"0(C47HB70D +XM!(D$).A3T`(`BPN%R0^$X@```(M#!(U[!(7`#X67````B?XQTH7`=1O'1"0$ +XM8````,<$)#,```#H7UC__XGR*?K!^@*)5"0$@\8$B3PDZ%G2`@#'1"0$,"H( +XM"(G#B00DZ"=;__^+10R)V8U5Z(D$)(U%W.AD^/__B1PDZ&Q:__^+!H7`#X1H +XM____@_A@B?,/A%W___^-M"8`````@\,$BP.%P'4,B=@I\,'X`NE%____@_A@ +XM=>;K[8/X8(G^#X1>____@_A<=!^#Q@2+!H7`=0R)\BGZP?H"Z4C___^#^&!T +XM[X/X7'7A@\8$BQ:%TG78Z33___^+1>R%P'0+C57HC47- +XM153@^P4 +XMBTT(BT$$@_@M='FI````0'5J@_A_=V7V!(6]40D(!'1;BU$(@^@PC5D(]\(` +XM``!`="7K*)"-="8`]@25O5$)"`1T&8/#!(T$@(U$0M"+$_?"````0'4%@_I_ +XM=MV%TG5YB00DZ-$4__\QR87`=`Z)7"0$B00DZ)_.`@")P8/$%(G(6UW#BU$( +XMC5D(A=)U6,=$)`3$F`H(QP0D=#,)".BGOP``A<")PG1)BP"%P'1#BPUDF0L( +XMBP&+0`R%P'4TBT$$BT@,A*)/"3HLF$"`,<#`````(M-X(MQ +XM!(/!!(E-X(7V=9*+1,"B5PD!(D4)(E-U.@E8@(`BU70C9P#`2#P`2)1=R%_W0ZBP>#^#UUX(D\).@[_?__A<")PP^$:P$``#G'=-.)/"3H +XME6`"`(M-W(D9BT7OHQT0D!,28"@C'!"0`/`D(Z.B[``"%P'0*B30DZ#Q4 +XM___KGXL&A%]G4&]D7P`74ZB1PDZ*[K__^) +XMV(MU^(M=](M]_(GL7<.)V(GRZ`;\__^)PXG'Z]")70B+=?B+7?2+??R)[%WI +XMC%P``(D<),=$)`3P(P8(Z+Q3__^)V.AE^?__.<>)PW0*B3PDZ`=3___KIXD$ +XM).A-4___Z^R-="8`C;PG`````%6)Y5.#[!2+70B)'"3H7NO__X7`=!J)'"2) +XM1"0$Z`[___^%P(G#="*)V(/$%%M=PXD<).@87```B<.)!"3H_NK__XG8@\04 +XM6UW#QP0D,0``$.A*4/__Z]"0C;0F`````%6)Y5=64X/L+,=$)`3$F`H(C7WL +XMQP0DU#L)".@0N@``QT7P`````(G#BT4(B47LB3PDZ-GJ__^%P(GS```` +XMA=L/E<#WQ@(````/MMAU+H7;=0F#Y@$/A>P```"+10B)!"3HA\D"`(D$).A_ +XM40``B44(BT4(@\0L6UY?7<.)^(G:Z,CZ__^%VXG'#X2#````B7W8BU78BP*% +XMP`^$I0$``(M5V(MR!(7V#X2S`0``@WT,`0^$:@$``(-]#`(/A+P```"+30R% +XMR76IBT4(B00DZ#K+`@"+5=B)%"2C('<*".@:5@``QP0D)P``$.A.3___ZX"+ +XM50B)%"3H\<@"`(D$).CI4```B44(BT4(@\0L6UY?7<.#Y@$/A'3___^)!"3' +XM1"0$\",&".@"4O__B?CHJ_?__SG'B478#X1#`0``B3PDZ$A1___K"HGXZ(_W +XM__^)1=B+7=B%VP^%-O___XM5"(D4).BFR@(`QP0D,0``$*,@=PH(Z,5.___I +XM%?___XM5V(E5W(D$).@^S_[_BUW8@\,$C7@!ZP.+=>"+0P2#PP2)1>")-"3H +XM'\_^_XM5X(72C7P'`77AC02]`````(D$).BY7`(`B44(BT78BTT(BQ"%T@^$ +XMI````(L"A+___\_B57DBQ>#QP2!XO___S^#^C\/A/$```!_'(72=6.+11")&(-]Y`$9 +XMP/?0@\`"@\0L6UY?7<.#^EL/A-H```"+=12%]G5B@?K_````#X?"`0``H>!= +XM"0B+G)`T!```@7WD_P````^'F0$``*'@70D(BU7DBX20-`0``#G##Y7`ZRV# +XM^BIUN8L',?:%P'5$B1PDZ'[!`@"+51")`H/$++@"````6UY?7<,[5>0/E<"$ +XMP'5>@T7P!(M=\.DX____BT40BS#W`____S\/A!X!``"#PP2+112)1"0,BU40 +XMB7PD!(D<)(E4)`CH^/[__X/X`73-@_@"#X3F````A)UHU?!('F +XM____/\=%Z`````")WW0M@_Y==#R+1>B%P'53@SLM=%6#PP0QP#EUY`^4P(E% +XMZ(L7B=:)WX'F____/W73QT0D!%T```#'!"0R```0Z/Y+__^+1>@+1>1T@HM5 +XM[#E5Z`^%&/___S'`Z8W^__^-=@"+%X/#!.N[BT<$@\,$@_A==*,E____/\=$ +XM)`@`````B40D!(M%Y(D$).C"UP``A +XM7UW#A?8/A!O___^+51"X`0```(DRZ2K^__^+1>2)!"3HD2)-"2)5"0$Z%K7``"%P'^8QT7H`0`` +XM`.N/C;8`````C;PG`````%6)Y5=64X/L+(MU#(M%",=%W`$```")1?"#/EX/ +XMA!4!``#'!"0$````Z$)9`@#'!"20`0``B(M5"(D4).@]OP(`BQ>)QHL"QT7@`````(7`=#N)TXE$)`2+10B-5?#'1"0, +XM`0```(E4)`B)!"3HW/S__X7`=`V+1?"#3>`!.?!S`HG&BT,$@\,$A`/E,"#Q"Q;#[;`7E]=PXL7BP+'1>``````A57B==64X/L#(E%\(MP"(M:"(L#B40D!(L& +XMB00DZ/C(_O^%P'4/BW8(.W7PBUL(=`XY^W7=@\0,,Q=PY"+'0QA"0B%VW0TBT(8A/&!@"+1?")!"3HA54" +XM`.E0____58GE4XG#@^P$B00DZ(\4``"+0QB%P'0(B00DZ&!5`@")'"3H6%4" +XM`(/$!%M=PXGV58GE5U:)QE.)TX/L+/;"`71FH7!A"0B-??#'!7!A"0@!```` +XMB47PQT0D!-`X!@B)/"3HF4K__X/C0`^%WP```*$,80D(A<`/A,4```"+1AB% +XMP`^$N@```(E$)`3'!"01%PD(Z+BB`@")/"3HP$G__X/$+%M>7UW#QP0D2LX( +XM".A!T;XG/@^<(ZR"+!H/H`87_B09T/X7`>`J+5=R)V.AW_O__BUL< +XMA=MT2*&4=PH(A"%P'X*BU77UW#58GE5S'_ +XM5E.#[!R+=0C'1"0$Q)@*",<$)*`S"0CH+K```(D$).@VK@``A<`/A)\```"# +XMQ@2+'H7;=#"#.RUU*X/#!(L#A7UW#QT0D!,28"@C'!"2@,PD(Z.^N``")!"3H]ZP``(E%\.E1 +XM____ZPV0D)"0D)"0D)"0D)"058GE@^PHB5WTBUT(B77XBT4,B7W\A=L/E,*) +XMUG4$AP/A%@!``")\(3` +XM=#C'1"0$Q)@*",<$).`S"0CHQ=P\=$)`0`````B1PDZ*[S__^)Q\=$)`0P*@@(B3PDZ,Q& +XM__^+%>AV"@C'!>AV"@@`````B57PQT0D!,28"@C'!"1@-@D(Z*6M``"%P'0Q +XMBP"%P'0KBT`$AR+'E?1?__QT0D!,28"@C'!"20+PD(Z$NM +XM``#'1"0$A#0)"(D$).@+O`(`BP/A8;^___'1>Q`+PD(Z7K^__^-M@````!5B>575E.#[!S'1"0$ +XMQ)@*",<$),`S"0CHXZP``#WX;PD(B<8/A.8!``#'1"0$@$,)"+\`=PH(B00D +XMZ$W"_O^%P'0_QT0D!'!#"0B[`'<*"(DT).@TPO[_A<`/A9@!``"+6QR%VW1J +XMBT4,B=KH__C__X7`=.N#+029"@@!B=_K7XG?BU\`2+0P2)1P2+0P2)>`C'1Q@`````BT44QT7L`'<*"(7`=2*+-1QW"@B) +XM=QR+7>R)>QR#Q!R)^%M>7UW#C;8`````B77LBT7LBW`PYT`^%P0```(M%\(GZZ,_W__^% +XMP`^%O0```(M5\(M*'(7)=S'1?``````BW(R+@L^/__BWWPZ=3^__^+%1QW"@B% +XMTG2*BT4,Z.+V__^%P`^$>O___XL=''<*"(,M!)D*"`&%VXG?#X4R_O__Z1_^ +XM__^-M"8`````C;PG`````%6)Y593@^P0BUT(A=MT#HM#"(L`@S@*#X33```` +XMQT0D!,28"@C'!"2@,PD(Z`^J``"+$(72#X3'````]\(```!`#X6[````@_I_ +XM#X>R````,?:)P?8$E;U1"0@$=2?IGP```/?"````0`^%DP```(/Z?P^'B@`` +XM`(/!!/8$E;U1"0@$='V-!+:-=$+0BU$$A=)UT(7;="BA!)D*"(M5#,=$)`@! +XM````B5PD!(/``:,$F0H(B50D#(D$).B!_/__NP!W"@B+4QR%TG0EH029"@@K +XM0A`Y\'P@BT("0C70F`(/$$%M>7<.%]G3!P``BQTLFPL(A=L/ +XMA-$'``"+#32;"PB%R0^$!`@``(L5/)L+"(72#X0W"```H62;"PB%P'0&@\04 +XM6UW#H8"8"@C'1"0,8M$(",=$)`A!````QT0D!`(```")!"3'!6";"PA>T0@( +XMZ'&>__^)!"3HV4<``*-DFPL(@\046UW#H8"8"@C'!6B:"PCXS@@(QT0D#/S. +XM"`C'1"0(`@```,=$)`0"````B00DZ"^>__^)!"3HET<``*-LF@L(Z=S]__^A +XM@)@*",<%<)H+"`//"`C'1"0,!\\(",=$)`@#````QT0D!`(```")!"3H[IW_ +XM_XD$).A61P``HW2:"PCIJ?W__Z&`F`H(QP5XF@L($<\(",=$)`P6SP@(QT0D +XM"`0```#'1"0$`@```(D$).BMG?__B00DZ!5'``"C?)H+".EV_?__H8"8"@C' +XM!8":"PB`SP@(QT0D#!O/"`C'1"0(!0```,=$)`0"````B00DZ&R=__^)!"3H +XMU$8``*.$F@L(Z4/]__^A@)@*",<%B)H+""_/"`C'1"0,-,\(",=$)`@&```` +XMQT0D!`(```")!"3H*YW__XD$).B31@``HXR:"PCI#_W__Z&`F`H(QP60F@L( +XM0\\(",=$)`Q(SP@(QT0D"`<```#'1"0$`@```(D$).CJG/__B00DZ%)&``"% +XMP*.4F@L(#X78_/__H8"8"@C'!9":"PA.SP@(QT0D#%+/"`C'1"0("````,=$ +XM)`0"````B00DZ*:<__^)!"3H#D8``*.4F@L(Z9?\__^-="8`H8"8"@C'!9B: +XM"PA;SP@(QT0D#%_/"`C'1"0("P```,=$)`0"````B00DZ&&<__^)!"3HR44` +XM`*.B:"PAJT`@(QT0D#&_0"`C' +XM1"0(+@```,=$)`0"````B00DZ)*8__^)!"3H^D$``*/LF@L(Z5GY__^A@)@* +XM",<%\)H+"(+0"`C'1"0,A]`(",=$)`@P````QT0D!`(```")!"3H49C__XD$ +XM).BY00``H_2:"PCI)?G__Z&`F`H(QP7XF@L(D=`(",=$)`R6T`@(QT0D"#(` +XM``#'1"0$`@```(D$).@0F/__B00DZ'A!``"C_)H+".GQ^/__H8"8"@C'!0B; +XM"PB@T`@(QT0D#*70"`C'1"0(,P```,=$)`0"````B00DZ,^7__^)!"3H-T$` +XM`*,,FPL(Z;WX__^A@)@*",<%$)L+"+O0"`C'1"0,P-`(",=$)`@U````QT0D +XM!`(```")!"3HCI?__XD$).CV0```HQ2;"PCIB?C__Z&`F`H(QP5`FPL(U]`( +XM",=$)`S=T`@(QT0D"#@```#'1"0$`@```(D$).A-E___B00DZ+5```"C1)L+ +XM".E5^/__H8"8"@C'!2";"PCQT`@(QT0D#/;0"`C'1"0(.@```,=$)`0"```` +XMB00DZ`R7__^)!"3H=$```*,DFPL(Z2'X__^A@)@*",<%*)L+"`W1"`C'1"0, +XM$M$(",=$)`@[````QT0D!`(```")!"3HRY;__XD$).@S0```HRR;"PCI[O?_ +XM_Z&`F`H(QP4PFPL(*M$(",=$)`PQT0@(QT0D"#P```#'1"0$`@```(D$).B* +XMEO__B00DZ/(_``"C-)L+".F[]___H8"8"@C'!3B;"PA$T0@(QT0D#$G1"`C' +XM1"0(/0```,=$)`0"````B00DZ$F6__^)!"3HL3\``*,\FPL(Z8CW__^0D)"0 +XMD)"0587`B>5T!8,X"G0%HT!A"0A=PXVV`````(V\)P````!5B>6+10A=HQAA +XM"0C#C78`58GE@^PHBPV0=@H(B5WTB77XB7W\AR9"P@`````=`V+7?2+ +XM=?B+??R)[%W#BQ6\F`H(A=)UZ:'`=@H(A7<.0C70F`%6)Y5WI +XMM____XVT)@````!5B>564X/L$*&T=@H(QT0D#`(```#'1"0$`````,=$)`@` +XM````B00DZ`^V_O^AL'<*"(L5M'<*",<%T"0)"`(```#'!3"9"P@`````HZ!W +XM"@B)%:1W"@C'!;28"@@`````QP5(=PH(`````,<%2)H+"`````#H9JW__XLU +XM[)D+"(7V=0J+'>"9"PB%VW0'@\006UY=PXL5H'<*"(/J`8G0P?@?P>@3C300 +XMP?X-A?9^WC';H;QW"@B+!)B#PP&)!"3HRS\"`#GS=>F+%;QW"@B-!+*)%"2) +XM1"0$Z'(S``")\,'@#8G"P?H?*06@=PH(&16D=PH(*06P=PH(&16T=PH(*36X +XM=PH(@\006UY=PXUV`%6)Y5>)QU93@^P,H;AW"@@YQWQM@\`"QT0D!`0```") +XM!"3HN3\"`(G&H;QW"@B%P'09B40D!(DT).@",P``H;QW"@B)!"3H-3\"`(L= +XMN'<*"(DUO'<*",=$)`0$````QP0D`"```.AU/P(`C1R>B0.AN'<*"(/``3G' +XMH[AW"@A]DX/$#%M>7UW#C;0F`````%6)Y8/L*(E=](L=T"0)"(E]_(M]"(EU +XM^(/[`HD?='.#^P-T7(/[`70WH8"8"@C'1"0,@-<(",=$)`@'````QT0D!!`` +XM``")!"3HTI+__XE<)`2)!"3H9HP"`.@MLO[_D*$PF0L(B4<,H;28"@B)1P2+ +XM7?2+=?B+??R)[%W#C78`H4AW"@B)1PRA2)H+"(E'!.O>H>R9"PB%P'4:H:!W +XM"@B+%:1W"@B)1P2)5PC'1PP`````Z[N+%:1W"@B+':QW"@BAH'<*"(L-J'<* +XM"#G:?-9^2SL5M'<*"'_,C;8`````?`@[!;!W"@AWO(G&*N)3P2)7PCKCSG(6#[$B+50B)7?2)=?B)??R+&H/[`HD=T"0)"'1S@_L# +XM=%R#^P%T-Z&`F`H(QT0D#(#7"`C'1"0(!P```,=$)`00````B00DZ**1__^) +XM7"0$B00DZ#:+`@#H_;#^_Y"+0@RC,)D+"(M"!*.TF`H(BUWTBW7XBWW\B>Q= +XMPXUV`(M"#*-(=PH(BT($HTB:"PCKWJ'LF0L(BW($BWH(A<")-:!W"@B)/:1W +XM"@ATPXL5K'<*"*&H=PH(.=>)1>B)5>P/C,H````/CKD```"+#;1W"@B+%;!W +XM"@@Y3>R)3=R)5=@/CZD```!\"3E5Z`^'G@```(M-V"M-Z(E-X'1DBU7L,57 +XM5E.![$P@``"%R8F%S-___XF5R-___XF-Q-___\>%U-___P`````/A#(!``"! +XM^0$@```/AU<"``#'A=3?__\`````,=O'A=C?__\`````.9W$W___N@$```!V +XM"(N5Q-___RG:C00:/0`@```/AZ@```"-A?/?__\!V(E$)`2+A#?__\/A:T```#'A=S?__\`````BY7@W___.97- +XM-)"!Q\!W"@B+G>#?__^-A?/?__\KG=S?__\#A=S?__^)-"2)7"0(B40D!.BW +XMJ0(`@_C_=%2%P(G"#XZ.````BTT(A57 +XM5E.#[%R+/1AA"0B%_W1"QP4880D(`````(/$7(GX6UY?7<.A,)D+"(7`#X2D +XM````H3"9"PC'!4R:"P@!````BP"%P*.TF`H(='N#!3"9"P@$H;28"@C'!=`D +XM"0@"````A@$``.E;!0``D(UT)@"+%:1W"@B+/:QW"@BA +XMH'<*"(LUJ'<*"(E5M#GZB46P?`X/CZL#```Y\`^#HP,``*.P=PH(HZAW"@B) +XM1"0$H;1V"@B)%;1W"@B)%:QW"@C'1"0,`````(E4)`B)!"3H&JS^_Z&@=PH( +XMBQ6D=PH(BPVP=PH(BQVT=PH(BS6H=PH(BSVL=PH(B46PB56TBU6TBT6P,=HQ +XMR`G"#X1U`P``BQ6\=PH(BT6PBQ(I\(L\@H-%L`0`BT6PBU6THZ!W"@B) +XM%:1W"@B#__\/A>;^__^+10B%P`^%LP0``*&T=@H(C57$B50D!(D$).@^I_[_ +XMA<`/A;#^___V1=$!#X2F_O__BQ5P8PD(A=)T%:$<80D(@\`!.<*C'&$)"`^. +XMA_[__X,]U)<*"/\/A/K]___'!"0/````Z.2J_O^#^/^)PP^$X_W__Z'4EPH( +XM.<,/A-;]__^)1"0$QP0D#P```.@@3`<*)UH'F_Q\``,'Z#2G&B56HB=#H(?3__XM]O+@`(``` +XM*?`YQWX"B<>+1;R-%+4`````BTVXC1R]`````(MUJ,'@`BG!H;QW"@@#%+") +XM7"0(B4PD!(D4).B)J_[_B?HI?;R+1;S!^A\!/;!W"@@1%;1W"@B%P`^/=O__ +XM_^G<_O__Z+2W`0")1:R)1;SI2?___XL0A=(/A*OZ__^#P`1FOR``B16TF`H( +XMHS"9"PCI%?K__Z%(=PH(Z27[__^+';1W"@B+#;!W"@@YV@^,I?S__P^/0_S_ +XM_SG(#X:7_/__Z3;\___'!?R8"@@!````Z#@E__^A2'<*".GY^O__B^O__QP0D`0```.AS2```Z8WZ__^+10B%P`^%P``` +XM`(UV`.AKQO[_H9!V"@CI#_O__Z&\F`H(A<`/A8\```")^(E$)`3'!"1LG`L( +XMZ#*:`@#IVOC__X/`!&:_(`")%4B:"PBC2'<*".G#^/__H8"8"@B+'0QV"@C' +XM1"0,K-<(",=$)`@#````QT0D!!````")!"3HNX7__XE<)`2)!"3H3W\"`.E+ +XM^O__BSB#P`2CD'8*"(7_#X5U^/__H7P@"0AFOPH`HY!V"@CI8OC__X/H`:.\ +XMF`H(N`H```#I8?___[______Z4;X__^)]HV\)P````!5B>564X/L$(MU#(M= +XM"(U&FX/X$W8*,<"#Q!!;7EW#D/\DA6C8"`B)'"3H(9@"`(G"C4#\.<,/ARD! +XM``"+4OR#^B]U(ND<`0``C;0F`````(/H!#G##X<*`0``BQ"#^B\/A/\```"# +XM^BYUY8/^98GV#X3D````*=C!^`*)10R)70B#Q!!;7EWI1)T"`(D<).C\G@(` +XMQT0D!"\```")!"3H_",``(7`#X65````@_YT#X5C____B5T(@\006UY=Z:V< +XM`@#'1"0$`0```(D<).@=<0(`A7<.)'"3HBIP"`(L0A=(/A"C_ +XM__^)P>L;@_H)=!N!R@```$")$8M1!(/!!(72#X0)____@_H@=>"#_G%UZ(VT +XM)@````#KU\=$)`0`````B1PDZ+YP`@"%P`^$>____X/$$%M>753@^P4BQ68=PH(H7R<"PB+70C'!"0@80D(QP4D80D( +XM`````"G0P>("`Q5XG`L(B40D"(E4)`3HPID"`(E<)`3'!"1XG`L(QP5\G`L( +XM`````.@HF@(`QP0D>)P+".@,F`(`H21A"0C'!"1XG`L(B40D"*$@80D(B40D +XM!.A^F0(`B1PDZ"8O`@#'!9AW"@@`````@\046UW#C;8`````58GE5U93@^P, +XMBT4,BW4(BW@(QP0D#````.C"+P(`B<.)<`3'``````"+10B)0PB)6`2+!XE> +XM"(G>B00DZ`^;`@"+?PB)`X,X"G7'@\0,6UY?7<.-M@````"-O"<`````58GE +XM5E.#[!"+=0B+7@B+`XE$)`3'!"22N0@(Z&!\`@"+6P@Y\W07BP.#.`ITXL<$ +XM)"````#H9C\``(L#Z]*#Q!!;7EW#C70F`(V\)P````!5B>575E.#[!R+'1QW +XM"@B)1>R)5>B%VW0^BU,,BWL(A=)X+8L7BPJ#^0IT)(M%Z,=%\`````"%P'5? +XMBT7LZP>0@\`$@\($BPB%R70H.PIT\(M;'(7;=<*+1>PQVXD$).ASK!H/`!(/"!(L(AC'1>P`````P?@"QT7P +XM`````(E$)`B+1>")%"2)1"0$Z"27`@"+'6!A"0B+`X7`="2#^"9T;X/X7(US +XM!'12B40D!(GSC47HB00DZ`J5`@"+`X7`==R+1>R+50B)`J%,80D(C02'B40D +XM!(U%Z(D$).A5EP(`BU77UW#58G"B>6# +XMX@)7@^`!5E.#[#R)5=")1__^A.&$)"(7`=%*+4`BA-&$)"(D5 +XM.&$)"(/H`87`HS1A"0AX*8L"Z#_I__^+#3!A"0B%R0^$1O___\<%,&$)"``` +XM``"#Q#R)R%M>7UW#QP4X80D(`````.D5____QP0D`````.CR\?__@_@DB<%T +XM&SL-C)@*"'7,BUW0A=MTQ3'`Z`4+``#IY_[__XM=S(7;=-ZA,&$)",=%Z``` +XM``#'1>P`````QT7P`````(7`B474HT1A"0@/A.`"``#'!3!A"0@`````BU74 +XMQP0DQM<("(E4)`3H`AX``(7`#X24````BT74QP4P80D()```0*,\80D(Z7K^ +XM__^A>)P+"(L,D(U"`:.8=PH(AC__X/$/+D@````6XG(7E]=PXU5Z(D4),=$ +XM)`2PD0@(Z&,?__^-1>C'1"0$)````(D$).@PD@(`BUW4@_M[#X2U`@``@_LC +XM#X1L`@``@_L_#X1C`@``,?:#^R4/A%@"``"-5>B)7"0$B10DZ/B1`@"-0_:# +XM^#(/AM$!``#WPP```$!U/H/[?Y!W#O8$G;U1"0@$#X5\`0``#[;3@?K_```` +XM#X=V!```H>!="0B+1)`T]L0!#X6G````@_M?#X2>````A?8/A',"``"#;>P! +XMB1T\80D(C47HB00DZ%D>__^-5>B)%"3H_AW__XU%Z(D$).B3D0(`B00DZ%OY +XM___I#?W__\<%,&$)"`````#WPP```$`/A38"```/MM.!^O\````/A\4!``"A +XMX%T)"(M$D#3VQ`%U'(/[7W07@_M_#X<+`@``]@2=O5$)"`0/A/T!``"-5>B) +XM7"0$B10DZ`B1`@"+'3!A"0B%VXD=1&$)"'62N`(```#H?OS__X7`B<-UC(-] +XMU'N)'3QA"0@/A43___^A,&$)"(7`HT1A"0@/A`D%``#'!3!A"0@`````@_A] +XM#X3>!```HSQA"0C'1"0$?0```,<$)#(```#H6AK__^D!____D(UT)@#'!3!A +XM"0@`````]\,```!`#X5@`0``@_M_#X=7`0``]@2=O5$)"`0/A$D!``"-1>B) +XM7"0$B00DZ%20`@"+'3!A"0B%VXD=1&$)"'6TN`(```#HROO__X7`B<-UKNE' +XM____N`(```#HM?O__XE%U(GVZ1;]____)(6XV`@(A?:)]@^$=O[__\<$)%`` +XM``"-=@#HNQG__^EB_O__A?:-="8`#X16_O__QP0D3@```(UV`.B;&?__Z4+^ +XM__^#;>P!A?;'!3QA"0@*````#X4L_O__QP0D3P```.AT&?__Z1O^__^-1>B) +XM7"0$B00DZ*"/`@"+'3!A"0B%VXD=1&$)"'17QP4P80D(`````+X!````Z77] +XM__^)%"3HL)G^_^DW_O__C57HQT0D!'L```")%"3H7(\"`(L=,&$)"(7;B1U$ +XM80D(#X3H`0``QP4P80D(`````.D5_?__N`(```#HO_K__XG#ZZ7'!"12```` +XMZ-\8___IAOW__X/[6P^$W@(``(/[.@^%(/[__\=%W`````#'1>``````C47H +XMB5PD!(D$).CKC@(`BQTP80D(A=N)'41A"0@/A-@!``#'!3!A"0@`````@_MG +XM#Y3`#X2&`0``@_MA#X0J`@``BU7@A=)U"(3`#X6[`0``@_MA#X3Y`0``C57H +XMB5PD!(D4).B1C@(`@_MS#X7>````BSTP80D(A?^)/41A"0@/A.\!``"-1>C' +XM!3!A"0@`````B7PD!(D$).A;C@(`]\<```!`=3^)^`^VT('Z_P````^'\0$` +XM`*'@70D(BT20-/;$`0^%S@$``(/_7P^$Q0$``(/_?W<.]@2]O5$)"`0/A;(! +XM``")?"0$QP0D_[D(".@4&0``A<`/A9H!``#'1=@"````ZR['!3!A"0@````` +XM@_[_#X1U`@``C57HB70D!(D4).C1C0(`,<`Y_@^4P"E%V'0;BS4P80D(A?:) +XM-41A"0AUPC'`Z#[Y__^)QNO!B5PD!,<$),K7"`CHJA@``(7`#X3G`0``BQTP +XM80D(A=N)'41A"0@/A,8```#'!3!A"0@`````@_LZ#X1Q_O__Z7[\__^-M@`` +XM``"X`@```.CF^/__B<.-="8`Z2?[__^)%"3H?Y?^_XUV`.F#^___@T7@`8U5 +XMZ(E<)`2)%"3H*(T"`(L=,&$)"(7;B1U$80D(#X30````QP4P80D(`````(/[ +XM9P^4P.E'_O__N`(```#HA?C__XG#Z2'^__^#1>`!C47HB5PD!(D$).C;C`(` +XMBQTP80D(A=N)'41A"0@/A$H!``#'!3!A"0@`````Z1C^__^X`@```.@^^/__ +XMB)1"0$Z&J,`@"%_P^%!_[__\<$)%@```#H%A;__^EI +XM^___B10DZ(66_O_I"_[__[@"````Z,KW__^)P^DI____C47HQT0D!%L```") +XM!"3H((P"`.LKQP4P80D(`````(/["@^$X````(U5Z(E<)`2)%"3H_(L"`(/[ +XM70^$J0```(L=,&$)"(7;B1U$80D(=<6X`P```.AI]___BGY__^X`@```.@#]___ +XMB<.0Z/G__[@"````Z)+V__^)P^GJ^___C70F`(V\)P````!5B>6# +XM["B)??R)UXL5,&$)"(EU^(G&B5WTB4WLA=*)%41A"0@/A!8!``"#^BK'!3!A +XM"0@`````BQX/A!4!```/CIL```"#^BT/A+(!``"#^EX/A"$!``#WP@```$"- +XM=@`/A7H!``"#^G\/AW$!``#V!)6]40D(!,=%\`````!U-.E;`0``QP4P80D( +XM`````/?"````0`^%X0$``(/Z?XGV#X?6`0``]@25O5$)"`0/A,@!``"+3?"- +XM!(F-1$+0BQ4P80D(B47PA=*)%41A"0AUM#'`Z*CU__^)PNNSC70F`(/Z)`^$ +XM/P$``(/Z)8UT)@`/A6'___^A;&$)"(/X_W0CA=L/B"X!``")!XVV`````(7; +XM>'R+!SD&?PDY1>P/C:T```#'!"1>````Z($3__\QP(M=](MU^(M]_(GL7<.) +XM]C'`Z#GU__^+'HG"@_HJ#X7K_O__A=L/B/H```"+1>R)!SL&?:NX`0```,<' +XM`````,<&`0```.NYA=L/B,L```"%V\<'`0```'F*C;8`````BQTP80D(A=N) +XM'41A"0@/A)D```#'!3!A"0@`````B1PDZ/K>__^)7"0$QP0DU-<(".@Z%``` +XMA<`/A$;___^)]K@!````Z5?___^-M@````"%VP^(A````(M%[(/H`8D'B10D +XMZ+C>___I$____XUV`(7;>S'!@````#'!"0M````@^@!B0?HDM[__[@! +XM````Z0G___^%VW@YBTWLB0_IVO[__XD&Z\<%,&$)"``````/A($'``"C,&$)"*$$F0H(QP5L80D(_____Z/@F`H(BT6\ +XM.P5$F@L(=&F+'3!A"0B%VXD=1&$)"`^$*`<``,<%,&$)"``````['8R8"@AT +XM0XU#W8/X.W8T,?^)7"0$QP0DV-<(".BW$@``A<`/A!X)``")'"3H5]W__Z&, +XMF`H(HS!A"0B#Q$Q;7E]=P_\DA839"`B+%2"9"PB%THE5P`^$2@H``(M=P#L= +XM()D+",<%+&$)"`$````/A'P(``"+5<"+0@B+4@2+0`@YP@^$E`H``#'VBT`( +XM@\8!.<)U]HM=O#L=1)H+",=%\`````")=>P/A-P)``"+'3!A"0B%VXD=1&$) +XM"`^$V@<``,<%,&$)"`````")7"0$QP0DYM<(".C]$0``AR+5?"#P`$IT(/J`872HS1A"0B)5?!X%8M-P(U"_X7`B<*+20B)1?") +XM3ANS?__B47`H3!A"0B%P*-$80D(#X2%!```QP4P80D( +XM`````(/X.@^%#P0``(L],&$)",<%.&$)"`````"%_XD]1&$)"`^$1@0``,<% +XM,&$)"`````#'1<0`````C;0F`````(/_9[L!````=%N#_V%T48U'VH/X4G9[ +XM@_\*#X2'!@``B7PD!,<$)%L```#H(`___XL=,&$)"(7;B1U$80D(#X2'`P`` +XMQP4P80D(`````(/[.@^$<____^GR_O__C70F`+L"````BSTP80D(A?^)/41A +XM"0AT$L<%,&$)"``````)7<3I>?___S'`Z)+P__^)Q^OM_R2%=-H("*%880D( +XMA<`/A'\)``"A5&$)",<%3&$)"`````#'!"1(80D(B40D!.@[AP(`QP0D2&$) +XM".@?A0(`H4AA"0C'!5AA"0@`````QP0D5&$)"(E$)`3H$(<"`,<$)%1A"0CH +XM](0"`(L=-&$)"(7;B5W(#X28_O__BT7$C5W8QT7H`````,=%S`````"#X`&) +XM1;CK08VT)@````"-7>2)^L=%Y`````"-3>B)'"2+7<"+`^A4[O__B<:+1>B% +XMP'0'QT7,`0```/9%Q`)U>8M5T(DRBUW0@VW(`0^(_?W__\=$)`0,````QP0D +XM`0```.@('`(`C578B470B5`(QP``````B4,(B5@$BTW`BTD(B4W`BP&%P'2[ +XMBTVXAB%P'2#@?[X;PD(#X1W____C47DB?J)!"2-3>B)\.BC[?__B?.)7"0$B00D +XMB<;HCXW^_X7`=;^)'"3H%QL"`.E$____BS4P80D(A?:)-41A"0@/A(,"``#' +XM!3!A"0@`````]\8```!`=3^)\0^VT8'Z_P````^'@0(``*'@70D(BT20-/;$ +XM`0^%A`8``(/^7P^$>P8``(/^?W<.]@2UO5$)"`0/A6@&``")="0$QP0D_[D( +XM".@-#@``A<`/A5`&``#'!"1(80D(Z$F#`@#'!4QA"0@`````ZRR#^PK'!3!A +XM"0@`````=#LY\W1#@_M<#X07`0``B5PD!,<$)$AA"0CHL8("`(L=,&$)"(7; +XMB1U$80D(=<0QP.@J[O__B<.#^PIUQ<<$)`H```#H1]C__Z%,80D(A<`/A:\! +XM``"A2&$)"(L8A=L/A"`'``")!"3H'XW^_Z-,80D(QP5D80D(`````.LNB?:# +XM^PK'!3!A"0@`````=#LY\W1#@_M<#X3L````B5PD!,<$)&!A"0CH)(("`(L= +XM,&$)"(7;B1U$80D(=<0QP.B=[?__B<.#^PIUQ<<$)`H```#HNM?__\<$)&!A +XM"0CH3H("`.DJ_?__@TW$`>DA_?__BQTP80D(@P5P=@H(`87;B1U$80D(#X5Y +XM_/__,<#H3NW__XG#Z77\__^)!"3H;]?__^E*_/__BQTP80D(A=N)'41A"0@/ +XMA(D```#'!3!A"0@`````.?,/A,/^__^#^UP/A+K^___'1"0$7````,<$)$AA +XM"0CH9X$"`.FA_O__,<#HZ^S__XG'Z;;[__\QP.C=[/__Z7G[__^+'3!A"0B% +XMVXD=1&$)"'0]QP4P80D(`````#GS#X3R_O__QT0D!%P```#'!"1@80D(Z!*! +XM`@#IV?[__S'`Z);L__^)PXUT)@#I;____S'`Z(3L__^)PXGVZ\#'!"1<```` +XMZ*(*__^)]NG'^O__,<#H9.S__XG&B?;I=_W__\<$)$AA"0CH'X$"`.E<_O__ +XMB10DZ.Z*_O^)]NEY_?__,<#H-.S__XG#B?;ITOC__S'`Z"3L__^#^'N0#X5_ +XM^/__QT6\>P```.EX^/__QP0D2&$)".C2@`(`QP5,80D(`````.LLQP4P80D( +XM`````(/X"@^$PP(``(/X/P^$Q@(``(E$)`3'!"1(80D(Z#J``@"A,&$)"(7` +XMHT1A"0AUQC'`Z+7K___KQXL=,&$)"(7;B1U$80D(#X2%!```QP4P80D(```` +XM`+\!````Z43X__^+->"8"@@[-029"@B)'3!A"0@/A$,$``"+%1QW"@B%TG44 +XMZ2$!``"-="8`BU(0```.@S"?__Z>'W___'!3!A"0@J````B?&)^HU%\.AH]/__A<`/A,/W +XM__^+'3!A"0B%VXD=1&$)"`^$&P,``,<%,&$)"`````#IJ/C__S'`Z+;J__^) +XMP^DB^/__H3!A"0B%P*-$80D(#X2>`@``QP4P80D(`````(/X?0^$ROC__\<$ +XM)%8```#HK@C__^FY^/__QP0D"@```.B=U/__Z6CY__^+0PB+%828"@B+0`@Y +XMT`^$&`(``#'VBT`(@\8!.=!U]NE_]___B30DZ,MS``")PXD$).BAA`(`QP0D +XM8````(E$)`3H40C__XD<).@I%@(`@\1,6UY?7#^W^0=Q'V!)V]40D( +XM!(T$MHUT0]!U!;[_____B5PD!,<$)$AA"0CH^'T"`(L=,&$)"(7;B1U$80D( +XM=!2%V\<%,&$)"``````/B7'____KCS'`Z%WI__^)P^E=____B1PDZ'[3__^A +XM3&$)"(7`#X5<`0``H4AA"0B)!"3H8(C^_Z-,80D(H8R8"@BC,&$)".D#]O__ +XMQP0D"@```.A$T___H4QA"0B%P`^%]P```*%(80D(B00DZ":(_O^%P*-,80D( +XM#X1*`0``N@$```"A2&$)".B.YO__A<")P@^%COW__^F1_?__B1PDNSH```#' +XM!3!A"0AS````Z.C2___IGO;__XLU!)D*".DU_?__BSTP80D(A?^)/41A"0@/ +XMA(D!``#'!3!A"0@`````B3PDZ++2___WQP```$!U,XGX#[;0@?K_````#X=_ +XM`0``H>!="0B+1)`T]L0!=06#_U]U#\=%\`````")=>SI,O;__X/_)@^%XO7_ +XM_^OF,?;IP(`QP0D2&$)".@W?`(`H4AA"0B+%4QA +XM"0B)1"0$@\`$C125_/___XE4)`B)!"3HSHK^_Z%(80D(,=+'`"T```#I2/[_ +XM_XL-()D+"(7)B4W`#X4B]/__Z:?[__\QP.@3Y___B<.0Z7;[__\QP.@$Y___ +XMB<>)]NEQ_O__QP0D5P```.@?!?__Z?KU__^)%"3HCH7^_XGVZ7O^___'!"19 +XM````Z/\$___IVO7__XUV`(V\)P````!5B>575E.#[%RA[%T)",<%$&$)"``` +XM``#'!7"<"P@`````QP0D[)@*"(E%H.BOT___BU4(B5($B5((QP+X;PD(QP4L +XM80D(`````,<$)`````#H:MG__X/X('3O@_@)=.H[!42:"PAU#HL5P'8*"(72 +XM#X6/!0``B00DZ'+0__^+10B-?>C'1"0$D.D%"(D$).B\!___BUT(QP0D#``` +XM`.C]$@(`B46DB5@$QP``````BU4(B5`(B4($B4,(QT7H`````,=%[`````#' +XM1?``````QT0D!+"1"`B)/"3H<`?__XL=,&$)"(7;B1U$80D(#X1``@``QP4P +XM80D(`````(/[('3=@_L)=-B%VW@,]\,```!`#X0M`@``,?;'1:@#````A?9T +XM13GS#X24````@_M<#X2:````@_L*#X3!`P``D(E<)`2)/"3HY'D"`(L=,&$) +XM"(7;B1U$80D(=%:%]L<%,&$)"`````!UNX7;>-*)V,'H'H/P`8/[?P^>PH30 +XM=,`/ML,/MX0`X"`)"*A3=+&#^UP/A%(!``"H`P^$D@```#'`@_LB#Y3`B=Z# +XMP`*)1:CKCHM%J.@&Y?__B[^__^)'3!A"0B)/"3HH`7_ +XM_XD\).A(!?__B3PDZ.!X`@"+5:2)TXD"QT6@`````(,X"@^%$/[__XM%"(D$ +XM).AN!?__BU4(B10DZ!,%___'!"1LG`L(Z.=X`@"+%7"<"PB%TG04H6R<"PB# +XMZ`2-!)"#.`H/A#,#``"A+&$)",<%$&$)"`$```"#Q%Q;7E]=PS'`Z-OC___I +XM`O___XL=,&$)"(7;B1U$80D(#X1^`0``@_L*QP4P80D(``````^$?0$``#L= +XMC)@*"'00QT0D!%P```")/"3H!W@"`('+````0.D,_O__N`,```#H@N/__XG# +XMZ;G]__^#^W\/C\K]__\/ML,/MX0`X"`)"*A0#X2W_?__@_L[#X12`0``#X^X +XM````@_LF#X3-````C;0F``````^/*@$``(/["HVT)@`````/A"8!``"#^R.- +XMM"8`````#X5R_?__H)7+6X +XM@\8!@_L*#X3-````B5VPBQTP80D(A=N)'41A"0AUR#'`Z*;B__^)P^O'N`H` +XM`$#I\_W__X/[/I"-="8`=!0/C^<```"#^SR0C70F``^%TOS__XE<)`2)/"3H +XMWG8"`*$P80D(A<"C1&$)"`^$&P$``,<%,&$)"``````YV'1*HS!A"0CIW/W_ +XM_S'`Z#WB__^)PX/["@^%@_[__X,]O)@*"`$/A;W]___'!;R8"@@"````Z:[] +XM__^-M@````"-0]B#^`$/AUS\__^)7"0$B3PDZ&AV`@#IB_W__X!]KP!T&X-] +XMN"O'1>0`````B?8/A*@````QR8D-%&$)"(-]L%P/A.C[___KPHVV`````(ET +XM)`3'!"0S````Z.#__O_'!3!A"0@*````Z3G]__^#^UQT$8/[?`^%Z_O__XUV +XM`.D1____BQTP80D(A=N)'41A"0AT+\<%,&$)"`````"#^PH/A;T```"#/;R8 +XM"@@!#X5[^___QP6\F`H(`@```.EL^___,<#H1>'__XG#Z]"X`P```.@WX?__ +XMZ>#^__^+1;R%P`^$3?___P^VT(/Z?Y`/AT#___\QR3'V]@25O5$)"`1U)NDM +XM____C;0F``````^VT(/Z?P^'&O____8$E;U1"0@$#X0,____C02)@\8!C4Q" +XMT(M$M;R%P'74@_X*#X7Q_O__Z>[^___'``````#IPOS__^CF[/__C;8````` +XMZ6GZ__\['8R8"@AT$,=$)`1<````B3PDZ`-U`@"!RP```$#IX/K__Y"0D)"0 +XMD)"058GEBU4(BTT,A=)U!NL9D(/"`0^V`H3`=`X/OL`YR'7O7;@!````PUTQ +XMP,.-="8`53'`B>6+50B+"H7)=`R)]H/``8L,@H7)=?9=PXUT)@!5B>53BUT( +XMBTT,B=J-="8`BP&#P02)`H/"!(7`=?*)V%M=PXVV`````(V\)P````!5B>6+ +XM10B%P'08BQ"%TG4$ZQ")T(M(!(U0!(7)=?2+`%W#73'`PXUV`(V\)P````!5 +XM,=*)Y8M%"(7`=0?K#(GV@\`!@#@`=?B)PEV)T,.)]E6)Y8M-"(7)=!:)RHUT +XM)@"+`B7___\_B0*#P@2%P'7P78G(PXVV`````(V_`````%6)Y8M%"(7`=!F+ +XM$(72=!.)P8'*````0(D1@\$$BQ&%TG7O7<.-="8`C;PG`````%6)Y5.+70B+ +XM30SK"HUT)@"#PP2#P02+$X72=!J+`87`=`^!XO___S\E____/SG"=-];,575E.#[`R+?0R+=1"0Z+MP`@"+10B)="0(B7PD!(D$ +XM).@T?/[_@_C_B<-U"NAX@/[_@S@$=->#Q`R)V%M>7UW#C;8`````C;PG```` +XM`%6)Y5=64X/L#(M]#(MU$.L4Z$:`_O^#.`1U))"-="8`Z%MP`@"+10B)="0( +XMB7PD!(D$).C4@?[_@_C_B<-TTH/$#(G86UY?7<.-M"8`````58GE5U93@^P, +XMBWT,BW40D.@;<`(`BT4(B70D"(E\)`2)!"3HA(/^_X/X_XG#=0KHV'_^_X,X +XM!'37@\0,B=A;7E]=PXVV`````(V\)P````!5B>575E.#[!R+?0SWQP`"``!T +XM80^W=1"-112)1?#K%>B7?_[_@S@$=26-M@````#HJV\"`(ET)`B)?"0$BT4( +XMB00DZ$2!_O^#^/^)PW31@\056 +XM4X/L$(MU".B\?O[_QP``````ZQKHKW[^_X,X!'4>Z,EN`@#HH'[^_\<````` +XM`(DT).A">_[_A<")PW38@\00B=A;7EW#C;0F`````%6)Y593@^P0BW4(Z&Q^ +XM_O_'``````#K&NA??O[_@S@$=1[H>6X"`.A0?O[_QP``````B30DZ!)[_O^% +XMP(G#=-B#Q!")V%M>7<.-M"8`````58GE5U93@^P,BWT(#[=U#.L3Z!5^_O^# +XM.`1U'(UT)@#H*VX"`(ET)`2)/"3H:WK^_X/X_XG#=-J#Q`R)V%M>7UW#C;0F +XM`````(V\)P````!5B>53@^P$BUT(ZQF-="8`Z,=]_O^#.`1U&(VV`````.C; +XM;0(`B1PDZ"^!_O^#P`%TWH/$!%M=PY"-M"8`````58GE4X/L!(M="(7;>1?K +XM(NB'??[_@S@$=1B-M@````#HFVT"`(D<).@??O[_@\`!=-Z#Q`1;7<.0C;0F +XM`````%6)Y8/L",<$)`````#HKO___\<$)`$```#HHO___\<$)`(```#HEO__ +XM_\<%Z'8*"`````#)PXUV`(V\)P````!5B>575E.[`00``(/L#(M]",<$)`$$ +XM``#H0P@"`(G&ZQ&-'`")-"2)7"0$Z(`(`@")QHE<)`B)="0$B3PDZ.J`_O\Y +XMV'3;@_C_=!O&!`8`@\`!B40D!(DT).A2"`(`@\0,6UY?7#2+7?`Q]NL'@\8!.?YT$8/#!(D$).C8!@(`BP.%P'7HBT7PB5T,B44(@\0, +XM6UY?7>E]^O__BUWPZ^:0C;0F`````%6)Y593@^P0BW4(A?9T*(L&A53 +XM@^P$BUT(BP.)!"3HK/___XE="(/$!%M=Z4\&`@#K#9"0D)"0D)"0D)"0D)!5 +XMB>5=Z8?___^-M"8`````58GE@^P(BT4(B00DZ']T`@"C('<*",=%"!D``!#) +XMZ9WX_O^-M@````"-O"<`````58GE5E.#[!"+70R+=0C'1@0`````BQ.%TG0Z +XMD(UT)@"%TG@<]\(```!`=12#^G^0?PX/ML+VA`#@(`D(\W4GD(/#!(E4)`2) +XM-"3H$6X"`(L3A=)URXDT).AC;@(`BP:#Q!!;7EW#QT0D!%P```")-"3HZFT" +XM`(L3Z\:-M@````!5B>53@^P4BUT(B1PDZ`[Y___'1"0$!````(/``8D$).B[ +XM!0(`B5PD!(D$).@/^?__@\046UW#B?:-O"<`````58GE5U93@^P,BW4(BWT, +XMB30DZ,GX__^)/"2)P^B_^/__QT0D!`0```"-1!@!B00DZ&L%`@")="0$B<.) +XM!"3HO?C__XLSB=B%]G0.D(UT)@"#P`2+"(7)=?>)?"0$B00DZ)OX__^#Q`R) +XMV%M>7UW#D%6)Y5>)QU:)UE.#[`SK%I#H1WK^_X,X!'4>C;8`````Z%MJ`@") +XM="0$B3PDZ'MW_O^#^/^)PW38@\0,B=A;7E]=PXVT)@````"-O"<`````58GE +XM@^P8B5WXB=.)=?R)!"3HEG?^_X7`B<9X.X/[_W0E.=YT%8G:B?#HTO___XDT +XM)(G#Z#C\__^)WHGPBUWXBW7\B>Q=PX/X!7[6B?"+7?B+=?R)[%W#OO____^+ +XM7?B)\(MU_(GL7<.0C;0F`````%6)Y5.#[`2+10B+70PYV'06A!>) +XMVI"-="8`Z!O___^)V(/$!%M=PXUV`(/X!7_R@\0$B=I;7>E/____ZPV0D)"0 +XMD)"0D)"0D)"058GE@^P8B5WXBUT(B77\BW4,.?-T'X7;>!N%]G@CB?*)V.C) +XM_O__.=YT"HD<)(GSZ'O[__^)V(MU_(M=^(GL7<.)="0$B1PDZ&/___\YPXG& +XM==CKX(UT)@"-O"<`````58GE4S';@^P$Z*)5__^)]CL=M'8*"'0H.QW,EPH( +XM="`['01V"@AT&#L=1)D+"'00@_L/=`N)'"3H$_O__XUV`(/#`8/[0'7(@\0$ +XM6UWI/E;__XVT)@````"-O"<`````58GE@^PHB7W\BWT(B5WTB77XA?]T>HM% +XM#(7`=&.)/"3HMWO^_XG&BT4,B00DZ*I[_O^)1?"-1`8!B00DZ(\#`@")="0( +XMB7PD!(G#B00DZ-EZ_O^+1?"-%#.)%"2#P`&)1"0(BT4,B40D!.B]>O[_B=B+ +XM=?B+7?2+??R)[%W#B?;'10Q%R0@(ZY2-M"8`````OT7)"`CI?/___XVV```` +XM`%6)Y8/L&(EU^(MU"(E=](E]_(7V=#J)-"3H'GO^_XUX`8D\).@'`P(`B7PD +XM"(ET)`2)PXD$).A1>O[_B=B+=?B+7?2+??R)[%W#C;8`````OD7)"`CKOXGV +XMC;PG`````%6)Y8/L&(EU_(MU#(E=^(U&`8D$).BV`@(`B70D"(G#BT4(B1PD +XMB40D!.C]>?[_B=C&!#,`BUWXBW7\B>Q=PY!5,<")Y5=64X/L#(M="(7;=$>) +XM'"3H1O7__\=$)`0$````@\`!B00DZ/,!`@")QXL#AB?N-M"8````` +XMB00DZ+AM`@")`XM&!(/#!(/&!(7`=>F)^(/$#%M>7UW#ZPV0D)"0D)"0D)"0 +XMD)"058GE5E.#[""+70C'1>P`````C77LQT7P`````,=%]`````"+`^L2QT0D +XM!"````")-"3H>6D"`(L#A"%P%T/ +XME,`/ML##BT($J0```$!T!%TQP,.#^'^0=_;V!(6]40D(!'3L@\((BP+KGI"0 +XMD)"0D)"0D)"0D)!5B>5=QP4@F0L(`````,<%A)@*"`````#'!3"9"P@````` +XMPXVV`````(V\)P````!5B>564X/L$(MU"(7V#X2@````#[8&/`(/A(@```!W +XM$BP!=#:)=0B#Q!!;7EWI?O\!`#P&=^Z+1@B)!"3HO____XM&#(D$).BT____ +XMB74(@\006UY=Z5;_`0"+5A"+`H7`=!>)TXD$).A#_P$`BT,$@\,$A7>D*_P$` +XMBT84B00DZ$_____KSX/$$%M>7<.-M@````!5B>5=Z3?___^-M"8`````58GE +XM5U93NP$```"#[#PYT(E%V(E5U(E-T,=%[``````/A(4```")PXL#B00DZ%Y? +XM__^#^!*)P0^&90,``,=%[`````"+7=@Q_S'VZR*-=@"#^"@/A)<#``"+3>R% +XMR74$A?]U`X/&`8M;"#E=U'0PBP.+`(/X*0^$A`,``'[2@_@\=`6#^#YUT87_ +XM#X2``P``BT7LA3'1"0$!````(D<).AN_@$`BU7DB47HB4(0BTW4BP&#."D/ +XMA&,#``"+1=0Y1=@/A&H#``"+5=`Q_XM-T(M=V,=%W`````"#X@�+'1>`` +XM````QT7P`````(E5S(E-R.LO@_@H#X0N`0``A?\/A4T!``"+-8!>"0B%]@^$ +XM6`$``(-%\`&+6P@Y7=0/A-H```"+$XL"@_@I#X3!`0``?L*#^#P/A$@!``"# +XM^#Z-=@!UNH7_#X4'`0``@WH$/HGV#X3J`@``BT,(.T74#X3_`0``BS#'1"0$ +XM,#L)"(DT).BH;_[_A<`/A,(!``#'1"0$0#L)"(DT).B0;_[_A<`/A<<"``"+ +XM1>2!2`0``0``BUL(BW,(.W74#X2T`0``BP:)\XL`QP0DSML("(E$)`3H7?#_ +XM_X7`#X66`0``BT70@^`,@_@$=`Z+5>2+0@R%P`^$EP(``,<$)&4```#HX.[^ +XM_XM;"#E=U`^%)O___XM=W(7;=`N+3>R%R0^$_@```(M%\(7`#X06`@``BTWD +XMQ@$!BT7D@\0\6UY?7<.%_W4@BU7R%P`^$NO[__XLU@%X)"(7V#X6H_O__BP.)!"3H?&@"`(M- +XM\(M5Z(D$BNF0_O__A?]URX-Z!#P/A+P!``"+2+ +XM00B%P`^$M@$``,<$)&<```#HZNW^_^DK_O__D(UT)@"#[P$/A5C___^+1>R) +XM7>"%P`^$#_[__^E0____BU7PA=(/A5,!``"+3>3&`0*+5>"Y`0```(M%W.CS +XM!```BU7DB4(4BT7D@\0\6UY?7<.+3>2!202`````]D70#(M;"`^%C_[__XM# +XM"#M%U`^%`@$``,<$)&0```#H8^W^_^FD_?__N`$```#3X*D`ZP0`#X6,```` +XMJ!`/A('\__^+6P@[7=0/A6#\___IP!````Z?C[___'0@00````BT74.478#X66_/__QP0D)````.B5 +XM[/[_Z=G]__^+5>2#2@0"Z0K]__^+1>2!2`0``@``Z37^__^+2)00SIAOS__XL& +XMB00DZ%9F`@"+5>2)0@CI=>V+3>B)\H/$'(GX6UY?7>G#^O__C78`A=)US,=$)`08 +XM````QP0D`0```.CH^0$`BTWH@\D$B47PBT,(.?")1>QT7HL`@S@F=$"+1?") +XMVL8``XGXZ'_Z__^+5?")0@B+5>R+`H,X)G0S@TWH`HGRBT,(BTWHZ#[___^+ +XM5?")0@R#Q!R)T%M>7UW#BT7PBTWH@4@$@````(/)#.NNBUWLZ\B+5?")^,8" +XM`XG:Z"CZ__^+5?")0@CKL56)Y5>)UU93B<.#[!PYT(E-['0TB<8QR>L;C;8` +XM````@_@I#X27````@_@F=#*+=@@Y]W03BQ:+`H/X*'7BBW8(@\$!.?=U[8M- +XM[(GZ@\0EF____D(VT)@````!5 +XMB>57B==64XG#@^P<.=")3>QT-HG&,@1\=57B<=6B=93@^P<.=")3>P/A*(```")PS'2ZQV)]H/X +XM"G0F@_@H=0:#P@&-=@"+6P@YW@^$?P```(L#BP"#^"ET;'[:@_@[=>6%THUV +XM`'7>QT0D!!@```#'!"0!````Z&KW`0")VHE%\,8`!(M-[(GXZ,C^__^+5?") +XM0@B+1>R)="0$B40D"(M#"(D$).BL`0``BU7PA<")0@QT+XM%\(/$'%M>7UW# +XMC;0F`````(M;"(/J`3G>=8&+3>R)\H/$'(GX6UY?7>ES_O__BT((QT((```` +XM`(E"#.O"C70F`%6)Y5=64X/L'#G0B47PB57LB4WH#X3L````BQB)QC'_ZQR# +XM^"9T;X/X*'4$@\BP.#^"ET/G[;@_@^=`R#^'R0 +XM==Z#>P1\=-B+=@@[=>R)]@^$G````(L>QT0D!#`["0B)'"3HA&C^_X7`=+2+ +XM`X/X*77"@^\!>:C'!"1A````Z!SH_O_KFH7_=9:#>P0FB?9TCHM-Z(GRBT7P +XMZ''^__^)QP^V`#P$='L\!G1W/`5TR)-"2)1"0$Z&,```")0PSK)X7_ +XM=16+3>B+5>R+1?"#Q!Q;7E]=Z07^___'!"1B````,=OHA^?^_X/$'(G86UY? +XM7575E.#[`R+70B+=0R+?1`Y\W4)ZS&+6P@YWG0JBP.+`,<$),K;"`B) +XM1"0$Z&WH__^%P'7A@\0,B?F)\HG86UY?7>E7_O__@\0,,575HG64XG#@^PL.=`/A#D!``"+`(,X*`^$#P$``,=$)`24 +XM=@H(B00DZ"!1``"%P(G"#X04`0``BT,$B36$F`H(HR"9"PB+`L=$)`10*@8( +XMQP0D,)D+"*,PF0L(Z.WI_O^-1>B)1=B)!"3HC^'__XE%X,<$)#"9"PCH,.G^ +XM_XL-@%X)"(7)=!>-1>B)!"3H6[/__\<$)````$#HO^;^_XL#BQ"%T@^%T@`` +XM`(M%X(7`#X2T````BWL$D(UT)@"+`XD$).@&]`$`BUL(BT,$B00DZ/CS`0`Y +XMWG7DB7<(N`$```")?@2+5=@Y5?!T88M%[(M`!(E&!(M%[(M`!(EP"(M%\(EX +XM!(E'"(M%[(L`B00DZ+GS`0"+1>R)!"3HKO,!`(/$++@!````6UY?7<.+4@2+ +XM`H,X*741ZQV0C70F`(M2!(L"@S@I=`XYTW7R,<"#Q"Q;7E]=PXM#"#G0=._H +XM7````(/$+%M>7UW#BW,(BWL$.?,/A4;____I7?___XM5\(E5W(LZB00DB7PD +XM!.BI9?[_A<`/A1+___^)?"0$QP0D($,)".C57@(`BU7P/A,X```"+&(G&,?_K(I"#^"9T.X/X +XM*`^$G````(/X"G0MBW8(.77L#X26````BQZ+`X/X*71H?M:#^#Z-=@!T-(/X +XM?'0)@_@[==>-="8`A?]USXM%\(GRZ-+]__^Z`0```(7`=62+1@B+5>R#Q!Q; +XM7E]=ZWJ+=@@[=>QT1XL>QT0D!#`["0B)'"3HW&3^_X7`=(^+`X/X*76=D(UT +XM)@"#[P$/B7K____'!"1A````Z-OD_O_I:?___X/'`8UV`.E>____,=*%_W0* +XM@\07UWI2?W__XGVC;PG`````%6)Y5:)UE.) +XMPX/L$#G0=0GK+HM;"#G>=">+`XL`QP0DRML("(E$)`3H4^7__X7`=>&#Q!") +XM\HG86UY=Z<#^__^#Q!`QP%M>7<.-M"8`````58GE5E.[,@```(/L$(MU",<% +XM:)P+"`L```"-M@````"+1@B)\NB&____A&#Q!!;7EW#D)"0D)"0D)"0D)"058GEBT4(78L`HW!A +XM"0C#D%6)Y5W'!=@D"0B@G`L(PY!5B>6#[!BAV"0)"#V@G`L(#X2`````BPV$ +XM=PH(A&$) +XM"`$```"%TG5)BPWH=@H(N@$```"%R74&BQ7,EPH(+:"<"PB)1"0(QT0D!*"< +XM"PB)%"3HH^7__X/``71>QP78)`D(H)P+",<%>&$)"`````#)PXL-Z'8*"+H" +XM````A&$)"`````#'!=@D"0B@G`L(QP0D````(.@` +XMX_[_H=@D"0CI8?___XVV`````.CG9?[_BP"#^`ET'HUT)@!^*8/X&703B?:- +XMO"<`````?"&#Z$6#^`%W&<<$)`$```#HZH+^_^EG____@^@%@_@!=N?'!"0` +XM```@Z*'B_O^0Z4W___^-="8`C;PG`````%6)Y8/L"*'8)`D(BU4(@>+__S\` +XMB!"#P`$]EJ0+"*/8)`D(<@7HEO[__\FX`0```,/K#9"0D)"0D)"0D)"0D)!5 +XMB>53@^P$BPW`F`H(BUT(A#.-=@")'"3H.*4!`(E="(/$!%M=Z4O___^A?)@*"(7`#Y7`Z\*A_)D+"(7` +XM#Y7`Z[:-=@"!XW____>!RP````CKPNA]9@$`ZZN-="8`C;PG`````%6)Y593 +XM@^P0BT4(BQ5P80D(B<:)PX'F````/('C__\_0(72=5VI````0'56.QW<70D( +XM?2RAX%T)"/9$F#4"=!:#^W\/CA8!``"#/8!1"0@!#X0)`0``]D28-@1U&8UV +XM`(/[?P^.L@```(,]@%$)"`$/A*4````)WHDT).C0_O__ZR^+%<"8"@B!X___ +XM_S^%TG0^H>AV"@B%P'5EH?R9"PB%P`^5P(3`=3Z)'"3H7_[__XLUU"0)"(7V +XM=`N!X___/P"#^PIT2H/$$%M>7<.-=@"AZ'8*"(7`=!JA?)@*"(7`#Y7`A,!T +XMP@G>B30DZ/^C`0#KMJ'@=0D(A<`/E<#KII"A;)D+"(7`#Y7`ZYF-="8`@\00 +XM6UY=Z;7\__^)\(/(7(D$).C8_O__B=C!^`:#X`>#P#`)\(D$).C#_O__B=C! +XM^`.#X`>#P#`)\(D$).BN_O__B=B#X`>-6##I%____XU#]X/X`0^&"____XL- +XM=&$)"(7)=!J)\(/(7HD$).A^_O__@_M_=!*#RT#IY_[__X/[#77AZ=W^__^S +XM/Y"-="8`Z='^__^-="8`C;PG`````%6)Y5=64X/L'(M="(G8)?__/P")1"0$ +XMC47NB00DZ"Y:`@"%P(G'="")WC';@>8``,#_#[9$*^Z#PP$)\(D$).@,_O__ +XM.?MUZH/$'%M>7UW#58GE5U93@^PZ)!"3HWED" +XM`(7`B<=T((G>,=N!Y@``P/\/MD0K[H/#`0GPB00DZ`S]__\Y^W7J@\0<6UY? +XM7<-5ND#C12)`=(ITXE<)`B)3"0$ +XMZ&`Z`@"#Q!1;7<.-=@"-O"<`````5;AWFBX`B>564X/L$(MU"(GQP>D&]^&) +XMT\'K`H7;#X2,````B5PD!,<$)-C;"`CH'#H"`&G#0'X%`(GQ*<&X'X7K4??A +XMB=.ZB8B(B,'K!8G8]^J-!!K!^`7H8O___\<$)-K;"`CHYCD"`(G8NHF(B(CW +XMZ@':P?H%:](\*=.)V.@\____QP0DDAT)".C`.0(`B?"Z'X7K4??B@\006\'J +XM!6O29"G6B?!>7>D2____B?:X'X7K4??FQP0D/=P("(G3NHF(B(C!ZP6)V/?J +XM`=K!^@6)5"0$Z'8Y`@#K@HUT)@!5N,6SHI&)Y593@^P0BW4(]^:)T\'K"X7; +XM=&B)7"0$QP0DV-L(".A%.0(`:<,0#@``B?.ZB8B(B"G#B=CWZHT$&HG:P?@% +XMP?H?*=#HD/[__\<$)-K;"`CH%#D"`(G8NHF(B(CWZHG8P?@?@\00`=K!^@4I +XMPFO2/"G3B=A;7EWI7?[__XGPNHF(B(CWZHGPP?@?B?/'!"0]W`@(`?+!^@4I +XMPHE4)`3HQC@"`.NDD)"0D%6A@'<*"(GE7<<%@'<*"`````"CB'8*",.-M"8` +XM````5:&(=@H(B>5=QP6(=@H(`````*.`=PH(PXVT)@````!5B>564XG#H0"8 +XM"@B%P'1`BPT\=PH(,?;K#(VV`````(L`A7<.-M@````"-OP`````[!3QW +XM"@A5B>53B<-T$CL%<)D+"'0J6UW#C;0F`````*%PF0L(A6#[`B#/=27"@C_="*AU)<*"(7`=`C)PXVV`````,<$)#X```#H5-S^ +XM_\F-=@##QP0D(````.A#W/[_C78`Z\V-M"8`````C;PG`````%6)Y593@^P0 +XMBQT`F`H(BW4(QP6,=@H(`@```(7;="N0]D,,`G0>A?:X`;H("'4%N$7)"`B) +XM1"0$QP0D0````.CLV_[_BQN%VW76@\006UY=P^L-D)"0D)"0D)"0D)"0D%6) +XMY8/L6(E]_(M]"(E=](EU^(/_``^."@$``(U=U(UUY(D<).B#8/[_QT0D!!(` +XM``")'"3H@UO^_\=$)`05````B1PDZ'-;_O^)="0(B5PD!,<$)`$```#H#UO^ +XM_\=$)`1@'@4(B30DZ%/>_O^+10S'!"0`````B40D!.B<7/[_@\`!#X2G```` +XMA?]^=L<$)`\```#H\UW^_SE%#'1:C5V\B5PD",=$)`0`````QP0D%@```.CS +XM7O[_QT0D!`$```#'!"06````Z$]?_O^+10S'!"0/````B40D!.@,6O[_QT0D +XM"`````")7"0$QP0D%@```.BT7O[_C47DB00DZ!W=_O\QP(M=](,]U)<*"`"+ +XM=?B+??P/G\"#Z`$A!=27"@B)[%W##XU"____Z]:-=@#HQV#^_\<$)`````") +XM10R)1"0$Z-1;_O^#P`%T"(M]#.DT____Z')=_O^+`(D$).@86_[_QT0D!-S; +XM"`C'!"0V````B40D".A4VO[_QP0D`````.AX>O[_Z\.-M@````!5B>53B<.# +XM[!2+0!B%P'4(ZWZ+6P2+0Q@[0QQU]8G8Z#S]__\QP#L=@'<*"`^4P(/H`2$% +XM@'<*"(G8BU,4C78`@6`,_W___\=`&`````#'0!0`````BT`$.=AUY#L5,)H+ +XM"'0&@\046UW#H0"8"@@QR87`=`^+4!0YT7T"B=&+`(7`=?&)#3":"PB#Q!1; +XM7<.A@)@*",=$)`SLVP@(QT0D"`,```#'1"0$$0```(D$).@K.___B00DZ,,T +XM`@"#Q!1;7<.-M@````"-O"<`````58GE@^PHB77XBW4(B5WTB7W\A?9T"HM> +XM!(U^!(7;=2"+'3QW"@B%VW1HBQ4\=PH(BUWTB="+=?B+??R)[%W#D,=$)`3< +XM/0D(B30DZ/Q8_O^%P'3,QT0D!.@]"0B)-"3HZ%C^_X7`=+C'1"0$]#T)"(DT +XM).C46/[_AP`````ZPR+5?"+$H72B57P=&Z+ +XM5?"+0A@[0AQUZ8,_/W5&BU)XBP*%P'3;B=/K"HM#!(/#!(7`=,T[!G7RB5PD +XM!(DT).A1VO__ASKGHM5\(M" +XM>(D\)(E$)`3H(-K__X7`=(CKS8M5[(72D(UT)@`/A;K^__\QP(,_/P^4P(/H +XM`8/@\04\```0B00DZ-_7_O\QTNF8_O__QP0D.P``$.C,U_[_Z>'^__^)/"3H +XMCU,"`(D$).@S5O[_BQ4`F`H(A=*)P74(ZQB+$H72=!([2A1U]8M"&#M"''7M +XMZ5'^___'!"0M```0Z(77_O^0C70F`.G;_O__C70F`(V\)P````!5B>6#[`B+ +XM10B+0`2)!"3H[/W__X-(#"#)PXVV`````%6)Y593@^P0BS6`=PH(A?9T5/=& +XM#`(!``!T".M)C78`BW8$BT88.T8<=?6+1A2)\\<$)`?<"`B)1"0$Z%`R`@"+ +XM0QC'!"0\W`@(B40D!.@],@(`BUL$.=YUYL<$)`H```#H2O7__\<%@'<*"``` +XM``#'!8AV"@@`````@\006UY=P^L-D)"0D)"0D)"0D)"0D%6)Y5=64XG#@>RL +XM````B95D____BT`8.T,<=`^-="8`BUL$BT,8.T,<=?4Y6P0/A)`'``"+A63_ +XM__^)WHN59/___\>%=/_________'A7C___\`````@^`0B46`BX5D____@>*$ +XM````B56(BY5D____QX5P_________X/@`HE%A(N%9/___X/B`8F58/___X/@ +XM!(F%7/___XVT)@````"+1@R+E7C___^)QPG"@>%?/___R3<"`B%P'4*QX5\____^]X("#N]MP(".@# +XM,`(`C48@B40D#(U&*(E$)`B-1C")1"0$QP0DH&$)".AR6@``B?:+1@0YPW0) +XMB<;IC]___'!"0@````Z"+R___IK?[___:%9/__ +XM_P@/A8("``#VA63___]`#X2Y_O__H629"PB+0`R)1"0$BT,(BT`,B00DZ&53 +XM_O^%P`^$E_[__Z&`F`H(QT0D#'/<"`C'1"0("@```,=$)`01````B00DZ/PT +XM__^)!"3HE"X"`(M#"(M`#(D$).BFH?[_QP0D><((".AZ+@(`Z4O^__^0C70F +XM`#L=/'<*"+@K````=!0QP#L=<)D+"`^4P(/H`8/@\X/`+8M6%+D=W`@(@_H) +XM?@6Y12-1BB)1"0$B10DZ(-4``"+1>PY1>1UMHM%Z#M% +XM\`^?P.NNC47LQT0D#(!A"0B)1"0(B7PD!,<$)*!A"0CHT50``.FJ^O__BT,, +XM]L1`#X1D^/__@.2_@\A`B4,,Z5;X___'!"07W`@(Z!8J`@#I+/___Y!5B>56 +XM4X/L$(MU"(M=#(,%T*P+"`''1"0$L)`(",<$)-"L"PCHE]'^_XGPZQ"-=@"` +XMS@&)4`R+0`0Y\'0IBU`,]L(#=/&)T8/)`8G*@^+]A=N)4`QUVH'A_?[__XE( +XM#(M`!#GP==>%VW5#B?#H?_'__[H+````B?#HD_?__\=$)`03````BT8(D$).C,<$)(0``!")1"0$Z!W-_O^+5@2%TG6DC;8`````@\006UY= +XMPXGVC;PG`````%6)Y5=64X/L#(LUC'8*"(M5"(7V=`K'!8QV"@@"````C4($ +XMBU($OP<```"%TG08BU@$A=MT=,<$)#@```"_5P```.BYS/[_BPTPF@L(A7UW#B=CH&/+__^OD +XMQT0D!*PX"0AFOU<`B10DZ!Y,_O^%P'2%Z6____^)]HV\)P````!5B>53@^P4 +XMBQT`F`H(QP50F@L(`````(7;=0OK68UV`(L;A=MT4&:#>PP`D(UT)@!Y[H,% +XMT*P+"`''1"0$L)`(",<$)-"L"PCHT\[^_[H'````B=B!8PS_?___Z!#U__^H +XM`W08QP0DT*P+".@0SO[_BQN%VW6P@\046UW#B=CH;?'__^O?C70F`(V\)P`` +XM``!5B>575HG&4X/L+(7`B578="V+`(7`=">)\^L/C70F`(/#!'0:BP.%P'04 +XM@S@EB?9U[HD$).A&S?__@\,$=>:)-"3HN7K__\=$)`3P(P8(B<>)!"3H-\[^ +XM_X,%T*P+"`''1"0$L)`(",<$)-"L"PCH',[^_Z&4=PH(A<`/A08"``"%_P^$ +XM6`(``(L?A=L/A$X"``#'1=P`````QT7@`````.MG@_A_=W3V!(6]40D(!'1J +XMB1PDZ+9&`@"-5?#'1"0("@```(E4)`2)!"3HJTW^_XG#BT7P@#@`#X2!```` +XMQP0D.0``$.BURO[_@WW8#P^$+`$``(-]V`$/A"(!``"#QP1T+XL?A=MT*8L# +XM@_@E#X2.````J0```$!TAX/X+9!TD,<$)#D``!#H7UW#C;8`````BTW8B1PD +XMB4PD!.A]2?[_A<`/B73____H($W^_XL`B00DZ,9*_O^)7"0$QP0DJ=P("(E$ +XM)`CH1B4"`(-%X`'I7/___XD<).B%\/__B<:-=@"+4`P)5=R+0`0YQG7S@WW8 +XM%G<<#[9-V+@!````T^"I``!F`'1A]D7<`0^$R````(M%V(E$)`2+1AR)!"3H +XM*T_^_X7`#XCY````@WW8#W0*@WW8`0^%]O[__\=$)`03````BT8,<$ +XM)(0``!")1"0$Z![)_O_I>/[__X,%Q*P+"`''1"0$L)`(",<$),2L"PCH[LO^ +XM_^G:_?__H8"8"@C'1"0,BMP(",=$)`@,````QT0D!!$```")!"3H="K__XE< +XM)`2)!"3H""0"`(-%X`'I'O[__\<$)-"L"PCH`\O^_^E@_O__Z*5+_O^+`(D$ +XM).A+2?[_B5PD!,<$)*'<"`B)1"0(Z,LC`@"#1>`!Z=O^__^)]E6)Y5=64X/L +XM'(M5"(M"!(UZ!(7`=`6#."UT%KL/````B=J)^.BW_/__@\0<6UY?7<.-<`2+ +XM0`2#^&QT=X/XNIQP0D"@```.B[Y?__Z?_^__^+0@B-2@B%P'1AB<^)QND(____]@2%O5$) +XM"`0/A`S___^)-"3H_4("`(U5\,=$)`@`````B50D!(D$).@22?[_B<.+1?"` +XM.`!U#87;>`F#^Q\/CBK____'!"0;```0Z//&_O^-=@#I%O___\<$)`X``!#H +XMW\;^_^F?_O__C78`C;PG`````%6Z$0```(GEBT4(78/`!.D<^___C;8````` +XMC;\`````58GE@^P8B5WXB<.)=?R+`#L%($,)"'1YB1PDZ!Q'_O^)QJ%08PD( +XM@_A/=RT!\(/X3W8PQT0D!,@]"0BA5&,)"(D$).CT1?[_@P548PD($,<%4&,) +XM"%````"+7?B+=?R)[%W#B5PD!*%48PD(B00DZ,A%_O^-!+4``````3508PD( +XM`0548PD(BUWXBW7\B>Q=PX/#!.N"C78`C;PG`````%6%P(GE5HG&4P^$P0`` +XM``^V!CP"#X3M````=WHL`8GV#X2N````BU8$]L($C70F`'4EBT8(A!B+1@2#X`&#^`$9P"4``0``@\`!B4,,BU8$]L8@=`F`S$")0PR+5@3V +XMQD!T"H%+#````0"+5@1FA=)Y!X%+#````@")\,<%5&,)"`!B"0C'!5!C"0@` +XM````Z/O]__^A5&,)",<``````(/`!*-48PD(]D8$"'02BU,,B="`S`B)0PR` +XM?@0`>'N0QP0D`&()".B$/0(`B4-XH8!W"@B%P'1MQT,(`````*&`=PH(BT`4 +XMB4,4H8!W"@B)0P2A@'<*"(M`&(E#'(L5@'<*"(G1ZP*)PHM"!#G!=?>+#0"8 +XM"@B)6@2-0R")"XD=`)@*",=%#`````")10B#Q`Q;7E]=Z9)$_O^`S@R)4PSI +XM>____XD=@'<*"(E['(E;!*%DF0L(B4,(H629"PB#0`@"H3":"PB#^`A_+8L- +XM`)@*"(/``:,PF@L(B4,4BS4\=PH(A?9T28L5<)D+"(72=8B)'7"9"PCK@(L- +XM`)@*"+X!````ARA@)@*",=$)`S( +XMW`@(QT0D"`$```#'1"0$$0```(D$).A$'___B00DZ-P8`@"+6P0Y\W6_C5W( +XMB1PDC7VXZ&-"_O_'1"0$`@```(D<).AC/?[_QT0D!!0```")'"3H4SW^_XU% +XMV(E$)`B)7"0$QP0D`0```.CL//[_C478B00DQT0D!&`>!0CH+<#^_XM%V(E% +XMN(M%W(E%O(M%X(E%P(M%Y(E%Q,=$)`04````B3PDZ.%"_O^0C70F`.@K,`(` +XM,=N)\(VT)@`````+6`R+0`0Y\'7V]L,!=`J)/"3HI4+^_^O7C478B00DZ"R_ +XM_O^AU)<*"(7`?A")1"0$QP0D#P```.C?._[_]L-2#X3T`0``]L,"#X4E`0`` +XMNJ````")\.CEY?__]\,"(```=`Z+/91W"@B%_P^%C@$``(GR,=L/MD(0A,!T +XM$O="#!`@```/MMAT!H/(@`^VV(M2!#GR==^%VP^$@0```,=$)`3$F`H(QP0D +XMP#P)".@^)@``A7]___H>ES^_XGPZ%/@ +XM__^#Q%Q;7E]=PZ&`F`H(QT0D#+W<"`C'1"0(`@```,=$)`01````B00DZ`8< +XM__^)7"0$B00DZ)H5`@#I%?[__XGPZ`[@___I564X/L$(M=".A`W?__BT,$B=[K/L=#&``` +XM``#HJ3S^_XL`B00DZ$\Z_O^)1"0(BT-XQP0DA```$(E$)`3HC+G^_XM&!(7` +XM=#>+1@B#Q@2%P'0MB00DZ`/@___'1"0$`0```(G#B00DZ)'J__^%P'2DB1PD +XMZ%7[__^+1@2%P'7)@\006UY=PXVT)@````!5B>564X/L$(L=`)@*"(7;=%2^ +XM`)@*".L/C;0F`````(L8B<:%VW0^BTL8B=B%R77OBP.)!HM#>(D$).APQ@$` +XMBU,(A=)T#8M""(/H`H7`B4((=":)'"3H5,8!`(GPBQB)QH7;=<*A@'<*"(D$ +XM).C-^O__@\006UY=PXM#"(L0A=)UT8D$).AE>/[_Z\>-=@!5B>575E.#[&R- +XMM"8`````Z)<[_O_'``````"+-91W"@B%]@^$7@(``(L=P'8*"(7;=0Z+#?Q= +XM"0B%R0^$1@(``+@#````C56HB40D!(U%\(E4)`B)!"3H<#C^_XG"C4`!@_@! +XM#X8S`@``BS4`F`H(A?9U".N:BS:%]G24.U88D'7TBTX,B"$``(D$).CP,@(`B00DZ)0U_O\YPP^,]0`` +XM`(M'#(/(0(E'#`E%H(M_!#GW=8N+5@R)T(#D_CMV!(E&#`^$G@$``/=%H`$0 +XM```/A3S^__^)\XM##*@"=`:`S!")0PR+6P0Y\W7LBT,8.T,<=`N+6P2+0Q@[ +XM0QQU]8M]H(/G`@^$?`$``*$\=PH(A^__^)0P3'1"0(`0```,=$)`0"````B00DZ.@S +XM_O^+`X7`>!6+4P2%TG@&@\046UW#B00DZ+&Y__^+0P2%P'@(B00DZ**Y___' +XM10@U````@\046UWI,;3^_Y!5B>6#["C'1"0$Q)@*"(E=](G3B7W\B<>)=?C' +XM!"1@1@D(Z/D=``"%P`^$A@```(D<)(U=[.C6L?[_QT7P`````(D<)(E%[.BT +XM3O__ASH[<`!`.N;B1PDZ%.Q_O_'1"0$,"H("(G#B00DZ%&V_O_' +XM1"0$`````(D<).@18___B1PDB47LZ):U_O_I8?___XM%[(D$).@&+P(`HR!W +XM"@B+1>R)!"3HEL`!`,<$)#$``!#H&K/^_^E7____D(UT)@!5B>575E.![.P` +XM``"+?0B%_W1JBS70F0L(A?9T,XL=P'8*"(7;=0J+#229"PB%R70?BU4(BT(0 +XMABS7H=@H(A?9T"8MU"/9&!01T%8'$[````%M>7UW##[8!_R2%\-P( +XM".@9N/__@<3L````6UY?7<.+70B+0Q"+,(L&)?___W\]````0`^$I@\``(#F +XM!`^$*P\``(M5"(M"$(LPA?9TK(M2!/;""`^%A@(``(#F`@^%1`(``,=$)`@" +XM````QT0D!!`O"0C'!"3T+@D(Z$XE``"+50B`.@$/A90```"+30B+<1"+'L=$ +XM)`0,2`D(B1PDZ,8Q_O^%P`^%5@$``(M&!(7`#X2(!@``BP#'!"3JW`@(B40D +XM!.B1,_[_A<`/A+$!``"+3@B%R0^$8P8``(M=",<%('<*"/31"`B+0Q"+0`2) +XM!"3H]QD``(A#`<=$)`0"````BT,0B00DZ.&W__^!2P0`"```BU4(@#H!#X1L +XM____H2AW"@C'1?``````A<`/A;3^__^+1?"%P'0PBT7P@7@$`/D$"`^$50<` +XM`(M%\(%X!&#V!`@/A$4'``"+1?"!>`2@[00(#X0U!P``BT4(BW`$]\8`(``` +XM=1[WQA`````/A2H'``"+1?"%P'0+9O?&"9@/A!@'``"+50B`.@)T$X'F`00` +XM`'4+BT7PA<`/A,$*``"+10R%P'@-H5AC"0B%P`^$V`T``(M%#(E$)`2+30B) +XM#"3H]NW__X7`#X7""0``H5AC"0B%P`^%2PH``(M%"(MP!,>%'/___P$```#I +XMR@8``,=$)`3D1PD(B1PDZ%@P_O^%P'4JBU8$A=(/A!X%``"+30B!200`$``` +XMQT0D!`$```")-"3HL[;__^E`_O__QT0D!/Q'"0B)'"3H&C#^_X7`#X4&!@`` +XMBT8$A<`/A-P$``"+70B!2P0`@```QT0D!`$```")-"3H<;;__^G^_?__BT4( +XMQD`!!,=$)`0!````B30DZ%6V__^+50B!2@0`"```Z=C]___'!"0`````Z#JU +XM__^+50B+0@B)!"3HS*+^_XL=*'<*"(7;#X24_?__QP0D`````.@2M?__Z8/] +XM__^+712)'"3HPOK__XMU"(M6!.ED_?__BW4(@#X"=`^+11B)-"2)1"0$Z"#B +XM_O_'1"0$$P```,<$)`````#HS+C__\=$)`@!````QT0D!`(```"C1)D+"(D$ +XM).C++O[_QT0D!!$```#'!"0!````Z)NX___'1"0(`0```,=$)`0"````H\R7 +XM"@B)!"3HFB[^_Z',EPH(B00DZ)TT_O_'1"0$$@```,<$)`(```"CX'4)".A8 +XMN/__QT0D"`$```#'1"0$`@```*,$=@H(B00DZ%AV"@@`````BT$$ +XMBU$4@^`@"4($BT4,BUT8B10DQT0D#`````")1"0$B5PD$,=$)`@`````Z`C[ +XM___H\T_^_XMU"(U=Z(M."(M6!(M!!('BI0```(/("`G0B4$$BU48BT4,B5PD +XM#(E4)!"+=1")1"0$B0PDB70D".C%^O__BT4(BW4(BT@,BU8$BT$$@^(Y@\@$ +XM"=")002+51B+10R)5"00BW44B5PD"(E$)`2)#"2)="0,Z(KZ___I[_K__XM% +XM"(M("(7)=%"#XB`)402+10R+51B)#"3'1"0,`````(E$)`2)5"00QT0D"``` +XM``#H3_K__XM-"(M!"/9`!`%T&(M1#(72#X2B^O__]D($`745B?;HZ]7__XM= +XM"(M3#(72#X2'^O__BW4(BT8$@^`P"4($BT4,BU48QT0D#`````#'1"0(```` +XM`(E$)`2)5"00BT8,B00DZ.CY___I3?K__XM="(M+"(7)=%N#XB`)402+10R+ +XM=1B)#"3'1"0,`````(E$)`2)="00QT0D"`````#HK?G__\=$)`3$F`H(QP0D +XM]"X)".CY%@``B00DZ`$5``"%P`^4PH`[!@^4P#C"#X7[^?__BT4(BU`,A=(/ +XMA-KY__^+0`2#X#`)0@2+10R+71C'1"0,`````,=$)`@`````B40D!(E<)!") +XM%"3H0?G__^FF^?__B00DZ%2M__^#Z`&0#X5Z^?__BSTH=PH(A?\/A6SY__^+ +XM30B+01"+`(D$).B\80``A<")A2#___]T"8,X?@^$;PX``(N%(/___XD$).C+ +XM)P(`BY4@____B10DB%`20H@4(='R+1?"!>`3@H04(='"+1?"!>`30H@4(=&2+1?"! +XM>`1`M04(=%B+1?"!>`20H04(=$R+1?"!>`3PI@4(=$"+1?"!>`3PI04(=#2+ +XM1?"!>`3@GP4(="B+1?"!>`1@H`4(=!R+1?"!>`0@HP4(=!"+1?"!>`10?`4( +XM#X7J]___BUT(@#L!#X4J^?__BT7PA<`/A1_Y__^%T@^%%_G__Z'`=@H(A<`/ +XMA`KY__^)'"3H;.O__\=$)`0P*@@(B<.)!"3H.JW^_XD<).@2Y`$`B1PDZ(JL +XM_O_IV_C__Y"-="8`QT0D!'0\"0B)'"3H_"G^_X7`#X7)_O__BT8$A<`/A+[^ +XM__^+10B!2`0`(```QT0D!`$```")-"3H4[#__^G@]___BW4(@68$__?__^F\ +XM^/__BT7PA%'/___P````"AZ'8*"(7`#X4=`@`` +XM]\8`!```#X41`@``]\8``@``#X7<````BU4(BT((A<`/A.\)``"AM'8*",=$ +XM)`0`````B00DZ-JR__^AS)<*",=$)`0!````B00DZ,6R__^A!'8*",=$)`0" +XM````B00DZ+"R__^+30B+40B)R.@3]?__B<.)!"3H"24"`(D$).A!M/__B1PD +XMBL_O_'1"0$`````(D\).A'K/__A<")PP^( +XMI@H``(D\).A%J_[_QT0D!`,```")'"3H82C^_\=$)`0$````B1PDB40D".A- +XM*/[_QT0D!`````")'"3H<;+__XM%"(M0#(72#X2;!@``Z'[T__^)PXD$).AT +XM)`(`B00DZ*RS__^)'"2)Q^@"M@$`QT0D!#`J"`B)/"3HD```#'1"0$Q)@*",<$),`\"0CH0!$``(7`#X2B]/__QT0D!,28"@C' +XM!"3T+@D(Z(01``")!"3HC`\``(7`B<,/A'ST__^A@)@*",=$)`R]W`@(QT0D +XM"`(```#'1"0$$0```(D$).B="/__B5PD!(D$).@Q`@(`Z4;T__^+=0B+5@3V +XMP@%T"*-L=@H(BU8$BQWH=@H(A=MU)O;"!'0ABU40BP*)!"3H':S__XM-$(M! +XM!(D$).@/K/__BUT(BU,$]L((#X7Z\___H5AC"0B%P`^%2@0``(/B`0^%Y//_ +XM_^A%[?__D(UT)@#IU?/__^A62/[_C;8`````Z<7S__^+1?"!>`2P@04(#X6/ +XM_/__Z5_U___'1"0(`````,=$)`1@8PD(QP0D`P```.C6)?[_BUT(QP588PD( +XM`````(MS!,>%'/___P$```#I6?S__XM%#(7`>!B+/5AC"0B%_W4.BS4H=PH( +XMA?8/A"`(``"-7=B)'"3HS2K^_XD<),=$)`04````Z,TE_O^)'"3'1"0$`@`` +XM`.B])?[_C47(B5PD!(E$)`C'!"0!````Z%8E_O^AY'4)"(L5E'<*"(L-P)@* +XM"(L=Z'8*"(LUM'8*"(F%)/___Z',EPH(B94H____BQ4$=@H(B8TL____BPU$ +XMF0L(B9TP____BQW4EPH(B;4T____BS7@=0D(B84X____H?R9"PB)E3S___^+ +XM%6QC"0B)C4#___^+#6AC"0B)G43___^+'61C"0B)M4C___^+-6!C"0B)A4S_ +XM__^A6&,)"(F58/___XF=6/___XF-7/___XFU5/___Z-<8PD(QP7$=@H(```` +XM`,<%3)D+"`````"+'>A="0C'!;AV"@@`````QP51U"0@!A<`/A`T%``"%V\<% +XME'<*"``````/A!0'``#'1"0$`0```,<$)`(```#H;"C^_\=$)`0!````QP0D +XM`P```.A8*/[_BT4,A;Q__^- +XM7@2)'"3H+R/^_XDT)(E<)`2-!(4$````B40D".AX)_[_BW4(BU8$Z2WP__^A +XM!'8*"(D$).@0(_[_H?R9"PC'1"0(`````,=$)`0"````QP0D`@```*-LF0L( +XMZ,HA_O_IH?K__\=$)`@`````QT0D!&!C"0C'!"0#````Z,DA_O^+=0C'!5AC +XM"0@`````BU8$Z87[___WQ@@````/A"@"``#'!"0!````Z&"G__^+312+002) +XM!"3HCB+^_\<%?)@*"`````#I#_K__\=$)`0)````B3PDZ!.E__^#^/^)PP^% +XMR_G__^E\^?__C47(QT0D"`````")1"0$QP0D`P```.A$(?[_QP0D,````.B< +XMH?[_BX4D____BY4H____BXTL____B[4P____H^1U"0B+A33___^)%91W"@B+ +XME3C___^)#<"8"@B+C3S___^)->AV"@B+M4#___^CM'8*"(N%1/___XD5S)<* +XM"(N52/___XD-!'8*"(N-3/___XDU1)D+"(NU8/___Z/4EPH(BX5<____B17@ +XM=0D(BY58____B0W\F0L(BXU4____B35L8PD(HVAC"0BA7&,)"(D59&,)"(D- +XM8&,)"*-88PD(H4R9"PB)!"3H1:X!`*'$=@H(QP5,F0L(`````(D$).@NK@$` +XMH;AV"@C'!<1V"@@`````B00DZ!>N`0"A7)D+",<%N'8*"`````")!"3HP*?_ +XM_XMU",<%7)D+"`````")'"2)="0$Z.?;__^-1_G__\=$)`3$F`H(QP0DH$$)".@P"@``A<`/A/WW__^+ +XMA5#___^%P`^%)@(``(V%:/___XE$)`2)/"3HA"+^_X7`#XC5]___#[>%!U"0C'1"0(`````,=$)`0"````QP0D`0`` +XM`*-\F`H(Z"$?_O_IS/?___?&!`````^%S````/?&(````'0-@SW4EPH(_P^$ +XM30,``,<$)`````#HTZ3__Z%$F0L(B00DZ`(@_O_'1"0(`````,=$)`0"```` +XMQP0D`````.C&'O[_Z83V___HG"7^_XG#Z7?Z__^#/=27"@C_#X5_^___BU4( +XM]D($(`^$ +XM_O_II_;__\<$)`````#H'*3__XM=$(L#B00DZ$L?_O^+`XD$).@%I/__BT,$ +XMB00DZ/JC___IU/7__\=$)`0`````QP0D`0```.C-(O[_BT4(BW`$Z?/Z___' +XM1"0$`0```,<$)`$```#HKB+^_XM="(MS!.G+^O__Z$XA_O^+`(D$).CT'O[_ +XMB7PD!,<$)#8```")1"0(Z#2>_O_I,O7__\=$)`@`````QT0D!&!C"0C'!"0# +XM````Z*\=_O_'!5AC"0@`````Z5_Y___H^R#^_XL`B00DZ*$>_O^)?"0$QP0D +XM-@```(E$)`CHX9W^_^FR_?__C5W8B1PDZ*TB_O_'1"0$%````(D<).BM'?[_ +XMQT0D"&!C"0B)7"0$QP0D`0```.A%'?[_QP588PD(`0```.F>]___B<+'1<@` +XM````@\($QT7,`````,=%T`````"+0`2%P`^%F@```(G6QT0D!,28"@C'!"20 +XM+PD(Z*\'``")1"0$C47(B00DZ)`5`@"-7?X__^+10BS`?9`!"`/A7KX__^-="8` +XMZ4_X__^#^"\/A%W___^)UH/&!(L&AZZ7H8Q_^_XL`A<"-=@!U98M="(MS +XM!,>%'/___P$```#IA_+__P^VP(/(@.GC^/__Z&4B_O^)QNG8]___QP0D```` +XM`.B&H?__QT0D!`````#'!"3,L0@(Z%*?___I3//__XU%R(E\)`2)!"3H/A0" +XM`.EX____Z/`>_O^+`(D$).B6'/[_QT0D!+'<"`C'!"0V````B40D".C2F_[_ +XMBT4(BW`$QX4<____`0```.G[\?__C;8`````C;PG`````%6)Y8/L",<$)`$` +XM``#HNB#^_Y"0D)"0D)"0D)"0D)"058/X"8GE4XG#=A&ZSH#B=#H +XMY/___XG8NLW,S,R+#71C"0CWXHU!!,'J`XT4D@'2*=.-4S")$5M=HW1C"0C# +XMC70F`(V\)P````!5B>575E.)PX/L"(E-[.LFQT,8`0```+@!````C70F`(7` +XMBU7PB?L/E,`/ML`[1>P/A9H```"+>Q2%_P^$CP```#'`.5\0#Y3`.U7LB47P +XM=!^+0QB%P'2X@_@!="B#^/]UOC'`QT,8`````.NSC78`BT,8A12%P(E#$'0&BT$,B5@4B5D, +XMB4L4BT7PB4R'#(M!#,=`&`$```"X_____\=!&/_____I4O___XGV@\0(6UY? +XM7<.#^`%TA8/X_P^%.O___XMS#(M6&(72#X7_````BT80B7X4A<")0PQT!HM& +XM$(E8%(E>$(ES%(M%\(ETAPR+1A#'0!C_____N`$```#'1A@!````Z?'^__^# +XM^@$/A(,```"#P@$/A=_^__^+<0R+012+5A")1A2+0Q"%THE0#'0)BU80BT,0 +XMB4(4BT,0B480B7`4BT,4B7,0B484BT8,A<")0Q!T!HM&#(E8%(E>#(ES%(M% +XM\(ETAPPQP(M6#(-^&``/GL"#Z`&)0AB+1AB+5A#!Z!^)0A@QP,=&&`````#I +XM9?[__XM!#(EY%(7`B4,0=`:+00R)6!2)60R)2Q2+1?")3(<,BT$,QT`8```` +XM`#'`QT$8`````.DM_O__@_H!=$&#P@$/A1_^__^+1A")?A2%P(E##'0&BT80 +XMB5@4B5X0B7,4BT7PB72'#(M&$,=`&``````QP,=&&`````#IY_W__XM.$(M& +XM%(M1#(E!%(M##(72B5`0=`F+40R+0PR)0A2+0PR)00R)2!2+0Q2)2PR)012+ +XM01"%P(E##'0&BT$0B5@4B5D0B4L4BT7PB4R'##'`BU$,@WD8``^>P(/H`8E" +XM&(M!&(M1$,'H'XE"&#'`QT$8`````.EM_?__C;8`````C;PG`````%6)Y5=6 +XM4X/L'(M%"(M]#)")QHM`#(7`=?>+5A2%T@^$B@```(5^"'1?H91W"@B%P`^% +XM@````(L&B00DZ%"9__^)PXM&!,<$)`S="`B)1"0$Z&OS`0"#ZP%T=\<$)"@` +XM``#H>K;__XL&B00DZ*"D___'!"0I````Z&2V___'!"0*````Z%BV__^+1A"% +XMP'6!BT84.W`0=0J)QHM&%#MP$'3VB<:+5A2%T@^%=O___X/$'%M>7UW#C47P +XMB00DZ'\+`@"-1?")!"3H!)K^_^EE____BP:)!"3H-:3__^N?C78`58GE5E.# +XM[!"+70B%VP^$W````(L3@_HKB=`/A*`````Q]H/X+8G"=&WWP@```$`/A;8` +XM``"#^G\/AZT```")V3';]@25O5$)"`1U%^F:````@_I_=Q^#P03V!)6]40D( +XM!'02C02;C5Q"T(M1!/?"````0'36_O^+ +XM$^EI____BT,$,?:-2P2%P`^$6?___XG+Z4G____V!)6]40D(!&:^`0`/A57_ +XM___KO3';ZX;'!"0)```0Z*66_O_I$____U6)Y5.)TX/L!,<"`````(M(!(U0 +XM!,<``````(7)=$_WP0```$!U3(/Y?W=']@2-O5$)"`1T/8L#ZR*-M@````#W +XMP0```$!U*X/Y?Y"-="8`=R'V!(V]40D(!'07C02`@\($C41!T(D#BPJ%R772 +XMC5H$ZPB#^5V-6@1T#,<$)`@``!#H&9;^_XG8@\0$6UW#D%6)Y5=64X/L#(M% +XM#(M]"(M8#(7;="Z+-^L1C;8`````AR)5"0$ +XMB3PDZ*P5_O^%P'7<@\0,B=A;7E]=PXGVBUL,Z]*-="8`C;PG`````%6)Y8/L +XM"(M5"(M%#(72="*%P'0>B40D!(D4).B`____A6#[!C'1"0$Q)@*"(E=](EU^(G&B7W\B=>)!"3H +XM/?___X7`B<-T+87_?@Z+`XD$).A)EO__.<=^#,<$)"L``!#H*97^_XG8BW7X +XMBUWTBWW\B>Q=PXDT).A2G/__Z\E5B>53@^Q$BU4(C5W(B1UT8PD(A=)Y$8U% +XMS/?:QT7(+0```*-T8PD(B=#H4?G__Z%T8PD(QP``````B1PDZ'X.`@"#Q$1; +XM7<.0C;0F`````%6)Y5=6B<93@^P,BP")!"3H:YO__XM&!(D$).@0H@$`BTX0 +XMA +XM7UWI_/C__XM.#.O'BUX4.W,0#Y3`#[;XB4R[#.O)D(UT)@!5B>6#[!B)=?R+ +XM=0B)7?C'1"0$Q)@*"(DT).CQ_?__A<")PW00BW7\B=B+7?B)[%WI*____XDT +XM).@CF___Z^:058GE5HG&4X/L$(M:#(7;=0GK+XM;$(7;="B+2PR%R9!T#8G: +XMB?#HU?___X7`=16)="0$BT,$B00DZ,))__^%P'31B=B#Q!!;7EW#D(UT)@!5 +XMB>575E.#[`R+=0B+?0R+1@2%P'1*,=OK'(VV`````(M`!,<$)(,``!")1"0$ +XMZ%V3_O^+1@2)^NAS____AB$_O__@\,!D.OAA=MT$H/&!(M& +XM!(7`=;:#Q`Q;7E]=PXM&!(D$).CM#@(`HR!W"@CKW(VV`````%6)Y5=64X/L +XM#(M=",=$)`3$F`H(QP0DX$8)".C@_/__QT0D!,28"@C'!"2`,0D(BF5\?[_D(UT)@#'1"0$ +XMQ)@*",<$)(`Q"0CHS/K__X/X`1G`]]`A!8AW"@CKBZ'4F0L(HTQW"@CISO[_ +XM_\<%C)@*""$```#'!42:"PA>````Z1K^__^0C70F`,<%-)H+"#X```#'!8QW +XM"@@C````Z3G^__^-M"8`````Z-N5``#IR+.NL5A<`/G\`/ML")1?"+1(8,A2)>Q3'0Q@`````QT,0```` +XM`(E#"(GXQT,,`````(M5\.@O]/__BU7HB1.)50B#Q!Q;7E]=Z?LI__^)7"0$ +XMQP0D@P``$.A+C_[_Z63___^-M@````!5B>575E.#[#R+712+10B+50R+31") +XM7"+7=2+1(L$@\$! +XMB4W@A# +XM1>P!BTW@.4WL?3V+?>R%_W[MBUWLBT74BSR8ZZ;V1")UC'`@^D! +XMB4WDZQ&-6`$[7>`/C,(```"#Q@2)V#M%Y'SJBW7@,-=@"+7=2+ +XM!(N%P'0&B023@\(!@\$!.TW@=>@[5>!]%XM-U(T$D<<``````(/"`8/`!#M5 +XMX'7O@V7,GXM=S(M%T(M5U(M-V(E=%(E%$(E5#(E-"(/$/%M>7UWI=/W__XD4 +XM).B,*/__A<`/A)[^__^)1"0$BT74B00DZ#4\__^%P(G#=':+3=2)#"3H5)3_ +XM_XE=U.EV_O__B3PDZ/2:`0"+5=S'`@````#I__[__XE=\(EUZ(M^_(7_=!F+ +XM5>B+`H7`=!")?"0$B00DZ#`-_O^%P'06@T7P`8M-X(-%Z`0Y3?`/C03____K +XMRHD\).BBF@$`QT;\`````.O9BU74B10DZ-Z3___'!"0Q```0Z!*-_O_I;O__ +XM_XVV`````(V\)P````!5B>6#[!C'!"0(````Z"Z;`0"+50S'0`0`````B1"+ +XM51")1"0$BT4(QT0D",28"@B)5"0,B00DZ(3]___)PXGV58GE@^P8BT4,B5WT +XMB77XBW40B7W\BWT(B00DZ%`&`@#'1"0$,"H("(G#B00DZ'Z/_O^)="0(B5PD +XM!(D\).A^____B1PDZ!:/_O^+=?B)70B+??R+7?2)[%WILH[^_XGV58GE@^P8 +XMBT4(QT0D"`(```#'1"0$^&\)"(D$).A_____R<.-M@````"-O"<`````58GE +XM5XG'5E.#[!S'1"0$E#()"(D$).CQ"_[_A<`/A=,```#'1"0$Q)@*",<$))0R +XM"0CHZ?7__X7`#X1/`0``BP"-=>C'1>@`````QT7L`````,=%\`````"%P'1+ +XMBQ"%TG1%B7UW#QT0D!``_"0B)/"3H!@O^_X7`=2C'1"0$Q)@* +XM"(D\).AF]?__BQ")%8R8"@B+0`2C1)H+"(/$'%M>7UW#QT0D!$`_"0B)/"3H +XMR@K^_X7`="#'1"0$@#\)"(D\).BV"O[_A#^G]W4O8$E;U1"0@$=$BA<&,)"(/!!(T$@(U$0M"C<&,) +XM"'7-H7!C"0B%P`^/T?O__^LMQT0D!&!`"0B)/"3HH0;^_X7`=2C'!6QW"@@! +XM````Z:S[___'!7!C"0@`````QP5P8PD(&@```.F3^___QT0D!``V"0B)/"3H +XM90;^_X7`=0KHX$G^_^EU^___QT0D!.!&"0B)/"3H1P;^_X7`=0SHTBH``(GV +XMZ57[___'1"0$H$D)"(D\).@G!O[_A@#BP``C78`Z97Z___'1"0$P#0)"(D\).AG!?[_AA"Y?[_B?;H +XM&^;^_^EP^O__QT0D!,P^"0B)/"3H0@7^_X7`#X58^O__QP7T8`D(`0```.E) +XM^O__ZPV0D)"0D)"0D)"0D)"058GE5E.#[!"+10B+<`2%]G1.B30DZ-:&___' +XM1"0$Q)@*"(DT).@&[___A<")PW0WBP"%P'0QBP"%P'0[QT0D!`$```"+`XD$ +XM).A2B___@\00B?!;7EWIM?C__Y"-="8`OB0V"0CKLXDT).@1C/__BP.+`(7` +XM=<7'!"0*```0Z+V$_O_KMXUT)@"-O"<`````58GE@^PXB5WT@_@]C5W4B7W\ +XMB<^)=?B)7?`/A(````"+"H7)=6"-3=B)WHU5W(U=Z(/X/(E%Z,=%[`````") +XM'G12@_@^=$V).8U%\,<"`````(D$).A&U/[_B<.+1?"+`(7`=`S'!"0A```0 +XMZ#^$_O^)'"3H)^___XM=](MU^(M]_(GL7<.)5=2-==B-3=R-5>#KFHD9B=&# +XMP@3KJHUV`(U5V(G9ZZ")]HV\)P````!5B>6#[!B)=?R)UHE=^(L8A=MT((D$ +XM).B4_0$`BQ:)PXU"_(D&BT+\B00DZ$"1`0"+!HD8B30DZ+33_O^)!"3HK.[_ +XM_XM=^(MU_(GL7<.)]E6)Y8/L&(E=](G3B7W\B77XB4WPZ"?N___V0`@!B<=T +XM$XM`!,<$)(,``!")1"0$Z'R#_O^+!\'C`HMT`_S'1"0$,"H("(DT).A3AO[_ +XMBP?'1"0$`@```(/H!`'#BT7PB00DZ`DS__^)`XDT).B/A?[_BUWTBW7XBWW\ +XMB>Q=PXGV58GE5U93@^P\BT4(@\`$B44(BQ"#P`2)10B%THE5S`^%2@$``.GS +XM`@``C;8`````BT4(BQB%VP^$=`,``(/`!(E%"(L[A?\/A8,!``#'!"0E```0 +XMZ->"_O^-M"8`````BP.%P'4-BT4(BP"%P`^$5P,``(M%S(D$).AB_`$`QT0D +XM!#`J"`B)1=")!"3HCX7^_X/_/0^$0@(``(LSC5,$B57@QP0DZMP("(ET)`3H +XM7H/__X7`#X1S`@``.?YU!XM#!(7`=`S'!"0F```0Z%^"_O_'!"08+PD(Z`/\ +XM`0")P\=$)`0P*@@(B1PDZ#&%_O^+==2%]@^$A@$``(M5\(M%T.B[[/__B=F+ +XM$(M%\(M4@OR)^.AI_?__QT0D!#`J"`B)PXD$).CWA/[_BU7PB=F+1=#H2O[_ +XM_XD<).B2A/[_B1PDZ#J$_O^+1=#HLO7__XM-T(D,).@GA/[_BT4(BQ"%THE5 +XMS`^$O`$``(/`!(E%"(M-S(LY]\<```!`=2F)^`^VP#W_````B478#X?U`0`` +XMH>!="0B+5=B+1)`T]L0!=4"#_U]T.XMUS,<$)!T``!#H?('^_XL^QT74```` +XM`(/_6P^$H````(7_B?,/A&#^___'`P````"#PP3I@O[__XGVBPW@70D(B?N+ +XM=7UW#B7PD!,<$)-3'"`CHTX#__X7`="`Y_G00QP0D)@``$(UT)@#H +XMVW_^_\<$)````!#HSW_^_X/^/70,QP0D)@``$.B^?_[_BT7@C54(Z+/[__^) +XMP^E;_?__B00DZ+#__?^-="8`Z0;^__^+3=#'1"0(`@```(E<)`2)#"3HA/+_ +XM_^E?____B?/IE?S__XM-V(D,)(GVZ'?__?_I>/[__\<$)"4``!#H6G_^_^F8 +XM_/__D(UT)@!5B>575E.#[$R+10B+>`2-<`3'1=P"````QT7(`````,=%S``` +XM``"%_P^$?@```)")/"3'1"0$2#0)".CL_OW_B?HQ_X7`=1B#Q@2+%H72#X2' +XM````QT7<`0```&:_`0#'1"0$H#@)"(D4).B\_OW_"T7,=6.#Q@2+'L=%R`$` +XM``"%VXG:=""_`0```,=$)`2L.`D(B1PDZ)#^_?\+1"-M"8`````BP_WP0`` +XM`$")3=AU,`^VP3W_````B470#X>``@``H>!="0B+5="+1)`T]L0!#X7S```` +XM@WW87P^$Z0```(G^QP0D'0``$.@%?O[_BP8QVX/X6P^$_0$``(7`#X18`0`` +XMQP8`````@\8$BQ:%TG42BTW@BQ&%TG0)@SHH#X1,`@``@_@]#X4R`@``QT0D +XM!%`["0B)-"3HDOW]_X7`#X70````A=L/A0$"``"+7>"-=@#K`X/#!(LSA?8/ +XMA#P!``"#/BEU[L<#`````(M%X(D$).@KB?__BTW(A")^.@2\?__BT7@BSB% +XM_P^$I?[__X/`!(E%X.G:_O__BPW@70D(B?Z+7=B)3=3K)HM5U(M$@C3VQ`5U +XM"8/[7P^%RP```(/&!(L>]\,```!`#X6Z````#[;#/?\```!VT(D$).CN_/W_ +XMB?;KRX7;#X3P````B30DC78`Z'OV`0#'1"0$,"H("(G#B00DZ*E__O^+5?") +XMV8GXZ/WX__^)'"3H17_^_XD<).CM?O[_Z4____^+5>"+`H7`#X3%_O__QT0D +XM!#@["0B)!"3H5_S]_X7`#X6M_O__@T7@!(M-X(L!A<`/A)S^__^#P02)QHE- +XMX.F/_O__QT0D!"D```#'!"0R```0Z$%\_O^+,^FI_O__.?O````BU70BTW4BT21-/;$`0^%#?[__X-]V%\/A??]__^+!C';@_A; +XM#X4#_O__B?"S`8U5\.A/Y?__B<:+`.GN_?__B30DZ([U`0"+3<2)/"2)3"0( +XMB40D!.C+[O__Z7W^__^+5#I +XMI_W__XM-T(D,).AW^_W_Z4O___^0D)"0D)")P8L"50$!B>6+000#0@0]/T(/ +XM`(E!!'X*@P$!@6D$0$(/`%W#C70F`(V\)P````!5B>56BW4,4XM="(GRB=CH +XMO/___XU#"(U6".BQ____BT80.T,0?@.)0Q"+1A0!0Q2+1A@!0QB+1AP!0QR+ +XM1B`!0R"+1B0!0R2+1B@!0RB+1BP!0RR+1C`!0S"+1C0!0S2+1C@!0SB+1CP! +XM0SR+1D`!0T"+1D0!0T1;7EW#C70F`%6)Y8M5#(M-$%.+70B+`BL!B0.+0@0K +XM002%P(E#!'D*@RL!@4,$0$(/`%M=PXUV`%6)Y8/L*(E$)`2-1?B)5"0(B00D +XMZ+?___^+3?RZTTUB$,<$)!#="`B)R/?JBT7XP?D?P?H&*") +XM5=R+3@R)3="+0`PIP8G(]^^)3=#!?=`?BT8$B=&+5>#!^0PK3=")1="+4@0I +XMT(E%T/?OP7W0'XL&`T8(P?H,*U70C101BTW@*P$K00AKP&0!PHE5Y,=$)`3$ +XMF`H(QP0D=#P)".B9X___BU7AT'8L!AEDE___ +XMC70F`(/H1#PS=RD/ML#_)(54W0@(BTW@BT9`*T%`C;8`````B40D!,<$)";= +XM"`CH$-0!``^V0P&->P'KG8M-Y#'`AB->P&)!"3HAYG__P^V0P'I9/___XM5X(M&)"M").NCBU7@BT8L +XM*T(LZYB+5>0QP(72=(^+3>"+5A0#5AP#5A@K41PK410K41B)T,'Z'_=]Y.EM +XM____BU80B=#!Z!\!T-'XZ5S___^+3>"+1C`K03#I3O___XM5Z#'),<"%TG1# +XMVT7DNF=F9F;8#23>"`C9??(/MT7RVT7HWOFT#&:)1?#9;?#;7>S9;?*+3>R) +XMR/?JBP&)3"0(QP0D&MT(".@)TP$` +XM#[9#`>F6_O__BTW@BT8@*T$@Z=+^__^+1=2->P&+5=CH)/W__P^V0P'I"+1B@K0BCIE_[__XM]Y#'`A?\/ +XMA(K^__^+3>"+5A0K412)T,'Z'_=]Y.ET_O__BU7@BT9$*T)$Z6;^__^+5>"+ +XM1CPK0CSI6/[__XM5X(M&."M"..E*_O__BTW@BT8T*T$TZ3S^__^-M@````"- +XMOP````!5B>53@^P4BT4(BU@$C5`$N`0```"%VW0)BT($ARX````B5WXC5VH +XMB77\C;5@____B5PD!,<$)`````#H9/K]_XET)`3'!"3_____Z%3Z_?^)="0$ +XMC77PB1PDZ/GZ__^)-"3'1"0$`````.A%]_W_B70D"(E<)`3'1"0,J)D+",<$ +XM)"!V"@CHS?O__XM=^(MU_(GL7<.-=@!5B>53@^QDC5VTQT0D!`````#'!"2H +XMF0L(Z/[V_?_'1"0$('8*",<$)`````#HVOG]_XE<)`3'!"3_____Z,KY_?^) +XM7"0$QP0D('8*".AN^O__@\1D6UW#D)"0D)"0D)!5B>575E.#[`R+50B+0A"% +XMP'1(B=&+4@B+.87_="N-')`Q]NL#@\,$BP.%P'0.B00DZ,J"`0#'`P````"# +XMQ@$Y_G7BBU4(BT(0B00DZ*^"`0"+30C'01``````@\0,6UY?7<.-M@````"- +XMO"<`````58GE5U:)SE.)TX/L+(/Y!HE%X'8%O@8```"-?>Z-##>)^NL&@\(! +XM@\,".)7?2)=?B)1>R+0@@#`HT$A0@```") +XM1"0$BT(0B00DZ"&#`0")1?"+1Q"%P'0\BQ^+1?"+5>R)WH/#`0-W"(E'$(D4 +XM)(TTL.AY?___B0:+1?")'P-?",<$F`````"+7?2+=?B+??R)[%W#BT<(A*V+5?`QR8/!`<="_`````"#Z@0YR'7OP>`"*47P +XMZX^-M@````!5B>6+10R+`(E%#(M%"(L`B44(7>GC]?W_C;0F`````%4QP(GE +XM5E.#[""+70B+=0PY\W1=BU40A=)T78'[_P````^'Z0```*'@70D(BYR8-`0` +XM`('^_P````^'P0```*'@70D(B[2P-`0``(U%Z(E$)`2-1?")7?")=>C'1>P` +XM````QT7T`````(D$).@[]_W_@\0@6UY=PX'[_P```'=PH>!="0B+1)@T]L00 +XM=!N!_O\```!W2J'@70D(BU2P-&:%TK@!````>,B!^_\```!W;Z'@70D(BT28 +XM-&:%P'F,@?[_````=V.AX%T)"(M4L#2`YA"X_____P^$;?___^N1B30DZ!3S +XM_?^)PNNSC70F`(D<).@$\_W_ZX^-M@````")-"3H!/7]_XG&Z3S___^0B1PD +XMZ/3T_?^)P^D4____D(D<).C4\OW_ZY")-"3HRO+]_XG"ZYJ-=@"-O"<````` +XM58GE5U:)QE.)TX/L+#G*B4W8R)!"3H\.\!`&:!_S^`B47@="QF@?];@`^$@````&:!_RJ` +XM="F+1>P[1?!U%P-UX#E=V'>H,<"`/@`/E,#K5X`^`'7I@\0L,"-1>S'1"0(!@```(ET)`2)!"3H@>\!`(E%X(M% +XM"(G:B00DBTW8B?#H//___X7`=,BX`0```(/$+%M>7UW#@#X`=*$/MQ,/M\([ +XM10@/E,`/MOB%_P^%P@```,=%W`````#K"8VV``````^W$V:!^EV`#X2"```` +XMB=JY!@```(U%\.AS_/__C1Q#9H$[+8!T$8M%\#M%['71QT7<`0```.O(@\," +XMN08```")VHU%Z.A&_/__QT0D"`````"-'$.+1>R)1"0$BT7PB00DZ%G]__^% +XMP'^5QT0D"`````"+1>B)1"0$BT7LB00DZ#O]__^%P`^/<____^N@D+D&```` +XMB=J-1?#H\?O__SE]W`^$T_[__P-UX(T<0^FT_O__@\,"#[<3Z3/___^)]E6) +XMY5=6B<93@>R\````B95<____B8U8____#[<"ZQ60A?\/A1(!``!F@_@O=%2) +XMG5S___]FAHM6!&:#^"^)E6#___]T0#'_9H7`BYU<____>"4/OL"#PP*) +XM1"0$B30DZ"GG`0`/MP-FA8!`(N57/___P^W`F:#^"]TVF:%P'6&C5V( +XMB30DZ#+G`0")7"0$BP:)!"3H8._]_\=%A`````"%P'55BX58____]D`,"'0K +XMBQ:+1@2`?!#_+W0?#[=%D"4`\```/0!````/A,7UW#BX5@ +XM____B48$BY58____BT(,)0`0``"#^`$9P(/@PV8MHG]FB85H____B30DZ(3F +XM`0#H>_+]_\<``````(L&@#@`#X7&````QP0DDAT)".C>\?W_B<>%_P^$P@`` +XM`(M6!`^WA6C____'180`````B95D____B854____B3PDZ!_U_?^%P'1Q@'@( +XM+G4,BY5<____9H,Z+G7BBY5D____@\`(B58$B40D!(DT).CUYP$`B30DZ/WE +XM`0"+E53___^)V8N%9/___P,&B10DBY5<____Z"_\__\Y10ATGXM%"(G:B00D +XMBXU8____B?#HU?W__X7`B46$=(.)/"3H,O7]_XM%A('$O````%M>7UW#B00D +XMZ!SQ_?^)QX7_#X4^____BY58____BUH4A=MT(NB`\?W_BP")1"0$BP:)!"3_ +XMTX7`=`S'183^____Z:/^__^+A5C____'180`````]D`,!`^$C/[__^O;B5PD +XM!(D4).BN\/W_A<`/A5C^__\/MT60)0#P```]`$````^%1/[__\=$)`0O```` +XMB30DZ+;D`0")-"3H#N4!`.DG_O__B?:-O"<`````58GE5U93@^QLBT4(]D4, +XM`8E%O'4:BU44QP(`````QT(0`````/9%#`(/A`P#``"+10R+?12`Y/Z)1PR+ +XM11")1Q2+!XE%I(M'#,='!``````E`!```(/X`1G2@^+#9H'JHG^#^`&+10@9 +XM_X/GPX/'7F:)5:B)?<")!"3HS?/]_XU$``*)!"3HM7L!`(M5"(E%Q`^V.HGX +XM#[;(,<`[3<`/E,"%P(E%R'02@\(!B56\BU4(#[9Z`8GX#[;(BU4,@>(`(``` +XMB56@#X0!`@``B?J+7<2$T@^$F````(VT)@````")^HM%O`^VTHE5T(M5O,=$ +XM)`0&````@\`!B474B10DZ%CM_?^#^/^)Q@^$`@$``(/X`0^.#0$```^W?="- +XM0P(QTHU._V:).XE%S(VV`````(M]O`^V1#H!@,Q`9HE$4P*#P@$YRG7IBT74 +XMBU7,C40P_XU4`````` +XMQT7D`````&:#.@`/A0P"``"+512+`CM%I`^$-0(``/9%#"`/A/\```"+1<0Q +XMVXD$).AI>0$`@\1LB=A;7E]=P\=$)`0`````QP0D`````.@W[/W_B?@\7`^$ +XM&`$```^W?=!FB3N#PP*)7_XJ@`^$ +XM)/___V;'`RJ`@\,"Z1?___\/MP$/M_@[?NGB?B+7<2$P`^$E_[__XM5O(M= +XMQ&:)"P^V0@&#PP*#P@&$P`^VR'7LZ7C^__\Y1:0/A/C^__^+510K1:3'1"0, +XML*@&"(M]%,=$)`@$````B40D!(M2"`%5I(M%I,'@`@-'$(D$).CVZ?W_Z;_^ +XM___'0@@`````Z>C\__^+5=0/M@*#P@&)5=2$P`^$YP````^VP(#,0&:)`X/# +XM`HE=S.GL_?__A=(/A![___^+112-4P*!2`P``0``9L<#6X`[?<`/A-<````/ +XMMP'K"V:#^%UT1`^WP(G.9B7_`&:)`@^W!H/"`HU.`F:#^"UUWP^W7@*-3@)F +XM@_M==-@/ML-FQP(M@(U.!F:)0@(/MT8$@\($9H/X776\C5H"9L<"78#IDOW_ +XM_XM]R(U%W(M-%(D\).@1^?__B<.+1=R)!"3H9'+]___V10P0="6+3:"%R75'BU44BT4(Z`/U___IN/W__X-MU`&X +XM7$```.D1____]T4,``(```^$D_W___9"#0$/A8G]___KP@^W5:AFB5,"C5,$ +XMZ1G___^+?0B)/"3HR._]_X/``8D$).BQ=P$`#[87A-*)PXG!="J)^.L2#[80 +XM@\`!B!$/MA"#P0&$TG04@/I<=>F#P`$/MA"$TG7B@^@!Z]K&`0"+512)V.AO +XM]/__B1PDZ)=V`0#I'/W__Y"058GE5U93@>RL`@``BU4(BP*#^"`/A/8!``"- +XMM@````"#^`D/A.W'`@````"+A5C]__^+$(72#X1C`0``QT0D!)1V"@C' +XM!"3@00D(Z&/2__^%P`^$>0$``(L5+)H+"*$HF@L(B960_?__BQ4DF@L(B86, +XM_?__H2":"PB)E8C]__^+%1R:"PB)A83]__^A&)H+"(F5@/W__XL5%)H+"(F% +XM?/W__Z$0F@L(B95X_?__BQ4,F@L(B85T_?__H0B:"PB)E7#]__^+%02:"PB) +XMA6S]__^A`)H+"(F5:/W__XF%9/W__^@L9_[_QP0D`)H+"(F%7/W__^C&Z/W_ +XMA<`/A"@#``"+A5S]__^)!"3HM&G^_XN5D/W__XN%C/W__XD5+)H+"(N5B/W_ +XM_Z,HF@L(BX6$_?__B14DF@L(BY6`_?__HR":"PB+A7S]__^)%1R:"PB+E7C] +XM__^C&)H+"(N%=/W__XD5%)H+"(N5`0"+A5C]__^-5>B)%"2)1"0$Z!S>`0"+ +XM7>RX0]X(".L4B?:+!+7`W@@(@\8!A<`/A%?___^)7>R)!"3HL^,!`(E$)`2- +XM1>B)!"3HY-T!`(U5Z(D4).C)VP$`BT7HB00DZ%[A`0#'1"0$`````(D$).B^ +XM:/__H]PD"0B#P`%TI(U=L,=$)`1`'@4(C768QP0DW"0)".A*:/[_C46@QT68 +XMP+@&"(D$).@DZOW_B5PD",=%G`````")="0$QP0D`@```.@)Z?W_B1PDC5W8 +XMQT0D!)`>!0CH"FC^_XU%R(E<)`B)1"0$QP0D`@```.B?Y/W_B1PDC9V8_?__ +XMQT0D!&`>!0CHW6?^_^L5B40D"*',EPH(B5PD!(D$).@F9___H=PD"0C'1"0( +XM``(``(E<)`2)!"3HK6?__X7`?\['!"3<)`D(Z/UF_O_I?OW__X/X.@^%4_[_ +XM_^EA_O__BY58_?__QT0D!.!!"0C'!"0"````B50D".A\FP$`Z;7\__^+E5C] +XM___IS_O__\<"+@```(N%8/W__\=`!`````#I)/[__\<$)%3>"`CH2.(!`.F" +XM_?__H8"8"@C'1"0,+MX(",=$)`@!````QT0D!!T```")!"3HOL7^_XN56/W_ +XM_XE4)`2)!"3H3+\!`.G=_/__C;0F`````%6)Y8/L"*'<)`D(@_C_=`B)!"3H +XM2&G__\<%W"0)"/_____)PY"0D)"0D)"0D)"0D(G"58GEHXAC"0B+0@R%P'0) +XMB<*+0@R%P'7WBTH4A&,)"(M">(E$)`2+10B)!"3H3=L!`+@! +XM````@P5X8PD(`8/$$%M>7<.#P0$Y\7ZSB0UX8PD(@\00,&,)"#'`@\006UY=PXD5>&,)"`^V`83`=!R)RP^^P(E$)`2) +XM-"3H,=8!``^V0P&#PP&$P'7F@P5X8PD(`8/$$%NX`0```%Y=PXUV`%6)Y593 +XM@^P0H8!C"0B+=0B%P'0]BU`$A=)T-@^V`H3`=!R)TP^^P(E$)`2)-"3HW=4! +XM``^V0P&#PP&$P'7F@P6`8PD($(/$$%NX`0```%Y=PX/$$#'`6UY=PXVV```` +XM`%6)Y593@^P0H81C"0B+=0B%P'0\BQ"%TG0V#[8"A,!T'(G3#[[`B40D!(DT +XM).A^U0$`#[9#`8/#`83`=>:#!81C"0@,@\006[@!````7EW#@\00,6#[!B)7?2+71")=?B+ +XM=0R)??R+#8AC"0B+?0B%R704B5PD"(ET)`2)/"3H_OO__X7`=2J+%8QC"0@Q +XMP(72=!Z)71"+7?2)=0R+=?B)?0B+??R)[%WI-/___XUT)@"+7?2+=?B+??R) +XM[%W#C78`58GE@^P(BT4(A<"C?&,)"'0(B00DZ"+B_?_'1"0$Q)@*"(M%#(D$ +XM).ACR/__A<"CB&,)"'0:BP#'!8AC"0@`````HXQC"0C)PXVT)@````#'!8QC +XM"0@`````R<.-="8`58GE@^P(BT4(A<"C?&,)"'0(B00DZ,+A_?_'1"0$Q)@* +XM",<$)-PX"0CH`LC__X7`=`>+`*.,8PD(R<.0C70F`%6)Y8/L&(E]_(L]D&,) +XM"(E=](EU^(7_=#F+70B%VW0RH9AC"0B%P(E%\'0F,?:)]HLQ=PXVV```` +XM`(V\)P````!5B>57B==64XG#@^P,BT`0.T,(#X:2````B?@#0PPY0Q1V(HM# +XM#(M+"(L3P>`"`T,$B02*@\$!`7L,B4L(@\0,6UY?7<.+`"B40D!(L#B00DZ%1K`0#'!"3$K`L(B0/HIM`! +XM`.DZ____D%6XD&,)"(GE4X/L%(M="(M3!(/"`>@&____BQ.)5"0$B00DZ!3< +XM_?^#Q!1;7<.)]E6)Y5.)PX/L!(,%Q*P+"`&+`(7`=!R)!"3HTFD!`,<#```` +XM`,=#"`````#'0Q``````BT,$A575E.#[`R+10B+%7QC"0B+=0R+71")1?#HD/___X7`B<8` +XM``#V`Q`/A-T```"A?&,)"(7`="6#!<2L"P@!B00DZ,5?___'!7QC"0@````` +XMQP0DQ*P+".A_S@$`H8QC"0B%P`^$D0```(L`ASP$`B30DZ#;0`0"+1?"+%7QC"0B#Q`Q;7E]=Z;'^__^+#7QC"0B%R76G +XMC;0F`````(/$#(GX6UY?7<.-M@````!5B>575C'V4X/L#(L-R&,)"#L-L&,) +XM"(M]#`^",@$``(L5T&,)"(72=!*+10CH7O[__X7`B<8/A4(!``"AS&,)"(L8 +XMA=L/A#,!``"+%=!C"0B%TG0P@P7$K`L(`8D4).B,7O__QP708PD(`````,<$ +XM),2L"PCH1LT!`*',8PD(BQB%VW2;@SLO=`OK(8UT)@"#.R]U$X/`!(L8A=MU +XM\J/,8PD(Z7C___^CS&,)"(M%"(E<)`2)!"3H5-$!`,='!`````"+`X7`=`R# +XM^"YU.HM;!(7;=3/'!"22'0D(Z&O;_?^CT&,)"(M%$,<`$0```(D\)+X!```` +XMZ`3/`0"#!DSW_W_C;0F`````%6)Y5.#[!2#!<2L +XM"P@!Z!G;_?_'``````#K)9"-="8`Z`?;_?^#.`1U48VV`````.@;RP$`Z/+: +XM_?_'``````#H9]C]_X7`B<-TU<<$),2L"PCHRD,V_W_58GE7>G3V_W_C;0F```` +XM`%6)Y5.#[!2#!<2L"P@!Z)G=_?_'!"3$K`L(B53B<.#[!2)!"3H>]?]_XU0`KBH +XM8PD(Z%+Y__^)7"0$B00DZ&+6_?^#Q!1;7<-5B>575E.#["R+10B%P*-\8PD( +XM=`B)!"3H3]K]__8%P&,)"`$/A"4!``#V!#2"`AV,KOPT@@(BT/PA`$@\,0!>#2"`@YT'?3H#R`2C +XMP&,)"/8%P&,)"`@/A!\"``"AT&,)",<%R&,)"`````"%P'0E@P7$K`L(`8D$ +XM).@C6___QP708PD(`````,<$),2L"PCHW+0Q2%P'0HBT,$ABR_O__BT,0 +XMA:)%"3HUM`!`(D$).AZU_W_A<") +XM1>1TUHD$),=$)`0P'@4(Z-=7_O^+1=R%P'0EQT0D!+@X"0B+!XD$).CNS0$` +XMB47@QT0D!#`J"`B)!"3HJU?^_XM=Y(D<).BP`````QT7H`````(E=\.L' +XM@T7L`8EUZ(MUZ(/&`3MU\'-"BQVH8PD(C02U_/___XL\`XM$`P2)/"2)1"0$ +XMZ&K3_?^%P'3*BT7LAPI7?"+1?#'!"3$K`L( +XMH[!C"0CH'\57 +XM5E.#[`R+-<1C"0B%]G1_BP:%P'1YBSW@70D(ZQB+1(7UW#D)"0D%6)Y5=6 +XM4XM-"(M]#(LQA?9T0XL?ZP^+<02#QP2%]G0UBQ^#P02)\HG8@>+___\_)?__ +XM_S\YPG3>A=NX`0```'0;B?"!X____S\E____/RG86UY?7<.#/P$9P/?06UY? +XM753BTT(BUT,BU40BP&%P'0S@^H!A=)_"^LJ +XMC70F`(/J`70A@\$$BP&%P'7R@^H!A=)_&,53BUT(BTT,BU40ZP>0@\,$@\$$ +XM@^H!=`N+`87`B0-U[5M=P\<#`````%M=PY!5B>575E.#[`R+10B)!"3HJ-'] +XM_XLUT)<*"(7VB47P=%^+'H7;=%F)Q\'G`NL-B?:#Q@1T2XL>A=MT18D<).AY +XMT?W_.47P=^B-!#N#.#UUX,<``````(M%"(E$)`2+!HD$).B9_O__BQ;'!!<] +XM````A6+10R+`(E% +XM#(M%"(L`B44(7>F'=0$`C;0F`````%6)Y5=64X/L'(MU"(M]##G^#X*S```` +XMB?(QR9"-="8`,<"#.F`/E,"#Z@0!P3G7=N^#X0''1>P()0D(=0?'1>P,)0D( +XMQT7P`````.L*C78`@^X$.?=W18L>A=MT\XE<)`2+1>R)!"3H0-3]_X7`=#F# +XM?OQ@^X$.?=VN[@! +XM````@\0<6UY?7<.)7"0$QP0D["0)".CST_W_A<`/A(4```#'1?`!````ZX8Y +XM]XUT)@!SRHL&@_@F=$J#^"AUOH/N!(L6@_H@=`6#^@EU!#GW7UW#@WWP`0^%`/___S'` +XMZ4K___\/ML+VA`#A(`D(('2CZ3/___^-M"8`````58GE5E.#['"%P'17<.# +XMQ'`QP%M>757B<=64X/L;(7`B560=%['1"0$ +XMQ)@*",<$)`PR"0CH6KC__X7`=%6+`(7`=$^+&(7;=$F)QNL@C;8`````B5PD +XM!(D\).AD!/__A!(/&!(7;="7'1"0$A#,)"(D<).@"SOW_A7UW#BT60B3PDB40D!.@BQP$`B<.)!"3HR,D!`(D<)(U= +XME(G&Z%M;`0")7"0$B30DZ!O-_?^#P`%TN@^W39R)R"4`\```/0"@``!T1#T` +XMP```NCT```!TH3T`$```LGQTF#T`(```LB5TCST`8```LB-TACT`0```LB\/ +XMA'G___^#X4FR*@^%;O___^ED____QT0D!,28"@C'!"3@0@D(Z&"W__^%P'0P +XMB5PD!(DT).C,S_W_NB8```"#P`$/A#?___\/MT6````(D$).C_T/W_A<`/E<`/ML")1>2+3<0Q_X7)?DN+5<@Q]HL" +XMB00DZ!"=`0"+7-1@$Y1<2)QHT4@7X=BP*)TXD$ +XM).CEG`$`C5,$.?AST8U&`3E%Q(G&?^.#?<`!&<`QTO?0C7P'`J'@EPH(B7WP +XM]_>%P(G#=".+%>AV"@BX`0```(72#X3%`0``B00DZ,?1_?^%P`^%I0$``,=% +XMX`$```#'1>@`````BU7H`U7$QT78_____\=%W`````")T,'Z'_=]X(7`B46\ +XM#XX>`0``BT7@,?^+3=R%P(E-['\NZ>4```"#1=@!BTW$.4W8?#*+1>2%P`^% +XMS@```(M%O(/'`0%%[#M]X`^$O````(M%Y(7`=="+5>R+3<2)5=@Y3=A]SHM5 +XMR(M%V(T$@HE%T(L8B1PDZ"+,_?^)QHM%P(7`#X2_````C12U`````(U$$_R) +XM5=2+&,<``````(U&_XE$)`2)7"0(BTW0BP&)!"3HNTH``(M5T(M-U(L"B5P! +XM_#';.WWH#XUQ____BTW0BP&)!"3HEYL!`(T<&#E=\`^&6/___\<$)"````"# +XMPP'H?&G__SM=\'7LBT6\@\-M"8`````@_HD="N#P`2)10B)5"0$B1PDZ.F_`0"+10B+ +XM$(72=>")'"3H^+\!`(/$)%M=PXGVC44(QT0D"````$")1"0$B1PDZ%FF`0"% +XMP'6EBT7PB00DZ$I7`0"#Q"0QP%M=PXGV58GE5U93,=N#["R)5>B)3>2)1>R) +XM!"3H5/___XE%\,=$)`0P*@@(B00DZ)%,_O^+??"%_P^$!@$``(M%Z,=`!``` +XM``"+5?"+`H/X/0^$KP$``(/X?@^$&0$``(M-\(E,)`2+1>B)!"3HH\$!`(M5 +XMZ(D4).B(OP$`BTWHNHPS"0BAV)<*"(MQ!(7V=`6+3>B+$8/H`H/X`0^6P`^V +XMP(E$)`2)%"3HIQS^_X7`B<,/A(T```")!"3HY<0!`(D$).B)R_W_BU7DA<") +XM`G1TBU7PB10DZ$E+_O^+3>R+,87V=#J+1>B+4`2%TG0/B<&+`(-\D/PO#X1\ +XM`0``BU7HQT($`````(E<)`2)%"3H`<$!`(M%Z(D$).CFO@$`B1PDZ!Y6`0"# +XMQ"PQP%M>7UW#BT7H,=N)!"3HQ[X!`(VT)@````")'"3H^%4!`(-]"`9T#HL= +XMY&,)"(7;#X16`0``BTWPB0PDZ+E*_O^X_O___X/$+%M>7UW#BTWP@\($BT$$ +XMA<`/A.<```"#^"^)U@^$W````(/&!(L&A<`/A:,```")\"G0P?@"B10DB40D +XM!.@PP@$`B<.)!"3HAM']_XD<)(G'Z'Q5`0"%_P^$8/___XE\)`2+1>B)!"3H +XM-<`!`(D\).A=50$`BU7HBP*#."]T:(ET)`2+3>B)#"3H%,`!`.EL_O__BT7P +XMB00DZ,3Q_O^%P(G##X06____.47P#X0\_O__B40D!(M5Z(D4).CBOP$`B1PD +XMZ`I5`0#I,O[__Y"-="8`@_@O#X5'____C;0F`````.E(____@WH$`8VT)@`` +XM``!UBX,^+W6&@\8$ZX&)UC'`Z2_____'000`````B0PDB5PD!.B(OP$`BT7H +XMBU`$B<&+`(-\D/PO#X1R_O__QT0D!"\```")#"3H\[P!`.E=_O__Z!7*_?^# +XM.!2-M@`````/A(D```#H`S' +XM!"3OW@@(B4PD!.COH0$`BT7PQP6PF0L(`0```(D$).CJ2/[_N/_____I+/[_ +XM_XM]\(7_=,.+5?")5>SKNZ&`F`H(QT0D#-3>"`C'1"0("@```,=$)`0>```` +XMB00DZ/RG_O_KA:&`F`H(QT0D##N["`C'1"0("P```,=$)`0>````B00DZ-6G +XM_O_I6____U6)Y8/L&(/X$HE=](G3B77XBW4(B7W\=B_'0P0`````B30DZ.A' +XM__^)="0$B1PDZ#R^`0"+=?B)70B+??R+7?2)[%WI&+P!`/\DA4#?"`B0QT($ +XM`````(E,)`2)%"3H#;X!`.N[QT($`````,=$)`1^````B10DZ(2[`0#KHHGV +XMBSK'1"0$)````(D\).AZQ/W_A!?WP@```$!U#X/Z?P^.N@,``(VV`````(L6A=(/A#4!``")TX'C____ +XMOP^(R`$``(/[?P^/OP$```^VPP^WA`#@(`D(J$$/A*P!``"+1=C'1>````!` +XMA<`/E<(QR832=`D[7=@/A$X"``"+1>"%P'0-@WW8(HUV``^$I0(``(3)=4B$ +XMTHUT)@!U&87;>`F#^W\/CG,#```['42:"P@/A!,$``"+1=B%P'@4]T78```` +XM0'4+@WW8?Y`/COP````['8R8"@@/A`X!``"%_W08BU74BP*#P@2)5=0YV`^5 +XMP`^VP(/H`2''C47H@\8$B5PD!(D$).C0N0$`BT78A<`/B,7^__^+1=C!Z!Z# +XM\`&#X`&#?=A_#Y["A,`/A*K^__^$T@^$HO[__P^V1=CVA`#@(`D(0`^$D/[_ +XM_XM%T#E%U,=%V``````/@HG^__^+%C'_A=(/A7UW##[9%V/:$`.`@"0A`#X5C_O__Z3[^__\/MD78 +XM]H0`X"`)"$`/A?[^__\['8R8"@@/A?+^__^-5>C'1"0$7````(D4).C=N`$` +XMB5PD!.D:`0``C70F`(M%V('B````0`^4P8E5X(7`#Y7"A,D/A$G^__^$T@^$ +XM3O[__X7;#X@Y_O__@_M_D`^/+_[__P^VPP^WA`#@(`D(J/,/A!S^__^#^R,/ +XMA!/^__^#?=@B#X1R`@``BT78A<`/B,H!``#W1=@```!`B?8/A;L!``"#?=A_ +XM#X^Q`0``#[9%V/:$`.`@"0A`#X2?`0``BU7L@\8$BT7HB5R0_(M%V,'H'H/P +XM`8/@`8-]V'\/GL(Q_^EE_O__C;0F`````(M5[(72=!2+1>B#Z`2-!)"+5=@Y +XM$`^$LP$``(M5V(U%Z(D$)(E4)`3HX[B)7"0$B00DZ,&W`0"+5=B)5"0$C47H@\8$B00D,?_HJKB)%"2)7"0$Z$FW`0"- +XM1>C'1"0$(@```(D$).@VMP$`Z6S]__]\&_=%V````$"0C;0F`````'4*@WW8 +XM?P^.NP```(U5Z,=$)`0`````B10DZ`&W`0#IG/W__P^VP@^WA`#@(`D(J$$/ +XMA#G\__^+1=B%P'0).578#X4I_/__,578@T74!(E4)`2-5>B)%"3HP[8!`.F^ +XM^___#[;#]H0`X"`)"/,/A'S\__^#^R,/A;3]___I;OS__XM%V(U5Z(/&!(D4 +XM)(E$)`3HBK8!`(U%Z(D$)(E<)`3H>[8!`(L&A<`/A8P```"X`0```+H!```` +XM,?_'1=@`````Z:?\__\/MD78]H0`X"`)"$`/A>?\___I+O___\<`7````(U% +XMZ(/&!(E4)`0Q_XD$).@HM@$`N`$```"Z`0```,=%V`````#I8/S__XM%[(7` +XM#X07_?__Z=W[__^#^W\/CZG]__^H@HVT)@`````/A)K]___I>OO__XM5V(U% +XMZ#'_B00DB50D!.C1M0$`Z?S[__^-M@````"-OP````!5B>575E.#[%R)1;2) +XM5;"+`(L0A=)T#XD$).BAVO[_A<")1;AU"C'`@\1<6UY?7<.A+)H+"(E%\(L5 +XM*)H+"(E5[*$DF@L(B47HBQ4@F@L(B57DH1R:"PB)1>"+%1B:"PB)5=RA%)H+ +XM"(E%V(L5$)H+"(E5U*$,F@L(B470BQ4(F@L(B57,H02:"PB)1RC*)H+"(M5Z(D5))H+"(M%Y*,@F@L(BU7@B147UW#BT6XB40D!(M5M(L"B00DZ(OL_O^+5;2)`NFS +XM_O__BT6TBQCKR[C_____QP7`F`H(`````,<%L)D+"`$```#I!/[__XVV```` +XM`(V_`````%6)Y5=64X'L'`$``(F%_/[__Z$LF@L(B97X_O__BQ4HF@L(B8WT +XM_O__BPTDF@L(QT7P`````(E%E*$@F@L(B560BQ4/___XL5!)H+ +XM"(F-=/___XL-`)H+"(F%R+1?"%P`^(O0D``(M5$(M-#(E= +XMZ(F5`/___XD,).@VO?W_B=J)V8/B!(/A((F5%/___XF-#/___\=%W`````#' +XM1>``````B85,____B=B#X`*)A1C___^)V(/@0(F%"/___\=%Y`````#'1=`` +XM````QT74`````,=%V`````#'1>@`````QT0D!,28"@C'!"2`2`D(Z(.F___' +XMA23___\`````/?AO"0AU%>LJ@_IA=0O'A23___\"````D(/`!(L0A=)T$8/Z +XM077BQX4D____`0```.OFB=J#XQ"#X@&-3=")E1S___^)#"2)G1#____'1"0$ +XML)$(".B_/O[_C47%*/___P````#' +XMA2#___\`````QT6L`````(L$A>#@"`C'A03___\$````QX5(____`````,>% +XM9/___P````")19S'A43___\`````BX7T_O__C4WHC570QT74`````(E,)`B) +XM1"0$B10D_U6!(/&!(7;=;J+C43___\+ +XMC4C___^)C2S___\/A+(#``"+1="+50R)1;B+.H7_#X3R`P``BPW@70D(B<.) +XM5:B)C33___^+`XG^@>;___\_B84P____)?___S\YQHE%P`^$?P(``('^_P`` +XM`(FU./___P^'K@4``(N5-/___XM$LC1FA<")=;QY((&]./____\````/A^X& +XM``"+C33___^+C+$T!```B4V\BT7`/?\```")A3S___\/AW4%``"+3<"+A33_ +XM__^+5(@T9H72BT7`>2"!O3S_____````#X>8!@``BU7`BXTT____BX21-`0` +XM`#E%O`^$Z0$``(N%1/___X7`=4Z!Y____S^-1].#^`$/ABH%``"#_E]U-[HM +XM````B[TP____A?]T*#M5P'4:Z:\!```E____/SG+`0``.<(/A)H!``"# +XMPP2+`X7`=>*+A2C___^%P`^$B?W__XU-T(D,).@W._[_@[W\_O__!'4?Z?0$ +XM``"+0P2CX&,)"(L#B00DZ#=&`0")'"3H+T8!`(L=X&,)"(7;==R#O?S^__\& +XM#X2U!```B[4(____A?9T'(M=K(7;=16+C2#___^%R7X+BY4@____]]J)5:R+ +XM3:R)3?"+1>R)!"3H<3K^_XM%E(M5D(M-C*,LF@L(BT6(B14HF@L(BU6$B0TD +XMF@L(BTV`HR":"PB+A7S___^)%1R:"PB+E7C___^)#1B:"PB+C73___^C%)H+ +XM"(N%7UW#C;0F`````(.]^/[__Q(/A:'\__^#O23___\!#X2<`@``QX4H____ +XM`````(N=3/___X7;#X6&_/__BT70@S@N#X5Z_/__BXTD____AW^_X7`#X3W^___BT70BTT,B40D +XM!(D,).B#)0``.84$____B<,/C3@"``"#^`0/A<[[__^+1="+50R+C?3^__^) +XM1"0(B50D#(L!B40D!(M%"(D$).CW(P``A<`/A*'[__^+A1S___^%P`^%(@H` +XM`,>%!/___P,```#IA/O__XGVBU70BTT,B56XBQ&%TG1$BTVX@>+___\_BP&) +XMRXM-#"7___\_.<)T).E3_?__C78`BT,$@>+___\_@\,$@\$$)?___S\YP@^% +XM-/W__XM1!(72==V+C1S___^%R0^%9`,``(N5&/___X72#X4!!0``BX44____ +XMA<`/A2,%``"+A0S___^%P`^%104``(.]^/[__P$/E,.#O?C^__\##Y3`A-N) +XMQP^$6`,``(.]^/[__PL"``"+A2C___^#1:P!A<`/A,CY___I.OS__XM% +XMW(D$).@AU___A#^BX/A4/]__^+0`B%P`^4PH/X+P^4P`G"#[;2B94H____ +XMZ2_]___'A2C___\!````Z2#]__^+10@QV\=`!`````")!"3HV*H!`(F=!/__ +XM_^FK^___@_@$#X3(_?__BX4<____A53^_X7`#X1C^?__BTT(BT70QT$$`````(E$)`2)#"3HB*P! +XM`(M%"(D$).AMJ@$`A=MTD8F=!/___^DP^?__B30DZ#*T_?_I3_K__XD$).@E +XMM/W_B<+IB?K__X/^7P^$TOK__X/^+;I?````D`^$R/K__XGRZ<'Z__^+A03_ +XM__^)1:SI8_O__Z'H)`D(.85D____#X[;````@_C_#X32````@WVL`0^.`OO_ +XM_X/``0^,600``(NU9/___XT\M0````")/"3HXT$!`,=$)`0P*@@(B<.)!"3H +XM@3;^_XL-X&,)"(7)=">%]G@CC10?@ZUD____`8L!B4+\BTD$@^H$A>#'1"0,(,P&",=$)`@$````B70D!(D<).APLOW_BT4(QT`$```` +XM`*'H)`D(BU4(BP2#B10DB40D!.ACJP$`BTT(B0PDZ$BI`0")'"3H8#7^_\=% +XMK`$```#I1?K__XN=\/[__^DX]O__QP7H)`D(_____\>%(/___P````#'1:P` +XM````Z1KZ__^)!"3H[;3]_^EK^?__B30DZ."T_?^)1;R0Z1'Y__^+A1#___^+ +XM5;B+C?3^__^)1"0(B50D!(L!B00DZ*I2_O^%P`^%<_S__XN%*/___X7`#X0; +XM]___Z8WY__^$P`^%H/S__X.]^/[__P%T@^$ +XM\`4``(N-5/___X'B____/XL!)?___S\YP@^%U04``,>%4/___P````#K%XN- +XM5/___X'B____/XL!)?___S\YPG47@X50____`8/'!(.%5/___P2+%X72==+' +XM!P````"+50@K.L'_`HEZ!*'48PD(A<`/A(D$``"+A4C___^%P`^$3OC__XM5 +XM"(N-3/___SM*!`^&//C__\="!`````"+10R)%"2)1"0$Z&:I`0"+50B)%"3H +XM2Z@/X?__@_@O#X4?^O__QT0D!"\```")-"3H +XM5J4!`.D*^O__D,=$)`3$F`H(QP0D0$()".A+___\_)?___S\YT'36BT6DBW@$@\`$B46DA?\/ +XMA7K____I#?S__XM%"(L`B46PB<*+`(7`#X0$`0``BQ7@70D(BXU4____BWVP +XMQX50____`````(F56/___XE-M.F&````BY58____BT2:-&:%P'D=@;U<____ +XM_P````^'HP```(N-6/___XN;_ +XM__\_@?O_````#X95____B1PDZ&.M_?_I4O___XDT).A6K?W_ZXJ)'"3H7*_] +XM_XG#Z5O___^)-"3H3:_]_XG&ZXV+C53___^)U\>%4/___P````")3;2+1;2+ +XM$(72=26+A5#___^+E53___^+3;#!X`*)1"0(B50D!(D,).B)LOW_BT6TB854 +XM____Z67[__^#A2#___\!Z=/S___'1"0$Q)@*",<$)$!""0CHKY;__X7`#X5; +XM^___BX5(____A!C"0CIVOG_ +XM_XM5",="!`````")1"0$B10DZ"^D`0"+30B)#"3H%*(!`.F#^O__QX50____ +XM`````.E6^O__58GE5U93@^Q\BT48BWT0BP#'1=P`````QT7@`````,=%Y``` +XM``")19S'1=``````QT74`````,=%V`````#'1<0`````QT7(`````,=%S``` +XM``#'1>@`````Z&'/__^+50C'!=AC"0@`````BS+'1"0$+P```(DT).@NJOW_ +XMA<`/A.H#``"-6`2)'"0I\^CMI`$`P?L"C4W0B5PD"(ET)`2)#"2)1>SHY*(! +XM`(U%T(D$).A)H0$`C570B10DQT0D!+"1"`CH]BW^_XU%[(D$),=$)`0P'`4( +XMZ.,M_O^+30B+`8,X?@^$]0$``(M5[,=$)`0D````B56HB10DZ*NI_?^%P(G# +XM=!N+3:C'1"0$+P```(D,).CBKOW_A<`/A$X"``")^"4`$```B46@#X7>`0`` +XM,<")^X-]G``/E<"`Y^^)1:2-3=R)#"3HLJ`!`(U%W,=$)`2PD0@(B00DZ%\M +XM_O^#^P8/A#8"```/CM4```"#^Q$/A"<#``"!^_\/``"0#X0-`@``@_L-#X01 +XM`@``,<"+5:2%T@^$]````(/(((E%P(/_#`^/]````(/_"`^-)`(``(/_!`^$ +XM_0$``(UV``^/4@0``(/_`HVT)@`````/A.0!```/CR0%``"#_P&0#X3@```` +XMH8"8"@B+'0QV"@C'1"0,,.$(",=$)`@)````QT0D!!X```")!"3H7XO^_XE< +XM)`2)!"3H\X0!`,<%L)D+"`$```"^_____XUT)@"-3=")#"3HY2O^_X/$?(GP +XM6UY?7<.%V[[_____=.*#ZP$/A3C___^+50C'1"0$+P```(L"B00DZ)"M_?^% +XMP`^$\00``(M5I+\$````N!$```"%T@^%$____XVT)@````"#R$"#_PR)1<`/ +XMC@S___^#_Q,/A#`!```/CS<"``"#_Q`/C_4```"#_PZ-M@`````/C1(!``"+ +XM50B+`HD$).BMH@$`B46HB47LZ?H```")]L=$)`0O````B00DZ`RM_?^%P`^% +XM\_W__XM%[+\#````NP,```")1:CK=HVV`````(M5&(U-W(D,)(E4)`3H[J`! +XM`(M5X(72=!V+1=R#?)#\+W03C47__^%P(GX +XM_O__C5W$QT0D!+"1"`B)'"3HU2K^_XM%Z(M-P(M5J(D<)(E$)!"+11B)3"0, +XMC4W@/A&X&``"+5>"%TG0HBT7<@WR0_"]T'HU-W,=$)`0O````B0PDZ&&< +XM`0"-1=R)!"3HMIP!`('G_^___X/_!`^$?_[__P^/$00``(/_`0^$#@4``)"- +XMM"8`````Z&>G_?^%P`^.L_S__XD<).A[G`$`BT7$BTW0BU4(B00DB?CH".#_ +XM_Z'48PD(A<`/A8O\___'1"0$Q)@*",<$)*`Q"0CH!Y#__X7`#X1O_/__@_X! +XM#X5F_/__@WT<_XGV=#:+11R%P`^%E04``(M=Q(M-W(D<)(E-K.B2)___@_\3 +XM#X:$````,<")1"0$BT4(B00DZ)B;`0"+10B)!"3H[9L!`.D8_/__@_\. +XM_/__#X[F````BT4(BQB#?0P�/`0``BT7LB00DZ/\R`0")'"3H-Y\!`(E% +XMJ(E%[.F$_?__@?\2$```#X6&^___Z9C^__^!_P$0``"0C70F``^%B+1=")%"2-5=SHW]K__X7`B<8/A07[__^# +XM3<`"Z:3\___'!"0-````Z/!"___IBOW__XD<)#'VZ%&@`0")!"3HJ2C__X7` +XM#X71^O__D.G1_O__BT6@A<`/A03[___I&OK__\=$)`3$F`H(QP0DP$()".B7 +XMCO__/?AO"0@/A/L!``"+$(72#X3Q`0``]\(```!`#X7E`0``@_I_C78`#X?9 +XM`0``B<$QP/8$E;U1"0@$=3/IQ@$``(VT)@````#WP@```$`/A;,!``"#^G^0 +XM#X>I`0``@\$$]@25O5$)"`0/A)@!``"-!("-1$+0BU$$A=)URX7`#XZ"`0`` +XM.?`/C7H!``"+112%P`^$;P$``*&`F`H(QT0D#!O?"`C'1"0(!0```,=$)`0> +XM````B00DZ"N%_O^)=;R)!"3HD"[__\=$)`0P*@@(B<.)!"3H7B;^_Z&`F`H( +XMQT0D#&CA"`C'1"0(!P```,=$)`0>````B00DZ.F$_O^+5;R)7"0(B50D!(D$ +XM).AV?@$`B1PDZ'XE_O_H63___XU%\XE$)`2AM'8*",=$)`@!````B00DZ/TE +XM__\/OD7SQP0D`]\("(E$)`3H.7X!`*&`F`H(#[Y=\\=$)`P(WP@(QT0D"`T` +XM``#'1"0$'@```(D$).APA/[_B5PD!(D$).B0I/W_A<`/A"W[__^#_P]T,8VT +XM)@````#H.[___\=$)`P@S`8(QT0D"`0```")="0$B00DZ+NA_?^#_Q`/A#P! +XM``#H$;___\=$)`P!````B70D",<$)/AO"0B)1"0$Z#75___IT?K__X/_!0^$ +XMLOW__X/_$HUT)@`/A>+[__^#3<`$Z4GZ___'1"0$Q)@*",<$)(!""0CH?8S_ +XM_SWX;PD(#X1F____BQ"%T@^$7/____?"````0`^%4/___X/Z?P^'1____S'; +XMB<'V!)6]40D(!'4LZ33____WP@```$`/A2C___^#^G^0#X<>____@\$$]@25 +XMO5$)"`0/A`W___^-!)N-7$+0BU$$A=)URX7;#X7$````A=L/G\")=;R$P`^$ +XMY_[__SE=O`^.WO[__XM%%(7`#X33_O__BT6\A<`/A,C^__^A@)@*",=$)`S^ +XMW@@(QT0D"`8```#'1"0$'@```(D$).C_@O[_Z=+]__^+1>R)!"3HORX!`.E` +XM^/__Z-6]__^%]HG'D`^.J_G__S';ZQV-M@````"#PP''!"0*````Z($___\Y +XM\P^$BOG__XL$G\<$))*Y"`B)1"0$Z$9\`0"A8&0)"(7`=,W'!"0-````Z%$_ +XM___KOX/_$`^$,____XVV`````.AKO?__A?:Z`0```(E%L'XVQT6X`````,=% +XMM`````"+5;B+3;"+!)&)!"3H/*']_SE%M',#B46T@T6X`3EUN'7>BU6T@\(! +XMH>"7"@B)T3'2QT68`0```(/``??QA<")191T`XE%F(M%F(U4!O^)T,'Z'_=] +XMF(7;B46\#Y_`Z;/^__^+51R+30B)5"0$B0PDZ!R6`0#I?_K__X-]#`)T.)#H +XM-Z/]_XL`B00DZ-V@_?_'!"3WW@@(B40D"(M%W(E$)`3H6GL!`,<$)`&Z"`CH +XM3GL!`.E6]O__QP0D`;H(".@]>P$`Z/2B_?^+`(D$).B:H/W_QP0D]]X("(E$ +XM)`B+1=R)1"0$Z!=[`0#I'_;__XGV58GE5U93@>RL````BUT(BT4,QT70```` +XM`,=%U`````#'1=@`````C02#B85X____C470QT7P^&\)",=%[`````#'1"0$ +XML)$("(D$).AO(O[_.YUX____#X-H"0``BY5X____,?^)G7S____'A6C___\` +XM````QT6@`````(/J!,>%#;WP@```$!U+H/Z?W\I#[;"#[>$`.`@"0CVQ"!T +XM"8M-U(/!`8E-H*A`=`PYG6#___\/APP#``"-````B00DZ)A^_O^)7"0$B00DZ"QX`0#'180! +XM````C570B10DZ"H?_O^+182!Q*P```!;7E]=PX-]$`8/A%/___^+A6C___^# +XM?1`$B85L____#X0]____@WT0"W>#BT40_R2%W-\("(/Z?@^$&/[__XU-T(E4 +XM)`2)#"3H5)(!`(M-U(M%T(M4B/R%T@^).?[__XGV@\,$Z6S^__^+$X72>#+W +XMP@```$!U*H/Z?W\E#[;"#[>$`.`@"0BH0706A?]U"C'7@\,$Z6C^__\YUW3R +XMC70F`(/_)P^$,/W__X72D(UT)@`/B%W]___WP@```$"-="8`#X5-_?__@_I_ +XM#X]$_?__#[;"]H0`X"`)"`(/A`7]__^#=8@!#X6&````BX5P____@\,$BXUT +XM____B85H____BT6`B4V@B85\____B50D!(U5T(D4).B&D0$`Z>']__^+0P2- +XM7\__\-````0(E$)`2-1=")!"3H6Y$!`(U#"(GSB<;I-/W_ +XM_X/Z?P^/%OW__P^VPO:$`.`@"0B"#X72_O__Z0#]__^+1=2#PP2+C6C___^# +XMP`&)C7#___^+3:")A6C___^)1:"+A7S___^)G7S___^)C73___^)18#I8/__ +XM_\=%Q`````#'1<@`````QT7,`````,=$)`3$F`H(QP0D@$0)".CLA/__A<`/ +XMA%D%``"+C6S____'1"0$+P```,'A`HG+`UW0B4V!VI````0'46@_A_?Q$/ML#V +XMA`#@(`D((`^%3`<``(/"!#E5C'?5B5PD!(U=Q(D<).B[D@$`B1PDZ*.0`0#' +XM1"0$L)$("(D<).A3'?[_BT7LQT0D#`$```")="0(B1PDB40D%(M%\(E$)!"+ +XM11")1"0$Z&KN__^+E6S___^-3=")#"2)5=2)182+1<2)1"0$Z%R2`0"-1=") +XM!"3H09`!`(D<).A9'/[_@WV$_L<%Y&,)"``````/A,$%``"+1="+E63___^+ +XM')"%VP^$_/S__XM5F(T,$#'`A?\/E,")!"2+E7C___^+A7S____H0-3__X7` +XM#XG3_/__C4W0B0PDZ/T;_O_'183_____Z/__ +XM_P^4P(G9B00DBX5\____Z-#3__^%P`^(W@0``(D<).BP)@$`QT6$`0```.E/ +XM_/__H=B7"@B#Z`*#^`$/EL`/ML")1"0$BX5L____P>`"`T70B00DZ(OL_?^% +XMP(G#=9C'180`````Z13\__^-1>2)1"0$BX5L____P>`"`T70B00DZ"Y:`0"% +XMP`^$\`(``(M%Y(D$).@[)@$`QT6$`````.G:^___BX5L____C5W$QT7$```` +XM`,=%R`````#'1`"`T70B1PDB40D!.C/D`$`B1PDZ+>.`0#'1"0$ +XML)$("(D<).AG&_[_BT7LQT0D#`$```")="0(QT0D!`````")1"04BT7PB1PD +XMB40D$.A][/__BY5L____C4W0B0PDB574B46$BT7$B40D!.AOD`$`C470B00D +XMZ%2.`0")'"3H;!K^_^DR^___BXU\____.8UX____QT7$`````,=%R`````#' +XM1@/A&4!```QTH/^`0^4PHU%Z.CCUO__B<:+1=R)!"3H%AG^_XM%Z#G' +XM=!#'1"0$\",&"(D$).B?&?[_A?8/CH4```"#?1`'#X1"`@``BX5\____,=LI +XMA7C____!O7C___\"BY5X____B10DZ.H?``"+1>CK!X/#`3GS=$^+%)B%TG3R +XMBPJ%R73LB10DZ#D8__^+1>@QTHL,F#'`QP0D`````.C#T/__A<`/B-@"``#' +XM!"04/0D(Z$\W``"%P`^(Q`(``(M%Z.NMBT7H.<=T"(D$).AC&/[_B76$Z2;Y +XM__\Q_XF=?/___\>%:/___P````#'1:``````QT68`````.DN^/__,<"%_XM- +XMY`^4P(N5>/___XD$)(N%?/___^A(T/__AC'1"0,`````(ET)`C' +XM!"3X;PD(B40D!.@,Q___BT7HZ17^__^+58R)%"3HV8T!`,=$)`0P*@@(B460 +XMB00DZ`87_O^!?8SX;PD(=`F+38S'`0````"AX*P+"(D<)(E%Q*'DK`L(B47( +XMH>BL"PB)1,`0")'"3H_XD!`,=$)`2PD0@(B1PD +XMZ*\6_O^+1>R)="0$B1PDB40D#(M%\(E$)`CH50,``(E%A(/H`0^$B@```(M% +XMQ(N-;/___XE$)`2-1=")3=2)!"3HOHL!`(U5T(D4).BCB0$`BTV0B0PDZ+@5 +XM_O_I;OG__XM%Z#G'#X2@^?__B00DD(UT)@#HFQ7^_^F.^?__QP7D8PD(```` +XM`.FM^/__Z#*W__^)-"3HFHH!`(DT)(E%Z.B_%?[_B30DZ&<5_O^+=R)="0(B50D!(D<)(E$)!2+1?")1"00Z/#F__^)183I'____Y"0 +XMD)"0D)"058GE5U93@^P+!HG3B<&!X____S^!X?___S\YRW3>A=)U0XL.A-1P2)1>R+5P2%TG4CC48$B47PBT7PB40D!(M%[(D$).AMOO__N@,` +XM``"%P'6XZX>-1@2)1?"+1@2%P'36)?___S\YPW7-@>+___\_.=%UPXU&"(E$ +XM)`2-1PB)!"3H,+[__X7`=:WI1____XVT)@````!5B>575E.#[#R+10C'1>@` +XM````C77HQT7<`````,=%[`````#'1?``````BQC'1>``````QT7D`````,=$ +XM)`2PD0@(B30DZ/42_O^-5=S'1"0$L)$("(D4).CB$O[_BP.#^"\/A+0```"- +XMM"8`````A7UW#B30DN______HS1#^ +XM_X/$/(G86UY?7<.0D)!5B>57B<]6B<93@^P,BUH,A=MU$>M/BT,$@S@M=$*+ +XM6Q"%VW1`BT,,A+0P2)1"0$B30DZ$+$ +XM_O^%P'3,BP.%P'3&@\0,6UY?7<.#P`3KW8/$##'`6UY?7<.058GE5U93B<.# +XM[#R)1=R-?>B)5=B)3=3'1>@`````QT7L`````,=%\`````"+$X72="H[50QT +XM)8/Z)(US!'4)@WL$.HUS!'1HB50D!(D\).A\@P$`B?.+$X72==:)/"3HC(,! +XM`(M-##D+B<*-0P0/A`(!``")%"3H]!H!`(M%W(D$).A)B0$`B40D#(M5$(E4 +XM)`B+30S'!"1_````B4PD!.A;#?[_@\0\B=A;7E]=PY"-0PB)1>"+0PB#^"V) +XMP0^$OP```('A````0`^%>/___X/X+8G!#X2P````@_E_B?8/AV+____V!(V] +XM40D(!`^$5/___S')@_@M#X2=````BUW@@^@PBW7@BU,$@\8$]\(```!`="/K +XM)O8$E;U1"0@$=!R-5`+0@\8$C02`C01"BQ;WP@```$!U!8/Z?W;:AR+`HL8A=MT8HG&QT7P```` +XM`.LZD(UT)@"AX%T)"(M$F#3!Z`Z)QX/G`70-BT7PA&!^_\```!VN8D<).B]B_W_D.NW +XMQP0D)P```.@"*O__@T7L!(M%[(L(AR+ +XM$H72#X51____@\0,6UY?7<-5B>564X/L((M%"(MP!(7V=$.-4`B+0`B%P`^$ +XMP````(D4).CX%O__B30DBB* +XM_O__QP0D"@```.@>*?__BT,0ANID(UT)@")PXM#%#M8$'3VB7<.)-"3H_@O__S')NJ"D"PCH +XMTOO__X7`==#I%____XGVC;PG`````%6)Y5=64X/L#(7`=`6CZ&,)"(L]Z&,) +XM"(L'B?J%P`^$S0```*D```!`=4F+'>!="0CK)XM$@S3VQ$!T,H/'!(D]Z&,) +XM"(L'A<`/A*(```"I````0`^%HP```#W_````=M*)!"3HTXG]__;$0'7.BQ7H +XM8PD(BQJ)UHG8)0```$")1?!U%H'[_P```'=;H>!="0B+1)@T]L1`=6J%VW@B +XMBT7PA@\8$ +XMB37H8PD(BQZ%VW6ABP>%P'04@\0,B?A;7E]=PXD<).A-B?W_ZZ0Q_X/$#(GX +XM6UY?7<.)^NEP____C58$QP8`````B17H8PD(Z\*+/7P@"0CKP(UV`%6)Y5=6 +XM4X/L3(M="(MU%(D<).BI@@$`QT0D!#`J"`B)1B-!(4(````B00DZ`H7`0#'1"0$,"H("(G'B00DZ*@+_O^+17UW#.P5\(`D(=-XQR8/^ +XM`0^4P;J@I`L(Z`;Z__^Z!````,=%U`$```"%P(E%T'44Z:8"```[!7P@"0B- +XM5@1TJ8-%U`$QP(G6C1P7Z!/^__^+3=2%P(D$CW7;BPU\(`D(A8"C1PWZ0_____'1=@`````BTL$]\$```!`B4W< +XM#X79`@``@?G_````#X=O`@``H>!="0B+5=R+1)`T]L0@#X2X`@``H8"8"@B# +XMPPC'1"0,Z;T(",=$)`@#````QT0D!!L```")!"3H;6C^_XM-U(U5\(D4)(GZ +XMB40D"(M%W(E$)`2)V.BP^/__QT0D!#`J"`B)PXM%\(D$).B+"?[_BT7PBPB% +XMR0^$EP(``*&`F`H(QT0D#%+K"`C'1"0(!0```,=$)`0;````B00DZ`EH_O^+ +XM3=R)^HE,)`2+3=2)1"0(C47LB00DB=CH3/C__\=$)`0P*@@(B<.+1>R)!"3H +XM)PG^_XL3A=(/A((!```QP(M-&#E5W`^5P(/H`0G"B1&#?<0M=FWH'(?]_X-] +XMU`''1=@@)0D(#X;7_O__BU0^^(E5V.G+_O__@WW4`L=%V"`E"0@/AKK^__^+ +XM1#[TB478Z:[^__^+1=3'1=@@)0D(A<`/A)S^__^+3#[\B4W8Z9#^__^+5QC"0B+=>R%P'02B00DZ(82`0#'!>QC"0@`````BP8E____OX/H)(/X +XM5`^&9P$``(DT)+O_#P``Z+R``0#'!"1]````B40D!.C")!"3HSVS__SG##XX]____Z>7\__^)!"3HNFS__SG##Y3`#[;`Z1O___^+ +XM2`2%R0^%QO[__^D3____H8"8"@B^_P\``,=$)`R6X0@(QT0D"`(```#'1"0$ +XM&P```(D$).BS9?[_BTWP`^V +XMP.E@_O___R2%$.,("*&`F`H(QT0D#`>]"`C'1"0(!````,=$)`0;````B00D +XMZ`9E_O_KF(-]R&,/A3#^__^+30S!X`(!`8GVZ2'^__^[$0```(M&!"7___^_ +XM#X1<_O__@_@Z#X4V_O__C48(B00DZ-1\`0"+31"C[&,)"(D!B00DZ,($___I +XM,?[__[L"````Z\"[!P```)#KN+L2````Z[&["@```(GVZZ@QV^NDNPX```"0 +XMC70F`.N8NQ````#KD;L3````B?;KB+L$````ZX&["P```(GVZ77___^[!0`` +XM`.EK____NP$```#I8?___[L,````B?;I5?___[L)````Z4O___^)-"3H.7P! +XM`,=$)`1@````H^QC"0B#P`2)!"3HG8;]_X7`=`?'0`0`````H>AV"@B%P'4_ +XMH;1V"@C'1"0$`````(D$).BH"___HQC"0B[_P\``,=$)`0"````B00DZ,2Q_O^% +XMP(G�>_?__H>QC"0AFNPT`B00DZ%D/`0#'!>QC"0@`````B30DZ(=[`0"+ +XM51"C[&,)"(D"B30DZ#4/`0#IY/S__[L(````Z7#^__^[$A```)#I9?[__[L/ +XM````Z5O^__^[!!```.E1_O__NP40``")]NE%_O__NP$0``#I._[__XU&!(D$ +XM).@F>P$`BTT0H^QC"0B)PXD!QT0D!"D```")!"3HAH7]_X7`=`;'``````") +XM'"2[#0```.CS`O__Z6+\__^-1@2[!@```(D$).C>>@$`BU40H^QC"0B)`HD$ +XM).C,`O__Z3O\__^0D)"0D)"058GE5U93B<.#[!R+,*%P80D(C7WPQP5P80D( +XM`0```,=$)`30.`8(B3PDB47PZ,X#_O^+6P2%VW0:C;0F``````^^!H/&`8D$ +XM).@B'___@^L!=>V)/"3H!0/^_X/$'%M>7UW#C;8`````C;PG`````%6)Y5=6 +XM4X/L+(M%"(M]$(E%Y(M%#(E%X*'T8PD(A<`/A#L!``"AP)@*"(7`#X10`0`` +XMH>AV"@B%P`^%$@$``(LU_)D+"(7V#X03`0``C78`BT7DB00DZ!5\`0`#1>"# +XM_SJ)1>P/A',!``"#_S['1>A()0D(#X2&````,!R[8E4)`B+`XE$)`2+1>PI +XMT(D$).AM?_W_A+B8)@D(Z$[^ +XM__^)?0B#Q"Q;7E]=Z5\?__^A;)D+"(7`#X7R_O__B?:+1>3'!"22N0@(B40D +XM!.AM6@$`B7T(@\0L6UY?7>DN'___BQWH=@H(A=MT%(L-?)@*"(7)=,KIM?[_ +XM_Y"-="8`BQ7@=0D(A=)TMNFA_O__D+AH)@D(Z-;]__^X."8)".C,_?__N(`F +XM"0CHPOW__XE]"(/$+%M>7UWITQ[__\=%Z"`F"0CI%____XT$28/Y%(T$Q4@E +XM"0B)1>@/A0'____IJ_[__XVV`````(V_`````%6)Y5>)QU93@^PLBW4(B57@ +XMBQ^)3=R+$HE5\(L"A<`/A(,````E__\_`#GP='J#^#IU->MS@_A>=#.#P@2) +XM5?")1"0$B1PDZ*1X`0"+5?"-#!B+`H7`="DE__\_`#GP=""#^#IT&XG+@_A< +XM=`!``!U +XMW87VQP4`9`D(`````,<%^&,)"`````#'!?QC"0@`````#X32`0``B30DNQ`` +XM``#H]GW]_XEU\(L6A=*)Q[@0````="V)\;,!C;8`````@>+__S\`,<"#^CH/ +XME,"#P02)3?"+$0'#A=)UY(G8P>`$B<,!^(D$).AC"P$`B77PQP7\8PD(```` +XM`(T4&(D5`&0)"(E5[(E%Z*/X8PD(Z$W\_?_'!"0`F@L(B46LH2R:"PB)1=RA +XM*)H+"(E%V*$DF@L(B474H2":"PB)1="A')H+"(E%S*$8F@L(B47(H12:"PB) +XM1<2A$)H+"(E%P*$,F@L(B46\H0B:"PB)1;BA!)H+"(E%M*$`F@L(B46PZ(I] +XM_?^%P'5IBU7PBS*%]G1@B?.!X___/P"#^RH/A-X```"#^SH/A,H```"+0@2% +XMP(E%J'01BT(()?__/P"#^#T/A"N[D(UT)@`E__\_`(/X.G2L +XM@\($B57PBP*%P'7JBU7PBS*%]G6@BT6LB00DZ!;^_?^+1=RC+)H+"(M%V*,H +XMF@L(BT74HR2:"PB+1="C()H+"(M%S*,@K!?AC +XM"0C!^`2C_&,)"(/$7%M>7UW#C4($B47PZ0C___^+3>B-0@2)1?"-5?"-1>S' +XM!"0]````Z.?\__^%P'0*BT7HBT`$A``````)?__/P")1:3K#8-%X`&#QQB#?>`4=$"+CT0E"0@/ +XMO@$YPW7F#[Y!`3M%I'7=C4(,B47PBT7@C57PQP0D.@```(T,0(T,S4@E"0B- +XM1>SH-_S__^DX_O__BT6HB70D!,<$)(8```")1"0(Z*OZ_?_I/?___XVV```` +XM`%6)Y5=64X/L#,=$)`3$F`H(QP0D:$P)".AS9/__A<")QP^$J0```(L`A<`/ +XMA)\```"+`(7`='F+`(7`='/'!?!C"0@`````QP7T8PD(`````(L'BQB%VW1K +XMO@0```#K%L<%\&,)"`$```"+!XL<,(/&!(7;=$['1"0$R$P)"(D<).CV>?W_ +XMA7UW#D)"0D%6%P(GE=1''!7!W"@C`JPL(HSB:"PA=PX/X`77Y +XMQP5P=PH(P*0+"*,XF@L(Z^B)]E6+#31W"@B)Y5.+70C!XP*-!`L[!;"8"@AS +XM,3L-5)D+"'8CB<*+`8/I!(D"H529"PB#Z@0YR';MBQ50F0L(A=)T!#G"=PD! +XM'31W"@A;7<.-!!.C4)D+".OMC;0F`````(L5-'<*"%6+#529"PB)Y593BUT( +XMB=`IR,'X`CG8?@*)V(7`?E^+'7<,YRL<%/)H+"`(```"C0'<*"(D- +XMD'<*"'(WB7<.--)4`````B=@I\#L%-'<*",<%/)H+"`(```") +XM%4!W"@BCD'<*"'>GB<(QR8T575HG64XG#@^P$B4WPC4@$ +XMBT`$@_A>=#N#^"2_`0```'1!C5#0,<"#^@EW%)"#P02-!("-!$*+$8/J,(/Z +XM"7;MA?]X-8D&@\0$@^D$6XG(7E]=P\<"`0```(/$!(G(6UY?7<.#>P@M=!G' +XM`O___W^#Q`2)R%M>7UW#BU7P*<*)T.O"BT,,C4L,O______KDXVT)@````"- +XMO"<`````58GEBU4(A=)^#XT$E0!V"0@[!529"PAV!UW#D(UT)@!=Z3K^__^- +XM=@"-O"<`````58GEBU4(@^)_@_I_=S+V!)6]40D(!'0HH41W"@B%P'0FH7QW +XM"@@]0$(/`'\3C02`78U$0M"C?'<*"+@,````PUVX9````,-=C4+0HWQW"@BX +XM#````,<%1'<*"`$```##H9QW"@A5B>6#^`%^!:.HF`H(H31W"@B-4`3'``H` +XM``")%31W"@C'0`0`````N`$```!=PXVV`````(V_`````*$T=PH(58GEQP`` +XM````N`,```!=PXUT)@"-O"<`````H31W"@A5B>7'``````"X%````%W#C70F +XM`(V\)P````"A-'<*"%6)Y<<``````+@3````7<.-="8`C;PG`````*$T=PH( +XM58GEQP``````N!(```!=PXUT)@"-O"<`````H529"PB+%31W"@A5B>4YT',( +XM@\`$HU29"PC'`@````"X`P```%W#B?:-O"<`````H31W"@A5B>7'``````"X +XM"@```%W#C70F`(V\)P````"A-'<*"%6)Y<<``````+@-````7<.-="8`C;PG +XM`````*$T=PH(58GEQP``````N`8```!=PXUT)@"-O"<`````H31W"@A5B>7' +XM``````"X$````%W#C70F`(V\)P````"A-'<*"%6)Y<<``````+@5````7<.- +XM="8`C;PG`````*$T=PH(58GEQP``````N`\```!=PXUT)@"-O"<`````58GE +XM@^P$BQ4H)PD(A=)T%*%4F0L(BPU\=PH(*=#!^`(YR'T,R;AD````PY"-="8` +XMB0PDZ.C[__^X#@```,G#D%6X9````(GE@^P$@3U4F0L(`'8)"'<)R<.-M"8` +XM````H7QW"@B)!"3HL_O__[@.````R<.-M@````"-OP````!5B>6#[`2A5)D+ +XM"#L%-'<*"'0MH7QW"@B)!"3HD/K__XL5-'<*"+@.````.154F0L(=@:)%529 +XM"PC)PY"-="8`BQ7(F0L(A=)T%CT`=@D(=`^#Z`2C5)D+".NXD(UT)@#)N&0` +XM``##B?:-O"<`````BPU4F0L(58GE@?D`=@D(="^A-'<*"#T$=@D(=",YP7,) +XM@\$$B0U4F0L(BT'\BU'XB4'XN`X```")4?Q=PXUV`%VX9````,.)]HV\)P`` +XM``"+#529"PBX9````%6)Y8'Y!'8)"'81BT'\BU'XB4'XN`X```")4?Q=PXVT +XM)@````!5B>6#[`R#/0QD"0@!B7PD"(G'B1PDB70D!'0DH529"PB)/0QD"0BC +XM$&0)"+@,````BQPDBW0D!(M\)`B)[%W#BS4T=PH(QP4,9`D(`````,<%$&0) +XM"`````#'!4!W"@@`````@?X`=@D(=BJY`'8)"#';,=*+!)4`=@D(@\$$@\,! +XMB025()D*"(/"`3GQ4]0$(/`'\4P>`"L@S'!41W"@@!````HWQW"@A= +XMB=##C70F`%6X#````(GE7<<%$'8*"`$```##C;8`````C;\`````53'`B>7H +XM]O?__Z%4F0L(7<<%`)D*"`(```#'!3R:"P@$````HY!W"@@QP,<%0'<*"``` +XM``##C78`C;PG`````%4QP(GEZ+;W__^A5)D+"%W'!0"9"@@!````QP4\F@L( +XM!````*.0=PH(,<#'!4!W"@@`````PXUV`(V\)P````!5B>6#[`2A?'<*"(D$ +XM).C]]___,<#H9O?__[@.````RA&]___ +XMH529"PA=QP4\F@L(`0```*,H)PD(HY!W"@@QP,.)]HV\)P````!5,<")Y5W# +XMB?:-O"<`````,<"#/0"9"@@`58GE70^4P*,`F0H(,<##D(VT)@````!5,<") +XMY5W#B?:-O"<`````53'`B>5=PXGVC;PG`````%4QP(GE7<.)]HV\)P````!5 +XM,<")Y5W#B?:-O"<`````53'`B>5=PXGVC;PG`````%4QP(GE7<.)]HV\)P`` +XM``!5N`,```")Y>A3_?__70^^P,.-M"8`````C;PG`````%6X`0```(GEZ#/] +XM__]=#[[`PXVT)@````"-O"<`````58GE5U93@^P$H3R:"PB#^`(/A($```!_ +XM%X/H`0^$SP```+AD````@\0$6UY?7<.0@_@##X2X````@_@$=>2A0'<*"(7` +XM#X0\`0``BQV0=PH(B=XK-31W"@B)'529"PC!_@(YQ@^,%@$``(7V?ATQR8L4 +XMC2"9"@B+!(N)!(T@F0H(B12+@\$!.?%UY8/$!+@.````6UY?7<.A0'<*"(7` +XM#X3B````BQV0=PH(B00DB1U4F0L(Z,?U__^+#4!W"@B%R7X7,=*+!)4@F0H( +XMB023@\(!.15`=PH(?^O'!3R:"P@!````@\0$N`X```!;7E]=PXLU0'<*"(/^ +XM``^$AP```(L]D'<*"(G[?AF)^C')B?:+`H/"!(D$C2"9"@B#P0$Y\77MBQ4T +XM=PH(.==V">LED(LU0'<*"(L$LXD#BQ4T=PH(@\,$.=ISZ(LU0'<*"(L]D'<* +XM"(T$M0`````IPK@.````B3U4F0L(B14T=PH(QP4\F@L(`@```(/$!%M>7UW# +XMB<;IX_[__S'`Z9G^__^)]E6X9````(GE7<.-M@````!5N&0```")Y5W#C;8` +XM````5;AD````B>5=PXVV`````%6X9````(GE7<.-M@````!5N&0```")Y5W# +XMC;8`````5;AD````B>5=PXVV`````%6)Y8/L",=$)`0`=@D(QP0D\)D+",<% +XM])D+"`````#H+&8!`,<$)/"9"PCH$&0!`*$T=PH(Q@4D=PH(`2T`=@D(P?@" +XMH^B9"PBA5)D+""T`=@D(P?@"HS!W"@BAG'<*"*.HF`H(R<.)]HV\)P````!5 +XMB>6#[`CHA?___Z$T=PH(QP6HF`H(`````(U0!,<`"@```(D5-'<*",=`!``` +XM``"X`0```,G#B?:-O"<`````58GE@^P(H529"P@[!31W"@AT+:%\=PH(B00D +XMZ"#T__^+%31W"@BX#@```#D55)D+"'8&B154F0L(R<.0C70F`.C;DP``H31W +XM"@C'``````"X!````,G#B?:-O"<`````58GE@^P(Z.7^___'!9QW"@@````` +XMZ*:3``"A-'<*",<``````+@+````R<.-="8`58GE@^P(Z(63``"A-'<*",<` +XM`````+@%````R<.-=@!5B>6#[`CH99,``*$T=PH(QP``````N!$```#)PXUV +XM`%6)Y8/L".A%DP``H31W"@C'``````"X!````,G#C78`58GE@^P(Z"63``"A +XM-'<*",<``````+@)````R<.-=@!5B>6#[`CH!9,``*$T=PH(QP``````N`(` +XM``#)PXUV`%4QP(GE@^P(Z'/R__^A-'<*",<%/)H+"`$```"C5)D+"*,H)PD( +XMHY!W"@CHL*8``#'`R<.-M@````"-OP````!5,<")Y8/L".@S\O__H529"PB+ +XM%31W"@@YT',6@\`$.<*C5)D+"'(HZ'.F``"A5)D+"*,H)PD(HY!W"@@QP,<% +XM/)H+"`$```#)PXVV`````(D55)D+".O0D(VT)@````!5B>6#[`C'!529"P@` +XM=@D(QP4H)PD(`'8)",<%D'<*"`!V"0C'!3R:"P@!````Z`VF```QP.BF\?__ +XM,<#)PXGV58GE@^P(H5"9"PB+%529"PBC5)D+"(D54)D+".C?I0``,<#)PXUT +XM)@"-O"<`````58GE@^P(BQ60=PH(H529"PC'!2@G"0@`````QP4,9`D(```` +XM`,<%$&0)"``````YPL<%1'<*"`````!V*"G"P?H"B15`=PH(N`$```#'!0"9 +XM"@@`````Z!3Q___H;Z4``#'`R<,IT,'X`J-`=PH(Z]?K#9"0D)"0D)"0D)"0 +XMD)!5B>53@^P$]@4,9`D(`G5ABQ409`D(QP4,9`D(`````(72=#:A5)D+",<% +XM/)H+"`(````YPG))=R?'!"0!````NP$```#H-O'__Z%4F0L(B1U`=PH(HY!W +XM"@B#Q`1;7<.)TRG#P?L"B1PDZ!'Q___KV3'`Z'CP___KEHVV`````(G#*=/! +XM^P*)'"3HX?'__^B\I```Z[2-=@"-O"<`````58GE5HG6BQ4T=PH(4XG#H529 +XM"PB#[@&#_O]T%CD8=`@YT'/P.1AT[(/`!)"-="8`Z^XYPKYD````=B53B<.#[`2A5)D+"(GV +XM@^H!@_K_=!HY&'0/C70F`#T`=@D(=NDY&'3E@^@$B?;K[CT`=@D(<@IU$SD= +XM`'8)"'0+N&0```"#Q`1;7<,Y&'0F]@4,9`D(`:-4F0L(="*#P`2C5)D+".CC +XM_?__@\0$N`X```!;7<.%R736@\`$D.O0Z!FC```QP.N]D(UT)@!5NF0```") +XMY8/L"*$$9`D(A6#[`B+#529"PB+ +XM%31W"@@YT7,TH7QW"@B-!($YPJ-4F0L(6#[`B+ +XM%529"PB!^@!V"0AV/XL-?'<*"(G0+0!V"0C!^`(YR'PSC02-`````"G"H6#[`BA-'<*"*-4F0L(HB00DZ$YE_?_VQ$!UVO8%#&0)"`%T$>B/^O__ +XM@\00N`X```!;7EW#Z,Z?``"#Q!`QP%M>7<.0C70F`%6)Y5>)UU93@^PS_#X2-````.?YR&.OLC70F`(-^_%QT6(/&!#GW +XMD(UT)@!VUHL>BT4(B5PD!(D$).CI:/W_A575HG&4X/L'(M]"(E5[(E-Z(-MZ`&# +XM?>C_#X2'````BUWL.=YW&>F,````B?:#>_Q<=!Z#PP0YWI"-="8`=GB+`XD\ +XM)(E$)`3HO&?]_X7`==R)7?"+1?"Y`0```(GRB3PD@^@$Z&3^__^-6`0YWG,/ +XMZR.#>_Q<=!F#PP0YWG(6BP.)/"2)1"0$Z'QG_?^%P'7A.=YWO(-MZ`&#?>C_ +XMBW7P#X5Y____BT7L.?!S`HGP@\0<6UY?7<.)WNE3____ZPV0D)"0D)"0D)"0 +XMD)"05;AD````B>53@^P$BQU4F0L(@?L`=@D(=#&+#7QW"@BZ`'8)"(G8QP0D +XM,$T)".C]_O__]@4,9`D(`:-4F0L(=!#H*OC__[@.````@\0$6UW#Z&J=```Q +XMP.OQC;8`````58GE@^P8Z&6)``"-10B)1"0(QT0D!&5T`""AM'8*"(D$).CU +XM8OW_AH5"9"P@[!529"PAT$>BGAP``Z"*(``")]N@;F```H529 +XM"PC&!575E.#[`RAN)@*"(7`#X06`0``BPTXF0L( +XM*PU\=PH(A/>)#3B9"PB)RHG#P?H?BZ/__BQU4F0L(B30DZ`#G__^+%3B9"PBA*)D+"(L$T(L0 +XMA=)T#XD3BU`$@\,$@\`$A=)U\87_=&.A5)D+"(D=5)D+"*-0F0L(QT0D!,28 +XM"@C'!"0@20D(Z"5*__^%P'0)@#W,F0L(`'5'Q@7,F0L(`(/$#+@.````6UY? +XM7<.#Q`RX9````%M>7UW#B=._`0```"G#P?L"Z23___^)'5"9"PCKI8D<).C& +XMYO__Z5/___^0Z)N%``#H%H8``.NLC70F`%6)Y5.#[!2+#;B8"@B%R74/@\04 +XMN&0```!;7<.-="8`BQ4XF0L(H2B9"PB+!-")!"3H)F#]_XG"C02%``````,% +XM-'<*"#L%L)@*"'/$B10DBQU4F0L(Z/7E__^+%3B9"PBA*)D+"(L$T(L0A=)T +XM$)")$XM0!(/#!(/`!(72=?&#/7QW"@@!=#F)'5"9"PC'1"0$Q)@*",<$)"!) +XM"0CH'DG__X7`=`F`/6#[!B)7?B+'3!D"0B)=?R)QJ$T9`D(B70D +XM!(D<)(E$)`CH@V#]_[H!````A7UW#@\0,N&0```!; +XM7E]=PXL=5)D+"('[`'8)"',=Z^.)="0$B1PDZ*"3_O^%P'7#@^L$@?L`=@D( +XMNBC70F`(V\)P````!5B>564X/L$(LU +XM?'<*"(7V#XZ,````H1QW"@B%P`^$?P```(M(!(M1!(72='6+6`BX_____SG9 +XM=!,QP)"-="8`@\`!.<9_/H/H`8G1B40D",=$)`0`````BT$$B00DZ!TG`0") +XMPXD$).@#_O__A7<.#Q!"X9````%M>7<.)]E6)Y5=64X/L3(L=5)D+ +XM"(/K!('[`'8)"'8XBP.#^"!T,X/X"70NBQ6,F`H(.=")5;QU%.LWBP.#^"!T +XM&(/X"9!T$CM%O'0E@^L$@?L`=@D(=^.+`SD%C)@*"'0-Z'^2``"#Q$Q;7E]= +XMPXE%O(US!(EUX(M3!(/Z(`^$Z0$``(/Z"0^$X`$``(/X((G"="B#^`D/A`\% +XM``"!^P!V"0@/AA,"``"#ZP2+$X/Z(`^$!0(``(/Z"77AH529"PB)1<`Y5;QT +XM$CL=5)D+"',*@\,$BQ,Y5;QU[HU#_#T`=@D(#X+A`0``@WO\7`^%UP$``(U3 +XM^+D!````ZPJ+`H/J!(/X7'4+@\$!@?H`=@D(<^OVP0%U`X/#!#M=P`^#/___ +XM_XG*P>H?C001@^`!*="#Z`%UGXL5''<*"(72B570#X0;`0``BST$F0H(B=XQ +XMTH/'`8E]N(U&!(E%V(M&!(/X*@^$@P$``(/X7@^$R`(``(/X)`^$9`(``(72 +XM#X4,!0``@_@ZBWW8#X0*!```.46\#X2%`P``@_@@#X0J!```@_@)C78`#X0> +XM!```@_@Z#X05!```.WW`#X,,!```,#^"!T,(/X"70K@_@Z="8Y?#^"!UT(M5S(/O!(72#X6>`@``B?@I\(G&BT70P?X"A8``.@TH```B5W'+3@2)]XU!T(/X"78+@_DM=`:)^(GWZSZ#^20/A9$!``")^(GW@W@( +XM+71WN@$```")_NGM^___@_DM#X1K`0``@_DJD'0.@_DD=`F#^5X/A3$!``") +XM^(/Y)'3*@_E>=")1<#I^OK__X/O!#')Z?O^__^+4`R#^B\/CGW___^# +XM^CD/CW3___^+=="+5@2%T@^$:OS__XM2!(MV"#GR#X1<_/__,?^+4@2#QP$Y +XM\G7VA?\/A$C\__^#^2T/A?H```#'1?``````C5`$B578BU`$@_HM#X3````` +XM@_HJ#X2G````BU7PB478B57LA=(/B`S\__^+1>PYP@^/`?S__XM]T(E$)`B) +XM5"0$B3PDZ&,@`0"+==B#Q@2)1S___]_D.E2____BW78BU8$C4+0@_@)=B*#^B1T'8M5\(U'_XE%[.DQ____ +XMB?F-5?#H4-[__^G^_O__BT78C57LB?GH/M[__XM5\(E%V.D*____C78`58GE +XM@^P(H31W"@C'``````#HJOC__S'`R<.-M@````!5B>575E.#["RA8&0)"(7` +XMB47@#X6"````H;1V"@B-?>['1"0(`0```,=$)`0!N@@(B00DZ%?7_O^+10B) +XM/"0E__\_`(E$)`3H4T\!`(7`B<9T)3';C00?@\,!B40D"*&T=@H(QT0D!')T +XM`8")!"3H.%7]_SGS==V+3>"%R70&D.C;60``BT4(B00DZ'#R__^#Q"Q;7E]= +XM#[[`P^C`6```Z73___^-="8`C;PG`````%6)Y8/L".@EG```Z,!Z``"X#@`` +XM`,G#B?:-O"<`````58GE@^P(QP0D`````.BN50``N`X```#)PXVT)@````!5 +XMB>575E.#[`R+?0B%_P^$U0```(L=?'<*"(T$G0`````#!31W"@@[!;"8"@@/ +XM@[8```"#^P$/A+H```"+-0"9"@B%]G1-A=L/CCP!``"+-529"P@QR8L50'<* +XM"(UT)@"+!(Z#P0&)!)4@F0H(@\(!.=F)%4!W"@AUYHD<),<$E2"9"@@````` +XMZ*/:__^+'7QW"@B)'"3H-=K__Z%\=PH(@^@!@_C_HWQW"@AT)(G"D*%4F0L( +XM@^H!B3B#P`2#^O^C5)D+"'7IQP5\=PH(_____^BZB0``,<"#/0"9"@@"=%J# +XMQ`Q;7E]=PX/$#+AD````6UY?7<.A`)D*"(7`=5+'!"0!````Z,79__^A5)D+ +XM"(DX@\`$HU29"PC'!41W"@@`````QP0D`0```.@@C```,<"#/0"9"@@"=:;' +XM!"0`````Z.GG__^#Q`PQP%M>7UW#BQ54F0L(H4!W"@B+$L<$)`$```")%(4@ +XMF0H(C5`!B15`=PH(QP25()D*"`````#HJ]G__^EU____BQ5`=PH(Z>7^__^- +XM="8`C;PG`````%6)Y8/L"*$T=PH(QP``````Z/KU___'!"0@````Z#[^___) +XM#[[`PXGVC;PG`````%6)Y5.#["3HI%0``(U%"(D$),=$)`2P2@<(Z%'5_?^- +XM1?B)!"3H1F```(G#C44(B00DZ)G4_?^#ZP%T%<<$)`````#HZ.7__X/$)%M= +XM#[[`PXM%^(D$).C4_?__@\0D6UT/OL##C70F`(V\)P````!5B>5=Z>=3``"- +XMM"8`````58GE5U93@^P\BPVXF`H(B578*<+!^@*)1=R%R8E5U`^.:`$``,=$ +XM)`3$F`H(QP0DX$D)".@7//__/?AO"0B)PP^$R````*&XF`H(QT0D!(!#"0B) +XM'"2)P@,5/)D+"(E%T(U"_XG"P?H?]WW0B14XF0L(B=>)UNAA4?W_A<`/A30! +XM``"+5="%T@^.B````*$HF0L(BU74QT7L`````(E%S(M%T,'B`HE5Y(/H`8E% +XMR.L/BT7(`?")PL'Z'_=]T(G6BU7,C1SU`````(T\$XM5U(L'B50D"(E%X(M% +XMW(M5X(E$)`2)%"3H45/]_X7`=1&+1>"+5>2+!!"%P`^$*`$``(-%[`&+1=`Y +XM1>QUI>L(H;B8"@B)1="+==2+%3R9"PB+#;QV"@B#Q@$Y3=")%3B9"PA]"XM% +XMT(/``:.XF`H(C1S5`````(/"`8G0P?H?]_D#'2B9"PB)%3R9"P@[GN_O__BT7LBW\$A<")?>A_#>LZBQ4HF0L(B?Z)5____ +XM,<#H%]3__[@.````R<-5N`!V"0B)Y8/L"(L55)D+".BJ^___H529"P@M`'8) +XM",'X`HD$).AEU?__BQ50F0L(A=)T%J%4F0L(.<)V#2T`=@D(*<*)%5"9"PC) +XMN`X```##C;0F`````(V\)P````!5B>6#[`BA5)D+"(L5-'<*".A*^___H529 +XM"P@[!5"9"PBC-'<*"',%HU"9"PC&!6#[`BA5)D+"#L%-'<*"'0= +XMZ*AS``"A-'<*",<``````+@$````R<.-M@`````]`'8)"'76#[`BA5)D+"#L% +XM-'<*"'0MH7QW"@B)!"3H8-/__XL5-'<*"+@.````.154F0L(=@:)%529"PC) +XMPY"-="8`/0!V"0AT%^@4C^_[@"````R<.)]E6)Y8/L"*%4F0L(.P4T=PH(="VA +XM?'<*"(D$).C@TO__BQ4T=PH(N`X````Y%529"PAV!HD55)D+",G#D(UT)@"+ +XM%/__QP58F0L(`0```,<$)`!V"0CHNSX!`#T`=@D(HS1W"@AV(8-X +XM_`H/A(8```"A-'<*"(-X_"!T<8$]-'<*"`!V"0AR6:$T=PH(HU29"PB#Q!2X +XM#@```%M=PX/$%+AD````6UW#B10DZ#85`0#'1"0(`$```,<$)`!V"0B)PXE$ +XM)`3H7'C__XD<).@DUP``QP58F0L(`````.EN____QP4T=PH(`'8)".N;@^@$ +XMHS1W"@CKA8/H!*,T=PH(Z6W___^)]E6)Y5.#[!2+#9QW"@B%R75&H9B8"@B% +XMP`^$#`$``,=$)`@`0```B40D!,<$)`!V"0CHZG?__Z&/P*#X2#````@3TT=PH(`'8) +XM"',*QP4T=PH(`'8)"*$T=PH(HU29"PB#Q!2X#@```%M=PZ.<=PH(@\04N&0` +XM``!;7+!#.%P'01B?#H +XMV>C__X7`=`:+1>R)1?"A#&$)"(7`#X2(````BW\<@T7L`8M%[#D%G'<*"'\P +XMBW7PA?9U#J&8F`H(Z)_H__^%P'1PBT7PHYQW"@CH?OW__X/$'%M>7UT/OL## +XMC78`A?]TS(M'&(7`#X51____B3PDZ#D2`0")1QBA#&$)"(7`#X5&____B3PD +XMZ"$2`0#'1"0$,"H("(G&B00DZ)_)_?_I*O___XDT).CRR/W_B?;I:?___X/$ +XM'+AD````6UY?7<.-M"8`````C;PG`````%6)Y5=64X/L'*$T=PH(QP4,9`D( +XM`````,<%/)H+"`````#'``````"#/9QW"@@`#XQ6`0``#X0A`0``BS4<=PH( +XMA?8/A`8!``#HPOK__XL5G'<*",=%\`$```"%TGX:,<"#P`&+=APYT'7V@\(! +XMA?:)5?`/A-8```"+7AB%VW1LBPT,80D(AL`=@D(B=C!^`*)1"0(Z`I(_?^%P'4'BQ0[A=)T8XGXNP$```#H1^?_ +XM_X7`=%.A#&$)"(7`=%6%VW5=BW87UT/OL## +XM@\06#[`B+%31D"0B%TG07,<"#/2`G"0@5#Y3`@\`5Z(?___\/OL#)PXGV +XM5;AD````B>6#[`B+#31D"0B%R74"R<.A("<)".A?____R0^^P,.-=@"-O"<` +XM````58GE5U93@^PLC77DB478C5WPQT7D`````,=%Z`````#'1>P`````QT0D +XM!+"1"`B)-"3HV<;]_\<$)`!V"0CHC3T!`,=$)`0P*@@(B<>)!"3HN\;]_Z$T +XM=PH(B47#'1"0$*@```(DT).A[.0$`BT78QP4`=@D(`````,<% +XM-'<*"`!V"0C'!529"P@`=@D(HR`G"0C'!"0"````Z/G)__^+%529"P@QP,<" +XM"@```(-]V!4/E,"#Z`&#X/"#P#^)0@2#P@B)%529"PCHBGD``,=%\`````"- +XM=@")'"3H*%$``(/H`75:BT7P@_@-#X2N````?VN#^`B)]G1N@_@*#X2<```` +XMB40D!(DT).C9.`$`H529"PB+5?")$(/`!*-4F0L(HS1W"@CH+7D``,=%\``` +XM``")'"3HSE```(/H`72FB30DZ"'%_?_'!"0`````Z'76__^#Q"Q;7E]=#[[` +XMPX/X&W0\@_A_=9N#?>@!#X91`0``H529"PC'``````"#Z`2#;>@!HU29"PBC +XM-'<*".C%>```QT7P`````.DY____A<`/A#'___^)/"3HN<3]_X-]Z`$/A)P` +XM``#'1"0$*@```(DT).@?.`$`B30DZ'3'!31D"0@`````QP0D,&0) +XM"(E$)`3H:CH!`,<$)#!D"0CH3C@!`(DT).AFQ/W_#[9%V(-]V!7'!31W"@@` +XM=@D(QP54F0L(`'8)"*)(F0L(#X2$````QP0D`````.CC^?__/&0/E,"$P'5= +XM@WWP&[@.````#X2P````@\0L6UY?7<.+'31D"0B%VP^%R0```,<%`'8)"``` +XM``#'!31W"@@`=@D(QP54F0L(`'8)".C2=P``B30DZ-K#_?^#Q"RX9````%M> +XM7UW#Z+AW``"#Q"RX9````%M>7UW#QP0D`````.C?^O__/&0/E,#I=____\=$ +XM)`@`0```B7PD!,<$)`!V"0CHW6___XM%W*,T=PH(BT7@B30DHU29"PCH=1''!9QW"@@`````N&0```#)P^AK]O__ +XMR0^^P,.-M@````!5B>6#[`BA-'<*",<%/)H+"`````#'``````"AG'<*"(7` +XM="RA?'<*"`$%G'<*".@L]O__/&1U1.@C]O__C78`Z-MU``"X9````,G#C70F +XM`,<%G)@*"`````#'1"0$`'8)",<$))B8"@CHLC575E.#[!R+?0B%_P^.^@```#L]O'8* +XM"'1"QT0D!`@```")/"3H],P``(E%[*$HF0L(A0/A+P!``"+/029"@@I\\'[`HD] +XM+&0)"(DU(&0)",<%-&0)"`````")7"0(B70D!,<$)#!D"0CH+#0!`,<%*&0) +XM"`````#'!21D"0@`````QT7@`'8)",=%\``````Q_\=%Z`````#'1>P````` +XMZUJ+1>2#!2AD"0@!QP4D9`D(`````(7`#X3@````QT0D"/___W_'1"0$```` +XM`(M-Y(D,).@Q!@$`B47PB00DZ(8P`0"+3?")QHM%Y(M`'(E-X(E%Y(M%[(7` +XM=7O'!"1`30D(BU7@N0$```")\.CHU___.<:)PW2*BQ#WP@```$!U'H'Z_P`` +XM``^'K`$``*'@70D(BT20-/;$0`^%8O___XU#_+D!````B?*#!21D"0@!QP0D +XM0$T)".AMUO__*=C!^`*->`&A-&0)"#G'=TR+1>R)WH7`=(6+%529"PB-!+T` +XM````*Q4@9`D(`P4T=PH(*=`[!;"8"@@/@DD!``"+3?")#"3HH<@``(/$++AD +XM````6UY?7<.-="8`B40D"*$P9`D(B1PDB40D!.A'/?W_AZ0#___^+/029"@@[/2QD"0@/A3C^__\[ +XM-2!D"0@/A2S^__\['1QD"0@/A2#^__^A-&0)"(7`#X03_O__B40D"*$P9`D( +XMB70D!(D$).C5//W_A<`/A?;]__^+%2AD"0C'1>``=@D(QT7P`````(72=$N# +XM^@$/CQ2%T@^$,0$``,=$)`C___]_QT0D!`````"+1>2)!"3H>@0! +XM`(E%\(D$).C/+@$`BTWDBTD2)1>#'!"1`30D(BPTD9`D(B?"+ +XM5>#H-];__XG&Z<;]__^#Q"RX9````%M>7UW#C78`B10DZ`0Z_?_I4/[__\'Z +XM`HD4).A8P___B3PDZ&#`__^%_W0=,6A5)D+"*,<9`D(BT7PB00DZ!K'``"#Q"RX#@```%M>7UW#B10DZ*$Y +XM_?_IT?S__XL5(&0)"*%4F0L(*=#!^`(Y^`^%B/[__XE\)`B)WHE4)`2)'"3H +XMHCO]_X7`#X1Y_?__Z6G^__^+3>2%R8UT)@!T&K`!BTWD@\`!.<*+21R)3>0/ +XMCLC^__^%R77HQT7P`````.GL_?__D(VT)@````!5NF0```")Y5=64X/L#*%4 +XMF0L(BSTT=PH(.?@/A$L!``"+%7QW"@B-<`2AX%T)"(E5[(E%\(-M[`&#?>S_ +XM#X0(`0``.?YR(.FF````C70F`(M5\(M$@C3VQ$!T*(/&!#GW#X:+````BP:I +XM````0'5./?\```!VV8D$).BM./W_]L1`==B+!CW_````=G6)!"3HESC]_^MR +XMBU7PBT2:-/;$0'62@?O_````=S>+5?"+1)HT]L0%#X5Z____@\8$.?!="0B)1>R)5?"#;>P!@WWL_W1E.?YR%>OPBU7PBT2:-/;$0'5`@\8$ +XM.?=VW8L>]\,```!`=>^!^_\```!VVXD<).@\-_W_Z]B+5?"+1)HT]L1`=+6# +XMQ@0Y]W:NBQ[WPP```$!UI('[_P```';;B1PDZ`TW_?^0Z]53B<.#[`2I````0'00@_M?N`,` +XM``!T.X/$!%M=PSW_````=T6AX%T)"(M4F#2`YD"X`0```'7@@_M_=B&!^_\` +XM``!W,:'@70D(BT28-/;$`72[@\0$N`(```!;757B==6B<93@^P< +XMHB%P`^%_````*'@70D(BQ5,=PH(B47PB57L@VWH`8-]Z/\/A!4! +XM```Y_G([Z^R+5?"+1)HT]L0!#X6$````@_M_=PKV!)V]40D(!'5UB5PD!(M% +XM[(D$).C<.?W_A]\,```!`==2!^_\```!VL8D<).@^-?W_ +XMB?;KK(/K`74>B?:-O"<`````ZQ>+!NAG_O__@^@!C70F`'4'@\8$.?=WZ8-M +XMZ`&#?>C_=",Y_G,?BP;H0O[__XG#ZPN+!N@W_O__.<-UM8/&!#GW=^[KK(U& +XM_(/$'%M>7UW#.?>)^';R@\0C#R?__N`X```"#Q`1;7<.#P`2C5)D+ +XM"*'(F0L(A53@^P$ +XMBQU4F0L(BQ4T=PH(.=-T+HL-?'<*"(G8Z.?]__^C5)D+"*'(F0L(A53@^P$BQU4F0L(BQ4T=PH(.=-T18L-?'<*"(G8Z(?]__^)PHG#H529"PCH +XMF>'__RL=5)D+",'[`HD<).AHNO__BQ4T=PH(N`X````Y%529"PAV!HD55)D+ +XM"(/$!%M=PXGVC;PG`````%6)Y5=64X/L/(L5)"<)"(E%S*%4F0L(B574BQ4T +XM9`D(B470H9QW"@B)5>")1=BA-'<*"(/`&(T$D#L%L)@*"`^#8@0``(G0,=N+ +XM=@,``*$T=PH(QP`*````@\`$@_X5HS1W"@BXI.8("'0%N+3F"`B+ +XM$(72=!V)P8GVH31W"@B)$(/`!*,T=PH(BU$$@\$$A=)UYZ$T=PH(BQ4D)PD( +XMB1"#P`2+#3!D"0BC-'<*"*$T9`D(C5$$C02!.<)S+(/!"(M1_*$T=PH(B1"# +XMP`2)RJ,T=PH(H31D"0B#P03!X`(#!3!D"0@YPG+7H31W"@C'``````#'1"0$ +XMQ)@*",<$)"!)"0CH0AS__X7`=`V#/20G"0@Z#X1L`P``Z'QH``"-1?")!"3H +XM(4```(/H`0^%:@4``(M-\('Y``$``']#H7!W"@@/MM$/M@0"/!MT,P^'O`(` +XM`#P"="D\!)`/A<@"```Q_X,]-&0)"`''1=P!````=UKHTW@``,=%W`````#K +XM3*$T=PH(@\`$.P6PF`H(#X-7`@``B4PD!#'_QP0D,&0)".B$)P$`H31W"@B+ +XM5?")$(U0!(D5-'<*",=`!`````#HU6<``,=%W`````"A-'<*"#T`=@D(=Q?K +XM&L<``````(/H!#T`=@D(HS1W"@AV!8,X"G7FQP``````BTWV)1?"#^P$/AKH```"#??!;#X2P````A?]T"3EUS`^$T````,=$)`0J```` +XMQP0D,&0)".B^)@$`QP0D,&0)".@2)P$`H529"P@]`'8)"'(,.P4T=PH(#X:F +XM`@``B?"#_A6B2)D+"`^$)`(``,<$)`````#HKNC__SQD#X0D`@``@_X5N`!V +XM"0@/A&H"``"C5)D+"*$P9`D(B?*#P`3H9-+__XL5-&0)"*$P9`D(@^H!B14T +XM9`D(QP20`````,<%)"<)"#H```")\.CX_/__/&2)PW1'A-MT7(#[9`^4P(M5 +XMX(72#X3B````#[[#@\0\6UY?7<.#/20G"0@_#X0=`@``,<"#_A4/E<"-!,7\ +XM____`054F0L(Z0G___^#/20G"0@_#X4)`0``@WW4.@^%_P```#';BU74BT7@ +XMB14D)PD(BU78.16<=PH(HS1D"0AT$XD5G'<*".A+YO__/&0/A`H!``"+1="` +XM^V2C5)D+"`^$"`,``(M%W(7`#X5J____A-L/A6+___^A-&0)"(7`#X6&_/__ +XMQT0D!"H```#'!"0P9`D(QP4D)PD(.@```.A$)0$`Z6/\___H6G8``#'_QT7< +XM`````)#IS?W__X3`#X06____C78`Z5G___\\8710#X1,`0``B0T49`D(QP0D%&0)".BH +XM/@``NPX````Q_\=%W`$```#I9_W__[@!````Z:/^__^^%@```+\!````QT7< +XM`````.E'_?__H31D"0B#Z`&CV)D+".B#5```Z/Y4``#I>/S__X/$/+AD```` +XM6UY?7<.^%0```+\!````QT7<`````.D(_?__QP0D`````.@*Z/__/&0/A=S] +XM__^+%31D"0BA,&0)"(/J`8D5-&0)",<$D`````#H4G4``(M5V#D5G'<*"'02 +XMBU78B16<=PH(Z,GD__\\9'2,BT70QP4D)PD(/P```*-4F0L(Z<_]__^A-'<* +XM".F,_?__H3!D"0B)\H/`!.CUS___/&0/A8G]___I/OW__S'`@_X5#Y3`@^@! +XM)?___W^CG'<*".ANY/__/&0/A%4!``"#_A6X`'8)"`^$/0$``*-4F0L(Z53@^P4QP4T +XM9`D(`````,8%S)D+"`#H;OC__\=$)`3$F`H(QP0D($D)"(G#Z*@5__^%P'0) +XMH=B9"PB%P'43#[[#QP78F0L(`````(/$%%M=P\<%V)D+"`````#H25$``.C$ +XM40``Z+]A``#KTHVV`````(V\)P````!5B>57B==64X/L'(UP_*'(F0L(B4WH +XMA<`/A=D```"AX%T)"(L53'<*"(E%\(E5[(-MZ`&#?>C_#X0@`0``.?YS.^OL +XMBU7PBT2:-/;$`0^%A````(/[?W<*]@2=O5$)"`1U=8E<)`2+1>R)!"3H*R_] +XM_X7`=6*#[@0Y]W>SBQ[WPP```$!UW('[_P```':UB1PDZ.8J_?_KLHM5\(M$ +XMFC3VQ`%U)H/[?W<*]@2=O5$)"`1U%XE<)`2+1>R)!"3HVB[]_X7`#X1E____ +XM@^X$.?)PW?!@^X$.?=WNHL&Z'SS__\YPW3N@VWH`8-]Z/]U +XML(U&!(/$'%M>7UW#C58$B?@YUW/O@\053@^P$BQU4F0L(@?L` +XM=@D(=#.+#7QW"@BZ`'8)"(G8Z.3]__^C5)D+"*'(F0L(A53@^P$H529 +XM"P@]`'8)"'0TBPU\=PH(N@!V"0CHB/W__XL55)D+"(G#Z.O6__^A5)D+""G8 +XMP?@"B00DZ*FP__^Z#@```(/$!(G06UW#C;8`````C;\`````58GE5E.[`'8) +XM"(/L$*$`=@D(J0```$!U,8LUX%T)".L5BT2&-/;$0'0@@\,$BP.I````0'44 +XM/?\```!VY(D$).B'*/W_]L1`=>`['31W"@BX9````'0=@P5P=@H(`8`%B)@* +XM"`''!"0`````Z(_&__\/OL"#Q!!;7EW#D(UT)@!5N&0```")Y8/L&(EU_(LU +XM5)D+"#LU-'<*"(E=^'-GBQ[WPP```$!U1X'[_P```'=_H>!="0B+1)@T9H7` +XM>%&!^_\```!W?:'@70D(BT28-/;$$'0;@?O_````=WBAX%T)"(N$F#0(``#K +XM.9"-="8`C48$HU29"PC'!"0!````Z+Q@```QP(M=^(MU_(GL7<.!^_\```!W +XM(J'@70D(BX28-`0``(D&C48$HU29"PCKR(D<).B4)_W_ZX")'"3HFBG]_^O@ +XMB1PDZ(`G_?^-="8`Z7O___^)'"3H'R[]_XUV`.O"C;0F`````(V\)P````!5 +XMB>575E.#[`R+#7QW"@B+%31W"@BA5)D+".@1\?__BS54F0L(.?")QW9"D(UT +XM)@"+'O?#````0'4L@?O_````=TZAX%T)"(M$F#1FA!= +XM"0B+A)@T!```B0:#Q@0Y]W?#H31W"@B)/529"P@YQW8%HU29"PB#Q`RX#@`` +XM`%M>7UW#B?:)'"3HQ";]_^NQB1PDZ,HH_?_KP(VV`````(V_`````%6)Y5=6 +XM4X/L#(L-?'<*"(L5-'<*"*%4F0L(Z&'P__^+-529"P@Y\(G'#X:G````H>!= +XM"0B)1?#K'HVT)@````"+5?"+1)HT]L0!=2J#Q@0Y]P^&?P```(L>]\,```!` +XM=>N!^_\```!VUXD<).@[)OW_]L0!=-:!^_\````/AZ$```"+5?"+1)HT]L00 +XM#X5[````@\8$.?=V/8L>]\,```!`=>^!^_\```!W3*'@70D(BT28-&:%P'G9 +XM@?O_````=T"AX%T)"(N$F#0$``")!H/&!#GW=\.A-'<*"(D]5)D+"#G'=@6C +XM5)D+"(/$#+@.````6UY?7<.)'"3HK27]_^NSB1PDZ+,G_?^)!NO"@?O_```` +XM=QN+5?"+A)HT"```B0;KK(D<).B!)?W_Z5G___^)'"3H)"S]_XD&ZY.-="8` +XM58GE5U93@^P,BPU\=PH(BQ4T=PH(H529"PCH(>___XLU5)D+"#GPB<=V0I"- +XM="8`BQ[WPP```$!U+('[_P```'=.H>!="0B+1)@T]L00=!:!^_\```!W0J'@ +XM70D(BX28-`@``(D&@\8$.?=WPZ$T=PH(B3U4F0L(.<=V!:-4F0L(@\0,N`X` +XM``!;7E]=PXGVB1PDZ-0D_?_KL8D<).AZ*_W_Z\"0D)"0D)"0D)"0D)!5,<") +XMY5=64X/L+.L1C78`@\`!/0`!```/A(0```"`N,"K"P@>=>F^P*L+"(E%X(U% +XMX+N`````QT7H`````(U][(E%[,=%\`(```"0C70F``^V%#.-0O\\`78M@/HU +XM="B)V(/@?XE%Y`^V!#.)!"3HK)L``,=$)`@`````B3PDB40D!.@8GP``@\,! +XM@?L``0``=;V+1>#&!#`U@\0L6UY?7<-F,<#K"H/``3T``0``=!.`N,"D"P@> +XM=>V^P*0+".EH____BQ7(F0L(N!L```"^P*0+"(72#X50____Z4;____K#9"0 +XMD)"0D)"0D)"0D)!5B>564X/L$(L=8)D+"(7;=5^+#<"E"PB%R755BS7@70D( +XMNX````#K+(VT)@````"+1)XTJ0``!`!T!\:#P*L+"`*#PP&!^_\```!_&O?# +XM````0'7M@?O_````=M.)'"3H9R/]_^O-QP5`9`D(`0```(/$$%M>7<.0C;0F +XM`````%6)Y5.#[#2-1>B)1?3'1?@"````QP7(F0L(`````.B=GP``,=(/MH)` +XM*0D(QH+`I`L(`8B"P*L+"(/"`8'Z``$``'7AZ$?^__^-7?3H+____\=%Z!@` +XM``#'1?``````QT7L&````,<$)"L```#H/IH``(D<),=$)`@`````B40D!.BJ +XMG0``QT7L*@```,<$)$T```#H%YH``(D<),=$)`@`````B40D!.B#G0``QT7L +XM)````,<$)$X```#H\)D``(D<),=$)`@`````B40D!.AYD``(D< +XM),=$)`@`````B40D!.CGG```QT7L3@```,<$)&<```#H5)D``(D<),=$)`@` +XM````B40D!.C`G```QT7L/P```,<$)&\```#H+9D``(D<),=$)`@`````B40D +XM!.B9G```QT7L"0```,<$)&H```#H!ID``(D<),=$)`@`````B40D!.ARG``` +XMQT7L!````,<$)&L```#HWY@``(D<),=$)`@`````B40D!.A+G```Z.9=``#H +XM,7<``(/$-%M=PXUT)@"-O"<`````58GE@^P(H3QD"0B%P'0"RF?=@``ZPV0D)"0D)"0D)"0D)"058GE4S';@^P4C;0F```` +XM`(N#Z*4+"(/##(D$).C_K0``@?O0!0``=>>A@)@*",=$)`S2Y@@(QT0D"`$` +XM``#'1"0$`P```(D$),<%X*4+",3F"`C'!>2E"P@(````Z.X!_O^)!"3H5JO^ +XM_\=$)`S<\0@(QT0D"`(```#'1"0$`P```,<%[*4+".CF"`C'!?"E"P@$```` +XMH^BE"PBA@)@*"(D$).BH`?[_B00DZ!"K_O_'1"0,`/((",=$)`@#````QT0D +XM!`,```#'!?BE"PC]Y@@(QP7\I0L(&0```*/TI0L(H8"8"@B)!"3H8@'^_XD$ +XM).C*JO[_QT0D#$3R"`C'1"0(!````,=$)`0#````QP4$I@L($N<(",<%"*8+ +XM"!T```"C`*8+"*&`F`H(B00DZ!P!_O^)!"3HA*K^_\=$)`R`\@@(QT0D"`4` +XM``#'1"0$`P```,<%$*8+""7G"`C'!12F"P@.````HPRF"PBA@)@*"(D$).C6 +XM`/[_B00DZ#ZJ_O_'1"0,1><(",=$)`@&````QT0D!`,```#'!1RF"P@SYP@( +XMQP4@I@L(!P```*,8I@L(H8"8"@B)!"3HD`#^_XD$).CXJ?[_QT0D#*3R"`C' +XM1"0(!P```,=$)`0#````QP4HI@L(7^<(",<%+*8+"#@```"C)*8+"*&`F`H( +XMB00DZ$H`_O^)!"3HLJG^_\=$)`SD\@@(QT0D"`@```#'1"0$`P```,<%-*8+ +XM"&_G"`C'!3BF"PA0````HS"F"PBA@)@*"(D$).@$`/[_B00DZ&RI_O_'1"0, +XMD^<(",=$)`@)````QT0D!`,```#'!4"F"PA[YP@(QP5$I@L(1````*,\I@L( +XMH8"8"@B)!"3HOO_]_XD$).@FJ?[_QT0D#"CS"`C'1"0("@```,=$)`0#```` +XMQP5,I@L(K.<(",<%4*8+"!````"C2*8+"*&`F`H(B00DZ'C__?^)!"3HX*C^ +XM_\=$)`S'YP@(QT0D"`L```#'1"0$`P```,<%6*8+"+GG"`C'!5RF"P@1```` +XMHU2F"PBA@)@*"(D$).@R__W_B00DZ)JH_O_'1"0,[^<(",=$)`@,````QT0D +XM!`,```#'!62F"PC=YP@(QP5HI@L(;````*-@I@L(H8"8"@B)!"3H[/[]_XD$ +XM).A4J/[_QT0D#!SH"`C'1"0(#0```,=$)`0#````QP5PI@L(">@(",<%=*8+ +XM"&T```"C;*8+"*&`F`H(B00DZ*;^_?^)!"3H#JC^_\=$)`Q4\P@(QT0D"`X` +XM``#'1"0$`P```,<%?*8+"#?H"`C'!8"F"PAJ````HWBF"PBA@)@*"(D$).A@ +XM_OW_B00DZ,BG_O_'1"0,6.@(",=$)`@/````QT0D!`,```#'!8BF"PA)Z`@( +XMQP6,I@L(2P```*.$I@L(H8"8"@B)!"3H&O[]_XD$).B"I_[_QT0D#(SS"`C' +XM1"0($````,=$)`0#````QP64I@L(=.@(",<%F*8+"#(```"CD*8+"*&`F`H( +XMB00DZ-3]_?^)!"3H/*?^_\=$)`R\\P@(QT0D"!$```#'1"0$`P```,<%H*8+ +XM"(CH"`C'!:2F"PAP````HYRF"PBA@)@*"(D$).B._?W_B00DZ/:F_O_'1"0, +XME^@(",=$)`@2````QT0D!`,```#'!:RF"PCQY@@(QP6PI@L(!0```*.HI@L( +XMH8"8"@B)!"3H2/W]_XD$).BPIO[_QT0D#/#S"`C'1"0($P```,=$)`0#```` +XMQP6XI@L(M>@(",<%O*8+"&@```"CM*8+"*&`F`H(B00DZ`+]_?^)!"3H:J;^ +XM_\=$)`PX]`@(QT0D"!0```#'1"0$`P```,<%Q*8+",CH"`C'!I?[_QT0D#,3T"`C'1"0(%@```,=$)`0#````QP7RF"P@;````H^2F"PBA@)@*"(D$).CJ +XM^_W_B00DZ%*E_O_'1"0,#.D(",=$)`@8````QT0D!`,```#'!?2F"PC]Z`@( +XMQP7XI@L(,````*/PI@L(H8"8"@B)!"3HI/O]_XD$).@,I?[_QT0D#"?I"`C' +XM1"0(&0```,=$)`0#````QP4`IPL(QNL(",<%!*<+"!0```"C_*8+"*&`F`H( +XMB00DZ%[[_?^)!"3HQJ3^_\=$)`PL]0@(QT0D"!H```#'1"0$`P```,<%#*<+ +XM"$'I"`C'!1"G"P@W````HPBG"PBA@)@*"(D$).@8^_W_B00DZ("D_O_'1"0, +XM6^D(",=$)`@;````QT0D!`,```#'!1BG"PA/Z0@(QP4````QT0D +XM!`,```#'!3RG"PC`Z0@(QP5`IPL(30```*,XIPL(H8"8"@B)!"3H`/K]_XD$ +XM).AHH_[_QT0D#/;I"`C'1"0('P```,=$)`0#````QP5(IPL(Y^D(",<%3*<+ +XM"$<```"C1*<+"*&`F`H(B00DZ+KY_?^)!"3H(J/^_\=$)`QH]0@(QT0D""`` +XM``#'1"0$`P```,<%5*<+"`WJ"`C'!5BG"PA1````HU"G"PBA@)@*"(D$).AT +XM^?W_B00DZ-RB_O_'1"0,*NH(",=$)`@A````QT0D!`,```#'!6"G"P@9Z@@( +XMQP5DIPL(3@```*-*<+ +XM"&/J"`C'!7RG"P@/````HW2G"PBA@)@*"(D$).BB^/W_B00DZ`JB_O_'1"0, +XMM/4(",=$)`@D````QT0D!`,```#'!82G"PAPZ@@(QP6(IPL(,P```*.`IPL( +XMH8"8"@B)!"3H7/C]_XD$).C$H?[_QT0D#.3U"`C'1"0()0```,=$)`0#```` +XMQP60IPL(B.H(",<%E*<+"!4```"CC*<+"*&`F`H(B00DZ!;X_?^)!"3H?J'^ +XM_\=$)`P@]@@(QT0D""8```#'1"0$`P```,<%G*<+"*#J"`C'!:"G"P@6```` +XMHYBG"PBA@)@*"(D$).C0]_W_B00DZ#BA_O_'1"0,6/8(",=$)`@G````QT0D +XM!`,```#'!:BG"PBWZ@@(QP6LIPL(+````*.DIPL(H8"8"@B)!"3HBO?]_XD$ +XM).CRH/[_QT0D#,CJ"`C'1"0(*````,=$)`0#````QP6TIPL(;/`(",<%N*<+ +XM"&$```"CL*<+"*&`F`H(B00DZ$3W_?^)!"3HK*#^_\=$)`SCZ@@(QT0D""D` +XM``#'1"0$`P```,<%P*<+"$+P"`C'!<2G"PAB````H[RG"PBA@)@*"(D$).C^ +XM]OW_B00DZ&:@_O_'1"0,#>L(",=$)`@J````QT0D!`,```#'!BG"P@Q````H^"G"PBA@)@*"(D$).@L]OW_B00DZ)2?_O_'1"0, +XMY/8(",=$)`@M````QT0D!`,```#'!?"G"P@DZP@(QP7TIPL(/0```*/LIPL( +XMH8"8"@B)!"3HYO7]_XD$).A.G_[_QT0D#$'K"`C'1"0(+@```,=$)`0#```` +XMQP7\IPL(-.L(",<%`*@+"!@```"C^*<+"*&`F`H(B00DZ*#U_?^)!"3H")_^ +XM_\=$)`P0]P@(QT0D""\```#'1"0$`P```,<%"*@+"%WK"`C'!0RH"PAK```` +XMHP2H"PBA@)@*"(D$).A:]?W_B00DZ,*>_O_'1"0,4/<(",=$)`@P````QT0D +XM!`,```#'!12H"PANZP@(QP48J`L(1@```*,0J`L(H8"8"@B)!"3H%/7]_XD$ +XM).A\GO[_QT0D#'#W"`C'1"0(,0```,=$)`0#````QP4@J`L(Z^@(",<%)*@+ +XM"$4```"C'*@+"*&`F`H(B00DZ,[T_?^)!"3H-I[^_\=$)`RT]P@(QT0D"#(` +XM``#'1"0$`P```,<%+*@+"'CK"`C'!3"H"PA2````HRBH"PBA@)@*"(D$).B( +XM]/W_B00DZ/"=_O_'1"0,Y/<(",=$)`@S````QT0D!`,```#'!3BH"PB%ZP@( +XMQP4\J`L(2````*,TJ`L(H8"8"@B)!"3H0O3]_XD$).BJG?[_QT0D#)GK"`C' +XM1"0(-````,=$)`0#````QP5$J`L(D>L(",<%2*@+"`,```"C0*@+"*&`F`H( +XMB00DZ/SS_?^)!"3H9)W^_\=$)`P0^`@(QT0D"'H```#'1"0$`P```,<%4*@+ +XM"*GK"`C'!52H"PAX````HTRH"PBA@)@*"(D$).BV\_W_B00DZ!Z=_O_'1"0, +XM./@(",=$)`A[````QT0D!`,```#'!5RH"PBZZP@(QP5@J`L(>0```*-8J`L( +XMH8"8"@B)!"3H2H"P@J```` +XMH]RH"PBA@)@*"(D$).AN\/W_B00DZ-:9_O_'1"0,V/D(",=$)`A`````QT0D +XM!`,```#'!>RH"PBW[`@(QP7PJ`L($@```*/HJ`L(H8"8"@B)!"3H*/#]_XD$ +XM).B0F?[_QT0D#`#Z"`C'1"0(00```,=$)`0#````QP7XJ`L(PNP(",<%_*@+ +XM"$P```"C]*@+"*&`F`H(B00DZ.+O_?^)!"3H2IG^_\=$)`PD^@@(QT0D"$(` +XM``#'1"0$`P```,<%!*D+",WL"`C'!0BI"PAI````HP"I"PBA@)@*"(D$).B< +XM[_W_B00DZ`29_O_'1"0,3/H(",=$)`A#````QT0D!`,```#'!1"I"PC8[`@( +XMQP44J0L(3P```*,,J0L(H8"8"@B)!"3H5N_]_XD$).B^F/[_QT0D#(3Z"`C' +XM1"0(1````,=$)`0#````QP4.H(",<%(*D+""````"C&*D+"*&`F`H( +XMB00DZ!#O_?^)!"3H>)C^_\=$)`RT]0@(QT0D"$4```#'1"0$`P```,<%**D+ +XM"._L"`C'!2RI"P@S````HR2I"PBA@)@*"(D$).C*[OW_B00DZ#*8_O_'1"0, +XM"^T(",=$)`A&````QT0D!`,```#'!32I"P@![0@(QP4XJ0L((P```*,PJ0L( +XMH8"8"@B)!"3HA.[]_XD$).CLE_[_QT0D##KM"`C'1"0(1P```,=$)`0#```` +XMQP5`J0L(*>T(",<%1*D+""0```"C/*D+"*&`F`H(B00DZ#[N_?^)!"3HII?^ +XM_\=$)`QA[0@(QT0D"$@```#'1"0$`P```,<%3*D+"%7M"`C'!5"I"P@-```` +XMHTBI"PBA@)@*"(D$).CX[?W_B00DZ&"7_O_'1"0,A>T(",=$)`A)````QT0D +XM!`,```#'!5BI"PAY[0@(QP5X(",<%C*D+"`$```"CA*D+"*&`F`H( +XMB00DZ)KL_?^)!"3H`I;^_\=$)`S(^@@(QT0D"$X```#'1"0$`P```,<%E*D+ +XM"#_N"`C'!9BI"P@I````HY"I"PBA@)@*"(D$).A4[/W_B00DZ+R5_O_'1"0, +XM7>X(",=$)`A/````QT0D!`,```#'!:"I"PA2[@@(QP6DJ0L($P```*.^X(",<%L*D+"#8```"CJ*D+"*&`F`H(B00DZ,CK_?^)!"3H,)7^ +XM_\=$)`PP^P@(QT0D"%$```#'1"0$`P```,<%N*D+"(?N"`C'!;RI"P@\```` +XMH[2I"PBA@)@*"(D$).B"Z_W_B00DZ.J4_O_'1"0,5/L(",=$)`A2````QT0D +XM!`,```#'!<2I"PBA[@@(QP7(J0L(.@```*/`J0L(H8"8"@B)!"3H/.O]_XD$ +XM).BDE/[_QT0D#'S["`C'1"0(4P```,=$)`0#````QP70J0L(J.X(",<%U*D+ +XM"#L```"CS*D+"*&`F`H(B00DZ/;J_?^)!"3H7I3^_\=$)`SD\@@(QT0D"%0` +XM``#'1"0$`P```,<%W*D+"+;N"`C'!>"I"PA0````H]BI"PBA@)@*"(D$).BP +XMZOW_B00DZ!B4_O_'1"0,SNX(",=$)`A5````QT0D!`,```#'!>BI"PC"[@@( +XMQP7LJ0L(8````*/DJ0L(H8"8"@B)!"3H:NK]_XD$).C2D_[_QT0D#)/G"`C' +XM1"0(5@```,=$)`0#````QP7TJ0L(Y^X(",<%^*D+"$0```"C\*D+"*&`F`H( +XMB00DZ"3J_?^)!"3HC)/^_\=$)`R@^P@(QT0D"%<```#'1"0$`P```,<%`*H+ +XM"/7N"`C'!02J"P@N````H_RI"PBA@)@*"(D$).C>Z?W_B00DZ$:3_O_'1"0, +XMV/L(",=$)`A8````QT0D!`,```#'!0RJ"P@![P@(QP40J@L(2@```*,(J@L( +XMH8"8"@B)!"3HF.G]_XD$).@`D_[_QT0D#`#\"`C'1"0(60```,=$)`0#```` +XMQP48J@L(%N\(",<%'*H+"%,```"C%*H+"*&`F`H(B00DZ%+I_?^)!"3HNI+^ +XM_\=$)`PL[P@(QT0D"%H```#'1"0$`P```,<%)*H+""'O"`C'!2BJ"PA4```` +XMHR"J"PBA@)@*"(D$).@,Z?W_B00DZ'22_O_'1"0,+/P(",=$)`A;````QT0D +XM!`,```#'!3"J"PA%[P@(QP4TJ@L(5P```*,LJ@L(H8"8"@B)!"3HQNC]_XD$ +XM).@NDO[_QT0D#&3\"`C'1"0(7````,=$)`0#````QP4\J@L(4.\(",<%0*H+ +XM"%@```"C.*H+"*&`F`H(B00DZ(#H_?^)!"3HZ)'^_\=$)`R,_`@(QT0D"%T` +XM``#'1"0$`P```,<%2*H+"%GO"`C'!4RJ"PA?````HT2J"PBA@)@*"(D$).@Z +XMZ/W_B00DZ**1_O_'1"0,N/P(",=$)`A>````QT0D!`,```#'!52J"PAF[P@( +XMQP58J@L(7@```*-0J@L(H8"8"@B)!"3H].?]_XD$).A\(",=$)`AA````QT0D!`,```#'!7BJ"PB/[P@(QP5\J@L(+P```*-TJ@L( +XMH8"8"@B)!"3H(N?]_XD$).B*D/[_QT0D#$3]"`C'1"0(8@```,=$)`0#```` +XMQP6$J@L(KN\(",<%B*H+"#\```"C@*H+"*&`F`H(B00DZ-SF_?^)!"3H1)#^ +XM_\=$)`QP_0@(QT0D"&,```#'1"0$`P```,<%D*H+"+_O"`C'!92J"PAC```` +XMHXRJ"PBA@)@*"(D$).B6YOW_B00DZ/Z/_O_'1"0,L/T(",=$)`AD````QT0D +XM!`,```#'!9RJ"PC2[P@(QP6@J@L(9````*.8J@L(H8"8"@B)!"3H4.;]_XD$ +XM).BXC_[_QT0D#/3]"`C'1"0(90```,=$)`0#````QP6HJ@L(YN\(",<%K*H+ +XM"%P```"CI*H+"*&`F`H(B00DZ`KF_?^)!"3H?`(",=$)`AJ````QT0D!`,```#'!>2J"PAK\`@(QP7HJ@L(6P```*/@J@L( +XMH8"8"@B)!"3HK.3]_XD$).@4CO[_QT0D#*S^"`C'1"0(:P```,=$)`0#```` +XMQP7PJ@L(D_`(",<%]*H+"$,```"C[*H+"*&`F`H(B00DZ&;D_?^)!"3HSHW^ +XM_\=$)`RY\`@(QT0D"&P```#'1"0$`P```,<%_*H+"*;P"`C'!0"K"PA"```` +XMH_BJ"PBA@)@*"(D$).@@Y/W_B00DZ(B-_O_'1"0,W?`(",=$)`AM````QT0D +XM!`,```#'!0BK"PC0\`@(QP4,JPL(5@```*,$JPL(H8"8"@B)!"3HVN/]_XD$ +XM).A"C?[_QT0D#`;Q"`C'1"0(;@```,=$)`0#````QP44JPL(^O`(",<%&*L+ +XM"%4```"C$*L+"*&`F`H(B00DZ)3C_?^)!"3H_(S^_\=$)`PG\0@(QT0D"&\` +XM``#'1"0$`P```,<%(*L+"!_Q"`C'!22K"PA9````HQRK"PBA@)@*"(D$).A. +XMX_W_B00DZ+:,_O_'1"0,0_$(",=$)`AP````QT0D!`,```#'!2RK"P@[\0@( +XMQP4PJPL(.0```*,HJPL(H8"8"@B)!"3H"./]_XD$).APC/[_QT0D#.C^"`C' +XM1"0(<0```,=$)`0#````QP4XJPL(8?$(",<%/*L+""$```"C-*L+"*&`F`H( +XMB00DZ,+B_?^)!"3H*HS^_\=$)`P,_P@(QT0D"'(```#'1"0$`P```,<%1*L+ +XM"&_Q"`C'!4BK"P@B````HT"K"PBA@)@*"(D$).A\XOW_B00DZ.2+_O_'1"0, +XM,/\(",=$)`AS````QT0D!`,```#'!5"K"PAT\0@(QP54JPL(=P```*-,JPL( +XMH8"8"@B)!"3H-N+]_XD$).B>B_[_QT0D#&C_"`C'1"0(=````,=$)`0#```` +XMQP5AD"0BC*&4)"*'`+0D( +XM]]`C!0!E"0@+!;PM"0BC`&4)"*',+0D(]]`C!01E"0@+!<@M"0BC!&4)"*'8 +XM+0D(]]`C!0AE"0@+!=0M"0BC"&4)"*'D+0D(BPW\70D(]]`C!0QE"0@+!>`M +XM"0B%R:,,90D(=2JAM'8*",=$)`0`90D(B00DZ'*$``"#P`$/A`C____'!61D +XM"0@!````R<.A1)D+".O4C;8`````58GE4X'L)"```*%H9`D(QT7X`````(7` +XM=`B)!"3H_HD``(L58&0)"#'`QP5H9`D(`````(72=`F!Q"0@``!;7<.-1?B) +XM1"0(H;1V"@C'1"0$?V8$0(D$).B__/S_BT7XAB-==B) +XM'"3HC`#]_\=$)`0"````B1PDZ(S[_/^)="0(B5PD!,<$)`$```#H*/O\_\=$ +XM)`1@'@4(B30DZ&Q^_?^+#?Q="0B%R70ZH429"PC'1"0$@&0)"(D$).C]@@`` +XMB30DB2L)",<$),!D"0CH +XMOWX``(LU="T)"#')BQUX+0D(#[8]<&0)"+@!````T^"%QG45#[:1DBL)"#J1 +XM8"L)"'0&B)%@*PD(A<-T"(GXB(%@*PD(@\$!@_D9='^_XD$).@]W_[_B00DZ(6W__^+-?Q="0B%]@^$ +XM]@$``*%$F0L(QT0D!(!D"0B)!"3HHGX``(/``0^$+@(``*&`9`D(BPV<9`D( +XMBQ6D9`D(BQV@9`D(H\!D"0BAA&0)"(L]D&0)"(LUF&0)"(D-W&0)"*/$9`D( +XMH8AD"0B)%>1D"0B)'>!D"0B)/=!D"0BCR&0)"*&,9`D(B3789`D(B3T090D( +XMH\QD"0BAE&0)"*/49`D(H:AD"0BCZ&0)"*&`9`D(HP!E"0BAA&0)"*,$90D( +XMH8AD"0BC"&4)"*&,9`D(HPQE"0BAE&0)"*,490D(B34890D(H:AD"0B)#1QE +XM"0B)%21E"0B)'2!E"0BC*&4)",<$)(!D"0CH.WT``,<$)(!D"0BC:)D+".C: +XM?```QP0D@&0)"*+`F0L(Z.E\``"+70BC1"L)"*%(+0D(]]`C!8!D"0@+!40M +XM"0BC@&0)"*%4+0D(]]`C!81D"0@+!5`M"0BCA&0)"*%@+0D(]]`C!8AD"0@+ +XM!5PM"0BCB&0)"*%L+0D(]]`C!8QD"0@+!6@M"0B%VZ.,9`D(=7;'1"0$8"L) +XM",<$)(!D"0CHN7L``(U=Y,=$)`0`G@<(QP0D'````.A>^?S_B1PDZ.;Y_/_' +XM1"0$'````(D<).CF]/S_QT0D"`````")7"0$QP0D`@```.A^]/S_,<#'!6QD +XM"0@!````Z6S]__^AM'8*".D%_O__QP0D`&4)".@;?```AP``BPW\70D(A2L)"'0&B)!Y*PD(@\`!@_@7==\PP`^VD)(K"0@X +XMT70..HA@*PD(=`:(D&`K"0B#P`&#^!EUW^DF____C;8`````C;PG`````%6) +XMY8/L",<$)`$```#H#O7__\<%A'<*"`````#'!"0`````Z"C\__^#P`%T?:%@ +XM90D(AJ&$+0D(QT0D!'DK"0C'!"3`9`D(]]`C!0``R<.-="8`Z'M*``#I +XM?/___XVV`````%6)Y8/L&,=$)`2PD`@(@P7$K`L(`<<$),2L"PCHWW7]_XU% +XM^(E$)`2-1?R)!"3H;30``(7`=0>+10B%P'1"H81W"@B%P'11Z(08``#H_Q@` +XM`,<$)`````#HDT,``,<$)`````#H9T$``(M%^(E$)`2+1?R)!"3HI2\``.C0 +XM*```QP0DQ*P+",<%M)D+"`````#HRG3]_\G#BT7XB40D!(M%_(D$).AV+P`` +XMZ]20D)"058GEBT4(78L0B15(=PH(BT`$QP7\F`H(`````*-(F@L(PXVT)@`` +XM``"-O"<`````58GEBT4(7<<%-&4)"`$```"C,&4)",.)]HV\)P````!5B>57 +XM5E.#["R+/31E"0B+=0B%_W1%H3!E"0B_`0```,<%-&4)"`````")!H/$+(GX +XM6UY?7+__S\`@\`$B1:+%4`K"0B_`0```(D$C8"9"PB+!)6`F0L( +XMBPB%R76;C4+_HT`K"0B#Q"R)^%M>7UW#Z(CV__\Q_X7`#XAZ____H;29"PB% +XMP`^%P0```,=%X``````QVXU%[@'8B40D!*&T=@H(QT0D"`$```")!"3H&G3^ +XM_X/X_XG'=&.A8)D+"(7`#X6;````@\,!C47NB5PD"(E$)`2)-"3H$.X``(/` +XM`0^%$____\=$)`@`````QT0D!`````#'!"0`````Z)?Q_/\['8!1"0ARBP^V +XM1>X-```@`(D&Z=_^__^-=@"+5>"%TG5)Z+#S_/^+`(E$)`2AM'8*"(D$).AA +XME@``@\`!="S'1>`!````Z4C____'!"0`````Z'3]__^-="8`Z2K___\/MD7N +XMB0;IC/[__\<&`````.F!_O__D(UT)@!5B>6#[`B+50B%TG0*H4`K"0B#^`A^ +XM"^@T-P``R>ENC/[_@\`!HT`K"0B)%(6`F0L(R<.-M@````"-O"<`````58GE +XM@^P(H;"9"PB%P'04Z,P5``#H1Q8``,<%L)D+"`````#H."8``*$T=PH(QP5\ +XM=PH(`0```,<%1'<*"`````#'!>@D"0C_____R2T`=@D(P?@"PXUT)@"-O"<` +XM````58GE5U:^`0```%.[`'8)"(/L'(L]-'<*"(E%Z*%4F0L(QT7L`````(E% +XM\(L3A=)X,O?"````0'4J@_I_?R4/ML(/MX0`X"`)"*@0#X35````@_HC#X3, +XM````@\,$BQ.%TGG.B1U4F0L(BQ.)V872=$XYRW0&@WG\7'0UA=*-=@!X+O?" +XM````0'4F@_I_C78`?QX/ML(/MX0`X"`)"*@0=`6#^B-U*_;$('4FD(UT)@"# +XMP02)#529"PB+$872=;*A-'<*"#'VHU29"PB#>/P*=$NAC)@*"*/`*PD(H42: +XM"PBCQ"L)"(L#QP0DP"L)"(E$)`3H]?+\_X7`=#J%]HL=5)D+"`^%(O___XM% +XM\*-4F0L(BT7L@\0<6UY?7<.#Z`2C5)D+".NK]L0@#X4K____D.DN____BT7H +XMAT[__X/X_W0I@^@!=0?'1>P!````BQ4T=PH(.?IT##M= +XM\','B=`I^`%%\(G7Z5C___^#?>P!&<`)1>SKV(GV58GE5U93@>R,````H<27 +XM"@C'19@`````A<`/A/,$``#'1"0$Q)@*",<$),!$"0CHS-?^_\=$)`3$F`H( +XMQP0D($4)"(E%G.BUU_[_QT0D!,28"@C'!"1@1PD(B46@Z)[7_O^)PZ$\9`D( +XMA<`/A)@$``#HVA,``,<$)`````#HWN[__X,]A'<*"`$9P/?0"05`*PD(A=MT +XM*HL#AW\_X7`#X5X!```QP4`F0H(`````*%@ +XM9`D(AR!^O\````/C]<```"A<'<*"`^V +XM'`*`^S4/A-,```"$VP^4P#'2BPTXF@L(AC2$0`` +XMB?;H2Q(``.A&(@``QP5$=PH(`````,<%?'<*"`$```#HW3(``.@8B/[_QP7H +XM)`D(_____Z$T=PH(+0!V"0C!^`*)1;#IK@4``+L"````,<`QTNDT____C57L +XMB578C47@C578QT7<`0```(E$)`2)%"3H_&<``(/X`0^$(`$``(/X`G13A"$VP^4P(#[-0^4PNGO_O__/?___W\/A`C____HAN___\<%A'<*"``` +XM``#HAX?^_X'$C````(G86UY?7<,/ML#_)(7@`0D(Z$?L_/^+=>#'!"0*```` +XMZ(R)_O_'1=0`````B770C770Z#KO___'!81W"@@`````B30DZ-@%_O^%P`^% +XMI````(DT).CH^___QT0D!,28"@C'!"1`0PD(Z-G2_O^) +XM19CI\?K__\=$)`2@1PD(B1PDZ*WH_/^%P`^%>OO__\<%`)D*"`$```#I:_O_ +XM_XU%Z(E$)`BAM'8*",=%Z`````#'1"0$?V8$0(D$).@#Z?S_BW7HA?8/A53[ +XM___HI^W__S';A<`/B47[___I(?W__XM%F,<%Z"0)"/____^%P`^$7`8``(M5 +XMF(L"A<`/A$\&``"+,,=$)`1@0PD(B30DZ"#H_/^%P`^$S08``,=$)`1P0PD( +XMB30DZ`CH_/^%P`^$M08``,=$)`3`0PD(B30DZ/#G_/^%P`^%!08``(LU-'<* +XM"('^`'8)"'8B@W[\"G4?Q<=#:%THUT)@!X+O?"````0'4F@_I_ +XMC78`?QX/ML(/MX0`X"`)"*@0=`6#^B-U+_;$('4JD(UT)@"#P02)#529"PB+ +XM$872=;&A-'<*"#'_HU29"PB#>/P*#X2!!0``BP;'!"3`*PD(B40D!.@EZ_S_ +XMA<`/A.<%``"%_XLU5)D+"`^%)____XM%N+X!````QP748PD(`````*-4F0L( +XMH;"9"PB%P'04Z'X,``#H^0P``,<%L)D+"`````#HZAP``(/N`<<%?'<*"`$` +XM``#'!41W"@@`````#X6O^O__Z$@-``"A-'<*"(UP!,<`"@```(DU-'<*",=` +XM!`````"+-31W"@B)\H'J`'8)",'Z`HE5L.E?!```C70F`,=$)`@)````H529 +XM"PC'!"0`=@D(+0!V"0C!^`*)1"0$Z%M&__^%P`^.N0(``.C^]?__B46P@?O_ +XM__]_#X0O^?__Z9_Z___'!"0*````C78`Z%N$_O^A-'<*",=$)`@%````QP0D +XM`'8)""T`=@D(P?@"B40D!.@&1O__Z!$<``"A-'<*",<%?'<*"`$```#'!41W +XM"@@`````QP7H)`D(_____RT`=@D(P?@"B46PZX8QV\<%Z"0)"/_____I)?K_ +XM_XGZ@/H2#X3(`P``#X\,!@``@/H##X4V^O__BS4T=PH(QP7H)`D(_____\<% +XM+&4)"`````#'1:P"````B?*!Z@!V"0C!^@*)5;"+5;"+!)4`=@D(A`"`054F0L(B34T=PH(QT0D!,28"@C'!"1`1`D(Z)[. +XM_O^%P'0,QP0D`````.@^C___H529"PB+5:S'!"0`=@D(+0!V"0C!^`*)19") +XM5"0(B40D!.BG1/__A<`/A=,#``"+3:"%R70WBU6@BP*%P'0NBSC'1"0$8$4) +XM"(D\).@IY/S_A*$L90D(AX`=@D(B76PP7VP`NAZ&``` +XMQP5\=PH(`0```,<%1'<*"`````#I!OS__\=$)`@'````Z87^___'1"0("``` +XM`.F_^___Z,((``"+-31W"@C'1;``````B?.!ZP!V"0C!^P+'1"0$`````,<$ +XM)`$```#'!?!="0@`````QP6<=PH(`````.@RS```Z:+[__^+-31W"@C'!>@D +XM"0C_____QP4L90D(`````,=%K`,```")\"T`=@D(P?@"B46PZ4/\__^#Z`2C +XM5)D+".ER^O__]L0@#X7G^?__Z>OY___H*@@``,<$)`!V"0CH#ML``,=$)`0P +XM*@@(B<>)!"3H/&3]_Z$T=PH(BU68QT0D!&!#"0B)1:2+`HL`B00DZ`GA_/^% +XMP`^4P`^VP.A@\?__@^@!#X0\`@``B3PDZ%]C_?_I"/___\=$)`0`=@D(B30D +XMZ'H0__^%P`^$`?K__Z%4F0L(QT0D"`(```#'!"0`=@D(+0!V"0C!^`*)1"0$ +XMZ/U`__^%P`^.EP,``(/H`0^/2`,``(L5-'<*"#M5M'0-.W6X@D"0@!BS4T=PH(QP4L90D(`0```,=%K`0```#I^_G__Z'88PD( +XMA<`/A`G[__^+?:"%_P^$_OK__XM5H(L"A<`/A/'Z___'1"0$P$4)"(L`B00D +XMZ.?>_/^%P`^%U_K__^G-^O__@P7H)`D(`8LU-'<*",<%+&4)"`$```#'1:P$ +XM````Z93Y___HE@4``,<$)`!V"0CH>M@``,=$)`0P*@@(B<:)!"3HJ&']_\=$ +XM)`0*````B30DZ-3B_/_'``````"A-'<*",<%-'<*"`!V"0B)1:CH>R4``(DT +XM).A3V@``QP0D`@```(E$)`3HX\@``(DT).B[8/W_Z*84``"-1?.)1"0$H;1V +XM"@C'1"0(`0```(D$).@Z8?[_A<`/B-,!```/MD7S@_AYB47L='N#^"!T=HE\ +XM)`3'!"0`=@D(Z*W=_/^+1:2C-'<*"(M%[(/X90^$L@$``(/X80^$.P$``,=$ +XM)`RR`0D(QT0D"`4```"A@)@*",=$)`0&````B00DZ'^__?^)!"3H%[D``.@" +XM>O[_B?;IM/S__^BV)```C;8`````Z6_[__^+5:C'1"0,H`$)",=$)`@"```` +XMB14T=PH(ZZS'!>@D"0C_____Z6#Y___'1"0$P$4)"(D\).A=W?S_A<`/A4WY +XM___I0_G__\<%U&,)"`````"^`@```.@@!```H8"8"@C'1"0,RP$)",=$)`@' +XM````QT0D!`8```")!"3HV[[]_XD$).ASN```Z6+V___'!=1C"0@`````,?;H +XMW0,``*&`F`H(QT0D#+8!"0C'1"0(!@```,=$)`0&````B00DZ)B^_?^)!"3H +XM,+@``.D?]O__Q@7,F0L(`.B?`@``Z!H#``#H%1,``,8%S)D+"`'I[?S__Z&` +XMF`H(QT0D#*L!"0C'1"0(!````,=$)`0&````B00DZ$2^_?^)!"3HW+<``,<% +XM-'<*"`!V"0C'!529"P@`=@D(QT0D!`````#'!"0`````Z.3&``#HKQ(``(D\ +XM).BW7OW_QT6P`````.E[[___H8"8"@C'1"0,I0$)",=$)`@#````QT0D!`8` +XM``")!"3HUKW]_XD$).ANMP``H31W"@C'``````"-"7"@A_X(L]2&4)"(7;C02]`````(E%\*&P +XM=@H(BP2XB320=#R-2_^#P@&%R8E5[(D51&4)"'XIP>("H;!V"@B+=?"+!`;' +XM!!#___\'@\($@^D!=>:+5>R-1!K_HT1E"0B+%>"7"@@Y%41E"0A\)*&P=@H( +XMBTWPBP0!QP20`````(U'`<<%1&4)"`````"C2&4)"(/$"%M>7UW#C70F`(V\ +XM)P````!5B>575E.)TX/L"(MU#(E%[(M]"(7V?F&)R"G0.<9^!H7`?E6)QHM% +XM[(T,B(G*@^H$C02U`````"G"BT7LB4WPC1R8.=IR#XL"@^H$B4'\@^D$.=IS +XM\8M%\#G8QP``````=A:%]GX2BP>#[@&#QP2)`X/#!#E=\'?J@\0(6UY?753B<-T'XL"AE;7<-5B>53@^P$H=R7"@B%P'0_BQTX90D(A=MX+XVV +XM`````(D<)(/K`>CU*@``QP0D`````.C)*```H>"7"@B)!"3H3"(``(/[_W77 +XM@\0$6UW#H3AE"0B)!"3HQ"H``,<$)`T```#HB'?^_\<$)`H```#H?'?^_X/$ +XM!%M=PXVV`````%6)Y5.#[!2+%`"B40D",=$)`0`````B10DZ/W;_/\Y +XM'DZ=?[_C78`C;PG`````%6)Y5=64X/L+(7)B47DB")3?`/ +XMA:`!``"A/&4)"(7`B47B+1>"+#4!E"0B-5`,$BUWRCP*P+"(7;#X36`0``C47P.T7L#X38`0``BT7P)?____O!X`0!PJ$\ +XM90D(B57LB47@>C1P0P?L"@?O___\##X]*`0``BTWLAR)1"0$B=#!X`(#!<"L"PB)!"3H1=[\_XM5Z`$5/&4)"(L- +XM/&4)"(E-W(M%X(E$)`B+5>2)5"0$BT7

`"`P7`K`L(B00DZ!'>_/^+5>`# +XM%3QE"0B-#)4`````D(UT)@"AP*P+"(/"`<<$"`````"#P03VP@-UZ8G8B14\ +XM90D(#0````2#Q"Q;7E]=PZD````$#X6O````C57PQT7H`0```(E5[(L=/&4) +XM"(7;B5W<#XZ1_O__BSW`K`L(,=N+1>B+5>"--(R)!"3H%-G\_X7`==2+5>")="0$ +XMB50D"(M-Y(D,).CZV/S_A@>`=C!^`(- +XM````!.E+____@\0LN#\```!;7E]=PXL-P*P+""7____[P>`$`R)!"3H +XM^];\_XE%Z.D[____B?B#Q"S!^!_!Z!X!^%M>7UW!^`(-````!,.+%3QE"0B) +XM5=SI0/[__XL-/&4)"(E-W.DR_O__D%6)Y5=64X/L'(E%Z(L`B<$E__\_`('A +XM``#`_XE-\(E%[(E4)`2)!"3H$Z4``(G#C4`'@_@'=AF+3>B)VHL!Z`WZ__^# +XMQ!RX`0```%M>7UW#_R2%C`,)"+H!````N"````#HZOG___8%1&4)"`=UZ.O2 +XMBT7PN@$```"#R%SHS_G__XM%[+H!````P?@&@^`'@\`P"T7PZ+;Y__^+1>RZ +XM`0```,'X`X/@!X/`,`M%\.B=^?__N@$```"#9>P'BT7L@\`P"T7PZ(;Y__^# +XMQ!RX`0```%M>7UW#BT7PN@$```"#R%SH:?G__XM%\+H!````@\A5Z%GY__^+ +XM1?"Z`0```(/(*^A)^?__C03=`````/?8B<.#ZQP/B"C___^0C70F`(M%[(G9 +XMN@$```#3^(/@#P^^@'@#"0@+1?#H$OG__X/K!'G=@\0Z,GX__^#?>Q_#X2I````BT7LN@$````)1?"#3?!`BT7PZ*CX__^#Q!RX +XM`0```%M>7UW#BS5(90D(BQ5$90D(BSVP=@H(ZQJ-M"8`````C1RU`````(L$ +XM'X$\D/___P=U+X/J`7GH@^X!#XB`_O__BP2WC1RU`````(D$).BYU/S_C5#_ +XMBP0?@3R0____!W31A?8/B%?^__^-')4`````BT7HN@$````#'+>+"^C]^O__ +XMB0/I"?[__X--\#^Z`0```(M%\.@%^/__Z?/]__]5B>57B<=6B=93@^P,@_H! +XM?Q'K'[H!````N"````#HW?___XGP`P6XF0L(.P7@EPH(?^'WQP````0/A.\` +XM``")^H'B____^\'B!`,5P*P+"(L"AAN)D+"#L%X)<* +XM"'P_#[X%K)@*"(,%:'8*"`&#!3AE"0@!J`''!;B9"P@`````="2H`G08QP0D +XM(````.B6)QU93@^P, +XMA<")1?!T4(L'A%P'6V@\0, +XM6UY?7<,QTHGX.WWP#Y3"Z/?[__^--(>)]^O<58GE5U93@^Q\B56(B<*)18R) +XM382+`(7`#X0$!@``BTV(.P$/A?D%``")5?")3>CK!XM5Z#L"=1?`$BW7P +XM@T7H!(L&A?P@=!#K&I"-="8`BW68@W[\('4, +XM@VV8!(M%\#E%F'?KBU68QP(`````BTWHB0PDZ/?%``")19S'1"0$Q)@*",<$ +XM)"!)"0CH0+O^_X7`=`F`/@Y=9QV(HM%G(-X_"!T#8GVZQ6+ +XM59R#>OP@=0R#;9P$BTWH.4V<=^N+=9S'!@````"+1?"+`(7`B46\=0V+5>B+ +XM`H7`#X2"`@``BTV8BW6@(``(L!.P9T!Y"#P02#Q@2!.?___P=T +XM\HM%O(7`#X5X`@``B4VHB4VLB76TB76PBU7HBQ*%THE5['1R.TWP=FV+??#K +XM$9"-="8`@\<$.?EV7(L'B46\BT6\.47L=>PYSP^"X`(``(M=Z(GZQT7````` +XM`,=%Q`````"+1:PK1:C!^`([1<1]PXGX*T7PT7W`P?@".47`?K.)5:R+5>B) +XM?:B#QP0Y^8E=M(E5L'>DBT68B*T6L*W6TP?@"P?X" +XM*<:%_W4_AC!^@+!^P(YVGT,BT68BU6%6+18@I1=C!?=@"BU78B10DZ'4= +XM``"+3:`Y39@/A*(#``"+1>"%P'X2BW7@B70D!(M%M(D$).B@&P``BU7@*57< +XMBTW@/@WW]__^#Z02#[@2+ +XM`3L_?__Z6_]__\[=>@/AG_]__^+?>B)3:B)3:R)=;2)=;#K$)"-="8` +XM@\<$.?X/AFK]__^+1;P[!W7N.?=R0HM=\(GZQT7(`````,=%S`````"+1;0K +XM1;#!^`([1B)^CG>#X83_?__C;0F`````(/"!(/#!#G1=Q:)T"GXB47`P?@" +XMB47$Z0/]__^-="8`.=YVYHL".P-TUNO>BW6@BT6DB4W8QT7<`````(EUU(EU +XMJ(EUK(E%M(E%L(EUT,=%X`````#ITOW__X7)#XA4`0``BU6LBTVHB=.)5=`I +XMRXE-U(7VBWV@#X@F`0``BTVDB?HK5?")R"M%Z,'Z`L'X`CG"#XYO_?__BT68 +XMBTV)1:")3:3I7/W__XM%Z"M%B,'X`HD$).B4&P``BTVP.4V<#X3:`@`` +XM@'V3``^%S@$``(G[BWWDBW7H*UWDP><"`?Z)7"0$B30DZ((6``"+1?")V8GR +XM`?CH)/+__^F^_?__BT6LZ5?]__^+1>@K18C!^`*)!"3H-AL``(MUL#EUG`^$ +XM60(``(M%Y(E$)`2+5>B)%"3H:!D``(M-Y(M5\"M5C(E,)`2+=>B+#>"7"@C! +XM^@*)-"2+18R)_N@R\?__BT7DBUWH*W7DP>`"`<.)192)'"2)="0$Z/45``"+ +XM1?")V@-%E(GQZ);Q__^+7>3I#_W__XM-C(MUB(E-\(EUZ.D6^O__BTV8BW6< +XMB<^)3:")=:3IQ_[__XM%H#';BU6DB474B46HB46LB56TB56PB470Z9W^__^+ +XM38PI3=#!?=`"BW70C00SB00DZ&,:``"+1:`Y19@/A`L!``"+1>#WV(D$).A* +XM%```BU7B)^8M%\.B?\/__BUWDZ1C\__^+ +XM1=R)1"0$BU6TB10DZ-44``#I>_S__XMUY(ET)`2+1>B)!"3H[A<``(M5\"M5 +XMC(ET)`2+3>C!^@*)#"2+#>"7"@B+18SHO>___^GZ_?__BT6,C0RPBW6XC129 +XMC1RP.=IS#HL"@\($B0&#P00YVG+RQP,`````Z6'___^+19@K18R+%>"7"@C! +XM^`*--`,YUGX"B=:+1=R)1"0$BU6TB10DZ$(4``"+19PK18C!^`(IQHDT).B? +XM$@``Z6;[__^)?"0$BU7HB10DZ!L4``"+=8@I=9R+38PI39C!?9P"P7V8`HM% +XMG"E%F(M5F(D4).AF$@``Z9S[__^)?"0$BU7HB10DZ.(3``"+5>B)^8M%\(/$ +XM?%M>7UWI?N___XE\)`2+=>B)-"3HOQ,``(M%\(GYB?+H8^___^G]^O__C;0F +XM`````(V\)P````!5B>575E.#[!RAA'<*",<%1&4)"`````#'!81W"@@````` +XMQP5(90D(`````(E%\*%XF0L(Z.?V__^A1&4)",<%1&4)"`````"C3&4)"*%( +XM90D(QP5(90D(`````*-090D(H2QW"@CHM?;__X$]-'<*"`!V"0@/AB("``"[ +XM`'8)",=%Y/_____'1>@`````.QU4F0L(3_=1:A1&4)"(D=5)D+"(E% +XMY*%(90D(B47H,=*!^P!V"0@/E,*)V.C,\O__C1R#.1TT=PH(=[^#?>3_#X3$ +XM`0``BPU$90D(H4QE"0B+%>"7"@B%P'0.BQU090D(A=L/A%T!``#'!4QE"0@` +XM````QP5090D(`````*%(90D(N@$```")1>PQP.B\[/__BT7LQT7@`````(7` +XM>&Z+7>"AL'8*"(M-X,'C`HL4&*%`F@L(BP08Z%#V__^AL'8*"(LUX)<*"(L\ +XM&*%`F@L(A?:+%!A^)(L',`Y1>Q]DJ$X90D(.47L?4`[1>!\.XM=X,'C`J%` +XMF@L(NOAO"0B+3>"+!!CHUO7__Z%`F@L(BP08@\,$QP``````@T7@`8M%X#D% +XM.&4)"'W+BT7LHSAE"0B+1>B)!"3HHQ@``(M%Y(D$).AX%@``QP0D`````.C\ +XM"@``Z-=C_O^+1?"CA'<*"(/$'%M>7UW#,RA>)D+".B(]/__ +XMZ7/^__^A1&4)"(E%Y(G!H4AE"0B)1>CI*_[__XVV`````(V_`````%6)Y8/L +XM&(EU^(MU"(E=](E]_(L55)D+"#L5-'<*"'01BUWTBW7XBWW\B>Q=Z0_]__^+ +XM#4QE"0B%R702H>"7"@@K!;B9"P@IR(/X`G[3C02U`````(G7*</_ +XM_S\`@?\`=@D(#Y3`B40D!(D<).B9E0``@_C_=&B#^`$/A(0```"#^/QUEKH! +XM````N%P```#HA_+__XG8N@$```#!^`:#X`>#P##H#X`>#P##H6O+__XU#,+H!````Z$WR__^+7?2+=?B+??R)[%WI3&+^_[H! +XM````N%X```#H+?+__X/[?W1_@\M`N@$```")V.@9\O__Z\K'1"0$Q)@*",<$ +XM)"!)"0CHTZ_^_X7`=`F`/@Y!2QW"@@/E,"!XO__/P`/ML")%"2)1"0$Z/:3``"-4`>#^@9V +XM9@'&.?Y\O"G^@T7P`87;=;:[`'8)".L6C;0F``````'&.?Y\!H-%\`$I_H/# +XM!#L=5)D+"`^#H@```#'`@?L`=@D(#Y3`B40D!(L#)?__/P")!"3HEY,``(U0 +XM!X/Z!G>__R25K`,)"/\DE<@#"0B0@\8!]\8'````C;0F`````'2"@\8!]\8' +XM````=>.-=@#I;____X/&`??&!P```(GV=("#Q@'WQ@<```!UZ(UV`.EM____ +XM@T7P`3'VZ6+___^#Q@3I6O___P'`]]B-=`;]Z4W___^#Q@+I1?___XM%\(D$ +XM).C8%```B30DZ+`2``#'1"0$Q)@*",<$)"!)"0CHS*W^_X7`=`F`/PL0@``BU4,BTT(@_H!B=`/C@D$``"%R:.L;PD(B<@/CO`#```Y +XM%:QO"0BCH&\)"`^$#0$``*%`F@L(QP5`F@L(`````(D$).A<2?[_H;!V"@C' +XM!;!V"@@`````B00DZ$5)_O^AK&\)"+H```$`B<&CX)<*"(G0P?H?]_F-4`&- +XM!(4(````B17(=@H(B00DZ)50``"+%_(L5R'8*"(G8@\,!.<)_VL<$E@````"AR'8* +XM"(DU0)H+"(/``<'@`HD$).@Z4```BQ7(=@H(A=*)QGXKNP$```"AX)<*"(/` +XM`<'@`HD$).@64```B42>_(L5R'8*"(G8@\,!.<)_VL<$E@````")-;!V"@CH +XM\>?__X'$+$(``%M>7UW#.<@/A>O^___'!"3D`PD(Z)[`_/^%P'1'H:QO"0C' +XM1"0(`````,=$)`0`````B00DZ#%I``#'1"0$,"H("(G#B00DZ$]$_?^)7"0$ +XMQP0D`$P)".@_MOW_B1PDZ)=#_?_'!"3L`PD(Z$?`_/^%P'1'H:!O"0C'1"0( +XM`````,=$)`0`````B00DZ-IH``#'1"0$,"H("(G#B00DZ/A#_?^)7"0$QP0D +XMY$L)".CHM?W_B1PDZ$!#_?_'!"3R`PD(Z/"__/^%P`^$*?[__XD$).C4O@`` +XMQT0D"``(``")1"0$C87DWO__B87@O?__B00DZ$#'_/^-1>2-C>3>___'A>#^ +XM__\`````QT7D8P```,=%Z&\```#'1>PC````QT7P`````(E$)`2)#"3H*;4` +XM`(7`B<2)PXD,).CNP/S_C8WDO?__*YW@O?__B8W3>__^)7"0(B40D!.C!QOS_H:QO"0C'A)WDO?__`````(V2] +XM___'1"0(`````,=$)`0`````B00DZ,9G``")'"2)QHE$)`3H9+[\_XDT).A@ +XM30``QT0D!#H```")/"3H#,3\_XV-Y+W__XD,)(E$)`3H.K[\_XU%Y(V-Y+W_ +XM_\=%Y&P```#'1>AI````QT7L(P```,=%\`````")1"0$B0PDZ$VT``"%P(G& +XM#X3[````B<.-1>2)!"3H$L#\_XV-Y+W__RN=W+W__XE,)`3!^P(!PXV%Y-[_ +XM_XE<)`B)!"3HZ\7\_Z&@;PD(QX2=Y-[__P````#'1"0(`````,=$)`0````` +XMB00DZ/=F``"-C>3>__^)#"2)PXE$)`3HC[W\_XD<).B+3```QT0D!#H```") +XM-"3H-\/\_XE$)`2-A>3>__^)!"3H9;W\_XV-Y-[__\>%X/[__P````")3"0$ +XMQP0D($P)".C)L_W_Z2'\__^X&````.D&_/__N%````"0C70F`.GH^___C8WD +XMO?__C87DWO__B40D!(F-W+W__XD,).@IOOS_Z2]__^-C>3>__^) +XM1"0$B0PDZ`R^_/_KA8VT)@````"-O"<`````58GE5E.#[""+70RAK&\)"(MU +XM"(D#H:!O"0B)!HU%\(E$)`BAM'8*",=$)`1H=`A`B00DZ*2^_/^#P`%T%P^W +XM1?)FA7<.0 +XMC70F``^WP+H!````B0:AK&\)"#L#==^AH&\)"#'2.P8/E<*#Q"!;B=!>7<.0 +XMC;0F`````%6)Y8/L&(72B5WTB=.)=?B)QHE]_'0%@#H`=22+1@B)!"3H&4L` +XM`,=&"`````"+7?2+=?B+??R)[%W#D(UT)@")%"3HU,/\_XUX`8M&"(E\)`2) +XM!"3H!DP``(E\)`B)7"0$B48(B00DZ/_"_/_KOY!5B>6#[!B+%,````\.=,/A/@```"+#6AE"0B%R0^%^@```(G'B<8E````(('G +XM````"('F````$(E%\*&`;0D()0```!`Y\'0IA?8/A-X!``"AL&X)"(7`=!B` +XM.`!T$XL5O&X)"(72=`F`.@`/A9T"``"A@&T)""4````(.?AT+87_#X1J`0`` +XMH>QN"0B%P'0<@#@`=!>+%>!N"0B%TG0-@#H`#X4_`@``C70F`*&`;0D()0`` +XM`"`[1?!T48M%\(7`#X3N````H1!O"0B%P'0]@#@`=#B+%1QO"0B%TG0N@#H` +XM="G'1"0(,#H&",=$)`0!````B00DZ,V]_/^!#8!M"0@````@C;0F`````(M= +XM](MU^(M]_(GL7<.-=@"+#;QN"0B%R0^$^/[__X`Y``^$[_[___?"````$`^% +XM>`$``(G&@>8````0]\(````@#X5W`0``B=@E````((E%\('B````"'1"B=^! +XMYP````@/A8````0)0```"")1?#'1"0(,#H&",=$)`0!```` +XMB0PDZ"N]_/_'!8!M"0@`````B=^!YP````CIAO[__Z$<;PD(A<`/A$O___^` +XM.``/A$+____'1"0(,#H&",=$)`0!````B00DZ.:\_/^!)8!M"0C____?Z1O_ +XM__^AX&X)"(7`#X2N_O__@#@`#X2E_O__QT0D"#`Z!@C'1"0$`0```(D$).BI +XMO/S_@26`;0D(____]^E^_O__H;!N"0B%P`^$-O[__X`X``^$+?[__Z&\;@D( +XMA<`/A"#^__^`.``/A!?^___'1"0(,#H&",=$)`0!````B00DZ%:\_/_V!8-M +XM"0@(=!*AX&X)"(7`=`F`.``/A<\```#V!8-M"0@@=!*A'&\)"(7`=`F`.``/ +XMA8T```"!)8!M"0C____OZ;K]__^)QH'F````$`^$N/[__^E]_O__B=@E```` +XM((E%\`^%@_[__XG>@>8````0Z9[^___'1"0(,#H&",=$)`0!````B00DZ,F[ +XM_/^!#8!M"0@````(Z9[]___'1"0(,#H&",=$)`0!````B00DZ**[_/^!#8!M +XM"0@````0Z3S]___'1"0(,#H&",=$)`0!````B00DZ'N[_/^!)8!M"0C____? +XMZ4S____'1"0(,#H&",=$)`0!````B00DZ%2[_/^!)8!M"0C____WZ0K___^) +XM]HV\)P````!5B>6#[!CH%74``,=$)`3$F`H(QP0D\$4)".CAHO[_A7"7"@A_/*$T;PD(A7<.+%?QM"0B%TG3& +XM@#H`=,&A%&X)"(7`=`6`.`!U>*'\;0D(A7<.#Q!!;7EWI +XM=%+^_\=$)`@P.@8(QT0D!`$```")!"3H6+C\_^EK____C;0F`````%6)Y5=6 +XM4X/L+(MU#(M]"(7V?@@[->"7"@A^"(/$+%M>7UW#QT0D!,28"@C'!"0@20D( +XMZ-F?_O^%P`^$H`(``(L5+'<*",=%V`````"+&H7;=!2)T(/`!(L(A``````=#R+ +XM%5"9"PB+#529"PB)T#G*#X=Z`@``+0!V"0C!^`(#1=@YRHE%W(G0#X);`@`` +XM+0!V"0C!^`(#1=B)1>#'1"0$Q)@*",<$)"!)"0CH-9_^_X7`=%*A9&4)"(L= +XMX)<*"`^O'6AV"@@#';B9"PB%P`^$I````#M=X'P,Z`?X__^-M"8`````H61E +XM"0B%P'08H529"P@M`'8)",'X`@-%V#G8#X2(`0``BP<]____!W0XJ0````0/ +XMA(````")PH'B____^\'B!`,5P*P+"(L"AZ#!;B9"P@!@^X!=%N#QP3I0?___Z%4F0L(+0!V"0C!^`(#1=@!PHE% +XMW(E5X.DD____.UW<#XQD____.UW@#XU;____Z(;W__^-M@````#I2____XD$ +XM).BS5/[_@P6XF0L(`8/N`76EQT0D!,28"@C'!"0@20D(Z".>_O^%P'0-H61E +XM"0B%P`^%UP```*'@EPH(.06XF0L(#XP,_O__#[X5K)@*"/;"`0^$I@```(L- +XM:'8*",<%N)D+"`````"#P0&#X@*)#6AV"@@/A-K]__^A0)H+"(L$B(L`A<") +XM1?`/A*,```"-1?")!"3'1"0$`0```.B7_?__H6AV"@B+%;B9"PB-'(4````` +XM`QU`F@L(BP.!/)#___\'#X6+_?__C4H!C12-`````.L#@\$!B0VXF0L(BP.+ +XM!!"#P@0]____!W3HZ6+]___H4O;__XGVZ6S^__^#Z`&CN)D+"(/$+%M>7UW# +XMZ#;V___I'____\=%V`````#'1=P`````QT7@`````.G._?__QP0D(````.C+ +XM4/[_QP6XF0L(`0```.D'_?__B7>E9_/__BQ50;@D(A=)TP8`Z`'2\ +XMH5QN"0B%P`^$N````(`X``^$KP```(L5+&X)"(72#X2A````@#H`#X28```` +XMB00DQT0D"#`Z!@C'1"0$`0```.A1M/S_B5PD!(DT).CY^___H6AN"0B%P'0) +XM@#@`#X6B````H2QN"0C'1"0(,#H&",=$)`0!````B00DZ!:T_/^#Q!!;7EW# +XMQT0D"#`Z!@C'1"0$`0```(D$).CWL_S_QT0D!`$```")-"3HF_O__Z%H;@D( +XMA7>F53?[_QT0D"#`Z!@C' +XM1"0$`0```(D$).AYL_S_Z4'___^0C;0F`````%6)Y5=64X/L'(M]"(L5N)D+ +XM"#G7#X3$````.SW@EPH(#XVX````A?\/A+@```")^(G^@^`'P?X#B47LZS&- +XM=@"+1>P!\#G##Y_`A,!T;<<$)`T```#HED[^_S'2.SW@EPH(QP6XF0L(```` +XM`'UPB?LITXU#!(/X"'82H>1M"0B%P'0)@#@`#X5:`0``A=M_=/?;@_L$?A*A +XM6&\)"(7`=`F`.``/A?H```"`/<"9"P@`=8XYWP^7UW#QP0D#0```.C^3?[_ +XMQP6XF0L(`````(/$'%M>7UW#@_L$?A*A9&\)"(7`=`F`.``/A8@```"`/<"9 +XM"P@`#X2M````B=.)_H'C^````(/F^#GS#X3/````BQ5H=@H(B57PBPU`F@L( +XMBP21@3RP____!W0K.?-](8/#",<$)`D```#HA4W^_SG>?^VA:'8*"(E%\(L- +XM0)H+"(DUN)D+"*&XF0L(B?HIPHE4)`2+5?#!X`(#!)&)!"3H?_G__^LDB5PD +XM"(E<)`2)!"3HZ:[\_\=$)`@P.@8(B5PD!(D$).BEL?S_B3VXF0L(@\0<6UY? +XM7<.+%6AV"@B)5?"+#4":"PCKG8E\)`B)?"0$B00DZ*:N_/_'1"0(,#H&"(E\ +XM)`2)!"3H8K'\_^N[H6AV"@B)1?"+#4":"PCI9/___Y!5B>575E.#[`R+?0BA +XM:'8*"#G'#X3J````.SW(=@H(#X_>````B?LIPX7;#XX``0``]@6LF`H(`0^$ +XMB````(L5:'8*"*%`F@L(BP20BQ"%TG1TBQ7@EPH(B=&#Z0%T(X$\B/___P=U +XM&HT4D.L0C78`BT+X@^H$/?___P=U!8/I`77NB0PDZ%;]__^+%;B9"PBAX)<* +XM"(L-:'8*""G0B40D!*%`F@L(P>("`Q2(B10DZ$SX__^#ZP%T1/8%K)@*"`$/ +XMA7C___^#^P%^%:%`;PD(A`.@")]G5'H01O"0B% +XMP'2R@#@`=*V)WO?>,=N%]G\+ZZ&-="8`H01O"0B#PP''1"0(,#H&",=$)`0! +XM````B00DZ,RO_/\Y\W7@_X!?BF)="0(B70D!(D4).C:K/S_ +XMQT0D"#`Z!@B)="0$B00DZ):O_/_I0O___Z$$;PD(A0C70F +XM`%6)Y5.#["2A)"P)"(U=],=%^`,```#'1?0H+0D(B40D",=$)`0<+`D(B1PD +XMZ`\H``"A$"P)",=%]!@M"0C'1"0$""P)"(D<)(E$)`CH[R<``*%,+`D(QT7T +XM""T)",=$)`1$+`D(B1PDB40D".C/)P``H3@L"0C'1?3X+`D(QT0D!#`L"0B) +XM'"2)1"0(Z*\G``"A8"P)",=%].@L"0C'1"0$6"P)"(D<)(E$)`CHCR<``*%T +XM+`D(QT7TV"P)",=$)`1L+`D(B1PDB40D".AO)P``H20L"0C'1?3(+`D(QT0D +XM!!PL"0B)'"2)1"0(Z$\G``"A$"P)",=%]+@L"0C'1"0$""P)"(D<)(E$)`CH +XM+R<``*%,+`D(QT7TJ"P)",=$)`1$+`D(B1PDB40D".@/)P``H3@L"0C'1?28 +XM+`D(QT0D!#`L"0B)'"2)1"0(Z.\F``"A8"P)",=%](@L"0C'1"0$6"P)"(D< +XM)(E$)`CHSR8``*%T+`D(QT7T>"P)",=$)`1L+`D(B1PDB40D".BO)@``BPW( +XMF0L(A``````ZQ"#QP>`4@_\=```` +XMBU7@BX($+`D(C01`BQR%J&T)"(7;=-D/MC.)\(3`=-")'"3HI:<``(E%[(D$ +XM).@FJOS_BU7@BXH0+`D(B47P@_G_#X2?````@'L!`(GP#[;0=%*+7=B+==P! +XMTP^V`S@$%G1?/#5T6RP!=86+==B-5>R)5"0$B30DZ,`B``"+5>"+@A`L"0B% +XMP'5T#[:"""P)"(@#Z5C___^0C70F`(/$+%M>7UW#BUW8`=,/M@/KN,=%W$`I +XM"0C'1=C`JPL(Z1[___^-!+^-!(4(+`D(B40D!(U%[(E,)`B)!"3HWB,``,8# +XM->D)____BT78C77LB70D!(D$).A$(@``Z?+^__^)1"0(C02_C02%""P)"(UU +XM[(E$)`2)-"3HHB,``.G0_O__C;8`````C;PG`````%6)Y5=64X'L3`@``(U= +XMR(D<).AEK?S_B1PDQT0D!!P```#H9:C\_XU%V(E<)`2)1"0(QP0D`0```.C^ +XMI_S_C478B00DQT0D!&`>!0CH/RO]_XV%R/?__XE%\,<%8&4)"`$```#'!2!W +XM"@CZ`PD(QP0D++((".@RI_S_A<")PW0)@#@`#X6:`P``NS&R"`C'1"0$``@` +XM`,<$)(!E"0CHWC3^_XE<)`3'!"2`90D(Z+JK_/^%P`^.G`(``,<$)`[/"`CH +XM%JC\_X7`#X6>`P``,=*)%91O"0C'!"0*!`D(Z/JG_/^%P`^$9P,``+H!```` +XMB16X;PD(QP0D#00)".C;I_S_QP0D$`0)"*.(;PD(Z,JG_/_'!"03!`D(H\1O +XM"0CH&:;\_\<$)!8$"0BCK&\)".@(IOS_HZ!O"0BAH&T)"(7`="R[H&T)"(UU +XM\(VV`````(ET)`2)!"3H<*[\_XG"B=B#PPSH:.G__XL#A'<*"(7;=&Z`.P!T +XM::$<;PD(AB)1"0$C47LB00DZ%/G__^+ +XM1>B)1"0$BT7LB00DZ,'B__^-1=B)!"3H]B?]_^B!^___@<1,"```6UY?7<.A +XM4&X)"(7`=`F`.``/A0K___^+%4QO"0@QP(72#X3__O__,<"`.@`/E<#I\O[_ +XM_XL5-&\)"#'`A=(/A,+^__\QP(`Z``^5P.FU_O__@_C_#X27`0``A<`/A$$! +XM``"A@)@*"(L=#'8*",=$)`R4"`D(QT0D"!8```#'1"0$!P```(D$).BNAOW_ +XMB5PD!(D$).A"@```H:!M"0C'!:QO"0A0````QP6@;PD(`````,<%N&\)"``` +XM``"%P,<%E&\)"``````/A)O]__^[H&T)"(G8,=*#PPSH[.;__XL#A*#Q!`QP%M>7<.#Q!"P +XM`5M>7<-5B>575C'V4S';@^P,BT4(BSB+@P`L"0B)/"2)1"0$Z'BB_/^%P'08 +XM@\8!@\,4@_X&==^#Q`RX_____UM>7UW#BTT,BP&+402-#+:)!(T(+`D(B12- +XM#"P)"(M%$(D$C1`L"0B#Q`PQP%M>7UW#C78`58GE5U8Q]E,QVX/L#(M]".LV +XMBX80+`D(@_C_="")1"0(C02;C02%""P)"(E$)`2+A@`L"0B)!"3H@R```(/# +XM`8/&%(/[!G0JBT<$A53,=N#[!2-M"8`````BX.D;0D(@\,, +XMB00DZ!\O``"!^^`!``!UYV8QVXUT)@"+@X1O"0B#PPR)!"3H_RX``(/[5'7J +XMH8"8"@C'1"0,&00)",=$)`@!````QT0D!`0```")!"3'!:QM"0CX'`D(Z/N" +XM_?^)!"3H8RS^_\=$)`PO!`D(QT0D"`(```#'1"0$!````,<%N&T)""P$"0BC +XML&T)"*&`F`H(B00DZ+^"_?^)!"3H)RS^_\=$)`P\!`D(QT0D"`,```#'1"0$ +XM!````,<%Q&T)")_1"`BCO&T)"*&`F`H(B00DZ(."_?^)!"3HZRO^_\=$)`Q, +XM!`D(QT0D"`0```#'1"0$!````,<%T&T)",`%"0BCR&T)"*&`F`H(B00DZ$>" +XM_?^)!"3HKRO^_\=$)`QA!`D(QT0D"`4```#'1"0$!````,<%W&T)"$V]"`BC +XMU&T)"*&`F`H(B00DZ`N"_?^)!"3H!_?^)!"3HORK^_\=$)`RI!`D(QT0D"`D```#'1"0$ +XM!````,<%#&X)"*8$"0BC!&X)"*&`F`H(B00DZ!N!_?^)!"3H@RK^_\=$)`R[ +XM!`D(QT0D"`H```#'1"0$!````,<%&&X)"$T;"0BC$&X)"*&`F`H(B00DZ-^` +XM_?^)!"3H1RK^_\=$)`S.!`D(QT0D"`L```#'1"0$!````,<%)&X)",L$"0BC +XM'&X)"*&`F`H(B00DZ*.`_?^)!"3H"RK^_\=$)`SA!`D(QT0D"`P```#'1"0$ +XM!````,<%,&X)"-X$"0BC*&X)"*&`F`H(B00DZ&>`_?^)!"3HSRG^_\=$)`SY +XM!`D(QT0D"`T```#'1"0$!````,<%/&X)"+/1"`BC-&X)"*&`F`H(B00DZ"N` +XM_?^)!"3HDRG^_\=$)`P(!0D(QT0D"`X```#'1"0$!````,<%2&X)"`4%"0BC +XM0&X)"*&`F`H(B00DZ.]__?^)!"3H5RG^_\=$)`P +XM!0D(QT0D"!8```#'1"0$!````,<%M&X)"""_"`BCK&X)"*&`F`H(B00DZ`]^ +XM_?^)!"3H=R?^_\=$)`RM!0D(QT0D"!<```#'1"0$!````,<%S&X)"*;K"`BC +XMN&X)"*&`F`H(B00DZ--]_?^)!"3H.R?^_\=$)`S#!0D(QT0D"!@```#'1"0$ +XM!````,<%V&X)"'CG"`BCT&X)"*&`F`H(B00DZ)=]_?^)!"3H_R;^_\=$)`S0 +XM!0D(QT0D"!D```#'1"0$!````,<%Y&X)",0>"0BCW&X)"*&`F`H(B00DZ%M] +XM_?^)!"3HPR;^_\=$)`S?!0D(QT0D"!H```#'1"0$!````,<%\&X)"*/!"`BC +XMZ&X)"*&`F`H(B00DZ!]]_?^)!"3HAR;^_\=$)`SU!0D(QT0D"!L```#'1"0$ +XM!````,<%_&X)"(T%"0BC]&X)"*&`F`H(B00DZ.-\_?^)!"3H2R;^_\=$)`P# +XM!@D(QT0D"!P```#'1"0$!````,<%"&\)"->\"`BC`&\)"*&`F`H(B00DZ*=\ +XM_?^)!"3H#R;^_\=$)`P3!@D(QT0D"!T```#'1"0$!````,<%%&\)"$D;"0BC +XM#&\)"*&`F`H(B00DZ&M\_?^)!"3HTR7^_\=$)`PD!@D(QT0D"!X```#'1"0$ +XM!````,<%(&\)""$&"0BC&&\)"*&`F`H(B00DZ"]\_?^)!"3HER7^_\=$)`PT +XM!@D(QT0D"!\```#'1"0$!````,<%+&\)"#$&"0BC)&\)"*&`F`H(B00DZ/-[ +XM_?^)!"3H6R7^_\=$)`Q-!@D(QT0D""````#'1"0$!````,<%.&\)"$H&"0BC +XM,&\)"*&`F`H(B00DZ+=[_?^)!"3H'R7^_\=$)`QE!@D(QT0D""$```#'1"0$ +XM!````,<%1&\)"&(&"0BC/&\)"*&`F`H(B00DZ'M[_?^)!"3HXR3^_\=$)`Q^ +XM!@D(QT0D""(```#'1"0$!````,<%4&\)"'L&"0BC2&\)"*&`F`H(B00DZ#][ +XM_?^)!"3HIR3^_\=$)`R6!@D(QT0D"",```#'1"0$!````,<%7&\)"),&"0BC +XM5&\)"*&`F`H(B00DZ`-[_?^)!"3H:R3^_\=$)`RL!@D(QT0D""0```#'1"0$ +XM!````,<%:&\)"/G."`BC8&\)"*&`F`H(B00DZ,=Z_?^)!"3H+R3^_\=$)`S" +XM!@D(QT0D""L```#'1"0$!````,<%>&X)"+\&"0BC;&\)"*&`F`H(B00DZ(MZ +XM_?^)!"3H\R/^_\=$)`S6!@D(QT0D""P```#'1"0$!````,<%H&T)"-,&"0BC +XM?&X)"*&`F`H(B00DZ$]Z_?^)!"3HMR/^_\=$)`SI!@D(QT0D""T```#'1"0$ +XM!````,<%P&X)".8&"0BCI&T)"*&`F`H(B00DZ!-Z_?^)!"3H>R/^_\=$)`S] +XM!@D(QT0D""4```#'1"0$!````,<%=&\)"`````#'!7AO"0@`````H\1N"0BA +XM@)@*",<%@&\)"`T$"0B)!"3HPWG]_XD$).@K(_[_QT0D#!,'"0C'1"0()@`` +XM`,=$)`0$````QP6,;PD(#L\("*.$;PD(H8"8"@B)!"3HAWG]_XD$).CO(O[_ +XMQT0D#"D'"0C'1"0()P```,=$)`0$````QP68;PD(%@0)"*.0;PD(H8"8"@B) +XM!"3H2WG]_XD$).BS(O[_QT0D##D'"0C'1"0(*````,=$)`0$````QP6D;PD( +XM$P0)"*.<;PD(H8"8"@B)!"3H#WG]_XD$).AW(O[_QT0D#$L'"0C'1"0(*0`` +XM`,=$)`0$````QP6P;PD("@0)"*.H;PD(H8"8"@B)!"3HTWC]_XD$).@[(O[_ +XMQT0D#+@("0C'1"0(*@```,=$)`0$````QP6\;PD($`0)"*.T;PD(H8"8"@B) +XM!"3HEWC]_XD$).C_(?[_QP7(;PD(`````,<%S&\)"`````"CP&\)"(/$%%M= +XMPU6)Y8'L2`@``(V%\/?__XE%\(M%"(E=](EU^(E]_,<%('<*"+;1"`B)!"3H +XM`,;]_\=$)`3P(P8(B<.)!"3H?AG]_XL#A<`/A+0```"+$(72#X2J````@_HM +XM#X2V````B9W@]___QX78]___`````,>%W/?__P````")!"2_)`<)".@:D@`` +XMB00DZ%(A_O_'1"0$,"H("(F%S/?__XD$).@<&?W_B[7,]___N04```#\\Z8/ +XMA%W/?__P````!T(,<$)'<``!#H>A7]_\>%V/?__P````#'A=SW__\` +XM````C4,$B87@]___BT,$AG'1"0$`````,<$)"`+"0CHH&\``.F%_O__ +XMB[7,]___O_[>"`BY!0```/SSIG04B[7,]___OS,'"0BY!@```/.F=2^AH&\) +XM",<$)"`+"0B)1"0$Z%UO``#I0O[__XE4)`3'!"0D"PD(Z$AO``#I+?[__XNU +XMS/?__[\6!`D(N0,```#SIG2]B[7,]___OV$'"0BY!0```/SSI@^$40(``(NU +XMS/?__[\3!`D(N0,```#SI@^$.0(``*&@;0D(OJ!M"0B%P'42Z;`#``"#Q@R+ +XM!H7`#X2C`P``BY7,]___B00DB50D!.@(E_S_A#W__^+0@2%P'0R +XMBS"%]G0LBXW<]___A+A#W__^+0@2)!"3HCHP``(D$).@RC_S_B<>+1@2%P'0RBP"% +XMP'0LBX7<]___A<`/AG*_/__BX78]___ +XMA<`/A+S\__\/OL*)1"0$QP0D=```$.BN#_W_Z:3\__^)]HV\)P````!5B>57 +XM5E.#[!R+10R+70C'!2!W"@@UT@@(B47LH:!M"0B%P`^$`P$``+Z@;0D(ZPV# +XMQ@R+!H7`#X3O````B5PD!(D$).C3DOS_AT!``"+%4QO"0@Q +XMP(72=`@QP(`Z``^5P(L5!&\)"*/DF`H(A=)T"H`Z`+@!````=12+%7!O"0@Q +XMP(72=`@QP(`Z``^5P*-X=PH(@\0<6UY?7<.+%8!O"0C'1?"`;PD(A=*)5>AU +XM)HE=#,=%"',``!"#Q!Q;7E]=Z4H._?^#1?`,BT7PBP"%P(E%Z'3:B5PD!(M] +XMZ(D\).BGD?S_AR)/"3H9(S\_XM5\(E""(L5K&\)"*&@ +XM;PD(@7WPI&\)"(D5=)D+"*/$F0L(=`V!??"8;PD(#X4Z____B54,Z!N"0B%P`^$6?[__X`X``^$ +XM4/[__XE$)`2)'"3H[)#\_X7`#Y3`#[;`"05H90D(Z3'^__^+=>RX6`<)"+D$ +XM````_(G'\Z8/A9@```"+1?#'0`@!````H91O"0B#/<1O"0@!BPV(;PD(HL"9 +XM"PBAN&\)"*+(EPH(&<#WT(/@`H7)#Y7""="!??"`;PD(HJR8"@AT#8%]\+QO +XM"0@/A77^__^AK&\)"(E%#*&@;PD(B44(@\0<6UY?7>GER?__N`$```#I'?[_ +XM_XE$)`2)'"3H.Y#\_X7`#Y3`#[;`HVAE"0CI&____XMU[+B1Y`@(N0,```#\ +XMB575E.#[!RA@)@*",=$)`S8"`D(QT0D"`$```#'1"0$!P```(D$).CB +XM;?W_B00DZ'IG``"A@)@*",=$)`QF!PD(QT0D"`(```#'1"0$!P```(D$).BU +XM;?W_B00DZ$UG``"A@)@*"(L=H&\)"(LUK&\)",=$)`P`"0D(QT0D"`,```#' +XM1"0$!P```(D$).A\;?W_B5PD"(ET)`2)!"3H#&<``(`]R)<*"``/A+`"``"A +XM@)@*",=$)`S,[@@(QT0D"`4```#'1"0$!P```(D$).@Z;?W_B00DZ*(6_O_' +XM1"0$,"H("(G'B00DZ'`._?^A@)@*",=$)`R$!PD(QT0D"`0```#'1"0$!P`` +XM`(D$).C[;/W_B7PD!(D$).B/9@``N$7)"`B`/<"9"P@`#X2"`@``B00DZ$46 +XM_O_'1"0$,"H("(G#B00DZ!,._?^A@)@*",=$)`R>!PD(QT0D"`<```#'1"0$ +XM!P```(D$).B>;/W_B5PD!(D$).@R9@``]@6LF`H(`0^$K`$``*&`F`H(QT0D +XM#+('"0C'1"0("@```,=$)`0'````B00DZ&!L_?^)!"3HR!7^_\=$)`0P*@@( +XMB<.)!"3HE@W]_Z&`F`H(QT0D#,0'"0C'1"0("0```,=$)`0'````B00DZ"%L +XM_?^)7"0$B00DZ+5E```/O@6LF`H(J`%T>*@"#X5]`0``H8"8"@C'1"0,M@<) +XM",=$)`@+````QT0D!`<```")!"3HW6O]_XD$).A%%?[_QT0D!#`J"`B)PXD$ +XM).@3#?W_H8"8"@C'1"0,W@<)",=$)`@,````QT0D!`<```")!"3HGFO]_XE< +XM)`2)!"3H,F4``(L=H&T)"(7;#X2/````,?:)]HN&J&T)"(7`=`6`.`!U):&` +XMF`H(QT0D#/0'"0C'1"0(#0```,=$)`0'````B00DZ$QK_?^)!"3HM!3^_\=$ +XM)`0P*@@(B<.)!"3H@@S]_XN&H&T)"(E<)`S'!"3\!PD(B40D"(N&I&T)"(E$ +XM)`3HKF0``(D<).BV"_W_BX:L;0D(@\8,A<`/A77____'!"0*````Z*DG_O^) +XM/"3HD0O]_X/$'%M>7UW#H8"8"@C'1"0,M@<)",=$)`@+````QT0D!`<```") +XM!"3HM&K]_^E/_O__H8"8"@C'1"0,D>0(",=$)`@&````QT0D!`<```")!"3H +XMBFK]_^E+_?__H8"8"@C'1"0,L@<)",=$)`@*````QT0D!`<```")!"3H8&K] +XM_^E^_O__H8"8"@C'1"0,F0<)",=$)`@(````QT0D!`<```")!"3H-FK]_^E4 +XM_?__D%6)Y8M%"%VBX&\)"+C@;PD(PXVT)@````"-O"<`````58GEBT4(78M0 +XM!(L`B17<;PD(H]AO"0BXV&\)",.-=@!5B>53B<.#[`3'!"08````Z'L6``"+ +XM$XL2QT`$_____\=`"`````")$,=`#`````#'0!``````QT`4`````(/$!%M= +XMPXVV`````(V_`````%6)Y5.)PX/L!(7`=$N+0!"%P'0,Z.?____'0Q`````` +XMBT,4Z-C___^+0P2#^/]\"87`?AR#^`)^#(VT)@````#HQXC\_XM#"(D$).@@ +XM%0``B1PDZ!@5``"#Q`1;7<.)]E6)Y5=6B=93@^P,B47PBSJ+&(L7.1.)V74( +XMZQF-="8`B<&+012%P'0W.Q!U\X/!%(G#B4WPC4<$B0:+1@2#Z`&%P(E&!'0J +XMBU,0A=)T$HU#$(GRZ*C___^#Z`%T#8UV`(/$##'`6UY?7<.+0Q"%P'7OBT,4 +XMBU7PB0*)V,=#%`````#H&?___X/$#+@!````6UY?7<.-M@````"-OP````!5 +XMB>6#["B+10B+4`2+`(72B57\B47X=!V+#=1O"0@QP(7)=`^-5?BXU&\)".@O +XM____,<#)P\=$)`PH"PD(QT0D"`,```#'1"0$"0```*&`F`H(B00DZ$9H_?^) +XM!"3HWF$``+C_____R<.-M"8`````58GEBTT,BU4(BP$/M@"`/!`U=`)=PX'Z +XMP*L+"'0:@?K`I`L(=>Z`N,"K"P@U=.6)30A=Z5C___^`N,"D"P@U=>[KVXVV +XM`````(V\)P````!5B>57B<=6B=93B?N#[!R)3?"+`HL0.1=U".L8C70F`(G# +XMBT,4A<`/A,L````[$)!U[HG'BT8$@P8$@^@!A<")1@1U+(M'$(7`=`SH\/W_ +XM_\='$`````"+1P2#^/]\"87`?D>#^`)^,.C?AOS_C78`BU\0A=L/A*0```"+ +XM50B+1Q")%"2+3?")\NAR____@\0<,7<.)V.@5_/__H]1O"0CI>___ +XM_XUT)@"-O"<`````58GE@^PHB5WTB<.)=?B)SHE]_(G7BQ*+`#L"=#.+0Q2% +XMP'04B?KHU?___XM=](MU^(M]_(GL7<.X`0```,____ZX>-M@`` +XM``"-OP````!5H=1O"0B)Y8M5"(M-#%WI//___XVV`````(V_`````%6)Y8/L +XM"*'4;PD(Z'#[___'!=1O"0@`````R>D0UO__58GE5U93@^P-=@"!^_\````/AS0!``"AX%T)"(M$F#3VQ`)T/X/[ +XM?\8&7@^$)P$``(G8@\A`B$8!@\8"BU4(@T7P`8M%\#E"!`^.DP```(M5"(L" +XMBU7PBQR0B=^!YP```$!TIX/[7@^$T````(/[7`^$QP```(/[((GV=#Z%_P^% +XMA@```('[_P````^'TP```*'@70D(BT28-*D```0`=&J!^_\````/A\@```"A +XMX%T)"(M$F#3VQ$!U4('C__\_`(DT)(E<)`3HKGP``(M5"(-%\`$!QHM%\#E" +XM!`^/;?___XM%#(L0A=)T#(M`!(7`=`6(!H/&`<8&`(M%[(/$'%M>7UW#C;8` +XM````B=C!^`:#X`>#P#"(1@&)V,'X`X/@!X/`,(A&`HG8@^`'@\`PQ@97UW#C70F`'Q3@_L"?TZ#ZP&X +XM:#T)")!T!;AT/0D(B30DB40D!.B-_?__QT0D!#`J"`B)PXD$).C+`_W_H4@- +XM"0B)7"0$B00DZ`I<``")70B#Q!Q;7E]=Z0L#_?_HPH'\_Z&`F`H(QT0D#.$+ +XM"0C'1"0(!P```,=$)`0)````B00DZ#%B_?^)10RA2`T)"(E%"(/$'%M>7UWI +XMNEL``(UV`(V\)P````!5B>6#["B+10B)??R)7?2)=?B+&(U3!(E5[(MS!(GW +XM@>?__S\`#X2"`0``BPN)R"7__S\`@_AQ=PXUT)@"!__\```!W-Z'@70D(BT2X-/;$`70S@_\_ +XMQT7P?P```'3"@>:?````B77PZ[>-=@"-1]"#^$9W\/\DA2P,"0B)/"3HU7_\ +XM_^O(B7PD!,<$)`4,"0CH@X'\_X7`=;GK@L=%\`L```#I>?___\=%\`D```#I +XM;?___\=%\`T```")]NE?____QT7P"@```(UT)@#I3____\=%\`P```"-="8` +XMZ3_____'1?`;````C70F`.DO____QT7P"````(UT)@#I'____\=%\`<```"- +XM="8`Z0_____'1?!<````C70F`.G__O__BUWL,=(QR8/#!(/X!P^'T@```(M- +XM[(G"BT$$B6#[!B%THE=](G3B77XB<:)??P/A.@```")UX'G````0'4>@?K_ +XM````#X=0`0``H>!="0B+1)`T]L0"#X7B````@_M>#X1"`0``@_M<#X0'`0`` +XM@_L@=#Z%_XUT)@!U1('[_P````^'X0```*'@70D(BT28-*D```0`="B!^_\` +XM```/ARD!``"AX%T)"(M$F#3VQ$!U#HE<)`2)-"3H7',``.M0QT0D!%P```") +XM-"3H2G,``(G8P?@&@^`'@\`PB40D!(DT).@S#P#") +XM1"0$B30DZ!ES``"-0S")1"0$B30DZ`IS``"+7?2+=?B+??R)[%W#QT0D!%X` +XM``")!"3H[7(``,=$)`1`````B30DZ-UR``#KT<=$)`1>````B30DZ,MR``"# +XM^W\/A(<```"#RT")7"0$B30DZ+-R``#KIXD<).CE?/S_Z1O____'1"0$7``` +XM`(DT).B4<@``QT0D!%P```")-"3HA'(``.EU____B10DZ+-\_/_IK/[__\=$ +XM)`1<````B30DZ&)R``#'1"0$7@```(DT).A2<@``Z4/___^)'"3H@7S\_Y"- +XM="8`Z<[^___'1"0$/P```(DT).@K<@``Z1S___^-M@````!5B>6#[!B%THE= +XM](G3B77XB<:)??QT.8L2BW@$Z/_]__^+4Q"%TG0XB?#HT?___XM#%(7`=!J) +XM?@2+4Q2)\(M=](MU^(M]_(GL7>NTC70F`(M=](MU^(M]_(GL7<.-=@#'1"0$ +XM(@```(DT).BP<0``B30DZ`AR``"+0P2)1"0(C4,(B40D!(L&B00DZ##Z___K +XMG8VT)@````"-O"<`````58GE@^PHAR+2Q"#P`2)1>R+1@2#Z`&) +XM1?")^.BL____BUWTBW7XBWW\B>Q=PXGXB''1"0$(@```(D\).CA<```B3PDZ#EQ +XM``"+0P2)1"0(C4,(B40D!(L'B00DZ&'Y__\QP.N1C;8`````C;PG`````%6) +XMY593@^PPBU4(QT7D`````,=%Z`````#'1>P`````A=)T;(L"B47PBT($B47T +XMH=1O"0B%P'1(C77DQT0D!"(```")-"3H97```,=$)`2PD0@(B30DZ'7]_/^+ +XM#=1O"0B-5?")\.C%_O__@\`!?C")-"3HN/S\_X/$,%M>7<.0BT7TA7<.)]L=%\/AO"0C'1?0`````ZX^A@)@*"(M=\,=$)`P0#`D(QT0D"`0` +XM``#'1"0$"0```(D$).BX6_W_B5PD!(D$).A,50``ZYJ0D)"0D)"0D)"058GE +XMBT4(BU4,#[9(&(@*#[9(&8A*`0^V2!.(2@(/MD@5B$H##[9($(A*!`^V2!&( +XM2@4/MD@2B$H&#[9(%XA*"0^V2!R(2@H/MD@=B$H+#[9(%(A*#`^V2!J(2@T/ +XMMD@;B$H.#[9(%HA*#P^V2!^(2A`/MD@>B$H1#[9((HA*$@^V2""(2A#[9($HA*(@^V +XM2!>(2B`/MD`8B$(A7<.058GEBT4(78M`!(/P!,'H`H/@`<.-M@````"-OP`` +XM``!5B>6+10A=BT`()0`#```]``,```^4P`^VP,.0C70F`%6)Y8M%"%V+0`PE +XM``$``,-5B>53@^P$BUT(B1PDZ-IY_/^%P'0*@\0$6UW#C70F`(E="(/$!%M= +XMZ;][_/^-=@!5B>564X/L$(MU"(M=#.L*Z$=[_/^#."-U(HE<)`C'1"0$`0`` +XM`(DT).C2^OW_@\`!=-TQP(/$$%M>77`P``BU7@`````QT7L`````(E5S(E%R.MMNRT```"_`0```,9%TP&+5>R+LD`/"0B) +XM-"3HD7S\_XU\!P$!?>2+1>0[!>"7"@@/C<`"``"`?=,`#X2A`@``#[[#B70D +XM"(E$)`3'!"1E#0D(Z$Y1``"+5>R+@DP/"0B#P@R)5>R%P`^$P0(``(M5[(N" +XM2`\)"#M%X'1=C11`BT7(*T7,@WW@_XN$D$`M"0BZ`;H("`^$B@(``(E$)`B) +XM5"0$QP0D6PT)".CV4```BT7LBU7(*U7,BX!(#PD(B47@C01`BX2"0"T)"(D$ +XM).C>>_S_B47DB47HBU7LBT7@BXI$#PD(C11`BT7(*T7,C120B<@C@D0M"0B# +XM^`$9V_?3@^,KA8I(+0D(#X7R_O__A-L/E473=0N+1=B%P`^$-?___P^V?=/I +XMY/[__X/&!,=%W`(```#I+/[__X/&!,=%W`$```#I'?[__X-%V`&#Q@3I$?[_ +XM_\=%V`````#'1=P`````QP7H;PD(`0```(L6A=(/A$S^__^+1=R-?@3!X`*) +XM1<2+1=S!X`:)1<"+`H/X*P^$FP```(/X+<9%\P`/A(X```")%"2[0`\)".B$ +XM<```B<:A0`\)"(7`=1+K?XVT)@````"#PPR+`X7`=&^)="0$B00DZ`=X_/^% +XMP'7G@'WS*P^$F````(!]\RT/A,@```"+0PB+5<"+2P0K5<2-!$"-!(+WT2&( +XM1"T)""&(2"T)"(7_#X2.````BQ>%T@^$A````(L"@\<$@_@K#X5E____@\($ +XMB$7SZ6?___^A@)@*",=$)`QK#0D(QT0D"`(```#'1"0$"````(D$).BC5?W_ +XMB70D!,<$)#8``!")1"0(Z._S_/^`??,K#X5H____BT,(BU7`*U7$BTL$C01` +XMC02""8A$+0D(]]$AB$@M"0B%_P^%7UWI^_7\_XM# +XM"(M+!(M5P"M5Q(T$0(T$@HG*]]()B$@M"0@AD$0M"0CI,?___XET)`3'!"1G +XM#0D(Z+1.``#I8?W__\=$)`A%R0@(BU7HQP0D8`T)"(E4)`3HE$X``(M%[`-] +XMZ(E]Y(NP0`\)".D1_?__ND7)"`CI;/W__\<$)`H```#HBA'^_XM%U(E%"(/$ +XM3%M>7UWI:/7\_\=%V`````#'1=P`````Z5G\__^0D)"0D%6)Y8/L&,<$)``` +XM``")7?B)=?SHY';\_XLU]&\)",=$)`Q\$@D(QT0D"`P```#'1"0$$P```(G# +XMH_!O"0BA@)@*"(D$).A65/W_B=HI\HE<)`B)="0$B50D#(D$).C>30``BUWX +XMBW7\B>Q=PXUT)@!5B>6+10B%P'0)H>QO"0B%P'0"7<-=Z7%X_/^0C70F`%6X +XM`@```(GE@^P8BQ7H=@H(A=)U!:$$=@H(QT0D"`X```#'1"0$J1()"(D$).CJ +XM6#[!B)=?R+=0P/KW4(B5WXA?9U!&:^`0"+ +XM#?1O"0B%R70UB30DZ$]W_/^%P(G#="")="0(B1PDQT0D!`````#H=73\_XG8 +XMBW7\BUWXB>Q=P^AH____Z]G'!"0`````Z,9U_/^C]&\)".NXC78`58GE4X/L +XM!(M="(7;=0*S`:'T;PD(A6#[!B)7?B+70R)=?R+ +XM=0B%VW4"LP&A]&\)"(7`=$&%]G0>B5PD!(DT).@K;HJO[__XG8BW7\BUWXB>Q=P\<$)`````#H +XM_G3\_Z/T;PD(ZZR0D)"0D)"0D)"0D%6)Y8/L&*&`F`H(QT0D#+@2"0C'1"0( +XM#````,=$)`04````B00DZ&52_?^)!"3H_4L``*&`F`H(QT0D#.@2"0C'1"0( +XM#0```,=$)`04````B00DZ#A2_?^)!"3HT$L``*&`F`H(QT0D#!P3"0C'1"0( +XM#@```,=$)`04````B00DZ`M2_?^)!"3HHTL``*&`F`H(QT0D#%03"0C'1"0( +XM#P```,=$)`04````B00DZ-Y1_?^)!"3H=DL``*&`F`H(QT0D#)03"0C'1"0( +XM$````,=$)`04````B00DZ+%1_?^)!"3H24L``*&`F`H(QT0D#-03"0C'1"0( +XM$0```,=$)`04````B00DZ(11_?^)!"3H'$L``*&`F`H(QT0D#/P3"0C'1"0( +XM$@```,=$)`04````B00DZ%=1_?^)!"3H[TH``*&`F`H(QT0D#"@4"0C'1"0( +XM$P```,=$)`04````B00DZ"I1_?^)!"3HPDH``*&`F`H(QT0D#&`4"0C'1"0( +XM%````,=$)`04````B00DZ/U0_?^)!"3HE4H``*&`F`H(QT0D#)04"0C'1"0( +XM%0```,=$)`04````B00DZ-!0_?^)!"3H:$H``*&`F`H(QT0D#+04"0C'1"0( +XM%@```,=$)`04````B00DZ*-0_?^)!"3H.TH``*&`F`H(QT0D#.P4"0C'1"0( +XM%P```,=$)`04````B00DZ'90_?^)!"3H#DH``*&`F`H(QT0D#!P5"0C'1"0( +XM&````,=$)`04````B00DZ$E0_?^)!"3HX4D``,<$)`&Z"`CHU4D``*&`F`H( +XMQT0D#$P5"0C'1"0(&0```,=$)`04````B00DZ!!0_?^)!"3HJ$D``*&`F`H( +XMQT0D#'P5"0C'1"0(&@```,=$)`04````B00DZ.-/_?^)!"3H>TD``,G#B?:- +XMO"<`````58GE4XG#@^P4H8"8"@C'1"0,T!4)",=$)`@$````QT0D!!0```") +XM!"3HHD_]_XE<)`2)!"3H-DD``(/$%%M=PU6)Y5=64XG3@^P\B470C47LB47< +XMC47DB57LB4W,B474C47`!````QT78`0`` +XM`,=$)`1H/0D(B00DZ#[J___'1"0$,"H("(G'B00DZ'SP_/^+1=`/MA08@/H! +XM#X3O````H>"E"PB%P'0E#[;2ON"E"P@Y%>2E"PAT?K[@I0L(ZP4Y5@1T57B==6B<93@^PLQT7D```` +XM`,=%Z`````#'1>P`````BP"%P`^$L0```(U=Y,=$)`2PD0@(B1PDZ+'N_/^) +XM=?"+!H7`=%.-=?#K(XUV`(/X7G0EB40D!(D<).AO80``BT7P@\`$B47PBP"% +XMP'0K)?__/P"#^%QUUHDT).@.Z___@_C_=2)!"3H +XMQ?G__XD'BT7HB4<$@\0LB?A;7E]=PZ&`F`H(,?_'1"0,018)",=$)`@%```` +XMQT0D!!0```")!"3HG$S]_XD$).@T1@``@\0LB?A;7E]=PXUV`(V\)P````!5 +XMB>575E.#[%RA/&0)"(M]"(7`#X2+````C4<$B46TBU\$A=L/A,T#``"+`R7_ +XM_S\`@_@M#X6U`@``BT,$)?__/P"#^"T/A'T#``"-5PBY`0```,=%O,"K"PC' +XM1<``````QT7$`````,=%R`````#'1 +XM7UW#D(UT)@#_)(48%PD(Z`1'__^#Q%Q;7E]=P^CW2/__Z6O____'1<`"```` +XMBQJ#P0&)UH7;#X0S`P``BP,E__\_`(/X+0^%T@(``(M#!(U6!"7__S\`@_@M +XM=9*-40&-!)4`````C30'BQZ%VP^$_`(``(/"`8E5T(M%R(7`#X4=`@``BTW, +XMA*?````C478B50D!(D$).C\7@``C478B00DZ,'K_/^-5=B) +XM%"3H9NO\_XU-V(D,).@[7P``BT7<@\`!P>`"B40D!(M%V(D$).B#]___B47L +XMBT7R)!"3HQ^O\_XM%[(L0@?K_````B56X#X]T`0`` +XMBT7$A<`/A#(!``"+?R)!"3HF.'__XM% +XM[(D$).C=ZOS_Z2O^___'1<@!````D.E0_O__QT7$`0```(UT)@#I0/[__\=% +XMP`$```"-="8`Z3#^___H1D?__X/$7%M>7UW#QT6\P*0+".D7_O__QT7,`0`` +XM`.D+_O__BQ7@I0L(,=N%T@^$R?W__XVV`````(N#Z*4+"(E4)`3'!"1<%@D( +XMB40D".A&0P``BY/LI0L(@\,,A=)UV8/$7%M>7UW#QT6\P*L+",=%P`````#' +XM1<0`````QT7(`````,=%T`(```"-5>R)V.C$^___A<`/A=+^___I6OW__XD< +XM)(UT)@#HJ\3__X7`#X3:`@``BP:)!"3H26$``(E%[(D$).@::/S_B47PZ9S^ +XM__^+3="+1="+-(_!X`*%]@^$H`,``(M5M(L<`H7;#X3C`@``Z&_V__^+1>R) +XM!"3HI.G\_^GR_/__Z!KY__^+1>R)!"3HC^G\_^G=_/__@\$!B4W0Z5#]__^) +XMV.CX^/__C478B00DZ&WI_/_IN_S__[H"````L`C'1;S`JPL(QT7``````,=% +XMQ`````#'1<@`````QT7,`````.GW_/__H8"8"@@QV\=%V`````#'1=P````` +XMQT0D#&T6"0C'1"0(!@```,=$)`04````B00DZ%1(_?^)!"3H[$$``#'2#[:" +XMP*L+"#J#P*L+"'0/C4O_N,"K"PCHGOC__XG:@\,!@?L``0``==>Y_P```+C` +XMJPL(Z(+X__^A@)@*"&8QV\=$)`R$%@D(QT0D"`<```#'1"0$%````(D$).CJ +XM1_W_B00DZ()!```QT@^V@L"D"P@Z@\"D"PAT#XU+_[C`I`L(Z#3X__^)VH/# +XM`8'[``$``'77N?\```"XP*0+".@8^/__H8"8"@C'1"0,GA8)",=$)`@(```` +XMQT0D!!0```")!"3H@T?]_XD$).@;00``QP0D`````.COZO__H8"8"@C'1"0, +XMN!8)",=$)`@)````QT0D!!0```")!"3H2D?]_XD$).CB0```C478B00DZ$?# +XM___I-?O__X-[!"T/A5G^__^+0PB-@,``(U%V(D$),=$)`0;````Z.E:``"+!HU5V(D4 +XM)(E$)`3HV%H``.G7^___C578QT0D!!L```")%"3HP%H``(U-V(ET)`2)#"3H +XM(5T``.FP^___@_@_NG\````/A8O[___ICOO__Z&`F`H(BQ['1"0,S!8)",=$ +XM)`@!````QT0D!!0```")!"3H0D;]_XE<)`2)!"3HUC\``.GN_/__C47LB00D +XMZ";!___IZ?O__X-]P``/A>X```"+'>"E"PB_X*4+"(7;=17I?0$``(UV`(/' +XM#(L?A=L/A&T!``")-"3H&V```(E<)`2)!"3HNV?\_X7`==L/ME\$A-L/A)?[ +XM__^+5<@/ML.%T@^%A0(``(-]\`$/CJH"``")!"3H?]O__\=$)`@`````B40D +XM!(U%[(D$).CHWO__BT6\BU6XQ@00->E1^___BUV\`UVX@#LU#X0J`0``Q@,! +XMZ3K[__^+=R)!"3HS^C__^D2^___ +XMC4W8B70D!(D,).AK60``Z6KZ__^)-"3HFF/\_^D'^O__#XP;_O__@WW``@^/ +XM$?[__XU=Y(GPB=KH;??__X7`#X3-^O__QT0D!#`J"`B+1>2)!"3H0N;\_XM- +XMR(7)#X2L````B1PDZ,_:__^+3<")3"0(B40D!(U%[(D$).AIP/__@\`!#X0U +XM`0``BT7DB00DZ+7E_/^+5;R+3;C&!`HUBT7LB00DZ%#E_/_HV[C__^F9^/__ +XMC47LB00DZ)O`___I3OK__Z&`F`H(QT0D#/\6"0C'1"0(`P```,=$)`04```` +XMB00DZ&%$_?^)="0$B00DZ/4]``#I&/K__XU%[(D$).BEV___Q@,!B?;I`_K_ +XM_XD<).@CVO__BU7`B50D"(E$)`2-1>R)!"3H;=W__XM%N(M-O,8$`36+1>R) +XM!"3HN.3\_^D&^/__C47LQT0D!&@]"0B)!"3H\-[__\=$)`0P*@@(B<:)!"3H +XM+N7\_XL5X*4+"(72=#LQV^L-BY/LI0L(@\,,A=)T*HM%[(M-O(L`#[8$"#F# +XMY*4+"'7?B50D"(ET)`3'!"3C%@D(Z#L]``#KR8DT).A!Y/S_D.E3^?__H8"8 +XM"@B+7>S'1"0,[18)",=$)`@"````QT0D!!0```")!"3H8T/]_XE<)`2)!"3H +XM]SP``.F=_O__#("-3=B)1"0$B0PDZ'%7``#IR)!"3HPN/\_^EM_O__C47LB40D!(M-O(D, +XM).C+VO__BT6\BU6XB!P0Z;7X__^0D)"0D)"0D)"0D)"053'`B>5=PXGVC;PG +XM`````%4QP(GE7<<%_&\)"`````##D)"0D)"0D)"0D)"0D)"058M*"(GEB5`$ +XMB4@(B4((BU`(B4($7<.)]HV\)P````!5B>56B=93BPB)TX7)="60BQ.%TG0> +XM.=%T/(VV`````(/Y('0;@\`$BPB%R77RA_/^) +XMP^EX____C;8`````58GE5U93@>P<(0``C46TC5VLQT74`````,=%V`````#' +XM1=P`````QT6L`````(D$).AF9/S_QT6P`````,=$)`@`````B5PD!,<$)!0` +XM``#H1V/\_XU%X(D$).B`*O[_Z(=?_/^%P(G'#X4V`0``BT7@C5W$B00DZ*/D +XM_?_'1"0$H$$(",<$)`X```#H>V/\_XD<).@#9/S_B1PDQT0D!`X```#H`U_\ +XM_XE<)`2-G0S____'1"0(`````,<$)`(```#HE5[\_\<$)`(```#HZ6/\_XM% +XMY,=%[(````")7"0$B84`W___C47LB40D"*&T=@H(B00DZ/%A_/^#P`%T%P^V +XMA0W___\\'`^$H@$``#P"#X2:`0``Z*1G``"%P(G&='(/M@"$P'1K/#IT9\=$ +XM)`0Z````B30DZ$]@_/^%P(G#=`/&``")-"2)]^@\8?S_@\`!#X2E`0``B3PD +XMZ*MD_/^%P(G#=0OK*XVT)@`````!QXN%`-___XE<)`B)?"0$B00DZ(C@_?^% +XMP`^(8@$``"G#==S'!"0`````D(UT)@#H-V/\_XM%Y(V=#-___XD$).AJX_W_ +XMZQN%P`^$KP```(E$)`B-1=2)7"0$B00DZ%U6``"+1>#'1"0(`"```(E<)`2) +XM!"3HQN#]_X/X_W7)QT78`````,>%_-[__P$```"+1>"-=?")!"3H$N/]_^L5 +XMZ*=@_/^#.`1U*(VV`````.B[4```BX7\WO__B70D!(D\)(E$)`CH@5W\_X/X +XM_XG#=,Z-1=3'1"0$T)$("(D$).A;X/S_.=]T(HU%U(D$).BLW_S_@<0<(0`` +XM6UY?7__\`````ZX6+1?"H?W77P?@(AR_('`)",=$)!@"````QT0D +XM%`````#'1"00`````,=$)`P!!```QT0D""!P"0B)1"0$B1PDZ#]@_/_I9_[_ +XM_\<$)`$```#HWF'\_SG>#X2._O__C46,N0@```")A?C>__^+O?C>__\QP/S' +XM1>@`````\ZO'19``````QT64`0```,=%C`,```")-"3HR6+\_XG#Z(9>```Y +XMPP^#K0```(U%Z(E$)`R-18R)1"0(QT0D!`````")-"3H+&/\_X7`=$C'1>@` +XM````Z13^__^)1"0$B30DZ*3F_?_'1"0$`````(G#C47HB40D#(U%C(E$)`B) +XM'"3H\&+\_XD<)(/X`1G`(47HZ'3I__^+1>B%P`^$S?W__XM0%(72#X2R```` +XMB50D!+\@<`D(QT0D"`$$``#'!"0@<`D(Z&U=_/^+1>B)!"3H\F#\_^E:_?__ +XMC9T,W___QT0D!``!``")'"3H5V'\_X7`=:/&A0O@__\`QT0D!"X```")'"3H +XM7%W\_X7`B<=TAL=$)`0N````B30DZ$9=_/^%P`^$;O___X!X`0"-6`%T%(E$ +XM)`2)/"3HJ5[\_X7`#X45____QT0D!"X```")'"3H$5W\_X7`=<_I./___XD$ +XM).A@8/S_C70F`.G__/__C70F`(V\)P````!5B>6#[`C'!"0!````Z"I@_/^- +XMM"8`````C;PG`````%6)Y8/L&(M%"(E=](EU^(E]_(D$).BV5@``B00DZ.[E +XM_?^)QHM%#(D$).BA5@``B00DZ-GE_?^)P^B^7?S_QP``````B5PD!(DT).B< +XM7/S_BQ= +XMPY"-="8`B30DZ.CG__^)'"3HX.?__^AG7?S_BP")!"3H#5O\_\=$)`1(&`D( +XMQP0D-@```(E$)`CH2=K\_^NCC;0F`````%6)Y8/L&(M%#(/X!`^$@````(/X +XM(W0,@\`!=`?)N/_____#QT4,`````,=$)`@`````QT0D!`,```"+10B)!"3H +XM=UG\_X/X_W32@^#[B44,B40D",=$)`0$````BT4(B00DZ%59_/^#P`%TL(U% +XM#,=%#`````")1"0(QT0D!'YF!("+10B)!"3H'UK\_X/``72*R3'`PXUV`(V\ +XM)P````!5B>575E.#[!R+70B%VP^$U````(M%"(L`B47LQT0D!,28"@C'!"20 +XM+PD(Z,!#_O\]^&\)"(G#="&)!"3HZUG\_XE<)`2)1"0(BU7LB<:)%"3HAEO\ +XM_X7`=&NA`'`)"(7`B47P=%6+'21T"0@Q_XGVBW,(B70D"(M#!(E$)`2+1>R) +XM!"3H4UO\_X7`=2.+1>R-%+"+`H/X+W0$A7UW#BPT`<`D(A575E.#[!R+50B+`H/X*P^$I@```(/X+0^$G0```(L= +XM)'0)"(7;#X1F`0``H0!P"0B+-21T"0B-!$"-/(8Y_G-CBT4(BP")1?#K#HUV +XM`(7`>$R-7UW#C78`B=\Y_G*UBT4( +XMB00DZ(]1``")!"3HY]G]_X7`=1+'1>P`````BT7L@\0<6UY?7<.+0!R)!"3H +XMEE,``(D$).@^3P``A<")1>QTVXL=`'`)"(M5"(T<6\'C`HD4)`,=)'0)".@: +XM3P``B0.A`'`)"(M5[(L])'0)"(T$0(E4AP2+-0!P"0B)%"3HT57\_XT<=H/& +XM`<'C`HE$.PB)-0!P"0C'1"0,,$8(",=$)`@,````B70D!(D\).A"5/S_H0!P +XM"0@[!9A-"0@/A5G___^#P`JCF$T)"(T$0,'@`HE$)`2A)'0)"(D$).AVX___ +XMHR1T"0CI,/___\<$)'@```#H$./__Z,D=`D(Z83^__^-M@````!5B>575E.# +XM["S'1"0$Q)@*",<$)"`^"0CH\S[^_XE%W,=$)`3$F`H(QP0D8#X)".C#H4_/__PG#B47D="R+'0"8"@B%VW0B +XMB?:+0WB)-"2)1"0$Z#'6_?^%P'0'BT,4A+!H/X.W01.7T(=-^+ +XM?PB+-XL&@_@[=>^+?P@Y?0AUUX/$+%M>7UW#QP0DF#X)".@]5/S_B47HBP>) +XM!"3H,%3\_XE%[(T$A00```")1"0$QP0D`0```.A:X?__B47PBP>)1"0$BU7P +XMB10DZ`)3_/^+=>2%]@^$,P(``(L'B00DZ-'@___'1"0$%````,<$)`$```#H +XM'>'__XD'QT0D!(`R"0B)!"3HQU+\_\=$)`0,````QP0D`0```.CWX/__QT0D +XM!!@```#'!"0!````B<;HX>#__XD&QT0D!+0^"0B)!"3HBU+\_XGPB?KHYO'_ +XM_XL&BP"#^`IT$8/X.W0,BW8(BP:+`(/X"G7OQT0D!`P```#'!"0!````Z)C@ +XM___'1"0$"````,<$)`$```")P^B"X/__B0/'1"0$P#T)"(D$).@L4OS_BU8$ +XMB=CHAO'__\=$)`0,````QP0D`0```.A2X/__QT0D!`@```#'!"0!````B) +XM!"3HGM[__XM5[,<$)`$```"-!)4(````B40D!.CDWO__B0?'`"4```"+1?") +XM1"0$BP>#P`2)!"3HA%#\_XM?"(L+BP&#^#L/E<*#^`IT>X32='V#Q"Q;7E]=PXG?Z6'\__^-="8`58GE5U93@^P\QT0D +XM!,28"@C'!"3D2`D(Z#,Z_O^%P`^$[````(M%"(MX"(L'@S@[#X3C````.7T( +XM#X32````QT78`````,=%W`````#'1"0$`$D)"(L'B00DZ-U/_/^%P`^%XP$` +XM`(M7"(E5U(L2BP*#^"V)1>`/A+$```"#?>`MBW74#X3Z````BT78A`[#X2/`0``BWW4.7T(#X2#`0``BW\(BP>+`(/X.XE%X'08 +XM.7T(#X1N`0``BW\(BP>+`(/X.XE%X'7HBW\(.7T(#X4\____@\0\6UY?7<,Y +XM?0AT\XM_"(L'@S@[#X4*____Z^N+3=R%R0^%1/___XMUU(M%W(M*!(7`#Y3` +XMA)TX/Y:0^4PH/Y9HM+"`^4P`G0@^`!B47<#Y3`@\,$A"#?>`[#X5Q_O__BWW4@WW@.P^%FO[__^F2_O__A,`/A=;^__^0C70F`.GQ +XM_O__BP>+`(/X"G1Z@_@[='4Y?0AT<(G[ZPV#^#N0=#LY=0AT+XGSBU,$BT,( +XMB4((BT,(B5`$BP.)!"3H#MO__XMS"(D<).@#V___BPZ+`8/X"G7&@_@[=2:+ +XM#HM6!(M&"(E""(M&"(E0!(D,).C7<,YUG;CZ]20C70F`#'VZYS'!2AT"0C04`@(BQ.)QHM"!(7` +XM#X5/____ZX&0A?8/A'C___\IQHVV`````.EK____B<;'!2AT"0A040@(Z5K_ +XM__^-=@"-O"<`````58GE@^P(_Q4H=`D(QP0D`0```.BH_O__R<.-M@````!5 +XMB>6#[!C'!"16&`D(Z!XG``"AY)D+"(7`=`7H\$___Z&T=@H(B00DZ"/1_?_' +XM1"0(`@```,=$)`1@+@D(QP0D`"X)".CG/O[_QT0D!`````#'!"0`````QP7D +XM=0D(`0```,<%A'<*"`````#HGVW\_\G#C;8`````C;PG`````%6)Y5=64X/L +XM?*$LF0L(B00DZ#K/_?^%P(E%D`^$PP$``(MX!(7_#X2X`0``QP0D`````(UU +XM\^CE_?__QP0D"@```.B)Z?W_QT6,`````,=%M`$```"-1;R)!"3H[$_\_XU% +XMG,=%N`````")1"0(C46TB40D!,<$)`(```#HRT[\_XU%S(D$).C`3_S_C47, +XMQT0D!`(```")!"3HO4K\_XU%W(E$)`B-1!0CHE,W\_XU%W(D$),=$)`1@'@4(Z('-_/_HK$___\=$)`0" +XM````QP0D8Q@)".BXS?W_B47L@\`!#X7M````H;1V"@B)1>S'1"0$;!@)",<$ +XM)/O>"`CHD"4``.A[YOW_QP4P=`D(`````.L;#[9%\SP*="X/OL")1"0$QP0D +XM+'0)".C$0```QT0D"`$```")="0$BT7LB00DZ/W,_?^%P'_*QP0D+'0)".C] +XM0```C46TB00DZ$+,_/^+'2QT"0B)?"0$B1PDZ,Q,_/^)?"0$B00DZ%!-_/^% +XMP'1IBT60BQBA@)@*",=$)`QV&`D(QT0D"`(```#'1"0$%@```(D$).A&*_W_ +XMB5PD!(D$).C:)```@T6,`8-]C`4/A6K^___HE_W__X/$?%M>7UW#C47LQT0D +XM!$`>!0B)!"3H7,S\_^D#____B1PDZ*M/_/_'1"0$`````(D<)(E$)`CHUTO\ +XM_Z&$=PH(A2A*)H+"(E%X*$DF@L(B47"0B%P'02B00DZ/?5___'!8!>"0@`````QT7L^&\)",=$)`0,````QP0D +XM`0```.@RUO__B<:+10R)!"3H!4(``(D&@WT(`0^$``(``,=$)`0,````QP0D +XM`0```.@%UO__B<.+11")!"3HV$$``(ES!(EU](E=\(E>"(D#C47LB4,(B48$ +XMC5WLQT0D!)#I!0B)'"3H[LK\_\=$)`3$F`H(QP0D]"X)".@Z,O[_B00DZ$(P +XM_O^)'"2)1;#HA^/]_XM%],=$)`@`````B5PD!(D$).@`X/W_QT0D!$`K!@B) +XM1:R)!"3HGR)!"3HX\C\_^@^[_W_BT6PB00DZ',Q_O_'1"0(`@`` +XM`,<$)/0N"0B)1"0$Z&LY_O^#Q&!;7EW#C70F`.@K!```Z[OH!`4``*$\=`D( +XMAOIC47LB77PB77TB48$B48(Z23^__^0C70F`%6)Y8/L&(E=^(EU_(MU +XM"(,%Q*P+"`''1"0$L)`(",<$),2L"PCH]LC\_XL=0'0)"(7;=3.+#>"9"PC' +XM!4!T"0@!````AQ=Z1G(_/_' +XM1"0(U#<)",=$)`2`-PD(QP0D`@```.BM_/__QT0D#/08"0C'1"0(#@```,=$ +XM)`06````H8"8"@B)!"3H*"?]_XD$).C`(```ZY;'1"0$E'8*",<$)-0W"0CH +XM6B_^_X7`#X1Z____BQV`=PH(B70D",=$)`34-PD(QP0D`@```.A$_/__B1V` +XM=PH(Z5'___^)]HV\)P````!5B>53@^PDQT0D!+"0"`B#!<2L"P@!QP0DQ*P+ +XM".C^Q_S_H41T"0B%P'4UH>"9"PC'!41T"0@!````A"9"PC'!4QT"0@!````A6#[!C'1"0$L)`("(,%Q*P+"`''!"3$ +XMK`L(Z/_$_/^+#3QT"0B%R74LBQ7@F0L(QP4\=`D(`0```(72=&/'!"3$K`L( +XMQP4\=`D(`````.@KQ/S_R"+%0B:"PB)1=RA!)H+"(E5V(L5`)H+"(E%U*&$=PH( +XMB570BQ7`F`H(QP6$=PH(`````(E%R(E5Q.@MO_S_QP0D`)H+"(E%S.C*0/S_ +XMA<`/A)P```#'!"0!````Z&KR__^+52)%1B: +XM"PB+5>"C%)H+"(M%W(D5$)H+"(M5V*,,F@L(BT74B14(F@L(BU70HP2:"PB+ +XM1<2)%0":"PB+5?]_\<$)`````#H%43\ +XM_XM%",<%R*P+"`$```#'1"0$`0```(D$).@L\/W_A,<$)(0` +XM``")1"0$Z+6^_/_KNXUV`%6)Y8/L6(U%Z(E%Y(U5W(E%U(M%"(EU^(UUT(E= +XM](E]_(M]#(E5V(EU\(EUX(E5[,=%T/AO"0C'1>CH10D(QT0D!)1V"@B)!"3H +XM4BC^_X7`B<-T+(L`A564X/L$*%@90D(BUT(AB7E/__BT,$B00DZ/PX``") +XM!"3H-,C]_\=$)`0P*@@(B<:)!"3H`L#\_XM#"(D$).C7.```B00DZ`_(_?_' +XM1"0$,"H("(G#B00DZ-V__/^)7"0$B30DZ$&M__^)=0B#Q!!;7EWI([_\_XUV +XM`%6)Y5.#[`2A8&4)"(M="(7`=07H&)3__XU#!(E%"(/$!%M=Z=BE__^0C;0F +XM`````%6)Y8/L"*%@90D(ACLD___R>D6L/__C;8`````58GE5U93@>R< +XM````BT4(C5`$BT`$A<`/A(@%``")%"3HNVO]_XE%@(D$),=$)`3P(P8(Z#B_ +XM_/^+58"+`H7`="*#."T/A*T"``")T.L.B?:#P`2#.BT/A)L"``"+4`2%TG7M +XMQT7H`````(U-Z,=%[`````#'1?``````QT0D!+"1"`B)#"3HY;[\_XM%@(L0 +XMA=(/A`0&```Q_\>%=/___P````#'A7C___\!````ZV>)-"3HF#<``(U5B(E4 +XM)`2)!"3H)3[\_X/``0^$L@$```^W19"+G7C___\E`/```#T`0```#X2````` +XMB30DZ-Z]_/^+C73___^+18"+5(@$@\$!@X5X____`8F-=/___X72#X0Q!``` +XM,<"#/=B7"@@"B10D#Y3`B40D!.C1COS_QT0D!#`J"`B)QHD$).@OOOS_B30D +XMZ,/POC5#\#X5:____.=8/A%+____'0/P`````Z4;___\YO73___]T +XM,H7_#X4:!```QT0D#`````"+A73___\I^(E$)`B+58#'!"3X;PD(C02ZB40D +XM!.BL;?[_BY5T____A=)T%HM-@(M!!(7`=`S'!"0*````Z!S9_?^)="0$QP0D +XMJQ@)".CL%0``QT7L`````(L&AB+1>R#Z@2-!(*!."\``$`/A,@```"- +XM3>C'1"0$+P```(D,).@9,```C47HB00DZ&XP``"-5>C'1"04`````,=$)!#X +XM;PD(QT0D#`````#'1"0(_P\``,=$)`0`````B10DZ#N._O^+O7C___^)^^EH +XM_O__Z/4\_/\YO73___^+&'0RA?\/A7\#``#'1"0,`````(N%=/___RGXB40D +XM"(M-@,<$)/AO"0B-!+F)1"0$Z(UL_O^)'"3H83K\_XET)`3'!"2B&`D(B40D +XM".CA%```B[UX____B?OI_OW__\<`+P```.E+____H91W"@B%P`^%)0,``*&` +XM7@D(AB)4`B)1>R)%"3'1"0$D.D% +XM".C/NOS_C47HQT0D"`````")1"0$BT7PB00DZ`70_?_'1"0$0"L&"(G#B00D +XMZ*.Z_/^+-8!>"0B%]G0,QP0D````0.B=M_S_BQ74EPH(,<#'1"00`````,=$ +XM)`P`````QT0D"`````"%T@^?P(/H`0G"B50D!(D<).A7!/[_C57HB10DZ*RY +XM_/^+#91W"@B%R0^%2`$``(M%@(D$).B3N?S_@<2<````6UY?7<.-5>B)%"3H +XM?;G\_SG[=-N%_P^%+`$``"G[QT0D#`````")7"0(BTV`QP0D^&\)"(T$N8E$ +XM)`3HS6G^_^NMQP5$3`D(>````.D,_O__QP0D"@```.A`U?W_Z=7[__^-7>C' +XM1>@`````QT7L`````,=%\`````")'"3HZRP``(D<),=$)`2PD0@(Z)NY_/^) +XM'"3'1"04`````,=$)!#X;PD(QT0D#`````#'1"0(_P\``,=$)`0`````Z*N* +XM_O^)'"3HP[C\_X'$G````%M>7UW#QP0D"@```.B\U/W_Z7#\__^#!<2L"P@! +XMQT0D!+"0"`C'!"3$K`L(Z"RY_/_IN_S__\=$)`0,````QP0D`0```.CSP___ +XMQP0D@$P)"(G#Z,4O``")7PB)>P2)WXD#Z;#]___'!"3$K`L(Z$JX_/_II_[_ +XM_\<$)`H```#H2=3]_^G#_O__C57HB10DZ"FX_/_IAO[__XUT)@!5B>575E.# +XM["R+10C'1>@`````QT7L`````,=%\`````"%P`^$\````(MP"#G>```` +XMBT`$.?")1>`/A-<```#'1=@`````C7WHQT7<`````(M%##E%W'QXBU40.57< +XM?W"+'HL#ASKZ(U%Z(D$).B<*@``@\0L6UY?7<.-="8`58GE@^P8BT4(QT0D"/___W_' +XM1"0$`````(D$).BO_O__R<.-M@````"-O"<`````58GE5U93@^PLQP0DL!@) +XM".AG,_S_A<")1>0/A.8!``"+1>3'1"0$+P```(D$).A)-OS_AB+7>@/M@/'1?``````A,!T+HL5W%T)"(L-X%T)"(GV#[;`.=!] +XM!_9$@35`=1*#1?`!BW7PBUWH#[8$'H3`=>"+=>0/M@;'1>P`````A,!T+XL5 +XMW%T)"(L-X%T)"(UV``^VP#G0?0?V1($U0'42@T7L`8M=[(MUY`^V!#.$P'7@ +XMH3QW"@@QVX7`#X3=````BQT`F`H(A=L/A,\```#'1>``````ZPJ+&X7;#X2Y +XM````BT,8.T,<=>Z+0PPE'R```#T`(```=`J#^`)T!8/X$'75BT-XB00DZ/0N +XM``")QP^V`(GZA,!T)(L-W%T)"(LUX%T)"`^VP#G(?0?V1(8U0'4*@\(!#[8" +XMA,!UZ,8"`(G^QT0D!"\```")/"3H[#3\_X7`=`.-<`&+1>R+5>2)="0$B40D +XM"(D4).A_,OS_A"#Q"R)V%M>7UW#BT7PBU7HB70D!(E$)`B)%"3H,#+\_X7` +XM#X42____ZZO'1>1-&PD(C78`Z2C^___'1>B^&`D(Z5#^__^0D)"0D)"0D)"0 +XMD)"0D)!5N@$```")Y8/L"(M-"/?!```@`'4J,-*%R70D@?G_````=SRAX%T) +XM"(M$B#2)PH'B````X'0-P>H>C;8`````R8G0PR4```0`@_@!&<"#R`&)PL'Z +XM'\GWTB'"B=##B?:)#"3HY#'\_^O#C;8`````58GE5U93@^P,BT4(BQB%VP^$ +XMI0```(L]X%T)"(G&ZRKWPP```$!U&('[_P```'=CBT2?-/;$$'5GC;0F```` +XM`(M>!(/&!(7;='&+10R%P'3/]\,```!`=>>!^_\```"0=T^+1)\T9H7`>=6! +XM^_\```!W4HN7UW#B1PDZ$$Q +XM_/_VQ!!TH('[_P```'6#[!B)=?R+=0B)7?CWQ@`` +XM(`!T$;O\____B=B+=?R+7?B)[%W#B30DZ(#^__^%P(G##XZ[````]\8```!` +XM==J!_O\````/AYD```"AX%T)"(M$L#3VQ`)TP(GP)?__/P`]_P```'^R@?[_ +XM````#X>/````H>!="0B+1+`TJ0``!`!T!XM5#(72=(^!_O\````/AWP```"A +XMX%T)"(M$L#3VQ`)T#HGP)?__/P`]_P```'YP@?[___\`N_G___\/CU;___^! +XM_O__``"S^@^/2/___X'^_P```+/[#XXU____Z37___^)-"3H#3#\_Y#I8O__ +XM__?&````0'6XC78`Z67___^)-"3H[R_\_XUV`.EJ____B30DZ-\O_/^-=@#I +XM??___X/^"KO]____#X3I_O__,=N#_@D/E<.#ZP+IV?[__XVV`````(V\)P`` +XM``!5B>575C'V4X/L#(M5"(L"AH> +XM@\,$`=:%P'7<@\0,B?!;7E]=PY"-="8`B00DZ#0O_/_KSI"0D)"0D%6)Y5W# +XMD)"0D)"0D)"0D)"A4'0)"#D%5'0)"%6)Y700#[95"(@0@\`!7:-0=`D(P\8` +XM`%W#C70F`(V\)P````!5B>575E.)RX'LC````(E%A`^V`H3`#X0(`0``B56, +XMQT6L`````.LD#[;`"T6LB00D_U6$B5W0@T6,`8M5C`^V`H3`#X3;````BUW0 +XM/"5UV(-%C`&+58P/M@+'19P`````/"T/A',!```\,`^$O@```#PNQD6;(`^$ +XML@```#PJD`^$OP````^VT(/Z?W<.]@25O5$)"`0/A?T$``#'1:``````/"X/ +XMA+0```#'1:3___]_,?\\(P^$;@$``#'2/&P/A#P!```QR3QZ#X0A`0``#[;` +XM@_A3B464="6#^%%T(#L%W%T)"'T8H>!="0B+=91F@WRP-``/B$$!``"-="8` +XMBT64@^@E@_A3#X;&````@T6,`8M5C(E=T`^V`H3`#X4E____@<2,````6UY? +XM7<.#18P!BTV,#[8!QD6;,#PJ#X5!____BS.#PP2#18P!BU6,B76@#[8"/"X/ +XMA4S___^#18P!BTV,#[8!/"H/A'0$```/MM"#^G\/AR[____V!)6]40D(!`^$ +XM(/___XM%C(D$).C&*_S_BU6,B46D#[8"#[;0@_I_=A_I!O___XUT)@"#18P! +XMBTV,#[8!#[;0@_I_#X?L_O__]@25O5$)"`1UX.G=_O___R2%P!D)"(/"`8E5 +XMC`^V`L=%G`$```#I>/[__X-%C`&Q`8MUC`^V!NG._O__@T6,`8M5C`^V`KH! +XM````/&P/A:W^__^#18P!L@*+38P/M@'IG/[__X-%C`%FOP$`BW6,#[8&Z7_^ +XM__^+A+`T!```N@$```")193IK_[__XUS!(EUT(L;A=N)79`/A`$$``")'"3H +XM`"W\_XM]H"G'BT6FW^O__C477B85X____B47,B1PDB70D!,=$)`@*````QT0D +XM#`````#H738``(M-S(/`,(@!@\$!B1PDB70D!,=$)`@*````QT0D#`````") +XM3)A7C___^)QXD<)(ET)`3'1"0("@```,=$)`P````` +XMZ&XX``"#P#"(!X/'`8D<)(ET)`3'1"0("@```,=$)`P`````Z&HZ``"#^@") +XMPXG6?[=\!8/X`'>PBUVHA=N0C70F`'0&Q@/___W;IBT6/___XE5S(M5S(G8@^`'#ZSS`X/`,,'N`XGQB`*# +XMP@$)V8E5S'7@A?]T&8MUS,8&,(/&`8GP*X5X____B77,Z7/\__^)T"N%>/__ +XM_^EF_/__C5,$B570BP.)QHG#P?X?Z7K^__^-0P0Q]HE%T(L;Z1?\__^-2P2) +XM3="+`\=%J`````")QHG#P?X?A?8/B5S^___WVX/6`/?>QT6H`0```.E)_O__ +XMJ0```$`/A&OZ__^+A7S___^)!"3_583I6OK__XU-V.LA@\`PB$'_B4W,B?*) +XMV`^LT`2#P0'!Z@2)PXG0B=8)V'05B=B#X`^#^`E^U8/`5XA!_XE-S.O3A?]U +XM$XM%S(U5UXF5>/___RG0Z:3[__^+3/___^F"^___B6#[`B+10B+ +XM312+51"C4'0)"`-%#(/H`:-4=`D(N+!M"`CH%_;__Z%0=`D(Q@``@\`!HU!T +XM"0C)PY"-="8`5;@@.P8(B>6+50B+30Q=Z>SU__^-M@````"-OP````!5N"`[ +XM!@B)Y8/L&(M5"(U-#(E-_.C']?__R<.0C70F`%6)Y8/L&(M%"(U-%(M5$(E- +XM_*-0=`D(`T4,@^@!HU1T"0BXL&T(".B4]?__H5!T"0C&``"#P`&C4'0)",G# +XMD)!5B>5=QP6`=`D($!L)",<%A'0)"!0;"0C'!8AT"0@8&PD(QP6,=`D('!L) +XM",<%D'0)""`;"0C'!91T"0@D&PD(QP68=`D(*!L)",<%G'0)""P;"0C'!:!T +XM"0@P&PD(QP6D=`D(-!L)",<%J'0)"#@;"0C'!:QT"0@\&PD(QP6P=`D(0!L) +XM",<%M'0)"$0;"0C'!;AT"0A(&PD(QP6\=`D(3!L)",<%P'0)"%`;"0C'!<1T +XM"0A4&PD(QP7(=`D(6!L)",.-M@````"-O"<`````58GE5U8Q]E.#["R+10R+ +XM.(D\).@$)/S_C02%!````(D$).BIL?__QT7P`````(E%[.L6H>!="0B+1)`T +XM]L0%=06#^U]U4H/&`8M%[(/'!(T$L(E%X(L?BT7L@>/___\_A?:)'+!U!8/[ +XM>W06#[;3@?K_````=KR)%"3H'2/\_Y#KNH/'!(L?@>/___\_B1C'1?`!```` +XMZ]2+1>#'``````"+5?"%TG00BP2+1`$$A +XM7UW#@\<$Z3;___^+1>R)!"3HTU#^_X7`=#"+$(72=,:)PX/Z"G07@_H-=!*+ +XM10@+51")!"2)5"0$Z*L7``"+4P2#PP2%TG7:ZYR+10R).(M%[(D$).@OK___ +XM,<#KG8UT)@"-O"<`````58GE5XG'5HG.4XG3@^P<@#H`="^-1?")7"0$QT0D +XM"`8```")!"3H!1\``(D\)`'#B?`+1?")1"0$Z$(7``"`.P!UT8/$'%M>7UW# +XMD(UT)@!5B>575E.#[$R+10S'1>``````QT7D`````,=%Z`````")1?"-112) +XM!"3H;2+\_\=$)`2PD0@(B47`C47@B00DZ`ND_/^+5?"+`H7`#X28````QT6\ +XM`````.M.D(UT)@"#?0@"#X3Y````H029"@C'!"0]W`@(@\`!B40D!.B>^___ +XMB<.+3;R)VHU%X.@?____B1PDZ#>N__^+1?"-4`2)5?"+0`2%P'1!@_@E=&6# +XM^%P/A)P```"#^%X/A),````[!8R8"@ATF`M%O(U5X(E$)`2)%"3H5A8``(M% +XM\(U0!(E5\(M`!(7`=;^-1>")!"3H"Z/\_XU5X(D4).BPHOS_C47@B00DZ$46 +XM``"#Q$Q;7E]=PXM:!(U*!(7;=*.)3?"+6@2-0]^#^%UV4H/[80^$`0<``(M% +XMO(/()8E$)`2-1>")!"3HYQ4``(M%\(L`Z77___^-1?")!"3HDI___^EE____ +XMBT48QP0D:````(E$)`3H^E;]_XG#Z0?_____)(5D&PD(@66\____^XM%\(GV +XMZ0?___^!3;P````$BT7PD.GW_O__BU6\BT7`QT0D!`(```")5"0(NA^%ZU&+ +XM2!2)R/?JB")%"2)PXE$)`3HM1<` +XM`.FA_O__BU7`BTV\BT(0BQ2%@'0)"(U%X.BH_?__BT7PZ8S^__^!9;S____? +XMBT7PZ7W^__^!9;S____WBT7PZ6[^__^#?0@!#X1W"```QT0D!,28"@C'!"2D +XM+PD(Z&0)_O\]^&\)"'0DBQ"%TG0>B<,+5;R-1>")!"2)5"0$Z,,4``"+4P2# +XMPP2%TG7DBT7PZ1W^__^#?0@!#X0*"```QP0D7!L)"#'VZ-4=_/^)PX7;=3OK +XM0)"#?0@!=`0\+G0UC57LB5PD!,=$)`@&````B10DZ!\<```!PXM%O`M%[(E$ +XM)`2-1>")!"3H6!0```^V`X3`=<&%]G24B30DZ.6K__^+1?")]NFG_?__@WT( +XM`0^$>@<``,=$)`3$F`H(QP0DO"X)".B="/[_/?AO"0@/A%G___^+$(72#X1/ +XM____B<,+5;R-1>")!"2)5"0$Z/03``"+4P2#PP2%TG7DZ2S___^A`)@*"+K_ +XM____AO(@4V\````((M%\.F3 +XM_/__@4V\````"(M%\.F$_/__@WT(`@^$IP8``(M-$(7)#X1*_O__BTV\C47@ +XMBU40Z'7[__^+1?#I6?S__X-]"`$/A+@%``#'!"1<&PD(Z!,<_/^)PX7;=`V+ +XM3;R)VHU%X.A$^___@WT(`0^%`?[__^D6_/__@4V\````$(M%\.D2_/__BT7` +XMBU@(QT0D!,28"@C'!"1@/`D(Z*P&_O^%P`^$L@0``(/["P^.YP,``(/[#+]P +XM````C78`?@.#ZPR+5<"+0@2%P`^%L`,``(M%"`L%:'0)"`^$=P,``,=$)`3$ +XMF`H(QP0D0$8)".A:!O[_BU6\B1PDB50D"(/X`1G`]]"#X`*)1"0$Z`W$__^) +XMPXE$)`2-1>")!"3H?!0``(D<).BDJ?__BW6\C57@B10D@\XZB70D!.CO$0`` +XMBU7`BT6\QT0D!`(```")1"0(BT($B00DZ,+#__^)PXE$)`2-1>")!"3H,10` +XM`(D<).A9J?__BT7PBP"#^'`/A"P$``"#^%`/A",$``#'1"0$Q)@*",<$)&`\ +XM"0CHK@7^_X7`#X3K`P``B?H/OL(+1;R)1"0$C47@B00DZ&\1``"+1;R#R&WI +XM__K__\=$)`3$F`H(QP0D]"X)".C0!?[_/?AO"0@/A(S\__^+$(72#X2"_/__ +XMB<,+5;R-1>")!"2)5"0$Z"<1``"+4P2#PP2%TG7DZ5_\__^#^V,/A-D#``#' +XM1"0$Q)@*",<$)&0S"0CH>P7^_SWX;PD(B<)/6!T"0C'!"1@=`D(Z$+! +XM__^C9'0)"*%D=`D(AL.@_@O#Y3`@\8$#[;``<&+ +XM!H7`=>R$TG0*,<"#/R\/E<`!P8M%\,=%Q`````"#P`2#.#`/A/4!``"+5?"# +XMP@2)5="+`KH!````B47,@^@Q@_@(=PR+5OV__^-5>")%"2)="0$Z'`-``"+1;R+5<#'1"0$`@```(E$)`B+ +XM`HD$).A$O___B<.)1"0$C47@B00DZ+,/``")'"3HVZ3__^F4^___LRZ-="8` +XMZ1S\__^+51C'1"0$30```(D4).C((```B")!"3HQ@P``(M#!(/#!(7`=>3I7?S__XM5&,=$)`1L````B10D +XMZ%0@``")P^GQ]?__BT48QT0D!&T```")!"3H.B```(G&B") +XM%"2#R#R)1"0$Z!0,``"#?<@)#XZ!````BT6\@\@YB40D!(U%X(D$).CU"P`` +XMBT6\C57@B10D@\@KB40D!.C@"P``BT6\C57@B10D@\@^B40D!.C+"P``Z")!"3HI@L``(L$G0A#"0B%P'7@ +XMBT7PQP5H=`D(`0```.GU]/__BT7(@\`P"T6\B40D!(U%X(D$).AQ"P``ZX_K +XM#9"0D)"0D)"0D)"0D)!5B>575E.#[!R+=0B+?0S'!"0`````Z`$4_/^#_@*) +XM1?`/A)0!``"#_@,/A'8!``"#_@$/A+T```#'1"0$Q)@*",<$)*@R"0CHD__] +XM_X/^`8G##XZT````H2QW"@B)!"3HFZ+__\=$)!``````BT7PQP4L=PH(```` +XM`(E\)`B)7"0$B40D#,<$)`````#HGO/__XL]Y)D+"(7_HRQW"@AU,HL0A=)T +XM&XG#C;0F`````(D4).@XM?W_BU,$@\,$A=)U[L<$)`````#H$EC__^CML/W_ +XMH7B9"PB)!"3H(*+__X7VQP5XF0L(`````'0O@\0<6UY?77UWI&K#]_XL=<'0)"(7;=":+/6QT +XM"0CIG?[__\=$)`3$F`H(QP0D`#,)".@1_OW_B"0B%P'02B00DZ&^@___'!8!> +XM"0@`````BT7")6`B)0P2+=P2#QP2)7>"%]G7*B=B- +XM5>2)4`B+5=R)1>B+`J/,=`D(BT((B00DZ$29_?^+1=R)!"3HZ9___XU5Y(D4 +XM),=$)`20Z04(Z%:5_/^-1>2)!"3H"Z[]_XM%[(U5Y(E4)`3'1"0(`````(D$ +XM).B!JOW_QT0D!$`K!@B)PXD$).@?E?S_BPV`7@D(A_?^-1>2) +XM!"3H-I3\_XL5S'0)"(72B57<=`R+0@0[1?`/C+W^__^+%81W"@B%TG0)H3AW +XM"@B%P'0>QP4X=PH(`````,<$),2L"PCH])/\_X/$+%M>7UW#Z+<6___H4C?_ +XM_XGVZ,LW___HQD?__^O*C70F`.B;%?__H!(7;#X2C`@`` +XMC58(B57@BP.#^"T/A,@!``"+=@B%]@^$>0,``*D```!`#X0Y`0``@_@K=`S' +XM!"1L````Z`&1_/^#PP2^`0```(D<).C!#```B00DZ&4/_/^)QXL#AR)5"00B70D#(E$)`B+1=S'!"0#````B40D!.BU[/__B1PDB<;H +XM6Y#\_\=$)`0P*@@(B30DZ.N0_/^+!H7`=!>)\XUV`(D$).CXK?W_BT,$@\,$ +XMA5=QP74=`D(`0```,.058GE7<<%V'0)"`$```## +XMD%6)Y5W'!=QT"0@!````PY!5B>6+10A=BP"CQ*P+",.058GE@^P(HL& +XM@\`$@\$$BQ&%TG0/.Q!T\(L+A6+10B+`(E%"%WI;YC__^L-D)"0D)"0D)"0D)"0D%6)Y8M%"(L`B44( +XM7>E/F/__ZPV0D)"0D)"0D)"0D)"058GE5E.#[!"+=0B+7@2%VW07,=N+!HL$ +XMF(/#`8D$).@7>D'F/__C;0F`````%6)Y8/L +XM&(E=^(G#B77\BT`(B=8[0P1T&(M3!(L#B320BUWXBW7\B>Q=PXVV`````(7` +XM=1_'0PA`````BT,(P>`"B40D!(L#B00DZ-&8__^)`^O%`<")0PCKX8VV```` +XM`%6)Y5.#[`2+70B+50R)V.B,____@T,$`8/$!%M=PXGV58GE4X/L%(M=",=$ +XM)`0`````B1PDZ,;___^+0P3!X`*)1"0$BP.)!"3HDR____B?95B>6#[!B)7?B)PXEU_(M`"(G6.T,$ +XM=!B+$XGQBT,$B`P"BUWXBW7\B>Q=PXUT)@"%P'453@^P$BUT(#[Y5#(G8 +XMZ(O___^#0P0!@\0$6UW#D%6)Y5.#[!2+70C'1"0$`````(D<).C&____BT,$ +XMB40D!(L#B00DZ*67__^#Q!1;753@^P4BUT(B=CHC?___XM#!(/``<'@`HE$)`2+ +XM`XD$).CVEO__@\046UW#58GE4X/L!(M="(M5#(G8Z%S___^#0P0!@\0$6UW# +XMB?95B>564X/L$(M="(MU$(M3"(GP`T,$.<)S.H72=16#^$!FN@`!QT,(0``` +XM`'86ND````")\`'2`T,$B5,(.=!W\L'B`HE4)`2+`XD$).A^EO__B0.+0P2- +XM%+4`````P>`"`P.)5"0(BU4,B00DB50D!.AF#?S_`7,$@\006UY=PU6)Y5.# +XM[!2+70R)'"3H.@C\_XE<)`2)1"0(BT4(B00DZ%O___^#Q!1;7<.0C70F`%6) +XMY593@^P0BUT(BW40BU,(B?`#0P0YPG,UA=)U$X/X0+)`QT,(0````'83ND`` +XM``")\`'2`T,$B5,(.=!W\HE4)`2+`XD$).C3E?__B0.+4P2+10P#$XET)`B) +XM1"0$B10DZ,4,_/\!)\I"-="8`BP*# +XMP@2%P'7WN/S___\IV"GP`<@!T(D$).C2E/__B=J)QXG!BP*#P@2)`8/!!(7` +XM=?*)\HL"@\($B4'\@\$$A6#[!B)7?B+70R)=?R+=0CWPP``(`!T%H@>N@$```"+7?B)T(MU_(GL7<.- +XM=@")7"0$B30DZ'`*_/^#^/]TV87`N@$```!^UXM=^(G"BW7\B>R)T%W#D(VT +XM)@````!5,<")Y5=64X/L#(M]"(7_#X21````BS7D=`D(A?8/A,$```"+'>1T +XM"0B#QP2)W@,UX'0)".L#@\<$BT?\A=\NAX'0)"(/H@*/@=`D(@\`&B40D!*'D +XM=`D(B00DZ$.3__^)Q@,UX'0)"*/D=`D(C5Z`ZYC&`P"AY'0)"(/$#%M>7UW# +XMH>!T"0B#Z("CX'0)"(/`!HE$)`2AY'0)"(D$).@`D___B<8#->!T"0BCY'0) +XM"(U>@.EM____QP7@=`D(@````,<$)(8```#HA9+__Z/D=`D(Z1____^-="8` +XMC;PG`````%4QP(GE5U93@^P,BWT(A?]T>:'L=`D(A(L=['0)"(G>`S7H +XM=`D(ZPB0C70F`(/'!(L'AAT +XM"0B#Z("CZ'0)"(/`!HE$)`2A['0)"(D$).A/DO__B<8#->AT"0BC['0)"(U> +XM@.NMQ@,`H>QT"0B#Q`Q;7E]=P\<%Z'0)"(````#'!"2&````Z,>1__^C['0) +XM".EH____C;8`````C;PG`````%6X!````(GE5U93@^P,BUT(BPN%R70:,,"- +XMM"8`````@\`!BQ2#A=)U]HT$A00```")!"3H=Y'__XG'BP.)_H7`=!^)!"3H +XM]?[__XD$).@MCOW_B0:+0P2#Q@2#PP2%P'7AQP8`````B?B#Q`Q;7E]=PXVT +XM)@````"-O"<`````58GE@^PXBT40B77XBW4(B5WTB7W\B40D"(M%#(DT)(E$ +XM)`3HA`/\_X7`B<-^+(L&B40D!(U%[HE%X(D$).BZ!_S_.<-U#XMU##G;B=F+ +XM?>#\\Z9T!;O_____B=B+=?B+7?2+??R)[%W#C;0F`````%6)Y8/L&(E=^(M% +XM$(EU_(M=#(MU"(E$)`B)7"0$B30DZ&O___^#^/]T%X7`N@$```!^`HG"BUWX +XMB="+=?R)[%W#QT0D"`````#'1"0$`````,<$)`````#HWP+\_P^V`[H!```` +XM#0``(`")!HM=^(G0BW7\B>Q=PY"-M"8`````53'`B>564X/L((M="(7;=%'' +XM!?1T"0@`````@#L`=#&-=?2)7"0$QT0D"`8```")-"3H2?___\<$)/!T"0@! +XMPXM%](E$)`3HA/?__X`[`'72QP0D\'0)".C3]___H?!T"0B#Q"!;7EW#C;0F +XM`````%6X!````(GE5U93@^P,BUT(BSN%_W0:,,"-M"8`````@\`!BS2#A?9U +XM]HT$A00```")!"3HEX___XG'BP.)_H7`=!^)!"3H1?___XD$).CM^O__B0:+ +XM0P2#Q@2#PP2%P'7AQP8`````B?B#Q`Q;7E]=PXVT)@````"-O"<`````58GE +XM5U93@^P,BT4(BQB%VP^$FP```(L5X%T)"(G'B57PZS*+5?"!_O\```"+E)HT +XM!```B57L=TB+5?"+A+(T!```.47L=4:#10P$BU\$@\<$A=MT7(M%#(LP.?-T +XMZ8'[_P```':]B1PDZ+X"_/^!_O\```")1>QVOXVT)@````")-"3HI`+\_SE% +XM['2ZA=N0=#2%]KH!````="$Y1>R)]G0SBU7L@\0,6UY?72G"B=##BT4,,=*+ +XM`(7`=0J#Q`R)T%M>7UW#@\0,NO____];B=!>7UW#B=HI\NOAD)"0D)!5B>56 +XM4X/$@,<$)$`Q"0CH["[^_\<$)"0Q"0B)QNC>+O[_QP0D9#$)"(G#Z-`N_O^% +XMVP^$J`$``(7V#X21`0``A<`/A'\!``")7"0_/^)!"3H2?O__\=$)`3$F`H(QP0DO$@)"(G#Z"/G_?^%P'0. +XMBP"%P'0(BP"%P'0"B<.)="00BT9$QT0D"`````")7"0$QP0D`0```(E$)`SH +XMGMO__\=$)`0P*@@(B<:)!"3HW'_\_XL&AR\````@ST`=0D(`<=$)`2PD`@(QP0DQ*P+"`^4P(F%3/___X,%Q*P+"`'H +XM9W_\_\=$)`3$F`H(QP0DO$`)".A3YOW_A<`/A((```"+`(7`B850____=':+ +XM?0B%_P^$:0$``,>%4/___P`````QVXU%[(D$).BY^OO_BU7LB=`K!01U"0@Y +XMPW\NC85@____B14$=0D(B40D!,<$))0="0CH;O[[_X7`=#"+=0B%]@^$>@$` +XM`(UV`,<$),2L"PCH-'[\_X'$O````%M>7UW#BT4(A0C70F`(G>BQZ%VP^$Y0```(U%P(E$)`2-1BK'1"0("``` +XM`(D$).C&^OO_@_@`?-4/A<````"+7>@[7D1\AXGZA-*-=@`/A6`#``")7D3' +XM1D@"````Z6O___^+A5#___^[6`(``(D$).AH%?W_BY50____B10DZ,I[_?^H +XM`0^$>O[__XN54/___XL"B00DZ+*'_?^%P`^$8O[__XN54/___XL"@\($B950 +XM____B00DZ.'B_?]KV#SI0?[__\=$)`S('0D(QT0D"`$```"A@)@*",=$)`0: +XM````B00DZ/3;_/_'1"0$E!T)"(D$).B$U?__Z4_^___'1"0$3````,<$)`$` +XM``#H^X?__XU5P(E4)`3'1"0("````(G#C4`JB00DZ*O[^_^-1=B)1"0$C4,S +XMQT0D"!````")!"3HD?O[_XM%Z(E#1(!]R`!U&<=#2`(```"+1@2),XE#!(D8 +XMB5X$Z6#^__^-5_S_BT4(A<`/A:?]__^+A5#___^%P`^$F?W__XN]4/___X/'"(M' +XM^(7`#X2%_?__BQ"%T@^$>_W__XM?_(7;#X1P_?__BS.%]@^$9OW__\=$)`3D +XM+@D(B00DZ"+Y^__'A4C___\`````A<`/A'L!``"+-2!U"0B+!H7`=13IL0`` +XM`(UV`(LVBQZ%VP^$H@```/9&2`AU[HM?^,<$).0N"0B)7"0$Z-?X^_^%P'0? +XMC48(B00DZ.SV__^)7"0$B00DZ``O_?^%P`^$[0```(U&*HM?_(D$).C*]O__ +XMB5PD!(D$).C>+OW_A<`/A*L```"+1DBH$'01H01U"0B)1D2+1DB#X.^)1DBH +XM`G1>@'X(`'18BX5,____A<`/A/````"#3D@(QD8(`(LVBQZ%VP^%7O___XN- +XM2/___X/'"(7)#X3A_O__Z6S\__^+70B%VP^%8?S__\=$)`SP'0D(QT0D"`(` +XM``#IT_W__Z@!=0BH!`^$$/___XN%3/___X7`=&*-1AF)1"0$C48(B00DZ.#^ +XM^_^#3D@(Z>O^__^+1_S'!"3D+@D(B40D!.C4]_O_A<`/A=#^___I-?___XU& +XM&8M?^(D$).C=]?__B5PD!(D$).CQ+?W_A<`/A*G^___I[/[__XGPB?;H._K_ +XM_^N3QT0D!.0N"0B)'"3HA??[_X7`#Y3`#[;`B85(____Z6+^__^)\.@/^O__ +XMZ03___^-1@B)1"0$C47(QT0D"!````")!"3H+/?[_X7`=0^)7D3'1D@)```` +XMZ>W[__^-557,?]64X/L#,=$)`3$F`H(QP0DO"X)".@QX?W_B00DZ*GR +XM___'!"0!````B<;H&_K__XL=('4)"(L#AS/&0P@`BQN+`X7`==[HB/C__X/$#(GX6UY?7<.-M"8`````C;PG```` +XM`%6)Y5=64X/L+(M=#(MU"(U#LX/X(78IQP0D`P```.B=A/__B!= +XM"0AF@WR.-`!Y"`^VA(XT!```B`,/MD(!@\,!@\(!A,!UTL8#`.E2____C48J +XMB44(@\0L6UY?7>FA@/W_@'XS``^$&P$``(U>,XD<).C(^_O_@\`!B00DZ+&# +XM__^)QP^V1C,/MM"#^G\/AB\!``#'1>0N````A,")_G12BQ7<70D(B57H#[[` +XM.T7D#X2R````#[8#/#H/MM`/A(\````Y5>A^&XL-X%T)"&:#?)$T`'D-A=)X +XM!XN4D30$``")T(/#`8@&#[8#@\8!A,!UM\8&`.FG_O__BT9(@^`'@_@"#X0- +XM`0``@_@$#X3*````@^@!#X6__O__H8"8"@C'1"0,HAT)",=$)`@)````QT0D +XM!!H```")!"3H4M;\_^D-____C489Z07___^0C70F`+HZ````QT7D`````(UT +XM)@#I7/___XD<),=$)`0Z````Z$?V^_^%P(G##X4T____Z6S___^A@)@*",=$ +XM)`Q1#@D(QT0D"`P```#'1"0$&@```(D$).CGU?S_B44(@\0L6UY?7>E(?_W_ +XMC48(Z9#^___V!)6]40D(!,=%Y``````/A"0CHGO'__\<$)``Q"0B)1"0$Z'[H_/_'!"2P'@D(Z(+Q +XM___'!"0D,0D(B40D!.ABZ/S_QP0DJ!X)".AF\?__QP0D9#$)"(E$)`3H1NC\ +XM_\<$)+8>"0CH2O'__\<$)$`Q"0B)1"0$Z"KH_/_)PY"0D)"0D)"058GE@^P8 +XMB5WXBUT,B77\BQ7,=0D(BW4(A=)T)*'0=0D(A<`/A(P```")70R+7?B)=0B+ +XM#=1U"0B+=?R)[%W_X<<%S'4)"`$```#'1"0$`0$``,<$)+L>"0CH[OG[_X7` +XMH]!U"0AT3L=$)`3''@D(B00DZ"7T^_^CU'4)",=$)`32'@D(H=!U"0B)!"3H +XM"_3[_Z/LK`L(QT0D!-@>"0BAT'4)"(D$).CQ\_O_H_"L"PCI=/___XM=^+C_ +XM____BW7\B>Q=PY"0D)"0D)"0D)"0D%6)Y5=6@^PPBT40BU44BW4(BWT,B47L +XMB<&)5>B+1>C'1=``````QT74`````(GZB77DA<")=?")?>!U%#GY=F")\/?Q +XMB570QT74`````.L0BTW@.4WH=AB)==")?=2)]HM%T(M5U(/$,%Y?7<.-=@`/ +XMO47H@_`?B478=4:+1>@Y1>`/A\D```"+3>PY3>0/@[T```"+3?")5=2)3=#K +XMP9"+1>R%P'4,N`$````QTO=U[(G!BT7@BU7H]_&+1>3W\>N"N"````"+5>PK +XM1=B+=>R+?>2)P8E%W-/JBT7H#[9-V-/@"<*+1>33Y@^V3=R)5?2+5>#3Z`^V +XM3=C3X@G0BU7@T^"+1>0K1>P;5>B)1?#I+____SGX=K``````BW4,QT7D`````(E%](G!BT4(A=*)UXE%['4C.?$/AI@```")\O?Q +XMB<$QP(E-X(E%Y(M%X(M5Y(/$(%Y?7<,Y\@^'M0````^]PH/P'XE%Z`^$E@`` +XM`+@@````BU7T*T7HB<'3Z@^V3>B)1?")^(M]]-/@"<*+1>S3YP^V3?")5=R) +XM\M/H#[9-Z-/B#[9-\`G0T^Z)\O=UW(G1B778B478]^QS%(UT)@`QR3'`Z2?___^-M"8` +XM````N0$````QP.D4____BT7L#[9-Z-/@.<9VAXM-V#'`@^D!Z?K^__^0D)"0 +XMD)"0D)"058GE5U:#[%"+30R+512+11#'1;@`````A@]<`]]_I!O____?:@]$`]]G'1<#_____Z>C^__^X(````(M5W"M%R(G! +XMT^H/MDW(B474B?B)UXGRT^`)QXM%W-/@#[9-U(E%K(M%V-/H#[9-R-/B"="+ +XM5=C3X@^V3=2)5>2)\M/J]_>)UO=EK#G60IP1G6BG^__\[1>1VI2M%K!GZZYZ0D)"0 +XMD)"0D)"0D)"0D%6)Y5=6@^PPBU4,BT4(BW40BWT4B570`````#XBD````A?\/B+H```")UXG&BU78B<&+ +XM1=R%_XE5\(E%['44.<9V08G0BU7L]_:)P3'`ZQ.-=@`[?>QV3S'),<"-M"8` +XM````B4W0BTWDB474BT70BU74A7UW#A?9U"[@!```` +XM,=+W]HG!BT7LB?KW\8G&BT7P]_&)P8GPZ[P/O<>#\!^)1>AU1#E]['<%.77P +XM3_____#XE+____D(UT)@")\(GZ +XM]]B#T@#WVO=5Y.DS____N"````")\BM%Z(G!T^H/MDWHB47TB?B)UXM5[-/@ +XM"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>)553@^P$H1A/"0B#^/]T$C';_]"+@Q1/"0B#ZP2#^/]U\(/$!%M= +XMPY"0D(/L#.B\\_O_@\0,PP```````````````````````````````"1&'0@87)G=6UE;G0@"BUD"0EL;V%D(&1I2!S=&%C:R!F2D@"BUI"0EI;G1E6YT87@@;V8@=&AE(&9O;&QO=VEN9R!@9FEL92<@"BUQ"0EA8V-E<'0@ +XM4TE'455)5"!F;W(@&5C=71I +XM;VX@"BU8"0EL:6ME("UX(&)U="!I;F-L=61I;F<@8V]M;6%N9',@&ET(`H*4V5E('1H92!T8W-H*#$I(&UA;G5A +XM;"!P86=E(&9O2!I9@!);7!R;W!EF5D`"5S(&YO="!F;W5N9`!);7!R;W!E6YT87@`3F\@:&]M92!D:7)E8W1O0!$:7)E8W1O0!5`!%>'!A;G-I;VX@8G5F9F5R(&]V97)F;&]W`%9A`!"860@(2!F;W)M`$YO('!R979I;W5S('-U8G-T:71U=&4`0F%D('-U +XM8G-T:71U=&4`3F\@<')E=FEO=7,@;&5F="!H86YD('-I9&4`4FEG:'0@:&%N +XM9"!S:61E('1O;R!L;VYG`$)A9"`A(&UO9&EF:65R.B`E8P!-;V1I9FEE2`I)W,`5&]O(&UA;GD@*"=S`$)A9&QY('!L86-E9"`H`$UI0``07)G=6UE +XM;G0@9F]R("UC(&5N9',@:6X@8F%C:W-L87-H````07)G=6UE;G1S('-H;W5L +XM9"!B92!J;V)S(&]R('!R;V-E6YC(&9A=6QT.B!065T*0```%5S86=E.B!H:7-T +XM;W)Y(%LM)7-=(%LC(&YU;6)E2!A2!F:6QE(&YO="!E>&5C=71A8FQE``!5;FMN;W=N(&]P=&EO;CH@ +XM8"TE%@@72!;(&%R9W5M +XM96YT("XN+B!=```*36ES"4P.'@*`"5D(&AI=',L("5D(&UI!0CO6@4([UH%".]:!0CO6@4([UH%".]:!0CO +XM6@4([EX%"`=?!0@@7P4(.5\%"$-?!0A<7P4([UH%".]:!0CO6@4(:U\%"'I? +XM!0BS7`4([UH%"*%>!0BU7@4([UH%".]:!0C.7@4([UH%"-]>!0CO6@4([UH% +XM".]:!0CO6@4(ZUT%"%);!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4( +XMCEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B. +XM6@4(CEH%"(Y:!0B.6@4(CEH%"(Y:!0B.6@4(2UL%"(Y:!0@I6P4(CEH%"(Y: +XM!0@B6P4(UUH%"`<`#0`````````````````````````````````@````)P`` +XM`"(````)````.P```"8````\````/@```"@````I````?````%X````E```` +XM`````'1CF4`=FUE;6]R>75S90!D97-CF4`)6IO8B`F`"5J;V(``"5S +XM.B`E6!0@ME@4(&98%"`^5!0@/ +XME@4(!98%"`^5!0@/E04(#Y4%"`^5!0@/E04(#Y4%"`^5!0C[E04(#Y4%"`^5 +XM!0@/E04(\94%"`^5!0CGE04(#Y4%"-V5!0ACF@4(0YH%"(B9!0B(F04((YH% +XM"(B9!0B(F04(B)D%"(B9!0B(F04(\9D%"-&9!0B(F04(B)D%"(B9!0A#F@4( +XM;)L%"&R;!0C%G`4(H)P%"&>;!0ALFP4(YYL%"&R;!0BG +XMFP4(@)T%"&R;!0ALFP4(2)T%"&R;!0ALFP4(YYL%"'1C&-E<'1I;VX`2TE,3`!+:6QL960`55-2 +XM,0!5&ET960`24\`07-Y;F-H&-E961E9`!81E-:`$9I;&5S:7IE(&QI;6ET(&5X +XM8V5E9&5D`%9404Q230!6:7)T=6%L('1I;64@86QA0!B&5C`&5X:70`9F<`9FEL +XM971E0!O;FEN='(`<&]P9`!P&5S +XM=6P`+20J`"@]?@!>*BTE)'M].B,`.EXD*BTE`````&YC:&%R^04(N@(&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``& +XM"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8( +XMI``&"*0`!@B:`@8(I``&"*0`!@B:`@8(I``&"*0`!@BD``8(I``&"*0`!@A\ +XM`@8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@BD``8(I``&"*0` +XM!@BD``8(I``&"*0`!@BD``8(I``&"*0`!@B:`@8(]1(&")42!@B5$@8(UPH& +XM"-<*!@C7"@8(UPH&")42!@C7"@8(UPH&"&T2!@C7"@8(UPH&"-<*!@C7"@8( +XMUPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@B5$@8(UPH&"-<*!@C7 +XM"@8(UPH&"!(2!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<* +XM!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH& +XM"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@C7"@8(UPH&"-<*!@B5$@8( +XMF0T&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7 +XM#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<- +XM!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT& +XM"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08( +XM%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7 +XM#08(%PT&"!<-!@@7#08(%PT&"!<-!@@7#08(T0T&"!<-!@@7#08(T0T&"!<- +XM!@@7#08(%PT&"-$-!@@7#08(%PT&"!<-!@BP$`8(IQ`&"-$-!@@>#P8(T0T& +XM"-$-!@@7#08(%PT&"*<0!@AW:61E7W)E860`.R8*`#P^*"D`)74E=0`E9#H` +XM"`A)W@@(3-X("$_>"`A%R0@(`````&YO="!A +XM(&1I0!U;G)E861A8FQE``HE4R`E0!"860@='=?8V]M;6%N9`H`:71E;7,`)7,Z($EN=&5R;F%L(&UA=&-H +XM(&5R!0<(G@4'"#P#!PB,`P<(QP,'"``````````` +XM````````````````@+X&"/#%!@C`NP8(H,4&"("^!@B`O@8((+X&"*#%!@A@ +XMNP8(D+L&","[!@C`NP8(`+L&"#"[!@C0N@8(H+H&"'"Z!@B`O@8(@+X&""#% +XM!@@`````````````````````P,`&",#`!@C`P`8(0,4&",#`!@C`P`8(P,`& +XM"$#%!@C`P`8(P,`&",#`!@C`P`8(P,`&",#`!@C`P`8(P,`&",#`!@C`P`8( +XMP,`&"(#$!@@`````````````````````T,$&"/#"!@BPO08(4,4&"-#!!@C0 +XMP08(L+T&"%#%!@BPO08(L+T&"."Y!@A`O08(X+P&"+#)!@B`O`8(\+L&"&"Y +XM!@C0P08(T,$&")#$!@@*)7,@:6YT97)N86P@97)R;W(Z($D@9&]N)W0@:VYO +XM=R!W:&%T($DG;2!L;V]K:6YG(&9OF4M=V]R9`!C:&%N9V4M +XM8V%S90!C:&%N9V4M=&EL;"UE;F0M;V8M;&EN90!6:2!C:&%N9V4@=&\@96YD +XM(&]F(&QI;F4`8VQE87(M&-H86YG +XM92UP;VEN="UA;F0M;6%R:P!%>&-H86YG92!T:&4@8W5R'!A;F0@=F%R:6%B;&5S`&9O2US96%R8V@M8F%C:W=A2US96%R8V@M9F]R=V%R9`!I;G-E"UM971A`'%U;W1E9"UI;G-E2!E=F5R +XM>71H:6YG`')U;BUF9RUE9&ET;W(`4F5S=&%R="!S=&]P<&5D(&5D:71O<@!R +XM=6XM:&5L<`!S96QF+6EN2!D96QA>65D +XM('-U2UF;'5S:"UO=71P=70`5'1Y(&9L=7-H +XM(&]U='!U="!C:&%R86-T97(`='1Y+7-I9VEN='(`5'1Y(&EN=&5R2US +XM:6=T'0M=V]R9`!V:2UA9&0`=FDM +XM861D+6%T+65O;`!V:2UC:&"!C;VUM86YD`'9I+65N9'=O6%N:P!Y86YK+7!O +XM<`!E7V-O<'E?=&]?8VQI<&)O87)D`&5?<&%S=&5?9G)O;5]C;&EP8F]A5]P`!$ +XM96QE=&4@8VAA2!L:6YE````1&ES<&QA>2!L;V%D(&%V97)A9V4@86YD(&-U +XM&5C=71E(&-O;6UA;F0@86YD(&ME97`@ +XM8W5R'0@:&ES=&]R>2!L:6YE````17AP86YD('!A=&AN86UE7!E9"!T;R!T:&4@;&EN92!V97)B871I;0```$QO;VL@9F]R +XM(&AE;'`@;VX@8W5R&EC86P@8W5R +XM7!E +XM9`!6:2!R97!L86-E(&-H87)A8W1E6%N:V5D('1E>'0@=VET:"!Y86YK(&9R;VT@96%R;&EE +XM2D@4&%S=&4@8VQI<&)O87)D +XM(&)U9F9E'0@=V]R9"!T;R`G7%PG```H5TE.,S(@;VYL +XM>2D@0V]N=F5R="!E86-H("`!K;0!A;0!X;@!C;P!L:0!A9&0@ +XM;F5W(&)L86YK(&QI;F4`8FP`875D:6)L92!B96QL`&-L96%R('1O(&)O='1O +XM;0!C;&5A7-I8V%L('1A8G,`3G5M8F5R(&]F(&QI;F5S`$YU;6)E0!Y97,`8F%U9`!C;VQS``EF;VQL;W=I;F<@8VAA +XM3H@3G5L;"!E>'1E;F1E9"UK97D@;F]T(&%L;&]W960N +XM"@!!9&18:V5Y.B!.=6QL(&5X=&5N9&5D+6ME>2!N;W0@86QL;W=E9"X*```` +XM`$%D9%AK97DZ('-E<75E;F-E+6QE860M:6X@8V]M;6%N9"!N;W0@86QL;W=E +XM9`H``$]C=&%L(&-O;G-T86YT(&1O97,@;F]T(&9I="!I;B!A(&-H87(N"@`E +XM+3$U4RT^(`!N;R!I;G!U=`!3;VUE=&AI;F<@;75S="!F;VQL;WUU]`%5N8F]U;F0@97AT96YD960@:V5Y("(E4R(*``"5'0@(E1T( +XM")4="`B5'0@(E1T(")4="`B5'0@(E1T("-@<"`C8'`@(V!P("-@<"`C8'`@( +XMV!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8 +XM'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("-@< +XM"`C8'`@(V!P("-@<"`C8'`@(V!P("-@<"`C8'`@(V!P("(4="`C8'`@(V!P( +XM"-@<"`C8'`@(=1T("&4="`C8'`@(V!P("%4="`A%'0@(V!P("-@<"`C8'`@( +XMV!P("-@<"`C8'`@(V!P("#4="`C8'`@(V!P("-@<"`@G'0@(V!P("!L="`C8 +XM'`@(#QT(".D6"0A5;FMN;W=N('-W:71C:``E&%N>0!I>&]F9@!I;6%X8F5L`&ED +XM96QE=&4`;W!O'0`"5L>"!T;R`P>"5L>"`H)6QD*2X*`$]U="!O9B!M96UO +XM7,@=&\@96UA8W,@ +XM8FEN9&EN9W,*````("`@("UD("`@8FEN9"!A;&P@:V5Y4UA<%LE9%T@/3T@)60*`$-C06QT36%P6R5D +XM72`]/2`E9`H`3G5L;"!S=')I;F<@2!B:6YD:6YG,@@(7C(("%XR"`A>,@@(.#0("(HT +XM"`A>,@@(7C(("%XR"`A>,@@(7C(("$4T"`A5-`@(7C(("%XR"`AE-`@(Y#<( +XM"%@W"`A8-P@(O3<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("(8W"`A8-P@( +XM6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(73<("%@W"`A8 +XM-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`CD-P@(6#<("%@W +XM"`B]-P@(6#<("%@W"`A8-P@(6#<("%@W"`A8-P@(AC<("%@W"`A8-P@(6#<( +XM"%@W"`A8-P@(6#<("%@W"`A8-P@(6#<("%@W"`A=-P@(2!A;&EA($("(M\"`B+?`@(BWP( +XM"(M\"`B+?`@(BWP("(M\"`B+?`@(BWP("(M\"`B+?`@(BWP("(M\"`B+?`@( +XMBWP(""R!"`CJ?P@(BWP("-M_"`AX@0@(S8(("(M\"`B+?`@(BWP("(M\"`B+ +XM?`@(BWP("(M\"`C`@@@(HW\("(M\"`B+?`@(ZG\("(M\"`AX?P@(:7\(".I_ +XM"`A:?P@(BWP("$!_"`B+?`@("'\("(M\"`B+?`@(BWP("(M\"`B+?`@(BWP( +XM"(M\"`B+?`@(^7X("'B!"`C9?@@(BWP("(M\"`B+?`@(98,("(M\"`BK?@@( +XMBWP("%5^"`C??0@(CGT("(M\"`CJ?P@(BWP("(M\"`A_?0@(ZG\("'!]"`B+ +XM?`@(4'T("(M\"`@%?0@(BWP("/5\"`B+?`@(Y'P("'B!"`@L9FEL96,`+&-O +XM;&]R`"QR:``L'`@)``` +XM``$;`SMP+@``!````#"+__^,+@``H(S__ZPN``#PC?__S"X``!"0___L+@`` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````````````````````!%R0@(`````"1/"0@````` +XM`````````````````````$`H(RD@0V]P>7)I9VAT("AC*2`Q.3DQ(%1H92!2 +XM96=E;G1S(&]F('1H92!5;FEV97)S:71Y(&]F($-A;&EF;W)N:6$N"B!!;&P@ +XM"0@D-@D(`@````````````````````````#X;PD( +XM``````````````````````````````````````!``$``0`!``$``0`!``$`` +XM0!1`&$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!` +XM`$`4``"``8`0@("``(`0H`&`$*`0@""``(``@`"``(``@``1`!$`$0`1`!$` +XM$0`1`!$`$0`1`(`0H!"``(`0@""``(``%@`6`!8`%@`6`!8`!@`&``8`!@`& +XM``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`&((!`@`"``(``@#*``!H` +XM&@`:`!H`&@`:``H`"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`* +XM``H`"B"`$*``@`"``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$`` +XM0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``(``@`"``(``@`"` +XM`(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(`` +XM@`"``(``@``&``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`&``8`!@`& +XM``8`!@`&``8`@``&``8`!@`&``8`!@`&``H`"@`*``H`"@`*``H`"@`*``H` +XM"@`*``H`"@`*``H`"@`*``H`"@`*``H`"@`*`(``"@`*``H`"@`*``H`"@`* +XM`````"_*"`@!````[\D("`$````WR@@(``0``/?)"`@"````0,H("``$``#W +XMR0@(`P```$G*"`@`!```]\D("`0```!3R@@(``0``/?)"`@%````80("'#D"`@%````<.0("`4````F````YQP)"$7)"`@`````10("`(````]````Q!X)"'GD"`@%```` +XM>>0("`4````^````)/$("'GD"`@%````>>0("`4````C````?^0("(+D"`@% +XM````@N0("`4````E````G]$("(+D"`@%````@N0("`4````J````.K\("(CD +XM"`@%````B.0("`4`````````CN0("*^^"`@!````K[X("`$`````````D>0( +XM"*^^"`@!````K[X("`$`````````E.0("$7)"`@`````10("$7)"`@`````1!PA@3P<(`$\'"/`J!PAP,`<(8"D'",`O!PCP/`<( +XM("P'"#`L!PA`+`<(4"P'"&`L!PAP+`<(P"H'"*`Z!PAP,0<(<#\'""!0!PB@ +XM,0<(P"L'"&`F!PC@30<(H$T'"+`I!PBP40<(,%$'"&!W!PAP=0<(('8'"+`V +XM!PC0,`<(D#`'"!!H!PB03@<(,%$'"#`Q!PA0*P<($"L'".!.!PB0*P<(H$\' +XM",!/!PCP+P<(8$<'"!!*!P@`+`<(@"<'",!R!PC0)P<(\"<'"%`H!P@04@<( +XM@'0'"`!T!P@0.@<(<"@'"*`L!P@@90<(L#D'"(`X!PB@8P<(P"P'"'!`XX&@$/`1````7````"T````E```````` +XM`"(````G````8`````````````````````````````````````````#@3`D( +XM$0```````````````````-1,"0@5````````````````````]$P)"!,````` +XM```````````````(30D(%````````````````````)`O"0@2```````````` +XM````````($T)"``````````````````````;````3P```$8`````````&P`` +XM`$\```!(`````````!L```!/````1``````````;````3P```$,````````` +XM&P```$\```!"`````````!L```!/````00`````````;````6P```$8````` +XM````&P```%L```!(`````````!L```!;````1``````````;````6P```$,` +XM````````&P```%L```!"`````````!L```!;````00`````````````````` +XM`'P-"0@``0``P````(,-"0@#````0````(H-"0@``````````)$-"0C*!0`` +XM$`B`@)@-"0@``````````'P-"0A``0``@````(,-"0@#````0````(H-"0@` +XM`````````)$-"0B`````'`V`@)@-"0BP\;\!`````'P-"0@```````8``(,- +XM"0@``````````(H-"0@``````````)$-"0@`````@`0``)@-"0@````````` +XM`````````````````&P```!O````9P```&\```!U````=``````````````` +XM80```'4```!T````;P```&P```!O````9P```&\```!U````=``````````V +XM````,````````````````````&$```!U````=````&\```!M````80```'0` +XM``!I````8P````````!H````80```&X```!G````=0```'``````````80`` +XM`"X```!O````=0```'0`````````=````'0```!Y`````````"\```!P```` +XM=````',````O`````````&$```!N````>0````````!S````=````&$```!T +XM````=0```',`````````,``````````Q`````````"T````Q```````````` +XM````````````````````````,````'@````W````9@```&8```!F````9@`` +XM`&8```!F````9@`````````Z`````````%\`````````=````&,```!S```` +XM:`````````!H````;P```&T```!E`````````'4```!S````90```'(````` +XM````9P```'(```!O````=0```'``````````=````&4```!R````;0`````` +XM````````````````````````````````````````=@```&4```!R````0```````````````````````````````````&,```!A````=````&$` +XM``!L````;P```&<`````````3@```$P```!3````4````$$```!4````2``` +XM``````!N````;P```&L```!A````;@```&H```!I`````````'X````O```` +XM+@```&,```!S````:````&0```!I````<@```',````````````````````` +XM``````````````!D````:0```'(```!S````9@```&D```!L````90`````` +XM````````````````````````````````````````0```'P```!N````?````&4```!\````80```"D````_ +XM``!`(```````````````=0```&X```!A````;````&D```!A````````'0```!R````80```&,` +XM``!T``````````````````````````````````````````````!D````=0`` +XM`&X```!I````<0```'4```!E`````````',```!Y````;0```&P```!I```` +XM;@```&L```!S`````````&D```!G````;@```&\```!R````90````````!C +XM````:````&$```!S````90````````!E````>````'````!A````;@```&0` +XM````````````````````````90```&,```!H````;P```%\```!S````=``` +XM`'D```!L````90````````!B````P````````![````(````"X````N````+@```"````!]```` +XM`````'T`````````4````$$```!4````2```````````````9````&4```!F +XM````80```'4```!L````=``````````M````;@`````````M`````````&X` +XM``!O````9P```&P```!O````8@``````````````````````````````;@`` +XM`&\```!N````;P```&T```!A````=````&,```!H```````````````````` +XM`````````````````````&`````@````+@```"X````N````(````&`````` +XM````80```&T```!P````;0````````!T````:0```&T```!E`````````&X` +XM``!O````=````&D```!F````>0`````````````````````````````````` +XM````````````<````'(```!I````;@```'0```!E````>````&D```!T```` +XM=@```&$```!L````=0```&4`````````*````"``````````(````"D````` +XM````(``````````@````?````'P````@`````````"`````F````)@```"`` +XM````````(````'P````@`````````#L````@`````````#L`````````(@`` +XM`"(`````````6P```%T`````````(````#P````\````(``````````@```` +XM/````"``````````(````#X````^`````````"`````^`````````#X````` +XM````(````"X````N````+@`````````E````)0`````````E````*P`````` +XM```E````+0`````````E````(P`````````````````````````````````` +XM`&,```!O````;@```'0```!I````;@```'4```!E```````````````````` +XM``````````````````````````!C````;P```&X```!T````:0```&X```!U +XM````90```%\```!A````<@```&<```!S`````````%\```!P````80```'4` +XM``!S````90````````!@````<````'<```!D````8`````````!F````:0`` +XM`&P```!E````8P`````````````````````````````````````````````` +XM:````&D```!S````=````&,```!H````80```'(```!S```````````````` +XM`````````````````````````'````!R````;P```&T```!P````=````&,` +XM``!H````80```'(```!S``````````````````````````````!H````:0`` +XM`',```!T````;````&D```!T`````````%4```!3````10```%(````````` +XM````````````````3````$\```!'````3@```$$```!-````10````````!' +XM````4@```$\```!5````4````````````````````'<```!O````<@```&0` +XM``!C````:````&$```!R``````````` +XM``!L````:0```',```!T````;````&D```!N````:P```',`````````1``` +XM`$D```!.````1P```"$`````````````0``````````````````````````` +XM``````````!C````;P```'(```!R````90```&,```!T`````````&,```!M +XM````9`````````!A````;````&P`````````90```'(```!A````````1`````@````(```````` +XM``H````H;FEL*0```!0``````````7I2``%\"`$;#`0$B`$``!P````<```` +XMG%S__W`!````00X(A0)"#05%A@2'`P``'````#P```#L7?__1@$```!!#@B% +XM`D(-!46&!(<#```<````7````!Q?__\2`@```$$."(4"0@T%188$AP,``!P` +XM``!\````'&'__X!`@BG@0(,IX$"$*>!`A2G@0(8IX$"'*>!`B" +XMG@0(DIX$"**>!`BRG@0(PIX$"-*>!`CBG@0(\IX$"`*?!`@2GP0((I\$"#*? +XM!`A"GP0(4I\$"&*?!`ARGP0(@I\$")*?!`BBGP0(LI\$",*?!`C2GP0(XI\$ +XM"/*?!`@"H`0($J`$""*@!`@RH`0(0J`$"%*@!`ABH`0(6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I +XM;FD`+G)O9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`0```0````+````!`````@```!E```` +XM`0````8````(FP0("!L``!$```````````````0`````````8`````$````& +XM````')L$"!P;````"0`````````````$````!````&L````!````!@```""D +XM!`@@)```W`P$````````````$`````````!Q`````0````8```#\L`@(_#`$ +XM``P```````````````0`````````=P````$````"````(+$(""`Q!``.;@`` +XM```````````@`````````'\````!`````@```#`?"0@PGP0`+``````````` +XM````!`````````"-`````0````,`````(`D(`*`$`*0M`````````````"`` +XM````````DP````$````"````I$T)"*3-!`"<```````````````$```````` +XM`)T````&`````P```$!."0A`S@0`V`````4`````````!`````@```"F```` +XM`0````,````83PD(&,\$``@```````````````0`````````K0````$````# +XM````($\)""#/!``(```````````````$`````````+0````!`````P```"A/ +XM"0@HSP0`!```````````````!`````````"Y`````0````,````L3PD(+,\$ +XM`$@"``````````````0````$````O@````@````#````@%$)"(#1!`!T6P(` +XM```````````@`````````,,````!``````````````"`T00`60D````````` +XM`````0`````````!`````P``````````````V=H$`,P```````````````$` +X&```````` +X` +Xend +END-of-tcsh.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.sh new file mode 100644 index 0000000000..312d4b1292 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-3/strip-all-3.sh @@ -0,0 +1,6 @@ +# $Id: strip-all-3.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-all-3 tc/strip-all-3 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} tcsh" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/in/strip-all-4.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/in/strip-all-4.in.shar new file mode 100644 index 0000000000..4acf57ad90 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/in/strip-all-4.in.shar @@ -0,0 +1,6817 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# vi.uu +# +echo x - vi.uu +sed 's/^X//' >vi.uu << 'END-of-vi.uu' +Xbegin 755 vi +XM?T5,1@$!`0D```````````(``P`!````X*0$"#0````8IP0``````#0`(``' +XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! +XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(@(\$ +XM`("/!``%`````!````$`````D`0``!`)"``0"0B$!```@!$```8`````$``` +XM`@```%"1!`!0$0D(4!$)"-````#0````!@````0````$````+`$``"R!!`@L +XM@00(&````!@````$````!````%#E=&1LCP0`;`\)"&P/"0@4````%`````0` +XM```$````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``)-0P`@P```*@````Q```````````````W`````````&<```!4```` +XMH@````````"(`````````'<```"9````3@```&X````_``````````````"0 +XM````@@``````````````I0```*<```"/`````````(````!6````G0```)$` +XM``"*`````````)L```!2``````````4`````````F````&$````T````>@`` +XM``````"+````G````)X````-`````````'\``````````````'D````````` +XM)P```$,````8````:@````````!T````H0````````"$`````````$P````X +XM````H``````````?````E0```#``````````8P`````````6`````````#T` +XM``!F````E@``````````````EP```!$```!:``````````````!B````@P`` +XM`($```!7````7````)0`````````%P```'4````N````?0````````!H```` +XM`````(P``````````````'````"'````F@```*0```!)````<@```*8````` +XM````4`````````!8````>P```)(`````````HP```````````````````)\` +XM```\````;P```%4```!^`````````(D```!?````60```(4````Z```````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````````0```````````````````!(````` +XM````````````````````!`````(````````````````````.````#``````` +XM```5`````````!0````(````````````````````````````````````*0`` +XM````````````(P````D``````````````"H````E````+P`````````````` +XM"@`````````````````````````L```````````````<```````````````9 +XM`````````"@````D`````````$(``````````P`````````V`````````$H` +XM```Y````,P`````````;`````````$$````````````````````+````-0`` +XM`````````````````!T````0````&@````\````'````70`````````````` +XM`````#X```!$`````````!X````A````:0``````````````(````&0````` +XM````````````````````$P````````!1````````````````````10```$\` +XM```R````!@```#L``````````````&P```!(`````````$<````````````` +XM`',```!`````````````````````6P````````!@````)@```(T```!+```` +XM`````%X```!Q`````````'P```!-````C@```'@```!M`````````"(```"& +XM`````````&L```!&`````````%,````M````DP```'8````K````90`````` +XM``````````````````!\!````````,8````2````VP$````````R`@``$@`` +XM`*P"````````-````!(```!3!````````#,````2````N@(```````!#```` +XM$@```!($````````5@$``!(````]!``````````````2````K@,````````R +XM````$@```#8$````````H0```!(```!0`0```````'(#```2````+P$````` +XM``""`0``$@```+\"`````````````!(```"C`0```````&L!```2````R`$` +XM``````#]"```$@```!$```!0$0D(`````!$`\?^T`@`````````````2```` +XM.0(`````````````$@```!H`````````U`,``!(```"1!``````````````2 +XM````-P0```````"A````$@```/\"`````````````!(```!/`P```````%H` +XM```2````50(```````!7````$@```$(!````````.0```!(````P!``````` +XM```````2````!@(```````!J````$@```"``````````30```!(````G```` +XM`````/8#```2````>P0```````":````$@```"0$`````````````!(````O +XM`````````!D````2````XP$```````#!````$@```/,!`````````````!(` +XM``">`P```````%T````2````2@$`````````````$@```&X!````````3P`` +XM`!(```",`P````````4````2````S`(`````````````$@```.`#```````` +XM3@4``!(````5`P```````-T#```2````:@(```````#8````$@```#<```"@ +XMFP0(`````!(`"@`@`@```````.H````2````=P(`````````````$@```%X# +XM`````````````!(```#M`@`````````````2````S@$```````"2`0``$@`` +XM`)`0```````#,````2````3``` +XM``````"2````$@```'$#``"@%`D(!````!$`%P!5`````````"0````2```` +XM*@(````````5`@``$@```'X#````````90(``!(```"/`@`````````````2 +XM````,`,````````T````$@```-,"````$`D(!````!$`$`!:`````````-T` +XM```2````9`````````!"````$@```&L`````````;@```!(```!U```````` +XM`-P#```2````0P0`````````````$@```*<"`````````````!(```"X`P`` +XM`````%(7```2````&0(``*04"0@$````$0`7`,`#````````*P```!(````^ +XM`P```````,T````2````?`(``*@4"0A4#```$0`7`(4#`````````````!(` +XM``#/`P```````,P````2````90(```````"A````$@```'L`````````)``` +XM`!(```"0`0```````#````!(```";````'(H("``````2 +XM``T`,0$```````"8````$@```-<#````````'0```!(```"7!````````.T` +XM```2````.`$```0A"0@$````$0`7`*H!`````````````!(````\!``````` +XM`+$````2````&P0````````D````$@```#0"`````````````!(````=`P`` +XM""$)"`0````1`!<`8@$````````E````$@```'\!`````````````!(```"A +XM`````````#D````2````7P0`````````````$@```%@$````````8@```!(` +XM``"6`P```````,L````2````@00`````````````$@```*L````,(0D(!``` +XM`!$`%P!L!````````/H````2````8`0```````!#````$@```*$$```````` +XM`````!(````+`@```````,,````2````KP0``(04"0@`````$`#Q_Z<$```` +XM````/0```!(````2`@```````#,````2````U`$`````````````$@```+(` +XM```T$@D(`````!$`\?_M`P```````($````2````P@0``(`A"0@`````$`#Q +XM_P@$````````8@,``!(```"K`0`````````````2````R`````````!T```` +XM$@```$`"````````80```!(```"G`P````````,!```2````Z0$``!`A"0@$ +XM````$0`7`&\$````````DP```!(```#%`@``%"$)"`0````1`!<`^`$````` +XM````````$@```,T`````````H@```!(```"Q`0```````$4````2````5@,` +XM``````#*#```$@````$$````````*P```!(```#6````&"$)"`0````1`!<` +XM7P(`````````````$@```,$!`````````````!(```#=`````````+4````2 +XM````YP`````````%`0``$@```#("````````[````!(```!E!``````````` +XM```2````(P0`````````````$@```'0!S971V8G5F`&5X96-L`%]?7-T96T`9F5O9@!M86QL;V,`:7-A='1Y`&]P=&%R9P!V&5C +XM`&]P96YD:7(`6YA;64`9V5T<'=U:60`9V5T8W=D`&9G971C +XM`&=E=&AO&ET`'-E=&QO8V%L90!R96=E&ET`'-T@<` +XM``(`QP0```````"@%`D(!3P``*04"0@%2@``J!0)"`5-``#\(`D(!6(````A +XM"0@%9P``!"$)"`5Q```((0D(!78```PA"0@%?@``$"$)"`6/```4(0D(!9$` +XM`!@A"0@%EP``'"$)"`6C``!`$@D(!P$``$02"0@'`@``2!()"`<#``!,$@D( +XM!P0``%`2"0@'!0``5!()"`<&``!8$@D(!P<``%P2"0@'"```8!()"`<)``!D +XM$@D(!PH``&@2"0@'"P``;!()"`<,``!P$@D(!PT``'02"0@'#@``>!()"`<0 +XM``!\$@D(!Q$``(`2"0@'$@``A!()"`<3``"($@D(!Q0``(P2"0@'%0``D!() +XM"`<6``"4$@D(!Q<``)@2"0@'&```G!()"`<9``"@$@D(!QH``*02"0@'&P`` +XMJ!()"`<<``"L$@D(!QT``+`2"0@''@``M!()"````[!,)"`=Y``#P$PD(!WH``/03"0@'>P``^!,) +XM"`=\``#\$PD(!WT````4"0@'?P``!!0)"`>````(%`D(!X$```P4"0@'@@`` +XM$!0)"`>$```4%`D(!X4``!@4"0@'A@``'!0)"`>(```@%`D(!XH``"04"0@' +XMBP``*!0)"`>,```L%`D(!XT``#`4"0@'C@``-!0)"`>0```X%`D(!Y(``#P4 +XM"0@'DP``0!0)"`>4``!$%`D(!Y4``$@4"0@'E@``3!0)"`>8``!0%`D(!YD` +XM`%04"0@'F@``6!0)"`>;``!<%`D(!YP``&`4"0@'G0``9!0)"`>>``!H%`D( +XM!Y\``&P4"0@'H```A``!T%`D(!Z(``'@4"0@'I0``?!0)"`>F``"` +XM%`D(!Z<``(/L#.@("@``Z$/N`P"#Q`S#````_S4X$@D(_R4\$@D(`````/\E +XM0!()"&@`````Z>#_____)402"0AH"````.G0_____R5($@D(:!````#IP/__ +XM__\E3!()"&@8````Z;#_____)5`2"0AH(````.F@_____R54$@D(:"@```#I +XMD/____\E6!()"&@P````Z8#_____)5P2"0AH.````.EP_____R5@$@D(:$`` +XM``#I8/____\E9!()"&A(````Z5#_____)6@2"0AH4````.E`_____R5L$@D( +XM:%@```#I,/____\E`2"0AH0`$``.E@_?___R7D$@D(:$@!``#I4/W___\EZ!() +XM"&A0`0``Z4#]____)>P2"0AH6`$``.DP_?___R7P$@D(:&`!``#I(/W___\E +XM]!()"&AH`0``Z1#]____)?@2"0AH<`$``.D`_?___R7\$@D(:'@!``#I\/S_ +XM__\E`!,)"&B``0``Z>#\____)003"0AHB`$``.G0_/___R4($PD(:)`!``#I +XMP/S___\E#!,)"&B8`0``Z;#\____)1`3"0AHH`$``.F@_/___R44$PD(:*@! +XM``#ID/S___\E&!,)"&BP`0``Z8#\____)1P3"0AHN`$``.EP_/___R4@$PD( +XM:,`!``#I8/S___\E)!,)"&C(`0``Z5#\____)2@3"0AHT`$``.E`_/___R4L +XM$PD(:-@!``#I,/S___\E,!,)"&C@`0``Z2#\____)303"0AHZ`$``.D0_/__ +XM_R4X$PD(:/`!``#I`/S___\E/!,)"&CX`0``Z?#[____)4`3"0AH``(``.G@ +XM^____R5$$PD(:`@"``#IT/O___\E2!,)"&@0`@``Z<#[____)4P3"0AH&`(` +XM`.FP^____R50$PD(:"`"``#IH/O___\E5!,)"&@H`@``Z9#[____)5@3"0AH +XM,`(``.F`^____R5<$PD(:#@"``#I!,)"&AP`@``Z0#[ +XM____)7P3"0AH>`(``.GP^O___R6`$PD(:(`"``#IX/K___\EA!,)"&B(`@`` +XMZ=#Z____)8@3"0AHD`(``.G`^O___R6,$PD(:)@"``#IL/K___\ED!,)"&B@ +XM`@``Z:#Z____)903"0AHJ`(``.F0^O___R68$PD(:+`"``#I@/K___\EG!,) +XM"&BX`@``Z7#Z____):`3"0AHP`(``.E@^O___R6D$PD(:,@"``#I4/K___\E +XMJ!,)"&C0`@``Z4#Z____):P3"0AHV`(``.DP^O___R6P$PD(:.`"``#I(/K_ +XM__\EM!,)"&CH`@``Z1#Z____);@3"0AH\`(``.D`^O___R6\$PD(:/@"``#I +XM\/G___\EP!,)"&@``P``Z>#Y____)<03"0AH"`,``.G0^?___R7($PD(:!`# +XM``#IP/G___\ES!,)"&@8`P``Z;#Y____)=`3"0AH(`,``.F@^?___R74$PD( +XM:"@#``#ID/G___\EV!,)"&@P`P``Z8#Y____)=P3"0AH.`,``.EP^?___R7@ +XM$PD(:$`#``#I8/G___\EY!,)"&A(`P``Z5#Y____)>@3"0AH4`,``.E`^?__ +XM_R7L$PD(:%@#``#I,/G___\E\!,)"&A@`P``Z2#Y____)?03"0AH:`,``.D0 +XM^?___R7X$PD(:'`#``#I`/G___\E_!,)"&AX`P``Z?#X____)0`4"0AH@`,` +XM`.G@^/___R4$%`D(:(@#``#IT/C___\E"!0)"&B0`P``Z<#X____)0P4"0AH +XMF`,``.FP^/___R40%`D(:*`#``#IH/C___\E%!0)"&BH`P``Z9#X____)1@4 +XM"0AHL`,``.F`^/___R4<%`D(:+@#``#I#V__\```````````````!5B>564X/L$(/D +XM\(M=!(G1C72=#(7;B35H(0D(?C:+10B%P'0OHP`0"0@/MA"$TG0C@\`!ZPH/ +XMMA"#P`&$TG04@/HO=?&C`!`)"`^V$(/``832=>RX4!$)"(7`=#2)#"3HG_[_ +XM_\<$)!R*"`CHD_[__^A*]O__C44(B70D"(E$)`2)'"3H5P\``(D$).AC_?__ +XMZ'[X___KS9"0D)"0D)"058GE@^P(@#T@(0D(`'0,ZQR#P`2C"!`)"/_2H0@0 +XM"0B+$(72=>O&!2`A"0@!R<.058GE@^P(H3`2"0B%P'02N`````"%P'0)QP0D +XM,!()"/_0R<.0D)"0D)"0D)"0D)"0H0PA"0BZ_____U6)Y8M-#(7`=`,/OQ") +XM$:$,(0D(NO____^%P'0$#[]0`HM%$(D0BT4(BT!(*0$QP%W#C70F`%6)Y8M% +XM"(M5#(M-%(M`$(/Z`8M`)'0Y6#[!BA$"$)",=$)`B`````QT0D!`$```#' +XM!"2,B@@(B40D#.AI^___R<.-=@!5B>6#[!B+10B)7?2)=?B)??R+0!"+4"2) +XM5?"+<%R+11"%P'0;BYH0`@``]L,$=46+7?0QP(MU^(M]_(GL7<.0BTWPBX$0 +XM`@``J`)TXX/@_8F!$`(``(ET)`3'!"0UBP@(Z,[Y__^A!"$)"(D$).CA]___ +XMZ[NX!0```+\OBP@(_(G!\Z9UJHM%\(/+`HF8$`(``(M5#(E4)`3KOY"-="8` +XM53'2B>6#[`B+10B+0!"+0"2+B*0!``"%R74@*A +XM'"$)"(D4),=$)`@`````@^@!B40D!.@(^?__H0PA"0B)!"3H6_;__Z$,(0D( +XMQT0D!`````")!"3H)O?__\=$)`@`````QT0D!`````")-"3H*O[__^BY]/__ +XMC8,$`0``B40D",=$)`01````QP0D`````.A+^?__QT0D!!(```#'!"0````` +XMZ-?S__^+@Z0!``"%P'0Y@Z,0`@``YS'2BUWTB="+=?B+??R)[%W#D(U%Q(E$ +XM)`C'1"0$$0```,<$)`````#H^?C__S'2Z]&0QT0D"`$```"+1B"+0`B)-"2) +XM1"0$Z);]__^A#"$)",=$)`0!````B00DZ&7V__^+1<")?"0(B40D!*$,(0D( +XMB00DZ`WX___'1"0$`0```(DT).CY_?__C47PB40D$,=$)`P`````QT0D"``` +XM``#'1"0$`0```(DT).AB(0``N@$```"%P`^%1?___XM=\(7;#X1R_O__BT80 +XM,-*+0"2!B!`"`````0``Z2/___^-=@"-1<2)1"0$QP0D`````.AA\O__C8,$ +XM`0``B40D",=$)`01````QP0D`````.@3^/__Z0'^__^-=@"-O"<`````58GE +XM@^PHB5WTBUT(B77XBW40B7W\BWT,B70D"(GX`T-(B40D!*$,(0D(B00DZ#+W +XM__\QTH/``70/BUWTB="+=?B+??R)[%W#BT-(B70D$(E\)`S'1"0($(L("(E$ +XM)!3'1"0$`P```(D<).@1H@``N@$```#KPXUV`(V\)P````!5B>6#[`BA#"$) +XM",=$)`0!````B00DZ!GU___)@\`!#Y3`#[;`PXUV`(V\)P````!5B>6#["B+ +XM50B)7?2)=?B)??SV@JP$```0BT(0#X64````@\`(.0(/A,,```"+#0PA"0B_ +XM_____[[_____A0(/OS&+0D"+6DB+4C0YT`^#B`````'8QT0D"``` +XM``")1"0$B0PDZ$7V__^#P`%T+:$,(0D(QT0D$`````#'1"0,`````,=$)`@` +XM````QT0D!/____^)!"3HT_C__Z$,(0D(B7PD"(ET)`2)!"3H_O7__Z$,(0D( +XMQT0D!/____^)!"3H.?3__XM=](MU^(M]_(/``0^4P(GL70^VP,.-0O_I`" +XM`T(0BT`XA<`/E<"$P'7___S'`R<.)]HV\)P````!5B>6#[`B+10B+0!"+0"0%!`$``(D$).A8 +XM]/__/98```!T378Q/2P!``"-M@````!T/G9,/5@"``"-M"8`````="X]L`0` +XM`'4^BT4,QP"P!```,<#)PX/X2W05=C>#^&YT#CV&````=1Z-M"8`````BT4, +XMQP!8`@``,<#)PXUV`#W(````=.F+10S'`(`E```QP,G#@_@R=>[KU9"-="8` +XM58GE4X/L%(M-"(M5#(M!$(72BU@D=5F+51"%T@^%S@```(N##`(``(7`#X20 +XM````BX.@`0``QX,,`@```````(7`#X0[`0``QT0D"(#*!`C'1"0$`0```(D$ +XM).AD\O__H00A"0B)!"3HI_'__^M1D(/J`70+Z+KP__^-M@````#V@:P$```1 +XM=$R+DY@!``"X`0```(72=%*+11"%P`^$E````,=$)`B`R@0(QT0D!`$```") +XM%"3H"?+__Y"-="8`H00A"0B)!"3H1_'__X/$%#'`6UW#BT40A?KB(GV58GE4X/L +XM%(M%"(M5#(M`$(72BU@D=#"#Z@%T!>BC[O__BX.0`0``A<`/A'(!``#'1"0( +XM@,H$",=$)`0!````B00DZ`WP__^+@X@!``"%P'1GH:`4"0B%P'5'BQ4$(0D( +XMBT((@^@!A<")0@@/B%\!``"+`L8`#8/``8D"QT0D"(#*!`C'1"0$`0```(N# +XMB`$``(D$).B[[___@\04,6+0"2# +XMB!`"```@QX"D`0```0```%W#B?:A?"$)"%6)Y8M`)(.($`(``$!=PXVV```` +XM`(V_`````*%\(0D(58GEBT`D@8@0`@``@````,>`I`$```\```!=P^L-D)"0 +XMD)"0D)"0D)"0D*%\(0D(58GEBT`D@8@0`@````$``%W#B?:-O"<`````58GE +XM4XG3@^P4B40D"*$0(0D(QT0D!$F+"`B)!"3H4NG__X7;=!FA$"$)"(E<)`C' +XM1"0$28L("(D$).@UZ?__Z-#M__^+`(D$).@FZ___QT0D!'WI"`B)1"0(H1`A +XM"0B)!"3H#>G__\<$)`$```#H\>___XVV`````(V\)P````!5B>6#[#B)7?2- +XM7=R)=?B)UHE]_(G'C47DB4W[__XM=](MU^(M]_(GL7<.0C;0F`````%6)Y8/L&(EU^(MU#(E]_(M]"(E= +XM](7VBU\D='8QTKG@L00(N`$```#H@____X7`="?'1"0(38L(",=$)`0%```` +XMB30DZ/>8```QP(M=](MU^(M]_(GL7<,QTKD`L@0(L`+H2O___X7`=<"Q!`BP`>CH_O__ +XMAC__X7` +XM==6-D\`!``"Y`+($"+`"Z*?^__^%P'6_QT0D!`\```#'!"1L(0D(Z+/H__^% +XMP'6GC9/8`0``N2"R!`BP#^AY_O__A575E-1@^PXBP&+202)1=2A)"$)"(E-T(/``:,D +XM(0D(@^@!#X5F`P``BT70BQC'1"0$+P```(D<).AJZO__AB35\(0D(QT0D!!0"``#'!"0! +XM````Z"GL__^%P(G'#X3J`@``B7XDQP0D`````.BP[?__A<`/A7@!``"#CE0( +XM```0]H<1`@```@^$>P$``(V'!`$``(E$)`3'!"0`````Z)[F__^#P`$/A*&8`@``&"L!`C'AF0(``#@JP0(QX9H +XM"````````,>&;`@``,"K!`C'AG`(``#@I00(QX9T"```L*H$",>&>`@``)"Y +XM!`C'AGP(``!PKP0(QX:`"```L-`$",>&B`@``("J!`C'AH0(```@I@0(QX:0 +XM"````*H$",>&E`@```````#'AHP(``#0S@0(QX:8"```8*<$",>&G`@``,"F +XM!`C'AJ`(``!`PP0(QX:D"```P*<$",>&J`@``)"F!`C'!"1MBP@(Z`?F__^% +XMP(E%W`^$G0$``(U%Y(L>B40D"(M%W,=$)`0!````B00DZ-#K__^+1>2#^/\/ +XMA%`!``"%P`^%J````(M%W(E<)`C'1"0$E(L("(E$)`RA$"$)"(D$).@,Y?__ +XMQP0D`0```.CPZ___@8\0`@````(``/:'$0(```(/A87^___'1"0(`````,=$ +XM)`0`````QP0D6HL(".@MZ___@_C_B<,/A'W^__^-AP0!``")1"0$B1PDZ`#E +XM__^#P`%T#8D<).C3Z?__Z5G^__^+!KICBP@(Z![[___'!"0!````Z';K__^) +XM]HM%W(D$).B9Y?__A<")1ER)1F`/A-0```"-1>B)1"0,C47LQT0D$`````") +XM1"0(QT0D!`````#'!"0`````Z$T3``"%P'5+BT7LQT0D#`````#'1"0(```` +XM`,=$)`0`````B49(B49$BT7HB48\B48XH00A"0B)!"3H]N/__\=$)`0````` +XMB30DZ%+[__^%P'1NQP0D`0```.C6ZO__B?:A$"$)"(E<)`C'1"0$=(L("(D$ +XM).C+X___QP0D`0```.BOZO__QT7____Z-3E__^+1=")-"2)1"0(BT74 +XMB40D!.C*=P``BUXDQT0D!`````#'!"0!````B478C8.H`0``B40D".CJZ/__ +XMC8/``0``B40D",=$)`0`````QP0D`@```.C,Z/__C8/8`0``@]H<0`@```G5=BX>D`0``A?__Z$$(0D(B00DZ(CE___K@9"058GE5U93@>PL!0``BU4(BTT4BT(0BT`D +XMB87P^O__N---8A#W;12+113!^@;!^!\IPFG"Z`,``(F5Z/K__RG!:<'H`P`` +XM]D40`8F%[/K__P^%C@4``(N5\/K__XN"$`(``*A`#X5:!0``J:`!``!T&:@@ +XM#X6,!0``A,`/B)4%``#VQ`$/A5\"``"+310QTH7)=!6+E>CZ__^+C>SZ__^) +XM5>"-5>")3>2+10B+0!")A?SZ__^+2"2X(````(F-`/O___:!$0(```(/A'`! +XM``")]L>$A03___\`````@^@!=?"%TG1'@XT(____`8E4)!"-E0C____'1"0, +XM`````,=$)`@`````B50D!,<$)`$```#H#^+__X/X_P^$4P$``(7`NP0````/ +XMA#\!``#V11`PD`^%GP,``,>%^/K__P````"+C?SZ__^X(````(N5_/K__X/! +XM"(F-Y/K___:"5`@``"`/A.X"``"%P`^%O````(N-_/K__[`!@XT(____`8MQ +XM"#NUY/K__W1(,?^0C70F`(M%"/:`KP0```%T*(N8@````+@!````BTL$B+-CNUY/K__W7"C4%^/K__P````#H=.3__[L#````@S@$=!W'1"0( +XM=+P("+,"QT0D!`4```"+10B)!"3H29```(N%^/K__X7`#X6``0``@_L$=K#H +XMY>'__XN%]/K__XN-\/K__XM5#(E"%#'`B4H0QT(("0```('$+`4``%M>7UW# +XMBY7P^O__@.3^C4WHB8(0`@``C47LB40D#(U%\(E,)!")1"0(QT0D!`$```"+ +XM50B)%"3H00X``(7`#X7_`@``BUWHA=L/A%?]__^-18B+=>R)A0C___^-1;2) +XMA0S___^+1?"-G0C[__^)78C'1;0`````QT6\`````,=%D`````")1"0,QT0D +XM"+.+"`C'1"0$``0``(D<).@0Y/__B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!T +XMZ??"@(```'4&P>H0@\$"`-*#V0,IV8E-D(V-"/___\=$)`@`````B4PD!(M% +XM"(D$).CNI```A<`/A%8"``"+10S'0`@+````,<#I\O[__Y"-="8`BU4,,<#' +XM0@@#````@<0L!0``6UY?7<.+10S'0`@"````@<0L!0``,7UW#C46TB40D",=$)`01````QP0D`````.@DY/__ +XMZ6#^___'1"0(_P```(N%\/K__\<$)`````")1"0$Z('F__^#^/^)P@^$_?W_ +XM_X7`#X2B````BTT(]H&L!````70FBX7P^O__@'P"_PIT&8N-`/O__P^V@10! +XM``"+C?#Z__^(!!&#P@&+A0#[__\QV\>```$```````")E?3Z___ITOW__XU% +XMM(E$)`3'!"0`````Z+S=__^%P`^%1OS___9%$!!U=8N%`/O__P5<`0``B40D +XM",=$)`01````QP0D`````.A;X___QX7X^O__`0```.D8_/__BY4`^___NP$` +XM``"+@@`!``"#P`&#^#&)@@`!```/CUS]__\/MH(4`0``,-N+C?#Z__^(`<>% +XM]/K__P$```#I//W__XM%M(E%B(M%N(%EB/_Y__^)18R+1;R)19"+1<")192+ +XM1<2!991_____B468BT7(B46*`@("`=.GWPH"```!U +XM!L'J$(/!`@#2@]D#*=F-E0C___^)39#'1"0(`````(E4)`2+30B)#"3H)J(` +XM`.D[_?__D%6)Y8/L&(M%#(E=^(EU_(D$).A=X/__A<")PW01@_C_=`R)!"3H +XMZN/__X7`=1(QP(M=^(MU_(GL7<.-M@````"-<`&)-"3H>>+__XM5$(7`B0)T +XM'(ET)`B)7"0$B00DZ-#A__^+7?@QP(MU_(GL7C;0F`````(V\)P````!5B>53B<.#[`2+@(@! +XM``"%P'02B00DZ*GB___'@X@!````````BX.,`0``A+__\>#D`$```````"+@Y0!``"%P'02 +XMB00DZ%7B___'@Y0!````````BX.8`0``A6#[!B)=?B+=0B)??PQ_XE=](M>)/:#$`(``!AU$(GXBUWT +XMBW7XBWW\B>Q=PY")-"3HR`X``(7`#Y7`#[;XBX,0`@``)1`"```]$`(``'0Y +XMBX,0`@``)0@"```]"`(``'0YC8,$`0``B40D",=$)`01````QP0D`````.AB +XMW___@Z,0`@``Y^N5B?#HOO[__X7`=+R_`0```.NUBT8DZ`O^___KO8GVC;PG +XM`````%6)Y8/L2(72B77\B<:)7?AT'L=$)`@!````B50D!(D$).CNWO__BUWX +XMBW7\B>Q=PXU=T(E,)`R)'"3'1"0(^I8(",=$)`0H````Z`7>__^)7"0$B30D +XMQT0D"`$```#HL=[__XM=^(MU_(GL7<.-=@!5B>575E.#["R+=0B+7A"+0R2) +XM1>2`NU0(````#XB^`0``#[95#(/B`8G7#X0_`0``BX:L!```J`0/A5$!``#V +XM10P"=`BH"`^%0P$``*@$D'0)@^#[B8:L!```J`AT:X/@]XF&K`0``(U#"#D& +XM="S'1"0(`````(M&2`-&-(E$)`2A#"$)"(D$).B6W?__H0PA"0B)!"3HN=O_ +XM_\=$)`@`````BT8T`T9(@^@!B40D!*$,(0D(B00DZ&?=__^A#"$)"(D$).BZ +XMVO__B?B$P`^$S````(M&$(M8)(N#$`(``*@(#X75!```]L0"#X4Q`P``BU7D +XM@XH0`@``"?:&K`0```$/A(@```"+1>2+D(P!``"%TG1[]H8@`@```0^$`@4` +XM`(N&&`(``(T$0,'@`@-&$(M`.(/H`8D4)(E$)`C'1"0$`````.@YV/__QT0D +XM"(#*!`C'1"0$`0```(D$).@AV___@\0L,)-"3'1"0('(P(",=$)`0#````Z&^'``"#Q"RX +XM`0```%M>7UW#B?:)'"3H^/S__X7`#X7``P``@:-4"```?____^DC_O__D,<$ +XM)`$```#HR-W__X7`=*G'1"0(`````,=$)`0_````B30DZ!B0``"%P`^%@`,` +XM`/:&]`,```$/A"P$``"+ANP#``"-!$#!X`(#1A"+6#C'!"1MBP@(Z.G6__\Q +XMR8G:B47HN&V+"`CH)/W__\<$)/2+"`CHS-;__XE%[/:&(`(```$/A/<#``"+ +XMAA@"``"-!$#!X`(#1A"+2#@QTKCTBP@(Z.K\___'!"3ZBP@(Z)+6__^)1?#V +XMAF`!```!#X2R`P``BX98`0``C01`P>`"`T80BT@X,=*X^HL(".BP_/__Z%_: +XM___'``````"A`"$)"(D<)(E$)`BA!"$)"(E$)`3H']?__X7`#X2:`P``BTWH +XMAR%T@^$UP,``(M%\(7`#X2[`P``B70D!(M&$(V?7`$``(D$ +XM).B][/__Z,S9___HM]C__XUV`.B_VO__H0PA"0C'1"0$`0```(D$).CZU___ +XMH0PA"0C'1"0$`0```(D$).CEV/__QX<,`@```0```,=$)`0`````QP0D$@`` +XM`.CWVO__B5PD!,<$)`````#H1]7__X7`#X75`@``BX<$`0``]L0"=`J!CUP! +XM`````@``]L0$=`J!CUP!````!```@8]H`0``@````,:'=P$``/_&AW4!``#_ +XMQH=V`0``_\:'>P$``/_&AWH!``#_QH=^`0``_XDT).@+"@``A<`/A?4!``#I +XMK@$``(V#C`$``(E$)`C'1"0$18L("(DT).BT^/__C8.8`0``B40D",=$)`3@ +XMBP@(B30DZ)KX__^-@Y0!``")1"0(QT0D!.6+"`B)-"3H@/C__XV#B`$``(E$ +XM)`C'1"0$N8P("(DT).AF^/__C8.0`0``B40D",=$)`27C0@(B30DZ$SX__^+ +XM@Y@!``"%P`^$D@$``(N3E`$``(72#X1R`0``BX,$`0``BY,(`0``B8,P`0`` +XMBX,,`0``@\H#@8LP`0````$``(F#.`$``(N#$`$``(F3-`$``(F#/`$``(N# +XM%`$``(&+/`$``,\%``")@T`!``"+@Q@!``")@T0!``"+@QP!``")@T@!``"+ +XM@R`!``")@TP!``"+@R0!``")@U`!``"+@R@!``")@U0!``"+@RP!``")@U@! +XM``"!PS`!``")7"0(QT0D!!$```#'!"0`````Z$O9__^%P`^$7UW#@\0L +XMN`$```!;7E]=PX'#,`$``.NTO__Z1C\__^)7"0,QT0D"`*,"`C'1"0$ +XM`P```(DT).@9@@``N`$```#I8?K__Y"0D)"0D)"0D)"0D)"0D%6)Y8/L"*&@ +XM%`D(BU4(A"N+`8@0@\`!#[;2B0')B=## +XMH00A"0B)%"2)1"0$Z![2___)B<*)T,.-="8`.T$8?`6`^@IURXD4)(E,)`3H +XMOM?__XG"Z\>-M@````!5B>575E.#["R+=1B%]G0&QP8!````C47LB40D",=$ +XM)`1H=`A`QP0D`@```.BSTO__@\`!#X2&`0``#[=][`^W1>Z%_P^4PX7`B47< +XM#Y1%XXM%#(7`=!R$VP^$Y````(7V=`;'!@````"#Q"PQP%M>7UW#A-L/A+D` +XM``#'!"1MBP@(Z`W1__^%P'05A-L/A8P!``"`?>,`#X51`0``C78`A?]U!&:_ +XM&`"+7=R%VW4'QT7<4````,<$)/2+"`CHTM#__X7`=!K'1"0("@```,=$)`0` +XM````B00DZ*;4__^)Q\<$)/J+"`CHJ-#__X7`=!O'1"0("@```,=$)`0````` +XMB00DZ'S4__^)1=R+31"%R70%BU40B3J+512%T@^$1____XM%%(M5W(D0@\0L +XM,,!Z7G^__^+@A@"``"-!$#! +XMX`(#0A"+0#CI>____\<$)&R,"`CHRM;__X7`>#B)1=SIFO[__XG"BX!8`0`` +XMC01`P>`"`T(0BT`XZ6?____'!"1'@QP(/$<%M>7<.-M"8`````#[=%H(D<)"7O_P`` +XMB40D!.@_U?__A +XM7<.%]G0FB5PD#,=$)`BXC0@(QT0D!`4```")-"3H^'T``+@!````Z6#___^# +XMQ'"X`0```%M>7<.)]H7V=.Z)7"0,B30DQT0D")^M"`C'1"0$!0```.C`?0`` +XM@\1PN`$```!;7EW#C70F`%6)Y5.#[!2+70B+50R+0Q"#^AZ+2"1T>WX6@_H_ +XM="&#^DIT-8/$%#'`6UW#C70F`(/Z"'0+@_H8=>J-M@````"!B%0(``"````` +XM,<"#HZP$``#S@\046UW#BT44BP"%P'56@XD0`@``!(M#((7`=+2+0`B%P'2M +XMB1PDQT0D"`$```")1"0$Z&77__^#Q!0QP%M=PXM%%(L0B1PDB4PD!(72#Y3` +XM#[;`B40D".CP_?__@\04,Q=Z9_^__^+7?0QP(MU^(M]_(GL7<-5B>53@^P$BT4(BX!$`0``A@`````B?:+5>B+@B"."`B)!"3H$\__ +XM_X7`B<B+@CB."`B#PA")5>B%P`^%3?___XL=2(\("(7;#X3+````QT7D +XM`````(MUY(N&0(\("(D$).A+SO__A<")1?`/A)$```"#P`$/A(@````/MH9, +XMCP@(OR`0"0@Y!2`0"0AT"X/'"#D'=?F%_W1IBT7DBU7PBX!(CP@(B470B10D +XMZ*'1__^+==")-"2)P^B4T?__C5<$QT0D(`8```#'1"0<`@```,=$)!@!```` +XMB50D%(E<)!"+5?")1"0(B70D!(E4)`R+=0B)-"3HX\\``(7`#X5E`0``BU7D +XMBX)8CP@(@\(0B57DA<`/A3S___^+#6B/"`B%R0^$30$``,=%X`````#ID0`` +XM`(M5X(MU[(N2:(\("(E5U(DT).@'T?__B478BT7$B00DZ/G0__^+5=2)%"2) +XMP^CLT/__QT0D(`8```#'1"0<`@```(MUV(ET)!B+5>R)7"00B50D%(MUQ(E$ +XM)`B)="0,BT74B40D!(M5"(D4).@YSP``A<`/A;L```"0BW7@BX9XCP@(@\80 +XMB77@A<`/A+````"+=>"+AF"/"`B)!"3HW,S__X7`B47$=-&#^/]TS/R_C8P( +XM"+D"````B<;SIG2[BT7@BX!DCP@(A<")1>P/A2W___^+=<2+5>")-"2+NFB/ +XM"`CH-]#__XD\)(G#Z"W0___'1"0@!@```,=$)!P"````QT0D&`````#'1"04 +XM`````(E<)!")="0,B40D"(E\)`2+10B)!"3H?LX``(7`#X1&____@\1____XL3A=)T!HM#!(E"!(M#!(D0B1PDZ`;.__^+GD`!``"%VW7-C88L +XM`0``.88L`0``=`Z)10B#Q!!;7EWI//___X/$$%M>7<.0C70F`%6)Y5.#[`2+ +XM0!"+D$`!``"%TG1*,=L/MD(0@^@Q/`AW#P^VP/\DA;"/"`B)TXUV`(L2A=)U +XMX(7;="2+$X72=`:+0P2)0@2+0P2)$(U#"(D$).C:_O__B1PDZ';-__^#Q`1; +XM7QD(0->N8QD(0-(UT)@#KCHVT)@````"-O"<`````58GE@^P8QT0D!#P` +XM``")7?2)=?B+=12)??S'!"0!````Z-[*__^%P(G##X2#````A?:)QXEP#'47 +XMBT40B4,0B?B+7?2+=?B+??R)[%W#B?:)-"3H+,S__X7`B4,(=":+30R%R733 +XMBU40A=)TS(M5$(D$)(E4)`B+50R)5"0$Z#',___KM(M5",=$)`@`````QT0D +XM!`4```")%"3H<'4``(M#"(7`=;B)'"0Q_^ASS/__ZXR+10@Q_\=$)`@````` +XMQT0D!`4```")!"3H0'4``.EJ____C70F`(V\)P````!5B>564X/L,(M="(U% +XM](MU&(E$)!"-1?")1"0,QT0D"`$```"+10R)'"2)1"0$Z*U```"%P'0,@\0P +XMN`$```!;7EW#BT7TB1PDQT0D"`````#'1"0$`````(E$)`SHOO[__X7`B<-T +XMSXM%](7`="R+512%TG1,BU7PBT,(`540BU44B50D"(M5$(D$)(E4)`3H/\O_ +XM_XM%%(E#$(U6"(D3BT8,B4,$.U8(=!^+1@R)&(E>#(M#$`%&%(/$,%LQP%Y= +XMPRM%$(E%%.NLB5X(Z^&058GE5U93@^PLBT4,BWT(A<`/A,X"```/M@#V11@$ +XMB$7K#X4-`0``]D48`@^%^0```,=%[``````/ME7K,N+1Q"+L$`!``"%]G4/Z9`"``"+-H7V#X2&`@``.E80=?&% +XM]@^$>0(``(7)B?8/A(X!``#V11@!#X2'````@$X8`8M5$(M-%(L:.QEV$^D@ +XM`0``BT44@\,!.1@/@A(!``")="00QT0D#`````#'1"0(`````(E<)`2)/"3H +XM+?[__X7`=,Z-1@B)!"3HOOO__[@!````QT84`````,9&&`"#Q"Q;7E]=P_9% +XM&`$/A(X!``")^.AE_/__QT7L`0```.GQ_O__BTT0,<"+$8M-%#L1#X0E`0`` +XMBTT0B70D$(E$)`R+002)5"0$B3PDB40D".BY_?__ALQQT7L`````,=% +XM\`````#I0?W__\=$)`0<````QP0D`0```.@;QO__A<`/A)````")Q@^V1>N( +XM1A"-1@B)1@B)1@R+5Q"+@D`!``"%P(D&=`R+@D`!``")<`2+5Q")LD`!``"+ +XM1Q`%0`$``(E&!.DR_?__,<"#?>P`#Y3`B47P#[:4DS0$``"(5>L/MM+IP_S_ +XM_XM5$(M-%(L".P$/A4W___^+=Q`QR<=%[`````#'1?``````@<8D`0``Z=/\ +XM___'1"0(`````,=$)`0%````B3PDZ'=P``"X`0```.DO_?__D)"0D)"0D)"0 +XMD)"0D%6)Y5=64X/L/(M=%(MU"(M]#(7;#X2D````BT40BPB)3?")RCD/=FOI +XMA0```(UV`(-&9`&Z'X7K48M-\(G(]^+!Z@5KTF0YT74_BT80]H!4"```!'5< +XMQT0D#`$```#'1"0(`````,=$)`0`````B30DZ!HT``"%P'4,BT80]H!4"``` +XM!'4LBTWPC5'_B57P.1=W'XE4)`2)-"3H040``(7`=(V[`0```(/$/(G86UY? +XM7<,QVX/$/(G86UY?7<.-1?")1"0$B30DZ(,]``"%P'72BTT0BQ$[5?`/@M4` +XM``"0#X23````B57P.Q=W=XUV`.DF`P``@T9D`;H?A>M1BTWPB+1A#V@%0(```$#X7\`@``QT0D#`$```#'1"0(`````,=$)`0````` +XMB30DZ%$S``"%P'40BT80]H!4"```!`^%R`(``(M-\(U1_XE5\#D7#X.W`@`` +XMB50D!(DT).AP0P``ADJ____C47HC5WDB40D$(E<)`S'1"0(`0```(E4 +XM)`2)-"3H=3H``(7`#X4`____BU40BT($.T7H#X-%!0``BQ*+!SG0#X22`P`` +XMBU\$QT7@`````(7;B5W<#X20````C57DQT0D$`````")5"0,QT0D"`$```") +XM1"0$B30DZ!HZ``"%P`^%I?[__X7V#X3^`@``BUX0A=L/A/,"``#V@U4(```! +XM#X7F`@``BT7"+0WB)1>R!BU0(`````0`` +XMBUW")!"3HIL3__XM-$(L1C47HC5WDB40D$(E<)`S' +XM1"0(`0```(E4)`2)-"3HBSD``(7`#X57`0``BU7HA=(/A)@```"+11"+0`2) +XM1=2-0O\Y1=0/A(,```"+3=R-1!'_*T74.<$/AQ8$``"+3=R%R0^%MP,``(7V +XM=!2+7A"%VW0-]H-5"````0^$*00``(7`QT7L`````,=%X``````/A08%``"+ +XM1>2+7>`K5=0#7=R#P`$#1=2#Z@&)5"0(B1PDB40D!.CGP___BU40BT7H`47< +XM@VW<`8M2!"E5W(M-W(E,)`R+7>")7"0(BP>)-"2)1"0$Z'0]``"%P`^%D``` +XM`(M5$(L"B47P.0=R=.E5`0``@T9D`;H?A>M1BTWPB+ +XM1A#V@%0(```$#X4K`0``QT0D#`$```#'1"0(`````,=$)`0`````B30DZ.$P +XM``"%P'40BT80]H!4"```!`^%]P```(M-\(U!_XE%\#D'#X/F````B40D!(DT +XM).@`00``AP___Z8W\__^-1>B)1"00C47DB40D#,=$)`@!````BP>) +XM-"2)1"0$Z-$W``"%P`^%7/S__X7V=':+7A"%VW1O]H-5"````75FBT<$.T-X +XM#X?4`@``BU-TB57@BT-XB47L@8M4"`````$``(M'!(E$)`B+1>2)1"0$BTW@ +XMB0PDZ&["__^+1P2)1"0,BUW@B5PD"(L'B30DB40D!.@./```A<`/A>G[__\Q +XMV^DH____QT7L`````(M'!,=%X`````"%P'2JB40D#(U%[(E$)`C'1"0$```` +XM`(DT).@/X```A<`/A*K[__^)1>"+1P3I?/___XM%W,=%[`````#'1>`````` +XM!0`!```/A"7]__^)1"0,C47LB40D",=$)`0`````B30DZ,7?``"%P(E%X`^% +XM__S__^E8^___D(UT)@"-1>B)1"00C47DB40D#,=$)`@!````B50D!(DT).B> +XM-@``A<`/A2G[__^%]@^$NP```(M>$(7;#X2P````]H-5"````0^%HP```(M% +XMZ#E#>`^"+@(``(M3=(E5X(M#>(E%[(&+5`@````!``"+1P2%P`^%G@$``(M= +XM$(M%Y(M;!(/``8E=V(M5V(M=X`-?!`-%V/?2`U7HB40D!(D<)(E4)`CH#<'_ +XM_XM'!(M5$`-%Z(/H`2M"!(E$)`R+3>")3"0(BP>)-"2)1"0$Z*$Z``"%P`^% +XMO?W__S';Z;O]__^!H%0(``#__O__Z6OZ__^+1>C'1>P`````QT7@`````(7` +XM#X1F____B40D#(U%[(E$)`C'1"0$`````(DT).B/W@``A<")1>`/A4#____I +XM(OK__S';A?9T>HM>$(7;='.+3>`Y2W1T:SM%[`^&6?S__XE$)`R-1>R)1"0( +XMBTW@B30DB4PD!.A'W@``A<`/A.+Y__^+71")1>"+5>B+6P2)7=3I(_S__\=$ +XM)`C4CP@(NP$```#'1"0$`P```(DT).AN:0``Z?+\__^+71"+$^GE^?__@:-4 +XM"```__[__SM#>`^'E@```(M#=(E%X(M#>(E%[(&+5`@````!``"+51"+4@2) +XM5=2+5>CIO?O__XE$)`R-0WB)1"0(BT-TB30DB40D!.BKW0``A<`/A$;Y__^) +XM0W3I`OW__XE$)`B+1>2)1"0$BTW@B0PDZ(F____I1_[__XE$)`R-0WB)1"0( +XMBT-TB30DB40D!.AFW0``A<`/A`'Y__^)0W3IA?K__XE$)`R-0WB)1"0(BT-T +XMB30DB40D!.@\W0``A<`/A-?X__^)0W3I0/___XE$)`R-0WB)1"0(BT-TB30D +XMB40D!.@2W0``A<`/A*WX__^)0W3IJ/W__XE$)`R-1>R)1"0(QT0D!`````") +XM-"3HY]P``(7`#X6@_O__Z7WX__^0D)"0D)"0D)"058GE@^P8BU4(]H)$`@`` +XM`70DBX(\`@``C01`P>`"`T(0BU`XA=*Z`0````^4P(3`=!C)B=##BX(\`@`` +XMN@$```"%P`^4P(3`=>CHY;O__\<``````,=$)`0&````BT44B00DZ+RY__^% +XMP'4DQT0D"`$```#'1"0$`@```(M%%(D$).C]M___N@$```#)B=##Z)^[__^# +XM."-T%HVV`````.B/N___,=*#."-UAHUT)@#)N@(```")T,.-M"8`````58GE +XM@^P8B5WXBUT(B77\BW4,BX.D````AQ=PXD<),=$ +XM)`@`````QT0D!`4```#H`&<``(M=^(MU_(GL7<.-M@````!5B>6#[!B+30B+ +XM41R%TG0.BT$@]D`80'0%@SH!?@3),<##BT4,ABX48VO__A%#-K__P````"%P`^$/@$``(M%&(/@`H/X`1G2@>+X`P``@<()`@`` +XMB84(VO__B94`"`T(0BW`XZ*6X___'```` +XM``#'1"0(`````,=$)`0`````BY5`VO__B10DZ$&Z__^%P(F%*-K__P^(L@4` +XM`(V=C/[__S'_B5PD!(M%"(D$).A8)P$`QT0D&`````#'1"04`````,=$)!`` +XM````QT0D#`````#'1"0(`````,=$)`0`````B1PDZ!`R`@"`/DX/A`<%``") +XM-"3HT[O__XET)`B)7"0$B40D#(M5"(D4).B(-0$`A<`/A*`#``"`O0;:__\` +XM#X2&`0``N`$```"!Q!PF``!;7E]=PXUV`("]!]K__P`/A#,#``"%VP^%*P,` +XM`(N5$-K___9"6`$/A?0&``"+E1#:__^+19`[0D0/A`D#``#V11@0N"R1"`AU +XM!;ATD0@(B40D#(N%0-K__\=$)`0#````B40D"(M5"(D4).AX:```N`$```#I +XM@/___XM5"/:"^`(```$/A#X#``"+@O`"``"-!$#!X`(#0A"+6#B%VP^5P(3` +XM#X1:_?__]D48$+ATD`@(=06XJ)`("(E$)`C'1"0$`P```(M5"(D4).@(8P`` +XM@<0<)@``N`$```!;7E]=PXM5&(F=0-K__\>%&-K__P````#&A0?:__\`@^($ +XMB94`VO__#Y2%!MK__^D%_?__B<*+@*`$``"-!$#!X`(#0A"+4#B%T@^4P.D1 +XM_?__BX4DVO__B00DZ#&W__^%P`^%D@D``(N%.-K__X7`="Z+10B%P'09BU4( +XMBT(0A#91@#@WT8`0^$E@4``(U%Z(E$)`B+A4#:__^)1"0$ +XMBU4(B10DZ.A4``"+G0S:__^%VXF%(-K__P^%+00``,=$)`@`````QT0D!$R2 +XM"`B+10B-O4SZ__^)!"3H,U<``(M5[(E4)!2+5?")5"00BY4@VO__B40D",=$ +XM)`1`!```B3PDB50D#.BKM?__B?F)PXM%"(MP.#GS#X-5!@``B4PD#,=$)`B? +XMK0@(QT0D!`0```"+10B)!"3HUF```(M5Z#'`A=(/A.O\__^+10B%P'09BU4( +XMBT(0AWZ__^-E7#___^) +XM5"0$BX5`VO__B00DZ%"R__^%P`^%F`0``(N5$-K__X!*6`&+A7#___^)0CR+ +XMA73___^)0D"+19")0D3I&/W__^B\LO__@S@"#X12_/__B[5`VO__QX4PVO__ +XM`````,>%.-K__P````#'A23:________@[THVO___W0.BY4HVO__B10DZ`BS +XM__^#O23:____=!R+A3#:__^)!"3HL;#__XN5)-K__XD4).CCLO__A?9T'\=$ +XM)`R?K0@(B70D",=$)`0%````BT4(B00DZ#QC``"+O3C:__^%_P^$+OK__XMU +XM"(7V=!F+50B+0A"%P'0/BY4XVO__.5!T#X0&!0``BX4XVO__B00DZ`2U___I +XM^_G__X7_#X13`0``BT4(A<`/A*(#``"+10B+6!"%VP^$E`,``/:#50@```$/ +XMA8<#``"+A0#___^+`(M`"(U$`#([0W@/A[\%``"+4W2)E3C:__^+0WB)1>2! +XMBU0(`````0``BX4`____BXTXVO__BQ"#P0&+`@^V$(32#X3Y!```BYTXVO__ +XMC4@!QX4TVO__`````.L@@/HO#X17`0``#[9!_X@##[81@\,!@\$!A-(/A,@! +XM``"`^B5UVX`Y)73?Q@,E@\,!Z]>#O0S:__\!=$+HS:[__XU=T,=%V`$```#' +XM1=P`````B5PD!(M5"(D4).CI*@``A<`/A0[Y__^-1=C'1=0`````B44,B5T0 +XMZ>OZ__^+C0C:__^X>)(("(7)=06XI)((",=$)`@`````B40D!.ES^___BX5P +XM____.T(\#X4/^?__BX5T____.T)`#X4`^?__Z>GX__^-="8`BX4`____BP"+ +XM`,>%.-K__P````")A3#:__^-A1#___^)1"0$BY4PVO__B10DZ,*O__^Z`0H` +XM`(7`#X7/`@``#[>%&/___R4`\```/0"````/A'0#``#'1"0,190("(ET)`@Q +XM]L=$)`0#````BT4(B00DZ"EA``#'A23:________Z7_]__^!H%0(``#__O__ +XM,<#I&_C__XF=--K__^F>_O__BY40VO__@&)8^XN5%-K__P^W0AB$P`^)3OK_ +XM_X"]!]K__P`/A#X#``"#R$!FB4(8Z37Z___HN*___X,X#9!U#HN=`-K__X7; +XM#X5]`P``QT0D#)^M"`B+A4#:___'1"0$!0```(E$)`B+50B)%"3HBV```+@! +XM````Z9/W___&`R7&0P%DQD,"`(N%--K__X7`#X3U`@``BY4TVO__Q@(`BX4X +XMVO__B00DZ,6N__^+E33:___&`B^#P@&)E3S:__^)QX7_#X0\`@``QX4LVO__ +XM`````(D\).@'LO__A<`/A$0!``"-5>"#P`B)5"0(BY4\VO__B00DB50D!.B# +XMKO__@^@!=<^+1>`YA2S:__]]Q(F%+-K__^N\QT0D#)^M"`B+E4#:___'1"0$ +XM!0```(E4)`B+10B)!"3HPE\``(D<).@^K___N`$```#IPO;__XN5(-K__XD4 +XM).A6LO__C4[]C10'B?@YUW(0ZQJ-="8`@\`!.<)V#X/K`8`X+XUV`'7N.%.-K__P````"-1``R +XMA<`/A([\__^)1"0,C47DB40D",=$)`0`````BU4(B10DZ(O.``"%P`^$)@(` +XM`(F%.-K__XN%`/___XN-.-K__XL0@\$!Z4S\__^)/"3HL['__XN%+-K__\=$ +XM)`A:W@@(@\`!B40D#(N%.-K__P-%Y(D<)"G8B40D!.@WKO__BX4XVO__B84P +XMVO__Z0S]___'1"0(@`$``(E4)`2+E3#:__^)%"3H+*___X7`B84DVO__#XC/ +XM^O__C95,VO__QT0D"``@``")5"0$BX4HVO__B00DZ#ZQ__^#^`")QP^.EP$` +XM`#';ZP8IQW3-`<.-A4S:__\!V(E\)`B)1"0$BX4DVO__B00DZ*NH__^%P'G8 +XMB[4PVO__Z6WZ__^!H%0(``#__O__Z?GT__^+A0#___^+`(LPQX4PVO__```` +XM`,>%)-K________I._K__XN='/___^C?K___.<-T%)-K________I_/G__XN5%-K__X/@OV:) +XM0ACI\?;__XN%.-K__\8`)8G#Q@%DQD$!`,<$)$'Q"`CHVZO__XG'BX4XVO__ +XMB84\VO__Z1?]__\/MX48____N@$$``"H-@^$KO[__\=$)`S4D0@(Z?'[__^- +XMA1#___^)1"0$BY5`VO__B10DZ&^K__^%P'41#[>U&/___XGPA,`/B8$```#H +XM]:O__\<`#0```.E&_/__B40D#(U#>(E$)`B+0W2)1"0$BT4(B00DZ&G,``"% +XMP'0(B4-TZ1CZ__\Q]L>%,-K__P````#'A3C:__\`````QX4DVO_______^D- +XM^?__?!:+E2C:__^)%"3H'*S__X7`#X35]/__B[5`VO__Z>KX__^+G1S____H +XMCJ[__SG##X5L____9H'.@``/M\:)1"0$BY5`VO__B10DZ!RN__^%P`^%2O__ +XM_\=$)`BV`0``BX4___\G#C;0F`````(N"\`(``(7`#Y7`ZX&-=@!5,G"[O__B?:+@QP! +XM``"-!$#!X`(#0Q"+0#B%P`^5P(3`=____Y"-M"8`````58GE5U93@>R\"``` +XMBU4,#[="&*@@="&#X-]FB4(8B50D!(M-"(D,).BCK@``@<2\"```6UY?7<.+ +XM50R#X`%FB4(8QT0D!%P```#'!"0!````Z!ZF__^%P(F%5/?__P^$UP8``(N% +XM5/?__X!(6`+'0!0`````QT`0`````,=`2/_____'0%3_____BU4,BU((A=*) +XME5SW__\/A!@"``"+C5SW__\/M@$\+P^$)P,``#PN#X0#`P``C95L____B50D +XM!(N-7/?__XD,).@5I/__N@$```"%P`^$Z0```(M%"/:`U`(```$/A-P&``") +XMPHN`S`(``(T$0,'@`@-"$(M0.(UR`>L-A-L/A&,&``")\H/&`0^V7O^`^SIT +XM!(3;=?"-1OXYPG/?QD;_`(N%7/?__XV];/?__XE4)`S'1"0(N90(",=$)`0` +XM!```B40D$(D\).C.I/__C95L____B85@]___B%[_B50D!(D\).ASH___A)UL'_'XG_P?\? +XMB?Z)_L'N%C'_`<81UP^L_@K!_PJ#_@IW#(7V9KL`!`^%E@4``(N%5/?__X!( +XM6`&+A6S___^+E53W__^)0CR+A7#___^)0D"+18R)0D0/MX5T____)0#P```] +XM`(````^$)`(``,=$)`RXDP@(BXU8]___QT0D!`,```")3"0(BT4(B00DZ-]3 +XM``#I^@$``(MU%(/F"(UT)@#'1"0(`````,=$)`0*````BU4(B10DZ*57``"% +XMP`^$%P$``(M5#(M""(7`=!*)!"3HGZ7__XM-#,=!"`````"+50PQVXM"#(7` +XM="")!"3HP:#__XM-#(M!#(D$).ASI?__BT4,QT`,`````(N55/?___9"6$`/ +XMA24$``"+C53W__^+04R%P'05B00DZ$2E__^+A53W___'0$P`````BY54]___ +XMBT($A7UW##[9! +XM`3PO=!0\+@^%[?S__X!Y`B^)]@^%X?S__XV%;/___XE$)`2+A5SW__^)!"3H +XM]J#__S'2A<`/E,+IR_W__XM-"/:!>`$```$/A+`#``"+@7`!``"-!$#!X`(# +XM01"+0#B-G6S[__^)1"0,QT0D"+^4"`C'1"0$``0``(D<).CFH?__B1PDZ.ZB +XM__^#^/\/A-4#``")!"3HO:'__XM%#(M0"(72#X0L!```B1PDZ)>=__^+50R% +XMP(E"#`^$[@,``(M""(7`#X2^`P``BU4,A?:+4@R)E5CW__\/A#P#``"+A53W +XM__^[``0``(/`1(D$).A4G/__BU4(QT7,`````,=%X`````#'1=``````QT78 +XM`````,=%W`````#'1>0`````QD7@"HE=U(M"$(N`5`@``(/@0(/X`1G`]]"# +XMX`2)12+A53W__\QTH!(6`2-1Z``"%P'4,BY54]___BT),B47DBY58]___Z0_] +XM___'1"0(E),(",=$)`0%````BTT(B0PDZ$%)``#IG_K__XD<).BXF?__BTT, +XMA<")00@/A2S\__^+00R%P'0(B00DZ"N@___'1"0(`````,=$)`0%````BT4( +XMB00DZ/Q(``")'"3H2)O__^E2^O__9H%(&(``Z__^%P'5WBU4,9H%*&``!Z1/[__^[`0```(U][(UUZ.L1C;0F```` +XM`(M%[(7`=2:#PP&)?"00B70D#,=$)`@`````B5PD!(M%"(D$).CG$0``AR%P'0(BT7H@#@C=,N+30B)64R[`0```.GK^O__#[9``3PJ +XM=&P\+P^%8?___XM5"(&*K`0````!``"#1>@"@VWL`NL*@T7H`8/H`8E%[(M% +XM[(/X`780BU7H@#HO=>:`>@$O=>#KIX/#`8E\)!")="0,QT0D"`````")7"0$ +XMBT4(B00DZ,L0``"%P'3"Z?W^__^+50B!BJP$`````0``ZPV-=@"#1>@!@^@! +XMB47LBT7L@_@!=A.+5>B`.BIUYH!Z`2]UX.E%____@\,!B7PD$(ET)`S'1"0( +XM`````(E<)`2+10B)!"3H:1```(7`=+_IF_[__U6)Y5:)UE.#[""+6!"-5?") +XM5"0,C57WB50D"(E,)`2)!"3_DX0(``"%P'54BT7PA53BUT(#[9-#/:#X`(```$/A!P!``"+@]@"``"-!$#!X`(# +XM0Q"+0#B%P'0]#[80A-)U$.LT#[90`832C78`="F#P`$XT77NB(N(````N`$` +XM``")@Y````#&A!B(`````(V#B````%M=P_:#C`(```$/A<<```"+@X0"``"% +XMP`^$TP````^V$(32=13IQP````^V4`&$T@^$NP```(/``3C1=>T/MM$[%?P@ +XM"0A]$*$((0D(]D20-0(/A0H!``#V@Z0"```!#X3M````BX.<`@``C01`P>`" +XM`T,0BT`XA<`/E<"$P`^$D0```,'J!@^V@CR6"`C&@X@```!`"`T,0BT`XA<`/A2W___\/MM$[%?P@ +XM"0@/C4#___^A""$)"/9$D#8$#X0P____Z +XM=`.-04"(@XD```"X`@```.E8_O__C70F`%6)Y5.#[`B+70B+10R)'"2)1"0$ +XMZ.?]__^+@Y````"#Q`A;7<.-="8`C;PG`````%6)Y5=6,?93@^P,BT4(BW@0 +XMB7WPBU4(B70D!(D4).BM_?__BU4(B<.+@I````"(AUT!```/ML"-2/^#^?]T +XM)(M%\(T4=HV44%@!``"-="8`#[8#@^D!@\,!B`*#P@&#^?]U[8/&`8/'!H'^ +XM_P```'6C@\0,6UY?7<.-M"8`````58GEBT4(5XM]#%8Q]E.+2!#K#\>!'`$` +XM``````"^`0```(N9&`$``(7;="QKD1P!```53@^P4BUT,BU4(@WL(#'8%Z'R2__^+0PC_)(7H +XME0@(QT0D",N5"`C'1"0$`P```(D4).BF0```C;8`````BT,,A6# +XM["B+10S'1"00@`L%",=$)`P(````QT0D!"`0"0B(1?RAZ!`)"(E$)`B-1?B) +XM!"3H+)3__S'2A`` +XM``"+BQ0!```Y310/A]<```"-="8`BTT4`8L8`0``BY,0`0``A7UW#BY,8`0``A=(/A$?___\K112)@QP!``#I.?___XN[&`$` +XM`(N+%`$``(M5%(U$`AZ-%#@YRG-'A?]U:K@>````QX,<`0``'@```.D'____ +XMBU4(BT(0,=*`N%('``#_#X5X____BTT(QT0D!/\```")#"3H/_[__XG"Z5[_ +XM__^#^D!S!;I`````BT4(Z+;]__^Z`0```(7`#X5:____B[L8`0``ZY)KQQR+ +XMDQ`!``")1"0(:X,<`0``'(T$`HE$)`1K110@0"0C'1"0,@`L% +XM",=$)`@(````QP0D(!`)"(E$)`3HA(S__\:&4@<```"+'>@0"0B%VW0^,575E.#[&R+10B+>!"+10R%P`^$WP4``(M-%(M%%(/A0(/@08E- +XML(E%K(N'&`$``(7`="J+1;"%P`^%L04``(M%K,=%R`````#'1<0`````A<`/ +XMA#0!``"-M@````#VAU0(```@#X6F`P``QT7(`````(M-$(E,)`R+112#X#&) +XM1"0(BT4,B40D!(M5"(D4)/^7>`@``(7`#X7P`@``BTT,BT$(C5#]@_H'=R3_ +XM))40@)#X3?`@``BTT,BP&)`HM!!(E"!(M!"(E" +XM"(M!#(E"#(M!$(E"$(M!%(E"%(M!&(E"&,=%Q`````"+3:R%R0^%9`0``(M% +XM%(M5%(/@!H/B`HE%N(E5M&NW'`$``!P#MQ`!``"#?@@!#X6 +XM_?__BT4(]H`<`P```0^%S0(``(M%"(N`%`,``(7`#Y7`A,`/A!`#``"#1<@! +XM@WW(`70?BT7(NF=F9F;WZHM%R,'Z`L'X'RG"C122`=(Y57UW#QT7$`0```.G:_?__@_@( +XM#Y7`#[;PBT4(@\8&BT`0B47,BU@(B<>#QP@Y^W08C;8`````B1PDB70D!.AD +XMI```BQLY^W7NBU7,BUH0B=>#QQ`Y^W2?B1PDB70D!.A#I```BQLY^W7NZXN+ +XM0Q@!AQP!``#IL/[__XM5"(D4).AB?P$`A<`/A$?\___I9?___Y"-="8`BUW0 +XMBT$0A=MT?XG&BT70C5H<`?")1;SK)XVT)@````"+30@/ML"+41`/MI0"4P<` +XM`(E3],9#^`"#PQP[=;QT2<=#[`$````/M@:#Q@$\_XA#\'7,BU4(BT(0,=*` +XMN%('``#_=''`$```````#IZOW__XG!BX`4`P``C01`P>`"`T$0BT`XA<`/E<#I(_W_ +XM__9%%`ATBXM-##'`QD$,8<=!$`````#'00@!````QD$4`(/$;%M>7UW#,<#I +XMG/W__XU5U(E5#.D6^O__QT0D$`8```"+0R")5"0(QT0D!`````")1"0,BU4( +XMB10DZ,;V__^%P`^%7OW__P^V5@R#^G]WCI"-="8`Z0O___^#AQP!```!,<#I +XM0OW__XL&BTT,B0&+1@2)002+1@B)00B+1@R)00R+1A")01"+1A2)012+1AB) +XM01CI`O___XM5"/:"&`0```%T58N"$`0``(T$0,'@`@-"$(M`.(7`#Y7`A,#' +XM11``````#X2_^?__@WX0"71+BT4(]H`(`@```70MB<*+@``"``"-!$#!X`(# +XM0A!K0#ADB440Z9#Y__^+30B+@1`$``"%P`^5P.NRBTT(:XD``@``9(E-$.EN +XM^?__BT4(]H"0`0```70HB<*+@(@!``#KLXM-"(M!$(.(5`@```2+10S'0`@$ +XM````,<#I6_S__XM-"&N)B`$``&2)31#I*/G__Y"0D)!5B>6#[!B+10S'1"0( +XM6)8(",=$)`0#````B40D#(M%"(D$).A8-```R<.-M@````!5B>6#[#B+50R) +XM??R+?1B)7?2)=?B%T@^$PP```(M%"(M8'(7;#X0X`0``]D40`G5"BT4(]H"O +XM!```"'0CBTAXBT!\BW$4B47@BT`4.?*)1=P/@]L````[5=P/AR`!``"+0Q`[ +XM10P/A+H```#'0Q``````C44,B47DC47LQT7H!````(M3!(E$)`B-1>3'1"0, +XM`````(E$)`2)%"3_4@R#^/]T;H/H`70WBT4,A?^)0Q"+1?")0PR+1>R)0PAT +XM!8M%\(D'BT44A<`/A+\```"+0PB+512)`C'`ZRJ0C70F`/9%$`%U+(7_=`;' +XM!P````"+512X`0```(72=`F+513'`@````"+7?2+=?B+??R)[%W#BT4,B40D +XM!(M%"(D$).BL_O__Z\"%_W2:BT,,B0>0ZY(YPG=*.?)T#8VV`````(L).U$4 +XM=?F%_W0%BT$0B0>+712%VW0WBT$(BU44B0(QP.NBQT0D"`0```#'1"0$```` +XM`(D$).CU_0$`Z6;___\I==PK5=R)50SITO[__S'`Z7#___^-="8`C;PG```` +XM`%6)Y5.#[!2+30B+70R+41R%TG1A,<"%VW0CBU(4A=)T(O:!KP0```AT#(M! +XM?`-0%(M!>"M0%#'`.=H/D\"#Q!1;7<.)7"0$QT0D$`````#'1"0,`````,=$ +XM)`@`````B0PDZ/G]__^%P`^4P(/$%%L/ML!=P\=$)`@$````QT0D!`````") +XM#"3H0_T!`+@!````ZZF-M@````"-OP````!5B>6#[$B)=?B+=0B)??R+?0R) +XM7?2+7AR%VP^$NP```(M3%(72="J)%S'`]H:O!```"'00BT9\`U`4BT9X*U`4 +XM,<")%XM=](MU^(M]_(GL7<.-1?")1>"-1>C'1>0$````BU,$B40D"(U%X,=$ +XM)`P&````B40D!(D4)/]2%(/X_W0Q@^@!=':+1>"+`(E%\(E#$(E#%(M%[(E# +XM#(M%Z(E#"/:&KP0```AU8(M%\(D',<#KD<=$)`C%E@@(QT0D!`4```")-"3H +XM13$``+@!````QP<`````Z6G____'1"0(!````,=$)`0`````B30DZ#W\`0"X +XM`0```.E'____,<#'!P````#I.O___XM&?(M`%#M%\'>8ZY.)]HV\)P````!5 +XMB>6#[#B)=?B+=1B)7?2+70R)??R+?0B%]G0&QP8`````BT44QT0D"`````") +XM7"0$B3PDB40D$(M%$(E$)`SH7/S__S'2ASVAJP$```!=4N+?AR#/P%T2XM&$(M8"(/`"#G#=0[K +XM/(M&$(L;@\`(.=AT,#G>=/`Y>QQUZXM%[(E$)`B+1?")'"2)1"0$Z.))`P"% +XMP'31N`$```"#Q!Q;7E]=PXM5"#'`A=)T[XM%[(E$)`B+1?")-"2)1"0$Z+)) +XM`P"#Q!Q;7E]=PXUV`(V\)P````!5B>564X/L((MU"(M>'(7;#X2\````QT0D +XM"`<```"+10R)-"2)1"0$Z),/``"-10R)1>B+11#'1>P$````B47PBT44B47T +XMBU,$C47PB40D"(U%Z,=$)`P`````B40D!(D4)/]2$(/``0^$B````(M#$#M% +XM#'1*]D-8`G4X@$M8!,=$)`@&````BT4,B30DB40D!.@I#P``BU4,B?"Y`P`` +XM`,<$)`$```#HL_[__X/$(%M>7<.)-"3H-)X``.N^B?;V0U@"QT,0`````'2O +XMC78`Z^*)-"3'1"0(!````,=$)`0`````Z-;Y`0"#Q""X`0```%M>7<.+10R) +XM-"3'1"0(X98(",=$)`0%````B40D#.B++@``@\0@N`$```!;7EW#ZPV0D)"0 +XMD)"0D)"0D)"058GE5U93@^PLBW4(BUX2+11#'1>@$ +XM````B47LBT44B47PBU,$C47LB40D"(U%Y,=$)`P%````B40D!(D4)/]2$(/` +XM`0^$Z````(M#$#M%#'<'QT,0`````(M#%(7`=`:#P`&)0Q3V0U@"#X6'```` +XM@$M8!+\!````QT0D"`4```"+10R)-"2)1"0$Z/(-``"+10S'1"0$`@```(DT +XM)(E$)`CH6QT``(G#BT4,QT0D!`(```")-"2)1"0(Z&(X`0"%P'4(A=L/E<`/ +XMMOB+50RY`@```(GPQP0D`0```.A`_?__N@$```"%P'4"B?J#Q"R)T%M>7UW# +XMB30DZ+.<``#I;/___XDT),=$)`@$````QT0D!`````#H9O@!`(/$++H!```` +XM6XG07E]=PXVT)@````"+10R)-"3'1"0(@)8(",=$)`0%````B40D#.@1+0`` +XM@\0LN@$```!;B=!>7UW#B?95B>575E.#["R+=0B+7AR%VP^$"0$``(U%$(E% +XMY(M%%,=%Z`0```")1>R+11B)1?"+4P2-1>R)1"0(C47DQT0D#`0```")1"0$ +XMB10D_U(0@\`!#X3O````BT,0.T40=@?'0Q``````BT,4A7UW#C70F`(V\)P````!5B>56 +XM4X/L((MU"(M>'(7;#X3*````BT4,QT0D!`$```")-"2)1"0(Z/,:``"%P'0/ +XMN`$```"#Q"!;7EW#C78`BT4,QT0D!`$```")-"2)1"0(Z.DU`0"%P'76QT0D +XM"`0```"+10R)-"2)1"0$Z"X+``"-10R)1?"-1?#'1?0$````BU,$QT0D"``` +XM``")1"0$B10D_U((@^@!='*+0Q`[10QR!\=#$`````"+0Q2%P'0&@^@!B4,4 +XM]D-8`G5&@$M8!(GPBU4,N0$```#'!"0!````Z&CZ__^#Q"!;7EW#D(DT),=$ +XM)`@$````QT0D!`````#HJ/4!`(/$(+@!````6UY=PXDT).C$F0``Z["+10S' +XM1"0(_I8(",=$)`0%````B30DB40D#.A3*@``N`$```#I__[__Y"0D)"0D)"0 +XMD%6)Y5.#[`2+70R+0QB%P'0-B00D_U`$QT,8`````(M#'(7`=`^)!"3H)X'_ +XM_\=#'`````#'0R``````,<#'0RP!````QT,P`````,=#*`$```#'0R0!```` +XM@\0$6UW#D%6)Y5.#[!2+70S'0QP`````QT,@`````,=#+`$```#'0S`````` +XMQT,H`0```,=#)`$```#'1"00`````,=$)`P"````QT0D"(`!``#'1"0$!@(` +XM`,<$)`````#H-('__S'2A<")0QAT"(/$%(G06UW#QT0D"!R7"`C'1"0$!0`` +XM`(M%"(D$).A4*0``N@$```"`2U@0@\046XG07<.-=@!5B>56B<93B7<.058GE5U93@^Q,BWT(BW<<#[966/;"$`^%Z`$``(M&*#M&)`^$ +XM`0(``(/*$(U&*(A66(E%Z,=%[`0```#'1<``````BT88C57@@T8H`8E4)`B- +XM5>C'1"0,`````(E4)`2)!"3_4`R%P`^%X0$``(M=X(`["'8+Z`IZ__^-M@`` +XM```/M@/_)(5\F`@(C57$C4,!B10DQT0D"!0```")1"0$Z!!^__^+1C'1>P$````B?:+1AB-5>"# +XM;B@!B50D"(U5Z,=$)`P`````B50D!(D$)/]0#(7`#X5W`0``BUW@@#L(=@7H +XMC'?__P^V`_\DA:"8"`B-0P&)1"0$C478QT0D"`@```")!"3HF'O__XM5"(M% +XMV#M"3'29@T8H`8!F6.\QP(/$3%M>7UW#C7L!C47$QT0D"!0```")?"0$B00D +XMZ&%[__^+1___BT4(BU!,.U7P='R+50B+1?`Y0E@/A'3___^#0F`!B4)8Z6C___^- +XM0P&)1"0$C478QT0D"`@```")!"3HQGK__XM5"(M%V#M"3`^%+O___X-^*`$/ +XMA;G^___I'____XUT)@")!"3'1"0(%)@(",=$)`0#````Z*@D``"#Q$RX`0`` +XM`%M>7UW#BT7DB50D!(/H!8E$)`R-0P6)1"0(BU4(B10DZ-OT__^%P`^$7/__ +XM_^DG____BT4(N>\!``"ZP)<(".@<^___N`$```#IL_[__XGV58GE5U93@^Q, +XMBWT(BW<<#[9&6*@0#X7=`0``@WXH`0^$^`$``(/($(A&6(U&*(E%Z,=%[`0` +XM``#'1<``````D(M&&(U5X(-N*`&)5"0(C57HQT0D#`````")5"0$B00D_U`, +XMA<`/A="`.PAV!>B,=?__#[8#_R2%Q)@("(U5Q(U#`8D4),=$)`@4 +XM````B40D!.B8>?__BT7,B478BT70B472#Z`6)1"0,C4,%B40D"(M%\(D\)(E$)`3HF_/__X7` +XM#X4]`0``BT7P.4=8=*J#1V`!B4=8QT7``0```.D(____C4,!B40D!(U%\,=$ +XM)`@$````B00DZ.)X__^+1>2#Z`6)1"0,C4,%B40D"(M%\(D\)(E$)`3H;O3_ +XM_X7`#X7@````@T=<`<=%P`$```#IMO[__XU#`8E$)`2-1?#'1"0(!````(D$ +XM).B0>/__BT7PB3PDB40D!.@=]___A<`/A9\```"#1V0!QT7``0```.EU_O__ +XMBU7`A=(/A&K^__^-0P''1"0("````(E$)`2+10R)!"3H1'C__S'`@&98[^L= +XMQT0D"$B8"`C'1"0$`P```(D\).A`(@``N`$```"#Q$Q;7E]=PXD\),=$)`AL +XMEP@(QT0D!`(```#H&R(``(/$3+@!````6UY?7<.)^+F(`0``NL"7"`CHO?C_ +XM_[@!````Z[N`9ECON`$```#KL(UT)@"-O"<`````58GE5XG75HG&4X/L+(M8 +XM'(-[(`AW*HU#(,=$)`P)````B40D"(M#'(DT)(E$)`3H3)8``+H!````ABT,H,=*#P`&)0RB)0R2#Q"R)T%M>7UW#C;8`````B?"Z +XMP)<("+G#````Z,_W__^#Q"RZ`0```%N)T%Y?7<-5,<")Y593@^P@BW4(BUX< +XM]D-8$`^%J0```(M++(7)#X6K````@WL@%'B+1?2#P`6)1>R+4QB-1>B)1"0(C47@QT0D#`````")1"0$ +XMB10D_U(0@\`!#X2-````BT,H@\`!B4,HB4,D,<"#Q$!;7EW#N@$```")\.C$ +XM_/__A7<.0C47TB40D +XM$(U%\(E$)`S'1"0(`@```(M%#(DT)(E$)`3H"^K__X7`#X38_O__BT4,@_@! +XM="Z)1"0$B30DZ+_I__^X`0```.N!B?"Y$0$``+K`EP@(Z.?T__^X`0```.EF +XM____QT7T`````,=%\$^-"`CIC_[__XUV`(V\)P````!5B>6+30B+41SV0E@0 +XM=1.+0BR%P'00BT%,B4(LBT%0B4(P73'`PXM!3(E"+(M!4(E",+H"````B'[__^058GE5E.#[""+=0B+1AB%P'0CQT0D"`$```#'1"0$`````(D$).AF +XMR/__BT88B00DZ'M>``"+1@B-7@@YV'00D(D$).AH7@``BT8(.=AU\8M&$(U> +XM$#G8=!:-M"8`````B00DZ$A>``"+1A`YV'7Q]H94"````G10ZUR-M@````"# +XM>P@#N>B8"`B+4PR+0Q!T!;E/C0@(B40D#*$0(0D(B50D$(E,)`C'1"0$\)@( +XM"(D$).AM;/__BQ.%TG0&BT,$B4($BT,$B1"+7FR%VW6Q@\0@6UY=PZ$0(0D( +XMQP0D!P```(E$)`3HF6S__^O;C78`58GE5HG64XG+@^P0BQ40(0D(B00DB50D +XM!.BF;?__A=MT&:$0(0D(B5PD",=$)`2=K0@(B00DZ/EK__^%]G0HZ)!P__^+ +XM`(D$).CF;?__QT0D!)VM"`B)1"0(H1`A"0B)!"3HS6O__Z$0(0D(QP0D"@`` +XM`(E$)`3H&&S__X/$$%M>7<.-M@````"-O"<`````58GE5U93@>R<`0``BT4( +XMBYAH"```A=L/A'L#``"+50B+BI0(``"%R0^$A0,``(M="+_XF`@(BTT(_(G8 +XM@\$(@\`0B8U\_O__BS.)0Q")0Q2#P'")0WR#Z`2)@X0```"#Z$R)0S")0S0% +XM_````(E+"(E+#+D#````QX.``````````,9#<`&)@RP!``")@S`!``#'@T`! +XM````````QX-$`0```````(FU@/[___.F#X6;`@``QX6(_O__`0```,>%E/[_ +XM_P````"+71"0C70F`(/#!(L3A=*)E7C^__]T9OR_`9D("+D#````B=;SIG15 +XMBY5X_O__#[8"/"L/A,\````\+77+B[5X_O__#[9&`83`#X0I`0``/&-T##Q4 +XM=`@\='0$/'=UJ8N%>/[__X!X`@!UG8/#!(/#!(L3A=*)E7C^__]UFHM%"#'_ +XM,=LQ]H.(5`@``$#'A8S^__\`````QX68_O__`````,>%G/[__P````#'A9#^ +XM__\`````C78`QT0D"`29"`B+31")3"0$BT4,B00DZ(IM__^#^/\/A!\"``"# +XMZ$:#^#$/AK4```"+50B[`0```/^2J`@``('$G`$``(G86UY?7<.-M@````") +XMUX/'`8!Z`0!U)<<$)`0```#HS7#__X7`B0,/A'H"``#'`"UC)`#IU/[__XUT +XM)@"+C7C^__^)#"3H]G'__X/``HD$).B;%D/[__P$```#I7O[__\>%E/[__P$```#I3_[__\>%F/[__P$` +XM``#I0/[__XM-"(.A5`@``+_I,?[__XNU@/[__[_WF`@(N00```#SI@^$3?W_ +XM_XNU@/[__[_[F`@(N08```#SI@^%J`0``,>%B/[__P(```#'A93^__\!```` +XMZ3#]___'@&@(```0,@@(BU4(BXJ4"```A7UW#BT7P@XBL!``` +XM`8M="(M%\(M3"(D0BY5\_O__BT7PB5`$.U,,#X1G`P``BTT(BT7PBU$(B4($ +XMBU7PBUT(B5,(B10DZ`?:__^%P'68BX6,_O__A<`/A#`#``#'1<`9````C47( +XMQT7$-P```(N=E/[__X7;=`G'`"H```"#P`2+C9C^__^%R70)QP`2````@\`$ +XMBY60_O__A=)T"<<`,P```(/`!,<`_____XU%P(E$)`2+1?")!"3H8S8``(7` +XM#X4@____A?8/A(H```"-G:3^__^)="0,QT0D"!29"`C'1"0$``$``(D<).@% +XM:___B=F)7=2+`8/!!(V0__[^_O?0(<*!XH"`@(!TZ??"@(```'4&P>H0@\$" +XM`-*-1=2#V0.)1>0IV8U%Y(U5P(E-W,=%P`````#'1<@`````B57HQT0D"``` +XM``")1"0$BT7PB00DZ,DK``"+A:#^__^%P`^%M`(``(M5\/:"(`(```$/A(D" +XM``"+@A@"``"-!$#!X`(#0A"+0#B)0C2+5?#V@F`!```!#X19`@``BX)8`0`` +XMC01`P>`"`T(0BT`XB4(XBX6@_O__A<`/A/;]__^+5?"+C83^__^#_W*+=1"- +XM'(X/A`(#``#V@FP$```!#X0G`@``BX)D!```C01`P>`"`T(0BT`X@\`!T>B) +XM@H0```"+10B+@`P!``"%P`^$^P(``(N%G/[__X7`=!V+E9S^__^)5"0$BT7P +XMB00DZ)'.`0"%P`^%KOW__XLSA?9T;(M5\(M"((7`=#V+0`B#ZP2)!"3HOVS_ +XM_X/``8D$).AD:___A<")PHD##X3.`P``BT7PBT`@BT`(B10DB40D!.CC;/__ +XMBU7PB5HHB5HDBT7P@8BL!````"```(/_3\__^-1>R)%"2-7:2)1"0(QT0D!`,```#H^@@``(M5[,<$)`$```") +XM5"0(B40D!.B78?__ZQ2#^`QT2XM%\(D$)(M5"/^29`@``,=$)`P`````QT0D +XM"`````")7"0$BT7PB00DZ.[5__^%P`^%2_K__XM%K(/X!'0-@^@!=;V+1;2# +XM^`AUL(M5\.D-_?__BT(DA564XM`'(G3BU`XA=)T'P^V2A`Q]HG0 +XM.L9D`^V2!`YV7,.B<*+`H7`=?!;B=!>7<.)UCG9=`*)\%N)PEZ)T%W# +XMC78`C;PG`````%6)Y593@^P@BT4,BW40@_@!=%US"^CZ8?__C;8`````@_@" +XM=`LQTH/$((G06UY=PXM5",=$)`0"````B10DZ&W=__^%P'10BU4(BT(WKO(VT)@````"+50B+0AR+6#B%VW2H +XMC78`BT,(.?!R"'0\@^@!B4,(BQN%VW7KZXZ-1?2)1"0$BT4(B00DZ*?=__^Z +XM`0```(7`#X5Q____@WWT`76+C70F`.E@____@$L1`8M%"(E<)`2)!"3HB.[_ +XM_^NUC;8`````58GE5U93@^P,BW4,BWT(@_Y@#X2(````B?*)^.BO_O__A<") +XMPW0/#[9($`^VP3GP#X1Z````QP0D%````.BR9?__A<")P@^$S0```(7;#X2? +XM````BP.%P(D"=`6+`XE0!(D3B5H$BTT0B=.+`8E""(M!!(E"#(GPB$(0BTT4 +XM,<"%R74/B$,1,=*#Q`R)T%M>7UW#B=.X`@```.OHC70F`&:^)P#I;____XVT +XM)@````"+112%P'4I#[9#$3'2@^`#@_@"=,2+51"+`HE#"(M"!(A+$(E###'` +XMZZJ-M@````"+51"+`HE#"(M"!(A+$(E##.NBBT\6#["B)7?2+70R)=?B)??R#^V!T;8M%"(G:Z&_] +XM__^%P(G&=`X/MD`0#[;X.=^(1?-T4X#[_P^$XP```(M5"`^VPXT$0(V$`%`! +XM```#0A"#P`B)1"0,QT0D"(":"`B+10B+512)!"2)5"0$Z,X-``"X`0```(M= +XM](MU^(M]_(GL7<.S)^N/]D81`70R@'WS_P^$G0```(M5"(T$?XV$`%`!```# +XM0A"#P`B)1"0,QT0D")B:"`CKIXVT)@````"+1@B#^`%U!XM>#(7;=$"+50B) +XM1"0$B10DZ++:__^%P'4J@'WS_W1ABU4(C01_C80`4`$```-"$(/`"(E$)`S' +XM1"0(O)H(".E4____BT8(BU40B0*+1@R)0@0QP.E6____BT4(B5PD!(D$).@` +XMR?__Z1____^+10B)?"0$B00DZ.S(___I8O___XM%"(E\)`2)!"3HV,C__^NA +XMC;8`````58GE4X/L!(M=#(M3.(72=""+"H7)=`:+0@2)002+0@2)"(D4).C* +XM8___BU,XA=)UX(/$!#'`6UW#D)"0D)"0D%6)Y8M%"(M`:(7`=`F)10B+2`1= +XM_^%=PY"-M"8`````58GE5U93@^PLBW40QP8`````BU4,#[8"A,!T00^^P(7` +XM>$N+'?P@"0@YV'U!BPT((0D(]D2!-@1U&^LRC70F``^^P(7`>"`Y4'0/A`X!``"+1>`Q]HD$).AZ8O__BU4(@47<``$``(72#X5;____BU7< +XMB10DZ+UA__^%P'5*QT7@3XT(".D<____BT7#I +XM-____XM=X(G7.?,/@T?___\\_W0]BU4(#[;`C01`C80`4`$```-"$(/`"#G> +XM#[80#Y?!A-)U0`^V1P&#QP&$P`^$%?___X3)#X0-____//]UPXM%",=$)`3_ +XM____B00DZ(+&__\YW@^7P0^V$(32=,:-M@````"$R72\B!,/ME`!@\,!.=X/ +XME\&#P`&$TG7GZZ6!H%0(``#__O__,?;I[O[__XE$)`R-0WB+50B)1"0(BT-T +XMB10DB40D!.C7?@``A<`/A.K^__^)0W3I5?[__XM5X#'VB10DZ"YA___IK_[_ +XM_\8#`.GP_?__C;8`````C;PG`````%6)Y8/L.(E=^(M=#(EU_(MU$`^^`X/X +XM?W<*]@2%W10)"`1U'(7V=`J)'"3HE&'__XD&B=B+=?R+7?B)[%W#B?8/OD,! +XM@_A_=]OV!(7=%`D(!'31#[Y#`H/X?W?(]@2%W10)"`1TOH![`WQUN(U%](E% +XMY,=%Z`0```")'"3H\UC__XE%](M%"(7`=%6+50B+0A"%P'1+BU!HA=)T1(U% +XM[(E$)`B-1>3'1"0,`````(E$)`2)%"3_4@R%P'4DBU7PA=)T'87V=`6-0O^) +XM!HM%[,9$`O\`BUWLZ5;___^-="8`@\,$Z3S___^0C;0F`````%6)Y8/L"(M% +XM#(M-"(M5$(/X!78,Z*M:__^-M"8`````_R2%')T("(E5$,=%#,2<"`B)30C) +XMZ=;^__^)51#'10SJF@@(B4T(R>G#_O__B540QT4,9)P("(E-",GIL/[__XE5 +XM$,=%#(2<"`B)30C)Z9W^__^)51#'10S]F@@(B4T(R>F*_O__B540QT4,&YL( +XM"(E-",GI=_[__XVT)@````!5B>575E.#["R+10B+<""+1@B)!"3H&F#__XM= +XM"(7;B47H#X3M````BU4(BUH0A=L/A-\```#V@U4(```!#X72````C02%@``` +XM`#M#>`^'9`4``(M+=(E-X(M#>(E%[(&+5`@````!``"+10B+<""+5@B+?>`/ +XMM@*$P`^$Y@```(G6ZU>+50@/ML"-!$`!P`-"$`^VF%T!``")7>@/M@8\_W1= +XMBU4(#[;`C01`C80`4`$```-"$(/`"(D\)(E<)`B)1"0$Z$M>__\/MD8!@\8! +XM`WWHA,`/A(L````\_W6EQT0D!/____^+30B)#"3H;L7__XG#B5WH#[8&//]U +XMI8GVQT0D!/____^+30B)#"3H3`"`T$0BT`XA<`/E<"$P`^%"0(``,8".HUR +XM`L9"`2#V11`!#X0K`0``C47PB40D!(M%"(D$).BMT___A<`/A0D!``"+1?"% +XMP`^%C0(``(U5Z(E4)`C'1"0$CYL("(M-"(D,).B0^___BU7HB30DB50D"(E$ +XM)`3H(5S__XGP`T7HZ0B)%"2)3"0(QT0D!%F;"`CH7/O__XG"Z1O_ +XM__^-5>B)5"0(QT0D!$B;"`B+30B)#"3H._O__XM5Z(D<)(E4)`B)1"0$Z,Q; +XM__^)V`-%Z,8`+(U8`L9``2"+50B+0ASV0%@$#X2S_O__ZY2+=>"+30B)#"3H +XM*34!`(M%"(M0$(M%Z(ET)`C'1"0$!````(E$)`R+30B)#"3_DI0(``"+10B% +XMP'06BU4(BT(0AB)1"0(QT0D!+J;"`B+50B)%"3HBOK__XM-#(DT)(E,)`B)1"0$Z)M<__^) +XM-"3H,US__XT$!HU(`<8`"HG(*T7@]D40`HE%Z`^$3?___XM5"(MR.#GP#X8_ +XM____BU7@C5[].?IR+#G7=#>-C&0@$@C5H"B0PDB40D",=$)`1UFP@(Z'CY__^+5>B)'"2)5"0(B40D!.@) +XM6O__B=H#5>CI2?W__X/@[V:)01B-3>B)3"0(QT0D!#N;"`B+10B)!"3H.OG_ +XM_XM5Z(D<)(E4)`B)1"0$Z,M9__^)V@-5Z.G[_/__C47HB40D",=$)`2>FP@( +XMBU4(B10DZ`/Y__\QTHE$)`2+3?!K70QDB4PD#(G8]_&)1"00BTT,B30DB4PD +XM".C_6O__B30DZ)=:__^-!`;I7_[__X&@5`@``/_^__^#Q"Q;7E]=PXE$)`R- +XM0WB)1"0(BT-TB40D!(M5"(D4).@\=P``A<`/A.C]__^)0W3I;_K__XVV```` +XM`(V_`````%6)Y5=64X/L/(MU"/:&K@0```0/A;"`C'1"0$&0```(E$)`SH-%;__XU5[(E%U`'#B47L,<")5"0(@WR^7`&) +XM-"0/E<"+!(50G0@(B40D!.AD]___BU7LB1PDB50D"(E$)`3H]5?__XM%[(U5 +XM[`'#B47@Q@,@BP2]6)T("(/#`8E4)`B)-"2)1"0$Z"GW__^+5>R)'"2)5"0( +XMB40D!.BZ5___BT7LBU7@`<.-1!`!`T78`T74B478,<#'1+Y<`````(/'`8/_ +XM!P^%'?___\8#"HDT).@0,0$`BT78BU80@\`!B40D#(M%W,=$)`0$````B30D +XMB40D"/^2E`@``(7V=`^+1A"%P'0(BU7<.5!T=&B+1=R)!"3HL5?__X/$/%M> +XM7UW#BX8@`P``C01`P>`"`T80BT@XZ3'^__\PP,=$AEP`````@\`!@_@'=?"# +XMQ#Q;7E]=PX%[>+P"``!V)XM#=(E%W(M#>(E%\(&+5`@````!``#I8?[__X&@ +XM5`@``/_^___KEXU#>,=$)`R]`@``B40D"(M#=(DT)(E$)`3HMG0``(7`#X1Q +XM____B4-TZZZ)]HV\)P````!5B>575E.#[#R+?0B%_P^$9`0``(M%"(-]#`:+ +XM0!")1=AV!>B,4?__BU4,_R25-)T(",=%#`,```"A*"$)"(/``:,H(0D(@^@! +XM=$:#Q#Q;7E]=PXM%"/:`,`0```$/A#@$``"+@"@$``"+5=B-!$"+3((XA+1>R- +XM'`8[7?!W'(!]UP"--`$`0`` +XMBU-TB57@BT-XB47P@8M4"`````$``(-]#`4/A`L!``"#?0P##X7R_O__BWW@ +XM,?;&1=<`BT4(A<`/A.?^__^+1=B%P`^$W/[__XM%V(N0!`$``(72#X3+_O__ +XM#[8"A,`/A$P!``")T^M5C78`BU4(#[;`C01`C80`4`$```-"$(/`"(E$)`S' +XM1"0(GZT("(M%\(D\)"GPB40D!.B!4O__`<8[=?")1>P/A^_^__\!QP^V0P&# +XMPP&$P`^$\P```#S_=:K'1"0$_____XM%"(D$).B7N?__ZZN0C70F`(M%W,=% +XM\`````#'1>``````A<`/A"'___^+1=R-5?")5"0(QT0D!`````")1"0,BT4( +XMB00DZ`9R``"%P`^$A@$``(-]#`6)1>`/A?7^__^-1>R)1"0(QT0D!,R;"`B+ +XM10B)!"3H-_/__XM5[#E5\`^"2_[__XE4)`B)1"0$BU7@B10DZ+Q3__^+=>R+ +XM?>#&1=(E4)`R)1"0(BT-TB40D +XM!(M%"(D$).A[<0``A<`/A/L```")0W3I3_[__XM5V(N""`$``,=$)`C8FP@( +XMB40D#(M%\(D\)"GPB40D!.A)4?__`<8[=?")1>P/A[?]__\!Q^DY_?__Z(]0 +XM__^+`(D$).CE3?__QT0D")VM"`B)1"0,BT7PB30D*=B)1"0$Z`A1__\!PSM= +XM\(E%[`^'=OW__P'&@\,!.UWPQT4,`P````^'8?W__\8&"HM]"(7_=`N+10B) +XM!"3H7"P!`(MUV(7V#X3Y````B5PD#(M5X(E4)`B+10R)1"0$BU4(B10DBT78 +XM_Y"4"```BTT(A`Y4'0/A.````"+1>")!"3H[%+_ +XM_\<%*"$)"`````"#Q#Q;7E]=PXM%"/:`K`0```(/A.C[___V@#`$```!=6Z+ +XM10B+F"@$``"%VP^4P(3`#X3)^___BU78@XI4"````NG3^___@WT,`G0P@WT, +XM!L=%V``````/A:K[___'10P$````Z9[[__^+10B+D"@$``"%T@^4P.G*^___ +XMQT4,`P```,=%V`````#I>/O__XN`*`0``(M5V(T$0(MT@CB%]@^4P.N)BU7@ +XMH1`A"0B)7"0(QT0D!/*8"`B)5"0,B00DZ&Q*___I`____X&@5`@``/_^___I +XM'/___XUT)@!5B>6#[#B)=?B+=1")??R+?0B)7?2%]G1IZ-9.__^+&(U%\(ET +XM)`2)1"0(B3PDZ#WN__^)QNBZ3O__B1B+112)="0,B3PDB40D"(M%#(E$)`3H +XMFOK__XM%\(7`=!B%_W0,BT<0A"-1>C'1>0$````QT7P`0```(E$)`B- +XM1>#'1"0,`````(E$)`2)'"3_4PR%P'4*@WWL$@^$`P$``(D<)/]3!*'L$`D( +XMA<`/A+L```#'!>P0"0@`````N`$```"!Q#P$``!;7E]=PZ'L$`D(A7UW#QP0DWYL(".@H2?__ABX\)L("+D2````_(G'\Z8/A>7^ +XM__^+10C'!>P0"0@`````BU`0BT)HA575C'V4X/L#(M]"(G[ZQ*#QA"#PPR!_O`$```/A+P```"#OFBC +XM"`@#=>7VAFRC"`@!==P/MI,``0``@^(!#X2B````BX/X````C01`P>`"`T<0 +XMBT`XA<`/E<"$P'0LA-(/A*0```"+@_@```"-!$#!X`(#1Q"+0#B)!"3HX4[_ +XM_P^VDP`!``"#X@&$TG1GBX/X````C01`P>`"`T<0BT@\A7UW#BX/X````A<`/E<#I9?___XN#_````(7`#Y7`ZZ.+@_P` +XM``#KN8N#^````.EC____D(VT)@````!5B>6#[!B+10S'1"0,=)T(",=$)`0# +XM````B40D"(M%"(D$).@8_/__R<.-M@````!5B>53@^P4BTT,BUT(C01)C02# +XM]H```0```70TBX#X````C01`P>`"`T,0BU`XA=)T!S'`@#H`=0R+51"X`0`` +XM`(72=!.#Q!1;7<.0C70F`(N0^````.O6P>$$BX%@HP@(B1PDQT0D#+"="`C' +XM1"0$`P```(E$)`CHD_O__X/$%+@!````6UW#D(VT)@````!5B>6#[%B)7?2+ +XM70B-1>R)=?B)??S'1"000%<%"(E=[,=$)`P(````QT0D""8```#'1"0$8*@( +XM"(D$).AD2___AQ=PXU%W(E=W,=$ +XM)!`@5P4(QT0D#!````#'1"0(3P```,=$)`1@HP@(B00DZ!I+__^%P'7!B1PD +XMZ)Y-__^+-6"C"`B%]HE%R'19#[8#QT708*,(",=%Q`````"(1<_K%(VT)@`` +XM``"#1=`0BT70BS"%]G0G#[9%SS@&?.M_'8M%R(G?_#G`B<'SIG7;BTW$A`"`T80BU`XBP.)5"0,QT0D!':?"`B)-"2)1"0(Z/XD +XM`0")PNGZ_O__C;0F`````(N`^````(T$0,'@`@-&$(M`.(7`#Y3`ZY:-M"8` +XM````BX#X````C01`P>`"`T80BT`XZ3+___^+@/@```"-!$#!X`(#1A"+0#B% +XMP`^5P.G/_O__C01)BY2&^````.EV____C;0F`````(V\)P````!5B>575E.! +XM[,P"``"+10B+2#C'A53]__\*````C70F`#'2B#'A43]__\`````QX50_?__`````,>%7/W__P````"#Z@*)E3S]__^) +XMC3C]__^+E5S]__\/MH)LHP@(J`0/A1`!``")U\'_!(-]#`)T%8-]#`,/A&(" +XM``"#?0P!=%'H7$3__Z@!=4B+C5S]__^+@6BC"`B#^`(/A\\#``"+50B-!'^- +XM!(+V@``!```!#X2=!```BX#X````C01`P>`"`T(0BU`XBT`\.<(/A*0```"+ +XM50B-!'^--(*-AO`````/ME@0@^/]B%@0BXU<_?__BX%@HP@(B00DZ/-)__^+ +XME5S]__^)A4S]__^+@FBC"`B#^`(/A'D"```/@]8!``"#XP$/A%H"``"+AO@` +XM``"+30B-!$#!X`(#01"+0#B%P`^4P(3`=`>#A4S]__\"BX4\_?__.85,_?__ +XM#X\(`@``BY50_?__B;R5:/W__X/"`8F54/W__XN57/W__XN"<*,("(/"$(F5 +XM7/W__X7`#X6^_O__BY50_?__A=(/CNX```"+C5#]__\YC53]__\/C#L#``#' +XMA5C]__\!````QX5`_?__`````,>%8/W__P````"+A53]__^%P'Y[BX58_?__ +XM,?8QVXN50/W__XT\$.LXBX5(_?__@\8!BTT(QT0D#$^-"`C'1"0$?I\(""G0 +XMB40D"(D,).@D(@$``YU8_?__.[54_?__="Z+E4#]__^-!!.+E(5H_?__BT4( +XMP>($@<)@HP@(Z,7[__^)PHT$'SF%4/W__W^:@X5@_?__`8N%8/W__SF%6/W_ +XM_P^/'0,``(.]1/W__P`/A+(!``"+50C'1"0$)KH("(D4).@?(0$`BX5$_?__ +XM,=N-M:3^__^%P`^.B0$``(L4GH/#`8M%",'B!('"8*,(".A2^___.YU$_?__ +XM#X1F`0``BTT(QT0D!":Z"`B)#"3HTR`!`.O(BTT(C01_]H2!``$```(/A(7^ +XM___IW/W__X/X`P^%3_[__XG:@^(!#X1"`0``BTT(C01_BX2!^````(T$0,'@ +XM`@-!$(M8.(7;#Y7`A,!T(X32#X7O`0``BTT(C01_BX2!^````(D$).BI1___ +XM`85,_?__@X5,_?__`XN%//W__SF%3/W__P^.^/W__XN-1/W__XF\C:3^__^# +XMP0&)C43]___I\_W__XNV^````(7V#Y3`Z;#]__^#XP$/A,<```"+AO@```"+ +XM50B-!$#!X`(#0A"+0#B-3>")#"2)1"0,QT0D"+.@"`C'1"0$%````.@"1/__ +XMC4W@BP&#P02-D/_^_O[WT"'"@>*`@("`=.GWPH"````/A"(!````TH/9`RN- +XM./W__P&-3/W__^E"_?__@\`&,=*#X/J)A4C]__^)R/>U2/W__XF%5/W__^GA +XM^___D(M%",=$)`0FN@@(B00DZ&T?`0"!Q,P"``!;7E]=PXM-"(T$?XN,@?@` +XM``"%R0^5P.G%_O__BX;X````Z4/___^#^`,/A5O\__^+30B-!'^-!($/MH@` +XM`0``@^$!#X2Q````BX#X````BU4(C01`P>`"`T(0BU`XBT`\.<(/A,;\__^$ +XMR0^%JP```(M5"(T$?XT$@HN0_````(72#X0#_/__BX#X````B50D!(D$).BQ +XM0O__A<`/A(W\___IY/O__XN54/W__XG0P?H?][U4_?__@_H!@]C_A<")A5C] +XM__\/CZK\___I=_W__\'J$(/!`NG3_O__BU4(C01_BX2"^````(T$0,'@`@-" +XM$(M`..D`_O__BY#X````BX#\````Z5;___^+D/@```"+@/P```#I9_O__XM- +XM"(T$?XN$@?@```"-!$#!X`(#01"+4#R%T@^$3OO__XM`..E)____BU4(QT0D +XM!":Z"`B)%"3H#QX!`(N-8/W__XF-0/W__^DA_/__C;0F`````(V\)P````!5 +XMB>6#[!B+10R)??R+?0B)7?2)=?B+=1"-!$#!X`*-%#CV@@`!```!C9P'^``` +XM`'06BX+X````C01`C02%,`````-'$(U8"/?&"````'5Q]\8!````=#[WQ@P` +XM```/A)T```"#Y@)U&(M#!(7`C78`=`Z)!"3H"D3__XVV`````(M5%#'`B5,$ +XMBUWTBW7XBWW\B>Q=P_?&#````'18@^8"=0Z+`X7`=`B)!"3HU$/__XM5%#'` +XMB1/KSXVT)@````"+112)!"3H*3W__X7`B444#X5Y____QT0D"`````#'1"0$ +XM!0```(D\).B"[/__N`$```#KDXM%&(D#,<#KBHGVBT48B4,$,<#I>____XUV +XM`%6)Y57VAVRC"`@!==R+1?"%P`^%'`$``/:#``$```$/A`$!``"+@_@```"+50R- +XM!$#!X`(#0A"+0#B%P`^$\@```(M5#,=$)!``````B40D#,=$)`@*````B70D +XM!(D4).@T_O__A<`/A2H!```/MI,``0``@^(!#X0*`0``BX/X````BTT,C01` +XMP>`"`T$0BT`\A<`/E<"$P`^$2O___X32#X0<`0``BX/X````BU4,C01`P>`" +XM`T(0BT`\BTT,QT0D$`````")1"0,QT0D"`L```")="0$B0PDZ+K]__^%P`^$ +XM`O___XM%"(/&`8/'$,=$)`@`````@\,,QT0D!`4```")!"3H_NK__X/^3\=% +XM\`$````/A>#^__^+1?"#Q!Q;7E]=PXN#^````(7`#X4.____BTT,QT0D$``` +XM``#'1"0,`````,=$)`@&````B70D!(D,).@^_?__BT4,QT0D$`````#'1"0, +XM`````,=$)`@'````B70D!(D$).@7_?__Z6+^__^+@_P```"%P`^5P.D`____ +XMBTT,QT0D$`````#'1"0,`````,=$)`@'````B70D!(D,).C;_/__Z23___^+ +XM@_P```#I[O[__XUT)@"-O"<`````58GE5U93@^Q\Z8/A&4YV9`/A%H(``"`^CW'1<0!````QT7(`````'0.QT7$```` +XM`,=%R`$```"%R<=%[`````#'1=``````=`G&`0"#P0&)3=")'"3H]O+__X7` +XMB<P/MD<, +XMA=(/E<&H(`^%`0(``*@0#X57`@``BU7$A=(/A3H%``"+5R%P`^%#`,``(M%R(7`#X1V`0``BT6X +XMA_O__]D<,`G5@BTT(C01;C02!#[:0``$``(/B`0^$ +XM&00``(N`^````(T$0,'@`@-!$(MP.(7V#Y7`A,!T+(32#X6)!```BTT(C01; +XMBX2!^````(M5T(D$)(E4)`3HPSO__X7`#X33_O__BT<$A/[__X3)#X3W_?__QT0D#-"= +XM"`B+10B)="0(QT0D!`,```")!"3HY>O__\=%S`$```#I1?[__X![`6\/A8C^ +XM__^-P!````B30DZ#WP__^%P(G'#X5'_?__Z6?^__^%T@^%H?W__\=$ +XM)`P`G@@(Z9,!``"+1<2%P`^$?_[__XM5T`^^`H/X?P^'GP```/8$A=T4"0@$ +XM#X21````C47@C4WPQT0D#`H```")1"0(B50D!(D,).CS6```B46\@^@!#X25 +XM`P``BU4(C47HB70D!(E$)`B)%"3HH=G__XM5"(U-Y(E,)`B)%"2)PXM%T(E$ +XM)`3HAMG__X-]O`&)Q@^#-P4``(M-"(E$)!")7"0,QT0D")"?"`C'1"0$!0`` +XM`(D,).C7Y?__ZUN0C70F`(M5"(U%Z(ET)`2)1"0(B10DZ#K9__^+50B-3>2) +XM3"0(B10DB<.+1=")1"0$Z!_9__^+30B)7"0,QT0D"*B>"`C'1"0$`P```(D, +XM)(G&B40D$.AZY?__BT7HA2%VP^$/O[__XM-"(7)=!.+30B+01"%P'0).W!T#X1#!``` +XMB30DZ#@\___'1`/M@"$P'0G#[[0A=(/B+W\__\[%?P@ +XM"0@/C;'\__^A""$)"/9$D#8"#X2A_/__#[9'#*A`=`N+5?"%T@^$VP$``*@" +XM=3&+50B-!%N-!(+V@``!```!#X3.`0``BX#X````C01`P>`"`T(0BT`X.T7P +XM#X2E^?__BT<$ASIM/S__XNP^````(7V#Y3`Z6O\__^!H%0( +XM``#__O__Z9C[__^!H%0(``#__O__QT7,`0```.E/^/__BY#X````A=(/E<#I +XM-OS__X-]O`)T$H-]O`,/A3G[__^-=@#ID?C__XE$)!"+10B)7"0,QT0D"("> +XM"`C'1"0$`P```(D$).B(X/__Z0G[___'1"0,U)X(".F*^?__BX#X````Z3G^ +XM__^+10C'1"00`0```,=$)`P`````QT0D"`````")7"0$B00DZ-3R___IN_?_ +XM_^L-D)"0D)"0D)"0D)"0D%6)Y8'L6`0``(EU^(MU"(U%V(E=](V=R/O__XE% +XMZ(U%R(E]_(G?B5W8QT7(`````,=%T`````#'1>``````B47LQT0D$`,```#' +XM1"0,`````,=$)`@`````QT0D!#\```")-"3H5_+__X7`=3.`CO0#```!QT0D +XM$`$```#'1"0,`````,=$)`@`````QT0D!!@```")-"3H)/+__X7`=$#!XP2+ +XM@V"C"`C'1"0(2)\(",=$)`0#````B30DB40D#.AKW___N@$```"+7?2)T(MU +XM^(M]_(GL7<.-M"8`````@(X@`@```<=$)!``````QT0D#`````#'1"0(```` +XM`,=$)`0(````B30DZ+'Q__^%P'6-@(Y@`0```<=$)!`"````QT0D#`````#' +XM1"0(`````,=$)`0S````B30DZ'[Q__^%P`^%5O___X".9`,```''!"2GGP@( +XMZ-*`@("`=.GWPH"```!U!L'J$(/!`@#2NPH```"#V0,I +XM^8U5Z(E-X,=$)`@`````B50D!(DT).BL\___A<`/A43^__^!_]*?"`B)^W0E +XMQX7(^___97-C8<>%S/O__W!E=&G'A=#[__]M93TVQH74^___`(G9BP&#P02- +XMD/_^_O[WT"'"@>*`@("`=.GWPH"```!U!L'J$(/!`@#2@]D#*?F-1>B)3>#' +XM1"0(`````(E$)`2)-"3H+?/__X7`=!2[#````.F__?__N"'5"`CI>O[__X'_ +XMWY\("'0=QX7(^___:V5Y=,>%S/O__VEM93UFQX70^___-@")^8L!@\$$C9#_ +XM_O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TH/9`RG9C57HB4W@QT0D +XM"`````")5"0$B30DZ*CR__^%P'04NQ8```#I.OW__[B_GP@(Z7O^__^!^^F? +XM"`AT'L>%R/O__VUA=&/'A*`@("`=.GWPH"```!U!L'J$(/!`@#2@]D#*=F-1>B)3>#'1"0( +XM`````(E$)`2)-"3H(O+__X7`=`J['0```.FT_/__QT0D#/6?"`C'1"0(#*`( +XM",=$)`0`!```B1PDZ,@P__^)V8L!@\$$C9#__O[^]]`APH'B@("`@'3I]\*` +XM@```=0;!ZA"#P0(`TH/9`RG9C57HB4W@QT0D"`````")5"0$B30DZ*SQ__^% +XMP'0*NR````#I/OS__X'[%J`("(G?=!O'A%S/O__V=R87#'A=#[__]H% +XMV/O__U!14%#'A=S[__\@3$EPQX7@^___<&QP:<>%Y/O__W!B<`")V8L!@\$$ +XMC9#__O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TKLF````@]D#*?F- +XM5>B)3>#'1"0(`````(E4)`2)-"3HA/#__X7`#X4<^___QT0D#$^-"`C'1"0( +XML)\(",=$)`0`!```B3PDZ#`O__^)^8L!@\$$C9#__O[^]]`APH'B@("`@'3I +XM]\*`@```=0;!ZA"#P0(`TKLG````@]D#*?F-1>B)3>#'1"0(`````(E$)`2) +XM-"3H#_#__X7`#X6G^O__QT0D#!^@"`C'1"0(,Z`(",=$)`0`!```B3PDZ+LN +XM__^)^8L!@\$$C9#__O[^]]`APH'B@("`@'3I]\*`@```=0;!ZA"#P0(`TKLK +XM````@]D#*?F-5>B)3>#'1"0(`````(E4)`2)-"3HFN___X7`#X4R^O__@?\] +XMH`@(B?MT.\>%R/O__W-E8W3'A%U/O__TA( +XM($C'A=C[__]5;FAS9L>%W/O__V@`B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!T +XMZ??"@(```'4&P>H0@\$"`-*#V0,I^8U%Z(E-X,=$)`@`````B40D!(DT).@% +XM[___A%S/O__VQM973'A=#[__]A/7Y[QX74^___6RH_),>% +XMV/O__V`G(ES&A=S[__\`C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2@]D#*=F-1>B)3>#'1"0(`````(E$)`2)-"3HS.W_ +XM_X7`=`J[-0```.E>^/__@?M_H`@(="7'A% +XMT/O__W1H/3C&A=3[__\`B=F+`8/!!(V0__[^_O?0(<*!XH"`@(!TZ??"@(`` +XM`'4&P>H0@\$"`-*[-@```(/9`RN-O/O__XU5Z,=$)`@`````B4W@B50D!(DT +XM).A`[?__A<`/A=CW__^!O;S[__^,H`@(="?'A%T/O__VQL/3%FQX74^___-@"-CH0@\$"`-*[.0```(/9`RN-O/O__XU%Z,=$)`@````` +XMB4W@B40D!(DT).BP[/__A<`/A4CW__^!O;S[__^:H`@(=!W'A")5"0$B30DZ"KL__^%P`^%PO;__XV%R/O__\=$)`Q@P0@(QT0D"*2@"`C' +XM1"0$``0``(D$).C0*O__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2NSX```"#V0,KC;S[__^-5>C'1"0(`````(E-X(E4 +XM)`2)-"3HI^O__X7`#X4_]O__]H8@`@```0^$QP$``(N&&`(``(T$0,'@`@-& +XM$(M`.(/H`='HA<")1?!U!\=%\`$```"+1?#'1"0(K*`(",=$)`0`!```B40D +XM#(V%R/O__XD$).@<*O__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("`=.GW +XMPH"```!U!L'J$(/!`@#2NS````"#V0,KC;S[__^-5>C'1"0(`````(E-X(E4 +XM)`2)-"3H\^K__X7`#X6+]?__BT80C57PB50D!(DT)/^08`@``+H!````A<`/ +XMA97U__^+1?`]6`(```^'U````,=%\`@```"+1?#'1"0(MZ`(",=$)`0`!``` +XMB40D#(V%R/O__XD$).AE*?__C8W(^___BP&#P02-D/_^_O[WT"'"@>*`@("` +XM=.GWPH"```!U!L'J$(/!`@#2NTD```"#V0,KC;S[__^-5>C'1"0(`````(E- +XMX(E4)`2)-"3H/.K__X7`#X74]/__H6"C"`B%P`^$L`$``(GS,?^)^,'@!(F% +XMP/O__XN`:*,("(/X`0^$9`$```^"L0```(/X`@^$`@$``(/X`XVT)@````!T +XM,^C-)?__/;`$``"-="8`#X>\````QT7P$````(UV`.D5____BX88`@``@^@! +XMT>CI0/[__P^VDP`!``"#X@$/A(````"+@_@```"-!$#!X`(#1A"+0#B%P`^5 +XMP(3`=#Z$TG19BX/X````C01`P>`"`T80BT`XQT0D$`````")1"0,QT0D"`L` +XM``")?"0$B30DZ!KF__^%P`^%\O/__XN%P/O__X/##(N`<*,("(7`#X3$```` +XM@\O___S'2Z:3R__^+&^ES\O__ +XMC78`58GE5U93@^PLBQ5@HP@(BWT,A=(/A)L"``#'1?``````Z8(```"+3>2- +XM!$F+30B-!('V@``!```!#X1>`@``BX#X````C01`P>`"`T$0BT`XA<`/E<"$ +XMP`^$%@(``(E4)`C'1"0$PJ`("(D\).CR(/__H:`4"0B%P`^%<0$```^_1PS! +XMZ`:#X`&$P`^%=`$``(M-\(N1<*,("(/!$(E-\(72#X0-`@``BT7P]H!LHP@( +XM"'7=BTWPP?@$B47DBX%HHP@(@_@"#X1D`0``#X)4____@_@#=9N+5>2+30B- +XM!%*-!('V@``!```!#X2=`0``BX#X````C01`P>`"`T$0BT`XA<`/E,"$P`^% +XM8____XE\)`S'1"0(!````,=$)`0!````QP0DXJ`(".AU)O__BU7PBX)@HP@( +XM#[8PB?&$R0^$L`$```^^V8E%[.MTC78`H0@A"0CV1)@V`G1QH:`4"0B%P`^% +XM=P$``(M'"(/H`87`B4<(#XC4`@``BP?&`%R#P`&)!Z&@%`D(A(&(/``8D'BTWL#[9Q`8/!`8E-[(GPA,`/A#2-!$F+30B-!('V@``!```!=&B+ +XM@/@```"-!$#!X`(#01"+0#B)1"0,B50D",=$)`34H`@(B3PDZ/4>___I_OW_ +XM_XE4)`C'1"0$RJ`("(D\).C<'O__Z>7]__^+@/@```"%P`^4P.EJ_O__BX#X +XM````A<`/E<#IJ?W__XN`^````.NB@\0L,CK;8GVH0@A"0CV1)@V`G1KBPV@%`D(A+%:`4"0B%TG5)BT<(@^@!A<")1PAX2HL' +XMB!B#P`&)!XM5Z`^V<@&#P@&)5>B)\83)=%T/OMF%VW@(.1W\(`D(?XF)\8#Y +XM7'2.BQ6@%`D(A=)TMXE\)`2)'"3H)\#P*D'6JB7PD!(D< +XM).@6)/__ZZ6)?"0$QP0D7````.A$'O__Z7#___^AH!0)"(7`=6>+1PB#Z`&% +XMP(E'"`^(G@```(L'Q@`*@\`!B0?I)/S__SM'&`^-(_W__XE\)`3'!"1<```` +XMZ+TC___I&/W__SM'&`^-%O___XE\)`3'!"1<````Z)\C___I"____XN`^``` +XM`.FT_O__B7PD!,<$)`H```#HOQW__^G(^___B7PD!,<$)#T```#HJAW__^E? +XM_O__.T<8#XU,_O__B7PD!,<$)#T```#H3"/__^E!_O__B7PD!,<$)`H```#H +XM-R/__XUV`.E]^___D)"0D)"0D)"0D)!5B>6+112+50B+`(7`=!&!HJP$``#_ +XM_]__,6+10B#B*P$```@,Q=PXN1&`(``(U"_^O+C012P>`"`T$0 +XMBT`X@^@!Z\>-M"8`````C;PG`````%6)Y5.#["2+70B-5?B+0Q")5"0$B1PD +XM_Y!@"```N@$```"%P'4+,-*!??C`$@``=P^#Q"2)T%M=PXVT)@````"+112) +XM1"0,BT40B40D"(M%#(D<)(E$)`3H$____X/$)%M=B<*)T,.)]HV\)P````!5 +XMB>53@^PDBUT(C57XBT,0B50D!(D<)/^08`@``+H!````A6#[!B+112+"(7)=2N+10C'1"00`````,=$ +XM)`P`````QT0D"`````#'1"0$0P```(D$).CFW/__R3'`PXGV58GE@^P8BT40 +XMB00DZ`,B__\QTJ@!=""+10C'1"0(F*D(",=$)`0#````B00DZ![*__^Z`0`` +XM`,F)T,.0C70F`%6)Y8/L&(M%$(D$).C#(?__,=*H`70@BT4(QT0D"-"I"`C' +XM1"0$`P```(D$).C>R?__N@$```#)B=##D(UT)@!5B>6#[!B+10C'1"0(#*H( +XM",=$)`0#````B00DZ*_)__\QP,G#C70F`(V\)P````!5B>6#["B)=?B+=12) +XM7?2+70B)??R+!H7`#X01`0``/?0!``!V,L=$)`ST`0``QT0D"&"J"`C'1"0$ +XM`P```(D<).A:R?__N`$```"+7?2+=?B+??R)[%W#B40D$,=$)`P`````QT0D +XM"`````#'1"0$&````(D<).BTV___BP:#^`$/A/D```"#Z`'1Z(F#A`````^V +XM@VP$``"#X`&)QP^%O````(N+9`0``(N#:`0``(G*.<$/A%L!``")^(3`=`R- +XM!%+!X`(#0Q"+4#B+!CG"#X8:`0``@^@!B40D$,=$)`P`````QT0D"`````#' +XM1"0$20```(D<).@SV___BP:#Z`&)1"00QT0D#`````#'1"0(`0```,=$)`1) +XM````B1PDZ`K;__\QP.D>____C78`QT0D#`$```#'1"0(-*H(",=$)`0#```` +XMB1PDZ%#(__^X`0```.GQ_O__C;8`````BY-D!```C012P>`"`T,0BT@XBT`\ +XMZ3C___^-M@`````/MH-L!```QX.$`````0```(/@`8G'=%^+DV0$``"-!%+! +XMX`(#0Q"+2#B+0#PYP70*B?B$P'50.Q9V-<=$)!`!````QT0D#`````#'1"0( +XM`````,=$)`1)````B1PDZ$W:___'1"00`0```.D6____,<#I5/[__XN+9`0` +XM`(N#:`0``(G*ZZ:-!%+!X`(#0Q"+4#CKHHL&Z;K^__^-="8`58GE@^P8BT44 +XMBP"#^!-V0#'2/?0!``!W!\F)T,.-=@#'1"0,]`$``,=$)`BXJ@@(QT0D!`,` +XM``"+10B)!"3H/53@^P$BUT( +XMB1PDZ*Z$__\QP(.+K`0``""#Q`1;76#[`B+ +XM11")1"0$BT4(B00DZ!C,__\QP,G#D)"0D%6)Y5=64X/L3(MU#(M]"(7V#X3I +XM`@``BU44BUX(@SH!#X1B`P``]D88`0^$G0```(M%'(7`=6*+312+`8/H`8M5 +XM&(/&"(E%\(/``3GSB0)U$.M-@T7P`8-'7`&+&SGS=#^+0Q")1"00BT,(B40D +XM#(M%\,=$)`0!````B3PDB40D".C*F/__A2)1"0,QT0D"`$```")5"0$B3PDZ`F1 +XM__^%P'6/A?\/A/,"``"+5Q"%THE5T`^$Y0(``/:"50@```$/A=@"``"+1>B+ +XM3=`#0Q"#P`$[07@/A[T#``"+3="+5="+272)3R!BE0(`````0`` +XMB4W4BT7HA`[`P^$\`(``(M5\(M#$(E$)!"+0PB)5"0( +XMQT0D!`$```")/"2)1"0,Z(66__^%P'3"NP$```"%_W03BT<0A#X1\ +XM`@``BT,0B40D$(M#"(E$)`R+1?#'1"0$`0```(D\)(E$)`CH8Y7__X7`=,7I +XME/S__XM%Z,=%[``````#0Q#'1<@`````QT74`````(/``0^$./W__XE$)`R- +XM1>R)1"0(QT0D!`````")/"3HNS8``(7`B47(B474#X4/_?__Z4+\__^!IE0( +XM``#__O__BU7`BT7$`T(0.T9X=V:+3G2)3R!CE0(`````0``B4W4 +XMZ:#]__\QP(-[$``/E<#I-_W__P^VA)`T!```Z9;^__^)1"0,C47LB40D"(M- +XMR(D\)(E,)`3H/38``(7`#X3/^___B47(B474Z5C]__^)1"0,C49XB40D"(M& +XM=(D\)(E$)`3H$#8``(7`#X2B^___B49TZ7#___^)1"0,B2)1"0$BT7(B00DZ,,6__^+5=B+3<@!5>0! +XMT8E-S.DS^___BTT8,=O'`0$```#'000`````Z33Z__^!H%0(``#__O__Z27Z +XM___'1"0$_P```(D\).C&>___Z>/\__^+5<2)5"0(BT7DB40D!(M-S(D,).A< +XM%O__BT7$`47,BU7PZ3/___^0D)"0D)"0D)"058GEBT4(5U93BT@0BU$(C7D( +XM.?IT"CG0=3N+$CG7=4"+41"-<1`Y\G1`BQHYWG1,BT($B4,$BT($.<9T.HD8 +XMBT$(B7H$B0(Y>0QT)HM!"(E0!(E1"%N)T%Y?7<.-="8`.=!U\3G0=/CKZS'2 +XMC70F`.OCB5$,Z]N)61#KPXM"!(E!%(L:Z["-=@"-O"<`````58GE5S'_5E.# +XM[`R+=0B+1@R#Z`&%P(E&#`^%'`$``(L6A=)T)(M>$(U#"#G"#X1&`0``BT8$ +XMB4($BTX$C4,(.<$/A$L!``")$8.FK`0``/._`0```(DT).B3P`$`B30DBN?C8;(````B00DZ.<3__^+AN`` +XM``"%P'6:ZZ"+1@2)0PR+7A"+3@2+%HU#"#G!#X6U_O__B5,(Z:_^__^-M@`` +XM``!5B>575E.#[`R+11"+=0B+?0S'``````#'1"0$L`0``,<$)`$```#H.!+_ +XM_X7`B<,/A%0"``"+11")&(M&!(/``87_B48$B4,(C4-XQT,,`0```(ES$,=# +XM+`(```")0WB)0WP/A.1H````@8NL!````(```(B#J````(N7P````#'` +XM@[^L``````^5P(72B8.L````="2+A\0```")5"0$B1PDB40D".C$+P``A<") +XM@\`````/A$8!``"+E]@```"+A\0```"%THF#Q````'0DBX?<````B50D!(D< +XM)(E$)`CHBB\``(7`B8/8````#X0,`0``BY?@````BX?<````A=*)@]P```!T +XM)(N'Y````(E4)`2)'"2)1"0(Z%`O``"%P(F#X`````^$T@```(N'Y````(F# +XMY````(N'[````(7`=$V--(4`````B30DZ&$2__^%P(F#Z````'1XBX?L```` +XMBY/H````B8/L````BX?P````B8/P````BX?H````B70D"(D4)(E$)`3H4Q+_ +XM_XE<)`2)/"3H0\___X7`=1^+AZP$``")7"0$B3PD@^`#"8.L!```Z(36``"% +XMP'1ZB1PDZ&C\__^X`0```(/$#%M>7UW#QT0D"`````#'1"0$!0```(D<).A3 +XMN___BY/H````A=(/A6+___^0C70F`,=$)`@`````QT0D!`4```")/"3H*+O_ +XM_^NFC;8`````QX.L`````````(E<)`2)/"3H"M8``(7`=8:)7"0$B3PDZ%J] +XM`0"%P`^%`/MDL!.,@/A`0!``"#[@$/A"`"```/OM`XP8E5V(M5X(G3=%*+5>") +XMT^LCC70F``^V"H/"`8@+@\,!@^X!#X35`0``#[8*#[[!.T78="B#_@%VW(#Y +XM7'77C4(!B47<#[9*`0^^P3M%V`^$2P$```^V"HM5W.N_B=Z#P@$K=>"+10R% +XMP'0%BT4,B1"+7>")]HM%$`^V51"+31")="0(@^`0@_@!&<"#XH"#X`2#P`*` +XM^@$9TH/A`??2"N!```0'59 +XMBT40QT0D$`````#'1"0,`````(/@$(/X`1G`@^`$@\`"B40D&(V'L````(E$ +XM)!2+A\0```")5"0$B3PDB40D".BT(`$`A7UW#C;0F`````(/$/#'`6UY?7<.#[@&# +XMP@+I*W7@Z5S^__^)^+("Z-3\__^X`0```.G3_O__BU7@Z4'^__^)]E6Z`@`` +XM`(GE5U93@^QLBT4@BW4(B40D"(M%'(E$)`2+11B)!"2+312)\.A1_?__A<`/ +XMA>````#V12`(#X3E````BU4,BP*)1>R+2@2#P0&)3<2+12"[9````#'_QT7` +XM`0```(/@$(E%K.M8D(UT)@"+AI0$``"-!$#!X`(#1A"+0#B%P`^4P(3`#X4N +XM`P``C47LB40D!(DT).BBA/__A<`/A<\"``"+1>R%P'1@@\`!OP$```")1>R# +XM;>P!QT7$`````(/K`8/[_P^$D0$``(7_=`Z+50R+`CM%[`^'OP(``(M5[(72 +XM=6B%_P^%L`(``/:&G`0```$/A7/___^+AI0$``"%P`^4P.EZ____]D4@$`^% +XMW@(``+L!````@\1LB=A;7E]=PXM5#(MZ!(7_#X6I`0``BQ*#^@$/A-`"``"- +XM0O^)1>SIFP$``(VV`````(U-Z(U%Y(E,)!")1"0,QT0D"`````")5"0$B30D +XMZ(Z!__^%P`^%^P$``(M%Z(V6L````(U-U,=%U`````#'1=@`````B47 +XM`0``BTW$QT6T`````(E-L(M%U(M5V(M-Z(E%R(/``8E5S(/2`#';@_H`B474 +XMB578#X[)````BT7LBTT0BU7(B0'V12`"#X7#`0``BT7H.<(/@K@!``"#^`&- +XM4/\9P/?0,=LAPHE1!.D:`0``BT80]H!4"```!`^%!0$``,=$)`P!````QT0D +XM"`````#'1"0$`````(DT).CP>/__A")1"00B50D#,=$)`@!````BT7DB40D!(M-O(D,).B2 +XM!___@_@!#X3O_O__A<`/A10!``"+1<2%P`^$MO[__X-]V``/C*S^__\/C\S^ +XM__^+3;`Y3=0/@IK^__^-M@````#IM?[__[L!````]D4@$(GV#X26_?__B30D +XMQT0D!`(```#H^OC__X/$;(G86UY?7575E.#[$R+12")1"0(BT4R)1"0,QT0D"`````")="0$BU4(B10DZ+E]__^%P`^$ +XM-0$``(M%T(7`#X7!````BTT(]H&R-??")?"00B50D#,=$)`@!````BTT,BP&)1"0$BT4(B00D +XMZ*)\__^%P'7#BU4,]D4@"(LR#X0=`0``BUH$A=L/A&K^__^#ZP'I8O[__XM5 +XM\(72=`2!P;````")3@`````B5W< +XMQT7@`````(E$)!"-1=R)1"0,QT0D"`$```"+1>R)#"2)1"0$Z.@#__^#^`%U +XM?8/&`3';Z:S^__^0C70F`(M%"(N`E`0``(7`#Y3`A,`/A(/^___V12`0#X05 +XM____BT4(N@$```#HH_7__^L-BT4(N@,```#HE/7__[L!````QT0D!`(```"+ +XM10B)!"3H3/7__X/$3(G86UY?7<.[`0```/9%(!!UV.G,_O__A<`/A+L```#V +XM12`0C;8`````#X3^````BU7(B40D!(E4)`B+30B)#"3HI!BT4,BU@$ +XM@\,!.UWP#X)&_?__@\8!,=N-5>R)?"00B50D#,=$)`@`````B70D!(M-"(D, +XM).@Y>___A<`/A!?]__^+10CV@)P$```!#X2N````B<*+@)0$``"-!$#!X`(# +XM0A"+2#B%R0^4P(3`#X3?_/__]D4@$`^$&_[__XM%"+H!````NP$```#HI/3_ +XM_^D)_O__BT70AP/A)\!``"+ +XM1>R+50PY4`AUY?9`)`%UWXMP&+L&````BW@4A?9^>##;ZS.-="8`BU4(#[;` +XMC01`C80`4`$```-"$(/`"(M5"(E$)`2)%"3H6]X```'#@^X!=!^#QP$/M@<\ +XM_W7*BT4(QT0D!/\```")!"3HIVG__^O+B=BZJZJJ*O?JB=C!^!\IPHT44@'2 +XM*=J-6@:%VWX@C;0F`````(M5",=$)`32U`@(B10DZ/W=```IPX7;?^>+1>R+ +XMR+$H72 +XMB57L#X5A_O__BT7P@\0<6UY?7<.+50@/ML"-!$"-A`!0`0```T(0@\`(BU4( +XMB40D!(D4).C9W```@^L!=*2#Q@$/M@8\_W7,BT4(QT0D!/\```")!"3H)VC_ +XM_^O-D(UT)@!5B>564X/L$(MU"(N>1`$``(7;=%"+0PR%P'0(B00DZ"`#__^+ +XM0Q2%P'0(B00DZ!$#__^+0QR%P'0(B00DZ`(#__^+$X72=`:+0P2)0@2+0P2) +XM$(D<).CI`O__BYY$`0``A=MUL(/$$%M>7<.-="8`58GE4X/L!(M="(L3A=)T +XM!HM#!(E"!(M#!(D0BT,,A(```"+ +XM31"+4Q0/MD$,.`(/A]````!R"(M]'#E["'1?BP.)7?"%P`^$T````(G#BT40 +XMA?````+31PY2PAUS_9#)`%UR8M+&(M%&#G( +XM=@*)R(M]%#G`B<'\\Z8/DL`/E\(HP@^^PNLHD(UT)@#V0R0!=9N+2QB+11@Y +XMR'=JB40D"(M%$(D4)(E$)`3HW?O__X/X`'\_#XQS____BU48.U,8D%_O__D(UT +XM)@#)N`$```##B?:-O"<`````58GE@^PXBT4DB77XBU44BW48B5WTB40D%(U% +XM\(E$)`2+10B)??R+?2#'1"08`````(ET)!")5"0,QT0D"`````")!"3H!_[_ +XM_X7`B<-T9?9%*`)U6XM%'(7`=$J%_XGV=$2+51R+10B)?"0(B50D!(D$).AH +XM'```A<")Q@^$I0$``(M#'(7`=`B)!"3H,P#__XE[(#'`B7,Q=PS'_,?;KUHUT)@`QP.OEQT0D!"@```#'!"0!````Z-S]_O^%P(G##X0Z +XM`0``BT4,A____QT,,`````(M5$(E3$(M%%(M5"(ET)`B)1"0$ +XMB10DZ((;``"%P(E#%`^$!`$``(ES&(M%'(7`#X2*````BT4____Z$+[_O^+,(M##(7`#X2(_O__B00DZ#W^_O_I>_[__XUT)@#H +XM'_O^_XLPBT,4B00DZ"+^_O_KT(VV`````(V_`````%6)Y5=64X/L'(M5"(MU +XM#(M"$(N`1`$``(7`B47D=17I3@(``(M%Y(L`A<")1>0/A#X"``"+1>2+510Y +XM4`AUY?9`)`ATWXM%$(7`=`^+11")="0$B00DZ)GW_O^+5>2+1>2+4A2)5>"+ +XM0!B%P(E%Z'5DZ<8```"#^WQT<#L=_"`)"'T,H0@A"0CV1)@V`G5%R+!HGZB!"#P`&)!H-MZ`%T9XM5X`^V.H/"`8E5X(GX#[;8@_L6=8NAH!0) +XM"(7`#X6(`0``BT8(@^@!A<")1@@/B#<"``"+!L8`%H/``8D&BT8(@^@!A<") +XM1@AYI#M&&'P%@/L*=9J)="0$B1PDZ.[[_O^#;>@!=9FAH!0)"(7`#X5(`@`` +XMBT8(@^@!A<")1@@/B$P"``"+!L8`((/``8D&BT7DBT`P/A,0```"+ +XM5>2+4B"%THE5\'50Z;(```"#^WQT7(#"`9`/A'L!``"+50B+0A"`O`-3!P`` +XM#'1"BPV@%`D(A+1>P/MCB#P`&)1>R)^@^VVH/[%G6?H:`4"0B%P`^%ZP```(M&"(/H`87` +XMB48(#XA8`0``BP;&`!:#P`&)!HM&"(/H`87`B48(>:0[1AA\!8#["G6:B70D +XM!(D<).CQ^O[_@VWP`769BQ6@%`D(A=(/A34!``"+1@B#Z`&%P(E&"`^(;`$` +XM`(L&Q@`*@\`!B0:+1>2+`(7`B47D#X7"_?__@\0<,% +XM://__P````#'A7#S__\`````QX5X\___`````(F%@//__\>%?//________' +XMA8SS__\`````QX60\___`````(F58//__XN%9//__XD$).C3^/[_A<`/A!0! +XM``"-6`B_<:P("/RY"````(G>\Z9UUHE<)!"+A8CS__^-E93S__^)%"3'1"0( +XMN90(",=$)`0`!```B40D#.@[]O[_C864\___QT0D"`````#'1"0$`@```(D$ +XM).@]]_[_@_C_B85L\___=(''1"00`0```(E$)`S'1"0(`````,=$)`0````` +XMBU4(B10DZ!//__P%^&\=$)`CXK0@(QT0D!`0```"+10B)!"3H>:#__XN5>//__SF5 +XM%=//__P$```#I;?[__XN5C//__XD4).BA +XM]O[_BX60\___B00DZ)/V_O^+E7SS__^)%"3H!?3^_X'$K`P``+H!````6XG0 +XM7E]=PXV5E/O__\=$)`0*````B10DZ+WQ_O^%P(F%A//__P^$0/[__XN-;//_ +XM_XV%E/?__[H`!```B85<\___Z/_[__^%P`^$'/[__XNU7//__[\TK`@(N1,` +XM``#\\Z8/A0/^__^-E93W___'1"0$"@```(D4).A<\?[_A<`/A.7]___&``"+ +XMA83S__^-=93&``"#A7#S__\!Z,GR_O_'``````"-A:?W__^)="0$B00DZ!'R +XM_O^%P'0/Z*CR_O^#.`*0#X1(`0``BY6`\___C86G^___B00DB50D!.CF\O[_ +XMA<`/A:3]__^#A7CS__\!B70D!(N%;//__XD$).BE]O[_BX6,\___A[_[_Z6_\ +XM___'1"0(`````,=$)`0%````BU4(B10DZ"J=___I3_S__\=$)`@`````QT0D +XM!`4```"+50B)%"3H"IW__XD<).@6]/[_Z2?\__^-M@````"-O"<`````58GE +XM5U93@>R,"```QT0D"`````#'1"0$*P```(M%"(D$).C)I?__N@$```"%P`^% +XM<@(``(M5"/:"!`,```$/A6\"``"+?0B+M_P"``")-"3HC^S^_X7`#X5X`@`` +XMQP0D0?$(".@+\/[_A<")A8CW__\/A%X"``"-A93[__^-E93W___'A8SW__\` +XM````B86$]___B96`]___C;0F`````(N5B/?__XD4).@V\_[_A<`/A,H!``"- +XM6`B_<:P("/RY"````(G>\Z9UUL=$)`13K`@(B1PDZ"KQ_O^%P(F%?/?__W2\ +XMBQ6@%`D(A=(/A5D"```/OT`.QT0D$`$```")1"0,QT0D"`````#'1"0$```` +XM`(M5"(D4).BC,___@_@"#X02`@``BX5\]___C964^___QT0D!``$``")%"2) +XM1"0(Z*[M_O^%P`^$N`$``(NUA/?__[@@K`@(N1,```#\B0$``(N5?/?__XV]E/?_ +XM_\=$)`0`!```B3PDB50D".A'[?[_A<`/A%$!``"+M8#W__^X-*P("+D3```` +XM_(G'\Z8/A38!``"-A93W___'1"0$"@```(D$).A^[?[_A<`/A!@!``#&``"+ +XMO9#W__^-=93&!P#H\N[^_\<``````(V%I_?__XET)`2)!"3H.N[^_X7`#X4\ +XM`0``H:`4"0B%P`^%1P$``(N5?/?__P^_0@Z)="0$B00DZ._R_O^-1;2)!"3H +XM!.W^_XV5I_O__XE4)`C'!"16K`@(B40D!.CZ[O[_QX6,]___`0```.FL```` +XMC;0F`````(N%C/?__X7`=0S'!"1AK`@(Z)[I_O^+O8CW__^)/"3H0/+^_S'2 +XM@<2,"```B=!;7E]=PXN"_`(``(T$0,'@`@-"$(MP.(DT).@7ZO[_A<`/A(C] +XM__^)="0(QT0D#$BL"`C'1"0$!0```(M]"(D\).@,G___@<2,"```N@$```!; +XMB=!>7UW#QT0D#&BN"`B)7"0(QT0D!`,```"+50B)%"3HVY[__XN%?/?__XD$ +XM).C!\/[_Z6C]__^+O7SW__^)/"3HKO#^_^E5_?__BX5\]___B00DZ*OO_O_I +XMF/W__^B1[?[_@S@"#X6V_O__B1PDZ-#K_O_KKXN]?/?__XD\).B`[_[_Z;#^ +XM__^-M"8`````58GE@>RH"```B77\B<:-19B)7?B)TXE$)`3'!"1ZK`@(Z)[L +XM_O^%P'0JB30DQT0D#(VL"`C'1"0(>JP(",=$)`0%````Z":>__^+7?B+=?R) +XM[%W#B5PD$(V=A/?__XD<),=$)`QZK`@(QT0D"*>L"`C'1"0$%`@``.B&[?[_ +XMB1PDZ%[K_O^+7?B+=?R)[%W#58GE@^PHB10DB5WTB=.)=?B)??R)SXE%\.AF +XM[O[_@_C_B<9T'P^W10B)'"2)1"0$Z&_O_O^)\(M=](MU^(M]_(GL7<.+1?#' +XM1"0,GZT("(E\)`C'1"0$!0```(D$).A]G?__Z]"-="8`C;PG`````%6)Y5>) +XMQU93BK^_[@!````@<1\%0``6UY? +XM7<.+A_P"``"-!$#!X`(#1Q"+<#CI-?[__XVV`````('$?!4``+@!````6UY? +XM7<.+E=3J__^+A7UW#BX7,ZO__BY70ZO__BQB-1?"+,HD$).B5Y_[_ +XMBY78ZO__QT0D1`:M"`B)7"1`QT0D/`NM"`B)5"1(C97P_O__B5PD.,=$)#08 +XMKP@(QT0D,$"O"`C'1"0L=*\("(E4)"C'1"0D$*T("(N5V.K__XE$)!"-A?#J +XM___'1"0<(:T("(ET)!B)5"0@QT0D%#RM"`C'1"0,2*T(",=$)`B8KP@(QT0D +XM!``0``")!"3H0>G^_SW_#P``B87@ZO__#X<+_O__A<"-M?#J__]U0>FN```` +XMQ@(*@\(!B=,I\XF5W.K__XE<)`B)="0$BY74ZO__B10DZ/OC_O\YPP^%G_[_ +XM_RF=X.K__XNUW.K__W1RBX7@ZO__@_@\C50P_W:UQT0D!`H```")-"3HEN;^ +XM_XG"*?"#^#Q^G#GR=IB)T.L(D(/J`3GR=A:`.B!U](G0*?"#^#P/CGK___^) +XMT.OCB<+I;____\=$)`@`````QT0D!`4```")/"3HU)/__^E%_O__BYW$ZO__ +XMA=MU!S'`Z7;]__^-E?#Z__^)^.A1^O__BX74ZO__B00DZ#?H_O^%P`^%Z_W_ +XM_S'`Z4S]__^-="8`58GE@>PH)```B7W\BWT(B5WTB77XBU\Q= +XMPY`Q]NOLBT,$QT0D!`L```")!"3_4!B%P`^%Y0$``/9%#`1T!(!+6"#V10P! +XM=*N+4U")^.BI^?__ZY^-M"8`````QT0D"`````#'1"0$*P```(D\).CHF___ +XMA<`/A9`!``#VAP0#```!#X7"`0``B[?\`@``C87T^___B70D#,=$)`AYK0@( +XMQT0D!``$``")!"3H3^?^_XGQB?B-E?3[___'!"2``0``Z,7Y__^)A>C;__^# +XMP`$/A#8!``"+1Q#'1"0(`0```,=$)`3DKP@(B3PD_Y!H"```BUM,QT0D"``` +XM``#'1"0$`````(F=[-O__XD<).@-Z/[_B87PV___@\`!=%>-A?3;__^)1"0$ +XMBX7PV___QT0D"``@``")!"3H(NK^_X/X`(G##XX9`0``,?;K!BG#=,T!QHV% +XM]-O__P'PB40D!(N%Z-O__XE<)`B)!"3HC^'^_X7`>=B+A>S;___'1"0,GZT( +XM",=$)`0%````B3PDB40D".C5EO__C87T^___O@$```")!"3H!N3^_XN%Z-O_ +XM_XD$).@XYO[_BT<0QT0D"`(```#'1"0$`````(D\)/^0:`@``.DC_O__C78` +XMQT0D"`$```#'1"0$`````(D\).@X//__A<`/A!#^__^^`0```.D&_O__C;8` +XM````]D4,`KX!````#X3Q_?__D.N^@&-8G[X!````QT0D#%ZM"`B+0TS'1"0$ +XM!0```(D\)(E$)`CH)I;__^G!_?__BX?\`@``C01`P>`"`T<0BW`XZ2W^__\/ +XMA0W___^+A>C;__^)!"3H>N7^_X7`#X49____C8WT^___N@$```")^#'VZ&KX +XM__^%P`^$'O___^GX_O__C;8`````C;PG`````%4QR8GE@^PHB77\BW4(B5WX +XMBUX<#[936(G0@^#]J$"(0UAT)HM#4(/BO8A36(7`="7'1"0$@`$``(M#3(D$ +XM).A`Y_[_,Q\!``` +XMBW4(QT0D"`````#'1"0$*P```(DT).A)F/__A'^__^058GE4X/L%(M=".BUX?[_QP``````BT44B40D"(M% +XM$(E$)`2+10R)!"3HAN'^_XD#Z(_A_O^Z`0```(L`A'^_\<``````(M%%(E$)`B+11")1"0$BT4,B00DZ/;?_O^)`^@?X?[_ +XMN@$```"+"(7)=0B#Q!2)T%M=P^@'X?[_@S@B=`Z#Q!0QTEN)T%W#C70F`(,[ +XM_[H"````=>B#Q!2)T%M=PXVT)@````"-O"<`````58GE@^P8B77\BW40B5WX +XMC48!B00DZ"KC_O^%P'0EB<.+10R)="0(B1PDB40D!.A!X_[_Q@0S`(G8BW7\ +XMBUWXB>Q=PXM%"#';QT0D"`````#'1"0$!0```(D$).APC/__Z]6-M"8````` +XMC;PG`````%6)Y5.#[!2+70C'1"0$+P```(D<).@ZW_[_A7UW# +XMBT7LAQT*0^V`SP@=.8\"73BB0^#Q"PQP%M>7UW# +XMC;8`````@\0L,6#[!B+ +XM112)7?2+70R)??R+?1")=?B%P'54/0`!``"+%W)8A=N--`)T78D<)(ET)`3H +XMS-S^_XG#A=MT5XL'B?+'1"0$`````"G"`=B)5"0(B00DZ*K>_O^)-XG8BW7X +XMBUWTBWW\B>Q=PY"-="8`BQ53@^PDBT44BUT(@_@"=&Z#^`-T287`=27'1"0(`````,=$)`0% +XM````B1PDZ&V*__^#Q"1;7<.-M"8`````BTL)___I-?___^A1V_[_C47XB40D +XM!(D<).A^5___A<`/A1G___^+1?B%P`^$>?___XE$)`S'1"0(`+((",=$)`0# +XM````B1PDZ%^)___I[?[__XM5##'`A=)T!8M5#(L"QT0D"`0```")1"0$B1PD +XMZ%A4`0#IQO[__XUV`%6)Y5=64X/L#(L]P,P("(E%\(E5[(7_=$( +XM1>NXP,P("#A5ZWT6ZS*)]HM[&(7_="D/MA>-0Q@X5>M\'CA5ZXG#=>>+3>R+ +XM=?#\.Q`/MC>-1MP\.`^&)@$``(M# +XM%(7`#X01`0``BTL0#[8QB?`/OM"%TGA#.17\(`D(?R_K.8M#%(U1`8E3$(/H +XM`87`B4,4#X3A````#[8RB=&)\`^^T(72>!0[%?P@"0A]#*$((0D(]D20-@)U +XMQX/Z?P^'R@```/8$E=T4"0@$#X2\````BTT(BS&%]G47QP$!````BU7=='I)/___X-K%`&ZT)D%"(E+$(`Y+W0%NC"5!0B+3=R+ +XM04R+3=B)`8M-W(M!4(M-V(E!!(N#@````"4````!@_@!&<`PP`5P`0``B40D +XM&(U%[(E$)!2+0Q2)1"00BT,0B4PD"(E,)`2)1"0,BT7Q0!#X:R````BU,0#[Y"`8/X?P^'H@```/8$A=T4 +XM"0@$#X24````Q@(KZ7?]__^+50C'`@$```"!BX````````0`@WL4`0^$,@,` +XM`,=$)`P#````BU78B50D"(M#$`^^0`&)1"0$BTWS'`@$` +XM``"!BX````````0`QT0D#`H```")1"0(BT,0B40D!(U%\(D$).CN]O__@_@! +XM#X6L````BT7PBU78B0+'0@0`````BU7LB=`K0Q`I0Q2)4Q#I?_S__[K0F04( +XMZ=O]__^#^G\/AZ0```#V!)7=%`D(!`^$E@```(#Y+0^$'0$``#'_@/E>#X02 +XM`0``C47LC57PQT0D#`H```")1"0(B70D!(D4).AP]O__@_@!=3*#?>``#XR@ +XM````D`^.L````(M5\(72D(UT)@!^$+C___]_*T7@.=`/@Y0```"X`@```(E$ +XM)`S'1"0(`P```,=$)`0`````BTW`%%X(-#$`&-1_^)0Q3I(OS__XM5\(72>1"X````@"M%X#G" +XM#XT!`0``A?]T1HM%\/?8BU7L`47@B=`K0Q`I0Q2)4Q#I[/O___8$E=T4"0@$ +XM=(WIVO[__X-K%`&_`0```(U&`8G&B4,0Z=C^__^-M@````"+1?#KNK@!```` +XMZX&+3=B+1>"+$??8.=`/A@_\___'1"0(C+((",=$)`0#````BT7" +XM__^+50S'`@$```#I\?O__X/$/+@!````6UY?7<.+>Q`/MC?'!"0*L0@(B?(/ +XMOL*)1"0$Z"75_O^%P`^$FOK__\=$)`P!````QT0D"`$```#'1"0$`````(M- +XMW(D,).CF]___BT4,QP`!````,<#ID/O__X-#$`*#:Q0"Z67Z__^X`P```.EF +XM_O__QT0D#`(```#'1"0(`P```,=$)`0`````BT7575KX"````4X/L+(M=#(M%$(M]",<``````,=#8``` +XM``"+0Q2%P'1_BTL0#[81C4+W/#(/AJ0```"+11"-3>B)VHE$)`2-1?")!"2) +XM^.@K^?__A<`/A4<"``"+11"+`(7`=6J+1?"%P'0]A?8/A#D"``"+0V"#^`$/ +XMA)H!``"#^`(/A'(!```Q]H7`=92+1>B+5>S'0V`!````B4-DBT,4B5-HAG<_O__]H.#````!`^%>____XM7'(72#X01 +XM`0``A?8/A$8!``"-0VR)1"0$B3PDZ$E.__^%P`^%)0$``#'`@WML`,=#<``` +XM``#'0V@`````#Y7`,?:#0Q`!@VL4`8E#9,=#8`(```#I=?[__Y"+0V"#^`%T +XM?8/X`@^$D@```(7`#X5M____C;0F`````.BOT?[_BU-LBT-PB5-DB4-HBT=, +XMB4-LBT=0QT-@`@```(E#<`^V$>DU____BU-L,?:+0W")4V2)0VB+1>B+5>R) +XM0VR)4W#I"?[__XM%Z#'VBU7LQT-@`@```(E#;(E3<.GO_?__BT-DO@$```") +XM1TR+0VB)1U"#0Q`!@VL4`>G1_?__BT-LO@$```")1TR+0W")1U"#0Q`!@VL4 +XM`>FS_?__QT0D#`$```#'1"0(`0```(D\),=$)`0`````Z)_T__^+11#'``$` +XM``"#Q"PQP%M>7UW#N`$```#I)/[__\=$)`P!````QT0D"`````#KP8M#8(/X +XM`71<@_@"=$N%P)`/A>G]__^+1TR)0V2+1U#'0V`!````B4-H,<#IXOW__\=$ +XM)`BXL@@(QT0D!`,```")/"3HR'[__XM%$,<``0```#'`Z;K]__^+4VR+0W") +XM4V2)0VB+1TR)0VR+1U#'0V`"````B4-PZ8C]__^-="8`58GE5U93@>R,```` +XMBT4(BU4(BTT(BT`0@\%,B464BY*8````B560BUA\B4V$BT,(A%"+1:`[!?P@"0A]1:$((0D(BU6@]D20 +XM-@)T-KX!````BTL4@T,0`8/I`87)B4L4=#&+0Q`/M@`/OM`\"HE5H'6YBTV4 +XM@X$(`0```8-##`'KSX7)=`J#?:`Z#X0[`0``BTL4A0`````Z?$%``"0BTL4@^D!A2)3"0(B5PD!(DT).C)^?__A<`/A5H%``"+5>2%T@^%D0X` +XM`(M#%(7`=$*+>Q`/MA!0[!?P@"0A]#*$((0D(]D2P-@)U +XM"8#Z.@^%Y@,``(U'`8E#$(M#%(/H`87`B4,4=;['0R!0T`@(BW60BT8H"8.` +XM````BT-@A`P`` +XMQT6L`0```.G2`P``H0@A"0B+?:#V1+@V`@^$UOW__XM+%(U"`8E#$(/I`87) +XMB4L4#X0__/__B<(/O@"%P(E%H`^(K_W__SL%_"`)"'R^Z:+]__^)]HM#%(/H +XM`87`B4,4#X2Z`0``BU,0C4(!B4,0@'H!"G7@@8N```````"``(-#$`&#:Q0! +XMBTV4BUE\Z=#Z__^+182+50B)1"0$B10DZ!%'__^%P`^%X@(``(M-",=!4``` +XM``"+@X`````E__^__XF#@````.G#^O__BU9(BT9,B580C0P"B10DB40D"(E, +XM)`3H@<_^_XM&3(E&%(M'"(M5"(E"3(E&1(/``8E'"`^V1E"H#`^$>_S__XM% +XM"(&(K`0``````@"+592+6GR+2Q2%R0^%./K__^EI_/__C;8`````BW,4A?:) +XM\0^$>P(``(M]C`^V%X#Z(0^$EA0```^^\H7V>!0Y-?P@"0A^#*$((0D(]D2P +XM-@)U38#Z*P^$G!0``(MS%,=%G`````#'19@`````QT6P`````.E<_O__#[X7 +XMA=(/B.$1```[%?P@"0@/C=41``"A""$)"/9$D#8"#X3%$0``BWL0C4'_B4,4 +XMB<&#QP&%P(E[$'7$,?:+>Q")\,=%K`````#'19@`````QT6<`````,=%L``` +XM``#IZ`$``(M3(.DE_?__@:.`````___^_^GR_/__BTT(B[F0`@``A?\/E<#I +XMQ_S__XM#$(`X"@^$2?[__XMUE(M>?.DK^?__BT4(]H"L!````@^%-OK__XN3 +XM@````/;&"`^$I?O__^DB^O__@/I\#X0D_/__@/H*#X0;_/__BT6@QP0D5;$( +XM"(E$)`3HN-2KN`^1\/ +XMABP4```Q]HM5J(GXZ.'M__^%P(E#(`^$0QP``(M3(('Z.-,("(G1#X2.&P`` +XMA?8/A#$6```/MT$(]L0!#X4K%@``@?E0T`@(#X06%@``@?F8T`@(#X0*%@`` +XM#[8/#[[1A=)X%#L5_"`)"'T,H0@A"0B+E)`T"```B!?I_1L``(UV`(M#2(D$ +XM).BIS?[_BQ.%TG0&BT,$B4($BT,$B1")'"3HD,W^_XM>?#E=P`^%7@H``,=# +XM%`````"+50C'1"0$`@```(D4).CV-/__A7UW#BWV,,<#'19P`````QT6L`````,=%F`````#'1;`````` +XMA<`/A'0@``")^.L\B?*`^A9T9(-]H`H/A,4```"#?:!\#X2[````#[9-H(@/ +XMBT,0@VL4`8M3%(/``8E#$(72#X2\````@\Q0!=I:+0Q`/OD`!@_@* +XMB47D=6J+=92#A@@!```!@T,,`8-%G`&#:Q0!@T,0`8M%Y(E%H.EV____BU4( +XMBT(0@+A2!P``_P^%3____XM-H(D4)(E,)`3HY#7__X/X$G2?@WV@"@^%.___ +XM_XGR@/H*#X1#$```@VL4`8MS%.L-@_A\#X4H____ZYDQ]HM#$(M3&(ES'(/` +XM`8E#&"G0B5,0*T6<@^@!@7L@H-$("(E#%`^$L0X``(N#@````(G"@^(/@_H" +XM#X0<#@``#X?`````@^H!#X7-````BU-@A=*)]@^%=!````T```@`J"#'0V`! +XM````B8.`````#X5V&P``BU4(BT),B4-DBTT(@7L@P,P("(M!4(E#:`^%GP`` +XM`,=#8`(```"+50B+0DR#P`&)0V2+30CV@4`#```!BU%,#X4V$```BW4(BX8X +XM`P```=")0VR+?0B+1U")0W")0VB-1?")1"0$B3PDZ/)!__^%P`^%!0<``(M% +XM\(7`=$$[1TQV/#M#;',WB4-LZS*-="8`@_H$#X3F`@``@_H(C70F``^$7@,` +XM`(MS8(7V#X6E!@``@7L@P,P("`^$8?___XM#(,=#7`````"+>`P/MC>)\(3` +XM#X26&@``BTL4B?*`^B$/A'$$``"%R71GBT,0#[X0A=(/B,4#```Y%?P@"0@/ +XMCKD#``"A""$)"/9$D#8"=2SIJ`,```^^$H72#XB:`P``.Q7\(`D(#XV.`P`` +XMH0@A"0CV1)`V`@^$?@,``(M3$(U!_XE#%(G!@\(!A<")4Q!UQ,=$)`2WL0@( +XMB3PDZ)/)_O^%P`^%[04``(M#8(/X`0^$P`0``(/X`@^$,@L``(M-"(N#@``` +XM`(N1K`0``/;"`@^%?P,``/;$0`^%=@,``*D```0`#X59#0``@^(!C78`=`>+ +XM10B#0"P!BU4(BTH((``"+ +XM30CV@:X$```"#X72"```]H$8`0```0^%P1<``(MU"(N&$`$``(7`#Y7`A,`/ +XMA*\(``#V@X````!`#X2B"```N@`0``#IG`@``,=#8`$```"+1TR#P`&)0V2+ +XM1U")0VCIWO7__XM38(72#X6%````#0``"`")@X````#'0V`"````BW4(BT8< +XMA<`/A+$3``"+?0B-0VR)1"0$B3PDZ*0^__^%P`^%MP,``/:#@````"`/A)$1 +XM``"+0VR%P`^%AA$``(.+@````!#'0V0`````@XN`````!,=#<`````#'0V@` +XM````Z:W\__^+4V"%T@^$HOS__X/J`0^%F?S__XM39(M#:,=#8`(```")4VR) +XM0W#I@?S__XMS%(M]C(7VB?`/A'$2``")^<=%G`````#K+(#Z"@^$UO?__P^V +XM1:"(`8M[$(-K%`&+Q"%]HGP#X0`^O__@\$!#[87#[["@/IL!```Z3'[__\/ML#_)(5(M@@(9H-+?""#:Q0!@T,0 +XM`8MS%(7VB?$/A.?^__^+0Q`/M@`\+@^$XPT```^/*P@``#PK#X3?#0``/"V) +XM]G3$B?'IOO[__SPCD(UT)@!U\(&C@````/___O]F@4M\``*+39"!22@``@`` +XM@VL4`8-#$`&+O$B4PD#(M-"(M#$(E<)`2)#"2)1"0(Z"XN``"%P'55 +XM#[9'`8U7`3Q.#X0T^O__#[[`@^@PB47D@'H!;P^$4`L``(MUD(M6)#G0#X03 +XM^O__BT,@BW4(BT`0QT0D"+JQ"`C'1"0$`P```(DT)(E$)`SH]6S__XM['(7_ +XM#X6C````BW,4A?9U+XUV`.F"````@/H6=%>#_@J-=@`/A!H/``"#_GP/A!$/ +XM``"+0Q2#Z`&%P(E#%'14BT,0#[80@\`!]H."`````HE#$`^^\G7!B?`\_P^$ +XM7`8``(M]"`^VP(M7$("\`E,'```2=:F+0Q2#^`%VH8/H`8E#%(M#%(-#$`&# +XMZ`&%P(E#%'6LBTL?(V&@````(E%P#G##X2B]?__]D-0 +XM#P^$<_7__XM3/(U[/#GZ=2?I6?7__XM"!(E!!(M"!#G'="J)"(D4).CVPO[_ +XMBU,\.=2%T@^%;O[__XM%Z(7`#X3& +XM%0``BT74A<`/A<R)!"3H!]W__X/X`0^%VQ0``(M-[(7)#X02$0``BT7@*T,0*4,4BT7@ +XMB4,0@#]A#X35$0``BT7LB4-89H-+?`2+2Q3I?_O__XM#$`^V,(GR@/HK#X0K +XM"0``@/HM#X0B"0``@/I>#X09"0``@/HCB?8/A`X)``")\0^^P8/X?W<.]@2% +XMW10)"`0/A>+Z__^#:Q0!B?"#0Q`!9H-+?`&+2Q2(0U'I'_O__XM[$(E]R(E] +XMX(M#%(7`#X3R````@\(7V>!@[-?P@"0A]$*$((0D(]D2P +XM-@(/A;L```"+5<2)^(A"_X-K%`�Q`!@T7$`8M#%(7`#X2J````BT7$B47( +XM@^@!B47,BT,0]H."`````@^V.(GZ#[[R=:")\#S_#X2'"```BTT(#[;`BU$0 +XM@+P"4P<``!)UB(M#%(/X`7:`BU,0@^@!B4,4C4(!B4,0#[9"`8M-Q(A!_^N) +XM,<"!>R#8S`@(B4PD#(M-"`^4P(E$)!"+0Q")7"0$B0PDB40D".AB,P``A<`/ +XMA#/V___I0/S__Y"-="8`@T,0`8-K%`&+=`I1Q")?8P/O@>% +XMP(E%H`^(W`D``#D%_"`)"`^.T`D``*$((0D(BU6@]D20-@)U,NF\"0``#[X" +XMA<")1:`/B*L)```[!?P@"0@/C9\)``"A""$)"(MUH/9$L#8"#X2,"0``BU,0 +XMC4'_B4,4B<&#P@&%P(E3$'6^Z5K[__^%TG0KBWT(BT=,QT78`````(E4)!") +XM7"0$B474C474B40D#(E$)`B)/"3H)9\``(M%F(7`=%GV@X(````"#X1.`P`` +XMBT68BU6P@'P0_Q8/E,"$P'01BU,8C4+_B4,8QD+_%H-#'`&+39@I2Q@!2QR+ +XM0QB+=;")3"0(B00DB70D!.B3OO[_@8N```````!``(M#&(E#$(M#'(E#%(M] +XM"(N7K`0``/;&'G5BBT64BUA\Z5WI__^+0VR%P`^%/?G__XN#@````*@0#X5L +XM^?__BWT(]H>L!````74+J0````(/A57Y___'1"0,`0```,=$)`@$````BT,@ +XMB40D!(M%"(D$).C.W/__Z73Z__^+30B+01"+6'R%VW15,?\Q]H![4`AV!>@! +XMN?[_#[9#4/\DA62W"`B%_W4@BWT(QT0D"*RS"`C'1"0$`P```(D\)+\!```` +XMZ!YG__^+&X7;=<`)]P^%R?K__XM-"(N1K`0``(#F%@^$9>___^G,ZO__A?9U +XMUXM%"&:^`0#'1"0(Y+,(",=$)`0#````B00DZ-9F__^+&X7;#X5T____Z[*+ +XM30B+D:P$``#VP@%U"ZD````"#X7.\___QT0D#`$```"+=0C'1"0(!````(M# +XM((DT)(E$)`3H[]O__^F5^?__BU-@A=(/A1[V__\-```(`,=#8`(```")@X`` +XM``"+30B+44R#^@$/A,X$``")4VR)4V2+?0B+1U")0W")0VCIB/+__P^V%X#Z +XM*P^%Z^W__^F"`@``BU4(BT(0@+A2!P``_P^%3?G__XET)`2)%"3HYR;__X/X +XM$@^%./G__^F*^?__A<"-M"8`````=1?I/_'__X/H`8VV``````^$,/'__X/" +XM`8`Z7(UT)@!UY<8"%NO@BWT(B40D!(D\).@:,___A<`/A"4/``"+EZP$``"+ +XM@X````#ISO+__SP]#X2_!0``/%X/A=/W__]F@TM\`NF2]___/&R0C70F``^$ +XMOP4``#QP#X6T]___9H%+?``0BT60@4@H`!```.G)]___BWT(BT=,B474BT=0 +XMB478C474@:.`````___[_\=$)`P!````B40D",=$)`0G````B3PDZ+55__^% +XMP`^%./C__XN7K`0``.E<\O__B10DZ)IB___I'//__XM-"(E$)`2)#"3H5C+_ +XM_X7`#X2U!P``BT9$BWT(B4=,Z63H__^)%"3HZ$;__^E#\O__BTV8BW6P#[9$ +XM,?\\_P^$"P,``(M]"`^VP(M7$("\`E,'```2#Y3`Z93\__^!BX```````(`` +XMZ:[O__^+4VR+=0B%THG0BTY,=06X`0```#G!#X1<]?__A=)U`K(!BWT(B?B) +XM5TR#P%#'1U``````B40D"(E4)`2)/"3H--C__^DO]?__BU-DBT4(A=*+2$R) +XMT'4%N`$````YP0^$$_7__X72=0*R`8M-"(G(B5%,@\!0QT%0`````(E$)`B) +XM5"0$B0PDZ.O7___IYO3__X/Z`@^%3O#__XM3;(M#<,=#8`$```")4V2)0VCI +XM-O#__XN!.`,``(T$0,'@`@-!$(M`..F\[___@VL4`8MS%(U'`6:!2WP``8E# +XM$(7VB?&)0Q@/A,GK__\/MA")Q^E`Z___BT,4@\!Z+1:`[!?P@"0A]$Z$((0D(BU6@ +XM]D20-@(/A5`#```/MDV@B`Z+0Q"#:Q0!BU,4@\`!B4,0A=(/A#(#``"#Q@$/ +XMM@`/OM")5:#V@X(````"=:0/MD6@//\/A#H"``"+30@/ML"+41"`O`)3!P`` +XM$G6)BT,4@_@!=HP!@^@!BU,0B4,4C4(!B4,0#[Y2`8E5H.N*N`$```#3 +XMX*D#B@(`#X5%!0``A<`/B;KK__^+%7#."`B)^8E5X`^V!SH"=1"#P0&#P@&) +XM5>`/M@$Z`G3P/&QT&SQP=!<\*W03/"UT#SQ>C78`=`@\(P^%>>O__XM#$#'V +XMB4L0*<@!0Q2A<,X("(E#)*%TS@@(B4,HH7C."`B)0RRA?,X("(E#,*&`S@@( +XMQT,P>;$("(E#-*&$S@@(B4,XC4,DB4,@Z4'K__^+0Q"`.`0/A(SF__^`YG^) +XMDX````#I?N;__ZD````"=0V!>R#`S`@(#X6G[___BWT(BU64QT0D!`$```") +XM/"3_DGP(``#IB^___X`_*P^%E/+__SPKB?8/A/+V__\\+0^%@O+__V:#2WP( +XMZ?#V__^+?9"+5R2%T@^$P^[__^FC]/__BU4(BT(0@+A2!P``_P^%I/G__\=$ +XM)`3_____B10DZ'(B__^#^!(/A8OY___I=?G__XUT)@"H(`^$*OO__XU%\(E$ +XM)`2)#"3H:2___X7`#X5\]/__BWWPA?\/A9L*``"#BX`````0QT-L`````,=# +XM9`````#I]/K__\=$)`0Q````B3PDZ+"S_O^%P`^%U/'__^G5]O__BT,4A<`/ +XMA`7N__^-="8`Z0'T__^+50B+0A"`N%('``#_#X4!]___B70D!(D4).C,(?__ +XM@_@2#X7L]O__Z5_W__^+50B+0A"`N%('``#_#X5/_?__BTV@B10DB4PD!.B< +XM(?__@_@2#X4W_?__Z:G]__\Q]HM3(`^W0@CVQ`)T+XM5"/:"9`,```$/A)<# +XM``"+@EP#``"-!$#!X`(#0A"+0#B%P`^5P(3`#X71"@``@?DXS0@(#X0O!0`` +XM@?EHS0@(#X1N!@``@?GPS`@(#X2"!@``@?F0SP@(#X1F!@``@?E0T`@(#X0T +XM!P``@:.`````_____>DOY?__@VL4`8/``6:!2WP``8M+%(E#$.D5\?__,?;I +XMO^+__XM#$(G&*?Z)=9B+0`````BW,4A?8/A'P```"+0Q`/O@"%P(E%H`^(E3`0``C78`#[X`A<")1:`/ +XMB$(!```[!?P@"0@/C38!``"A""$)"(M-H/9$B#8"#X0C`0``QT7D`0```(M# +XM$(-K%`&+"+0Q2%P'4FZ9T```")\H#Z%G1,B?"(!X-K +XM%`&#QP&+0Q2#0Q`!A<`/A'P```"+0Q`/MC")\`^^P(E%H/:#@@````)UR`^V +XM1:`\_W0RBTT(#[;`BU$0@+P"4P<``!)UM(M#%(/X`7:LBU,0@^@!B4,4C4(! +XMB4,0#[9"`8@'ZYF+50B+0A"`N%('``#_=8:+3:")%"2)3"0$Z"T?__^#^!(/ +XMA6[____KN(GVBT7@BU4(B5PD!"G'B7PD#(E$)`B)%"3HA"$``(7`#X0EZ___ +XMZ3+Q__^-M"8`````A?:)\`^$[O[__X-]H"&)]@^%XO[__X%[(/C0"`AT"XM] +XMY(7_#X3._O__A?8/A"\(``"+>Q`/MA>`^@IU$8UV`.F.Y?__@#\*#X0T!0`` +XMBWL0@^@!B4,4@\Q!UY,=%G`````#IM^?__XUV`(-[%`$/AD;Q___' +XM0QP!````Z5/Q__\/OM*%TG@4.Q7\(`D(?0RA""$)"(N4D#0$``"^`0```(@7 +XMZ5CF__^)T/?8.4%,#X>TZ___QT0D"&2S"`C'1"0$`P```(D,).A.7?__Z53P +XM__^+182+50B)1"0$B10DZ"3__P^V!SP\#X7V^O__#[[`B46@BTL4A +XM``"%P`^%UNW__XM+(.E:^O__#[8/@/EK#X1]`0``@/ES#X2N`@``A?8/A>'C +XM__^+10B%P)`/A#("``"+50B+P_O^+=;R+?0C'1"0,?[$(",=$)`0#````B70D"(D\).@Q7___ +XMBWT(BT<0AQ"+0Q3'19P`````Z:7C__^`/S`/A.7N +XM__^+?0C'1"0(G;$(",=$)`0#````B3PDZ'U9___I@^S__XN!$`$``(T$0,'@ +XM`@-!$(M`.(7`#Y7`Z3'H__^+30C'1"0$_____XD,).@Y%?__Z;SI__]F@TM\ +XM$.E2[O__@WVH`HVV``````^%?/[__X-K$`&Y>,\("(-#%`''0R!XSP@(Z1SB +XM__^+39#'02@`$```Z;WX__^+2Q3I`>K__XMU"(U%\(E$)`2)-"3HV";__X7` +XM#X7KZ___BT7PAR)0VSI%^[__XM]"(M'3(E#9.DWY/__N@H```")QL=%G`````#I1>#_ +XM_XL"QT0D".RR"`C'1"0$`P```(D\)(E$)`SH;5C__^ESZ___BT6HQT7<```` +XM`,=%O`````"#P`$/A>L"``"+5:B+1;S&!!``B50D"(E\)`2)!"3HV*[^_XMU +XM"(M-O,=$)`Q_L0@(QT0D!`,```")-"2)3"0(Z")=__^%]@^%Z?W__^GZ_?__ +XMD(UT)@"#?:@!="B+1:@QTH/H`8E%B`^V1#H!/&-T##QG=`@\<@^%+/W__X/" +XM`3M5B'7CBT,0@\`!*T6HB4,0BT,4@^@!`T6HB4,4H7#1"`B)0R2A=-$("(E# +XM**%XT0@(QT,H4-T&"(E#+*%\T0@(B4,PH8#1"`B)0S2AA-$("(E#.(U#)(E# +XM(.ERX/__BU,4C4$!B4,0@^H!A=*)4Q3'1:0"````#X3E````BTL0#[8!/%QT +XM+P^^P#G'#Y3`#[;`*46D@VL4`8MS%(-#$`&%]HGR#X0%^/__BTVDA(E$)`B+1G2) +XM1"0$BT4(B00DZ-7*__^%P`^$..G__XE&=.FU^___BW4(QT0D#`$```#'1"0( +XM`@```,=$)`0`````B30DZ&++___I".G__XM3$(E5C.D"^___@:!4"```__[_ +XM_^GNZ/__BW4(B40D#,=$)`@#````QT0D!`````")-"3H),O__^G*Z/__BWL0 +XMQT6<`````.FTW___QT0D"`@```"+50B+`8D4)(E$)`3HMR`!`.F=Z/__QT0D +XM#!BS"`B+=0B+0Q#'1"0$`P```(DT)(E$)`CH@%K__^EVZ/__BW,4Z7_@__^+ +XM30B)1"0,C47575E.#[!R+10B)1?"+,(M^$(DT).C$'@$`A4"```BQ.%TG0&BT,$B4($BT,$ +XMB1"+0PR)!"3HM:O^_XD<).BMJ_[_BU]LA=MUM_:'5`@``!`/A9,"``"-5GB[ +XM(`H``(V'D````(E5[(E%Z.FH`0``BX8T`0``BU80C01`BTR".(7)#Y7`A,!T +XM`X/+0/:&[`(```$/A.,!``"+AN0"``"-!$"+1((XA<`/E<"$P'0&@'D````-+4"`C'AY0````!````QX<``0```(`` +XM`(DT).C:U/__A,`````8N&K`0` +XM`*D````"=!&I```$`'1W@::L!```_____8DT).C.@@``]H8\`0```0^%)?[_ +XM_XN&-`$``(M6$(7`#Y7`Z2?^___'1"0$)KH("(DT).CN@@``B30DZ):"``#K +XMF8UT)@"+AN0"``"%P`^5P.D?_O__BT((B8>0````BT(0B8>4````Z;W^___' +XM1"0(`````(M&3(DT)(E$)`3HLDG__^EM____@>(`!```B50D",=$)`0````` +XMB30DZ-/\_O^%P'0U@\0'C`````$```#'AX@```#(L0@( +XMZ53]__^+5?`QP(DR@\0<6UY?7<.)-"3H(I+__XM5\(D"B74(@\0<6UY?7>F> +XMDO__D)"0D)"0D)"0D)"0D)!5B>564X/L$(M%#(MU"(M`=(L8BT80]H!4"``` +XM`70CQT0D#`````"+0PB)1"0(BP.)-"2)1"0$Z%2G__\QTH7`="/'1"0,B+<( +XM"(L#QT0D!`,```")-"2)1"0(Z%!6__^Z`0```(/$$(G06UY=PXGV58GE5U93 +XM@^P\BT4,BU!XA=)U+\=$)`@`````QT0D!`````"+10B)!"3HHJ+__S'2A<`/ +XMA&L!``"#Q#R)T%M>7UW#@_H"=`7HF*+^_XM`=(E%X(L`BSB)?>B+0`B)1>0/ +XMMDP'_P^VT3L5_"`)"`^-_0```*$((0D(]T20-``%```/A.H```"+1>@/M@B$ +XMR70NBQW\(`D(B@/ML`YV'T+]D2&-@(/A80!```/MD(!@\(! +XMA,!UXX-]Y`(/A@(!``"+=>2#[@(/A/8```"+/?P@"0BA""$)"(M5Z(E]W(E% +XM[.L2C;8`````@\(!@^X!#X3.````#[;!.T7S&1?,!]T2#-``%``!U +XM!X#Y7P^41?,/MDH!#[;!.47R[`0```/=$AS0`!0``=0R-M@````"` +XM^5\/E,,Z7?-TI<=$)`@PN`@(QT0D!`,```"+10B)!"3HRD___[H!````Z"+4P3'1"0@"````,=$)!P`````BT((B40D&(L"B40D%(M]Y(E\)!"+ +XM1>C'1"0(`````,=$)`0`````B40D#(M5"(D4).AJI?__N@$```"%P`^%%?[_ +XM_XM="##2BT,0@XA4"````>D!_O__QT0D"/RW"`C'1"0$`P```(M="(D<).C> +XM3O__N@$```#IW/W__Y"0D)!5B>575E.#[#R)1=R)5=B+5=R+0!")1>"+0AR% +XMP`^$L`,``(M%V(M5W(MX9(U!_X/X`8EZ3`^&>`$``(/I`0^$?@$``(M-V(MQ +XM'(7V=&N+41B)TX`["@^$Y`$``(/#`8/N`77OBT7<]H"N!````@^$ZP$``(G8 +XM*="#^`$/A.`"`T$0 +XMBW`XA?8/E<"$P+H0$!``=06Z`!`0`(M-W/:!/`$```$/A=0!``"+1=R+@#0! +XM``"%P`^5P(3`=`.#RD"-=>R)=>R)=?")5"0,QT0D"`````")="0$BU7DR0C70F``^$E0```#'` +XM@\0\6UY?7<,YTP^%'/[__X7V#X04_O__@^X!=#^#PP&)VNGT_?__B=@IT.D9 +XM_O__@#HN#X40_O__A?8/A#K^__^#[@&-="8`#X0M_O__BU78C4,!B4(8Z1_^ +XM___'1"00`````,=$)`Q/C0@(B7PD",=$)`0!````BTWGH_?__QT0D!`$```")%"3H11G__X7`#X13____BTW<,<#'04P! +XM````@\0\6UY?7<.+@30!``"-!$#!X`(#01"+2#B%R0^5P.D>_O__BT7$P/A17____'1"0$`0```(D$).CO&/__A<`/A/W^__^+5=PQP,="3`$```#I +XM[O[__\=$)`0!````BT7P``Z3S___^-M@````!5N0(` +XM``")Y8M%"(M5#%WIG/O__XVV`````(V_`````%6Y`0```(GEBT4(BU4,7>E\ +XM^___C;8`````C;\`````53')B>6+10B+50Q=Z5_[__^0D)"0D)"0D)"0D)"0 +XMD)!5N`(```")Y5=64X/L'(M=#(M]"(7;=`:+0WB#P`''1"0$!````(D$).CF +XMGO[_A<`/A)$```"%VXE%\'1-BTMTBW7PBP&+4`B%TG1JB) +XMUH/&!,<&`````(M%\(/$'%M>7UW#QT0D"`````#'1"0$!0```(D\).A!2?__ +XMQT7P`````.O4D(VT)@````!5B>575E.#["R+?0B+7R2%VP^$1`$``(L#A<`/ +XMA"`!``#'1>@!````QT7L`````,=%\`````#IGP```)"-="8`@WWH`70:QT0D +XM!-+4"`B)/"3H6GD``(M/*,=%\`$````YRP^$R````(L3N4^-"`B)R(E$)!") +XM5"0,B4PD",=$)`2RN`@(B3PDZ+-Y``"+1Q#V@%0(```$#X6D````QT0D#`$` +XM``#'1"0(`````,=$)`0`````B3PDZ*,,__^%P'4,BT<0]H!4"```!'5T@\,$ +XMBP.%P'1K@T7H`8D$).@2H/[_BT\H,=(YV0^4P@-%\(TT4`%U[(M'.(/H`3E% +XM[`^"//___\=$)`0FN@@(B3PDZ)QX``"+3RB)=>S'1?``````.```@\0L,56 +XM4X/L$(M="(MU#(M#)(7`#X2(````QT0D"!$````/MT9\B1PD)0`!``")1"0$ +XMZ&KQ_O^%P'0,@\00N`$```!;7EW#BT,DB4,HBP")'"2)1"0$Z%;T_O^%P(G" +XM=-H/MT9\QT0D"`````")5"0$B1PD)0`!``"#^`$9P(/@_(/`)(E$)`SHI/7^ +XM_X7`=:J!BZP$````"``$@\006UY=PXD<),=$)`CTN`@(QT0D!`,```#H]T;_ +XM_X/$$+@!````6UY=PXUT)@"-O"<`````58GE@^PHB77XBW4(B7W\BWT,B5WT +XMBT8H.T8D#X3>````]H>!`````74VQT0D"!$````/MT=\B30D)0`!``")1"0$ +XMZ(GP_O^%P'15N`$```"+7?2+=?B+??R)[%W#C78`BUC\B1PDZ#F>_O^)7"0( +XMB7PD!(DT)(E$)`SHL0D``(7`=(72=1:+1RB%P`^$GP$` +XM`(M(!(7)#X24`0``BTT,]H&!`````71XA=)T-(U%\(E$)`B)?"0$BT<0B00D +XMZ.Z'__^Z`0```(7`#X2(`0``@\0LB=!;7E]=PXVT)@````"+1RB+6`2)'"3H +XM]IS^_XE<)`B)1"0,BT4,B3PDB40D!.AK"```A<`/A`0!``"#Q"RZ`0```%N) +XMT%Y?7<.-="8`QT0D"!$```"+50P/MT)\B3PD)0`!``")1"0$Z-#N_O^%P'7) +XMBTT,BU%XA=(/A"`"``#VAZT$```@=3*+5R2%TG0KBP*%P'0=B=.-M@````") +XM!"3HO)O^_XM#!(/#!(7`=>Z+5R2)%"3HIYO^_X&GK`0``/^?___'1R@````` +XMQT0D!`0```"+50R+0GB#P`&)!"3H79G^_X7`B<:)1R0/A"8"``"+10R+2'2+ +XM`8M0"(72#X0;`0``B +XM7UV)PHG0PXUT)@")/"3'1"0(U[@(",=$)`0#````Z-A#__^#Q"RZ`0```%N) +XMT%Y?70O__N@$```#IP_S__Y"0D)!5B>57 +XM5E.#[`R+10B+F)@```"+4QR%TG1,BT,@A) +XM%"3HOYC^_\=#'``````QP,=#(`````#'0R0`````@\0,6UY?7<.-M@````"- +XMOP````!5B>575E.#[!R)1>R)5>B+L)@```"+1B2)1?"+3B"%R70,B<*#P@*- +XM0?\YPGQ/BU8((M]\,'G +XM`HG[`UXB#P`$Y0P1S(XL3B4,$ +XMA=)T8HE$)`2)%"3H99+^_X7`B0,/A!$!``"`2PP!BT7P@\`!B2) +XM^P->'(L+A6_O^-=@#KG<=$)`00````QP0D`0```.@^E?[_ +XMA<")`P^$U0```(M&'(M5\(L4D(72#X5$____BU7LQT0D"`````#'1"0$!0`` +XM`(D4).@40/__N`$```#KAL=$)`00````QP0D`0```.CME/[_A<")`P^$I``` +XM`(M&'(M5Y(L4D(72#X5+____ZZV+5>S'1"0(`````,=$)`0%````B10DZ,$_ +XM__^+5AR%T@^%DO[__XM%[(D$).B;_?__Z7?___^+1>S'1"0(`````,=$)`0% +XM````B00DZ(L___^+.X7_#X7*_O__@&,,_L<#`````,=#!`````#I//___XM5 +XM[,=$)`@`````QT0D!`4```")%"3H4#___^D+____BU7LQT0D"`````#'1"0$ +XM!0```(D4).@P/___Z3S___^-="8`C;PG`````%6)Y5=64X/L'(M%"(MU%(N` +XMF````(7VB47D=#:+#?P@"0B+%0@A"0B+?1#K!HUV`(/'`0^^!X7`>#0YR'TP +XM]D2"-@(/A+T!``"#[@&-="8`==Z+5>2+30R+0AR)072+0B2)07B#Q!PQP%M> +XM7UW#A?9TX(E]$,=%\`````#K+8GV/!9T6(7;>!8['?P@"0B)]GT,H0@A"0CV +XM1)@V`G57@T40`8-%\`&#[@%T2HM5$(M-#`^V`O:!@@````(/OMAUP(#[_P^$ +XMN@```(M-"`^VPXM1$("\`E,'```2=:B#_@%VHX-%$`&#[@ `!@T7P`8/N +XM`76VBU7PBT4(Z*#\__^+3>2+422+01R+3?"+!)")2`B+3>2+7?"+01R%VXL$ +XMD(L`B47L#X3!````BT7PB?N+?>R)1>CK(H`[%@^4P(3`=`.#PP$/M@.(!X/' +XM`8-MZ`$/A(D```"#PP&+50SV@H(````"==(/M@,\_W1#BTT(#[;`BU$0@+P" +XM4P<``!(/E,#KNXM5"(M"$("X4@<``/\/A>[^__^)7"0$B10DZ$[^_O^#^!(/ +XMA=G^___I+/___XM5"(M"$("X4@<``/]UAL=$)`3_____B10DZ"'^_O^#^!(/ +XMA6W____I9?___XUV`(M%[(M-\(T$`8E%[(M5[,8"`(M-Y(-!)`&%]@^%&_[_ +XM_^E,_O__A?:)?1#'1?``````#X5:_O__Z=C^__^-=@!5N@$```")Y8/L"(M% +XM"(ET)`2+=0R)'"2+F)@```#'0R0`````Z%;[__^+0QR)1G2+0R2)1GB+'"0Q +XMP(MT)`2)[%W#C;8`````C;PG`````%6)Y8/L&(M%"(EU^(MU%(E]_(M]#(E= +XM](N8F````(GRZ`O[__^+4R2+0QR+!)"+$(M%$(ET)`B)%"2)1"0$Z!&3_O^+ +XM4R2+0QR+!)"+`,8$,`"+4R2+0QR+!)")<`B+0QR#0R0!B4=TBT,DB4=XBUWT +XM,<"+=?B+??R)[%W#C78`58GE5U93@^Q,BWT,B47`BT44B56\BU48B4VXBTT0 +XMBP")1>"+`HM5"(E%\(L)A=*)37UW#BTW`BT$@ +XMBT`(A<")1<@/A&H#``"+7`^''@$``(M#>(MS=(E%\(&+5`@` +XM```!``#I;?___XU-\(E4)`R)3"0(BUW@B5PD!(M%P(D$).@'K?__A<`/A*P! +XM``")P>FJ_/__C4-XB4PD#(E$)`B+0W2)1"0$BT7`B00DZ-NL__^%P`^$@`$` +XM`(E#=.D1_?__@:-4"```__[__XM-S#M+>`^'$`$``(M#>(MS=(E%\(&+5`@` +XM```!``#I8_W__XU-\(E4)`R)3"0(B70D!(M%P(D$).B#K/__A<`/A"@!``") +XMQNDS_O__C5WPB4PD#(E<)`B)="0$BU7`B10DZ%JL__^%P`^$_P```(G&Z93^ +XM__^-0WB)3"0,B40D"(M#=(E$)`2+1<")!"3H+JS__X7`#X33````B4-TZ;3^ +XM__^)1"0,C4-XB40D"(M#=(E$)`2+5<")%"3H`:S__X7`#X2F````B4-TZ;7^ +XM__^!HU0(``#__O__.W-X=V:+0WB+4W2)1?"!BU0(`````0``Z0C]__^-3?") +XM5"0,B4PD"(ET)`2+1<")!"3HL*O__X7`=%F)QNEK_/__C4-XB4PD#(E$)`B+ +XM0W2)1"0$BT7`B00DZ(BK__^%P'0QB4-TZ7UW#QT0D"#RY"`C'1"0$ +XM`P```(D,).AF-O__@\1,N`$```!;7E]=PXU%\(ET)`R)1"0(B50D!(M%P(D$ +XM).C?JO__A*_O^-=@!5B>575E.#[#R+?0B%_W04BU\0A=MT#?:#50@```$/A$P! +XM``#'1>@`````C5WPQT7P`````,=$)`P``@``B5PD",=$)`0`````B3PDZ"^J +XM__^%P`^$D`$``(E%Z(M%&,=%[`````")7"00B40D%(U%Z(E$)`R-1>R)1"0( +XMBT7HB40D!(M5%(GXB10DBTT0BU4,Z!KY__^%P`^%H@```(M%[(7`B47<=&B+ +XM5>B)T0'!.`/@]T````/O@*%P`^(T@```(LU_"`)"#G&#X[$````BQT( +XM(0D(]D2#-@)U(^FR````#[X"A<`/B+`````YQ@^.J````/9$@S8"#X2=```` +XM@\(!.7UW#C70F`(7_=!.+5Q"%TG0,BT)T.T7H#X2O````BT7HB00D +XMZ)*+_O^X`0```(/$/%M>7UW#D(%[>/\!``!V28M#=(E%Z(M#>(E%\(&+5`@` +XM```!``"-7?#IQ?[__SE-X`^$")5"0(BT4,B3PDB40D +XM!.AS]___Z4[___^-0WC'1"0,``(``(E$)`B+0W2)/"2)1"0$Z*"H__^%P'0% +XMB4-TZY"X`0```(GVZ7+___^!HE0(``#__O__,<#I8?___X&B5`@``/_^__^X +XM`0```.E-____C;8`````58GE5U93@^Q,B47(B57$B4W`]H!D`P```0^$D0(` +XM`(G"BX!<`P``C01`P>`"`T(0BT`XA<`/E<"$P`^%A@(``(M%R/:`<`,```$/ +XMA9X"``"+1#'1"0$+P```(M5X(D4).A%AO[_BU7@B57S'1?#_____QT7L_____XE5U(D$).CL +XMA/[_A<`/B-8#``#'1"0$D+X("(M%[(D$).B!A_[_A<")1

7UW# +XMB<*+@&@#``"-!$#!X`(#0A"+0#B)1>#I4OW__\=$)`0!````BT7PB00DZ->! +XM_O^+1>R)!"3H+(7^_XM%\(D$).@AA?[_QP0D`@```.@5A?[_QT0D$`````"+ +XM1=C'1"0(V[D("(E$)`R+5=R)5"0$BT7@B00DZ'R!_O_'1"0,WKD("(M5X,=$ +XM)`0%````B50D"(M%R(D$).A&-?__QP0D?P```.@NAO[_@:-4"```__[__XM5 +XMP(L"`<`[0WAW8(M3=(E5V(M5P(M#>(D"@8M4"`````$``(L"Z9C]__^)5"0, +XMBT7`B40D"(M5V(E4)`2+1*3__X7`#X1*`0``BU7`B478BP+I9OW_ +XM_XD4).C_AO[_B<;I%?W__XE$)`R-0WB)1"0(BT-TB40D!(M%R(D$).@WI/__ +XMA<`/A`D!``")0W3I<____\=$)`C5N0@(QT0D!`4```"+5 +XM7UW#QT0D"%;?"`C'1"0$!0```(M%R(D$).@?+___@\1,N`$```!;7E]=P\=$ +XM)`SSN0@(BT7<,?;'1"0$`P```(E$)`B+5@/A)X! +XM``"+1>B)!"3HKX3^_X/$;(GP6UY?7<.0@7YX_P$```^&CP$``(M&=(E%Z(M& +XM>(E%\(&.5`@````!``#I5/___\=$)`@!````QT0D!#0```")'"3H4#;__X7` +XM="V+1>R+5>B#Z`6#P@6)1>R)1"0,B50D"(M5#(D<)(E4)`3H!N[__XG&Z6+_ +XM___'1"0(`0```,=$)`0U````B1PDZ`)1:2#[P4/ME$%A-(/A,(```"%_W4%_P^$\_[_ +XM_X/O`0^$"P$``(U%[(D$)(U-\(G8C57HZ&/X__^%P`^%6?[__XM%[(E$)`R+ +XM1>B)1"0(Z=/^__^!HE0(``#__O__B?"#Q&Q;7E]=PXU&>,=$)`P``@``B40D +XM"(M&=(D<)(E$)`3H=J#__X7`=`B)1G3I1_[__[X!````D(UT)@#I(/[__X7_ +XM#X1G_O__H?P@"0@Q]HL-""$)"(E%K(E-L.L(BT78#[94!@6+1=B-1#`%B47< +XMBT6D*?"#Z`6)1=0/OL*%P'@:.T6L?16+5;#V1((V`G4>]T2"-``%``!U%)") +XM1"0$BTVHB0PDZ,5]_O^%P'4:@\8!.?=UJ.GU_?__BX-T`P``B46HZ5+^__^+ +XM?=3IY/[__XM-W(`Y*@^%Z?[__\8!`(M%Z(/`!8E%M(N3F````(E5S,=$)`0O +XM````B00DZ.Y]_O^%P(G`0``.46T#X2_`0``Q@``BT6TB00DZ)V"_O^) +XM1<"#Q@&)=>"+5>")%"3HB8+^_XM-M(E%N(D,).@[?O[_A<")1<@/A+T!``"+ +XM5`@ND'3; +XM@\`(B470B00DZ#2"_O^)1;R+?;R)V`-]P(U7`NC=Z/__BT7,BU`DBT`?[_Z>K[__^#P`B)1=")!"3H +XM78'^_SE%N(E%O`^'ZO[__XM-N(MUT(M]X/PYR?.F#X76_O__Z0?___^+1<") +XM1"0(BU6TB30DB50D!.@"@/[_`W7`@WW``799Q@8O@\8!Z0;____'1"0(!;H( +XM"+X!````QT0D!`,```")'"3H+2G__^EK^___QT7``0```,=%M`J@"`CI/_[_ +XM_XM-M,=%P`````#'1;1!\0@(B4W@Z2S^__^+3;2`.2]UG^FK_O__QT0D#)^M +XM"`B+1;2^`0```,=$)`0%````B1PDB40D".C;+?__Z0G[__^0D)"0D)!5B>57 +XM5E.#[!R+?0SV1WP!=`X/ME=1@/I`=`6`^BIU&XM%"&:#N*P$````#XGB`0`` +XMBTT(#[:1J````(M="`^VRH&+K`0```"```"(DZ@````[#?P@"0@/C&4!``") +XMT(M="(MS$(N>0`$``(7;=0_I;`$``(L;A=L/A&(!```Z0Q!U\<=$)`2$```` +XMQP0D`0```.@=??[_A<")1?`/A*4!``"+=?"+1?"#QCR)<#R)<$#'1"0$$``` +XM`,<$)`$```#H[WS^_X7`B<(/A+H!``"+1V2)0@CVAX(````(#X56`0``BT=L +XMB4(,BT7P@$A0`8M-\(M!/(ER!(D".W%`#X1^`0``B5`$BT7PC7L(,?:)4#R+ +XM4PPQP#G7=!B-M@````"+0A"+4@2#P`$!QCG7=?&-!#:)!"3H^GW^_XM5\(7` +XMB4(0#X3_````BU7PB4)(B7),Q@0P`(M;##G?="P!QHGVBT,(BU,0B30DB40D +XM!(E4)`CH[GW^_XGP`T,0Q@`*BUL$C7`!.=]UV(M-"(M=\(M1$(M"?(7`B0-T +XM"8M"?(E8!(M1$(M%\(E"?(M5"(M-\(M"$(/`?(E!!(/$'#'`6UY?7<.A""$) +XM"&:#?(@T``^)BO[__P^VA(@T!```Z7_^__^-!$F`P@&-A$98`0``='J)1"0$ +XMQT0D"`````"+50B)%"3HVO$``+@!````@\0<6UY?7<.)!"3'1"0(!0```,=$ +XM)`0`````Z+7Q``"#Q!RX`0```%M>7UW#B4(,BTWP@$E0`NFH_O__QT0D"``` +XM``#'1"0$!0```(M-"(D,).A>)O__N`$```#KHL=$)`3_````BT4(B00DZ#3B +XM_O_I;O___XE10.E]_O__QT0D"`````#'1"0$!0```(M5"(D4).@<)O__N`$` +XM``#I7?___Y"058GE5U93@^P\BWT,BW4(BT=TBP")1>"+0`B%P`^$K@$``(N> +XMF````(M#&(7`=`B)!"3H[7S^_XM5X(L"B00DZ%!V_O^%P(E#&`^$3`(``/:' +XM@@```"!T+HN&K`0``*D```0`=2&H`@^$^`$``(M5X(L"QT0D!-7:"`B)-"2) +XM1"0(Z+H)`@"+1V"%P`^%L@```(M&'(7`=&CV0%@$=&+VAB0!```!#X3@`0`` +XMBX8<`0``C01`P>`"`T80BT`XA<`/E<"$P`^%(@(``/:&8`0```$/A.8!``"+ +XMAE@$``"-!$#!X`(#1A"+0#B%P`^5P(3`=`[VAJX$```$#X3.`0``D#'2,<#V +XMAJP$```1B50D#`^4P(E$)!"+5>"+`HE\)`2)-"2)1"0(Z/6```#WAJP$```" +XM``0`='TQTH/$/(G06UY?7<.+3AR%R0^$NP$``(./@````$"#?V0!#X2A```` +XM,<")1"08BU7@BP*)?"0$B30DB40D%(U%Z(E$)!"-1VR)1"0,C4=DB40D".B! +XM)P``BU7H]H:L!````HE63`^%I````(M%[/>&K`0```(`!`")1E!U@XDT),=$ +XM)`0EN@@(Z,Q4``"#Q#PQTEN)T%Y?7P<"```BU4(BUT,BT(<]D!8!'0Y]D-] +XM`74SBT(@BT`(@#@O="C'1"0(3+H(",=$)`0#````B10DZ)PB__^!Q!P(``"X +XM`0```%M>7UW#BT-XA<`/A:,```#'!"2_N@@(Z'ER_O^%P(F%\/?__P^$HP$` +XM`(N5\/?__XD4).A-`"`T(0BU`XC7(!ZPB`^SIT"X/&`0^V7O^$VW7PC4;^.<)R:X3;="") +XM\NOF@^@!=$SHB'/^_X!Y`2YUJ`^V00(\+W0$A,!UG,=$)`R?K0@(BX7P]___ +XMQT0D!`4```")1"0(BU4(B10DZ*TF__^X`0```('$'`@``%M>7UW#BT-TBP"+ +XM`(F%\/?__^D4____QD;_`(N%\/?__XV]]/?__XE4)`S'1"0(N90(",=$)`0` +XM"```B40D$(D\).CO=?[_B%[_B3PDZ#1Q_O^%P'0R#[9>_^E-____@<0<"``` +XM,7<.0QX:L`````0```.O*C70F`(M5#(M"%(DT),=$ +XM)`0"````B40D".AFNP``@\0PN`$```!;7EW#BT,575KX!````4X/L'(M]"(N'F````(M8$(7;=#>)]HM# +XM$(E$)!"+0PB)="0(@\8!QT0D!%C4"`B)/"2)1"0,Z"M0``"+&X7;==6#Q!PQ +XMP%M>7UW#B3PDQT0D!$#4"`CH"U```(/$'#'`6UY?7<.058GE4X'L-`@``(F% +XMZ/?__XU%](F5Y/?__XF-X/?__\=%[/_____'1?C_____QT7T_____XD$).B( +XMR)!"3H=7#^_X7`#XCY````Z&AV_O^+E>3W__^#^/^) +XM0A`/A+@!``"%P`^%2P$``,=$)`0`````BT7TC9WL]___B00DZ)5O_O_'1"0$ +XM`0```(M%\(D$).B";_[_QT0D!`(```"+1?")!"3H;V_^_XM%^(D$).C$#W__^)5"00BY7D]___BT((QT0D"*S5"`C'1"0$``@` +XM`(D<)(E$)`SHFG+^_\=$)!``````B5PD#,=$)`C;N0@(QT0D!%Z@"`C'!"19 +XMH`@(Z/)N_O_'1"0,Z;D("(E<)`C'1"0$!0```(N%Z/?__XD$).B\(O__QP0D +XM?P```.BD<_[_QT0D"%;?"`C'1"0$!0```(N%Z/?__XD$).B"'?__BT7T@_C_ +XM=`B)!"3H!G+^_XM%^(/X_W0(B00DZ/9Q_O^+1>R#^/]T"(D$).CF3W__^)0AB!Q#0(```QP%M=P\=$ +XM)`C5N0@(QT0D!`4```"+A>CW__^)!"3HK!S__^DE____C;0F`````%6)Y5.) +XMTX/L)(7;BY"8````='V+0QB%P'0(B00DZ()S_O^+0R"%P'0(B00DZ'-S_O^- +XM1?C'1"0(`````(E$)`2+0Q")!"3H^6S^_XL3A=)T!HM#!(E"!(M#!(D0BT,L +XMA +XM7UW#D(UT)@!5B>57B<=64X/L#(D$).BAB70D"(E$)`2)/"3H)FK^_X7`=>.#Q`R)V%M>7UW#,=N#Q`R) +XMV%M>7UW#D(VT)@````!5B>575HG&4XG3@^PDH``(L5(-@("(72=#4QVXN#*-@("(E4)`S'1"0(!0```,=$)`22U`@( +XMB40D$(DT).A(2@``BY,PV`@(@\,0A=)US3'`@\0<6UY?7<.)T.@J____A<") +XMQW0^BT`(B40D#(L'B30DQT0D!&[4"`B)1"0(Z`=*``"+1PR)-"3'1"0$7ND( +XM"(E$)`CH\$D``(/$'#'`6UY?7<.)7"0(QT0D!/#5"`B)-"3HTDD``+@!```` +XMZY*-="8`C;PG`````%6)Y8M%"(M5$%WI$?___Y!5B>575E.![.P,``"+10B+ +XM71"+@)@```")A33S__^+0!"%P`^$8`$``(N--//__\>%///__P````#'A4#S +XM__\`````.0D/A&,!``"%VW0]#[8##[[0A=)X+XLU_"`)"#G6?B6+#0@A"0CK +XM%I"-="8`@\,!#[8##[[0A=)X"SGR?0?V1)$V`G7HA,!U38M%"+JGU`@(Z'?^ +XM__^+A3SS__^%P'0.BX4\\___B00DZ`-O_O^+A4#S__^%P'0.BY5`\___B10D +XMZ.MN_O^X`0```('$[`P``%M>7UW#C5,!B95<\___#[9[`8GY#[[1A=)XG8LU +XM_"`)"#GR?9.+#0@A"0B)C5CS___V1)$V`G2`/'/'A4SS__\`````#X0<`0`` +XMN9W4"`CK$H.%3//__P&#P0$XP@^$`P$```^V40&$TG7F//\/A#$!``"+50@/ +XMML"-!$"-A`!0`0```T(0@\`(BWT(QT0D$)W4"`B)1"0,QT0D"#S6"`C'1"0$ +XM`P```(D\).@<%___Z1#___^+50C'1"0(&-8(",=$)`0#````B10DZ/P6__^X +XM`0```.D@____QT0D!"````#'!"0!````Z-)K_O^%P(F%///__P^$^?[__XN] +XM///__XG&@\8(B7<(B7<,QT0D!"P```#'!"0!````Z)]K_O^%P(F%0//__P^$ +XMEO[__XM'"(N50//__XD"B7($.W<,#X2\!@``BXU`\___B4@$BX5`\___B[T\ +XM\___B4<(B4<0Z1'^__^)^(3`=1_I1_[__P^^PH7`>$0YQHGV?CZ+C5CS___V +XM1($V`G0Q@X5<\___`8N%7//__P^V$(32==+I%/[__XM-",=$)`3_____B0PD +XMZ`72_O_IS?[__X#Z(@^%*`8``(N]7//__P^V5P&$T@^$%@8``(!_`@`/A0P& +XM```/OL*%P'@<.<:)]GX6BXU8\___9H-\@30`>0@/MI2!-`0``(M]"(M'$(N` +XM0`$``(7`=1+IU`4``(UV`(L`A<`/A,<%```Z4!"-=@!U[HM`"(M("(F-7//_ +XM_XMP$(U&(XE$)`3'!"0!````Z'!J_O^%P(F%9//__P^$*@<``(N]9//__XN- +XM9//__XGZ@\$(@\(=B8U@\___B4\(B4\,B5<4#[8#B$<=C48"QD(!((E'&(M' +XM%(N57//__XET)`B#P`*)5"0$B00DZ,-K_O^+1Q3&1`8"`(!/'`&+30B+?0B+ +XM10B+22")C3CS__^+?TR)O43S__^+0%#'A5#S__\`````B85(\___@'D8`'D7 +XMBU4,BY*`````P>H(]]*#X@&)E5#S__^+C33S__^+21"%R8F-+//__P^$E08` +XM`,>%5//__P````"+O2SS__^+E63S__^+C4SS__^+/XF],//__XM"%(N]+//_ +XM_XE,)`C'1"0$K-0("(/``HE$)`R+1R")!"3HRF/^_XM'((D$).CO9O[_ZW^- +XM1>R-E8CS__^-??*)?"0,B40D",=$)`2RU`@(B10DZ,EG_O^#^`(/A#$#``"- +XMC8CS___'1"0$"@```(D,).B*9O[_A<")1>AT`\8``(N5+//__XV]B//__XE\ +XM)!"+30B+0@C'1"0(R-0(",=$)`0#````B0PDB40D#.C:$___BY4L\___C8V( +XM\___BT(8QT0D!``(``")#"2)1"0(Z+ME_O^%P`^%5O___XL=H!0)"(7;#X43 +XM!0``BY4L\___BT(8#[]`#,'H!8/@`83`=`OHB6?^_\<`!0```(N]+//__XM' +XM",=$)`B?K0@(QT0D!`4```")1"0,BT4(B00DZ&<8__^+10@QR8GZZ*OV__^+ +XMC3SS__^%R70.BY4\\___B10DZ$=J_O^+C63S__^+?0B)3"0$B3PDZ"ZL``"X +XM`0```.E"^___@_L"#X09`P``@_\"B?L/CK`"``"#^P,/A?P!``"+5>B%THF5 +XM://__P^$ZP$``(7V#X3C`0``B10DZ)IJ_O^+C2SS__^)A7CS__^+62B+`X7` +XM#X1*!```C76(ZPV#PP2+`X7`#X0X!```B[UL\___B40D#(V%B/O__\=$)`BY +XME`@(QT0D!``$``")?"00B00DZ"-G_O^-E8C[__^)="0$B10DZ-%E_O^%P'6Q +XMBQN)G7#S__^)'"3H'6K^_XN-+//__XF%*//__XM%J#M!%`^%://__P````"+E2CS__^+C7SS +XM___'!"0!````C40*,`.%>//__XE$)`3HYV;^_X7`B<,/A.\#``"-0"B)0Q2+ +XMO2CS__^%_W0RBY4H\___BXUP\___B00DB50D"(E,)`3H86C^_XN]*//__XM# +XM%,8$."^#QP&)O2CS__^+A7SS__^+E2CS__\#4Q2#P`&)1"0(BX5L\___B10D +XMB40D!.@C:/[_BX4H\___`X5\\___B4,8BY6`\___B5,//__XE+)(N]://__XG(@\`!B40D"(D4)(E\)`3HU&?^_XN% +XM8//__XD#BY5D\___BT(,B4,$BXU@\___.TH(#X3I`@``B1B+O63S__^)7PR# +XMA53S__\!BT7L@^@!B47L@\`!#X0V`0``B[TL\___BT<8QT0D!``(``")1"0( +XMC86(\___B00DZ,IB_O^%P`^$#_W__XV5B//__\=$)`0*````B10DZ!QC_O^% +XMP(E%Z`^$C0```(V-B//__[\!````Q@``B4WHC47HQT0D!-'4"`B-7_^)!"3H +XMFF7^_X7`B<8/A&S]__^%VP^%4/W__XDT).@@:/[_B;5L\___B85\\___@\C\__^+A5SS__^)!"3HE6?^_XG&Z3OZ__^)5PSI +XM1?G__XM!&(D$).C[9O[_B<'KD8N5+//__XM%".CU\___BX4P\___A<")A2SS +XM__\/A>KZ__^+E53S__^%T@^$9P$``(N-9//__XM1"(E1$(M]#`^W1WPE``$` +XM`/:'@0````$/A/$!``")1"0(BT4(B50D!(D$).@KM```A<`/A3SW__^+50B+ +XM4A2)50B+BI@```")C33S__^+A33S__^+E33S__^+&#G3B=@/A&\!``"+O63S +XM__^)!XE7!(N%-//__SM`!`^$30$``(N5-//__XN-9//__XL"B4@$BX5D\___ +XMB[TT\___B0>+E63S__^+30B+0A")5"0$B0PDB40D".A1[O__BX50\___A<`/ +XMA-D```"+?0B+4Q"+1R")0@B+4Q"+1TR)0@R+1U"+4Q")0A`QP.F\]O__BXTL +XM\___BT$8B00DZ$%?_O^%P`^5P.GE^O__QX4H\___`````.DI_/__B[5H\___ +XMN-34"`BY"@```/R)Q_.F#X4P_/__Z1?\__^+50C'1"0(`````,=$)`0%```` +XMB10DZ"D.___I'?;__XE:".D1_?__BT4(QT0D"-[4"`C'1"0$!````(D$).@! +XM#O__,<#I*/;__XM]",=$)`@`````QT0D!`4```")/"3HWPW__^F/^O__BT,0 +XMBY4X\___B5`(BT,0BXU$\___B4@,BT,0B[U(\___B7@0,<#IW?7__XEX!.F\ +XM_O__BY4\\___B1J+C3SS__^)VHE9!#M;!'1"BP.+O3SS__^)>`2+C3SS__^+ +XMA33S__^)RXD(B>(D\).C29/[_BU4(B7PD"(ET)`2)%"2)1"0,Z(?>__^Z +XM`0```(7`=2Z+5G@YV@^$QP$``(U#`3G"="R+10C'1"0(`0```(E\)`2)!"3H +XMY=<``+H!````BUWTB="+=?B+??R)[%W#D(M&=(U]E(L$F(LPB7PD!(DT).C] +XM7_[_A<`/A3`"```/MT6<)0#P```]`$````^$/0(``,=$)`0O````B30DZ&%? +XM_O^%P(F%+//__W0,Q@``@\`!B84L\___B30DZ!-D_O_'!"0!````B<.-0#B) +XM1"0$Z"YA_O^%P(G'#X19`@``C4`TB4<(B5\,B5PD"(ET)`2)!"3HNV+^_XM% +XMM(E'%,=$)!`&U0@(BT<(QT0D"+F4"`C'1"0$``@``(E$)`R-A33S__^)!"3H +XMB&#^_XV%-/___XV5-//__XE$)`2)%"3H,%_^_X7`#X2_````BT<(B00DZ#U< +XM_O^%P(E'+`^$Y`$``,=$)`0$````QP0D`@```.B.8/[_A<")PHE'*`^$XP$` +XM`(M'+(D"BXTL\___B?J+10CHB.S__X7`#X7]````BY4H\___BT(0A<")!W0& +XMBT(0B7@$BX4H\___B?J)>!"+A2CS__^#P!")1P2+10CHC.___S'2A<`/A'+^ +XM__^+10B)^C')Z(;N__^Z`0```.E<_O__BT4(NO?4"`CH?_'__[H!````Z47^ +XM__^+M63___^-1@&)!"3H:&'^_X7`B4%+//___O4"`B%P`^$H?W_ +XM_XM%"(E<)`C'1"0$!0```(D$).CA"?__N@$```#I%_W__\=$)`@`````Z6W_ +XM__^+10C'1"0(`````,=$)`0%````B00DZ*\)___I-____XM'+(7`#X0L____ +XMB00DZ*M@_O_'1RP`````Z1C___^)'"3H%U[^_XM'++D!````BY4P\___Q@00 +XM`(M'+`^V$(32="6#P`$PR>L*#[80A-)T%(/``8#Z.G7Q#[80A-)T!8/!`>OL +XM@\$!QT0D!`0```")#"3H)E[^_X7`B<.)1R@/A'O____'1"0$(=4("(M'+(D$ +XM).@67/[_A<`/A(+]__^)`X/#!,=$)`0AU0@(QP0D`````.CU6_[_A575E.#[#R+10B+L)@```#VAC@$```!#X0X`0`` +XM@(XX!````8M5#(M"=(L`BU`(BS"%TGYC#[X&A7'1"0(:-8( +XM",=$)`0#````BT4(B00DZ",(__^X`0```(/$/%M>7UW#A=)TU(72#XX2`@`` +XMBSW\(`D(B?.A""$)"(E]U(E%X(VT)@`````/M@L/OL&%P'@/.T74?0J+?>#V +XM1(#"+#?P@ +XM"0@YR'TFBQ4((0D(ZQ>)]H/#`0^V`X3`=!(/OL"%P'@+.<%^!_9$@C5`=>2) +XM\.B-[?__A<`/A#?___^)7"0(BU4,B50D!(M]"(D\)/]0!(/$/%M>7UW#QP0D +XM$]4(".A15_[_A<")QP^$LO[__XD$).C_7O[_B47%W^_XM]V(E] +XM[,=$)`0?U0@(B1PDZ.);_O^%P'0=@#@`=.>)1"0(BT4,B40D!(M5"(D4).A? +XM^?__Z\^+10B%P'06BWT(BT<0AO__A<")1=@/A3O___^X`0```.D#_O__B40D#(U# +XM>(E$)`B+0W2)1"0$BU4(B10DZ*1Z__^%P'35B4-TZ?+^__\/M@Z)\XUV`.D? +XM_O__@:!4"```__[__^E+_?__D)"0D)"0D)"0D)"058GE@^PXB77XBW4(B5WT +XMBUT,B7W\BT8`/MT-\C5-1C7MDQT0D$`$```")?"0( +XM@^`!]]@APHM%X(E4)`2)-"2)1"0,Z!J1_O^%P'06N`$```"+7?2+=?B+??R) +XM[%W#C70F`(M%X,=$)`P!````B7PD!(DT)(E$)`CHY93^_X7`=57OX#8"`A6B=93B<.# +XM[!R+4!#V1A@!=06_C=@("(7)#X3R````B7PD#(E,)`C'1"0$G]@("(D<).C` +XM-0``BT8(@\8(B77L.?")1?`/A+X```"+5?"+>A"+0@B%_XE%Z`^$AP```#'V +XMZV:-="8`#[;`C01`C80`4`$```-#$(/`"(E$)`2)'"3HX30``(M#$/:`5`@` +XM``1U=\=$)`P!````QT0D"`````#'1"0$`````(D<).AER/[_A@/M@06//]UD\=$)`3_````B1PDZ/.__O_KE,=$ +XM)`0FN@@(B1PDZ'$T``"+1?"+5>R+`#G0B47P#X5"____@\0<6UY?7<,/MD80 +XM//]T$@^VP(T$0(V,0E@!``#I]/[__\=$)`3_````B1PDZ)R__O^)P>G=_O__ +XMD(UT)@!5B>6#["B+50R+10B)7?2)=?B)??R)1>R)5?"+0G2+`(L8#[83@/IC +XM#X2W````=T*`^F(/A.<```"-M"8`````QT0D"`H```"+5?"+0B"+0!")1"0$ +XMBWWLB3PDZ&#.``"X`0```(M=](MU^(M]_(GL7<.`^G-T.8#Z='7$BT`(@_@$ +XM=[RZ8,$("#G`_(G>B=>)P?.F=:J+1>R+7?2+=?B+??R)10B)[%WIPZ$``(UV +XM`(M`"(/X!W>(NA_N"`@YP/R)WHG7B<'SI@^%GK10``BT`(@_@+#X=/____NN78"`@YP/R)WHG7B<'SI@^%.?___XM% +XM[(M=](MU^(M]_(E%"(GL7>DBX___B?:+0`B#^` +XMB=>)P?.F#X7^_O__BU7LBT(0BYA``0``A=L/A"$!```/MD,0@_A_=PKV!(7= +XM%`D(!'5>C4,(.4,(=`R+1>PQR8G:Z#/]__^+5>R+0A#V@%0(```$#X7@```` +XMQT0D#`$```#'1"0(`````,=$)`0`````B10DZ"#&_O^%P'43BWWLBT<0]H!4 +XM"```!`^%J0```(L;A=MUB8M5[(M"$(NP0`$``(7V='6-=@`/MD80@_A_=UWV +XM!(7=%`D(!'13C48(.48(=`R+1>PQR8GRZ*G\__^+?>R+1Q#V@%0(```$=5K' +XM1"0,`0```,=$)`@`````QT0D!`````")/"3HFL7^_X7`=0R+1Q#V@%0(```$ +XM=2J+-H7V=92+5>R+0A"+D"`!``"%TG04BT7LN=;8"`CH1_S__S'`Z?7]__\Q +XMP.GN_?__BY`@`0``A=)UV\=$)`BXV`@(QT0D!`0```"+?>R)/"3H!`'__S'` +XMZ<+]__^0D)"0D)"0D)"0D)"058GE@^PXB5WTBUT,B77XBW4(B7W\BT-XA#' +XM1"0(`````(E\)`0E``$``/?:@^(@@_@!&<#WT(/@!`G0B40D#(DT).A'KO[_ +XMA+0&2) +XM1?B+1?C'1"0$\=@("(D<)(E$)`CH5B\``#'2@\0DB=!;7<.-1?B)1"0$B1PD +XMZ!W,_O^Z`0```(7`=,?KWL=$)`@$````BT`@BP")'"2)1"0$Z"G)``"Z`0`` +XM`.N^D)!5B>6#[!B)7?2+70B)=?B+50R)??R+0QR%P`^$O0```(M">(7`=2G' +XM1"0(`0```(M#3(D<)(E$)`3H4O7^_S'`BUWTBW7XBWW\B>Q=PXUV`(/H`70+ +XMZ%I/_O^-M@````"+0G2+#_____QT7<_____\=%Z/_____'1>3_ +XM____=!.-1>2)!"3H84[^_X7`#XCP!```C47") +XM!"3H0TW^_\=$)`0"````BT7@B00DZ#!-_O^+1>2#^/]T"(D$).B`4/[_BT7H +XM@_C_=`B)!"3H<%#^_XM%W(D$).AE4/[_BT7@B00DZ%I0_O^+10@/MIAP`P`` +XM@^,!#X2/`P``B<*+@&@#``"-!$#!X`(#0A"+0#C'1"0$+P```(D$).B#3O[_ +XMA<"-4`$/A-8$``"$VP^$2@,``(M-"(N!:`,``(T$0,'@`@-!$(M`.,=$)!`` +XM````BTT`"`T(0BT`XQT0D#.FY"`B)1"0(QT0D!`4```"+10B) +XM!"3H$0#__\<$)'\```#H^5#^_Y"-="8`N@$```"#Q$R)T%M>7UW#D(M%Y(/X +XM_W0(B00DZ&1/_O^+1>")!"3H64_^_XM%((/H`8/X`0^&H`(``(M-"(M!'(!( +XM6`CHJTO^_X/X_XG'#X2S`P``A<`/A"8#``"+1>B)!"3H'4_^_X-](`,/A?,# +XM``"+50B+LI@```"-1>R)1"0(BU70B50D!(M-"(D,).CMQ@``AR)1"0(BT8LB40D +XM!(M-"(D,).B.+P``A<`/A'#___^+%:`4"0B%T@^%%`0``(M5T`^_0@S!Z`:# +XMX`&$P`^%WP,``(M5T#'VB10DZ+I0_O_'1"00`0```,=$)`P`````QT0D"`G9 +XM"`B)?"0$BT4(B00DZ`]3``"%P`^$00,``+X!````BU48BP*#^`%V&8E$)`2+ +XM30B)#"3HN<;^_X7`=0:+11B#*`&+50B+0AR`8%CW@WT@`@^$G`$``#'`QT0D +XM$`````")1"0,BT4B#^/]T"(D$).AB3?[_BUW0A=MT+HM-T(D,).C` +XM3_[_BT7@@_C_#X3`_?__B00DZ#Q-_O^#Q$RZ`0```%N)T%Y?7<.+1=R#^/]T +XMU8D$).@=3?[_Z\N-M"8`````QT0D"-6Y"`C'1"0$!0```(M5"(D4).AE^/[_ +XMZ7+____'1"0(SKD(",=$)`0%````BT4(B00DZ$7X_O_I4O___XM-"(N!:`,` +XM`.D2_?__BTT(BX%H`P``Z;W\__^+30B+@6@#``#I=_S__X-](`$/A-````"- +XM1?#'1"04`0```(E$)!"+31")3"0,BT70QT0D!/;8"`B)1"0(BU4(B10DZ*PR +XM``"+30B%P`^5P`^V\(M%\`%!7(-](`(/A7;^__^+51"+"H7)#X7&`0``BTT8 +XMB0&+30BX`0```/:!K`0```(/A5'^___I2O[__\=$)`A6WP@(QT0D!`4```"+ +XM50B)%"3H>O?^_\=%T`````#I@/[__XM%W(D$).CW2_[_QT0D!!KW"`B+1>B) +XM!"3HU$O^_X7`#X7#`0``QP0D`0```.A`3?[_BT7HB00DZ,5+_O^-1?#'1"04 +XM`0```(E$)!"+51")5"0,BTW0QT0D!/;8"`B)3"0(BT4(B00DZ-$Q``"+50B% +XMP`^5P`^V\(M%\`%"7#'`Z:#]___'1"0(UKD("+X!````QT0D!`4```"+10B) +XM!"3HR?;^_XM%Z(D$).A22_[_BT7`"`T(0BU`XZ0C[__^-1?#'1"04`0```(E$)!"+312)3"0, +XMBT70QT0D!/;8"`B)1"0(BU4(B10DZ"PQ``"+30B%P`^5P`^V\(M%\`%!7.F0 +XM_/__A?8/A;S\__^+12"%P`^%L?S__\=$)!`!````BU44B50D#(M-$,=$)`0` +XM````B4PD"(M%"(D$).BJ@?[_AR)5>B+5?`/MD)0J`UT1(M:/(UZ/#G?=#&+,XM###M%$(GQ +XMR)0@B+0PR#P`&)0@R+1>B)6@2)0PR+`XD"BP,Y +XMQW0=B5`$B1.)\^E@____@VL,`8U"_XE#"(GSZ4____^+1?")4$")$^O>BT7P +XMB4@\ZX>+0P2+5?")0D"+"^EN____QT0D"`````#'1"0$!0```(M5"(D4).C0 +XM\_[_@\057B<=64X/L +XM;(E5M(E-L(MP'(7V#X1?`0``]H"N!````@^%(0$``(M-M(M9>(7;#X3I```` +XMBT%TBS7\(`D(BP"+"`^V$0^VVCGS?1NA""$)".L-@\$!#[81#[;:.?-]!_9$ +XMF#8"=>R$T@^$KP```#D=_"`)"`^/CP```(#Z7`^$F@```(#Z?`^$D0```(#Z +XM"@^$B````(U!`8E%S`^V40&$T@^$;@$``(MUS`^VPCG#B?%U*^GR````D(UT +XM)@`/MA:#Q@&($0^V%H/!`832#X1'`0``#[;".<,/A-$```"`^EQUVHU&`8E% +XMT`^V5@$/ML(YPP^$J@```(#Z7`^$EP````^V%HMUT.NZH0@A"0CW1)@T``4` +XM``^$7O___Y#'1"0("@```(MUM(M&((M`$(D\)(E$)`3HD[T``+@!````@\1L +XM6UY?7<.+5;2+0B"+`(D\),=$)`@8V0@(QT0D!`,```")1"0,Z$+R_O^#Q&RX +XM`0```%M>7UW#QT0D"`0```"+0B"+`(D\)(E$)`3H/+T``+@!````ZZ?&`5P/ +XMME8!@\$!@\8"Z1G___^+=N!```0`^$&@,``(M'3(E%Y(M'4(E%Z(U%Y,=$)`P!````B40D +XM",=$)`0G````B3PDZ";B_O^%P'08N`$```#I*O___XMUS(GQ#[;".<-UD>N, +XMQT0D!(0```#'!"0!````Z&I&_O^%P(E%N`^$^0(``(M-N(M%N(/!/(E-O(E( +XM/(E(0(M5M(M"=(GRBP`K$(M`""G0A<")1?!U#+Y+C0@(QT7P`0```(M%\`'` +XMB00DZ)Q'_O^+3;B%P(E!$`^$J`(``(M5N(E"2(M%\(E"3(M-N(G"`U$0B70D +XM!(E$)`B)%"3HFD?^_XMUN,=&1`````"#?;`!&<"#X/R#P`@(1E"+1Q"+4'R% +XMTHD6=`F+0'R)<`2+1Q"+5;B)4'R+1Q"#P'R)0@2+3;2+662+<6PY\XEUQ`^' +XM?P(``,=%P`$```#'1R)5"00B4PD#,=$)`@!````B5PD!(D\).A+N_[_ +XMA<`/A?']__^+=?"-1=3'1=0`````QT78`````,=%X`````")==R-M[````#' +XM1"00!````(E$)`S'1"0(`````(M%[(DT)(E$)`3HP$+^_X7`#X2O_O__@_@! +XM=!6)="0(B40D!(D\).@/5P``Z9O^__^+5;"%T@^$Z_[__^F+_O__B5H,Z=[^ +XM__^)03SIT/[__XV'L````(E$)!2-A\0```")1"00C8?`````QT0D&`(```") +XM1"0,*TW,B4PD"(M5S(D\)(E4)`3H;E<``(7`#X4D_?__QX>L`````0```.GF +XM_/__C8>P````QT0D&`(```")1"04QT0D$`````#'1"0,`````(N'Q````(E4 +XM)`2)/"2)1"0(Z!]7``"%P`^$IOS__^G0_/__QT0D"`````#'1"0$!0```(D\ +XM).A:[O[_N`$```#IXOO__XM%N(L0A=)T!HM`!(E"!(MUN(M&!(D0BT80B00D +XMZ$)%_O^)-"3H.D7^_\=$)`0"````B3PDZ%8S__\QP.FA^___QT0D"`8```#' +XM1"0$`````(D\).@7N0``N`$```#I?_O__XVV`````(V\)P````!5N0$```") +XMY8M%"(M5#%WI'/K__XVV`````(V_`````%6)Y8M5#(M%"%T/MDI]@^$!Z?KY +XM__^0D)"0D)"0D)"058GE@^P8BT4(B5WTB7W\BWT,B77XBW`0BT9\C9Z````` +XMBU`4A=(/A80```"#?1@!&<#WT"4`:`(`B8.`````BT4Q=PS'`QT,(```` +XM`.OHD(UT)@#'1"0$A````,<$)`$```#HT$'^_X7`=$V)PXM&?(7`B0-T!HM& +XM?(E8!(U&?(E>?(E#!.E%____BT44B40D"(M%$(E$)`2+10B)!"3HT%___X7` +XMB4,0#X5%____N`$```#I?O___XM%",=$)`@`````QT0D!`4```")!"3H<.S^ +XM_[@!````Z5G___^-M@````!5B>6![#@$``")5"0$B5WTB=.)=?B)SHE]_(G' +XMB0PDZ*`__O\QTH7`=!:+7?2)T(MU^(M]_(GL7<.-M"8`````Z/]#_O^+50B% +XMT@^$Q@```(M+#(7)#X6[````#[=#"+H"````J!)TPKL"````C47PB40D"(ET +XM)`2)/"3H8-_^_\=$)`0O````B30DB87@^___Z#X^_O^%P`^$!`$``(/[`0^$ +XMP`````^"DP```(/[`G4BBY7@^___QT0D"%C:"`C'1"0$`P```(D\)(E4)`SH +XMC.O^_XM-\+H!````A_O__C47LB70D!(E$)`B)/"3H#=[^_X/[`8G^```` +XM#[__^)="0,QT0D"%S9"`C'1"0$`P```(E$)!")/"3H6NK^_XM=[(7; +XM#X3#_O__A?]T#8M'$(7`=`8[<'20=&*)-"3H2D'^_^FE_O__@_L"==*+A>#[ +XM__^)="0,QT0D"+S9"`C'1"0$`P```(E$)!")/"3H!NK^_^NJBY7@^___B40D +XM#,=$)`B0V0@(QT0D!`,```")5"00B3PDZ-[I_O_K@H&@5`@``/_^___I0?[_ +XM_XVV`````(V\)P````!5B>6![,@```")7?2-G5C___^)=?B)UHE]_(G'C47L +XMB40D&(D<),=$)!0`````QT0D$`````#'1"0,`````,=$)`@`````QT0D!#8` +XM``#H7;<``(DT).@I0?[_B70D"(D<)(E$)`R-1=R)1"0$Z.ZR``")7"0$B3PD +XMZ")/``"+7?2+=?B+??R)[%W#D(UT)@!5N9;:"`B)Y8'LZ`0``(EU^(MU"(E] +XM_(U]E(GZB5WTB?#'1"0$`````,<$)`$```#HF_S__X/X`@^$4@$``(M&$(M` +XM?(M`%(7`#X5B`0``]X:L!`````8``'05,<"+7?2+=?B+??R)[%W#C;8````` +XMQP0DH]H(".BX./[_A<")PP^$50$``(D$).AF0/[_QT0D%`````#'1"00`0`` +XM`(E<)`C'1"0$H]H("(DT)(E$)`SHVOK__X7`#X7(````BT80BT!\BT`4A<`/ +XMA>\```#WAJP$````!@``=8#VAJ@!```!#X3C````BX:@`0``C01`P>`"`T80 +XMBW@XA?\/E<"$P`^$5/___XV=-/___[FKV@@(B=J)\,=$)`0`````QP0D```` +XM`.BF^___A<`/A?P```"YG=H("(G:B?#'1"0$`````,<$)`````#H@?O__X/X +XM`@^%VP```(N%-/___SM%E'4/BX4X____.T68#X3!````NIW:"`B)\.CR_?__ +XMA<`/A*T```"X`0```.G-_O__NI;:"`B)\.C4_?__A_O__B30DZ.=H___ID?[__XDT).C::/__Z03___^+GJ`!``"%VP^5P.DD +XM____QP0DI-H(".A--_[_A<")PP^$C0```(D$).C[/O[_QT0D%`````#'1"00 +XM`0```(E<)`C'1"0$I-H("(DT)(E$)`SH;_G__X7`#X25_O__Z5C___^#^`)T +XM((M&$(M`?(M(%(7)#X07_O__B30DZ%1H__\QP.D*_O__BX4T____.T64=0N+ +XMA3C___\[19ATRKJKV@@(B?#H^_S__X7`=+KI"/___\<$)+^Z"`CHJC;^_X7` +XMB<,/A"K^__^`.``/A"'^__^)1"0,C84T^___QT0D$*O:"`C'1"0(N90(",=$ +XM)`0`!```B00DZ`T[_O^-C33[__^)^HGPQT0D!`$```#'!"0`````Z.OY__^% +XMP'5(C84T^___QT0D$)W:"`B)7"0,QT0D"+F4"`C'1"0$``0``(D$).C!.O[_ +XMC8TT^___B?J)\,=$)`0!````QP0D`````.B?^?__@_@"#X6$_?__C94T^___ +XMB?#H*?S__X7`#X1O_?__Z3+^__^-M@````"-OP````!5B>6#?0P^BT40=`1= +XM,<##B44,7>D7@```C;0F`````%6)Y8/L&(EU^(MU"(E]_#'_B5WTBYZ8```` +XMA=MT4_:&KP0```%U:3'_B30DZ&^C__^%P'52BT,LA)]HDT)&:_`0#H9"L``(7`=8GK +XMA8VT)@````"-O"<`````58GE@^P8QT0D!#P$``")7?2)=?B+=0B)??R+?0S' +XM!"0!````Z,LY_O^%P(G#=&*)AY@```")`XE#!,=`"`````"-0`B)0PPQP(7V +XMQT,0`````'0PBX:8````BT`8AQ=P\=$)`@`````QT0D!`4```")-"3H +XM5^3^_[@!````Z]3'1"0(`````,=$)`0%````B3PDZ#CD_O^X`0```.NUD%6) +XMY5=64X/L3(M%"(M`'(7`#X1Z!0``BW4,BT9D@\`!B40D!(M%"(D$).A1L?[_ +XMA<`/A,P$``"+10B%P'07BTT(BUD0A=MT#?:#50@```$/A.<$``"-1?#'1?`` +XM````QT0D#``!``")1"0(QT0D!`````"+=0B)-"3H4EC__X7`B478#X1"!0`` +XMBTT,]D%\!'0$@T%L`8MU#(M&9(M6;(G'.=")5>`/A!$%```Y1>#'1=0!```` +XM#X*F`0``QT7(`````,=%S`````"-M@````"-1>R-5>B)1"00B50D#,=$)`@` +XM````B7PD!(M-"(D,).CKKO[_A<`/A2X$``"+1>R%P`^$2`$``(M5S#';C50" +XM`HM%"(E5S(7`#X2T`0``BTT(BUD0A=L/A*8!``"+1=@Y0W0/A)H!``"+5R%]HEU +XMQ(EUO'1EBTWH#[X!B`/AG3^__^+=0R+1F2+50B)0DR+30R+<62+66PYWG(6Z3<" +XM``"-M@````"#ZP$YW@^#)@(``(E<)`2+10B)!"3H%K;^_X7`=.*+50B%TG06 +XMBU4(BT(0AR+30@IT(/H`8E!4#M]X,=%U``````/AJ+] +XM___I*?___XM-Z(E$)`B)3"0$BT7R+5>@!1=P!1<@/OG00 +XM_^G(_O__BTWH@#DI#X2E_O__B70D!,<$)-/:"`CH*3/^_\=%T`````"%P'07 +XMBT7R#P@<@!B57_/__ +XMC4-XB50D#(E$)`B+0W2)1"0$BTT(B0PDZ$Q4__^%P`^$/P$``(E#=.E5_O__ +XMB57$QT70`````(M%Q.F0_O__B57$BT7$Z87^__^+3=2%R0^$J````(M%"(7` +XM=!:+50B+0A"%P'0,BTW8.4AT#X0]`0``BW78B30DZ&`V_O^+50R+30B+0FP# +XM06B#P`$K0F2)06B#Q$PQP%M>7UW#QT0D"+3:"`C'1"0$`P```(M5"(D4).@2 +XMW_[_@\1,N`$```!;7E]=PXMU#(U'_XE&;(M&9.DF_?__@7MX_P````^&C``` +XM`(M3=(E5V(M#>(E%\(&+5`@````!``#I)?O__XM5V"E5W(M-W(ET)`2)5"0( +XMB4PD#(MU"(DT).@,K_[_A<`/A##____I#?W__\=$)`@$````BU4,BT(@BP") +XM1"0$BTT(B0PDZ*"I``"#Q$RX`0```%M>7UW#C4@!B4W@B4YLZ>'Z__^X`0`` +XM`.GV_/__C4-XQT0D#``!``")1"0(BT-TB40D!(M%"(D$).C:4O__AR+`8E%\`^V.(GZ@/HC#X2@````@_L!=$Z+ +XM5@3'1"0@"````(E<)!R+0@B)1"08BP*+50B)1"04BP:+0`B)%"3'1"0(```` +XM`,=$)`0`````B40D$(M%\(E$)`SHUC+__XG"Z6[___^+1?"`>`$`=:F)^H#" +XM`0^$A`$``(M-"(M1$(GY#[;!#[:,`E,'``"#^0P/AQ0!``"X`0```-/@J8`2 +XM```/A0T!``"+30R+<73I9?___XM-\`^V40&#^G\/AU#____V!)7=%`D(!`^$ +XM0O___P^V00(/MM"#^G]V%^L?C;8`````#[9!`P^VT(/Z?W<-@\$!]@25W10) +XM"`1UYX3`#X4-____BU8$QT0D(`D```"+3?")7"0?[__XM5"(M"$#'2B["`"```A?8/A&/^__^+10R+2'2+402+0@B)1"04 +XMBP*+5?")1"00BP&+30B+0`B)5"0(B5PD!(D,)(E$)`S_UHG"Z2K^__^+50R+ +XM@@! +XM="/'1"0(6-L(",=$)`0#````B1PDZ&G:_O^X`0```(/$%%M=PXU!9,=$)`P! +XM````B40D"(L"#[8`B1PDB40D!.B^RO[_@\046UW#QT0D"`0```"+02"+`(D< +XM)(E$)`3H/Z4``+@!````Z[20D)"0D)"0D%6)Y8'LB````(E=](M=#(EU^(E] +XM_(M#>,=%D)W:"`B%P'0F@^@!=`CHERO^_XUV`(M#=(L`BP")19")1"0$BT4( +XMB00DZ%=R_O_V0WT!=1J-192)1"0$BT60B00DZ!,M_O^%P`^$D0$``(M%D,=$ +XM)`BD`0``QT0D!`$&``")!"3H4"_^_X7`B<,/B#@!``#'1"0$&O<("(D$).CV +XM+?[_A<")QP^$>P$``(E$)`2+10C'1"0,`````,=$)`B"VP@(B00DZ$DR__^% +XMP`^%X0```(L=H!0)"(7;#X7#````]D<,0`^%R0```(M%",=$)`P!````QT0D +XM"([;"`B)?"0$B00DZ`HR__^%P`^%H@```(L-H!0)"(7)#X48`0``]D<,0`^% +XMB@```(M%",=$)`P"````QT0D")/;"`B)?"0$B00DZ,LQ__^%P'5GBQ6@%`D( +XMA=(/A?0```#V1PQ`=5.+10B)?"0$B00DZ*0&__^%P'5`H:`4"0B%P`^%Z``` +XM`/9'#$!U+8D\).B)+_[_A<`/A.@```#H?"S^_XLPZR.-="8`B3PDZ*PM_O^% +XMP`^$-____^A?+/[_BS")/"3H52_^_^A0+/[_B3"+19#'1"0,GZT(",=$)`0% +XM````B40D"(M%"(D$).@XW?[_N`$```"+7?2+=?B+??R)[%W#BT60QT0D#+#; +XM"`C'1"0$`P```(E$)`B+10B)!"3H!-W^_[@!````Z\KH["O^_XLPB1PDZ'(L +XM_O_KBXD\).@8+?[_A<")]@^%:O___^G;_O__B3PDB?;H_RS^_X7`#X53____ +XMC78`Z?C^__^)/"3HYRS^_X7`D`^%.O___^D(____BT60QT0D#)G;"`C'1"0$ +XM!````(E$)`B+10B)!"3H@]S^_S'`Z4G___^0D)"0D)"0D)"0D)!5B>575E.# +XM[$R+30B+10R+41R%T@^$:`,``(M(;(MP9(E-V(M`5#GPB47<#X.S`0``BUHX +XMQT74`````(7;=0CK/8L;A=MT-X![$">0C70F`'3OBT,(.?!RZ#E%W'+C@&,1 +XM_8E<)`2+50B)%"3H[[7^_\=%U`$```"+&X7;=7UW#.<@/AT7^___'1"0(X-L(",=$ +XM)`0#````BT4(B00DZ%G5_O^#Q$RX`0```%M>7UW#B?.+==R)3>"-="8`@VW@ +XM`8-]X/\/A`P"``"-3>R-1>B)3"00B40D#,=$)`@!````B5PD!(M5"(D4).B] +XMH/[_A4_?__Z<#^__^-0WC'1"0,``$` +XM`(E$)`B+0W2)1"0$BU4(B10DZ(M(__^%P`^$6O[__XE#=.NFQT0D"`0```"+ +XM0""+`(D,)(E$)`3HY9X``+@!````Z3?^__^+1=R+5=PK1*O[_BT4(BU77UW#BU4,@$W@`8M"5,=%Z`````")1>2-1>R) +XM1"00C47DB40D#(U%R,=$)!0!````QT0D"`````")1"0$B3PDZ,<+__^%P'6A +XM`W7L,=LK=<#'1U``````B7=,ZY+'1"0(!````(M5#+L!````BT(@BP")/"2) +XM1"0$Z/Z<``"#Q$R)V%M>7UW#D)"0D%6)Y8/L&(M5"/:"L`(```%T/HN"J`(` +XM`(T$0,'@`@-"$(M(.(7)#Y3`A,!T,L=$)`@,W`@(QT0D!`,```")%"3HB]'^ +XM_[@!````R<.-="8`BX*H`@``A<`/E,"$P'7.QT0D"$C<"`C'1"0$`P```(D4 +XM).A9T?[_N`$```#)PY"058GE@^PHB77XBW4,B7W\BWT(B5WTBT9TBQB+`XD\ +XM)(E$)`3HN&G^_P^W1GR)/"0E``$``(E$)`3HD(VT)@````!5B>53@^PDBUT(BT,_O^%P'00N`$```"#Q"1;7<.0C70F +XM`,=$)`0(````B1PDZ+`\__^%P'757,?]64X/L#(MU#(M% +XM"(`^`(N8F````'1IQT7P`````.LEBX,T!```#[84-XA4#P`&`^@J)@S0$ +XM``!T(H/'`8`\-P!T*8&[-`0````$``!VSXM%"(D$).A/____Z\*#QP''1?`! +XM````@#PW`'77BT7PA6#[#B+ +XM10B)??R)7?2)=?B+L)@```"-11")1?"+GC0$``")1"0,BT4,B40D"+@`!``` +XM*=B)1"0$C40>-(D$).AN(/[_B<>-!!B`?#`S"HF&-`0``'0'/0`"``!V"XM% +XM"(D$).BV_O__B?B+7?2+=?B+??R)[%W#C;0F`````%6)Y5=6B<93@^PLB4W@ +XMBTT,B57D]H`X`@```0^$`0(``(M0$(N`,`(``(T$0(M$@CB%P`^5P(3`=`.` +XMS03VAM`#```!#X3*`0``BX;(`P``C01`BT2".(E%\(M5X('A``0``(L:B4W< +XM@VT(`8-]"/\/A(\!``"+3>0/M@$\"0^$\P```#S_#X2I`0``BU80#[;`C01` +XM`<"-C`)8`0``B4WH#[:4`ET!``")5>R+31"%R74.BWWL`=\[?C@/@IP```"+ +XM5>PQ_X72=7?IGP```)"+11"%P'4'BU7H#[8$%XE$)`C'1"0$BNP("(DT).B. +XM_O__BT80]H!4"```!`^%`P$``,=$)`P!````QT0D"`````#'1"0$`````(DT +XM).A^D?[_AQT+3E>.'6*QT0D +XM!":Z"`@QVXDT).B8_?__Z7/___^+1>B)^XDT)(E$)`3H@OW__X-%Y`'I\?[_ +XM_XM]W(7_#X4*____.UXX<^`QP(D9@\0L6UY?7<.+AL@#``")1?#I./[__XN`,`(``(M6 +XM$(7`#Y7`Z0'^___'1"0$_P```(DT).@;B/[_QT0D!/\```")-"2)1>CH"(K^ +XM_XE%[.E,_O__58GE5U93@^PLBUT(QT7L`````(MU#/:#F`(```$/A($```"+ +XM@Y`"``"-!$#!X`(#0Q"+0#B%P`^5P(3`=#&-3>RZLMP("(G8QT7PLMP(",=$ +XM)`@`````QT0D!`````#'!"0(````Z#7]__^%P'4HC57PC47HB40D$(E4)`S' +XM1"0(`0```(L&B1PDB40D!.@ME_[_AS'1"0$`````(M&!(GYB00DB=CHROS__X7` +XM=;V+5?"+11`#5@2)5?"+2`2+1@2^`0```#G!=`2)SBG&B?F)V,=$)`A>```` +XMQT0D!`````")-"3HB_S__X7`#X5Z____BT,0]H!4"```!`^%:O___\=$)`P! +XM````QT0D"`````#'1"0$`````(D<).CSCO[_A____\=$)`0FN@@(B1PDZ"KZ__\QP.EF____ +XMC78`QT0D"`````"+11B-312)%"0E``0``(E$)`2+50R)V.@,^___A<`/A"G_ +XM__^#Q!2X`0```%M=PXM#$/:`5`@```0/A1K____I3/___XE$)`2-312Z+?`( +XM"(G8QT0D"`````#'!"0!````Z,+Z__^%P`^$,/___^NTD(VT)@````!5B>57 +XM5E.#[#R+=0B+?1B+1AR%P`^$@P$``(M%$(M5%(L8BQ(YTXE5S`^'5P$``(GX +XM)0`"``")1=#IX````(GVQT7HPMP("(M5Z(U-\(GPQT0D"`````#'1"0$```` +XM`,<$)`@```#H1?K__X7`#X4=`0``C47LB40D$(U%Z(E$)`S'1"0(`0```(E< +XM)`2)-"3H.Y3^_X7`#X7S````BU7LA=)U#/?'``0```^$M@```(E\)!"+1?") +XM5"0(B40D#(M%Z(DT)(E$)`3H\OW__X7`#X6Z````BT80]H!4"```!`^%H``` +XM`,=$)`P!````QT0D"`````#'1"0$`````(DT).A*C/[_A +XMB5PD#,=$)`B[W`@(QT0D!`H```")%"3H:1S^_XU%WHE%Z.GA_O__QT0D!":Z +XM"`B)-"3H*OC__XM&$/:`5`@```0/A&#___^#Q#PQP%M>7UW#N`$```"#Q#Q; +XM7E]=P\=$)`@$````BU4,BT(@BP")-"2)1"0$Z(>2``"X`0```.O558GE5E.# +XM[""+70R+=0@/MT-\B5PD!(DT)(E$)!"-0VR)1"0,C4-DB40D".@0_O__N@$` +XM``"%P'4.BT-L,-*)1DR+0W")1E"#Q"")T%M>7<-5B>564X/L((M=#(MU"`^W +XM0WR)7"0$B30D@,P"#[?`B40D$(U#;(E$)`R-0V2)1"0(Z+K]__^Z`0```(7` +XM=0Z+0VPPTHE&3(M#<(E&4(/$((G06UY=PXUV`(V\)P````!5B>564X/L((M= +XM#(MU"`^W0WR)7"0$B30D@,P$#[?`B40D$(U#;(E$)`R-0V2)1"0(Z%K]__^Z +XM`0```(7`=0Z+0VPPTHE&3(M#<(E&4(/$((G06UY=PY"0D)"0D)"0D)!5B>53 +XM@^PTBUT(BTT,BT,575E.#[#R+?0B+1Q")1=2+112+EY@```")5="+ +XM,,=%V`````#'1=P`````QT7@R]P(".G/````C;8`````BUW8NA^%ZU&#PP&) +XMV/?BP>H%:])D.=-U=XM'$/:`5`@```0/A;X```#'1"0,`0```,=$)`@````` +XMQT0D!`````")/"3HUXC^_X7`=1"+1Q#V@%0(```$#X6*````BT4")/"2)1"0$_]+'1>``````BT7P +XMBU70B40D$(M"+(ET)`C'1"0$`0```(D\)(E$)`SH.Y?^_X7`#X7L````BT7P +XM@\8!`47R)1"0(BT4,B3PDB40D!.@IM_[_ +XMBU7R%TG08A?]T#(M'$(7`=`4[6'1T>XD<).AR&O[_,=OK28M%$(D$).B3&/[_ +XMA<`/A%G___^+50R[`0```,=$)`R?K0@(QT0D!`4```")/"2)5"0(Z#/(_O^+ +XM11")!"3H'!K^_XM%'(7`=1R+5=3'1"0(`@```,=$)`0`````B3PD_Y)H"``` +XM@\0\B=A;7E]=PX&@5`@``/_^__\QV^O,C;8`````C;PG`````%6)Y8'LJ``` +XM`(E]_(M]"(E=](M5##';B77XBT<0B85X____BT)XAL +XM!```J`(/A:D"``"+10SV@((````@#X0C`P``BT!TBP28BP#'1"0$(+H("(D\ +XM)(E$)`CHW_'__XD\).CW\/__BX>L!```J!!U"PT```@`B8>L!```J`)T)HN5 +XM>/___\=$)`0!````B3PD_Y*@"```A<`/A2$#``"#CZP$```4BU4,QT0D&`(` +XM``"+0G2+E73___^+!`*+`,=$)`P`````B3PDB40D%(U%Z(E$)!"+10R#P&2) +XM1"0(BT4,B40D!.A#P___A<`/A1,!``"+50PQR8.*@````$"+5>CVAZP$```" +XMB5=,#X2M````QT=0`````(U'4(E$)`B)5"0$B3PDZ-(S__\QR>F,````BX5\ +XM____BU4,B70D"(D\)(E$)`R)5"0$Z&Z1__^%P`^%K@```(M5#(M">(7`>!*# +XM^`$/CB+]__^#^`(/A)\!``"+50S'1"0(`0```(M"=(L`BP")/"2)1"0$Z+R* +XM``"Y`0```.LFD(UT)@#'1"0,GZT("(ET)`C'1"0$!0```(D\).B$Q/[_N0$` +XM``"+7?2)R(MU^(M]_(GL7_S__XM5#(M"9`-%\(E'3.D`____BX=<`P``BY5X____ +XMC01`BT2".(7`#Y7`Z>7[__^+50SV@H(````@#X2!_?__BT)TBP28BP#'1"0$ +XMU=H("(D\)(E$)`CH5J(!`(N'K`0``.E:_?__BU4,BT)TBU`$BT<@BS(/MT`8 +XM)80```"#P(`/A*````")="0$B3PDZ']6_O_INOO__XD<).CV$_[_B?;IS/[_ +XM_XM5#,=$)`@)````BT(@Z1[^___'1"0$);H("(D\).@X[O__Z>3\__^)="0, +XMQT0D"#3="`C'1"0$`P```(D\).B7O?[_Z;#^___'1"0("@```(M"((M`$(D\ +XM)(E$)`3HF(@``+D!````Z?_]__^+50S'1"0(`P```(M"(.FQ_?__BT((B70D +XM!(D\)(E$)`CH>##__X7`B<-T%(M'((M`"(D$).A(%/[_BT<@B5@(BT<@9H%@ +XM&#__BT<@9H-(&`R+5Q#'1"0(`0```(M'((M`"(D\)(E$)`3_DIP(``#IROK_ +XM_\=$)`@`````QT0D!`4```")/"3HXKS^_[D!````Z6G]__^0D)"0D)"0D%6) +XMY5=64X/L+(M]"(M'$(MP$(U0$(E5Y#G6#X39````QT7H`0```,=%[`````#' +XM1?``````ZT&#?>@!=!?'1"0$TM0("(D\).@#[?__QT7P`0```(M&((M`"(D\ +XM)(E$)`3HZNS__XLV.77D#X2O````@T7H`8M'$/:`5`@```0/A8P```#'1"0, +XM`0```,=$)`@`````QT0D!`````")/"3H6X#^_X7`=0R+1Q#V@%0(```$=5R+ +XM1B"+0`B)!"3HT1/^_XM=\`'#`5WLBT7UW#C78`C;PG`````%6)Y5.#[!2+30R+70@/MT%\@^`<@_@, +XM=%>#^!1T,H/X!+H"````="W'1"0("@```(M!((M`$(D<)(E$)`3H+H8``(/$ +XM%+@!````6UW#C78`N@$```")5"0(BT%8B1PDB40D!.A(Z@$`@\046UW#B?8Q +XMTNOAC;8`````C;\`````53'`B>564X/L((M5#(MU"(N:@````(M*>('C``$` +XM`(7)=`>+0G2+`(L`B40D"(U%](E<)`R)1"0$B30DZ-_T`0"Z`0```(7`=18P +XMTH7;=!"+1?2!CJP$````$```B484@\0@B=!;7EW#C;0F`````%6)Y5WIQ^\! +XM`)"0D)"0D)!5B>56B=93BY"`````B0` +XM````BU@(N`$````Y^W1),?;V@Z\$```!=#6+@X````"+2`2X`0```(G*@^$? +XMP>H%T^`)A)58____BX.`````BT`$.?!^"8G&C;0F`````(L;.?MUO(U&`8U5 +XMX(E4)!"-E5C____'1"0,`````,=$)`@`````B50D!(D$).C"!_[_@_C_=!&% +XMP'4U,<"!Q%P!``!;7E]=PXD<),=$)`B*W0@(QT0D!`4```#H8+?^_X'$7`$` +XM`+@!````6UY?7<.+A;S^__^+<`@Y_@^$"O____:&KP0```$/A`H!``"+AH`` +XM``"+2`2)R(/A'\'H!8N$A5C____3Z*@!#X3H````C57PB50D!(DT).CQA/[_ +XMA<`/A<<```"%]@^$V````(M>$(7;#X3-````]H-5"````0^%P````(%[>/\# +XM```/AFX#``"+0W2)A<#^__^+0WB)1>R!BU0(`````0``BYW`_O__BY:````` +XMB=B#P`&)ES'1"0,``0``(E$)`C'1"0$`````(DT).B3*O__ +XMAS'1"0$_P```(DT).C0=?[_@_@(#Y3"@_@,#Y3`Z[['1"0(A-T("+L!```` +XMQT0D!`4```")-"3HU;3^_^ER_O__.=@/AAL!```IV(G:B87$_O__C47HB00D +XMBXW$_O__B?#H6_K__X7`=`N+3>B%R0^$J0```,=%V`````"X(````,=%W*"& +XM`0#'A(74_O__`````(/H`77PBY7(_O__N`$```"+2@2)RH/A'\'J!=/@"825 +XMV/[__XU%V(E$)!"-A=C^___'1"0,`````,=$)`@`````B40D!(N5R/[__XM" +XM!(/``8D$).A9!/[_@^@!=2V+A<3^__^)7"0$B40D"(N5P/[__XD4).CH"?[_ +XMBYW`_O__`YW$_O__Z5W]__^+C<3^__^)VHGPZ/3Z__^%P`^%JOW__XM%\(U0 +XM`8E5\(N5Q/[__XE<)`R)1"0(QT0D!`$```")5"00B30DZ+&&_O^%P'4VBT7P +XMB49,BY7$_O__@^H!@[W$_O__`1G`]]`APHE64,=$)`0!````B30DZ%ZV`0") +XMP^D9_?__NP$```#I#_W__X&@5`@``/_^___I*/W__XU#>,=$)`P`!```B40D +XM"(M#=(DT)(E$)`3HX"?__X7`#X0&_?__B4-TZ63\__]5B>6#[$B)=?B+=0B- +XM1?")7?2)??R)1"0$B30DZ/^`_O^%P'0;NP$```")V(MU^(M=](M]_(GL7<.- +XMM"8`````C47DB40D$(M%\(U]V(E\)`S'1"0(`0```(DT)(E$)`3H>W[^_X7` +XM=;R+3>2-1>"+5=B)!"2)\.AD^/__A$(7; +XM#X3<````]H-5"````0^%SP```(M%Y(/H@#M#>`^'E0$``(M3=(E5T(M#>(E% +XM[(&+5`@````!``"+1>2)1"0(BT78B40D!(M%T(D$).@O"/[_QT7,`0```.L) +XMB?;'1")!"2)\.@%]___AB+1>B+OH`` +XM``")1"0(BT78B40D!(M'!(D$).C``/[_.T7HB<-T9X7;=%;'1"0(A-T(",=$ +XM)`0%````B30DZ/FP_O_I`____X&@5`@``/_^___IW_W__XE$)`R-0WB)1"0( +XMBT-TB30DB40D!.AK)?__A<`/A+C]__^)0W3I0?[__^BZ!/[_QP`%````ZYW' +XM1"0(`0```,=$)`0FN@@(BT<$B00DZ#<`_O^#Z`$/A77___^+?$(7;=%N+5=`Y4W1T4XM%Y`-%Z#M%['=UBT7H,=N)1"0(BT78 +XMB40D!(M%T`-%Y(D$).@E!O[_BT7D`T7HB30DB40D#(M%T(E$)`B+1?")1"0$ +XMZ(&`_O^%P`^5P^DV_O__@:-4"```__[__XM%Y`-%Z#M#>'="BT-TB470BT-X +XMB47L@8M4"`````$``.N+BU70B40D#(U%[(E$)`B)-"2)5"0$Z'`D__^%P`^$ +XMO?S__XE%T.EA____B40D#(U#>(E$)`B+0W2)-"2)1"0$Z$8D__^%P`^$D_S_ +XM_XE#=.N7B?:-O"<`````58GE5U93@>S,!```BU4(BT4,]H*L!````@^$"@(` +XM`(M0>(72=!.)1"0$BTT(B0PDZ&NN__^%P'4?QT0D"`````#'1"0$-````(M% +XM"(D$).@\N/[_A% +XM8/O__ZO="`BX<````+^QW0@(HO@0"0CI@P```,8%]1`)"'3H8`7^_XN55/O_ +XM_\<$)/`0"0B)5"0(B40D!.B6!?[_QT0D!)`!``#'!"3P$`D(Z.($_O_'!"3P +XM$`D(Z,8"_O_'1"0(`````,=$)`0"````QP0D\!`)".BJ`_[_@_C_B<8/A2(! +XM``")'"3H9P+^_P^V!X/'`83`#X3A````Q@7U$`D(<`^V1__'1"0(`````,=$ +XM)`0"````QP0D\!`)"*+Y$`D(Z%T#_O^#^/^)PP^%1O___^B-`?[_@S@"=;'' +XM1"0(7`H)",=$)`0%````BT4(B00DZ&FM_O_K0\=$)`@`W@@(QT0D!`,```") +XM%"3H3ZW^_X'$S`0``+@!````6UY?77UW#BXU@^___#[9!`8/!`8F-8/O__X3` +XM#X5R_O__Z,@`_O_'``(```#I-?___XN-3/O__XE!"(G(@\`4B5D$=!#'1"0$ +XM\!`)"(D$).BJ!/[_BX50^___A`'^_\=$)`@!````QT0D!,?="`C'!"3.W0@(Z%P!_O_'1"0(`0```,=$ +XM)`3-H0@(QP0DUMT(".A``?[_Z`L"_O_'1"0(`````,=$)`1A=``@BXU,^___ +XMBT$(B00DZ`K]_?^+E4S[__^+0@2)!"3H.0#^_\=$)`0`````BXU,^___BT$( +XMB00DZ,#\_?_'1"0$`0```(N53/O__XM""(D$).BG_/W_QT0D!`(```"+C4S[ +XM__^+00B)!"3HCOS]_XN53/O__XM""(D$).C=__W_BTT(]H%P`P```0^$V@$` +XM`(N!:`,``(T$0,'@`@-!$(M8.,=$)`0O````B1PDZ`O^_?^)VH7`=`.-4`&) +XM5"0$QT0D#`````#'1"0(G-X("(D<).@6_/W_QT0D#.FY"`B)7"0(QT0D!`4` +XM``"+50B)%"3HXZ_^_\<$)'\```#HRP#^_\=$)`@`````QT0D!`4```"+50B) +XM%"3HK*K^_[@!````Z6_[__\QP(VU:/___\=$AGP`````@^@!@_C@=?"+30BX +XM`0```,=%Z`4```#'1>P`````BXF`````B8U8^___BTD$BB)5"00QT0D#`````#'1"0(`````(ET)`2+C5C[__^+002#P`&) +XM!"3H6?K]_X/X_P^$Z````(7`#X3#````C85H^___B85$^___B<.+A43[__^) +XM7"0$*=@%``0``(E$)`B+E5C[__^+0@2)!"3HY`'^_X/X_P^$KP$``(7`#X6[ +XM````QT0D".W="`C'1"0$`P```(M-"(D,).BTJ?[_BT4(B00DZ/GO__^X`0`` +XM`.EL^O__QT0D"&.+"`C'1"0$!0```(M%"(D$).B$J?[_Z5O\___'1"0(UKD( +XM",=$)`0%````BU4(B10DZ&2I_O_I._S__XM%"(N8:`,``.DJ_O__QT0D"-S= +XM"`C'1"0$`P```(M-"(D,).@VJ?[_ZX#'1"0(BMT(",=$)`0%````BU4(B10D +XMZ!FI_O_I8/___P'#.9U$^___#X,Q`0``C95H^___C;UI^___B95<^___ZV:- +XM3?")3"0$BT4(B00DZ-!V_O^%P`^%)/___XU'_RN%7/O__XE$)!"+E5S[__^) +XM5"0,BT7PQT0D!`````")1"0(BTT(B0PDZ*=[_O^%P`^%Z_[__XF]7/O__XGX +XM@\EC____BU4(BT(0@+A2!P``_W6MB10DQT0D!/\` +XM``#H!FG^_X/X"`^4PH/X#`^4P.O"QT0D"(3="`C'1"0$!0```(M%"(D$).@- +XMJ/[_Z53^__\YA43[__]S*RN=7/O__XV5:/O__XE<)`B+A5S[__^)%"2)1"0$ +XMZ,+]_?^-C6C[__^-'!DYG43[__\/A,/]__^-1>C'1>@`````QT7LH(8!`(E$ +XM)!#'1"0,`````,=$)`@`````B70D!(N56/O__XM"!(/``8D$).C`]_W_@_C_ +XM#X23````@^@!#X1T_?__C47PB40D!(M%"(D$).A8=?[_A<`/A:S]__\KG43[ +XM__^-E6C[__^)5"0,B5PD$(M%\,=$)`0`````B40D"(M-"(D,).@R>O[_A<`/ +XMA7;]__^+10B)V8V5:/O__^@J[O__A<`/A=KW__^+50B+0A"!BJP$```````! +XM@XA4"```(#'`Z<'W__^-="8`QT0D"(K="`C'1"0$!0```(M-"(D,).C5IO[_ +XMZ1S]__]5B>6#[!B+50R+30B+0GB%P'44QT0D!`(```")#"3H/;/^_S'`R<.+ +XM0B"+0!")1"0(BT)TB0PDB40D!.A@O/[_R87`#Y7`#[;`PY"0D)"0D%6)Y5=6 +XM4X/L/(M]#(M=$(UU[.AM^OW_QP``````QT0D"`````")="0$B3PDZ//V_?^# +XMP`%U-.A)^OW_@S@$B?9TT,=$)`@TW@@(QT0D!`4```"+10B)!"3H(Z;^_[@! +XM````@\0\6UY?7<.+5>R)T(/@?X/X?P^$O0$``(7`#X3^````BWT8A?]T#(/X +XM#8UV``^$H@$```^V`SP@#X2'`0``/`D/A'\!``"-1?"_/-X("(E<)`2)1"0( +XMBU4(B10DZ#R9_O^)!"2)P^AV_?W_B<:+1>R$P'@%OT^-"`B)PKB@X`@(@^)_ +XMZPX]F.$("`^$3P$``(/`"#L0=>Z+0`2#_A2Z/O$("'<%ND^-"`B#_A2)1"08 +XMB?")?"0EF_O__@\,!Z5____^#Q#PQP%M>7UW#B50D#,=$)`A*W@@( +XMQT0D!"@```#'!"1`(0D(Z,+X_?^X0"$)".F1_O__N4^-"`CI9?___X&@5`@` +XM`/_^__^X`0```.G8_?__C;8`````58GE4X/L%(M%"(M8$,=$)`@`````QT0D +XM!#0```")!"3HRZS^_[H!````A<`/A58!``"+50CV@JP$```"#X5.`0``BT48 +XMA<`/A80!``"+112%P'0EBU44B50D!(M-"(D,).@*U/__QT0D!":Z"`B+10B) +XM!"3H]]/__XM5"(D4).B]OW_A<"-4`$/ +XMA+H!``"$VP^$I`$``(M-"(N!:`,``(T$0,'@`@-!$(M`.,=$)!``````BTT0 +XMQT0D"-NY"`B)5"0$B00DB4PD#.@#]/W_BT4(]H!P`P```0^$3@$``(G"BX!H +XM`P``C01`P>`"`T(0BT`XQT0D#.FY"`B)1"0(QT0D!`4```"+10B)!"3HK*?^ +XM_\<$)'\```#HE/C]_\=$)!``````QT0D#`````"+51")1"0$B50D"(M-"(D, +XM).CJ^___B<*#Q!2)T%M=P\=$)`0!````B10D_Y.@"```A\=$)`@"```` +XMBTT,BT$@BP")1"0$BT4(B00DZ$QM``"#Q!2Z`0```%N)T%W#QT0D!":Z"`B+ +XM10B)!"3HC-+__XM%%(7`#X5E_O__Z87^___'1"0(U;D(",=$)`0%````BTT( +XMB0PDZ.&A_O^#Q!2Z`0```%N)T%W#C70F`,=$)`@`````QT0D!`````"+50B) +XM%"3_DUP(``"+30B#B:P$```4BT48A<`/A/S]___I>____XG"BX!H`P``C01` +XMP>`"`T(0BT`XZ4?^__^+30B+@6@#``#IN/[__XM-"(N!:`,``.EC_O__A-MT +XM'(M5"(N":`,``(T$0,'@`@-"$(M`.(G"Z2;^__^+30B+@6@#``")PND6_O__ +XMD(UT)@!5B>564[L!````@>P@!```BW4(QT0D"`````#'1"0$-````(DT).@% +XMJO[_A<`/A:D```#VAG`#```!#X6H````BX9H`P``C9WX^___B1PDB40D#,=$ +XM)`B9W@@(QT0D!``$``#H;/7]_XM&$,=$)`@`````QT0D!`````")-"3_D)P( +XM``"+AJP$``")7"0(QT0D#`````")-"2#\!#!Z`2#X`&)1"00BT4,B40D!.B. +XM_/__BU80QT0D"`$```")PXM&((M`"(DT)(E$)`3_DIP(``"!CJP$``````@` +XM@<0@!```B=A;7EW#BX9H`P``C01`P>`"`T80BT`XZ4?___^058GE5XG'5E.# +XM[%R)5<")3;R+6!R%VP^$$`4``/:`B`,```%U,8N0@`,``(72#Y3`A,!T/<=$ +XM)`B@X0@(QT0D!`0```")/"3HY)_^_S'`@\1<6UY?7<.+@(`#``"-!$#!X`(# +XM1Q"+2#B%R0^4P(3`=WC_````#X9^!```BW-TB77@QR<=%T`````")1;CK,HN'R`,``(T$0,'@ +XM`@-'$(M0.(T$"HG6B46T,=*)R/?VBTVT@T70`2G1.5W0#X2[````BU70BW6X +XM#[8$,CP@#X29````/`D/A:$```#VA]`#```!=:N+E\@#``#KM<=%\`````"- +XM1?#'1"0,``$``(E$)`C'1"0$`````(D\).BZ$O__A<")1=P/A>[^__^#Q%RX +XM`0```%M>7UW#QT74`````(N/@`,``(T<2?:'B`,```&)R'0-C02=``````-' +XM$(M`.(/"`0%%U(E5Z`^V`CP^=-@\/`^%7O[__^O.@T70`8/!`3E=T`^%1?__ +XM_X-]O`$/A.8!``")SBMUU#M-U!G`]]`AQCGQ#X3;`0``A?_'1>``````#X2& +XM`0``BT<0A<")1>`/A'@!``"+5=PY4'0/A&P!``"-!!X[1?`/A[X!```/MH_0 +XM`P``BY?(`P``BUWPK7=R)7"0,BW7"+5>"+0'2)1=R+0GB)1?"!BE0(`````0``Z67^ +XM__^+1=2--`'I)?[__XM5Q#E73`^%M_S__\=%V`$```#IJ_S__XE$)`R-1?") +XM1"0(BU7(E$ +XM)`B+0G2)/"2)1"0$Z/,=$ +XM)`P``0``B40D"(M#=(D\)(E$)`3H.P___X7`#X2$_/__B4-TZ53[__^!H%0( +XM``#__O__N`$```#IE?K__X&@5`@``/_^___I-/[__Y"-M"8`````5;D!```` +XMB>6+10B+50Q=Z1SZ__^-M@````"-OP````!5,"N-192)1"0$B1PDZ!OR_?^%P'48 +XMBU7(BT7$@_H`?$A^/.C%[?W_QP`,````BU4(QT0D#)^M"`B)="0(QT0D!`4` +XM``")%"3HK)[^_[@!````BUWTBW7XBWW\B>Q=PST``!``=[V-=@"#P`&)!"3H +XMZ>_]_X7`B460=&F+59"+1<3&!!``B50D!(E$)`B)'"3H6/']_XD<)(G'Z-[M +XM_?^#__]T+HM5R(G[BT7$P?L?,=HQ^`G"=%KH,>W]_\<`!0```(M%D(D$).@P +XM\/W_Z5S___^+5N?]_XD$ +XM)(G&Z%#N_?^%P(G#=$J)="0,B7PD!(E$)`B+1>R)!"3H4^?]_XE<)`S'1"0( +XMO^$(",=$)`0#````BT7PB00DZ*"7_O^+=?B)70B+??R+7?2)[%WIH.[]_XM% +XM\,=%$`````"+7?3'10P%````BW7XBWW\B44(B>Q=Z6>7_O^-M"8`````58GE +XM5U93@^P\]D4@$<=%V``````/A;P```"+10CV@+0!```!#X55!```BTT(BX&L +XM`0``A<`/E<"+70@/ML")1=CV@_P!```!#X1B!```BX/T`0``C01`P>`"`T,0 +XMBT`XA<`/E<"$P'0$@TW8`HM%"/:`\`$```$/A"`$``")PHN`Z`$``(T$0,'@ +XM`@-"$(M`.(7`#Y7`A,!T/(MU$(7V=#&+'?P@"0B+-0@A"0B+31"+50SK`X/" +XM`0^^`H7`>`PYV'T(9H-\AC0`>`N#Z0&)]G7C@TW8`HM=((/C`HE=T'00BWT( +XM]H>N!```0`^%>@4``(M%((/@"(E%U'00BU4(]H*N!```@`^%?04``(M=%(7; +XM#X01`@``]D4@`0^$6@(``(M-$+@W````A+?0B+7Q"%VW0-]H-5"``` +XM`0^$.`4``(7`QT7P``````^%HP<``,=%X`````"P`;X:````BUW@Q@->QP`H +XM6R`)QT`$77PO7,=`""HH6U['0`PJ77QMXD(UT)@`/OL.)1"0$QP0DS.$(".CQY_W_A@\8!@VT0`71%@T4,`8M]#`^V'X#[('7#QP8H6R`)QT8$77PO7,=&""HH +XM6U['1@PJ77QO]_XM-%(L!Q@0X`(7V="B+70B%VW06BUT(BT,0A7UW#]D4@$`^$/@$``(M% +XM"(7`#X1R`P``BTT(BUD0A=L/A&0#``#V@U4(```!#X57`P``BT40`<`[0W@/ +XMAP\(``"+0W2)1>"+0WB)1?"!BU0(`````0``BT40A<`/A?4$``"+50P/M@+' +XM1=P`````/%Z+=>`/A%H&``"+11"%P'5T#``")]@^V00&)SX/'`3PO#X2_ +XM`P``/#\/A+<#``"-M"8`````#[[#B40D!,<$)-OA"`CHH>7]_X7`=`S&!ER+ +XM10R#Q@$/MAB('H/&`8-M$`$/A)D#``")?0R+30P/MAF`^UQTH(M]#(/'`>NX +XM]D4@!`^$V0$``(/$/+@!````6UY?7<.)PHN`K`$``(T$0,'@`@-"$(M`.(7` +XM#Y7`Z9O[__^+30B+N>@!``"%_P^5P.GF^___BWT(BX?T`0``A<`/E<#IHOO_ +XM_XM%$#'VNP$```"%P`^$:P$``(M5$##;BTT,ZQR0/"H/A.T````\+@^$Y0`` +XM`(/&`8/J`71:@\$!#[8!/%L/A,\```!^V#Q<#X2`````/'YUW(M]"/:'4`(` +XM``$/A.D```"+AT@"``"-!$#!X`(#1Q"+0#B%P`^5P(3`=+2+70@#L^0```"# +XMZ@&[`0```'6FA=L/A)L!``"+70B%VW07BU4(BUH0A=MT#?:#50@```$/A$(% +XM```Q_X7VQT7P``````^%$@8``(G[Z>D!``"#^@$/AE?___^#P0&#Z@$/M@$\ +XM/'0@#XXL`0``/%L/A``$```\?@^$GP,``#P^B?8/A2(!``"#Q@B[`0```(GV +XMZ1[___^+?0CVAU`"```!=#^+AT@"``"-!$#!X`(#1Q"+0#B%P`^4P(3`#X3S +XM_O__@\8"NP$```#IYO[__XM%"(N`2`(``(7`#Y7`Z1O___^+10B+N$@"``"% +XM_P^4P.O(*?N^`0```(E=$(/#`8E]#(M]#(E]X.E$_/__B7PD"(E$)`2+10B) +XM!"3HXOC__X/$/+@!````6UY?7<.)^`6P````B00DZ"KG_?^!IZP$``#__[__ +XMZ6CZ__^)T`7(````B00DZ`SG_?^+30B!H:P$``#__W__Z6+Z__\Y0W@/@C0$ +XM``"+2W2)3>"+0WB)SH/&&HE%\(G(@8M4"`````$``(/``>FW^O__/"H/A-0" +XM```\+@^$S`(``(/&`I"-="8`Z?[]__^+71`Q]H/#`>D^____BT40QT7P```` +XM`,=%X``````!P`^$M/S__XE$)`R-1?")1"0(QT0D!`````"+70B)'"3HQP3_ +XM_X7`B47@#X6+_/__Z2G]__^-M"8`````@/HJ#X07`0``@/HNC70F``^$"@$` +XM`(@3@\,!@VT0`0^$N_[__X-%#`&+10P/MA"`^EL/A.@```!^QH#Z7'1^@/I^ +XM==*+30CV@5`"```!#X0(`0``BX%(`@``C01`P>`"`T$0BT`XA<`/E<"$P`^% +XM+0(``,8#?H/#`>N@D(UT)@"+?0R)PX-M$`&('H/&`8/'`H-M$`$/A6?\__^+ +XM1=R%P'0&Q@8D@\8!*W7@B?.)=1"#PP&^`0```.F"^O__@WT0`0^&<@(``(-% +XM#`&+30R#;1`!#[81@/H\#X0_`P``#X_I`0``@/HJ=`V`^BZ-="8`#X7R`0`` +XMBTT(]H%0`@```0^$L@,``(N!2`(``(T$0,'@`@-!$(M`.(7`#Y7`ZR20BTT( +XM]H%0`@```71#BX%(`@``C01`P>`"`T$0BT`XA<`/E,"$P`^$R_[__\8#7(M- +XM#(/#`0^V$>FZ_O__BT4(BX!(`@``A<`/E<#I_/[__XM%"(N`2`(``(7`#Y3` +XMZ\2+30R+71"+50P/MD09_X/J`3PO#X2)`0``/#\/A($!```\),=%W``````/ +XMA(8"``"+?0P/M@<\+W0(/#\/A=;Z__^#10P!BU4,@VT0`0^V`NG#^O__B40D +XM#(U%\(E$)`C'1"0$`````(M%"(D$).B^`O__A<`/A"C[__^)1>"+=>"#P`&# +XMQAKI-/C__XM]"/:'4`(```$/A#P!``"+AT@"``"-!$#!X`(#1Q"+>#B%_P^4 +XMP.FT^___QT0D"`````#'1"0$!0```(M-"(D,).B^C?[_BUT4BP.%P`^%'OG_ +XM_^DX^?__BWT(]H=0`@```0^$T````(N'2`(``(T$0,'@`@-'$(M`.(7`#Y3` +XMA,`/A!#[__^#Q@&[`0```.D#^___BTT(BY'@````BX'D````B1PDB50D!(E$ +XM)`CH]>/]_XM%"`.8Y````.E._?__@/I;#X0@_O__@/I^#X3]````@/H^#X3< +XM````Q@-"#10P!@VT0`8/&`>F0^?__ +XM@:!4"```__[__^FG^/__@VT0`75DBWT,#[8'QT7<`````.E>^?__Q@-<@\,! +XMZ=?\__^+10B+@$@"``"%P`^4P.DT____BT4(BX!(`@``A<`/E,#I@?K__SMS +XM>`^'6`$``(M#>(M[=(E%\(&+5`@````!``#IKOK__XM-$`^V!!'I"?[__XE$ +XM)`R-0WB)1"0(BT-TB40D!(M5"(D4).C\`/__A<`/A&;Y__^)0W3IG_O__\<# +XM6ULZ/F;'0P0Z7<9#!EV#PP?I/_S__XM%"/:`4`(```$/A+D```")PHN`2`(` +XM`(T$0,'@`@-"$(M(.(7)#Y7`A,`/A6;\__^+10B+D.````")P>F,_O__QP-; +XM6SH\9L=#!#I=QD,&78/#!^GF^___@VT0`0^$N0```,=%W`$```#I9/W__XU% +XM\(ET)`R)1"0(QT0D!`````"+30B)#"3H1P#__X7`B<%N/[__P````#'A;S^__\`````QX7`_O__`````,>% +XMQ/[__P````"#Y@&)C93^__^#Z`D\:793BY6@_O__NP$```#'1"0("@```(M" +XM((M`$(D\)(E$)`3H/E4``('$?`$``(G86UY?7<.+AWP!``"-!$#!X`(#1Q"+ +XM6#B%VP^4P.E$____D(UT)@`/ML#_)(6TX@@(A?8/A2`5``#VAZX$``!`#X0U +XM%0``BXV4_O__QX7$_O__`0```(E-"(N%$/___X/``8F%$/___P^V`(3`#X5: +XM____BY7$_O__A=(/A*80``#VAZP$```"="&`O_0`````=!B+A;S^__\+A;C^ +XM__\+A<#^__\/A2T2``"+C:#^___'1?``````BX6@_O__BTEDB8T,____BT!L +XM.<&)A:3^__\/A_\4``"+1Q#V@%0(```$#X7O%```BY6\_O__BXW`_O__"Y6X +XM_O__QX70_O__`````,>%U/[__P`````)RL>%V/[__P````#'A0C___\````` +XMQX4$____`````(F5F/[__\=$)`P!````QT0D"`````#'1"0$`````(D\).CS +XM3/[_A\.``"+C0S___^-1>R-E1#___^)1"00B50D +XM#,=$)`@!````B4PD!(D\).@T5/[_A<`/A7,%``"`O_0`````=&:+A=C^__^% +XMP`^$BA(``#';A?\/A'H/``"+7Q"%VP^$;P\``(N5V/[__SE3=`^$8`\``(M5 +XM[#M5\`^'PQ```(E4)`B+A1#___^+E=C^__^)1"0$B10DZ+W>_?^+C=C^__^) +XMC1#___^+1>R[`0```#'VQX6P_O__`````,>%R/[__P$```#'A%&/___P````#' +XMA1S___\`````B8T@____BTT(B40D$(N%L/[__P.%$/___\>%)/___P````") +XM5"0,QT0D"`H```")1"0$B0PDZ.C:_?^#^`$/A$$#``"%P`^%%!4``(.-S/[_ +XM_P&%VP^%!`(``(N%&/___PN%'/___P^%\@$``(N%(/___PN%)/___P^%X`$` +XM`(N%K/[__X7`#X1M#P``BYT`____@\,!.YT(____=DF!^P`!``")V',%N``! +XM```!A0C___^+A03___^%P`^$O!0``(N%"/___XN5!/___XE$)`2)%"3H>MC] +XM_X7`#X1`$0``B84$____BX6P_O__`X40____BXT`____BY4$____#[8`B`01 +XM@X6P_O__`8.MK/[__P&)G0#___^[`0```,>%T/[__P$```#IK?[__\>%P/[_ +XM_P$```#IM?S__\>%N/[__P$```#IIOS__X"_]0`````/E(?U````Z9/\__^` +XMO_0`````#Y2']````/:'K`0```$/A'C\__^-1=2)1=2)1=CI:OS__X72#X7= +XM^___Z!_:_?_'``````"-A1#___^)1"0$BX40____QT0D"`H```")!"3HR=C] +XM_XG#BX40____@#@`=0F#Z`&)A1#____HWMG]_X,X(@^$5Q$``(N5H/[__XM" +XM;(E"9(/H`0'8B4)LB40D!(D\).@!4_[_AC[__^+C:#^__^#:5P! +XMZ=G[__^+A:#^__^#0%P!ZB+A;#^__\#A2#___^)3=R)3>2)1>"+1>R% +XMP'4.QT7@`````,=%Z`````#VAZP$```"#X1&`@``BU7L.57@<@:-0O^)1>`Y +XM5>AR!HU"_XE%Z(M%Y,=$)`0!````B3PDB4=,BT7HB4=0Z**'`0"%P`^%L0$` +XM`,=$)`@`````C5VXQT0D!`GB"`B)/"3HGWK^_\=$)`@`````B3PDB40D!.B[ +XM:`$`QT0D#`````#'1"0(`````(E<)`2)/"3HGTC^_X7`#X5>`0``BT7`@_@! +XM#X0H`@``<@6#^`1V#(E<)`2)/"3H:$/^_XM'$(.(5`@```3'A=#^__\!```` +XMQX74_O__`0```(7V#X1-"@``BYVL_O__A=L/A)<```"+G0#___\#G:S^__\[ +XMG0C___]V28'[``$``(G8_O__C474QT0D#``(``#'1"0(`````(E$)`2)/"3H)ST``(7` +XM#X4V____BT74BT`(#[8`B$7$#[9%Q#QQ#X3?_?__/'D/A:\)``"+A0S___\Q +XMTHNU&/___XN-"/___XE'3(N%`/___P.%&/___Q.5'/___XEW4(/Z`'P.#X]0 +XM`P``.<@/AT@#``"+E0#___^+A;#^__\#E03___\#A1#___^)="0(B10DB40D +XM!.AS^__\/A&,#```\7`^$$P,```^VM>S^__^)\8#Y +XM_P^$O@(```^VT8M'$`^VA`)3!P``@_@(#Y3"@_@,#Y3`A,!U"(32#X2H`@`` +XMBX?L````.X?P````#X0D!0``BX?P````BY?H````BXT`____B0R"@\`!B8?P +XM````BYT`____@\,!.9T(____OW__X.]^/[__P(/A.L"```/AS(#``"#O?C^__\! +XM#X3B`@``Z+;/_?^+C?3^__^^7````+I<````AS^__\/AHT"``"#A?#^__\!Z:7\___VAU`"```! +XM#X2*`0``BX=(`@``C01`P>`"`T<0BW`XA?8/E<"$P(V5&/___P^$<_S__XL: +XMBW($B=@A\(/``0^$8?S__XM*#(M2"(G0(C^__^+E>C^__^)\(@" +XM@\(!.YV<_O__B97H_O__#X0O_/__@X7D_O__`8N%Y/[__P^V,(GR@,(!#X4> +XM____BT<0@+A2!P``_P^%#O___\=$)`3_````B3PDZ/@\_O_I^?[__XN?2`(` +XM`(7;#Y7`Z7W^___'A;C^__\`````QX6\_O__`````,>%P/[__P````#I6O+_ +XM_X.]^/[__P,/A($"``"#O?C^__\$#X7/_?__B?(/ML([!?P@"0@/C>7^__^+ +XM%0@A"0CV1((U$`^$U/[__P^VM((T"```Z_[_BX?H````A<`/A8+Z__^[`0```,>'[`````````#I +XM-?C__P^VP/\DA5SD"`C'A?C^__\`````B?(/ML([!?P@"0@/C6?Z__^+%0@A +XM"0AF@WR"-``/B57Z__\/MK2"-`0``.E(^O__BX4(____B00DZ%O1_?_I@?K_ +XM_X.]^/[__P,/A"L"``"#O?C^__\$#X7!_/__B?$/ML$[!?P@"0@/C0KZ__^+ +XM%0@A"0CV1((U$`^$^?G__P^VM((T"```Z>SY__\IE0#___^)T,>'\``````` +XM``"+E0#___^+C0S___\#A03___^)/"2)5"0,B40D"(E,)`3HP4K^_X7`#X50 +XM]___BX4,____.4=8=`>#1V`!B4=8BX68_O__A@`````A<")5=R)5>0/A2,(``"+A;S^__^%P`^%Z`<``(NUP/[_ +XM_X7V="B+E:#^__^-1=R)1"0,C47DQT0D$``0``")1"0(B50D!(D\).BUL/__ +XMBYW4_O__@X4,____`87;#X0E`0``@+_T`````'4SBX6H_O__.4=,=0N+E;3^ +XM__\Y5U!T'8U'4(E$)`B+1TS'1U``````B3PDB40D!.A4[?[_BXW0_O__A%^/[__P````#I??W__\>%^/[_ +XM_P````#I1/S__\=$)`@$````BT(@NP$```"+`(D\)(E$)`3H1D0``.D#[___ +XMBXT(____B0PDZ(?/_?_I=/S__\>%P/[__P````#'A;C^__\`````QX6\_O__ +XM`````/9%#`(/A%#O___IGN[__X&C5`@``/_^__^+1>PY0W@/@JX!``"+2W2) +XMC=C^__^+0WB)1?"!BU0(`````0``BU7LZ77P___'A?C^__\`````Z=/]__^+ +XMC0S___\YC:3^__\/@LG^__^+1Q#V@%0(```$#X26[___Z;3^__^-="8`BX4` +XM____,=(#A2#___\3E23___^+C0C___^#^@!\27\$.0(``,>%T/[__P$```#I?//__XVV`````,=$)`3_````B3PDZ&`X_O^#^`@/ +XME,*#^`P/E,#IEO;__P^VM((T!```Z9+Z__^-1?")1"0(BX78_O__B50D#(D\ +XM)(E$)`3H]>O^_X7`#X3M\?__BU7LB878_O__Z0KO___'1"0(;.(("+L!```` +XMQT0D!`,```")/"3H(G?^_^G_[/__B40D#(U#>(E$)`B+0W2)/"2)1"0$Z*/K +XM_O^%P`^$F_'__XE#=.DH_O__@X7P_O__`<>%^/[__P````#I@_7__XN%[/[_ +XM_X.%\/[__P'!X`2-E"@8_/__Z3GY__^#A?#^__\!]H=0`@```0^$WP$``(N' +XM2`(``(T$0,'@`@-'$(M0.(72#Y3`Z?OX__^#A?#^__\!QX7X_O__`P```.DA +XM]?__@X7P_O__`<>%^/[__P0```#I"_7__X.%\/[__P''A?C^__\!````Z?7T +XM__^#A?#^__\!QX7X_O__`@```.G?]/__@:!4"```__[__^E8\___QT0D""'B +XM"`B[`0```,=$)`0#````B3PDZ`UV_O_I!//__\'@`HD$).AQS/W_Z7?Z__]\ +XM##T``0``D`^#8/?__[@``0``D(UT)@#I4??__X7_#X3+````BU\0A=L/A,`` +XM``#V@U4(```!#X6S````BT7L.4-X#X)G!```BT-TB878_O__BT-XB47P@8M4 +XM"`````$``(M5[.E9[?__QT0D"`````"[`0```,=$)`0%````B3PDZ'%U_O_I +XM3NO__XN5"/___XD4).C2R_W_Z?OV___'1"0(`````,=$)`0%````B3PDZ$%U +XM_O_I,_+__XN%R/[__X7`#X1Y_?__BX6L_O__,=N%P`^%C>[__X.-S/[__P+' +XMAS'1?``````A=(/A,'L__^-1?")5"0,B40D",=$ +XM)`0`````B3PDZ'OI_O^%P`^%AOW__^EN[___BX=(`@``A<`/E,#I*/?__\=$ +XM)`@TX@@(NP$```#'1"0$`P```(D\).BA=/[_Z7[J___'1"0(!@```+L!```` +XMQT0D!`````")/"3HGS\``.E%T/[__P````#' +XMA=C^__\`````QX4$____`````.E=^O__BX4`____*97\_O__QX?P```````` +XM`"G0B86P_O__B="+E?S^__^+C0S___\#A=S^__^)/"2)5"0,B40D"(E,)`3H +XM-T3^_X7`#X7&\/__BXT,____C47LC940____B40D$(E4)`S'1"0(`0```(E, +XM)`2)/"3H5#_^_X7`#X63\/__,=N%_P^$S0$``(M?$(7;#X3"`0``BX78_O__ +XM.4-T#X2S`0``BU7L.U7P#X>R`@``B50D"(N%$/___XN5V/[__XE$)`2)%"3H +XM],G]_XN-V/[__XN%"/___SF%L/[__XM=[(F-$/___W9,BX6P_O__/0`!``!S +XM!;@``0```84(____BX7<_O__A<`/A$`"``"+C0C___^+A=S^__^)3"0$B00D +XMZ)G$_?^%P`^$7_W__XF%!/___XN5L/[__XN%$/___XN-!/___RN=L/[__XE4 +XM)`B)1"0$B9VL_O__B0PDZ%W)_?^+AP$``(N5L/[__S';O@$```")E0#____I\.O__XN-N/[__PF-O/[__XN% +XMO/[__PN%P/[__P^%^OC__XN5H/[__S';@XJ`````0.E+[___BU4(NP$```") +XM1"0$B3PDB50D".@7VO__Z2[O__^+C0C___^)#"3HF,C]_^E)Z___C47`^".P$``(M3=(F5V/[__XM#>(E%\(&+5`@````!``"+5>SI +XM(O[__XN-"/___XD,).CTQ_W_Z;;M__]\#ST``0``C70F``^#*/G__[@``0`` +XMD(UT)@#I&?G__XN%"/___XD$).C!Q_W_Z3+Y__^)1"0,C4-XB40D"(M#=(D\ +XM)(E$)`3HSN7^_X7`#X3&Z___B4-TZ6_[__^+E;#^__\QV[X!````@XW,_O__ +XM`L>%R/[__P````")E:S^__^)E0#____I7NK__\=$)`CBX0@(NP$```#'1"0$ +XM`P```(D\).C2O__XM5[(F%V/[__^D;_?__BXT( +XM____B0PDZ.W&_?_I`O'__XE$)`R-0WB)1"0(BT-TB3PDB40D!.CZY/[_A<`/ +XMA/+J__^)0W3IF_[__XN-L/[__XN%!/___XF-`/___XF%W/[__XN5W/[__\>% +XMT/[__P$```")E03____I]>O__XVT)@````!5B>6#["B)7?2+70B)=?B+=0R) +XM??R+D\````"%T@^$E0```/:#K@0``$"-N[````!T/HM&>#')AQ=Z;;D__^-M@````"+1G2+`(L(Z]*-M"8` +XM````QT0D&`(```")?"04QT0D$`````#'1"0,`````(N#Q````(E4)`2)'"2) +XM1"0(Z`[8__^%P'2,BUWTN`$```"+=?B+??R)[%W#QT0D"`8```#'1"0$```` +XM`(D<).A@.@``Z]2-M"8`````C;PG`````%6)Y8/L*(E=](M="(EU^(MU#(E] +XM_(N3V````(72#X25````]H.N!```@(V[R````'0^BT9X,7UW#@\`!.3W\(`D(B47!Y``` +XM``````"+5=2)V8E4)`2+10@%L````(D$)(M5#(M%".C[X/__@\1,6UY?7<.) +XMSBMUW,=$)!@"````BT4(!;````")1"04BT4(!<0```")1"00BT4(B70D"`7` +XM````B40D#(M%W(E$)`2+50B)%"3H3-3__X7`=`JX`0```.G-_?__QT0D&`@` +XM``"+10@%R````(E$)!2+10@%W````(E$)!"+10B)="0(!=@```")1"0,BTW< +XMB4PD!(M%"(D$).C\T___A"K`````$```#'1=0!````Z7O^__^# +XMPP'I\?[__XM%"(7`#X0L`@``BU4(BW(0A?8/A!X"``#VAE4(```!#X41`@`` +XMBU70.59X#X(G`P``BT9TB478BT9XB47P@8Y4"`````$``(MUV,=%X``````/ +XMMA.$TG0P#[[".?@/A","``"`^EP/A*4```"`^GX/A/<```"#PP&(%H/&`8-% +XMX`$/MA.$TG70A?\/A/8!``"+1>"+30B%P(F!Y````'1$BX'@````A`"`T$0 +XMBT`XA<`/E<"$P`^$V/[__XM5"(/#`8N"X````(N2Y````(DT)(E$)`2)5"0( +XMZ!O`_?^+50B+@N0````!1>`!QNE__O__!;````#'1"08`@```(E$)!3'1"00 +XM`````,=$)`P`````BTT(BX'$````B50D!(D,)(E$)`CHRM'__X7`#X17_/__ +XMZ77]__^+10B+@$@"``"%P`^5P.EI____@\,!B`!#[83 +XM@\,!Z=7]__\/ME,!C4L!A-)T2@^^PCGX#X7;^___C4L"BS,``+@!````Z8#Z__^+30B+D4@"``"%T@^4P.EC +XM_O__A?]TO8G+Z1G\__^!H%0(``#__O__Z0K\___'1"0(`````,=$)`0%```` +XMB0PDZ`QH_O^+10B%P'02BU4(BT(0A=G,/MA.`^@ET:X#Z(+C_____=&%;7E]=PSGR +XM"(NX +XMF````#G:=2#K18M"!(E!!(M"!#G8=":)"(D4).C,O?W_BU8(.=IT)XL*.=EU +XMW(M"!(E&#(M"!(L*.=AUVHE."(D4).BEO?W_BU8(.=IUV8L6A=)T#SGZ=!V+ +XM1@2)0@2+1@2)$(DT).B!O?W_@\0,,53B=.#[`2+$HN(F````(72="N+0P2)0@2+0P2)$(M#"(D$).@YO?W_ +XMB1PDZ#&]_?^#Q`0QP%M=PY"-="8`BT,$B4$,BQ/KT8VV`````%6)Y593@^P0 +XMBW4(BYZ8````BP,YV'0@B40D!(DT).CM_O__BP,YV'7NBU,(A=)T#HGPZ'G_ +XM__^+4PB%TG7RBT,4AR+4`B% +XMTG7NC7L!B5WPZTV-M@````")="0(BU7PB00DB50D!.CQN_W_BT,(Q@0P`,9# +XM$`#'`P````"+5>R+0@R)0P2+0@R)&(E:#`^V3_^$R0^$EP```(E]\(/'`0^V +XM3_^$R70A#[[1A=)X[CL5_"`)"'WFH0@A"0CV1)`V`G3:C;8`````C7?_*W7P +XM@_X!=K['!"04````Z$V[_?^%P(G#=%6-1@&)!"3H/+O]_X7`B4,(#X5=____ +XMQT0D"`````#'1"0$!0```(M%"(D$).BB9/[_BT,(A<`/A3?___^)'"3HH[O] +XM_[@!````ZP(QP(/$'%M>7UW#QT0D"`````#'1"0$!0```(M5"(D4).AC9/[_ +XM@\0B+1?")7"0(B4PD!(D$).@"NOW_BU7PBTWP@\(( +XMB57LB5$(B5$,QT$0`````(M%Z(MP%(7V=`B)R(/`'8E!%(M5Z(MR"(/""(E5 +XMW#G6=2_IN````(M-[(D+BU7PBT(,B4,$.TH(#X2-````B1B+3?")60R+-CMU +XMW`^$C@```(M>%+\L````A=MT!HM^&(/'+8M.((7)=`B+1B2#P`$!QXD\).@_ +XMN?W_A<")PP^$$@$``(E\)`B)="0$B00DZ%6Y_?^+5A2%TG0&C4,HB4,4BT8@ +XMA2+1?")$(M"!(M-\(E!!#L2#X3&````BU7DBTWP +XMBT($B0B+1>2+5?")4`2+3>B+1>"+"3G!B4WH#X6*_O__BU7@BW((A?9U6^FY +XM````C;0F`````(L&B0.+1@2)0P2+1@B)0PB+1@R)0PR+1A")0Q"+1@B)!"3H +XM;;+]_X7`B4,(#X2@````QP,`````BU7DBT(,B4,$BT(,B1B)6@R+-H7V=&/' +XM!"04````Z"FX_?^%P(G#=9^+30S'1"0(`````,=$)`0%````B0PDZ)1A_O^X +XM`0```(/$+%M>7UW#B0KI/O___XM5#,=$)`@`````QT0D!`4```")%"3H96'^ +XM_[@!````Z\^+3>"+012%P'02B00DZ-"Q_?^+5>2%P(E"%'23,<#KK[`!ZZN- +XM=@"-O"<`````58GE5U93@^PLBT4(BX"8````B47HBS@YQP^$-P(``(M%"(-X +XM."(/A@4"``"+0!#'1>P!````]H!4"```!`^%"0(``,=$)`P!````QT0D"``` +XM``#'1"0$`````(M%"(D$).CZ)/[_A@/A,8!``"+=PB-5PB)5>0YU@^$@`$``(GPZV.0C70F`(U$`^:)1"00QT0D +XM#!H```#'1"0(&@```,=$)`0.YP@(BU4(B10DZ'61__\Y=Q`/A)0````Y=P@/ +XMA*<```#'1"0$)KH("(M%"(D$).A0D?__BS8[=>0/A!P!``"+1P@YQ@^$\@`` +XM`,=$)`2WW`@(BT4(B00DZ">1__^+1@B%P`^$S````(M8"(D<).C%M_W_@_@> +XM#X=H____B5PD$,=$)`P>````QT0D"!X```#'1"0$&^<("(M%"(D$).CAD/__ +XM.7<0#X5L____QT0D!.#A"`B+50B)%"3HQ9#__SEW"`^%6?___XM?%(7;#X1. +XM____BT4(BT`XB47P@^@>@_@8#X8Y____B1PDZ$BW_?^YMMP("#MW$(G"=`6Y +XMM=P("(E<)!"+1?"#Z",YT'8"B=")1"0,B4PD",=$)`3PF`@(BU4(B10DZ%B0 +XM___I\/[__XUV`(M>%.DO____BT7LQT0D!`GG"`B)1"0(BU4(B10DZ"Z0___I +XM`O___XM5"(L_BT(0]H!4"```!'4D@T7L`>D2_O__QT0D"/+F"`C'1"0$`P`` +XM`(M%"(D$).CD7O[_@\0L, +XM7UW#BU,(BT,,B4(0BT,0BU,(B4(4BT8@9H-(&`''1"0,(````,=$)`@````` +XMBT,(B30DB40D!.BM#/[_A$``0``7>GM_O__B1PDQT0D"`````#'1"0$`0```.@U +XM^?__@\04N`$```!;7<.-=@"-O"<`````58GE5U93@^PLBT4(B[B8````BQ(7`=1V+10P/MTA\BT4(@>$``0``Z(7^__^#Q"Q;7E]= +XMPX/H`70%Z->N_?^+072+`(L`QT0D"`H```")1=R-1?")1"0$BT7+5>`/A9+^__\QP.F@_O__D(UT)@!5B>564X/L$(MU +XM#(M="(M&"(7`='(QTCE#('0@QT0D"!$```"+11")'"2)1"0$Z(T%_O^%P'0. +XMN@$```"#Q!")T%M>77<.+1A2)'"2)1"0$ +XMZ#H(_O^%P(E&"`^%=/___^N4C;8`````C;PG`````%6)Y8/L.(E]_(M]#(EU +XM^(MU"(E=](M'"(7`#X0``0``C47PB40D"(ET)`2+1A")!"3H>IW^_X7`=!:X +XM`0```(M=](MU^(M]_(GL7<.-="8`BT7PQT0D"`````")-"2)1"0$Z!F1`0"% +XMP`^%T0```(M'"#M&(`^$]0```(M5$(E$)`2+1?#'1"0(`````(E4)`R)!"3H +XM!PG^_X7`=52+1PB+7?"+0`C'1"0$`````(DT)(E$)`CH1A#__XE#)(E#*(M% +XM\(&@K`0``/_^__^+1?"!B*P$``"`````BT7P@8ZL!````!```(E&%#'`Z4[_ +XM__^+1?#'1"0$`````(D$).@IO[_A<`/A88```"+@ZP```"%P'0OBU7LC4-0 +XMQT-0`````(E$)`B)'"2)4TR)5"0$Z*S,_O\QP(M=](MU^(M]_(GL7R)1"0$Z/DE_O^%P'6IBT4(QT0D!``` +XM``")'"2)1"0(Z#[T__^X`0```.NMC;0F`````,=$)`0H````B30DZ&2K_?^% +XMP'0R*?#'1"08A````,=$)!0`````B40D$(ET)`R)?"0(B7PD!(D<).B2I?[_ +XMA<`/A#3___^+10C'1"0$`@```(D<)(E$)`CHT_/__[@!````Z3____^)]HV\ +XM)P````!5B>6#[!B)??R+?0B)7?2)=?B+AY@```"+&#G##X24````BT,0BW`$ +XMC4,(.<9T:(M5#`^W0GR)="0$B3PD)0`!``")1"0(Z/7[__^Z`0```(7`=1SV +XM0QP!B7,0=".)="0(B5PD!(D\).@S-___,=*0BUWTB="+=?B+??R)[%W#D(M# +XM%(M6((M.)(D$)(GXZ`W^__\QTNO9QT0D"(#F"`C'1"0$`P```(D\).AA5_[_ +XMN@$```#KNL=$)`@`````QT0D!`$```")/"3H\O+__S'2ZYZ-M"8`````C;PG +XM`````%6)Y8/L&(E]_(M]"(E=](EU^(N'F````(L8.<,/A)0```"+0Q"+,(U# +XM"#G&=&F+50P/MT)\B70D!(D\)"4``0``B40D".@6^___N@$```"%P'4=]D,< +XM`8ES$'0DB70D"(E<)`2)/"3H5#;__S'2B?:+7?2)T(MU^(M]_(GL7<.0BT,4 +XMBU8@BTXDB00DB?CH+?W__S'2Z]G'1"0(K.8(",=$)`0#````B3PDZ(%6_O^Z +XM`0```.NZQT0D"`````#'1"0$`0```(D\).@2\O__N@$```#KFXUT)@"-O"<` +XM````58GE5U93@>R<#```BT4(BU4,BX"8````B86(\___BT)XA<`/A5,#``"+ +XME8CS__^+C[__^) +XM1"0,QT0D"$/G"`C'1"0$``0``(E4)!")'"3HRJG]_\=$)`20O@@(B1PDZ.JD +XM_?^-C>CW__^)C7SS__^%P(F%I//__P^$QP```(N%I//__XV5Z/?__\=$)`0` +XM!```B10DB40D".C@IOW_A<`/A)$```"-C>CW__^+`8/!!(V0__[^_O?0(<*! +XMXH"`@(!TZ??"@(```'4&P>H0@\$"`-*#V0,KC7SS__^-0?^`O`7H]___"@^% +XMUP@``,:$!>CW__\`#[:%Z/?__X3`=#.+#?P@"0B-E>CW__^+'0@A"0@/OL"% +XMP'@/.%G//__P````"`>A@`#XE0!```BU4,]H*!`````0^%4PD``(M5#`^W +XM0GS'A9SS__\!````)0`!``")1"0(BXV0\___BT$(B40D!(M%"(D$).BS]___ +XMA<`/A4,$``"+E8CS__^+&CG3B=@/A#P*``"+M9#S__^)!HE6!(N%B//__SM` +XM!`^$&@H``(N5B//__XN-D//__XL"B4@$BX60\___B[6(\___B0:+E9#S__^+ +XMM9#S__^+0A"+2"2+4""+1A2)!"2+10CHG?G__XN%G//__X7`#X1D"```BTT( +XMBU,0BT$@B4((BU,0BT%,B4(,BU,0BT%0B4(0@<2<#```,`"`T80BU@XA=L/E<"$P`^%M_S__XNUB//_ +XM_XM%"(MV%(FUV//__XN`F````(F%L//__XDT).A%JOW_QP0D`0```(G#C4`A +XMB40D!.A@I_W_A<")A8#S__\/A(X'``")A9#S__^+E9#S__^#P`B)ACW__^)="0$ +XMBX7`\___B00DZ/>I_?^%P`^%N`(``,=$)!0`````QT0D&`````"+E<#S___' +XM1"0,`@```,=$)`@#````B50D$(N%&/C__\<$)`````")1"0$Z"^E_?^)A=3S +XM__^#P`$/A&D"``"+A=3S__\#A1CX__^+G=3S__^)PBN5U//__XF%X//__XG0 +XMP>@?`=#1^`'#.9W@\___=Q7K'8VT)@`````[G>#S__\/A#8*```/M@.#PP$\ +XM"G7J.9W@\___#X0@"@``B[W4\___B[7@\___BX78\___B?&)VNA3Z?__@^@! +XM#X3@`0``B=Z)\BGZB=#!Z!\!T-'XC1PX.=YW".L0B?8Y\W0.#[8#@\,!/`IU +XM\CG>=;PYO>#S__]V.HN-X//__XGZBX78\___Z`/I__^#^/]T(H7`#X3*`0`` +XM.[W@\___#QP$\"G3&.[W@\___=>Z+A1CX__^)1"0$B[74\___B30D +XMZ&BB_?^%P`^%=@0``(N5P//__XD4).C2I/W_A<`/A4`$``"+E=SS__^`8A#\ +XMBX7<\___BP"%P(F%W//__P^%'/[__XN5@//__XM""#F%S//__P^$,0<``(NU +XM@//__XE&$.G<^___BXV(\___BT$4A7UW#B=_I&_[__^CR +XMHOW_BXW<\___BP")00R+M<#S__^)-"3H::/]_XNUW//__X!.$`''A:SS__\! +XM````Z9#^__^%_P^$2/[__SN]X//__XE]Z',A@#\*=!R)^.L%@#@*="&#P`$[ +XMA>#S__^)1>AU[>D<_O__.[W@\___#X00_O__B?B`.`H/A07^___&``"+5>B) +XM?>B_`0```(F5T//__XU-Z,=$)`31U`@(C5__B0PDZ&NC_?^%P(G&=!^%VW4+ +XMB;6\\___@\B%_W0:A?9T%HD\ +XM).C.I?W_A<")A<3S__\/A0$!``"-=?")="0(BX78\___B40D!(M5"(D4).A@ +XM0?[_B47HC47LB40D"(N-W//__XM!"(E$)`2+=0B)-"3H/D'^_XE$)!")PXM% +XMZ,=$)`AIYP@(QT0D!`,```")-"2)1"0,Z)E-_O^+5?"%TG0>A?9T#XM6$(72 +XM=`B+0G0[1>AT5XM%Z(D$).B(I/W_BT7LAF-_O__B30DZ/VD_?^)M;3S__^)A@/H?W_BXW<\___BP") +XM00SI)O[__XN-O//__XE,)`2+M=CS__^)-"3H1Z']_X7`#X5O_/__BX6T\___ +XM@#@O=!J-E>C[__^)5"0$B00DZ"*@_?^%P`^%20$``#'VBY7(\___BXW$\___ +XMQP0D`0```(U$"C`!\(E$)`3HAJ']_X7`B<,/A!S\__^-0"B%]HE#%`^%N@$` +XM`(N%R//__XGR`U,4@\`!B40D"(N-M//__XD4)(E,)`3H^J+]_XN5R//__XT$ +XM%HE#&`-#%(/``8E#((N-Q//__XG*B4LD@\(!B50D"(E\)`2)!"3HQZ+]_XNU +XMS//__XDSBY6`\___BT(,B4,$.W((#X2<`0``B1B+C8#S__^)60SII_[__\=$ +XM)`B0E`@(QT0D!`4```"+30B)#"3HVTO^_^F@^___QT0D"(7G"`C'1"0$!0`` +XM`(M%"(D$).B[2_[_Z6K[__^+M:3S__^)-"3H[)_]_X/X"G7MZ1GW__^+@=0# +XM``"-!$#!X`(#01"+<#CIY_O__XM%"(M`%(E%"(N0F````(F5B//__^GR]___ +XMQT0D!"\```"+C=SS__^+00B)!"3H2)[]_X7`B<8/A)3^___&``"+A;3S__^- +XMG>CS__^)1"00BY7<\___BT((QT0D"+F4"`C'1"0$``0``(D<)(E$)`SHMI_] +XM_XV-Z/O__\8&+XE,)`2)'"3H89[]_X7`#X4__O__B[7<\___BW8(B;6X\___ +XMB30DZ**B_?^)QNDC_O__C;0F`````('$G`P``+@!````6UY?7<.)="0(BY6X +XM\___B00DB50D!.A.H?W_BT,4Q@0P+X/&`>DA_O__BT,0B[6,\___B7`(BT,0 +XMBY64\___B5`,BT,0BXV8\___B4@0@<2<#```,_O__BTT, +XM#[=!?,>%G//__P`````E``$``.GK^O__#[9"`8UR`<8"`(3`=2+I[?7__XUT +XM)@`YP7X<]D2#-4!T%8/&`0^V!H3`#X30]?__#[[`A_?^%P(G< +XM^O__C5@(B5X(B5X,QT0D!"P```#'!"0!````Z%*>_?^%P(G'#X0<^O__BT8( +XMB5\$B0<[7@P/A%T"``")>`2)?@B)?A#I,/7__XEP!.GO]?__B1Z)VHE>!#M; +XM!`^$)`(``(L#B7`$BXV(\___B?.)\(DQZ9[U___'1"0,4^<("(N%H//__\=$ +XM)`0#````B40D"(M5"(D4).CR3?[_B30DZ.Z?_?^X`0```.G+^?__QT0D#%/G +XM"`B+C=CS___'1"0$`P```(E,)`B+=0B)-"3HNTW^_XN%K//__X7`=%6+A;#S +XM__^+6`B%VW4*ZT:)]HL;A=MT/@^V0Q"#X`.#Z`%U[NA]G/W_BU,,B1#'1"0, +XMGZT("(M#",=$)`0%````B40D"(M5"(D4).AB3?[_@$L0`NN\BXV`\___B0PD +XMZ%*?_?^X`0```.DO^?__#[9"`8UZ`<8"`(3`#X3;\___#[[`A<`/B$0!``"+ +XM#?P@"0@YP0^.&`$``(L=""$)".L9@\")^NL2#[9"`8/"`83`#X2'\___#[[`A;V1(,U0'3? +XMQ@(`@+WH]___``^$9?/__X`^``^$7//__X`_``^$4_/__XDT).@&E_W_A<`/ +XMCD/S__^)/"3H1I_]_XDT)(G#Z#R?_?_'!"0!````C40#+HE$)`3H6)S]_X7` +XMB<,/A(K\__^-0"B)0Q2)?"0$B00DZ%R?_?^)/"3H!)_]_XE#&`-#%(/``8E# +XM((ET)`2)!"3H/)_]_XN%J//__XD#BY6$\___BT(,B4,$BXVH\___.TH(=$>) +XM&(NUA//__XE>#.G]\?__B7,$Z=G]__^+'0@A"0CI!?___XE^#.F>_?__B[W4 +XM\___Z27V__^+#?P@"0B+'0@A"0CIX?[__XE:".NVC;8`````C;PG`````%6) +XMY8M%#(&(@`````````B)10Q=Z4?P__^-M"8`````58GE@>S(````B77XBW4, +XMC47LB5WTC9U8____B7W\BWT(B40D&,=$)!0`````QT0D$`````#'1"0,```` +XM`,=$)`@`````QT0D!#H```")'"3H*Q0``(DT).CWG?W_B70D"(D<)(E$)`R- +XM1=R)1"0$Z+P/``")7"0$B3PDZ,#O__^%P'41BX>L!```@.3^#(")AZP$``"+ +XM7?0QP(MU^(M]_(GL7<.0D)"0D)"0D)"0D)!5B>6#[!B)7?2+70B)=?B)QHE] +XM_(G7]\,``$``#X6.````]\,``!``=!CVAI@"```!=4V+AI`"``"%P`^5P(3` +XM=5F#XQ!T&HM'"(E$)`B+1QS'!"3RF`@(B40D!.CSF?W_H00A"0B+7?2+=?B+ +XM??R)10B)[%WI^I?]_XVV`````(N&D`(``(T$0,'@`@-&$(M0.(72#Y7`A,!T +XMIXM'%,<$)+O<"`B)1"0$Z*:9_?_KDHD,).A575E.! +XM[,P```"+?0R+=12+'SG[=!`Y.P^$%0(``(D\).AHS?W_QT0D#"````#'1"0( +XM`````,=$)`0`````BT4(B00DZ,7._?^%P(G##X0K`0``BP>)>P2)`SE_!`^$ +XM,@,``(L'B5@$B1^+50B+0DR#P`&)0Q2+2A")C53____V@50(```0#X2B```` +XM@^;OB?&)\(/A0"4``@``QX5<____`````(F-4/___XF%3/___XU5V,=$)`P` +XM````QT0D"`````")5"0$BTT(B0PDZ'L(_O^%P`^%HP```(-]X`L/AJL```"- +XM1=@Q]HE$)`2+50B)%"3H10/^_XL3.?H/A+$```"+0P2)0@2+0P0Y^`^$LP`` +XM`(D0B1PDZ$#,_?^!Q,P```")\%M>7UW#C78`]\80````=#")7"00QT0D#``` +XM``#'1"0(`````(M5"(M"3(D4)(E$)`3H$HX``(7`=1Z!S@!```")-"2+31") +XMVHM%".C(_?__Z13___^-=@"^`0```('$S````(GP6UY?7<.+1>#_)(6,YP@( +XMBT,(@'P"_RX/A1D!``"+$S'V.?H/A4____^+0P2)1P2+0P2+$SGX#X5-____ +XMB1?I2/___[X!````Z2'___^+0Q"#P`$[0PQWBX50____A0[%?P@"0A]&J$((0D(]D20-0)T#H/Y"G0)@_D/#X66_O__BT,0#[95 +XMY(M+"(@4`8/``8E#$.E^_O__@WL,'P^&X?W__\=#$`````#I(?[__Y"-="8` +XM_R2-O.<("(E$)`R-0PR)1"0(BT,(B40D!(M-"(D,).A,M_[_A<`/A`3___^) +XM0PCI8?____9%[`(/A%_____WQB`````/A04!``#WQ@`(```/A84$``#WQ@`0 +XM``"-="8`=!&+0QR+4Q"#P`$YP@^$V?[__\=$)`P@````QT0D"`````#'1"0$ +XM`````(M%"(D$).@JS/W_A<")A5C___\/A(S^__^+0Q2+E5C___^#P`'WQA`` +XM``")0A1T1X.]7/___P(/A,@"``"+A5C___^)1"00BT,0B5PD",=$)`0````` +XMB40D#(M5"(D4).@PC```A<`/A3C^___'A5S___\`````B30DBTT0BT4(BY58 +XM____Z-K[__^+C5C___^).8M'!(E!!#D_#X2K`@``BT<$BY58____B1"+C5C_ +XM__^)RXE/!.D<_?__B5\$Z2+E43___^( +XM`HM#",9``0"AH!0)"(7`#X7=`P``BQ4$(0D(BT((@^@!A<")0@@/B.(#``"+ +XM`C'VQ@`*@\`!B0+I2OS__XM#$#M#'`^'"_W___?&$`````^$__S__\>%7/__ +XM_P$```#I\/S___?&$`````^$JOO__XM+$(7)B4V`#X2<^___@[U<____`0^$ +XM'`$```^#!`$``(M%@#M#'`^'??O__XM5"/:"T`,```$/A/,"``"+@L@#``"- +XM!$#!X`(#0A"+0#B)A7#___^+10CV@(@#```!#X2W`@``B<*+@(`#``"-!$#! +XMX`(#0A"+0#B)A73___^+0P@QTL=%D`````")A7S____K%XUT)@"#P@`! +XMBT6`.460#X2)`0``BTV0BX5\____@#P!"77>BXUP____B=`!T3'2][5P____ +XMB8U(____*=&)RNO#B50D$(M%N,=$)`0`````B40D#(U%G(E$)`B+30B)#"3H +XM:XD``(7`#X5S^___BT6DB00DZ!R6_?_'A5S___\`````Z2O]__^)#^E9_?__ +XM@[U<____`P^$U0```.B4D/W_BT,<@\`!.46`#X=D^O__BU,E?W_BT,%7/___P````#KCHM3"#'VBT,0Q@0"`.GD^?__ +XM@^H!B95(____B=`QTO>U=/___S'`BXU(____QX5H____`````"G1.8UP____ +XMB4V,=S.+A7#___^)18CK`XE-B(M%B#'2][5P____BTV(`XUP____@X5H____ +XM`2G1.4V,<]N+18B+58PIPHF5;/___P.5:/___XG0B95X____@\`!.T,,#X>' +XM````BY5X____QT,0`````(E3'(N%:/___X7`=!F+0Q"+4PC&!`()@\`!B4,0 +XM@ZUH____`77GBX5L____A<`/A-K^__^+0Q"+4PC&!`(@@\`!B4,0@ZUL____ +XM`77GZ;S^__^+30B+B8`#``")C73____I3_W__XM-"(N)R`,``(F-$:#R("(0UC'0S0!````B7PD!(DT).BK%_[_AR)1DR+1?")1E`QP.L%N`$```"+7?2+=?B+??R)[%W#BT,T@_@! +XM=+]S"8UT)@#H;XW]_X/X`G7&B7PD!(DT).C:$O[_A53@^P4BUT(QT0D!!#H"`B)'"3H]FO__XD<),=$)`1( +XMZ`@(Z.9K__^)'"3'1"0$@.@(".C6:___B1PDQT0D!,#H"`CHQFO__XD<),=$ +XM)`0?Z0@(Z+9K__^#Q!0QP%M=PXVT)@````"-O"<`````58GE5U93@^Q,BU4, +XMBT)XA<`/A0@!``"+'<#,"`B%VP^$\````(M5"+O`S`@(C77CBT(0]H!4"``` +XM!`^%U0```,=$)`P!````QT0D"`````#'1"0$`````(M%"(D$).CM_OW_A!0[%?P@"0A]#*$((0D(BY20-`@``(A5Y`^V`3'2QD7F78A% +XMY0^V1`H!B$0R!(/"`83`=?")\HM#%(/#&(E4)`S'1"0(#````,=$)`24U`@( +XMB40D$(M%"(D$).@T:___BP.%P'03BU4(BT(0]H!4"```!`^$*____X/$3#'` +XM6UY?7<.#Z`%T!>BKB_W_BT)TBP")1D( +XM"(E$)`B+10B)!"3HGFG__X/$3#'`6UY?7<.-="8`58GE5U93@^PC;0F`````(N&!`0``(7`=(NX8`L)".N&@^@!=`7H28G]_XM"=(L` +XM@W@(`70GQT0D"`H```"+0B"+0!")-"2)1"0$Z)`"``"#Q!RX`0```%M>7UW# +XMBP`/MA@/MM.#^GY_=X/Z6W1J@_I==&6`^WX/A)$```")T,'@!`4`_`@(BW@( +XMA?]T4XM(#`^^$872>!D[%?P@"0A]$:$((0D(NT^-"`CV1)`V`G4%N]+4"`B) +XM?"00B4PD#(E<)`C'1"0$:^D("(DT).C^9___,<#I`O___P^V0`$YT'23C012 +XM@,,!C81!6`$``'1&B30DB40D",=$)`3\Z`@(Z,QG__^#Q!PQP%M>7UW#]H8, +XM!````70MBX8$!```C01`BT2!.(7`#X11____N&`+"0CI4?___XE4)`2)-"3H +XM;O+]_^NLBX8$!```A(M1=(/``8E!>,<$@@````!;7<.-M@`` +XM``"-OP````!5B>564X/L$(M="(MS$,=$)`0!````B1PD_Y:@"```N@$```"% +XMP'0)@\00B=!;7EW#QT0D"`````#'1"0$`````(D<)/^67`@``/:#(`(```%T +XM4(N#&`(``(T$0,'@`@-#$/:#8`$```&+0#B)0S1T1(N#6`$``(T$0,'@`@-# +XM$(M`.(E#.(N#K`0``#'2@^#]@\@%B8.L!```@\00B=!;7EW#BX,8`@``]H-@ +XM`0```8E#-'6\BX-8`0``Z\:-=@!5B>53@^P4BT4,BUT(AGQ,_[_QT40\.H(",=%#`,```")30C) +XMZ=HS_O_'11`4ZP@(QT4,`P```(E-",GIPS/^_XE4)`S'1"0(/.L(",=$)`0# +XM````B0PDZ*EP,_[_58GE5S'_5E.#[!R+10B+=0R+@)@```") +XM1?#H58?]_\<``````(M5\(M:+(/",(E5[(M5\(M",#G'<@^-5P$YT')3BT7P +XMB?L#6"RAH!0)"(7`=6Z+1@2#Z`&%P(E&!`^(W0```(L&#[80@\`!B0:#^O]T +XM78/Z"@^$U````(@3BU7P@\(/]_^GP_O__B30DZ&N)_?^)PND>____BU40 +XM,<").H/$'%M>7UW#D%6)Y8/L&(E=](M=#(EU^(MU"(E]_(M](,=$)`B$```` +XMC1Q;C1S=P,P(",=$)`0`````B30DZ'J%_?^)7B"+11")1F"+112)1F2+11C' +XM1G`!````QT9H`0```(E&;(M%'(7`=`9F@4Y\``&%_\=&>`````")?G1T!L<' +XM`````(M=](MU^(M]_(GL7<.0D)"0D%6)Y8/L&(M%",=$)`CXZP@(QT0D!`0` +XM``")!"3H7S'^_S'`R<.0D)"0D)"0D)"0D%6)Y5=64X'L+`$``(M="(M]#/:# +XML`(```$/A)$```"+@Z@"``"-!$#!X`(#0Q"+4#B%T@^4P(3`#X6%````BU=D +XMA=(/A*<```")4TP/MT]\B<@E8@@``(/X(`^$X`````^/D0```(/X`@^%G``` +XM`(/A!+Y>````#X71````C78`B70D$(VU\/[__XE4)`S'1"0(ANP(",=$)`0` +XM`0``B30DZ$Z%_?_IT````)"-="8`BX.H`@``A<`/E,"$P`^$>____\=$)`A` +XM[`@(QT0D!`,```")'"3H=3#^_[@!````@<0L`0``6UY?7<.0C70F`+(!Z5+_ +XM__^#^$`/A!4!```]``@```^$<@$``(M#((E0$(M#(,=`%`````"-0U")1"0( +XMBT-,B1PDB40D!.COH_[_BT,@9H-(&`'IH@```(GVOBT```"#X00/A#+___^+ +XM1UB)="00C;7P_O__B50D#,=$)`A\[`@(B40D%,=$)`0``0``B30DZ'F$_?_' +XM1"00#````(E$)`R)="0(QT0D!`````")'"3HU?#]_P^W1WPE`!8``#T``@`` +XM#X2A````/0`$``!U*L=$)!`!````QT0D#`````#'1"0(`````,=$)`0:```` +XMB1PDZ`)"_O^)]HN#K`0``*@0=0L-```(`(F#K`0``*D```(`=22#X/J#R`*) +XM@ZP$``"!Q"P!```QP%M>7UW#OBX```#I)O___Y"+0QR#0PP!@P`!C47PB5WP +XMB00DZ"CG``"%P'1+@<0L`0``N`$```!;7E]=PXUT)@#'1"00`0```,=$)`P` +XM````QT0D"`````#'1"0$(@```(D<).AH0?[_Z6/___^^*P```.F^_O__B1PD +XMC;8`````Z)OX__^%P'6CQT0D!":Z"`B)'"3H)U___S'`Z3#^__]5B>575E.! +XM[)P```"+10B+?1"+0!")A7#___^+112+,(M%&(L`B85X____BT4/___X7`#X1S`@``.[5X____#X=G`@``QX5T +XM____`````,>%?/___P````#'18"-[`@(ZSR0C70F`(M'"(/H`87`B4<(#X@9 +XM`@``BP?&``J#P`&)!X.%=/___P&#Q@$YM7C___\/@H0"``")G7S___^+G7S_ +XM__^Z'X7K48/#`8G8]^+!Z@5KTF0YTP^%@P```(M5"(M"$/:`5`@```0/A>T` +XM``#'1"0,`0```,=$)`@`````QT0D!`````")%"3HQO']_X7`=1.+50B+0A#V +XM@%0(```$#X6V````BT4DA%?/___P`` +XM``")/"3H4W[]_X7`#X7Z_O__Z4/___^+10S'1"0,GZT(",=$)`0%````B10D +XMB40D".BC,/[_Z>'^__^+#:`4"0B%R75##[]'#HD$).@L?/W_A<`/A;/^___I +XM-?___XF=?/___XD\).CQ??W_A<`/A9C^___IX?[__XD\).A<@?W_B<+IY/[_ +XM_XD\).A-@?W_Z[>-M"8`````58GE5XG75E.#[#R)1=B)3=2+!T5HM'=(L`BQ@/M@.$P'0U +XM#[[`A2#?=0"=0V`.R$/A+P```"-="8`@W]D`0^&7`(``(M%X(7`D'0; +XM@WW4`W0)@#L^#X2O`0``BT7@A7UW#B1PDZ`*"_?^+5=B)7"0(B7PD +XM!(D4)(E$)`SHM_O^_X7`#X4,`@``BT=XA!K`0` +XM``(`!``/A:#^___'1"0$);H("(D,).A>6?__,<#IB?[__XVT)@````"`>P$^ +XM#X5'_O__@\,"@\X"#[8#A,`/A#;^__\/OL"%P`^(*_[__XL-_"`)"#G!#XX= +XM_O__BQ4((0D(ZR6-="8`@\,!#[8#A,`/A`/^__\/OL"%P`^(^/W__SG!#X[P +XM_?__]D2"-@)UV.GD_?__C78`QT0D"`0```"+0B"+`(E$)`2+1=B)!"3H9//_ +XM_[@!````Z>S]__^+1VR#P`&)1"0$BT78B00DZ'7U_?^%P'4=BT]X@\X!B4W@ +XMZ7W]__^X`0```.F[_?__Z+AY_?^+5WB)5>#I8_W__XN!7`,``(T$0,'@`@-! +XM$(M(.(7)#Y7`Z1/^__^+1W2+3=B+4`2+02"+&@^W0!@EA````(/`@`^$@@`` +XM`(M%V(E<)`2)!"3H/L#]_XM-V(U';(E$)`B-1V2)="00B5PD#(E$)`2)#"3H +XM3<']_^DZ_?__BT<@QT0D"`H```"+3=B+0!")#"2)1"0$Z(OR__^X`0```.D3 +XM_?__BT<@QT0D"`D```"+5=B+`(D4)(E$)`3H9?+__[@!````Z>W\__^+0@B) +XM7"0$B0PDB40D".A8FO[_A<")1=QT'8M5V(M"((M`"(D$).@D?OW_BTW8BU7< +XMBT$@B5`(BTW8BT$@9H%@&#__BT$@9H-(&`R+41#'1"0(`0```(M!((M`"(D, +XM)(E$)`3_DIP(``#I'____XVV`````(V\)P````!5B>564X/L$(MU"(M&'(7` +XM='GV0%@$=!.+50RY`P```(GPZ&G[__^%P'44QT0D!`````")-"3HE;_]_X7` +XM=!&X`0```(/$$%M>7<.0C70F`(M%#`^W6'R)-"2!XP`!``")7"0$Z/?P__^% +XMP'72@_L!&<`E`/[__P4`!```"8:L!```@\006S'`7EW#QT0D"`0```"+50R+ +XM0B"+`(DT)(E$)`3H.?'__[@!````ZY:)]E6Y`@```(GEBT4(BU4,7>G,^O__ +XMC;8`````C;\`````5;D!````B>6#[!B)=?R+=0B+50R)7?B)\.BB^O__AQ=P\=$)`0`````B30DZ+^^_?^%P'7=BT4,#[=8?(DT +XM)('C``$``(E<)`3H,O#__X7`=<"#^P$9P"4`_O__!0`$```)AJP$```QP(M= +XM^(MU_(GL7<.-M@````"-O"<`````53')B>6#[!B)7?B+70R)=?R+=0B)VHGP +XMZ!/Z__^%P'0/BUWXN`$```"+=?R)[%W#QT0D!`````")-"3H,+[]_X7`==W' +XM0W@`````B5T,BUWXB74(BW7\B>Q=Z5'?_O^058GE4X/L%(M="(M-#(M#'(7` +XM=#8/MT%\C5%1QT0D$`$```")'"2#X`'WV"'"C4%LB40D#(U!9(E$)`B)5"0$ +XMZ%RP_?^#Q!1;7+B +XM"```@_I`B47P#X2+`0``#X^5````@_H"#X1-`0``@_H@#X0A`0``]H."```` +XM"'0&@\`!B47PBT7PB4-DBT7P@^@!```````C47PB40D!(DT).C- +XM\?W_A<`/A<4```"+1?`Y0VQV`XE#;(E<)`2)-"3H7ES__X7`#X6F````BU7@ +XMA=)T"(M%X(E&3#'`@\0L6UY?7<.+2UCI5____XVT)@````"!^H````!T$X'Z +XM``@``(GV#X5G____Z7'___^->?^Z`0```-'O.?AV!(G"*?J)4V2+1?"#Z`&) +XM0VR)7"0$B30DZ.M;__^%P'4WQT0D!)SL"`B)-"3HMU/__XM%\(E%X(E#9(E# +XM;(E<)`2)-"3HOUO__X7`#X3Z````C;0F`````(/$++@!````6UY?7<.-=@"+ +XMCF0$``"#Z0'ILO[__SG!N@$```!S!8U0`2G*B5-DBT7PB4-LQT7@`````.D% +XM____C10).=`/AIL```"#P`$IT(E#9(M#9(/H`0'(B4-LQT7@`````.FY_O__ +XMD(UT)@"-4?^Y`0```-'J.=!V!(G!*=&)2V2)T`-%\(E#;(M&3(E%Z(M&4(E% +XM[(U%Z,=$)`P!````B40D",=$)`0G````B30DZ-@2_O_'1>``````Z6#^___' +XM1"0(!````(M#((L`B30DB40D!.A3[?__N`$```#I@O[__\=#9`$```#I8?__ +XM_\=$)`2<[`@(B30DZ(U2__^+1?"#P`&)0V2+1?"#Z`$!^(E#;.D(_O__D)"0 +XMD%6)Y8/L&(M%",=$)`C([`@(QT0D!`,```")!"3HSR'^_[@!````R<.0D)"0 +XMD)"0D%6)Y8/L&(M%",=$)`CX[`@(QT0D!`,```")!"3HGR'^_[@!````R<.0 +XMD)"0D)"0D%6)Y5.#[!2+70R#>Q0$=@7H+W/]_XM#%/\DA2CM"`B0,<"#Q!1; +XM7<.+`X/X`71QC5#_C4,,B1.)1"00C4,(B40D#,=$)`@!````B50D!(M%"(D$ +XM).CG[/W_A____C;8`````58GE5E.#[#"+70R-1?2+=0B)1"00 +XMC4,,B40D#(U#"(E$)`B+`XDT)(E$)`3H;^[]_X7`=!.+5?2X`0```(72=26# +XMQ#!;7EW#BT,,A7<.X`0```.ORC;8`````C;\`````58GE +XM5E.#[!"+=0B+70R)]HE<)`2)-"3HQ/S__X7`=3.+0Q2#^`-TZ(/X`73CA<"0 +XM=1@/ME,0.Q7\(`D(?0RA""$)"/9$D#8"=<:#Q!`QP%M>7<.#Q!"X`0```%M> +XM7<.058GE5E.#[!"+=0B+70R)]HE<)`2)-"3H=/W__X7`=3.+0Q2#^`-TZ(/X +XM`73CA<"0=1@/ME,0.Q7\(`D(?0RA""$)"/9$D#8"=<:#Q!`QP%M>7<.#Q!"X +XM`0```%M>7<.058GE5U93@^P\BT4,]D`Q`G0.#[90`8#Z0'0%@/HJ=1N+50AF +XM@[JL!`````^)0P$``(M="`^VDZ@```"+10@/MLJ!B*P$````@```.PW\(`D( +XM#XS(````B="+70B+7UW#QT0D"`4```#'1"0$`````(D4).A$Y___ +XM@\0\N`$```!;7E]=PXM5##'`]D(Q"`^$;____XM"!(U=X(D<),=$)`CZE@@( +XMQT0D!!0```")1"0,Z(IP_?_'1"00`````(E<)`C'1"0$`````(E$)`R+70B) +XM'"3HX]S]_X7`#Y7`#[;`Z1W____'1"0$_P```(M%"(D$).B3U_W_Z3[___^0 +XMD)"0D)"0D)"0D)"0D%6)Y5.)PX/L%(#Z_W0U#[;"C01`C80`4`$```-#$(/` +XM"(D<)(E$)`S'1"0(2^T(",=$)`0"````Z%,;_O^#Q!1;7<.)5"0$B1PDZ#'7 +XM_?_KT.L-D)"0D)"0D)"0D)"0D%6)Y5=64X/L+(M]#`^V5P+V1S$@#[;:=0^+ +XM30B+@9P```"(D(0!``"+50B+@IP```#'@(@!```!````C47LB40D$(U%\(E$ +XM)`R-1>B)1"0(BT7UW#BT7PAAS!P^^`CG8=>PYT77B)5T2)1T")1TB+1RR%P'0.]D`&('0(@V\X`3'`ZX0Q +XMP.N`B?95B>6#[!B)7?B+70R)=?R+=0B)7"0$B30DZ.+^__^Z`0```(7`=22+ +XM0T"+4SR#P`&)4T0QTHE#0(E#2(N&G````,>`B`$```,```"+7?B)T(MU_(GL +XM7<.)]HV\)P````!5B>575E.#["R+?0P/ME<"]DC]_X7`=".+3>RX`0```(7)=`^+10B)VNC'_?__N`$` +XM``"#Q"Q;7E]=PXM%\(7`=.*+3>B^`0```(E-X`'!BT7@`TAV!P^^`CG8=>PYT77@ZYV+=P3K +XMV8M'+(M5Z"M5X(7`B5=`=`;V0`8@=0V+1SR)5TB)1T0QP.N$BT`B`$```0` +XM``"+7?B)T(MU_(GL7<.0C70F`(M#/(E32(E#1.O2D(UT)@!5B>6#[!C'1"0( +XM7.T(",=$)`0"````B00DZ#(8_O_)PU6)Y8/L&(EU_(MU"(E=^(M5#(N&G``` +XM``^V@(0!``"(0@*+AIP```"+F(@!``"#^P1V!>BL:?W__R2=@.T("(E4)`2) +XM-"3HM?W__XG"C78`BX:<````B9B(`0``BUWXB="+=?R)[%W#B?#HR)T%W#B50D!(DT).C4_?__B<+KP(E4)`2)-"3H9/S__XG" +XMZ[")5"0$B30DZ,3^__^)PNN@58GE@^P(BU4(BTT,BX*<````#[:`A`$``(A! +XM`HN"G````(.XB`$```1V!>@$:?W_BX"(`0``_R2%E.T("(E-#(E5",GI=_[_ +XM_XG0Z.#^__^X`0```,G#B4T,B54(R>GM^___B4T,B54(R>E!_?__B4T,B54( +XMR>G5_/__D)"0D)!5B>575E.#["R+10R+?0R+70R+2#")SHG(P>X#@^`"@^8! +XM@_@!BT4,&=*!X0`"``"#XOZ#QS2#P@2#PP&#P#R#^0&)1>`9P`GR]]`APXM% +XM"(E4)!"+5>")?"0(B5PD!(D$)(E4)`SH-:+]_X7`=!&X`0```(/$+%M>7UW# +XMC70F`(M5X(M%"(ET)`R)?"0$B50D"(D$).@&IOW_AR)7"00QT0D#`````#'1"0(`````(M" +XM1(E$)`2+10B)!"3HRN']_X7`#X63````BT4,BT@P]L$(=1>!X0_^__^#R2") +XM2#"+50R+1>PY0DAS73'`]L$$#X19____BU4,@>$/_O__@\E`B4HPZ47___^0 +XMBU4(C47PB40D!(D4).BNX_W_A<`/A27___^+1?"%P`^%9?___XM%#,=`1`$` +XM``#'0$@`````,<#I!____X/X`8U0_QG`]]`APHM%#(E02.N/BT7PBU4(B5PD +XM$,=$)`P`````QT0D"`$```")1"0$B10DZ`GA_?^%P`^%P/[__XM%\(M5#(E" +XM1.DQ____D)"058GE4X/L-(M="(U%^(E$)!"-1?2)1"0,QT0D"`````"+0TR) +XM'"2)1"0$Z,'@_?^%P'0&@WM,`71\BT7XA<")]G1.QT0D%`````#'1"00```` +XM`(E$)`R+1?3'1"0$`````(D<)(E$)`CH,R?__[H!````A6#["B)7?2)PXE]_(EU^(MP$,=$)`0`````B00DZ#S!_?^% +XMP(G'=!>-1AB)1"0(B5PD!(DT).BS5O[_AQ= +XMP\=$)`P`````QT0D"`````")?"0$BT88B00DZ&["_?^%P'4.BT88BT`<@&!8 +XMOS'`Z\*+1AB)!"3HP53^_[@!````Z["-=@"-O"<`````58GE@^PXB5WTB<.) +XM??R)UXEU^(M`$(M`&(7`=&6+7<.+1?0Y0U!RU8/X`8U0_QG`]]`A +XMPHE34.O$58GE@^P8B5WTB<.+02")=?B)UHE]_(E,)`2)'"3_4`2)\HG'B=CH +XM5?___[H!````A57 +XM5E.#["R+70B+>Q#'1>``````Z>,```"0C70F`(N#3`$``(T$0,'@`@-#$(M` +XM.(7`#Y7`A,!T$8GRB=CH3/[__X7`#X6.`0``QT0D%`$```#'1"00`````(M& +XM$(E$)`R+1@C'1"0$`````(D<)(E$)`CH-B3__X7`#X58`0``B1PDZ$;H``#V +XM@ZP$```0="ZAH!0)"(7`#X7#````BQ4$(0D(BT((@^@!A<")0@@/B#`!``"+ +XM`L8`"H/``8D"B1PDZ/>2_O^)'"3HKT'__XU%\(E$)`2)'"3H0/,``(7`#X7R +XM````BT7PA<`/A(H```"#0RP!QT7@`0```(M'?(M`%(7`#X5V____BT4,QT0D +XM#(`!00#'1"0(.@```(D<)(E$)`3H!:(``(7`#X6G````BW-XBT8X@_@!#X2Z +XM````A7UW#B50D!,<$)`H```#H +XM?6;]_^G%_O__@WX0`78-B?*)V.B%_/__AS'1"0( +XM`0```(D<)(E$)`3H@$8!`(7`=".+1>R)!"3H`5'^_[@!````ZYF)V.BC^___ +XMA<"0=8CI;/___XM&&(M0'(M%[(E0'(M%[(M`'(,``8M&&(M0((M%[(E0((M% +XM[(M0((M#(`^W0!AFB4(8BU7LC4),B10DB40D!.BEW?W_BT7LBU!,A=)U"L=` +XM3`$```"+1>R!B*P$``````$`B5L8BT7L@8NL!````!```(E#%#'`Z0S___^- +XMM@````"-O"<`````58GE4X'LM````(V=>/___XD<),=$)!@`````QT0D%``` +XM``#'1"00`````,=$)`P`````QT0D"`````#'1"0$/````.@8W?__BU4,B=F+ +XM10CH>_S__X'$M````%M=PXGV58GE5E.![+````"+=0R+1C3V1C$(C4@!=`R+ +XM5@2#^@)V!(U,`O^-G73___^)3"00B40D#(D<),=$)!@`````QT0D%`````#' +XM1"0(`@```,=$)`0<````Z*3<__^+10B)V8GRZ`C\__^!Q+````!;7EW#C;0F +XM`````(V\)P````!5B>6![+@```")=?R+=0R)7?B+1A2#^`5T"H/X#'19Z"!@ +XM_?^-G73____'1"08`````,=$)!0`````QT0D$`````#'1"0,`````,=$)`@` +XM````QT0D!"P```")'"3H'MS__XM%"(G9B?+H@OO__XM=^(MU_(GL7<.-G73_ +XM___'1"08`````,=$)!0`````QT0D$`````#'1"0,`````,=$)`@`````QT0D +XM!$@```")'"3HRMO__^NJD(VT)@````!5B>6![+@```")=?B+=0R)??R+?0B) +XM7?3V1C$@=6*+1BP]X``)"'18/>`""0AT4<=$)`R`B$$`QT0D""$```")="0$ +XMB3PDZ&6>``"%P`^%G@```(M?>(-[.`0/A,(```"+1TR)1D2+1U")1D@QP(GV +XMBUWTBW7XBWW\B>Q=PXUV`,=$)!@`````C9UP____QT0D%`````"+1CR)1"00 +XMBT8TQT0D"`(```#'1"0$`0```(D<)(E$)`SH!-O__XN'F````,=`)`````#' +XM1"00`0```,=$)`P!````QT0D"-7:"`B)7"0$B3PDZ`/7_O^%P'0/N`$```#I +XM=?___Y"-="8`BX>8````B=F+4"2)5>B+0!R)\HE%Y(GXZ!/Z___I3O___XD\ +XM).@FXP``QT0D&`````#'1"04`````(M&/(E$)!"+1C3'1"0(`@```,=$)`0! +XM````B40D#(V%8````QT`D`````,=$)!`!````BT,0 +XM@^@!B40D#(M#"(D\)(/``8E$)`B-A7#___^)1"0$Z$_6_O^%P`^%2/___XN' +XMF````(V-R-O5C___^)1"08QT0D%`````#'1"00`````,=$)`P` +XM````QT0D"`````#'1"0$.@```(D\).ASV?__BX:<````BY@P`0``B1PDZ#-C +XM_?^)7"0(B3PDB40D#(U%W(E$)`3H^-3__XM5#(GYB?#HK/C__XM=](MU^(M] +XM_(GL7<.+EM`!``"%T@^$____D%6)Y5.![,0```"-G6#___^-1?2)1"08B1PDQT0D%`````#' +XM1"00`````,=$)`P`````QT0D"`````#'1"0$-P```.B)V/__C47DB40D!(D< +XM),=$)`P'````QT0D"'[`"`CH&M3__XM5#(G9BT4(Z,WW__^!Q,0```!;7<.- +XM="8`58GE5E.![,````"+=0R-1?")1"08C9U<____QT0D%`````"+1CR)1"00 +XMBT8TB1PDQT0D"`(```#'1"0$!P```(E$)`SH!]C__XU%X(E$)`2)'"3'1"0, +XM`0```,=$)`B9[P@(Z)C3__^+10B)V8GRZ$SW__^!Q,````!;7EW#B?95B>56 +XM4X'LP````(MU#(U%\(E$)!B-G5S____'1"04`````(M&/(E$)!"+1C2)'"3' +XM1"0(`@```,=$)`0%````B40D#.B'U___C47@B40D!(D<),=$)`P!````QT0D +XM"':["`CH&-/__XM%"(G9B?+HS/;__X'$P````%M>7<.)]E6)Y593@>S````` +XMBW4,C9U<____C47PBU8TB40D&(D<),=$)!0!````B50D$(E4)`S'1"0(`@`` +XM`,=$)`0#````Z`K7__^-1>")1"0$B1PDQT0D#`$```#'1"0(3XT(".B;TO__ +XMBT4(B=F)\NA/]O__@<3`````6UY=PY"-="8`58GE@>S(````B7W\BWT(B5WT +XMB77XB[>D````A?8/A)T```#'1"0(`0```,=$)`0`````B3PDZ)6R_?^Z`0`` +XM`(7`=`^+7?2)T(MU^(M]_(GL7<.-1>R-G5C___^)1"08QT0D%`````#'1"00 +XM`````,=$)`P`````QT0D"`````#'1"0$%````(D<).A`UO__B30DZ`Q@_?^) +XM="0(B1PDB40D#(U%W(E$)`3HT='__XM5#(G9B?CHA?7__XG"ZX60QT0D"`T$ +XM"0C'1"0$`P```(D\).@("/[_N@$```#I8O___XVT)@````"-O"<`````58GE +XM5E.#[!"+70B+7<.)'"3'1"0(`````,=$)`0`````_Y9< +XM"```BU,@BT-,B4(0BT-0BU,@B4(4BT,@9H-(&`&+@ZP$``"#X/6#R`&)@ZP$ +XM``")'"3'1"0$)KH(".C4-___@\00,6#[!B# +XM^@)T-8/Z`W05@^H!=`+)PXGVC;PG`````.C/6/W_QT0D"(0$"0C'1"0$`P`` +XM`(D$).@#!_[_R<.0QT0D"&0$"0C'1"0$`P```(D$).CH!O[_R<.-M@````!5 +XMB>575E.![+P```"+50P/MD("/"-T.CPK=#H\+70VQT0D"`8```"+30R[`0`` +XM`(M!*(M`"(E$)`2+=0B)-"3HC)T``('$O````(G86UY?72+0#@Y^(F%7/__ +XM_W-XBU7'@Y +XM\'UT@\(!]D2!-4!T:H/#`3G[=>/K"XM=X(7;#X1X`0``QT0D"+\$"0B[`0`` +XM`,=$)`0#````BTT(B0PDZ)`%_O^!Q+P```")V%M>7UW#QX58____`0```.D' +XM____BT4(N@(```"[`0```.@B_O__Z]"+G5S___\[G5S___\/A,`!``"+30B) +XM65#'1"0$`````(D,).@8"`$`BW7%9/___P````"#P#(/ +XMA(P!``")1"0,C47HB40D",=$)`0`````BU4(B10DZ.9X_O^%P(F%9/___P^% +XM8`$``+L!````@<2\````B=A;7E]=PX/X`G8JB[5L____#[94%@&`^EB(E4__ +XM__\/E(57____#X3P`0``@/IX#X3G`0``A,D/A//^__^#^`$/ANK^__^+M5S_ +XM__^+C5#___^#Q@$/MA0Q#[["@_A_#X?3_O__]@2%W10)"`0/A,7^__^`^C@/ +XMA+S^__^`^CG'A6C___^S!`D(QX5@____"`````^%T_[__^F:_O__B9UL____ +XMB9U<____Z5W^__\/MD,!#[[0@_I_#X;#`0``@^@X/`%W0\>%:/___[.@"`C' +XMA6#___\*````@\,!Z9+^__\/OD,!@_A_=PKV!(7=%`D(!'7EB40D!,<$)-H$ +XM"0CHFU7]_X7`==&+30B%R0^$E_[__XM%"(M8$(7;#X2)_O__]H-5"````0^% +XM?/[__XU',CM#>`^'8`,``(M#=(F%9/___XM#>(E%Z(&+5`@````!``")\BN5 +XM7/___SMUY(F5%8/___Q````#IZOS___8$E=T4"0@$#X0O_O__/#@/ +XMA"[^__\\.0^%.O[__^DA_O__@/LKC70F`'0)@/LM#X6!_/__B[5<____BY50 +XM____QX5H____N@0)"(/&`0^^!#*#^'\/AY_[___IS'1"0, +XM"@```,=$)`@`````B00DZ&MS_O^#^`$/A:'^__^+30R+E5C___^`>0(M=0+W +XMVHM-[(7)#X[4`0``A=(/CLP!``"X____?RG(.=`/@[T!``"X`@```.ED_O__ +XMBT4,@'@"*P^$@P$``(M%\#F%6/___P^'+@$``"N%6/___XE%\(.]8/___Q"+ +XME7#___]U`X/J`HM%\(V->/___XE4)`R)1"00BY5H____QT0D!&0```")#"2) +XM5"0(Z"=5_?^)QXN%7/___XE$)`B+1=R)1"0$BY5D____B10DZ$96_?^+G63_ +XM__^-C7C___\#G6S___^)3"0$B7PD"(D<)`'[Z")6_?^+1>0KA5S___\KA7#_ +XM__^)1"0(`W72)1"0,B[5D____ +XMB70D"(M5#(M"-(E$)`2+30B)#"3H2]#]_XG#Z7+]__^)5"0(BX5L____`T7< +XMB40D!(N-9/___XD,).BI5?W_BX5D____BY5P____Q@00`(N%9/___^GR_/__ +XMA=)Y>+@```"`*<@YPGUMN`,```#I$/W__XE$)`R-0WB)1"0(BT-TB40D!(M- +XM"(D,).@4=/[_A<`/A#3[__^)0W3I<_S__X&@5`@``/_^___IQ?G__XM5\(G0 +XM]]`[A5C___\/@E/^__^+A5C___\!T(E%\.ER_O__AD?&@`` +XMBX'``@``C01`P>`"`T$0BT`XB5T0B4T(B44,6UWI_1D``(N!4`,``(T$0,'@ +XM`@-!$(M`.(E=#(E-"(E%$%M=Z=L9``"-="8`C;PG`````%6)Y593@^P0BW4( +XMBYZ<````A=MT8(N#,`$``(7`=`B)!"3H#57]_XN#1`$``(7`=`B)!"3H^U3] +XM_XN#?`$``(7`=`B)!"3HZ53]_XN&G````(N`C`$``(7`=`B)!"3HT53]_XD< +XM).C)5/W_QX:<`````````(/$$#'`6UY=PXGV58GE@^P8QT0D!,P!``")7?2+ +XM70B)=?B)??S'!"0!````Z&Y2_?^%P(G6````BT4,A=N)L)P```#'AJP! +XM````````#X3:````B[N<````BX=(`0``A$`0``,=*( +XMAH0!``"+AX@!``")AH@!``"+A[0!``")AK0!``"+7?2)T(MU^(M]_(GL7<.) +XM!"3H1U/]_X7`B<*)AD0!``!T+8N'2`$``(E$)`B+AT0!``")%"2)1"0$Z(]2 +XM_?^+AT@!``")AD@!``#I5?___\=$)`@`````QT0D!`4```")'"3H@OS]_[H! +XM````ZY$QTL>&B`$```````#K@Y"0D)"0D)"0D)"0D)!5B>575HG.4XMZ,('. +XM`(2$!(G#]\<`(```=`B)SH'.`(2$!O:#``$```$/A*`!``"+@_@```"-!$#! +XMX`(#0Q"+0#B%P`^5P(3`=`.#S@3V@PP!```!#X1E`0``BX,$`0``C01`P>`" +XM`T,0BT`XA<`/E<"$P'0#@\X0]H,\`0```0^$*@$``(N#-`$``(T$0,'@`@-# +XM$(M(.(7)#Y7`A,!T`X/.0/:#E`,```$/A.\```"+@XP#``"-!$#!X`(#0Q"+ +XM0#B%P`^5P(3`=`:!S@```!#V@Z\$```!=`:!S@`(``#V@R0$```!#X2B```` +XMBX,`"`T,0BT`XA<`/E<"$P'0&@'E`````$```")QHU%[(E$)!"-1?")1"0,C47HB40D"(M#-(D\)(E$ +XM)`3HYLC]_X7`=!J+5>R%T@^$!P$``(/.",=%\`````")=>#K%(M%\(7`#X3A +XM````@B%P`^$O0```(M#,(U3`8US/,=$)!``````B70D#"4``@`` +XM@_@!&<#WT"'"C4,TB40D"(E4)`2)/"3HVH3]_X7`=7:+1>#'1"0<`0```,=$ +XM)!@`````QT0D%`````")1"0@BT7PB40D$(M%Z(ET)`B)7"0$B3PDB40D#.BY +XM4P``@\0\6UY?7<.0B5-`Z6W___^+4P2#Z@&-!`*)0T"+5?"#Z@$YT`^&4___ +XM_^O<@\X(Z1?___^-="8`@\0\N`$```!;7E]=PXUS/.EU____C70F`(V\)P`` +XM``!5,'E`````0```")QHU%[(E$ +XM)!"-1?")1"0,C47HB40D"(M#-(D\)(E$)`3H9L?]_X7`=!B+5>RX`0```(72 +XM='B#S@C'1?``````ZQ"+3?"%R74#@\X(@B)1"0(B50D!(DT).B#QOW_A7UW# +XMBU7PA=)UKX/+".NJD(M'!.NOC70F`(V\)P````!5,&E`````````"+5S2)5DR)PXU%[(E$)!"-1?")1"0,C47H +XMB40D"(E4)`2)-"3HL\7]_X7`=&6+5>RX`0```(72=%$QTH/+",=%\`````#V +XM1S$(N`$```!T`XM'!(E$)!R+1>B)7"0@QT0D&`````#'1"04`````(E4)!") +XM1"0,QT0D"`````")?"0$B30DZ`)1``"#Q#Q;7E]=PXM5\(72=!.+1E"#P`$Y +XMPG0.B490ZYV-="8`@\L(ZY2#RPB)5E#KC(UV`%6)Y8/L&(E=^(M="(EU_(MU +XM#(U#4,=#4`````")1"0(BT8TB1PDB40D!.BQ:?[_AQ= +XMZ>#]__^+7?BX`0```(MU_(GL7<.058GE5E.#[#"+=0R-1?2+70B)1"00QT0D +XM#`````#'1"0(`````(M&-(D<)(E$)`3H#,']_X7`=1*+1?2#^`&-4/\9P/?0 +XM(<*)4U"+0Q"+D!@!``"%TG04BY`0`0``:X`<`0``'/9$`A0"=0B)'"3H'=?] +XM_XET)`2)'"3H(?[__X/$,%M>7<.-=@"-O"<`````58GE5U93@^Q,BUT,BW4( +XMBT,PBU,T)0_^__^#R"`[4SR)0S`/A!<"```QR8G:B?#H;/C__XE%T,>&E``` +XM``$```"+0S#!Z`.)QX/G`70SQT,X`````/:&#`$```$/A!X"``"+A@0!``"- +XM!$#!X`(#1A"+0#B%P`^5P(3`#X42`@``BT,TB49,BT,XB490BT80BY`8`0`` +XMA=)T%(N0$`$``&N`'`$``!SV1`(4`G4(B30DZ$K6_?^%_W4,BT,T.T,\#X0* +XM`@``C4,\C5,TB57R-1>B)1"00C47LB40D#(U%Y(E$)`B+0S2)-"2)1"0$Z'#"_?^%P`^% +XM#@$``(M5[#E3.'($@TW0"/9#,0BX`0```'0#BT,$BTW0B40D',=$)!@````` +XMQT0D%`````")3"0@B50D$(M%Y(E<)`3'1"0(`````(DT)(E$)`SHQ$T``(M- +XMU(7)B<-T,87V=!.+1A"%P'0,BU74.5!T#X0E`@``BTW4B0PDZ.U)_?^#Q$R) +XMV%M>7UW#NP$```"#Q$R)V%M>7UW#C47HB40D$(U%[(E$)`R-1>2)1"0(B50D +XM!(DT).BOP?W_A<`/A,#]__^+1>B%P'3!B5PD!(DT).B4^___BP`````Z>'^__^0BT,PC5,!C7L\QT0D$``` +XM``")?"0,)0`"``"#^`$9P/?0(<*-0S2)1"0(B50D!(DT).B:??W_A<`/A2/_ +XM__^+1>R%P'4$@TW0"/9#,0BZ`0````^%T0```(%-T``@(`"+3=")5"0B)1"0,QT0D"`$```")5"0$B1PDZ`6[_?^%P`^% +XM6____XM33(/J`?9',0BX`0```'0#BT<$BTW@B40D'(E4)!C'1"04`````(E, +XM)""+1>R)1"00BT7HB7PD!(D<),=$)`@`````B40D#.C`20``@\0\6UY?7<.- +XM1?")1"0$B1PDZ-F\_?^%P`^%[_[__XM-\(7)#X6&_O__,=+'1>@`````QT7L +XM`````.EZ____D%4QR8GEBT4(BU4,7>DO_O__ZPV0D)"0D)"0D)"0D)"05;D! +XM````B>6+10B+50Q=Z0S^__^0D)"0D)"0D)"0D)!5B>6#[`B+30R+02R%P'0& +XM]D`&('4JA<#'04``````=`KV0`8@=`2#:3@!BT%`BU$\B4%(,<")443)PY"- +XM="8`BU$XA=)USXM%"(D$).C^A0``N`$```#)PXVT)@````!5B>6#[`B+30R+ +XM03B%P'10]D$Q"+H!````=34YPG(HQT%``````(M!+(7`=`KV0`8@=`2#:3@! +XMBT%`BU$\B4%(,<")443)PRG0B4%`Z]B)]HM1!#G"<\CK[HVT)@````"+10B) +XM!"3HA84``+@!````R<.-M"8`````C;PG`````%6)Y5.#[!2+70SV0S$(='"+ +XM0P2#^`%V:(/H`8E#!(E$)`B+0S2)1"0$BT4(B00DZ,SR``")P8E#0(M#+(7` +XM=`KV0`8@#X66````BU,X.=%V1H7`#X2D````]D`&((UV``^$EP```(U!_XE# +XM0(M#-(E32(E#1#'`ZS:-M"8`````BT,LA-M"8`````A!W5`^$*`$``(M+.(/N`8E+2(E[1`^$D0```(M#/#E#-',+ +XMBU-`A=(/A(4```"#:T`!,<#I0____XM#0(M3/(E#2#'`B5-$Z3#___^+4SR+ +XM>S2)5>#KIXM30(M+.(G(B=&)4SB+5>")>SR)0T")UXE3-.N8@TLP"+X!```` +XMZ37___^+4T"+2S@YR@^$KP```#G1#X9T____Z\.%T@^$.?___Y"-="8`Z>O^ +XM__\QP.G)_O__@^@!B4,\C77PB40D!(M%W(ET)!#'1"0,`````,=$)`@!```` +XMB00DZ'BT_?^%P`^%D/[__XM%\(ET)`C'1?``````@_@!C5#_&<#WT"'"BT,T +XMB5-`BU7EO_?__ZPV0 +XMD)"0D)"0D)"0D)"058GE@^P8BU4,QT0D#`$```"-0C2)1"0(#[9"`HE$)`2+ +XM10B)!"3H9=C]_\G#D)"058GE5U93@^Q,BTT,C47HBW4(B40D$(U5Y(U%[(E$ +XM)`R)5"0(BT$TB30DB40D!.B]MOW_A7UW#BT4,BUWLBT@X.=ESRXG*`U7D +XM#[8"#[[P/#Z)=<`/A`0"``!_)SPI#X0M`@``/#P/A!0"```\*(UV``^$^`$` +XM`(/!`8/"`3G9=-(E.0#G##X.C`0``BW4,BU8L +XMA=(/A+P!``#V0@8@#X2R`0``BT8XB5Y$B49(A=(/A*````#V0@8@#X26```` +XMBW4,B=J+1CPYPP^$A@````^#CP$``(GS@\,TBTL$AP/A-\````/M@(\ +XM(`^$O0```#P)#X2U````,<")]NDY_O__#[9%W#M%P'07.46\#X7*_O__@^X! +XM#X7!_O__Z?'^__^#Q@'IM/[__SQ[D'09/'T/A4S^__^[\"H'",=%O'L```#I +XM:_[__[L`+`<(QT6\?0```.E:_O__N_`J!PC'1;Q;````Z4G^__^[\"H'",=% +XMO#P```#I./[__[L`+`<(QT6\*0```.DG_O__NP`L!PC'1;P^````Z1;^__^[ +XM\"H'",=%O"@```#I!?[__XM%[(/"`8E5Y(/H`87`B47L#X4A____BTT,,<"# +XM23`(Z6C]__\/A(8```"+50R)2DB)0D2+30R+42SI9/[__\=$)`@,!0D(Z2G] +XM__^+=0R)3DB)1D3I2?[__XM=#(/#/.EK_O__BUT,@\,TZ7G^__^-1?#'1?`` +XM````B40D"(L#B40D!(M%"(D$).A06/[_A<`/A?'\__^+0P0[1?`/AZC^__^+ +XM30R+432+03SI*O[__SM..`^&R+@'P!``"%P'0(B00DZ-@Z_?^%_W03BT7HB7PD!(D< +XM)(E$)`CHD3G]_XM%$(7`=!R+51"-1@&)1"0(B50D!(M5\(T$$XD$).AN.?W_ +XMBT7LB9A\`0``,<#I-(7`=`;V0`8@=52)V(/X +XM`78IBT4(C57PC4WLB50D$(E,)`S'1"0(`````(E<)`2)!"3HN*[]_X7`=$2[ +XM`0```(E>/#'`QT9``````,=&2`````")7D2#Q#Q;7E]=PY"+1CB%P`^%50$` +XM`(/[`0^$T0$``(-.,`B-0_^)1C3KCL=%W`(```#V1C$(#X4_`0``BT7PA<`/ +XMA70!``#'1=@!````BT4(@^L!C57PC4WLB50D$(E,)`S'1"0(`````(E<)`2) +XM!"3H):[]_X7`#X5I____BTW8A0'K$HUV``^V0@*#P@*$P`^$ +XM5/___XGY.,AUZP^V0@$\(`^$``$``(M-U#I!`G77@VW<`771D.G,_O__@WW8 +XM`8VT)@````!T!>AM,_W_BT7PA<`/A!'___^)1"0$BT7LB00DZ!]X``"%P`^% +XM^O[__X-MW`$/A([^___'1=@`````Z>3^__^0@^@!B48XB=CI0?[__XUV`(M& +XM!`'`B47`"#X7V_O__D(UT)@#I]/[__XUT)@"-O"<`````58GE5U93 +XM@^P\BWT,BTB) +XM3=2)1"00B50D#,=$)`@`````B5PD!(M%"(D$).C"J_W_A@8,?W_C70F`(M-\(7)#X05____B4PD +XM!(M%Z(D$).C&=0``A<`/A6W___^#;=@!='.+3?#'1=``````Z>G^__^+3?"# +XM^0$/AMW^__^+50B+@IP```"+@'P!``")1

.+ +XM5-U[`^V0@$\(`^$F`$``#I&`G7; +XM@VW8`775BT7UW#@?M``@D(#X7, +XM_O__BTB)!"3H%70``(7`#X2F +XM_?__Z9#]__^#;=@!C70F``^%J?W__^FP_O__D(UT)@"+3?"-<_^#^0$9P(U1 +XM__?0(<(Y5S@/A:+]___'1"0$`````(M%"(D$).AB=@``N`$```#IP?W__X/Y +XM`@^%7_[__^E?_O__N`$```"0C70F`.FD_?__BTWPZ#[;` +XM_R2%,`4)"+DY````BX.<````B$H!B(B9````6UW#N3(```#KY[DS````Z^"Y +XM-````.O9N34```"-="8`Z\ZY-@```.O'N3<```")]NN^N3@```#KMXVT)@`` +XM``!5B>575E.#["R+70R+?0B+0S#VQ"`/A<(```#VQ`B^`0```'0#BW,$C4,! +XMB47PC4-$B47L@^X!@_[_#X2N````BT,P)0`"``"#^`$9TO?2(U7PQT0D%`$` +XM``"+1>S'1"0$`````(E4)`B)/"2)1"00C4,TB40D#.BT%?[_A<````B46TC47LB40D$(U%Z(E$)`S' +XM1"0(`0```(M&-(D\)(E$)`3HTZ7]_X7`#X6A`0``BT7LA<`/A$,!``#'1;@! +XM````]D8Q"'0&BU8$B56XBT8TB48\BT8X@^@!`T6XB49`BU7L@^H!.=`/A[4! +XM``#'1;P`````]D8Q(`^$)@$``(7_#X19`0``BU\0A=L/A$X!``#V@U4(```! +XM#X5!`0``BT7L.4-X#X(@/A$\!``"+ +XM5;2+@D`!``"#^`P/A$\!``"+3;2+5<`#5C@/MH$\`0``BTVXB10DB40D!(E, +XM)`CHR"S]_XM%[(E$)`R+1<")1"0(BT8TB3PDB40D!.AGJ?W_B<.%_W03BT<0 +XMA' +XME`````0```"-77UW#BT7LQT7P`````,=%P`````"%P`^$TO[__XE$)`R-1?") +XM1"0(QT0D!`````")/"3HUTS^_X7`=+F)1<"+1>SIJ/[__XU&-+L!````B40D +XM!(D\).B4<```@\1QT6/:'#`$```$/A$,"``"+AP0!``"- +XM!$#!X`(#1Q"+0#B%P`^5P(3`B=%T+HM=Z`^^$X72>"<[%?P@"0A]'Z$((0D( +XM]D20-@)T$XU!_X-%Z`&%P(G!B47L==*+7>B+1>R)7"0$B3PDB40D#(E$)`CH +XM*&']_X7`B<-T_?_IZ?S__\=$)`@'````,=O'1"0$`````(D\).C$;``` +XMZ1_]__^)7"0$B3PDZ,/#``"%P`^$(____^D\_?__@_@)C78`=60QV^GW_/__ +XM@8^L!`````0``+L!````Z>/\__^!H%0(``#__O__Z:'\__^)1"0,C4-XB40D +XM"(M#=(D\)(E$)`3H"DK^_X7`#X3H_/__B4-TZ;K[__^+GP0!``"%VP^5P.G$ +XM_?__#[9%V(M-M(B!/`$``(M%W(F!0`$``.EC^___D)"0D)"0D)"0D)"0D)"0 +XM58GE5E.#[#"+70R+=0CV0S$(=%R#>P0!=%:-0T#'0T``````B40D"(M#-(DT +XM)(E$)`3HN4C^_X7`#X7"````BT,LA7<.+1?2%P'3)C5#_ +XMBT,LB5-`A7<.- +XM=@"#Q#`QP%M>7<.-M"8`````BT,\B5-(B4-$@\0P,6#[#B)7?2+70R-1>R)1"00C47PB77XBW4(B7W\B40D#,=$)`@` +XM````BT,TB30DB40D!.BVHOW_A6#[`B)'"2)="0$BT@\BW!`B4A$B7!(BT`LA/KV(GVC;PG`````%6X`0```(GE4X/L%(M=#/9#,0AT +XM`XM#!(E$)`B-0SR)1"0$BT4(QT0D#`(```")!"3HJO0``+H!````AR+61"-0P@Y`0^$D`````^V@6P$ +XM``"+<4"#X`&(1?-U7HN19`0``(G0.?!V8XGRBT7L#Z_"N@$```"#^`)V`XU0 +XM_HU'/(E4)`C'1"0,`````(E$)`2)#"3HHO,``+H!````AR+61"- +XM0P@Y`0^$D`````^V@6P$``"+<4"#X`&(1?-U7HN19`0``(G0.?!V8XGRBT7L +XM#Z_"N@$```"#^`)V`XU0_HU'/(E4)`C'1"0,`P```(E$)`2)#"3HLO(``+H! +XM````AED&O__C70F +XM`(E-#(E5"%WI-/___XUT)@!=Z3JX__^-=@"-O"<`````5;H!````B>6#[`B+ +XM30SV03$(=`.+402+030YPG,4*=")PHE!/(M!0(E11(E!2#'`R<.-032)1"0$ +XMBT4(B00DZ"QE``"X`0```,G#D(UT)@!5,<")Y5.#[!2+70SV0S$(=`:+0P2# +XMZ`&)1"0(C4,\B40D!(M%",=$)`P`````B00DZ+KA``"Z`0```(7`=0F)V.BZ +XM^O__,=*#Q!2)T%M=PU6)Y5.#[!2+70S'1"0,`@```,=$)`@`````C4,\B40D +XM!(M%"(D$).ATX0``N@$```"%P'4)B=CH=/K__S'2@\04B=!;7<.-=@"-O"<` +XM````53'`B>53@^P4BUT,]D,Q"'0&BT,$@^@!B40D"(U#/(E$)`2+10C'1"0, +XM`P```(D$).@:X0``N@$```"%P'4)B=CH&OK__S'2@\04B=!;7<-5B>564X/L +XM((M=#(MU"/9#,0AT+(M#!(DT)(E$)`3H79G]_X7`=#N+0P2)0SR)V.C<^?__ +XM,<"#Q"!;7EW#C78`C47TB40D!(DT).C1F?W_A9_?^%P'0/C78`@\0@N`$```!;7EW#BU7TA=)UM>N!D)"0D)"0 +XMD)"0D)!5B>6#[#B)7?2+70R)??R+?1")=?B+2S2+Q=PXGV==,[4T!VSHGVC;PG`````.NP +XMBU-`A=)UTH/H`8E#/(UU\(E$)`2+10B)="00QT0D#`````#'1"0(`0```(D$ +XM).AKEOW_A6#[#B)7?2)TXE-\(M-#(EU +XM^(G&BT,LB7W\BWT0BW2)1?"!BU0(`````0``QT0D%'T&"0B+AIP```"+@#`!``#' +XM1"0,A08)",=$)`BRN`@(B40D$(M%\(D\)(E$)`3H^AS]_XGYQT0D"`$```#' +XM1"0$0````(D$)(M5#(GPZ!?^__^)P^MFC78`,?^%TL=%\`````!U=,=$)!1] +XM!@D(BX`P`0``QT0D#(4&"0C'1"0(LK@("(E$)!"+1?")/"2)1"0$Z)8<_?^) +XM^<=$)`@!````QT0D!$````")!"2+50R)\.BS_?__A?:)PW0,BT80A_?^#Q"R)V%M>7UW#C47PB50D#(E$)`C'1"0$`````(DT).@T +XM//[_A(E4)`R)1"0(BT-TB30DB40D!.CR._[_AZ`0`` +XM`(GVB50D"(M5##')QT0D!"````#'!"0`````Z*/\___)PY"Z`@```.O9B?:- +XMO"<`````58GE5XG75HG&4X/L3/9",2`/A1D"``#V@$P#```!#X7<`0``BX!$ +XM`P``A<`/E<`\`1G`,=(E````^`6`B$`(@_D"#Y3"@^H!@^+P@\(_B40D#(E4 +XM)`B)?"0$B30DZ"Y7``"%P`^%M@$``(M6>(M".(7`#X2H`0``@_@%#X31`0`` +XMBT((BUX0B8.0````BT(0QX,``0``````!(F#E````(M&$(N`&`$``(7`=0K' +XM@P`!```````%BT9,B47$BT90B47,C47PB40D"(V#@````(E$)`2)-"3H!$3^ +XM_X7`#X4\`0``BX.0````B470BX.4````B47(QX.4`````````(M%\(7`#X75 +XM````BX/@````@_@!#X2B`0``@_@"#X2"`0``BT<\B30DB40D!.C.DOW_A<`/ +XMA#X!``"+1RR%P'0*]D`&(`^%T`$``(N+``$``(M=R(7;#X20`0``BT70@#AZ +XM=5V+7LA@^L!#X2O`0``@\(! +XM#[8*#[[!@_A_=PKV!(7=%`D(!'7?C4'3/`$/AE8"``"`^2L/A$T"``"`^5X/ +XMA$0"``#'1"0(/`8)",=$)`0#````B30DZ-?$_?^-M"8`````BT7$B4=$BT7, +XMB4=(@\1,N`$```!;7E]=PXVT)@````"+@$0#``"-!$#!X`(#1A"+0#B%P`^5 +XMP.D3_O__C70F`+@!````@\1,6UY?7<.-=@")3"0(,7UW#BT9,B4<\BT$``!``B5=$#X0?____BTK^___'1"00#````,=$)`P!````QT0D"#\- +XM"0C'1"0$`````(DT).AMA/W_A<`/A;7^___'1"00#````(M%R(E$)`R+1=#' +XM1"0$`````(DT)(E$)`CH/X3]_X7`#X6'_O__BT<\C5W6+10B+50Q=Z"+5>"X`0```(72#X3N````BT4,]D`Q"`^%40$``,=%W`$```"# +XM[@&-5?"-3>R)5"00B4PD#,=$)`@`````B70D!(M="(D<).B`C?W_A<`/A>T` +XM``"+3?"%R73)BUWLB5W8#[8#/'L/A+0````\#`^$K````#PN=:R#^0&0=J:+ +XM5>`/M@*$P'2L+#[9"`H/"`H3`=(B)^SC8=>\/MD(!/"`/A'X` +XM``"+7=@Z0P)UVX-MW`%UU8M%#(EP/,=`0`````"+50R+0CB%P`^%B0```(M" +XM,(-J-`$E#_[__X/(0(E",(-*,`B+70R+0T"+4SR)0T@QP(E31(/$/%M>7UW# +XMBX%0`P``C01`P>`"`T$0BT`XB47@Z>#^__^#;=P!#X7Z_O__ZY"#^0(/A7G_ +XM__^-M"8`````Z77___^+10S'0#P!````QT!``````(M5#(M".(7`#X1W____ +XMBTT,@^@!B4$XZ7____^+50R+4@2)5=SIJ/[__\=$)`0`````BU4(B10DZ(U8 +XM``"#Q#RX`0```%M>7UW#58GE5U93@^P\BT4(]H!8`P```0^$%P(``(G"BX!0 +XM`P``C01`P>`"`T(0BT`XB478!``"+50R+6C2#PP&- +XM5?"-3>R)5"00B4PD#,=$)`@`````B5PD!(M%"(D$).B4B_W_A<`/A?X```"+ +XM3?"%R73)BW7L#[8&/'MT?8M5#(MZ+(7_=!'V1P8@=`L\?71IC;0F`````#P, +XM#X2D````/"YUF(/Y`9!VDHM5W`^V`H3`=(@/ME8!B%7CBU7-U[`^V0@$\('1T.D8"==^#;=@!C78`==:%_W0F]D<&('0@ +XM@^L!D.M_@VW8`0^%./___SQ[B?8/A',!``"+30R+>2R+10R%_XE8/,=`0``` +XM```/A9T```"+10R+4#R)P8M`0(E11(E!2(/$/#'`6UY?7<.#;=@!#X7N_O__ +XMZYJ#^0*0C70F`'6"@VW8`0^%7/___XUT)@#K@(M5#(/K`3E:-`^$[@```(U% +XM\(E$)!#'1"0,`````,=$)`@!````B5PD!(M5"(D4).A9BOW_A +XM_O__D)"0D)"0D)"0D)"058GE5U93@^P\BU4,C7W8BT(TB478BT(XB47R#^`$/ +XMA,T!``"%P`^$I0$``+L!````B7PD!(M-"(D,).C$G/__A<`/A4R# +XM^`(/A.N#@_L"C;8`````=`B%VP^%_O[_ +XM_X/N`8UV``^%\O[__XE\)`2+70B)'"3HNYO__X7`=4*+=>R%]@^%9?___P^V +XM5>@[%?P@"0@/C57___^A""$)"/9$D#8"#X1%____B7PD!(M%"(D$).CMG?__ +XMA<`/A"[___^X`0```(/$/%M>7UW#@_X!#X08____B7PD!(M5"(D4).C`G?__ +XMA7UW##[95Z#L5_"`)"'T,H0@A"0CV1)`V`G47B5PD!(DT +XM).A+F/__AR%P'4K#[9%Z#PI=-T\7739/")TU3PG +XM=-$/MM`[%?P@"0A](*$((0D(]D20-@)T%(E<)`2)-"3HRYK__X7`#X7'_O__ +XMBU78.5R#^`-TY(7`#X6\````#[95Z#L5_"`)"'T,H0@A"0CV1)`V`G7$BT7$@T7, +XM`8E%V(M%R(E%W.F:_O__@/H_#X7?_O__BT70A<`/A(W^__^#;7UW#B5PD!(DT).B:F?__A<`/A#+^___I\?W__XE<)`2)-"3H89;_ +XM_X7`#X7=_?__@WWL`W3FC78`Z0O^__^#Z`$/A5/___^+5=B+1RR)5SR+5=R% +XMP(E70'1B]D`&('1#0!#X0N`0``BX*0`0``BP")@I0!``"+@9P```"+ +XM@)`!``"+0`B)@IP!``"+@9P```"+@)`!``"+0`2)@I@!``"+04")@J`!``"+ +XM042)@J0!``"+03R)@J@!``"+04`Y040/A-4```"+F9P```"-!$"+DXP!``"# +XMZAB--,*+DY`!```YUG90BP*#P`&)0AB+@9P```"+D)`!``"+@(P!``"+0`2) +XM0AR+@9P```"+@)`!``#'0"`!````BX&<````@X"0`0``&(N9G````(N3D`$` +XM`#G6=["+DY`!``"+`H/``8E"&(N!G````(N`D`$``,=`(`$```"+@9P```"+ +XM@)`!``#'0!P`````BX&<````BX"0`0``QD`N`(N!G````(.`D`$``!B+04"# +XMP`&)04")042)03Q;,7<.+F9P```#KDHVV`````(V\)P````!5B>575E.# +XM["R+11"%P`^$"`$``(M`"(E%\(M-%(M]\(7)#X2:````#[X'A<`/B(\```"+ +XM-?P@"0@YQ@^.@0```(L=""$)"(GZ]D2#-@)U&>MP#[X"A(M5&(E""(M-&(M1$(72=)2+31B+00B)5"0(B40D!`'8B00DZ'T* +XM_?_I=____XM%#(7`=12+11C'0!P`````@\0L,575E.)PX/L/(E5U(E-T,#B+5=2+3=B+4@B%R8E5Z`^$80$` +XM``^V$@^^PH7`#XA3`0``BS7\(`D(.?")=>P/C4(!``"+#0@A"0B)3?#V1($V +XM`@^$+@$``(MUZ#';BT78QT7<`````,=%X`````"-!`:)1#@[1>Q],XM-\/9$@38"="F`^@EUTX7;=`?'1>`! +XM````BU70`````=QR)^^L"B#1>0!C0P[*=$[3=QV +XMZHG8BWW)\"M%Z(T4#SG0=&HI1=B)PXM%V"G3B70D!"G>B30DB40D +XM".B*"/W_BU74*5H0*5H8BUWDBTW4@^L!@_O_BU$(=!J+=>2)T(T,%HUT)@#& +XM``F#P`$YR'7VC50:`87_=`V-!#K&`B"#P@$YPG7VBT70QP`!````@\0\6UY? +XM76#[!C'1"0(Y`<)",=$)`0"````B00DZ`*R_?_)PU6)Y5>)QU:) +XMUE.#[#SV10L!B4W8#X1>`0``BT(HA<`/A`L!``"#Z`&)0BB0C70F`(M=V(M& +XM&(M."`^V$X@4`8/``8E&&#'`@\0\6UY?7<.)T0-.$#M.#'8KC48,B40D"(M& +XM"(E,)`R)/"2)1"0$Z"TF_O^%P`^$U0(``(E&"(M5[(M%Z"G"BT8HB57['1>@`````BT7@A``````ZTT\_P^$Q@````^VP(T$0`'``T<0#[:`70$``(E%[(M5[(M%Z#G" +XM#X0)____#X-,_O__*="#1>`!A<")1>@/A/G^__^+1BB%P`^$[O[__X/H`8M6 +XM"(E&*(M%\`^V!`(\"76?C47LB40D$(M&%(E<)`R)5"0$B3PDB40D".@_N``` +XMZYR)1"0,C48,B40D"(M&"(D\)(E$)`3H,R3^_X7`#X3;````BU8@@T80`8E& +XM"(72#X2I_?__Z<+^__^+3@B+5A@/M@01B$01`>F1_?__D,=$)`3_____B3PD +XMZ$!M_?_I-____\=$)`3_````B3PDZ"MM_?_IX_[__XM%W(7`#X0Q_O__,<#& +XM1!`!((/``3M%W'7SZ1W^__^)T`-&"`^V&,8`"8U%Z(E$)!"-1?")1"0,BT84 +XMB3PDB40D"(M&"(E$)`3H>+<``(M6"(M%\(@<`NF*_O__BT7PBU8HBUW@`T8( +XM`U8@`U7@B00DB50D"(T4&(E4)`3HF03]_^G5_?__N`$```#I[?S__\=$)`3_ +XM____B3PDZ(9J_?^+3@B)PNEN_?__C;8`````C;\`````58GE5U:)UE.#[$R) +XM1#B+5`"`T(0BT`XB47,BUX8,)^"G0`47@.5X8=]^+5>`QVSE5 +XMU,=%V`````!V'8G3B=`QT@'[]_>+1>`ITSE=U`^#O````(M=U"G#BT7-=@"+1BB+?C2%P(E^$'1#@R'WBPLYT715 +XMBT,$B4$$BT,$B0B)'"3H=S/]_\=$)`@!````BT84@\`!B40D!(M%\(D$).@: +XMQ0``@_@!&=LA\^N%D(M&((7`=;:+1@C&!#@@@T8@`8-&$`&#"0CKI8M#!(E! +XM!(L+ZZ>-="8`C;PG`````%6)Y5=64X/L7(E%U(M%#(E5T(E-S,<``````(M" +XM&(M2)#G0B578#X1,`0``BUW0C4C_BW,(`"+7<"#Z0$I +XM^X/'`3M-V'12BW7`B?CWV`^V%#`/ML([1>!]#8MUR/=$AC0`!0``=3*`^E]T +XM+3M%X'W&BU7(]D2"-@)TO.L7UW#B7PD +XM!(D<).C2(/[_A<`/A+<```"+11#'``$```"#Q%PQP%M>7UW#QT0D$`$```"+ +XM0R")1"0,BT,7UW#BUW(]T2#-``%```/A%+^__^A_"`) +XM"+\!````BUW`B47<@^D!@^L!@\B+2AB+0QR#Z0&) +XMR@-3"(E%Y*$((0D(B7WLB47PZPLY2R1T)(/J`8/I`0^^`H7`>`\[1>Q]"HM] +XM\/9$AS8"=32#Q@$[3>1UUXET)`2)%"3H%Q_^_X7`=0Z+?>B##P2#Q!Q;7E]= +XMPXM%Z(,@^X/$'%M>7UW#@\(!.4WD=,PY2R1UU^O%D(VT)@````!5B>57B==6 +XM4X/L'(M"&`-""`^V$(A5\\8``(M'&(/H`8G#`U\(@#L8=#"+3QPYP70IBUNBT<8BU<(#[9-\X@,`HM' +XM""EW&(M7&"EW$(A<`O^+5RB%TG4HBU<@A=)TD(M'&`-'"`-'*(E4)`B-%#") +XM5"0$B00DZ)'\_/_I;____XM'&`-'"(E4)`B-%#")5"0$B00DZ'/\_/_KO8VV +XM`````(V\)P````!5B>575HG&4X/L#(NXG````(-X-`&)^0^$TP```(N7J`$` +XM`(E0/(N'I`$``(E&1(N'H`$``#M&1(E&0`^$Y````#G0B=-R,HM&$(E<)`2# +XMPP''1"0(`````(DT)/^0D`@``(M&$(DT)/^0;`@``#E>0'/4BXZ<````BT8\ +XMBY&,`0``C01`@^H8C03"B8&0`0``]H84`@```75RBXX,`@``AL`0`````` +XM`(/$#%M>7UW#BX8,`@``C01`P>`"`T80BU@XA=L/E,#K@(.OD`$``!CI8/__ +XM_^L-D)"0D)"0D)"0D)"0D%6)Y5=64X'LO`(``(M%"(M5"(M-"(MU%(M`$(F% +XMB/W__XN2G````(F5?/W__X&)K`0```````B#P7B+70B)C8S]__^+6W@YRXF= +XM8/W__P^$6A$``#D+#X1;"```BUT8@\,@BX6,_?__B00DZ$`M_?^)7"0,BWT8 +XMB70D!(E\)`B+10B)!"3HIB[]_X7`B85@_?__#X3H!P``BU4(BXU@_?__BT)X +XMB0&+G8S]__^)600Y6GP/A$$/``"+=0B+O6#]__^+1GB)>`2+E6#]__^+10B) +XM4'B+C6#]___'03@$````BUT(BT-,B4$4BU-0B5$8BUT8A=L/A#]``"%P`^%3P8``(M%**@0=$B+ +XM52"%TG1!B[U@_?__QT0D#`````#'1"0(`````(E\)!"+12")1"0$BU4(B10D +XMZ"7M__^%P`^%#08``(M''(E'&.L9D(UT)@"H`@^%"`8``(N=8/W__XM#&(E# +XM)/9%*D!T(8NU8/W__P^V31R+1AB+5@B(#`*#P`A`!@T8D`8E&&/9%*`@/ +XMA6(&``#V12M`QX6@_?__`````'0OBWT(]H>0!````0^%>08``(M5"(N"B`0` +XM`(7`#X2"!@``BTT(BTDX*<&)C:#]__^+O8C]___'1=P`````]H=4"````0^$ +XMB@4``/9%*@3'A9#]__\"````#X1V!0``BU4H]\(````"=!:)T"7__W__B44H +XMB<+'A9#]__\`````B="+30@E````"(/X`1G`@>(```0`]]"#X`.#^@&+E6#] +XM__^(A:C]__\9P/?0@^`$B47@BT(4B4%,BT(8B4%0QT0D!`$```")#"3H?J0` +XM`(7`#X76!```BUT,]D,Q(`^$QP@``,>%F/W__P````#'A%I/W__P````#'A=3]__\`````QX64_?__`````,>%P/W__P`` +XM``#'A)O83]__^+M=3]__^%]G0:BY6$_?__@'H,(`^$ +XM!Q\``,>%U/W__P````"+C83]___V010(#X68"P``@[V8_?__`@^4PH.]F/W_ +XM_P0/E,&$TG4$A,ET3(M%X(/@[_9%*@2)1>!T!H/(!(E%X(32=!6+G83]__^+ +XM0Q"#Z!"#^`$/AM8B``"$R700BX6$_?__@W@0#`^%8R,``,>%F/W__P````"# +XMO%`D(`74@BY5@_?__BT4(Z)7X +XM__^%P`^%$`<``,>%R/W__P````"+G83]__^+2Q"#^10/AD@'``#V12A`#X32 +XM"@``BX6$_?__#[90##L5_"`)"`^-:0T``*$((0D(]D20-0(/A%D-``"#^0H/ +XMA%`-``"#^0\/A$<-``#'1"0(<`@)",=$)`0"````BU4(B10DZ+2?_?_V12L" +XM#X65#```BXV@_?__A%S/W__P````"+A7S]__^+@%P!``"% +XMP`^$@@P``(M-"/:!KP0``!!U*HN%Q/W__X7`=2#'1"0(`````,=$)`0````` +XMB0PDZ'1X``"%P`^%+`(``(N%H/W__X7`=1"+70B+0Q"+@!@!``"%P'4UB[5@ +XM_?__BWT(BT84B4=,BT88B4=0,<"#O:#]__\`B3PD#Y7`B40D!.B%H0``A<`/ +XMA=T!```/MH6H_?__J`*)A5S^__\/A/T```"+50B#>C0!#X3I````BXU@_?__ +XMBTD8@_D!B8TX_O__#X;<&P``B[5@_?__BUX(B[4X_O__#[9$'O\\7(B%/_[_ +XM_P^$#AL``(M5"/:"?`,```$/A+<:``"+@G0#``"-!$#!X`(#0A"+4#@/OH4_ +XM_O__B10DB40D!.B`\/S_A"(MV&(FU./[__P^V1![_B(4__O__#[:5 +XM/_[__SH3#X6O&```@[TX_O__`G0+@'P>_EP/A)L8``"+30R+432+03B)442) +XM04B`I:C]___]]D4K`@^%4OS__^D=!0``#[:%#/___SGP#X0N&@``.<,/A0(7 +XM``"#K2#^__\!#X7U%@``BY7\_O__.Y5X_O__#X(&_O__#X6;)@``BX4`____ +XM.X5\_O__#X+N_?__BTT(B5%,B4%0QT0D!`$```")#"3H]9\``(7`=5&+70CV +XM@UP"```!#X1-)@``BX-4`@``C01`P>`"`T,0:T`X9,=$)`Q`````B40D",=$ +XM)`0`````BWT(B3PDZ/]@_?^%P`^$A_W__XVT)@````"X`0```('$O`(``%M> +XM7UW#BXU@_?__BT$8QT$D`````(E!'.GL^?__QX60_?__`````.E[^O__BUT8 +XMB[U@_?__@\,@.5\,#X*6]___BY5@_?__A?;'0B@`````QT(D`````,="(``` +XM``#'0AP`````#X3#"```BTT8B4H0B4PD"(ET)`2+0@B)!"3H%?+\_^F_]___ +XMBT48B[U@_?__*=")1R#I]_?__XN=8/W__XM#"(M3&,8$$""#0Q`!@T,@`<=$ +XM)`@#````BT,4B40D!(MU"(DT).CGM0``Z6?Y__^+AX@$``"-!$#!X`(#1Q"+ +XM0#B%P`^%?OG__XM="/:#A`0```$/A!((``"+@WP$``"-!$#!X`(#0Q"+0#B) +XMA:#]___I7_G__XN]8/W__XM'&`-'"(T,&(M%"/:`#`$```$/A/4=``")PHN` +XM!`$``(T$0,'@`@-"$(M0.(72#Y7`A,!T08N%G/W__X7`=##O93]__\"#X15(```B70D +XM$(N-8/W__XM!&(E,)`C'1"0$`````(E$)`R+70B)'"3HPN3__X7`#X5-`0`` +XMQX64_?__`````(M&'(E&&(N%T/W__X7`#X3(````BX5@_O__A$(N-8/[__P%.&(N=,/[__XE>*(N]+/[__XE^(,>%T/W_ +XM_P````"+?BB%_W4LBUX@A=MU)8M&$(/``3M&#`^'("```(--*`B+5@B+1AC& +XM!`(@@T8@`8-&$`''1"0(`@```(M&%(E$)`2+50B)%"3H-[,``(N-8/[__XFU +XM8/W__XF--/[__X7`#X1S^?__BU4(BT)XBU@4ZPF)]H7;=!J#ZP&)7"0$BTT( +XMB0PDZ$IF_?^%P'3FA=MU!;L!````BW4(N`$```"#CJP$``!`B5Y,QT90```` +XM`('$O`(``%M>7UW#_R2-J`@)"(UUM,>%F/W__P````#'A%I/W__P````#'A=3]__\`````B;6$_?__QX64_?__`````,>% +XMP/W__P````#'A`7`$```````#'@%@!````````QX!4`0`` +XM`````(E<)`2+50B)%"3HM(4``,=$)`0!````BTT(B0PDZ(&:``#'A<3]__\` +XM````B[V$_?__@W\("P^&UP,``(N=A/W__XE<)`2+=0B)-"3HDE;]_X.]D/W_ +XM_P(/A!,+``#V1>`$=`KV12H"#X7-!0``]D4H")!T$8N]8/W__XM/((7)#X7P +XM!```]D4K`0^$R@```(N%8/W__XMP*(7V#X3^````BU4(,=N+2GB)RNL2BT(0 +XM`T(LBQ(!PSF5C/W__W03.Y5@_?__=>:+O6#]__^+1QCKX3E=&`^&C````(U% +XMT,=$)!``````B40D#,=$)`@#````BT$4B40D!(M%"(D$).AO8OW_A(F%$/[__P^% +XMCP0``,=%T`````"+0Q")1"0,BT,(B40D"(M#%(E$)`2+30B)#"3H.F;]_X7` +XM#X6U_/__BU70A=(/A3,0``"+`$=!?V12H"=!&+E6#]__^-3>"+10CH;NS__XN%D/W__X7`="R+O83]__\/ +XMMD\,#[;1.Q7\(`D(#XS)`0``@/E?QX60_?__`0````^$R0$``(M%*(G9B00D +XMBY5@_?__BT4(Z&+B__^%P`^%/?O__X.]F/W__P,/A``)``"+O>[__X-O$`&#;R`!Z0/[__^)P2G1Z4KZ___'1"0(!P```,=$)`0````` +XMBTT(B0PDZ`PI``#II?K__XET)`2+50B)%"3H"(```(7`#X2G^?__Z3OU__^+ +XM10B!B*P$````!```N`$```#I*?7__XN-I/W__X7)#X5E!P``BT4HJ0````(/ +XMA5<'``"+O83]__^`?PP`#X5'!P``BY5\_?__BY)$`0``A=(/A(_^__\E__]_ +XM_PT````"B44HQX60_?__`````.E9\/__BY5@_?__C4W@BT4(Z#?I___I'?K_ +XM_XM%"(U-T(G:Z#7=___I9OO__XE$)`R)T(/`#(E$)`B+0@B)1"0$BTT(B0PD +XMZ.$%_O^%P`^$'/C__XN=8/W__XE#".G+_?__B[5@_?__BT88.T8<#X<(\?__ +XM]D4H$`^$_O#__\>%E/W__P,```#I[_#___9%*00/A.7P__^+E6#]__^Y`0`` +XM`(M%".ACXO__A<`/A;[W___IM?S___9%*!")]@^$N?#__XN]8/W__XM?&(7; +XM#X0/\?__@[V4_?__`0^$LA,```^#.A$``(NU8/W__XM&'(7`#X2$\/__`T8D +XM.<,/AWGP__^+10@QR8GRZ/[A___IS_#__XN=8/W__XM#&#M#'`^'5O#___9% +XM*!`/A$SP___'A93]__\!````Z3WP__^+O6#]__^+7QB%VXG9#X3?"@``BX5@ +XM_?__.4@D#X.D!0``BY5@_?__BT("-7PS'A9C]__\#````@\@0@^#[B47@ +XMZ8#Z__^+C6#]__^+41B%T@^$MPD``(N=8/W__SM3)`^&4`0``(NU8/W__XM& +XM'(7`=`8YPHG!=Q"+O6#]__^+3R3'1QP`````BY5@_?__BT(H`T(8*E!____B[U@_?__BT<8BU%S/W__P$```#I&>[__XM%*&:%P`^)#>[__X-] +XM)`$/AA\5```E__]__PT````"@VTD`:@!B44H#X7A%```J0````%T&HNU8/W_ +XM_XM&*,=&*`````")1B"!92C____^QX60_?__`````,>%I/W__P````#IDNS_ +XM_XNU-/[__XFU8/[__XM5*/;&"`^$F@4``('B```"``^%Z0H``(M5"/:"KP0` +XM``$/A?0-``"+C6#]__^+01@[021W!\=!.`(```#VA:C]__\"#X3^!P``BYU@ +XM_?__BT,D@\`!.4,8#X+I!P``QT,X!0```(NU8/[__XFU-/[__^G,]?__QX7( +XM_?__`0```.GZ]___BY5@_?__BT4(Z('E__^%P`^%_//__\>%R/W__P````#I +XMV_C__\=$)`@#````BT,4B3PDB40D!.CSI@``A<`/A'KW___IR?/__XVV```` +XM`(G(@\`,B50D#(E$)`B+00B)1"0$BW4(B30DZ&$!_O^%P`^$^>___XN]8/W_ +XM_XE'"(M%T.GSZ/__BXU@_?__BT74`T$(B50D"(/``8E$)`0!V(D$).AKXOS_ +XMZ>+H__^-!!.%VXE%U`^$,^G__XGPC1P>Q@`@@\`!.=AU]ND?Z?__B[6$_?__ +XMC5X,Z:3W__^+52CWP@````(/A=[T__^+G8C]___V@U0(```!#X3+]/__BYV$ +XM_?__C47<@>(```(`B40D"(U%V(E$)`2)%"2+E6#]__^+10B#PPR)V>@@X?__ +XMA<`/A=OR__^+1=B%P`^$B/3___9%*H`/A#GL__^+M:3]__\IQHGP@^@!B86D +XM_?__Z2'L__^+52CWP@````(/A=/V__^+A8C]___V@%0(```!#X3`]O__C47< +XM@>(```(`B40D"(U%V(G9B40D!(D4)(N58/W__XM%".BBX/__A<`/A5WR__^+ +XM1=B%P`^$AO;___9%*H`/A+OK__^+E:3]__\IPHG0@^@!B86D_?__Z:/K__^+ +XMA6#]__^#:!@!@T`H`>GM]O__C47DB40D!(M5"(D4).C(CP``A<`/A0/R__^+ +XMC:#]__\[3>0/A_#V__^+72B+M6#]__^+O6#]__^A""$)"(F=%/[__XMV&(GQ +XM@^D!B;4<_O__B!4Y\'T1B[T8_O__]D2'-@(/A>,.``"+O6#]__\Y +XM3QQUQ,=%V`````#I9_;___9%*P(/A=3J__^+10CH5MC__^G'ZO__B[V8_?__ +XMA?\/A?$```"+32CVQ0$/A)($``"+70@/MI-4`0``@^(!#X2&"```BX-,`0`` +XMC01`P>`"`T,0BW`XA?8/E<"$P`^$8`0``(32#X1B#```BWT(BX=,`0``C01` +XMP>`"`T<0BT`XBYV$_?__#[X`#[93##';.=`/E,.!X0```0`/A!P$``"+=0@/ +XMMI;``0``@^(!#X0$"```BX:X`0``C01`P>`"`T80BT`XA<`/E<"$P`^$Z@,` +XM`(32#X3E"P``BU4(BX*X`0``C01`P>`"`T(0BT`XB[6$_?__#[X`#[96##G0 +XM#Y3`#[;0@^L!#X1A!@``@^H!#X3[!P``BY6$_?__]D(4`0^$AP,``(.%P/W_ +XM_P&!O<#]__\``0``#X^@!P``]D4J@`^$$NC__XN=I/W__XNU?/W__X/#`6O# +XM'#N&2`$```^'4PD``(NUA/W__XN%?/W__VN5I/W__QR+B$0!``"+!HD$"HM& +XM!(E$"@2+1@B)1`H(BT8,B40*#(M&$(E$"A"+1A2)1`H4BT88B40*&(F=I/W_ +XM_^FAY___QT0D!/____^+10B)!"3HK4;]_^GAY/__A<`/A$0%```YT`^&(/[_ +XM_XU0_XN%8/W__XE0&`^VC:C]__^#X0)T#8N=8/W__XM#",8$$""+M6#]__^+ +XM1AR#1B@!.488C__^DR^?__QT0D!/____^+30B)#"3H +XM.T3]_XG!Z>?D__^)1"0,B="#P`R)1"0(BT((B40D!(M-"(D,).C%_/W_A<`/ +XMA`#O__^+G6#]__^)0PCI"/3__X.]D/W__P(/A(\%``"+G9#]__^%VP^%:P0` +XM`/9%X`1T"O9%*@(/A04*``#V12@(=!6+G6#]__^+2R"%R70(@VL0`8-K(`&+ +XMM6#]__^+1A")1C2+1AB)1C")1A#'1"0(`P```(M&%(E$)`2+?0B)/"3HFJ$` +XM`(7`#X5U[O__BT8@QT8L`````(M>*/9%*P&)A9S]__\/A-KK__^%VP^$TNO_ +XM_XM.&`-."`^^$872#XA`[/__.17\(`D(?S+I,^S__XN58/W__X/!`8-"+`&# +XMZP$/A,4)```/OA&%T@^($NS__SL5_"`)"`^-!NS__Z$((0D(]D20-@)UQ^GU +XMZ___D(NU8/W__XM&%(E#3(M&&(E#4,=$)`0!````B1PDZ,Z)``"%P`^%)NK_ +XM_XV%>/[__\=$)`P#````QT0D"`````")1"0$B1PDZ)2;``"%P`^%_.G__XM& +XM%(V]_/[__XF%_/[__XM&&(/H`8F%`/___XE\)`2)'"3H!6?__X7`#X7-Z?__ +XM#[:%#/___S';QX4@_O__`0```#PI#[;P#Y7#@^L!@^.MB(4G_O__@\-[C97\ +XM_O__B50D!(M-"(D,).B^9/__A<`/A8;I__^+A1#___^%P`^$O.C__X/X`G0% +XM@_@$=%F/W__P(```#I,>;__\>% +XMP/W__P````#I@?S__S'2Z4'\__\QV^G*^___BT4(@:"L!```____]^E<\O__ +XMBX5@_?__BW`DBT@8QT`<`````.F#]?__QT0D"`,```"+0Q2)1"0$BW4(B30D +XMZ'J?``"%P`^%5>S__^FF[___BXU@_O__B8TT_O__Z>KM__^-12B)^8D$)(N5 +XMC/W__XM%".B6V?__A<`/A"'L__^+2!B)A6#]___I]?3__XU%*(D$)(N5C/W_ +XM_XM%".ALV?__A<`/A/?K__^+4!B)A6#]___I'_;__XM]"(NU8/W__XN'G``` +XM`(M>%&:!B,@!``"``(GX@:>L!```____Y^A:WO__A<`/A1+H___VA5S^__\! +XM#X1W!0``BT4,BU`TBT`XB95X_O__B85\_O__N$````"+O6#]__^+5PB`.B\/ +XMA&D(``")1"08QT0D%`````"+C6#]__^+01B#Z`&)1"00C4(!B40D#(M%#(/` +XM1(E$)`B-A7C^__^)1"0$BW4(B30DZ`?-_?^%P`^4P(3`#X3P!```BWT,BU4( +XMBT=$B4),BT=(B4)0@*6H_?___HM"$(NX&`$``(7_#X2N"@``BT4(Z`C-__^% +XMP`^%4.?__XM-"(N!G````&:!H,@!``!__XN!G````(&)K`0``````!B+M6#] +XM__^+@)`!``"+`(E&%(N!G````(N`D`$``#D8#X0^YO__QT0D#`````#'1"0( +XM`````(E$)`2)#"3HO4L``(7`#X7EYO__BWT(BT<0QT0D!`````")/"3_D)@( +XM``#I_N7__\>%D/W__P$```#IAOO__XM-"(N1=`,``.E-Y?__C44HB00DBXU@ +XM_?__BY6,_?__BT4(Z*+7__^%P(F%8/W__P^%FN/__^DBZO__@X4@_O__`>G0 +XM_/__@_X"#X2?Y?__@'P>_EP/A93E___IV>3__X72=!*+O6#]__^+1Q@[1R0/ +XMA8GY__^+A6#]___'0#@!````Z8#K__^H!`^%NP,```^VE:C]__^+A6#]__^# +XMX@*+2!B)E4#^__\YS@^"_0,```^VA:C]__^#X`*)A4#^___I>O/__\=$)`@# +XM````B[U@_?__BT<4B40D!(M%"(D$).B4G```A<`/A6_I___I^O3__XM=#(M3 +XM-(M#.(E31(E#2.GHY/__]\(````"#X7>_O__B[V(_?__]H=4"````0^$R_[_ +XM_XN=A/W__XU%W('B```"`(E$)`B-1=B)1"0$B10DBY5@_?__BT4(@\,,B=GH +XM1-?__X7`#X7_Z/__BT78A<`/A(C^__^+E6#^___V12J`B94T_O__#X11XO__ +XMBXVD_?__*<&)R(/H`8F%I/W__^DYXO__C78`QX74_?__`````.DGXO__BWT( +XMBX>X`0``A<`/E<#I`/C__XMU"(N>3`$``(7;#Y7`Z7[W___'1"0$`0```(M- +XM"(D,).@X0/W_A<`/A2,'``#V12L"QX7`_?__``````^%9^[__^G-X?__BY5@ +XM_?__BUH8QX7<_?__`````,>%Q/W__P````"#^P$/A,H&``"+M6#]__^+/?P@ +XM"0BA""$)"(MV"(F]9/W__XF%V/W__\>%6/[__P````"-3![_B;5T_O__ZP@Y +XM1R1T0(/I`0^^$8G8*X58_O__@^@!A=)X&3N59/W__WT1B[78_?__]D26-@(/ +XMA9,'``"+O6#]__^#A5C^__\!.4<<=;N)RRN==/[__XN58/W__XM"$(/``3M" +XM#'8SB40D#(G0@\`,B40D"(N-=/[__XE,)`2+=0B)-"3H._7]_X7`#X1VY___ +XMB[U@_?__B4<(BX5@_?__`U@(B9UP_O__`YU8_O__B9UL_O__#[8SQ@,JC9UX +XM_O__QT0D&`````#'1"04`````,=$)!``````QT0D#`````#'1"0(`````,=$ +XM)`0`````B1PDZ!M.__^)7"0$BU4(B10DZ!Q#_O^%P`^%]^;__XN%6/[__X/` +XM`8E$)`R+C7#^__^)7"0$B4PD"(M="(D<).A^4?[_A<`/A#0'``"+E6S^__^) +XM\(@"Z2W@__^-M"8`````B40D#(GP!4@!``")1"0(BX9$`0``B40D!(M]"(D\ +XM).A,]/W_A<`/A(?F__^)AD0!``#I=O;__\=$)!`$````QT0D#`$```#'1"0( +XME@@)",=$)`0`````B10DZ)%`_?_IW_'__X.]E/W__P,/A'4#``#H#M'\_X"- +XMJ/W__P'I+OO__XMU#(M&2(M61(F%?/[__[A(````B95X_O__Z83Z__^-4?^+ +XMC6#]__^#02@!B5$8#[:=J/W__X/C`HF=0/[__W0'BT$(Q@00((N]8/W__XM/ +XM&(M'"`^^5`'_A=(/B!S\__\[%?P@"0@/C1#\__^A""$)"/9$D#8"#X4GW___ +XMZ?O[__^+E6#]__^+0@@/MEP!_P^^TX72>!P[%?P@"0A]%*$((0D(N0$```#W +XM1)`T``4``'4(,"+10CHCM7__^GE]?__BTT(BX&X +XM`0``Z2+T__^+50B+@DP!``#II?/__XNU8/W__X-N&`B@!B[V$_?__QX68 +XM_?__`````(U?#.D/Z?__BUT(BX,$`0``A<`/E<#I$>+__XNUG/W__X7V#X1( +XMXO__#[X1A=(/B#_B__\Y%?P@"0A_-NDRXO__B[5@_?__@\$!@T8L`8.MG/W_ +XM_P$/A!;B__\/OA&%T@^(#>+__SL5_"`)"`^-`>+__Z$((0D(]D20-@)UP^GP +XMX?__C5@,QX68_?__`````.F"Z/__BX5@_?__BU`%:/___P````")5"0, +XMB40D",=$)`0`````BWT(B3PDZ#[Q_?^%P(G"#X1WX___B85D____BT8%E/W__P(```"+7AB)A6S___^)A7C___^+ +XMC6#]__^+00C&1`/_((M!*`-!&"M!),=!'`````")02B+022)01CIAMS__XE$ +XM)!C'1"04`````(M'&(/H`8E$)!"-0@&)1"0,BT4,@\!$B40D"(V%>/[__XE$ +XM)`2+10B)!"3H1,G]_X7`#Y3`Z9CW__^+E6#]__^+0AR%P`^$R-O__P-")(/` +XM`3G##X>ZV___QX64_?__`````.E@____]H44_O__"(U"`8F%*/[__P^$WP$` +XM`(N%8/W__XN]8/[__XM8((/K`8F=+/[__XMP*"F]'/[__XN='/[__XFU,/[_ +XM_XE8&(NU8/W__XM&$(/``2M&("M&*,=&(`$````I^(E&$(N%8/W__\=`*``` +XM```/OAJ%VWAP.1W\(`D(?FBA""$)"/9$F#8"=%R+G6#]__^#:Q@!@VL0`3M+ +XM''1)B[5@_?__B=,[3B1U-.LZ.Q7\(`D(?3*A""$)"/9$D#8"=":+O6#]__^# +XMZ0&#;Q@!@V\0`3E/''00@^L!.4\D=`@/OE/_A=)YQHN%A/W__\=%V`$````/ +XMME`,.Q7\(`D(?26A""$)"/9$D#8"=!G'A=#]__\!````QX74_?__`0```.GA +XM[/__QX70_?__`0```.G2[/__BTH(,-O'A5C^__\`````B8UT_O__Z9_Y___' +XM1"0(,`@)",=$)`0#````BUT(B1PDZ%)Z_?_IO?C__XER>.EWW___B70D$(N% +XM>/___\=$)`0`````B3PDB40D#(V%7/___XE$)`CH;<3__X7`#X7XX/__A?\/ +XMA(P#``"+5Q"%T@^$@0,``(N%9/___SM"=`^$60,``(D$).C_T/S_QX64_?__ +XM`````.E\W___#[:5J/W__X/B`HF50/[__^F-ZO__B[U@_?__BX5@_?__BYU@ +XM_O__B[5@_?__BW\@B;TL_O__BT`H*9T<_O__B[T<_O__B84P_O__B7X8BX4L +XM_O__QT8@`````/?8*T8H*=@!1A#I&O[__\=$)`0`````B10DZ$)\``"%P`^$ +XM.O7__^F5W/__C5D!*YUT_O__Z7GX__^)1"0,C48,B40D"(M&"(E$)`2+10B) +XM!"3HRNW]_X7`#X0%X/__B48(Z;/?__^+G33^___'A:3]__\`````QX60_?__ +XM`````(F=8/[__^E`Z___B[U@_?__BT<8.T'__XN58/W__XM")(/``3E"&`^"3.'__\=".`4```#I0.'__XN-\/[__XGP +XMBYWL_O__BY5L_O__A#]__^)G03^__^(`G4BBX7<_?__A<`/A=38__^+ +XM30B+01")#"3_D&0(``#IP-C__X/I`0^$_P$``(M5"(N-!/[__XM2$(F5`/[_ +XM_XL!BP")A4C^___'1"0$+P```(D$).@IR_S_A<`/A+#]__\KA4C^ +XM__^#ZP&#P`&%VXF%[/W__XF=#]__\QVX/J`HF5:/W__^LDC70F`#N=:/W__W0]BXT$_O__B[7L_?__BT29 +XM"(/#`3MP"'<;B[WL_?__BS"+C>S]___\.?^+O4C^___SIG3%QX7L_?__```` +XM`(N%X/W__XN-!/[__\>%3/[__P8```"%P`^.6`0``(NUX/W__XF-5/[__\>% +XM:/[__P````"+E>S]__\#E4C^__\/M@*$P'1XB=/'A?3]__\`````ZR:+50@/ +XMML"-!$`!P`-"$`^V@%T!```!A?3]__\/MD,!@\,!A,!T,#S_==;'1"0$_P`` +XM`(M-"(D,).CY-/W_Z]:)="0$BW4(B30DZ.@R_?_IY?#__XUV`(N=]/W__SF= +XM:/[__W,&B9UH_O__@^X!#X2"`P``B[U4_O__BT<$@\<$BP")O53^__^)A4C^ +XM___I3?___XMU"&N&5`(``&3IM]G__XN%`/___^ELV?__@:)4"```__[__\>% +XME/W__P````#I(=S__XN%9/___^F#_/__BX7@_?__@^@!B85P_?__Z;W^__^+ +XMA>S^__^+`(L`B85$_O__B00DZ`[._/\YA5C^__^)PP^$P````(N%6/[__XNU +XM1/[__X7`#Y7`#X6&````A=MT1XN-8/W__XM!*(7`=1/I`0$``(MX*(/&`87_ +XM#X3S````#[8&B[UP_O__B`>+A6#]__^#QP&)O7#^__^#:"@!@T`8`8/K`77+ +XMB[5P_O__B;5L_O__Z6P!```/M@:#ZP&#Q@&+O7#^__^(!X/'`8.M6/[__P&) +XMO7#^__\/E<`/A'K___^%VW72A,`/A&[___^+A6#]__^+E5C^__\I4!@!4"CI +XM5____XNU1/[__SG`B<&+O7#^___\\Z8/A2?___^+A=S]__^%P`^%J]7__XV% +XM_/[__XE$)`2+A43^__^)!"3HH3]__^-7#,!B9UL_O__@[W@_?__`0^%IM3__XV%_/[__XE$)`2+ +XMA>S^__^+`(L`B00DZ)C'_/^%P`^%@M3__P^WA03___\E`/```#T`0```#X5K +XMU/__B[U@_?__BT%W/W__P$```#I +XM//+__XE$)`R)^(/`#(E$)`B)7"0$BT4(B00DZ!'H_?^%P`^$3-K__XG"B4<( +XMZ6O___^+M6#]__^#Z`&)1BCKGXN%X/W__XN5!/[__XT,@HN%:/[__[JKJJJJ +XM]^+!Z@*-%%*-5!(&B95,_O__BUT(BY.L!```QX7H_?__`````/?"````$'06 +XM@>+____OB9.L!```QX7H_?__`0```(MU"(M&.#F%3/[__P^'Q0$``(/H`3'2 +XMB[W@_?__][5,_O__.?B)A7C]__\/@@@#``#'A?#]__\!````BY7P_?__,<#' +XMA?S]__\`````P>("B95L_?__BY5X_?__A=(/A"T!``"+G?#]__^+O03^___' +XMA?C]__\``````<.--(>)G5#^___ID@```(D<).AVR?S_BX4`_O__]H!4"``` +XM!`^%U@$``(N54/[__SF5X/W__P^&V@```,=$)`Q/C0@(BX5,_O__*X4(_O__ +XMQT0D!'Z?"`B)1"0(BTT(B0PDZ"*C_O^+G0#^___V@U0(```$#X6&`0``@X7X +XM_?__`8N]\/W__XN%>/W__P&]4/[__P.U;/W__SF%^/W__W1UC570B50D"(L& +XMBP`#A>S]__^)1"0$BTT(B0PDZ#AE_?_'1"0$GZT("(E$)`B+?0B)PXD\).BO +XMHO[_BTW0A#]__^%P'XY +XMBYW@_?__ZPN-M@````"#ZP%T)HET)`C'1"0$?>D("(M5"(D4).C4H?[_BXT` +XM_O__]H%4"```!'35BWW0A?]T(HM="(7;=!.+70B+0Q"%P'0).7!T#X1C`0`` +XMB30DZ*#'_/^+M0#^___VAE0(```$#X0&`0``BYT`_O__@Z-4"```^XN%Z/W_ +XM_X7`=`V+=0B!CJP$```````0BX7L_O__B[W@_?__BQ"--+B+6@B+$HF5=/W_ +XM_XN5L:C70F`(N]=/W__P^V!!,Z!#MU!X/#`3G+=>J+A7#]__^#[@2# +XMZ`&)A7#]___KG8N-=/W__\>%Q/W__P$```")C43^___I?_G__XN%X/W__S'2 +XM][5X_?__@_H!@]C_A<")A?#]__\/A>#\___'1"0$)KH("(M%"(D$).@&H/[_ +XMBY4`_O__]H)4"```!`^%^O[__XM-"(D,).B8G_[_Z??^__^)1"0,BL```"+@YP```"+@)`!``"+`(&+K`0``````!#'0U``````B4-,BU44 +XM@)QU:)SE.#["R%P(E5W`^$Y@```(M8$(7;#X3;````]H-5"``` +XM`0^%S@```(M5"#E3>`^"3@$``(M+=(E-X(M#>(E%\(&+5`@````!``"+10B) +XM="0$B40D"(M5X(D4).@\P_S_BTW@BT40BU7@`U4,C5P!`3G:7UW#BT4(QT7P`````,=% +XMX`````"%P`^$.____XM%",=$)`0`````B3PDB40D#(U%\(E$)`CH*^']_X7` +XMB47@#X42____NP$```#KK8M5"+L!````B50D#(M-X(E,)`B+1=R)/"2)1"0$ +XMZ+<\_?^%P`^%8?___^E:____@:!4"```__[__X/$+(G86UY?7<.-0WB)5"0, +XMB40D"(M#=(D\)(E$)`3HO.#]_X7`=)B)0W3IC/[__U6)Y5=64X/L+(MU#(M> +XM-)"-1>R)1"00C47PB40D#,=$)`@!````B5PD!(M%"(D$).B+-_W_A575E.#["R+10SV0#$(BW@TBW`X#X7`````QT7@`0`` +XM`(U%\(U-[(E$)!")3"0,QT0D"`````")?"0$BT4(B00DZ-@V_?^%P`^%H``` +XM`(M5\(72=1F+10S'0$@`````@VW@`71%,?;KN)"-="8`BT7@`?`YPG='BTT, +XMC5K_B=`I\"E%X(E92(M-[(D4)(GZB5PD"(ET)`2+10CH#_W__X7`=56+5>"% +XMTG4FBT4,B7A$,<"#Q"Q;7E]=PXUT)@"+30R-6/^)04C'1>``````Z[>#QP$Q +XM]NE'____BTT,BTD$A`/A3;____KO9"#_P%T$H/O`>NR@\0LN`$```!; +XM7E]=P\=$)`@!````QT0D!`````"+30B)#"3H/@$``+@!````ZXN0D)"0D)"0 +XM58GE4X/L!(M-"(M=#(N1G````(M!+(F"@`$``(M1'`^V0EB$P'@@@\B`B$)8 +XMQT(T`@```(U#1(E%#(E-"(/$!%M=Z:E%_?_V0S$@=0\QP(-Z-`(/E<"#P`&) +XM0C2+0C2#^`%T"H/X`G3+Z(:[_/^-0T2)10R)30B#Q`1;7>GO0/W_ZPV0D)"0 +XMD)"0D)"0D)"058GEBU4(BT4,QT!(`````(M"'(!(6("+0AS'0#0"````B54( +XM7>DV0_W_D)"0D)"058GE5E.+30R+50B#Z0&#^?]T00^^`H7`>$.+-?P@"0@Y +XM\'TYBQT((0D(]D2#-@)U&^LJ#[Y"`87`>"(Y\(UV`'T;@\(!]D2#-@)T$8/I +XM`8/Y_W7?6[@!````7EW#6S'`7EW#C;8`````C;PG`````%6)Y8/L&(M%$(M5 +XM"(M-#(/X!W8"RFN:/W_QT40 +XM8`H)",=%#`(```")50C)Z9=H_?_'11!["@D(QT4,`@```(E5",GI@&C]_X/X +XM!0^5P`^VP(/``HE,)`S'1"0(E@H)"(E$)`2)%"3H7&C]_\G#B4PD#,=$)`BP +XM"@D(QT0D!`,```")%"3H/FC]_\G#C;8`````C;\`````58GE@^P8BT4(QT0D +XM"(P)"0C'1"0$`@```(D$).@/:/W_R<.-M@````"-O"<`````58GE@^P8BT4, +XMAQT0D"-@)"0C'1"0$`@```(M%"(D$).C39_W_R<.0QT0D"*P) +XM"0C'1"0$`@```(M%"(D$).BU9_W_R<.-=@!5B>6#[!B+10C'1"0(O@H)",=$ +XM)`0"````B00DZ(]G_?_)PXVV`````(V\)P````!5B>6#[#B)7?B+70R)=?R+ +XM=0B%VW1:C47TB40D$,=$)`P`````QT0D"`$```"+`XDT)(E$)`3H]3+]_X7` +XM=2.+1?2#Z`$Y0P1T)L=$)`@$"@D(QT0D!`(```")-"3H'F?]_XM=^(MU_(GL +XM7<.-="8`B30DQT0D"`,```#'1"0$`````.CH_?__BUWXBW7\B>Q=PXVT)@`` +XM``"-O"<`````58GE@^PHB5WXBUT,B77\BW4(A=MT&HU%](E$)`2)-"3HJS3] +XM_X7`=1^+`SM%]'(BQT0D"`(```#'1"0$`````(DT).B(_?__BUWXBW7\B>Q= +XMPXDT),=$)`@H"@D(QT0D!`(```#H=F;]_XM=^(MU_(GL7<.0D)"0D)"0D)"0 +XMD)!5B>575HG&4XG+@^P\B57,QT70`0```/9",0AT!HM"!(E%T(M5S(U-W(M" +XM-(E%W(M".(E%X(E,)`2)-"3HCT;__X7`#X47`0``BT7PAP[%?P@ +XM"0@/C0T!``"A""$)"/9$D#8"#X3]````C57#??`$=9"+3"+3"+??"%_P^%Y?[__P^V5>P[%?P@ +XM"0@/C>S^__^A""$)"/9$D#8"#X3<_O__Z<#^__^A""$)"&8Q__=$D#0`!0`` +XM=0Z`^5\/E<`/MOB0C70F`(U-W(E,)`2)-"3H\4+__X7`#X5Y____BUWP@_L$ +XM#X0,____A=MU/P^V3>P/MM$[%?P@"0A]#*$((0D(]D20-@)U)(7_#X6F```` +XM.Q7\(`D(?0^A""$)"/=$D#0`!0``=9^`^5]TFHM%T(7`#X0"____A=MU&`^V +XM5>P[%?P@"0A]+:$((0D(]D20-@)T(8U5W(E4)`2)-"3HA$7__X7`#X7L_O__ +XM@WWP!`^$@?[__X-MT`&#?=#_#X1S_O__BU7POP$```"%T@^%-/___P^V3>P/ +XMMM$[%?P@"0@/C`'___^`^5\/E<`/MOCI$____XUV`#L5_"`)"'T3H0@A"0CW +XM1)`T``4```^%6____X#Y7P^%[/[__^E-____BT7@.T$XD`^%&_[__XG(@\`T +XMB40D!(DT).A9^___N`$```#I5/[__S'`Z4W^__^%R0^%W_W__^DB_O__C70F +XM`(V\)P````!5N0$```")Y8M%"(M5#%WIO/S__XVV`````(V_`````%4QR8GE +XMBT4(BU4,7>F?_/__ZPV0D)"0D)"0D)"0D)"058GE5XG75HG&4XG+@^P\QT70 +XM`0```/9",0AT!HM"!(E%T(M'-(E%W(M7.(U%W(E5X(E$)`2)-"3H(T/__X7` +XM#X4+`0``BU7PA=)U(`^V5>P[%?P@"0@/C0$!``"A""$)"/9$D#8"#X3Q```` +XMC47P[%?P@"0A]T:$( +XM(0D(]D20-@)TQ8M%T(7`#X1+`@``C47"+1?"%P`^%\?[_ +XM_P^V5>P[%?P@"0@/C?C^__^A""$)"/9$D#8"#X3H_O__Z/___XM=\(/[`@^$$/___X7;=4(/MDWL#[;1.Q7\(`D(?0RA""$)"/9$D#8" +XM=2>+1+1="% +XMP`^$`O___X7;=1@/ME7L.Q7\(`D(?2VA""$)"/9$D#8"="&-1=R)1"0$B30D +XMZ(!"__^%P`^%Z/[__X-]\`(/A(+^__^#;=`!@WW0_P^$=/[__XM%\,=%S`$` +XM``"%P`^%+____P^V3>P/MM$[%?P@"0@/C/O^__\QP(#Y7P^5P(E%S.D,____ +XM.Q7\(`D(?1.A""$)"/=$D#0`!0``#X5:____@/E?#X7H_O__Z4S___^+1=P[ +XM1S1T&XM5X.DA_O__BT<\B5=(B4=$@\0\,FL_/__C;8`````C;\`````53')B>6+10B+ +XM50Q=Z8_\___K#9"0D)"0D)"0D)"0D)!5B>575HG&4XG+@^P\B57,QT70`0`` +XM`/9",0AT!HM"!(E%T(M5S(U-W(M"-(E%W(M".(E%X(E,)`2)-"3HGS___X7` +XM#X6;`0``BU7P@_H!#X0O`0``A=)U$`^V3>P[#?P@"0@/C`L!``"%VP^%70(` +XM`(-MT`&#?=#_#X1\````D(U=W(E<)`2)-"3H83[__X7`#X5-`0``BT7P@_@" +XM=%R%P'48#[95[#L5_"`)"'W1H0@A"0CV1)`V`G3%BT70AP/MM$[%?P@"0A]#*$((0D(]D20-@)U)(7_#X7:````.Q7\(`D(?0^A +XM""$)"/=$D#0`!0``=:.`^5]TGHM]T(7_=1B+1`[0S@/A9K]__^)V(/`-(E$)`2)-"3H +XM\O3__[@!````Z4'^__^!^D`""0@/A!G^__^!^I`#"0@/A4W]___I"/[__XUT +XM)@"-O"<`````5;D!````B>6+10B+50Q=Z1S\__^-M@````"-OP````!5,"+0S"-4P&->S3'1"00`````(E\ +XM)`@E``(``(/X`1G`]]`APHM%X(E4)`2)-"2)1"0,Z#?E_/^%P'4CBT7@QT0D +XM#`````")?"0$B30DB40D".@8Z?S_Z6G___^-=@"X`0```.E<____C;8````` +XMB4-`BT,X@_@!C5#_&<#WT"'"B5-(Z7/___^0D)"0D)!5B>564X/L,(M=#(MU +XM"(M3,(U+`8DT)(G0)0`"``"#^`$9P/?0(<'!Z@.-0SR#X@&)1"0,C4,TB50D +XM$(E$)`B)3"0$Z)CD_/^%P'0,@\0PN`$```!;7EW#BT,\`T9T@\`!*T,TB49T +XMC47TB40D$,=$)`P`````QT0D"`$```"+0T2)-"2)1"0$Z&,D_?^%P'6[BT,P +XMJ`AU*R4/_O__@\@@B4,PBT7T.4-( +XM7<.#Q#`QP%M>7<.0D)"058GEBT4,4XM="(E#/(E#1(M#-(/H`3E#/'8&B4,\ +XMB4-$BXN<````BT,\BY&,`0``C01`@^H8C03"B8&0`0``,<"#BZP$``!`6UW# +XMD(UT)@!5B>6#[#B)7?2+70R)=?B+=0B)??SV0S$(#X51`0``BT,TB47PBT7P +XM]D,Q$(E#1(M#.(E#2'1>BU,(A=)T5P^VAFP$``"#X`&)QP^%5@$``(N.9`0` +XM`(G(.=!S%XGXA,!T#(T$2<'@`@-&$(M(.(G*B4L(B50D!(DT).@Q____AQ=PP^V4P*`^BT/A+0!``!V8X#Z+@^$1`$``(#Z +XM7G5>]D,Q"`^$J@$``(M%\,=$)`@`````B30DB40D!.B-:```AQ=PXVV +XM`````(M#"/\DA1@+"0B)7"0$B30DZ%I"``"%P'2AN`,```#KS(-[$!)U++@0 +XM````C70F`.N)BT80B30D_Y!D"```N`0```#KJ(M5\+@"````A=)TCNN:N`4` +XM``#KDXVV`````%6)Y5=6B<93@^P\B%7D#[;2C5K0C7W8B4W0ZP:-="8`B<,Q +XMTHGYB?#'!"0*````Z`S___^#^`5U:`^V5>2#^G]W;/8$E=T4"0@$=&*-!)N- +XM1$+0.=ASR3'2B?F)\,<$)`H```#HU_[__X/X!74S#[9%Y(/X?W<*]@2%W10) +XM"`1UUL=$)`S_____QT0D"'`+"0C'1"0$`P```(DT).AO4_W_@\0\N`$```!; +XM7E]=PXM%T(D8@\0\,`)B46P#X0\`0``]D7D`G0)BT40QP`!````BTT(#[9]W(7) +XM#X2F`0``B?J`^B(/A.8```")^0^VT8/Z?W<.]@25W10)"`0/A8\!``"+50S' +XM`@````")^8#Y(@^$=@(``(GX/'X/APD!``")^(GZB`,/ML#!X`0%`/P("(#Z +XM1(E%M`^$'0,``(M%M(L`A<`/A,0$``")^8#Y?@^$*P,``(M%M(E#*(L`A<`/ +XMA-8$``"+1;2+0`2)1;B+0S#VQ`@/A$D"``#W1;@```0`#X4\`@``BT4(A<`/ +XMA`$&``"+?0@/MA>`^GX/A%P&```/ML+!X`2+@`C\"`C'1"0(!@```(E$)`2+ +XM1:R)!"3HM^C__S'V@\1\B?!;7E]=PXM5"(72#X0-`0``QT0D"``````Q]L=$ +XM)`0`````BTVLB0PDZ(/H___IG?[__XM-L(7)=6''1"0(O0L)"+X!````QT0D +XM!`(```"+3:R)#"3H9U']_^EQ_O__//\/A$D$``"+5:P/ML"-!$"-A`!0`0`` +XM`T(0@\`(QT0D"`0````Q]HE$)`2+?:R)/"3H&^C__^DU_O__@WVP`@^%5?__ +XM_XM]K#'VBT<0B3PD_Y!D"```Z4'____'1;`"````Z4[^__^`^3"-M"8````` +XM#X1A_O__BT6LC4L$Z,_\__^%P`^%$/___X%+,``(```QTHM]#(U-T,<'`0`` +XM`,<$)`(```"+1:SHX_O__X/X!0^$B0```(G&Z;+]___'!"0`````BT6L,=*- +XM3=#HO_O__X/X!77@@WW@"0^$N?[___9%Y`)T"8M]$,<'`0````^V1=PQTH%+ +XM,``"``"-3="(0P''!"0"````BT6LZ'_[__^#^`5UH(-]X`D/A'G^___V1>0" +XM=`F+11#'``$````/MGW`)#X3@_/__ +XM]D7D`HUV`'0)BTT0QP$!````#[9]W`^V`XGZ.-`/A8#\___IW?[__\=$)`@8 +XM#`D(QT0D!`,```"+?:PQ]HD\).AB3OW_Z9C\___W1;@```(`#X7%!0``BTVT +XM]D$&$`^$4OO__XU%\(E$)!"-1>R)1"0,QT0D"`$```"+?:R+1TR)/"2)1"0$ +XMZ,L9_?^%P`^%3/S__XM?4(M%\#G8B46@=F>+3>P/O@09A<`/B,(#``"+%?P@ +XM"0@YPHE5G`^.N0,``(L]""$)"(E]I/9$AS5`#X2)!0``C10+ZR8/OD(!A<`/ +XMB+($```[19P/C:D$``"+3:2#P@'V1($U0`^$F`0``(/#`3M=H'72QT0D"*0+ +XM"0@Q]L=$)`0"````BWVLB3PDZ()-_?_IC/K__P^V`SQ$#X0/`P``B?8/AWT! +XM```\0P^$\P(``(M%M(7`#X46^___,?;IB_O__XGZ@/HN#X3M`0``,=N#?>`) +XM#Y3#@\,$@/K_#X3Q`P``BTVL#[;"C01`C80`4`$```-!$(/`"(E<)`CI._O_ +XM_\=$)`3_````BTVLB0PDZ.X(_?_IM?O__XM-K(N!!`0``(7`#Y7`Z03^___W +XM1;@``(``=0GVQ`(/A=P```#W1;@````!#X0*_?__QP0D`````(M%K#'2C4W0 +XMZ./W__^#^`4/A0#\__^#?>`)#X39^O__]D7D`G0)BU40QP(!````#[9%W(%+ +XM,``"``"(0P'IP?S__\<$)`````"+1:PQTHU-T.B:]___@_@%#X6W^___@WW@ +XM"0^$D/K___9%Y`*-=@!T"8M5$,<"`0````^V1=PQTH%+,``"``"-3="(0P'' +XM!"0"````BT6LZ%/W__^#^`4/A7#[__^#?>`)#X1)^O__]D7D`G0)BTT0QP$! +XM````#[9]W.F#^?__BTVTBT$(Z0_Z__\\4P^$C@$``#Q9C78`#X5X_O__QD7P +XM7\8#>8U%\,=$)!`,````QT0D#`$```")1"0(QT0D!`````"+5:R)%"3HR0S] +XM_X7`#X7:^?__#[8#P>`$!0#\"`B)1;3I+/[__XM%K/:`#`0```$/A#,!``") +XMP8N`!`0``(T$0,'@`@-!$(M`.(7`#X1X^?__H6@+"0CI>OG__XM-J(7)#X1) +XM^?__BU6LBX*<````BX"``0``.T(L#X53`@``@4LP`"```,=#*%`#"0CI,?C_ +XM_\<$)`````"+1:PQTHU-T.@^]O__@_@%#X5;^O__@WW@"0^$-/G___9%Y`)T +XM"8M5$,<"`0````^V1=P/MM"#^G^(0P(/AS_[___V!)7=%`D(!`^$,?O__XM% +XMK(U+".BP]O__A<`/A?'X__^!2S``$```,=*-3=#'!"0`````BT6LZ,WU__^# +XM^`4/A>KY__^#?>`)#X3#^/__]D7D`G0)BTT0QP$!````#[9%W(A#`NG5^O__ +XMQD7P),8#8^F0_O__QD7P),8#9.F$_O__QD7P7\8#8^EX_O__BWVLBX<$!``` +XMA<`/A%#X___IT_[__Z'\(`D(B46<#[84"P^^PH7`#XC"````BST((0D(B7VD +XM.P7\(`D(#XVU````BWVD]T2'-``%```/A*0```#'1;P!````C3P9B=F#P0$[ +XM3:!S/@^V5P&(59L/OM*%TG@9.U6R)7"0$BXR)5:"+/?P@"0B)?9SIM?[__XM-J(M1,/;& +XM(`^$S````(M#,/;$"'05BT6H@,X(B5`PBT,$BU6HB4($BT,P]L0"=`H/MD,! +XMBTVHB$$!QT0D"$P```"+?:B)'"2)?"0$Z#2?_/_IFO7__\<$)`````"+1:PQ +XMTHU-T.BG\___@_@%#X7$]___@WW@"0^$G?;___9%Y`)T"8M5$,<"`0````^V +XM1=R(0P+I^?G__P^V%`L/OL+I*/[__XE$)`R-AS0!``")1"0(BXS\````BT4(BS"-18R+5A#'1"0(3````,=$)`0` +XM````B00DB948____Z%^;_/^#3;P@BUX0B[Z<````QT0D!`(```")-"3_DZ`( +XM``"%P'00N`$```"!Q/P```!;7E]=P\=$)`@!````QT0D!`````")-"3_DUP( +XM``"+AJP$``"#X/J#R`+VAB`"```!B8:L!```#X0I!P``BX88`@``C01`P>`" +XM`T80BT`XB8>T`0``]H9@`0```8E&-`^$]@8``(N&6`$``(T$0,'@`@-&$(M` +XM./:&;`0```&)1C@/A+`&``"+AF0$``"+5C2-!$#!X`(#1A"#^@&+0#B)1D2) +XM1CP/A*0&``"#Z@$YT`^'E0D``(M&-(/H`8E&0(N>G````,=&2`````#'1"0$ +XM&````(N#M`$``(/``8D$).B=F_S_A<")@XP!```/A"<*``"+CIP```"+1CR+ +XMD8P!``"-!$"#ZAB-!,*)@9`!``"+AIP```"+D(P!``"+1DR)`HN&G````(N` +XMC`$``,=`!`````"+AIP```"+@(P!``#'0`@!````@8ZL!```H````&:#C\@! +XM```%BU80QT0D"`$```"+1B"+0`B)-"2)1"0$_Y*<"```BYZ<````BT80BX@8 +XM`0``AB% +XM_W5;BX:<````C56,QT0D"$P```")5"0$!9@```")!"3HJ)O\_XN&G````(&( +XMR``````@``#V1;T$=!"+AIP```"!B,@`````"```BX:<````@:#(`````/[_ +XM_XM%O"7P`0``@_@@#X0"!```#X8Q!0``/8`````/A.D#```]``$``(VT)@`` +XM``!T$(/X0`^%(`4``,=%U`````"-1=2)1"0(BT70B30DB40D!.A(N/W_A<`/ +XMA+4#``#'1"0$`@```(DT).@``_W_A<`/A7@#``"+1A#V@%0(```$#X0H`P`` +XM@Z!4"```^\=$)`0"````B30DZ-$"_?^%P`^$^@$``,=$)`C0#`D(QT0D!`,` +XM``")-"3H$43]_XN&K`0``/;$$`^%^@$``/;$"`^%60(``(N%&/___X"X5`@` +XM``!X#?:&K`0```$/A,W]__^+50B),HM^$(M?"(U'"(U7$(F%+/___\>%*/__ +XM_P`````YPXF5%/___W5-Z9$&``"+0P2)0@2+0P0YA2S___]T?(D0BY44____ +XMB1.+1Q2)0P0[5Q`/A#@&``"+1Q2)&(E?%(.%*/___P&+7P@YG2S___\/A$D& +XM``"+@YP```"+@(P!``"%P'08B00DZ&&:_/^+@YP```#'@(P!````````BQ,Y +XME2S___]UAHM#!(E'#(M#!#F%+/___XL3=82)5PCK@8DT).@3)?W_A<"0#X6: +XM_O__BY48____QT7H`````(M"?(M`%(7`#X6+_?__C46,QT0D"$P```"-?>C' +XM1"0$`````(D$).AUEOS_BY:<````C47LB40D!(U-C(GPB7PD",<$)`````"! +XMPI@```#H6>___X/X!`^&0@(``(M-M/9!!P(/A%P#``#VAF0#```!#X1+!P`` +XMBX9<`P``C01`P>`"`T80BT`XA<`/E<"$P`^$,`,```^V18P\_P^$=0@```^V +XMP(T$0(V$`%`!```#1A"#P`C'1"0("````(E$)`2)-"3H5`W__^F__?__QT0D +XM"-D+"0C'1"0$`P```(DT).@70OW_BX:L!```]L00#X0&_O__@.3O#0````*) +XMAJP$``"+=A2+GIP```"+5A#'1"0(`0```(M&((M`"(DT)(E$)`3_DIP(``!F +XM@XO(`0```<=$)`0!````B30DZ)M$``"%P`^%&OK__XN&K`0``/;$"`^$J_W_ +XM_XUT)@"`Y/>)AJP$``"+1A#'1"0(`0```(M6((M2"(DT)(E4)`3_D)P(``#I +XM>_W__XUT)@#'AI0````"````QT0D!`````")-"3H-D0``(7`#X6U^?__]T6\ +XM8`$```^$F?O__Y!F@Z/(`0``OXU&5(E$)`2)-"3HR44``.E\^___C70F`,=$ +XM)`P!````QT0D"`````#'1"0$`````(DT).@P!?W_A<`/A>?\__^+1A#V@%0( +XM```$#X37_/__Z9O\__^-=@#'1"0(H`P)",=$)`0"````B30DZ,A`_?_I:_S_ +XM_V:#B\@!``!`BU70B59,BTW4B4Y0BT6\]L1`=1VI```!``^%,0$``&:%P`^) +XM._S__SM5V`^$-`4``(U5V,=$)`P!````B50D",=$)`0G````B30DZ.LP_?^% +XMP`^$"_S__^GN^____R2%3`L)"(M6-(N&9`0``(/Z`8E&1(E&/`^%7/G__\=& +XM0`$```#I9/G__XN&6`$``.D1^?__BX88`@``Z=[X__\E``0``(E$)`C'1"0$ +XM`````(DT).C4ZOS_A<`/A6/X__^-7?")7"0$B30DZ.US``"%P`^%3/C__XM% +XM\(7`#X2(`P``BT7PBU4(B0*)-"3HNH#]_X7`#X4I^/__BW7PA?8/A&\$``"+ +XMGIP```"+1A#'1"0(`0```(M6((M2"(DT)(E4)`3_D)P(``!F@XO(`0```>EV +XM^?__A<`/A,/^__^#^!`/A-P"``"0C70F`.@?D?S_.U78#X78_O__B?;IO_[_ +XM_XU5C(E4)`2)-"3HO##__X7`#X74^O__Z?GY__^+1A#I[_K__XM5O/;&()!T +XM%XM%[(7`=!"+AIP```#'@.@````!````B=`+002I`,`!`(E%O'0,BT9,B478 +XMBT90B47`S`2)1;P/MD6,.H5`____#X3>`P``BT6TQX4<____```` +XM`#U@"PD(B85L____#X2J`P``BT6\B<*!XO`!``"H((F5(/___W0,@\H0@^+? +XMB94@____BY5H____)0_^__^)1;R+0@0E#_[__PF%0```")!"3H))+\_XN5 +XM)/___XN%,/___XF0Z````(M%O"4("```/0@(``!T48-&+`'I^?7__SM-W`^% +XMP_K__^GP]O__,<"-M@````#II_/__XN&7`,``(7`#Y7`Z;SX__^)=PCI3O[_ +XM_XE7$.DD_O__BT8$B4<4BQ;I!O[__XM%D`-%R(/H`8E%R.NAC95`____B10D +XMQT0D"$P```#'1"0$`````.B&COS_C47@,=*)1"0$C46,B00DC8U`____B?") +XM?"0(Z'+G__^#^`4/A1_]___I)OS__XM%R(DT)(E$)`3H]0?]_X7`#X5S_O__ +XM@WW(`745#[9%C#QCD`^$6?[__SPA#X11_O__QT0D"`$```#'1"0$`````(DT +XM).A:T?__Z0#5DR)1"00QT0D#`````"#Z@&)52#^`&-4/\9P/?0(<*)5/___SM-@`^&R/W__^O$ +XMD)"0D)"0D)"0D)"0D)"058GE5U93@^P\BW4(]H:O!```$(M^$(N&G````'0* +XM@\0\,*)!"3H%8W\_XDT)(E$)`B-1>*)1"0$_Y=8"```BY:<````@\,8 +XM.9J0`0``0"```@\0\,%2/___P````#WP@`` +XM`!!U&8N`G````(.X7`$```$/E\`/ML")A4C___^#XA!T.8M="(N#G````(M3 +XM0(N(C`$``(M#-#G"#X.B)1"0$BUT(B1PD_Y%P"```QT0D"`````"+@YP```"+50PKD(P!``")'"2) +XMT,'X`VG`JZJJJHE$)`2+C23_____D9`(``"-1?")1"00C47DB40D#,=$)`@` +XM````BUT,BP.)1"0$BT4(B00DZ(4"_?^+50B+30B+4CB)QHF5+/____:!%`(` +XM``$/A68$``"+70B+@PP"``"%P`^5P(3`#X1O!```BT4,BUT(BT`$QX4\____ +XM`````(F%./____:#.`(```$/A'4$``"+@S`"``"-!$#!X`(#0Q"+0#B)A4S_ +XM__^+50C'A5#___\`````]H*O!```$'51]H*8`@```0^$504``(N"D`(``(T$ +XM0,'@`@-"$(M`.(7`#Y7`A,!T'8.M+/___PB%]@^%+`0``(N=./___X7;#X2* +XM"```BY5,____B950____A?8/A20$``"+3?"%R0^$&00``(N%./___X7`#X4# +XM!0``BU4,QT(,`````,9"%`#'A3#___\`````QX4T____`````(M%$(7`=!&+ +XM50R+30B+`CM!3`^$>PD``(N=2/___\>%*/___P`````)^P^%"P,``(N5-/__ +XM_SM5\`^#?@L```N]2/___XV=9/___XU%XXF]5/___XG?QX5<____`````,>% +XM1/___P````")G1S___^)A2#___^-=@"+1>0/MA"#P`&)1>0/MLJ`^@F(E6/_ +XM__^)C4#___\/A,P$``"`O6/_____#X2M!0``BY5`____BTT(C012`<`#01`/ +XMMH!=`0``B<8QTBNU,/___P&U7/___XN-7/___SF-+/___W=4@_H!#X1.!0`` +XMBT4,B?.(6!:+A5S___\KA2S___^+70PIQHGQB$L5BX5<____.84L____<#``"+70B+30R+ +XM@YP```"+71`KB(P!``")R,'X`VG`JZJJJHD#BT4(]H"O!```"`^$5@4``(N% +XM7/___XM-%"GPB0&+10CV@)@"```!#X0F!0``B<&+@)`"``"-!$#!X`(#01"+ +XM0#B%P`^5P(3`=!J+10CV@*\$```0=0Z+C3C___^%R0^$5@,``(N%5/___X7` +XM#X4^`0``A=(/A+@#``"%]G15,=OK#8/#`<8'((/'`3GS=$0[O2#___]RZ\8' +XM`(V%9/___X/#`2N]'/___XE$)`2)?"0(BU4(C;UD____B10DBXTD_____Y%8 +XM"```Q@<@@\# +XMQP&#^?]U[8N%7/___X/``3F%+/___W82BU4(B10DBXTD_____Y%L"```.;T< +XM____#X()!@``BT7LB40D"(M%Z(E$)`2+30B)#"2+G23_____DY`(``"!Q.P` +XM```QP%M>7UW#BX$,`@``C01`P>`"`T$0BT`XA<`/E<"$P`^%D?O__XM5#(M= +XM"(M*"(/I`8F-//___P^OC2S___^)C3C____V@S@"```!#X6+^___BT4(BX`P +XM`@``B85,____Z8_[__^-4/_I7/K__XN=3/___XM%#(F=4/___X,X`0^$O/O_ +XM_XGVBU40A=)T$8M-#(M="(L!.T-,#X1P`@``"[U(____#X4N____BUT,QT,0 +XM`````,=##`````#&0Q4`QD,4`(N%./___X7`=4J%]@^$S`(``(,[`;I^```` +XM#X2^`@``BTT(C112`=*+01`/MHP070$``(V$$%@!``")1"0$B4PD"(M="(D< +XM)(N5)/____^26`@``(M-"(D,)(N=)/____^3;`@``(M%[(E$)`B+1>B)1"0$ +XMBT4(B00D_Y.0"```@<3L````,^?__@<3L```` +XM,2)G3#____V@!0"```!#X5=!```BTT(BX$,`@``A`"`T,0BT@XBX5<____,=*)SO?Q*=:Z +XM`0```"NU,/___P&U7/___^D5^___C1PW.9T@____#X;4````@+UC_____P^$ +XM0P$``(N-0/___XM="(T$28V$`%`!```#0Q"#P`B-3O^)C5C___^#P0$/A%K\ +XM__^+G3#___^)^8T4&(T<-XVT)@`````/M@*#P@&(`8/!`3G9=?&+A5C___^- +XM?#@!Z2?\__^+G2S___\IV2G.BTT,B?"(016(01:)G5S____IR/K__XN=0/__ +XM_XE<)`2+10B)!"3H/>W\_^E1^O__BX.<````BU40*XB,`0``B0/MA"#P`&) +XM1>0/MLJ`^@F)C4#___]UH8N53/___X72=:"+10CV@-`#```!#X0J`@``B<*+ +XM@,@#``"-!$#!X`(#0A"+2#B)V#'2]_&)R"G0ZXB+50R-G63___^+`HD<),=$ +XM)`@K#0D(QT0D!(````")1"0,Z/N!_/^)7"0$B40D"(M-"(D,)(N=)/____^3 +XM6`@``(N%3/___XF%4/___^DP]___@,(!#X0V`0``BY5`____BTT(C012`<`# +XM01`/MH!=`0```<,[G2S___]R'XM-""N=+/___XM).(.M//___P&)C2S___\/ +XMA#P!``"#A33___\!BY4T____.57P#X8F`0``BT7D#[80@\`!B47D#[;*@/H) +XMB8U`____=8:+A4S___^%P'6%BT4(]H#0`P```0^$%@$``(G"BX#(`P``C01` +XMP>`"`T(0BT@XB=@QTO?QB<@IT.EJ____Q@<`C9UD____*[T<____B5PD!(E\ +XM)`B+10B)!"2+E23_____DE@(``#IR?G__XG"BX`,`@``C01`P>`"`T(0BT`X +XMA<`/A:;[___IC_O__XM14#F5-/___P^'=O;__XN%-/___P.%+/___SG"#X=B +XM]O__BX4T____@\(!*<*)E2C____I9/;__XN%0/___XE$)`2+50B)%"3HR.G\ +XM_^G(_O__BX5`____B40D!(M5"(D4).BNZ?S_ZG)]?__BT4( +XMBXC(`P``Z?#^__^+10B+B,@#``#IW/W__XM%"(M`.(F%+/___XN%-/___XM= +XM#(E##,9#%/_'A3#___\`````Z8+U__^#A33___\!BYTT____BTT,B5D,QD$4 +XM`,>%,/___P````#I7/7__XM5"(N--/___SM-\(M2.(F5+/___W.D.YTX____ +XM#X0B`0``BXTT____BU4,B4H,*YTX____*=B)A3#___^(0A2#;>0!Z1/U___& +XM!P"-E63___\KO1S___^)5"0$B7PD"(M-"(V]9/___XD,)(N=)/____^36`@` +XM`(M%"(M8$.G$]___BX5`____B40D!(M5"(D4).AMZ/S_Z7/W__\/MD(5.,$/ +XMA,(```"+4A`/ML")A3#___\/MH4P____B94T____BXTT____BU4,B4H,B$(4 +XMBUT(`4WD]H,4`@```716BX,,`@``C01`P>`"`T,0BT`XA%,/___P````#I\?/__XM2$#'`QX4P____`````(/"`8F5-/___^DZ +XM____D)"0D)"0D)"0D)"0D%6)Y5.#[!2+70B+0Q"+4S2+B)`(``"+0T`YT'(# +XMC4+_B1PDQT0D"`````")1"0$_]&+0Q")'"3'1"0$`````/^0F`@``(/$%%M= +XMPY"-="8`58GE5U93B<.#[#R)5=")3S0!#X1/`0``@WW,`0^$!0$```^# +XML````(U%\(E$)`C'1"0$`0```(D<).BQ'_W_B<*+1?")5"0$B1PDB40D"/^6 +XM6`@``(.'7`$```''AU0!````````C7W4B1PD_Y9L"```QT0D!`````")'"3_ +XMEI@(``"+5="%TG0ABT70QP``````ZQ:+1=R#^`%T48/X!'1!B1PD_Y9D"``` +XMQT0D#`````#'1"0(`````(E\)`2)'"3H:>S\_X7`=,J0C70F`(/$/%M>7UW# +XM@WW,`G0KZ-%Y_/_&1>!Q@XY4"```!(-]S`%T48-]S`)UUH!]X'%UT(..5`@` +XM``3KQXU%\(E$)`C'1"0$!0```(D<).C0'OW_B<+I&O___XU%\(E$)`C'1"0$ +XM`@```(D<).BR'OW_B<+I_/[__X!]X#IUA8M%T(7`#X1Z____BT70QP`!```` +XM@\0\6UY?7<.-1?")1"0(QT0D!`0```")'"3H@"=#&+3>B)V(M5[(M=](MU^(M]_(GL7>F3_?__C78` +XMBU-`.=!V*2G*ZX60C70F`(U"_^NOBU7PBX)4`0``.T-`<\&+7?2+=?B+??R) +XM[%W#C5#_*L!```"`^$ +XM;0$``(M#$(E$)`R+0PR)1"0(BT,(B3PDB40D!/^6E`@``(L3A=)T!HM#!(E" +XM!(M#!(D0BT,,B00DZ.)\_/^)'"3HVGS\_XM>;(7;=;>+1+1<#'@%P!````````QX!8`0```````,>`5`$```````"+ +XM1>R+50R)1"0(BT7PB10DB40D!/^6D`@``#'2@\1,B=!;7E]=PX/H`71F,"7`$```````#'@E@!````````QX)4`0```````(E$)`2)/"3H +XM^A(``.EO____BTT0AL +XM!```QT0D"`(```"+1TR)/"2)1"0$Z$<<_?_ICO[__X/@_8F&5`@``(D\)/^6 +XM9`@``.EF_O__QT0D!`$```")/"3H:R<``+H!````A<`/A+C^___I#____XG! +XM*='I0/___XE]#.D+_O__,S<````B85`____B94\____BY5`____B8TX____BT`0B85$____BT4(BY*< +XM````B8U4____A<")E4C___\/CI8#``"-C7#___^-7>^)C3#___^)G33___^+ +XM70B+M3C____'1"0$"@```(E<)`B)-"3H6'7\_XF=4/___XF%5/___XN%5/__ +XM_X7`=!"+E53___\I\HF54/___XG3BXU(____B[5`____BY%8`0``BTXXC003 +XM.7UW#B[5`____BYU,____B30DB5PD!.@OWOS_ +XMB<;I"?[__XN-0/___XNU1/___XM!0(M)-(N>D`@``#G(<@.-0?^)1"0$BX5` +XM____B50D"(D$)/_3@[T\____`P^%7/W__XN50/___XN-1/___\=$)`@!```` +XMQT0D!`$```")%"3_D5P(``#I,OW__XN-0/___XN=1/___\=$)`@`````QT0D +XM!`$```")#"3_DUP(``#IX?[__XN%0/___[D"````,=+H(_C__^E*_/__BY5( +XM____BX)<`0``Z3'\__^+E4C____V@L@!```"#X0>_/__@ZI4`0```8/H`6:# +XMHL@!``#]B8)<`0``Z0'\__^+M4#___^+G43___^+1D"+BY`(```YP@^&Q0`` +XM`(/H`8E$)`2+A4#____'1"0(`````(D$)/_1BY5`____BXU$____B10D_Y%L +XM"```BYU`____BW,X@_X/=@6^#P```(N%0/___XM8$,=$)`@!````QT0D!`$` +XM``")!"3_DUP(``"+E4#___^)="0(QT0D!#$-"0B)%"3_DU@(``"+C4#____' +XM1"0(`````,=$)`0!````B0PD_Y-<"```BYU(____@X-<`0```6:#B\@!```" +XM@X-4`0```8N#7`$``.D0^___C4+^Z3;___^+A4C___^+M4#___^+E43___\% +XM6`$``(E$)`B-1?")1"0$B30D_Y)P"```Z=']__^-=@!5B>575E.#[#R+=0B+ +XM?0R+1A")1="+GIP```#'!P````"+@U@!``!F@XO(`0```87`#X5)`0``BY:L +XM!```]L(0#X40`0``]\(``!``=0V#NUP!```!#X:X`0``B=`E___O_X'B```( +XM`(F&K`0``'40BT80]H!4"```!`^$,@$``/:&K`0``!`/A;4```"+1A"#P`@Y +XM!G0'@XZL!```0/:#R`$```@/A8L```#'1"0(`0```,=$)`0`````B30DBU70 +XM_Y)<"```@::L!```[__W_X.[7`$```$/AD@!``#'1>`&````BY-<`0``N0$` +XM``"+1C0YPG)9B47LC478B4WDQX-<`0```````,>#6`$```````#'@U0!```` +XM````B40D!(DT).@&"P``,=*#Q#R)T%M>7UW#@XZL!```(.EI____9H.+R`$` +XM``3I/O___Y")P2G1ZZ&+1A#'1"0$`@```(DT)/^0H`@``+H!````A#4`$```$```#IA?[__\=$)`P!````QT0D"`````#'1"0$`````(DT).B. +XMX/S_A7UW#B?J)\.BG +XM\O__ZZ>0C70F`%6)Y5=64X/L+(MU"(M=#/:&K`0``!"+?A!T-8M5$(72#X0L +XM`0``A=N)V`^$&`$``(E4)`R)1"0(QT0D!'WI"`B)-"3HF$S^_XDT).BP2_[_ +XMC47PB40D"(U%[(E$)`2)-"3_EW`(``"+1D"+5C2+CY`(```YT'(#C4+_QT0D +XM"`````")1"0$B30D_]&)-"3_EVP(``"%V\=%X`````!T+HD<).CM'````BT7@B40D"(E<)`2)-"3_EU@(``"+51"%TG0PBT40 +XMB00DZ+5R_/^+7CB+5>")P0'"C4/^.<)W1(M%$(E,)`B)-"2)1"0$_Y=8"``` +XMBT7PB30DB40D"(M%[(E$)`3_EY`(``")-"3'1"0$`````/^7F`@``(/$+%M> +XM7UW#*UW@C4O^Z[2-="8`B47@Z73___^X3XT(".G>_O__ND^-"`CIRO[__XUT +XM)@!5B>6#[#B)=?B+=0B)7?2+11")??SVAJP$```1=3.#^`*+?A"+GIP```!T +XM-(/X`P^$JP$``(/H`0^$D@```(GVQT0D!`````")-"3_EY@(``"+7?2+=?B+ +XM??R)[%W#B?:+@V`!``"%P'36BY-<`0``@^@!B8-@`0``A=)U,87`=2V+1D"+ +XM5C2+CY`(```YT'(#C4+_QT0D"`````")1"0$B30D_]&)-"3_EVP(``"+@W`! +XM``")1"0(BX-L`0``B30DB40D!/^7D`@``.EP____BX-@`0``BXM<`0``@\`! +XMA`$``&G`0$(/``'"@?I'Z`$`#XX<_O__BT7DBU7H@[MD`0``!(F#=`$` +XM`(F3>`$```^$A0```(N'D`@``(E%W(M&0(M6-(N+:`$``#G0<@.-0O^)3"0( +XMB40D!(DT)/]5W(N39`$``(N'6`@``(U*`8'"1PT)"(F+9`$``(E4)`3'1"0( +XM`0```(DT)/_0BX>0"```B47@BU9`BTXTBX-H`0``.7UW#BTW<@Z%4"```_8M%"(D$)/^19`@``.GB_O__J!`/A.T"``"+ +XM50B+0A#'1"0$`0```(D4)/^0H`@``(7`#X37_O__Z2;___^-1?")1"0(C47L +XMB40D!(M-"(D,)(M5W/^2<`@``(-]#`$/A`$"``"+512+11"+30B`?!#_"@^4 +XMP`^VP"G"B544@WDT`0^$?`,``,=%Z`````"+5>B+10B#P@*)5>B+2#B#Z0&) +XM3>"+3=B+@5@!``"%P'0IC00"`T44.47@#X/U`@``BY%0`0``N574"`C'!"0" +XM````BT4(Z/[P__^+30R+5=B)BE`!``"+112+71"%P'4FZ8L-B?8Y^'T2]D2&-@)T"X/I`0^^0?^%P'GJB=:)\"G8*444#X7P```` +XMB<@IV(/X`7X+@'P8_RX/A`P!``")!"2+50R)V8M%".C7[___BTT(BT$0]H!4 +XM"```!'5LQT0D#`$```#'1"0(`````,=$)`0`````B0PDZ"C8_/^%P'4/BU4( +XMBT(0]H!4"```!'4YB?/IP?[__XM!$,=$)`0"````B0PD_Y"@"```@\0L6UY? +XM7<.+312Z`0```(D,)(M-$(M%".A<[___BT7PB40D"(M%[(E$)`2+30B)#"2+ +XM5=S_DI`(``#'1"0$`````(M-"(D,)(M5W/^2F`@``(/$+%M>7UW#BU44C303 +XMB?")\2G8*444#X00____*=F)#"2+50R)V8M%".CY[O__N2:Z"`BZ`0```,<$ +XM)`$```"+10CHX.[__^D$____C4'_*=CIZO[__XM-"(D,).CVW/[_A<`/A/;[ +XM___I1?S__\=$)`@!````QT0D!`$```"+10B)!"2+5=S_DEP(``"+31")3"0( +XMBT44QP0D\I@("(E$)`3H1&?\_\=$)`@`````QT0D!`$```"+50B)%"2+3=S_ +XMD5P(``#IO/O__XG1B=;I2_[__XD<).BO:?S_BT40B40D#*$0(0D(BU44QT0D +XM!$$-"0B)!"2)5"0(Z-QA_/_IK_O__XM%V+E8\0@(BY!0`0``QP0D`0```(M% +XM".@&[O__N=+4"`BZ`0```,<$)`$```"+10CH[>W__^GJ_/__QP,`````B5AL +XM@\!LB4,$Z6#[__^-1>B)1"0(QT0D!`0```")#"3H_0C]_^EO_/__D)"0D)"0 +XMD)!5B>564X/L$(M=#(MU"(M3##M3%'80ZU.+4PR#P@$Y4Q2)4PQR18N&G``` +XM`(T44L'B`P.0C`$``(/J&,9"%@#'1"0,`````,=$)`@`````B50D!(DT).BU +XMV?__ARL````B95P____BT`0B85X____BY:<````B95\____B='VAJP$```@ +XM='7'@JP!````````BX:L!```]L0!#X6/!P``A,!Y+\=$)`@"````BT9,B30D +XMB40D!.A8(@``A7UW#QT0D"`,```#'1"0$ +XM`````(DT).@H(@``A2)?"0,B40D"(E<)`2)-"3HH=?__X7`#X5Y +XM_O__@WWD_W3&BY5\____BX+$`0``A``"Z`0```(G#BT9`@_@!=`2)PM'J.=H/@OD'``"%VP^$?@```#M& +XM/'4'ZW`"`T80BT`XA<`/E<"$P`^%.@<``(N-?/___\=%Y/_____'@<0!```````` +XMBX:<````.9B0`0``#X+J"0``BP,[1DP/A=\)``"-N<`!``#K(9"+AIP```"# +XMPQ@YF)`!```/@MH&``"+`SM&3`^%SP8``(U%Y(E\)`R)1"0(B5PD!(DT).C) +XMU/__A<`/A:'[__^#?>3_=+N+E7S___^)FL0!```QTL=%B`````#K&O:&K`0` +XM`$!T#(M&0#E&1`^%?0<``+H!````BXU\____BYG$`0``A=L/A$P)``"+1E"+ +XMC7S___^)@;P!``"+1DR)@;@!``#VAI@"```!#X4=`0``BX:0`@``A<`/E<"$ +XMP'07BX5\____]H#(`0``('0(A=(/A"<#``"+18B%P'0'@XUP____`XN5_K)`^VP(T$0`'``T80#[:`70$```%%D#M]D`^"P@@``(M& +XM((M`"(/K`3G8#X-L!P``#[8#/"\/A%X'```\_W7"QT0D!/____^)-"3H%LG\ +XM_^O"BX:0`@``C01`P>`"`T80BT@XAF)5"0(B5PD!(E,)`R)-"3H&QD``(M6/(/Z +XM`8G#N`$```!T!(G0T>@YV`^'>P@``,=%J`$```"+AIP```"#^@&+@(P!``#' +XM1;`!````BT`$B46LN`$```!T!(G0T>B)1"0,BT9,B30DB40D"(U%J(E$)`3H +XMN!@``(M6/+D!````@_H!=`2)T='I.<$/AQ0)``"+5DS'1"0(`@```(E4)`2) +XM-"3H^!H``(7`#X6@^/__@XZL!```0.GX^/__QT0D"`,```#I/X__^+0@@YQP^&V/C_ +XM_XM./+L!````@_D!=`2)R]'KB?DIP3G+#X)_"@``B30DZ"(B``"%P`^%^O?_ +XM_XN&G````(N`D`$``#MX"'??Z97X__^)-"3H;,___X7`#X3)_/__C70F`.G+ +XM]___QT60`````#M&!)`/A3/]__^)-"2+593_DFP(``"+7CB#ZP'VAC0#```! +XM#X3?!@``BX8L`P``C01`P>`"`T80BT`XA<`/E<"$P`^%+0<``(M]D(/'`O:& +XMH`,```$/A)T&``"+AI@#``"-!$#!X`(#1A"+0#B%P`^5P(3`=#:+1AP/MD!8 +XM@^`$@_@!C474@]/_B40D"(N&E````(DT)(L$A9`-"0B)1"0$Z"[^_/\K7=2) +XM18PY^W9TBT64BU8TBXB0"```BT9`.=!R`XU"_XE<)`B)1"0$B30D_]'VAJ`# +XM```!#X1>!P``BX:8`P``C01`P>`"`T80BU@XA=L/E<"$P'0IBT8<]D!8!`^% +XM00H``(M%U(E$)`B+38R)-"2)3"0$BU64_Y)8"```B?;VA7#___\!#X5=`0`` +XMBX5T____A<`/A2/____^2D`@``(DT)(N->/__ +XM__^1;`@``(N&G````(-N/`&#J)`!```8BT8\.T9$=Z+'1"0(`0```(M&3(E$ +XM)`2)-"3HRQ<``(7`#X33_/__Z6[U__^+A@P"``"%P`^5P.DY^?__BXU\____ +XM#[>!R`$``(DT)(/@!(E$)`2+E7C_____DI@(``#IL?[__XN-?/___XN!P`$` +XM`(E$)`B+1>2)-"2)1"0$BY5X_____Y*0"```BU6(A=(/A'+^__^-1E2)1"0$ +XMB30DZ*8*``#I7O[__S'2QT6(`````.EY^?__C490QT0D$`````")1"0,B50D +XM",=$)`0`````B30DZ&`.``")1:`/MHZ8`@``@^$!#X6?````BY:0`@``A=(/ +XME<"$P'0*@WV@!W8$@VV@"(M[!#E]H`^'WP```(N6I`,```^VCJP#``"-!%*# +XMX0&)A6S___^$R8G0=`^+A6S____!X`(#1A"+0#@YQP^"I@,``(3)B=!T#XN% +XM;/___\'@`@-&$(M`."G'.7V@=L?VAJ\$```0#X3>`0``B7L$BX:<````BXB0 +XM`0``QT6(`````.D+]?__BY:0`@``C012P>`"`T80BT`XA<`/E<#I4/___XM> +XM/#G8#X)X^/__C;0F`````(E<)`2#PP''1"0(`````(DT)(N->/____^1D`@` +XM`(DT)(N5>/____^2;`@``#E>0'/.Z3KX__^%_XVT)@`````/A?$!``"$R0^$ +XM.0,``(T$4L'@`@-&$(M`.(7`#Y7`A,`/A!,#``"+5CB)T(E5G(/H"#E%H`^& +XMSP$``(N&I`,```^VCJP#``"-%$"#X0&)A63___^)E6C___^%R8N%9/___W0/ +XMBX5H____P>`"`T80BT`XBU6<`<>-!!@2+AIP```"#PAB+B)`!```YT7/JQT6(`0```.D'\___@XZL!```((GP +XMBY5P____Z(;Q___I]O'__XM&4#N!O`$```^$W0(``(U%X(E$)!"-1>R)1"0, +XMC47B)1"0(C47DB40D!(DT)(N5>/____^2<`@``#'2QT6(`````.EP\___BX5\ +XM____BY"\`0``.590#X-A`0``B=<#?=R)?=R+@+P!```[1>R+3E`/@S?V__^- +XM4`$IRHN-?/___XN!P`$``(/`!3G"#X<;]O__C5K_@_O_QT6`_____P^$#/__ +XM_P^V%XU'_XE%W(#Z"0^$]O7__P^VPC'_B46$ZSN+582-!%(!P`-&$`^V@%T! +XM``"#ZP$!QX/[_P^$RO[__XM%W`^V$(/H`8E%W(#Z"0^$M_7__P^VRHE-A(#" +XM`77`BTV$B30DB4PD!.@1O?S_Z\''1"0$_____XDT).C_NOS_Z6#[__^)>0C' +XM1"0(`P```,=$)`0`````B30DZ"\0``"+1DR#CJP$``!`BY:<````Z8KU__^+ +XM?9"#QP*-!#HYPP^&[_W__\=$)`@"````QT0D!+C<"`B)-"2+593_DE@(``"+ +XM1=2+39"#P`*-?`$"Z<']__^)>@C'1"0(`````,=$)`0`````B30DZ,`/``"# +XMCJP$``!`Z17N__^+1=R+C7S___^#P`$!T(E%W(M>4(NYP`$``"N9O`$``.LE +XMBX:0`@``C01`P>`"`T80BT`XA<`/E<"$P'16BT8X@^@(.?AV7X/K`8/[_W17 +XMBT7<#[80@\`!B47<@/H)#X2,]/__#[;"@,(!="R-!$`!P`-&$`^V@%T!```! +XMQ_:&F`(```%UG(N.D`(``(7)#Y7`ZZ:+1CCKJXE$)`2)-"3HP+O\_^O5BX5\ +XM____B;C``0``]H:8`@```71;BX:0`@``C01`P>`"`T80BU`XA=(/E<"$P'0[ +XMBT8X@^@(.<GD_/__58GE5U93@^P< +XMBWT(BT<0B47L]H>L!```0`^%%@$``(M8"(UP"/:'F`(```$/A#T!``"+AY`" +XM``"+5>R-!$"+1((XA<`/E<`\`1G`@^#@@\`Q.=Z)1?!U0NM;C;8`````BY.< +XM````#[>"R`$``(5%\'0B#[>2R`$``(G8@^(!@\H"Z!KK__^+AYP```!F@XC( +XM`0```8L;.?-T&SG[=/:+@ZP$``#VQ`9UZZA@=+.+DYP```#KO8M=#(7;=0WV +XMAZP$```(#X6V````N@,```")^.C+ZO__N@$```"%P'5-BU7LBUH(.?-U#NLX +XMC;8`````BQLY\W0H]H.O!````G3QB1PDQT0D"`````")?"0$Z(W5__^+&[@! +XM````.?-UV(7`=7B#CZP$```(,=*#Q!R)T%M>7UW#BU7LBUH(B=:#Q@@Y\P^$ +XMW?[__SG[=`J!BZP$``!````"BQLY\W7LBT7L]H>8`@```8M8"`^%P_[__XN' +XMD`(``(7`#Y7`ZS' +XM1"0$`````(D\)/^2F`@``#'2@X^L!```".EO____D)"0D%6)Y8M-"%/V@10" +XM```!BY&<````=&*+@0P"``"-!$#!X`(#01"+0#B%P`^5P(3`=%:+@L0!``#V +XM@9@"```!BY+``0``BU@$=%V+@9`"``"-!$#!X`(#01"+2#B%R0^5P,'@'\'X +XM'X/@"(T4$RG"BT4,B1`QP%M=PXN9#`(``(7;#Y7`A,!UJHN"Q`$``(N2P`$` +XM`(M8"(/K`0^O63CV@9@"```!=:.+@9`"``"%P`^5P.NMC;8`````C;PG```` +XM`%6)Y5=64X/L3(U%\(E$)!"-1>R)1"0,QT0D"`````"+10R)1"0$BT4(B00D +XMZ!_&_/^+=>R%]@^$A0$``(M=\(7;#X1Z`0``BU4(]H(X`@```0^%\````(M- +XM"(M%"(N),`(``(E-W/:`%`(```$/A/D```")PHN`#`(``(T$0,'@`@-"$(M` +XM.(E%V(M-"#'2,?^+11#W<3B)5/^__\Q_^G<_O__ +XM@\1,,/_#[9%XW1W +XMBU4(C01``<`#0A`/MH!=`0```<,)=&:#ZP$I3D#____BT7`"`T(0BT@XZ\R)^#'2]_''1`"`T(0BT`XB474,?^%VP^$$@$``(L[B77@QT70`````.M7@/O_#[;# +XM#X1]`0``BU4(C01``<`#0A`/MH!=`0```470C30PBT74A`" +XM`T(0BT@XBT70,=+W\8G(*=#I>____XM%"(N0D`(``(72#Y7`Z=C^__^-=@"` +XM^_\/ML,/A!"+51B%TG0)BU48B?`IV(D"@\0\B?!;7E]=PXM%"(N(R`,``.G+_O__ +XMB?`QTO?QQT70`````"G6Z6W^__^)1"0$BT4(B00DZ,ZR_/_IY_[__XG"BX#( +XM`P``C01`P>`"`T(0BT@XZ3C___^+3=B%R720BU4(BT(0#[:`-0(```'&Z7S_ +XM__^)R#'2]W7,,?\IT>G(_O__C47PBU4(B40D$(U%#(E$)`R+11#'1"0(```` +XM`(D4)(E$)`3H'<#\_XM%\(7`=1F+11B%P`^$0O___XM5&,<"`````.DT____ +XMBT4,A<")1=P/A1W]___KUXVV`````(V\)P````!5B>564X/L((M="(MU$/:# +XM%`(```$/A)@```"+@PP"``"-!$#!X`(#0Q"+0#B%P`^5P(3`=6^%]@^$A0`` +XM`(L&A7<.Z`0```(/$((G06UY=PXN##`(``(7`#Y7`Z6____^+ +XM@YP```"+50PYD*P!```/A6S___^+D+`!``#KRE6)Y5=64XG#@^PLB57@BW`0 +XM@W@T`71_C47LB40D"(U%\(E$)`2)'"3_EG`(``"+1>"%P'17,?^)'"3_EG0( +XM``"+0T"+4S2+CI`(```YT'(#C4+_QT0D"`````"#QP&)1"0$B1PD_]&)'"3_ +XMEH@(``"+1>R)1"0(BT7PB1PDB40D!/^6D`@``#M]X'6K@\0L,R)'"2)1"0(BT7PB40D!/^6D`@``(D<)/^6B`@``#M] +XMX'0WBU-`BT,TBXZ0"```.<)RJX/H`NNIQT0D"`````#'1"0$`````(D$)/^6 +XMD`@``(D<)/^6;`@``(/$+#'`6UY?7<.)]HV\)P````!5B>575E.#[`R+?0B+ +XM=0SVAQ0"```!=#B+APP"``"-!$#!X`(#1Q"+6#B%VP^5P(3`="R+!CM%$'=S +XMBW40*<:#Q`R)\%M>7UW#C;0F`````(N/#`(``(7)#Y7`A,!UU(L>.UT0=%8Y +XM71!S88MV"(/K`8/N`3E=$'?&.W44=@?KOSEU%'*ZB5PD!(/K`<=$)`@````` +XMB3PDZ&3\__\!QCE=$';=@\0,B?!;7E]=PXG&*W40@\0,6XGP7E]=PXMV"(/$ +XM#%N#[@&)\%Y?7<.)7"0$@\,!QT0D"`````")/"3H'?S__RM&"#E=$(UP`753@^P4BU4(BUT0BTT,QD,6`/:"%`(```%T-HN"#`(``(T$0,'@ +XM`@-"$(M`.(7`#Y7`A,!T*HL!@^@!B0.+002)0P0QP(,[``^4P(/$%%M=PXN" +XM#`(``(7`#Y7`A,!UUH-Y"`%T&XL!B0.+00B#Z`&)0P@QP(,[``^4P(/$%%M= +XMPXL!@^@!B0/'1"0(`````(E$)`2)%"3H0OO__XE#".NBC;8`````C;PG```` +XM`%6)Y593@^P0BU4(BUT0BW4,QD,6`/:"%`(```%T,HN"#`(``(T$0,'@`@-" +XM$(M`.(7`#Y7`A,!T)HL&@\`!B0.+1@2)0P2#Q!`QP%M>7<.0BX(,`@``A<`/ +XME<"$P'7:QT0D"`````"+!HD4)(E$)`3HN_K__SM&"'06BP:)`XM&"(/``8E# +XM"(/$$#'`6UY=PXL&QT,(`0```(/``8D#ZZ95B>575E.#[#R+?0B+=0R+71"+ +XM3SR+AYP```"%R8N`C`$``'00,=*#P@'&0!8`@\`8.<````BX*0`0``ZPV0C70F`(N7G````(G8.X*,`0``#X8-`0``C5CHB5PD +XM"(E$)`2)/"3H"?[__X7`=-6^`0```(N'G````(N`C`$``(DPBX><````BX", +XM`0``QT`$`````(N'G````(N`C`$``,=`"`$```"+AYP```"+7SR+@(P!``#K +XM`HGP@^L!#X2A````C7`8B70D"(E$)`2)/"3H3?[__X7`=-Z+AYP```"+@(P! +XM``#'``$```"+AYP```"+@(P!``#'0`0`````BX><````BX",`0``QT`(`0`` +XM`(N7G````(N"C`$``.L+C78`BY><````B=@[@I`!``!S,8U8&(E<)`B)1"0$ +XMB3PDZ-W]__^%P'39@\0\N`$```!;7E]=PX7V#X44____Z4/___^#Q#PQP%M> +XM7UW#QT7<`0```+H!````QT7@`````,=%Y`$```"+1SR#^`%T!(G"T>J-7=R) +XM5"0,B70D"(E<)`2)/"3HJ/O__XM7/+D!````@_H!=`2)T='I.<$/@ZK^__^) +XM7"0$B3PDZ*.Z_/^%P`^%<````BY"0`0``BT7")0@2+AYP```"+D)`!``"+1>2)0@CIO_W__XN'G````(N` +XMD`$``(DPBX><````BX"0`0``QT`$`````(N'G````(N8D`$``,=$)`@````` +XMB70D!(D\).BA]___B4,(Z7;]__^+3SR+EYP```#1Z8T$2<'@`P."C`$``(DP +XMQT`$`````,=`"`$```#K`HG8BY><````BXJ,`0``.L(BY><````B=@[@I`!```/ +XM@S+^__^-6!B)7"0(B40D!(D\).C>^___AF,_?__D(UT)@!5B>6#[#B+ +XM112)=?B+=1")??R+?0B)7?2#^`(/A+\```"#^`-T4H7`=4F+AYP```"+D)`! +XM``")T2N(C`$``(G(P?@#:<"KJJJJ.<8/A@4!``#'1"0(R`T)",=$)`0"```` +XMB3PDZ,?J_/^X`0```.G6````Z&P\_/^+AYP```"+D(P!``"+@)`!```IT,'X +XM`VG`JZJJJCGP-!':%]HT@?`=#1^`'PC01`C1S!@'L6``^$!@$``(L#BTT,B0&+ +XM0PR)000QP(M=](MU^(M]_(GL7<.-!':)T\'@`RG#B47@BP.)/"2)1"0$Z`^W +XM_/^%P'6[C47PB40D!(D\).B@?`=#1^(T$0,'@`RG#Z?;^__^-M@````#'1"0,`````,=$)`@````` +XMB5PD!(D\).CDL/__A<`/A-;^__^X`0```.G;_O__BX",`0``ZYF+AYP```"+ +XM@(P!``#I*?___XGVC;PG`````%6)Y593@^P0BW4(BX:<````BU9,BYB,`0`` +XMBPLYRG(@BX"0`0``.Q!W%CG*=%F)]H/#&#L3=?DYV'-0D(UT)@"#Q!"X`0`` +XM`%M>7<.-="8`QT0D#`````#'1"0(`````(E<)`2)-"3H1+#__X7`=="+0Q`[ +XM1E!S+(N&G````(/#&(N`D`$``#G87<.-M"8`````C;PG`````%6)Y5.#[!2+70B+0Q#' +XM1"0(`````,=$)`0`````B1PD_Y"0"```N@$```")V.BN]?__A<`/A88```"+ +XM2S2#^0$/A(H```"+@YP```"+D(P!``"-!$F-!,7H____B40D"(E4)`2#PAB) +XM%"3H53W\_XN#G````(N`C`$``(E$)`B#P!B)1"0$B1PDZ$+W__^%P'4NQT0D +XM#`````#'1"0(`````(N#G````(N`C`$``(D<)(E$)`3H-J___X/$%%M=PX/$ +XM%+@!````6UW#D(UT)@"+@YP```"+@(P!``")1"0(ZZ"-M"8`````C;PG```` +XM`%6)Y5.#[!2+70B+0Q#'1"0(`````,=$)`0`````B1PD_Y"0"```N@$```") +XMV.AN\___A<`/A88```"+2S2#^0$/A(H```"+@YP```"+D(P!``"-!$F-!,7H +XM____B40D"(U"&(E$)`2)%"3H93S\_XN#G````(N`D`$``(E$)`B#Z!B)1"0$ +XMB1PDZ`+W__^%P'4NQT0D#`````#'1"0(`````(N#G````(N`D`$``(D<)(E$ +XM)`3H1J[__X/$%%M=PX/$%+@!````6UW#D(UT)@"+@YP```"+@)`!``")1"0( +XMZZ"-M"8`````C;PG`````%6)Y5=64X/L/(M%"(M=$(M]#(N`G````(7;#Y3" +XMB=:)1=!U3(7_=4C'1"0$`@```(M-"(D,).@5L_S_A^@*-_S_C;8`````BT4(BY"<````Z[V0C70F`(/_`76PZ5[___^-M@````"+ +XM==!F@X[(`0``$,>&K`$```````"+10@Y>$P/A'\!``"+50B+@JP$``"I```` +XM$'5UJ!!T8HM-T#'`9H.)R`$```B#Q#Q;7E]=PXVV`````(/[`@^%-____XMU +XM"(M./(7)=`\QTH/"`8,``8/`&#G*=?.+50B+0DPYQW<&@\`!B4),BTW0,7UW#BX*<````@[A<`0```7>/BW4(C57LBT80B50D"(U5 +XM\(E4)`2)-"3_D'`(``"#^P(/A!H!``"#^P,/A&L!``"#ZP$/A??^__^+EIP` +XM``"+BHP!```[.8G+=`>#PQ@[.W7YBT4(]H`4`@```0^$M0$``(G&BX`,`@`` +XMC01`P>`"`T80BT`XA<`/E<"$P`^%B@$``(N2D`$``(U#&#G0#X=Y`0``.WL8 +XM#X5P`0``O@$```#K"XVT)@`````[.'4*@\`8@\8!.=!V\HM5"#MR/`^"C0(` +XM`(.*K`0``""+==!F@X[(`0``((MU"(M5[(M&$(E4)`B+5?")-"2)5"0$_Y"0 +XM"```,<#I\OW__V:#CL@!```!Z73^__^+=0B+3CR%R706,=*-M"8`````@\(! +XM@R@!@\`8.G_O__@^@!B4),Z9S^__^+50B+@IP```"+ +XMF(P!``"+2P2)3=0[.W0(D(/#&#L[=?G'1"0(`````(E\)`2+=0B)-"3HXN[_ +XM_SM&/(G!#X+J`@``@XZL!```((M-T&:#B<@!```@Z3S___^+=0B+EIP```"+ +XMLHP!```[/G0'@\88.SYU^8M%"/:`%`(```$/A'H!``")P8N`#`(``(T$0,'@ +XM`@-!$(M8.(7;#Y7`A,`/A`H!``")\\=%X`$```#'1=@!````BTT(BT7@.T$\ +XM`!.=AS\<=$)`@`````B7PD!(M5"(D4).@D[?__B478 +XMZ;?^__^+10B+B`P"``"%R0^5P.F,_O__BU4(BT(0B=HIRL'Z`VG2JZJJJL=$ +XM)`@`````B50D!(M-"(D,)/^0D`@``(M%"(GRZ+3M__^%P`^%(O___XM5"(T$ +XM=HT\Q0````"+@IP```"+@)`!``")'"0IV,'X`VG`JZJJJH/``2GPC01`P>`# +XMB40D"(T$'XE$)`3HGC;\_XM-"(N!G````(N0D`$``(G0*?@YV'(=@RL!@\,8 +XM.=AS]HMU"(N&G````(N0D`$``(G0*?B-6!B-0^B)WCG0`#B40D".A;-?S_BU4(BX*<````.["0`0``=Q>#!@&# +XMQAB+30B+@9P````YL)`!``!SZ8MUW(7V#X1$_/__O@$```#K#X/&`3MUW`^' +XM,?S__X/#&(D[BT74B7,(QD,6`(E#!,=$)`P`````QT0D"`````")7"0$BU4( +XMB10DZ!"G__^%P'2_Z1W]__^+30B+@9P```"+@)`!``")="0$*?#!^`-IP*NJ +XMJJJ#P`$IV(T$0,'@`XE$)`B-!%N-!,:)!"3HH#3\_XM%V(7`#X3]^O__BU4( +XMBX*<````.["0`0``#X?H^O__NP$```#K*9"-="8`.UW8#X33^O__BU4(@\88 +XMBX*<````.;"0`0``#X*[^O__@\,!B3Z)7@C&1A8`QT0D#`````#'1"0(```` +XM`(ET)`2+30B)#"3H5*;__X7`=+#I8?S__XM-"(M=X"M=V(M1$,=$)`@````` +XMBX&<````B?$KB(P!``")R,'X`VG`JZJJJHE$)`2+10B)!"3_DI`(``"+10B) +XMVNBDZO__A<`/A1+\__^+50B-!%O!X`.)1`#B40D"(M%S(DT)`'PB40D!.B-,_S_BT78A",9&%@#'1"0,`````,=$)`@`````B70D!(M-"(D, +XM).A]I?__A<`/A8O[__\[7=AUQ8MU"(N&G````(N0D`$``(G0*T7,C7`8C4;H +XMB?,YT',;B70D"(E$)`2+10B)!"3HS>W__X7`#X5+^___QT0D#`````#'1"0( +XM`````(ET)`2+50B)%"3H%J7__X7`#X4D^___BTT(@\88BX&<````BY"0`0`` +XM.=IUG^DO^?__B?/'1>``````Z6K[__^0C70F`%6)Y5=64X/L?(M]"(MU$(N' +XMG````&:#B,@!```!C47PB40D!(D\).@$]/__A<`/A7P!``"#?10'=@N-M@`` +XM``#H/R[\_P^V312P`=/@J(X/A6@!``"H<73ABX><````BUWPBY",`0``BPJ# +XM^0$/A-$#``"+1T`Y1T0/A!\$```YQ@^"NP(``(L"B46\BT($B47`BT((B47$ +XMBT(,B47(BT(0B47,BT(4B470B?CH?^G__X7`#X7W````A?9T?3';D.LKBT78 +XM@\,!BTW4.?.)1<"+1=R)3;R)1<2+1>")12)1B)1=!T4(U%U(U5 +XMO(E$)`B)5"0$B3PDZ+WK__^%P`^%I0```(-]U`%UL?:'%`(```$/A!8&``"+ +XMAPP"``"-!$#!X`(#1Q"+0#B%P'4&@WW<`76(BTW4BX><````BY",`0``B0J+ +XM1=B)0@2+1=R)0@B+1>")0@R+1>2)0A"+1>B)0A3'1"0(`P```,=$)`0````` +XMB3PDZ(_L__^%P'4KQT0D#`````#'1"0(`````(M-#(D\)(E,)`3H_.___X7` +XM#X1@`@``C70F`+@!````@\1\6UY?7<.+3?"-1=2)39R)1"0(BX><````BX"0 +XM`0``B3PDB40D!.B.Z___A<````BX"0`0``B3PDB40D!.@[ZO__A<`/A"/_ +XM___I;O[__XM%%(7`#X0Z_?__@WT4!0^$X0```(U%[(E$)`2)/"3HRO#__\=% +XMF`````"%P`^%PP```(7V='2+1SP[1T!U2.MJBX<,`@``C01`P>`"`T<0BT`X +XMAR+30R+$(D1BT`,B4$$A?8/A0(#``"#?10%#Y5%JX!]JP!T%(-] +XM%`)T#HM-#(M!!(7`#X2\`@``@\1\,_[___'1"0$`````(D\).@\<````BYB,`0``QT6P`0```.F9_O__BX><````BY"0 +XM`0``BP*)1=2+0@2)1=B+0@B)1=R+0@R)1>"+0A")1>2+0A2)1>B)^.C+X___ +XMA<`/A4/[__^%]@^$20,``#';ZU*-M"8`````BT6\.T74=!2)1"0$B3PDZ(RC +XM_/^%P`^$(@,``(M%P(/#`8M-O#GSB478BT7$B4W4B47R+30R+$(D1BT`,B4$$A?8/A!#\ +XM__\QV\=%H`````#K$X-]%`<```` +XMBX"0`0``B3PDB40D!.@WY?__A<`/A6_Y__^+AYP```"+5=2+@)`!```Y$'04 +XMB50D!(D\).C`H?S_A<`/A"H!``")/"3H<.W__X7`#X4X^?__@WT4`G6)BX>< +XM````BU6<.Y",`0``=S#'1:`!````Z7;___^%VW0IBX><````BTV<.XB,`0`` +XM#X9=____@^D8B4V<````BU6<.Y"0`0``=1OK.(UV`(/N`70P +XMBX><````BTV<.8B0`0``=!^+79R#19P8BU6`#*<.)7:SI?/O__XM% +XME(7`#X2;^?__BP.+30R)`?:'%`(```$/A&@!``"+APP"``"-!$#!X`(#1Q"+ +XM0#B%P`^5P(3`#X0Y`0``BTL$BT=4,=+W=SB-%!&)5"0(BP.)/"2)1"0$Z&37 +XM__^+50R)0@3I/?G__\=$)`P`````QT0D"`````")3"0$B3PDZ.V9__^%P`^$ +XM_/K__^FP]O__@WT4`P^$@P```(-]%`>)]@^%)/7__^E*_O__BT6@A<`/A.;X +XM__^+39R+50R+`8D"]H<4`@```0^$V@```(N'#`(``(T$0,'@`@-'$(M`.(7` +XM#Y7`A,`/A*D```"+19R+2`2+1U0QTO=W.(T4$8E4)`B+39R+`8D\)(E$)`3H +XMKM;__XM5#(E"!.E_^/__A?8/A87]__^+AYP```"+@(P!``")19SIO/W__\=$ +XM)`P`````QT0D"`````")3"0$B3PDZ!N9__^%P`^$I?W__^G>]?__QT64```` +XM`(VT)@````#IA?G__XM+"(/I`0^O3SB0Z;K^__^+MPP"``"%]@^5P.F?_O__ +XMBU6R+3P2#P`@YP0^$ +XM0`$``(GRB?LQP`%32"ES-`%!2(M!1`%Q-`%Q/#M!0`^$\0```(N1G````(T$ +XM=@%Q0(T\Q0`````!NI`!``"+0T"!B:P$```@```"*7,\*?`[0T2)0T!S`XE# +XM1(N#G````"FXD`$``#'`@8NL!```(````NLEQT0D#`$```#'1"0(+`X)",=$ +XM)`0"````B3PDZ*_/_/^X`0```(M=](MU^(M]_(GL7<,QP.OO*=:-M"8````` +XMBU7LBQ^#P@@YTW0(C48!.4-`)\(G[]]@QTNFN_O__D(VT)@````!5B>57 +XM5E.#[`R%THE5\(M`$'1_BW`0C7@0.?=T?XGSZP:+&SG?="^+0R"+5?"+0`B) +XM5"0$B00DZ`@C_/^%P'7A@\0,B=A;7E]=PXVV`````(LV.?=T1HM&((M8",=$ +XM)`0O````B1PDZ&@A_/^%P'0#C5@!BT7PB1PDB40D!.C"(OS_A+ +XM1TR)0A"+1U"+5R")0A2+1R!F@T@8`8N'G````(&/K`0````0``"+EIP```") +XM=Q2+@+0!``")@K0!``"+1SB)1CB+1S2)1C2+1TB)1DB+1D0[1D`/A#,!``#V +XMAFP$```!#X7[````BX9D!```BU=`B48\.=")1D0/A@G````-'HB8:$````QT0D!!@```"+@[0!``"#P`&)!"3H/2+\_X7` +XMB8.,`0``#X3@````BXZ<````BT8\BY&,`0``C01`@^H8C03"B8&0`0``QT0D +XM"`$```"+1DR)-"2)1"0$Z$;>__^Z`0```(7`=5F+3?"+%H/!$#G*#X3/```` +XMBT8$B4($BT8$.<$/A+,```")$(L'B7X$B0:+1?"+%X/`"#G"#X2/````B7($ +XMBX:<````,=*)-V:#B,@!```!@8ZL!```0````H/$'(G06UY?7<.+AF0$``"+ +XM5T"-!$#!X`(#1A"+0#@YT(E&/(E&1`^'^?[__XM&0.GW_O__BT8T@^@!B49$ +XMB49`B48\Z>O^__^)-"3'1"0(`````,=$)`0%````Z$/,_/^#Q!RZ`0```%N) +XMT%Y?7<.+5?")<@SI:?___XM%\(E0$.E$____BU7PBT8$B4(4BQ;I)____XVT +XM)@````"-O"<`````58GE5U93@^P%]@^$KP```(M&1#M&0`^$R0```(M&-(N6G````(/H`8E&0-'HB8:$ +XM````BT8\BXJ0`0``C01`P>`#`X*,`0``BQ&-6.B)4.B+002)0P2+00B)0PB+ +XM00R)0PR+01")0Q"+012)0Q2+CIP```"+1CR+D8P!``"-!$"#ZAB-!,*)@9`! +XM``"#??`!=#>#??`"=`7HS!S\_\=$)`@`````QT0D!`````")-"3H0-S__X&. +XMK`0```````*#Q!PQP%M>7UW#QT0D"`,```#'1"0$`````(DT).@4W/__Z]*) +XM]HM&-(/H`8E&1(E&/.DF____BQDQ]CG:#X0`____BT%(B=Z)0TB+030!0S3' +XM1?`"````Z>;^__^)]HV\)P````!5B>564X/L((M="(U%](MS$(E$)`2)'"3H +XM<_[__[H!````A`C`$```````"+1?2!BZP$````$```B4,4@\0@B=!;7EW# +XMBT,$B48,BT,$BQ,YP768D(E6"(U6$(D3BT84B4,$.U80=9:)7A#KEL=$)`A8 +XM#@D(QT0D!`,```")'"3HL,G\_[H!````Z[")]HV\)P````!5B>575E.#[#R+ +XM=0B+?0R+1A")1>"#?C0#=RW'1"0,`P```,=$)`B0#@D(QT0D!`,```")-"3H +XM9@2)/C';BT8TN@$```"# +XM^`%T`XU0_XM/-(E60+H!````@_D!=`.-4?^)5T"+5=PY5=@/A.(!``"%VW0# +XM*4X\BT9`.48\=@.)1CPY1D1V`XE&1/:&;`0```$/A=X```"+AF0$``")1SR) +XM1T2+1T`Y1SQV`XE'/#M'1',#B4=$@WXT`8N.G`````^$?`$``(N1C`$``(M& +XM/(/J&(T$0(T$PHF!D`$``(N/G````(-_-`$/A$@!``"+D8P!``"+1SR#ZAB- +XM!$"-!,*)@9`!``"+1D#1Z(7`B8:$````=0K'AH0````!````BT=`T>B%P(F' +XMA````'4*QX>$`````0```(N'K`0``(N6K`0```T@```"@^(/"=")AZP$``"# +XMQ#PQP%M>7UW#C70F`(/[!@^&"_[__[L&````Z0'^__^+AF0$``"-!$#!X`(# +XM1A"+0#CI$?___XVV`````(U%\(E$)`2)-"3H8=[__S'2A-(M/ +XM-(E'2(M&!`%.2(E'!(M%X(M6!(/`"#G"#X3<````B3J+AIP```"[`0```(E^ +XM!(N0C`$``(M&0(D4)"G(C01`P>`#B40D"(T$28T$PHE$)`3H51S\_^D(_O__ +XMBX&,`0``Z;_^__^0BX&,`0``Z8O^__^0C70F`(/X`;H!````=`.-4/_VAFP$ +XM```!B58\B59$=#R+AF0$``"-!$#!X`(#1A"+0#B)1SR)1T2-0?\Y1SP/AB3^ +XM__^#Z0%T.(E'/.D4_O__BU7@B7H,Z9#]__^+AF0$``#KSL=$)`@`````QT0D +XM!`4```")-"3HV,7\_^G@_/__N`$```#KP8M%X(EX"(M/-(UV`.D5____C70F +XM`(V\)P````!5B>575E.#["R+112+=0B+?1"%P(M>$'1KB?J)\.BN]O__BU4, +XMB47PBT7PA<")`G1[BWT4A?\/A:4```"+%HU+"#G*#X0&`0``BT8$B4($BT8$ +XM.<$/A!D!``")$(U3$(D6BT,4B48$.U,0#X3[````BT,4B3")SW]HG!,<#K$XUV`#M]['9/,2)1=2+1="+5=2%R70']]B#T@#WVH/$,%Y?7<.%]G4+N`$````QTO?VB<&+ +XM1>R)^O?QB<:+1?#W\8G!B?#KO`^]QX/P'XE%Z'5$.7WL=P4Y=?!RG+D!```` +XM,<#KGO==V(-5W`#W7=R%_\=%Y/____\/B4O___^0C70F`(GPB?KWV(/2`/?: +XM]U7DZ3/___^X(````(GR*T7HB<'3Z@^V3>B)1?2)^(G7BU7LT^`)QXM%\-/F +XM#[9-]-/H#[9-Z-/B#[9-]`G0BU7LB47,T^KW]XE5S(G']^8Y5'`@)````'5S86=E.B!E>"!;+65&4G)3F5= +XM(%MF:6QE("XN+ET*`````$5R7!E"@!L +XM:6YE]!`B`O00(Y;D$"*Z]!`AS +XM;7-O`')MC0@(`````&"<"`AHC0@(:XT( +XM"`````"#C0@(+_8("(F-"`@`````EHT("!+V"`B&ET('=I;&P@9&ES8V%R +XM9"!M;V1I9FEC871I;VYS`````#(V-'Q&:6QE(&UO9&EF:65D('-I;F-E(&QA +XM2!T:&%N('1H:7,@8V]P>0``,C4X?"5S +XM(&5X<&%N9&5D(&EN=&\@=&]O(&UA;GD@9FEL92!N86UE6]U`#(T,'PE +XMF4@979E;G0`,C@W?%5N97AP96-T960@=W)I=&4@979E;G0` +XM``"S"P4(]`L%",$,!0BS"P4(APP%"*0,!0@9#`4(LPL%"+,+!0@S#`4(30P% +XM"&H,!0C""P4(610%"&41!0B"$04(@A$%"%D4!0A9%`4(@A$%"$T4!0@P,3(S +XM-#4V-P`P,3(S-#4V-S@Y86)C9&5F````,#`X?$5R"]V:3H@`"5S)2XJ2!O;F4@=&%G(&9I;&4@;6%Y(&)E('-P96-I9FEE9"X`+7,@ +XM;W!T:6]N(&ES(&]N;'D@87!P;&EC86)L92!T;R!E>"X`@#,%"'$S!0CO,04( +XM[S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04(8C,%"%,S!0CO +XM,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q!0CO,04([S$%".\Q +XM!0CO,04([S$%".\Q!0@O,P4([S$%"!PS!0CO,04([S$%".\Q!0CO,04([S$% +XM".\Q!0@-,P4([S$%".\Q!0CO,04([S$%".\Q!0CZ,@4(\#(%",DR!0CO,04( +XMMC(%"*LR!0@P,3=\36%R:R`E&ES=',`,C8X?&-O;F9I2!K97D@=&\@8V]N=&EN=64Z(``R-S!\4')E2!T;R!C;VYT:6YU92!;.B!T;R!E;G1E2!K97D@=&\@8V]N=&EN=64@6W$@=&\@<75I=%TZ +XM(``P,S!\5&AE(&9I;&4@)7,@:7,@;F]T(&$@;65S3TEULJ/R1@)R)<`'-H:69T=VED=&@].`!S:61EA"`@``````P````````##]0@(`(4%"`(````(````+:$("``` +XM`````````````*>\"`@``````P`````````UH0@(````````````````0J$( +XM"``````"`````````$VA"`@```````````````">V@@(```````````````` +XM6*$("'"%!0@``````````&&A"`@``````P````````!GH0@(``````$````` +XM````;:$("````````````````'>A"`@``````@````````"`H0@(<(4%"``` +XM````````B*$("'"%!0@``````````).A"`@``````@````````";H0@(L'\% +XM"```````````7(P(".""!0@"````"````*6A"`BP@@4(``````@```!8O`@( +XML'\%"```````````L=X("``````!`````````*JA"`@``````0````````"P +XMH0@(``````(`````````NJ$("``````!`````````+^A"`@``````````!`` +XM``#(H0@($(8%"`,`````````SZ$("."%!0@#`````````-,$"0BP?P4(```` +XM``````#7H0@(X(4%"```````````T+D("``````!`````````-VA"`@````` +XM`0````````#FH0@(<((%"`,`````````(J$("``````#`````````-&A"`C@ +XMA04(`P````````#QH0@(``````$`````````AIL("(!_!0@``````@```/BA +XM"`@``````P````````#_H0@(````````````````!J(("``````!```````` +XM``RB"`@``````@`````````3H@@(````````````````8*(("``````"```` +XM`````!FB"`@````````````````DH@@(,((%"`,`````````+:(("``````` +XM````(````(3="`@``````P`````````TH@@(``````,`````````/J(("``` +XM```"````0````$FB"`@```````````````!3H@@(````````````````7*(( +XM"``````"````0````&>B"`@```````````````!PH@@(```````````0```` +XM>J(("+!_!0@"````0````(*B"`@``````@````````!@P0@(``````,````` +XM````,(L("``````#````"0```(RB"`@```````````````"2H@@(```````` +XM````````FJ(("``````!`````````**B"`BP@04(``````````"LH@@(```` +XM````````````M*(("-"`!0@"````#````+JB"`A`@04(`@````P```"_H@@( +XM8(`%"`(````,````Q:(("``````!`````````,JB"`C0?P4(`@````````#1 +XMH@@(````````````````W*(("``````"`````````.2B"`@``````@`````` +XM``#OH@@(``````$`````````^*(("``````````````````````````````` +XM```````!HP@(`0````FB"`@"`````Z(("`,````$HP@(!0````>C"`@(```` +XM^Z$("`H````*HP@(#0```!V<"`@+````^)@("`X````-HP@($@```).-"`@3 +XM````K:$("!4````0HP@(&````!.C"`@?````':,(""(````@HP@()0```"2C +XM"`@F````,:((""P```"TL0@(*@```"FC"`@P````+:,("#(```!>H`@(-``` +XM`#*C"`@Z````-Z,("#<````ZHP@(.````#ZC"`@V````/<$("#X```!!HP@( +XM/0```$2C"`A"````1Z,("#P```!?BP@(/P```$JC"`@_````&O<("$D```!2 +XMHP@(3@```%6C"`A)````6*,("$L```!;HP@(3````+^_"`A-```````````` +XM```P-#E\5&AE('-E8W1I;VX@;W!T:6]N(&UU2!0A8+79I+7)E8V]V97(M9FEL93H@`%@M=FDM +XM2!F:6QE`````$9R;VTZ(')O +XM;W0@*$YV:2!R96-O=F5R>2!P2X@```E2`O(&]R +XM(#\`!"$C)BH\/3Y`?@`P.#!\56YK;F]W;B!C;VUM86YD(&YA;64`,6)C83$` +XM,#DX?%1H92`E2!N +XM;W0@8F4@>F5R;P!L<@`P.#9\57-A9V4Z("5S`'-C2`E;'4@;&EN97,@:6X@=&AE(&9I;&4`,3`S +XM?$EL;&5G86P@861D"!M;V1E +XM`````#`X-'PE"!T86)L92!E"!C;VUM86YD(&9A:6QE9#H@<&5N9&EN9R!C;VUM86YDP@4(N,(%"%W'!0A\Q`4(?,0%"`7'!0A\ +XMQ`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0BOQ@4(_<<%")['!0B>QP4(GL<%")[' +XM!0B>QP4(GL<%")['!0B>QP4(GL<%")['!0A\Q`4(?,0%"'S$!0A\Q`4(?,0% +XM"-W%!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4( +XM?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\ +XMQ`4(?,0%"'S$!0A\Q`4(?,0%"'S$!0A\Q`4(9\8%".O+!0CLR@4([,H%".S* +XM!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H% +XM".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4(Z\L%".S*!0CLR@4( +XM[,H%".S*!0CXRP4([,H%".S*!0CLR@4([,H%".S*!0CLR@4(FLL%".S*!0CL +XMR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S*!0CLR@4([,H%".S* +XM!0CLR@4(H\L%".3>!0B#W@4(@]X%"-C$%"-C&-E<'0@870@=&AE(&5N9``R-S-\16YT97)I;F<@ +XM97@@:6YP=70@;6]D92X`,3$T?$YO(&9I;&4@;&ES="!T;R!D:7-P;&%Y`"5S +XM)7,E'!A;G-I;VX@9F%I +XM;&5D`"$E3H@)7,`&5C=71E(&$@8G5F9F5R`#P`2!L:6YE(&YU;6)E<@!S +XM:&EF="!L:6YE5T`8V]P>0!C'5S86=E`%ME>'5=')C +XM(&9I;&4`(69.`%ML:6YE72!O6W!E;ET@6R]212]=(%MF;&%G2!L:6YEF4@6RLM +XM77)O=W,`5T@;&EN92!;9FQA9W-= +XM``!C;W!Y(&QI;F5S(&5L2!B6W5F9F5R2!S970I(&9I;&4@;F%M +XM90``8G)I;F<@82!B86-K9W)O=6YD960@72!;=VEN +XM9&]W7W-I>F5=(%MF;&%G2!D:69F97)E;G0@,,( +XM")S#"`C3O`@(T$,&"`````#:O`@(W;P(",##"`@1"PD(L$8&"$(```!ZL0@( +XM[,,("/6\"`C.V`@(X$@&"`````#+P0@(),0("%S$"`@E!`D(D$L&"``!``!^ +XMO`@($+T(""N]"`CXF`@(D$L&"``!``!^O`@(1KT(""N]"`A=O0@(8!$'"``` +XM``#;OP@(9;T("(S$"`B;T("+#$"`B'O0@(L)$& +XM"``%``!^O`@(BKT("-C$"`B7O0@(P%X&"`0```#:O`@(",4("#S%"`B>O0@( +XM\!`'"`````!/C0@(H[T("*J]"`C!O0@(``(&"#$```#5V@@(R+T("-N]"`CV +XMO0@(4&@&"$(```#[O0@(<,4("`"^"`@2]@@(X'$&"`$```#+P0@('KX(""N^ +XM"`A8O`@(T(4&"((```#\O0@(G,4(",#%"`B#E`@(('4&"$(````O]@@(0+X( +XM".C%"`C3]`@(X'$&"`$```#+P0@(6[X(""N^"`@(H@@(`&\&"`````!MO@@( +XM<+X("`S&"`B&O@@(<'(&"`````"-O@@(DKX("*&^"`C)P`@(T`8&"``!``"T +XMO@@(.,8("%C&"`C3!`D(<(4&"((```#\O0@(A,8("*C&"`C0N0@(L'H&"`$` +XM``#;O`@(N+X(",C&"`C1H0@(((4&"((```#\O0@([,8("-6^"`CCO@@(P"H' +XM"#0"``#;O`@(Z+X("!#'"`CSO@@(P"H'"#0"``#;O`@(^KX("#S'"`@'OP@( +XMX'L&"`````!/C0@($+\("'3'"`@;OP@(H`4&"``!``#5V@@()+\(")S'"`AV +XMO`@(,(8&"'$```#_]`@(-;\("-#'"`A+OP@(T(8&"`````#5V@@(4+\("%J_ +XM"`@$V0@(L(D&"#$```#;O`@(9;\("/#'"`@KH`@(,'L&"`````"-O@@(@[\( +XM")._"`BHOP@(,)$&"``$``"OOP@(LK\(""#("`C"OP@(T`0&"`````#5V@@( +XMR;\("$3("`C5OP@(T`4'"``!``#:OP@(W[\("'3("`C;O`@(,-X&"`(```#; +XMO`@(F,@("-3("`C(L0@(\)P&"``"``!]O`@(];\("`C`"`B1F@@(L*4&"``` +XM```@P`@(^,@("#C)"`B$W0@(4*L&"``"``!/C0@((\`("&C)"`@KP`@(8+(& +XM"`````".O@@(,L`("$#`"`A]H@@(X+,&"``"``#5V@@(6\`("&7`"`A^P`@( +XMX+,&"``"``#5V@@(AL`("&7`"`C-H0@(@'D&"$(````9C0@(D\`(")S#"`@] +XMP0@(,/8&"``!``#:OP@(L<`("'3("`C&P`@(4/4&"`````#5V@@(SL`("-O` +XM"`CPP`@($.\&"`````#:OP@(]\`("(C)"`@3P0@(L0@(<-P&"`(```#;O`@( +XM7,P("(3,"`@```````````````````````````````!.;R!C0!A9&0`8W-C;W!E +XM+F]U=`!C&5C(&-S8V]P92`M9&P@+68@)7,`````,S$R?"5D.B!N;R!S=6-H(&-S +XM8V]P92!S97-S:6]N```E2!C7!E.B!U2!Y;W4@;W(@2!Y;W4````Q,S!\)7,Z(&YO="!S;W5R8V5D.B!W2!M87!P960`,3,T +XM?%1H92`E2!B92!R96%D```Q-#9\)7,Z(')E860@;&]C +XM:R!W87,@=6YA=F%I;&%B;&4````Q-#E\3F\@8F%C:V=R;W5N9"!S8W)E96YS +XM('1O(&1I&5C=71E`'!Q&ET960`0V]N=&EN=65D`$5- +XM5"!T'!IF4@;&EM:70@97AC965D960````````` +XM```````&````G]X("`X```"JW@@("@```+;>"`@4````P-X("!,```#-W@@( +XM!P```-?>"`@(````X-X("`$```#YW@@(!`````#?"`@=````%-\("`(````H +XMWP@(%P```#+?"`@&````/]\("`D```!(WP@(#0```$_?"`@;````6]\("`,` +XM``!SWP@("P```'C?"`@1````B]\("`P```">WP@(#P```*[?"`@%````N=\( +XM"!(```#(WP@(%0```-+?"`@6````YM\("!````#[WP@('@```!#@"`@?```` +XM)N`("!H````\X`@('````%+@"`@8````9N`("!D```!]X`@(,34R?'-H:69T +XM=VED=&@@;W!T:6]N('-E="!T;R`P`%)%(&5R+EM=)"H`,34S?$-O=6YT(&]V97)F;&]W`#$U-'Q#;W5N="!U;F1E +XM2!N +XM;W0@8F4@8V]M8FEN960@=VET:"!T:&4@8R!F;&%G(&EN('9I(&UO9&4`PL(& +XM"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8( +XM/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@C" +XMP@8(/<(&"#W"!@CXQ@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&".G& +XM!@@]P@8(VL8&"#W"!@@]P@8(6,8&"%C&!@A8Q@8(6,8&"%C&!@A8Q@8(6,8& +XM"%C&!@A8Q@8(6,8&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8( +XM/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@] +XMP@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W" +XM!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(/<(&"#W"!@@]P@8(+\8& +XM"#W"!@@]P@8(/<(&"!S&!@@]P@8(/<(&"#W"!@@]P@8(#<8&"#W"!@@]P@8( +XM/<(&"/[%!@@]P@8(FL(&"+_5!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZ +XMS@8(NLX&"+K.!@BCU08(H]4&"*/5!@BCU08(H]4&"*/5!@BCU08(H]4&"*/5 +XM!@BCU08(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX& +XM"+K.!@B-U08(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(&]8&"+K.!@BZS@8( +XMNLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(!=8&"+K.!@BZS@8(NLX&"+K.!@BZ +XMS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@BZS@8(NLX&"(W5 +XM!@BZS@8(NLX&"+K.!@BZS@8(NLX&"+K.!@@QU@8(NLX&"+K.!@BZS@8(NLX& +XM"+K.!@BZS@8(NLX&"+K.!@COU08(,38T?"5S.B!T:&4@=&%G)W,@;&EN92!N +XM=6UB97(@:7,@<&%S="!T:&4@96YD(&]F('1H92!F:6QE````,38V?"5S.B!S +XM96%R8V@@<&%T=&5R;B!N;W0@9F]U;F0`````,34Y?$QE2!A="!T:&4@;&%S +XM="!T86<@;V8@=&AI'5S86=E +XM(%MC;61=/$-2/B(*````1F]R(&$@=FD@:V5Y('5S86=E('-T871E;65N="!E +XM;G1E5T\0U(^(@H`````5&AE("5S(&ME>2!H87,@ +XM;F\@8W5R&ET+"!E;G1E0`Q-S1\57-A9V4Z("5S +XM`#$T-'PE2!F:6QE(&YA;65S```` +XM,C@S?%1H92`E"!T97)M:6YA;"!I +XM;G1E"!T97)M:6YA;"!I;G1E2!O9B!#86QI9F]R;FEA+"!" +XM97)K96QE>2X````Q-S5\5&AE('9IB5C`#(U +XM,WQ72!S8W)E96YS`%Y#`%MC;W5N=%U>1`!;8V]U;G1=7D4`7D4@2!C:&%R86-T97)S`%MC;W5N=%U>2@!>2B!M;W9E(&1O=VX@8GD@;&EN97,` +XM7DP`7DP@2!L:6YE2!L:6YE +XM4@!>4B!R961R87<@5@!>5B!I;G!U="!A(&QI +XM=&5R86P@8VAA"!M;V1E`%Y=`%Y= +XM('1A9R!P=7-H(&-U`%Y>('-W:71C:"!T;R!P&ET`%M;`%M;(&UO=F4@8F%C:R!S96-T:6]N`%U=(&UO=F4@ +XM9F]R=V%R9"!S96-T:6]N`"!>(&UO=F4@=&\@9FER2!C;VQU;6YS`&U;82UZ70`@;2!S970@;6%R:P`@;B!R97!E870@ +XM;&%S="!S96%R8V@`6V-O=6YT76\`(&\@87!P96YD(&%F=&5R(&QI;F4`6V)U +XM9F9EB!R97!O02!S96%R8V@@9F]R=V%R9"!F;W(@8W5R +XM0R!I;G1E2!L:6YE2!L:6YE2!L +XM:6YE2!T +XM97AT('1O(&UO=&EO;B!I;G1O(&$@8W5T(&)U9F9E<@````!;;&EN95UZ6W=I +XM;F1O=U]S:7IE75LM?"Y\*WQ>?#Q#4CY=```````````````````````````` +XM````````````H(,'"")`5`"H[0@(!/@(")![!P@@``0`LNT("+SM"`@````` +XM`````-3M"`@H^`@(<'T'""``!`#7[0@(8/@("-!Z!P@```0`X>T(".OM"`B` +XM?`<((``$``/N"`@-[@@(0)4'"``````G[@@(*NX("&!>!P@@`$0`.>X("$/N +XM"`@`````````````````````,'X'"!@`1`!>[@@(:.X("``````````````` +XM````````<@<(`````'[N"`B![@@(P'X'"$@`1`"2[@@(D/@("#!^!P@8`$0` +XMG.X("*;N"`@`````````````````````$'\'"!@`1`"\[@@(QNX("``````` +XM````````````````<@<(`````-KN"`C=[@@(`````````````````````!`] +XM!P@@0```[NX("/'N"`C0?0<((``$`/SN"`@&[P@(```````````B[P@()>\( +XM"-!Y!P@`````0N\("$7O"`@`````````````````````,'L'"```!`!<[P@( +XM9N\("*!!!P@````">N\("'WO"`@``````````(_O"`B\^`@(D$0'"`````"; +XM[P@(GN\("(!`!P@@0!``M.\("+?O"`B@0P<(`````,_O"`C2[P@(```````` +XM`````````````*!X!P@@`$0`[>\("/3X"`BP/@<((``L`ACY"`@\^0@(```` +XM`````````````````*!%!P@@``X`^.\("`?P"`A@=P<(@`!$`"7P"`@O\`@( +XMH&0'"")`1`!&\`@(2/`(""!#!P@`````/+L("%GP"`@P9`<(*`!#`'#P"`AD +XM^0@($)('"")`1`!X\`@(@?`("-".!P@B0$0`E_`("*#P"`@````````````` +XM````````,'X'"$@`1`"Y\`@(C/D("%`T!P@@`$0`PO`("+CY"`@0?P<(2`!$ +XM`,OP"`C<^0@(``````````!!\0@(U/`("/")!P@B@$``[_`("/WP"`@`7@<( +XM(`!``+BB"`@/\0@(```````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM````````````````````````````,#H'"``````J\0@(0_$("``U!P@@`$0` +XM4?$("`CZ"`B@0@<((``L`%KQ"`AP\0@(`````````````````````"!"!P@@ +XM`"P`CO$(""SZ"`@0B@<((H!``*3Q"`BR\0@(T"X'""``!`'%\0@(S?$("/!6 +XM!P@@``P`W_$(".CQ"`APZ0<((`!$`/[Q"`@'\@@(```````````<\@@(+?(( +XM"```````````1O(("%#R"`CP[`<((`!$`&GR"`AR\@@(4#$'""``1@",\@@( +XM3/H("%"`!PA(`$4`G_(("*CR"`@`@`<("`%%`+CR"`AT^@@(<%8'""``#`#! +XM\@@(G/H("'`]!P@@``P`RO(("-/R"`@`````````````````````8'\'"`@! +XM10#A\@@(ZO(("+!_!P@(`44`<(L("`/S"`B`A0<((H!``/:B"`@<\P@(X%T' +XM""``#``S\P@(//,("`!Q!P@@`(P`4?,("+SZ"`B01`<(`````%OS"`A=\P@( +XMX%,'""``#`!R\P@(>_,("```````````D?,("*+S"`A0,@<((`!&`,#S"`C@ +XM^@@(T.('""`````$[P@(T_,("```````````````````````\0<((`!$`._S +XM"`CX\P@((/$'""``C``0]`@(#/L("```````````(?0("#+T"`@@]P<(```` +XM`#_T"`A"]`@(,(H'""!`1`!8]`@(6_0("```````````````````````C`<( +XM($!$`(H&"0AP]`@(\%\'""``1``!P@@`$0` +XMJO4("+/U"`C`5`<((``,`,OU"`C4]0@(,'X'"!@`1`#L]0@(]?4("!!_!P@8 +XM`$0`"_8("!3V"`B@>`<((`!$`"CV"`@Q]@@(<&0'"````@!*]@@(4?8("%"% +XM!P@B@$``]J(("%WV"`C`70<((``,`'/V"`A\]@@(`'`'""``C`"1]@@(5/L( +XM"``````````````````````@<@<((``,`)OV"`BN]@@(8%('""``C`##]@@( +XMU/8(",`S!P@@`$8`[/8("'C["`A`X@<((````/R6"`C_]@@(```````````` +XM`````````.#P!P@@`$0`$_<("!SW"`@0\@<((`",`#'W"`A"]P@(0/,'""`` +XMK`!6]P@(I/L("&#T!PA```4`T/L("'3W"`@P:0<((D!$`(WW"`B6]P@(X%X' +XM""``1`"M]P@(MO<(",!K!P@B0$0`R/<("-'W"`@0X0<((``,`.OW"`CT]P@( +XM,S`W?$YO(&5X(&-O;6UA;F0@=&\@97AE8W5T90`Q.#!\3F\@<')E=FEO=7,@ +XM9FEL92!T;R!E9&ET````,C`W?%1H92!1(&-O;6UA;F0@/!P@HCP<(*(\'""B/!P@HCP<(=X\'""B/!PAWCP<(*(\'""B/ +XM!P@HCP<(*(\'"(*/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\' +XM""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(@H\'""B/!P@HCP<( +XM*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@H +XMCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/!P@HCP<(*(\'""B/ +XM!P@HCP<(*(\'""B/!P@HCP<(=X\'"#$Y-'Q.;R!M;W)E(&-H87)A8W1E\!PBJNP<(;ZP'"("[!PAOK`<(;ZP'"+^^!PA6O@<(;ZP'"$*_!PB_O@<( +XM/;X'"#V^!PAOK`<($[X'"(B]!PA@O0<(,KP'"%6[!PCYM`<(G+H'"(6Z!PB% +XMN@<(#K4'"/FT!PAIN@<(^;0'"/FT!PCYM`<(^;0'"$FZ!P@R,#%\0G5F9F5R +XM2!I;B!T:&4@9FER,'"#(P-GQ.;R!C:&%R86-T97)S('1O(&1E;&5T90#O]P<(,?@'""KX!P@J +XM^`<(0O@'"%7X!P@:^`<([_<'"._W!PCO]P<([_<'"/OW!PA5^`<($`@(""@( +XM"`@E#0@(YP0("$$-"`APX`<((``L`.D+"0C_"PD(,C,U?$YU;6)E2!I;B!C;VUM86YD(&UO9&4` +XM,C,V?$EN=&5R7,@9&ES8V%R9&5D`````#(S,7Q);G1E7,@9&ES8V%R9&5D```E9"!S8W)E96YS(&)A8VMG6]U'`@)````1L#.Z0!```!````]'C__\`!```````````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````````````````````````````$^-"`@`````+!()"``````` +XM`````````````````````0```%P````"````7@````,````$````!````!(` +XM```%````%`````8````:````!P```#H````(````#0````D````;````"@`` +XM``P````+````&`````P````*````#0```'T````.````*0````\````)```` +XM$`````@````1````%0```!(````1````$@```!8````3````%P```!0````P +XM```````````````````````````````````````````````5`````0```"]D +XM978O<'1Y6%@``"SS"`@``````````````````````````!0``````````7I2 +XM``%\"`$;#`0$B`$``!P````<````+'?__X)`$"`8```#XA00("@```-`$```+````$````!4``````````P```#02 +XM"0@"````B`0``!0````1````%P```!B7!`@1````N)8$"!(```!@````$P`` +XM``@```#^__]OF)8$"/___V\!````\/__;TB5!`@````````````````````` +XM``````````````````````````````````````````#_____`````/____\` +XM`````````%`1"0@``````````,J;!`C:FP0(ZIL$"/J;!`@*G`0(&IP$""J< +XM!`@ZG`0(2IP$"%JIP$"(J!`@:G@0(*IX$"#J>!`A* +XMG@0(6IX$"&J>!`AZG@0(BIX$")J>!`BJG@0(NIX$",J>!`C:G@0(ZIX$"/J> +XM!`@*GP0(&I\$""J?!`@ZGP0(2I\$"%J?!`AJGP0(>I\$"(J?!`B:GP0(JI\$ +XM"+J?!`C*GP0(VI\$".J?!`CZGP0("J`$"!J@!`@JH`0(.J`$"$J@!`A:H`0( +XM:J`$"'J@!`B*H`0(FJ`$"*J@!`BZH`0(RJ`$"-J@!`CJH`0(^J`$"`JA!`@: +XMH00(*J$$"#JA!`A*H00(6J$$"&JA!`AZH00(BJ$$")JA!`BJH00(NJ$$",JA +XM!`C:H00(ZJ$$"/JA!`@*H@0(&J($""JB!`@ZH@0(2J($"%JB!`AJH@0(>J($ +XM"(JB!`B:H@0(JJ($"+JB!`C*H@0(VJ($".JB!`CZH@0("J,$"!JC!`@JHP0( +XM.J,$"$JC!`A:HP0(:J,$"'JC!`B*HP0(FJ,$"*JC!`BZHP0(RJ,$"-JC!`CJ +XMHP0(^J,$"`JD!`@:I`0(*J0$"#JD!`A*I`0(6J0$"&JD!`AZI`0(BJ0$")JD +XM!`BJI`0(NJ0$",JD!`@``````````````````````````````````````"1& +XM'`@)``D1G)E94)31#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6YA +XM;6EC`"YC=&]R!```-`$```` +XM``````````$`````````-P```/___V\"````2)4$"$@5``!0`0``!``````` +XM```"`````@```$0```#^__]O`@```)B6!`B8%@``(`````4````!````!``` +XM``````!3````"0````(```"XE@0(N!8``&`````$``````````0````(```` +XM7`````D````"````&)<$"!@7``"(!```!`````L````$````"````&4````! +XM````!@```*";!`B@&P``$0``````````````!`````````!@`````0````8` +XM``"TFP0(M!L``"`)``````````````0````$````:P````$````&````X*0$ +XM".`D```\Y0,````````````0`````````'$````!````!@```!R*"`@<"@0` +XM#```````````````!`````````!W`````0````(```!`B@@(0`H$`"N%```` +XM`````````"``````````?P````$````"````;`\)"&R/!``4```````````` +XM```$`````````(T````!`````P`````0"0@`D`0`%`$`````````````(``` +XM``````"3`````0````(````4$0D(%)$$`#P```````````````0````````` +XMG0````8````#````4!$)"%"1!`#0````!0`````````$````"````*8````! +XM`````P```"`2"0@@D@0`"```````````````!`````````"M`````0````,` +XM```H$@D(*)($``@```````````````0`````````M`````$````#````,!() +XM"#"2!``$```````````````$`````````+D````!`````P```#02"0@TD@0` +XM4`(`````````````!`````0```"^````"`````,```"@%`D(H)0$`.`,```` +XM`````````"``````````PP````$``````````````*"4!`"I$0`````````` +XM```!``````````$````#``````````````!)I@0`S````````````````0`` +X%```````` +X` +Xend +END-of-vi.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.sh new file mode 100644 index 0000000000..6e5cb74004 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-4/strip-all-4.sh @@ -0,0 +1,6 @@ +# $Id: strip-all-4.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-all-4 tc/strip-all-4 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} vi" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-5/in/strip-all-5.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-5/in/strip-all-5.in.shar new file mode 100644 index 0000000000..7293a5b2b4 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-5/in/strip-all-5.in.shar @@ -0,0 +1,398 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# pkill.uu +# +echo x - pkill.uu +sed 's/^X//' >pkill.uu << 'END-of-pkill.uu' +Xbegin 755 pkill +XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```#T+@```````#0`(``& +XM`"@`&P`8``8````T````-(`$"#2`!`C`````P`````4````$`````P```/0` +XM``#T@`0(](`$"!4````5````!`````$````!``````````"`!`@`@`0(YBH` +XM`.8J```%`````!````$```#H*@``Z+H$".BZ!`C$`0``R`(```8`````$``` +XM`@````0K```$NP0(!+L$"-````#0````!@````0````$````#`$```R!!`@, +XM@00(&````!@````$````!````"]L:6)E>&5C+VQD+65L9BYS;RXQ``````@` +XM```$`````0```$9R965"4T0`%C4,`"4```!"`````````$`````%```````` +XM``D````W````$````"\````4````!P```"4````H````*P```"(````D```` +XM-``````````]````,````#D````;`````````#4````N````$@```#,````6 +XM````(0`````````_````*@```#(````8`````0`````````Q````00`````` +XM`````````````````````````````````````````@````8````````````` +XM````````````#0`````````````````````````+```````````````````` +XM```````````,```````````````9````'````````````````````!$````` +XM`````P```!H````.`````````",````$````'P````\`````````'@```"D` +XM```(````)P```!4````L`````````"8````=`````````!,`````````%P`` +XM`#8````X````+0```#L````*````(````#P````^````.@`````````````` +XM```````````P`0```````#0````2````ZP$```````!6`0``$@````T````$ +XMNP0(`````!$`\?\X`0`````````````2````S`$```````"A````$@```-$! +XM````````'0```!(```#;`````````&H````2````70$```````"_````$@`` +XM`*0!````````!0```!(````-`0```````,H````2````%@```(R+!`@````` +XM$@`*`%P$```````#*#``` +XM$@```-H!````````*P```!(```"Z```````````````2````$`(````````` +XM````$@```$\`````````M@```!(````@`0`````````````2````70`````` +XM````````(````.X`````````&````!(```#'`````````(0````2````<0`` +XM``````!J!```$@````!L:6)K=FTN@<```(`/`(```````"PO`0( +XM!1```#"]!`@%$@``-+T$"`47```XO00(!2(``#R]!`@%(P``0+T$"`4G``!$ +XMO00(!2@``$B]!`@%-0``3+T$"`4V``#TNP0(!P$``/B[!`@'`@``_+L$"`<$ +XM````O`0(!P4```2\!`@'!@``"+P$"`<'```,O`0(!P@``!"\!`@'"0``%+P$ +XM"`<*```8O`0(!PP``!R\!`@'#0``(+P$"`<.```DO`0(!Q$``"B\!`@'$P`` +XM++P$"`<5```PO`0(!Q8``#2\!`@'&```.+P$"`<9```\O`0(!QH``$"\!`@' +XM&P``1+P$"`<<``!(O`0(!QT``$R\!`@''P``4+P$"`<@``!4O`0(!R$``%B\ +XM!`@')```7+P$"`#_____)?B[!`AH +XM"````.G0_____R7\NP0(:!````#IP/____\E`+P$"&@8````Z;#_____)02\ +XM!`AH(````.F@_____R4(O`0(:"@```#ID/____\E#+P$"&@P````Z8#_____ +XM)1"\!`AH.````.EP_____R44O`0(:$````#I8/____\E&+P$"&A(````Z5#_ +XM____)1R\!`AH4````.E`_____R4@O`0(:%@```#I,/____\E)+P$"&A@```` +XMZ2#_____)2B\!`AH:````.D0_____R4LO`0(:'````#I`/____\E,+P$"&AX +XM````Z?#^____)32\!`AH@````.G@_O___R4XO`0(:(@```#IT/[___\E/+P$ +XM"&B0````Z<#^____)4"\!`AHF````.FP_O___R5$O`0(:*````#IH/[___\E +XM2+P$"&BH````Z9#^____)4R\!`AHL````.F`_O___R50O`0(:+@```#I+P$"&@(`0``Z=#]____)7R\!`AH$`$``.G`_?___R6` +XMO`0(:!@!``#IL/W___\EA+P$"&@@`0``Z:#]____)8B\!`AH*`$``.F0_?__ +XM_R6,O`0(:#`!``#I@/W___\ED+P$"&@X`0``Z7#]____)92\!`AH0`$``.E@ +XM_?___R68O`0(:$@!``#I4/W___\EG+P$"&A0`0``Z4#]____):"\!`AH6`$` +XM`.DP_?___R6DO`0(:&`!``#I(/W___\EJ+P$"&AH`0``Z1#]__]5B>564X/L +XM$(/D\(M=!(G1C72=#(7;B36LO00(?C:+10B%P'0OH^BZ!`@/MA"$TG0C@\`! +XMZPH/MA"#P`&$TG04@/HO=?&CZ+H$"`^V$(/``832=>RX!+L$"(7`=#2)#"3H +XM&____\<$)(RE!`CH#____^B&_/__C44(B70D"(E$)`2)'"3HEP0``(D$).A_ +XM_O__Z/K\___KS9"0D)"0D)"058GE@^P(@#U0O00(`'0,ZQR#P`2C\+H$"/_2 +XMH?"Z!`B+$(72=>O&!5"]!`@!R<.058GE@^P(H>2[!`B%P'02N`````"%P'0) +XMQP0DY+L$"/_0R<.0D)"0D)"0D)"0D)"058GE4[OBI00(@^P4H8"]!`B%P'4% +XMN_JE!`CHL?[__XE<)`S'1"0$#*@$"(E$)`BA2+T$"(D$).CD^___QP0D`@`` +XM`.C(_?__D(VT)@````!5B>575KX!````4X'LG`0``(F%=/O__XF5%?/O__Q"F!`B-=@"-E8#[___'1"0$V:8$"(D4).@J_?__A<")PP^$ +XM@`(``(`[``^$BP```,<$)`@```#H:_W__X7`B85L^___#X1P`@``BY5T^___ +XMB[UL^___BP*)!XU%\(DZQT0D"`````")1"0$B1PDZ$3\__^)1P2)PHM%\(`X +XM`'4?@[UP^___!`^$.@$``'%>/O__W"F!`@/E\(/DL`XP@^%R0```(N5?/O_ +XM_XV]D/O__XN%>/O__\=$)`B!I@0(QT0D!``$``")5"0,B40D$(D\).C(^O__ +XMC460B40D!(D\).@Y^O__@\`!#X3R````]D69(`^$"@$``(M%I#'VBY5L^___ +XMB4($Z9/]__^XP*8$"+D$````_(G>B7UW#QT0D"`@```#'1"0$ +XM%J8$",<$)`,```#HX?K__[A]I@0(N0,```")G7C[__^)WHG'\Z8/A!O____' +XMA7S[__]XI@0(Z0S___^)7"0(QT0D!$:F!`C'!"0"````Z"[Y__^)7"0(QT0D +XM!#"F!`C'!"0"````Z!;Y__^)7"0(QT0D!%BF!`C'!"0"````Z/[X___H>?G_ +XM_X,X`G4PB5PD",=$)`2&I@0(QP0D`@```.C<^/__B5PD",=$)`2KI@0(QP0D +XM`@```.C$^/__B5PD",=$)`28I@0(QP0D`P```.@<^O__C;8`````C;\````` +XMC4PD!(/D\/]Q_%6)Y5>_VZ8$"%9348'LJ`P``(L9BTD$QT0D!+^G!`C'!"0` +XM````B8UP\___Z.7Y___H%=//__P`````Q]L>%>//__^6F!`C'A7SS___EI@0(QX6` +XM\___`````,>%B//__P````"+E7#S___'1"0(L*@$"(D<)(E4)`3H'OC__X/X +XM_P^$I`(``(/H1(/X-'8%Z!C[____)(7(J00(QP6FY_?__BX5P\___BY5P\___@\`$@_L!B86T\___BW($QX6, +XM\___X*,$"`^.6OW__X`^+0^%4?W__XU%[(U^`<=$)`@*````B40D!(D\).CC +XM]?__B<*+1>R`.``/A5<&``"+C;3S__^#ZP&)%?2Z!`C'A8SS___@HP0(B8UP +XM\___Z07]__^+/4R]!`@I^XF=O//__P^$'0$``(L=A+T$"(7;#X7M````BY5T +XM\___A=(/A%X!``"+C73S___'1"0$[Z8$"(D,).CK]?__A<")PP^$DPH``(N% +XMB//__X7`=#>A,+T$"(7`#X5[!@``#[]##L=$)`0&````B00DZ+;T__^%P`^$ +XM.@H``.@Y]?__@S@C#X6."@``C;7(^___B5PD",=$)`0`!```B30DZ*;T__^% +XMP`^$E@```(D<).@6]O__C47HQT0D"`H```")1"0$B30DZ-_T__^)P8M%Z`^V +XM`(3`#X0?!0``#[;0.Q4XO00(#XP`!0``BXUT\___QT0D!%:G!`C'!"0#```` +XMB4PD".@R]/__BPV(O00(A,'```/OT,,P>@%@^`! +XMA,`/A"\)``")'"3H8?7__XN%=//__\=$)`1`IP0(QP0D`P```(E$)`CHL_/_ +XM_XN%B//__\>%A//_______^%P`^%F@@``.AF]?__BXU\\___C97(\___B50D +XM$,=$)`P`````QT0D"`````")3"0$HZB]!`B+A7CS__^)!"3H3_7__X7`HZ2] +XM!`@/A(H(``#'1"0,?+T$",=$)`@`````QT0D!`@```")!"3H8O7__X7`HW2] +XM!`@/A#@(``"A?+T$"(D$).AX]/__A<")PJ-XO00(#X0%"0``BXUP\___H7R] +XM!`B)%"3'1"0$`````(T\N8F]N//__XE$)`CH0?/__XN%N//__XL0A=(/A&X" +XM``"A_+H$"(E4)`2-5=B)%"2)1"0(Z>__^%P`^%AP4``*%\O00(BSUTO00( +XMA<`/CAD"``#'A9SS__\`````ZV&)]O:'*`$```1T:HNU@//__X7V?BV-AV\! +XM``")1"00BX>(````B50D",=$)`2JIP0(B40D#*%(O00(B00DZ+#Q__^#A9SS +XM__\!BX6<\___.05\O00(#XZR`0``@<<``P``BU+E83S__^%TG@(.86$\___=:2A7+T$"(7`#X0=`0``BY.,````.U`$=1/I +XM#0$``)"-="8`.5`$#X3_````BP"%P(UV`'7NBY68\___QD0Z_P"+-7R]!`CI +XM:____XD<).A0\?__,T70"T74#X6D_?__H7B]!`B+E9SS___&!`(!Z9#]__^A +XM1+T$"/9$D#5`#X3P^O__C4'[/9J&`0")C83S__\/AI'[__^+A73S___'1"0$ +XM5J<$",<$)`,```")1"0(Z`[O___'1"0(`P```,=$)`3AI@0(B3PDZ-;N__^% +XMP'4#C7X$O@$```#K#(/&`8/^(`^$<0,``(L$M;"\!`B)?"0$B00DZ(GN__^% +XMP'7=@_X@#X11`P``BX6T\___@^L!B37TN@0(QX6,\___X*,$"(F%%E//__P````")C:SS__\QR>L_BX6L\___AN/C8W(\___C578B4PD"(E4)`3'1"0,``@``(D$).AY[/__BY6X +XM\___C8W(\___B4PD#(L"QT0D!'"I!`C'!"0"````B40D".C?[/__BX6H\___ +XMBX`8`0``B85L\___Z2W___^)="0(QT0D!`````")'"3H%.W__X/__W0)H7B] +XM!`C&!#@!BQ5\O00(N`$```"+'72]!`B%TGYG,?8Q_^LFBPV0O00(ANP,<"%_P^4P(D$).AR +XM[?__BX6H\___BY60\___.Y`<`0``#YS`Z<[^__^)'"3HL.O__X7`#Y7`Z17X +XM__^A8+T$"(7`="*+4S`[4`1U"NL8C78`.5`$=!"+`(7`=?60C70F`.E6_?__ +XMH6R]!`B%P'48B?;K)3E31'0@BP"%P)"-="8`#X2,^___BU`$@_K_=>3V@R@! +XM```"==NA:+T$"(7`=#6+4S@[4`1U#>LKC;8`````.5`$=""+`(7`=?60C70F +XM`.G=^___QX6,\___X*,$")#I'_/__XL59+T$"(72="R+BP`"``"+0@0YP746 +XMZQV)]HL2A=(/A,'\__^+0@0YR)!T"87)?NJ#P`%UY8N%O//__X7`#X4*^___ +XMBX68\___QD0X_P&+-7R]!`CI]/K__\=$)`0@J00(QP0D`P```.CMZO__H:2] +XM!`B)!"3H<.O__\=$)`2-IP0(QP0D`P```(E$)`CHR.K__XV5R//__XE4)`C' +XM1"0$;Z<$",<$)`,```#HJNK__XD<).@R[/__BY5T\___QT0D!`"I!`C'!"0# +XM````B50D".CTZ___B1PDZ`SL__^+E73S___'1"0$"J<$",<$)`,```")5"0( +XMZ%[J__^+A73S___'1"0$\:8$",<$)`,```")1"0(Z+#K__^A>+T$"(ET)`C' +XM1"0$`````(D$).B'ZO__Z7S]__^+C73S___'1"0$(J<$",<$)`,```")3"0( +XMZ`3J__^A?+T$",=$)`1(J00(QP0D`P```(E$)`CH5^O__XVT)@````!5B>56 +XMB<93@^P0H92]!`B%P'4-BQV`O00(A=MU0XUV`(L-F+T$"(7)=5:AE+T$"(7` +XM="2-AF\!``")1"0(BT8HQP0DZ:<$"(E$)`3H0.K__X/$$%M>7<.A@+T$"(7` +XM=-.+1BC'!"0'J`0(B40D!.@=ZO__@\006UY=PXVV`````*&DO00(QT0D"``` +XM``")="0$B00DZ&?J__^%P(G#=(N+1BC'!"3EIP0(B40D!.C>Z?__BP.%P'28 +XM@\,$B40D!,<$).RG!`CHQ>G__XL3A=)TX:$PO00(A#.+`L8`((/``8D"BP.%P'6[Z4[___^A0+T$",<$)"````")1"0$ +XMZ%GH___KF8VT)@`````[0AA]R(E4)`3'!"0@````Z-OI___I>/___XVV```` +XM`%6)Y8/L"(M%".BR_O__H?BZ!`C'!"3LIP0(B40D!.@MZ?__N`$```#)PXVV +XM`````%6)Y593@^P0H8R]!`B+=0B%P`^$N````,<$).^G!`CH_.C__XGPZ&7^ +XM___'!"3UIP0(Z.GH__^A0+T$"(D$).A,Z/__H3"]!`B%P`^%^````*$\O00( +XMBU`$@^H!A=*)4`0/B/8```"+%3R]!`B+`@^V&(/``8D"B=F-M"8`````@_D* +XM=#N#P0%T-J$PO00(A70+@_M9=1^-M@````"A]+H$"(E$)`2+1BB) +XM!"3H#.?__X/``70VN@$```"#Q!")T%M>7<.A/+T$"(D$).B,Z?__B<'I=?__ +XM_Z$\O00(B00DZ/CH__^)P>EA____Z,SG__\QTH,X`W3#BT8HQP0D^*<$"(E$ +XM)`3H`NC__X/$$#'26XG07EW#H3R]!`B)!"3H.NG__XG#Z1K___^A/+T$"(D$ +XM).BFZ/__B'`@)`!;+4Q39FEL;F]V>%T@6RUD(&1E;&EM +XM70!;+7-I9VYA;%T@6RU)3&9I;F]V>%T`+V1E=B\`0V%N;F]T(&%L;&]C871E +XM("5Z=2!B>71E0`E0!);G9A;&ED('!I +XM9"!I;B!F:6QE(&`E7-T +XM96U="B`@("`@("`@("`@("!;+5`@<'!I9%T@6RU5('5I9%T@6RUG('!G'!R97-S:6]N(&`E'`@ +XM)````+^G!`@`````X+L$"`\```"^IP0(`0`````````!`````0````$```!^ +XM````#````(R+!`@-````C*4$"`0````D@00(!0```.B&!`@&````R(($"`H` +XM``!%`@``"P```!`````5``````````,```#HNP0(`@```'`!```4````$0`` +XM`!<````'`@)``D1G)E94)3 +XM1#H@'`@)`!'0T,Z("A'3E4I(#0N,BXQ(#(P,#

6%R($5X<"`D`$=#0SH@*$=. +XM52D@-"XR+C$@,C`P-S`W,3D@(%M&6YS +XM='(`+F=N=2YV97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R`$``````````````0`````````1`````P``````````````)"X``,X````` +XM``````````$``````````0````(``````````````"PS``!@"0``&@```%(` +XM```$````$`````D````#``````````````",/```9@8``````````````0`` +XM`````````````````````````````````/2`!`@``````P`!```````,@00( +XM``````,``@``````)($$"``````#``,``````,B"!`@``````P`$``````#H +XMA@0(``````,`!0``````+HD$"``````#``8``````+2)!`@``````P`'```` +XM``#4B00(``````,`"```````'(H$"``````#``D``````(R+!`@``````P`* +XM``````"@BP0(``````,`"P``````D(X$"``````#``P``````(RE!`@````` +XM`P`-``````"8I00(``````,`#@``````Z+H$"``````#``\```````"[!`@` +XM`````P`0```````$NP0(``````,`$0``````U+L$"``````#`!(``````-R[ +XM!`@``````P`3``````#DNP0(``````,`%```````Z+L$"``````#`!4````` +XM`*R\!`@``````P`6``````````````````,`%P`````````````````#`!@` +XM`````````````````P`9``````````````````,`&@`!```````````````$ +XM`/'_"`````R!!`@8`````0`"``\```````````````0`\?\P```````````` +XM```$`/'_/P``````````````!`#Q_P\```````````````0`\?]*```````` +XM```````$`/'_50```-2[!`@``````0`2`&,```#````Y+L$"``````!`!0`Z@```&"E!`@``````@`,```!```````` +XM``````0`\?\P```````````````$`/'_/P``````````````!`#Q_P`!```` +XM``````````0`\?\A`0`````````````$`/'_*0$``)"/!`A(`````@`,`"\! +XM``"`O00(!`````$`%@`U`0``X(\$",0#```"``P`/@$``*B]!`@$`````0`6 +XM`$0!``"PHP0(*@````(`#`!,`0``G+T$"`0````!`!8`5@$``)"]!`@$```` +XM`0`6`%X!``!PO00(!`````$`%@!G`0``;+T$"`0````!`!8`<`$``&B]!`@$ +XM`````0`6`'@!``"(O00(!`````$`%@!_`0``A+T$"`0````!`!8`A@$``)2] +XM!`@$`````0`6`(X!``!DO00(!`````$`%@"6`0``_+H$"`0````!``\`G0$` +XM`&"]!`@$`````0`6`*8!``"8O00(!`````$`%@"P`0``^+H$"`0````!``\` +XMM@$``%R]!`@$`````0`6`+\!``"@O00(!`````$`%@#(`0``6+T$"`0````! +XM`!8`T0$``(R]!`@$`````0`6`-T!``!4O00(!`````$`%@#F`0``X*,$"'$! +XM```"``P`[@$``/2Z!`@$`````0`/`/4!``"DO00(!`````$`%@#X`0``?+T$ +XM"`0````!`!8`_@$``'2]!`@$`````0`6``0"``!XO00(!`````$`%@`-`@`` +XM<*($"#H!```"``P`&@(````````T````$@```"P"````````5@$``!(````_ +XM`@``!+L$"``````1`/'_2`(`````````````$@```%<"````````H0```!(` +XM``!F`@```````!T````2````>0(```````!J````$@```(@"``#LN@0(```` +XM`!$"#P"5`@```````+\````2````J@(````````%````$@```+X"```````` +XMR@```!(```#4`@``C(L$"``````2``H`V@(`````````````$@```.H"```` +XM````+@```!(```#Y`@```````)(!```2````"0,``*R]!`@$````$0`6`!$# +XM``"PO`0(@````!$`%@`G`P```````)`````2````.`,``#"]!`@$````$0`6 +XM`$\#````````90(``!(```!@`P``Z+H$"`0````1``\`:P,``)".!`B8```` +XM$@`,`'(#`````````````!(```"!`P```````%(7```2````DP,``#2]!`@$ +XM````$0`6`*0#`````````````!(```"U`P```````!T"```2````Q@,````` +XM```6````$@```-@#````````"P```!(```#C`P```````!T````2````]@,` +XM```````Y````$@````<$``"LO`0(`````!``\?\3!```L),$"+D.```2``P` +XM&`0```````#?````$@```"L$````````00```!(````Z!``````````````2 +XM````2P0``#B]!`@$````$0`6`&,$```\O00(!````!$`%@!V!````````-,` +XM```2````A@0```````!?````$@```)<$``",I00(`````!(`#0"=!```0+T$ +XM"`0````1`!8`L00``$2]!`@$````$0`6`,X$````````8@```!(```#?!``` +XM`````"8"```2````ZP0```````#+````$@```/T$````````^@```!(````/ +XM!0```````$,````2````'@4```````##````$@```"\%````````/@```!(` +XM```]!0``K+P$"``````0`/'_1`4``.B[!`@`````$0#Q_UH%``"PO00(```` +XM`!``\?]?!0```````&(#```2````&5C0$!&0E-$7S$N,`!O<'1Amcs.o.uu << 'END-of-mcs.o.uu' +Xbegin 644 mcs.o +XM?T5,1@$!`0D```````````$``P`!``````````````!\"0```````#0````` +XM`"@`"@`'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ +XM,=*%P'0),=*#>"``#Y7"R8G0PXUV`%6)Y8/L&(E4)`3'1"0(`````(D$).C\ +XM____,=*%P'0),=*#>!@`#Y7"R8G0PXUV`%6)Y8/L&,=$)`@`````B50D!(D$ +XM).C\____A575E.![/P```#'A1#___\`````QX44____`````(N%$/___XM5"(E$)`2+ +XM0AB)!"3H_/___X7`B840____#X0Z!@``BY40____C46TB40D!(D4).C\____ +XMA<`/A$D&``"+30B+1;2+24")A0S___^)C0C___^+C13___^%R0^%?P(``(M5 +XMS(F5%/___XM%N(/X"'2)A"C`````````#'@H@````` +XM`@``QP0D``(``.C\____BTT(A<")@80````/A$<%``"+A2C___^+E2C___^+ +XM0`B)A3#___\#0A0YA3#___^)A2#___\/@M$```#IZ0$``(M%"(NXC````(M- +XM"(N1B````(N-'/___XT$#SG0%6/___P````")1"0$B10DB8U4 +XM____Z/S___^%P`^$HO[__XN5)/___XM%".B"^O__A6UT86(`+G-T``!4!P```A8``%P'```!"```;`<` +XM``(7``!T!P```0@``(`'```"'@``C`<```(6``"4!P```0@``*0'```"%P`` +XML`<```(6``"X!P```0@``,@'```"%P``T`<```(6``#8!P```0@``.@'```" +X;%P``\`<```(6``#X!P```0@```@(```"%P`` +X` +Xend +END-of-mcs.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.sh new file mode 100644 index 0000000000..53992c2644 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-6/strip-all-6.sh @@ -0,0 +1,6 @@ +# $Id: strip-all-6.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-all-6 tc/strip-all-6 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -o mcs.o.1 mcs.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/in/strip-all-7.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/in/strip-all-7.in.shar new file mode 100644 index 0000000000..565fd43ce1 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/in/strip-all-7.in.shar @@ -0,0 +1,262 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# sections.o.uu +# +echo x - sections.o.uu +sed 's/^X//' >sections.o.uu << 'END-of-sections.o.uu' +Xbegin 644 sections.o +XM?T5,1@$!`0D```````````$``P`!``````````````!X'````````#0````` +XM`"@`"P`(`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R +XM''<%.T$07@`````BT80BU84QT6X +XM`P```,=%O`````")1`````` +XMQT7<`````(M&"(D$).C\____A<")PP^$Z@```/9'3!`/A(\```"+1AB+5AR) +XM1=2-1;2)5=B)1"0$BT8(B00DZ/S___^%P`^$W@```,<#`0```,=#!`````"+ +XM1@R)0PB+1AB+5AS'0PP`````QT,0`````(E#%(E3&,=#'`$```#'0R`!```` +XMBT8(B00DZ/S___^)1"0$BT<8B00DZ/S___^%P`^$I0```(/$3%M>7UW#C70F +XM`(M&&(M6'(M.#(/`\(/2_XE&&(E6'(E$)`B-01")1"0$B0PDZ/S____I1/__ +XM_\<$)/_____H_/___\=$)`0`````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0>````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0W +XM````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`15````QP0D1@`` +XM`(E$)`CH_/___XUV`%6)Y5=64X/L3(MU"(M>?(7;='>-?;2)?"0$BT,(B00D +XMZ/S___^%P'1[BP.)1"0$BT9$B00DZ/S___^+5=R%THE%M'0LBT9\A7UW#QT7<`````.O,QP0D +XM_____^C\____QT0D!'(```#'!"1&````B40D".C\____QP0D_____^C\____ +XMQT0D!#<```#'!"1&````B40D".C\____B00DZ/S____'1"0$C@```,<$)$8` +XM``")1"0(Z/S___^-="8`58GE@^P8B77\B=:)7?B+6$2+0PR%P'08B70D!(D< +XM).C\____BUWXBW7\B>Q=PXGVQT0D!*4```")'"3H_/___\=$)`2F````B1PD +XMZ/S____'1"0$K@```(D<).C\____QT0D!+8```")'"3H_/___^NFC;0F```` +XM`(V\)P````!5B>575E.#[$R+10B+6'R%VW4)ZQB+6TB%VW01BS.Y"@```+^V +XM````_/.F=>B+50B+0B)64B)04R+0TR)"(U!2(E#3(D\).C\____A<")P@^$Q@```,<``0```,=` +XM!`````#'0`P`````QT`0`````(M&!(E""(M&",="&`````#'0AP!````QT(@ +XM`0```(E"%(U5M(E4)`2)/"3H_/___X7`#X27````QT6X`0```(M%"(L6Z$O^ +XM__^-1;2)1"0$B3PDZ/S___^%P`^$DP```(MV#(7V#X7I_O__@\1,6UY?7````QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`3E````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0W````QP0D1@```(E$)`CH_/___XVV`````(V\)P````!5B>56 +XM4X/L$(MU"(M>1(7;=`>+3@R%R71U,=OK4XUV`(M&"(D$).C\____A<")P0^$ +XMG0```(M61(72=5F+`XM3!(D!BT,,B5$$BU,0B4$,BT,(B5$0BU,8B4$(BT,< +XMB4$7564X'LD````(MU$(U%N(E$)`2+10R)!"3H_/__ +XM_X7`#X2E````C9UX____B5PD!(DT).C\____A<`/A*\```"+1;B+512)A7C_ +XM__^+1;R)A7S___^+1<")18"+1<2)182+1")1:"+1>2)1:2+1>B)1:B+1>R)1:R+1?")1;"+ +XM1?2)1;2+10CHG?O__XE<)`2)-"3H_/___X7`=%*!Q)````!;7EW#QP0D____ +XM_^C\____QT0D!!P!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D +XM!#H!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D!%@!``#'!"1& +XM````B40D".C\____C;0F`````%6)Y5=64X/L?(M%"(MX?(7_#X0N`0``QT6H +XM`````,=%K`````#I_````(VV`````(MW%#MUK(M?$`^"$0$``'<).UVH#X(& +XM`0``BT<\A<"0=4^+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2) +XM5"0$Z/S___^)59R+39R)19@/K\8/K\L!P8M%F/?CC301B4<0B7<4BUVHBW6L +XMBT=`A<`/A88```"+5S"+3S2)T(/P"`G(=!*)R`G0=`R+7Q"+=Q0#7Q@3=QR- +XM5;")5"0$BT<(B00DZ/S___^%P`^$P0```(M'$(M7%(E%R(E5S(M'&(M7'(E% +XMT(U%L(E5U(E$)`2+1PB)!"3H_/___X7`#X2S````BW](A?]T)8E=J(EUK(M% +XMK`M%J`^%_O[__XM?$(MW%`-?&!-W'(M_2(7_==N#Q'Q;7E]=PXUV`(M'/(7` +XM=4.+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2)5"0$Z/S___^) +XM592+392)19`/K\8/K\L!P8M%D.GV_O__QP0D`````.C\____ZZ_'!"3_____ +XMZ/S____'1"0$564X/L4(MU"(U%N(E$)`2+1A2)!"3H +XM_/___X7`#X2G````QT0D!%@```#'!"0!````Z/S___^%P(G##X31````BT7@ +XMBU7DB4,0B5,4BT9\N@$```"%P'06,-*-=@"#>$`!BT!(@](`A7LCBULLA=MT'(L#B30D +XMB40D!.C\____A!@`#Y7"R8G0PXUV`%6)Y8/L&,=$ +XM)`@`````B50D!(D$).C\____A575E.#[&S'1"0$6````,<$)`$```#H_/___XM5"(7` +XMB4)$#X1S`P``QP"V````QT`$`````,=`&`````#'0!P`````QT`H`0```,=` +XM+`````#'0#P`````QT`P`P```,=`-`````"+50B-1?")1"0$BT(4B00DZ/S_ +XM__^%P`^$+`,``,=%H`````#I$0$``(MUG+^F````N0@```#SI@^%K@$``(M% +XM"(-X2`$/A.\```#'1"0$6````,<$)`$```#H_/___X7`#X3.`@``B<.+19R) +XM`XM5H(E3!(M%R(M5S(E#$(E3%(M%T(M5U(E#&(E3'(M%X(M5Y(E#*(E3+(M% +XMM,=#-`````")0S"+50B)7"0$B10DZ/S___^)0SR+50B+0AB)!"3H_/___X7` +XMB4,(#X0=`@``BT6@B00DZ/S___^%P(E#.`^$*P(``(MUG+D*````O[8```#\ +XM\Z8/A_^__^+`XM5"(E$)`R+0PB) +XM1"0(BT,$B10DB40D!.C\____Z1#___^+=9R_K@```+D(````\Z8/A#W^__^+ +XM50B+0C2%P'4+BT(XA<`/A#7^__^+50B+19S'1"0(`````(D4)(E$)`3H_/__ +XM_XM5"(MZ-(7_=`^%P'0+BW`DA?8/A?'^__^+50B+6CB%VW03A<`/A-_^__^+ +XM2!R%R0^$U/[__XMUG+D*````O[8```#\\Z8/DL`/E\(HP@^^PH7`#X0H____ +XMZ;W]___H_/___X7`B?8/A=````"#Q&Q;7E]=P\<$)/_____H_/___\=$)`3^ +XM`0``QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0:`@``QP0D1@`` +XM`(E$)`CH_/___\<$)/_____H_/___\=$)`0P`@``QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`1&`@``QP0D1@```(E$)`CH_/___\=$)`2K`0`` +XMQP0D1@```.C\____QP0D_____^C\____QT0D!.,!``#'!"1&````B40D".C\ +XM____B00DZ/S____'1"0$C@```,<$)$8```")1"0(Z/S___^-=@"-O"<````` +XM58GE5U93C3P0@^P,.?AS;8G#ZS&A`````(7`=6B+%0````"+0@B#Z`&%P(E" +XM"`^(GP```(L"Q@`*@\`!B0*#PP$Y^W0X#[83A-)TR*$`````A$N+`8GR@\,!B!"#P`$Y^XD!=R,````BT4(BT!\A<")18!T5XU5Y(F5 +XM?/___^L-BTV`BTE(AF+&;^F````N0@```#\B=[S +XMIG4MBUT(]D-,0'7-B1PDZ/S___^#2TQ`BTV`BTE(A +XM7UW#OZX```"Y"````(G>\Z9TP_R_M@```+D*````B=[SIG2(BT4(@WA(`0^$ +XMF````(M%"(G:Z!WZ__^%P`^$-@,``#';QT60`````,=%H`````#K08UV`(M% +XMH`-#%(D$).C\____B460BW60A?8/A/0#``"+4PB+0Q2+39`#3:")5"0$B40D +XM"(D,).C\____BU,4`56@BTV`B5PD!(M!!(D$).C\____A<")PP^$EP```(M] +XMD(7_=9^+0Q2)!"3H_/___XE%D.N@BU6`BT(P@_`)"T(T#X56____C4VDB4PD +XM!(M"!(D$).C\____A<`/A+P%``"+70CV0TP0#X64`P``BT-\AC^___H_/___X7`#X5P!```BTV0A_S__XM=@(M%"(L3Z!KW__^%P`^$,O___^DA_O__BUV0BT64B7PD"(E< +XM)`2)!"3H_/___XM5H(M-G(T$%\8$"`"#P`&)1:#IO?[__XM%"(G:Z*7V__^% +XMP`^$[?[__^FS_/__D(VT)@````#H^_K__^E<____BU60BT6<`T6@B7PD"(E4 +XM)`2)!"3H_/___P%]H.F)_O__BU6`BTT(QT0D"`````"+`HD,)(E$)`3H_/__ +XM_XMP#(DT).C\____B70D!(G#B40D"(M%G`-%H(D$).C\____BT6<`UV@Q@0# +XM`(/#`8E=H.E*_O__BU6@BTV0BUVD< +XM_?__QT0D!($"``#'!"1&````Z/S___^A`````,<$)`H```")1"0$Z/S____I +XM%OO__XM-"(M%S(M1/#M".'0IBT6`BQCI@_O__XE4)`3'!"0*````Z/S____I +XMZ?K__XM-@(L9Z63[__\Q_\=%B`````#'180`````BUV$BU6`B5PD!(M"!(D$ +XM).C\____A<")180/A$4!``"+182-7>2)7"0(QT0D!`````")!"3H_/___SN% +XM?/___P^%^P```(M5"(M=\(M"0(M`!(D$).C\____BTT(B5PD"(E$)`2+012) +XM!"3H_/___X7`#X2E````BUT(B40D!(D<).C\____A<`/A''___^#>Q`!=#+' +XM!"1`````Z/S___^%P'1DB46(BU7HBTV(BT7DB5$$BU7PB0&+1>R)40R)00CI +XM.?___\<$)"````#H_/___X7`=#*)QXM%Y(D'BT7LB4<$Z1?___^)!"3H_/__ +XM_\=$)`0#`0``QP0D1@```(E$)`CH_/___\=$)`1S`@``QP0D1@```.C\____ +XMQP0D_____^C\____QT0D!!H"``#'!"1&````B40D".C\____QP0D_____^C\ +XM____QT0D!%P"``#'!"1&````B40D".C\____Z/S___^%P`^%=____XM-"(-Y +XM$`&)]G1[BU6(BT6`B5`,BTT(QT0D#`$```#'1"0(`````,=$)`0,````BT$8 +XMB00DZ/S___^+78#'0QP`````QT-$`0```(E#&(M%@(L8Z8KY__^+58"+&NF` +XM^?__QP0D_____^C\____QT0D!)$!``#'!"1&````B40D".C\____BUV`B7L, +XMZX8`````)$9R965"4T0D`$=#0SH@*$=.52D@-"XR+C$@,C`P-S`W,3D@(%M& +XM0!E;&9? +XM9V5T@``````````````$````(8``````````````!````"7```````````` +XM```0````H@``````````````$````+(``````````````!````"Z```````` +XM```````0````Q0``````````````$````,H```!P`@``#`$``!(``0#6```` +XM```````````0````Y```````````````$````.X``````````````!````#_ +XM``````0```,"```2``$`#P$`````````````$````!H!`````````````!`` +XM```A`0`````````````0````)0$``!`&```6`0``$@`!`"\!```````````` +XM`!`````[`0``,`<``#D!```2``$`10$`````````````$````$\!``!P"``` +XM\`$``!(``0!?`0`````````````0````90$``&`*```H`0``$@`!`'(!```` +XM`````````!````!_`0`````````````0````B@$``)`+``"7````$@`!`)D! +XM`````````````!````"@`0`````````````0````IP$``*`,``#V`P``$@`! +XM`+(!`````````````!````#"`0`````````````0````U`$````````````` +XM$````.`!`````````````!````#K`0`````````````0````^`$````````` +XM````$`````("`````````````!`````'`@`````````````0````#P(``)`1 +XM``!5!P``$@`!`!P"`````````````!`````J`@`````````````0````,0(` +XM````````````$````#@"`````````````!````!``@`````````````0```` +XM3`(`````````````$`````!S96-T:6]N`!M96UM;W9E`&5L9E]E`!U<&1A=&5? +XM5]D +XM871A`&5L9E]G971D871A`&-O<'E?6YC7W-E +XM8W1I;VYS`'=A5]C;VYT96YT`&-R96%T95]S>6UT86(`;65M8W!Y`'-T`\```$&``"8 +XM#P```A@``+8/```"%```O@\```$&``#.#P```A4``-H/```"%```X@\```$& +XM``#R#P```A4``/X/```"%```!A````$&```6$````A4``"(0```"%```*A`` +XM``$&```Z$````A4``$(0```!!@``3A````(=``!:$````A0``&(0```!!@`` +XM``"@ +XM%````B<``.X4```"'P``^10```(8```'%0```2\``!45```!,```914```(W +XM``"_%0```C<``.,5```")P``[A4```(V```&%@```C<``#06```"-0``518` +XM``(G``!@%@```C8``'06```!!@``@!8```(=``"%%@```3```)46```",0`` +XMPA8```(R``#V%@```A\``!L7```".```.Q<```(1``!1%P```BX``&@7```" +XM.0``@A<```(I``"T%P```BD``-(7```"%```VA<```$&``#J%P```A4``/(7 +XM```!!@``_A<```(=```*&````A0``!(8```!!@``(A@```(5```N&````A0` +XM`#88```!!@``1A@```(5``!+&````A@``(T8```")@``P1@```(4``#)&``` +X,`08``-D8```"%0`` +X` +Xend +END-of-sections.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.sh new file mode 100644 index 0000000000..65acfe9c56 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-7/strip-all-7.sh @@ -0,0 +1,6 @@ +# $Id: strip-all-7.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-all-7 tc/strip-all-7 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -o sections.o.1 sections.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/in/strip-all-8.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/in/strip-all-8.in.shar new file mode 100644 index 0000000000..959c4dce85 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/in/strip-all-8.in.shar @@ -0,0 +1,708 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# sections.o.debug.uu +# +echo x - sections.o.debug.uu +sed 's/^X//' >sections.o.debug.uu << 'END-of-sections.o.debug.uu' +Xbegin 644 sections.o.debug +XM?T5,1@$!`0D```````````$``P`!``````````````!86@```````#0````` +XM`"@`&0`6`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R +XM''<%.T$07@`````BT80BU84QT6X +XM`P```,=%O`````")1`````` +XMQT7<`````(M&"(D$).C\____A<")PP^$Z@```/9'3!`/A(\```"+1AB+5AR) +XM1=2-1;2)5=B)1"0$BT8(B00DZ/S___^%P`^$W@```,<#`0```,=#!`````"+ +XM1@R)0PB+1AB+5AS'0PP`````QT,0`````(E#%(E3&,=#'`$```#'0R`!```` +XMBT8(B00DZ/S___^)1"0$BT<8B00DZ/S___^%P`^$I0```(/$3%M>7UW#C70F +XM`(M&&(M6'(M.#(/`\(/2_XE&&(E6'(E$)`B-01")1"0$B0PDZ/S____I1/__ +XM_\<$)/_____H_/___\=$)`0`````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0>````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0W +XM````QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`15````QP0D1@`` +XM`(E$)`CH_/___XUV`%6)Y5=64X/L3(MU"(M>?(7;='>-?;2)?"0$BT,(B00D +XMZ/S___^%P'1[BP.)1"0$BT9$B00DZ/S___^+5=R%THE%M'0LBT9\A7UW#QT7<`````.O,QP0D +XM_____^C\____QT0D!'(```#'!"1&````B40D".C\____QP0D_____^C\____ +XMQT0D!#<```#'!"1&````B40D".C\____B00DZ/S____'1"0$C@```,<$)$8` +XM``")1"0(Z/S___^-="8`58GE@^P8B77\B=:)7?B+6$2+0PR%P'08B70D!(D< +XM).C\____BUWXBW7\B>Q=PXGVQT0D!*4```")'"3H_/___\=$)`2F````B1PD +XMZ/S____'1"0$K@```(D<).C\____QT0D!+8```")'"3H_/___^NFC;0F```` +XM`(V\)P````!5B>575E.#[$R+10B+6'R%VW4)ZQB+6TB%VW01BS.Y"@```+^V +XM````_/.F=>B+50B+0B)64B)04R+0TR)"(U!2(E#3(D\).C\____A<")P@^$Q@```,<``0```,=` +XM!`````#'0`P`````QT`0`````(M&!(E""(M&",="&`````#'0AP!````QT(@ +XM`0```(E"%(U5M(E4)`2)/"3H_/___X7`#X27````QT6X`0```(M%"(L6Z$O^ +XM__^-1;2)1"0$B3PDZ/S___^%P`^$DP```(MV#(7V#X7I_O__@\1,6UY?7````QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`3E````QP0D1@```(E$)`CH_/___\<$)/_____H +XM_/___\=$)`0W````QP0D1@```(E$)`CH_/___XVV`````(V\)P````!5B>56 +XM4X/L$(MU"(M>1(7;=`>+3@R%R71U,=OK4XUV`(M&"(D$).C\____A<")P0^$ +XMG0```(M61(72=5F+`XM3!(D!BT,,B5$$BU,0B4$,BT,(B5$0BU,8B4$(BT,< +XMB4$7564X'LD````(MU$(U%N(E$)`2+10R)!"3H_/__ +XM_X7`#X2E````C9UX____B5PD!(DT).C\____A<`/A*\```"+1;B+512)A7C_ +XM__^+1;R)A7S___^+1<")18"+1<2)182+1")1:"+1>2)1:2+1>B)1:B+1>R)1:R+1?")1;"+ +XM1?2)1;2+10CHG?O__XE<)`2)-"3H_/___X7`=%*!Q)````!;7EW#QP0D____ +XM_^C\____QT0D!!P!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D +XM!#H!``#'!"1&````B40D".C\____QP0D_____^C\____QT0D!%@!``#'!"1& +XM````B40D".C\____C;0F`````%6)Y5=64X/L?(M%"(MX?(7_#X0N`0``QT6H +XM`````,=%K`````#I_````(VV`````(MW%#MUK(M?$`^"$0$``'<).UVH#X(& +XM`0``BT<\A<"0=4^+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2) +XM5"0$Z/S___^)59R+39R)19@/K\8/K\L!P8M%F/?CC301B4<0B7<4BUVHBW6L +XMBT=`A<`/A88```"+5S"+3S2)T(/P"`G(=!*)R`G0=`R+7Q"+=Q0#7Q@3=QR- +XM5;")5"0$BT<(B00DZ/S___^%P`^$P0```(M'$(M7%(E%R(E5S(M'&(M7'(E% +XMT(U%L(E5U(E$)`2+1PB)!"3H_/___X7`#X2S````BW](A?]T)8E=J(EUK(M% +XMK`M%J`^%_O[__XM?$(MW%`-?&!-W'(M_2(7_==N#Q'Q;7E]=PXUV`(M'/(7` +XM=4.+7RB+=RR)V(/`_XGR@]+_`T6H$U6LB5PD"(ET)`R)!"2)5"0$Z/S___^) +XM592+392)19`/K\8/K\L!P8M%D.GV_O__QP0D`````.C\____ZZ_'!"3_____ +XMZ/S____'1"0$564X/L4(MU"(U%N(E$)`2+1A2)!"3H +XM_/___X7`#X2G````QT0D!%@```#'!"0!````Z/S___^%P(G##X31````BT7@ +XMBU7DB4,0B5,4BT9\N@$```"%P'06,-*-=@"#>$`!BT!(@](`A7LCBULLA=MT'(L#B30D +XMB40D!.C\____A!@`#Y7"R8G0PXUV`%6)Y8/L&,=$ +XM)`@`````B50D!(D$).C\____A575E.#[&S'1"0$6````,<$)`$```#H_/___XM5"(7` +XMB4)$#X1S`P``QP"V````QT`$`````,=`&`````#'0!P`````QT`H`0```,=` +XM+`````#'0#P`````QT`P`P```,=`-`````"+50B-1?")1"0$BT(4B00DZ/S_ +XM__^%P`^$+`,``,=%H`````#I$0$``(MUG+^F````N0@```#SI@^%K@$``(M% +XM"(-X2`$/A.\```#'1"0$6````,<$)`$```#H_/___X7`#X3.`@``B<.+19R) +XM`XM5H(E3!(M%R(M5S(E#$(E3%(M%T(M5U(E#&(E3'(M%X(M5Y(E#*(E3+(M% +XMM,=#-`````")0S"+50B)7"0$B10DZ/S___^)0SR+50B+0AB)!"3H_/___X7` +XMB4,(#X0=`@``BT6@B00DZ/S___^%P(E#.`^$*P(``(MUG+D*````O[8```#\ +XM\Z8/A_^__^+`XM5"(E$)`R+0PB) +XM1"0(BT,$B10DB40D!.C\____Z1#___^+=9R_K@```+D(````\Z8/A#W^__^+ +XM50B+0C2%P'4+BT(XA<`/A#7^__^+50B+19S'1"0(`````(D4)(E$)`3H_/__ +XM_XM5"(MZ-(7_=`^%P'0+BW`DA?8/A?'^__^+50B+6CB%VW03A<`/A-_^__^+ +XM2!R%R0^$U/[__XMUG+D*````O[8```#\\Z8/DL`/E\(HP@^^PH7`#X0H____ +XMZ;W]___H_/___X7`B?8/A=````"#Q&Q;7E]=P\<$)/_____H_/___\=$)`3^ +XM`0``QP0D1@```(E$)`CH_/___\<$)/_____H_/___\=$)`0:`@``QP0D1@`` +XM`(E$)`CH_/___\<$)/_____H_/___\=$)`0P`@``QP0D1@```(E$)`CH_/__ +XM_\<$)/_____H_/___\=$)`1&`@``QP0D1@```(E$)`CH_/___\=$)`2K`0`` +XMQP0D1@```.C\____QP0D_____^C\____QT0D!.,!``#'!"1&````B40D".C\ +XM____B00DZ/S____'1"0$C@```,<$)$8```")1"0(Z/S___^-=@"-O"<````` +XM58GE5U93C3P0@^P,.?AS;8G#ZS&A`````(7`=6B+%0````"+0@B#Z`&%P(E" +XM"`^(GP```(L"Q@`*@\`!B0*#PP$Y^W0X#[83A-)TR*$`````A$N+`8GR@\,!B!"#P`$Y^XD!=R,````BT4(BT!\A<")18!T5XU5Y(F5 +XM?/___^L-BTV`BTE(AF+&;^F````N0@```#\B=[S +XMIG4MBUT(]D-,0'7-B1PDZ/S___^#2TQ`BTV`BTE(A +XM7UW#OZX```"Y"````(G>\Z9TP_R_M@```+D*````B=[SIG2(BT4(@WA(`0^$ +XMF````(M%"(G:Z!WZ__^%P`^$-@,``#';QT60`````,=%H`````#K08UV`(M% +XMH`-#%(D$).C\____B460BW60A?8/A/0#``"+4PB+0Q2+39`#3:")5"0$B40D +XM"(D,).C\____BU,4`56@BTV`B5PD!(M!!(D$).C\____A<")PP^$EP```(M] +XMD(7_=9^+0Q2)!"3H_/___XE%D.N@BU6`BT(P@_`)"T(T#X56____C4VDB4PD +XM!(M"!(D$).C\____A<`/A+P%``"+70CV0TP0#X64`P``BT-\AC^___H_/___X7`#X5P!```BTV0A_S__XM=@(M%"(L3Z!KW__^%P`^$,O___^DA_O__BUV0BT64B7PD"(E< +XM)`2)!"3H_/___XM5H(M-G(T$%\8$"`"#P`&)1:#IO?[__XM%"(G:Z*7V__^% +XMP`^$[?[__^FS_/__D(VT)@````#H^_K__^E<____BU60BT6<`T6@B7PD"(E4 +XM)`2)!"3H_/___P%]H.F)_O__BU6`BTT(QT0D"`````"+`HD,)(E$)`3H_/__ +XM_XMP#(DT).C\____B70D!(G#B40D"(M%G`-%H(D$).C\____BT6<`UV@Q@0# +XM`(/#`8E=H.E*_O__BU6@BTV0BUVD< +XM_?__QT0D!($"``#'!"1&````Z/S___^A`````,<$)`H```")1"0$Z/S____I +XM%OO__XM-"(M%S(M1/#M".'0IBT6`BQCI@_O__XE4)`3'!"0*````Z/S____I +XMZ?K__XM-@(L9Z63[__\Q_\=%B`````#'180`````BUV$BU6`B5PD!(M"!(D$ +XM).C\____A<")180/A$4!``"+182-7>2)7"0(QT0D!`````")!"3H_/___SN% +XM?/___P^%^P```(M5"(M=\(M"0(M`!(D$).C\____BTT(B5PD"(E$)`2+012) +XM!"3H_/___X7`#X2E````BUT(B40D!(D<).C\____A<`/A''___^#>Q`!=#+' +XM!"1`````Z/S___^%P'1DB46(BU7HBTV(BT7DB5$$BU7PB0&+1>R)40R)00CI +XM.?___\<$)"````#H_/___X7`=#*)QXM%Y(D'BT7LB4<$Z1?___^)!"3H_/__ +XM_\=$)`0#`0``QP0D1@```(E$)`CH_/___\=$)`1S`@``QP0D1@```.C\____ +XMQP0D_____^C\____QT0D!!H"``#'!"1&````B40D".C\____QP0D_____^C\ +XM____QT0D!%P"``#'!"1&````B40D".C\____Z/S___^%P`^%=____XM-"(-Y +XM$`&)]G1[BU6(BT6`B5`,BTT(QT0D#`$```#'1"0(`````,=$)`0,````BT$8 +XMB00DZ/S___^+78#'0QP`````QT-$`0```(E#&(M%@(L8Z8KY__^+58"+&NF` +XM^?__QP0D_____^C\____QT0D!)$!``#'!"1&````B40D".C\____BUV`B7L, +XMZX8````!$0$E#A,+`PX;#A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+.PM) +XM$P``!"0`"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8`21,` +XM``D3`0,."PLZ"SL+`1,```H-``,..@L["TD3.`H```L-``,(.@L["TD3.`H` +XM``P5`2<,21,!$P``#04`21,```X3``,./`P```\!`4D3`1,``!`A`$D3+PL` +XM`!$3`0L+.@L["P$3```2%@`#"#H+.PM)$P``$P0!"PLZ"SL+`1,``!0H``,. +XM'`T``!4N`0,..@L["R<,$0$2`4`&`1,``!8%``,(.@L["TD3`@8``!4P````,W!@`` +XM!6-W````!P2B````!P3M````"*(````#Z`(```7DEP````/"`0```B^P```` +XM"94'```(`D8Q`0``"FX$```"1S$!```"(P`*4P````"(SP*O0@` +XM``)\VP(```(C0`IW"````GWK`@```B-#"U]L8@`"@`@!```"(T0*L`8```*# +XM3`````(C3`IJ`@```H3]`````B-0``P!3````&D"```-O@`````'!%D"```, +XM`4P```")`@``#;X````-X0````U,``````<$;P(```P!_0```*D"```-O@`` +XM``W]````#4P`````!P2/`@``#`%,````R0(```V^````#><````-3``````' +XM!*\"```."P````$'!,\"```/+````.L"```0NP````(`#RP```#[`@``$+L` +XM``````.5"````H4W`0```Z\'```&)LL````#G0````8JRP````\L````+`,` +XM`!"[````#P`1"`9Z40,```K/!0``!GL&`P```B,`"FD#```&?!$#```"(P0` +XM`WX$```&?2P#```#``````%B`,```(C"``#D04```>&"P4``!)%;&8` +XM""9&!0``#B$(```!`QX!```()U<%```.,@$```$3!`@V]@4``!0@!0```!2V +XM!````12!`P```A1?`P```Q1+!```!!2:"```!11P`P``!A0^````!Q13`P`` +XM"!2+`P``"10S!```"A1`!P``"Q0E!@``#!3=`@``#13F!```#A2K"```#Q0$ +XM`0``$!1Z`@``$13V`@``$A2*,&```"(P``"?D%```P"&BC +XM!@``"KD&```(;-8````"(P`*P00```AMO@````(C"`I0!@``"&[6`````B,, +XM"E$````(;]8````"(Q0*[P(```AP]@4```(C'`KE!@``"'%>`````B,@"NH` +XM```(=JD&```"(R0*<`<```AW7@````(C*`H4!```"'@!!@```B,L``<$&`8` +XM``<$3`4```-?!P``"'D8!@```^`````)+F`$```#N`$```DP``4```/&!0`` +XM"3(P!0``$00*)/(&```*&P8```HD&P<```(C```)5@0```@*(1L'```*EP8` +XM``HBYP````(C``IL`0``"B3;!@```B,$``<$\@8``!$$"C8X!P``"AL&```* +XM-NT'```"(P``";L%```P"BCM!P``"I<&```**><````"(P`*#`4```HJYP`` +XM``(C!`IS!0``"BOG`````B,("IX#```*+.<````"(PP+861D``HN3`````(C +XM$`K;`0``"B],`````B,4"OX#```*,$P````"(Q@*AP$```HQ3`````(C'`K@ +XM!0``"C),`````B,@"B0````*,TP````"(R0*#00```HT3`````(C*`JG!@`` +XM"C8A!P```B,L``<$.`<``!$$"C\*"```"AL&```*/T\(```"(P``"74!```0 +XM"CI/"```"I<&```*.^$````"(P`*:`<```H\X0````(C!`K'!```"CWR```` +XM`B,("A0````*/_,'```"(PP`!P0*"```$0@*4GH(```*\`````I25@D```(C +XM``J=`0``"E)<"0```B,$``F`!@``6`I#5@D```J7!@``"D3G`````B,`"VES +XM``I%J08```(C!`MOT!```("E^P"0``"L$&```*7U8)```"(P`*I@<` +XM``I?7`D```(C!``1!`I@QPD```H;!@``"F`V"@```B,```G`````,`I7-@H` +XM``MO9F8`"EC6`````B,`"V9S>@`*6=8````"(P@+;7-Z``I:U@````(C$`H0 +XM!P``"EO6`````B,8"B0````*74P````"(R`*?P<```I?APD```(C)`H)`P`` +XM"F"P"0```B,L``<$QPD``!,$"H1C"@``%*P#````%+8````!%)4$```"%)D" +XM```#%(@&```$`!$("IB("@``"@@"```*F#8*```"(P`*SP,```J8B`H```(C +XM!``'!#8*```1"`J9LPH```H(`@``"IGM!P```B,`"L\#```*F;,*```"(P0` +XM!P3M!P``$0@*FMX*```*"`(```J:3P@```(C``K/`P``"IK>"@```B,$``<$ +XM3P@``!$("IP)"P``"@@"```*G!L'```"(P`*SP,```J<"0L```(C!``'!!L' +XM```1"`J>-`L```H(`@``"IX;!P```B,`"L\#```*G@D+```"(P0`$0@*H%D+ +XM```*P08```J@5@D```(C``JF!P``"J!<"0```B,$`!$$"J)P"P``"E\%```* +XMHE8)```"(P``"3\"``"("F8�``"D0!```*9^<````"(P`*L`0```IJ3``` +XM``(C!`HX`@``"FM,`````B,("VEE8P`*;4P````"(PP+;V5C``IN3`````(C +XM$`ME:6X`"F\�```B,4"GL&```*<`8-```"(Q@*I0,```IR3`````(C'`HW +XM````"G-,`````B,@"E0(```*>4P````"(R0*_08```IZ3`````(C*`HN`P`` +XM"GM,`````B,L"J8!```*?$P````"(S`*FP4```I]3`````(C-`I(!0``"GY, +XM`````B,X"M8"```*@%8)```"(SP*)@@```J!5@D```(C0`H_!0``"H)6"0`` +XM`B-$"M\'```*BCP*```"(T@*$@,```J33`````(C3`H;!```"I8Q`0```B-0 +XM"AX````*F&,*```"(U0*7@0```J9C@H```(C7`K/`@``"IJY"@```B-D"B8! +XM```*G.0*```"(VP*60$```J>#PL```(C=`I_!P``"J`T"P```B-\"E@'```* +XMHED+```#(X0!``<$.P4``!5D"````9H!`````'0`````````3@T``!9E8W`` +XM`9E.#0``+````!9S96,``9E6"0``50```!=S``&;5@D```%1``<$<`L``!@! +XM,@4```$-`P&`````;0(``(D```"L#0``&65C<``!#`-.#0``M0```!IS``$. +XM`U8)``#K````&[<#```!#P.L#0``"0$``!QS:``!$`/%!@```Y&L?P`'!*\& +XM```8`2L````!WP(!<`(``'P#```]`0``)0X``!EE8W```=X"3@T``&D!```: +XM("3````.8!```=3@,```'B`DP`````'@L&```!T`(!@`,``/(#```$ +XM`@``;0X``!EE8W```<\"3@T``#`"```?EP8```'/`N<```!#`@``&G,``=$" +XM5@D``&P"````&`%`!@```9D"`0`$```#!@``B@(``.\.```996-P``&8`DX- +XM``"V`@``&G-A``&:`D\(``#6`@``&Z@````!FP)6"0``]`(``"!S``&;`E8) +XM```:;V0``9P"K`T``!(#```:;W,``9T"J08``#L#```<;W-H``&>`L4&```# +XMD:Q_`!@!?0$```%T`@$0!@``)@<``%D#``!&#P``&7,``7,"5@D``(4#```: +XM:60``74"K`T``-(#```:;V0``74"K`T``/L#```;J00```%V`DP````D!``` +XM`!@!\00```%@`@$P!P``:0@``$($``"_#P``&65C<``!7P).#0``;@0``!EI +XM@@````DR0$```%5`4P```!@ +XM#```E@P``(T(``!Q$0``%F5C<``!5$X-``"Y"```(I<&```!5.<```#,"``` +XM(W-A8P`!5NT'``#?"````"6Z!P```38!3`````&F$0``)F5C<``!-4X-```G +XMEP8```$UYP```"@I!(``#%?8P`"AP%,````,5]P +XM``*'`7@2````!P3[`@``'L,(```!'P(!H!```(@1``!X"@```1,``!ED``$> +XM`N<```"D"@``&7-Z``$>`O(```#-"@``&F,``2`"YP```/8*```R3Q(``"`` +XM```!)`+A$@``,VP2```4"P``+6$2````-$\2```X`````28",VP2```]"P`` +XM,V$2``!Q"P`````U$0$```%3`0$!I1,``#%E8W```5(!3@T``#%S``%2`58) +XM```@=``!5`%6"0``'9<&```!50'G````(&ES:``!5@'%!@``(')E;``!5P'0 +XM!@``'5D%```!6`&E$P``'?<&```!60&K$P``(&ED``%:`:P-```=J00```%; +XM`4P````@:0`!6P%,````';4%```!6P%,````(&-A<``!6P%,``````<$40,` +XM``<$,`4``"4C!P```7D!3`````'9$P``)F5C<``!>$X-```GEP8```%XYP`` +XM```UUP0```'7`0$!>A0``#%E8W```=8!3@T``#%S``'6`58)```@T'```=!P0```'9`?(````=`@(```'9`?(````@<``!V0'R````(&QE;@`! +XMV0'R````(&(``=H!X0```"!C``':`>$````@9``!V@'A````('-R8P`!V@'A +XM````(&5N9``!V@'A````'?D````!VP%,`````#![!0```4`"`;X````!SQ0` +XM`#%S``$_`E8)```VQP0```$_`L\4```@:60``4$"K`T``"!B``%"`N$````@ +XM<5```M&Q,``"T/$P``-Y`````O)1,``.8+```O +XM+Q,``!H,```X.Q,```.1G'\X1Q,```*17"]3$P``.`P``#A?$P```W6(?SAK +XM$P```W6$?R]V$P``Q`P``#F"$P``.8P3```YF!,`````,K$3```8`0```4,! +XM!A8``#/-$P``^`P``"W"$P```#+9$P``,`$```%$`:\6```M\Q,``"WG$P`` +XM-V`!```O_1,``!8-```O"10``#0-```Y%10``#DA%```+RL4``"1#0``.3<4 +XM```O010``/$-```O2Q0``#8.```Y510``#AA%````W6,?SEM%```-'H4``#P +XM`0```=T!+984```MC!0``#<0`@``+Z(4``"6#@``.:T4```YMQ0``"_"%``` +XM(@\````````ZU10``(L4``"W%````4@!X18``"WQ%```+>84```NI!0``+<4 +XM```O_!0``$L/`````#0(%0``0`(```%)`2T6%0``-W`"```O(!4``'0/```O +XM*Q4``+X/```T3Q(``+`"```!.P(S;!(``-P/```M81(````````[9`0```** +XM>!(```$!/$<"```"H`%,`````0$`<`0```(`N`````$!^PX*``$!`0$````! +XM+W5S7,``'-E8W1I;VYS+F,`````K?P\/`#00CAE0@L"!,(+`AT",IL#40BW9@@ZY0-L<68(.M<9@RPB=!`(#XGX(5;H$`0.9?P(N`;H#Y0#%`YM_J<>?""V.@`-V1P,DQ0-BJ0,* +XM[P@6`[U^Q0/2`P(G`?ZL"*H#=V,(JG(#\WWO`Q\('0B2QG((<`,)C;@#YP$( +XM*U8#B7]_"%T(=0@MD0@>9)HZ90@>ME>4-3WFSHX#"P@K`VF;`Q"@I(&9A:6QE9#H@)7,`-C8X(&=E;&9?9V5T6UT86(`+G-T@P```$`4```````````8`P``'H,```!`%(``````````'P, +XM``"(#````0!0D@P``)4,```!`%```````````*`,``"A#````@!T!*$,``"C +XM#````@!T"*,,``"6$````@!U"```````````H`P``,L,```"`)$`RPP``)80 +XM```"`'4(```````````R#0``6`\```$`4Y#P``K@\```$`4'80 +XM``!^$````0!0``````````!##@``1@X```$`4$4/``""#P```0!0```````` +XM``"@$```H1````(`=`2A$```HQ````(`=`BC$```B!$```(`=0@````````` +XM`*`0``"Y$````0!0Y1```/$0```!`%`=$0``)1$```$`4```````````H!`` +XM`+00```!`%+E$```Z!````$`4AT1```E$0```0!2``````````"R$```(1$` +XM``$`4R41``"($0```0!3``````````##$```Z!````$`4AT1```E$0```0!2 +XM%@```0!7MA8``,L6```!`%?7%@``KQ@```$`5]T8``#E&````0!7```` +XM``````#.%P``UA<```$`4%$8``!H&````0!0:Q@``(D8```!`%#=&```Y1@` +XM``$`4```````````/A(``$,2```!`%*&%0``BQ4```$`4@``````````ZA4` +XM`/(5```!`%!<%@``7!8```$`4```````````M!$``(P3```#`'6@?XP3``"4 +XM$P```0!2E!,``#T6```#`'6@?ST6``!`%@```0!20!8``&L6```#`'6@?VL6 +XM``!P%@```0!28%0``'Q8```$`5X06``"> +XM%@```0!7MA8``,L6```!`%?.%P``[A<```$`5P``````````M!$``-\3```# +XM`'60?]\3```"%````0!0`A0``*H5```#`'60?ZH5``"P%0```0!0L!4``.48 +XM```#`'60?P``````````M!$``-H1```!`%8`$@``"!(```$`5M,3```Y%0`` +XM`0!64Q4``($5```!`%:8%0``ZA4```$`5H06``">%@```0!6MA8``,L6```! +XM`%;.%P``[A<```$`5@``````````31(``-$2```!`%-1$P``Z!,```$`4_83 +XM```:%````0!3*Q0``$04```!`%-4%```@Q0```$`4SD5```\%0```0!34Q4` +XM`%85```!`%.J%0``^!4```$`4Q\6```H%@```0!3/18``&<6```!`%-P%@`` +XMA!8```$`4\X7```"&````0!3``````````!8$P``=Q,```$`4#D5```_%0`` +XM`0!0SA<``-87```!`%```````````+01``#'$0```0!0`!(```L2```!`%"F +XM%```KQ0```$`4```````````M!$``,T1```!`%,`$@``!Q(```$`4],4```Y +XM%0```0!3A!8``)X6```!`%.V%@``RQ8```$`4\X7``#N%P```0!3```````` +XM``#_%```"Q4```$`4,X7``#6%P```0!0``````````"T$0``[Q$```$`4@`2 +XM```^$@```0!2T1(``-02```!`%(9%0``.14```$`4K86``#&%@```0!2```` +XM``````"W`````@``````0Q<``%0-``!S971?5]S:&1R`+\/``!R97-Y;F-?$```%@``MA8``.,2``!1$P`` +XM``````````#U$@``41,``,48``#E&```D1@``+D8``!/&```:Q@``#(8``!* +XM&```#A@``"88``"X%P``SA<``(87``"L%P``;!<``'H7``!5%P``71<``"X7 +XM```Q%P``'Q<``"L7``#_%@``!1<``/H6``#\%@``U18``.46``">%@``MA8` +XM````````````.1(``&`2``"!%0``F!4`````````````8!(``-$2``#N%P`` +XM`A@``*H5``"$%@``.14``($5``!1$P``@!0`````````````8!(``-$2``#N +XM%P```A@``'`6``"$%@``^!4``#T6``#R%0``]A4``.<5``#J%0``JA4``,L5 +XM``!&%0``@14``&$4``"`%```/A0``%04```B%```*Q0``!<4```:%```LA,` +XM`!04``"9$P``J!,``)03``"6$P``@1,``(P3``!1$P``=!,````````````` +XM8!(``-$2``!P%@``A!8``%$3``!>$P````````````!Q$@``GA(``'`6``"$ +XM%@``5A,``%X3``"T$@``P1(``+`2``"R$@````````````"W%```.14``,X7 +XM``#N%P``MA8``-46``"$%@``GA8``)@5``"J%0````````````"W%```X!0` +XM`-87``#N%P``MA8``-46``"8%0``JA4``/T4```Y%0``]A0``/@4``#R%``` +XM]!0`````````````&14``#D5``"V%@``U18`````````````16QF-C1?061D +XM<@!?7W-&24Q%6`!S861D7VQI6U?5]D871A`&-O<'D`95]E;G1R>0!U:6YT,S)?=`!T +XM<65?<')E=@!S96-T:6]N0!C;VUP@!R96YA;64` +XM9%]N97AT`'9?F5? +XM=`!I7!E +XM`&1?=F5R7!E`'5N```"````!<````(````!`````@```!>`````0`` +XM````````````"C@``#````````````````$`````````9P````$````R```` +XM`````#HX``":`@`````````````!`````0```'8````!````,@````````#4 +XM.@``+0``````````````!`````$```")`````0``````````````!#L``.0! +XM``````````````0`````````A0````D``````````````&!X``#P````%P`` +XM``T````$````"````)8````!``````````````#H/```&Q`````````````` +XM`0````````"E`````0```````````````TT``+L```````````````$````` +XM````H0````D``````````````%!Y```(````%P```!`````$````"````+D` +XM```!``````````````"^30``(````````````````0````````"U````"0`` +XM````````````6'D``!`````7````$@````0````(````R`````$````````` +XM`````-Y-``#(`@`````````````!`````````-8````!````,`````````"F +XM4```S@@``````````````0````$````1`````P``````````````=%D``.$` +XM``````````````$``````````0````(``````````````$!>```P!```&``` +XM`!8````$````$`````D````#``````````````!P8@``8`(````````````` +XM`0```````````````````````````````0``````````````!`#Q_P`````` +XM``````````,``0`````````````````#``,``````````````````P`$```` +XM``````````````,`!0`````````````````#``8``````````````````P`( +XM``P`````````=`````(``0`````````````````#``L`'P```(`#``!R```` +XM`@`!``````````````````,`#``O````,`P``"T````"``$`0P```&`,```V +XM`````@`!`%4```"@$```Z`````(``0`````````````````#``T````````` +XM`````````P`/``````````````````,`$``````````````````#`!(````` +XM`````````````P`4``````````````````,`%0`````````````````#``H` +XM8````(````#M`0``$@`!`&T``````````````!````!Z```````````````0 +XM````A@``````````````$````)<``````````````!````"B```````````` +XM```0````L@``````````````$````+H``````````````!````#%```````` +XM```````0````R@```'`"```,`0``$@`!`-8``````````````!````#D```` +XM```````````0````[@``````````````$````/\`````!````P(``!(``0`/ +XM`0`````````````0````&@$`````````````$````"$!`````````````!`` +XM```E`0``$`8``!8!```2``$`+P$`````````````$````#L!```P!P``.0$` +XM`!(``0!%`0`````````````0````3P$``'`(``#P`0``$@`!`%\!```````` +XM`````!````!E`0``8`H``"@!```2``$`<@$`````````````$````'\!```` +XM`````````!````"*`0``D`L``)<````2``$`F0$`````````````$````*`! +XM`````````````!````"G`0``H`P``/8#```2``$`L@$`````````````$``` +XM`,(!`````````````!````#4`0`````````````0````X`$````````````` +XM$````.L!`````````````!````#X`0`````````````0`````@(````````` +XM````$`````<"`````````````!`````/`@``D!$``%4'```2``$`'`(````` +XM````````$````"H"`````````````!`````Q`@`````````````0````.`(` +XM````````````$````$`"`````````````!````!,`@`````````````0```` +XM`'-E8W1I;VYS+F,`:6YS97)T7W1O7W-E8U]L:7-T`&%D9%]T;U]S:'-T5]S:&1R`%]?=61I=F1I,P!R97-Y;F-?'1S8VX`96QF7W-T```)`@```AT``!$"```!"0``(0(```(>```M`@```AT``#4"```!"0`` +XM10(```(>``!1`@```AT``%D"```!"0``:0(```(>``"1`@```A<``*8"```" +XM(```TP(```(:``#K`@```AD``/L"```"(0``'`,```(=```D`P```0D``#0# +XM```"'@``0`,```(=``!(`P```0D``%@#```"'@``8`,```(=``!H`P```0D` +XM`'@#```"'@``H`,```(B``"T`P```0D``+P#```"(@``Q`,```$)``#,`P`` +XM`B(``-0#```!"0``W`,```(B``#D`P```0D``.P#```"(@``)`0```$)``!* +XM!````B0``&@$```")0``PP0```(8```8!0```A<``$`%```"&0``9P4```(= +XM``!O!0```0D``'\%```"'@``AP4```$)``"3!0```B8``)\%```"'0``IP4` +XM``$)``"W!0```AX``,,%```"'0``RP4```$)``#;!0```AX``.<%```"'0`` +XM[P4```$)``#_!0```AX``#<&```"&```BP8```(H``"6!@```B$``.H&```" +XM'0``\@8```$)```"!P```AX```H'```"'0``$@<```$)```B!P```AX``$P' +XM```"%P``9@<```(7``#K!P```AD```4(```"'0``#0@```$)```="````AX` +XM`"D(```"'0``,0@```$)``!!"````AX``$T(```"'0``50@```$)``!E"``` +XM`AX``.@(```"*@``2PD```(7``!]"0```AD``.T)```"*@``#0H```$+```2 +XM"@```BP``"`*```"'0``*`H```$)```X"@```AX``$0*```"'0``3`H```$) +XM``!<"@```AX``'D*```"+@``E0H```(E``#L"@```B\``#0+```"'0``/`L` +XM``$)``!,"P```AX``%@+```"'0``8`L```$)``!P"P```AX``'@+```!"0`` +XMA`L```(>``"Y"P```C$``-P+```",@``%PP```$)```C#````AX``$8,```" +XM,```=@P```(P``"Y#````B4``,T,```!"0``&@T```(T```V#0```0D``&0- +XM```")0``N0T```(U``#*#0```B0``.`-```"&@``^`T```$)```)#@```0D` +XM`"4.```!"0``5`X```(V``!Q#@```A<``)4.```"-P``K0X```$)``#L#@`` +XM`BD``/D.```!"0``-0\```(P``!X#P```0D``)@/```"(0``M@\```(=``"^ +XM#P```0D``,X/```"'@``V@\```(=``#B#P```0D``/(/```"'@``_@\```(= +XM```&$````0D``!80```"'@``(A````(=```J$````0D``#H0```"'@``0A`` +XM``$)``!.$````B8``%H0```"'0``8A````$)``!R$````AX``'H0```"'0`` +XM@A````$)``"2$````AX``+40```!.```OQ````$Y``#M$````3@``/<0```! +XM.0``)A$```$Y```V$0```CH``$$1```!.0``4!$```(Z``!J$0```CL``'\1 +XM```".P``SA$```$)``#K$0```CT```P2```!"0``'1(```$)``!J$@```C(` +XM`)02```"/@``K!(```(H``#($@```C(``/$2```"%P``4A,```(A``"0$P`` +XM`C(``!L4```"/P``-A0```(Q``"'%````B<``*`4```",```[A0```(H``#Y +XM%````B$```<5```!.```%14```$Y``!E%0```D```+\5```"0```XQ4```(P +XM``#N%0```C\```86```"0```-!8```(^``!5%@```C```&`6```"/P``=!8` +XM``$)``"`%@```B8``(46```!.0``E18```(Z``#"%@```CL``/86```"*``` +XM&Q<```)!```[%P```AH``%$7```"-P``:!<```)"``""%P```C(``+07```" +XM,@``TA<```(=``#:%P```0D``.H7```"'@``\A<```$)``#^%P```B8```H8 +XM```"'0``$A@```$)```B&````AX``"X8```"'0``-A@```$)``!&&````AX` +XM`$L8```"(0``C1@```(O``#!&````AT``,D8```!"0``V1@```(>```&```` +XM`04```P````!%```$0````$4```5`````10``!D````!`@``'0````$"```A +XM`````0<``"@````!%```+P````$4```V`````10``#L````!%```2`````$4 +XM``!4`````10``&$````!%```9@````$4``!S`````10``'@````!%```A0`` +XM``$4``",`````10``),````!%```F`````$4``"E`````10``*P````!%``` +XML0````$4``#!`````10``,P````!%```UP````$4``#S`````10``/X````! +XM%```"0$```$4```5`0```10``",!```!%```.`$```$4``!K`0```10``'D! +XM```!%```E0$```$4``"C`0```10``+$!```!%```OP$```$4``#-`0```10` +XM`-L!```!%```]P$```$4```3`@```10``"$"```!%```/0(```$4``!+`@`` +XM`10``-`"```!%```_`(```$4```'`P```10``!(#```!%```-0,```$4``!# +XM`P```10``%(#```!%```70,```$4``!H`P```10``',#```!%```?@,```$4 +XM``")`P```10``)P#```!%```J@,```$4``"X`P```10``,8#```!%```U`,` +XM``$4``#B`P```10``/`#```!%```_@,```$4```,!````10``!H$```!%``` +XM*`0```$4```V!````10``$0$```!%```4@0```$4``!A!````10``'0$```! +XM%```@@0```$4``"0!````10``)X$```!%```K`0```$4``"Z!````10``,@$ +XM```!%```U@0```$4``#D!````10``/($```!%````04```$4```4!0```10` +XM`"(%```!%```,04```$4``!'!0```10``$T%```!%```6`4```$4``!F!0`` +XM`10``&P%```!%```<@4```$4``!X!0```10``'X%```!%```A`4```$4``"* +XM!0```10``)`%```!%```E@4```$4``""````10``&P(```!%```>P@```$4``"'"````10``.8(```!%``` +XM]`@```$4```0"0```10``!X)```!%```+`D```$4```Z"0```10``$@)```! +XM%```:PD```$4``!Y"0```10``(@)```!%```E`D```$4``"B"0```10``+D) +XM```!%```R`D```$4``#^"0```10```P*```!%```&@H```$4```H"@```10` +XM`$4*```!%```2PH```$4``!1"@```10``%<*```!%```70H```$4``!L"@`` +XM`10``'H*```!%```EPH```$4``"E"@```10``,(*```!%```T`H```$4``#M +XM"@```10``/L*```!%```&`L```$4```F"P```10``#T+```!%```2PL```$4 +XM``!B"P```10``'$+```!%```?0L```$4``"+"P```10``)D+```!%```T0L` +XM``$4``#?"P```10``.T+```!%```^PL```$4```)#````10``!<,```!%``` +XM)0P```$4```S#````10``$$,```!%```3PP```$4``!=#````10``&L,```! +XM%```>0P```$4``"'#````10``)4,```!%```HPP```$4``"Q#````10``+\, +XM```!%```S0P```$4``#;#````10``.D,```!%```]PP```$4```-#0```10` +XM`!0-```!`@``&`T```$"```<#0```1```"\-```!$```/@T```$0``!6#0`` +XM`10``%X-```!`@``8@T```$"``!F#0```1```'H-```!$```B`T```$0``"- +XM#0```10``)@-```!$```M`T```$4``"\#0```0(``,`-```!`@``Q`T```$0 +XM``#8#0```1```.8-```!$```]`T```$0```)#@```10``!0.```!$```&0X` +XM``$4```F#@```10``"X.```!`@``,@X```$"```V#@```1```$H.```!$``` +XM3PX```$4``!:#@```1```&@.```!$```;PX```$4``!W#@```0(``'L.```! +XM`@``?PX```$0``"3#@```1```*(.```!$```IPX```$4``"R#@```1```,L. +XM```!$```V@X```$0``#Q#@```10``/D.```!`@``_0X```$"```!#P```1`` +XM`!,/```!$```(@\```$0```Q#P```1```#8/```!%```00\```$0``!(#P`` +XM`10``%`/```!`@``5`\```$"``!8#P```1```&P/```!$```>P\```$0``"* +XM#P```1```(\/```!%```F@\```$0``#!#P```10``,D/```!`@``S0\```$" +XM``#1#P```1```.4/```!$```\P\```$0```3$````1```!H0```!%```)1`` +XM``$"```I$````0(``"T0```!$```0!````$0``!.$````1```%,0```!%``` +XM7A````$0``!S$````10``'X0```!$```A1````$4``"0$````0(``)00```! +XM`@``F!````$0``"K$````1```+`0```!%```NA````$0``#)$````1```-@0 +XM```!$```WA````$4``#I$````0(``.T0```!`@``\1````$0```$$0```1`` +XM``D1```!%```$Q$```$0```B$0```1```"@1```!%```,Q$```$"```W$0`` +XM`0(``#L1```!$```3A$```$0``!3$0```10``%T1```!$```;!$```$0``!R +XM$0```10``(X1```!%```J!$```$4``"O$0```0(``+,1```!`@``MQ$```$0 +XM``#*$0```1```-<1```!$```W!$```$4``#F$0```1```/01```!$```"!(` +XM``$4```2$@```1```!<2```!%```(1(```$0```J$@```1,``#L2```!`@`` +XM/Q(```$"``!($@```1```%`2```!%```?Q(```$4``"'$@```0(``(L2```! +XM`@``CQ(```$0``"A$@```1```+`2```!$```OA(```$0``#'$@```1,``-<2 +XM```!$```YA(```$3``#R$@```1```/L2```!$````A,```$4```P$P```10` +XM`%03```!%```8!,```$4``!W$P```10``(T3```!%```LA,```$4``#.$P`` +XM`10``-H3```!%```"A0```$4```6%````10``&X4```!%```>Q0```$4``"7 +XM%````10``,,4```!%```UA0```$4``#R%````10```D5```!%```+!4```$4 +XM```Z%0```10``$(5```!`@``1A4```$"``!*%0```1```%X5```!$```=14` +XM``$3``"+%0```1,``)05```!$```G14```$0``"W%0```1```-(5```!$``` +XM[!4```$3``#\%0```1````L6```!$P``(18```$3```J%@```1```#,6```! +XM$```1A8```$0``!4%@```1```%T6```!$```>18```$3``"+%@```1,``)06 +XM```!$```IQ8```$0``"T%@```0(``+@6```!`@``SA8```$"``#2%@```0(` +XM`-L6```!$```YA8```$3``#S%@```1,``/P6```!$```!1<```$0```.%P`` +XM`1,``!H7```!$```*!<```$4```U%P```10``,4````!`@``&`````$/```< +XM`````0(``#@````!#P``/`````$"``!8`````0\``%P````!`@``>`````$/ +XM``!\`````0(``)@````!#P``G`````$"``"X`````0\``+P````!`@``V``` +XM``$/``#<`````0(``/@````!#P``_`````$"```8`0```0\``!P!```!`@`` +XM.`$```$/```\`0```0(``%@!```!#P``7`$```$"``!P`0```0\``'0!```! +XM`@``B`$```$/``",`0```0(``*@!```!#P``K`$```$"``#(`0```0\``,P! +X>```!`@``!@````$&```&`````08``!`````!`@`` +X` +Xend +END-of-sections.o.debug.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.sh new file mode 100644 index 0000000000..136599e715 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-8/strip-all-8.sh @@ -0,0 +1,6 @@ +# $Id: strip-all-8.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-all-8 tc/strip-all-8 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -o sections.o.debug.1 sections.o.debug" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-9/in/strip-all-9.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-9/in/strip-all-9.in.shar new file mode 100644 index 0000000000..9d05c99386 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-all-9/in/strip-all-9.in.shar @@ -0,0 +1,2302 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# elfcopy.uu +# +echo x - elfcopy.uu +sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' +Xbegin 755 elfcopy +XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` +XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````$QR````````3'(````````` +XM`!````````$````&````8'(```````!@@```````*!Z4```````H'I0 +XM``````"@`0```````*`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````1'(```````!$```````````````.````&P```!$````B````'````!4` +XM```#````&````````````````````"T``````````````"<````J````.``` +XM`"\`````````0````"`````)```````````````P````0@```#P```!&```` +XM%P```#L````_````$``````````````````````````````````````````` +XM````2`(``!(```#L%D```````)````````````$``!(```#\%D```````(<` +XM````````+P```!(````,%T```````!0(``!(```#L%T```````(<& +XM````````I@```!(```#\%T```````#L`````````*0$``!(````,&$`````` +XM`!D!````````SP```!(````<&$```````"0`````````$P(``!(````L&$`` +XM`````(@`````````0`(``!$`%P#8?E````````@`````````<0(``!(````\ +XM&$```````$P`````````^@(``!(```!,&$```````"D`````````<0```!(` +XM``!<&$```````#4`````````#0```!(```!L&$```````&D!````````?``` +XM`!(```!\&$```````&H`````````E`(``!$`%P"P?E````````0````````` +XMH0(``!(```",&$```````*T"````````G@$``!(```"<&$```````!8````` +XM````5P(``!$`$`!@`!G96QF7V=E=&-L87-S`&=E;&9?9V5T`!G96QF7W5P9&%T95]R96QA`&5L9E]E;F0`9V5L9E]G971S +XM:&1R`&=E;&9?9V5T<&AD<@!E;&9?97)R;7-G`&=E;&9?9V5T'-C;@!G96QF7W5P9&%T95]E:&1R +XM`&=E;&9?=7!D871E7W!H9'(`96QF7VMI;F0`7TIV7U)E9VES=&5R0VQA0!?7W-T9&5R`!M86QL;V,`;W!T87)G`&=E='!R;V=N86UE`')E;F%M90!C86QL;V,` +XM96YV:7)O;@!F<')I;G1F`&]P=&EN9`!?7W!R;V=N86UE`&9E'U0```````' +XM````)```````````````@'U0```````'````)0``````````````B'U0```` +XM```'````)@``````````````D'U0```````'````)P``````````````F'U0 +XM```````'````*```````````````H'U0```````'````*0`````````````` +XMJ'U0```````'````*@``````````````L'U0```````'````*P`````````` +XM````N'U0```````'````+```````````````P'U0```````'````+0`````` +XM````````R'U0```````'````+@``````````````T'U0```````'````+P`` +XM````````````V'U0```````'````,```````````````X'U0```````'```` +XM,0``````````````Z'U0```````'````,@``````````````\'U0```````' +XM````-```````````````^'U0```````'````-0```````````````'Y0```` +XM```'````-@``````````````"'Y0```````'````-P``````````````$'Y0 +XM```````'````.```````````````&'Y0```````'````.0`````````````` +XM('Y0```````'````.@``````````````*'Y0```````'````.P`````````` +XM````,'Y0```````'````/```````````````.'Y0```````'````/0`````` +XM````````0'Y0```````'````/@``````````````2'Y0```````'````/P`` +XM````````````4'Y0```````'````0```````````````6'Y0```````'```` +XM00``````````````8'Y0```````'````0@``````````````:'Y0```````' +XM````1```````````````<'Y0```````'````1@``````````````>'Y0```` +XM```'````2```````````````@'Y0```````'````20``````````````B'Y0 +XM```````'````2@``````````````D'Y0```````'````2P`````````````` +XMF'Y0```````'````3```````````````H'Y0```````'````3@`````````` +XM````J'Y0```````'````3P``````````````2(/L".A?!0``Z#I2``!(@\0( +XMPP#_-8YE$`#_)9!E$`"0D)"0_R6.91``:`````#IX/____\EAF40`&@!```` +XMZ=#_____)7YE$`!H`@```.G`_____R5V91``:`,```#IL/____\E;F40`&@$ +XM````Z:#_____)69E$`!H!0```.F0_____R5>91``:`8```#I@/____\E5F40 +XM`&@'````Z7#_____)4YE$`!H"````.E@_____R5&91``:`D```#I4/____\E +XM/F40`&@*````Z4#_____)39E$`!H"P```.DP_____R4N91``:`P```#I(/__ +XM__\E)F40`&@-````Z1#_____)1YE$`!H#@```.D`_____R4691``:`\```#I +XM\/[___\E#F40`&@0````Z>#^____)09E$`!H$0```.G0_O___R7^9!``:!(` +XM``#IP/[___\E]F00`&@3````Z;#^____)>YD$`!H%````.F@_O___R7F9!`` +XM:!4```#ID/[___\EWF00`&@6````Z8#^____)=9D$`!H%P```.EP_O___R7. +XM9!``:!@```#I8/[___\EQF00`&@9````Z5#^____);YD$`!H&@```.E`_O__ +XM_R6V9!``:!L```#I,/[___\EKF00`&@<````Z2#^____):9D$`!H'0```.D0 +XM_O___R6>9!``:!X```#I`/[___\EEF00`&@?````Z?#]____)8YD$`!H(``` +XM`.G@_?___R6&9!``:"$```#IT/W___\E?F00`&@B````Z<#]____)79D$`!H +XM(P```.FP_?___R5N9!``:"0```#IH/W___\E9F00`&@E````Z9#]____)5YD +XM$`!H)@```.F`_?___R569!``:"<```#I9C$`!H-0```.F0_/___R7>8Q``:#8```#I@/S___\E +XMUF,0`&@W````Z7#\____)#[____)89C$`!H00```.G0^____R5^8Q`` +XM:$(```#IP/O___\E=F,0`&A#````Z;#[____)6YC$`!H1````.F@^____R5F +XM8Q``:$4```#ID/O__P````!!5$R-9PA54XL?2&/#A=M(C6S'$$B)+6UC$`!^ +XM.DB+5PA(A=)T,4B)%>-6$``/M@*$P'0C2(/"`3PO2(L%SU80`$@/1,)(B07$ +XM5A``#[8"2(/"`83`=>&XH'I0`$B%P'0K2(GWZ"/___^_.&E``.@9____Z`#[ +XM__^)WTB)ZDR)YNBK!P``B3&!;%B +XM$``!2(/$",-F9F:09F9FD$B#/2A@$```=!:X`````$B%P'0,OV!\4`!)B<-! +XM_^.0\\.0D)"0D)"0D)"0D)"0D$B#[`A(BPU=8A``OY%I0`"Z#0```+X!```` +XMZ&W]__^_0````.C3_?__9F9FD&9FD$B#[`A(BPTM8A``OX!L0`"Z,P```+X! +XM````Z#W]__^_0````.BC_?__9F9FD&9FD$B#[`A(BPW]81``OY]I0`"Z#P`` +XM`+X!````Z`W]__^_0````.AS_?__9F9FD&9FD$B);"383(E\)/A(B?U(B5PD +XMT$R)9"3@28G73(EL).A,B70D\$B![-@```!(A?9(B70D"`^$H`0``$B+?"0( +XM,?8QP.CE_/__@_C_08G'!```387_#X1)`P``,<"Z[0$``+X"`@``3(G_ +XM13'MZ+G\__^#^/]!B<0/A)\$```QTKX%````1(GWZ"[\__](A_H8"T``$B)[^BH&@``BT5H@_@"=!.#^`1T#DB#O=`````` +XM#X23`@``@V5LWXM--(7)#X4*`@``]D5L$`^%\P$``$B)[^AL'@``2(M]($B- +XM="00Z)KY__^%P`^$Y@(``$B)[^@.#0``2(GOZ,8.``!(BWT@2(UT)!#HE/?_ +XM_TB%P`^$H0(``$B)[^B7%0``2(GO2(G#Z$P4``!(BT,@2(E$)#B+52R%TGXF +XM2(M](+D!````N@$```"^!````.B@^/__2(7`2(E$)#`/A%<#``!(BWT@2(UT +XM)!#H%/G__X7`#X1@`@``BT4LA$`"Z'@`` +XM`+X!````O[AL0`#HL?G__TV%_P^$OP```$2)]^@`^?__1(GGZ/CX__](BYPD +XMJ````$B+K"2P````3(ND)+@```!,BZPDP````$R+M"3(````3(N\)-````!( +XM@<38````PX--;`'I)O[__[_4:4``Z(WV__](A_H/OG__X/X_T&)Q`^$,P(``+[M`0`` +XMB_H@_;__X/``0^$/`$``$R)[^BB^?__Z17___](B>_HJ2T``.D` +XM_O__2(GOZ&P.``#IZ?W__TB)Q^B;^?__2(UX#DF)Q.@/^?__2(7`2(G'#X0' +XM`@``28G%3(GB2(G>2(G'Z,+V__]+C40L_X`X+TB-4`%T"$B-4`+&0`$O2+YE +XM8W`N6%A86,=""%A86%C&0@P`2(DRZ1G___^#36P"Z07]__](@[W```````^% +XM7_W__^E>_?__OJ]I0`"_1@```#'`Z%+V__](BU0D"+[%:4``OTH````QP.B< +XM^/__O______HPO7__[XG:D``2(G"OT$````QP.@>]O__3(GZOL5I0`"_2@`` +XM`#'`Z&KX__^______^B0]?__OEEJ0`!(B<*_1@```#'`Z.SU__^______^AR +XM]?__OMIJ0`!(B<*_1@```#'`Z,[U__](BTPD"$R)ZKY":T``OTH````QP.@5 +XM^/__O______H._7__[XG:D``2(G"OT8````QP.B7]?__O______H'?7__[ZT +XM:D``2(G"OT8````QP.AY]?__O______H__3__[YS:D``2(G"OT8````QP.A; +XM]?__O______HX?3__[Z):D``2(G"OT8````QP.@]]?__O______HP_3__[X0 +XM:T``2(G"OT8````QP.@?]?__3(GJO@1J0`"_2@```#'`Z&OW__^______^B1 +XM]/__OOAJ0`!(B<*_1@```#'`Z.WT__^^]FE``+]&````,<#H//?__[[,:D`` +XMOT8```#H+??__[ZA:D``OT$````QP.B\]/__OMMI0`!`MT8QP.@-]___D$%7 +XM28GW059!B?Z_`0```$%505154TB![)@```#HB_7__X7`#X0?"```O_````#H +XMN?;__TB%P$F)Q`^$MP8``#'VNO````!(B$))``````````2<>$)*``````````2<>$)+``````````28F$))@` +XM``!)C80DH````$G'A"3``````````$G'A"30`````````$G'A"3@```````` +XM`$F)A"2H````28V$)+````!!QT0D#`````!!QT0D"`````!)B80DN````$F- +XMA"3`````28F$),@```!)C80DT````$F)A"38````28V$).````!)B80DZ``` +XM`.B6]O__0;A9:T``2(7`N08```!,#T7`N&%K0`#\2(G'38D$)$R)QO.F#Y?" +XM#Y+`13'M.,(/A!4$``"X=&M``+D$````3(G&_$B)Q_.F#X20`@``13'`N?H&2@``.GX_O__9F9FD$B+-<%8$`"Z +XM`0```$R)Y^@<$```1(M(-$6%R0^%100``,=`+`$```!!QT0D2`$```#IOO[_ +XM_TB+-8M8$`!,B>?H.R@``.FJ_O__0<=$)&@$````Z9S^__](BSUI6!``OCT` +XM``#H\_'__TB%P$F)Q0^$+`0``+\@````Z/WS__](ALK +XM'318$`"->P%(8__HW?/__TB%P$B)10`/A,L#``!(BS456!``2&/;2(G'2(G: +XM28/%`>B'\?__2(M%`$B-="003(GOQ@08`.CR\?__@\`!#X3/`P``2(M\)%A( +XMB7T0Z(OS__](A_HD?+__TB%P$B)PP^$K`,` +XM`$B+51!(BWT(2(G!O@$```#HW'1"0$`````,=$)`@````` +XM13'M,=NZAFM``$R)_D2)]^CJ\/__@_C_#X2'`0``@^A6@_@:=@?HV/3__^O8 +XMB&M``+Y^:T``,<#HPN[__S'_Z"OR__](B=_H@_'__X7`#X3^_O__ +XMOL!K0`"_00```#'`Z#KR__]!BWPD#(7_=%6+%6]6$`!!.=9T"(U"`D$YQGX+ +XMZ$WT__^+%5=6$`!(8\)(C0S%`````(U"`3'203G&28LT#W\73(GGZ%;T__], +XMB>?H*O+__S'_Z+/Q__]*BU0Y".OB08M$)`A!B40D#.N?@_AOD`^$@0(```^/ +XM^P$``(/X9)!T!8/X9W5/0<=$)&@"````13'`N8!R4`"Z9VM``$R)_D2)]^A$ +XM\/__@_C_#X1D`@``@_A3=-%_M(/X2V9FD&:0#X0)`@``#X_+`0``@_@"D`^$ +XM+0(``.@U\___9F:09I#KKD0[-9=5$``/A$@!``"+!"0+1"0$"T0D"`G8#X3Z +XM````BT0D!(7`=!I!QT0D1`$```#'!"0`````,=O'1"0(`````(L$)(M4)`A% +XMA>U!B5PD0$&)1"0X08E4)#P/A*(```!)BX0DH````$B%P'0DBSPDB7@DBU0D +XM"(E8,(E0*(M\)`1(B6@8B7@T2(M`0$B%P'7W__[[;:4``OT8```#H%O#__[[;:4``OT8````QP.@%\/__Z`3R +XM___IKO[__[X@;4``OT`````QP.B*[?__OJ)K0`"_00```#'`Z-GO__],B>J^ +XML&M``+]!````,<#HQ>___X/X<`^$$/[__X/X#^%*0#X4P_O__2(LUNU,0`+H!````3(GGZ!8+``#'0#0!```` +XM0<=$)$0!````Z<']__](BS624Q``3(GGZ$(C``#IK?W__TB+-7Y3$`!,B>?H +XMOB(``.F9_?__3(LM:E,0`.F-_?__0<=$)&@$````9F9FD.E[_?__08M$)&B% +XMP'4)0<=$)&@!````08M$)`R%P'4*08M$)`A!B40D#$0[-3]3$`!T5HLM-U,0 +XM`$$Y[@^.^/S__TACQ4F-',=(BS-,B>I,B>>#Q0%(@\,(Z#+Q__]$.?5UYNG2 +XM_/__O_____]F9I#HY^O__[[8;$``2(G"OT8````QP.A#[/__Z'+P___KHTB+ +XME^````!(A=)T'TB+1B!(.T(@U(QT98 +XM`````$B+A^@```!(B49@2(N'Z````$B),$B-1EA(B8?H````BT9,AO__TB%P`^$"@$``$C' +XM1"00`````$C'1"0P`0```$B+12#'1"0$`P```$C'1"0(`````$C'1"0X```` +XM`,=$)"P`````QT0D*`````!(B40D&$B+?1#HBNK__TB%P$B)PP^$S@```$'V +XM1"1L$`^$A@```$B+12A(B>9(B40D($B+?1#H_>W__X7`#X3#````2,<#`0`` +XM`$B+11A(B4,(2(M%*$C'0Q``````QT,@`0```,=#)`$```!(B4,82(M]$.BO +XM[?__28M\)"!(B<;HDNG__X7`#X26````2(M<)$A(BVPD4$R+9"183(ML)&!( +XM@\1HPV9FD&:02(M5*$B+?1A(@^H02(UW$$B)52CH@^S__^E<____O______H +XM!.K__[X@;D``2(G"OT8````QP.A@ZO__O______HYNG__[X^;D``2(G"OT8` +XM```QP.A"ZO__O______HR.G__[Y7;D``2(G"OT8````QP.@DZO__O______H +XMJNG__[YU;D``2(G"OT8````QP.@&ZO__9F9FD&9FD&9FD$%454B)_5-(@^Q` +XM2(N?X````$B%VW4OZ8(```!F9F:02(/X!'1@2(M[$$B)YF9FD.BW[/__A<`/ +XMA)$```!(BUM82(7;=%A(BWL02(GFZ(KI__](AC__[ZN;D``2(G"OT8````QP.CUZ/__9F:09F:09F:02(EL)/A(B5PD +XM\$B#[!A(BU]@2(GU2(-[&`!T&4B)[DB)WTB+;"002(M<)`A(@\08Z?LW``!( +XMB=^^GFE``.CN-P``2(G?OL5N0`#HX3<``$B)W[[-;D``Z-0W``"^U6Y``$B) +XMW^C'-P``Z[%F9I!FD$%6055)B?U!5%532(/L0$B+K^````!(A>UT(D&XU6Y` +XM`.L)2(MM6$B%[7012(MU`+D*````3(G'_/.F=>9)BYVP````2(7;#X3_```` +XM9F:028M](.CSZ?__2(7`28G$#X3T````OG@```"_`0```.A(Z?__2(7`2(G" +XM#X3W````2(L#3(GG2(D"2(M%($B)0B!(BT,0QT)(`````$C'0@@`````3(EB +XM$$B):EA(B4(H2(M%8$B)0F!(BT5@2(D02(U"6$B)16#H`.?__TB%P$B)P@^$ +XML````$C'``$```!(QT`0`````$B)YDB+0PA,B>=(B4((2(M#$,="(`$```#' +XM0B0!````2(E"&.A,Y___2(7`#X2-````QT0D!`$```!(BS-,B>_H9/[__TB) +XMYDR)Y^@UZO__A<`/A(4```!(BUL82(7;#X4$____2(/$0%M=05Q!74%>P[__ +XM____Z*GF__^^WVY``$B)PK]&````,<#H!>?__[[,:D``OT8````QP.A4Z?__ +XMO______H>N;__[X^;D``2(G"OT8````QP.C6YO__O______H7.;__[[W;D`` +XM2(G"OT8````QP.BXYO__O______H/N;__[Y7;D``2(G"OT8````QP.B:YO__ +XM9F9FD&9F9I!F9I!F9I!52(G]4TB#[`B+=U"%]G0'2(-_&`!T;#';ZTMF9I!F +XMD$B+?1#HL^7__TB%P$B)P@^$A@```(M-4(7)=4Y(BP-(B0)(BT,02(E"$$B+ +XM0PA(B4((BT,@B4(@2(M#&$B)0AB+0R2)0B1(BWT(2(G>Z"KE__](ARH````28G\2(GW2(UT)$!(BY,B>=( +XMB00D2(M$)$A(B40D"$B+1"102(E$)!!(BT0D6$B)1"082(M$)&!(B40D($B+ +XM1"1H2(E$)"A(BT0D<$B)1"0P2(M$)'A(B40D..CX^___2(GF2(G?Z,GG__^% +XMP'1D2(N<)(@```!(BZPDD````$R+I"28````3(NL)*````!(@<2H````P[__ +XM____Z#/D__^^+F]``$B)PK]&````,<#HC^3__[______Z!7D__^^3&]``$B) +XMPK]&````,<#H<>3__[______Z/?C__^^:F]``$B)PK]&````,<#H4^3__V9F +XM9I!F9I!!54%455-(@^Q(2(N?X````$B%VP^$M````$4QY.F2````2(MK($PY +XMY0^"L0```$2+2TA%AR"+>TR%_W5?2(M#0$B#^`AT#4B%P'0(2(MK($@#:RA(BWL02(GFZ*OC__]( +XMA$B+0R!(B>9(B40D&$B+0RA(B40D($B+>Q#HF.;__X7`='1(BUM82(7; +XM=!U)B>Q-A>0/A67___](BVL@2`-K*$B+6UA(A=MUXTB#Q$A;74%<05W#9F9F +XMD&9FD$2+0TA%A<`/A$O___^_P'!``#'`Z-/C___I.O___[______Z-3B__^^ +XMA6]``$B)PK]&````,<#H,./__[______Z+;B__^^:F]``$B)PK]&````,<#H +XM$N/__V9FD&9FD%5(B?U32(/L2$B+?QA(B>;HU^'__TB%P`^$E````+YX```` +XMOP$```#H'^3__TB%P$B)PP^$M0```$B+1"0HN@$```!(B4,@2(N-X````$B% +XMR708,<"#>4P!2(M)6(/0`$B%R77P@\`!2&/02(M](+D!````O@X```#HON+_ +XM_TB%P$B)0RAT24B)WDB)[TC'0S@$````QT-(`````,=#3`$```#H*/;__TB) +XMV$B#Q$A;7<.______^C@X?__OEEJ0`!(B<*_1@```#'`Z#SB__^______^C" +XMX?__OOAJ0`!(B<*_1@```#'`Z![B__^^S&I``+]&````,<#H#>+__Y!!54&) +XMU4%428G\54B)]5-(@^P(2(N?H````$B%VW4+ZR9(BUM`2(7;=!U(BS-(B>_H +XMQ^+__X7`=>A(@\0(2(G86UU!7$%=PS';187M=.N_2````.CTX___2(7`=#9( +XMB<.Z2````#'V2(G'Z#WB__](B2M(QT-``````$F+A"2H````2(D82(U#0$F) +XMA"2H````ZZ:^HV]``+]&````Z&KA__]F9F:09F9FD&9FD&9FD#'22(/L".A% +XM____,=)(A[SIG3CN[5O +XM0`!)B>1(QP0DM6]``$C'1"0(O&]``$C'1"00SF]``$C'1"08U&]``$C'1"0@ +XM`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G?Z.;B__](B=Y(B<)(B>_H2-__ +XM_X7`==A!BT5H@^@!@_@!=PJX`0```.E!____08M%1(7`=0Q!BT5(A<`/A"O_ +XM__\QTDB)[DR)[^C1_?__18ME1$6%Y'4C08M=2(7;#X0)____2(7`=+M$BU@L +XM187;#Y3`#[;`Z?3^__](A_H..+__T@YPW7>2(GF2(GOZ"C?__](A<`/A)H```"+%"1(BW0D +XM2$F+?"08Z&W?__](A__^%P`^$:P(``$4Q]DB+?1A,B?;HS-W_ +XM_TB%P$F)Q@^$K`$``$B)YDR)]^C%W?__2(7`#X33`0``BQ0D2(MT)$A(BWT8 +XMZ`O>__](A_HR/S__X7`=:B+1"0$@_@)#X3+```` +XM@_@$#X3"````0;_5;D``N0H```!,B>;\3(G_\Z8/A;S +XMIG4$2(E=6$B)WDB)[^BA\/__Z=#^__^+="0LA?8/A#+___](B>_H*/W__X7` +XM#X6T_O__Z1W___^^>````+\!````D.CGW?__2(7`#X3O````2(G#3(D@3(EP +XM"$B+1"082(G>2(GO2(E#($B+1"0@2(E#*$B+1"0P2(E#.(M$)`1(B4-`Z,H- +XM``")0TCIZ_[__V:02(M3$$B+](BPOHO?;__^DL____Z(_>__^%P)`/ +XMA;0```!(@\186UU!7$%=05Y!7\.______^BMV___OCUP0`!(B<*_1@```#'` +XMZ`G<__^______^B/V___O@MP0`!(B<*_1@```#'`Z.O;__^______^AQV___ +XMOO5O0`!(B<*_1@```#'`Z,W;__^______^A3V___OB=P0`!(B<*_1@```#'` +XMZ*_;__^^S&I``+]&````Z`#>__^______^@FV___OMIO0`!(B<*_1@```#'` +XMZ(+;__^)Q^@+V___OJYN0`!(B<*_1@```#'`Z&?;__]F9F:09F9FD&9FD%5( +XMC2PW4TB#[`A(.>]S>TB)^^LXBP7&01``AM(B09U +XMPDB#Q`A;7<-(BS5801``OPH```#HVMG__^N?2(LU14$0``^^^NC)V?__ZXX[ +XM1BA\"(#Z"F9FD'6RZ*7<___I=____[\*````Z);<___I:/___V9FD&:005=! +XM5D%505154TB![-@```!(B7PD&$R+M^````!-A?8/A/\```!(C80DH````$B- +XME"3`````2(D$)$B)5"0(ZPU-BW98387V#X37````08M63(72=>M)BQZ_Q6Y` +XM`+D(````_$B)WO.F=-:_S6Y``+D(````2(G>\Z9TQ;_5;D``N0H```!(B=[S +XMIG2T2(M,)!B#>6@!#X2;````2(M\)!A(B=[HI_C__X7`#X1P`P``,=M%,?]( +XMQT0D6`````#K.4B+?"182`-[&.CMV___28G'387_#X3\`P``2(M$)%A(BU,8 +XM2(MS"$F-/`?H"]S__TB+4QA(`50D6$F+?@A(B=[HAMC__TB%P$B)PP^$C@`` +XM`$V%_W6J2(M[&.BO^__],B??H#?'__TB+5"08BT)L@^`P@_@0=1M)BT9`2(/X"70&2(/X +XM!'4+28-^*``/A?`!``!)BS9(BWPD&#'2Z%/U__](A<`/A!O]__^+0#"%P`^$ +XM$/W__TF+?AA(A?]T#4F+=BA(A?8/A?0````QV^L-2(MS&$B+>PCHR/O__TF+ +XM?@A(B=[H*-;__TB%P$B)PW7?Z%O9__^%P`^%$08``(L%@3T0`(7`#X5A`0`` +XM2(LU@CT0`(M&#(/H`87`B48,#XCZ/+T__^%P`^$I?[__^EV_/__ +XM9F:09I#HV_K__^DO____28LV2(M\)!@QTN@7]/__3(M@&$R)Y^C7V/__2(M\ +XM)%!(`WPD6$B)PDR)YDB)P^@/UO__2`-<)%A(BTPD4,8$"P!(@\,!2(E<)%CI +XMD)_?__OFIP0`"_1@```#'`Z/37__](BS4A/!`` +XMOPH```#HH]3__^E#^___28M^$$B-="1@Z%#5__](A<`/A&$%``!(BTPD&(N< +XM)(@```!(BT%02(MX".@NV/__2#G##X77_?__28M^$#'VZ$K4__](AT))@```!(A`@2`'02(GRB=Y(B80DJ````.B"U___A,/A#/]__])@WY`"76.2(V4),````")WDB)[^B8U___2#M$)`A(B<8/ +XMA9($``!(BWPD&$B+E"3(````2(M'>$B)T8/B_TC!Z2!(B>](BP3(2,'@($@! +XMT$B)\HG>2(F$),@```#HW]/__X7`=8V______^C!T___OIQP0`!(B<*_1@`` +XM`#'`Z!W4__^028L>0<=&4`$```!)QT8H`````.DD^O__2(M4)!B+G"2(```` +XM2(M"4$B+>`CHR];__T@YPP^%]_K__TF+?@@Q]NCGTO__2(7`2(E$)"`/A+D# +XM```QTDB+A"2`````2/>T))@```!(A`CH(];_ +XM_TB)QDB+1"082(G:2(MX&.AOT___2(7`2(GU`@``2(M\)!CHG0@``(7` +XM=&)(BU0D&(-Z%`$/A*L```!)@WY`"0^$"0$``$V%Y`^$C`$``$DY[&9FD`^# +XM60$``$B+?"0H2XT$9$B-%,=(BX0DH````$B)`DB+A"2H````2(E""$F#?D`$ +XM#X3@`0``28/$`4F#Q0%,.VPD$`^$.P,``$F#?D`)#X4>____2(M\)"!(C90D +XMP````$2)[NB4U?__2#M$)`@/A!W___^______^C_T?__OE-P0`!(B<*_1@`` +XM`#'`Z%O2__])@WY`"0^$T@$``$V%Y`^$J0$``$DY[`^#>`$``$B+?"0P2XT$ +XM9$B-%(=(BX0DH````(D"2(N$)*@```")0@1)@WY`!`^%6O___TB+A"2P```` +XMB4((Z4K___^_"@```.@'U/__Z;?W__]-A>1F9I`/A,8```!).>QF9F:09F:0 +XM#X./````3(G@2(N4),````!(P>`$2`-$)#A(B1!(BY0DR````$B)4`A)@WY` +XM!`^%\?[__TB+A"2P````2(M,)"A+C11D2(E$T1#IUO[__T@![4B+?"0H2(GN +XM2,'F!.@YT?__2(7`#X3$`0``2(E$)"CI@/[__TB)[TC!YP3HFM/__TB%P`^$ +XMM@$``$B)1"0HZ57^__](`>U(BWPD.$B)[DC!Y@3H\]#__TB%P`^$?@$``$B) +XM1"0XZ4K___](B>](P><$Z%33__](A<`/A'`!``!(B40D..D;____OMMI0`"_ +XM1@```.A2T___B]#__[X5;T``2(G"OT8````QP.C7T/__2(N$)+````!( +XMB4(0Z0_^__](`>U(BWPD,$B--.T`````Z''0__](A<`/A/P```!(B40D,.E@ +XM_O__2(T\[0````#HT=+__TB%P`^$[0```$B)1"0PZ3?^__]-A>0/A)H!``!) +XM.>P/@VT!``!(BY0DP````$N-!.>)$$B+E"3(````B5`$28-^0`0/A9']__]( +XMBX0DL````$B+3"0P2XT49(E$D0CI=_W__[______Z+3/__^^]6]``$B)PK]& +XM````,<#H$-#__[______Z1;___^______^B,S___OEEJ0`!(B<*_1@```#'` +XMZ.C/__^______^ANS___OH-P0`!(B<*_1@```#'`Z,K/__^______^A0S___ +XMOCYN0`!(B<*_1@```#'`Z*S/__^^='!``+]&````,<#H^]'__[[;:4``OT8` +XM```QP.CJT?__13'_2,=$)#@`````2,=$)#``````2,=$)"@`````13'DZ+31 +XM__^%P(G'#X5J_O__2(M$)!B#>!0!#X2.````28-^0`E(BU0D.$@/150D*$F) +XM5AA(BTPD&#'V28-^0`E,B>)(BWD@N0$```!`#Y7&@\8,Z$//__])BQY)B48H +XM0<=&4`$```#I'_7__T@![4R)_TB--.T`````Z*S.__](A<`/A#?___])BL.08/$`40Y +XM92@/CI4```!(BWT83(GR1(GFZ`G.__],.?`/A8H```!(BWT@2(GB1(GFZ/'- +XM__],.>AU=HM$)$!(B>)$B>:)!"1(BT0D4$B)1"002(M$)%A(B40D&(M$)$2) +XM1"0$2(M$)'!(B40D,$B+1"1(2(E$)`A(BT,(2(E$)"!(BT,02(E$)"A(BWT@ +XMZ(3.__^%P'0X2(M;.$B%VP^%7?___TB#[(!;74%<05U!7L.______^C,R___ +XMO@=Q0`!(B<*_1@```#'`Z"C,__^______^BNR___OA]Q0`!(B<*_1@```#'` +XMZ&K.__^______^B0R___ONUP0`!(B<*_1@```#'`Z.S+__^______^ARR___ +XMOA!K0`!(B<*_1@```#'`Z,[+__]FD$%455-(B?M(@^Q`2(M_&$B-="0XZ#/+ +XM__^%P`^$Y@```$B+1"0X2(7`B4,HB4,L#X2:````,>U)B>1F9I!F9I!(BWL8 +XM2(GBB>[HKLS__TPYX`^%@0```+Y`````OP$```#HILS__TB%P$B)P@^$A``` +XM`$B+1"0(2(/%`4B)`DB+1"0@2(E""$B+1"0H2(E"$(L$)$C'0B@`````2,=" +XM.`````!(B4(82(U"*$B)0C!(BX.8````2(D02#EL)#A(C4(X2(F#F`````^' +XMPH`@``2(M'4$B)1"0P2(M76$B)5"0X2(M0$$B+<`CHB./__TB+ +XM3"0X3(GO2(M1$$B+<0BYS6Y``.ANX___2(M<)#!(C;0D@`$``$B+>Q#HQ,C_ +XM_TB%P`^$KQ(``$B+1"0X2(VT)$`!``!(BW@0Z*7(__](A<`/A)`2``!!]D5L +XM(`^%R@4``$F+?1A(C;0D&`(``.CPR/__A<`/A"06``!)BWT@Z"_*__^%P(E$ +XM)$0/A-$5``"^`0```+\P````Z+3)__](ARO__ +XM2(7`#X32%0``2(E$)$C&``"^`0```$&+?3"#QP>-1P>%_P](^,'_`TAC_^AN +XMR?__2(7`28F%B`````^$714``$R-I"0``0``,=LQ[69FD&9FD$F+?1A(B=[H +XMT,?__TB%P$B)PP^$.0X``$R)YDB)W^C)Q___3#G@#X6W#@``BY0D``$``$B+ +XMM"08`@``28M]&.@(R/__2(7`2(G%#X1U#@``_+_-;D``N0@```!(B<;SIG6> +XM2(G?Z(+*__](B40D8.CHR?__A<`/A;04``!(@WPD8``/A(`4``!,C:0D``$` +XM`#';28M]&$B)WN@^Q___2(7`2(G#=$Y,B>9(B=_H.\?__TPYX`^%*0X``(N4 +XM)``!``!(B[0D&`(``$F+?1CH>L?__TB%P$B)Q0^$YPT``$&_Q6Y``+D(```` +XM2(G&_$R)__.F=9[H8\G__X7`#X4O%```2(7;#X3^$P``,=)(BX0D(`$``$CW +XMM"0X`0``2(7`2(E$)"@/A:\%``!(QT0D<`````!(QX0DN````$````!(QT0D +XM4`$```!)BYW@````2(7;#X2Q`0``0;_%;D``ZPU(BUM82(7;#X2<`0``3(L# +XMN0@```!,B?_\3(G&\Z9TX+_-;D``N0@```!,B<;SIG3/O]5N0`"Y"@```$R) +XMQO.F=+Y!]D5L!'002(M#0$B#^`ETK4B#^`1TITB+>Q#H*LG__TF+E8@```!( +XMB<%(P>D##[84"HG!@^$'T^J#X@%U@,>$).`!````````2,>$).@!```````` +XM2,>$)/`!````````QH0DY`$```-(BWL(Z-C(__^#?"1$`6:)A"3F`0``#X2Q +XM#0``28M6$$B%T@^$JA(``$B+C"2X````23M.*`^&"@\``(N$).`!``"%P`^% +XM`PT``$F+1BA(C01`QP3"`````$F+1B@/MI0DY`$``$F+3A!(C01`B%3!!$F+ +XM1B@/MI0DY0$``$F+3A!(C01`B%3!!4F+1BA)BTX02(N4).@!``!(C01`2(E4 +XMP0A)BT8H28M.$$B+E"3P`0``2(T$0$B)5,$0#[>,).8!``"-0?]F/?[^#X=G +XM#```28M%<$F+5B@/M\E)BW802(L$R$B-%%)FB436!DF#1B@!2(M;6$B%VP^% +XM9/[__TB#?"1P`'152(-\)"@`=$,QTC'VZP202(GRB?!(BUPD<(GQP?@#@^$' +XM2)@/M@08T^BH`7032(T$U0````!)`T5X28M6*$@!$$B#Q@%(.W0D*'7$2(M\ +XM)'#H1L?__S'`@WPD1`%)BU8@28M-4`^5P$D#5BA(C03%$````$@/K\)(B4$H +XM28M%4$R)R@`#X6]`@``2(-[(``/A4L"``!(BTPD.$B+>1#H@$))`!````````,$)(0!```"````2,>$ +XM)(@!````````2(F$)*`!``!)BWT@Z+7#__](BTPD,$B)A"2X`0``2(G>2(MY +XM$.A,P___2#G8#X4Z"@``3(V\),`!```QVT4Q]DB+1"0P2(G>2(MX$.A5PO__ +XM2(7`2(G#='PQTDB+0QA(][0D^````$B%P$B)Q73113'D0;T!````3(GZ1(GF +XM2(G?Z/##__],.?@/A?D,```/MH0DQ`$``,#H!(3`10]$]4F#Q`%)@\4!23GL +XM=)/KR4B+?"0PZ%'<__](BWPD..A'W/__2('$*`(``%M=05Q!74%>05_#Z`S% +XM__^%P`^%Z!```$B+5"0X1(FT)*P!``!(C;0D@`$``$C'A"10`0```````$C' +XMA"1P`0```0```$B+3"0P2(M"*,>$)$0!```#````2,>$)$@!````````2,>$ +XM)'@!````````QX0D;`$```````#'A"1H`0```````$B)A"1@`0``2(MY$.@D +XMQ?__A`#2(E"$$B+0QA(B4(( +XM2(M#(,="(!(```#'0B0!````2(T$0$C!X`-(B4(8Z4[]__](BW@0Z-3`__]( +XMAG\__](BWPD*+X(```` +XMZ&3"__](AH#2(G72(F4)(`` +XM``#H-<+__TB%P$B)1"1X#X0F#@``2(M,)'@Q]DB)WTB)3"1PZ..___](A$)+@```!`````2,=$)%`!````0;\``@``2,>$)*@````````` +XM2,>$)+``````````2(E<)!A(B40D$$B)%"1(B4PD"(N$)+````!(BWPD:$B- +XME"3@`0``B<:)A"2D````Z!3!__](.T0D&`^%&PH``(N4).`!``!)BWT82(MT +XM)&#H5,#__TB%P$B)Q0^$P08``$B)QDR)[^B!]?__A<`/A><```!)BYW````` +XM2(7;=0OK24B+6PA(A=MT0$B+,TB)[^C#P/__A&X`0```-/@"`0:28M5>$F+1B!(BXPDJ````$B)!,J#?"1$`0^$ +XMR@$``$B-O"3@`0``Z!;T__^%P`^$E`(``$F+5A!(A=(/A)4'``!(BX0DN``` +XM`$D[1B@/A@<%``"+O"3@`0``A?\/A(X#``"`?0``#X2$`P``28M&*(M,)%!( +XMC01`B0S"28M&*`^VE"3D`0``28M.$$B-!$"(5,$$28M&*`^VE"3E`0``28M. +XM$$B-!$"(5,$%28M&*$F+3A!(BY0DZ`$``$B-!$!(B53!"$F+1BA)BTX02(N4 +XM)/`!``!(C01`2(E4P1`/MXPDY@$``(U!_V8]_OX/AC,#``!)BT8H28M6$$B- +XM!$!FB4S"!DF#1B@!#[:$).0!``"#X`^#^`,/A)$"``"`?0``#X39_?__ZQY( +XMBWPD2$T!_TR)_NA6O?__2(7`#X0(!```2(E$)$A(B>_H0,#__TB+5"102(G! +XM2`'"28U'_T@YPG/&2(M<)$A(`UPD4$B)RDB)[DB)W^ADO?__2(GOZ`S`__]( +XMB>_&!`,`Z`#`__](BUPD4$B-7`,!2(E<)%#I7?W__TB-O"3@`0``Z(/R__^% +XMP`^%-_[__P^VA"3D`0``P.@$/`(/A`$B%0(#$F+1B@/MI0DY0$` +XM`$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4"`1)BT8H28L.2(N4 +XM)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&,0,``$F+1BA)BQ9(P>`$ +XM9HE,$`[I._[__TF+5AA(A=(/A*(%``!(BT0D6$D[1B`/ACT"``"+M"3@`0`` +XMA?8/A.D```"`?0``#X3?````28M&((M,)%!(C01`B0S"28M&(`^VE"3D`0`` +XM28M.&$B-!$"(5,$$28M&(`^VE"3E`0``28M.&$B-!$"(5,$%28M&($F+3AA( +XMBY0DZ`$``$B-!$!(B53!"$F+1B!)BTX82(N4)/`!``!(C01`2(E4P1`/MXPD +XMY@$``(U!_V8]_OX/AH$```!)BT8@28M6&$B-!$!FB4S"!DF#1B`!#[:$).0! +XM``"#X`^#^`,/A6_]__\/MY0DY@$``$F+17!(BPS0N`$```!(BH# +XM20.5B````-/@"`+I0/W__TF+1B!(C01`QP3"`````.D<____28M&*$B-!$#' +XM!,(`````Z7?\__])BT5P28M6(`^WR4F+=AA(BP3(2(T44F:)1-8&Z6____]) +XMBT5P28M6*`^WR4F+=A!(BP3(2(T44F:)1-8&Z;W\__])BU8(2(72#X2_!@`` +XM2(M<)%A).UX@#X8R`P``1(N$).`!``!%A8# +XMZ%6Y__](A8#Z!FY__](A($9HE$,@[I__K__TF+1BA)BU802(T$0&:)3,(& +XMZ9_S__^`?0``#X3S\O__28M&*(M,)%!(C01`B0S"Z>[R__])BT8@BTPD4$C! +XMX`2)#!#I//[__TF+1BB+3"102,'@!(D,$.GB^___2,<`!````$B+0RA(P>`$ +XM2(E"$$B+0PA(B4((2(M#(,="(!(```#'0B0!````2,'@!$B)0ACI]?/__TF+ +XM%DB%T@^$,08``$B+C"2X````23M.*`^&?00``(N,).`!``"%R0^$^P```(!] +XM```/A/$```!)BT8HBTPD4$C!X`2)#!!)BT8H#[:4).0!``!)BPY(P>`$B%0( +XM#$F+1B@/MI0DY0$``$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4 +XM"`1)BT8H28L.2(N4)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&C0$` +XM`$F+1BA)BQ9(P>`$9HE,$`[I4_+__T@!P$B)UTB)QDB)A"2X````2,'F!.@. +XMM___2(7`2(G"28D-^O__Z;7]__](`=M(B==(B=Y(B5PD6$C!Y@3HX[;_ +XM_TB%P$B)PDF)1@@/A:?\___IB?W__V:028M&*$C!X`3'!!``````Z0K___]( +XMBYPDN````$B-/%M(P><#Z".Y__](A8#Z&&V__](A($9HE$,@[IN_#__TB+O"2`````O@$```#H_K;__TB% +XMP$F)A8`````/A.T"``!)BWT82(VT)!`"``#H[;7__X7`#X0A`P``13'D28M] +XM&$R)YNA6M?__2(7`28G$#X2'`@``2(VT),````!,B>?H2K7__T@[1"00#X4V +XM_/__BX0DQ````(/X"70%@_@$=;R+E"3`````2(NT)!`"``!)BWT8Z':U__]( +XMA_H-M3__X7`=8R+M"3L````3(GOZ'/5__^%P`^%=?__ +XM_TF+15"+G"3H````2(MX".C3M___2#G#2,>$))``````````2,>$))@````` +XM````#X5`____2(N,))````!(.XPDX`````^#KP(``$B+M"28````3(GGZ+RS +XM__](AT)/@```"%P$B) +XMPWZLQX0DC`````````"#O"3$````"0^$H`(``(NT)(P```!(B[PDF````$B- +XME"3``0``Z+FU__](.P0D#X6Q`@``BX0DS`$``$B)A"20````2(.\))`````` +XM#Y7`="-(BU0D*$@YE"20````#X+7`0``A,!T#+_,<4``,<#H?[3__X.$)(P` +XM```!.9PDC`````^$&/___^ER____2(N\)+@```!(P><$Z!2V__](A;Y___HMK7__X7`B<=(QX0DN````$````!(QT0D4`$````/A(/L___H +XMTK+__[Z'<4``2(G"OT8````QP.@NL___2(N$)+@```!(C3Q`2,'G`^A9M?__ +XM2(7`2(G"28E&$`^%0^W__^DQ_/__OFQQ0`"_00```#'`Z/.R___H/K7__X7` +XMB<=U#DF+E8````#I=//__XG'Z&6R__^^KFY``$B)PK]&````,<#HP;+__[[, +XM:D``OT8```#H$K7__[______Z#BR__^^4W%``$B)PK]&````,<#HE++__[[, +XM:D``OT8````QP.CCM/__OMMI0`"_1@```.C4M/__O______H^K'__[[:;T`` +XM2(G"OT8````QP.A6LO__O______HW+'__[[A<4``2(G"OT8````QP.@XLO__ +XM2(N$))````"+C"20````N@$```!(P>@#20.%@````(/A!]/B"!#I#O[__^A8 +XMM/__A<")QP^$;/S__V:0Z;#^__](B[PDN````$C!YP3H)K3__TB%P$B)PDF) +XM!@^%P?G__^G_^O__9F:09F:0BQA) +XMB<5-B?Y,`W,H33GW_HQ;/__TDYQ4B)PW?F +XM3"GH2(LT)$R-)"A,B>?HVK'__X7`=<](@\0(1(G@6UU!7$%=05Y$*?A!7\-( +XM@\0(N/____];74%<05U!7D%?PY!!5T%6055)B?U!5%532(/L&$B)-"1(BV\H +XM2(7M28GN=29(QT2`,T).C3L/__A7!E +XM`&5L9E]G971S:&YU;2!F86EL960Z("5S`&-A;&QO8R!F86EL960`9V5L9E]U +XM<&1A=&5?96AD6UB;VP`;W5T +XM<'5T+69I;&4`<')E2!A;F0@6UT86(`+G-T"!I;F1E>`!E;&9?;F5W +XM9&%T82@I(&9A:6QE9#H@)7,N`"1&'`@ +XM)``!&___&`,0````````````````````````````GFE````````````````` +XM`%A\4`````````````````#::T````````````````````````````!H```` +XM`````-]K0````````0```````````````````$L`````````ZVM````````! +XM````````````````````;P````````#W:T`````````````````````````` +XM``!P``````````9L0````````0```````````````````%(`````````%6Q` +XM````````````````````````````E(` +XM`7@0`0,,!PB0`0``'````!P```!0&T``DP````!"#A",`D4.&$$.((,$A@,4 +XM````/````/`;0``X`````$0.$``````4````5````#`<0``B```````````` +XM```4````;````&`<0``I`````$0.$``````4````A````)`<0``I`````$0. +XM$``````4````G````,`<0``I`````$0.$``````D````M````/`<0`"/!@`` +XM`$J/`H8&80[@`8X#C02,!8,'````````-````-P```"`(T``<`@```!"#A"/ +XM`D4.&(X#2@X@0@XH00XP00XX1P[0`8,'A@:,!8T$```````4````%`$``/`K +XM0`!]```````````````<````+`$``'`L0`"V`0```$J#!8P#40YPC0*&!``` +XM`"0```!,`0``,"Y```!`!`PP'")`!```` +XM````%````"`````0:4``)0````!(#A"#`@```0`````````!``````````$` +XM````````Q@$````````,`````````,@60```````#0`````````X:4`````` +XM``0`````````^`%````````%`````````-`+0```````!@````````!0!$`` +XM``````H`````````#P,````````+`````````!@`````````%0`````````` +XM``````````,`````````:'Q0```````"`````````)`&````````%``````` +XM```'`````````!<`````````.!!````````'`````````,`/0```````"``` +XM``````!X``````````D`````````&`````````#^__]O`````(`/0``````` +XM____;P`````"`````````/#__V\`````X`Y````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````````````````````````````````#_________ +XM_P``````````__________\`````````````````````H'I0```````````` +XM````````````````\A9````````"%T```````!(70```````(A=````````R +XM%T```````$(70```````4A=```````!B%T```````'(70```````@A=````` +XM``"2%T```````*(70```````LA=```````#"%T```````-(70```````XA=` +XM``````#R%T````````(80```````$AA````````B&$```````#(80``````` +XM0AA```````!2&$```````&(80```````6YC7W-E8W1I;VYS`"(1``!I;G-E5]C;VYT96YT``````!! +XM`````@!^+@``W`D``'$(``!A9&1?=&]?:6YS96=?;&ES=`#W"```8V]P>5]P +XM:&1R`'P)``!S971U<%]P:&1R``````!C`````@!:.```!1,```L,``!L;V]K +XM=7!?:V5E<%]S>6UL:7-T`&8,``!A9&1?=&]?6`@```TP&```".8,````" +XM"`5=`P```X8"```".I4````""`>1`@```@@$AP,```($!*D#```#]00```)2 +XMB@````,\!0```E1X````!0@'!@@#?`$```,F9@````,5`P```R=X`````[0& +XM```#*68````#B0````,L9@````,T`P```RYF`````PT"```#,4(````#70<` +XM``,S0@````,(!0```S1X`````W`&```#/F8````#&@$```-;9@````(!!K(! +XM```#_`$```190@````-/`P``!%YF`````X@"```$8XH````'"#,!```'"&U````"7(&```$"`$=`0``"MT%```0 +XM!2X/`@``"X<'```%+\\!```"(P`+\`4```4P@P````(C"``*U@```'@&@PH# +XM```+V`0```:$*`$```(C``M-!P``!H68`0```B,$"V@&```&AJ,!```"(P@+ +XM@P0```:'K@$```(C"@N0`0``!HC:`0```B,,"V0"```&B8T!```"(Q`+O@$` +XM``:**`$```(C%`O9!0``!HSF`0```B,8"R`#```&C>8!```"(R@+8`4```:. +XMY@$```(C.`NK`@``!I>Y`0```B-("S8````&F')`P```B,`#%]R``AH +XM7P````(C"`Q?=P`(:5\````"(PP+?0H```AJ.P````(C$`NN!@``"&L[```` +XM`B,2#%]B9@`(;&`#```"(Q@+0P8```AM7P````(C*`M)`@``"'##`````B,P +XM"_,!```(<<,$```"(S@+L@0```ARXP0```(C0`O2!```"',#!0```B-("TD` +XM```(=",%```"(U`,7W5B``AW8`,```(C6`L`````"'@O!0```B-H#%]U<@`( +XM>5\````"(W`+1@0```A\-04```(C=`N;````"'U%!0```B-W#%]L8@`(@&`# +XM```"(W@++0````B#7P````,CB`$+=PD```B$50,```,CD`$`#0%?````PP0` +XM``[#``````<(LP0```T!7P```.,$```.PP````Y;`0``#E\`````!PC)!``` +XM#0%5`P```P4```[#````#E4#```.7P`````'".D$```-`5\````C!0``#L,` +XM```.80$```Y?``````<("04```_M`@```0<(*04``!`T````104``!'````` +XM`@`0-````%4%```1P````````Z8"```(A8\#```""`58`P``$#0```!W!0`` +XM$<`````/``/[`@``"290`0```Y0&```!%7$#```"%7$'```#%=L````$`!0$"C9=!P``%3$%````%9H'```! +XM%>8%```"%;$%```#%H````3%>$"```4%7P#```5%0X!```6%?X$```7`!0$ +XM"E6T'```+MPH```PB80$```(C``M>!```#"2M +XM!P```B,(``<(Q`<``!((##8*"```"U8%```,-K\(```"(P``"F8#``!(#"B_ +XM"```"[<*```,*6$!```"(P`+H@$```PJ80$```(C"`M!`@``#"MA`0```B,0 +XM"X4-```,+&$!```"(Q@,861D``PN7P````(C(`M;`0``#"]?`````B,D"\D' +XM```,,%\````"(R@+404```PQ7P````(C+`O9`0``##)?`````B,P"V\````, +XM,U\````"(S0+5P0```PT7P````(C.`NB!```##;S!P```B-```<("@@``!(( +XM##_<"```"U8%```,/R$)```"(P``"@<&```@##HA"0``"[<*```,.UL!```" +XM(P`+=`H```P\6P$```(C"`L`"```##W$`0```B,0"Z<````,/\4(```"(Q@` +XM!PC<"```$A`,44P)```+5P4```Q1&@H```(C``LX`@``#%$@"@```B,(``JD +XM"0``>`Q#&@H```NW"@``#$1A`0```B,`#&ES``Q%G`<```(C"`QO=`H```O7`@`` +XM#%X:"@```B,`"P0'```,7B`*```"(P@`$@@,7XL*```+5@4```Q?^@H```(C +XM```*NP(``$`,5OH*```,;V9F``Q74`$```(C``QF@`,65`!```"(Q`+W0@```Q:4`$```(C&`MO````#%Q?`````B,@"X@'```, +XM7DL*```"(R@+3@L```Q?=`H```(C.``'"(L*```4!`R-)PL``!5B`0```!40 +XM!0```14W!@```A7X!0```Q43!@``!``2$`RI3`L```O6`@``#*GZ"@```B,` +XM"P,'```,J4P+```"(P@`!PCZ"@``$A`,JG<+```+U@(```RJOP@```(C``L# +XM!P``#*IW"P```B,(``<(OP@``!(0#*NB"P``"]8"```,JR$)```"(P`+`P<` +XM``RKH@L```(C"``'""$)```2$`RMS0L```O6`@``#*WM!P```B,`"P,'```, +XMKU\````" +XM(RP,;F]S``Q]7P````(C,`LQ!```#()?`````B,T"T\!```,@U\````"(S@+ +XMO0<```R$7P````(C/`O-`0``#(5?`````B-`"V,````,AE\````"(T0+104` +XM``R'7P````(C2`O@#```#(D:"@```B-0"VH-```,BAH*```"(U@+Y@D```R+ +XM&@H```(C8`M^!@``#),`"P```B-H"WX*```,FU\````"(VP+KP<```R>Z@T` +XM``(C<`OS!@``#*'J#0```B-X"^T&```,I(D#```#(X`!"U0'```,IXD#```# +XM(X@!"S`!```,J2<+```#(Y`!"P<````,JE(+```#(Z`!"S8!```,JWT+```# +XM([`!"W@&```,K:@+```#(\`!"XP$```,K],+```#(]`!"X@'```,L?@+```# +XM(^`!``<(>P8```<(4`$``!8W!P``!`$L#PX``!7&`````!5V`````14/!@`` +XM`@`7>P<```%:`@%@'$```````(D<0````````````!<&`P```5,"`9`<0``` +XM````N1Q````````X````%[@````!3`(!P!Q```````#I'$```````'`````8 +XM/P<```$,`0$!F0X``!EE8W```0L!F0X``!EI9F0``0L!7P```!EO9F0``0L! +XM7P`````'"!T,```:&`````&(`0'D#@``&V5C<``!AYD.```J`8```$O`0'P +XM'$```````'\C0```````J````/D/```?96-P``$N`9D.``#A````'W-R8P`! +XM+@%A`0``*@$``!]D04```$R`<0!```A:69D``$S`5\```#&`P``(6]F9``!,P%?````(@0``"-F +XM#@````````%7`22,#@``)(`.```D=`X``".?#@``H`````$=`22L#@``)3`! +XM```FMPX``,H$```GP@X```.1\'XGS0X```.1L'XFV`X``$P%````````&%T& +XM```!%0(!`5H0```996-P``$4`ID.```H]@(```$4`E\````H$`,```$4`EH0 +XM```IA```"1N$```);`$```F +XMDA```+,+```FGA```.D+```FJA```$4,```MMA```"W"$```+BJ`````X0&```"+[H````)5@8``!`"1E,!```*(@4```)'4P$` +XM``(C``K_!P```DA?`````B,(``<(-`````FC`@``F`)F?0(```M?<``"9U,! +XM```"(P`+7W(``FA?`````B,("U]W``)I7P````(C#`I]"@```FH[`````B,0 +XM"JX&```":SL````"(Q(+7V)F``)L*@$```(C&`I#!@```FU?`````B,H"DD" +XM```"<+@````"(S`*\P$```)QC0(```(C.`JR!````G*M`@```B-`"M($```" +XM<\T"```"(T@*20````)T[0(```(C4`M?=6(``G/D" +XM```"(V@+7W5R``)Y7P````(C<`I&!````GS_`@```B-T"IL````"?0\#```" +XM(W<+7VQB``*`*@$```(C>`HM`````H-?`````R.(`0IW"0```H0?`0```R.0 +XM`0`,`5\```"-`@``#;@`````!PA]`@``#`%?````K0(```VX````#0,!```- +XM7P`````'"),"```,`1\!``#-`@``#;@````-'P$```U?``````<(LP(```P! +XM7P```.T"```-N`````T)`0``#5\`````!PC3`@``#NT"```!!PCS`@``#S0` +XM```/`P``$+4````"``\T````'P,``!"U```````#I@(```*%60$```((!5@# +XM```#C0H```8F[0````,%"```!BG,`````Q$(```&*NT````/-````&(#```0 +XMM0````\`$0@&>H<#```*Q0D```9[,0,```(C``KV"```!GQ'`P```B,$``-& +XM"0``!GUB`P``$0P&@,4#```*Q0D```:!,0,```(C``KV"```!H)'`P```B,$ +XM"D,*```&@SP#```"(P@``V0*```&A)(#```#^P(```$T`,```(C``KV"``` +XM!X4'!````B,(``.L"0``!X:*!0``$1@'B>T%```*Q0D```>*T`,```(C``KV +XM"```!XL'!````B,("D,*```'C/$#```"(Q```^\)```'C;H%```216QF``@F +XM`P8```ZV`P```0,&`0``""<4!@``#@4!```!$P0(-K,&```4,04````4F@<` +XM``$4Y@4```(4L04```,4S`,```04OP8```44C@<```843`0```<4D`4```@4 +XM4`````D4?`(```H4^@````L49P<```P4?@4```T4EP0```X4G`8```\4(0(` +XM`!`4(@$``!$4(@8``!(4Z@```!,4X0(``!04?`,``!44#@$``!84_@0``!<` +XM`^((```(3QH&```1"`AXU08```I6!0``"'A@!P```B,```G5"0``0`AH8`<` +XM``HT"@``"&SX`````B,`"E@)```(;;@````"(P@*$@H```AN^`````(C$`K^ +XM!P``"&_X`````B,8"ML(```(<+,&```"(R`*J@H```AQ<0````(C)`HY"``` +XM"'9F!P```B,H"GP*```(=W$````"(S`*(PD```AXO@8```(C.``'"-4&```' +XM"`D&```#U@D```AYU08```.,'```*MPH```HB"0$```(C``I>!```"B2C!P```B,(``<(N@<``!$("C8` +XM"```"E8%```*-K4(```"(P``"68#``!("BBU"```"K<*```**0D!```"(P`* +XMH@$```HJ"0$```(C"`I!`@``"BL)`0```B,0"H4-```*+`D!```"(Q@+861D +XM``HN7P````(C(`I;`0``"B]?`````B,D"LD'```*,%\````"(R@*404```HQ +XM7P````(C+`K9`0``"C)?`````B,P"F\````*,U\````"(S0*5P0```HT7P`` +XM``(C.`JB!```"C;I!P```B-```<(``@``!$("C_2"```"E8%```*/Q<)```" +XM(P``"0<&```@"CH7"0``"K<*```*.P,!```"(P`*=`H```H\`P$```(C"`H` +XM"```"CT4`0```B,0"J<````*/[L(```"(Q@`!PC2"```$1`*44()```*5P4` +XM``I1$`H```(C``HX`@``"E$6"@```B,(``FD"0``>`I#$`H```JW"@``"D0) +XM`0```B,`"VES``I%9@<```(C"`MO:@H```K7`@``"EX0"@```B,`"@0'```*7A8* +XM```"(P@`$0@*7X$*```*5@4```I?\`H```(C```)NP(``$`*5O`*```+;V9F +XM``I7^`````(C``MF@`*6?@````"(Q`*W0@```I: +XM^`````(C&`IO````"EQ?`````B,@"H@'```*7D$*```"(R@*3@L```I?:@H` +XM``(C.``'"($*```3!`J-'0L``!1B`0```!00!0```10W!@```A3X!0```Q03 +XM!@``!``1$`JI0@L```K6`@``"JGP"@```B,`"@,'```*J4(+```"(P@`!PCP +XM"@``$1`*JFT+```*U@(```JJM0@```(C``H#!P``"JIM"P```B,(``<(M0@` +XM`!$0"JN8"P``"M8"```*JQ<)```"(P`*`P<```JKF`L```(C"``'"!<)```1 +XM$`JMPPL```K6`@``"JWC!P```B,`"@,'```*K<,+```"(P@`!PCC!P``$1`* +XMK^X+```*U@(```JOXP<```(C``H#!P``"J_#"P```B,(`!$0"K$3#```"M<" +XM```*L1`*```"(P`*!`<```JQ%@H```(C"``)(P```/`*;MH-```*E0,```IO +XM"0$```(C``JA````"G)?`````B,("K8'```*U\````"(RP+;F]S``I]7P````(C,`HQ +XM!```"H)?`````B,T"D\!```*@U\````"(S@*O0<```J$7P````(C/`K-`0`` +XM"H5?`````B-`"F,````*AE\````"(T0*104```J'7P````(C2`K@#```"HD0 +XM"@```B-0"FH-```*BA`*```"(U@*Y@D```J+$`H```(C8`I^!@``"I/V"@`` +XM`B-H"GX*```*FU\````"(VP*KP<```J>X`T```(C<`KS!@``"J'@#0```B-X +XM"NT&```*I%,!```#(X`!"E0'```*IU,!```#(X@!"C`!```*J1T+```#(Y`! +XM"@<````*JD@+```#(Z`!"C8!```*JW,+```#([`!"G@&```*K9X+```#(\`! +XM"HP$```*K\D+```#(]`!"H@'```*L>X+```#(^`!``<(^`4```<(^````!73 +XM"@```>(!\"M```````!M+$````````)W"#H.```696-P``'A.@X```%5%G-E +XM8P`!X1`*```!5!=S``'C$`H```%1&/,*```![D,L0`````````<($PP``!D! +XMC`D```&C`P%P+$```````"8N0```````OA```*`.```:96-P``&B`SH.``#W +XM$```&W,``:0#$`H``$`1```<`0L```&E`Z`.``!V$0``'7-H``&F`X('```# +XMD9!_``<(;`<``!D!\@<```%[`P$P+D```````#WPD```%L`P%`+T```````*LO0```````_!(` +XM`%`S0```````&C5```````#4&```(A$``!IE +XM8W```4@".@X``%T9```; +XM$@``$+4````$``<("0$``"(!F`H```$W`5\```!`-T```````(DX0``````` +XMY!X``'X3```C96-P``$V.@X``!T?```DMPH```$V"0$``&8?```KD`4``$`3 +XM```ET```#O(```,;<*```!7PD!```X(0``%VES:``!8(('```#D9!_)6ES +XM``%A9@<``&XA```Q!0D```%B%`$``*0A```Q$0D```%C7P```-PA````,@&( +XM"````?D!L#E```````#%/$```````!(B``"S%```(V5C<``!^#H.``##(@`` +XM)7,``?H0"@``#",``#&W"@```?L)`0``52,``"5IL'```!__@```"3)```,3P* +XM```!__@```#<)```'!$)```!``%?````."4````SDP@```*'`0%?`````]P4 +XM```T7V,``H`(#`0``('-R8P`!>`(#`0``(&5N9``!>`(#`0``.3\( +XM```!>0)?`````#.?"0```=X"`;@````!:Q<``#1S``'=`A`*```[``@```'= +XM`FL7```@:60``=\"H`X``"!B``'@`@,!```@$"%`$``#D1"0```>(" +XM7P`````'"!0!```X7@D```$@`@$!V1<``#1E8W```1\".@X``#1S``$?`A`* +XM```@;W-H``$A`H('```@;"````;4!7P````$,&```.F5C +XM<``!M#H.```HMPH```&T"0$``"IS86,``;:U"````#B>"````X8```V:18```8J```M7A8````U=18``"`(```!E0&7 +XM&0``+8\6```M@Q8``#R`"```/9D6```\*@``/:46``!R*@``,+$6```PO18` +XM`#W'%@``#RL``##3%@``/=T6``#=*P``/><6``#1+```,/$6```O_18```.1 +XML'XP"1<``#<6%P``H`D```%[`BTR%P``+2@7```\X`D``#T^%P``Q2T``#!) +XM%P``,%,7```]7A<``),N````````-6T5``!`"@```9`!,AH``"V'%0``+7L5 +XM```\H`H``#V1%0``W"X``"^=%0```Y'0?B^I%0```Y&P?R^U%0```Y&0?SW! +XM%0``)2\``"_-%0```Y&H?B_9%0```Y&@?B_E%0```Y&8?B_Q%0```Y&0?CW\ +XM%0``NB\``#`(%@``/1(6```\,```/1X6``#1,```/2H6```M,0`````^V1<` +XM`+Y`0```````X4!````````!H@%T&@``+?47```MZA<``"[-0$```````.%` +XM0```````/0`8``!C,0`````W#!@``)`,```!HP$M&A@``#SP#```/208``"L +XM,0``/2\8```N,@``-[,4``!P#0```=D"-M`4``!W,@``+<44````````/SP) +XM```"BMP4```!`4#%!````J`!7P````$!`-@)```"`-X%```(`0T'```!)@L` +XM`.$#``"024```````(5-0```````$`@```(!!JL!```"`0BI`0```@(%NP4` +XM``("!]$&```#!`5I;G0`!$T#```".%L````"!`>6`@```@@%70,```2&`@`` +XM`CIT`````@@'D0(```((!(<#```"!`2I`P``!/4$```"4FD````%"`<&"`(! +XM!K(!```$3P,```->4`````2(`@```V-I````!PB9````!PC"````")D````$ +XM]P0```/HB0````3[`@``!":K````!-<#```$**L````$I@4```0KH`````0P +XM"0``!"VK````"3@$9W`L```1KT@````(C$`J("P``!&S2`````B,8"CP+ +XM```$;?,````"(R`*@`L```1N\P````(C*`I7"P``!&_S`````B,P``0Q"P`` +XM!'#^````"T5L9@`%)HT!```,M@,```$$!@$```4GG@$```P%`0```0T$!57C +XM`0``#A\$````#L\%```!#G8$```"#M\!```##IX#```$#@T````%#L4%```& +XM#LH"```'#BX"```(``<(DP$```1?"P``!B]W`0``!P@T`````@@%6`,```D( +XM!R08`@``"E8%```')$$"```"(P``#T,-```0!R%!`@``"K<*```'(KP````" +XM(P`*7@0```,!```" +XM(P@0;W,`!T;C`0```B,0$&)U9@`'1Y<````"(Q@0;V9F``=(JP````(C(!!S +XM>@`'2:L````"(R@08V%P``=*JP````(C,`HV"@``!TNK`````B,X"MT(```' +XM3*L````"(T`*WP0```=-20````(C2`JQ````!TY)`````B-,"JL$```'3TD` +XM```"(U`*W0H```=1>P,```(C6`HM`P``!U)Z!````B-H``<(H`,```<(;@0` +XM``D0!U*?!```"E<%```'4FX$```"(P`*.`(```=2=`0```(C"``/*`4``!`' +XM7L@$```*UP(```=>;@0```(C``H$!P``!UYT!````B,(``D(!U_?!```"E8% +XM```'7TX%```"(P``#[L"``!`!U9.!0``$&]F9@`'5ZL````"(P`09G-Z``=8 +XMJP````(C"!!MI3@4```(C``H#!P``!ZF@!0```B,(``<(3@4```D0!ZK+!0``"M8"```' +XMJA,#```"(P`*`P<```>JRP4```(C"``'"!,#```)$`>K]@4```K6`@``!ZMU +XM`P```B,`"@,'```'J_8%```"(P@`!PAU`P``"1`'K2$&```*U@(```>M00(` +XM``(C``H#!P``!ZTA!@```B,(``<(00(```D0!Z],!@``"M8"```'KT$"```" +XM(P`*`P<```>O(08```(C"``)$`>Q<08```K7`@``![%N!````B,`"@0'```' +XML70$```"(P@`#R,```#P!VXX"```"I4#```';[P````"(P`*H0````=R20`` +XM``(C"`JV!P``!W-)`````B,,$&EE8P`'=4D````"(Q`0;V5C``=V20````(C +XM%!!E:6X`!W#@(```"(R`*Q@$```=Z20````(C*`HJ +XM!```!WM)`````B,L$&YO"20````(C-`I/`0`` +XM!X-)`````B,X"KT'```'A$D````"(SP*S0$```>%20````(C0`IC````!X9) +XM`````B-$"D4%```'ATD````"(T@*X`P```>);@0```(C4`IJ#0``!XIN!``` +XM`B-8"N8)```'BVX$```"(V`*?@8```>35`4```(C:`I^"@``!YM)`````B-L +XM"J\'```'GCX(```"(W`*\P8```>A/@@```(C>`KM!@``!Z3T`0```R.``0I4 +XM!P``!Z?T`0```R.(`0HP`0``!ZE[!0```R.0`0H'````!ZJF!0```R.@`0HV +XM`0``!ZO1!0```R.P`0IX!@``!ZW\!0```R/``0J,!```!Z\G!@```R/0`0J( +XM!P``![%,!@```R/@`0`'"((!```'"*L````1$0L```%5`0%Q"```$G-E9P`! +XM5$X%```2=``! +XMA\<```#M-```'FD``8A)````$#4````@`08+```!9`%@3$```````(5-0``` +XM````634``!5E8W```6/Q"```SC4``!-S96<``65.!0``'Z`+```!9ND!```# +XMD:!_&,8!```!9\<````7-@``$VD``6A)```````!$P```@")!P``"`$-!P`` +XM`9L,``#A`P``D$U```````#:9D```````&4)```"`0:K`0```@$(J0$```(" +XM!;L%```#^@$```(V30````("!]$&```$!`5I;G0``TT#```".&8````"!`>6 +XM`@```TP&```".7@````""`5=`P```X8"```".HH````""`>1`@```@@$AP,` +XM``($!*D#```#]00```)2?P````4(!P8(`@$&L@$```-.!@```T]M`````_P! +XM```#64(````#3P,```->6P````.(`@```V-_````!PBO````!PCN````"*\` +XM```#]P0```/HGP````((!5@#```#C0H```0FS`````.\#```!"?!`````Q$( +XM```$*LP````)$`2W@P$```I+#0``!+@;`0```B,`"A4-```$N04!```"(P0* +XMJP(```2Z&P$```(C"`H-#0``!+LT`````B,,"O,,```$O#0````"(PT*_`P` +XM``2]$`$```(C#@`##@P```2^)@$```/[`@``!2;7`````YN@$```(C+`KF"@``!5_%`0```B,P"NL( +XM```%8,4!```"(S@``[P(```%8=`!```)$`6#E0(```K%"0``!82.`0```B,` +XM"O8(```%A<4!```"(P@``ZP)```%AG`"```)&`6)TP(```K%"0``!8J.`0`` +XM`B,`"O8(```%B\4!```"(P@*0PH```6,KP$```(C$``#[PD```6-H`(```D8 +XM!;X[`P``"DL-```%O[H!```"(P`*#0T```7`-`````(C!`KS#```!<$T```` +XM`B,%"OP,```%PID!```"(P8*%0T```7#C@$```(C"`JK`@``!<3%`0```B,0 +XM``,U#```!<7>`@``"T5L9@`&)E$#```,M@,```$#!@$```8G8@,```P%`0`` +XM`0T$!C8!!```#C$%````#IH'```!#N8%```"#K$%```##LP#```$#K\&```% +XM#HX'```&#DP$```'#I`%```(#E`````)#GP"```*#OH````+#F<'```,#GX% +XM```-#I<$```.#IP&```/#B$"```0#B(!```1#B(&```2#NH````3#N$"```4 +XM#GP#```5#@X!```6#OX$```7``/B"```!D]H`P``"0@&>",$```*5@4```9X +XMK@0```(C```/U0D``$`&:*X$```*-`H```9LUP````(C``I8"0``!FVM```` +XM`B,("A(*```&;M<````"(Q`*_@<```9OUP````(C&`K;"```!G`!!````B,@ +XM"JH*```&<68````"(R0*.0@```9VM`0```(C*`I\"@``!G=F`````B,P"B,) +XM```&>`P$```"(S@`!P@C!```!PA7`P```]8)```&>2,$```#6P@```@`(2=<````" +XM(R@08V%P``A*UP````(C,`HV"@``"$O7`````B,X"MT(```(3-<````"(T`* +XMWP0```A-5`````(C2`JQ````"$Y4`````B-,"JL$```(3U0````"(U`*W0H` +XM``A1:P8```(C6`HM`P``"%)J!P```B-H``<(D`8```<(7@<```D0"%*/!P`` +XM"E<%```(4EX'```"(P`*.`(```A29`<```(C"``/*`4``!`(7K@'```*UP(` +XM``A>7@<```(C``H$!P``"%YD!P```B,(``D("%_/!P``"E8%```(7SX(```" +XM(P``#[L"``!`"%8^"```$&]F9@`(5]<````"(P`09G-Z``A8UP````(C"!!M +XME0````"(R@**@0```A[5`````(C+!!N;W,`"'U4`````B,P"C$$```(@E0` +XM```"(S0*3P$```B#5`````(C.`J]!P``"(14`````B,\"LT!```(A50````" +XM(T`*8P````B&5`````(C1`I%!0``"(=4`````B-("N`,```(B5X'```"(U`* +XM:@T```B*7@<```(C6`KF"0``"(M>!P```B-@"GX&```(D[$(```"(V@*?@H` +XM``B;5`````(C;`JO!P``")Z;"P```B-P"O,&```(H9L+```"(W@*[08```BD +XMH0L```,C@`$*5`<```BGH0L```,CB`$*,`$```BIV`@```,CD`$*!P````BJ +XM`PD```,CH`$*-@$```BK+@D```,CL`$*>`8```BM60D```,CP`$*C`0```BO +XMA`D```,CT`$*B`<```BQJ0D```,CX`$`!PA&`P``!PC7````!P@T````$:\+ +XM```!00%4````D$U```````"@34````````)W"-8+```2E@#```&W,``>M>!P``'(,,```![``.```<[@P```'MH0L``!MI[% +XM!```&W-Y;0`![]`$```;:60``?`&#@``&VES``'QM`0``!SG"P```?+S```` +XM&VYD>``!\O,````<"`P```'R\P```!MS8P`!\O,````<\P8```'R\P```!P? +XM#````?/S````'`4-```!\_,````(````<9PP```'UX@```!ME8P`!]E0````<$0D```'V5````!MI``'V +XM5````!T_#````9L!``<(1`@```<(N@0``!X>#0```58!5`````%0#@``&F5C +XM<``!5&`,```:@` +XM````(&X,```!@`(!5`````&%#@``(65C<``!?P)@#```(K<*```!?P+H```` +XM&',``8$",04````94PT```%Z`0$5#P``&F5C<``!>6`,```:^@````;9``!?`8.```;B@P```',`50````!1`\``!IE8W````!5`````%?#P``&G,``=_6 +XM"P```![1"P```38!5`````%Z#P``&G,``376"P```"`G#````3H"`!])P`- +XM```@#@```>,!M!(``"@-#0``*<`.```J&`T``-0[```K(0T``"HL#0``R#P` +XM`"PW#0```Y&@?2Q"#0```Y&`?RI-#0``@#T``"I7#0``.#X``"IA#0``S3X` +XM`"IL#0``,3\``"MW#0``*X(-```JC`T``%0_```KEPT``"JB#0``S3\``"JM +XM#0``%$(``"JX#0``7T,``"K##0``GT0``"K.#0``-$4``"K9#0``F$4``"KC +XM#0``YT4``"KN#0``[D8``"WW#0``:%%````````N#`X``"`4```!<@$H1`X` +XM`"@[#@``*#(.```H*`X``"@=#@``+U`.```W6$```````%U80````````5O1 +XM$0``,&X.```11P``*&(.```Q-UA```````!.6$```````"IZ#@``1T<````` +XM,H4.``#P%````6=4$@``,)T.``#O1P``*)(.```ID!4``"JG#@``$D@``"JR +XM#@``6T@``"J[#@``*$D``"S$#@```Y&@?RS-#@```Y'@?BS7#@```Y'@?"KA +XM#@``T$D``"KJ#@``G4H``"KU#@``:DL``"H`#P``O4P``"L)#P`````R%0\` +XM`#`7```!:902```H.@\``#`Q#P``BDT``"@F#P``,T0/```56T```````"A; +XM0````````=@\``&`7```!)0(HC`\``"GP%P``+)8/```#D>!\+*(/```#D>!^*JX/ +XM``!_3@``*KD/```!3P``*\4/```JT`\``(-/```KW`\````````(`P```@`S +XM"@``"`$-!P```78-``#A`P``X&9````````/:4```````!(-```"`0:K`0`` +XM`@$(J0$```("!;L%```"`@?1!@```P0%:6YT``($!Y8"```""`5=`P``!(8" +XM```".FD````""`>1`@```@@$AP,```($!*D#```$]00```)27@````4(!P8( +XM`@$&L@$```3W!````S)^````!PB.````!PBL````"(X````""`58`P``!(@" +XM```$8UX````$!@$```4GS@````D%`0```0<(PP````H0!E'_````"U<%```& +XM4@`&2;@````"(R@-8V%P``9*N`````(C,`LV"@`` +XM!DNX`````B,X"]T(```&3+@````"(T`+WP0```9-20````(C2`NQ````!DY) +XM`````B-,"ZL$```&3TD````"(U`+W0H```91V@````(C6`LM`P``!E+9`0`` +XM`B-H``<(_P````<(S0$```H0!E+^`0``"U<%```&4LT!```"(P`+.`(```92 +XMTP$```(C"``.`7X-```!5P%)````X&9```````!O9T```````,Q/``"#`@`` +XM#W0``5;-`0``?5````]S``%6I@```-E0```08@`!6*8````040``$&,``5BF +XM````1E$``!!R``%8I@```'Q1```0;&5N``%9E0```+)1```1<0T```%9E0`` +XM`.A1````$@%@#0```2D!<&=````````/:4```````!Y2```/=``!*,T!``#/ +XM4@``#W,``2BF````*U,``!-R``$JI@```!!B``$KH````&-3```08P`!*Z`` +XM``"P4P``$&QE;@`!+)4```#Y4P``$7$-```!+)4````O5```$5L!```!+4D` +XM``!X5``````!$0$E#A,+`PX;#A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+ +XM.PM)$P``!"0`"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8` +XM21,```D6``,..@L[!4D3```*$P$##@L+.@L["P$3```+#0`##CH+.PM)$S@* +XM```,#0`#"#H+.PM)$S@*```-%0$G#$D3`1,```X%`$D3```/$P`##CP,```0 +XM`0%)$P$3```1(0!)$R\+```2$P$+"SH+.PL!$P``$Q8``P@Z"SL+21,``!0$ +XM`0L+.@L["P$3```5*``##AP-```6!`$##@L+.@L["P$3```7+@`##CH+.P4G +XM#!$!$@%`!@``&"X!`PXZ"SL%)PP@"P$3```9!0`#"#H+.P5)$P``&BX!`PXZ +XM"SL+)PP@"P$3```;!0`#"#H+.PM)$P``'#0``PXZ"SL+21,``!TT``,(.@L[ +XM"TD3```>+@$##CH+.P4G#!$!$@%`!@$3```?!0`#"#H+.P5)$P(&```@-``# +XM#CH+.P5)$P(&```A-``#"#H+.P5)$P(&```B-``##CH+.P5)$P``(QT!,1-5 +XM!E@+604``"0%`#$3```E"P%5!@``)C0`,1,"!@``)S0`,1,""@``*`4``PXZ +XM"SL%21,``"DT``,(.@L[!4D3```J+@$_#`,..@L[!2<,21,1`1(!0`8!$P`` +XM*P4``PXZ"SL%21,"!@``+!T!,1-5!E@+604!$P``+30`,1,``"XT``,..@L[ +XM"TD3`@H``"\T``,..@L["TD3/PP\#```,#0``PXZ"SL%21,_##P,`````1$! +XM)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```Q8``PXZ"SL+21,```0D``L+ +XM/@L#"```!20`"PL^"P``!@\`"PL```+@$##CH+.P4G#!$!$@%`!@$3```?!0`##CH+.P5)$P(&```@ +XM-``#"#H+.P5)$P``(2X!/PP##CH+.P4G#$D3$0$2`4`&`1,``"(N`3\,`PXZ +XM"SL+)PQ)$Q$!$@%`!@$3```C!0`#"#H+.PM)$P(&```D!0`##CH+.PM)$P(& +XM```E-``#"#H+.PM)$P(&```F+@$##CH+.PLG#$D3$0$2`4`&`1,``"+@$# +XM#CH+.PLG#$D3(`L!$P``'P4``PXZ"SL+21,``"`N`0,..@L[!2<,21,@"P$3 +XM```A!0`#"#H+.P5)$P``(@4``PXZ"SL%21,``",T``,..@L[!4D3```D+@$_ +XM#`,..@L[!2<,$0$2`4`&```E-``#"#H+.P5)$P(*```F-``##CH+.P5)$P(& +XM```G'0$Q$U4&6`M9!0$3```H!0`Q$P``*0L!508``"HT`#$3`@8``"LT`#$3 +XM```L-``Q$P(*```M"@`Q$Q$!```N'0$Q$U4&6`M9!0``+QT!,1,1`1(!6`M9 +XM"P$3```P!0`Q$P(&```Q"P$1`1(!```R'0$Q$U4&6`M9"P$3```S'0$Q$Q$! +XM$@%8"UD+`````1$!)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```R0`"PL^ +XM"P,(```$%@`##CH+.PM)$P``!20`"PL^"P``!@\`"PL```7!E2YH````````"0)@'$````````/9 +XM!`%(")P#=_U(")P#=_U(")P#X7W]`BL5`WHY6V4(D0,9C>(X`[E__0BO`Q(( +XMJ0-P_0@2"*T#\GX('4D(9@A`13OR"&=84J)#4E:JG9R!99V<2PB"`B03@8(( +XMGTFLGH4(6H*""&>"-CQ7`P^-<@AR.%8#"6,(67*!`QH(8P,*C0-Z_0,W")N4 +XM@(`#QWX".`$#E`&-G#@Z`PVIG#@Z9@@["$@(0(X(6`/J?L7"`_L`Q8%%.U8X +XM.F(\U%:.@/Y&`^-^?P,2C0/Y``@K_P-6"%4#QP`(Q0.&?P@Y`R,(Q0/=``C% +XM`[Y_"'\#F7\(Q0-B",4(S`/J``C%`\L`",4#I7\(.0/8``C%`^E^_0-YX0.4 +XM`?T#G@+OGE+(R9PX.F7F?8^XN+6`@;BXLX"%`WH('8#P\/16CU-)BTD(5P/O +XM?0A_"/$#P@`",0$#OG^W`P\(X0-Q""L#"M,#=@@=QP@ZR'(#%M,#=0AQ"#K( +XM7,``'-E8W1I;VYS+F,````` +XM7!E2YH````````"0+P*T````````/D`0&X"%24`B@2<@-W8P.\!0CA +XM"*!)"$J.CDB`CHZ`>EP(3[U(.%8($W*`2(!R;DP(R`-L",5(1DA&2`-KFP,, +XM",4##PC%`PL(Q0.J?P(H`:X#$PA'9P-I"&.."!3G@-D('_562@-CC0,6",4( +XMR@-/`B0!UD0]=V324,;&Q@-#"#GI"+@($P@L"$H(G4$#>#DZ@$AR@$A#2PAE +XM"!)RA31,-$A(Q0C(`PK]`PH(Q0C-`ZU_`BP!D0,7 +XMTP-NC0A+`PEQ9("`9(`#;6,#%0@Y5DH#;7$Z?CN`9(`##F,#:7$#%0C%`TT" +XM)P$(Q692/-8(/59B`DH05^0#=`(H`0C(",P#O7X")0&A"'?&E0C6"%:%"!)) +XM-U:.`V+%N`,2C0-M?P,BC0-J"!W&`PW]",H#Z7T")`$#"HT(2@B>6%)*U45) +XM-ZX(+#A(,&"`4@@24CP#%D)L(/<:0`B,,`Q$(1P,58P-K*P,-.0-S*TX(6@A( +XMQ@@\"&<##0@K`WF-20-6 +XM[PCU"*LZ2%E?2(Z.@`,3X0,+"'%6D`-KX0-6",4(R`,B",4#<0C%`V3A`\,` +XM",4#[`(")@$@1%B=!`(#QGW]_@0!`[<"Q8YT!`(#Q'T(.<8$`0.W`CD$`@/) +XM?4<$`0.W`G$$`@/)?3D$`0.W`CDQ;0@M!`(#Q'W]R`0!`W$(Q?U8`\0![WV! +XM10.^?G''@P,)`C5HPZ.%:/"!Y^5E0ML)=9ROB.`POA +XM`VF;JP-L?P.9?@A'A0.6`0CA`X5]J>(#E00(.0A:_`@[5H,$`@.O?0A'_@0! +XM`YH""!W4""P#<=,(2`,850@75GX#C'R-`XP$"-,#89OBN.XZ5M0#=M,#6PAC +XMX@/G``AQ`VS]`]Q^"%4(9PC_"&8('C@ZGP)B"XYR`E\1`X)_"/V`R@,="/T( +XM@@@>.%8"-!4(UP(M$3<[9M3GK`-G`DP!JJH(Y@,*",6L!`(#BW\"3P$$`0/X +XM`.$"91$"1@T#A@$"1@$#S0#A`Z]^")OX`D@-`E`*`W`(Q0/-`)L##0C%`WD( +XMQ0-)",4#9PC]`QT([U8J+&?H"#T"*Q$#8\4#$@)"`0(4``$!40$```(`E@`` +XM``$!^PX*``$!`0$````!+W5S7!EG$Q`VL('=,\ +XM4CS(.@BXW0-P")O3/%(\R#H(N-T#ZWX(FP,)*P-W50@CCH_&"(\(U@C7`YM^ +XMJ0B""$L(H`AS.PC4.')JA@-XFPAR"#P")!(('LE6@[QZ+P@Z"#P")!,(6%:" +XM`R.-"!XX5@/*``(D`0(E$`(U$PAGC@C&JKBX@8Y4@&8#;`+5`0$#&<6`"!YP +XM+`@>"&%TG@(F$8#&`R#%C@,4J0,5J0B0<@,+?P-V50,*50-V58`#+4<#5']R +XM;TNXP.5?W&<`]<`FP,; +XM"!U6`U=_40,+?P-W?[B_`WE52*JXN*JDAL@(Q@-'",4(D+%R\(!(G\#M`%_`[!^`D$! +XM`R)5`WI'`[.%Y\@/L?0CO`ZL$""L(9`.4?N$#4(T#>0@K`_Y]"$<( +XMUW0#Z0#O`B86`Y9_J<@#254#O@((8P(N$`@>"#RO"$@#"0+4`0$(/+M4.H", +XM4PBO"'*`.$@#OWX(?P,+"$<#F`$(*P@ZJ@A(`LH!%@+1`18(.@-X`B\!"#<( +XM.PCM".P#D'\"S0$!`_4`TP,Q`B@!`TW]`YA^`BT!`ZD#",4#O'X(Q0CM`S@( +XMX0-*`C0!"#<#@@$(.7*X@$AR;P.Q?\4#2@+,`0$"+A$#-`(N`0-/"#D#,P(E +XM`0,V`D.')F"*X( +XM<@B?"!8")!("(Q0(9`AP:`(W$`A6*CK&V@(F$^,(\4@#;[<#U0$(C0(I$0,T +XM`B,!`ZQ_`BX!5BHL`_,!")L#XGX(?P/_?@(J`0.-?_U6*BP#[P#3`Y)_*P-# +XM"'\#]@#A",D(%`.$?^$#AP,(Q0.G?0C%`BL45BHL`_8!Q0.@`0(K`0/7?'$" +XM(Q,(/`-Z",4"'@`!`0(!```"`(D````!`?L."@`!`0$!`````2]U7!EG\_`W5Q`PM5`T&W_4VX@`C)CT4[Z`,) +XM50-Q?P@>JL<#%PA5`VOA5PA6.GY(.$@#"0(D`4A&2`@;RDBX.%:`N`-ZX0-E +XM_0@``0$`%````/____\!``%X$`P'")`!````````'`````````!@'$`````` +XM`"D`````````1`X0```````<`````````)`<0```````*0````````!$#A`` +XM`````!P`````````P!Q````````I`````````$0.$```````+`````````#P +XM'$```````(\&````````2H\"A@9A#N`!C@.-!(P%@P<`````````/``````` +XM``"`(T```````'`(````````0@X0CP)%#AB.`TH.($(.*$$.,$$..$<.T`&# +XM!X8&C`6-!````````!0```#_____`0`!>!`,!PB0`0```````!0```#H```` +XM\"M```````!]`````````"0```#H````<"Q```````"V`0```````$J#!8P# +XM40YPC0*&!``````L````Z````#`N0```````!P$```````!"#A!!#AB&`XP" +XM1`X@1`Y@@P0````````<````Z````$`O0```````:P````````!.#B"#`X8" +XM`#0```#H````L"]```````#B`0```````$(.$$(.&(T#C@)%#B!!#BA!#C!$ +XM#G"#!H8%C`0`````)````.@```"@,4```````/0`````````00X0A@)$#AA$ +XM#B"#`P```"0```#H````H#)````````Y`0```````$J&!(,%5`ZP`8T"C`,` +XM```L````Z````.`S0```````.@$```````!"#A!"#AA!#B!!#BA$#G"#!88$ +XMC`.-`@`D````Z````"`U0```````_P````````!!#A"&`D0.&$0.8(,#```` +XM+````.@````@-D```````*(`````````0@X0C0)%#AB,`T0.((8$1`XH1`XP +XM@P4`'````.@```#0-D```````"(`````````1@X0```````<````Z``````W +XM0```````-P````````!$#A```````"0```#H````0#=```````!)`0`````` +XM`%J,`X,%C0*&!$<.8``````L````Z````)`X0```````%0$```````!"#A", +XM`D0.&(8#0PX@@P1(#G`````````\````Z````+`Y0```````%0,```````!" +XM#A!'#AA"#B!"#BA!#C"&!HP%C02.`X\"20XX1`Z0`8,'````````)````.@` +XM``#0/$```````-L`````````00X0A@)%#AA$#B"#`P```#P```#H````L#U` +XM``````#3"P```````$(.$$(.&$(.($(.*$$.,$$..$<.D`*#!X8&C`6-!(X# +XMCP(````````4````_____P$``7@0#`<(D`$````````4````X`,``)!)0``` +XM````V0`````````T````X`,``'!*0```````[@$```````!"#A!"#AA"#B!! +XM#BB&!8P$C0..`D0.,$0.L`&#!@```"P```#@`P``8$Q````````E`0`````` +XM`$(.$$$.&$$.((,$A@.,`D<.8````````!0```#_____`0`!>!`,!PB0`0`` +XM`````!0```!X!```D$U````````0`````````!0```!X!```H$U````````0 +XM`````````"0```!X!```L$U```````!!`````````$$.$(8"1`X81`X@@P,` +XM```<````>`0```!.0```````9@````````!.#B"&`H,#`!P```!X!```<$Y` +XM``````!F`````````$X.((8"@P,`/````'@$``#@3D```````/H7```````` +XM0@X01PX80@X@C02.`X\"10XH00XP00XX1P[@!(,'A@:,!0```````!0```#_ +XM____`0`!>!`,!PB0`0```````#P```!H!0``X&9```````"/`````````$(. +XM$$(.&$(.($(.*$$.,$$..(,'A@:,!8T$C@./`DH.0``````````\````:`4` +XM`'!G0```````GP$```````!"#A!"#AA"#B"-!(X#CP)%#BA!#C!!#CA$#E"# +XM!X8&C`4`````````7V5X=')A`'9?F4`5]L;VYG;W!T +XM`!%3$9?0U].54Q,`&]P +XM:&YU;0!S96-T:6]N6U?;&ES=`!S=')I<%]L;VYG;W!T6U?:V5E<`!%3$9?5%]32$12`'-A8U]L:7-T`&YO8V]P>0!? +XM6U?F4`14Q&7U1? +XM4U=/4D0`8W)E871E7V9I;&4`7U]F9FQA9W-?=`!%3$9?5%](04Q&`&]P=&%R +XM9P!S:&]R="!U;G-I9VYE9"!I;G0`14Q&7TM?05(`=E]R96P`6YC7W-E8W1I;VYS`$5L +XM9C8T7U-H9'(`:7-?'0`;G-E8W,`16QF-C1?6'=O`!R7V%D9&5N9`!R96PV-`!I +XM@!A9&1?=&]?:6YS96=?;&ES=`!P7V%L:6=N`$=% +XM;&9?4&AD<@!P7V9L86=S`'!?='EP90!P7W9A9&1R`'!?;65M6UB;VQS`&ES7V1E8G5G7W-Y;6)O;`!S=%]S>@!I +XM6T`5]C87``8V%L8U]N;VYL;V-A;`!%;&8V-%]3>6T`8W)E +XM871E7W-E8W-Y;0!'16QF7U-Y;0!A9&1?=&]?:V5E<%]L:7-T`'-T7V)U9@!L +XM;V]K=7!?5]B=68`:7-?;F5E9&5D7W-Y;6)O;`!S +XM>6UB;VQS+F,`:7-?;&]C86Q?6UB;VP`;'-Y9&%T80!L;V]K=7!?:V5E<%]S>6UL:7-T`'-T7VYA +XM;64`;6%R:U]S>6UB;VQS`&EN>@4````````?!P````````$`7@`````````````````````&`0`````` +XM``D!`````````0!0"0$````````,!`````````$`7"P$````````-00````` +XM```!`%QQ!````````'0$`````````0!0=`0```````#I!`````````$`7$T% +XM````````:04````````!`%R0!0```````-\&`````````0!<\`8````````0 +XM!P````````$`7``````````````````````O`P```````+H#`````````0!3 +XMVP,```````#\`P````````$`4Z,$````````SP0````````!`%/@!0`````` +XM`!<&`````````0!3CP8```````"M!@````````$`4\$&````````WP8````` +XM```!`%,`````````````````````?`(```````"Z`P````````,`D;A_VP,` +XM```````L!`````````,`D;A_HP0```````#I!`````````,`D;A_5@4````` +XM``!I!0````````,`D;A_P@4````````7!@````````,`D;A_CP8```````"M +XM!@````````,`D;A_P08```````#?!@````````,`D;A_\`8```````#_!@`` +XM``````,`D;A_`````````````````````"`'````````(@<````````"`'<( +XM(@<````````G!P````````(`=Q`G!P```````#$'`````````@!W&#$'```` +XM````,P<````````"`'<@,P<````````T!P````````(`=R@T!P```````#4' +XM`````````@!W,#4'````````/`<````````"`'`````````````````````"`'````````00<````` +XM```!`%1!!P```````(8-`````````0!?U0T```````"0#P````````$`7P`` +XM``````````````````!I!P```````&X'`````````0!540D```````!6"0`` +XM``````$`58()````````APD````````!`%6?"0```````*0)`````````0!5 +XMT`D```````#5"0````````$`58$+````````C`L````````!`%4U#``````` +XM`#H,`````````0!5/0P```````!"#`````````$`59T-````````H@T````` +XM```!`%7.#0```````-,-`````````0!5X@T```````#G#0````````$`5:4. +XM````````J@X````````!`%7)#@```````,X.`````````0!5W0X```````#B +XM#@````````$`55(/````````7@\````````!`%4````````````````````` +XMA`@```````"<"`````````$`4%H)````````>`D````````!`%"H"0`````` +XM`,8)`````````0!0]@T````````"#@````````$`4``````````````````` +XM```P#````````#H,`````````0!420P```````!0#`````````$`5``````` +XM```````````````I#````````#H,`````````0!120P```````!0#``````` +XM``$`40````````````````````#\"0```````/\)`````````0!0_PD````` +XM```>"@````````$`75`*````````4`H````````!`%T6#@```````"<.```` +XM`````0!=,0X```````!"#@````````$`70````````````````````"$"``` +XM`````/\)`````````0!=4`H````````4"P````````$`7=$+````````7`P` +XM```````!`%WV#0```````!8.`````````0!=0@X```````!G#@````````$` +XM70````````````````````"$"````````!X*`````````0!3G@H```````"A +XM"@````````$`4*$*````````%`L````````!`%/1"P```````%P,```````` +XM`0!3]@T````````'#@````````$`4Q8.````````)PX````````!`%,Q#@`` +XM`````$(.`````````0!34PX```````!G#@````````$`4P`````````````` +XM``````"$"````````)P(`````````0!0GP@```````#;"`````````$`4.(( +XM````````5@D````````!`%!X"0```````(<)`````````0!0C`D```````"D +XM"0````````$`4,8)````````U0D````````!`%#:"0```````/D)```````` +XM`0!0\@L````````)#`````````$`4`X,````````$PP````````!`%!0#``` +XM`````%4,`````````0!0`````````````````````!X*````````1@H````` +XM```!`%,'#@```````!8.`````````0!3`````````````````````#H,```` +XM````0@P````````!`%`[#0```````'H-`````````0!0```````````````` +XM`````!T+````````T0L````````!`%;2#````````&H-`````````0!6U0T` +XM``````#V#0````````$`5B<.````````,0X````````!`%8````````````` +XM````````&PL````````E"P````````,`D;!^)0L````````M"P````````,` +XMD;1^+0L````````P"P````````,`D;A^,`L````````R"P````````$`73(+ +XM````````,@L````````!`%,R"P```````$L+`````````P"1L'Y+"P`````` +XM`&P+`````````0!3;`L```````!R"P````````$`4W(+````````APL````` +XM```!`%.'"P```````(X+`````````0!=C@L```````"6"P````````$`4Y8+ +XM````````F`L````````#`)&T?I@+````````H`L````````!`%.@"P`````` +XM`*(+`````````P"1N'ZB"P```````+`+`````````0!3L`L```````"R"P`` +XM``````,`D;!^L@L```````#1"P````````$`4SH,````````20P````````# +XM`)&T?M(,````````^@P````````!`%/Z#`````````H-`````````P"1M'X* +XM#0````````P-`````````P"1L'X,#0```````!0-`````````0!3%`T````` +XM```S#0````````,`D;A^,PT```````"!#0````````$`4X$-````````E0T` +XM```````#`)&P?I4-````````U0T````````#`)&T?M4-````````]@T````` +XM```!`%,G#@```````#$.`````````0!3`````````````````````$4+```` +XM````3@L````````!`%#2#````````.(,`````````0!0)PX````````L#@`` +XM``````$`4``````````````````````Z#````````$D,`````````0!6:@T` +XM``````!Z#0````````$`5GH-````````E0T````````!`%"5#0```````-4- +XM`````````0!6`````````````````````(`,````````F`P````````!`%"Q +XM#@```````+\.`````````0!0`````````````````````&,(````````_PD` +XM```````!`%T4"P```````#`+`````````0!=\@L```````#2#`````````$` +XM7?8-````````!PX````````!`%UG#@```````&@/`````````0!=B0\````` +XM``"0#P````````$`70````````````````````!<#````````)@,```````` +XM`0!0FPP```````#+#`````````$`4&<.````````J@X````````!`%"_#@`` +XM`````,X.`````````0!0TPX```````#B#@````````$`4.<.````````"@\` +XM```````!`%``````````````````````.@P```````!)#`````````$`5CD/ +XM````````10\````````!`%9%#P```````%4/`````````0!050\```````!H +XM#P````````$`5@````````````````````"``````````)L``````````@!W +XM")L`````````-@(````````#`'?P``````````````````````"````````` +XM`*8``````````0!5I@````````"1`0````````$`7)L!````````-@(````` +XM```!`%P`````````````````````GP````````",`0````````$`5IL!```` +XM````-@(````````!`%8`````````````````````!0$````````(`0`````` +XM``$`4`@!````````AP$````````!`%.;`0```````+X!`````````0!3W`$` +XM```````V`@````````$`4P````````````````````!``@```````$("```` +XM`````@!W"$("````````0P(````````"`'<00P(```````!'`@````````(` +XM=QA'`@```````$L"`````````@!W($L"````````1P,````````#`'?@```` +XM``````````````````!``@```````%P"`````````0!57`(```````#M`@`` +XM``````$`5O`"````````1P,````````!`%8`````````````````````4@(` +XM``````#L`@````````$`4_`"````````1P,````````!`%,````````````` +XM````````Y0(```````#P`@````````$`4"P#````````,P,````````!`%`` +XM````````````````````4`,```````!>`P````````(`=PA>`P```````+L# +XM`````````@!W(`````````````````````!0`P```````'(#`````````0!5 +XMA0,```````"(`P````````$`50````````````````````!0`P```````&P# +XM`````````0!4;`,```````!W`P````````$`5G<#````````A0,````````! +XM`%2%`P```````+L#`````````0!6`````````````````````&(#```````` +XM?`,````````!`%-\`P```````(4#`````````0!5A0,```````"[`P`````` +XM``$`4P````````````````````#``P```````,(#`````````@!W",(#```` +XM````Q`,````````"`'<0Q`,```````#)`P````````(`=QC)`P```````,H# +XM`````````@!W(,H#````````RP,````````"`',#````````%@4````````!`%T6!0```````!D% +XM`````````0!5&04```````"B!0````````$`70`````````````````````$ +XM!````````!$%`````````0!3&04```````"B!0````````$`4P`````````` +XM``````````#6`P```````!(%`````````0!6&04```````"B!0````````$` +XM5@````````````````````"/!````````)($`````````0!0D@0```````#0 +XM!`````````$`44@%````````4@4````````!`%$````````````````````` +XM#00````````4!0````````$`7!D%````````H@4````````!`%P````````` +XM````````````L`4```````"Q!0````````(`=PBQ!0```````+4%```````` +XM`@!W$+4%````````N04````````"`'<8N04```````"D!@````````(`=R`` +XM````````````````````L`4```````#+!0````````$`5P`0````````````````````"P!@```````-0&`````````0!5U`8` +XM``````!_!P````````$`7(\'````````Z0<````````!`%P````````````` +XM````````L`8```````#9!@````````$`5-D&````````X08````````!`%4` +XM````````````````````L`8```````#A!@````````$`4>$&````````;P<` +XM```````!`%./!P```````.D'`````````0!3`````````````````````+`& +XM````````X08````````!`%+A!@```````'<'`````````0!6CP<```````#I +XM!P````````$`5@````````````````````#P!P```````/('`````````@!W +XM"/('````````]`<````````"`'<0]`<```````#U!P````````(`=QCU!P`` +XM`````/8'`````````@!W(/8'````````^@<````````"`'PL````````!`%1]"P```````(D+`````````0!6I0L```````"G +XM"P````````$`5L(+````````Q`L````````!`%;\"P```````),,```````` +XM`0!6`````````````````````'T+````````?PL````````!`%`T#``````` +XM`#D,`````````0!0:`P```````"##`````````$`4(X,````````F0P````` +XM```!`%``````````````````````H`P```````"B#`````````(`=PBB#``` +XM`````*8,`````````@!W$*8,````````J0P````````"`'<8J0P```````"Q +XM#`````````(`=R"Q#````````+4-`````````P!W\``````````````````` +XM````H`P```````"U#`````````$`5;4,````````+PT````````!`%PP#0`` +XM`````+4-`````````0!<`````````````````````*`,````````K0P````` +XM```!`%2M#````````"P-`````````0!3,`T```````"U#0````````$`4P`` +XM```````````````````2#0```````!\-`````````0!0>0T```````"##0`` +XM``````$`4`````````````````````"H#````````"T-`````````0!6,`T` +XM``````"U#0````````$`5@`````````````````````%#0```````#`-```` +XM`````@"16'D-````````EPT````````"`)%8`````````````````````"<- +XM````````,`T````````!`%$W#0```````$<-`````````0!1```````````` +XM`````````,`-````````P@T````````"`'<(P@T```````#)#0````````(` +XM=Q#)#0```````,L-`````````@!W&,L-````````S0T````````"`'<@S0T` +XM``````#.#0````````(`=RC.#0```````-<-`````````@!W,-<-```````` +XMVPT````````"`'NA````````#5$`````````$`7@`````````````` +XM```````T#@```````)P0`````````P"1N'^Z$````````-40`````````P"1 +XMN'\`````````````````````-`X````````0$`````````$`7140```````` +XMG!`````````!`%VZ$````````-40`````````0!=```````````````````` +XM`/\.`````````@\````````!`%`"#P```````%\/`````````0!1W@\````` +XM``#D#P````````$`4140````````'Q`````````!`%$````````````````` +XM````_P\````````5$`````````$`4+H0````````P1`````````!`%`````` +XM````````````````X!````````#A$`````````(`=PCA$````````.80```` +XM`````@!W$.80````````ZA`````````"`'<8ZA````````"[$0````````(` +XM=R``````````````````````X!````````!'$0````````$`56H1```````` +XM?1$````````!`%6$$0```````(X1`````````0!5K!$```````"Q$0`````` +XM``$`50````````````````````#@$`````````41`````````0!4+!$````` +XM``!$$0````````$`5&H1````````>!$````````!`%2$$0```````(L1```` +XM`````0!4`````````````````````/(0````````;Q$````````!`%-Q$0`` +XM`````+L1`````````0!3`````````````````````/00````````1!$````` +XM```!`%1J$0```````'@1`````````0!4A!$```````"+$0````````$`5*P1 +XM````````MA$````````!`%0`````````````````````]!`````````%$0`` +XM``````$`5"P1````````>!$````````!`%2$$0```````(L1`````````0!4 +XME1$```````"G$0````````$`5`````````````````````#T$````````'T1 +XM`````````0!5A!$```````".$0````````$`5941````````IQ$````````! +XM`%6L$0```````+$1`````````0!5`````````````````````,`1```````` +XMPA$````````"`'<(PA$```````#$$0````````(`=Q#$$0```````,81```` +XM`````@!W&,81````````R!$````````"`'<@R!$```````#)$0````````(` +XM=RC)$0```````,H1`````````@!W,,H1````````T1$````````"`'!8````````!`%5X%@```````)(6`````````P"1 +XMR'Z2%@```````)<6`````````0!5EQ8```````"3'0````````,`DP`0````````````````````#@ +XM`````````%P!`````````0!57`$```````!/`@````````$`5E8"```````` +XMS@(````````!`%8`````````````````````]@````````!A`0````````$` +XM4H4!````````3@(````````!`%-6`@```````)("`````````0!3```````` +XM`````````````/T`````````!`$````````!`%`+`0```````&$!```````` +XM`0!0`````````````````````/T`````````80$````````!`%$````````` +XM````````````H0$```````"J`0````````$`7*H!````````40(````````! +XM`%Q6`@```````)("`````````0!<`````````````````````-`"```````` +XMT@(````````"`'<(T@(```````#3`@````````(`=Q#3`@```````-0"```` +XM`````@!W&-0"````````VP(````````"`'<@VP(```````#U`P````````,` +XM=^```````````````````````-`"````````WP(````````!`%7?`@`````` +XM`*0#`````````0!3J`,```````#U`P````````$`4P`````````````````` +XM``#V`@````````4#`````````@"16`H#````````UP,````````"`)%8```` +XM`````````````````"``````````(0`````````"`'<((0`````````E```` +XM``````(`=Q`E`````````"D``````````@!W&"D`````````80`````````" +XM`'<@`````````````````````"``````````-P`````````!`%5````````` +XM`$8``````````0!56`````````!A``````````$`50`````````````````` +XM```@`````````#4``````````0!4-0````````!7``````````$`5E@````` +XM````8``````````!`%9@`````````&$``````````0!4```````````````` +XM`````#``````````5@`````````!`%-8`````````%\``````````0!3```` +XM`````````````````'``````````?@`````````"`'<(?@````````#6```` +XM``````(`=R``````````````````````<`````````"&``````````$`588` +XM````````P``````````!`%;%`````````-8``````````0!6```````````` +XM`````````'``````````C@`````````!`%2.`````````+L``````````0!3 +XMQ0````````#6``````````$`4P````````````````````#@`````````.X` +XM`````````@!W".X`````````1@$````````"`'<@```````````````````` +XM`.``````````]@`````````!`%7V`````````#`!`````````0!6-0$````` +XM``!&`0````````$`5@````````````````````#@`````````/X````````` +XM`0!4_@`````````K`0````````$`4S4!````````1@$````````!`%,````` +XM````````````````4`$```````!2`0````````(`=PA2`0```````%D!```` +XM`````@!W$%D!````````6P$````````"`'<86P$```````!@`0````````(` +XM=R!@`0```````&$!`````````@!W*&$!````````8@$````````"`'"0```````&D)`````````0!1$!0````` +XM``!%%`````````$`4488````````4!@````````!`%$````````````````` +XM````;@8```````!Q!@````````$`4'$&````````TP8````````!`%%&&``` +XM`````%`8`````````0!1`````````````````````-\#````````KP4````` +XM```!`%.S!0```````+H%`````````0!3[`4```````!'!@````````$`4Q<1 +XM````````*!$````````!`%/2$0````````82`````````0!3:!(````````T +XM$P````````$`4XX3````````I!,````````!`%/)$P```````!`4```````` +XM`0!3K!0```````#,%`````````$`4P,7````````,1<````````!`%-N%P`` +XM`````)@7`````````0!3I1@```````#*&`````````$`4P`````````````` +XM``````##`P```````+4'`````````P"1D'S)!P```````&D)`````````P"1 +XMD'S$"0```````.$0`````````P"1D'SO$````````&P4`````````P"1D'R. +XM%````````)@7`````````P"1D'RI%P```````,`7`````````P"1D'S"%P`` +XM`````.H7`````````P"1D'PH&````````$H9`````````P"1D'P````````` +XM````````````V`,```````"U!P````````,`D8A\R0<```````!I"0`````` +XM``,`D8A\T0D```````#A$`````````,`D8A\[Q````````!L%`````````,` +XMD8A\CA0```````"8%P````````,`D8A\J1<```````#`%P````````,`D8A\ +XMPA<```````#J%P````````,`D8A\*!@```````!*&0````````,`D8A\```` +XM`````````````````(@"````````WP,````````!`%-I"0```````-\)```` +XM`````0!3X1````````#O$`````````$`4U41````````D1$````````!`%,Q +XM%P```````&X7`````````0!3F!<```````"I%P````````$`4\`7```````` +XMZA<````````!`%,`````````````````````B@(```````"U!P````````,` +XMD;A_R0<```````!L%`````````,`D;A_CA0```````#J%P````````,`D;A_ +XM*!@```````!*&0````````,`D;A_`````````````````````%P$```````` +XM9@0````````!`%``````````````````````_P(```````"U!P````````,` +XMD8!\R0<```````#A$`````````,`D8!\ZA````````!L%`````````,`D8!\ +XMCA0```````#J%P````````,`D8!\*!@```````!*&0````````,`D8!\```` +XM`````````````````,\#````````M0<````````#`)'8?,D'````````:0D` +XM```````#`)'8?``*````````#`H````````#`)'X>PP*````````L@X````` +XM```#`)'8?+(.````````>P\````````#`)'X>WL/````````J@\````````# +XM`)'8?*H/````````O@\````````#`)'X>[X/````````T@\````````#`)'8 +XM?-(/````````\P\````````#`)'X>_,/````````,!`````````#`)'8?#`0 +XM````````X1`````````#`)'X>^\0````````%Q$````````#`)'X>Q<1```` +XM````D1$````````#`)'8?)$1````````LA$````````#`)'X>[(1```````` +XM!A(````````#`)'8?`82````````&A(````````#`)'X>QH2````````8A,` +XM```````#`)'8?&(3````````CA,````````#`)'X>XX3````````9Q0````` +XM```#`)'8?&<4````````;!0````````#`)'X>XX4````````_A8````````# +XM`)'8?/X6`````````Q<````````#`)'X>P,7````````,1<````````#`)'8 +XM?$87````````F!<````````#`)'8?*D7````````P!<````````#`)'8?,(7 +XM````````ZA<````````#`)'8?"@8````````2AD````````#`)'8?``````` +XM``````````````#8`P```````+4'`````````P"1\'O)!P```````&D)```` +XM`````P"1\'L5"@```````$D,`````````P"1\'OV#````````-H.```````` +XM`P"1\'MB#P```````'L/`````````P"1\'NJ#P```````-(/`````````P"1 +XM\'L4$````````.$0`````````P"1\'OO$````````*X2`````````P"1\'LT +XM$P```````&P4`````````P"1\'N.%````````*P4`````````P"1\'O,%``` +XM`````#$7`````````P"1\'M/%P```````)@7`````````P"1\'NI%P`````` +XM`,`7`````````P"1\'O"%P```````.H7`````````P"1\'LH&````````$H9 +XM`````````P"1\'L`````````````````````V`,```````#N`P````````$` +XM7YD%````````00<````````!`%^H"````````&D)`````````0!?&PH````` +XM``#A$`````````$`7^\0````````TA$````````!`%\&$@```````&@2```` +XM`````0!?-!,```````".$P````````$`7Z03````````VA,````````!`%\0 +XM%````````&P4`````````0!?CA0```````"L%`````````$`7\P4```````` +XM`Q<````````!`%]5%P```````&X7`````````0!?J1<```````#`%P`````` +XM``$`7\(7````````ZA<````````!`%\H&````````*48`````````0!?UQ@` +XM``````!*&0````````$`7P````````````````````"*`@```````/`"```` +XM`````0!6_P(```````""`P````````$`5H0#````````\D'````````;!0````````#`)'H>XX4 +XM````````ZA<````````#`)'H>R@8````````2AD````````#`)'H>P`````` +XM```````````````3`@```````+4'`````````P"1Y'O)!P```````&P4```` +XM`````P"1Y'N.%````````$H9`````````P"1Y'L````````````````````` +XM!@,````````N`P````````$`4(L#````````I`,````````!`%#8`P`````` +XM`/`#`````````0!5_0,````````(!`````````$`59D%````````\04````` +XM```!`%7V!0```````&8&`````````0!5J`@```````"Q"`````````$`50\) +XM````````$PD````````!`%4X%P```````#H7`````````0!0.A<```````!: +XM%P````````$`59@7````````I!<````````!`%#`%P```````,(7```````` +XM`0!0PA<```````#'%P````````$`50````````````````````"O!0`````` +XM`/8%`````````0!2`````````````````````)<*````````GPH````````! +XM`%3$"@```````,D*`````````0!5`````````````````````-@#```````` +XMWP,````````!`%.N"@```````/$*`````````0!3_@H```````!-"P`````` +XM``$`4U41````````D1$````````!`%/,%````````*`5`````````0!3J1<` +XM``````#`%P````````$`4\(7````````ZA<````````!`%,H&````````$88 +XM`````````0!3`````````````````````&X)````````>`D````````!`%4` +XM````````````````````51$```````!?$0````````$`5&D5````````;!4` +XM```````!`%!L%0```````'H5`````````0!4`````````````````````-@# +XM````````M0<````````#`)&X?,D'````````:0D````````#`)&X?$8*```` +XM````X1`````````#`)&X?.\0````````;!0````````#`)&X?(X4```````` +XM,1<````````#`)&X?%47````````F!<````````#`)&X?*D7````````P!<` +XM```````#`)&X?,(7````````ZA<````````#`)&X?"@8````````2AD````` +XM```#`)&X?``````````````````````T"P```````$,+`````````0!<51$` +XM``````"1$0````````$`7`H5````````MQ8````````!`%Q5%P```````&X7 +XM`````````0!`T````````!`%4*%0````````X5`````````0!5 +XM51<```````!:%P````````$`5;`7````````LA<````````!`%"R%P`````` +XM`,`7`````````0!5PA<```````#'%P````````$`5988````````F!@````` +XM```!`%"8&````````*48`````````0!5`````````````````````-@#```` +XM````M0<````````#`)&L?,D'````````:0D````````#`)&L?$8*```````` +XMX1`````````#`)&L?.\0````````;!0````````#`)&L?(X4````````,1<` +XM```````#`)&L?%47````````F!<````````#`)&L?*D7````````P!<````` +XM```#`)&L?,(7````````ZA<````````#`)&L?"@8````````2AD````````# +XM`)&L?`````````````````````#8`P```````+4'`````````P"1Q'S)!P`` +XM`````&D)`````````P"1Q'Q&"@```````%P*`````````P"1Q'Q<"@`````` +XM`&,*`````````0!48PH```````#A$`````````,`D<1\[Q````````!L%``` +XM``````,`D<1\CA0````````Q%P````````,`D<1\51<```````"8%P`````` +XM``,`D<1\J1<```````#`%P````````,`D<1\PA<```````#J%P````````,` +XMD<1\*!@```````!*&0````````,`D<1\`````````````````````$,'```` +XM````M0<````````!`%/;!P```````'$(`````````0!3B@@```````"H"``` +XM``````$`4XX4````````K!0````````!`%-5%P```````&X7`````````0!3 +XMRA@```````#7&`````````$`4P````````````````````!&!P```````+4' +XM`````````0!>R0<```````#8!P````````$`7ML'````````J`@````````! +XM`%Z.%````````*P4`````````0!>51<```````!N%P````````$`7LH8```` +XM````UQ@````````!`%X`````````````````````X@<````````>"``````` +XM``$`4%47````````6A<````````!`%7*&````````-<8`````````0!0```` +XM`````````````````````````````@`````````"`'<(`@`````````$```` +XM``````(`=Q`$``````````8``````````@!W&`8`````````"``````````" +XM`'<@"``````````)``````````(`=R@)``````````H``````````@!W,`H` +XM````````%``````````"`'@`````````!`%][```` +XM`````(X``````````0!?`````````````````````#,`````````;P`````` +XM```!`%9[`````````(8``````````0!6`````````````````````#4````` +XM````;0`````````!`%Q[`````````(@``````````0!<```````````````` +XM`````#4`````````;@`````````!`%-[`````````(4``````````0!3```` +XM`````````````````"0``````````@````````,` +XMD;A_`````````````````````.0`````````2P$````````!`%Q2`0`````` +XM``8"`````````0!<#0(````````>`@````````$`7``````````````````` +XM``#V`````````$@!`````````0!34@$```````"E`0````````$`4P`````` +XM``````````````#G`````````%$!`````````0!?4@$````````,`@`````` +XM``$`7PT"````````'@(````````!`%\`````````````````````[P`````` +XM```>`@````````(`D40`````````````````````#P$```````#;`P`````` +XM`/`&````````$`<```````#!!@```````-\&````````%P8```````"M!@`` +XM`````,(%````````_@4```````"0!0```````*X%````````304```````!I +XM!0```````,\$````````Z00````````L!````````#4$```````````````` +XM`````````````)!<```````!) +XM%P```````&H7````````0A<```````!&%P````````@7````````,!<````` +XM```"%P````````47````````[A8```````#W%@```````-H6````````X18` +XM``````#,%@```````-46`````````````````````````````%P2```````` +XM@1(```````#A%0```````/L5`````````````````````````````($2```` +XM````Y1(````````[&P```````$H;````````"A8```````"H%@```````'$5 +XM````````X14```````!@$P```````)L4```````````````````````````` +XM`($2````````Y1(````````[&P```````$H;````````EQ8```````"H%@`` +XM`````#@6````````6X`+G)E;&$N<&QT`"YI;FET`"YT97AT`"YF +XM:6YI`"YR;V1A=&$`+F5H7V9R86UE7VAD<@`N9&%T80`N96A?9G)A;64`+F1Y +XM;F%M:6,`+F-T;W)S`"YD=&]RE```````*!Z```````` +XMH`$````````%``````````@`````````$`````````"X`````0````,````` +XM````0'Q0``````!`?````````!`````````````````````(```````````` +XM````````OP````$````#`````````%!\4```````4'P````````0```````` +XM````````````"````````````````````,8````!`````P````````!@?%`` +XM`````&!\````````"`````````````````````@```````````````````#+ +XM`````0````,`````````:'Q0``````!H?````````$@"```````````````` +XM```(``````````@`````````T`````@````#`````````+!^4```````L'X` +XM```````P````````````````````"````````````````````-4````!```` +XM`````````````````````+!^````````]@$```````````````````$````` +XM``````````````#>`````0````````````````````````"F@````````/`` +XM```````````````````!````````````````````[0````$````````````` +XM````````````EH$```````#I`0```````````````````0`````````````` +XM`````/T````!`````````````````````````'^#````````:TX````````` +XM``````````$````````````````````)`0```0`````````````````````` +XM``#JT0```````#4+```````````````````!````````````````````%P$` +XM``$`````````````````````````']T````````8#@`````````````````` +XM`0```````````````````",!```!`````````````````````````#CK```` +XM``````8```````````````````@````````````````````P`0```0```#`` +XM```````````````````X\0```````(P-```````````````````!```````` +XM``$`````````.P$```$`````````````````````````Q/X```````"<5``` +XM`````````````````0```````````````````$8!```!```````````````` +XM`````````&!3`0``````@!@```````````````````$````````````````` +XM```1`````P````````````````````````#@:P$``````%0!```````````` +XM```````!`````````````````````0````(````````````````````````` +XM>'8!``````"@$0```````"0```!/````"``````````8``````````D````# +XM`````````````````````````!B(`0``````B@D```````````````````$` +XM`````````````````````````````````````````````````````````P`! +XM`,@!0````````````````````````P`"`.`!0``````````````````````` +XM`P`#`/@!0````````````````````````P`$`%`$0``````````````````` +XM`````P`%`-`+0````````````````````````P`&`.`.0``````````````` +XM`````````P`'`(`/0````````````````````````P`(`,`/0``````````` +XM`````````````P`)`#@00````````````````````````P`*`,@60``````` +XM`````````````````P`+`-P60````````````````````````P`,`%`;0``` +XM`````````````````````P`-`#AI0````````````````````````P`.`$AI +XM0````````````````````````P`/`$1R0````````````````````````P`0 +XM`&!R4````````````````````````P`1`&!U4``````````````````````` +XM`P`2`*!Z4````````````````````````P`3`$!\4``````````````````` +XM`````P`4`%!\4````````````````````````P`5`&!\4``````````````` +XM`````````P`6`&A\4````````````````````````P`7`+!^4``````````` +XM`````````````P`8`````````````````````````````P`9```````````` +XM`````````````````P`:`````````````````````````````P`;```````` +XM`````````````````````P`<`````````````````````````````P`=```` +XM`````````````````````````P`>`````````````````````````````P`? +XM`````````````````````````````P`@```````````````````````````` +XM`P`A`````````````````````````````P`B```````````````````````` +XM`````P`C`````````````````````````````P`D```````````````````` +XM```!````!`#Q_P`````````````````````(`````0`"`.`!0```````&``` +XM```````/````!`#Q_P`````````````````````M````!`#Q_P`````````` +XM```````````\````!`#Q_P`````````````````````/````!`#Q_P`````` +XM``````````````!'````!`#Q_P````````````````````!2`````0`3`$!\ +XM4`````````````````!@`````0`4`%!\4`````````````````!N`````0`5 +XM`&!\4`````````````````![`````@`,`/`;0`````````````````"1```` +XM`0`7`-1^4````````0````````"@`````0`0`'!R4`````````````````"G +XM`````@`,`#`<0`````````````````!'````!`#Q_P`````````````````` +XM``"S`````0`3`$A\4`````````````````#``````0`4`%A\4``````````` +XM``````#-`````0`1`&AZ4`````````````````#;`````0`5`&!\4``````` +XM``````````#G`````@`,`!!I0`````````````````#]````!`#Q_P`````` +XM```````````````M````!`#Q_P`````````````````````\````!`#Q_P`` +XM``````````````````#]````!`#Q_P`````````````````````;`0``!`#Q +XM_P`````````````````````B`0```@`,`&`<0```````*0`````````N`0`` +XM`@`,`)`<0```````*0`````````X`0```@`,`,`<0```````*0````````!& +XM`0```@`,`/`<0```````CP8```````!2`0```0`0`,!S4```````H`$````` +XM``!C`0```0`0`(!R4```````0`$```````!R`0``!`#Q_P`````````````` +XM``````!]`0```@`,`/`K0```````?0````````"0`0```@`,`$`O0``````` +XM:P````````"@`0```@`,`-`V0```````(@````````"T`0```@`,```W0``` +XM````-P````````#&`0```@`,`-`\0```````VP````````#1`0``!`#Q_P`` +XM``````````````````#<`0``!`#Q_P````````````````````#F`0```@`, +XM`)!-0```````$`````````#W`0```@`,`*!-0```````$``````````'`@`` +XM!`#Q_P`````````````````````/`@``$@`,`"`U0```````_P`````````< +XM`@``$@`,`*`Q0```````]``````````F`@``$@```.P60```````D``````` +XM```X`@``$@```/P60```````AP````````!2`@``$@````P70```````%P$` +XM``````!I`@``$@```!P70```````314```````!^`@``$@`,`*`R0``````` +XM.0$```````"(`@``$@```"P70```````?`$```````"9`@``$@`,`'!.0``` +XM````9@````````"J`@``$0`2`*!Z4`````````````````"S`@``$@```#P7 +XM0```````V@(```````#)`@``$@```$P70```````G@````````#8`@``$@`` +XM`%P70```````-`````````#J`@``$@```&P70```````50````````#[`@`` +XM$@`,`)`X0```````%0$````````/`P``$@`,`+`]0```````TPL````````< +XM`P``$@```'P70```````Y0`````````R`P``$@`,`.!F0```````CP`````` +XM``!``P``$@```(P70```````B@````````!0`P``$@```)P70``````````` +XM``````!A`P``$@```*P70```````:@````````!X`P``$0(0`&AR4``````` +XM``````````"%`P``$@```+P70```````X@````````":`P``$@`,`.!.0``` +XM````^A<```````"H`P``$@```,P70```````C`$```````#"`P``$@`,`+`O +XM0```````X@$```````#2`P``$@```-P70````````@````````#F`P``$@`` +XM`.P70```````AP8```````#X`P``$@```/P70```````.P`````````.!``` +XM$@````P80```````&0$````````E!```$@`,`.`S0```````.@$````````U +XM!```$@`*`,@60``````````````````[!```$@```!P80```````)``````` +XM``!2!```$@```"P80```````B`````````!A!```$0`7`-A^4```````"``` +XM``````!I!```$@```#P80```````3`````````![!```$@```$P80``````` +XM*0````````",!```$@```%P80```````-0````````"A!```$@```&P80``` +XM````:0$```````"V!```$@```'P80```````:@````````#0!```$0`7`+!^ +XM4```````!`````````#G!```$@```(P80```````K0(```````#X!```$@`` +XM`)P80```````%@`````````+!0``$0`0`&!R4```````"``````````6!0`` +XM$@`,`"`V0```````H@`````````E!0``$@`,`%`;0```````DP`````````L +XM!0``$@```*P80```````E0`````````\!0``$@```+P80``````````````` +XM``!+!0``$0`7`+A^4```````"`````````!!0``$@`,`#`N0```````!P$```````"J!0``$@`,`'!*0``` +XM````[@$```````"T!0``$@`,`'!G0```````GP$```````#%!0``$@```/P8 +XM0```````*`````````#"```$@```+P:0```````\@````````!O"```$0`7`,A^4```````"``` +XM``````"#"```$@```,P:0```````=@````````"2"```$0`7`-!^4``````` +XM!`````````"C"```$@```-P:0```````+P````````"T"```$@`,``!.0``` +XM````9@````````#&"```$@`,`)!)0```````V0````````#8"```$@```.P: +XM0```````'@````````#I"```$@```/P:0```````N0$````````$"0``$@`` +XM``P;0```````(0`````````9"0``$@```!P;0``````` +XM"0``$@`,`&!,0```````)0$```````!I"0``$@```#P;0```````:`$````` +XM``!_"0``$@`,`+`Y0```````%0,`````````8W)T,2YC`&%B:71A9P`O=7-R +XM+W-R8R]L:6(O8W-U+V%M9#8T+V-R=&DN4P`\8V]M;6%N9"UL:6YE/@`\8G5I +XM;'0M:6X^`&-R='-T=69F+F,`7U]#5$]27TQ)4U1?7P!?7T143U)?3$E35%]? +XM`%]?2D-27TQ)4U1?7P!?7V1O7V=L;V)A;%]D=&]R4!`1D)31%\Q +XM+C``5]P:&1R +XM`&EN'-C;D!`1D)31%\Q+C``9V5L9E]U<&1A=&5?liba.a.uu << '610ec18d793cc5cecdc2a997e4eaf41c' +Xbegin 644 liba.a +XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` +XM+F)S6#[`C'1"0$`````,<$ +XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` +XM``$`````````.`````$``````````````(T````F```````````````!```` +XM`````!$````#``````````````"S````00```````````````0`````````! +XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` +XM`````````````#0#```A```````````````!```````````````````````` +XM```````!```````````````$`/'_`````````````````P`!```````````` +XM``````,``P`````````````````#``0``````````````````P`%```````` +XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` +XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!Mliblong.a.uu << 'bffcfa998f235061c92dda36112dc47a' +Xbegin 644 liblong.a +XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P +XM,#6UT86(`+G-T`!Y``4````!!P``#P`` +XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` +XM`'@````5```````````````!`````````#@````!``````````````"-```` +XM)@```````````````0`````````1`````P``````````````LP```$$````` +XM``````````$``````````0````(``````````````(0"``"P````"0````<` +XM```$````$`````D````#```````````````T`P``(0```````````````0`` +XM`````````````````````````````0``````````````!`#Q_P`````````` +XM``````,``0`````````````````#``,``````````````````P`$```````` +XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` +XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` +XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Msections.o.uu << 'END-of-sections.o.uu' +Xbegin 644 sections.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` +XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@U(QT98`````$B+A\@```!(B49@2(N'R````$B) +XM,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D +XM\$B)7"3@28G\2(EL).A,B6PD^$B#[&A(BV]82(GF2(M]$.@`````2(7`#X0* +XM`0``2,=$)!``````2,=$)#`!````2(M%(,=$)`0#````2,=$)`@`````2,=$ +XM)#@`````QT0D+`````#'1"0H`````$B)1"082(M]$.@`````2(7`2(G##X3. +XM````0?9$)&00#X2&````2(M%*$B)YDB)1"0@2(M]$.@`````A<`/A,,```!( +XMQP,!````2(M%&$B)0PA(BT4H2,=#$`````#'0R`!````QT,D`0```$B)0QA( +XMBWT0Z`````!)BWPD($B)QN@`````A<`/A)8```!(BUPD2$B+;"103(MD)%A, +XMBVPD8$B#Q&C#9F:09I!(BU4H2(M]&$B#ZA!(C7<02(E5*.@`````Z5S___^_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!( +XMB<*_1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:005152(G] +XM4TB#[$!(BY_`````2(7;=')(BWL02(GFZ`````!(AY(BW@0Z`````")1"0HD$B+>Q!(B>;H`````(7`=$-(BUM82(7;=8[H```` +XM`(7`=4](@\1`6UU!7,/'1"0H`````.O+O______H`````+X`````2(G"OT8` +XM```QP.@`````O______H`````+X`````2(G"OT8````QP.@`````BQ@`=!E(B>Y(B=](BVPD$$B+7"0(2(/$&.D`````2(G?O@````#H```` +XM`$B)W[X`````Z`````!(B=^^`````.@`````O@````!(B=_H`````.NQ9F:0 +XM9I!!5D%528G]05154TB#[$!(BZ_`````2(7M=")!N`````#K"4B+;5A(A>UT +XM$4B+=0"Y"@```$R)Q_SSIG7F28N=D````$B%VP^$!@$``&9FD$F+?2#H```` +XM`$B%P$F)Q`^$^P```+YX````OP$```#H`````$B%P$B)P@^$_@```$B+`TR) +XMYTB)`DB+12!(B4(@2(M#$,="2/_____'0DP`````2,=""`````!,B6(02(E" +XM*$B+16!(B6I82(E"8$B+16!(B1!(C4)82(E%8.@`````2(7`2(G"#X2P```` +XM2,<``0```$C'0!``````2(GF2(M#"$R)YTB)0@A(BT,0QT(@`0```,=")`$` +XM``!(B4(8Z`````!(A<`/A(T```#'1"0$`0```$B+,TR)[^A=_O__2(GF3(GG +XMZ`````"%P`^$A0```$B+6QA(A=L/A?W^__](@\1`6UU!7$%=05[#O______H +XM`````+X`````2(G"OT8````QP.@`````O@````"_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````!F9F:0 +XM9F:054B)_5-(@^P(BU=4A=)T!TB#?Q@`=&PQV^M+9F:09I!(BWT0Z`````!( +XMA9(B=_H`````$B%P`^$KP```$B+1"1`2(GN3(GG2(D$)$B+1"1(2(E$ +XM)`A(BT0D4$B)1"002(M$)%A(B40D&$B+1"1@2(E$)"!(BT0D:$B)1"0H2(M$ +XM)'!(B40D,$B+1"1X2(E$)#CH^/O__TB)YDB)W^@`````A3ID````$B+:R!,.>4/@J@```"+>TR% +XM_W4?2(MS.#'23(GE2HU,)O](BQ!(B>;H`````$B%P'1O2(M#($B)YDB) +XM1"082(M#*$B)1"0@2(M[$.@`````A;H +XM`````$B%P`^$E````+YX````OP$```#H`````$B%P$B)PP^$M0```$B+1"0H +XMN@$```!(B4,@2(N-P````$B%R708,<"#>5`!2(M)6(/0`$B%R77P@\`!2&/0 +XM2(M](+D!````O@X```#H`````$B%P$B)0RAT24B)WDB)[TC'0S@$````QT-, +XM`````,=#4`$```#H6/;__TB)V$B#Q$A;7<.______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````,<#H`````)!!54&)U4%428G\54B)]5-(@^P(2(N?@````$B%VW4+ +XMZR9(BUM`2(7;=!U(BS-(B>_H`````(7`=>A(@\0(2(G86UU!7$%=PS';187M +XM=.N_2````.@`````2(7`=#9(B<.Z2````#'V2(G'Z`````!(B2M(QT-````` +XM`$F+A"2(````2(D82(U#0$F)A"2(````ZZ:^`````+]&````Z`````!F9F:0 +XM9F9FD&9FD&9FD#'22(/L".@`````,=)(A[SIG3CNP````!)B>1(QP0D`````$C'1"0(`````$C'1"00 +XM`````$C'1"08`````$C'1"0@`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G? +XMZ`````!(B=Y(B<)(B>_H`````(7`==A!BT5@@^@!@_@!=PJX`0```.E!____ +XM28-]0``/A#3___\QTDB)[DR)[^@`````08M=0(7;=`Y(A_HZ/W__X7`=:2+1"1$@_@)#X2M```` +XM@_@$#X2D````0;T`````N0H```!,B>;\3(GO\Z8/A20!``!(BUU82(M$)%A( +XMB4,@2(M](.@`````2(7`2(E#$`^$#@(``$R)]^@`````A<")0T@/A-T!``#\ +XMN0H```!,B>9,B>_SI@^%,@$``/R_`````+D(````3(GF\Z9U"(--9!!(B5U( +XM_+\`````N0@```!,B>;SIG4$2(E=4$B)WDB)[^@/\O__Z>K^__]$BVPD;$6% +XM[0^$3O___TB+?1A(C;0D@````.@`````A<`/A*T!```QVT6)[4B+?1A(B=[H +XM`````$B%P$B)PP^$Q@```$B)W^@`````23G%==M(B>9(B=_H`````$B%P`^$ +XMC0$``(L4)$B+M"2`````2(M]&.@`````2(7`2(G(````2(GOZ)W\__^% +XMP`^%5?[__^G"_O__OG@```"_`0```.@`````2(7`#X03`0``2(G#3(D@3(EP +XM"$B+1"182(G>2(GO2(E#($B+1"1@2(E#*$B+1"1P2(E#.(M$)$1(B4-`Z``` +XM``")0TSID?[__TB+4Q!(BW,(2(GO2(L+Z`````#IMO[__^@`````A<`/A-/] +XM__^)Q^@`````O@````!(B<*_1@```#'`Z`````#H`````(7`==Q(@<28```` +XM6UU!7$%=05Y!7\.______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:054B-+#=32(/L +XM"$@Y[W-[2(G[ZSB+!0````"%P'5S2(LU`````(M&#(/H`87`B48,#XB6```` +XM2(L&Q@`*2(/``4B)!DB#PP%(.>MT/@^V$X32=,&+!0````"%P'5'2(LU```` +XM``^^^HM&#(/H`87`B48,>$%(BP9(@\,!0(@X2(/``4@YZTB)!G7"2(/$"%M= +XMPTB+-0````"_"@```.@`````ZY](BS4`````#[[ZZ`````#KCCM&*'P(@/H* +XM9F:0=;+H`````.EW____OPH```#H`````.EH____9F:09I!!5T%6055!5%53 +XM2('LF````$B)?"083(NOP````$V%[71;2(V$)(````!(B40D".L)38MM6$V% +XM[71#08M%4(7`=>])BUT`OP````"Y"````/Q(B=[SIG4W2(M4)!CV0F1`=UUO4B!Q)@```!;74%<05U!7D%?P[\` +XM````N0@```!(B=[SIG2X_+\`````N0H```!(B=[SI@^$>____TB+5"08@WI@ +XM`0^$CP```$B+?"082(G>Z![Y__^%P`^$,0,``#';13'_2,=$)#@`````ZS]F +XM9I!F9I!(BWPD.$@#>QCH`````$F)QTV%_P^$V0,``$B+5"0X2(MS"$F-/!=( +XMBU,8Z`````!(BT,82`%$)#A)BWT(2(G>Z`````!(AQCH`````$F)Q^NM28-]0`D/A6;___])BWT(2(UT)$#H`````$B%P`^$ +XMU`0``$B+1"08]D!D$`^%C@,``$B+@,````!(AU(QT0D*`````"`.`!T%4B#Q0%*C40]`$@Y +XM1"0@2(EL)"AWYD@Y1"0@#X2@`0``3(MT)#!,`W0D.$R+9"0P33GF=R'I+@$` +XM`&:028U<)`%,B>?H`````$R-)`--.>8/AA(!``!,B?Y,B>?H`````(7`===( +XMBT0D*$Z-?#@!3#E\)"`/AW3___])BW4`2(M\)!CH]/;__X7`#X50`0``2(M$ +XM)#A!QT54`0```$F)12A,B>_H`````$F+=0!(BWPD&#'2Z`````!(A<`/A/O\ +XM__^+0#"%P`^$\/S__TF+?1A(A?]T#4F+=2A(A?8/APCHN/O__TF+?0A(B=[H`````$B%P$B)PW7?Z`````"%P`^%EP(``(L%```` +XM`(7`#X5=`0``2(LU`````(M&#(/H`87`B48,#X@U`@``2(L&Q@`*2(/``4B) +XM!NEP_/__28MU`$B+?"08Z"'V__^%P`^$/O___^D:_O__2(GJ3(G^3(GWZ``` +XM``!(BU0D.$B-1!4`2(M4)##&!!``2(/``4B)1"0XZ<[^__](BWPD&$B)WNBH +XM]?__A<`/A/7^___IM?S__^CV^O__9F:09F:0Z53___](BWPD,$@#?"0X2(GJ +XM3(G^Z`````!(`6PD..F:_O__28MU`$B+?"08,=+H`````$R+8!A,B>?H```` +XM`$B+?"0P2`-\)#A(B<),B>9(B4Q[44QY$4Q]DF+?0A,B?;H`````$B%P$F)Q@^$7P$``$B-E"2`````,?9, +XMB??H`````$@[1"0(#X4D`0``2(M4)!B+G"2,````2(M"4$B+>`CH`````$B) +XMQDB+1"082(G:2(MX&.@`````2(7`2(G-````2(M\)!CH`````(7`=(1( +XMBU0D&(-Z%`%T/[]`````Z`````!(A$F)Q$B+A"2`````28D$)$B+A"2( +XM````28E$)`CI2?___[\*````Z`````#I/OK__[\@````Z`````!(A6P````,`````!6-_````!PBZ +XM````!PCN````"+H````#``````7HGP````,``````B^O````"0`````0`D8R +XM`0``"@`````"1S(!```"(P`*``````)(5`````(C"``'"#0````)`````)@" +XM9EP"```+7W```F50````"(W`*``````)\W@(```(C +XM=`H``````GWN`@```B-W"U]L8@`"@`D!```"(W@*``````*#5`````,CB`$* +XM``````*$_@````,CD`$`#`%4````;`(```VM``````<(7`(```P!5````(P" +XM```-K0````WB````#50`````!PAR`@``#`'^````K`(```VM````#?X````- +XM5``````'")("```,`50```#,`@``#:T````-Z`````U4``````<(L@(```X` +XM`````0<(T@(```\T````[@(``!"J`````@`/-````/X"```0J@```````P`` +XM```"A3@!```""`4``````P`````&)LP````#``````8JS`````\T````-@,` +XM`!"J````#P`1"`9Z6P,```H`````!GL0`P```B,`"@`````&?!L#```"(P0` +XM`P`````&?38#```#``````%D@,```(C"``#``````>&%04``!)%;&8` +XM""90!0``#@`````!`P`````()V$%```.``````$3!`@V``8``!0``````!0` +XM`````10``````A0``````Q0`````!!0`````!10`````!A0`````!Q0````` +XM"!0`````"10`````"A0`````"Q0`````#!0`````#10`````#A0`````#Q0` +XM````$!0`````$10`````$A0`````$Q0`````%!0`````%10`````%A0````` +XM%P`#``````A/9P4``!$("'@B!@``"@`````(>*T&```"(P``"0````!`"&BM +XM!@``"@`````(;-<````"(P`*``````AMK0````(C"`H`````"&[7`````B,0 +XM"@`````(;]<````"(Q@*``````AP``8```(C(`H`````"'%F`````B,D"@`` +XM```(=K,&```"(R@*``````AW9@````(C,`H`````"'@+!@```B,X``<((@8` +XM``<(5@4```,`````"'DB!@```P`````)+FH$```#``````DP"@4```,````` +XM"3(Z!0``$0@*)/P&```*``````HD)0<```(C```)`````!`*(24'```*```` +XM``HBZ`````(C``H`````"B3E!@```B,(``<(_`8``!$("C9"!P``"@`````* +XM-O<'```"(P``"0````!("BCW!P``"@`````**>@````"(P`*``````HJZ``` +XM``(C"`H`````"BOH`````B,0"@`````*+.@````"(Q@+861D``HN5`````(C +XM(`H`````"B]4`````B,D"@`````*,%0````"(R@*``````HQ5`````(C+`H` +XM````"C)4`````B,P"@`````*,U0````"(S0*``````HT5`````(C.`H````` +XM"C8K!P```B-```<(0@<``!$("C\4"```"@`````*/UD(```"(P``"0`````@ +XM"CI9"```"@`````*.^(````"(P`*``````H\X@````(C"`H`````"CWS```` +XM`B,0"@`````*/_T'```"(Q@`!P@4"```$1`*4H0(```*``````I28`D```(C +XM``H`````"E)F"0```B,(``D`````>`I#8`D```H`````"D3H`````B,`"VES +XM``I%LP8```(C"`MO@`*6=<````"(P@+;7-Z``I:UP````(C$`H` +XM````"EO7`````B,8"@`````*750````"(R`*``````I?D0D```(C*`H````` +XM"F"Z"0```B,X``<(T0D``!,$"H1M"@``%```````%``````!%``````"%``` +XM```#%``````$`!$0"IB2"@``"@`````*F$`*```"(P`*``````J8D@H```(C +XM"``'"$`*```1$`J9O0H```H`````"IGW!P```B,`"@`````*F;T*```"(P@` +XM!PCW!P``$1`*FN@*```*``````J:60@```(C``H`````"IKH"@```B,(``<( +XM60@``!$0"IP3"P``"@`````*G"4'```"(P`*``````J<$PL```(C"``'""4' +XM```1$`J>/@L```H`````"IXE!P```B,`"@`````*GA,+```"(P@`$1`*H&,+ +XM```*``````J@8`D```(C``H`````"J!F"0```B,(`!$("J)Z"P``"@`````* +XMHF`)```"(P``"0````#8"F85#0``"@`````*9^@````"(P`*``````IJ5``` +XM``(C"`H`````"FM4`````B,,"VEE8P`*;50````"(Q`+;V5C``IN5`````(C +XM%`ME:6X`"F\5#0```B,8"@`````*50````"(S`*``````IZ5`````(C-`H````` +XM"GM4`````B,X"@`````*?%0````"(SP*``````I]5`````(C0`H`````"GY4 +XM`````B-$"@`````*@&`)```"(T@*``````J!8`D```(C4`H`````"H)@"0`` +XM`B-8"@`````*BD8*```"(V`*``````J35`````(C9`H`````"I8R`0```B-H +XM"@`````*F&T*```"(W`*``````J9F`H```,C@`$*``````J:PPH```,CD`$* +XM``````J<[@H```,CH`$*``````J>&0L```,CL`$*``````J@/@L```,CP`$* +XM``````JB8PL```,CT`$`!PA%!0``%0`````!XP$````````````````````` +XM`G<(8`T``!9E8W```>)@#0```5461@"0```5$` +XM!PAZ"P``&`$``````5X#`0``````````````````````````Q@T``!EE8W`` +XM`5T#8`T````````:P"8`D````````@$@````_H````'A(``!"J````!``' +XM".@````F``````$X`50``````````````````````````````+T2```C96-P +XM``$W8`T````````D``````$WZ``````````K`````'\2```E``````%P`@$``````````````````````````*<4 +XM```99``!;P+H`````````!ES>@`!;P+S`````````!IC``%Q`N@````````` +XM.NT3`````````74"AQ0``#L*%````````"W_$P```#7M$P````````%W`CL* +XM%````````#O_$P``````````/``````!I0$!`4L5```Y96-P``&D`6`-```Y +XM@`````/``````!*`(!`2`6```Y96-P``$G`F`-```Y&```+9D5```MC14``#8`````-Z,5````````-Z\5````````,+L5```P +XMQQ4``#?1%0```````##=%0``-^<5````````-_$5````````,/L5```O!Q8` +XM``.1T'XP$Q8``#4@%@````````$N`BT\%@``+3(6```V`````#=(%@`````` +XM`#!3%@``,%T6```W:!8`````````````/GL6```````````````````````` +XM`9H!H!@``"V7%@``+8P6```N`````````````````````#>B%@`````````` +XM-:X6`````````9L!+;P6```V`````#?&%@```````#?1%@```````#7M$P`` +XM``````&,`CL*%````````"W_$P```````#\``````HH6%````0%```````*@ +XM`50````!`0!^!````@"X`````0'[#@H``0$!`0````$O=7-R+VEN8VQU9&4` +XM+W5S7!E7!E6%)*U45)-ZX(+#A(,&"`4@@24CP#%D)NMQ@A8`Z4!`B0!`PDK`W=5`PF; +XM`W=5`PE_""!RA7J`@'*!"!4#>E5,"'((/`CTZ`A;`PP(C4B0"%D(,`@\"!Y( +XM20@>20-8[P/'?M,##@A_`W@K.`ARQ@@\".4#L0$(1PB=.DA97TB.CH`#$<4# +XMO'X(<58#T`%_")E62@.E?@@=`YX!",4#*0C%",$#<0C%`\%^X0C,`X($`B@! +XM($18G00"`Y-^_?X$`0/J`<6.=`0"`Y%^"#G&!`$#Z@$Y!`(#EGY'!`$#Z@%Q +XM!`(#EGXY!`$#Z@$Y,6T(+00"`Y%^_<@$`0-K",7]6`/D`+<#G'_ACX,(5ZJ` +XM`W:-`R2-`V(('0,*_0A<`[1^X0/:`P(K`?Z0"%8#=XT(F4H*2!F +XM86EL960Z("5S`&YO="!E;F]U9V@@;65M;W)Y`"YD96)U9P`N9VYU+FQI;FMO +XM;F-E+G=I+@`N;&EN90`N&!HP%C02.`X\"````````%``` +XM```````!>E(``7@0`0,,!PB0`0``%````!P`````````<``````````````` +XM'````#0`````````M@$```!*@P6,`U$.<(T"A@0````D````5`````````#\ +XM`````$(.$$$.&(8#C`)$#B!$#F"#!```````%````'P`````````:P````!. +XM#B"#`X8"+````)0`````````Z0$```!"#A!"#AB-`XX"10X@00XH00XP1`YP +XM@P:&!8P$````'````,0`````````]`````!!#A"&`D0.&$0.((,#```<```` +XMY``````````Y`0```$J&!(,%5`ZP`8T"C`,``"0````$`0```````"\!```` +XM0@X00@X800X@00XH1`YP@P6&!(P#C0(<````+`$```````#_`````$$.$(8" +XM1`X81`Y@@P,``"0```!,`0```````*(`````0@X0C0)%#AB,`T0.((8$1`XH +XM1`XP@P44````=`$````````B`````$8.$``````4````C`$````````W```` +XM`$0.$``````<````I`$```````!``0```%J,`X,%C0*&!$<.8````#0```#$ +XM`0```````*8#````0@X01PX80@X@0@XH00XPA@:,!8T$C@./`DD..$<.T`&# +XM!P``````'````/P!````````VP````!!#A"&`D4.&$0.((,#```T````'`(` +XM``````#N!@```$(.$$(.&$(.($(.*$$.,$$..$<.T`&#!X8&C`6-!(X#CP(` +XM`````'``````````BP`````````"`'<(BP`````````F`@````````,`=_`` +XM`````````````````````'``````````E@`````````!`%66`````````($! +XM`````````0!00` +XM``````"W!`````````$`42\%````````.04````````!`%$````````````` +XM````````[0,```````#[!`````````$`7``%````````B04````````!`%P` +XM````````````````````D`4```````"1!0````````(`=PB1!0```````)4% +XM`````````@!W$)4%````````F04````````"`'<8F04```````"$!@`````` +XM``(`=R``````````````````````D`4```````"K!0````````$`5:L%```` +XM````&08````````!`%89!@```````!H&`````````0!5&@8```````!*!@`` +XM``````$`5DL&````````A`8````````!`%8`````````````````````J04` +XM```````8!@````````$`4QH&````````208````````!`%-+!@```````(0& +XM`````````0!3`````````````````````+P%````````OP4````````!`%"_ +XM!0````````(&`````````0!1&@8```````!5!@````````$`40`````````` +XM```````````1!@```````!H&`````````0!0:08```````!P!@````````$` +XM4`````````````````````"0!@```````*X&`````````@!W"*X&```````` +XMR0<````````#`'>P`0````````````````````"0!@```````+0&```````` +XM`0!5M`8```````!?!P````````$`7&\'````````R0<````````!`%P````` +XM````````````````D`8```````"Y!@````````$`5+D&````````P08````` +XM```!`%4`````````````````````D`8```````#!!@````````$`4<$&```` +XM````3P<````````!`%-O!P```````,D'`````````0!3```````````````` +XM`````)`&````````P08````````!`%+!!@```````%<'`````````0!6;P<` +XM``````#)!P````````$`5@````````````````````#0!P```````-('```` +XM`````@!W"-('````````U`<````````"`'<0U`<```````#5!P````````(` +XM=QC5!P```````-8'`````````@!W(-8'````````V@<````````"`'0T```````"P#0````````$`7,0-````````Q@T````````! +XM`%S>#0```````.`-`````````0!<]@T```````"0#@````````$`7*X.```` +XM````Z`X````````!`%P`#P```````#P/`````````0!<0P\```````"[#P`` +XM``````$`7,H/````````!A`````````!`%P`````````````````````WPP` +XM``````!`#P````````$`7D,/````````!A`````````!`%X````````````` +XM````````#0\````````4#P````````$`4"\/````````0P\````````!`%`` +XM````````````````````<@X```````!U#@````````$`4'4.````````@PX` +XM```````!`%1##P```````$T/`````````0!4`````````````````````-\, +XM````````<`T````````!`%/V#0```````*L.`````````0!3``\````````Y +XM#P````````$`4T,/````````?P\````````!`%.[#P````````80```````` +XM`0!3`````````````````````-\,````````[`P````````!`%`'#P`````` +XM`!0/`````````0!0`````````````````````!`0````````$1`````````" +XM`'<($1`````````6$`````````(`=Q`6$````````!H0`````````@!W&!H0 +XM````````ZQ`````````"`'<@`````````````````````!`0````````=Q`` +XM```````!`%6:$````````*T0`````````0!5M!````````"^$`````````$` +XM5=P0````````X1`````````!`%4`````````````````````$!`````````U +XM$`````````$`5%P0````````=!`````````!`%2:$````````*@0```````` +XM`0!4M!````````"[$`````````$`5``````````````````````B$``````` +XM`)\0`````````0!3H1````````#K$`````````$`4P`````````````````` +XM```D$````````'00`````````0!4FA````````"H$`````````$`5+00```` +XM````NQ`````````!`%3<$````````.80`````````0!4```````````````` +XM`````"00````````-1`````````!`%1<$````````*@0`````````0!4M!`` +XM``````"[$`````````$`5,40````````UQ`````````!`%0````````````` +XM````````)!````````"M$`````````$`5;00````````OA`````````!`%7% +XM$````````-<0`````````0!5W!````````#A$`````````$`50`````````` +XM``````````#P$````````/(0`````````@!W"/(0````````]!`````````" +XM`'<0]!````````#V$`````````(`=QCV$````````/@0`````````@!W(/@0 +XM````````^1`````````"`'%P`````` +XM``$`70````````````````````"U$0```````,(1`````````0!0?!(````` +XM``"[$@````````$`4/H5`````````Q8````````!`%`````````````````` +XM````@A8```````"%%@````````$`4(46````````E18````````!`%18%P`` +XM`````&(7`````````0!4`````````````````````"$1````````=A$````` +XM```!`%9_$0```````%<3`````````0!6WA,```````#,%`````````$`5OL4 +XM````````)14````````!`%9$%0```````-X7`````````0!6```````````` +XM`````````"$1````````>!$````````!`%Q_$0```````)03`````````0!< +XMWA,```````#,%`````````$`7/L4````````6!4````````!`%R4%0`````` +XM`-X7`````````0!<`````````````````````"$1````````?!$````````! +XM`%Y_$0```````(H3`````````0!>WA,```````#,%`````````$`7OL4```` +XM````WA<````````!`%X`````````````````````$A<````````7%P`````` +XM``$`59L7````````G1<````````!`%"=%P```````,07`````````0!5```` +XM`````````````````+T1````````PA$````````!`%0#%0````````@5```` +XM`````0!4`````````````````````%@5````````8!4````````!`%"_%0`` +XM`````,05`````````0!0`````````````````````"$1`````````1,````` +XM```#`)'H?@$3````````!A,````````!`%4&$P```````*L5`````````P"1 +XMZ'ZK%0```````+05`````````0!5M!4```````#.%0````````,`D>A^SA4` +XM``````#3%0````````$`5=,5````````WA<````````#`)'H?@`````````` +XM```````````A$0```````'81`````````0!6?Q$```````!M%0````````$` +XM5FT5````````>!4````````!`%&4%0```````!<6`````````0!6U!8````` +XM``#C%@````````$`5A`7````````6!<````````!`%8````````````````` +XM````(1$```````!^$0````````$`7W\1````````8!,````````!`%]@$P`` +XM`````)X3`````````0!0GA,````````E%0````````$`7R45````````.A4` +XM```````!`%`Z%0```````-X7`````````0!?`````````````````````"$1 +XM````````>!$````````!`%Q_$0```````)<3`````````0!%0```````*85```````` +XM`0!5JQ4````````:%@````````$`7-06````````XQ8````````!`%P0%P`` +XM`````%@7`````````0!<`````````````````````"$1````````-A$````` +XM```!`%-M$0```````'41`````````0!3S!$```````!$$@````````$`4[L2 +XM````````I1,````````!`%.Z$P```````$D4`````````0!3>10```````#[ +XM%`````````$`4Q45````````6YC7W-E8W1I;VYS`&(0``!I;G-EPX```````!O +XM#@```````'(.````````4@X```````!;#@```````$(.````````1PX````` +XM```T#@```````#H.````````+@X````````Q#@`````````````````````` +XM```````U$````````%,0````````W!````````#K$``````````````````` +XM``````````!W$````````(<0````````Q1````````#<$````````)40```` +XM````F!````````"+$````````)(0`````````````````````````````!(1 +XM````````(1$````````Z%P```````-X7````````XQ8````````0%P`````` +XM``,6````````U!8```````!/$@```````,`2```````````````````````` +XM`````%T2````````P!(```````#-%P```````-X7````````O!<```````#` +XM%P```````+(7````````NA<```````"=%P```````*@7````````F1<````` +XM``";%P```````(`7````````E!<```````!B%P```````'87````````1!<` +XM``````!8%P```````.T6````````$!<```````"N%@```````-06```````` +XME18```````"D%@```````(46````````BQ8```````!_%@```````((6```` +XM````5Q8```````!>%@```````$<6````````4A8````````O%@```````#46 +XM````````*18````````L%@````````,6````````'18````````````````` +XM````````````M1$```````#@$0```````/L4````````%14````````````` +XM````````````````X!$```````!$$@```````"L7````````.A<````````E +XM%0```````.05````````L10```````#[%````````,`2````````!10````` +XM````````````````````````X!$```````!$$@```````"L7````````.A<` +XM``````#3%0```````.05````````$P```````+$3 +XM````````NA,````````K$P```````*43````````'1,````````A$P`````` +XM``X3````````&1,````````&$P````````D3````````]!(````````!$P`` +XM`````,`2````````YA(`````````````````````````````X!$```````!$ +XM$@```````-,5````````Y!4```````#`$@```````,T2```````````````` +XM`````````````/$1````````&1(```````#3%0```````.05````````Q1(` +XM``````#-$@```````"L2````````-A(````````E$@```````"@2```````` +XM`````````````````````#$4````````L10````````0%P```````"L7```` +XM````U!8```````#C%@```````.05`````````Q8````````5%0```````"45 +XM`````````````````````````````#$4````````6!0````````7%P`````` +XM`"L7````````U!8```````#C%@```````!45````````)14```````!Q%``` +XM`````+$4````````:A0```````!L%````````&04````````9Q0````````` +XM````````````````````CA0```````"Q%````````-06````````XQ8````` +XM````````````````````````16QF-C1?061D<@!D8F=?F4`7V9L86=S`&5?=F5RF4`1T5L +XM9E]%:&1R`&1?6U?;&ES=`!S96-?861D`&-O<'E?9&%T80!C;W!Y`&5?96YT@!S='%H7V9I6UT86(`:7-?F5?=`!D7W1Y<&4`14Q&7U1? +XM4UE-`$5L9E]4>7!E`'-E9U]L:7-T`&9L86=S`%]?=6EN=#8T7W0`16QF-C1? +XM2&%L9@!S96-T:6]NF4`:6YF;70`14Q&7U1?0EE410!D7V)U9@!S:7IE`$5,1E]47U=/4D0` +XM;6]D:69Y7W-E8W1I;VX`14Q&7U1?4TA$4@!C;W!Y7W-H9'(`<'-E=61O`'-H +XM7V]F9G-E=`!A9&1O<'0`:6YS97)T7W-H=&%B`$5,1E]47T%$1%(`7V5X=')A +XM`'-E=%]S:'-T5]C;VYT96YT`'9?;61A=`!%;&9? +XM1&%T80!C;VYT96YT`&1?9FQA9W,`95]T>7!E`'9?6UT86(`+G-T`!M96UM;W9E`&5L9E]E`!U<&1A=&5?5]D871A`&5L9E]G971D871A`&-O<'E?5]C;VYT96YT`&-R +XM96%T95]S>6UT86(`;65M8W!Y`'-TP,````````"````)````/S_________@P,````````*````"0```*X````` +XM````B`,````````"````)````/S_________C0,````````*````"0```+8` +XM````````E0,````````"````)````/S_________O0,````````*````"0`` +XM`+8`````````]0,````````"````)@```/S_________$`0````````"```` +XM)P```/S_________;P0````````"````&@```/S_________LP0````````" +XM````&0```/S_________V@0````````"````&P```/S_________!@4````` +XM```"````'P```/S_________"P4````````*````"0```,``````````&@4` +XM```````"````(````/S_________'P4````````*````"0```-@````````` +XM*P4````````"````*````/S_________-04````````"````'P```/S_____ +XM____.@4````````*````"0```!X`````````204````````"````(````/S_ +XM________4P4````````"````'P```/S_________6`4````````*````"0`` +XM`.4`````````9P4````````"````(````/S_________<04````````"```` +XM'P```/S_________=@4````````*````"0```#<`````````A04````````" +XM````(````/S_________M04````````"````&@```/S__________@4````` +XM```"````*@```/S_________"P8````````"````(P```/S_________408` +XM```````"````'P```/S_________5@8````````*````"0```!X````````` +XM908````````"````(````/S_________;`8````````"````'P```/S_____ +XM____<08````````*````"0````,!````````@`8````````"````(````/S_ +XM________O08````````"````&0```/S_________T08````````"````&0`` +XM`/S_________/P<````````"````&P```/S_________=0<````````"```` +XM'P```/S_________>@<````````*````"0```!P!````````B0<````````" +XM````(````/S_________DP<````````"````'P```/S_________F`<````` +XM```*````"0```#H!````````IP<````````"````(````/S_________L0<` +XM```````"````'P```/S_________M@<````````*````"0```%@!```````` +XMQ0<````````"````(````/S_________2P@````````"````&0```/S_____ +XM____;@@````````"````&P```/S_________LP@````````*````"P`````` +XM````````N@@````````"````+0```/S_________R0@````````"````'P`` +XM`/S_________S@@````````*````"0```',!````````W0@````````"```` +XM(````/S_________YP@````````"````'P```/S_________[`@````````* +XM````"0```%@!````````^P@````````"````(````/S_________$0D````` +XM```"````+P```/S_________*0D````````"````)P```/S_________>@D` +XM```````"````,````/S_________N`D````````"````'P```/S_________ +XMO0D````````*````"0```)$!````````S`D````````"````(````/S_____ +XM____U@D````````"````'P```/S_________VPD````````*````"0```+D! +XM````````Z@D````````"````(````/S_________[PD````````*````"0`` +XM`*L!````````^PD````````"````(````/S_________,0H````````"```` +XM,@```/S_________5`H````````"````,P```/S_________:PH````````" +XM````-````/S_________E`H````````*````"0```-$!````````G@H````` +XM```"````(````/S_________MPH````````"````,0```/S_________YPH` +XM```````"````,0```/S_________0@L````````*````"0```+8````````` +XM:0L````````*````"0```*8`````````A@L````````*````"0```*X````` +XM````EPL````````*````"0```.,!````````H@L````````+````"0```.,! +XM````````JPL````````+````"0```.H!````````M`L````````+````"0`` +XM`/P!````````O0L````````+````"0````("````````X@L````````"```` +XM-0```/S_________\`L````````"````-@```/S_________(@P````````" +XM````,0```/S_________?PP````````"````)P```/S_________DPP````` +XM```+````"0```+8`````````RPP````````"````.````/S_________Z`P` +XM```````"````.0```/S__________PP````````"````&0```/S_________ +XM'0T````````"````.@```/S_________5`T````````*````"0```+8````` +XM````?@T````````"````)@```/S_________DPT````````"````'````/S_ +XM________N`T````````*````"0```*8`````````T@T````````*````"0`` +XM`*X`````````$0X````````"````.````/S_________*@X````````"```` +XM.0```/S_________/@X````````"````'````/S_________3@X````````" +XM````&0```/S_________:PX````````"````.@```/S_________FPX````` +XM```"````)P```/S_________W`X````````"````.P```/S_________]PX` +XM```````"````*P```/S_________`0\````````"````(P```/S_________ +XM$`\````````"````'P```/S_________%0\````````*````"0```(X````` +XM````)`\````````"````(````/S_________*0\````````"````(P```/S_ +XM________20\````````"````'P```/S_________3@\````````*````"0`` +XM`#\"````````70\````````"````(````/S_________9P\````````"```` +XM'P```/S_________;`\````````*````"0```","````````>P\````````" +XM````(````/S_________A0\````````"````'P```/S_________B@\````` +XM```*````"0```(,"````````F0\````````"````(````/S_________HP\` +XM```````"````'P```/S_________J`\````````*````"0```&T"```````` +XMMP\````````"````(````/S_________O`\````````*````"0```*L!```` +XM````Q@\````````"````*````/S_________T`\````````"````'P```/S_ +XM________U0\````````*````"0````@"````````Y`\````````"````(``` +XM`/S_________[@\````````"````'P```/S_________\P\````````*```` +XM"0```%4"`````````A`````````"````(````/S_________)A`````````" +XM````/````/S_________,1`````````"````/0```/S_________91`````` +XM```"````/````/S_________Q0````````"````/````/S_________BA0````````"```` +XM/0```/S_________UA0````````"````0P```/S_________-A4````````" +XM````0P```/S_________4!4````````"````,0```/S_________7!4````` +XM```"````-0```/S_________=!4````````"````0P```/S_________HA4` +XM```````"````0@```/S_________MQ4````````"````,0```/S_________ +XMP!4````````"````-0```/S_________U!4````````*````"0```+X"```` +XM````X!4````````"````*````/S_________YQ4````````"````/0```/S_ +XM________\14````````"````/@```/S_________)18````````"````*@`` +XM`/S_________0Q8````````"````1````/S_________9Q8````````"```` +XM'````/S_________>Q8````````"````.@```/S_________D18````````" +XM````10```/S_________JA8````````"````,P```/S_________VA8````` +XM```"````/P```/S_________Z18````````"````,P```/S_________$Q<` +XM```````"````'P```/S_________&!<````````*````"0````,!```````` +XM)Q<````````"````(````/S_________+!<````````*````"0```+`"```` +XM````-A<````````"````*````/S_________0!<````````"````'P```/S_ +XM________11<````````*````"0```)$!````````5!<````````"````(``` +XM`/S_________7A<````````"````'P```/S_________8Q<````````*```` +XM"0```#\"````````P`````````*````%@```/,%````````@``````````*````%@```#0#```` +XM````C0`````````*````%@```.4&````````E``````````*````%@```&<( +XM````````FP`````````*````%@```.(!````````H``````````*````%@`` +XM`'`&````````L``````````*````%@```/$'````````O0`````````*```` +XM%@```)@#````````P@`````````*````%@```(L%````````S0`````````* +XM````%@```*T!````````V``````````*````%@```#H&````````]``````` +XM```*````%@````0#````````_P`````````*````%@```-L!````````"@$` +XM```````*````%@```*\'````````%@$````````*````%@```'@$```````` +XM)`$````````*````%@```(P`````````.0$````````*````%@```#@"```` +XM````;`$````````*````%@```*4`````````>@$````````*````%@```)D$ +XM````````E@$````````*````%@```)P`````````I`$````````*````%@`` +XM`'T!````````L@$````````*````%@```/H#````````P`$````````*```` +XM%@```!0<````````*````%@```+H#````````E0<````````*````%@`` +XM`/H!````````HP<````````*````%@````@$````````L0<````````*```` +XM%@```*`!````````OP<````````*````%@```.,%````````S0<````````* +XM````%@```#T`````````VP<````````*````%@```!<$````````Z0<````` +XM```*````%@```,$&````````!@@````````*````%@```!X&````````%0@` +XM```````*````%@```(X!````````(0@````````*````%@```+$&```````` +XM+P@````````*````%@```(('````````/0@````````*````%@```,H$```` +XM````2P@````````*````%@```"T`````````:`@````````*````%@````D! +XM````````=@@````````*````%@```+8!````````A0@````````*````%@`` +XM`)H&````````D0@````````*````%@```+$&````````\`@````````*```` +XM%@```+\(````````_@@````````*````%@```"H'````````&@D````````* +XM````%@```%0!````````*`D````````*````%@```/X$````````-@D````` +XM```*````%@```)($````````1`D````````*````%@```"H(````````4@D` +XM```````*````%@```)\'````````=0D````````*````%@````D!```````` +XM@PD````````*````%@```+8!````````D@D````````*````%@````P"```` +XM````G@D````````*````%@```-L&````````K`D````````*````%@```,`' +XM````````PPD````````*````%@```!X&````````T@D````````*````%@`` +XM`-D`````````"`H````````*````%@```"H'````````%@H````````*```` +XM%@```#T`````````)`H````````*````%@```)D'````````,@H````````* +XM````%@```"4#````````3PH````````*````%@```,@#````````50H````` +XM```*````%@```,\`````````6PH````````*````%@```)\$````````80H` +XM```````*````%@```*$"````````9PH````````*````%@```*(&```````` +XM=@H````````*````%@```"<"````````A`H````````*````%@```.L#```` +XM````H0H````````*````%@```"<"````````KPH````````*````%@```.L# +XM````````S`H````````*````%@```"<"````````V@H````````*````%@`` +XM`.L#````````]PH````````*````%@```"<"````````!0L````````*```` +XM%@```.L#````````(@L````````*````%@```"<"````````,`L````````* +XM````%@```.L#````````1PL````````*````%@```-L&````````50L````` +XM```*````%@```,`'````````;`L````````*````%@```&(%````````>PL` +XM```````*````%@```$<"````````APL````````*````%@```%T!```````` +XME0L````````*````%@```+,$````````HPL````````*````%@```$`"```` +XM````VPL````````*````%@```)4&````````Z0L````````*````%@```,$# +XM````````]PL````````*````%@```%``````````!0P````````*````%@`` +XM`&X(````````$PP````````*````%@```!<'````````(0P````````*```` +XM%@```$H#````````+PP````````*````%@```+\!````````/0P````````* +XM````%@```)X%````````2PP````````*````%@```$L%````````60P````` +XM```*````%@```-X"````````9PP````````*````%@```$`(````````=0P` +XM```````*````%@```$(%````````@PP````````*````%@```/D'```````` +XMD0P````````*````%@```"X#````````GPP````````*````%@```"4$```` +XM````K0P````````*````%@```#<`````````NPP````````*````%@```&@$ +XM````````R@P````````*````%@```-<"````````V0P````````*````%@`` +XM`#\!````````Z`P````````*````%@```'(!````````]PP````````*```` +XM%@```)D'````````!@T````````*````%@```'('````````'`T````````* +XM````%@```'X(````````(PT````````!`````@``````````````*PT````` +XM```!`````@```'``````````:`T````````*````%@```#4%````````<`T` +XM```````!`````@```'``````````>`T````````!`````@```"8"```````` +XM@`T````````*````$@``````````````E`T````````*````$@```#D````` +XM````H@T````````*````$@```((`````````IPT````````*````%@```-,# +XM````````L@T````````*````$@```+@`````````S@T````````*````%@`` +XM`$0`````````U@T````````!`````@```#`"````````W@T````````!```` +XM`@```"P#````````Y@T````````*````$@```!0!````````^@T````````* +XM````$@```(D!````````"`X````````*````$@```-(!````````%@X````` +XM```*````$@````@"````````*PX````````*````%@````$$````````-@X` +XM```````*````$@```%$"````````.PX````````*````%@```&H#```````` +XM2`X````````*````%@````X&````````4`X````````!`````@```#`#```` +XM````6`X````````!`````@```)L#````````8`X````````*````$@```(<" +XM````````=`X````````*````$@```+\"````````>0X````````*````%@`` +XM`+$&````````A`X````````*````$@```/4"````````D@X````````*```` +XM$@```%$#````````F0X````````*````%@```%H&````````H0X````````! +XM`````@```*`#````````J0X````````!`````@```(D%````````L0X````` +XM```*````$@```)H#````````Q0X````````*````$@```#<$````````U`X` +XM```````*````$@```),$````````V0X````````*````%@```,$````````` +XMY`X````````*````$@```,D$````````_0X````````*````$@```/\$```` +XM````#`\````````*````$@```$@%````````(P\````````*````%@```)8! +XM````````*P\````````!`````@```)`%````````,P\````````!`````@`` +XM`(0&````````.P\````````*````$@```'X%````````30\````````*```` +XM$@```-X%````````7`\````````*````$@```$T&````````:P\````````* +XM````$@```)8&````````<`\````````*````%@````$$````````>P\````` +XM```*````$@```-\&````````@@\````````*````%@```/0$````````B@\` +XM```````!`````@```)`&````````D@\````````!`````@```,D'```````` +XMF@\````````*````$@```!4'````````K@\````````*````$@```$X'```` +XM````O0\````````*````$@```)<'````````S`\````````*````$@```,T' +XM````````T0\````````*````%@```+$&````````W`\````````*````$@`` +XM`!8(`````````Q`````````*````%@```+P"````````"Q`````````!```` +XM`@```-`'````````$Q`````````!`````@```/\(````````&Q`````````* +XM````$@```%\(````````+Q`````````*````$@```.@(````````/1`````` +XM```*````$@```#$)````````71`````````*````$@```&<)````````9!`` +XM```````*````%@```!8%````````!`````````!`````@```/\)````````@!`````````*````$@```"(*```` +XM````E!`````````*````$@```(,*````````HA`````````*````$@```,P* +XM````````IQ`````````*````%@```#("````````LA`````````*````$@`` +XM`.\*````````QQ`````````*````%@```"L$````````TA`````````*```` +XM$@```!(+````````V1`````````*````%@```.$`````````Y!`````````! +XM`````@`````*````````[!`````````!`````@```*(*````````]!`````` +XM```*````$@```$@+````````!Q$````````*````$@```-`+````````#!$` +XM```````*````%@```+$&````````%A$````````*````$@```"P,```````` +XM)1$````````*````$@```(@,````````-!$````````*````$@```.0,```` +XM````.A$````````*````%@```'D&````````11$````````!`````@```+`* +XM````````31$````````!`````@```-(*````````51$````````*````$@`` +XM`!H-````````:!$````````*````$@```%(-````````;1$````````*```` +XM%@```+$&````````=Q$````````*````$@```'4-````````AA$````````* +XM````$@```)@-````````C!$````````*````%@```.@!````````EQ$````` +XM```!`````@```.`*````````GQ$````````!`````@```!<+````````IQ$` +XM```````*````$@```+L-````````NA$````````*````$@```/,-```````` +XMOQ$````````*````%@```+$&````````R1$````````*````$@```!8.```` +XM````V!$````````*````$@```#D.````````WA$````````*````%@```!P` +XM````````[Q$````````*````%@```+$&````````^A$````````*````%@`` +XM``L`````````)1(````````*````%@```-0'````````,!(````````!```` +XM`@```"`+````````.!(````````!`````@```&`,````````0!(````````* +XM````$@```&\.````````4Q(````````*````$@```*@.````````6!(````` +XM```*````%@```+$&````````8A(````````*````$@```/$.````````9Q(` +XM```````*````%0``````````````>A(````````*````$@```&`/```````` +XMA!(````````!`````@```)8+````````C!(````````!`````@```/@+```` +XM````G!(````````!`````@```)8+````````I!(````````!`````@```-X+ +XM````````OA(````````*````%@```.4"````````VA(````````*````%@`` +XM`-@#````````Y1(````````*````%@```+$&````````!1,````````*```` +XM%@```/4#````````$!,````````*````%@````$$````````'1,````````* +XM````%@```&<"````````)!,````````!`````@```&`,````````+!,````` +XM```!`````@````80````````-!,````````*````$@```*D/````````1Q,` +XM```````*````$@```%H0````````5!,````````*````$@```*,0```````` +XM61,````````*````%@```+$&````````8Q,````````*````$@```/\0```` +XM````<1,````````*````$@```+H1````````A1,````````*````%@```/4# +XM````````E!,````````*````%@````$$````````GA,````````*````$@`` +XM`/`1````````IQ,````````*````%0```$``````````N1,````````*```` +XM%0```)``````````PA,````````*````$@```"82````````U!,````````* +XM````$@```&\2````````YA,````````*````$@```-X2````````[A,````` +XM```*````%@```'H"````````'10````````*````%@```-T(````````)10` +XM```````!`````@```!`0````````+10````````!`````@```.L0```````` +XM-10````````*````$@```!03````````1Q0````````*````$@```'03```` +XM````5A0````````*````$@```-`3````````9!0````````*````$@```"P4 +XM````````;10````````*````%0```&`!````````?10````````*````$@`` +XM`&(4````````C!0````````*````%0```)`!````````F!0````````*```` +XM$@```+X4````````H10````````*````$@```!H5````````J!0````````* +XM````%@```"H!````````UA0````````*````%@```+$&````````^A0````` +XM```*````%@```%P%````````!A4````````*````%@```!$'````````'14` +XM```````*````%@````$$````````,Q4````````*````%@```+@%```````` +XM6!4````````*````%@```#T'````````=!4````````*````%@```+$&```` +XM````@!4````````*````%@```-H$````````L!4````````*````%@```!$$ +XM````````O!4````````*````%@```"$"````````%!8````````*````%@`` +XM`!(!````````(18````````*````%@```'X%````````/18````````*```` +XM%@```,H$````````:18````````*````%@````$$````````?!8````````* +XM````%@```)`"````````F!8````````*````%@```+$&````````KQ8````` +XM```*````%@```'X`````````TA8````````*````%@````$$````````X!8` +XM```````*````%@```&4'````````Z!8````````!`````@```/`0```````` +XM\!8````````!`````@```-X7````````^!8````````*````$@```'85```` +XM````#!<````````*````$@```"<6````````&A<````````*````$@```(<6 +XM````````(Q<````````*````%0```.`!````````.1<````````*````%0`` +XM`$`"````````0A<````````*````$@```+T6````````2Q<````````*```` +XM$@````87````````9A<````````*````$@```$\7````````;Q<````````* +XM````$@```+X7````````>!<````````*````$@```"T8````````@1<````` +XM```*````$@```(D8````````FQ<````````*````%0```(`#````````JQ<` +XM```````*````$@```-(8````````NA<````````*````%0```+`#```````` +XMT!<````````*````%0```!`$````````V1<````````*````$@````@9```` +XM````XA<````````*````$@```#X9````````]1<````````*````$@```-L9 +XM`````````Q@````````*````$@```%T:````````#!@````````*````$@`` +XM`-\:````````*!@````````*````%0```#`%````````.A@````````*```` +XM%0```'`%````````0Q@````````*````$@```(<;````````5A@````````* +XM````$@```%4<````````8Q@````````!`````@````T4````````:Q@````` +XM```!`````@```#$4````````A1@````````!`````@```!T4````````C1@` +XM```````!`````@```#$4````````FA@````````*````$@```)X<```````` +XMI1@````````*````%0```-`%````````LA@````````*````%0```#`&```` +XM````NQ@````````*````$@```.<<````````Q!@````````*````$@```&D= +XM````````S1@````````*````%0```+`&````````V1@````````*````$@`` +XM`+(=````````YQ@````````*````%@```&X$````````]!@````````*```` +XM%@```$\"````````Q0`````````!`````@``````````````'``````````* +XM````$```````````````(``````````!`````@``````````````-``````` +XM```*````$```````````````.``````````!`````@```'``````````7``` +XM```````*````$```````````````8``````````!`````@```#`"```````` +XMC``````````*````$```````````````D``````````!`````@```#`#```` +XM````K``````````*````$```````````````L``````````!`````@```*`# +XM````````Y``````````*````$```````````````Z``````````!`````@`` +XM`)`%````````#`$````````*````$```````````````$`$````````!```` +XM`@```)`&````````-`$````````*````$```````````````.`$````````! +XM`````@```-`'````````9`$````````*````$```````````````:`$````` +XM```!`````@`````)````````C`$````````*````$```````````````D`$` +XM```````!`````@`````*````````O`$````````*````$``````````````` +XMP`$````````!`````@```+`*````````W`$````````*````$``````````` +XM````X`$````````!`````@```.`*````````_`$````````*````$``````` +XM``````````(````````!`````@```"`+````````)`(````````*````$``` +XM````````````*`(````````!`````@```&`,````````9`(````````*```` +XM$```````````````:`(````````!`````@```!`0````````C`(````````* +XM````$```````````````D`(````````!`````@```/`0````````(``````` +XM```*`````@``````````````.``````````*`````@```'``````````6``` +XM```````*`````@```#`"````````@``````````*`````@```#`#```````` +XMF``````````*`````@```*`#````````R``````````*`````@```)`%```` +XM````Z``````````*`````@```)`&````````"`$````````*`````@```-`' +XM````````,`$````````*`````@`````)````````4`$````````*`````@`` +XM```*````````>`$````````*`````@```+`*````````D`$````````*```` +XM`@```.`*````````J`$````````*`````@```"`+````````R`$````````* +XM`````@```&`,``````````(````````*`````@```!`0````````(`(````` +XM```*`````@```/`0````````!@`````````*````!@``````````````!@`` +XM```````*````!@``````````````$``````````!`````@`````````````` +X` +Xend +END-of-sections.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.sh new file mode 100644 index 0000000000..4db09d9165 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-1/strip-debug-1.sh @@ -0,0 +1,6 @@ +# $Id: strip-debug-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-debug-1 tc/strip-debug-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -g -o sections.o.1 sections.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/in/strip-debug-2.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/in/strip-debug-2.in.shar new file mode 100644 index 0000000000..559b0f91ae --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/in/strip-debug-2.in.shar @@ -0,0 +1,913 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# symbols.o.uu +# +echo x - symbols.o.uu +sed 's/^X//' >symbols.o.uu << 'END-of-symbols.o.uu' +Xbegin 644 symbols.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````,!C```` +XM`````````$```````$``&@`7``^V1P3`Z`0L`0^4P`^VP,,/MD<$P.@$A,`/ +XME,`/ML##54B)]5-(@^P(2(N?T````$B%VW4+ZR%(BUL(2(7;=!A(BS-(B>_H +XM`````(7`=>A(@\0(L`%;7<-(@\0(,](BU$02(MQ"+D`````Z`````!(BUPD,$B-M"2``0`` +XM2(M[$.@`````2(7`#X2O$@``2(M$)#A(C;0D0`$``$B+>!#H`````$B%P`^$ +XMD!(``$'V16P@#X7*!0``28M]&$B-M"08`@``Z`````"%P`^$)!8``$F+?2#H +XM`````(7`B40D1`^$T14``+X!````OS````#H`````$B%P$F)Q@^$U!4``+\` +XM`@``Z`````!(A<`/A-(5``!(B40D2,8``+X!````08M],(/'!XU'!X7_#TCX +XMP?\#2&/_Z`````!(A`/A;<.``"+ +XME"0``0``2(NT)!@"``!)BWT8Z`````!(AZ`````!(AT)#@!``!(A````!(A=L/A+$!``!!OP````#K#4B+6UA(A=L/ +XMA)P!``!,BP.Y"````$R)__Q,B<;SIG3@OP````"Y"````$R)QO.F=,^_```` +XM`+D*````3(G&\Z9TOD'V16P$=!!(BT-`2(/X"72M2(/X!'2G2(M[$.@````` +XM28N5B````$B)P4C!Z0,/MA0*B<�?3ZH/B`76`QX0DX`$```````!(QX0D +XMZ`$```````!(QX0D\`$```````#&A"3D`0```TB+>PCH`````(-\)$0!9HF$ +XM).8!```/A+$-``!)BU802(72#X2J$@``2(N,)+@```!).TXH#X8*#P``BX0D +XMX`$``(7`#X4##0``28M&*$B-!$#'!,(`````28M&*`^VE"3D`0``28M.$$B- +XM!$"(5,$$28M&*`^VE"3E`0``28M.$$B-!$"(5,$%28M&*$F+3A!(BY0DZ`$` +XM`$B-!$!(B53!"$F+1BA)BTX02(N4)/`!``!(C01`2(E4P1`/MXPDY@$``(U! +XM_V8]_OX/AV<,``!)BT5P28M6*`^WR4F+=A!(BP3(2(T44F:)1-8&28-&*`%( +XMBUM82(7;#X5D_O__2(-\)'``=%5(@WPD*`!T0S'2,?;K!)!(B?*)\$B+7"1P +XMB?'!^`.#X0=(F`^V!!C3Z*@!=!-(C035`````$D#17A)BU8H2`$02(/&`4@[ +XM="0H=<1(BWPD<.@`````,<"#?"1$`4F+5B!)BTU0#Y7`20-6*$B-!,40```` +XM2`^OPDB)02A)BT503(EP&$F+15A(BU0D4$B)4"A)BT582(M,)$A(B4@82(M$ +XM)#!(BU@82(-[*``/A;T"``!(@WL@``^%2P(``$B+3"0X2(MY$.@`````2(7` +XM2(G"#X3/$0``2,<``0```$C'0!``````N0$```!(BUPD.+X2````2(M#&$B) +XM0@A(BT,H2(V<),````#'0B`!````QT(D`0```$B)0AA(QX0DD`$````````Q +XMP$&#?10!2(M4)#`/E1!O0$` +XM``!,B?I$B>9(B=_H`````$PY^`^%^0P```^VA"3$`0``P.@$A,!%#T3U28/$ +XM`4F#Q0%).>QTD^O)2(M\)##H`````$B+?"0XZ`````!(@<0H`@``6UU!7$%= +XM05Y!7\/H`````(7`#X7H$```2(M4)#A$B;0DK`$``$B-M"2``0``2,>$)%`! +XM````````2,>$)'`!```!````2(M,)#!(BT(HQX0D1`$```,```!(QX0D2`$` +XM``````!(QX0D>`$```````#'A"1L`0```````,>$)&@!````````2(F$)&`! +XM``!(BWD0Z`````"%P'0>2(M<)#A(C;0D0`$``$B+>Q#H`````(7`#X4_____ +XMO______H`````+X`````2(G"OT8````QP.@`````2(M4)#!(BWH0Z`````!( +XMA!#H`````$B%P$B)P@^$(@\``$&#?10!#X3A"@``2,<`"````$C'0!`````` +XM2(M#$$B)0@A(BT,HQT(@$@```,=")`$```!(C01`2,'@`TB)0ACIZ?S__TB+ +XM?"0HO@@```#H`````$B%P$F)17@/A%8.``!(BU0D*+X!````2(/"!TC!Z@-( +XMB==(B90D@````.@`````2(7`2(E$)'@/A"8.``!(BTPD>#'V2(G?2(E,)'#H +XM`````$B%P$B)1"1H#X1:#0``2(V<).`!``!(C80DP````$B-E"3``0``2(V, +XM)``"``!(QT0D6$````!(QX0DN````$````!(QT0D4`$```!!OP`"``!(QX0D +XMJ`````````!(QX0DL`````````!(B5PD&$B)1"002(D4)$B)3"0(BX0DL``` +XM`$B+?"1H2(V4).`!``")QHF$)*0```#H`````$@[1"08#X4;"@``BY0DX`$` +XM`$F+?1A(BW0D8.@`````2(7`2(G%#X3!!@``2(G&3(GOZ`````"%P`^%YP`` +XM`$F+G<````!(A=MU"^M)2(M;"$B%VW1`2(LS2(GOZ`````"%P'7H2(.$)+`` +XM```!2(N$)+````!(.40D*`^$[_C__TB+G"2P````2(F<)*@```#I2/___P^W +XME"3F`0``C4+_9CW^_G<.28M%<`^WTDB#/-``=+!!@WUH`72I28N5@````$B% +XMT@^$F`D``(N$)*0```!$BZ0DI````,'X`T&#Y`=(8]A$B>$/M@03T^BH`74T +XM0?9%;`0/A0L"``!!BT5H@_@$#X1;____@_@"=1$2)X;@!````T^`(!!I)BU5X28M&($B+C"2H````2(D$ +XMRH-\)$0!#X3*`0``2(V\).`!``#H%O3__X7`#X24`@``28M6$$B%T@^$E0<` +XM`$B+A"2X````23M&*`^&!P4``(N\).`!``"%_P^$C@,``(!]```/A(0#``!) +XMBT8HBTPD4$B-!$")#,))BT8H#[:4).0!``!)BTX02(T$0(A4P01)BT8H#[:4 +XM).4!``!)BTX02(T$0(A4P05)BT8H28M.$$B+E"3H`0``2(T$0$B)5,$(28M& +XM*$F+3A!(BY0D\`$``$B-!$!(B53!$`^WC"3F`0``C4'_9CW^_@^&,P,``$F+ +XM1BA)BU802(T$0&:)3,(&28-&*`$/MH0DY`$``(/@#X/X`P^$D0(``(!]```/ +XMA-G]___K'DB+?"1(30'_3(G^Z`````!(A<`/A`@$``!(B40D2$B)[^@````` +XM2(M4)%!(B<%(`<))C4?_2#G"<\9(BUPD2$@#7"102(G*2(GN2(G?Z`````!( +XMB>_H`````$B)[\8$`P#H`````$B+7"102(U<`P%(B5PD4.E=_?__2(V\).`! +XM``#H@_+__X7`#X4W_O__#[:$).0!``#`Z`0\`@^%S?W__TF+57A)BT8H2(N< +XM)*@```!(B03:@WPD1`$/A3;^__](C;PDX`$``.A,\O__A<`/A$@"``!)BQ9( +XMA=(/A-\(``!(BX0DN````$D[1B@/ADH%``!$BXPDX`$``$6%R70*@'T```^% +XM&00``$F+1BA(P>`$QP00`````$F+1B@/MI0DY`$``$F+#DC!X`2(5`@,28M& +XM*`^VE"3E`0``28L.2,'@!(A4"`U)BT8H28L.2(N4).@!``!(P>`$B50(!$F+ +XM1BA)BPY(BY0D\`$``$C!X`2)5`@(#[>,).8!``"-0?]F/?[^#X8Q`P``28M& +XM*$F+%DC!X`1FB4P0#ND[_O__28M6&$B%T@^$H@4``$B+1"1823M&(`^&/0(` +XM`(NT).`!``"%]@^$Z0```(!]```/A-\```!)BT8@BTPD4$B-!$")#,))BT8@ +XM#[:4).0!``!)BTX82(T$0(A4P01)BT8@#[:4).4!``!)BTX82(T$0(A4P05) +XMBT8@28M.&$B+E"3H`0``2(T$0$B)5,$(28M&($F+3AA(BY0D\`$``$B-!$!( +XMB53!$`^WC"3F`0``C4'_9CW^_@^&@0```$F+1B!)BU882(T$0&:)3,(&28-& +XM(`$/MH0DY`$``(/@#X/X`P^%;_W__P^WE"3F`0``28M%<$B+#-"X`0```$B) +XMRH/A!TC!Z@-)`Y6(````T^`(`NE`_?__28M&($B-!$#'!,(`````Z1S___]) +XMBT8H2(T$0,<$P@````#I=_S__TF+17!)BU8@#[?)28MV&$B+!,A(C1129HE$ +XMU@;I;____TF+17!)BU8H#[?)28MV$$B+!,A(C1129HE$U@;IO?S__TF+5@A( +XMA=(/A+\&``!(BUPD6$D[7B`/AC(#``!$BX0DX`$``$6%P'0*@'T```^%OP$` +XM`$F+1B!(P>`$QP00`````$F+1B`/MI0DY`$``$F+3@A(P>`$B%0(#$F+1B`/ +XMMI0DY0$``$F+3@A(P>`$B%0(#4F+1B!)BTX(2(N4).@!``!(P>`$B50(!$F+ +XM1B!)BTX(2(N4)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&Q@```$F+ +XM1B!)BU8(2,'@!&:)3!`.Z8'^__](QT0D8`````#I$/+__T@!P$B)UTB--$!( +XMB40D6$C!Y@/H`````$B%P$B)PDF)1A@/A9O]__^^`````+]&````,<#H```` +XM`$@!P$B)UTB--$!(B80DN````$C!Y@/H`````$B%P$B)PDF)1A`/A<[Z___K +XMPK______Z`````"^`````$B)PK]&````,<#H`````+______Z`````"^```` +XM`$B)PK]&````,<#H`````$F+17!)BU8@#[?)28MV"$B+!,A(P>($9HE$,@[I +XML/W__TF+17!)BU8H#[?)28LV2(L$R$C!X@1FB40R#NG_^O__28M&*$F+5A!( +XMC01`9HE,P@;IG_/__X!]```/A//R__])BT8HBTPD4$B-!$")#,+I[O+__TF+ +XM1B"+3"102,'@!(D,$.D\_O__28M&*(M,)%!(P>`$B0P0Z>+[__](QP`$```` +XM2(M#*$C!X`1(B4(02(M#"$B)0@A(BT,@QT(@$@```,=")`$```!(P>`$2(E" +XM&.GU\___28L62(72#X0Q!@``2(N,)+@```!).TXH#X9]!```BXPDX`$``(7) +XM#X3[````@'T```^$\0```$F+1BB+3"102,'@!(D,$$F+1B@/MI0DY`$``$F+ +XM#DC!X`2(5`@,28M&*`^VE"3E`0``28L.2,'@!(A4"`U)BT8H28L.2(N4).@! +XM``!(P>`$B50(!$F+1BA)BPY(BY0D\`$``$C!X`2)5`@(#[>,).8!``"-0?]F +XM/?[^#X:-`0``28M&*$F+%DC!X`1FB4P0#NE3\O__2`'`2(G72(G&2(F$)+@` +XM``!(P>8$Z`````!(A`$2(E"&.D-\O__2(M<)%A(C3Q;2,'G +XM`^@`````2(7`2(G"28E&&`^%2_K__^E=____9F9FD+______Z`````"^```` +XM`$B)PK]&````,<#H`````+______Z`````"^`````$B)PK]&````,<#H```` +XM`$F+17!)BU8H#[?)28LV2(L$R$C!X@1FB40R#NF[\/__2(N\)(````"^`0`` +XM`.@`````2(7`28F%@`````^$[0(``$F+?1A(C;0D$`(``.@`````A<`/A"$# +XM``!%,>1)BWT83(GFZ`````!(A_H```` +XM`(7`#X5U____28M%4(N<).@```!(BW@(Z`````!(.<-(QX0DD`````````!( +XMQX0DF``````````/A4#___](BXPDD````$@[C"3@````#X.O`@``2(NT))@` +XM``!,B>?H`````$B%P$B)A"28````#X2.`@``2(N4))@```!(BT(8,=)(][0D +XM^````(7`2(G#?JS'A"2,`````````(.\),0````)#X2@`@``B[0DC````$B+ +XMO"28````2(V4),`!``#H`````$@[!"0/A;$"``"+A"3,`0``2(F$))````!( +XM@[PDD``````/E8$Z`````!(A<#Z`````!(A`````((!0`````#``````(ZB@````((!P`````""`0``````@0$```` +XM``,``````E)_````!0@'!@@"`08``````P`````#3VT````#``````-90@`` +XM``,``````UY;`````P`````#8W\````'"*\````'".X````(KP````,````` +XM`^B?`````@@%``````,`````!";,`````P`````$)\$````#``````0JS``` +XM``D0!+>#`0``"@`````$N!L!```"(P`*``````2Y!0$```(C!`H`````!+H; +XM`0```B,("@`````$NS0````"(PP*``````2\-`````(C#0H`````!+T0`0`` +XM`B,.``,`````!+XF`0```P`````%)M<````#``````4GP0````,`````!2C7 +XM`````P`````%*K8````#``````4KS`````,`````!2W7````"4`%564"```* +XM``````56N@$```(C``H`````!5BZ`0```B,$"@`````%6<4!```"(P@*```` +XM``5:C@$```(C$`H`````!5ND`0```B,8"@`````%7,4!```"(R`*``````5= +XMN@$```(C*`H`````!5ZZ`0```B,L"@`````%7\4!```"(S`*``````5@Q0$` +XM``(C.``#``````5AT`$```D0!8.5`@``"@`````%A(X!```"(P`*``````6% +XMQ0$```(C"``#``````6&<`(```D8!8G3`@``"@`````%BHX!```"(P`*```` +XM``6+Q0$```(C"`H`````!8RO`0```B,0``,`````!8V@`@``"1@%OCL#```* +XM``````6_N@$```(C``H`````!<`T`````B,$"@`````%P30````"(P4*```` +XM``7"F0$```(C!@H`````!<..`0```B,("@`````%Q,4!```"(Q```P`````% +XMQ=X"```+16QF``8F40,```P``````0,`````!B=B`P``#``````!#00&-@$$ +XM```.```````.``````$.``````(.``````,.``````0.``````4.``````8. +XM``````<.``````@.``````D.``````H.``````L.``````P.``````T.```` +XM``X.``````\.`````!`.`````!$.`````!(.`````!,.`````!0.`````!4. +XM`````!8.`````!<``P`````&3V@#```)"`9X(P0```H`````!GBN!````B,` +XM``\`````0`9HK@0```H`````!FS7`````B,`"@`````&;:T````"(P@*```` +XM``9NUP````(C$`H`````!F_7`````B,8"@`````&<`$$```"(R`*``````9Q +XM9@````(C)`H`````!G:T!````B,H"@`````&=V8````"(S`*``````9X#`0` +XM``(C.``'"",$```'"%<#```#``````9Y(P0```,`````!S!E`@```P`````' +XM,3L#```#``````@````"(P`*``````@JZ`````(C"`H`````""OH`````B,0"@`````( +XM+.@````"(Q@0861D``@N5`````(C(`H`````""]4`````B,D"@`````(,%0` +XM```"(R@*``````@Q5`````(C+`H`````"#)4`````B,P"@`````(,U0````" +XM(S0*``````@T5`````(C.`H`````"#8W!0```B-```<(3@4```D("#\@!@`` +XM"@`````(/V4&```"(P``#P`````@"#IE!@``"@`````(.^(````"(P`*```` +XM``@\X@````(C"`H`````"#WS`````B,0"@`````(/PD&```"(Q@`!P@@!@`` +XM"1`(49`&```*``````A17@<```(C``H`````"%%D!P```B,(``\`````>`A# +XM7@<```H`````"$3H`````B,`$&ES``A%M`0```(C"!!O!P``"1`(4H\'```*``````A2 +XM7@<```(C``H`````"%)D!P```B,(``\`````$`A>N`<```H`````"%Y>!P`` +XM`B,`"@`````(7F0'```"(P@`"0@(7\\'```*``````A?/@@```(C```/```` +XM`$`(5CX(```0;V9F``A7UP````(C`!!F@`(6=<` +XM```"(Q`*``````A:UP````(C&`H`````"%Q4`````B,@"@`````(7H\'```" +XM(R@*``````A?N`<```(C.``'",\'```/`````#`(8Z4(```0;#,R``ADI0@` +XM``(C`!!G,S(`"&6E"````B,($&PV-``(9JL(```"(Q`09S8T``AGJP@```(C +XM&!!N9W,`"&CS`````B,@$&YL!P```B,`"@`` +XM```(L60'```"(P@`#P````#P"&Z5"P``"@`````(;^@````"(P`*``````AR +XM5`````(C"`H`````"'-4`````B,,$&EE8P`(=50````"(Q`0;V5C``AV5``` +XM``(C%!!E:6X`"'>5"P```B,8"@`````(>)4+```"(R`*``````AZ5`````(C +XM*`H`````"'M4`````B,L$&YO +XM!P```B-8"@`````(BUX'```"(V`*``````B3L0@```(C:`H`````")M4```` +XM`B-L"@`````(GIL+```"(W`*``````BAFPL```(C>`H`````"*2A"P```R.` +XM`0H`````"*>A"P```R.(`0H`````"*G8"````R.0`0H`````"*H#"0```R.@ +XM`0H`````"*LN"0```R.P`0H`````"*U9"0```R/``0H`````"*^$"0```R/0 +XM`0H`````"+&I"0```R/@`0`'"$8#```'"-<````'"#0````1``````%!`50` +XM`````````````````````````G<(U@L``!)S``%`U@L```%5``<(T`0``!$` +XM`````4L!5``````````````````````````"=P@+#```$G,``4K6"P```54` +XM$P$``````7,"`50``````````````````````````````&`,```496-P``%R +XM`F`,````````%0`````!<@+H`````````!9S``%T`C$%``````````<(S@D` +XM`!VA"P``&VES:``![L4$```;?,````<``````%[ +XMZ````!MD``%\!@X``!MS``%]M`0``!MR``%^VP0``!MR80`!?^8$```;6T``3P"T`0``!AO9``!/0(&#@``(P`` +XM```!/@+,````&'-C``$_`O,````C``````%``E0````8:0`!0`)4`````"0! +XM``````'*`0$``````````````````````````!1E8W```0`!S@'%!````Y&@?B5S:'0``!^+-<.```#D>!\*N$.```````` +XM*NH.````````*O4.````````*@`/````````*PD/`````#(5#P````````%I +XME!(``"@Z#P``,#$/````````*"8/```S1`\````````````````````````! +XMURA5#P`````S7P\````````````````````````!;RAP#P```````"YZ#P`` +XM``````$E`BB,#P``*0`````LE@\```.1X'PLH@\```.1X'XJK@\````````J +XMN0\````````KQ0\``"K0#P```````"O<#P```````*D#```"`*`````!`?L. +XM"@`!`0$!`````2]U7,`+W5S6UB;VQS+F,`````7W1Y<&5S+F@``0``='EP +XM97,N:``"``!E;&8S,BYH``(``&5L9C8T+F@``@``;&EB96QF+F@``P``9V5L +XM9BYH``,``&5L9F-O<'DN:`````````D"```````````#P``!YR'G`Z($'9`( +XM9.9",`-Z<3$#:P@=TSQ2/,@Z"+C=`W`(F],\4CS(.@BXW0/K?@B;`PDK`W=5 +XM""..C\8(CPC6"-<#FWZI"(((2PB@"',["-0XR5:# +XMO'HO"#H(/`(D$PA85H(#(XT('CA6`\H``B0!`B40`C43"&>.",:JN+B!CE2` +XM9@-L`M4!`0,9Q8`('G`L"!X(872>`B81@,8#(,6.`Q2I`Q6I")!R`PM_`W95 +XM`PI5`W95@`,M1P-4?W)O2[AR5`@L2E.JM8(#)(T#7%4#)'\"(A0(@-0X.JH( +XM9@A[`Y5_<9P#UP";`QL('58#5W]1`PM_`W=_N+\#>55(JKBXJJ2&R`C&`T<( +XMQ0B0L7+P@$AR;P->_0A*L7*`@$AR;P/C?OWB.$AE"/XX5F)84E@#L'X(FP,B +XM?P-Z?P.T`7\#L'X"00$#(E4#>D<#MP%5>0-XX7GR`^Q]".\#JP0(*PAD`Y1^ +XMX0-0C0-Y""L#_GT(1PC7=`/I`.\")A8#EG^IR`-)50.^`@AC`BX0"!X(/*\( +XM2`,)`M0!`0@\NU0Z@(Q3"*\(``$!`"1&"!I;F1E>`!R96%L;&]C(&9A:6QE9``N&!HP%````````%``````````!>E(``7@0`0,, +XM!PB0`0``%````!P`````````$```````````````%````#0`````````$``` +XM````````````'````$P`````````00````!!#A"&`D0.&$0.((,#```4```` +XM;`````````!F`````$X.((8"@P,4````A`````````!F`````$X.((8"@P,T +XM````G`````````#Z%P```$(.$$<.&$(.((T$C@./`D4.*$$.,$$..$<.X`2# +XM!X8&C`4``````"``````````(0`````````"`'<((0`````````E```````` +XM``(`=Q`E`````````"D``````````@!W&"D`````````80`````````"`'<@ +XM`````````````````````"``````````-P`````````!`%5``````````$8` +XM`````````0!56`````````!A``````````$`50`````````````````````@ +XM`````````#4``````````0!4-0````````!7``````````$`5E@````````` +XM8``````````!`%9@`````````&$``````````0!4```````````````````` +XM`#``````````5@`````````!`%-8`````````%\``````````0!3```````` +XM`````````````'``````````?@`````````"`'<(?@````````#6```````` +XM``(`=R``````````````````````<`````````"&``````````$`588````` +XM````P``````````!`%;%`````````-8``````````0!6```````````````` +XM`````'``````````C@`````````!`%2.`````````+L``````````0!3Q0`` +XM``````#6``````````$`4P````````````````````#@`````````.X````` +XM`````@!W".X`````````1@$````````"`'<@`````````````````````.`` +XM````````]@`````````!`%7V`````````#`!`````````0!6-0$```````!& +XM`0````````$`5@````````````````````#@`````````/X``````````0!4 +XM_@`````````K`0````````$`4S4!````````1@$````````!`%,````````` +XM````````````4`$```````!2`0````````(`=PA2`0```````%D!```````` +XM`@!W$%D!````````6P$````````"`'<86P$```````!@`0````````(`=R!@ +XM`0```````&$!`````````@!W*&$!````````8@$````````"`'"0```````&D)`````````0!1$!0```````!% +XM%`````````$`4488````````4!@````````!`%$````````````````````` +XM;@8```````!Q!@````````$`4'$&````````TP8````````!`%%&&``````` +XM`%`8`````````0!1`````````````````````-\#````````KP4````````! +XM`%.S!0```````+H%`````````0!3[`4```````!'!@````````$`4Q<1```` +XM````*!$````````!`%/2$0````````82`````````0!3:!(````````T$P`` +XM``````$`4XX3````````I!,````````!`%/)$P```````!`4`````````0!3 +XMK!0```````#,%`````````$`4P,7````````,1<````````!`%-N%P`````` +XM`)@7`````````0!3I1@```````#*&`````````$`4P`````````````````` +XM``##`P```````+4'`````````P"1D'S)!P```````&D)`````````P"1D'S$ +XM"0```````.$0`````````P"1D'SO$````````&P4`````````P"1D'R.%``` +XM`````)@7`````````P"1D'RI%P```````,`7`````````P"1D'S"%P`````` +XM`.H7`````````P"1D'PH&````````$H9`````````P"1D'P````````````` +XM````````V`,```````"U!P````````,`D8A\R0<```````!I"0````````,` +XMD8A\T0D```````#A$`````````,`D8A\[Q````````!L%`````````,`D8A\ +XMCA0```````"8%P````````,`D8A\J1<```````#`%P````````,`D8A\PA<` +XM``````#J%P````````,`D8A\*!@```````!*&0````````,`D8A\```````` +XM`````````````(@"````````WP,````````!`%-I"0```````-\)```````` +XM`0!3X1````````#O$`````````$`4U41````````D1$````````!`%,Q%P`` +XM`````&X7`````````0!3F!<```````"I%P````````$`4\`7````````ZA<` +XM```````!`%,`````````````````````B@(```````"U!P````````,`D;A_ +XMR0<```````!L%`````````,`D;A_CA0```````#J%P````````,`D;A_*!@` +XM``````!*&0````````,`D;A_`````````````````````%P$````````9@0` +XM```````!`%``````````````````````_P(```````"U!P````````,`D8!\ +XMR0<```````#A$`````````,`D8!\ZA````````!L%`````````,`D8!\CA0` +XM``````#J%P````````,`D8!\*!@```````!*&0````````,`D8!\```````` +XM`````````````,\#````````M0<````````#`)'8?,D'````````:0D````` +XM```#`)'8?``*````````#`H````````#`)'X>PP*````````L@X````````# +XM`)'8?+(.````````>P\````````#`)'X>WL/````````J@\````````#`)'8 +XM?*H/````````O@\````````#`)'X>[X/````````T@\````````#`)'8?-(/ +XM````````\P\````````#`)'X>_,/````````,!`````````#`)'8?#`0```` +XM````X1`````````#`)'X>^\0````````%Q$````````#`)'X>Q<1```````` +XMD1$````````#`)'8?)$1````````LA$````````#`)'X>[(1````````!A(` +XM```````#`)'8?`82````````&A(````````#`)'X>QH2````````8A,````` +XM```#`)'8?&(3````````CA,````````#`)'X>XX3````````9Q0````````# +XM`)'8?&<4````````;!0````````#`)'X>XX4````````_A8````````#`)'8 +XM?/X6`````````Q<````````#`)'X>P,7````````,1<````````#`)'8?$87 +XM````````F!<````````#`)'8?*D7````````P!<````````#`)'8?,(7```` +XM````ZA<````````#`)'8?"@8````````2AD````````#`)'8?``````````` +XM``````````#8`P```````+4'`````````P"1\'O)!P```````&D)```````` +XM`P"1\'L5"@```````$D,`````````P"1\'OV#````````-H.`````````P"1 +XM\'MB#P```````'L/`````````P"1\'NJ#P```````-(/`````````P"1\'L4 +XM$````````.$0`````````P"1\'OO$````````*X2`````````P"1\'LT$P`` +XM`````&P4`````````P"1\'N.%````````*P4`````````P"1\'O,%``````` +XM`#$7`````````P"1\'M/%P```````)@7`````````P"1\'NI%P```````,`7 +XM`````````P"1\'O"%P```````.H7`````````P"1\'LH&````````$H9```` +XM`````P"1\'L`````````````````````V`,```````#N`P````````$`7YD% +XM````````00<````````!`%^H"````````&D)`````````0!?&PH```````#A +XM$`````````$`7^\0````````TA$````````!`%\&$@```````&@2```````` +XM`0!?-!,```````".$P````````$`7Z03````````VA,````````!`%\0%``` +XM`````&P4`````````0!?CA0```````"L%`````````$`7\P4`````````Q<` +XM```````!`%]5%P```````&X7`````````0!?J1<```````#`%P````````$` +XM7\(7````````ZA<````````!`%\H&````````*48`````````0!?UQ@````` +XM``!*&0````````$`7P````````````````````"*`@```````/`"```````` +XM`0!6_P(```````""`P````````$`5H0#````````\D'````````;!0````````#`)'H>XX4```` +XM````ZA<````````#`)'H>R@8````````2AD````````#`)'H>P`````````` +XM```````````3`@```````+4'`````````P"1Y'O)!P```````&P4```````` +XM`P"1Y'N.%````````$H9`````````P"1Y'L`````````````````````!@,` +XM```````N`P````````$`4(L#````````I`,````````!`%#8`P```````/`# +XM`````````0!5_0,````````(!`````````$`59D%````````\04````````! +XM`%7V!0```````&8&`````````0!5J`@```````"Q"`````````$`50\)```` +XM````$PD````````!`%4X%P```````#H7`````````0!0.A<```````!:%P`` +XM``````$`59@7````````I!<````````!`%#`%P```````,(7`````````0!0 +XMPA<```````#'%P````````$`50````````````````````"O!0```````/8% +XM`````````0!2`````````````````````)<*````````GPH````````!`%3$ +XM"@```````,D*`````````0!5`````````````````````-@#````````WP,` +XM```````!`%.N"@```````/$*`````````0!3_@H```````!-"P````````$` +XM4U41````````D1$````````!`%/,%````````*`5`````````0!3J1<````` +XM``#`%P````````$`4\(7````````ZA<````````!`%,H&````````$88```` +XM`````0!3`````````````````````&X)````````>`D````````!`%4````` +XM````````````````51$```````!?$0````````$`5&D5````````;!4````` +XM```!`%!L%0```````'H5`````````0!4`````````````````````-@#```` +XM````M0<````````#`)&X?,D'````````:0D````````#`)&X?$8*```````` +XMX1`````````#`)&X?.\0````````;!0````````#`)&X?(X4````````,1<` +XM```````#`)&X?%47````````F!<````````#`)&X?*D7````````P!<````` +XM```#`)&X?,(7````````ZA<````````#`)&X?"@8````````2AD````````# +XM`)&X?``````````````````````T"P```````$,+`````````0!<51$````` +XM``"1$0````````$`7`H5````````MQ8````````!`%Q5%P```````&X7```` +XM`````0!`T````````!`%4*%0````````X5`````````0!551<` +XM``````!:%P````````$`5;`7````````LA<````````!`%"R%P```````,`7 +XM`````````0!5PA<```````#'%P````````$`5988````````F!@````````! +XM`%"8&````````*48`````````0!5`````````````````````-@#```````` +XMM0<````````#`)&L?,D'````````:0D````````#`)&L?$8*````````X1`` +XM```````#`)&L?.\0````````;!0````````#`)&L?(X4````````,1<````` +XM```#`)&L?%47````````F!<````````#`)&L?*D7````````P!<````````# +XM`)&L?,(7````````ZA<````````#`)&L?"@8````````2AD````````#`)&L +XM?`````````````````````#8`P```````+4'`````````P"1Q'S)!P`````` +XM`&D)`````````P"1Q'Q&"@```````%P*`````````P"1Q'Q<"@```````&,* +XM`````````0!48PH```````#A$`````````,`D<1\[Q````````!L%``````` +XM``,`D<1\CA0````````Q%P````````,`D<1\51<```````"8%P````````,` +XMD<1\J1<```````#`%P````````,`D<1\PA<```````#J%P````````,`D<1\ +XM*!@```````!*&0````````,`D<1\`````````````````````$,'```````` +XMM0<````````!`%/;!P```````'$(`````````0!3B@@```````"H"``````` +XM``$`4XX4````````K!0````````!`%-5%P```````&X7`````````0!3RA@` +XM``````#7&`````````$`4P````````````````````!&!P```````+4'```` +XM`````0!>R0<```````#8!P````````$`7ML'````````J`@````````!`%Z. +XM%````````*P4`````````0!>51<```````!N%P````````$`7LH8```````` +XMUQ@````````!`%X`````````````````````X@<````````>"`````````$` +XM4%47````````6A<````````!`%7*&````````-<8`````````0!0```````` +XM`````````````&,````"```````%$P``"PP``&QO;VMU<%]K965P7W-Y;6QI +XM1,```````!\$P`` +XM`````&L3`````````D```````"*"0```````,X%```````` +XM/@8```````"Z!0```````+P%````````I`0```````"S!0```````%($```` +XM````FP0````````R!````````$D$````````B0,`````````!````````&@# +XM````````;@,```````!B`P```````&4#````````00,```````!*`P`````` +XM`#0#````````-@,````````N`P```````#$#````````(`,````````B`P`` +XM``````0#````````&`,```````#:`@```````.`"````````U`(```````#7 +XM`@```````+,"````````O`(```````"B`@```````*@"````````G`(````` +XM``"?`@```````&X"````````?@(````````^`@```````$\"````````+@(` +XM```````T`@```````"@"````````*P(````````3`@```````!D"```````` +XM#0(````````/`@````````````````````````````#?"0```````/<)```` +XM````UQ@```````!*&0```````&08````````I1@````````H&````````$88 +XM````````PA<```````#J%P```````*D7````````P!<```````#,%``````` +XM`+<6````````51$```````!S$0```````'`-````````F`T```````#^"@`` +XM`````(X+````````E`H```````#-"@```````#@*````````1@H````````` +XM````````````````````WPD```````#W"0```````-<8````````2AD````` +XM``!D&````````*48````````*!@```````!&&````````,(7````````ZA<` +XM``````"I%P```````,`7````````S!0```````"W%@```````%41```````` +XMA4` +XM``````!^%0```````&P5````````F4`=6YS:6=N +XM960@:6YT`$5,1E]47TY530!%;&8S,E]7;W)D`&ES7V1E8G5G7W-Y;6)O;`!3 +XM5%))4%]!3$P`@!D7W-C;@!T<65?;F5X=`!%;&8S,E]! +XM9&1R`$5,1E]47U-85T]21`!%;&9?4V-N`'-Y;6YD>`!I6U?:V5E<`!%3$9?5%]214P`61A=&$`6UB;VP`;G-Y +XM;7,`87!P96YD`'-E8U]H96%D`$5,1E]47UA73U)$`$5L9C,R7U-Y;0!S='%H +XM7V9I0!?7W5I;G0Q-E]T`$5,1E]4 +XM7U-934E.1D\`4U1225!?3D].1$5"54<`9W-Y7V-A<`!V7W-A9&0`7!E`$5,1E]47U-930!C +XM86QC7VYO;FQO8V%L`$5L9C8T7U-Y;0!S96-N9'@`16QF7U1Y<&4`6UB;VP`6UB=68`16QF-C1?6'=O6UL:7-T`$5L9C,R7TAA;&8` +XM=E]S86,`14Q&7U1?3D]410!%;&8V-%]/9F8`861D7W1O7W-TF4`96QF97)R`&-R96%T95]S>6UT +XM86(`:6YF;70`14Q&7U1?0EE410!D7V)U9@!S:7IE`$5,1E]47U=/4D0`6T``!PF4`:7-?'=O6UT86(`+G-T6UB;VP`:7-?;&]C86Q? +XM`!G +XM96QF7V=E=&-L87-S`&-A;&QO8P!E;&9?;F5X='-C;@!E;&9?1$````````"````*@```/S_________?A$` +XM```````*````"@```(P`````````C1$````````"````%P```/S_________ +XM2A,````````"````*P```/S_________=1,````````"````*P```/S_____ +XM____M1,````````"````%@```/S_________RA,````````*````"@```'X` +XM````````UA,````````"````+@```/S_________]Q,````````"````*P`` +XM`/S_________4Q0````````"````%@```/S_________=A0````````"```` +XM*@```/S_________>Q0````````*````"@```"(`````````BA0````````" +XM````%P```/S_________E!0````````"````*@```/S_________F10````` +XM```*````"@````(!````````J!0````````"````%P```/S_________VA0` +XM```````"````'@```/S_________^Q0````````"````'````/S_________ +XM$A4````````"````'P```/S_________+A4````````"````&P```/S_____ +XM____8A4````````"````(````/S_________=A4````````"````+P```/S_ +XM________B14````````"````,````/S_________I14````````"````(0`` +XM`/S_________[!4````````"````)@```/S_________3Q8````````"```` +XM,0```/S_________DA8````````*````"@```$8!````````F18````````" +XM````,@```/S_________Q!8````````"````%@```/S_________ZA8````` +XM```"````%@```/S_________&1<````````"````*P```/S_________,A<` +XM```````"````(@```/S_________5A<````````"````*@```/S_________ +XM6Q<````````*````"@```.L`````````:A<````````"````%P```/S_____ +XM____?Q<````````"````%@```/S_________F1<````````*````"@```-`` +XM````````I1<````````"````%P```/S_________JA<````````"````(@`` +XM`/S_________PQ<````````"````*@```/S_________R!<````````*```` +XM"@```+D`````````UQ<````````"````%P```/S_________W!<````````* +XM````"@```'``````````YA<````````"````+@```/S_________\!<````` +XM```"````*@```/S_________]1<````````*````"@```%<`````````!!@` +XM```````"````%P```/S_________"1@````````*````"@```'`````````` +XM%1@````````"````+@```/S_________&A@````````*````"@```'X````` +XM````)!@````````"````+@```/S_________+A@````````"````*@```/S_ +XM________,Q@````````*````"@```#P`````````0A@````````"````%P`` +XM`/S_________3!@````````"````*@```/S_________41@````````*```` +XM"@```'0!````````8!@````````"````%P```/S_________D!@````````" +XM````(@```/S_________LA@````````"````%@```/S_________[Q@````` +XM```"````,P```/S_________%!D````````"````*@```/S_________&1D` +XM```````*````"@```"\!````````*!D````````"````%P```/S_________ +XM,AD````````"````*@```/S_________-QD````````*````"@```!D!```` +XM````1AD````````"````%P```/S_________!@`````````*````!0`````` +XM````````#``````````*````$0```%`'````````$0`````````*````$0`` +XM`'`#````````%0`````````*````$0```*(%````````&0`````````!```` +XM`@``````````````(0`````````!`````@```$H9````````*0`````````* +XM````!P``````````````,``````````*````$0```.,&````````-P`````` +XM```*````$0```$T&````````/@`````````*````$0```%<%````````0P`` +XM```````*````$0```,0!````````4``````````*````$0````<'```````` +XM7``````````*````$0```%L&````````:0`````````*````$0```&8````` +XM````;@`````````*````$0```,P$````````>P`````````*````$0```&D% +XM````````@``````````*````$0```'("````````C0`````````*````$0`` +XM``H&````````E``````````*````$0```'`'````````FP`````````*```` +XM$0```&(!````````H``````````*````$0```+\%````````L@`````````* +XM````$0````X#````````MP`````````*````$0```!0"````````P@`````` +XM```*````$0```.8$````````S0`````````*````$0```#0!````````V``` +XM```````*````$0```)D%````````]``````````*````$0````T"```````` +XM`0$````````*````$0```,0#````````!@$````````*````$0```+\````` +XM````$0$````````*````$0```.4#````````'`$````````*````$0```'T` +XM````````+P$````````*````$0```+H'````````/0$````````*````$0`` +XM`*D&````````2P$````````*````$0```+(&````````60$````````*```` +XM$0```!P&````````9P$````````*````$0```#H%````````=0$````````* +XM````$0```$@%````````A`$````````*````$0```)D!````````CP$````` +XM```*````$0``````````````F@$````````*````$0```(8"````````I0$` +XM```````*````$0````$$````````L`$````````*````$0```$,'```````` +XMNP$````````*````$0```)X'````````Q@$````````*````$0```*X#```` +XM````V0$````````*````$0```-8$````````YP$````````*````$0```"0& +XM````````]0$````````*````$0```)<&`````````P(````````*````$0`` +XM`,@%````````$0(````````*````$0```(T$````````'P(````````*```` +XM$0```#`$````````+0(````````*````$0```)$%````````.P(````````* +XM````$0```$@#````````20(````````*````$0```)$'````````5P(````` +XM```*````$0```+<"````````9@(````````*````$0```,('````````>0(` +XM```````*````$0```#$%````````AP(````````*````$0```-@"```````` +XME@(````````*````$0```.\$````````J0(````````*````$0```#$%```` +XM````MP(````````*````$0```-@"````````Q0(````````*````$0```"P& +XM````````U`(````````*````$0```(8%````````YP(````````*````$0`` +XM`+H'````````]0(````````*````$0```!P&`````````P,````````*```` +XM$0```#H%````````$0,````````*````$0```$@%````````'P,````````* +XM````$0```*D&````````+0,````````*````$0```+(&````````/`,````` +XM```*````$0```#L"````````4@,````````*````$0```",'````````6`,` +XM```````*````$0```-<`````````8P,````````*````$0```*D$```````` +XM<0,````````*````$0```)X$````````=P,````````*````$0```%,$```` +XM````?0,````````*````$0```!,#````````@P,````````*````$0```,X" +XM````````B0,````````*````$0```-(#````````CP,````````*````$0`` +XM`*D'````````E0,````````*````$0````(#````````FP,````````*```` +XM$0```$,`````````H0,````````*````$0```,("````````IP,````````* +XM````$0```/8#````````K0,````````*````$0```+H#````````LP,````` +XM```*````$0```&8&````````N0,````````*````$0````0!````````OP,` +XM```````*````$0````("````````Q0,````````*````$0```'L$```````` +XMRP,````````*````$0````P%````````T0,````````*````$0```,H````` +XM````UP,````````*````$0```,\!````````W0,````````*````$0```"," +XM````````XP,````````*````$0```.0%````````Z0,````````*````$0`` +XM`.\&````````[P,````````*````$0```&D$````````]0,````````*```` +XM$0```(T!````````^P,````````*````$0```',``````````@0````````* +XM````$0```$P"````````%00````````*````$0```'P%````````)`0````` +XM```*````$0```'(%````````,`0````````*````$0```/@%````````/@0` +XM```````*````$0```%X$````````3`0````````*````$0```+D%```````` +XM6@0````````*````$0```%\`````````:`0````````*````$0```!P"```` +XM````=@0````````*````$0```-,&````````A`0````````*````$0```+`` +XM````````D@0````````*````$0```((&````````H`0````````*````$0`` +XM`)H#````````NP0````````*````$0```'$&````````Q@0````````*```` +XM$0```%@!````````T00````````*````$0```'T"````````W`0````````* +XM````$0```",%````````YP0````````*````$0```'<'````````^@0````` +XM```*````$0```'P%````````"04````````*````$0```-T#````````%04` +XM```````*````$0```-\%````````(P4````````*````$0````X!```````` +XM0`4````````*````$0```'P%````````3P4````````*````$0```!@%```` +XM````6P4````````*````$0```-\%````````:04````````*````$0```)<$ +XM````````=P4````````*````$0```-X$````````A04````````*````$0`` +XM`"\#````````H04````````*````$0```'T!````````KP4````````*```` +XM$0```'H#````````O04````````*````$0```!\!````````RP4````````* +XM````$0```%$%````````V04````````*````$0```#4`````````YP4````` +XM```*````$0```),#````````]04````````*````$0```.\%````````$@8` +XM```````*````$0```'P%````````(08````````*````$0```!`P` +XM```````!`````@```-8`````````@`P````````*````#0```#L!```````` +XME`P````````*````#0```',!````````F0P````````*````$0```-\%```` +XM````I`P````````*````#0```+P!````````M0P````````*````$0```*8" +XM````````O0P````````!`````@```.``````````Q0P````````!`````@`` +XM`$8!````````S0P````````*````#0````4"````````X0P````````*```` +XM#0```#T"````````Y@P````````*````$0```-\%````````\0P````````* +XM````#0```(8"`````````0T````````*````$0```$X`````````(@T````` +XM```*````$0```/L"````````+0T````````*````$0```"P%````````8@T` +XM```````*````$0```.8`````````>`T````````*````$0```'P\````````*````$0`` +XM`"T"````````N@\````````*````$0````L`````````T0\````````*```` +XM$0```#@$````````Z0\````````*````$0```#\$````````\0\````````! +XM`````@```%`!````````^0\````````!`````@```$H9`````````1`````` +XM```*````#0```,\"````````$1`````````*````#0```(`#````````-!`` +XM```````*````$0```/L"````````/Q`````````*````#0```-P#```````` +XM1!`````````*````$0```"0!````````3Q`````````*````#0```$L$```` +XM````5!`````````*````$0```,L&````````7Q`````````*````#0```+H$ +XM````````9!`````````*````$0```'0$````````;Q`````````*````#0`` +XM`#P%````````F!`````````*````$```````````````J1`````````*```` +XM$````*``````````LA`````````*````#0```(4%````````P!`````````* +XM````#0```'D&````````VQ`````````*````#0```#$'````````Y!`````` +XM```*````#0```.D'````````[1`````````*````#0```'X(````````]A`` +XM```````*````#0```.((````````"1$````````*````#0````4)```````` +XM%Q$````````*````#0```'X)````````(!$````````*````#0```,4+```` +XM````*1$````````*````#0```!`-````````,A$````````*````#0```%`. +XM````````.Q$````````*````#0```.4.````````1!$````````*````#0`` +XM`$D/````````31$````````*````#0```)@/````````5A$````````*```` +XM#0```)\0````````7Q$````````!`````@```-@#````````;!$````````* +XM````$``````&````````D1$````````!`````@```*<*````````F1$````` +XM```!`````@```,T*````````K!$````````*````#0```,(0````````MA$` +XM```````!`````@```*<*````````OA$````````!`````@```+X*```````` +XMRQ$````````*````#0```/@0````````UA$````````*````$````-`&```` +XM````Y1$````````*````#0```*`1````````[Q$````````*````$````'`' +XM````````^!$````````*````#0```,,1`````````1(````````*````#0`` +XM``P2````````"A(````````*````#0```-D2````````+A(````````*```` +XM#0```($3````````-Q(````````*````#0```$X4````````0!(````````* +XM````#0```!L5````````21(````````*````#0```&X6````````61(````` +XM```*````$````!`)````````;1(````````*````#0```#L7````````>Q(` +XM```````!`````@```(4-````````@Q(````````!`````@```)@-```````` +XMF1(````````!`````@```'<+````````H1(````````!`````@```(X+```` +XM````N1(````````*````$````$`)````````QA(````````*````$````-`) +XM````````X1(````````*````#0```#`8````````ZA(````````*````#0`` +XM`+(8````````^!(````````*````#0```#09````````K0`````````!```` +XM`@``````````````'``````````*````"P``````````````(``````````! +XM`````@``````````````-``````````*````"P``````````````.``````` +XM```!`````@```!``````````3``````````*````"P``````````````4``` +XM```````!`````@```"``````````=``````````*````"P`````````````` +XM>``````````!`````@```'``````````E``````````*````"P`````````` +XM````F``````````!`````@```.``````````M``````````*````"P`````` +XM````````N``````````!`````@```%`!````````(``````````*`````@`` +XM````````````.``````````*`````@```!``````````4``````````*```` +XM`@```"``````````<``````````*`````@```'``````````B``````````* +XM`````@```.``````````H``````````*`````@```%`!````````!@`````` +XM```*````!@``````````````!@`````````*````!@``````````````$``` +X5```````!`````@`````````````` +X` +Xend +END-of-symbols.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.sh new file mode 100644 index 0000000000..fcd2955c80 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-2/strip-debug-2.sh @@ -0,0 +1,6 @@ +# $Id: strip-debug-2.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-debug-2 tc/strip-debug-2 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -g -o symbols.o.1 symbols.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/in/strip-debug-3.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/in/strip-debug-3.in.shar new file mode 100644 index 0000000000..a9a6af6afa --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/in/strip-debug-3.in.shar @@ -0,0 +1,676 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# ls.uu +# +echo x - ls.uu +sed 's/^X//' >ls.uu << 'END-of-ls.uu' +Xbegin 555 ls +XM?T5,1@(!`0D```````````(`/@`!````H!M```````!``````````#!M```` +XM`````````$``.``'`$``&@`9``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````&1>````````9%X````````` +XM`!````````$````&`````&``````````8%````````!@4```````P`D````` +XM``!P"P``````````$````````@````8```"P90```````+!E4```````L&50 +XM``````"P`0```````+`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````7%X```````!<7D```````%Q>0```````"``````````(``````````0` +XM````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +XM94)31``9-0P`0P```%4````]````40```!4`````````.@```%`````````` +XM.0```#<```!.````0P```!0`````````/@```#0```!!````2P`````````I +XM`````````!8````%````2@```%(```!%`````````!H````J````)````$8` +XM`````````````#$`````````4P```"4`````````"0````@````````````` +XM```````,````.P```#,```!/````"P```!P```!4````+P```!T````````` +XM`````$T````L````1P```$P``````````````#\`````````20```$`````` +XM````+@```#(````````````````````````````````````````````````` +XM```!`````````````````````````````````````P``````````````#0`` +XM``````````````````8`````````"@`````````````````````````````` +XM$0```!@````````````````````>`````````!D````7``````````(````2 +XM````````````````````(@````X````0````#P````<````?````$P`````` +XM```````````````````C````+0```"`````````````````````A````-0`` +XM```````X````,```````````````&P```"8````G`````````#8````$```` +XM2````$(`````````/````$0`````````*P`````````H```````````````` +XM`````````````````````````&X!```2````7!=```````"*`````````-`" +XM```2````;!=```````#2`````````)D!```2````?!=```````"0```````` +XM`),"```2````C!=````````5`````````'4"```2````G!=````````R```` +XM`````"T!```2````K!=````````;`````````'L"```2````O!=````````` +XM`````````/8````2````S!=```````!\`0````````X````1`/'_L&50```` +XM`````````````*$!```2````W!=``````````````````!<````2````[!=` +XM``````"_`P```````&T````2````_!=```````#A`P```````%("```2```` +XM#!A```````">`````````!`"```2````'!A```````!5`````````!`````````$H!```2 +XM````_!A```````!?`````````.X````2````#!E````````H`````````+D" +XM```2````'!E````````I`````````-\!```2````+!E```````#H`0`````` +XM`!<"```1`!<`P&E0```````$`````````"0"```2````/!E```````"M`@`` +XM`````+D!```1`!```&!0```````(`````````+X````2````3!E```````#X +XM`@```````+(````2````7!E```````"5`````````',````2````;!E````` +XM``"S`P````````D"```2````?!E```````!D`0```````#4"```2````C!E` +XM`````````````````,0!```2````G!E````````(`````````.4````2```` +XMK!E``````````````````-4"```2````O!E````````A`0```````)H!```2 +XM````S!E```````"B`````````)@"```2````W!E````````/`0```````.X" +XM```0`/'_P&E0`````````````````-P````2````[!E```````!J`0`````` +XM`.("```2````_!E```````"H`````````),````1`!<`Q&E0```````$```` +XM`````'D````2````#!I```````#8!0```````,P!```2````'!I```````!? +XM`````````&@"```2````+!I```````#0!````````"T````2``T`>%A````` +XM`````````````*8!```2````/!I```````"E`@```````.`````````*$````2````7!M````````````` +XM`````$D````@`````````````````````````"0!```2````;!M````````` +XM`````````($````2````?!M```````!C`0```````,8````2````C!M````` +XM``!=``````````!L:6)U=&EL+G-O+C<`7T193D%-24,`:'5M86YI>F5?;G5M +XM8F5R`%]I;FET`%]F:6YI`%]'3$]"04Q?3T9&4T547U1!0DQ%7P!?2G9?4F5G +XM:7-T97)#;&%S&ET`'-E=&QO8V%L90!F='-? +XMF4`871O:0!U +XM#_____)390$`!H`0```.G0_____R4N4!``:`(```#IP/____\E +XM)E`0`&@#````Z;#_____)1Y0$`!H!````.F@_____R464!``:`4```#ID/__ +XM__\E#E`0`&@&````Z8#_____)090$`!H!P```.EP_____R7^3Q``:`@```#I +XM8/____\E]D\0`&@)````Z5#_____)>Y/$`!H"@```.E`_____R7F3Q``:`L` +XM``#I,/____\EWD\0`&@,````Z2#_____)=9/$`!H#0```.D0_____R7.3Q`` +XM:`X```#I`/____\EQD\0`&@/````Z?#^____);Y/$`!H$````.G@_O___R6V +XM3Q``:!$```#IT/[___\EKD\0`&@2````Z<#^____):9/$`!H$P```.FP_O__ +XM_R6>3Q``:!0```#IH/[___\EED\0`&@5````Z9#^____)8Y/$`!H%@```.F` +XM_O___R6&3Q``:!<```#I````Z0#^____)49/ +XM$`!H'P```.GP_?___R4^3Q``:"````#IX/W___\E-D\0`&@A````Z=#]____ +XM)2Y/$`!H(@```.G`_?___R4F3Q``:",```#IL/W___\E'D\0`&@D````Z:#] +XM____)19/$`!H)0```.F0_?___R4.3Q``:"8```#I@/W___\E!D\0`&@G```` +XMZ7#]____)?Y.$`!H*````.E@_?___R7V3A``:"D```#I4/W___\E[DX0`&@J +XM````Z4#]____)>9.$`!H*P```.DP_?___R7>3A``:"P```#I(/W___\EUDX0 +XM`&@M````Z1#]____)#\____);9.$`!H,0```.G0_/___R6N3A``:#(```#IP/S_ +XM__\EIDX0`&@S````Z;#\____)9Y.$`!H-````.F@_/___R663A``:#4```#I +XMD/S___\ECDX0`&@V````Z8#\____)89.$`!H-P```.EP_/___R5^3A``:#@` +XM``#I8/S___\E=DX0`&@Y````Z5#\____)6Y.$`!H.@```.E`_/___R5F3A`` +XM:#L```#I,/S___\E7DX0`&@\````Z2#\____)59.$`!H/0```.D0_/___R5. +XM3A``:#X```#I`/S___\E1DX0`&@_````Z?#[____)3Y.$`!H0````.G@^___ +XM_R4V3A``:$$```#IT/O___\E+DX0`&A"````Z<#[____)29.$`!H0P```.FP +XM^___`````$%43(UG"%53BQ](8\.%VTB-;,<02(DM+4\0`'XZ2(M7"$B%TG0Q +XM2(D5,T00``^V`H3`="-(@\(!/"](BP4?1!``2`]$PDB)!11$$``/M@)(@\(! +XMA,!UX;BP95``2(7`="M(B??H$____[]X6$``Z`G____H(/O__XG?2(GJ3(GF +XMZ-L1``")Q^AP_O__Z(O\___KUI"0D)"0D)"0D)"0D)!(@^P(@#V931```'00 +XMZR202(/`"$B)!;5#$`#_TDB+!:Q#$`!(BQ!(A=)UY,8%<4T0``%(@\0(PV9F +XM9I!F9F:02(,]^$H0``!T%K@`````2(7`=`R_@&=0`$F)PT'_XY#SPY"0D)"0 +XMD)"0D)"0D)"04TB+5GBY`0```$B+1WA(BUA(2#E:2'X$6XG(PWT'N?_____K +XM\UM(B[:`````2(N_@````.E#_/__9F9FD&9FD$B)\$B)_DB)Q^FR____9I!( +XMBU9X2(M'>$B+2#A(.4HX?@:X`0```,-\#$B+2$!(.4I`?^Y]"[C_____9F:0 +XM9I##2(NV@````$B+OX````#IZ/O__V9F9I!F9F:09F9FD$B)\$B)_DB)Q^FB +XM____9I!(BU9X2(M'>$B+2&A(.4IH?@:X`0```,-\#$B+2'!(.4IP?^Y]"[C_ +XM____9F:09I##2(NV@````$B+OX````#IB/O__V9F9I!F9F:09F9FD$B)\$B) +XM_DB)Q^FB____9I!(BU9X2(M'>$B+2!A(.4H8?@:X`0```,-\#$B+2"!(.4H@ +XM?^Y]"[C_____9F:09I##2(NV@````$B+OX````#I*/O__V9F9I!F9F:09F9F +XMD$B)\$B)_DB)Q^FB____9I!(BU9X2(M'>$B+2"A(.4HH?@:X`0```,-\#$B+ +XM2#!(.4HP?^Y]"[C_____9F:09I##2(NV@````$B+OX````#IR/K__V9F9I!F +XM9F:09F9FD$B)\$B)_DB)Q^FB____9I!(BX>`````2(N^@````$B)QNF6^O__ +XM9F9FD&9FD&9FD$B+MH````!(B[^`````Z7GZ__^0D)"0D)"0D)"0D)"02(L_ +XMBU=H@_H'=%5(BS:+3FB#^0=T2H/Z"G0F@_D*="$YRG0L2(-_8`!U)8L%"TL0 +XM`(7`=1N#Z@&X`0```'4'\\/IFO___X/I`;C_____=.],BQW92A``0?_C9F:0 +XM9F:0,<##9F9FD&9FD&9FD&9FD$%7059!54%408G455-(@>QH!0``1(L5%4P0 +XM`$B)?"1(2(ET)$!(QX0D&`4```````!%A=)U$$2+#?=+$`!%A$)%@%````````QX0D5`4```````!(QX0D*`4```````!(QX0D,`4````` +XM``!(QX0D.`4```````!(QX0D0`4```````!(QX0D(`4```````!T"8`X``^% +XMD08``$B#?"1```^$+@8``$B+7"1`08/D`DC'1"10`````,=$)%@`````QT0D +XM?`````!(QT0D<`````!$B60D/.G,`@``@_@*#X3/`@``2(-\)$@`#X2K`P`` +XM2(N#@````(`X+@^$@`,``$B+0TA(.X0D,`4``$@/1H0D,`4``(L-M4H0`(7) +XM2(F$)#`%``!U"HL57TH0`(72="E(BW-(2(N[@````.AG+```2#N$)#`%``!( +XM#T:$)#`%``!(B80D,`4``(M$)%R%P`^$,P(``$R+8WA)BT0D4$@[A"1`!0`` +XM2`].A"1`!0``2(F$)$`%``!!BT0D!$@[A"0X!0``2`]&A"0X!0``2(F$)#@% +XM``!!#[=$)`I(.X0D*`4``$@/1H0D*`4``$B)A"0H!0``28M$)$A(.X0D2`4` +XM`$@/3H0D2`4``$B)A"1(!0``28M$)%!(`40D4(L%"4H0`(7`#X2>`0``BP6C +XM2!``A<`/A*L"``!!BTPD#$B-O"3P!```NO180`"^#0```#'`Z%WX__]!BTPD +XM$$B-O"0`!0``NO180`"^#0```#'`Z#_X__](C80D\`0``$B)1"1@2(V$)``% +XM``!(B40D:$B+?"1@Z'OY__])B<:+A"14!0``2(M\)&A).<9$B?`/1H0D5`4` +XM`(F$)%0%``#H4OG__TF)Q8N$)%@%``!).<5$B>@/1H0D6`4``$4Q_XF$)%@% +XM``"+!3I)$`"%P`^%4P(``(L%Y$@0`#'22,>$)!@%````````A<`/A:,"``!- +XM`?5+C7PO+$@!U^A6^/__2(7`2(G%#X3`"```2(UX($B).$B+="1@Z.GX__]) +XMC7PN(4B)?0A(BW0D:.C6^/__00^W1"0()0#P```]`"````^$IP$``#T`8``` +XM#X2<`0``1(L=KD@0`$6%VP^%I`$``$2+%59($`!%A=)T.D2+#9)($`!)C5SCHB?7__TB+LX`` +XM``!(B<*_[5A``#'`Z"/V__](QT,8`0```,<%X480``$```!(BUL02(7;=;M$ +XMBT0D?$6%P`^$\P(``$B+1"1`BTPD7$B)A"20!```BT0D?(7)B80DI`0``$B+ +XMA"0P!0``B80DJ`0```^%"P4``$B-O"20!```_Q5%1A``BQ6[1Q``QP5]1A`` +XM`0```(72=!](@WPD0`!T%TB+7"1`2(M[(.@O]___2(M;$$B%VW7N2('$:`4` +XM`%M=05Q!74%>05_#BS421A``A?8/A7+\__](QT,8`0```.D#____@^@!#X5< +XM_/__BSWJ11``A?\/A4[\___KVD&+?"0,,?;HM/7__TB)1"1@08M\)!`Q]NA3 +XM]/__2(E$)&CIA/W__T2+'1)'$`#'1"18`0```$6%VP^$7/[__TJ-?"TB2(E] +XM$$B+="1PZ.[V__](BWPD<.B$]O__Z3K^__]!BWPD7.C5\O__2(7`2(E$)'`/ +XMA+L&``"`.`!U($B)Q^A:]O__O_=80`#H_HO_3__XM$)#R%P'1X2(NT)!`%``!(B>_H=_7_ +XM_X/``71X2(N\)!`%``!(C;0D&`4``.@-\___@\`!=%Y(B[PD$`4``.A[\___ +XM2(.\)!@%````='E(B[PD&`4``.C#]?__2#N$)"`%``!(B<)(BX0D(`4``$@/ +XM1\)(B80D(`4``.F9_/__2(NT)!`%``!(B>_H;_+__X/``76(2(M#"$B+DX`` +XM``"_!5E``$B+<#`QP.@?]/__2(N\)!`%``#H`O/__TB#O"08!0```'6'O_=8 +XM0`#H'?+__TB)A"08!0``Z7#___](BT,(2(VL)(````!,BX.`````NA-90`"^ +XM`00``$B)[TB+2"@QP.BU\___Z?'^___'1"1\`````$C'1"10`````,=$)%@` +XM````BST)11``A?]U#HLUFT00`(7V#X1I_?__2(-\)$@`#X7I_/__Z5C]__\Q +XMP(,]>400```/E<")1"1OX__](B`.CIUY3PZ=>'&`3`/MD(!B$$!2(/!`L9!`0`/ +XMMD("2(/"`83`==F`>?\Z#X08!```2(V$)"`%``!(C8PD0`4``$B-E"0X!0`` +XM3(V,)%0%``!,C80D*`4``+Z064``2(E$)"!(C80D,`4``$B)[TB)1"082(V$ +XM)$@%``!(B40D$$B-A"1](B80D2`4``.AA\O__ +XMZ6+W__^+1"182(N,)$`%``!(C9PDT`0``+H964``OA@```!(B=^)A"2@!``` +XM2(M$)%!(B80DF`0``#'`Z!#Q__](B=F+`4B#P02-D/_^_O[WT"'"@>*`@("` +XM=.B)T+X8````2(G?P>@0]\*`@```#T302(U!`D@/1,B+A"1$)%@%````````QX0D7`4```````!(QX0D +XM2`4```````!(QX0D,`4```````!$BP4Q0!``,___V;'`3``Z=[[__]( +XMC4T"9L=%`#`ZQD4"`.EW^___OOE80`"_`0```#'`Z&OO__]F9F:09F9FD&9F +XM9I!F9I!!5[C`'D``059!B?Y(B?=!54&)U3'21(GN05154TB#[`B+#7$^$`"% +XMR4@/1-#HRN[__TB%P$F)Q`^$.`(``#'V2(G'Z`3N__](AP$``(L%^#T0`(7`#X0(`0``BP5Z/1``A<`/A4D! +XM``!(BS5S/1``BT8,@^@!A<")1@P/B%H!``!(BP;&``I(@\`!2(D&2(M[,.BD +XM#P``OT=90`#HYNK__T2)_DR)Y^@K[?__1(GJ2(G&2(G?2(G%Z([R__^+!6@] +XM$`"%P`^%0/___TB%[0^$-____[H$````2(G>3(GGZ$/L___I(O___V:0@_@$ +XM=`F#^`SCHQNO__TB+LX````!(B<*_[5A``#'`Z&#L___'!28] +XM$``!````Z>7^__]F9I!FD$B+LX````"_*EE``#'`Z#GL___IR/[__^AO[/__ +XM1(L8187;#X6<````2(/$"%M=05Q!74%>05_#08/^`0^.-/___TB+>S#HQ0X` +XM`+]'64``Z`?J___'!<$\$``!````Z1+___^+!9H]$`"%P`^%9/[__T'VQ0A! +XMOP`!```/A5[^___I3_[__TB+-2H\$`"_"@```.ADZO__Z<;^__^+!4T\$`"% +XMP`^$-?[__^ER_O__OPH```#HPNS__V9FD&9FD.F>_O__ODE90`"_`0```#'` +XMZ.;L__^^(5E``+\!````,<#HU>S__V9FD&9FD&9FD$%6055)B?6^&UU``$%4 +XM55.)^S'_2('L(`8``$B-A"0`!```2(F$)`@&``#HO.S__[\!````Z*+L__^% +XMP`^$B````+]264``QP7/,1``4````.AVZ?__2(7`=`F`.``/A=`'``!(C90D +XM$`8``#'`OFAT"$"_`0```.C_Z?__@\`!=!8/MX0D$@8``&:%P'0)#[?`B06( +XM,1``QP5V/!```0```+T0````NLA90`!,B>Z)W^B&ZO__@_C_=$&#Z#&#^$=V +XM,.@8'@``Z]V_4EE``,<%/SL0``$```#H[NC__TB%P'2_2(G'Z*'H__^)!2\Q +XM$`#KKXG`_R3%.%I``(L-_CH0`$2+)=P4``+]:64``Z+'H__]( +XMA=(B<;HQ>K__X/H +XM`0^$-@8``(L%VCL0`(7`=#J^4#=``+\"````QP6^.Q```0```.BIZO__OE`W +XM0`"_`P```.B:ZO__OX990`#H0.C__TB)Q^@,"```BP7&.Q``A<`/A-D```"+ +XM%;P[$`"%TG4:BSU*.A``A?]U$(LUE#L0`(GH@\@!A?8/1.B+#5PZ$`")Z`R` +XMAB%TG4,1(LU(#L0`$6%]G0;1(L=##H0`$6%VP^$.@4``$C'!2`[$``" +XM````1(L5#3H0`$6%T@^$5`0``$2+#0DZ$`!%A;__TB%P`^%/O[__^E7_O__@\T@QP7Z.!```0```.F<_?__ +XMQP4#.A```````,<%&3H0``$```#'!/K__XL59340`+`!A=(/1056-1``B050-1``Z5SZ__]$BS5H-1`` +XM187V=;M$BQU(-A``187;#X2:`0``2,<%%#40`,`=0`#I6OO__XL]/340`(7_ +XM#X5!^___BS4;-A``A?8/A%0!``!(QP7H-!``$!Y``.DN^___BS4)-1``N#!% +XM0`"ZP$%``(7V2`]$PDB)!;XT$`#I)_O__TB-O"00`#IM?K__TR-M"0(!@``OW=90`!,B?;HX>7__TR) +XM]K]Z64``2(D%3C40`.C-Y?__3(GVOWU90`!(B06*-1``Z+GE__],B?:_@%E` +XM`$B)!98U$`#HI>7__TR)]K^#64``2(D%6C40`.B1Y?__2(7`2(D%$S40``^$ +XMT@```$B#/?4T$```#X1'^?__2(,]-S40```/A#GY__](@SWI-!````^$*_G_ +XM_\<%`340``$```#I)OG__TB)Q^A0X?__QP72-!```0```(D%U"D0`.E1^/__ +XMBPT!-1``A0`!%AXO__NG`W0`!(BSU.-!``O@$```!(@\0(Z43B__](BSW9,Q``NF`\ +XM0`"^`0```.@NXO__NF`\0`#KSF9F9I!F9F:09F:04XG[Z)C___^)WS'VZ+OB +XM___HUN/__XG>B<=;Z6S@__](@^P8N@$```!(C70D%T"(?"07OP$```#H+^#_ +XM_S'`2(/$&,-F9F:09F9FD&9F9I!!5[@;74``28G_059!54%455-(@^PH2(7_ +XM3`]$^$4Q[44Q]DR)_T4QY.A^X___9L=$)`X``$B)!"3K1&9FD&:0#[[!@^@P +XMB0-F@WPD#@`/A,````!FQT0D#@$`2(/%`4B#PP1(@_T"=5)!@\4!28/&#$F# +XMQ`)!@_T+#X3A````3#DD)$''AFAJ4```````=U!(BQ5Y)0``00^V!!2(1"00 +XM00^V1!0!B$0D$4ECQ3'M2(T$0$B-'(5@:E``#[9,+!"-0=`\!P^&=?___XU! +XMGSP'=R,/OL&#Z&&)`^E\____D$,/M@0\B$0D$$,/MD0\`8A$)!'KM8U!OSP' +XM=RD/OL%!QX9H:E```0```(/H08D#Z4?___^_.%U``#'`Z)S@___I+____P^V +XMP3L%]C`0`'T12&/02(L%]C`0`(N$D$`(``"#^'AT#P^^\;^`74``,<#H9^#_ +XM_\<#_____^G[_O__2(/$*%M=05Q!74%>05_#D%53B?M(C2Q;2(/L"(L$K6AJ +XM4`"%P'5YBQ2M8&I0`(/Z_W0E2(L]OC$0`#'VZ+O>__](AG_&```Z:H1``!F9F:09F:09F:02(/L"(L%5BT0`(7`=2A(BS53+1``BT8, +XM@^@!A<")1@QX+DB+!D"(.$B#P`%(B08QP$B#Q`C#2(LU*RT0`.AJV___,<`\```@?\`0```='4QP$B#Q`C#B?@E`/```#T`H``` +XM#X3N````#X>5````/0`0```/A'(!```]`$```&9FD&:0=#^#YTETQ8L%DRP0 +XM`(7`#X6I`0``2(LUC"P0`(M&#(/H`87`B48,#XB.`@``2(L&Q@`J2(/``4B) +XM!K@!````ZXV+%5DL$`"%T@^%P0```$B+-5(L$`"+1@R#Z`&%P(E&#`^(.@$` +XM`$B+!L8`+TB#P`%(B0:X`0```$B#Q`C#9I`]`,````^$H````#T`X```#X5L +XM____BP4$+!``A<`/A:L!``!(BS7]*Q``BT8,@^@!A<")1@P/B',!``!(BP;& +XM`"5(@\`!2(D&N`$```#I^_[__XL%QRL0`(7`#X6)`0``2(LUP"L0`(M&#(/H +XM`87`B48,#XC@````2(L&Q@!`2(/``4B)!K@!````Z;[^__](BS61*Q``OR\` +XM``#HR]G__[@!````Z:/^__^+!6\K$`"%P`^%9P$``$B+-6@K$`"+1@R#Z`&% +XMP(E&#`^(O@```$B+!L8`/4B#P`%(B0:X`0```.EF_O__BP4R*Q``A<`/A0\! +XM``!(BS4K*Q``BT8,@^@!A<")1@QX;$B+!L8`?$B#P`%(B0:X`0```.DM_O__ +XM.T8H#XV]_O__OR\```#HN-O__[@!````Z1#^__](BS7C*A``ORH```#H'=G_ +XM_[@!````Z?7]__\[1B@/C1?___^_0````.B`V___N`$```#IV/W__SM&*'V/ +XMOWP```#H9]O__[@!````Z;_]__\[1B@/C3G___^_/0```&9FD.A'V___N`$` +XM``#IG_W__SM&*`^-A/[__[\E````9F:0Z"?;__^X`0```.E__?__2(LU4BH0 +XM`+\E````Z(S8__^X`0```.ED_?__2(LU-RH0`+]`````Z''8__^X`0```.E) +XM_?__2(LU'"H0`+]\````Z%;8__^X`0```.DN_?__2(LU`2H0`+\]````Z#O8 +XM__^X`0```.D3_?__.T8H#XUI_?__ORH```#HGMK__[@!````Z?;\__]F9F:0 +XM9F9FD$B)7"3@3(ED)/!%,>1,B6PD^$B);"3H2(/L*$2+%3XK$`!(B?M)B=5( +XMBV]X1872#X7;````1(L-Q"H0`$6%R0^%C0```$2+!>0J$`!%AZ_ +XM!%U``$B)PD@#55!(B<%(@^H!2(G02,'Z/TCW^4B)PC'`Z,G8__]!`<3I.O__ +XM_V9FD&:0BU4$O[Q<0``QP.BMV/__08G$Z0[___]F9I!F9I!F9I!52(G]4TB# +XM[`A(BQ](A=MU+.ME2(LU?B@0`(M&#(/H`87`B48,>%A(BP;&``I(@\`!2(D& +XM2(M;$$B%VW0[2(-[&`%T\(M5'(MU+$B)W^A^_O__1(L=-R@0`$6%VW2U2(LU +XM,R@0`+\*````Z&W6__](BUL02(7;=<5(@\0(6UW#OPH```#HT]C__^NI9F:0 +XM9I!!5T%6055!5%532(/L*(,]5RD0``%(B7PD"(M'%$49[4&#Y0=!@\4!.P56 +XM'A``#X_\`@``2(M<)`A(BQ/'1"08`````$B%TG0E2(L-,"@0`$B#>A@!=`Y( +XM8T0D&$B)%,"08`4B+4A!(A=)UXD2+%2LI$`!(BT0D"$6%THM0&'0(BT`L +XM@\`!`<*+#;`H$`"%R70-2(M<)`B+0QR#P`$!PH,]Z"@0``%$B>B#VO_WV$0! +XMZHE$)!`APHE4)"2+1"0DBQ69'1```<`YT`^/1P(``(G0P?H?]WPD)(M4)!A! +XMB<>)T,'Z'T'W_X/Z`4B+5"0(@]C_B40D'$B+`DB%P`^$PP$``$B#>&``#X6X +XM`0``1(M$)!Q%A<`/CGP!``#'1"04`````,=$)"``````BSUA*!``BU0D((7_ +XM#T54)!1%A?^)5"04#XX0`0``1(MD)"0Q[4&^`0```$B+3"0(2(L%'"<0`(M1 +XM'(MQ+$AC3"042(L\R.C(_/__BU0D%(G!BS40*!``BT0D%`-$)!R+7"08@\(! +XMA?8/1-`YVHE4)!0/C;<````!S4*-7"T`(UPD$$0YXW]=BP7:)Q``AASUO__ZZB+'9\E$`"%VW5#2(LUG"40`(M&#(/H`87` +XMB48,>$)(BP;&``I(@\`!2(D&@T0D(`&+1"0<.40D(`^%E/[__TB#Q"A;74%< +XM05U!7D%?PTB+-5DE$`"_"@```.B3T___Z\N_"@```.@'UO__Z[]$BPW6)A`` +XM187)=0B%R0^$-/[__TB+3"0(2(LU>280`+_"7$``2(M1"$B#Z@%(C0PR,=)( +XMB0/A7L```!(BS47)!``BT8,@^@!A<")1@P/B(X```!(BP9%,>3& +XM``I(@\`!2(D&BU4$](BP;&``I(@\`!2(D&6UU! +XM7,-(BS6<(Q``OPH```!%,>3HT]'__^N76UU!7$B+-8(C$`"_"@```.F\T?__ +XMOPH```!%,>3H+]3__^EP____6UU!7+\*````Z1S4__]!5T%628G^055!5%53 +XM2('L:`@``$R+)TV%Y`^$\P(``$F#?"1@``^%YP(``$R-O"0P!```0;T!```` +XMQT0D'/_____'1"08`````.D[`@``D$F+C"2`````NO%80`"^`00``$R)_S'` +XM3(G[Z`W3__])BT0D>`^W0`@E`/```#T`H```#X3X`@``/0#@```/A.T"``"^ +XM.P```$B)W^B[`0```.BVT?__@^@!#X00!0``3(GO0;T!````Z,_3__]F +XM9I"+30")3"0<28M<)"`/MTT*2(VT)$`(``!%BT8X08M6,+_07$``2(M#"$B) +XM1"0(08M&*(D$)$R+"S'`Z"W2__]$BQ6V(Q``1872#X51`P``1(L-7B,0`$6% +XMR0^%)P,```^W10@E`/```#T`(```#X0M`@``/0!@```/A"("``!%BT80187` +XM#X7F`P``BST3(Q``2(M52$&+=C2%_P^$OP,``+X%````3(G_0;D'````0;@@ +XM````N1M=0`#HS<___TR)_K\*74``,<#HGM'__V:0BPW:(A``A[__XL% +XMLR(0`(7`#X4;`@``#[=%""4`\```/0"@```/A&<"``"+!0$A$`"%P`^%"0(` +XM`$B+-?H@$`"+1@R#Z`&%P(E&#`^(KP,``$B+!L8`"DB#P`%(B09-BV0D$$V% +XMY`^$U0```$F#?"08`73JBQU8(A``28ML)'B%VP^%2P$``$2+'>0A$`!%A=L/ +XMA5X!```/MWT(2(VT)$`(``#H%M#__T6%[74-BT0D'#E%``^$'_[__TF#?"1@ +XM`&:0#X1J_?__28M$)`A-BX0D@````$R)^[H364``O@$$``!,B?](BT@H,<#H +XM;M#__^E<_?__1(LMVB$0`$6%[74*BRUK(1``A>UT+4F+5@A(BS5\(1``O\)< +XM0`!(@^H!2(T,,C'22(G(2/?V2(G&,<#H"=#__TV+)DV%Y`^%S?S__TB!Q&@( +XM``!;74%<05U!7D%?PTB)WK_Q6$``,<#H#-#__T&]`0```.EE_?__9F:09I"+ +XM112)PC#F@?K_````#X9U`0``#[;TO^I<0``QP.BJS___BPWH(!``AUF9F:09F9FD.DK^___Z&+-__^+..AKS/__2(L]D!T0`$B) +XMP4B)VKX/74``,<#H(LO__^E:_/__2(V4)%@(``"^`0```$R)[^B(S/__@^@! +XM=4F#PP&#^P1UWL:$)$H(```KZ<'Z__^_"@```.CTS?__Z4_\__]F9I#H]\S_ +XM_X,X%@^$=____TB)WK_Q6$``,<#H/\W__^F>^O__@_L##XZ$^O__9F:09I#K +XMKY"0D)"0D)"0D)"0D)"02(/L"$B+#>T<$`"_N%U``+H^````O@$```#H7Z@````$%6055%,>U!5$&)]#'V54B)_5-( +XM@>R8````2(GG3(V\)(P```#H2\S__T6%Y'46Z8P```!F9I!FD$F#Q0%(`=U% +XMA>1T>TECU$B)X4B)[DR)_^@_RO__2(7`2(G#=&)(@_O_=#Q(@_O^D'1JB[PD +XMC````('__P```'1UA4B!Q)@```!, +XMB>A;74%<05U!7D%?PT*-!*4`````2)A)`<7KW&9FD&:005>Z@````#'V059% +XM,?9!54F)_4%455-(@>R8````2(GGZ&;+__](C;PDC````$B)X;H&````3(GN +XMZ&[)__](A5T)8L%%QL0`(7`=,,/MCM(BS41&Q``@\4!2(/#`>A) +XMR?__1#GE==N+G"2,````30'E@?O_````=WM(BP7O&A``2&/3BT300*D```0` +XM#X0S____,<"%VW0U@?O_````#X?B````2(L%Q!H0`$ACTXM$T$`E```$X$B) +XMPH'B````X`^$K0```$B)T$C!Z!Y!`<;I\/[__SM&*`^V^GP*0(#_"@^%0___ +XM_^@_R___9F:0Z4+___^)W^CPR/__9F9FD.N&NH`````Q]DB)Y^@;RO__BQ5) +XM&A``A=)U>$B+-48:$`!!#[95`(M&#(/H`87`B48,>')(BP:($$B#P`%(B09) +XM@\4!08/&`>EY_O__3(GNO_%80``QP.@0RO__00'&2('$F````$2)\%M=05Q! +XM74%>05_#)0``!`!(@_@!&<"#R`'I1____XG?Z%[(___I(/___T$/MGT`2(LU +XMR1D0`.@(R/__ZYH[1B@/MOI\!D"`_PIU@.ASRO__ZX5F9I!FD$%7NH`````Q +XM]D4Q_T%6055)B?U!5%532('LF````$B)Y^A&R?__2(V\)(P```!(B>&Z!@`` +XM`$R)[NA.Q___2(7`28GM`P``28U&`DB#^`$/A@4!``"+G"2,````@?O_ +XM````#X>/`P``2(L%/AD0`$ACTXM$T$"I```$``^$`0,``(/[(@^$^`(``(/[ +XM7`^$[P(``$6%]GYH3(GK,>WK,TB+-?\8$``/MA.+1@R#Z`&%P(E&#`^('`,` +XM`$B+!H@02(/``4B)!H/%`4B#PP%$.?5T)T2+)<08$`!%A>1TP0^V.TB+-;T8 +XM$`"#Q0%(@\,!Z/7&__]$.?5UV8N<)(P````QP(7;=#6!^_\````/AZX#``!( +XMBP64&!``2&/3BT300"4```3@2(G"@>(```#@#X1V`P``2(G02,'H'D$!QTF# +XM_OX/A&P"``!)@_[_#X2U`@``30'UZV0 +XMZ>T```!(BS4L&!``BT8,@^@!A<")1@P/B)@!``!(BP;&`%Q(@\`!2(D&BST` +XM&!``A?\/A>\```!(BS7Y%Q``B=C`Z`8/ML"->#"+1@R#Z`&%P(E&#`^(-P$` +XM`$B+!D"(.$B#P`%(B0:+-<(7$`"%]@^%V@```$B+-;L7$`")V,#H`X/@!XUX +XM,(M&#(/H`87`B48,#X@W`0``2(L&0(@X2(/``4B)!HL-A!<0`(7)#X7#```` +XM2(LU?1<0`(G8@^`'C7@PBT8,@^@!A<")1@P/B"$!``!(BP9`B#A(@\`!2(D& +XM2(/%`4&#QP1!.>P/CM_^__]$BP4W%Q``0@^V7"T`187`#X3]_O__2(LU*1<0 +XM`+]<````Z&/%__^+/1$7$`"%_P^$$?___XG82(LU"!<0`,#H!@^V^(/',.@^ +XMQ?__BS7L%A``A?8/A"K___]F9F:0B=A(BS7?%A``P.@#B<>#YP>#QS#H$\7_ +XM_XL-P180`(7)#X0]____OP<```!(BS6U%A``(=^#QS#H[\3__^E/____.T8H +XM?`]`@/\*9F:09I`/A;7^___H40`#HS<3__TB%P$B)PP^$9O___T2+%5X5 +XM$`!%A=(/A98```!(BS56%1``BT8,@^@!A<")1@P/B*8```!(BP;&`%Q(@\`! +XM2(D&1(L-*140`$6%R7532(LU)140``^V0P&+5@P/OOB#Z@&%THE6#'A@2(L& +XM0(@X2(/``4B)!D&#QP+IE/S__R4```0`2(/X`1G`@\@!00''Z7[\__^)W^AB +XMP___Z53\__\/OGL!2(LUSA00`.@-P___Z\-(BS7`%!``OUP```#H^L+__^EY +XM____.U8H?`8\"F:0=97H9<7__^N;.T8H9F9FD`^-3?___[]<````9F:09I#H +XM1\7__^E&____9F:09F:005>Z@````#'V13'_059)B?Y!54%455-(@>R8```` +XM2(GGZ!;$__](C;PDC````$B)X;H&````3(GVZ!["__](AQUVHNL)(P````QP(7M=#6! +XM_?\````/AW0!``!(BP5O$Q``2&/5BT300"4```3@2(G"@>(```#@#X0_`0`` +XM2(G02,'H'DT![D$!Q^GH_O__9I`[1B@/MOI\"D"`_PH/A6#____HYF+_O__BP7/$A``A<`/A:P```!(BS7($A``BT8, +XM@^@!A<")1@P/B.D```!(BP;&`#](@\`!2(D&28/&`4&#QP&Z@````#'V2(GG +XMZ%?"___I//[__XGOZ`O!___IB?[__TB+-7L2$`"_/P```.BUP/__ZX:+!6$2 +XM$`"%P`^%LP```$B+-5H2$`"+1@R#Z`&%P(E&#`^(L0```$B+!L8`/TB#P`%( +XMB09!@\05_#2(LU'!(0`+\_````Z%;`___I +XM8____R4```0`2(/X`1G`@\@!Z;7^__^)[^AWP/__Z8[^__\[1BAF9I`/C>S^ +XM__^_/P```&9FD&:0Z)?"___IY?[__SM&*&9FD`^-"____[\_````9F:09I#H +XM=\+__^D$____2(LUIQ$0`+\_````Z.&____I7/___SM&*`^-1O___[\_```` +XM9I#H1\+__^E"____D)"0D)"02(L%"0\0`%-(@_C_=!4QV__02(N#6&=0`$B# +XMZPA(@_C_=>U;PY"0D$B#[`CHO\/__TB#Q`C#`````````````"1&'`@)`!,4U]#3TQ724142%,`;6%L;&]C`"5S.B`E +XM"``)3-D+"`E +XM,V0@`"4J&-X9'AB +XM>&5G961A8F%G86-A9`!,4T-/3$]24R!S:&]U;&0@=7-E(&-H87)A8W1E!`!`PP'")`!```<````'````*`;0`"3`````$(.$(P"10X8 +XM00X@@P2&`Q0````\````0!Q``#@`````1`X0`````!0```!4````@!Q``"(` +XM`````````````!0```!L````L!Q``#D`````00X0@P(``!0```"$````\!Q` +XM``X``````````````!0```"<`````!U``$0``````````````!0```"T```` +XM4!U```X``````````````!0```#,````8!U``$0``````````````!0```#D +XM````L!U```X``````````````!0```#\````P!U``$0``````````````!0` +XM```4`0``$!Y```X``````````````!0````L`0``(!Y``$0````````````` +XM`!0```!$`0``&!@``````-````-P!``!P*T``AP(```!"#A!'#AB.`X\" +XM2`X@C01*#BA!#C!!#CA$#D"#!X8&C`4````````L````%`(````N0`#F"``` +XM`$(.$$(.&(T#C@)*#B!!#BA!#C"#!H8%C`1+#M`,```4````1`(``/`V0`!5 +XM`````$0.$``````4````7`(``%`W0``@`````$$.$(,"```4````=`(``'`W +XM0``D`````$0.(``````T````C`(``*`W0`!O`0```$(.$(\"2@X80@X@0@XH +XM00XP00XX1`Y@@P>&!HP%C02.`P```````!P```#$`@``$#E``*L`````00X0 +XM00X8@P.&`DH.(```%````.0"``#`.4``1@$```!'#A``````'````/P"```0 +XM.T``#@$```!!#A!!#AA$#H`!@P.&`@`4````'`,``"`\0``V```````````` +XM```4````-`,``&`\0`!G`````$0.$``````4````3`,``-`\0``H`P```$0. +XM$``````<````9`,```!`0``G`0```$J,`X,%40XPA@2-`@```!P```"$`P`` +XM,$%``(L`````00X0A@)$#AA$#B"#`P``-````*0#``#`04``90,```!"#A!" +XM#AA"#B!"#BA!#C!!#CA$#F"#!X8&C`6-!(X#CP(````````<````W`,``#!% +XM0`!``0```$(.$$$.&(8#C`)$#B"#!#0```#\`P``<$9``&(&````0@X00@X8 +XMC@./`D4.($(.*$$.,$$..$<.H!&#!X8&C`6-!```````%````#0$``#@3$`` +XM*0````!$#A``````-````$P$```034``ZP````!"#A!'#AA"#B"-!(X#CP)% +XM#BB,!48.,(8&1`XX1P[0`8,'```````T````A`0```!.0``;`@```$(.$$D. +XM&(X#CP)%#B"-!$4.*$$.,$$..$<.T`&#!X8&C`4``````#0```"\!```(%!` +XM`"H%````0@X0CP),#AA"#B"-!(X#10XH00XP00XX1P[0`8,'A@:,!0`````` +XM-````/0$``!054``^@(```!"#A"/`DP.&(X#10X@0@XH00XP00XX1P[0`8,' +XMA@:,!8T$````````````&``````````!>E(``7@0`0,,!PB0`0```````!0` +XM```@````4%A``"4`````2`X0@P(```$``````````0`````````!```````` +XM`%T``````````0````````")``````````P`````````.!=````````-```` +XM`````'A80```````!`````````#X`4````````4`````````6`Q````````& +XM`````````&`$0```````"@`````````1`P````````L`````````&``````` +XM```5`````````````````````P````````"(9U````````(`````````8`8` +XM```````4``````````<`````````%P````````#8$$````````<````````` +XM2!!````````(`````````)``````````"0`````````8`````````/[__V\` +XM````&!!```````#___]O``````$`````````\/__;P````!J#T`````````` +XM```````````````````````````````````````````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````/__________``````````#__________P````````````````````"P +XM95````````````````````````````!B%T```````'(70```````@A=````` +XM``"2%T```````*(70```````LA=```````#"%T```````-(70```````XA=` +XM``````#R%T````````(80```````$AA````````B&$```````#(80``````` +XM0AA```````!2&$```````&(80```````'`@)``D1G)E94)31#H@'`@)`!'0T,Z +XM("A'3E4I(#0N,BXQ(#(P,#'`@)`!'0T,Z("A' +XM3E4I(#0N,BXQ(#(P,#6YS='(`+F=N=2YV97)S:6]N +XM`"YG;G4N=F5R'0`+F9I;FD`+G)O9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F%A```````!X6`````````X````````````````````$```````````````` +XM````>0````$````"`````````)!80```````D%@```````#,!0`````````` +XM````````$````````````````````($````!`````@````````!<7D`````` +XM`%Q>````````"`````````````````````0```````````````````"/```` +XM`0````,``````````&!0````````8````````$P````````````````````0 +XM````````````````````E0````$````"`````````%!@4```````4&`````` +XM``!@!0``````````````````"````````````````````)\````&`````P`` +XM``````"P95```````+!E````````L`$````````%``````````@````````` +XM$`````````"H`````0````,`````````8&=0``````!@9P```````!`````` +XM```````````````(````````````````````KP````$````#`````````'!G +XM4```````<&<````````0````````````````````"``````````````````` +XM`+8````!`````P````````"`9U```````(!G````````"``````````````` +XM``````@```````````````````"[`````0````,`````````B&=0``````"( +XM9P```````#@"```````````````````(``````````@`````````P`````@` +XM```#`````````,!I4```````P&D```````"P`0``````````````````(``` +XM`````````````````,4````!`````````````````````````,!I```````` +XMGP(```````````````````$````````````````````!`````P`````````` +XM``````````````!?;````````,X````````````````````!```````````` +X&```````` +X` +Xend +END-of-ls.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.sh new file mode 100644 index 0000000000..416bcfa3c7 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-3/strip-debug-3.sh @@ -0,0 +1,6 @@ +# $Id: strip-debug-3.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-debug-3 tc/strip-debug-3 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -g -o ls.1 ls" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-4/in/strip-debug-4.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-4/in/strip-debug-4.in.shar new file mode 100644 index 0000000000..9d05c99386 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-debug-4/in/strip-debug-4.in.shar @@ -0,0 +1,2302 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# elfcopy.uu +# +echo x - elfcopy.uu +sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' +Xbegin 755 elfcopy +XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` +XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````$QR````````3'(````````` +XM`!````````$````&````8'(```````!@@```````*!Z4```````H'I0 +XM``````"@`0```````*`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````1'(```````!$```````````````.````&P```!$````B````'````!4` +XM```#````&````````````````````"T``````````````"<````J````.``` +XM`"\`````````0````"`````)```````````````P````0@```#P```!&```` +XM%P```#L````_````$``````````````````````````````````````````` +XM````2`(``!(```#L%D```````)````````````$``!(```#\%D```````(<` +XM````````+P```!(````,%T```````!0(``!(```#L%T```````(<& +XM````````I@```!(```#\%T```````#L`````````*0$``!(````,&$`````` +XM`!D!````````SP```!(````<&$```````"0`````````$P(``!(````L&$`` +XM`````(@`````````0`(``!$`%P#8?E````````@`````````<0(``!(````\ +XM&$```````$P`````````^@(``!(```!,&$```````"D`````````<0```!(` +XM``!<&$```````#4`````````#0```!(```!L&$```````&D!````````?``` +XM`!(```!\&$```````&H`````````E`(``!$`%P"P?E````````0````````` +XMH0(``!(```",&$```````*T"````````G@$``!(```"<&$```````!8````` +XM````5P(``!$`$`!@`!G96QF7V=E=&-L87-S`&=E;&9?9V5T`!G96QF7W5P9&%T95]R96QA`&5L9E]E;F0`9V5L9E]G971S +XM:&1R`&=E;&9?9V5T<&AD<@!E;&9?97)R;7-G`&=E;&9?9V5T'-C;@!G96QF7W5P9&%T95]E:&1R +XM`&=E;&9?=7!D871E7W!H9'(`96QF7VMI;F0`7TIV7U)E9VES=&5R0VQA0!?7W-T9&5R`!M86QL;V,`;W!T87)G`&=E='!R;V=N86UE`')E;F%M90!C86QL;V,` +XM96YV:7)O;@!F<')I;G1F`&]P=&EN9`!?7W!R;V=N86UE`&9E'U0```````' +XM````)```````````````@'U0```````'````)0``````````````B'U0```` +XM```'````)@``````````````D'U0```````'````)P``````````````F'U0 +XM```````'````*```````````````H'U0```````'````*0`````````````` +XMJ'U0```````'````*@``````````````L'U0```````'````*P`````````` +XM````N'U0```````'````+```````````````P'U0```````'````+0`````` +XM````````R'U0```````'````+@``````````````T'U0```````'````+P`` +XM````````````V'U0```````'````,```````````````X'U0```````'```` +XM,0``````````````Z'U0```````'````,@``````````````\'U0```````' +XM````-```````````````^'U0```````'````-0```````````````'Y0```` +XM```'````-@``````````````"'Y0```````'````-P``````````````$'Y0 +XM```````'````.```````````````&'Y0```````'````.0`````````````` +XM('Y0```````'````.@``````````````*'Y0```````'````.P`````````` +XM````,'Y0```````'````/```````````````.'Y0```````'````/0`````` +XM````````0'Y0```````'````/@``````````````2'Y0```````'````/P`` +XM````````````4'Y0```````'````0```````````````6'Y0```````'```` +XM00``````````````8'Y0```````'````0@``````````````:'Y0```````' +XM````1```````````````<'Y0```````'````1@``````````````>'Y0```` +XM```'````2```````````````@'Y0```````'````20``````````````B'Y0 +XM```````'````2@``````````````D'Y0```````'````2P`````````````` +XMF'Y0```````'````3```````````````H'Y0```````'````3@`````````` +XM````J'Y0```````'````3P``````````````2(/L".A?!0``Z#I2``!(@\0( +XMPP#_-8YE$`#_)9!E$`"0D)"0_R6.91``:`````#IX/____\EAF40`&@!```` +XMZ=#_____)7YE$`!H`@```.G`_____R5V91``:`,```#IL/____\E;F40`&@$ +XM````Z:#_____)69E$`!H!0```.F0_____R5>91``:`8```#I@/____\E5F40 +XM`&@'````Z7#_____)4YE$`!H"````.E@_____R5&91``:`D```#I4/____\E +XM/F40`&@*````Z4#_____)39E$`!H"P```.DP_____R4N91``:`P```#I(/__ +XM__\E)F40`&@-````Z1#_____)1YE$`!H#@```.D`_____R4691``:`\```#I +XM\/[___\E#F40`&@0````Z>#^____)09E$`!H$0```.G0_O___R7^9!``:!(` +XM``#IP/[___\E]F00`&@3````Z;#^____)>YD$`!H%````.F@_O___R7F9!`` +XM:!4```#ID/[___\EWF00`&@6````Z8#^____)=9D$`!H%P```.EP_O___R7. +XM9!``:!@```#I8/[___\EQF00`&@9````Z5#^____);YD$`!H&@```.E`_O__ +XM_R6V9!``:!L```#I,/[___\EKF00`&@<````Z2#^____):9D$`!H'0```.D0 +XM_O___R6>9!``:!X```#I`/[___\EEF00`&@?````Z?#]____)8YD$`!H(``` +XM`.G@_?___R6&9!``:"$```#IT/W___\E?F00`&@B````Z<#]____)79D$`!H +XM(P```.FP_?___R5N9!``:"0```#IH/W___\E9F00`&@E````Z9#]____)5YD +XM$`!H)@```.F`_?___R569!``:"<```#I9C$`!H-0```.F0_/___R7>8Q``:#8```#I@/S___\E +XMUF,0`&@W````Z7#\____)#[____)89C$`!H00```.G0^____R5^8Q`` +XM:$(```#IP/O___\E=F,0`&A#````Z;#[____)6YC$`!H1````.F@^____R5F +XM8Q``:$4```#ID/O__P````!!5$R-9PA54XL?2&/#A=M(C6S'$$B)+6UC$`!^ +XM.DB+5PA(A=)T,4B)%>-6$``/M@*$P'0C2(/"`3PO2(L%SU80`$@/1,)(B07$ +XM5A``#[8"2(/"`83`=>&XH'I0`$B%P'0K2(GWZ"/___^_.&E``.@9____Z`#[ +XM__^)WTB)ZDR)YNBK!P``B3&!;%B +XM$``!2(/$",-F9F:09F9FD$B#/2A@$```=!:X`````$B%P'0,OV!\4`!)B<-! +XM_^.0\\.0D)"0D)"0D)"0D)"0D$B#[`A(BPU=8A``OY%I0`"Z#0```+X!```` +XMZ&W]__^_0````.C3_?__9F9FD&9FD$B#[`A(BPTM8A``OX!L0`"Z,P```+X! +XM````Z#W]__^_0````.BC_?__9F9FD&9FD$B#[`A(BPW]81``OY]I0`"Z#P`` +XM`+X!````Z`W]__^_0````.AS_?__9F9FD&9FD$B);"383(E\)/A(B?U(B5PD +XMT$R)9"3@28G73(EL).A,B70D\$B![-@```!(A?9(B70D"`^$H`0``$B+?"0( +XM,?8QP.CE_/__@_C_08G'!```387_#X1)`P``,<"Z[0$``+X"`@``3(G_ +XM13'MZ+G\__^#^/]!B<0/A)\$```QTKX%````1(GWZ"[\__](A_H8"T``$B)[^BH&@``BT5H@_@"=!.#^`1T#DB#O=`````` +XM#X23`@``@V5LWXM--(7)#X4*`@``]D5L$`^%\P$``$B)[^AL'@``2(M]($B- +XM="00Z)KY__^%P`^$Y@(``$B)[^@.#0``2(GOZ,8.``!(BWT@2(UT)!#HE/?_ +XM_TB%P`^$H0(``$B)[^B7%0``2(GO2(G#Z$P4``!(BT,@2(E$)#B+52R%TGXF +XM2(M](+D!````N@$```"^!````.B@^/__2(7`2(E$)#`/A%<#``!(BWT@2(UT +XM)!#H%/G__X7`#X1@`@``BT4LA$`"Z'@`` +XM`+X!````O[AL0`#HL?G__TV%_P^$OP```$2)]^@`^?__1(GGZ/CX__](BYPD +XMJ````$B+K"2P````3(ND)+@```!,BZPDP````$R+M"3(````3(N\)-````!( +XM@<38````PX--;`'I)O[__[_4:4``Z(WV__](A_H/OG__X/X_T&)Q`^$,P(``+[M`0`` +XMB_H@_;__X/``0^$/`$``$R)[^BB^?__Z17___](B>_HJ2T``.D` +XM_O__2(GOZ&P.``#IZ?W__TB)Q^B;^?__2(UX#DF)Q.@/^?__2(7`2(G'#X0' +XM`@``28G%3(GB2(G>2(G'Z,+V__]+C40L_X`X+TB-4`%T"$B-4`+&0`$O2+YE +XM8W`N6%A86,=""%A86%C&0@P`2(DRZ1G___^#36P"Z07]__](@[W```````^% +XM7_W__^E>_?__OJ]I0`"_1@```#'`Z%+V__](BU0D"+[%:4``OTH````QP.B< +XM^/__O______HPO7__[XG:D``2(G"OT$````QP.@>]O__3(GZOL5I0`"_2@`` +XM`#'`Z&KX__^______^B0]?__OEEJ0`!(B<*_1@```#'`Z.SU__^______^AR +XM]?__OMIJ0`!(B<*_1@```#'`Z,[U__](BTPD"$R)ZKY":T``OTH````QP.@5 +XM^/__O______H._7__[XG:D``2(G"OT8````QP.B7]?__O______H'?7__[ZT +XM:D``2(G"OT8````QP.AY]?__O______H__3__[YS:D``2(G"OT8````QP.A; +XM]?__O______HX?3__[Z):D``2(G"OT8````QP.@]]?__O______HP_3__[X0 +XM:T``2(G"OT8````QP.@?]?__3(GJO@1J0`"_2@```#'`Z&OW__^______^B1 +XM]/__OOAJ0`!(B<*_1@```#'`Z.WT__^^]FE``+]&````,<#H//?__[[,:D`` +XMOT8```#H+??__[ZA:D``OT$````QP.B\]/__OMMI0`!`MT8QP.@-]___D$%7 +XM28GW059!B?Z_`0```$%505154TB![)@```#HB_7__X7`#X0?"```O_````#H +XMN?;__TB%P$F)Q`^$MP8``#'VNO````!(B$))``````````2<>$)*``````````2<>$)+``````````28F$))@` +XM``!)C80DH````$G'A"3``````````$G'A"30`````````$G'A"3@```````` +XM`$F)A"2H````28V$)+````!!QT0D#`````!!QT0D"`````!)B80DN````$F- +XMA"3`````28F$),@```!)C80DT````$F)A"38````28V$).````!)B80DZ``` +XM`.B6]O__0;A9:T``2(7`N08```!,#T7`N&%K0`#\2(G'38D$)$R)QO.F#Y?" +XM#Y+`13'M.,(/A!4$``"X=&M``+D$````3(G&_$B)Q_.F#X20`@``13'`N?H&2@``.GX_O__9F9FD$B+-<%8$`"Z +XM`0```$R)Y^@<$```1(M(-$6%R0^%100``,=`+`$```!!QT0D2`$```#IOO[_ +XM_TB+-8M8$`!,B>?H.R@``.FJ_O__0<=$)&@$````Z9S^__](BSUI6!``OCT` +XM``#H\_'__TB%P$F)Q0^$+`0``+\@````Z/WS__](ALK +XM'318$`"->P%(8__HW?/__TB%P$B)10`/A,L#``!(BS456!``2&/;2(G'2(G: +XM28/%`>B'\?__2(M%`$B-="003(GOQ@08`.CR\?__@\`!#X3/`P``2(M\)%A( +XMB7T0Z(OS__](A_HD?+__TB%P$B)PP^$K`,` +XM`$B+51!(BWT(2(G!O@$```#HW'1"0$`````,=$)`@````` +XM13'M,=NZAFM``$R)_D2)]^CJ\/__@_C_#X2'`0``@^A6@_@:=@?HV/3__^O8 +XMB&M``+Y^:T``,<#HPN[__S'_Z"OR__](B=_H@_'__X7`#X3^_O__ +XMOL!K0`"_00```#'`Z#KR__]!BWPD#(7_=%6+%6]6$`!!.=9T"(U"`D$YQGX+ +XMZ$WT__^+%5=6$`!(8\)(C0S%`````(U"`3'203G&28LT#W\73(GGZ%;T__], +XMB>?H*O+__S'_Z+/Q__]*BU0Y".OB08M$)`A!B40D#.N?@_AOD`^$@0(```^/ +XM^P$``(/X9)!T!8/X9W5/0<=$)&@"````13'`N8!R4`"Z9VM``$R)_D2)]^A$ +XM\/__@_C_#X1D`@``@_A3=-%_M(/X2V9FD&:0#X0)`@``#X_+`0``@_@"D`^$ +XM+0(``.@U\___9F:09I#KKD0[-9=5$``/A$@!``"+!"0+1"0$"T0D"`G8#X3Z +XM````BT0D!(7`=!I!QT0D1`$```#'!"0`````,=O'1"0(`````(L$)(M4)`A% +XMA>U!B5PD0$&)1"0X08E4)#P/A*(```!)BX0DH````$B%P'0DBSPDB7@DBU0D +XM"(E8,(E0*(M\)`1(B6@8B7@T2(M`0$B%P'7W__[[;:4``OT8```#H%O#__[[;:4``OT8````QP.@%\/__Z`3R +XM___IKO[__[X@;4``OT`````QP.B*[?__OJ)K0`"_00```#'`Z-GO__],B>J^ +XML&M``+]!````,<#HQ>___X/X<`^$$/[__X/X#^%*0#X4P_O__2(LUNU,0`+H!````3(GGZ!8+``#'0#0!```` +XM0<=$)$0!````Z<']__](BS624Q``3(GGZ$(C``#IK?W__TB+-7Y3$`!,B>?H +XMOB(``.F9_?__3(LM:E,0`.F-_?__0<=$)&@$````9F9FD.E[_?__08M$)&B% +XMP'4)0<=$)&@!````08M$)`R%P'4*08M$)`A!B40D#$0[-3]3$`!T5HLM-U,0 +XM`$$Y[@^.^/S__TACQ4F-',=(BS-,B>I,B>>#Q0%(@\,(Z#+Q__]$.?5UYNG2 +XM_/__O_____]F9I#HY^O__[[8;$``2(G"OT8````QP.A#[/__Z'+P___KHTB+ +XME^````!(A=)T'TB+1B!(.T(@U(QT98 +XM`````$B+A^@```!(B49@2(N'Z````$B),$B-1EA(B8?H````BT9,AO__TB%P`^$"@$``$C' +XM1"00`````$C'1"0P`0```$B+12#'1"0$`P```$C'1"0(`````$C'1"0X```` +XM`,=$)"P`````QT0D*`````!(B40D&$B+?1#HBNK__TB%P$B)PP^$S@```$'V +XM1"1L$`^$A@```$B+12A(B>9(B40D($B+?1#H_>W__X7`#X3#````2,<#`0`` +XM`$B+11A(B4,(2(M%*$C'0Q``````QT,@`0```,=#)`$```!(B4,82(M]$.BO +XM[?__28M\)"!(B<;HDNG__X7`#X26````2(M<)$A(BVPD4$R+9"183(ML)&!( +XM@\1HPV9FD&:02(M5*$B+?1A(@^H02(UW$$B)52CH@^S__^E<____O______H +XM!.K__[X@;D``2(G"OT8````QP.A@ZO__O______HYNG__[X^;D``2(G"OT8` +XM```QP.A"ZO__O______HR.G__[Y7;D``2(G"OT8````QP.@DZO__O______H +XMJNG__[YU;D``2(G"OT8````QP.@&ZO__9F9FD&9FD&9FD$%454B)_5-(@^Q` +XM2(N?X````$B%VW4OZ8(```!F9F:02(/X!'1@2(M[$$B)YF9FD.BW[/__A<`/ +XMA)$```!(BUM82(7;=%A(BWL02(GFZ(KI__](AC__[ZN;D``2(G"OT8````QP.CUZ/__9F:09F:09F:02(EL)/A(B5PD +XM\$B#[!A(BU]@2(GU2(-[&`!T&4B)[DB)WTB+;"002(M<)`A(@\08Z?LW``!( +XMB=^^GFE``.CN-P``2(G?OL5N0`#HX3<``$B)W[[-;D``Z-0W``"^U6Y``$B) +XMW^C'-P``Z[%F9I!FD$%6055)B?U!5%532(/L0$B+K^````!(A>UT(D&XU6Y` +XM`.L)2(MM6$B%[7012(MU`+D*````3(G'_/.F=>9)BYVP````2(7;#X3_```` +XM9F:028M](.CSZ?__2(7`28G$#X3T````OG@```"_`0```.A(Z?__2(7`2(G" +XM#X3W````2(L#3(GG2(D"2(M%($B)0B!(BT,0QT)(`````$C'0@@`````3(EB +XM$$B):EA(B4(H2(M%8$B)0F!(BT5@2(D02(U"6$B)16#H`.?__TB%P$B)P@^$ +XML````$C'``$```!(QT`0`````$B)YDB+0PA,B>=(B4((2(M#$,="(`$```#' +XM0B0!````2(E"&.A,Y___2(7`#X2-````QT0D!`$```!(BS-,B>_H9/[__TB) +XMYDR)Y^@UZO__A<`/A(4```!(BUL82(7;#X4$____2(/$0%M=05Q!74%>P[__ +XM____Z*GF__^^WVY``$B)PK]&````,<#H!>?__[[,:D``OT8````QP.A4Z?__ +XMO______H>N;__[X^;D``2(G"OT8````QP.C6YO__O______H7.;__[[W;D`` +XM2(G"OT8````QP.BXYO__O______H/N;__[Y7;D``2(G"OT8````QP.B:YO__ +XM9F9FD&9F9I!F9I!F9I!52(G]4TB#[`B+=U"%]G0'2(-_&`!T;#';ZTMF9I!F +XMD$B+?1#HL^7__TB%P$B)P@^$A@```(M-4(7)=4Y(BP-(B0)(BT,02(E"$$B+ +XM0PA(B4((BT,@B4(@2(M#&$B)0AB+0R2)0B1(BWT(2(G>Z"KE__](ARH````28G\2(GW2(UT)$!(BY,B>=( +XMB00D2(M$)$A(B40D"$B+1"102(E$)!!(BT0D6$B)1"082(M$)&!(B40D($B+ +XM1"1H2(E$)"A(BT0D<$B)1"0P2(M$)'A(B40D..CX^___2(GF2(G?Z,GG__^% +XMP'1D2(N<)(@```!(BZPDD````$R+I"28````3(NL)*````!(@<2H````P[__ +XM____Z#/D__^^+F]``$B)PK]&````,<#HC^3__[______Z!7D__^^3&]``$B) +XMPK]&````,<#H<>3__[______Z/?C__^^:F]``$B)PK]&````,<#H4^3__V9F +XM9I!F9I!!54%455-(@^Q(2(N?X````$B%VP^$M````$4QY.F2````2(MK($PY +XMY0^"L0```$2+2TA%AR"+>TR%_W5?2(M#0$B#^`AT#4B%P'0(2(MK($@#:RA(BWL02(GFZ*OC__]( +XMA$B+0R!(B>9(B40D&$B+0RA(B40D($B+>Q#HF.;__X7`='1(BUM82(7; +XM=!U)B>Q-A>0/A67___](BVL@2`-K*$B+6UA(A=MUXTB#Q$A;74%<05W#9F9F +XMD&9FD$2+0TA%A<`/A$O___^_P'!``#'`Z-/C___I.O___[______Z-3B__^^ +XMA6]``$B)PK]&````,<#H,./__[______Z+;B__^^:F]``$B)PK]&````,<#H +XM$N/__V9FD&9FD%5(B?U32(/L2$B+?QA(B>;HU^'__TB%P`^$E````+YX```` +XMOP$```#H'^3__TB%P$B)PP^$M0```$B+1"0HN@$```!(B4,@2(N-X````$B% +XMR708,<"#>4P!2(M)6(/0`$B%R77P@\`!2&/02(M](+D!````O@X```#HON+_ +XM_TB%P$B)0RAT24B)WDB)[TC'0S@$````QT-(`````,=#3`$```#H*/;__TB) +XMV$B#Q$A;7<.______^C@X?__OEEJ0`!(B<*_1@```#'`Z#SB__^______^C" +XMX?__OOAJ0`!(B<*_1@```#'`Z![B__^^S&I``+]&````,<#H#>+__Y!!54&) +XMU4%428G\54B)]5-(@^P(2(N?H````$B%VW4+ZR9(BUM`2(7;=!U(BS-(B>_H +XMQ^+__X7`=>A(@\0(2(G86UU!7$%=PS';187M=.N_2````.CTX___2(7`=#9( +XMB<.Z2````#'V2(G'Z#WB__](B2M(QT-``````$F+A"2H````2(D82(U#0$F) +XMA"2H````ZZ:^HV]``+]&````Z&KA__]F9F:09F9FD&9FD&9FD#'22(/L".A% +XM____,=)(A[SIG3CN[5O +XM0`!)B>1(QP0DM6]``$C'1"0(O&]``$C'1"00SF]``$C'1"08U&]``$C'1"0@ +XM`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G?Z.;B__](B=Y(B<)(B>_H2-__ +XM_X7`==A!BT5H@^@!@_@!=PJX`0```.E!____08M%1(7`=0Q!BT5(A<`/A"O_ +XM__\QTDB)[DR)[^C1_?__18ME1$6%Y'4C08M=2(7;#X0)____2(7`=+M$BU@L +XM187;#Y3`#[;`Z?3^__](A_H..+__T@YPW7>2(GF2(GOZ"C?__](A<`/A)H```"+%"1(BW0D +XM2$F+?"08Z&W?__](A__^%P`^$:P(``$4Q]DB+?1A,B?;HS-W_ +XM_TB%P$F)Q@^$K`$``$B)YDR)]^C%W?__2(7`#X33`0``BQ0D2(MT)$A(BWT8 +XMZ`O>__](A_HR/S__X7`=:B+1"0$@_@)#X3+```` +XM@_@$#X3"````0;_5;D``N0H```!,B>;\3(G_\Z8/A;S +XMIG4$2(E=6$B)WDB)[^BA\/__Z=#^__^+="0LA?8/A#+___](B>_H*/W__X7` +XM#X6T_O__Z1W___^^>````+\!````D.CGW?__2(7`#X3O````2(G#3(D@3(EP +XM"$B+1"082(G>2(GO2(E#($B+1"0@2(E#*$B+1"0P2(E#.(M$)`1(B4-`Z,H- +XM``")0TCIZ_[__V:02(M3$$B+](BPOHO?;__^DL____Z(_>__^%P)`/ +XMA;0```!(@\186UU!7$%=05Y!7\.______^BMV___OCUP0`!(B<*_1@```#'` +XMZ`G<__^______^B/V___O@MP0`!(B<*_1@```#'`Z.O;__^______^AQV___ +XMOO5O0`!(B<*_1@```#'`Z,W;__^______^A3V___OB=P0`!(B<*_1@```#'` +XMZ*_;__^^S&I``+]&````Z`#>__^______^@FV___OMIO0`!(B<*_1@```#'` +XMZ(+;__^)Q^@+V___OJYN0`!(B<*_1@```#'`Z&?;__]F9F:09F9FD&9FD%5( +XMC2PW4TB#[`A(.>]S>TB)^^LXBP7&01``AM(B09U +XMPDB#Q`A;7<-(BS5801``OPH```#HVMG__^N?2(LU14$0``^^^NC)V?__ZXX[ +XM1BA\"(#Z"F9FD'6RZ*7<___I=____[\*````Z);<___I:/___V9FD&:005=! +XM5D%505154TB![-@```!(B7PD&$R+M^````!-A?8/A/\```!(C80DH````$B- +XME"3`````2(D$)$B)5"0(ZPU-BW98387V#X37````08M63(72=>M)BQZ_Q6Y` +XM`+D(````_$B)WO.F=-:_S6Y``+D(````2(G>\Z9TQ;_5;D``N0H```!(B=[S +XMIG2T2(M,)!B#>6@!#X2;````2(M\)!A(B=[HI_C__X7`#X1P`P``,=M%,?]( +XMQT0D6`````#K.4B+?"182`-[&.CMV___28G'387_#X3\`P``2(M$)%A(BU,8 +XM2(MS"$F-/`?H"]S__TB+4QA(`50D6$F+?@A(B=[HAMC__TB%P$B)PP^$C@`` +XM`$V%_W6J2(M[&.BO^__],B??H#?'__TB+5"08BT)L@^`P@_@0=1M)BT9`2(/X"70&2(/X +XM!'4+28-^*``/A?`!``!)BS9(BWPD&#'2Z%/U__](A<`/A!O]__^+0#"%P`^$ +XM$/W__TF+?AA(A?]T#4F+=BA(A?8/A?0````QV^L-2(MS&$B+>PCHR/O__TF+ +XM?@A(B=[H*-;__TB%P$B)PW7?Z%O9__^%P`^%$08``(L%@3T0`(7`#X5A`0`` +XM2(LU@CT0`(M&#(/H`87`B48,#XCZ/+T__^%P`^$I?[__^EV_/__ +XM9F:09I#HV_K__^DO____28LV2(M\)!@QTN@7]/__3(M@&$R)Y^C7V/__2(M\ +XM)%!(`WPD6$B)PDR)YDB)P^@/UO__2`-<)%A(BTPD4,8$"P!(@\,!2(E<)%CI +XMD)_?__OFIP0`"_1@```#'`Z/37__](BS4A/!`` +XMOPH```#HH]3__^E#^___28M^$$B-="1@Z%#5__](A<`/A&$%``!(BTPD&(N< +XM)(@```!(BT%02(MX".@NV/__2#G##X77_?__28M^$#'VZ$K4__](AT))@```!(A`@2`'02(GRB=Y(B80DJ````.B"U___A,/A#/]__])@WY`"76.2(V4),````")WDB)[^B8U___2#M$)`A(B<8/ +XMA9($``!(BWPD&$B+E"3(````2(M'>$B)T8/B_TC!Z2!(B>](BP3(2,'@($@! +XMT$B)\HG>2(F$),@```#HW]/__X7`=8V______^C!T___OIQP0`!(B<*_1@`` +XM`#'`Z!W4__^028L>0<=&4`$```!)QT8H`````.DD^O__2(M4)!B+G"2(```` +XM2(M"4$B+>`CHR];__T@YPP^%]_K__TF+?@@Q]NCGTO__2(7`2(E$)"`/A+D# +XM```QTDB+A"2`````2/>T))@```!(A`CH(];_ +XM_TB)QDB+1"082(G:2(MX&.AOT___2(7`2(GU`@``2(M\)!CHG0@``(7` +XM=&)(BU0D&(-Z%`$/A*L```!)@WY`"0^$"0$``$V%Y`^$C`$``$DY[&9FD`^# +XM60$``$B+?"0H2XT$9$B-%,=(BX0DH````$B)`DB+A"2H````2(E""$F#?D`$ +XM#X3@`0``28/$`4F#Q0%,.VPD$`^$.P,``$F#?D`)#X4>____2(M\)"!(C90D +XMP````$2)[NB4U?__2#M$)`@/A!W___^______^C_T?__OE-P0`!(B<*_1@`` +XM`#'`Z%O2__])@WY`"0^$T@$``$V%Y`^$J0$``$DY[`^#>`$``$B+?"0P2XT$ +XM9$B-%(=(BX0DH````(D"2(N$)*@```")0@1)@WY`!`^%6O___TB+A"2P```` +XMB4((Z4K___^_"@```.@'U/__Z;?W__]-A>1F9I`/A,8```!).>QF9F:09F:0 +XM#X./````3(G@2(N4),````!(P>`$2`-$)#A(B1!(BY0DR````$B)4`A)@WY` +XM!`^%\?[__TB+A"2P````2(M,)"A+C11D2(E$T1#IUO[__T@![4B+?"0H2(GN +XM2,'F!.@YT?__2(7`#X3$`0``2(E$)"CI@/[__TB)[TC!YP3HFM/__TB%P`^$ +XMM@$``$B)1"0HZ57^__](`>U(BWPD.$B)[DC!Y@3H\]#__TB%P`^$?@$``$B) +XM1"0XZ4K___](B>](P><$Z%33__](A<`/A'`!``!(B40D..D;____OMMI0`"_ +XM1@```.A2T___B]#__[X5;T``2(G"OT8````QP.C7T/__2(N$)+````!( +XMB4(0Z0_^__](`>U(BWPD,$B--.T`````Z''0__](A<`/A/P```!(B40D,.E@ +XM_O__2(T\[0````#HT=+__TB%P`^$[0```$B)1"0PZ3?^__]-A>0/A)H!``!) +XM.>P/@VT!``!(BY0DP````$N-!.>)$$B+E"3(````B5`$28-^0`0/A9']__]( +XMBX0DL````$B+3"0P2XT49(E$D0CI=_W__[______Z+3/__^^]6]``$B)PK]& +XM````,<#H$-#__[______Z1;___^______^B,S___OEEJ0`!(B<*_1@```#'` +XMZ.C/__^______^ANS___OH-P0`!(B<*_1@```#'`Z,K/__^______^A0S___ +XMOCYN0`!(B<*_1@```#'`Z*S/__^^='!``+]&````,<#H^]'__[[;:4``OT8` +XM```QP.CJT?__13'_2,=$)#@`````2,=$)#``````2,=$)"@`````13'DZ+31 +XM__^%P(G'#X5J_O__2(M$)!B#>!0!#X2.````28-^0`E(BU0D.$@/150D*$F) +XM5AA(BTPD&#'V28-^0`E,B>)(BWD@N0$```!`#Y7&@\8,Z$//__])BQY)B48H +XM0<=&4`$```#I'_7__T@![4R)_TB--.T`````Z*S.__](A<`/A#?___])BL.08/$`40Y +XM92@/CI4```!(BWT83(GR1(GFZ`G.__],.?`/A8H```!(BWT@2(GB1(GFZ/'- +XM__],.>AU=HM$)$!(B>)$B>:)!"1(BT0D4$B)1"002(M$)%A(B40D&(M$)$2) +XM1"0$2(M$)'!(B40D,$B+1"1(2(E$)`A(BT,(2(E$)"!(BT,02(E$)"A(BWT@ +XMZ(3.__^%P'0X2(M;.$B%VP^%7?___TB#[(!;74%<05U!7L.______^C,R___ +XMO@=Q0`!(B<*_1@```#'`Z"C,__^______^BNR___OA]Q0`!(B<*_1@```#'` +XMZ&K.__^______^B0R___ONUP0`!(B<*_1@```#'`Z.S+__^______^ARR___ +XMOA!K0`!(B<*_1@```#'`Z,[+__]FD$%455-(B?M(@^Q`2(M_&$B-="0XZ#/+ +XM__^%P`^$Y@```$B+1"0X2(7`B4,HB4,L#X2:````,>U)B>1F9I!F9I!(BWL8 +XM2(GBB>[HKLS__TPYX`^%@0```+Y`````OP$```#HILS__TB%P$B)P@^$A``` +XM`$B+1"0(2(/%`4B)`DB+1"0@2(E""$B+1"0H2(E"$(L$)$C'0B@`````2,=" +XM.`````!(B4(82(U"*$B)0C!(BX.8````2(D02#EL)#A(C4(X2(F#F`````^' +XMPH`@``2(M'4$B)1"0P2(M76$B)5"0X2(M0$$B+<`CHB./__TB+ +XM3"0X3(GO2(M1$$B+<0BYS6Y``.ANX___2(M<)#!(C;0D@`$``$B+>Q#HQ,C_ +XM_TB%P`^$KQ(``$B+1"0X2(VT)$`!``!(BW@0Z*7(__](A<`/A)`2``!!]D5L +XM(`^%R@4``$F+?1A(C;0D&`(``.CPR/__A<`/A"06``!)BWT@Z"_*__^%P(E$ +XM)$0/A-$5``"^`0```+\P````Z+3)__](ARO__ +XM2(7`#X32%0``2(E$)$C&``"^`0```$&+?3"#QP>-1P>%_P](^,'_`TAC_^AN +XMR?__2(7`28F%B`````^$714``$R-I"0``0``,=LQ[69FD&9FD$F+?1A(B=[H +XMT,?__TB%P$B)PP^$.0X``$R)YDB)W^C)Q___3#G@#X6W#@``BY0D``$``$B+ +XMM"08`@``28M]&.@(R/__2(7`2(G%#X1U#@``_+_-;D``N0@```!(B<;SIG6> +XM2(G?Z(+*__](B40D8.CHR?__A<`/A;04``!(@WPD8``/A(`4``!,C:0D``$` +XM`#';28M]&$B)WN@^Q___2(7`2(G#=$Y,B>9(B=_H.\?__TPYX`^%*0X``(N4 +XM)``!``!(B[0D&`(``$F+?1CH>L?__TB%P$B)Q0^$YPT``$&_Q6Y``+D(```` +XM2(G&_$R)__.F=9[H8\G__X7`#X4O%```2(7;#X3^$P``,=)(BX0D(`$``$CW +XMM"0X`0``2(7`2(E$)"@/A:\%``!(QT0D<`````!(QX0DN````$````!(QT0D +XM4`$```!)BYW@````2(7;#X2Q`0``0;_%;D``ZPU(BUM82(7;#X2<`0``3(L# +XMN0@```!,B?_\3(G&\Z9TX+_-;D``N0@```!,B<;SIG3/O]5N0`"Y"@```$R) +XMQO.F=+Y!]D5L!'002(M#0$B#^`ETK4B#^`1TITB+>Q#H*LG__TF+E8@```!( +XMB<%(P>D##[84"HG!@^$'T^J#X@%U@,>$).`!````````2,>$).@!```````` +XM2,>$)/`!````````QH0DY`$```-(BWL(Z-C(__^#?"1$`6:)A"3F`0``#X2Q +XM#0``28M6$$B%T@^$JA(``$B+C"2X````23M.*`^&"@\``(N$).`!``"%P`^% +XM`PT``$F+1BA(C01`QP3"`````$F+1B@/MI0DY`$``$F+3A!(C01`B%3!!$F+ +XM1B@/MI0DY0$``$F+3A!(C01`B%3!!4F+1BA)BTX02(N4).@!``!(C01`2(E4 +XMP0A)BT8H28M.$$B+E"3P`0``2(T$0$B)5,$0#[>,).8!``"-0?]F/?[^#X=G +XM#```28M%<$F+5B@/M\E)BW802(L$R$B-%%)FB436!DF#1B@!2(M;6$B%VP^% +XM9/[__TB#?"1P`'152(-\)"@`=$,QTC'VZP202(GRB?!(BUPD<(GQP?@#@^$' +XM2)@/M@08T^BH`7032(T$U0````!)`T5X28M6*$@!$$B#Q@%(.W0D*'7$2(M\ +XM)'#H1L?__S'`@WPD1`%)BU8@28M-4`^5P$D#5BA(C03%$````$@/K\)(B4$H +XM28M%4$R)R@`#X6]`@``2(-[(``/A4L"``!(BTPD.$B+>1#H@$))`!````````,$)(0!```"````2,>$ +XM)(@!````````2(F$)*`!``!)BWT@Z+7#__](BTPD,$B)A"2X`0``2(G>2(MY +XM$.A,P___2#G8#X4Z"@``3(V\),`!```QVT4Q]DB+1"0P2(G>2(MX$.A5PO__ +XM2(7`2(G#='PQTDB+0QA(][0D^````$B%P$B)Q73113'D0;T!````3(GZ1(GF +XM2(G?Z/##__],.?@/A?D,```/MH0DQ`$``,#H!(3`10]$]4F#Q`%)@\4!23GL +XM=)/KR4B+?"0PZ%'<__](BWPD..A'W/__2('$*`(``%M=05Q!74%>05_#Z`S% +XM__^%P`^%Z!```$B+5"0X1(FT)*P!``!(C;0D@`$``$C'A"10`0```````$C' +XMA"1P`0```0```$B+3"0P2(M"*,>$)$0!```#````2,>$)$@!````````2,>$ +XM)'@!````````QX0D;`$```````#'A"1H`0```````$B)A"1@`0``2(MY$.@D +XMQ?__A`#2(E"$$B+0QA(B4(( +XM2(M#(,="(!(```#'0B0!````2(T$0$C!X`-(B4(8Z4[]__](BW@0Z-3`__]( +XMAG\__](BWPD*+X(```` +XMZ&3"__](AH#2(G72(F4)(`` +XM``#H-<+__TB%P$B)1"1X#X0F#@``2(M,)'@Q]DB)WTB)3"1PZ..___](A$)+@```!`````2,=$)%`!````0;\``@``2,>$)*@````````` +XM2,>$)+``````````2(E<)!A(B40D$$B)%"1(B4PD"(N$)+````!(BWPD:$B- +XME"3@`0``B<:)A"2D````Z!3!__](.T0D&`^%&PH``(N4).`!``!)BWT82(MT +XM)&#H5,#__TB%P$B)Q0^$P08``$B)QDR)[^B!]?__A<`/A><```!)BYW````` +XM2(7;=0OK24B+6PA(A=MT0$B+,TB)[^C#P/__A&X`0```-/@"`0:28M5>$F+1B!(BXPDJ````$B)!,J#?"1$`0^$ +XMR@$``$B-O"3@`0``Z!;T__^%P`^$E`(``$F+5A!(A=(/A)4'``!(BX0DN``` +XM`$D[1B@/A@<%``"+O"3@`0``A?\/A(X#``"`?0``#X2$`P``28M&*(M,)%!( +XMC01`B0S"28M&*`^VE"3D`0``28M.$$B-!$"(5,$$28M&*`^VE"3E`0``28M. +XM$$B-!$"(5,$%28M&*$F+3A!(BY0DZ`$``$B-!$!(B53!"$F+1BA)BTX02(N4 +XM)/`!``!(C01`2(E4P1`/MXPDY@$``(U!_V8]_OX/AC,#``!)BT8H28M6$$B- +XM!$!FB4S"!DF#1B@!#[:$).0!``"#X`^#^`,/A)$"``"`?0``#X39_?__ZQY( +XMBWPD2$T!_TR)_NA6O?__2(7`#X0(!```2(E$)$A(B>_H0,#__TB+5"102(G! +XM2`'"28U'_T@YPG/&2(M<)$A(`UPD4$B)RDB)[DB)W^ADO?__2(GOZ`S`__]( +XMB>_&!`,`Z`#`__](BUPD4$B-7`,!2(E<)%#I7?W__TB-O"3@`0``Z(/R__^% +XMP`^%-_[__P^VA"3D`0``P.@$/`(/A`$B%0(#$F+1B@/MI0DY0$` +XM`$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4"`1)BT8H28L.2(N4 +XM)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&,0,``$F+1BA)BQ9(P>`$ +XM9HE,$`[I._[__TF+5AA(A=(/A*(%``!(BT0D6$D[1B`/ACT"``"+M"3@`0`` +XMA?8/A.D```"`?0``#X3?````28M&((M,)%!(C01`B0S"28M&(`^VE"3D`0`` +XM28M.&$B-!$"(5,$$28M&(`^VE"3E`0``28M.&$B-!$"(5,$%28M&($F+3AA( +XMBY0DZ`$``$B-!$!(B53!"$F+1B!)BTX82(N4)/`!``!(C01`2(E4P1`/MXPD +XMY@$``(U!_V8]_OX/AH$```!)BT8@28M6&$B-!$!FB4S"!DF#1B`!#[:$).0! +XM``"#X`^#^`,/A6_]__\/MY0DY@$``$F+17!(BPS0N`$```!(BH# +XM20.5B````-/@"`+I0/W__TF+1B!(C01`QP3"`````.D<____28M&*$B-!$#' +XM!,(`````Z7?\__])BT5P28M6(`^WR4F+=AA(BP3(2(T44F:)1-8&Z6____]) +XMBT5P28M6*`^WR4F+=A!(BP3(2(T44F:)1-8&Z;W\__])BU8(2(72#X2_!@`` +XM2(M<)%A).UX@#X8R`P``1(N$).`!``!%A8# +XMZ%6Y__](A8#Z!FY__](A($9HE$,@[I__K__TF+1BA)BU802(T$0&:)3,(& +XMZ9_S__^`?0``#X3S\O__28M&*(M,)%!(C01`B0S"Z>[R__])BT8@BTPD4$C! +XMX`2)#!#I//[__TF+1BB+3"102,'@!(D,$.GB^___2,<`!````$B+0RA(P>`$ +XM2(E"$$B+0PA(B4((2(M#(,="(!(```#'0B0!````2,'@!$B)0ACI]?/__TF+ +XM%DB%T@^$,08``$B+C"2X````23M.*`^&?00``(N,).`!``"%R0^$^P```(!] +XM```/A/$```!)BT8HBTPD4$C!X`2)#!!)BT8H#[:4).0!``!)BPY(P>`$B%0( +XM#$F+1B@/MI0DY0$``$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4 +XM"`1)BT8H28L.2(N4)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&C0$` +XM`$F+1BA)BQ9(P>`$9HE,$`[I4_+__T@!P$B)UTB)QDB)A"2X````2,'F!.@. +XMM___2(7`2(G"28D-^O__Z;7]__](`=M(B==(B=Y(B5PD6$C!Y@3HX[;_ +XM_TB%P$B)PDF)1@@/A:?\___IB?W__V:028M&*$C!X`3'!!``````Z0K___]( +XMBYPDN````$B-/%M(P><#Z".Y__](A8#Z&&V__](A($9HE$,@[IN_#__TB+O"2`````O@$```#H_K;__TB% +XMP$F)A8`````/A.T"``!)BWT82(VT)!`"``#H[;7__X7`#X0A`P``13'D28M] +XM&$R)YNA6M?__2(7`28G$#X2'`@``2(VT),````!,B>?H2K7__T@[1"00#X4V +XM_/__BX0DQ````(/X"70%@_@$=;R+E"3`````2(NT)!`"``!)BWT8Z':U__]( +XMA_H-M3__X7`=8R+M"3L````3(GOZ'/5__^%P`^%=?__ +XM_TF+15"+G"3H````2(MX".C3M___2#G#2,>$))``````````2,>$))@````` +XM````#X5`____2(N,))````!(.XPDX`````^#KP(``$B+M"28````3(GGZ+RS +XM__](AT)/@```"%P$B) +XMPWZLQX0DC`````````"#O"3$````"0^$H`(``(NT)(P```!(B[PDF````$B- +XME"3``0``Z+FU__](.P0D#X6Q`@``BX0DS`$``$B)A"20````2(.\))`````` +XM#Y7`="-(BU0D*$@YE"20````#X+7`0``A,!T#+_,<4``,<#H?[3__X.$)(P` +XM```!.9PDC`````^$&/___^ER____2(N\)+@```!(P><$Z!2V__](A;Y___HMK7__X7`B<=(QX0DN````$````!(QT0D4`$````/A(/L___H +XMTK+__[Z'<4``2(G"OT8````QP.@NL___2(N$)+@```!(C3Q`2,'G`^A9M?__ +XM2(7`2(G"28E&$`^%0^W__^DQ_/__OFQQ0`"_00```#'`Z/.R___H/K7__X7` +XMB<=U#DF+E8````#I=//__XG'Z&6R__^^KFY``$B)PK]&````,<#HP;+__[[, +XM:D``OT8```#H$K7__[______Z#BR__^^4W%``$B)PK]&````,<#HE++__[[, +XM:D``OT8````QP.CCM/__OMMI0`"_1@```.C4M/__O______H^K'__[[:;T`` +XM2(G"OT8````QP.A6LO__O______HW+'__[[A<4``2(G"OT8````QP.@XLO__ +XM2(N$))````"+C"20````N@$```!(P>@#20.%@````(/A!]/B"!#I#O[__^A8 +XMM/__A<")QP^$;/S__V:0Z;#^__](B[PDN````$C!YP3H)K3__TB%P$B)PDF) +XM!@^%P?G__^G_^O__9F:09F:0BQA) +XMB<5-B?Y,`W,H33GW_HQ;/__TDYQ4B)PW?F +XM3"GH2(LT)$R-)"A,B>?HVK'__X7`=<](@\0(1(G@6UU!7$%=05Y$*?A!7\-( +XM@\0(N/____];74%<05U!7D%?PY!!5T%6055)B?U!5%532(/L&$B)-"1(BV\H +XM2(7M28GN=29(QT2`,T).C3L/__A7!E +XM`&5L9E]G971S:&YU;2!F86EL960Z("5S`&-A;&QO8R!F86EL960`9V5L9E]U +XM<&1A=&5?96AD6UB;VP`;W5T +XM<'5T+69I;&4`<')E2!A;F0@6UT86(`+G-T"!I;F1E>`!E;&9?;F5W +XM9&%T82@I(&9A:6QE9#H@)7,N`"1&'`@ +XM)``!&___&`,0````````````````````````````GFE````````````````` +XM`%A\4`````````````````#::T````````````````````````````!H```` +XM`````-]K0````````0```````````````````$L`````````ZVM````````! +XM````````````````````;P````````#W:T`````````````````````````` +XM``!P``````````9L0````````0```````````````````%(`````````%6Q` +XM````````````````````````````E(` +XM`7@0`0,,!PB0`0``'````!P```!0&T``DP````!"#A",`D4.&$$.((,$A@,4 +XM````/````/`;0``X`````$0.$``````4````5````#`<0``B```````````` +XM```4````;````&`<0``I`````$0.$``````4````A````)`<0``I`````$0. +XM$``````4````G````,`<0``I`````$0.$``````D````M````/`<0`"/!@`` +XM`$J/`H8&80[@`8X#C02,!8,'````````-````-P```"`(T``<`@```!"#A"/ +XM`D4.&(X#2@X@0@XH00XP00XX1P[0`8,'A@:,!8T$```````4````%`$``/`K +XM0`!]```````````````<````+`$``'`L0`"V`0```$J#!8P#40YPC0*&!``` +XM`"0```!,`0``,"Y```!`!`PP'")`!```` +XM````%````"`````0:4``)0````!(#A"#`@```0`````````!``````````$` +XM````````Q@$````````,`````````,@60```````#0`````````X:4`````` +XM``0`````````^`%````````%`````````-`+0```````!@````````!0!$`` +XM``````H`````````#P,````````+`````````!@`````````%0`````````` +XM``````````,`````````:'Q0```````"`````````)`&````````%``````` +XM```'`````````!<`````````.!!````````'`````````,`/0```````"``` +XM``````!X``````````D`````````&`````````#^__]O`````(`/0``````` +XM____;P`````"`````````/#__V\`````X`Y````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````````````````````````````````#_________ +XM_P``````````__________\`````````````````````H'I0```````````` +XM````````````````\A9````````"%T```````!(70```````(A=````````R +XM%T```````$(70```````4A=```````!B%T```````'(70```````@A=````` +XM``"2%T```````*(70```````LA=```````#"%T```````-(70```````XA=` +XM``````#R%T````````(80```````$AA````````B&$```````#(80``````` +XM0AA```````!2&$```````&(80```````6YC7W-E8W1I;VYS`"(1``!I;G-E5]C;VYT96YT``````!! +XM`````@!^+@``W`D``'$(``!A9&1?=&]?:6YS96=?;&ES=`#W"```8V]P>5]P +XM:&1R`'P)``!S971U<%]P:&1R``````!C`````@!:.```!1,```L,``!L;V]K +XM=7!?:V5E<%]S>6UL:7-T`&8,``!A9&1?=&]?6`@```TP&```".8,````" +XM"`5=`P```X8"```".I4````""`>1`@```@@$AP,```($!*D#```#]00```)2 +XMB@````,\!0```E1X````!0@'!@@#?`$```,F9@````,5`P```R=X`````[0& +XM```#*68````#B0````,L9@````,T`P```RYF`````PT"```#,4(````#70<` +XM``,S0@````,(!0```S1X`````W`&```#/F8````#&@$```-;9@````(!!K(! +XM```#_`$```190@````-/`P``!%YF`````X@"```$8XH````'"#,!```'"&U````"7(&```$"`$=`0``"MT%```0 +XM!2X/`@``"X<'```%+\\!```"(P`+\`4```4P@P````(C"``*U@```'@&@PH# +XM```+V`0```:$*`$```(C``M-!P``!H68`0```B,$"V@&```&AJ,!```"(P@+ +XM@P0```:'K@$```(C"@N0`0``!HC:`0```B,,"V0"```&B8T!```"(Q`+O@$` +XM``:**`$```(C%`O9!0``!HSF`0```B,8"R`#```&C>8!```"(R@+8`4```:. +XMY@$```(C.`NK`@``!I>Y`0```B-("S8````&F')`P```B,`#%]R``AH +XM7P````(C"`Q?=P`(:5\````"(PP+?0H```AJ.P````(C$`NN!@``"&L[```` +XM`B,2#%]B9@`(;&`#```"(Q@+0P8```AM7P````(C*`M)`@``"'##`````B,P +XM"_,!```(<<,$```"(S@+L@0```ARXP0```(C0`O2!```"',#!0```B-("TD` +XM```(=",%```"(U`,7W5B``AW8`,```(C6`L`````"'@O!0```B-H#%]U<@`( +XM>5\````"(W`+1@0```A\-04```(C=`N;````"'U%!0```B-W#%]L8@`(@&`# +XM```"(W@++0````B#7P````,CB`$+=PD```B$50,```,CD`$`#0%?````PP0` +XM``[#``````<(LP0```T!7P```.,$```.PP````Y;`0``#E\`````!PC)!``` +XM#0%5`P```P4```[#````#E4#```.7P`````'".D$```-`5\````C!0``#L,` +XM```.80$```Y?``````<("04```_M`@```0<(*04``!`T````104``!'````` +XM`@`0-````%4%```1P````````Z8"```(A8\#```""`58`P``$#0```!W!0`` +XM$<`````/``/[`@``"290`0```Y0&```!%7$#```"%7$'```#%=L````$`!0$"C9=!P``%3$%````%9H'```! +XM%>8%```"%;$%```#%H````3%>$"```4%7P#```5%0X!```6%?X$```7`!0$ +XM"E6T'```+MPH```PB80$```(C``M>!```#"2M +XM!P```B,(``<(Q`<``!((##8*"```"U8%```,-K\(```"(P``"F8#``!(#"B_ +XM"```"[<*```,*6$!```"(P`+H@$```PJ80$```(C"`M!`@``#"MA`0```B,0 +XM"X4-```,+&$!```"(Q@,861D``PN7P````(C(`M;`0``#"]?`````B,D"\D' +XM```,,%\````"(R@+404```PQ7P````(C+`O9`0``##)?`````B,P"V\````, +XM,U\````"(S0+5P0```PT7P````(C.`NB!```##;S!P```B-```<("@@``!(( +XM##_<"```"U8%```,/R$)```"(P``"@<&```@##HA"0``"[<*```,.UL!```" +XM(P`+=`H```P\6P$```(C"`L`"```##W$`0```B,0"Z<````,/\4(```"(Q@` +XM!PC<"```$A`,44P)```+5P4```Q1&@H```(C``LX`@``#%$@"@```B,(``JD +XM"0``>`Q#&@H```NW"@``#$1A`0```B,`#&ES``Q%G`<```(C"`QO=`H```O7`@`` +XM#%X:"@```B,`"P0'```,7B`*```"(P@`$@@,7XL*```+5@4```Q?^@H```(C +XM```*NP(``$`,5OH*```,;V9F``Q74`$```(C``QF@`,65`!```"(Q`+W0@```Q:4`$```(C&`MO````#%Q?`````B,@"X@'```, +XM7DL*```"(R@+3@L```Q?=`H```(C.``'"(L*```4!`R-)PL``!5B`0```!40 +XM!0```14W!@```A7X!0```Q43!@``!``2$`RI3`L```O6`@``#*GZ"@```B,` +XM"P,'```,J4P+```"(P@`!PCZ"@``$A`,JG<+```+U@(```RJOP@```(C``L# +XM!P``#*IW"P```B,(``<(OP@``!(0#*NB"P``"]8"```,JR$)```"(P`+`P<` +XM``RKH@L```(C"``'""$)```2$`RMS0L```O6`@``#*WM!P```B,`"P,'```, +XMKU\````" +XM(RP,;F]S``Q]7P````(C,`LQ!```#()?`````B,T"T\!```,@U\````"(S@+ +XMO0<```R$7P````(C/`O-`0``#(5?`````B-`"V,````,AE\````"(T0+104` +XM``R'7P````(C2`O@#```#(D:"@```B-0"VH-```,BAH*```"(U@+Y@D```R+ +XM&@H```(C8`M^!@``#),`"P```B-H"WX*```,FU\````"(VP+KP<```R>Z@T` +XM``(C<`OS!@``#*'J#0```B-X"^T&```,I(D#```#(X`!"U0'```,IXD#```# +XM(X@!"S`!```,J2<+```#(Y`!"P<````,JE(+```#(Z`!"S8!```,JWT+```# +XM([`!"W@&```,K:@+```#(\`!"XP$```,K],+```#(]`!"X@'```,L?@+```# +XM(^`!``<(>P8```<(4`$``!8W!P``!`$L#PX``!7&`````!5V`````14/!@`` +XM`@`7>P<```%:`@%@'$```````(D<0````````````!<&`P```5,"`9`<0``` +XM````N1Q````````X````%[@````!3`(!P!Q```````#I'$```````'`````8 +XM/P<```$,`0$!F0X``!EE8W```0L!F0X``!EI9F0``0L!7P```!EO9F0``0L! +XM7P`````'"!T,```:&`````&(`0'D#@``&V5C<``!AYD.```J`8```$O`0'P +XM'$```````'\C0```````J````/D/```?96-P``$N`9D.``#A````'W-R8P`! +XM+@%A`0``*@$``!]D04```$R`<0!```A:69D``$S`5\```#&`P``(6]F9``!,P%?````(@0``"-F +XM#@````````%7`22,#@``)(`.```D=`X``".?#@``H`````$=`22L#@``)3`! +XM```FMPX``,H$```GP@X```.1\'XGS0X```.1L'XFV`X``$P%````````&%T& +XM```!%0(!`5H0```996-P``$4`ID.```H]@(```$4`E\````H$`,```$4`EH0 +XM```IA```"1N$```);`$```F +XMDA```+,+```FGA```.D+```FJA```$4,```MMA```"W"$```+BJ`````X0&```"+[H````)5@8``!`"1E,!```*(@4```)'4P$` +XM``(C``K_!P```DA?`````B,(``<(-`````FC`@``F`)F?0(```M?<``"9U,! +XM```"(P`+7W(``FA?`````B,("U]W``)I7P````(C#`I]"@```FH[`````B,0 +XM"JX&```":SL````"(Q(+7V)F``)L*@$```(C&`I#!@```FU?`````B,H"DD" +XM```"<+@````"(S`*\P$```)QC0(```(C.`JR!````G*M`@```B-`"M($```" +XM<\T"```"(T@*20````)T[0(```(C4`M?=6(``G/D" +XM```"(V@+7W5R``)Y7P````(C<`I&!````GS_`@```B-T"IL````"?0\#```" +XM(W<+7VQB``*`*@$```(C>`HM`````H-?`````R.(`0IW"0```H0?`0```R.0 +XM`0`,`5\```"-`@``#;@`````!PA]`@``#`%?````K0(```VX````#0,!```- +XM7P`````'"),"```,`1\!``#-`@``#;@````-'P$```U?``````<(LP(```P! +XM7P```.T"```-N`````T)`0``#5\`````!PC3`@``#NT"```!!PCS`@``#S0` +XM```/`P``$+4````"``\T````'P,``!"U```````#I@(```*%60$```((!5@# +XM```#C0H```8F[0````,%"```!BG,`````Q$(```&*NT````/-````&(#```0 +XMM0````\`$0@&>H<#```*Q0D```9[,0,```(C``KV"```!GQ'`P```B,$``-& +XM"0``!GUB`P``$0P&@,4#```*Q0D```:!,0,```(C``KV"```!H)'`P```B,$ +XM"D,*```&@SP#```"(P@``V0*```&A)(#```#^P(```$T`,```(C``KV"``` +XM!X4'!````B,(``.L"0``!X:*!0``$1@'B>T%```*Q0D```>*T`,```(C``KV +XM"```!XL'!````B,("D,*```'C/$#```"(Q```^\)```'C;H%```216QF``@F +XM`P8```ZV`P```0,&`0``""<4!@``#@4!```!$P0(-K,&```4,04````4F@<` +XM``$4Y@4```(4L04```,4S`,```04OP8```44C@<```843`0```<4D`4```@4 +XM4`````D4?`(```H4^@````L49P<```P4?@4```T4EP0```X4G`8```\4(0(` +XM`!`4(@$``!$4(@8``!(4Z@```!,4X0(``!04?`,``!44#@$``!84_@0``!<` +XM`^((```(3QH&```1"`AXU08```I6!0``"'A@!P```B,```G5"0``0`AH8`<` +XM``HT"@``"&SX`````B,`"E@)```(;;@````"(P@*$@H```AN^`````(C$`K^ +XM!P``"&_X`````B,8"ML(```(<+,&```"(R`*J@H```AQ<0````(C)`HY"``` +XM"'9F!P```B,H"GP*```(=W$````"(S`*(PD```AXO@8```(C.``'"-4&```' +XM"`D&```#U@D```AYU08```.,'```*MPH```HB"0$```(C``I>!```"B2C!P```B,(``<(N@<``!$("C8` +XM"```"E8%```*-K4(```"(P``"68#``!("BBU"```"K<*```**0D!```"(P`* +XMH@$```HJ"0$```(C"`I!`@``"BL)`0```B,0"H4-```*+`D!```"(Q@+861D +XM``HN7P````(C(`I;`0``"B]?`````B,D"LD'```*,%\````"(R@*404```HQ +XM7P````(C+`K9`0``"C)?`````B,P"F\````*,U\````"(S0*5P0```HT7P`` +XM``(C.`JB!```"C;I!P```B-```<(``@``!$("C_2"```"E8%```*/Q<)```" +XM(P``"0<&```@"CH7"0``"K<*```*.P,!```"(P`*=`H```H\`P$```(C"`H` +XM"```"CT4`0```B,0"J<````*/[L(```"(Q@`!PC2"```$1`*44()```*5P4` +XM``I1$`H```(C``HX`@``"E$6"@```B,(``FD"0``>`I#$`H```JW"@``"D0) +XM`0```B,`"VES``I%9@<```(C"`MO:@H```K7`@``"EX0"@```B,`"@0'```*7A8* +XM```"(P@`$0@*7X$*```*5@4```I?\`H```(C```)NP(``$`*5O`*```+;V9F +XM``I7^`````(C``MF@`*6?@````"(Q`*W0@```I: +XM^`````(C&`IO````"EQ?`````B,@"H@'```*7D$*```"(R@*3@L```I?:@H` +XM``(C.``'"($*```3!`J-'0L``!1B`0```!00!0```10W!@```A3X!0```Q03 +XM!@``!``1$`JI0@L```K6`@``"JGP"@```B,`"@,'```*J4(+```"(P@`!PCP +XM"@``$1`*JFT+```*U@(```JJM0@```(C``H#!P``"JIM"P```B,(``<(M0@` +XM`!$0"JN8"P``"M8"```*JQ<)```"(P`*`P<```JKF`L```(C"``'"!<)```1 +XM$`JMPPL```K6`@``"JWC!P```B,`"@,'```*K<,+```"(P@`!PCC!P``$1`* +XMK^X+```*U@(```JOXP<```(C``H#!P``"J_#"P```B,(`!$0"K$3#```"M<" +XM```*L1`*```"(P`*!`<```JQ%@H```(C"``)(P```/`*;MH-```*E0,```IO +XM"0$```(C``JA````"G)?`````B,("K8'```*U\````"(RP+;F]S``I]7P````(C,`HQ +XM!```"H)?`````B,T"D\!```*@U\````"(S@*O0<```J$7P````(C/`K-`0`` +XM"H5?`````B-`"F,````*AE\````"(T0*104```J'7P````(C2`K@#```"HD0 +XM"@```B-0"FH-```*BA`*```"(U@*Y@D```J+$`H```(C8`I^!@``"I/V"@`` +XM`B-H"GX*```*FU\````"(VP*KP<```J>X`T```(C<`KS!@``"J'@#0```B-X +XM"NT&```*I%,!```#(X`!"E0'```*IU,!```#(X@!"C`!```*J1T+```#(Y`! +XM"@<````*JD@+```#(Z`!"C8!```*JW,+```#([`!"G@&```*K9X+```#(\`! +XM"HP$```*K\D+```#(]`!"H@'```*L>X+```#(^`!``<(^`4```<(^````!73 +XM"@```>(!\"M```````!M+$````````)W"#H.```696-P``'A.@X```%5%G-E +XM8P`!X1`*```!5!=S``'C$`H```%1&/,*```![D,L0`````````<($PP``!D! +XMC`D```&C`P%P+$```````"8N0```````OA```*`.```:96-P``&B`SH.``#W +XM$```&W,``:0#$`H``$`1```<`0L```&E`Z`.``!V$0``'7-H``&F`X('```# +XMD9!_``<(;`<``!D!\@<```%[`P$P+D```````#WPD```%L`P%`+T```````*LO0```````_!(` +XM`%`S0```````&C5```````#4&```(A$``!IE +XM8W```4@".@X``%T9```; +XM$@``$+4````$``<("0$``"(!F`H```$W`5\```!`-T```````(DX0``````` +XMY!X``'X3```C96-P``$V.@X``!T?```DMPH```$V"0$``&8?```KD`4``$`3 +XM```ET```#O(```,;<*```!7PD!```X(0``%VES:``!8(('```#D9!_)6ES +XM``%A9@<``&XA```Q!0D```%B%`$``*0A```Q$0D```%C7P```-PA````,@&( +XM"````?D!L#E```````#%/$```````!(B``"S%```(V5C<``!^#H.``##(@`` +XM)7,``?H0"@``#",``#&W"@```?L)`0``52,``"5IL'```!__@```"3)```,3P* +XM```!__@```#<)```'!$)```!``%?````."4````SDP@```*'`0%?`````]P4 +XM```T7V,``H`(#`0``('-R8P`!>`(#`0``(&5N9``!>`(#`0``.3\( +XM```!>0)?`````#.?"0```=X"`;@````!:Q<``#1S``'=`A`*```[``@```'= +XM`FL7```@:60``=\"H`X``"!B``'@`@,!```@$"%`$``#D1"0```>(" +XM7P`````'"!0!```X7@D```$@`@$!V1<``#1E8W```1\".@X``#1S``$?`A`* +XM```@;W-H``$A`H('```@;"````;4!7P````$,&```.F5C +XM<``!M#H.```HMPH```&T"0$``"IS86,``;:U"````#B>"````X8```V:18```8J```M7A8````U=18``"`(```!E0&7 +XM&0``+8\6```M@Q8``#R`"```/9D6```\*@``/:46``!R*@``,+$6```PO18` +XM`#W'%@``#RL``##3%@``/=T6``#=*P``/><6``#1+```,/$6```O_18```.1 +XML'XP"1<``#<6%P``H`D```%[`BTR%P``+2@7```\X`D``#T^%P``Q2T``#!) +XM%P``,%,7```]7A<``),N````````-6T5``!`"@```9`!,AH``"V'%0``+7L5 +XM```\H`H``#V1%0``W"X``"^=%0```Y'0?B^I%0```Y&P?R^U%0```Y&0?SW! +XM%0``)2\``"_-%0```Y&H?B_9%0```Y&@?B_E%0```Y&8?B_Q%0```Y&0?CW\ +XM%0``NB\``#`(%@``/1(6```\,```/1X6``#1,```/2H6```M,0`````^V1<` +XM`+Y`0```````X4!````````!H@%T&@``+?47```MZA<``"[-0$```````.%` +XM0```````/0`8``!C,0`````W#!@``)`,```!HP$M&A@``#SP#```/208``"L +XM,0``/2\8```N,@``-[,4``!P#0```=D"-M`4``!W,@``+<44````````/SP) +XM```"BMP4```!`4#%!````J`!7P````$!`-@)```"`-X%```(`0T'```!)@L` +XM`.$#``"024```````(5-0```````$`@```(!!JL!```"`0BI`0```@(%NP4` +XM``("!]$&```#!`5I;G0`!$T#```".%L````"!`>6`@```@@%70,```2&`@`` +XM`CIT`````@@'D0(```((!(<#```"!`2I`P``!/4$```"4FD````%"`<&"`(! +XM!K(!```$3P,```->4`````2(`@```V-I````!PB9````!PC"````")D````$ +XM]P0```/HB0````3[`@``!":K````!-<#```$**L````$I@4```0KH`````0P +XM"0``!"VK````"3@$9W`L```1KT@````(C$`J("P``!&S2`````B,8"CP+ +XM```$;?,````"(R`*@`L```1N\P````(C*`I7"P``!&_S`````B,P``0Q"P`` +XM!'#^````"T5L9@`%)HT!```,M@,```$$!@$```4GG@$```P%`0```0T$!57C +XM`0``#A\$````#L\%```!#G8$```"#M\!```##IX#```$#@T````%#L4%```& +XM#LH"```'#BX"```(``<(DP$```1?"P``!B]W`0``!P@T`````@@%6`,```D( +XM!R08`@``"E8%```')$$"```"(P``#T,-```0!R%!`@``"K<*```'(KP````" +XM(P`*7@0```,!```" +XM(P@0;W,`!T;C`0```B,0$&)U9@`'1Y<````"(Q@0;V9F``=(JP````(C(!!S +XM>@`'2:L````"(R@08V%P``=*JP````(C,`HV"@``!TNK`````B,X"MT(```' +XM3*L````"(T`*WP0```=-20````(C2`JQ````!TY)`````B-,"JL$```'3TD` +XM```"(U`*W0H```=1>P,```(C6`HM`P``!U)Z!````B-H``<(H`,```<(;@0` +XM``D0!U*?!```"E<%```'4FX$```"(P`*.`(```=2=`0```(C"``/*`4``!`' +XM7L@$```*UP(```=>;@0```(C``H$!P``!UYT!````B,(``D(!U_?!```"E8% +XM```'7TX%```"(P``#[L"``!`!U9.!0``$&]F9@`'5ZL````"(P`09G-Z``=8 +XMJP````(C"!!MI3@4```(C``H#!P``!ZF@!0```B,(``<(3@4```D0!ZK+!0``"M8"```' +XMJA,#```"(P`*`P<```>JRP4```(C"``'"!,#```)$`>K]@4```K6`@``!ZMU +XM`P```B,`"@,'```'J_8%```"(P@`!PAU`P``"1`'K2$&```*U@(```>M00(` +XM``(C``H#!P``!ZTA!@```B,(``<(00(```D0!Z],!@``"M8"```'KT$"```" +XM(P`*`P<```>O(08```(C"``)$`>Q<08```K7`@``![%N!````B,`"@0'```' +XML70$```"(P@`#R,```#P!VXX"```"I4#```';[P````"(P`*H0````=R20`` +XM``(C"`JV!P``!W-)`````B,,$&EE8P`'=4D````"(Q`0;V5C``=V20````(C +XM%!!E:6X`!W#@(```"(R`*Q@$```=Z20````(C*`HJ +XM!```!WM)`````B,L$&YO"20````(C-`I/`0`` +XM!X-)`````B,X"KT'```'A$D````"(SP*S0$```>%20````(C0`IC````!X9) +XM`````B-$"D4%```'ATD````"(T@*X`P```>);@0```(C4`IJ#0``!XIN!``` +XM`B-8"N8)```'BVX$```"(V`*?@8```>35`4```(C:`I^"@``!YM)`````B-L +XM"J\'```'GCX(```"(W`*\P8```>A/@@```(C>`KM!@``!Z3T`0```R.``0I4 +XM!P``!Z?T`0```R.(`0HP`0``!ZE[!0```R.0`0H'````!ZJF!0```R.@`0HV +XM`0``!ZO1!0```R.P`0IX!@``!ZW\!0```R/``0J,!```!Z\G!@```R/0`0J( +XM!P``![%,!@```R/@`0`'"((!```'"*L````1$0L```%5`0%Q"```$G-E9P`! +XM5$X%```2=``! +XMA\<```#M-```'FD``8A)````$#4````@`08+```!9`%@3$```````(5-0``` +XM````634``!5E8W```6/Q"```SC4``!-S96<``65.!0``'Z`+```!9ND!```# +XMD:!_&,8!```!9\<````7-@``$VD``6A)```````!$P```@")!P``"`$-!P`` +XM`9L,``#A`P``D$U```````#:9D```````&4)```"`0:K`0```@$(J0$```(" +XM!;L%```#^@$```(V30````("!]$&```$!`5I;G0``TT#```".&8````"!`>6 +XM`@```TP&```".7@````""`5=`P```X8"```".HH````""`>1`@```@@$AP,` +XM``($!*D#```#]00```)2?P````4(!P8(`@$&L@$```-.!@```T]M`````_P! +XM```#64(````#3P,```->6P````.(`@```V-_````!PBO````!PCN````"*\` +XM```#]P0```/HGP````((!5@#```#C0H```0FS`````.\#```!"?!`````Q$( +XM```$*LP````)$`2W@P$```I+#0``!+@;`0```B,`"A4-```$N04!```"(P0* +XMJP(```2Z&P$```(C"`H-#0``!+LT`````B,,"O,,```$O#0````"(PT*_`P` +XM``2]$`$```(C#@`##@P```2^)@$```/[`@``!2;7`````YN@$```(C+`KF"@``!5_%`0```B,P"NL( +XM```%8,4!```"(S@``[P(```%8=`!```)$`6#E0(```K%"0``!82.`0```B,` +XM"O8(```%A<4!```"(P@``ZP)```%AG`"```)&`6)TP(```K%"0``!8J.`0`` +XM`B,`"O8(```%B\4!```"(P@*0PH```6,KP$```(C$``#[PD```6-H`(```D8 +XM!;X[`P``"DL-```%O[H!```"(P`*#0T```7`-`````(C!`KS#```!<$T```` +XM`B,%"OP,```%PID!```"(P8*%0T```7#C@$```(C"`JK`@``!<3%`0```B,0 +XM``,U#```!<7>`@``"T5L9@`&)E$#```,M@,```$#!@$```8G8@,```P%`0`` +XM`0T$!C8!!```#C$%````#IH'```!#N8%```"#K$%```##LP#```$#K\&```% +XM#HX'```&#DP$```'#I`%```(#E`````)#GP"```*#OH````+#F<'```,#GX% +XM```-#I<$```.#IP&```/#B$"```0#B(!```1#B(&```2#NH````3#N$"```4 +XM#GP#```5#@X!```6#OX$```7``/B"```!D]H`P``"0@&>",$```*5@4```9X +XMK@0```(C```/U0D``$`&:*X$```*-`H```9LUP````(C``I8"0``!FVM```` +XM`B,("A(*```&;M<````"(Q`*_@<```9OUP````(C&`K;"```!G`!!````B,@ +XM"JH*```&<68````"(R0*.0@```9VM`0```(C*`I\"@``!G=F`````B,P"B,) +XM```&>`P$```"(S@`!P@C!```!PA7`P```]8)```&>2,$```#6P@```@`(2=<````" +XM(R@08V%P``A*UP````(C,`HV"@``"$O7`````B,X"MT(```(3-<````"(T`* +XMWP0```A-5`````(C2`JQ````"$Y4`````B-,"JL$```(3U0````"(U`*W0H` +XM``A1:P8```(C6`HM`P``"%)J!P```B-H``<(D`8```<(7@<```D0"%*/!P`` +XM"E<%```(4EX'```"(P`*.`(```A29`<```(C"``/*`4``!`(7K@'```*UP(` +XM``A>7@<```(C``H$!P``"%YD!P```B,(``D("%_/!P``"E8%```(7SX(```" +XM(P``#[L"``!`"%8^"```$&]F9@`(5]<````"(P`09G-Z``A8UP````(C"!!M +XME0````"(R@**@0```A[5`````(C+!!N;W,`"'U4`````B,P"C$$```(@E0` +XM```"(S0*3P$```B#5`````(C.`J]!P``"(14`````B,\"LT!```(A50````" +XM(T`*8P````B&5`````(C1`I%!0``"(=4`````B-("N`,```(B5X'```"(U`* +XM:@T```B*7@<```(C6`KF"0``"(M>!P```B-@"GX&```(D[$(```"(V@*?@H` +XM``B;5`````(C;`JO!P``")Z;"P```B-P"O,&```(H9L+```"(W@*[08```BD +XMH0L```,C@`$*5`<```BGH0L```,CB`$*,`$```BIV`@```,CD`$*!P````BJ +XM`PD```,CH`$*-@$```BK+@D```,CL`$*>`8```BM60D```,CP`$*C`0```BO +XMA`D```,CT`$*B`<```BQJ0D```,CX`$`!PA&`P``!PC7````!P@T````$:\+ +XM```!00%4````D$U```````"@34````````)W"-8+```2E@#```&W,``>M>!P``'(,,```![``.```<[@P```'MH0L``!MI[% +XM!```&W-Y;0`![]`$```;:60``?`&#@``&VES``'QM`0``!SG"P```?+S```` +XM&VYD>``!\O,````<"`P```'R\P```!MS8P`!\O,````<\P8```'R\P```!P? +XM#````?/S````'`4-```!\_,````(````<9PP```'UX@```!ME8P`!]E0````<$0D```'V5````!MI``'V +XM5````!T_#````9L!``<(1`@```<(N@0``!X>#0```58!5`````%0#@``&F5C +XM<``!5&`,```:@` +XM````(&X,```!@`(!5`````&%#@``(65C<``!?P)@#```(K<*```!?P+H```` +XM&',``8$",04````94PT```%Z`0$5#P``&F5C<``!>6`,```:^@````;9``!?`8.```;B@P```',`50````!1`\``!IE8W````!5`````%?#P``&G,``=_6 +XM"P```![1"P```38!5`````%Z#P``&G,``376"P```"`G#````3H"`!])P`- +XM```@#@```>,!M!(``"@-#0``*<`.```J&`T``-0[```K(0T``"HL#0``R#P` +XM`"PW#0```Y&@?2Q"#0```Y&`?RI-#0``@#T``"I7#0``.#X``"IA#0``S3X` +XM`"IL#0``,3\``"MW#0``*X(-```JC`T``%0_```KEPT``"JB#0``S3\``"JM +XM#0``%$(``"JX#0``7T,``"K##0``GT0``"K.#0``-$4``"K9#0``F$4``"KC +XM#0``YT4``"KN#0``[D8``"WW#0``:%%````````N#`X``"`4```!<@$H1`X` +XM`"@[#@``*#(.```H*`X``"@=#@``+U`.```W6$```````%U80````````5O1 +XM$0``,&X.```11P``*&(.```Q-UA```````!.6$```````"IZ#@``1T<````` +XM,H4.``#P%````6=4$@``,)T.``#O1P``*)(.```ID!4``"JG#@``$D@``"JR +XM#@``6T@``"J[#@``*$D``"S$#@```Y&@?RS-#@```Y'@?BS7#@```Y'@?"KA +XM#@``T$D``"KJ#@``G4H``"KU#@``:DL``"H`#P``O4P``"L)#P`````R%0\` +XM`#`7```!:902```H.@\``#`Q#P``BDT``"@F#P``,T0/```56T```````"A; +XM0````````=@\``&`7```!)0(HC`\``"GP%P``+)8/```#D>!\+*(/```#D>!^*JX/ +XM``!_3@``*KD/```!3P``*\4/```JT`\``(-/```KW`\````````(`P```@`S +XM"@``"`$-!P```78-``#A`P``X&9````````/:4```````!(-```"`0:K`0`` +XM`@$(J0$```("!;L%```"`@?1!@```P0%:6YT``($!Y8"```""`5=`P``!(8" +XM```".FD````""`>1`@```@@$AP,```($!*D#```$]00```)27@````4(!P8( +XM`@$&L@$```3W!````S)^````!PB.````!PBL````"(X````""`58`P``!(@" +XM```$8UX````$!@$```4GS@````D%`0```0<(PP````H0!E'_````"U<%```& +XM4@`&2;@````"(R@-8V%P``9*N`````(C,`LV"@`` +XM!DNX`````B,X"]T(```&3+@````"(T`+WP0```9-20````(C2`NQ````!DY) +XM`````B-,"ZL$```&3TD````"(U`+W0H```91V@````(C6`LM`P``!E+9`0`` +XM`B-H``<(_P````<(S0$```H0!E+^`0``"U<%```&4LT!```"(P`+.`(```92 +XMTP$```(C"``.`7X-```!5P%)````X&9```````!O9T```````,Q/``"#`@`` +XM#W0``5;-`0``?5````]S``%6I@```-E0```08@`!6*8````040``$&,``5BF +XM````1E$``!!R``%8I@```'Q1```0;&5N``%9E0```+)1```1<0T```%9E0`` +XM`.A1````$@%@#0```2D!<&=````````/:4```````!Y2```/=``!*,T!``#/ +XM4@``#W,``2BF````*U,``!-R``$JI@```!!B``$KH````&-3```08P`!*Z`` +XM``"P4P``$&QE;@`!+)4```#Y4P``$7$-```!+)4````O5```$5L!```!+4D` +XM``!X5``````!$0$E#A,+`PX;#A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+ +XM.PM)$P``!"0`"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8` +XM21,```D6``,..@L[!4D3```*$P$##@L+.@L["P$3```+#0`##CH+.PM)$S@* +XM```,#0`#"#H+.PM)$S@*```-%0$G#$D3`1,```X%`$D3```/$P`##CP,```0 +XM`0%)$P$3```1(0!)$R\+```2$P$+"SH+.PL!$P``$Q8``P@Z"SL+21,``!0$ +XM`0L+.@L["P$3```5*``##AP-```6!`$##@L+.@L["P$3```7+@`##CH+.P4G +XM#!$!$@%`!@``&"X!`PXZ"SL%)PP@"P$3```9!0`#"#H+.P5)$P``&BX!`PXZ +XM"SL+)PP@"P$3```;!0`#"#H+.PM)$P``'#0``PXZ"SL+21,``!TT``,(.@L[ +XM"TD3```>+@$##CH+.P4G#!$!$@%`!@$3```?!0`#"#H+.P5)$P(&```@-``# +XM#CH+.P5)$P(&```A-``#"#H+.P5)$P(&```B-``##CH+.P5)$P``(QT!,1-5 +XM!E@+604``"0%`#$3```E"P%5!@``)C0`,1,"!@``)S0`,1,""@``*`4``PXZ +XM"SL%21,``"DT``,(.@L[!4D3```J+@$_#`,..@L[!2<,21,1`1(!0`8!$P`` +XM*P4``PXZ"SL%21,"!@``+!T!,1-5!E@+604!$P``+30`,1,``"XT``,..@L[ +XM"TD3`@H``"\T``,..@L["TD3/PP\#```,#0``PXZ"SL%21,_##P,`````1$! +XM)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```Q8``PXZ"SL+21,```0D``L+ +XM/@L#"```!20`"PL^"P``!@\`"PL```+@$##CH+.P4G#!$!$@%`!@$3```?!0`##CH+.P5)$P(&```@ +XM-``#"#H+.P5)$P``(2X!/PP##CH+.P4G#$D3$0$2`4`&`1,``"(N`3\,`PXZ +XM"SL+)PQ)$Q$!$@%`!@$3```C!0`#"#H+.PM)$P(&```D!0`##CH+.PM)$P(& +XM```E-``#"#H+.PM)$P(&```F+@$##CH+.PLG#$D3$0$2`4`&`1,``"+@$# +XM#CH+.PLG#$D3(`L!$P``'P4``PXZ"SL+21,``"`N`0,..@L[!2<,21,@"P$3 +XM```A!0`#"#H+.P5)$P``(@4``PXZ"SL%21,``",T``,..@L[!4D3```D+@$_ +XM#`,..@L[!2<,$0$2`4`&```E-``#"#H+.P5)$P(*```F-``##CH+.P5)$P(& +XM```G'0$Q$U4&6`M9!0$3```H!0`Q$P``*0L!508``"HT`#$3`@8``"LT`#$3 +XM```L-``Q$P(*```M"@`Q$Q$!```N'0$Q$U4&6`M9!0``+QT!,1,1`1(!6`M9 +XM"P$3```P!0`Q$P(&```Q"P$1`1(!```R'0$Q$U4&6`M9"P$3```S'0$Q$Q$! +XM$@%8"UD+`````1$!)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```R0`"PL^ +XM"P,(```$%@`##CH+.PM)$P``!20`"PL^"P``!@\`"PL```7!E2YH````````"0)@'$````````/9 +XM!`%(")P#=_U(")P#=_U(")P#X7W]`BL5`WHY6V4(D0,9C>(X`[E__0BO`Q(( +XMJ0-P_0@2"*T#\GX('4D(9@A`13OR"&=84J)#4E:JG9R!99V<2PB"`B03@8(( +XMGTFLGH4(6H*""&>"-CQ7`P^-<@AR.%8#"6,(67*!`QH(8P,*C0-Z_0,W")N4 +XM@(`#QWX".`$#E`&-G#@Z`PVIG#@Z9@@["$@(0(X(6`/J?L7"`_L`Q8%%.U8X +XM.F(\U%:.@/Y&`^-^?P,2C0/Y``@K_P-6"%4#QP`(Q0.&?P@Y`R,(Q0/=``C% +XM`[Y_"'\#F7\(Q0-B",4(S`/J``C%`\L`",4#I7\(.0/8``C%`^E^_0-YX0.4 +XM`?T#G@+OGE+(R9PX.F7F?8^XN+6`@;BXLX"%`WH('8#P\/16CU-)BTD(5P/O +XM?0A_"/$#P@`",0$#OG^W`P\(X0-Q""L#"M,#=@@=QP@ZR'(#%M,#=0AQ"#K( +XM7,``'-E8W1I;VYS+F,````` +XM7!E2YH````````"0+P*T````````/D`0&X"%24`B@2<@-W8P.\!0CA +XM"*!)"$J.CDB`CHZ`>EP(3[U(.%8($W*`2(!R;DP(R`-L",5(1DA&2`-KFP,, +XM",4##PC%`PL(Q0.J?P(H`:X#$PA'9P-I"&.."!3G@-D('_562@-CC0,6",4( +XMR@-/`B0!UD0]=V324,;&Q@-#"#GI"+@($P@L"$H(G4$#>#DZ@$AR@$A#2PAE +XM"!)RA31,-$A(Q0C(`PK]`PH(Q0C-`ZU_`BP!D0,7 +XMTP-NC0A+`PEQ9("`9(`#;6,#%0@Y5DH#;7$Z?CN`9(`##F,#:7$#%0C%`TT" +XM)P$(Q692/-8(/59B`DH05^0#=`(H`0C(",P#O7X")0&A"'?&E0C6"%:%"!)) +XM-U:.`V+%N`,2C0-M?P,BC0-J"!W&`PW]",H#Z7T")`$#"HT(2@B>6%)*U45) +XM-ZX(+#A(,&"`4@@24CP#%D)L(/<:0`B,,`Q$(1P,58P-K*P,-.0-S*TX(6@A( +XMQ@@\"&<##0@K`WF-20-6 +XM[PCU"*LZ2%E?2(Z.@`,3X0,+"'%6D`-KX0-6",4(R`,B",4#<0C%`V3A`\,` +XM",4#[`(")@$@1%B=!`(#QGW]_@0!`[<"Q8YT!`(#Q'T(.<8$`0.W`CD$`@/) +XM?4<$`0.W`G$$`@/)?3D$`0.W`CDQ;0@M!`(#Q'W]R`0!`W$(Q?U8`\0![WV! +XM10.^?G''@P,)`C5HPZ.%:/"!Y^5E0ML)=9ROB.`POA +XM`VF;JP-L?P.9?@A'A0.6`0CA`X5]J>(#E00(.0A:_`@[5H,$`@.O?0A'_@0! +XM`YH""!W4""P#<=,(2`,850@75GX#C'R-`XP$"-,#89OBN.XZ5M0#=M,#6PAC +XMX@/G``AQ`VS]`]Q^"%4(9PC_"&8('C@ZGP)B"XYR`E\1`X)_"/V`R@,="/T( +XM@@@>.%8"-!4(UP(M$3<[9M3GK`-G`DP!JJH(Y@,*",6L!`(#BW\"3P$$`0/X +XM`.$"91$"1@T#A@$"1@$#S0#A`Z]^")OX`D@-`E`*`W`(Q0/-`)L##0C%`WD( +XMQ0-)",4#9PC]`QT([U8J+&?H"#T"*Q$#8\4#$@)"`0(4``$!40$```(`E@`` +XM``$!^PX*``$!`0$````!+W5S7!EG$Q`VL('=,\ +XM4CS(.@BXW0-P")O3/%(\R#H(N-T#ZWX(FP,)*P-W50@CCH_&"(\(U@C7`YM^ +XMJ0B""$L(H`AS.PC4.')JA@-XFPAR"#P")!(('LE6@[QZ+P@Z"#P")!,(6%:" +XM`R.-"!XX5@/*``(D`0(E$`(U$PAGC@C&JKBX@8Y4@&8#;`+5`0$#&<6`"!YP +XM+`@>"&%TG@(F$8#&`R#%C@,4J0,5J0B0<@,+?P-V50,*50-V58`#+4<#5']R +XM;TNXP.5?W&<`]<`FP,; +XM"!U6`U=_40,+?P-W?[B_`WE52*JXN*JDAL@(Q@-'",4(D+%R\(!(G\#M`%_`[!^`D$! +XM`R)5`WI'`[.%Y\@/L?0CO`ZL$""L(9`.4?N$#4(T#>0@K`_Y]"$<( +XMUW0#Z0#O`B86`Y9_J<@#254#O@((8P(N$`@>"#RO"$@#"0+4`0$(/+M4.H", +XM4PBO"'*`.$@#OWX(?P,+"$<#F`$(*P@ZJ@A(`LH!%@+1`18(.@-X`B\!"#<( +XM.PCM".P#D'\"S0$!`_4`TP,Q`B@!`TW]`YA^`BT!`ZD#",4#O'X(Q0CM`S@( +XMX0-*`C0!"#<#@@$(.7*X@$AR;P.Q?\4#2@+,`0$"+A$#-`(N`0-/"#D#,P(E +XM`0,V`D.')F"*X( +XM<@B?"!8")!("(Q0(9`AP:`(W$`A6*CK&V@(F$^,(\4@#;[<#U0$(C0(I$0,T +XM`B,!`ZQ_`BX!5BHL`_,!")L#XGX(?P/_?@(J`0.-?_U6*BP#[P#3`Y)_*P-# +XM"'\#]@#A",D(%`.$?^$#AP,(Q0.G?0C%`BL45BHL`_8!Q0.@`0(K`0/7?'$" +XM(Q,(/`-Z",4"'@`!`0(!```"`(D````!`?L."@`!`0$!`````2]U7!EG\_`W5Q`PM5`T&W_4VX@`C)CT4[Z`,) +XM50-Q?P@>JL<#%PA5`VOA5PA6.GY(.$@#"0(D`4A&2`@;RDBX.%:`N`-ZX0-E +XM_0@``0$`%````/____\!``%X$`P'")`!````````'`````````!@'$`````` +XM`"D`````````1`X0```````<`````````)`<0```````*0````````!$#A`` +XM`````!P`````````P!Q````````I`````````$0.$```````+`````````#P +XM'$```````(\&````````2H\"A@9A#N`!C@.-!(P%@P<`````````/``````` +XM``"`(T```````'`(````````0@X0CP)%#AB.`TH.($(.*$$.,$$..$<.T`&# +XM!X8&C`6-!````````!0```#_____`0`!>!`,!PB0`0```````!0```#H```` +XM\"M```````!]`````````"0```#H````<"Q```````"V`0```````$J#!8P# +XM40YPC0*&!``````L````Z````#`N0```````!P$```````!"#A!!#AB&`XP" +XM1`X@1`Y@@P0````````<````Z````$`O0```````:P````````!.#B"#`X8" +XM`#0```#H````L"]```````#B`0```````$(.$$(.&(T#C@)%#B!!#BA!#C!$ +XM#G"#!H8%C`0`````)````.@```"@,4```````/0`````````00X0A@)$#AA$ +XM#B"#`P```"0```#H````H#)````````Y`0```````$J&!(,%5`ZP`8T"C`,` +XM```L````Z````.`S0```````.@$```````!"#A!"#AA!#B!!#BA$#G"#!88$ +XMC`.-`@`D````Z````"`U0```````_P````````!!#A"&`D0.&$0.8(,#```` +XM+````.@````@-D```````*(`````````0@X0C0)%#AB,`T0.((8$1`XH1`XP +XM@P4`'````.@```#0-D```````"(`````````1@X0```````<````Z``````W +XM0```````-P````````!$#A```````"0```#H````0#=```````!)`0`````` +XM`%J,`X,%C0*&!$<.8``````L````Z````)`X0```````%0$```````!"#A", +XM`D0.&(8#0PX@@P1(#G`````````\````Z````+`Y0```````%0,```````!" +XM#A!'#AA"#B!"#BA!#C"&!HP%C02.`X\"20XX1`Z0`8,'````````)````.@` +XM``#0/$```````-L`````````00X0A@)%#AA$#B"#`P```#P```#H````L#U` +XM``````#3"P```````$(.$$(.&$(.($(.*$$.,$$..$<.D`*#!X8&C`6-!(X# +XMCP(````````4````_____P$``7@0#`<(D`$````````4````X`,``)!)0``` +XM````V0`````````T````X`,``'!*0```````[@$```````!"#A!"#AA"#B!! +XM#BB&!8P$C0..`D0.,$0.L`&#!@```"P```#@`P``8$Q````````E`0`````` +XM`$(.$$$.&$$.((,$A@.,`D<.8````````!0```#_____`0`!>!`,!PB0`0`` +XM`````!0```!X!```D$U````````0`````````!0```!X!```H$U````````0 +XM`````````"0```!X!```L$U```````!!`````````$$.$(8"1`X81`X@@P,` +XM```<````>`0```!.0```````9@````````!.#B"&`H,#`!P```!X!```<$Y` +XM``````!F`````````$X.((8"@P,`/````'@$``#@3D```````/H7```````` +XM0@X01PX80@X@C02.`X\"10XH00XP00XX1P[@!(,'A@:,!0```````!0```#_ +XM____`0`!>!`,!PB0`0```````#P```!H!0``X&9```````"/`````````$(. +XM$$(.&$(.($(.*$$.,$$..(,'A@:,!8T$C@./`DH.0``````````\````:`4` +XM`'!G0```````GP$```````!"#A!"#AA"#B"-!(X#CP)%#BA!#C!!#CA$#E"# +XM!X8&C`4`````````7V5X=')A`'9?F4`5]L;VYG;W!T +XM`!%3$9?0U].54Q,`&]P +XM:&YU;0!S96-T:6]N6U?;&ES=`!S=')I<%]L;VYG;W!T6U?:V5E<`!%3$9?5%]32$12`'-A8U]L:7-T`&YO8V]P>0!? +XM6U?F4`14Q&7U1? +XM4U=/4D0`8W)E871E7V9I;&4`7U]F9FQA9W-?=`!%3$9?5%](04Q&`&]P=&%R +XM9P!S:&]R="!U;G-I9VYE9"!I;G0`14Q&7TM?05(`=E]R96P`6YC7W-E8W1I;VYS`$5L +XM9C8T7U-H9'(`:7-?'0`;G-E8W,`16QF-C1?6'=O`!R7V%D9&5N9`!R96PV-`!I +XM@!A9&1?=&]?:6YS96=?;&ES=`!P7V%L:6=N`$=% +XM;&9?4&AD<@!P7V9L86=S`'!?='EP90!P7W9A9&1R`'!?;65M6UB;VQS`&ES7V1E8G5G7W-Y;6)O;`!S=%]S>@!I +XM6T`5]C87``8V%L8U]N;VYL;V-A;`!%;&8V-%]3>6T`8W)E +XM871E7W-E8W-Y;0!'16QF7U-Y;0!A9&1?=&]?:V5E<%]L:7-T`'-T7V)U9@!L +XM;V]K=7!?5]B=68`:7-?;F5E9&5D7W-Y;6)O;`!S +XM>6UB;VQS+F,`:7-?;&]C86Q?6UB;VP`;'-Y9&%T80!L;V]K=7!?:V5E<%]S>6UL:7-T`'-T7VYA +XM;64`;6%R:U]S>6UB;VQS`&EN>@4````````?!P````````$`7@`````````````````````&`0`````` +XM``D!`````````0!0"0$````````,!`````````$`7"P$````````-00````` +XM```!`%QQ!````````'0$`````````0!0=`0```````#I!`````````$`7$T% +XM````````:04````````!`%R0!0```````-\&`````````0!<\`8````````0 +XM!P````````$`7``````````````````````O`P```````+H#`````````0!3 +XMVP,```````#\`P````````$`4Z,$````````SP0````````!`%/@!0`````` +XM`!<&`````````0!3CP8```````"M!@````````$`4\$&````````WP8````` +XM```!`%,`````````````````````?`(```````"Z`P````````,`D;A_VP,` +XM```````L!`````````,`D;A_HP0```````#I!`````````,`D;A_5@4````` +XM``!I!0````````,`D;A_P@4````````7!@````````,`D;A_CP8```````"M +XM!@````````,`D;A_P08```````#?!@````````,`D;A_\`8```````#_!@`` +XM``````,`D;A_`````````````````````"`'````````(@<````````"`'<( +XM(@<````````G!P````````(`=Q`G!P```````#$'`````````@!W&#$'```` +XM````,P<````````"`'<@,P<````````T!P````````(`=R@T!P```````#4' +XM`````````@!W,#4'````````/`<````````"`'`````````````````````"`'````````00<````` +XM```!`%1!!P```````(8-`````````0!?U0T```````"0#P````````$`7P`` +XM``````````````````!I!P```````&X'`````````0!540D```````!6"0`` +XM``````$`58()````````APD````````!`%6?"0```````*0)`````````0!5 +XMT`D```````#5"0````````$`58$+````````C`L````````!`%4U#``````` +XM`#H,`````````0!5/0P```````!"#`````````$`59T-````````H@T````` +XM```!`%7.#0```````-,-`````````0!5X@T```````#G#0````````$`5:4. +XM````````J@X````````!`%7)#@```````,X.`````````0!5W0X```````#B +XM#@````````$`55(/````````7@\````````!`%4````````````````````` +XMA`@```````"<"`````````$`4%H)````````>`D````````!`%"H"0`````` +XM`,8)`````````0!0]@T````````"#@````````$`4``````````````````` +XM```P#````````#H,`````````0!420P```````!0#`````````$`5``````` +XM```````````````I#````````#H,`````````0!120P```````!0#``````` +XM``$`40````````````````````#\"0```````/\)`````````0!0_PD````` +XM```>"@````````$`75`*````````4`H````````!`%T6#@```````"<.```` +XM`````0!=,0X```````!"#@````````$`70````````````````````"$"``` +XM`````/\)`````````0!=4`H````````4"P````````$`7=$+````````7`P` +XM```````!`%WV#0```````!8.`````````0!=0@X```````!G#@````````$` +XM70````````````````````"$"````````!X*`````````0!3G@H```````"A +XM"@````````$`4*$*````````%`L````````!`%/1"P```````%P,```````` +XM`0!3]@T````````'#@````````$`4Q8.````````)PX````````!`%,Q#@`` +XM`````$(.`````````0!34PX```````!G#@````````$`4P`````````````` +XM``````"$"````````)P(`````````0!0GP@```````#;"`````````$`4.(( +XM````````5@D````````!`%!X"0```````(<)`````````0!0C`D```````"D +XM"0````````$`4,8)````````U0D````````!`%#:"0```````/D)```````` +XM`0!0\@L````````)#`````````$`4`X,````````$PP````````!`%!0#``` +XM`````%4,`````````0!0`````````````````````!X*````````1@H````` +XM```!`%,'#@```````!8.`````````0!3`````````````````````#H,```` +XM````0@P````````!`%`[#0```````'H-`````````0!0```````````````` +XM`````!T+````````T0L````````!`%;2#````````&H-`````````0!6U0T` +XM``````#V#0````````$`5B<.````````,0X````````!`%8````````````` +XM````````&PL````````E"P````````,`D;!^)0L````````M"P````````,` +XMD;1^+0L````````P"P````````,`D;A^,`L````````R"P````````$`73(+ +XM````````,@L````````!`%,R"P```````$L+`````````P"1L'Y+"P`````` +XM`&P+`````````0!3;`L```````!R"P````````$`4W(+````````APL````` +XM```!`%.'"P```````(X+`````````0!=C@L```````"6"P````````$`4Y8+ +XM````````F`L````````#`)&T?I@+````````H`L````````!`%.@"P`````` +XM`*(+`````````P"1N'ZB"P```````+`+`````````0!3L`L```````"R"P`` +XM``````,`D;!^L@L```````#1"P````````$`4SH,````````20P````````# +XM`)&T?M(,````````^@P````````!`%/Z#`````````H-`````````P"1M'X* +XM#0````````P-`````````P"1L'X,#0```````!0-`````````0!3%`T````` +XM```S#0````````,`D;A^,PT```````"!#0````````$`4X$-````````E0T` +XM```````#`)&P?I4-````````U0T````````#`)&T?M4-````````]@T````` +XM```!`%,G#@```````#$.`````````0!3`````````````````````$4+```` +XM````3@L````````!`%#2#````````.(,`````````0!0)PX````````L#@`` +XM``````$`4``````````````````````Z#````````$D,`````````0!6:@T` +XM``````!Z#0````````$`5GH-````````E0T````````!`%"5#0```````-4- +XM`````````0!6`````````````````````(`,````````F`P````````!`%"Q +XM#@```````+\.`````````0!0`````````````````````&,(````````_PD` +XM```````!`%T4"P```````#`+`````````0!=\@L```````#2#`````````$` +XM7?8-````````!PX````````!`%UG#@```````&@/`````````0!=B0\````` +XM``"0#P````````$`70````````````````````!<#````````)@,```````` +XM`0!0FPP```````#+#`````````$`4&<.````````J@X````````!`%"_#@`` +XM`````,X.`````````0!0TPX```````#B#@````````$`4.<.````````"@\` +XM```````!`%``````````````````````.@P```````!)#`````````$`5CD/ +XM````````10\````````!`%9%#P```````%4/`````````0!050\```````!H +XM#P````````$`5@````````````````````"``````````)L``````````@!W +XM")L`````````-@(````````#`'?P``````````````````````"````````` +XM`*8``````````0!5I@````````"1`0````````$`7)L!````````-@(````` +XM```!`%P`````````````````````GP````````",`0````````$`5IL!```` +XM````-@(````````!`%8`````````````````````!0$````````(`0`````` +XM``$`4`@!````````AP$````````!`%.;`0```````+X!`````````0!3W`$` +XM```````V`@````````$`4P````````````````````!``@```````$("```` +XM`````@!W"$("````````0P(````````"`'<00P(```````!'`@````````(` +XM=QA'`@```````$L"`````````@!W($L"````````1P,````````#`'?@```` +XM``````````````````!``@```````%P"`````````0!57`(```````#M`@`` +XM``````$`5O`"````````1P,````````!`%8`````````````````````4@(` +XM``````#L`@````````$`4_`"````````1P,````````!`%,````````````` +XM````````Y0(```````#P`@````````$`4"P#````````,P,````````!`%`` +XM````````````````````4`,```````!>`P````````(`=PA>`P```````+L# +XM`````````@!W(`````````````````````!0`P```````'(#`````````0!5 +XMA0,```````"(`P````````$`50````````````````````!0`P```````&P# +XM`````````0!4;`,```````!W`P````````$`5G<#````````A0,````````! +XM`%2%`P```````+L#`````````0!6`````````````````````&(#```````` +XM?`,````````!`%-\`P```````(4#`````````0!5A0,```````"[`P`````` +XM``$`4P````````````````````#``P```````,(#`````````@!W",(#```` +XM````Q`,````````"`'<0Q`,```````#)`P````````(`=QC)`P```````,H# +XM`````````@!W(,H#````````RP,````````"`',#````````%@4````````!`%T6!0```````!D% +XM`````````0!5&04```````"B!0````````$`70`````````````````````$ +XM!````````!$%`````````0!3&04```````"B!0````````$`4P`````````` +XM``````````#6`P```````!(%`````````0!6&04```````"B!0````````$` +XM5@````````````````````"/!````````)($`````````0!0D@0```````#0 +XM!`````````$`44@%````````4@4````````!`%$````````````````````` +XM#00````````4!0````````$`7!D%````````H@4````````!`%P````````` +XM````````````L`4```````"Q!0````````(`=PBQ!0```````+4%```````` +XM`@!W$+4%````````N04````````"`'<8N04```````"D!@````````(`=R`` +XM````````````````````L`4```````#+!0````````$`5P`0````````````````````"P!@```````-0&`````````0!5U`8` +XM``````!_!P````````$`7(\'````````Z0<````````!`%P````````````` +XM````````L`8```````#9!@````````$`5-D&````````X08````````!`%4` +XM````````````````````L`8```````#A!@````````$`4>$&````````;P<` +XM```````!`%./!P```````.D'`````````0!3`````````````````````+`& +XM````````X08````````!`%+A!@```````'<'`````````0!6CP<```````#I +XM!P````````$`5@````````````````````#P!P```````/('`````````@!W +XM"/('````````]`<````````"`'<0]`<```````#U!P````````(`=QCU!P`` +XM`````/8'`````````@!W(/8'````````^@<````````"`'PL````````!`%1]"P```````(D+`````````0!6I0L```````"G +XM"P````````$`5L(+````````Q`L````````!`%;\"P```````),,```````` +XM`0!6`````````````````````'T+````````?PL````````!`%`T#``````` +XM`#D,`````````0!0:`P```````"##`````````$`4(X,````````F0P````` +XM```!`%``````````````````````H`P```````"B#`````````(`=PBB#``` +XM`````*8,`````````@!W$*8,````````J0P````````"`'<8J0P```````"Q +XM#`````````(`=R"Q#````````+4-`````````P!W\``````````````````` +XM````H`P```````"U#`````````$`5;4,````````+PT````````!`%PP#0`` +XM`````+4-`````````0!<`````````````````````*`,````````K0P````` +XM```!`%2M#````````"P-`````````0!3,`T```````"U#0````````$`4P`` +XM```````````````````2#0```````!\-`````````0!0>0T```````"##0`` +XM``````$`4`````````````````````"H#````````"T-`````````0!6,`T` +XM``````"U#0````````$`5@`````````````````````%#0```````#`-```` +XM`````@"16'D-````````EPT````````"`)%8`````````````````````"<- +XM````````,`T````````!`%$W#0```````$<-`````````0!1```````````` +XM`````````,`-````````P@T````````"`'<(P@T```````#)#0````````(` +XM=Q#)#0```````,L-`````````@!W&,L-````````S0T````````"`'<@S0T` +XM``````#.#0````````(`=RC.#0```````-<-`````````@!W,-<-```````` +XMVPT````````"`'NA````````#5$`````````$`7@`````````````` +XM```````T#@```````)P0`````````P"1N'^Z$````````-40`````````P"1 +XMN'\`````````````````````-`X````````0$`````````$`7140```````` +XMG!`````````!`%VZ$````````-40`````````0!=```````````````````` +XM`/\.`````````@\````````!`%`"#P```````%\/`````````0!1W@\````` +XM``#D#P````````$`4140````````'Q`````````!`%$````````````````` +XM````_P\````````5$`````````$`4+H0````````P1`````````!`%`````` +XM````````````````X!````````#A$`````````(`=PCA$````````.80```` +XM`````@!W$.80````````ZA`````````"`'<8ZA````````"[$0````````(` +XM=R``````````````````````X!````````!'$0````````$`56H1```````` +XM?1$````````!`%6$$0```````(X1`````````0!5K!$```````"Q$0`````` +XM``$`50````````````````````#@$`````````41`````````0!4+!$````` +XM``!$$0````````$`5&H1````````>!$````````!`%2$$0```````(L1```` +XM`````0!4`````````````````````/(0````````;Q$````````!`%-Q$0`` +XM`````+L1`````````0!3`````````````````````/00````````1!$````` +XM```!`%1J$0```````'@1`````````0!4A!$```````"+$0````````$`5*P1 +XM````````MA$````````!`%0`````````````````````]!`````````%$0`` +XM``````$`5"P1````````>!$````````!`%2$$0```````(L1`````````0!4 +XME1$```````"G$0````````$`5`````````````````````#T$````````'T1 +XM`````````0!5A!$```````".$0````````$`5941````````IQ$````````! +XM`%6L$0```````+$1`````````0!5`````````````````````,`1```````` +XMPA$````````"`'<(PA$```````#$$0````````(`=Q#$$0```````,81```` +XM`````@!W&,81````````R!$````````"`'<@R!$```````#)$0````````(` +XM=RC)$0```````,H1`````````@!W,,H1````````T1$````````"`'!8````````!`%5X%@```````)(6`````````P"1 +XMR'Z2%@```````)<6`````````0!5EQ8```````"3'0````````,`DP`0````````````````````#@ +XM`````````%P!`````````0!57`$```````!/`@````````$`5E8"```````` +XMS@(````````!`%8`````````````````````]@````````!A`0````````$` +XM4H4!````````3@(````````!`%-6`@```````)("`````````0!3```````` +XM`````````````/T`````````!`$````````!`%`+`0```````&$!```````` +XM`0!0`````````````````````/T`````````80$````````!`%$````````` +XM````````````H0$```````"J`0````````$`7*H!````````40(````````! +XM`%Q6`@```````)("`````````0!<`````````````````````-`"```````` +XMT@(````````"`'<(T@(```````#3`@````````(`=Q#3`@```````-0"```` +XM`````@!W&-0"````````VP(````````"`'<@VP(```````#U`P````````,` +XM=^```````````````````````-`"````````WP(````````!`%7?`@`````` +XM`*0#`````````0!3J`,```````#U`P````````$`4P`````````````````` +XM``#V`@````````4#`````````@"16`H#````````UP,````````"`)%8```` +XM`````````````````"``````````(0`````````"`'<((0`````````E```` +XM``````(`=Q`E`````````"D``````````@!W&"D`````````80`````````" +XM`'<@`````````````````````"``````````-P`````````!`%5````````` +XM`$8``````````0!56`````````!A``````````$`50`````````````````` +XM```@`````````#4``````````0!4-0````````!7``````````$`5E@````` +XM````8``````````!`%9@`````````&$``````````0!4```````````````` +XM`````#``````````5@`````````!`%-8`````````%\``````````0!3```` +XM`````````````````'``````````?@`````````"`'<(?@````````#6```` +XM``````(`=R``````````````````````<`````````"&``````````$`588` +XM````````P``````````!`%;%`````````-8``````````0!6```````````` +XM`````````'``````````C@`````````!`%2.`````````+L``````````0!3 +XMQ0````````#6``````````$`4P````````````````````#@`````````.X` +XM`````````@!W".X`````````1@$````````"`'<@```````````````````` +XM`.``````````]@`````````!`%7V`````````#`!`````````0!6-0$````` +XM``!&`0````````$`5@````````````````````#@`````````/X````````` +XM`0!4_@`````````K`0````````$`4S4!````````1@$````````!`%,````` +XM````````````````4`$```````!2`0````````(`=PA2`0```````%D!```` +XM`````@!W$%D!````````6P$````````"`'<86P$```````!@`0````````(` +XM=R!@`0```````&$!`````````@!W*&$!````````8@$````````"`'"0```````&D)`````````0!1$!0````` +XM``!%%`````````$`4488````````4!@````````!`%$````````````````` +XM````;@8```````!Q!@````````$`4'$&````````TP8````````!`%%&&``` +XM`````%`8`````````0!1`````````````````````-\#````````KP4````` +XM```!`%.S!0```````+H%`````````0!3[`4```````!'!@````````$`4Q<1 +XM````````*!$````````!`%/2$0````````82`````````0!3:!(````````T +XM$P````````$`4XX3````````I!,````````!`%/)$P```````!`4```````` +XM`0!3K!0```````#,%`````````$`4P,7````````,1<````````!`%-N%P`` +XM`````)@7`````````0!3I1@```````#*&`````````$`4P`````````````` +XM``````##`P```````+4'`````````P"1D'S)!P```````&D)`````````P"1 +XMD'S$"0```````.$0`````````P"1D'SO$````````&P4`````````P"1D'R. +XM%````````)@7`````````P"1D'RI%P```````,`7`````````P"1D'S"%P`` +XM`````.H7`````````P"1D'PH&````````$H9`````````P"1D'P````````` +XM````````````V`,```````"U!P````````,`D8A\R0<```````!I"0`````` +XM``,`D8A\T0D```````#A$`````````,`D8A\[Q````````!L%`````````,` +XMD8A\CA0```````"8%P````````,`D8A\J1<```````#`%P````````,`D8A\ +XMPA<```````#J%P````````,`D8A\*!@```````!*&0````````,`D8A\```` +XM`````````````````(@"````````WP,````````!`%-I"0```````-\)```` +XM`````0!3X1````````#O$`````````$`4U41````````D1$````````!`%,Q +XM%P```````&X7`````````0!3F!<```````"I%P````````$`4\`7```````` +XMZA<````````!`%,`````````````````````B@(```````"U!P````````,` +XMD;A_R0<```````!L%`````````,`D;A_CA0```````#J%P````````,`D;A_ +XM*!@```````!*&0````````,`D;A_`````````````````````%P$```````` +XM9@0````````!`%``````````````````````_P(```````"U!P````````,` +XMD8!\R0<```````#A$`````````,`D8!\ZA````````!L%`````````,`D8!\ +XMCA0```````#J%P````````,`D8!\*!@```````!*&0````````,`D8!\```` +XM`````````````````,\#````````M0<````````#`)'8?,D'````````:0D` +XM```````#`)'8?``*````````#`H````````#`)'X>PP*````````L@X````` +XM```#`)'8?+(.````````>P\````````#`)'X>WL/````````J@\````````# +XM`)'8?*H/````````O@\````````#`)'X>[X/````````T@\````````#`)'8 +XM?-(/````````\P\````````#`)'X>_,/````````,!`````````#`)'8?#`0 +XM````````X1`````````#`)'X>^\0````````%Q$````````#`)'X>Q<1```` +XM````D1$````````#`)'8?)$1````````LA$````````#`)'X>[(1```````` +XM!A(````````#`)'8?`82````````&A(````````#`)'X>QH2````````8A,` +XM```````#`)'8?&(3````````CA,````````#`)'X>XX3````````9Q0````` +XM```#`)'8?&<4````````;!0````````#`)'X>XX4````````_A8````````# +XM`)'8?/X6`````````Q<````````#`)'X>P,7````````,1<````````#`)'8 +XM?$87````````F!<````````#`)'8?*D7````````P!<````````#`)'8?,(7 +XM````````ZA<````````#`)'8?"@8````````2AD````````#`)'8?``````` +XM``````````````#8`P```````+4'`````````P"1\'O)!P```````&D)```` +XM`````P"1\'L5"@```````$D,`````````P"1\'OV#````````-H.```````` +XM`P"1\'MB#P```````'L/`````````P"1\'NJ#P```````-(/`````````P"1 +XM\'L4$````````.$0`````````P"1\'OO$````````*X2`````````P"1\'LT +XM$P```````&P4`````````P"1\'N.%````````*P4`````````P"1\'O,%``` +XM`````#$7`````````P"1\'M/%P```````)@7`````````P"1\'NI%P`````` +XM`,`7`````````P"1\'O"%P```````.H7`````````P"1\'LH&````````$H9 +XM`````````P"1\'L`````````````````````V`,```````#N`P````````$` +XM7YD%````````00<````````!`%^H"````````&D)`````````0!?&PH````` +XM``#A$`````````$`7^\0````````TA$````````!`%\&$@```````&@2```` +XM`````0!?-!,```````".$P````````$`7Z03````````VA,````````!`%\0 +XM%````````&P4`````````0!?CA0```````"L%`````````$`7\P4```````` +XM`Q<````````!`%]5%P```````&X7`````````0!?J1<```````#`%P`````` +XM``$`7\(7````````ZA<````````!`%\H&````````*48`````````0!?UQ@` +XM``````!*&0````````$`7P````````````````````"*`@```````/`"```` +XM`````0!6_P(```````""`P````````$`5H0#````````\D'````````;!0````````#`)'H>XX4 +XM````````ZA<````````#`)'H>R@8````````2AD````````#`)'H>P`````` +XM```````````````3`@```````+4'`````````P"1Y'O)!P```````&P4```` +XM`````P"1Y'N.%````````$H9`````````P"1Y'L````````````````````` +XM!@,````````N`P````````$`4(L#````````I`,````````!`%#8`P`````` +XM`/`#`````````0!5_0,````````(!`````````$`59D%````````\04````` +XM```!`%7V!0```````&8&`````````0!5J`@```````"Q"`````````$`50\) +XM````````$PD````````!`%4X%P```````#H7`````````0!0.A<```````!: +XM%P````````$`59@7````````I!<````````!`%#`%P```````,(7```````` +XM`0!0PA<```````#'%P````````$`50````````````````````"O!0`````` +XM`/8%`````````0!2`````````````````````)<*````````GPH````````! +XM`%3$"@```````,D*`````````0!5`````````````````````-@#```````` +XMWP,````````!`%.N"@```````/$*`````````0!3_@H```````!-"P`````` +XM``$`4U41````````D1$````````!`%/,%````````*`5`````````0!3J1<` +XM``````#`%P````````$`4\(7````````ZA<````````!`%,H&````````$88 +XM`````````0!3`````````````````````&X)````````>`D````````!`%4` +XM````````````````````51$```````!?$0````````$`5&D5````````;!4` +XM```````!`%!L%0```````'H5`````````0!4`````````````````````-@# +XM````````M0<````````#`)&X?,D'````````:0D````````#`)&X?$8*```` +XM````X1`````````#`)&X?.\0````````;!0````````#`)&X?(X4```````` +XM,1<````````#`)&X?%47````````F!<````````#`)&X?*D7````````P!<` +XM```````#`)&X?,(7````````ZA<````````#`)&X?"@8````````2AD````` +XM```#`)&X?``````````````````````T"P```````$,+`````````0!<51$` +XM``````"1$0````````$`7`H5````````MQ8````````!`%Q5%P```````&X7 +XM`````````0!`T````````!`%4*%0````````X5`````````0!5 +XM51<```````!:%P````````$`5;`7````````LA<````````!`%"R%P`````` +XM`,`7`````````0!5PA<```````#'%P````````$`5988````````F!@````` +XM```!`%"8&````````*48`````````0!5`````````````````````-@#```` +XM````M0<````````#`)&L?,D'````````:0D````````#`)&L?$8*```````` +XMX1`````````#`)&L?.\0````````;!0````````#`)&L?(X4````````,1<` +XM```````#`)&L?%47````````F!<````````#`)&L?*D7````````P!<````` +XM```#`)&L?,(7````````ZA<````````#`)&L?"@8````````2AD````````# +XM`)&L?`````````````````````#8`P```````+4'`````````P"1Q'S)!P`` +XM`````&D)`````````P"1Q'Q&"@```````%P*`````````P"1Q'Q<"@`````` +XM`&,*`````````0!48PH```````#A$`````````,`D<1\[Q````````!L%``` +XM``````,`D<1\CA0````````Q%P````````,`D<1\51<```````"8%P`````` +XM``,`D<1\J1<```````#`%P````````,`D<1\PA<```````#J%P````````,` +XMD<1\*!@```````!*&0````````,`D<1\`````````````````````$,'```` +XM````M0<````````!`%/;!P```````'$(`````````0!3B@@```````"H"``` +XM``````$`4XX4````````K!0````````!`%-5%P```````&X7`````````0!3 +XMRA@```````#7&`````````$`4P````````````````````!&!P```````+4' +XM`````````0!>R0<```````#8!P````````$`7ML'````````J`@````````! +XM`%Z.%````````*P4`````````0!>51<```````!N%P````````$`7LH8```` +XM````UQ@````````!`%X`````````````````````X@<````````>"``````` +XM``$`4%47````````6A<````````!`%7*&````````-<8`````````0!0```` +XM`````````````````````````````@`````````"`'<(`@`````````$```` +XM``````(`=Q`$``````````8``````````@!W&`8`````````"``````````" +XM`'<@"``````````)``````````(`=R@)``````````H``````````@!W,`H` +XM````````%``````````"`'@`````````!`%][```` +XM`````(X``````````0!?`````````````````````#,`````````;P`````` +XM```!`%9[`````````(8``````````0!6`````````````````````#4````` +XM````;0`````````!`%Q[`````````(@``````````0!<```````````````` +XM`````#4`````````;@`````````!`%-[`````````(4``````````0!3```` +XM`````````````````"0``````````@````````,` +XMD;A_`````````````````````.0`````````2P$````````!`%Q2`0`````` +XM``8"`````````0!<#0(````````>`@````````$`7``````````````````` +XM``#V`````````$@!`````````0!34@$```````"E`0````````$`4P`````` +XM``````````````#G`````````%$!`````````0!?4@$````````,`@`````` +XM``$`7PT"````````'@(````````!`%\`````````````````````[P`````` +XM```>`@````````(`D40`````````````````````#P$```````#;`P`````` +XM`/`&````````$`<```````#!!@```````-\&````````%P8```````"M!@`` +XM`````,(%````````_@4```````"0!0```````*X%````````304```````!I +XM!0```````,\$````````Z00````````L!````````#4$```````````````` +XM`````````````)!<```````!) +XM%P```````&H7````````0A<```````!&%P````````@7````````,!<````` +XM```"%P````````47````````[A8```````#W%@```````-H6````````X18` +XM``````#,%@```````-46`````````````````````````````%P2```````` +XM@1(```````#A%0```````/L5`````````````````````````````($2```` +XM````Y1(````````[&P```````$H;````````"A8```````"H%@```````'$5 +XM````````X14```````!@$P```````)L4```````````````````````````` +XM`($2````````Y1(````````[&P```````$H;````````EQ8```````"H%@`` +XM`````#@6````````6X`+G)E;&$N<&QT`"YI;FET`"YT97AT`"YF +XM:6YI`"YR;V1A=&$`+F5H7V9R86UE7VAD<@`N9&%T80`N96A?9G)A;64`+F1Y +XM;F%M:6,`+F-T;W)S`"YD=&]RE```````*!Z```````` +XMH`$````````%``````````@`````````$`````````"X`````0````,````` +XM````0'Q0``````!`?````````!`````````````````````(```````````` +XM````````OP````$````#`````````%!\4```````4'P````````0```````` +XM````````````"````````````````````,8````!`````P````````!@?%`` +XM`````&!\````````"`````````````````````@```````````````````#+ +XM`````0````,`````````:'Q0``````!H?````````$@"```````````````` +XM```(``````````@`````````T`````@````#`````````+!^4```````L'X` +XM```````P````````````````````"````````````````````-4````!```` +XM`````````````````````+!^````````]@$```````````````````$````` +XM``````````````#>`````0````````````````````````"F@````````/`` +XM```````````````````!````````````````````[0````$````````````` +XM````````````EH$```````#I`0```````````````````0`````````````` +XM`````/T````!`````````````````````````'^#````````:TX````````` +XM``````````$````````````````````)`0```0`````````````````````` +XM``#JT0```````#4+```````````````````!````````````````````%P$` +XM``$`````````````````````````']T````````8#@`````````````````` +XM`0```````````````````",!```!`````````````````````````#CK```` +XM``````8```````````````````@````````````````````P`0```0```#`` +XM```````````````````X\0```````(P-```````````````````!```````` +XM``$`````````.P$```$`````````````````````````Q/X```````"<5``` +XM`````````````````0```````````````````$8!```!```````````````` +XM`````````&!3`0``````@!@```````````````````$````````````````` +XM```1`````P````````````````````````#@:P$``````%0!```````````` +XM```````!`````````````````````0````(````````````````````````` +XM>'8!``````"@$0```````"0```!/````"``````````8``````````D````# +XM`````````````````````````!B(`0``````B@D```````````````````$` +XM`````````````````````````````````````````````````````````P`! +XM`,@!0````````````````````````P`"`.`!0``````````````````````` +XM`P`#`/@!0````````````````````````P`$`%`$0``````````````````` +XM`````P`%`-`+0````````````````````````P`&`.`.0``````````````` +XM`````````P`'`(`/0````````````````````````P`(`,`/0``````````` +XM`````````````P`)`#@00````````````````````````P`*`,@60``````` +XM`````````````````P`+`-P60````````````````````````P`,`%`;0``` +XM`````````````````````P`-`#AI0````````````````````````P`.`$AI +XM0````````````````````````P`/`$1R0````````````````````````P`0 +XM`&!R4````````````````````````P`1`&!U4``````````````````````` +XM`P`2`*!Z4````````````````````````P`3`$!\4``````````````````` +XM`````P`4`%!\4````````````````````````P`5`&!\4``````````````` +XM`````````P`6`&A\4````````````````````````P`7`+!^4``````````` +XM`````````````P`8`````````````````````````````P`9```````````` +XM`````````````````P`:`````````````````````````````P`;```````` +XM`````````````````````P`<`````````````````````````````P`=```` +XM`````````````````````````P`>`````````````````````````````P`? +XM`````````````````````````````P`@```````````````````````````` +XM`P`A`````````````````````````````P`B```````````````````````` +XM`````P`C`````````````````````````````P`D```````````````````` +XM```!````!`#Q_P`````````````````````(`````0`"`.`!0```````&``` +XM```````/````!`#Q_P`````````````````````M````!`#Q_P`````````` +XM```````````\````!`#Q_P`````````````````````/````!`#Q_P`````` +XM``````````````!'````!`#Q_P````````````````````!2`````0`3`$!\ +XM4`````````````````!@`````0`4`%!\4`````````````````!N`````0`5 +XM`&!\4`````````````````![`````@`,`/`;0`````````````````"1```` +XM`0`7`-1^4````````0````````"@`````0`0`'!R4`````````````````"G +XM`````@`,`#`<0`````````````````!'````!`#Q_P`````````````````` +XM``"S`````0`3`$A\4`````````````````#``````0`4`%A\4``````````` +XM``````#-`````0`1`&AZ4`````````````````#;`````0`5`&!\4``````` +XM``````````#G`````@`,`!!I0`````````````````#]````!`#Q_P`````` +XM```````````````M````!`#Q_P`````````````````````\````!`#Q_P`` +XM``````````````````#]````!`#Q_P`````````````````````;`0``!`#Q +XM_P`````````````````````B`0```@`,`&`<0```````*0`````````N`0`` +XM`@`,`)`<0```````*0`````````X`0```@`,`,`<0```````*0````````!& +XM`0```@`,`/`<0```````CP8```````!2`0```0`0`,!S4```````H`$````` +XM``!C`0```0`0`(!R4```````0`$```````!R`0``!`#Q_P`````````````` +XM``````!]`0```@`,`/`K0```````?0````````"0`0```@`,`$`O0``````` +XM:P````````"@`0```@`,`-`V0```````(@````````"T`0```@`,```W0``` +XM````-P````````#&`0```@`,`-`\0```````VP````````#1`0``!`#Q_P`` +XM``````````````````#<`0``!`#Q_P````````````````````#F`0```@`, +XM`)!-0```````$`````````#W`0```@`,`*!-0```````$``````````'`@`` +XM!`#Q_P`````````````````````/`@``$@`,`"`U0```````_P`````````< +XM`@``$@`,`*`Q0```````]``````````F`@``$@```.P60```````D``````` +XM```X`@``$@```/P60```````AP````````!2`@``$@````P70```````%P$` +XM``````!I`@``$@```!P70```````314```````!^`@``$@`,`*`R0``````` +XM.0$```````"(`@``$@```"P70```````?`$```````"9`@``$@`,`'!.0``` +XM````9@````````"J`@``$0`2`*!Z4`````````````````"S`@``$@```#P7 +XM0```````V@(```````#)`@``$@```$P70```````G@````````#8`@``$@`` +XM`%P70```````-`````````#J`@``$@```&P70```````50````````#[`@`` +XM$@`,`)`X0```````%0$````````/`P``$@`,`+`]0```````TPL````````< +XM`P``$@```'P70```````Y0`````````R`P``$@`,`.!F0```````CP`````` +XM``!``P``$@```(P70```````B@````````!0`P``$@```)P70``````````` +XM``````!A`P``$@```*P70```````:@````````!X`P``$0(0`&AR4``````` +XM``````````"%`P``$@```+P70```````X@````````":`P``$@`,`.!.0``` +XM````^A<```````"H`P``$@```,P70```````C`$```````#"`P``$@`,`+`O +XM0```````X@$```````#2`P``$@```-P70````````@````````#F`P``$@`` +XM`.P70```````AP8```````#X`P``$@```/P70```````.P`````````.!``` +XM$@````P80```````&0$````````E!```$@`,`.`S0```````.@$````````U +XM!```$@`*`,@60``````````````````[!```$@```!P80```````)``````` +XM``!2!```$@```"P80```````B`````````!A!```$0`7`-A^4```````"``` +XM``````!I!```$@```#P80```````3`````````![!```$@```$P80``````` +XM*0````````",!```$@```%P80```````-0````````"A!```$@```&P80``` +XM````:0$```````"V!```$@```'P80```````:@````````#0!```$0`7`+!^ +XM4```````!`````````#G!```$@```(P80```````K0(```````#X!```$@`` +XM`)P80```````%@`````````+!0``$0`0`&!R4```````"``````````6!0`` +XM$@`,`"`V0```````H@`````````E!0``$@`,`%`;0```````DP`````````L +XM!0``$@```*P80```````E0`````````\!0``$@```+P80``````````````` +XM``!+!0``$0`7`+A^4```````"`````````!!0``$@`,`#`N0```````!P$```````"J!0``$@`,`'!*0``` +XM````[@$```````"T!0``$@`,`'!G0```````GP$```````#%!0``$@```/P8 +XM0```````*`````````#"```$@```+P:0```````\@````````!O"```$0`7`,A^4```````"``` +XM``````"#"```$@```,P:0```````=@````````"2"```$0`7`-!^4``````` +XM!`````````"C"```$@```-P:0```````+P````````"T"```$@`,``!.0``` +XM````9@````````#&"```$@`,`)!)0```````V0````````#8"```$@```.P: +XM0```````'@````````#I"```$@```/P:0```````N0$````````$"0``$@`` +XM``P;0```````(0`````````9"0``$@```!P;0``````` +XM"0``$@`,`&!,0```````)0$```````!I"0``$@```#P;0```````:`$````` +XM``!_"0``$@`,`+`Y0```````%0,`````````8W)T,2YC`&%B:71A9P`O=7-R +XM+W-R8R]L:6(O8W-U+V%M9#8T+V-R=&DN4P`\8V]M;6%N9"UL:6YE/@`\8G5I +XM;'0M:6X^`&-R='-T=69F+F,`7U]#5$]27TQ)4U1?7P!?7T143U)?3$E35%]? +XM`%]?2D-27TQ)4U1?7P!?7V1O7V=L;V)A;%]D=&]R4!`1D)31%\Q +XM+C``5]P:&1R +XM`&EN'-C;D!`1D)31%\Q+C``9V5L9E]U<&1A=&5?empty.o.uu << '446fa33c5b702a1d1fbfe3ec7a501a1a' +Xbegin 644 empty.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````'`````` +XM`````````$```````$``!P`$```Nsections.o.uu << 'END-of-sections.o.uu' +Xbegin 644 sections.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` +XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@U(QT98`````$B+A\@```!(B49@2(N'R````$B) +XM,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D +XM\$B)7"3@28G\2(EL).A,B6PD^$B#[&A(BV]82(GF2(M]$.@`````2(7`#X0* +XM`0``2,=$)!``````2,=$)#`!````2(M%(,=$)`0#````2,=$)`@`````2,=$ +XM)#@`````QT0D+`````#'1"0H`````$B)1"082(M]$.@`````2(7`2(G##X3. +XM````0?9$)&00#X2&````2(M%*$B)YDB)1"0@2(M]$.@`````A<`/A,,```!( +XMQP,!````2(M%&$B)0PA(BT4H2,=#$`````#'0R`!````QT,D`0```$B)0QA( +XMBWT0Z`````!)BWPD($B)QN@`````A<`/A)8```!(BUPD2$B+;"103(MD)%A, +XMBVPD8$B#Q&C#9F:09I!(BU4H2(M]&$B#ZA!(C7<02(E5*.@`````Z5S___^_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!( +XMB<*_1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:005152(G] +XM4TB#[$!(BY_`````2(7;=')(BWL02(GFZ`````!(AY(BW@0Z`````")1"0HD$B+>Q!(B>;H`````(7`=$-(BUM82(7;=8[H```` +XM`(7`=4](@\1`6UU!7,/'1"0H`````.O+O______H`````+X`````2(G"OT8` +XM```QP.@`````O______H`````+X`````2(G"OT8````QP.@`````BQ@`=!E(B>Y(B=](BVPD$$B+7"0(2(/$&.D`````2(G?O@````#H```` +XM`$B)W[X`````Z`````!(B=^^`````.@`````O@````!(B=_H`````.NQ9F:0 +XM9I!!5D%528G]05154TB#[$!(BZ_`````2(7M=")!N`````#K"4B+;5A(A>UT +XM$4B+=0"Y"@```$R)Q_SSIG7F28N=D````$B%VP^$!@$``&9FD$F+?2#H```` +XM`$B%P$F)Q`^$^P```+YX````OP$```#H`````$B%P$B)P@^$_@```$B+`TR) +XMYTB)`DB+12!(B4(@2(M#$,="2/_____'0DP`````2,=""`````!,B6(02(E" +XM*$B+16!(B6I82(E"8$B+16!(B1!(C4)82(E%8.@`````2(7`2(G"#X2P```` +XM2,<``0```$C'0!``````2(GF2(M#"$R)YTB)0@A(BT,0QT(@`0```,=")`$` +XM``!(B4(8Z`````!(A<`/A(T```#'1"0$`0```$B+,TR)[^A=_O__2(GF3(GG +XMZ`````"%P`^$A0```$B+6QA(A=L/A?W^__](@\1`6UU!7$%=05[#O______H +XM`````+X`````2(G"OT8````QP.@`````O@````"_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````!F9F:0 +XM9F:054B)_5-(@^P(BU=4A=)T!TB#?Q@`=&PQV^M+9F:09I!(BWT0Z`````!( +XMA9(B=_H`````$B%P`^$KP```$B+1"1`2(GN3(GG2(D$)$B+1"1(2(E$ +XM)`A(BT0D4$B)1"002(M$)%A(B40D&$B+1"1@2(E$)"!(BT0D:$B)1"0H2(M$ +XM)'!(B40D,$B+1"1X2(E$)#CH^/O__TB)YDB)W^@`````A3ID````$B+:R!,.>4/@J@```"+>TR% +XM_W4?2(MS.#'23(GE2HU,)O](BQ!(B>;H`````$B%P'1O2(M#($B)YDB) +XM1"082(M#*$B)1"0@2(M[$.@`````A;H +XM`````$B%P`^$E````+YX````OP$```#H`````$B%P$B)PP^$M0```$B+1"0H +XMN@$```!(B4,@2(N-P````$B%R708,<"#>5`!2(M)6(/0`$B%R77P@\`!2&/0 +XM2(M](+D!````O@X```#H`````$B%P$B)0RAT24B)WDB)[TC'0S@$````QT-, +XM`````,=#4`$```#H6/;__TB)V$B#Q$A;7<.______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````,<#H`````)!!54&)U4%428G\54B)]5-(@^P(2(N?@````$B%VW4+ +XMZR9(BUM`2(7;=!U(BS-(B>_H`````(7`=>A(@\0(2(G86UU!7$%=PS';187M +XM=.N_2````.@`````2(7`=#9(B<.Z2````#'V2(G'Z`````!(B2M(QT-````` +XM`$F+A"2(````2(D82(U#0$F)A"2(````ZZ:^`````+]&````Z`````!F9F:0 +XM9F9FD&9FD&9FD#'22(/L".@`````,=)(A[SIG3CNP````!)B>1(QP0D`````$C'1"0(`````$C'1"00 +XM`````$C'1"08`````$C'1"0@`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G? +XMZ`````!(B=Y(B<)(B>_H`````(7`==A!BT5@@^@!@_@!=PJX`0```.E!____ +XM28-]0``/A#3___\QTDB)[DR)[^@`````08M=0(7;=`Y(A_HZ/W__X7`=:2+1"1$@_@)#X2M```` +XM@_@$#X2D````0;T`````N0H```!,B>;\3(GO\Z8/A20!``!(BUU82(M$)%A( +XMB4,@2(M](.@`````2(7`2(E#$`^$#@(``$R)]^@`````A<")0T@/A-T!``#\ +XMN0H```!,B>9,B>_SI@^%,@$``/R_`````+D(````3(GF\Z9U"(--9!!(B5U( +XM_+\`````N0@```!,B>;SIG4$2(E=4$B)WDB)[^@/\O__Z>K^__]$BVPD;$6% +XM[0^$3O___TB+?1A(C;0D@````.@`````A<`/A*T!```QVT6)[4B+?1A(B=[H +XM`````$B%P$B)PP^$Q@```$B)W^@`````23G%==M(B>9(B=_H`````$B%P`^$ +XMC0$``(L4)$B+M"2`````2(M]&.@`````2(7`2(G(````2(GOZ)W\__^% +XMP`^%5?[__^G"_O__OG@```"_`0```.@`````2(7`#X03`0``2(G#3(D@3(EP +XM"$B+1"182(G>2(GO2(E#($B+1"1@2(E#*$B+1"1P2(E#.(M$)$1(B4-`Z``` +XM``")0TSID?[__TB+4Q!(BW,(2(GO2(L+Z`````#IMO[__^@`````A<`/A-/] +XM__^)Q^@`````O@````!(B<*_1@```#'`Z`````#H`````(7`==Q(@<28```` +XM6UU!7$%=05Y!7\.______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:054B-+#=32(/L +XM"$@Y[W-[2(G[ZSB+!0````"%P'5S2(LU`````(M&#(/H`87`B48,#XB6```` +XM2(L&Q@`*2(/``4B)!DB#PP%(.>MT/@^V$X32=,&+!0````"%P'5'2(LU```` +XM``^^^HM&#(/H`87`B48,>$%(BP9(@\,!0(@X2(/``4@YZTB)!G7"2(/$"%M= +XMPTB+-0````"_"@```.@`````ZY](BS4`````#[[ZZ`````#KCCM&*'P(@/H* +XM9F:0=;+H`````.EW____OPH```#H`````.EH____9F:09I!!5T%6055!5%53 +XM2('LF````$B)?"083(NOP````$V%[71;2(V$)(````!(B40D".L)38MM6$V% +XM[71#08M%4(7`=>])BUT`OP````"Y"````/Q(B=[SIG4W2(M4)!CV0F1`=UUO4B!Q)@```!;74%<05U!7D%?P[\` +XM````N0@```!(B=[SIG2X_+\`````N0H```!(B=[SI@^$>____TB+5"08@WI@ +XM`0^$CP```$B+?"082(G>Z![Y__^%P`^$,0,``#';13'_2,=$)#@`````ZS]F +XM9I!F9I!(BWPD.$@#>QCH`````$F)QTV%_P^$V0,``$B+5"0X2(MS"$F-/!=( +XMBU,8Z`````!(BT,82`%$)#A)BWT(2(G>Z`````!(AQCH`````$F)Q^NM28-]0`D/A6;___])BWT(2(UT)$#H`````$B%P`^$ +XMU`0``$B+1"08]D!D$`^%C@,``$B+@,````!(AU(QT0D*`````"`.`!T%4B#Q0%*C40]`$@Y +XM1"0@2(EL)"AWYD@Y1"0@#X2@`0``3(MT)#!,`W0D.$R+9"0P33GF=R'I+@$` +XM`&:028U<)`%,B>?H`````$R-)`--.>8/AA(!``!,B?Y,B>?H`````(7`===( +XMBT0D*$Z-?#@!3#E\)"`/AW3___])BW4`2(M\)!CH]/;__X7`#X50`0``2(M$ +XM)#A!QT54`0```$F)12A,B>_H`````$F+=0!(BWPD&#'2Z`````!(A<`/A/O\ +XM__^+0#"%P`^$\/S__TF+?1A(A?]T#4F+=2A(A?8/APCHN/O__TF+?0A(B=[H`````$B%P$B)PW7?Z`````"%P`^%EP(``(L%```` +XM`(7`#X5=`0``2(LU`````(M&#(/H`87`B48,#X@U`@``2(L&Q@`*2(/``4B) +XM!NEP_/__28MU`$B+?"08Z"'V__^%P`^$/O___^D:_O__2(GJ3(G^3(GWZ``` +XM``!(BU0D.$B-1!4`2(M4)##&!!``2(/``4B)1"0XZ<[^__](BWPD&$B)WNBH +XM]?__A<`/A/7^___IM?S__^CV^O__9F:09F:0Z53___](BWPD,$@#?"0X2(GJ +XM3(G^Z`````!(`6PD..F:_O__28MU`$B+?"08,=+H`````$R+8!A,B>?H```` +XM`$B+?"0P2`-\)#A(B<),B>9(B4Q[44QY$4Q]DF+?0A,B?;H`````$B%P$F)Q@^$7P$``$B-E"2`````,?9, +XMB??H`````$@[1"0(#X4D`0``2(M4)!B+G"2,````2(M"4$B+>`CH`````$B) +XMQDB+1"082(G:2(MX&.@`````2(7`2(G-````2(M\)!CH`````(7`=(1( +XMBU0D&(-Z%`%T/[]`````Z`````!(A$F)Q$B+A"2`````28D$)$B+A"2( +XM````28E$)`CI2?___[\*````Z`````#I/OK__[\@````Z`````!(A6P````,`````!6-_````!PBZ +XM````!PCN````"+H````#``````7HGP````,``````B^O````"0`````0`D8R +XM`0``"@`````"1S(!```"(P`*``````)(5`````(C"``'"#0````)`````)@" +XM9EP"```+7W```F50````"(W`*``````)\W@(```(C +XM=`H``````GWN`@```B-W"U]L8@`"@`D!```"(W@*``````*#5`````,CB`$* +XM``````*$_@````,CD`$`#`%4````;`(```VM``````<(7`(```P!5````(P" +XM```-K0````WB````#50`````!PAR`@``#`'^````K`(```VM````#?X````- +XM5``````'")("```,`50```#,`@``#:T````-Z`````U4``````<(L@(```X` +XM`````0<(T@(```\T````[@(``!"J`````@`/-````/X"```0J@```````P`` +XM```"A3@!```""`4``````P`````&)LP````#``````8JS`````\T````-@,` +XM`!"J````#P`1"`9Z6P,```H`````!GL0`P```B,`"@`````&?!L#```"(P0` +XM`P`````&?38#```#``````%D@,```(C"``#``````>&%04``!)%;&8` +XM""90!0``#@`````!`P`````()V$%```.``````$3!`@V``8``!0``````!0` +XM`````10``````A0``````Q0`````!!0`````!10`````!A0`````!Q0````` +XM"!0`````"10`````"A0`````"Q0`````#!0`````#10`````#A0`````#Q0` +XM````$!0`````$10`````$A0`````$Q0`````%!0`````%10`````%A0````` +XM%P`#``````A/9P4``!$("'@B!@``"@`````(>*T&```"(P``"0````!`"&BM +XM!@``"@`````(;-<````"(P`*``````AMK0````(C"`H`````"&[7`````B,0 +XM"@`````(;]<````"(Q@*``````AP``8```(C(`H`````"'%F`````B,D"@`` +XM```(=K,&```"(R@*``````AW9@````(C,`H`````"'@+!@```B,X``<((@8` +XM``<(5@4```,`````"'DB!@```P`````)+FH$```#``````DP"@4```,````` +XM"3(Z!0``$0@*)/P&```*``````HD)0<```(C```)`````!`*(24'```*```` +XM``HBZ`````(C``H`````"B3E!@```B,(``<(_`8``!$("C9"!P``"@`````* +XM-O<'```"(P``"0````!("BCW!P``"@`````**>@````"(P`*``````HJZ``` +XM``(C"`H`````"BOH`````B,0"@`````*+.@````"(Q@+861D``HN5`````(C +XM(`H`````"B]4`````B,D"@`````*,%0````"(R@*``````HQ5`````(C+`H` +XM````"C)4`````B,P"@`````*,U0````"(S0*``````HT5`````(C.`H````` +XM"C8K!P```B-```<(0@<``!$("C\4"```"@`````*/UD(```"(P``"0`````@ +XM"CI9"```"@`````*.^(````"(P`*``````H\X@````(C"`H`````"CWS```` +XM`B,0"@`````*/_T'```"(Q@`!P@4"```$1`*4H0(```*``````I28`D```(C +XM``H`````"E)F"0```B,(``D`````>`I#8`D```H`````"D3H`````B,`"VES +XM``I%LP8```(C"`MO@`*6=<````"(P@+;7-Z``I:UP````(C$`H` +XM````"EO7`````B,8"@`````*750````"(R`*``````I?D0D```(C*`H````` +XM"F"Z"0```B,X``<(T0D``!,$"H1M"@``%```````%``````!%``````"%``` +XM```#%``````$`!$0"IB2"@``"@`````*F$`*```"(P`*``````J8D@H```(C +XM"``'"$`*```1$`J9O0H```H`````"IGW!P```B,`"@`````*F;T*```"(P@` +XM!PCW!P``$1`*FN@*```*``````J:60@```(C``H`````"IKH"@```B,(``<( +XM60@``!$0"IP3"P``"@`````*G"4'```"(P`*``````J<$PL```(C"``'""4' +XM```1$`J>/@L```H`````"IXE!P```B,`"@`````*GA,+```"(P@`$1`*H&,+ +XM```*``````J@8`D```(C``H`````"J!F"0```B,(`!$("J)Z"P``"@`````* +XMHF`)```"(P``"0````#8"F85#0``"@`````*9^@````"(P`*``````IJ5``` +XM``(C"`H`````"FM4`````B,,"VEE8P`*;50````"(Q`+;V5C``IN5`````(C +XM%`ME:6X`"F\5#0```B,8"@`````*50````"(S`*``````IZ5`````(C-`H````` +XM"GM4`````B,X"@`````*?%0````"(SP*``````I]5`````(C0`H`````"GY4 +XM`````B-$"@`````*@&`)```"(T@*``````J!8`D```(C4`H`````"H)@"0`` +XM`B-8"@`````*BD8*```"(V`*``````J35`````(C9`H`````"I8R`0```B-H +XM"@`````*F&T*```"(W`*``````J9F`H```,C@`$*``````J:PPH```,CD`$* +XM``````J<[@H```,CH`$*``````J>&0L```,CL`$*``````J@/@L```,CP`$* +XM``````JB8PL```,CT`$`!PA%!0``%0`````!XP$````````````````````` +XM`G<(8`T``!9E8W```>)@#0```5461@"0```5$` +XM!PAZ"P``&`$``````5X#`0``````````````````````````Q@T``!EE8W`` +XM`5T#8`T````````:P"8`D````````@$@````_H````'A(``!"J````!``' +XM".@````F``````$X`50``````````````````````````````+T2```C96-P +XM``$W8`T````````D``````$WZ``````````K`````'\2```E``````%P`@$``````````````````````````*<4 +XM```99``!;P+H`````````!ES>@`!;P+S`````````!IC``%Q`N@````````` +XM.NT3`````````74"AQ0``#L*%````````"W_$P```#7M$P````````%W`CL* +XM%````````#O_$P``````````/``````!I0$!`4L5```Y96-P``&D`6`-```Y +XM@`````/``````!*`(!`2`6```Y96-P``$G`F`-```Y&```+9D5```MC14``#8`````-Z,5````````-Z\5````````,+L5```P +XMQQ4``#?1%0```````##=%0``-^<5````````-_$5````````,/L5```O!Q8` +XM``.1T'XP$Q8``#4@%@````````$N`BT\%@``+3(6```V`````#=(%@`````` +XM`#!3%@``,%T6```W:!8`````````````/GL6```````````````````````` +XM`9H!H!@``"V7%@``+8P6```N`````````````````````#>B%@`````````` +XM-:X6`````````9L!+;P6```V`````#?&%@```````#?1%@```````#7M$P`` +XM``````&,`CL*%````````"W_$P```````#\``````HH6%````0%```````*@ +XM`50````!`0!^!````@"X`````0'[#@H``0$!`0````$O=7-R+VEN8VQU9&4` +XM+W5S7!E7!E6%)*U45)-ZX(+#A(,&"`4@@24CP#%D)NMQ@A8`Z4!`B0!`PDK`W=5`PF; +XM`W=5`PE_""!RA7J`@'*!"!4#>E5,"'((/`CTZ`A;`PP(C4B0"%D(,`@\"!Y( +XM20@>20-8[P/'?M,##@A_`W@K.`ARQ@@\".4#L0$(1PB=.DA97TB.CH`#$<4# +XMO'X(<58#T`%_")E62@.E?@@=`YX!",4#*0C%",$#<0C%`\%^X0C,`X($`B@! +XM($18G00"`Y-^_?X$`0/J`<6.=`0"`Y%^"#G&!`$#Z@$Y!`(#EGY'!`$#Z@%Q +XM!`(#EGXY!`$#Z@$Y,6T(+00"`Y%^_<@$`0-K",7]6`/D`+<#G'_ACX,(5ZJ` +XM`W:-`R2-`V(('0,*_0A<`[1^X0/:`P(K`?Z0"%8#=XT(F4H*2!F +XM86EL960Z("5S`&YO="!E;F]U9V@@;65M;W)Y`"YD96)U9P`N9VYU+FQI;FMO +XM;F-E+G=I+@`N;&EN90`N&!HP%C02.`X\"````````%``` +XM```````!>E(``7@0`0,,!PB0`0``%````!P`````````<``````````````` +XM'````#0`````````M@$```!*@P6,`U$.<(T"A@0````D````5`````````#\ +XM`````$(.$$$.&(8#C`)$#B!$#F"#!```````%````'P`````````:P````!. +XM#B"#`X8"+````)0`````````Z0$```!"#A!"#AB-`XX"10X@00XH00XP1`YP +XM@P:&!8P$````'````,0`````````]`````!!#A"&`D0.&$0.((,#```<```` +XMY``````````Y`0```$J&!(,%5`ZP`8T"C`,``"0````$`0```````"\!```` +XM0@X00@X800X@00XH1`YP@P6&!(P#C0(<````+`$```````#_`````$$.$(8" +XM1`X81`Y@@P,``"0```!,`0```````*(`````0@X0C0)%#AB,`T0.((8$1`XH +XM1`XP@P44````=`$````````B`````$8.$``````4````C`$````````W```` +XM`$0.$``````<````I`$```````!``0```%J,`X,%C0*&!$<.8````#0```#$ +XM`0```````*8#````0@X01PX80@X@0@XH00XPA@:,!8T$C@./`DD..$<.T`&# +XM!P``````'````/P!````````VP````!!#A"&`D4.&$0.((,#```T````'`(` +XM``````#N!@```$(.$$(.&$(.($(.*$$.,$$..$<.T`&#!X8&C`6-!(X#CP(` +XM`````'``````````BP`````````"`'<(BP`````````F`@````````,`=_`` +XM`````````````````````'``````````E@`````````!`%66`````````($! +XM`````````0!00` +XM``````"W!`````````$`42\%````````.04````````!`%$````````````` +XM````````[0,```````#[!`````````$`7``%````````B04````````!`%P` +XM````````````````````D`4```````"1!0````````(`=PB1!0```````)4% +XM`````````@!W$)4%````````F04````````"`'<8F04```````"$!@`````` +XM``(`=R``````````````````````D`4```````"K!0````````$`5:L%```` +XM````&08````````!`%89!@```````!H&`````````0!5&@8```````!*!@`` +XM``````$`5DL&````````A`8````````!`%8`````````````````````J04` +XM```````8!@````````$`4QH&````````208````````!`%-+!@```````(0& +XM`````````0!3`````````````````````+P%````````OP4````````!`%"_ +XM!0````````(&`````````0!1&@8```````!5!@````````$`40`````````` +XM```````````1!@```````!H&`````````0!0:08```````!P!@````````$` +XM4`````````````````````"0!@```````*X&`````````@!W"*X&```````` +XMR0<````````#`'>P`0````````````````````"0!@```````+0&```````` +XM`0!5M`8```````!?!P````````$`7&\'````````R0<````````!`%P````` +XM````````````````D`8```````"Y!@````````$`5+D&````````P08````` +XM```!`%4`````````````````````D`8```````#!!@````````$`4<$&```` +XM````3P<````````!`%-O!P```````,D'`````````0!3```````````````` +XM`````)`&````````P08````````!`%+!!@```````%<'`````````0!6;P<` +XM``````#)!P````````$`5@````````````````````#0!P```````-('```` +XM`````@!W"-('````````U`<````````"`'<0U`<```````#5!P````````(` +XM=QC5!P```````-8'`````````@!W(-8'````````V@<````````"`'0T```````"P#0````````$`7,0-````````Q@T````````! +XM`%S>#0```````.`-`````````0!<]@T```````"0#@````````$`7*X.```` +XM````Z`X````````!`%P`#P```````#P/`````````0!<0P\```````"[#P`` +XM``````$`7,H/````````!A`````````!`%P`````````````````````WPP` +XM``````!`#P````````$`7D,/````````!A`````````!`%X````````````` +XM````````#0\````````4#P````````$`4"\/````````0P\````````!`%`` +XM````````````````````<@X```````!U#@````````$`4'4.````````@PX` +XM```````!`%1##P```````$T/`````````0!4`````````````````````-\, +XM````````<`T````````!`%/V#0```````*L.`````````0!3``\````````Y +XM#P````````$`4T,/````````?P\````````!`%.[#P````````80```````` +XM`0!3`````````````````````-\,````````[`P````````!`%`'#P`````` +XM`!0/`````````0!0`````````````````````!`0````````$1`````````" +XM`'<($1`````````6$`````````(`=Q`6$````````!H0`````````@!W&!H0 +XM````````ZQ`````````"`'<@`````````````````````!`0````````=Q`` +XM```````!`%6:$````````*T0`````````0!5M!````````"^$`````````$` +XM5=P0````````X1`````````!`%4`````````````````````$!`````````U +XM$`````````$`5%P0````````=!`````````!`%2:$````````*@0```````` +XM`0!4M!````````"[$`````````$`5``````````````````````B$``````` +XM`)\0`````````0!3H1````````#K$`````````$`4P`````````````````` +XM```D$````````'00`````````0!4FA````````"H$`````````$`5+00```` +XM````NQ`````````!`%3<$````````.80`````````0!4```````````````` +XM`````"00````````-1`````````!`%1<$````````*@0`````````0!4M!`` +XM``````"[$`````````$`5,40````````UQ`````````!`%0````````````` +XM````````)!````````"M$`````````$`5;00````````OA`````````!`%7% +XM$````````-<0`````````0!5W!````````#A$`````````$`50`````````` +XM``````````#P$````````/(0`````````@!W"/(0````````]!`````````" +XM`'<0]!````````#V$`````````(`=QCV$````````/@0`````````@!W(/@0 +XM````````^1`````````"`'%P`````` +XM``$`70````````````````````"U$0```````,(1`````````0!0?!(````` +XM``"[$@````````$`4/H5`````````Q8````````!`%`````````````````` +XM````@A8```````"%%@````````$`4(46````````E18````````!`%18%P`` +XM`````&(7`````````0!4`````````````````````"$1````````=A$````` +XM```!`%9_$0```````%<3`````````0!6WA,```````#,%`````````$`5OL4 +XM````````)14````````!`%9$%0```````-X7`````````0!6```````````` +XM`````````"$1````````>!$````````!`%Q_$0```````)03`````````0!< +XMWA,```````#,%`````````$`7/L4````````6!4````````!`%R4%0`````` +XM`-X7`````````0!<`````````````````````"$1````````?!$````````! +XM`%Y_$0```````(H3`````````0!>WA,```````#,%`````````$`7OL4```` +XM````WA<````````!`%X`````````````````````$A<````````7%P`````` +XM``$`59L7````````G1<````````!`%"=%P```````,07`````````0!5```` +XM`````````````````+T1````````PA$````````!`%0#%0````````@5```` +XM`````0!4`````````````````````%@5````````8!4````````!`%"_%0`` +XM`````,05`````````0!0`````````````````````"$1`````````1,````` +XM```#`)'H?@$3````````!A,````````!`%4&$P```````*L5`````````P"1 +XMZ'ZK%0```````+05`````````0!5M!4```````#.%0````````,`D>A^SA4` +XM``````#3%0````````$`5=,5````````WA<````````#`)'H?@`````````` +XM```````````A$0```````'81`````````0!6?Q$```````!M%0````````$` +XM5FT5````````>!4````````!`%&4%0```````!<6`````````0!6U!8````` +XM``#C%@````````$`5A`7````````6!<````````!`%8````````````````` +XM````(1$```````!^$0````````$`7W\1````````8!,````````!`%]@$P`` +XM`````)X3`````````0!0GA,````````E%0````````$`7R45````````.A4` +XM```````!`%`Z%0```````-X7`````````0!?`````````````````````"$1 +XM````````>!$````````!`%Q_$0```````)<3`````````0!%0```````*85```````` +XM`0!5JQ4````````:%@````````$`7-06````````XQ8````````!`%P0%P`` +XM`````%@7`````````0!<`````````````````````"$1````````-A$````` +XM```!`%-M$0```````'41`````````0!3S!$```````!$$@````````$`4[L2 +XM````````I1,````````!`%.Z$P```````$D4`````````0!3>10```````#[ +XM%`````````$`4Q45````````6YC7W-E8W1I;VYS`&(0``!I;G-EPX```````!O +XM#@```````'(.````````4@X```````!;#@```````$(.````````1PX````` +XM```T#@```````#H.````````+@X````````Q#@`````````````````````` +XM```````U$````````%,0````````W!````````#K$``````````````````` +XM``````````!W$````````(<0````````Q1````````#<$````````)40```` +XM````F!````````"+$````````)(0`````````````````````````````!(1 +XM````````(1$````````Z%P```````-X7````````XQ8````````0%P`````` +XM``,6````````U!8```````!/$@```````,`2```````````````````````` +XM`````%T2````````P!(```````#-%P```````-X7````````O!<```````#` +XM%P```````+(7````````NA<```````"=%P```````*@7````````F1<````` +XM``";%P```````(`7````````E!<```````!B%P```````'87````````1!<` +XM``````!8%P```````.T6````````$!<```````"N%@```````-06```````` +XME18```````"D%@```````(46````````BQ8```````!_%@```````((6```` +XM````5Q8```````!>%@```````$<6````````4A8````````O%@```````#46 +XM````````*18````````L%@````````,6````````'18````````````````` +XM````````````M1$```````#@$0```````/L4````````%14````````````` +XM````````````````X!$```````!$$@```````"L7````````.A<````````E +XM%0```````.05````````L10```````#[%````````,`2````````!10````` +XM````````````````````````X!$```````!$$@```````"L7````````.A<` +XM``````#3%0```````.05````````$P```````+$3 +XM````````NA,````````K$P```````*43````````'1,````````A$P`````` +XM``X3````````&1,````````&$P````````D3````````]!(````````!$P`` +XM`````,`2````````YA(`````````````````````````````X!$```````!$ +XM$@```````-,5````````Y!4```````#`$@```````,T2```````````````` +XM`````````````/$1````````&1(```````#3%0```````.05````````Q1(` +XM``````#-$@```````"L2````````-A(````````E$@```````"@2```````` +XM`````````````````````#$4````````L10````````0%P```````"L7```` +XM````U!8```````#C%@```````.05`````````Q8````````5%0```````"45 +XM`````````````````````````````#$4````````6!0````````7%P`````` +XM`"L7````````U!8```````#C%@```````!45````````)14```````!Q%``` +XM`````+$4````````:A0```````!L%````````&04````````9Q0````````` +XM````````````````````CA0```````"Q%````````-06````````XQ8````` +XM````````````````````````16QF-C1?061D<@!D8F=?F4`7V9L86=S`&5?=F5RF4`1T5L +XM9E]%:&1R`&1?6U?;&ES=`!S96-?861D`&-O<'E?9&%T80!C;W!Y`&5?96YT@!S='%H7V9I6UT86(`:7-?F5?=`!D7W1Y<&4`14Q&7U1? +XM4UE-`$5L9E]4>7!E`'-E9U]L:7-T`&9L86=S`%]?=6EN=#8T7W0`16QF-C1? +XM2&%L9@!S96-T:6]NF4`:6YF;70`14Q&7U1?0EE410!D7V)U9@!S:7IE`$5,1E]47U=/4D0` +XM;6]D:69Y7W-E8W1I;VX`14Q&7U1?4TA$4@!C;W!Y7W-H9'(`<'-E=61O`'-H +XM7V]F9G-E=`!A9&1O<'0`:6YS97)T7W-H=&%B`$5,1E]47T%$1%(`7V5X=')A +XM`'-E=%]S:'-T5]C;VYT96YT`'9?;61A=`!%;&9? +XM1&%T80!C;VYT96YT`&1?9FQA9W,`95]T>7!E`'9?6UT86(`+G-T`!M96UM;W9E`&5L9E]E`!U<&1A=&5?5]D871A`&5L9E]G971D871A`&-O<'E?5]C;VYT96YT`&-R +XM96%T95]S>6UT86(`;65M8W!Y`'-TP,````````"````)````/S_________@P,````````*````"0```*X````` +XM````B`,````````"````)````/S_________C0,````````*````"0```+8` +XM````````E0,````````"````)````/S_________O0,````````*````"0`` +XM`+8`````````]0,````````"````)@```/S_________$`0````````"```` +XM)P```/S_________;P0````````"````&@```/S_________LP0````````" +XM````&0```/S_________V@0````````"````&P```/S_________!@4````` +XM```"````'P```/S_________"P4````````*````"0```,``````````&@4` +XM```````"````(````/S_________'P4````````*````"0```-@````````` +XM*P4````````"````*````/S_________-04````````"````'P```/S_____ +XM____.@4````````*````"0```!X`````````204````````"````(````/S_ +XM________4P4````````"````'P```/S_________6`4````````*````"0`` +XM`.4`````````9P4````````"````(````/S_________<04````````"```` +XM'P```/S_________=@4````````*````"0```#<`````````A04````````" +XM````(````/S_________M04````````"````&@```/S__________@4````` +XM```"````*@```/S_________"P8````````"````(P```/S_________408` +XM```````"````'P```/S_________5@8````````*````"0```!X````````` +XM908````````"````(````/S_________;`8````````"````'P```/S_____ +XM____<08````````*````"0````,!````````@`8````````"````(````/S_ +XM________O08````````"````&0```/S_________T08````````"````&0`` +XM`/S_________/P<````````"````&P```/S_________=0<````````"```` +XM'P```/S_________>@<````````*````"0```!P!````````B0<````````" +XM````(````/S_________DP<````````"````'P```/S_________F`<````` +XM```*````"0```#H!````````IP<````````"````(````/S_________L0<` +XM```````"````'P```/S_________M@<````````*````"0```%@!```````` +XMQ0<````````"````(````/S_________2P@````````"````&0```/S_____ +XM____;@@````````"````&P```/S_________LP@````````*````"P`````` +XM````````N@@````````"````+0```/S_________R0@````````"````'P`` +XM`/S_________S@@````````*````"0```',!````````W0@````````"```` +XM(````/S_________YP@````````"````'P```/S_________[`@````````* +XM````"0```%@!````````^P@````````"````(````/S_________$0D````` +XM```"````+P```/S_________*0D````````"````)P```/S_________>@D` +XM```````"````,````/S_________N`D````````"````'P```/S_________ +XMO0D````````*````"0```)$!````````S`D````````"````(````/S_____ +XM____U@D````````"````'P```/S_________VPD````````*````"0```+D! +XM````````Z@D````````"````(````/S_________[PD````````*````"0`` +XM`*L!````````^PD````````"````(````/S_________,0H````````"```` +XM,@```/S_________5`H````````"````,P```/S_________:PH````````" +XM````-````/S_________E`H````````*````"0```-$!````````G@H````` +XM```"````(````/S_________MPH````````"````,0```/S_________YPH` +XM```````"````,0```/S_________0@L````````*````"0```+8````````` +XM:0L````````*````"0```*8`````````A@L````````*````"0```*X````` +XM````EPL````````*````"0```.,!````````H@L````````+````"0```.,! +XM````````JPL````````+````"0```.H!````````M`L````````+````"0`` +XM`/P!````````O0L````````+````"0````("````````X@L````````"```` +XM-0```/S_________\`L````````"````-@```/S_________(@P````````" +XM````,0```/S_________?PP````````"````)P```/S_________DPP````` +XM```+````"0```+8`````````RPP````````"````.````/S_________Z`P` +XM```````"````.0```/S__________PP````````"````&0```/S_________ +XM'0T````````"````.@```/S_________5`T````````*````"0```+8````` +XM````?@T````````"````)@```/S_________DPT````````"````'````/S_ +XM________N`T````````*````"0```*8`````````T@T````````*````"0`` +XM`*X`````````$0X````````"````.````/S_________*@X````````"```` +XM.0```/S_________/@X````````"````'````/S_________3@X````````" +XM````&0```/S_________:PX````````"````.@```/S_________FPX````` +XM```"````)P```/S_________W`X````````"````.P```/S_________]PX` +XM```````"````*P```/S_________`0\````````"````(P```/S_________ +XM$`\````````"````'P```/S_________%0\````````*````"0```(X````` +XM````)`\````````"````(````/S_________*0\````````"````(P```/S_ +XM________20\````````"````'P```/S_________3@\````````*````"0`` +XM`#\"````````70\````````"````(````/S_________9P\````````"```` +XM'P```/S_________;`\````````*````"0```","````````>P\````````" +XM````(````/S_________A0\````````"````'P```/S_________B@\````` +XM```*````"0```(,"````````F0\````````"````(````/S_________HP\` +XM```````"````'P```/S_________J`\````````*````"0```&T"```````` +XMMP\````````"````(````/S_________O`\````````*````"0```*L!```` +XM````Q@\````````"````*````/S_________T`\````````"````'P```/S_ +XM________U0\````````*````"0````@"````````Y`\````````"````(``` +XM`/S_________[@\````````"````'P```/S_________\P\````````*```` +XM"0```%4"`````````A`````````"````(````/S_________)A`````````" +XM````/````/S_________,1`````````"````/0```/S_________91`````` +XM```"````/````/S_________Q0````````"````/````/S_________BA0````````"```` +XM/0```/S_________UA0````````"````0P```/S_________-A4````````" +XM````0P```/S_________4!4````````"````,0```/S_________7!4````` +XM```"````-0```/S_________=!4````````"````0P```/S_________HA4` +XM```````"````0@```/S_________MQ4````````"````,0```/S_________ +XMP!4````````"````-0```/S_________U!4````````*````"0```+X"```` +XM````X!4````````"````*````/S_________YQ4````````"````/0```/S_ +XM________\14````````"````/@```/S_________)18````````"````*@`` +XM`/S_________0Q8````````"````1````/S_________9Q8````````"```` +XM'````/S_________>Q8````````"````.@```/S_________D18````````" +XM````10```/S_________JA8````````"````,P```/S_________VA8````` +XM```"````/P```/S_________Z18````````"````,P```/S_________$Q<` +XM```````"````'P```/S_________&!<````````*````"0````,!```````` +XM)Q<````````"````(````/S_________+!<````````*````"0```+`"```` +XM````-A<````````"````*````/S_________0!<````````"````'P```/S_ +XM________11<````````*````"0```)$!````````5!<````````"````(``` +XM`/S_________7A<````````"````'P```/S_________8Q<````````*```` +XM"0```#\"````````P`````````*````%@```/,%````````@``````````*````%@```#0#```` +XM````C0`````````*````%@```.4&````````E``````````*````%@```&<( +XM````````FP`````````*````%@```.(!````````H``````````*````%@`` +XM`'`&````````L``````````*````%@```/$'````````O0`````````*```` +XM%@```)@#````````P@`````````*````%@```(L%````````S0`````````* +XM````%@```*T!````````V``````````*````%@```#H&````````]``````` +XM```*````%@````0#````````_P`````````*````%@```-L!````````"@$` +XM```````*````%@```*\'````````%@$````````*````%@```'@$```````` +XM)`$````````*````%@```(P`````````.0$````````*````%@```#@"```` +XM````;`$````````*````%@```*4`````````>@$````````*````%@```)D$ +XM````````E@$````````*````%@```)P`````````I`$````````*````%@`` +XM`'T!````````L@$````````*````%@```/H#````````P`$````````*```` +XM%@```!0<````````*````%@```+H#````````E0<````````*````%@`` +XM`/H!````````HP<````````*````%@````@$````````L0<````````*```` +XM%@```*`!````````OP<````````*````%@```.,%````````S0<````````* +XM````%@```#T`````````VP<````````*````%@```!<$````````Z0<````` +XM```*````%@```,$&````````!@@````````*````%@```!X&````````%0@` +XM```````*````%@```(X!````````(0@````````*````%@```+$&```````` +XM+P@````````*````%@```(('````````/0@````````*````%@```,H$```` +XM````2P@````````*````%@```"T`````````:`@````````*````%@````D! +XM````````=@@````````*````%@```+8!````````A0@````````*````%@`` +XM`)H&````````D0@````````*````%@```+$&````````\`@````````*```` +XM%@```+\(````````_@@````````*````%@```"H'````````&@D````````* +XM````%@```%0!````````*`D````````*````%@```/X$````````-@D````` +XM```*````%@```)($````````1`D````````*````%@```"H(````````4@D` +XM```````*````%@```)\'````````=0D````````*````%@````D!```````` +XM@PD````````*````%@```+8!````````D@D````````*````%@````P"```` +XM````G@D````````*````%@```-L&````````K`D````````*````%@```,`' +XM````````PPD````````*````%@```!X&````````T@D````````*````%@`` +XM`-D`````````"`H````````*````%@```"H'````````%@H````````*```` +XM%@```#T`````````)`H````````*````%@```)D'````````,@H````````* +XM````%@```"4#````````3PH````````*````%@```,@#````````50H````` +XM```*````%@```,\`````````6PH````````*````%@```)\$````````80H` +XM```````*````%@```*$"````````9PH````````*````%@```*(&```````` +XM=@H````````*````%@```"<"````````A`H````````*````%@```.L#```` +XM````H0H````````*````%@```"<"````````KPH````````*````%@```.L# +XM````````S`H````````*````%@```"<"````````V@H````````*````%@`` +XM`.L#````````]PH````````*````%@```"<"````````!0L````````*```` +XM%@```.L#````````(@L````````*````%@```"<"````````,`L````````* +XM````%@```.L#````````1PL````````*````%@```-L&````````50L````` +XM```*````%@```,`'````````;`L````````*````%@```&(%````````>PL` +XM```````*````%@```$<"````````APL````````*````%@```%T!```````` +XME0L````````*````%@```+,$````````HPL````````*````%@```$`"```` +XM````VPL````````*````%@```)4&````````Z0L````````*````%@```,$# +XM````````]PL````````*````%@```%``````````!0P````````*````%@`` +XM`&X(````````$PP````````*````%@```!<'````````(0P````````*```` +XM%@```$H#````````+PP````````*````%@```+\!````````/0P````````* +XM````%@```)X%````````2PP````````*````%@```$L%````````60P````` +XM```*````%@```-X"````````9PP````````*````%@```$`(````````=0P` +XM```````*````%@```$(%````````@PP````````*````%@```/D'```````` +XMD0P````````*````%@```"X#````````GPP````````*````%@```"4$```` +XM````K0P````````*````%@```#<`````````NPP````````*````%@```&@$ +XM````````R@P````````*````%@```-<"````````V0P````````*````%@`` +XM`#\!````````Z`P````````*````%@```'(!````````]PP````````*```` +XM%@```)D'````````!@T````````*````%@```'('````````'`T````````* +XM````%@```'X(````````(PT````````!`````@``````````````*PT````` +XM```!`````@```'``````````:`T````````*````%@```#4%````````<`T` +XM```````!`````@```'``````````>`T````````!`````@```"8"```````` +XM@`T````````*````$@``````````````E`T````````*````$@```#D````` +XM````H@T````````*````$@```((`````````IPT````````*````%@```-,# +XM````````L@T````````*````$@```+@`````````S@T````````*````%@`` +XM`$0`````````U@T````````!`````@```#`"````````W@T````````!```` +XM`@```"P#````````Y@T````````*````$@```!0!````````^@T````````* +XM````$@```(D!````````"`X````````*````$@```-(!````````%@X````` +XM```*````$@````@"````````*PX````````*````%@````$$````````-@X` +XM```````*````$@```%$"````````.PX````````*````%@```&H#```````` +XM2`X````````*````%@````X&````````4`X````````!`````@```#`#```` +XM````6`X````````!`````@```)L#````````8`X````````*````$@```(<" +XM````````=`X````````*````$@```+\"````````>0X````````*````%@`` +XM`+$&````````A`X````````*````$@```/4"````````D@X````````*```` +XM$@```%$#````````F0X````````*````%@```%H&````````H0X````````! +XM`````@```*`#````````J0X````````!`````@```(D%````````L0X````` +XM```*````$@```)H#````````Q0X````````*````$@```#<$````````U`X` +XM```````*````$@```),$````````V0X````````*````%@```,$````````` +XMY`X````````*````$@```,D$````````_0X````````*````$@```/\$```` +XM````#`\````````*````$@```$@%````````(P\````````*````%@```)8! +XM````````*P\````````!`````@```)`%````````,P\````````!`````@`` +XM`(0&````````.P\````````*````$@```'X%````````30\````````*```` +XM$@```-X%````````7`\````````*````$@```$T&````````:P\````````* +XM````$@```)8&````````<`\````````*````%@````$$````````>P\````` +XM```*````$@```-\&````````@@\````````*````%@```/0$````````B@\` +XM```````!`````@```)`&````````D@\````````!`````@```,D'```````` +XMF@\````````*````$@```!4'````````K@\````````*````$@```$X'```` +XM````O0\````````*````$@```)<'````````S`\````````*````$@```,T' +XM````````T0\````````*````%@```+$&````````W`\````````*````$@`` +XM`!8(`````````Q`````````*````%@```+P"````````"Q`````````!```` +XM`@```-`'````````$Q`````````!`````@```/\(````````&Q`````````* +XM````$@```%\(````````+Q`````````*````$@```.@(````````/1`````` +XM```*````$@```#$)````````71`````````*````$@```&<)````````9!`` +XM```````*````%@```!8%````````!`````````!`````@```/\)````````@!`````````*````$@```"(*```` +XM````E!`````````*````$@```(,*````````HA`````````*````$@```,P* +XM````````IQ`````````*````%@```#("````````LA`````````*````$@`` +XM`.\*````````QQ`````````*````%@```"L$````````TA`````````*```` +XM$@```!(+````````V1`````````*````%@```.$`````````Y!`````````! +XM`````@`````*````````[!`````````!`````@```*(*````````]!`````` +XM```*````$@```$@+````````!Q$````````*````$@```-`+````````#!$` +XM```````*````%@```+$&````````%A$````````*````$@```"P,```````` +XM)1$````````*````$@```(@,````````-!$````````*````$@```.0,```` +XM````.A$````````*````%@```'D&````````11$````````!`````@```+`* +XM````````31$````````!`````@```-(*````````51$````````*````$@`` +XM`!H-````````:!$````````*````$@```%(-````````;1$````````*```` +XM%@```+$&````````=Q$````````*````$@```'4-````````AA$````````* +XM````$@```)@-````````C!$````````*````%@```.@!````````EQ$````` +XM```!`````@```.`*````````GQ$````````!`````@```!<+````````IQ$` +XM```````*````$@```+L-````````NA$````````*````$@```/,-```````` +XMOQ$````````*````%@```+$&````````R1$````````*````$@```!8.```` +XM````V!$````````*````$@```#D.````````WA$````````*````%@```!P` +XM````````[Q$````````*````%@```+$&````````^A$````````*````%@`` +XM``L`````````)1(````````*````%@```-0'````````,!(````````!```` +XM`@```"`+````````.!(````````!`````@```&`,````````0!(````````* +XM````$@```&\.````````4Q(````````*````$@```*@.````````6!(````` +XM```*````%@```+$&````````8A(````````*````$@```/$.````````9Q(` +XM```````*````%0``````````````>A(````````*````$@```&`/```````` +XMA!(````````!`````@```)8+````````C!(````````!`````@```/@+```` +XM````G!(````````!`````@```)8+````````I!(````````!`````@```-X+ +XM````````OA(````````*````%@```.4"````````VA(````````*````%@`` +XM`-@#````````Y1(````````*````%@```+$&````````!1,````````*```` +XM%@```/4#````````$!,````````*````%@````$$````````'1,````````* +XM````%@```&<"````````)!,````````!`````@```&`,````````+!,````` +XM```!`````@````80````````-!,````````*````$@```*D/````````1Q,` +XM```````*````$@```%H0````````5!,````````*````$@```*,0```````` +XM61,````````*````%@```+$&````````8Q,````````*````$@```/\0```` +XM````<1,````````*````$@```+H1````````A1,````````*````%@```/4# +XM````````E!,````````*````%@````$$````````GA,````````*````$@`` +XM`/`1````````IQ,````````*````%0```$``````````N1,````````*```` +XM%0```)``````````PA,````````*````$@```"82````````U!,````````* +XM````$@```&\2````````YA,````````*````$@```-X2````````[A,````` +XM```*````%@```'H"````````'10````````*````%@```-T(````````)10` +XM```````!`````@```!`0````````+10````````!`````@```.L0```````` +XM-10````````*````$@```!03````````1Q0````````*````$@```'03```` +XM````5A0````````*````$@```-`3````````9!0````````*````$@```"P4 +XM````````;10````````*````%0```&`!````````?10````````*````$@`` +XM`&(4````````C!0````````*````%0```)`!````````F!0````````*```` +XM$@```+X4````````H10````````*````$@```!H5````````J!0````````* +XM````%@```"H!````````UA0````````*````%@```+$&````````^A0````` +XM```*````%@```%P%````````!A4````````*````%@```!$'````````'14` +XM```````*````%@````$$````````,Q4````````*````%@```+@%```````` +XM6!4````````*````%@```#T'````````=!4````````*````%@```+$&```` +XM````@!4````````*````%@```-H$````````L!4````````*````%@```!$$ +XM````````O!4````````*````%@```"$"````````%!8````````*````%@`` +XM`!(!````````(18````````*````%@```'X%````````/18````````*```` +XM%@```,H$````````:18````````*````%@````$$````````?!8````````* +XM````%@```)`"````````F!8````````*````%@```+$&````````KQ8````` +XM```*````%@```'X`````````TA8````````*````%@````$$````````X!8` +XM```````*````%@```&4'````````Z!8````````!`````@```/`0```````` +XM\!8````````!`````@```-X7````````^!8````````*````$@```'85```` +XM````#!<````````*````$@```"<6````````&A<````````*````$@```(<6 +XM````````(Q<````````*````%0```.`!````````.1<````````*````%0`` +XM`$`"````````0A<````````*````$@```+T6````````2Q<````````*```` +XM$@````87````````9A<````````*````$@```$\7````````;Q<````````* +XM````$@```+X7````````>!<````````*````$@```"T8````````@1<````` +XM```*````$@```(D8````````FQ<````````*````%0```(`#````````JQ<` +XM```````*````$@```-(8````````NA<````````*````%0```+`#```````` +XMT!<````````*````%0```!`$````````V1<````````*````$@````@9```` +XM````XA<````````*````$@```#X9````````]1<````````*````$@```-L9 +XM`````````Q@````````*````$@```%T:````````#!@````````*````$@`` +XM`-\:````````*!@````````*````%0```#`%````````.A@````````*```` +XM%0```'`%````````0Q@````````*````$@```(<;````````5A@````````* +XM````$@```%4<````````8Q@````````!`````@````T4````````:Q@````` +XM```!`````@```#$4````````A1@````````!`````@```!T4````````C1@` +XM```````!`````@```#$4````````FA@````````*````$@```)X<```````` +XMI1@````````*````%0```-`%````````LA@````````*````%0```#`&```` +XM````NQ@````````*````$@```.<<````````Q!@````````*````$@```&D= +XM````````S1@````````*````%0```+`&````````V1@````````*````$@`` +XM`+(=````````YQ@````````*````%@```&X$````````]!@````````*```` +XM%@```$\"````````Q0`````````!`````@``````````````'``````````* +XM````$```````````````(``````````!`````@``````````````-``````` +XM```*````$```````````````.``````````!`````@```'``````````7``` +XM```````*````$```````````````8``````````!`````@```#`"```````` +XMC``````````*````$```````````````D``````````!`````@```#`#```` +XM````K``````````*````$```````````````L``````````!`````@```*`# +XM````````Y``````````*````$```````````````Z``````````!`````@`` +XM`)`%````````#`$````````*````$```````````````$`$````````!```` +XM`@```)`&````````-`$````````*````$```````````````.`$````````! +XM`````@```-`'````````9`$````````*````$```````````````:`$````` +XM```!`````@`````)````````C`$````````*````$```````````````D`$` +XM```````!`````@`````*````````O`$````````*````$``````````````` +XMP`$````````!`````@```+`*````````W`$````````*````$``````````` +XM````X`$````````!`````@```.`*````````_`$````````*````$``````` +XM``````````(````````!`````@```"`+````````)`(````````*````$``` +XM````````````*`(````````!`````@```&`,````````9`(````````*```` +XM$```````````````:`(````````!`````@```!`0````````C`(````````* +XM````$```````````````D`(````````!`````@```/`0````````(``````` +XM```*`````@``````````````.``````````*`````@```'``````````6``` +XM```````*`````@```#`"````````@``````````*`````@```#`#```````` +XMF``````````*`````@```*`#````````R``````````*`````@```)`%```` +XM````Z``````````*`````@```)`&````````"`$````````*`````@```-`' +XM````````,`$````````*`````@`````)````````4`$````````*`````@`` +XM```*````````>`$````````*`````@```+`*````````D`$````````*```` +XM`@```.`*````````J`$````````*`````@```"`+````````R`$````````* +XM`````@```&`,``````````(````````*`````@```!`0````````(`(````` +XM```*`````@```/`0````````!@`````````*````!@``````````````!@`` +XM```````*````!@``````````````$``````````!`````@`````````````` +X` +Xend +END-of-sections.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.sh new file mode 100755 index 0000000000..bc9c90dd8e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-onlydebug-1/strip-onlydebug-1.sh @@ -0,0 +1,6 @@ +# $Id: strip-onlydebug-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-onlydebug-1 tc/strip-onlydebug-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} --only-keep-debug -o sections.o.1 sections.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/in/strip-unneeded-1.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/in/strip-unneeded-1.in.shar new file mode 100644 index 0000000000..4c9f000b4e --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/in/strip-unneeded-1.in.shar @@ -0,0 +1,1129 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# sections.o.uu +# +echo x - sections.o.uu +sed 's/^X//' >sections.o.uu << 'END-of-sections.o.uu' +Xbegin 644 sections.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` +XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@U(QT98`````$B+A\@```!(B49@2(N'R````$B) +XM,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D +XM\$B)7"3@28G\2(EL).A,B6PD^$B#[&A(BV]82(GF2(M]$.@`````2(7`#X0* +XM`0``2,=$)!``````2,=$)#`!````2(M%(,=$)`0#````2,=$)`@`````2,=$ +XM)#@`````QT0D+`````#'1"0H`````$B)1"082(M]$.@`````2(7`2(G##X3. +XM````0?9$)&00#X2&````2(M%*$B)YDB)1"0@2(M]$.@`````A<`/A,,```!( +XMQP,!````2(M%&$B)0PA(BT4H2,=#$`````#'0R`!````QT,D`0```$B)0QA( +XMBWT0Z`````!)BWPD($B)QN@`````A<`/A)8```!(BUPD2$B+;"103(MD)%A, +XMBVPD8$B#Q&C#9F:09I!(BU4H2(M]&$B#ZA!(C7<02(E5*.@`````Z5S___^_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!( +XMB<*_1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_ +XM_____^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:005152(G] +XM4TB#[$!(BY_`````2(7;=')(BWL02(GFZ`````!(AY(BW@0Z`````")1"0HD$B+>Q!(B>;H`````(7`=$-(BUM82(7;=8[H```` +XM`(7`=4](@\1`6UU!7,/'1"0H`````.O+O______H`````+X`````2(G"OT8` +XM```QP.@`````O______H`````+X`````2(G"OT8````QP.@`````BQ@`=!E(B>Y(B=](BVPD$$B+7"0(2(/$&.D`````2(G?O@````#H```` +XM`$B)W[X`````Z`````!(B=^^`````.@`````O@````!(B=_H`````.NQ9F:0 +XM9I!!5D%528G]05154TB#[$!(BZ_`````2(7M=")!N`````#K"4B+;5A(A>UT +XM$4B+=0"Y"@```$R)Q_SSIG7F28N=D````$B%VP^$!@$``&9FD$F+?2#H```` +XM`$B%P$F)Q`^$^P```+YX````OP$```#H`````$B%P$B)P@^$_@```$B+`TR) +XMYTB)`DB+12!(B4(@2(M#$,="2/_____'0DP`````2,=""`````!,B6(02(E" +XM*$B+16!(B6I82(E"8$B+16!(B1!(C4)82(E%8.@`````2(7`2(G"#X2P```` +XM2,<``0```$C'0!``````2(GF2(M#"$R)YTB)0@A(BT,0QT(@`0```,=")`$` +XM``!(B4(8Z`````!(A<`/A(T```#'1"0$`0```$B+,TR)[^A=_O__2(GF3(GG +XMZ`````"%P`^$A0```$B+6QA(A=L/A?W^__](@\1`6UU!7$%=05[#O______H +XM`````+X`````2(G"OT8````QP.@`````O@````"_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````!F9F:0 +XM9F:054B)_5-(@^P(BU=4A=)T!TB#?Q@`=&PQV^M+9F:09I!(BWT0Z`````!( +XMA9(B=_H`````$B%P`^$KP```$B+1"1`2(GN3(GG2(D$)$B+1"1(2(E$ +XM)`A(BT0D4$B)1"002(M$)%A(B40D&$B+1"1@2(E$)"!(BT0D:$B)1"0H2(M$ +XM)'!(B40D,$B+1"1X2(E$)#CH^/O__TB)YDB)W^@`````A3ID````$B+:R!,.>4/@J@```"+>TR% +XM_W4?2(MS.#'23(GE2HU,)O](BQ!(B>;H`````$B%P'1O2(M#($B)YDB) +XM1"082(M#*$B)1"0@2(M[$.@`````A;H +XM`````$B%P`^$E````+YX````OP$```#H`````$B%P$B)PP^$M0```$B+1"0H +XMN@$```!(B4,@2(N-P````$B%R708,<"#>5`!2(M)6(/0`$B%R77P@\`!2&/0 +XM2(M](+D!````O@X```#H`````$B%P$B)0RAT24B)WDB)[TC'0S@$````QT-, +XM`````,=#4`$```#H6/;__TB)V$B#Q$A;7<.______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````,<#H`````)!!54&)U4%428G\54B)]5-(@^P(2(N?@````$B%VW4+ +XMZR9(BUM`2(7;=!U(BS-(B>_H`````(7`=>A(@\0(2(G86UU!7$%=PS';187M +XM=.N_2````.@`````2(7`=#9(B<.Z2````#'V2(G'Z`````!(B2M(QT-````` +XM`$F+A"2(````2(D82(U#0$F)A"2(````ZZ:^`````+]&````Z`````!F9F:0 +XM9F9FD&9FD&9FD#'22(/L".@`````,=)(A[SIG3CNP````!)B>1(QP0D`````$C'1"0(`````$C'1"00 +XM`````$C'1"08`````$C'1"0@`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G? +XMZ`````!(B=Y(B<)(B>_H`````(7`==A!BT5@@^@!@_@!=PJX`0```.E!____ +XM28-]0``/A#3___\QTDB)[DR)[^@`````08M=0(7;=`Y(A_HZ/W__X7`=:2+1"1$@_@)#X2M```` +XM@_@$#X2D````0;T`````N0H```!,B>;\3(GO\Z8/A20!``!(BUU82(M$)%A( +XMB4,@2(M](.@`````2(7`2(E#$`^$#@(``$R)]^@`````A<")0T@/A-T!``#\ +XMN0H```!,B>9,B>_SI@^%,@$``/R_`````+D(````3(GF\Z9U"(--9!!(B5U( +XM_+\`````N0@```!,B>;SIG4$2(E=4$B)WDB)[^@/\O__Z>K^__]$BVPD;$6% +XM[0^$3O___TB+?1A(C;0D@````.@`````A<`/A*T!```QVT6)[4B+?1A(B=[H +XM`````$B%P$B)PP^$Q@```$B)W^@`````23G%==M(B>9(B=_H`````$B%P`^$ +XMC0$``(L4)$B+M"2`````2(M]&.@`````2(7`2(G(````2(GOZ)W\__^% +XMP`^%5?[__^G"_O__OG@```"_`0```.@`````2(7`#X03`0``2(G#3(D@3(EP +XM"$B+1"182(G>2(GO2(E#($B+1"1@2(E#*$B+1"1P2(E#.(M$)$1(B4-`Z``` +XM``")0TSID?[__TB+4Q!(BW,(2(GO2(L+Z`````#IMO[__^@`````A<`/A-/] +XM__^)Q^@`````O@````!(B<*_1@```#'`Z`````#H`````(7`==Q(@<28```` +XM6UU!7$%=05Y!7\.______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +XM1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +XM`+]&````Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_____ +XM_^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:054B-+#=32(/L +XM"$@Y[W-[2(G[ZSB+!0````"%P'5S2(LU`````(M&#(/H`87`B48,#XB6```` +XM2(L&Q@`*2(/``4B)!DB#PP%(.>MT/@^V$X32=,&+!0````"%P'5'2(LU```` +XM``^^^HM&#(/H`87`B48,>$%(BP9(@\,!0(@X2(/``4@YZTB)!G7"2(/$"%M= +XMPTB+-0````"_"@```.@`````ZY](BS4`````#[[ZZ`````#KCCM&*'P(@/H* +XM9F:0=;+H`````.EW____OPH```#H`````.EH____9F:09I!!5T%6055!5%53 +XM2('LF````$B)?"083(NOP````$V%[71;2(V$)(````!(B40D".L)38MM6$V% +XM[71#08M%4(7`=>])BUT`OP````"Y"````/Q(B=[SIG4W2(M4)!CV0F1`=UUO4B!Q)@```!;74%<05U!7D%?P[\` +XM````N0@```!(B=[SIG2X_+\`````N0H```!(B=[SI@^$>____TB+5"08@WI@ +XM`0^$CP```$B+?"082(G>Z![Y__^%P`^$,0,``#';13'_2,=$)#@`````ZS]F +XM9I!F9I!(BWPD.$@#>QCH`````$F)QTV%_P^$V0,``$B+5"0X2(MS"$F-/!=( +XMBU,8Z`````!(BT,82`%$)#A)BWT(2(G>Z`````!(AQCH`````$F)Q^NM28-]0`D/A6;___])BWT(2(UT)$#H`````$B%P`^$ +XMU`0``$B+1"08]D!D$`^%C@,``$B+@,````!(AU(QT0D*`````"`.`!T%4B#Q0%*C40]`$@Y +XM1"0@2(EL)"AWYD@Y1"0@#X2@`0``3(MT)#!,`W0D.$R+9"0P33GF=R'I+@$` +XM`&:028U<)`%,B>?H`````$R-)`--.>8/AA(!``!,B?Y,B>?H`````(7`===( +XMBT0D*$Z-?#@!3#E\)"`/AW3___])BW4`2(M\)!CH]/;__X7`#X50`0``2(M$ +XM)#A!QT54`0```$F)12A,B>_H`````$F+=0!(BWPD&#'2Z`````!(A<`/A/O\ +XM__^+0#"%P`^$\/S__TF+?1A(A?]T#4F+=2A(A?8/APCHN/O__TF+?0A(B=[H`````$B%P$B)PW7?Z`````"%P`^%EP(``(L%```` +XM`(7`#X5=`0``2(LU`````(M&#(/H`87`B48,#X@U`@``2(L&Q@`*2(/``4B) +XM!NEP_/__28MU`$B+?"08Z"'V__^%P`^$/O___^D:_O__2(GJ3(G^3(GWZ``` +XM``!(BU0D.$B-1!4`2(M4)##&!!``2(/``4B)1"0XZ<[^__](BWPD&$B)WNBH +XM]?__A<`/A/7^___IM?S__^CV^O__9F:09F:0Z53___](BWPD,$@#?"0X2(GJ +XM3(G^Z`````!(`6PD..F:_O__28MU`$B+?"08,=+H`````$R+8!A,B>?H```` +XM`$B+?"0P2`-\)#A(B<),B>9(B4Q[44QY$4Q]DF+?0A,B?;H`````$B%P$F)Q@^$7P$``$B-E"2`````,?9, +XMB??H`````$@[1"0(#X4D`0``2(M4)!B+G"2,````2(M"4$B+>`CH`````$B) +XMQDB+1"082(G:2(MX&.@`````2(7`2(G-````2(M\)!CH`````(7`=(1( +XMBU0D&(-Z%`%T/[]`````Z`````!(A$F)Q$B+A"2`````28D$)$B+A"2( +XM````28E$)`CI2?___[\*````Z`````#I/OK__[\@````Z`````!(A6P````,`````!6-_````!PBZ +XM````!PCN````"+H````#``````7HGP````,``````B^O````"0`````0`D8R +XM`0``"@`````"1S(!```"(P`*``````)(5`````(C"``'"#0````)`````)@" +XM9EP"```+7W```F50````"(W`*``````)\W@(```(C +XM=`H``````GWN`@```B-W"U]L8@`"@`D!```"(W@*``````*#5`````,CB`$* +XM``````*$_@````,CD`$`#`%4````;`(```VM``````<(7`(```P!5````(P" +XM```-K0````WB````#50`````!PAR`@``#`'^````K`(```VM````#?X````- +XM5``````'")("```,`50```#,`@``#:T````-Z`````U4``````<(L@(```X` +XM`````0<(T@(```\T````[@(``!"J`````@`/-````/X"```0J@```````P`` +XM```"A3@!```""`4``````P`````&)LP````#``````8JS`````\T````-@,` +XM`!"J````#P`1"`9Z6P,```H`````!GL0`P```B,`"@`````&?!L#```"(P0` +XM`P`````&?38#```#``````%D@,```(C"``#``````>&%04``!)%;&8` +XM""90!0``#@`````!`P`````()V$%```.``````$3!`@V``8``!0``````!0` +XM`````10``````A0``````Q0`````!!0`````!10`````!A0`````!Q0````` +XM"!0`````"10`````"A0`````"Q0`````#!0`````#10`````#A0`````#Q0` +XM````$!0`````$10`````$A0`````$Q0`````%!0`````%10`````%A0````` +XM%P`#``````A/9P4``!$("'@B!@``"@`````(>*T&```"(P``"0````!`"&BM +XM!@``"@`````(;-<````"(P`*``````AMK0````(C"`H`````"&[7`````B,0 +XM"@`````(;]<````"(Q@*``````AP``8```(C(`H`````"'%F`````B,D"@`` +XM```(=K,&```"(R@*``````AW9@````(C,`H`````"'@+!@```B,X``<((@8` +XM``<(5@4```,`````"'DB!@```P`````)+FH$```#``````DP"@4```,````` +XM"3(Z!0``$0@*)/P&```*``````HD)0<```(C```)`````!`*(24'```*```` +XM``HBZ`````(C``H`````"B3E!@```B,(``<(_`8``!$("C9"!P``"@`````* +XM-O<'```"(P``"0````!("BCW!P``"@`````**>@````"(P`*``````HJZ``` +XM``(C"`H`````"BOH`````B,0"@`````*+.@````"(Q@+861D``HN5`````(C +XM(`H`````"B]4`````B,D"@`````*,%0````"(R@*``````HQ5`````(C+`H` +XM````"C)4`````B,P"@`````*,U0````"(S0*``````HT5`````(C.`H````` +XM"C8K!P```B-```<(0@<``!$("C\4"```"@`````*/UD(```"(P``"0`````@ +XM"CI9"```"@`````*.^(````"(P`*``````H\X@````(C"`H`````"CWS```` +XM`B,0"@`````*/_T'```"(Q@`!P@4"```$1`*4H0(```*``````I28`D```(C +XM``H`````"E)F"0```B,(``D`````>`I#8`D```H`````"D3H`````B,`"VES +XM``I%LP8```(C"`MO@`*6=<````"(P@+;7-Z``I:UP````(C$`H` +XM````"EO7`````B,8"@`````*750````"(R`*``````I?D0D```(C*`H````` +XM"F"Z"0```B,X``<(T0D``!,$"H1M"@``%```````%``````!%``````"%``` +XM```#%``````$`!$0"IB2"@``"@`````*F$`*```"(P`*``````J8D@H```(C +XM"``'"$`*```1$`J9O0H```H`````"IGW!P```B,`"@`````*F;T*```"(P@` +XM!PCW!P``$1`*FN@*```*``````J:60@```(C``H`````"IKH"@```B,(``<( +XM60@``!$0"IP3"P``"@`````*G"4'```"(P`*``````J<$PL```(C"``'""4' +XM```1$`J>/@L```H`````"IXE!P```B,`"@`````*GA,+```"(P@`$1`*H&,+ +XM```*``````J@8`D```(C``H`````"J!F"0```B,(`!$("J)Z"P``"@`````* +XMHF`)```"(P``"0````#8"F85#0``"@`````*9^@````"(P`*``````IJ5``` +XM``(C"`H`````"FM4`````B,,"VEE8P`*;50````"(Q`+;V5C``IN5`````(C +XM%`ME:6X`"F\5#0```B,8"@`````*50````"(S`*``````IZ5`````(C-`H````` +XM"GM4`````B,X"@`````*?%0````"(SP*``````I]5`````(C0`H`````"GY4 +XM`````B-$"@`````*@&`)```"(T@*``````J!8`D```(C4`H`````"H)@"0`` +XM`B-8"@`````*BD8*```"(V`*``````J35`````(C9`H`````"I8R`0```B-H +XM"@`````*F&T*```"(W`*``````J9F`H```,C@`$*``````J:PPH```,CD`$* +XM``````J<[@H```,CH`$*``````J>&0L```,CL`$*``````J@/@L```,CP`$* +XM``````JB8PL```,CT`$`!PA%!0``%0`````!XP$````````````````````` +XM`G<(8`T``!9E8W```>)@#0```5461@"0```5$` +XM!PAZ"P``&`$``````5X#`0``````````````````````````Q@T``!EE8W`` +XM`5T#8`T````````:P"8`D````````@$@````_H````'A(``!"J````!``' +XM".@````F``````$X`50``````````````````````````````+T2```C96-P +XM``$W8`T````````D``````$WZ``````````K`````'\2```E``````%P`@$``````````````````````````*<4 +XM```99``!;P+H`````````!ES>@`!;P+S`````````!IC``%Q`N@````````` +XM.NT3`````````74"AQ0``#L*%````````"W_$P```#7M$P````````%W`CL* +XM%````````#O_$P``````````/``````!I0$!`4L5```Y96-P``&D`6`-```Y +XM@`````/``````!*`(!`2`6```Y96-P``$G`F`-```Y&```+9D5```MC14``#8`````-Z,5````````-Z\5````````,+L5```P +XMQQ4``#?1%0```````##=%0``-^<5````````-_$5````````,/L5```O!Q8` +XM``.1T'XP$Q8``#4@%@````````$N`BT\%@``+3(6```V`````#=(%@`````` +XM`#!3%@``,%T6```W:!8`````````````/GL6```````````````````````` +XM`9H!H!@``"V7%@``+8P6```N`````````````````````#>B%@`````````` +XM-:X6`````````9L!+;P6```V`````#?&%@```````#?1%@```````#7M$P`` +XM``````&,`CL*%````````"W_$P```````#\``````HH6%````0%```````*@ +XM`50````!`0!^!````@"X`````0'[#@H``0$!`0````$O=7-R+VEN8VQU9&4` +XM+W5S7!E7!E6%)*U45)-ZX(+#A(,&"`4@@24CP#%D)NMQ@A8`Z4!`B0!`PDK`W=5`PF; +XM`W=5`PE_""!RA7J`@'*!"!4#>E5,"'((/`CTZ`A;`PP(C4B0"%D(,`@\"!Y( +XM20@>20-8[P/'?M,##@A_`W@K.`ARQ@@\".4#L0$(1PB=.DA97TB.CH`#$<4# +XMO'X(<58#T`%_")E62@.E?@@=`YX!",4#*0C%",$#<0C%`\%^X0C,`X($`B@! +XM($18G00"`Y-^_?X$`0/J`<6.=`0"`Y%^"#G&!`$#Z@$Y!`(#EGY'!`$#Z@%Q +XM!`(#EGXY!`$#Z@$Y,6T(+00"`Y%^_<@$`0-K",7]6`/D`+<#G'_ACX,(5ZJ` +XM`W:-`R2-`V(('0,*_0A<`[1^X0/:`P(K`?Z0"%8#=XT(F4H*2!F +XM86EL960Z("5S`&YO="!E;F]U9V@@;65M;W)Y`"YD96)U9P`N9VYU+FQI;FMO +XM;F-E+G=I+@`N;&EN90`N&!HP%C02.`X\"````````%``` +XM```````!>E(``7@0`0,,!PB0`0``%````!P`````````<``````````````` +XM'````#0`````````M@$```!*@P6,`U$.<(T"A@0````D````5`````````#\ +XM`````$(.$$$.&(8#C`)$#B!$#F"#!```````%````'P`````````:P````!. +XM#B"#`X8"+````)0`````````Z0$```!"#A!"#AB-`XX"10X@00XH00XP1`YP +XM@P:&!8P$````'````,0`````````]`````!!#A"&`D0.&$0.((,#```<```` +XMY``````````Y`0```$J&!(,%5`ZP`8T"C`,``"0````$`0```````"\!```` +XM0@X00@X800X@00XH1`YP@P6&!(P#C0(<````+`$```````#_`````$$.$(8" +XM1`X81`Y@@P,``"0```!,`0```````*(`````0@X0C0)%#AB,`T0.((8$1`XH +XM1`XP@P44````=`$````````B`````$8.$``````4````C`$````````W```` +XM`$0.$``````<````I`$```````!``0```%J,`X,%C0*&!$<.8````#0```#$ +XM`0```````*8#````0@X01PX80@X@0@XH00XPA@:,!8T$C@./`DD..$<.T`&# +XM!P``````'````/P!````````VP````!!#A"&`D4.&$0.((,#```T````'`(` +XM``````#N!@```$(.$$(.&$(.($(.*$$.,$$..$<.T`&#!X8&C`6-!(X#CP(` +XM`````'``````````BP`````````"`'<(BP`````````F`@````````,`=_`` +XM`````````````````````'``````````E@`````````!`%66`````````($! +XM`````````0!00` +XM``````"W!`````````$`42\%````````.04````````!`%$````````````` +XM````````[0,```````#[!`````````$`7``%````````B04````````!`%P` +XM````````````````````D`4```````"1!0````````(`=PB1!0```````)4% +XM`````````@!W$)4%````````F04````````"`'<8F04```````"$!@`````` +XM``(`=R``````````````````````D`4```````"K!0````````$`5:L%```` +XM````&08````````!`%89!@```````!H&`````````0!5&@8```````!*!@`` +XM``````$`5DL&````````A`8````````!`%8`````````````````````J04` +XM```````8!@````````$`4QH&````````208````````!`%-+!@```````(0& +XM`````````0!3`````````````````````+P%````````OP4````````!`%"_ +XM!0````````(&`````````0!1&@8```````!5!@````````$`40`````````` +XM```````````1!@```````!H&`````````0!0:08```````!P!@````````$` +XM4`````````````````````"0!@```````*X&`````````@!W"*X&```````` +XMR0<````````#`'>P`0````````````````````"0!@```````+0&```````` +XM`0!5M`8```````!?!P````````$`7&\'````````R0<````````!`%P````` +XM````````````````D`8```````"Y!@````````$`5+D&````````P08````` +XM```!`%4`````````````````````D`8```````#!!@````````$`4<$&```` +XM````3P<````````!`%-O!P```````,D'`````````0!3```````````````` +XM`````)`&````````P08````````!`%+!!@```````%<'`````````0!6;P<` +XM``````#)!P````````$`5@````````````````````#0!P```````-('```` +XM`````@!W"-('````````U`<````````"`'<0U`<```````#5!P````````(` +XM=QC5!P```````-8'`````````@!W(-8'````````V@<````````"`'0T```````"P#0````````$`7,0-````````Q@T````````! +XM`%S>#0```````.`-`````````0!<]@T```````"0#@````````$`7*X.```` +XM````Z`X````````!`%P`#P```````#P/`````````0!<0P\```````"[#P`` +XM``````$`7,H/````````!A`````````!`%P`````````````````````WPP` +XM``````!`#P````````$`7D,/````````!A`````````!`%X````````````` +XM````````#0\````````4#P````````$`4"\/````````0P\````````!`%`` +XM````````````````````<@X```````!U#@````````$`4'4.````````@PX` +XM```````!`%1##P```````$T/`````````0!4`````````````````````-\, +XM````````<`T````````!`%/V#0```````*L.`````````0!3``\````````Y +XM#P````````$`4T,/````````?P\````````!`%.[#P````````80```````` +XM`0!3`````````````````````-\,````````[`P````````!`%`'#P`````` +XM`!0/`````````0!0`````````````````````!`0````````$1`````````" +XM`'<($1`````````6$`````````(`=Q`6$````````!H0`````````@!W&!H0 +XM````````ZQ`````````"`'<@`````````````````````!`0````````=Q`` +XM```````!`%6:$````````*T0`````````0!5M!````````"^$`````````$` +XM5=P0````````X1`````````!`%4`````````````````````$!`````````U +XM$`````````$`5%P0````````=!`````````!`%2:$````````*@0```````` +XM`0!4M!````````"[$`````````$`5``````````````````````B$``````` +XM`)\0`````````0!3H1````````#K$`````````$`4P`````````````````` +XM```D$````````'00`````````0!4FA````````"H$`````````$`5+00```` +XM````NQ`````````!`%3<$````````.80`````````0!4```````````````` +XM`````"00````````-1`````````!`%1<$````````*@0`````````0!4M!`` +XM``````"[$`````````$`5,40````````UQ`````````!`%0````````````` +XM````````)!````````"M$`````````$`5;00````````OA`````````!`%7% +XM$````````-<0`````````0!5W!````````#A$`````````$`50`````````` +XM``````````#P$````````/(0`````````@!W"/(0````````]!`````````" +XM`'<0]!````````#V$`````````(`=QCV$````````/@0`````````@!W(/@0 +XM````````^1`````````"`'%P`````` +XM``$`70````````````````````"U$0```````,(1`````````0!0?!(````` +XM``"[$@````````$`4/H5`````````Q8````````!`%`````````````````` +XM````@A8```````"%%@````````$`4(46````````E18````````!`%18%P`` +XM`````&(7`````````0!4`````````````````````"$1````````=A$````` +XM```!`%9_$0```````%<3`````````0!6WA,```````#,%`````````$`5OL4 +XM````````)14````````!`%9$%0```````-X7`````````0!6```````````` +XM`````````"$1````````>!$````````!`%Q_$0```````)03`````````0!< +XMWA,```````#,%`````````$`7/L4````````6!4````````!`%R4%0`````` +XM`-X7`````````0!<`````````````````````"$1````````?!$````````! +XM`%Y_$0```````(H3`````````0!>WA,```````#,%`````````$`7OL4```` +XM````WA<````````!`%X`````````````````````$A<````````7%P`````` +XM``$`59L7````````G1<````````!`%"=%P```````,07`````````0!5```` +XM`````````````````+T1````````PA$````````!`%0#%0````````@5```` +XM`````0!4`````````````````````%@5````````8!4````````!`%"_%0`` +XM`````,05`````````0!0`````````````````````"$1`````````1,````` +XM```#`)'H?@$3````````!A,````````!`%4&$P```````*L5`````````P"1 +XMZ'ZK%0```````+05`````````0!5M!4```````#.%0````````,`D>A^SA4` +XM``````#3%0````````$`5=,5````````WA<````````#`)'H?@`````````` +XM```````````A$0```````'81`````````0!6?Q$```````!M%0````````$` +XM5FT5````````>!4````````!`%&4%0```````!<6`````````0!6U!8````` +XM``#C%@````````$`5A`7````````6!<````````!`%8````````````````` +XM````(1$```````!^$0````````$`7W\1````````8!,````````!`%]@$P`` +XM`````)X3`````````0!0GA,````````E%0````````$`7R45````````.A4` +XM```````!`%`Z%0```````-X7`````````0!?`````````````````````"$1 +XM````````>!$````````!`%Q_$0```````)<3`````````0!%0```````*85```````` +XM`0!5JQ4````````:%@````````$`7-06````````XQ8````````!`%P0%P`` +XM`````%@7`````````0!<`````````````````````"$1````````-A$````` +XM```!`%-M$0```````'41`````````0!3S!$```````!$$@````````$`4[L2 +XM````````I1,````````!`%.Z$P```````$D4`````````0!3>10```````#[ +XM%`````````$`4Q45````````6YC7W-E8W1I;VYS`&(0``!I;G-EPX```````!O +XM#@```````'(.````````4@X```````!;#@```````$(.````````1PX````` +XM```T#@```````#H.````````+@X````````Q#@`````````````````````` +XM```````U$````````%,0````````W!````````#K$``````````````````` +XM``````````!W$````````(<0````````Q1````````#<$````````)40```` +XM````F!````````"+$````````)(0`````````````````````````````!(1 +XM````````(1$````````Z%P```````-X7````````XQ8````````0%P`````` +XM``,6````````U!8```````!/$@```````,`2```````````````````````` +XM`````%T2````````P!(```````#-%P```````-X7````````O!<```````#` +XM%P```````+(7````````NA<```````"=%P```````*@7````````F1<````` +XM``";%P```````(`7````````E!<```````!B%P```````'87````````1!<` +XM``````!8%P```````.T6````````$!<```````"N%@```````-06```````` +XME18```````"D%@```````(46````````BQ8```````!_%@```````((6```` +XM````5Q8```````!>%@```````$<6````````4A8````````O%@```````#46 +XM````````*18````````L%@````````,6````````'18````````````````` +XM````````````M1$```````#@$0```````/L4````````%14````````````` +XM````````````````X!$```````!$$@```````"L7````````.A<````````E +XM%0```````.05````````L10```````#[%````````,`2````````!10````` +XM````````````````````````X!$```````!$$@```````"L7````````.A<` +XM``````#3%0```````.05````````$P```````+$3 +XM````````NA,````````K$P```````*43````````'1,````````A$P`````` +XM``X3````````&1,````````&$P````````D3````````]!(````````!$P`` +XM`````,`2````````YA(`````````````````````````````X!$```````!$ +XM$@```````-,5````````Y!4```````#`$@```````,T2```````````````` +XM`````````````/$1````````&1(```````#3%0```````.05````````Q1(` +XM``````#-$@```````"L2````````-A(````````E$@```````"@2```````` +XM`````````````````````#$4````````L10````````0%P```````"L7```` +XM````U!8```````#C%@```````.05`````````Q8````````5%0```````"45 +XM`````````````````````````````#$4````````6!0````````7%P`````` +XM`"L7````````U!8```````#C%@```````!45````````)14```````!Q%``` +XM`````+$4````````:A0```````!L%````````&04````````9Q0````````` +XM````````````````````CA0```````"Q%````````-06````````XQ8````` +XM````````````````````````16QF-C1?061D<@!D8F=?F4`7V9L86=S`&5?=F5RF4`1T5L +XM9E]%:&1R`&1?6U?;&ES=`!S96-?861D`&-O<'E?9&%T80!C;W!Y`&5?96YT@!S='%H7V9I6UT86(`:7-?F5?=`!D7W1Y<&4`14Q&7U1? +XM4UE-`$5L9E]4>7!E`'-E9U]L:7-T`&9L86=S`%]?=6EN=#8T7W0`16QF-C1? +XM2&%L9@!S96-T:6]NF4`:6YF;70`14Q&7U1?0EE410!D7V)U9@!S:7IE`$5,1E]47U=/4D0` +XM;6]D:69Y7W-E8W1I;VX`14Q&7U1?4TA$4@!C;W!Y7W-H9'(`<'-E=61O`'-H +XM7V]F9G-E=`!A9&1O<'0`:6YS97)T7W-H=&%B`$5,1E]47T%$1%(`7V5X=')A +XM`'-E=%]S:'-T5]C;VYT96YT`'9?;61A=`!%;&9? +XM1&%T80!C;VYT96YT`&1?9FQA9W,`95]T>7!E`'9?6UT86(`+G-T`!M96UM;W9E`&5L9E]E`!U<&1A=&5?5]D871A`&5L9E]G971D871A`&-O<'E?5]C;VYT96YT`&-R +XM96%T95]S>6UT86(`;65M8W!Y`'-TP,````````"````)````/S_________@P,````````*````"0```*X````` +XM````B`,````````"````)````/S_________C0,````````*````"0```+8` +XM````````E0,````````"````)````/S_________O0,````````*````"0`` +XM`+8`````````]0,````````"````)@```/S_________$`0````````"```` +XM)P```/S_________;P0````````"````&@```/S_________LP0````````" +XM````&0```/S_________V@0````````"````&P```/S_________!@4````` +XM```"````'P```/S_________"P4````````*````"0```,``````````&@4` +XM```````"````(````/S_________'P4````````*````"0```-@````````` +XM*P4````````"````*````/S_________-04````````"````'P```/S_____ +XM____.@4````````*````"0```!X`````````204````````"````(````/S_ +XM________4P4````````"````'P```/S_________6`4````````*````"0`` +XM`.4`````````9P4````````"````(````/S_________<04````````"```` +XM'P```/S_________=@4````````*````"0```#<`````````A04````````" +XM````(````/S_________M04````````"````&@```/S__________@4````` +XM```"````*@```/S_________"P8````````"````(P```/S_________408` +XM```````"````'P```/S_________5@8````````*````"0```!X````````` +XM908````````"````(````/S_________;`8````````"````'P```/S_____ +XM____<08````````*````"0````,!````````@`8````````"````(````/S_ +XM________O08````````"````&0```/S_________T08````````"````&0`` +XM`/S_________/P<````````"````&P```/S_________=0<````````"```` +XM'P```/S_________>@<````````*````"0```!P!````````B0<````````" +XM````(````/S_________DP<````````"````'P```/S_________F`<````` +XM```*````"0```#H!````````IP<````````"````(````/S_________L0<` +XM```````"````'P```/S_________M@<````````*````"0```%@!```````` +XMQ0<````````"````(````/S_________2P@````````"````&0```/S_____ +XM____;@@````````"````&P```/S_________LP@````````*````"P`````` +XM````````N@@````````"````+0```/S_________R0@````````"````'P`` +XM`/S_________S@@````````*````"0```',!````````W0@````````"```` +XM(````/S_________YP@````````"````'P```/S_________[`@````````* +XM````"0```%@!````````^P@````````"````(````/S_________$0D````` +XM```"````+P```/S_________*0D````````"````)P```/S_________>@D` +XM```````"````,````/S_________N`D````````"````'P```/S_________ +XMO0D````````*````"0```)$!````````S`D````````"````(````/S_____ +XM____U@D````````"````'P```/S_________VPD````````*````"0```+D! +XM````````Z@D````````"````(````/S_________[PD````````*````"0`` +XM`*L!````````^PD````````"````(````/S_________,0H````````"```` +XM,@```/S_________5`H````````"````,P```/S_________:PH````````" +XM````-````/S_________E`H````````*````"0```-$!````````G@H````` +XM```"````(````/S_________MPH````````"````,0```/S_________YPH` +XM```````"````,0```/S_________0@L````````*````"0```+8````````` +XM:0L````````*````"0```*8`````````A@L````````*````"0```*X````` +XM````EPL````````*````"0```.,!````````H@L````````+````"0```.,! +XM````````JPL````````+````"0```.H!````````M`L````````+````"0`` +XM`/P!````````O0L````````+````"0````("````````X@L````````"```` +XM-0```/S_________\`L````````"````-@```/S_________(@P````````" +XM````,0```/S_________?PP````````"````)P```/S_________DPP````` +XM```+````"0```+8`````````RPP````````"````.````/S_________Z`P` +XM```````"````.0```/S__________PP````````"````&0```/S_________ +XM'0T````````"````.@```/S_________5`T````````*````"0```+8````` +XM````?@T````````"````)@```/S_________DPT````````"````'````/S_ +XM________N`T````````*````"0```*8`````````T@T````````*````"0`` +XM`*X`````````$0X````````"````.````/S_________*@X````````"```` +XM.0```/S_________/@X````````"````'````/S_________3@X````````" +XM````&0```/S_________:PX````````"````.@```/S_________FPX````` +XM```"````)P```/S_________W`X````````"````.P```/S_________]PX` +XM```````"````*P```/S_________`0\````````"````(P```/S_________ +XM$`\````````"````'P```/S_________%0\````````*````"0```(X````` +XM````)`\````````"````(````/S_________*0\````````"````(P```/S_ +XM________20\````````"````'P```/S_________3@\````````*````"0`` +XM`#\"````````70\````````"````(````/S_________9P\````````"```` +XM'P```/S_________;`\````````*````"0```","````````>P\````````" +XM````(````/S_________A0\````````"````'P```/S_________B@\````` +XM```*````"0```(,"````````F0\````````"````(````/S_________HP\` +XM```````"````'P```/S_________J`\````````*````"0```&T"```````` +XMMP\````````"````(````/S_________O`\````````*````"0```*L!```` +XM````Q@\````````"````*````/S_________T`\````````"````'P```/S_ +XM________U0\````````*````"0````@"````````Y`\````````"````(``` +XM`/S_________[@\````````"````'P```/S_________\P\````````*```` +XM"0```%4"`````````A`````````"````(````/S_________)A`````````" +XM````/````/S_________,1`````````"````/0```/S_________91`````` +XM```"````/````/S_________Q0````````"````/````/S_________BA0````````"```` +XM/0```/S_________UA0````````"````0P```/S_________-A4````````" +XM````0P```/S_________4!4````````"````,0```/S_________7!4````` +XM```"````-0```/S_________=!4````````"````0P```/S_________HA4` +XM```````"````0@```/S_________MQ4````````"````,0```/S_________ +XMP!4````````"````-0```/S_________U!4````````*````"0```+X"```` +XM````X!4````````"````*````/S_________YQ4````````"````/0```/S_ +XM________\14````````"````/@```/S_________)18````````"````*@`` +XM`/S_________0Q8````````"````1````/S_________9Q8````````"```` +XM'````/S_________>Q8````````"````.@```/S_________D18````````" +XM````10```/S_________JA8````````"````,P```/S_________VA8````` +XM```"````/P```/S_________Z18````````"````,P```/S_________$Q<` +XM```````"````'P```/S_________&!<````````*````"0````,!```````` +XM)Q<````````"````(````/S_________+!<````````*````"0```+`"```` +XM````-A<````````"````*````/S_________0!<````````"````'P```/S_ +XM________11<````````*````"0```)$!````````5!<````````"````(``` +XM`/S_________7A<````````"````'P```/S_________8Q<````````*```` +XM"0```#\"````````P`````````*````%@```/,%````````@``````````*````%@```#0#```` +XM````C0`````````*````%@```.4&````````E``````````*````%@```&<( +XM````````FP`````````*````%@```.(!````````H``````````*````%@`` +XM`'`&````````L``````````*````%@```/$'````````O0`````````*```` +XM%@```)@#````````P@`````````*````%@```(L%````````S0`````````* +XM````%@```*T!````````V``````````*````%@```#H&````````]``````` +XM```*````%@````0#````````_P`````````*````%@```-L!````````"@$` +XM```````*````%@```*\'````````%@$````````*````%@```'@$```````` +XM)`$````````*````%@```(P`````````.0$````````*````%@```#@"```` +XM````;`$````````*````%@```*4`````````>@$````````*````%@```)D$ +XM````````E@$````````*````%@```)P`````````I`$````````*````%@`` +XM`'T!````````L@$````````*````%@```/H#````````P`$````````*```` +XM%@```!0<````````*````%@```+H#````````E0<````````*````%@`` +XM`/H!````````HP<````````*````%@````@$````````L0<````````*```` +XM%@```*`!````````OP<````````*````%@```.,%````````S0<````````* +XM````%@```#T`````````VP<````````*````%@```!<$````````Z0<````` +XM```*````%@```,$&````````!@@````````*````%@```!X&````````%0@` +XM```````*````%@```(X!````````(0@````````*````%@```+$&```````` +XM+P@````````*````%@```(('````````/0@````````*````%@```,H$```` +XM````2P@````````*````%@```"T`````````:`@````````*````%@````D! +XM````````=@@````````*````%@```+8!````````A0@````````*````%@`` +XM`)H&````````D0@````````*````%@```+$&````````\`@````````*```` +XM%@```+\(````````_@@````````*````%@```"H'````````&@D````````* +XM````%@```%0!````````*`D````````*````%@```/X$````````-@D````` +XM```*````%@```)($````````1`D````````*````%@```"H(````````4@D` +XM```````*````%@```)\'````````=0D````````*````%@````D!```````` +XM@PD````````*````%@```+8!````````D@D````````*````%@````P"```` +XM````G@D````````*````%@```-L&````````K`D````````*````%@```,`' +XM````````PPD````````*````%@```!X&````````T@D````````*````%@`` +XM`-D`````````"`H````````*````%@```"H'````````%@H````````*```` +XM%@```#T`````````)`H````````*````%@```)D'````````,@H````````* +XM````%@```"4#````````3PH````````*````%@```,@#````````50H````` +XM```*````%@```,\`````````6PH````````*````%@```)\$````````80H` +XM```````*````%@```*$"````````9PH````````*````%@```*(&```````` +XM=@H````````*````%@```"<"````````A`H````````*````%@```.L#```` +XM````H0H````````*````%@```"<"````````KPH````````*````%@```.L# +XM````````S`H````````*````%@```"<"````````V@H````````*````%@`` +XM`.L#````````]PH````````*````%@```"<"````````!0L````````*```` +XM%@```.L#````````(@L````````*````%@```"<"````````,`L````````* +XM````%@```.L#````````1PL````````*````%@```-L&````````50L````` +XM```*````%@```,`'````````;`L````````*````%@```&(%````````>PL` +XM```````*````%@```$<"````````APL````````*````%@```%T!```````` +XME0L````````*````%@```+,$````````HPL````````*````%@```$`"```` +XM````VPL````````*````%@```)4&````````Z0L````````*````%@```,$# +XM````````]PL````````*````%@```%``````````!0P````````*````%@`` +XM`&X(````````$PP````````*````%@```!<'````````(0P````````*```` +XM%@```$H#````````+PP````````*````%@```+\!````````/0P````````* +XM````%@```)X%````````2PP````````*````%@```$L%````````60P````` +XM```*````%@```-X"````````9PP````````*````%@```$`(````````=0P` +XM```````*````%@```$(%````````@PP````````*````%@```/D'```````` +XMD0P````````*````%@```"X#````````GPP````````*````%@```"4$```` +XM````K0P````````*````%@```#<`````````NPP````````*````%@```&@$ +XM````````R@P````````*````%@```-<"````````V0P````````*````%@`` +XM`#\!````````Z`P````````*````%@```'(!````````]PP````````*```` +XM%@```)D'````````!@T````````*````%@```'('````````'`T````````* +XM````%@```'X(````````(PT````````!`````@``````````````*PT````` +XM```!`````@```'``````````:`T````````*````%@```#4%````````<`T` +XM```````!`````@```'``````````>`T````````!`````@```"8"```````` +XM@`T````````*````$@``````````````E`T````````*````$@```#D````` +XM````H@T````````*````$@```((`````````IPT````````*````%@```-,# +XM````````L@T````````*````$@```+@`````````S@T````````*````%@`` +XM`$0`````````U@T````````!`````@```#`"````````W@T````````!```` +XM`@```"P#````````Y@T````````*````$@```!0!````````^@T````````* +XM````$@```(D!````````"`X````````*````$@```-(!````````%@X````` +XM```*````$@````@"````````*PX````````*````%@````$$````````-@X` +XM```````*````$@```%$"````````.PX````````*````%@```&H#```````` +XM2`X````````*````%@````X&````````4`X````````!`````@```#`#```` +XM````6`X````````!`````@```)L#````````8`X````````*````$@```(<" +XM````````=`X````````*````$@```+\"````````>0X````````*````%@`` +XM`+$&````````A`X````````*````$@```/4"````````D@X````````*```` +XM$@```%$#````````F0X````````*````%@```%H&````````H0X````````! +XM`````@```*`#````````J0X````````!`````@```(D%````````L0X````` +XM```*````$@```)H#````````Q0X````````*````$@```#<$````````U`X` +XM```````*````$@```),$````````V0X````````*````%@```,$````````` +XMY`X````````*````$@```,D$````````_0X````````*````$@```/\$```` +XM````#`\````````*````$@```$@%````````(P\````````*````%@```)8! +XM````````*P\````````!`````@```)`%````````,P\````````!`````@`` +XM`(0&````````.P\````````*````$@```'X%````````30\````````*```` +XM$@```-X%````````7`\````````*````$@```$T&````````:P\````````* +XM````$@```)8&````````<`\````````*````%@````$$````````>P\````` +XM```*````$@```-\&````````@@\````````*````%@```/0$````````B@\` +XM```````!`````@```)`&````````D@\````````!`````@```,D'```````` +XMF@\````````*````$@```!4'````````K@\````````*````$@```$X'```` +XM````O0\````````*````$@```)<'````````S`\````````*````$@```,T' +XM````````T0\````````*````%@```+$&````````W`\````````*````$@`` +XM`!8(`````````Q`````````*````%@```+P"````````"Q`````````!```` +XM`@```-`'````````$Q`````````!`````@```/\(````````&Q`````````* +XM````$@```%\(````````+Q`````````*````$@```.@(````````/1`````` +XM```*````$@```#$)````````71`````````*````$@```&<)````````9!`` +XM```````*````%@```!8%````````!`````````!`````@```/\)````````@!`````````*````$@```"(*```` +XM````E!`````````*````$@```(,*````````HA`````````*````$@```,P* +XM````````IQ`````````*````%@```#("````````LA`````````*````$@`` +XM`.\*````````QQ`````````*````%@```"L$````````TA`````````*```` +XM$@```!(+````````V1`````````*````%@```.$`````````Y!`````````! +XM`````@`````*````````[!`````````!`````@```*(*````````]!`````` +XM```*````$@```$@+````````!Q$````````*````$@```-`+````````#!$` +XM```````*````%@```+$&````````%A$````````*````$@```"P,```````` +XM)1$````````*````$@```(@,````````-!$````````*````$@```.0,```` +XM````.A$````````*````%@```'D&````````11$````````!`````@```+`* +XM````````31$````````!`````@```-(*````````51$````````*````$@`` +XM`!H-````````:!$````````*````$@```%(-````````;1$````````*```` +XM%@```+$&````````=Q$````````*````$@```'4-````````AA$````````* +XM````$@```)@-````````C!$````````*````%@```.@!````````EQ$````` +XM```!`````@```.`*````````GQ$````````!`````@```!<+````````IQ$` +XM```````*````$@```+L-````````NA$````````*````$@```/,-```````` +XMOQ$````````*````%@```+$&````````R1$````````*````$@```!8.```` +XM````V!$````````*````$@```#D.````````WA$````````*````%@```!P` +XM````````[Q$````````*````%@```+$&````````^A$````````*````%@`` +XM``L`````````)1(````````*````%@```-0'````````,!(````````!```` +XM`@```"`+````````.!(````````!`````@```&`,````````0!(````````* +XM````$@```&\.````````4Q(````````*````$@```*@.````````6!(````` +XM```*````%@```+$&````````8A(````````*````$@```/$.````````9Q(` +XM```````*````%0``````````````>A(````````*````$@```&`/```````` +XMA!(````````!`````@```)8+````````C!(````````!`````@```/@+```` +XM````G!(````````!`````@```)8+````````I!(````````!`````@```-X+ +XM````````OA(````````*````%@```.4"````````VA(````````*````%@`` +XM`-@#````````Y1(````````*````%@```+$&````````!1,````````*```` +XM%@```/4#````````$!,````````*````%@````$$````````'1,````````* +XM````%@```&<"````````)!,````````!`````@```&`,````````+!,````` +XM```!`````@````80````````-!,````````*````$@```*D/````````1Q,` +XM```````*````$@```%H0````````5!,````````*````$@```*,0```````` +XM61,````````*````%@```+$&````````8Q,````````*````$@```/\0```` +XM````<1,````````*````$@```+H1````````A1,````````*````%@```/4# +XM````````E!,````````*````%@````$$````````GA,````````*````$@`` +XM`/`1````````IQ,````````*````%0```$``````````N1,````````*```` +XM%0```)``````````PA,````````*````$@```"82````````U!,````````* +XM````$@```&\2````````YA,````````*````$@```-X2````````[A,````` +XM```*````%@```'H"````````'10````````*````%@```-T(````````)10` +XM```````!`````@```!`0````````+10````````!`````@```.L0```````` +XM-10````````*````$@```!03````````1Q0````````*````$@```'03```` +XM````5A0````````*````$@```-`3````````9!0````````*````$@```"P4 +XM````````;10````````*````%0```&`!````````?10````````*````$@`` +XM`&(4````````C!0````````*````%0```)`!````````F!0````````*```` +XM$@```+X4````````H10````````*````$@```!H5````````J!0````````* +XM````%@```"H!````````UA0````````*````%@```+$&````````^A0````` +XM```*````%@```%P%````````!A4````````*````%@```!$'````````'14` +XM```````*````%@````$$````````,Q4````````*````%@```+@%```````` +XM6!4````````*````%@```#T'````````=!4````````*````%@```+$&```` +XM````@!4````````*````%@```-H$````````L!4````````*````%@```!$$ +XM````````O!4````````*````%@```"$"````````%!8````````*````%@`` +XM`!(!````````(18````````*````%@```'X%````````/18````````*```` +XM%@```,H$````````:18````````*````%@````$$````````?!8````````* +XM````%@```)`"````````F!8````````*````%@```+$&````````KQ8````` +XM```*````%@```'X`````````TA8````````*````%@````$$````````X!8` +XM```````*````%@```&4'````````Z!8````````!`````@```/`0```````` +XM\!8````````!`````@```-X7````````^!8````````*````$@```'85```` +XM````#!<````````*````$@```"<6````````&A<````````*````$@```(<6 +XM````````(Q<````````*````%0```.`!````````.1<````````*````%0`` +XM`$`"````````0A<````````*````$@```+T6````````2Q<````````*```` +XM$@````87````````9A<````````*````$@```$\7````````;Q<````````* +XM````$@```+X7````````>!<````````*````$@```"T8````````@1<````` +XM```*````$@```(D8````````FQ<````````*````%0```(`#````````JQ<` +XM```````*````$@```-(8````````NA<````````*````%0```+`#```````` +XMT!<````````*````%0```!`$````````V1<````````*````$@````@9```` +XM````XA<````````*````$@```#X9````````]1<````````*````$@```-L9 +XM`````````Q@````````*````$@```%T:````````#!@````````*````$@`` +XM`-\:````````*!@````````*````%0```#`%````````.A@````````*```` +XM%0```'`%````````0Q@````````*````$@```(<;````````5A@````````* +XM````$@```%4<````````8Q@````````!`````@````T4````````:Q@````` +XM```!`````@```#$4````````A1@````````!`````@```!T4````````C1@` +XM```````!`````@```#$4````````FA@````````*````$@```)X<```````` +XMI1@````````*````%0```-`%````````LA@````````*````%0```#`&```` +XM````NQ@````````*````$@```.<<````````Q!@````````*````$@```&D= +XM````````S1@````````*````%0```+`&````````V1@````````*````$@`` +XM`+(=````````YQ@````````*````%@```&X$````````]!@````````*```` +XM%@```$\"````````Q0`````````!`````@``````````````'``````````* +XM````$```````````````(``````````!`````@``````````````-``````` +XM```*````$```````````````.``````````!`````@```'``````````7``` +XM```````*````$```````````````8``````````!`````@```#`"```````` +XMC``````````*````$```````````````D``````````!`````@```#`#```` +XM````K``````````*````$```````````````L``````````!`````@```*`# +XM````````Y``````````*````$```````````````Z``````````!`````@`` +XM`)`%````````#`$````````*````$```````````````$`$````````!```` +XM`@```)`&````````-`$````````*````$```````````````.`$````````! +XM`````@```-`'````````9`$````````*````$```````````````:`$````` +XM```!`````@`````)````````C`$````````*````$```````````````D`$` +XM```````!`````@`````*````````O`$````````*````$``````````````` +XMP`$````````!`````@```+`*````````W`$````````*````$``````````` +XM````X`$````````!`````@```.`*````````_`$````````*````$``````` +XM``````````(````````!`````@```"`+````````)`(````````*````$``` +XM````````````*`(````````!`````@```&`,````````9`(````````*```` +XM$```````````````:`(````````!`````@```!`0````````C`(````````* +XM````$```````````````D`(````````!`````@```/`0````````(``````` +XM```*`````@``````````````.``````````*`````@```'``````````6``` +XM```````*`````@```#`"````````@``````````*`````@```#`#```````` +XMF``````````*`````@```*`#````````R``````````*`````@```)`%```` +XM````Z``````````*`````@```)`&````````"`$````````*`````@```-`' +XM````````,`$````````*`````@`````)````````4`$````````*`````@`` +XM```*````````>`$````````*`````@```+`*````````D`$````````*```` +XM`@```.`*````````J`$````````*`````@```"`+````````R`$````````* +XM`````@```&`,``````````(````````*`````@```!`0````````(`(````` +XM```*`````@```/`0````````!@`````````*````!@``````````````!@`` +XM```````*````!@``````````````$``````````!`````@`````````````` +X` +Xend +END-of-sections.o.uu +exit + diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.err b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.eval b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.eval new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.eval @@ -0,0 +1 @@ +0 diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.sh b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.sh new file mode 100644 index 0000000000..909ad09ab2 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-1/strip-unneeded-1.sh @@ -0,0 +1,6 @@ +# $Id: strip-unneeded-1.sh 2081 2011-10-27 04:28:29Z jkoshy $ +inittest strip-unneeded-1 tc/strip-unneeded-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} --strip-unneeded -o sections.o.1 sections.o" work true +rundiff true diff --git a/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-2/in/strip-unneeded-2.in.shar b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-2/in/strip-unneeded-2.in.shar new file mode 100644 index 0000000000..9d05c99386 --- /dev/null +++ b/contrib/elftoolchain/tests/custom/elfcopy/tc/strip-unneeded-2/in/strip-unneeded-2.in.shar @@ -0,0 +1,2302 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# elfcopy.uu +# +echo x - elfcopy.uu +sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' +Xbegin 755 elfcopy +XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` +XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` +XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` +XM!0````````````````!``````````$```````$QR````````3'(````````` +XM`!````````$````&````8'(```````!@@```````*!Z4```````H'I0 +XM``````"@`0```````*`!````````"``````````$````!````.`!```````` +XMX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +XM````1'(```````!$```````````````.````&P```!$````B````'````!4` +XM```#````&````````````````````"T``````````````"<````J````.``` +XM`"\`````````0````"`````)```````````````P````0@```#P```!&```` +XM%P```#L````_````$``````````````````````````````````````````` +XM````2`(``!(```#L%D```````)````````````$``!(```#\%D```````(<` +XM````````+P```!(````,%T```````!0(``!(```#L%T```````(<& +XM````````I@```!(```#\%T```````#L`````````*0$``!(````,&$`````` +XM`!D!````````SP```!(````<&$```````"0`````````$P(``!(````L&$`` +XM`````(@`````````0`(``!$`%P#8?E````````@`````````<0(``!(````\ +XM&$```````$P`````````^@(``!(```!,&$```````"D`````````<0```!(` +XM``!<&$```````#4`````````#0```!(```!L&$```````&D!````````?``` +XM`!(```!\&$```````&H`````````E`(``!$`%P"P?E````````0````````` +XMH0(``!(```",&$```````*T"````````G@$``!(```"<&$```````!8````` +XM````5P(``!$`$`!@`!G96QF7V=E=&-L87-S`&=E;&9?9V5T`!G96QF7W5P9&%T95]R96QA`&5L9E]E;F0`9V5L9E]G971S +XM:&1R`&=E;&9?9V5T<&AD<@!E;&9?97)R;7-G`&=E;&9?9V5T'-C;@!G96QF7W5P9&%T95]E:&1R +XM`&=E;&9?=7!D871E7W!H9'(`96QF7VMI;F0`7TIV7U)E9VES=&5R0VQA0!?7W-T9&5R`!M86QL;V,`;W!T87)G`&=E='!R;V=N86UE`')E;F%M90!C86QL;V,` +XM96YV:7)O;@!F<')I;G1F`&]P=&EN9`!?7W!R;V=N86UE`&9E'U0```````' +XM````)```````````````@'U0```````'````)0``````````````B'U0```` +XM```'````)@``````````````D'U0```````'````)P``````````````F'U0 +XM```````'````*```````````````H'U0```````'````*0`````````````` +XMJ'U0```````'````*@``````````````L'U0```````'````*P`````````` +XM````N'U0```````'````+```````````````P'U0```````'````+0`````` +XM````````R'U0```````'````+@``````````````T'U0```````'````+P`` +XM````````````V'U0```````'````,```````````````X'U0```````'```` +XM,0``````````````Z'U0```````'````,@``````````````\'U0```````' +XM````-```````````````^'U0```````'````-0```````````````'Y0```` +XM```'````-@``````````````"'Y0```````'````-P``````````````$'Y0 +XM```````'````.```````````````&'Y0```````'````.0`````````````` +XM('Y0```````'````.@``````````````*'Y0```````'````.P`````````` +XM````,'Y0```````'````/```````````````.'Y0```````'````/0`````` +XM````````0'Y0```````'````/@``````````````2'Y0```````'````/P`` +XM````````````4'Y0```````'````0```````````````6'Y0```````'```` +XM00``````````````8'Y0```````'````0@``````````````:'Y0```````' +XM````1```````````````<'Y0```````'````1@``````````````>'Y0```` +XM```'````2```````````````@'Y0```````'````20``````````````B'Y0 +XM```````'````2@``````````````D'Y0```````'````2P`````````````` +XMF'Y0```````'````3```````````````H'Y0```````'````3@`````````` +XM````J'Y0```````'````3P``````````````2(/L".A?!0``Z#I2``!(@\0( +XMPP#_-8YE$`#_)9!E$`"0D)"0_R6.91``:`````#IX/____\EAF40`&@!```` +XMZ=#_____)7YE$`!H`@```.G`_____R5V91``:`,```#IL/____\E;F40`&@$ +XM````Z:#_____)69E$`!H!0```.F0_____R5>91``:`8```#I@/____\E5F40 +XM`&@'````Z7#_____)4YE$`!H"````.E@_____R5&91``:`D```#I4/____\E +XM/F40`&@*````Z4#_____)39E$`!H"P```.DP_____R4N91``:`P```#I(/__ +XM__\E)F40`&@-````Z1#_____)1YE$`!H#@```.D`_____R4691``:`\```#I +XM\/[___\E#F40`&@0````Z>#^____)09E$`!H$0```.G0_O___R7^9!``:!(` +XM``#IP/[___\E]F00`&@3````Z;#^____)>YD$`!H%````.F@_O___R7F9!`` +XM:!4```#ID/[___\EWF00`&@6````Z8#^____)=9D$`!H%P```.EP_O___R7. +XM9!``:!@```#I8/[___\EQF00`&@9````Z5#^____);YD$`!H&@```.E`_O__ +XM_R6V9!``:!L```#I,/[___\EKF00`&@<````Z2#^____):9D$`!H'0```.D0 +XM_O___R6>9!``:!X```#I`/[___\EEF00`&@?````Z?#]____)8YD$`!H(``` +XM`.G@_?___R6&9!``:"$```#IT/W___\E?F00`&@B````Z<#]____)79D$`!H +XM(P```.FP_?___R5N9!``:"0```#IH/W___\E9F00`&@E````Z9#]____)5YD +XM$`!H)@```.F`_?___R569!``:"<```#I9C$`!H-0```.F0_/___R7>8Q``:#8```#I@/S___\E +XMUF,0`&@W````Z7#\____)#[____)89C$`!H00```.G0^____R5^8Q`` +XM:$(```#IP/O___\E=F,0`&A#````Z;#[____)6YC$`!H1````.F@^____R5F +XM8Q``:$4```#ID/O__P````!!5$R-9PA54XL?2&/#A=M(C6S'$$B)+6UC$`!^ +XM.DB+5PA(A=)T,4B)%>-6$``/M@*$P'0C2(/"`3PO2(L%SU80`$@/1,)(B07$ +XM5A``#[8"2(/"`83`=>&XH'I0`$B%P'0K2(GWZ"/___^_.&E``.@9____Z`#[ +XM__^)WTB)ZDR)YNBK!P``B3&!;%B +XM$``!2(/$",-F9F:09F9FD$B#/2A@$```=!:X`````$B%P'0,OV!\4`!)B<-! +XM_^.0\\.0D)"0D)"0D)"0D)"0D$B#[`A(BPU=8A``OY%I0`"Z#0```+X!```` +XMZ&W]__^_0````.C3_?__9F9FD&9FD$B#[`A(BPTM8A``OX!L0`"Z,P```+X! +XM````Z#W]__^_0````.BC_?__9F9FD&9FD$B#[`A(BPW]81``OY]I0`"Z#P`` +XM`+X!````Z`W]__^_0````.AS_?__9F9FD&9FD$B);"383(E\)/A(B?U(B5PD +XMT$R)9"3@28G73(EL).A,B70D\$B![-@```!(A?9(B70D"`^$H`0``$B+?"0( +XM,?8QP.CE_/__@_C_08G'!```387_#X1)`P``,<"Z[0$``+X"`@``3(G_ +XM13'MZ+G\__^#^/]!B<0/A)\$```QTKX%````1(GWZ"[\__](A_H8"T``$B)[^BH&@``BT5H@_@"=!.#^`1T#DB#O=`````` +XM#X23`@``@V5LWXM--(7)#X4*`@``]D5L$`^%\P$``$B)[^AL'@``2(M]($B- +XM="00Z)KY__^%P`^$Y@(``$B)[^@.#0``2(GOZ,8.``!(BWT@2(UT)!#HE/?_ +XM_TB%P`^$H0(``$B)[^B7%0``2(GO2(G#Z$P4``!(BT,@2(E$)#B+52R%TGXF +XM2(M](+D!````N@$```"^!````.B@^/__2(7`2(E$)#`/A%<#``!(BWT@2(UT +XM)!#H%/G__X7`#X1@`@``BT4LA$`"Z'@`` +XM`+X!````O[AL0`#HL?G__TV%_P^$OP```$2)]^@`^?__1(GGZ/CX__](BYPD +XMJ````$B+K"2P````3(ND)+@```!,BZPDP````$R+M"3(````3(N\)-````!( +XM@<38````PX--;`'I)O[__[_4:4``Z(WV__](A_H/OG__X/X_T&)Q`^$,P(``+[M`0`` +XMB_H@_;__X/``0^$/`$``$R)[^BB^?__Z17___](B>_HJ2T``.D` +XM_O__2(GOZ&P.``#IZ?W__TB)Q^B;^?__2(UX#DF)Q.@/^?__2(7`2(G'#X0' +XM`@``28G%3(GB2(G>2(G'Z,+V__]+C40L_X`X+TB-4`%T"$B-4`+&0`$O2+YE +XM8W`N6%A86,=""%A86%C&0@P`2(DRZ1G___^#36P"Z07]__](@[W```````^% +XM7_W__^E>_?__OJ]I0`"_1@```#'`Z%+V__](BU0D"+[%:4``OTH````QP.B< +XM^/__O______HPO7__[XG:D``2(G"OT$````QP.@>]O__3(GZOL5I0`"_2@`` +XM`#'`Z&KX__^______^B0]?__OEEJ0`!(B<*_1@```#'`Z.SU__^______^AR +XM]?__OMIJ0`!(B<*_1@```#'`Z,[U__](BTPD"$R)ZKY":T``OTH````QP.@5 +XM^/__O______H._7__[XG:D``2(G"OT8````QP.B7]?__O______H'?7__[ZT +XM:D``2(G"OT8````QP.AY]?__O______H__3__[YS:D``2(G"OT8````QP.A; +XM]?__O______HX?3__[Z):D``2(G"OT8````QP.@]]?__O______HP_3__[X0 +XM:T``2(G"OT8````QP.@?]?__3(GJO@1J0`"_2@```#'`Z&OW__^______^B1 +XM]/__OOAJ0`!(B<*_1@```#'`Z.WT__^^]FE``+]&````,<#H//?__[[,:D`` +XMOT8```#H+??__[ZA:D``OT$````QP.B\]/__OMMI0`!`MT8QP.@-]___D$%7 +XM28GW059!B?Z_`0```$%505154TB![)@```#HB_7__X7`#X0?"```O_````#H +XMN?;__TB%P$F)Q`^$MP8``#'VNO````!(B$))``````````2<>$)*``````````2<>$)+``````````28F$))@` +XM``!)C80DH````$G'A"3``````````$G'A"30`````````$G'A"3@```````` +XM`$F)A"2H````28V$)+````!!QT0D#`````!!QT0D"`````!)B80DN````$F- +XMA"3`````28F$),@```!)C80DT````$F)A"38````28V$).````!)B80DZ``` +XM`.B6]O__0;A9:T``2(7`N08```!,#T7`N&%K0`#\2(G'38D$)$R)QO.F#Y?" +XM#Y+`13'M.,(/A!4$``"X=&M``+D$````3(G&_$B)Q_.F#X20`@``13'`N?H&2@``.GX_O__9F9FD$B+-<%8$`"Z +XM`0```$R)Y^@<$```1(M(-$6%R0^%100``,=`+`$```!!QT0D2`$```#IOO[_ +XM_TB+-8M8$`!,B>?H.R@``.FJ_O__0<=$)&@$````Z9S^__](BSUI6!``OCT` +XM``#H\_'__TB%P$F)Q0^$+`0``+\@````Z/WS__](ALK +XM'318$`"->P%(8__HW?/__TB%P$B)10`/A,L#``!(BS456!``2&/;2(G'2(G: +XM28/%`>B'\?__2(M%`$B-="003(GOQ@08`.CR\?__@\`!#X3/`P``2(M\)%A( +XMB7T0Z(OS__](A_HD?+__TB%P$B)PP^$K`,` +XM`$B+51!(BWT(2(G!O@$```#HW'1"0$`````,=$)`@````` +XM13'M,=NZAFM``$R)_D2)]^CJ\/__@_C_#X2'`0``@^A6@_@:=@?HV/3__^O8 +XMB&M``+Y^:T``,<#HPN[__S'_Z"OR__](B=_H@_'__X7`#X3^_O__ +XMOL!K0`"_00```#'`Z#KR__]!BWPD#(7_=%6+%6]6$`!!.=9T"(U"`D$YQGX+ +XMZ$WT__^+%5=6$`!(8\)(C0S%`````(U"`3'203G&28LT#W\73(GGZ%;T__], +XMB>?H*O+__S'_Z+/Q__]*BU0Y".OB08M$)`A!B40D#.N?@_AOD`^$@0(```^/ +XM^P$``(/X9)!T!8/X9W5/0<=$)&@"````13'`N8!R4`"Z9VM``$R)_D2)]^A$ +XM\/__@_C_#X1D`@``@_A3=-%_M(/X2V9FD&:0#X0)`@``#X_+`0``@_@"D`^$ +XM+0(``.@U\___9F:09I#KKD0[-9=5$``/A$@!``"+!"0+1"0$"T0D"`G8#X3Z +XM````BT0D!(7`=!I!QT0D1`$```#'!"0`````,=O'1"0(`````(L$)(M4)`A% +XMA>U!B5PD0$&)1"0X08E4)#P/A*(```!)BX0DH````$B%P'0DBSPDB7@DBU0D +XM"(E8,(E0*(M\)`1(B6@8B7@T2(M`0$B%P'7W__[[;:4``OT8```#H%O#__[[;:4``OT8````QP.@%\/__Z`3R +XM___IKO[__[X@;4``OT`````QP.B*[?__OJ)K0`"_00```#'`Z-GO__],B>J^ +XML&M``+]!````,<#HQ>___X/X<`^$$/[__X/X#^%*0#X4P_O__2(LUNU,0`+H!````3(GGZ!8+``#'0#0!```` +XM0<=$)$0!````Z<']__](BS624Q``3(GGZ$(C``#IK?W__TB+-7Y3$`!,B>?H +XMOB(``.F9_?__3(LM:E,0`.F-_?__0<=$)&@$````9F9FD.E[_?__08M$)&B% +XMP'4)0<=$)&@!````08M$)`R%P'4*08M$)`A!B40D#$0[-3]3$`!T5HLM-U,0 +XM`$$Y[@^.^/S__TACQ4F-',=(BS-,B>I,B>>#Q0%(@\,(Z#+Q__]$.?5UYNG2 +XM_/__O_____]F9I#HY^O__[[8;$``2(G"OT8````QP.A#[/__Z'+P___KHTB+ +XME^````!(A=)T'TB+1B!(.T(@U(QT98 +XM`````$B+A^@```!(B49@2(N'Z````$B),$B-1EA(B8?H````BT9,AO__TB%P`^$"@$``$C' +XM1"00`````$C'1"0P`0```$B+12#'1"0$`P```$C'1"0(`````$C'1"0X```` +XM`,=$)"P`````QT0D*`````!(B40D&$B+?1#HBNK__TB%P$B)PP^$S@```$'V +XM1"1L$`^$A@```$B+12A(B>9(B40D($B+?1#H_>W__X7`#X3#````2,<#`0`` +XM`$B+11A(B4,(2(M%*$C'0Q``````QT,@`0```,=#)`$```!(B4,82(M]$.BO +XM[?__28M\)"!(B<;HDNG__X7`#X26````2(M<)$A(BVPD4$R+9"183(ML)&!( +XM@\1HPV9FD&:02(M5*$B+?1A(@^H02(UW$$B)52CH@^S__^E<____O______H +XM!.K__[X@;D``2(G"OT8````QP.A@ZO__O______HYNG__[X^;D``2(G"OT8` +XM```QP.A"ZO__O______HR.G__[Y7;D``2(G"OT8````QP.@DZO__O______H +XMJNG__[YU;D``2(G"OT8````QP.@&ZO__9F9FD&9FD&9FD$%454B)_5-(@^Q` +XM2(N?X````$B%VW4OZ8(```!F9F:02(/X!'1@2(M[$$B)YF9FD.BW[/__A<`/ +XMA)$```!(BUM82(7;=%A(BWL02(GFZ(KI__](AC__[ZN;D``2(G"OT8````QP.CUZ/__9F:09F:09F:02(EL)/A(B5PD +XM\$B#[!A(BU]@2(GU2(-[&`!T&4B)[DB)WTB+;"002(M<)`A(@\08Z?LW``!( +XMB=^^GFE``.CN-P``2(G?OL5N0`#HX3<``$B)W[[-;D``Z-0W``"^U6Y``$B) +XMW^C'-P``Z[%F9I!FD$%6055)B?U!5%532(/L0$B+K^````!(A>UT(D&XU6Y` +XM`.L)2(MM6$B%[7012(MU`+D*````3(G'_/.F=>9)BYVP````2(7;#X3_```` +XM9F:028M](.CSZ?__2(7`28G$#X3T````OG@```"_`0```.A(Z?__2(7`2(G" +XM#X3W````2(L#3(GG2(D"2(M%($B)0B!(BT,0QT)(`````$C'0@@`````3(EB +XM$$B):EA(B4(H2(M%8$B)0F!(BT5@2(D02(U"6$B)16#H`.?__TB%P$B)P@^$ +XML````$C'``$```!(QT`0`````$B)YDB+0PA,B>=(B4((2(M#$,="(`$```#' +XM0B0!````2(E"&.A,Y___2(7`#X2-````QT0D!`$```!(BS-,B>_H9/[__TB) +XMYDR)Y^@UZO__A<`/A(4```!(BUL82(7;#X4$____2(/$0%M=05Q!74%>P[__ +XM____Z*GF__^^WVY``$B)PK]&````,<#H!>?__[[,:D``OT8````QP.A4Z?__ +XMO______H>N;__[X^;D``2(G"OT8````QP.C6YO__O______H7.;__[[W;D`` +XM2(G"OT8````QP.BXYO__O______H/N;__[Y7;D``2(G"OT8````QP.B:YO__ +XM9F9FD&9F9I!F9I!F9I!52(G]4TB#[`B+=U"%]G0'2(-_&`!T;#';ZTMF9I!F +XMD$B+?1#HL^7__TB%P$B)P@^$A@```(M-4(7)=4Y(BP-(B0)(BT,02(E"$$B+ +XM0PA(B4((BT,@B4(@2(M#&$B)0AB+0R2)0B1(BWT(2(G>Z"KE__](ARH````28G\2(GW2(UT)$!(BY,B>=( +XMB00D2(M$)$A(B40D"$B+1"102(E$)!!(BT0D6$B)1"082(M$)&!(B40D($B+ +XM1"1H2(E$)"A(BT0D<$B)1"0P2(M$)'A(B40D..CX^___2(GF2(G?Z,GG__^% +XMP'1D2(N<)(@```!(BZPDD````$R+I"28````3(NL)*````!(@<2H````P[__ +XM____Z#/D__^^+F]``$B)PK]&````,<#HC^3__[______Z!7D__^^3&]``$B) +XMPK]&````,<#H<>3__[______Z/?C__^^:F]``$B)PK]&````,<#H4^3__V9F +XM9I!F9I!!54%455-(@^Q(2(N?X````$B%VP^$M````$4QY.F2````2(MK($PY +XMY0^"L0```$2+2TA%AR"+>TR%_W5?2(M#0$B#^`AT#4B%P'0(2(MK($@#:RA(BWL02(GFZ*OC__]( +XMA$B+0R!(B>9(B40D&$B+0RA(B40D($B+>Q#HF.;__X7`='1(BUM82(7; +XM=!U)B>Q-A>0/A67___](BVL@2`-K*$B+6UA(A=MUXTB#Q$A;74%<05W#9F9F +XMD&9FD$2+0TA%A<`/A$O___^_P'!``#'`Z-/C___I.O___[______Z-3B__^^ +XMA6]``$B)PK]&````,<#H,./__[______Z+;B__^^:F]``$B)PK]&````,<#H +XM$N/__V9FD&9FD%5(B?U32(/L2$B+?QA(B>;HU^'__TB%P`^$E````+YX```` +XMOP$```#H'^3__TB%P$B)PP^$M0```$B+1"0HN@$```!(B4,@2(N-X````$B% +XMR708,<"#>4P!2(M)6(/0`$B%R77P@\`!2&/02(M](+D!````O@X```#HON+_ +XM_TB%P$B)0RAT24B)WDB)[TC'0S@$````QT-(`````,=#3`$```#H*/;__TB) +XMV$B#Q$A;7<.______^C@X?__OEEJ0`!(B<*_1@```#'`Z#SB__^______^C" +XMX?__OOAJ0`!(B<*_1@```#'`Z![B__^^S&I``+]&````,<#H#>+__Y!!54&) +XMU4%428G\54B)]5-(@^P(2(N?H````$B%VW4+ZR9(BUM`2(7;=!U(BS-(B>_H +XMQ^+__X7`=>A(@\0(2(G86UU!7$%=PS';187M=.N_2````.CTX___2(7`=#9( +XMB<.Z2````#'V2(G'Z#WB__](B2M(QT-``````$F+A"2H````2(D82(U#0$F) +XMA"2H````ZZ:^HV]``+]&````Z&KA__]F9F:09F9FD&9FD&9FD#'22(/L".A% +XM____,=)(A[SIG3CN[5O +XM0`!)B>1(QP0DM6]``$C'1"0(O&]``$C'1"00SF]``$C'1"08U&]``$C'1"0@ +XM`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G?Z.;B__](B=Y(B<)(B>_H2-__ +XM_X7`==A!BT5H@^@!@_@!=PJX`0```.E!____08M%1(7`=0Q!BT5(A<`/A"O_ +XM__\QTDB)[DR)[^C1_?__18ME1$6%Y'4C08M=2(7;#X0)____2(7`=+M$BU@L +XM187;#Y3`#[;`Z?3^__](A_H..+__T@YPW7>2(GF2(GOZ"C?__](A<`/A)H```"+%"1(BW0D +XM2$F+?"08Z&W?__](A__^%P`^$:P(``$4Q]DB+?1A,B?;HS-W_ +XM_TB%P$F)Q@^$K`$``$B)YDR)]^C%W?__2(7`#X33`0``BQ0D2(MT)$A(BWT8 +XMZ`O>__](A_HR/S__X7`=:B+1"0$@_@)#X3+```` +XM@_@$#X3"````0;_5;D``N0H```!,B>;\3(G_\Z8/A;S +XMIG4$2(E=6$B)WDB)[^BA\/__Z=#^__^+="0LA?8/A#+___](B>_H*/W__X7` +XM#X6T_O__Z1W___^^>````+\!````D.CGW?__2(7`#X3O````2(G#3(D@3(EP +XM"$B+1"082(G>2(GO2(E#($B+1"0@2(E#*$B+1"0P2(E#.(M$)`1(B4-`Z,H- +XM``")0TCIZ_[__V:02(M3$$B+](BPOHO?;__^DL____Z(_>__^%P)`/ +XMA;0```!(@\186UU!7$%=05Y!7\.______^BMV___OCUP0`!(B<*_1@```#'` +XMZ`G<__^______^B/V___O@MP0`!(B<*_1@```#'`Z.O;__^______^AQV___ +XMOO5O0`!(B<*_1@```#'`Z,W;__^______^A3V___OB=P0`!(B<*_1@```#'` +XMZ*_;__^^S&I``+]&````Z`#>__^______^@FV___OMIO0`!(B<*_1@```#'` +XMZ(+;__^)Q^@+V___OJYN0`!(B<*_1@```#'`Z&?;__]F9F:09F9FD&9FD%5( +XMC2PW4TB#[`A(.>]S>TB)^^LXBP7&01``AM(B09U +XMPDB#Q`A;7<-(BS5801``OPH```#HVMG__^N?2(LU14$0``^^^NC)V?__ZXX[ +XM1BA\"(#Z"F9FD'6RZ*7<___I=____[\*````Z);<___I:/___V9FD&:005=! +XM5D%505154TB![-@```!(B7PD&$R+M^````!-A?8/A/\```!(C80DH````$B- +XME"3`````2(D$)$B)5"0(ZPU-BW98387V#X37````08M63(72=>M)BQZ_Q6Y` +XM`+D(````_$B)WO.F=-:_S6Y``+D(````2(G>\Z9TQ;_5;D``N0H```!(B=[S +XMIG2T2(M,)!B#>6@!#X2;````2(M\)!A(B=[HI_C__X7`#X1P`P``,=M%,?]( +XMQT0D6`````#K.4B+?"182`-[&.CMV___28G'387_#X3\`P``2(M$)%A(BU,8 +XM2(MS"$F-/`?H"]S__TB+4QA(`50D6$F+?@A(B=[HAMC__TB%P$B)PP^$C@`` +XM`$V%_W6J2(M[&.BO^__],B??H#?'__TB+5"08BT)L@^`P@_@0=1M)BT9`2(/X"70&2(/X +XM!'4+28-^*``/A?`!``!)BS9(BWPD&#'2Z%/U__](A<`/A!O]__^+0#"%P`^$ +XM$/W__TF+?AA(A?]T#4F+=BA(A?8/A?0````QV^L-2(MS&$B+>PCHR/O__TF+ +XM?@A(B=[H*-;__TB%P$B)PW7?Z%O9__^%P`^%$08``(L%@3T0`(7`#X5A`0`` +XM2(LU@CT0`(M&#(/H`87`B48,#XCZ/+T__^%P`^$I?[__^EV_/__ +XM9F:09I#HV_K__^DO____28LV2(M\)!@QTN@7]/__3(M@&$R)Y^C7V/__2(M\ +XM)%!(`WPD6$B)PDR)YDB)P^@/UO__2`-<)%A(BTPD4,8$"P!(@\,!2(E<)%CI +XMD)_?__OFIP0`"_1@```#'`Z/37__](BS4A/!`` +XMOPH```#HH]3__^E#^___28M^$$B-="1@Z%#5__](A<`/A&$%``!(BTPD&(N< +XM)(@```!(BT%02(MX".@NV/__2#G##X77_?__28M^$#'VZ$K4__](AT))@```!(A`@2`'02(GRB=Y(B80DJ````.B"U___A,/A#/]__])@WY`"76.2(V4),````")WDB)[^B8U___2#M$)`A(B<8/ +XMA9($``!(BWPD&$B+E"3(````2(M'>$B)T8/B_TC!Z2!(B>](BP3(2,'@($@! +XMT$B)\HG>2(F$),@```#HW]/__X7`=8V______^C!T___OIQP0`!(B<*_1@`` +XM`#'`Z!W4__^028L>0<=&4`$```!)QT8H`````.DD^O__2(M4)!B+G"2(```` +XM2(M"4$B+>`CHR];__T@YPP^%]_K__TF+?@@Q]NCGTO__2(7`2(E$)"`/A+D# +XM```QTDB+A"2`````2/>T))@```!(A`CH(];_ +XM_TB)QDB+1"082(G:2(MX&.AOT___2(7`2(GU`@``2(M\)!CHG0@``(7` +XM=&)(BU0D&(-Z%`$/A*L```!)@WY`"0^$"0$``$V%Y`^$C`$``$DY[&9FD`^# +XM60$``$B+?"0H2XT$9$B-%,=(BX0DH````$B)`DB+A"2H````2(E""$F#?D`$ +XM#X3@`0``28/$`4F#Q0%,.VPD$`^$.P,``$F#?D`)#X4>____2(M\)"!(C90D +XMP````$2)[NB4U?__2#M$)`@/A!W___^______^C_T?__OE-P0`!(B<*_1@`` +XM`#'`Z%O2__])@WY`"0^$T@$``$V%Y`^$J0$``$DY[`^#>`$``$B+?"0P2XT$ +XM9$B-%(=(BX0DH````(D"2(N$)*@```")0@1)@WY`!`^%6O___TB+A"2P```` +XMB4((Z4K___^_"@```.@'U/__Z;?W__]-A>1F9I`/A,8```!).>QF9F:09F:0 +XM#X./````3(G@2(N4),````!(P>`$2`-$)#A(B1!(BY0DR````$B)4`A)@WY` +XM!`^%\?[__TB+A"2P````2(M,)"A+C11D2(E$T1#IUO[__T@![4B+?"0H2(GN +XM2,'F!.@YT?__2(7`#X3$`0``2(E$)"CI@/[__TB)[TC!YP3HFM/__TB%P`^$ +XMM@$``$B)1"0HZ57^__](`>U(BWPD.$B)[DC!Y@3H\]#__TB%P`^$?@$``$B) +XM1"0XZ4K___](B>](P><$Z%33__](A<`/A'`!``!(B40D..D;____OMMI0`"_ +XM1@```.A2T___B]#__[X5;T``2(G"OT8````QP.C7T/__2(N$)+````!( +XMB4(0Z0_^__](`>U(BWPD,$B--.T`````Z''0__](A<`/A/P```!(B40D,.E@ +XM_O__2(T\[0````#HT=+__TB%P`^$[0```$B)1"0PZ3?^__]-A>0/A)H!``!) +XM.>P/@VT!``!(BY0DP````$N-!.>)$$B+E"3(````B5`$28-^0`0/A9']__]( +XMBX0DL````$B+3"0P2XT49(E$D0CI=_W__[______Z+3/__^^]6]``$B)PK]& +XM````,<#H$-#__[______Z1;___^______^B,S___OEEJ0`!(B<*_1@```#'` +XMZ.C/__^______^ANS___OH-P0`!(B<*_1@```#'`Z,K/__^______^A0S___ +XMOCYN0`!(B<*_1@```#'`Z*S/__^^='!``+]&````,<#H^]'__[[;:4``OT8` +XM```QP.CJT?__13'_2,=$)#@`````2,=$)#``````2,=$)"@`````13'DZ+31 +XM__^%P(G'#X5J_O__2(M$)!B#>!0!#X2.````28-^0`E(BU0D.$@/150D*$F) +XM5AA(BTPD&#'V28-^0`E,B>)(BWD@N0$```!`#Y7&@\8,Z$//__])BQY)B48H +XM0<=&4`$```#I'_7__T@![4R)_TB--.T`````Z*S.__](A<`/A#?___])BL.08/$`40Y +XM92@/CI4```!(BWT83(GR1(GFZ`G.__],.?`/A8H```!(BWT@2(GB1(GFZ/'- +XM__],.>AU=HM$)$!(B>)$B>:)!"1(BT0D4$B)1"002(M$)%A(B40D&(M$)$2) +XM1"0$2(M$)'!(B40D,$B+1"1(2(E$)`A(BT,(2(E$)"!(BT,02(E$)"A(BWT@ +XMZ(3.__^%P'0X2(M;.$B%VP^%7?___TB#[(!;74%<05U!7L.______^C,R___ +XMO@=Q0`!(B<*_1@```#'`Z"C,__^______^BNR___OA]Q0`!(B<*_1@```#'` +XMZ&K.__^______^B0R___ONUP0`!(B<*_1@```#'`Z.S+__^______^ARR___ +XMOA!K0`!(B<*_1@```#'`Z,[+__]FD$%455-(B?M(@^Q`2(M_&$B-="0XZ#/+ +XM__^%P`^$Y@```$B+1"0X2(7`B4,HB4,L#X2:````,>U)B>1F9I!F9I!(BWL8 +XM2(GBB>[HKLS__TPYX`^%@0```+Y`````OP$```#HILS__TB%P$B)P@^$A``` +XM`$B+1"0(2(/%`4B)`DB+1"0@2(E""$B+1"0H2(E"$(L$)$C'0B@`````2,=" +XM.`````!(B4(82(U"*$B)0C!(BX.8````2(D02#EL)#A(C4(X2(F#F`````^' +XMPH`@``2(M'4$B)1"0P2(M76$B)5"0X2(M0$$B+<`CHB./__TB+ +XM3"0X3(GO2(M1$$B+<0BYS6Y``.ANX___2(M<)#!(C;0D@`$``$B+>Q#HQ,C_ +XM_TB%P`^$KQ(``$B+1"0X2(VT)$`!``!(BW@0Z*7(__](A<`/A)`2``!!]D5L +XM(`^%R@4``$F+?1A(C;0D&`(``.CPR/__A<`/A"06``!)BWT@Z"_*__^%P(E$ +XM)$0/A-$5``"^`0```+\P````Z+3)__](ARO__ +XM2(7`#X32%0``2(E$)$C&``"^`0```$&+?3"#QP>-1P>%_P](^,'_`TAC_^AN +XMR?__2(7`28F%B`````^$714``$R-I"0``0``,=LQ[69FD&9FD$F+?1A(B=[H +XMT,?__TB%P$B)PP^$.0X``$R)YDB)W^C)Q___3#G@#X6W#@``BY0D``$``$B+ +XMM"08`@``28M]&.@(R/__2(7`2(G%#X1U#@``_+_-;D``N0@```!(B<;SIG6> +XM2(G?Z(+*__](B40D8.CHR?__A<`/A;04``!(@WPD8``/A(`4``!,C:0D``$` +XM`#';28M]&$B)WN@^Q___2(7`2(G#=$Y,B>9(B=_H.\?__TPYX`^%*0X``(N4 +XM)``!``!(B[0D&`(``$F+?1CH>L?__TB%P$B)Q0^$YPT``$&_Q6Y``+D(```` +XM2(G&_$R)__.F=9[H8\G__X7`#X4O%```2(7;#X3^$P``,=)(BX0D(`$``$CW +XMM"0X`0``2(7`2(E$)"@/A:\%``!(QT0D<`````!(QX0DN````$````!(QT0D +XM4`$```!)BYW@````2(7;#X2Q`0``0;_%;D``ZPU(BUM82(7;#X2<`0``3(L# +XMN0@```!,B?_\3(G&\Z9TX+_-;D``N0@```!,B<;SIG3/O]5N0`"Y"@```$R) +XMQO.F=+Y!]D5L!'002(M#0$B#^`ETK4B#^`1TITB+>Q#H*LG__TF+E8@```!( +XMB<%(P>D##[84"HG!@^$'T^J#X@%U@,>$).`!````````2,>$).@!```````` +XM2,>$)/`!````````QH0DY`$```-(BWL(Z-C(__^#?"1$`6:)A"3F`0``#X2Q +XM#0``28M6$$B%T@^$JA(``$B+C"2X````23M.*`^&"@\``(N$).`!``"%P`^% +XM`PT``$F+1BA(C01`QP3"`````$F+1B@/MI0DY`$``$F+3A!(C01`B%3!!$F+ +XM1B@/MI0DY0$``$F+3A!(C01`B%3!!4F+1BA)BTX02(N4).@!``!(C01`2(E4 +XMP0A)BT8H28M.$$B+E"3P`0``2(T$0$B)5,$0#[>,).8!``"-0?]F/?[^#X=G +XM#```28M%<$F+5B@/M\E)BW802(L$R$B-%%)FB436!DF#1B@!2(M;6$B%VP^% +XM9/[__TB#?"1P`'152(-\)"@`=$,QTC'VZP202(GRB?!(BUPD<(GQP?@#@^$' +XM2)@/M@08T^BH`7032(T$U0````!)`T5X28M6*$@!$$B#Q@%(.W0D*'7$2(M\ +XM)'#H1L?__S'`@WPD1`%)BU8@28M-4`^5P$D#5BA(C03%$````$@/K\)(B4$H +XM28M%4$R)R@`#X6]`@``2(-[(``/A4L"``!(BTPD.$B+>1#H@$))`!````````,$)(0!```"````2,>$ +XM)(@!````````2(F$)*`!``!)BWT@Z+7#__](BTPD,$B)A"2X`0``2(G>2(MY +XM$.A,P___2#G8#X4Z"@``3(V\),`!```QVT4Q]DB+1"0P2(G>2(MX$.A5PO__ +XM2(7`2(G#='PQTDB+0QA(][0D^````$B%P$B)Q73113'D0;T!````3(GZ1(GF +XM2(G?Z/##__],.?@/A?D,```/MH0DQ`$``,#H!(3`10]$]4F#Q`%)@\4!23GL +XM=)/KR4B+?"0PZ%'<__](BWPD..A'W/__2('$*`(``%M=05Q!74%>05_#Z`S% +XM__^%P`^%Z!```$B+5"0X1(FT)*P!``!(C;0D@`$``$C'A"10`0```````$C' +XMA"1P`0```0```$B+3"0P2(M"*,>$)$0!```#````2,>$)$@!````````2,>$ +XM)'@!````````QX0D;`$```````#'A"1H`0```````$B)A"1@`0``2(MY$.@D +XMQ?__A`#2(E"$$B+0QA(B4(( +XM2(M#(,="(!(```#'0B0!````2(T$0$C!X`-(B4(8Z4[]__](BW@0Z-3`__]( +XMAG\__](BWPD*+X(```` +XMZ&3"__](AH#2(G72(F4)(`` +XM``#H-<+__TB%P$B)1"1X#X0F#@``2(M,)'@Q]DB)WTB)3"1PZ..___](A$)+@```!`````2,=$)%`!````0;\``@``2,>$)*@````````` +XM2,>$)+``````````2(E<)!A(B40D$$B)%"1(B4PD"(N$)+````!(BWPD:$B- +XME"3@`0``B<:)A"2D````Z!3!__](.T0D&`^%&PH``(N4).`!``!)BWT82(MT +XM)&#H5,#__TB%P$B)Q0^$P08``$B)QDR)[^B!]?__A<`/A><```!)BYW````` +XM2(7;=0OK24B+6PA(A=MT0$B+,TB)[^C#P/__A&X`0```-/@"`0:28M5>$F+1B!(BXPDJ````$B)!,J#?"1$`0^$ +XMR@$``$B-O"3@`0``Z!;T__^%P`^$E`(``$F+5A!(A=(/A)4'``!(BX0DN``` +XM`$D[1B@/A@<%``"+O"3@`0``A?\/A(X#``"`?0``#X2$`P``28M&*(M,)%!( +XMC01`B0S"28M&*`^VE"3D`0``28M.$$B-!$"(5,$$28M&*`^VE"3E`0``28M. +XM$$B-!$"(5,$%28M&*$F+3A!(BY0DZ`$``$B-!$!(B53!"$F+1BA)BTX02(N4 +XM)/`!``!(C01`2(E4P1`/MXPDY@$``(U!_V8]_OX/AC,#``!)BT8H28M6$$B- +XM!$!FB4S"!DF#1B@!#[:$).0!``"#X`^#^`,/A)$"``"`?0``#X39_?__ZQY( +XMBWPD2$T!_TR)_NA6O?__2(7`#X0(!```2(E$)$A(B>_H0,#__TB+5"102(G! +XM2`'"28U'_T@YPG/&2(M<)$A(`UPD4$B)RDB)[DB)W^ADO?__2(GOZ`S`__]( +XMB>_&!`,`Z`#`__](BUPD4$B-7`,!2(E<)%#I7?W__TB-O"3@`0``Z(/R__^% +XMP`^%-_[__P^VA"3D`0``P.@$/`(/A`$B%0(#$F+1B@/MI0DY0$` +XM`$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4"`1)BT8H28L.2(N4 +XM)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&,0,``$F+1BA)BQ9(P>`$ +XM9HE,$`[I._[__TF+5AA(A=(/A*(%``!(BT0D6$D[1B`/ACT"``"+M"3@`0`` +XMA?8/A.D```"`?0``#X3?````28M&((M,)%!(C01`B0S"28M&(`^VE"3D`0`` +XM28M.&$B-!$"(5,$$28M&(`^VE"3E`0``28M.&$B-!$"(5,$%28M&($F+3AA( +XMBY0DZ`$``$B-!$!(B53!"$F+1B!)BTX82(N4)/`!``!(C01`2(E4P1`/MXPD +XMY@$``(U!_V8]_OX/AH$```!)BT8@28M6&$B-!$!FB4S"!DF#1B`!#[:$).0! +XM``"#X`^#^`,/A6_]__\/MY0DY@$``$F+17!(BPS0N`$```!(BH# +XM20.5B````-/@"`+I0/W__TF+1B!(C01`QP3"`````.D<____28M&*$B-!$#' +XM!,(`````Z7?\__])BT5P28M6(`^WR4F+=AA(BP3(2(T44F:)1-8&Z6____]) +XMBT5P28M6*`^WR4F+=A!(BP3(2(T44F:)1-8&Z;W\__])BU8(2(72#X2_!@`` +XM2(M<)%A).UX@#X8R`P``1(N$).`!``!%A8# +XMZ%6Y__](A8#Z!FY__](A($9HE$,@[I__K__TF+1BA)BU802(T$0&:)3,(& +XMZ9_S__^`?0``#X3S\O__28M&*(M,)%!(C01`B0S"Z>[R__])BT8@BTPD4$C! +XMX`2)#!#I//[__TF+1BB+3"102,'@!(D,$.GB^___2,<`!````$B+0RA(P>`$ +XM2(E"$$B+0PA(B4((2(M#(,="(!(```#'0B0!````2,'@!$B)0ACI]?/__TF+ +XM%DB%T@^$,08``$B+C"2X````23M.*`^&?00``(N,).`!``"%R0^$^P```(!] +XM```/A/$```!)BT8HBTPD4$C!X`2)#!!)BT8H#[:4).0!``!)BPY(P>`$B%0( +XM#$F+1B@/MI0DY0$``$F+#DC!X`2(5`@-28M&*$F+#DB+E"3H`0``2,'@!(E4 +XM"`1)BT8H28L.2(N4)/`!``!(P>`$B50("`^WC"3F`0``C4'_9CW^_@^&C0$` +XM`$F+1BA)BQ9(P>`$9HE,$`[I4_+__T@!P$B)UTB)QDB)A"2X````2,'F!.@. +XMM___2(7`2(G"28D-^O__Z;7]__](`=M(B==(B=Y(B5PD6$C!Y@3HX[;_ +XM_TB%P$B)PDF)1@@/A:?\___IB?W__V:028M&*$C!X`3'!!``````Z0K___]( +XMBYPDN````$B-/%M(P><#Z".Y__](A8#Z&&V__](A($9HE$,@[IN_#__TB+O"2`````O@$```#H_K;__TB% +XMP$F)A8`````/A.T"``!)BWT82(VT)!`"``#H[;7__X7`#X0A`P``13'D28M] +XM&$R)YNA6M?__2(7`28G$#X2'`@``2(VT),````!,B>?H2K7__T@[1"00#X4V +XM_/__BX0DQ````(/X"70%@_@$=;R+E"3`````2(NT)!`"``!)BWT8Z':U__]( +XMA_H-M3__X7`=8R+M"3L````3(GOZ'/5__^%P`^%=?__ +XM_TF+15"+G"3H````2(MX".C3M___2#G#2,>$))``````````2,>$))@````` +XM````#X5`____2(N,))````!(.XPDX`````^#KP(``$B+M"28````3(GGZ+RS +XM__](AT)/@```"%P$B) +XMPWZLQX0DC`````````"#O"3$````"0^$H`(``(NT)(P```!(B[PDF````$B- +XME"3``0``Z+FU__](.P0D#X6Q`@``BX0DS`$``$B)A"20````2(.\))`````` +XM#Y7`="-(BU0D*$@YE"20````#X+7`0``A,!T#+_,<4``,<#H?[3__X.$)(P` +XM```!.9PDC`````^$&/___^ER____2(N\)+@```!(P><$Z!2V__](A;Y___HMK7__X7`B<=(QX0DN````$````!(QT0D4`$````/A(/L___H +XMTK+__[Z'<4``2(G"OT8````QP.@NL___2(N$)+@```!(C3Q`2,'G`^A9M?__ +XM2(7`2(G"28E&$`^%0^W__^DQ_/__OFQQ0`"_00```#'`Z/.R___H/K7__X7` +XMB<=U#DF+E8````#I=//__XG'Z&6R__^^KFY``$B)PK]&````,<#HP;+__[[, +XM:D``OT8```#H$K7__[______Z#BR__^^4W%``$B)PK]&````,<#HE++__[[, +XM:D``OT8````QP.CCM/__OMMI0`"_1@```.C4M/__O______H^K'__[[:;T`` +XM2(G"OT8````QP.A6LO__O______HW+'__[[A<4``2(G"OT8````QP.@XLO__ +XM2(N$))````"+C"20````N@$```!(P>@#20.%@````(/A!]/B"!#I#O[__^A8 +XMM/__A<")QP^$;/S__V:0Z;#^__](B[PDN````$C!YP3H)K3__TB%P$B)PDF) +XM!@^%P?G__^G_^O__9F:09F:0BQA) +XMB<5-B?Y,`W,H33GW_HQ;/__TDYQ4B)PW?F +XM3"GH2(LT)$R-)"A,B>?HVK'__X7`=<](@\0(1(G@6UU!7$%=05Y$*?A!7\-( +XM@\0(N/____];74%<05U!7D%?PY!!5T%6055)B?U!5%532(/L&$B)-"1(BV\H +XM2(7M28GN=29(QT2`,T).C3L/__A7!E +XM`&5L9E]G971S:&YU;2!F86EL960Z("5S`&-A;&QO8R!F86EL960`9V5L9E]U +XM<&1A=&5?96AD6UB;VP`;W5T +XM<'5T+69I;&4`<')E2!A;F0@6UT86(`+G-T"!I;F1E>`!E;&9?;F5W +XM9&%T82@I(&9A:6QE9#H@)7,N`"1&'`@ +XM)``!&___&`,0````````````````````````````GFE````````````````` +XM`%A\4`````````````````#::T````````````````````````````!H```` +XM`````-]K0````````0```````````````````$L`````````ZVM````````! +XM````````````````````;P````````#W:T`````````````````````````` +XM``!P``````````9L0````````0```````````````````%(`````````%6Q` +XM````````````````````````````E(` +XM`7@0`0,,!PB0`0``'````!P```!0&T``DP````!"#A",`D4.&$$.((,$A@,4 +XM````/````/`;0``X`````$0.$``````4````5````#`<0``B```````````` +XM```4````;````&`<0``I`````$0.$``````4````A````)`<0``I`````$0. +XM$``````4````G````,`<0``I`````$0.$``````D````M````/`<0`"/!@`` +XM`$J/`H8&80[@`8X#C02,!8,'````````-````-P```"`(T``<`@```!"#A"/ +XM`D4.&(X#2@X@0@XH00XP00XX1P[0`8,'A@:,!8T$```````4````%`$``/`K +XM0`!]```````````````<````+`$``'`L0`"V`0```$J#!8P#40YPC0*&!``` +XM`"0```!,`0``,"Y```!`!`PP'")`!```` +XM````%````"`````0:4``)0````!(#A"#`@```0`````````!``````````$` +XM````````Q@$````````,`````````,@60```````#0`````````X:4`````` +XM``0`````````^`%````````%`````````-`+0```````!@````````!0!$`` +XM``````H`````````#P,````````+`````````!@`````````%0`````````` +XM``````````,`````````:'Q0```````"`````````)`&````````%``````` +XM```'`````````!<`````````.!!````````'`````````,`/0```````"``` +XM``````!X``````````D`````````&`````````#^__]O`````(`/0``````` +XM____;P`````"`````````/#__V\`````X`Y````````````````````````` +XM```````````````````````````````````````````````````````````` +XM``````````````````````````````````````````````````#_________ +XM_P``````````__________\`````````````````````H'I0```````````` +XM````````````````\A9````````"%T```````!(70```````(A=````````R +XM%T```````$(70```````4A=```````!B%T```````'(70```````@A=````` +XM``"2%T```````*(70```````LA=```````#"%T```````-(70```````XA=` +XM``````#R%T````````(80```````$AA````````B&$```````#(80``````` +XM0AA```````!2&$```````&(80```````6YC7W-E8W1I;VYS`"(1``!I;G-E5]C;VYT96YT``````!! +XM`````@!^+@``W`D``'$(``!A9&1?=&]?:6YS96=?;&ES=`#W"```8V]P>5]P +XM:&1R`'P)``!S971U<%]P:&1R``````!C`````@!:.```!1,```L,``!L;V]K +XM=7!?:V5E<%]S>6UL:7-T`&8,``!A9&1?=&]?6`@```TP&```".8,````" +XM"`5=`P```X8"```".I4````""`>1`@```@@$AP,```($!*D#```#]00```)2 +XMB@````,\!0```E1X````!0@'!@@#?`$```,F9@````,5`P```R=X`````[0& +XM```#*68````#B0````,L9@````,T`P```RYF`````PT"```#,4(````#70<` +XM``,S0@````,(!0```S1X`````W`&```#/F8````#&@$```-;9@````(!!K(! +XM```#_`$```190@````-/`P``!%YF`````X@"```$8XH````'"#,!```'"&U````"7(&```$"`$=`0``"MT%```0 +XM!2X/`@``"X<'```%+\\!```"(P`+\`4```4P@P````(C"``*U@```'@&@PH# +XM```+V`0```:$*`$```(C``M-!P``!H68`0```B,$"V@&```&AJ,!```"(P@+ +XM@P0```:'K@$```(C"@N0`0``!HC:`0```B,,"V0"```&B8T!```"(Q`+O@$` +XM``:**`$```(C%`O9!0``!HSF`0```B,8"R`#```&C>8!```"(R@+8`4```:. +XMY@$```(C.`NK`@``!I>Y`0```B-("S8````&F')`P```B,`#%]R``AH +XM7P````(C"`Q?=P`(:5\````"(PP+?0H```AJ.P````(C$`NN!@``"&L[```` +XM`B,2#%]B9@`(;&`#```"(Q@+0P8```AM7P````(C*`M)`@``"'##`````B,P +XM"_,!```(<<,$```"(S@+L@0```ARXP0```(C0`O2!```"',#!0```B-("TD` +XM```(=",%```"(U`,7W5B``AW8`,```(C6`L`````"'@O!0```B-H#%]U<@`( +XM>5\````"(W`+1@0```A\-04```(C=`N;````"'U%!0```B-W#%]L8@`(@&`# +XM```"(W@++0````B#7P````,CB`$+=PD```B$50,```,CD`$`#0%?````PP0` +XM``[#``````<(LP0```T!7P```.,$```.PP````Y;`0``#E\`````!PC)!``` +XM#0%5`P```P4```[#````#E4#```.7P`````'".D$```-`5\````C!0``#L,` +XM```.80$```Y?``````<("04```_M`@```0<(*04``!`T````104``!'````` +XM`@`0-````%4%```1P````````Z8"```(A8\#```""`58`P``$#0```!W!0`` +XM$<`````/``/[`@``"290`0```Y0&```!%7$#```"%7$'```#%=L````$`!0$"C9=!P``%3$%````%9H'```! +XM%>8%```"%;$%```#%H````3%>$"```4%7P#```5%0X!```6%?X$```7`!0$ +XM"E6T'```+MPH```PB80$```(C``M>!```#"2M +XM!P```B,(``<(Q`<``!((##8*"```"U8%```,-K\(```"(P``"F8#``!(#"B_ +XM"```"[<*```,*6$!```"(P`+H@$```PJ80$```(C"`M!`@``#"MA`0```B,0 +XM"X4-```,+&$!```"(Q@,861D``PN7P````(C(`M;`0``#"]?`````B,D"\D' +XM```,,%\````"(R@+404```PQ7P````(C+`O9`0``##)?`````B,P"V\````, +XM,U\````"(S0+5P0```PT7P````(C.`NB!```##;S!P```B-```<("@@``!(( +XM##_<"```"U8%```,/R$)```"(P``"@<&```@##HA"0``"[<*```,.UL!```" +XM(P`+=`H```P\6P$```(C"`L`"```##W$`0```B,0"Z<````,/\4(```"(Q@` +XM!PC<"```$A`,44P)```+5P4```Q1&@H```(C``LX`@``#%$@"@```B,(``JD +XM"0``>`Q#&@H```NW"@``#$1A`0```B,`#&ES``Q%G`<```(C"`QO=`H```O7`@`` +XM#%X:"@```B,`"P0'```,7B`*```"(P@`$@@,7XL*```+5@4```Q?^@H```(C +XM```*NP(``$`,5OH*```,;V9F``Q74`$```(C``QF@`,65`!```"(Q`+W0@```Q:4`$```(C&`MO````#%Q?`````B,@"X@'```, +XM7DL*```"(R@+3@L```Q?=`H```(C.``'"(L*```4!`R-)PL``!5B`0```!40 +XM!0```14W!@```A7X!0```Q43!@``!``2$`RI3`L```O6`@``#*GZ"@```B,` +XM"P,'```,J4P+```"(P@`!PCZ"@``$A`,JG<+```+U@(```RJOP@```(C``L# +XM!P``#*IW"P```B,(``<(OP@``!(0#*NB"P``"]8"```,JR$)```"(P`+`P<` +XM``RKH@L```(C"``'""$)```2$`RMS0L```O6`@``#*WM!P```B,`"P,'```, +XMKU\````" +XM(RP,;F]S``Q]7P````(C,`LQ!```#()?`````B,T"T\!```,@U\````"(S@+ +XMO0<```R$7P````(C/`O-`0``#(5?`````B-`"V,````,AE\````"(T0+104` +XM``R'7P````(C2`O@#```#(D:"@```B-0"VH-```,BAH*```"(U@+Y@D```R+ +XM&@H```(C8`M^!@``#),`"P```B-H"WX*```,FU\````"(VP+KP<```R>Z@T` +XM``(C<`OS!@``#*'J#0```B-X"^T&```,I(D#```#(X`!"U0'```,IXD#```# +XM(X@!"S`!```,J2<+```#(Y`!"P<````,JE(+```#(Z`!"S8!```,JWT+```# +XM([`!"W@&```,K:@+```#(\`!"XP$```,K],+```#(]`!"X@'```,L?@+```# +XM(^`!``<(>P8```<(4`$``!8W!P``!`$L#PX``!7&`````!5V`````14/!@`` +XM`@`7>P<```%:`@%@'$```````(D<0````````````!<&`P```5,"`9`<0``` +XM````N1Q````````X````%[@````!3`(!P!Q```````#I'$```````'`````8 +XM/P<```$,`0$!F0X``!EE8W```0L!F0X``!EI9F0``0L!7P```!EO9F0``0L! +XM7P`````'"!T,```:&`````&(`0'D#@``&V5C<``!AYD.```J`8```$O`0'P +XM'$```````'\C0```````J````/D/```?96-P``$N`9D.``#A````'W-R8P`! +XM+@%A`0``*@$``!]D04```$R`<0!```A:69D``$S`5\```#&`P``(6]F9``!,P%?````(@0``"-F +XM#@````````%7`22,#@``)(`.```D=`X``".?#@``H`````$=`22L#@``)3`! +XM```FMPX``,H$```GP@X```.1\'XGS0X```.1L'XFV`X``$P%````````&%T& +XM```!%0(!`5H0```996-P``$4`ID.```H]@(```$4`E\````H$`,```$4`EH0 +XM```IA```"1N$```);`$```F +XMDA```+,+```FGA```.D+```FJA```$4,```MMA```"W"$```+BJ`````X0&```"+[H````)5@8``!`"1E,!```*(@4```)'4P$` +XM``(C``K_!P```DA?`````B,(``<(-`````FC`@``F`)F?0(```M?<``"9U,! +XM```"(P`+7W(``FA?`````B,("U]W``)I7P````(C#`I]"@```FH[`````B,0 +XM"JX&```":SL````"(Q(+7V)F``)L*@$```(C&`I#!@```FU?`````B,H"DD" +XM```"<+@````"(S`*\P$```)QC0(```(C.`JR!````G*M`@```B-`"M($```" +XM<\T"```"(T@*20````)T[0(```(C4`M?=6(``G/D" +XM```"(V@+7W5R``)Y7P````(C<`I&!````GS_`@```B-T"IL````"?0\#```" +XM(W<+7VQB``*`*@$```(C>`HM`````H-?`````R.(`0IW"0```H0?`0```R.0 +XM`0`,`5\```"-`@``#;@`````!PA]`@``#`%?````K0(```VX````#0,!```- +XM7P`````'"),"```,`1\!``#-`@``#;@````-'P$```U?``````<(LP(```P! +XM7P```.T"```-N`````T)`0``#5\`````!PC3`@``#NT"```!!PCS`@``#S0` +XM```/`P``$+4````"``\T````'P,``!"U```````#I@(```*%60$```((!5@# +XM```#C0H```8F[0````,%"```!BG,`````Q$(```&*NT````/-````&(#```0 +XMM0````\`$0@&>H<#```*Q0D```9[,0,```(C``KV"```!GQ'`P```B,$``-& +XM"0``!GUB`P``$0P&@,4#```*Q0D```:!,0,```(C``KV"```!H)'`P```B,$ +XM"D,*```&@SP#```"(P@``V0*```&A)(#```#^P(```$T`,```(C``KV"``` +XM!X4'!````B,(``.L"0``!X:*!0``$1@'B>T%```*Q0D```>*T`,```(C``KV +XM"```!XL'!````B,("D,*```'C/$#```"(Q```^\)```'C;H%```216QF``@F +XM`P8```ZV`P```0,&`0``""<4!@``#@4!```!$P0(-K,&```4,04````4F@<` +XM``$4Y@4```(4L04```,4S`,```04OP8```44C@<```843`0```<4D`4```@4 +XM4`````D4?`(```H4^@````L49P<```P4?@4```T4EP0```X4G`8```\4(0(` +XM`!`4(@$``!$4(@8``!(4Z@```!,4X0(``!04?`,``!44#@$``!84_@0``!<` +XM`^((```(3QH&```1"`AXU08```I6!0``"'A@!P```B,```G5"0``0`AH8`<` +XM``HT"@``"&SX`````B,`"E@)```(;;@````"(P@*$@H```AN^`````(C$`K^ +XM!P``"&_X`````B,8"ML(```(<+,&```"(R`*J@H```AQ<0````(C)`HY"``` +XM"'9F!P```B,H"GP*```(=W$````"(S`*(PD```AXO@8```(C.``'"-4&```' +XM"`D&```#U@D```AYU08```.,'```*MPH```HB"0$```(C``I>!```"B2C!P```B,(``<(N@<``!$("C8` +XM"```"E8%```*-K4(```"(P``"68#``!("BBU"```"K<*```**0D!```"(P`* +XMH@$```HJ"0$```(C"`I!`@``"BL)`0```B,0"H4-```*+`D!```"(Q@+861D +XM``HN7P````(C(`I;`0``"B]?`````B,D"LD'```*,%\````"(R@*404```HQ +XM7P````(C+`K9`0``"C)?`````B,P"F\````*,U\````"(S0*5P0```HT7P`` +XM``(C.`JB!```"C;I!P```B-```<(``@``!$("C_2"```"E8%```*/Q<)```" +XM(P``"0<&```@"CH7"0``"K<*```*.P,!```"(P`*=`H```H\`P$```(C"`H` +XM"```"CT4`0```B,0"J<````*/[L(```"(Q@`!PC2"```$1`*44()```*5P4` +XM``I1$`H```(C``HX`@``"E$6"@```B,(``FD"0``>`I#$`H```JW"@``"D0) +XM`0```B,`"VES``I%9@<```(C"`MO:@H```K7`@``"EX0"@```B,`"@0'```*7A8* +XM```"(P@`$0@*7X$*```*5@4```I?\`H```(C```)NP(``$`*5O`*```+;V9F +XM``I7^`````(C``MF@`*6?@````"(Q`*W0@```I: +XM^`````(C&`IO````"EQ?`````B,@"H@'```*7D$*```"(R@*3@L```I?:@H` +XM``(C.``'"($*```3!`J-'0L``!1B`0```!00!0```10W!@```A3X!0```Q03 +XM!@``!``1$`JI0@L```K6`@``"JGP"@```B,`"@,'```*J4(+```"(P@`!PCP +XM"@``$1`*JFT+```*U@(```JJM0@```(C``H#!P``"JIM"P```B,(``<(M0@` +XM`!$0"JN8"P``"M8"```*JQ<)```"(P`*`P<```JKF`L```(C"``'"!<)```1 +XM$`JMPPL```K6`@``"JWC!P```B,`"@,'```*K<,+```"(P@`!PCC!P``$1`* +XMK^X+```*U@(```JOXP<```(C``H#!P``"J_#"P```B,(`!$0"K$3#```"M<" +XM```*L1`*```"(P`*!`<```JQ%@H```(C"``)(P```/`*;MH-```*E0,```IO +XM"0$```(C``JA````"G)?`````B,("K8'```*U\````"(RP+;F]S``I]7P````(C,`HQ +XM!```"H)?`````B,T"D\!```*@U\````"(S@*O0<```J$7P````(C/`K-`0`` +XM"H5?`````B-`"F,````*AE\````"(T0*104```J'7P````(C2`K@#```"HD0 +XM"@```B-0"FH-```*BA`*```"(U@*Y@D```J+$`H```(C8`I^!@``"I/V"@`` +XM`B-H"GX*```*FU\````"(VP*KP<```J>X`T```(C<`KS!@``"J'@#0```B-X +XM"NT&```*I%,!```#(X`!"E0'```*IU,!```#(X@!"C`!```*J1T+```#(Y`! +XM"@<````*JD@+```#(Z`!"C8!```*JW,+```#([`!"G@&```*K9X+```#(\`! +XM"HP$```*K\D+```#(]`!"H@'```*L>X+```#(^`!``<(^`4```<(^````!73 +XM"@```>(!\"M```````!M+$````````)W"#H.```696-P``'A.@X```%5%G-E +XM8P`!X1`*```!5!=S``'C$`H```%1&/,*```![D,L0`````````<($PP``!D! +XMC`D```&C`P%P+$```````"8N0```````OA```*`.```:96-P``&B`SH.``#W +XM$```&W,``:0#$`H``$`1```<`0L```&E`Z`.``!V$0``'7-H``&F`X('```# +XMD9!_``<(;`<``!D!\@<```%[`P$P+D```````#WPD```%L`P%`+T```````*LO0```````_!(` +XM`%`S0```````&C5```````#4&```(A$``!IE +XM8W```4@".@X``%T9```; +XM$@``$+4````$``<("0$``"(!F`H```$W`5\```!`-T```````(DX0``````` +XMY!X``'X3```C96-P``$V.@X``!T?```DMPH```$V"0$``&8?```KD`4``$`3 +XM```ET```#O(```,;<*```!7PD!```X(0``%VES:``!8(('```#D9!_)6ES +XM``%A9@<``&XA```Q!0D```%B%`$``*0A```Q$0D```%C7P```-PA````,@&( +XM"````?D!L#E```````#%/$```````!(B``"S%```(V5C<``!^#H.``##(@`` +XM)7,``?H0"@``#",``#&W"@```?L)`0``52,``"5IL'```!__@```"3)```,3P* +XM```!__@```#<)```'!$)```!``%?````."4````SDP@```*'`0%?`````]P4 +XM```T7V,``H`(#`0``('-R8P`!>`(#`0``(&5N9``!>`(#`0``.3\( +XM```!>0)?`````#.?"0```=X"`;@````!:Q<``#1S``'=`A`*```[``@```'= +XM`FL7```@:60``=\"H`X``"!B``'@`@,!```@$"%`$``#D1"0```>(" +XM7P`````'"!0!```X7@D```$@`@$!V1<``#1E8W```1\".@X``#1S``$?`A`* +XM```@;W-H``$A`H('```@;"````;4!7P````$,&```.F5C +XM<``!M#H.```HMPH```&T"0$``"IS86,``;:U"````#B>"````X8```V:18```8J```M7A8````U=18``"`(```!E0&7 +XM&0``+8\6```M@Q8``#R`"```/9D6```\*@``/:46``!R*@``,+$6```PO18` +XM`#W'%@``#RL``##3%@``/=T6``#=*P``/><6``#1+```,/$6```O_18```.1 +XML'XP"1<``#<6%P``H`D```%[`BTR%P``+2@7```\X`D``#T^%P``Q2T``#!) +XM%P``,%,7```]7A<``),N````````-6T5``!`"@```9`!,AH``"V'%0``+7L5 +XM```\H`H``#V1%0``W"X``"^=%0```Y'0?B^I%0```Y&P?R^U%0```Y&0?SW! +XM%0``)2\``"_-%0```Y&H?B_9%0```Y&@?B_E%0```Y&8?B_Q%0```Y&0?CW\ +XM%0``NB\``#`(%@``/1(6```\,```/1X6``#1,```/2H6```M,0`````^V1<` +XM`+Y`0```````X4!````````!H@%T&@``+?47```MZA<``"[-0$```````.%` +XM0```````/0`8``!C,0`````W#!@``)`,```!HP$M&A@``#SP#```/208``"L +XM,0``/2\8```N,@``-[,4``!P#0```=D"-M`4``!W,@``+<44````````/SP) +XM```"BMP4```!`4#%!````J`!7P````$!`-@)```"`-X%```(`0T'```!)@L` +XM`.$#``"024```````(5-0```````$`@```(!!JL!```"`0BI`0```@(%NP4` +XM``("!]$&```#!`5I;G0`!$T#```".%L````"!`>6`@```@@%70,```2&`@`` +XM`CIT`````@@'D0(```((!(<#```"!`2I`P``!/4$```"4FD````%"`<&"`(! +XM!K(!```$3P,```->4`````2(`@```V-I````!PB9````!PC"````")D````$ +XM]P0```/HB0````3[`@``!":K````!-<#```$**L````$I@4```0KH`````0P +XM"0``!"VK````"3@$9W`L```1KT@````(C$`J("P``!&S2`````B,8"CP+ +XM```$;?,````"(R`*@`L```1N\P````(C*`I7"P``!&_S`````B,P``0Q"P`` +XM!'#^````"T5L9@`%)HT!```,M@,```$$!@$```4GG@$```P%`0```0T$!57C +XM`0``#A\$````#L\%```!#G8$```"#M\!```##IX#```$#@T````%#L4%```& +XM#LH"```'#BX"```(``<(DP$```1?"P``!B]W`0``!P@T`````@@%6`,```D( +XM!R08`@``"E8%```')$$"```"(P``#T,-```0!R%!`@``"K<*```'(KP````" +XM(P`*7@0```,!```" +XM(P@0;W,`!T;C`0```B,0$&)U9@`'1Y<````"(Q@0;V9F``=(JP````(C(!!S +XM>@`'2:L````"(R@08V%P``=*JP````(C,`HV"@``!TNK`````B,X"MT(```' +XM3*L````"(T`*WP0```=-20````(C2`JQ````!TY)`````B-,"JL$```'3TD` +XM```"(U`*W0H```=1>P,```(C6`HM`P``!U)Z!````B-H``<(H`,```<(;@0` +XM``D0!U*?!```"E<%```'4FX$```"(P`*.`(```=2=`0```(C"``/*`4``!`' +XM7L@$```*UP(```=>;@0```(C``H$!P``!UYT!````B,(``D(!U_?!```"E8% +XM```'7TX%```"(P``#[L"``!`!U9.!0``$&]F9@`'5ZL````"(P`09G-Z``=8 +XMJP````(C"!!MI3@4```(C``H#!P``!ZF@!0```B,(``<(3@4```D0!ZK+!0``"M8"```' +XMJA,#```"(P`*`P<```>JRP4```(C"``'"!,#```)$`>K]@4```K6`@``!ZMU +XM`P```B,`"@,'```'J_8%```"(P@`!PAU`P``"1`'K2$&```*U@(```>M00(` +XM``(C``H#!P``!ZTA!@```B,(``<(00(```D0!Z],!@``"M8"```'KT$"```" +XM(P`*`P<```>O(08```(C"``)$`>Q<08```K7`@``![%N!````B,`"@0'```' +XML70$```"(P@`#R,```#P!VXX"```"I4#```';[P````"(P`*H0````=R20`` +XM``(C"`JV!P``!W-)`````B,,$&EE8P`'=4D````"(Q`0;V5C``=V20````(C +XM%!!E:6X`!W#@(```"(R`*Q@$```=Z20````(C*`HJ +XM!```!WM)`````B,L$&YO"20````(C-`I/`0`` +XM!X-)`````B,X"KT'```'A$D````"(SP*S0$```>%20````(C0`IC````!X9) +XM`````B-$"D4%```'ATD````"(T@*X`P```>);@0```(C4`IJ#0``!XIN!``` +XM`B-8"N8)```'BVX$```"(V`*?@8```>35`4```(C:`I^"@``!YM)`````B-L +XM"J\'```'GCX(```"(W`*\P8```>A/@@```(C>`KM!@``!Z3T`0```R.``0I4 +XM!P``!Z?T`0```R.(`0HP`0``!ZE[!0```R.0`0H'````!ZJF!0```R.@`0HV +XM`0``!ZO1!0```R.P`0IX!@``!ZW\!0```R/``0J,!```!Z\G!@```R/0`0J( +XM!P``![%,!@```R/@`0`'"((!```'"*L````1$0L```%5`0%Q"```$G-E9P`! +XM5$X%```2=``! +XMA\<```#M-```'FD``8A)````$#4````@`08+```!9`%@3$```````(5-0``` +XM````634``!5E8W```6/Q"```SC4``!-S96<``65.!0``'Z`+```!9ND!```# +XMD:!_&,8!```!9\<````7-@``$VD``6A)```````!$P```@")!P``"`$-!P`` +XM`9L,``#A`P``D$U```````#:9D```````&4)```"`0:K`0```@$(J0$```(" +XM!;L%```#^@$```(V30````("!]$&```$!`5I;G0``TT#```".&8````"!`>6 +XM`@```TP&```".7@````""`5=`P```X8"```".HH````""`>1`@```@@$AP,` +XM``($!*D#```#]00```)2?P````4(!P8(`@$&L@$```-.!@```T]M`````_P! +XM```#64(````#3P,```->6P````.(`@```V-_````!PBO````!PCN````"*\` +XM```#]P0```/HGP````((!5@#```#C0H```0FS`````.\#```!"?!`````Q$( +XM```$*LP````)$`2W@P$```I+#0``!+@;`0```B,`"A4-```$N04!```"(P0* +XMJP(```2Z&P$```(C"`H-#0``!+LT`````B,,"O,,```$O#0````"(PT*_`P` +XM``2]$`$```(C#@`##@P```2^)@$```/[`@``!2;7`````YN@$```(C+`KF"@``!5_%`0```B,P"NL( +XM```%8,4!```"(S@``[P(```%8=`!```)$`6#E0(```K%"0``!82.`0```B,` +XM"O8(```%A<4!```"(P@``ZP)```%AG`"```)&`6)TP(```K%"0``!8J.`0`` +XM`B,`"O8(```%B\4!```"(P@*0PH```6,KP$```(C$``#[PD```6-H`(```D8 +XM!;X[`P``"DL-```%O[H!```"(P`*#0T```7`-`````(C!`KS#```!<$T```` +XM`B,%"OP,```%PID!```"(P8*%0T```7#C@$```(C"`JK`@``!<3%`0```B,0 +XM``,U#```!<7>`@``"T5L9@`&)E$#```,M@,```$#!@$```8G8@,```P%`0`` +XM`0T$!C8!!```#C$%````#IH'```!#N8%```"#K$%```##LP#```$#K\&```% +XM#HX'```&#DP$```'#I`%```(#E`````)#GP"```*#OH````+#F<'```,#GX% +XM```-#I<$```.#IP&```/#B$"```0#B(!```1#B(&```2#NH````3#N$"```4 +XM#GP#```5#@X!```6#OX$```7``/B"```!D]H`P``"0@&>",$```*5@4```9X +XMK@0```(C```/U0D``$`&:*X$```*-`H```9LUP````(C``I8"0``!FVM```` +XM`B,("A(*```&;M<````"(Q`*_@<```9OUP````(C&`K;"```!G`!!````B,@ +XM"JH*```&<68````"(R0*.0@```9VM`0```(C*`I\"@``!G=F`````B,P"B,) +XM```&>`P$```"(S@`!P@C!```!PA7`P```]8)```&>2,$```#6P@```@`(2=<````" +XM(R@08V%P``A*UP````(C,`HV"@``"$O7`````B,X"MT(```(3-<````"(T`* +XMWP0```A-5`````(C2`JQ````"$Y4`````B-,"JL$```(3U0````"(U`*W0H` +XM``A1:P8```(C6`HM`P``"%)J!P```B-H``<(D`8```<(7@<```D0"%*/!P`` +XM"E<%```(4EX'```"(P`*.`(```A29`<```(C"``/*`4``!`(7K@'```*UP(` +XM``A>7@<```(C``H$!P``"%YD!P```B,(``D("%_/!P``"E8%```(7SX(```" +XM(P``#[L"``!`"%8^"```$&]F9@`(5]<````"(P`09G-Z``A8UP````(C"!!M +XME0````"(R@**@0```A[5`````(C+!!N;W,`"'U4`````B,P"C$$```(@E0` +XM```"(S0*3P$```B#5`````(C.`J]!P``"(14`````B,\"LT!```(A50````" +XM(T`*8P````B&5`````(C1`I%!0``"(=4`````B-("N`,```(B5X'```"(U`* +XM:@T```B*7@<```(C6`KF"0``"(M>!P```B-@"GX&```(D[$(```"(V@*?@H` +XM``B;5`````(C;`JO!P``")Z;"P```B-P"O,&```(H9L+```"(W@*[08```BD +XMH0L```,C@`$*5`<```BGH0L```,CB`$*,`$```BIV`@```,CD`$*!P````BJ +XM`PD```,CH`$*-@$```BK+@D```,CL`$*>`8```BM60D```,CP`$*C`0```BO +XMA`D```,CT`$*B`<```BQJ0D```,CX`$`!PA&`P``!PC7````!P@T````$:\+ +XM```!00%4````D$U```````"@34````````)W"-8+```2E@#```&W,``>M>!P``'(,,```![``.```<[@P```'MH0L``!MI[% +XM!```&W-Y;0`![]`$```;:60``?`&#@``&VES``'QM`0``!SG"P```?+S```` +XM&VYD>``!\O,````<"`P```'R\P```!MS8P`!\O,````<\P8```'R\P```!P? +XM#````?/S````'`4-```!\_,````(````<9PP```'UX@```!ME8P`!]E0````<$0D```'V5````!MI``'V +XM5````!T_#````9L!``<(1`@```<(N@0``!X>#0```58!5`````%0#@``&F5C +XM<``!5&`,```:@` +XM````(&X,```!@`(!5`````&%#@``(65C<``!?P)@#```(K<*```!?P+H```` +XM&',``8$",04````94PT```%Z`0$5#P``&F5C<``!>6`,```:^@````;9``!?`8.```;B@P```',`50````!1`\``!IE8W````!5`````%?#P``&G,``=_6 +XM"P```![1"P```38!5`````%Z#P``&G,``376"P```"`G#````3H"`!])P`- +XM```@#@```>,!M!(``"@-#0``*<`.```J&`T``-0[```K(0T``"HL#0``R#P` +XM`"PW#0```Y&@?2Q"#0```Y&`?RI-#0``@#T``"I7#0``.#X``"IA#0``S3X` +XM`"IL#0``,3\``"MW#0``*X(-```JC`T``%0_```KEPT``"JB#0``S3\``"JM +XM#0``%$(``"JX#0``7T,``"K##0``GT0``"K.#0``-$4``"K9#0``F$4``"KC +XM#0``YT4``"KN#0``[D8``"WW#0``:%%````````N#`X``"`4```!<@$H1`X` +XM`"@[#@``*#(.```H*`X``"@=#@``+U`.```W6$```````%U80````````5O1 +XM$0``,&X.```11P``*&(.```Q-UA```````!.6$```````"IZ#@``1T<````` +XM,H4.``#P%````6=4$@``,)T.``#O1P``*)(.```ID!4``"JG#@``$D@``"JR +XM#@``6T@``"J[#@``*$D``"S$#@```Y&@?RS-#@```Y'@?BS7#@```Y'@?"KA +XM#@``T$D``"KJ#@``G4H``"KU#@``:DL``"H`#P``O4P``"L)#P`````R%0\` +XM`#`7```!:902```H.@\``#`Q#P``BDT``"@F#P``,T0/```56T```````"A; +XM0````````=@\``&`7```!)0(HC`\``"GP%P``+)8/```#D>!\+*(/```#D>!^*JX/ +XM``!_3@``*KD/```!3P``*\4/```JT`\``(-/```KW`\````````(`P```@`S +XM"@``"`$-!P```78-``#A`P``X&9````````/:4```````!(-```"`0:K`0`` +XM`@$(J0$```("!;L%```"`@?1!@```P0%:6YT``($!Y8"```""`5=`P``!(8" +XM```".FD````""`>1`@```@@$AP,```($!*D#```$]00```)27@````4(!P8( +XM`@$&L@$```3W!````S)^````!PB.````!PBL````"(X````""`58`P``!(@" +XM```$8UX````$!@$```4GS@````D%`0```0<(PP````H0!E'_````"U<%```& +XM4@`&2;@````"(R@-8V%P``9*N`````(C,`LV"@`` +XM!DNX`````B,X"]T(```&3+@````"(T`+WP0```9-20````(C2`NQ````!DY) +XM`````B-,"ZL$```&3TD````"(U`+W0H```91V@````(C6`LM`P``!E+9`0`` +XM`B-H``<(_P````<(S0$```H0!E+^`0``"U<%```&4LT!```"(P`+.`(```92 +XMTP$```(C"``.`7X-```!5P%)````X&9```````!O9T```````,Q/``"#`@`` +XM#W0``5;-`0``?5````]S``%6I@```-E0```08@`!6*8````040``$&,``5BF +XM````1E$``!!R``%8I@```'Q1```0;&5N``%9E0```+)1```1<0T```%9E0`` +XM`.A1````$@%@#0```2D!<&=````````/:4```````!Y2```/=``!*,T!``#/ +XM4@``#W,``2BF````*U,``!-R``$JI@```!!B``$KH````&-3```08P`!*Z`` +XM``"P4P``$&QE;@`!+)4```#Y4P``$7$-```!+)4````O5```$5L!```!+4D` +XM``!X5``````!$0$E#A,+`PX;#A$!$@$0!@```B0`"PL^"P,.```#%@`##CH+ +XM.PM)$P``!"0`"PL^"P,(```%)``+"SX+```&#P`+"P``!P\`"PM)$P``""8` +XM21,```D6``,..@L[!4D3```*$P$##@L+.@L["P$3```+#0`##CH+.PM)$S@* +XM```,#0`#"#H+.PM)$S@*```-%0$G#$D3`1,```X%`$D3```/$P`##CP,```0 +XM`0%)$P$3```1(0!)$R\+```2$P$+"SH+.PL!$P``$Q8``P@Z"SL+21,``!0$ +XM`0L+.@L["P$3```5*``##AP-```6!`$##@L+.@L["P$3```7+@`##CH+.P4G +XM#!$!$@%`!@``&"X!`PXZ"SL%)PP@"P$3```9!0`#"#H+.P5)$P``&BX!`PXZ +XM"SL+)PP@"P$3```;!0`#"#H+.PM)$P``'#0``PXZ"SL+21,``!TT``,(.@L[ +XM"TD3```>+@$##CH+.P4G#!$!$@%`!@$3```?!0`#"#H+.P5)$P(&```@-``# +XM#CH+.P5)$P(&```A-``#"#H+.P5)$P(&```B-``##CH+.P5)$P``(QT!,1-5 +XM!E@+604``"0%`#$3```E"P%5!@``)C0`,1,"!@``)S0`,1,""@``*`4``PXZ +XM"SL%21,``"DT``,(.@L[!4D3```J+@$_#`,..@L[!2<,21,1`1(!0`8!$P`` +XM*P4``PXZ"SL%21,"!@``+!T!,1-5!E@+604!$P``+30`,1,``"XT``,..@L[ +XM"TD3`@H``"\T``,..@L["TD3/PP\#```,#0``PXZ"SL%21,_##P,`````1$! +XM)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```Q8``PXZ"SL+21,```0D``L+ +XM/@L#"```!20`"PL^"P``!@\`"PL```+@$##CH+.P4G#!$!$@%`!@$3```?!0`##CH+.P5)$P(&```@ +XM-``#"#H+.P5)$P``(2X!/PP##CH+.P4G#$D3$0$2`4`&`1,``"(N`3\,`PXZ +XM"SL+)PQ)$Q$!$@%`!@$3```C!0`#"#H+.PM)$P(&```D!0`##CH+.PM)$P(& +XM```E-``#"#H+.PM)$P(&```F+@$##CH+.PLG#$D3$0$2`4`&`1,``"+@$# +XM#CH+.PLG#$D3(`L!$P``'P4``PXZ"SL+21,``"`N`0,..@L[!2<,21,@"P$3 +XM```A!0`#"#H+.P5)$P``(@4``PXZ"SL%21,``",T``,..@L[!4D3```D+@$_ +XM#`,..@L[!2<,$0$2`4`&```E-``#"#H+.P5)$P(*```F-``##CH+.P5)$P(& +XM```G'0$Q$U4&6`M9!0$3```H!0`Q$P``*0L!508``"HT`#$3`@8``"LT`#$3 +XM```L-``Q$P(*```M"@`Q$Q$!```N'0$Q$U4&6`M9!0``+QT!,1,1`1(!6`M9 +XM"P$3```P!0`Q$P(&```Q"P$1`1(!```R'0$Q$U4&6`M9"P$3```S'0$Q$Q$! +XM$@%8"UD+`````1$!)0X3"P,.&PX1`1(!$`8```(D``L+/@L##@```R0`"PL^ +XM"P,(```$%@`##CH+.PM)$P``!20`"PL^"P``!@\`"PL```7!E2YH````````"0)@'$````````/9 +XM!`%(")P#=_U(")P#=_U(")P#X7W]`BL5`WHY6V4(D0,9C>(X`[E__0BO`Q(( +XMJ0-P_0@2"*T#\GX('4D(9@A`13OR"&=84J)#4E:JG9R!99V<2PB"`B03@8(( +XMGTFLGH4(6H*""&>"-CQ7`P^-<@AR.%8#"6,(67*!`QH(8P,*C0-Z_0,W")N4 +XM@(`#QWX".`$#E`&-G#@Z`PVIG#@Z9@@["$@(0(X(6`/J?L7"`_L`Q8%%.U8X +XM.F(\U%:.@/Y&`^-^?P,2C0/Y``@K_P-6"%4#QP`(Q0.&?P@Y`R,(Q0/=``C% +XM`[Y_"'\#F7\(Q0-B",4(S`/J``C%`\L`",4#I7\(.0/8``C%`^E^_0-YX0.4 +XM`?T#G@+OGE+(R9PX.F7F?8^XN+6`@;BXLX"%`WH('8#P\/16CU-)BTD(5P/O +XM?0A_"/$#P@`",0$#OG^W`P\(X0-Q""L#"M,#=@@=QP@ZR'(#%M,#=0AQ"#K( +XM7,``'-E8W1I;VYS+F,````` +XM7!E2YH````````"0+P*T````````/D`0&X"%24`B@2<@-W8P.\!0CA +XM"*!)"$J.CDB`CHZ`>EP(3[U(.%8($W*`2(!R;DP(R`-L",5(1DA&2`-KFP,, +XM",4##PC%`PL(Q0.J?P(H`:X#$PA'9P-I"&.."!3G@-D('_562@-CC0,6",4( +XMR@-/`B0!UD0]=V324,;&Q@-#"#GI"+@($P@L"$H(G4$#>#DZ@$AR@$A#2PAE +XM"!)RA31,-$A(Q0C(`PK]`PH(Q0C-`ZU_`BP!D0,7 +XMTP-NC0A+`PEQ9("`9(`#;6,#%0@Y5DH#;7$Z?CN`9(`##F,#:7$#%0C%`TT" +XM)P$(Q692/-8(/59B`DH05^0#=`(H`0C(",P#O7X")0&A"'?&E0C6"%:%"!)) +XM-U:.`V+%N`,2C0-M?P,BC0-J"!W&`PW]",H#Z7T")`$#"HT(2@B>6%)*U45) +XM-ZX(+#A(,&"`4@@24CP#%D)L(/<:0`B,,`Q$(1P,58P-K*P,-.0-S*TX(6@A( +XMQ@@\"&<##0@K`WF-20-6 +XM[PCU"*LZ2%E?2(Z.@`,3X0,+"'%6D`-KX0-6",4(R`,B",4#<0C%`V3A`\,` +XM",4#[`(")@$@1%B=!`(#QGW]_@0!`[<"Q8YT!`(#Q'T(.<8$`0.W`CD$`@/) +XM?4<$`0.W`G$$`@/)?3D$`0.W`CDQ;0@M!`(#Q'W]R`0!`W$(Q?U8`\0![WV! +XM10.^?G''@P,)`C5HPZ.%:/"!Y^5E0ML)=9ROB.`POA +XM`VF;JP-L?P.9?@A'A0.6`0CA`X5]J>(#E00(.0A:_`@[5H,$`@.O?0A'_@0! +XM`YH""!W4""P#<=,(2`,850@75GX#C'R-`XP$"-,#89OBN.XZ5M0#=M,#6PAC +XMX@/G``AQ`VS]`]Q^"%4(9PC_"&8('C@ZGP)B"XYR`E\1`X)_"/V`R@,="/T( +XM@@@>.%8"-!4(UP(M$3<[9M3GK`-G`DP!JJH(Y@,*",6L!`(#BW\"3P$$`0/X +XM`.$"91$"1@T#A@$"1@$#S0#A`Z]^")OX`D@-`E`*`W`(Q0/-`)L##0C%`WD( +XMQ0-)",4#9PC]`QT([U8J+&?H"#T"*Q$#8\4#$@)"`0(4``$!40$```(`E@`` +XM``$!^PX*``$!`0$````!+W5S7!EG$Q`VL('=,\ +XM4CS(.@BXW0-P")O3/%(\R#H(N-T#ZWX(FP,)*P-W50@CCH_&"(\(U@C7`YM^ +XMJ0B""$L(H`AS.PC4.')JA@-XFPAR"#P")!(('LE6@[QZ+P@Z"#P")!,(6%:" +XM`R.-"!XX5@/*``(D`0(E$`(U$PAGC@C&JKBX@8Y4@&8#;`+5`0$#&<6`"!YP +XM+`@>"&%TG@(F$8#&`R#%C@,4J0,5J0B0<@,+?P-V50,*50-V58`#+4<#5']R +XM;TNXP.5?W&<`]<`FP,; +XM"!U6`U=_40,+?P-W?[B_`WE52*JXN*JDAL@(Q@-'",4(D+%R\(!(G\#M`%_`[!^`D$! +XM`R)5`WI'`[.%Y\@/L?0CO`ZL$""L(9`.4?N$#4(T#>0@K`_Y]"$<( +XMUW0#Z0#O`B86`Y9_J<@#254#O@((8P(N$`@>"#RO"$@#"0+4`0$(/+M4.H", +XM4PBO"'*`.$@#OWX(?P,+"$<#F`$(*P@ZJ@A(`LH!%@+1`18(.@-X`B\!"#<( +XM.PCM".P#D'\"S0$!`_4`TP,Q`B@!`TW]`YA^`BT!`ZD#",4#O'X(Q0CM`S@( +XMX0-*`C0!"#<#@@$(.7*X@$AR;P.Q?\4#2@+,`0$"+A$#-`(N`0-/"#D#,P(E +XM`0,V`D.')F"*X( +XM<@B?"!8")!("(Q0(9`AP:`(W$`A6*CK&V@(F$^,(\4@#;[<#U0$(C0(I$0,T +XM`B,!`ZQ_`BX!5BHL`_,!")L#XGX(?P/_?@(J`0.-?_U6*BP#[P#3`Y)_*P-# +XM"'\#]@#A",D(%`.$?^$#AP,(Q0.G?0C%`BL45BHL`_8!Q0.@`0(K`0/7?'$" +XM(Q,(/`-Z",4"'@`!`0(!```"`(D````!`?L."@`!`0$!`````2]U7!EG\_`W5Q`PM5`T&W_4VX@`C)CT4[Z`,) +XM50-Q?P@>JL<#%PA5`VOA5PA6.GY(.$@#"0(D`4A&2`@;RDBX.%:`N`-ZX0-E +XM_0@``0$`%````/____\!``%X$`P'")`!````````'`````````!@'$`````` +XM`"D`````````1`X0```````<`````````)`<0```````*0````````!$#A`` +XM`````!P`````````P!Q````````I`````````$0.$```````+`````````#P +XM'$```````(\&````````2H\"A@9A#N`!C@.-!(P%@P<`````````/``````` +XM``"`(T```````'`(````````0@X0CP)%#AB.`TH.($(.*$$.,$$..$<.T`&# +XM!X8&C`6-!````````!0```#_____`0`!>!`,!PB0`0```````!0```#H```` +XM\"M```````!]`````````"0```#H````<"Q```````"V`0```````$J#!8P# +XM40YPC0*&!``````L````Z````#`N0```````!P$```````!"#A!!#AB&`XP" +XM1`X@1`Y@@P0````````<````Z````$`O0```````:P````````!.#B"#`X8" +XM`#0```#H````L"]```````#B`0```````$(.$$(.&(T#C@)%#B!!#BA!#C!$ +XM#G"#!H8%C`0`````)````.@```"@,4```````/0`````````00X0A@)$#AA$ +XM#B"#`P```"0```#H````H#)````````Y`0```````$J&!(,%5`ZP`8T"C`,` +XM```L````Z````.`S0```````.@$```````!"#A!"#AA!#B!!#BA$#G"#!88$ +XMC`.-`@`D````Z````"`U0```````_P````````!!#A"&`D0.&$0.8(,#```` +XM+````.@````@-D```````*(`````````0@X0C0)%#AB,`T0.((8$1`XH1`XP +XM@P4`'````.@```#0-D```````"(`````````1@X0```````<````Z``````W +XM0```````-P````````!$#A```````"0```#H````0#=```````!)`0`````` +XM`%J,`X,%C0*&!$<.8``````L````Z````)`X0```````%0$```````!"#A", +XM`D0.&(8#0PX@@P1(#G`````````\````Z````+`Y0```````%0,```````!" +XM#A!'#AA"#B!"#BA!#C"&!HP%C02.`X\"20XX1`Z0`8,'````````)````.@` +XM``#0/$```````-L`````````00X0A@)%#AA$#B"#`P```#P```#H````L#U` +XM``````#3"P```````$(.$$(.&$(.($(.*$$.,$$..$<.D`*#!X8&C`6-!(X# +XMCP(````````4````_____P$``7@0#`<(D`$````````4````X`,``)!)0``` +XM````V0`````````T````X`,``'!*0```````[@$```````!"#A!"#AA"#B!! +XM#BB&!8P$C0..`D0.,$0.L`&#!@```"P```#@`P``8$Q````````E`0`````` +XM`$(.$$$.&$$.((,$A@.,`D<.8````````!0```#_____`0`!>!`,!PB0`0`` +XM`````!0```!X!```D$U````````0`````````!0```!X!```H$U````````0 +XM`````````"0```!X!```L$U```````!!`````````$$.$(8"1`X81`X@@P,` +XM```<````>`0```!.0```````9@````````!.#B"&`H,#`!P```!X!```<$Y` +XM``````!F`````````$X.((8"@P,`/````'@$``#@3D```````/H7```````` +XM0@X01PX80@X@C02.`X\"10XH00XP00XX1P[@!(,'A@:,!0```````!0```#_ +XM____`0`!>!`,!PB0`0```````#P```!H!0``X&9```````"/`````````$(. +XM$$(.&$(.($(.*$$.,$$..(,'A@:,!8T$C@./`DH.0``````````\````:`4` +XM`'!G0```````GP$```````!"#A!"#AA"#B"-!(X#CP)%#BA!#C!!#CA$#E"# +XM!X8&C`4`````````7V5X=')A`'9?F4`5]L;VYG;W!T +XM`!%3$9?0U].54Q,`&]P +XM:&YU;0!S96-T:6]N6U?;&ES=`!S=')I<%]L;VYG;W!T6U?:V5E<`!%3$9?5%]32$12`'-A8U]L:7-T`&YO8V]P>0!? +XM6U?F4`14Q&7U1? +XM4U=/4D0`8W)E871E7V9I;&4`7U]F9FQA9W-?=`!%3$9?5%](04Q&`&]P=&%R +XM9P!S:&]R="!U;G-I9VYE9"!I;G0`14Q&7TM?05(`=E]R96P`6YC7W-E8W1I;VYS`$5L +XM9C8T7U-H9'(`:7-?'0`;G-E8W,`16QF-C1?6'=O`!R7V%D9&5N9`!R96PV-`!I +XM@!A9&1?=&]?:6YS96=?;&ES=`!P7V%L:6=N`$=% +XM;&9?4&AD<@!P7V9L86=S`'!?='EP90!P7W9A9&1R`'!?;65M6UB;VQS`&ES7V1E8G5G7W-Y;6)O;`!S=%]S>@!I +XM6T`5]C87``8V%L8U]N;VYL;V-A;`!%;&8V-%]3>6T`8W)E +XM871E7W-E8W-Y;0!'16QF7U-Y;0!A9&1?=&]?:V5E<%]L:7-T`'-T7V)U9@!L +XM;V]K=7!?5]B=68`:7-?;F5E9&5D7W-Y;6)O;`!S +XM>6UB;VQS+F,`:7-?;&]C86Q?6UB;VP`;'-Y9&%T80!L;V]K=7!?:V5E<%]S>6UL:7-T`'-T7VYA +XM;64`;6%R:U]S>6UB;VQS`&EN>@4````````?!P````````$`7@`````````````````````&`0`````` +XM``D!`````````0!0"0$````````,!`````````$`7"P$````````-00````` +XM```!`%QQ!````````'0$`````````0!0=`0```````#I!`````````$`7$T% +XM````````:04````````!`%R0!0```````-\&`````````0!<\`8````````0 +XM!P````````$`7``````````````````````O`P```````+H#`````````0!3 +XMVP,```````#\`P````````$`4Z,$````````SP0````````!`%/@!0`````` +XM`!<&`````````0!3CP8```````"M!@````````$`4\$&````````WP8````` +XM```!`%,`````````````````````?`(```````"Z`P````````,`D;A_VP,` +XM```````L!`````````,`D;A_HP0```````#I!`````````,`D;A_5@4````` +XM``!I!0````````,`D;A_P@4````````7!@````````,`D;A_CP8```````"M +XM!@````````,`D;A_P08```````#?!@````````,`D;A_\`8```````#_!@`` +XM``````,`D;A_`````````````````````"`'````````(@<````````"`'<( +XM(@<````````G!P````````(`=Q`G!P```````#$'`````````@!W&#$'```` +XM````,P<````````"`'<@,P<````````T!P````````(`=R@T!P```````#4' +XM`````````@!W,#4'````````/`<````````"`'`````````````````````"`'````````00<````` +XM```!`%1!!P```````(8-`````````0!?U0T```````"0#P````````$`7P`` +XM``````````````````!I!P```````&X'`````````0!540D```````!6"0`` +XM``````$`58()````````APD````````!`%6?"0```````*0)`````````0!5 +XMT`D```````#5"0````````$`58$+````````C`L````````!`%4U#``````` +XM`#H,`````````0!5/0P```````!"#`````````$`59T-````````H@T````` +XM```!`%7.#0```````-,-`````````0!5X@T```````#G#0````````$`5:4. +XM````````J@X````````!`%7)#@```````,X.`````````0!5W0X```````#B +XM#@````````$`55(/````````7@\````````!`%4````````````````````` +XMA`@```````"<"`````````$`4%H)````````>`D````````!`%"H"0`````` +XM`,8)`````````0!0]@T````````"#@````````$`4``````````````````` +XM```P#````````#H,`````````0!420P```````!0#`````````$`5``````` +XM```````````````I#````````#H,`````````0!120P```````!0#``````` +XM``$`40````````````````````#\"0```````/\)`````````0!0_PD````` +XM```>"@````````$`75`*````````4`H````````!`%T6#@```````"<.```` +XM`````0!=,0X```````!"#@````````$`70````````````````````"$"``` +XM`````/\)`````````0!=4`H````````4"P````````$`7=$+````````7`P` +XM```````!`%WV#0```````!8.`````````0!=0@X```````!G#@````````$` +XM70````````````````````"$"````````!X*`````````0!3G@H```````"A +XM"@````````$`4*$*````````%`L````````!`%/1"P```````%P,```````` +XM`0!3]@T````````'#@````````$`4Q8.````````)PX````````!`%,Q#@`` +XM`````$(.`````````0!34PX```````!G#@````````$`4P`````````````` +XM``````"$"````````)P(`````````0!0GP@```````#;"`````````$`4.(( +XM````````5@D````````!`%!X"0```````(<)`````````0!0C`D```````"D +XM"0````````$`4,8)````````U0D````````!`%#:"0```````/D)```````` +XM`0!0\@L````````)#`````````$`4`X,````````$PP````````!`%!0#``` +XM`````%4,`````````0!0`````````````````````!X*````````1@H````` +XM```!`%,'#@```````!8.`````````0!3`````````````````````#H,```` +XM````0@P````````!`%`[#0```````'H-`````````0!0```````````````` +XM`````!T+````````T0L````````!`%;2#````````&H-`````````0!6U0T` +XM``````#V#0````````$`5B<.````````,0X````````!`%8````````````` +XM````````&PL````````E"P````````,`D;!^)0L````````M"P````````,` +XMD;1^+0L````````P"P````````,`D;A^,`L````````R"P````````$`73(+ +XM````````,@L````````!`%,R"P```````$L+`````````P"1L'Y+"P`````` +XM`&P+`````````0!3;`L```````!R"P````````$`4W(+````````APL````` +XM```!`%.'"P```````(X+`````````0!=C@L```````"6"P````````$`4Y8+ +XM````````F`L````````#`)&T?I@+````````H`L````````!`%.@"P`````` +XM`*(+`````````P"1N'ZB"P```````+`+`````````0!3L`L```````"R"P`` +XM``````,`D;!^L@L```````#1"P````````$`4SH,````````20P````````# +XM`)&T?M(,````````^@P````````!`%/Z#`````````H-`````````P"1M'X* +XM#0````````P-`````````P"1L'X,#0```````!0-`````````0!3%`T````` +XM```S#0````````,`D;A^,PT```````"!#0````````$`4X$-````````E0T` +XM```````#`)&P?I4-````````U0T````````#`)&T?M4-````````]@T````` +XM```!`%,G#@```````#$.`````````0!3`````````````````````$4+```` +XM````3@L````````!`%#2#````````.(,`````````0!0)PX````````L#@`` +XM``````$`4``````````````````````Z#````````$D,`````````0!6:@T` +XM``````!Z#0````````$`5GH-````````E0T````````!`%"5#0```````-4- +XM`````````0!6`````````````````````(`,````````F`P````````!`%"Q +XM#@```````+\.`````````0!0`````````````````````&,(````````_PD` +XM```````!`%T4"P```````#`+`````````0!=\@L```````#2#`````````$` +XM7?8-````````!PX````````!`%UG#@```````&@/`````````0!=B0\````` +XM``"0#P````````$`70````````````````````!<#````````)@,```````` +XM`0!0FPP```````#+#`````````$`4&<.````````J@X````````!`%"_#@`` +XM`````,X.`````````0!0TPX```````#B#@````````$`4.<.````````"@\` +XM```````!`%``````````````````````.@P```````!)#`````````$`5CD/ +XM````````10\````````!`%9%#P```````%4/`````````0!050\```````!H +XM#P````````$`5@````````````````````"``````````)L``````````@!W +XM")L`````````-@(````````#`'?P``````````````````````"````````` +XM`*8``````````0!5I@````````"1`0````````$`7)L!````````-@(````` +XM```!`%P`````````````````````GP````````",`0````````$`5IL!```` +XM````-@(````````!`%8`````````````````````!0$````````(`0`````` +XM``$`4`@!````````AP$````````!`%.;`0```````+X!`````````0!3W`$` +XM```````V`@````````$`4P````````````````````!``@```````$("```` +XM`````@!W"$("````````0P(````````"`'<00P(```````!'`@````````(` +XM=QA'`@```````$L"`````````@!W($L"````````1P,````````#`'?@```` +XM``````````````````!``@```````%P"`````````0!57`(```````#M`@`` +XM``````$`5O`"````````1P,````````!`%8`````````````````````4@(` +XM``````#L`@````````$`4_`"````````1P,````````!`%,````````````` +XM````````Y0(```````#P`@````````$`4"P#````````,P,````````!`%`` +XM````````````````````4`,```````!>`P````````(`=PA>`P```````+L# +XM`````````@!W(`````````````````````!0`P```````'(#`````````0!5 +XMA0,```````"(`P````````$`50````````````````````!0`P```````&P# +XM`````````0!4;`,```````!W`P````````$`5G<#````````A0,````````! +XM`%2%`P```````+L#`````````0!6`````````````````````&(#```````` +XM?`,````````!`%-\`P```````(4#`````````0!5A0,```````"[`P`````` +XM``$`4P````````````````````#``P```````,(#`````````@!W",(#```` +XM````Q`,````````"`'<0Q`,```````#)`P````````(`=QC)`P```````,H# +XM`````````@!W(,H#````````RP,````````"`',#````````%@4````````!`%T6!0```````!D% +XM`````````0!5&04```````"B!0````````$`70`````````````````````$ +XM!````````!$%`````````0!3&04```````"B!0````````$`4P`````````` +XM``````````#6`P```````!(%`````````0!6&04```````"B!0````````$` +XM5@````````````````````"/!````````)($`````````0!0D@0```````#0 +XM!`````````$`44@%````````4@4````````!`%$````````````````````` +XM#00````````4!0````````$`7!D%````````H@4````````!`%P````````` +XM````````````L`4```````"Q!0````````(`=PBQ!0```````+4%```````` +XM`@!W$+4%````````N04````````"`'<8N04```````"D!@````````(`=R`` +XM````````````````````L`4```````#+!0````````$`5P`0````````````````````"P!@```````-0&`````````0!5U`8` +XM``````!_!P````````$`7(\'````````Z0<````````!`%P````````````` +XM````````L`8```````#9!@````````$`5-D&````````X08````````!`%4` +XM````````````````````L`8```````#A!@````````$`4>$&````````;P<` +XM```````!`%./!P```````.D'`````````0!3`````````````````````+`& +XM````````X08````````!`%+A!@```````'<'`````````0!6CP<```````#I +XM!P````````$`5@````````````````````#P!P```````/('`````````@!W +XM"/('````````]`<````````"`'<0]`<```````#U!P````````(`=QCU!P`` +XM`````/8'`````````@!W(/8'````````^@<````````"`'PL````````!`%1]"P```````(D+`````````0!6I0L```````"G +XM"P````````$`5L(+````````Q`L````````!`%;\"P```````),,```````` +XM`0!6`````````````````````'T+````````?PL````````!`%`T#``````` +XM`#D,`````````0!0:`P```````"##`````````$`4(X,````````F0P````` +XM```!`%``````````````````````H`P```````"B#`````````(`=PBB#``` +XM`````*8,`````````@!W$*8,````````J0P````````"`'<8J0P```````"Q +XM#`````````(`=R"Q#````````+4-`````````P!W\``````````````````` +XM````H`P```````"U#`````````$`5;4,````````+PT````````!`%PP#0`` +XM`````+4-`````````0!<`````````````````````*`,````````K0P````` +XM```!`%2M#````````"P-`````````0!3,`T```````"U#0````````$`4P`` +XM```````````````````2#0```````!\-`````````0!0>0T```````"##0`` +XM``````$`4`````````````````````"H#````````"T-`````````0!6,`T` +XM``````"U#0````````$`5@`````````````````````%#0```````#`-```` +XM`````@"16'D-````````EPT````````"`)%8`````````````````````"<- +XM````````,`T````````!`%$W#0```````$<-`````````0!1```````````` +XM`````````,`-````````P@T````````"`'<(P@T```````#)#0````````(` +XM=Q#)#0```````,L-`````````@!W&,L-````````S0T````````"`'<@S0T` +XM``````#.#0````````(`=RC.#0```````-<-`````````@!W,-<-```````` +XMVPT````````"`'NA````````#5$`````````$`7@`````````````` +XM```````T#@```````)P0`````````P"1N'^Z$````````-40`````````P"1 +XMN'\`````````````````````-`X````````0$`````````$`7140```````` +XMG!`````````!`%VZ$````````-40`````````0!=```````````````````` +XM`/\.`````````@\````````!`%`"#P```````%\/`````````0!1W@\````` +XM``#D#P````````$`4140````````'Q`````````!`%$````````````````` +XM````_P\````````5$`````````$`4+H0````````P1`````````!`%`````` +XM````````````````X!````````#A$`````````(`=PCA$````````.80```` +XM`````@!W$.80````````ZA`````````"`'<8ZA````````"[$0````````(` +XM=R``````````````````````X!````````!'$0````````$`56H1```````` +XM?1$````````!`%6$$0```````(X1`````````0!5K!$```````"Q$0`````` +XM``$`50````````````````````#@$`````````41`````````0!4+!$````` +XM``!$$0````````$`5&H1````````>!$````````!`%2$$0```````(L1```` +XM`````0!4`````````````````````/(0````````;Q$````````!`%-Q$0`` +XM`````+L1`````````0!3`````````````````````/00````````1!$````` +XM```!`%1J$0```````'@1`````````0!4A!$```````"+$0````````$`5*P1 +XM````````MA$````````!`%0`````````````````````]!`````````%$0`` +XM``````$`5"P1````````>!$````````!`%2$$0```````(L1`````````0!4 +XME1$```````"G$0````````$`5`````````````````````#T$````````'T1 +XM`````````0!5A!$```````".$0````````$`5941````````IQ$````````! +XM`%6L$0```````+$1`````````0!5`````````````````````,`1```````` +XMPA$````````"`'<(PA$```````#$$0````````(`=Q#$$0```````,81```` +XM`````@!W&,81````````R!$````````"`'<@R!$```````#)$0````````(` +XM=RC)$0```````,H1`````````@!W,,H1````````T1$````````"`'!8````````!`%5X%@```````)(6`````````P"1 +XMR'Z2%@```````)<6`````````0!5EQ8```````"3'0````````,`DP`0````````````````````#@ +XM`````````%P!`````````0!57`$```````!/`@````````$`5E8"```````` +XMS@(````````!`%8`````````````````````]@````````!A`0````````$` +XM4H4!````````3@(````````!`%-6`@```````)("`````````0!3```````` +XM`````````````/T`````````!`$````````!`%`+`0```````&$!```````` +XM`0!0`````````````````````/T`````````80$````````!`%$````````` +XM````````````H0$```````"J`0````````$`7*H!````````40(````````! +XM`%Q6`@```````)("`````````0!<`````````````````````-`"```````` +XMT@(````````"`'<(T@(```````#3`@````````(`=Q#3`@```````-0"```` +XM`````@!W&-0"````````VP(````````"`'<@VP(```````#U`P````````,` +XM=^```````````````````````-`"````````WP(````````!`%7?`@`````` +XM`*0#`````````0!3J`,```````#U`P````````$`4P`````````````````` +XM``#V`@````````4#`````````@"16`H#````````UP,````````"`)%8```` +XM`````````````````"``````````(0`````````"`'<((0`````````E```` +XM``````(`=Q`E`````````"D``````````@!W&"D`````````80`````````" +XM`'<@`````````````````````"``````````-P`````````!`%5````````` +XM`$8``````````0!56`````````!A``````````$`50`````````````````` +XM```@`````````#4``````````0!4-0````````!7``````````$`5E@````` +XM````8``````````!`%9@`````````&$``````````0!4```````````````` +XM`````#``````````5@`````````!`%-8`````````%\``````````0!3```` +XM`````````````````'``````````?@`````````"`'<(?@````````#6```` +XM``````(`=R``````````````````````<`````````"&``````````$`588` +XM````````P``````````!`%;%`````````-8``````````0!6```````````` +XM`````````'``````````C@`````````!`%2.`````````+L``````````0!3 +XMQ0````````#6``````````$`4P````````````````````#@`````````.X` +XM`````````@!W".X`````````1@$````````"`'<@```````````````````` +XM`.``````````]@`````````!`%7V`````````#`!`````````0!6-0$````` +XM``!&`0````````$`5@````````````````````#@`````````/X````````` +XM`0!4_@`````````K`0````````$`4S4!````````1@$````````!`%,````` +XM````````````````4`$```````!2`0````````(`=PA2`0```````%D!```` +XM`````@!W$%D!````````6P$````````"`'<86P$```````!@`0````````(` +XM=R!@`0```````&$!`````````@!W*&$!````````8@$````````"`'"0```````&D)`````````0!1$!0````` +XM``!%%`````````$`4488````````4!@````````!`%$````````````````` +XM````;@8```````!Q!@````````$`4'$&````````TP8````````!`%%&&``` +XM`````%`8`````````0!1`````````````````````-\#````````KP4````` +XM```!`%.S!0```````+H%`````````0!3[`4```````!'!@````````$`4Q<1 +XM````````*!$````````!`%/2$0````````82`````````0!3:!(````````T +XM$P````````$`4XX3````````I!,````````!`%/)$P```````!`4```````` +XM`0!3K!0```````#,%`````````$`4P,7````````,1<````````!`%-N%P`` +XM`````)@7`````````0!3I1@```````#*&`````````$`4P`````````````` +XM``````##`P```````+4'`````````P"1D'S)!P```````&D)`````````P"1 +XMD'S$"0```````.$0`````````P"1D'SO$````````&P4`````````P"1D'R. +XM%````````)@7`````````P"1D'RI%P```````,`7`````````P"1D'S"%P`` +XM`````.H7`````````P"1D'PH&````````$H9`````````P"1D'P````````` +XM````````````V`,```````"U!P````````,`D8A\R0<```````!I"0`````` +XM``,`D8A\T0D```````#A$`````````,`D8A\[Q````````!L%`````````,` +XMD8A\CA0```````"8%P````````,`D8A\J1<```````#`%P````````,`D8A\ +XMPA<```````#J%P````````,`D8A\*!@```````!*&0````````,`D8A\```` +XM`````````````````(@"````````WP,````````!`%-I"0```````-\)```` +XM`````0!3X1````````#O$`````````$`4U41````````D1$````````!`%,Q +XM%P```````&X7`````````0!3F!<```````"I%P````````$`4\`7```````` +XMZA<````````!`%,`````````````````````B@(```````"U!P````````,` +XMD;A_R0<```````!L%`````````,`D;A_CA0```````#J%P````````,`D;A_ +XM*!@```````!*&0````````,`D;A_`````````````````````%P$```````` +XM9@0````````!`%``````````````````````_P(```````"U!P````````,` +XMD8!\R0<```````#A$`````````,`D8!\ZA````````!L%`````````,`D8!\ +XMCA0```````#J%P````````,`D8!\*!@```````!*&0````````,`D8!\```` +XM`````````````````,\#````````M0<````````#`)'8?,D'````````:0D` +XM```````#`)'8?``*````````#`H````````#`)'X>PP*````````L@X````` +XM```#`)'8?+(.````````>P\````````#`)'X>WL/````````J@\````````# +XM`)'8?*H/````````O@\````````#`)'X>[X/````````T@\````````#`)'8 +XM?-(/````````\P\````````#`)'X>_,/````````,!`````````#`)'8?#`0 +XM````````X1`````````#`)'X>^\0````````%Q$````````#`)'X>Q<1```` +XM````D1$````````#`)'8?)$1````````LA$````````#`)'X>[(1```````` +XM!A(````````#`)'8?`82````````&A(````````#`)'X>QH2````````8A,` +XM```````#`)'8?&(3````````CA,````````#`)'X>XX3````````9Q0````` +XM```#`)'8?&<4````````;!0````````#`)'X>XX4````````_A8````````# +XM`)'8?/X6`````````Q<````````#`)'X>P,7````````,1<````````#`)'8 +XM?$87````````F!<````````#`)'8?*D7````````P!<````````#`)'8?,(7 +XM````````ZA<````````#`)'8?"@8````````2AD````````#`)'8?``````` +XM``````````````#8`P```````+4'`````````P"1\'O)!P```````&D)```` +XM`````P"1\'L5"@```````$D,`````````P"1\'OV#````````-H.```````` +XM`P"1\'MB#P```````'L/`````````P"1\'NJ#P```````-(/`````````P"1 +XM\'L4$````````.$0`````````P"1\'OO$````````*X2`````````P"1\'LT +XM$P```````&P4`````````P"1\'N.%````````*P4`````````P"1\'O,%``` +XM`````#$7`````````P"1\'M/%P```````)@7`````````P"1\'NI%P`````` +XM`,`7`````````P"1\'O"%P```````.H7`````````P"1\'LH&````````$H9 +XM`````````P"1\'L`````````````````````V`,```````#N`P````````$` +XM7YD%````````00<````````!`%^H"````````&D)`````````0!?&PH````` +XM``#A$`````````$`7^\0````````TA$````````!`%\&$@```````&@2```` +XM`````0!?-!,```````".$P````````$`7Z03````````VA,````````!`%\0 +XM%````````&P4`````````0!?CA0```````"L%`````````$`7\P4```````` +XM`Q<````````!`%]5%P```````&X7`````````0!?J1<```````#`%P`````` +XM``$`7\(7````````ZA<````````!`%\H&````````*48`````````0!?UQ@` +XM``````!*&0````````$`7P````````````````````"*`@```````/`"```` +XM`````0!6_P(```````""`P````````$`5H0#````````\D'````````;!0````````#`)'H>XX4 +XM````````ZA<````````#`)'H>R@8````````2AD````````#`)'H>P`````` +XM```````````````3`@```````+4'`````````P"1Y'O)!P```````&P4```` +XM`````P"1Y'N.%````````$H9`````````P"1Y'L````````````````````` +XM!@,````````N`P````````$`4(L#````````I`,````````!`%#8`P`````` +XM`/`#`````````0!5_0,````````(!`````````$`59D%````````\04````` +XM```!`%7V!0```````&8&`````````0!5J`@```````"Q"`````````$`50\) +XM````````$PD````````!`%4X%P```````#H7`````````0!0.A<```````!: +XM%P````````$`59@7````````I!<````````!`%#`%P```````,(7```````` +XM`0!0PA<```````#'%P````````$`50````````````````````"O!0`````` +XM`/8%`````````0!2`````````````````````)<*````````GPH````````! +XM`%3$"@```````,D*`````````0!5`````````````````````-@#```````` +XMWP,````````!`%.N"@```````/$*`````````0!3_@H```````!-"P`````` +XM``$`4U41````````D1$````````!`%/,%````````*`5`````````0!3J1<` +XM``````#`%P````````$`4\(7````````ZA<````````!`%,H&````````$88 +XM`````````0!3`````````````````````&X)````````>`D````````!`%4` +XM````````````````````51$```````!?$0````````$`5&D5````````;!4` +XM```````!`%!L%0```````'H5`````````0!4`````````````````````-@# +XM````````M0<````````#`)&X?,D'````````:0D````````#`)&X?$8*```` +XM````X1`````````#`)&X?.\0````````;!0````````#`)&X?(X4```````` +XM,1<````````#`)&X?%47````````F!<````````#`)&X?*D7````````P!<` +XM```````#`)&X?,(7````````ZA<````````#`)&X?"@8````````2AD````` +XM```#`)&X?``````````````````````T"P```````$,+`````````0!<51$` +XM``````"1$0````````$`7`H5````````MQ8````````!`%Q5%P```````&X7 +XM`````````0!`T````````!`%4*%0````````X5`````````0!5 +XM51<```````!:%P````````$`5;`7````````LA<````````!`%"R%P`````` +XM`,`7`````````0!5PA<```````#'%P````````$`5988````````F!@````` +XM```!`%"8&````````*48`````````0!5`````````````````````-@#```` +XM````M0<````````#`)&L?,D'````````:0D````````#`)&L?$8*```````` +XMX1`````````#`)&L?.\0````````;!0````````#`)&L?(X4````````,1<` +XM```````#`)&L?%47````````F!<````````#`)&L?*D7````````P!<````` +XM```#`)&L?,(7````````ZA<````````#`)&L?"@8````````2AD````````# +XM`)&L?`````````````````````#8`P```````+4'`````````P"1Q'S)!P`` +XM`````&D)`````````P"1Q'Q&"@```````%P*`````````P"1Q'Q<"@`````` +XM`&,*`````````0!48PH```````#A$`````````,`D<1\[Q````````!L%``` +XM``````,`D<1\CA0````````Q%P````````,`D<1\51<```````"8%P`````` +XM``,`D<1\J1<```````#`%P````````,`D<1\PA<```````#J%P````````,` +XMD<1\*!@```````!*&0````````,`D<1\`````````````````````$,'```` +XM````M0<````````!`%/;!P```````'$(`````````0!3B@@```````"H"``` +XM``````$`4XX4````````K!0````````!`%-5%P```````&X7`````````0!3 +XMRA@```````#7&`````````$`4P````````````````````!&!P```````+4' +XM`````````0!>R0<```````#8!P````````$`7ML'````````J`@````````! +XM`%Z.%````````*P4`````````0!>51<```````!N%P````````$`7LH8```` +XM````UQ@````````!`%X`````````````````````X@<````````>"``````` +XM``$`4%47````````6A<````````!`%7*&````````-<8`````````0!0```` +XM`````````````````````````````@`````````"`'<(`@`````````$```` +XM``````(`=Q`$``````````8``````````@!W&`8`````````"``````````" +XM`'<@"``````````)``````````(`=R@)``````````H``````````@!W,`H` +XM````````%``````````"`'@`````````!`%][```` +XM`````(X``````````0!?`````````````````````#,`````````;P`````` +XM```!`%9[`````````(8``````````0!6`````````````````````#4````` +XM````;0`````````!`%Q[`````````(@``````````0!<```````````````` +XM`````#4`````````;@`````````!`%-[`````````(4``````````0!3```` +XM`````````````````"0``````````@````````,` +XMD;A_`````````````````````.0`````````2P$````````!`%Q2`0`````` +XM``8"`````````0!<#0(````````>`@````````$`7``````````````````` +XM``#V`````````$@!`````````0!34@$```````"E`0````````$`4P`````` +XM``````````````#G`````````%$!`````````0!?4@$````````,`@`````` +XM``$`7PT"````````'@(````````!`%\`````````````````````[P`````` +XM```>`@````````(`D40`````````````````````#P$```````#;`P`````` +XM`/`&````````$`<```````#!!@```````-\&````````%P8```````"M!@`` +XM`````,(%````````_@4```````"0!0```````*X%````````304```````!I +XM!0```````,\$````````Z00````````L!````````#4$```````````````` +XM`````````````)!<```````!) +XM%P```````&H7````````0A<```````!&%P````````@7````````,!<````` +XM```"%P````````47````````[A8```````#W%@```````-H6````````X18` +XM``````#,%@```````-46`````````````````````````````%P2```````` +XM@1(```````#A%0```````/L5`````````````````````````````($2```` +XM````Y1(````````[&P```````$H;````````"A8```````"H%@```````'$5 +XM````````X14```````!@$P```````)L4```````````````````````````` +XM`($2````````Y1(````````[&P```````$H;````````EQ8```````"H%@`` +XM`````#@6````````6X`+G)E;&$N<&QT`"YI;FET`"YT97AT`"YF +XM:6YI`"YR;V1A=&$`+F5H7V9R86UE7VAD<@`N9&%T80`N96A?9G)A;64`+F1Y +XM;F%M:6,`+F-T;W)S`"YD=&]RE```````*!Z```````` +XMH`$````````%``````````@`````````$`````````"X`````0````,````` +XM````0'Q0``````!`?````````!`````````````````````(```````````` +XM````````OP````$````#`````````%!\4```````4'P````````0```````` +XM````````````"````````````````````,8````!`````P````````!@?%`` +XM`````&!\````````"`````````````````````@```````````````````#+ +XM`````0````,`````````:'Q0``````!H?````````$@"```````````````` +XM```(``````````@`````````T`````@````#`````````+!^4```````L'X` +XM```````P````````````````````"````````````````````-4````!```` +XM`````````````````````+!^````````]@$```````````````````$````` +XM``````````````#>`````0````````````````````````"F@````````/`` +XM```````````````````!````````````````````[0````$````````````` +XM````````````EH$```````#I`0```````````````````0`````````````` +XM`````/T````!`````````````````````````'^#````````:TX````````` +XM``````````$````````````````````)`0```0`````````````````````` +XM``#JT0```````#4+```````````````````!````````````````````%P$` +XM``$`````````````````````````']T````````8#@`````````````````` +XM`0```````````````````",!```!`````````````````````````#CK```` +XM``````8```````````````````@````````````````````P`0```0```#`` +XM```````````````````X\0```````(P-```````````````````!```````` +XM``$`````````.P$```$`````````````````````````Q/X```````"<5``` +XM`````````````````0```````````````````$8!```!```````````````` +XM`````````&!3`0``````@!@```````````````````$````````````````` +XM```1`````P````````````````````````#@:P$``````%0!```````````` +XM```````!`````````````````````0````(````````````````````````` +XM>'8!``````"@$0```````"0```!/````"``````````8``````````D````# +XM`````````````````````````!B(`0``````B@D```````````````````$` +XM`````````````````````````````````````````````````````````P`! +XM`,@!0````````````````````````P`"`.`!0``````````````````````` +XM`P`#`/@!0````````````````````````P`$`%`$0``````````````````` +XM`````P`%`-`+0````````````````````````P`&`.`.0``````````````` +XM`````````P`'`(`/0````````````````````````P`(`,`/0``````````` +XM`````````````P`)`#@00````````````````````````P`*`,@60``````` +XM`````````````````P`+`-P60````````````````````````P`,`%`;0``` +XM`````````````````````P`-`#AI0````````````````````````P`.`$AI +XM0````````````````````````P`/`$1R0````````````````````````P`0 +XM`&!R4````````````````````````P`1`&!U4``````````````````````` +XM`P`2`*!Z4````````````````````````P`3`$!\4``````````````````` +XM`````P`4`%!\4````````````````````````P`5`&!\4``````````````` +XM`````````P`6`&A\4````````````````````````P`7`+!^4``````````` +XM`````````````P`8`````````````````````````````P`9```````````` +XM`````````````````P`:`````````````````````````````P`;```````` +XM`````````````````````P`<`````````````````````````````P`=```` +XM`````````````````````````P`>`````````````````````````````P`? +XM`````````````````````````````P`@```````````````````````````` +XM`P`A`````````````````````````````P`B```````````````````````` +XM`````P`C`````````````````````````````P`D```````````````````` +XM```!````!`#Q_P`````````````````````(`````0`"`.`!0```````&``` +XM```````/````!`#Q_P`````````````````````M````!`#Q_P`````````` +XM```````````\````!`#Q_P`````````````````````/````!`#Q_P`````` +XM``````````````!'````!`#Q_P````````````````````!2`````0`3`$!\ +XM4`````````````````!@`````0`4`%!\4`````````````````!N`````0`5 +XM`&!\4`````````````````![`````@`,`/`;0`````````````````"1```` +XM`0`7`-1^4````````0````````"@`````0`0`'!R4`````````````````"G +XM`````@`,`#`<0`````````````````!'````!`#Q_P`````````````````` +XM``"S`````0`3`$A\4`````````````````#``````0`4`%A\4``````````` +XM``````#-`````0`1`&AZ4`````````````````#;`````0`5`&!\4``````` +XM``````````#G`````@`,`!!I0`````````````````#]````!`#Q_P`````` +XM```````````````M````!`#Q_P`````````````````````\````!`#Q_P`` +XM``````````````````#]````!`#Q_P`````````````````````;`0``!`#Q +XM_P`````````````````````B`0```@`,`&`<0```````*0`````````N`0`` +XM`@`,`)`<0```````*0`````````X`0```@`,`,`<0```````*0````````!& +XM`0```@`,`/`<0```````CP8```````!2`0```0`0`,!S4```````H`$````` +XM``!C`0```0`0`(!R4```````0`$```````!R`0``!`#Q_P`````````````` +XM``````!]`0```@`,`/`K0```````?0````````"0`0```@`,`$`O0``````` +XM:P````````"@`0```@`,`-`V0```````(@````````"T`0```@`,```W0``` +XM````-P````````#&`0```@`,`-`\0```````VP````````#1`0``!`#Q_P`` +XM``````````````````#<`0``!`#Q_P````````````````````#F`0```@`, +XM`)!-0```````$`````````#W`0```@`,`*!-0```````$``````````'`@`` +XM!`#Q_P`````````````````````/`@``$@`,`"`U0```````_P`````````< +XM`@``$@`,`*`Q0```````]``````````F`@``$@```.P60```````D``````` +XM```X`@``$@```/P60```````AP````````!2`@``$@````P70```````%P$` +XM``````!I`@``$@```!P70```````314```````!^`@``$@`,`*`R0``````` +XM.0$```````"(`@``$@```"P70```````?`$```````"9`@``$@`,`'!.0``` +XM````9@````````"J`@``$0`2`*!Z4`````````````````"S`@``$@```#P7 +XM0```````V@(```````#)`@``$@```$P70```````G@````````#8`@``$@`` +XM`%P70```````-`````````#J`@``$@```&P70```````50````````#[`@`` +XM$@`,`)`X0```````%0$````````/`P``$@`,`+`]0```````TPL````````< +XM`P``$@```'P70```````Y0`````````R`P``$@`,`.!F0```````CP`````` +XM``!``P``$@```(P70```````B@````````!0`P``$@```)P70``````````` +XM``````!A`P``$@```*P70```````:@````````!X`P``$0(0`&AR4``````` +XM``````````"%`P``$@```+P70```````X@````````":`P``$@`,`.!.0``` +XM````^A<```````"H`P``$@```,P70```````C`$```````#"`P``$@`,`+`O +XM0```````X@$```````#2`P``$@```-P70````````@````````#F`P``$@`` +XM`.P70```````AP8```````#X`P``$@```/P70```````.P`````````.!``` +XM$@````P80```````&0$````````E!```$@`,`.`S0```````.@$````````U +XM!```$@`*`,@60``````````````````[!```$@```!P80```````)``````` +XM``!2!```$@```"P80```````B`````````!A!```$0`7`-A^4```````"``` +XM``````!I!```$@```#P80```````3`````````![!```$@```$P80``````` +XM*0````````",!```$@```%P80```````-0````````"A!```$@```&P80``` +XM````:0$```````"V!```$@```'P80```````:@````````#0!```$0`7`+!^ +XM4```````!`````````#G!```$@```(P80```````K0(```````#X!```$@`` +XM`)P80```````%@`````````+!0``$0`0`&!R4```````"``````````6!0`` +XM$@`,`"`V0```````H@`````````E!0``$@`,`%`;0```````DP`````````L +XM!0``$@```*P80```````E0`````````\!0``$@```+P80``````````````` +XM``!+!0``$0`7`+A^4```````"`````````!!0``$@`,`#`N0```````!P$```````"J!0``$@`,`'!*0``` +XM````[@$```````"T!0``$@`,`'!G0```````GP$```````#%!0``$@```/P8 +XM0```````*`````````#"```$@```+P:0```````\@````````!O"```$0`7`,A^4```````"``` +XM``````"#"```$@```,P:0```````=@````````"2"```$0`7`-!^4``````` +XM!`````````"C"```$@```-P:0```````+P````````"T"```$@`,``!.0``` +XM````9@````````#&"```$@`,`)!)0```````V0````````#8"```$@```.P: +XM0```````'@````````#I"```$@```/P:0```````N0$````````$"0``$@`` +XM``P;0```````(0`````````9"0``$@```!P;0``````` +XM"0``$@`,`&!,0```````)0$```````!I"0``$@```#P;0```````:`$````` +XM``!_"0``$@`,`+`Y0```````%0,`````````8W)T,2YC`&%B:71A9P`O=7-R +XM+W-R8R]L:6(O8W-U+V%M9#8T+V-R=&DN4P`\8V]M;6%N9"UL:6YE/@`\8G5I +XM;'0M:6X^`&-R='-T=69F+F,`7U]#5$]27TQ)4U1?7P!?7T143U)?3$E35%]? +XM`%]?2D-27TQ)4U1?7P!?7V1O7V=L;V)A;%]D=&]R4!`1D)31%\Q +XM+C``5]P:&1R +XM`&EN'-C;D!`1D)31%\Q+C``9V5L9E]U<&1A=&5? ${WORKDIR}.uu.${1}/${f}.uu + done + fi + + # Pack them up using shar if required, or just copy. + mkdir -p ${OPATH}/${1} || exit 1 + if [ "${USE_SHAR}" = yes ]; then + cd ${WORKDIR}.uu.${1} || exit 1 + shar * > ${OPATH}/${1}/$TC.${1}.shar + elif [ "${USE_UUENCODE}" = yes ]; then + cp ${WORKDIR}.uu.${1}/* ${OPATH}/${1} + else + cp -R ${WORKDIR}/* ${OPATH}/${1} + fi + fi +} + +THISDIR=`/bin/pwd` + +# Check the command line options. +# +while getopts "nsui:o:c:g:" COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + n) + NODIFFRLT=yes; + ;; + s) + USE_SHAR=yes; + USE_UUENCODE=yes; + ;; + u) + USE_UUENCODE=yes; + ;; + i) + IPATH=${OPTARG} + ;; + o) + OPATH=${OPTARG} + ;; + g) + GCMD=${OPTARG} + ;; + c) + RCMD=${OPTARG} + ;; + *) + usage + exit 1 + ;; + esac +done + +if [ $# -ne $OPTIND ]; then + usage + exit 1 +fi +eval TC=$"{${OPTIND}}" + +if [ -z "${OPATH}" ]; then + OPATH=${TC}; +fi +mkdir -p ${OPATH} || exit 1 + +if [ -z "${RCMD}" ]; then + RCMD=":" +fi + +if [ -z "${GCMD}" ]; then + GCMD=${RCMD} +fi + +# Convert to absolute pathnames. +# +if [ -n "${IPATH}" ]; then + IPATH=`cd ${IPATH} 2>/dev/null && /bin/pwd \ + || echo "can't locate ${IPATH}" && exit 1` +fi + +ROPATH=${OPATH} # backup relative opath for later use. +OPATH=`cd ${OPATH} 2>/dev/null && /bin/pwd \ + || echo "can't locate ${OPATH}" && exit 1` + +# Prefix $GCMD with absolute pathnames. +# +executable=`echo ${GCMD} | cut -f 1 -d ' '` +relapath=`dirname ${executable}` +cd ${THISDIR} +absolpath=`cd ${relapath} && /bin/pwd` +GCMD=${absolpath}/`basename ${executable}`" "`echo ${GCMD} | cut -f 2- -d ' '` + +# Set up temporary directories. +# +WORKDIR=/tmp/bsdar-tcgen-work +rm -rf ${WORKDIR} +rm -rf ${WORKDIR}.uu.in +rm -rf ${WORKDIR}.uu.out +mkdir -p ${WORKDIR} || exit 1 +mkdir -p ${WORKDIR}.uu.in || exit 1 # Keep encoded input files +mkdir -p ${WORKDIR}.uu.out || exit 1 # Keep encoded output files + +if [ -n "${IPATH}" ]; then + cp -R ${IPATH}/* ${WORKDIR} 2>/dev/null +fi + +# Keep a record of input state. +# +recstate "in" + +# Execute the cmd, record stdout, stderr and exit value. +# +cd ${WORKDIR} || exit 1 +${GCMD} > ${OPATH}/$TC.out 2> ${OPATH}/$TC.err +echo $? > ${OPATH}/$TC.eval + +# Keep a record of output state. +# +recstate "out" + +# Generate test script. +# +echo "inittest ${TC} ${ROPATH}" > ${OPATH}/${TC}.sh +if [ "${USE_SHAR}" = yes ]; then + echo 'extshar ${TESTDIR}' >> ${OPATH}/${TC}.sh + echo 'extshar ${RLTDIR}' >> ${OPATH}/${TC}.sh +elif [ "${USE_UUENCODE}" = yes ]; then + echo 'udecode ${TESTDIR}' >> ${OPATH}/${TC}.sh + echo 'udecode ${RLTDIR}' >> ${OPATH}/${TC}.sh +fi +echo "runcmd \"${RCMD}\" work true" >> ${OPATH}/${TC}.sh +if [ "${NODIFFRLT}" = yes ]; then + echo "rundiff false" >> ${OPATH}/${TC}.sh +else + echo "rundiff true" >> ${OPATH}/${TC}.sh +fi + +cd ${THISDIR} || exit 1 +echo "done." diff --git a/contrib/elftoolchain/tests/libtest/Makefile b/contrib/elftoolchain/tests/libtest/Makefile new file mode 100644 index 0000000000..3cf6de08f3 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/Makefile @@ -0,0 +1,16 @@ +# $Id$ +# +# The test(3) API. + +TOP= ../.. + +SUBDIR+= bin +SUBDIR+= lib +SUBDIR+= driver +SUBDIR+= examples + +.if !make(install) && !make(test) +.include "$(TOP)/mk/elftoolchain.subdir.mk" +.else +install test: .SILENT .PHONY +.endif diff --git a/contrib/elftoolchain/tests/libtest/README.rst b/contrib/elftoolchain/tests/libtest/README.rst new file mode 100644 index 0000000000..b93dca7a69 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/README.rst @@ -0,0 +1,116 @@ +===================================== +test(3) - a library for writing tests +===================================== + +The ``test(3)`` API and its related scaffolding generator +(`make-test-scaffolding(1) `_) work together to reduce the +boilerplate needed for tests. + +.. _mts: bin/make-test-scaffolding + +Quick Start +=========== + +The following source code defines a test suite that contains a single +test: + +.. code:: c + + /* File: test.c */ + #include "test.h" + + enum test_result + tf_goodbye_world(testcase_state tcs) + { + return (TEST_PASS); + } + +By convention, test functions are named using a ``tf_`` prefix. + +Given an object file compiled from this source, the +`make-test-scaffolding(1) `_ utility would generate scaffolding +describing a single invocable test named "``goodbye_world``". + +Test Cases +---------- + +Test functions that are related to each other can be grouped into test +cases. The following code snippet defines a test suite with two test +functions contained in a test case named "``helloworld``": + +.. code:: c + + /* File: test.c */ + #include "test.h" + + TEST_CASE_DESCRIPTION(helloworld) = + "A description of the helloworld test case."; + + enum test_result + tf_helloworld_hello(testcase_state tcs) + { + return (TEST_PASS); + } + + enum test_result + tf_helloworld_goodbye(testcase_state tcs) + { + return (TEST_FAIL); + } + +Test cases can define their own set up and tear down functions: + +.. code:: c + + /* File: test.c continued. */ + struct helloworld_test { .. state used by the helloworld tests .. }; + + enum testcase_status + tc_setup_helloworld(testcase_state *tcs) + { + *tcs = ..allocate a struct helloworld_test.. ; + return (TEST_CASE_OK); + } + + enum testcase_status + tc_teardown_helloworld(testcase_state tcs) + { + .. deallocate test case state.. + return (TEST_CASE_OK); + } + +The set up function for a test case will be invoked prior to any of +the functions that are part of the test case. The set up function can +allocate test-specific state, which is then passed to each test function +for its use. + +The tear down function for a test case will be invoked after the test +functions in the test case are invoked. This function is responsible for +deallocating the resources allocated by its corresponding set up function. + +Building Tests +-------------- + +Within the `Elftoolchain Project`_'s sources, the ``elftoolchain.test.mk`` +rule set handles the process of invoking the `make-test-scaffolding(1) +`_ utility and building an test executable. + +.. code:: make + + # Example Makefile. + + TOP= ..path to the top of the elftoolchain source tree.. + + TEST_SRCS= test.c + + .include "$(TOP)/mk/elftoolchain.test.mk" + + +.. _Elftoolchain Project: http://elftoolchain.sourceforge.net/ + +Further Reading +=============== + +- The `test(3) `_ manual page. +- The `make-test-scaffolding(1) `_ manual page. +- `Example code `_. diff --git a/contrib/elftoolchain/tests/libtest/bin/Makefile b/contrib/elftoolchain/tests/libtest/bin/Makefile new file mode 100644 index 0000000000..a6a3b8d6ae --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/bin/Makefile @@ -0,0 +1,9 @@ +# $Id$ + +TOP= ../../.. + +SCRIPTS= make-test-scaffolding + +MAN1= make-test-scaffolding.1 + +.include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding b/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding new file mode 100755 index 0000000000..6ec78e8224 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding @@ -0,0 +1,222 @@ +#!/bin/sh +# +# Copyright (c) 2018, Joseph Koshy. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer +# in this position and unchanged. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# $Id$ + +# Given a list of objects that use the test(3) API, this script will +# generate test case and test function descriptors based on the symbols +# contained in those objects. + +usage() +{ + echo Usage: `basename $0`: "[options] objects..." + echo + echo "Generate test(3) scaffolding from objects." + echo "Options include:" + echo + echo "\t-o out\t\tcreate output file \"out\" [default \"tc.c\"]." + echo +} + +output_file="tc.c" +prefix_tc_descr='tc_description_' +prefix_tc_setup='tc_setup_' +prefix_tc_tags='tc_tags_' +prefix_tc_teardown='tc_teardown_' +prefix_tf='tf_' +prefix_tf_descr='tf_description_' +prefix_tf_tags='tf_tags_' + + +args=`getopt o: $*` +if [ ${?} -ne 0 ]; then + usage + exit 2 +fi + +set -- ${args} + +for i +do + case "${i}" in + -o ) + output_file="${2}" + shift; shift;; + -- ) + shift; break;; + esac +done + +if [ ${#} -eq 0 ]; then + usage + exit 2 +fi + +exec > ${output_file} +cat < +#include "test.h" +#include "test_case.h" +EOF + +if ! nm ${*} | sort -k 3 | \ + awk -v prefix_tc_descr=${prefix_tc_descr} \ + -v prefix_tc_setup=${prefix_tc_setup} \ + -v prefix_tc_tags=${prefix_tc_tags} \ + -v prefix_tc_teardown=${prefix_tc_teardown} \ + -v prefix_tf=${prefix_tf} \ + -v prefix_tf_descr=${prefix_tf_descr} \ + -v prefix_tf_tags=${prefix_tf_tags} ' + function suffix(value, prefix) { + return substr(value, length(prefix) + 1); + } + function matched_test_case(tf_name, tc_matched) { + tc_matched = "" + for (tc_name in test_cases) { + if (tf_name ~ tc_name "_" && + length(tc_name) > length(tc_matched)) { + tc_matched = tc_name + } + } + if (tc_matched != "") + return tc_matched + return DEFAULT + } + function print_test_case_record(tc_name) { + printf("\t{\n") + printf("\t\t.tc_name = \"%s\",\n", tc_name) + printf("\t\t.tc_description = %s,\n", + test_case_descriptions[tc_name]) + printf("\t\t.tc_tags = %s,\n", test_case_tags[tc_name]) + tf_name = "test_functions_" tc_name + printf("\t\t.tc_tests = %s,\n", tf_name) + printf("\t\t.tc_count = sizeof (%s) / sizeof (%s[0]),\n", + tf_name, tf_name) + printf("\t},\n") + } + function delete_test_functions(tc_name) { + for (tf_name in test_functions) { + if (matched_test_case(tf_name) == tc_name) + delete test_functions[tf_name] + } + } + function print_test_functions_record(tc_name) { + printf("struct test_function_descriptor test_functions_%s[]", + tc_name) + printf(" = {\n") + for (tf_name in test_functions) { + if (tc_name != matched_test_case(tf_name)) + continue + printf("\t{\n") + printf("\t\t.tf_name = \"%s\",\n", tf_name) + printf("\t\t.tf_description = %s,\n", + test_function_descriptions[tf_name]) + printf("\t\t.tf_func = %s,\n", prefix_tf tf_name) + printf("\t\t.tf_tags = %s\n", + test_function_tags[tf_name]) + printf("\t},\n") + } + printf("};\n") + } + function is_non_empty(array, i) { + for (i in array) return 1 + return 0 + } + BEGIN { + DEFAULT = "default" + test_case_descriptions[DEFAULT] = "NULL" + test_case_tags[DEFAULT] = "NULL" + } + ($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_descr { + printf("extern test_case_description %s;\n", $3) + tc_name = suffix($3, prefix_tc_descr) + test_cases[tc_name] = 1 + test_case_descriptions[tc_name] = $3 + } + $2 == "T" && $3 ~ "^" prefix_tc_setup { + tc_name = suffix($3, prefix_tc_setup) + test_cases[tc_name] = 1 + test_case_setup[tc_name] = $3 + } + ($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tc_tags { + printf("extern test_case_tags %s;\n", $3) + tc_name = suffix($3, prefix_tc_tags) + test_cases[tc_name] = 1 + test_case_tags[tc_name] = $3 + } + $2 == "T" && $3 ~ "^" prefix_tc_teardown { + tc_name = suffix($3, prefix_tc_teardown) + test_cases[tc_name] = 1 + test_case_teardown[tc_name] = $3 + } + ($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tf_descr { + printf("extern test_description %s;\n", $3) + tf_name = suffix($3, prefix_tf_descr) + test_function_descriptions[tf_name] = $3 + } + ($2 == "R" || $2 == "D") && $3 ~ "^" prefix_tf_tags { + printf("extern test_tags %s;\n", $3) + tf_name = suffix($3, prefix_tf_tags) + test_function_tags[tf_name] = $3 + } + $2 == "T" && $3 ~ "^" prefix_tf { + printf("test_function %s;\n", $3) + tf_name = suffix($3, prefix_tf) + test_functions[tf_name] = 1 + } + END { + for (tf_name in test_functions) { + if (test_function_descriptions[tf_name] == "") + test_function_descriptions[tf_name] = "NULL" + if (test_function_tags[tf_name] == "") + test_function_tags[tf_name] = "NULL" + } + for (tc_name in test_cases) { + if (test_case_descriptions[tc_name] == "") + test_case_descriptions[tc_name] = "NULL" + if (test_case_tags[tc_name] == "") + test_case_tags[tc_name] = "NULL" + } + for (tc_name in test_cases) { + print_test_functions_record(tc_name) + delete_test_functions(tc_name) + } + needs_default = is_non_empty(test_functions) + if (needs_default) + print_test_functions_record(DEFAULT) + printf("struct test_case_descriptor test_cases[] = {\n") + for (tc_name in test_cases) + print_test_case_record(tc_name) + if (needs_default) + print_test_case_record(DEFAULT) + printf("};\n") + printf("const int test_case_count = sizeof(test_cases) / ") + printf("sizeof(test_cases[0]);\n") + }'; then + # Cleanup in case of an error. + rm ${output_file} + exit 1 +fi diff --git a/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding.1 b/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding.1 new file mode 100644 index 0000000000..2d120e1bb5 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/bin/make-test-scaffolding.1 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2018, Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd December 25, 2018 +.Dt TEST 1 +.Os +.Sh NAME +.Nm make-test-scaffolding +.Nd generate scaffolding for tests +.Sh SYNOPSIS +.Nm +.Op Fl o Ar output_file +.Ar test_object ... +.Sh DESCRIPTION +The +.Nm +utility takes as input object files containing symbols following +its naming convention and generates the scaffolding needed to assemble +a test executable. +.Pp +The +.Nm +utility expects symbols to be named using the following conventions: +.Bl -bullet +.It +Test case descriptions are named using the +.Li tc_description_ +prefix, followed by the name of the test case. +For example, the symbol +.Sy tc_description_helloworld +would name the description of a test case named +.Dq helloworld . +.It +Test set up functions are named using a +.Li tc_setup_ +prefix, followed by the name of a test case. +For example, the function +.Fn tc_setup_helloworld +would name the set up function for a test case named +.Dq helloworld . +.It +Test tear down functions are named using a +.Li tc_teardown_ +prefix, followed by the name of a test case. +For example, the function +.Fn tc_teardown_helloworld +would name the tear down function for a test case named +.Dq helloworld . +.It +Tags for test cases are named using symbols with a +.Li tc_tags_ +prefix, followed by the name of their test case. +.It +Test functions are named using a +.Li tf_ +prefix, followed by the name for their containing test case and a +disambiguating suffix. +For example, the two test functions +.Fn tf_helloworld_sayhello +and +.Fn tf_helloworld_saygoodbye +would be associated with the test case named +.Dq helloworld . +.Pp +A test function that is not associated with a test case will be +added to a special test case named +.Dq default . +.It +Tags for test functions are named using symbols with a +.Li tf_tags_ +prefix, followed by the name of their test case. +.El +.Pp +The +.Nm +utility will generate a C source file containing the appropriate +.Vt "struct test_descriptor" +and +.Vt "struct test_case_descriptor" +structures for use by a test driver. +.Sh SEE ALSO +.Xr test 3 , +.Xr test_runner 3 +.Sh AUTHORS +The +.Nm +utility was written by +.An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net . diff --git a/contrib/elftoolchain/tests/libtest/driver/Makefile b/contrib/elftoolchain/tests/libtest/driver/Makefile new file mode 100644 index 0000000000..b4fdb1f867 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/driver/Makefile @@ -0,0 +1,19 @@ +# $Id$ +# +# A command-line driver for libtest based tests. + +TOP= ../../.. + +INCDIR= -I${TOP}/tests/libtest/lib +CFLAGS+= ${INCDIR} +LINTFLAGS+= ${INCDIR} + +LIB= driver +SRCS= driver.c \ + driver_main.c + +WARNS?= 6 + +MAN= test_driver.1 + +.include "$(TOP)/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/tests/libtest/driver/driver.c b/contrib/elftoolchain/tests/libtest/driver/driver.c new file mode 100644 index 0000000000..aa85c7cb4d --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/driver/driver.c @@ -0,0 +1,216 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * The implementation of the test driver. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "driver.h" + +#if defined(ELFTC_VCSID) +ELFTC_VCSID("$Id$"); +#endif + +#define SYSTEM_TMPDIR_ENV_VAR "TMPDIR" + +bool +test_driver_add_search_path(struct test_run *tr, const char *directory_name) +{ + char *canonical_path; + struct test_search_path_entry *entry; + + if (!test_driver_is_directory(directory_name)) + return (false); + + if ((canonical_path = realpath(directory_name, NULL)) == NULL) + err(1, "Cannot determine the canonical path for \"%s\"", + directory_name); + + /* Look for, and ignore duplicates. */ + STAILQ_FOREACH(entry, &tr->tr_search_path, tsp_next) { + if (strcmp(canonical_path, entry->tsp_directory) == 0) + return (true); + } + + entry = calloc(1, sizeof(*entry)); + entry->tsp_directory = canonical_path; + + STAILQ_INSERT_TAIL(&tr->tr_search_path, entry, tsp_next); + + return (true); +} + +/* + * Return an initialized test run descriptor. + * + * The caller should use test_driver_free_run() to release the returned + * descriptor. + */ +struct test_run * +test_driver_allocate_run(void) +{ + struct test_run *tr; + + tr = calloc(sizeof(struct test_run), 1); + tr->tr_action = TEST_RUN_EXECUTE; + tr->tr_style = TR_STYLE_LIBTEST; + STAILQ_INIT(&tr->tr_test_cases); + STAILQ_INIT(&tr->tr_search_path); + + return (tr); +} + +/* + * Destroy an allocated test run descriptor. + * + * The passed in pointer should not be used after this function returns. + */ +void +test_driver_free_run(struct test_run *tr) +{ + struct test_search_path_entry *path_entry; + struct test_case_selector *test_case_entry; + struct test_function_selector *function_entry; + + free(tr->tr_runtime_base_directory); + free(tr->tr_name); + if (tr->tr_artefact_archive) + free(tr->tr_artefact_archive); + + /* Free the search path list. */ + while (!STAILQ_EMPTY(&tr->tr_search_path)) { + path_entry = STAILQ_FIRST(&tr->tr_search_path); + STAILQ_REMOVE_HEAD(&tr->tr_search_path, tsp_next); + free(path_entry); + } + + /* Free the test selector list. */ + while (!STAILQ_EMPTY(&tr->tr_test_cases)) { + test_case_entry = STAILQ_FIRST(&tr->tr_test_cases); + STAILQ_REMOVE_HEAD(&tr->tr_test_cases, tcs_next); + + /* Free the linked test functions. */ + while (!STAILQ_EMPTY(&test_case_entry->tcs_functions)) { + function_entry = + STAILQ_FIRST(&test_case_entry->tcs_functions); + STAILQ_REMOVE_HEAD(&test_case_entry->tcs_functions, + tfs_next); + + free(function_entry); + } + + free(test_case_entry); + } + + free(tr); +} + +/* + * Populate unset fields of a struct test_run with defaults. + */ +bool +test_driver_finish_run_initialization(struct test_run *tr, const char *argv0) +{ + struct timeval tv; + const char *basedir; + const char *search_path; + const char *last_component; + char *argv0_copy, *path_copy, *path_element; + char test_name[NAME_MAX]; + + if (tr->tr_name == NULL) { + /* Per POSIX, basename(3) can modify its argument. */ + argv0_copy = strdup(argv0); + last_component = basename(argv0_copy); + + if (gettimeofday(&tv, NULL)) + return (false); + + (void) snprintf(test_name, sizeof(test_name), "%s+%ld%ld", + last_component, (long) tv.tv_sec, (long) tv.tv_usec); + + tr->tr_name = strdup(test_name); + + free(argv0_copy); + } + + /* + * Select a base directory, if one was not specified. + */ + if (tr->tr_runtime_base_directory == NULL) { + basedir = getenv(TEST_TMPDIR_ENV_VAR); + if (basedir == NULL) + basedir = getenv(SYSTEM_TMPDIR_ENV_VAR); + if (basedir == NULL) + basedir = "/tmp"; + tr->tr_runtime_base_directory = realpath(basedir, NULL); + if (tr->tr_runtime_base_directory == NULL) + err(1, "realpath(%s) failed", basedir); + } + + /* + * Add the search paths specified by the environment variable + * 'TEST_PATH' to the end of the search list. + */ + if ((search_path = getenv(TEST_SEARCH_PATH_ENV_VAR)) != NULL && + *search_path != '\0') { + path_copy = strdup(search_path); + path_element = strtok(path_copy, ":"); + do { + if (!test_driver_add_search_path(tr, path_element)) + warnx("in environment variable \"%s\": path " + "\"%s\" does not name a directory.", + TEST_SEARCH_PATH_ENV_VAR, path_element); + } while ((path_element = strtok(NULL, ":")) != NULL); + } + + return (true); +} + +/* + * Helper: return true if the passed in path names a directory, or false + * otherwise. + */ +bool +test_driver_is_directory(const char *path) +{ + struct stat sb; + if (stat(path, &sb) != 0) + return false; + return S_ISDIR(sb.st_mode); +} diff --git a/contrib/elftoolchain/tests/libtest/driver/driver.h b/contrib/elftoolchain/tests/libtest/driver/driver.h new file mode 100644 index 0000000000..5ae5cfd812 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/driver/driver.h @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2018,2019 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LIBTEST_DRIVER_H_ +#define _LIBTEST_DRIVER_H_ + +#include + +#include +#include + +#include "_elftc.h" + +#include "test.h" + +#define TEST_SEARCH_PATH_ENV_VAR "TEST_PATH" +#define TEST_TMPDIR_ENV_VAR "TEST_TMPDIR" + +/* + * Run time data strucrures. + */ + +/* The completion status for a test run */ +enum test_run_status { + /* + * All test cases were successfully invoked, and all their contained + * test purposes passed. + */ + TR_STATUS_PASS = 0, + + /* + * All test cases were successfully invoked but at least one test + * function reported a failure. + */ + TR_STATUS_FAIL = 1, + + /* + * At least one test case reported an error during its set up or tear + * down phase. + */ + TR_STATUS_ERROR = 2 +}; + +/* + * The 'style' of the run determines the manner in which the test + * executable reports test status. + */ +enum test_run_style { + /* Libtest semantics. */ + TR_STYLE_LIBTEST, + + /* + * Be compatible with the Test Anything Protocol + * (http://testanything.org/). + */ + TR_STYLE_TAP, + + /* Be compatible with NetBSD ATF(9). */ + TR_STYLE_ATF +}; + +/* + * Structures used for selecting tests. + */ +struct test_function_selector { + const struct test_function_descriptor *tfs_descriptor; + + STAILQ_ENTRY(test_function_selector) tfs_next; + int tfs_is_selected; +}; + +STAILQ_HEAD(test_function_selector_list, test_function_selector); + +struct test_case_selector { + const struct test_case_descriptor *tcs_descriptor; + STAILQ_ENTRY(test_case_selector) tcs_next; + struct test_function_selector_list tcs_functions; + int tcs_selected_count; +}; + +/* + * The action being requested of the test driver. + */ +enum test_run_action { + TEST_RUN_EXECUTE, /* Execute the selected tests. */ + TEST_RUN_LIST, /* Only list tests. */ +}; + +STAILQ_HEAD(test_case_selector_list, test_case_selector); + +/* + * Runtime directories to look up data files. + */ +struct test_search_path_entry { + char *tsp_directory; + STAILQ_ENTRY(test_search_path_entry) tsp_next; +}; + +STAILQ_HEAD(test_search_path_list, test_search_path_entry); + +/* + * Used to track flags that were explicity set on the command line. + */ +enum test_run_flags { + TRF_BASE_DIRECTORY = 1U << 0, + TRF_EXECUTION_TIME = 1U << 1, + TRF_ARTEFACT_ARCHIVE = 1U << 2, + TRF_NAME = 1U << 3, + TRF_SEARCH_PATH = 1U << 4, + TRF_EXECUTION_STYLE = 1U << 5, +}; + +/* + * Parameters for the run. + */ +struct test_run { + /* + * Flags tracking the options which were explicitly set. + * + * This field is a bitmask formed of 'enum test_run_flags' values. + */ + unsigned int tr_commandline_flags; + + /* What the test run should do. */ + enum test_run_action tr_action; + + /* The desired behavior of the test harness. */ + enum test_run_style tr_style; + + /* The desired verbosity level. */ + int tr_verbosity; + + /* An optional name assigned by the user for this test run. */ + char *tr_name; + + /* + * The absolute path to the directory under which the test is + * to be run. + * + * Each test case will be invoked in some subdirectory of this + * directory. + */ + char *tr_runtime_base_directory; + + /* + * The test timeout in seconds. + * + * A value of zero indicates that the test driver should wait + * indefinitely for tests. + */ + long tr_max_seconds_per_test; + + /* + * If not NULL, An absolute pathname to an archive that will hold + * the artefacts created by a test run. + */ + char *tr_artefact_archive; + + /* + * Directories to use when resolving non-absolute data file + * names. + */ + struct test_search_path_list tr_search_path; + + /* All tests selected for this run. */ + struct test_case_selector_list tr_test_cases; +}; + +#ifdef __cplusplus +extern "C" { +#endif +struct test_run *test_driver_allocate_run(void); +bool test_driver_add_search_path(struct test_run *, + const char *search_path); +void test_driver_free_run(struct test_run *); +bool test_driver_is_directory(const char *); +bool test_driver_finish_run_initialization(struct test_run *, + const char *argv0); +#ifdef __cplusplus +} +#endif + +#endif /* _LIBTEST_DRIVER_H_ */ diff --git a/contrib/elftoolchain/tests/libtest/driver/driver_main.c b/contrib/elftoolchain/tests/libtest/driver/driver_main.c new file mode 100644 index 0000000000..c43ccf52ca --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/driver/driver_main.c @@ -0,0 +1,726 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file defines a "main()" that invokes (or lists) the tests that were + * linked into the current executable. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_elftc.h" + +#include "test.h" +#include "test_case.h" + +#include "driver.h" + +#if defined(ELFTC_VCSID) +ELFTC_VCSID("$Id$"); +#endif + +enum selection_scope { + SCOPE_TEST_CASE = 0, /* c:STRING */ + SCOPE_TEST_FUNCTION, /* f:STRING */ + SCOPE_TAG, /* t:STRING */ +}; + +/* Selection list entry. */ +struct selection_option { + STAILQ_ENTRY(selection_option) so_next; + + /* The text to use for matching. */ + const char *so_pattern; + + /* + * Whether matched test and test cases should be selected + * (if false) or deselected (if true). + */ + bool so_select_tests; + + /* The kind of information to match. */ + enum selection_scope so_selection_scope; +}; + +/* All selection options specified. */ +STAILQ_HEAD(selection_option_list, selection_option); + +static struct selection_option * +parse_selection_option(const char *option) +{ + int scope_char; + bool select_tests; + enum selection_scope scope; + struct selection_option *so; + + scope_char = '\0'; + select_tests = true; + scope = SCOPE_TEST_CASE; + + /* Deselection patterns start with a '-'. */ + if (*option == '-') { + select_tests = false; + option++; + } + + /* + * If a scope was not specified, the selection scope defaults + * to SCOPE_TEST_CASE. + */ + if (strchr(option, ':') == NULL) + scope_char = 'c'; + else { + scope_char = *option++; + if (*option != ':') + return (NULL); + option++; /* Skip over the ':'. */ + } + + if (*option == '\0') + return (NULL); + + switch (scope_char) { + case 'c': + scope = SCOPE_TEST_CASE; + break; + case 'f': + scope = SCOPE_TEST_FUNCTION; + break; + case 't': + scope = SCOPE_TAG; + break; + default: + return (NULL); + } + + so = calloc(1, sizeof(*so)); + so->so_pattern = option; + so->so_selection_scope = scope; + so->so_select_tests = select_tests; + + return (so); +} + +/* Test execution styles. */ +struct style_entry { + enum test_run_style se_style; + const char *se_name; +}; + +static const struct style_entry known_styles[] = { + { TR_STYLE_LIBTEST, "libtest" }, + { TR_STYLE_TAP, "tap" }, + { TR_STYLE_ATF, "atf" } +}; + +/* + * Parse a test run style. + * + * This function returns true if the run style was recognized, or + * false otherwise. + */ +static bool +parse_run_style(const char *option, enum test_run_style *run_style) +{ + size_t n; + + for (n = 0; n < sizeof(known_styles) / sizeof(known_styles[0]); n++) { + if (strcasecmp(option, known_styles[n].se_name) == 0) { + *run_style = known_styles[n].se_style; + return (true); + } + } + + return (false); +} + +/* + * Return the canonical spelling of a test execution style. + */ +static const char * +to_execution_style_name(enum test_run_style run_style) +{ + size_t n; + + for (n = 0; n < sizeof(known_styles) / sizeof(known_styles[0]); n++) { + if (known_styles[n].se_style == run_style) + return (known_styles[n].se_name); + } + + return (NULL); +} + +/* + * Parse a string value containing a positive integral number. + */ +static bool +parse_execution_time(const char *option, long *execution_time) { + char *end; + long value; + + if (option == NULL || *option == '\0') + return (false); + + value = strtol(option, &end, 10); + + /* Check for parse errors. */ + if (*end != '\0') + return (false); + + /* Reject negative numbers. */ + if (value < 0) + return (false); + + /* Check for overflows during parsing. */ + if (value == LONG_MAX && errno == ERANGE) + return (false); + + *execution_time = value; + + return (true); +} + +/* + * Match the names of test cases. + * + * In the event of a match, then the selection state specifed in + * 'option' is applied to all the test functions in the test case. + */ +static void +match_test_cases(struct selection_option *option, + struct test_case_selector *tcs) +{ + const struct test_case_descriptor *tcd; + struct test_function_selector *tfs; + + tcd = tcs->tcs_descriptor; + + if (fnmatch(option->so_pattern, tcd->tc_name, 0)) + return; + + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) + tfs->tfs_is_selected = option->so_select_tests; +} + +/* + * Match the names of test functions. + */ +static void +match_test_functions(struct selection_option *option, + struct test_case_selector *tcs) +{ + struct test_function_selector *tfs; + const struct test_function_descriptor *tfd; + + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) { + tfd = tfs->tfs_descriptor; + + if (fnmatch(option->so_pattern, tfd->tf_name, 0)) + continue; + + tfs->tfs_is_selected = option->so_select_tests; + } +} + +/* + * Helper: returns true if the specified text matches any of the + * entries in the array 'tags'. + */ +static bool +match_tags_helper(const char *pattern, const char *tags[]) +{ + const char **tag; + + if (!tags) + return (false); + + for (tag = tags; *tag && **tag != '\0'; tag++) { + if (!fnmatch(pattern, *tag, 0)) + return (true); + } + + return (false); +} + +/* + * Match tags. + * + * Matches against test case tags apply to all the test + * functions in the test case. + * + * Matches against test function tags apply to the matched + * test function only. + */ +static void +match_tags(struct selection_option *option, + struct test_case_selector *tcs) +{ + const struct test_case_descriptor *tcd; + const struct test_function_descriptor *tfd; + struct test_function_selector *tfs; + + tcd = tcs->tcs_descriptor; + + /* + * If the tag in the option matches a tag associated with + * a test case, then we set all of the test case's functions + * to the specified selection state. + */ + if (match_tags_helper(option->so_pattern, tcd->tc_tags)) { + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) + tfs->tfs_is_selected = option->so_select_tests; + return; + } + + /* + * Otherwise, check the tag against the tags for each function + * in the test case and set the selection state of each matched + * function. + */ + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) { + tfd = tfs->tfs_descriptor; + if (match_tags_helper(option->so_pattern, tfd->tf_tags)) + tfs->tfs_is_selected = option->so_select_tests; + } +} + +/* + * Add the selected tests to the test run. + * + * The memory used by the options list is returned to the system when this + * function completes. + */ +static void +select_tests(struct test_run *tr, + struct selection_option_list *selections) +{ + int i, j; + struct selection_option *selection; + const struct test_case_descriptor *tcd; + struct test_case_selector *tcs; + struct test_function_selector *tfs; + bool default_selection_state; + int selected_count; + + default_selection_state = STAILQ_EMPTY(selections); + + /* + * Set up runtime descriptors. + */ + for (i = 0; i < test_case_count; i++) { + if ((tcs = calloc(1, sizeof(*tcs))) == NULL) + err(EX_OSERR, "cannot allocate a test-case selector"); + STAILQ_INSERT_TAIL(&tr->tr_test_cases, tcs, tcs_next); + STAILQ_INIT(&tcs->tcs_functions); + + tcd = &test_cases[i]; + + tcs->tcs_descriptor = tcd; + + for (j = 0; j < tcd->tc_count; j++) { + if ((tfs = calloc(1, sizeof(*tfs))) == NULL) + err(EX_OSERR, "cannot allocate a test " + "function selector"); + STAILQ_INSERT_TAIL(&tcs->tcs_functions, tfs, tfs_next); + + tfs->tfs_descriptor = tcd->tc_tests + j; + tfs->tfs_is_selected = default_selection_state; + } + } + + /* + * Set or reset the selection state based on the options. + */ + STAILQ_FOREACH(selection, selections, so_next) { + STAILQ_FOREACH(tcs, &tr->tr_test_cases, tcs_next) { + switch (selection->so_selection_scope) { + case SCOPE_TEST_CASE: + match_test_cases(selection, tcs); + break; + case SCOPE_TEST_FUNCTION: + match_test_functions(selection, tcs); + break; + case SCOPE_TAG: + match_tags(selection, tcs); + break; + } + } + } + + /* + * Determine the count of tests selected, for each test case. + */ + STAILQ_FOREACH(tcs, &tr->tr_test_cases, tcs_next) { + selected_count = 0; + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) + selected_count += tfs->tfs_is_selected; + tcs->tcs_selected_count = selected_count; + } + + /* Free up the selection list. */ + while (!STAILQ_EMPTY(selections)) { + selection = STAILQ_FIRST(selections); + STAILQ_REMOVE_HEAD(selections, so_next); + free(selection); + } +} + +/* + * Translate a file name to absolute form. + * + * The caller needs to free the returned pointer. + */ +static char * +to_absolute_path(const char *filename) +{ + size_t space_needed; + char *absolute_path; + char current_directory[PATH_MAX]; + + if (filename == NULL || *filename == '\0') + return (NULL); + if (*filename == '/') + return strdup(filename); + + if (getcwd(current_directory, sizeof(current_directory)) == NULL) + err(1, "getcwd failed"); + + /* Reserve space for the slash separator and the trailing NUL. */ + space_needed = strlen(current_directory) + strlen(filename) + 2; + if ((absolute_path = malloc(space_needed)) == NULL) + err(1, "malloc failed"); + if (snprintf(absolute_path, space_needed, "%s/%s", current_directory, + filename) != (int) (space_needed - 1)) + err(1, "snprintf failed"); + return (absolute_path); +} + + +/* + * Display run parameters. + */ + +#define FIELD_NAME_WIDTH 24 +#define INFOLINE(NAME, FLAG, FORMAT, ...) do { \ + printf("I %c %-*s " FORMAT, \ + (FLAG) ? '!' : '.', \ + FIELD_NAME_WIDTH, NAME, __VA_ARGS__); \ + } while (0) + +static void +show_run_header(const struct test_run *tr) +{ + time_t start_time; + struct test_search_path_entry *path_entry; + + if (tr->tr_verbosity == 0) + return; + + INFOLINE("test-run-name", tr->tr_commandline_flags & TRF_NAME, + "%s\n", tr->tr_name); + + INFOLINE("test-execution-style", + tr->tr_commandline_flags & TRF_EXECUTION_STYLE, + "%s\n", to_execution_style_name(tr->tr_style)); + + if (!STAILQ_EMPTY(&tr->tr_search_path)) { + INFOLINE("test-search-path", + tr->tr_commandline_flags & TRF_SEARCH_PATH, + "%c", '['); + STAILQ_FOREACH(path_entry, &tr->tr_search_path, tsp_next) { + printf(" %s", path_entry->tsp_directory); + } + printf(" ]\n"); + } + + INFOLINE("test-run-base-directory", + tr->tr_commandline_flags & TRF_BASE_DIRECTORY, + "%s\n", tr->tr_runtime_base_directory); + + if (tr->tr_artefact_archive) { + INFOLINE("test-artefact-archive", + tr->tr_commandline_flags & TRF_ARTEFACT_ARCHIVE, + "%s\n", tr->tr_artefact_archive); + } + + printf("I %c %-*s ", + tr->tr_commandline_flags & TRF_EXECUTION_TIME ? '=' : '.', + FIELD_NAME_WIDTH, "test-execution-time"); + if (tr->tr_max_seconds_per_test == 0) + printf("unlimited\n"); + else + printf("%lu\n", tr->tr_max_seconds_per_test); + + printf("I %% %-*s %d\n", FIELD_NAME_WIDTH, "test-case-count", + test_case_count); + + if (tr->tr_action == TEST_RUN_EXECUTE) { + start_time = time(NULL); + printf("I %% %-*s %s", FIELD_NAME_WIDTH, + "test-run-start-time", ctime(&start_time)); + } +} + +static void +show_run_trailer(const struct test_run *tr) +{ + time_t end_time; + + if (tr->tr_verbosity == 0) + return; + + if (tr->tr_action == TEST_RUN_EXECUTE) { + end_time = time(NULL); + printf("I %% %-*s %s", FIELD_NAME_WIDTH, "test-run-end-time", + asctime(localtime(&end_time))); + } +} + +#undef INFOLINE +#undef FIELD_HEADER_WIDTH + +/* + * Helper: returns a character indicating the selection status for + * a test case. This character is as follows: + * + * - "*" all test functions in the test case were selected. + * - "+" some test functions in the test case were selected. + * - "-" no test functions from the test case were selected. + */ +static int +get_test_case_status(const struct test_case_selector *tcs) +{ + if (tcs->tcs_selected_count == 0) + return '-'; + if (tcs->tcs_selected_count == tcs->tcs_descriptor->tc_count) + return '*'; + return '?'; +} + +/* + * Helper: print out a comma-separated list of tags. + */ +static void +show_tags(int indent, const char *tags[]) +{ + const char **tag; + + printf("%*c: ", indent, ' '); + for (tag = tags; *tag && **tag != '\0';) { + printf("%s", *tag++); + if (*tag && **tag != '\0') + printf(","); + } + printf("\n"); +} + +/* + * Display a test case descriptor. + */ +static void +show_test_case(struct test_run *tr, const struct test_case_selector *tcs) +{ + const struct test_case_descriptor *tcd; + int prefix_char; + + prefix_char = get_test_case_status(tcs); + tcd = tcs->tcs_descriptor; + + printf("C %c %s\n", prefix_char, tcd->tc_name); + + if (tr->tr_verbosity > 0 && tcd->tc_tags != NULL) + show_tags(2, tcd->tc_tags); + + if (tr->tr_verbosity > 1 && tcd->tc_description) + printf(" & %s\n", tcd->tc_description); +} + +static void +show_test_function(struct test_run *tr, + const struct test_function_selector *tfs) +{ + const struct test_function_descriptor *tfd; + int selection_char; + + selection_char = tfs->tfs_is_selected ? '*' : '-'; + tfd = tfs->tfs_descriptor; + + printf(" F %c %s\n", selection_char, tfd->tf_name); + + if (tr->tr_verbosity > 0 && tfd->tf_tags != NULL) + show_tags(4, tfd->tf_tags); + + if (tr->tr_verbosity > 1 && tfd->tf_description) + printf(" & %s\n", tfd->tf_description); +} + +static int +show_listing(struct test_run *tr) +{ + const struct test_case_selector *tcs; + const struct test_function_selector *tfs; + + STAILQ_FOREACH(tcs, &tr->tr_test_cases, tcs_next) { + show_test_case(tr, tcs); + STAILQ_FOREACH(tfs, &tcs->tcs_functions, tfs_next) + show_test_function(tr, tfs); + } + + return (EXIT_SUCCESS); +} + +int +main(int argc, char **argv) +{ + struct test_run *tr; + int exit_code, option; + enum test_run_style run_style; + struct selection_option *selector; + struct selection_option_list selections = + STAILQ_HEAD_INITIALIZER(selections); + + tr = test_driver_allocate_run(); + + /* Parse arguments. */ + while ((option = getopt(argc, argv, ":R:T:c:ln:p:s:t:v")) != -1) { + switch (option) { + case 'R': /* Test runtime directory. */ + if (!test_driver_is_directory(optarg)) + errx(EX_USAGE, "option -%c: argument \"%s\" " + "does not name a directory.", option, + optarg); + tr->tr_runtime_base_directory = realpath(optarg, NULL); + if (tr->tr_runtime_base_directory == NULL) + err(1, "realpath failed for \"%s\"", optarg); + tr->tr_commandline_flags |= TRF_BASE_DIRECTORY; + break; + case 'T': /* Max execution time for a test function. */ + if (!parse_execution_time( + optarg, &tr->tr_max_seconds_per_test)) + errx(EX_USAGE, "option -%c: argument \"%s\" " + "is not a valid execution time value.", + option, optarg); + tr->tr_commandline_flags |= TRF_EXECUTION_TIME; + break; + case 'c': /* The archive holding artefacts. */ + tr->tr_artefact_archive = to_absolute_path(optarg); + tr->tr_commandline_flags |= TRF_ARTEFACT_ARCHIVE; + break; + case 'l': /* List matching tests. */ + tr->tr_action = TEST_RUN_LIST; + break; + case 'n': /* Test run name. */ + if (tr->tr_name) + free(tr->tr_name); + tr->tr_name = strdup(optarg); + tr->tr_commandline_flags |= TRF_NAME; + break; + case 'p': /* Add a search path entry. */ + if (!test_driver_add_search_path(tr, optarg)) + errx(EX_USAGE, "option -%c: argument \"%s\" " + "does not name a directory.", option, + optarg); + tr->tr_commandline_flags |= TRF_SEARCH_PATH; + break; + case 's': /* Test execution style. */ + if (!parse_run_style(optarg, &run_style)) + errx(EX_USAGE, "option -%c: argument \"%s\" " + "is not a supported test execution style.", + option, optarg); + tr->tr_style = run_style; + tr->tr_commandline_flags |= TRF_EXECUTION_STYLE; + break; + case 't': /* Test selection option. */ + if ((selector = parse_selection_option(optarg)) == NULL) + errx(EX_USAGE, "option -%c: argument \"%s\" " + "is not a valid selection pattern.", + option, optarg); + STAILQ_INSERT_TAIL(&selections, selector, so_next); + break; + case 'v': + tr->tr_verbosity++; + break; + case ':': + errx(EX_USAGE, + "ERROR: option -%c requires an argument.", optopt); + break; + case '?': + errx(EX_USAGE, + "ERROR: unrecognized option -%c", optopt); + break; + default: + errx(EX_USAGE, "ERROR: unspecified error."); + break; + } + } + + /* + * Set unset fields of the test run descriptor to their + * defaults. + */ + if (!test_driver_finish_run_initialization(tr, argv[0])) + err(EX_OSERR, "cannot initialize test driver"); + + /* Choose tests and test cases to act upon. */ + select_tests(tr, &selections); + + assert(STAILQ_EMPTY(&selections)); + + show_run_header(tr); + + /* Perform the requested action. */ + switch (tr->tr_action) { + case TEST_RUN_LIST: + exit_code = show_listing(tr); + break; + + case TEST_RUN_EXECUTE: + default: + /* Not yet implemented. */ + exit_code = EX_UNAVAILABLE; + } + + show_run_trailer(tr); + + test_driver_free_run(tr); + + exit(exit_code); +} diff --git a/contrib/elftoolchain/tests/libtest/driver/test_driver.1 b/contrib/elftoolchain/tests/libtest/driver/test_driver.1 new file mode 100644 index 0000000000..0e70c8d469 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/driver/test_driver.1 @@ -0,0 +1,308 @@ +.\" Copyright (c) 2019 Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd November 05, 2019 +.Dt TEST-DRIVER 1 +.Os +.Sh NAME +.Nm test-driver +.Nd scaffolding for executing +.Xr test 3 +based tests from the command-line +.Sh SYNOPSIS +.Nm test-executable +.Op Fl c Ar artefact-archive-name +.Op Fl l +.Op Fl n Ar run-name +.Op Fl p Ar search-path-directory +.Op Fl R Ar runtime-base-directory +.Op Fl s Ar execution-style +.Op Fl t Ar test-selector +.Op Fl T Ar seconds +.Op Fl v +.Sh DESCRIPTION +The +.Nm +library provides a +.Fn main +function that will execute the +.Xr test 3 +based tests in an executable according to the options specified +on the command-line. +The +.Nm +library usually used in conjunction with code generated by the +.Xr make-test-scaffolding 1 +utility. +.Pp +Test executables built using +.Nm +recognize the following command-line options: +.Bl -tag -width indent +.It Fl c Ar archive-name +If this option is specified, then the +.Nm +provided scaffolding will copy test outputs and other artefacts from +the test run to the archive named by argument +.Ar archive-name . +The format of the archive is specified by the path name suffix of the +archive name. +The supported output formats are those supported by +.Xr libarchive 3 . +.It Fl l +If this option is specified, then the +.Nm +utility will list the selected tests and exit. +.It Fl n Ar run-name +Use the specified test run name in status messages and to name +any files and directories created during the test run. +If this option is not specified, then the base name of the test +executable is used. +.It Fl p Ar search-path-directory +Add the argument +.Ar search-path-directory +to the list of directories searched for by +.Xr test 3 +utility functions. +.It Fl R Ar runtime-base-directory +Set the runtime base directory to the directory specified by the +argument +.Ar runtime-base-directory . +Tests execute with their current directory set to a subdirectory +within this directory. +The path specified by argument +.Ar runtime-base-directory +must exist, and must name a directory. +.Pp +If this option is not specified, then the +.Ev TEST_TMPDIR +environment variable will be examined. +If set to a non-empty value, then its value will be used. +Otherwise, the value of the +.Ev TMPDIR +environment variable will be used, if non-empty. +If neither of the environment variables +.Ev TEST_TMPDIR +and +.Ev TMPDIR +contain a non-empty value, then the path +.Dq Pa /tmp +will be used. +.It Fl s Ar execution-style +Set the desired execution style to that specified by argument +.Ar execution-style . +Legal values for +.Ar execution-style +are: +.Bl -tag -width indent -compact +.It Li atf +Be compatible with +.Nx +.Xr atf 9 . +.It Li tap +Be compatible with TAP +.Pq Test Anything Protocol . +.It Li test +Be compatible with libtest (this test framework). +.El +The default is to use libtest semantics. +.It Fl t Ar test-selector +Select (or deselect) tests to execute according to the argument +.Ar test-selector . +.Pp +Test selectors are specified using the following syntax: +.Bl -tag -compact -width indent +.It Xo +.Op Li - Ns +.Li c : Ns Ar pattern +.Xc +Select test cases whose names match +.Ar pattern . +Selecting a test case will cause all of its contained +test functions to be selected. +.It Xo +.Op Li - Ns +.Li f : Ns Ar pattern +.Xc +Select test functions whose names match +.Ar pattern . +.It Xo +.Op Li - Ns +.Li t : Ns Ar pattern +.Xc +Select the test cases and test functions associated with +tags matching +.Ar pattern . +.It Xo +.Op Li - Ns +.Ar pattern +.Xc +If the +.Li c , +.Li f +or +.Li t +qualifiers were not specified, then the pattern is matched +against the names of test cases. +.El +The +.Ar pattern +fields of test selectors use shell wildcard syntax, as implemented by +.Xr fnmatch 3 . +.Pp +If no test selectors are specified then all the tests present in +the test executable will be run. +Otherwise, the test selectors specified are processed in the +order specified on the command line. +.Pp +A test selector that does not start with a +.Dq Li - +will add the entries that it matches to the currently selected list +of tests. +A test selector that starts with a +.Dq Li - +will remove the entries that it matches from the currently selected list +of tests. +.Pp +If at least one test selector was specified, and if the result of +applying the specified test selectors was an empty list +of tests, then the +.Nm +library will exit with an error message. +.It Fl T Ar seconds +Set the timeout for individual tests to +.Ar seconds . +If a test function fails to return with the specified number of seconds +then it is treated as having failed. +The default is to wait indefinitely for the test function to complete. +.It Fl v +Increase verbosity level by 1. +The default verbosity level is 0. +.El +.Ss Link-time Pre-requisites +The +.Nm +library expects the following symbols to be present in the +test executable it is linked with: +.Pp +.Bl -tag -width indent -compact +.It Xo +.Vt struct test_case_descriptor +.Va test_cases Ns [] +.Xc +An array of test cases descriptors. +Test case descriptors described by +.Xr test_case 5 . +.It Xo +.Vt int +.Va test_case_count +.Xc +The number of entries in the +.Va test_cases +array. +.El +.Ss Test Execution +At start up, the +.Fn main +function provided by +.Nm +will select tests (and test cases) to execute, based on the test +selection options specified. +.Pp +For each selected test case, test execution proceeds as follows: +.Bl -enum -compact +.It +The runtime directory for the test case is created. +.It +The test process forks, with test execution continuing in the +child. +.It +.Pq Child +The current directory of the process is changed to the runtime +directory. +.It +.Pq Child +The test case's set up function is then executed. +If this function returns an error then test case execution is +aborted. +.It +.Pq Child +Each selected test function in the test case is then executed and +its status is output to stdout (or stderr) according to the test +execution style selected. +.It +.Pq Child +The test case's tear down function is then executed. +.It +If test artefacts need to be preserved, then these are +copied to the specified archive. +.It +The test's runtime directory is then deleted. +.El +.Pp +After all test cases have been attempted, the +.Fn main +function exits with the exit code appropriate for the +test execution style selected. +.Sh EXAMPLES +To run all tests in the binary named +.Pa tc_example , +copying test artefacts to a +.Xr cpio 1 +archive named +.Pa /tmp/tc_example.cpio , +use: +.Bd -literal -offset indent +tc_example -c /tmp/tc_example.cpio +.Ed +.Pp +To execute tests in the test case +.Dq tc1 +alone, use: +.Bd -literal -offset indent +tc_example -t 'c:tc1' +.Ed +.Pp +To execute tests in the test case +.Dq tc1 +but not the test functions associated with tag +.Li tag1 , +use: +.Bd -literal -offset indent +tc_example -t 'c:tc1' -t '-t:tag1' +.Ed +.Sh DIAGNOSTICS +Test programs built with the +.Nm +library will exit with an exit code of 0 if all of the selected tests +passed when run, and with a non-zero exit code if an error +occurred during test execution. +.Sh SEE ALSO +.Xr make-test-scaffolding 1 , +.Xr fnmatch 3 , +.Xr libarchive 3 , +.Xr test 3 , +.Xr test_case 5 diff --git a/contrib/elftoolchain/tests/libtest/examples/Makefile b/contrib/elftoolchain/tests/libtest/examples/Makefile new file mode 100644 index 0000000000..9cc82d3dd7 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/examples/Makefile @@ -0,0 +1,14 @@ +# $Id$ +# +# Examples of tests built using test(3). + +TOP= ../../.. + +NOMAN= true + +CFLAGS+= -I../lib -Wall -pedantic + +TEST_SRCS= minimal_example.c \ + simple_example.c + +.include "$(TOP)/mk/elftoolchain.test.mk" diff --git a/contrib/elftoolchain/tests/libtest/examples/minimal_example.c b/contrib/elftoolchain/tests/libtest/examples/minimal_example.c new file mode 100644 index 0000000000..3bc76fe66e --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/examples/minimal_example.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $Id$ */ + +/* + * This C source defines a single test function named 'tf_helloworld', + * that is not part of a test case, and lacking a description or tags. + * + * Since no test cases are specified in this file, the test function + * would be assigned to the default test case (named 'default'). + * + * Given the object file created from this source, the + * 'make-test-scaffolding' utility will prepare the scaffolding + * needed to build an executable containing the test function. + */ + +#include "test.h" + +/* + * Function prototypes. + */ +enum test_result tf_helloworld(test_case_state); + +/* + * Function names prefixed with 'tf_' name test functions. + */ +enum test_result +tf_helloworld(test_case_state state) +{ + (void) state; + return (TEST_PASS); +} diff --git a/contrib/elftoolchain/tests/libtest/examples/simple_example.c b/contrib/elftoolchain/tests/libtest/examples/simple_example.c new file mode 100644 index 0000000000..6d72f65dd4 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/examples/simple_example.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $Id$ */ + +#include + +#include "test.h" + +/* + * Function prototypes. + */ +enum test_case_status tc_setup_helloworld(test_case_state *); +enum test_case_status tc_teardown_helloworld(test_case_state); +enum test_result tf_helloworld_sayhello(test_case_state); +enum test_result tf_helloworld_saygoodbye(test_case_state); + +/* + * This source defines a single test case named 'helloworld' containing a + * single test function named 'sayhello' contained in that test case. At + * test execution time the test case would be selectable using the tags + * "tag1" or "tag2", or by its name 'helloworld'. The test function can + * be selected using tags "tag3" or "tag4", or by its name + * 'helloworld_sayhello'. + * + * Given the object code generated from this file, the + * 'make-test-scaffolding' utility will prepare the scaffolding needed + * to create a executable that can be used to execute these tests. + * + * Specifically the 'make-test-scaffolding' utilit will generate test and + * test case descriptors equivalent to: + * + * struct test_descriptor test_functions_helloworld[] = { + * { + * .t_description = tf_description_helloworld_sayhello, + * .t_tags = tf_tags_helloworld_sayhello, + * .t_func = tf_helloworld_sayhello + * } + * }; + * + * struct test_case_descriptor test_cases[] = { + * { + * .tc_description = tc_description_helloworld, + * .tc_tags = tc_tags_helloworld, + * .tc_tests = test_functions_helloworld + * } + * }; + */ + +/* + * A symbol name prefixed with 'tc_description_' contains a + * test case description. The TEST_CASE_DESCRIPTION macro offers + * a convenient way to define such symbols. In the case of the + * symbol below, the test case named is 'helloworld'. + */ +TEST_CASE_DESCRIPTION(helloworld) = "A description for a test case."; + +/* + * Function names prefixed with 'tc_setup_' are assumed to be test + * case set up functions. + */ +enum test_case_status +tc_setup_helloworld(test_case_state *state) +{ + (void) state; + return (TEST_CASE_OK); +} + +/* + * Function names prefixed with 'tc_teardown_' are assumed to be test + * case tear down functions. + */ +enum test_case_status +tc_teardown_helloworld(test_case_state state) +{ + (void) state; + return (TEST_CASE_OK); +} + +/* + * Names prefixed with 'tc_tags_' denote the tags associated with test + * cases. The TESTC_ASE_TAGS macro offers a convenient way to define such + * symbols. + * + * In the example below, all test functions belonging to the test case + * named 'helloworld' would be associated with tags "tag1" and "tag2". + * + * Tags lists are terminated by a NULL entry. + */ +TEST_CASE_TAGS(helloworld) = { + "tag1", + "tag2", + NULL +}; + +/* + * Function names prefixed with 'tf_' name test functions. + */ +enum test_result +tf_helloworld_sayhello(test_case_state state) +{ + (void) state; + return (TEST_PASS); +} + +enum test_result +tf_helloworld_saygoodbye(test_case_state state) +{ + (void) state; + return (TEST_PASS); +} + +/* + * Names prefixed by 'tf_description_' contain descriptions of test + * functions (e.g., 'tf_description_helloworld_sayhello' contains the + * description for test function 'tf_helloworld_sayhello'). + * + * The TEST_DESCRIPTION macro offers a convenient way to define such + * symbols. + */ +TEST_DESCRIPTION(helloworld_sayhello) = + "A description for the test function 'tf_helloworld_sayhello'."; + +TEST_DESCRIPTION(helloworld_saygoodbye) = + "A description for the test function 'tf_helloworld_saygoodbye'."; + +/* + * Names prefixed by 'tf_tags_' contain the tags associated with + * test functions. + * + * In the example below, the tags 'tag3' and 'tag4' are associated + * with the test function 'tf_helloworld_sayhello'. + * + * Alternately, the TEST_TAGS() macro offers a convenient way to + * define such symbols. + * + * Tags lists are terminated by a NULL entry. + */ +test_tags tf_tags_helloworld_sayhello = { + "tag3", + "tag4", + NULL +}; + +test_tags tf_tags_helloworld_saygoodbye = { + "tag5", + NULL +}; diff --git a/contrib/elftoolchain/tests/libtest/lib/Makefile b/contrib/elftoolchain/tests/libtest/lib/Makefile new file mode 100644 index 0000000000..e36d8fa072 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/lib/Makefile @@ -0,0 +1,15 @@ +# $Id$ + +TOP= ../../.. + +LIB= test + +SRCS= test.c + +INCS= test.h test_case.h + +WARNS?= 6 + +MAN= test.3 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/tests/libtest/lib/test.3 b/contrib/elftoolchain/tests/libtest/lib/test.3 new file mode 100644 index 0000000000..e170c18159 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/lib/test.3 @@ -0,0 +1,110 @@ +.\" Copyright (c) 2018,2019 Joseph Koshy. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" This software is provided by Joseph Koshy ``as is'' and +.\" any express or implied warranties, including, but not limited to, the +.\" implied warranties of merchantability and fitness for a particular purpose +.\" are disclaimed. in no event shall Joseph Koshy be liable +.\" for any direct, indirect, incidental, special, exemplary, or consequential +.\" damages (including, but not limited to, procurement of substitute goods +.\" or services; loss of use, data, or profits; or business interruption) +.\" however caused and on any theory of liability, whether in contract, strict +.\" liability, or tort (including negligence or otherwise) arising in any way +.\" out of the use of this software, even if advised of the possibility of +.\" such damage. +.\" +.\" $Id$ +.\" +.Dd January 21, 2019 +.Dt TEST 3 +.Os +.Sh NAME +.Nm test +.Nd API for writing tests +.Sh LIBRARY +.Lb libtest +.Sh SYNOPSIS +.In test.h +.Ft enum test_case_status +.Fn test_case_setup "test_case_state *state" +.Ft enum test_case_status +.Fn test_case_teardown "test_case_state state" +.Ft enum test_result +.Fn test_function "test_case_state state" +.Vt "const char" +.Va test_description [] ; +.Vt "const char *" +.Va test_tags [] ; +.Vt "const char" +.Va test_case_description [] ; +.Vt "const char *" +.Va test_case_tags [] ; +.Sh DESCRIPTION +The +.Lb libtest +implements an API for writing tests. +.Ss Concepts +Tests are implemented using test functions, where each test function +verifies a specific assertion about the system being tested. +Test functions are associated with the following: +.Bl -bullet -compact +.It +An optional human-readable test description. +.It +An optional set of tags. +Tags are used to select or deselect specific tests in a run. +.El +.Pp +Test functions are further grouped into test cases, where a test case +contains a logical group of assertions about the system under test. +Test cases are associated the following: +.Bl -bullet -compact +.It +An optional human-readable test case description. +.It +An optional test case set up function. +If specified, this set up function would be invoked prior to any test +function contained in the test case. +The set up function can allocate and initialize test-specific state, to be +passed to test functions. +If no set up function is specified for the test case, a default (no-op) +function will be supplied. +.It +An optional test case tear down function. +The tear down function will be invoked after all test functions have been +invoked. +It would be responsible for deallocating any resources that its corresponding +set up function had allocated. +If no tear down function is specified for a test case, a default no-op +function will be supplied. +.It +An optional set of tags for the test case. +These tags are used to select or delect specific test cases in a given test +run. +.El +.Pp +One or more test cases would be linked with a test driver to form a +test executable. +The default test driver supplied allows the test cases and specific tests +within the executable to be specified on the command line. +.Ss Scaffolding Generation +The +.Xr make-test-scaffolding 1 +script will generate the scaffolding needed to produce a test executable +from object files containing symbols following its naming conventions. +.Sh SEE ALSO +.Xr make-test-scaffolding 1 +.Sh AUTHORS +The +.Lb libtest +was written by +.An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net . diff --git a/contrib/elftoolchain/tests/libtest/lib/test.c b/contrib/elftoolchain/tests/libtest/lib/test.c new file mode 100644 index 0000000000..04999c1966 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/lib/test.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test.h" + +/* To be implemented. */ diff --git a/contrib/elftoolchain/tests/libtest/lib/test.h b/contrib/elftoolchain/tests/libtest/lib/test.h new file mode 100644 index 0000000000..6928f867a6 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/lib/test.h @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LIBTEST_TEST_H_ +#define _LIBTEST_TEST_H_ + +/* + * The return values from test functions. + * + * - TEST_PASS : The assertion(s) in the test function passed. + * - TEST_FAIL : At least one assertion in the test function failed. + * - TEST_UNRESOLVED : The assertions in the test function could not be + * checked for some reason. + */ +enum test_result { + TEST_PASS = 0, + TEST_FAIL = 1, + TEST_UNRESOLVED = 2 +}; + +/* + * The return values from test case set up and tear down functions. + * + * - TEST_CASE_OK : The set up or tear down function was successful. + * - TEST_CASE_ERROR : Set up or tear down actions could not be completed. + * + * If a test case set up function returns TEST_CASE_ERROR then: + * - The test functions in the test case will not be run. + * - The test case's tear down function will not be invoked. + * - The test run as a whole will be treated as being in error. + * + * If a test case tear down function returns a TEST_CASE_ERROR, then + * the test run as a whole be treated as being in error. + */ +enum test_case_status { + TEST_CASE_OK = 0, + TEST_CASE_ERROR = 1 +}; + +/* + * A 'test_case_state' is a handle to resources shared by the test functions + * that make up a test case. A test_case_state is allocated by the test case + * set up function and is deallocated by the test case tear down function. + * + * The test(3) framework treats a 'test_case_state' as an opaque value. + */ +typedef void *test_case_state; + +/* + * Test case and test function descriptions, and convenience macros + * to define these. + */ +typedef const char test_case_description[]; + +#if !defined(TEST_CASE_DESCRIPTION) +#define TEST_CASE_DESCRIPTION(NAME) test_case_description tc_description_##NAME +#endif + +typedef const char test_description[]; + +#if !defined(TEST_DESCRIPTION) +#define TEST_DESCRIPTION(NAME) test_description tf_description_##NAME +#endif + +/* + * Test case and test function tags, and convenience macros to define + * these. + */ +typedef const char *test_case_tags[]; + +#if !defined(TEST_CASE_TAGS) +#define TEST_CASE_TAGS(NAME) test_case_tags tc_tags_##NAME +#endif + +typedef const char *test_tags[]; + +#if !defined(TEST_TAGS) +#define TEST_TAGS(NAME) test_tags tf_tags_##NAME +#endif + +/* + * A test case set up function. + * + * If defined for a test case, this function will be called prior to + * the execution of an of the test functions within the test cae. Test + * case execution will be aborted if the function returns any value other + * than TEST_CASE_OK. + * + * The function can set '*state' to a memory area holding test state to be + * passed to test functions. + * + * If the test case does not define a set up function, then a default + * no-op set up function will be used. + */ +typedef enum test_case_status test_case_setup_function( + test_case_state *state); + +/* + * A test function. + * + * This function will be invoked with the state that had been set by the + * test case set up function. The function returns TEST_PASS to report that + * its test succeeded or TEST_FAIL otherwise. In the event the test could + * not be executed, it can return TEST_UNRESOLVED. + */ +typedef enum test_result test_function(test_case_state state); + +/* + * A test case tear down function. + * + * If defined for a test case, this function will be called after the + * execution of the test functions in the test case. It is passed the + * state that had been allocated by the test case set up function, and is + * responsible for deallocating the resources that the set up function + * had allocated. + */ +typedef enum test_case_status test_case_teardown_function( + test_case_state state); + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Write a progress report to the test log. + * + * This function takes a printf(3)-like format string and associated + * arguments. + */ +int test_report_progress(const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBTEST_TEST_H_ */ diff --git a/contrib/elftoolchain/tests/libtest/lib/test_case.h b/contrib/elftoolchain/tests/libtest/lib/test_case.h new file mode 100644 index 0000000000..c40b15fb69 --- /dev/null +++ b/contrib/elftoolchain/tests/libtest/lib/test_case.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2018, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LIBTEST_TEST_CASE_H_ +#define _LIBTEST_TEST_CASE_H_ + +#include "test.h" + +/* + * These structures describe the test cases that are linked into a + * test executable. + */ + +/* A single test function, with its associated tags and description. */ +struct test_function_descriptor { + const char *tf_name; /* Test name. */ + const char *tf_description; /* Test description. */ + const char **tf_tags; /* The tags for the test. */ + test_function *tf_func; /* The function to invoke. */ +}; + +/* A test case, with its associated tests. */ +struct test_case_descriptor { + const char *tc_name; /* Test case name. */ + const char *tc_description; /* Test case description. */ + const char **tc_tags; /* Any associated tags. */ + const struct test_function_descriptor *tc_tests; /* Contained tests. */ + const int tc_count; /* The number of tests. */ +}; + +/* All test cases linked into the test binary. */ +extern struct test_case_descriptor test_cases[]; +extern const int test_case_count; + +#endif /* _LIBTEST_TEST_CASE_H_ */ diff --git a/contrib/elftoolchain/tests/tet/Makefile b/contrib/elftoolchain/tests/tet/Makefile new file mode 100644 index 0000000000..d5e15501ec --- /dev/null +++ b/contrib/elftoolchain/tests/tet/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile 4037 2024-01-17 11:21:50Z jkoshy $ +# +# TET-based test suites used by the Elftoolchain project. +# + +TOP= ../.. + +# Build TET and LIBTEST first. +SUBDIR+= tet + +# Build tests for libraries. +SUBDIR+= libelf +SUBDIR+= libelftc +SUBDIR+= libdwarf + +# Build tests for tools. +SUBDIR+= elfdump +SUBDIR+= nm + +.if !make(install) +.include "$(TOP)/mk/elftoolchain.subdir.mk" +.else +install: .SILENT .PHONY + echo Nothing to install. +.endif diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/Makefile new file mode 100644 index 0000000000..b9b3be677e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/Makefile @@ -0,0 +1,6 @@ +# $Id$ + +TOP= ../../.. +SUBDIR= ts + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/tet_scen b/contrib/elftoolchain/tests/tet/cxxfilt/tet_scen new file mode 100644 index 0000000000..9ec6da840f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/tet_scen @@ -0,0 +1,41 @@ +# $Id$ + +all + "Starting Test Suite" + ^builtin + ^misc + ^qualifiers + ^regression + ^substitute + ^template + "Complete Test Suite" + +builtin + "Starting builtin Test" + /ts/builtin/tc + "Complete builtin Test" + +misc + "Starting misc Test" + /ts/misc/tc + "Complete misc Test" + +qualifiers + "Starting qualifiers Test" + /ts/qualifiers/tc + "Complete qualifiers Test" + +regression + "Starting regression Test" + /ts/regression/tc + "Complete regression Test" + +substitute + "Starting substitute Test" + /ts/substitute/tc + "Complete substitute Test" + +template + "Starting template Test" + /ts/template/tc + "Complete template Test" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/tetexec.cfg b/contrib/elftoolchain/tests/tet/cxxfilt/tetexec.cfg new file mode 100644 index 0000000000..580b3aea6c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/tetexec.cfg @@ -0,0 +1,5 @@ +# elfdump Test Suite. +# +# $Id$ + +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/Makefile new file mode 100644 index 0000000000..9c87ccba50 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/Makefile @@ -0,0 +1,12 @@ +# $Id$ + +TOP= ../../../.. + +SUBDIR+= builtin +SUBDIR+= misc +SUBDIR+= qualifiers +SUBDIR+= regression +SUBDIR+= substitute +SUBDIR+= template + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/tclist new file mode 100644 index 0000000000..3c8ae27833 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/builtin/tclist @@ -0,0 +1,48 @@ +# ::= v # void +# ::= w # wchar_t +# ::= b # bool +# ::= c # char +# ::= a # signed char +# ::= h # unsigned char +# ::= s # short +# ::= t # unsigned short +# ::= i # int +# ::= j # unsigned int +# ::= l # long +# ::= m # unsigned long +# ::= x # long long, __int64 +# ::= y # unsigned long long, __int64 +# ::= n # __int128 +# ::= o # unsigned __int128 +# ::= f # float +# ::= d # double +# ::= e # long double, __float80 +# ::= g # __float128 +# ::= z # ellipsis +# ::= Dd # IEEE 754r decimal floating point (64 bits) +# ::= De # IEEE 754r decimal floating point (128 bits) +# ::= Df # IEEE 754r decimal floating point (32 bits) +# ::= Dh # IEEE 754r half-precision floating point (16 bits) +# ::= Di # char32_t +# ::= Ds # char16_t +# ::= Da # auto +# ::= Dc # decltype(auto) +# ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) +# ::= u # vendor extended type + +"_Z3barv", "bar()" +"_Z3barPv", "bar(void*)" +"_Z3bariPv", "bar(int, void*)" +"_Z3fooww", "foo(wchar_t, wchar_t)" +"_Z3foob", "foo(bool)" +"_Z3foocah", "foo(char, signed char, unsigned char)" +"_Z3barstij", "bar(short, unsigned short, int, unsigned int)" +"_Z3barlmxy", "bar(long, unsigned long, long long, unsigned long long)" +"_Z3barno", "bar(__int128, unsigned __int128)" +"_Z3foofdeg", "foo(float, double, long double, __float128)" +"_Z3fooiPcz", "foo(int, char*, ...)" +"_Z3fooDdDeDfDh", "foo(decimal64, decimal128, decimal32, half)" +"_Z3barDiDs", "bar(char32_t, char16_t)" +"_Z3barIiEDai", "auto bar(int)" +"_Z3barIiEDci", "decltype(auto) bar(int)" +"_Z3barIiEDni", "decltype(nullptr) bar(int)" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/func.sh b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/func.sh new file mode 100755 index 0000000000..b3956eb720 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/func.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# $Id$ + +tpstart() # write test purpose banner and initialise variables +{ + tet_infoline "$*" + FAIL=N +} + +tpresult() # give test purpose result +{ + # $1 is result code to give if FAIL=N (default PASS) + if [ $FAIL = N ]; then + tet_result ${1-PASS} + else + tet_result FAIL + fi +} + +check_rlt() # execute command (saving output) and check exit code +{ + # $1 is command, $2 is expected exit code (0 or "N" for non-zero) + RLT=`$1` + CODE=$? + if [ $2 = 0 -a $CODE -ne 0 ]; then + tet_infoline "Command ($1) gave exit code $CODE, expected 0" + FAIL=Y + elif [ $2 != 0 -a $CODE -eq 0 ]; then + tet_infoline "Command ($1) gave exit code $CODE, expected non-zero" + FAIL=Y + fi + + # $3 is expected result. + if [ "$RLT" != "$3" ]; then + tet_infoline "Command ($1) gave wrong result:" + tet_infoline "$RLT" + tet_infoline "expected:" + tet_infoline "$3" + FAIL=Y + fi +} + +run() +{ + tpstart "Running test '$1'" + check_rlt "$TET_SUITE_ROOT/../../cxxfilt/c++filt $1" 0 "$2" + tpresult +} diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/gen.awk b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/gen.awk new file mode 100755 index 0000000000..9aa8973659 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/gen.awk @@ -0,0 +1,33 @@ +#!/usr/bin/awk -f +# +# $Id$ + +BEGIN { + FS = "\"" + tp = 0 + print "#!/bin/sh\n" +} + +{ + sub(/#.*/, ""); + if (NF >= 5) { + tp++ + printf("tp%d()\n{\n run \"%s\" \"%s\"\n}\n\n", tp, $2, $4); + } +} + +END { + print "tet_startup=\"\"" + print "tet_cleanup=\"\"\n" + printf("%s", "iclist=\""); + for (i = 1; i <= tp; i++) { + printf("ic%d", i); + if (i != tp) + printf(" "); + } + printf("\"\n\n"); + for (i = 1; i <= tp; i++) + printf("ic%d=\"tp%d\"\n", i, i); + print "\n. $TET_SUITE_ROOT/ts/common/func.sh"; + print ". $TET_ROOT/lib/xpg3sh/tcm.sh"; +} diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/ts.mk b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/ts.mk new file mode 100644 index 0000000000..12429b2a94 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/common/ts.mk @@ -0,0 +1,15 @@ +# $Id$ + +TCLIST?= tclist + +.PHONY: all + +all: tc + +tc: ${TCLIST} + ${.CURDIR}/../common/gen.awk ${.ALLSRC} > ${.TARGET} + chmod +x ${.TARGET} + +clean: + rm -rf tc + diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/tclist new file mode 100644 index 0000000000..ebe3e65c1d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/misc/tclist @@ -0,0 +1,51 @@ +# simple function +"_Z1f", "f" +"_Z1fi", "f(int)" +"_Z1fic", "f(int, char)" +"_Z1f3bar", "f(bar)" +"_Z1fFviE", "f(void (int))" + +# namespace +"_ZN12elftoolchainE", "elftoolchain" +"_ZN11elftoolchainE", "_ZN11elftoolchainE" +"_ZN12elftoolchain", "_ZN12elftoolchain" +"_ZN12elftoolchain3foo3barE", "elftoolchain::foo::bar" +"_ZN12elftoolchain3foo3barEi", "elftoolchain::foo::bar(int)" +"_ZN12elftoolchain3foo3barEic", "elftoolchain::foo::bar(int, char)" + +# non-static member function with qualifiers +# N [] [] E +"_ZNKR12elftoolchain3fooEi", "elftoolchain::foo(int) const &" +"_ZNKO12elftoolchain3fooEi", "elftoolchain::foo(int) const &&" + +# function type with qualifiers. (note that the place to encode qualifiers +# is different than ) +# ::= [] [Dx] F [Y] + [] E +"_Z3fooKFviRE", "foo(void (int) const &)" +"_Z3fooKFviOE", "foo(void (int) const &&)" + +# Pointer-to-member type and type qualifiers +# ::= M +"_Z3barM12elftoolchainFviE", "bar(void (elftoolchain::*)(int))" +"_Z3barM12elftoolchainKFviRE", "bar(void (elftoolchain::*)(int) const &)" +"_Z3fooFvvEM1AFvvE", "foo(void (), void (A::*)())" +"_Z3fooPFvvEM1AFvvE", "foo(void (*)(), void (A::*)())" +"_Z3fooPFvvREM1AFvvE", "foo(void (*)() &, void (A::*)())" +"_Z3fooPFvvREM1AFvvOE", "foo(void (*)() &, void (A::*)() &&)" +"_Z3fooKFvvREM1AFvvE", "foo(void () const &, void (A::*)())" +"_Z3fooKPFvvREM1AFvvE", "foo(void (* const)() &, void (A::*)())" +"_Z3fooPKFvvREM1AFvvE", "foo(void (*)() const &, void (A::*)())" +"_Z3fooPKFvvREPM1AFvvE", "foo(void (*)() const &, void (A::**)())" +"_Z3fooPKFviREPM1AFvidE", "foo(void (*)(int) const &, void (A::**)(int, double))" +"_Z3fooPrKFvvREPKVM1APKFvvE", "foo(void (*)() const restrict &, void (* A::* volatile const*)() const)" + +# local names + + + +# abbreviation St +"_ZSt3foo", '::std::foo' +"_ZNSt3for3barE", 'std::for::bar' + +# c++11 decltype diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/tclist new file mode 100644 index 0000000000..98e725c7a6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/qualifiers/tclist @@ -0,0 +1,36 @@ +# ::= +# ::= P # pointer-to +# ::= R # reference-to +# ::= O # rvalue reference-to (C++0x) +# ::= C # complex pair (C 2000) +# ::= G # imaginary (C 2000) +# ::= U [] # vendor extended type qualifier + +# ::= [r] [V] [K] +"_Z3foorPirPirPi", "foo(int* restrict, int* restrict, int* restrict)" +"_Z3fooVPd", "foo(double* volatile)" + +# Pointer +"_Z3fooPi", "foo(int*)" +"_Z3fooPPi", "foo(int**)" +"_Z3fooKPi", "foo(int* const)" +"_Z3fooPKi", "foo(int const*)" +"_Z3fooKPKi", "foo(int const* const)" +"_Z3fooKPPi", "foo(int** const)" +"_Z3fooPKPi", "foo(int* const*)" +"_Z3fooPPKi", "foo(int const**)" +"_Z3fooKPKPi", "foo(int* const* const)" + +# Reference +"_Z3barRi", "bar(int&)" +"_Z3barRKi", "bar(int const&)" +"_ZplR1XS0_", "operator+(X&, X&)" +"_ZrsRK1XS1_", "operator>>(X const&, X const&)" +"_ZN1XaSEO1X", "X::operator=(X&&)" + +# Complex +"_Z3fooCd", "foo(double complex)" +"_Z3fooGdGf", "foo(double imaginary, float imaginary)" + +# Vendor +"_Z3fooPU3farc", "foo(char far*)" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/tclist new file mode 100644 index 0000000000..bca4daaa43 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/regression/tclist @@ -0,0 +1,42 @@ +# ticket 481, TLS wrappers +"_ZTWL20PrettyStackTraceHead", "TLS wrapper function for PrettyStackTraceHead" + +# ticket 488, trailing E +"_ZN1fILi4EEE", "f<4>" + +# ticket 489, handle Dv (__vector) +"_Z22__gen_ocl_write_imagef11ocl_image2dDv2_iDv4_f", "__gen_ocl_write_imagef(ocl_image2d, int __vector(2), float __vector(4))" +"_Z23__gen_ocl_write_imageui16ocl_image2darrayDv3_iDv4_j", "__gen_ocl_write_imageui(ocl_image2darray, int __vector(3), unsigned int __vector(4))" +"_Z1fDv2_i", "f(int __vector(2))" + +# ticket 491, omit "void" +"_Z1fv", "f()" +"_Z1fPv", "f(void*)" +"_Z1fiv", "f(int, void)" +"_Z1fvi", "f(void, int)" + +# ticket 508, demangler failure +"_ZN8TaskPool11AddTaskImplEONSt3__18functionIFvvEEE", "TaskPool::AddTaskImpl(std::__1::function&&)" + +# ticket 530, assertion failure +"_ZNSp16invalidOargumentC1ERKSs", "invalidOargument::invalidOargument(std::basic_string, std::allocator > const&)" + +# ticket 531, assertion failure +"____new_strtold_internal", "____new_strtold_internal" + +# ticket 537, demangler fails on a symbol from GNU gold +"_ZN4gold15relocate_relocsILi64ELb1ENS_22Default_classify_relocILi4ELi64ELb1EEEEEvPKNS_13Relocate_infoIXT_EXT0_EEEPKhmPNS_14Output_sectionEN6elfcpp9Elf_typesIXT_EE7Elf_OffEPhNSD_8Elf_AddrEmSF_m", "void gold::relocate_relocs<64, true, gold::Default_classify_reloc<4, 64, true> >(gold::Relocate_info<64, true> const*, unsigned char const*, unsigned long, gold::Output_section*, elfcpp::Elf_types<64>::Elf_Off, unsigned char*, elfcpp::Elf_types<64>::Elf_Addr, unsigned long, unsigned char*, unsigned long)" + +# ticket 538, demangler uses incorrect back-ref +"_ZN1f1gEP1hNS0_1iE", "f::g(h*, h::i)" + +# ticket 539, demangler does not demangle lambdas +"_ZZN9libunwind17LocalAddressSpace18findUnwindSectionsEjRNS_18UnwindInfoSectionsEENUlP12dl_phdr_infojPvE_8__invokeES4_jS5_", "libunwind::LocalAddressSpace::findUnwindSections(unsigned int, libunwind::UnwindInfoSections&)::{lambda(dl_phdr_info*, unsigned int, void*)#1}::__invoke(dl_phdr_info*, unsigned int, void*)" + +# ticket 554, assertion failure +"_ZZN7simlib318SIMLIB_create_nameEPKczE1s", "simlib3::SIMLIB_create_name(char const*, ...)::s" + +# ticket 581, memory corruption +"_ZZN5boost13serialization16singleton_module8get_lockEvE4lock", "boost::serialization::singleton_module::get_lock()::lock" +"_ZZN7WebCore19SVGAnimatedProperty20LookupOrCreateHelperINS_32SVGAnimatedStaticPropertyTearOffIbEEbLb1EE21lookupOrCreateWrapperEPNS_10SVGElementEPKNS_15SVGPropertyInfoERbE19__PRETTY_FUNCTION__", "WebCore::SVGAnimatedProperty::LookupOrCreateHelper, bool, true>::lookupOrCreateWrapper(WebCore::SVGElement*, WebCore::SVGPropertyInfo const*, bool&)::__PRETTY_FUNCTION__" +"_ZN10linked_ptrIN12CrxInstaller14WhitelistEntryEE4copyIS1_EEvPKS_IT_E", "void linked_ptr::copy(linked_ptr const*)" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/tclist new file mode 100644 index 0000000000..41173dc6fa --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/substitute/tclist @@ -0,0 +1,56 @@ +# ::= S _ +# ::= S_ + +"_ZN1N1TIiiE2mfES_IddE", "N::T::mf(N)" +"_ZN1N1TIiiE2mfES0_IddE", "N::T::mf(N::T)" +"_ZN1N1TIiiE2mfES1_IddE", "N::T::mf(N::T)" +"_ZN1N1TIiiE2mfES2_IddE", "_ZN1N1TIiiE2mfES2_IddE" +# wrong result: +# "_ZN1N1TIiiE2mfES2_IddE", "N::T::mf(N::T::mf)" + +"_ZN1f1gEP1hNS_1iE", "f::g(h*, f::i)" +"_ZN1f1gEP1hNS0_1iE", "f::g(h*, h::i)" +# wrong result: +# "_ZN1f1gEP1hNS0_1iE", "f::g(h*, f::g::i)" +"_ZN1f1gEP1hNS1_1iE", "f::g(h*, h*::i)" + +"_Z3fooN1A1B1TES_", "foo(A::B::T, A)" +"_Z3fooN1A1B1TES0_", "foo(A::B::T, A::B)" +"_Z3fooN1A1B1TES1_", "foo(A::B::T, A::B::T)" + +"_Z3foo5Hello5WorldS_S0_", "foo(Hello, World, Hello, World)" + +# qualifiers with builtin type should be substitute candidates +"_Z3fooPiS_", "foo(int*, int*)" +"_Z3fooKPiS_", "foo(int* const, int*)" +"_Z3fooKPiS0_", "foo(int* const, int* const)" +"_Z3fooRKiS_", "foo(int const&, int const)" +"_Z3fooRKiS0_", "foo(int const&, int const&)" +"_Z3foorKiS_", "foo(int const restrict, int const restrict)" +"_Z3fooPrKiS_", "foo(int const restrict*, int const restrict)" +"_Z3fooPrKiS0_", "foo(int const restrict*, int const restrict*)" +"_Z3foorPKiS_", "foo(int const* restrict, int const)" +"_Z3foorPKiS0_", "foo(int const* restrict, int const*)" +"_Z3foorPKiS1_", "foo(int const* restrict, int const* restrict)" +"_Z3foorKPiS_", "foo(int* const restrict, int*)" +"_Z3foorKPiS0_", "foo(int* const restrict, int* const restrict)" + +# qualifers with non-builin type +"_Z3fooP3BarS_", "foo(Bar*, Bar)" +"_Z3fooP3BarS0_", "foo(Bar*, Bar*)" +"_Z3fooPK3BarS_", "foo(Bar const*, Bar)" +"_Z3fooPK3BarS1_", "foo(Bar const*, Bar const*)" +"_Z3foorKP3BarS0_", "foo(Bar* const restrict, Bar*)" +"_Z3foorKP3BarS1_", "foo(Bar* const restrict, Bar* const restrict)" + +# vendor extended qualifiers and substitution +# note that ABI requires that "the type with all the K, V, and r qualifiers +# " plus any vendor extended types in the same order-insensitive set is +# substitutible". Here vendor extended type is not handled as above +# requirement. +"_Z3fooU3barKiS_", "foo(int const bar, int const)" +"_Z3fooU3barKiS0_", "foo(int const bar, int const bar)" + +# bug introduced with a botched fix for omitting "void" +"_Z3barvPvS_", "bar(void, void*, void*)" +# wrong result: bar(void, void*, void, void*) diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/Makefile b/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/Makefile new file mode 100644 index 0000000000..75324b6cad --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/Makefile @@ -0,0 +1,5 @@ +# $Id$ + +TOP= ../../../../.. + +.include "../common/ts.mk" diff --git a/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/tclist b/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/tclist new file mode 100644 index 0000000000..bb1a6234b6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/cxxfilt/ts/template/tclist @@ -0,0 +1,10 @@ +# Misc +"_Z1TIiE", "T" +"_Z1TIidE", "T" +"_Z1TIidET_T0_", "int T(double)" +"_ZN3Foo3BarIiiE1fEii", "Foo::Bar::f(int, int)" +"_ZN3Foo3BarIiiE1fIiiEEii", "int Foo::Bar::f(int)" +"_ZN3Foo3BarIiiE1fE1TIiE", "Foo::Bar::f(T)" +"_ZN3Foo3BarIiiE1fE1TIiEi", "Foo::Bar::f(T, int)" +"_ZN3Foo3BarIiiE1fE1TIiEii", "Foo::Bar::f(T, int, int)" +"_Z3foo1TIiEdh", "foo(T, double, unsigned char)" diff --git a/contrib/elftoolchain/tests/tet/elfdump/Makefile b/contrib/elftoolchain/tests/tet/elfdump/Makefile new file mode 100644 index 0000000000..ff9a8afba2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/Makefile @@ -0,0 +1,5 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/elfdump/tet_scen b/contrib/elftoolchain/tests/tet/elfdump/tet_scen new file mode 100644 index 0000000000..37b55250a1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/tet_scen @@ -0,0 +1,47 @@ +# $Id: tet_scen 4002 2023-04-16 16:06:14Z jkoshy $ + +all + "Starting Test Suite" + ^exec1 + ^exec2 + ^exec3 + ^dso1 + ^dso2 + ^archive1 + ^archive2 + "Complete Test Suite" + +exec1 + "Starting exec1 Test" + /ts/exec1/tc + "Complete exec1 Test" + +exec2 + "Starting exec2 Test" + /ts/exec2/tc + "Complete exec2 Test" + +exec3 + "Starting exec3 Test" + /ts/exec3/tc + "Complete exec3 Test" + +dso1 + "Starting dso1 Test" + /ts/dso1/tc + "Complete dso1 Test" + +dso2 + "Starting dso2 Test" + /ts/dso2/tc + "Complete dso2 Test" + +archive1 + "Starting archive1 Test" + /ts/archive1/tc + "Complete archive1 Test" + +archive2 + "Starting archive2 Test" + /ts/archive2/tc + "Complete archive2 Test" diff --git a/contrib/elftoolchain/tests/tet/elfdump/tetexec.cfg b/contrib/elftoolchain/tests/tet/elfdump/tetexec.cfg new file mode 100644 index 0000000000..aef50d7d5b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/tetexec.cfg @@ -0,0 +1,5 @@ +# elfdump Test Suite. +# +# $Id: tetexec.cfg 2083 2011-10-27 04:41:39Z jkoshy $ + +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@G%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@G%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@G%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@G%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@c%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@c%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@d%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@d%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@e%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@e%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@h%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@h%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@k%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@k%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@n%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@n%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@p%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@p%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@r%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@r%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s@N%.symtab%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s@N%.symtab%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s@N%ARSYM%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@s@N%ARSYM%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@v%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@S@v%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c@p@n%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c@p@n%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c@s%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@c@s%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@d%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@d%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e@i%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e@i%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e@p@c%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@e@p@c%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@h%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@h%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@n%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@n%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@p%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@p%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@p@s%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@p@s%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@r%liba.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/@r%liba.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/tc new file mode 100755 index 0000000000..18894e288f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/archive1/tc @@ -0,0 +1,168 @@ +#!/bin/sh +# +# $Id: tc 2083 2011-10-27 04:41:39Z jkoshy $ + +tp1() +{ + run "@e%liba.a" +} + +tp2() +{ + run "@p%liba.a" +} + +tp3() +{ + run "@G%liba.a" +} + +tp4() +{ + run "@n%liba.a" +} + +tp5() +{ + run "@p@s%liba.a" +} + +tp6() +{ + run "@c%liba.a" +} + +tp7() +{ + run "@c@s%liba.a" +} + +tp8() +{ + run "@c@p@n%liba.a" +} + +tp9() +{ + run "@d%liba.a" +} + +tp10() +{ + run "@e@i%liba.a" +} + +tp11() +{ + run "@r%liba.a" +} + +tp12() +{ + run "@h%liba.a" +} + +tp13() +{ + run "@e@p@c%liba.a" +} + +tp14() +{ + run "@S@e%liba.a" +} + +tp15() +{ + run "@S@p%liba.a" +} + +tp16() +{ + run "@S@G%liba.a" +} + +tp17() +{ + run "@S@r%liba.a" +} + +tp18() +{ + run "@S@d%liba.a" +} + +tp19() +{ + run "@S@n%liba.a" +} + +tp20() +{ + run "@S@c%liba.a" +} + +tp21() +{ + run "@S@s%liba.a" +} + +tp22() +{ + run "@S@k%liba.a" +} + +tp23() +{ + run "@S@v%liba.a" +} + +tp24() +{ + run "@S@h%liba.a" +} + +tp25() +{ + run "@S@s@N%ARSYM%liba.a" +} + +tp26() +{ + run "@S@s@N%.symtab%liba.a" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@G%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@G%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@G%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@G%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@c%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@c%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@d%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@d%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@e%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@e%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@h%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@h%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@k%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@k%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@n%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@n%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@p%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@p%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@r%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@r%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s@N%.symtab%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s@N%.symtab%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s@N%ARSYM%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@s@N%ARSYM%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@v%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@S@v%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@c%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@c%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@d%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@d%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@e%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@e%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@h%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@h%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@i%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@i%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@k%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@k%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@n%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@n%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@p%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@p%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@r%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@r%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@s%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@s%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@v%libdwarf.a.err b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/@v%libdwarf.a.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/tc new file mode 100755 index 0000000000..1dca91359e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/archive2/tc @@ -0,0 +1,162 @@ +#!/bin/sh +# +# $Id: tc 2083 2011-10-27 04:41:39Z jkoshy $ + +tp1() +{ + run "@e%libdwarf.a" +} + +tp2() +{ + run "@p%libdwarf.a" +} + +tp3() +{ + run "@G%libdwarf.a" +} + +tp4() +{ + run "@n%libdwarf.a" +} + +tp5() +{ + run "@c%libdwarf.a" +} + +tp6() +{ + run "@s%libdwarf.a" +} + +tp7() +{ + run "@d%libdwarf.a" +} + +tp8() +{ + run "@i%libdwarf.a" +} + +tp9() +{ + run "@r%libdwarf.a" +} + +tp10() +{ + run "@h%libdwarf.a" +} + +tp11() +{ + run "@v%libdwarf.a" +} + +tp12() +{ + run "@k%libdwarf.a" +} + +tp13() +{ + run "@S@e%libdwarf.a" +} + +tp14() +{ + run "@S@p%libdwarf.a" +} + +tp15() +{ + run "@S@G%libdwarf.a" +} + +tp16() +{ + run "@S@r%libdwarf.a" +} + +tp17() +{ + run "@S@d%libdwarf.a" +} + +tp18() +{ + run "@S@n%libdwarf.a" +} + +tp19() +{ + run "@S@c%libdwarf.a" +} + +tp20() +{ + run "@S@s%libdwarf.a" +} + +tp21() +{ + run "@S@k%libdwarf.a" +} + +tp22() +{ + run "@S@v%libdwarf.a" +} + +tp23() +{ + run "@S@h%libdwarf.a" +} + +tp24() +{ + run "@S@s@N%ARSYM%libdwarf.a" +} + +tp25() +{ + run "@S@s@N%.symtab%libdwarf.a" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/bin/tcgen.sh b/contrib/elftoolchain/tests/tet/elfdump/ts/bin/tcgen.sh new file mode 100755 index 0000000000..f4af41df85 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/bin/tcgen.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# $Id: tcgen.sh 2083 2011-10-27 04:41:39Z jkoshy $ + +usage() +{ + echo "Usage: tcgen.sh prog tcdir file [-S]" +} + +if [ $# -lt 3 ]; then + usage + exit 1 +fi + +prog=$1 +tcdir=$2 +file=$3 +rundir=`pwd` +if [ "$4" = "-S" ]; then + ADD_S=yes +fi + +cd "$tcdir" +rm -f tc +touch tc +echo "#!/bin/sh" > tc +echo "" >> tc +c=0 +while [ 1 ]; do + read line || break + rlt=`echo "$line" | sed -e 's/ *-/@/g' -e 's/ */%/g'` + if [ "$ADD_S" = yes ]; then + rlt="@S${rlt}" + fi + $prog ${line} > "${rlt}.out" 2> "${rlt}.err" + c=`expr $c + 1` + echo "tp$c()" >> tc + echo "{" >> tc + echo " run \"$rlt\"" >> tc + echo "}" >> tc + echo "" >> tc +done < ${rundir}/${file} +echo "" >> tc + +echo "tet_startup=\"\"" >> tc +echo "tet_cleanup=\"cleanup\"" >> tc +echo "" >> tc + +echo -n "iclist=\"" >> tc +i=1 +while [ $i -le $c ]; do + echo -n "ic${i}" >> tc + if [ $i -ne $c ]; then + echo -n " " >> tc + fi + i=`expr $i + 1` +done +echo "\"" >> tc +echo "" >> tc + +i=1 +while [ $i -le $c ]; do + echo "ic${i}=\"tp${i}\"" >> tc + i=`expr $i + 1` +done +echo "" >> tc + +echo ". \$TET_SUITE_ROOT/ts/common/func.sh" >> tc +echo ". \$TET_ROOT/lib/xpg3sh/tcm.sh" >> tc + +chmod +x tc diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/common/func.sh b/contrib/elftoolchain/tests/tet/elfdump/ts/common/func.sh new file mode 100755 index 0000000000..2afc7e6d53 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/common/func.sh @@ -0,0 +1,127 @@ +#!/bin/sh +# +# $Id: func.sh 2083 2011-10-27 04:41:39Z jkoshy $ + +tpstart() # write test purpose banner and initialise variables +{ + tet_infoline "$*" + FAIL=N +} + +tpresult() # give test purpose result +{ + # $1 is result code to give if FAIL=N (default PASS) + if [ $FAIL = N ]; then + tet_result ${1-PASS} + else + tet_result FAIL + fi +} + +check_exit() # execute command (saving output) and check exit code +{ + # $1 is command, $2 is expected exit code (0 or "N" for non-zero) + eval "$1" > out.stdout 2> out.stderr + CODE=$? + if [ $2 = 0 -a $CODE -ne 0 ]; then + tet_infoline "Command ($1) gave exit code $CODE, expected 0" + FAIL=Y + elif [ $2 != 0 -a $CODE -eq 0 ]; then + tet_infoline "Command ($1) gave exit code $CODE, expected non-zero" + FAIL=Y + fi +} + +check_nostdout() # check that nothing went to stdout +{ + if [ -s out.stdout ]; then + tet_infoline "Unexpected output written to stdout, as shown below:" + infofile out.stdout stdout: + FAIL=Y + fi +} + +check_nostderr() # check that nothing went to stderr +{ + if [ -s out.stderr ]; then + tet_infoline "Unexpected output written to stderr, as shown below:" + infofile out.stderr stderr: + FAIL=Y + fi +} + +check_stderr() # check that stderr matches expected error +{ + # $1 is file containing expected error + # if no argument supplied, just check out.stderr is not empty + + case $1 in + "") + if [ ! -s out.stderr ]; then + tet_infoline "Expected output to stderr, but none written" + FAIL=Y + fi + ;; + *) + diff -uN out.stderr ${1}.err > diff.out 2> /dev/null + if [ $? -ne 0 ]; then + tet_infoline "Incorrect output written to stderr, as shown below" + infofile "diff.out" "diff:" + FAIL=Y + fi + ;; + esac +} + +check_stdout() # check that stdout matches expected output +{ + # $1 is file containing expected output + # if no argument supplied, just check out.stdout is not empty + + case $1 in + "") + if [ ! -s out.stdout ] + then + tet_infoline "Expected output to stdout, but none written" + FAIL=Y + fi + ;; + *) + diff -uN out.stdout ${1}.out > diff.out 2> /dev/null + if [ $? -ne 0 ]; then + tet_infoline "Incorrect output written to stdout, as shown below" + infofile "diff.out" "diff:" + FAIL=Y + fi + ;; + esac +} + +infofile() # write file to journal using tet_infoline +{ + # $1 is file name, $2 is prefix for tet_infoline + + prefix=$2 + while read line + do + tet_infoline "$prefix$line" + done < $1 +} + +run() +{ + tpstart + cmdline=`echo $1 | sed -e 's/@/ -/g' -e 's/%/ /g'` + tet_infoline "$cmdline" + check_exit "$TET_SUITE_ROOT/../../elfdump/elfdump $cmdline" 0 + check_stderr $1 + check_stdout $1 + tpresult +} + +cleanup() +{ + rm -f out.stdout + rm -f out.stderr + rm -f diff.out +} diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@G%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@G%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@G%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@G%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@c@s%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@c@s%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@d%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@d%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@e%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@e%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@h%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@h%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@k%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@k%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@n%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@n%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@p%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@p%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@r%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@r%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@s@N%.dynsym%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@s@N%.dynsym%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@v%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@S@v%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c@p@n%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c@p@n%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c@s%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@c@s%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@d%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@d%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e@i%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e@i%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e@p@c%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@e@p@c%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@h%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@h%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@n%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@n%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@p%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@p%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@p@s%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@p@s%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@r%libelf.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/@r%libelf.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/tc new file mode 100755 index 0000000000..d97437fdb1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/dso1/tc @@ -0,0 +1,157 @@ +#!/bin/sh +# +# $Id: tc 2083 2011-10-27 04:41:39Z jkoshy $ + +tp1() +{ + run "@e%libelf.so" +} + +tp2() +{ + run "@p%libelf.so" +} + +tp3() +{ + run "@G%libelf.so" +} + +tp4() +{ + run "@n%libelf.so" +} + +tp5() +{ + run "@p@s%libelf.so" +} + +tp6() +{ + run "@c%libelf.so" +} + +tp7() +{ + run "@c@s%libelf.so" +} + +tp8() +{ + run "@c@p@n%libelf.so" +} + +tp9() +{ + run "@d%libelf.so" +} + +tp10() +{ + run "@e@i%libelf.so" +} + +tp11() +{ + run "@r%libelf.so" +} + +tp12() +{ + run "@h%libelf.so" +} + +tp13() +{ + run "@e@p@c%libelf.so" +} + +tp14() +{ + run "@S@e%libelf.so" +} + +tp15() +{ + run "@S@p%libelf.so" +} + +tp16() +{ + run "@S@G%libelf.so" +} + +tp17() +{ + run "@S@s@N%.dynsym%libelf.so" +} + +tp18() +{ + run "@S@r%libelf.so" +} + +tp19() +{ + run "@S@d%libelf.so" +} + +tp20() +{ + run "@S@n%libelf.so" +} + +tp21() +{ + run "@S@c@s%libelf.so" +} + +tp22() +{ + run "@S@k%libelf.so" +} + +tp23() +{ + run "@S@v%libelf.so" +} + +tp24() +{ + run "@S@h%libelf.so" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" + + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@G%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@G%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@G%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@G%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@c%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@c%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@d%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@d%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@e%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@e%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@h%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@h%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@k%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@k%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@n%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@n%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@p%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@p%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@r%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@r%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@s%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@s%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@v%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@S@v%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c@p@n%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c@p@n%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c@s%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@c@s%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@d%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@d%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e@i%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e@i%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e@p@c%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@e@p@c%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@h%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@h%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@n%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@n%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@p%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@p%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@p@s%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@p@s%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@r%test.so.err b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/@r%test.so.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/tc new file mode 100755 index 0000000000..73659a6421 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/dso2/tc @@ -0,0 +1,156 @@ +#!/bin/sh +# +# $Id: tc 2083 2011-10-27 04:41:39Z jkoshy $ + +tp1() +{ + run "@e%test.so" +} + +tp2() +{ + run "@p%test.so" +} + +tp3() +{ + run "@G%test.so" +} + +tp4() +{ + run "@n%test.so" +} + +tp5() +{ + run "@p@s%test.so" +} + +tp6() +{ + run "@c%test.so" +} + +tp7() +{ + run "@c@s%test.so" +} + +tp8() +{ + run "@c@p@n%test.so" +} + +tp9() +{ + run "@d%test.so" +} + +tp10() +{ + run "@e@i%test.so" +} + +tp11() +{ + run "@r%test.so" +} + +tp12() +{ + run "@h%test.so" +} + +tp13() +{ + run "@e@p@c%test.so" +} + +tp14() +{ + run "@S@e%test.so" +} + +tp15() +{ + run "@S@p%test.so" +} + +tp16() +{ + run "@S@G%test.so" +} + +tp17() +{ + run "@S@r%test.so" +} + +tp18() +{ + run "@S@d%test.so" +} + +tp19() +{ + run "@S@n%test.so" +} + +tp20() +{ + run "@S@c%test.so" +} + +tp21() +{ + run "@S@s%test.so" +} + +tp22() +{ + run "@S@k%test.so" +} + +tp23() +{ + run "@S@v%test.so" +} + +tp24() +{ + run "@S@h%test.so" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@G%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@G%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@G@e%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@G@e%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@G%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@G%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@c@s%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@c@s%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@d%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@d%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e@k%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e@k%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e@p%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@e@p%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@h%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@h%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@n%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@n%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r@N%.rela.dyn%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r@N%.rela.dyn%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r@N%.rela.dyn@N%.rela.plt%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@r@N%.rela.dyn@N%.rela.plt%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@s@N%.dynsym%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@s@N%.dynsym%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@v%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@S@v%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@d%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@d%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@p@n%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@p@n%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@s%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@c@s%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@d%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@d%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@p%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@p%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@p@c@d%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@e@p@c@d%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@n%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@n%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@e%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@e%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@n%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@n%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@s%ls.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/@p@s%ls.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/ls b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/ls new file mode 100644 index 0000000000..4b7329db8e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/ls differ diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/tc new file mode 100755 index 0000000000..bd201e65a7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/exec1/tc @@ -0,0 +1,174 @@ +#!/bin/sh +# +# $Id: tc 2083 2011-10-27 04:41:39Z jkoshy $ + +tp1() +{ + run "@e%ls" +} + +tp2() +{ + run "@e@p%ls" +} + +tp3() +{ + run "@p@e%ls" +} + +tp4() +{ + run "@G%ls" +} + +tp5() +{ + run "@G@e%ls" +} + +tp6() +{ + run "@n%ls" +} + +tp7() +{ + run "@p@n%ls" +} + +tp8() +{ + run "@p@s%ls" +} + +tp9() +{ + run "@c%ls" +} + +tp10() +{ + run "@c@s%ls" +} + +tp11() +{ + run "@c@p@n%ls" +} + +tp12() +{ + run "@e@d%ls" +} + +tp13() +{ + run "@c@d%ls" +} + +tp14() +{ + run "@e@p@c@d%ls" +} + +tp15() +{ + run "@S@e%ls" +} + +tp16() +{ + run "@S@e@p%ls" +} + +tp17() +{ + run "@S@G%ls" +} + +tp18() +{ + run "@S@s@N%.dynsym%ls" +} + +tp19() +{ + run "@S@r%ls" +} + +tp20() +{ + run "@S@d%ls" +} + +tp21() +{ + run "@S@n%ls" +} + +tp22() +{ + run "@S@c@s%ls" +} + +tp23() +{ + run "@S@e@k%ls" +} + +tp24() +{ + run "@S@v%ls" +} + +tp25() +{ + run "@S@h%ls" +} + +tp26() +{ + run "@S@r@N%.rela.dyn%ls" +} + +tp27() +{ + run "@S@r@N%.rela.dyn@N%.rela.plt%ls" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@G%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@G%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@G@e%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@G@e%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@G%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@G%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@c@s%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@c@s%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@d%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@d%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@e%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@e%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@e@p%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@e@p%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@h%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@h%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@k%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@k%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@n%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@n%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@r%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@r%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@r@N%.rela.dyn%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@r@N%.rela.dyn%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@s@N%.dynsym%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@s@N%.dynsym%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@v%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@S@v%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@d%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@d%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@p@n%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@p@n%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@s%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@c@s%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@d%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@d%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@i%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@i%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@p%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@p%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@p@c@d%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@e@p@c@d%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@h%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@h%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@n%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@n%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@e%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@e%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@n%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@n%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@s%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@p@s%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@r%cp.err b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/@r%cp.err new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/cp b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/cp new file mode 100644 index 0000000000..ad3e1d1330 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/cp differ diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/tc new file mode 100755 index 0000000000..8bcb057559 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/exec2/tc @@ -0,0 +1,184 @@ +#!/bin/sh + +tp1() +{ + run "@e%cp" +} + +tp2() +{ + run "@e@p%cp" +} + +tp3() +{ + run "@p@e%cp" +} + +tp4() +{ + run "@G%cp" +} + +tp5() +{ + run "@G@e%cp" +} + +tp6() +{ + run "@n%cp" +} + +tp7() +{ + run "@p@n%cp" +} + +tp8() +{ + run "@p@s%cp" +} + +tp9() +{ + run "@c%cp" +} + +tp10() +{ + run "@c@s%cp" +} + +tp11() +{ + run "@c@p@n%cp" +} + +tp12() +{ + run "@e@d%cp" +} + +tp13() +{ + run "@c@d%cp" +} + +tp14() +{ + run "@e@i%cp" +} + +tp15() +{ + run "@r%cp" +} + +tp16() +{ + run "@h%cp" +} + +tp17() +{ + run "@e@p@c@d%cp" +} + +tp18() +{ + run "@S@e%cp" +} + +tp19() +{ + run "@S@e@p%cp" +} + +tp20() +{ + run "@S@G%cp" +} + +tp21() +{ + run "@S@s@N%.dynsym%cp" +} + +tp22() +{ + run "@S@r%cp" +} + +tp23() +{ + run "@S@d%cp" +} + +tp24() +{ + run "@S@n%cp" +} + +tp25() +{ + run "@S@c@s%cp" +} + +tp26() +{ + run "@S@k%cp" +} + +tp27() +{ + run "@S@v%cp" +} + +tp28() +{ + run "@S@h%cp" +} + +tp29() +{ + run "@S@r@N%.rela.dyn%cp" +} + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27 ic28 ic29" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" +ic28="tp28" +ic29="tp29" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/note_sections b/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/note_sections new file mode 100644 index 0000000000..a5c293150b Binary files /dev/null and b/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/note_sections differ diff --git a/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/tc b/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/tc new file mode 100755 index 0000000000..05d67b388e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/elfdump/ts/exec3/tc @@ -0,0 +1,185 @@ +#!/bin/sh + +tp1() +{ + run "@G%note_sections" +} + +tp2() +{ + run "@G@e%note_sections" +} + +tp3() +{ + run "@S@G%note_sections" +} + +tp4() +{ + run "@S@c@s%note_sections" +} + +tp5() +{ + run "@S@d%note_sections" +} + +tp6() +{ + run "@S@e%note_sections" +} + +tp7() +{ + run "@S@e@p%note_sections" +} + +tp8() +{ + run "@S@h%note_sections" +} + +tp9() +{ + run "@S@k%note_sections" +} + +tp10() +{ + run "@S@n%note_sections" +} + +tp11() +{ + run "@S@r%note_sections" +} + +tp12() +{ + run "@S@r@N%.rela.dyn%note_sections" +} + +tp13() +{ + run "@S@s@N%.symtab%note_sections" +} + +tp14() +{ + run "@S@v%note_sections" +} + +tp15() +{ + run "@c%note_sections" +} + +tp16() +{ + run "@d%note_sections" +} + +tp17() +{ + run "@c@p@n%note_sections" +} + +tp18() +{ + run "@c@s%note_sections" +} + +tp19() +{ + run "@e%note_sections" +} + +tp20() +{ + run "@e@d%note_sections" +} + +tp21() +{ + run "@e@i%note_sections" +} + +tp22() +{ + run "@e@p%note_sections" +} + +tp23() +{ + run "@e@p@c@d%note_sections" +} + +tp24() +{ + run "@h%note_sections" +} + +tp25() +{ + run "@n%note_sections" +} + +tp26() +{ + run "@p@e%note_sections" +} + +tp27() +{ + run "@p@n%note_sections" +} + +tp28() +{ + run "@p@s%note_sections" +} + +tp29() +{ + run "@r%note_sections" +} + + +tet_startup="" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic13 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27 ic28 ic29" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic13="tp13" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" +ic28="tp28" +ic29="tp29" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/libdwarf/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/Makefile new file mode 100644 index 0000000000..bc8bfebe1c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/Makefile @@ -0,0 +1,6 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. +SUBDIR= ts + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/tet_scen b/contrib/elftoolchain/tests/tet/libdwarf/tet_scen new file mode 100644 index 0000000000..9de96a4729 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/tet_scen @@ -0,0 +1,119 @@ +# $Id: tet_scen 2084 2011-10-27 04:48:12Z jkoshy $ + +all + "Starting Test Suite" + ^dwarf_init + ^dwarf_next_cu_header + ^dwarf_get_address_size + ^dwarf_siblingof + ^dwarf_child + ^dwarf_die_query + ^dwarf_die_offset + ^dwarf_die_convenience + ^dwarf_attr + ^dwarf_attrlist + ^dwarf_form + ^dwarf_loclist + ^dwarf_lineno + ^dwarf_frame + ^dwarf_arange + ^dwarf_abbrev + ^dwarf_pubnames + ^dwarf_macinfo + ^dwarf_ranges + "Complete Test Suite" + +dwarf_init + "Starting dwarf_init Test Case" + /ts/dwarf_init/tc_dwarf_init + "Complete dwarf_init Test Case" + +dwarf_next_cu_header + "Starting dwarf_next_cu_header Test Case" + /ts/dwarf_next_cu_header/tc_dwarf_next_cu_header + "Complete dwarf_next_cu_header Test Case" + +dwarf_get_address_size + "Starting dwarf_get_address_size Test Case" + /ts/dwarf_get_address_size/tc_dwarf_get_address_size + "Complete dwarf_get_address_size Test Case" + +dwarf_siblingof + "Starting dwarf_siblingof Test Case" + /ts/dwarf_siblingof/tc_dwarf_siblingof + "Complete dwarf_siblingof Test Case" + +dwarf_child + "Starting dwarf_child Test Case" + /ts/dwarf_child/tc_dwarf_child + "Complete dwarf_child Test Case" + +dwarf_die_query + "Starting dwarf_die_query Test Case" + /ts/dwarf_die_query/tc_dwarf_die_query + "Complete dwarf_die_query Test Case" + +dwarf_die_offset + "Starting dwarf_die_offset Test Case" + /ts/dwarf_die_offset/tc_dwarf_die_offset + "Complete dwarf_die_offset Test Case" + +dwarf_die_convenience + "Starting dwarf_die_convenience Test Case" + /ts/dwarf_die_convenience/tc_dwarf_die_convenience + "Complete dwarf_die_convenience Test Case" + +dwarf_attr + "Starting dwarf_attr Test Case" + /ts/dwarf_attr/tc_dwarf_attr + "Complete dwarf_attr Test Case" + +dwarf_attrlist + "Starting dwarf_attrlist Test Case" + /ts/dwarf_attrlist/tc_dwarf_attrlist + "Complete dwarf_attrlist Test Case" + +dwarf_form + "Starting dwarf_form Test Case" + /ts/dwarf_form/tc_dwarf_form + "Complete dwarf_form Test Case" + +dwarf_loclist + "Starting dwarf_loclist Test Case" + /ts/dwarf_loclist/tc_dwarf_loclist + "Complete dwarf_loclist Test Case" + +dwarf_lineno + "Starting dwarf_lineno Test Case" + /ts/dwarf_lineno/tc_dwarf_lineno + "Complete dwarf_lineno Test Case" + +dwarf_frame + "Starting dwarf_frame Test Case" + /ts/dwarf_frame/tc_dwarf_frame + "Complete dwarf_frame Test Case" + +dwarf_arange + "Starting dwarf_arange Test Case" + /ts/dwarf_arange/tc_dwarf_arange + "Complete dwarf_arange Test Case" + +dwarf_abbrev + "Starting dwarf_abbrev Test Case" + /ts/dwarf_abbrev/tc_dwarf_abbrev + "Complete dwarf_abbrev Test Case" + +dwarf_pubnames + "Starting dwarf_pubnames Test Case" + /ts/dwarf_pubnames/tc_dwarf_pubnames + "Complete dwarf_pubnames Test Case" + +dwarf_macinfo + "Starting dwarf_macinfo Test Case" + /ts/dwarf_macinfo/tc_dwarf_macinfo + "Complete dwarf_macinfo Test Case" + +dwarf_ranges + "Starting dwarf_ranges Test Case" + /ts/dwarf_ranges/tc_dwarf_ranges + "Complete dwarf_ranges Test Case" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/tetbuild.cfg b/contrib/elftoolchain/tests/tet/libdwarf/tetbuild.cfg new file mode 100644 index 0000000000..a073d6126c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/tetbuild.cfg @@ -0,0 +1,5 @@ +# $Id: tetbuild.cfg 2084 2011-10-27 04:48:12Z jkoshy $ + +TET_BUILD_TOOL=make +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libdwarf/tetclean.cfg b/contrib/elftoolchain/tests/tet/libdwarf/tetclean.cfg new file mode 100644 index 0000000000..154f724a30 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/tetclean.cfg @@ -0,0 +1,7 @@ +# $Id: tetclean.cfg 2084 2011-10-27 04:48:12Z jkoshy $ + +TET_CLEAN_TOOL=make +TET_CLEAN_FILE=clean + +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libdwarf/tetexec.cfg b/contrib/elftoolchain/tests/tet/libdwarf/tetexec.cfg new file mode 100644 index 0000000000..1dbc956d73 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/tetexec.cfg @@ -0,0 +1,3 @@ +# $Id: tetexec.cfg 2084 2011-10-27 04:48:12Z jkoshy $ + +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile new file mode 100644 index 0000000000..29417ec70b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile @@ -0,0 +1,27 @@ +# +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ +# + +TOP= ../../../.. + +SUBDIR+= dwarf_init +SUBDIR+= dwarf_next_cu_header +SUBDIR+= dwarf_get_address_size +SUBDIR+= dwarf_siblingof +SUBDIR+= dwarf_child +SUBDIR+= dwarf_die_query +SUBDIR+= dwarf_die_offset +SUBDIR+= dwarf_die_convenience +SUBDIR+= dwarf_attr +SUBDIR+= dwarf_attrlist +SUBDIR+= dwarf_form +SUBDIR+= dwarf_loclist +SUBDIR+= dwarf_lineno +SUBDIR+= dwarf_frame +SUBDIR+= dwarf_arange +SUBDIR+= dwarf_abbrev +SUBDIR+= dwarf_pubnames +SUBDIR+= dwarf_macinfo +SUBDIR+= dwarf_ranges + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile.tset b/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile.tset new file mode 100644 index 0000000000..a5c1121c82 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/Makefile.tset @@ -0,0 +1,56 @@ +# $Id: Makefile.tset 3290 2016-01-03 21:02:06Z jkoshy $ + +# libdwarf test suite uses libdwarf in /usr/local (i.e. SGI libdwarf), +# if TCGEN is defined. +.if defined(TCGEN) +DWARF_INC?= /usr/local/include +DWARF_LIBS?= /usr/local/lib +CFLAGS+= -DTCGEN -I${DWARF_INC} +LDADD+= -L${DWARF_LIBS} +.endif +LDADD+= -ldwarf + +DPADD+= ${LIBELF} +LDADD+= -lelf + +# Test cases do not have manual pages. +NOMAN= noman + +.include "${TOP}/mk/elftoolchain.os.mk" + +# Determine the location of the XML handling library. +.if ${OS_HOST} == FreeBSD +LDADD+= -lbsdxml +.else +.if ${OS_HOST} == DragonFly || ${OS_HOST} == NetBSD +CFLAGS+= -I/usr/pkg/include +LDADD+= -L/usr/pkg/lib +.endif +LDADD+= -lexpat +.endif + +.if !defined(TCGEN) +TS_SRCS+= ${.OBJDIR}/ic_count.c +${.OBJDIR}/ic_count.c: + ${TS_ROOT}/bin/count-ic ${.OBJDIR} +CLEANFILES+= ${.OBJDIR}/ic_count.c +.endif + +.for f in ${TS_DATA} +CLEANFILES+= ${f}.xml +.endfor + +# Copy test objects(binaries) to the build directory. +.for f in ${TS_DATA} +.if !exists(${f:R}) +${f}: ${TS_OBJROOT}/common/object/${f}.gz + cp ${.ALLSRC} ${.TARGET}.gz + gunzip ${.TARGET}.gz +.endif +.endfor + +# TET 3.8's headers do not compile with -Wstrict-prototypes, so restrict the +# OSes for which we use a non-zero WARNS value. +.if ${OS_HOST} == FreeBSD || ${OS_HOST} == DragonFly || ${OS_HOST} == Minix +WARNS?= 2 +.endif diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/README b/contrib/elftoolchain/tests/tet/libdwarf/ts/README new file mode 100644 index 0000000000..0a041dcbd6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/README @@ -0,0 +1,46 @@ +: $Id: README 3072 2014-06-23 03:08:44Z kaiwang27 $ + +Libdwarf test suite use XML files to describe test case, invocable +component and test purpose. + +Each test case can have several XML files, and each XML file +corresponds to exact one invocable component. + +For example, test case dwarf_get_address_size contains following +XML file: + + + + 4 + + + +Element 'ic' defines invocable component, in libdwarf test suite, one +invocable component can be invoked on only one test object (dt32-g1 in +this case). Element 'tp' defines a test purpose. A 'ic' can have +multiple 'tp' (only one in this case). Element 'vc' defines a +"variable check", which means verify varible's value against constant. +In this example, test purpose tp_dwarf_get_address_size will verify +that variable addr_size has value 4. + +When a test case is compiled nomarlly, during test case startup, the +test driver will parse the XML files and report to TET how many IC and +TP this test case have. When each TP is executed, test driver will +verify variable values according to the list of VC defined in that TP. + +When a test case is compiled with 'make TCGEN=yes', it will instead +link with SGI libdwarf and genearte XML files during TP execution. +These generated XML files can then be used directly to test this +libdwarf implementation. + +For example, to generate XML files for test case dwarf_next_cu_header: + +% cd /path/to/elftoolchain/test/libdwarf/ +# unsetenv TET_ROOT +% make clean && make TCGEN=yes +% cd ts/dwarf_next_cu_header +% setenv TET_ROOT /path/to/elftoolchain/test/tet +% env ICLIST=dt32-g1:dt64-g1:ec32-g1:ec64-g1:ld_symver.o-64-g1 ./tc_dwarf_next_cu_header + +(ICLIST defines a list of test objects on which the test case +generates. One gzipped XML file is generated for each test object.) diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/bin/count-ic b/contrib/elftoolchain/tests/tet/libdwarf/ts/bin/count-ic new file mode 100755 index 0000000000..8c3c249a80 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/bin/count-ic @@ -0,0 +1,38 @@ +#!/bin/sh +# +# $Id: count-ic 2084 2011-10-27 04:48:12Z jkoshy $ +# +# This shell script generates ic_count.c which contains a single +# variable definition `ic_count'. Variable `ic_count' is assigned +# the number of IC (invocable components) in the directory `dir'. +# The script count IC number by simply counting the number +# of .xml.gz files contained in the `dir', based on the fact that +# one .xml.gz file defines exactly one IC. + +usage() +{ + echo "usage:" `basename $0` "dir" +} + + +if [ $# -ne 1 ]; then + usage + exit 1 +fi + +dir=$1 + +if [ ! -d ${dir} ]; then + echo "${dir} does not exist or is not a directory" + exit 1 +fi + +count=`ls ${dir}/*.xml.gz | wc -l | awk '{print $1}'` +output="${dir}/ic_count.c" + +exec > ${output} +echo " +/* WARNING GENERATED FILE */ + +int ic_count = ${count}; +" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse.c new file mode 100644 index 0000000000..0dde964f15 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: die_traverse.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include + +#include "driver.h" + +static int die_cnt; + +/* + * DIE traverse function shared by test cases. + */ + +static void +_die_traverse_recursive(Dwarf_Debug dbg, Dwarf_Die die, + void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die0; + Dwarf_Off offset; + Dwarf_Half tag; + Dwarf_Error de; + const char *tagname; + int r; + + assert(dbg != NULL && die != NULL && die_callback != NULL); + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tagname = NULL; + if (dwarf_get_TAG_name(tag, &tagname) != DW_DLV_OK) { + tet_infoline("dwarf_get_TAG_name failed"); + result = TET_FAIL; + } + offset = 0; + if (dwarf_dieoffset(die, &offset, &de) != DW_DLV_OK) { + tet_printf("dwarf_dieoffset failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tet_printf("DIE #%d (%s) [%#x]\n", die_cnt++, tagname, offset); + + die_callback(die); + + /* Search children. */ + r = dwarf_child(die, &die0, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_child failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive(dbg, die0, die_callback); + + /* Search sibling. */ + r = dwarf_siblingof(dbg, die, &die0, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_siblingof failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive(dbg, die0, die_callback); +} + +static void +_die_traverse(Dwarf_Debug dbg, void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Unsigned cu_next_offset; + + assert(dbg != NULL && die_callback != NULL); + + die_cnt = 0; + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_siblingof(dbg, NULL, &die, &de) != DW_DLV_OK) + break; + _die_traverse_recursive(dbg, die, die_callback); + } +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse2.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse2.c new file mode 100644 index 0000000000..059ca13cb1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/die_traverse2.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 2010,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: die_traverse2.c 3076 2014-06-23 23:54:01Z kaiwang27 $ + */ + +#include +#include +#include + +#include "driver.h" + +static int die_cnt; + +/* + * DIE traverse function shared by test cases. (another version with + * .debug_types support) + */ + +static void +_die_traverse_recursive2(Dwarf_Debug dbg, Dwarf_Die die, + Dwarf_Bool is_info, void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die0; + Dwarf_Off offset; + Dwarf_Half tag; + Dwarf_Error de; + const char *tagname; + int r; + + assert(dbg != NULL && die != NULL && die_callback != NULL); + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tagname = NULL; + if (dwarf_get_TAG_name(tag, &tagname) != DW_DLV_OK) { + tet_infoline("dwarf_get_TAG_name failed"); + result = TET_FAIL; + } + offset = 0; + if (dwarf_dieoffset(die, &offset, &de) != DW_DLV_OK) { + tet_printf("dwarf_dieoffset failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tet_printf("DIE #%d (%s) [%#x]\n", die_cnt++, tagname, offset); + + die_callback(die); + + /* Search children. */ + r = dwarf_child(die, &die0, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_child failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive2(dbg, die0, is_info, die_callback); + + /* Search sibling. */ + r = dwarf_siblingof_b(dbg, die, &die0, is_info, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_siblingof failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive2(dbg, die0, is_info, die_callback); +} + +static void +_die_traverse2(Dwarf_Debug dbg, Dwarf_Bool is_info, + void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Unsigned cu_next_offset; + + assert(dbg != NULL && die_callback != NULL); + + die_cnt = 0; + + if (is_info) { + TS_DWARF_CU_FOREACH2(dbg, 1, cu_next_offset, de) { + if (dwarf_siblingof_b(dbg, NULL, &die, 1, &de) != + DW_DLV_OK) + break; + _die_traverse_recursive2(dbg, die, 1, die_callback); + } + } else { + do { + TS_DWARF_CU_FOREACH2(dbg, 0, cu_next_offset, de) { + if (dwarf_siblingof_b(dbg, NULL, &die, 0, + &de) != DW_DLV_OK) + break; + _die_traverse_recursive2(dbg, die, 0, + die_callback); + } + } while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); + } +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.c new file mode 100644 index 0000000000..0ce8842fac --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.c @@ -0,0 +1,893 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: driver.c 3772 2019-07-02 06:09:48Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#else +#include +#endif + +#include "_elftc.h" + +#include "driver.h" +#include "tet_api.h" + +#ifndef TCGEN +#define _XML_BUFSIZE 8192 +#define _XML_DATABUFSZ 65536 +struct _drv_vc { + const char *var; + union { + uint64_t u64; + int64_t i64; + char *str; + struct { + char *data; + int len; + } b; + } v; + enum { + _VTYPE_NONE, + _VTYPE_INT, + _VTYPE_UINT, + _VTYPE_STRING, + _VTYPE_BLOCK, + } vt; + enum { + _OP_EQ, + _OP_NE, + } op; + enum { + _FAIL_CONTINUE, + _FAIL_ABORT, + } fail; + STAILQ_ENTRY(_drv_vc) next; +}; +struct _drv_tp { + struct dwarf_tp *dtp; + int testnum; + STAILQ_HEAD(, _drv_vc) vclist; + STAILQ_ENTRY(_drv_tp) next; +}; +struct _drv_ic { + const char *file; + int tpcnt; + STAILQ_HEAD(, _drv_tp) tplist; + STAILQ_ENTRY(_drv_ic) next; +}; +extern int ic_count; +static STAILQ_HEAD(, _drv_ic) _iclist; +static struct _drv_ic *_cur_ic = NULL; +static struct _drv_tp *_cur_tp = NULL; +static struct _drv_vc *_cur_vc = NULL; +static char _xml_buf[_XML_BUFSIZE]; +static char _xml_data[_XML_DATABUFSZ]; +static int _xml_data_pos = 0; +static int _test_cnt = 0; +#else +FILE *_cur_fp = NULL; +#endif /* !TCGEN */ + +/* The name of the file currently being processed. */ +const char *_cur_file = NULL; + +static void driver_startup(void); +static void driver_cleanup(void); +static __attribute__ ((unused)) char * driver_string_encode(const char *str); +#ifndef TCGEN +static void driver_base64_decode(const char *code, int codesize, char **plain, + int *plainsize); +#else +static __attribute__ ((unused)) void driver_base64_encode(const char *plain, + int plainsize, char **code, int *codesize); +#endif /* !TCGEN */ + +void (*tet_startup)(void) = driver_startup; +void (*tet_cleanup)(void) = driver_cleanup; + +/* + * Functions used by TCM for supporting a dynamic test case. + */ + +#ifndef TCGEN +static struct _drv_ic * +_find_ic(int icnum) +{ + struct _drv_ic *ic; + int i; + + for (i = 1, ic = STAILQ_FIRST(&_iclist); + i < icnum && ic != NULL; + i++, ic = STAILQ_NEXT(ic, next)) + ; + + return (ic); +} + +static struct _drv_tp * +_find_tp(int icnum, int tpnum) +{ + struct _drv_ic *ic; + struct _drv_tp *tp; + int i; + + ic = _find_ic(icnum); + assert(ic != NULL); + for (i = 1, tp = STAILQ_FIRST(&ic->tplist); + i < tpnum && tp != NULL; + i++, tp = STAILQ_NEXT(tp, next)) + ; + + return (tp); +} +#endif /* !TCGEN */ + +int +tet_getminic(void) +{ + + return (1); /* IC start with 1. */ +} + +int +tet_getmaxic(void) +{ + +#ifdef TCGEN + return (1); +#else + return (ic_count); +#endif /* TCGEN */ +} + +int +tet_isdefic(int icnum) +{ + +#ifdef TCGEN + assert(icnum == 1); + return (1); +#else + if (icnum >= 1 && icnum <= ic_count) + return (1); + + return (0); +#endif /* TCGEN */ +} + +int +tet_gettpcount(int icnum) +{ +#ifdef TCGEN + assert(icnum == 1); + return (1); +#else + struct _drv_ic *ic; + + ic = _find_ic(icnum); + assert(ic != NULL); + + return (ic->tpcnt); +#endif /* TCGEN */ +} + +int +tet_gettestnum(int icnum, int tpnum) +{ +#ifdef TCGEN + assert(icnum == 1 && tpnum == 1); + return (1); +#else + struct _drv_tp *tp; + + tp = _find_tp(icnum, tpnum); + assert(tp != NULL); + + return (tp->testnum); +#endif /* TCGEN */ +} + +int +tet_invoketp(int icnum, int tpnum) +{ +#ifdef TCGEN + assert(icnum == 1 && tpnum == 1); + return (0); +#else + struct _drv_ic *ic; + struct _drv_tp *tp; + + ic = _find_ic(icnum); + assert(ic != NULL); + _cur_ic = ic; + _cur_file = _cur_ic->file; + tp = _find_tp(icnum, tpnum); + assert(tp != NULL && tp->dtp != NULL); + tet_printf("Start Test Purpose <%s> on <%s>\n", tp->dtp->tp_name, + _cur_ic->file); + _cur_vc = STAILQ_FIRST(&tp->vclist); + tp->dtp->tp_func(); + + return (0); +#endif /* TCGEN */ +} + +#ifndef TCGEN +static void +_xml_start_cb(void *data, const char *el, const char **attr) +{ + XML_Parser p; + int i, j; + + p = data; + + if (!strcmp(el, "ic")) { + if (_cur_ic != NULL) + errx(EXIT_FAILURE, "Nested IC at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + _cur_ic = calloc(1, sizeof(*_cur_ic)); + STAILQ_INIT(&_cur_ic->tplist); + if (_cur_ic == NULL) + err(EXIT_FAILURE, "calloc"); + for (i = 0; attr[i]; i += 2) { + if (!strcmp(attr[i], "file")) { + _cur_ic->file = strdup(attr[i + 1]); + if (_cur_ic->file == NULL) + err(EXIT_FAILURE, "strdup"); + break; + } + } + if (_cur_ic->file == NULL) + errx(EXIT_FAILURE, "IC without 'file' attribute " + "at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + + } else if (!strcmp(el, "tp")) { + if (_cur_ic == NULL) + errx(EXIT_FAILURE, "TP without containing IC at " + "line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + if (_cur_tp != NULL) + errx(EXIT_FAILURE, "Nested TP at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + _cur_tp = calloc(1, sizeof(*_cur_tp)); + STAILQ_INIT(&_cur_tp->vclist); + if (_cur_tp == NULL) + err(EXIT_FAILURE, "calloc"); + for (i = 0; attr[i]; i += 2) { + if (!strcmp(attr[i], "func")) { + for (j = 0; dwarf_tp_array[j].tp_name != NULL; + j++) + if (!strcmp(attr[i + 1], + dwarf_tp_array[j].tp_name)) { + _cur_tp->dtp = + &dwarf_tp_array[j]; + break; + } + if (_cur_tp->dtp == NULL) + errx(EXIT_FAILURE, + "TP function '%s' not found", + attr[i]); + break; + } + } + if (_cur_tp->dtp == NULL) + errx(EXIT_FAILURE, + "TP without 'func' attribute at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + + } else if (!strcmp(el, "vc")) { + if (_cur_tp == NULL) + errx(EXIT_FAILURE, + "VC without containing IC at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + if (_cur_vc != NULL) + errx(EXIT_FAILURE, "Nested VC at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + _cur_vc = calloc(1, sizeof(*_cur_vc)); + + _cur_vc->op = _OP_EQ; + _cur_vc->fail = _FAIL_CONTINUE; + if (_cur_vc == NULL) + err(EXIT_FAILURE, "calloc"); + for (i = 0; attr[i]; i += 2) { + if (!strcmp(attr[i], "var")) { + _cur_vc->var = strdup(attr[i + 1]); + if (_cur_vc->var == NULL) + err(EXIT_FAILURE, "strdup"); + } else if (!strcmp(attr[i], "type")) { + if (!strcmp(attr[i + 1], "int")) + _cur_vc->vt = _VTYPE_INT; + else if (!strcmp(attr[i + 1], "uint")) + _cur_vc->vt = _VTYPE_UINT; + else if (!strcmp(attr[i + 1], "str")) + _cur_vc->vt = _VTYPE_STRING; + else if (!strcmp(attr[i + 1], "block")) + _cur_vc->vt = _VTYPE_BLOCK; + else + errx(EXIT_FAILURE, + "Unknown value type %s at " + "line %jd", attr[i + 1], + (intmax_t) XML_GetCurrentLineNumber(p)); + } else if (!strcmp(attr[i], "op")) { + if (!strcmp(attr[i + 1], "ne")) + _cur_vc->op = _OP_NE; + } else if (!strcmp(attr[i], "fail")) { + if (!strcmp(attr[i + 1], "abort")) + _cur_vc->fail = _FAIL_ABORT; + } else + errx(EXIT_FAILURE, + "Unknown attr %s at line %jd", + attr[i], + (intmax_t) XML_GetCurrentLineNumber(p)); + } + if (_cur_vc->var == NULL || _cur_vc->vt == _VTYPE_NONE) + errx(EXIT_FAILURE, + "VC without 'var' or 'type' attribute at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + } else + errx(EXIT_FAILURE, "Unknown element %s at line %jd", el, + (intmax_t) XML_GetCurrentLineNumber(p)); +} + +static void +_xml_end_cb(void *data, const char *el) +{ + XML_Parser p; + + p = data; + + if (!strcmp(el, "ic")) { + if (_cur_ic == NULL) + errx(EXIT_FAILURE, "bogus IC end tag at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + STAILQ_INSERT_TAIL(&_iclist, _cur_ic, next); + _cur_ic = NULL; + } else if (!strcmp(el, "tp")) { + if (_cur_tp == NULL) + errx(EXIT_FAILURE, "bogus TP end tag at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + assert(_cur_ic != NULL); + _test_cnt++; + _cur_tp->testnum = _test_cnt; + STAILQ_INSERT_TAIL(&_cur_ic->tplist, _cur_tp, next); + _cur_ic->tpcnt++; + _cur_tp = NULL; + } else if (!strcmp(el, "vc")) { + if (_cur_vc == NULL) + errx(EXIT_FAILURE, "bogus VC end tag at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + if (_xml_data_pos == 0 && _cur_vc->vt != _VTYPE_STRING) + errx(EXIT_FAILURE, + "VC element without value defined at line %jd", + (intmax_t) XML_GetCurrentLineNumber(p)); + _xml_data[_xml_data_pos] = '\0'; + switch (_cur_vc->vt) { + case _VTYPE_INT: + _cur_vc->v.i64 = strtoimax(_xml_data, NULL, 0); + break; + case _VTYPE_UINT: + _cur_vc->v.u64 = strtoumax(_xml_data, NULL, 0); + break; + case _VTYPE_STRING: + _cur_vc->v.str = strdup(_xml_data); + if (_cur_vc->v.str == NULL) + err(EXIT_FAILURE, "strdup"); + break; + case _VTYPE_BLOCK: + driver_base64_decode(_xml_data, _xml_data_pos, + &_cur_vc->v.b.data, &_cur_vc->v.b.len); + break; + default: + assert(0); + break; + } + _xml_data_pos = 0; + + assert(_cur_tp != NULL); + STAILQ_INSERT_TAIL(&_cur_tp->vclist, _cur_vc, next); + _cur_vc = NULL; + } +} + +#define _VALUE_BUFSIZE 1024 + +static void +_xml_data_cb(void *data, const char *s, int len) +{ + + (void) data; + + if (_cur_vc != NULL) { + if (_xml_data_pos + len >= _XML_DATABUFSZ) { + warnx("_xml_data overflowed, data(%d) discarded", len); + return; + } + memcpy(&_xml_data[_xml_data_pos], s, len); + _xml_data_pos += len; + } +} + +#define _CMD_SIZE (2*PATH_MAX + 32) /* Two paths and a command */ + +static void +driver_parse_ic_desc(const char *fname) +{ + XML_Parser p; + ssize_t bytes; + int fd, final; + char *xml_name, *ext, *fname0; + char cmd[_CMD_SIZE]; + + if ((fname0 = strdup(fname)) == NULL) + err(EXIT_FAILURE, "strdup"); + fname0[strlen(fname) - 3] = '\0'; + snprintf(cmd, _CMD_SIZE, "gunzip -f -c %s > %s", fname, fname0); + if (system(cmd) < 0) + err(EXIT_FAILURE, "system"); + + if ((xml_name = strdup(fname)) == NULL) + err(EXIT_FAILURE, "strdup"); + ext = strrchr(xml_name, '.'); + assert(ext != NULL); + *ext = '\0'; + + if ((p = XML_ParserCreate(NULL)) == NULL) + errx(EXIT_FAILURE, "XML_ParserCreate failed"); + XML_SetUserData(p, p); + XML_SetElementHandler(p, _xml_start_cb, _xml_end_cb); + XML_SetCharacterDataHandler(p, _xml_data_cb); + + if ((fd = open(xml_name, O_RDONLY)) < 0) + err(EXIT_FAILURE, "open %s failed", xml_name); + + final = 0; + for (;;) { + bytes = read(fd, _xml_buf, _XML_BUFSIZE); + if (bytes < 0) + err(EXIT_FAILURE, "read %s failed", xml_name); + if (bytes == 0) + final = 1; + if (!XML_Parse(p, _xml_buf, (int) bytes, final)) + errx(EXIT_FAILURE, "XML_Parse error at line %jd: %s\n", + (intmax_t) XML_GetCurrentLineNumber(p), + XML_ErrorString(XML_GetErrorCode(p))); + if (final) + break; + } + + free(xml_name); +} + +static void +driver_parse_ic(void) +{ + struct dirent *dp; + DIR *dirp; + + if ((dirp = opendir(".")) == NULL) + err(EXIT_FAILURE, "opendir"); + while ((dp = readdir(dirp)) != NULL) { + if (strlen(dp->d_name) <= 7) + continue; + if (!strcmp(&dp->d_name[strlen(dp->d_name) - 7], ".xml.gz")) + driver_parse_ic_desc(dp->d_name); + } + (void) closedir(dirp); +} + +#else /* !TCGEN */ + +static void +driver_gen_tp(FILE *fp, const char *file) +{ + int i; + + assert(fp != NULL); + for (i = 0; dwarf_tp_array[i].tp_name != NULL; i++) { + fprintf(fp, " \n", dwarf_tp_array[i].tp_name); + _cur_file = file; + _cur_fp = fp; + dwarf_tp_array[i].tp_func(); + fprintf(fp, " \n"); + } +} + +#define _FILENAME_BUFSIZE 1024 +#define _CMD_SIZE 256 + +static void +driver_gen_ic(void) +{ + char *flist, *token; + FILE *fp; + char nbuf[_FILENAME_BUFSIZE], cmd[_CMD_SIZE]; + + flist = getenv("ICLIST"); + if (flist == NULL) + errx(EXIT_FAILURE, + "Driver in TCGEN mode but ICLIST env is not defined"); + if ((flist = strdup(flist)) == NULL) + err(EXIT_FAILURE, "strdup"); + while ((token = strsep(&flist, ":")) != NULL) { + snprintf(nbuf, sizeof(nbuf), "%s.xml", token); + if ((fp = fopen(nbuf, "w")) == NULL) + err(EXIT_FAILURE, "fopen %s failed", nbuf); + fprintf(fp, "\n", token); + driver_gen_tp(fp, token); + fprintf(fp, "\n"); + fclose(fp); + snprintf(cmd, _CMD_SIZE, "gzip -f %s", nbuf); + if (system(cmd) < 0) + err(EXIT_FAILURE, "system"); + } + free(flist); +} + +#endif /* !TCGEN */ + +#define _MAX_STRING_SIZE 65535 + +static char * +driver_string_encode(const char *str) +{ + static char enc[_MAX_STRING_SIZE]; + size_t len; + int pos; + +#define _ENCODE_STRING(S) do { \ + len = strlen(S); \ + if (pos + len < _MAX_STRING_SIZE) { \ + strncpy(enc + pos, S, len); \ + pos += len; \ + } else { \ + assert(0); \ + return (NULL); \ + } \ + } while(0) + + pos = 0; + for (; *str != '\0'; str++) { + switch (*str) { + case '"': + _ENCODE_STRING("""); + break; + case '\'': + _ENCODE_STRING("'"); + break; + case '<': + _ENCODE_STRING("<"); + break; + case '>': + _ENCODE_STRING(">"); + break; + case '&': + _ENCODE_STRING("&"); + break; + default: + /* Normal chars. */ + if (pos < _MAX_STRING_SIZE - 1) + enc[pos++] = *str; + else { + enc[pos] = '\0'; + assert(0); + return (NULL); + } + break; + } + } + enc[pos] = '\0'; + + return (enc); +#undef _ENCODE_STRING +} + +static void +driver_startup(void) +{ + +#ifdef TCGEN + driver_gen_ic(); +#else + STAILQ_INIT(&_iclist); + driver_parse_ic(); +#endif +} + +static void +driver_cleanup(void) +{ + +} + +/* + * Base64 encode/decode utility modified from libb64 project. It's been + * placed in the public domain. Note that this modified version doesn't + * emit newline during encoding. + */ + +#ifdef TCGEN + +typedef enum +{ + step_A, step_B, step_C +} base64_encodestep; + +typedef struct +{ + base64_encodestep step; + char result; +} base64_encodestate; + +static void +base64_init_encodestate(base64_encodestate* state_in) +{ + state_in->step = step_A; + state_in->result = 0; +} + +static char +base64_encode_value(char value_in) +{ + static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + + if (value_in > 63) + return '='; + + return encoding[(int)value_in]; +} + +static int +base64_encode_block(const char* plaintext_in, int length_in, char* code_out, + base64_encodestate* state_in) +{ + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char res; + char fragment; + + res = state_in->result; + + switch (state_in->step) + { + while (1) + { + case step_A: + if (plainchar == plaintextend) + { + state_in->result = res; + state_in->step = step_A; + return codechar - code_out; + } + fragment = *plainchar++; + res = (fragment & 0x0fc) >> 2; + *codechar++ = base64_encode_value(res); + res = (fragment & 0x003) << 4; + case step_B: + if (plainchar == plaintextend) + { + state_in->result = res; + state_in->step = step_B; + return codechar - code_out; + } + fragment = *plainchar++; + res |= (fragment & 0x0f0) >> 4; + *codechar++ = base64_encode_value(res); + res = (fragment & 0x00f) << 2; + case step_C: + if (plainchar == plaintextend) + { + state_in->result = res; + state_in->step = step_C; + return codechar - code_out; + } + fragment = *plainchar++; + res |= (fragment & 0x0c0) >> 6; + *codechar++ = base64_encode_value(res); + res = (fragment & 0x03f) >> 0; + *codechar++ = base64_encode_value(res); + } + } + /* control should not reach here */ + return codechar - code_out; +} + +static int +base64_encode_blockend(char* code_out, base64_encodestate* state_in) +{ + char* codechar = code_out; + + switch (state_in->step) + { + case step_B: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + break; + case step_C: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + break; + case step_A: + break; + } + + return codechar - code_out; +} + +static void +driver_base64_encode(const char *plain, int plainsize, char **code, + int *codesize) +{ + base64_encodestate state; + + assert(plain != NULL && plainsize > 0); + + *code = malloc(sizeof(char) * plainsize * 2); + if (*code == NULL) + err(EXIT_FAILURE, "malloc"); + + base64_init_encodestate(&state); + + *codesize = base64_encode_block(plain, plainsize, *code, &state); + *codesize += base64_encode_blockend(*code + *codesize, &state); +} + +#else /* TCGEN */ + +typedef enum +{ + step_a, step_b, step_c, step_d +} base64_decodestep; + +typedef struct +{ + base64_decodestep step; + char plainchar; +} base64_decodestate; + +static int +base64_decode_value(int value_in) +{ + static const char decoding[] = { 62,-1,-1,-1,63,52,53,54,55,56,57,58, + 59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2, + 3,4,5,6,7,8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,-1,-1,-1, + -1,-1,-1,26,27,28,29,30,31,32,33,34, + 35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51 }; + static const int decoding_size = sizeof(decoding); + + value_in -= 43; + if (value_in < 0 || value_in > decoding_size) + return -1; + + return decoding[value_in]; +} + +static void +base64_init_decodestate(base64_decodestate* state_in) +{ + state_in->step = step_a; + state_in->plainchar = 0; +} + +static int +base64_decode_block(const char* code_in, const int length_in, + char* plaintext_out, base64_decodestate* state_in) +{ + const char* codechar = code_in; + char* plainchar = plaintext_out; + char fragment; + + *plainchar = state_in->plainchar; + + switch (state_in->step) + { + while (1) { + case step_a: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_a; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar = (fragment & 0x03f) << 2; + case step_b: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_b; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x030) >> 4; + *plainchar = (fragment & 0x00f) << 4; + case step_c: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_c; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03c) >> 2; + *plainchar = (fragment & 0x003) << 6; + case step_d: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_d; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03f); + } + } + /* control should not reach here */ + return plainchar - plaintext_out; +} + +static void +driver_base64_decode(const char *code, int codesize, char **plain, int *plainsize) +{ + base64_decodestate state; + + assert(code != NULL && codesize > 0); + + *plain = malloc(sizeof(char) * codesize); + if (*plain == NULL) + err(EXIT_FAILURE, "malloc"); + + base64_init_decodestate(&state); + + *plainsize = base64_decode_block(code, codesize, *plain, &state); +} +#endif /* TCGEN */ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.h b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.h new file mode 100644 index 0000000000..580683ffd1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/driver.h @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: driver.h 3074 2014-06-23 03:08:53Z kaiwang27 $ + */ + +#ifndef _DRIVER_H_ +#define _DRIVER_H_ + +struct dwarf_tp { + const char *tp_name; + void (*tp_func)(void); +}; + +#define TS_DWARF_INIT(D,FD,DE) do { \ + (D) = NULL; \ + if (((FD) = open(_cur_file, O_RDONLY)) < 0) { \ + tet_printf("open %s failed; %s", _cur_file, \ + strerror(errno)); \ + result = TET_FAIL; \ + goto done; \ + } \ + if (dwarf_init((FD), DW_DLC_READ, NULL, NULL, &(D), &(DE)) != \ + DW_DLV_OK) { \ + tet_printf("dwarf_init failed: %s", dwarf_errmsg((DE)));\ + result = TET_FAIL; \ + goto done; \ + } \ + } while (0) + +#define TS_DWARF_FINISH(D,DE) do { \ + if (dwarf_finish((D), &(DE)) != DW_DLV_OK) { \ + tet_printf("dwarf_finish failed: %s", \ + dwarf_errmsg((DE))); \ + result = TET_FAIL; \ + } \ + } while (0) + +#define TS_DWARF_CU_FOREACH(D,N,DE) \ + while (dwarf_next_cu_header((D), NULL, NULL, NULL, NULL, &(N), \ + &(DE)) == DW_DLV_OK) + +#define TS_DWARF_CU_FOREACH2(D,I,N,DE) \ + while (dwarf_next_cu_header_c((D), (I), NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL, &(N), &(DE)) == DW_DLV_OK) + +#define TS_DWARF_DIE_TRAVERSE(D,CB) \ + _die_traverse((D), (CB)) + +#define TS_DWARF_DIE_TRAVERSE2(D,I,CB) \ + _die_traverse2((D), (I), (CB)) + +#ifndef TCGEN + +#define _TS_CHECK_VAR(X,S) do { \ + struct _drv_vc *_next_vc; \ + int skip = 0; \ + if (strcmp(_cur_vc->var, S)) { \ + tet_printf("VC var(%s) does not match %s, possibly" \ + " caused by the skip of previous VCs, try finding" \ + " the next var with maching name", _cur_vc->var, \ + S); \ + _next_vc = _cur_vc; \ + do { \ + _next_vc = STAILQ_NEXT(_next_vc, next); \ + skip++; \ + if (!strcmp(_next_vc->var, S)) \ + break; \ + } while (_next_vc != NULL); \ + if (_next_vc != NULL) { \ + tet_printf("skipped %d VC(s)\n", skip); \ + _cur_vc = _next_vc; \ + } \ + } \ + } while (0) + +#define TS_CHECK_INT(X) do { \ + assert(_cur_vc != NULL); \ + _TS_CHECK_VAR(X,#X); \ + if (X != _cur_vc->v.i64) { \ + tet_printf("assertion %s(%jd) == %jd failed", \ + _cur_vc->var, (intmax_t) (X), \ + (intmax_t) _cur_vc->v.i64); \ + result = TET_FAIL; \ + } \ + _cur_vc = STAILQ_NEXT(_cur_vc, next); \ + } while (0) + +#define TS_CHECK_UINT(X) do { \ + assert(_cur_vc != NULL); \ + _TS_CHECK_VAR(X,#X); \ + if (X != _cur_vc->v.u64) { \ + tet_printf("assertion %s(%ju) == %ju failed", \ + _cur_vc->var, (uintmax_t) (X), \ + (uintmax_t) _cur_vc->v.u64); \ + result = TET_FAIL; \ + } \ + _cur_vc = STAILQ_NEXT(_cur_vc, next); \ + } while (0) + +#define TS_CHECK_STRING(X) do { \ + assert(_cur_vc != NULL); \ + _TS_CHECK_VAR(X,#X); \ + if (strcmp(X, _cur_vc->v.str)) { \ + tet_printf("assertion %s('%s') == '%s' failed", \ + _cur_vc->var, (X), _cur_vc->v.str); \ + result = TET_FAIL; \ + } \ + _cur_vc = STAILQ_NEXT(_cur_vc, next); \ + } while (0) + +#define TS_CHECK_BLOCK(B,S) do { \ + assert(_cur_vc != NULL); \ + _TS_CHECK_VAR(B,#B); \ + if ((S) != _cur_vc->v.b.len || \ + memcmp((B), _cur_vc->v.b.data, _cur_vc->v.b.len)) { \ + tet_printf("assertion block %s failed\n", _cur_vc->var);\ + result = TET_FAIL; \ + } \ + _cur_vc = STAILQ_NEXT(_cur_vc, next); \ + } while (0) + +#define TS_RESULT(X) tet_result(X) + +#else /* !TCGEN */ + +#define TS_CHECK_INT(X) do { \ + fprintf(_cur_fp, " %jd\n", #X, \ + (intmax_t) (X)); \ + } while (0) + +#define TS_CHECK_UINT(X) do { \ + fprintf(_cur_fp, " %ju\n", #X, \ + (uintmax_t)(X)); \ + } while (0) + +#define TS_CHECK_STRING(X) do { \ + fprintf(_cur_fp, " %s\n", #X, \ + driver_string_encode(X)); \ + } while (0) + +#define TS_CHECK_BLOCK(B,S) do { \ + char *code; \ + int codesize; \ + size_t wsize; \ + fprintf(_cur_fp, " ", #B); \ + driver_base64_encode((char *) (B), (S), &code, &codesize); \ + wsize = fwrite(code, 1, (size_t) codesize, _cur_fp); \ + assert(wsize == (size_t) codesize); \ + fprintf(_cur_fp, "\n"); \ + free(code); \ + } while (0) + +#define TS_RESULT(X) + +#endif /* !TCGEN */ +#endif /* !_DRIVER_H_ */ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt32-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt32-g1.gz new file mode 100755 index 0000000000..8c5f75d9c1 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt32-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g1.gz new file mode 100755 index 0000000000..462c1750ce Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g3.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g3.gz new file mode 100755 index 0000000000..ab04c65596 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dt64-g3.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dto64-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dto64-g1.gz new file mode 100644 index 0000000000..09be38b32c Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/dto64-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec32-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec32-g1.gz new file mode 100755 index 0000000000..140dbd03b7 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec32-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g1.gz new file mode 100755 index 0000000000..553cc9dcf9 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g3.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g3.gz new file mode 100755 index 0000000000..d3dc21715b Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ec64-g3.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ld_symver.o-64-g1.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ld_symver.o-64-g1.gz new file mode 100644 index 0000000000..5fd90579c8 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/common/object/ld_symver.o-64-g1.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/Makefile new file mode 100644 index 0000000000..0ba2416046 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_abbrev.c +TS_DATA= dt32-g1 ec64-g1 dto64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dt32-g1.xml.gz new file mode 100644 index 0000000000..5c1f982810 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dto64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dto64-g1.xml.gz new file mode 100644 index 0000000000..a96259b3c5 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dto64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dwarf_abbrev.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dwarf_abbrev.c new file mode 100644 index 0000000000..130cc46029 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/dwarf_abbrev.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_abbrev.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf address range API. + */ +static void tp_dwarf_abbrev(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_abbrev", tp_dwarf_abbrev}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +static void +tp_dwarf_abbrev(void) +{ + Dwarf_Debug dbg; + Dwarf_Abbrev ab; + Dwarf_Unsigned off, length, attr_count, code; + Dwarf_Signed children_flag, form; + Dwarf_Half tag, attr_num; + Dwarf_Off attr_off; + Dwarf_Error de; + int fd, r_abbrev, r_abbrev_entry, i; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + off = 0; + for (;;) { + tet_printf("check abbrev at offset(%ju):\n", (uintmax_t) off); + r_abbrev = dwarf_get_abbrev(dbg, off, &ab, &length, + &attr_count, &de); + off += length; + TS_CHECK_INT(r_abbrev); + if (r_abbrev != DW_DLV_OK) + break; + TS_CHECK_UINT(length); + TS_CHECK_UINT(attr_count); + if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_abbrev_tag failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(tag); + if (dwarf_get_abbrev_code(ab, &code, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_abbrev_code failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(code); + if (dwarf_get_abbrev_children_flag(ab, &children_flag, &de) != + DW_DLV_OK) { + tet_printf("dwarf_get_abbrev_children_flag failed: " + "%s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(children_flag); + for (i = 0; i < attr_count; i++) { + tet_printf("check attr %d:\n", i); + if (dwarf_get_abbrev_entry(ab, i, &attr_num, &form, + &attr_off, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_abbrev_entry failed: " + "%s\n", dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(attr_num); + TS_CHECK_INT(form); + TS_CHECK_INT(attr_off); + } + /* Invalid index. */ + r_abbrev_entry = dwarf_get_abbrev_entry(ab, i + 10, &attr_num, + &form, &attr_off, &de); + TS_CHECK_INT(r_abbrev_entry); + } + if (r_abbrev == DW_DLV_ERROR) { + tet_printf("dwarf_get_abbrev failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/ec64-g1.xml.gz new file mode 100644 index 0000000000..d061687855 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_abbrev/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/Makefile new file mode 100644 index 0000000000..0b0132a910 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_arange.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt32-g1.xml.gz new file mode 100644 index 0000000000..16a1cef7b8 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt64-g1.xml.gz new file mode 100644 index 0000000000..7adcf11af5 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dwarf_arange.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dwarf_arange.c new file mode 100644 index 0000000000..c03d93cda9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/dwarf_arange.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_arange.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf address range API. + */ +static void tp_dwarf_arange(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_arange", tp_dwarf_arange}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +static void +tp_dwarf_arange(void) +{ + Dwarf_Debug dbg; + Dwarf_Arange *aranges; + Dwarf_Arange arange; + Dwarf_Signed arange_cnt; + Dwarf_Off cu_die_offset, cu_die_offset2, cu_header_offset; + Dwarf_Addr start; + Dwarf_Unsigned length; + Dwarf_Error de; + int fd, i, r_aranges, r_arange; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + r_aranges = dwarf_get_aranges(dbg, &aranges, &arange_cnt, &de); + TS_CHECK_INT(r_aranges); + if (r_aranges == DW_DLV_ERROR) { + tet_printf("dwarf_get_aranges failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (r_aranges == DW_DLV_OK) { + for (i = 0; i < arange_cnt; i++) { + if (dwarf_get_cu_die_offset(aranges[i], &cu_die_offset, + &de) != DW_DLV_OK) { + tet_printf("dwarf_get_cu_die_offset failed:" + " %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_INT(cu_die_offset); + if (dwarf_get_arange_cu_header_offset(aranges[i], + &cu_header_offset, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_arange_cu_header_offset" + "failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_INT(cu_header_offset); + if (dwarf_get_arange_info(aranges[i], &start, &length, + &cu_die_offset2, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_arange_info failed:%s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(start); + TS_CHECK_UINT(length); + TS_CHECK_UINT(cu_die_offset2); + r_arange = dwarf_get_arange(aranges, arange_cnt, start, + &arange, &de); + TS_CHECK_INT(r_arange); + r_arange = dwarf_get_arange(aranges, arange_cnt, + start + 1, &arange, &de); + TS_CHECK_INT(r_arange); + r_arange = dwarf_get_arange(aranges, arange_cnt, + start + length, &arange, &de); + TS_CHECK_INT(r_arange); + r_arange = dwarf_get_arange(aranges, arange_cnt, + start + length + 1, &arange, &de); + TS_CHECK_INT(r_arange); + r_arange = dwarf_get_arange(aranges, arange_cnt, + start + length - 1, &arange, &de); + TS_CHECK_INT(r_arange); + } + } + + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec32-g1.xml.gz new file mode 100644 index 0000000000..ff13e0c1d7 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec64-g1.xml.gz new file mode 100644 index 0000000000..0cca099f4f Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_arange/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/Makefile new file mode 100644 index 0000000000..7e28deef6f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_attr.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 dto64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt32-g1.xml.gz new file mode 100644 index 0000000000..5e999ae993 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt64-g1.xml.gz new file mode 100644 index 0000000000..3cb66127dd Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dto64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dto64-g1.xml.gz new file mode 100644 index 0000000000..b046103890 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dto64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dwarf_attr.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dwarf_attr.c new file mode 100644 index 0000000000..f6566916e9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/dwarf_attr.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_attr.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf_attr, dwarf_hasattr and dwarf_whatattr etc. + */ +static void tp_dwarf_attr(void); +static void tp_dwarf_attr_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_attr", tp_dwarf_attr}, + {"tp_dwarf_attr_sanity", tp_dwarf_attr_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" + +static Dwarf_Half attr_array[] = { DW_AT_ordering, + DW_AT_bit_offset, + DW_AT_bit_size, + DW_AT_byte_size, + DW_AT_high_pc, + DW_AT_low_pc, + DW_AT_language, + DW_AT_name, + DW_AT_data_member_location, + DW_AT_producer, + DW_AT_comp_dir, + DW_AT_location, + DW_AT_decl_file, + DW_AT_decl_line }; +static int attr_array_size = sizeof(attr_array) / sizeof(Dwarf_Half); + +static void +_dwarf_attr(Dwarf_Die die) +{ + Dwarf_Attribute at; + Dwarf_Bool has_attr; + Dwarf_Half attr; + Dwarf_Error de; + const char *attr_name; + int i, r; + + for (i = 0; i < attr_array_size; i++) { + if (dwarf_hasattr(die, attr_array[i], &has_attr, &de) != + DW_DLV_OK) { + tet_printf("dwarf_hasattr failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(has_attr); + + if (has_attr) { + if (dwarf_get_AT_name(attr_array[i], &attr_name) != + DW_DLV_OK) { + tet_printf("dwarf_get_AT_name failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + if (attr_name == NULL) { + tet_infoline("dwarf_get_AT_name returned " + "DW_DLV_OK but didn't return string"); + result = TET_FAIL; + continue; + } + TS_CHECK_STRING(attr_name); + + tet_printf("DIE #%d has attribute '%s'\n", die_cnt, + attr_name); + + r = dwarf_attr(die, attr_array[i], &at, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_attr failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } else if (r == DW_DLV_NO_ENTRY) { + tet_infoline("dwarf_hasattr returned true for " + "attribute '%s', while dwarf_attr returned" + " DW_DLV_NO_ENTRY for the same attr"); + result = TET_FAIL; + continue; + } + if (dwarf_whatattr(at, &attr, &de) != DW_DLV_OK) { + tet_printf("dwarf_whatattr failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + if (attr != attr_array[i]) { + tet_infoline("attr returned by dwarf_whatattr" + " != attr_array[i]"); + result = TET_FAIL; + continue; + } + } + } +} + +static void +tp_dwarf_attr(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_attr); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_attr_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Bool has_attr; + Dwarf_Half attr; + Dwarf_Attribute at; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_hasattr(NULL, DW_AT_name, &has_attr, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_hasattr didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_attr(NULL, DW_AT_name, &at, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_attr didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_whatattr(NULL, &attr, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_whatattr didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec32-g1.xml.gz new file mode 100644 index 0000000000..b8ea5a2247 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec64-g1.xml.gz new file mode 100644 index 0000000000..44d581a375 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attr/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/Makefile new file mode 100644 index 0000000000..a2536520c8 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_attrlist.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz new file mode 100644 index 0000000000..78629601d1 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz new file mode 100644 index 0000000000..8b69a054fa Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c new file mode 100644 index 0000000000..e8f29edc93 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_attrlist.c 3083 2014-09-02 22:08:01Z kaiwang27 $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf_attrlist and dwarf_whatattr etc. + */ +static void tp_dwarf_attrlist(void); +static void tp_dwarf_attrlist_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_attrlist", tp_dwarf_attrlist}, + {"tp_dwarf_attrlist_sanity", tp_dwarf_attrlist_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse2.c" + +static void +_dwarf_attrlist(Dwarf_Die die) +{ + Dwarf_Attribute *attrlist; + Dwarf_Signed attrcount; + Dwarf_Half attr; + Dwarf_Error de; + int i, r; + + r = dwarf_attrlist(die, &attrlist, &attrcount, &de); + TS_CHECK_INT(r); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_attrlist failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } else if (r == DW_DLV_NO_ENTRY) + return; + + TS_CHECK_INT(attrcount); + for (i = 0; i < attrcount; i++) { + if (dwarf_whatattr(attrlist[i], &attr, &de) != DW_DLV_OK) { + tet_printf("dwarf_whatattr failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(attr); + } +} + +static void +tp_dwarf_attrlist(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE2(dbg, 1, _dwarf_attrlist); + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_attrlist); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_attrlist_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Attribute *attrlist; + Dwarf_Signed attrcount; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_attrlist(NULL, &attrlist, &attrcount, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_attrlist didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz new file mode 100644 index 0000000000..f2a53356cc Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz new file mode 100644 index 0000000000..19faaf701f Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz new file mode 100644 index 0000000000..b78ab0abd9 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/Makefile new file mode 100644 index 0000000000..c6520f64fa --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_child.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt32-g1.xml.gz new file mode 100644 index 0000000000..0510e6afc1 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt64-g1.xml.gz new file mode 100644 index 0000000000..202c9cc13c Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dwarf_child.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dwarf_child.c new file mode 100644 index 0000000000..045fdac816 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/dwarf_child.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_child.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +static void tp_dwarf_child_first(void); +static void tp_dwarf_child_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_child_first", tp_dwarf_child_first}, + {"tp_dwarf_child_sanity", tp_dwarf_child_sanity}, + {NULL, NULL}, +}; +#include "driver.c" + +static void +tp_dwarf_child_first(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Die die, die0; + Dwarf_Unsigned cu_next_offset; + int r, fd, result, die_cnt; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + tet_infoline("count the number of children of compilation unit DIE"); + + die_cnt = 0; + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + r = dwarf_siblingof(dbg, NULL, &die, &de); + if (r == DW_DLV_OK) { + r = dwarf_child(die, &die0, &de); + while (r == DW_DLV_OK) { + if (die0 == NULL) { + tet_infoline("dwarf_child or " + "dwarf_siblingof return " + "DW_DLV_OK while argument die0 " + "is not filled in"); + result = TET_FAIL; + goto done; + } + die_cnt++; + die = die0; + r = dwarf_siblingof(dbg, die, &die0, &de); + } + } + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof or dwarf_child failed:" + " %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + } + + TS_CHECK_INT(die_cnt); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_child_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Die die; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_child(NULL, &die, &de) != DW_DLV_ERROR || + dwarf_child(NULL, NULL, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_child didn't return DW_DLV_ERROR when" + " called with NULL arguments"); + result = TET_FAIL; + goto done; + + } + + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_child(NULL, &die, &de) != DW_DLV_ERROR || + dwarf_child(NULL, NULL, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_child didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec32-g1.xml.gz new file mode 100644 index 0000000000..355cacbb61 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec64-g1.xml.gz new file mode 100644 index 0000000000..3ad7586bf2 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_child/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/Makefile new file mode 100644 index 0000000000..eec85f1eac --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_die_convenience.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt32-g1.xml.gz new file mode 100644 index 0000000000..d69ae6e2bd Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt64-g1.xml.gz new file mode 100644 index 0000000000..c115a1fe86 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dwarf_die_convenience.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dwarf_die_convenience.c new file mode 100644 index 0000000000..7471762103 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/dwarf_die_convenience.c @@ -0,0 +1,242 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_die_convenience.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for a few convenience functions used to retrieve certain + * attribute values from DIE. + */ + +static void tp_dwarf_die_convenience(void); +static void tp_dwarf_die_convenience_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_die_convenience", tp_dwarf_die_convenience}, + {"tp_dwarf_die_convenience_sanity", tp_dwarf_die_convenience_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" + +static void +_dwarf_die_convenience(Dwarf_Die die) +{ + Dwarf_Error de; + Dwarf_Addr highpc, lowpc; + Dwarf_Unsigned arrayorder, bitoffset, bitsize, bytesize; + Dwarf_Unsigned srclang; + int r_arrayorder, r_bitoffset, r_bitsize, r_bytesize; + int r_highpc, r_lowpc, r_srclang; + + r_arrayorder = dwarf_arrayorder(die, &arrayorder, &de); + TS_CHECK_INT(r_arrayorder); + if (r_arrayorder == DW_DLV_ERROR) { + tet_printf("dwarf_arrayorder failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_arrayorder == DW_DLV_OK) + TS_CHECK_UINT(arrayorder); + + r_bitoffset = dwarf_bitoffset(die, &bitoffset, &de); + TS_CHECK_INT(r_bitoffset); + if (r_bitoffset == DW_DLV_ERROR) { + tet_printf("dwarf_bitoffset failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_bitoffset == DW_DLV_OK) + TS_CHECK_UINT(bitoffset); + + r_bitsize = dwarf_bitsize(die, &bitsize, &de); + TS_CHECK_INT(r_bitsize); + if (r_bitsize == DW_DLV_ERROR) { + tet_printf("dwarf_bitsize failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_bitsize == DW_DLV_OK) + TS_CHECK_UINT(bitsize); + + r_bytesize = dwarf_bytesize(die, &bytesize, &de); + TS_CHECK_INT(r_bytesize); + if (r_bytesize == DW_DLV_ERROR) { + tet_printf("dwarf_bytesize failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_bytesize == DW_DLV_OK) + TS_CHECK_UINT(bytesize); + + r_highpc = dwarf_highpc(die, &highpc, &de); + TS_CHECK_INT(r_highpc); + if (r_highpc == DW_DLV_ERROR) { + tet_printf("dwarf_highpc failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_highpc == DW_DLV_OK) + TS_CHECK_UINT(highpc); + + r_lowpc = dwarf_lowpc(die, &lowpc, &de); + TS_CHECK_INT(r_lowpc); + if (r_lowpc == DW_DLV_ERROR) { + tet_printf("dwarf_lowpc failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_lowpc == DW_DLV_OK) + TS_CHECK_UINT(lowpc); + + r_srclang = dwarf_srclang(die, &srclang, &de); + TS_CHECK_INT(r_srclang); + if (r_srclang == DW_DLV_ERROR) { + tet_printf("dwarf_srclang failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (r_srclang == DW_DLV_OK) + TS_CHECK_UINT(srclang); +} + +static void +tp_dwarf_die_convenience(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_die_convenience); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_die_convenience_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Die die; + Dwarf_Addr highpc, lowpc; + Dwarf_Unsigned arrayorder, bitoffset, bitsize, bytesize; + Dwarf_Unsigned srclang, cu_next_offset; + int r, fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_siblingof(dbg, NULL, &die, &de) == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_arrayorder(NULL, &arrayorder, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_arrayorder didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_bitoffset(NULL, &bitoffset, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_bitoffset didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_bitsize(NULL, &bitsize, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_bitsize didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_bytesize(NULL, &bytesize, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_bytesize didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_highpc(NULL, &highpc, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_highpc didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + r = dwarf_highpc(die, &highpc, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_highpc failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } else if (r == DW_DLV_OK) + TS_CHECK_UINT(highpc); + + if (dwarf_lowpc(NULL, &lowpc, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_lowpc didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + r = dwarf_lowpc(die, &lowpc, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_lowpc failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } else if (r == DW_DLV_OK) + TS_CHECK_UINT(lowpc); + + if (dwarf_srclang(NULL, &srclang, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_srclang didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + r = dwarf_srclang(die, &srclang, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_srclang failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } else if (r == DW_DLV_OK) + TS_CHECK_UINT(srclang); + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec32-g1.xml.gz new file mode 100644 index 0000000000..b2c04b5c6f Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec64-g1.xml.gz new file mode 100644 index 0000000000..a4d2ea5d60 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_convenience/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/Makefile new file mode 100644 index 0000000000..0f2ac99ea3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_die_offset.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt32-g1.xml.gz new file mode 100644 index 0000000000..cd6b2a3d74 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt64-g1.xml.gz new file mode 100644 index 0000000000..89cc4546ef Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dwarf_die_offset.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dwarf_die_offset.c new file mode 100644 index 0000000000..087b175f27 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/dwarf_die_offset.c @@ -0,0 +1,190 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_die_offset.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for DIE offset query functions: dwarf_die_CU_offset, + * dwarf_die_CU_offset_range, dwarf_dieoffset and + * dwarf_get_cu_die_offset_given_cu_header_offset. + */ + +static void tp_dwarf_die_offset(void); +static void tp_dwarf_die_offset_given_cu(void); +static void tp_dwarf_die_offset_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_die_offset", tp_dwarf_die_offset}, + {"tp_dwarf_die_offset_given_cu", tp_dwarf_die_offset_given_cu}, + {"tp_dwarf_die_offset_sanity", tp_dwarf_die_offset_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" + +static void +_dwarf_die_offset(Dwarf_Die die) +{ + Dwarf_Off rel_off, die_off, cu_off, cu_len; + Dwarf_Error de; + + if (dwarf_die_CU_offset(die, &rel_off, &de) != DW_DLV_OK) { + tet_printf("dwarf_die_CU_offset failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(rel_off); + + if (dwarf_die_CU_offset_range(die, &cu_off, &cu_len, &de) != + DW_DLV_OK) { + tet_printf("dwarf_die_CU_offset_range failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(cu_off); + TS_CHECK_INT(cu_len); + + if (dwarf_dieoffset(die, &die_off, &de) != DW_DLV_OK) { + tet_printf("dwarf_dieoffset failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(die_off); +} + +static void +tp_dwarf_die_offset(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_die_offset); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_die_offset_given_cu(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Off cu_offset, cu_dieoff; + Dwarf_Unsigned cu_next_offset; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + cu_offset = 0; + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_get_cu_die_offset_given_cu_header_offset(dbg, + cu_offset, &cu_dieoff, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_cu_die_offset_given_cu_header" + "_offset failed: %s", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + TS_CHECK_INT(cu_dieoff); + cu_offset = cu_next_offset; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_die_offset_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Off rel_off, die_off, cu_off, cu_len; + Dwarf_Unsigned cu_next_offset; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_siblingof(dbg, NULL, &die, &de) == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_die_CU_offset(NULL, &rel_off, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_die_CU_offset didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_die_CU_offset_range(NULL, &cu_off, &cu_len, &de) != + DW_DLV_ERROR) { + tet_infoline("dwarf_die_CU_offset_range didn't return" + " DW_DLV_ERROR when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_dieoffset(NULL, &die_off, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_dieoffset didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec32-g1.xml.gz new file mode 100644 index 0000000000..335c6c61b9 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec64-g1.xml.gz new file mode 100644 index 0000000000..fd6f9eac7d Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_offset/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/Makefile new file mode 100644 index 0000000000..8644817240 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_die_query.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 dto64-g1 ld_symver.o-64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz new file mode 100644 index 0000000000..1fc0851421 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz new file mode 100644 index 0000000000..6a1a6fd547 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz new file mode 100644 index 0000000000..2cd4ea5a2f Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dwarf_die_query.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dwarf_die_query.c new file mode 100644 index 0000000000..5c99fc2304 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/dwarf_die_query.c @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_die_query.c 3075 2014-06-23 03:08:57Z kaiwang27 $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for DIE query functions: dwarf_tag, dwarf_die_abbrev_code, + * dwarf_diename and dwarf_dieoffset. + */ + +static void tp_dwarf_die_query(void); +static void tp_dwarf_die_query_types(void); +static void tp_dwarf_die_query_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_die_query", tp_dwarf_die_query}, + {"tp_dwarf_die_query_types", tp_dwarf_die_query_types}, + {"tp_dwarf_die_query_sanity", tp_dwarf_die_query_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" +#include "die_traverse2.c" + +static void +_dwarf_die_query(Dwarf_Die die) +{ + Dwarf_Half tag; + Dwarf_Error de; + char *die_name; + int abbrev_code, dwarf_diename_ret; + + /* Check DIE abbreviation code. */ + abbrev_code = dwarf_die_abbrev_code(die); + TS_CHECK_INT(abbrev_code); + + /* Check DIE tag. */ + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(tag); + + /* Check DIE name. */ + dwarf_diename_ret = dwarf_diename(die, &die_name, &de); + TS_CHECK_INT(dwarf_diename_ret); + if (dwarf_diename_ret == DW_DLV_ERROR) { + tet_printf("dwarf_diename failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } else if (dwarf_diename_ret == DW_DLV_OK) + TS_CHECK_STRING(die_name); +} + +static void +tp_dwarf_die_query(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_die_query); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_die_query_types(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_die_query); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_die_query_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Half tag; + Dwarf_Unsigned cu_next_offset; + char *die_name; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_siblingof(dbg, NULL, &die, &de) == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_tag(NULL, &tag, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_tag didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + TS_CHECK_UINT(tag); + + if (dwarf_diename(NULL, &die_name, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_diename didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz new file mode 100644 index 0000000000..0dde710087 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz new file mode 100644 index 0000000000..3c9890e18d Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz new file mode 100644 index 0000000000..c8de24e2c3 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/Makefile new file mode 100644 index 0000000000..5eddcf1936 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_form.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt32-g1.xml.gz new file mode 100644 index 0000000000..afc398d021 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt64-g1.xml.gz new file mode 100644 index 0000000000..257b4687bd Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dwarf_form.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dwarf_form.c new file mode 100644 index 0000000000..5ef73d3f48 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/dwarf_form.c @@ -0,0 +1,284 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_form.c 3084 2014-09-02 22:08:13Z kaiwang27 $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for DWARF attribute query functions. + */ +static void tp_dwarf_form(void); +static void tp_dwarf_form_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_form", tp_dwarf_form}, + {"tp_dwarf_form_sanity", tp_dwarf_form_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse2.c" + +static void +_dwarf_form(Dwarf_Die die) +{ + Dwarf_Attribute *attrlist, at; + Dwarf_Signed attrcount; + Dwarf_Half form, direct_form; + Dwarf_Off offset; + Dwarf_Addr addr; + Dwarf_Bool flag, hasform; + Dwarf_Unsigned uvalue; + Dwarf_Signed svalue; + Dwarf_Block *block; + Dwarf_Sig8 sig8; + Dwarf_Ptr ptr; + Dwarf_Error de; + char *str; + int i, r; + int r_formref, r_global_formref, r_formaddr, r_formflag; + int r_formudata, r_formsdata, r_formblock, r_formstring; + int r_formsig8, r_formexprloc; + + r = dwarf_attrlist(die, &attrlist, &attrcount, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_attrlist failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } else if (r == DW_DLV_NO_ENTRY) + return; + + for (i = 0; i < attrcount; i++) { + at = attrlist[i]; + if (dwarf_whatform(at, &form, &de) != DW_DLV_OK) { + tet_printf("dwarf_whatform failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(form); + if (dwarf_hasform(at, form, &hasform, &de) != DW_DLV_OK) { + tet_printf("dwarf_hasform failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + if (!hasform) { + tet_infoline("dwarf_hasform contradicts with" + " dwarf_whatform"); + result = TET_FAIL; + } + if (dwarf_whatform_direct(at, &direct_form, &de) != DW_DLV_OK) { + tet_printf("dwarf_whatform_direct failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(direct_form); + + r_formref = dwarf_formref(at, &offset, &de); + TS_CHECK_INT(r_formref); + if (r_formref == DW_DLV_OK) + TS_CHECK_INT(offset); + + r_global_formref = dwarf_global_formref(at, &offset, &de); + TS_CHECK_INT(r_global_formref); + if (r_global_formref == DW_DLV_OK) + TS_CHECK_INT(offset); + + r_formaddr = dwarf_formaddr(at, &addr, &de); + TS_CHECK_INT(r_formaddr); + if (r_formaddr == DW_DLV_OK) + TS_CHECK_UINT(addr); + + r_formflag = dwarf_formflag(at, &flag, &de); + TS_CHECK_INT(r_formflag); + if (r_formflag == DW_DLV_OK) + TS_CHECK_INT(flag); + + r_formudata = dwarf_formudata(at, &uvalue, &de); + TS_CHECK_INT(r_formudata); + if (r_formudata == DW_DLV_OK) + TS_CHECK_UINT(uvalue); + + r_formsdata = dwarf_formsdata(at, &svalue, &de); + TS_CHECK_INT(r_formsdata); + if (r_formsdata == DW_DLV_OK) + TS_CHECK_INT(svalue); + + r_formblock = dwarf_formblock(at, &block, &de); + TS_CHECK_INT(r_formblock); + if (r_formblock == DW_DLV_OK) + TS_CHECK_BLOCK(block->bl_data, block->bl_len); + + r_formstring = dwarf_formstring(at, &str, &de); + TS_CHECK_INT(r_formstring); + if (r_formstring == DW_DLV_OK) + TS_CHECK_STRING(str); + + r_formsig8 = dwarf_formsig8(at, &sig8, &de); + TS_CHECK_INT(r_formsig8); + if (r_formsig8 == DW_DLV_OK) + TS_CHECK_BLOCK(sig8.signature, 8); + + r_formexprloc = dwarf_formexprloc(at, &uvalue, &ptr, &de); + TS_CHECK_INT(r_formexprloc); + if (r_formexprloc == DW_DLV_OK) + TS_CHECK_BLOCK(ptr, uvalue); + } +} + +static void +tp_dwarf_form(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE2(dbg, 1, _dwarf_form); + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_form); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_form_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Half form, direct_form; + Dwarf_Off offset; + Dwarf_Addr addr; + Dwarf_Bool flag, hasform; + Dwarf_Unsigned uvalue; + Dwarf_Signed svalue; + Dwarf_Block *block; + char *str; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_whatform(NULL, &form, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_whatform didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_whatform_direct(NULL, &direct_form, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_whatform_direct didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_hasform(NULL, DW_FORM_indirect, &hasform, &de) != + DW_DLV_ERROR) { + tet_infoline("dwarf_hasform didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formref(NULL, &offset, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formref didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_global_formref(NULL, &offset, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_global_formref didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formaddr(NULL, &addr, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formaddr didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formflag(NULL, &flag, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formflag didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formudata(NULL, &uvalue, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formudata didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formsdata(NULL, &svalue, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formsdata didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formblock(NULL, &block, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formblock didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_formstring(NULL, &str, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_formstring didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec32-g1.xml.gz new file mode 100644 index 0000000000..bf8b65ed07 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec64-g1.xml.gz new file mode 100644 index 0000000000..1c964962fc Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz new file mode 100644 index 0000000000..22c60db868 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/Makefile new file mode 100644 index 0000000000..1f49eb7c1b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_frame.c +TS_DATA= dt64-g1 ec32-g1 dto64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dt64-g1.xml.gz new file mode 100644 index 0000000000..b053c9d0de Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dto64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dto64-g1.xml.gz new file mode 100644 index 0000000000..c6512db46f Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dto64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dwarf_frame.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dwarf_frame.c new file mode 100644 index 0000000000..3c5ed4d99c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/dwarf_frame.c @@ -0,0 +1,498 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_frame.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf line informatio API. + */ +static void tp_dwarf_frame2(void); +static void tp_dwarf_frame3(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_frame2",tp_dwarf_frame2}, + {"tp_dwarf_frame3",tp_dwarf_frame3}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +#define _MAX_REG_NUM 10 + +static void +_frame2_test(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Addr pc, + Dwarf_Unsigned func_len, Dwarf_Unsigned caf) +{ + Dwarf_Signed offset_relevant, register_num, offset; + Dwarf_Addr pc_end, row_pc; + Dwarf_Regtable reg_table; + Dwarf_Error de; + int i, cnt; + + (void) dwarf_set_frame_cfa_value(dbg, DW_FRAME_CFA_COL); + + /* Sanity check for invalid table_column. */ + if (dwarf_get_fde_info_for_reg(fde, 9999, 0, &offset_relevant, + ®ister_num, &offset, &row_pc, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_get_fde_info_for_reg didn't return" + " DW_DLV_ERROR when called with invalid table_column" + " value"); + result = TET_FAIL; + return; + } + + cnt = 0; + pc_end = pc + func_len; + while (pc < pc_end && cnt < 16) { + tet_printf("query CFA register pc %#jx\n", (uintmax_t) pc); + /* + * XXX If application want to use DW_FRAME_CFA_COL for CFA, + * it should call dwarf_set_frame_cfa_value() to set that + * explicitly. So here DW_FRAME_CFA_COL might not be refering + * to the CFA at all, depends on whether CFA(0) is set by + * dwarf_set_frame_cfa_value. + */ + if (dwarf_get_fde_info_for_reg(fde, DW_FRAME_CFA_COL, + pc, &offset_relevant, ®ister_num, &offset, + &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_reg(cfa) failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + return; + } + TS_CHECK_INT(offset_relevant); + TS_CHECK_INT(offset); + TS_CHECK_INT(register_num); + TS_CHECK_UINT(row_pc); + for (i = 1; i < _MAX_REG_NUM; i++) { + tet_printf("query register %d\n", i); + if (dwarf_get_fde_info_for_reg(fde, i, pc, + &offset_relevant, ®ister_num, &offset, + &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_reg(%d)" + " failed: %s", i, dwarf_errmsg(de)); + result = TET_FAIL; + goto next; + } + TS_CHECK_INT(offset_relevant); + TS_CHECK_INT(offset); + TS_CHECK_INT(register_num); + TS_CHECK_UINT(row_pc); + } + tet_infoline("query all register"); + if (dwarf_get_fde_info_for_all_regs(fde, pc, ®_table, + &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_all_regs failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + goto next; + } + TS_CHECK_UINT(row_pc); + for (i = 0; i < _MAX_REG_NUM; i++) { + tet_printf("check reg_table[%d]\n", i); + TS_CHECK_UINT(reg_table.rules[i].dw_offset_relevant); + TS_CHECK_UINT(reg_table.rules[i].dw_regnum); + TS_CHECK_UINT(reg_table.rules[i].dw_offset); + } + + next: + pc += caf; + cnt++; + } +} + +static void +_frame3_test(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Addr pc, + Dwarf_Unsigned func_len, Dwarf_Unsigned caf) +{ + Dwarf_Signed offset_relevant, register_num, offset_or_block_len; + Dwarf_Addr pc_end, row_pc; + Dwarf_Ptr block_ptr; + Dwarf_Regtable3 reg_table3; + Dwarf_Small value_type; + Dwarf_Error de; + int i, cnt; + + /* Initialise regster table (DWARF3). */ + reg_table3.rt3_reg_table_size = DW_REG_TABLE_SIZE; + reg_table3.rt3_rules = calloc(reg_table3.rt3_reg_table_size, + sizeof(Dwarf_Regtable_Entry3)); + if (reg_table3.rt3_rules == NULL) { + tet_infoline("calloc failed when initialising reg_table3"); + result = TET_FAIL; + return; + } + + /* Sanity check for invalid table_column. */ + if (dwarf_get_fde_info_for_reg3(fde, 9999, 0, &value_type, + &offset_relevant, ®ister_num, &offset_or_block_len, &block_ptr, + &row_pc, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_get_fde_info_for_reg3 didn't return" + " DW_DLV_ERROR when called with invalid table_column" + " value"); + result = TET_FAIL; + return; + } + + cnt = 0; + pc_end = pc + func_len; + while (pc < pc_end && cnt < 16) { + tet_printf("query CFA(3) register pc %#jx\n", (uintmax_t) pc); + if (dwarf_get_fde_info_for_cfa_reg3(fde, pc, &value_type, + &offset_relevant, ®ister_num, &offset_or_block_len, + &block_ptr, &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_reg3(cfa) failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + return; + } + TS_CHECK_INT(value_type); + TS_CHECK_INT(offset_relevant); + TS_CHECK_INT(offset_or_block_len); + TS_CHECK_INT(register_num); + TS_CHECK_UINT(row_pc); + if (value_type == DW_EXPR_EXPRESSION || + value_type == DW_EXPR_VAL_EXPRESSION) + TS_CHECK_BLOCK(block_ptr, offset_or_block_len); + for (i = 1; i < _MAX_REG_NUM; i++) { + tet_printf("query register(3) %d\n", i); + if (dwarf_get_fde_info_for_reg3(fde, i, pc, &value_type, + &offset_relevant, ®ister_num, + &offset_or_block_len, &block_ptr, + &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_reg3(%d)" + " failed: %s", i, dwarf_errmsg(de)); + result = TET_FAIL; + goto next; + } + TS_CHECK_INT(value_type); + TS_CHECK_INT(offset_relevant); + TS_CHECK_INT(offset_or_block_len); + TS_CHECK_INT(register_num); + TS_CHECK_UINT(row_pc); + if (value_type == DW_EXPR_EXPRESSION || + value_type == DW_EXPR_VAL_EXPRESSION) + TS_CHECK_BLOCK(block_ptr, offset_or_block_len); + } + tet_infoline("query all register(3)"); + if (dwarf_get_fde_info_for_all_regs3(fde, pc, ®_table3, + &row_pc, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_info_for_all_regs failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + goto next; + } + TS_CHECK_UINT(row_pc); + +#define CFA3 reg_table3.rt3_cfa_rule +#define RT3 reg_table3.rt3_rules + TS_CHECK_UINT(CFA3.dw_offset_relevant); + TS_CHECK_UINT(CFA3.dw_value_type); + TS_CHECK_UINT(CFA3.dw_regnum); + TS_CHECK_UINT(CFA3.dw_offset_or_block_len); + if (CFA3.dw_value_type == DW_EXPR_EXPRESSION || + CFA3.dw_value_type == DW_EXPR_VAL_EXPRESSION) + TS_CHECK_BLOCK(CFA3.dw_block_ptr, + CFA3.dw_offset_or_block_len); + for (i = 0; i < _MAX_REG_NUM; i++) { + tet_printf("check reg_table3[%d]\n", i); + TS_CHECK_UINT(RT3[i].dw_offset_relevant); + TS_CHECK_UINT(RT3[i].dw_value_type); + TS_CHECK_UINT(RT3[i].dw_regnum); + TS_CHECK_UINT(RT3[i].dw_offset_or_block_len); + if (RT3[i].dw_value_type == DW_EXPR_EXPRESSION || + RT3[i].dw_value_type == DW_EXPR_VAL_EXPRESSION) + TS_CHECK_BLOCK(RT3[i].dw_block_ptr, + RT3[i].dw_offset_or_block_len); + } +#undef CFA3 +#undef RT3 + + next: + pc += caf; + cnt++; + } +} + +static void +_dwarf_cie_fde_test(Dwarf_Debug dbg, int eh, void (*_frame_test)(Dwarf_Debug, + Dwarf_Fde, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned)) +{ + Dwarf_Cie *cielist, cie; + Dwarf_Fde *fdelist, fde; + Dwarf_Frame_Op *oplist; + Dwarf_Signed ciecnt, fdecnt; + Dwarf_Addr low_pc, high_pc; + Dwarf_Unsigned func_len, fde_byte_len, fde_inst_len, bytes_in_cie; + Dwarf_Unsigned cie_caf, cie_daf, cie_inst_len; + Dwarf_Signed cie_index, opcnt; + Dwarf_Off cie_offset, fde_offset; + Dwarf_Ptr fde_bytes, fde_inst, cie_initinst; + Dwarf_Half cie_ra; + Dwarf_Small cie_version; + Dwarf_Error de; + const char *cfa_str; + char *cie_augmenter; + int i, j, r_fde_at_pc; + + if (eh) { + if (dwarf_get_fde_list_eh(dbg, &cielist, &ciecnt, &fdelist, + &fdecnt, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_list_eh failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + } else { + if (dwarf_get_fde_list(dbg, &cielist, &ciecnt, &fdelist, + &fdecnt, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_list failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + } + TS_CHECK_INT(ciecnt); + TS_CHECK_INT(fdecnt); + + /* + * Test dwarf_get_fde_at_pc using hard-coded PC values. + */ + + tet_infoline("attempt to get fde at 0x08082a30"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08082a30, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + tet_infoline("attempt to get fde at 0x08083087"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08083087, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + tet_infoline("attempt to get fde at 0x080481f0"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x080481f0, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + tet_infoline("attempt to get fde at 0x08048564"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08048564, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + tet_infoline("attempt to get fde at 0x00401280"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x00401280, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + tet_infoline("attempt to get fde at 0x004012b1"); + r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x004012b1, &fde, &low_pc, + &high_pc, &de); + TS_CHECK_INT(r_fde_at_pc); + if (r_fde_at_pc == DW_DLV_OK) { + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(high_pc); + } + + /* + * Test each FDE contained in the FDE list. + */ + + for (i = 0; i < fdecnt; i++) { + if (dwarf_get_fde_n(fdelist, i, &fde, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_n(%d) failed: %s\n", i, + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_bytes, + &fde_byte_len, &cie_offset, &cie_index, &fde_offset, + &de) == DW_DLV_ERROR) { + tet_printf("dwarf_get_fde_range(%d) failed: %s\n", i, + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(low_pc); + TS_CHECK_UINT(func_len); + TS_CHECK_UINT(fde_byte_len); + if (fde_byte_len > 0) + TS_CHECK_BLOCK(fde_bytes, fde_byte_len); + TS_CHECK_INT(cie_offset); + TS_CHECK_INT(cie_index); + TS_CHECK_INT(fde_offset); + if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_cie_of_fde(%d) failed: %s\n", i, + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + if (dwarf_get_cie_index(cie, &cie_index, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_cie_index(%d) failed: %s\n", i, + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_INT(cie_index); + if (dwarf_get_cie_info(cie, &bytes_in_cie, &cie_version, + &cie_augmenter, &cie_caf, &cie_daf, &cie_ra, &cie_initinst, + &cie_inst_len, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_cie_info(%d) failed: %s\n", i, + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(bytes_in_cie); + TS_CHECK_UINT(cie_version); + TS_CHECK_STRING(cie_augmenter); + TS_CHECK_UINT(cie_caf); + TS_CHECK_UINT(cie_daf); + TS_CHECK_UINT(cie_ra); + TS_CHECK_UINT(cie_inst_len); + if (cie_inst_len > 0) + TS_CHECK_BLOCK(cie_initinst, cie_inst_len); + if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_inst_len, + &de) != DW_DLV_OK) { + tet_printf("dwarf_get_fde_instr_bytes(%d) failed: %s\n", + i, dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(fde_inst_len); + if (fde_inst_len > 0) { + TS_CHECK_BLOCK(fde_inst, fde_inst_len); + if (dwarf_expand_frame_instructions(cie, fde_inst, + fde_inst_len, &oplist, &opcnt, &de) != DW_DLV_OK) { + tet_printf("dwarf_expand_frame_instructions(%d)" + " failed: %s\n", i, dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_INT(opcnt); + for (j = 0; j < opcnt; j++) { + TS_CHECK_UINT(oplist[j].fp_base_op); + if (oplist[j].fp_base_op != 0) { + if (dwarf_get_CFA_name( + oplist[j].fp_base_op << 6, + &cfa_str) != DW_DLV_OK) { + tet_printf("dwarf_get_CFA_name" + " failed\n"); + continue; + } + TS_CHECK_STRING(cfa_str); + } + TS_CHECK_UINT(oplist[j].fp_extended_op); + if (oplist[j].fp_extended_op != 0) { + if (dwarf_get_CFA_name( + oplist[j].fp_extended_op, + &cfa_str) != DW_DLV_OK) { + tet_printf("dwarf_get_CFA_name" + " failed\n"); + continue; + } + TS_CHECK_STRING(cfa_str); + } + TS_CHECK_UINT(oplist[j].fp_register); + TS_CHECK_INT(oplist[j].fp_offset); + TS_CHECK_INT(oplist[j].fp_instr_offset); + } + } + _frame_test(dbg, fde, low_pc, func_len, cie_caf); + } + +done: + return; +} + +static void +tp_dwarf_frame2(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + _dwarf_cie_fde_test(dbg, 0, _frame2_test); + _dwarf_cie_fde_test(dbg, 1, _frame2_test); + + if (result == TET_UNRESOLVED) + result = TET_PASS; +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_frame3(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + _dwarf_cie_fde_test(dbg, 0, _frame3_test); + _dwarf_cie_fde_test(dbg, 1, _frame3_test); + + if (result == TET_UNRESOLVED) + result = TET_PASS; +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/ec32-g1.xml.gz new file mode 100644 index 0000000000..a63c1e222e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_frame/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/Makefile new file mode 100644 index 0000000000..450b073453 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_get_address_size.c +TS_DATA= dt32-g1 dt64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt32-g1.xml.gz new file mode 100644 index 0000000000..4317b6bdad Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt64-g1.xml.gz new file mode 100644 index 0000000000..b16cb3614e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dwarf_get_address_size.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dwarf_get_address_size.c new file mode 100644 index 0000000000..be9a10f0bb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_get_address_size/dwarf_get_address_size.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_get_address_size.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +static void tp_dwarf_get_address_size(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_get_address_size", tp_dwarf_get_address_size}, + {NULL, NULL}, +}; +#include "driver.c" + +static void +tp_dwarf_get_address_size(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Half addr_size; + int fd, result; + + dbg = NULL; + result = TET_UNRESOLVED; + + if (dwarf_get_address_size(NULL, &addr_size, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_get_adderss_size NULL 'dbg' test failed"); + result = TET_FAIL; + goto done; + } + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_get_address_size(dbg, NULL, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_get_adderss_size NULL 'addr_size' test " + "failed"); + result = TET_FAIL; + goto done; + } + + if (dwarf_get_address_size(dbg, &addr_size, &de) != DW_DLV_OK) { + tet_printf("dwarf_get_address_size failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + + TS_CHECK_UINT(addr_size); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/Makefile new file mode 100644 index 0000000000..b9acb0b158 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_init.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt32-g1.xml.gz new file mode 100644 index 0000000000..2ae60f2388 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt64-g1.xml.gz new file mode 100644 index 0000000000..ee7365f486 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dwarf_init.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dwarf_init.c new file mode 100644 index 0000000000..73fa7cca1b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/dwarf_init.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_init.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +static void tp_dwarf_init(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_init", tp_dwarf_init}, + {NULL, NULL}, +}; +#include "driver.c" + +static void +tp_dwarf_init(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd, result; + + result = TET_UNRESOLVED; + + assert(_cur_file != NULL); + dbg = NULL; + if ((fd = open(_cur_file, O_RDONLY)) < 0) { + tet_printf("open %s failed: %s", _cur_file, strerror(errno)); + result = TET_FAIL; + goto done; + } + + if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de) != DW_DLV_OK) { + tet_printf("dwarf_init failed: %s", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + + if (dwarf_init(-1, DW_DLC_READ, NULL, NULL, &dbg, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_init didn't return DW_DLV_ERROR when" + " called with fd(-1)"); + result = TET_FAIL; + goto done; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec32-g1.xml.gz new file mode 100644 index 0000000000..32a51f94b9 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec64-g1.xml.gz new file mode 100644 index 0000000000..caceadb417 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_init/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/Makefile new file mode 100644 index 0000000000..41e76589d6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_lineno.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 dto64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt32-g1.xml.gz new file mode 100644 index 0000000000..e71efb4cd2 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt64-g1.xml.gz new file mode 100644 index 0000000000..7dbb07d1de Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dto64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dto64-g1.xml.gz new file mode 100644 index 0000000000..24fe7b01b6 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dto64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dwarf_lineno.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dwarf_lineno.c new file mode 100644 index 0000000000..322031e808 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/dwarf_lineno.c @@ -0,0 +1,278 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_lineno.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf line informatio API. + */ +static void tp_dwarf_lineno(void); +static void tp_dwarf_srcfiles(void); +static void tp_dwarf_lineno_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_lineno", tp_dwarf_lineno}, + {"tp_dwarf_srcfiles", tp_dwarf_srcfiles}, + {"tp_dwarf_lineno_sanity", tp_dwarf_lineno_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" + +static void +_dwarf_lineno(Dwarf_Die die) +{ + Dwarf_Line *linebuf, ln; + Dwarf_Signed linecount, lineoff; + Dwarf_Unsigned lineno, srcfileno; + Dwarf_Addr lineaddr; + Dwarf_Half tag; + Dwarf_Error de; + Dwarf_Bool linebeginstatement, lineendsequence, lineblock; + char *linesrc; + int r_srclines; + int i; + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } + + r_srclines = dwarf_srclines(die, &linebuf, &linecount, &de); + TS_CHECK_INT(r_srclines); + + if (r_srclines == DW_DLV_ERROR) { + tet_printf("dwarf_srclines should not fail but still failed:", + " %s", dwarf_errmsg(de)); + return; + } + + if (r_srclines != DW_DLV_OK) + return; + + for (i = 0; i < linecount; i++) { + + ln = linebuf[i]; + + if (dwarf_linebeginstatement(ln, &linebeginstatement, + &de) != DW_DLV_OK) { + tet_printf("dwarf_linebeginstatement failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(linebeginstatement); + + if (dwarf_linebeginstatement(ln, &linebeginstatement, + &de) != DW_DLV_OK) { + tet_printf("dwarf_linebeginstatement failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(linebeginstatement); + + if (dwarf_lineendsequence(ln, &lineendsequence, + &de) != DW_DLV_OK) { + tet_printf("dwarf_lineendsequence failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(lineendsequence); + + if (dwarf_lineno(ln, &lineno, &de) != DW_DLV_OK) { + tet_printf("dwarf_lineno failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(lineno); + + if (dwarf_line_srcfileno(ln, &srcfileno, &de) != DW_DLV_OK) { + tet_printf("dwarf_line_srcfileno failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(srcfileno); + + if (dwarf_lineaddr(ln, &lineaddr, &de) != DW_DLV_OK) { + tet_printf("dwarf_lineaddr failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_UINT(lineaddr); + + if (dwarf_lineoff(ln, &lineoff, &de) != DW_DLV_OK) { + tet_printf("dwarf_lineoff failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(lineoff); + + if (dwarf_linesrc(ln, &linesrc, &de) != DW_DLV_OK) { + tet_printf("dwarf_linesrc failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_STRING(linesrc); + + if (dwarf_lineblock(ln, &lineblock, &de) != DW_DLV_OK) { + tet_printf("dwarf_lineblock failed: %s", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(lineblock); + } +} + +static void +tp_dwarf_lineno(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_lineno); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +_dwarf_srcfiles(Dwarf_Die die) +{ + Dwarf_Half tag; + Dwarf_Error de; + Dwarf_Signed srccount; + char **srcfiles; + int r_srcfiles, i; + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } + + r_srcfiles = dwarf_srcfiles(die, &srcfiles, &srccount, &de); + TS_CHECK_INT(r_srcfiles); + + if (r_srcfiles == DW_DLV_ERROR) { + tet_printf("dwarf_srcfiles should not fail but still failed:", + " %s", dwarf_errmsg(de)); + return; + } + + if (r_srcfiles != DW_DLV_OK) + return; + + if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK) { + tet_printf("dwarf_srcfiles failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } + + TS_CHECK_INT(srccount); + for (i = 0; i < srccount; i++) { + if (srcfiles[i] == NULL) { + tet_printf("dwarf_srcfiles returned NULL pointer" + " srcfiles[%d]\n", i); + result = TET_FAIL; + } else + TS_CHECK_STRING(srcfiles[i]); + } +} + +static void +tp_dwarf_srcfiles(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_srcfiles); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_lineno_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Line *linebuf; + Dwarf_Signed linecount; + Dwarf_Signed srccount; + char **srcfiles; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_srclines(NULL, &linebuf, &linecount, &de) != + DW_DLV_ERROR) { + tet_infoline("dwarf_srclines didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + } + + if (dwarf_srcfiles(NULL, &srcfiles, &srccount, &de) != + DW_DLV_ERROR) { + tet_infoline("dwarf_srcfiles didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec32-g1.xml.gz new file mode 100644 index 0000000000..a8ed45fce4 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec64-g1.xml.gz new file mode 100644 index 0000000000..94a9822388 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_lineno/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/Makefile new file mode 100644 index 0000000000..8429a451cf --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_loclist.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt32-g1.xml.gz new file mode 100644 index 0000000000..008fdd98b8 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt64-g1.xml.gz new file mode 100644 index 0000000000..b7beeaf6fb Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dwarf_loclist.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dwarf_loclist.c new file mode 100644 index 0000000000..8ea7689483 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/dwarf_loclist.c @@ -0,0 +1,234 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_loclist.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for DWARF loclist query functions. + */ +static void tp_dwarf_loclist(void); +static void tp_dwarf_loclist_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_loclist", tp_dwarf_loclist}, + {"tp_dwarf_loclist_sanity", tp_dwarf_loclist_sanity}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" +#include "die_traverse.c" + +static void +_dwarf_loclist(Dwarf_Die die) +{ + Dwarf_Attribute *attrlist, at; + Dwarf_Signed attrcount; + Dwarf_Half attr; + Dwarf_Locdesc **llbuf, *llbuf0; + Dwarf_Loc *loc; + Dwarf_Signed listlen; + Dwarf_Error de; + const char *atname; + int r, i, j, k; + int r_loclist, r_loclist_n; + + r = dwarf_attrlist(die, &attrlist, &attrcount, &de); + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_attrlist failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + return; + } else if (r == DW_DLV_NO_ENTRY) + return; + + for (i = 0; i < attrcount; i++) { + at = attrlist[i]; + if (dwarf_whatattr(at, &attr, &de) != DW_DLV_OK) { + tet_printf("dwarf_whatattr failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + continue; + } + TS_CHECK_UINT(attr); + switch (attr) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + break; + default: + continue; + } + + atname = NULL; + if (dwarf_get_AT_name(attr, &atname) != DW_DLV_OK) { + tet_printf("dwarf_get_AT_name failed\n"); + result = TET_FAIL; + } + tet_printf("process attribute %s\n", atname); + + r_loclist_n = dwarf_loclist_n(at, &llbuf, &listlen, &de); + TS_CHECK_INT(r_loclist_n); + if (r_loclist_n == DW_DLV_OK){ +#ifndef TCGEN + /* + * XXX SGI libdwarf do not return the End-List-Indicator + * to the application (when loclist is in .debug_loc .i.e, + * listen > 1), while our libdwarf does. Workaround this + * by decreasing listlen by 1 when TCGEN is not defined, + * so this test case can work. + */ + if (listlen > 1) + listlen--; +#endif + TS_CHECK_INT(listlen); + for (j = 0; j < listlen; j++) { + tet_printf("process loclist[%d]\n", j); + TS_CHECK_UINT(llbuf[j]->ld_lopc); + TS_CHECK_UINT(llbuf[j]->ld_hipc); + TS_CHECK_UINT(llbuf[j]->ld_cents); + for (k = 0; k < llbuf[j]->ld_cents; k++) { + tet_printf("process ld_s[%d]\n", k); + loc = &llbuf[j]->ld_s[k]; + TS_CHECK_UINT(loc->lr_atom); + TS_CHECK_UINT(loc->lr_number); + TS_CHECK_UINT(loc->lr_number2); +#ifndef TCGEN + /* + * XXX SGI libdwarf defined that + * lr_offset is lr_atom's offset + 1. + */ + loc->lr_offset++; +#endif + TS_CHECK_UINT(loc->lr_offset); +#ifndef TCGEN + loc->lr_offset--; +#endif + } + } + } + + r_loclist = dwarf_loclist(at, &llbuf0, &listlen, &de); + TS_CHECK_INT(r_loclist); + if (r_loclist == DW_DLV_OK) { + if (listlen != 1) { + tet_printf("listlen(%d) returned by" + " dwarf_loclist must be 1", listlen); + result = TET_FAIL; + } + tet_printf("process the only loclist\n"); + TS_CHECK_UINT(llbuf0->ld_lopc); + TS_CHECK_UINT(llbuf0->ld_hipc); + TS_CHECK_UINT(llbuf0->ld_cents); + for (k = 0; k < llbuf0->ld_cents; k++) { + tet_printf("process ld_s[%d]\n", k); + loc = &llbuf0->ld_s[k]; + TS_CHECK_UINT(loc->lr_atom); + TS_CHECK_UINT(loc->lr_number); + TS_CHECK_UINT(loc->lr_number2); +#ifndef TCGEN + /* + * XXX SGI libdwarf defined that + * lr_offset is lr_atom's offset + 1. + */ + loc->lr_offset++; +#endif + TS_CHECK_UINT(loc->lr_offset); +#ifndef TCGEN + loc->lr_offset--; +#endif + } + } + } +} + +static void +tp_dwarf_loclist(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_loclist); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_loclist_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Locdesc **llbuf, *llbuf0; + Dwarf_Signed listlen; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_loclist_n(NULL, &llbuf, &listlen, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_loclist_n didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (dwarf_loclist(NULL, &llbuf0, &listlen, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_loclist didn't return DW_DLV_ERROR" + " when called with NULL arguments"); + result = TET_FAIL; + goto done; + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec32-g1.xml.gz new file mode 100644 index 0000000000..2849eb8b0b Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec64-g1.xml.gz new file mode 100644 index 0000000000..b6ff7dbb5d Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_loclist/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/Makefile new file mode 100644 index 0000000000..ed6d2698cc --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_macinfo.c +TS_DATA= dt64-g1 dt64-g3 ec64-g3 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g1.xml.gz new file mode 100644 index 0000000000..3e1a467368 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g3.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g3.xml.gz new file mode 100644 index 0000000000..28a458355e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dt64-g3.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dwarf_macinfo.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dwarf_macinfo.c new file mode 100644 index 0000000000..bf4201f206 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/dwarf_macinfo.c @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_macinfo.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf macro information API. + */ +static void tp_dwarf_macinfo(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_macinfo", tp_dwarf_macinfo}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +static void +_check_details(Dwarf_Macro_Details *details, Dwarf_Signed entry_count) +{ + char *macro_value; + int i; + + for (i = 0; i < entry_count; i++) { + tet_printf("check macro details entry %d:\n", i); + TS_CHECK_INT(details[i].dmd_offset); + TS_CHECK_UINT(details[i].dmd_type); + TS_CHECK_INT(details[i].dmd_lineno); + TS_CHECK_INT(details[i].dmd_fileindex); + if (details[i].dmd_macro != NULL) { + TS_CHECK_STRING(details[i].dmd_macro); + macro_value = dwarf_find_macro_value_start(details[i].dmd_macro); + if (macro_value != NULL) + TS_CHECK_STRING(macro_value); + } + } +} + +static void +_get_macinfo(Dwarf_Debug dbg, Dwarf_Off macro_offset, Dwarf_Unsigned max_count) +{ + Dwarf_Macro_Details *details; + Dwarf_Signed entry_count; + Dwarf_Error de; + int r_details; + + r_details = dwarf_get_macro_details(dbg, macro_offset, max_count, + &entry_count, &details, &de); + TS_CHECK_INT(r_details); + if (r_details != DW_DLV_OK) { + if (r_details == DW_DLV_ERROR) { + tet_printf("dwarf_get_macro_details failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + return; + } + TS_CHECK_UINT(entry_count); + _check_details(details, entry_count); +} + +static void +_get_all_macinfo(Dwarf_Debug dbg) +{ + Dwarf_Macro_Details *details; + Dwarf_Signed entry_count; + Dwarf_Off off; + Dwarf_Error de; + int r_details; + + off = 0; + while ((r_details = dwarf_get_macro_details(dbg, off, 0, &entry_count, + &details, &de)) == DW_DLV_OK) { + TS_CHECK_UINT(entry_count); + _check_details(details, entry_count); + off = details[entry_count - 1].dmd_offset + 1; + } + TS_CHECK_INT(r_details); +} + +static void +tp_dwarf_macinfo(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + TS_DWARF_INIT(dbg, fd, de); + + /* Get all Dwarf_Macro_Details entries in the first CU. */ + _get_macinfo(dbg, 0, 0); + + /* Get first 100 entries. */ + _get_macinfo(dbg, 0, 100); + + /* Get all entries in all CUs. */ + _get_all_macinfo(dbg); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/ec64-g3.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/ec64-g3.xml.gz new file mode 100644 index 0000000000..a174e75b7a Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_macinfo/ec64-g3.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/Makefile new file mode 100644 index 0000000000..8d6e161294 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_next_cu_header.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz new file mode 100644 index 0000000000..7ba737cc6e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz new file mode 100644 index 0000000000..93a44424c7 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c new file mode 100644 index 0000000000..b5a580d497 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c @@ -0,0 +1,209 @@ +/*- + * Copyright (c) 2010,2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_next_cu_header.c 3073 2014-06-23 03:08:49Z kaiwang27 $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +static void tp_dwarf_next_cu_header(void); +static void tp_dwarf_next_cu_header_b(void); +static void tp_dwarf_next_cu_header_c(void); +static void tp_dwarf_next_cu_header_loop(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_next_cu_header", tp_dwarf_next_cu_header}, + {"tp_dwarf_next_cu_header_b", tp_dwarf_next_cu_header_b}, + {"tp_dwarf_next_cu_header_c", tp_dwarf_next_cu_header_c}, + {"tp_dwarf_next_cu_header_loop", tp_dwarf_next_cu_header_loop}, + {NULL, NULL}, +}; +#include "driver.c" + +static void +tp_dwarf_next_cu_header(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Unsigned cu_header_length; + Dwarf_Half cu_version; + Dwarf_Off cu_abbrev_offset; + Dwarf_Half cu_pointer_size; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + while (dwarf_next_cu_header(dbg, &cu_header_length, &cu_version, + &cu_abbrev_offset, &cu_pointer_size, &cu_next_offset, &de) == + DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_next_offset); + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_next_cu_header_b(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Unsigned cu_header_length; + Dwarf_Half cu_version; + Dwarf_Off cu_abbrev_offset; + Dwarf_Half cu_pointer_size; + Dwarf_Half cu_offset_size; + Dwarf_Half cu_extension_size; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + while (dwarf_next_cu_header_b(dbg, &cu_header_length, &cu_version, + &cu_abbrev_offset, &cu_pointer_size, &cu_offset_size, + &cu_extension_size, &cu_next_offset, &de) == DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_offset_size); + TS_CHECK_UINT(cu_extension_size); + TS_CHECK_UINT(cu_next_offset); + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_next_cu_header_c(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Unsigned cu_header_length; + Dwarf_Half cu_version; + Dwarf_Off cu_abbrev_offset; + Dwarf_Half cu_pointer_size; + Dwarf_Half cu_offset_size; + Dwarf_Half cu_extension_size; + Dwarf_Sig8 cu_type_sig; + Dwarf_Unsigned cu_type_offset; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + while (dwarf_next_cu_header_c(dbg, 1, &cu_header_length, &cu_version, + &cu_abbrev_offset, &cu_pointer_size, &cu_offset_size, + &cu_extension_size, NULL, NULL, &cu_next_offset, &de) == + DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_offset_size); + TS_CHECK_UINT(cu_extension_size); + TS_CHECK_UINT(cu_next_offset); + } + + do { + while (dwarf_next_cu_header_c(dbg, 0, &cu_header_length, + &cu_version, &cu_abbrev_offset, &cu_pointer_size, + &cu_offset_size, &cu_extension_size, &cu_type_sig, + &cu_type_offset, &cu_next_offset, &de) == DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_offset_size); + TS_CHECK_UINT(cu_extension_size); + TS_CHECK_BLOCK(cu_type_sig.signature, 8); + TS_CHECK_UINT(cu_type_offset); + TS_CHECK_UINT(cu_next_offset); + } + } while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +#define _LOOP_COUNT 50 + +static void +tp_dwarf_next_cu_header_loop(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int i, r, fd, result; + Dwarf_Unsigned cu_next_offset; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + for (i = 0; i < _LOOP_COUNT; i++) { + tet_printf("dwarf_next_cu_header loop(%d)\n", i); + r = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, + &cu_next_offset, &de); + TS_CHECK_INT(r); + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz new file mode 100644 index 0000000000..c613d8ec74 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz new file mode 100644 index 0000000000..1800628153 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz new file mode 100644 index 0000000000..adf56ab1f7 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/Makefile new file mode 100644 index 0000000000..1b62ff985f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_pubnames.c +TS_DATA= dt32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dt32-g1.xml.gz new file mode 100644 index 0000000000..fe85f1786c Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dwarf_pubnames.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dwarf_pubnames.c new file mode 100644 index 0000000000..c6c677fbec --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/dwarf_pubnames.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_pubnames.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf address range API. + */ +static void tp_dwarf_pubnames(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_pubnames", tp_dwarf_pubnames}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +static void +tp_dwarf_pubnames(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Global *globals; + Dwarf_Signed global_cnt; + Dwarf_Off die_off, cu_off; + char *glob_name; + int fd, r_globals, i; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + r_globals = dwarf_get_globals(dbg, &globals, &global_cnt, &de); + TS_CHECK_INT(r_globals); + if (r_globals == DW_DLV_ERROR) { + tet_printf("dwarf_get_globals failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + TS_CHECK_INT(global_cnt); + if (r_globals == DW_DLV_OK) { + for (i = 0; i < global_cnt; i++) { + if (dwarf_globname(globals[i], &glob_name, &de) != + DW_DLV_OK) { + tet_printf("dwarf_globname failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_STRING(glob_name); + if (dwarf_global_die_offset(globals[i], &die_off, + &de) != DW_DLV_OK) { + tet_printf("dwarf_global_die_offset failed: " + "%s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(die_off); + if (dwarf_global_cu_offset(globals[i], &cu_off, + &de) != DW_DLV_OK) { + tet_printf("dwarf_global_cu_offset failed: " + "%s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_INT(cu_off); + if (dwarf_global_name_offsets(globals[i], &glob_name, + &die_off, &cu_off, &de) != DW_DLV_OK) { + tet_printf("dwarf_global_name_offsets failed: ", + "%s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + TS_CHECK_STRING(glob_name); + TS_CHECK_INT(die_off); + TS_CHECK_INT(cu_off); + } + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/ec64-g1.xml.gz new file mode 100644 index 0000000000..4549439f6e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_pubnames/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/Makefile new file mode 100644 index 0000000000..e5403082eb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_ranges.c +TS_DATA= dt32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dt32-g1.xml.gz new file mode 100644 index 0000000000..12d4edf630 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dwarf_ranges.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dwarf_ranges.c new file mode 100644 index 0000000000..2cb758bb81 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/dwarf_ranges.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_ranges.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +/* + * Test case for dwarf address range API. + */ +static void tp_dwarf_ranges(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_ranges", tp_dwarf_ranges}, + {NULL, NULL}, +}; +static int result = TET_UNRESOLVED; +#include "driver.c" + +static void +tp_dwarf_ranges(void) +{ + Dwarf_Debug dbg; + Dwarf_Ranges *ranges; + Dwarf_Signed range_cnt; + Dwarf_Unsigned byte_cnt; + Dwarf_Off off; + Dwarf_Error de; + int fd, r_ranges, i; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + off = 0; + for (;;) { + tet_printf("check ranges at offset(%ju):\n", (uintmax_t) off); + r_ranges = dwarf_get_ranges_a(dbg, off, NULL, &ranges, + &range_cnt, &byte_cnt, &de); + if (r_ranges != DW_DLV_OK) + break; + TS_CHECK_INT(range_cnt); + TS_CHECK_UINT(byte_cnt); + off += byte_cnt; + for (i = 0; i < range_cnt; i++) { + tet_printf("check range %d:\n", i); + TS_CHECK_INT(ranges[i].dwr_type); + TS_CHECK_UINT(ranges[i].dwr_addr1); + TS_CHECK_UINT(ranges[i].dwr_addr2); + } + } + + /* + * SGI libdwarf return DW_DLV_ERROR when provided offset is out of + * range, instead of DW_DLV_NO_ENTRY as stated in the SGI libdwarf + * documentation. elftoolchain libdwarf follows the SGI libdwarf + * documentation. + */ +#if 0 + if (r_ranges == DW_DLV_ERROR) { + tet_printf("dwarf_get_ranges failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } +#endif + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/ec64-g1.xml.gz new file mode 100644 index 0000000000..acb5532cdf Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_ranges/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/Makefile b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/Makefile new file mode 100644 index 0000000000..37f2df7c09 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= dwarf_siblingof.c +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt32-g1.xml.gz new file mode 100644 index 0000000000..adec08c4e3 Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt64-g1.xml.gz new file mode 100644 index 0000000000..f4e01e048a Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dt64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dwarf_siblingof.c b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dwarf_siblingof.c new file mode 100644 index 0000000000..5347620689 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/dwarf_siblingof.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: dwarf_siblingof.c 2084 2011-10-27 04:48:12Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "tet_api.h" + +static void tp_dwarf_siblingof_level1(void); +static void tp_dwarf_siblingof_sanity(void); +static struct dwarf_tp dwarf_tp_array[] = { + {"tp_dwarf_siblingof_level1", tp_dwarf_siblingof_level1}, + {"tp_dwarf_siblingof_sanity", tp_dwarf_siblingof_sanity}, + {NULL, NULL}, +}; +#include "driver.c" + +static void +tp_dwarf_siblingof_level1(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Die die, die0; + Dwarf_Unsigned cu_next_offset; + int r, fd, result, die_cnt; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + tet_infoline("count the number of level 1 DIEs"); + + die_cnt = 0; + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + r = dwarf_siblingof(dbg, NULL, &die, &de); + while (r == DW_DLV_OK) { + if (die == NULL) { + tet_infoline("dwarf_siblingof return DW_DLV_OK" + " while argument die is not filled in"); + result = TET_FAIL; + goto done; + } + die_cnt++; + die0 = die; + r = dwarf_siblingof(dbg, die0, &die, &de); + } + if (r == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + } + + TS_CHECK_INT(die_cnt); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void +tp_dwarf_siblingof_sanity(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Die die, die0; + Dwarf_Half tag, tag0; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + if (dwarf_siblingof(dbg, NULL, &die, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_siblingof didn't return DW_DLV_ERROR when" + " called without CU context"); + result = TET_FAIL; + goto done; + } + + die = die0 = NULL; + TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { + if (dwarf_siblingof(dbg, NULL, &die, &de) == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_siblingof(dbg, NULL, &die0, &de) == DW_DLV_ERROR) { + tet_printf("dwarf_siblingof failed: %s\n", + dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (dwarf_tag(die0, &tag0, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + goto done; + } + if (tag != tag0) { + tet_infoline("DIEs returned by two identical " + "dwarf_siblingof calls have different tags"); + result = TET_FAIL; + goto done; + } + if (dwarf_siblingof(NULL, die0, &die, &de) != DW_DLV_ERROR) { + tet_infoline("dwarf_siblingof didn't return " + "DW_DLV_ERROR when called with NULL dbg"); + result = TET_FAIL; + goto done; + } + } + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec32-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec32-g1.xml.gz new file mode 100644 index 0000000000..7dc98d9a7e Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec32-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec64-g1.xml.gz b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec64-g1.xml.gz new file mode 100644 index 0000000000..ec096c453d Binary files /dev/null and b/contrib/elftoolchain/tests/tet/libdwarf/ts/dwarf_siblingof/ec64-g1.xml.gz differ diff --git a/contrib/elftoolchain/tests/tet/libelf/Makefile b/contrib/elftoolchain/tests/tet/libelf/Makefile new file mode 100644 index 0000000000..0899ff97ab --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/Makefile @@ -0,0 +1,6 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. +SUBDIR= tset + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/README b/contrib/elftoolchain/tests/tet/libelf/README new file mode 100644 index 0000000000..f3d08801b7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/README @@ -0,0 +1,96 @@ +: README +: $Id: README 2055 2011-10-26 12:15:06Z jkoshy $ + +This directory contains a test suite for libelf. + +: Pre-requisites + +1) TET (Test Execution Toolkit) from The Open Group. + http://tetworks.opengroup.org/tet/ + +2) YAML tools for Python. + http://pyyaml.org + +On FreeBSD, you may install the following ports: + - misc/tet, version 3.7 or later + - devel/py-yaml, version 3.04 or later + +: Using make(1) to build the test suite + +For developers who prefer using make(1) as their build tool, a +top-level 'Makefile' that builds the test suite is provided. + +This Makefile also supports the following targets: + + 'tccbuild' Build the test suite using tcc. + 'tccclean' Clean the test suite using tcc. + 'execute' Execute the test suite using tcc. + +: Notes on TET Configuration + +Debugging TET executables is much easier if you've built +the 'lite' version of TET. The LibElf test suite does not +use TET's distributed testing features, so the 'lite' version +of TET is sufficient. + +The 'lite' version of TET does not need further configuration. + +If you chosen to install the 'inet' (distributed) version of TET, +you'll need a minimal ${TET_ROOT}/systems file. The following +content in the file is enough for this test suite. + + 000 localhost + +For the 'inet' version of TET, you'll need `tccd` running, and a +`systems.equiv` file in the directory of the user running `tccd`. +The following contents will do for this file: + + localhost + +We use regular 'make' as our build tool. Since make doesn't use +the TETware API when printing messages we must tell tcc to execute +make with output capture mode enabled. + +TET_BUILD_TOOL=make +TET_OUTPUT_CAPTURE=True + +We'll assume that each test case is in a directory of its +own and the Makefile in that directory builds that executable +We don't need the name of the test case to be passed in to 'make' + +TET_PASS_TC_NAME=False + +Similarly, for cleaning the test suite, we use 'make'. + +TET_CLEAN_TOOL=make +TET_CLEAN_FILE=clean + +Since the test cases themselves are API compliant, we'll +set TET_OUTPUT_CAPTURE=False for test case execution. + +: Notes on TET execution + +Edit the top-level 'Makefile' and set the TET_ROOT variable to +the path where the TET test suite is installed. Once this is +done: + + * A `make all` at the top level will build the test suite. + * A `make execute` will run `tcc`, leaving a log in a `results/` + directory. + +Here is how to run `tcc` by hand: + + % TET_ROOT=/where/ever TET_EXECUTE=/usr/obj/`pwd` TET_SUITE_ROOT=`pwd` \ + $TET_ROOT/bin/tcc [-e | -b | -c] . + +The TET_ROOT setting points points `tcc` to its configuration files. + +TET_EXECUTE points `tcc` to the location of the binaries created by the +'build' phase. Since we are using FreeBSD `make`, this path would be +under ${MAKEOBJDIRPREFIX}. + +TET_SUITE_ROOT informs `tcc` that the test suite is NOT located under +${TET_ROOT}. + +If all goes well, `tcc` will create a journal file in the +'results/NNNN[bec]/' directory under ${PWD}. diff --git a/contrib/elftoolchain/tests/tet/libelf/tet_code b/contrib/elftoolchain/tests/tet/libelf/tet_code new file mode 100644 index 0000000000..ddeff88d5d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tet_code @@ -0,0 +1,17 @@ +# LibELF test suite. +# +# $Id: tet_code 2055 2011-10-26 12:15:06Z jkoshy $ + +# TET reserved codes +0 "PASS" +1 "FAIL" +2 "UNRESOLVED" +3 "NOTINUSE" +4 "UNSUPPORTED" +5 "UNTESTED" +6 "UNINITIATED" +7 "NORESULT" + +# Test suite additional codes +101 "INSPECT" + diff --git a/contrib/elftoolchain/tests/tet/libelf/tet_scen b/contrib/elftoolchain/tests/tet/libelf/tet_scen new file mode 100644 index 0000000000..6626bf0f57 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tet_scen @@ -0,0 +1,118 @@ +# LibElf Test Suite + +# Scenario file + +# $Id: tet_scen 3926 2021-03-07 12:16:56Z jkoshy $ + +all + ^abi + ^elf32_getehdr + ^elf32_getphdr + ^elf32_getshdr + ^elf32_newehdr + ^elf32_xlatetof + ^elf32_xlatetom + ^elf64_getehdr + ^elf64_getphdr + ^elf64_getshdr + ^elf64_newehdr + ^elf64_xlatetof + ^elf64_xlatetom + ^elf_begin + ^elf_cntl + ^elf_end + ^elf_errmsg + ^elf_errno + ^elf_fill + ^elf_flagarhdr + ^elf_flagdata + ^elf_flagehdr + ^elf_flagelf + ^elf_flagphdr + ^elf_flagscn + ^elf_flagshdr + ^elf_fsize + ^elf_getarhdr + ^elf_getarsym + ^elf_getbase + ^elf_getdata + ^elf_getident + ^elf_getscn + ^elf_getshnum + ^elf_getshstrndx + ^elf_getversion + ^elf_hash + ^elf_kind + ^elf_memory + ^elf_ndxscn + ^elf_newscn + ^elf_next + ^elf_nextscn + ^elf_rawfile + ^elf_strptr + ^elf_update + ^elf_version + ^gelf_getclass + ^gelf_getehdr + ^gelf_newehdr + ^gelf_xlate + +abi :include:/tset/abi/tet_scen +elf32_getehdr :include:/tset/elf32_getehdr/tet_scen +elf32_getphdr :include:/tset/elf32_getphdr/tet_scen +elf32_getshdr :include:/tset/elf32_getshdr/tet_scen +elf32_newehdr :include:/tset/elf32_newehdr/tet_scen +elf32_xlatetof :include:/tset/elf32_xlatetof/tet_scen +elf32_xlatetom :include:/tset/elf32_xlatetom/tet_scen +elf64_getehdr :include:/tset/elf64_getehdr/tet_scen +elf64_getphdr :include:/tset/elf64_getphdr/tet_scen +elf64_getshdr :include:/tset/elf64_getshdr/tet_scen +elf64_newehdr :include:/tset/elf64_newehdr/tet_scen +elf64_xlatetof :include:/tset/elf64_xlatetof/tet_scen +elf64_xlatetom :include:/tset/elf64_xlatetom/tet_scen +elf_begin :include:/tset/elf_begin/tet_scen +elf_cntl :include:/tset/elf_cntl/tet_scen +elf_end :include:/tset/elf_end/tet_scen +elf_errmsg :include:/tset/elf_errmsg/tet_scen +elf_errno :include:/tset/elf_errno/tet_scen +elf_fill :include:/tset/elf_fill/tet_scen +elf_flagarhdr :include:/tset/elf_flagarhdr/tet_scen +elf_flagdata :include:/tset/elf_flagdata/tet_scen +elf_flagehdr :include:/tset/elf_flagehdr/tet_scen +elf_flagelf :include:/tset/elf_flagelf/tet_scen +elf_flagphdr :include:/tset/elf_flagphdr/tet_scen +elf_flagscn :include:/tset/elf_flagscn/tet_scen +elf_flagshdr :include:/tset/elf_flagshdr/tet_scen +elf_fsize :include:/tset/elf_fsize/tet_scen +elf_getarhdr :include:/tset/elf_getarhdr/tet_scen +elf_getarsym :include:/tset/elf_getarsym/tet_scen +elf_getbase :include:/tset/elf_getbase/tet_scen +elf_getdata :include:/tset/elf_getdata/tet_scen +elf_getident :include:/tset/elf_getident/tet_scen +elf_getscn :include:/tset/elf_getscn/tet_scen +elf_getshnum :include:/tset/elf_getshnum/tet_scen +elf_getshstrndx :include:/tset/elf_getshstrndx/tet_scen +elf_getversion :include:/tset/elf_getversion/tet_scen +elf_hash :include:/tset/elf_hash/tet_scen +elf_kind :include:/tset/elf_kind/tet_scen +elf_memory :include:/tset/elf_memory/tet_scen +elf_ndxscn :include:/tset/elf_ndxscn/tet_scen +elf_newscn :include:/tset/elf_newscn/tet_scen +elf_next :include:/tset/elf_next/tet_scen +elf_nextscn :include:/tset/elf_nextscn/tet_scen +elf_rawfile :include:/tset/elf_rawfile/tet_scen +elf_strptr :include:/tset/elf_strptr/tet_scen +elf_update :include:/tset/elf_update/tet_scen +elf_version :include:/tset/elf_version/tet_scen +gelf_getclass :include:/tset/gelf_getclass/tet_scen +gelf_getehdr :include:/tset/gelf_getehdr/tet_scen +gelf_newehdr :include:/tset/gelf_newehdr/tet_scen +gelf_xlate :include:/tset/gelf_xlate/tet_scen + +# +# Other aliases +# +getehdr + ^elf32_getehdr + ^elf64_getehdr + ^gelf_getehdr diff --git a/contrib/elftoolchain/tests/tet/libelf/tetbuild.cfg b/contrib/elftoolchain/tests/tet/libelf/tetbuild.cfg new file mode 100644 index 0000000000..ed3f88aa0d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tetbuild.cfg @@ -0,0 +1,7 @@ +# LibElf Test Suite +# +# $Id: tetbuild.cfg 2055 2011-10-26 12:15:06Z jkoshy $ + +TET_BUILD_TOOL=make +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libelf/tetclean.cfg b/contrib/elftoolchain/tests/tet/libelf/tetclean.cfg new file mode 100644 index 0000000000..3c7ce9ca69 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tetclean.cfg @@ -0,0 +1,9 @@ +# LibElf Test Suite. +# +# $Id: tetclean.cfg 2055 2011-10-26 12:15:06Z jkoshy $ + +TET_CLEAN_TOOL=make +TET_CLEAN_FILE=clean + +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libelf/tetexec.cfg b/contrib/elftoolchain/tests/tet/libelf/tetexec.cfg new file mode 100644 index 0000000000..29f044068e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tetexec.cfg @@ -0,0 +1,5 @@ +# LibElf Test Suite. +# +# $Id: tetexec.cfg 2055 2011-10-26 12:15:06Z jkoshy $ + +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/Makefile new file mode 100644 index 0000000000..ec4aace372 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/Makefile @@ -0,0 +1,62 @@ +# +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ +# + +TOP= ../../../.. + +SUBDIR+= common # must be first + +SUBDIR+= abi +SUBDIR+= elf_begin +SUBDIR+= elf_cntl +SUBDIR+= elf_end +SUBDIR+= elf_errmsg +SUBDIR+= elf_errno +SUBDIR+= elf_fill +SUBDIR+= elf_flagarhdr +SUBDIR+= elf_flagdata +SUBDIR+= elf_flagehdr +SUBDIR+= elf_flagelf +SUBDIR+= elf_flagphdr +SUBDIR+= elf_flagscn +SUBDIR+= elf_flagshdr +SUBDIR+= elf_fsize +SUBDIR+= elf_getarhdr +SUBDIR+= elf_getarsym +SUBDIR+= elf_getbase +SUBDIR+= elf_getdata +SUBDIR+= elf_getident +SUBDIR+= elf_getscn +SUBDIR+= elf_getshnum +SUBDIR+= elf_getshstrndx +SUBDIR+= elf_getversion +SUBDIR+= elf_hash +SUBDIR+= elf_kind +SUBDIR+= elf_memory +SUBDIR+= elf_ndxscn +SUBDIR+= elf_next +SUBDIR+= elf_newscn +SUBDIR+= elf_nextscn +SUBDIR+= elf_rand +SUBDIR+= elf_rawfile +SUBDIR+= elf_strptr +SUBDIR+= elf_update +SUBDIR+= elf_version +SUBDIR+= elf32_getehdr +SUBDIR+= elf32_getphdr +SUBDIR+= elf32_getshdr +SUBDIR+= elf32_newehdr +SUBDIR+= elf32_xlatetof +SUBDIR+= elf32_xlatetom +SUBDIR+= elf64_getehdr +SUBDIR+= elf64_getphdr +SUBDIR+= elf64_getshdr +SUBDIR+= elf64_newehdr +SUBDIR+= elf64_xlatetof +SUBDIR+= elf64_xlatetom +SUBDIR+= gelf_getclass +SUBDIR+= gelf_getehdr +SUBDIR+= gelf_newehdr +SUBDIR+= gelf_xlate + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/Makefile.tset b/contrib/elftoolchain/tests/tet/libelf/tset/Makefile.tset new file mode 100644 index 0000000000..45ae4d68d0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/Makefile.tset @@ -0,0 +1,36 @@ +# $Id: Makefile.tset 2077 2011-10-27 03:59:40Z jkoshy $ + +# All the test cases in this test suite need -lelf. +DPADD+= ${LIBELF} +LDADD+= -lelf + +GENERATE_TEST_SCAFFOLDING= yes + +# Add a file name to TS_YAML if all four variants of the generated ELF +# object are needed. +.if defined(TS_YAML) +.for yaml in ${TS_YAML} +.for sufx in lsb32 lsb64 msb32 msb64 +TS_DATA+= ${yaml}.${sufx} +.endfor +.endfor +.endif + +# Copy ELF binaries used by test cases to the build directory so that +# the test binaries have access to them. +_TS_YAMLOBJ?= ${TS_DATA:M*.msb32} ${TS_DATA:M*.lsb32} ${TS_DATA:M*.msb64} \ + ${TS_DATA:M*.lsb64} +.for f in ${_TS_YAMLOBJ} +.if exists(${TS_OBJROOT}/common/${f}) +_YO= ${TS_OBJROOT}/common/${f} +.elif exists(${TS_ROOT}/common/obj/${f}) +_YO= ${TS_ROOT}/common/obj/${f} +.else +_YO= /nonexistent +.endif +${f}: ${_YO} + @cp ${.ALLSRC} ${.TARGET} +.endfor + +# Test cases do not supply manual pages. +NOMAN= noman diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/abi/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/abi/Makefile new file mode 100644 index 0000000000..3093876111 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/abi/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= abi.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/abi/abi.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/abi/abi.m4 new file mode 100644 index 0000000000..4d946cb3f6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/abi/abi.m4 @@ -0,0 +1,296 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: abi.m4 2077 2011-10-27 03:59:40Z jkoshy $ + */ + +/* + * Tests for ABI values. + * + * See: http://www.sco.com/developers/gabi/latest/ch4.eheader.html + */ + +#include + +#include "tet_api.h" + +include(`elfts.m4') + +undefine(`FN') +define(`FN',` +void +tcCheck$1(void) +{ + int result; + const size_t nconst = sizeof($2) / sizeof ($2[0]); + size_t n; + + TP_ANNOUNCE("Check " $3 " values"); + + result = TET_FAIL; + + for (n = 0; n < nconst; n++) + if ($2[n].symbol != $2[n].value) + goto done; + + result = TET_PASS; + +done: + tet_result(result); +} +') + +struct _sym { + size_t symbol; + size_t value; +}; + +/* + * Check ELFOSABI_* values. + */ +struct _sym elf_osabi[] = { + { ELFOSABI_NONE, 0}, + { ELFOSABI_SYSV, 0}, + { ELFOSABI_HPUX, 1}, + { ELFOSABI_NETBSD, 2}, + { ELFOSABI_GNU, 3}, + { ELFOSABI_HURD, 4}, + { ELFOSABI_86OPEN, 5}, + { ELFOSABI_SOLARIS, 6}, + { ELFOSABI_AIX, 7}, + { ELFOSABI_IRIX, 8}, + { ELFOSABI_FREEBSD, 9}, + { ELFOSABI_TRU64, 10}, + { ELFOSABI_MODESTO, 11}, + { ELFOSABI_OPENBSD, 12}, + { ELFOSABI_OPENVMS, 13}, + { ELFOSABI_NSK, 14}, + { ELFOSABI_AROS, 15}, + { ELFOSABI_FENIXOS, 16} +}; + +FN(OsAbi, elf_osabi, "ELF_OSABI") + +/* + * Check EM_* values. + */ +struct _sym elf_em[] = { + { EM_NONE, 0 }, + { EM_M32, 1 }, + { EM_SPARC, 2 }, + { EM_386, 3 }, + { EM_68K, 4 }, + { EM_88K, 5 }, + { EM_860, 7 }, + { EM_MIPS, 8 }, + { EM_S370, 9 }, + { EM_MIPS_RS3_LE, 10 }, + { EM_PARISC, 15 }, + { EM_VPP500, 17 }, + { EM_SPARC32PLUS, 18 }, + { EM_960, 19 }, + { EM_PPC, 20 }, + { EM_PPC64, 21 }, + { EM_S390, 22 }, + { EM_SPU, 23 }, + { EM_V800, 36 }, + { EM_FR20, 37 }, + { EM_RH32, 38 }, + { EM_RCE, 39 }, + { EM_ARM, 40 }, + { EM_ALPHA, 41 }, + { EM_SH, 42 }, + { EM_SPARCV9, 43 }, + { EM_TRICORE, 44 }, + { EM_ARC, 45 }, + { EM_H8_300, 46 }, + { EM_H8_300H, 47 }, + { EM_H8S, 48 }, + { EM_H8_500, 49 }, + { EM_IA_64, 50 }, + { EM_MIPS_X, 51 }, + { EM_COLDFIRE, 52 }, + { EM_68HC12, 53 }, + { EM_MMA, 54 }, + { EM_PCP, 55 }, + { EM_NCPU, 56 }, + { EM_NDR1, 57 }, + { EM_STARCORE, 58 }, + { EM_ME16, 59 }, + { EM_ST100, 60 }, + { EM_TINYJ, 61 }, + { EM_X86_64, 62 }, + { EM_PDSP, 63 }, + { EM_PDP10, 64 }, + { EM_PDP11, 65 }, + { EM_FX66, 66 }, + { EM_ST9PLUS, 67 }, + { EM_ST7, 68 }, + { EM_68HC16, 69 }, + { EM_68HC11, 70 }, + { EM_68HC08, 71 }, + { EM_68HC05, 72 }, + { EM_SVX, 73 }, + { EM_ST19, 74 }, + { EM_VAX, 75 }, + { EM_CRIS, 76 }, + { EM_JAVELIN, 77 }, + { EM_FIREPATH, 78 }, + { EM_ZSP, 79 }, + { EM_MMIX, 80 }, + { EM_HUANY, 81 }, + { EM_PRISM, 82 }, + { EM_AVR, 83 }, + { EM_FR30, 84 }, + { EM_D10V, 85 }, + { EM_D30V, 86 }, + { EM_V850, 87 }, + { EM_M32R, 88 }, + { EM_MN10300, 89 }, + { EM_MN10200, 90 }, + { EM_PJ, 91 }, + { EM_OPENRISC, 92 }, + { EM_ARC_COMPACT, 93 }, + { EM_XTENSA, 94 }, + { EM_VIDEOCORE, 95 }, + { EM_TMM_GPP, 96 }, + { EM_NS32K, 97 }, + { EM_TPC, 98 }, + { EM_SNP1K, 99 }, + { EM_ST200, 100 }, + { EM_IP2K, 101 }, + { EM_MAX, 102 }, + { EM_CR, 103 }, + { EM_F2MC16, 104 }, + { EM_MSP430, 105 }, + { EM_BLACKFIN, 106 }, + { EM_SE_C33, 107 }, + { EM_SEP, 108 }, + { EM_ARCA, 109 }, + { EM_UNICORE, 110 }, + { EM_EXCESS, 111 }, + { EM_DXP, 112 }, + { EM_ALTERA_NIOS2, 113 }, + { EM_CRX, 114 }, + { EM_XGATE, 115 }, + { EM_C166, 116 }, + { EM_M16C, 117 }, + { EM_DSPIC30F, 118 }, + { EM_CE, 119 }, + { EM_M32C, 120 }, + { EM_TSK3000, 131 }, + { EM_RS08, 132 }, + { EM_SHARC, 133 }, + { EM_ECOG2, 134 }, + { EM_SCORE7, 135 }, + { EM_DSP24, 136 }, + { EM_VIDEOCORE3, 137 }, + { EM_LATTICEMICO32, 138 }, + { EM_SE_C17, 139 }, + { EM_TI_C6000, 140 }, + { EM_TI_C2000, 141 }, + { EM_TI_C5500, 142 }, + { EM_MMDSP_PLUS, 160 }, + { EM_CYPRESS_M8C, 161 }, + { EM_R32C, 162 }, + { EM_TRIMEDIA, 163 }, + { EM_QDSP6, 164 }, + { EM_8051, 165 }, + { EM_STXP7X, 166 }, + { EM_NDS32, 167 }, + { EM_ECOG1, 168 }, + { EM_ECOG1X, 168 }, + { EM_MAXQ30, 169 }, + { EM_XIMO16, 170 }, + { EM_MANIK, 171 }, + { EM_CRAYNV2, 172 }, + { EM_RX, 173 }, + { EM_METAG, 174 }, + { EM_MCST_ELBRUS, 175 }, + { EM_ECOG16, 176 }, + { EM_CR16, 177 }, + { EM_ETPU, 178 }, + { EM_SLE9X, 179 }, + { EM_AVR32, 185 }, + { EM_STM8, 186 }, + { EM_TILE64, 187 }, + { EM_TILEPRO, 188 }, + { EM_MICROBLAZE, 189 }, + { EM_CUDA, 190 }, + { EM_TILEGX, 191 }, + { EM_CLOUDSHIELD, 192 }, + { EM_COREA_1ST, 193 }, + { EM_COREA_2ND, 194 }, + { EM_ARC_COMPACT2, 195 }, + { EM_OPEN8, 196 }, + { EM_RL78, 197 }, + { EM_VIDEOCORE5, 198 }, + { EM_78KOR, 199 }, +}; + +FN(ElfMachine, elf_em, "EM_*") + +/* + * Check ET_* values. + */ +struct _sym elf_type[] = { + { ET_NONE, 0 }, + { ET_REL, 1 }, + { ET_EXEC, 2 }, + { ET_DYN, 3 }, + { ET_CORE, 4 } +}; + +FN(ElfType, elf_type, "ET_*") + +/* + * Check values for miscellaneous ABI symbols. + */ +struct _sym elf_misc[] = { + { EV_NONE, 0 }, + { EV_CURRENT, 1 }, + { EI_MAG0, 0 }, + { EI_MAG1, 1 }, + { EI_MAG2, 2 }, + { EI_MAG3, 3 }, + { EI_CLASS, 4 }, + { EI_DATA, 5 }, + { EI_VERSION, 6 }, + { EI_OSABI, 7 }, + { EI_ABIVERSION, 8 }, + { EI_NIDENT, 16 }, + { ELFMAG0, 0x7F }, + { ELFMAG1, 'E' }, + { ELFMAG2, 'L' }, + { ELFMAG3, 'F' }, + { ELFCLASSNONE, 0 }, + { ELFCLASS32, 1 }, + { ELFCLASS64, 2 }, + { ELFDATANONE, 0 }, + { ELFDATA2LSB, 1 }, + { ELFDATA2MSB, 2 }, +}; + +FN(ElfMisc, elf_misc, "miscellaneous symbol"); diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/bin/elf-hash b/contrib/elftoolchain/tests/tet/libelf/tset/bin/elf-hash new file mode 100755 index 0000000000..6cb4236c35 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/bin/elf-hash @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# +# $Id: elf-hash 3863 2020-06-24 21:39:04Z jkoshy $ + +import io, sys, os + + +def elf_hash(s : bytes): + """A python implementation of elf_hash(3).""" + h = 0 + for c in s: + h = (h << 4) + c + t = (h & 0xF0000000) + if t != 0: + h = h ^ (t >> 24) + h = h & ~t + return h + + +if __name__ == '__main__': + from optparse import OptionParser + + usage = "usage: %prog [options] files...\n" + \ + " print ELF hash values for strings or file contents" + + p = OptionParser(usage=usage) + p.add_option( + "-s", + "--string", + dest="hash_strings", + action="append", + metavar="STRING", + help="compute hash for STRING") + + options, args = p.parse_args() + if not options.hash_strings and not args: + p.print_help() + sys.exit(1) + + if options.hash_strings: + for s in options.hash_strings: + print("\"%s\" 0x%x" % (s, elf_hash(bytes(s, 'utf-8')))) + for f in args: + print("[%s] 0x%x" % (f, elf_hash(io.open(f, 'rb').read()))) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/bin/elfc b/contrib/elftoolchain/tests/tet/libelf/tset/bin/elfc new file mode 100755 index 0000000000..cb4f2e5849 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/bin/elfc @@ -0,0 +1,1804 @@ +#!/usr/bin/env python3 +# +# This script converts a textual (YAML) description of an ELF file to +# an equivalent 'binary' file. +# +# The YAML description may have the following top-level keys: +# +# 'elf_fillchar': char +# Sets the fill character to 'char'. +# 'ehdr': EHDR-DESCRIPTOR +# Defines an ELF Ehdr structure. +# 'phdrtab': list-of(PHDR-DESCRIPTOR) +# Defines the contents of the ELF Program Header table. +# Each `Phdr' descriptor represents one ELF Phdr entry. +# 'sections': list-of(SECTION-DESCRIPTOR) +# Defines the content of each section in the file. Each +# `SECTION-DESCRIPTOR' contains information for the +# section `header' and the actual data for the section. +# +# The script will compute reasonable defaults for any fields +# left unspecified in the YAML description. +# +# Descriptors EHDR-DESCRIPTOR and PHDR-DESCRIPTOR may be specified +# as a YAML key-value set. The key names correspond to the +# field names of the corresponding ELF structures, e.g., 'e_machine' +# and 'e_ident' for the Ehdr and 'p_type' and 'p_paddr' for +# a Phdr entry. +# +# Descriptor SECTION-DESCRIPTOR contains the fields in an ELF +# Shdr structure and an additional member 'sh_data', whose +# value is the data for the section. +# +# Example: +# +# +# ehdr: !Ehdr +# e_ident: !Ident +# ei_class: ELFCLASS32 +# ei_data: ELFDATA2MSB +# e_machine: EM_PPC +# phdrtab: +# - !Phdr +# ph_type: PHT_NULL +# ... other program header fields ... +# - !Phdr +# ... etc. ... +# sections: +# - !Section +# sh_name: .dynsym +# ... other section header fields ... +# sh_data: # ... list of data ... +# - !Dyn +# d_tag: 0xdeadcode +# - !Dyn +# d_tag: 0xcafebabe +# - !Section +# sh_name: .shstrtab +# sh_type: SHT_STRTAB +# sh_data: +# - string1 +# - string2 +# +# +# :: Handling of strings :: +# +# Fields like 'sh_name' (in a section header) are defined to contain +# an integer index into a specified string table (in this case a +# section with name '.shstrtab'). Other ELF data structures use a +# similar convention; names in a '.dynamic' section as stored as +# indices into a '.dynstr' section. In the YAML descriptor, such +# fields may be specified as indices, which are used as-is, or as text +# strings which are converted to the appropriate string index. +# For convenience in creating ELF objects with a large number of +# sections, a section index may be manually specified using a +# 'sh_index' pseudo field. +# +# Formatting note: comment lines containing the string '-YAPF-' serve +# as guides for the YAPF formatting utility. +# +# $Id: elfc 3968 2022-04-22 17:19:00Z jkoshy $ + +version = "%prog 1.0" +usage = "usage: %prog [options] [input-file]" +description = """Create an ELF binary from a textual description in """ + \ + """'input-file' (or stdin)""" + +import io, operator, optparse, re, struct, sys, types, yaml + + +class ElfError(Exception): + """An exception signalled during conversion.""" + + def __init__(self, node=None, msg=None): + """Initialize an exception object. + + Arguments: + node -- a YAML parse tree node. + msg -- human readable message associated with this + exception. + """ + if node: + self.ee_start = node.start_mark.line + 1 + self.ee_end = node.end_mark.line + 1 + else: + self.ee_start = self.ee_end = -1 + self.ee_msg = msg + + def __str__(self): + """Form a printable representation of an exception.""" + + if self.ee_start != -1: + if self.ee_start == self.ee_end: + return "Error: line {start}: {msg}".format( + start=self.ee_start, end=self.ee_msg) + else: + return "Error: lines {start}--{end}: {msg}".format( + start=self.ee_start, end=self.ee_end, msg=self.ee_msg) + else: + return "Error: {msg}".format(msg=self.ee_msg) + + +# +# Mappings used by the 'encode()' function +# + +elf_cap_tag = {'CA_SUNW_NULL': 0, 'CA_SUNW_HW_1': 1, 'CA_SUNW_SF_1': 2} + +elf_d_flags = { + 'DF_ORIGIN': 0x0001, + 'DF_SYMBOLIC': 0x0002, + 'DF_TEXTREL': 0x0004, + 'DF_BIND_NOW': 0x0006, + 'DF_STATIC_TLS': 0x0010 +} + +elf_d_tag = { + # from + 'DT_NULL': 0, + 'DT_NEEDED': 1, + 'DT_PLTRELSZ': 2, + 'DT_PLTGOT': 3, + 'DT_HASH': 4, + 'DT_STRTAB': 5, + 'DT_SYMTAB': 6, + 'DT_RELA': 7, + 'DT_RELASZ': 8, + 'DT_RELAENT': 9, + 'DT_STRSZ': 10, + 'DT_SYMENT': 11, + 'DT_INIT': 12, + 'DT_FINI': 13, + 'DT_SONAME': 14, + 'DT_RPATH': 15, + 'DT_SYMBOLIC': 16, + 'DT_REL': 17, + 'DT_RELSZ': 18, + 'DT_RELENT': 19, + 'DT_PLTREL': 20, + 'DT_DEBUG': 21, + 'DT_TEXTREL': 22, + 'DT_JMPREL': 23, + 'DT_BIND_NOW': 24, + 'DT_INIT_ARRAY': 25, + 'DT_FINI_ARRAY': 26, + 'DT_INIT_ARRAYSZ': 27, + 'DT_FINI_ARRAYSZ': 28, + 'DT_RUNPATH': 29, + 'DT_FLAGS': 30, + 'DT_ENCODING': 32, + 'DT_PREINIT_ARRAY': 32, + 'DT_PREINIT_ARRAYSZ': 33, + 'DT_LOOS': 0x6000000d, + 'DT_HIOS': 0x6ffff000, + 'DT_LOPROC': 0x70000000, + 'DT_HIPROC': 0x7fffffff, + 'DT_SUNW_AUXILIARY': 0x6000000D, + 'DT_SUNW_RTLDINF': 0x6000000E, + 'DT_SUNW_FILTER': 0x6000000F, + 'DT_SUNW_CAP': 0x60000010, + # from "usr.bin/elfdump/elfdump.c" + 'DT_GNU_PRELINKED': 0x6ffffdf5, + 'DT_GNU_CONFLICTSZ': 0x6ffffdf6, + 'DT_GNU_LIBLISTSZ': 0x6ffffdf7, + 'DT_SUNW_CHECKSUM': 0x6ffffdf78, + 'DT_PLTPADSZ': 0x6ffffdf79, + 'DT_MOVEENT': 0x6ffffdfa, + 'DT_MOVESZ': 0x6ffffdfb, + 'DT_FEATURE': 0x6ffffdfc, + 'DT_FEATURE': 0x6ffffdfd, + 'DT_POSFLAG_1': 0x6ffffdfe, + 'DT_SYMINENT': 0x6ffffdff, + 'DT_VALRNGHI': 0x6ffffdff, # dup + 'DT_ADDRRNGLO': 0x6ffffe00, + 'DT_GNU_CONFLICT': 0x6ffffef8, + 'DT_GNU_LIBLIST': 0x6ffffef9, + 'DT_SUNW_CONFIG': 0x6ffffefa, + 'DT_SUNW_DEPAUDIT': 0x6ffffefb, + 'DT_SUNW_AUDIT': 0x6ffffefc, + 'DT_SUNW_PLTPAD': 0x6ffffefd, + 'DT_SUNW_MOVETAB': 0x6ffffefe, + 'DT_SYMINFO': 0x6ffffeff, + 'DT_ADDRRNGHI': 0x6ffffeff, # dup + 'DT_VERSYM': 0x6ffffff0, + 'DT_GNU_VERSYM': 0x6ffffff0, # dup + 'DT_RELACOUNT': 0x6ffffff9, + 'DT_RELCOUNT': 0x6ffffffa, + 'DT_FLAGS_1': 0x6ffffffb, + 'DT_VERDEF': 0x6ffffffc, + 'DT_VERDEFNUM': 0x6ffffffd, + 'DT_VERNEED': 0x6ffffffe, + 'DT_VERNEEDNUM': 0x6fffffff, + 'DT_IA_64_PLT_RESERVE': 0x70000000, + 'DT_SUNW_AUXILIARY': 0x7ffffffd, + 'DT_SUNW_USED': 0x7ffffffe, + 'DT_SUNW_FILTER': 0x7fffffff +} + +elf_dyn_fields = ['d_tag', 'd_val', 'd_ptr'] + +elf_ehdr_flags = { # no known flags +} + +elf_ehdr_type = { # e_type + 'ET_NONE': 0, + 'ET_REL': 1, + 'ET_EXEC': 2, + 'ET_DYN': 3, + 'ET_CORE': 4 +} + +elf_ehdr_machine = { # e_machine + 'EM_NONE': 0, + 'EM_M32': 1, + 'EM_SPARC': 2, + 'EM_386': 3, + 'EM_68K': 4, + 'EM_88K': 5, + 'EM_486': 6, + 'EM_860': 7, + 'EM_MIPS': 8, + 'EM_S370': 9, + 'EM_MIPS_RS3_LE': 10, + 'EM_MIPS_RS4_BE': 10, + 'EM_PARISC': 15, + 'EM_VPP500': 17, + 'EM_SPARC32PLUS': 18, + 'EM_960': 19, + 'EM_PPC': 20, + 'EM_PPC64': 21, + 'EM_S390': 22, + 'EM_V800': 36, + 'EM_FR20': 37, + 'EM_RH32': 38, + 'EM_RCE': 39, + 'EM_ARM': 40, + 'EM_ALPHA_STD': 41, + 'EM_SH': 42, + 'EM_SPARCV9': 43, + 'EM_TRICORE': 44, + 'EM_ARC': 45, + 'EM_H8_300': 46, + 'EM_H8_300H': 47, + 'EM_H8S': 48, + 'EM_H8_500': 49, + 'EM_IA_64': 50, + 'EM_MIPS_X': 51, + 'EM_COLDFIRE': 52, + 'EM_68HC12': 53, + 'EM_MMA': 54, + 'EM_PCP': 55, + 'EM_NCPU': 56, + 'EM_NDR1': 57, + 'EM_STARCORE': 58, + 'EM_ME16': 59, + 'EM_ST100': 60, + 'EM_TINYJ': 61, + 'EM_X86_64': 62, + 'EM_ALPHA': 0x9026 +} + +elf_ei_version = { # e_version + 'EV_NONE': 0, + 'EV_CURRENT': 1 +} + +elf_ei_class = {'ELFCLASSNONE': 0, 'ELFCLASS32': 1, 'ELFCLASS64': 2} + +elf_ei_data = {'ELFDATANONE': 0, 'ELFDATA2LSB': 1, 'ELFDATA2MSB': 2} + +elf_ei_osabi = { + # Official values. + 'ELFOSABI_NONE': 0, + 'ELFOSABI_HPUX': 1, + 'ELFOSABI_NETBSD': 2, + 'ELFOSABI_GNU': 3, + 'ELFOSABI_HURD': 4, + 'ELFOSABI_86OPEN': 5, + 'ELFOSABI_SOLARIS': 6, + 'ELFOSABI_AIX': 7, + 'ELFOSABI_IRIX': 8, + 'ELFOSABI_FREEBSD': 9, + 'ELFOSABI_TRU64': 10, + 'ELFOSABI_MODESTO': 11, + 'ELFOSABI_OPENBSD': 12, + 'ELFOSABI_OPENVMS': 13, + 'ELFOSABI_NSK': 14, + 'ELFOSABI_ARM': 97, + 'ELFOSABI_STANDALONE': 255, + # Aliases. + 'ELFOSABI_SYSV': 0, + 'ELFOSABI_LINUX': 3, + 'ELFOSABI_MONTEREY': 7 +} + +elf_ph_fields = [ + 'p_align', 'p_filesz', 'p_flags', 'p_memsz', 'p_offset', 'p_paddr', + 'p_type', 'p_vaddr' +] + +elf_ph_flags = {'PF_X': 0x1, 'PF_W': 0x2, 'PF_R': 0x4} + +elf_ph_type = { + 'PT_NULL': 0, + 'PT_LOAD': 1, + 'PT_DYNAMIC': 2, + 'PT_INTERP': 3, + 'PT_NOTE': 4, + 'PT_SHLIB': 5, + 'PT_PHDR': 6, + 'PT_TLS': 7, + 'PT_LOOS': 0x60000000, + 'PT_HIOS': 0x6FFFFFFF, + 'PT_SUNW_UNWIND': 0x6464E550, + 'PT_GNU_EHFRAME': 0x6464E550, # dup + 'PT_SUNWBSS': 0x6FFFFFFA, + 'PT_SUNWSTACK': 0x6FFFFFFB, + 'PT_SUNWDTRACE': 0x6FFFFFFC, + 'PT_SUNWCAP': 0x6FFFFFFD, + 'PT_LOPROC': 0x70000000, + 'PT_HIPROC': 0x7FFFFFFF +} + +elf_sh_type = { + 'SHT_NULL': 0, + 'SHT_PROGBITS': 1, + 'SHT_SYMTAB': 2, + 'SHT_STRTAB': 3, + 'SHT_RELA': 4, + 'SHT_HASH': 5, + 'SHT_DYNAMIC': 6, + 'SHT_NOTE': 7, + 'SHT_NOBITS': 8, + 'SHT_REL': 9, + 'SHT_SHLIB': 10, + 'SHT_DYNSYM': 11, + 'SHT_INIT_ARRAY': 14, + 'SHT_FINI_ARRAY': 15, + 'SHT_PREINIT_ARRAY': 16, + 'SHT_GROUP': 17, + 'SHT_SYMTAB_SHNDX': 18, + 'SHT_LOOS': 0x60000000, + 'SHT_HIOS': 0x6fffffff, + 'SHT_LOPROC': 0x70000000, + 'SHT_HIPROC': 0x7fffffff, + 'SHT_LOUSER': 0x80000000, + 'SHT_HIUSER': 0xffffffff, + # OS specific types + 'SHT_SUNW_dof': 0x6FFFFFF4, + 'SHT_SUNW_cap': 0x6FFFFFF5, + 'SHT_SUNW_SIGNATURE': 0x6FFFFFF6, + 'SHT_SUNW_ANNOTATE': 0x6FFFFFF7, + 'SHT_GNU_LIBLIST': 0x6ffffff7, # dup + 'SHT_SUNW_DEBUGSTR': 0x6FFFFFF8, + 'SHT_SUNW_DEBUG': 0x6FFFFFF9, + 'SHT_SUNW_move': 0x6FFFFFFA, + 'SHT_SUNW_COMDAT': 0x6FFFFFFB, + 'SHT_SUNW_syminfo': 0x6FFFFFFC, + 'SHT_GNU_verdef': 0x6ffffffd, + 'SHT_SUNW_verdef': 0x6ffffffd, # dup + 'SHT_GNU_verneed': 0x6ffffffe, + 'SHT_SUNW_verneed': 0x6ffffffe, # dup + 'SHT_GNU_versym': 0x6fffffff, + 'SHT_SUNW_versym': 0x6fffffff, # dup + # Processor specific types + 'SHT_IA_64_EXT': 0x70000000, + 'SHT_IA_64_UNWIND': 0x70000001 +} + +elf_sh_flags = { + 'SHF_WRITE': 0x1, + 'SHF_ALLOC': 0x2, + 'SHF_EXECINSTR': 0x4, + 'SHF_MERGE': 0x10, + 'SHF_STRINGS': 0x20, + 'SHF_INFO_LINK': 0x40, + 'SHF_LINK_ORDER': 0x80, + 'SHF_OS_NONCONFORMING': 0x100, + 'SHF_GROUP': 0x200, + 'SHF_TLS': 0x400, + 'SHF_MASKOS': 0x0ff00000, + 'SHF_MASKPROC': 0xf0000000 +} + +elf_st_bindings = {'STB_LOCAL': 0, 'STB_GLOBAL': 1, 'STB_WEAK': 2} + +elf_st_flags = {'SHF_WRITE': 1, 'SHF_ALLOC': 2, 'SHF_EXECINSTR': 4} + +elf_st_types = { + 'STT_NOTYPE': 0, + 'STT_OBJECT': 1, + 'STT_FUNC': 2, + 'STT_SECTION': 3, + 'STT_FILE': 3 +} + +elf_syminfo_flags = { + 'SYMINFO_FLG_DIRECT': 1, + 'SYMINFO_FLG_PASSTHRU': 2, + 'SYMINFO_FLG_FILTER': 2, # dup + 'SYMINFO_FLG_COPY': 4, + 'SYMINFO_FLG_LAZYLOAD': 8, + 'SYMINFO_FLG_DIRECTBIND': 0x10, + 'SYMINFO_FLG_NOEXTDIRECT': 0x20, + 'SYMINFO_FLG_AUXILIARY': 0x40 +} + +elf_syminfo_boundto_types = { + 'SYMINFO_BT_SELF': 0xFFFF, + 'SYMINFO_BT_PARENT': 0xFFFE, + 'SYMINFO_BT_NONE': 0xFFFD, + 'SYMINFO_BT_EXTERN': 0xFFFC +} + +# Defaults + +defaults = { + # ElfDyn structures + 'd_tag': 'DT_NULL', + 'd_un': '0', + + # fields in an ELf Executable Header + 'e_ehsize': None, + 'e_entry': '0', + 'e_flags': ['0'], + 'e_ident': None, + 'e_machine': 'EM_NONE', + 'e_phentsize': None, + 'e_phnum': None, + 'e_phoff': None, + 'e_shentsize': None, + 'e_shnum': None, + 'e_shoff': None, + 'e_shstrndx': None, + 'e_type': 'ET_NONE', + 'e_version': 'EV_CURRENT', + # e_ident bytes + 'ei_class': 'ELFCLASS32', + 'ei_data': 'ELFDATA2LSB', + 'ei_version': 'EV_CURRENT', + 'ei_osabi': 'ELFOSABI_NONE', + 'ei_abiversion': '0', + # File-wide defaults + 'elf_fillchar': '0', + # Elf Notes + 'n_namesz': None, + 'n_descsz': None, + 'n_type': '0', + 'n_data': ["", ""], + # Phdr + 'p_align': '1', + 'p_filesz': '0', + 'p_memsz': '0', + 'p_flags': ['0'], + 'p_offset': '0', + 'p_paddr': '0', + 'p_type': 'PT_NULL', + 'p_vaddr': '0', + # Shdr + 'sh_addr': '0', + 'sh_addralign': None, + 'sh_data': [], + 'sh_entsize': '0', + 'sh_flags': ['0'], + 'sh_info': '0', + 'sh_index': None, + 'sh_link': '0', + 'sh_name': '0', + 'sh_offset': None, + 'sh_size': None, + 'sh_type': 'SHT_NULL', + 'sh_word_size': 32, + # Verdaux + 'vda_name': 0, + 'vda_next': 0, + # Verdef + 'vd_version': 1, + 'vd_flags': 0, + 'vd_ndx': 0, + 'vd_cnt': 0, + 'vd_hash': 0, + 'vd_aux': 0, + 'vd_next': 0, + # Vernaux + 'vna_hash': 0, + 'vna_flags': 0, + 'vna_other': 0, + 'vna_name': 0, + 'vna_next': 0, + # Verneed + 'vn_version': 1, + 'vn_cnt': 0, + 'vn_file': 0, + 'vn_aux': 0, + 'vn_next': 0 +} + +# +# Module wide constants. +# + +ELFCLASS32 = elf_ei_class['ELFCLASS32'] +ELFDATA2LSB = elf_ei_data['ELFDATA2LSB'] +SHT_NOBITS = elf_sh_type['SHT_NOBITS'] +SHT_NULL = elf_sh_type['SHT_NULL'] +SHT_STRTAB = elf_sh_type['SHT_STRTAB'] +SHN_LORESERVE = 0xFF00 +SHN_XINDEX = 0xFFFF + +# +# Helper functions. +# + + +def get(d, key, default): + """Retrieve the value of 'key' from YAML dictionary 'd'. + + The return value is guaranteed to be not 'None'. + """ + v = d.get(key, default) + if v is None: + v = default + return v + + +def encode(d, key, default, mapping): + """Return the numeric value of d[key] in map 'mapping'.""" + + v = get(d, key, default) + try: + return mapping[v] + except KeyError: + return int(v) + + +def encode_flags(flags, m): + """Convert 'flags' to a single numeric value using mapping 'm'.""" + try: + v = int(flags) + return v + except: + pass + v = 0 + for f in flags: + try: + t = int(m[f]) + except KeyError: + t = int(f) + v |= t + return v + + +def check_dict(d, l, node=None): + """Check a dictionary for unknown keys.""" + unknown = [] + for k in d.keys(): + if k not in l: + unknown.append(k) + if len(unknown) > 0: + raise ElfError(node, "{tag} Unknown key(s) {key}".format( + tag=node.tag, key=unknown)) + + +def bounded_value(v, encoding): + """Return the value of 'v' bounded to the maximum size for a type.""" + if encoding == "H": + return (v & 0xFFFF) + elif encoding == "I": + return (v & 0xFFFFFFFF) + return v + + +# +# Helper classes. +# + + +class ElfStrTab: + """A ELF string table. + + This class manages strings in an ELF string table section. + """ + + def __init__(self, strs=None): + """Initialize a string table from a list of strings.""" + self.offset = 1 # reserve space for initial null byte + self.htab = {} + if isinstance(strs, str): # one string + self.add(strs) + elif isinstance(strs, list): # list of strings + for s in strs: + self.add(s) + + def add(self, s: str): + """Add a string to the string table. + + Returns the offset of the string in the ELF section.""" + try: + return self.lookup(s) + except KeyError: + self.htab[s] = offset = self.offset + self.offset += len(s) + 1 # Keep space for a NUL. + return offset + + def bits(self): + """Return the contents of an ELF string table.""" + + # Prepare the string table, ordered by string offset. + ls = [b""] # initial NUL + for (ss, oo) in sorted(self.htab.items(), key=operator.itemgetter(1)): + ls.append(bytes(ss, 'utf-8')) + return b"\000".join(ls) + b"\000" # Add trailing NULs + + def lookup(self, str): + """Return the ELF string table offset for string 'str'.""" + + return self.htab[str] + + +class ElfType: + """A base type for ELF type descriptors. + + Derived classes are expected to provide the following attributes: + + 'fields' -- a list of 4-typles (name, fn, lsz, msz). + + 'name' is the name of a field in the ELF structure. + + 'fn' is a convertor function, one of the functions + 'do_{long,encode,flags}' below. + + 'msz' and 'lsz' provide the appropriate sizes when + generating a binary representation of the type. + """ + + fields = None + + def __init__(self, d, node): + """Initialize an ELF datatype from a YAML description. + + Arguments: + d -- a dictionary containing name/value pairs specified + in the text description. + node -- YAML parser node for this element. + """ + + keys = [t[0] for t in self.fields] + check_dict(d, keys, node) + for f in self.fields: + name = f[0] + fn = f[1] + try: + v = fn(d, name) + setattr(self, f[0], v) + except: + raise ElfError( + node, "key: {key!r} value: {value!r} unrecognized.".format( + key=name, value=d[name])) + self._n = node # Save YAML node and associated value + self._d = d # for error reporting. + + def __getitem__(self, attrib): + """Allow an ELF type to be treated like a dictionary.""" + + return getattr(self, attrib) + + def bits(self, formatchar, elfclass): + """Convert an ELF type to its file representation.""" + + format, args = self.getfields(elfclass) + return struct.pack(formatchar + format, *args) + + def formatstring(self, elfclass): + """Return the format string for this type.""" + + if elfclass == ELFCLASS32: + n = 2 + else: + n = 3 + return "".join([t[n] for t in self.fields]) + + def content(self, elfclass): + """Return a tuple containing the values for an ELF type.""" + + a = [] + if elfclass == ELFCLASS32: + n = 2 + else: + n = 3 + for t in self.fields: + field_encoding = t[n] + if field_encoding != "": + v = getattr(self, t[0]) + a.append(bounded_value(v, field_encoding)) + return tuple(a) + + def getfields(self, elfclass): + """Describe the binary layout of the type. + + Return a tuple (formatstring, *args) describing the + desired binary layout in the manner of the 'struct' + python library module. + """ + + return (self.formatstring(elfclass), self.content(elfclass)) + + def layout(self, offset, elf): + """Perform any layout-time translation for an ELF type.""" + + return offset + + def size(self, elfclass): + """Return the size of the type in bytes. + + The size returned is independent of the alignment needs of + the type. + """ + + format = self.formatstring(elfclass) + sz = 0 + for f in format: + if f == "B": + sz += 1 + elif f == "H": + sz += 2 + elif f == "I": + sz += 4 + elif f == "Q": + sz += 8 + elif f == "": + pass + else: + raise TypeError("Invalid format char {char!r}.".format(char=f)) + return sz + + +# +# Translation helper functions. +# + + +def do_string(d, n): + """Convert a YAML value to a Python string.""" + + v = get(d, n, defaults[n]) + if v: + return str(v) + return v + + +def do_long(d, n): + """Convert a YAML value to a Python 'long'.""" + + v = get(d, n, defaults[n]) + if v: + return int(v) + return v + + +def do_copy(d, n): + """Copy a YAML value without conversion.""" + + v = get(d, n, defaults[n]) + return v + + +def do_encode(xlate): + """Translate a YAML value according to mapping 'xlate'.""" + + return lambda d, n, xl=xlate: encode(d, n, defaults[n], xl) + + +def do_flags(xlate): + """Translate a list of flags according to mapping 'xlate'.""" + + return lambda d, n, xl=xlate: encode_flags(get(d, n, defaults[n]), xl) + + +# +# Definitions of ELF types. +# + + +class ElfCap(ElfType): + """A representation of an ELF Cap structure. + + YAML tag: !Cap + """ + + fields = [ + # -YAPF- + ('c_tag', do_encode(elf_cap_tag), "I", "Q"), + ('c_un', do_long, "I", "Q") + ] + + def __init__(self, cap, node): + ElfType.__init__(self, cap, node) + + +class ElfDyn(ElfType): + """A representation of an ELF Dyn structure. + + YAML tag: !Dyn + """ + + fields = [ + # -YAPF- + ('d_tag', do_encode(elf_d_tag), "I", "Q"), + ('d_un', do_long, "I", "Q") + ] + + def __init__(self, d, node): + ElfType.__init__(self, d, node) + + +class ElfEhdrIdent(ElfType): + """A representation for the 'ident' field of an ELF Ehdr. + + YAML tag: !Ident + """ + + fields = [ + # -YAPF- + ('ei_class', do_encode(elf_ei_class), "B", "B"), + ('ei_data', do_encode(elf_ei_data), "B", "B"), + ('ei_version', do_encode(elf_ei_version), "B", "B"), + ('ei_osabi', do_encode(elf_ei_osabi), "B", "B"), + ('ei_abiversion', do_long, "B", "B") + ] + + def __init__(self, ei, node): + ElfType.__init__(self, ei, node) + + def bits(self, format, elfclass): + f, args = self.getfields(elfclass) + s = b"\x7FELF" + s += struct.pack(f + 'xxxxxxx', *args) + return s + + +class ElfEhdr(ElfType): + """A representation of an ELF Executable Header. + + YAML tag: !Ehdr + """ + + fields = [ + # -YAPF- + ('e_ident', do_copy, "", ""), + ('e_type', do_encode(elf_ehdr_type), "H", "H"), + ('e_machine', do_encode(elf_ehdr_machine), "H", "H"), + ('e_version', do_encode(elf_ei_version), "I", "I"), + ('e_entry', do_long, "I", "Q"), + ('e_phoff', do_long, "I", "Q"), + ('e_shoff', do_long, "I", "Q"), + ('e_flags', do_flags(elf_ehdr_flags), "I", "I"), + ('e_ehsize', do_long, "H", "H"), + ('e_phentsize', do_long, "H", "H"), + ('e_phnum', do_long, "H", "H"), + ('e_shentsize', do_long, "H", "H"), + ('e_shnum', do_long, "H", "H"), + ('e_shstrndx', do_copy, "H", "H") + ] + + def __init__(self, eh, node): + """Initialize an Ehdr structure. + + If an 'ident' structure was not specified as part of + the YAML description, initialize it explicitly. + """ + + ElfType.__init__(self, eh, node) + if self.e_ident is None: + self.e_ident = ElfEhdrIdent({}, node) + + def layout(self, offset, elf): + """Layout an ELF Ehdr. + + This method will fill in defaults and/or compute + values for fields that were not specified in the YAML + description. + """ + + elfclass = elf.elfclass() + if elfclass == ELFCLASS32: + e_ehsize = 52 + e_phentsize = 32 + e_shentsize = 40 + alignment = 4 + else: # 64 bit sizes + e_ehsize = 64 + e_phentsize = 56 + e_shentsize = 64 + alignment = 8 + + if self.e_ehsize is None: + self.e_ehsize = e_ehsize + + # Compute e_phnum if needed. + if self.e_phnum is None: + self.e_phnum = len(elf.elf_phdrtab) + + # Compute a value for the e_phentsize field. + if self.e_phentsize is None: + if self.e_phnum: + self.e_phentsize = e_phentsize + else: + self.e_phentsize = 0 + + # Set the e_shentsize field. + if self.e_shentsize is None: + self.e_shentsize = e_shentsize + + # The program header defaults to just after the ELF header. + if self.e_phoff is None: + if self.e_phnum > 0: + self.e_phoff = \ + (self.e_ehsize + (alignment - 1)) & \ + ~(alignment - 1) + else: + self.e_phoff = 0 + + # compute e_shnum + self.nsections = elf.elf_sections.get_shnum() + if self.nsections > 0: + if self.e_shstrndx is None: + self.e_shstrndx = '.shstrtab' + if isinstance(self.e_shstrndx, str): + self.e_shstrndx = \ + elf.elf_sections.get_index(self.e_shstrndx) + elif isinstance(self.e_shstrndx, int): + pass + else: + raise ElfError( + self._n, + "Unparseable e_shstrndx field: {v!r}".format( + v=self.e_shstrndx)) + if self.e_shstrndx is None: + raise ElfError(self._n, + 'Cannot determine section ' + \ + 'name string table index: {v!r}'.format(v=self.e_shstrndx)) + else: + if self.e_shstrndx is None: + self.e_shstrndx = 0 + + if self.e_shnum is None: + self.e_shnum = self.nsections + + # section data comes after the program header by default. The + # section header table is placed after all section data. + + if self.e_phnum > 0: + offset = self.e_phoff + self.e_phnum * self.e_phentsize + else: + offset = self.e_ehsize + offset = elf.elf_sections.layout(offset, elf) + if self.e_shoff is None: + if self.nsections > 0: + self.e_shoff = (offset + (alignment-1)) & \ + ~(alignment-1) + else: + self.e_shoff = 0 + + if self.nsections >= SHN_LORESERVE: + elf.elf_sections.set_extended_shnum(self.nsections) + self.e_shnum = 0 + if self.e_shstrndx >= SHN_XINDEX: + elf.elf_sections.set_extended_shstrndx(self.e_shstrndx) + self.e_shstrndx = SHN_XINDEX + + def bits(self, formatchar, elfclass): + """Return the file representation of an Elf Ehdr.""" + + s = self.e_ident.bits(formatchar, elfclass) + s += ElfType.bits(self, formatchar, elfclass) + + return s + + +class ElfLong: + """Wrapper around a python Int/Long.""" + + def __init__(self, v): + self._v = int(v) + + def bits(self, formatchar, elfclass): + """Return the file representation for this object. + + Depending on the number of bits needed to represent + the number, the returned bits would be either 4 or + 8 bytes wide. + """ + + if self._v > 0xFFFFFFFF: + f = formatchar + "Q" + else: + f = formatchar + "I" + return struct.pack(f, self._v) + + +class ElfMove(ElfType): + """A representation of an Elf Move type. + + YAML tag: !Move + """ + + fields = [ + # -YAPF- + ('m_value', do_long, "I", "I"), + ('m_info', do_long, "I", "Q"), + ('m_poffset', do_long, "I", "Q"), + ('m_repeat', do_long, "H", "H"), + ('m_stride', do_long, "H", "H") + ] + + def __init__(self, move, node): + ElfType.__init__(self, move, node) + + +class ElfNote(ElfType): + """A representation of an Elf Note type. + + YAML tag: !Note + + The data in the note is held in YAML node named 'n_data' which is + a pair of strings, one for the note's name field and one for the + description. + + If the fields 'n_namesz' and 'n_descz' aren't specified, they + are computed from the contents of 'n_data'. + """ + + fields = [ + # -YAPF- + ('n_namesz', do_long, "I", "I"), + ('n_descsz', do_long, "I", "I"), + ('n_type', do_long, "I", "I"), + ('n_data', do_copy, "", "") + ] + + def __init__(self, note, node): + ElfType.__init__(self, note, node) + self._note = note + + def layout(self, offset, elfclass): + if len(self.n_data) != 2: + raise ElfError(node, "Note data not a pair of strings.") + + for nd in self.n_data: + if isinstance(nd, ElfType): + nd.layout(offset, elfclass) + + if self.n_namesz is None: + self.n_namesz = len(self.n_data[0]) + if self.n_descsz is None: + self.n_descsz = len(self.n_data[1]) + + def bits(self, format, elfclass): + b = ElfType.bits(self, format, elfclass) + nbits = str(self.n_data[0]) + dbits = str(self.n_data[1]) + return b + nbits + dbits + + +class ElfPhdr(ElfType): + """A representation of an ELF Program Header Table entry. + + YAML tag: !Phdr + """ + + fields = [ + # NOTE: class-dependent field ordering + # -YAPF- + ('p_align', do_long), + ('p_filesz', do_long), + ( + 'p_flags', + do_flags(elf_ph_flags), + ), + ('p_memsz', do_long), + ('p_offset', do_long), + ('p_paddr', do_long), + ('p_type', do_encode(elf_ph_type)), + ('p_vaddr', do_long) + ] + + def __init__(self, ph, node): + ElfType.__init__(self, ph, node) + + def to_string(self): + """Helper during debugging.""" + + s = "Phdr(type:%(p_type)d,flags:%(p_flags)d," \ + "offset:%(p_offset)ld,vaddr:%(p_vaddr)ld," \ + "paddr:%(p_paddr)ld,filesz:%(p_filesz)ld," \ + "memsz:%(p_memsz)ld)" % self + return s + + def bits(self, formatchar, elfclass): + """Return the file representation of a Phdr.""" + + f = formatchar + # Phdr structures are laid out in a class-dependent way + if elfclass == ELFCLASS32: + f += "IIIIIIII" + s = struct.pack(f, self.p_type, self.p_offset, self.p_vaddr, + self.p_paddr, self.p_filesz, self.p_memsz, + self.p_flags, self.p_align) + else: + f += "IIQQQQQQ" + s = struct.pack(f, self.p_type, self.p_flags, self.p_offset, + self.p_vaddr, self.p_paddr, self.p_filesz, + self.p_memsz, self.p_align) + return s + + +class ElfRel(ElfType): + """A representation of an ELF Rel type. + + YAML tag: !Rel + """ + + fields = [ + # -YAPF- + ('r_offset', do_long, "I", "Q"), + ('r_info', do_long, "I", "Q") + ] + + def __init__(self, rel, node): + ElfType.__init__(self, rel, node) + + +class ElfRela(ElfType): + """A representation of an ELF Rela type. + + YAML tag: !Rela + """ + + fields = [ + # -YAPF- + ('r_offset', do_long, "I", "Q"), + ('r_info', do_long, "I", "Q"), + ('r_addend', do_long, "I", "Q") + ] + + def __init__(self, rela, node): + ElfType.__init__(self, rela, node) + + +class ElfSection(ElfType): + """A representation of an ELF Section. + + YAML tag: !Section + + A section description consists of the fields that make up an ELF + section header entry with the following additional fields: + + - Field 'sh_data' contains the data associated with this section. + 'sh_data' may be a YAML string, or can be a YAML list of items + that comprise the content of the section. + - Field 'sh_index' can be used to manually set the section's index. + - Field 'sh_word_size' specifies the word size to use for data in + integer literal form. The value of this field can be 32 or 64. + """ + + fields = [ + # -YAPF- + ('sh_name', do_string, "I", "I"), + ('sh_type', do_encode(elf_sh_type), "I", "I"), + ('sh_flags', do_flags(elf_sh_flags), "I", "Q"), + ('sh_addr', do_long, "I", "Q"), + ('sh_offset', do_long, "I", "Q"), + ('sh_size', do_long, "I", "Q"), + ('sh_link', do_long, "I", "I"), + ('sh_info', do_long, "I", "I"), + ('sh_addralign', do_copy, "I", "Q"), + ('sh_entsize', do_long, "I", "Q"), + ('sh_data', do_copy, "", ""), + ('sh_index', do_long, "", ""), + ('sh_word_size', do_long, "", ""), + ] + + def __init__(self, shdr, node): + """Initialize a section descriptor.""" + + ElfType.__init__(self, shdr, node) + if not isinstance(self.sh_data, list): + self.sh_data = list(self.sh_data) + if self.sh_addralign is None: + if self.sh_type == SHT_NULL or self.sh_type == SHT_NOBITS: + self.sh_addralign = 0 + else: + self.sh_addralign = 1 + else: + if (self.sh_addralign == 0 or \ + (self.sh_addralign & (self.sh_addralign - 1)) != 0): + raise ElfError(node, "'sh_addralign' not a power of two.") + if self.sh_word_size != 32 and self.sh_word_size != 64: + raise ElfError( + node, + "unsupported 'sh_word_size' value: {v!r}".format( + v=self.sh_word_size)) + self._data = None # 'cache' of translated data + self._strtab = None + + def to_string(self): + """Helper function during debugging.""" + + return "Section(name:%(sh_name)s,type:%(sh_type)d," \ + "flags:%(sh_flags)x,addr:%(sh_addr)d,"\ + "offset:%(sh_offset)d,size:%(sh_size)d," \ + "link:%(sh_link)d,info:%(sh_info)d," \ + "addralign:%(sh_addralign)d,entsize:%(sh_entsize)d)" % \ + self + + def make_strtab(self): + """Create a string table from section contents.""" + + self._strtab = ElfStrTab(self.sh_data) + + def string_to_index(self, name): + """Convert 'name' to an offset inside a string table. + + Only valid for sections of type SHT_STRTAB.""" + + if self._strtab: + return self._strtab.lookup(name) + raise ElfError( + None, "Cannot translate {name!r} to an index.".format(name=name)) + + def bits(self, formatchar, elfclass): + raise AssertionError("Section objects should use " \ + "databits() or headerbits()") + + def layout(self, offset, elf): + """Prepare an ELF section for output.""" + + if isinstance(self.sh_name, str): + # first try convert it to a long + try: + self.sh_name = int(self.sh_name) + except ValueError: # lookup in string table + try: + self.sh_name = \ + elf.section_name_index(self.sh_name) + except KeyError: + raise ElfError( + self._n, + "Section name {name!r} not in string table.".format( + name=self.sh_name)) + # give a chance for the contents of a section to xlate strings + for d in self.sh_data: + if isinstance(d, ElfType): + d.layout(offset, elf) + # compute the space used by the section data + self._data = self.databits(elf.formatchar(), elf.elfclass()) + + align = self.sh_addralign + if align == 0: + align = 1 + if self.sh_type == SHT_NULL or self.sh_type == SHT_NOBITS: + isnulltype = 1 + else: + isnulltype = 0 + + offset = (offset + (align - 1)) & ~(align - 1) + if self.sh_size is None: + if isnulltype: + self.sh_size = 0 + else: + self.sh_size = len(self._data) + if self.sh_offset is None: + if isnulltype: + self.sh_offset = 0 + else: + self.sh_offset = offset + if isnulltype: # ignore bits for null types + return offset + return offset + len(self._data) + + def databits(self, formatchar, elfclass): + """Return the contents of a section.""" + + if self._data: + return self._data + # special-case string table handling + if self.sh_type == SHT_STRTAB: + return self._strtab.bits() + # 'normal' section + s = b"" + for d in self.sh_data: + if isinstance(d, ElfType): + s += d.bits(formatchar, elfclass) + elif isinstance(d, int): + word_size_char = "I" + if self.sh_word_size == 64: + word_size_char = "Q" + s += struct.pack(formatchar + word_size_char, d) + else: + s += bytes(d, 'utf-8') + return s + + def headerbits(self, formatchar, elfclass): + """Return the file representation of the section header.""" + + return ElfType.bits(self, formatchar, elfclass) + + +class ElfSym(ElfType): + """A representation for an ELF Symbol type. + + YAML tag: !Sym + """ + + fields = [ # NOTE: class-dependent layout. + # -YAPF- + ('st_info', do_long, "B", "B"), + ('st_name', do_string, "I", "I"), + ('st_other', do_long, "B", "B"), + ('st_shndx', do_string, "H", "H"), + ('st_size', do_long, "I", "Q"), + ('st_value', do_long, "I", "Q") + ] + + def __init__(self, sym, node): + ElfType.__init__(self, sym, node) + + def bits(self, format, elfclass): + """Return the file representation for an ELF Sym.""" + + if elfclass == ELFCLASS32: + s = struct.pack(format + "IIIBBH", self.st_name, self.st_value, + self.st_size, self.st_info, self.st_other, + self.st_shndx) + else: + s = struct.pack(format + "IBBHQQ", self.st_name, self.st_info, + self.st_other, self.st_shndx, self.st_value, + self.st_size) + return s + + def layout(self, offset, elf): + """Perform layout-time conversions for an ELF Sym. + + String valued fields are converted to offsets into + string tables. + """ + + if isinstance(self.st_shndx, str): + self.st_shndx = \ + elf.elf_sections.get_index(self.st_shndx) + if self.st_shndx is None: + raise ElfError(self._n, "Untranslateable 'st_shndx' " + \ + "value {value!r}.".format(value=self.st_shndx)) + + if isinstance(self.st_name, str): + try: + strtab = \ + elf.elf_sections[self.st_shndx]._strtab + except IndexError: + raise ElfError(self._n, "'st_shndx' out of range") + if strtab is None: + raise ElfError(self._n, "'st_shndx' not of type STRTAB.") + + try: + self.st_name = strtab.lookup(self.st_name) + except KeyError: + raise ElfError( + self._n, + "unknown string {string!r}".format(string=self.st_name)) + return offset + + +class ElfSyminfo(ElfType): + """A representation of an ELF Syminfo type. + + YAML tag: !Syminfo + """ + + fields = [ + # -YAPF- + ('si_boundto', do_encode(elf_syminfo_boundto_types), "H", "H"), + ('si_flags', do_flags(elf_syminfo_flags), "H", "H") + ] + + def __init__(self, syminfo, node): + ElfType.__init__(self, syminfo, node) + + +class ElfVerdaux(ElfType): + """A representation of an ELF Verdaux type.""" + + fields = [ + # -YAPF- + ('vda_name', do_long, "I", "I"), + ('vda_next', do_long, "I", "I") + ] + + def __init__(self, verdaux, node): + ElfType.__init__(self, verdaux, node) + + +class ElfVerdef(ElfType): + """A representation of an ELF Verdef type.""" + + fields = [ + # -YAPF- + ('vd_version', do_long, "H", "H"), + ('vd_flags', do_long, "H", "H"), + ('vd_ndx', do_long, "H", "H"), + ('vd_cnt', do_long, "H", "H"), + ('vd_hash', do_long, "I", "I"), + ('vd_aux', do_long, "I", "I"), + ('vd_next', do_long, "I", "I") + ] + + def __init__(self, verdef, node): + ElfType.__init__(self, verdef, node) + + +class ElfVernaux(ElfType): + """A representation of an ELF Vernaux type.""" + + fields = [ + # -YAPF- + ('vna_hash', do_long, "I", "I"), + ('vna_flags', do_long, "H", "H"), + ('vna_other', do_long, "H", "H"), + ('vna_name', do_long, "I", "I"), + ('vna_next', do_long, "I", "I") + ] + + def __init__(self, vernaux, node): + ElfType.__init__(self, vernaux, node) + + +class ElfVerneed(ElfType): + """A representation of an ELF Verneed type.""" + + fields = [ + # -YAPF- + ('vn_version', do_long, "H", "H"), + ('vn_cnt', do_long, "H", "H"), + ('vn_file', do_long, "I", "I"), + ('vn_aux', do_long, "I", "I"), + ('vn_next', do_long, "I", "I") + ] + + def __init__(self, verneed, node): + ElfType.__init__(self, verneed, node) + + +# +# Aggregates +# + + +class ElfPhdrTable: + """A representation of an ELF Program Header Table. + + A program header table is a list of program header entry sections. + """ + + def __init__(self, phdr): + """Initialize a program header table object. + + Argument 'phdr' is a list of parsed ElfPhdr objects. + """ + + self.pht_data = [] + for ph in phdr: + if isinstance(ph, dict): + ph = ElfPhdr(ph) + elif not isinstance(ph, ElfPhdr): + raise ElfError(ph.node, "Program Header Table " + "contains non header data.") + self.pht_data.append(ph) + + def bits(self, formatchar, elfclass): + """Return the file representation of the Phdr table.""" + + s = "" + for d in self.pht_data: + s += d.bits(formatchar, elfclass) + return s + + def __len__(self): + """Return the number of program header table entries.""" + + return len(self.pht_data) + + def __iter__(self): + """Return an iterator for traversing Phdr entries.""" + + return self.pht_data.__iter__() + + +class ElfSectionList: + """A list of ELF sections.""" + + def __init__(self, shlist): + """Initialize an ELF section list. + + Argument 'shlist' is a list of parser ElfSection + objects. + """ + + self.shl_sections = shlist + self.shl_sectionnames = [] + self.shl_nentries = len(shlist) + + for sh in shlist: + if not isinstance(sh, ElfSection): + raise ElfError(None, """Section 'sections' contains + unrecognized data.""") + if sh.sh_index is not None: + if self.shl_nentries <= sh.sh_index: + self.shl_nentries = sh.sh_index + 1 + self.shl_sectionnames.append((sh.sh_name, sh.sh_index)) + if sh.sh_type == SHT_STRTAB: # a string table + sh.make_strtab() + + def __len__(self): + """Return the number of ELF sections.""" + + return len(self.shl_sections) + + def __iter__(self): + """Iterate through ELF sections.""" + + return self.shl_sections.__iter__() + + def __getitem__(self, ind): + """Retrieve the ELF section at index 'ind'.""" + + try: + return self.shl_sections[ind] + except IndexError: + for sh in self.shl_sections: + if sh.sh_index == ind: + return sh + raise IndexError("no section at index {index}".format(index=ind)) + + def layout(self, offset, elf): + """Compute the layout for section.""" + + if len(self.shl_sections) == 0: + return 0 + for sh in self.shl_sections: # layout sections + offset = sh.layout(offset, elf) + return offset + + def get_index(self, name): + """Return the section index for section 'name', or 'None'.""" + + c = 0 + for (n, i) in self.shl_sectionnames: + if n == name: + if i is None: + return c + else: + return i + c += 1 + return None + + def get_shnum(self): + """Retrieve the number of sections in this container.""" + + return self.shl_nentries + + def set_extended_shnum(self, shnum): + """Set the extended section number.""" + + sh = self.shl_sections[0] + sh.sh_size = shnum + + def set_extended_shstrndx(self, strndx): + """Set the extended string table index.""" + + sh = self.shl_sections[0] + sh.sh_link = strndx + + +class Elf: + """A representation of an ELF object.""" + + def __init__(self, yamldict, ehdr, phdrtab, sections): + self._d = yamldict + self._n = None + self.elf_ehdr = ehdr + self.elf_phdrtab = phdrtab + self.elf_sections = sections + self.elf_fillchar = int( + get(yamldict, 'elf_fillchar', defaults['elf_fillchar'])) + + def byteorder(self): + """Return the byteorder for this ELF object.""" + return self.elf_ehdr.e_ident.ei_data + + def elfclass(self): + """Return the ELF class for this ELF object.""" + return self.elf_ehdr.e_ident.ei_class + + def formatchar(self): + """Return the format character corresponding to the ELF + byteorder.""" + + if self.byteorder() == ELFCLASS32: + return "<" + else: + return ">" + + def layout(self): + """Compute a file layout for this ELF object and update + internal data structures.""" + + self.elf_ehdr.layout(0, self) + + def section_name_index(self, name): + """Compute index of section 'name' in the section name string table.""" + + strndx = self.elf_ehdr.e_shstrndx + if strndx is None: + return None + return self.elf_sections[strndx].string_to_index(name) + + def write(self, fn): + """Write out the file representation of an ELF object. + + Argument 'fn' denotes the destination.""" + + of = io.open(fn, 'wb') + + formatchar = self.formatchar() + elfclass = self.elfclass() + + # Write out the header + of.write(self.elf_ehdr.bits(formatchar, elfclass)) + + # Write out the program header table if present + if self.elf_phdrtab: + self.reposition(of, self.elf_ehdr.e_phoff) + for ph in self.elf_phdrtab: + of.write(ph.bits(formatchar, elfclass)) + # Write out the sections + if self.elf_sections: + # First the contents of the sections + for sh in self.elf_sections: + if sh.sh_type == SHT_NULL or sh.sh_type == SHT_NOBITS: + continue + self.reposition(of, sh.sh_offset) + of.write(sh.databits(formatchar, elfclass)) + # Then the header table + self.reposition(of, self.elf_ehdr.e_shoff) + for sh in self.elf_sections: + if sh.sh_index: + new_offset = sh.sh_index * self.elf_ehdr.e_shentsize + \ + self.elf_ehdr.e_shoff + self.reposition(of, new_offset) + of.write(sh.headerbits(formatchar, elfclass)) + of.close() + + def reposition(self, f, offset): + """Reposition file `f' to offset `offset', filling gaps with + the configured fill character as needed.""" + + pos = f.tell() + if offset == pos: + return + if offset < pos or (offset > pos and self.elf_fillchar == 0): + f.seek(offset, 0) + return + s = ("{fillchar}".format(fillchar=self.elf_fillchar) * (offset - pos)) + f.write(s) + + +# +# YAML Parser configuration and helpers. +# + +yaml_tags = [ + # -YAPF- + ('!Cap', ElfCap), + ('!Dyn', ElfDyn), + ('!Ehdr', ElfEhdr), + ('!Ident', ElfEhdrIdent), + ('!Move', ElfMove), + ('!Note', ElfNote), + ('!Phdr', ElfPhdr), + ('!Rel', ElfRel), + ('!Rela', ElfRela), + ('!Section', ElfSection), + ('!Sym', ElfSym), + ('!Syminfo', ElfSyminfo), + ('!Verdaux', ElfVerdaux), + ('!Verdef', ElfVerdef), + ('!Vernaux', ElfVernaux), + ('!Verneed', ElfVerneed) +] + + +def init_parser(): + for t in yaml_tags: + yaml.add_constructor(t[0], # lamdba: loader, node, class + lambda l, n, c=t[1]: \ + c(l.construct_mapping(n, deep=True), n)) + + +def make_elf(yd): + """Convert a YAML description `yd' of an ELF file into an + ELF object.""" + + try: + eh = yd['ehdr'] + except KeyError: + eh = ElfEhdr({}, None) + + phdrtab = ElfPhdrTable(get(yd, 'phdrtab', {})) + sectionlist = ElfSectionList(get(yd, 'sections', {})) + + return Elf(yd, eh, phdrtab, sectionlist) + + +# +# MAIN +# + +if __name__ == '__main__': + parser = optparse.OptionParser( + usage=usage, version=version, description=description) + parser.add_option( + "-o", + "--output", + dest="output", + help="write output to FILE [default: %default]", + metavar="FILE", + default="a.out") + parser.add_option( + "-N", + "--no-shstrtab", + dest="do_shstrtab", + help="do not create a string table section for " + "section names if missing", + action="store_false", + metavar="BOOLEAN", + default=True) + parser.add_option( + "-U", + "--no-shnundef", + dest="do_shnundef", + help="do not create a section header for index " + "SHN_UNDEF if missing", + action="store_false", + metavar="BOOLEAN", + default=True) + + (options, args) = parser.parse_args() + + if len(args) > 1: + parser.error("only one input-file must be specified") + + try: + if args: + stream = io.open(args[0], 'r') + else: + stream = sys.stdin + except IOError as err: + parser.error("cannot open stream: {err}".format(err=err)) + + init_parser() + + try: + elf = make_elf(yaml.load(stream, Loader=yaml.Loader)) + elf.layout() + elf.write(options.output) + except yaml.YAMLError as err: + parser.error("cannot parse stream: {err}".format(err=err)) + except ElfError as msg: + print(msg) + sys.exit(1) + +# Local Variables: +# mode: python +# tab-width: 4 +# py-indent-offset: 4 +# End: diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/common/Makefile new file mode 100644 index 0000000000..515b66326d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/Makefile @@ -0,0 +1,37 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +YAML_FILES= check_elf \ + getclass \ + ehdr \ + ehdr-malformed-1 \ + fsize \ + newehdr newscn newscn2 \ + phdr \ + rdwr rdwr1 rdwr2 \ + shdr \ + u1 \ + versioning \ + xlate xscn-1 xscn-2 xscn-3 \ + zerosection + +# Generate ELF binary files from their YAML desciptions. +.for f in ${YAML_FILES} +. for e in msb lsb +. for c in 32 64 +_YAML_ELF+= ${f}.${e}${c} +${f}.${e}${c}: ${f}.yaml + _E=`echo ${e} | tr '[a-z]' '[A-Z]'`; _C=`echo ${c} | tr '[a-z]' '[A-Z]'`; \ + cat ${.CURDIR}/${f}.yaml | sed -e "s/ELFDATANONE/ELFDATA2$${_E}/g" \ + -e "s/ELFCLASSNONE/ELFCLASS$${_C}/g" | \ + ${PYTHON} ${TS_ROOT}/bin/elfc -o ${.TARGET} +. endfor +. endfor +.endfor + +CLEANFILES+= ${_YAML_ELF} + +all: ${_YAML_ELF} + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/check_elf.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/check_elf.yaml new file mode 100644 index 0000000000..6c9bc06cd0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/check_elf.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +# $Id: check_elf.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_FREEBSD + ei_abiversion: 1 + ei_class: ELFCLASSNONE + e_type: ET_REL + e_machine: EM_NONE + e_version: EV_CURRENT + e_flags: [2, 1] + e_entry: 0xdeadbeef + e_phoff: 0 + e_shoff: 0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr-malformed-1.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr-malformed-1.yaml new file mode 100644 index 0000000000..d7c000f47a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr-malformed-1.yaml @@ -0,0 +1,23 @@ +%YAML 1.1 +# $Id$ +--- +ehdr: !Ehdr + e_ident: !Ident # e_ident[] members + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_SYSV + ei_abiversion: 0 + # other members + e_type: 0xFF03 + e_machine: 0x42 + e_version: 0xFFFFFFFF + e_entry: 0xFFFFFFFFFFFFFFFF + e_phoff: 0xFFFFFFFFFFFFFFFF + e_shoff: 0xFFFFFFFFFFFFFFFF + e_flags: [ 64, 8, 2, 1] + e_ehsize: 62 + e_phentsize: 228 + e_phnum: 0 + e_shentsize: 8192 + e_shnum: 0 + e_shstrndx: 0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr.yaml new file mode 100644 index 0000000000..cf4edf9da6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr.yaml @@ -0,0 +1,23 @@ +%YAML 1.1 +# $Id: ehdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident # e_ident[] members + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_FREEBSD + ei_abiversion: 1 + # other members + e_type: ET_REL + e_machine: 0x42 + e_version: EV_CURRENT + e_entry: 0xF0F0F0F0 + e_phoff: 0x0E0E0E0E + e_shoff: 0xD0D0D0D0 + e_flags: [ 64, 8, 2, 1] + e_ehsize: 0x0A0A + e_phentsize: 0xB0B0 + e_phnum: 0x0C0C + e_shentsize: 0xD0D0 + e_shnum: 0x0E0E + e_shstrndx: 0xF0F0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr_template.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr_template.m4 new file mode 100644 index 0000000000..31cacd4de5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/ehdr_template.m4 @@ -0,0 +1,417 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr_template.m4 3703 2019-03-02 20:41:03Z jkoshy $ + */ + +include(`elfts.m4') + +/* + * Boilerplate for testing the *_getehdr and *_newehdr APIs. + * + * This template is to be used as follows: + * + * `define(`TS_EHDRFUNC',`_getehdr')' (or `_newehdr') + * `define(`TS_EHDRSZ',`32')' (or `64') + * `include(`ehdr_template.m4')' + */ + +ifdef(`TS_EHDRFUNC',`',`errprint(`TS_EHDRFUNC was not defined')m4exit(1)') +ifdef(`TS_EHDRSZ',`',`errprint(`TS_EHDRSZ was not defined')m4exit(1)') +define(`TS_OTHERSIZE',`ifelse(TS_EHDRSZ,32,64,32)') + +define(`TS_ICFUNC',`elf'TS_EHDRSZ`'TS_EHDRFUNC) +define(`TS_EHDR',`Elf'TS_EHDRSZ`_Ehdr') +define(`TS_ICNAME',TS_ICFUNC) +define(`TS_ELFCLASS',`ELFCLASS'TS_EHDRSZ) + +IC_REQUIRES_VERSION_INIT(); + +/* + * Checks for the contents of an Ehdr structure. The values here must + * match that in the "ehdr.yaml" file in the test case directory. + */ + +#define CHECK_SIGFIELD(E,I,V) do { \ + if ((E)->e_ident[EI_##I] != (V)) \ + TP_FAIL(#I " value 0x%x != " \ + "expected 0x%x.", (E)->e_ident[EI_##I], \ + (V)); \ + } while (0) + +#define CHECK_SIG(E,ED,EC,EV,EABI,EABIVER) do { \ + if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \ + (E)->e_ident[EI_MAG1] != ELFMAG1 || \ + (E)->e_ident[EI_MAG2] != ELFMAG2 || \ + (E)->e_ident[EI_MAG3] != ELFMAG3) \ + TP_FAIL("incorrect ELF signature " \ + "(%x %x %x %x).", (E)->e_ident[EI_MAG0], \ + (E)->e_ident[EI_MAG1], (E)->e_ident[EI_MAG2],\ + (E)->e_ident[EI_MAG3]); \ + CHECK_SIGFIELD(E,CLASS, EC); \ + CHECK_SIGFIELD(E,DATA, ED); \ + CHECK_SIGFIELD(E,VERSION, EV); \ + CHECK_SIGFIELD(E,OSABI, EABI); \ + CHECK_SIGFIELD(E,ABIVERSION, EABIVER); \ + } while (0) + + +#define CHECK_FIELD(E,FIELD,VALUE) do { \ + if ((E)->e_##FIELD != (VALUE)) \ + TP_FAIL("field \"%s\" actual 0x%jx " \ + "!= expected 0x%jx.", #FIELD, \ + (uintmax_t) (E)->e_##FIELD, \ + (uintmax_t) (VALUE)); \ + } while (0) + +#define CHECK_EHDR(E,ED,EC) do { \ + CHECK_SIG(E,ED,EC,EV_CURRENT,ELFOSABI_FREEBSD,1); \ + CHECK_FIELD(E,type, ET_REL); \ + CHECK_FIELD(E,machine, 0x42); \ + CHECK_FIELD(E,version, EV_CURRENT); \ + CHECK_FIELD(E,entry, 0xF0F0F0F0); \ + CHECK_FIELD(E,phoff, 0x0E0E0E0E); \ + CHECK_FIELD(E,shoff, 0xD0D0D0D0); \ + CHECK_FIELD(E,flags, 64+8+2+1); \ + CHECK_FIELD(E,ehsize, 0x0A0A); \ + CHECK_FIELD(E,phentsize,0xB0B0); \ + CHECK_FIELD(E,phnum, 0x0C0C); \ + CHECK_FIELD(E,shentsize,0xD0D0); \ + CHECK_FIELD(E,shnum, 0x0E0E); \ + CHECK_FIELD(E,shstrndx, 0xF0F0); \ + } while (0) + +/* + * Check behaviour when passed a NULL argument. + */ + +void +tcNullArgument(void) +{ + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'(NULL) fails with ELF_E_ARGUMENT."); + + if (TS_ICFUNC`'(NULL) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + +/* + * Check behaviour when passed a pointer to a non-ELF object. + */ + +static char data[] = "This isn't an ELF file."; + +void +tcNonElfData(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'(non-ELF) fails with ELF_E_ARGUMENT."); + + TS_OPEN_MEMORY(e, data); + + if (TS_ICFUNC`'(e) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + + +/* + * Check behaviour when an object with a malformed ELF header. + */ + +static char badelftemplate[EI_NIDENT+1] = { + [EI_MAG0] = '\177', + [EI_MAG1] = 'E', + [EI_MAG2] = 'L', + [EI_MAG3] = 'F', + [EI_CLASS] = ELFCLASS64, + [EI_DATA] = ELFDATA2MSB, + [EI_NIDENT] = '@' +}; + +/* + * Verify that the version number is checked before other kinds + * of errors. + */ + +void +tcBadElfVersion(void) +{ + int err, result; + Elf *e; + TS_EHDR *eh; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'() with an unsupported version " + "fails with ELF_E_VERSION."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + + badelf[EI_VERSION] = EV_NONE; + badelf[EI_CLASS] = TS_ELFCLASS; + + TS_OPEN_MEMORY(e, badelf); + + result = TET_PASS; + + if ((eh = TS_ICFUNC`'(e)) != NULL || + (err = elf_errno()) != ELF_E_VERSION) + TP_FAIL("error=%d eh=%p.", err, (void *) eh); + + (void) elf_end(e); + + tet_result(result); +} + +void +tcBadElf(void) +{ + int err, result; + Elf *e; + TS_EHDR *eh; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'() on a malformed ELF file " + "fails with ELF_E_HEADER."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + badelf[EI_VERSION] = EV_CURRENT; + badelf[EI_CLASS] = TS_ELFCLASS; + + TS_OPEN_MEMORY(e, badelf); + + result = TET_PASS; + if ((eh = TS_ICFUNC`'(e)) != NULL || + (err = elf_errno()) != ELF_E_HEADER) + TP_FAIL("error=%d eh=%p.", err, (void *) eh); + + (void) elf_end(e); + + tet_result(result); +} + +/* + * Verify non-NULL return for a legal ELF object. + */ + +undefine(`FN') +define(`FN',` +void +tcValidElfNonNull$1(void) +{ + int fd; + Elf *e; + TS_EHDR *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'($1) on valid EHDR returns non-NULL."); + + TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd); + + if ((eh = TS_ICFUNC`'(e)) == NULL) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); + (void) close(fd); +}') + +FN(`LSB') +FN(`MSB') + +/* + * Verify accuracy of the return header. + */ + +define(`FN',` +void +tcValidElf$1(void) +{ + int fd, result; + Elf *e; + TS_EHDR *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'($1) returns the correct $1 ehdr."); + + TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd); + + if ((eh = TS_ICFUNC`'(e)) == NULL) { + TP_UNRESOLVED("TS_ICNAME`'() failed."); + goto done; + } + + result = TET_PASS; + + CHECK_EHDR(eh, ELFDATA2$1, TS_ELFCLASS); + +done: + (void) elf_end(e); + (void) close(fd); + + tet_result(result); + +}') + +FN(`LSB') +FN(`MSB') + +/* + * Verify duplicate handling. + */ + +undefine(`FN') +define(`FN',` +void +tcElfDup$1(void) +{ + int fd, result; + Elf *e; + TS_EHDR *eh1, *eh2; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Successful calls to TS_ICNAME`'($1) return " + "identical pointers."); + + TS_OPEN_FILE(e,"ehdr.TOLOWER($1)`'TS_EHDRSZ",ELF_C_READ,fd); + + if ((eh1 = TS_ICFUNC`'(e)) == NULL || + (eh2 = TS_ICFUNC`'(e)) == NULL) { + TP_UNRESOLVED("TS_ICNAME`'() failed."); + tet_result(result); + return; + } + + tet_result(eh1 == eh2 ? TET_PASS : TET_FAIL); + + (void) elf_end(e); + (void) close(fd); +}') + +FN(`LSB') +FN(`MSB') + +/* + * Verify the error reported for incorrectly sized ELF objects. + */ + +undefine(`FN') +define(`FN',` +void +tcElfWrongSize$1(void) +{ + int error, fd, result; + Elf *e; + char *fn; + TS_EHDR *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'($1.TS_OTHERSIZE) fails with ELF_E_CLASS."); + + result = TET_PASS; + + fn = "ehdr.TOLOWER($1)`'TS_OTHERSIZE"; + TS_OPEN_FILE(e,fn,ELF_C_READ,fd); + if ((eh = TS_ICFUNC`'(e)) != NULL || + (error = elf_errno()) != ELF_E_CLASS) + TP_FAIL("\"%s\" opened (error %d).", fn, error); + + (void) elf_end(e); + (void) close(fd); + + tet_result(result); + +}') + +FN(`LSB') +FN(`MSB') + +/* + * Verify that malformed ELF objects are rejected. + */ + +undefine(`FN') +define(`FN',` +void +tcMalformed1$1(void) +{ + int error, fd, result; + Elf *e; + char *fn; + TS_EHDR *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME with a malformed ELF header " + "fails with ELF_E_HEADER."); + + e = NULL; + fd = -1; + fn = "ehdr-malformed-1.TOLOWER($1)`'TS_EHDRSZ"; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, fn, ELF_C_READ, fd, goto done;); + + error = 0; + if ((eh = TS_ICFUNC`'(e)) != NULL) { + TP_FAIL("\"%s\" TS_ICNAME`'() succeeded.", fn); + goto done; + } else if ((error = elf_errno()) != ELF_E_HEADER) { + TP_FAIL("\"%s\" incorrect error (%d).", fn, error); + goto done; + } + + result = TET_PASS; + +done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(`LSB') +FN(`MSB') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elf_flag.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/common/elf_flag.m4 new file mode 100644 index 0000000000..cc92f3e68c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elf_flag.m4 @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elf_flag.m4 1412 2011-02-05 10:09:22Z jkoshy $ + */ + +/* + * M4 macros for use with the elf_flag*() APIs. + */ + +divert(-1) + +define(`_TP_FLAG_FN',` +void +$1(void) +{ + int result; +$2 +$3 +$4 + tet_result(result); +}') + +define(`TP_FLAG_NULL',`_TP_FLAG_FN(`tcArgsNull',` + int error, ret; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("A NULL first parameter returns zero.");',` + result = TET_PASS; + if ((ret = $1(NULL, ELF_C_SET, ELF_F_DIRTY)) != 0 || + (error = elf_errno()) != ELF_E_NONE) + TP_FAIL("ret=%d, error=%d \"%s\".", ret, error, + elf_errmsg(error));',`')') + +/* + * TP_FLAG_ILLEGAL_CMD(FN,ARG) + * + * Check that illegal `cmd' values are rejected. + */ +define(`TP_FLAG_ILLEGAL_CMD',`_TP_FLAG_FN(`tcArgsIllegalCmd',` + int error, ret; + Elf_Cmd cmd; + _TP_DECLARATIONS + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Illegal CMD values are rejected."); + + _TP_PROLOGUE',` + result = TET_PASS; + for (cmd = ELF_C_NULL-1; cmd <= ELF_C_NUM; cmd++) { + if (cmd == ELF_C_CLR || cmd == ELF_C_SET) + continue; + if ((ret = $1($2, ELF_C_NUM, ELF_F_DIRTY)) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("cmd=%d ret=%d, error=%d \"%s\".", cmd, ret, + error, elf_errmsg(error)); + goto done; + } + }',`_TP_EPILOGUE')') + +/* + * TP_FLAG_SET(FN,ARG) + * + * Check that an ELF_C_SET works. + */ +define(`TP_FLAG_SET',`_TP_FLAG_FN(`tcArgsSet',` + int error, flag; + _TP_DECLARATIONS + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("ELF_C_SET works correctly."); + + _TP_PROLOGUE',` + result = TET_PASS; + + if ((flag = $1($2, ELF_C_SET, ELF_F_DIRTY)) != ELF_F_DIRTY) { + error = elf_errno(); + TP_FAIL("flag=0x%x, expected 0x%x, error=%d \"%s\".", flag, + ELF_F_DIRTY, error, elf_errmsg(error)); + goto done; + }',`_TP_EPILOGUE')') + +/* + * TP_FLAG_CLR(FN,ARG) + * + * Check that an ELF_C_CLR works. + */ +define(`TP_FLAG_CLR',`_TP_FLAG_FN(`tcArgsClr',` + int error, flag; + _TP_DECLARATIONS + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("ELF_C_CLR works correctly."); + + _TP_PROLOGUE',` + result = TET_PASS; + + (void) $1($2, ELF_C_SET, ELF_F_DIRTY); + if ((flag = $1($2, ELF_C_CLR, ELF_F_DIRTY)) != 0) { + error = elf_errno(); + TP_FAIL("flag=0x%x, error=%d \"%s\".", flag, error, + elf_errmsg(error)); + goto done; + }',`_TP_EPILOGUE')') + +/* + * TP_FLAG_ILLEGAL_CMD(FN, ARG, LEGALFLAGS) + * + * Check that all flag values other than those in LEGALFLAGS are + * rejected with ELF_E_ARGUMENT. + */ +define(`TP_FLAG_ILLEGAL_FLAG',`_TP_FLAG_FN(`tcArgsIllegalFlags',` + int error, ret; + unsigned int flags; + + _TP_DECLARATIONS + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Illegal flag values are rejected."); + + _TP_PROLOGUE',` + result = TET_PASS; + for (flags = 0x1; flags; flags <<= 1) { + if (flags & ($3)) + continue; + if ((ret = $1($2, ELF_C_SET, flags)) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("ret=%d, error=%d \"%s\".", ret, error, + elf_errmsg(error)); + goto done; + } + }',`_TP_EPILOGUE')') + +/* + * TP_FLAG_NON_ELF(FN,ARG) + * + * Check that a non-elf file is rejected. + */ +define(`TP_FLAG_NON_ELF',` +char *rawdata = "This is not an ELF file."; +_TP_FLAG_FN(`tcArgsNonElf',` + int error, ret; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Non-ELF files are rejected."); + + TS_OPEN_MEMORY(e, rawdata);',` + result = TET_PASS; + if ((ret = $1(e, ELF_C_SET, ELF_F_DIRTY)) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("ret=%d, error=%d \"%s\".", ret, error, + elf_errmsg(error)); + }',`')') + +divert(0) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-compare-files.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-compare-files.c new file mode 100644 index 0000000000..6d22dc9f0d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-compare-files.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts-compare-files.c 1193 2010-09-12 05:43:52Z jkoshy $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tet_api.h" + +/* + * A helper function to compare a generated file against + * a reference. + */ + +int +elfts_compare_files(const char *rfn, const char *fn) +{ + int fd, result, rfd; + struct stat sb, rsb; + char *m, *rm; + size_t c, nc; + + fd = rfd = -1; + m = rm = NULL; + result = TET_UNRESOLVED; + + if ((fd = open(fn, O_RDONLY, 0)) < 0) { + tet_printf("U: open \"%s\" failed: %s.", fn, + strerror(errno)); + goto done; + } + + if ((rfd = open(rfn, O_RDONLY, 0)) < 0) { + tet_printf("U: open \"%s\" failed: %s.", rfn, + strerror(errno)); + goto done; + } + + if (fstat(fd, &sb) < 0) { + tet_printf("U: fstat \"%s\" failed: %s.", fn, + strerror(errno)); + goto done; + } + + if (fstat(rfd, &rsb) < 0) { + tet_printf("U: fstat \"%s\" failed: %s.", rfn, + strerror(errno)); + goto done; + } + + if (sb.st_size != rsb.st_size) { + tet_printf("F: refsz(%d) != target(%d).", rsb.st_size, sb.st_size); + result = TET_FAIL; + goto done; + } + + if ((m = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, + (off_t) 0)) == MAP_FAILED) { + tet_printf("U: mmap \"%s\" failed: %s.", fn, + strerror(errno)); + goto done; + } + + if ((rm = mmap(NULL, rsb.st_size, PROT_READ, MAP_SHARED, rfd, + (off_t) 0)) == MAP_FAILED) { + tet_printf("U: mmap \"%s\" failed: %s.", rfn, + strerror(errno)); + goto done; + } + + result = TET_PASS; + nc = sb.st_size; + + /* Compare bytes. */ + for (c = 0; c < nc && *m == *rm; c++, m++, rm++) + ; + if (c != nc) { + tet_printf("F: @ offset 0x%x ref[%d] != actual[%d].", c, + *rm, *m); + result = TET_FAIL; + } + + done: + if (m) + (void) munmap(m, sb.st_size); + if (rm) + (void) munmap(rm, rsb.st_size); + if (fd != -1) + (void) close(fd); + if (rfd != -1) + (void) close(rfd); + return (result); + +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-copy-file.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-copy-file.c new file mode 100644 index 0000000000..1fef268e3d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-copy-file.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts-copy-file.c 2077 2011-10-27 03:59:40Z jkoshy $ + */ + +#include +#include +#include + +#include "elfts.h" + +/* + * A helper function to copy a file to a temporary. Returns the name + * of the temporary file created. + */ + +#define ELFTS_BUFSIZE 4096 +#define ELFTS_NAME_TEMPLATE "elftsXXXXXXXX" + +char * +elfts_copy_file(const char *rfn, int *error) +{ + int rfd, wfd; + ssize_t nr, nw, wrem; + char buf[ELFTS_BUFSIZE], *bp, *wfn; + + *error = 0; + rfd = wfd = -1; + bp = wfn = NULL; + + if ((wfn = malloc(sizeof(ELFTS_NAME_TEMPLATE))) == NULL) + return NULL; + + (void) strcpy(wfn, ELFTS_NAME_TEMPLATE); + + if ((wfd = mkstemp(wfn)) == -1) + goto error; + + if ((rfd = open(rfn, O_RDONLY)) == -1) + goto error; + + /* + * Copy the bits over. + * + * Explicitly check for the POSIX `EINTR` error return so that + * the code works correctly non-BSD systems. + */ + for (;;) { + if ((nr = read(rfd, buf, sizeof(buf))) < 0) { + if (errno == EINTR) + continue; + goto error; + } + + if (nr == 0) + break; /* EOF */ + + for (bp = buf, wrem = nr; wrem > 0; bp += nw, wrem -= nw) { + if ((nw = write(wfd, bp, wrem)) < 0) { + if (errno == EINTR) + continue; + goto error; + } + } + } + + (void) close(rfd); + (void) close(wfd); + return (wfn); + + error: + *error = errno; + + if (wfd) + (void) close(wfd); + if (rfd) + (void) close(rfd); + if (wfn) { + (void) unlink(wfn); + free(wfn); + } + return (NULL); +} + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-initversion.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-initversion.c new file mode 100644 index 0000000000..bab1cc91d7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-initversion.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts-initversion.c 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include + +#include "tet_api.h" + +/* + * A TET startup() function for test cases that need elf_version() + * to be called before each invocable component. + */ + +int elfts_tcinit = TET_PASS; + +void +elfts_init_version(void) +{ + if (elf_version(EV_CURRENT) != EV_CURRENT) { + tet_printf("setup: elf_version() failed: %s", + elf_errmsg(-1)); + elfts_tcinit = TET_UNRESOLVED; + } +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-openfile.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-openfile.c new file mode 100644 index 0000000000..6f6640a489 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts-openfile.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts-openfile.c 1192 2010-09-12 05:40:00Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +/* + * A TET startup() function for test cases that need elf_version() + * to be called before each invocable component. + */ + +Elf * +elfts_open_file(const char *fn, Elf_Cmd cmd, int *fdp) +{ + Elf *e; + int fd, mode; + + switch (cmd) { + case ELF_C_WRITE: + mode = O_WRONLY | O_CREAT; + break; + case ELF_C_READ: + mode = O_RDONLY; + break; + case ELF_C_RDWR: + mode = O_RDWR; + break; + default: + tet_printf("internal error: unknown cmd=%d.", cmd); + return (NULL); + } + + if ((fd = open(fn, mode, 0644)) < 0) { + tet_printf("setup: open \"%s\" failed: %s.", fn, + strerror(errno)); + return (NULL); + } + + if (fdp) + *fdp = fd; + + if ((e = elf_begin(fd, cmd, NULL)) == NULL) { + tet_printf("setup: elf_begin(%s) failed: %s.", fn, + elf_errmsg(-1)); + tet_result(TET_UNRESOLVED); + } + + return (e); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts.h b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts.h new file mode 100644 index 0000000000..b1632da831 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/elfts.h @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts.h 1337 2010-12-31 15:38:31Z jkoshy $ + */ + +#ifndef _ELF_TS_H_ +#define _ELF_TS_H_ 1 + +/* + * Common definitions used by test cases. + */ + +/* Invocable component requires elf_version() to be set. */ +#define IC_REQUIRES_VERSION_INIT() \ + extern int elfts_tcinit; \ + void (*tet_startup)(void) = elfts_init_version + +/* Test purpose needs to check for initialization success */ +#define TP_CHECK_INITIALIZATION() do { \ + if (elfts_tcinit != TET_PASS) { \ + tet_infoline("unresolved: test case setup " \ + "failed."); \ + tet_result(elfts_tcinit); \ + return; \ + } \ + } while (0) + +/* Treat a memory area as containing ELF data */ +#define TS_OPEN_MEMORY(E,M) do { \ + if (((E) = elf_memory((M), sizeof((M)))) == NULL) { \ + tet_infoline("unresolved: elf_memory() " \ + "failed."); \ + tet_result(TET_UNRESOLVED); \ + return; \ + } \ + } while (0) + +/* Get an ELF descriptor for a file */ +#define _TS_OPEN_FILE(E,FN,CMD,FD,ACTION) do { \ + if (((E) = elfts_open_file((FN),(CMD),&(FD))) == NULL) \ + ACTION \ + } while (0) + +#define TS_OPEN_FILE(E,FN,CMD,FD) _TS_OPEN_FILE(E,FN,CMD,FD,return;) + +#define _TS_WRITE_FILE(FN,DATA,DSZ,ACTION) do { \ + int _fd; \ + if ((_fd = open((FN), O_CREAT|O_WRONLY, 0666)) < 0) { \ + tet_printf("unresolved: open("FN") failed: %s.",\ + strerror(errno)); \ + ACTION \ + } \ + if (write(_fd, (DATA), (DSZ)) != (DSZ)) { \ + tet_printf("unresolved: write("FN") failed: %s.",\ + strerror(errno)); \ + ACTION \ + } \ + (void) close(_fd); \ + } while (0) + +#define _TS_READ_FILE(FN,DATA,DSZ,ACTION) do { \ + int _fd; \ + size_t _rsz, _sz; \ + struct stat _sb; \ + if ((_fd = open((FN), O_RDONLY, 0)) < 0) { \ + tet_printf("unresolved: open("FN") failed: %s.", \ + strerror(errno)); \ + ACTION \ + } \ + if (fstat(_fd, &_sb) < 0) { \ + tet_printf("unresolved: fstat("FN") failed: %s.", \ + strerror(errno)); \ + ACTION \ + } \ + if ((DSZ) < _sb.st_size) \ + _sz = (DSZ); \ + else \ + _sz = _sb.st_size; \ + if ((_rsz = read(_fd, (DATA), _sz)) != _sz) { \ + tet_printf("unresolved: read("FN") failed: %s.", \ + strerror(errno)); \ + ACTION \ + } \ + (void) close(_fd); \ + } while (0) + +#define TS_NEWFILE "new.file" + +void elfts_init_version(void); + +Elf *elfts_open_file(const char *_fn, Elf_Cmd _cmd, int *_fdp); +int elfts_compare_files(const char *_reffn, const char *fn); +char *elfts_copy_file(const char *_fn, int *_error); + +#endif /* _LIBELF_TS_H_ */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/fsize.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/fsize.yaml new file mode 100644 index 0000000000..cd6cbe7b1c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/fsize.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +# $Id: fsize.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_FREEBSD + ei_abiversion: 1 + ei_class: ELFCLASSNONE + e_type: ET_REL + e_machine: EM_NONE + e_version: EV_CURRENT + e_flags: [2, 1] + e_entry: 0xdeadbeef + e_phoff: 0 + e_shoff: 0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/gelf_ehdr_template.h b/contrib/elftoolchain/tests/tet/libelf/tset/common/gelf_ehdr_template.h new file mode 100644 index 0000000000..30c7c675a3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/gelf_ehdr_template.h @@ -0,0 +1,165 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: gelf_ehdr_template.h 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +/* + * Boilerplate for testing gelf_getehdr() and gelf_newehdr(). + * + * Usage: + * + * For gelf_getehdr() define: + * #define TC_ICFUNC(E,V) gelf_getehdr(E,V) + * For gelf_newehdr() define: + # #define TC_ICFUNC(E,V) + * #include "gelf_getehdr_template.c" + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * The values here must match those in the "ehdr.yaml" file. + */ + +#define CHECK_SIGFIELD(E,I,V) do { \ + if ((E)->e_ident[EI_##I] != (V)) { \ + tet_printf("fail: " #I " value 0x%x != " \ + "expected 0x%x.", (E)->e_ident[EI_##I], \ + (V)); \ + result = TET_FAIL; \ + } \ + } while (0) + +#define CHECK_SIG(E,ED,EC,EV,EABI,EABIVER) do { \ + if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \ + (E)->e_ident[EI_MAG1] != ELFMAG1 || \ + (E)->e_ident[EI_MAG2] != ELFMAG2 || \ + (E)->e_ident[EI_MAG3] != ELFMAG3) { \ + tet_printf("fail: incorrect ELF signature " \ + "(%x %x %x %x).", (E)->e_ident[EI_MAG0], \ + (E)->e_ident[EI_MAG1], (E)->e_ident[EI_MAG2],\ + (E)->e_ident[EI_MAG3]); \ + result = TET_FAIL; \ + } \ + CHECK_SIGFIELD(E,CLASS, EC); \ + CHECK_SIGFIELD(E,DATA, ED); \ + CHECK_SIGFIELD(E,VERSION, EV); \ + CHECK_SIGFIELD(E,OSABI, EABI); \ + CHECK_SIGFIELD(E,ABIVERSION, EABIVER); \ + } while (0) + + +#define CHECK_FIELD(E,FIELD,VALUE) do { \ + if ((E)->e_##FIELD != (VALUE)) { \ + tet_printf("fail: field \"%s\" actual 0x%jx " \ + "!= expected 0x%jx.", #FIELD, \ + (uintmax_t) (E)->e_##FIELD, \ + (uintmax_t) (VALUE)); \ + tet_result(TET_FAIL); \ + return; \ + } \ + } while (0) + +#define CHECK_EHDR(E,ED,EC) do { \ + CHECK_SIG(E,ED,EC,EV_CURRENT,ELFOSABI_FREEBSD,1); \ + CHECK_FIELD(E,type, ET_REL); \ + CHECK_FIELD(E,machine, 0x42); \ + CHECK_FIELD(E,version, EV_CURRENT); \ + CHECK_FIELD(E,entry, 0xF0F0F0F0); \ + CHECK_FIELD(E,phoff, 0x0E0E0E0E); \ + CHECK_FIELD(E,shoff, 0xD0D0D0D0); \ + CHECK_FIELD(E,flags, 64+8+2+1); \ + CHECK_FIELD(E,ehsize, 0x0A0A); \ + CHECK_FIELD(E,phentsize,0xB0B0); \ + CHECK_FIELD(E,phnum, 0x0C0C); \ + CHECK_FIELD(E,shentsize,0xD0D0); \ + CHECK_FIELD(E,shnum, 0x0E0E); \ + CHECK_FIELD(E,shstrndx, 0xF0F0); \ + } while (0) + +#define COMPARE_SIG(FN,H1,H2) do { \ + if (memcmp(H1.e_ident,H2.e_ident,EI_NIDENT) != 0) { \ + tet_printf("fail: \"%s\" e_ident mismatch.", \ + FN); \ + result = TET_FAIL; \ + } \ + } while (0) +#define COMPARE_FIELD(FN,H1,H2,FIELD) do { \ + if (H1.e_##FIELD != H2.e_##FIELD) { \ + tet_printf("fail: \"%s\" (e_" #FIELD ") 0x%jx " \ + "!= 0x%jx.", FN, (uintmax_t) H1.e_##FIELD, \ + (uintmax_t) H2.e_##FIELD); \ + result = TET_FAIL; \ + } \ + } while (0) +#define COMPARE_EHDR(FN,H1,H2) do { \ + COMPARE_SIG(FN,H1,H2); \ + COMPARE_FIELD(FN,H1,H2,type); \ + COMPARE_FIELD(FN,H1,H2,machine); \ + COMPARE_FIELD(FN,H1,H2,version); \ + COMPARE_FIELD(FN,H1,H2,entry); \ + COMPARE_FIELD(FN,H1,H2,phoff); \ + COMPARE_FIELD(FN,H1,H2,shoff); \ + COMPARE_FIELD(FN,H1,H2,flags); \ + COMPARE_FIELD(FN,H1,H2,ehsize); \ + COMPARE_FIELD(FN,H1,H2,phentsize); \ + COMPARE_FIELD(FN,H1,H2,phnum); \ + COMPARE_FIELD(FN,H1,H2,shentsize); \ + COMPARE_FIELD(FN,H1,H2,shnum); \ + COMPARE_FIELD(FN,H1,H2,shstrndx); \ + } while (0) + +/* + * Non-ELF data. + */ + +static char data[] = "This isn't an ELF file."; + + +/* + * A malformed (too short) ELF header. + */ + +static char badelftemplate[EI_NIDENT+1] = { + [EI_MAG0] = '\177', + [EI_MAG1] = 'E', + [EI_MAG2] = 'L', + [EI_MAG3] = 'F', + [EI_NIDENT] = '@' +}; + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/getclass.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/getclass.yaml new file mode 100644 index 0000000000..f438651feb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/getclass.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +# $Id: getclass.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_FREEBSD + ei_abiversion: 1 + ei_class: ELFCLASSNONE + e_type: ET_REL + e_machine: EM_NONE + e_version: EV_CURRENT + e_flags: [2, 1] + e_entry: 0xdeadbeef + e_phoff: 0 + e_shoff: 0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/getshdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/common/getshdr.m4 new file mode 100644 index 0000000000..060c1f44a4 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/getshdr.m4 @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getshdr.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +/* + * TP_NULL(CLASS) + * + * Check that a NULL argument returns ELF_E_ARGUMENT. + */ + +define(`TP_NULL',` +void +tcNull_tpNull$1(void) +{ + int error, result; + Elf$1_Shdr *sh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf$1_getshdr(NULL) fails with ELF_E_ARGUMENT."); + + result = TET_PASS; + if ((sh = elf$1_getshdr(NULL)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("sh=%p error=%d \"%s\".", (void *) sh, + error, elf_errmsg(error)); + + tet_result(result); +}') + +/* TP_CHECK_FIELD(I, SH,REF,FIELD) */ +define(`TP_CHECK_FIELD',`do { + if ($2->$4 != $3->$4) { + TP_FAIL("field[%d] \"$4\" %jd != ref %jd.", $1, + (uintmax_t) $2->$4, (uintmax_t) $3->$4); + goto done; + } + } while (0)') +/* TP_CHECK_SHDR(IND, SH, REF) */ +define(`TP_CHECK_SHDR',`do { + TP_CHECK_FIELD($1,$2,$3,sh_name); + TP_CHECK_FIELD($1,$2,$3,sh_type); + TP_CHECK_FIELD($1,$2,$3,sh_flags); + TP_CHECK_FIELD($1,$2,$3,sh_addr); + TP_CHECK_FIELD($1,$2,$3,sh_offset); + TP_CHECK_FIELD($1,$2,$3,sh_size); + TP_CHECK_FIELD($1,$2,$3,sh_link); + TP_CHECK_FIELD($1,$2,$3,sh_info); + TP_CHECK_FIELD($1,$2,$3,sh_addralign); + TP_CHECK_FIELD($1,$2,$3,sh_entsize); + } while (0)') + +/* + * TC_MAKE_REF_SHDR(CLASS) + * + * This must match the values in "shdr.yaml". + */ +define(`TC_MAKE_REF_SHDR',` +static Elf$1_Shdr RefShdr$1[] = { + /* index 0 */ + { .sh_type = SHT_NULL }, + /* index 1 : .shstrtab */ + { .sh_name = 1, .sh_type = SHT_STRTAB, .sh_flags = SHF_ALLOC | SHF_STRINGS, + .sh_offset = 256, .sh_link = ~0, .sh_info = ~0, .sh_addralign = 1, + .sh_entsize = 0, .sh_size = 38 }, + /* index 2 : SHT_PROGBITS */ + { .sh_name = 11, .sh_type = SHT_PROGBITS, .sh_flags = SHF_ALLOC, .sh_offset = 128, + .sh_link = 0xdeadc0de, .sh_info = 0xcafebabe, .sh_addralign = 8, + .sh_entsize = 0 } +}; + +#define NSHDR (sizeof(RefShdr$1)/sizeof(RefShdr$1[0])) +') + +/* + * TP_SHDR(CLASS,ENDIANNESS) + * + * Check that the Shdrs returned are valid. + */ + +define(`TP_SHDR',` +void +tcShdr_tpValid$1`'TOUPPER($2)(void) +{ + int i, fd; + Elf *e; + Elf$1_Shdr *sh, *rs; + Elf_Scn *scn; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: Check shdr contents."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, "shdr.$2$1", ELF_C_READ, fd, goto done;); + + i = SHN_UNDEF; + rs = RefShdr$1; + + if ((scn = elf_getscn(e, i)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_FAIL("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + TP_CHECK_SHDR(i, sh, rs); + + while ((scn = elf_nextscn(e, scn)) != NULL) { + + i++; rs++; + + if (i >= NSHDR) { + TP_UNRESOLVED("Too many (%d) sections.", i); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_FAIL("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + TP_CHECK_SHDR(i, sh, rs); + + } + + result = TET_PASS; + if ((error = elf_errno()) != ELF_E_NONE) + TP_UNRESOLVED("error=%d \"%s\".", error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr.yaml new file mode 100644 index 0000000000..bc717dbe61 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr.yaml @@ -0,0 +1,7 @@ +%YAML 1.1 +# $Id: newehdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr_template.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr_template.m4 new file mode 100644 index 0000000000..52a7cea3ec --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/newehdr_template.m4 @@ -0,0 +1,243 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: newehdr_template.m4 1376 2011-01-23 04:15:51Z jkoshy $ + */ + +#include + +/* + * Boilerplate for testing newehdr{32,64} behaviour that is not + * common to the getehdr{32,64} functions. + */ + +define(`TS_NEWELF',`"new.elf"') + +ifdef(`TS_ICNAME',`', + `errprint(`File included before "ehdr_template.m4".')m4exit(1)') + +#define CHECK_NEWEHDR(E,VER) do { \ + if ((E)->e_ident[EI_MAG0] != ELFMAG0 || \ + (E)->e_ident[EI_MAG1] != ELFMAG1 || \ + (E)->e_ident[EI_MAG2] != ELFMAG2 || \ + (E)->e_ident[EI_MAG3] != ELFMAG3 || \ + (E)->e_ident[EI_CLASS] != TS_ELFCLASS || \ + (E)->e_ident[EI_DATA] != ELFDATANONE || \ + (E)->e_ident[EI_VERSION] != (VER) || \ + (E)->e_machine != EM_NONE || \ + (E)->e_type != ELF_K_NONE || \ + (E)->e_version != (VER)) \ + TP_FAIL("TS_ICNAME`'() header mismatch."); \ + } while (0) + +/* + * Verify that a new ehdr has the appropriate defaults. + */ + +void +tcAllocateCheckDefaults(void) +{ + TS_EHDR *eh; + Elf *e; + int fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'() allocates an ehdr with the " + "documented defaults."); + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + result = TET_PASS; + + if ((eh = TS_ICFUNC`'(e)) == NULL) { + TP_FAIL("TS_ICNAME`'() failed: %s.", elf_errmsg(-1)); + goto done; + } + + CHECK_NEWEHDR(eh,EV_CURRENT); + + done: + (void) elf_end(e); + (void) close(fd); + (void) unlink(TS_NEWELF); + + tet_result(result); +} + +/* + * Verify that a new ehdr is marked `dirty'. This test uses extended + * functionality in libelf. + */ + +void +tcAllocateFlagDirty(void) +{ + TS_EHDR *eh; + Elf *e; + int fd, flags, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TS_ICNAME`'() marks the new Ehdr as \"dirty\"."); + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + if ((eh = TS_ICFUNC`'(e)) == NULL) { + TP_UNRESOLVED("TS_ICNAME`'() failed: %s.", elf_errmsg(-1)); + goto done; + } + + flags = elf_flagehdr(e, ELF_C_CLR, 0); /* Our extension */ + + tet_result((flags & ELF_F_DIRTY) == 0 ? TET_FAIL : TET_PASS); + + done: + (void) unlink(TS_NEWELF); + (void) elf_end(e); + (void) close(fd); +} + +/* Declare fixed sizes associated with an ELF header. */ +ifelse(`TS_EHDRSZ',`32',` +#define TS_EHSIZE 52 +#define TS_PHENTSIZE 32 +#define TS_SHENTSIZE 40 +',` +#define TS_EHSIZE 64 +#define TS_PHENTSIZE 56 +#define TS_SHENTSIZE 64 +') + +define(`TS_REFELF',`newehdr') + +/* + * Verify that the correct header is written out. + */ + +define(`FN',` +void +tcUpdate$1`'TS_EHDRSZ`'(void) +{ + TS_EHDR *eh; + Elf *e; + int fd, reffd, result; + off_t offset; + size_t fsz; + void *t, *tref; + char *ref = "TS_REFELF.TOLOWER($1)`'TS_EHDRSZ"; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("the contents of the Ehdr for byteorder $1 are correct."); + + t = tref = NULL; + fd = reffd = -1; + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + result = TET_UNRESOLVED; + + if ((eh = TS_ICFUNC`'(e)) == NULL) { + TP_UNRESOLVED("TS_ICNAME`'() failed: %s.", elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2$1; + + /* Write out the new ehdr. */ + if ((offset = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: %s.", elf_errmsg(-1)); + goto done; + } + + /* check that the correct number of bytes were written out. */ + fsz = elf`'TS_EHDRSZ`'_fsize(ELF_T_EHDR, 1, EV_CURRENT); + + if (offset != fsz) { + TP_FAIL("elf_update() -> %d, expected %d.", offset, fsz); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + if ((t = malloc(fsz)) == NULL) { + TP_UNRESOLVED("malloc %d bytes failed: %s.", fsz, + strerror(errno)); + goto done; + } + + if ((fd = open(TS_NEWELF, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open() failed: %s.", strerror(errno)); + goto done; + } + + if (read(fd, t, fsz) != fsz) { + TP_UNRESOLVED("read %d bytes failed: %s.", fsz, + strerror(errno)); + goto done; + } + + if ((reffd = open(ref, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open(%s) failed: %s.", ref, + strerror(errno)); + goto done; + } + + if ((tref = malloc(fsz)) == NULL) { + TP_UNRESOLVED("malloc %d bytes failed: %s.", fsz, + strerror(errno)); + goto done; + } + + if (read(reffd, tref, fsz) != fsz) { + TP_UNRESOLVED("unresolved: read \"%s\" failed: %s.", ref, + strerror(errno)); + goto done; + } + + /* Read it back in */ + result = TET_PASS; + if (memcmp(t, tref, fsz) != 0) + TP_FAIL("memcmp(" TS_NEWELF ",%s) failed.", ref); + + done: + (void) unlink(TS_NEWELF); + if (e) + (void) elf_end(e); + if (tref) + free(tref); + if (t) + free(t); + if (fd != -1) + (void) close(fd); + if (reffd != -1) + (void) close(reffd); + tet_result(result); +}') + +FN(`LSB') +FN(`MSB') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn.yaml new file mode 100644 index 0000000000..735a450238 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn.yaml @@ -0,0 +1,27 @@ +%YAML 1.1 +# $Id: newscn.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section # index 0 + sh_type: SHT_NULL + + - !Section + sh_name: .shstrtab + sh_type: SHT_STRTAB + sh_data: + - .shstrtab + - .foobar + + - !Section + sh_name: .foobar + sh_offset: 2048 + sh_type: SHT_PROGBITS + sh_data: + - 0x01234567 + - 0x89ABCDEF diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn2.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn2.yaml new file mode 100644 index 0000000000..f9f2c7d8df --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/newscn2.yaml @@ -0,0 +1,28 @@ +%YAML 1.1 +# $Id: newscn2.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +# +# This is the library-defined layout of the 'newscn' ELF object. +--- +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section # index 0 + sh_type: SHT_NULL + + - !Section + sh_name: .shstrtab + sh_type: SHT_STRTAB + sh_data: + - .shstrtab + - .foobar + + - !Section + sh_name: .foobar + sh_type: SHT_PROGBITS + sh_data: + - 0x01234567 + - 0x89ABCDEF diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr.yaml new file mode 100644 index 0000000000..14ad5d1bb0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr.yaml @@ -0,0 +1,38 @@ +%YAML 1.1 +# $Id: phdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE +# +# These values should match those in "common/phdr_template.c" +# +phdrtab: + - !Phdr + p_type: PT_NULL + p_offset: 1 + p_vaddr: 2 + p_paddr: 3 + p_filesz: 4 + p_memsz: 5 + p_flags: [ PF_X ] + p_align: 1 + - !Phdr + p_type: PT_LOPROC + p_offset: 6 + p_vaddr: 7 + p_paddr: 8 + p_filesz: 9 + p_memsz: 10 + p_flags: [ PF_R ] + p_align: 4 + - !Phdr + p_type: PT_INTERP + p_offset: 11 + p_vaddr: 12 + p_paddr: 13 + p_filesz: 14 + p_memsz: 15 + p_flags: [ PF_W ] + p_align: 8 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr_template.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr_template.c new file mode 100644 index 0000000000..3bca4ceca2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/phdr_template.c @@ -0,0 +1,416 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: phdr_template.c 3174 2015-03-27 17:13:41Z emaste $ + */ + +/* + * Boilerplate for testing the *_getphdr and *_newphdr APIs. + * + * This template is to be used as follows: + * + * #define TS_PHDRFUNC _getphdr (or _newphdr) + * #define TS_PHDRSZ 32 (or 64) + * #include "phdr_template.c" + */ + +/* Variations of __CONCAT and __STRING which expand their arguments. */ +#define __XCONCAT(x,y) __CONCAT(x,y) +#ifndef __XSTRING +#define __XSTRING(x) __STRING(x) +#endif + +#define TS_ICFUNC __XCONCAT(elf,__XCONCAT(TS_PHDRSZ,TS_PHDRFUNC)) +#define TS_PHDR __XCONCAT(Elf,__XCONCAT(TS_PHDRSZ,_Phdr)) +#define TS_ICNAME __XSTRING(TS_ICFUNC) +#define TS_ELFCLASS __XCONCAT(ELFCLASS,TS_PHDRSZ) + +#define TS_GETEHDR __XCONCAT(elf,__XCONCAT(TS_PHDRSZ,_getehdr)) +#define TS_EHDR __XCONCAT(Elf,__XCONCAT(TS_PHDRSZ,_Ehdr)) + +#define TS_NPHDR 3 /* should match "phdr.yaml" */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * Reference data for the contents of an Phdr structure. The values + * here must match that in the "phdr.yaml" file. + */ + +static TS_PHDR phdr_testdata[TS_NPHDR] = { + { + .p_type = PT_NULL, + .p_offset = 1, + .p_vaddr = 2, + .p_paddr = 3, + .p_filesz = 4, + .p_memsz = 5, + .p_flags = PF_X, + .p_align = 1 + }, + { + .p_type = PT_NULL, + .p_offset = 6, + .p_vaddr = 7, + .p_paddr = 8, + .p_filesz = 9, + .p_memsz = 10, + .p_flags = PF_R, + .p_align = 4 + }, + { + .p_type = PT_INTERP, + .p_offset = 11, + .p_vaddr = 12, + .p_paddr = 13, + .p_filesz = 14, + .p_memsz = 15, + .p_flags = PF_W, + .p_align = 8 + } +}; + +static int +check_phdr(TS_PHDR *p) +{ + int i, result; + TS_PHDR *pt; + + result = TET_PASS; + for (pt = phdr_testdata, i = 0; i < TS_NPHDR; i++) { + +#define CHECK_PH_FIELD(FIELD) do { \ + if (p->p_##FIELD != pt->p_##FIELD) { \ + tet_printf("fail: [%d] field \"%s\" actual " \ + "0x%jx != expected 0x%jx.", i, #FIELD, \ + (uintmax_t) p->p_##FIELD, \ + (uintmax_t) pt->p_##FIELD); \ + result = TET_FAIL; \ + } \ + } while (0) + + CHECK_PH_FIELD(type); + CHECK_PH_FIELD(offset); + CHECK_PH_FIELD(vaddr); + CHECK_PH_FIELD(paddr); + CHECK_PH_FIELD(filesz); + CHECK_PH_FIELD(memsz); + CHECK_PH_FIELD(flags); + CHECK_PH_FIELD(align); + + if (result != TET_PASS) + return (result); + } + + return (result); +} + +void +tcNull_tpGet(void) +{ + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "(NULL) fails with " + "ELF_E_ARGUMENT."); + + if (TS_ICFUNC(NULL) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + +static char data[] = "This isn't an ELF file."; + +void +tcData_tpElf(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "(E) for non-ELF (E) fails with " + "ELF_E_ARGUMENT."); + + TS_OPEN_MEMORY(e, data); + + if (TS_ICFUNC(e) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + + +/* + * A malformed (too short) ELF header. + */ + +static char badelftemplate[EI_NIDENT+1] = { + [EI_MAG0] = '\177', + [EI_MAG1] = 'E', + [EI_MAG2] = 'L', + [EI_MAG3] = 'F', + [EI_CLASS] = ELFCLASS64, + [EI_DATA] = ELFDATA2MSB, + [EI_NIDENT] = '@' +}; + +void +tcBadElfVersion_tpElf(void) +{ + int err; + Elf *e; + TS_PHDR *ph; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "() with an unsupported version " + "fails with ELF_E_VERSION."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + + badelf[EI_VERSION] = EV_NONE; + badelf[EI_CLASS] = TS_ELFCLASS; + + TS_OPEN_MEMORY(e, badelf); + + if ((ph = TS_ICFUNC(e)) != NULL || + (err = elf_errno()) != ELF_E_VERSION) { + tet_printf("fail: error=%d ph=%p.", err, (void *) ph); + tet_result(TET_FAIL); + } else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +void +tcBadElf_tpElf(void) +{ + int err; + Elf *e; + TS_PHDR *ph; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "() on a malformed ELF file " + "fails with ELF_E_HEADER."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + badelf[EI_VERSION] = EV_CURRENT; + badelf[EI_CLASS] = TS_ELFCLASS; + + TS_OPEN_MEMORY(e, badelf); + + if ((ph = TS_ICFUNC(e)) != NULL || + (err = elf_errno()) != ELF_E_HEADER) { + tet_printf("fail: error=%d ph=%p.", err, (void *) ph); + tet_result(TET_FAIL); + } else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +void +tcElf_tpCorruptEhdr(void) +{ + int err, fd, result; + char *fn; + Elf *e; + TS_PHDR *ph; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "(E) with corrupt phdr values " + "the header returns E_HEADER."); + + fn = "ehdr.msb" __XSTRING(TS_PHDRSZ); + TS_OPEN_FILE(e, fn, ELF_C_READ, fd); + + result = TET_PASS; + + if ((ph = TS_ICFUNC(e)) != NULL || + (err = (elf_errno() != ELF_E_HEADER))) { + tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph, + err); + result = TET_FAIL; + } + (void) elf_end(e); + (void) close(fd); + + if (result != TET_PASS) { + tet_result(result); + return; + } + + fn = "ehdr.lsb" __XSTRING(TS_PHDRSZ); + TS_OPEN_FILE(e, fn, ELF_C_READ, fd); + + if ((ph = TS_ICFUNC(e)) != NULL || + (err = (elf_errno() != ELF_E_HEADER))) { + tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph, + err); + result = TET_FAIL; + } + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +} + +void +tcElf_tpElfLSB(void) +{ + int fd; + Elf *e; + TS_PHDR *ph; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: " TS_ICNAME "(E) returns the correct LSB phdr."); + + TS_OPEN_FILE(e,"phdr.lsb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd); + + if ((ph = TS_ICFUNC(e)) == NULL) { + tet_infoline("fail: " TS_ICNAME "() failed."); + tet_result(TET_FAIL); + return; + } + + tet_result(check_phdr(ph)); + + (void) elf_end(e); + (void) close(fd); +} + +void +tcElf_tpElfMSB(void) +{ + int fd; + Elf *e; + TS_PHDR *ph; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion:" TS_ICNAME "(E) returns the correct MSB phdr."); + + TS_OPEN_FILE(e,"phdr.msb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd); + + if ((ph = TS_ICFUNC(e)) == NULL) { + tet_infoline("fail: " TS_ICNAME "() failed."); + tet_result(TET_FAIL); + return; + } + + tet_result(check_phdr(ph)); + + (void) elf_end(e); + (void) close(fd); +} + +void +tcElf_tpElfDup(void) +{ + int fd; + Elf *e; + TS_PHDR *ph1, *ph2; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: successful calls to " TS_ICNAME "() return " + "identical pointers."); + + TS_OPEN_FILE(e,"phdr.msb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd); + + if ((ph1 = TS_ICFUNC(e)) == NULL || + (ph2 = TS_ICFUNC(e)) == NULL) { + tet_infoline("unresolved: " TS_ICNAME "() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + tet_result(ph1 == ph2 ? TET_PASS : TET_FAIL); + + (void) elf_end(e); + (void) close(fd); +} + +#if TS_PHDRSZ == 32 +#define TS_OTHERSIZE 64 +#else +#define TS_OTHERSIZE 32 +#endif + +void +tcElf_tpElfWrongSize(void) +{ + int error, fd, result; + Elf *e; + char *fn; + TS_PHDR *ph; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: a call to " TS_ICNAME "() and a mismatched " + "ELF class fails with ELF_E_CLASS."); + + result = TET_PASS; + + fn = "phdr.msb" __XSTRING(TS_OTHERSIZE); + TS_OPEN_FILE(e,fn,ELF_C_READ,fd); + + if ((ph = TS_ICFUNC(e)) != NULL || + (error = elf_errno()) != ELF_E_CLASS) { + tet_printf("fail: \"%s\" opened (error %d).", fn, error); + result = TET_FAIL; + } + + (void) elf_end(e); + (void) close(fd); + + if (result != TET_PASS) { + tet_result(result); + return; + } + + fn = "phdr.lsb" __XSTRING(TS_OTHERSIZE); + TS_OPEN_FILE(e,fn,ELF_C_READ,fd); + if ((ph = TS_ICFUNC(e)) != NULL || + (error = elf_errno()) != ELF_E_CLASS) { + tet_printf("fail: \"%s\" opened (error %d).", fn, error); + result = TET_FAIL; + } + + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr.yaml new file mode 100644 index 0000000000..927c5a4865 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr.yaml @@ -0,0 +1,27 @@ +%YAML 1.1 +--- +# $Id: rdwr.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +# +# This file is used for tests requiring a well-formed ELF file +# opened in ELF_C_RDWR mode. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section + sh_type: SHT_NULL + - !Section + sh_type: SHT_PROGBITS + sh_name: .progbits + sh_data: + - hello world + - !Section + sh_type: SHT_STRTAB + sh_name: .shstrtab + sh_data: + - .shstrtab + - .progbits diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr1.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr1.yaml new file mode 100644 index 0000000000..433106b967 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr1.yaml @@ -0,0 +1,27 @@ +%YAML 1.1 +# $Id: rdwr1.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +--- +# +# This file is used for tests requiring a well-formed ELF file +# opened in ELF_C_RDWR mode. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_DYN + +sections: + - !Section + sh_type: SHT_NULL + - !Section + sh_type: SHT_PROGBITS + sh_name: .progbits + sh_data: + - hello world + - !Section + sh_type: SHT_STRTAB + sh_name: .shstrtab + sh_data: + - .shstrtab + - .progbits diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr2.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr2.yaml new file mode 100644 index 0000000000..abb579132e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/rdwr2.yaml @@ -0,0 +1,28 @@ +%YAML 1.1 +# $Id: rdwr2.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +--- +# +# This file is used for tests requiring a well-formed ELF file +# opened in ELF_C_RDWR mode. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section + sh_type: SHT_NULL + - !Section + sh_type: SHT_PROGBITS + sh_name: .progbits + sh_data: + - hello world + - goodbye world + - !Section + sh_type: SHT_STRTAB + sh_name: .shstrtab + sh_data: + - .shstrtab + - .progbits diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/shdr.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/shdr.yaml new file mode 100644 index 0000000000..c8c67a055a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/shdr.yaml @@ -0,0 +1,42 @@ +%YAML 1.1 +# $Id: shdr.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +# +# This file is used for tests requiring a set of valid section +# headers. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section # index 0 + sh_type: SHT_NULL + - !Section + sh_name: .shstrtab + sh_type: SHT_STRTAB + sh_flags: [ SHF_ALLOC , SHF_STRINGS ] + sh_offset: 256 + sh_link: 0xFFFFFFFF + sh_info: 0xFFFFFFFF + sh_addralign: 1 + sh_entsize: 0 + sh_data: + - .shstrtab + - .dynsym + - yet another string + - !Section + sh_name: .dynsym + sh_type: SHT_PROGBITS + sh_flags: [ SHF_ALLOC ] + sh_offset: 128 + sh_link: 0xdeadc0de + sh_info: 0xcafebabe + sh_addralign: 8 + sh_entsize: 0 + + + + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/u1.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/u1.yaml new file mode 100644 index 0000000000..992ddd0ade --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/u1.yaml @@ -0,0 +1,29 @@ +%YAML 1.1 +# $Id: u1.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +phdrtab: + - !Phdr + p_type: PT_NULL + p_offset: 0x0F0F0F0F + p_vaddr: 0xA0A0A0A0 + p_filesz: 0x1234 + p_memsz: 0x5678 + p_flags: [ PF_X, PF_R ] + p_align: 64 + +sections: + - !Section # index 0 + sh_type: SHT_NULL + + - !Section + sh_name: .shstrtab + sh_type: SHT_STRTAB + sh_data: + - .shstrtab + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/versioning.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/versioning.yaml new file mode 100644 index 0000000000..37e8995b6c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/versioning.yaml @@ -0,0 +1,55 @@ +%YAML 1.1 +--- +# $Id: versioning.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +# +# This file is used to test handling of sections with symbol +# versioning information. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section + sh_type: SHT_NULL + - !Section + sh_type: SHT_GNU_verdef + sh_name: .gnu.version_d + sh_data: + - !Verdef + vd_version: 1 + vd_flags: 0 + vd_ndx: 1 + vd_cnt: 1 + vd_hash: 0x1234 + vd_aux: 42 + vd_next: 0 + - !Verdaux + vda_name: 1 + vda_next: 0 + - !Section + sh_type: SHT_GNU_verneed + sh_name: .gnu.version_r + sh_data: + - !Verneed + vn_version: 1 + vn_cnt: 1 + vn_file: 0x1234 + vn_aux: 42 + vn_next: 0 + - !Vernaux + vna_hash: 0x4321 + vna_flags: 0x1 + vna_other: 0 + vna_name: 1 + vna_next: 0 + - !Section + sh_type: SHT_STRTAB + sh_name: .shstrtab + sh_data: + - .shstrtab + - .gnu.version_d + - .gnu.version_r + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate.yaml new file mode 100644 index 0000000000..bd4aa7e017 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate.yaml @@ -0,0 +1,23 @@ +%YAML 1.1 +# $Id: xlate.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +ehdr: !Ehdr + e_ident: !Ident # e_ident[] members + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + ei_osabi: ELFOSABI_FREEBSD + ei_abiversion: 1 + # other members + e_type: ET_REL + e_machine: 0x42 + e_version: EV_CURRENT + e_entry: 0xF0F0F0F0 + e_phoff: 0x0E0E0E0E + e_shoff: 0xD0D0D0D0 + e_flags: [64, 8, 2, 1] + e_ehsize: 0x0A0A + e_phentsize: 0xB0B0 + e_phnum: 0x0C0C + e_shentsize: 0xD0D0 + e_shnum: 0x0E0E + e_shstrndx: 0xF0F0 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.c b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.c new file mode 100644 index 0000000000..b361ab3f7c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.c @@ -0,0 +1,1824 @@ +/*- + * Copyright (c) 2006,2010-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate_template.c 3174 2015-03-27 17:13:41Z emaste $ + */ + +/* + * Boilerplate for testing the *_xlate() functions. + * + * Usage: + * + * #define TS_XLATESZ 32 (or 64) + * #include "xlate_template.c" + */ + +#include + +#define __XCONCAT(x,y) __CONCAT(x,y) +#ifndef __XSTRING +#define __XSTRING(x) __STRING(x) +#endif + +#include +#include +#include + +#define TS_XLATETOF __XCONCAT(elf,__XCONCAT(TS_XLATESZ,_xlatetof)) +#define TS_XLATETOM __XCONCAT(elf,__XCONCAT(TS_XLATESZ,_xlatetom)) + +#define BYTE_VAL 0xFF +#define BYTE_SEQ_LSB 0xFF, +#define BYTE_SEQ_MSB 0xFF, + +#define HALF_VAL 0xFEDC +#define HALF_SEQ_LSB 0xDC,0xFE, +#define HALF_SEQ_MSB 0xFE,0xDC, + +#define WORD_VAL 0xFEDCBA98UL +#define WORD_SEQ_LSB 0x98,0xBA,0xDC,0xFE, +#define WORD_SEQ_MSB 0xFE,0xDC,0xBA,0x98, + +#define QUAD_VAL 0xFEDCBA9876543210ULL +#define QUAD_SEQ_LSB 0x10,0x32,0x54,0x76,\ + 0x98,0xBA,0xDC,0xFE, +#define QUAD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,\ + 0x76,0x54,0x32,0x10, + +#define IDENT_BYTES 46,33,46,64,46,35,46,36,46,37,46,94,46,38,46,42 +#define IDENT_VAL { IDENT_BYTES } +#define IDENT_SEQ_LSB IDENT_BYTES, +#define IDENT_SEQ_MSB IDENT_BYTES, + + +#define TYPEDEFNAME(E,N) __XCONCAT(__XCONCAT(td_, \ + __XCONCAT(E,TS_XLATESZ)), __XCONCAT(_,N)) +#define TYPEDEFINITION(E,N) __XCONCAT(ELF_TYPE_E,__XCONCAT(TS_XLATESZ, \ + __XCONCAT(_, N))) +#define CHKFNNAME(N) __XCONCAT(__XCONCAT(td_chk_,TS_XLATESZ), \ + __XCONCAT(_,N)) +#define MEMSIZENAME(N) __XCONCAT(N,__XCONCAT(TS_XLATESZ,_SIZE)) +#define MEMSTRUCTNAME(N) __XCONCAT(N,__XCONCAT(TS_XLATESZ,_mem)) + +/* + * Definitions of 32 bit ELF file structures. + */ + +#define ELF_TYPE_E32_CAP() \ + MEMBER(c_tag, WORD) \ + MEMBER(c_un.c_val, WORD) + +#define ELF_TYPE_E32_DYN() \ + MEMBER(d_tag, WORD) \ + MEMBER(d_un.d_val, WORD) + +#define ELF_TYPE_E32_EHDR() \ + MEMBER(e_ident, IDENT) \ + MEMBER(e_type, HALF) \ + MEMBER(e_machine, HALF) \ + MEMBER(e_version, WORD) \ + MEMBER(e_entry, WORD) \ + MEMBER(e_phoff, WORD) \ + MEMBER(e_shoff, WORD) \ + MEMBER(e_flags, WORD) \ + MEMBER(e_ehsize, HALF) \ + MEMBER(e_phentsize, HALF) \ + MEMBER(e_phnum, HALF) \ + MEMBER(e_shentsize, HALF) \ + MEMBER(e_shnum, HALF) \ + MEMBER(e_shstrndx, HALF) + +#define ELF_TYPE_E32_MOVE() \ + MEMBER(m_value, QUAD) \ + MEMBER(m_info, WORD) \ + MEMBER(m_poffset, WORD) \ + MEMBER(m_repeat, HALF) \ + MEMBER(m_stride, HALF) + +#define ELF_TYPE_E32_PHDR() \ + MEMBER(p_type, WORD) \ + MEMBER(p_offset, WORD) \ + MEMBER(p_vaddr, WORD) \ + MEMBER(p_paddr, WORD) \ + MEMBER(p_filesz, WORD) \ + MEMBER(p_memsz, WORD) \ + MEMBER(p_flags, WORD) \ + MEMBER(p_align, WORD) + +#define ELF_TYPE_E32_REL() \ + MEMBER(r_offset, WORD) \ + MEMBER(r_info, WORD) + +#define ELF_TYPE_E32_RELA() \ + MEMBER(r_offset, WORD) \ + MEMBER(r_info, WORD) \ + MEMBER(r_addend, WORD) + +#define ELF_TYPE_E32_SHDR() \ + MEMBER(sh_name, WORD) \ + MEMBER(sh_type, WORD) \ + MEMBER(sh_flags, WORD) \ + MEMBER(sh_addr, WORD) \ + MEMBER(sh_offset, WORD) \ + MEMBER(sh_size, WORD) \ + MEMBER(sh_link, WORD) \ + MEMBER(sh_info, WORD) \ + MEMBER(sh_addralign, WORD) \ + MEMBER(sh_entsize, WORD) + +#define ELF_TYPE_E32_SYM() \ + MEMBER(st_name, WORD) \ + MEMBER(st_value, WORD) \ + MEMBER(st_size, WORD) \ + MEMBER(st_info, BYTE) \ + MEMBER(st_other, BYTE) \ + MEMBER(st_shndx, HALF) + +#define ELF_TYPE_E32_SYMINFO() \ + MEMBER(si_boundto, HALF) \ + MEMBER(si_flags, HALF) + +/* + * Definitions of 64 bit ELF file structures. + */ + +#define ELF_TYPE_E64_CAP() \ + MEMBER(c_tag, QUAD) \ + MEMBER(c_un.c_val, QUAD) + +#define ELF_TYPE_E64_DYN() \ + MEMBER(d_tag, QUAD) \ + MEMBER(d_un.d_val, QUAD) + +#define ELF_TYPE_E64_EHDR() \ + MEMBER(e_ident, IDENT) \ + MEMBER(e_type, HALF) \ + MEMBER(e_machine, HALF) \ + MEMBER(e_version, WORD) \ + MEMBER(e_entry, QUAD) \ + MEMBER(e_phoff, QUAD) \ + MEMBER(e_shoff, QUAD) \ + MEMBER(e_flags, WORD) \ + MEMBER(e_ehsize, HALF) \ + MEMBER(e_phentsize, HALF) \ + MEMBER(e_phnum, HALF) \ + MEMBER(e_shentsize, HALF) \ + MEMBER(e_shnum, HALF) \ + MEMBER(e_shstrndx, HALF) + +#define ELF_TYPE_E64_MOVE() \ + MEMBER(m_value, QUAD) \ + MEMBER(m_info, QUAD) \ + MEMBER(m_poffset, QUAD) \ + MEMBER(m_repeat, HALF) \ + MEMBER(m_stride, HALF) + +#define ELF_TYPE_E64_PHDR() \ + MEMBER(p_type, WORD) \ + MEMBER(p_flags, WORD) \ + MEMBER(p_offset, QUAD) \ + MEMBER(p_vaddr, QUAD) \ + MEMBER(p_paddr, QUAD) \ + MEMBER(p_filesz, QUAD) \ + MEMBER(p_memsz, QUAD) \ + MEMBER(p_align, QUAD) + +#define ELF_TYPE_E64_REL() \ + MEMBER(r_offset, QUAD) \ + MEMBER(r_info, QUAD) + +#define ELF_TYPE_E64_RELA() \ + MEMBER(r_offset, QUAD) \ + MEMBER(r_info, QUAD) \ + MEMBER(r_addend, QUAD) + +#define ELF_TYPE_E64_SHDR() \ + MEMBER(sh_name, WORD) \ + MEMBER(sh_type, WORD) \ + MEMBER(sh_flags, QUAD) \ + MEMBER(sh_addr, QUAD) \ + MEMBER(sh_offset, QUAD) \ + MEMBER(sh_size, QUAD) \ + MEMBER(sh_link, WORD) \ + MEMBER(sh_info, WORD) \ + MEMBER(sh_addralign, QUAD) \ + MEMBER(sh_entsize, QUAD) + +#define ELF_TYPE_E64_SYM() \ + MEMBER(st_name, WORD) \ + MEMBER(st_info, BYTE) \ + MEMBER(st_other, BYTE) \ + MEMBER(st_shndx, HALF) \ + MEMBER(st_value, QUAD) \ + MEMBER(st_size, QUAD) \ + +#define ELF_TYPE_E64_SYMINFO() \ + MEMBER(si_boundto, HALF) \ + MEMBER(si_flags, HALF) + +static unsigned char TYPEDEFNAME(L,CAP)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,CAP)() +}; +static unsigned char TYPEDEFNAME(M,CAP)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,CAP)() +}; + +static unsigned char TYPEDEFNAME(L,DYN)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,DYN)() +}; +static unsigned char TYPEDEFNAME(M,DYN)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,DYN)() +}; + +static unsigned char TYPEDEFNAME(L,EHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,EHDR)() +}; +static unsigned char TYPEDEFNAME(M,EHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,EHDR)() +}; + +static unsigned char TYPEDEFNAME(L,HALF)[] = { + HALF_SEQ_LSB +}; +static unsigned char TYPEDEFNAME(M,HALF)[] = { + HALF_SEQ_MSB +}; + +static unsigned char TYPEDEFNAME(L,MOVE)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,MOVE)() +}; +static unsigned char TYPEDEFNAME(M,MOVE)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,MOVE)() +}; + +static unsigned char TYPEDEFNAME(L,PHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,PHDR)() +}; +static unsigned char TYPEDEFNAME(M,PHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,PHDR)() +}; + +static unsigned char TYPEDEFNAME(L,REL)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,REL)() +}; +static unsigned char TYPEDEFNAME(M,REL)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,REL)() +}; + +static unsigned char TYPEDEFNAME(L,RELA)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,RELA)() +}; +static unsigned char TYPEDEFNAME(M,RELA)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,RELA)() +}; + +static unsigned char TYPEDEFNAME(L,SHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,SHDR)() +}; +static unsigned char TYPEDEFNAME(M,SHDR)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,SHDR)() +}; + +static unsigned char TYPEDEFNAME(L,SYM)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,SYM)() +}; +static unsigned char TYPEDEFNAME(M,SYM)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,SYM)() +}; + +static unsigned char TYPEDEFNAME(L,SYMINFO)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_LSB + TYPEDEFINITION(L,SYMINFO)() +}; +static unsigned char TYPEDEFNAME(M,SYMINFO)[] = { +#undef MEMBER +#define MEMBER(N,K) K##_SEQ_MSB + TYPEDEFINITION(M,SYMINFO)() +}; + +static unsigned char TYPEDEFNAME(L,QUAD)[] = { + QUAD_SEQ_LSB +}; + +static unsigned char TYPEDEFNAME(M,QUAD)[] = { + QUAD_SEQ_MSB +}; + +static unsigned char TYPEDEFNAME(L,WORD)[] = { + WORD_SEQ_LSB +}; +static unsigned char TYPEDEFNAME(M,WORD)[] = { + WORD_SEQ_MSB +}; + +#if TS_XLATESZ == 32 +/* + * 32 bit reference structures. + */ + +#define td_L32_ADDR td_L32_WORD +#define td_M32_ADDR td_M32_WORD +#define td_L32_SWORD td_L32_WORD +#define td_M32_SWORD td_M32_WORD +#define td_L32_OFF td_L32_WORD +#define td_M32_OFF td_M32_WORD + +static Elf32_Addr MEMSTRUCTNAME(ADDR) = WORD_VAL; +#define ADDR32_SIZE sizeof(Elf32_Addr) + +static Elf32_Cap MEMSTRUCTNAME(CAP) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_CAP() +}; +#define CAP32_SIZE sizeof(Elf32_Cap) + +static Elf32_Dyn MEMSTRUCTNAME(DYN) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_DYN() +}; +#define DYN32_SIZE sizeof(Elf32_Dyn) + +static Elf32_Ehdr MEMSTRUCTNAME(EHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_EHDR() +}; +#define EHDR32_SIZE sizeof(Elf32_Ehdr) + +static Elf32_Half MEMSTRUCTNAME(HALF) = HALF_VAL; +#define HALF32_SIZE sizeof(Elf32_Half) + +static Elf32_Move MEMSTRUCTNAME(MOVE) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_MOVE() +}; +#define MOVE32_SIZE sizeof(Elf32_Move) + +static Elf32_Off MEMSTRUCTNAME(OFF) = WORD_VAL; +#define OFF32_SIZE sizeof(Elf32_Off) + +static Elf32_Phdr MEMSTRUCTNAME(PHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_PHDR() +}; +#define PHDR32_SIZE sizeof(Elf32_Phdr) + +static Elf32_Rel MEMSTRUCTNAME(REL) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_REL() +}; +#define REL32_SIZE sizeof(Elf32_Rel) + +static Elf32_Rela MEMSTRUCTNAME(RELA) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_RELA() +}; +#define RELA32_SIZE sizeof(Elf32_Rela) + +static Elf32_Shdr MEMSTRUCTNAME(SHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_SHDR() +}; +#define SHDR32_SIZE sizeof(Elf32_Shdr) + +static Elf32_Sword MEMSTRUCTNAME(SWORD) = WORD_VAL; +#define SWORD32_SIZE sizeof(Elf32_Sword) + +static Elf32_Sym MEMSTRUCTNAME(SYM) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_SYM() +}; +#define SYM32_SIZE sizeof(Elf32_Sym) + +static Elf32_Syminfo MEMSTRUCTNAME(SYMINFO) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E32_SYMINFO() +}; +#define SYMINFO32_SIZE sizeof(Elf32_Syminfo) + +static Elf32_Word MEMSTRUCTNAME(WORD) = WORD_VAL; +#define WORD32_SIZE sizeof(Elf32_Word) + +#else +/* + * 64 bit reference structures. + */ + +#define td_L64_ADDR td_L64_QUAD +#define td_M64_ADDR td_M64_QUAD +#define td_L64_OFF td_L64_QUAD +#define td_M64_OFF td_M64_QUAD +#define td_L64_SWORD td_L64_WORD +#define td_M64_SWORD td_M64_WORD +#define td_L64_SXWORD td_L64_QUAD +#define td_M64_SXWORD td_M64_QUAD +#define td_L64_XWORD td_L64_QUAD +#define td_M64_XWORD td_M64_QUAD + +static Elf64_Addr MEMSTRUCTNAME(ADDR) = QUAD_VAL; +#define ADDR64_SIZE sizeof(Elf64_Addr) + +static Elf64_Cap MEMSTRUCTNAME(CAP) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_CAP() +}; +#define CAP64_SIZE sizeof(Elf64_Cap) + +static Elf64_Dyn MEMSTRUCTNAME(DYN) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_DYN() +}; +#define DYN64_SIZE sizeof(Elf64_Dyn) + +static Elf64_Ehdr MEMSTRUCTNAME(EHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_EHDR() +}; +#define EHDR64_SIZE sizeof(Elf64_Ehdr) + +static Elf64_Half MEMSTRUCTNAME(HALF) = HALF_VAL; +#define HALF64_SIZE sizeof(Elf64_Half) + +static Elf64_Move MEMSTRUCTNAME(MOVE) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_MOVE() +}; +#define MOVE64_SIZE sizeof(Elf64_Move) + +static Elf64_Phdr MEMSTRUCTNAME(PHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_PHDR() +}; +#define PHDR64_SIZE sizeof(Elf64_Phdr) + +static Elf64_Off MEMSTRUCTNAME(OFF) = QUAD_VAL; +#define OFF64_SIZE sizeof(Elf64_Off) + +static Elf64_Rel MEMSTRUCTNAME(REL) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_REL() +}; +#define REL64_SIZE sizeof(Elf64_Rel) + +static Elf64_Rela MEMSTRUCTNAME(RELA) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_RELA() +}; +#define RELA64_SIZE sizeof(Elf64_Rela) + +static Elf64_Shdr MEMSTRUCTNAME(SHDR) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_SHDR() +}; +#define SHDR64_SIZE sizeof(Elf64_Shdr) + +static Elf64_Sword MEMSTRUCTNAME(SWORD) = WORD_VAL; +#define SWORD64_SIZE sizeof(Elf64_Sword) + +static Elf64_Sxword MEMSTRUCTNAME(SXWORD) = QUAD_VAL; +#define SXWORD64_SIZE sizeof(Elf64_Sxword) + +static Elf64_Sym MEMSTRUCTNAME(SYM) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_SYM() +}; +#define SYM64_SIZE sizeof(Elf64_Sym) + +static Elf64_Syminfo MEMSTRUCTNAME(SYMINFO) = { +#undef MEMBER +#define MEMBER(N,K) .N = K##_VAL , + ELF_TYPE_E64_SYMINFO() +}; +#define SYMINFO64_SIZE sizeof(Elf64_Syminfo) + +static Elf64_Word MEMSTRUCTNAME(WORD) = WORD_VAL; +#define WORD64_SIZE sizeof(Elf64_Word) + +static Elf64_Xword MEMSTRUCTNAME(XWORD) = QUAD_VAL; +#define XWORD64_SIZE sizeof(Elf64_Xword) + +#endif /* TS_XLATESZ == 32 */ + + +#ifndef _TESTDATA_STRUCT_ +#define _TESTDATA_STRUCT_ 1 +struct testdata { + char *tsd_name; + Elf_Type tsd_type; + void *tsd_mem; + size_t tsd_fsz; + size_t tsd_msz; + const unsigned char *tsd_lsb; + const unsigned char *tsd_msb; +}; +#endif /*_TESTDATA_STRUCT_*/ + +#define TESTDATASET __XCONCAT(tests,TS_XLATESZ) +static struct testdata TESTDATASET [] = { +#undef DEFINE_TEST_DATA +#define DEFINE_TEST_DATA(N) { \ + .tsd_name = #N, \ + .tsd_type = ELF_T_##N, \ + .tsd_fsz = sizeof(TYPEDEFNAME(L,N)), \ + .tsd_msz = MEMSIZENAME(N), \ + .tsd_mem = (void *) &MEMSTRUCTNAME(N), \ + .tsd_lsb = TYPEDEFNAME(L,N), \ + .tsd_msb = TYPEDEFNAME(M,N), \ + } +#if TS_XLATESZ == 32 + DEFINE_TEST_DATA(ADDR), + DEFINE_TEST_DATA(CAP), + DEFINE_TEST_DATA(DYN), + DEFINE_TEST_DATA(EHDR), + DEFINE_TEST_DATA(HALF), + DEFINE_TEST_DATA(MOVE), + DEFINE_TEST_DATA(OFF), + DEFINE_TEST_DATA(PHDR), + DEFINE_TEST_DATA(REL), + DEFINE_TEST_DATA(RELA), + DEFINE_TEST_DATA(SHDR), + DEFINE_TEST_DATA(SWORD), + DEFINE_TEST_DATA(SYM), + DEFINE_TEST_DATA(SYMINFO), + DEFINE_TEST_DATA(WORD), +#else + DEFINE_TEST_DATA(ADDR), + DEFINE_TEST_DATA(CAP), + DEFINE_TEST_DATA(DYN), + DEFINE_TEST_DATA(EHDR), + DEFINE_TEST_DATA(HALF), + DEFINE_TEST_DATA(MOVE), + DEFINE_TEST_DATA(OFF), + DEFINE_TEST_DATA(PHDR), + DEFINE_TEST_DATA(REL), + DEFINE_TEST_DATA(RELA), + DEFINE_TEST_DATA(SHDR), + DEFINE_TEST_DATA(SWORD), + DEFINE_TEST_DATA(SXWORD), + DEFINE_TEST_DATA(SYM), + DEFINE_TEST_DATA(SYMINFO), + DEFINE_TEST_DATA(WORD), + DEFINE_TEST_DATA(XWORD), +#endif /* TS_XLATESZ == 32 */ + { .tsd_name = NULL } +}; + + +#define NCOPIES 3 +#define NOFFSET 8 /* check every alignment in a quad word */ + +#ifndef NO_TESTCASE_FUNCTIONS + +static int +check_xlate(Elf_Data *xlator(Elf_Data *d, const Elf_Data *s, unsigned int enc), + int ed, Elf_Data *dst, Elf_Data *src, struct testdata *td, int ncopies) +{ + Elf_Data *dstret; + size_t msz; + + msz = td->tsd_msz; + + /* Invoke translator */ + if ((dstret = xlator(dst, src, ed)) != dst) { + tet_printf("fail: \"%s\" " __XSTRING(TC_XLATETOM) + ": %s", td->tsd_name, elf_errmsg(-1)); + tet_result(TET_FAIL); + return (0); + } + + /* Check return parameters. */ + if (dst->d_type != td->tsd_type || dst->d_size != msz*ncopies) { + tet_printf("fail: \"%s\" type(ret=%d,expected=%d) " + "size (ret=%d,expected=%d).", td->tsd_name, + dst->d_type, td->tsd_type, dst->d_size, msz*ncopies); + tet_result(TET_FAIL); + return (0); + } + + return (1); +} + +/* + * Check byte conversions: + */ + +void +__XCONCAT(tcXlate_tpByte,TS_XLATESZ)(void) +{ + Elf_Data dst, src; + int i, offset, sz; + char *filebuf, *membuf, *t, *ref; + + ref = TYPEDEFNAME(L,QUAD); + sz = sizeof(TYPEDEFNAME(L,QUAD)); + + if ((membuf = malloc(sz*NCOPIES)) == NULL || + (filebuf = malloc(sz*NCOPIES+NOFFSET)) == NULL) { + if (membuf) + free(membuf); + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + /* + * Check memory to file conversions. + */ + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, ref, sz) + sz; + + src.d_buf = membuf; + src.d_size = sz*NCOPIES; + src.d_type = ELF_T_BYTE; + src.d_version = EV_CURRENT; + + tet_infoline("assertion: Byte TOF() succeeds."); + + for (offset = 0; offset < NOFFSET; offset++) { + /* + * LSB + */ + dst.d_buf = filebuf + offset; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (TS_XLATETOF(&dst,&src,ELFDATA2LSB) != &dst || + dst.d_size != sz*NCOPIES) { + tet_infoline("fail: LSB TOF() conversion."); + tet_result(TET_FAIL); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + tet_infoline("fail: LSB TOF() memcmp()."); + tet_result(TET_FAIL); + goto done; + } + + /* + * MSB + */ + dst.d_buf = filebuf + offset; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (TS_XLATETOF(&dst,&src,ELFDATA2MSB) != &dst || + dst.d_size != sz*NCOPIES) { + tet_infoline("fail: MSB TOF() conversion."); + tet_result(TET_FAIL); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + tet_infoline("fail: MSB TOF() memcmp()."); + tet_result(TET_FAIL); + goto done; + } + } + + /* + * Check file to memory conversions. + */ + + tet_infoline("assertion: Byte TOM() succeeds."); + + ref = TYPEDEFNAME(M,QUAD); + sz = sizeof(TYPEDEFNAME(M,QUAD)); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t,ref,sz); + + src.d_size = sz*NCOPIES; + src.d_type = ELF_T_BYTE; + src.d_version = EV_CURRENT; + + /* + * LSB + */ + dst.d_buf = membuf; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (TS_XLATETOM(&dst,&src,ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES) { + tet_infoline("fail: LSB TOM() conversion."); + tet_result(TET_FAIL); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + tet_infoline("fail: LSB TOM() memcmp()."); + tet_result(TET_FAIL); + goto done; + } + + /* + * MSB + */ + dst.d_buf = membuf; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (TS_XLATETOM(&dst,&src,ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES) { + tet_infoline("fail: MSB TOM() conversion."); + tet_result(TET_FAIL); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + tet_infoline("fail: MSB TOM() memcmp()."); + tet_result(TET_FAIL); + goto done; + } + } + + tet_result(TET_PASS); + + done: + if (membuf) + free(membuf); + if (filebuf) + free(filebuf); +} + +/* + * Check a byte conversion on a shared buffer. + */ + +void +__XCONCAT(tcXlate_tpByteShared,TS_XLATESZ)(void) +{ + int i; + size_t sz; + Elf_Data dst, src; + char *membuf, *t, *ref; + +#define PREPARE_SHARED(T,SZ) do { \ + src.d_buf = dst.d_buf = membuf; \ + src.d_size = dst.d_size = (SZ) * NCOPIES; \ + src.d_type = dst.d_type = (T); \ + src.d_version = dst.d_version = EV_CURRENT; \ + } while (0) + +#define VERIFY(R,SZ) do { \ + t = dst.d_buf; \ + for (i = 0; i < NCOPIES; i++, t += (SZ)) \ + if (memcmp((R), t, (SZ))) { \ + tet_infoline("fail: LSB TOF() " \ + "memcmp()."); \ + tet_result(TET_FAIL); \ + goto done; \ + } \ + } while (0) + + membuf = NULL; + ref = TYPEDEFNAME(L,QUAD); + sz = sizeof(TYPEDEFNAME(L,QUAD)); + + if ((membuf = malloc(sz * NCOPIES)) == NULL) { + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, ref, sz) + sz; + + tet_infoline("assertion: byte TOF() on a shared dst/src arena " + "succeeds."); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (TS_XLATETOF(&dst, &src, ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + tet_printf("fail: LSB TOF() conversion: %s.", + elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(ref,sz); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (TS_XLATETOF(&dst, &src, ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + tet_printf("fail: MSB TOF() conversion: %s.", + elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(ref,sz); + + tet_infoline("assertion: byte TOM() on a shared dst/src arena " + "succeeds."); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (TS_XLATETOM(&dst, &src, ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + tet_printf("fail: LSB TOM() conversion: %s.", + elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(ref,sz); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (TS_XLATETOM(&dst, &src, ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + tet_printf("fail: MSB TOM() conversion: %s.", + elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(ref,sz); + + tet_result(TET_PASS); + + done: + free(membuf); +} + +/* + * Check non-byte conversions from file representations to memory. + */ +void +__XCONCAT(tcXlate_tpToM,TS_XLATESZ)(void) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, offset; + char *srcbuf, *membuf, *t; + + srcbuf = NULL; /* file data (bytes) */ + membuf = NULL; /* memory data (struct) */ + + /* Loop over all types */ + for (td = TESTDATASET; td->tsd_name; td++) { + + fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type, + 1, EV_CURRENT); + + msz = td->tsd_msz; + + if (msz == 0 || + fsz != td->tsd_fsz) { + tet_printf("? %s: msz=%d fsz=%d td->fsz=%d.", + td->tsd_name, msz, fsz, td->tsd_fsz); + } + + assert(fsz == td->tsd_fsz); + + /* + * allocate space for NCOPIES of data + offset for file data and + * NCOPIES of memory data. + */ + if ((srcbuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL || + ((membuf = malloc(NCOPIES*msz))) == NULL) { + if (srcbuf) + free(srcbuf); + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + + tet_printf("assertion: "__XSTRING(TS_XLATETOM)"(%s) succeeds.", + td->tsd_name); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = t = srcbuf + offset; + src.d_size = fsz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + dst.d_buf = membuf; + dst.d_size = msz * NCOPIES; + dst.d_version = EV_CURRENT; + + + /* + * Check conversion of LSB encoded data. + */ + + /* copy `NCOPIES*fsz' bytes in `srcbuf+offset' */ + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_lsb, fsz); + t += fsz; + } + (void) memset(membuf, 0, NCOPIES*msz); + + if (check_xlate(TS_XLATETOM, ELFDATA2LSB, &dst, &src, + td, NCOPIES) == 0) + goto done; + + /* compare the retrieved data with the canonical value */ + t = dst.d_buf; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_mem, msz)) { + tet_printf("fail: \"%s\" LSB memory " + "compare failed.", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + t += msz; + } + + /* + * Check conversion of MSB encoded data. + */ + + t = srcbuf + offset; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_msb, fsz); + t += fsz; + } + (void) memset(membuf, 0, NCOPIES*msz); + if (check_xlate(TS_XLATETOM, ELFDATA2MSB, &dst, &src, + td, NCOPIES) == 0) + goto done; + + /* compare the retrieved data with the canonical value */ + t = dst.d_buf; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_mem, msz)) { + tet_printf("fail: \"%s\" MSB memory " + "compare failed.", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + t += msz; + } + } + + free(srcbuf); srcbuf = NULL; + free(membuf); membuf = NULL; + } + + tet_result(TET_PASS); + + done: + if (srcbuf) + free(srcbuf); + if (membuf) + free(membuf); +} + +void +__XCONCAT(tcXlate_tpToMShared,TS_XLATESZ)(void) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, result; + char *membuf, *t; + + membuf = NULL; + + for (td = TESTDATASET; td->tsd_name; td++) { + + tet_printf("assertion: in-place "__XSTRING(TS_XLATETOM)"(\"%s\").", + td->tsd_name); + + fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type, + 1, EV_CURRENT); + msz = td->tsd_msz; + + assert(msz >= fsz); + + if ((membuf = malloc(fsz * NCOPIES)) == NULL) { + tet_printf("unresolved: \"%s\" malloc() failed.", + td->tsd_name); + tet_result(TET_UNRESOLVED); + goto done; + } + + /* + * In-place conversion of LSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_lsb, fsz) + fsz; + + PREPARE_SHARED(td->tsd_type, fsz); + result = TS_XLATETOM(&dst, &src, ELFDATA2LSB) == &dst; + + if (fsz < msz) { + /* conversion should fail with ELF_E_DATA */ + if (result || elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" LSB TOM() succeeded " + "with fsz < msz", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + free(membuf); membuf = NULL; + continue; + } + + /* conversion should have succeeded. */ + if (!result) { + tet_printf("fail: \"%s\" LSB TOM() failed.", + td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + + VERIFY(td->tsd_mem,msz); + + /* + * In-place conversion of MSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_msb, fsz) + fsz; + + PREPARE_SHARED(td->tsd_type, fsz); + result = TS_XLATETOM(&dst, &src, ELFDATA2MSB) == &dst; + + if (fsz < msz) { + /* conversion should fail with ELF_E_DATA */ + if (result || elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" MSB TOM() succeeded " + "with fsz < msz", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + free(membuf); membuf = NULL; + continue; + } + + /* conversion should have succeeded. */ + if (!result) { + tet_printf("fail: \"%s\" MSB TOM() failed.", + td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + + VERIFY(td->tsd_mem,msz); + + } + + tet_result(TET_PASS); + + done: + if (membuf) + free(membuf); +} + + +/* + * Check non-byte conversions from memory to file. + */ +void +__XCONCAT(tcXlate_tpToF,TS_XLATESZ)(void) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, offset; + char *filebuf, *membuf, *t; + + filebuf = NULL; /* file data (bytes) */ + membuf = NULL; /* memory data (struct) */ + + /* Loop over all types */ + for (td = TESTDATASET; td->tsd_name; td++) { + + fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type, + 1, EV_CURRENT); + + msz = td->tsd_msz; + + if (msz == 0 || + fsz != td->tsd_fsz) { + tet_printf("? %s: msz=%d fsz=%d td->fsz=%d.", + td->tsd_name, msz, fsz, td->tsd_fsz); + } + + assert(msz > 0); + assert(fsz == td->tsd_fsz); + + /* + * allocate space for NCOPIES of data + offset for file data and + * NCOPIES of memory data. + */ + if ((filebuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL || + ((membuf = malloc(NCOPIES*msz))) == NULL) { + if (filebuf) + free(filebuf); + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + + tet_printf("assertion: "__XSTRING(TS_XLATETOF)"(%s) succeeds.", + td->tsd_name); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = membuf; + src.d_size = msz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + /* + * Check LSB conversion. + */ + + /* copy `NCOPIES' of canonical memory data to the src buffer */ + t = membuf; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_mem, msz); + t += msz; + } + (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET); + + dst.d_buf = filebuf + offset; + dst.d_size = fsz * NCOPIES; + dst.d_version = EV_CURRENT; + + if (check_xlate(TS_XLATETOF, ELFDATA2LSB, &dst, &src, + td, NCOPIES) == 0) + goto done; + + /* compare converted data to canonical form */ + t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_lsb, fsz)) { + tet_printf("fail: \"%s\" LSB memory " + "compare.", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + t += fsz; + } + + /* + * Check MSB conversion. + */ + t = membuf; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_mem, msz); + t += msz; + } + (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET); + + dst.d_buf = filebuf + offset; + dst.d_size = fsz * NCOPIES; + dst.d_version = EV_CURRENT; + + if (check_xlate(TS_XLATETOF, ELFDATA2MSB, &dst, &src, + td, NCOPIES) == 0) + goto done; + + /* compare converted data to canonical form */ + t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_msb, fsz)) { + tet_printf("fail: \"%s\" MSB memory " + "compare.", td->tsd_name); + tet_result(TET_FAIL); + goto done; + } + t += fsz; + } + } + + free(filebuf); filebuf = NULL; + free(membuf); membuf = NULL; + } + + tet_result(TET_PASS); + + done: + if (filebuf) + free(filebuf); + if (membuf) + free(membuf); +} + +void +__XCONCAT(tcXlate_tpToFShared,TS_XLATESZ)(void) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i; + char *membuf, *t; + + membuf = NULL; + + for (td = TESTDATASET; td->tsd_name; td++) { + + tet_printf("assertion: in-place "__XSTRING(TS_XLATETOF)"(\"%s\").", + td->tsd_name); + + fsz = __XCONCAT(__XCONCAT(elf,TS_XLATESZ),_fsize)(td->tsd_type, + 1, EV_CURRENT); + msz = td->tsd_msz; + + assert(msz >= fsz); + + if ((membuf = malloc(msz * NCOPIES)) == NULL) { + tet_printf("unresolved: \"%s\" malloc() failed.", + td->tsd_name); + tet_result(TET_UNRESOLVED); + goto done; + } + + /* + * In-place conversion to LSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_mem, msz) + msz; + + PREPARE_SHARED(td->tsd_type, msz); + if (TS_XLATETOF(&dst, &src, ELFDATA2LSB) != &dst) { + tet_printf("fail: \"%s\" LSB TOF() failed: %s.", + td->tsd_name, elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(td->tsd_lsb,fsz); + + /* + * In-place conversion to MSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_mem, msz) + msz; + + PREPARE_SHARED(td->tsd_type, msz); + if (TS_XLATETOF(&dst, &src, ELFDATA2MSB) != &dst) { + tet_printf("fail: \"%s\" MSB TOF() failed: %s.", + td->tsd_name, elf_errmsg(-1)); + tet_result(TET_FAIL); + goto done; + } + VERIFY(td->tsd_msb,fsz); + + } + + tet_result(TET_PASS); + + done: + if (membuf) + free(membuf); +} + + + +/* + * Various checks for invalid arguments. + */ + +void +__XCONCAT(tcArgs_tpNullArgs,TS_XLATESZ)(void) +{ + Elf_Data ed; + int result; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/" + __XSTRING(TS_XLATETOM) " with NULL arguments fail " + "with ELF_E_ARGUMENT."); + + result = TET_PASS; + + if (TS_XLATETOF(NULL,&ed,ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (TS_XLATETOF(&ed,NULL,ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (TS_XLATETOM(NULL,&ed,ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (TS_XLATETOM(&ed,NULL,ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + tet_result(result); +} + +void +__XCONCAT(tcArgs_tpBadType,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + char buf[1024]; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/" + __XSTRING(TS_XLATETOM) " with an out of range type " + "fails with ELF_E_DATA."); + + result = TET_PASS; + + es.d_version = ed.d_version = EV_CURRENT; + es.d_buf = ed.d_buf = buf; + es.d_size = ed.d_size = sizeof(buf); + + es.d_type = (Elf_Type) -1; + + if (TS_XLATETOF(&ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + es.d_type = ELF_T_NUM; + + if (TS_XLATETOF(&ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + tet_result(result); +} + +void +__XCONCAT(tcArgs_tpBadEncoding,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF) "/" + __XSTRING(TS_XLATETOM) " (*,*,BADENCODING) " + "fails with ELF_E_ARGUMENT."); + + result = TET_PASS; + + if (TS_XLATETOF(&ed,&es,ELFDATANONE-1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (TS_XLATETOF(&ed,&es,ELFDATA2MSB+1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (TS_XLATETOM(&ed,&es,ELFDATANONE-1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (TS_XLATETOM(&ed,&es,ELFDATA2MSB+1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + tet_result(result); +} + +void +__XCONCAT(tcArg_tpDstSrcVersionToF,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() / " + __XSTRING(TS_XLATETOM) "() with unequal " + "src,dst versions fails with ELF_E_UNIMPL."); + + es.d_buf = ed.d_buf = buf; + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_NONE; + + result = TET_PASS; + + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_UNIMPL) + result = TET_FAIL; + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_UNIMPL) + result = TET_FAIL; + + tet_result(result); +} + +/* + * Check for an unimplemented type. + */ +void +__XCONCAT(tcArg_tpUnimplemented,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int i, result; + char *buf; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() on " + "unimplemented types will with ELF_E_UNIMPL."); + + /* + * allocate a buffer that is large enough for any potential + * ELF data structure. + */ + if ((buf = malloc(1024)) == NULL) { + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + return; + } + + ed.d_buf = es.d_buf = buf; + ed.d_size = es.d_size = 1024; + ed.d_version = es.d_version = EV_CURRENT; + + result = TET_PASS; + + for (i = 0; i < ELF_T_NUM; i++) { + switch (i) { + case ELF_T_MOVEP: +#if TS_XLATESZ == 32 + case ELF_T_SXWORD: + case ELF_T_XWORD: +#endif + break; + default: + continue; + } + + es.d_type = i; + + if (TS_XLATETOF(&ed,&es,ELFDATA2LSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + tet_printf("fail: TOF/LSB/type=%d.", i); + result = TET_FAIL; + } + + if (TS_XLATETOF(&ed,&es,ELFDATA2MSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + tet_printf("fail: TOF/MSB/type=%d.", i); + result = TET_FAIL; + } + + if (TS_XLATETOM(&ed,&es,ELFDATA2LSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + tet_printf("fail: TOM/LSB/type=%d.", i); + result = TET_FAIL; + } + + if (TS_XLATETOM(&ed,&es,ELFDATA2MSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + tet_printf("fail: TOM/MSB/type=%d.", i); + result = TET_FAIL; + } + } + + tet_result(result); + free(buf); +} + +/* + * Check for null buffer pointers. + */ +void +__XCONCAT(tcBuffer_tpNullDataPtr,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + tet_infoline("assertion: "__XSTRING(TS_XLATETOF)"() / " + __XSTRING(TS_XLATETOM) "() with a null " + "src,dst buffer pointer fails with ELF_E_DATA."); + + result = TET_PASS; + + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_CURRENT; + + es.d_buf = NULL; + ed.d_buf = buf; + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + es.d_buf = buf; + ed.d_buf = NULL; + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + tet_result(result); +} + +/* + * Misaligned data. + */ + +void +__XCONCAT(tcBuffer_tpMisaligned,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + size_t fsz, msz; + char *sb, *db; + struct testdata *td; + + tet_infoline("assertion: misaligned buffers are rejected with " + "ELF_E_DATA."); + + sb = db = NULL; + if ((sb = malloc(1024)) == NULL || + (db = malloc(1024)) == NULL) { + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + if (sb) + free(sb); + return; + } + + result = TET_PASS; + + for (td = TESTDATASET; td->tsd_name; td++) { + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + es.d_type = td->tsd_type; + es.d_version = EV_CURRENT; + + /* Misalign the destination for to-memory xfers */ + es.d_size = (1024 / fsz) * fsz; /* round down */ + es.d_buf = sb; + + ed.d_buf = db + 1; /* guaranteed to be misaliged */ + ed.d_version = EV_CURRENT; + ed.d_size = 1024; + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOM alignment.", + td->tsd_name); + result = TET_FAIL; + } + + /* Misalign the source for to-file xfers */ + es.d_buf = sb + 1; + es.d_size = (1024/msz) * msz; /* round down */ + ed.d_buf = db; + + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOF alignment.", + td->tsd_name); + result = TET_FAIL; + } + } + + tet_result(result); + free(sb); + free(db); +} + + +/* + * Overlapping buffers. + */ +void +__XCONCAT(tcBuffer_tpOverlap,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + tet_infoline("assertion: overlapping buffers are rejected with " + "ELF_E_DATA."); + + es.d_buf = buf; ed.d_buf = buf+1; + es.d_version = ed.d_version = EV_CURRENT; + es.d_size = ed.d_size = sizeof(buf); + es.d_type = ELF_T_BYTE; + + result = TET_PASS; + + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_infoline("fail: "__XSTRING(TS_XLATETOF)); + result = TET_FAIL; + } + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_infoline("fail: "__XSTRING(TS_XLATETOM)); + result = TET_FAIL; + } + + tet_result(result); +} + +/* + * Non-integral number of src elements. + */ +void +__XCONCAT(tcBuffer_tpSrcExtra,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + size_t fsz, msz; + char *sb, *db; + struct testdata *td; + + tet_infoline("assertion: mis-sized buffers are rejected with " + "ELF_E_DATA."); + + sb = db = NULL; + if ((sb = malloc(1024)) == NULL || + (db = malloc(1024)) == NULL) { + tet_infoline("unresolved: malloc() failed."); + tet_result(TET_UNRESOLVED); + if (sb) + free(sb); + return; + } + + result = TET_PASS; + + for (td = TESTDATASET; td->tsd_name; td++) { + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + es.d_type = td->tsd_type; + es.d_version = EV_CURRENT; + ed.d_version = EV_CURRENT; + ed.d_buf = db; + es.d_buf = sb; + ed.d_size = 1024; + + /* Pad src bytes with extra bytes for to memor */ + es.d_size = fsz+1; + + if (TS_XLATETOM(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOM buffer size.", + td->tsd_name); + result = TET_FAIL; + } + + es.d_size = msz+1; + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOF buffer size.", + td->tsd_name); + result = TET_FAIL; + } + } + + tet_result(result); + free(sb); + free(db); +} + +void +__XCONCAT(tcBuffer_tpDstTooSmall,TS_XLATESZ)(void) +{ + Elf_Data ed, es; + int result; + struct testdata *td; + size_t fsz, msz; + char buf[1024]; + + result = TET_PASS; + + tet_infoline("assertion: too small destination buffers are rejected " + "with ELF_E_DATA."); + + for (td = TESTDATASET; td->tsd_name; td++) { + msz = td->tsd_msz; + fsz = td->tsd_fsz; + + es.d_type = td->tsd_type; + es.d_version = ed.d_version = EV_CURRENT; + es.d_buf = ed.d_buf = buf; + + es.d_size = (sizeof(buf) / msz) * msz; + ed.d_size = 1; /* too small a size */ + + if (TS_XLATETOF(&ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOF dst size.", + td->tsd_name); + result = TET_FAIL; + } + + es.d_size = (sizeof(buf) / fsz) * fsz; + if (TS_XLATETOM(&ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + tet_printf("fail: \"%s\" TOF dst size.", + td->tsd_name); + result = TET_FAIL; + } + } + + tet_result(result); +} + +#endif /* NO_TESTCASE_FUNCTIONS */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.m4 new file mode 100644 index 0000000000..05efc59f21 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xlate_template.m4 @@ -0,0 +1,1436 @@ +/*- + * Copyright (c) 2006,2010-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate_template.m4 2053 2011-10-26 11:50:18Z jkoshy $ + */ + +/* + * Boilerplate for testing the *_xlate() functions. + * + * This M4-based macro set attempts to generate test functions for + * testing the elf{32,54}_xlateto{f,m}() and gelf_xlateto{f,m}() + * functions. + * + * The following needs to be kept in mind: + * + * - 32 bit ELF code uses a subset of the primitive types used by + * 64 bit code. In particular, the Sxword and Xword types do not + * exist in the 32 bit ELF definition. + * - Elf type identifiers `FOO' usually map to a C type name `Foo', + * except in the case of a few types. + * - Elf types `ADDR' and `OFF' use ELF class dependent sizes for initializers. + * - Each Elf type needs to be associated with a FreeBSD version where + * it first appeared, so that the generated code can be made compilable + * on older systems. + */ + +divert(-1) + +ifdef(`TPFNNAME',`',`errprint(`Macro TPFNNAME must be defined.')m4exit(1)') +ifelse(index(TPFNNAME,`32'),-1,`define(`ISELF64',`Y')') +ifelse(index(TPFNNAME,`64'),-1,`define(`ISELF32',`Y')') +ifelse(index(TPFNNAME,`gelf'),0,`define(`ISGELF',`Y')') + +/* + * TO_M_OR_F(M_TEXT,F_TEXT) + * + * Selectively expand one of `M_TEXT' or `F_TEXT' depending on whether + * the function being tested is a *_tom() or *_tof() function. + */ + +define(`TO_M_OR_F',`ifelse(eval(index(TPFNNAME,`tom') > 0),1,`$1',`$2')') +define(`__N__',TOUPPER(substr(TPFNNAME,regexp(TPFNNAME,`to[fm]')))) + +/* + * DO(SIZE,TEXT) + * + * Invoke `TEXT' in an environment that defines `__SZ__' to SIZE. + */ +define(`DO',`pushdef(`__SZ__',$1)$2`'popdef(`__SZ__')') + +/* + * ELF_TYPE_LIST((TYPE, VERSION)...) + * + * Lists all ELF types for which macro expansion is desired and associates + * each such type with its `C Name'. + * + * Note that the following ELF types with variable sized `file'/memory + * representations need to be handled specially and are not part of + * this list: + * - ELF_T_BYTE + * - ELF_T_GNUHASH + * - ELF_T_NOTE + * - ELF_T_VDEF + * - ELF_T_VNEED + */ +define(`ELF_COMMON_TYPES', + ``ADDR, Addr', + `CAP, Cap', + `DYN, Dyn', + `EHDR, Ehdr', + `HALF, Half', + `LWORD, Lword', + `MOVE, Move', + `OFF, Off', + `PHDR, Phdr', + `REL, Rel', + `RELA, Rela', + `SHDR, Shdr', + `SWORD, Sword', + `SYM, Sym', + `SYMINFO, Syminfo', + `WORD, Word'') + +define(`ELF32_TYPES', + `ELF_COMMON_TYPES, + `_, _'') + +define(`ELF64_TYPES', + `ELF_COMMON_TYPES, + `SXWORD, Sxword', + `XWORD, Xword', + `_, _'') + +/* + * Tests that need to be written manually: include those for + * types: BYTE, NOTE and perhaps VDEF and VNEED. + */ + +/* + * _DOTYPE(TYPE) + * + * Process one type. This invokes `__F__' with args: 1=TYPE, 2=C-Name and the + * the additional arguments specified to `DOELFTYPES' below. + */ +define(`_DOTYPE',` +indir(`__F__',$1,$2,__ARGS__) +') + +/* + * _DOELFTYPES: iterate over an ELF type list. + */ +define(`_DOELFTYPES', + `ifelse($#,1,`', + `_DOTYPE($1) +_DOELFTYPES(shift($@))')') + +/* + * DOELFTYPES(MACRO,ARGS...) + * + * Invoke `MACRO'(TYPE,C-NAME,ARGS...) for each type in the ELF type list + * for the current size in macro `__SZ__'. + */ +define(`DOELFTYPES', + `pushdef(`__F__',defn(`$1'))pushdef(`__ARGS__',`shift($@)')dnl +ifelse(__SZ__,32,`_DOELFTYPES(ELF32_TYPES)',`_DOELFTYPES(ELF64_TYPES)')dnl +popdef(`__ARGS__')popdef(`__F__')') + +/* + * ELFTYPEDEFINITION(TYPE,SZ,ENDIANNESS) + * + * Generate the `C' name of the char[] array holding the `raw' bits + * for an ELF type. + */ +define(`ELFTYPEDEFINITION',`td_$1_$2_$3') + +/* + * ELFMEMSTRUCT(TYPE,SZ) + * + * Generate the name for a `C' struct containing the memory + * representation of an ELF type. + */ +define(`ELFMEMSTRUCT',`$1_$2_mem') + +/* + * ELFTESTS(SZ) + */ +define(`ELFTESTS',`tests$1') + +divert(0) + +#define TPBUFSIZE 1024 + +#define BYTE_VAL 0xFF +#define BYTE_SEQ_LSB 0xFF, +#define BYTE_SEQ_MSB 0xFF, + +#define HALF_SEQ_LSB 0xDC,0xFE, +#define HALF_SEQ_LSB32 HALF_SEQ_LSB +#define HALF_SEQ_LSB64 HALF_SEQ_LSB +#define HALF_SEQ_MSB 0xFE,0xDC, +#define HALF_SEQ_MSB32 HALF_SEQ_MSB +#define HALF_SEQ_MSB64 HALF_SEQ_MSB +#define HALF_VAL 0xFEDC +#define HALF_VAL32 HALF_VAL +#define HALF_VAL64 HALF_VAL + +#define WORD_SEQ_LSB 0x98,0xBA,0xDC,0xFE, +#define WORD_SEQ_MSB 0xFE,0xDC,0xBA,0x98, +#define WORD_SEQ_LSB32 WORD_SEQ_LSB +#define WORD_SEQ_MSB32 WORD_SEQ_MSB +#define WORD_SEQ_LSB64 WORD_SEQ_LSB +#define WORD_SEQ_MSB64 WORD_SEQ_MSB +#define WORD_VAL 0xFEDCBA98UL +#define WORD_VAL32 WORD_VAL +#define WORD_VAL64 WORD_VAL + +#define QUAD_SEQ_LSB 0x10,0x32,0x54,0x76,\ + 0x98,0xBA,0xDC,0xFE, +#define QUAD_SEQ_MSB 0xFE,0xDC,0xBA,0x98,\ + 0x76,0x54,0x32,0x10, +#define QUAD_VAL 0xFEDCBA9876543210ULL +#define QUAD_VAL32 QUAD_VAL +#define QUAD_VAL64 QUAD_VAL + +#define IDENT_BYTES 46,33,46,64,46,35,46,36,46,37,46,94,46,38,46,42 +#define IDENT_VAL { IDENT_BYTES } +#define IDENT_SEQ_LSB IDENT_BYTES, +#define IDENT_SEQ_MSB IDENT_BYTES, + +#define LWORD_SEQ_LSB QUAD_SEQ_LSB +#define LWORD_SEQ_LSB32 QUAD_SEQ_LSB +#define LWORD_SEQ_LSB64 QUAD_SEQ_LSB +#define LWORD_SEQ_MSB QUAD_SEQ_MSB +#define LWORD_SEQ_MSB32 QUAD_SEQ_MSB +#define LWORD_SEQ_MSB64 QUAD_SEQ_MSB +#define LWORD_VAL32 QUAD_VAL32 +#define LWORD_VAL64 QUAD_VAL64 + +#define SWORD_SEQ_LSB WORD_SEQ_LSB +#define SWORD_SEQ_LSB32 WORD_SEQ_LSB +#define SWORD_SEQ_LSB64 WORD_SEQ_LSB +#define SWORD_SEQ_MSB WORD_SEQ_MSB +#define SWORD_SEQ_MSB32 WORD_SEQ_MSB +#define SWORD_SEQ_MSB64 WORD_SEQ_MSB +#define SWORD_VAL32 WORD_VAL32 +#define SWORD_VAL64 WORD_VAL64 + +#define SXWORD_SEQ_LSB QUAD_SEQ_LSB +#define SXWORD_SEQ_LSB64 QUAD_SEQ_LSB +#define SXWORD_SEQ_MSB QUAD_SEQ_MSB +#define SXWORD_SEQ_MSB64 QUAD_SEQ_MSB +#define SXWORD_VAL64 QUAD_VAL64 + +#define XWORD_SEQ_LSB QUAD_SEQ_LSB +#define XWORD_SEQ_LSB64 QUAD_SEQ_LSB +#define XWORD_SEQ_MSB QUAD_SEQ_MSB +#define XWORD_SEQ_MSB64 QUAD_SEQ_MSB +#define XWORD_VAL64 QUAD_VAL64 + +/* + * ELF class dependent types. + */ +#define ADDR_SEQ_LSB32 WORD_SEQ_LSB +#define ADDR_SEQ_MSB32 WORD_SEQ_MSB +#define ADDR_VAL32 WORD_VAL32 +#define OFF_SEQ_LSB32 WORD_SEQ_LSB +#define OFF_SEQ_MSB32 WORD_SEQ_MSB +#define OFF_VAL32 WORD_VAL32 + +#define ADDR_SEQ_LSB64 QUAD_SEQ_LSB +#define ADDR_SEQ_MSB64 QUAD_SEQ_MSB +#define ADDR_VAL64 QUAD_VAL64 +#define OFF_SEQ_LSB64 QUAD_SEQ_LSB +#define OFF_SEQ_MSB64 QUAD_SEQ_MSB +#define OFF_VAL64 QUAD_VAL64 + +#define NCOPIES 3 +#define NOFFSET 8 /* Every alignment in a quad word. */ + +divert(-1) +/* + * Definitions of 32 bit ELF file structures. + */ + +define(`ELF_TYPE_E32_CAP', + `MEMBER(c_tag, WORD) + MEMBER(c_un.c_val, WORD)') + +define(`ELF_TYPE_E32_DYN', + `MEMBER(d_tag, WORD) + MEMBER(d_un.d_val, WORD)') + +define(`ELF_TYPE_E32_EHDR', + `MEMBER(e_ident, IDENT) + MEMBER(e_type, HALF) + MEMBER(e_machine, HALF) + MEMBER(e_version, WORD) + MEMBER(e_entry, WORD) + MEMBER(e_phoff, WORD) + MEMBER(e_shoff, WORD) + MEMBER(e_flags, WORD) + MEMBER(e_ehsize, HALF) + MEMBER(e_phentsize, HALF) + MEMBER(e_phnum, HALF) + MEMBER(e_shentsize, HALF) + MEMBER(e_shnum, HALF) + MEMBER(e_shstrndx, HALF)') + +define(`ELF_TYPE_E32_MOVE', + `MEMBER(m_value, QUAD) + MEMBER(m_info, WORD) + MEMBER(m_poffset, WORD) + MEMBER(m_repeat, HALF) + MEMBER(m_stride, HALF)') + +define(`ELF_TYPE_E32_PHDR', + `MEMBER(p_type, WORD) + MEMBER(p_offset, WORD) + MEMBER(p_vaddr, WORD) + MEMBER(p_paddr, WORD) + MEMBER(p_filesz, WORD) + MEMBER(p_memsz, WORD) + MEMBER(p_flags, WORD) + MEMBER(p_align, WORD)') + +define(`ELF_TYPE_E32_REL', + `MEMBER(r_offset, WORD) + MEMBER(r_info, WORD)') + +define(`ELF_TYPE_E32_RELA', + `MEMBER(r_offset, WORD) + MEMBER(r_info, WORD) + MEMBER(r_addend, WORD)') + +define(`ELF_TYPE_E32_SHDR', + `MEMBER(sh_name, WORD) + MEMBER(sh_type, WORD) + MEMBER(sh_flags, WORD) + MEMBER(sh_addr, WORD) + MEMBER(sh_offset, WORD) + MEMBER(sh_size, WORD) + MEMBER(sh_link, WORD) + MEMBER(sh_info, WORD) + MEMBER(sh_addralign, WORD) + MEMBER(sh_entsize, WORD)') + +define(`ELF_TYPE_E32_SYM', + `MEMBER(st_name, WORD) + MEMBER(st_value, WORD) + MEMBER(st_size, WORD) + MEMBER(st_info, BYTE) + MEMBER(st_other, BYTE) + MEMBER(st_shndx, HALF)') + +define(`ELF_TYPE_E32_SYMINFO', + `MEMBER(si_boundto, HALF) + MEMBER(si_flags, HALF)') + +define(`ELF_TYPE_E32_VDEF', + `MEMBER(vd_version, HALF) + MEMBER(vd_flags, HALF) + MEMBER(vd_ndx, HALF) + MEMBER(vd_cnt, HALF) + MEMBER(vd_hash, WORD) + MEMBER(vd_aux, WORD) + MEMBER(vd_next, WORD)') + +define(`ELF_TYPE_E32_VNEED', + `MEMBER(vn_version, HALF) + MEMBER(vn_cnt, HALF) + MEMBER(vn_file, WORD) + MEMBER(vn_aux, WORD) + MEMBER(vn_next, WORD)') + + +/* + * Definitions of 64 bit ELF file structures. + */ + +define(`ELF_TYPE_E64_CAP', + `MEMBER(c_tag, QUAD) + MEMBER(c_un.c_val, QUAD)') + +define(`ELF_TYPE_E64_DYN', + `MEMBER(d_tag, QUAD) + MEMBER(d_un.d_val, QUAD)') + +define(`ELF_TYPE_E64_EHDR', + `MEMBER(e_ident, IDENT) + MEMBER(e_type, HALF) + MEMBER(e_machine, HALF) + MEMBER(e_version, WORD) + MEMBER(e_entry, QUAD) + MEMBER(e_phoff, QUAD) + MEMBER(e_shoff, QUAD) + MEMBER(e_flags, WORD) + MEMBER(e_ehsize, HALF) + MEMBER(e_phentsize, HALF) + MEMBER(e_phnum, HALF) + MEMBER(e_shentsize, HALF) + MEMBER(e_shnum, HALF) + MEMBER(e_shstrndx, HALF)') + +define(`ELF_TYPE_E64_MOVE', + `MEMBER(m_value, QUAD) + MEMBER(m_info, QUAD) + MEMBER(m_poffset, QUAD) + MEMBER(m_repeat, HALF) + MEMBER(m_stride, HALF)') + +define(`ELF_TYPE_E64_PHDR', + `MEMBER(p_type, WORD) + MEMBER(p_flags, WORD) + MEMBER(p_offset, QUAD) + MEMBER(p_vaddr, QUAD) + MEMBER(p_paddr, QUAD) + MEMBER(p_filesz, QUAD) + MEMBER(p_memsz, QUAD) + MEMBER(p_align, QUAD)') + +define(`ELF_TYPE_E64_REL', + `MEMBER(r_offset, QUAD) + MEMBER(r_info, QUAD)') + +define(`ELF_TYPE_E64_RELA', + `MEMBER(r_offset, QUAD) + MEMBER(r_info, QUAD) + MEMBER(r_addend, QUAD)') + +define(`ELF_TYPE_E64_SHDR', + `MEMBER(sh_name, WORD) + MEMBER(sh_type, WORD) + MEMBER(sh_flags, QUAD) + MEMBER(sh_addr, QUAD) + MEMBER(sh_offset, QUAD) + MEMBER(sh_size, QUAD) + MEMBER(sh_link, WORD) + MEMBER(sh_info, WORD) + MEMBER(sh_addralign, QUAD) + MEMBER(sh_entsize, QUAD)') + +define(`ELF_TYPE_E64_SYM', + `MEMBER(st_name, WORD) + MEMBER(st_info, BYTE) + MEMBER(st_other, BYTE) + MEMBER(st_shndx, HALF) + MEMBER(st_value, QUAD) + MEMBER(st_size, QUAD)') + +define(`ELF_TYPE_E64_SYMINFO', + `MEMBER(si_boundto, HALF) + MEMBER(si_flags, HALF)') + +define(`ELF_TYPE_E64_VDEF', + `MEMBER(vd_version, HALF) + MEMBER(vd_flags, HALF) + MEMBER(vd_ndx, HALF) + MEMBER(vd_cnt, HALF) + MEMBER(vd_hash, WORD) + MEMBER(vd_aux, WORD) + MEMBER(vd_next, WORD)') + +define(`ELF_TYPE_E64_VNEED', + `MEMBER(vn_version, HALF) + MEMBER(vn_cnt, HALF) + MEMBER(vn_file, WORD) + MEMBER(vn_aux, WORD) + MEMBER(vn_next, WORD)') + +/* + * MKRAWBITS(TYPE,CNAME,ENDIANNESS,SIZE) + * + * Create a char[] array that holds the type's file representation. + */ +define(`MKRAWBITS', + `static unsigned char ELFTYPEDEFINITION($1,`'__SZ__`',$3)[] = { +ifdef(`ELF_TYPE_E'__SZ__`_$1', + `pushdef(`MEMBER',`$'2`_SEQ_$3')ELF_TYPE_E'__SZ__`_$1`'popdef(`MEMBER')', + `$1_SEQ_$3`'__SZ__') };') + +divert(0) + +ifdef(`ISELF32', + DO(32,`DOELFTYPES(`MKRAWBITS',LSB)') + DO(32,`DOELFTYPES(`MKRAWBITS',MSB)')) + +ifdef(`ISELF64', + `DO(64,`DOELFTYPES(`MKRAWBITS',LSB)') + DO(64,`DOELFTYPES(`MKRAWBITS',MSB)')') + +divert(-1) + +/* + * MKMEMSTRUCT(TYPE,CNAME) + * + * Define a C-structure with test data for TYPE. + */ +define(`MKMEMSTRUCT', + `static Elf`'__SZ__`'_$2 ELFMEMSTRUCT($1,__SZ__) = +ifdef(`ELF_TYPE_E'__SZ__`_$1', + `pushdef(`MEMBER',.`$'1 = `$'2_VAL `,'){ +ELF_TYPE_E'__SZ__`_$1 + }popdef(`MEMBER')', + `$1_VAL`'__SZ__');') + +/* + * MKMEMCHECK(TYPE,CNAME) + * + * Generate code to check a memory structure against reference data. + */ +define(`MKMEMCHECK', + `ifdef(`ELF_TYPE_E'__SZ__`_$1',dnl Structure type + `pushdef(`_T_',defn(`ELF_TYPE_E'__SZ__`_$1'))dnl + pushdef(`MEMBER',` + 'if (`ifelse'($`'2,IDENT,memcmp(dt->$`'1,ref->$`'1,sizeof(ref->$`'1)), + dt->$`'1 != ref->$`'1)) { + TP_FAIL("$1: unequal `$'1."); + goto done; + }) + _T_ + dt += 1; + popdef(`MEMBER')popdef(`_T_')',`dnl Primitive type. + if (memcmp(t, td->tsd_mem, msz) != 0) { + TP_FAIL("$1 compare failed."); + goto done; + } + t += msz;')') + +divert(0) + +ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKMEMSTRUCT')')') +ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKMEMSTRUCT')')') + +struct testdata { + char *tsd_name; + Elf_Type tsd_type; + + size_t tsd_fsz; + const unsigned char *tsd_lsb; + const unsigned char *tsd_msb; + void *tsd_mem; + size_t tsd_msz; +}; + +define(`DEFINE_TEST_DATA', + `[ELF_T_$1] = { + .tsd_name = "$1", + .tsd_type = ELF_T_$1, + + .tsd_fsz = sizeof(ELFTYPEDEFINITION($1,__SZ__,LSB)), + .tsd_lsb = ELFTYPEDEFINITION($1,__SZ__,LSB), + .tsd_msb = ELFTYPEDEFINITION($1,__SZ__,MSB), + + .tsd_mem = (void *) &ELFMEMSTRUCT($1,__SZ__), + .tsd_msz = sizeof(ELFMEMSTRUCT($1,__SZ__)) +}') + +dnl Tests for variable length Elf types. +define(`DEFINE_TEST_DATA_VARIABLE_LENGTH',` +[ELF_T_BYTE] = { + /* For byte compares, the LSB/MSB and memory data are identical. */ + .tsd_name = "BYTE", + .tsd_type = ELF_T_BYTE, + .tsd_fsz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)), + .tsd_lsb = (void *) &ELFMEMSTRUCT(WORD,__SZ__), + .tsd_msb = (void *) &ELFMEMSTRUCT(WORD,__SZ__), + .tsd_mem = (void *) &ELFMEMSTRUCT(WORD,__SZ__), + .tsd_msz = sizeof(ELFMEMSTRUCT(WORD,__SZ__)) +}') +define(`MKTD',`DEFINE_TEST_DATA($1) `,'') + +ifdef(`ISELF32',`static struct testdata ELFTESTS(32)[] = { +DO(32,`DEFINE_TEST_DATA_VARIABLE_LENGTH'), +DO(32,`DOELFTYPES(`MKTD')') +{ } +};') + +ifdef(`ISELF64',`static struct testdata ELFTESTS(64)[] = { +DO(64,`DEFINE_TEST_DATA_VARIABLE_LENGTH'), +DO(64,`DOELFTYPES(`MKTD')') +{ } +};') + +divert(-1) + +/* + * CallXlator(ARGS) + * + * Munge the call sequence depending on whether a gelf_* function is + * being tested or not. + */ +define(`CallXlator',`ifdef(`USEGELF',`TPFNNAME (e, $*)',`TPFNNAME ($*)')') + +/* + * CheckXlateResult(SZ) + */ +define(`CheckXlateResult',` + if (dst->d_type != td->tsd_type || dst->d_size != $1 * ncopies) { + TP_FAIL("type: ret=%d/expected=%d size: ret=%d/expected=%d", + dst->d_type, td->tsd_type, dst->d_size, $1*ncopies); + goto done; + }') +define(`CheckXlateResultM',`CheckXlateResult(msz)') +define(`CheckXlateResultF',`CheckXlateResult(fsz)') + +/* + * For all xlate tests we need to do the following: + * + * 1. Declare variables. + * 2. Allocate memory. + * 3. Locate reference data. + * 4. For each offset: + * 4a. if doing a ToF: initialize the source buffer (N copies) + * 4b. if doing a ToM: initialize the source (N copies) at the offset + * 4c. Invoke the xlator. + * 4d. Check by memcmp() against the reference. + * + * XlatePrelude(TYPE,ENDIANNESS,C-NAME) + */ +define(`XlatePrelude',` + Elf_Data dst, src, *r; + struct testdata *td; + size_t expected_size, fsz, msz; + int i, offset, result; + char *srcbuf, *dstbuf, *t; + TO_M_OR_F(`ifdef(`ELF_TYPE_E'__SZ__`_$1',` + Elf`'__SZ__`'_$3 *dt, *ref;')',`') + + TP_ANNOUNCE("TPFNNAME""($1,$2) conversion."); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + td = &tests`'__SZ__[ELF_T_$1]; + + fsz = elf`'__SZ__`'_fsize(td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + result = TET_PASS; + + assert(msz > 0); + assert(fsz == td->tsd_fsz); /* Sanity check. */ + + srcbuf = dstbuf = NULL; + + TO_M_OR_F(` + /* Copy to memory. */ + if ((srcbuf = malloc(NCOPIES*fsz + NOFFSET)) == NULL) { + TP_UNRESOLVED("TPFNNAME"" malloc() failed."); + goto done; + } + + if ((dstbuf = calloc(1,NCOPIES*msz)) == NULL) { + TP_UNRESOLVED("TPFNNAME"" malloc() failed."); + goto done; + }',` + /* Copy to file. */ + if ((srcbuf = malloc(NCOPIES*msz)) == NULL) { + TP_UNRESOLVED("TPFNNAME"" malloc() failed."); + goto done; + } + + if ((dstbuf = calloc(1,NCOPIES*fsz + NOFFSET)) == NULL) { + TP_UNRESOLVED("TPFNNAME"" malloc() failed."); + goto done; + }') +') + +/* + * XlateCopySrcData(TYPE,ENDIANNESS) + * + * Copy bytes of src data, and set the src and dst Elf_Data structures. + */ +define(`XlateCopySrcData',` +TO_M_OR_F(` + t = srcbuf + offset; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_`'TOLOWER($2), fsz); + t += fsz; + } + + src.d_buf = srcbuf + offset; + src.d_size = fsz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + dst.d_buf = dstbuf; + dst.d_size = msz * NCOPIES; + dst.d_version = EV_CURRENT; + ',` + t = srcbuf; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_mem, msz); + t += msz; + } + + src.d_buf = srcbuf; + src.d_size = msz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + dst.d_buf = dstbuf + offset; + dst.d_size = fsz * NCOPIES; + dst.d_version = EV_CURRENT;')') + +/* + * XlateConvertAndCheck(TYPE,ENDIANNESS,C-NAME) + * + * Invoke TPFNNAME () and check the returned buffer type and size. + */ +define(`XlateConvertAndCheck',` + if ((r = CallXlator(&dst, &src, ELFDATA2$2)) != &dst) { + TP_FAIL("TPFNNAME""($1:$2) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + expected_size = NCOPIES * TO_M_OR_F(`msz',`fsz'); + + if (dst.d_type != td->tsd_type || + dst.d_size != expected_size) { + TP_FAIL("TPFNNAME""($1:$2) type(%d != %d expected), " + "size(%d != %d expected).", dst.d_type, td->tsd_type, + dst.d_size, expected_size); + goto done; + } + TO_M_OR_F(` + /* Check returned memory data. */ +ifdef(`ELF_TYPE_E'__SZ__`_$1',` + dt = (Elf`'__SZ__`'_$3 *) (uintptr_t) dst.d_buf; + ref = (Elf`'__SZ__`'_$3 *) td->tsd_mem;',` + t = dst.d_buf;') + + for (i = 0; i < NCOPIES; i++) { + MKMEMCHECK($1) + }',` + /* Check returned file data. */ + t = dst.d_buf; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_`'TOLOWER($2), fsz) != 0) { + TP_FAIL("$1 compare failed."); + goto done; + } + t += fsz; + }') +') + +/* + * MKCONVERSIONTP(TYPE,C-Name,ENDIANNESS) + * + * Generate a test purpose that tests conversions for Elf type TYPE. + */ +define(`MKCONVERSIONTP',` +void +tcXlate_tp$1_$3`'__SZ__ (void) +{ + XlatePrelude($1,$3,$2) + + result = TET_PASS; + + for (offset = 0; offset < NOFFSET; offset++) { + XlateCopySrcData($1,$3) + XlateConvertAndCheck($1,$3,$2) + } + + done: + if (srcbuf) + free(srcbuf); + if (dstbuf) + free(dstbuf); + tet_result(result); +}') + +/* + * Xlate_TestConversions_Byte() + * + * Test byte conversions. + */ +define(`Xlate_TestConversions_Byte',` +void +tcXlate_tpByte`'__SZ__ (void) +{ + Elf_Data dst, src, *r; + int i, offset, result; + size_t expected_size, fsz, msz; + struct testdata *td; + char srcbuf[NCOPIES*sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)) + NOFFSET]; + char dstbuf[sizeof(srcbuf)]; + char *t; + + TP_ANNOUNCE("TPFNNAME""(BYTE) conversion."); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + td = &tests`'__SZ__[ELF_T_BYTE]; + + fsz = msz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)); + expected_size = NCOPIES * msz; + result = TET_PASS; + + for (offset = 0; offset < NOFFSET; offset++) { + + XlateCopySrcData(BYTE,LSB); + XlateConvertAndCheck(BYTE,LSB); + XlateConvertAndCheck(BYTE,MSB,Word); + } + + done: + tet_result(result); +}') + +define(`Xlate_TestConversions_Note') + +/* + * Xlate_TestConversions + * + * Make test cases th non-byte conversions from file representations + * to memory. + */ +define(`Xlate_TestConversions',` +ifdef(`ISELF32',dnl +`DO(32,`Xlate_TestConversions_Byte +Xlate_TestConversions_Note') +DO(32,`DOELFTYPES(`MKCONVERSIONTP',LSB)') +DO(32,`DOELFTYPES(`MKCONVERSIONTP',MSB)')') +ifdef(`ISELF64',dnl +`DO(64,`Xlate_TestConversions_Byte +Xlate_TestConversions_Note') +DO(64,`DOELFTYPES(`MKCONVERSIONTP',LSB)') +DO(64,`DOELFTYPES(`MKCONVERSIONTP',MSB)')')') + +define(`Xlate_TestSharedConversions_Byte',` +void +tcXlate_tpByteShared`'__SZ__ (void) +{ + Elf_Data dst, src, *r; + int i, offset, result; + size_t expected_size, fsz, msz; + struct testdata *td; + char srcbuf[NCOPIES*sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB))]; + char *dstbuf; + char *t; + + TP_ANNOUNCE("Test TPFNNAME""(BYTE) shared-buffer conversion."); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + td = &tests`'__SZ__[ELF_T_BYTE]; + + fsz = msz = sizeof(ELFTYPEDEFINITION(WORD,__SZ__,LSB)); + expected_size = NCOPIES * msz; + result = TET_PASS; + dstbuf = srcbuf; + offset = 0; + + XlateCopySrcData(BYTE,LSB); + XlateConvertAndCheck(BYTE,LSB,Word); + XlateConvertAndCheck(BYTE,MSB,Word); + + done: + tet_result(result); +}') + +define(`Xlate_TestSharedConversions_Note') + +define(`MKSHAREDCONVERSIONTP',` +void +tcXlate_tpShared$1_$3`'__SZ__ (void) +{ + Elf_Data dst, src, *r; + struct testdata *td; + size_t expected_size, fsz, msz; + int i, result; + char *srcbuf, *t; + TO_M_OR_F(`ifdef(`ELF_TYPE_E'__SZ__`_$1',` + Elf`'__SZ__`'_$2 *dt, *ref;')',`') + + TP_ANNOUNCE("TPFNNAME""($1,$3) conversion."); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + td = &tests`'__SZ__[ELF_T_$1]; + + fsz = elf`'__SZ__`'_fsize(td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + result = TET_PASS; + + assert(msz > 0); + assert(fsz == td->tsd_fsz); /* Sanity check. */ + + srcbuf = t = NULL; + if ((srcbuf = malloc(NCOPIES*msz)) == NULL) { + TP_UNRESOLVED("TPFNNAME"" malloc() failed."); + goto done; + } + + src.d_buf = dst.d_buf = srcbuf; + src.d_version = dst.d_version = EV_CURRENT; + TO_M_OR_F(`src.d_size = fsz * NCOPIES; + dst.d_size = msz * NCOPIES;',`dnl + src.d_size = msz * NCOPIES; + dst.d_size = fsz * NCOPIES;') + src.d_type = dst.d_type = ELF_T_$1; + t = srcbuf; + for (i = 0; i < NCOPIES; i++) { + TO_M_OR_F(` + (void) memcpy(t, td->tsd_`'TOLOWER($3), fsz); + t += fsz;',` + (void) memcpy(t, td->tsd_mem, msz); + t += msz;') + } + + result = TET_PASS; + + XlateConvertAndCheck($1,$3,$2) + + done: + if (srcbuf) + free(srcbuf); + tet_result(result); +}') + +define(`Xlate_TestConversionsSharedBuffer',` +ifdef(`ISELF32',dnl +`DO(32,`Xlate_TestSharedConversions_Byte +Xlate_TestSharedConversions_Note') +DO(32,`DOELFTYPES(`MKSHAREDCONVERSIONTP',LSB)') +DO(32,`DOELFTYPES(`MKSHAREDCONVERSIONTP',MSB)')') +ifdef(`ISELF64',dnl +`DO(64,`Xlate_TestSharedConversions_Byte +Xlate_TestSharedConversions_Note') +DO(64,`DOELFTYPES(`MKSHAREDCONVERSIONTP',LSB)') +DO(64,`DOELFTYPES(`MKSHAREDCONVERSIONTP',MSB)')')') + +define(`Xlate_TestBadArguments',` +void +tcArgs_tpNullArgs(void) +{ + Elf_Data ed, *r; + int error, result; + + TP_ANNOUNCE("TPFNNAME () with NULL arguments fails with " + "ELF_E_ARGUMENT"); + + memset(&ed, 0, sizeof(ed)); + + result = TET_PASS; + + if ((r = CallXlator(NULL, &ed, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("TPFNNAME(NULL, *, LSB) failed: r=%p error=\"%s\".", + (void *) r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(NULL, &ed, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("TPFNNAME(NULL, *, MSB) failed: r=%p error=\"%s\".", + (void *) r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, NULL, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("TPFNNAME(*, NULL, LSB) failed: r=%p error=\"%s\".", + (void *) r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, NULL, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("TPFNNAME(*, NULL, MSB) failed: r=%p error=\"%s\".", + (void *) r, elf_errmsg(error)); + + done: + tet_result(result); +} + +void +tcArgs_tpBadType(void) +{ + + Elf_Data ed, es, *r; + int error, result; + char buf[1024]; + + TP_ANNOUNCE("TPFNNAME () with an out of range type fails with " + "ELF_E_DATA."); + + result = TET_PASS; + + (void) memset(&es, 0, sizeof(es)); + (void) memset(&ed, 0, sizeof(ed)); + + es.d_version = ed.d_version = EV_CURRENT; + es.d_buf = ed.d_buf = buf; + es.d_size = ed.d_size = sizeof(buf); + + es.d_type = (Elf_Type) -1; + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME (*, *, LSB) (%d): r=%p error=\"%s\".", + es.d_type, (void *) r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME (*, *, MSB) (%d): r=%p error=\"%s\".", + es.d_type, (void *) r, elf_errmsg(error)); + goto done; + } + + es.d_type = ELF_T_NUM; + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME (*, *, LSB) (%d): r=%p error=%\"%s\".", + es.d_type, (void *) r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("TPFNNAME (*, *, MSB) (%d): r=%p error=\"%s\".", + es.d_type, (void *) r, elf_errmsg(error)); + + + done: + tet_result(result); +} + +void +tcArgs_tpBadEncoding(void) +{ + Elf_Data ed, es, *r; + int error, result; + + TP_ANNOUNCE("TPFNNAME (*,*,BADENCODING) fails with " + "ELF_E_ARGUMENT."); + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + result = TET_PASS; + + if ((r = CallXlator(&ed, &es, ELFDATANONE-1)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("TPFNNAME (*, *, %d): r=%p error=\"%s\".", + ELFDATANONE-1, r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB+1)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("TPFNNAME (*, *, %d): r=%p error=\"%s\".", + ELFDATA2MSB+1, r, elf_errmsg(error)); + + done: + tet_result(result); +} + +void +tcArgs_tpDstVersion(void) +{ + Elf_Data ed, es, *r; + int error, result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("TPFNNAME (*,*,*) with an illegal dst version " + "fails with ELF_E_UNIMPL."); + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + es.d_buf = ed.d_buf = buf; + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_NONE; + + result = TET_PASS; + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) { + TP_FAIL("TPFNNAME (*,*,LSB) ver=%d r=%p error=\"%s\".", + ed.d_version, r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) + TP_FAIL("TPFNNAME (*,*,MSB) ver=%d r=%p error=\"%s\".", + ed.d_version, r, elf_errmsg(error)); + + done: + tet_result(result); +} + +void +tcArgs_tpSrcVersion(void) +{ + Elf_Data ed, es, *r; + int error, result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("TPFNNAME (*,*,*) with an illegal src version fails " + "with ELF_E_UNIMPL."); + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + es.d_buf = ed.d_buf = buf; + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT+1; + ed.d_version = EV_CURRENT; + + result = TET_PASS; + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) { + TP_FAIL("TPFNNAME (*,*,LSB) ver=%d r=%p error=\"%s\".", + es.d_version, r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) + TP_FAIL("TPFNNAME (*,*,MSB) ver=%d r=%p error=\"%s\".", + es.d_version, r, elf_errmsg(error)); + + done: + tet_result(result); +} + +/* + * Check for an unimplemented type. + */ +void +tcArgs_tpUnimplemented(void) +{ + Elf_Data ed, es, *r; + int error, i, result; + char sbuf[TPBUFSIZE]; /* large enough for any ELF type */ + char dbuf[TPBUFSIZE]; + + TP_ANNOUNCE("TPFNNAME""() on unimplemented types fails with " + "ELF_E_UNIMPL."); + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + ed.d_buf = dbuf; ed.d_size = sizeof(dbuf); + es.d_buf = sbuf; es.d_size = sizeof(sbuf); + es.d_version = ed.d_version = EV_CURRENT; + + result = TET_PASS; + + for (i = 0; i < ELF_T_NUM; i++) { + /* Skip over supported types. */ + switch (i) { + case ELF_T_MOVEP: + ifelse(ISELF64,`Y',`',` + case ELF_T_SXWORD: + case ELF_T_XWORD: +') + break; + default: + continue; + } + + es.d_type = i; + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) { + TP_FAIL("TPFNNAME (*,*,LSB): type=%d r=%p " + "error=\"%s\".", i, r, elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_UNIMPL) { + TP_FAIL("TPFNNAME (*,*,LSB): type=%d r=%p " + "error=\"%s\".", i, r, elf_errmsg(error)); + goto done; + } + } + + done: + tet_result(result); +} +') + +/* + * MKMISALIGNEDTP(TYPE,C-NAME) + * + * Generate a test case for checking misaligned buffers. + */ + +define(`MKMISALIGNEDTP',` +void +tcBuffer_tpMisaligned_$1_`'__SZ__`'(void) +{ + Elf_Data ed, es, *r; + int count, error, result; + size_t fsz, msz; + char sb[TPBUFSIZE], db[TPBUFSIZE]; + struct testdata *td; + + TP_ANNOUNCE("TPFNNAME""($1) misaligned buffers with " + "ELF_E_DATA."); + + result = TET_PASS; + + td = &tests`'__SZ__[ELF_T_$1]; + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + es.d_type = es.d_type = td->tsd_type; + es.d_version = ed.d_version = EV_CURRENT; + + count = sizeof(sb) / msz; /* Note: msz >= fsz always. */ + + TO_M_OR_F(` + /* Misalign the destination for to-memory xfers. */ + es.d_size = count * fsz; + ed.d_size = count * msz; + + es.d_buf = sb; + ed.d_buf = db + 1; /* Guaranteed to be misaliged. */ + ',` + /* Misalign the source for to-file xfers. */ + + es.d_size = count * msz; + ed.d_size = count * fsz; + + es.d_buf = sb + 1; /* Guaranteed to be misaliged. */ + ed.d_buf = db;') + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("TPFNNAME""(MSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + + done: + tet_result(result); +}') + +define(`MKNONINTEGRALSRC',` +void +tcBuffer_tpSrcExtra_$1_`'__SZ__`'(void) +{ + Elf_Data ed, es, *r; + int count, error, result; + size_t fsz, msz; + char sb[TPBUFSIZE], db[TPBUFSIZE]; + struct testdata *td; + + TP_ANNOUNCE("TPFNNAME""($1) mis-sized source buffer is rejected with " + "ELF_E_DATA."); + + result = TET_PASS; + + td = &tests`'__SZ__[ELF_T_$1]; + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + ed.d_type = es.d_type = td->tsd_type; + ed.d_version = es.d_version = EV_CURRENT; + es.d_buf = sb; ed.d_buf = db; + + count = (sizeof(db) / msz) - 1; /* Note: msz >= fsz always. */ + + /* Add an extra byte to the source buffer size. */ + TO_M_OR_F(` + es.d_size = (count * fsz) + 1; + ed.d_size = count * msz;',` + es.d_size = (count * msz) + 1; + ed.d_size = count * fsz;') + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + + done: + tet_result(result); + +}') + +define(`MKDSTTOOSMALL',` +void +tcBuffer_tpDstTooSmall_$1_`'__SZ__`'(void) +{ + Elf_Data ed, es, *r; + int count, error, result; + struct testdata *td; + size_t fsz, msz; + char sb[TPBUFSIZE], db[TPBUFSIZE]; + + TP_ANNOUNCE("TPFNNAME""($1) small destination buffers are rejected " + "with ELF_E_DATA."); + + result = TET_PASS; + + td = &tests`'__SZ__[ELF_T_$1]; + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + count = sizeof(sb) / msz; /* Note: msz >= fsz always. */ + + ed.d_type = es.d_type = td->tsd_type; + ed.d_version = es.d_version = EV_CURRENT; + es.d_buf = sb; ed.d_buf = db; + ed.d_size = 1; + + TO_M_OR_F(`es.d_size = sizeof(sb) / fsz;', + `es.d_size = sizeof(sb) / msz;') + + if ((r = CallXlator(&ed, &es, ELFDATA2LSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + goto done; + } + + if ((r = CallXlator(&ed, &es, ELFDATA2MSB)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("TPFNNAME""(LSB) r=%p error=\"%s\".", r, + elf_errmsg(error)); + + done: + tet_result(result); +}') + +define(`Xlate_TestBadBuffers',` +void +tcBuffer_tpNullDataPtr(void) +{ + Elf_Data ed, es, *r; + int error, result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("TPFNNAME" "(...) with null d_buf pointers fails with " + "ELF_E_DATA."); + + (void) memset(&ed, 0, sizeof(ed)); + (void) memset(&es, 0, sizeof(es)); + + result = TET_PASS; + + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_CURRENT; + + es.d_buf = NULL; + ed.d_buf = buf; + if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL || + (error = elf_errno()) != ELF_E_DATA) { + TP_FAIL("TPFNNAME""(...) src.d_buf=NULL r=%d error=\"%s\".", + r, elf_errmsg(error)); + goto done; + } + + es.d_buf = buf; + ed.d_buf = NULL; + + if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("TPFNNAME""(...) dst.d_buf=NULL r=%d error=\"%s\".", + r, elf_errmsg(error)); + + done: + tet_result(result); +} + +/* + * Misaligned data. + */ + +ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKMISALIGNEDTP')')') +ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKMISALIGNEDTP')')') + +/* + * Overlapping buffers. + */ +void +tcBuffer_tpOverlap(void) +{ + Elf_Data ed, es, *r; + int error, result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("TPFNNAME""(...) overlapping buffers are rejected with " + "ELF_E_DATA."); + + es.d_buf = buf; ed.d_buf = buf+1; + es.d_version = ed.d_version = EV_CURRENT; + es.d_size = ed.d_size = sizeof(buf); + es.d_type = ELF_T_BYTE; + + result = TET_PASS; + + if ((r = CallXlator(&ed, &es, ELFDATANONE)) != NULL || + (error = elf_errno()) != ELF_E_DATA) + TP_FAIL("r=%p error=\"%s\".", r, elf_errmsg(error)); + + tet_result(result); +} + +/* + * Non-integral number of src elements. + */ +ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKNONINTEGRALSRC')')') +ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKNONINTEGRALSRC')')') + +/* + * Destination too small. + */ +ifdef(`ISELF32',`DO(32,`DOELFTYPES(`MKDSTTOOSMALL')')') +ifdef(`ISELF64',`DO(64,`DOELFTYPES(`MKDSTTOOSMALL')')') + +') +divert(0) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-1.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-1.yaml new file mode 100644 index 0000000000..113dbcb68d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-1.yaml @@ -0,0 +1,23 @@ +%YAML 1.1 +--- +# $Id: xscn-1.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +# +# This file is used for tests requiring malformed extended section +# numbering. 'e_shnum' is set to zero, but the section at index +# SHN_UNDEF is not of type SHT_NULL. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + e_shnum: 0 + +sections: + - !Section # index 0 + sh_type: SHT_PROGBITS + - !Section + sh_type: SHT_STRTAB + sh_name: .shstrtab + sh_data: + - .shstrtab diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-2.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-2.yaml new file mode 100644 index 0000000000..54b6752e0c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-2.yaml @@ -0,0 +1,22 @@ +%YAML 1.1 +# $Id: xscn-2.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +# +# This file is used for tests requiring a well-formed ELF file that +# uses extended section numbering. +# +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section + sh_type: SHT_NULL + - !Section + sh_type: SHT_STRTAB + sh_index: 65537 + sh_name: .shstrtab + sh_data: + - .shstrtab diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-3.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-3.yaml new file mode 100644 index 0000000000..b5edbff46c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/xscn-3.yaml @@ -0,0 +1,26 @@ +%YAML 1.1 +# $Id: xscn-3.yaml 2053 2011-10-26 11:50:18Z jkoshy $ +--- +# +# This file is used for tests requiring malformed extended section +# numbering for elf_getshstrndx(). 'e_shnum' is set to zero, but +# the section at index SHN_UNDEF is not of type SHT_NULL. `e_shstrndx' +# corresponds to a section > SHN_LORESERVE. + +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + e_shnum: 0 + e_shstrndx: 65537 + +sections: + - !Section # index 0 + sh_type: SHT_PROGBITS + - !Section + sh_type: SHT_STRTAB + sh_index: 65537 + sh_name: .shstrtab + sh_data: + - .shstrtab diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/common/zerosection.yaml b/contrib/elftoolchain/tests/tet/libelf/tset/common/zerosection.yaml new file mode 100644 index 0000000000..8bcc2d73c2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/common/zerosection.yaml @@ -0,0 +1,27 @@ +%YAML 1.1 +--- +# $Id: zerosection.yaml 2077 2011-10-27 03:59:40Z jkoshy $ +# +# An ELF file containing a zero-sized section. + +ehdr: !Ehdr + e_ident: !Ident + ei_class: ELFCLASSNONE + ei_data: ELFDATANONE + e_type: ET_REL + +sections: + - !Section # index 0 + sh_type: SHT_NULL + + - !Section + sh_name: .shstrtab + sh_type: SHT_STRTAB + sh_data: + - .shstrtab + - .zerosection + + - !Section + sh_name: .zerosection + sh_offset: 2048 + sh_type: SHT_NOBITS diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/Makefile new file mode 100644 index 0000000000..519fd4e67a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_YAML= ehdr ehdr-malformed-1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/ehdr.m4 new file mode 100644 index 0000000000..bd69b1bf7c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getehdr/ehdr.m4 @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +define(`TS_EHDRFUNC',`_getehdr') +define(`TS_EHDRSZ',`32') +include(`ehdr_template.m4') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/Makefile new file mode 100644 index 0000000000..92104ea063 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= phdr.m4 +TS_DATA= ehdr.msb32 ehdr.lsb32 \ + phdr.msb32 phdr.lsb32 phdr.msb64 phdr.lsb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/phdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/phdr.m4 new file mode 100644 index 0000000000..ea00caadc3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getphdr/phdr.m4 @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: phdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +#define TS_PHDRFUNC _getphdr +#define TS_PHDRSZ 32 +#include "phdr_template.c" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/Makefile new file mode 100644 index 0000000000..3f0d2d46e5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= shdr.m4 +TS_YAML= shdr + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/shdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/shdr.m4 new file mode 100644 index 0000000000..738d3aad2c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_getshdr/shdr.m4 @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +include(`getshdr.m4') + +TP_NULL(32) + +TC_MAKE_REF_SHDR(32) +TP_SHDR(32,lsb) +TP_SHDR(32,msb) + + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/Makefile new file mode 100644 index 0000000000..9a26379dd6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/Makefile @@ -0,0 +1,10 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_DATA= ehdr.msb32 ehdr.lsb32 ehdr.msb64 ehdr.lsb64 \ + ehdr-malformed-1.lsb32 ehdr-malformed-1.msb32 \ + newehdr.lsb32 newehdr.msb32 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/ehdr.m4 new file mode 100644 index 0000000000..04577441ca --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_newehdr/ehdr.m4 @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +define(`TS_EHDRFUNC',`_newehdr') +define(`TS_EHDRSZ',`32') +include(`ehdr_template.m4') + +include(`newehdr_template.m4') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/Makefile new file mode 100644 index 0000000000..28f4fe3e76 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= xlate.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/xlate.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/xlate.m4 new file mode 100644 index 0000000000..65e5f195e1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetof/xlate.m4 @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +include(`elfts.m4') + +define(`TPFNNAME',`elf32_xlatetof') + +include(`xlate_template.m4') + +Xlate_TestConversions() +Xlate_TestConversionsSharedBuffer() + +Xlate_TestBadArguments() +Xlate_TestBadBuffers() diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/Makefile new file mode 100644 index 0000000000..28f4fe3e76 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= xlate.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/xlate.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/xlate.m4 new file mode 100644 index 0000000000..941eb31398 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf32_xlatetom/xlate.m4 @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $ + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +include(`elfts.m4') + +define(`TPFNNAME',`elf32_xlatetom') + +include(`xlate_template.m4') + +Xlate_TestConversions() +Xlate_TestConversionsSharedBuffer() + +Xlate_TestBadArguments() +Xlate_TestBadBuffers() diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/Makefile new file mode 100644 index 0000000000..519fd4e67a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_YAML= ehdr ehdr-malformed-1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/ehdr.m4 new file mode 100644 index 0000000000..ce7774c7c2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getehdr/ehdr.m4 @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +define(`TS_EHDRFUNC',`_getehdr') +define(`TS_EHDRSZ',`64') +include(`ehdr_template.m4') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/Makefile new file mode 100644 index 0000000000..683b9d76b5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= phdr.m4 +TS_DATA= ehdr.lsb64 ehdr.msb64 \ + phdr.lsb32 phdr.msb32 phdr.msb64 phdr.lsb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/phdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/phdr.m4 new file mode 100644 index 0000000000..97af5fa1dd --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getphdr/phdr.m4 @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: phdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +#define TS_PHDRFUNC _getphdr +#define TS_PHDRSZ 64 +#include "phdr_template.c" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/Makefile new file mode 100644 index 0000000000..f1c7913cb4 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= shdr.m4 +TS_DATA= shdr.msb64 shdr.lsb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/shdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/shdr.m4 new file mode 100644 index 0000000000..ed877833df --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_getshdr/shdr.m4 @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +include(`getshdr.m4') + +TP_NULL(64) + +TC_MAKE_REF_SHDR(64) +TP_SHDR(64,lsb) +TP_SHDR(64,msb) + + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/Makefile new file mode 100644 index 0000000000..bf71d451c2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/Makefile @@ -0,0 +1,10 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_DATA= ehdr.msb64 ehdr.lsb64 ehdr.msb32 ehdr.lsb32 \ + ehdr-malformed-1.lsb64 ehdr-malformed-1.msb64 \ + newehdr.lsb64 newehdr.msb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/ehdr.m4 new file mode 100644 index 0000000000..36c5d8e38f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_newehdr/ehdr.m4 @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +define(`TS_EHDRFUNC',`_newehdr') +define(`TS_EHDRSZ',`64') +include(`ehdr_template.m4') + +include(`newehdr_template.m4') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/Makefile new file mode 100644 index 0000000000..28f4fe3e76 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= xlate.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/xlate.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/xlate.m4 new file mode 100644 index 0000000000..a4c405bc5c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetof/xlate.m4 @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +include(`elfts.m4') + +define(`TPFNNAME',`elf64_xlatetof') + +include(`xlate_template.m4') + +Xlate_TestConversions() +Xlate_TestConversionsSharedBuffer() + +Xlate_TestBadArguments() +Xlate_TestBadBuffers() diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/Makefile new file mode 100644 index 0000000000..28f4fe3e76 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= xlate.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/xlate.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/xlate.m4 new file mode 100644 index 0000000000..2b6799f2c5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf64_xlatetom/xlate.m4 @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate.m4 2206 2011-11-25 11:41:01Z jkoshy $ + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +include(`elfts.m4') + +define(`TPFNNAME',`elf64_xlatetom') + +include(`xlate_template.m4') + +Xlate_TestConversions() +Xlate_TestConversionsSharedBuffer() + +Xlate_TestBadArguments() +Xlate_TestBadBuffers() diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/Makefile new file mode 100644 index 0000000000..d0c68d45a5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/Makefile @@ -0,0 +1,24 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= begin.m4 +TS_FILES= entry-too-large.ar +TS_DATA= check_elf.msb32 check_elf.lsb32 check_elf.msb64 \ + check_elf.lsb64 a.ar a-bsd.ar a.o zero +CLEANFILES+= a.c + +a.c: .SILENT + echo "int dummy;" > a.c + +a.ar: a.o .SILENT + ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null + +a-bsd.ar: a.o .SILENT + rm -f ${.TARGET} + ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} ${.ALLSRC} > /dev/null + +zero: .SILENT + rm -f ${.TARGET}; touch ${.TARGET} + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/begin.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/begin.m4 new file mode 100644 index 0000000000..16ac34e668 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/begin.m4 @@ -0,0 +1,677 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: begin.m4 3706 2019-03-02 20:57:45Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +include(`elfts.m4') + +define(`TS_ARFILE_BSD',`"a-bsd.ar"') +define(`TS_ARFILE_SVR4',`"a.ar"') + +/* + * Test the `elf_begin' entry point. + */ + +/* + * Calling elf_begin() before elf_version() results in ELF_E_SEQUENCE. + * Note that these test cases should run as a separate invocation than + * the others since they need to be run before elf_version() is called. + */ +undefine(`FN') +define(`FN',` +void +tcSequenceUninitialized$1(void) +{ + Elf *e; + int error, result; + + TP_ANNOUNCE("elf_version() needs to be set before " + "using the elf_begin($1) API."); + + result = TET_PASS; + if ((e = elf_begin(-1, ELF_C_$1, NULL)) != NULL || + (error = elf_errno()) != ELF_E_SEQUENCE) + TP_FAIL("ELF_C_$1: e=%p error=%d \"%s\".", (void *) e, error, + elf_errmsg(error)); + + tet_result(result); +}') + +FN(`NULL') +FN(`READ') +FN(`WRITE') +FN(`RDWR') + +void +tcCmdInvalid(void) +{ + Elf *e; + int c, error, result; + + TP_ANNOUNCE("An invalid cmd value returns ELF_E_ARGUMENT."); + + TP_SET_VERSION(); + + result = TET_PASS; + for (c = ELF_C_NULL-1; c <= ELF_C_NUM; c++) { + if (c == ELF_C_READ || c == ELF_C_WRITE || c == ELF_C_RDWR || + c == ELF_C_NULL) + continue; + if ((e = elf_begin(-1, c, NULL)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("cmd=%d: e=%p error=%d .", c, + (void *) e, error); + break; + } + } + + done: + tet_result(result); +} + +void +tcCmdNull(void) +{ + Elf *e; + int result; + + TP_ANNOUNCE("cmd == ELF_C_NULL returns NULL."); + + TP_SET_VERSION(); + + result = (e = elf_begin(-1, ELF_C_NULL, NULL)) != NULL ? TET_FAIL : + TET_PASS; + + done: + tet_result(result); +} + + +/* + * Verify that opening non-regular files fail with ELF_E_ARGUMENT + */ +undefine(`FN') +define(`FN',` +void +tcNonRegular$1(void) +{ + Elf *e; + int error, fd, result; + + e = NULL; + fd = -1; + result = TET_FAIL; + + TP_ANNOUNCE("opening a $3 fails with ELF_E_ARGUMENT."); + + TP_SET_VERSION(); + + if ((fd = open("$2", O_RDONLY)) < 0) { + TP_UNRESOLVED("open \"$2\" failed: %s", strerror(errno)); + goto done; + } + + e = elf_begin(fd, ELF_C_READ, NULL); + + if (e == NULL && (error = elf_errno()) == ELF_E_ARGUMENT) + result = TET_PASS; /* Verify the error. */ + + done: + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(`DeviceFile', `/dev/null', `device file') +FN(`Directory', `.', `directory') + +/* + * Verify that for command modes ELF_C_READ and ELF_C_RDWR, opening + * a zero sized regular file fails with ELF_E_ARGUMENT. + */ + +undefine(`FN',`ZERO') +define(`ZERO',`"zero"') +define(`FN',` +void +tcZero$1(void) +{ + Elf *e; + int error, fd, result; + + e = NULL; + fd = -1; + result = TET_FAIL; + + TP_ANNOUNCE("opening an zero-sized file in mode ELF_C_$1 fails " + "with ELF_E_ARGUMENT."); + + TP_SET_VERSION(); + + if ((fd = open(ZERO, O_RDONLY)) < 0) { + TP_UNRESOLVED("open \"$2\" failed: %s", strerror(errno)); + goto done; + } + + e = elf_begin(fd, ELF_C_$1, NULL); + + if (e == NULL && (error = elf_errno()) == ELF_E_ARGUMENT) + result = TET_PASS; /* Verify the error. */ + + done: + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(`READ') +FN(`RDWR') + +#define TEMPLATE "TCXXXXXX" +#define FILENAME_SIZE 16 +char filename[FILENAME_SIZE]; + +int +setup_tempfile(void) +{ + int fd; + + (void) strncpy(filename, TEMPLATE, sizeof(filename)); + filename[sizeof(filename) - 1] = '\0'; + + if ((fd = mkstemp(filename)) < 0 || + write(fd, TEMPLATE, sizeof(TEMPLATE)) < 0) + return 0; + + (void) close(fd); + + return 1; + +} + +void +cleanup_tempfile(void) +{ + (void) unlink(filename); +} + + +define(`FN',` +void +tcCmdWriteFdRead_$1(void) +{ + Elf *e; + Elf$1_Ehdr *eh; + int error, fd, result; + + TP_ANNOUNCE("($1): cmd == ELF_C_WRITE fails with a non-writable FD."); + + TP_SET_VERSION(); + + if (setup_tempfile() == 0 || + (fd = open(filename, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("setup failed: %s", strerror(errno)); + goto done; + } + + result = TET_PASS; + error = -1; + + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + TP_UNRESOLVED("elf_begin() failed: %s", elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_getehdr() failed: %s", elf_errmsg(-1)); + goto done; + } + + /* Verify that elf_update() fails with the appropriate error. */ + if (elf_update(e, ELF_C_WRITE) >= 0) { + TP_FAIL("fn=%s, elf_update() succeeded unexpectedly.", + filename); + goto done; + } + + if ((error = elf_errno()) != ELF_E_IO) + TP_FAIL("fn=%s, error=%d \"%s\".", filename, error, + elf_errmsg(error)); + + done: + cleanup_tempfile(); + tet_result(result); +}') + +FN(32) +FN(64) + +void +tcCmdWriteFdRdwr(void) +{ + Elf *e; + int error, fd, result; + + TP_ANNOUNCE("cmd == ELF_C_WRITE on an 'rdwr' FD passes."); + + TP_SET_VERSION(); + + if (setup_tempfile() == 0 || + (fd = open(filename, O_RDWR, 0)) < 0) { + TP_UNRESOLVED("setup failed: %s", strerror(errno)); + goto done; + } + + result = TET_PASS; + error = -1; + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + error = elf_errno(); + TP_FAIL("fn=%s, error=%d \"%s\"", filename, error, + elf_errmsg(error)); + } + + done: + cleanup_tempfile(); + tet_result(result); +} + +void +tcCmdWriteFdWrite(void) +{ + Elf *e; + int error, fd, result; + + TP_ANNOUNCE("cmd == ELF_C_WRITE on write-only FD passes."); + + TP_SET_VERSION(); + + if (setup_tempfile() == 0 || + (fd = open(filename, O_WRONLY, 0)) < 0) { + TP_UNRESOLVED("setup failed: %s", strerror(errno)); + goto done; + } + + result = TET_PASS; + error = -1; + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + error = elf_errno(); + TP_FAIL("fn=%s, error=%d \"%s\"", filename, + error, elf_errmsg(error)); + } + + done: + cleanup_tempfile(); + tet_result(result); +} + +void +tcCmdWriteParamIgnored(void) +{ + Elf *e, *t; + int error, fd, fd1, result; + + TP_ANNOUNCE("cmd == ELF_C_WRITE ignores the last parameter."); + + TP_SET_VERSION(); + + if (setup_tempfile() == 0 || + (fd = open(filename, O_WRONLY, 0)) < 0 || + (fd1 = open(filename, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("setup failed: %s", strerror(errno)); + goto done; + } + + if ((t = elf_begin(fd1, ELF_C_READ, NULL)) == NULL) { + TP_UNRESOLVED("elf_begin() failed unexpectedly: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + error = -1; + if ((e = elf_begin(fd, ELF_C_WRITE, t)) == NULL) { + TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1)); + } + + done: + cleanup_tempfile(); + tet_result(result); +} + + +/* + * Check that opening various classes/endianness of ELF files + * passes. + */ +undefine(`FN') +define(`FN',` +void +tcElfOpen$1$2(void) +{ + Elf *e; + int fd, result; + char *p; + + TP_ANNOUNCE("open(ELFCLASS$1,ELFDATA2`'TOUPPER($2)) succeeds."); + + TP_SET_VERSION(); + + fd = -1; + e = NULL; + result = TET_UNRESOLVED; + + if ((fd = open ("check_elf.$2$1", O_RDONLY)) < 0) { + TP_UNRESOLVED("open() failed: %s.", strerror(errno)); + goto done; + } + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + TP_FAIL("elf_begin() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((p = elf_getident(e, NULL)) == NULL) { + TP_FAIL("elf_getident() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if (p[EI_CLASS] != ELFCLASS$1 || + p[EI_DATA] != ELFDATA2`'TOUPPER($2)) + TP_FAIL("class %d expected %d, data %d expected %d.", + p[EI_CLASS], ELFCLASS$1, p[EI_DATA], ELFDATA2`'TOUPPER($2)); + else + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Check an `fd' mismatch is detected. + */ +void +tcFdMismatch(void) +{ + Elf *e, *e2; + int error, fd, result; + + TP_ANNOUNCE("an fd mismatch is detected."); + + TP_SET_VERSION(); + + e = e2 = NULL; + fd = -1; + + if ((fd = open("check_elf.msb32", O_RDONLY)) < 0 || + (e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + TP_UNRESOLVED("open(check_elf) failed: fd=%d.", fd); + goto done; + } + + result = TET_PASS; + + if ((e2 = elf_begin(fd+1, ELF_C_READ, e)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("elf_begin(%d+1) -> %p, error=%d \"%s\".", fd, + (void *) e2, error, elf_errmsg(error)); + done: + if (e) + (void) elf_end(e); + if (e2) + (void) elf_end(e2); + if (fd >= 0) + (void) close(fd); + tet_result(result); +} + +undefine(`ARFN') +define(`ARFN',` +/* + * Check that an $1-style AR archive detects a cmd mismatch. + */ +void +tcArCmdMismatchRDWR_$1(void) +{ + Elf *e, *e2; + int error, fd, result; + + TP_ANNOUNCE("($1): a cmd mismatch is detected."); + + TP_SET_VERSION(); + + result = TET_UNRESOLVED; + e = e2 = NULL; + fd = -1; + + /* Open the archive with ELF_C_READ. */ + _TS_OPEN_FILE(e, TS_ARFILE_$1, ELF_C_READ, fd, goto done;); + + /* Attempt to iterate through it with ELF_C_RDWR. */ + result = TET_PASS; + if ((e2 = elf_begin(fd, ELF_C_RDWR, e)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("e2=%p error=%d \"%s\".", (void *) e2, + error, elf_errmsg(error)); + done: + if (e) + (void) elf_end(e); + if (e2) + (void) elf_end(e2); + if (fd >= 0) + (void) close(fd); + tet_result(result); +} + +/* + * Check that a member is correctly retrieved for $1-style archives. + */ +void +tcArRetrieval_$1(void) +{ + Elf *e, *e1; + int fd, result; + Elf_Kind k; + + TP_ANNOUNCE("($1): an archive member is correctly retrieved."); + + TP_SET_VERSION(); + + e = e1 = NULL; + fd = -1; + + _TS_OPEN_FILE(e, TS_ARFILE_$1, ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if ((e1 = elf_begin(fd, ELF_C_READ, e)) == NULL) { + TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((k = elf_kind(e1)) != ELF_K_ELF) + TP_FAIL("kind %d, expected %d.", k, ELF_K_ELF); + + done: + if (e1) + (void) elf_end(e1); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} + +/* + * Check opening of ar(1) archives opened with elf_memory(). + */ + +void +tcArMemoryFdIgnored_$1(void) +{ + Elf *e, *e1; + int fd, result; + Elf_Kind k; + struct stat sb; + char *b; + + TP_ANNOUNCE("($1): The fd value is ignored for archives opened " + "with elf_memory()."); + + TP_SET_VERSION(); + + e = e1 = NULL; + b = NULL; + fd = -1; + result = TET_UNRESOLVED; + + /* + * First, populate a memory area with the contents of + * an ar(1) archive. + */ + + if ((fd = open(TS_ARFILE_$1, O_RDONLY)) < 0) { + TP_UNRESOLVED("open of \"" TS_ARFILE_$1 "\" failed: %s", + strerror(errno)); + goto done; + } + + if (fstat(fd, &sb) < 0) { + TP_UNRESOLVED("fstat failed: %s", strerror(errno)); + goto done; + } + + if ((b = malloc(sb.st_size)) == NULL) { + TP_UNRESOLVED("malloc failed: %s", strerror(errno)); + goto done; + } + + if (read(fd, b, sb.st_size) != sb.st_size) { + /* Deal with ERESTART? */ + TP_UNRESOLVED("read failed: %s", strerror(errno)); + goto done; + } + + if ((e = elf_memory(b, sb.st_size)) == NULL) { + TP_FAIL("elf_memory failed: %s", elf_errmsg(-1)); + goto done; + } + + /* + * Verify that the fd value is ignored for this case. + */ + if ((e1 = elf_begin(-2, ELF_C_READ, e)) == NULL) { + TP_FAIL("elf_begin() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((k = elf_kind(e1)) != ELF_K_ELF) + TP_FAIL("kind %d, expected %d.", k, ELF_K_ELF); + + result = TET_PASS; + + done: + if (b) + free(b); + if (e1) + (void) elf_end(e1); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} +') + +ARFN(`BSD') +ARFN(`SVR4') + +/* + * Verify behavior with a corrupted header containing a too-large size. + */ +void +tcArEntryTooLarge(void) +{ + Elf *ar_e, *e; + int error, fd, result; + + result = TET_UNRESOLVED; + ar_e = NULL; + e = NULL; + + TP_ANNOUNCE("elf_begin() returns ELF_E_ARCHIVE for too-large archive " + "entries."); + + TP_SET_VERSION(); + + _TS_OPEN_FILE(ar_e, "entry-too-large.ar", ELF_C_READ, fd, goto done;); + + if ((e = elf_begin(fd, ELF_C_READ, ar_e)) != NULL) { + TP_FAIL("elf_begin() succeeded."); + goto done; + } + + error = elf_errno(); + if (error != ELF_E_ARCHIVE) { + TP_FAIL("unexpected error %d", error); + goto done; + } + + result = TET_PASS; + +done: + if (e) + (void) elf_end(e); + if (ar_e) + (void) elf_end(ar_e); + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/entry-too-large.ar b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/entry-too-large.ar new file mode 100644 index 0000000000..5cab148630 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_begin/entry-too-large.ar @@ -0,0 +1,3 @@ +! +a1.c/ 1551379738 1000 1000 100644 9 ` +1234567 diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/Makefile new file mode 100644 index 0000000000..4db10d7ef2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/Makefile @@ -0,0 +1,16 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= cntl.m4 +TS_DATA= a.ar +CLEANFILES+= a.c a.o + +a.c: .SILENT + echo "int foobar;" > ${.TARGET} + +a.ar: a.o .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/cntl.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/cntl.m4 new file mode 100644 index 0000000000..33b12f7d0b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_cntl/cntl.m4 @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: cntl.m4 2191 2011-11-21 08:34:02Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * Test the `elf_cntl' API. + */ + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +/* + * A NULL elf parameter causes elf_cntl() to fail. + */ +void +tcInvalidNull(void) +{ + int error, result, ret; + + TP_ANNOUNCE("elf_cntl(NULL,...) fails with ELF_E_ARGUMENT."); + + TP_CHECK_INITIALIZATION(); + + ret = error = 0; + result = TET_PASS; + if ((ret = elf_cntl(NULL, ELF_C_FDREAD)) != -1 || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("ret=%d, error=%d \"%s\".", ret, error); + + tet_result(result); +} + +/* + * Invalid `cmd' values are rejected. + */ +void +tcInvalidInvalid(void) +{ + Elf *e; + int c, error, result, ret; + + TP_ANNOUNCE("elf_cntl(e,[INVALID]) fails with ELF_E_ARGUMENT."); + + TP_CHECK_INITIALIZATION(); + + TS_OPEN_MEMORY(e, elf_file); + + ret = error = 0; + result = TET_PASS; + for (c = ELF_C_FIRST-1; c <= ELF_C_LAST; c++) { + if (c == ELF_C_FDDONE || c == ELF_C_FDREAD) + continue; + if ((ret = elf_cntl(e, c)) != -1 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("returned (%d) / error (%d) for " + "c = %d.", ret, error, c); + break; + } + } + + (void) elf_end(e); + tet_result(result); +} + +/* + * Calling elf_cntl(FDREAD) for files opened in read mode. + */ +void +tcReadFDREAD(void) +{ + Elf *e; + int result; + + TP_ANNOUNCE("elf_cntl(e,FDREAD) for a read-only descriptor succeeds."); + + TP_CHECK_INITIALIZATION(); + + TS_OPEN_MEMORY(e, elf_file); + + result = TET_PASS; + if (elf_cntl(e, ELF_C_FDREAD) != 0) + TP_FAIL("elf_errmsg=\"%s\".", elf_errmsg(-1)); + + (void) elf_end(e); + tet_result(result); +} + +static char pathname[PATH_MAX]; + +/* + * elf_cntl(FDREAD) doesn't make sense for a descriptor opened + * for writing. + */ +void +tcWriteFDREAD(void) +{ + Elf *e; + int err, fd, result, ret; + + TP_ANNOUNCE("elf_cntl(e,FDREAD) for a descriptor opened for write " + "fails with ELF_E_MODE."); + + TP_CHECK_INITIALIZATION(); + + (void) strncpy(pathname, "/tmp/TCXXXXXX", sizeof(pathname)); + pathname[sizeof(pathname) - 1] = '\0'; + + if ((fd = mkstemp(pathname)) == -1 || + (e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + TP_UNRESOLVED("elf_begin(%d,WRITE,NULL) failed."); + goto done; + } + + result = TET_PASS; + if ((ret = elf_cntl(e, ELF_C_FDREAD)) != -1 || + (err = elf_errno()) != ELF_E_MODE) + TP_FAIL("ret (%d) error (%d).", ret, err); + + done: + (void) elf_end(e); + (void) unlink(pathname); + tet_result(result); +} + +/* + * An elf_cntl(FDDONE) causes a subsequent elf_update(WRITE) to fail. + */ + +void +tcWriteFDDONE(void) +{ + Elf *e; + Elf32_Ehdr *eh; + int err, fd, result; + off_t ret; + + TP_ANNOUNCE("elf_cntl(e,FDDONE) makes a subsequent " + "elf_update(ELF_C_WRITE) fail with ELF_E_SEQUENCE."); + + TP_CHECK_INITIALIZATION(); + + (void) strncpy(pathname, "/tmp/TCXXXXXX", sizeof(pathname)); + pathname[sizeof(pathname) - 1] = '\0'; + + if ((fd = mkstemp(pathname)) == -1 || + (e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + TP_UNRESOLVED("elf_begin(%d,WRITE,NULL) failed."); + goto done; + } + + if (elf_cntl(e, ELF_C_FDDONE) == -1) { + TP_FAIL("elf_cntl(e,FDONE) failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if (elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf32_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if ((ret = elf_update(e, ELF_C_WRITE)) != (off_t) -1 || + (err = elf_errno()) != ELF_E_SEQUENCE) + TP_FAIL("ret (%jd) err (%d).", (uint64_t) ret, err); + + done: + tet_result(result); + + (void) elf_end(e); + (void) unlink(pathname); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/Makefile new file mode 100644 index 0000000000..5c44b4c255 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= end.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/end.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/end.m4 new file mode 100644 index 0000000000..ef2972eb1d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_end/end.m4 @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: end.m4 1349 2011-01-01 15:18:43Z jkoshy $ + */ + +include(`elfts.m4') + +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +/* + * Test the `elf_end' entry point. + */ + +void +tcEndNullOk(void) +{ + TP_ANNOUNCE("a NULL argument is allowed."); + + tet_result(elf_end(NULL) == 0 ? TET_PASS : TET_FAIL); +} + +char data[] = "0xDEADC0DE"; + +void +tcBeginEndPair(void) +{ + Elf *e; + + TP_ANNOUNCE("a single begin/end pair works"); + + TP_CHECK_INITIALIZATION(); + + TS_OPEN_MEMORY(e,data); + + tet_result (elf_end(e) == 0 ? TET_PASS : TET_FAIL); +} + +void +tcNestedCount(void) +{ + int r1, r2; + Elf *e, *e1; + + TP_ANNOUNCE("begin/end pairs nest correctly"); + + TP_CHECK_INITIALIZATION(); + + TS_OPEN_MEMORY(e,data); + + if ((e1 = elf_begin(-1, ELF_C_READ, e)) != e) { + tet_result(TET_UNRESOLVED); + return; + } + + if ((r1 = elf_end(e1)) != 1 || + (r2 = elf_end(e)) != 0) { + tet_printf("fail: r1=%d r2=%d.", r1, r2); + tet_result(TET_FAIL); + return; + } + + tet_result(TET_PASS); +} + +/* + * TODO + * - closing a member of an archive should decrement the parent's activation + * count. + * - opening a member of an archive should increment the parent's activation + * count. + * - What do we do about out of order elf_end()'s on archives and members. + */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/Makefile new file mode 100644 index 0000000000..daa9521472 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= errmsg.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/errmsg.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/errmsg.m4 new file mode 100644 index 0000000000..c5d1d17185 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errmsg/errmsg.m4 @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2006,2010,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: errmsg.m4 2191 2011-11-21 08:34:02Z jkoshy $ + */ + +include(`elfts.m4') + +#include +#include + +#include "tet_api.h" + +/* + * Test the `elf_errmsg' entry point. + */ + +/* + * Assertion: the function returns NULL if the argument is zero and + * there is no pending error in the library. + */ +void +tcZeroNoerror(void) +{ + + TP_ANNOUNCE("returns NULL with zero & no current error"); + + (void) elf_errno(); /* discard current error number */ + + if (elf_errmsg(0) == NULL) + tet_result(TET_PASS); + else + tet_result(TET_FAIL); +} + +/* + * An error value of -1 should return non-NULL + */ + +define(`NO_ERROR_MESSAGE',`"No Error"')dnl Needs to match the string in "libelf/elf_errmsg.c". + +void +tcMinusoneNoerror(void) +{ + int result; + const char *msg; + + TP_ANNOUNCE("returns non-null for arg -1 & no current error"); + + (void) elf_errno(); /* discard stored error */ + + result = TET_UNRESOLVED; + + msg = elf_errmsg(-1); + if (msg == NULL) { + TP_FAIL("null return from elf_errmsg()"); + goto done; + } + + if (strcmp(msg, NO_ERROR_MESSAGE)) { + TP_FAIL("unexpected message \"%s\"", msg); + goto done; + } + + result = TET_PASS; + +done: + tet_result(result); +} + +/* + * Assertion: All error numbers from 1..NUM return a non-null string. + */ + +void +tcCheckAllValidErrorMessages(void) +{ + int n, result; + const char *msg; + + TP_ANNOUNCE("returns non-null for all valid error numbers"); + + (void) elf_errno(); /* discard stored error */ + + result = TET_UNRESOLVED; + + for (n = ELF_E_NONE+1; n < ELF_E_NUM; n++) { + if ((msg = elf_errmsg(n)) == NULL) { + TP_FAIL("null return from elf_errmsg()"); + goto done; + } + } + + result = TET_PASS; + +done: + tet_result(result); + +} + +/* + * Assertion: with an error pending, elf_errmsg(0) returns a non-NULL + * pointer. + */ + +void +tcNonNullWithErrorPending(void) +{ + int result, version; + const char *msg; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("non null error message is returned for a pending error"); + + /* Generate an error, e.g., ELF_E_VERSION. */ + if ((version = elf_version(EV_CURRENT+1)) != EV_NONE) { + TP_UNRESOLVED("elf_version() returned %d", version); + goto done; + } + + if ((msg = elf_errmsg(0)) == NULL) { + TP_FAIL("elf_errmsg() returned NULL"); + goto done; + } + + result = TET_PASS; + +done: + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/Makefile new file mode 100644 index 0000000000..2e67823605 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= errno.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/errno.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/errno.m4 new file mode 100644 index 0000000000..b55ee96f98 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_errno/errno.m4 @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: errno.m4 2191 2011-11-21 08:34:02Z jkoshy $ + */ + +include(`elfts.m4') + +#include +#include +#include +#include +#include + +#include "tet_api.h" + +/* + * Test the `elf_errno' entry point. + * + * Specific errors expected from other elf_* APIs are tested in the test + * cases for those APIs. + * + * The tests here only check the behaviour of the elf_errno() API. + */ + +/* + * Assertion: The initial value of the libraries error number is zero. + */ + +void +tcInitialValue(void) +{ + int err; + + TP_ANNOUNCE("The initial error value must be zero."); + err = elf_errno(); + tet_result(err == 0 ? TET_PASS : TET_FAIL); +} + +/* + * Assertion: an elf_errno() call resets the stored error number. + */ + +void +tcReset(void) +{ + int err; + + TP_ANNOUNCE("A pending error number must be reset by elf_errno()."); + + (void) elf_errno(); /* discard stored error */ + err = elf_errno(); + tet_result(err == 0 ? TET_PASS : TET_FAIL); +} + +/* + * Assertion: elf_begin with cmd == ELF_C_NULL does not reset the + * error value. + */ + +void +tcNonResetWithNull(void) +{ + int error, fd, result; + Elf *e, *e1; + + result = TET_UNRESOLVED; + fd = -1; + e = e1 = NULL; + + TP_ANNOUNCE("a pending error number is not reset by " + "elf_begin(ELF_C_NULL)."); + + TP_SET_VERSION(); + + /* Force an error. */ + if ((fd = open(".", O_RDONLY)) < 0) { + TP_UNRESOLVED("open(.) failed: %s", strerror(errno)); + goto done; + } + + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) != NULL) { + TP_UNRESOLVED("elf_begin(ELF_C_WRITE) succeeded " + "unexpectedly."); + goto done; + } + + /* Invoke an operation with ELF_C_NULL */ + if ((e1 = elf_begin(fd, ELF_C_NULL, NULL)) != NULL) { + TP_FAIL("elf_begin(ELF_C_NULL) returned non-null (%p)", + (void *) e1); + goto done; + } + + /* Recheck the old error. */ + if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + + if (e) + elf_end(e); + if (e1) + elf_end(e1); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Assertion: elf_errno() retrieves the expected error, when one is pending. + */ + +void +tcExpectedErrorIsReturned(void) +{ + int error, fd, result; + Elf *e; + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TP_ANNOUNCE("A pending error number is correctly returned."); + + TP_SET_VERSION(); + + /* Force an error. */ + if ((fd = open(".", O_RDONLY)) < 0) { + TP_UNRESOLVED("open(.) failed: %s", strerror(errno)); + goto done; + } + + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) != NULL) { + TP_UNRESOLVED("elf_begin(ELF_C_WRITE) succeeded " + "unexpectedly."); + goto done; + } + + /* Check the current error. */ + if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/Makefile new file mode 100644 index 0000000000..53241941f9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= fill.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/fill.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/fill.m4 new file mode 100644 index 0000000000..6d07891b9f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fill/fill.m4 @@ -0,0 +1,558 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: fill.m4 1696 2011-08-06 09:12:19Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +define(`TS_ALIGN', 512) +define(`TS_FILLCHAR', `0xAB') +define(`TS_OFFSET_1', 512) +define(`TS_OFFSET_2', 1024) +define(`TS_SHDR_OFFSET', 2048) + +/* + * Test the `elf_fill' entry point. + */ + +static char testdata[] = { + 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x99, 0x88 +}; + +/* + * Check that gaps in the file are correctly filled with the + * specified fill character. + */ +undefine(`FN') +define(`FN',` +void +tcDefaultLayout$2$1(void) +{ + Elf *e; + Elf$1_Ehdr *eh; + Elf$1_Shdr *sh; + Elf_Scn *scn; + Elf_Data *d; + int fd, result; + size_t fsz; + off_t rc; + unsigned char *p, *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("$2$1: elf_fill()/lib-layout fills gaps."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + r = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + /* + * We create an ELF file with a section with a 1K and 2K alignments + * and verify that the gaps are filled appropriately. + */ + + elf_fill(TS_FILLCHAR); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2$2; + + /* + * Create the first section. + */ + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_PROGBITS; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_align = TS_ALIGN; + d->d_buf = testdata; + d->d_size = sizeof(testdata); + d->d_type = ELF_T_BYTE; + + /* + * Create the second section. + */ + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_PROGBITS; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + d->d_align = TS_ALIGN; + d->d_buf = testdata; + d->d_size = sizeof(testdata); + d->d_type = ELF_T_BYTE; + + if ((rc = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + /* + * Mmap() in the file and check that the contents match. + */ + + if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open() failed: %s.", strerror(errno)); + goto done; + } + + if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd, + (off_t) 0)) == MAP_FAILED) { + TP_UNRESOLVED("mmap() failed: %s.", strerror(errno)); + goto done; + } + + /* Check the first gap */ + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Section data would be placed at the next alignment boundary. */ + for (p = r + fsz; p < r + TS_ALIGN; p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + /* Check whether valid contents exist at first section offset. */ + if (memcmp(r + TS_ALIGN, testdata, sizeof(testdata)) != 0) { + TP_FAIL("memcmp(first) failed."); + goto done; + } + + /* Check the between sections. */ + for (p = r + TS_ALIGN + sizeof(testdata); p < r + 2*TS_ALIGN; p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + /* Check whether valid contents exist at second section offset. */ + if (memcmp(r + 2*TS_ALIGN, testdata, sizeof(testdata)) != 0) { + TP_FAIL("memcmp(second) failed."); + goto done; + } + + result = TET_PASS; + done: + if (r) + (void) munmap(r, rc); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + unlink(TS_NEWFILE); + tet_result(result); +}') + +FN(32,LSB) +FN(32,MSB) +FN(64,LSB) +FN(64,MSB) + + +/* + * Check that regions are filled correctly, for application specified + * layouts. + */ +define(`FN',` +void +tcAppLayout$2$1(void) +{ + Elf *e; + Elf$1_Ehdr *eh; + Elf$1_Shdr *sh; + Elf_Scn *scn; + Elf_Data *d; + int fd, result; + size_t fsz; + off_t rc; + unsigned char *p, *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("$2$1: elf_fill()/app-layout fills gaps."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + r = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + /* + * We create an ELF file with a section with a 1K and 2K alignments + * and verify that the gaps are filled appropriately. + */ + + elf_fill(TS_FILLCHAR); + if (elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT) != ELF_F_LAYOUT) { + TP_UNRESOLVED("elf_flagdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2$2; + + /* + * Create the first section. + */ + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_PROGBITS; + sh->sh_offset = TS_OFFSET_2; + sh->sh_addralign = 1; + sh->sh_size = sizeof(testdata); + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + d->d_align = 1; + d->d_off = 0; + d->d_buf = testdata; + d->d_size = sizeof(testdata); + d->d_type = ELF_T_BYTE; + + /* + * Create the second section, physically located BEFORE the + * first section. + */ + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_scn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_PROGBITS; + sh->sh_offset = TS_OFFSET_1; + sh->sh_addralign = 1; + sh->sh_size = sizeof(testdata); + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + d->d_align = 1; + d->d_off = 0; + d->d_buf = testdata; + d->d_size = sizeof(testdata); + d->d_type = ELF_T_BYTE; + + /* + * Position the section header after section data. + */ + eh->e_shoff = TS_SHDR_OFFSET; + + if ((rc = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + /* + * Mmap() in the file and check that the contents match. + */ + + if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open() failed: %s.", strerror(errno)); + goto done; + } + + if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd, + (off_t) 0)) == MAP_FAILED) { + TP_UNRESOLVED("mmap() failed: %s.", strerror(errno)); + goto done; + } + + /* Check the first gap */ + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + for (p = r + fsz; p < r + TS_OFFSET_1; p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + /* Check whether valid contents exist at first section offset. */ + if (memcmp(r + TS_OFFSET_1, testdata, sizeof(testdata)) != 0) { + TP_FAIL("memcmp(first) failed."); + goto done; + } + + /* Check the second gap. */ + for (p = r + TS_OFFSET_1 + sizeof(testdata); p < r + TS_OFFSET_2; p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + /* Check whether valid contents exist at second section offset. */ + if (memcmp(r + TS_OFFSET_2, testdata, sizeof(testdata)) != 0) { + TP_FAIL("memcmp(second) failed."); + goto done; + } + + /* Check the gap till the shdr table. */ + for (p = r + TS_OFFSET_2 + sizeof(testdata); + p < r + TS_SHDR_OFFSET; + p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + result = TET_PASS; + + done: + if (r) + (void) munmap(r, rc); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + unlink(TS_NEWFILE); + tet_result(result); +}') + +FN(32,LSB) +FN(32,MSB) +FN(64,LSB) +FN(64,MSB) + +/* + * Check that the region between the Ehdr and Phdr is filled correctly, + * when the application specifies the file layout. + */ +define(`FN',` +void +tcAppLayoutEhdrPhdrGap$2$1(void) +{ + Elf *e; + Elf$1_Ehdr *eh; + Elf$1_Phdr *ph; + int fd, result; + size_t fsz; + off_t rc; + unsigned char *p, *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("$2$1: elf_fill()/app-layout fills gaps."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + r = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + /* + * We create an ELF file with the PHDR placed an offset away + * from the EHDR. + */ + elf_fill(TS_FILLCHAR); + if (elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT) != ELF_F_LAYOUT) { + TP_UNRESOLVED("elf_flagdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2$2; + + /* + * Create the PHDR. + */ + if ((ph = elf$1_newphdr(e, 1)) == NULL) { + TP_UNRESOLVED("elf_newphdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* + * Position the PHDR. + */ + eh->e_phoff = TS_OFFSET_1; + + /* + * Update the ELF object. + */ + if ((rc = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + /* + * Mmap() in the file and check that the contents match. + */ + + if ((fd = open(TS_NEWFILE, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open() failed: %s.", strerror(errno)); + goto done; + } + + if ((r = mmap(NULL, (size_t) rc, PROT_READ, MAP_SHARED, fd, + (off_t) 0)) == MAP_FAILED) { + TP_UNRESOLVED("mmap() failed: %s.", strerror(errno)); + goto done; + } + + /* Check the gap between the EHDR and the PHDR. */ + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("elf$1_fsize(ELF_T_EHDR) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + for (p = r + fsz; p < r + TS_OFFSET_1; p++) + if (*p != TS_FILLCHAR) { + TP_FAIL("offset 0x%x [%d] != %d", p - r, *p, + TS_FILLCHAR); + goto done; + } + + result = TET_PASS; + + done: + if (r) + (void) munmap(r, rc); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + unlink(TS_NEWFILE); + tet_result(result); +}') + +FN(32,LSB) +FN(32,MSB) +FN(64,LSB) +FN(64,MSB) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/Makefile new file mode 100644 index 0000000000..edc0582aa3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/Makefile @@ -0,0 +1,16 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= flagarhdr.m4 + +TS_DATA= a.ar +CLEANFILES+= a1 + +a1: .SILENT + echo "a1" > ${.TARGET} + +a.ar: a1 .SILENT + ${AR} crv ${.TARGET} a1 > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/flagarhdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/flagarhdr.m4 new file mode 100644 index 0000000000..e35f2b3bc4 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagarhdr/flagarhdr.m4 @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: flagarhdr.m4 2077 2011-10-27 03:59:40Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagarhdr(). + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * The following defines to match that in ./Makefile. + */ +define(`TP_ARFILE',`"a.ar"') + + +/* + * Boiler plate to get a valid ELF pointer. + */ +define(`_TP_DECLARATIONS',` + int fd; + Elf *ar, *member; + Elf_Arhdr *arh;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + ar = member = NULL; + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((member = elf_begin(fd, ELF_C_READ, ar)) == NULL) { + TP_UNRESOLVED("retrieval of archive member failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((arh = elf_getarhdr(member)) == NULL) { + TP_UNRESOLVED("elf_getarhdr() on member failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } +') +define(`_TP_EPILOGUE',` + done: + if (member) + (void) elf_end(member); + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); +') + +TP_FLAG_NULL(`elf_flagarhdr'); +TP_FLAG_ILLEGAL_CMD(`elf_flagarhdr',`arh') +TP_FLAG_CLR(`elf_flagarhdr',`arh') +TP_FLAG_SET(`elf_flagarhdr',`arh') +TP_FLAG_ILLEGAL_FLAG(`elf_flagarhdr',`arh',`ELF_F_DIRTY') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/Makefile new file mode 100644 index 0000000000..b7421dec15 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= data.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/data.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/data.m4 new file mode 100644 index 0000000000..f1ec5bc0d3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagdata/data.m4 @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: data.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagdata(). + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * A Null argument is allowed. + */ + +TP_FLAG_NULL(`elf_flagdata') + +/* Boilerplate for getting hold of a valid Elf_Data structure. */ + +define(`_TP_DECLARATIONS',` + int fd; + Elf *e; + Elf32_Ehdr *eh; + Elf_Scn *scn; + Elf_Data *d;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd); + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", elf_errmsg(-1)); + goto done; + }') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +/* + * An illegal cmd value is rejected. + */ + +TP_FLAG_ILLEGAL_CMD(`elf_flagdata',`d') + +/* + * Legal cmd values are allowed. + */ +TP_FLAG_CLR(`elf_flagdata',`d') +TP_FLAG_SET(`elf_flagdata',`d') + +/* + * Illegal flag values are rejected. + */ +TP_FLAG_ILLEGAL_FLAG(`elf_flagdata',`d',`ELF_F_DIRTY') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/Makefile new file mode 100644 index 0000000000..96bc3894aa --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_DATA= ehdr.lsb32 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/ehdr.m4 new file mode 100644 index 0000000000..41b7a5bdb0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagehdr/ehdr.m4 @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 1408 2011-02-05 08:34:33Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagehdr(). + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * A Null argument is allowed. + */ + +TP_FLAG_NULL(`elf_flagehdr') + +/* Boilerplate for getting hold of a valid Ehdr pointer */ + +define(`_TP_DECLARATIONS',` + int fd; + Elf *e; + Elf32_Ehdr *eh;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd); + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + }') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +TP_FLAG_NON_ELF(`elf_flagehdr') + +TP_FLAG_ILLEGAL_CMD(`elf_flagehdr',`e') + +TP_FLAG_CLR(`elf_flagehdr',`e') +TP_FLAG_SET(`elf_flagehdr',`e') + +TP_FLAG_ILLEGAL_FLAG(`elf_flagehdr',`e',`ELF_F_DIRTY') + +/* + * An out-of-sequence call is detected. + */ +_TP_FLAG_FN(`tcArgsSequence',` + int error, fd; + unsigned int f; + Elf *e;',` + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Out of sequence use is detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, "ehdr.lsb32", ELF_C_READ, fd); + + result = TET_PASS; + if ((f = elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY)) != 0 || + (error = elf_errno()) != ELF_E_SEQUENCE) { + TP_FAIL("flag=0x%x, error=%d \"%s\".", f, error, + elf_errmsg(error)); + goto done; + }',`_TP_EPILOGUE') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/Makefile new file mode 100644 index 0000000000..01f6e37225 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/Makefile @@ -0,0 +1,17 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= elf.m4 +TS_DATA= a.ar + +CLEANFILES= zero + +zero: + touch ${.TARGET} + +a.ar: zero + rm -f ${.TARGET} + ar crv ${.TARGET} ${.ALLSRC} + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/elf.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/elf.m4 new file mode 100644 index 0000000000..e5006f798c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagelf/elf.m4 @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elf.m4 1599 2011-07-04 03:18:52Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagelf(). + */ + +IC_REQUIRES_VERSION_INIT(); + +TP_FLAG_NULL(`elf_flagelf') + +/* + * Boiler plate to get a valid ELF pointer. + */ +define(`_TP_DECLARATIONS',` + int fd; + Elf *e;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd);') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +TP_FLAG_NON_ELF(`elf_flagelf') + +TP_FLAG_ILLEGAL_CMD(`elf_flagelf',`e') + +TP_FLAG_CLR(`elf_flagelf',`e') +TP_FLAG_SET(`elf_flagelf',`e') + +TP_FLAG_ILLEGAL_FLAG(`elf_flagelf',`e', + `ELF_F_DIRTY|ELF_F_LAYOUT|ELF_F_ARCHIVE|ELF_F_ARCHIVE_SYSV') + + +define(`TS_ARFILE',`"a.ar"') + +dnl Helper function. + +define(`_FN',` +void +$1(void) +{ + int error, fd, result, ret; + Elf *e; + + TP_ANNOUNCE($2); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, $3, $4, fd); + + result = TET_PASS; + if ((ret = elf_flagelf(e, ELF_C_SET, $5)) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("ret=%d,error=%d \"%s\".", ret, error, + elf_errmsg(error)); + goto done; + } + + _TP_EPILOGUE() + + tet_result(result); +}') + +/* + * Attempting to set ELF_F_ARCHIVE on an object opened with ELF_C_READ + * should fail. + */ +_FN(`tcArgsArchiveFlagOnReadFD', + `"Setting ELF_F_ARCHIVE on an object opened with " + "ELF_C_READ should fail."', + TS_ARFILE, ELF_C_READ, + ELF_F_ARCHIVE) + +/* + * Attempting to set ELF_F_ARCHIVE_SYSV without ELF_F_ARCHIVE should fail. + */ +_FN(`tcArgsArchiveFlagSysV', + `"Setting ELF_F_ARCHIVE_SYSV without ELF_F_ARCHIVE should fail."', + TS_NEWFILE, ELF_C_WRITE, + ELF_F_ARCHIVE_SYSV) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/Makefile new file mode 100644 index 0000000000..db683cbb73 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= phdr.m4 +TS_DATA= phdr.lsb32 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/phdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/phdr.m4 new file mode 100644 index 0000000000..753938f895 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagphdr/phdr.m4 @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: phdr.m4 1413 2011-02-05 10:26:18Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagdata(). + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * A Null argument is allowed. + */ + +TP_FLAG_NULL(`elf_flagphdr') + +define(`_TP_DECLARATIONS',` + int fd; + Elf *e; + Elf32_Ehdr *eh; + Elf32_Phdr *ph;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd); + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((ph = elf32_newphdr(e, 1)) == NULL) { + TP_UNRESOLVED("elf_newphdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + }') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +TP_FLAG_ILLEGAL_CMD(`elf_flagphdr',`e') + +TP_FLAG_CLR(`elf_flagphdr',`e') +TP_FLAG_SET(`elf_flagphdr',`e') + +TP_FLAG_ILLEGAL_FLAG(`elf_flagphdr',`e',`ELF_F_DIRTY') + +/* + * An out-of-sequence call is detected. + */ +_TP_FLAG_FN(`tcArgsSequence',` + int error, fd; + unsigned int f; + Elf *e;',` + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("Out of sequence use is detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, "phdr.lsb32", ELF_C_READ, fd); + + result = TET_PASS; + if ((f = elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY)) != 0 || + (error = elf_errno()) != ELF_E_SEQUENCE) { + TP_FAIL("flag=0x%x, error=%d \"%s\".", f, error, + elf_errmsg(error)); + goto done; + }',`_TP_EPILOGUE') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/Makefile new file mode 100644 index 0000000000..995ddc935b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= scn.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/scn.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/scn.m4 new file mode 100644 index 0000000000..6d6b0c66bc --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagscn/scn.m4 @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: scn.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagdata(). + */ + +IC_REQUIRES_VERSION_INIT(); + +TP_FLAG_NULL(`elf_flagscn') + +/* Boilerplate for getting hold of a valid Elf_Scn pointer */ +define(`_TP_DECLARATIONS',` + int fd; + Elf *e; + Elf32_Ehdr *eh; + Elf_Scn *scn;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd); + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + }') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +TP_FLAG_ILLEGAL_CMD(`elf_flagscn',`scn') + +TP_FLAG_CLR(`elf_flagscn',`scn') +TP_FLAG_SET(`elf_flagscn',`scn') + +TP_FLAG_ILLEGAL_FLAG(`elf_flagscn',`scn',`ELF_F_DIRTY') + + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/Makefile new file mode 100644 index 0000000000..a5d6161734 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= shdr.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/shdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/shdr.m4 new file mode 100644 index 0000000000..e0d8958869 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_flagshdr/shdr.m4 @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: shdr.m4 223 2008-08-10 15:40:06Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +include(`elf_flag.m4') + +/* + * Tests for elf_flagdata(). + */ + +IC_REQUIRES_VERSION_INIT(); + +TP_FLAG_NULL(`elf_flagshdr') + +/* Boilerplate for getting hold of a valid Elf_Scn pointer */ +define(`_TP_DECLARATIONS',` + int fd; + Elf *e; + Elf32_Ehdr *eh; + Elf_Scn *scn;') +define(`_TP_PROLOGUE',` + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd); + + if ((eh = elf32_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf_newehdr() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + }') +define(`_TP_EPILOGUE',` + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE);') + +TP_FLAG_ILLEGAL_CMD(`elf_flagshdr',`scn') + +TP_FLAG_CLR(`elf_flagshdr',`scn') +TP_FLAG_SET(`elf_flagshdr',`scn') + +TP_FLAG_ILLEGAL_FLAG(`elf_flagshdr',`scn',`ELF_F_DIRTY') + + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/Makefile new file mode 100644 index 0000000000..b0f82ed933 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= fsize.m4 +TS_DATA= fsize.msb32 fsize.msb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/fsize.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/fsize.m4 new file mode 100644 index 0000000000..4a43e4d442 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_fsize/fsize.m4 @@ -0,0 +1,273 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: fsize.m4 1722 2011-08-13 05:34:38Z jkoshy $ + */ + +include(`elfts.m4') + +#include + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +/* + * Test the `elf[32,64]_fsize' and `gelf_fsize' entry points. + */ + +void +tcArgumentGelfNull(void) +{ + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_fsize(NULL,...) fails with error ELF_E_ARGUMENT."); + + if (gelf_fsize(NULL, ELF_T_ADDR, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + +void +tcArgumentBadVersion(void) +{ + Elf *e; + int bad_version, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("using an unsupported version number fails with " + "ELF_E_VERSION."); + + TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd); + + bad_version = EV_CURRENT+1; + + result = TET_PASS; + + if (elf32_fsize(ELF_T_ADDR, 1, bad_version) != 0 || + elf_errno() != ELF_E_VERSION) + result = TET_FAIL; + else if (elf64_fsize(ELF_T_ADDR, 1, bad_version) != 0 || + elf_errno() != ELF_E_VERSION) + result = TET_FAIL; + else if (gelf_fsize(e, ELF_T_ADDR, 1, bad_version) != 0 || + elf_errno() != ELF_E_VERSION) + result = TET_FAIL; + + tet_result(result); + + (void) elf_end(e); + (void) close(fd); +} + +void +tcArgumentBadTypeTooSmall(void) +{ + Elf *e; + int fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("a type parameter less than 0 fails with " + "ELF_E_ARGUMENT."); + + TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd); + + result = TET_PASS; + if (elf32_fsize(-1, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (elf64_fsize(-1, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (gelf_fsize(e, -1, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + tet_result(result); + (void) elf_end(e); + (void) close(fd); +} + +void +tcArgumentBadTypeTooLarge(void) +{ + Elf *e; + int fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("a type parameter >= ELF_T_NUM is fails with " + "ELF_E_ARGUMENT."); + + TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd); + + result = TET_PASS; + if (elf32_fsize(ELF_T_NUM, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (elf64_fsize(ELF_T_NUM, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (gelf_fsize(e, ELF_T_NUM, 1, EV_CURRENT) != 0 || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + tet_result(result); + (void) elf_end(e); + (void) close(fd); +} + +static size_t sizes32[ELF_T_NUM] = { +#define DEFINE_SIZE(N,SZ) [ELF_T_##N] = (SZ) + DEFINE_SIZE(ADDR, 4), + DEFINE_SIZE(BYTE, 1), + DEFINE_SIZE(CAP, 8), + DEFINE_SIZE(DYN, 4+4), + DEFINE_SIZE(EHDR, 16+2+2+4+4+4+4+4+2+2+2+2+2+2), + DEFINE_SIZE(HALF, 2), + DEFINE_SIZE(LWORD, 8), + DEFINE_SIZE(MOVE, 20), + DEFINE_SIZE(MOVEP, 0), + DEFINE_SIZE(NOTE, 1), + DEFINE_SIZE(OFF, 4), + DEFINE_SIZE(PHDR, 4+4+4+4+4+4+4+4), + DEFINE_SIZE(REL, 4+4), + DEFINE_SIZE(RELA, 4+4+4), + DEFINE_SIZE(SHDR, 4+4+4+4+4+4+4+4+4+4), + DEFINE_SIZE(SWORD, 4), + DEFINE_SIZE(SXWORD, 0), + DEFINE_SIZE(SYM, 4+4+4+1+1+2), + DEFINE_SIZE(SYMINFO, 4), + DEFINE_SIZE(VDEF, 1), + DEFINE_SIZE(VNEED, 1), + DEFINE_SIZE(WORD, 4), + DEFINE_SIZE(XWORD, 0), + DEFINE_SIZE(GNUHASH, 1) +#undef DEFINE_SIZE +}; + +void +tcSizesSize32(void) +{ + Elf *e; + int fd, i; + size_t size; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("check 32 bit sizes of ELF types"); + + TS_OPEN_FILE(e,"fsize.msb32",ELF_C_READ,fd); + + for (i = ELF_T_ADDR; i < ELF_T_NUM; i++) { + if ((size = elf32_fsize(i, 1, EV_CURRENT)) != sizes32[i]) { + tet_printf("fail: elf32_fsize(%d): %d != %d", + i, size, sizes32[i]); + tet_result(TET_FAIL); + return; + } + if ((size = gelf_fsize(e, i, 1, EV_CURRENT)) != sizes32[i]) { + tet_printf("fail: gelf_fsize(%d): %d != %d", + i, size, sizes32[i]); + tet_result(TET_FAIL); + return; + } + } + tet_result(TET_PASS); + (void) elf_end(e); + (void) close(fd); +} + +static size_t sizes64[ELF_T_NUM] = { +#define DEFINE_SIZE(N,SZ) [ELF_T_##N] = (SZ) + DEFINE_SIZE(ADDR, 8), + DEFINE_SIZE(BYTE, 1), + DEFINE_SIZE(CAP, 16), + DEFINE_SIZE(DYN, 8+8), + DEFINE_SIZE(EHDR, 16+2+2+4+8+8+8+4+2+2+2+2+2+2), + DEFINE_SIZE(HALF, 2), + DEFINE_SIZE(LWORD, 8), + DEFINE_SIZE(MOVE, 28), + DEFINE_SIZE(MOVEP, 0), + DEFINE_SIZE(NOTE, 1), + DEFINE_SIZE(OFF, 8), + DEFINE_SIZE(PHDR, 4+4+8+8+8+8+8+8), + DEFINE_SIZE(REL, 8+8), + DEFINE_SIZE(RELA, 8+8+8), + DEFINE_SIZE(SHDR, 4+4+8+8+8+8+4+4+8+8), + DEFINE_SIZE(SWORD, 4), + DEFINE_SIZE(SXWORD, 8), + DEFINE_SIZE(SYM, 4+1+1+2+8+8), + DEFINE_SIZE(SYMINFO, 4), + DEFINE_SIZE(VDEF, 1), + DEFINE_SIZE(VNEED, 1), + DEFINE_SIZE(WORD, 4), + DEFINE_SIZE(XWORD, 8), + DEFINE_SIZE(GNUHASH, 1) +#undef DEFINE_SIZE +}; + +void +tcSizesSize64(void) +{ + Elf *e; + int fd, i; + size_t size; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("check 64 bit sizes of ELF types"); + + TS_OPEN_FILE(e,"fsize.msb64",ELF_C_READ,fd); + + for (i = ELF_T_ADDR; i < ELF_T_NUM; i++) { + if ((size = elf64_fsize(i, 1, EV_CURRENT)) != sizes64[i]) { + tet_printf("fail: elf64_fsize(%d): %d != %d", + i, size, sizes64[i]); + tet_result(TET_FAIL); + return; + } + if ((size = gelf_fsize(e, i, 1, EV_CURRENT)) != sizes64[i]) { + tet_printf("fail: gelf_fsize(%d): %d != %d", + i, size, sizes64[i]); + tet_result(TET_FAIL); + return; + } + } + tet_result(TET_PASS); + (void) elf_end(e); + (void) close(fd); + +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/Makefile new file mode 100644 index 0000000000..9b91801311 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/Makefile @@ -0,0 +1,29 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getarhdr.m4 + +# These names must match those in the test case code. +TS_DATA= a.ar a-bsd.ar a1.o a2.o +TS_LONGNAME= "s------------------------2" +CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3" + +a1.c: .SILENT + echo "int a1;" > ${.TARGET} +a2.c: .SILENT + echo "int a2;" > ${.TARGET} + +a.ar: a1.o a2.o .SILENT + rm -f ${.TARGET} + echo 'This is s1.' > s1 + echo 's2.' > ${TS_LONGNAME} + echo 's-3.' > "s 3" + ${AR} crvU ${.TARGET} s1 a1.o ${TS_LONGNAME} a2.o "s 3" > /dev/null + +a-bsd.ar: a.ar .SILENT + rm -f ${.TARGET} + ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} s1 a1.o ${TS_LONGNAME} \ + a2.o "s 3" > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/getarhdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/getarhdr.m4 new file mode 100644 index 0000000000..a6af5313a4 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarhdr/getarhdr.m4 @@ -0,0 +1,471 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getarhdr.m4 3622 2018-09-29 07:44:28Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') +/* + * The following defines should match that in `./Makefile'. + */ +define(`TP_ELFFILE',`"a1.o"') +define(`TP_ARFILE_SVR4', `"a.ar"') +define(`TP_ARFILE_BSD', `"a-bsd.ar"') + +/* + * A NULL `Elf' argument fails. + */ +void +tcArgsNull(void) +{ + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr(NULL) fails."); + + result = TET_PASS; + if (elf_getarhdr(NULL) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + result = TET_FAIL; + } + + tet_result(result); +} + +/* + * elf_getarhdr() on a non-Ar file fails. + */ +static char *nonar = "This is not an AR file."; + +void +tcArgsNonAr(void) +{ + Elf *e; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr(non-ar) fails."); + + TS_OPEN_MEMORY(e, nonar); + + result = TET_PASS; + + if (elf_getarhdr(e) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + result = TET_FAIL; + } + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_getarhdr() on a top-level ELF file fails. + */ + +void +tcArgsElf(void) +{ + Elf *e; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr(elf) fails."); + + TS_OPEN_FILE(e, TP_ELFFILE, ELF_C_READ, fd); + + result = TET_PASS; + + if (elf_getarhdr(e) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + result = TET_FAIL; + } + + (void) elf_end(e); + + tet_result(result); +} + + + +/* + * elf_getarhdr() on ar archive members succeed. + */ + +/* This list of files must match the order of the files in test archive. */ +static char *rfn[] = { + "s1", + "a1.o", + "s------------------------2", /* long file name */ + "a2.o", + "s 3" /* file name with blanks */ +}; + +#define RAWNAME_SIZE 16 /* See */ + +struct arnames { + char *name; + char rawname[RAWNAME_SIZE]; +}; + +/* These lists of names and raw names must match those in the test archives. */ +static struct arnames rn_BSD[] = { + { + .name = "__.SYMDEF", /* Symbol table. */ + .rawname = { '_', '_', '.', 'S', 'Y', 'M', 'D', 'E', + 'F', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "s1", /* Ordinary, non object member (short name). */ + .rawname = { 's', '1', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "a1.o", /* Ordinary, object file (short name). */ + .rawname = { 'a', '1', '.', 'o', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "s------------------------2", /* Long file name. */ + .rawname = { '#', '1', '/', '2', '6', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "a2.o", /* Ordinary, object file (short name). */ + .rawname = { 'a', '2', '.', 'o', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + + }, + { + .name = "s 3", /* file name with blanks */ + .rawname = { '#', '1', '/', '3', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + } +}; + +static struct arnames rn_SVR4[] = { + { + .name = "/", + .rawname = { '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "//", + .rawname = { '/', '/', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "s1", + .rawname = { 's', '1', '/', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "a1.o", + .rawname = { 'a', '1', '.', 'o', '/', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "s------------------------2", /* long file name */ + .rawname = { '/', '0', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + }, + { + .name = "a2.o", + .rawname = { 'a', '2', '.', 'o', '/', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + + }, + { + .name = "s 3", /* file name with blanks */ + .rawname = { 's', ' ', '3', '/', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } + } +}; + +define(`ARCHIVE_TESTS',` +/* + * elf_getarhdr() on an ar archive (not a member) fails. + */ + +void +tcArArchive$1(void) +{ + Elf *e; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr(ar-descriptor)/$1 fails."); + + TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd); + + result = TET_PASS; + + if (elf_getarhdr(e) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + } + + (void) elf_end(e); + + tet_result(result); +} + +void +tcArMember$1(void) +{ + Elf_Arhdr *arh; + Elf *ar_e, *e; + Elf_Cmd c; + int error, fd, result; + char **fn; + struct stat sb; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr()/$1 succeeds for all members of an archive."); + + ar_e = e = NULL; + c = ELF_C_READ; + + TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd); + + result = TET_FAIL; + + fn = rfn; + while ((e = elf_begin(fd, c, ar_e)) != NULL) { + + if ((arh = elf_getarhdr(e)) == NULL) { + TP_FAIL("elf_getarhdr(\"%s\") failed: \"%s\".", *fn, + elf_errmsg(-1)); + goto done; + } + + if (stat(*fn, &sb) < 0) { + TP_UNRESOLVED("stat \"%s\" failed: %s.", *fn, + strerror(errno)); + goto done; + } + + if (strcmp(arh->ar_name, *fn) != 0) { + TP_FAIL("name: \"%s\" != \"%s\".", *fn, + arh->ar_name); + goto done; + } + + if (arh->ar_mode != sb.st_mode) { + TP_FAIL("\"%s\" mode: 0%o != 0%o.", *fn, + arh->ar_mode, sb.st_mode); + goto done; + } + + if (arh->ar_size != sb.st_size) { + TP_FAIL("\"%s\" size: %d != %d.", *fn, + arh->ar_size, sb.st_size); + goto done; + } + + if (arh->ar_uid != sb.st_uid) { + TP_FAIL("\"%s\" uid: %d != %d.", *fn, + arh->ar_uid, sb.st_uid); + goto done; + } + + if (arh->ar_gid != sb.st_gid) { + TP_FAIL("\"%s\" gid: %d != %d.", *fn, + arh->ar_gid, sb.st_gid); + goto done; + } + + c = elf_next(e); + (void) elf_end(e); e = NULL; + fn++; + } + + if ((error = elf_errno()) != ELF_E_NONE) { + TP_UNRESOLVED("elf_begin() failed: \"%s\".", elf_errmsg(error)); + result = TET_UNRESOLVED; + } else + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (ar_e) + (void) elf_end(ar_e); + + tet_result(result); + +} + +undefine(`CHECK_SPECIAL')dnl +undefine(`CHECK_NAMES')dnl +define(`CHECK_SPECIAL',` + if ((e = elf_begin(fd, c, ar_e)) == NULL) { + TP_FAIL("elf_begin($1) failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + CHECK_NAMES(); +') + +define(`CHECK_NAMES',` + if ((arh = elf_getarhdr(e)) == NULL) { + TP_FAIL("elf_getarhdr(\"%s\") failed: \"%s\".", fn->name, + elf_errmsg(-1)); + goto done; + } + + if (strcmp(arh->ar_name, fn->name) != 0) { + TP_FAIL("name: \"%s\" != \"%s\".", fn->name, + arh->ar_name); + goto done; + } + + + if (memcmp(arh->ar_rawname, fn->rawname, RAWNAME_SIZE) != 0) { + TP_FAIL("rawname: \"%s\" != \"%s\".", fn->rawname, + arh->ar_rawname); + goto done; + } +') + +void +tcArSpecial$1(void) +{ + + Elf_Arhdr *arh; + Elf *ar_e, *e; + Elf_Cmd c; + int fd, result; + struct arnames *fn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr() after an elf_rand(SARMAG) retrieves special members."); + + ar_e = e = NULL; + c = ELF_C_READ; + fn = rn_$1; + + TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd); + + result = TET_PASS; + + if (elf_rand(ar_e, (off_t) SARMAG) != (off_t)SARMAG) { + TP_UNRESOLVED("elf_rand(SARMAG) failed: \"%s\".", elf_errmsg(-1)); + goto done; + + } + + ifelse($1,`SVR4',`dnl # SVR4 + CHECK_SPECIAL(`/'); + CHECK_SPECIAL(`//');',`dnl # BSD + CHECK_SPECIAL(`__.SYMDEF');') + + done: + if (e) + (void) elf_end(e); + if (ar_e) + (void) elf_end(ar_e); + + tet_result(result); +} + +void +tcArRawnames$1(void) +{ + Elf_Arhdr *arh; + Elf *ar_e, *e; + Elf_Cmd c; + int fd, result; + struct arnames *fn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr() returns the correct rawnames."); + + ar_e = e = NULL; + c = ELF_C_READ; + fn = rn_$1; + + TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd); + + result = TET_PASS; + + if (elf_rand(ar_e, (off_t) SARMAG) != (off_t)SARMAG) { + TP_UNRESOLVED("elf_rand(SARMAG) failed: \"%s\".", elf_errmsg(-1)); + goto done; + + } + + ifelse($1,`SVR4',`dnl # SVR4 + CHECK_SPECIAL(`/'); + CHECK_SPECIAL(`//');',`dnl # BSD + CHECK_SPECIAL(`__.SYMDEF');') + + /* Check the rest of the archive members. */ + + while ((e = elf_begin(fd, c, ar_e)) != NULL) { + CHECK_NAMES(); + + c = elf_next(e); + (void) elf_end(e); e = NULL; + fn ++; + } + + done: + if (e) + (void) elf_end(e); + if (ar_e) + (void) elf_end(ar_e); + + tet_result(result); +} +') + +ARCHIVE_TESTS(`SVR4') +ARCHIVE_TESTS(`BSD') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/Makefile new file mode 100644 index 0000000000..6805cf8287 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/Makefile @@ -0,0 +1,40 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getarsym.m4 + +# These names must match those in the test case code. +TS_DATA= a.ar a-bsd.ar a2.ar a2-bsd.ar a1.o a2.o +TS_LONGNAME= "s------------------------2" +CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3" + +a1.c: .SILENT + echo "int a1;" > ${.TARGET} +a2.c: .SILENT + echo "int a2;" > ${.TARGET} + +s1: .SILENT + echo 'This is s1.' > ${.TARGET} +${TS_LONGNAME}: .SILENT + echo 's2.' > ${.TARGET} + +a.ar: a1.o a2.o ${TS_LONGNAME} s1 .SILENT + rm -f ${.TARGET} + echo 's-3.' > "s 3" + ${AR} crv ${.TARGET} s1 a1.o ${TS_LONGNAME} a2.o "s 3" > /dev/null + +a2.ar: s1 ${TS_LONGNAME} .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null + +a-bsd.ar: a.ar .SILENT + rm -f ${.TARGET} + ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} s1 a1.o ${TS_LONGNAME} \ + a2.o "s 3" > /dev/null + +a2-bsd.ar: a2.ar .SILENT + rm -f ${.TARGET} + ${ELFTOOLCHAIN_AR} -F bsd -crv ${.TARGET} ${.ALLSRC} > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/getarsym.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/getarsym.m4 new file mode 100644 index 0000000000..8b8d4a1a2b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getarsym/getarsym.m4 @@ -0,0 +1,363 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getarsym.m4 1407 2011-02-05 08:31:07Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') +/* + * The following defines should match that in `./Makefile'. + */ +define(`TP_ELFFILE',`"a1.o"') +define(`TP_ARFILE_BSD', `"a-bsd.ar"') +define(`TP_ARFILE_NOSYMTAB_BSD',`"a2-bsd.ar"') +define(`TP_ARFILE_SVR4', `"a.ar"') +define(`TP_ARFILE_NOSYMTAB_SVR4',`"a2.ar"') +define(`TP_NSYMBOLS',`3') + +/* + * A NULL `Elf' argument fails. + */ +void +tcArgsNull(void) +{ + int error, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarhdr(NULL) fails."); + + result = TET_PASS; + n = ~(size_t) 0; + if (elf_getarsym(NULL, &n) != NULL || + (n != (size_t) 0) || (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_getarsym() on a non-Ar file fails. + */ +static char *nonar = "This is not an AR file."; + +void +tcArgsNonAr(void) +{ + Elf *e; + int error, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarsym(non-ar) fails."); + + TS_OPEN_MEMORY(e, nonar); + + result = TET_PASS; + + n = ~ (size_t) 0; + if (elf_getarsym(e, &n) != NULL || (n != (size_t) 0) || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_getarsym() on a top-level ELF file fails. + */ + +void +tcArgsElf(void) +{ + Elf *e; + int error, fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarsym(elf) fails."); + + TS_OPEN_FILE(e, TP_ELFFILE, ELF_C_READ, fd); + + result = TET_PASS; + + n = ~ (size_t) 0; + if (elf_getarsym(e, &n) != NULL || (n != (size_t) 0) || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + +/* This list of symbols must match the order of the files in test archive. */ +struct refsym { + char *as_name; + unsigned long as_hash; + char *as_object; + int as_found; +}; + +struct refsym refsym[] = { + { .as_name = "a1", .as_hash = 0x641, .as_object = "a1.o" }, + { .as_name = "a2", .as_hash = 0x642, .as_object = "a2.o" }, + { .as_name = NULL } +}; + + +define(`ARCHIVE_TESTS',` +/* + * elf_getarsym() on an ar archive succeeds. + */ + +void +tcArAr$1(void) +{ + Elf *e; + Elf_Arsym *arsym; + int fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarsym(ar-descriptor)/$1 succeeds."); + + TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd); + + result = TET_PASS; + n = ~ (size_t) 0; + if ((arsym = elf_getarsym(e, &n)) == NULL || + n != TP_NSYMBOLS) + TP_FAIL("error=\"%s\".", elf_errmsg(-1)); + + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +} + +/* + * Two elf_getarsym invocations return the same value. + */ + +void +tcArDup$1(void) +{ + Elf *e; + Elf_Arsym *arsym, *t; + int fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("duplicate elf_getarsym()/$1 calls return the " + "same value."); + + TS_OPEN_FILE(e, TP_ARFILE_$1, ELF_C_READ, fd); + + result = TET_PASS; + n = ~ (size_t) 0; + if ((arsym = elf_getarsym(e, &n)) == NULL || + n != TP_NSYMBOLS) { + TP_FAIL("error=\"%s\".", elf_errmsg(-1)); + goto done; + } + + if ((t = elf_getarsym(e, &n)) == NULL || + n != TP_NSYMBOLS) { + TP_FAIL("error=\"%s\".", elf_errmsg(-1)); + goto done; + } + + if (t != arsym) + TP_FAIL("return values differ."); + +done: + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +} + +/* + * elf_getarsym() on an ar archive without a symbol table fails. + */ + +void +tcArNoSymtab$1(void) +{ + Elf *e; + size_t n; + Elf_Arsym *arsym; + int fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarsym(ar-with-no-symtab)/$1 fails."); + + TS_OPEN_FILE(e, TP_ARFILE_NOSYMTAB_$1, ELF_C_READ, fd); + + result = TET_PASS; + n = ~ (size_t) 0; + if ((arsym = elf_getarsym(e, &n)) != NULL || + n != 0) + TP_FAIL("arsym=%p n=%d.", (void *) arsym, n); + + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +} + +/* + * elf_getarsym() on ar archive members succeed. + */ + +void +tcArArSym$1(void) +{ + Elf_Arhdr *arh; + Elf *ar_e, *e; + Elf_Arsym *arsym; + off_t offset; + int c, fd, result; + struct refsym *r; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getarsym()/$1 returns a correct list of symbols."); + + ar_e = e = NULL; + c = ELF_C_READ; + fd = -1; + + TS_OPEN_FILE(ar_e, TP_ARFILE_$1, c, fd); + + result = TET_PASS; + + if ((arsym = elf_getarsym(ar_e, &n)) == NULL || + (n != TP_NSYMBOLS)) { + TP_FAIL("elf_getarsym() failed: n=%d error=\"%s\".", n, + elf_errmsg(-1)); + goto done; + } + + for (; arsym->as_name; arsym++) { + + /* Lookup this symbol in the reference table */ + c = 0; + for (r = refsym; r->as_name; r++) { + if (strcmp(r->as_name, arsym->as_name) == 0 && + r->as_hash == arsym->as_hash) { + r->as_found = c = 1; + break; + } + } + + if (c == 0) { + TP_FAIL("extra symbol \"%s\".", arsym->as_name); + goto done; + } + + if ((offset = elf_rand(ar_e, arsym->as_off)) != arsym->as_off) { + TP_FAIL("elf_rand(%jd) failed: \"%s\".", + (intmax_t) arsym->as_off, elf_errmsg(-1)); + goto done; + } + + if ((e = elf_begin(fd, ELF_C_READ, ar_e)) == NULL) { + TP_UNRESOLVED("elf_begin() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((arh = elf_getarhdr(e)) == NULL) { + TP_UNRESOLVED("elf_getarhdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (strcmp(arh->ar_name, r->as_object) != 0) { + TP_FAIL("object-name \"%s\" != ref \"%s\".", + arh->ar_name, r->as_name); + goto done; + } + + (void) elf_end (e); + e = NULL; + } + + /* Check the last entry */ + if (arsym->as_name != NULL || arsym->as_hash != ~0UL || + arsym->as_off != (off_t) 0) { + TP_FAIL("last entry mangled."); + goto done; + } + + /* Check that all names have been retrieved. */ + for (r = refsym; r->as_name; r++) { + if (r->as_found == 0) { + TP_FAIL("symbol \"%s\" was not present.", r->as_name); + break; + } + } + + done: + if (e) + (void) elf_end(e); + if (ar_e) + (void) elf_end(ar_e); + if (fd != -1) + (void) close(fd); + + tet_result(result); + +} +') + +ARCHIVE_TESTS(`SVR4') +ARCHIVE_TESTS(`BSD') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/Makefile new file mode 100644 index 0000000000..3816372fa4 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getbase.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/getbase.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/getbase.m4 new file mode 100644 index 0000000000..3a9c0e85bd --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getbase/getbase.m4 @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getbase.m4 1694 2011-08-02 04:34:35Z jkoshy $ + */ + +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * Test the `elf_getbase' entry point. + */ + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +void +tcNonMemberElf(void) +{ + int result; + off_t off; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getbase() on an ELF file returns 0"); + + TS_OPEN_MEMORY(e, elf_file); + + result = TET_PASS; + if ((off = elf_getbase(e)) != (off_t) 0) + result = TET_FAIL; + + tet_result(result); + (void) elf_end(e); +} + +changequote({,}) +static char ar_file[] = "!\n" + "t/ 1151656346 1001 0 100644 5 `\n" + "Test\n"; +changequote + +void +tcNonMemberAr(void) +{ + int result; + off_t off; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getbase on an AR file returns 0"); + + TS_OPEN_MEMORY(e, ar_file); + + result = TET_PASS; + + if ((off = elf_getbase(e)) != (off_t) 0) + result = TET_FAIL; + + tet_result(result); + (void) elf_end(e); +} + +/* + * Todo: + * - test an ar archive with an embedded ELF file. + * - test an ar archive with an embedded non-elf file. + */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/Makefile new file mode 100644 index 0000000000..0f4befc567 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getdata.m4 +TS_YAML= zerosection + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/getdata.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/getdata.m4 new file mode 100644 index 0000000000..332f81bceb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getdata/getdata.m4 @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getdata.m4 3695 2019-02-25 18:55:07Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * Find an ELF section with the given name. + */ +static Elf_Scn * +findscn(Elf *e, const char *name) +{ + size_t shstrndx; + const char *scn_name; + Elf_Scn *scn; + GElf_Shdr shdr; + + /* Locate the string table. */ + if (elf_getshdrstrndx(e, &shstrndx) != 0) + return (NULL); + + /* Find a section with a matching name. */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) == NULL) + return (NULL); + if ((scn_name = elf_strptr(e, shstrndx, + (size_t) shdr.sh_name)) == NULL) + return (NULL); + if (strcmp(scn_name, name) == 0) + return (scn); + } + + return (NULL); +} + +/* + * Check the contents of an Elf_Data descriptor. + * + * The return value from this helper is as follows: + * + * 0 - the descriptor matched the specified content. + * -1 - the descriptor size had a mismatch. + * >0 - the content of the descriptor did not match. The returned value + * is the index of the first byte that differs. + */ +static int +match_content(Elf_Data *ed, size_t nbytes, const char *content) +{ + int n; + const char *buf; + + if (ed->d_size != nbytes) + return (-1); + + buf = (const char *) ed->d_buf; + for (n = 0; n < nbytes; n++) { + if (*buf != *content) + return (n); + buf++; + content++; + } + + return (0); +} + +define(`ZEROSECTION',".zerosection") +undefine(`FN') +define(`FN',` +void +tcZeroSection$1$2(void) +{ + Elf *e; + int error, fd, result; + Elf_Scn *scn; + Elf_Data *ed; + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("a data descriptor for a zero sized section is correctly retrieved"); + + _TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;); + + if ((scn = findscn(e, ZEROSECTION)) == NULL) { + TP_UNRESOLVED("Cannot find section \""ZEROSECTION"\""); + goto done; + } + + ed = NULL; + if ((ed = elf_getdata(scn, ed)) == NULL) { + error = elf_errno(); + TP_FAIL("elf_getdata failed %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + if (ed->d_size != 0 || ed->d_buf != NULL) { + TP_FAIL("Illegal values returned: size %d buf %p", + (int) ed->d_size, (void *) ed->d_buf); + goto done; + } + + if ((ed = elf_getdata(scn, ed)) != NULL) { + TP_FAIL("Extra data descriptor in section."); + goto done; + } + + result = TET_PASS; + +done: + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} +') + +FN(lsb,32) +FN(lsb,64) +FN(msb,32) +FN(msb,64) + +/* + * Verify that a non-zero section is correctly read. + */ + +static const char stringsection[] = { +changequote({,}) + '\0', + '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0', + '.', 'z', 'e', 'r', 'o', 's', 'e', 'c', 't', 'i', 'o', 'n', '\0' +changequote + }; + +undefine(`_FN') +define(`_FN',` +void +tcNonZeroSection$1$2(void) +{ + int error, fd, result; + int match_error; + size_t shstrndx; + const char *buf; + Elf_Scn *scn; + Elf_Data *ed; + Elf *e; + + fd = -1; + e = NULL; + scn = NULL; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("a data descriptor for a non-zero sized section " + "is correctly retrieved"); + + _TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;); + + if (elf_getshdrstrndx(e, &shstrndx) != 0 || + (scn = elf_getscn(e, shstrndx)) == NULL) { + TP_UNRESOLVED("Cannot find string table section"); + goto done; + } + + ed = NULL; + if ((ed = elf_getdata(scn, ed)) == NULL) { + error = elf_errno(); + TP_FAIL("elf_getdata failed %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + match_error = match_content(ed, sizeof(stringsection), + stringsection); + if (match_error == -1) { + TP_FAIL("Illegal values returned: d_size %d != expected %d", + (int) ed->d_size, sizeof(stringsection)); + goto done; + } else if (match_error > 0) { + buf = (const char *) ed->d_buf; + TP_FAIL("String mismatch: buf[%d] \"%c\" != \"%c\"", + match_error, buf[match_error], + stringsection[match_error]); + goto done; + } + + if ((ed = elf_getdata(scn, ed)) != NULL) { + TP_FAIL("Extra data descriptor in section."); + goto done; + } + + result = TET_PASS; + +done: + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} +') + +_FN(lsb,32) +_FN(lsb,64) +_FN(msb,32) +_FN(msb,64) + +static const char new_content[] = { +changequote({,}) + 'n', 'e', 'w', ' ', 'c', 'o', 'n', 't', 'e', 'n', 't', '\0' +changequote +}; + +/* + * Verify that a section with multiple Elf_Data segments is handled correctly. + */ +undefine(`_FN') +define(`_FN',` +void +tcDataTraversal$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *ed; + size_t shstrndx; + int error, fd, match_error, result; + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("multiple Elf_Data segments can be traversed."); + _TS_OPEN_FILE(e, "zerosection.$1$2", ELF_C_READ, fd, goto done;); + + if (elf_getshdrstrndx(e, &shstrndx) != 0 || + (scn = elf_getscn(e, shstrndx)) == NULL) { + TP_UNRESOLVED("Cannot find the string table"); + goto done; + } + + /* + * Add new data to the string section. + */ + if ((ed = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("Cannot allocate new data."); + goto done; + } + + ed->d_buf = (char *) new_content; + ed->d_size = sizeof(new_content); + + /* + * Rescan the descriptor list for the section. + */ + ed = NULL; + if ((ed = elf_getdata(scn, ed)) == NULL) { + error = elf_errno(); + TP_FAIL("elf_getdata failed %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + match_error = match_content(ed, sizeof(stringsection), + stringsection); + if (match_error == -1) { + TP_FAIL("Unexpected size of first descriptor: " + "d_size %d != expected %d", (int) ed->d_size, + sizeof(stringsection)); + goto done; + } else if (match_error > 0) { + TP_FAIL("String content mismatch for data descriptor 1."); + goto done; + } + + if ((ed = elf_getdata(scn, ed)) == NULL) { + error = elf_errno(); + TP_FAIL("Missing second data section: %d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + match_error = match_content(ed, sizeof(new_content), + new_content); + if (match_error == -1) { + TP_FAIL("Unexpected size of second descriptor: " + "d_size %d != expected %d", (int) ed->d_size, + sizeof(new_content)); + goto done; + } else if (match_error > 0) { + TP_FAIL("String content mismatch for data descriptor 2."); + goto done; + } + + /* + * There should be no other Elf_Data descriptors. + */ + if ((ed = elf_getdata(scn, ed)) != NULL) { + TP_FAIL("Too many Elf_Data descriptors for section."); + goto done; + } + + result = TET_PASS; + +done: + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +_FN(lsb,32) +_FN(lsb,64) +_FN(msb,32) +_FN(msb,64) diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/Makefile new file mode 100644 index 0000000000..41dadebac7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getident.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/getident.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/getident.m4 new file mode 100644 index 0000000000..b2f9e9449e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getident/getident.m4 @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getident.m4 1694 2011-08-02 04:34:35Z jkoshy $ + */ + +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +void +tcNullNull(void) +{ + int result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getident(NULL,...) fails with error ELF_E_ARGUMENT."); + + result = TET_PASS; + if (elf_getident(NULL, NULL) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + tet_result(result); +} + +void +tcNullSize(void) +{ + size_t dummy; + int result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getident(NULL,&foo) fails, and sets" + " `foo' to zero."); + + dummy = (size_t) 0xdeadc0de; + + result = TET_PASS; + if (elf_getident(NULL, &dummy) != NULL || + elf_errno() != ELF_E_ARGUMENT || + dummy != 0) + result = TET_FAIL; + tet_result(result); + +} + +changequote({,}) +static char ar_file[] = "!\n" + "t/ 1151656346 1001 0 100644 5 `\n" + "Test\n"; +changequote + +void +tcMainArIdent(void) +{ + Elf *e; + char *p; + size_t sz; + int result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("an ar(1) archive's ident is correctly returned."); + + TS_OPEN_MEMORY(e, ar_file); + + result = TET_PASS; + sz = (size_t) 0xdeadc0de; + if ((p = elf_getident(e, &sz)) == NULL || + sz != SARMAG || strncmp(p, ARMAG, SARMAG)) + result = TET_FAIL; + tet_result(result); +} + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +void +tcMainElfIdent(void) +{ + Elf *e; + char *p; + size_t sz; + int result; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: an ELF object's ident is correctly" + " returned."); + + TS_OPEN_MEMORY(e, elf_file); + + result = TET_PASS; + sz = (size_t) 0xdeadc0de; + if ((p = elf_getident(e, &sz)) == NULL || + sz != EI_NIDENT || + memcmp(elf_file, p, sz)) + result = TET_FAIL; + tet_result(result); +} + + +static char unknown_data[] = "Revenge! Revenge!"; + +void +tcMainUnknownData(void) +{ + Elf *e; + char *p; + size_t sz; + int result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getident() returns the initial bytes of" + " an unknown data object."); + + TS_OPEN_MEMORY(e, unknown_data); + + result = TET_PASS; + sz = (size_t) 0xdeadc0de; + if ((p = elf_getident(e, &sz)) == NULL || + sz != sizeof(unknown_data) || + memcmp(p, unknown_data, sizeof(unknown_data))) + result = TET_FAIL; + tet_result(result); +} + +/* + * TODO: + * + * - getident on an elf descriptor opened for WRITE should fail until + * an elf_update() is done. + * + */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/Makefile new file mode 100644 index 0000000000..02c1681b90 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getscn.m4 +TS_YAML= newscn xscn-1 xscn-2 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/getscn.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/getscn.m4 new file mode 100644 index 0000000000..98b37e4792 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getscn/getscn.m4 @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getscn.m4 1405 2011-02-05 07:53:03Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * A NULL argument is handled correctly. + */ +void +tcArgsNull(void) +{ + int error, result; + Elf_Scn *scn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getscn(NULL,*) fails."); + + result = TET_PASS; + if ((scn = elf_getscn(NULL, (size_t) 0)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_getscn(non-elf) fails. + */ + +static char *nonelf = "This is not an ELF file."; + +void +tcArgsNonElf(void) +{ + Elf *e; + Elf_Scn *scn; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getscn(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + result = TET_PASS; + + if ((scn = elf_getscn(e, (size_t) 0)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_getscn works for all sections in a file. + */ + +undefine(`FN') +define(`FN',` +void +tcElfAll$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int error, fd, result; + size_t nsections, n, r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() can retrieve all sections."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &nsections) == 0) { + TP_UNRESOLVED("elf_getshnum() failed."); + goto done; + } + + result = TET_PASS; + + for (n = 0; n < nsections; n++) { + /* Retrieve the section ... */ + if ((scn = elf_getscn(e, n)) == NULL) { + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + break; + } + + /* ... and verify that the section has the correct index. */ + if ((r = elf_ndxscn(scn)) != n) { + TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n); + break; + } + } + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_getscn(e,nsections+1) returns NULL. + */ +undefine(`FN') +define(`FN',` +void +tcElfRange$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int error, fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn(elf,nsections+1) fails."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &n) == 0) { + TP_UNRESOLVED("elf_getshnum() failed."); + goto done; + } + + result = TET_PASS; + if ((scn = elf_getscn(e, n)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=\"%s\".", (void *) scn, + elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_getscn(e,*) fails with ELF_E_SECTION on malformed extended numbering. + */ +undefine(`FN') +define(`FN',` +void +tcExSecNumError$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() fails on a malformed file."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "xscn-1.$2$1", ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if ((scn = elf_getscn(e, 0)) != NULL || + (error = elf_errno()) != ELF_E_SECTION) + TP_FAIL("scn=%p, error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_getscn works correctly for a file with > SHN_XINDEX sections. + */ + +undefine(`FN') +define(`FN',` +void +tcExSecNumLast$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + Elf$1_Shdr *sh; + int error, fd, result; + size_t n, r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getscn() retrieves the last extended " + "section."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "xscn-2.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &n) == 0) { + TP_UNRESOLVED("elf_getshnum() failed."); + goto done; + } + + result = TET_PASS; + + n--; + + /* Retrieve the section ... */ + if ((scn = elf_getscn(e, n)) == NULL) { + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + goto done; + } + + /* ... and verify that the section has the correct index. */ + if ((r = elf_ndxscn(scn)) != n) { + TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n); + goto done; + } + + /* ... and check the type of the section too. */ + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (sh->sh_type != SHT_STRTAB) + TP_FAIL("section[%d] has wrong type %d.", n, sh->sh_type); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/Makefile new file mode 100644 index 0000000000..5220f0c880 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getshnum.m4 +TS_YAML= newscn xscn-1 xscn-2 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/getshnum.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/getshnum.m4 new file mode 100644 index 0000000000..29e1e290bf --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshnum/getshnum.m4 @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getshnum.m4 1416 2011-02-05 12:46:59Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * A NULL `Elf' argument fails. + */ +void +tcArgsNull(void) +{ + int error, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getshnum(NULL,*) fails."); + + result = TET_PASS; + if (elf_getshnum(NULL, &n) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("n=%d error=%d \"%s\".", n, error, + elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_getshnum() on a non-ELF file fails. + */ +static char *nonelf = "This is not an ELF file."; + +void +tcArgsNonElf(void) +{ + Elf *e; + size_t n; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getshnum(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + result = TET_PASS; + if (elf_getshnum(e, &n) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("n=%d error=%d \"%s\".", n, error, + elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + + +/* + * elf_getshnum() on a well-formed file succeeds. + */ +undefine(`FN') +define(`FN',` +void +tcNormal$1$3`'TOUPPER($4)(void) +{ + Elf *e; + int fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($4)$1$3: elf_getshnum(elf) succeeds."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "$2.$4$3", ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if (elf_getshnum(e, &n) == 0 || n != $5) + TP_FAIL("n=%d, expected $5: error=\"%s\".", n, + elf_errmsg(-1)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(N,newscn,32,lsb,3) +FN(N,newscn,32,msb,3) +FN(N,newscn,64,lsb,3) +FN(N,newscn,64,msb,3) +FN(X,`xscn-2',32,lsb,65538) +FN(X,`xscn-2',32,msb,65538) +FN(X,`xscn-2',64,lsb,65538) +FN(X,`xscn-2',64,msb,65538) + +/* + * elf_getshnum() on a file with a malformed section number 0 fails. + */ +undefine(`FN') +define(`FN',` +void +tcMalformedXscn$1$2(void) +{ + Elf *e; + int error, fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getshnum(elf) returns ELF_E_SECTION."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "xscn-1.$2$1", ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if ((elf_getshnum(e, &n) != 0 || + (error = elf_errno()) != ELF_E_SECTION)) + TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/Makefile new file mode 100644 index 0000000000..88449e4bd0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getshstrndx.m4 +TS_YAML= newscn xscn-1 xscn-2 xscn-3 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/getshstrndx.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/getshstrndx.m4 new file mode 100644 index 0000000000..6b2a40d32c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getshstrndx/getshstrndx.m4 @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getshstrndx.m4 1404 2011-02-05 07:51:28Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * A NULL `Elf' argument fails. + */ +void +tcArgsNull(void) +{ + int error, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getshstrndx(NULL,*) fails."); + + result = TET_PASS; + if (elf_getshstrndx(NULL, &n) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("n=%d error=%d \"%s\".", n, error, + elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_getshstrndx() on a non-ELF file fails. + */ +static char *nonelf = "This is not an ELF file."; + +void +tcArgsNonElf(void) +{ + Elf *e; + size_t n; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getshstrndx(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + result = TET_PASS; + if (elf_getshstrndx(e, &n) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("n=%d error=%d \"%s\".", n, error, + elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + + +/* + * elf_getshstrndx() on a well-formed file succeeds. + */ +undefine(`FN') +define(`FN',` +void +tcNormal_$1$3`'TOUPPER($4)(void) +{ + Elf *e; + int fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($4)$1$3: elf_getshstrndx(elf) succeeds."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "$2.$4$3", ELF_C_READ, fd, goto done;); + + n = ~ (size_t) 0; + + result = TET_PASS; + if (elf_getshstrndx(e, &n) == 0 || n != $5) + TP_FAIL("n=%d, expected $5: error=\"%s\".", n, + elf_errmsg(-1)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(N,newscn,32,lsb,1) +FN(N,newscn,32,msb,1) +FN(N,newscn,64,lsb,1) +FN(N,newscn,64,msb,1) +FN(X,`xscn-2',32,lsb,65537) +FN(X,`xscn-2',32,msb,65537) +FN(X,`xscn-2',64,lsb,65537) +FN(X,`xscn-2',64,msb,65537) + +/* + * elf_getshstrndx() on a file with a malformed section #0 fails. + */ +undefine(`FN') +define(`FN',` +void +tcMalformed_Xscn$1$2(void) +{ + Elf *e; + int error, fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_getshstrndx(elf) returns ELF_E_SECTION."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "xscn-3.$2$1", ELF_C_READ, fd, goto done;); + + n = ~(size_t) 0; + result = TET_PASS; + if ((elf_getshstrndx(e, &n) != 0 || + (error = elf_errno()) != ELF_E_SECTION)) + TP_FAIL("n=%d error=%d \"%s\".", n, error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/Makefile new file mode 100644 index 0000000000..0e4e1bb497 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/Makefile @@ -0,0 +1,16 @@ +# $Id$ + +TOP= ../../../../.. + +TS_SRCS= getversion.m4 +TS_DATA= check_elf.msb32 check_elf.lsb32 check_elf.msb64 \ + check_elf.lsb64 a.ar s1 + +s1: .SILENT + echo 'This is s1.' > ${.TARGET} + +a.ar: s1 .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} s1 > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/getversion.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/getversion.m4 new file mode 100644 index 0000000000..153c69ffd0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_getversion/getversion.m4 @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2021 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * elf_getversion() fails with a NULL argument. + */ +void +tcArgsNull(void) +{ + int error, result; + unsigned int version; + + error = 0; + result = TET_UNRESOLVED; + version = EV_CURRENT; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getversion(NULL) fails."); + + if ((version = elf_getversion(NULL)) != EV_NONE) + TP_FAIL("version=%d", version); + else if ((error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + else + result = TET_PASS; + + tet_result(result); +} + +/* + * elf_getversion() on a non-ELF object fails. + */ +static char *nonelf = "This is not an ELF object."; + +void +tcArgsNonElf(void) +{ + Elf *e; + int error, result; + unsigned int version; + + e = NULL; + error = 0; + version = EV_CURRENT; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getversion(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + if ((version = elf_getversion(e)) != EV_NONE) + TP_FAIL("version=%d", version); + else if ((error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + else + result = TET_PASS; + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_version() fails on ar(1) archives. + */ +void +tcArgsArArchive(void) +{ + Elf *e; + int error, fd, result; + unsigned int version; + + e = NULL; + error = 0; + fd = -1; + result = TET_UNRESOLVED; + version = EV_CURRENT; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getversion(ar-archive) fails."); + + _TS_OPEN_FILE(e, "a.ar", ELF_C_READ, fd, goto done;); + + if ((version = elf_getversion(e)) != EV_NONE) + TP_FAIL("version=%d expected EV_NONE", version); + else if ((error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("error=%d \"%s\"", error, elf_errmsg(error)); + else + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * elf_getversion() succeeds on well-formed ELF files. + */ +undefine(`FN') +define(`FN',` +void +tcNormal$1_$2(void) +{ + Elf *e; + int fd, result; + unsigned int version; + + fd = -1; + e = NULL; + result = TET_UNRESOLVED; + version = EV_NONE; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_getversion($2$1) succeeds."); + + _TS_OPEN_FILE(e, "check_elf.$2$1", ELF_C_READ, fd, goto done;); + + if ((version = elf_getversion(e)) != EV_CURRENT) + TP_FAIL("version=%d", version); + else + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/Makefile new file mode 100644 index 0000000000..882374a239 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= hash.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/hash.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/hash.m4 new file mode 100644 index 0000000000..5a64f1da2e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_hash/hash.m4 @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: hash.m4 2191 2011-11-21 08:34:02Z jkoshy $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +/* + * Test the `elf_hash' API. + */ + +/* + * A motley collection of test strings. + */ +static struct htab { + const char *s; + unsigned long h; +} htab[] = { +#undef H +#define H(S,V) { .s = (S), .h = (V) } + H("", 0), + H("\377\377\377\377", 0x10FFEfL), + H("\030\2265Q\023_;\312\214\212#f\001\220\224|", + 0xe07d55c), + H("elf-hash", 0x293ee58), + H(NULL, 0) +}; + +static void +to_printable_string(char *dst, const char *src) +{ + int c; + char *s; + + s = dst; + while (c = *src++) { + if (isprint(c)) + *s++ = c; + else + s += sprintf(s, "\\%3.3o", (c & 0xFF)); + } + *s = '\0'; +} + +void +tpCheckHash(void) +{ + unsigned long h; + struct htab *ht; + int result; + char *tmp; + + tet_infoline("assertion: check elf_hash() against several constant " + "strings."); + + result = TET_PASS; + for (ht = htab; ht->s; ht++) { + if ((h = elf_hash(ht->s)) != ht->h) { + if ((tmp = malloc(4 * strlen(ht->s) + 1)) != NULL) { + to_printable_string(tmp, ht->s); + tet_printf("fail: elf_hash(\"%s\") = 0x%x != " + "expected 0x%x.", tmp, h, ht->h); + free(tmp); + } + result = TET_FAIL; + } + } + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/Makefile new file mode 100644 index 0000000000..61c801a2d8 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= kind.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/kind.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/kind.m4 new file mode 100644 index 0000000000..ada6095ac3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_kind/kind.m4 @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: kind.m4 1694 2011-08-02 04:34:35Z jkoshy $ + */ + +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * Test the `elf_kind' entry point. + */ + +void +tcNullParameter(void) +{ + TP_ANNOUNCE("NULL elf returns null."); + + TP_CHECK_INITIALIZATION(); + + tet_result(elf_kind(NULL) == ELF_K_NONE ? TET_PASS : TET_FAIL); +} + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +void +tcValidElf(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("valid ELF file returns ELF_K_ELF."); + + if ((e = elf_memory(elf_file, sizeof(elf_file))) == NULL) { + tet_printf("elf_memory: %s", elf_errmsg(-1)); + tet_result(TET_UNRESOLVED); + return; + } + + tet_result(elf_kind(e) == ELF_K_ELF ? TET_PASS : TET_FAIL); + + (void) elf_end(e); +} + +changequote({,}) +static char ar_file[] = "!\n" + "t/ 1151656346 1001 0 100644 5 `\n" + "Test\n"; +changequote + +void +tcValidAr(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("valid ar archive returns ELF_K_AR."); + + if ((e = elf_memory(ar_file, sizeof(ar_file))) == NULL) { + tet_printf("elf_memory: %s", elf_errmsg(-1)); + tet_result(TET_UNRESOLVED); + return; + } + + tet_result(elf_kind(e) == ELF_K_AR ? TET_PASS : TET_FAIL); + + (void) elf_end(e); +} + +static char unknown_file[] = "0xdeadc0de"; + +void +tcUnknownKind(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("unknown file type returns ELF_K_NONE."); + + if ((e = elf_memory(unknown_file, sizeof(unknown_file))) == NULL) { + tet_printf("elf_memory: %s", elf_errmsg(-1)); + tet_result(TET_UNRESOLVED); + } + + tet_result(elf_kind(e) == ELF_K_NONE ? TET_PASS : TET_FAIL); + + (void) elf_end(e); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/Makefile new file mode 100644 index 0000000000..28b130e108 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= memory.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/memory.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/memory.m4 new file mode 100644 index 0000000000..da7ac7bc6d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_memory/memory.m4 @@ -0,0 +1,240 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: memory.m4 1694 2011-08-02 04:34:35Z jkoshy $ + */ + +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * Test the `elf_memory' entry point. + * + * See also: elf_memory() sequence tests in the test cases for elf_version(). + */ + +/* + * Check that a NULL memory pointer and a zero size arena size are + * rejected. + */ + +void +tcInvalidArgNullPtrs(void) +{ + Elf *e; + + TP_ANNOUNCE("elf_memory(NULL,0) results in a NULL return" + " and an error return of ELF_E_ARGUMENT."); + + TP_CHECK_INITIALIZATION(); + + if ((e = elf_memory(NULL, ~0)) != NULL || + elf_errno() != ELF_E_ARGUMENT) { + tet_result(TET_FAIL); + return; + } + + if ((e = elf_memory((char *) &e, 0)) != NULL || + elf_errno() != ELF_E_ARGUMENT) { + tet_result(TET_FAIL); + return; + } + + tet_result(TET_PASS); +} + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +/* + * The next two test cases check a pointer to valid ELF content, but + * with (a) a valid object size and (b) a too-small object size. + */ + +void +tcValidElfValidSize(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("valid ELF contents and size are correctly" + " recognized as an ELF file."); + + if ((e = elf_memory(elf_file, sizeof(elf_file))) == NULL || + elf_kind(e) != ELF_K_ELF) { + tet_result(TET_FAIL); + return; + } + + (void) elf_end(e); + tet_result(TET_PASS); +} + +void +tcValidElfInvalidSize(void) +{ + Elf *e; + + TP_ANNOUNCE("a valid ELF prelude with a too-small size is" + " to be recognized as 'DATA'."); + + TP_CHECK_INITIALIZATION(); + + /* Check size > SARMAG, but < EI_NIDENT */ + if ((e = elf_memory(elf_file, EI_NIDENT-1)) == NULL || + elf_kind(e) != ELF_K_NONE) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); +} + + +void +tcInvalidElfSignature(void) +{ + Elf *e; + char newelf[sizeof(elf_file)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("an ELF-like object with an invalid signature" + " should be recognized as 'DATA'."); + + memcpy(newelf, elf_file, sizeof(elf_file)); + newelf[EI_MAG0] = '\1'; + + if ((e = elf_memory(newelf, sizeof(newelf))) == NULL || + elf_kind(e) != ELF_K_NONE) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); +} + +void +tcInvalidElfVersionMismatch(void) +{ + Elf *e; + char newelf[sizeof(elf_file)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("an ELF blob with an invalid version number is" + " to be rejected, with error ELF_E_VERSION."); + + memcpy(newelf, elf_file, sizeof(elf_file)); + newelf[EI_VERSION] = EV_CURRENT+1; /* change version */ + + if ((e = elf_memory(newelf, sizeof(newelf))) != NULL || + elf_errno() != ELF_E_VERSION) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); +} + +/* + * `ar' archives. + */ + +changequote({,}) +static char ar_file[] = "!\n" + "t/ 1151656346 1001 0 100644 5 `\n" + "Test\n"; +changequote + +void +tcValidArValid(void) +{ + Elf *e; + TP_ANNOUNCE("an valid AR archive is accepted as type" + " ELF_K_AR."); + + TP_CHECK_INITIALIZATION(); + + if ((e = elf_memory(ar_file, sizeof(ar_file))) == NULL || + elf_kind(e) != ELF_K_AR) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); + +} + +void +tcInvalidArInvalidSize(void) +{ + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("a too-small AR archive size is classified" + " as 'DATA'."); + + if ((e = elf_memory(ar_file, SARMAG-1)) == NULL || + elf_kind(e) != ELF_K_NONE) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); +} + +void +tcInvalidArSignature(void) +{ + Elf *e; + char not_an_archive[sizeof(ar_file)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("invalid signature for an archive -> unrecognized"); + + (void) memcpy(not_an_archive, ar_file, sizeof(not_an_archive)); + not_an_archive[0] = '~'; + + if ((e = elf_memory(not_an_archive, sizeof(not_an_archive))) == NULL || + elf_kind(e) != ELF_K_NONE) + tet_result(TET_FAIL); + + (void) elf_end(e); + tet_result(TET_PASS); +} + +/* + * TODO + * - `ar' archives with an archive symbol table. + */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/Makefile new file mode 100644 index 0000000000..f020b675d0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ndxscn.m4 +TS_YAML= newscn + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/ndxscn.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/ndxscn.m4 new file mode 100644 index 0000000000..5a8eb3b48c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_ndxscn/ndxscn.m4 @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ndxscn.m4 1415 2011-02-05 12:45:23Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +/* + * A NULL argument is handled. + */ +void +tcArgsNull(void) +{ + int error, result; + size_t shn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_ndxscn(NULL) fails."); + + result = TET_PASS; + if ((shn = elf_ndxscn(NULL)) != SHN_UNDEF || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("shn=%d error=%d \"%s\".", shn, + error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_ndxscn() on a valid section succeeds. + */ +undefine(`FN') +define(`FN',` +void +tcScnSuccess$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int fd, result; + size_t nscn, n, r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_ndxscn(elf) succeeds."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &nscn) == 0) { + TP_UNRESOLVED("elf_getshnum(old) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + for (n = SHN_UNDEF; n < nscn; n++) { + if ((scn = elf_getscn(e, n)) == NULL) { + TP_UNRESOLVED("elf_getscn(%d) failed: \"%s\".", n, + elf_errmsg(-1)); + break; + } + + if ((r = elf_ndxscn(scn)) != n) { + TP_FAIL("r=%d != %n, error=\"%s\".", r, n, + elf_errmsg(-1)); + break; + } + } + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/Makefile new file mode 100644 index 0000000000..9700c62731 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= newscn.m4 +TS_YAML= newscn + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/newscn.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/newscn.m4 new file mode 100644 index 0000000000..db76058abe --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_newscn/newscn.m4 @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: newscn.m4 1389 2011-01-26 02:31:24Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * A null argument is handled. + */ +void +tcArgsNull(void) +{ + int error, result; + Elf_Scn *scn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_newscn(NULL) fails."); + + result = TET_PASS; + if ((scn = elf_newscn(NULL)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * An ELF descriptor for a data file is rejected. + */ +static char *nonelf = "This is not an ELF file."; + +void +tcArgsNonElf(void) +{ + Elf *e; + Elf_Scn *scn; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_newscn(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + result = TET_PASS; + + if ((scn = elf_newscn(e)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_newscn() on a valid elf file succeeds. + */ +undefine(`FN') +define(`FN',` +void +tcElfSuccess$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int fd, result; + size_t oldn, newn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_newscn(read-only-elf) succeeds."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &oldn) == 0) { + TP_UNRESOLVED("elf_getshnum(old) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_FAIL("elf_newscn() failed: error=\"%s\".", + elf_errmsg(-1)); + result = TET_FAIL; + goto done; + } + + if (elf_getshnum(e, &newn) == 0) { + TP_UNRESOLVED("elf_getshnum(new) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if (newn != (oldn + 1)) + TP_FAIL("newn %d != oldn %d + 1.", newn, oldn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_newscn() sets the dirty bit on the new descriptor. + */ +undefine(`FN') +define(`FN',` +void +tcAllocateDirty$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int fd, result; + unsigned int flags; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: newly returned section is \"dirty\"."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: error=\"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if ((flags = elf_flagscn(scn, ELF_C_SET, 0U)) != ELF_F_DIRTY) + TP_FAIL("flags=0x%x != 0x%x.", flags, ELF_F_DIRTY); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_newscn() on a file with lacking an ehdr fails. + */ + +void +tcAllocateNoEhdr(void) +{ + Elf *e; + Elf_Scn *scn; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_newscn() fails without an EHdr."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + result = TET_PASS; + if ((scn = elf_newscn(e)) != NULL || + (error = elf_errno()) != ELF_E_CLASS) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +} + +/* + * elf_newscn() on a new file returns a section descriptor with index 1. + */ +undefine(`FN') +define(`FN',` +void +tcAllocateNew$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + Elf$1_Ehdr *eh; + int fd, result; + size_t ndx; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: newly returned section is \"dirty\"."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: error=\"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: error=\"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if ((ndx = elf_ndxscn(scn)) != 1U) + TP_FAIL("ndx=%d.", ndx); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/Makefile new file mode 100644 index 0000000000..205bcfbca2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/Makefile @@ -0,0 +1,36 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= next.m4 +TS_DATA= a1.ar a1.o a2.ar a2.o a3.ar +TS_LONGNAME= s------------------------2 +CLEANFILES+= a1.c a2.c s1 ${TS_LONGNAME} "s 3" + +s1: + echo 'This is s1.' > ${.TARGET} +${TS_LONGNAME}: + echo ${TS_LONGNAME} > ${.TARGET} + +# a1.ar contains short names only; a2.ar contains long names; a3.ar contains ELF binaries +# and a symbol table. + +a1.c: .SILENT + echo "int a1;" > ${.TARGET} +a2.c: .SILENT + echo "int a2;" > ${.TARGET} + +a1.ar: s1 .SILENT + rm -f ${.TARGET} + echo 's-3.' > "s 3" + ${AR} crv ${.TARGET} s1 "s 3" > /dev/null + +a2.ar: s1 ${TS_LONGNAME} .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null + +a3.ar: s1 ${TS_LONGNAME} a1.o a2.o .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} ${.ALLSRC} > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/next.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/next.m4 new file mode 100644 index 0000000000..8611de6fee --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_next/next.m4 @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: next.m4 1622 2011-07-07 11:48:35Z jkoshy $ + */ + +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * Test the `elf_next' API. + */ + +/* + * Assertion: with a NULL value passed in, elf_next returns ELF_C_NULL. + */ +void +tcArgsNull(void) +{ + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("NULL argument returns ELF_C_NULL"); + + tet_result(elf_next(NULL) == ELF_C_NULL ? TET_PASS : TET_FAIL); +} + +/* + * Invoking elf_next on a non-archive should return ELF_C_NULL. + */ + +static char *notar = "This is not an AR archive."; +static char *elf = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +undefine(`FN') +define(`FN',` +void +tcArgsNonAr`'TOUPPER($1)(void) +{ + Elf *e; + Elf_Cmd c; + int result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("error ELF_C_NULL with a non-archive \"$1\"."); + + TS_OPEN_MEMORY(e, $1); + + result = TET_PASS; + if ((c = elf_next(e)) != ELF_C_NULL) + TP_FAIL("\"$1\" c=%d, != ELF_C_NULL", c); + + (void) elf_end(e); + + tet_result(result); +}') + +FN(notar) +FN(elf) + +/* + * FN(ar-file-name, count) + * + * Returns ELF_C_READ as expected for an archive with > 1 members (as measured + * by the number of ELF_C_READ return values). + * + * The test cases for elf_begin() verify that the correct Elf * pointers get + * returned by a subsequent call to elf_begin(). + * + */ +undefine(`FN') +define(`FN',` +void +tcArArchive$1(void) +{ + int error, fd, i, result; + Elf_Cmd c; + Elf *a, *e; + + TP_ANNOUNCE("correctly iterates through \"a$1.ar\" with $2 members."); + + result = TET_UNRESOLVED; + a = e = NULL; + fd = -1; + i = 0; + + _TS_OPEN_FILE(a, "a$1.ar", ELF_C_READ, fd, goto done;); + + (void) elf_errno(); + c = ELF_C_READ; + while ((e = elf_begin(fd, c, a)) != NULL) { + c = elf_next(e); + (void) elf_end(e); + i++; + } + + if ((error = elf_errno()) != ELF_E_NONE) { + TP_FAIL("error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + if (i != $2) + TP_FAIL("i=%d expected $2.", i); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(1, 2) dnl text files with short names +FN(2, 2) dnl text files with long names +FN(3, 4) dnl text files + ELF objects. + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/Makefile new file mode 100644 index 0000000000..5dcb9e3137 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= nextscn.m4 +TS_YAML= newscn + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/nextscn.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/nextscn.m4 new file mode 100644 index 0000000000..c9315a125f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_nextscn/nextscn.m4 @@ -0,0 +1,378 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: nextscn.m4 1385 2011-01-23 15:10:19Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * Null arguments are handled correctly. + */ +void +tcArgsNull(void) +{ + int error, result; + Elf_Scn *scn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(NULL,*) fails."); + + result = TET_PASS; + if ((scn = elf_nextscn(NULL, NULL)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * elf_nextscn(non-elf) fails. + */ + +static char *nonelf = "This is not an ELF file."; + +void +tcArgsNonElf(void) +{ + Elf *e; + Elf_Scn *scn; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(non-elf) fails."); + + TS_OPEN_MEMORY(e, nonelf); + + result = TET_PASS; + + if ((scn = elf_nextscn(e, NULL)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + (void) elf_end(e); + + tet_result(result); +} + +/* + * elf_nextscn(e,NULL) returns section number 1. + */ +undefine(`FN') +define(`FN',` +void +tcElfSuccess$1$2(void) +{ + Elf *e; + Elf_Scn *scn; + int fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_nextscn(elf,NULL) succeeds."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if ((scn = elf_nextscn(e, NULL)) == NULL) { + TP_FAIL("elf_newscn() failed: error=\"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((n = elf_ndxscn(scn)) != 1) + TP_FAIL("elf_nextscn() returned index %d.", n); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_nextscn(new-elf, last-section) returns NULL and no error. + */ + +undefine(`FN') +define(`FN',` +void +tcElfLastNewFile$1(void) +{ + Elf *e; + Elf_Scn *scn, *nextscn; + Elf$1_Ehdr *eh; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(newelf,last-scn) returns NULL."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed."); + goto done; + } + + (void) elf_errno(); + + result = TET_PASS; + if ((nextscn = elf_nextscn(e, scn)) != NULL || + (error = elf_errno()) != ELF_E_NONE) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(32) +FN(64) + + +/* + * elf_nextscn(old-elf, last-section) returns NULL and no error. + */ + +undefine(`FN') +define(`FN',` +void +tcElfLastOldFile$2$1(void) +{ + Elf *e; + Elf_Scn *scn, *nextscn; + int error, fd, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(oldelf,last-scn) returns NULL."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &n) == 0) { + TP_UNRESOLVED("elf_getshnum() failed."); + goto done; + } + + if ((scn = elf_getscn(e, n - 1)) == NULL) { + TP_UNRESOLVED("elf_getscn(%d) failed.", (n-1)); + goto done; + } + + (void) elf_errno(); + + result = TET_PASS; + if ((nextscn = elf_nextscn(e, scn)) != NULL || + (error = elf_errno()) != ELF_E_NONE) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * elf_nextscn(iterates through sections in ascending order. + */ + +undefine(`FN') +define(`FN',` +void +tcElfAscending$2$1(void) +{ + Elf *e; + Elf_Scn *scn, *oldscn; + int error, fd, result; + size_t nsections, n, r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(elf,last-scn) returns NULL."); + + e = NULL; + fd = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e, "newscn.$2$1", ELF_C_READ, fd, goto done;); + + if (elf_getshnum(e, &nsections) == 0) { + TP_UNRESOLVED("elf_getshnum() failed."); + goto done; + } + + if ((oldscn = elf_getscn(e, 0)) == NULL) { + TP_UNRESOLVED("elf_getscn(0) failed."); + goto done; + } + + result = TET_PASS; + + for (n = 0; n < nsections-1; n++) { + if ((scn = elf_nextscn(e, oldscn)) == NULL) { + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + goto done; + } + + if ((r = elf_ndxscn(scn)) != n+1) { + TP_FAIL("scn=%p ndx %d != %d.", (void *) scn, r, n+1); + goto done; + } + oldscn = scn; + } + + /* check the last one */ + if ((scn = elf_nextscn(e, oldscn)) != NULL || + (r = elf_ndxscn(oldscn)) != (nsections-1)) + TP_FAIL("scn=%p r=%d", (void *) scn, r); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + + +/* + * elf_nextscn() returns an error on mismatched Elf,Scn. + */ + +undefine(`FN') +define(`FN',` +void +tcElfMismatch$2$1(void) +{ + Elf *e1, *e2; + Elf_Scn *scn, *nextscn; + int error, fd1, fd2, result; + size_t n; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_nextscn(e1,scn-not-of-e1) fails."); + + e1 = e2 = NULL; + fd1 = fd2 = -1; + result = TET_UNRESOLVED; + + _TS_OPEN_FILE(e1, "newscn.$2$1", ELF_C_READ, fd1, goto done;); + _TS_OPEN_FILE(e2, TS_NEWFILE, ELF_C_WRITE, fd2, goto done;); + + if ((scn = elf_getscn(e1, 0)) == NULL) { + TP_UNRESOLVED("elf_getscn(%d) failed.", (n-1)); + goto done; + } + + result = TET_PASS; + if ((nextscn = elf_nextscn(e2, scn)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("scn=%p error=%d \"%s\".", (void *) scn, + error, elf_errmsg(error)); + + done: + if (e1) + (void) elf_end(e1); + if (e2) + (void) elf_end(e2); + if (fd1 != -1) + (void) close(fd1); + if (fd2 != -1) + (void) close(fd2); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/Makefile new file mode 100644 index 0000000000..d1e415c156 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/Makefile @@ -0,0 +1,18 @@ +# $Id$ + +TOP= ../../../../.. + +TS_SRCS= rand.m4 +TS_DATA= a.ar s1 s2 +TS_FILES= empty-file.ar missing-file.ar + +s1: .SILENT + echo 'This is s1.' > ${.TARGET} +s2: .SILENT + echo 's2.' > ${.TARGET} + +a.ar: s1 s2 .SILENT + rm -f ${.TARGET} + ${AR} crv ${.TARGET} s1 s2 > /dev/null + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/empty-file.ar b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/empty-file.ar new file mode 100644 index 0000000000..f7039eda3a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/empty-file.ar @@ -0,0 +1,2 @@ +! +e1/ 0 0 0 644 0 ` diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/missing-file.ar b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/missing-file.ar new file mode 100644 index 0000000000..d62c803db2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/missing-file.ar @@ -0,0 +1,2 @@ +! +e1/ 0 0 0 644 42 ` diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/rand.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/rand.m4 new file mode 100644 index 0000000000..bdcf436456 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rand/rand.m4 @@ -0,0 +1,415 @@ +/*- + * Copyright (c) 2019 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include +#include + +#include +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * The following definitions should match those in `./Makefile'. + */ +define(`TP_ARFILE',`"a.ar"') +define(`TP_NONARCHIVE', `"s1"') + +/* + * The use of an offset less than SARMAG should fail. + */ +void +tcSeekBelowSarmag(void) +{ + Elf *ar; + off_t offset; + int error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand() fails for an offset less than SARMAG"); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + result = TET_PASS; + + if ((offset = elf_rand(ar, 1)) != 0) { + TP_FAIL("elf_rand() succeeded with offset=%lld", + (unsigned long long) offset); + } else if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error=%d \"%s\"", error, + elf_errmsg(error)); + } + + (void) elf_end(ar); + (void) close(fd); + + tet_result(result); +} + +/* + * The use of an offset greater than the largest valid file offset + * should fail. + */ +void +tcSeekMoreThanFileSize(void) +{ + Elf *ar; + off_t offset; + struct stat sb; + int error, fd, result; + + result = TET_UNRESOLVED; + ar = NULL; + fd = -1; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand() fails with a too-large offset"); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + /* Get the file size of the archive. */ + if (fstat(fd, &sb) < 0) { + TP_UNRESOLVED("cannot determine the size of \"%s\"", + TP_ARFILE); + goto done; + } + + result = TET_PASS; + + if ((offset = elf_rand(ar, sb.st_size)) != 0) { + TP_FAIL("elf_rand() succeeded with offset=%lld", + (unsigned long long) offset); + } else if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error=%d \"%s\"", error, + elf_errmsg(error)); + } + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * An offset with value SARMAG is accepted. + */ +void +tcOffsetEqualsSARMAG(void) +{ + Elf *ar; + off_t offset; + int fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(SARMAG) succeeds."); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((offset = elf_rand(ar, SARMAG)) != SARMAG) { + TP_FAIL("unexpected offset: %lld", + (long long) offset); + goto done; + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Invoking elf_rand() on a non-archive should fail. + */ +void +tcOnNonArchive(void) +{ + Elf *e; + off_t offset; + int error, fd, result; + + fd = -1; + e = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(non-archive) fails."); + + TS_OPEN_FILE(e, TP_NONARCHIVE, ELF_C_READ, fd); + + if ((offset = elf_rand(e, SARMAG)) != 0 || + (error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected offset=%lld", + (long long) offset); + goto done; + } + + result = TET_PASS; + +done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Use an offset value that could cause an overflow. + */ +void +tcOffsetOverflow(void) +{ + Elf *ar; + off_t offset; + uint64_t max_offset; + int error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + /* A even offset that is close to overflowing. */ + max_offset = (1ULL << (sizeof(off_t) * CHAR_BIT - 1)) - 2; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("offset close to overflowing an off_t"); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((offset = elf_rand(ar, (off_t) max_offset)) != 0) { + TP_FAIL("unexpected success, offset=%lld", + (long long) offset); + goto done; + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Setting the offset to a value that does not correspond to an ar header + * should fail. + */ +void +tcOffsetNotCorrespondingToAnArchiveHeader(void) +{ + Elf *ar; + off_t offset; + int error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(non-header-offset) should fail."); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((offset = elf_rand(ar, SARMAG+2)) != 0) { + TP_FAIL("unexpected success, offset=%lld", + (long long) offset); + goto done; + } else if ((error = elf_errno()) != ELF_E_ARCHIVE) { + TP_FAIL("unexpected error=%d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Odd values of offsets are not legal. + */ +void +tcOddOffset(void) +{ + Elf *ar; + off_t offset; + int error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(odd-offset-value) should fail."); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((offset = elf_rand(ar, SARMAG+1)) != 0) { + TP_FAIL("unexpected success, offset=%lld", + (long long) offset); + goto done; + } else if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error=%d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + +/* + * Negative offset values are not legal. + */ +void +tcNegativeOffset(void) +{ + Elf *ar; + off_t offset; + int error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(odd-offset-value) should fail."); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + if ((offset = elf_rand(ar, -SARMAG)) != 0) { + TP_FAIL("unexpected success, offset=%lld", + (long long) offset); + goto done; + } else if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("unexpected error=%d \"%s\"", error, + elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} + + +/* These offsets correspond to archive TP_ARFILE. */ +static off_t valid_offsets[] = { + SARMAG, /* File 's1'. */ + 80 /* File 's2'. */ +}; + +static const int number_of_offsets = + sizeof(valid_offsets) / sizeof(valid_offsets[0]); + +/* + * Valid offsets should be usable. + */ +void +tcValidOffsets(void) +{ + Elf *ar; + off_t offset; + int i, error, fd, result; + + fd = -1; + ar = NULL; + result = TET_UNRESOLVED; + + TP_CHECK_INITIALIZATION(); + TP_ANNOUNCE("elf_rand(valid-offsets) succeeds."); + + TS_OPEN_FILE(ar, TP_ARFILE, ELF_C_READ, fd); + + for (i = 0; i < number_of_offsets; i++) { + if ((offset = elf_rand(ar, valid_offsets[i])) != + valid_offsets[i]) { + error = elf_errno(); + TP_FAIL("failed to seek to offset %lld, error=%d " + "\"%s\"", (long long) offset, error, + elf_errmsg(error)); + goto done; + } + } + + result = TET_PASS; + +done: + if (ar) + (void) elf_end(ar); + if (fd != -1) + (void) close(fd); + + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/Makefile new file mode 100644 index 0000000000..769f6038f2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= rawfile.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/rawfile.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/rawfile.m4 new file mode 100644 index 0000000000..a8beda1c8b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_rawfile/rawfile.m4 @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: rawfile.m4 1694 2011-08-02 04:34:35Z jkoshy $ + */ + +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +include(`elfts.m4') + +/* + * Test the `elf_rawfile' entry point. + */ + +IC_REQUIRES_VERSION_INIT(); + +/* + * A NULL `elf *' argument should return the appropriate error, + * and set the `sz' pointer to zero. + */ +void +tcNullNonNull(void) +{ + size_t sz; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_rawfile(NULL,...) returns an error," + " and sets the size pointer to zero."); + + sz = -1; + if (elf_rawfile(NULL, &sz) != NULL || + elf_errno() != ELF_E_ARGUMENT || + sz != 0) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + +changequote({,}) +static char ar_file[] = "!\n" + "t/ 1151656346 1001 0 100644 5 `\n" + "Test\n"; +changequote + +void +tcValidAr(void) +{ + char *p; + Elf *e; + size_t sz; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_rawfile(E,...) descriptor with a valid" + " descriptor `E' to an ar(1) archive succeeds and returns" + " correct values."); + + TS_OPEN_MEMORY(e, ar_file); + + if ((p = elf_rawfile(e, &sz)) == NULL || + sz != sizeof(ar_file) || + memcmp(p, ar_file, sizeof(ar_file))) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +static char elf_file[] = "\177ELF\001\001\001 \001\000\000\000\000" + "\000\000\000\001\000\003\000\001\000\000\000\357\276\255\336" + "\000\000\000\000\000\000\000\000\003\000\000\0004\000 \000" + "\000\000(\000\000\000\000\000"; + +void +tcValidElf(void) +{ + char *p; + Elf *e; + size_t sz; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_rawfile(E,...) descriptor with a valid" + " descriptor `E' to an ELF object succeeds and returns" + " correct values."); + + TS_OPEN_MEMORY(e, elf_file); + + if ((p = elf_rawfile(e, &sz)) == NULL || + sz != sizeof(elf_file) || + memcmp(p, elf_file, sizeof(elf_file))) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +void +tcValidNull(void) +{ + char *p; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("assertion: elf_rawfile(E,NULL) on a valid descriptor " + "`E' and NULL sz pointer succeeds and returns the correct " + "value."); + + TS_OPEN_MEMORY(e, elf_file); + + if ((p = elf_rawfile(e, NULL)) == NULL || + memcmp(p, elf_file, sizeof(elf_file))) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +/* + * Todo: + * + * Test elf_rawfile() on an ELF object embedded inside an `ar' archive. + */ diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/Makefile new file mode 100644 index 0000000000..2ac4c294a1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= strptr.m4 +TS_YAML= newscn xscn-2 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/strptr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/strptr.m4 new file mode 100644 index 0000000000..b89dfcc0d9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_strptr/strptr.m4 @@ -0,0 +1,363 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: strptr.m4 1380 2011-01-23 07:21:25Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +IC_REQUIRES_VERSION_INIT(); + +include(`elfts.m4') + +/* + * A Null ELF value is rejected. + */ + +void +tcArgsNull(void) +{ + int error, result; + char *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_strptr(NULL,*,*) fails."); + + result = TET_PASS; + if ((r = elf_strptr(NULL, (size_t) 0, (size_t) 0)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p error=%d \"%s\".", r, error, elf_errmsg(error)); + + tet_result(result); +} + +/* + * An illegal section index is rejected. + */ +undefine(`FN') +define(`FN',` +void +tcArgsIllegalSection$1`'TOUPPER($2)(void) +{ + int error, fd, result; + Elf *e; + char *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: a non-STRTAB section is rejected."); + + _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;); + + result = TET_PASS; + if ((r = elf_strptr(e, SHN_UNDEF, (size_t) 0)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p error=%d \"%s\".", r, error, + elf_errmsg(error)); + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(32,`lsb',`newscn') +FN(32,`msb',`newscn') +FN(64,`lsb',`newscn') +FN(64,`msb',`newscn') + +/* + * An invalid section offset is rejected. + */ + +undefine(`FN') +define(`FN',` +void +tcArgsIllegalOffset$1`'TOUPPER($2)(void) +{ + Elf *e; + char *r; + Elf_Scn *scn; + Elf$1_Ehdr *eh; + Elf$1_Shdr *sh; + int error, fd, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected."); + + _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;); + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() faied: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if ((r = elf_strptr(e, eh->e_shstrndx, sh->sh_size)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p error=%d \"%s\".", (void *) r, error, + elf_errmsg(error)); + + /* Try a very large value */ + if ((r = elf_strptr(e, eh->e_shstrndx, ~ (size_t) 0)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p error=%d \"%s\".", (void *) r, error, + elf_errmsg(error)); + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(32,`lsb',`newscn') +FN(32,`msb',`newscn') +FN(64,`lsb',`newscn') +FN(64,`msb',`newscn') + +/* + * A section index inside a 'hole' is rejected. + */ + +static char teststring[] = { + 'a', 'b', 'c', 'd', '\0' +}; + +undefine(`FN') +define(`FN',` +void +tcArgsOffsetInHole$1`'TOUPPER($2)(void) +{ + int error, fd, result; + Elf *e; + size_t sz; + Elf_Scn *scn; + Elf_Data *d; + Elf$1_Shdr *sh; + Elf$1_Ehdr *eh; + char *r; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected."); + + _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;); + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr(): failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Get the current size of the section. */ + sz = sh->sh_size; + + /* Add a new data descriptor to the section. */ + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_align = 512; + d->d_buf = teststring; + d->d_size = sizeof(teststring); + + /* Resync. */ + if (elf_update(e, ELF_C_NULL) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + + /* first byte offset in the "hole". */ + if ((r = elf_strptr(e, eh->e_shstrndx, sz)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r, sz, + error, elf_errmsg(error)); + + /* last offset in the "hole". */ + if ((r = elf_strptr(e, eh->e_shstrndx, (size_t) d->d_align - 1)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r, (d->d_align-1), + error, elf_errmsg(error)); + + /* offset after the new end of the section. */ + if ((r = elf_strptr(e, eh->e_shstrndx, (size_t) d->d_align + d->d_size)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("r=%p offset=%d error=%d \"%s\".", (void *) r, + (d->d_align+d->d_size), error, elf_errmsg(error)); + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(32,`lsb',`newscn') +FN(32,`msb',`newscn') +FN(64,`lsb',`newscn') +FN(64,`msb',`newscn') + +/* + * Check that all strings have their correct offsets. + */ + +struct refstr { + size_t offset; + char *string; +} refstr[] = { + /* From the newscn.* file. */ + { .offset = 0, .string = "" }, + { .offset = 1, .string = ".shstrtab" }, + { .offset = 11, .string = ".foobar" }, +#define NSTATIC 3 + /* added by test case() */ + { .offset = 512, .string = "abcd" } +}; + +undefine(`FN') +define(`FN',` +void +tcArgsValidOffset$1`'TOUPPER($2)(void) +{ + int error, fd, result; + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + Elf$1_Shdr *sh; + Elf$1_Ehdr *eh; + char *r; + struct refstr *rs; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: invalid offsets are rejected."); + + _TS_OPEN_FILE(e, "$3.$2$1", ELF_C_READ, fd, goto done;); + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_getscn(e, eh->e_shstrndx)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr(): failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + for (rs = refstr; rs < &refstr[NSTATIC]; rs++) + if ((r = elf_strptr(e, eh->e_shstrndx, rs->offset)) == NULL || + strcmp(r, rs->string) != 0) { + TP_FAIL("r=\"%s\" rs=\"%s\" offset=%d error=\"%s\".", + r, rs->string, rs->offset, elf_errmsg(-1)); + goto done; + } + + /* Add a new data descriptor to the section. */ + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_align = 512; + d->d_buf = teststring; + d->d_size = sizeof(teststring); + + /* Resync. */ + if (elf_update(e, ELF_C_NULL) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + + /* first byte offset in the "hole". */ + if ((r = elf_strptr(e, eh->e_shstrndx, rs->offset)) == NULL || + strcmp(r, rs->string) != 0) + TP_FAIL("r=\"%s\" rs=\"%s\" offset=%d error=\"%s\".", r, + rs->string, rs->offset, elf_errmsg(error)); + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(32,`lsb',`newscn') +FN(32,`msb',`newscn') +FN(64,`lsb',`newscn') +FN(64,`msb',`newscn') + +/* + * TODO: With the layout bit set, an out of bounds offset is detected. + */ + +/* + * TODO: With the layout bit set, strings are correctly retrieved. + */ + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/Makefile new file mode 100644 index 0000000000..12978c90e6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= update.m4 +TS_YAML= newehdr newscn newscn2 rdwr rdwr1 rdwr2 u1 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/update.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/update.m4 new file mode 100644 index 0000000000..5d7e789a8e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_update/update.m4 @@ -0,0 +1,2390 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: update.m4 3081 2014-07-28 08:53:14Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "elfts.h" + +#include "tet_api.h" + +include(`elfts.m4') +define(`TS_OFFSET_SHDR',512) +define(`MAKE_EM', + `ifelse($1,32, + ifelse($2,msb,EM_SPARC,EM_386), + ifelse($2,msb,EM_SPARCV9,EM_X86_64))') + +/* + * Tests for the `elf_update' API. + */ + +IC_REQUIRES_VERSION_INIT(); + +static char rawdata[] = "This is not an ELF file."; + +/* + * A NULL Elf argument returns ELF_E_ARGUMENT. + */ + +void +tcArgsNull(void) +{ + int error, result; + off_t offset; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_update(NULL,*) fails with ELF_E_ARGUMENT."); + + if ((offset = elf_update(NULL, 0)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("elf_update() did not fail with ELF_E_ARGUMENT; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + tet_result(result); +} + +/* + * Illegal values for argument `cmd' are rejected. + */ + +void +tcArgsBadCmd(void) +{ + Elf *e; + Elf_Cmd c; + int error, result; + off_t offset; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("illegal cmd values are rejected with ELF_E_ARGUMENT."); + + TS_OPEN_MEMORY(e, rawdata); + + result = TET_PASS; + for (c = ELF_C_NULL-1; result == TET_PASS && c < ELF_C_NUM; c++) { + if (c == ELF_C_WRITE || c == ELF_C_NULL) /* legal values */ + continue; + if ((offset = elf_update(e, c)) != (off_t) -1) + TP_FAIL("elf_update() succeeded unexpectedly; " + "offset=%jd.", (intmax_t) offset); + else if ((error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("elf_update() did not fail with " + "ELF_E_ARGUMENT; error=%d \"%s\".", error, + elf_errmsg(error)); + } + + (void) elf_end(e); + tet_result(result); +} + +/* + * Non-ELF descriptors are rejected by elf_update(). + */ +undefine(`FN') +define(`FN',` +void +tcArgsNonElf$1(void) +{ + Elf *e; + int error, fd, result; + off_t offset; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_update(non-elf,ELF_C_$1) returns ELF_E_ARGUMENT."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_WRITE_FILE(TS_NEWFILE,rawdata,sizeof(rawdata),goto done;); + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_READ, fd, goto done;); + + if ((offset = elf_update(e, ELF_C_$1)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_ARGUMENT) { + TP_FAIL("elf_update() did not fail with ELF_E_ARGUMENT; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(`NULL') +FN(`WRITE') + +/* + * In-memory (i.e., non-writeable) ELF objects are rejected for + * ELF_C_WRITE with error ELF_E_MODE. + */ + +undefine(`FN') +define(`FN',` +void +tcMemElfWrite$1$2(void) +{ + Elf *e; + off_t offset; + int error, result; + char elf[sizeof(Elf64_Ehdr)]; /* larger of the Ehdr variants */ + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: ELF_C_WRITE with in-memory objects " + "returns ELF_E_MODE."); + + result = TET_UNRESOLVED; + e = NULL; + + _TS_READ_FILE("newehdr.$2$1", elf, sizeof(elf), goto done;); + + TS_OPEN_MEMORY(e, elf); + + if ((offset = elf_update(e, ELF_C_WRITE)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_MODE) { + TP_FAIL("elf_update() did not fail with ELF_E_MODE; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(`32', `lsb') +FN(`32', `msb') +FN(`64', `lsb') +FN(`64', `msb') + +/* + * In-memory ELF objects are updateable with command ELF_C_NULL. + */ + +undefine(`FN') +define(`FN',` +void +tcMemElfNull$1$2(void) +{ + Elf *e; + int result; + size_t fsz; + off_t offset; + char elf[sizeof(Elf64_Ehdr)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: ELF_C_NULL updates in-memory objects."); + + result = TET_UNRESOLVED; + + _TS_READ_FILE("newehdr.$2$1", elf, sizeof(elf), goto done;); + + TS_OPEN_MEMORY(e, elf); + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("elf$2_fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + result = TET_PASS; + if ((offset = elf_update(e, ELF_C_NULL)) != fsz) + TP_FAIL("offset=%jd != %d, error=%d \"%s\".", + (intmax_t) offset, fsz, elf_errmsg(-1)); + + done: + (void) elf_end(e); + tet_result(result); +}') + +FN(`32', `lsb') +FN(`32', `msb') +FN(`64', `lsb') +FN(`64', `msb') + +/* + * A mismatched class in the Ehdr returns an ELF_E_CLASS error. + */ + +undefine(`FN') +define(`FN',` +void +tcClassMismatch$1$2(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf$1_Ehdr *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: a class-mismatch is detected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: %s", elf_errmsg(-1)); + goto done; + } + + /* change the class */ + eh->e_ident[EI_CLASS] = ELFCLASS`'ifelse($1,32,64,32); + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_CLASS) { + TP_FAIL("elf_update() did not fail with ELF_E_CLASS; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(`32', `lsb') +FN(`32', `msb') +FN(`64', `lsb') +FN(`64', `msb') + +/* + * Changing the byte order of an ELF file on the fly is not allowed. + */ + +undefine(`FN') +define(`FN',` +void +tcByteOrderChange$1$2(void) +{ + int error, fd, result; + Elf *e; + off_t offset; + Elf$1_Ehdr *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: byte order changes are rejected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2`'ifelse($2,`lsb',`MSB',`LSB'); + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_HEADER) { + TP_FAIL("elf_update() did not fail with ELF_E_HEADER; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(`32', `lsb') +FN(`32', `msb') +FN(`64', `lsb') +FN(`64', `msb') + +/* + * An unsupported ELF version is rejected with ELF_E_VERSION. + */ + +undefine(`FN') +define(`FN',` +void +tcUnsupportedVersion$1$2(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf$1_Ehdr *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: version changes are rejected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + eh->e_version = EV_CURRENT+1; + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_VERSION) { + TP_FAIL("elf_update() did not fail with ELF_E_VERSION; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(`32', `lsb') +FN(`32', `msb') +FN(`64', `lsb') +FN(`64', `msb') + +/* + * Invoking an elf_cntl(ELF_C_FDDONE) causes a subsequent elf_update() + * to fail with ELF_E_SEQUENCE. + */ +undefine(`FN') +define(`FN',` +void +tcSequenceFdDoneWrite$1(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf$1_Ehdr *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("*$1: elf_update(ELF_C_WRITE) after an elf_cntl(FDDONE) " + "is rejected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if (elf_cntl(e, ELF_C_FDDONE) != 0) { + TP_UNRESOLVED("elf_cntl() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((offset = elf_update(e, ELF_C_WRITE)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_SEQUENCE) { + TP_FAIL("elf_update() did not fail with ELF_E_SEQUENCE; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(32) +FN(64) + +/* + * Invoking an elf_cntl(ELF_C_FDDONE) causes a subsequent + * elf_update(ELF_C_NULL) to succeed. + */ + +undefine(`FN') +define(`FN',` +void +tcSequenceFdDoneNull$1(void) +{ + int fd, result; + off_t offset; + size_t fsz; + Elf *e; + Elf$1_Ehdr *eh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("elf_update(ELF_C_NULL) after an elf_cntl(FDDONE) " + "succeeds."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if (elf_cntl(e, ELF_C_FDDONE) != 0) { + TP_UNRESOLVED("elf_cntl() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((offset = elf_update(e, ELF_C_NULL)) != fsz) { + TP_FAIL("elf_update()->%jd, (expected %d).", + (intmax_t) offset, fsz); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +}') + +FN(32) +FN(64) + +/* + * Check that elf_update() can create a legal ELF file. + */ + +const char strtab[] = { + '\0', + '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0' +}; + +#define INIT_PHDR(P) do { \ + (P)->p_type = PT_NULL; \ + (P)->p_offset = 0x0F0F0F0F; \ + (P)->p_vaddr = 0xA0A0A0A0; \ + (P)->p_filesz = 0x1234; \ + (P)->p_memsz = 0x5678; \ + (P)->p_flags = PF_X | PF_R; \ + (P)->p_align = 64; \ + } while (0) + +#define INIT_SHDR(S,O) do { \ + (S)->sh_name = 1; \ + (S)->sh_type = SHT_STRTAB; \ + (S)->sh_flags = 0; \ + (S)->sh_addr = 0; \ + (S)->sh_offset = (O); \ + (S)->sh_size = sizeof(strtab); \ + (S)->sh_link = 0; \ + (S)->sh_info = 0; \ + (S)->sh_addralign = 1; \ + (S)->sh_entsize = 0; \ + } while (0) + +undefine(`FN') +define(`FN',` +void +tcUpdate$1$2(void) +{ + int fd, result; + off_t offset; + size_t esz, fsz, psz, roundup, ssz; + Elf$1_Shdr *sh; + Elf$1_Ehdr *eh; + Elf$1_Phdr *ph; + Elf_Data *d; + Elf_Scn *scn; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() creates a legal ELF file."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Set the version and endianness */ + eh->e_version = EV_CURRENT; + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2); + eh->e_type = ET_REL; + + if ((esz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0 || + (psz = elf$1_fsize(ELF_T_PHDR, 1, EV_CURRENT)) == 0 || + (ssz = elf$1_fsize(ELF_T_SHDR, 2, EV_CURRENT)) == 0) { + TP_UNRESOLVED("elf$1_fsize() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((ph = elf$1_newphdr(e,1)) == NULL) { + TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + INIT_PHDR(ph); + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + eh->e_shstrndx = elf_ndxscn(scn); + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_buf = (char *) strtab; + d->d_size = sizeof(strtab); + d->d_off = (off_t) 0; + + INIT_SHDR(sh, esz+psz); + + fsz = esz + psz + sizeof(strtab); + roundup = ifelse($1,32,4,8); + fsz = (fsz + roundup - 1) & ~(roundup - 1); + + fsz += ssz; + + if ((offset = elf_update(e, ELF_C_WRITE)) != fsz) { + TP_FAIL("ret=%jd != %d [elferror=\"%s\"]", + (intmax_t) offset, fsz, elf_errmsg(-1)); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + result = elfts_compare_files("u1.$2$1", TS_NEWFILE); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * An unsupported section type should be rejected. + */ +undefine(`FN') +define(`FN',` +void +tcSectionType$2$1(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf_Scn *scn; + Elf$1_Shdr *sh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: unsupported section types are rejected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;); + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf$1_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_LOOS - 1; + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_SECTION) { + TP_FAIL("elf_update() did not fail with ELF_E_SECTION; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd) + (void) close(fd); + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Verify that sections with unrecognized sh_type values in the + * range [SHT_LOUSER,SHT_HIUSER], [SHT_LOPROC,SHT_HIPROC], + * and [SHT_LOOS,SHT_HIOS] are accepted. + */ + +define(`ADD_SECTION',` + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + sh->sh_type = $2; + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + d->d_align = 1; + d->d_buf = NULL; + d->d_size = 0; + d->d_off = (off_t) 0; + (void) elf_flagdata(d, ELF_C_SET, ELF_F_DIRTY); + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);') +undefine(`FN') +define(`FN',` +void +tcSectionTypeOSUserProcDefined_$2$1(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf_Data *d; + Elf_Scn *scn; + Elf$1_Shdr *sh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: user, OS and processor specific " + "section types are accepted.") ; + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;); + + /* + * Create two new sections, one of type SHT_LOOS (0x60000000UL), + * and the other of type SHT_HIUSER (0xFFFFFFFFUL). These + * should be accepted as valid sections. + */ + ADD_SECTION($1,`SHT_LOOS') + ADD_SECTION($1,`SHT_HIUSER') + + if ((offset = elf_update(e, ELF_C_NULL)) == (off_t) -1) { + TP_FAIL("elf_update() failed."); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd) + (void) close(fd); + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +undefine(`ADD_SECTION') + +/* + * An Elf_Data descriptor that is malformed in various ways + * should be rejected. + */ + +undefine(`FN') +define(`FN',` +void +tc$3_$2$1(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf_Data *d; + Elf_Scn *scn; + Elf$1_Shdr *sh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: data descriptors with " $6 + " are rejected."); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;); + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf$1_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + sh->sh_type = SHT_SYMTAB; + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Setup defaults for the test. */ + d->d_buf = (char *) NULL; + d->d_size = sizeof(Elf$1_Sym); + d->d_type = ELF_T_SYM; + d->d_align = 1; + + /* Override, on a per test case basis. */ + $4 + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_$5) { + TP_FAIL("elf_update() did not fail with ELF_E_$5; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd) + (void) close(fd); + tet_result(result); +}') + +define(`MKFN',` +FN(32,`lsb',$1,$2,$3,$4) +FN(32,`msb',$1,$2,$3,$4) +FN(64,`lsb',$1,$2,$3,$4) +FN(64,`msb',$1,$2,$3,$4) +') + +MKFN(IllegalAlignment, `d->d_align = 3;', DATA, "incorrect alignments") +MKFN(UnsupportedVersion, `d->d_version = EV_CURRENT+1;', VERSION, + "an unknown version") +MKFN(UnknownElfType, `d->d_type = ELF_T_NUM;', DATA, "an unknown type") +MKFN(IllegalSize, `d->d_size = 1;', DATA, "an illegal size") + + +/* + * Ensure that updating the section header on an ELF object opened + * in ELF_C_RDWR mode in an idempotent manner leaves the object + * in a sane state. See ticket #269. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrShdrIdempotent$2$1(void) +{ + Elf *e; + off_t fsz; + struct stat sb; + size_t strtabidx; + Elf_Scn *strtabscn; + int error, fd, tfd, result; + GElf_Shdr strtabshdr; + char *srcfile = "newscn.$2$1", *tfn; + char *reffile = "newscn2.$2$1"; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: (liblayout) a no-op update of section " + "headers works as expected"); + + result = TET_UNRESOLVED; + e = NULL; + tfn = NULL; + fd = tfd = -1; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", srcfile, + strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, tfd, goto done;); + + if (stat(reffile, &sb) < 0) { + TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno)); + goto done; + } + + /* Retrieve the index of the section name string table. */ + if (elf_getshdrstrndx(e, &strtabidx) != 0) { + TP_UNRESOLVED("elf_getshdrstrndx() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* + * Retrieve the section descriptor for the section name string table. + */ + if ((strtabscn = elf_getscn(e, strtabidx)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + /* Read the section header ... */ + if (gelf_getshdr(strtabscn, &strtabshdr) == NULL) { + TP_UNRESOLVED("gelf_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* ... and write it back. */ + if (gelf_update_shdr(strtabscn, &strtabshdr) == 0) { + TP_UNRESOLVED("gelf_update_shdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Update the underlying ELF object. */ + if ((fsz = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if (fsz != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() returned %d.", error); + goto done; + } + + e = NULL; + /* Compare against the original. */ + result = elfts_compare_files(reffile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfd != -1) + (void) close(tfd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Ensure that updating the section header table on an ELF object opened + * in ELF_C_RDWR mode in an idempotent manner leaves the object + * in a sane state. See ticket #269. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrShdrIdempotentAppLayout$2$1(void) +{ + Elf *e; + off_t fsz; + struct stat sb; + size_t strtabidx; + Elf_Scn *strtabscn; + unsigned int flags; + int error, fd, tfd, result; + GElf_Shdr strtabshdr; + char *srcfile = "newscn.$2$1", *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: (applayout) a no-op update of section " + "headers works as expected"); + + result = TET_UNRESOLVED; + e = NULL; + tfn = NULL; + fd = tfd = -1; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", srcfile, + strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, tfd, goto done;); + + flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); + if ((flags & ELF_F_LAYOUT) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fstat(tfd, &sb) < 0) { + TP_UNRESOLVED("fstat() failed: \"%s\".", + strerror(errno)); + goto done; + } + + /* Retrieve the index of the section name string table. */ + if (elf_getshdrstrndx(e, &strtabidx) != 0) { + TP_UNRESOLVED("elf_getshdrstrndx() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* + * Retrieve the section descriptor for the section name string table. + */ + if ((strtabscn = elf_getscn(e, strtabidx)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + /* Read the section header ... */ + if (gelf_getshdr(strtabscn, &strtabshdr) == NULL) { + TP_UNRESOLVED("gelf_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* ... and write it back. */ + if (gelf_update_shdr(strtabscn, &strtabshdr) == 0) { + TP_UNRESOLVED("gelf_update_shdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Update the underlying ELF object. */ + if ((fsz = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: \"%s\".", elf_errmsg(-1)); + goto done; + } + + if (fsz != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() returned %d.", error); + goto done; + } + + e = NULL; + /* Compare against the original. */ + result = elfts_compare_files(srcfile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfd != -1) + (void) close(tfd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Test handling of sections with buffers of differing Elf_Data types. + */ + +/* + * The contents of the first Elf_Data buffer for section ".foo" + * (ELF_T_WORD, align 4). + */ +uint32_t hash_words[] = { + 0x01234567, + 0x89abcdef, + 0xdeadc0de +}; + +/* + * The contents of the second Elf_Data buffer for section ".foo" + * (ELF_T_BYTE, align 1) + */ +char data_string[] = "helloworld"; + +/* + * The contents of the third Elf_Data buffer for section ".foo" + * (ELF_T_WORD, align 4) + */ +uint32_t checksum[] = { + 0xffffeeee +}; + +/* + * The contents of the ".shstrtab" section. + */ +char string_table[] = { + /* Offset 0 */ '\0', + /* Offset 1 */ '.', 'f' ,'o', 'o', '\0', + /* Offset 6 */ '.', 's' , 'h' , 's' , 't', + 'r', 't', 'a', 'b', '\0' +}; + +undefine(`FN') +define(`FN',` +void +tcMixedBuffer_$2$1(void) +{ + Elf *e; + Elf_Scn *scn, *strscn; + int error, fd, result; + Elf$1_Ehdr *ehdr; + Elf$1_Shdr *shdr, *strshdr; + Elf_Data *data1, *data2, *data3, *data4; + char *reffile = "mixedscn.$2$1", *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: sections with mixed data work " + "as expected"); + + result = TET_UNRESOLVED; + e = NULL; + tfn = NULL; + fd = -1; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + if ((ehdr = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + ehdr->e_ident[EI_DATA] = `ELFDATA2'TOUPPER($2); + ehdr->e_machine = MAKE_EM($1,$2); + ehdr->e_type = ET_REL; + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((data1 = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata(data1) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + data1->d_align = 4; + data1->d_off = 0; + data1->d_buf = hash_words; + data1->d_type = ELF_T_WORD; + data1->d_size = sizeof(hash_words); + data1->d_version = EV_CURRENT; + + if ((data2 = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata(data2) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + data2->d_align = 1; + data2->d_off = 0; + data2->d_buf = data_string; + data2->d_type = ELF_T_BYTE; + data2->d_size = sizeof(data_string); + data2->d_version = EV_CURRENT; + + + if ((data3 = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata(data3) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + data3->d_align = 4; + data3->d_off = 0; + data3->d_buf = checksum; + data3->d_type = ELF_T_WORD; + data3->d_size = sizeof(checksum); + data3->d_version = EV_CURRENT; + + if ((shdr = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + shdr->sh_name = 1; /* offset of ".foo" */ + shdr->sh_type = SHT_PROGBITS; + shdr->sh_flags = SHF_ALLOC; + shdr->sh_entsize = 0; + shdr->sh_addralign = 4; + + /* + * Create the .shstrtab section. + */ + if ((strscn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((data4 = elf_newdata(strscn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + data4->d_align = 1; + data4->d_off = 0; + data4->d_buf = string_table; + data4->d_type = ELF_T_BYTE; + data4->d_size = sizeof(string_table); + data4->d_version = EV_CURRENT; + + if ((strshdr = elf$1_getshdr(strscn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + strshdr->sh_name = 6; /* \0 + strlen(".foo") + \0 */ + strshdr->sh_type = SHT_STRTAB; + strshdr->sh_flags = SHF_STRINGS | SHF_ALLOC; + strshdr->sh_entsize = 0; + + ehdr->e_shstrndx = elf_ndxscn(strscn); + + if (elf_update(e, ELF_C_WRITE) < 0) { + TP_FAIL("elf_update() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Compare files here. */ + TP_UNRESOLVED("Verification is yet to be implemented."); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Test that a call to elf_update() without any changes flagged + * leaves the ELF object unchanged. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrModeNoOp_$1$2(void) +{ + struct stat sb; + int error, fd, result; + Elf *e; + Elf$1_Ehdr *eh; + const char *srcfile = "rdwr.$2$1"; + off_t fsz1, fsz2; + char *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() without flagged changes " + "is a no-op"); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + tfn = NULL; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", + srcfile, strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;); + + if (fstat(fd, &sb) < 0) { + TP_UNRESOLVED("fstat() failed: \"%s\".", + strerror(errno)); + goto done; + } + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_getehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) { + TP_FAIL("elf_update(NULL) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz1); + goto done; + } + + if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) { + TP_FAIL("elf_update(WRITE) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != fsz2) { + TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2); + goto done; + } + + e = NULL; + (void) close(fd); + + /* compare against the original */ + result = elfts_compare_files(srcfile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +}') + +FN(32,lsb) +FN(32,msb) +FN(64,lsb) +FN(64,msb) + +/* + * Test that a call to elf_update() without a change to underlying + * data for the object is a no-op. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrModeNoDataChange_$1$2(void) +{ + int error, fd, result; + Elf *e; + Elf_Scn *scn; + const char *srcfile = "rdwr.$2$1"; + off_t fsz1, fsz2; + struct stat sb; + char *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() with no data changes " + "is a no-op"); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + tfn = NULL; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", + srcfile, strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;); + + if (fstat(fd, &sb) < 0) { + TP_UNRESOLVED("fstat() failed: \"%s\".", + strerror(errno)); + goto done; + } + + if ((scn = elf_getscn(e, 1)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) { + TP_UNRESOLVED("elf_flagscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) { + TP_FAIL("elf_update(NULL) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz1); + goto done; + } + + if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) { + TP_FAIL("elf_update(WRITE) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != fsz2) { + TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + e = NULL; + (void) close(fd); + + /* compare against the original */ + result = elfts_compare_files(srcfile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +}') + +FN(32,lsb) +FN(32,msb) +FN(64,lsb) +FN(64,msb) + +/* + * Test that a call to elf_update() with a changed ehdr causes the + * underlying file to change. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrModeEhdrChange_$1$2(void) +{ + int error, fd, result; + unsigned int flag; + struct stat sb; + Elf *e; + Elf$1_Ehdr *eh; + const char *srcfile = "rdwr.$2$1"; + const char *reffile = "rdwr1.$2$1"; + off_t fsz1, fsz2; + char *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() updates a changed " + "header correctly"); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + tfn = NULL; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", + srcfile, strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;); + + if (fstat(fd, &sb) < 0) { + TP_UNRESOLVED("fstat() failed: \"%s\".", + strerror(errno)); + goto done; + } + + if ((eh = elf$1_getehdr(e)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Change the ELFCLASS of the object. */ + eh->e_type = ET_DYN; + + flag = elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); + if ((flag & ELF_F_DIRTY) == 0) { + TP_UNRESOLVED("elf_flagehdr failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) { + TP_FAIL("elf_update(NULL) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz1); + goto done; + } + + if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) { + TP_FAIL("elf_update(WRITE) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != fsz2) { + TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + e = NULL; + (void) close(fd); + + /* compare against the reference */ + result = elfts_compare_files(reffile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +} +') + +FN(32,lsb) +FN(32,msb) +FN(64,lsb) +FN(64,msb) + +/* + * Test extending a section. + */ + +static char *base_data = "hello world"; +static char *extra_data = "goodbye world"; + +undefine(`FN') +define(`FN',` +void +tcRdWrExtendSection_$1$2(void) +{ + int error, fd, result; + unsigned int flag; + struct stat sb; + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + const char *srcfile = "rdwr.$2$1"; + const char *reffile = "rdwr2.$2$1"; + off_t fsz1, fsz2; + char *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() deals with an " + "extended section correctly"); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + tfn = NULL; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", + srcfile, strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;); + + if (stat(reffile, &sb) < 0) { + TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno)); + goto done; + } + + /* Retrieve section 1 and extend it. */ + + if ((scn = elf_getscn(e, 1)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_buf = extra_data; + d->d_size = strlen(extra_data); + + if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) { + TP_UNRESOLVED("elf_flagscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) { + TP_FAIL("elf_update(NULL) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz1); + goto done; + } + + if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) { + TP_FAIL("elf_update(WRITE) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != fsz2) { + TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + e = NULL; + (void) close(fd); + + /* compare against the reference */ + result = elfts_compare_files(reffile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +} +') + +FN(32,lsb) +FN(32,msb) +FN(64,lsb) +FN(64,msb) + +/* + * Test shrinking a section. + */ + +undefine(`FN') +define(`FN',` +void +tcRdWrShrinkSection_$1$2(void) +{ + int error, fd, result; + unsigned int flag; + struct stat sb; + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + const char *srcfile = "rdwr2.$2$1"; + const char *reffile = "rdwr.$2$1"; + off_t fsz1, fsz2; + char *tfn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: elf_update() deals with an " + "shrunk section correctly"); + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + tfn = NULL; + + /* Make a copy of the reference object. */ + if ((tfn = elfts_copy_file(srcfile, &error)) < 0) { + TP_UNRESOLVED("elfts_copyfile(%s) failed: \"%s\".", + srcfile, strerror(error)); + goto done; + } + + /* Open the copied object in RDWR mode. */ + _TS_OPEN_FILE(e, tfn, ELF_C_RDWR, fd, goto done;); + + if (stat(reffile, &sb) < 0) { + TP_UNRESOLVED("stat() failed: \"%s\".", strerror(errno)); + goto done; + } + + /* Retrieve section 1 and shrink it. */ + + if ((scn = elf_getscn(e, 1)) == NULL) { + TP_UNRESOLVED("elf_getscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((d = elf_getdata(scn, NULL)) == NULL) { + TP_UNRESOLVED("elf_getdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_size = strlen(base_data); + + if (elf_flagdata(d, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) { + TP_UNRESOLVED("elf_flagdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY) != ELF_F_DIRTY) { + TP_UNRESOLVED("elf_flagscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz1 = elf_update(e, ELF_C_NULL)) < 0) { + TP_FAIL("elf_update(NULL) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != sb.st_size) { + TP_FAIL("Size error: expected=%d, elf_update()=%d", + sb.st_size, fsz1); + goto done; + } + + if ((fsz2 = elf_update(e, ELF_C_WRITE)) < 0) { + TP_FAIL("elf_update(WRITE) failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if (fsz1 != fsz2) { + TP_FAIL("fsz1 (%d) != fsz2 (%d)", fsz1, fsz2); + goto done; + } + + /* Close the temporary file. */ + if ((error = elf_end(e)) != 0) { + TP_UNRESOLVED("elf_end() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + e = NULL; + (void) close(fd); + + /* compare against the reference */ + result = elfts_compare_files(reffile, tfn); + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (tfn != NULL) + (void) unlink(tfn); + + tet_result(result); +} +') + +FN(32,lsb) +FN(32,msb) +FN(64,lsb) +FN(64,msb) + +/* + * Test cases rejecting malformed ELF files created with the + * ELF_F_LAYOUT flag set. + */ + +undefine(`FN') +define(`FN',` +void +tcEhdrPhdrCollision$1$2(void) +{ + int error, fd, result, flags; + off_t offset; + size_t fsz, psz, roundup, ssz; + Elf$1_Ehdr *eh; + Elf$1_Phdr *ph; + Elf_Data *d; + Elf_Scn *scn; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the ehdr and phdr is " + "detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); + if ((flags & ELF_F_LAYOUT) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Fill in sane values for the Ehdr. */ + eh->e_type = ET_REL; + eh->e_shoff = 0; + eh->e_ident[EI_CLASS] = ELFCLASS`'$1; + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2); + + if ((ph = elf$1_newphdr(e, 1)) == NULL) { + TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + /* Make the phdr table overlap with the ehdr. */ + eh->e_phoff = fsz - 1; + + /* Check the return values from elf_update(). */ + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_LAYOUT) { + TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT, " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +} +') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +undefine(`FN') +define(`FN',` +void +tcShdrPhdrCollision$1$2(void) +{ + int error, fd, result, flags; + off_t offset; + size_t fsz, psz, roundup, ssz; + Elf$1_Ehdr *eh; + Elf$1_Phdr *ph; + Elf_Data *d; + Elf_Scn *scn; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the shdr and phdr is " + "detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); + if ((flags & ELF_F_LAYOUT) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Fill in sane values for the Ehdr. */ + eh->e_type = ET_REL; + eh->e_ident[EI_CLASS] = ELFCLASS`'$1; + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2); + + if ((ph = elf$1_newphdr(e, 1)) == NULL) { + TP_UNRESOLVED("elf$1_newphdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1)); + goto done; + } + + /* Make the PHDR and SHDR tables overlap. */ + eh->e_phoff = fsz; + eh->e_shoff = fsz; + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_LAYOUT) { + TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +} +') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Verify that an overlap between a section's data and the SHDR + * table is detected. + */ + +undefine(`FN') +define(`FN',` +void +tcShdrSectionCollision$1$2(void) +{ + int error, fd, result, flags; + off_t offset; + size_t fsz, psz, roundup, ssz; + Elf$1_Ehdr *eh; + Elf$1_Shdr *sh; + Elf_Data *d; + Elf_Scn *scn; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: an overlap of the shdr and a section is " + "detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); + if ((flags & ELF_F_LAYOUT) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Fill in sane values for the Ehdr. */ + eh->e_type = ET_REL; + eh->e_ident[EI_CLASS] = ELFCLASS`'$1; + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2); + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1)); + goto done; + } + + eh->e_shoff = fsz; + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + /* Fill in application-specified fields. */ + sh->sh_type = SHT_PROGBITS; + sh->sh_addralign = 1; + sh->sh_size = 1; + sh->sh_entsize = 1; + + /* Make this section overlap with the section header. */ + sh->sh_offset = fsz; + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_LAYOUT) { + TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +} +') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +/* + * Check that overlapping sections are rejected when ELF_F_LAYOUT is set. + */ + +undefine(`FN') +define(`FN',` +void +tcSectionOverlap$1$2(void) +{ + int error, fd, result, flags; + off_t offset; + size_t fsz, psz, roundup, ssz; + Elf$1_Ehdr *eh; + Elf$1_Shdr *sh; + Elf_Data *d; + Elf_Scn *scn; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: an overlap between two sections is " + "detected."); + + result = TET_UNRESOLVED; + fd = -1; + e = NULL; + + _TS_OPEN_FILE(e, TS_NEWFILE, ELF_C_WRITE, fd, goto done;); + + flags = elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); + if ((flags & ELF_F_LAYOUT) == 0) { + TP_UNRESOLVED("elf_flagelf() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf$1_newehdr(e)) == NULL) { + TP_UNRESOLVED("elf$1_newehdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + /* Fill in sane values for the Ehdr. */ + eh->e_type = ET_REL; + eh->e_ident[EI_CLASS] = ELFCLASS`'$1; + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($2); + eh->e_shoff = TS_OFFSET_SHDR; + + if ((fsz = elf$1_fsize(ELF_T_EHDR, 1, EV_CURRENT)) == 0) { + TP_UNRESOLVED("fsize() failed: %s.", elf_errmsg(-1)); + goto done; + } + + /* + * Build the first section. + */ + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_type = ELF_T_BYTE; + d->d_off = 0; + d->d_buf = base_data; + d->d_size = strlen(base_data); + + /* Fill in application-specified fields. */ + sh->sh_type = SHT_PROGBITS; + sh->sh_addralign = 1; + sh->sh_size = 1; + sh->sh_entsize = 1; + sh->sh_offset = fsz; + + /* + * Build the second section. + */ + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: %s.", elf_errmsg(-1)); + goto done; + } + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + + d->d_buf = base_data; + d->d_size = strlen(base_data); + + /* Fill in application-specified fields. */ + sh->sh_type = SHT_PROGBITS; + sh->sh_addralign = 1; + sh->sh_size = 1; + sh->sh_entsize = 1; + + sh->sh_offset = fsz + 1; /* Overlap with the first section. */ + + if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { + TP_FAIL("elf_update() succeeded unexpectedly; offset=%jd.", + (intmax_t) offset); + goto done; + } + + if ((error = elf_errno()) != ELF_E_LAYOUT) { + TP_FAIL("elf_update() did not fail with ELF_E_LAYOUT; " + "error=%d \"%s\".", error, elf_errmsg(error)); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + (void) unlink(TS_NEWFILE); + + tet_result(result); +} +') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/Makefile new file mode 100644 index 0000000000..8078e99888 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= version.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/version.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/version.m4 new file mode 100644 index 0000000000..56880f640b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/elf_version/version.m4 @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: version.m4 1339 2010-12-31 15:42:52Z jkoshy $ + */ + +include(`elfts.m4') + +#include + +#include "tet_api.h" + +/* + * Test the `elf_version' entry point. + * + * Each test case requires a separate invocation of the test + * executable because the first call of elf_version() sets private + * state in the library. Consequently these tests are organized as + * one test purpose per test case. + */ + +/* + * Test version number retrieval. + */ + +void +tcParamNoneReturnsCurrentVersion(void) +{ + TP_ANNOUNCE("Param EV_NONE returns version == EV_CURRENT"); + if (elf_version(EV_NONE) != EV_CURRENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + + +/* + * Test that an unsupported version number is not accepted. + */ + +void +tcValueTooLarge(void) +{ + TP_ANNOUNCE("calling elf_version() with an unsupported " + "(too-large) value fails and sets the error to ELF_E_VERSION."); + + if (elf_version(EV_CURRENT+1) != EV_NONE) { + tet_result(TET_FAIL); + return; + } + + if (elf_errno() != ELF_E_VERSION) { + tet_result(TET_FAIL); + return; + } + + tet_result(TET_PASS); +} + +/* + * Test that a reject version number does not cause the internal + * version number to change. + */ + +void +tcValueErrorNoChange(void) +{ + TP_ANNOUNCE("the library's current version should not be " + "changed by a failing call to elf_version()."); + + if (elf_version(EV_CURRENT+1) != EV_NONE) { + tet_infoline("unresolved: illegal elf_version() call did not " + "fail as expected."); + tet_result(TET_UNRESOLVED); + return; + } + + if (elf_version(EV_NONE) != EV_CURRENT) { + tet_result(TET_FAIL); + return; + } + + tet_result(TET_PASS); +} + +/* + * Test that setting the library version to a legal value should + * succeed. + * + * Currently, EV_CURRENT (== 1) is the only legal version. When more + * ELF versions are defined, this test should be changed to iterate + * over all of them. + */ + +void +tcValidValuesAreOk(void) +{ + int result; + unsigned int old_version, new_version; + + TP_ANNOUNCE("setting the ELF version to a legal value" + "passes"); + + result = TET_UNRESOLVED; + old_version = elf_version(EV_NONE); + + if (old_version == EV_NONE) { + TP_UNRESOLVED("unknown current elf version"); + goto done; + } + + new_version = EV_CURRENT; + if (elf_version(new_version) != old_version) { + TP_FAIL("unexpected return value from " + "elf_version(new_version)"); + goto done; + } + + /* retrieve the version that was set and check */ + if (elf_version(EV_NONE) != new_version) { + TP_FAIL("the new ELF version was not succesfully " + "set. "); + goto done; + } + + result = TET_PASS; + +done: + tet_result(result); +} + +/* + * Other APIs that shouldn't have elf_version() called. + */ + +void +tcSequenceErrorElfMemory(void) +{ + Elf *e; + + TP_ANNOUNCE("elf_memory() before elf_version() " + "fails with ELF_E_SEQUENCE."); + + if ((e = elf_memory(NULL, 0)) != NULL || + elf_errno() != ELF_E_SEQUENCE) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} + +void +tcSequenceErrorElfKind(void) +{ + TP_ANNOUNCE("assertion: calling elf_kind() before elf_version() " + "fails with ELF_E_SEQUENCE."); + + /* Note: no elf_version() call */ + if (elf_kind(NULL) != ELF_K_NONE && + elf_errno() != ELF_E_SEQUENCE) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/Makefile new file mode 100644 index 0000000000..2fdd6b1247 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= getclass.m4 +TS_DATA= getclass.msb32 getclass.msb64 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/getclass.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/getclass.m4 new file mode 100644 index 0000000000..9ea731dfbe --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getclass/getclass.m4 @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: getclass.m4 1358 2011-01-08 05:40:41Z jkoshy $ + */ + +#include +#include +#include + +#include "elfts.h" +#include "tet_api.h" + +/* + * Test the `gelf_getclass' entry point. + */ + +IC_REQUIRES_VERSION_INIT(); + +void +tp_null(void) +{ + tet_infoline("assertion: gelf_getclass(NULL) should return " + "ELFCLASSNONE."); + + tet_result (gelf_getclass(NULL) != ELFCLASSNONE ? TET_FAIL : TET_PASS); +} + +void +tp_class32(void) +{ + Elf *e; + int fd; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: gelf_getclass() return ELFCLASS32 for a " + "32 bit ELF file."); + + TS_OPEN_FILE(e,"getclass.msb32",ELF_C_READ,fd); + + tet_result (gelf_getclass(e) != ELFCLASS32 ? TET_FAIL : TET_PASS); + + (void) elf_end(e); + (void) close(fd); +} + +void +tp_class64(void) +{ + Elf *e; + int fd; + + TP_CHECK_INITIALIZATION(); + + tet_infoline("assertion: gelf_getclass() return ELFCLASS64 for a " + "64 bit ELF file."); + + TS_OPEN_FILE(e,"getclass.msb64",ELF_C_READ,fd); + + tet_result (gelf_getclass(e) != ELFCLASS64 ? TET_FAIL : TET_PASS); + + (void) elf_end(e); + (void) close(fd); +} diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/Makefile new file mode 100644 index 0000000000..158db64377 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_YAML= ehdr + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/ehdr.m4 new file mode 100644 index 0000000000..29f9960c23 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_getehdr/ehdr.m4 @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +include(`elfts.m4') + +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +#include "gelf_ehdr_template.h" + + +void +tcNullGelfGetNullElf(void) +{ + int result; + GElf_Ehdr dst; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_getehdr(NULL,*) fails with ELF_E_ARGUMENT"); + + result = TET_PASS; + if (gelf_getehdr(NULL,&dst) != NULL || elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + tet_result(result); +} + +void +tcNullGelfGetNullDst(void) +{ + Elf *e; + int fd; + char *fn = "ehdr.msb32"; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_getehdr(*,NULL) fails with ELF_E_ARGUMENT"); + + TS_OPEN_FILE(e,fn,ELF_C_READ,fd); + + if (gelf_getehdr(e, NULL) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); + (void) close(fd); +} + +void +tcNonElfFails(void) +{ + Elf *e; + GElf_Ehdr d; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_getehdr(E) for non-ELF (E) fails with " + "ELF_E_ARGUMENT"); + + TS_OPEN_MEMORY(e,data); + + if (gelf_getehdr(e, &d) != NULL || + elf_errno() != ELF_E_ARGUMENT) + tet_result(TET_FAIL); + else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +void +tcBadElfVersion(void) +{ + int err; + Elf *e; + void *eh; + GElf_Ehdr d; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_getehdr() on an ELF object with an unsupported " + "version fails with ELF_E_VERSION"); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + + badelf[EI_VERSION] = EV_NONE; + badelf[EI_CLASS] = ELFCLASS32; + badelf[EI_DATA] = ELFDATA2MSB; + + TS_OPEN_MEMORY(e,badelf); + + if ((eh = gelf_getehdr(e, &d)) != NULL || + (err = elf_errno()) != ELF_E_VERSION) { + tet_printf("fail: error=%d eh=%p.", err, (void *) eh); + tet_result(TET_FAIL); + } else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +void +tcMalformedElf(void) +{ + int err; + Elf *e; + void *eh; + GElf_Ehdr d; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_getehdr() on a malformed ELF object fails with " + "ELF_E_HEADER"); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + badelf[EI_VERSION] = EV_CURRENT; + badelf[EI_CLASS] = ELFCLASS32; + badelf[EI_DATA] = ELFDATA2MSB; + + TS_OPEN_MEMORY(e, badelf); + + if ((eh = gelf_getehdr(e, &d)) != NULL || + (err = elf_errno()) != ELF_E_HEADER) { + tet_printf("fail: error=%d eh=%p.", err, (void *) eh); + tet_result(TET_FAIL); + } else + tet_result(TET_PASS); + + (void) elf_end(e); +} + +static char *filenames[] = { + "ehdr.lsb32", + "ehdr.msb32", + "ehdr.lsb64", + "ehdr.msb64", + NULL +}; + +void +tcGoodElfValid(void) +{ + int fd, result; + GElf_Ehdr d1, *eh; + Elf *e; + char *fn; + int i, data, class; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("a successful gelf_getehdr() call returns " + "a pointer to the passed in structure, filled with the correct " + "contents"); + + result = TET_PASS; + e = NULL; + fd = -1; + + for (i = 0; i < 4; i++) { + fn = filenames[i]; + + TS_OPEN_FILE(e, fn, ELF_C_READ, fd); + + if ((eh = gelf_getehdr(e, &d1)) == NULL) { + tet_printf("fail: gelf_getehdr(%s): %s.", *fn, + elf_errmsg(-1)); + result = TET_FAIL; + goto done; + } + + if (eh != &d1) { + tet_printf("fail: gelf_getehdr() return != argument."); + result = TET_FAIL; + goto done; + } + + data = (i & 1) ? ELFDATA2MSB : ELFDATA2LSB; + class = (i <= 1) ? ELFCLASS32 : ELFCLASS64; + + CHECK_EHDR(eh, data, class); + + if (result != TET_PASS) + break; + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + } + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} + +void +tcDupCalls(void) +{ + int fd, result; + Elf *e; + GElf_Ehdr d1, d2; + GElf_Ehdr *eh1, *eh2; + char **fn; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("successful calls to gelf_getehdr() for the same object " + "return identical contents"); + + result = TET_PASS; + e = NULL; + fd = -1; + + for (fn = filenames; *fn; fn++) { + TS_OPEN_FILE(e,*fn,ELF_C_READ,fd); + + if ((eh1 = gelf_getehdr(e, &d1)) == NULL || + (eh2 = gelf_getehdr(e, &d2)) == NULL) { + tet_printf("unresolved: gelf_getehdr(%s) failed.", + *fn); + result = TET_UNRESOLVED; + goto done; + } + + COMPARE_EHDR(*fn, d1, d2); + + if (result != TET_PASS) + goto done; + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + } + + done: + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + + tet_result(result); + +} + diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/Makefile new file mode 100644 index 0000000000..4840d74f6e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= ehdr.m4 +TS_YAML= ehdr newehdr + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/ehdr.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/ehdr.m4 new file mode 100644 index 0000000000..a22a65bef0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_newehdr/ehdr.m4 @@ -0,0 +1,468 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ehdr.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +#include "elfts.h" + +#include "gelf_ehdr_template.h" + +include(`elfts.m4') + +/* + * A NULL `Elf *' argument returns an ELF_E_ARGUMENT error. + */ +undefine(`FN')dnl +define(`FN',` +void +tcGelfGetNullElf$1(void) +{ + void *eh; + int error, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr(NULL,ELFCLASS$2) fails with " + "ELF_E_ARGUMENT."); + + result = TET_PASS; + if ((eh = gelf_newehdr(NULL,ELFCLASS$1)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("eh=%p, error=\"%s\".", eh, elf_errmsg(error)); + + tet_result(result); +}') + +FN(`NONE') +FN(`32') +FN(`64') + +/* + * For a non-NULL but non Elf descriptor, the function should fail + * with ELF_E_ARGUMENT. + */ +undefine(`FN')dnl +define(`FN',` +void +tcDataNonElfDesc$1(void) +{ + int error, result; + void *eh; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr(E,ELFCLASS$1) for non-ELF (E) " + "fails with ELF_E_ARGUMENT."); + + TS_OPEN_MEMORY(e, data); + + result = TET_PASS; + if ((eh = gelf_newehdr(e, ELFCLASS$1)) != NULL || + (error = elf_errno()) != ELF_E_ARGUMENT) + TP_FAIL("eh=%p error=%d \"%s\".", (void *) eh, + error, elf_errmsg(error)); + + (void) elf_end(e); + tet_result(result); +}') + +FN(`NONE') +FN(`32') +FN(`64') + +/* + * A valid Elf descriptor with of an unsupported version should + * return an ELF_E_VERSION error. + */ +undefine(`FN')dnl +define(`FN',` +void +tcBadElfVersion$1$2(void) +{ + int err, result; + Elf *e; + void *eh; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr(E,ELFCLASS$1) with an unsupported " + "version fails with ELF_E_VERSION."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + + badelf[EI_VERSION] = EV_NONE; + badelf[EI_CLASS] = ELFCLASS$2; + badelf[EI_DATA] = ELFDATA2$1; + + TS_OPEN_MEMORY(e, badelf); + + result = TET_PASS; + if ((eh = gelf_newehdr(e, ELFCLASS$2)) != NULL || + (err = elf_errno()) != ELF_E_VERSION) + TP_FAIL("eh=%p error=\"%s\".", (void *) eh, elf_errmsg(err)); + + (void) elf_end(e); + tet_result(result); +}') + +FN(`LSB',`32') +FN(`LSB',`64') +FN(`MSB',`32') +FN(`MSB',`64') + +/* + * A malformed ELF descriptor should return an ELF_E_HEADER error. + */ +undefine(`FN')dnl +define(`FN',` +void +tcMalformedElf$1$2(void) +{ + int err, result; + Elf *e; + void *eh; + char badelf[sizeof(badelftemplate)]; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr($2,ELFCLASS$1) on a malformed " + "ELF header fails with ELF_E_HEADER."); + + (void) memcpy(badelf, badelftemplate, sizeof(badelf)); + badelf[EI_VERSION] = EV_CURRENT; + badelf[EI_CLASS] = ELFCLASS$1; + badelf[EI_DATA] = ELFDATA2$2; + + TS_OPEN_MEMORY(e, badelf); + + result = TET_PASS; + if ((eh = gelf_newehdr(e, ELFCLASS$1)) != NULL || + (err = elf_errno()) != ELF_E_HEADER) + TP_FAIL("eh=%p error=\"%s\".", (void *) eh, elf_errmsg(err)); + + (void) elf_end(e); + tet_result(result); +}') + +FN(`32',`LSB') +FN(`32',`MSB') +FN(`64',`LSB') +FN(`64',`MSB') + +/* + * Attempting to open pre-existing ELF file of the wrong class + * should fail with ELF_E_CLASS. + */ +undefine(`FN')dnl +define(`FN',` +void +tcWrongElfClass$1$2(void) +{ + int error, fd, result; + Elf$2_Ehdr *eh; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("A call to gelf_newehdr(ehdr.$1$3,ELFCLASS$2) " + "fails with ELF_E_CLASS"); + + TS_OPEN_FILE(e, "ehdr.$1$3", ELF_C_READ, fd); + + result = TET_PASS; + error = 0; + eh = NULL; + + result = TET_PASS; + if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) != NULL || + (error = elf_errno()) != ELF_E_CLASS) + TP_FAIL("eh=%p, error=\"%s\".", (void *) eh, elf_errmsg(error)); + + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +}') + +FN(`lsb',`32',`64') +FN(`lsb',`64',`32') +FN(`msb',`32',`64') +FN(`msb',`64',`32') + +/* + * Attempting to open a pre-existing ELF file of the correct class + * should succeed. + */ +undefine(`FN') +define(`FN',` +void +tcElfValidClass$1$2(void) +{ + int fd, result; + Elf$2_Ehdr *eh; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("a successful gelf_newehdr(ehdr.$1$2," + "ELFCLASS$2) call returns the correct contents."); + + TS_OPEN_FILE(e, "ehdr.$1$2", ELF_C_READ, fd); + + result = TET_PASS; + + result = TET_PASS; + if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) == NULL) { + TP_FAIL("gelf_newehdr(ehdr.$1$2) failed: %s.", elf_errmsg(-1)); + goto done; + } + + CHECK_EHDR(eh, ELFDATA2`'TOUPPER($1), ELFCLASS$2); + + done: + (void) elf_end(e); + (void) close(fd); + + tet_result(result); +}') + +FN(`lsb',`32') +FN(`lsb',`64') +FN(`msb',`32') +FN(`msb',`64') + +define(`TS_NEWELF',`"new.elf"') +define(`CHECK_NEWEHDR',` do { + if (($1)->e_ident[EI_MAG0] != ELFMAG0 || + ($1)->e_ident[EI_MAG1] != ELFMAG1 || + ($1)->e_ident[EI_MAG2] != ELFMAG2 || + ($1)->e_ident[EI_MAG3] != ELFMAG3 || + ($1)->e_ident[EI_CLASS] != ELFCLASS$2 || + ($1)->e_ident[EI_DATA] != ELFDATANONE || + ($1)->e_ident[EI_VERSION] != EV_CURRENT || + ($1)->e_machine != EM_NONE || + ($1)->e_type != ELF_K_NONE || + ($1)->e_version != EV_CURRENT) + TP_FAIL("gelf_getnewehdr(ELFCLASS$2) " + "header mismatch."); +} while (0) +') + +/* + * Retrieving the header from a new ELF file should return the + * correct values. + */ + +undefine(`FN') +define(`FN',` +void +tcNewElfExpected$1(void) +{ + int fd, result; + Elf$1_Ehdr *eh; + Elf *e; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr(new.elf,ELFCLASS$1) returns " + "the correct header."); + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + result = TET_PASS; + if ((eh = (Elf$1_Ehdr *) gelf_newehdr(e, ELFCLASS$1)) == NULL) { + TP_FAIL("gelf_newehdr("TS_NEWELF",ELFCLASS$1) failed: %s", + elf_errmsg(-1)); + goto done; + } + + CHECK_NEWEHDR(eh, $1); + + done: + (void) elf_end(e); + (void) close(fd); + (void) unlink(TS_NEWELF); + tet_result(result); +}') + +FN(`32') +FN(`64') + +/* + * Allocating a new Ehdr should mark it as dirty. + */ + +undefine(`FN') +define(`FN',` +void +tcNewElfFlagDirty$1(void) +{ + Elf *e; + Elf$1_Ehdr *eh; + int fd, flags, result; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("gelf_newehdr("TS_NEWELF",ELFCLASS$1) marks " + "the header as dirty."); + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + if ((eh = (Elf$1_Ehdr *) gelf_newehdr(e, ELFCLASS$1)) == NULL) { + TP_FAIL("gelf_newehdr("TS_NEWELF",ELFCLASS$1) failed: %s.", + elf_errmsg(-1)); + goto done; + } + + flags = elf_flagehdr(e, ELF_C_CLR, 0); + + result = (flags & ELF_F_DIRTY) == 0 ? TET_FAIL : TET_PASS; + + done: + (void) elf_end(e); + (void) close(fd); + (void) unlink(TS_NEWELF); + + tet_result(result); +}') + +FN(`32') +FN(`64') + +/* + * Allocating and updating an Elf_Ehdr works correctly. + */ + +define(`TS_REFELF',`"newehdr."') + +undefine(`FN') +define(`FN',` +void +tcUpdateElf$1$2(void) +{ + Elf$2_Ehdr *eh; + Elf *e; + int fd, reffd, result; + off_t offset; + size_t fsz; + void *t, *tref; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("The contents of the $1$2 Ehdr structure are " + "correctly updated."); + + t = tref = NULL; + fd = reffd = -1; + + TS_OPEN_FILE(e, TS_NEWELF, ELF_C_WRITE, fd); + + result = TET_UNRESOLVED; + + if ((eh = (Elf$2_Ehdr *) gelf_newehdr(e, ELFCLASS$2)) == NULL) { + TP_UNRESOLVED("gelf_newehdr(ELFCLASS$2) failed: %s", + elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2`'TOUPPER($1); + + if ((offset = elf_update(e, ELF_C_WRITE)) < 0) { + TP_UNRESOLVED("elf_update() failed: %s.", elf_errmsg(-1)); + goto done; + } + + fsz = gelf_fsize(e, ELF_T_EHDR, 1, EV_CURRENT); + + if (offset != fsz) { + TP_FAIL("elf_update() -> %d, expected %d.", offset, fsz); + goto done; + } + + (void) elf_end(e); e = NULL; + (void) close(fd); fd = -1; + + if ((t = malloc(fsz)) == NULL || + (tref = malloc(fsz)) == NULL) { + TP_UNRESOLVED("malloc(%d) failed.", fsz); + goto done; + } + + if ((fd = open(TS_NEWELF, O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open("TS_NEWELF") failed: %s", strerror(errno)); + goto done; + } + + if (read(fd, t, fsz) != fsz) { + TP_UNRESOLVED("read(%d) failed: %s", fsz, strerror(errno)); + goto done; + } + + if ((reffd = open(TS_REFELF "$1$2", O_RDONLY, 0)) < 0) { + TP_UNRESOLVED("open("TS_REFELF"$1$2) failed: %s.", + strerror(errno)); + goto done; + } + + if (read(reffd, tref, fsz) != fsz) { + TP_UNRESOLVED("read(%d) failed: %s.", fsz, strerror(errno)); + goto done; + } + + result = TET_PASS; + if (memcmp(t, tref, fsz) != 0) + TP_FAIL("memcmp("TS_NEWELF","TS_REFELF"$1$2) failed."); + + done: + (void) unlink(TS_NEWELF); + if (e) + (void) elf_end(e); + if (fd != -1) + (void) close(fd); + if (reffd != -1) + (void) close(reffd); + if (t) + free(t); + if (tref) + free(tref); + tet_result(result); +}') + +FN(`lsb',`32') +FN(`lsb',`64') +FN(`msb',`32') +FN(`msb',`64') diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/Makefile b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/Makefile new file mode 100644 index 0000000000..07295bdaf0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= xlate.m4 +TS_YAML= xlate + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/xlate.m4 b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/xlate.m4 new file mode 100644 index 0000000000..906211c444 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelf/tset/gelf_xlate/xlate.m4 @@ -0,0 +1,1354 @@ +/*- + * Copyright (c) 2006,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlate.m4 3174 2015-03-27 17:13:41Z emaste $ + */ + +#include +#include +#include +#include +#include + +#include "tet_api.h" +#include "elfts.h" + +include(`elfts.m4') + +IC_REQUIRES_VERSION_INIT(); + +#define NO_TESTCASE_FUNCTIONS /* only want the tables */ + +#define TS_XLATESZ 32 +#include "xlate_template.c" + +#undef TS_XLATESZ +#define TS_XLATESZ 64 +#include "xlate_template.c" + +static int +check_gelf_xlate(Elf_Data *xlator(Elf *e,Elf_Data *d, const Elf_Data *s, unsigned int enc), + Elf *e, int ed, Elf_Data *dst, Elf_Data *src, struct testdata *td, int ncopies) +{ + Elf_Data *dstret; + int result; + size_t msz; + + msz = td->tsd_msz; + result = TET_UNRESOLVED; + + /* Invoke translator */ + if ((dstret = xlator(e, dst, src, ed)) != dst) { + TP_FAIL("\"%s\" " __XSTRING(TC_XLATETOM) + ": %s", td->tsd_name, elf_errmsg(-1)); + return (result); + } + + /* Check return parameters. */ + if (dst->d_type != td->tsd_type || dst->d_size != msz*ncopies) { + TP_FAIL("\"%s\" type(ret=%d,expected=%d) " + "size (ret=%d,expected=%d).", td->tsd_name, + dst->d_type, td->tsd_type, dst->d_size, msz*ncopies); + return (result); + } + + return (TET_PASS); +} + +static const char *testfns[] = { + "xlate.lsb32", + "xlate.msb32", + "xlate.lsb64", + "xlate.msb64", + NULL +}; + +static int +tcDriver(int (*tf)(const char *fn, Elf *e)) +{ + int fd, result; + Elf *e; + const char **fn; + + result = TET_PASS; + for (fn = testfns; result == TET_PASS && *fn; fn++) { + + _TS_OPEN_FILE(e,*fn,ELF_C_READ,fd,;); + + if (e == NULL) { + result = TET_UNRESOLVED; + break; + } + + result = (*tf)(*fn, e); + + (void) elf_end(e); + (void) close(fd); + } + + return (result); +} + +/* + * Check byte conversions: + */ + +static int +_tcByte(const char *fn, Elf *e) +{ + Elf_Data dst, src; + int i, offset, sz, result; + char *filebuf, *membuf, *t, *ref; + + ref = td_L32_QUAD; + sz = sizeof(td_L32_QUAD); + + if ((membuf = malloc(sz*NCOPIES)) == NULL || + (filebuf = malloc(sz*NCOPIES+NOFFSET)) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + /* + * Check memory to file conversions. + */ + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t,ref,sz) + sz; + + src.d_buf = membuf; + src.d_size = sz*NCOPIES; + src.d_type = ELF_T_BYTE; + src.d_version = EV_CURRENT; + + TP_ANNOUNCE("\"%s\" Byte TOF() succeeds.", fn); + + for (offset = 0; offset < NOFFSET; offset++) { + /* + * LSB + */ + dst.d_buf = filebuf + offset; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (gelf_xlatetof(e,&dst,&src,ELFDATA2LSB) != &dst || + dst.d_size != sz*NCOPIES) { + TP_FAIL("LSB TOF() conversion."); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + TP_FAIL("LSB TOF() memcmp()."); + goto done; + } + + /* + * MSB + */ + dst.d_buf = filebuf + offset; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (gelf_xlatetof(e,&dst,&src,ELFDATA2MSB) != &dst || + dst.d_size != sz*NCOPIES) { + TP_FAIL("MSB TOF() conversion."); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + TP_FAIL("MSB TOF() memcmp()."); + goto done; + } + } + + /* + * Check file to memory conversions. + */ + + TP_ANNOUNCE("\"%s\" Byte TOM() succeeds.", fn); + + ref = td_M32_QUAD; + sz = sizeof(td_M32_QUAD); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t,ref,sz); + + src.d_size = sz*NCOPIES; + src.d_type = ELF_T_BYTE; + src.d_version = EV_CURRENT; + + /* + * LSB + */ + dst.d_buf = membuf; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (gelf_xlatetom(e,&dst,&src,ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES) { + TP_FAIL("LSB TOM() conversion."); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + TP_FAIL("LSB TOM() memcmp()."); + goto done; + } + + /* + * MSB + */ + dst.d_buf = membuf; + dst.d_size = sz*NCOPIES; + dst.d_version = EV_CURRENT; + + if (gelf_xlatetom(e,&dst,&src,ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES) { + TP_FAIL("MSB TOM() conversion."); + goto done; + } + + if (memcmp(membuf, filebuf+offset, sz*NCOPIES)) { + TP_FAIL("MSB TOM() memcmp()."); + goto done; + } + } + + result = TET_PASS; + + done: + if (membuf) + free(membuf); + if (filebuf) + free(filebuf); + + return (result); +} + +void +tcXlateByte(void) +{ + tet_result(tcDriver(_tcByte)); +} + +static int +_tpToM(const char *fn, Elf *e) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, offset, result; + char *srcbuf, *membuf, *t; + + srcbuf = NULL; /* file data (bytes) */ + membuf = NULL; /* memory data (struct) */ + + result = TET_PASS; + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + /* Loop over all types for this ELF class */ + for (; td->tsd_name; td++) { + + fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + if (msz == 0 || + fsz != td->tsd_fsz) { + TP_UNRESOLVED("\"%s\" %s: msz=%d fsz=%d td->fsz=%d.", + fn, td->tsd_name, msz, fsz, td->tsd_fsz); + goto done; + } + + assert(fsz == td->tsd_fsz); + + /* + * allocate space for NCOPIES of data + offset for file data and + * NCOPIES of memory data. + */ + if ((srcbuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL || + ((membuf = malloc(NCOPIES*msz))) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + + TP_ANNOUNCE("\"%s\" gelf_xlatetom(%s) succeeds.", fn, + td->tsd_name); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = t = srcbuf + offset; + src.d_size = fsz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + dst.d_buf = membuf; + dst.d_size = msz * NCOPIES; + dst.d_version = EV_CURRENT; + + + /* + * Check conversion of LSB encoded data. + */ + + /* copy `NCOPIES*fsz' bytes in `srcbuf+offset' */ + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_lsb, fsz); + t += fsz; + } + (void) memset(membuf, 0, NCOPIES*msz); + + if ((result = check_gelf_xlate(gelf_xlatetom,e, + ELFDATA2LSB, &dst,&src,td,NCOPIES)) != + TET_PASS) + goto done; + + /* + * Compare the retrieved data with the canonical + * value + */ + t = dst.d_buf; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_mem, msz)) { + TP_FAIL("\"%s\" \"%s\" LSB " + "memory compare failed.", fn, + td->tsd_name); + goto done; + } + t += msz; + } + + /* + * Check conversion of MSB encoded data. + */ + + t = srcbuf + offset; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_msb, fsz); + t += fsz; + } + (void) memset(membuf, 0, NCOPIES*msz); + if ((result = check_gelf_xlate(gelf_xlatetom,e, + ELFDATA2MSB, &dst,&src,td,NCOPIES)) != + TET_PASS) + goto done; + + /* compare the retrieved data with the canonical value */ + t = dst.d_buf; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_mem, msz)) { + TP_FAIL("\"%s\" \"%s\" MSB " + "memory compare failed.", fn, + td->tsd_name); + goto done; + } + t += msz; + } + } + + free(srcbuf); srcbuf = NULL; + free(membuf); membuf = NULL; + } + + done: + if (srcbuf) + free(srcbuf); + if (membuf) + free(membuf); + + return (result); +} + +void +tcXlateToM(void) +{ + tet_result(tcDriver(_tpToM)); +} + +/* + * Check non-byte conversions from memory to file. + */ +static int +_tpToF(const char *fn, Elf *e) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, offset, result; + char *filebuf, *membuf, *t; + + filebuf = NULL; /* file data (bytes) */ + membuf = NULL; /* memory data (struct) */ + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + result = TET_PASS; + + /* Loop over all types */ + for (; td->tsd_name; td++) { + + fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + if (msz == 0 || + fsz != td->tsd_fsz) { + TP_UNRESOLVED("? \"%s\" %s: msz=%d fsz=%d td->fsz=%d.", + fn, td->tsd_name, msz, fsz, td->tsd_fsz); + goto done; + } + + assert(msz > 0); + assert(fsz == td->tsd_fsz); + + /* + * allocate space for NCOPIES of data + offset for file data and + * NCOPIES of memory data. + */ + if ((filebuf = malloc(NCOPIES*fsz+NOFFSET)) == NULL || + ((membuf = malloc(NCOPIES*msz))) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + + TP_ANNOUNCE("\"%s\" gelf_xlatetof(%s) succeeds.", fn, + td->tsd_name); + + for (offset = 0; offset < NOFFSET; offset++) { + + src.d_buf = membuf; + src.d_size = msz * NCOPIES; + src.d_type = td->tsd_type; + src.d_version = EV_CURRENT; + + /* + * Check LSB conversion. + */ + + /* + * Copy `NCOPIES' of canonical memory data to the + * src buffer. + */ + t = membuf; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_mem, msz); + t += msz; + } + (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET); + + dst.d_buf = filebuf + offset; + dst.d_size = fsz * NCOPIES; + dst.d_version = EV_CURRENT; + + if ((result = check_gelf_xlate(gelf_xlatetof, e, + ELFDATA2LSB, &dst, &src, td, NCOPIES)) != + TET_PASS) + goto done; + + /* compare converted data to canonical form */ + t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_lsb, fsz)) { + TP_FAIL("\"%s\" \"%s\" LSB memory " + "compare.", fn, td->tsd_name); + goto done; + } + t += fsz; + } + + /* + * Check MSB conversion. + */ + t = membuf; + for (i = 0; i < NCOPIES; i++) { + (void) memcpy(t, td->tsd_mem, msz); + t += msz; + } + (void) memset(filebuf, 0, NCOPIES*fsz+NOFFSET); + + dst.d_buf = filebuf + offset; + dst.d_size = fsz * NCOPIES; + dst.d_version = EV_CURRENT; + + if ((result = check_gelf_xlate(gelf_xlatetof, e, + ELFDATA2MSB, &dst, &src, td, NCOPIES)) == + TET_PASS) + goto done; + + /* compare converted data to canonical form */ + t = filebuf + offset; + for (i = 0; i < NCOPIES; i++) { + if (memcmp(t, td->tsd_msb, fsz)) { + TP_FAIL("\"%s\" \"%s\" MSB " + "memory compare.", fn, + td->tsd_name); + goto done; + } + t += fsz; + } + } + + free(filebuf); filebuf = NULL; + free(membuf); membuf = NULL; + } + + done: + if (filebuf) + free(filebuf); + if (membuf) + free(membuf); + + return (result); +} + +void +tcXlateToF(void) +{ + tet_result(tcDriver(_tpToF)); +} + + +/* + * Various checks for invalid arguments. + */ + +static int +_tpNullArgs(const char *fn, Elf *e) +{ + Elf_Data ed; + int result; + + TP_ANNOUNCE("gelf_xlatetof(%s)/gelf_xlatetom(%s)" + " with NULL arguments fails with ELF_E_ARGUMENT.", + fn, fn); + + result = TET_PASS; + + if (gelf_xlatetof(NULL, NULL, NULL, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetof(e, NULL, &ed, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetof(e, &ed, NULL, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetom(NULL, NULL, NULL, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetom(e, NULL, &ed, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, NULL, ELFDATANONE) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + return (result); +} + +void +tcArgsNull(void) +{ + tet_result(tcDriver(_tpNullArgs)); +} + + +static int +_tpBadType(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + char buf[1024]; + + TP_ANNOUNCE("gelf_xlatetof(%s)/" + "gelf_xlatetom(%s) with an out of range type " + "fails with ELF_E_DATA.", fn, fn); + + result = TET_PASS; + + es.d_version = ed.d_version = EV_CURRENT; + es.d_buf = ed.d_buf = buf; + es.d_size = ed.d_size = sizeof(buf); + + es.d_type = (Elf_Type) -1; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + es.d_type = ELF_T_NUM; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + return (result); +} + +void +tcArgsBadType(void) +{ + tet_result(tcDriver(_tpBadType)); +} + +static int +_tpBadEncoding(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + + TP_ANNOUNCE("gelf_xlatetof/" + "gelf_xlatetom()(*,*,BADENCODING) " + "fails with ELF_E_ARGUMENT."); + + result = TET_PASS; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE-1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (gelf_xlatetof(e, &ed, &es, ELFDATA2MSB+1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE-1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + else if (gelf_xlatetom(e, &ed, &es, ELFDATA2MSB+1) != NULL || + elf_errno() != ELF_E_ARGUMENT) + result = TET_FAIL; + + return (result); +} + +void +tcArgsBadEncoding(void) +{ + tet_result(tcDriver(_tpBadEncoding)); +} + +static int +_tpDstSrcVersion(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("gelf_xlateto[fm]() with unequal src,dst versions " + "fails with ELF_E_UNIMPL."); + + es.d_buf = ed.d_buf = buf; + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_NONE; + + result = TET_PASS; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_UNIMPL) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_UNIMPL) + result = TET_FAIL; + + return (result); +} + +void +tcArgsDstSrcVersion(void) +{ + tet_result(tcDriver(_tpDstSrcVersion)); +} + +/* + * Check for an unimplemented type. + */ +static int +_tpUnimplemented(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int i, result; + char *buf; + + buf = NULL; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("gelf_xlateto[fm]() on unimplemented types will " + "fail with ELF_E_UNIMPL."); + + /* + * allocate a buffer that is large enough for any potential + * ELF data structure. + */ + if ((buf = malloc(1024)) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + ed.d_buf = es.d_buf = buf; + ed.d_size = es.d_size = 1024; + ed.d_version = es.d_version = EV_CURRENT; + + result = TET_PASS; + + for (i = 0; i < ELF_T_NUM; i++) { + switch (i) { + case ELF_T_MOVEP: + break; + + case ELF_T_SXWORD: /* unimplemented for 32 bit ELF */ + case ELF_T_XWORD: + if (gelf_getclass(e) == ELFCLASS64) + continue; + break; + default: + continue; + } + + es.d_type = i; + + if (gelf_xlatetof(e, &ed, &es, ELFDATA2LSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + TP_FAIL("TOF/LSB/type=%d.", i); + goto done; + } + + if (gelf_xlatetof(e, &ed, &es, ELFDATA2MSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + TP_FAIL("TOF/MSB/type=%d.", i); + goto done; + } + + if (gelf_xlatetom(e, &ed, &es, ELFDATA2LSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + TP_FAIL("TOM/LSB/type=%d.", i); + goto done; + } + + if (gelf_xlatetom(e, &ed, &es, ELFDATA2MSB) != NULL || + elf_errno() != ELF_E_UNIMPL) { + TP_FAIL("fail: TOM/MSB/type=%d.", i); + goto done; + } + } + +done: + if (buf) + free(buf); + return (result); +} + +void +tcArgsUnimplemented(void) +{ + tet_result(tcDriver(_tpUnimplemented)); +} + +/* + * Check for null buffer pointers. + */ +static int +_tpNullDataPtr(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("gelf_xlateto[fm](%s) with a null " + "src,dst buffer pointer fails with ELF_E_DATA.", fn); + + result = TET_PASS; + + es.d_type = ELF_T_BYTE; + es.d_size = ed.d_size = sizeof(buf); + es.d_version = EV_CURRENT; + ed.d_version = EV_CURRENT; + + es.d_buf = NULL; + ed.d_buf = buf; + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + es.d_buf = buf; + ed.d_buf = NULL; + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) + result = TET_FAIL; + + return (result); +} + +void +tcBufferNullDataPtr(void) +{ + tet_result(tcDriver(_tpNullDataPtr)); +} + +/* + * Misaligned data. + */ + +static int +_tpMisaligned(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + size_t fsz, msz; + char *sb, *db; + struct testdata *td; + + sb = db = NULL; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("\"%s\" misaligned buffers are rejected with " + "ELF_E_DATA.", fn); + + if ((sb = malloc(1024)) == NULL || + (db = malloc(1024)) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + result = TET_PASS; + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + for (; td->tsd_name; td++) { + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + es.d_type = td->tsd_type; + es.d_version = EV_CURRENT; + + /* Misalign the destination for to-memory xfers */ + es.d_size = (1024 / fsz) * fsz; /* round down */ + es.d_buf = sb; + + ed.d_buf = db + 1; /* guaranteed to be misaliged */ + ed.d_version = EV_CURRENT; + ed.d_size = 1024; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOM alignment.", td->tsd_name); + goto done; + } + + /* Misalign the source for to-file xfers */ + es.d_buf = sb + 1; + es.d_size = (1024/msz) * msz; /* round down */ + ed.d_buf = db; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOF alignment.", + td->tsd_name); + goto done; + } + } + +done: + if (sb) + free(sb); + if (db) + free(db); + return (result); +} + +void +tcBufferMisaligned(void) +{ + tet_result(tcDriver(_tpMisaligned)); +} + +/* + * Overlapping buffers. + */ +static int +_tpOverlap(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + char buf[sizeof(int)]; + + TP_ANNOUNCE("\"%s\" overlapping buffers are rejected with " + "ELF_E_DATA.", fn); + + es.d_buf = buf; ed.d_buf = buf+1; + es.d_version = ed.d_version = EV_CURRENT; + es.d_size = ed.d_size = sizeof(buf); + es.d_type = ELF_T_BYTE; + + result = TET_PASS; + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("gelf_xlatetof()."); + goto done; + } + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("gelf_xlatetom()."); + goto done; + } + +done: + return (result); +} + +void +tcBufferOverlap(void) +{ + tet_result(tcDriver(_tpOverlap)); +} + +/* + * Non-integral number of src elements. + */ +static int +_tpSrcExtra(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + size_t fsz, msz; + char *sb, *db; + struct testdata *td; + + TP_ANNOUNCE("\"%s\" mis-sized buffers are rejected with " + "ELF_E_DATA.", fn); + + sb = db = NULL; + if ((sb = malloc(1024)) == NULL || + (db = malloc(1024)) == NULL) { + TP_UNRESOLVED("malloc() failed."); + goto done; + } + + result = TET_PASS; + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + for (; td->tsd_name; td++) { + fsz = td->tsd_fsz; + msz = td->tsd_msz; + + es.d_type = td->tsd_type; + es.d_version = EV_CURRENT; + ed.d_version = EV_CURRENT; + ed.d_buf = db; + es.d_buf = sb; + ed.d_size = 1024; + + /* Pad src bytes with extra bytes for to memor */ + es.d_size = fsz+1; + + if (gelf_xlatetom(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOM buffer size.", td->tsd_name); + goto done; + } + + es.d_size = msz+1; + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOF buffer size.", td->tsd_name); + goto done; + } + } + +done: + if (sb) + free(sb); + if (db) + free(db); + + return (result); +} + +void +tcBufferSrcExtra(void) +{ + tet_result(tcDriver(_tpSrcExtra)); +} + +static int +_tpDstTooSmall(const char *fn, Elf *e) +{ + Elf_Data ed, es; + int result; + struct testdata *td; + size_t fsz, msz; + char buf[1024]; + + result = TET_PASS; + + TP_ANNOUNCE("\"%s\" too small destination buffers are " + "rejected with ELF_E_DATA.", fn); + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + for (; td->tsd_name; td++) { + msz = td->tsd_msz; + fsz = td->tsd_fsz; + + es.d_type = td->tsd_type; + es.d_version = ed.d_version = EV_CURRENT; + es.d_buf = ed.d_buf = buf; + + es.d_size = (sizeof(buf) / msz) * msz; + ed.d_size = 1; /* too small a size */ + + if (gelf_xlatetof(e, &ed, &es, ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOF dst size.", td->tsd_name); + goto done; + } + + es.d_size = (sizeof(buf) / fsz) * fsz; + if (gelf_xlatetom(e, &ed,&es,ELFDATANONE) != NULL || + elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" TOF dst size.", td->tsd_name); + goto done; + } + } + +done: + return (result); +} + +void +tcBufferDstTooSmall(void) +{ + tet_result(tcDriver(_tpDstTooSmall)); +} + +static int +_tpSharedBufferByte(const char *fn, Elf *e) +{ + int i, result; + size_t sz; + Elf_Data dst, src; + char *membuf, *t, *ref; + +#define PREPARE_SHARED(T,SZ) do { \ + src.d_buf = dst.d_buf = membuf; \ + src.d_size = dst.d_size = (SZ) * NCOPIES; \ + src.d_type = dst.d_type = (T); \ + src.d_version = dst.d_version = EV_CURRENT; \ + } while (0) + +#define VERIFY(R,SZ) do { \ + t = dst.d_buf; \ + for (i = 0; i < NCOPIES; i++, t += (SZ)) \ + if (memcmp((R), t, (SZ))) { \ + TP_FAIL("LSB TOF() memcmp()."); \ + goto done; \ + } \ + } while (0) + + membuf = NULL; + ref = TYPEDEFNAME(L,QUAD); + sz = sizeof(TYPEDEFNAME(L,QUAD)); + + if ((membuf = malloc(sz * NCOPIES)) == NULL) { + TP_UNRESOLVED("\"%s\" malloc() failed.", fn); + return (TET_UNRESOLVED); + } + + result = TET_PASS; + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, ref, sz) + sz; + + TP_ANNOUNCE("\"%s\" byte TOF() on a shared dst/src arena " + "succeeds.", fn); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + TP_FAIL("\"%s\" LSB TOF() conversion: %s.", fn, + elf_errmsg(-1)); + goto done; + } + VERIFY(ref,sz); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (gelf_xlatetof(e, &dst, &src, ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + TP_FAIL("\"%s\" MSB TOF() conversion: %s.", fn, + elf_errmsg(-1)); + goto done; + } + VERIFY(ref,sz); + + TP_ANNOUNCE("assertion: \"%s\" byte TOM() on a shared dst/src arena " + "succeeds.", fn); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (gelf_xlatetom(e, &dst, &src, ELFDATA2LSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + TP_FAIL("\"%s\" LSB TOM() conversion: %s.", fn, + elf_errmsg(-1)); + goto done; + } + VERIFY(ref,sz); + + PREPARE_SHARED(ELF_T_BYTE, sz); + if (gelf_xlatetom(e, &dst, &src, ELFDATA2MSB) != &dst || + dst.d_size != sz * NCOPIES || + dst.d_buf != src.d_buf) { + TP_FAIL("\"%s\" MSB TOM() conversion: %s.", fn, + elf_errmsg(-1)); + goto done; + } + VERIFY(ref,sz); + + done: + if (membuf) + free(membuf); + + return (result); +} + + +void +tcBufferSharedBufferByte(void) +{ + tet_result(tcDriver(_tpSharedBufferByte)); +} + +static int +_tpToMShared(const char *fn, Elf *e) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, r, result; + char *membuf, *t; + + membuf = NULL; + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + + result = TET_PASS; + + for (; td->tsd_name; td++) { + + TP_ANNOUNCE("\"%s\" in-place gelf_xlatetom" + "(\"%s\").", fn, td->tsd_name); + + fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + assert(msz >= fsz); + + if ((membuf = malloc(fsz * NCOPIES)) == NULL) { + TP_UNRESOLVED("\"%s\" \"%s\" malloc() failed.", + fn, td->tsd_name); + goto done; + } + + /* + * In-place conversion of LSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_lsb, fsz) + fsz; + + PREPARE_SHARED(td->tsd_type, fsz); + r = gelf_xlatetom(e, &dst, &src, ELFDATA2LSB) == &dst; + + if (fsz < msz) { + /* conversion should fail with ELF_E_DATA */ + if (r || elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" \"%s\" LSB TOM() succeeded " + "with fsz < msz", fn, td->tsd_name); + goto done; + } + free(membuf); membuf = NULL; + continue; + } + + /* conversion should have succeeded. */ + if (!r) { + TP_FAIL("\"%s\" \"%s\" LSB TOM() failed.", + fn, td->tsd_name); + goto done; + } + + VERIFY(td->tsd_mem,msz); + + /* + * In-place conversion of MSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_msb, fsz) + fsz; + + PREPARE_SHARED(td->tsd_type, fsz); + r = gelf_xlatetom(e, &dst, &src, ELFDATA2MSB) == &dst; + + if (fsz < msz) { + /* conversion should fail with ELF_E_DATA */ + if (r || elf_errno() != ELF_E_DATA) { + TP_FAIL("\"%s\" \"%s\" MSB TOM() succeeded " + "with fsz < msz", fn, td->tsd_name); + goto done; + } + free(membuf); membuf = NULL; + continue; + } + + /* conversion should have succeeded. */ + if (!r) { + TP_FAIL("\"%s\" \"%s\" MSB TOM() failed.", + fn, td->tsd_name); + goto done; + } + + VERIFY(td->tsd_mem,msz); + + } + + done: + if (membuf) + free(membuf); + return (result); +} + +void +tcXlateToMShared(void) +{ + tet_result(tcDriver(_tpToMShared)); +} + +static int +_tpToFShared(const char *fn, Elf *e) +{ + Elf_Data dst, src; + struct testdata *td; + size_t fsz, msz; + int i, result; + char *membuf, *t; + + membuf = NULL; + + td = gelf_getclass(e) == ELFCLASS32 ? tests32 : tests64; + result = TET_PASS; + + for (; td->tsd_name; td++) { + + TP_ANNOUNCE("\"%s\" in-place gelf_xlatetof(\"%s\").", + fn, td->tsd_name); + + fsz = gelf_fsize(e, td->tsd_type, 1, EV_CURRENT); + msz = td->tsd_msz; + + assert(msz >= fsz); + + if ((membuf = malloc(msz * NCOPIES)) == NULL) { + TP_UNRESOLVED("\"%s\" \"%s\" malloc() failed.", + fn, td->tsd_name); + goto done; + } + + /* + * In-place conversion to LSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_mem, msz) + msz; + + PREPARE_SHARED(td->tsd_type, msz); + if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) != &dst) { + TP_FAIL("\"%s\" \"%s\" LSB TOF() failed: %s.", + fn, td->tsd_name, elf_errmsg(-1)); + goto done; + } + VERIFY(td->tsd_lsb,fsz); + + /* + * In-place conversion to MSB data. + */ + + t = membuf; + for (i = 0; i < NCOPIES; i++) + t = memcpy(t, td->tsd_mem, msz) + msz; + + PREPARE_SHARED(td->tsd_type, msz); + if (gelf_xlatetof(e, &dst, &src, ELFDATA2MSB) != &dst) { + TP_FAIL("\"%s\" \"%s\" MSB TOF() failed: %s.", + fn, td->tsd_name, elf_errmsg(-1)); + goto done; + } + VERIFY(td->tsd_msb,fsz); + } + + done: + if (membuf) + free(membuf); + return (result); +} + +void +tcXlateToFShared(void) +{ + tet_result(tcDriver(_tpToFShared)); +} diff --git a/contrib/elftoolchain/tests/tet/libelftc/Makefile b/contrib/elftoolchain/tests/tet/libelftc/Makefile new file mode 100644 index 0000000000..0899ff97ab --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/Makefile @@ -0,0 +1,6 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. +SUBDIR= tset + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/libelftc/tet_scen b/contrib/elftoolchain/tests/tet/libelftc/tet_scen new file mode 100644 index 0000000000..28f7f97cc5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tet_scen @@ -0,0 +1,8 @@ +# $Id: tet_scen 2861 2013-01-05 09:35:42Z jkoshy $ + +all + ^elftc_string_table + ^elftc_version + +elftc_string_table :include:/tset/elftc_string_table/tet_scen +elftc_version :include:/tset/elftc_version/tet_scen diff --git a/contrib/elftoolchain/tests/tet/libelftc/tetbuild.cfg b/contrib/elftoolchain/tests/tet/libelftc/tetbuild.cfg new file mode 100644 index 0000000000..c2369b074a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tetbuild.cfg @@ -0,0 +1,5 @@ +# $Id: tetbuild.cfg 2826 2012-12-29 16:39:18Z jkoshy $ + +TET_BUILD_TOOL=make +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libelftc/tetclean.cfg b/contrib/elftoolchain/tests/tet/libelftc/tetclean.cfg new file mode 100644 index 0000000000..380d795e26 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tetclean.cfg @@ -0,0 +1,7 @@ +# $Id: tetclean.cfg 2826 2012-12-29 16:39:18Z jkoshy $ + +TET_CLEAN_TOOL=make +TET_CLEAN_FILE=clean + +TET_OUTPUT_CAPTURE=True +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/libelftc/tetexec.cfg b/contrib/elftoolchain/tests/tet/libelftc/tetexec.cfg new file mode 100644 index 0000000000..eda10f771e --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tetexec.cfg @@ -0,0 +1,3 @@ +# $Id: tetexec.cfg 2826 2012-12-29 16:39:18Z jkoshy $ + +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile b/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile new file mode 100644 index 0000000000..b8e5bde59a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. +SUBDIR= +SUBDIR+= elftc_string_table +SUBDIR+= elftc_version + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile.tset b/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile.tset new file mode 100644 index 0000000000..dc637a9026 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/Makefile.tset @@ -0,0 +1,11 @@ +# $Id: Makefile.tset 3021 2014-04-17 16:32:00Z jkoshy $ + +# All the test cases in this test suite need -lelftc. In addition, +# a few need -lelf. +DPADD+= ${LIBELFTC} ${LIBELF} +LDADD+= -lelftc -lelf + +GENERATE_TEST_SCAFFOLDING= yes + +# Test cases do not supply manual pages. +NOMAN= noman diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/Makefile b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/Makefile new file mode 100644 index 0000000000..84bc8ac81d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/Makefile @@ -0,0 +1,9 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= string_table.m4 + +LDADD+= -L${LIBELF} -lelf + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/string_table.m4 b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/string_table.m4 new file mode 100644 index 0000000000..74e66c99c1 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_string_table/string_table.m4 @@ -0,0 +1,985 @@ +/*- + * Copyright (c) 2013 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: string_table.m4 3021 2014-04-17 16:32:00Z jkoshy $ + */ + +/* + * include(`elfts.m4') + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tet_api.h" + +/* + * A list of test strings. + * + * For the curious, these are titles of stories by Cordwainer Smith. + */ + +static const char *test_strings[] = { + "Mark Elf", + "Scanners Live in Vain", + "The Dead Lady of Clown Town", + "The Lady Who Sailed the \"The Soul\"", + "No, No, Not Rogov!", + NULL +}; + +static const int nteststrings = sizeof(test_strings) / sizeof(test_strings[0]); + +static char test_image[] = { + 0, + 'M', 'a', 'r', 'k', ' ', 'E', 'l', 'f', 0, + 'S', 'c', 'a', 'n', 'n', 'e', 'r', 's', ' ', + 'L', 'i', 'v', 'e', ' ', 'i', 'n', ' ', 'V', 'a', 'i', 'n', 0, + 'T', 'h', 'e', ' ', 'D', 'e', 'a', 'd', ' ', + 'L', 'a', 'd', 'y', ' ', 'o', 'f', ' ', 'C', 'l', 'o', 'w', 'n', ' ', + 'T', 'o', 'w', 'n', 0, + 'T', 'h', 'e', ' ', 'L', 'a', 'd', 'y', ' ', 'W', 'h', 'o', ' ', + 'S', 'a', 'i', 'l', 'e', 'd', ' ', 't', 'h', 'e', ' ', + '"', 'T', 'h', 'e', 'S', 'o', 'u', 'l', '"', 0, + 'N', 'o', ',', ' ', 'N', 'o', ',', ' ', 'N', 'o', 't', ' ', + 'R', 'o', 'g', 'o', 'v', '!', 0 +}; + +#define UNKNOWN_STRING "Don't Panic!" + +/* + * Verify that strings are inserted at the expected offsets, and that + * the returned value is equivalent to the original string. + */ +void +tcInsertReturnValues(void) +{ + int result; + const char **s; + unsigned int expectedindex, hashindex; + Elftc_String_Table *table; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Insertion returns the expected offsets."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + expectedindex = 1; + /* Insert test strings. */ + for (s = test_strings; *s != NULL; s++) { + hashindex = elftc_string_table_insert(table, *s); + if (hashindex != expectedindex) { + TP_FAIL("incorrect hash index: expected %d, actual %d", + expectedindex, hashindex); + goto done; + } + + expectedindex += strlen(*s) + 1; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + tet_result(result); +} + +/* + * Verify that multiple insertions of the same string yield the same + * return values and offsets. + */ + +void +tcInsertDuplicate(void) +{ + const char **s; + int n, result; + Elftc_String_Table *table; + unsigned int hindex, *hashrecord; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Multiple insertions return the same offset value."); + + hashrecord = NULL; + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + if ((hashrecord = malloc(nteststrings*sizeof(*hashrecord))) == NULL) { + TP_UNRESOLVED("memory allocation failed."); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + hashrecord[n] = elftc_string_table_insert(table, *s); + + /* Re-insert, and verify the returned pointers and offsets. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + hindex = elftc_string_table_insert(table, *s); + + if (hindex != hashrecord[n]) { + TP_FAIL("incorrect hash index: expected %d, actual %d", + hashrecord[n], hindex); + goto done; + } + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + free(hashrecord); + + tet_result(result); +} + +/* + * Verify that the lookup() API returns the expected + * values. + */ + +void +tcLookupReturn(void) +{ + int result; + const char **s, *str; + unsigned int expectedindex, hashindex; + Elftc_String_Table *table; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("A lookup after an insertion returns the correct " + "string."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert test strings. */ + for (s = test_strings; *s != NULL; s++) + (void) elftc_string_table_insert(table, *s); + + expectedindex = 1; + for (s = test_strings; *s != NULL; s++) { + hashindex = elftc_string_table_lookup(table, *s); + + if (hashindex != expectedindex) { + TP_FAIL("incorrect hash index: expected %d, actual %d", + expectedindex, hashindex); + goto done; + } + + str = elftc_string_table_to_string(table, hashindex); + + if (str == NULL || strcmp(str, *s)) { + TP_FAIL("Lookup of \"%s\" returned \"%s\".", *s, + str); + goto done; + } + + expectedindex += strlen(*s) + 1; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + tet_result(result); +} + +/* + * Verify that multiple lookups return the same pointer + * and string offset. + */ + +void +tcLookupDuplicate(void) +{ + int n, result; + const char **s, *str1, *str2; + unsigned int hindex1, hindex2, *hashrecord; + Elftc_String_Table *table; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Multiple invocations of lookup on a valid string " + "return the same value."); + + hashrecord = NULL; + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + if ((hashrecord = malloc(nteststrings*sizeof(*hashrecord))) == NULL) { + TP_UNRESOLVED("memory allocation failed."); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + hashrecord[n] = elftc_string_table_insert(table, *s); + + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + hindex1 = elftc_string_table_lookup(table, *s); + hindex2 = elftc_string_table_lookup(table, *s); + + if (hindex1 != hindex2 || hindex1 != hashrecord[n]) { + TP_FAIL("incorrect hash index: expected %d, " + "actual %d & %d", hashrecord[n], hindex1, + hindex2); + goto done; + } + + str1 = elftc_string_table_to_string(table, hindex1); + str2 = elftc_string_table_to_string(table, hindex2); + if (str1 == NULL || str2 == NULL || str1 != str2 || + strcmp(str1, *s)) { + TP_FAIL("Lookup of \"%s\" returned \"%s\" & \"%s\".", + *s, str1, str2); + goto done; + } + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + free(hashrecord); + + tet_result(result); +} + +/* + * Verify that a deleted string cannot be subsequently looked up. + */ + +void +tcDeletionCheck(void) +{ + const char **s; + Elftc_String_Table *table; + int hindex, n, result, status; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Lookup after deletion should fail."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + (void) elftc_string_table_insert(table, *s); + + /* Delete strings, and look them up. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + status = elftc_string_table_remove(table, *s); + if (status == 0) { + TP_FAIL("Deletion of \"%s\" failed.", *s); + goto done; + } + + hindex = elftc_string_table_lookup(table, *s); + if (hindex != 0) { + TP_FAIL("Lookup of \"%s\" succeeded unexpectedly."); + goto done; + } + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); + +} + +/* + * Verify that a deleted string is re-inserted at the old index. + */ + +void +tcDeletionInsertion(void) +{ + const char **s; + unsigned int *hashrecord, hindex; + Elftc_String_Table *table; + int n, result, status; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Re-insertion of a string after deletion should " + "return the prior offset."); + + hashrecord = NULL; + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + if ((hashrecord = malloc(nteststrings*sizeof(*hashrecord))) == NULL) { + TP_UNRESOLVED("memory allocation failed."); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + hashrecord[n] = elftc_string_table_insert(table, *s); + + /* Delete strings ... */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + status = elftc_string_table_remove(table, *s); + if (status == 0) { + TP_UNRESOLVED("Deletion of \"%s\" failed.", *s); + goto done; + } + } + + /* and re-insert them, and check. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + hindex = elftc_string_table_insert(table, *s); + + if (hindex != hashrecord[n]) { + TP_FAIL("Re-insertion at a different offset: " + "old %d, new %p", hashrecord[n], hindex); + goto done; + } + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + if (hashrecord) + free(hashrecord); + + tet_result(result); + +} + +/* + * Verify that the 2nd deletion of the string fails. + */ + +void +tcDoubleDeletion(void) +{ + const char **s; + int n, result, status; + Elftc_String_Table *table; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Double deletion of a string should fail."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + (void) elftc_string_table_insert(table, *s); + + /* Delete strings twice. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) { + status = elftc_string_table_remove(table, *s); + if (status == 0) { + TP_FAIL("First deletion of \"%s\" failed.", *s); + goto done; + } + status = elftc_string_table_remove(table, *s); + if (status != 0) { + TP_FAIL("Second deletion of \"%s\" succeeded.", *s); + goto done; + } + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); + +} + +/* + * Verify that deletion of an unknown string fails. + */ + +void +tcUnknownDeletion(void) +{ + const char **s; + int n, result, status; + Elftc_String_Table *table; + + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Deletion of an unknown string should fail."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert test strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + (void) elftc_string_table_insert(table, *s); + + status = elftc_string_table_remove(table, UNKNOWN_STRING); + if (status != 0) { + TP_FAIL("Deletion of an unknown string succeeded."); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); + +} + +/* + * Ensure that string indices remain constant after the underlying + * string pool is resized/moved. + */ + +#define TC_STRING_SIZE 64 +#define TC_INSERT_SIZE 20 + +void +tcIndicesAfterRebase(void) +{ + int j, n, result; + const char *str1, *str2; + char buf[TC_STRING_SIZE]; + Elftc_String_Table *table; + unsigned int offset1, offset2, expectedoffset; + + n = 0; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Indices are consistent after a pool resize."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert test strings. */ +#define TC_BUILD_STRING(buf, n) do { \ + (void) snprintf(buf, sizeof(buf), "%-*.*d", \ + TC_INSERT_SIZE - 1, TC_INSERT_SIZE - 1, n); \ + } while (0) + + TC_BUILD_STRING(buf, n); + + offset1 = elftc_string_table_insert(table, buf); + str1 = elftc_string_table_to_string(table, offset1); + + if (offset1 == 0 || str1 == NULL) { + TP_UNRESOLVED("Initialization failed."); + goto done; + } + + n++; + + /* + * Insert unique strings till we detect a move of the initial + * string. + */ + do { + + TC_BUILD_STRING(buf, n); + + if ((offset2 = elftc_string_table_insert(table, buf)) == 0) { + TP_UNRESOLVED("String insertion failed at %d", n); + goto done; + } + + if ((str2 = elftc_string_table_to_string(table, offset1)) == + NULL) { + TP_UNRESOLVED("String looked failed at %d", n); + goto done; + } + + n++; + } while (str2 == str1); + + /* + * Verify the offset for each string inserted so far. + */ + expectedoffset = 1; + for (j = 0; j < n; j++) { + TC_BUILD_STRING(buf, j); + offset1 = elftc_string_table_lookup(table, buf); + if (offset1 != expectedoffset) { + TP_FAIL("Offset mismatch: string #%d, " + "expected %d, actual %d", j, expectedoffset, + offset1); + goto done; + } + expectedoffset += TC_INSERT_SIZE; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); +} + +void +tcEmptyImage(void) +{ + int result; + size_t tblsz; + const char *image; + Elftc_String_Table *table; + + TP_ANNOUNCE("Check the image for an empty table."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + tblsz = 0; + image = elftc_string_table_image(table, &tblsz); + if (image == NULL) { + TP_FAIL("Null image returned."); + goto done; + } + + if (*image != 0 || tblsz != 1) { + TP_FAIL("Incorrect image parameters: [0]=%d, sz=%d", + *image, tblsz); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); +} + +void +tcImageDeleted(void) +{ + const char **s; + int n, result; + size_t tblsz; + const char *image; + Elftc_String_Table *table; + + TP_ANNOUNCE("Check the image for an empty table."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + /* Insert, then delete a set of strings. */ + for (n = 0, s = test_strings; *s != NULL; s++, n++) + if (elftc_string_table_insert(table, *s) == 0) { + TP_UNRESOLVED("String insertion of \"%s\" failed.", + *s); + goto done; + } + + for (n = 0, s = test_strings; *s != NULL; s++, n++) + if (elftc_string_table_remove(table, *s) == 0) { + TP_UNRESOLVED("String deletion of \"%s\" failed.", + *s); + goto done; + } + + /* Check for an empty table. */ + tblsz = 0; + image = elftc_string_table_image(table, &tblsz); + if (image == NULL) { + TP_FAIL("Null image returned."); + goto done; + } + + if (*image != 0 || tblsz != 1) { + TP_FAIL("Incorrect image parameters: [0]=%d, sz=%d", + *image, tblsz); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + + tet_result(result); +} + +static int +validate_string_table(int nstrings, const char *image, size_t imagesz, + const char **strings) +{ + int n, result, *seen; + const char *s, *end; + + if (*image != '\0') + return (0); + + if (nstrings == 0) + return (1); + + if ((seen = calloc(nstrings, sizeof(int))) == NULL) + return (0); + + /* + * Each string in the image should be in strings[], + * and vice-versa. + */ + s = image + 1; + end = image + imagesz; + while (s < end) { + /* Look for this string in the strings[] array. */ + for (n = 0; n < nstrings; n++) + if (strcmp(s, strings[n]) == 0) { + seen[n] = 1; + break; + } + if (n == nstrings) /* Not in the strings[] array. */ + goto fail; + + s += strlen(s) + 1; + } + + /* Verify all strings in the array were seen. */ + for (n = 0; n < nstrings; n++) + if (seen[n] == 0) + goto fail; + + free(seen); + + return (1); + +fail: + free(seen); + return (0); +} + +void +tcImageInsertOnly(void) +{ + int result; + const char **s; + const char *image; + Elftc_String_Table *table; + size_t expectedsize, imagesz; + + TP_ANNOUNCE("Insertion returns the expected image."); + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + result = TET_PASS; + + expectedsize = 1; + for (s = test_strings; *s != NULL; s++) { + expectedsize += strlen(*s) + 1; + if(elftc_string_table_insert(table, *s) == 0) { + TP_UNRESOLVED("String insertion failed for \"%s\".", + *s); + goto done; + } + } + + imagesz = 0; + image = elftc_string_table_image(table, &imagesz); + + if (image == NULL || imagesz != expectedsize) { + TP_FAIL("Incorrect image parameters: [0]=%d, sz=%d != %d", + *image, imagesz, expectedsize); + goto done; + } + + if (!validate_string_table(nteststrings - 1, image, imagesz, + test_strings)) { + TP_FAIL("Image mismatch."); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + tet_result(result); +} + +void +tcImagePartiallyDeleted(void) +{ + int n, nstr, result; + Elftc_String_Table *table; + size_t expectedsize, imagesz; + const char *image, **s, **savedstr; + + TP_ANNOUNCE("Insertion+deletion returns the expected image."); + + savedstr = NULL; + + if ((table = elftc_string_table_create(0)) == NULL) { + TP_UNRESOLVED("elftc_string_table_create() failed: %s", + strerror(errno)); + goto done; + } + + expectedsize = 1; + for (nstr = 0, s = test_strings; *s != NULL; s++, nstr++) { + expectedsize += strlen(*s) + 1; + if(elftc_string_table_insert(table, *s) == 0) { + TP_UNRESOLVED("String insertion failed for \"%s\".", + *s); + goto done; + } + } + + if ((savedstr = malloc(sizeof(*savedstr) * nstr)) == NULL) { + TP_UNRESOLVED("Memory allocation failed."); + goto done; + } + + for (nstr = n = 0, s = test_strings; *s != NULL; s++, n++) { + if ((n & 1) == 0) { + savedstr[nstr++] = *s; + continue; + } + + expectedsize -= (strlen(*s) + 1); + if (elftc_string_table_remove(table, *s) == 0) { + TP_UNRESOLVED("String removal failed for \"%s\".", + *s); + goto done; + } + } + + imagesz = 0; + image = elftc_string_table_image(table, &imagesz); + + if (image == NULL || imagesz != expectedsize) { + TP_FAIL("Incorrect image parameters: [0]=%d, sz=%d != %d", + *image, imagesz, expectedsize); + goto done; + } + + if (!validate_string_table(nstr, image, imagesz, savedstr)) { + TP_FAIL("Image mismatch."); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + free(savedstr); + tet_result(result); +} + +/* + * Verify that initialization from a ELF string table works. + */ + +void +tcFromSection(void) +{ + Elf *e; + Elf_Data *d; + Elf_Scn *scn; + int fd, result; + const char *image; + Elf32_Ehdr *eh; + Elf32_Shdr *shdr; + Elftc_String_Table *table; + size_t imagesz, scnindex; + + table = NULL; + result = TET_UNRESOLVED; + + TP_ANNOUNCE("Loading a table form an ELF section works correctly."); + + fd = -1; + e = NULL; + scn = NULL; + d = NULL; + + /* + * Create the ELF section. + */ + if ((fd = open("/dev/null", O_RDONLY)) < 0) { + TP_UNRESOLVED("File open failed."); + goto done; + } + + if (elf_version(EV_CURRENT) == EV_NONE) { + TP_UNRESOLVED("libelf initialization failed."); + goto done; + } + + if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) { + TP_UNRESOLVED("Elf open failed: %s", + elf_errmsg(-1)); + goto done; + } + + if ((eh = elf32_getehdr(e)) == NULL) { + TP_UNRESOLVED("Elf open failed: %s", + elf_errmsg(-1)); + goto done; + } + + eh->e_ident[EI_DATA] = ELFDATA2LSB; + eh->e_machine = EM_386; + eh->e_version = EV_CURRENT; + + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("Elf newscn failed: %s", + elf_errmsg(-1)); + goto done; + } + + scnindex = elf_ndxscn(scn); + + if ((shdr = elf32_getshdr(scn)) == NULL) { + TP_UNRESOLVED("Elf getshdr failed: %s", + elf_errmsg(-1)); + goto done; + } + + shdr->sh_type = SHT_STRTAB; + + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("Elf newdata failed: %s", + elf_errmsg(-1)); + goto done; + } + + d->d_buf = test_image; + d->d_size = sizeof(test_image); + + if (elf_update(e, ELF_C_NULL) < 0) { + TP_UNRESOLVED("elf_update failed: %s", + elf_errmsg(-1)); + goto done; + } + + if ((scn = elf_getscn(e, scnindex)) == NULL) { + TP_UNRESOLVED("Elf getscn failed: %s", + elf_errmsg(-1)); + goto done; + } + + /* Create a string table from the contents. */ + if ((table = elftc_string_table_from_section(scn, 0)) == NULL) { + TP_FAIL("from_section call failed."); + goto done; + } + + /* Retrieve the image. */ + if ((image = elftc_string_table_image(table, &imagesz)) == NULL) { + TP_FAIL("from_section call failed."); + goto done; + } + + /* Check the retrieved image against the original. */ + if (imagesz != sizeof(test_image) || + memcmp(image, test_image, imagesz) != 0) { + TP_FAIL("image compare failed."); + goto done; + } + + result = TET_PASS; + +done: + if (table) + (void) elftc_string_table_destroy(table); + if (e) + elf_end(e); + if (fd != -1) + (void) close(fd); + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/Makefile b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/Makefile new file mode 100644 index 0000000000..27003d9d71 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_SRCS= elftc_version.m4 + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/elftc_version.m4 b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/elftc_version.m4 new file mode 100644 index 0000000000..2bef2c3834 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/libelftc/tset/elftc_version/elftc_version.m4 @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2012 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elftc_version.m4 2846 2012-12-31 04:20:43Z jkoshy $ + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "tet_api.h" + +include(`elfts.m4') + +void +tcReturnValueIsNonNull(void) +{ + const char *version; + + TP_ANNOUNCE("elftc_version() returns a non-null pointer"); + + version = elftc_version(); + + tet_result(version != NULL ? TET_PASS : TET_FAIL); +} + +#define DELIMS " \t" + +/* + * Check the form of the returned string. + */ +void +tcReturnValueFormat(void) +{ + int result; + const char *version; + struct utsname unamebuf; + char *field, *versioncopy; + + TP_ANNOUNCE("The returned string from elftc_version() has the " + "correct form."); + + result = TET_UNRESOLVED; + versioncopy = NULL; + + if ((version = elftc_version()) == NULL || + (versioncopy = strdup(version)) == NULL) { + TP_UNRESOLVED("version retrieval failed: %s", + strerror(errno)); + goto done; + } + + if (uname(&unamebuf) < 0) { + TP_UNRESOLVED("uname failed: %s", strerror(errno)); + goto done; + } + + /* + * Field 1 should be "elftoolchain". + */ + if ((field = strtok(versioncopy, DELIMS)) == NULL) { + TP_FAIL("Missing field 1: \"%s\"", version); + goto done; + } + if (strcmp(field, "elftoolchain")) { + TP_FAIL("Field 1 \"%s\" != \"elftoolchain\": \"%s\"", + field, version); + goto done; + } + + /* + * Field 2 is the branch identifier. We do not check + * the value of this field. + */ + if ((field = strtok(NULL, DELIMS)) == NULL) { + TP_FAIL("Missing field 2: \"%s\"", version); + goto done; + } + + /* + * Field 3 is the system name. + */ + if ((field = strtok(NULL, DELIMS)) == NULL) { + TP_FAIL("Missing field 3: \"%s\"", version); + goto done; + } + if (strcmp(field, unamebuf.sysname)) { + TP_FAIL("System name mismatch: field \"%s\" != " + "uname \"%s\": %s", field, unamebuf.sysname, + version); + goto done; + } + + /* + * Field 4 is the current version identifier. + */ + if ((field = strtok(NULL, DELIMS)) == NULL) { + TP_FAIL("Missing field 4: \"%s\"", version); + goto done; + } + + /* + * There should be no other fields. + */ + if ((field = strtok(NULL, DELIMS)) != NULL) { + TP_FAIL("Extra fields: \%s\" in \"%s\"", field, version); + goto done; + } + + result = TET_PASS; + +done: + free(versioncopy); + tet_result(result); +} diff --git a/contrib/elftoolchain/tests/tet/nm/Makefile b/contrib/elftoolchain/tests/tet/nm/Makefile new file mode 100644 index 0000000000..bc8bfebe1c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/Makefile @@ -0,0 +1,6 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../.. +SUBDIR= ts + +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/tet_code b/contrib/elftoolchain/tests/tet/nm/tet_code new file mode 100644 index 0000000000..89dd859481 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/tet_code @@ -0,0 +1,15 @@ +# $Id: tet_code 2085 2011-10-27 05:06:47Z jkoshy $ + +# TET reserved codes +0 "PASS" +1 "FAIL" +2 "UNRESOLVED" +3 "NOTINUSE" +4 "UNSUPPORTED" +5 "UNTESTED" +6 "UNINITIATED" +7 "NORESULT" + +# Test suite additional codes +33 "INSPECT" + diff --git a/contrib/elftoolchain/tests/tet/nm/tet_scen b/contrib/elftoolchain/tests/tet/nm/tet_scen new file mode 100644 index 0000000000..174280924c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/tet_scen @@ -0,0 +1,55 @@ +# $Id: tet_scen 2085 2011-10-27 05:06:47Z jkoshy $ + +# cpp_demangle test suite. + +all + "Starting Test Suite" + ^nm_object1 + ^nm_object2 + ^nm_archive1 + ^nm_archive2 + ^nm_shared_object1 + ^nm_shared_object2 + ^nm_option + ^nm_debug + "Complete Test Suite" + +nm_object1 + "Starting nm Object Test 1" + /ts/nm_object1/tc.sh + "Complete nm Object Test 1" + +nm_object2 + "Starting nm Object Test 2" + /ts/nm_object2/tc.sh + "Complete nm Object Test 2" + +nm_archive1 + "Starting nm Archive Test 1" + /ts/nm_archive1/tc.sh + "Complete nm Archive Test 1" + +nm_archive2 + "Starting nm Archive Test 2" + /ts/nm_archive2/tc.sh + "Complete nm Archive Test 2" + +nm_shared_object1 + "Starting nm Shared Object Test 1" + /ts/nm_shared_object1/tc.sh + "Complete nm Shared Object Test 1" + +nm_shared_object2 + "Starting nm Shared Object Test 2" + /ts/nm_shared_object2/tc.sh + "Complete nm Shared Object Test 2" + +nm_option + "Starting nm Option Test" + /ts/nm_option/tc.sh + "Complete nm Option Test" + +nm_debug + "Starting nm Debug Option Test" + /ts/nm_debug/tc.sh + "Complete nm Debug Option Test" diff --git a/contrib/elftoolchain/tests/tet/nm/tetbuild.cfg b/contrib/elftoolchain/tests/tet/nm/tetbuild.cfg new file mode 100644 index 0000000000..633b832a97 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/tetbuild.cfg @@ -0,0 +1,4 @@ +# $Id: tetbuild.cfg 2085 2011-10-27 05:06:47Z jkoshy $ + +TET_OUTPUT_CAPTURE=True +TET_BUILD_TOOL=make diff --git a/contrib/elftoolchain/tests/tet/nm/tetclean.cfg b/contrib/elftoolchain/tests/tet/nm/tetclean.cfg new file mode 100644 index 0000000000..f62f479867 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/tetclean.cfg @@ -0,0 +1,6 @@ +# $Id: tetclean.cfg 2085 2011-10-27 05:06:47Z jkoshy $ + +TET_OUTPUT_CAPTURE=True +TET_CLEAN_TOOL=make +TET_CLEAN_FILE=clean +TET_PASS_TC_NAME=False diff --git a/contrib/elftoolchain/tests/tet/nm/tetexec.cfg b/contrib/elftoolchain/tests/tet/nm/tetexec.cfg new file mode 100644 index 0000000000..ffaa3932d6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/tetexec.cfg @@ -0,0 +1,2 @@ +# $Id: tetexec.cfg 2085 2011-10-27 05:06:47Z jkoshy $ +TET_OUTPUT_CAPTURE=False diff --git a/contrib/elftoolchain/tests/tet/nm/ts/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/Makefile new file mode 100644 index 0000000000..8775caad26 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/Makefile @@ -0,0 +1,14 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../.. + +SUBDIR+= nm_archive1 +SUBDIR+= nm_archive2 +SUBDIR+= nm_debug +SUBDIR+= nm_object1 +SUBDIR+= nm_object2 +SUBDIR+= nm_option +SUBDIR+= nm_shared_object1 +SUBDIR+= nm_shared_object2 + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/ts/Makefile.tset b/contrib/elftoolchain/tests/tet/nm/ts/Makefile.tset new file mode 100644 index 0000000000..4b9ca8adb0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/Makefile.tset @@ -0,0 +1,24 @@ +# $Id: Makefile.tset 3719 2019-03-23 08:30:55Z jkoshy $ + +NM_EXEC?= ${.CURDIR}/../../../../nm/nm +CSTD?= iso9899:1999 + +CFLAGS+= -DNM=\"${NM_EXEC}\" -DTC_DIR=\"$(.CURDIR)\" \ + -DTESTFILE=\"$(TS_DATA)\" + +CLEANFILES+= test.out + +.for f in ${TS_SRCS} +.if exists(${.CURDIR}/../common/${f}) +${f}: ${.CURDIR}/../common/${f} + cp ${.ALLSRC} ${.TARGET} +CLEANFILES+= test_nm.c +.endif +.endfor + +.if !empty(${TS_DATA:R}) && !exists(${TS_DATA:R}) +${TS_DATA}: + uudecode ${TS_DATA}.uu +.endif + +CLEANFILES+= ${TS_DATA} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/common/func.sh b/contrib/elftoolchain/tests/tet/nm/ts/common/func.sh new file mode 100644 index 0000000000..19ed56f601 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/common/func.sh @@ -0,0 +1,304 @@ +#!/bin/sh +# +# $Id: func.sh 4043 2024-07-08 11:56:17Z jkoshy $ + +test_format_bsd1() +{ + # $1 test file + # $2 oracle file + + run "-t d -B" $1 $2 +} + +test_format_bsd2() +{ + # $1 test file + # $2 oracle file + + run "-t d --format=bsd" $1 $2 +} + +test_dynamic1() +{ + # $1 test file + # $2 oracle file + + run "-t d -D" $1 $2 +} + +test_dynamic2() +{ + # $1 test file + # $2 oracle file + + run "-t d --dynamic" $1 $2 +} + +test_external() +{ + # $1 test file + # $2 oracle file + + run "-t d -g" $1 $2 +} + +test_hexa1() +{ + # $1 test file + # $2 oracle file + + run "-x" $1 $2 +} + +test_hexa2() +{ + # $1 test file + # $2 oracle file + + run "-t x" $1 $2 +} + +test_hexa3() +{ + # $1 test file + # $2 oracle file + + run "--radix=x" $1 $2 +} + +test_no_sort1() +{ + # $1 test file + # $2 oracle file + + run "-t d -p" $1 $2 +} + +test_no_sort2() +{ + # $1 test file + # $2 oracle file + + run "-t d --no-sort" $1 $2 +} + +test_num_sort1() +{ + # $1 test file + # $2 oracle file + + run "-t d -n" $1 $2 +} + +test_num_sort2() +{ + # $1 test file + # $2 oracle file + + run "-t d --numeric-sort" $1 $2 +} + +test_octal2() +{ + # $1 test file + # $2 oracle file + + run "-t o" $1 $2 +} + +test_octal3() +{ + # $1 test file + # $2 oracle file + + run "--radix=o" $1 $2 +} + +test_posix1() +{ + # $1 test file + # $2 oracle file + + run "-P" $1 $2 +} + +test_posix2() +{ + # $1 test file + # $2 oracle file + + run "--format=posix" $1 $2 +} + +test_print_file_name1() +{ + # $1 test file + # $2 oracle file + + run "-t d -A" $1 $2 +} + +test_print_file_name2() +{ + # $1 test file + # $2 oracle file + + run "-t d --print-file-name" $1 $2 +} + +test_print_size1() +{ + # $1 test file + # $2 oracle file + + run "-t d -S" $1 $2 +} + +test_print_size2() +{ + # $1 test file + # $2 oracle file + + run "-t d --print-size" $1 $2 +} + +test_reverse_sort1() +{ + # $1 test file + # $2 oracle file + + run "-t d -r" $1 $2 +} + +test_reverse_sort2() +{ + # $1 test file + # $2 oracle file + + run "-t d --reverse-sort" $1 $2 +} + +test_reverse_sort_num() +{ + # $1 test file + # $2 oracle file + + run "-t d -r -n" $1 $2 +} + +test_reverse_sort_no() +{ + # $1 test file + # $2 oracle file + + run "-t d -r -p" $1 $2 +} + +test_reverse_sort_size() +{ + # $1 test file + # $2 oracle file + + run "-t d -r --size-sort" $1 $2 +} + +test_size_sort() +{ + # $1 test file + # $2 oracle file + + run "-t d --size-sort" $1 $2 +} + +test_sysv() +{ + # $1 test file + # $2 oracle file + + run "-t d --format=sysv" $1 $2 +} + +test_undef1() +{ + # $1 test file + # $2 oracle file + + run "-t d -u" $1 $2 +} + +test_undef2() +{ + # $1 test file + # $2 oracle file + + run "-t d --undefined-only" $1 $2 +} + +test_debug_syms1() +{ + # $1 test file + # $2 oracle file + + run "-a" $1 $2 +} + +test_debug_syms2() +{ + # $1 test file + # $2 oracle file + + run "--debug-syms" $1 $2 +} + +run() +{ + # $1 nm option + # $2 test file + # $3 oracle file + + tet_infoline "OPTION $1" + + NM_PATH="$TET_SUITE_ROOT/../../../nm/nm" + TEST_OUTPUT_FILE="test.out" + + $NM_PATH $1 $2 > $TEST_OUTPUT_FILE 2> /dev/null + NM_RETURN_CODE="$?" + if [ $NM_RETURN_CODE -ne "0" ]; then + tet_infoline "nm execution failed" + tet_result FAIL + + return + fi + + diff $TEST_OUTPUT_FILE $3 > /dev/null + DIFF_RETURN_CODE="$?" + if [ $DIFF_RETURN_CODE -ne "0" ]; then + tet_infoline "diff failed" + tet_result FAIL + + return + fi + + tet_result PASS +} + +run_without_diff() +{ + # $1 nm option + # $2 oracle return code + + tet_infoline "OPTION $1" + + NM_PATH="$TET_SUITE_ROOT/../../../nm/nm" + + $NM_PATH $1 > /dev/null 2> /dev/null + NM_RETURN_CODE="$?" + if [ $NM_RETURN_CODE -ne $2 ]; then + tet_infoline "nm execution failed" + tet_result FAIL + + return + fi + + tet_result PASS +} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/common/test_nm.c b/contrib/elftoolchain/tests/tet/nm/ts/common/test_nm.c new file mode 100644 index 0000000000..76fca042a9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/common/test_nm.c @@ -0,0 +1,343 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: test_nm.c 2378 2012-01-03 08:59:56Z jkoshy $ + */ + +#include +#include +#include +#include + +#include + +static int exec_cmd(const char *, const char *); +static void startup(); +static void test_bsd(); +static void test_dynamic(); +static void test_external(); +static void test_hexa(); +static bool test_nm_out(const char *, const char *); +static void test_no_sort(); +static void test_num_sort(); +static void test_octal(); +static void test_posix(); +static void test_print_filename(); +static void test_print_size(); +static void test_reverse_sort(); +static void test_size_sort(); +static void test_sysv(); +static void test_undef(); + +struct tet_testlist tet_testlist[] = { + { test_dynamic, 1}, + { test_external, 2}, + { test_num_sort, 3}, + { test_no_sort, 4}, + { test_posix, 5}, + { test_print_size, 6}, + { test_undef, 7}, + { test_size_sort, 8}, + { test_sysv, 9}, + { test_bsd, 10}, + { test_print_filename, 11}, + { test_octal, 12}, + { test_hexa, 13}, + { test_reverse_sort, 14}, + { NULL, 0} +}; + +#define NM_CMD NM " %s " TESTFILE " > test.out" +#define DIFF_CMD "diff test.out " TC_DIR "/" TESTFILE "%s.txt > /dev/null" + +void (*tet_startup)() = startup; +void (*tet_cleanup)() = NULL; + +static int +exec_cmd(const char *cmd, const char *op) +{ + char *this_cmd; + int rtn; + size_t cmd_len; + + if (cmd == NULL || op == NULL) + return (-1); + + cmd_len = strlen(cmd) + strlen(op); + + if ((this_cmd = malloc(sizeof(char) * cmd_len)) == NULL) { + tet_infoline("cannot allocate memory"); + + return (-1); + } + + snprintf(this_cmd, cmd_len, cmd, op); + + rtn = system(this_cmd); + + free(this_cmd); + + return (rtn); +} + +static void +startup() +{ + + if (system("cp " TC_DIR "/" TESTFILE " .") < 0) { + tet_infoline("cannot cp object"); + + exit(EXIT_FAILURE); + } +} + +static void +test_bsd() +{ + bool rtn = true; + + tet_infoline("OPTION -B, --format=bsd"); + + rtn |= test_nm_out("-B", "-B"); + rtn |= test_nm_out("--format=bsd", "-B"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_dynamic() +{ + bool rtn = true; + + tet_infoline("OPTION -D, --dynamic"); + + rtn |= test_nm_out("-D", "-D"); + rtn |= test_nm_out("--dynamic", "-D"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_external() +{ + + tet_infoline("OPTION -g"); + + if (test_nm_out("-g", "-g") == true) + tet_result(TET_PASS); + else + tet_result(TET_FAIL); +} + +static void +test_hexa() +{ + bool rtn = true; + + tet_infoline("OPTION -x, -t x"); + + rtn |= test_nm_out("-x", "-x"); + rtn |= test_nm_out("-t x", "-x"); + rtn |= test_nm_out("--radix=x", "-x"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static bool +test_nm_out(const char *op, const char *d_op) +{ + int rtn; + + if (op == NULL) { + tet_result(TET_FAIL); + + return (false); + } + + if ((rtn = exec_cmd(NM_CMD, op)) < 0) { + tet_infoline("system function failed"); + + return (false); + } else if (rtn == 127) { + tet_infoline("execution shell failed"); + + return (false); + } + + if ((rtn = exec_cmd(DIFF_CMD, d_op)) < 0) + tet_infoline("system function failed"); + else { + switch (rtn) { + case 127: + tet_infoline("execution shell failed"); + + break; + case 2: + tet_infoline("diff has trouble"); + + break; + case 1: + tet_infoline("output is different"); + + break; + case 0: + return (true); + } + } + + return (false); +} + +static void +test_no_sort() +{ + bool rtn = true; + + tet_infoline("OPTION -p"); + + rtn |= test_nm_out("-p", "-p"); + rtn |= test_nm_out("--no-sort", "-p"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_num_sort() +{ + bool rtn = true; + + tet_infoline("OPTION -n, --numeric-sort"); + + rtn |= test_nm_out("-n", "-n"); + rtn |= test_nm_out("--numeric-sort", "-n"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_octal() +{ + bool rtn = true; + + tet_infoline("OPTION --radix=o, -t o"); + + rtn |= test_nm_out("-t o", "-o"); + rtn |= test_nm_out("--radix=o", "-o"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_posix() +{ + bool rtn = true; + + tet_infoline("OPTION -P, --format=posix"); + + rtn |= test_nm_out("-P", "-P"); + rtn |= test_nm_out("--format=posix", "-P"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_print_filename() +{ + bool rtn = true; + + tet_infoline("OPTION -A, --print-file-name"); + + rtn |= test_nm_out("-A", "-A"); + rtn |= test_nm_out("--print-file-name", "-A"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_print_size() +{ + bool rtn = true; + + tet_infoline("OPTION -S, --print-size"); + + rtn |= test_nm_out("-S", "-S"); + rtn |= test_nm_out("--print-size", "-S"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_reverse_sort() +{ + bool rtn = true; + + tet_infoline("OPTION -r, --reverse-sort"); + + rtn |= test_nm_out("-r", "-r"); + rtn |= test_nm_out("--reverse-sort", "-r"); + + rtn |= test_nm_out("-r -n", "-r-n"); + rtn |= test_nm_out("-r -p", "-r-p"); + rtn |= test_nm_out("-r --size-sort", "-r-size-sort"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} + +static void +test_size_sort() +{ + + tet_infoline("OPTION --size-sort"); + + if (test_nm_out("--size-sort", "-size-sort") == true) + tet_result(TET_PASS); + else + tet_result(TET_FAIL); +} + +static void +test_sysv() +{ + + tet_infoline("OPTION --format=sysv"); + + if (test_nm_out("--format=sysv", "-sysv") == true) + tet_result(TET_PASS); + else + tet_result(TET_FAIL); +} + +static void +test_undef() +{ + bool rtn = true; + + tet_infoline("OPTION -u, --undefined-only"); + + rtn |= test_nm_out("-u", "-u"); + rtn |= test_nm_out("--undefined-only", "-u"); + + tet_result(rtn == true ? TET_PASS : TET_FAIL); +} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/Makefile new file mode 100644 index 0000000000..800448e4ae --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile 2085 2011-10-27 05:06:47Z jkoshy $ + +TET_ROOT?= /usr/tet +LIBDIR= $(TET_ROOT)/lib/tet3 +INCDIR= $(TET_ROOT)/inc/tet3 +CSTD= -std=iso9899:1999 +CFLAGS= -I$(INCDIR) +TC= cpp_demangle-tc + +vector_str.o: ../../../vector_str.c + $(CC) $(CSTD) -o vector_str.o -c ../../../vector_str.c + +cpp_demangle.o: ../../../cpp_demangle.c vector_str.o + $(CC) $(CSTD) -o cpp_demangle.o -c ../../../cpp_demangle.c + +$(TC): $(TC).c cpp_demangle.o $(INCDIR)/tet_api.h + $(CC) $(CFLAGS) $(CSTD) -o $(TC) $(TC).c vector_str.o \ + cpp_demangle.o $(LIBDIR)/tcm.o \ + $(LIBDIR)/libapi.a + +clean: + rm -f *.o $(TC) + +lint: + lint $(CFLAGS) $(TC) -ltcm diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/cpp_demangle-tc.c b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/cpp_demangle-tc.c new file mode 100644 index 0000000000..361816b6ac --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle/cpp_demangle-tc.c @@ -0,0 +1,170 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: cpp_demangle-tc.c 2085 2011-10-27 05:06:47Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "../../../cpp_demangle.h" + +static void startup(); +static void cleanup(); +static void test_func(); +static void test_oper(); +static void test_templ(); +static void test_scope(); +static void test_subst(); +static void test_cpp_demangle_ia64(const char *, const char *); + +void (*tet_startup)() = NULL; +void (*tet_cleanup)() = NULL; + +struct tet_testlist tet_testlist[] = { + { test_func, 1}, + { test_oper, 2}, + { test_templ, 3}, + { test_scope, 4}, + { test_subst, 5}, + { NULL, 0} +}; + +static void +test_func() +{ + + tet_infoline("FUNCTION"); + test_cpp_demangle_ia64("_Z1fv", "f(void)"); + test_cpp_demangle_ia64("_Z1fi", "f(int)"); + test_cpp_demangle_ia64("_Z3foo3bar", "foo(bar)"); +} + +static void +test_oper() +{ + + tet_infoline("OPERATOR"); + test_cpp_demangle_ia64("_Zrm1XS_", "operator%(X, X)"); + test_cpp_demangle_ia64("_ZplR1XS0_", "operator+(X&, X&)"); + test_cpp_demangle_ia64("_ZlsRK1XS1_", + "operator<<(X const&, X const&)"); +} + +static void +test_templ() +{ + + tet_infoline("TEMPLATE"); + test_cpp_demangle_ia64("_ZN3FooIA4_iE3barE", + "Foo::bar"); + test_cpp_demangle_ia64("_Z1fIiEvi", "void f(int)"); + test_cpp_demangle_ia64("_Z5firstI3DuoEvS0_", + "void first(Duo)"); + test_cpp_demangle_ia64("_Z5firstI3DuoEvT_", + "void first(Duo)"); + test_cpp_demangle_ia64("_Z3fooIiPFidEiEvv", + "void foo(void)"); + test_cpp_demangle_ia64("_Z1fI1XEvPVN1AIT_E1TE", + "void f(A::T volatile*)"); + test_cpp_demangle_ia64("_ZngILi42EEvN1AIXplT_Li2EEE1TE", + "void operator-<42>(A::T)"); + test_cpp_demangle_ia64("_Z4makeI7FactoryiET_IT0_Ev", + "Factory make(void)"); +} + +static void +test_scope() +{ + + tet_infoline("SCOPE"); + test_cpp_demangle_ia64("_ZN1N1fE", "N::f"); + test_cpp_demangle_ia64("_ZN6System5Sound4beepEv", + "System::Sound::beep(void)"); + test_cpp_demangle_ia64("_ZN5Arena5levelE", "Arena::level"); + test_cpp_demangle_ia64("_ZN5StackIiiE5levelE", + "Stack::level"); + +} + +static void +test_subst() +{ + + tet_infoline("SUBSTITUTION"); + test_cpp_demangle_ia64("_Z3foo5Hello5WorldS0_S_", + "foo(Hello, World, World, Hello)"); + test_cpp_demangle_ia64("_Z3fooPM2ABi", "foo(int AB::**)"); + test_cpp_demangle_ia64("_ZlsRSoRKSs", + "operator<<(std::ostream&, std::string const&)"); + test_cpp_demangle_ia64("_ZTI7a_class", + "typeinfo for (a_class)"); + test_cpp_demangle_ia64("_ZSt5state", "std::state"); + test_cpp_demangle_ia64("_ZNSt3_In4wardE", "std::_In::ward"); +} + +static void +test_cpp_demangle_ia64(const char *org, const char *dst) +{ + char *rst; + + if ((rst = cpp_demangle_ia64(org)) == NULL) { + const size_t len = strlen(org); + char *msg; + + if ((msg = malloc(len + 8)) != NULL) { + snprintf(msg, len + 8, "Cannot demangle : %s", org); + tet_infoline(msg); + free(msg); + } + + tet_result(TET_FAIL); + + return; + } + + if (strcmp(rst, dst) != 0) { + const size_t len = strlen(org) + strlen(rst) + strlen(dst); + char *msg; + + if ((msg = malloc(len + 17)) != NULL) { + snprintf(msg, len + 17, "Diff for %s : %s != %s", org, + rst, dst); + tet_infoline(msg); + free(msg); + } + + free(rst); + tet_result(TET_FAIL); + + return; + } + + free(rst); + + tet_result(TET_PASS); +} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/Makefile new file mode 100644 index 0000000000..2bf60463aa --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/Makefile @@ -0,0 +1,24 @@ +# $Id: Makefile 2085 2011-10-27 05:06:47Z jkoshy $ +TET_ROOT?= /usr/tet +LIBDIR= $(TET_ROOT)/lib/tet3 +INCDIR= $(TET_ROOT)/inc/tet3 +CSTD= -std=iso9899:1999 +CFLAGS= -I$(INCDIR) +TC= cpp_demangle_ARM-tc + +vector_str.o: ../../../vector_str.c + $(CC) $(CSTD) -o vector_str.o -c ../../../vector_str.c + +cpp_demangle_arm.o: ../../../cpp_demangle_arm.c vector_str.o + $(CC) $(CSTD) -o cpp_demangle_arm.o -c ../../../cpp_demangle_arm.c + +$(TC): $(TC).c cpp_demangle_arm.o $(INCDIR)/tet_api.h + $(CC) $(CFLAGS) $(CSTD) -o $(TC) $(TC).c vector_str.o \ + cpp_demangle_arm.o $(LIBDIR)/tcm.o \ + $(LIBDIR)/libapi.a + +clean: + rm -f *.o $(TC) + +lint: + lint $(CFLAGS) $(TC) -ltcm diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/cpp_demangle_ARM-tc.c b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/cpp_demangle_ARM-tc.c new file mode 100644 index 0000000000..c3fe32fa2d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_ARM/cpp_demangle_ARM-tc.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: cpp_demangle_ARM-tc.c 2085 2011-10-27 05:06:47Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "../../../cpp_demangle_arm.h" + +static void startup(); +static void cleanup(); +static void test_basic(); +static void test_modifier(); +static void test_subst(); +static void test_example(); +static void test_cpp_demangle_ARM(const char *, const char *); + +void (*tet_startup)() = NULL; +void (*tet_cleanup)() = NULL; + +struct tet_testlist tet_testlist[] = { + { test_basic, 1}, + { test_modifier, 2}, + { test_subst, 3}, + { test_example, 4}, + { NULL, 0} +}; + +static void +test_basic() +{ + + tet_infoline("BASIC ENCODING"); + test_cpp_demangle_ARM("f__Fide", "f(int, double, ...)"); + test_cpp_demangle_ARM("f__Fv", "f(void)"); + test_cpp_demangle_ARM("f__Q25Outer5Inner__Fv", "Outer::Inner::f(void)"); + test_cpp_demangle_ARM("update__3recFd", "rec::update(double)"); + test_cpp_demangle_ARM("f__1xFi", "x::f(int)"); + test_cpp_demangle_ARM("f__F1xi", "f(x, int)"); + test_cpp_demangle_ARM("__ct__1xFv", "x::x()"); + test_cpp_demangle_ARM("__dt__1xFv", "x::~x()"); + test_cpp_demangle_ARM("__opQ25Name16Class1__Q25Name16Class2", + "Name1::Class2::operator Name1::Class1()"); +} + +static void +test_modifier() +{ + + tet_infoline("MODIFIER and TYPE DECLARATOR"); + test_cpp_demangle_ARM("f__FUi", "f(unsigned int)"); + test_cpp_demangle_ARM("f__FCSc", "f(const signed char)"); + test_cpp_demangle_ARM("f__FPc", "f(char*)"); + test_cpp_demangle_ARM("f__FPCc", "f(const char*)"); + test_cpp_demangle_ARM("f__FCPc", "f(char* const)"); + test_cpp_demangle_ARM("f__FPFPc_i", "f(int (*)(char*))"); + test_cpp_demangle_ARM("f__FA10_i", "f(int[10])"); + test_cpp_demangle_ARM("f__FM1S7complex", "f(S::*complex)"); +} + +static void +test_subst() +{ + + tet_infoline("SUBSTITUTION"); + test_cpp_demangle_ARM("f__F7complexT1", "f(complex, complex)"); + test_cpp_demangle_ARM("f__F6recordN21", "f(record, record, record)"); +} + +static void +test_example() +{ + + tet_infoline("EXAMPLE"); + test_cpp_demangle_ARM("__dt__12PathListHeadFv", + "PathListHead::~PathListHead()"); + test_cpp_demangle_ARM("__ad__4PathFR4Path", "Path::operator&(Path&)"); + test_cpp_demangle_ARM("first__4PathFv", "Path::first(void)"); + test_cpp_demangle_ARM("last__4PathFv", "Path::last(void)"); + test_cpp_demangle_ARM("findpath__4PathFR6String", + "Path::findpath(String&)"); + test_cpp_demangle_ARM("fullpath__4PathFv", "Path::fullpath(void)"); +} + +static void +test_cpp_demangle_ARM(const char *org, const char *dst) +{ + char *rst; + + if ((rst = cpp_demangle_ARM(org)) == NULL) { + const size_t len = strlen(org); + char *msg; + + if ((msg = malloc(len + 19)) != NULL) { + snprintf(msg, len + 19, "Cannot demangle : %s", org); + tet_infoline(msg); + free(msg); + } + + tet_result(TET_FAIL); + + return; + } + + if (strcmp(rst, dst) != 0) { + const size_t len = strlen(org) + strlen(rst) + strlen(dst); + char *msg; + + if ((msg = malloc(len + 17)) != NULL) { + snprintf(msg, len + 17, "Diff for %s : %s != %s", org, + rst, dst); + tet_infoline(msg); + free(msg); + } + + free(rst); + tet_result(TET_FAIL); + + return; + } + + free(rst); + + tet_result(TET_PASS); +} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/Makefile new file mode 100644 index 0000000000..eba6ab3fd7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/Makefile @@ -0,0 +1,24 @@ +# $Id: Makefile 2085 2011-10-27 05:06:47Z jkoshy $ +TET_ROOT?= /usr/tet +LIBDIR= $(TET_ROOT)/lib/tet3 +INCDIR= $(TET_ROOT)/inc/tet3 +CSTD= -std=iso9899:1999 +CFLAGS= -I$(INCDIR) +TC= cpp_demangle_gnu2-tc + +vector_str.o: ../../../vector_str.c + $(CC) $(CSTD) -o vector_str.o -c ../../../vector_str.c + +cpp_demangle_gnu2.o: ../../../cpp_demangle_gnu2.c vector_str.o + $(CC) $(CSTD) -o cpp_demangle_gnu2.o -c ../../../cpp_demangle_gnu2.c + +$(TC): $(TC).c cpp_demangle_gnu2.o $(INCDIR)/tet_api.h + $(CC) $(CFLAGS) $(CSTD) -o $(TC) $(TC).c vector_str.o \ + cpp_demangle_gnu2.o $(LIBDIR)/tcm.o \ + $(LIBDIR)/libapi.a + +clean: + rm -f *.o $(TC) + +lint: + lint $(CFLAGS) $(TC) -ltcm diff --git a/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/cpp_demangle_gnu2-tc.c b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/cpp_demangle_gnu2-tc.c new file mode 100644 index 0000000000..d0c49dc362 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/cpp_demangle_gnu2/cpp_demangle_gnu2-tc.c @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: cpp_demangle_gnu2-tc.c 2085 2011-10-27 05:06:47Z jkoshy $ + */ + +#include +#include +#include +#include + +#include "../../../cpp_demangle_gnu2.h" + +static void startup(); +static void cleanup(); +static void test_basic(); +static void test_modifier(); +static void test_subst(); +static void test_example(); +static void test_gnu2(); +static void test_cpp_demangle_gnu2(const char *, const char *); + +void (*tet_startup)() = NULL; +void (*tet_cleanup)() = NULL; + +struct tet_testlist tet_testlist[] = { + { test_basic, 1}, + { test_modifier, 2}, + { test_subst, 3}, + { test_example, 4}, + { test_gnu2, 5}, + { NULL, 0} +}; + +static void +test_basic() +{ + + tet_infoline("BASIC ENCODING"); + test_cpp_demangle_gnu2("f__Fide", "f(int, double, ...)"); + test_cpp_demangle_gnu2("f__Fv", "f(void)"); + test_cpp_demangle_gnu2("f__Q25Outer5Inner__Fv", "Outer::Inner::f(void)"); + test_cpp_demangle_gnu2("update__3recFd", "rec::update(double)"); + test_cpp_demangle_gnu2("f__1xFi", "x::f(int)"); + test_cpp_demangle_gnu2("f__F1xi", "f(x, int)"); + test_cpp_demangle_gnu2("__opQ25Name16Class1__Q25Name16Class2", + "Name1::Class2::operator Name1::Class1()"); +} + +static void +test_modifier() +{ + + tet_infoline("MODIFIER and TYPE DECLARATOR"); + test_cpp_demangle_gnu2("f__FUi", "f(unsigned int)"); + test_cpp_demangle_gnu2("f__FCSc", "f(const signed char)"); + test_cpp_demangle_gnu2("f__FPc", "f(char*)"); + test_cpp_demangle_gnu2("f__FPCc", "f(const char*)"); + test_cpp_demangle_gnu2("f__FCPc", "f(char* const)"); + test_cpp_demangle_gnu2("f__FPFPc_i", "f(int (*)(char*))"); + test_cpp_demangle_gnu2("f__FA10_i", "f(int[10])"); + test_cpp_demangle_gnu2("f__FM1S7complex", "f(S::*complex)"); +} + +static void +test_subst() +{ + + tet_infoline("SUBSTITUTION"); + test_cpp_demangle_gnu2("f__F7complexT1", "f(complex, complex)"); + test_cpp_demangle_gnu2("f__F6recordN21", "f(record, record, record)"); +} + +static void +test_example() +{ + + tet_infoline("EXAMPLE"); + test_cpp_demangle_gnu2("__ad__4PathFR4Path", "Path::operator&(Path&)"); + test_cpp_demangle_gnu2("first__4PathFv", "Path::first(void)"); + test_cpp_demangle_gnu2("last__4PathFv", "Path::last(void)"); + test_cpp_demangle_gnu2("findpath__4PathFR6String", + "Path::findpath(String&)"); + test_cpp_demangle_gnu2("fullpath__4PathFv", "Path::fullpath(void)"); +} + +static void +test_gnu2() +{ + + tet_infoline("GNU 2 SPECIFIC"); + test_cpp_demangle_gnu2("Func1__Q25Name16Class1", + "Name1::Class1::Func1(void)"); + test_cpp_demangle_gnu2("_$_10bad_typeid", + "bad_typeid::~bad_typeid(void)"); + test_cpp_demangle_gnu2("__16__user_type_infoPCc", + "__user_type_info::__user_type_info(const char*)"); + test_cpp_demangle_gnu2("__Q25Name16Class1", + "Name1::Class1::Class1(void)"); + test_cpp_demangle_gnu2("__tf10bad_typeid", + "bad_typeid type_info function"); + test_cpp_demangle_gnu2("__ti10bad_typeid", + "bad_typeid type_info node"); + test_cpp_demangle_gnu2("_vt$10bad_typeid", + "bad_typeid virtual table"); + test_cpp_demangle_gnu2("what__C9exception", + "exception::what(void) const"); +} + +static void +test_cpp_demangle_gnu2(const char *org, const char *dst) +{ + char *rst; + + if ((rst = cpp_demangle_gnu2(org)) == NULL) { + const size_t len = strlen(org); + char *msg; + + if ((msg = malloc(len + 19)) != NULL) { + snprintf(msg, len + 19, "Cannot demangle : %s", org); + tet_infoline(msg); + free(msg); + } + + tet_result(TET_FAIL); + + return; + } + + if (strcmp(rst, dst) != 0) { + const size_t len = strlen(org) + strlen(rst) + strlen(dst); + char *msg; + + if ((msg = malloc(len + 17)) != NULL) { + snprintf(msg, len + 17, "Diff for %s : %s != %s", org, + rst, dst); + tet_infoline(msg); + free(msg); + } + + free(rst); + tet_result(TET_FAIL); + + return; + } + + free(rst); + + tet_result(TET_PASS); +} diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/Makefile new file mode 100644 index 0000000000..58d8e00ca6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_DATA= test_ar + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/tc.sh b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/tc.sh new file mode 100755 index 0000000000..ca210f4a27 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/tc.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# +# $Id: tc.sh 2378 2012-01-03 08:59:56Z jkoshy $ + +tp1() +{ + test_format_bsd1 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp2() +{ + test_format_bsd2 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp3() +{ + test_dynamic1 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp4() +{ + test_dynamic2 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp5() +{ + test_external $TEST_FILE "$TEST_FILE-external.txt" +} + +tp6() +{ + test_hexa1 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp7() +{ + test_hexa2 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp8() +{ + test_hexa3 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp9() +{ + test_no_sort1 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp10() +{ + test_no_sort2 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp11() +{ + test_num_sort1 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp12() +{ + test_num_sort2 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp14() +{ + test_octal2 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp15() +{ + test_octal3 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp16() +{ + test_posix1 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp17() +{ + test_posix2 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp18() +{ + test_print_file_name1 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp19() +{ + test_print_file_name2 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp20() +{ + test_print_size1 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp21() +{ + test_print_size2 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp22() +{ + test_reverse_sort1 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp23() +{ + test_reverse_sort2 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp24() +{ + test_reverse_sort_num $TEST_FILE "$TEST_FILE-sort-reverse-num.txt" +} + +tp25() +{ + test_reverse_sort_no $TEST_FILE "$TEST_FILE-sort-reverse-no.txt" +} + +tp26() +{ + test_reverse_sort_size $TEST_FILE "$TEST_FILE-sort-reverse-size.txt" +} + +tp27() +{ + test_size_sort $TEST_FILE "$TEST_FILE-size-sort.txt" +} + +tp28() +{ + test_sysv $TEST_FILE "$TEST_FILE-sysv.txt" +} + +tp29() +{ + test_undef1 $TEST_FILE "$TEST_FILE-undef.txt" +} + +tp30() +{ + test_undef2 $TEST_FILE "$TEST_FILE-undef.txt" +} + +startup() +{ + uudecode "$TEST_FILE.uu" +} + +cleanup() +{ + rm -f $TEST_FILE +} + +TEST_FILE="test_ar" + +tet_startup="startup" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27 ic28 ic29 ic30" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" +ic28="tp28" +ic29="tp29" +ic30="tp30" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-dynamic.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-dynamic.txt new file mode 100644 index 0000000000..5c975f4e7f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-dynamic.txt @@ -0,0 +1,8 @@ + +data.o: + +usage.o: + +parse.o: + +descr.o: diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-external.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-external.txt new file mode 100644 index 0000000000..a99b7c3f86 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-external.txt @@ -0,0 +1,48 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000128 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen +0000000000000704 T hid_init +0000000000000000 T hid_parse_usage_in_page +0000000000000240 T hid_parse_usage_page +0000000000000368 T hid_usage_in_page +0000000000000576 T hid_usage_page + U malloc + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free +0000000000001744 T hid_end_parse +0000000000000224 T hid_get_item +0000000000001808 T hid_locate +0000000000001952 T hid_report_size +0000000000000080 T hid_start_parse + U malloc + U memcpy + U memset + +descr.o: + U __error + U free +0000000000000000 T hid_dispose_report_desc +0000000000000128 T hid_get_report_desc +0000000000000016 T hid_use_report_desc + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-bsd.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-bsd.txt new file mode 100644 index 0000000000..06567bbd97 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-bsd.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000128 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit +0000000000000100 b b.3186 +0000000000000000 b b.3204 + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen +0000000000000704 T hid_init +0000000000000000 T hid_parse_usage_in_page +0000000000000240 T hid_parse_usage_page +0000000000000368 T hid_usage_in_page +0000000000000576 T hid_usage_page + U malloc +0000000000000120 b npages +0000000000000124 b npagesmax +0000000000000112 b pages + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free +0000000000000000 t hid_clear_local +0000000000001744 T hid_end_parse +0000000000000224 T hid_get_item +0000000000001808 T hid_locate +0000000000001952 T hid_report_size +0000000000000080 T hid_start_parse + U malloc + U memcpy + U memset + +descr.o: + U __error + U free +0000000000000000 T hid_dispose_report_desc +0000000000000128 T hid_get_report_desc +0000000000000016 T hid_use_report_desc + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-posix.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-posix.txt new file mode 100644 index 0000000000..d000019d14 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-format-posix.txt @@ -0,0 +1,50 @@ +test_ar[data.o]: +hid_get_data T 0000000000000000 000000000000007f +hid_set_data T 0000000000000080 0000000000000076 +test_ar[usage.o]: +_CurrentRuneLocale U +__mb_sb_limit U +b.3186 b 0000000000000064 000000000000000a +b.3204 b 0000000000000000 0000000000000064 +err U +errx U +fclose U +fgets U +fmtcheck U +fopen U +hid_init T 00000000000002c0 0000000000000368 +hid_parse_usage_in_page T 0000000000000000 00000000000000e3 +hid_parse_usage_page T 00000000000000f0 0000000000000079 +hid_usage_in_page T 0000000000000170 00000000000000c5 +hid_usage_page T 0000000000000240 000000000000007b +malloc U +npages b 0000000000000078 0000000000000004 +npagesmax b 000000000000007c 0000000000000004 +pages b 0000000000000070 0000000000000008 +realloc U +sprintf U +sscanf U +strchr U +strcmp U +strdup U +strncmp U +test_ar[parse.o]: +free U +hid_clear_local t 0000000000000000 0000000000000047 +hid_end_parse T 00000000000006d0 000000000000003d +hid_get_item T 00000000000000e0 00000000000005e6 +hid_locate T 0000000000000710 0000000000000081 +hid_report_size T 00000000000007a0 000000000000008f +hid_start_parse T 0000000000000050 0000000000000085 +malloc U +memcpy U +memset U +test_ar[descr.o]: +__error U +free U +hid_dispose_report_desc T 0000000000000000 0000000000000005 +hid_get_report_desc T 0000000000000080 0000000000000040 +hid_use_report_desc T 0000000000000010 000000000000006e +ioctl U +malloc U +memcpy U diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-file-name.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-file-name.txt new file mode 100644 index 0000000000..0dd3e5a3f9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-file-name.txt @@ -0,0 +1,46 @@ +test_ar:data.o:0000000000000000 T hid_get_data +test_ar:data.o:0000000000000128 T hid_set_data +test_ar:usage.o: U _CurrentRuneLocale +test_ar:usage.o: U __mb_sb_limit +test_ar:usage.o:0000000000000100 b b.3186 +test_ar:usage.o:0000000000000000 b b.3204 +test_ar:usage.o: U err +test_ar:usage.o: U errx +test_ar:usage.o: U fclose +test_ar:usage.o: U fgets +test_ar:usage.o: U fmtcheck +test_ar:usage.o: U fopen +test_ar:usage.o:0000000000000704 T hid_init +test_ar:usage.o:0000000000000000 T hid_parse_usage_in_page +test_ar:usage.o:0000000000000240 T hid_parse_usage_page +test_ar:usage.o:0000000000000368 T hid_usage_in_page +test_ar:usage.o:0000000000000576 T hid_usage_page +test_ar:usage.o: U malloc +test_ar:usage.o:0000000000000120 b npages +test_ar:usage.o:0000000000000124 b npagesmax +test_ar:usage.o:0000000000000112 b pages +test_ar:usage.o: U realloc +test_ar:usage.o: U sprintf +test_ar:usage.o: U sscanf +test_ar:usage.o: U strchr +test_ar:usage.o: U strcmp +test_ar:usage.o: U strdup +test_ar:usage.o: U strncmp +test_ar:parse.o: U free +test_ar:parse.o:0000000000000000 t hid_clear_local +test_ar:parse.o:0000000000001744 T hid_end_parse +test_ar:parse.o:0000000000000224 T hid_get_item +test_ar:parse.o:0000000000001808 T hid_locate +test_ar:parse.o:0000000000001952 T hid_report_size +test_ar:parse.o:0000000000000080 T hid_start_parse +test_ar:parse.o: U malloc +test_ar:parse.o: U memcpy +test_ar:parse.o: U memset +test_ar:descr.o: U __error +test_ar:descr.o: U free +test_ar:descr.o:0000000000000000 T hid_dispose_report_desc +test_ar:descr.o:0000000000000128 T hid_get_report_desc +test_ar:descr.o:0000000000000016 T hid_use_report_desc +test_ar:descr.o: U ioctl +test_ar:descr.o: U malloc +test_ar:descr.o: U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-size.txt new file mode 100644 index 0000000000..811ca3b279 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-print-size.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 0000000000000127 T hid_get_data +0000000000000128 0000000000000118 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit +0000000000000100 0000000000000010 b b.3186 +0000000000000000 0000000000000100 b b.3204 + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen +0000000000000704 0000000000000872 T hid_init +0000000000000000 0000000000000227 T hid_parse_usage_in_page +0000000000000240 0000000000000121 T hid_parse_usage_page +0000000000000368 0000000000000197 T hid_usage_in_page +0000000000000576 0000000000000123 T hid_usage_page + U malloc +0000000000000120 0000000000000004 b npages +0000000000000124 0000000000000004 b npagesmax +0000000000000112 0000000000000008 b pages + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free +0000000000000000 0000000000000071 t hid_clear_local +0000000000001744 0000000000000061 T hid_end_parse +0000000000000224 0000000000001510 T hid_get_item +0000000000001808 0000000000000129 T hid_locate +0000000000001952 0000000000000143 T hid_report_size +0000000000000080 0000000000000133 T hid_start_parse + U malloc + U memcpy + U memset + +descr.o: + U __error + U free +0000000000000000 0000000000000005 T hid_dispose_report_desc +0000000000000128 0000000000000064 T hid_get_report_desc +0000000000000016 0000000000000110 T hid_use_report_desc + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-hexa.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-hexa.txt new file mode 100644 index 0000000000..7b0fc51c26 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-hexa.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000080 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit +0000000000000064 b b.3186 +0000000000000000 b b.3204 + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen +00000000000002c0 T hid_init +0000000000000000 T hid_parse_usage_in_page +00000000000000f0 T hid_parse_usage_page +0000000000000170 T hid_usage_in_page +0000000000000240 T hid_usage_page + U malloc +0000000000000078 b npages +000000000000007c b npagesmax +0000000000000070 b pages + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free +0000000000000000 t hid_clear_local +00000000000006d0 T hid_end_parse +00000000000000e0 T hid_get_item +0000000000000710 T hid_locate +00000000000007a0 T hid_report_size +0000000000000050 T hid_start_parse + U malloc + U memcpy + U memset + +descr.o: + U __error + U free +0000000000000000 T hid_dispose_report_desc +0000000000000080 T hid_get_report_desc +0000000000000010 T hid_use_report_desc + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-octal.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-octal.txt new file mode 100644 index 0000000000..135ae43293 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-radix-octal.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000200 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit +0000000000000144 b b.3186 +0000000000000000 b b.3204 + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen +0000000000001300 T hid_init +0000000000000000 T hid_parse_usage_in_page +0000000000000360 T hid_parse_usage_page +0000000000000560 T hid_usage_in_page +0000000000001100 T hid_usage_page + U malloc +0000000000000170 b npages +0000000000000174 b npagesmax +0000000000000160 b pages + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free +0000000000000000 t hid_clear_local +0000000000003320 T hid_end_parse +0000000000000340 T hid_get_item +0000000000003420 T hid_locate +0000000000003640 T hid_report_size +0000000000000120 T hid_start_parse + U malloc + U memcpy + U memset + +descr.o: + U __error + U free +0000000000000000 T hid_dispose_report_desc +0000000000000200 T hid_get_report_desc +0000000000000020 T hid_use_report_desc + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-size-sort.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-size-sort.txt new file mode 100644 index 0000000000..62030c5fe5 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-size-sort.txt @@ -0,0 +1,29 @@ + +data.o: +0000000000000118 T hid_set_data +0000000000000127 T hid_get_data + +usage.o: +0000000000000004 b npages +0000000000000004 b npagesmax +0000000000000008 b pages +0000000000000010 b b.3186 +0000000000000100 b b.3204 +0000000000000121 T hid_parse_usage_page +0000000000000123 T hid_usage_page +0000000000000197 T hid_usage_in_page +0000000000000227 T hid_parse_usage_in_page +0000000000000872 T hid_init + +parse.o: +0000000000000061 T hid_end_parse +0000000000000071 t hid_clear_local +0000000000000129 T hid_locate +0000000000000133 T hid_start_parse +0000000000000143 T hid_report_size +0000000000001510 T hid_get_item + +descr.o: +0000000000000005 T hid_dispose_report_desc +0000000000000064 T hid_get_report_desc +0000000000000110 T hid_use_report_desc diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-no.txt new file mode 100644 index 0000000000..f7024a09d0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-no.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000128 T hid_set_data + +usage.o: +0000000000000120 b npages +0000000000000112 b pages +0000000000000000 b b.3204 +0000000000000100 b b.3186 +0000000000000124 b npagesmax +0000000000000000 T hid_parse_usage_in_page + U strchr + U strncmp + U strcmp +0000000000000240 T hid_parse_usage_page + U errx +0000000000000368 T hid_usage_in_page + U sprintf + U fmtcheck +0000000000000576 T hid_usage_page +0000000000000704 T hid_init + U fopen + U fgets + U __mb_sb_limit + U _CurrentRuneLocale + U sscanf + U strdup + U realloc + U malloc + U err + U fclose + +parse.o: +0000000000000000 t hid_clear_local +0000000000000080 T hid_start_parse + U malloc + U memset +0000000000000224 T hid_get_item + U memcpy + U free +0000000000001744 T hid_end_parse +0000000000001808 T hid_locate +0000000000001952 T hid_report_size + +descr.o: +0000000000000000 T hid_dispose_report_desc + U free +0000000000000016 T hid_use_report_desc + U malloc + U memcpy + U __error +0000000000000128 T hid_get_report_desc + U ioctl diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-num.txt new file mode 100644 index 0000000000..b1f6da65d7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-num.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000128 T hid_set_data + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen + U malloc + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp +0000000000000000 b b.3204 +0000000000000000 T hid_parse_usage_in_page +0000000000000100 b b.3186 +0000000000000112 b pages +0000000000000120 b npages +0000000000000124 b npagesmax +0000000000000240 T hid_parse_usage_page +0000000000000368 T hid_usage_in_page +0000000000000576 T hid_usage_page +0000000000000704 T hid_init + +parse.o: + U free + U malloc + U memcpy + U memset +0000000000000000 t hid_clear_local +0000000000000080 T hid_start_parse +0000000000000224 T hid_get_item +0000000000001744 T hid_end_parse +0000000000001808 T hid_locate +0000000000001952 T hid_report_size + +descr.o: + U __error + U free + U ioctl + U malloc + U memcpy +0000000000000000 T hid_dispose_report_desc +0000000000000016 T hid_use_report_desc +0000000000000128 T hid_get_report_desc diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-no.txt new file mode 100644 index 0000000000..f7024a09d0 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-no.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000000 T hid_get_data +0000000000000128 T hid_set_data + +usage.o: +0000000000000120 b npages +0000000000000112 b pages +0000000000000000 b b.3204 +0000000000000100 b b.3186 +0000000000000124 b npagesmax +0000000000000000 T hid_parse_usage_in_page + U strchr + U strncmp + U strcmp +0000000000000240 T hid_parse_usage_page + U errx +0000000000000368 T hid_usage_in_page + U sprintf + U fmtcheck +0000000000000576 T hid_usage_page +0000000000000704 T hid_init + U fopen + U fgets + U __mb_sb_limit + U _CurrentRuneLocale + U sscanf + U strdup + U realloc + U malloc + U err + U fclose + +parse.o: +0000000000000000 t hid_clear_local +0000000000000080 T hid_start_parse + U malloc + U memset +0000000000000224 T hid_get_item + U memcpy + U free +0000000000001744 T hid_end_parse +0000000000001808 T hid_locate +0000000000001952 T hid_report_size + +descr.o: +0000000000000000 T hid_dispose_report_desc + U free +0000000000000016 T hid_use_report_desc + U malloc + U memcpy + U __error +0000000000000128 T hid_get_report_desc + U ioctl diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-num.txt new file mode 100644 index 0000000000..b939feeeba --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-num.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000128 T hid_set_data +0000000000000000 T hid_get_data + +usage.o: +0000000000000704 T hid_init +0000000000000576 T hid_usage_page +0000000000000368 T hid_usage_in_page +0000000000000240 T hid_parse_usage_page +0000000000000124 b npagesmax +0000000000000120 b npages +0000000000000112 b pages +0000000000000100 b b.3186 +0000000000000000 T hid_parse_usage_in_page +0000000000000000 b b.3204 + U strncmp + U strdup + U strcmp + U strchr + U sscanf + U sprintf + U realloc + U malloc + U fopen + U fmtcheck + U fgets + U fclose + U errx + U err + U __mb_sb_limit + U _CurrentRuneLocale + +parse.o: +0000000000001952 T hid_report_size +0000000000001808 T hid_locate +0000000000001744 T hid_end_parse +0000000000000224 T hid_get_item +0000000000000080 T hid_start_parse +0000000000000000 t hid_clear_local + U memset + U memcpy + U malloc + U free + +descr.o: +0000000000000128 T hid_get_report_desc +0000000000000016 T hid_use_report_desc +0000000000000000 T hid_dispose_report_desc + U memcpy + U malloc + U ioctl + U free + U __error diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-size.txt new file mode 100644 index 0000000000..6cf9cc72f6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse-size.txt @@ -0,0 +1,29 @@ + +data.o: +0000000000000127 T hid_get_data +0000000000000118 T hid_set_data + +usage.o: +0000000000000872 T hid_init +0000000000000227 T hid_parse_usage_in_page +0000000000000197 T hid_usage_in_page +0000000000000123 T hid_usage_page +0000000000000121 T hid_parse_usage_page +0000000000000100 b b.3204 +0000000000000010 b b.3186 +0000000000000008 b pages +0000000000000004 b npagesmax +0000000000000004 b npages + +parse.o: +0000000000001510 T hid_get_item +0000000000000143 T hid_report_size +0000000000000133 T hid_start_parse +0000000000000129 T hid_locate +0000000000000071 t hid_clear_local +0000000000000061 T hid_end_parse + +descr.o: +0000000000000110 T hid_use_report_desc +0000000000000064 T hid_get_report_desc +0000000000000005 T hid_dispose_report_desc diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse.txt new file mode 100644 index 0000000000..77d46315b7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sort-reverse.txt @@ -0,0 +1,54 @@ + +data.o: +0000000000000128 T hid_set_data +0000000000000000 T hid_get_data + +usage.o: + U strncmp + U strdup + U strcmp + U strchr + U sscanf + U sprintf + U realloc +0000000000000112 b pages +0000000000000124 b npagesmax +0000000000000120 b npages + U malloc +0000000000000576 T hid_usage_page +0000000000000368 T hid_usage_in_page +0000000000000240 T hid_parse_usage_page +0000000000000000 T hid_parse_usage_in_page +0000000000000704 T hid_init + U fopen + U fmtcheck + U fgets + U fclose + U errx + U err +0000000000000000 b b.3204 +0000000000000100 b b.3186 + U __mb_sb_limit + U _CurrentRuneLocale + +parse.o: + U memset + U memcpy + U malloc +0000000000000080 T hid_start_parse +0000000000001952 T hid_report_size +0000000000001808 T hid_locate +0000000000000224 T hid_get_item +0000000000001744 T hid_end_parse +0000000000000000 t hid_clear_local + U free + +descr.o: + U memcpy + U malloc + U ioctl +0000000000000016 T hid_use_report_desc +0000000000000128 T hid_get_report_desc +0000000000000000 T hid_dispose_report_desc + U free + U __error diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sysv.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sysv.txt new file mode 100644 index 0000000000..f5cebe90c8 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-sysv.txt @@ -0,0 +1,70 @@ + + +Symbols from test_ar[data.o]: + +Name Value Class Type Size Line Section + +hid_get_data |0000000000000000| T | FUNC|0000000000000127| |.text +hid_set_data |0000000000000128| T | FUNC|0000000000000118| |.text + + +Symbols from test_ar[usage.o]: + +Name Value Class Type Size Line Section + +_CurrentRuneLocale | | U | NOTYPE| | |*UND* +__mb_sb_limit | | U | NOTYPE| | |*UND* +b.3186 |0000000000000100| b | OBJECT|0000000000000010| |.bss +b.3204 |0000000000000000| b | OBJECT|0000000000000100| |.bss +err | | U | NOTYPE| | |*UND* +errx | | U | NOTYPE| | |*UND* +fclose | | U | NOTYPE| | |*UND* +fgets | | U | NOTYPE| | |*UND* +fmtcheck | | U | NOTYPE| | |*UND* +fopen | | U | NOTYPE| | |*UND* +hid_init |0000000000000704| T | FUNC|0000000000000872| |.text +hid_parse_usage_in_page|0000000000000000| T | FUNC|0000000000000227| |.text +hid_parse_usage_page|0000000000000240| T | FUNC|0000000000000121| |.text +hid_usage_in_page |0000000000000368| T | FUNC|0000000000000197| |.text +hid_usage_page |0000000000000576| T | FUNC|0000000000000123| |.text +malloc | | U | NOTYPE| | |*UND* +npages |0000000000000120| b | OBJECT|0000000000000004| |.bss +npagesmax |0000000000000124| b | OBJECT|0000000000000004| |.bss +pages |0000000000000112| b | OBJECT|0000000000000008| |.bss +realloc | | U | NOTYPE| | |*UND* +sprintf | | U | NOTYPE| | |*UND* +sscanf | | U | NOTYPE| | |*UND* +strchr | | U | NOTYPE| | |*UND* +strcmp | | U | NOTYPE| | |*UND* +strdup | | U | NOTYPE| | |*UND* +strncmp | | U | NOTYPE| | |*UND* + + +Symbols from test_ar[parse.o]: + +Name Value Class Type Size Line Section + +free | | U | NOTYPE| | |*UND* +hid_clear_local |0000000000000000| t | FUNC|0000000000000071| |.text +hid_end_parse |0000000000001744| T | FUNC|0000000000000061| |.text +hid_get_item |0000000000000224| T | FUNC|0000000000001510| |.text +hid_locate |0000000000001808| T | FUNC|0000000000000129| |.text +hid_report_size |0000000000001952| T | FUNC|0000000000000143| |.text +hid_start_parse |0000000000000080| T | FUNC|0000000000000133| |.text +malloc | | U | NOTYPE| | |*UND* +memcpy | | U | NOTYPE| | |*UND* +memset | | U | NOTYPE| | |*UND* + + +Symbols from test_ar[descr.o]: + +Name Value Class Type Size Line Section + +__error | | U | NOTYPE| | |*UND* +free | | U | NOTYPE| | |*UND* +hid_dispose_report_desc|0000000000000000| T | FUNC|0000000000000005| |.text +hid_get_report_desc |0000000000000128| T | FUNC|0000000000000064| |.text +hid_use_report_desc |0000000000000016| T | FUNC|0000000000000110| |.text +ioctl | | U | NOTYPE| | |*UND* +malloc | | U | NOTYPE| | |*UND* +memcpy | | U | NOTYPE| | |*UND* diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-undef.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-undef.txt new file mode 100644 index 0000000000..3f1c6022e9 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar-undef.txt @@ -0,0 +1,33 @@ + +data.o: + +usage.o: + U _CurrentRuneLocale + U __mb_sb_limit + U err + U errx + U fclose + U fgets + U fmtcheck + U fopen + U malloc + U realloc + U sprintf + U sscanf + U strchr + U strcmp + U strdup + U strncmp + +parse.o: + U free + U malloc + U memcpy + U memset + +descr.o: + U __error + U free + U ioctl + U malloc + U memcpy diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar.uu b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar.uu new file mode 100644 index 0000000000..d92e8e9fdc --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_archive1/test_ar.uu @@ -0,0 +1,356 @@ +begin 644 test_ar +M(3QA@```'H``` +M!Z````>@```'H```'Y0``!^4```?E```'Y0``!^4```V&```-A@``#88:&ED +M7V=E=%]D871A`&AI9%]S971?9&%T80!H:61?<&%RF4` +M:&ED7V1I'$4QP$2+5F!%A=MT64.-!!-$B=+!Z@/!Z`.)P2G1>#]( +M8\)$C4D!2(T4!S'_#[8"C0S]`````/_'2/_"T^!!"X +M`0```-/@1(G10=/X_\A!(<"+1@2%P'@$1(G`P[D@````1"G90=/@0=/X1(G` +MPY!$BTY@BW8@#0=/@0=/BP>H#B<%!]]`IT7@N2&/"1(U)`4B--`E(``7@0`0,,!PB0`0``%````!P````````` +M?P``````````````%````#0`````````=@```````````````"YS>6UT86(` +M+G-T'0`+F1A=&$`+F)S[K#V9F9I#_ +MPTF#Q"!$.?MTK$F+/"1,B?)(B>[H`````(7`=>)-C74!18ML)!A%A>U^BTF+ +M7"00,>WK#__%2(/#$$0Y[0^$<____TB+.TR)]N@`````A`0 +M"T,(Z5G___]F9F:09F:09F:09F:0055)B?U!5%532(/L"$B+!0````!(A[H```` +M`(7`=>:+0PA(@\0(6UU!7$%=PTB#Q`BX_____UM=05Q!7<.^`````+\!```` +M,<#H`````&9F9I!F9I!$BPT`````4P^WWT6%R7XO2(LU`````,'O$#')NB`` +M```Y?@AU$NLTBT0R"$R-!!9(@\(@.?AT(?_!1#G)=>F)VKX`````OP`````Q +MP.@`````6[@`````PTR)QHM^&(7_?MQ(BT80BU`(@_K_="PYVG1-2(U0$#'V +MZQAF9I!FD(M*"$B)T(/Y_W002(/"$#G9="W_QCG^=>?KI$B+.+X`````Z``` +M``")VDB)QK\`````,<#H`````%NX`````,-;2(L`PV9F9I!F9F:09F:02(/L +M"$B+-0````!(A?9T6D2+!0````!%A?H`````/_(#X6"`0``QX0D[``` +M`/____\/ME0D$(32=$F+-0````!(BST`````3(GYZQQF9I!FD$B8]D3'04!T +M&0^V40'&`5](_\&$TG0;#[["A&`[!0````!]6$ACT$B+!0`` +M``#V1-!!0'1'2(7;#X0I`0``BT,<.4,8#XUN`0``2&-#&$B+4Q!!_\9(P>`$ +M2(DL$$AC0QB+E"3L````2(M+$$C!X`2)5`@(_T,8Z8[^__^+!0`````Y!0`` +M``!\.DB+/0````!(A?\/A.8```"-<`6)-0````!(8_9(P>8%Z`````!(B04` +M````2(,]```````/A#?H```` +M`(/X`@^$9O[__TB-E"3L````,05_#C7`*2(M[$(ES +M'$AC]DC!Y@3H`````$B%P$B)0Q`/A6_^__^^`````+\!````Z`````"^```` +M`+\!````,<#H`````+X`````OP$````QP.@`````2(M4)`B^`````+\!```` +M,<#H```````````````````````````````````````D1G)E94)31#H@"ET` +M(#!X)7@@)5M>"ET`("5D("5;7@I=`'-T6YT87@@97)R;W(``!0``````````7I2``%X$`$##`<( +MD`$``"0````<`````````.,`````68P%@P>-!(8&40Y`CP*.`P`````````D +M````1`````````!Y`````$(.$(T"10X800X@00XH1`XP@P6&!(P#%````&P` +M````````Q0````!(#A"#`@``%````(0`````````>P````!$#A``````-``` +M`)P`````````:`,```!"#A!,#AA"#B!"#BA!#C!!#CA'#K`"@P>&!HP%C02. +M`X\"````````+G-Y;71A8@`N``````````+````"`````@`````````&``````````1`````P`````````` +M``````````````!8"````````&<````````````````````!```````````` +M`````````0````(```````````````````````````P```````!(`P`````` +M``P````.````"``````````8``````````D````#```````````````````` +M`````$@/````````!@$```````````````````$````````````````````` +M```````````````````````````````!````!`#Q_P`````````````````` +M`````````P`!`````````````````````````````P`#```````````````` +M`````````````P`$```````````````````````)`````0`$`'@````````` +M!``````````0`````0`$`'``````````"````````````````P`&```````` +M```````````````6`````0`$````````````9``````````=`````0`$`&0` +M````````"@```````````````P`'```````````````````````D`````0`$ +M`'P`````````!````````````````P`(```````````````````````````` +M`P`%```````````````````````N````$@`!````````````XP````````!& +M````$`````````````````````````!-````$``````````````````````` +M``!5````$`````````````````````````!<````$@`!`/``````````>0`` +M``````!Q````$`````````````````````````!V````$@`!`'`!```````` +MQ0````````"(````$`````````````````````````"0````$``````````` +M``````````````"9````$@`!`$`"````````>P````````"H````$@`!`,`" +M````````:`,```````"Q````$`````````````````````````"W````$``` +M``````````````````````"]````$`````````````````````````#+```` +M$`````````````````````````#>````$`````````````````````````#E +M````$`````````````````````````#L````$``````````````````````` +M``#T````$`````````````````````````#[````$``````````````````` +M``````#_````$```````````````````````````=7-A9V4N8P!N<&%G97,` +M<&%G97,`8BXS,C`T`&(N,S$X-@!N<&%G97-M87@`:&ED7W!A`@````````H````$```````````````E`@````````(````5```` +M_/________\K`@````````H````$``````````````!'`@````````(````$ +M````;`````````!3`@````````(````$````=`````````"(`@````````H` +M```'````$`````````"-`@````````H````$````9`````````"4`@`````` +M``(````5````_/________^9`@````````H````$````9`````````"K`@`` +M``````H````'``````````````"W`@````````(````3````_/_________# +M`@````````H````*``````````````#(`@````````H````'````%P`````` +M``#K`@````````(````9````_/________\<`P````````(````:````_/__ +M______](`P````````(````;````_/________]3`P````````(````<```` +M_/________^1`P````````H````'````'`````````"9`P````````(````= +M````_/________^[`P````````(````;````_/_________"`P````````(` +M```<````_/________\&!`````````(````>````_/________\D!``````` +M``(````;````_/________\P!`````````(````<````_/________^$!``` +M``````(````$````>`````````"*!`````````(````$````=`````````"3 +M!`````````(````$````;`````````"E!`````````(````$````>``````` +M``"Q!`````````(````?````_/________^X!`````````(````$````;``` +M``````"_!`````````(````$````:P````````#,!`````````(````$```` +M=`````````#A!`````````(````$````;`````````#G!`````````(````$ +M````=``````````'!0````````(````@````_/________\9!0````````H` +M```'````4``````````C!0````````(````A````_/________\U!0`````` +M``H````'````)0`````````]!0````````(````=````_/________]8!0`` +M``````H````'````,0````````!@!0````````(````=````_/________]V +M!0````````H````*````(`````````""!0````````(````3````_/______ +M__^+!0````````(````$````=`````````"4!0````````(````@````_/__ +M______^;!0````````(````$````;`````````"H!0````````(````B```` +M_/_________0!0````````(````?````_/_________B!0````````H````' +M````0@````````#L!0````````(````A````_/_________Q!0````````H` +M```'````.P````````#]!0````````(````A````_/________\"!@`````` +M``H````'````2@`````````.!@````````(````A````_/________\8!@`` +M``````H````'````&0`````````D!@````````(````A````_/________\@ +M``````````H````"``````````````!(``````````H````"````\``````` +M``!P``````````H````"````<`$```````"(``````````H````"````0`(` +M``````"@``````````H````"````P`(```````!P87)S92YO+R`@("`@("`@ +M,3(P.#@T,#`W-B`@,"`@("`@,"`@("`@,3`P-C0T("`U-S`T("`@("`@8`I_ +M14Q&`@$!"0```````````0`^``$`````````````````````````(`L````` +M````````0```````0``-``H`QT%*`(` +M``````!,B>_'A1@"````````Z)/^__]F9I!(BU402#M5"`^#X`$```^V`DB- +M<@$\_@^$DP````^VT(G1@^$#@_D#B<@/A-4```!!B=2)UTB-!`9!P>P"P>\$ +M08/D`X/Y`4B)11`/A(8```!S,S'208/\`0^$A0```)`/@XP```"-1_B#^`0/ +MANL```"X_O___TB#Q'A;74%<05U!7D%?PX/Y`@^$M````(/Y!`^$B````$B# +MQ'BX_____UM=05Q!74%>05_#9F9FD`^V2@(/MD(!2(UR!`^V>@/!X0@)P8G( +M2`'P@_D!2(E%$`^%>O___T&#_`$/MA8/A7O___^#_PMV:[C]____9I#KA4&# +M_`)T&;C[____9F:0Z7+___^Q!+@$````Z1____^#_PIV4+C\____Z5?___\/ +MME8!#[8&P>(("<(/MD8"P>`0"<(/MD8#P>`8"<+I$O___P^V5@$/M@;!X@@) +MPND!____B?C_),4`````B<#_),4`````B?C_),4`````@+VH`@````^$#0$` +M`+IP````3(G^3(GWZ`````"+13A!B48@QH6H`@```(N5,`(``$$Y5B"X`0`` +M``^$R/[____"#X79_?__Z;O^__^^`@```+D"````BX4L`@``T_BH`0^%=`(` +M`$B+51!(.U4(QX48`@````````^"(/[__S'`Z8+^____16R)56A,B>ZZ<``` +M`$B)Y\=%<`,```#H`````$R)[XM<)"#HC^__^)T8N5 +M&`(```M-&(/Z8XE-0`^/-_W__TACPHF,A8@```"-0@&)A1@"``#I'_W__PM5 +M&,>%'`(```$```")543I"OW__PM5&(E52.G__/__B55,Z??\__^)55#I[_S_ +M_XE55.GG_/__B5589F9FD.G;_/__B55%L`(````` +M``#'A:P"````````Z87\__^)51R)C2`"``#I=_S__XE5(.EO_/__B54\Z6?\ +M__^_<````&:0Z`````"Z<````$B)PTR)[DB)Q^@`````2(F=@````.D\_/__ +MP>(0B548Z3'\__](BYV`````3(GONG````!(B=[H`````$B)W^@`````Z0W\ +M__^+A1@"``!,B>Y,B??_R#G"#T["_X4D`@``NG````!(F(N$A8@```")14#H +M`````(M%<(M5<(N$A:P"``!!B49@BT4T`825K`(``$G'1F@`````Z5#]__^) +M572#X@*)=7`/A)\```"+E1P"``"+13S'A20"````````QT4\`0```(72B84H +M`@``#X02^___BTU$.TU(?R6+E1@"``!(8\*#^F*)C(6(````?PF-0@&)A1@" +M``#_P3E-2'W;QT5$`````,=%2`````#'A1P"````````ZZ +M<````.@`````08E>(+IP````2(GF3(G_B5PD(.@`````Z:+\__^+A1P"``"% +MP'0&BT5$B45`NG````!,B>Y,B??H`````(M%<$G'1F@`````3(GOBU5PBX2% +MK`(``$&)1F"+13P/KT4T`825K`(``.A)^?__QX4<`@```````.E$_/__9F9F +MD&9FD&9FD%5(B?U32(/L"$B+OX````!(A?]U!>L82(G?2(M?:.@`````2(7; +M2(F=@````'7H2(/$"$B)[UM=Z0````!F9I!!54&)];X!````051!B=1$B<)5 +M4TB)RT2)X=/F2(/L".@`````2(G%2(G>2(GOZ`````"%P'0N1#EC6'7K]D-< +M`77E1#EK*'7?2(GO9F9FD.@`````2(/$"+@!````6UU!7$%=PTB)[^@````` +MQT,<`````$B#Q`@QP%M=05Q!7<-F9F:09F9FD&9F9I!F9I!!5T%6055%,>U! +M5$&)]#'V18GG58G5NG````!32(G[2(/L>$B)Y^@`````1(GAO@$```!(B=_3 +MYHGJZ`````!(B<-(B>9(B=_H`````(7`=!M$.60D6'7D1HNLNZP" +M``#KVDB)W^@`````08U5#D2)Z(/`!P](PDB#Q'A;74%<05U!7D%?P?@#PP`` +M)$9R965"4T0Z('-R8R]L:6(O;&EB=7-B:&ED+W!A"!%>'`@)`!'0T,Z("A'3E4I(#0N,BXQ +M(#(P,#!`!`PP'")`!```4 +M````'`````````!'```````````````<````-`````````"%`````$J,!(,% +M5@XPC@*-`P```#0```!4`````````.8%````0@X0CP))#AB.`T4.((T$1@XH +M00XPA@:,!40..$0.L`&#!P``````'````(P`````````/0````!!#A"&`D0. +M&$0.((,#```D````K`````````"!`````$(.$(T"2@X8C`-'#B!!#BB#!88$ +M3`XP-````-0`````````CP````!"#A!"#AA"#B"-!(X#CP)%#BB,!4D.,(8& +M2`XX@P='#K`!````````+G-Y;71A8@`N0<````````"````#P```/S_________QP<` +M```````"````"P```/S_________VP<````````"````"0```/S_________ +MZ0<````````"````#````/S_________#`@````````"````#P```/S_____ +M____"0<````````"````#@```/S_________```````````!`````@```#0% +M````````"``````````!`````@```.L$````````$``````````!`````@`` +M`/D$````````&``````````!`````@```-T#````````(``````````!```` +M`@```-T#````````*``````````!`````@```*T$````````,``````````! +M`````@```+4$````````.``````````!`````@```+T$````````0``````` +M```!`````@```,4$````````2``````````!`````@````$%````````4``` +M```````!`````@````D%````````6``````````!`````@```#\%```````` +M8``````````!`````@```-0#````````:``````````!`````@```,4#```` +M````<``````````!`````@```&4#````````>``````````!`````@```"P# +M````````@``````````!`````@```-\"````````B``````````!`````@`` +M`"($````````D``````````!`````@```%$$````````F``````````!```` +M`@```&8$````````H``````````!`````@```'$$````````J``````````! +M`````@```'D$````````L``````````!`````@```($$````````N``````` +M```!`````@```(8"````````P``````````!`````@```(D$````````R``` +M```````!`````@```)4$````````T``````````!`````@```)T$```````` +MV``````````!`````@```*4$````````(``````````*`````@`````````` +M````.``````````*`````@```%``````````6``````````*`````@```.`` +M````````D``````````*`````@```-`&````````L``````````*`````@`` +M`!`'````````V``````````*`````@```*`'````````9&5S8W(N;R\@("`@ +M("`@(#$R,#@X-#`P-S8@(#`@("`@(#`@("`@(#$P,#8T-"`@,3DU,B`@("`@ +M(&`*?T5,1@(!`0D```````````$`/@`!`````````````````````````#`" +M`````````````$```````$``"P`(`.D`````9F9FD&9F9I!F9I!,B60D\$&) +M]$R);"3X28G]28U\)`A(B6PDZ$B)7"3@2(/L*(GUZ`````!(A`2) +M*$R)XDR)[DB)P^@`````2(G82(ML)!!(BUPD"$R+9"083(ML)"!(@\0HPS'; +MZ`````#'``P```#KU6:04S'`OA55!$1(@>P0!```2(GBQP0D`````.@````` +M,=*%P'@0BS0D2(U\)`3H`````$B)PDB!Q!`$``!(B=!;PP`D1G)E94)31#H@ +M!`!`PP'")`!```4````'``````` +M```%```````````````<````-`````````!N`````$6,`TB-`E8.,(,%A@0` +M`!P```!4`````````$``````00X03@Z@"(,"`````````"YS>6UT86(`+G-T +M7-C=&Q? +M;6%L;&]C`&UE;7-T871?71E0!M96US=&%T7VUT;%]F"2)WDB)[^@`````,=*%P'@42(M<)`A( +MBVPD$(G02(/$&,-F9I"Z_____^OE`!0``````````7I2``%X$`$##`<(D`$` +M`!0````<`````````$<`````3@X@A@*#`Q0````T`````````$<`````3@X@ +MA@*#`P!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6UT86(`+G-T7-C=&Q?=6UA```` +M%0`````````"````"````/S_________)``````````"````"0```/S_____ +M____9``````````"````"P```/S_________<@`````````"````#````/S_ +M________(``````````*`````@``````````````.``````````*`````@`` +M`%``````````;65M`#6\-F9I!F9I!F9I!!5TF)_T%628GVO@````!!54%455-(@>SX +M`0``2(L'3(GW2(E$)`CH`````(7`#X6/!```@#T``````'0*2(,]``````!U +M'T''1P@'````N/____](@<3X`0``6UU!7$%=05Y!7\-(C90D[`$``$4QP+D$ +M````O@$```!,B??H#?___X7`#X7E`P``2(V4).`!``!%,<`Q]KD(````3(GW +MZ.O^__^%P`^%PP,``$B-E"3H`0``13'`N00```"^`@```$R)]^C&_O__A<`/ +MA9X#``"+O"3L`0``_\=(8_](P><%Z`````!(A_[_ +M_X7`B<,/A=8"``"+C"3L`0``2(M4)!!!N'@```!(BW0D&$R)]__!2&/)2,'A +M!>A)_O__A<")PP^%I`(``$R+I"0``0``,=MF9I!FD$B-K"2@`0``2HTT([D! +M````3(GW2`'=2(GJZ`````!(A<`/B&@"``!(_\@/A9@"``"`?0``=!:-0P%( +M_\-(@_L@=;U(F,:$!)\!````2(-\)`@`#X2%`@``2(V4)*`!``"^`@```$R) +M_^@`````2(7`2(G##X1D`@``2(G?Z`````!(BX0D6`$``$B)0UA(BX0D8`$` +M`$B)0V!(BX0D:`$``$B)@X````#VA"3S````(`^%T@```(N$).P!``#_P(7` +M#X[!````2(ML)!!%,>2X`0```$2)X=/@A80DZ`$```^$B0```$B+11!(`4-8 +M2(M%&$@!0V!(BW4(2(7V=#!(C90DP`$``$4QP+D8````3(GWZ!C]__^%P$&) +MQ0^%$@(``$@/OX0DT`$``$@!0WA(BW4`2(7V=#=(C90DP`$``$4QP+D8```` +M3(GWZ-_\__^%P$&)Q0^%V0$``$@/OX0DT`$``$@!0WAF9F:09F:0BX0D[`$` +M`$'_Q$B#Q2#_P$0YX`^/1____XN$)*````!(B4-`2(G"2`^O0V!(#Z]36$B) +M0U!(B5-(2"G"2(E3:&:#O"3J`````0^&E@$```^WC"3L````B[0DJ````#'2 +MB?#W\8G!2(E+*$B+0T!(#Z]#*$B)0S!(BT-82"M#8$B)0W!(B[0D*`$``$B% +M]G0U2(V4),`!``!%,<"Y&````$R)]^@8_/__2`^_A"30`0``2`&#B`$``$B+ +MM"3``0``2(7V=S\__](BWPD$.@````` +M,<#I*?S__V9FD&:0NP8```!(BWPD$.@`````3(G_Z`````"X_____T&)7PCI +M__O__XN$))P```!(`4-X2(F#D`$``.N"NP@```#KQ4&)1PBX_____^G6^___ +M2(V4)*`!``"^`@```$R)_^@`````2(7`2(G##X5[_?__2(M\)!#H`````$R) +M_^@`````N/____]!QT<(`0```.F1^___N/____]!QT<(!@```.E_^___2(M\ +M)!#H`````$R)_^@`````N/____]%B6\(Z5_[__\/MX0D[`````^OA"2H```` +M2(E#*.EL_O__9I!!5T%628G^055!5%532(/L&$B+!TB-7"0(2(UL)!!,C60D +M%$B)!"3IL@```&9F9I!(@WPD"`0/A?P```"#?"00(`^/50$``$4QP#')2(G: +M3(GFOP````!(QT0D"`0```#H`````(7`#XA+`0``2(-\)`@$#X6_````2&-\ +M)!!(8T0D%$C!YP9(@\=X2`^O^$B#QWA(B7PD".@`````2(7`28G%#X37```` +M13'`,05_#3(GBO@(```!, +MB??H`````$B%P$B)PP^%[0```$R)]^@`````3(GOZ`````!!QT8(`0```$B# +MQ!BX_____UM=05Q!74%>05_#0<=&"`0```!(@\08N/____];74%<05U!7D%? +MP^@`````@S@-#X16____Z`````"#.`%FD`^$1O___[C_____0<=&"`(```#I +M7?___TB+1"0(2(7`#X1<`0``2(/X#P^&J`$``$&#?0`!#X6=`0``08M%!(/X +M(`^'J@$``(E$)!!!BT4(A<")1"04#XXF`0``28UM$$4Q_TB#/"0`28GL#X03 +M____2(GJO@(```!,B??H`````$B%P$B)PP^$]_[__TB)WTB#Q7CH`````$F+ +M1"1(2(E#6$F+1"102(E#8$F+1"182(F#@````(M$)!"%P'XV,=)(@\5`2(M% +MT$B)A-.8)@``2(M%T$@!0WA(BT7`2`%#6$B+1$B)@Y`!``!(BX.(`0``2`%#>$'_QT0Y?"04 +M#X_A_O__3(GOZ``````QP.GD_?__Z`````"#.`UT&69FD&:0Z`````"#.`%T +M"D''1@@"````ZPA!QT8(`P```$R)[^@`````2(/$&+C_____6UU!7$%=05Y! +M7\-!QT8(`@```$R)[^@`````N/_____I@_W__T''1@@$````Z\`````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````&ME&-P=7,`=FTN>F]N95]C +M;W5N=`!V;2YZ;VYE7W-T871S`%]U;6%?:V5GE(``7@0`0,,!PB0`0``%````!P````````` +M/P````!$#A"#`@``%````#0`````````)P````!!#A"#`@``-````$P````` +M````#@4```!"#A"/`D4.&(X#2@X@0@XH00XP00XX1PZP!(,'A@:,!8T$```` +M```T````A`````````#,`P```$(.$$(.&(X#CP)%#B!"#BA!#C!!#CA$#E"# +M!X8&C`6-!`````````!'0T,Z("A'3E4I(#0N,BXQ(#(P,#6UT86(`+G-T7-C=&Q?=6UA`'-YP`````````*`````P`````````````` +MF``````````"````#0```/S_________I@`````````"`````P````,````` +M````L``````````"`````P````L`````````4P$````````"````#@```/S_ +M________*P(````````"````"P```/S_________>@(````````"````#P`` +M`/S_________C@(````````"````$````/S_________D`0````````"```` +M$0```/S_________JP0````````"````$0```/S_________LP0````````" +M````$@```/S__________P0````````"````$P```/S_________%04````` +M```"````$0```/S_________'04````````"````$@```/S_________2P4` +M```````"````$0```/S_________4P4````````"````$@```/S_________ +MTP4````````*````"````!$`````````X04````````"````%0```/S_____ +M____&08````````"````#@```/S_________-08````````*````"````!\` +M````````.@8````````"````%0```/S_________1P8````````"````%@`` +M`/S_________6@8````````"````$0```/S_________:@8````````*```` +M"```````````````>`8````````"````%0```/S_________A08````````" +M````%@```/S_________DP8````````"````%@```/S_________X`8````` +M```"````$P```/S_________]`8````````"````$@```/S__________`8` +M```````"````$0```/S_________.0<````````"````%@```/S_________ +M1P<````````"````%@```/S_________S0<````````"````#P```/S_____ +M____Y0<````````"````$````/S_________U@@````````"````$0```/S_ +M________X@@````````"````%@```/S_________\0@````````"````%@`` +M`/S_________$`D````````"````$0```/S_________-`D````````"```` +M$0```/S_________```````````!````"````"T`````````&``````````! +M````"````#<`````````,``````````!````"````$$`````````2``````` +M```!````"````$L`````````(``````````*`````@``````````````.``` +M```````*`````@```$``````````4``````````*`````@```'`````````` +MB``````````*`````@```(`%````````+S`@("`@("`@("`@("`@(#$R,#DT +M,#0Y-C<@(#`@("`@(#`@("`@(#$P,#8T-"`@-#DW-B`@("`@(&`*?T5,1@(! +M`0D```````````$`/@`!`````````````````````````"`)```````````` +M`$```````$``#0`*`$AC]E-(B`#6\-F9I!F9I!F9I!!5T%628G^055) +MB?6^`````$%455-(@>S("```2(L'3(GO2(E$)`CH`````(7`#X67`@``@#T` +M`````'0*2(,]``````!U'T''1@@'````N/____](@<3("```6UU!7$%=05Y! +M7\-(C90DO`@``$4QP+D$````O@$```!,B>_H#?___X7`#X5D`@``@[PDO`@` +M`"`/CT0"``!(C90DL`@``$4QP#'VN0@```!,B>_HW?[__X7`#X4T`@``2(NT +M)+`(``!(A?8/A*`!``!(C40D$$R-O"20"```2(/`($B)!"1(C90D$`@``$4Q +MP+F`````3(GOZ-?^__^%P(G##X5U`0``3(ND)$@(```QVV9FD$F-+!]*C30C +MN0$```!,B>](B>KH`````$B%P`^(0@$``$C_R`^%B@$``(!]``!FD'06C4,! +M2/_#2(/[('7"2)C&A`2/"````$ACC"2\"```2(NT)%`(``!(C50D$$4QP$R) +M[TC!X0;H5/[__X7`B<,/A?(```!(@WPD"``/A/P```!,B?J^`0```$R)]^@` +M````2(7`2(G##X3@````2(G?Z`````"+A"2\"```A<`/CGX```!(BQ0D2(G9 +M,?9FD$B+0N!(`4-(_\9(BT+H2`%#4$B+0O!(`4-82(M"^$@!0V!(BP)("4,X +M2(M"X$B)@9@!``!(BT+H2(F!H`$``$B+0O!(B8&H`0``2(M"^$B)@;`!``!( +MBP)(@\)`2(F!N`$``$B!P2@!```YM"2\"```?XU(BT-(2"M#4$B)0VA(BT-8 +M2"M#8$B)0W!(B[0D$`@``$B%]@^%=?[__S'`Z>']__^[!@```$R)]^@````` +MN/____]!B5X(Z<;]__],B?J^`0```$R)]^@`````2(7`2(G##X4$____3(GW +MZ`````"X_____T''1@@!````Z9#]__^["````.NMN/____]!QT8(!@```.EW +M_?__N/____]!QT8(!````.EE_?__08E&"+C_____Z5?]__]F9I!!5T%6055) +MB?U!5%532(/L&$R+/TB-7"0(2(UL)!!,C70D%.FL````2(-\)`@$#X7Z```` +M@WPD$"`/CU,!``!%,<`QR4B)VDR)]K\`````2,=$)`@$````Z`````"%P`^( +M20$``$B#?"0(!`^%O0```$AC?"002&-$)!1(P><&2(/'($@/K_A(@\<@2(E\ +M)`CH`````$B%P$F)Q`^$U0```$4QP#')2(G:2(G&OP````#H`````(7`#XDB +M`0``Z`````"#.`P/A4L"``!,B>?H`````$4QP#')2(G:2(GNOP````!(QT0D +M"`0```#H`````(7`#XDN____Z`````"#.`UT#N@`````@S@!9F9FD'4<0<=% +M"`,```!(@\08N/____];74%<05U!7D%?PT''10@%````N/____](@\086UU! +M7$%=05Y!7\-(B>J^`0```$R)[^@`````2(7`2(G##X7O````3(GOZ`````!, +MB>?H`````$''10@!````2(/$&+C_____6UU!7$%=05Y!7\-!QT4(!````$B# +MQ!BX_____UM=05Q!74%>05_#Z`````"#.`T/A%;___]F9F:0Z`````"#.`$/ +MA$3___^X_____T''10@"````Z5O___](BT0D"$B%P`^$&@$``$B#^`\/AF(! +M``!!@SPD`0^%5P$``$&+1"0$@_@@#X=C`0``B40D$$&+1"0(A<")1"04#X[B +M````28UL)!!%,?9FD$V%_P^$$?___TB)ZKX!````3(GOZ`````!(A4B)VC')9I!(@\5`_\%(BT7`2`%# +M2$B+1!("4,X2(M%P$B)@I@!``!( +MBT7(2(F"H`$``$B+1=!(B8*H`0``2(M%V$B)@K`!``!(BT7@2(F"N`$``$B! +MPB@!```Y3"00?XY(BT-(2"M#4$'_QDB)0VA(BT-82"M#8$B)0W!$.70D%`^/ +M*/___TR)Y^@`````,<#I)/[__^@`````@S@-D'04Z`````"#.`%T"D''10@" +M````ZPA!QT4(`P```$R)Y^@`````2(/$&+C_____6UU!7$%=05Y!7\-!QT4( +M`@```$R)Y^@`````N/_____IQ_W__T''10@$````Z\`````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````!K97)N+G-M<"YM87AC +M<'5S`&MEE(``7@0 +M`0,,!PB0`0``%````!P`````````/P````!$#A"#`@``%````#0````````` +M)P````!!#A"#`@``-````$P`````````_0(```!"#A!"#AB.`X\"10X@C01* +M#BA!#C!!#CA'#H`2@P>&!HP%```````T````A`````````!^`P```$(.$$(. +M&$(.((T$C@./`D4.*$$.,$$..$0.4(,'A@:,!0````````!'0T,Z("A'3E4I +M(#0N,BXQ(#(P,#6UT86(`+G-T7-C=&Q?;6%L;&]C`'-Y`P`` +M``````(````0````_/________^[`P````````H````(````$0````````#) +M`P````````(````3````_/________\!!`````````(````4````_/______ +M__\=!`````````H````(````(P`````````B!`````````(````3````_/__ +M______\O!`````````(````5````_/________]`!`````````(````6```` +M_/________]0!`````````H````(``````````````!>!`````````(````3 +M````_/________]K!`````````(````5````_/________]U!`````````(` +M```5````_/_________&!`````````(````1````_/_________:!``````` +M``(````0````_/_________B!`````````(````6````_/________\?!0`` +M``````(````5````_/________\Q!0````````(````5````_/________^U +M!0````````(````.````_/_________-!0````````(````/````_/______ +M__]\!@````````(````6````_/________^(!@````````(````5````_/__ +M______^3!@````````(````5````_/________^R!@````````(````6```` +M_/_________6!@````````(````6````_/________\```````````$````( +M````-0`````````8``````````$````(````10`````````P``````````$` +M```(````40`````````@``````````H````"```````````````X```````` +M``H````"````0`````````!0``````````H````"````<`````````"(```` +M``````H````"````<`,```````!M96US=&%T+F\O("`@("`@,3(P.30P-#DV +M-R`@,"`@("`@,"`@("`@,3`P-C0T("`W-3DR("`@("`@8`I_14Q&`@$!"0`` +M`````````0`^``$`````````````````````````"`L`````````````0``` +M````0``.``L`@_\(=@NX`````,-F9I!FD(GX_R3%`````+@`````P[@````` +MP[@`````P[@`````P[@`````P[@`````P[@`````P[@`````PV9F9I!F9I!( +MBP?#9F9FD&9F9I!F9F:02(N'F"<``,-F9F:09F9FD(M'",-F9F:09F9FD&9F +M9I!(QT`````!(QX>``````````$C'AX@!````````2,>'D`$```````!FD$C'@)@! +M````````2,>`H`$```````!(QX"H`0```````$C'@+`!````````2,>`N`$` +M``````!(QX37F"8```````!(_\)(!2@!``!(@_H@=:[SPV9F9I!F9F:09F9F +MD$B-1P3#9F9FD&9F9I!F9I"+!\-F9F:09F:09F:09F:02(M'*,-F9F:09F9F +MD&9FD$B+1S##9F9FD&9F9I!F9I!(BT`````PV9F9I!F9F:0 +M2&/V2(N$]X@```##9F9FD$AC]DB)E/>(````PV9F9I!(8_9(BX3W"`$``,-F +M9F:02&/V2(F4]P@!``##9F9FD$B+AX@!``##9F9FD&9F9I!(BX>0`0``PV9F +M9I!F9F:02&/V2&GV*`$``$B+A#>8`0``PV9F9I!F9I!F9I!F9I!(8_9(:?8H +M`0``2(N$-Z`!``##9F9FD&9FD&9FD&9FD$AC]DAI]B@!``!(BX0WJ`$``,-F +M9F:09F:09F:09F:02&/V2&GV*`$``$B+A#>P`0``PV9F9I!F9I!F9I!F9I!( +M8_9(:?8H`0``2(N$-[@!``##9F9FD&9FD&9FD&9FD$AC]DACTDB)\$C!X`5( +MC02P2`'P2`'02(N$Q\`!``##2&/V2&/22(GP2,'@!4B-!+!(`?!(`=!(B8S' +MP`$``,-(8_9(8])(B?!(P>`%2(T$L$@!\$@!T$B+A,=``@``PTAC]DACTDB) +M\$C!X`5(C02P2`'P2`'02(F,QT`"``##2&/V2(N$]Y@F``##9F9FD$B#[`B_ +M$````.@`````2(G",P1,B>[H +M`````(7`==E(@\0(2(G86UU!7$%=PV9F9I!F9I!32(G[2(L_2(7_=#5F9F:0 +M2(N7F"<``$B%TG0.2(N'H"<``$B)@J`G``!(BX>@)P``2(D0Z`````!(BSM( +MA?]USUO#9F9FD&9FD&9FD&9FD%-(B?OH`````$B)WUOI````````2U9-('-H +M;W)T(')E860`56YK;F]W;B!E"@```````&4````` +M```````````````!`````````````````````0````(````````````````` +M````````B`X````````0!0````````T````)````"``````````8```````` +M``D````#`````````````````````````)@3````````Q@,````````````` +M``````$````````````````````````````````````````````````````! +M````!`#Q_P```````````````````````````P`!```````````````````` +M`````````P`#`````````````````````````````P`$```````````````` +M`````````````P`%`````````````````````````````P`&```````````` +M`````````````````P`(`````````````````````````````P`*```````` +M```````````````+````$@`!````````````20`````````<````$@`!`%`` +M````````!``````````N````$@`!`&``````````"``````````_````$@`! +M`'``````````!`````````!4````$@`!`(``````````U`````````!L```` +M$@`!`&`!````````!0````````!]````$@`!`'`!`````````P````````"3 +M````$@`!`(`!````````!0````````"J````$@`!`)`!````````!0`````` +M``#!````$@`!`*`!````````!0````````#6````$@`!`+`!````````!0`` +M``````#G````$@`!`,`!````````!0````````#^````$@`!`-`!```````` +M!0`````````3`0``$@`!`.`!````````!0`````````I`0``$@`!`/`!```` +M````!0`````````^`0``$@`!```"````````!0````````!0`0``$@`!`!`" +M````````!0````````!B`0``$@`!`"`"````````!0````````!S`0``$@`! +M`#`"````````"`````````"(`0``$@`!`$`"````````#`````````"C`0`` +M$@`!`%`"````````#`````````"^`0``$@`!`&`"````````#`````````#8 +M`0``$@`!`'`"````````#`````````#R`0``$@`!`(`"````````"``````` +M```'`@``$@`!`)`"````````"``````````;`@``$@`!`*`"````````$P`` +M```````Y`@``$@`!`,`"````````$P````````!5`@``$@`!`.`"```````` +M$P````````!R`@``$@`!```#````````$P````````".`@``$@`!`"`#```` +M````$P````````"J`@``$@`!`$`#````````(`````````#,`@``$@`!`&`# +M````````(`````````#N`@``$@`!`(`#````````(``````````/`P``$@`! +M`*`#````````(``````````P`P``$@`!`,`#````````#`````````!(`P`` +M$@`!`-`#````````+@````````!:`P``$`````````````````````````!A +M`P``$@`!```$````````G0````````!V`P``$``````````````````````` +M``!]`P``$`````````````````````````"%`P``$@`!`*`$````````60`` +M``````"6`P``$`````````````````````````"=`P``$@`!```%```````` +M0P````````"P`P``$`````````````````````````"U`P``$@`!`%`%```` +M````$@``````````;65M71EU(QT98`````$B+A\@```!(B49@2(N'R````$B) +M,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D +M\$B)7"3@28G\2(EL).A,B6PD^$B#[&A(BV]82(GF2(M]$.@`````2(7`#X0* +M`0``2,=$)!``````2,=$)#`!````2(M%(,=$)`0#````2,=$)`@`````2,=$ +M)#@`````QT0D+`````#'1"0H`````$B)1"082(M]$.@`````2(7`2(G##X3. +M````0?9$)&00#X2&````2(M%*$B)YDB)1"0@2(M]$.@`````A<`/A,,```!( +MQP,!````2(M%&$B)0PA(BT4H2,=#$`````#'0R`!````QT,D`0```$B)0QA( +MBWT0Z`````!)BWPD($B)QN@`````A<`/A)8```!(BUPD2$B+;"103(MD)%A, +MBVPD8$B#Q&C#9F:09I!(BU4H2(M]&$B#ZA!(C7<02(E5*.@`````Z5S___^_ +M_____^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!( +MB<*_1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_ +M_____^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:005152(G] +M4TB#[$!(BY_`````2(7;=')(BWL02(GFZ`````!(AY(BW@0Z`````")1"0HD$B+>Q!(B>;H`````(7`=$-(BUM82(7;=8[H```` +M`(7`=4](@\1`6UU!7,/'1"0H`````.O+O______H`````+X`````2(G"OT8` +M```QP.@`````O______H`````+X`````2(G"OT8````QP.@`````BQ@`=!E(B>Y(B=](BVPD$$B+7"0(2(/$&.D`````2(G?O@````#H```` +M`$B)W[X`````Z`````!(B=^^`````.@`````O@````!(B=_H`````.NQ9F:0 +M9I!!5D%528G]05154TB#[$!(BZ_`````2(7M=")!N`````#K"4B+;5A(A>UT +M$4B+=0"Y"@```$R)Q_SSIG7F28N=D````$B%VP^$!@$``&9FD$F+?2#H```` +M`$B%P$F)Q`^$^P```+YX````OP$```#H`````$B%P$B)P@^$_@```$B+`TR) +MYTB)`DB+12!(B4(@2(M#$,="2/_____'0DP`````2,=""`````!,B6(02(E" +M*$B+16!(B6I82(E"8$B+16!(B1!(C4)82(E%8.@`````2(7`2(G"#X2P```` +M2,<``0```$C'0!``````2(GF2(M#"$R)YTB)0@A(BT,0QT(@`0```,=")`$` +M``!(B4(8Z`````!(A<`/A(T```#'1"0$`0```$B+,TR)[^A=_O__2(GF3(GG +MZ`````"%P`^$A0```$B+6QA(A=L/A?W^__](@\1`6UU!7$%=05[#O______H +M`````+X`````2(G"OT8````QP.@`````O@````"_1@```#'`Z`````"_____ +M_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +M1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````!F9F:0 +M9F:054B)_5-(@^P(BU=4A=)T!TB#?Q@`=&PQV^M+9F:09I!(BWT0Z`````!( +MA9(B=_H`````$B%P`^$KP```$B+1"1`2(GN3(GG2(D$)$B+1"1(2(E$ +M)`A(BT0D4$B)1"002(M$)%A(B40D&$B+1"1@2(E$)"!(BT0D:$B)1"0H2(M$ +M)'!(B40D,$B+1"1X2(E$)#CH^/O__TB)YDB)W^@`````A3ID````$B+:R!,.>4/@J@```"+>TR% +M_W4?2(MS.#'23(GE2HU,)O](BQ!(B>;H`````$B%P'1O2(M#($B)YDB) +M1"082(M#*$B)1"0@2(M[$.@`````A;H +M`````$B%P`^$E````+YX````OP$```#H`````$B%P$B)PP^$M0```$B+1"0H +MN@$```!(B4,@2(N-P````$B%R708,<"#>5`!2(M)6(/0`$B%R77P@\`!2&/0 +M2(M](+D!````O@X```#H`````$B%P$B)0RAT24B)WDB)[TC'0S@$````QT-, +M`````,=#4`$```#H6/;__TB)V$B#Q$A;7<.______^@`````O@````!(B<*_ +M1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +M`+]&````,<#H`````)!!54&)U4%428G\54B)]5-(@^P(2(N?@````$B%VW4+ +MZR9(BUM`2(7;=!U(BS-(B>_H`````(7`=>A(@\0(2(G86UU!7$%=PS';187M +M=.N_2````.@`````2(7`=#9(B<.Z2````#'V2(G'Z`````!(B2M(QT-````` +M`$F+A"2(````2(D82(U#0$F)A"2(````ZZ:^`````+]&````Z`````!F9F:0 +M9F9FD&9FD&9FD#'22(/L".@`````,=)(A[SIG3CNP````!)B>1(QP0D`````$C'1"0(`````$C'1"00 +M`````$C'1"08`````$C'1"0@`````.L29F9FD$F+7"0(28/$"$B%VW0P2(G? +MZ`````!(B=Y(B<)(B>_H`````(7`==A!BT5@@^@!@_@!=PJX`0```.E!____ +M28-]0``/A#3___\QTDB)[DR)[^@`````08M=0(7;=`Y(A_HZ/W__X7`=:2+1"1$@_@)#X2M```` +M@_@$#X2D````0;T`````N0H```!,B>;\3(GO\Z8/A20!``!(BUU82(M$)%A( +MB4,@2(M](.@`````2(7`2(E#$`^$#@(``$R)]^@`````A<")0T@/A-T!``#\ +MN0H```!,B>9,B>_SI@^%,@$``/R_`````+D(````3(GF\Z9U"(--9!!(B5U( +M_+\`````N0@```!,B>;SIG4$2(E=4$B)WDB)[^@/\O__Z>K^__]$BVPD;$6% +M[0^$3O___TB+?1A(C;0D@````.@`````A<`/A*T!```QVT6)[4B+?1A(B=[H +M`````$B%P$B)PP^$Q@```$B)W^@`````23G%==M(B>9(B=_H`````$B%P`^$ +MC0$``(L4)$B+M"2`````2(M]&.@`````2(7`2(G(````2(GOZ)W\__^% +MP`^%5?[__^G"_O__OG@```"_`0```.@`````2(7`#X03`0``2(G#3(D@3(EP +M"$B+1"182(G>2(GO2(E#($B+1"1@2(E#*$B+1"1P2(E#.(M$)$1(B4-`Z``` +M``")0TSID?[__TB+4Q!(BW,(2(GO2(L+Z`````#IMO[__^@`````A<`/A-/] +M__^)Q^@`````O@````!(B<*_1@```#'`Z`````#H`````(7`==Q(@<28```` +M6UU!7$%=05Y!7\.______^@`````O@````!(B<*_1@```#'`Z`````"_____ +M_^@`````O@````!(B<*_1@```#'`Z`````"______^@`````O@````!(B<*_ +M1@```#'`Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"^```` +M`+]&````Z`````"______^@`````O@````!(B<*_1@```#'`Z`````"_____ +M_^@`````O@````!(B<*_1@```#'`Z`````!F9F:09F:09F:054B-+#=32(/L +M"$@Y[W-[2(G[ZSB+!0````"%P'5S2(LU`````(M&#(/H`87`B48,#XB6```` +M2(L&Q@`*2(/``4B)!DB#PP%(.>MT/@^V$X32=,&+!0````"%P'5'2(LU```` +M``^^^HM&#(/H`87`B48,>$%(BP9(@\,!0(@X2(/``4@YZTB)!G7"2(/$"%M= +MPTB+-0````"_"@```.@`````ZY](BS4`````#[[ZZ`````#KCCM&*'P(@/H* +M9F:0=;+H`````.EW____OPH```#H`````.EH____9F:09I!!5T%6055!5%53 +M2('LF````$B)?"083(NOP````$V%[71;2(V$)(````!(B40D".L)38MM6$V% +M[71#08M%4(7`=>])BUT`OP````"Y"````/Q(B=[SIG4W2(M4)!CV0F1`=UUO4B!Q)@```!;74%<05U!7D%?P[\` +M````N0@```!(B=[SIG2X_+\`````N0H```!(B=[SI@^$>____TB+5"08@WI@ +M`0^$CP```$B+?"082(G>Z![Y__^%P`^$,0,``#';13'_2,=$)#@`````ZS]F +M9I!F9I!(BWPD.$@#>QCH`````$F)QTV%_P^$V0,``$B+5"0X2(MS"$F-/!=( +MBU,8Z`````!(BT,82`%$)#A)BWT(2(G>Z`````!(AQCH`````$F)Q^NM28-]0`D/A6;___])BWT(2(UT)$#H`````$B%P`^$ +MU`0``$B+1"08]D!D$`^%C@,``$B+@,````!(AU(QT0D*`````"`.`!T%4B#Q0%*C40]`$@Y +M1"0@2(EL)"AWYD@Y1"0@#X2@`0``3(MT)#!,`W0D.$R+9"0P33GF=R'I+@$` +M`&:028U<)`%,B>?H`````$R-)`--.>8/AA(!``!,B?Y,B>?H`````(7`===( +MBT0D*$Z-?#@!3#E\)"`/AW3___])BW4`2(M\)!CH]/;__X7`#X50`0``2(M$ +M)#A!QT54`0```$F)12A,B>_H`````$F+=0!(BWPD&#'2Z`````!(A<`/A/O\ +M__^+0#"%P`^$\/S__TF+?1A(A?]T#4F+=2A(A?8/APCHN/O__TF+?0A(B=[H`````$B%P$B)PW7?Z`````"%P`^%EP(``(L%```` +M`(7`#X5=`0``2(LU`````(M&#(/H`87`B48,#X@U`@``2(L&Q@`*2(/``4B) +M!NEP_/__28MU`$B+?"08Z"'V__^%P`^$/O___^D:_O__2(GJ3(G^3(GWZ``` +M``!(BU0D.$B-1!4`2(M4)##&!!``2(/``4B)1"0XZ<[^__](BWPD&$B)WNBH +M]?__A<`/A/7^___IM?S__^CV^O__9F:09F:0Z53___](BWPD,$@#?"0X2(GJ +M3(G^Z`````!(`6PD..F:_O__28MU`$B+?"08,=+H`````$R+8!A,B>?H```` +M`$B+?"0P2`-\)#A(B<),B>9(B4Q[44QY$4Q]DF+?0A,B?;H`````$B%P$F)Q@^$7P$``$B-E"2`````,?9, +MB??H`````$@[1"0(#X4D`0``2(M4)!B+G"2,````2(M"4$B+>`CH`````$B) +MQDB+1"082(G:2(MX&.@`````2(7`2(G-````2(M\)!CH`````(7`=(1( +MBU0D&(-Z%`%T/[]`````Z`````!(A$F)Q$B+A"2`````28D$)$B+A"2( +M````28E$)`CI2?___[\*````Z`````#I/OK__[\@````Z`````!(A6P````,`````!6-_````!PBZ +M````!PCN````"+H````#``````7HGP````,``````B^O````"0`````0`D8R +M`0``"@`````"1S(!```"(P`*``````)(5`````(C"``'"#0````)`````)@" +M9EP"```+7W```F50````"(W`*``````)\W@(```(C +M=`H``````GWN`@```B-W"U]L8@`"@`D!```"(W@*``````*#5`````,CB`$* +M``````*$_@````,CD`$`#`%4````;`(```VM``````<(7`(```P!5````(P" +M```-K0````WB````#50`````!PAR`@``#`'^````K`(```VM````#?X````- +M5``````'")("```,`50```#,`@``#:T````-Z`````U4``````<(L@(```X` +M`````0<(T@(```\T````[@(``!"J`````@`/-````/X"```0J@```````P`` +M```"A3@!```""`4``````P`````&)LP````#``````8JS`````\T````-@,` +M`!"J````#P`1"`9Z6P,```H`````!GL0`P```B,`"@`````&?!L#```"(P0` +M`P`````&?38#```#``````%D@,```(C"``#``````>&%04``!)%;&8` +M""90!0``#@`````!`P`````()V$%```.``````$3!`@V``8``!0``````!0` +M`````10``````A0``````Q0`````!!0`````!10`````!A0`````!Q0````` +M"!0`````"10`````"A0`````"Q0`````#!0`````#10`````#A0`````#Q0` +M````$!0`````$10`````$A0`````$Q0`````%!0`````%10`````%A0````` +M%P`#``````A/9P4``!$("'@B!@``"@`````(>*T&```"(P``"0````!`"&BM +M!@``"@`````(;-<````"(P`*``````AMK0````(C"`H`````"&[7`````B,0 +M"@`````(;]<````"(Q@*``````AP``8```(C(`H`````"'%F`````B,D"@`` +M```(=K,&```"(R@*``````AW9@````(C,`H`````"'@+!@```B,X``<((@8` +M``<(5@4```,`````"'DB!@```P`````)+FH$```#``````DP"@4```,````` +M"3(Z!0``$0@*)/P&```*``````HD)0<```(C```)`````!`*(24'```*```` +M``HBZ`````(C``H`````"B3E!@```B,(``<(_`8``!$("C9"!P``"@`````* +M-O<'```"(P``"0````!("BCW!P``"@`````**>@````"(P`*``````HJZ``` +M``(C"`H`````"BOH`````B,0"@`````*+.@````"(Q@+861D``HN5`````(C +M(`H`````"B]4`````B,D"@`````*,%0````"(R@*``````HQ5`````(C+`H` +M````"C)4`````B,P"@`````*,U0````"(S0*``````HT5`````(C.`H````` +M"C8K!P```B-```<(0@<``!$("C\4"```"@`````*/UD(```"(P``"0`````@ +M"CI9"```"@`````*.^(````"(P`*``````H\X@````(C"`H`````"CWS```` +M`B,0"@`````*/_T'```"(Q@`!P@4"```$1`*4H0(```*``````I28`D```(C +M``H`````"E)F"0```B,(``D`````>`I#8`D```H`````"D3H`````B,`"VES +M``I%LP8```(C"`MO@`*6=<````"(P@+;7-Z``I:UP````(C$`H` +M````"EO7`````B,8"@`````*750````"(R`*``````I?D0D```(C*`H````` +M"F"Z"0```B,X``<(T0D``!,$"H1M"@``%```````%``````!%``````"%``` +M```#%``````$`!$0"IB2"@``"@`````*F$`*```"(P`*``````J8D@H```(C +M"``'"$`*```1$`J9O0H```H`````"IGW!P```B,`"@`````*F;T*```"(P@` +M!PCW!P``$1`*FN@*```*``````J:60@```(C``H`````"IKH"@```B,(``<( +M60@``!$0"IP3"P``"@`````*G"4'```"(P`*``````J<$PL```(C"``'""4' +M```1$`J>/@L```H`````"IXE!P```B,`"@`````*GA,+```"(P@`$1`*H&,+ +M```*``````J@8`D```(C``H`````"J!F"0```B,(`!$("J)Z"P``"@`````* +MHF`)```"(P``"0````#8"F85#0``"@`````*9^@````"(P`*``````IJ5``` +M``(C"`H`````"FM4`````B,,"VEE8P`*;50````"(Q`+;V5C``IN5`````(C +M%`ME:6X`"F\5#0```B,8"@`````*50````"(S`*``````IZ5`````(C-`H````` +M"GM4`````B,X"@`````*?%0````"(SP*``````I]5`````(C0`H`````"GY4 +M`````B-$"@`````*@&`)```"(T@*``````J!8`D```(C4`H`````"H)@"0`` +M`B-8"@`````*BD8*```"(V`*``````J35`````(C9`H`````"I8R`0```B-H +M"@`````*F&T*```"(W`*``````J9F`H```,C@`$*``````J:PPH```,CD`$* +M``````J<[@H```,CH`$*``````J>&0L```,CL`$*``````J@/@L```,CP`$* +M``````JB8PL```,CT`$`!PA%!0``%0`````!XP$````````````````````` +M`G<(8`T``!9E8W```>)@#0```5461@"0```5$` +M!PAZ"P``&`$``````5X#`0``````````````````````````Q@T``!EE8W`` +M`5T#8`T````````:P"8`D````````@$@````_H````'A(``!"J````!``' +M".@````F``````$X`50``````````````````````````````+T2```C96-P +M``$W8`T````````D``````$WZ``````````K`````'\2```E``````%P`@$``````````````````````````*<4 +M```99``!;P+H`````````!ES>@`!;P+S`````````!IC``%Q`N@````````` +M.NT3`````````74"AQ0``#L*%````````"W_$P```#7M$P````````%W`CL* +M%````````#O_$P``````````/``````!I0$!`4L5```Y96-P``&D`6`-```Y +M@`````/``````!*`(!`2`6```Y96-P``$G`F`-```Y&```+9D5```MC14``#8`````-Z,5````````-Z\5````````,+L5```P +MQQ4``#?1%0```````##=%0``-^<5````````-_$5````````,/L5```O!Q8` +M``.1T'XP$Q8``#4@%@````````$N`BT\%@``+3(6```V`````#=(%@`````` +M`#!3%@``,%T6```W:!8`````````````/GL6```````````````````````` +M`9H!H!@``"V7%@``+8P6```N`````````````````````#>B%@`````````` +M-:X6`````````9L!+;P6```V`````#?&%@```````#?1%@```````#7M$P`` +M``````&,`CL*%````````"W_$P```````#\``````HH6%````0%```````*@ +M`50````!`0!^!````@"X`````0'[#@H``0$!`0````$O=7-R+VEN8VQU9&4` +M+W5S7!E7!E6%)*U45)-ZX(+#A(,&"`4@@24CP#%D)NMQ@A8`Z4!`B0!`PDK`W=5`PF; +M`W=5`PE_""!RA7J`@'*!"!4#>E5,"'((/`CTZ`A;`PP(C4B0"%D(,`@\"!Y( +M20@>20-8[P/'?M,##@A_`W@K.`ARQ@@\".4#L0$(1PB=.DA97TB.CH`#$<4# +MO'X(<58#T`%_")E62@.E?@@=`YX!",4#*0C%",$#<0C%`\%^X0C,`X($`B@! +M($18G00"`Y-^_?X$`0/J`<6.=`0"`Y%^"#G&!`$#Z@$Y!`(#EGY'!`$#Z@%Q +M!`(#EGXY!`$#Z@$Y,6T(+00"`Y%^_<@$`0-K",7]6`/D`+<#G'_ACX,(5ZJ` +M`W:-`R2-`V(('0,*_0A<`[1^X0/:`P(K`?Z0"%8#=XT(F4H*2!F +M86EL960Z("5S`&YO="!E;F]U9V@@;65M;W)Y`"YD96)U9P`N9VYU+FQI;FMO +M;F-E+G=I+@`N;&EN90`N&!HP%C02.`X\"````````%``` +M```````!>E(``7@0`0,,!PB0`0``%````!P`````````<``````````````` +M'````#0`````````M@$```!*@P6,`U$.<(T"A@0````D````5`````````#\ +M`````$(.$$$.&(8#C`)$#B!$#F"#!```````%````'P`````````:P````!. +M#B"#`X8"+````)0`````````Z0$```!"#A!"#AB-`XX"10X@00XH00XP1`YP +M@P:&!8P$````'````,0`````````]`````!!#A"&`D0.&$0.((,#```<```` +MY``````````Y`0```$J&!(,%5`ZP`8T"C`,``"0````$`0```````"\!```` +M0@X00@X800X@00XH1`YP@P6&!(P#C0(<````+`$```````#_`````$$.$(8" +M1`X81`Y@@P,``"0```!,`0```````*(`````0@X0C0)%#AB,`T0.((8$1`XH +M1`XP@P44````=`$````````B`````$8.$``````4````C`$````````W```` +M`$0.$``````<````I`$```````!``0```%J,`X,%C0*&!$<.8````#0```#$ +M`0```````*8#````0@X01PX80@X@0@XH00XPA@:,!8T$C@./`DD..$<.T`&# +M!P``````'````/P!````````VP````!!#A"&`D4.&$0.((,#```T````'`(` +M``````#N!@```$(.$$(.&$(.($(.*$$.,$$..$<.T`&#!X8&C`6-!(X#CP(` +M`````'``````````BP`````````"`'<(BP`````````F`@````````,`=_`` +M`````````````````````'``````````E@`````````!`%66`````````($! +M`````````0!00` +M``````"W!`````````$`42\%````````.04````````!`%$````````````` +M````````[0,```````#[!`````````$`7``%````````B04````````!`%P` +M````````````````````D`4```````"1!0````````(`=PB1!0```````)4% +M`````````@!W$)4%````````F04````````"`'<8F04```````"$!@`````` +M``(`=R``````````````````````D`4```````"K!0````````$`5:L%```` +M````&08````````!`%89!@```````!H&`````````0!5&@8```````!*!@`` +M``````$`5DL&````````A`8````````!`%8`````````````````````J04` +M```````8!@````````$`4QH&````````208````````!`%-+!@```````(0& +M`````````0!3`````````````````````+P%````````OP4````````!`%"_ +M!0````````(&`````````0!1&@8```````!5!@````````$`40`````````` +M```````````1!@```````!H&`````````0!0:08```````!P!@````````$` +M4`````````````````````"0!@```````*X&`````````@!W"*X&```````` +MR0<````````#`'>P`0````````````````````"0!@```````+0&```````` +M`0!5M`8```````!?!P````````$`7&\'````````R0<````````!`%P````` +M````````````````D`8```````"Y!@````````$`5+D&````````P08````` +M```!`%4`````````````````````D`8```````#!!@````````$`4<$&```` +M````3P<````````!`%-O!P```````,D'`````````0!3```````````````` +M`````)`&````````P08````````!`%+!!@```````%<'`````````0!6;P<` +M``````#)!P````````$`5@````````````````````#0!P```````-('```` +M`````@!W"-('````````U`<````````"`'<0U`<```````#5!P````````(` +M=QC5!P```````-8'`````````@!W(-8'````````V@<````````"`'0T```````"P#0````````$`7,0-````````Q@T````````! +M`%S>#0```````.`-`````````0!<]@T```````"0#@````````$`7*X.```` +M````Z`X````````!`%P`#P```````#P/`````````0!<0P\```````"[#P`` +M``````$`7,H/````````!A`````````!`%P`````````````````````WPP` +M``````!`#P````````$`7D,/````````!A`````````!`%X````````````` +M````````#0\````````4#P````````$`4"\/````````0P\````````!`%`` +M````````````````````<@X```````!U#@````````$`4'4.````````@PX` +M```````!`%1##P```````$T/`````````0!4`````````````````````-\, +M````````<`T````````!`%/V#0```````*L.`````````0!3``\````````Y +M#P````````$`4T,/````````?P\````````!`%.[#P````````80```````` +M`0!3`````````````````````-\,````````[`P````````!`%`'#P`````` +M`!0/`````````0!0`````````````````````!`0````````$1`````````" +M`'<($1`````````6$`````````(`=Q`6$````````!H0`````````@!W&!H0 +M````````ZQ`````````"`'<@`````````````````````!`0````````=Q`` +M```````!`%6:$````````*T0`````````0!5M!````````"^$`````````$` +M5=P0````````X1`````````!`%4`````````````````````$!`````````U +M$`````````$`5%P0````````=!`````````!`%2:$````````*@0```````` +M`0!4M!````````"[$`````````$`5``````````````````````B$``````` +M`)\0`````````0!3H1````````#K$`````````$`4P`````````````````` +M```D$````````'00`````````0!4FA````````"H$`````````$`5+00```` +M````NQ`````````!`%3<$````````.80`````````0!4```````````````` +M`````"00````````-1`````````!`%1<$````````*@0`````````0!4M!`` +M``````"[$`````````$`5,40````````UQ`````````!`%0````````````` +M````````)!````````"M$`````````$`5;00````````OA`````````!`%7% +M$````````-<0`````````0!5W!````````#A$`````````$`50`````````` +M``````````#P$````````/(0`````````@!W"/(0````````]!`````````" +M`'<0]!````````#V$`````````(`=QCV$````````/@0`````````@!W(/@0 +M````````^1`````````"`'%P`````` +M``$`70````````````````````"U$0```````,(1`````````0!0?!(````` +M``"[$@````````$`4/H5`````````Q8````````!`%`````````````````` +M````@A8```````"%%@````````$`4(46````````E18````````!`%18%P`` +M`````&(7`````````0!4`````````````````````"$1````````=A$````` +M```!`%9_$0```````%<3`````````0!6WA,```````#,%`````````$`5OL4 +M````````)14````````!`%9$%0```````-X7`````````0!6```````````` +M`````````"$1````````>!$````````!`%Q_$0```````)03`````````0!< +MWA,```````#,%`````````$`7/L4````````6!4````````!`%R4%0`````` +M`-X7`````````0!<`````````````````````"$1````````?!$````````! +M`%Y_$0```````(H3`````````0!>WA,```````#,%`````````$`7OL4```` +M````WA<````````!`%X`````````````````````$A<````````7%P`````` +M``$`59L7````````G1<````````!`%"=%P```````,07`````````0!5```` +M`````````````````+T1````````PA$````````!`%0#%0````````@5```` +M`````0!4`````````````````````%@5````````8!4````````!`%"_%0`` +M`````,05`````````0!0`````````````````````"$1`````````1,````` +M```#`)'H?@$3````````!A,````````!`%4&$P```````*L5`````````P"1 +MZ'ZK%0```````+05`````````0!5M!4```````#.%0````````,`D>A^SA4` +M``````#3%0````````$`5=,5````````WA<````````#`)'H?@`````````` +M```````````A$0```````'81`````````0!6?Q$```````!M%0````````$` +M5FT5````````>!4````````!`%&4%0```````!<6`````````0!6U!8````` +M``#C%@````````$`5A`7````````6!<````````!`%8````````````````` +M````(1$```````!^$0````````$`7W\1````````8!,````````!`%]@$P`` +M`````)X3`````````0!0GA,````````E%0````````$`7R45````````.A4` +M```````!`%`Z%0```````-X7`````````0!?`````````````````````"$1 +M````````>!$````````!`%Q_$0```````)<3`````````0!%0```````*85```````` +M`0!5JQ4````````:%@````````$`7-06````````XQ8````````!`%P0%P`` +M`````%@7`````````0!<`````````````````````"$1````````-A$````` +M```!`%-M$0```````'41`````````0!3S!$```````!$$@````````$`4[L2 +M````````I1,````````!`%.Z$P```````$D4`````````0!3>10```````#[ +M%`````````$`4Q45````````6YC7W-E8W1I;VYS`&(0``!I;G-EPX```````!O +M#@```````'(.````````4@X```````!;#@```````$(.````````1PX````` +M```T#@```````#H.````````+@X````````Q#@`````````````````````` +M```````U$````````%,0````````W!````````#K$``````````````````` +M``````````!W$````````(<0````````Q1````````#<$````````)40```` +M````F!````````"+$````````)(0`````````````````````````````!(1 +M````````(1$````````Z%P```````-X7````````XQ8````````0%P`````` +M``,6````````U!8```````!/$@```````,`2```````````````````````` +M`````%T2````````P!(```````#-%P```````-X7````````O!<```````#` +M%P```````+(7````````NA<```````"=%P```````*@7````````F1<````` +M``";%P```````(`7````````E!<```````!B%P```````'87````````1!<` +M``````!8%P```````.T6````````$!<```````"N%@```````-06```````` +ME18```````"D%@```````(46````````BQ8```````!_%@```````((6```` +M````5Q8```````!>%@```````$<6````````4A8````````O%@```````#46 +M````````*18````````L%@````````,6````````'18````````````````` +M````````````M1$```````#@$0```````/L4````````%14````````````` +M````````````````X!$```````!$$@```````"L7````````.A<````````E +M%0```````.05````````L10```````#[%````````,`2````````!10````` +M````````````````````````X!$```````!$$@```````"L7````````.A<` +M``````#3%0```````.05````````$P```````+$3 +M````````NA,````````K$P```````*43````````'1,````````A$P`````` +M``X3````````&1,````````&$P````````D3````````]!(````````!$P`` +M`````,`2````````YA(`````````````````````````````X!$```````!$ +M$@```````-,5````````Y!4```````#`$@```````,T2```````````````` +M`````````````/$1````````&1(```````#3%0```````.05````````Q1(` +M``````#-$@```````"L2````````-A(````````E$@```````"@2```````` +M`````````````````````#$4````````L10````````0%P```````"L7```` +M````U!8```````#C%@```````.05`````````Q8````````5%0```````"45 +M`````````````````````````````#$4````````6!0````````7%P`````` +M`"L7````````U!8```````#C%@```````!45````````)14```````!Q%``` +M`````+$4````````:A0```````!L%````````&04````````9Q0````````` +M````````````````````CA0```````"Q%````````-06````````XQ8````` +M````````````````````````16QF-C1?061D<@!D8F=?F4`7V9L86=S`&5?=F5RF4`1T5L +M9E]%:&1R`&1?6U?;&ES=`!S96-?861D`&-O<'E?9&%T80!C;W!Y`&5?96YT@!S='%H7V9I6UT86(`:7-?F5?=`!D7W1Y<&4`14Q&7U1? +M4UE-`$5L9E]4>7!E`'-E9U]L:7-T`&9L86=S`%]?=6EN=#8T7W0`16QF-C1? +M2&%L9@!S96-T:6]NF4`:6YF;70`14Q&7U1?0EE410!D7V)U9@!S:7IE`$5,1E]47U=/4D0` +M;6]D:69Y7W-E8W1I;VX`14Q&7U1?4TA$4@!C;W!Y7W-H9'(`<'-E=61O`'-H +M7V]F9G-E=`!A9&1O<'0`:6YS97)T7W-H=&%B`$5,1E]47T%$1%(`7V5X=')A +M`'-E=%]S:'-T5]C;VYT96YT`'9?;61A=`!%;&9? +M1&%T80!C;VYT96YT`&1?9FQA9W,`95]T>7!E`'9?6UT86(`+G-T`!M96UM;W9E`&5L9E]E`!U<&1A=&5?5]D871A`&5L9E]G971D871A`&-O<'E?5]C;VYT96YT`&-R +M96%T95]S>6UT86(`;65M8W!Y`'-TP,````````"````)````/S_________@P,````````*````"0```*X````` +M````B`,````````"````)````/S_________C0,````````*````"0```+8` +M````````E0,````````"````)````/S_________O0,````````*````"0`` +M`+8`````````]0,````````"````)@```/S_________$`0````````"```` +M)P```/S_________;P0````````"````&@```/S_________LP0````````" +M````&0```/S_________V@0````````"````&P```/S_________!@4````` +M```"````'P```/S_________"P4````````*````"0```,``````````&@4` +M```````"````(````/S_________'P4````````*````"0```-@````````` +M*P4````````"````*````/S_________-04````````"````'P```/S_____ +M____.@4````````*````"0```!X`````````204````````"````(````/S_ +M________4P4````````"````'P```/S_________6`4````````*````"0`` +M`.4`````````9P4````````"````(````/S_________<04````````"```` +M'P```/S_________=@4````````*````"0```#<`````````A04````````" +M````(````/S_________M04````````"````&@```/S__________@4````` +M```"````*@```/S_________"P8````````"````(P```/S_________408` +M```````"````'P```/S_________5@8````````*````"0```!X````````` +M908````````"````(````/S_________;`8````````"````'P```/S_____ +M____<08````````*````"0````,!````````@`8````````"````(````/S_ +M________O08````````"````&0```/S_________T08````````"````&0`` +M`/S_________/P<````````"````&P```/S_________=0<````````"```` +M'P```/S_________>@<````````*````"0```!P!````````B0<````````" +M````(````/S_________DP<````````"````'P```/S_________F`<````` +M```*````"0```#H!````````IP<````````"````(````/S_________L0<` +M```````"````'P```/S_________M@<````````*````"0```%@!```````` +MQ0<````````"````(````/S_________2P@````````"````&0```/S_____ +M____;@@````````"````&P```/S_________LP@````````*````"P`````` +M````````N@@````````"````+0```/S_________R0@````````"````'P`` +M`/S_________S@@````````*````"0```',!````````W0@````````"```` +M(````/S_________YP@````````"````'P```/S_________[`@````````* +M````"0```%@!````````^P@````````"````(````/S_________$0D````` +M```"````+P```/S_________*0D````````"````)P```/S_________>@D` +M```````"````,````/S_________N`D````````"````'P```/S_________ +MO0D````````*````"0```)$!````````S`D````````"````(````/S_____ +M____U@D````````"````'P```/S_________VPD````````*````"0```+D! +M````````Z@D````````"````(````/S_________[PD````````*````"0`` +M`*L!````````^PD````````"````(````/S_________,0H````````"```` +M,@```/S_________5`H````````"````,P```/S_________:PH````````" +M````-````/S_________E`H````````*````"0```-$!````````G@H````` +M```"````(````/S_________MPH````````"````,0```/S_________YPH` +M```````"````,0```/S_________0@L````````*````"0```+8````````` +M:0L````````*````"0```*8`````````A@L````````*````"0```*X````` +M````EPL````````*````"0```.,!````````H@L````````+````"0```.,! +M````````JPL````````+````"0```.H!````````M`L````````+````"0`` +M`/P!````````O0L````````+````"0````("````````X@L````````"```` +M-0```/S_________\`L````````"````-@```/S_________(@P````````" +M````,0```/S_________?PP````````"````)P```/S_________DPP````` +M```+````"0```+8`````````RPP````````"````.````/S_________Z`P` +M```````"````.0```/S__________PP````````"````&0```/S_________ +M'0T````````"````.@```/S_________5`T````````*````"0```+8````` +M````?@T````````"````)@```/S_________DPT````````"````'````/S_ +M________N`T````````*````"0```*8`````````T@T````````*````"0`` +M`*X`````````$0X````````"````.````/S_________*@X````````"```` +M.0```/S_________/@X````````"````'````/S_________3@X````````" +M````&0```/S_________:PX````````"````.@```/S_________FPX````` +M```"````)P```/S_________W`X````````"````.P```/S_________]PX` +M```````"````*P```/S_________`0\````````"````(P```/S_________ +M$`\````````"````'P```/S_________%0\````````*````"0```(X````` +M````)`\````````"````(````/S_________*0\````````"````(P```/S_ +M________20\````````"````'P```/S_________3@\````````*````"0`` +M`#\"````````70\````````"````(````/S_________9P\````````"```` +M'P```/S_________;`\````````*````"0```","````````>P\````````" +M````(````/S_________A0\````````"````'P```/S_________B@\````` +M```*````"0```(,"````````F0\````````"````(````/S_________HP\` +M```````"````'P```/S_________J`\````````*````"0```&T"```````` +MMP\````````"````(````/S_________O`\````````*````"0```*L!```` +M````Q@\````````"````*````/S_________T`\````````"````'P```/S_ +M________U0\````````*````"0````@"````````Y`\````````"````(``` +M`/S_________[@\````````"````'P```/S_________\P\````````*```` +M"0```%4"`````````A`````````"````(````/S_________)A`````````" +M````/````/S_________,1`````````"````/0```/S_________91`````` +M```"````/````/S_________Q0````````"````/````/S_________BA0````````"```` +M/0```/S_________UA0````````"````0P```/S_________-A4````````" +M````0P```/S_________4!4````````"````,0```/S_________7!4````` +M```"````-0```/S_________=!4````````"````0P```/S_________HA4` +M```````"````0@```/S_________MQ4````````"````,0```/S_________ +MP!4````````"````-0```/S_________U!4````````*````"0```+X"```` +M````X!4````````"````*````/S_________YQ4````````"````/0```/S_ +M________\14````````"````/@```/S_________)18````````"````*@`` +M`/S_________0Q8````````"````1````/S_________9Q8````````"```` +M'````/S_________>Q8````````"````.@```/S_________D18````````" +M````10```/S_________JA8````````"````,P```/S_________VA8````` +M```"````/P```/S_________Z18````````"````,P```/S_________$Q<` +M```````"````'P```/S_________&!<````````*````"0````,!```````` +M)Q<````````"````(````/S_________+!<````````*````"0```+`"```` +M````-A<````````"````*````/S_________0!<````````"````'P```/S_ +M________11<````````*````"0```)$!````````5!<````````"````(``` +M`/S_________7A<````````"````'P```/S_________8Q<````````*```` +M"0```#\"````````P`````````*````%@```/,%````````@``````````*````%@```#0#```` +M````C0`````````*````%@```.4&````````E``````````*````%@```&<( +M````````FP`````````*````%@```.(!````````H``````````*````%@`` +M`'`&````````L``````````*````%@```/$'````````O0`````````*```` +M%@```)@#````````P@`````````*````%@```(L%````````S0`````````* +M````%@```*T!````````V``````````*````%@```#H&````````]``````` +M```*````%@````0#````````_P`````````*````%@```-L!````````"@$` +M```````*````%@```*\'````````%@$````````*````%@```'@$```````` +M)`$````````*````%@```(P`````````.0$````````*````%@```#@"```` +M````;`$````````*````%@```*4`````````>@$````````*````%@```)D$ +M````````E@$````````*````%@```)P`````````I`$````````*````%@`` +M`'T!````````L@$````````*````%@```/H#````````P`$````````*```` +M%@```!0<````````*````%@```+H#````````E0<````````*````%@`` +M`/H!````````HP<````````*````%@````@$````````L0<````````*```` +M%@```*`!````````OP<````````*````%@```.,%````````S0<````````* +M````%@```#T`````````VP<````````*````%@```!<$````````Z0<````` +M```*````%@```,$&````````!@@````````*````%@```!X&````````%0@` +M```````*````%@```(X!````````(0@````````*````%@```+$&```````` +M+P@````````*````%@```(('````````/0@````````*````%@```,H$```` +M````2P@````````*````%@```"T`````````:`@````````*````%@````D! +M````````=@@````````*````%@```+8!````````A0@````````*````%@`` +M`)H&````````D0@````````*````%@```+$&````````\`@````````*```` +M%@```+\(````````_@@````````*````%@```"H'````````&@D````````* +M````%@```%0!````````*`D````````*````%@```/X$````````-@D````` +M```*````%@```)($````````1`D````````*````%@```"H(````````4@D` +M```````*````%@```)\'````````=0D````````*````%@````D!```````` +M@PD````````*````%@```+8!````````D@D````````*````%@````P"```` +M````G@D````````*````%@```-L&````````K`D````````*````%@```,`' +M````````PPD````````*````%@```!X&````````T@D````````*````%@`` +M`-D`````````"`H````````*````%@```"H'````````%@H````````*```` +M%@```#T`````````)`H````````*````%@```)D'````````,@H````````* +M````%@```"4#````````3PH````````*````%@```,@#````````50H````` +M```*````%@```,\`````````6PH````````*````%@```)\$````````80H` +M```````*````%@```*$"````````9PH````````*````%@```*(&```````` +M=@H````````*````%@```"<"````````A`H````````*````%@```.L#```` +M````H0H````````*````%@```"<"````````KPH````````*````%@```.L# +M````````S`H````````*````%@```"<"````````V@H````````*````%@`` +M`.L#````````]PH````````*````%@```"<"````````!0L````````*```` +M%@```.L#````````(@L````````*````%@```"<"````````,`L````````* +M````%@```.L#````````1PL````````*````%@```-L&````````50L````` +M```*````%@```,`'````````;`L````````*````%@```&(%````````>PL` +M```````*````%@```$<"````````APL````````*````%@```%T!```````` +ME0L````````*````%@```+,$````````HPL````````*````%@```$`"```` +M````VPL````````*````%@```)4&````````Z0L````````*````%@```,$# +M````````]PL````````*````%@```%``````````!0P````````*````%@`` +M`&X(````````$PP````````*````%@```!<'````````(0P````````*```` +M%@```$H#````````+PP````````*````%@```+\!````````/0P````````* +M````%@```)X%````````2PP````````*````%@```$L%````````60P````` +M```*````%@```-X"````````9PP````````*````%@```$`(````````=0P` +M```````*````%@```$(%````````@PP````````*````%@```/D'```````` +MD0P````````*````%@```"X#````````GPP````````*````%@```"4$```` +M````K0P````````*````%@```#<`````````NPP````````*````%@```&@$ +M````````R@P````````*````%@```-<"````````V0P````````*````%@`` +M`#\!````````Z`P````````*````%@```'(!````````]PP````````*```` +M%@```)D'````````!@T````````*````%@```'('````````'`T````````* +M````%@```'X(````````(PT````````!`````@``````````````*PT````` +M```!`````@```'``````````:`T````````*````%@```#4%````````<`T` +M```````!`````@```'``````````>`T````````!`````@```"8"```````` +M@`T````````*````$@``````````````E`T````````*````$@```#D````` +M````H@T````````*````$@```((`````````IPT````````*````%@```-,# +M````````L@T````````*````$@```+@`````````S@T````````*````%@`` +M`$0`````````U@T````````!`````@```#`"````````W@T````````!```` +M`@```"P#````````Y@T````````*````$@```!0!````````^@T````````* +M````$@```(D!````````"`X````````*````$@```-(!````````%@X````` +M```*````$@````@"````````*PX````````*````%@````$$````````-@X` +M```````*````$@```%$"````````.PX````````*````%@```&H#```````` +M2`X````````*````%@````X&````````4`X````````!`````@```#`#```` +M````6`X````````!`````@```)L#````````8`X````````*````$@```(<" +M````````=`X````````*````$@```+\"````````>0X````````*````%@`` +M`+$&````````A`X````````*````$@```/4"````````D@X````````*```` +M$@```%$#````````F0X````````*````%@```%H&````````H0X````````! +M`````@```*`#````````J0X````````!`````@```(D%````````L0X````` +M```*````$@```)H#````````Q0X````````*````$@```#<$````````U`X` +M```````*````$@```),$````````V0X````````*````%@```,$````````` +MY`X````````*````$@```,D$````````_0X````````*````$@```/\$```` +M````#`\````````*````$@```$@%````````(P\````````*````%@```)8! +M````````*P\````````!`````@```)`%````````,P\````````!`````@`` +M`(0&````````.P\````````*````$@```'X%````````30\````````*```` +M$@```-X%````````7`\````````*````$@```$T&````````:P\````````* +M````$@```)8&````````<`\````````*````%@````$$````````>P\````` +M```*````$@```-\&````````@@\````````*````%@```/0$````````B@\` +M```````!`````@```)`&````````D@\````````!`````@```,D'```````` +MF@\````````*````$@```!4'````````K@\````````*````$@```$X'```` +M````O0\````````*````$@```)<'````````S`\````````*````$@```,T' +M````````T0\````````*````%@```+$&````````W`\````````*````$@`` +M`!8(`````````Q`````````*````%@```+P"````````"Q`````````!```` +M`@```-`'````````$Q`````````!`````@```/\(````````&Q`````````* +M````$@```%\(````````+Q`````````*````$@```.@(````````/1`````` +M```*````$@```#$)````````71`````````*````$@```&<)````````9!`` +M```````*````%@```!8%````````!`````````!`````@```/\)````````@!`````````*````$@```"(*```` +M````E!`````````*````$@```(,*````````HA`````````*````$@```,P* +M````````IQ`````````*````%@```#("````````LA`````````*````$@`` +M`.\*````````QQ`````````*````%@```"L$````````TA`````````*```` +M$@```!(+````````V1`````````*````%@```.$`````````Y!`````````! +M`````@`````*````````[!`````````!`````@```*(*````````]!`````` +M```*````$@```$@+````````!Q$````````*````$@```-`+````````#!$` +M```````*````%@```+$&````````%A$````````*````$@```"P,```````` +M)1$````````*````$@```(@,````````-!$````````*````$@```.0,```` +M````.A$````````*````%@```'D&````````11$````````!`````@```+`* +M````````31$````````!`````@```-(*````````51$````````*````$@`` +M`!H-````````:!$````````*````$@```%(-````````;1$````````*```` +M%@```+$&````````=Q$````````*````$@```'4-````````AA$````````* +M````$@```)@-````````C!$````````*````%@```.@!````````EQ$````` +M```!`````@```.`*````````GQ$````````!`````@```!<+````````IQ$` +M```````*````$@```+L-````````NA$````````*````$@```/,-```````` +MOQ$````````*````%@```+$&````````R1$````````*````$@```!8.```` +M````V!$````````*````$@```#D.````````WA$````````*````%@```!P` +M````````[Q$````````*````%@```+$&````````^A$````````*````%@`` +M``L`````````)1(````````*````%@```-0'````````,!(````````!```` +M`@```"`+````````.!(````````!`````@```&`,````````0!(````````* +M````$@```&\.````````4Q(````````*````$@```*@.````````6!(````` +M```*````%@```+$&````````8A(````````*````$@```/$.````````9Q(` +M```````*````%0``````````````>A(````````*````$@```&`/```````` +MA!(````````!`````@```)8+````````C!(````````!`````@```/@+```` +M````G!(````````!`````@```)8+````````I!(````````!`````@```-X+ +M````````OA(````````*````%@```.4"````````VA(````````*````%@`` +M`-@#````````Y1(````````*````%@```+$&````````!1,````````*```` +M%@```/4#````````$!,````````*````%@````$$````````'1,````````* +M````%@```&<"````````)!,````````!`````@```&`,````````+!,````` +M```!`````@````80````````-!,````````*````$@```*D/````````1Q,` +M```````*````$@```%H0````````5!,````````*````$@```*,0```````` +M61,````````*````%@```+$&````````8Q,````````*````$@```/\0```` +M````<1,````````*````$@```+H1````````A1,````````*````%@```/4# +M````````E!,````````*````%@````$$````````GA,````````*````$@`` +M`/`1````````IQ,````````*````%0```$``````````N1,````````*```` +M%0```)``````````PA,````````*````$@```"82````````U!,````````* +M````$@```&\2````````YA,````````*````$@```-X2````````[A,````` +M```*````%@```'H"````````'10````````*````%@```-T(````````)10` +M```````!`````@```!`0````````+10````````!`````@```.L0```````` +M-10````````*````$@```!03````````1Q0````````*````$@```'03```` +M````5A0````````*````$@```-`3````````9!0````````*````$@```"P4 +M````````;10````````*````%0```&`!````````?10````````*````$@`` +M`&(4````````C!0````````*````%0```)`!````````F!0````````*```` +M$@```+X4````````H10````````*````$@```!H5````````J!0````````* +M````%@```"H!````````UA0````````*````%@```+$&````````^A0````` +M```*````%@```%P%````````!A4````````*````%@```!$'````````'14` +M```````*````%@````$$````````,Q4````````*````%@```+@%```````` +M6!4````````*````%@```#T'````````=!4````````*````%@```+$&```` +M````@!4````````*````%@```-H$````````L!4````````*````%@```!$$ +M````````O!4````````*````%@```"$"````````%!8````````*````%@`` +M`!(!````````(18````````*````%@```'X%````````/18````````*```` +M%@```,H$````````:18````````*````%@````$$````````?!8````````* +M````%@```)`"````````F!8````````*````%@```+$&````````KQ8````` +M```*````%@```'X`````````TA8````````*````%@````$$````````X!8` +M```````*````%@```&4'````````Z!8````````!`````@```/`0```````` +M\!8````````!`````@```-X7````````^!8````````*````$@```'85```` +M````#!<````````*````$@```"<6````````&A<````````*````$@```(<6 +M````````(Q<````````*````%0```.`!````````.1<````````*````%0`` +M`$`"````````0A<````````*````$@```+T6````````2Q<````````*```` +M$@````87````````9A<````````*````$@```$\7````````;Q<````````* +M````$@```+X7````````>!<````````*````$@```"T8````````@1<````` +M```*````$@```(D8````````FQ<````````*````%0```(`#````````JQ<` +M```````*````$@```-(8````````NA<````````*````%0```+`#```````` +MT!<````````*````%0```!`$````````V1<````````*````$@````@9```` +M````XA<````````*````$@```#X9````````]1<````````*````$@```-L9 +M`````````Q@````````*````$@```%T:````````#!@````````*````$@`` +M`-\:````````*!@````````*````%0```#`%````````.A@````````*```` +M%0```'`%````````0Q@````````*````$@```(<;````````5A@````````* +M````$@```%4<````````8Q@````````!`````@````T4````````:Q@````` +M```!`````@```#$4````````A1@````````!`````@```!T4````````C1@` +M```````!`````@```#$4````````FA@````````*````$@```)X<```````` +MI1@````````*````%0```-`%````````LA@````````*````%0```#`&```` +M````NQ@````````*````$@```.<<````````Q!@````````*````$@```&D= +M````````S1@````````*````%0```+`&````````V1@````````*````$@`` +M`+(=````````YQ@````````*````%@```&X$````````]!@````````*```` +M%@```$\"````````Q0`````````!`````@``````````````'``````````* +M````$```````````````(``````````!`````@``````````````-``````` +M```*````$```````````````.``````````!`````@```'``````````7``` +M```````*````$```````````````8``````````!`````@```#`"```````` +MC``````````*````$```````````````D``````````!`````@```#`#```` +M````K``````````*````$```````````````L``````````!`````@```*`# +M````````Y``````````*````$```````````````Z``````````!`````@`` +M`)`%````````#`$````````*````$```````````````$`$````````!```` +M`@```)`&````````-`$````````*````$```````````````.`$````````! +M`````@```-`'````````9`$````````*````$```````````````:`$````` +M```!`````@`````)````````C`$````````*````$```````````````D`$` +M```````!`````@`````*````````O`$````````*````$``````````````` +MP`$````````!`````@```+`*````````W`$````````*````$``````````` +M````X`$````````!`````@```.`*````````_`$````````*````$``````` +M``````````(````````!`````@```"`+````````)`(````````*````$``` +M````````````*`(````````!`````@```&`,````````9`(````````*```` +M$```````````````:`(````````!`````@```!`0````````C`(````````* +M````$```````````````D`(````````!`````@```/`0````````(``````` +M```*`````@``````````````.``````````*`````@```'``````````6``` +M```````*`````@```#`"````````@``````````*`````@```#`#```````` +MF``````````*`````@```*`#````````R``````````*`````@```)`%```` +M````Z``````````*`````@```)`&````````"`$````````*`````@```-`' +M````````,`$````````*`````@`````)````````4`$````````*`````@`` +M```*````````>`$````````*`````@```+`*````````D`$````````*```` +M`@```.`*````````J`$````````*`````@```"`+````````R`$````````* +M`````@```&`,``````````(````````*`````@```!`0````````(`(````` +M```*`````@```/`0````````!@`````````*````!@``````````````!@`` +M```````*````!@``````````````$``````````!`````@`````````````` +` +end diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/Makefile new file mode 100644 index 0000000000..2c9a9b1ca6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_DATA= test_obj + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/tc.sh b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/tc.sh new file mode 100755 index 0000000000..134bffcc96 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/tc.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# +# $Id: tc.sh 2378 2012-01-03 08:59:56Z jkoshy $ + +tp1() +{ + test_format_bsd1 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp2() +{ + test_format_bsd2 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp3() +{ + test_dynamic1 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp4() +{ + test_dynamic2 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp5() +{ + test_external $TEST_FILE "$TEST_FILE-external.txt" +} + +tp6() +{ + test_hexa1 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp7() +{ + test_hexa2 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp8() +{ + test_hexa3 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp9() +{ + test_no_sort1 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp10() +{ + test_no_sort2 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp11() +{ + test_num_sort1 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp12() +{ + test_num_sort2 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp14() +{ + test_octal2 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp15() +{ + test_octal3 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp16() +{ + test_posix1 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp17() +{ + test_posix2 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp18() +{ + test_print_file_name1 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp19() +{ + test_print_file_name2 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp20() +{ + test_print_size1 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp21() +{ + test_print_size2 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp22() +{ + test_reverse_sort1 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp23() +{ + test_reverse_sort2 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp24() +{ + test_reverse_sort_num $TEST_FILE "$TEST_FILE-sort-reverse-num.txt" +} + +tp25() +{ + test_reverse_sort_no $TEST_FILE "$TEST_FILE-sort-reverse-no.txt" +} + +tp26() +{ + test_reverse_sort_size $TEST_FILE "$TEST_FILE-sort-reverse-size.txt" +} + +tp27() +{ + test_size_sort $TEST_FILE "$TEST_FILE-sort-size.txt" +} + +tp28() +{ + test_sysv $TEST_FILE "$TEST_FILE-format-sysv.txt" +} + +tp29() +{ + test_undef1 $TEST_FILE "$TEST_FILE-undef.txt" +} + +tp30() +{ + test_undef2 $TEST_FILE "$TEST_FILE-undef.txt" +} + +startup() +{ + uudecode "$TEST_FILE.uu" +} + +cleanup() +{ + rm -f $TEST_FILE +} + +TEST_FILE="test_obj" + +tet_startup="startup" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27 ic28 ic29 ic30" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" +ic28="tp28" +ic29="tp29" +ic30="tp30" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-dynamic.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-dynamic.txt new file mode 100644 index 0000000000..fc9a39a389 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-dynamic.txt @@ -0,0 +1,43 @@ +0000000005252136 B _CurrentRuneLocale + w _Jv_RegisterClasses + U __error +0000000005252112 B __isthreaded +0000000005252116 B __mb_sb_limit +0000000005251072 D __progname + U __srget +0000000005252144 B __stderrp +0000000005252120 B __stdinp +0000000005252128 B __stdoutp + U __swbuf +0000000005252224 A _end + U _init_tls + U atexit + U clearerr + U close + U connect +0000000005252176 B environ + U err + U exit + U fclose + U fdopen + U feof + U ferror + U fileno + U fprintf + U fstat + U fwrite + U getc + U getopt + U malloc + U memset + U open +0000000005252152 B optind + U putc + U read + U setbuf + U setlocale + U shutdown + U socket + U strlcpy + U warn + U write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-external.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-external.txt new file mode 100644 index 0000000000..75a80d67fb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-external.txt @@ -0,0 +1,60 @@ +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 +0000000005251392 D _DYNAMIC +0000000005251832 D _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000005252112 A __bss_start +0000000005251080 D __dso_handle + U __error@@FBSD_1.0 +0000000005252112 B __isthreaded@@FBSD_1.0 +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005251072 D __progname + U __srget@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 +0000000005252128 B __stdoutp@@FBSD_1.0 + U __swbuf@@FBSD_1.0 +0000000005252112 A _edata +0000000005252224 A _end +0000000004201448 T _fini +0000000004197600 T _init + U _init_tls@@FBSD_1.0 +0000000004198160 T _start + U atexit@@FBSD_1.0 +0000000005252212 B bflag + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 + U connect@@FBSD_1.0 +0000000005252208 B eflag +0000000005252176 B environ + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000005252200 B filename + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000004201024 T main + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 +0000000005252216 B nflag + U open@@FBSD_1.0 +0000000005252152 B optind@@FBSD_1.0 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 +0000000005252192 B rval + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 +0000000005252220 B sflag + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000005252188 B tflag +0000000005252184 B vflag + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-bsd.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-bsd.txt new file mode 100644 index 0000000000..5083ae0d7b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-bsd.txt @@ -0,0 +1,77 @@ +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 +0000000005251392 D _DYNAMIC +0000000005251832 D _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000005251800 d __CTOR_END__ +0000000005251792 d __CTOR_LIST__ +0000000005251816 d __DTOR_END__ +0000000005251808 d __DTOR_LIST__ +0000000005251336 r __FRAME_END__ +0000000005251824 d __JCR_END__ +0000000005251824 d __JCR_LIST__ +0000000005252112 A __bss_start +0000000004201408 t __do_global_ctors_aux +0000000004198320 t __do_global_dtors_aux +0000000005251080 D __dso_handle + U __error@@FBSD_1.0 +0000000005252112 B __isthreaded@@FBSD_1.0 +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005251072 D __progname + U __srget@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 +0000000005252128 B __stdoutp@@FBSD_1.0 + U __swbuf@@FBSD_1.0 +0000000005252112 A _edata +0000000005252224 A _end +0000000004201448 T _fini +0000000004197600 T _init + U _init_tls@@FBSD_1.0 +0000000004198160 T _start +0000000004194784 r abitag + U atexit@@FBSD_1.0 +0000000005252212 B bflag +0000000005252168 b bsize.4467 +0000000005252160 b buf.4468 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 +0000000005252156 b completed.5107 + U connect@@FBSD_1.0 +0000000004198432 t cook_cat +0000000005252208 B eflag +0000000005252176 B environ + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000005252200 B filename + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 +0000000004198384 t frame_dummy + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000004201024 T main + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 +0000000005252216 B nflag + U open@@FBSD_1.0 +0000000005252152 B optind@@FBSD_1.0 +0000000005251088 d p.5105 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 +0000000005252192 B rval +0000000004200240 t scanfiles + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 +0000000005252220 B sflag + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000005252188 B tflag +0000000005252184 B vflag + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-posix.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-posix.txt new file mode 100644 index 0000000000..e14200cfe2 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-posix.txt @@ -0,0 +1,77 @@ +_CurrentRuneLocale@@FBSD_1.0 B 0000000000502428 0000000000000008 +_DYNAMIC D 0000000000502140 +_GLOBAL_OFFSET_TABLE_ D 00000000005022f8 +_Jv_RegisterClasses w +__CTOR_END__ d 00000000005022d8 +__CTOR_LIST__ d 00000000005022d0 +__DTOR_END__ d 00000000005022e8 +__DTOR_LIST__ d 00000000005022e0 +__FRAME_END__ r 0000000000502108 +__JCR_END__ d 00000000005022f0 +__JCR_LIST__ d 00000000005022f0 +__bss_start A 0000000000502410 +__do_global_ctors_aux t 0000000000401bc0 +__do_global_dtors_aux t 0000000000400fb0 +__dso_handle D 0000000000502008 +__error@@FBSD_1.0 U +__isthreaded@@FBSD_1.0 B 0000000000502410 0000000000000004 +__mb_sb_limit@@FBSD_1.0 B 0000000000502414 0000000000000004 +__progname D 0000000000502000 0000000000000008 +__srget@@FBSD_1.0 U +__stderrp@@FBSD_1.0 B 0000000000502430 0000000000000008 +__stdinp@@FBSD_1.0 B 0000000000502418 0000000000000008 +__stdoutp@@FBSD_1.0 B 0000000000502420 0000000000000008 +__swbuf@@FBSD_1.0 U +_edata A 0000000000502410 +_end A 0000000000502480 +_fini T 0000000000401be8 +_init T 0000000000400ce0 +_init_tls@@FBSD_1.0 U +_start T 0000000000400f10 0000000000000092 +abitag r 00000000004001e0 0000000000000018 +atexit@@FBSD_1.0 U +bflag B 0000000000502474 0000000000000004 +bsize.4467 b 0000000000502448 0000000000000008 +buf.4468 b 0000000000502440 0000000000000008 +clearerr@@FBSD_1.0 U +close@@FBSD_1.0 U +completed.5107 b 000000000050243c 0000000000000001 +connect@@FBSD_1.0 U +cook_cat t 0000000000401020 000000000000070e +eflag B 0000000000502470 0000000000000004 +environ B 0000000000502450 0000000000000008 +err@@FBSD_1.0 U +exit@@FBSD_1.0 U +fclose@@FBSD_1.0 U +fdopen@@FBSD_1.0 U +feof@@FBSD_1.0 U +ferror@@FBSD_1.0 U +filename B 0000000000502468 0000000000000008 +fileno@@FBSD_1.0 U +fprintf@@FBSD_1.0 U +frame_dummy t 0000000000400ff0 +fstat@@FBSD_1.0 U +fwrite@@FBSD_1.0 U +getc@@FBSD_1.0 U +getopt@@FBSD_1.0 U +main T 0000000000401a40 0000000000000178 +malloc@@FBSD_1.0 U +memset@@FBSD_1.0 U +nflag B 0000000000502478 0000000000000004 +open@@FBSD_1.0 U +optind@@FBSD_1.0 B 0000000000502438 0000000000000004 +p.5105 d 0000000000502010 +putc@@FBSD_1.0 U +read@@FBSD_1.0 U +rval B 0000000000502460 0000000000000004 +scanfiles t 0000000000401730 000000000000030a +setbuf@@FBSD_1.0 U +setlocale@@FBSD_1.0 U +sflag B 000000000050247c 0000000000000004 +shutdown@@FBSD_1.0 U +socket@@FBSD_1.0 U +strlcpy@@FBSD_1.0 U +tflag B 000000000050245c 0000000000000004 +vflag B 0000000000502458 0000000000000004 +warn@@FBSD_1.0 U +write@@FBSD_1.0 U diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-sysv.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-sysv.txt new file mode 100644 index 0000000000..0ad8f7c6ff --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-format-sysv.txt @@ -0,0 +1,83 @@ + + +Symbols from test_obj: + +Name Value Class Type Size Line Section + +_CurrentRuneLocale@@FBSD_1.0|0000000005252136| B | OBJECT|0000000000000008| |.bss +_DYNAMIC |0000000005251392| D | OBJECT| | |.dynamic +_GLOBAL_OFFSET_TABLE_|0000000005251832| D | OBJECT| | |.got +_Jv_RegisterClasses | | w | NOTYPE| | |*UND* +__CTOR_END__ |0000000005251800| d | OBJECT| | |.ctors +__CTOR_LIST__ |0000000005251792| d | OBJECT| | |.ctors +__DTOR_END__ |0000000005251816| d | OBJECT| | |.dtors +__DTOR_LIST__ |0000000005251808| d | OBJECT| | |.dtors +__FRAME_END__ |0000000005251336| r | OBJECT| | |.eh_frame +__JCR_END__ |0000000005251824| d | OBJECT| | |.jcr +__JCR_LIST__ |0000000005251824| d | OBJECT| | |.jcr +__bss_start |0000000005252112| A | NOTYPE| | |*ABS* +__do_global_ctors_aux|0000000004201408| t | FUNC| | |.text +__do_global_dtors_aux|0000000004198320| t | FUNC| | |.text +__dso_handle |0000000005251080| D | OBJECT| | |.data +__error@@FBSD_1.0 | | U | FUNC|0000000000000008| |*UND* +__isthreaded@@FBSD_1.0|0000000005252112| B | OBJECT|0000000000000004| |.bss +__mb_sb_limit@@FBSD_1.0|0000000005252116| B | OBJECT|0000000000000004| |.bss +__progname |0000000005251072| D | OBJECT|0000000000000008| |.data +__srget@@FBSD_1.0 | | U | FUNC|0000000000000037| |*UND* +__stderrp@@FBSD_1.0 |0000000005252144| B | OBJECT|0000000000000008| |.bss +__stdinp@@FBSD_1.0 |0000000005252120| B | OBJECT|0000000000000008| |.bss +__stdoutp@@FBSD_1.0 |0000000005252128| B | OBJECT|0000000000000008| |.bss +__swbuf@@FBSD_1.0 | | U | FUNC|0000000000000195| |*UND* +_edata |0000000005252112| A | NOTYPE| | |*ABS* +_end |0000000005252224| A | NOTYPE| | |*ABS* +_fini |0000000004201448| T | FUNC| | |.fini +_init |0000000004197600| T | FUNC| | |.init +_init_tls@@FBSD_1.0 | | U | FUNC|0000000000000002| |*UND* +_start |0000000004198160| T | FUNC|0000000000000146| |.text +abitag |0000000004194784| r | OBJECT|0000000000000024| |.note.ABI-tag +atexit@@FBSD_1.0 | | U | FUNC|0000000000000047| |*UND* +bflag |0000000005252212| B | OBJECT|0000000000000004| |.bss +bsize.4467 |0000000005252168| b | OBJECT|0000000000000008| |.bss +buf.4468 |0000000005252160| b | OBJECT|0000000000000008| |.bss +clearerr@@FBSD_1.0 | | U | FUNC|0000000000000090| |*UND* +close@@FBSD_1.0 | | U | FUNC| | |*UND* +completed.5107 |0000000005252156| b | OBJECT|0000000000000001| |.bss +connect@@FBSD_1.0 | | U | FUNC| | |*UND* +cook_cat |0000000004198432| t | FUNC|0000000000001806| |.text +eflag |0000000005252208| B | OBJECT|0000000000000004| |.bss +environ |0000000005252176| B | OBJECT|0000000000000008| |.bss +err@@FBSD_1.0 | | U | FUNC|0000000000000170| |*UND* +exit@@FBSD_1.0 | | U | FUNC|0000000000000047| |*UND* +fclose@@FBSD_1.0 | | U | FUNC|0000000000000242| |*UND* +fdopen@@FBSD_1.0 | | U | FUNC|0000000000000274| |*UND* +feof@@FBSD_1.0 | | U | FUNC|0000000000000101| |*UND* +ferror@@FBSD_1.0 | | U | FUNC|0000000000000101| |*UND* +filename |0000000005252200| B | OBJECT|0000000000000008| |.bss +fileno@@FBSD_1.0 | | U | FUNC|0000000000000091| |*UND* +fprintf@@FBSD_1.0 | | U | FUNC|0000000000000144| |*UND* +frame_dummy |0000000004198384| t | FUNC| | |.text +fstat@@FBSD_1.0 | | U | FUNC| | |*UND* +fwrite@@FBSD_1.0 | | U | FUNC|0000000000000202| |*UND* +getc@@FBSD_1.0 | | U | FUNC|0000000000000127| |*UND* +getopt@@FBSD_1.0 | | U | FUNC|0000000000000682| |*UND* +main |0000000004201024| T | FUNC|0000000000000376| |.text +malloc@@FBSD_1.0 | | U | FUNC|0000000000001280| |*UND* +memset@@FBSD_1.0 | | U | FUNC| | |*UND* +nflag |0000000005252216| B | OBJECT|0000000000000004| |.bss +open@@FBSD_1.0 | | U | FUNC| | |*UND* +optind@@FBSD_1.0 |0000000005252152| B | OBJECT|0000000000000004| |.bss +p.5105 |0000000005251088| d | OBJECT| | |.data +putc@@FBSD_1.0 | | U | FUNC|0000000000000153| |*UND* +read@@FBSD_1.0 | | U | FUNC| | |*UND* +rval |0000000005252192| B | OBJECT|0000000000000004| |.bss +scanfiles |0000000004200240| t | FUNC|0000000000000778| |.text +setbuf@@FBSD_1.0 | | U | FUNC|0000000000000019| |*UND* +setlocale@@FBSD_1.0 | | U | FUNC|0000000000000874| |*UND* +sflag |0000000005252220| B | OBJECT|0000000000000004| |.bss +shutdown@@FBSD_1.0 | | U | FUNC| | |*UND* +socket@@FBSD_1.0 | | U | FUNC| | |*UND* +strlcpy@@FBSD_1.0 | | U | FUNC|0000000000000054| |*UND* +tflag |0000000005252188| B | OBJECT|0000000000000004| |.bss +vflag |0000000005252184| B | OBJECT|0000000000000004| |.bss +warn@@FBSD_1.0 | | U | FUNC|0000000000000168| |*UND* +write@@FBSD_1.0 | | U | FUNC| | |*UND* diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-file-name.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-file-name.txt new file mode 100644 index 0000000000..26c4241f54 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-file-name.txt @@ -0,0 +1,77 @@ +test_obj:0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 +test_obj:0000000005251392 D _DYNAMIC +test_obj:0000000005251832 D _GLOBAL_OFFSET_TABLE_ +test_obj: w _Jv_RegisterClasses +test_obj:0000000005251800 d __CTOR_END__ +test_obj:0000000005251792 d __CTOR_LIST__ +test_obj:0000000005251816 d __DTOR_END__ +test_obj:0000000005251808 d __DTOR_LIST__ +test_obj:0000000005251336 r __FRAME_END__ +test_obj:0000000005251824 d __JCR_END__ +test_obj:0000000005251824 d __JCR_LIST__ +test_obj:0000000005252112 A __bss_start +test_obj:0000000004201408 t __do_global_ctors_aux +test_obj:0000000004198320 t __do_global_dtors_aux +test_obj:0000000005251080 D __dso_handle +test_obj: U __error@@FBSD_1.0 +test_obj:0000000005252112 B __isthreaded@@FBSD_1.0 +test_obj:0000000005252116 B __mb_sb_limit@@FBSD_1.0 +test_obj:0000000005251072 D __progname +test_obj: U __srget@@FBSD_1.0 +test_obj:0000000005252144 B __stderrp@@FBSD_1.0 +test_obj:0000000005252120 B __stdinp@@FBSD_1.0 +test_obj:0000000005252128 B __stdoutp@@FBSD_1.0 +test_obj: U __swbuf@@FBSD_1.0 +test_obj:0000000005252112 A _edata +test_obj:0000000005252224 A _end +test_obj:0000000004201448 T _fini +test_obj:0000000004197600 T _init +test_obj: U _init_tls@@FBSD_1.0 +test_obj:0000000004198160 T _start +test_obj:0000000004194784 r abitag +test_obj: U atexit@@FBSD_1.0 +test_obj:0000000005252212 B bflag +test_obj:0000000005252168 b bsize.4467 +test_obj:0000000005252160 b buf.4468 +test_obj: U clearerr@@FBSD_1.0 +test_obj: U close@@FBSD_1.0 +test_obj:0000000005252156 b completed.5107 +test_obj: U connect@@FBSD_1.0 +test_obj:0000000004198432 t cook_cat +test_obj:0000000005252208 B eflag +test_obj:0000000005252176 B environ +test_obj: U err@@FBSD_1.0 +test_obj: U exit@@FBSD_1.0 +test_obj: U fclose@@FBSD_1.0 +test_obj: U fdopen@@FBSD_1.0 +test_obj: U feof@@FBSD_1.0 +test_obj: U ferror@@FBSD_1.0 +test_obj:0000000005252200 B filename +test_obj: U fileno@@FBSD_1.0 +test_obj: U fprintf@@FBSD_1.0 +test_obj:0000000004198384 t frame_dummy +test_obj: U fstat@@FBSD_1.0 +test_obj: U fwrite@@FBSD_1.0 +test_obj: U getc@@FBSD_1.0 +test_obj: U getopt@@FBSD_1.0 +test_obj:0000000004201024 T main +test_obj: U malloc@@FBSD_1.0 +test_obj: U memset@@FBSD_1.0 +test_obj:0000000005252216 B nflag +test_obj: U open@@FBSD_1.0 +test_obj:0000000005252152 B optind@@FBSD_1.0 +test_obj:0000000005251088 d p.5105 +test_obj: U putc@@FBSD_1.0 +test_obj: U read@@FBSD_1.0 +test_obj:0000000005252192 B rval +test_obj:0000000004200240 t scanfiles +test_obj: U setbuf@@FBSD_1.0 +test_obj: U setlocale@@FBSD_1.0 +test_obj:0000000005252220 B sflag +test_obj: U shutdown@@FBSD_1.0 +test_obj: U socket@@FBSD_1.0 +test_obj: U strlcpy@@FBSD_1.0 +test_obj:0000000005252188 B tflag +test_obj:0000000005252184 B vflag +test_obj: U warn@@FBSD_1.0 +test_obj: U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-size.txt new file mode 100644 index 0000000000..36e458f17f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-print-size.txt @@ -0,0 +1,77 @@ +0000000005252136 0000000000000008 B _CurrentRuneLocale@@FBSD_1.0 +0000000005251392 D _DYNAMIC +0000000005251832 D _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000005251800 d __CTOR_END__ +0000000005251792 d __CTOR_LIST__ +0000000005251816 d __DTOR_END__ +0000000005251808 d __DTOR_LIST__ +0000000005251336 r __FRAME_END__ +0000000005251824 d __JCR_END__ +0000000005251824 d __JCR_LIST__ +0000000005252112 A __bss_start +0000000004201408 t __do_global_ctors_aux +0000000004198320 t __do_global_dtors_aux +0000000005251080 D __dso_handle + U __error@@FBSD_1.0 +0000000005252112 0000000000000004 B __isthreaded@@FBSD_1.0 +0000000005252116 0000000000000004 B __mb_sb_limit@@FBSD_1.0 +0000000005251072 0000000000000008 D __progname + U __srget@@FBSD_1.0 +0000000005252144 0000000000000008 B __stderrp@@FBSD_1.0 +0000000005252120 0000000000000008 B __stdinp@@FBSD_1.0 +0000000005252128 0000000000000008 B __stdoutp@@FBSD_1.0 + U __swbuf@@FBSD_1.0 +0000000005252112 A _edata +0000000005252224 A _end +0000000004201448 T _fini +0000000004197600 T _init + U _init_tls@@FBSD_1.0 +0000000004198160 0000000000000146 T _start +0000000004194784 0000000000000024 r abitag + U atexit@@FBSD_1.0 +0000000005252212 0000000000000004 B bflag +0000000005252168 0000000000000008 b bsize.4467 +0000000005252160 0000000000000008 b buf.4468 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 +0000000005252156 0000000000000001 b completed.5107 + U connect@@FBSD_1.0 +0000000004198432 0000000000001806 t cook_cat +0000000005252208 0000000000000004 B eflag +0000000005252176 0000000000000008 B environ + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000005252200 0000000000000008 B filename + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 +0000000004198384 t frame_dummy + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000004201024 0000000000000376 T main + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 +0000000005252216 0000000000000004 B nflag + U open@@FBSD_1.0 +0000000005252152 0000000000000004 B optind@@FBSD_1.0 +0000000005251088 d p.5105 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 +0000000005252192 0000000000000004 B rval +0000000004200240 0000000000000778 t scanfiles + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 +0000000005252220 0000000000000004 B sflag + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000005252188 0000000000000004 B tflag +0000000005252184 0000000000000004 B vflag + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-hexa.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-hexa.txt new file mode 100644 index 0000000000..b82b35633d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-hexa.txt @@ -0,0 +1,77 @@ +0000000000502428 B _CurrentRuneLocale@@FBSD_1.0 +0000000000502140 D _DYNAMIC +00000000005022f8 D _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +00000000005022d8 d __CTOR_END__ +00000000005022d0 d __CTOR_LIST__ +00000000005022e8 d __DTOR_END__ +00000000005022e0 d __DTOR_LIST__ +0000000000502108 r __FRAME_END__ +00000000005022f0 d __JCR_END__ +00000000005022f0 d __JCR_LIST__ +0000000000502410 A __bss_start +0000000000401bc0 t __do_global_ctors_aux +0000000000400fb0 t __do_global_dtors_aux +0000000000502008 D __dso_handle + U __error@@FBSD_1.0 +0000000000502410 B __isthreaded@@FBSD_1.0 +0000000000502414 B __mb_sb_limit@@FBSD_1.0 +0000000000502000 D __progname + U __srget@@FBSD_1.0 +0000000000502430 B __stderrp@@FBSD_1.0 +0000000000502418 B __stdinp@@FBSD_1.0 +0000000000502420 B __stdoutp@@FBSD_1.0 + U __swbuf@@FBSD_1.0 +0000000000502410 A _edata +0000000000502480 A _end +0000000000401be8 T _fini +0000000000400ce0 T _init + U _init_tls@@FBSD_1.0 +0000000000400f10 T _start +00000000004001e0 r abitag + U atexit@@FBSD_1.0 +0000000000502474 B bflag +0000000000502448 b bsize.4467 +0000000000502440 b buf.4468 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 +000000000050243c b completed.5107 + U connect@@FBSD_1.0 +0000000000401020 t cook_cat +0000000000502470 B eflag +0000000000502450 B environ + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000000502468 B filename + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 +0000000000400ff0 t frame_dummy + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000000401a40 T main + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 +0000000000502478 B nflag + U open@@FBSD_1.0 +0000000000502438 B optind@@FBSD_1.0 +0000000000502010 d p.5105 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 +0000000000502460 B rval +0000000000401730 t scanfiles + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 +000000000050247c B sflag + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +000000000050245c B tflag +0000000000502458 B vflag + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-octal.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-octal.txt new file mode 100644 index 0000000000..213a5486cb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-radix-octal.txt @@ -0,0 +1,77 @@ +0000000024022050 B _CurrentRuneLocale@@FBSD_1.0 +0000000024020500 D _DYNAMIC +0000000024021370 D _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000024021330 d __CTOR_END__ +0000000024021320 d __CTOR_LIST__ +0000000024021350 d __DTOR_END__ +0000000024021340 d __DTOR_LIST__ +0000000024020410 r __FRAME_END__ +0000000024021360 d __JCR_END__ +0000000024021360 d __JCR_LIST__ +0000000024022020 A __bss_start +0000000020015700 t __do_global_ctors_aux +0000000020007660 t __do_global_dtors_aux +0000000024020010 D __dso_handle + U __error@@FBSD_1.0 +0000000024022020 B __isthreaded@@FBSD_1.0 +0000000024022024 B __mb_sb_limit@@FBSD_1.0 +0000000024020000 D __progname + U __srget@@FBSD_1.0 +0000000024022060 B __stderrp@@FBSD_1.0 +0000000024022030 B __stdinp@@FBSD_1.0 +0000000024022040 B __stdoutp@@FBSD_1.0 + U __swbuf@@FBSD_1.0 +0000000024022020 A _edata +0000000024022200 A _end +0000000020015750 T _fini +0000000020006340 T _init + U _init_tls@@FBSD_1.0 +0000000020007420 T _start +0000000020000740 r abitag + U atexit@@FBSD_1.0 +0000000024022164 B bflag +0000000024022110 b bsize.4467 +0000000024022100 b buf.4468 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 +0000000024022074 b completed.5107 + U connect@@FBSD_1.0 +0000000020010040 t cook_cat +0000000024022160 B eflag +0000000024022120 B environ + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000024022150 B filename + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 +0000000020007760 t frame_dummy + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000020015100 T main + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 +0000000024022170 B nflag + U open@@FBSD_1.0 +0000000024022070 B optind@@FBSD_1.0 +0000000024020020 d p.5105 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 +0000000024022140 B rval +0000000020013460 t scanfiles + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 +0000000024022174 B sflag + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000024022134 B tflag +0000000024022130 B vflag + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-no.txt new file mode 100644 index 0000000000..e2ef8cab9f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-no.txt @@ -0,0 +1,77 @@ +0000000004194784 r abitag +0000000005251792 d __CTOR_LIST__ +0000000005251808 d __DTOR_LIST__ +0000000005251824 d __JCR_LIST__ +0000000004198320 t __do_global_dtors_aux +0000000005252156 b completed.5107 +0000000005251088 d p.5105 +0000000004198384 t frame_dummy +0000000005251800 d __CTOR_END__ +0000000005251816 d __DTOR_END__ +0000000005251336 r __FRAME_END__ +0000000005251824 d __JCR_END__ +0000000004201408 t __do_global_ctors_aux +0000000004198432 t cook_cat +0000000004200240 t scanfiles +0000000005252160 b buf.4468 +0000000005252168 b bsize.4467 + U fprintf@@FBSD_1.0 + U write@@FBSD_1.0 +0000000005252184 B vflag +0000000005251392 D _DYNAMIC + U putc@@FBSD_1.0 + U feof@@FBSD_1.0 +0000000005252188 B tflag +0000000005251080 D __dso_handle + U clearerr@@FBSD_1.0 + U shutdown@@FBSD_1.0 + U _init_tls@@FBSD_1.0 +0000000004197600 T _init +0000000005252192 B rval +0000000005252200 B filename +0000000005252176 B environ +0000000005252208 B eflag +0000000005252212 B bflag + U socket@@FBSD_1.0 +0000000005252112 B __isthreaded@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000005251072 D __progname +0000000004198160 T _start + U memset@@FBSD_1.0 +0000000005252216 B nflag + U connect@@FBSD_1.0 + U __error@@FBSD_1.0 + U fdopen@@FBSD_1.0 +0000000005252112 A __bss_start + U close@@FBSD_1.0 +0000000004201024 T main + U warn@@FBSD_1.0 +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000004201448 T _fini +0000000005252128 B __stdoutp@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U open@@FBSD_1.0 +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 + U fileno@@FBSD_1.0 + U __swbuf@@FBSD_1.0 + U setbuf@@FBSD_1.0 + U exit@@FBSD_1.0 + U malloc@@FBSD_1.0 + U err@@FBSD_1.0 +0000000005252112 A _edata +0000000005251832 D _GLOBAL_OFFSET_TABLE_ +0000000005252224 A _end + U setlocale@@FBSD_1.0 + U fclose@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252152 B optind@@FBSD_1.0 + U __srget@@FBSD_1.0 + U atexit@@FBSD_1.0 +0000000005252220 B sflag + U read@@FBSD_1.0 + w _Jv_RegisterClasses + U getc@@FBSD_1.0 + U fstat@@FBSD_1.0 + U strlcpy@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-num.txt new file mode 100644 index 0000000000..6ddfc583dd --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-num.txt @@ -0,0 +1,77 @@ + w _Jv_RegisterClasses + U __error@@FBSD_1.0 + U __srget@@FBSD_1.0 + U __swbuf@@FBSD_1.0 + U _init_tls@@FBSD_1.0 + U atexit@@FBSD_1.0 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 + U connect@@FBSD_1.0 + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 + U warn@@FBSD_1.0 + U write@@FBSD_1.0 +0000000004194784 r abitag +0000000004197600 T _init +0000000004198160 T _start +0000000004198320 t __do_global_dtors_aux +0000000004198384 t frame_dummy +0000000004198432 t cook_cat +0000000004200240 t scanfiles +0000000004201024 T main +0000000004201408 t __do_global_ctors_aux +0000000004201448 T _fini +0000000005251072 D __progname +0000000005251080 D __dso_handle +0000000005251088 d p.5105 +0000000005251336 r __FRAME_END__ +0000000005251392 D _DYNAMIC +0000000005251792 d __CTOR_LIST__ +0000000005251800 d __CTOR_END__ +0000000005251808 d __DTOR_LIST__ +0000000005251816 d __DTOR_END__ +0000000005251824 d __JCR_END__ +0000000005251824 d __JCR_LIST__ +0000000005251832 D _GLOBAL_OFFSET_TABLE_ +0000000005252112 A __bss_start +0000000005252112 B __isthreaded@@FBSD_1.0 +0000000005252112 A _edata +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 +0000000005252128 B __stdoutp@@FBSD_1.0 +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252152 B optind@@FBSD_1.0 +0000000005252156 b completed.5107 +0000000005252160 b buf.4468 +0000000005252168 b bsize.4467 +0000000005252176 B environ +0000000005252184 B vflag +0000000005252188 B tflag +0000000005252192 B rval +0000000005252200 B filename +0000000005252208 B eflag +0000000005252212 B bflag +0000000005252216 B nflag +0000000005252220 B sflag +0000000005252224 A _end diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-no.txt new file mode 100644 index 0000000000..e2ef8cab9f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-no.txt @@ -0,0 +1,77 @@ +0000000004194784 r abitag +0000000005251792 d __CTOR_LIST__ +0000000005251808 d __DTOR_LIST__ +0000000005251824 d __JCR_LIST__ +0000000004198320 t __do_global_dtors_aux +0000000005252156 b completed.5107 +0000000005251088 d p.5105 +0000000004198384 t frame_dummy +0000000005251800 d __CTOR_END__ +0000000005251816 d __DTOR_END__ +0000000005251336 r __FRAME_END__ +0000000005251824 d __JCR_END__ +0000000004201408 t __do_global_ctors_aux +0000000004198432 t cook_cat +0000000004200240 t scanfiles +0000000005252160 b buf.4468 +0000000005252168 b bsize.4467 + U fprintf@@FBSD_1.0 + U write@@FBSD_1.0 +0000000005252184 B vflag +0000000005251392 D _DYNAMIC + U putc@@FBSD_1.0 + U feof@@FBSD_1.0 +0000000005252188 B tflag +0000000005251080 D __dso_handle + U clearerr@@FBSD_1.0 + U shutdown@@FBSD_1.0 + U _init_tls@@FBSD_1.0 +0000000004197600 T _init +0000000005252192 B rval +0000000005252200 B filename +0000000005252176 B environ +0000000005252208 B eflag +0000000005252212 B bflag + U socket@@FBSD_1.0 +0000000005252112 B __isthreaded@@FBSD_1.0 + U getopt@@FBSD_1.0 +0000000005251072 D __progname +0000000004198160 T _start + U memset@@FBSD_1.0 +0000000005252216 B nflag + U connect@@FBSD_1.0 + U __error@@FBSD_1.0 + U fdopen@@FBSD_1.0 +0000000005252112 A __bss_start + U close@@FBSD_1.0 +0000000004201024 T main + U warn@@FBSD_1.0 +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 + U ferror@@FBSD_1.0 +0000000004201448 T _fini +0000000005252128 B __stdoutp@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U open@@FBSD_1.0 +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 + U fileno@@FBSD_1.0 + U __swbuf@@FBSD_1.0 + U setbuf@@FBSD_1.0 + U exit@@FBSD_1.0 + U malloc@@FBSD_1.0 + U err@@FBSD_1.0 +0000000005252112 A _edata +0000000005251832 D _GLOBAL_OFFSET_TABLE_ +0000000005252224 A _end + U setlocale@@FBSD_1.0 + U fclose@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252152 B optind@@FBSD_1.0 + U __srget@@FBSD_1.0 + U atexit@@FBSD_1.0 +0000000005252220 B sflag + U read@@FBSD_1.0 + w _Jv_RegisterClasses + U getc@@FBSD_1.0 + U fstat@@FBSD_1.0 + U strlcpy@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-num.txt new file mode 100644 index 0000000000..4207b9860d --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-num.txt @@ -0,0 +1,77 @@ +0000000005252224 A _end +0000000005252220 B sflag +0000000005252216 B nflag +0000000005252212 B bflag +0000000005252208 B eflag +0000000005252200 B filename +0000000005252192 B rval +0000000005252188 B tflag +0000000005252184 B vflag +0000000005252176 B environ +0000000005252168 b bsize.4467 +0000000005252160 b buf.4468 +0000000005252156 b completed.5107 +0000000005252152 B optind@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 +0000000005252128 B __stdoutp@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005252112 A _edata +0000000005252112 B __isthreaded@@FBSD_1.0 +0000000005252112 A __bss_start +0000000005251832 D _GLOBAL_OFFSET_TABLE_ +0000000005251824 d __JCR_LIST__ +0000000005251824 d __JCR_END__ +0000000005251816 d __DTOR_END__ +0000000005251808 d __DTOR_LIST__ +0000000005251800 d __CTOR_END__ +0000000005251792 d __CTOR_LIST__ +0000000005251392 D _DYNAMIC +0000000005251336 r __FRAME_END__ +0000000005251088 d p.5105 +0000000005251080 D __dso_handle +0000000005251072 D __progname +0000000004201448 T _fini +0000000004201408 t __do_global_ctors_aux +0000000004201024 T main +0000000004200240 t scanfiles +0000000004198432 t cook_cat +0000000004198384 t frame_dummy +0000000004198320 t __do_global_dtors_aux +0000000004198160 T _start +0000000004197600 T _init +0000000004194784 r abitag + U write@@FBSD_1.0 + U warn@@FBSD_1.0 + U strlcpy@@FBSD_1.0 + U socket@@FBSD_1.0 + U shutdown@@FBSD_1.0 + U setlocale@@FBSD_1.0 + U setbuf@@FBSD_1.0 + U read@@FBSD_1.0 + U putc@@FBSD_1.0 + U open@@FBSD_1.0 + U memset@@FBSD_1.0 + U malloc@@FBSD_1.0 + U getopt@@FBSD_1.0 + U getc@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U fstat@@FBSD_1.0 + U fprintf@@FBSD_1.0 + U fileno@@FBSD_1.0 + U ferror@@FBSD_1.0 + U feof@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U fclose@@FBSD_1.0 + U exit@@FBSD_1.0 + U err@@FBSD_1.0 + U connect@@FBSD_1.0 + U close@@FBSD_1.0 + U clearerr@@FBSD_1.0 + U atexit@@FBSD_1.0 + U _init_tls@@FBSD_1.0 + U __swbuf@@FBSD_1.0 + U __srget@@FBSD_1.0 + U __error@@FBSD_1.0 + w _Jv_RegisterClasses diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-size.txt new file mode 100644 index 0000000000..f36e031686 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse-size.txt @@ -0,0 +1,25 @@ +0000000000001806 t cook_cat +0000000000000778 t scanfiles +0000000000000376 T main +0000000000000146 T _start +0000000000000024 r abitag +0000000000000008 B filename +0000000000000008 B environ +0000000000000008 b buf.4468 +0000000000000008 b bsize.4467 +0000000000000008 B __stdoutp@@FBSD_1.0 +0000000000000008 B __stdinp@@FBSD_1.0 +0000000000000008 B __stderrp@@FBSD_1.0 +0000000000000008 D __progname +0000000000000008 B _CurrentRuneLocale@@FBSD_1.0 +0000000000000004 B vflag +0000000000000004 B tflag +0000000000000004 B sflag +0000000000000004 B rval +0000000000000004 B optind@@FBSD_1.0 +0000000000000004 B nflag +0000000000000004 B eflag +0000000000000004 B bflag +0000000000000004 B __mb_sb_limit@@FBSD_1.0 +0000000000000004 B __isthreaded@@FBSD_1.0 +0000000000000001 b completed.5107 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse.txt new file mode 100644 index 0000000000..80c5f86045 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-reverse.txt @@ -0,0 +1,77 @@ + U write@@FBSD_1.0 + U warn@@FBSD_1.0 +0000000005252184 B vflag +0000000005252188 B tflag + U strlcpy@@FBSD_1.0 + U socket@@FBSD_1.0 + U shutdown@@FBSD_1.0 +0000000005252220 B sflag + U setlocale@@FBSD_1.0 + U setbuf@@FBSD_1.0 +0000000004200240 t scanfiles +0000000005252192 B rval + U read@@FBSD_1.0 + U putc@@FBSD_1.0 +0000000005251088 d p.5105 +0000000005252152 B optind@@FBSD_1.0 + U open@@FBSD_1.0 +0000000005252216 B nflag + U memset@@FBSD_1.0 + U malloc@@FBSD_1.0 +0000000004201024 T main + U getopt@@FBSD_1.0 + U getc@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U fstat@@FBSD_1.0 +0000000004198384 t frame_dummy + U fprintf@@FBSD_1.0 + U fileno@@FBSD_1.0 +0000000005252200 B filename + U ferror@@FBSD_1.0 + U feof@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U fclose@@FBSD_1.0 + U exit@@FBSD_1.0 + U err@@FBSD_1.0 +0000000005252176 B environ +0000000005252208 B eflag +0000000004198432 t cook_cat + U connect@@FBSD_1.0 +0000000005252156 b completed.5107 + U close@@FBSD_1.0 + U clearerr@@FBSD_1.0 +0000000005252160 b buf.4468 +0000000005252168 b bsize.4467 +0000000005252212 B bflag + U atexit@@FBSD_1.0 +0000000004194784 r abitag +0000000004198160 T _start + U _init_tls@@FBSD_1.0 +0000000004197600 T _init +0000000004201448 T _fini +0000000005252224 A _end +0000000005252112 A _edata + U __swbuf@@FBSD_1.0 +0000000005252128 B __stdoutp@@FBSD_1.0 +0000000005252120 B __stdinp@@FBSD_1.0 +0000000005252144 B __stderrp@@FBSD_1.0 + U __srget@@FBSD_1.0 +0000000005251072 D __progname +0000000005252116 B __mb_sb_limit@@FBSD_1.0 +0000000005252112 B __isthreaded@@FBSD_1.0 + U __error@@FBSD_1.0 +0000000005251080 D __dso_handle +0000000004198320 t __do_global_dtors_aux +0000000004201408 t __do_global_ctors_aux +0000000005252112 A __bss_start +0000000005251824 d __JCR_LIST__ +0000000005251824 d __JCR_END__ +0000000005251336 r __FRAME_END__ +0000000005251808 d __DTOR_LIST__ +0000000005251816 d __DTOR_END__ +0000000005251792 d __CTOR_LIST__ +0000000005251800 d __CTOR_END__ + w _Jv_RegisterClasses +0000000005251832 D _GLOBAL_OFFSET_TABLE_ +0000000005251392 D _DYNAMIC +0000000005252136 B _CurrentRuneLocale@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-size.txt new file mode 100644 index 0000000000..cadebc5b08 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-sort-size.txt @@ -0,0 +1,25 @@ +0000000000000001 b completed.5107 +0000000000000004 B __isthreaded@@FBSD_1.0 +0000000000000004 B __mb_sb_limit@@FBSD_1.0 +0000000000000004 B bflag +0000000000000004 B eflag +0000000000000004 B nflag +0000000000000004 B optind@@FBSD_1.0 +0000000000000004 B rval +0000000000000004 B sflag +0000000000000004 B tflag +0000000000000004 B vflag +0000000000000008 B _CurrentRuneLocale@@FBSD_1.0 +0000000000000008 D __progname +0000000000000008 B __stderrp@@FBSD_1.0 +0000000000000008 B __stdinp@@FBSD_1.0 +0000000000000008 B __stdoutp@@FBSD_1.0 +0000000000000008 b bsize.4467 +0000000000000008 b buf.4468 +0000000000000008 B environ +0000000000000008 B filename +0000000000000024 r abitag +0000000000000146 T _start +0000000000000376 T main +0000000000000778 t scanfiles +0000000000001806 t cook_cat diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-undef.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-undef.txt new file mode 100644 index 0000000000..2517744d6b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj-undef.txt @@ -0,0 +1,33 @@ + w _Jv_RegisterClasses + U __error@@FBSD_1.0 + U __srget@@FBSD_1.0 + U __swbuf@@FBSD_1.0 + U _init_tls@@FBSD_1.0 + U atexit@@FBSD_1.0 + U clearerr@@FBSD_1.0 + U close@@FBSD_1.0 + U connect@@FBSD_1.0 + U err@@FBSD_1.0 + U exit@@FBSD_1.0 + U fclose@@FBSD_1.0 + U fdopen@@FBSD_1.0 + U feof@@FBSD_1.0 + U ferror@@FBSD_1.0 + U fileno@@FBSD_1.0 + U fprintf@@FBSD_1.0 + U fstat@@FBSD_1.0 + U fwrite@@FBSD_1.0 + U getc@@FBSD_1.0 + U getopt@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U putc@@FBSD_1.0 + U read@@FBSD_1.0 + U setbuf@@FBSD_1.0 + U setlocale@@FBSD_1.0 + U shutdown@@FBSD_1.0 + U socket@@FBSD_1.0 + U strlcpy@@FBSD_1.0 + U warn@@FBSD_1.0 + U write@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj.uu b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj.uu new file mode 100644 index 0000000000..69f5bf405a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_object1/test_obj.uu @@ -0,0 +1,351 @@ +begin 644 test_obj +M?T5,1@(!`0D```````````(`/@`!````$`]```````!``````````&`F```` +M`````````$``.``'`$``'``9``8````%````0`````````!``$```````$`` +M0```````B`$```````"(`0````````@``````````P````0```#(`0`````` +M`,@!0```````R`%````````5`````````!4``````````0`````````!```` +M!0````````````````!``````````$```````(P=````````C!T````````` +M`!````````$````&`````"``````````(%`````````@4```````$`0````` +M``"`!```````````$````````@````8```!`(0```````$`A4```````0"%0 +M``````"0`0```````)`!````````"``````````$````!````.`!```````` +MX`%```````#@`4```````!@`````````&``````````$`````````%#E=&0$ +M````A!T```````"$'4```````(0=0```````"``````````(``````````0` +M````````+VQI8F5X96,O;&0M96QF+G-O+C$`````"`````0````!````1G)E +M94)31``D-0P`)0```"P`````````*0```!P`````````!P```"4````````` +M'P````P````$````"0```"H````;````$P````\````B````$0````4````5 +M````)@```"L````G````(P```!X````*````(0```````````````````!T` +M```(````(````!`````!``````````8````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````T````"````````````````````#@```!0````````````````````` +M``````````,````:`````````!8``````````````!<`````````"P`````` +M```D````&````!(````H````&0`````````````````````````````````` +M````````````@````!(````$#4```````)``````````+0$``!(````4#4`` +M````````````````#0$``!(````D#4```````)D`````````7P```!(````T +M#4```````&4`````````_0```!(```!$#4```````%H`````````$@$``!(` +M``!4#4``````````````````ZP```!(```!D#4````````(`````````<@`` +M`!$`%P!0)%````````@`````````:P```!(```!T#4`````````````````` +MT````!$`%P`0)%````````0`````````W0```!(```"$#4```````*H"```` +M````CP```!$`$```(%````````@`````````Y````!(```"4#4`````````` +M````````-P```!(```"D#4``````````````````H0```!(```"T#4`````` +M``@`````````R0```!(```#$#4```````!(!````````!P$``!(```#4#4`` +M````````````````00$``!(```#D#4```````*@`````````'P```!$`%P`4 +M)%````````0`````````/P```!$`%P`8)%````````@`````````F@```!(` +M``#T#4```````&4`````````+0```!$`%P`@)%````````@`````````+`$` +M`!(````$#D```````,H`````````RP```!(````4#D`````````````````` +MM@```!$`%P`H)%````````@`````````.@$``!(````D#D```````%L````` +M````]0```!(````T#D```````,,`````````,P$``!(```!$#D```````!,` +M````````'0$``!(```!4#D```````"\`````````9````!(```!D#D`````` +M```%`````````@$``!(```!T#D```````*H`````````1@$``!``\?^`)%`` +M````````````````(@$``!(```"$#D```````&H#````````!@$``!(```"4 +M#D```````/(`````````50```!$`%P`P)%````````@`````````B````!$` +M%P`X)%````````0`````````2````!(```"D#D```````"4`````````&P$` +M`!(```"T#D```````"\`````````J0```!(```#$#D`````````````````` +M`0```"``````````````````````````4````!(```#4#D```````'\````` +M````>@```!(```#D#D``````````````````K@```!(```#T#D```````#8` +M`````````%]*=E]296=I0!?0W5R@<```(`2P$````````0)%````````4````*```````````````4 +M)%````````4````3```````````````8)%````````4````4```````````` +M```@)%````````4````6```````````````H)%````````4````9```````` +M```````P)%````````4````C```````````````X)%````````4````D```` +M```````````0(U````````<````!```````````````8(U````````<````" +M```````````````@(U````````<````#```````````````H(U````````<` +M```$```````````````P(U````````<````%```````````````X(U`````` +M``<````&``````````````!`(U````````<````'``````````````!((U`` +M``````<````)``````````````!0(U````````<````+``````````````!8 +M(U````````<````-``````````````!@(U````````<````.```````````` +M``!H(U````````<````/``````````````!P(U````````<````0```````` +M``````!X(U````````<````1``````````````"`(U````````<````2```` +M``````````"((U````````<````5``````````````"0(U````````<````7 +M``````````````"8(U````````<````8``````````````"@(U````````<` +M```:``````````````"H(U````````<````;``````````````"P(U`````` +M``<````<``````````````"X(U````````<````=``````````````#`(U`` +M``````<````>``````````````#((U````````<````?``````````````#0 +M(U````````<````A``````````````#8(U````````<````B```````````` +M``#@(U````````<````E``````````````#H(U````````<````F```````` +M``````#P(U````````<````G``````````````#X(U````````<````I```` +M````````````)%````````<````J```````````````()%````````<````K +M``````````````!(@^P(Z`<#``#HT@X``$B#Q`C#`/\U!A80`/\E"!80`)"0 +MD)#_)086$`!H`````.G@_____R7^%1``:`$```#IT/____\E]A40`&@"```` +MZ<#_____)>X5$`!H`P```.FP_____R7F%1``:`0```#IH/____\EWA40`&@% +M````Z9#_____)=85$`!H!@```.F`_____R7.%1``:`<```#I%1``:`T```#I$/__ +M__\EEA40`&@.````Z0#_____)8X5$`!H#P```.GP_O___R6&%1``:!````#I +MX/[___\E?A40`&@1````Z=#^____)785$`!H$@```.G`_O___R5N%1``:!,` +M``#IL/[___\E9A40`&@4````Z:#^____)5X5$`!H%0```.F0_O___R56%1`` +M:!8```#I@/[___\E3A40`&@7````Z7#^____)485$`!H&````.E@_O___R4^ +M%1``:!D```#I4/[___\E-A40`&@:````Z4#^____)2X5$`!H&P```.DP_O__ +M_R4F%1``:!P```#I(/[___\E'A40`&@=````Z1#^____)185$`!H'@```.D` +M_O___R4.%1``:!\```#I\/W__P```````````````$%43(UG"%53BQ](8\.% +MVTB-;,<02(DM)140`'XX2(M7"$B%TG0O2(D5PQ`0``^V`H3`="%(_\(\+TB+ +M!;`0$`!(#T3"2(D%I1`0``^V`DC_PH3`=>*X0"%0`$B%P'0K2(GWZ#W___^_ +MZ!M``.@S____Z%K]__^)WTB)ZDR)YNBM"@``B!T['5D3$`!]%4B+%603$`!(8\/V1,)"!`^%O0(``$2+'3<3$`!%A=L/A3H$ +M``!(BS4W$Q``BT8,_\B%P(E&#`^(_`0``$B+!L8`34C_P$B)!D2+%003$`!% +MA=(/A3`$``!(BS4$$Q``BT8,_\B%P(E&#`^(!P4``$B+!L8`+4C_P$B)!H/C +M?X7;>!$['<\2$``/C#H"``!F9I!FD(L]NA(0`(7_#X5V`0``2(LUNQ(0`(M& +M#/_(A<")1@P/B/(!``!(BP8/MM.(&$C_P$B)!O_"#Y3`A,!U(XG=BS5\$A`` +MA?8/A+7^__],B>?H,/W__XG#@_O_#X7-_O__BPU;$A``APXLU=1(0`(7V=`R#^PH/A*P"``!%,?:+#5L2 +M$`"%R0^$8/[__XL521(0`(72#Y3"@_L*#Y7`",(/A$?^__](BSW;$1``0?_% +M,J^01Q``.BM^O__BP6S$1``A<`/A?`#``!(BP6T$1``#[]`$,'H!H/@ +M`83`#X4Q____@_L*#X4'_O__BP7C$1``A<`/A+O^__^+!741$`"%P`^%^@$` +M`$B+-781$`"+1@S_R(7`B48,#XC4`@``2(L&Q@`D2/_`2(D&BSU$$1``A?\/ +MA(K^__](BS5%$1``B=_H0OK____`#Y3`Z9S^__]F9F:0BP5F$1``A<`/A%+^ +M__^+!0P1$`"%P`^%R0$``$B+-0T1$`"+1@S_R(7`B48,#XB,`@``2(L&Q@!> +M2/_`2(D&BP7;$!``A<`/A;\!``!(BS7<$!``BT8,_\B%P(E&#`^(?`(``$B+ +M!HG=Q@!)2/_`2(D&Z2?^__\[1BA\"8#["@^%`/[__XG?Z+CZ__^)PF:0Z?[] +M__](BQ6<$!``2&/#]D3"00(/A+;]__]$BPUO$!``187)#X5K`@``2(LU;Q`0 +M`(M&#/_(A<")1@P/B`0#``!(BP;&`%Y(_\!(B09$BP4\$!``187`#X6&`0`` +M2(LU/!`0`(G8OS\```"#R$"#^W\/1?B+1@S_R(7`B48,#XAK`@``2(L&0`^V +MUT"(.$C_P$B)!O_"#X23_?__B=WI:_W__TR)Y^C)^?__A<`/E<"$P`^$F?W_ +M_TB+-2D0$``QP+]&'$``Z)GY__^+%;\/$`#'!040$``!````A=(/A8("``!F +M08-D)!"?BP6@#Q``A<`/A&?]__](BSVA#Q``Z'#Y__^%P`^5P.EB_?__3(GG +MZ`[Z__^)P^G6^___2(LU?`\0`+\D````Z';X____P`^4P(3`#X25_/__Z>_\ +M__]%A?8/A````Z'+X____P`^%9?W__^G@ +M^___D#M&*`^->_W__[])````9I#H3_C____`#X3"^___B=V0Z9G[__\[1B@/ +MC?OZ__^_30```.@L^/___\`/A?7Z___IFOO__TB+-00.$`"_7@```.C^]O__ +M_\`/A9_]___I?/O__SM&*`^-\/K__[\M````Z.[W____P`^%ZOK__V:0Z5K[ +M__](BSW$#1``9F9FD.B/]___A<`/E<#I!_S__SM&*'P*0(#_"@^%AOW__V:0 +MZ*_W__^)PNF(_?__1(L%?0T0`$6%P'5B#[]'$,'H!8/@`83`#X2.^?__BSU@ +M#1``A?]U6$B+!5T-$`!F@V`0G^ES^?__.T8H#XWS_/__OUX```#H7/?____` +M#X7M_/__Z=F9F:09F9FD.A/]O__Z=?Z__]F9I!F9I#H+_;__X7` +M#Y7`ZY9(BST%#1``Z"SV___I&_G__[Y)'$``OP$````QP.A&]___9I!!5T4Q +M_T%6055!5%532('LJ````$B-1"0@2(E\)!B)="042(/``DB)1"0(2(M$)!A. +MBS3X387V#X3L````_+]0'$``N0(```!,B?;SI@^%`@$``$C'!=H,$`!2'$`` +M13'M1(M4)!1%A=)T-T6%[0^$T````+Y='$``1(GOZ!/V__](B<-(B_HKO;_ +M_TB#^`!(B<,/CJT````Q[>L'2"G#=-0!Q4AC]4@#-0@,$`!(B=I$B>?HT?3_ +M_TB%P'G?ODD<0`"_`0```#'`Z!OV__]%A?\/A"'___](@<2H````6UU!7$%= +M05Y!7\-(BSV="Q``Z*#W___I/____S'V,(G_2(D]#PL0`.@F]?__2(7`2(D%^`H0``^%LO[__[Y8 +M'$``OP$```#H%_7__V9FD$B-?"0@,?:Z:@```.@C]/__,=*^`0```+\!```` +MZ/+S__^%P$&)Q0^()/___TB+?"0(NF@```!,B?;&1"0A`>A0]?__@_AG=C+H +M!O3__\<`/P```.GX_O__2(LUJ`H0`+]&'$``,<#H&/3__\<%B@H0``$```#I +M^_[__XU0`TB-="0@1(GOZ+GS__^%P'@^O@$```!$B>_H6//____`#X6-_?__ +M,?\QP.C7\___9F:0Z7S]__](BQ5,"A``OD8<0`"_`0```#'`Z$?T__]$B>_H +MG_/__^EW_O__9F:09F:058G]OP(```!32(GSOD4<0`!(@^P(Z"KT__]F9I!F +M9I"Z7QQ``$B)WHGOZ!7S__^#^/\/A+@```"#Z&*#^!1V)4B+#:D)$`"_:!Q` +M`+HA````O@$```#H:?/__[\!````Z*_S__^)P/\DQ9`<0`#'!:`)$``!```` +MZZ9(BSU?"1``,?;H?//__^N6QP6$"1```0```,<%?@D0``$```#K@,<%D@D0 +M``$```#IUUP8L=R`@0`(7;=;=$ +MBQVY"!``187;=:LQ]NB%^___ZZR+/:T($`#HG/+__Y"0D)"0D)"02(L%"0<0 +M`%-(@_C_=!4QV__02(N#R")0`$B#ZPA(@_C_=>U;PY"0D$B#[`CHO_/__TB# +MQ`C#```D1G)E94)31#H@'`@)``````!&___ +MD`(0```````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``!%'$``````````````````Z")0```````4``````````%Z4@`!>!`!`PP' +M")`!```<````'````!`/0`"2`````$(.$(P"10X800X@@P2&`Q0````\```` +ML`]``#@`````1`X0`````!0```!4````\`]``"(``````````````"P```!L +M````(!!```X'````0@X020X80@X@C`2-`XX"1`XH00XP@P:&!0```````#0` +M``"<````,!=```H#````0@X0CP)%#AA"#B!"#BA!#C!!#CA'#N`!@P>&!HP% +MC02.`P``````'````-0```!`&D``>`$```!!#A"&`D@.&(,#3`X@```````` +M&``````````!>E(``7@0`0,,!PB0`0```````!0````@````P!M``"4````` +M2`X0@P(```$`````````%0`````````,`````````.`,0```````#0`````` +M``#H&T````````0`````````^`%````````%`````````&@'0```````!@`` +M``````!(`T````````H`````````5`$````````+`````````!@````````` +M%0````````````````````,`````````^")0```````"```````````#```` +M````%``````````'`````````!<`````````X`E````````'`````````#@) +M0```````"`````````"H``````````D`````````&`````````#^__]O```` +M`!@)0```````____;P`````!`````````/#__V\`````O`A````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``#__________P``````````__________\`````````````````````0"%0 +M````````````````````````````"@U````````:#4```````"H-0``````` +M.@U```````!*#4```````%H-0```````:@U```````!Z#4```````(H-0``` +M````F@U```````"J#4```````+H-0```````R@U```````#:#4```````.H- +M0```````^@U````````*#D```````!H.0```````*@Y````````Z#D`````` +M`$H.0```````6@Y```````!J#D```````'H.0```````B@Y```````":#D`` +M`````*H.0```````N@Y```````#*#D```````-H.0```````Z@Y```````#Z +M#D`````````D1G)E94)31#H@6UT86(`+G-T6YS>6T`+F1Y;G-T<@`N9VYU+G9E +M6YA;6EC`"YC=&]R`````````````````````0`` +M``````````````````$````"`````````````````````````&`M```````` +M^`H````````;````.0````@`````````&``````````)`````P`````````` +M``````````````!8.````````+$$```````````````````!```````````` +M``````````````````````````````````````````````,``0#(`4`````` +M``````````````````,``@#@`4````````````````````````,``P#X`4`` +M``````````````````````,`!`!(`T````````````````````````,`!0!H +M!T````````````````````````,`!@"\"$````````````````````````,` +M!P`8"4````````````````````````,`"``X"4`````````````````````` +M``,`"0#@"4````````````````````````,`"@#@#$`````````````````` +M``````,`"P#T#$````````````````````````,`#``0#T`````````````` +M``````````,`#0#H&T````````````````````````,`#@#X&T`````````` +M``````````````,`#P"$'4````````````````````````,`$```(%`````` +M``````````````````,`$0`8(%````````````````````````,`$@!`(5`` +M``````````````````````,`$P#0(E````````````````````````,`%`#@ +M(E````````````````````````,`%0#P(E````````````````````````,` +M%@#X(E````````````````````````,`%P`0)%`````````````````````` +M``,`&`````````````````````````````,`&0`````````````````````` +M``````,`&@````````````````````````````,`&P`````````````````` +M`````0````0`\?\`````````````````````"`````$``@#@`4```````!@` +M````````#P````0`\?\`````````````````````+0````0`\?\````````` +M````````````/`````0`\?\`````````````````````#P````0`\?\````` +M````````````````1P````0`\?\`````````````````````4@````$`$P#0 +M(E``````````````````8`````$`%`#@(E``````````````````;@````$` +M%0#P(E``````````````````>P````(`#`"P#T``````````````````D0`` +M``$`%P`\)%````````$`````````H`````$`$``0(%`````````````````` +MIP````(`#`#P#T``````````````````1P````0`\?\````````````````` +M````LP````$`$P#8(E``````````````````P`````$`%`#H(E`````````` +M````````S0````$`$0`((5``````````````````VP````$`%0#P(E`````` +M````````````YP````(`#`#`&T``````````````````_0````0`\?\````` +M````````````````+0````0`\?\`````````````````````/`````0`\?\` +M````````````````````_0````0`\?\`````````````````````&P$```0` +M\?\`````````````````````(0$```(`#``@$$````````X'````````*@$` +M``(`#``P%T````````H#````````-`$```$`%P!`)%````````@````````` +M/0$```$`%P!()%````````@`````````2`$``!(````$#4```````)`````` +M````6@$``!(````4#4``````````````````:@$``!$`%P!8)%````````0` +M````````<`$``!$`$@!`(5``````````````````>0$``!(````D#4`````` +M`)D`````````B`$``!(````T#4```````&4`````````EP$``!$`%P!<)%`` +M``````0`````````G0$``!$"$``((%``````````````````J@$``!(```!$ +M#4```````%H`````````O0$``!(```!4#4``````````````````T`$``!(` +M``!D#4````````(`````````Y`$``!(`"@#@#$``````````````````Z@$` +M`!$`%P!@)%````````0`````````[P$``!$`%P!H)%````````@````````` +M^`$``!$`%P!0)%````````@```````````(``!$`%P!P)%````````0````` +M````!@(``!$`%P!T)%````````0`````````#`(``!(```!T#4`````````` +M````````'0(``!$`%P`0)%````````0`````````-`(``!(```"$#4`````` +M`*H"````````10(``!$`$```(%````````@`````````4`(``!(`#``0#T`` +M`````)(`````````5P(``!(```"4#4``````````````````:`(``!$`%P!X +M)%````````0`````````;@(``!(```"D#4``````````````````@`(``!(` +M``"T#4````````@`````````D@(``!(```#$#4```````!(!````````HP(` +M`!``\?\0)%``````````````````KP(``!(```#4#4`````````````````` +MOP(``!(`#`!`&D```````'@!````````Q`(``!(```#D#4```````*@````` +M````TP(``!$`%P`4)%````````0`````````ZP(``!$`%P`8)%````````@` +M````````_@(``!(```#T#4```````&4`````````#P,``!(`#0#H&T`````` +M````````````%0,``!$`%P`@)%````````@`````````*0,``!(````$#D`` +M`````,H`````````.@,``!(````4#D``````````````````20,``!$`%P`H +M)%````````@`````````9@,``!(````D#D```````%L`````````=P,``!(` +M```T#D```````,,`````````B0,``!(```!$#D```````!,`````````F@,` +M`!(```!4#D```````"\`````````J0,``!(```!D#D`````````%```````` +MN@,``!(```!T#D```````*H`````````R`,``!``\?\0)%`````````````` +M````SP,``!$`%@#X(E``````````````````Y0,``!``\?^`)%`````````` +M````````Z@,``!(```"$#D```````&H#````````_@,``!(```"4#D`````` +M`/(`````````#P0``!$`%P`P)%````````@`````````(P0``!$`%P`X)%`` +M``````0`````````-`0``!(```"D#D```````"4`````````1@0``!(```"T +M#D```````"\`````````5P0``!$`%P!\)%````````0`````````700``!(` +M``#$#D``````````````````;`0``"``````````````````````````@`0` +M`!(```#4#D```````'\`````````CP0``!(```#D#D`````````````````` +MGP0``!(```#T#D```````#8``````````&-R=#$N8P!A8FET86<`+W5S0!?7T-43U)?14Y$7U\`7U]$5$]27T5. +M1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G;&]B86Q?8W1O +M8+$`!H"````.E@_____R7>"Q``:`D```#I4/____\E +MU@L0`&@*````Z4#_____)#&1>\!2,=%\`````#K +M+4B+=>!(BWVPZ&O^__\/MA!(BT7P2`-%P`^V`#C"#Y3`B$7O2(-MX`%(@T7P +M`4B+1?!(.T78\`=!(BWVPZ"S^__\/MA!(BT782`-%P`^V +M`#C"#Y3`B$7O2(-MX`%(@WW@`'0&@'WO`'7+2(M%V$@#1<`/M@"$P'XR#[9= +M[TB+?;"^`````.CC_?__#[802(M%V$@#1<`/M@`XP@^>P`^VP"'8A<`/E<"( +M1>\/MD7O2(/$2%O)PV9F9I!52(GE2(/L$(E]_(EU^(-]_`%U)X%]^/__``!U +M'K\4%5``Z-W\__^Z"!!0`+X`````O]`*0`#HV?S__\G#D&:054B)Y;[__P`` +MOP$```#HK?___\G#D&9F9I!F9I!F9I!52(GE2(/L$$B)??B_%!50`.@N_?__ +MR<-F9F:09F9FD%5(B>5(@^P@QT7T"@```$BX\6CCB+7XY#Y(B47XZ:<```#R +M#Q!-^/(/$`61`0``\@]9P>B<_/__9@\HR/(/$`6$`0``9@\HT?(/6=#R#Q%5 +MX/(/$$WX\@\0!7(!``!F#RC1\@]>T&8/*,+H9?S___(/$$W@\@]>R/(/$4WH +M\@\01?B_`!10`.@H_/__2(G'OB````#H2_S__TB)Q_(/$$7HZ`[\__](B<>^ +M"@```.@Q_/__\@\03?CR#Q`%^````/(/6,'R#Q%%^/(/$$WX\@\0!0(!``!F +M#R[!#X="____N`````#)PY"0D)"0D)"0D%5(B>5(B7WX2(EU\$B+1?!(BQ!( +MBT7X2(L`2#G"A(BT7HR<.0D)"0D)"0D)!( +MBP4Y!Q``4TB#^/]T%3';_]!(BX-8$U``2(/K"$B#^/]U[5O#D)"02(/L".B/ +M_/__2(/$",,````D1G)E94)31#H@'`@)``````!&___^`(0```````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`%@,0`````````````````!X$U```````!0``````````7I2``%X$`$##`<( +MD`$``!P````<````0`A``)(`````0@X0C`)%#AA!#B"#!(8#%````#P```#@ +M"$``.`````!$#A``````%````%0````@"4``(@``````````````'``````` +M```!>E!2``%X$`8#!`A```,,!PB0`0`````<````)````.`+0``W`````$$. +M$(8"0PT&`````````!P```!$````4`E``!P!````00X0A@)##09%@P,````` +M'````&0```!P"D``/0````!!#A"&`D,-!@`````````<````A````+`*0``5 +M`````$$.$(8"0PT&`````````!P```"D````T`I``!@`````00X0A@)##08` +M````````'````,0```#P"D``YP````!!#A"&`D,-!@``````````````&``` +M```````!>E(``7@0`0,,!PB0`0```````!0````@````(`Q``"4`````2`X0 +M@P(```$``````````0`````````!`````````,P``````````0````````#: +M``````````$`````````Z``````````,`````````%`'0```````#0`````` +M``!(#$````````0`````````^`%````````%`````````$`$0```````!@`` +M``````"0`D````````H`````````00$````````+`````````!@````````` +M%0````````````````````,`````````B!-0```````"`````````"`!```` +M````%``````````'`````````!<`````````,`9````````'`````````!@& +M0```````"``````````8``````````D`````````&`````````#^__]O```` +M`*@%0```````____;P`````#`````````/#__V\`````@@5````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``#__________[`*0`````````````````#__________P`````````````` +M``````"8$5````````````````````````````!Z!T```````(H'0``````` +MF@=```````"J!T```````+H'0```````R@=```````#:!T```````.H'0``` +M````^@=````````*"$```````!H(0```````*@A`````````)$9R965"4T0Z +M('-R8R]L:6(O8W-U+V-O;6UO;B]C6X`+G)E;&$N +M<&QT`"YI;FET`"YT97AT`"YF:6YI`"YR;V1A=&$`+F5H7V9R86UE7VAD<@`N +M9&%T80`N96A?9G)A;64`+F1Y;F%M:6,`+F-T;W)S`"YD=&]R```````````` +M`````````0````````````````````$````"```````````````````````` +M`!`=````````^`<````````;````.@````@`````````&``````````)```` +M`P`````````````````````````()0```````)D#```````````````````! +M``````````````````````````````````````````````````````````,` +M`0#(`4````````````````````````,``@#@`4`````````````````````` +M``,``P#X`4````````````````````````,`!`"0`D`````````````````` +M``````,`!0!`!$````````````````````````,`!@""!4`````````````` +M``````````,`!P"H!4````````````````````````,`"``8!D`````````` +M``````````````,`"0`P!D````````````````````````,`"@!0!T`````` +M``````````````````,`"P!D!T````````````````````````,`#`!`"$`` +M``````````````````````,`#0!(#$````````````````````````,`#@!8 +M#$````````````````````````,`#P`<#4````````````````````````,` +M$```$%````````````````````````,`$0`8$%`````````````````````` +M``,`$@"8$5````````````````````````,`$P!8$U`````````````````` +M``````,`%`!P$U````````````````````````,`%0"`$U`````````````` +M``````````,`%@"($U````````````````````````,`%P``%%`````````` +M``````````````,`&`````````````````````````````,`&0`````````` +M``````````````````,`&@````````````````````````````,`&P`````` +M`````````````````0````0`\?\`````````````````````"`````$``@#@ +M`4```````!@`````````#P````0`\?\`````````````````````+0````0` +M\?\`````````````````````/`````0`\?\`````````````````````#P`` +M``0`\?\`````````````````````1P````0`\?\````````````````````` +M4@````$`$P!8$U``````````````````8`````$`%`!P$U`````````````` +M````;@````$`%0"`$U``````````````````>P````(`#`#@"$`````````` +M````````D0````$`%P`0%5````````$`````````H`````$`$``0$%`````` +M````````````IP````(`#``@"4``````````````````1P````0`\?\````` +M````````````````LP````$`$P!H$U``````````````````P`````$`%`!X +M$U``````````````````S0````$`$0!@$5``````````````````VP````$` +M%0"`$U``````````````````YP````(`#``@#$``````````````````_0`` +M``0`\?\`````````````````````+0````0`\?\````````````````````` +M/`````0`\?\`````````````````````_0````0`\?\````````````````` +M````&P$```0`\?\`````````````````````(@$```(`#`"P"D```````!4` +M````````,@$```(`#`!0"4```````!P!````````4@$```(`#`!P"D`````` +M`#T`````````@@$```$`%P`4%5````````$`````````D`$```(`#`#0"D`` +M`````!@`````````F`$``!(```!T!T```````&0(````````O0$``!$`%P`` +M%%```````!`!````````U`$``!$`$@"8$5``````````````````W0$``!(` +M``"$!T```````"<`````````]`$``!$"$``($%```````````````````0(` +M`!(```"4!T````````(`````````%0(``!(`"@!0!T`````````````````` +M&P(``!$`%P`8%5````````@`````````(P(``!(```"D!T````````4````` +M````.@(``!$`$```$%````````@`````````10(``!(`#`!`"$```````)(` +M````````3`(``"(`#`#@"T```````#<`````````8@(``!``\?\`%%`````` +M````````````;@(``!(`#`#P"D```````.<`````````0!?7T-43U)?14Y$7U\`7U]$ +M5$]27T5.1%]?`%]?1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G;&]B +M86Q?8W1O&%?871E>&ET0$!&0E-$7S$N,`!?7V1S;U]H86YD +M;&4`7VEN:71?=&QS0$!&0E-$7S$N,`!?:6YI=`!E;G9IF5%=D!`1TQ) +M0D-86%\S+C0`%]P97)S;VYA;&ET>5]V,$!`0UA804))7S$N,P!?6DY3=#AI;W-? +M8F%S931);FET1#%%=D!`1TQ)0D-86%\S+C0`7UI.2U-S:7A%;4!`1TQ)0D-8 +&6%\S+C0` +` +end diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_option/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/nm_option/Makefile new file mode 100644 index 0000000000..715c5299f3 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_option/Makefile @@ -0,0 +1,5 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_option/tc.sh b/contrib/elftoolchain/tests/tet/nm/ts/nm_option/tc.sh new file mode 100755 index 0000000000..889179004a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_option/tc.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# +# $Id: tc.sh 3966 2022-04-22 17:02:17Z jkoshy $ + +tp1() +{ + run_without_diff "-z" $ERROR_USAGE +} + +tp2() +{ + run_without_diff "-Z" $ERROR_USAGE +} + +tp3() +{ + run_without_diff "-y" $ERROR_USAGE +} + +tp4() +{ + run_without_diff "-Y" $ERROR_USAGE +} + +tp5() +{ + run_without_diff "--aaaaaa" $ERROR_USAGE +} + +tp6() +{ + run_without_diff "--+_" $ERROR_USAGE +} + +tp7() +{ + run_without_diff "--help" $ERROR_OK +} + +ERROR_OK="0" +ERROR_USAGE="64" + +tet_startup="" +tet_cleanup="" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/Makefile new file mode 100644 index 0000000000..d65aeea4f6 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ + +TOP= ../../../../.. + +TS_DATA= test_so + +.include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/tc.sh b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/tc.sh new file mode 100755 index 0000000000..07ae40ee9c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/tc.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# +# $Id: tc.sh 2378 2012-01-03 08:59:56Z jkoshy $ + +tp1() +{ + test_format_bsd1 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp2() +{ + test_format_bsd2 $TEST_FILE "$TEST_FILE-format-bsd.txt" +} + +tp3() +{ + test_dynamic1 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp4() +{ + test_dynamic2 $TEST_FILE "$TEST_FILE-dynamic.txt" +} + +tp5() +{ + test_external $TEST_FILE "$TEST_FILE-external.txt" +} + +tp6() +{ + test_hexa1 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp7() +{ + test_hexa2 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp8() +{ + test_hexa3 $TEST_FILE "$TEST_FILE-radix-hexa.txt" +} + +tp9() +{ + test_no_sort1 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp10() +{ + test_no_sort2 $TEST_FILE "$TEST_FILE-sort-no.txt" +} + +tp11() +{ + test_num_sort1 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp12() +{ + test_num_sort2 $TEST_FILE "$TEST_FILE-sort-num.txt" +} + +tp14() +{ + test_octal2 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp15() +{ + test_octal3 $TEST_FILE "$TEST_FILE-radix-octal.txt" +} + +tp16() +{ + test_posix1 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp17() +{ + test_posix2 $TEST_FILE "$TEST_FILE-format-posix.txt" +} + +tp18() +{ + test_print_file_name1 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp19() +{ + test_print_file_name2 $TEST_FILE "$TEST_FILE-print-file-name.txt" +} + +tp20() +{ + test_print_size1 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp21() +{ + test_print_size2 $TEST_FILE "$TEST_FILE-print-size.txt" +} + +tp22() +{ + test_reverse_sort1 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp23() +{ + test_reverse_sort2 $TEST_FILE "$TEST_FILE-sort-reverse.txt" +} + +tp24() +{ + test_reverse_sort_num $TEST_FILE "$TEST_FILE-sort-reverse-num.txt" +} + +tp25() +{ + test_reverse_sort_no $TEST_FILE "$TEST_FILE-sort-reverse-no.txt" +} + +tp26() +{ + test_reverse_sort_size $TEST_FILE "$TEST_FILE-sort-reverse-size.txt" +} + +tp27() +{ + test_size_sort $TEST_FILE "$TEST_FILE-sort-size.txt" +} + +tp28() +{ + test_sysv $TEST_FILE "$TEST_FILE-format-sysv.txt" +} + +tp29() +{ + test_undef1 $TEST_FILE "$TEST_FILE-undef.txt" +} + +tp30() +{ + test_undef2 $TEST_FILE "$TEST_FILE-undef.txt" +} + +startup() +{ + uudecode "$TEST_FILE.uu" +} + +cleanup() +{ + rm -f $TEST_FILE +} + +TEST_FILE="test_so" + +tet_startup="startup" +tet_cleanup="cleanup" + +iclist="ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 ic9 ic10 ic11 ic12 ic14 ic15 ic16 ic17 ic18 ic19 ic20 ic21 ic22 ic23 ic24 ic25 ic26 ic27 ic28 ic29 ic30" + +ic1="tp1" +ic2="tp2" +ic3="tp3" +ic4="tp4" +ic5="tp5" +ic6="tp6" +ic7="tp7" +ic8="tp8" +ic9="tp9" +ic10="tp10" +ic11="tp11" +ic12="tp12" +ic14="tp14" +ic15="tp15" +ic16="tp16" +ic17="tp17" +ic18="tp18" +ic19="tp19" +ic20="tp20" +ic21="tp21" +ic22="tp22" +ic23="tp23" +ic24="tp24" +ic25="tp25" +ic26="tp26" +ic27="tp27" +ic28="tp28" +ic29="tp29" +ic30="tp30" + +. $TET_SUITE_ROOT/ts/common/func.sh +. $TET_ROOT/lib/xpg3sh/tcm.sh diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-dynamic.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-dynamic.txt new file mode 100644 index 0000000000..c6db3b9fe7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-dynamic.txt @@ -0,0 +1,38 @@ +0000000001057328 A _DYNAMIC +0000000001057768 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000001057992 A __bss_start + w __cxa_finalize + U __error +0000000001057992 A _edata +0000000001058000 A _end +0000000000007112 T _fini +0000000000003320 T _init +0000000000006160 T berase +0000000000006704 T bread +0000000000006304 T bwrite +0000000000004720 T cgread +0000000000004544 T cgread1 +0000000000004400 T cgwrite1 + U close + U free + U getfsfile +0000000000003856 T getino + U ioctl + U malloc + U memcpy + U memset + U open + U pread + U pwrite +0000000000005856 T sbread +0000000000005584 T sbwrite + U snprintf + U stat + U statfs + U strdup + U strlcpy +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout +0000000000004864 T ufs_disk_fillout_blank +0000000000004752 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-external.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-external.txt new file mode 100644 index 0000000000..6c20fec3d7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-external.txt @@ -0,0 +1,38 @@ +0000000001057328 A _DYNAMIC +0000000001057768 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000001057992 A __bss_start + w __cxa_finalize@@FBSD_1.0 + U __error@@FBSD_1.0 +0000000001057992 A _edata +0000000001058000 A _end +0000000000007112 T _fini +0000000000003320 T _init +0000000000006160 T berase +0000000000006704 T bread +0000000000006304 T bwrite +0000000000004720 T cgread +0000000000004544 T cgread1 +0000000000004400 T cgwrite1 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000003856 T getino + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 +0000000000005856 T sbread +0000000000005584 T sbwrite + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout +0000000000004864 T ufs_disk_fillout_blank +0000000000004752 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-bsd.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-bsd.txt new file mode 100644 index 0000000000..6ac646fff7 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-bsd.txt @@ -0,0 +1,39 @@ +0000000001057328 A _DYNAMIC +0000000001057768 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000001057992 A __bss_start + w __cxa_finalize@@FBSD_1.0 +0000000001056768 d __dso_handle + U __error@@FBSD_1.0 +0000000001057992 A _edata +0000000001058000 A _end +0000000000007112 T _fini +0000000000003320 T _init +0000000000006160 T berase +0000000000006704 T bread +0000000000006304 T bwrite +0000000000004720 T cgread +0000000000004544 T cgread1 +0000000000004400 T cgwrite1 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000003856 T getino + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 +0000000000005856 T sbread +0000000000005584 T sbwrite + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout +0000000000004864 T ufs_disk_fillout_blank +0000000000004752 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-posix.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-posix.txt new file mode 100644 index 0000000000..3d6b4916bb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-posix.txt @@ -0,0 +1,39 @@ +_DYNAMIC A 0000000000102230 +_GLOBAL_OFFSET_TABLE_ A 00000000001023e8 +_Jv_RegisterClasses w +__bss_start A 00000000001024c8 +__cxa_finalize@@FBSD_1.0 w +__dso_handle d 0000000000102000 +__error@@FBSD_1.0 U +_edata A 00000000001024c8 +_end A 00000000001024d0 +_fini T 0000000000001bc8 +_init T 0000000000000cf8 +berase T 0000000000001810 0000000000000082 +bread T 0000000000001a30 0000000000000161 +bwrite T 00000000000018a0 0000000000000184 +cgread T 0000000000001270 0000000000000014 +cgread1 T 00000000000011c0 00000000000000b0 +cgwrite1 T 0000000000001130 0000000000000090 +close@@FBSD_1.0 U +free@@FBSD_1.0 U +getfsfile@@FBSD_1.0 U +getino T 0000000000000f10 0000000000000219 +ioctl@@FBSD_1.0 U +malloc@@FBSD_1.0 U +memcpy@@FBSD_1.0 U +memset@@FBSD_1.0 U +open@@FBSD_1.0 U +pread@@FBSD_1.0 U +pwrite@@FBSD_1.0 U +sbread T 00000000000016e0 0000000000000129 +sbwrite T 00000000000015d0 0000000000000107 +snprintf@@FBSD_1.0 U +stat@@FBSD_1.0 U +statfs@@FBSD_1.0 U +strdup@@FBSD_1.0 U +strlcpy@@FBSD_1.0 U +ufs_disk_close T 0000000000001580 000000000000004e +ufs_disk_fillout T 0000000000001530 0000000000000044 +ufs_disk_fillout_blank T 0000000000001300 0000000000000227 +ufs_disk_write T 0000000000001290 0000000000000069 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-sysv.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-sysv.txt new file mode 100644 index 0000000000..e60a7a400f --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-format-sysv.txt @@ -0,0 +1,45 @@ + + +Symbols from test_so: + +Name Value Class Type Size Line Section + +_DYNAMIC |0000000001057328| A | OBJECT| | |*ABS* +_GLOBAL_OFFSET_TABLE_|0000000001057768| A | OBJECT| | |*ABS* +_Jv_RegisterClasses | | w | NOTYPE| | |*UND* +__bss_start |0000000001057992| A | NOTYPE| | |*ABS* +__cxa_finalize@@FBSD_1.0| | w | FUNC|0000000000000301| |*UND* +__dso_handle |0000000001056768| d | OBJECT| | |.data +__error@@FBSD_1.0 | | U | FUNC|0000000000000008| |*UND* +_edata |0000000001057992| A | NOTYPE| | |*ABS* +_end |0000000001058000| A | NOTYPE| | |*ABS* +_fini |0000000000007112| T | FUNC| | |.fini +_init |0000000000003320| T | FUNC| | |.init +berase |0000000000006160| T | FUNC|0000000000000130| |.text +bread |0000000000006704| T | FUNC|0000000000000353| |.text +bwrite |0000000000006304| T | FUNC|0000000000000388| |.text +cgread |0000000000004720| T | FUNC|0000000000000020| |.text +cgread1 |0000000000004544| T | FUNC|0000000000000176| |.text +cgwrite1 |0000000000004400| T | FUNC|0000000000000144| |.text +close@@FBSD_1.0 | | U | FUNC| | |*UND* +free@@FBSD_1.0 | | U | FUNC|0000000000000750| |*UND* +getfsfile@@FBSD_1.0 | | U | FUNC|0000000000000054| |*UND* +getino |0000000000003856| T | FUNC|0000000000000537| |.text +ioctl@@FBSD_1.0 | | U | FUNC| | |*UND* +malloc@@FBSD_1.0 | | U | FUNC|0000000000001280| |*UND* +memcpy@@FBSD_1.0 | | U | FUNC| | |*UND* +memset@@FBSD_1.0 | | U | FUNC| | |*UND* +open@@FBSD_1.0 | | U | FUNC| | |*UND* +pread@@FBSD_1.0 | | U | FUNC|0000000000000139| |*UND* +pwrite@@FBSD_1.0 | | U | FUNC|0000000000000139| |*UND* +sbread |0000000000005856| T | FUNC|0000000000000297| |.text +sbwrite |0000000000005584| T | FUNC|0000000000000263| |.text +snprintf@@FBSD_1.0 | | U | FUNC|0000000000000453| |*UND* +stat@@FBSD_1.0 | | U | FUNC| | |*UND* +statfs@@FBSD_1.0 | | U | FUNC| | |*UND* +strdup@@FBSD_1.0 | | U | FUNC|0000000000000085| |*UND* +strlcpy@@FBSD_1.0 | | U | FUNC|0000000000000054| |*UND* +ufs_disk_close |0000000000005504| T | FUNC|0000000000000078| |.text +ufs_disk_fillout |0000000000005424| T | FUNC|0000000000000068| |.text +ufs_disk_fillout_blank|0000000000004864| T | FUNC|0000000000000551| |.text +ufs_disk_write |0000000000004752| T | FUNC|0000000000000105| |.text diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-file-name.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-file-name.txt new file mode 100644 index 0000000000..050ae3c036 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-file-name.txt @@ -0,0 +1,39 @@ +test_so:0000000001057328 A _DYNAMIC +test_so:0000000001057768 A _GLOBAL_OFFSET_TABLE_ +test_so: w _Jv_RegisterClasses +test_so:0000000001057992 A __bss_start +test_so: w __cxa_finalize@@FBSD_1.0 +test_so:0000000001056768 d __dso_handle +test_so: U __error@@FBSD_1.0 +test_so:0000000001057992 A _edata +test_so:0000000001058000 A _end +test_so:0000000000007112 T _fini +test_so:0000000000003320 T _init +test_so:0000000000006160 T berase +test_so:0000000000006704 T bread +test_so:0000000000006304 T bwrite +test_so:0000000000004720 T cgread +test_so:0000000000004544 T cgread1 +test_so:0000000000004400 T cgwrite1 +test_so: U close@@FBSD_1.0 +test_so: U free@@FBSD_1.0 +test_so: U getfsfile@@FBSD_1.0 +test_so:0000000000003856 T getino +test_so: U ioctl@@FBSD_1.0 +test_so: U malloc@@FBSD_1.0 +test_so: U memcpy@@FBSD_1.0 +test_so: U memset@@FBSD_1.0 +test_so: U open@@FBSD_1.0 +test_so: U pread@@FBSD_1.0 +test_so: U pwrite@@FBSD_1.0 +test_so:0000000000005856 T sbread +test_so:0000000000005584 T sbwrite +test_so: U snprintf@@FBSD_1.0 +test_so: U stat@@FBSD_1.0 +test_so: U statfs@@FBSD_1.0 +test_so: U strdup@@FBSD_1.0 +test_so: U strlcpy@@FBSD_1.0 +test_so:0000000000005504 T ufs_disk_close +test_so:0000000000005424 T ufs_disk_fillout +test_so:0000000000004864 T ufs_disk_fillout_blank +test_so:0000000000004752 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-size.txt new file mode 100644 index 0000000000..33e8e9c396 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-print-size.txt @@ -0,0 +1,39 @@ +0000000001057328 A _DYNAMIC +0000000001057768 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000001057992 A __bss_start + w __cxa_finalize@@FBSD_1.0 +0000000001056768 d __dso_handle + U __error@@FBSD_1.0 +0000000001057992 A _edata +0000000001058000 A _end +0000000000007112 T _fini +0000000000003320 T _init +0000000000006160 0000000000000130 T berase +0000000000006704 0000000000000353 T bread +0000000000006304 0000000000000388 T bwrite +0000000000004720 0000000000000020 T cgread +0000000000004544 0000000000000176 T cgread1 +0000000000004400 0000000000000144 T cgwrite1 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000003856 0000000000000537 T getino + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 +0000000000005856 0000000000000297 T sbread +0000000000005584 0000000000000263 T sbwrite + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000005504 0000000000000078 T ufs_disk_close +0000000000005424 0000000000000068 T ufs_disk_fillout +0000000000004864 0000000000000551 T ufs_disk_fillout_blank +0000000000004752 0000000000000105 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-hexa.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-hexa.txt new file mode 100644 index 0000000000..d917b0c759 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-hexa.txt @@ -0,0 +1,39 @@ +0000000000102230 A _DYNAMIC +00000000001023e8 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +00000000001024c8 A __bss_start + w __cxa_finalize@@FBSD_1.0 +0000000000102000 d __dso_handle + U __error@@FBSD_1.0 +00000000001024c8 A _edata +00000000001024d0 A _end +0000000000001bc8 T _fini +0000000000000cf8 T _init +0000000000001810 T berase +0000000000001a30 T bread +00000000000018a0 T bwrite +0000000000001270 T cgread +00000000000011c0 T cgread1 +0000000000001130 T cgwrite1 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000000f10 T getino + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 +00000000000016e0 T sbread +00000000000015d0 T sbwrite + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000001580 T ufs_disk_close +0000000000001530 T ufs_disk_fillout +0000000000001300 T ufs_disk_fillout_blank +0000000000001290 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-octal.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-octal.txt new file mode 100644 index 0000000000..1365b23d0c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-radix-octal.txt @@ -0,0 +1,39 @@ +0000000004021060 A _DYNAMIC +0000000004021750 A _GLOBAL_OFFSET_TABLE_ + w _Jv_RegisterClasses +0000000004022310 A __bss_start + w __cxa_finalize@@FBSD_1.0 +0000000004020000 d __dso_handle + U __error@@FBSD_1.0 +0000000004022310 A _edata +0000000004022320 A _end +0000000000015710 T _fini +0000000000006370 T _init +0000000000014020 T berase +0000000000015060 T bread +0000000000014240 T bwrite +0000000000011160 T cgread +0000000000010700 T cgread1 +0000000000010460 T cgwrite1 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000007420 T getino + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 +0000000000013340 T sbread +0000000000012720 T sbwrite + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000012600 T ufs_disk_close +0000000000012460 T ufs_disk_fillout +0000000000011400 T ufs_disk_fillout_blank +0000000000011220 T ufs_disk_write diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-no.txt new file mode 100644 index 0000000000..ffbf676cef --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-no.txt @@ -0,0 +1,39 @@ +0000000001056768 d __dso_handle + U pread@@FBSD_1.0 + U statfs@@FBSD_1.0 +0000000000004720 T cgread +0000000001057328 A _DYNAMIC +0000000000004400 T cgwrite1 + U strdup@@FBSD_1.0 + w __cxa_finalize@@FBSD_1.0 +0000000000004864 T ufs_disk_fillout_blank +0000000000006160 T berase + U ioctl@@FBSD_1.0 +0000000000005584 T sbwrite +0000000000003320 T _init + U pwrite@@FBSD_1.0 + U stat@@FBSD_1.0 + U memset@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000004544 T cgread1 + U __error@@FBSD_1.0 +0000000000003856 T getino +0000000000004752 T ufs_disk_write +0000000001057992 A __bss_start + U close@@FBSD_1.0 + U snprintf@@FBSD_1.0 +0000000000007112 T _fini + U open@@FBSD_1.0 +0000000000006704 T bread + U malloc@@FBSD_1.0 +0000000001057992 A _edata + U memcpy@@FBSD_1.0 +0000000001057768 A _GLOBAL_OFFSET_TABLE_ +0000000001058000 A _end + U free@@FBSD_1.0 +0000000000006304 T bwrite +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout + w _Jv_RegisterClasses +0000000000005856 T sbread + U strlcpy@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-num.txt new file mode 100644 index 0000000000..91eeefadac --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-num.txt @@ -0,0 +1,39 @@ + w _Jv_RegisterClasses + w __cxa_finalize@@FBSD_1.0 + U __error@@FBSD_1.0 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 +0000000000003320 T _init +0000000000003856 T getino +0000000000004400 T cgwrite1 +0000000000004544 T cgread1 +0000000000004720 T cgread +0000000000004752 T ufs_disk_write +0000000000004864 T ufs_disk_fillout_blank +0000000000005424 T ufs_disk_fillout +0000000000005504 T ufs_disk_close +0000000000005584 T sbwrite +0000000000005856 T sbread +0000000000006160 T berase +0000000000006304 T bwrite +0000000000006704 T bread +0000000000007112 T _fini +0000000001056768 d __dso_handle +0000000001057328 A _DYNAMIC +0000000001057768 A _GLOBAL_OFFSET_TABLE_ +0000000001057992 A __bss_start +0000000001057992 A _edata +0000000001058000 A _end diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-no.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-no.txt new file mode 100644 index 0000000000..ffbf676cef --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-no.txt @@ -0,0 +1,39 @@ +0000000001056768 d __dso_handle + U pread@@FBSD_1.0 + U statfs@@FBSD_1.0 +0000000000004720 T cgread +0000000001057328 A _DYNAMIC +0000000000004400 T cgwrite1 + U strdup@@FBSD_1.0 + w __cxa_finalize@@FBSD_1.0 +0000000000004864 T ufs_disk_fillout_blank +0000000000006160 T berase + U ioctl@@FBSD_1.0 +0000000000005584 T sbwrite +0000000000003320 T _init + U pwrite@@FBSD_1.0 + U stat@@FBSD_1.0 + U memset@@FBSD_1.0 + U getfsfile@@FBSD_1.0 +0000000000004544 T cgread1 + U __error@@FBSD_1.0 +0000000000003856 T getino +0000000000004752 T ufs_disk_write +0000000001057992 A __bss_start + U close@@FBSD_1.0 + U snprintf@@FBSD_1.0 +0000000000007112 T _fini + U open@@FBSD_1.0 +0000000000006704 T bread + U malloc@@FBSD_1.0 +0000000001057992 A _edata + U memcpy@@FBSD_1.0 +0000000001057768 A _GLOBAL_OFFSET_TABLE_ +0000000001058000 A _end + U free@@FBSD_1.0 +0000000000006304 T bwrite +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout + w _Jv_RegisterClasses +0000000000005856 T sbread + U strlcpy@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-num.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-num.txt new file mode 100644 index 0000000000..0200111134 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-num.txt @@ -0,0 +1,39 @@ +0000000001058000 A _end +0000000001057992 A _edata +0000000001057992 A __bss_start +0000000001057768 A _GLOBAL_OFFSET_TABLE_ +0000000001057328 A _DYNAMIC +0000000001056768 d __dso_handle +0000000000007112 T _fini +0000000000006704 T bread +0000000000006304 T bwrite +0000000000006160 T berase +0000000000005856 T sbread +0000000000005584 T sbwrite +0000000000005504 T ufs_disk_close +0000000000005424 T ufs_disk_fillout +0000000000004864 T ufs_disk_fillout_blank +0000000000004752 T ufs_disk_write +0000000000004720 T cgread +0000000000004544 T cgread1 +0000000000004400 T cgwrite1 +0000000000003856 T getino +0000000000003320 T _init + U strlcpy@@FBSD_1.0 + U strdup@@FBSD_1.0 + U statfs@@FBSD_1.0 + U stat@@FBSD_1.0 + U snprintf@@FBSD_1.0 + U pwrite@@FBSD_1.0 + U pread@@FBSD_1.0 + U open@@FBSD_1.0 + U memset@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U malloc@@FBSD_1.0 + U ioctl@@FBSD_1.0 + U getfsfile@@FBSD_1.0 + U free@@FBSD_1.0 + U close@@FBSD_1.0 + U __error@@FBSD_1.0 + w __cxa_finalize@@FBSD_1.0 + w _Jv_RegisterClasses diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-size.txt new file mode 100644 index 0000000000..0a2edf72bb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse-size.txt @@ -0,0 +1,13 @@ +0000000000000551 T ufs_disk_fillout_blank +0000000000000537 T getino +0000000000000388 T bwrite +0000000000000353 T bread +0000000000000297 T sbread +0000000000000263 T sbwrite +0000000000000176 T cgread1 +0000000000000144 T cgwrite1 +0000000000000130 T berase +0000000000000105 T ufs_disk_write +0000000000000078 T ufs_disk_close +0000000000000068 T ufs_disk_fillout +0000000000000020 T cgread diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse.txt new file mode 100644 index 0000000000..c161cdbe72 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-reverse.txt @@ -0,0 +1,39 @@ +0000000000004752 T ufs_disk_write +0000000000004864 T ufs_disk_fillout_blank +0000000000005424 T ufs_disk_fillout +0000000000005504 T ufs_disk_close + U strlcpy@@FBSD_1.0 + U strdup@@FBSD_1.0 + U statfs@@FBSD_1.0 + U stat@@FBSD_1.0 + U snprintf@@FBSD_1.0 +0000000000005584 T sbwrite +0000000000005856 T sbread + U pwrite@@FBSD_1.0 + U pread@@FBSD_1.0 + U open@@FBSD_1.0 + U memset@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U malloc@@FBSD_1.0 + U ioctl@@FBSD_1.0 +0000000000003856 T getino + U getfsfile@@FBSD_1.0 + U free@@FBSD_1.0 + U close@@FBSD_1.0 +0000000000004400 T cgwrite1 +0000000000004544 T cgread1 +0000000000004720 T cgread +0000000000006304 T bwrite +0000000000006704 T bread +0000000000006160 T berase +0000000000003320 T _init +0000000000007112 T _fini +0000000001058000 A _end +0000000001057992 A _edata + U __error@@FBSD_1.0 +0000000001056768 d __dso_handle + w __cxa_finalize@@FBSD_1.0 +0000000001057992 A __bss_start + w _Jv_RegisterClasses +0000000001057768 A _GLOBAL_OFFSET_TABLE_ +0000000001057328 A _DYNAMIC diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-size.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-size.txt new file mode 100644 index 0000000000..a58f0c453c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-sort-size.txt @@ -0,0 +1,13 @@ +0000000000000020 T cgread +0000000000000068 T ufs_disk_fillout +0000000000000078 T ufs_disk_close +0000000000000105 T ufs_disk_write +0000000000000130 T berase +0000000000000144 T cgwrite1 +0000000000000176 T cgread1 +0000000000000263 T sbwrite +0000000000000297 T sbread +0000000000000353 T bread +0000000000000388 T bwrite +0000000000000537 T getino +0000000000000551 T ufs_disk_fillout_blank diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-undef.txt b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-undef.txt new file mode 100644 index 0000000000..0b019ccf00 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so-undef.txt @@ -0,0 +1,18 @@ + w _Jv_RegisterClasses + w __cxa_finalize@@FBSD_1.0 + U __error@@FBSD_1.0 + U close@@FBSD_1.0 + U free@@FBSD_1.0 + U getfsfile@@FBSD_1.0 + U ioctl@@FBSD_1.0 + U malloc@@FBSD_1.0 + U memcpy@@FBSD_1.0 + U memset@@FBSD_1.0 + U open@@FBSD_1.0 + U pread@@FBSD_1.0 + U pwrite@@FBSD_1.0 + U snprintf@@FBSD_1.0 + U stat@@FBSD_1.0 + U statfs@@FBSD_1.0 + U strdup@@FBSD_1.0 + U strlcpy@@FBSD_1.0 diff --git a/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so.uu b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so.uu new file mode 100644 index 0000000000..a108d62a7c --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/nm_shared_object1/test_so.uu @@ -0,0 +1,315 @@ +begin 644 test_so +M?T5,1@(!`0D```````````,`/@`!````D`X```````!````````````H```` +M`````````$``.``$`$``&@`7``$````%```````````````````````````` +M````````(!\````````@'P``````````$````````0````8`````(``````` +M```@$````````"`0``````#(!````````-`$```````````0```````"```` +M!@```#`B````````,"(0```````P(A```````)`!````````D`$````````( +M`````````%#E=&0$````&!\````````8'P```````!@?````````"``````` +M```(``````````0`````````)0```#T````I````.@```#@`````````*@`` +M````````````&@```#D````````````````````C`````````"@````P```` +M+````"8````R````(@```#P````O````(````#$````>````+@`````````` +M````&````"T````=````-P```"4`````````&0```#0````[```````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````7````````````````````&P`````````` +M````````````````````)````````````````````"$``````````````!\` +M````````'``````````G`````````"L`````````-0```#8````S```````` +M```````````````````````````````````````````````````````#``$` +M(`$````````````````````````#``(`L`(````````````````````````# +M``,`:`@````````````````````````#``0`T@D````````````````````` +M```#``4`4`H````````````````````````#``8`<`H````````````````` +M```````#``<`T`H````````````````````````#``@`^`P````````````` +M```````````#``D`#`T````````````````````````#``H`D`X````````` +M```````````````#``L`R!L````````````````````````#``P`X!L````` +M```````````````````#``T`&!\````````````````````````#``X``"`0 +M```````````````````````#``\`$"`0```````````````````````#`!`` +M,"(0```````````````````````#`!$`P",0```````````````````````# +M`!(`T",0```````````````````````#`!,`X",0```````````````````` +M```#`!0`Z",0```````````````````````#`!4`R"00```````````````` +M```````#`!8``````````````````````"4!```2``````````````"+```` +M`````+\````2`````````````````````````&X````2``H`&%?9FEN +M86QI>F4`7TIV7U)E9VES=&5R0VQA@<```(`8`$`````````(!````````@``````````"`0```````((!`` +M``````@`````````V",0``````"X)!````````8````=``````````````#` +M)!````````8````Z````````````````)!````````<````7```````````` +M```()!````````<````8```````````````0)!````````<````<```````` +M```````8)!````````<````=```````````````@)!````````<````>```` +M```````````H)!````````<````@```````````````P)!````````<````C +M```````````````X)!````````<````D``````````````!`)!````````<` +M```E``````````````!()!````````<````F``````````````!0)!`````` +M``<````G``````````````!8)!````````<````H``````````````!@)!`` +M``````<````J``````````````!H)!````````<````L``````````````!P +M)!````````<````M``````````````!X)!````````<````O```````````` +M``"`)!````````<````P``````````````"()!````````<````Q```````` +M``````"0)!````````<````S``````````````"8)!````````<````V```` +M``````````"@)!````````<````W``````````````"H)!````````<````[ +M``````````````"P)!````````<````\``````````````!(@^P(Z-\!``#H +MF@X``$B#Q`C#`/\UWA80`/\EX!80`)"0D)#_)=X6$`!H`````.G@_____R76 +M%A``:`$```#IT/____\ESA80`&@"````Z<#_____)<86$`!H`P```.FP____ +M_R6^%A``:`0```#IH/____\EMA80`&@%````Z9#_____):X6$`!H!@```.F` +M_____R6F%A``:`<```#I%A``:!````#IX/[___\E5A80`&@1````Z=#^____ +M)4X6$`!H$@```.G`_O___R5&%A``:!,```#IL/[___\E/A80`&@4````Z:#^ +M____)386$`!H%0```.F0_O___R4N%A``:!8```#I@/[__P````!(@^P(@#TM +M%A```'4[2(,]$Q80``!T&TB+/5(1$`#HF?[__^L-2(/`"$B)!4@1$`#_TDB+ +M!3\1$`!(BQ!(A=)UY,8%\!40``%(@\0(PV9FD$B#/?@4$```=!E(BP7/%1`` +M2(7`=`U(C3WC%!``28G#0?_C\\.0D)"0D)"0D)"0D$B)7"302(EL)-A(B?M, +MB7PD^$R)9"3@B=5,B6PDZ$R)="3P2(/L.$B%_TB)-"1)B<]T"TC'AS@``@`` +M````3(MS($2+8RA$BVLL387V#X2+`0``1#GE#Y/"1#GM#Y+`A-!T38M#"(/X +M`0^$[@```(/X`@^$"@$``$B%VP^%)@$``+C_____2(M<)`A(BVPD$$R+9"08 +M3(ML)"!,BW0D*$R+?"0P2(/$.,-F9F:09F:0@;N,!0``&0%4&8M+8`^$_0`` +M`(N[Z````(GH,=+W]TACD^P```!!B<"+0TQ$B<9(#Z_R]]!$(<`/KT-(2(T4 +M,$ACSJ````(N3D````(G13(GR +MT^!(`<:+@Y0```")P4C3YDR)P>C8_?__,=*)Z/>SJ````$$IU$2)X`.#J``` +M`$2)8RB)0RR+0PB#^`$/A1+___^)ZD0IXDC!X@=,`?(/MP(E`/```$&)!TB+ +M!"1(B1`QP.D$____B>I(BPPD1"GB2,'B"$P!\@^W`B4`\```08D',)PDAC +M@^P```!(#Z_0Z1+___](8WM@Z#7]__](AC1_/__,=)(@_C_=!1; +MB=##2&.#[````$AC_D@/K_CKO$B%VXG"=.5(C16["@``2(F3.``"`(G"Z]-5 +M,=*)]5-(B?M(@^P(.7=CO^___2(/X_W0DB:LT``(`N@$```!(@\0(B=!;7<-( +M8X/L````2&/]2`^O^.NT2(7;B<)TX$B-%2H*``!(B9,X``(`B<+KSHNW,``" +M`(U&`8F',``"`.DX^___D)"0D)"0D)"0D)"02(7_4TB)^W0+2,>'.``"```` +M```QP/:#0``"``)T`EO#BWL,Z#/[__](BSLQP+X"````Z$3[__^%P(E##'@+ +M@XM```(``C'`6\-(A=NX_____W3+2(T%Q0D``$B)@S@``@"X_____UO#9F9F +MD&9FD$%728GW059!54%428G\55-(@>QH!@``2(7_=`M(QX/HG/K__TR)]DB)W^@A^O__A<")Q7C##[>$).@%```E`/```#T`(``` +M=!1(B=_H'_K__TB%P`^$R````$B+&#'V,$)#0``@``````0<>$)$```@``````0<=$)`@`````2<>$ +M)#@``@``````=!U(B=_H'_G__TB%P$B)PP^$O@```$&#C"1```(``4F)'"0Q +MP$B!Q&@&``!;74%<05U!7D%?PTR)^TB)W^A7^?__2(7`#X4X____A>UX%`^W +MA"3H!0``)0#P```]`$```'0,387D=3JX_____^NV2(VL)``$``!(B=](B>[H +ME_C__X7`>&Q(C;4H`0``N@`$``!(B>=(B>/HS/G__^GD_O__2(T5<@@``+C_ +M____28F4)#@``@#I:O___TV%Y'2H2(T5<@@``$F)E"0X``(`Z5'___]-A>1T +MCTB-!=T'``!)B80D.``"`+C_____Z3/___]-A>0/A&W___](C049"```28F$ +M)#@``@"X_____^D1____9F:09F:09F:04TB)^^@C^/___\!T$TB)W^@G^?__ +MB<(QP(/Z_W0)6\-;N/_____#2(7;9F:09F:0=.Y(C06/!P``2(F#.``"`(G0 +M6\-F9F:09F9FD&9F9I!(A?]32(G[=`M(QX'.``"``````!(@WL8`$R-8S!U$4B+@Q@$ +M``!(F4CW>Q!(B4,82(MS&+D`(```3(GB2(G?Z$/X__](@_C_#X2?````A>UT +M=8M#7(7`?FZ+D^P````Q[>M/BT-,2&/22`^OU??0(>@/KT-(2)A(`=!(8W,X +MBXN4````3(GB2(G?2(TT,$C3YKD`(```Z.SW__](@_C_="V-10%(_\4Y0UQ^ +M&XN3[````(&[C`4``!D!5!EUI4ACPD@/K\7KLS'`6UU!7,-(A=MU"EM=05RX +M_____\-(C17,!@``2(F3.``"`.O<2(7;=.%(C16'.``"``````!,C27\!@``3(UK +M,+T```$`ZS^0/1D!5!ET:8M#8#T```$`#Y["/5\%```/E\"$T'0+BU,(A=(/ +MA9\```!!BVPD!$F#Q`3'0P@`````@_W_=$1(8^VY`"```$R)ZDB)[DB)W^BX +M]O__2(/X_W15BX.,!0``/509`0!UF<=#"`$```#KET@[JQ@$``!UCL=#"`(` +M``#KA4B%VW0.2(T%,@8``$B)@S@``@#H(O;__XGJQP`"````2(/$"(G06UU! +M7$%=PTB%VXG"=.Q(C17;!0``2(F3.``"`(G"Z]I(8W-DBXN4````OP$```!( +MT^=(B?!(F4CW_TB)P4B)0Q!(B>A(F4CW^3'22(E#&.NID)"0D)"0D$B)7"3H +M2(EL)/!(B?M,B60D^$B#["A(A?](B?5)B=1T"TC'AS@``@``````2(G?Z)CU +M__^#^/]T-$@/KVL0BWL,2(GBOHAD$(`QP$R)9"0(2(DL).@#]?__2(M<)!!( +MBVPD&$R+9"0@2(/$*,-(A=MTYTB-%2<$``!(B9,X``(`Z]=F9F:09F9FD&9F +MD&9FD$B)7"382(EL).!(B?M,B60DZ$R);"3P2(GU3(ET)/A(@^PH2(7_28G4 +M28G-=`M(QXAW]/__2(G%2(/]_P^$W````$PY[0^%HP```$B)Z$B+'"1( +MBVPD"$R+9"003(ML)!A,BW0D($B#Q"C#9F:09I!,B>_HY/3__TB%P$F)QG0Q +M3(GJ3(GF2(G'Z-[T__](#Z]K$(M[#$R)ZDR)]DB)Z>@(]/__3(GW2(G%Z,WT +M___KATB%VW0.2(T%M@0``$B)@S@``@!,B>I,B>8Q_^B;]/__2`^O:Q"+>PQ, +MB>HQ]DB)Z>C&\___2(G%Z4K___](A=MU1TC'Q?_____I3/___TB%VW3O2(T% +MU0(``$C'Q?____](B8,X``(`Z2W___](A=L/A"3___](C05'.``"``````!!]L4_38GL#X6?````2`^O71"+?0Q,B?),B>9(B=GHD/+_ +M_TB#^/](B<,/A-P```!(AT/A$3___](C04*`P``2(F%.``" +M`.DQ____33GL=)-,B>](B<),B>;HY/+__TR)Y^CL\O__Z7C___],B>?HW_+_ +M_V9FD.EH____2(7M#X1"____2(T%#0,``$B)A3@``@#I+____Y"0D)"0D)"0 +MD)"0D)"0D$B+!1D($`!32(/X_W072(T="P@0`/_02(M#^$B#ZPA(@_C_=?!; +MPY!(@^P(Z+_R__](@\0(PP`````````````D1G)E94)31#H@'`@)`````$;___T +M`!`````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````(!```````-@C$```````%``````````!>E(``7@0`1L,!PB0`0``%``` +M`!P```!@[N__30````!$#A``````%````#0```"8[N__)0`````````````` +M)````$P```"P[N__&0(```!*A@:#!UT.0(X#C02,!8\"`````````!0```!T +M````J/#O_Y``````00X0@P(``!P```",````(/'O_[``````00X0A@)%#AB# +M`T<.(```%````*P```"P\>__%```````````````%````,0```"X\>__:0`` +M``!$#A"#`@``-````-P````0\N__)P(```!"#A"/`D4.&$(.($(.*(P%C02. +M`T0.,$$..$<.H`V#!X8&```````4````%`$```CT[_]$`````$$.$(,"```4 +M````+`$``$#T[_].`````$0.$(,"```<````1`$``'CT[_\'`0```$(.$$0. +M&(8#C`)##B"#!"0```!D`0``:/7O_RD!````0@X00@X800X@00XH@P6&!(P# +MC0)'#C`<````C`$``'#V[_^"`````$J&`X,$3`XPC`(``````!P```"L`0`` +MX/;O_X0!````2H8%@P99#C".`HT#C`0`'````,P!``!0^.__80$```!*A@6# +M!ED.,(P$C@*-`P``````&``````````!>E(``7@0`1L,!PB0`0```````!0` +M```@````@/GO_R<`````2`X0@P(```$`````````,@$````````.```````` +M`%0!````````#`````````#X#`````````T`````````R!L````````$```` +M`````"`!````````!0````````!H"`````````8`````````L`(````````* +M`````````&D!````````"P`````````8``````````,`````````Z",0```` +M```"`````````"@"````````%``````````'`````````!<`````````T`H` +M```````'`````````'`*````````"`````````!@``````````D````````` +M&`````````#^__]O`````%`*````````____;P`````!`````````/#__V\` +M````T@D```````#Y__]O``````(````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````#__________P``````````__________\````` +M````````````````,"(0````````````````````````````(@T````````R +M#0```````$(-````````4@T```````!B#0```````'(-````````@@T````` +M``"2#0```````*(-````````L@T```````#"#0```````-(-````````X@T` +M``````#R#0````````(.````````$@X````````B#@```````#(.```````` +M0@X```````!2#@```````&(.````````<@X```````""#@`````````````` +M````````````````1T-#.B`H1TY5*2`T+C(N,2`R,#`W,#6UT86(`+G-T6X` +M+G)E;&$N<&QT`"YI;FET`"YT97AT`"YF:6YI`"YR;V1A=&$`+F5H7V9R86UE +M7VAD<@`N9&%T80`N96A?9G)A;64`+F1Y;F%M:6,`+F-T;W)S`"YD=&]R5T>S'`@_X"=`:%]K`M=`+)PXL% +M`````(7`=7[H`````$G'P0````!!N*`!``"Y`@```#'2,?9(Q\<`````,<#H +M`````$G'P0````!(B04`````0;B@`0``N0(````QTKX!````2,?'`````#'` +MZ`````!(B04`````R3'`PTB+/0````#H`````$B+/0````#H`````,DQP,-( +MQ\<`````,<#H`````.EO____9F9FD&9FD&9FD&9FD%6#Y@)(B>5U!\DQP,-F +M9I!(B[D@`0``R3'VZ0````"054B+!0````!(B>5(A5(@^PP2#G^3(EM +M^$F)U0^5PD@YSDB)7>A,B67P#Y7`NQD```"$T'4J2(,]``````"S+70>BP4` +M````LP:%P'022#G.=!TPVT@Y_G1=9F:09F:0B=A,BV7P2(M=Z$R+;?C)P[H" +M````2,?&`````+\@````Z`````!)BWT`NB````!(B<9)B<3H`````(7`B<-! +MQD0D&P!T?H`````.NI03E%"(G"00].50B%THE5Y'Y(2&/Z +M2,?&`````+H"````2,'G!>@`````2(UUY$B)QTF)Q.@`````A<")PW0U2,?& +M`````$R)Y^@`````BT7D08E%".E/____,=N)1>3K[4F-=0A,B>?H`````(G# +MZ7O___](8U7D28MU`$R)YTC!X@7H`````(G#Z[-F9F:09F:09F:09F:054B) +MY4B#["!(B5WH3(EE\$B)^TR);?A)B?1)B=7H`````(7`=1I-B64`2(M=Z$R+ +M9?`QP$R+;?C)PV9FD&9FD$B)W^@`````_\AUWDR)Y^@`````28E%`.O09F:0 +M9F:054B)Y4%7059!544Q[4%428GT4TB#[`A(B7W09F:09I!!BT0D&(7`#Y_" +M187M#Y3`A-`/A!$!``!)BQPD2(-["`!U+4B-0Q!)B00D08M$)`C_R(7`08E$ +M)`AYQ4C'QP`````QP.@`````9F9FD&9FD$B+?=#H`````(7`=3Q)BWPD$(GX +MO@`0``!,B>(E_P\``"G&08M$)!@YQ@]'\$BX``````#___^)]D@)Q^@````` +M08G%Z6?___](BWW0Z`````#_R`^%5O___TV+="002+H```````$``$F-!!9( +MNO____]_````2#G0#X:;````3(M["$R)\TBX____?_____](@>,`\/__2#G# +M=C9/C:P^_P\``$F!Y0#P__],.>MR#NLX2('#`!```$DYW78L2(G>2,?'```` +M`.@`````2(7`=>!!O0X```!(@\0(1(GH6T%<05U!7D%?R<-!@WPD(`%$B?Y, +MB?<9TH/"`N@`````A7^__^0D)!52(L%`````$B)Y4B%P'052(GR3(M8"$B)_LE(Q\<` +M````0?_CR;@M````PV9F9I!52(,]``````"X+0```$B)Y700BP:%P'4,BP4` +M````B08QP,G#2(G^2(L]`````$ACT$C!X@7H`````,DQP,.058/_!K@@```` +M2(GE=PI(8\>+!(4`````R<-F9I!F9I!5@>?___\`,5F9F:0BQ2-```` +M`(G(@_H@=`0YUW0.2/_!2(/Y!W7EN/_____)PV9F9I!F9F:09F:09F:054B) +MY5.)\^BT____B<(/ML-;R0^VRO_"#T7!PV9F9I!52(GE05=!5D%505132(/L +M0$B)?:A,BV\0#R#@B<*$P$B)5:!Y"HG`)7____\/(N`/(,!()?___Y](#0`` +M`$`/(L`/";G_`@``#S)(P>(@)?_W__]("=!(B<)(P>H@#S!(BTVH,=+V00@! +M#X0B`0``3(EML$&X4`(``$2)P0\R28G73(MEL(G`2<'G($&^.````$D)QS'` +M08N\)/````!$B?%,B?Y(B<-(T^Y$B4682,'C"$&#[@A)@^P@Z"#___](F$2+ +M19A("=A!@_[X=H@#S!(@46P``$``$&!^%`"```/A38"``!) +M@<4``0``0;]8`@``3(EMT$R);$/,D&+?1!!B?A!@>`````(=)E(B=9,B?-)(UT`B8@ +M2`G&Z*S]__](F$6+11!("=A(B<*)QDB+1:A(P>H@08'@````"$2+2`SI7___ +M_P\)N?\"```/,HG`2,'B((#,"$@)T$B)PDC!ZB`/,`\@P$@E____GP\BP$B+ +M3:`/(N%(@\1`6T%<05U!7D%?R<-(BT700;]H`@``2`4``@``2(E%R$B)1;A$ +MB?D/,DF)UDR+9;B)P$G!YB!!O3@```!)"<8QP)!!B[PD\````$2)Z4R)]DB) +MPTC3[D&#[0A(P>,(28/L(.CK_/__2)A("=A!@_WX==!(B<)$B?E(P>H@#S!( +M@46X``$``$&!_V\"```/A%?^__]!_\?KC$'_P.E,_?__9I!52(M'$#')2(GE +MZP]F9F:0_\&#^5AT%TB#P"!(BQ!(.?)W[4@#4`A(.=9SY,G#R3'`PV9F9I!F +M9F:09F:09F:054B)Y>B'_/__2(L%`````+G_`@``2(G"2,'J(`\PR<.+!0`` +M``!52(GEA0@13'V20G$ZQ%!_\9(@\,@08/^"'1#2<'L"$$/MOSH#?O__XM3 +M$`T````(@>(```#_"<*`>Q0`B5,0=U)"<3K%F9FD&:00?_%2(/#($&#_0AT +M0TG![`A!#[;\Z';Z__^+4Q`-````"('B````_PG"@'L4`(E3$'7-2(LU```` +M`$B->Q1!_\5(@\,@Z`````!!@_T(=;U)@<<``0``08'^60(```^$2@$``$'_ +MQNEV____3(MMT$B+1;A)@<4`"```3(GJ2"M0$$C!^@5(BTVX2&-!#$@YT`^. +M"`$``$&^``(``$F_````"/\```#I@````&9F9I")V`T````(08E%$$B)T$F+ +M30!((?!(@<[_#P``2/?02"'P]\'_#P``2(U0`4F)50AU$TB!^O\/``!V"DB% +MPG4%2(7!=`A!@4T0````$$F+11!,(?A(/0````AT?DB+5;A)@\4@3(GH2"M" +M$$AC4@Q(P?@%2#G0?7=!@\8"1(GQ#S))B=1!BUT0B0@20G$00^V_('C +M````_^A`^?__"<-!C4X!08E=$$B+-0````!)(?1-B64`#S)(P>(@B05_)PTB+1U)"<3K$V:00?_%2(/#($&#_0AT0TG![`A!#[;\Z);X__^+ +M4Q`-````"('B````_PG"@'L4`(E3$'7-2(LU`````$B->Q1!_\5(@\,@Z``` +M``!!@_T(=;U)@<<``0``08'^;P(```^$*/[__T'_QNEY____0?_'D.GZ_/__ +M9F9FD&9F9I!F9I!52(GE05=!5D%528G]05132(GS2(/L"(L2A=(/A6@!``!( +MBP[WP?\/```/A:@"``!(BT8(2#W_#P``#X:8`@``2(U0_TB%T`^%BP(``$B% +MT0^%@@(``(M^$.CR]____\`/A'("``!%,<`QTD'V10@!#X6,`0``18M5#$F+ +M11!%.=`/C9L"``!(C30013')ZWQ(BSY(BQ-(.='___\`J"`/A08"```YSW0J +M@_\(#Y3"@_D!#Y3`A-!U&H/Y"`^4PO_/#Y3`A-`/A-\!``!F9F:09F:00?_` +M13G0=")(@\8@BTX0]\$````(#X5U____387)3`]$SD'_P$4YT'7>3(G.2(7V +M#X3L`0``2(L#2(U[%+H(````2(D&2(M#"$B)1@B+0Q`E____``T````(B480 +M2(/&%.@`````^DR)[^A!]___^TR)[^A(^___,B+=PQ(BU<0A?9^44B+"S'`ZPK_P#GP=$1(@\(@2#D*=?%(BWL( +M2#EZ"'7G2(72="R+2A"X`0```/?!````('6H]\$```!`L!!UGH'A____]\9" +M%`")2A#I>/___TB#Q`BX`@```%M!7$%=05Y!7\G#2(LS0;!89KH`"TB)\$@# +M0PA(/0``$``/AU?^__],B>_HN?G__TB%P$F)Q`^$I0```$B+]( +M_\[HF_G__TB%P$F)Q@^$AP```(M+$(7)#X@,`0``23G$#X(E____`(/X('4:Z>(```!F9F:0BT(0)?___P"#^"`/A,T```!(@\(@23G6 +M<^9,C7L408M4)!"+0Q!)C70D%$R)_X'B````^R7___\`"="Z"````$&)1"00 +M28/$(.@`````33GF<\OICO[__TB#Q`BX%@```%M!7$%=05Y!7\G#9F9FD$B+ +M1@A(.T,(=#)(`?A(.<(/@JC]__](.=O] +M__]F9I!FD%6Y_@```$B)Y4%5051)B?Q32(/L&`\R2(G7B<%Z`````!!]D0D"`%)B40D$$6);"0,#X2A````2(G","$`$``````"-( +M@\(@2('Y```,`'70N@``#`!(B9```P``2('"`!```$C'@`@#````$```QX`0 +M`P``````(TB#P"!(@?H``!``==!,B>?HP_?__T&+="0,28M4)!"%]@^.RO[_ +M_S')ZP1(@\(@BT(0J0````AT"`T````$B4(0_\%!.4PD#'_A2(/$&%M!7$%= +MR<.X"```@`^BB470B4W8#[;(N`$```")7=2)5=Q(T^!(_\A()0#P___WQP`! +M``!(B04`````#X2O_O__Z97^__](@\082,?'`````#'`6T%<05W)Z0`````` +M```````````````!`````@```"`````@````!````!`````(```````````` +M````````;65M.B`\;65M;W)Y/@H`;65M`&MM96T`:V5R;F5L`&UE;7)W`&UE +M;61E7,O9&5V+VUE;2]M96UD978N8RQV(#$N,R`R,#`T+S`X+S`T(#$X.C,P +M.C,Q(&UA7,O86UD-C0O86UD-C0O;65M+F,L +M=B`Q+C$R,B`R,#`X+S`S+S$R(#(Q.C0S.C4P(&IH8B!%>'`@)`!'0T,Z("A' +M3E4I(#0N,BXQ(#(P,#7-I;FET7W-E=``N7-U;FEN:71?````````N`@````````5````/P````@`````````&``````````) +M`````P````````````````````````!@)P```````*0%```````````````` +M```!```````````````````````````````````````````````````````` +M``,``0````````````````````````````,``P`````````````````````` +M``````,`!0````````````````````````````,`#``````````````````` +M``````````,`#P````````````````````````````,`$0`````````````` +M`````````0````(``0```````````+,`````````#@````$`#P`````````` +M`+@`````````&0````$`$0````````````@`````````(`````$`$0`(```` +M``````@`````````*`````$`!@````````````@`````````7`````$`#P#` +M`````````!@`````````=@````$`"`````````````@`````````GP````$` +M#P#@`````````!@`````````L@````$`!@`(``````````@`````````X0`` +M``$`#P```0```````!@`````````]@````$`!@`0``````````@````````` +M+P$```$`#P`@`0```````!@`````````3@$```$`#P`X`0````````0````` +M````6P$```$`#P!``0```````!@`````````8P$```$`#P!8`0````````P` +M````````>0$```$`"@````````````@`````````K0$```$`#P```@`````` +M`!@`````````R0$```$`"``(``````````@`````````]P$```$`#P`@`@`` +M`````!@`````````#P(```(``0#0!````````!H`````````'@(```$``P`` +M`````````!P`````````+@(```(``0#P!````````#(`````````/0(```(` +M`0`P!0```````!P`````````3`(```(``0!0!0```````"X#````````70(` +M``$`$0`H``````````@`````````:P(```(``0"`"````````#(````````` +M?P(```(``0#`"````````"``````````C@(```$`$0`@``````````@````` +M````E@(```(``0#@"````````',`````````J`(```$`$0`0``````````0` +M````````MP(```$`#P!``@```````!@`````````PP(```(``0!@"0`````` +M`#4#````````T0(```$``P`@``````````@`````````X`(```(``0"@#``` +M`````'L#````````[`(```(``0`@$````````!0"````````^0(```$`$0`8 +M``````````@``````````0,```$`"``0``````````@`````````+`,```$` +M#P!@`@```````!@`````````00,```$`#0````````````@`````````=0,` +M``$`#P"``@```````%``````````E`,```$`"``8``````````@````````` +MQ0,```$`#P#0`@```````!@`````````X`,```$`#P#P`@```````!`````` +M````\0,```$`#P"``0```````(``````````^P,```(``0!@`@```````%H` +M`````````P0```(``0#``````````!\`````````"P0```(``0!@!``````` +M`"P`````````'@0```(``0"0!````````#\`````````,00```(``0#@```` +M`````"(`````````000```(``0`0`0```````$,!````````2@0```(``0#` +M`@```````)T!``````````````,`!@````````````````````````````,` +M"`````````````````````````````,`"@`````````````````````````` +M``,`#0````````````````````````````,`$@`````````````````````` +M4`0``!``````````````````````````5P0``!`````````````````````` +M````7@0``!``````````````````````````:@0``!`````````````````` +M````````<`0``!``````````````````````````?`0``!`````````````` +M````````````@P0``!``````````````````````````BP0``!`````````` +M````````````````EP0``!``````````````````````````HP0``!`````` +M````````````````````N`0``!``````````````````````````T00``!`` +M````````````````````````V`0``!``````````````````````````X`0` +M`!``````````````````````````Z00``!`````````````````````````` +M\`0``!``````````````````````````^P0``!`````````````````````` +M````"@4``!``````````````````````````&@4``!`````````````````` +M````````(`4``!``````````````````````````,04``!`````````````` +M````````````-P4``!``````````````````````````/@4``!`````````` +M````````````````2P4``!``````````````````````````604``!`````` +M````````````````````904``!``````````````````````````=P4``!`` +M````````````````````````A04``!``````````````````````````EP4` +M`!``````````````````````````GP4``!`````````````````````````` +M`&UE;5]M;V1E=F5N=`!M96U?8V1E=G-W`&UE;61E=@!K;65M9&5V`%]?6U?7VUO9%]M971A9&%T85]M96U?=F5R6U?7VUO9%]M971A9&%T85]M9%]M96T` +M7VUO9%]M971A9&%T85]M9%]M96T`7U]S971?;6]D;65T861A=&%?7-U;FEN:71?7-? +M=6YI;FET`%]?7-?:6YI=`!-7TU%341%4T-?:6YI=%]S>7-?:6YI=`!A;60V-%]M=')R,FUR +M=`!A;60V-%]M=')R=&]M7-M87-K`&%M9#8T7VUT7-?:6YI +M=`!A;60V-&UE;61E=E]S>7-?:6YI=`!?7W-E=%]S>7-C=&Q?7-C=&Q?7U]M86-H9&5P7V1I7-?:6YI=`!?7U1U;F%B;&5?:6YI=%\V-U]S>7-?:6YI +M=`!?7W1U;F%B;&5?:6YT7S8W`$U?345-1$530P!M96UM;6%P`&UE;6]P96X` +M;65M7W)A;F=E7V%T=')?6]U=`!C<'5?97AT +M:&EG:`!D97-T7-C=&Q? +M7VUA8VAD97!?8VAI;&1R96X`8W!U7VED`'5I;VUO=F4`;6%K95]D978`8V]P +M>6EN`&-P=5]V96YD;W(``P````````L````#````'P`````````E`P`` +M``````(```!1````_/________\U`P````````(```!"````_/________]M +M`P````````(```!+````_/________]^`P````````(```!"````_/______ +M___U`P````````L```!:``````````````#Z`P````````(```!5````_/__ +M______\M!`````````(```!;````_/________\_!`````````(```!+```` +M_/________]D!`````````(```!0````_/________]^!`````````L```!0 +M``````````````"4!`````````(```!0````^_________^K!`````````(` +M``!0````"`````````"[!`````````(```!0````#`````````#'!``````` +M``(```!3````_/_________D!`````````L````"```````````````#!0`` +M``````L````"``````````````#Y!@````````(````&````)`````````#, +M"`````````(````&````'`````````#B"`````````(````&````#``````` +M``#P"`````````(```!#````_/_________Y"`````````(```!*````_/__ +M______\9"0````````L````#````+0`````````@"0````````L```!.```` +M```````````E"0````````(```!4````_/________\P"0````````(```!0 +M````^/________\T"0````````L````%````0`(````````]"0````````L` +M```#````.@````````!$"0````````L```!.``````````````!)"0`````` +M``(```!4````_/_________?"0````````(````"````'`````````#O"0`` +M``````(````_````_/________]V"@````````(````"````'`````````"& +M"@````````(````_````_/________^="P````````(````&````)``````` +M``#-"P````````(````"````'`````````#6"P````````(````_````_/__ +M______]6#`````````(````"````'`````````!F#`````````(````_```` +M_/________\"#@````````(```!3````_/________]J#P````````(```!3 +M````_/________]*$`````````(````&````%`````````!E$`````````(` +M```&````'`````````!M$`````````(```!7````_/________^*$``````` +M``(```!&````^/________^K$`````````(````&````)`````````#1$``` +M``````L````R``````````````#:$`````````(```!$````_/________\- +M$@````````(````&````)``````````C$@````````L````$```````````` +M```P$@````````(```!`````_/________\@``````````$````#````1P`` +M``````````````````$````%````P``````````(``````````$````%```` +M``$````````0``````````$````%````(`$```````````````````$````% +M````X``````````(``````````$````%````(`(````````0``````````$` +M```%````8`(````````8``````````$````%````T`(````````````````` +M``$````%``````(```````````````````$````%````@`(````````(```` +M``````$````#````#P`````````0``````````$````T```````````````H +M``````````$````Y```````````````P``````````$````Y```````````` +M```X``````````$````X``````````````!(``````````$````S```````` +M``````#(``````````$````%````.`$```````#0``````````$````#```` +M#P````````#H``````````$```!(``````````````#P``````````$````% +M````0`$````````(`0````````$````%````0`$````````0`0````````$` +M```#````#P`````````H`0````````$````%````6`$````````P`0`````` +M``$````#````&`````````!``0````````$````#````#P````````!(`0`` +M``````$````!``````````````"X`0````````$````#````)0`````````( +M`@````````$```!6```````````````0`@````````$````R```````````` +M```H`@````````$```!!```````````````P`@````````$````R```````` +M``````!``@````````$````!````(!````````!(`@````````$````!```` +MH`P```````!0`@````````$````!````P`@```````!H`@````````$````! +M````X`@```````"``@````````$```!)``````````````"8`@````````$` +M```&````$`````````"H`@````````$````#````3`````````"P`@`````` +M``$```!8``````````````"X`@````````$````#````6@````````#(`@`` +M``````$````#````7`````````#8`@````````$```!2``````````````#@ +M`@````````$````%````\`(```````#P`@````````$````#````<0`````` +:``#X`@````````$````&````$``````````` +` +end diff --git a/contrib/elftoolchain/tests/tet/nm/ts/vector_str/Makefile b/contrib/elftoolchain/tests/tet/nm/ts/vector_str/Makefile new file mode 100644 index 0000000000..17595dec91 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/vector_str/Makefile @@ -0,0 +1,20 @@ +# $Id: Makefile 2085 2011-10-27 05:06:47Z jkoshy $ +TET_ROOT?= /usr/tet +LIBDIR= $(TET_ROOT)/lib/tet3 +INCDIR= $(TET_ROOT)/inc/tet3 +CSTD= -std=iso9899:1999 +CFLAGS= -I$(INCDIR) +TC= vector_str-tc + +vector_str.o: ../../../vector_str.c + $(CC) $(CSTD) -o vector_str.o -c ../../../vector_str.c + +$(TC): $(TC).c vector_str.o $(INCDIR)/tet_api.h + $(CC) $(CFLAGS) $(CSTD) -o $(TC) $(TC).c vector_str.o $(LIBDIR)/tcm.o \ + $(LIBDIR)/libapi.a + +clean: + rm -f *.o $(TC) + +lint: + lint $(CFLAGS) $(TC) -ltcm diff --git a/contrib/elftoolchain/tests/tet/nm/ts/vector_str/vector_str-tc.c b/contrib/elftoolchain/tests/tet/nm/ts/vector_str/vector_str-tc.c new file mode 100644 index 0000000000..63ef85cc24 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/nm/ts/vector_str/vector_str-tc.c @@ -0,0 +1,392 @@ +/*- + * Copyright (c) 2008 Hyogeol Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: vector_str-tc.c 2085 2011-10-27 05:06:47Z jkoshy $ + */ + +#include +#include + +#include + +#include "../../../vector_str.h" + +static void test_find(); +static void test_get_flat(); +static void test_pop(); +static void test_substr(); +static void test_push(); +static void test_push_vector_head(); +static bool init_test_vec1(struct vector_str *); +static bool init_test_vec2(struct vector_str *); + +void (*tet_startup)() = NULL; +void (*tet_cleanup)() = NULL; + +const char *str1 = "TIGER, tiger, burning bright"; +const char *str2 = "In the forests of the night,"; +const char *str3 = "What immortal hand or eye"; +const char *str4 = "Could frame thy fearful symmetry?"; + +const char *str5 = "TIGER, tiger, burning brightIn the forests of the night,"; +const char *str6 = "In the forests of the night,What immortal hand or eye"; + +struct tet_testlist tet_testlist[] = { + { test_find, 1}, + { test_get_flat, 2}, + { test_pop, 3}, + { test_substr, 4}, + { test_push, 5}, + { test_push_vector_head, 6}, + { NULL, 0} +}; + +static void +test_find() +{ + struct vector_str v; + + tet_infoline("test vector_str_find"); + + if (init_test_vec1(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_find(NULL, "abc", 3) != -1) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_find(&v, "tiger", 5) == 1) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_find(&v, str1, strlen(str1)) != 1) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_find(&v, str2, strlen(str2)) != 1) { + tet_result(TET_FAIL); + + return; + } + + tet_result(TET_PASS); +} + +static void +test_get_flat() +{ + char *rtn; + size_t rtn_len; + struct vector_str v; + + tet_infoline("test vector_str_get_flat"); + + if (init_test_vec1(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + if ((rtn = vector_str_get_flat(NULL, &rtn_len)) != NULL) { + tet_result(TET_FAIL); + + return; + } + + if ((rtn = vector_str_get_flat(&v, &rtn_len)) == NULL) { + tet_result(TET_FAIL); + + return; + } + + if (strncmp(str5, rtn, rtn_len) != 0) { + tet_infoline(rtn); + + free(rtn); + + tet_result(TET_FAIL); + + return; + } + + free(rtn); + + tet_result(TET_PASS); +} + +static void +test_pop() +{ + size_t size; + struct vector_str v; + + tet_infoline("test vector_str_pop"); + + if (init_test_vec1(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + if (v.size == 0) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_pop(NULL) != false) { + tet_result(TET_FAIL); + + return; + } + + size = v.size; + if (vector_str_pop(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + if (v.size != size - 1) { + tet_infoline("Size mismatch."); + tet_result(TET_FAIL); + + return; + } + + tet_result(TET_PASS); +} + +static void +test_substr() +{ + char *rtn; + size_t rtn_len; + struct vector_str v; + + tet_infoline("test vector_str_substr"); + + if (vector_str_init(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v, str1, strlen(str1)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v, str2, strlen(str2)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v, str3, strlen(str3)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v, str4, strlen(str1)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_substr(NULL, 1, 2, NULL) != NULL) { + tet_result(TET_FAIL); + + return; + } + + if ((rtn = vector_str_substr(&v, 1, 2, &rtn_len)) == NULL) { + tet_result(TET_FAIL); + + return; + } + + if (strncmp(str6, rtn, rtn_len) != 0) { + tet_infoline(rtn); + tet_result(TET_FAIL); + + free(rtn); + + return; + } + + free(rtn); + + tet_result(TET_PASS); +} + +static void +test_push() +{ + size_t size; + struct vector_str v; + + tet_infoline("test vector_str_push"); + + if (init_test_vec1(&v) == false) { + tet_result(TET_FAIL); + + return; + } + + size = v.size; + if (vector_str_push(NULL, "abc", 3) != false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v, "abc", 3) == false) { + tet_result(TET_FAIL); + + return; + } + + if (v.size != size + 1) { + tet_result(TET_FAIL); + + return; + } + + if (strncmp(v.container[v.size - 1], "abc", 3) != 0) { + tet_result(TET_FAIL); + + return; + } + + tet_result(TET_PASS); +} + +static void +test_push_vector_head() +{ + char *rtn; + size_t rtn_len; + struct vector_str v1, v2; + + if (vector_str_init(&v1) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_init(&v2) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v2, str1, strlen(str1)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push(&v1, str2, strlen(str2)) == false) { + tet_result(TET_FAIL); + + return; + } + + if (vector_str_push_vector_head(&v1, &v2) == false) { + tet_result(TET_FAIL); + + return; + } + + if ((rtn = vector_str_get_flat(&v1, &rtn_len)) == NULL) { + tet_result(TET_FAIL); + + return; + } + + if (strncmp(str5, rtn, rtn_len) != 0) { + tet_infoline(rtn); + + free(rtn); + + tet_result(TET_FAIL); + + return; + } + + free(rtn); + + tet_result(TET_PASS); +} + +static bool +init_test_vec1(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + if (vector_str_init(v) == false) + return (false); + + if (vector_str_push(v, str1, strlen(str1)) == false) + return (false); + + if (vector_str_push(v, str2, strlen(str2)) == false) + return (false); + + return (true); +} + +static bool +init_test_vec2(struct vector_str *v) +{ + + if (v == NULL) + return (false); + + if (vector_str_init(v) == false) + return (false); + + if (vector_str_push(v, str3, strlen(str3)) == false) + return (false); + + if (vector_str_push(v, str4, strlen(str4)) == false) + return (false); + + return (true); +} diff --git a/contrib/elftoolchain/tests/tet/tet/Makefile b/contrib/elftoolchain/tests/tet/tet/Makefile new file mode 100644 index 0000000000..d035e34223 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/Makefile @@ -0,0 +1,66 @@ +# +# Build TET from source. +# +# $Id: Makefile 4029 2024-01-15 16:16:49Z jkoshy $ +# + +TOP= ../../.. + +.include "${TOP}/mk/elftoolchain.tetvars.mk" + +TET_BUILD_MARKER= .tet-build-done +TET_PATCH_MARKER= .tet-patch-done + +.MAIN: all + +.PHONY: all clean cleandepend clobber depend test + +.if exists(${TET_ROOT}/configure) + +# +# The TET source tree was present. +# + +all: ${TET_BUILD_MARKER} + +${TET_BUILD_MARKER}: ${TET_PATCH_MARKER} + cd ${TET_ROOT} && sh ./configure -t lite + cd ${TET_ROOT}/src && ${MAKE} all install + touch ${TET_BUILD_MARKER} + +${TET_PATCH_MARKER}: + for f in patches/*.patch; do \ + patch -p0 < $${f}; \ + done + touch ${TET_PATCH_MARKER} + +clean: + cd ${TET_ROOT}/src && ${MAKE} clean + rm -f ${TET_BUILD_MARKER} + +clobber: + rm -rf ${TET_ROOT} ${TET_BUILD_MARKER} ${TET_PATCH_MARKER} + +cleandepend depend test: .SILENT + true + +.else + +# +# The TET source tree was not detected. +# + +all depend test: .SILENT + echo "ERROR: The distribution of TET v${TET_VERSION} is missing." + echo + echo "Please download the distribution from:" + echo " ${TET_DOWNLOAD_URL}" + echo "and unpack it into directory \"${TET_ROOT}\"." + echo + false + +clean clobber: + rm -f ${TET_BUILD_MARKER} ${TET_PATCH_MARKER} + +cleandepend: # Nothing to do. +.endif diff --git a/contrib/elftoolchain/tests/tet/tet/bin/check-tet-journal b/contrib/elftoolchain/tests/tet/tet/bin/check-tet-journal new file mode 100755 index 0000000000..9f0549c15a --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/bin/check-tet-journal @@ -0,0 +1,125 @@ +#!/bin/sh +# +# $Id$ +# +# This script examines a TET journal for test invocations that did not +# report a 'PASS' test status. +# +# Unresolved test invocations cause a warning to be issued. Failed +# test invocations cause the script to return with a non-zero exit +# code. +# +# The script will use the most recent journal found under the test suite +# directory specified by the '-t' option. +# +# A specific journal may also be specified, by using the '-j' option. + +usage() +{ + if [ ${#} -ne 0 ]; then + echo ERROR: $* + fi + echo Usage: `basename $0`: "[options]" + echo + echo " -t DIR Look for the most recent journal under directory DIR." + echo " -j FILE Use the specified journal file." +} + +args=`getopt j:t: $*` +set -- ${args} +for arg +do + case "${arg}" in + -t ) + ts_root=${2} + shift; shift;; + -j ) + journal=${2} + shift; shift;; + -- ) + shift; break;; + esac +done + +if [ ${#} -ne 0 ]; then + usage + exit 2 +fi + +if [ -n "${ts_root}" -a -n "${journal}" ]; then + usage "Only one of -t or -j should be specified." + exit 1 +fi + +if [ -n "${ts_root}" -a ! -d "${ts_root}/results" ]; then + usage "No 'results' directory in test suite root \"${ts_root}\"." + exit 1 +fi + +# Determine the latest journal file to use, if one was not explicitly +# specified. +if [ -z "${journal}" ]; then + journal=`find "${ts_root}/results" -name journal | sort | tail -1` + if [ -z "${journal}" ]; then + usage "Could not find a TET journal under \"${ts_root}\"." + exit 1 + fi +fi + +awk -F'|' -v journal="${journal}" < "${journal}" ' +BEGIN { nErrors = 0; nWarnings = 0 } + +# Clear the accumulated message when a test purpose starts. +$1 == "200" { msg = "" } + +# Accumulate messages from the test purpose. +$1 == "520" { + split($2, fields, " "); # Field $2 has fields: ACT# TP# CTXT BLK# SEQ#. + msg = (msg ? msg "\n" : "") fields[1] " " fields[2] " " $3; +} + +# Handle the end of the test. +$1 == "220" { + # Test passes are unexceptional. + if ($3 == "PASS") { next; } + + # Record messages from test failures. + if ($3 == "FAIL") { + errors[nErrors] = msg; + nErrors++; + next; + } + + # Record messages for other test statuses as warnings. + warnings[nWarnings] = msg; + nWarnings++; +} + +# Catch exec failures. +$1 == "50" { + errors[nErrors] = $3; + nErrors++; + next; +} + +# Print out warnings and errors. +END { + if (nWarnings > 0 || nErrors > 0) + printf(":: JOURNAL \"%s\"\n", journal); + + if (nWarnings > 0) { + print ":: TEST SUITE WARNINGS" + for (w = 0; w < nWarnings; w++) { + print warnings[w]; + } + } + + if (nErrors > 0) { + print ":: TEST SUITE FAILURES" + for (e = 0; e < nErrors; e++) { + print errors[e]; + } + } + + exit (nErrors != 0); +}' diff --git a/contrib/elftoolchain/tests/tet/tet/bin/munge-ts b/contrib/elftoolchain/tests/tet/tet/bin/munge-ts new file mode 100755 index 0000000000..a3d034ae0b --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/bin/munge-ts @@ -0,0 +1,168 @@ +#!/bin/sh +# +# $Id: munge-ts 2834 2012-12-30 16:34:47Z jkoshy $ +# +# This shell script generates scaffolding for a TET C API test case +# given a list of objects that use the TET C API. +# +# - If the TET extended API function "tet_isdefic" is present, then +# no scaffolding is generated. In such cases, the test case +# is assumed to be self-sufficient. +# +# - If the symbol "tet_testlist[]' is defined, then no scaffolding is +# generated. +# +# - Otherwise, a "struct tet_testlist []" array is generated from the +# names of public functions in the objects. +# +# Functions with names matching "^tp\(.*\)" are treated as test +# purposes belonging to a test case named "Default". +# +# Functions with names matching '^tc\([a-zA-Z0-9_]+\)' are treated +# as test case names. +# +# Functions with names matching '^tc\([a-zA-Z0-9_]*\)_tp.*' +# are treated as test purposes belonging to the test case named +# by the first regular expression. Test purposes in a given test +# case are invoked in lexicographic sort order. +# +# - If variables "tet_startup" or "tet_cleanup" are not defined in the +# objects given to the script, a suitable NULL pointer definition +# is generated. +# +# - A scenario file that invokes each test case independently of the +# others is generated. This scenario file is intended to be +# included, using TET's ":include:" syntax, from a higher-level +# scenario file. + +usage() +{ + echo Usage: `basename $0`: "[options] objects..." + echo + /bin/echo -e " Generate TET scaffolding from objects. " \ + "Options include:" + /bin/echo -e "\t-o out\t\tcreate output file \"out\" " \ + "[default \"tc.c\"]." + /bin/echo -e "\t-s scen\t\tcreate scenario file \"scen\" " \ + "[default \"tet_scen\"]." + /bin/echo -e "\t-p prefix\t\tprefix for naming test cases" +} + +output="tc.c" +scen="tet_scen" + +args=`getopt o:p:s: $*` +if [ ${?} -ne 0 ]; then + usage + exit 2 +fi + +set -- ${args} + +for i +do + case "${i}" in + -o ) + output="${2}"; + shift; shift;; + -p ) + prefix="${2}"; + shift; shift;; + -s ) + scen="${2}"; + shift; shift;; + -- ) + shift; break;; + esac +done + +if [ ${#} -eq 0 ]; then + usage + exit 2 +fi + +exec > ${output} +echo "\ +/* + * WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! + * + * THIS FILE IS GENERATED FROM: ${@} + */ +#include " + +if ! nm ${*} | sort -k 3 | \ + awk -v scen=${scen} -v prefix=${prefix} ' + BEGIN { do_scaffolding = 1; tcseq[ntc++] = "Default"; } + $2 == "T" && $3 ~ "^tc" { + fnname = substr($3,3); + + if (match(fnname, "^.*_tp")) + tcname = substr(fnname,RSTART,RLENGTH-3); + else + tcname = fnname; + + if (ptc != tcname) { + tcseq[ntc++] = tcname; + ptc = tcname; + } + + c = tc[tcname]++; + tp[tcname,c] = $3 + } + $2 == "T" && $3 ~ "^tp" { + tcname = "Default"; + + c = tc[tcname]++; + tp[tcname,c++] = $3; + } + $2 == "T" && $3 == "tet_isdefic" { do_scaffolding = 0 } + $2 == "D" && $3 == "tet_testlist" { do_scaffolding = 0 } + $2 == "D" && $3 == "tet_cleanup" { has_tc_cleanup = 1 } + $2 == "D" && $3 == "tet_startup" { has_tc_startup = 1 } + $1 == "U" && $2 == "elfts_compare_files" { + printf("#include \"elfts-compare-files.c\"\n"); + } + $1 == "U" && $2 == "elfts_copy_file" { + printf("#include \"elfts-copy-file.c\"\n"); + } + $1 == "U" && $2 == "elfts_init_version" { + printf("#include \"elfts-initversion.c\"\n"); + } + $1 == "U" && $2 == "elfts_open_file" { + printf("#include \"elfts-openfile.c\"\n"); + } + END { + if (do_scaffolding == 0) + exit(1); + + if (has_tc_startup == 0) { + printf("void (*tet_startup)(void) = NULL;\n"); + } + + if (has_tc_cleanup == 0) { + printf("void (*tet_cleanup)(void) = NULL;\n"); + } + + for (tcname in tc) { + nc = tc[tcname]; + for (c = 0; c < nc; c++) + printf("void %s();\n", tp[tcname,c]); + } + + printf("struct tet_testlist tet_testlist[] = {\n"); + + n = 0; + for (n = 0; n < ntc; n++) { + tcname = tcseq[n]; + nc = tc[tcname]; + for (c = 0; c < nc; c++) { + printf("\t{%s,%d},\n", tp[tcname,c], n); + } + if (nc > 0) + printf("/%s{%d}\n", prefix, n) > scen; + } + printf("\t{NULL,0} };\n"); + }'; then + rm ${output} ${scen} + exit 1 +fi diff --git a/contrib/elftoolchain/tests/tet/tet/common/elfts.m4 b/contrib/elftoolchain/tests/tet/tet/common/elfts.m4 new file mode 100644 index 0000000000..c5426f0991 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/common/elfts.m4 @@ -0,0 +1,80 @@ +pushdef(`_DIVNUM',divnum)divert(-1) +/*- + * Copyright (c) 2006,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: elfts.m4 2844 2012-12-31 03:30:20Z jkoshy $ + */ + +dnl `mkstemp' is a built-in in GNU m4. +ifdef(`mkstemp',`undefine(`mkstemp')') + +/* + * Macros for use with `m4'. + */ + +/* + * TOUPPER/TOLOWER: Convert $1 to upper-case or lower-case respectively. + * CAPITALIZE: Make $1 capitalized. + */ + +define(`TOUPPER',`translit($1,`abcdefghijklmnopqrstuvwxyz',`ABCDEFGHIJKLMNOPQRSTUVWXYZ')') +define(`TOLOWER',`translit($1,`ABCDEFGHIJKLMNOPQRSTUVWXYZ',`abcdefghijklmnopqrstuvwxyz')') +define(`CAPITALIZE',`TOUPPER(substr($1,0,1))`'TOLOWER(substr($1,1))') + +/* + * TP_ANNOUNCE: Announce a test purpose. + * Usage: + * TP_ANNOUNCE() -- Announce the function name. + * TP_ANNOUNCE(fmt, args...) -- Announce the function and print arguments. + */ +define(`TP_ANNOUNCE',`TP_FUNCTION(); + tet_printf("A: " $*)'); + +/* + * TP_FUNCTION: Print the current function name to the TET log. + */ +define(`TP_FUNCTION',`tet_printf("N: %s", __func__)') + +/* + * TP_UNRESOLVED/T_FAIL: Print an appropriate message to the log, and set the + * `result' variable. + */ +define(`TP_UNRESOLVED', + `do { tet_printf("U: " $*); result = TET_UNRESOLVED; } while (0)') +define(`TP_FAIL', + `do { tet_printf("F: " $*); result = TET_FAIL; } while (0)') + +/* + * TP_SET_VERSION: set elf_version() or fail. + */ +define(`TP_SET_VERSION',`do { + if (elf_version(EV_CURRENT) != EV_CURRENT) { + TP_UNRESOLVED("elf_version() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + } while (0)') + +divert(_DIVNUM)popdef(`_DIVNUM') diff --git a/contrib/elftoolchain/tests/tet/tet/patches/configure.patch b/contrib/elftoolchain/tests/tet/tet/patches/configure.patch new file mode 100644 index 0000000000..c2307504ca --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/patches/configure.patch @@ -0,0 +1,13 @@ +: $Id: configure.patch 3721 2019-03-23 09:04:45Z jkoshy $ + +--- tet3.8/configure-- Sat Mar 23 10:36:51 2019 ++++ tet3.8/configure Sat Mar 23 10:38:03 2019 +@@ -317,7 +317,7 @@ CRAY*) + *-sgi-irix*) + fname=irix.mk + ;; +-*-freebsd) ++*-freebsd | *-netbsd | *-dragonfly | *-openbsd) #Use FreeBSD's configuration. + fname=freebsd.mk + ;; + *-bsdi) diff --git a/contrib/elftoolchain/tests/tet/tet/patches/defines.linux.patch b/contrib/elftoolchain/tests/tet/tet/patches/defines.linux.patch new file mode 100644 index 0000000000..51eea902bb --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/patches/defines.linux.patch @@ -0,0 +1,13 @@ +: $Id: defines.linux.patch 2204 2011-11-24 05:23:42Z jkoshy $ + +--- tet3.8/src/defines/linux.mk-- 2011-11-18 10:04:28.374703560 +0530 ++++ tet3.8/src/defines/linux.mk 2011-11-18 10:04:32.318703781 +0530 +@@ -71,7 +71,7 @@ + # ************************************************************************ + + # make utilities - these don't usually change +-MAKE = make ++MAKE ?= make + SHELL = /bin/sh + + diff --git a/contrib/elftoolchain/tests/tet/tet/patches/guessos.patch b/contrib/elftoolchain/tests/tet/tet/patches/guessos.patch new file mode 100644 index 0000000000..d438c49262 --- /dev/null +++ b/contrib/elftoolchain/tests/tet/tet/patches/guessos.patch @@ -0,0 +1,15 @@ +: $Id: guessos.patch 2204 2011-11-24 05:23:42Z jkoshy $ + +--- tet3.8/src/helpers/GuessOS-- 2005-12-09 16:29:25 +0530 ++++ tet3.8/src/helpers/GuessOS 2011-11-24 01:42:21 +0530 +@@ -175,6 +175,10 @@ + echo "${MACHINE}-whatever-bsdi"; exit 0 + ;; + ++ DragonFly:*) ++ echo "${MACHINE}-whatever-dragonfly"; exit 0 ++ ;; ++ + FreeBSD:*:*:*486*) + echo "i486-whatever-freebsd"; exit 0 + ;; diff --git a/contrib/elftoolchain/tools/Makefile b/contrib/elftoolchain/tools/Makefile new file mode 100644 index 0000000000..13db85769f --- /dev/null +++ b/contrib/elftoolchain/tools/Makefile @@ -0,0 +1,14 @@ +# $Id$ + +TOP= .. + +.include "${TOP}/mk/elftoolchain.os.mk" + +SUBDIR= + +.if defined(MKNOWEB) && ${MKNOWEB} == "yes" && exists(${NOWEB}) && \ + exists(${PDFLATEX}) +SUBDIR+= build-automation +.endif + +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/contrib/elftoolchain/tools/compare-elf-symbols.sh b/contrib/elftoolchain/tools/compare-elf-symbols.sh new file mode 100755 index 0000000000..a7f1a647d3 --- /dev/null +++ b/contrib/elftoolchain/tools/compare-elf-symbols.sh @@ -0,0 +1,189 @@ +#!/bin/sh +# +# Compare symbols in sys/${arch}/include/*.h with the corresponding +# symbols in Elftoolchain's common/sys/elfconstants.m4. +# +# $Id$ + +usage() { + if [ ${#} -gt 0 ]; then + echo "$@" + echo + fi + + echo "Usage: $0 [options]" + echo + echo 'Compare OS ELF symbol definitions against Elftoolchain sources.' + echo + echo 'Options:' + echo ' -a ARCH_DIR The architecture directory to check.' + echo ' -e ELF_CONSTANTS The file to check against.' + echo " Default: ${default_elfconstants_file}." + echo ' -o OS_FLAVOR Source tree flavor: one of FreeBSD or NetBSD.' + echo " Default: ${default_os_flavor}." + echo ' -t SYMBOL_TYPE Type of ELF symbol to compare.' + echo " Default: ${default_symbol_type}." +} + +# +# Set defaults. +# +if ! type realpath > /dev/null; then + echo "ERROR: No 'realpath' utility found." + exit 72 # EX_OSFILE +fi + +script_location="$(realpath $0)" +script_dir="$(dirname ${script_location})" +default_elfconstants_file="${script_dir}/../common/sys/elfconstants.m4" +default_os_flavor=NetBSD +default_symbol_type=R # Relocations. + +# +# Helper functions. +# + +# get_arch_name(arch-dir) +# +# Translate a directory under 'sys/arch' to an architecture name. +get_arch_name() { + echo "$(basename $1)" +} + +# get_relocation_prefix(arch-name) +# +# Translate an architecture name to an R_* symbol prefix. +get_relocation_prefix() { + case "${1}" in + i386) + echo R_386_ + ;; + ia64) + case ${os_flavor} in + FreeBSD) + echo R_IA_64_ + ;; + NetBSD) + echo R_IA64_ + ;; + esac + ;; + *) + echo "Unsupported architecture '${1}'." + exit 65 # EX_DATAERR + ;; + esac +} + +# get_os_symbols(symbol-prefix) +# +# Extract symbols matching the specified prefix from OS headers. +get_os_symbols() { + find . -name '*.h' | \ + xargs egrep -E "#define[[:space:]]+${1}" | \ + awk '{ printf("_(%s,\t%s)\n", $2, $3); }' +} + +# get_elf_constants(prefix) +# +# Extract symbols matching the specified prefix from . +get_elf_constants() { + awk -v prefix=$1 '$1 ~ prefix { print }' ${elf_constants_file} +} + +# +# Parse options. +# +options=":a:e:o:t:" +while getopts "$options" var; do + case $var in + a) arch_dir="${OPTARG}" + ;; + e) elf_constants_file="$OPTARG" + ;; + o) os_flavor="${OPTARG}" + ;; + t) symbol_type="${OPTARG}" + ;; + '?') usage "ERROR: Unknown option: '-$OPTARG'." + exit 64 # EX_USAGE + ;; + ':') usage "ERROR: Option '-$OPTARG' expects an argument." + exit 64 # EX_USAGE + ;; + esac + shift $((OPTIND - 1)) +done + +# Sanity check arguments. +if [ -z "${arch_dir}" ]; then + echo "ERROR: Option '-a' must be specified." + exit 64 # EX_USAGE +fi + +if [ ! -d "${arch_dir}" ]; then + echo "ERROR: '${arch_dir}' is not a directory" + exit 65 # EX_DATAERR +fi + +if [ -z ${elf_constants_file} ]; then + elf_constants_file="${default_elfconstants_file}" +fi + +if [ ! -f ${elf_constants_file} ]; then + echo "ERROR: No such file '${elf_constants_file}'." + exit 65 # EX_DATAERR +fi + +if [ -z ${os_flavor} ]; then + os_flavor=${default_os_flavor} +fi + +case ${os_flavor} in + NetBSD | FreeBSD ) + ;; + * ) + echo Unsupported OS: ${os_flavor} + exit 65 # EX_DATAERR + ;; +esac + +if [ -z ${symbol_type} ]; then + symbol_type=${default_symbol_type} +fi + +case ${symbol_type} in + R) # Relocations. + ;; + *) + echo Unimplemented symbol type ${symbol_type}. + exit 69 # EX_UNAVAILABLE +esac + +working_directory=$(mktemp -d -t ces.XXXXXXX) +trap "rm -rf ${working_directory}" EXIT HUP INT QUIT TERM + +# Extract symbols of the desired type from the OS source tree and from +# Elftoolchain code. +arch_name=$(get_arch_name ${arch_dir}) + +elf_constants_symbols=${working_directory}/elf-constants-symbols +os_symbols=${working_directory}/os-symbols + +case ${symbol_type} in + R) + relocation_prefix=$(get_relocation_prefix ${arch_name}) + + (cd ${arch_dir} && \ + get_os_symbols ${relocation_prefix}) > ${os_symbols} + + get_elf_constants ${relocation_prefix} > ${elf_constants_symbols} + ;; + + *) + echo "ERROR: Unexpected symbol type '${symbol_type}'." + exit 70 # EX_SOFTWARE +esac + +# Compare symbol sets. +diff -wu ${os_symbols} ${elf_constants_symbols} diff --git a/contrib/elftoolchain/tools/html-manpages/Makefile b/contrib/elftoolchain/tools/html-manpages/Makefile new file mode 100644 index 0000000000..8a06fffed6 --- /dev/null +++ b/contrib/elftoolchain/tools/html-manpages/Makefile @@ -0,0 +1,25 @@ +# Publish the Elftoolchain project's manual pages as static files on +# Sourceforge. +# +# $Id$ + +TOP= ../.. + +CSS= mandoc.css + +STAGING_DIRECTORY= ${.OBJDIR}/man + +# The location of the manual page collection on SF's website. +SF_WEBDIR= ${USER}@web.sourceforge.net:/home/project-web/elftoolchain/htdocs/man + +.MAIN: all + +all: .PHONY + ${.CURDIR}/html-manpages.sh -t ${TOP} -c ${CSS} \ + -o ${STAGING_DIRECTORY} + +publish: all .PHONY + rsync -Jaz ${STAGING_DIRECTORY}/ ${SF_WEBDIR}/ + +clean: .PHONY + rm -rf ${STAGING_DIRECTORY} diff --git a/contrib/elftoolchain/tools/html-manpages/html-manpages.sh b/contrib/elftoolchain/tools/html-manpages/html-manpages.sh new file mode 100755 index 0000000000..b9bfe2d23a --- /dev/null +++ b/contrib/elftoolchain/tools/html-manpages/html-manpages.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# +# Turn Elftoolchain's manual pages into a collection of static HTML pages. + +# +# Helper functions. +# +usage() +{ + exec >&2 + + # Print the supplied message, if present. + if [ -n "${@}" ]; then echo "## ${@}"; fi + + echo "Usage: ${progname} -t TOPDIR [options]" + + exit 1 +} + +log() +{ + if [ -z "${verbose}" ]; then return; fi + echo $* +} + +# Locate a BSD make. +bsdmakepath() +{ + case `uname -s` in + FreeBSD|Minix|NetBSD|OpenBSD|DragonFly) + which make;; + Linux ) which bmake;; + * ) usage "ERROR: Unsupported operating system.";; + esac +} + +# Replace a header element with an SF logo invocation. +add_sf_link() +{ + sed -e 's,\(\).*,\1SourceForge Logo,' +} + +# +# Defaults. +# +options='c:o:t:v' +css_file='mandoc.css' +output_dir='' +verbose='' +make=`bsdmakepath` + +# +# Parse options. +# +while getopts ${options} option +do + case ${option} in + 'c') css_file="${OPTARG}";; + 'm') make="${OPTARG}";; + 'o') output_dir="${OPTARG}";; + 't') top="${OPTARG}";; + 'v') verbose=TRUE;; + esac +done + +[ -n "${top}" ] || usage "The -t flag was not specified." + +curdir=`pwd` +if [ -z "${output_dir}" ]; then output_dir="${curdir}/man"; fi + +# Create the staging directory and copy the CSS specification into it. +mkdir -p ${output_dir} || \ + usage "ERROR: Cannot create output directory \"${output_dir}\"." +cp ${css_file} ${output_dir} || \ + usage "ERROR: Could not copy \"${css_file}\" to \"${output_dir}\"." + +# List the manual pages to be converted to HTML. +# +# This stanza selects all file names ending in ".", which may be +# too permissive. +cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"." +man_srcs=$(find . -name tet -prune -o -type f -name '*.[0-9]' -print) + +# Translate manual pages to HTML. +for m in ${man_srcs}; do + b=$(basename ${m}) + log Translating ${m} + mandoc -Thtml -O style=${css_file##*/},man=%N.%S.html -mdoc \ + -I os='The Elftoolchain Project' ${m} | \ + add_sf_link > ${output_dir}/${b}.html +done + +# Add MLINKS. +# +# Create a list of directories containing the manual pages being +# translated. +man_dirs=$(echo "$man_srcs" | sed -e 's,/[^/]*$,,' | sort -u) + +# The output from invoking 'make -V $MLINKS' is a sequence of +# (source, target) pairs of manual page names. +for d in ${man_dirs}; do + log Adding MLINKS for ${d} + mlinks=$(cd ${d} && ${make} -V '${MLINKS}') || \ + usage "ERROR: Failed to extract MLINKS for ${d}" + set -- ${mlinks} + while [ ${#} -gt 0 ]; do + log Linking ${2} to ${1} + (cd ${output_dir}; ln -fs ${1}.html ${2}.html); + shift; shift; + done +done + +# Build an index. +log Building an index + +cd ${output_dir} || \ + usage "ERROR: Could not change directory to \"${output_dir}\"." + +# Write out the HTML prologue. +cat > index.html < + + + + + + INDEX + + + + + + + +
Manual Page IndexSourceForge Logo +
+

+
+EOF + +# Build
elements for each generated HTML file. +for h in $(ls *.[0-9].html); do + hxextract -s "
${h%.html}
" \ + -e "
" span.Nd ${h} + echo +done >> index.html + +# Write out the epilogue. +cat >> index.html < +
+ + +EOF diff --git a/contrib/elftoolchain/tools/html-manpages/mandoc.css b/contrib/elftoolchain/tools/html-manpages/mandoc.css new file mode 100644 index 0000000000..436a8d1c23 --- /dev/null +++ b/contrib/elftoolchain/tools/html-manpages/mandoc.css @@ -0,0 +1,351 @@ +/* $Id: mandoc.css,v 1.45 2019/03/01 10:57:18 schwarze Exp $ */ +/* + * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). + * + * Written by Ingo Schwarze . + * I place this file into the public domain. + * Permission to use, copy, modify, and distribute it for any purpose + * with or without fee is hereby granted, without any conditions. + */ + +/* Global defaults. */ + +html { max-width: 65em; } +body { font-family: Helvetica,Arial,sans-serif; } +table { margin-top: 0em; + margin-bottom: 0em; + border-collapse: collapse; } +/* Some browsers set border-color in a browser style for tbody, + * but not for table, resulting in inconsistent border styling. */ +tbody { border-color: inherit; } +tr { border-color: inherit; } +td { vertical-align: top; + padding-left: 0.2em; + padding-right: 0.2em; + border-color: inherit; } +ul, ol, dl { margin-top: 0em; + margin-bottom: 0em; } +li, dt { margin-top: 1em; } + +.permalink { border-bottom: thin dotted; + color: inherit; + font: inherit; + text-decoration: inherit; } +* { clear: both } + +/* Search form and search results. */ + +fieldset { border: thin solid silver; + border-radius: 1em; + text-align: center; } +input[name=expr] { + width: 25%; } + +table.results { margin-top: 1em; + margin-left: 2em; + font-size: smaller; } + +/* Header and footer lines. */ + +table.head { width: 100%; + border-bottom: 1px dotted #808080; + margin-bottom: 1em; + font-size: smaller; } +td.head-vol { text-align: center; + vertical-align: middle; } +td.head-ltitle { + text-align: left; + vertical-align: middle; } +td.head-rtitle { + text-align: right; } + +table.foot { width: 100%; + border-top: 1px dotted #808080; + margin-top: 1em; + font-size: smaller; } +td.foot-os { text-align: right; } + +/* Sections and paragraphs. */ + +.manual-text { + margin-left: 3.8em; } +.Nd { } +section.Sh { } +h1.Sh { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -3.2em; + font-size: 110%; } +section.Ss { } +h2.Ss { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -1.2em; + font-size: 105%; } +.Pp { margin: 0.6em 0em; } +.Sx { } +.Xr { } + +/* Displays and lists. */ + +.Bd { } +.Bd-indent { margin-left: 3.8em; } + +.Bl-bullet { list-style-type: disc; + padding-left: 1em; } +.Bl-bullet > li { } +.Bl-dash { list-style-type: none; + padding-left: 0em; } +.Bl-dash > li:before { + content: "\2014 "; } +.Bl-item { list-style-type: none; + padding-left: 0em; } +.Bl-item > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-enum { padding-left: 2em; } +.Bl-enum > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-diag { } +.Bl-diag > dt { + font-style: normal; + font-weight: bold; } +.Bl-diag > dd { + margin-left: 0em; } +.Bl-hang { } +.Bl-hang > dt { } +.Bl-hang > dd { + margin-left: 5.5em; } +.Bl-inset { } +.Bl-inset > dt { } +.Bl-inset > dd { + margin-left: 0em; } +.Bl-ohang { } +.Bl-ohang > dt { } +.Bl-ohang > dd { + margin-left: 0em; } +.Bl-tag { margin-top: 0.6em; + margin-left: 5.5em; } +.Bl-tag > dt { + float: left; + margin-top: 0em; + margin-left: -5.5em; + padding-right: 0.5em; + vertical-align: top; } +.Bl-tag > dd { + clear: right; + width: 100%; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0.6em; + vertical-align: top; + overflow: auto; } +.Bl-compact { margin-top: 0em; } +.Bl-compact > dd { + margin-bottom: 0em; } +.Bl-compact > dt { + margin-top: 0em; } + +.Bl-column { } +.Bl-column > tbody > tr { } +.Bl-column > tbody > tr > td { + margin-top: 1em; } +.Bl-compact > tbody > tr > td { + margin-top: 0em; } + +.Rs { font-style: normal; + font-weight: normal; } +.RsA { } +.RsB { font-style: italic; + font-weight: normal; } +.RsC { } +.RsD { } +.RsI { font-style: italic; + font-weight: normal; } +.RsJ { font-style: italic; + font-weight: normal; } +.RsN { } +.RsO { } +.RsP { } +.RsQ { } +.RsR { } +.RsT { text-decoration: underline; } +.RsU { } +.RsV { } + +.eqn { } +.tbl td { vertical-align: middle; } + +.HP { margin-left: 3.8em; + text-indent: -3.8em; } + +/* Semantic markup for command line utilities. */ + +table.Nm { } +code.Nm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fl { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Cm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ar { font-style: italic; + font-weight: normal; } +.Op { display: inline; } +.Ic { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ev { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Pa { font-style: italic; + font-weight: normal; } + +/* Semantic markup for function libraries. */ + +.Lb { } +code.In { font-style: normal; + font-weight: bold; + font-family: inherit; } +a.In { } +.Fd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ft { font-style: italic; + font-weight: normal; } +.Fn { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fa { font-style: italic; + font-weight: normal; } +.Vt { font-style: italic; + font-weight: normal; } +.Va { font-style: italic; + font-weight: normal; } +.Dv { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Er { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Various semantic markup. */ + +.An { } +.Lk { } +.Mt { } +.Cd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ad { font-style: italic; + font-weight: normal; } +.Ms { font-style: normal; + font-weight: bold; } +.St { } +.Ux { } + +/* Physical markup. */ + +.Bf { display: inline; } +.No { font-style: normal; + font-weight: normal; } +.Em { font-style: italic; + font-weight: normal; } +.Sy { font-style: normal; + font-weight: bold; } +.Li { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Tooltip support. */ + +h1.Sh, h2.Ss { position: relative; } +.An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft, +.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs, +.St, .Sx, .Sy, .Va, .Vt, .Xr { + display: inline-block; + position: relative; } + +.An::before { content: "An"; } +.Ar::before { content: "Ar"; } +.Cd::before { content: "Cd"; } +.Cm::before { content: "Cm"; } +.Dv::before { content: "Dv"; } +.Em::before { content: "Em"; } +.Er::before { content: "Er"; } +.Ev::before { content: "Ev"; } +.Fa::before { content: "Fa"; } +.Fd::before { content: "Fd"; } +.Fl::before { content: "Fl"; } +.Fn::before { content: "Fn"; } +.Ft::before { content: "Ft"; } +.Ic::before { content: "Ic"; } +code.In::before { content: "In"; } +.Lb::before { content: "Lb"; } +.Lk::before { content: "Lk"; } +.Ms::before { content: "Ms"; } +.Mt::before { content: "Mt"; } +.Nd::before { content: "Nd"; } +code.Nm::before { content: "Nm"; } +.Pa::before { content: "Pa"; } +.Rs::before { content: "Rs"; } +h1.Sh::before { content: "Sh"; } +h2.Ss::before { content: "Ss"; } +.St::before { content: "St"; } +.Sx::before { content: "Sx"; } +.Sy::before { content: "Sy"; } +.Va::before { content: "Va"; } +.Vt::before { content: "Vt"; } +.Xr::before { content: "Xr"; } + +.An::before, .Ar::before, .Cd::before, .Cm::before, +.Dv::before, .Em::before, .Er::before, .Ev::before, +.Fa::before, .Fd::before, .Fl::before, .Fn::before, .Ft::before, +.Ic::before, code.In::before, .Lb::before, .Lk::before, +.Ms::before, .Mt::before, .Nd::before, code.Nm::before, +.Pa::before, .Rs::before, +h1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before, +.Va::before, .Vt::before, .Xr::before { + opacity: 0; + transition: .15s ease opacity; + pointer-events: none; + position: absolute; + bottom: 100%; + box-shadow: 0 0 .35em #000; + padding: .15em .25em; + white-space: nowrap; + font-family: Helvetica,Arial,sans-serif; + font-style: normal; + font-weight: bold; + color: black; + background: #fff; } +.An:hover::before, .Ar:hover::before, .Cd:hover::before, .Cm:hover::before, +.Dv:hover::before, .Em:hover::before, .Er:hover::before, .Ev:hover::before, +.Fa:hover::before, .Fd:hover::before, .Fl:hover::before, .Fn:hover::before, +.Ft:hover::before, .Ic:hover::before, code.In:hover::before, +.Lb:hover::before, .Lk:hover::before, .Ms:hover::before, .Mt:hover::before, +.Nd:hover::before, code.Nm:hover::before, .Pa:hover::before, +.Rs:hover::before, h1.Sh:hover::before, h2.Ss:hover::before, .St:hover::before, +.Sx:hover::before, .Sy:hover::before, .Va:hover::before, .Vt:hover::before, +.Xr:hover::before { + opacity: 1; + pointer-events: inherit; } + +/* Overrides to avoid excessive margins on small devices. */ + +@media (max-width: 37.5em) { +.manual-text { + margin-left: 0.5em; } +h1.Sh, h2.Ss { margin-left: 0em; } +.Bd-indent { margin-left: 2em; } +.Bl-hang > dd { + margin-left: 2em; } +.Bl-tag { margin-left: 2em; } +.Bl-tag > dt { + margin-left: -2em; } +.HP { margin-left: 2em; + text-indent: -2em; } +} diff --git a/contrib/elftoolchain/tools/netbsd-base-system-import.sh b/contrib/elftoolchain/tools/netbsd-base-system-import.sh new file mode 100755 index 0000000000..a6d7266e08 --- /dev/null +++ b/contrib/elftoolchain/tools/netbsd-base-system-import.sh @@ -0,0 +1,230 @@ +#!/bin/sh +# +# Copy files from an Elftoolchain checkout and prepare them for import +# into the NetBSD 'src' tree. +# +# Usage: +# +# netbsd-base-system-import.sh [-D] -s SRCDIR -d DISTDIR -m MODULE \ +# [-m MODULE]... + +usage() { + echo "Usage: $0 [options]" + echo + echo "Prepare elftoolchain sources for importing into NetBSD src." + echo + echo "Options:" + echo " -D Only show diffs." + echo " -d DISTDIR Set the 'dist' directory for the elftoolchain import." + echo " Defaults to './dist'." + echo " -h Display this help text." + echo " -m MODULE A subdirectory of the elftoolchain tree to be" + echo " imported, e.g. 'libelf', 'common', 'libdwarf', etc." + echo " -s SRCDIR The 'trunk' directory of an elftoolchain checkout." + echo " -v Be verbose." +} + +err() { + echo ERROR: "$@" 1>&2 + echo + usage + exit 1 +} + +## Parse options. +diff_only=NO +verbose=NO +options=":d:hs:m:vD" +while getopts "$options" var; do + case $var in + d) dstdir="$OPTARG";; + h) usage; exit 0;; + m) modules="$OPTARG $modules";; + s) srcdir="$OPTARG";; + v) verbose=YES;; + D) diff_only=YES;; + '?') err "Unknown option: '-$OPTARG'.";; + ':') err "Option '-$OPTARG' expects an argument.";; + esac + shift $((OPTIND - 1)) +done + +[ -n "${srcdir}" ] || err "Option -s must be specified." +[ -n "${modules}" ] || err "Option -m must be specified at least once." + +if [ -z "${dstdir}" ]; then + dstdir="./dist" +fi + +[ -d ${srcdir} ] || err "Missing source directory '$srcdir'." +[ -d ${dstdir} ] || err "Missing destination directory '$dstdir'." + +# Verify that the source modules exist. +for m in ${modules}; do + [ -d ${srcdir}/${m} ] || err "Missing source module '${srcdir}/${m}'" +done + +## Helpers. +rename_svn_id() { + sed -e '/\$Id:/ { + s/\$Id:/Id:/; + s/[ ]*\$// + }' +} + +handle_block_comment() { + sed -e '/^\/\*-/ { i\ +/* \$NetBSD\$ */\ + +}' +} + +transform_placeholders() { + sed -e \ +'/@ELFTC-DECLARE-DOWNSTREAM-VCSID@/ { +c \ +#if !defined(__RCSID)\ +#define __RCSID(ID) /**/\ +#endif /* !defined(__RCSID) */ +}' -e \ +'/@ELFTC-DEFINE-ELFTC-VCSID@/ { +c \ +#ifndef ELFTC_VCSID\ +#define ELFTC_VCSID(ID) /**/\ +#endif +}' -e \ +'/@ELFTC-USE-DOWNSTREAM-VCSID@/ { +c \ +__RCSID("$NetBSD$"); +}' -e \ +'/@ELFTC-INCLUDE-SYS-CDEFS@/ { +c \ +#include +}' +} + +# compare_and_move_or_diff filename generated_temp_file +compare_and_move_or_diff() { + local dstfile=${dstdir}/${1} + + egrep -v '\$NetBSD.*\$' ${2} > ${srccmptmp} + egrep -v '\$NetBSD.*\$' ${dstfile} > ${dstcmptmp} 2> /dev/null + + if cmp -s ${srccmptmp} ${dstcmptmp}; then + return 0 + fi + + if [ "${diff_only}" = YES ]; then + # Show the changes needed to update the destination. + if [ -f ${dstfile} ]; then + diff -u ${dstfile} ${2} + else + echo '--- new file' ${file} + diff -u /dev/null ${2} + fi + else + mv ${2} ${dstfile} || exit ${?} + changed_file="${1}" + fi +} + +# Manual pages need a CVS ID, and renaming of their SVN IDs. +handle_manual_page() { + echo '.\" $NetBSD$' > ${srctmp} + echo '.\"' >> ${srctmp} + rename_svn_id < ${srcdir}/${1} >> ${srctmp} + + compare_and_move_or_diff ${1} ${srctmp} +} + +# M4 files need a NetBSD RCS Id prepended, and any embedded +# VCS IDs transformed. +handle_m4_file() { + echo 'dnl $NetBSD$' > ${srctmp} + transform_placeholders < ${srcdir}/${1} | \ + rename_svn_id >> ${srctmp} + + compare_and_move_or_diff ${1} ${srctmp} +} + +# Regular files only need their SVN IDs renamed. +handle_regular_file() { + rename_svn_id < ${srcdir}/${1} > ${srctmp} + + compare_and_move_or_diff ${1} ${srctmp} +} + +# C sources need a NetBSD RCS Id prepended, the +# ELFTC macros and SVN ids transformed. +handle_c_source() { + handle_block_comment < ${srcdir}/${1} | \ + transform_placeholders | \ + rename_svn_id > ${srctmp} + + compare_and_move_or_diff ${1} ${srctmp} +} + +# Prepare temporary files. +get_temporary_file() { + mktemp -p ${TMPDIR:-/tmp} -t import-et.XXXXXX +} + +srctmp=`get_temporary_file` +srccmptmp=`get_temporary_file` +dstcmptmp=`get_temporary_file` + +trap "rm ${srctmp} ${srcmptmp} ${dstcmptmp};" 0 1 2 3 15 + +# For each module: +# - Create new directories in the destination. +# - For each file in the source directory. +# - Transform the source file to its imported content. +# - Ignore files that differ only in RCS +# - Display diffs or move changed files to the destination directory. + +for m in ${modules}; do + [ "$verbose" = YES ] && echo Examining module "'$m'". + + # Create any new directories under the destination root. + (cd "${srcdir}" && find "${m}" -depth -type d) | \ + while read dir; do + [ "${verbose}" = YES ] && echo "Creating '$dir'." + mkdir -p "${dstdir}/${dir}" + done + + # Import files, transforming them along the way. + (cd "${srcdir}" && find "${m}" -depth -type f $pattern) | \ + egrep -v '.o$|.a$|.po$|.so$|.swp$|*~$' | \ + while read file; do + changed_file='' # Set by 'compare_and_move_or_diff'. + + if [ "${diff_only}" = NO ]; then + [ "${verbose}" = YES ] && echo -n "Importing file '$file'" + fi + + case "${file##*/}" in + *.[0-9]) + handle_manual_page "${file}" + ;; + *.m4 ) + handle_m4_file "${file}" + ;; + Makefile | Version.map | *.m4 | *.mk) + handle_regular_file "${file}" + ;; + *.[ch]) + handle_c_source "${file}" + ;; + * ) error "Unsupported file: ${file}." + ;; + esac + + if [ "${diff_only}" = NO -a "${verbose}" = YES ]; then + if [ -n "${changed_file}" ]; then + echo '- changed.' + else + echo '- unchanged.' + fi + fi + done +done diff --git a/userspace/libpman/CMakeLists.txt b/userspace/libpman/CMakeLists.txt index e1799eb302..ae04064991 100644 --- a/userspace/libpman/CMakeLists.txt +++ b/userspace/libpman/CMakeLists.txt @@ -35,23 +35,17 @@ target_include_directories( $ # ppm_enum and tables $ # scap-stats struct ${ZLIB_INCLUDE} - ${LIBBPF_INCLUDE} ${MODERN_BPF_SKEL_DIR} - ${LIBELF_INCLUDE} ) target_link_libraries( - pman PUBLIC scap_event_schema scap_platform ${LIBBPF_LIB} ${LIBELF_LIB} ${ZLIB_LIB} + pman PUBLIC scap_event_schema scap_platform lbpf ${ZLIB_LIB} ) if(TARGET ProbeSkeleton) add_dependencies(pman ProbeSkeleton) endif() -if(USE_BUNDLED_LIBBPF) - add_dependencies(pman libbpf) -endif() - install( TARGETS pman ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" diff --git a/userspace/libscap/CMakeLists.txt b/userspace/libscap/CMakeLists.txt index 466a24864a..e4f826f321 100644 --- a/userspace/libscap/CMakeLists.txt +++ b/userspace/libscap/CMakeLists.txt @@ -170,14 +170,12 @@ if(HAS_ENGINE_KMOD) endif() if(HAS_ENGINE_BPF) - include(libelf) add_subdirectory(engine/bpf) target_link_libraries(scap PUBLIC scap_engine_bpf) target_include_directories(scap_engine_bpf PRIVATE ${PROJECT_BINARY_DIR}/driver/src) endif() if(HAS_ENGINE_MODERN_BPF) - include(libelf) add_subdirectory(engine/modern_bpf) target_link_libraries(scap PUBLIC scap_engine_modern_bpf) target_include_directories(scap_engine_modern_bpf PRIVATE ${PROJECT_BINARY_DIR}/driver/src) diff --git a/userspace/libscap/engine/bpf/CMakeLists.txt b/userspace/libscap/engine/bpf/CMakeLists.txt index 7e0e7ac22f..33ad99fe4f 100644 --- a/userspace/libscap/engine/bpf/CMakeLists.txt +++ b/userspace/libscap/engine/bpf/CMakeLists.txt @@ -13,11 +13,10 @@ # the License. # add_library(scap_engine_bpf scap_bpf.c attached_prog.c) -add_dependencies(scap_engine_bpf libelf zlib) +add_dependencies(scap_engine_bpf zlib) target_link_libraries( scap_engine_bpf PRIVATE scap_event_schema scap_platform scap_engine_util scap_error - ${LIBELF_LIB} ${ZLIB_LIB} + elf ${ZLIB_LIB} ) -target_include_directories(scap_engine_bpf PRIVATE ${LIBELF_INCLUDE}) set_scap_target_properties(scap_engine_bpf) diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 3f7ea6e586..f57ad1b362 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -706,7 +706,7 @@ static int32_t load_bpf_file(struct bpf_engine *handle) { handle->m_filepath); } - handle->elf = elf_begin(handle->program_fd, ELF_C_READ_MMAP_PRIVATE, NULL); + handle->elf = elf_begin(handle->program_fd, ELF_C_READ, NULL); if(!handle->elf) { scap_errprintf(handle->m_lasterr, 0, "can't read ELF format"); goto end;