From b91de7861c0a466f52d10d9b203f8374a1296224 Mon Sep 17 00:00:00 2001 From: Todd Fiala Date: Fri, 27 Jun 2014 16:52:49 +0000 Subject: [PATCH] Fix ObjectFileELF to determine architectures independent of host. Previously ObjectFileELF was simplifying and assuming the object file it was looking at was the same as the host architecture/triple. This would break attempts to run, say, lldb on MacOSX against lldb-gdbserver on Linux since the MacOSX lldb would say that the linux elf file was really an Apple MacOSX architecture. Chaos would ensue. This change allows the elf file to parse ELF notes for Linux, FreeBSD and NetBSD, and determine the OS appropriately from them. It also initializes the OS type from the ELF header OSABI if it is set (which it is for FreeBSD but not for Linux). Added a test with freebsd and linux images that verify that '(lldb) image list -t -A' prints out the expected architecture for each. llvm-svn: 211907 --- .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 328 ++++++++++++++++++--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 12 +- .../object-file/TestImageListMultiArchitecture.py | 41 +++ .../object-file/ls-freebsd-10.0-x86_64 | Bin 0 -> 30208 bytes .../object-file/sleep-ubuntu-14.04-x86_64 | Bin 0 -> 31296 bytes 5 files changed, 344 insertions(+), 37 deletions(-) create mode 100644 lldb/test/functionalities/object-file/TestImageListMultiArchitecture.py create mode 100755 lldb/test/functionalities/object-file/ls-freebsd-10.0-x86_64 create mode 100755 lldb/test/functionalities/object-file/sleep-ubuntu-14.04-x86_64 diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index bd733c8..b2119e3 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -41,6 +41,29 @@ using namespace elf; using namespace llvm::ELF; namespace { + +// ELF note owner definitions +const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; +const char *const LLDB_NT_OWNER_GNU = "GNU"; +const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; + +// ELF note type definitions +const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; +const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; + +const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; +const elf_word LLDB_NT_GNU_ABI_SIZE = 16; + +const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; + +const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01; +const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4; + +// GNU ABI note OS constants +const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; +const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; +const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; + //===----------------------------------------------------------------------===// /// @class ELFRelocation /// @brief Generic wrapper for ELFRel and ELFRela. @@ -448,6 +471,55 @@ ObjectFileELF::CalculateELFNotesSegmentsCRC32 (const ProgramHeaderColl& program_ return core_notes_crc; } +static const char* +OSABIAsCString (unsigned char osabi_byte) +{ +#define _MAKE_OSABI_CASE(x) case x: return #x + switch (osabi_byte) + { + _MAKE_OSABI_CASE(ELFOSABI_NONE); + _MAKE_OSABI_CASE(ELFOSABI_HPUX); + _MAKE_OSABI_CASE(ELFOSABI_NETBSD); + _MAKE_OSABI_CASE(ELFOSABI_GNU); + _MAKE_OSABI_CASE(ELFOSABI_HURD); + _MAKE_OSABI_CASE(ELFOSABI_SOLARIS); + _MAKE_OSABI_CASE(ELFOSABI_AIX); + _MAKE_OSABI_CASE(ELFOSABI_IRIX); + _MAKE_OSABI_CASE(ELFOSABI_FREEBSD); + _MAKE_OSABI_CASE(ELFOSABI_TRU64); + _MAKE_OSABI_CASE(ELFOSABI_MODESTO); + _MAKE_OSABI_CASE(ELFOSABI_OPENBSD); + _MAKE_OSABI_CASE(ELFOSABI_OPENVMS); + _MAKE_OSABI_CASE(ELFOSABI_NSK); + _MAKE_OSABI_CASE(ELFOSABI_AROS); + _MAKE_OSABI_CASE(ELFOSABI_FENIXOS); + _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI); + _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX); + _MAKE_OSABI_CASE(ELFOSABI_ARM); + _MAKE_OSABI_CASE(ELFOSABI_STANDALONE); + default: + return ""; + } +#undef _MAKE_OSABI_CASE +} + +static bool +GetOsFromOSABI (unsigned char osabi_byte, llvm::Triple::OSType &ostype) +{ + switch (osabi_byte) + { + case ELFOSABI_AIX: ostype = llvm::Triple::OSType::AIX; break; + case ELFOSABI_FREEBSD: ostype = llvm::Triple::OSType::FreeBSD; break; + case ELFOSABI_GNU: ostype = llvm::Triple::OSType::Linux; break; + case ELFOSABI_NETBSD: ostype = llvm::Triple::OSType::NetBSD; break; + case ELFOSABI_OPENBSD: ostype = llvm::Triple::OSType::OpenBSD; break; + case ELFOSABI_SOLARIS: ostype = llvm::Triple::OSType::Solaris; break; + default: + ostype = llvm::Triple::OSType::UnknownOS; + } + return ostype != llvm::Triple::OSType::UnknownOS; +} + size_t ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, lldb::DataBufferSP& data_sp, @@ -456,6 +528,8 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, lldb::offset_t length, lldb_private::ModuleSpecList &specs) { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); + const size_t initial_count = specs.GetSize(); if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) @@ -474,13 +548,22 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, LLDB_INVALID_CPUTYPE); if (spec.GetArchitecture().IsValid()) { - // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the - // machine information. However, this info isn't guaranteed to exist or be correct. Details: - // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html - // Instead of passing potentially incorrect information down the pipeline, grab - // the host information and use it. - spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString()); - spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString()); + llvm::Triple::OSType ostype; + // First try to determine the OS type from the OSABI field in the elf header. + + if (log) + log->Printf ("ObjectFileELF::%s file '%s' module OSABI: %s", __FUNCTION__, file.GetPath ().c_str (), OSABIAsCString (header.e_ident[EI_OSABI])); + if (GetOsFromOSABI (header.e_ident[EI_OSABI], ostype) && ostype != llvm::Triple::OSType::UnknownOS) + { + spec.GetArchitecture ().GetTriple ().setOS (ostype); + + // Also clear the vendor so we don't end up with situations like + // x86_64-apple-FreeBSD. + spec.GetArchitecture ().GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + + if (log) + log->Printf ("ObjectFileELF::%s file '%s' set ELF module OS type from ELF header OSABI.", __FUNCTION__, file.GetPath ().c_str ()); + } // Try to get the UUID from the section list. Usually that's at the end, so // map the file in if we don't have it already. @@ -495,8 +578,20 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, std::string gnu_debuglink_file; SectionHeaderColl section_headers; lldb_private::UUID &uuid = spec.GetUUID(); - GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc); + GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ()); + + // If the module vendor is not set and the module OS matches this host OS, set the module vendor to the host vendor. + llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple (); + if (spec_triple.getVendor () == llvm::Triple::VendorType::UnknownVendor) + { + const llvm::Triple &host_triple = Host::GetArchitecture ().GetTriple (); + if (spec_triple.getOS () == host_triple.getOS ()) + spec_triple.setVendor (host_triple.getVendor ()); + } + + if (log) + log->Printf ("ObjectFileELF::%s file '%s' module set to triple: %s (architecture %s)", __FUNCTION__, file.GetPath ().c_str (), spec_triple.getTriple ().c_str (), spec.GetArchitecture ().GetArchitectureName ()); if (!uuid.IsValid()) { @@ -596,15 +691,19 @@ ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, lldb::offset_t length) : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_header(), + m_uuid(), + m_gnu_debuglink_file(), + m_gnu_debuglink_crc(0), m_program_headers(), m_section_headers(), - m_filespec_ap() + m_dynamic_symbols(), + m_filespec_ap(), + m_entry_point_address(), + m_arch_spec() { if (file) m_file = *file; ::memset(&m_header, 0, sizeof(m_header)); - m_gnu_debuglink_crc = 0; - m_gnu_debuglink_file.clear(); } ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, @@ -613,9 +712,15 @@ ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, addr_t header_addr) : ObjectFile(module_sp, process_sp, LLDB_INVALID_ADDRESS, data_sp), m_header(), + m_uuid(), + m_gnu_debuglink_file(), + m_gnu_debuglink_crc(0), m_program_headers(), m_section_headers(), - m_filespec_ap() + m_dynamic_symbols(), + m_filespec_ap(), + m_entry_point_address(), + m_arch_spec() { ::memset(&m_header, 0, sizeof(m_header)); } @@ -963,35 +1068,168 @@ ObjectFileELF::ParseProgramHeaders() return GetProgramHeaderInfo(m_program_headers, m_data, m_header); } -static bool -ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid) +lldb_private::Error +ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid) { - // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id. - // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); + Error error; + lldb::offset_t offset = 0; - static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h while (true) { + // Parse the note header. If this fails, bail out. ELFNote note = ELFNote(); if (!note.Parse(data, &offset)) - return false; + { + // We're done. + return error; + } + + // If a tag processor handles the tag, it should set processed to true, and + // the loop will assume the tag processing has moved entirely past the note's payload. + // Otherwise, leave it false and the end of the loop will handle the offset properly. + bool processed = false; + + if (log) + log->Printf ("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, __FUNCTION__, note.n_name.c_str (), note.n_type); - // 16 bytes is UUID|MD5, 20 bytes is SHA1 - if (note.n_name == "GNU" && (note.n_type == g_gnu_build_id) && - (note.n_descsz == 16 || note.n_descsz == 20)) + // Process FreeBSD ELF notes. + if ((note.n_name == LLDB_NT_OWNER_FREEBSD) && + (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) && + (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) { - uint8_t uuidbuf[20]; - if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == NULL) - return false; - uuid.SetBytes (uuidbuf, note.n_descsz); - return true; + // We'll consume the payload below. + processed = true; + + // Pull out the min version info. + uint32_t version_info; + if (data.GetU32 (&offset, &version_info, 1) == nullptr) + { + error.SetErrorString ("failed to read FreeBSD ABI note payload"); + return error; + } + + // Convert the version info into a major/minor number. + const uint32_t version_major = version_info / 100000; + const uint32_t version_minor = (version_info / 1000) % 100; + + char os_name[32]; + snprintf (os_name, sizeof (os_name), "freebsd%" PRIu32 ".%" PRIu32, version_major, version_minor); + + // Set the elf OS version to FreeBSD. Also clear the vendor. + arch_spec.GetTriple ().setOSName (os_name); + arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + + if (log) + log->Printf ("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_major, version_minor, static_cast (version_info % 1000)); + } + // Process GNU ELF notes. + else if (note.n_name == LLDB_NT_OWNER_GNU) + { + switch (note.n_type) + { + case LLDB_NT_GNU_ABI_TAG: + if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) + { + // We'll consume the payload below. + processed = true; + + // Pull out the min OS version supporting the ABI. + uint32_t version_info[4]; + if (data.GetU32 (&offset, &version_info[0], note.n_descsz / 4) == nullptr) + { + error.SetErrorString ("failed to read GNU ABI note payload"); + return error; + } + + // Set the OS per the OS field. + switch (version_info[0]) + { + case LLDB_NT_GNU_ABI_OS_LINUX: + arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Linux); + arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + if (log) + log->Printf ("ObjectFileELF::%s detected Linux, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]); + // FIXME we have the minimal version number, we could be propagating that. version_info[1] = OS Major, version_info[2] = OS Minor, version_info[3] = Revision. + break; + case LLDB_NT_GNU_ABI_OS_HURD: + arch_spec.GetTriple ().setOS (llvm::Triple::OSType::UnknownOS); + arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + if (log) + log->Printf ("ObjectFileELF::%s detected Hurd (unsupported), min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]); + break; + case LLDB_NT_GNU_ABI_OS_SOLARIS: + arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Solaris); + arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + if (log) + log->Printf ("ObjectFileELF::%s detected Solaris, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]); + break; + default: + if (log) + log->Printf ("ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[0], version_info[1], version_info[2], version_info[3]); + break; + } + } + break; + + case LLDB_NT_GNU_BUILD_ID_TAG: + // Only bother processing this if we don't already have the uuid set. + if (!uuid.IsValid()) + { + // We'll consume the payload below. + processed = true; + + // 16 bytes is UUID|MD5, 20 bytes is SHA1 + if ((note.n_descsz == 16 || note.n_descsz == 20)) + { + uint8_t uuidbuf[20]; + if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == nullptr) + { + error.SetErrorString ("failed to read GNU_BUILD_ID note payload"); + return error; + } + + // Save the build id as the UUID for the module. + uuid.SetBytes (uuidbuf, note.n_descsz); + } + } + break; + } + } + // Process NetBSD ELF notes. + else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && + (note.n_type == LLDB_NT_NETBSD_ABI_TAG) && + (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) + { + + // We'll consume the payload below. + processed = true; + + // Pull out the min version info. + uint32_t version_info; + if (data.GetU32 (&offset, &version_info, 1) == nullptr) + { + error.SetErrorString ("failed to read NetBSD ABI note payload"); + return error; + } + + // Set the elf OS version to NetBSD. Also clear the vendor. + arch_spec.GetTriple ().setOS (llvm::Triple::OSType::NetBSD); + arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor); + + if (log) + log->Printf ("ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, __FUNCTION__, version_info); } - offset += llvm::RoundUpToAlignment(note.n_descsz, 4); + + if (!processed) + offset += llvm::RoundUpToAlignment(note.n_descsz, 4); } - return false; + + return error; } + //---------------------------------------------------------------------- // GetSectionHeaderInfo //---------------------------------------------------------------------- @@ -1001,8 +1239,18 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, const elf::ELFHeader &header, lldb_private::UUID &uuid, std::string &gnu_debuglink_file, - uint32_t &gnu_debuglink_crc) + uint32_t &gnu_debuglink_crc, + ArchSpec &arch_spec) { + // Only intialize the arch_spec to okay defaults if they're not already set. + // We'll refine this with note data as we parse the notes. + if (arch_spec.GetTriple ().getOS () == llvm::Triple::OSType::UnknownOS) + { + arch_spec.SetArchitecture (eArchTypeELF, header.e_machine, LLDB_INVALID_CPUTYPE); + arch_spec.GetTriple().setOSName (Host::GetOSString().GetCString()); + arch_spec.GetTriple().setVendorName(Host::GetVendorString().GetCString()); + } + // We have already parsed the section headers if (!section_headers.empty()) return section_headers.size(); @@ -1011,6 +1259,8 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, if (header.e_shnum == 0) return 0; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); + section_headers.resize(header.e_shnum); if (section_headers.size() != header.e_shnum) return 0; @@ -1063,12 +1313,19 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, } } - if (header.sh_type == SHT_NOTE && !uuid.IsValid()) + // Process ELF note section entries. + if (header.sh_type == SHT_NOTE) { + // Allow notes to refine module info. DataExtractor data; if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size)) { - ParseNoteGNUBuildID (data, uuid); + Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid); + if (error.Fail ()) + { + if (log) + log->Printf ("ObjectFileELF::%s ELF note processing failed: %s", __FUNCTION__, error.AsCString ()); + } } } } @@ -1114,7 +1371,7 @@ ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) size_t ObjectFileELF::ParseSectionHeaders() { - return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc); + return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec); } const ObjectFileELF::ELFSectionHeaderInfo * @@ -2312,9 +2569,10 @@ ObjectFileELF::GetArchitecture (ArchSpec &arch) if (!ParseHeader()) return false; - arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE); - arch.GetTriple().setOSName (Host::GetOSString().GetCString()); - arch.GetTriple().setVendorName(Host::GetVendorString().GetCString()); + // Allow elf notes to be parsed which may affect the detected architecture. + ParseSectionHeaders(); + + arch = m_arch_spec; return true; } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index ac7d38c..6b036af 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -17,6 +17,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Core/UUID.h" +#include "lldb/Core/ArchSpec.h" #include "ELFHeader.h" @@ -242,6 +243,9 @@ private: /// Cached value of the entry point for this module. lldb_private::Address m_entry_point_address; + /// The architecture detected from parsing elf file contents. + lldb_private::ArchSpec m_arch_spec; + /// Returns a 1 based index of the given section header. size_t SectionIndex(const SectionHeaderCollIter &I); @@ -273,14 +277,15 @@ private: size_t ParseSectionHeaders(); - /// Parses the elf section headers and returns the uuid, debug link name, crc. + /// Parses the elf section headers and returns the uuid, debug link name, crc, archspec. static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers, lldb_private::DataExtractor &data, const elf::ELFHeader &header, lldb_private::UUID &uuid, std::string &gnu_debuglink_file, - uint32_t &gnu_debuglink_crc); + uint32_t &gnu_debuglink_crc, + lldb_private::ArchSpec &arch_spec); /// Scans the dynamic section and locates all dependent modules (shared /// libraries) populating m_filespec_ap. This method will compute the @@ -407,6 +412,9 @@ private: unsigned PLTRelocationType(); + + static lldb_private::Error + RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid); }; #endif // #ifndef liblldb_ObjectFileELF_h_ diff --git a/lldb/test/functionalities/object-file/TestImageListMultiArchitecture.py b/lldb/test/functionalities/object-file/TestImageListMultiArchitecture.py new file mode 100644 index 0000000..23a9f2b --- /dev/null +++ b/lldb/test/functionalities/object-file/TestImageListMultiArchitecture.py @@ -0,0 +1,41 @@ +""" +Test lldb 'image list' on object files across multiple architectures. +This exercises classes like ObjectFileELF and their support for opening +foreign-architecture object files. +""" + +# import os +import os.path +import unittest2 +import lldb +from lldbtest import * +import lldbutil +import re + +class TestImageListMultiArchitecture(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def test_image_list_shows_multiple_architectures(self): + """Test that image list properly shows the correct architecture for a set of different architecture object files.""" + images = { + "ls-freebsd-10.0-x86_64": re.compile(r"x86_64-(unknown)?-freebsd10.0 x86_64"), + "sleep-ubuntu-14.04-x86_64": re.compile(r"x86_64-(unknown)?-linux x86_64"), + } + + for image_name in images: + file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), image_name)) + expected_triple_and_arch_regex = images[image_name] + + self.runCmd("file {}".format(file_name)) + self.match("image list -t -A", [expected_triple_and_arch_regex]) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/object-file/ls-freebsd-10.0-x86_64 b/lldb/test/functionalities/object-file/ls-freebsd-10.0-x86_64 new file mode 100755 index 0000000000000000000000000000000000000000..81605fc99073e0ae9abfd37f7194e1b00345ed14 GIT binary patch literal 30208 zcmchA3wRVowtr8^kPrwH-Vs3tNaP`e4Dtw%kr|j^4<;CS=_;6aNF*dN>4D(#2u{YO zX-BhOcdxtagX_9`b+5b2x{8QG5`q~}R?&4`uAs7r+T)<&3s8~y|4wz)q%(l--h01) z@%5ZKk2-bgRMn}f?xwRTH*bD|#nMaSDM7kMvLNpo?qU?<7ui~da$1g*EV-m%(&bW5 zP^`FIj6=}K3D`!;kOWLNP^kxCBIOe}A;D#2I2>ePl7L(dvyJNON-mx?;L!>L6;P7w zj6mhd)?=K1tfGj~1#Du*NYbgnjEo;U%aD0gE_o$G0gG5hK+!G%Mf*q{UFp1i=?N}i zgu4hx+3dFq^6I66_mwirHy0TK%|$Mj5pW83gn**l4Jb!;{89%D*O!;iUF?yr@z`Q?YL=iQE6u~T3|9`W6kKC*QL^Eh#d4D5 z1?-1wCa#6JvT#wl7S{+|vvDoOMJWTv827DEoEccM`7o zxUR+}lAC9Sb2uF^AJRl|uq!O!@dMjW-#WoinJ-gcF_o zupJ#dPs+vVZcvGyR`>^i2N`2leoy=p|D%DyBXVsewE6ArQ=T8t;@E z;^b*eQ#u|;f8QWWk7GcY_0$8W^s_kmU+@4hJdXalAuhcQXx1a_xjRn2l*`jNvh%zd z9Er1M6K8IU(=(pinH4AhD=z;BK(jq!OiYcFKh5P|iqkK~jWAW2(|^gR7*}!n#Tfq}PTtGqC&tMi&Qkg`&YtB4S-K*QF2>KAIJ(N^e++2W zzX@`bX2;1>e^5FaM;GJjbR1pOOYzUFe=`LFqyUA#_2i9<^K^! zzlYN^ZWX8_IZ67^1tvs2I?jH8RVu`Eu{I9~5hJ;db=swC}zousFL%L_fJT)v3gBjhWQ>4%*~ z8m9~SCwaZqoG$DfcnLkP@p^@Rq32Pi|1zmEPR}l`Uy8HyQBE(4qf6K?`;@9`+9=PE z3Ky&?TvWcYszE8QpI2Sn&`{nWRr*#J*Hqn6URdK>T~c081!_ut^_wQ&nGEBQ@02)mPOh6%r)N>+5Ul zrPalyg%#MGORLLQmsZwG#Y%0JR9mN1)s#tVi|cEos)k}kStqTks;;I|t82?3i$bWp zu%fEETtWu&#H%i^k?PBf%c`qtRuNw2t0Pcai=v_k;}urbR4Ii@b%Rv6q>@T3^3{~* z)s_|;>U>pYq^G*Nwp6O%23M@DuTsjThKADOnhIuFqf}E}SY2GRvZ|({Rw^#7F05)O zRO+kNR25ej*3?NW>uY^=Xj|>-!j(`+2GrG;*A>^7GrLi=q`X?Hsx4Kjr3$5?knE5u zDyoZDHYl|)TkaD};{9Mu#S*25Xfy1H`YjXr{K9V{SM)~#c; z6_>6mEUjEsSW#SsUMW}LDe@f|B3LVZ#r4!`=0$3}Qd_8$H!7^HrIl6HWoQlQtWc^j zLZ~gZb)cY1rl$-UvTb!qVM7UQU0tQnxG1h)$r`}MOfeLK4EstNFkGqJ+7e%d#LQu8 z!NS-h6A2W0$}5U})n*?SmX{SP#VA?Q0B1ry+*yvXHy@|PLPyrsBI6L5Y|O%h*uNe; zM>LV|;))z5I+II`l`}YkF64w}vnD|kG6syV&jQWHC2~TJ&UHPcTVa7%cmF*04jeZU zrA!uoBgMMU69#3!OJ7DPZ1|A<~- zqKmjrblF4~ah>R5kIL9Qo)KM~Z;3AAI?=Bq0#71-6FpxL0YzLS`ce~J=k2948A5R^ zoifo8T4U*~iOyYS@T!U!Bt0VL6Cv3|r@BQ-GttFfop|XcI_VP0Zla4df_P(1^j<<3 zFxy1$ZKCIx=yZ=jB$tUU_Ef}^O?2~_y}(4b2_=9xndo8+61&Jm7kd(-SDNVN{Y;&S zZa(`rn&@<17pciar+W+{Z86c!=Zh8-UEFV=G7p&OV$VkOZ6-S3iV|6R+(aMBD8|or z6P@nYh_us0r~5P_wVCKw2qNHq6MckqNkbYV@>pQ6MdYCZa2}#o9JUr^s7wtY!lsl4=l$- zpJPgXJEZ8;)7RUjXy#e`+D5pLBfOGIg^xv%GCv`lmZ|U| zhJQdfEl=S#hQC8NElc6;41bewT8_fo82$?3vsI_zuF8 z2`^&!9|-S7cmczIOLz+5E`~o$I4w8fY=-}wa9U=Eyq)382&ZKtyp7=t38&>D z+`{nrgwwJRZesW~gwt{mu4DK#!f6=@7co4Ga0>t70)}5nIEDSNi{V!gPT@YB&G5m5 zQ9}$!YQ1G z+Zg^1;S|Qh+Zp~Q;S|2Z+Zg@|;S{#REe!7@oWgauiQ#()r!XC^WB3lj#}Zz|@IMef zj_?A8|CVqH$6*)4A10i_a5$UcKPQ~RZ`jW8dkCkn8%|^RU4&;5E-`!~;gbkIb&mBv z;S^rO#~5BiIEB^lA%<5FPT@4%#_(GSr!X4c&hTY~Q}_&TWB5YCDQt#Y7(SnH3YXy~ zhF?QCg~@Oo!>18W;W1pq@GQb9EQSjhekI`)4#O^nUqLv9!EiRi2NO==FKlOcU&1Nu zh0_?`lW+=mVTs}A^MO;C3!nOy^*`Y*!jCch6T&I1g%2_O1Hvhsh1(eZ4&fBW!rK}C zCgBvm!rOoYN=s$+efN#-W$vZ!C5sEZ>bZPvN`|+zGe5X~Uz+T9zFcURBwtdV>fDQ* z7jY>!aC+kuua=l02ilaYBK;~TW!XkFlR8O`w#lk>4eE&`BHyw#x#{akO1Sxe@3Wos z%#jME$m$v0h6YBg`b_|WVGH~b8d|qq;gWP}?{h~hilm+NBahqfRbTYBe>cb5{;|_* zp=^)*z{iTiaU`yOE%9wu!hbfQzPCp`lc#==r+yPXBu6{)W<=`W{Q;$V!#B|=X&&P^ zLNQnVA$_qb^pOapYDn*incL+L^6%n;Zk5Vvhur?{9JxK>lr5C)5$Rna{0Bn=N0b3n z?Hkna=*zPItYytdkq>B1xMfB7uNY1(U5WH>wO)~DmzvuYTV%BCZ%>xhR4WKjrKO&` z&W<)%;CA1MPU}~|EGs%p{YB-`%}-xzmn5bCPS%C!qU2TyowXu*Y(+;`U6f<;+Kwg& z%33Rd72$p8D`CIE|B1oh!+_ekBK#jr1S8MjU*DLgxyQ=dvc{dXdgaZSJ9g914M{sO z#-ovbvgXZ}XDrCxWDqtatmyDNOIFxn;SgE7KzA;5%W)<-y4Sam*LUMTU*G4;slI{n ziVtIWT*QWUkZmKnw=dn?zVzm9r|lyZnak^|AJ$zOMHDV14~B z-oCS6U$lMy06D&WmFD(Uc5h!D+E>@DeUIL9ss0PFD!aGu_U`qu_MyJ6_WfXelUaQi z^k4eL+h^%s9~+-J=Jw@uZ=Vb8b9HOq-kUGgzTcd^aD4t0G?PDB`%qt3`+l&#MXbIH z+LyyByI_ut>|Wosjj|@ovG$=cvZ*ogWB$aM`1w7bm*@6gQ2v7Y{{t#mAffpmTW{pe zCvU=TQ&ykZ0{^SKpQO$S2HFUyft>)3=$_IdEC*!&^Asvt=|_L+t7sHa>ei5TECN>n z(GRVF*d5e*Fli2??@n%4 zdUO}-$6cqR(eO23xc#qK;EM2MCd00Tb>Jk8BIlpPd0tt()G zCHy6p-cW#i$m)*yHGG5^)@p84_#i|3#cW)O9Ho%;cAg7A!BkOyF++aIN+byd8c^6^ z@3g+Rlq&u)V?PNa3^k)-3ipv=Ack*ZB3*TU5ffHz5=%?P_9-KXEitX3PV|Drc;Fgyb?pS)UNs=qF^Pu#?Fh=W-Z_ z$WaPeYj`d^l!;syW3*y?2B#LFP~{n?t4x3mYyG<~ zSn#nme-7K(;M7w-qd4Uo(3*~MuOAfxuaUqQA{`)7a5wGNWwlfPCFHT)Gd99`!QWE| zY@GnXJoOX(W0F;^x52X3Nu2iI2JIfAP3E*04cbhiP35#d8MHM-%i*+#4BA}KXnUA0 z2cKc}Y2fQk1~ZeGe&<(Eg2}l;*8k?@ zRsB^r-vmS5>*=*u zOI?d>ua`Vp>NI3LyW% z4oFJ2pY08_+3s&kK4ja`*6XZWebK%7FHMpp`FFDr?Xh`uPp@`QuLFw5znjHxU$z|F zaBxr4h9XJtKsUh`5>(0Re!2ZDHuL&)*+SV~=%No%X{5Itvc823dBDG$Ee^g>{@pCr zE3^E&S*Ta$Lh7*_>{9kSgnEVB^hY>>0tA(sav zfeH~a2gp|isC*=l$v|`<1*3pu0yzRiB2GGxSAZNNgdEWhqzz($BfiW1&K*!E`9|ah zPWZ-v`6QU9=5rm70CCOWI_?9KJ&WrI0NI}F!nq?r({UD?gT6j&rtNXzzFH(z+fDOT z)}EnB>QO(^>E4oUhjST<>Z>v0*!d;4|0r;)e^)oW;b_}ckmZuLrVfQz^8wkGdk7~~ zk9uBz>tr;FgD1{|wq^>EdFrQ*)B3=VQ3r;9s)Hu2NBu^>5}mx&`WEiqG`HCTen=wD zZnf@b1mAU<^)+b59CPQY=iL4i$?ooJKlDkCt-n}h=$N1GH}G!oQk@%d6m)q{*eIfYo32|F}p}2FaSg3GHvn z$@29&ZJj~dl-4Gvmoh$&tW6zpjUA)saolu}e9N@?eS&gSUDzkkwsEPf^^}9MMOOQE zN-2>7S^G0-YR!j{Fz?SWI9!jl*uUY8g!Q?y_Ty~50j_Snm*#WeQ!@TNXthMfwWgq) zz6b>(DMo$`*sO#*R$?(oXqZR+K;Ic5k9W%IyLswqa_!3~ztu`Ng2=VsVbRMEoVGR7 zQja3C`p&LIs-XZq6@C{){R7nH&yjp~c3^fdcdu~Y>MmT-VT==x(Skpr8iR1VLD&WY z?T3u>=^X9)N=KXj>m+5KtWDFFRr+5$;21Gn#%+@=||2{Z?hDRt+z>6Y# zQ&+aKD=T+p>v%R4@WgU1!44b=1!fB*6e!|ZTk{hb_@1q^a+{;J=7*3+zv=IPg!+T) zr3C%DFzZa#VLsd@b~i<5`ue#$=O;)N?oiL{ncm?1gh-#gUJ`Nx<11$t4cOsdC|5m4hIPANXE`7T z`>1mCCEu536Qc)YHOShmu{O(r0~@p1;EucBW@(dyiA^%(0|z#JW^P(^KXyyhP-X`; zQx&Nf(c;!T8I}ICNeB#QQ+#f(_FzU6inz7) z89DkbAM(JCFl7YxbvkB5$di#y{m^OM?Zr?D--QS!?w`qi76K&SFzf?;j?>m=67h|V z6$;-3X|LAIs-e)1P0p<(V{2Z93Fw7AvOJ5;_cclA02D+2N`<`KH|zY9w3p2iULWL%h+e%`boy_2x#>N*T8{KM^z$gOQm17=09AU>kk(_jIV z>Q_TlW0P5)v42fZmBl)kl}v^rq748anUzYKg-K;wuco+5gw5tj@LC`9F{&qyTDwFc}O zi{|^Ccfv1llna9hYo%9x8{um#B=ud;gA=_Rd}upR-zXXl$zJXLj3$(mwYu!qzZsG0 zwG&t_+d=gD*Joe>o8Z;%HiY0s3yj-UV+b}vW8~_t(f1bBNm}#y5X6n7vE+JI=sly* zJZg^i44LHLO>+rhiTwC7DMLVgS1*P~>GnjrtTD?GhO?;wGu~r#-|$OXJ_MHYLV9oN zNsXuet$_e1=AjeiF^OF1S8xB#3C$JNgmU?jUuV?OAtn zs^pTSOz9N;FOnjJ=8>9rpd;!yy(?_EX&5Y32?tQIZe0;@Qe$)^r<$yZ4yJVuc!bl9e1sC6y~Q)|tVA=yU(|yWjmzw*B!X zxjj76(yj)nlQCJzRnb8^=h?9a?82|b?|jrll@5>CyRWZaZIfN^fq{~*Z9>mPeV<@2 zIRr)IS-FRNQ{>J2Xa{*q{5JQ1(YTk6iEZvr48n6D=*?(_c&fwpqstb1)$?BMiiovE z)^16oCs3t0L!?`jQ*Lcpx?5XAQ(P~Ss0XKp9dv4_pG)@I&8LPD-A)apDe^Sm|NjFM z|1rM*#}sG02X1lSO3$Jw#qMWz+aKe3_qi=cBR$;eQQTGZJ3ptkD5+Sy zHYDrgld=4$A+N@sUTM~zP}bYJ1iwm>{@qYXiVX5Q_puU5`tZTPt@@e)7(FoK2}XA0 z2BOLYS#y2}bPpznw5ur}(Z3qb2lYR?Qc_&x$#8KZ5awdX>++e;T2Etm;Vg{#l=KdbRi?t$d^g5s zDA0tP?QjC*AKH#=xBjL|(y@100?B-Ani~Dilc)_(-rU-aiEhm|R&@0r-ln-Zk1=7z zwbaoYfpv8>q|;ev8$G=N1>nq0$yi)kP_I4#T~F&uqwQHadGkLgFmL`^LS?q*pP`qK zFQU9^w7uqeCfR6QcI^3o`_`r;9@x#V$3Q{nql1x z{mKT_x(+a8ZNM)jOujuXKz%4=aXcT;X&vK2)CgH`fCNmDBFonG)lY)!&lzkB{2mm) zGlxq1oK$!g6@DB3FbaP(2b_>~peTIVx)lA7MqwXr3q>b_ZEN0)Lbe^&JrE8mQUXPQ znGj-oS-Sb)OKPP}LS%tg#chjs;pJxX@-$|nZ>WDap?G(oGw@4fuA=g99feCKQ0@?N ztT>MOkz|&GVvL{ZV3^`Tu9iCmop^nUTg%PB%*RG$IW1bfWvu~gu9A_gCT6szVutfx zhKlARG*W&+jid*-i_AVJo^McQ`Vd?N)=65b5+=m;Q?JP3@3&q$-zZQV> zND6){BZ>IU(Pt&lSV$uwC5=r7UG9Ns#b%{A1!z_~1bSO*@Qag&^L-~NAF4mx7eg!E z9G~@X5ls;BGWwC)=SYrjX0j=+Oh$D30whz+YlKHZ{e5?838;AG!9zNTB|?LeVpw<= zEM)z_c25;fX`3x@T>9ZD_Yz$7PfWRALkvBGp|^`(&ejL~H$037VcA}s)3o8qv+a`p z2u##+^asFVqF?NJ0{w%YGBzb`php(TrEQ(fR_YR|bqClK|G>cgKB(wz9f79#2Kb#n z2PXLj(m6B_2bjoE$~`p@xirchwqc@)_h+=J>UcZc(tj3}`JVMPl0oNZV@>^>tQlzJ z2h#+Kji0U^-F?_7BFrC|X*c!`{jqnT=x^FP=(oW!-Nzr_AK>-GIuw4G3ah!gtZvxi zcODrB6W3kVIs-kUUw;^Ty__=KRL3oK)!GIg3Ixy!+M4%uMD^XwmDYM9X~Q+fIpV|3 z>c3M{l|j$H4iEaB0n+O8JpT?bydk44-698{l0N$sad;Ieozb~*2=+W6$TRkC=(F=9 z$UXlB38(BlNBN$ZY5}^7dl+}@x9F$e#P&YuYk{Zt6u?rW3-w8VCwEL829?wY5)BD$ zYAVoH)Gz5H7~lHj3{*KQSNHY8I$XzgEV>5`5&cE}SzMr=Rolga5^a^FwPQAa9eo5a z3$PGy4i=X*G;+SN;P`S|@!VUAtOMGH)-GhvNg}ra-3D}y=~4H$xNjD@1&ksvu56`X z5}C`MqeNzb>H;3s=`yA{GxWVGYR<6dRV>3zvcQY!_UNWatj5|K})ytNfW zUebRJQC1D#VXWwIL?dA~gd)eg#t*em{n}`o-|0mEBaArOjGAqMxmbK6XjF6#8aW zGMhw{ey!ud)@Ng6vRi5^Ixe)O1rlak#z)>@4$-G!qDA(b3s~WjjrC?>XXHOG5I|G9 z{N;+=#X3XRG0ekjaT>WmevVl_GrSlwhS|?h5f7o{O8vKlP9@Yu=)V(sC86X3eG8#O zfb#blV*C3gbmqv{u3>lGk})Lk#02|OuYXgz#n;R052c04*Iwf#Gri>v?2<|k%9i$> zSkOo;P4Xq+6l!VLtYb3m2nOx-coH%7I^_M%H>TRrHN#Ae+K7JYYJUpWTlQpPC-jOZ z6Gzb>utFSp=+4k;JO))eusvrL<_9;WDYn)zg)Gt!|0`CFjszSc^0hhCjKCbU6A!hN z*|4J{gY3v7JCy#cE()~tBqHoVoo34hce6~0b#yN@2gY5nfA^mp>s9dr3QcUkbLBLu ztf!kTzuwZdX|twIgcTddV*xIMA#(c%J@jW$IlBe*8~D+!U7x0=CPN5ME!`0DYDo^< zdClJ+Nio)ES##k$*rtq>{f%@UL_FRvm%fg@cYo5TCcYNkE2~TQN8WU6*ADbMCovn6 zp?E9~U=}U)-yjw^pn!5?deD<*@mNk_-vA;#gthH>%hKUdPvxp#ojHuN$HsND*nS!HFqB@CA*SfSCOPl=$%>uok|7{ z26Q|rC*$Y@7=Jved<`ACqAgF|u+zU`pJcn|UJN})8#@LLA* z7zzR7T@%LF?tPOTtas~fA2$HQVR z^@SaMSSZo;CHNae3aw3llHrnJ#YTUmpJ&#FH#YQ*sIm7`nI&%%*><-?!(Batn%^8r<`lvx z+`=$bzj0Vs&GaB~NQ*J+=2E5nd0+)<)^eYYw#~}jXA7)3kKyUxH`cT(aYV7LvLB+` zcX6!nHF$7%k^PEzpBcNBvCq@aTMk6AA9z3A-C!~TR|hM0G7HM^Gx=-+|_! z6lPj@3u8CqSCYVQ1%Hsg1I<}+PBe$)BBfgH!5P*yBhaF0<`%ULGg<^Miv~^2zGQ>? zvIeoUX5VvxmI?7yIDdb-e7J;P#)xdHM|AK8hQZ=KY_0*J~ihDFoQ*7Y&!MTs11?$Q8VpFpy90*Je7F&FE~4Ig}2m@M?Fm&&G12B zVt*+Ihq*S-euxGsB?W7S^KqfcxV@ALUE08hwn4=IO;pK*#5Ith=O0i+!LmP|HJHw3 zM^PmTJjM%Lg#x)of!E1Y6u@IpQvr4-YDM@rC}w0kD){^0Q~!oR<#*niWrt}=dMP9# z-NI0R+M@JyHAPc=NxA}aBB@=G0WrzZwxXl!eOUj=G}o35xKZje9@4Y0ss9B=(QW5_ zX{MLbWBUpE{|mUEMS&AbBF6ORxQjuv*LGu@ZCoy0+i`8f)q<W zgxgJXAd;*-Bm=i}s0`wkZ644(_57}$r~uD_Nm{>!Ji%YY*oRps`@cPJYu;<*@G$WN zWCKSw*1FYq^3`*!eeSJ^8MYl~5i=jfsP#LqqI)gAaoWN@!5gCLvOai-I$_qru^W?S zr}#!=JnGk?)sf6te9@B*0v{B^Wv#Cqya7>c@D__Vy3ZYb#rL4s@~&L^5E(3Q{+6Oa zeJ=#PD_){bfn$DpnO(y4>B9p;BKyw)eZi2(V}UlW&GVwHc@Ddtp#QpTYmOo$JKE@F zlMj*O8gGZjg9k9Te~LE#D=v0#P2%mpoV9-f+HW}9S7`P^F?k^oUbsp3&~RD-1OJ|W z3Crh0OPuA>G2dXcFi~pP`$hMMC%|<5Wpcs5cKwR*a9U@ozq$%l&B{OIqw_P3Hq%O_kAM05*CR1L>3-`XQuHs5Pb^fCIo;N$ zf64XHPH*(Z*jWCg+gQFAzVWL2y#8|-!XvTqqQ^kZCCGpj^<9e*dkO=`?_7u56L{Io zw94}{8GYibYf^VgbHau2BwL=l*3-OFHj})YqikT>J=kP7hv4vQF{C|MH|D^l`Y0M% zBT>2qj{3*oi}X6JS_QBKz5X0uwb~bGp0mcF_2J$2scvTOOXFa!EpPy8FEn}d1tt#z z#k~GwJHK&FF1;fVVfJn9VT|4r7>a)9YEtgI$~Tnp0yjbX8!aQ#$mtnS0Jm9k>(gSlO-}1iO(i#2>);^<--RP7SqDDKz z&(eyhO?_twd12*PcmW#))^#h%s;kVdW?N8Ow~>Lp9}~U}DxnTWd!U0o(i(*0z(r=( zA*iMO>BZu`tbPj(38dj)pHK8M*=aZ+uk<`-7v8z0$R0`dMmzH??^U$$*@Ao1_+Mms zYFMZCVV>|gUakLE<~zod*Wa1wjlRmZWe#ds-?_oW-7r?dtxKG_xaf8u`;&k(ZlBrg`vy06WxFH%3f==FbhUYW^{ z#QyK1%3Ss`=hwKw+VWEA`YE`F*-QF*_&-cC zRHibOKW8d4E>L+{m))dt0PRoK8v3?zeQv078@k#DkPj9xU1KlMW$)7Efvz$9d_X}i zgH#Tt+yZE23rN>_jAG;~w!r;Zsy#h^Lml8zkKrW->VQaM3lQpZTk}A+a(#zg*b|6V z`Ib*HRM`KL#*n`^?GiKb{Ai3}(~4r=2Hl5_@qarC&j(p%xvjYgncTp~8-J9meu7aT zmWBiUsojg9iVnl3jolEjrRl5RP8~czpNX*+>0{oAur=Tn-=8(Me>1jS^bI#-+hx1+ zebk9TdP5rqDZTsacb1cb^VLsm&9|VTo4<`hg3zDj0k!S{prm zRYnlMjM@7rZXVDpDqU{@8}|;n-8Nf}+h%NlZiXfVahCrLx@+q^i)|0>Y7h3K#xG^c zF4cI2`geftBpuxv@5YG>9T=X;c4t<-Z?|shW06bo+|gLbmY{}9EM)yNV+)zbaxDBY zT8ZV1vd597h@n~kHWJ0@4GJtb#}M==jF~rb#juUde~NclH@|{>>kv3{PaY(V^N6z* zD|h! zs31xQl=76F=`wOZ0FPz-b8^xT==q=WH(qJfzkut%jl(iZeT|G;60!@tJK2|JEo zf-d-<$MLP)j(!}D=WqsxqTKR0T+mltf-d-%f_Lz8TRHqahlk?yy~lAYxBF9$pO2GE z9b@?ON)BgocmszkIIQL{z~N6h+{WP_Io!{ous_1_zGIDg#&I}kqJdX%cxr-yzrdlu z1r+orvJJVXIc(+dB@W-<@Es0y4!_{=JcskH&s&uAF&U-;S7>4P9UBgM}!6qt~-UUMxO!mpxOmXWr(sL$bPz{jz-5PZbewGqI|Db}7?` z&v%J$vE| z``Cu^a=TJlZpQ~9eWnA z*p^bw{6{`ak?a$%u}kHR6^*5hWsN0`>A!#R~HDc}aU# zR@RCX$()uiA2lkeIJu-xMM_O-eJ`c=8r;0UyvM9;ECiVleBlM`2$3JQ2d`xUo&>xf zun!iCrvWDbz5)0k;Fmw|#n@tpfhz$XC*CgS_W$50ON z+&`kx<%A!PM%M#Qct09_5U~1#XmlUo-Qj5TB;YyxKbe76*mn~40-gh;cenCBhP{C6 z0q+MKb}AZu0k9em&`toJ{4yHtgL`L3zeYL0f!wK0$~E{u;$>CXVa<$L%Z@Q-~D zzYP3rjI&GWZw9~Vd-#ume+c}XOSK>TQ{d0K2tNa~6X2&|Ja0+{BK%j-y&p-g55{pN zZi@^9jLBW3zo&p-gc}`25R1uC9*OiU0e>6#TWHE&qCV=^^^i;c8}`b`$K>Yu6Ys&u zAw3U*-w6Il*dOCx#GZYSYrwij$)je>$}#l zhxikS|8_L`Ch{>org5GJ{!Q=TjEeeVe3C^XJF3Cof_d)juD|EqvDswE-4D5Khy(or zV|wy0?5`KVf8azk%Dyxv{2V7ocAtRUF~pA|9b7$#hC`f{TFk)%j>G!JUaN0uoGTDLd80APsR!cB_j)v1;P~>9N$?0Qf?- zkp^)n02h-ERTeQ4bs42bu2`%WNd{RO!eK#w7t0BHQ9lExkVEN|0i<3Wiu%t-jrQ2N zJp9VqC;W%yi{W)?E?)Bg4@h2FbkT}F=lzs$nTzrJb2y5_$sEq*a1nJoXg=N4of(!=kQJr@8j@M4xi$1FNd#lc$~w}IZPPF>*sJ3hm$#+ z%i$spOE|3O@J7V=WrB`TOe$Sn$LyM%1JAMclByhdVCIymGaYCzzAL}-`@F~%RX1=w zQ?k4C%pkuxX3U&A?Phx&zKLG{Pbgv^!2dte#s2I78zb2>s1NxVnP$(PJacOH%&T*5 zwxh%A%h!INT^9_ynt#gkQdUDHJ~yuvmq=Oo8wBO}x_nkmtx}$)6t9%BR@V5kDvKK` zrL3}bH4W=l8xUXNXPh-S9#_@YbVCZk!-OcN0z6k&t&nbfl0J)l>OQLi2za&Z8}nJ^ zmH3=L{v1MKWf{r}Ov<8r4GpN!0JoKb37y5Ot4dK}EtKIWi|ID>;8XP|gh@hwec^wf zXkDf?Ppr36f(sZDC&aJQVtq7(jK9N0Yp*Dup5S6E@pt308P@e9_7#FM5*gY{i1K2; zA#*}Chho1W)^(w0ILe;JS}n?p{mD))P{u2YFVD%+7-Yx?qP*C@*m;38ULkEmsO_Tu zbmS>b!bN)*QC{qaviXKe?0-m>QoR4BgGPG~QC{pf>e86F^rQh|`z;|Spa*=~%LrWT zXYBoqf-YV@-hNJI-{>b-iSlCqRK&}R{ZqXEMEh5uthv0{j}`PcY7qN3Do=aPc>k>g zjeH{Zk77T%pI1Q7EzF7PGN%$C=JH4RKItegUldnBpxnLE>bUZ;zZ*#d3u%kffZ|t_ z6L|(6_HyaXt4G{Yk^$Wr}WT?FG|1neEDs0*nt#(>orLjU zV|S3UiJNgySwD9^W_0Is9d?G<@h}k;IuHr?Zv#4rq7o6c3Q!R>AR@iL`|4G95$Qd% z-*@)x`OcvqwO9n>vI;*F2wQi7lacgKL2w2b%4tQy z2*D|g6)qNrfs%ngC#xZ-mkfBEi#DK*^Q8f%E>I6o(lYro6pGnBO7s@`7YpA^HR-Iwhtxi@jU=5dNK%?EQXh(Yfy;nA8oXh)5 zWtSs-d$<)Fr4KYIY?liQ1?PM%tr7iiAAhK-x#6K}~a^I1=Z9dm$@ z&SUULK0x)ZvCr)s6I|8t(3rt_pS;{U;?K{ndXVa-;*Vs|xQ6X;38E!uG|_&Fzv=j! zc*&}#UXp@-VTyh~Nx|Qif`38^`X?#qKctX9JcYk)OTqtP3i&f3M?{;U*JUaA zA5KA^oPs_Qg3sii?iBoQr{MRc;18$Z?@7UbWeWZaQ_!nZ(6^?LFQk~4sVV4>rjY-u z6!Ozk&zir_^;g&Vg_`Q6K3Vp)%R*CC zQ*)rf=W7vset)wc@&a;I_1z?{qPD8OL8uS3u^t4!uc`skg{mdZep#sSwb#o+i@$lP zzpAmKzNr=c%Jt1n6-`x*K1ivSm$mpR&`U+*l8Wk}zoN0KU4UvN0a`TpnuK5zs;h-2 zUz?${uMs0aW2n;9TtQS4DKz>TX$%z=wdS$PHO)a;XbAXxcQXzcqqe%CIe@|I-83!< z)HgxNii%)uLvx$Z)KJk-)wHy}skS+x;1cRZfF8c4R_XwQtf_BW3KeUhgisr(u4<~K zdKeI_sHv@o?#)7No4;PBf!4P8npl%F*dkB|Q|T6|t!W0MumrO}cCTq}tg3IKX`yat zF4+KSmT3aeiq)e+Zmy|lfFc+sdTj~Hfr?-gl)l?nBS2kJfqLdQSlWpB(WO@iC0@^rnHAUMU7J^!C>JD)$TB|@gL@(r{P@2#6D^&U%@i{~ z<*{a5FAqD7rei;rKzUIH%Z-dYPQI{y1Z7Hdu`Y?W`d5!5ZORbt65g&+tgNbg$2cl0i(Q{fV88#fB2qlS2G|~BxSY57(PC2G=<(ue6Y@)g%6P@}t zE~kl3HZm^BL?@k$tIR|oF6=EqMv8tUvHw*y@7Fco9I6=h=4H@ z{d^OByNP~*iQaFb(>;iB?J?0QM=-7d6a6BC2&kIq7n|ruOmyR(m8y@M=$DxIg58U7yO6#BF>hVLSr zLZ0Si_^X6dsMGQpzJ+iKahk~Rjf7KZ)3O=vHt?Z_z*#{Z6R3Srs+ z!=EIaLYLOh@J9(BO?Zsq4-xg&2Mp;S`Fr z7KSe&oI;RR$?%^OPN7FDWB6RcDdcEQhTlXug&HlN;WG#yOSs7J>j|gOqGdDu8p0{0 zXad8pBK$JKkNiO6A4j-I_yEH%BAh~p*3a7%gW1nR};bJJ5L zKp(+}It@DMB`cMLi$PlnZN1S97X%l?TraH6aSAUy4Cal0#D}DO;Z{DA`rHn-?NY(^ zJkk5o9Wj#lFuIvl5G&ZRkvi4c)$tG>J|34dH`B^iH())x!Y3{ENC)s}MlHH>75Ca7 zc@n5p-G8i~SgkXjJvJi;EQTrV|N9_xsloZ}-^A>-6)P61yd&fPnr!(@oJu(gj z)>V%B5ZtjN7QC+@u8xAwhfXw-JQw82e+``o$Tyv)zq$vjX=4UDk(5_9eE=Jx-Sgka zHUd`Wqa%|k&Qua&X14qirJ$*63jT!Ij>6%HP&-oLGdJ&?&NshPsMt`L+Uz%J5Acc=-Ny;Z} z*2P=9$;PyCe6x5nRmBIm-Ma}h_iy7q@wSZfL9%?kmG&PgJpI}EV303Os4!;!X0Zv{DWAmq7i;&R ziTyG`3+Qk@GwM9$d)n|i;!w1)NEr``f?ER>(ZVoyVo`bQYS zq^gZnc#cUlo2U-L*ye|34b+SdKTXYIq)6aL%?i-$&|^tgWa|fR@xwex`I_f184yQ$ z7D>^ce0MvQcgbTYjggcOCFRS7i?u_?m_JAzd$Af~@^Jc;l>n;o_}b1-mv)mtdyN z*x}SUOoxp15OnB|`g)a=>3;?a-;2Nyg5X>^{U6Qve2Ux1q^8dVRsG^}3MBG*q3Hpj zf_%9;3f+f`#NY*Bk%;9r#uB`VD`2ep8=-{S3})~-!6zwOrH;6qr;a>d0P>2ub&w)~ zN7(}p+;}s%*;2m*a~7RG=Qar50tWS;7?-5HyK#=easq=owAawzzTpB%IUYJOC3r5g zrxcD^5L-czzfpFw7!uhbJ27~Dyi#}z>N7#RDD>SFS#(AQ*X7NyA?&tOn)t31 z{%+X)*i>6iY|imu=ciQp>)!__zCbHiQg&|^LH+volJb_*{=_!>qdm@|H-jUk&IRd` za>;$=B6u#@t%D~37H*ZI=llkRjXy?C>p@N8lNQGP!a;bp*ZU+9~ zW4+Q=b>r9OE?s&+r?lxCNjXK~pa2%a8dM9Qn^de~<;dsiAz%-mP3WnHvB2Tz;r;tU zC*}ti*f*3}Sh+k{h_aQHX9sgb?P-&P<3jD}MZvM5_6#9-e&~kE?rUMf7ajPJ?Cw2> zeg}CkP6mdQXn6P4j67@4p(yQ7p%W#+j}yXY1m6j@TML3aA+{*^8pP%YUxC1D@hlm_< zkdnYk2oefR@dgZ~%2x%Smnt8YDr)$M1@emQ8_7g{?2q->BZrZ#hVDgo_Q*#l-qh(nNAMK)*&lohSZU`ZIFRh9^eV4nsg`*$ z63MH4N$b|Beuc4h#AwAjz3?&#g))1`A9R7&3ighC%5q;sXQuvV**EwwB`5E>a;D`@smCfOLCgH881jmX&l|@emMK=-yn* zjll;XsZi*=WnbvKOWOP!sZ;5#{l~WS+$t2wOE5xG=zoLkE&e(%LW*L7x20cpqtrRi z;wj$UnyFLVms!Sv1nDM{l}Kr)kZc-_BFeCiYW%dob-Wupgev7`$FWO{E}T zBSp)x4{WevPq>oiFjt!RUeaGY#d}-RR;FJ_y4W|QUlfT24||LEO3EI4_;E5a+yly9 zDrhT#)po(>ED6`EfG?0r`uOWfs&hy6W#?7C zbCX-JDe@v&#GMxU!tQ~Tgd!j+TU_Cfejv=IUW7zbiayU)V2yNbAzPC6junXG*pq0P z>ru>gr>kOXSGOMoU8Tqr-F0a#Ool!#rI#HEuzj?93HT0u)YV-}@ZH4z+}%p}jwIeh zI3+s~6a=ALCj2)E9OEVVKgryX^aA_S76BQ#?a3*L4k93q;aib6`6{jX!n*utspIhYkbiXFx> z4mZ2@NGDCQMYV5$TQjFU)T)oq8Hw9F{tE3$<@9ao7eciFEIHU}cPpPdV_yslZ_9VC zlrMyZ1F+y=>u8;x7XEZNud=$r2ZodSu5fQYEkNvo_7$z@k_p8kybxgw3k7Q;vMacX zR`H%>f1u7P*n4Q3VQ-2&pQlsE-D{8hD}o-MGB|>Zmn-`NODj%vZAdyi%+|2fE%xsJLEC_60qXk)4u$MVfa3Teo7Cq2h!sd+j zJH(Q}(D))n8ys~cy$H7)>Z^w^)k=e-(xYr+ijwFe?Q5jrX8niSQr92eCTQCktFAw7 zX_y^NW@B<xss0IZnN1U=WluRmAi7sRA-fev4>NB#;0knLkD|57iVvPbA~zrKb`*@_L$ruzZe$u>T=V)*?67S*&1 zI_Laz=)23?F2qf&wE1duM`n@U`c&#TW$$>7%D5|$iVp^NMs;=6#}1=^=(Zk}9WhE~ z1h?HiAXyHnccH2yW{*rkOu^D|+c)SVMM1X;_6C|ktYF<5QdGB^7h6S{a@32B(Mg%h zQEYCzApRFYAA8=BINKVfot6v4*kr54A?ZUNC`SnS|+J6J{lSfFD4)Gc?z&d?q=pEpq`~ zz*7)Vs+?emSHXGK9@eR8ZW29vijO5E8ftM>bRTcM!WFt+2-*)_%;Fl-F6=^b7TxdS z05Stf<2!8!S>M`tZq%V>!%~}$`z_UmDLRwUQGW^QYjGuRiCnjPtK+WQT=OYYmyoIB z{)lDfl2VS_ydOS|$34m`QDIgGrg!}A*`k2yF0`+_8%xD~!}Je8@cUey%@&vP1(~4d z({#`BlOhh)ke`AF_lWP}VTBaE?ss6tt>)7J9;H`OG87^xxN&N?MW?R@;#H0!hE6;o z^?a5t_3TggT0T?PeTLvSxs|n@neRbO^zQUh%Sm@M&D(j8tu#8;Q3}7e@l0iAZukw0 zo@F5nh%UOF{m`pSb9j|wEPY{NPrVKIXe`Wminq4ijeAjxXZfiZl=div4tX?VmK{av zho8VhARd7d&582TC;?2!gAgsH=*)cR!Ma0F6nI3&%{xQpG&7ev*Au6Ykk2DP6}psJ z2nfAcI7dvG5|1Zdq% z*i?i-qV9pg-O3dtoDOBW8H0URUsOOo#t z^nROi{4KR$3+}9t8oaf?;DmCUZL8UTjP|(EJRU7cSK894I_Y0@r>F-_ zmhxyi`#MKb+Hfa$JJJ9=%2V$@pu1Xodi!+Vy;8|Y%OoPn{n-8Q^@S1c7W>B5|6~z)CO-t@+b0YBm zUAK9ZLF)VmI_r5mxl}rKQ2#hRf9qpfDX?*A#{s8(^(!OqPWN`svw4-TkWv>6!ez#i zRs{&2<&J!E7m&DzjL|)WGGp51X0qg{$SWP{=%-x;V4A zMu>yYjfGM!Ww<L`dTT-=utL>ZApfH&86y}(Osk}CAPSUF{GQV`cNsV))!B;}}Hube{N7nB#CCXb!!vD0{j#n052KgTGPk8nVy z?2~jY)ECf5w+BfZ% z`nIv@DZ}T+>oIc%;YJXKjF;7$?w?%crAjZ1{)YYt#0fn{Fg-rw154vt(XisKQ0FRQO7!Qt zUEkbG*#Y$rJZ|FPWDqA;X|$K^@ZjW9`D$Y>o~H6VT;2T)js= z$6P8s8--grEAAg~2=}asdkt~l4sQOCX4(M4V)*0;`$LbSw;6HAC+o{_7M0M?8@;*6 z8=YxmeIc}EZ?d5tQ8IcrqFi;ZH+qlgjRp|J=@^U!#puQ4%K7S7AL=P5I~_x;+~UPO z0vK!P(Dq%rAwcvkbg(f|bI9@1SuLsjE!4t%FEB+veLlR=d60K=Q9>V5Zc`C-8mf^L zy_iBdwsC02G-B!@;aQMW4E3Z7f^8Agj%f)6nRZYmsTWtX5Sa=RFQ_>8$0{PustZ40 z_hsl^pPn0GaP)ZqWEv29gV^M-&>^2x%>sd4uqjp!Z#zeC`|Oamr3zNL-i#hD&_PZ? zOxuDQ z$nQv=?s;saH0(|5A&|{Fd0&78V_xA<5Nu2-?*g-6Qg|iFf5eb~Gqjv(OL{n$uXna- zkI{#hJcc^TWE~Nj=q;t2>jui9{w~$~Lp@0|FETq->9n7m;ihDuberNLcmNWSK znVcQg&_<%8kn zv$+((6Sd-|{3a#+b$JRk^n}05l*hZGIH=C||E)AyX7hB;K<4eVB{_q;**@=42GndO zzjpyL&_sN}lZQP5osyC<5kPSACI6Hj&6UxkIXs`EGZQ?Q3xUZ#@frSnZk=N-!=LBR z=U#HefJ>bb#{eKbDPy~2Ha#E{agJjXK?WRUJRr+a&x>QQ%X_JFvp)0mRr{d6YVzL0 z4yivTPduPMxED0s`w5%q2|1Sb2r!-T8F>txQuLB##iFo@9**;ft?qdjbUM84Td2K+ z#z||`cCqK1!>J*j`&#kvtYfeIojQp8N{@d9yCi+bla38a#mD_4B>SIEX|$i0sr}&6 zUPRGs-;P0u{949S+7Hz@IwQF`^l(%^PoNX}1M1^@u%E>A-ab}WLQbL{>5JYWdOr4* zRD6VW`IYuG>vAzEhATOr9mul#rD&FX9U62$$1l&ZBT{isV7k=lvPe5s$b^_J88~Or>W8cq`)o^v+&LkFMRIqudS7 zI0y;l(4KC*-ZUO1Cf}vVR;#HKyp)A-(A!6nA^J;Kd^g>V+oWPmo<*)L;kB#`=_i74 z&y}w5G{-ocWDyy!`HVd3vY*Rt#Iub}3Qj8o_psBwL+|qVR1iD#CdJ8uSg2SCzSf0D z4<_~4{Wvp$6fLny)8jjyyrJ!0DS8=RkYl;GM>!xZ|6X|JGU0&>4&4m-9AmGwk<#~1 z#kAqZhdp!wo3#88ajOvw4<68u8+B1H{*>8)@lr`|!9AX8GUdh_4n@jd}B zVF=8ehx&e`uYP_2wkV`3U&4OsY{Z-J$0C-(V_Q1*1}}>2k~4A3NNYVVPg2-(Y5jeN z$Sy_<9#Z$eO&!r?u2)|JxnOU&XoUT-t;hEAs-zAyAF=bW6jnTlmh^VnMqr?BZ>>2h z*(V(-*dcBF%j(@%sw4Bx1>veUkJ=aE&A2-EG}iHoF(TcpnPYoz*J!mCf-AWg&#)T`|i=nW6}*+!ZoiJ1mtdtfUC5jF^%_tN}J zVbvln-$E^cVt#MmoQ3+t3EA?)&jPKHOpl`1fPfXU3l{Z8ulx0NBE8`Q|LH?Su_szp_lmDf9GZ1g5oMFL9avomvlP9v1#C_^G$b$!*;|%?9 zRdBm2bU)rA?4jltvgV71Swc4m-St?t>;wdd!K4VD$c^F;$@kbhZorzuCPXS5PL79i zo14){J-Q2S(-Fg&g*+lugyXtuEaGlt_=4*tI-qfFt^^yNd=8)DVlPF~K8J9OBm0Tq zEVX>%>AWvXeG%HQ@!}-C2Xx$0;eZ`sNL`K^oKx6v%rk7pHurd8ipTP~)LmUy<;Sixd&%q-2v*YZh^G{(XVfTx7^mA^s1n>=`{17e@kJA~f$2yBAg zxCSQ~q#VQ`g($IkZYasNhi9UW!n8-Z-DclV6poAX{?3wPIKXIqFC4$Z9(kM^<5|E& z64;4kpa4n2{!I^H)Ltd7&UlMno3Yp*d5rPxk7nW&KfQB#{M4ya$97)6eS8R)tSLQS zydPTGqh84MX$lpWiE2VSp}aPlcV(kC)c6>NRdi%OR!GzdS5?vj&;JTNo(0X?ee7{gUtMGQ!cZ4hUVv|^C1ZRx`V z_6Dnz20B&@*(rxChJ208*8=mA(aNAV8I9~kcFWebL8?9ytr()zO>8X3bduWt@47j1 z$Oh*!dt$!?QKQoVeIL`0(Z5$$V}uk1_O&lk_poxX5SY3MZLzA|>eFb)4lDQ3+j1G` zXjaDoc?6w8>iZyz^V2cJ>e3Jq%WQToqi8I$G7*c8D_ed*oZR<;x?~C3>%T z19sm+Z9EWW-(zWXmL?-!?qdQA235Q$gM9!@0+^^VZRu=3D=x{VClI}GGE^@|br)X8d`wND*7cqyFrIL5=*kVAr8 zBxx&DH!cf%wuj%f@Glc5j1P#DC)fEJS|*6K&3>`5+3yqSTc-X-_Wjj7oZ8M0R4w&g zFM{)y`K2>v&0RQe{_NSF1&j0Y@-juS*?+xAb#w4`^PF2U%c_C_9}}fBiveGCb5l(q zPZafLVq?`Zafwfy5YT(%^@TuQpCwkTsSmU?z>0EReE^C#v|uDPB7IR7+)4gcpFe=FAY+PxGQN8&8n|hC zPit5w%PrSWnbOwQmbbJinAhxIIwjCtE4NkoeN(F87eTqcA%IsROMFc}e^rCta}eKC zUMk`zK}3W1dU4trB;jkwr0JBOWeRhBE%<6N`3y|k6lh?RBrXXq1)(|7*i?rv2H)kY zmYGJfud0!R;F=AKS2xpC%kZ4$YG!pNY?9~?HeJvB7#v)4=IhBXdr!y|GLxDZy^jxM z3Mfxbv~qG&2vE1KxzUF?rNuC9d;m(&uoIkuuc<t9gEvS<)z zErqMe!cFy!VySPL58r)XDm2yym<90-YZ#+OfP%;&YM6^K@ALzQt?>Qxrlw}{;;I_@ zXdoXF@tyJNyU7;G>&T6I8F%M&iR*Nj^R2Te@0tQ(rog`ZE$ZKxA0MD~EnF?o+z8x3 zSiAq^qg>KO4rQt1gga8y(`!(F&*j1r^?I@PmbNa;Uo5s&1z_|*01HK~^EU^V*3rWC zwfm~Yz_NhsYZR;Top}VRDS7w`Ivlh?o-FJS{iE>PKM50ral&th`+%+yD)Bo6_{Mrw zgAl-I`RC-ShBm|xp<1Y(jAg&XC;0HS`4*o*mZcvfIMXFM88v@`4*SRJF#Ad!ws2U+ z;o1~%;0m38kK?}v%Q*iU-oBs17>DaQT+3k#hyT@n{=512kJHCJ6uvuz-hKJ$d?7ym zq3sOZ;Qyb3h90S)aJfDn!@mDhdj5CyYmB>+&y&%QK~IGn^#9*sY>59FxZ&3VE(`u} zr^$X#D;*Gr7x*OzL7;orVviG_xS!;(gu`+UZ{zSz4*ySy&hO(mYm5))v%Ji5N^kH#{Zfc2yI9s7 z#NL1$lgLOIa5Ih{V`0kqeMpUDfBh1qjAFe^A}Fncj9cc2x4Y)fb=^{a$0TY*`4)c4 z1ZkRxjkl33!t$_&sy3E$kqu8Xlx_i7A(L{gR2HK8(=7F$$RWPdcvJLe@SVo{cgW@K z{w{q@ef*d8H~KMTkbRnAUq3k)U9mzZgWEY2uG4WRhbuYk=TMxg*M~Ulx>mB(o;a=1ukkkOOH}3#f1CIc%1MCIt z1v~)wKA;0nH*&eJOKC&U^*V+j>1XT7(hDldIqo@@Oi)nz_$S-fZqT<1(=R! z^Uni10AB}m10DdZ0Xzx#Hr^{+hZBHr0DA#zK1F|o1D*tw@&4UdxZ-NSX@JiImIL+z zHUOsMUBlIYg@Ee-p8@Oz{08uSz%d%+P(9$-k&qAQ2Bh~zYXExz?*()mjK`lL9Plup zj2CnZM?ntYy@1c)t=QFoZy$mFfaPC7-Z{_FDpZC#e(*+d_Uzo+1DR}llh&dd+}P*418UyjEs;a5Ud_Ux>jo9rXoY$4&s zi*C5;TE{pNK|F5!74^pBJ+x7|va(lL!5U7Roh9mWYC!IeL0|Z_Fe58_mDQbatqz%FN1j zWrHOiq5VIQ{*R>1$`U)% zXJzHC%5Y`nuNdaaDhdz3DJx`6`z$Rps|Yk#R_=@}afUGMbCj`^xfP6t~f6u(8(-$(V# zo;RhkXGvD2b>5kbN%KN+e*xqiPRPN$n&$;J1ujc%t zO>_s!w0~7XP9D*d@nLpWWu*}km|wgNzB=#~5FgV!8E?S6h`Br3lXp;m>DbrW!9R-l z`9<`xptpcN)GrD_C;5*PF9MkLS6MdVr~UK@=-EW)7tw1#S3w_Y7ut7;-)tAMJMF{7 zA0Zh(*5BG}8UV?seOlV{WBqC0c7lEZ$>A6Af5Z9B{!8>x*tg5TZ`OzC4$w)yc|M3f zjq?v3S2^elz;B+{b>MFRy%O|V%#ZH>h!KyZCD%XmTQ|iML`F-Rjn@B<<4MU#>!W9^ zaF476z2rv$qiiGsBd3>|0+WaFm;H!;4gw5~Z!Gc;5&4dYvT+f;5cFKoeMEF)rB-Iy z*!l-O1bPS2OR@$m*87a*!S=}p)E_~;O!aKPur?VC)P5D}%aBjutLD7^mP7=heko6) zdXefEW-&J-I^|6ZK*zKuE(c1KM-hJ!QQ7`65Ar-COA}K0`bUtg1K$wKd-0fNu*D5bb6k!ir42-JzL+1 zYi$4b7~4OSL-`%O^Tqs&^;4GUhxB`!*R%DHen=eI<1pw>w3|l+)($)0J((<*C>aUH z*;zI>s>UD>YzN~FwC}A-$6mC8_Ra9Hk}Rjyo5`F9+jnBO;~OZ+Sp+%# zkn=k(hwo3|ro1QL>dQ1OFB|KVU*Ce--!3%XX@$anRCwJL}BNlcU_ry6( zl?e#+q>hr@ot`{(dV z4ySU+Cdc$qBXaBv_AsF0j5vU~dH1RpH-m%Bxw{6j;`%L)ov_7;la; zHjY%F&hKleq6WOw(jZfp_y>LR*gxQuR|^Dn&3Iv>O33ro;U6)=KfzQ{SA(_&rnji5 z^82fn39N-tzN;E+kY3eTUkyE)Ar>EbtQTG4l0bkdSW)A{yGrj9x zadkFm6w8hF#{RILGaCB=SlBhxez$;1vDj#D#NX@r268WNXXtP68E_%$DYhH95#PIc z`%2z^sQ#QR+=T+!)M#()CpmnBHTDyu|DofThqO2Lrx}S-TNJHD-4;tCTh!e(s z-hD2JxQu;T$8=qdGQnl|Gq)e$`^Ero&)y9&HOS^=14f3lr{A!r%gHzFgY020Be4&o zok4jR1#|yK{xOL=p0N)b{A6qM)dhsw8}@g)ovhl)+k1?}hEWAUh}BOOc5pMkGOAq#&-K4biQw#L8bYRtF6KNNon z74-btXm8|WIZb+tq5MPf?O>zv8|~?r{OJ<^&h~GBmweA?Z{#D!zqd=@v8T)MPosas z4|b!@+`sYfmK|r=)Q|0Dv^U`1A?<~hN>FgM=pe@X*RiBLqx}I?nEQ|YqLQ)3exbLZ z^=ZCDGlKF#{E;kU{7!!*Fg!!{GawA@U)0Ho&o5CLq9Us^+8cSg(O@XAS$Bhnpp*B1 L%1lIgX#4*F*=2wl literal 0 HcmV?d00001 -- 2.7.4