// C++ interface to dwfl // Copyright (C) 2005-2009 Red Hat Inc. // Copyright (C) 2005-2007 Intel Corporation. // Copyright (C) 2008 James.Bottomley@HansenPartnership.com // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. #include "dwflpp.h" #include "config.h" #include "staptree.h" #include "elaborate.h" #include "tapsets.h" #include "task_finder.h" #include "translate.h" #include "session.h" #include "util.h" #include "buildrun.h" #include "dwarf_wrappers.h" #include "auto_free.h" #include "hash.h" #include "rpm_finder.h" #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include #include #include #include #include #include #include #include #include #include #include #include "loc2c.h" #define __STDC_FORMAT_MACROS #include } // debug flag to compare to the uncached version from libdw // #define DEBUG_DWFLPP_GETSCOPES 1 using namespace std; using namespace __gnu_cxx; static string TOK_KERNEL("kernel"); dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p): sess(session), module(NULL), module_bias(0), mod_info(NULL), module_start(0), module_end(0), cu(NULL), dwfl(NULL), module_dwarf(NULL), function(NULL), blacklist_enabled(false) { if (kernel_p) setup_kernel(name); else { vector modules; modules.push_back(name); setup_user(modules); } } dwflpp::dwflpp(systemtap_session & session, const vector& names): sess(session), module(NULL), module_bias(0), mod_info(NULL), module_start(0), module_end(0), cu(NULL), dwfl(NULL), module_dwarf(NULL), function(NULL), blacklist_enabled(false) { setup_user(names); } dwflpp::~dwflpp() { delete_map(module_cu_cache); delete_map(cu_function_cache); delete_map(cu_inl_function_cache); delete_map(global_alias_cache); delete_map(cu_die_parent_cache); if (dwfl) dwfl_end(dwfl); } void dwflpp::get_module_dwarf(bool required, bool report) { module_dwarf = dwfl_module_getdwarf(module, &module_bias); mod_info->dwarf_status = (module_dwarf ? info_present : info_absent); if (!module_dwarf && report) { string msg = "cannot find "; if (module_name == "") msg += "kernel"; else msg += string("module ") + module_name; msg += " debuginfo"; int i = dwfl_errno(); if (i) msg += string(": ") + dwfl_errmsg (i); /* add module_name to list to find rpm */ find_debug_rpms(sess, module_name.c_str()); if (required) throw semantic_error (msg); else if (! sess.suppress_warnings) cerr << "WARNING: " << msg << "\n"; } } void dwflpp::focus_on_module(Dwfl_Module * m, module_info * mi) { module = m; mod_info = mi; if (m) { module_name = dwfl_module_info(module, NULL, &module_start, &module_end, NULL, NULL, NULL, NULL) ?: "module"; } else { assert(mi && mi->name && mi->name == TOK_KERNEL); module_name = mi->name; module_start = 0; module_end = 0; module_bias = mi->bias; } // Reset existing pointers and names module_dwarf = NULL; cu = NULL; function_name.clear(); function = NULL; } void dwflpp::focus_on_cu(Dwarf_Die * c) { assert(c); assert(module); cu = c; // Reset existing pointers and names function_name.clear(); function = NULL; } string dwflpp::cu_name(void) { return dwarf_diename(cu) ?: ""; } void dwflpp::focus_on_function(Dwarf_Die * f) { assert(f); assert(module); assert(cu); function = f; function_name = dwarf_diename(function) ?: "function"; } /* Return the Dwarf_Die for the given address in the current module. * The address should be in the module address address space (this * function will take care of any dw bias). */ Dwarf_Die * dwflpp::query_cu_containing_address(Dwarf_Addr a) { Dwarf_Addr bias; assert(dwfl); assert(module); get_module_dwarf(); Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias); assert(bias == module_bias); return cudie; } bool dwflpp::module_name_matches(const string& pattern) { bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0); if (t && sess.verbose>3) clog << "pattern '" << pattern << "' " << "matches " << "module '" << module_name << "'" << "\n"; return t; } bool dwflpp::name_has_wildcard (const string& pattern) { return (pattern.find('*') != string::npos || pattern.find('?') != string::npos || pattern.find('[') != string::npos); } bool dwflpp::module_name_final_match(const string& pattern) { // Assume module_name_matches(). Can there be any more matches? // Not unless the pattern is a wildcard, since module names are // presumed unique. return !name_has_wildcard(pattern); } bool dwflpp::function_name_matches_pattern(const string& name, const string& pattern) { bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0); if (t && sess.verbose>3) clog << "pattern '" << pattern << "' " << "matches " << "function '" << name << "'" << "\n"; return t; } bool dwflpp::function_name_matches(const string& pattern) { assert(function); return function_name_matches_pattern(function_name, pattern); } bool dwflpp::function_scope_matches(const vector scopes) { // walk up the containing scopes Dwarf_Die* die = function; for (int i = scopes.size() - 1; i >= 0; --i) { die = get_parent_scope(die); // check if this scope matches, and prepend it if so // NB: a NULL die is the global scope, compared as "" string name = dwarf_diename(die) ?: ""; if (name_has_wildcard(scopes[i]) ? function_name_matches_pattern(name, scopes[i]) : name == scopes[i]) function_name = name + "::" + function_name; else return false; // make sure there's no more if we're at the global scope if (!die && i > 0) return false; } return true; } static const char *offline_search_modname = NULL; static int offline_search_match_p = 0; static int dwfl_report_offline_predicate (const char* modname, const char* filename) { if (pending_interrupts) return -1; assert (offline_search_modname); // elfutils sends us NULL filenames sometimes if it can't find dwarf if (filename == NULL) return 0; if (dwflpp::name_has_wildcard (offline_search_modname)) { int match_p = !fnmatch(offline_search_modname, modname, 0); // In the wildcard case, we don't short-circuit (return -1) upon // offline_search_match_p, analogously to dwflpp::module_name_final_match(). if (match_p) offline_search_match_p ++; return match_p; } else { /* non-wildcard mode */ if (offline_search_match_p) return -1; /* Reject mismatching module names */ if (strcmp(modname, offline_search_modname)) return 0; else { offline_search_match_p ++; return 1; } } } void dwflpp::setup_kernel(const string& name, bool debuginfo_needed) { // XXX: See also translate.cxx:emit_symbol_data if (! sess.module_cache) sess.module_cache = new module_cache (); static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr ); static const Dwfl_Callbacks kernel_callbacks = { dwfl_linux_kernel_find_elf, dwfl_standard_find_debuginfo, dwfl_offline_section_address, (char **) & debuginfo_path }; dwfl = dwfl_begin (&kernel_callbacks); if (!dwfl) throw semantic_error ("cannot open dwfl"); dwfl_report_begin (dwfl); // We have a problem with -r REVISION vs -r BUILDDIR here. If // we're running against a fedora/rhel style kernel-debuginfo // tree, s.kernel_build_tree is not the place where the unstripped // vmlinux will be installed. Rather, it's over yonder at // /usr/lib/debug/lib/modules/$REVISION/. It seems that there is // no way to set the dwfl_callback.debuginfo_path and always // passs the plain kernel_release here. So instead we have to // hard-code this magic here. string elfutils_kernel_path; if (sess.kernel_build_tree == string("/lib/modules/" + sess.kernel_release + "/build")) elfutils_kernel_path = sess.kernel_release; else elfutils_kernel_path = sess.kernel_build_tree; offline_search_modname = name.c_str(); offline_search_match_p = 0; int rc = dwfl_linux_kernel_report_offline (dwfl, elfutils_kernel_path.c_str(), &dwfl_report_offline_predicate); offline_search_modname = NULL; (void) rc; /* Ignore since the predicate probably returned -1 at some point, And libdwfl interprets that as "whole query failed" rather than "found it already, stop looking". */ /* But we still need to check whether the module was itself found. One could do an iterate_modules() search over the resulting dwfl and count hits. Or one could rely on the match_p flag being set just before. */ if (! offline_search_match_p) { if (debuginfo_needed) { // Suggest a likely kernel dir to find debuginfo rpm for string dir = string("/lib/modules/" + sess.kernel_release ); find_debug_rpms(sess, dir.c_str()); } throw semantic_error (string("missing ") + sess.architecture + string(" kernel/module debuginfo under '") + sess.kernel_build_tree + string("'")); } // NB: the result of an _offline call is the assignment of // virtualized addresses to relocatable objects such as // modules. These have to be converted to real addresses at // run time. See the dwarf_derived_probe ctor and its caller. dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); build_blacklist(); } void dwflpp::setup_user(const vector& modules, bool debuginfo_needed) { if (! sess.module_cache) sess.module_cache = new module_cache (); static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); // NB: kernel_build_tree doesn't enter into this, as it's for // kernel-side modules only. static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr); static const Dwfl_Callbacks user_callbacks = { NULL, /* dwfl_linux_kernel_find_elf, */ dwfl_standard_find_debuginfo, dwfl_offline_section_address, (char **) & debuginfo_path }; dwfl = dwfl_begin (&user_callbacks); if (!dwfl) throw semantic_error ("cannot open dwfl"); dwfl_report_begin (dwfl); vector::const_iterator it; for (it = modules.begin(); it != modules.end(); ++it) { // XXX: should support buildid-based naming const string& module_name = *it; Dwfl_Module *mod = dwfl_report_offline (dwfl, module_name.c_str(), module_name.c_str(), -1); if (debuginfo_needed) dwfl_assert (string("missing process ") + module_name + string(" ") + sess.architecture + string(" debuginfo"), mod); } // NB: the result of an _offline call is the assignment of // virtualized addresses to relocatable objects such as // modules. These have to be converted to real addresses at // run time. See the dwarf_derived_probe ctor and its caller. dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); } void dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **, const char *, Dwarf_Addr, void *), base_query *data) { dwfl_getmodules (dwfl, callback, data, 0); // Don't complain if we exited dwfl_getmodules early. // This could be a $target variable error that will be // reported soon anyway. // dwfl_assert("dwfl_getmodules", off == 0); // PR6864 XXX: For dwarfless case (if .../vmlinux is missing), then the // "kernel" module is not reported in the loop above. However, we // may be able to make do with symbol table data. } void dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg), void * data) { get_module_dwarf(false); Dwarf *dw = module_dwarf; if (!dw) return; vector* v = module_cu_cache[dw]; if (v == 0) { v = new vector; module_cu_cache[dw] = v; Dwarf_Off off = 0; size_t cuhl; Dwarf_Off noff; while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0) { if (pending_interrupts) return; Dwarf_Die die_mem; Dwarf_Die *die; die = dwarf_offdie (dw, off + cuhl, &die_mem); v->push_back (*die); /* copy */ off = noff; } } for (vector::iterator i = v->begin(); i != v->end(); ++i) { int rc = (*callback)(&*i, data); if (rc != DWARF_CB_OK || pending_interrupts) break; } } bool dwflpp::func_is_inline() { assert (function); return dwarf_func_inline (function) != 0; } void dwflpp::cache_inline_instances (Dwarf_Die* die) { // If this is an inline instance, link it back to its origin Dwarf_Die origin; if (dwarf_tag(die) == DW_TAG_inlined_subroutine && dwarf_attr_die(die, DW_AT_abstract_origin, &origin)) { vector*& v = cu_inl_function_cache[origin.addr]; if (!v) v = new vector; v->push_back(*die); } // Recurse through other scopes that may contain inlines Dwarf_Die child, import; if (dwarf_child(die, &child) == 0) do { switch (dwarf_tag (&child)) { // tags that could contain inlines case DW_TAG_compile_unit: case DW_TAG_module: case DW_TAG_lexical_block: case DW_TAG_with_stmt: case DW_TAG_catch_block: case DW_TAG_try_block: case DW_TAG_entry_point: case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: cache_inline_instances(&child); break; // imported dies should be followed case DW_TAG_imported_unit: if (dwarf_attr_die(&child, DW_AT_import, &import)) cache_inline_instances(&import); break; // nothing to do for other tags default: break; } } while (dwarf_siblingof(&child, &child) == 0); } void dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg), void * data) { assert (function); assert (func_is_inline ()); if (cu_inl_function_cache_done.insert(cu->addr).second) cache_inline_instances(cu); vector* v = cu_inl_function_cache[function->addr]; if (!v) return; for (vector::iterator i = v->begin(); i != v->end(); ++i) { int rc = (*callback)(&*i, data); if (rc != DWARF_CB_OK || pending_interrupts) break; } } void dwflpp::cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die) { // Record and recurse through DIEs we care about Dwarf_Die child, import; if (dwarf_child(die, &child) == 0) do { switch (dwarf_tag (&child)) { // normal tags to recurse case DW_TAG_compile_unit: case DW_TAG_module: case DW_TAG_lexical_block: case DW_TAG_with_stmt: case DW_TAG_catch_block: case DW_TAG_try_block: case DW_TAG_entry_point: case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: case DW_TAG_namespace: case DW_TAG_class_type: case DW_TAG_structure_type: parents->insert(make_pair(child.addr, *die)); cache_die_parents(parents, &child); break; // record only, nothing to recurse case DW_TAG_label: parents->insert(make_pair(child.addr, *die)); break; // imported dies should be followed case DW_TAG_imported_unit: if (dwarf_attr_die(&child, DW_AT_import, &import)) { parents->insert(make_pair(import.addr, *die)); cache_die_parents(parents, &import); } break; // nothing to do for other tags default: break; } } while (dwarf_siblingof(&child, &child) == 0); } cu_die_parent_cache_t* dwflpp::get_die_parents() { assert (cu); cu_die_parent_cache_t *& parents = cu_die_parent_cache[cu->addr]; if (!parents) { parents = new cu_die_parent_cache_t; cache_die_parents(parents, cu); if (sess.verbose > 4) clog << "die parent cache " << module_name << ":" << cu_name() << " size " << parents->size() << endl; } return parents; } vector dwflpp::getscopes_die(Dwarf_Die* die) { cu_die_parent_cache_t *parents = get_die_parents(); vector scopes; Dwarf_Die *scope = die; cu_die_parent_cache_t::iterator it; do { scopes.push_back(*scope); it = parents->find(scope->addr); scope = &it->second; } while (it != parents->end()); #ifdef DEBUG_DWFLPP_GETSCOPES Dwarf_Die *dscopes = NULL; int nscopes = dwarf_getscopes_die(die, &dscopes); assert(nscopes == (int)scopes.size()); for (unsigned i = 0; i < scopes.size(); ++i) assert(scopes[i].addr == dscopes[i].addr); free(dscopes); #endif return scopes; } std::vector dwflpp::getscopes(Dwarf_Die* die) { cu_die_parent_cache_t *parents = get_die_parents(); vector scopes; Dwarf_Die origin; Dwarf_Die *scope = die; cu_die_parent_cache_t::iterator it; do { scopes.push_back(*scope); if (dwarf_tag(scope) == DW_TAG_inlined_subroutine && dwarf_attr_die(scope, DW_AT_abstract_origin, &origin)) scope = &origin; it = parents->find(scope->addr); scope = &it->second; } while (it != parents->end()); #ifdef DEBUG_DWFLPP_GETSCOPES // there isn't an exact libdw equivalent, but if dwarf_getscopes on the // entrypc returns the same first die, then all the scopes should match Dwarf_Addr pc; if (die_entrypc(die, &pc)) { Dwarf_Die *dscopes = NULL; int nscopes = dwarf_getscopes(cu, pc, &dscopes); if (nscopes > 0 && dscopes[0].addr == die->addr) { assert(nscopes == (int)scopes.size()); for (unsigned i = 0; i < scopes.size(); ++i) assert(scopes[i].addr == dscopes[i].addr); } free(dscopes); } #endif return scopes; } std::vector dwflpp::getscopes(Dwarf_Addr pc) { // The die_parent_cache doesn't help us without knowing where the pc is // contained, so we have to do this one the old fashioned way. assert (cu); vector scopes; Dwarf_Die* dwarf_scopes; int nscopes = dwarf_getscopes(cu, pc, &dwarf_scopes); if (nscopes > 0) { scopes.assign(dwarf_scopes, dwarf_scopes + nscopes); free(dwarf_scopes); } #ifdef DEBUG_DWFLPP_GETSCOPES // check that getscopes on the starting die gets the same result if (!scopes.empty()) { vector other = getscopes(&scopes[0]); assert(scopes.size() == other.size()); for (unsigned i = 0; i < scopes.size(); ++i) assert(scopes[i].addr == other[i].addr); } #endif return scopes; } Dwarf_Die* dwflpp::get_parent_scope(Dwarf_Die* die) { Dwarf_Die specification; if (dwarf_attr_die(die, DW_AT_specification, &specification)) die = &specification; cu_die_parent_cache_t *parents = get_die_parents(); cu_die_parent_cache_t::iterator it = parents->find(die->addr); while (it != parents->end()) { Dwarf_Die* scope = &it->second; switch (dwarf_tag (scope)) { case DW_TAG_namespace: case DW_TAG_class_type: case DW_TAG_structure_type: return scope; default: break; } it = parents->find(scope->addr); } return NULL; } int dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg) { cu_type_cache_t *cache = static_cast(arg); const char *name = dwarf_diename(die); if (!name) return DWARF_CB_OK; string structure_name = name; if (!dwarf_hasattr(die, DW_AT_declaration) && cache->find(structure_name) == cache->end()) (*cache)[structure_name] = *die; return DWARF_CB_OK; } Dwarf_Die * dwflpp::declaration_resolve(const char *name) { if (!name) return NULL; cu_type_cache_t *v = global_alias_cache[cu->addr]; if (v == 0) // need to build the cache, just once per encountered module/cu { v = new cu_type_cache_t; global_alias_cache[cu->addr] = v; iterate_over_globals(global_alias_caching_callback, v); if (sess.verbose > 4) clog << "global alias cache " << module_name << ":" << cu_name() << " size " << v->size() << endl; } // XXX: it may be desirable to search other modules' declarations // too, in case a module/shared-library processes a // forward-declared pointer type only, where the actual definition // may only be in vmlinux or the application. // XXX: it is probably desirable to search other CU's declarations // in the same module. if (v->find(name) == v->end()) return NULL; return & ((*v)[name]); } int dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg) { cu_function_cache_t* v = static_cast(arg); const char *name = dwarf_diename(func); if (!name) return DWARF_CB_OK; v->insert(make_pair(string(name), *func)); return DWARF_CB_OK; } int dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q), base_query * q, const string& function, bool has_statement_num) { int rc = DWARF_CB_OK; assert (module); assert (cu); cu_function_cache_t *v = cu_function_cache[cu->addr]; if (v == 0) { v = new cu_function_cache_t; cu_function_cache[cu->addr] = v; dwarf_getfuncs (cu, cu_function_caching_callback, v, 0); if (sess.verbose > 4) clog << "function cache " << module_name << ":" << cu_name() << " size " << v->size() << endl; mod_info->update_symtab(v); } cu_function_cache_t::iterator it; cu_function_cache_range_t range = v->equal_range(function); if (range.first != range.second) { for (it = range.first; it != range.second; ++it) { Dwarf_Die& die = it->second; if (sess.verbose > 4) clog << "function cache " << module_name << ":" << cu_name() << " hit " << function << endl; rc = (*callback)(& die, q); if (rc != DWARF_CB_OK) break; } } else if (name_has_wildcard (function)) { for (it = v->begin(); it != v->end(); ++it) { if (pending_interrupts) return DWARF_CB_ABORT; const string& func_name = it->first; Dwarf_Die& die = it->second; if (function_name_matches_pattern (func_name, function)) { if (sess.verbose > 4) clog << "function cache " << module_name << ":" << cu_name() << " match " << func_name << " vs " << function << endl; rc = (*callback)(& die, q); if (rc != DWARF_CB_OK) break; } } } else if (has_statement_num) // searching all for kernel.statement { for (it = v->begin(); it != v->end(); ++it) { rc = (*callback)(&it->second, q); if (rc != DWARF_CB_OK) break; } } else // not a wildcard and no match in this CU { // do nothing } return rc; } /* This basically only goes one level down from the compile unit so it * only picks up top level stuff (i.e. nothing in a lower scope) */ int dwflpp::iterate_over_globals (int (* callback)(Dwarf_Die *, void *), void * data) { int rc = DWARF_CB_OK; Dwarf_Die die; assert (module); assert (cu); assert (dwarf_tag(cu) == DW_TAG_compile_unit); if (dwarf_child(cu, &die) != 0) return rc; do /* We're only currently looking for named types, * although other types of declarations exist */ switch (dwarf_tag(&die)) { case DW_TAG_base_type: case DW_TAG_enumeration_type: case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_typedef: case DW_TAG_union_type: rc = (*callback)(&die, data); break; } while (rc == DWARF_CB_OK && dwarf_siblingof(&die, &die) == 0); return rc; } // This little test routine represents an unfortunate breakdown in // abstraction between dwflpp (putatively, a layer right on top of // elfutils), and dwarf_query (interpreting a systemtap probe point). // It arises because we sometimes try to fix up slightly-off // .statement() probes (something we find out in fairly low-level). // // An alternative would be to put some more intelligence into query_cu(), // and have it print additional suggestions after finding that // q->dw.iterate_over_srcfile_lines resulted in no new finished_results. bool dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno) { if (lineno < 0) return false; Dwarf_Line **srcsp = NULL; size_t nsrcs = 0; dwarf_assert ("dwarf_getsrc_file", dwarf_getsrc_file (module_dwarf, srcfile, lineno, 0, &srcsp, &nsrcs)); if (nsrcs != 1) { if (sess.verbose>4) clog << "alternative line " << lineno << " rejected: nsrcs=" << nsrcs << endl; return false; } // We also try to filter out lines that leave the selected // functions (if any). dwarf_line_t line(srcsp[0]); Dwarf_Addr addr = line.addr(); func_info_map_t *filtered_functions = get_filtered_functions(q); for (func_info_map_t::iterator i = filtered_functions->begin(); i != filtered_functions->end(); ++i) { if (die_has_pc (i->die, addr)) { if (sess.verbose>4) clog << "alternative line " << lineno << " accepted: fn=" << i->name << endl; return true; } } inline_instance_map_t *filtered_inlines = get_filtered_inlines(q); for (inline_instance_map_t::iterator i = filtered_inlines->begin(); i != filtered_inlines->end(); ++i) { if (die_has_pc (i->die, addr)) { if (sess.verbose>4) clog << "alternative line " << lineno << " accepted: ifn=" << i->name << endl; return true; } } if (sess.verbose>4) clog << "alternative line " << lineno << " rejected: leaves selected fns" << endl; return false; } void dwflpp::iterate_over_srcfile_lines (char const * srcfile, int lines[2], bool need_single_match, enum line_t line_type, void (* callback) (const dwarf_line_t& line, void * arg), const std::string& func_pattern, void *data) { Dwarf_Line **srcsp = NULL; size_t nsrcs = 0; dwarf_query * q = static_cast(data); int lineno = lines[0]; auto_free_ref free_srcsp(srcsp); get_module_dwarf(); if (!this->function) return; if (line_type == RELATIVE) { Dwarf_Addr addr; Dwarf_Line *line; int line_number; dwarf_assert ("dwarf_entrypc", dwarf_entrypc (this->function, &addr)); line = dwarf_getsrc_die (this->cu, addr); dwarf_assert ("dwarf_getsrc_die", line == NULL); dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number)); lineno += line_number; } else if (line_type == WILDCARD) function_line (&lineno); else if (line_type == RANGE) { /* correct lineno */ int start_lineno; if (name_has_wildcard(func_pattern)) /* PR10294: wider range like statement("*@foo.c") */ start_lineno = lineno; else function_line (&start_lineno); lineno = lineno < start_lineno ? start_lineno : lineno; if (lineno > lines[1]) { /* invalid line range */ stringstream advice; advice << "Invalid line range (" << lines[0] << "-" << lines[1] << ")"; if (start_lineno > lines[1]) advice << ", the end line number " << lines[1] << " < " << start_lineno; throw semantic_error (advice.str()); } } for (int l = lineno; ; l = l + 1) { set lines_probed; pair::iterator,bool> line_probed; int ret = 0; ret = dwarf_getsrc_file (module_dwarf, srcfile, l, 0, &srcsp, &nsrcs); if (line_type != WILDCARD && line_type != RANGE) dwarf_assert ("dwarf_getsrc_file", ret); if (line_type == WILDCARD || line_type == RANGE) { Dwarf_Addr line_addr; if (ret != 0) /* tolerate invalid line number */ break; dwarf_lineno (srcsp [0], &lineno); /* Maybe lineno will exceed the input end */ if (line_type == RANGE && lineno > lines[1]) break; line_probed = lines_probed.insert(lineno); if (lineno != l || line_probed.second == false || nsrcs > 1) continue; dwarf_lineaddr (srcsp [0], &line_addr); if (!function_name_matches(func_pattern) && dwarf_haspc (function, line_addr) != 1) break; } // NB: Formerly, we used to filter, because: // dwarf_getsrc_file gets one *near hits* for line numbers, not // exact matches. For example, an existing file but a nonexistent // line number will be rounded up to the next definition in that // file. This may be similar to the GDB breakpoint algorithm, but // we don't want to be so fuzzy in systemtap land. So we filter. // But we now see the error of our ways, and skip this filtering. // XXX: the code also fails to match e.g. inline function // definitions when the srcfile is a header file rather than the // CU name. size_t remaining_nsrcs = nsrcs; if (need_single_match && remaining_nsrcs > 1) { // We wanted a single line record (a unique address for the // line) and we got a bunch of line records. We're going to // skip this probe (throw an exception) but before we throw // we're going to look around a bit to see if there's a low or // high line number nearby which *doesn't* have this problem, // so we can give the user some advice. int lo_try = -1; int hi_try = -1; for (size_t i = 1; i < 6; ++i) { if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i)) lo_try = lineno - i; if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i)) hi_try = lineno + i; } stringstream advice; advice << "multiple addresses for " << srcfile << ":" << lineno; if (lo_try > 0 || hi_try > 0) { advice << " (try "; if (lo_try > 0) advice << srcfile << ":" << lo_try; if (lo_try > 0 && hi_try > 0) advice << " or "; if (hi_try > 0) advice << srcfile << ":" << hi_try; advice << ")"; } throw semantic_error (advice.str()); } for (size_t i = 0; i < nsrcs; ++i) { if (pending_interrupts) return; if (srcsp [i]) // skip over mismatched lines callback (dwarf_line_t(srcsp[i]), data); } if (line_type == ABSOLUTE || line_type == RELATIVE) break; else if (line_type == RANGE && l == lines[1]) break; } } void dwflpp::iterate_over_labels (Dwarf_Die *begin_die, const string& sym, const string& function, dwarf_query *q, void (* callback)(const string &, const char *, const char *, int, Dwarf_Die *, Dwarf_Addr, dwarf_query *)) { get_module_dwarf(); Dwarf_Die die; const char *name; int res = dwarf_child (begin_die, &die); if (res != 0) return; // die without children, bail out. do { switch (dwarf_tag(&die)) { case DW_TAG_label: name = dwarf_diename (&die); if (name && (name == sym || (name_has_wildcard(sym) && function_name_matches_pattern (name, sym)))) { // Don't try to be smart. Just drop no addr labels. Dwarf_Addr stmt_addr; if (dwarf_lowpc (&die, &stmt_addr) == 0) { // Get the file/line number for this label int dline; const char *file = dwarf_decl_file (&die); dwarf_decl_line (&die, &dline); vector scopes = getscopes_die(&die); if (scopes.size() > 1) callback(function, name, file, dline, &scopes[1], stmt_addr, q); } } break; case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: // Stay within our filtered function break; default: if (dwarf_haschildren (&die)) iterate_over_labels (&die, sym, function, q, callback); break; } } while (dwarf_siblingof (&die, &die) == 0); } void dwflpp::collect_srcfiles_matching (string const & pattern, set & filtered_srcfiles) { assert (module); assert (cu); size_t nfiles; Dwarf_Files *srcfiles; // PR 5049: implicit * in front of given path pattern. // NB: fnmatch() is used without FNM_PATHNAME. string prefixed_pattern = string("*/") + pattern; dwarf_assert ("dwarf_getsrcfiles", dwarf_getsrcfiles (cu, &srcfiles, &nfiles)); { for (size_t i = 0; i < nfiles; ++i) { char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL); if (fnmatch (pattern.c_str(), fname, 0) == 0 || fnmatch (prefixed_pattern.c_str(), fname, 0) == 0) { filtered_srcfiles.insert (fname); if (sess.verbose>2) clog << "selected source file '" << fname << "'\n"; } } } } void dwflpp::resolve_prologue_endings (func_info_map_t & funcs) { // This heuristic attempts to pick the first address that has a // source line distinct from the function declaration's. In a // perfect world, this would be the first statement *past* the // prologue. assert(module); assert(cu); size_t nlines = 0; Dwarf_Lines *lines = NULL; /* trouble cases: malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue sys_get?id in kernel/timer.c no-prologue sys_exit_group tail-recursive {do_,}sys_open extra-long-prologue (gcc 3.4) cpu_to_logical_apicid NULL-decl_file */ // Fetch all srcline records, sorted by address. dwarf_assert ("dwarf_getsrclines", dwarf_getsrclines(cu, &lines, &nlines)); // XXX: free lines[] later, but how? for(func_info_map_t::iterator it = funcs.begin(); it != funcs.end(); it++) { #if 0 /* someday */ Dwarf_Addr* bkpts = 0; int n = dwarf_entry_breakpoints (& it->die, & bkpts); // ... free (bkpts); #endif Dwarf_Addr entrypc = it->entrypc; Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc) dwfl_assert ("dwarf_highpc", dwarf_highpc (& it->die, & highpc)); if (it->decl_file == 0) it->decl_file = ""; unsigned entrypc_srcline_idx = 0; dwarf_line_t entrypc_srcline; // open-code binary search for exact match { unsigned l = 0, h = nlines; while (l < h) { entrypc_srcline_idx = (l + h) / 2; const dwarf_line_t lr(dwarf_onesrcline(lines, entrypc_srcline_idx)); Dwarf_Addr addr = lr.addr(); if (addr == entrypc) { entrypc_srcline = lr; break; } else if (l + 1 == h) { break; } // ran off bottom of tree else if (addr < entrypc) { l = entrypc_srcline_idx; } else { h = entrypc_srcline_idx; } } } if (!entrypc_srcline) { if (sess.verbose > 2) clog << "missing entrypc dwarf line record for function '" << it->name << "'\n"; // This is probably an inlined function. We'll end up using // its lowpc as a probe address. continue; } if (sess.verbose>2) clog << "prologue searching function '" << it->name << "'" << " 0x" << hex << entrypc << "-0x" << highpc << dec << "@" << it->decl_file << ":" << it->decl_line << "\n"; // Now we go searching for the first line record that has a // file/line different from the one in the declaration. // Normally, this will be the next one. BUT: // // We may have to skip a few because some old compilers plop // in dummy line records for longer prologues. If we go too // far (addr >= highpc), we take the previous one. Or, it may // be the first one, if the function had no prologue, and thus // the entrypc maps to a statement in the body rather than the // declaration. unsigned postprologue_srcline_idx = entrypc_srcline_idx; bool ranoff_end = false; while (postprologue_srcline_idx < nlines) { dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx)); Dwarf_Addr postprologue_addr = lr.addr(); const char* postprologue_file = lr.linesrc(); int postprologue_lineno = lr.lineno(); if (sess.verbose>2) clog << "checking line record 0x" << hex << postprologue_addr << dec << "@" << postprologue_file << ":" << postprologue_lineno << "\n"; if (postprologue_addr >= highpc) { ranoff_end = true; postprologue_srcline_idx --; continue; } if (ranoff_end || (strcmp (postprologue_file, it->decl_file) || // We have a winner! (postprologue_lineno != it->decl_line))) { it->prologue_end = postprologue_addr; if (sess.verbose>2) { clog << "prologue found function '" << it->name << "'"; // Add a little classification datum if (postprologue_srcline_idx == entrypc_srcline_idx) clog << " (naked)"; if (ranoff_end) clog << " (tail-call?)"; clog << " = 0x" << hex << postprologue_addr << dec << "\n"; } break; } // Let's try the next srcline. postprologue_srcline_idx ++; } // loop over srclines // if (strlen(it->decl_file) == 0) it->decl_file = NULL; } // loop over functions // XXX: how to free lines? } bool dwflpp::function_entrypc (Dwarf_Addr * addr) { assert (function); return (dwarf_entrypc (function, addr) == 0); } bool dwflpp::die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr) { int rc = 0; string lookup_method; * addr = 0; lookup_method = "dwarf_entrypc"; rc = dwarf_entrypc (die, addr); if (rc) { lookup_method = "dwarf_ranges"; Dwarf_Addr base; Dwarf_Addr begin; Dwarf_Addr end; ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end); if (offset < 0) rc = -1; else if (offset > 0) { * addr = begin; rc = 0; // Now we need to check that there are no more ranges // associated with this function, which could conceivably // happen if a function is inlined, then pieces of it are // split amongst different conditional branches. It's not // obvious which of them to favour. As a heuristic, we // pick the beginning of the first range, and ignore the // others (but with a warning). unsigned extra = 0; while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0) extra ++; if (extra) lookup_method += ", ignored " + lex_cast(extra) + " more"; } } if (sess.verbose > 2) clog << "entry-pc lookup (" << lookup_method << ") = 0x" << hex << *addr << dec << " (rc " << rc << ")" << endl; return (rc == 0); } void dwflpp::function_die (Dwarf_Die *d) { assert (function); *d = *function; } void dwflpp::function_file (char const ** c) { assert (function); assert (c); *c = dwarf_decl_file (function); } void dwflpp::function_line (int *linep) { assert (function); dwarf_decl_line (function, linep); } bool dwflpp::die_has_pc (Dwarf_Die & die, Dwarf_Addr pc) { int res = dwarf_haspc (&die, pc); // dwarf_ranges will return -1 if a function die has no DW_AT_ranges // if (res == -1) // dwarf_assert ("dwarf_haspc", res); return res == 1; } void dwflpp::loc2c_error (void *, const char *fmt, ...) { const char *msg = "?"; char *tmp = NULL; int rc; va_list ap; va_start (ap, fmt); rc = vasprintf (& tmp, fmt, ap); if (rc < 0) msg = "?"; else msg = tmp; va_end (ap); throw semantic_error (msg); } // This function generates code used for addressing computations of // target variables. void dwflpp::emit_address (struct obstack *pool, Dwarf_Addr address) { #if 0 // The easy but incorrect way is to just print a hard-wired // constant. obstack_printf (pool, "%#" PRIx64 "UL", address); #endif // Turn this address into a section-relative offset if it should be one. // We emit a comment approximating the variable+offset expression that // relocatable module probing code will need to have. Dwfl_Module *mod = dwfl_addrmodule (dwfl, address); dwfl_assert ("dwfl_addrmodule", mod); const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL); int n = dwfl_module_relocations (mod); dwfl_assert ("dwfl_module_relocations", n >= 0); Dwarf_Addr reloc_address = address; int i = dwfl_module_relocate_address (mod, &reloc_address); dwfl_assert ("dwfl_module_relocate_address", i >= 0); dwfl_assert ("dwfl_module_info", modname); const char *secname = dwfl_module_relocation_info (mod, i, NULL); if (sess.verbose > 2) { clog << "emit dwarf addr 0x" << hex << address << dec << " => module " << modname << " section " << (secname ?: "null") << " relocaddr 0x" << hex << reloc_address << dec << endl; } if (n > 0 && !(n == 1 && secname == NULL)) { dwfl_assert ("dwfl_module_relocation_info", secname); if (n > 1 || secname[0] != '\0') { // This gives us the module name, and section name within the // module, for a kernel module (or other ET_REL module object). obstack_printf (pool, "({ static unsigned long addr = 0; "); obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ", modname, secname, reloc_address); obstack_printf (pool, "addr; })"); } else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0') { // elfutils' way of telling us that this is a relocatable kernel address, which we // need to treat the same way here as dwarf_query::add_probe_point does: _stext. address -= sess.sym_stext; secname = "_stext"; obstack_printf (pool, "({ static unsigned long addr = 0; "); obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ", modname, secname, address); // PR10000 NB: not reloc_address obstack_printf (pool, "addr; })"); } else { throw semantic_error ("cannot relocate user-space dso (?) address"); #if 0 // This would happen for a Dwfl_Module that's a user-level DSO. obstack_printf (pool, " /* %s+%#" PRIx64 " */", modname, address); #endif } } else obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant } void dwflpp::loc2c_emit_address (void *arg, struct obstack *pool, Dwarf_Addr address) { static_cast(arg)->emit_address (pool, address); } void dwflpp::print_locals(vector& scopes, ostream &o) { // XXX Shouldn't this be walking up to outer scopes too? // Try to get the first child of die. Dwarf_Die child; if (dwarf_child (&scopes[0], &child) == 0) { do { const char *name; // Output each sibling's name (that is a variable or // parameter) to 'o'. switch (dwarf_tag (&child)) { case DW_TAG_variable: case DW_TAG_formal_parameter: name = dwarf_diename (&child); if (name) o << " " << name; break; default: break; } } while (dwarf_siblingof (&child, &child) == 0); } } Dwarf_Attribute * dwflpp::find_variable_and_frame_base (vector& scopes, Dwarf_Addr pc, string const & local, const target_symbol *e, Dwarf_Die *vardie, Dwarf_Attribute *fb_attr_mem) { Dwarf_Die *scope_die = &scopes[0]; Dwarf_Attribute *fb_attr = NULL; assert (cu); int declaring_scope = dwarf_getscopevar (&scopes[0], scopes.size(), local.c_str(), 0, NULL, 0, 0, vardie); if (declaring_scope < 0) { stringstream alternatives; print_locals (scopes, alternatives); throw semantic_error ("unable to find local '" + local + "'" + " near pc " + lex_cast_hex(pc) + ((scope_die == NULL) ? "" : (string (" in ") + (dwarf_diename(scope_die) ?: "") + "(" + (dwarf_diename(cu) ?: "") + ")")) + (alternatives.str() == "" ? "" : (" (alternatives:" + alternatives.str () + ")")), e->tok); } /* We start out walking the "lexical scopes" as returned by * as returned by dwarf_getscopes for the address, starting with the * declaring_scope that the variable was found in. */ vector physcopes, *fbscopes = &scopes; for (size_t inner = declaring_scope; inner < fbscopes->size() && fb_attr == NULL; ++inner) { Dwarf_Die& scope = (*fbscopes)[inner]; switch (dwarf_tag (&scope)) { default: continue; case DW_TAG_subprogram: case DW_TAG_entry_point: fb_attr = dwarf_attr_integrate (&scope, DW_AT_frame_base, fb_attr_mem); break; case DW_TAG_inlined_subroutine: /* Unless we already are going through the "pyshical die tree", * we now need to start walking the die tree where this * subroutine is inlined to find the appropriate frame base. */ if (declaring_scope != -1) { physcopes = getscopes_die(&scope); if (physcopes.empty()) throw semantic_error ("unable to get die scopes for '" + local + "' in an inlined subroutines", e->tok); fbscopes = &physcopes; inner = 0; // zero is current scope, for look will increase. declaring_scope = -1; } break; } } return fb_attr; } struct location * dwflpp::translate_location(struct obstack *pool, Dwarf_Attribute *attr, Dwarf_Addr pc, Dwarf_Attribute *fb_attr, struct location **tail, const target_symbol *e) { /* DW_AT_data_member_location, can be either constant offsets (struct member fields), or full blown location expressions. In older elfutils, dwarf_getlocation_addr would not handle the constant for us, but newer ones do. For older ones, we work it by faking an expression, which is what newer ones do. */ #if !_ELFUTILS_PREREQ (0,142) if (dwarf_whatattr (attr) == DW_AT_data_member_location) { Dwarf_Op offset_loc; offset_loc.atom = DW_OP_plus_uconst; if (dwarf_formudata (attr, &offset_loc.number) == 0) return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0, pc, &offset_loc, 1, NULL, NULL, NULL); } #endif Dwarf_Op *expr; size_t len; /* PR9768: formerly, we added pc+module_bias here. However, that bias value is not present in the pc value by the time we get it, so adding it would result in false negatives of variable reachibility. In other instances further below, the c_translate_FOO functions, the module_bias value used to be passed in, but instead should now be zero for the same reason. */ switch (dwarf_getlocation_addr (attr, pc /*+ module_bias*/, &expr, &len, 1)) { case 1: /* Should always happen. */ if (len > 0) break; /* Fall through. */ case 0: /* Shouldn't happen. */ throw semantic_error ("not accessible at this address (" + lex_cast_hex(pc) + ")", e->tok); default: /* Shouldn't happen. */ case -1: throw semantic_error (string ("dwarf_getlocation_addr failed, ") + string (dwarf_errmsg (-1)), e->tok); } // get_cfa_ops works on the dw address space, pc is relative to current // module, so add do need to add module_bias. Dwarf_Op *cfa_ops = get_cfa_ops (pc + module_bias); return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, pc, attr, expr, len, tail, fb_attr, cfa_ops); } void dwflpp::print_members(Dwarf_Die *vardie, ostream &o) { const int typetag = dwarf_tag (vardie); if (typetag != DW_TAG_structure_type && typetag != DW_TAG_class_type && typetag != DW_TAG_union_type) { o << " Error: " << dwarf_type_name(vardie) << " isn't a struct/class/union"; return; } // Try to get the first child of vardie. Dwarf_Die die_mem; Dwarf_Die *die = &die_mem; switch (dwarf_child (vardie, die)) { case 1: // No children. o << dwarf_type_name(vardie) << " is empty"; break; case -1: // Error. default: // Shouldn't happen. o << dwarf_type_name(vardie) << ": " << dwarf_errmsg (-1); break; case 0: // Success. break; } // Output each sibling's name to 'o'. do { int tag = dwarf_tag(die); if (tag != DW_TAG_member && tag != DW_TAG_inheritance) continue; const char *member = dwarf_diename (die) ; if ( tag == DW_TAG_member && member != NULL ) o << " " << member; else { Dwarf_Die temp_die; if (!dwarf_attr_die (die, DW_AT_type, &temp_die)) { string source = dwarf_decl_file(die) ?: ""; int line = -1; dwarf_decl_line(die, &line); clog << "\n Error in obtaining type attribute for anonymous member at " << source << ":" << line; return; } print_members(&temp_die,o); } } while (dwarf_siblingof (die, die) == 0); } bool dwflpp::find_struct_member(const target_symbol::component& c, Dwarf_Die *parentdie, Dwarf_Die *memberdie, vector& locs) { Dwarf_Attribute attr; Dwarf_Die die; switch (dwarf_child (parentdie, &die)) { case 0: /* First child found. */ break; case 1: /* No children. */ return false; case -1: /* Error. */ default: /* Shouldn't happen */ throw semantic_error (dwarf_type_name(parentdie) + ": " + string (dwarf_errmsg (-1)), c.tok); } do { int tag = dwarf_tag(&die); if (tag != DW_TAG_member && tag != DW_TAG_inheritance) continue; const char *name = dwarf_diename(&die); if (name == NULL || tag == DW_TAG_inheritance) { // need to recurse for anonymous structs/unions and // for inherited members Dwarf_Die subdie; if (dwarf_attr_die (&die, DW_AT_type, &subdie) && find_struct_member(c, &subdie, memberdie, locs)) goto success; } else if (name == c.member) { *memberdie = die; goto success; } } while (dwarf_siblingof (&die, &die) == 0); return false; success: /* As we unwind the recursion, we need to build the chain of * locations that got to the final answer. */ if (dwarf_attr_integrate (&die, DW_AT_data_member_location, &attr)) locs.insert(locs.begin(), attr); /* Union members don't usually have a location, * but just use the containing union's location. */ else if (dwarf_tag(parentdie) != DW_TAG_union_type) throw semantic_error ("no location for field '" + c.member + "': " + string(dwarf_errmsg (-1)), c.tok); return true; } Dwarf_Die * dwflpp::translate_components(struct obstack *pool, struct location **tail, Dwarf_Addr pc, const target_symbol *e, Dwarf_Die *vardie, Dwarf_Die *die_mem, Dwarf_Attribute *attr_mem) { Dwarf_Die *die = NULL; unsigned i = 0; if (vardie) *die_mem = *vardie; if (e->components.empty()) return die_mem; while (i < e->components.size()) { const target_symbol::component& c = e->components[i]; /* XXX: This would be desirable, but we don't get the target_symbol token, and printing that gives us the file:line number too early anyway. */ #if 0 // Emit a marker to note which field is being access-attempted, to give // better error messages if deref() fails. string piece = string(...target_symbol token...) + string ("#") + lex_cast(components[i].second); obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str()); #endif die = die ? dwarf_formref_die (attr_mem, die_mem) : die_mem; const int typetag = dwarf_tag (die); switch (typetag) { case DW_TAG_typedef: case DW_TAG_const_type: case DW_TAG_volatile_type: /* Just iterate on the referent type. */ break; case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); break; case DW_TAG_pointer_type: /* A pointer with no type is a void* -- can't dereference it. */ if (!dwarf_hasattr_integrate (die, DW_AT_type)) throw semantic_error ("invalid access '" + lex_cast(c) + "' vs. " + dwarf_type_name(die), c.tok); c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); if (c.type != target_symbol::comp_literal_array_index && c.type != target_symbol::comp_expression_array_index) break; /* else fall through as an array access */ case DW_TAG_array_type: if (c.type == target_symbol::comp_literal_array_index) { c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, NULL, c.num_index); ++i; } else if (c.type == target_symbol::comp_expression_array_index) { string index = "THIS->index" + lex_cast(i); c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, index.c_str(), 0); ++i; } else throw semantic_error ("invalid access '" + lex_cast(c) + "' for array type", c.tok); break; case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_class_type: if (c.type != target_symbol::comp_struct_member) throw semantic_error ("invalid access '" + lex_cast(c) + "' for " + dwarf_type_name(die), c.tok); if (dwarf_hasattr(die, DW_AT_declaration)) { Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die)); if (tmpdie == NULL) throw semantic_error ("unresolved " + dwarf_type_name(die), c.tok); *die_mem = *tmpdie; } { Dwarf_Die parentdie = *die; vector locs; if (!find_struct_member(c, &parentdie, die, locs)) { /* Add a file:line hint for anonymous types */ string source; if (!dwarf_hasattr_integrate(&parentdie, DW_AT_name)) { int line; const char *file = dwarf_decl_file(&parentdie); if (file && dwarf_decl_line(&parentdie, &line) == 0) source = " (" + string(file) + ":" + lex_cast(line) + ")"; } string alternatives; stringstream members; print_members(&parentdie, members); if (members.str().size() != 0) alternatives = " (alternatives:" + members.str() + ")"; throw semantic_error("unable to find member '" + c.member + "' for " + dwarf_type_name(&parentdie) + source + alternatives, c.tok); } for (unsigned j = 0; j < locs.size(); ++j) translate_location (pool, &locs[j], pc, NULL, tail, e); } ++i; break; case DW_TAG_enumeration_type: case DW_TAG_base_type: throw semantic_error ("invalid access '" + lex_cast(c) + "' vs. " + dwarf_type_name(die), c.tok); break; case -1: throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)), c.tok); break; default: throw semantic_error (dwarf_type_name(die) + ": unexpected type tag " + lex_cast(dwarf_tag (die)), c.tok); break; } /* Now iterate on the type in DIE's attribute. */ if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL) throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), c.tok); } /* For an array index, we need to dereference the final DIE */ if (e->components.back().type == target_symbol::comp_literal_array_index || e->components.back().type == target_symbol::comp_expression_array_index) die = dwarf_formref_die (attr_mem, die_mem); return die; } Dwarf_Die * dwflpp::resolve_unqualified_inner_typedie (Dwarf_Die *typedie_mem, Dwarf_Attribute *attr_mem, const target_symbol *e) { Dwarf_Die *typedie; int typetag = 0; while (1) { typedie = dwarf_formref_die (attr_mem, typedie_mem); if (typedie == NULL) throw semantic_error ("cannot get type: " + string(dwarf_errmsg (-1)), e->tok); typetag = dwarf_tag (typedie); if (typetag != DW_TAG_typedef && typetag != DW_TAG_const_type && typetag != DW_TAG_volatile_type) break; if (dwarf_attr_integrate (typedie, DW_AT_type, attr_mem) == NULL) throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)), e->tok); } return typedie; } void dwflpp::translate_final_fetch_or_store (struct obstack *pool, struct location **tail, Dwarf_Addr module_bias, Dwarf_Die *die, Dwarf_Attribute *attr_mem, bool lvalue, const target_symbol *e, string &, string &, exp_type & ty) { /* First boil away any qualifiers associated with the type DIE of the final location to be accessed. */ Dwarf_Die typedie_mem; Dwarf_Die *typedie; int typetag; typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem, e); typetag = dwarf_tag (typedie); /* If we're looking for an address, then we can just provide what we computed to this point, without using a fetch/store. */ if (e->addressof) { if (lvalue) throw semantic_error ("cannot write to member address", e->tok); if (dwarf_hasattr_integrate (die, DW_AT_bit_offset)) throw semantic_error ("cannot take address of bit-field", e->tok); c_translate_addressof (pool, 1, 0, 0, die, tail, "THIS->__retvalue"); ty = pe_long; return; } /* Then switch behavior depending on the type of fetch/store we want, and the type and pointer-ness of the final location. */ switch (typetag) { default: throw semantic_error ("unsupported type tag " + lex_cast(typetag) + " for " + dwarf_type_name(typedie), e->tok); break; case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_union_type: throw semantic_error ("'" + dwarf_type_name(typedie) + "' is being accessed instead of a member", e->tok); break; case DW_TAG_enumeration_type: case DW_TAG_base_type: // Reject types we can't handle in systemtap { Dwarf_Attribute encoding_attr; Dwarf_Word encoding = (Dwarf_Word) -1; dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr), & encoding); if (encoding < 0) { // clog << "bad type1 " << encoding << " diestr" << endl; throw semantic_error ("unsupported type (mystery encoding " + lex_cast(encoding) + ")" + " for " + dwarf_type_name(typedie), e->tok); } if (encoding == DW_ATE_float || encoding == DW_ATE_complex_float /* XXX || many others? */) { // clog << "bad type " << encoding << " diestr" << endl; throw semantic_error ("unsupported type (encoding " + lex_cast(encoding) + ")" + " for " + dwarf_type_name(typedie), e->tok); } } ty = pe_long; if (lvalue) c_translate_store (pool, 1, 0 /* PR9768 */, die, typedie, tail, "THIS->value"); else c_translate_fetch (pool, 1, 0 /* PR9768 */, die, typedie, tail, "THIS->__retvalue"); break; case DW_TAG_array_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: { Dwarf_Die pointee_typedie_mem; Dwarf_Die *pointee_typedie; Dwarf_Word pointee_encoding; Dwarf_Word pointee_byte_size = 0; pointee_typedie = resolve_unqualified_inner_typedie (&pointee_typedie_mem, attr_mem, e); if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, attr_mem)) dwarf_formudata (attr_mem, &pointee_byte_size); dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem), &pointee_encoding); if (lvalue) { ty = pe_long; if (typetag == DW_TAG_array_type) throw semantic_error ("cannot write to array address", e->tok); if (typetag == DW_TAG_reference_type || typetag == DW_TAG_rvalue_reference_type) throw semantic_error ("cannot write to reference", e->tok); assert (typetag == DW_TAG_pointer_type); c_translate_pointer_store (pool, 1, 0 /* PR9768 */, typedie, tail, "THIS->value"); } else { // We have the pointer: cast it to an integral type via &(*(...)) // NB: per bug #1187, at one point char*-like types were // automagically converted here to systemtap string values. // For several reasons, this was taken back out, leaving // pointer-to-string "conversion" (copying) to tapset functions. ty = pe_long; if (typetag == DW_TAG_array_type) c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail, NULL, 0); else c_translate_pointer (pool, 1, 0 /* PR9768 */, typedie, tail); c_translate_addressof (pool, 1, 0 /* PR9768 */, NULL, pointee_typedie, tail, "THIS->__retvalue"); } } break; } } string dwflpp::express_as_string (string prelude, string postlude, struct location *head) { size_t bufsz = 1024; char *buf = static_cast(malloc(bufsz)); assert(buf); FILE *memstream = open_memstream (&buf, &bufsz); assert(memstream); fprintf(memstream, "{\n"); fprintf(memstream, "%s", prelude.c_str()); bool deref = c_emit_location (memstream, head, 1); fprintf(memstream, "%s", postlude.c_str()); fprintf(memstream, " goto out;\n"); // dummy use of deref_fault label, to disable warning if deref() not used fprintf(memstream, "if (0) goto deref_fault;\n"); // XXX: deref flag not reliable; emit fault label unconditionally (void) deref; fprintf(memstream, "deref_fault:\n" " goto out;\n"); fprintf(memstream, "}\n"); fclose (memstream); string result(buf); free (buf); return result; } string dwflpp::literal_stmt_for_local (vector& scopes, Dwarf_Addr pc, string const & local, const target_symbol *e, bool lvalue, exp_type & ty) { Dwarf_Die vardie; Dwarf_Attribute fb_attr_mem, *fb_attr = NULL; fb_attr = find_variable_and_frame_base (scopes, pc, local, e, &vardie, &fb_attr_mem); if (sess.verbose>2) clog << "finding location for local '" << local << "' near address 0x" << hex << pc << ", module bias 0x" << module_bias << dec << "\n"; Dwarf_Attribute attr_mem; if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL) { throw semantic_error("failed to retrieve location " "attribute for local '" + local + "' (dieoffset: " + lex_cast_hex(dwarf_dieoffset (&vardie)) + ")", e->tok); } #define obstack_chunk_alloc malloc #define obstack_chunk_free free struct obstack pool; obstack_init (&pool); struct location *tail = NULL; /* Given $foo->bar->baz[NN], translate the location of foo. */ struct location *head = translate_location (&pool, &attr_mem, pc, fb_attr, &tail, e); if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL) throw semantic_error("failed to retrieve type " "attribute for local '" + local + "'", e->tok); /* Translate the ->bar->baz[NN] parts. */ Dwarf_Die die_mem, *die = dwarf_formref_die (&attr_mem, &die_mem); die = translate_components (&pool, &tail, pc, e, die, &die_mem, &attr_mem); /* Translate the assignment part, either x = $foo->bar->baz[NN] or $foo->bar->baz[NN] = x */ string prelude, postlude; translate_final_fetch_or_store (&pool, &tail, module_bias, die, &attr_mem, lvalue, e, prelude, postlude, ty); /* Write the translation to a string. */ return express_as_string(prelude, postlude, head); } string dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die, Dwarf_Addr pc, const target_symbol *e, bool lvalue, exp_type & ty) { if (sess.verbose>2) clog << "literal_stmt_for_return: finding return value for " << (dwarf_diename(scope_die) ?: "") << "(" << (dwarf_diename(cu) ?: "") << ")\n"; struct obstack pool; obstack_init (&pool); struct location *tail = NULL; /* Given $return->bar->baz[NN], translate the location of return. */ const Dwarf_Op *locops; int nlocops = dwfl_module_return_value_location (module, scope_die, &locops); if (nlocops < 0) { throw semantic_error("failed to retrieve return value location" " for " + string(dwarf_diename(scope_die) ?: "") + "(" + string(dwarf_diename(cu) ?: "") + ")", e->tok); } // the function has no return value (e.g. "void" in C) else if (nlocops == 0) { throw semantic_error("function " + string(dwarf_diename(scope_die) ?: "") + "(" + string(dwarf_diename(cu) ?: "") + ") has no return value", e->tok); } struct location *head = c_translate_location (&pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, pc, NULL, locops, nlocops, &tail, NULL, NULL); /* Translate the ->bar->baz[NN] parts. */ Dwarf_Attribute attr_mem; if (dwarf_attr_integrate (scope_die, DW_AT_type, &attr_mem) == NULL) throw semantic_error("failed to retrieve return value type attribute for " + string(dwarf_diename(scope_die) ?: "") + "(" + string(dwarf_diename(cu) ?: "") + ")", e->tok); Dwarf_Die die_mem, *die = dwarf_formref_die (&attr_mem, &die_mem); die = translate_components (&pool, &tail, pc, e, die, &die_mem, &attr_mem); /* Translate the assignment part, either x = $return->bar->baz[NN] or $return->bar->baz[NN] = x */ string prelude, postlude; translate_final_fetch_or_store (&pool, &tail, module_bias, die, &attr_mem, lvalue, e, prelude, postlude, ty); /* Write the translation to a string. */ return express_as_string(prelude, postlude, head); } string dwflpp::literal_stmt_for_pointer (Dwarf_Die *type_die, const target_symbol *e, bool lvalue, exp_type & ty) { if (sess.verbose>2) clog << "literal_stmt_for_pointer: finding value for " << dwarf_type_name(type_die) << "(" << (dwarf_diename(cu) ?: "") << ")\n"; struct obstack pool; obstack_init (&pool); struct location *head = c_translate_argument (&pool, &loc2c_error, this, &loc2c_emit_address, 1, "THIS->pointer"); struct location *tail = head; /* Translate the ->bar->baz[NN] parts. */ Dwarf_Attribute attr_mem; Dwarf_Die die_mem, *die = NULL; die = translate_components (&pool, &tail, 0, e, type_die, &die_mem, &attr_mem); /* Translate the assignment part, either x = (THIS->pointer)->bar->baz[NN] or (THIS->pointer)->bar->baz[NN] = x */ string prelude, postlude; translate_final_fetch_or_store (&pool, &tail, module_bias, die, &attr_mem, lvalue, e, prelude, postlude, ty); /* Write the translation to a string. */ return express_as_string(prelude, postlude, head); } static bool in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr) { if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0) { // If the probe point address is anywhere in the __kprobes // address range, we can't use this probe point. if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end) return true; } return false; } bool dwflpp::blacklisted_p(const string& funcname, const string& filename, int, const string& module, Dwarf_Addr addr, bool has_return) { if (!blacklist_enabled) return false; // no blacklist for userspace string section = get_blacklist_section(addr); if (!regexec (&blacklist_section, section.c_str(), 0, NULL, 0)) { // NB: module .exit. routines could be probed in theory: // if the exit handler in "struct module" is diverted, // first inserting the kprobes // then allowing the exit code to run // then removing these kprobes if (sess.verbose>1) clog << " skipping - init/exit"; return true; } // Check for function marked '__kprobes'. if (module == TOK_KERNEL && in_kprobes_function(sess, addr)) { if (sess.verbose>1) clog << " skipping - __kprobes"; return true; } // Check probe point against blacklist. int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0); if (has_return) goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0); int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0); if (! (goodfn && goodfile)) { if (sess.guru_mode) { if (sess.verbose>1) clog << " guru mode enabled - ignoring blacklist"; } else { if (sess.verbose>1) clog << " skipping - blacklisted"; return true; } } // This probe point is not blacklisted. return false; } void dwflpp::build_blacklist() { // We build up the regexps in these strings // Add ^ anchors at the front; $ will be added just before regcomp. string blfn = "^("; string blfn_ret = "^("; string blfile = "^("; string blsection = "^("; blsection += "\\.init\\."; // first alternative, no "|" blsection += "|\\.exit\\."; blsection += "|\\.devinit\\."; blsection += "|\\.devexit\\."; blsection += "|\\.cpuinit\\."; blsection += "|\\.cpuexit\\."; blsection += "|\\.meminit\\."; blsection += "|\\.memexit\\."; blfile += "kernel/kprobes\\.c"; // first alternative, no "|" blfile += "|arch/.*/kernel/kprobes\\.c"; // Older kernels need ... blfile += "|include/asm/io\\.h"; blfile += "|include/asm/bitops\\.h"; // While newer ones need ... blfile += "|arch/.*/include/asm/io\\.h"; blfile += "|arch/.*/include/asm/bitops\\.h"; blfile += "|drivers/ide/ide-iops\\.c"; // XXX: it would be nice if these blacklisted functions were pulled // in dynamically, instead of being statically defined here. // Perhaps it could be populated from script files. A "noprobe // kernel.function("...")" construct might do the trick. // Most of these are marked __kprobes in newer kernels. We list // them here (anyway) so the translator can block them on older // kernels that don't have the __kprobes function decorator. This // also allows detection of problems at translate- rather than // run-time. blfn += "atomic_notifier_call_chain"; // first blfn; no "|" blfn += "|default_do_nmi"; blfn += "|__die"; blfn += "|die_nmi"; blfn += "|do_debug"; blfn += "|do_general_protection"; blfn += "|do_int3"; blfn += "|do_IRQ"; blfn += "|do_page_fault"; blfn += "|do_sparc64_fault"; blfn += "|do_trap"; blfn += "|dummy_nmi_callback"; blfn += "|flush_icache_range"; blfn += "|ia64_bad_break"; blfn += "|ia64_do_page_fault"; blfn += "|ia64_fault"; blfn += "|io_check_error"; blfn += "|mem_parity_error"; blfn += "|nmi_watchdog_tick"; blfn += "|notifier_call_chain"; blfn += "|oops_begin"; blfn += "|oops_end"; blfn += "|program_check_exception"; blfn += "|single_step_exception"; blfn += "|sync_regs"; blfn += "|unhandled_fault"; blfn += "|unknown_nmi_error"; // Lots of locks blfn += "|.*raw_.*lock.*"; blfn += "|.*read_.*lock.*"; blfn += "|.*write_.*lock.*"; blfn += "|.*spin_.*lock.*"; blfn += "|.*rwlock_.*lock.*"; blfn += "|.*rwsem_.*lock.*"; blfn += "|.*mutex_.*lock.*"; blfn += "|raw_.*"; blfn += "|.*seq_.*lock.*"; // atomic functions blfn += "|atomic_.*"; blfn += "|atomic64_.*"; // few other problematic cases blfn += "|get_bh"; blfn += "|put_bh"; // Experimental blfn += "|.*apic.*|.*APIC.*"; blfn += "|.*softirq.*"; blfn += "|.*IRQ.*"; blfn += "|.*_intr.*"; blfn += "|__delay"; blfn += "|.*kernel_text.*"; blfn += "|get_current"; blfn += "|current_.*"; blfn += "|.*exception_tables.*"; blfn += "|.*setup_rt_frame.*"; // PR 5759, CONFIG_PREEMPT kernels blfn += "|.*preempt_count.*"; blfn += "|preempt_schedule"; // These functions don't return, so return probes would never be recovered blfn_ret += "do_exit"; // no "|" blfn_ret += "|sys_exit"; blfn_ret += "|sys_exit_group"; // __switch_to changes "current" on x86_64 and i686, so return probes // would cause kernel panic, and it is marked as "__kprobes" on x86_64 if (sess.architecture == "x86_64") blfn += "|__switch_to"; if (sess.architecture == "i686") blfn_ret += "|__switch_to"; blfn += ")$"; blfn_ret += ")$"; blfile += ")$"; blsection += ")"; // NB: no $, sections match just the beginning if (sess.verbose > 2) { clog << "blacklist regexps:" << endl; clog << "blfn: " << blfn << endl; clog << "blfn_ret: " << blfn_ret << endl; clog << "blfile: " << blfile << endl; clog << "blsection: " << blsection << endl; } int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED); if (rc) throw semantic_error ("blacklist_func regcomp failed"); rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED); if (rc) throw semantic_error ("blacklist_func_ret regcomp failed"); rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED); if (rc) throw semantic_error ("blacklist_file regcomp failed"); rc = regcomp (& blacklist_section, blsection.c_str(), REG_NOSUB|REG_EXTENDED); if (rc) throw semantic_error ("blacklist_section regcomp failed"); blacklist_enabled = true; } string dwflpp::get_blacklist_section(Dwarf_Addr addr) { string blacklist_section; Dwarf_Addr bias; // We prefer dwfl_module_getdwarf to dwfl_module_getelf here, // because dwfl_module_getelf can force costly section relocations // we don't really need, while either will do for this purpose. Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias)) ?: dwfl_module_getelf (module, &bias)); Dwarf_Addr offset = addr - bias; if (elf) { Elf_Scn* scn = 0; size_t shstrndx; dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx)); while ((scn = elf_nextscn (elf, scn)) != NULL) { GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); if (! shdr) continue; // XXX error? if (!(shdr->sh_flags & SHF_ALLOC)) continue; GElf_Addr start = shdr->sh_addr; GElf_Addr end = start + shdr->sh_size; if (! (offset >= start && offset < end)) continue; blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name); break; } } return blacklist_section; } Dwarf_Addr dwflpp::relocate_address(Dwarf_Addr dw_addr, string& reloc_section) { // PR10273 // libdw address, so adjust for bias gotten from dwfl_module_getdwarf Dwarf_Addr reloc_addr = dw_addr + module_bias; if (!module) { assert(module_name == TOK_KERNEL); reloc_section = ""; } else if (dwfl_module_relocations (module) > 0) { // This is a relocatable module; libdwfl already knows its // sections, so we can relativize addr. int idx = dwfl_module_relocate_address (module, &reloc_addr); const char* r_s = dwfl_module_relocation_info (module, idx, NULL); if (r_s) reloc_section = r_s; if (reloc_section == "" && dwfl_module_relocations (module) == 1) reloc_section = ".dynamic"; } else reloc_section = ".absolute"; return reloc_addr; } /* Converts a "global" literal address to the module symbol address * space. If necessary (not for kernel and executables using absolute * addresses), this adjust the address for the current module symbol * bias. Literal addresses are provided by the user (or contained on * the .probes section) based on the "on disk" layout of the module. */ Dwarf_Addr dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr) { if (sess.verbose > 2) clog << "literal_addr_to_sym_addr 0x" << hex << lit_addr << dec << endl; // Assume the address came from the symbol list. // If we cannot get the symbol bias fall back on the dw bias. // The kernel (and other absolute executable modules) is special though. if (module_name != TOK_KERNEL && dwfl_module_relocations (module) > 0) { Dwarf_Addr symbias = ~0; if (dwfl_module_getsymtab (module) != -1) dwfl_module_info (module, NULL, NULL, NULL, NULL, &symbias, NULL, NULL); if (sess.verbose > 3) clog << "symbias 0x" << hex << symbias << dec << ", dwbias 0x" << hex << module_bias << dec << endl; if (symbias == (Dwarf_Addr) ~0) symbias = module_bias; lit_addr += symbias; } if (sess.verbose > 2) clog << "literal_addr_to_sym_addr ret 0x" << hex << lit_addr << dec << endl; return lit_addr; } /* Returns the call frame address operations for the given program counter * in the libdw address space. */ Dwarf_Op * dwflpp::get_cfa_ops (Dwarf_Addr pc) { Dwarf_Op *cfa_ops = NULL; if (sess.verbose > 2) clog << "get_cfa_ops @0x" << hex << pc << dec << ", module_start @0x" << hex << module_start << dec << endl; #if _ELFUTILS_PREREQ(0,142) // Try debug_frame first, then fall back on eh_frame. size_t cfa_nops; Dwarf_Addr bias; Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); if (cfi != NULL) { if (sess.verbose > 3) clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); else if (sess.verbose > 3) clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } else if (sess.verbose > 3) clog << "dwfl_module_dwarf_cfi failed: " << dwfl_errmsg(-1) << endl; if (cfa_ops == NULL) { cfi = dwfl_module_eh_cfi (module, &bias); if (cfi != NULL) { if (sess.verbose > 3) clog << "got eh cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); else if (sess.verbose > 3) clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } else if (sess.verbose > 3) clog << "dwfl_module_eh_cfi failed: " << dwfl_errmsg(-1) << endl; } #endif if (sess.verbose > 2) clog << (cfa_ops == NULL ? "not " : " ") << "found cfa" << endl; return cfa_ops; } /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ 3 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533
%PDF-1.3
%âãÏÓ
1 0 obj<</Producer(htmldoc 1.8.22 Copyright 1997-2002 Easy Software Products, All Rights Reserved.)/CreationDate(D:20030115164419+0600)/Title(SAMBA Developers Guide)/Creator(Modular DocBook HTML Stylesheet Version 1.77)>>endobj
2 0 obj<</Type/Encoding/Differences[ 32/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quotesingle/parenleft/parenright/asterisk/plus/comma/minus/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/grave/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 128/Euro 130/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 145/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 159/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]>>endobj
3 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier/Encoding 2 0 R>>endobj
4 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier-Bold/Encoding 2 0 R>>endobj
5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Courier-Oblique/Encoding 2 0 R>>endobj
6 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Roman/Encoding 2 0 R>>endobj
7 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Bold/Encoding 2 0 R>>endobj
8 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-Italic/Encoding 2 0 R>>endobj
9 0 obj<</Type/Font/Subtype/Type1/BaseFont/Times-BoldItalic/Encoding 2 0 R>>endobj
10 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding 2 0 R>>endobj
11 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica-Bold/Encoding 2 0 R>>endobj
12 0 obj<</Type/Font/Subtype/Type1/BaseFont/Symbol>>endobj
13 0 obj<</Subtype/Link/Rect[72.0 684.0 197.9 697.0]/Border[0 0 0]/Dest[524 0 R/XYZ 0 734 0]>>endobj
14 0 obj<</Subtype/Link/Rect[108.0 670.8 174.9 683.8]/Border[0 0 0]/Dest[524 0 R/XYZ 0 696 0]>>endobj
15 0 obj<</Subtype/Link/Rect[72.0 644.4 112.9 657.4]/Border[0 0 0]/Dest[526 0 R/XYZ 0 734 0]>>endobj
16 0 obj<</Subtype/Link/Rect[72.0 618.0 409.3 631.0]/Border[0 0 0]/Dest[532 0 R/XYZ 0 734 0]>>endobj
17 0 obj<</Subtype/Link/Rect[108.0 604.8 173.7 617.8]/Border[0 0 0]/Dest[532 0 R/XYZ 0 672 0]>>endobj
18 0 obj<</Subtype/Link/Rect[108.0 591.6 237.6 604.6]/Border[0 0 0]/Dest[532 0 R/XYZ 0 201 0]>>endobj
19 0 obj<</Subtype/Link/Rect[108.0 578.4 200.3 591.4]/Border[0 0 0]/Dest[534 0 R/XYZ 0 705 0]>>endobj
20 0 obj<</Subtype/Link/Rect[72.0 552.0 219.9 565.0]/Border[0 0 0]/Dest[536 0 R/XYZ 0 734 0]>>endobj
21 0 obj<</Subtype/Link/Rect[108.0 538.8 181.6 551.8]/Border[0 0 0]/Dest[536 0 R/XYZ 0 696 0]>>endobj
22 0 obj<</Subtype/Link/Rect[108.0 525.6 244.6 538.6]/Border[0 0 0]/Dest[536 0 R/XYZ 0 529 0]>>endobj
23 0 obj<</Subtype/Link/Rect[108.0 512.4 199.0 525.4]/Border[0 0 0]/Dest[536 0 R/XYZ 0 335 0]>>endobj
24 0 obj<</Subtype/Link/Rect[108.0 499.2 200.3 512.2]/Border[0 0 0]/Dest[538 0 R/XYZ 0 734 0]>>endobj
25 0 obj<</Subtype/Link/Rect[108.0 486.0 186.2 499.0]/Border[0 0 0]/Dest[538 0 R/XYZ 0 434 0]>>endobj
26 0 obj<</Subtype/Link/Rect[72.0 459.6 252.9 472.6]/Border[0 0 0]/Dest[540 0 R/XYZ 0 734 0]>>endobj
27 0 obj<</Subtype/Link/Rect[108.0 446.4 214.6 459.4]/Border[0 0 0]/Dest[540 0 R/XYZ 0 696 0]>>endobj
28 0 obj<</Subtype/Link/Rect[108.0 433.2 223.8 446.2]/Border[0 0 0]/Dest[542 0 R/XYZ 0 734 0]>>endobj
29 0 obj<</Subtype/Link/Rect[108.0 420.0 247.6 433.0]/Border[0 0 0]/Dest[544 0 R/XYZ 0 734 0]>>endobj
30 0 obj<</Subtype/Link/Rect[108.0 406.8 245.2 419.8]/Border[0 0 0]/Dest[544 0 R/XYZ 0 514 0]>>endobj
31 0 obj<</Subtype/Link/Rect[108.0 393.6 194.2 406.6]/Border[0 0 0]/Dest[546 0 R/XYZ 0 734 0]>>endobj
32 0 obj<</Subtype/Link/Rect[126.0 380.4 193.8 393.4]/Border[0 0 0]/Dest[546 0 R/XYZ 0 700 0]>>endobj
33 0 obj<</Subtype/Link/Rect[126.0 367.2 192.0 380.2]/Border[0 0 0]/Dest[546 0 R/XYZ 0 602 0]>>endobj
34 0 obj<</Subtype/Link/Rect[126.0 354.0 244.5 367.0]/Border[0 0 0]/Dest[546 0 R/XYZ 0 491 0]>>endobj
35 0 obj<</Subtype/Link/Rect[72.0 327.6 216.8 340.6]/Border[0 0 0]/Dest[548 0 R/XYZ 0 734 0]>>endobj
36 0 obj<</Subtype/Link/Rect[72.0 301.2 202.8 314.2]/Border[0 0 0]/Dest[552 0 R/XYZ 0 734 0]>>endobj
37 0 obj<</Subtype/Link/Rect[108.0 288.0 213.7 301.0]/Border[0 0 0]/Dest[552 0 R/XYZ 0 696 0]>>endobj
38 0 obj<</Subtype/Link/Rect[108.0 274.8 209.1 287.8]/Border[0 0 0]/Dest[552 0 R/XYZ 0 568 0]>>endobj
39 0 obj<</Subtype/Link/Rect[108.0 261.6 224.7 274.6]/Border[0 0 0]/Dest[554 0 R/XYZ 0 705 0]>>endobj
40 0 obj<</Subtype/Link/Rect[126.0 248.4 223.5 261.4]/Border[0 0 0]/Dest[554 0 R/XYZ 0 630 0]>>endobj
41 0 obj<</Subtype/Link/Rect[126.0 235.2 222.2 248.2]/Border[0 0 0]/Dest[554 0 R/XYZ 0 571 0]>>endobj
42 0 obj<</Subtype/Link/Rect[126.0 222.0 245.8 235.0]/Border[0 0 0]/Dest[554 0 R/XYZ 0 513 0]>>endobj
43 0 obj<</Subtype/Link/Rect[126.0 208.8 222.2 221.8]/Border[0 0 0]/Dest[554 0 R/XYZ 0 455 0]>>endobj
44 0 obj<</Subtype/Link/Rect[126.0 195.6 219.8 208.6]/Border[0 0 0]/Dest[554 0 R/XYZ 0 383 0]>>endobj
45 0 obj<</Subtype/Link/Rect[126.0 182.4 228.4 195.4]/Border[0 0 0]/Dest[554 0 R/XYZ 0 325 0]>>endobj
46 0 obj<</Subtype/Link/Rect[126.0 169.2 225.9 182.2]/Border[0 0 0]/Dest[554 0 R/XYZ 0 266 0]>>endobj
47 0 obj<</Subtype/Link/Rect[126.0 156.0 244.5 169.0]/Border[0 0 0]/Dest[554 0 R/XYZ 0 208 0]>>endobj
48 0 obj<</Subtype/Link/Rect[126.0 142.8 242.1 155.8]/Border[0 0 0]/Dest[554 0 R/XYZ 0 149 0]>>endobj
49 0 obj<</Subtype/Link/Rect[126.0 129.6 256.2 142.6]/Border[0 0 0]/Dest[556 0 R/XYZ 0 734 0]>>endobj
50 0 obj<</Subtype/Link/Rect[126.0 116.4 253.7 129.4]/Border[0 0 0]/Dest[556 0 R/XYZ 0 675 0]>>endobj
51 0 obj<</Subtype/Link/Rect[126.0 103.2 235.1 116.2]/Border[0 0 0]/Dest[556 0 R/XYZ 0 617 0]>>endobj
52 0 obj<</Subtype/Link/Rect[126.0 90.0 232.6 103.0]/Border[0 0 0]/Dest[556 0 R/XYZ 0 558 0]>>endobj
53 0 obj<</Subtype/Link/Rect[126.0 76.8 257.4 89.8]/Border[0 0 0]/Dest[556 0 R/XYZ 0 500 0]>>endobj
54 0 obj<</Subtype/Link/Rect[126.0 63.6 254.9 76.6]/Border[0 0 0]/Dest[556 0 R/XYZ 0 428 0]>>endobj
55 0 obj[13 0 R
14 0 R
15 0 R
16 0 R
17 0 R
18 0 R
19 0 R
20 0 R
21 0 R
22 0 R
23 0 R
24 0 R
25 0 R
26 0 R
27 0 R
28 0 R
29 0 R
30 0 R
31 0 R
32 0 R
33 0 R
34 0 R
35 0 R
36 0 R
37 0 R
38 0 R
39 0 R
40 0 R
41 0 R
42 0 R
43 0 R
44 0 R
45 0 R
46 0 R
47 0 R
48 0 R
49 0 R
50 0 R
51 0 R
52 0 R
53 0 R
54 0 R]endobj
56 0 obj<</Subtype/Link/Rect[72.0 684.0 202.8 697.0]/Border[0 0 0]/Dest[552 0 R/XYZ 0 734 0]>>endobj
57 0 obj<</Subtype/Link/Rect[108.0 670.8 244.9 683.8]/Border[0 0 0]/Dest[556 0 R/XYZ 0 370 0]>>endobj
58 0 obj<</Subtype/Link/Rect[126.0 657.6 202.4 670.6]/Border[0 0 0]/Dest[556 0 R/XYZ 0 220 0]>>endobj
59 0 obj<</Subtype/Link/Rect[126.0 644.4 210.0 657.4]/Border[0 0 0]/Dest[558 0 R/XYZ 0 441 0]>>endobj
60 0 obj<</Subtype/Link/Rect[108.0 631.2 217.7 644.2]/Border[0 0 0]/Dest[560 0 R/XYZ 0 734 0]>>endobj
61 0 obj<</Subtype/Link/Rect[72.0 604.8 205.8 617.8]/Border[0 0 0]/Dest[562 0 R/XYZ 0 734 0]>>endobj
62 0 obj<</Subtype/Link/Rect[108.0 591.6 201.5 604.6]/Border[0 0 0]/Dest[562 0 R/XYZ 0 696 0]>>endobj
63 0 obj<</Subtype/Link/Rect[126.0 578.4 260.4 591.4]/Border[0 0 0]/Dest[562 0 R/XYZ 0 423 0]>>endobj
64 0 obj<</Subtype/Link/Rect[126.0 565.2 289.5 578.2]/Border[0 0 0]/Dest[562 0 R/XYZ 0 259 0]>>endobj
65 0 obj<</Subtype/Link/Rect[126.0 552.0 266.6 565.0]/Border[0 0 0]/Dest[564 0 R/XYZ 0 652 0]>>endobj
66 0 obj<</Subtype/Link/Rect[108.0 538.8 157.8 551.8]/Border[0 0 0]/Dest[564 0 R/XYZ 0 240 0]>>endobj
67 0 obj<</Subtype/Link/Rect[126.0 525.6 223.2 538.6]/Border[0 0 0]/Dest[566 0 R/XYZ 0 665 0]>>endobj
68 0 obj<</Subtype/Link/Rect[72.0 499.2 246.5 512.2]/Border[0 0 0]/Dest[568 0 R/XYZ 0 734 0]>>endobj
69 0 obj<</Subtype/Link/Rect[108.0 486.0 181.6 499.0]/Border[0 0 0]/Dest[568 0 R/XYZ 0 696 0]>>endobj
70 0 obj<</Subtype/Link/Rect[108.0 472.8 176.1 485.8]/Border[0 0 0]/Dest[568 0 R/XYZ 0 595 0]>>endobj
71 0 obj<</Subtype/Link/Rect[108.0 459.6 195.4 472.6]/Border[0 0 0]/Dest[568 0 R/XYZ 0 216 0]>>endobj
72 0 obj<</Subtype/Link/Rect[108.0 446.4 173.7 459.4]/Border[0 0 0]/Dest[570 0 R/XYZ 0 692 0]>>endobj
73 0 obj<</Subtype/Link/Rect[108.0 433.2 163.9 446.2]/Border[0 0 0]/Dest[570 0 R/XYZ 0 458 0]>>endobj
74 0 obj<</Subtype/Link/Rect[108.0 420.0 183.8 433.0]/Border[0 0 0]/Dest[572 0 R/XYZ 0 734 0]>>endobj
75 0 obj<</Subtype/Link/Rect[108.0 406.8 194.8 419.8]/Border[0 0 0]/Dest[572 0 R/XYZ 0 566 0]>>endobj
76 0 obj<</Subtype/Link/Rect[108.0 393.6 186.2 406.6]/Border[0 0 0]/Dest[572 0 R/XYZ 0 438 0]>>endobj
77 0 obj<</Subtype/Link/Rect[108.0 380.4 219.2 393.4]/Border[0 0 0]/Dest[572 0 R/XYZ 0 178 0]>>endobj
78 0 obj<</Subtype/Link/Rect[72.0 354.0 253.5 367.0]/Border[0 0 0]/Dest[576 0 R/XYZ 0 734 0]>>endobj
79 0 obj<</Subtype/Link/Rect[72.0 327.6 212.9 340.6]/Border[0 0 0]/Dest[580 0 R/XYZ 0 734 0]>>endobj
80 0 obj<</Subtype/Link/Rect[108.0 314.4 181.6 327.4]/Border[0 0 0]/Dest[580 0 R/XYZ 0 696 0]>>endobj
81 0 obj<</Subtype/Link/Rect[126.0 301.2 188.3 314.2]/Border[0 0 0]/Dest[582 0 R/XYZ 0 626 0]>>endobj
82 0 obj<</Subtype/Link/Rect[126.0 288.0 185.3 301.0]/Border[0 0 0]/Dest[582 0 R/XYZ 0 516 0]>>endobj
83 0 obj<</Subtype/Link/Rect[108.0 274.8 218.9 287.8]/Border[0 0 0]/Dest[582 0 R/XYZ 0 394 0]>>endobj
84 0 obj<</Subtype/Link/Rect[126.0 261.6 179.2 274.6]/Border[0 0 0]/Dest[582 0 R/XYZ 0 360 0]>>endobj
85 0 obj<</Subtype/Link/Rect[126.0 248.4 214.6 261.4]/Border[0 0 0]/Dest[584 0 R/XYZ 0 718 0]>>endobj
86 0 obj<</Subtype/Link/Rect[126.0 235.2 198.1 248.2]/Border[0 0 0]/Dest[584 0 R/XYZ 0 235 0]>>endobj
87 0 obj<</Subtype/Link/Rect[108.0 222.0 283.7 235.0]/Border[0 0 0]/Dest[604 0 R/XYZ 0 428 0]>>endobj
88 0 obj<</Subtype/Link/Rect[126.0 208.8 216.8 221.8]/Border[0 0 0]/Dest[604 0 R/XYZ 0 366 0]>>endobj
89 0 obj<</Subtype/Link/Rect[126.0 195.6 185.3 208.6]/Border[0 0 0]/Dest[606 0 R/XYZ 0 567 0]>>endobj
90 0 obj<</Subtype/Link/Rect[126.0 182.4 171.2 195.4]/Border[0 0 0]/Dest[614 0 R/XYZ 0 531 0]>>endobj
91 0 obj<</Subtype/Link/Rect[126.0 169.2 249.5 182.2]/Border[0 0 0]/Dest[614 0 R/XYZ 0 407 0]>>endobj
92 0 obj<</Subtype/Link/Rect[126.0 156.0 286.4 169.0]/Border[0 0 0]/Dest[616 0 R/XYZ 0 548 0]>>endobj
93 0 obj<</Subtype/Link/Rect[126.0 142.8 231.7 155.8]/Border[0 0 0]/Dest[616 0 R/XYZ 0 140 0]>>endobj
94 0 obj<</Subtype/Link/Rect[126.0 129.6 256.5 142.6]/Border[0 0 0]/Dest[618 0 R/XYZ 0 492 0]>>endobj
95 0 obj<</Subtype/Link/Rect[126.0 116.4 303.5 129.4]/Border[0 0 0]/Dest[618 0 R/XYZ 0 145 0]>>endobj
96 0 obj<</Subtype/Link/Rect[126.0 103.2 231.1 116.2]/Border[0 0 0]/Dest[620 0 R/XYZ 0 586 0]>>endobj
97 0 obj<</Subtype/Link/Rect[126.0 90.0 207.6 103.0]/Border[0 0 0]/Dest[620 0 R/XYZ 0 301 0]>>endobj
98 0 obj<</Subtype/Link/Rect[126.0 76.8 243.3 89.8]/Border[0 0 0]/Dest[622 0 R/XYZ 0 734 0]>>endobj
99 0 obj<</Subtype/Link/Rect[126.0 63.6 250.0 76.6]/Border[0 0 0]/Dest[622 0 R/XYZ 0 249 0]>>endobj
100 0 obj[56 0 R
57 0 R
58 0 R
59 0 R
60 0 R
61 0 R
62 0 R
63 0 R
64 0 R
65 0 R
66 0 R
67 0 R
68 0 R
69 0 R
70 0 R
71 0 R
72 0 R
73 0 R
74 0 R
75 0 R
76 0 R
77 0 R
78 0 R
79 0 R
80 0 R
81 0 R
82 0 R
83 0 R
84 0 R
85 0 R
86 0 R
87 0 R
88 0 R
89 0 R
90 0 R
91 0 R
92 0 R
93 0 R
94 0 R
95 0 R
96 0 R
97 0 R
98 0 R
99 0 R]endobj
101 0 obj<</Subtype/Link/Rect[72.0 684.0 212.9 697.0]/Border[0 0 0]/Dest[580 0 R/XYZ 0 734 0]>>endobj
102 0 obj<</Subtype/Link/Rect[108.0 670.8 301.4 683.8]/Border[0 0 0]/Dest[624 0 R/XYZ 0 413 0]>>endobj
103 0 obj<</Subtype/Link/Rect[126.0 657.6 259.8 670.6]/Border[0 0 0]/Dest[626 0 R/XYZ 0 665 0]>>endobj
104 0 obj<</Subtype/Link/Rect[126.0 644.4 241.5 657.4]/Border[0 0 0]/Dest[626 0 R/XYZ 0 273 0]>>endobj
105 0 obj<</Subtype/Link/Rect[126.0 631.2 267.5 644.2]/Border[0 0 0]/Dest[628 0 R/XYZ 0 531 0]>>endobj
106 0 obj<</Subtype/Link/Rect[126.0 618.0 232.3 631.0]/Border[0 0 0]/Dest[628 0 R/XYZ 0 165 0]>>endobj
107 0 obj<</Subtype/Link/Rect[126.0 604.8 234.2 617.8]/Border[0 0 0]/Dest[630 0 R/XYZ 0 353 0]>>endobj
108 0 obj<</Subtype/Link/Rect[108.0 591.6 269.6 604.6]/Border[0 0 0]/Dest[632 0 R/XYZ 0 734 0]>>endobj
109 0 obj<</Subtype/Link/Rect[126.0 578.4 220.7 591.4]/Border[0 0 0]/Dest[632 0 R/XYZ 0 658 0]>>endobj
110 0 obj<</Subtype/Link/Rect[126.0 565.2 208.8 578.2]/Border[0 0 0]/Dest[634 0 R/XYZ 0 734 0]>>endobj
111 0 obj<</Subtype/Link/Rect[108.0 552.0 267.5 565.0]/Border[0 0 0]/Dest[636 0 R/XYZ 0 705 0]>>endobj
112 0 obj<</Subtype/Link/Rect[126.0 538.8 226.2 551.8]/Border[0 0 0]/Dest[636 0 R/XYZ 0 577 0]>>endobj
113 0 obj<</Subtype/Link/Rect[126.0 525.6 240.6 538.6]/Border[0 0 0]/Dest[638 0 R/XYZ 0 734 0]>>endobj
114 0 obj<</Subtype/Link/Rect[108.0 512.4 346.9 525.4]/Border[0 0 0]/Dest[638 0 R/XYZ 0 433 0]>>endobj
115 0 obj<</Subtype/Link/Rect[126.0 499.2 203.0 512.2]/Border[0 0 0]/Dest[638 0 R/XYZ 0 400 0]>>endobj
116 0 obj<</Subtype/Link/Rect[126.0 486.0 190.8 499.0]/Border[0 0 0]/Dest[640 0 R/XYZ 0 734 0]>>endobj
117 0 obj<</Subtype/Link/Rect[126.0 472.8 201.2 485.8]/Border[0 0 0]/Dest[640 0 R/XYZ 0 385 0]>>endobj
118 0 obj<</Subtype/Link/Rect[108.0 459.6 193.9 472.6]/Border[0 0 0]/Dest[640 0 R/XYZ 0 128 0]>>endobj
119 0 obj<</Subtype/Link/Rect[126.0 446.4 235.8 459.4]/Border[0 0 0]/Dest[642 0 R/XYZ 0 633 0]>>endobj
120 0 obj<</Subtype/Link/Rect[126.0 433.2 238.8 446.2]/Border[0 0 0]/Dest[644 0 R/XYZ 0 665 0]>>endobj
121 0 obj<</Subtype/Link/Rect[72.0 406.8 250.1 419.8]/Border[0 0 0]/Dest[648 0 R/XYZ 0 734 0]>>endobj
122 0 obj<</Subtype/Link/Rect[108.0 393.6 170.0 406.6]/Border[0 0 0]/Dest[648 0 R/XYZ 0 696 0]>>endobj
123 0 obj<</Subtype/Link/Rect[108.0 380.4 307.2 393.4]/Border[0 0 0]/Dest[648 0 R/XYZ 0 621 0]>>endobj
124 0 obj<</Subtype/Link/Rect[108.0 367.2 216.6 380.2]/Border[0 0 0]/Dest[648 0 R/XYZ 0 361 0]>>endobj
125 0 obj<</Subtype/Link/Rect[108.0 354.0 358.2 367.0]/Border[0 0 0]/Dest[652 0 R/XYZ 0 692 0]>>endobj
126 0 obj<</Subtype/Link/Rect[108.0 340.8 309.3 353.8]/Border[0 0 0]/Dest[652 0 R/XYZ 0 630 0]>>endobj
127 0 obj<</Subtype/Link/Rect[72.0 314.4 240.4 327.4]/Border[0 0 0]/Dest[658 0 R/XYZ 0 734 0]>>endobj
128 0 obj<</Subtype/Link/Rect[108.0 301.2 200.3 314.2]/Border[0 0 0]/Dest[658 0 R/XYZ 0 696 0]>>endobj
129 0 obj<</Subtype/Link/Rect[72.0 274.8 263.3 287.8]/Border[0 0 0]/Dest[660 0 R/XYZ 0 734 0]>>endobj
130 0 obj<</Subtype/Link/Rect[108.0 261.6 248.5 274.6]/Border[0 0 0]/Dest[660 0 R/XYZ 0 696 0]>>endobj
131 0 obj<</Subtype/Link/Rect[108.0 248.4 236.0 261.4]/Border[0 0 0]/Dest[662 0 R/XYZ 0 639 0]>>endobj
132 0 obj<</Subtype/Link/Rect[108.0 235.2 291.6 248.2]/Border[0 0 0]/Dest[662 0 R/XYZ 0 498 0]>>endobj
133 0 obj<</Subtype/Link/Rect[108.0 222.0 162.7 235.0]/Border[0 0 0]/Dest[662 0 R/XYZ 0 198 0]>>endobj
134 0 obj<</Subtype/Link/Rect[126.0 208.8 210.9 221.8]/Border[0 0 0]/Dest[662 0 R/XYZ 0 165 0]>>endobj
135 0 obj<</Subtype/Link/Rect[126.0 195.6 224.7 208.6]/Border[0 0 0]/Dest[664 0 R/XYZ 0 734 0]>>endobj
136 0 obj<</Subtype/Link/Rect[126.0 182.4 224.1 195.4]/Border[0 0 0]/Dest[664 0 R/XYZ 0 596 0]>>endobj
137 0 obj<</Subtype/Link/Rect[108.0 169.2 197.8 182.2]/Border[0 0 0]/Dest[664 0 R/XYZ 0 485 0]>>endobj
138 0 obj<</Subtype/Link/Rect[126.0 156.0 287.3 169.0]/Border[0 0 0]/Dest[664 0 R/XYZ 0 451 0]>>endobj
139 0 obj<</Subtype/Link/Rect[126.0 142.8 196.9 155.8]/Border[0 0 0]/Dest[664 0 R/XYZ 0 366 0]>>endobj
140 0 obj<</Subtype/Link/Rect[108.0 129.6 230.8 142.6]/Border[0 0 0]/Dest[664 0 R/XYZ 0 229 0]>>endobj
141 0 obj<</Subtype/Link/Rect[108.0 116.4 165.8 129.4]/Border[0 0 0]/Dest[666 0 R/XYZ 0 489 0]>>endobj
142 0 obj<</Subtype/Link/Rect[72.0 90.0 313.7 103.0]/Border[0 0 0]/Dest[668 0 R/XYZ 0 734 0]>>endobj
143 0 obj<</Subtype/Link/Rect[108.0 76.8 187.1 89.8]/Border[0 0 0]/Dest[668 0 R/XYZ 0 696 0]>>endobj
144 0 obj<</Subtype/Link/Rect[108.0 63.6 216.2 76.6]/Border[0 0 0]/Dest[668 0 R/XYZ 0 568 0]>>endobj
145 0 obj[101 0 R
102 0 R
103 0 R
104 0 R
105 0 R
106 0 R
107 0 R
108 0 R
109 0 R
110 0 R
111 0 R
112 0 R
113 0 R
114 0 R
115 0 R
116 0 R
117 0 R
118 0 R
119 0 R
120 0 R
121 0 R
122 0 R
123 0 R
124 0 R
125 0 R
126 0 R
127 0 R
128 0 R
129 0 R
130 0 R
131 0 R
132 0 R
133 0 R
134 0 R
135 0 R
136 0 R
137 0 R
138 0 R
139 0 R
140 0 R
141 0 R
142 0 R
143 0 R
144 0 R]endobj
146 0 obj<</Subtype/Link/Rect[72.0 684.0 313.7 697.0]/Border[0 0 0]/Dest[668 0 R/XYZ 0 734 0]>>endobj
147 0 obj<</Subtype/Link/Rect[108.0 670.8 220.7 683.8]/Border[0 0 0]/Dest[670 0 R/XYZ 0 718 0]>>endobj
148 0 obj[146 0 R
147 0 R]endobj
149 0 obj<</S/URI/URI(http://devel.samba.org/)>>endobj
150 0 obj<</Subtype/Link/Rect[139.5 617.8 243.7 630.8]/Border[0 0 0]/A 149 0 R>>endobj
151 0 obj<</S/URI/URI(mailto:jelmer@samba.org)>>endobj
152 0 obj<</Subtype/Link/Rect[347.9 617.8 434.4 630.8]/Border[0 0 0]/A 151 0 R>>endobj
153 0 obj<</S/URI/URI(http://www.fsf.org/licenses/gpl.txt)>>endobj
154 0 obj<</Subtype/Link/Rect[72.0 565.0 223.3 578.0]/Border[0 0 0]/A 153 0 R>>endobj
155 0 obj<</Subtype/Link/Rect[80.2 525.4 351.6 538.4]/Border[0 0 0]/Dest[532 0 R/XYZ 0 734 0]>>endobj
156 0 obj<</Subtype/Link/Rect[124.5 512.2 171.2 525.2]/Border[0 0 0]/Dest[532 0 R/XYZ 0 672 0]>>endobj
157 0 obj<</Subtype/Link/Rect[124.5 499.0 230.8 512.0]/Border[0 0 0]/Dest[532 0 R/XYZ 0 201 0]>>endobj
158 0 obj<</Subtype/Link/Rect[124.5 485.8 196.0 498.8]/Border[0 0 0]/Dest[534 0 R/XYZ 0 705 0]>>endobj
159 0 obj<</Subtype/Link/Rect[80.2 472.6 170.7 485.6]/Border[0 0 0]/Dest[536 0 R/XYZ 0 734 0]>>endobj
160 0 obj<</Subtype/Link/Rect[124.5 459.4 182.2 472.4]/Border[0 0 0]/Dest[536 0 R/XYZ 0 696 0]>>endobj
161 0 obj<</Subtype/Link/Rect[124.5 446.2 245.8 459.2]/Border[0 0 0]/Dest[536 0 R/XYZ 0 529 0]>>endobj
162 0 obj<</Subtype/Link/Rect[124.5 433.0 199.1 446.0]/Border[0 0 0]/Dest[536 0 R/XYZ 0 335 0]>>endobj
163 0 obj<</Subtype/Link/Rect[124.5 419.8 200.3 432.8]/Border[0 0 0]/Dest[538 0 R/XYZ 0 734 0]>>endobj
164 0 obj<</Subtype/Link/Rect[124.5 406.6 185.6 419.6]/Border[0 0 0]/Dest[538 0 R/XYZ 0 434 0]>>endobj
165 0 obj<</Subtype/Link/Rect[80.2 393.4 203.1 406.4]/Border[0 0 0]/Dest[540 0 R/XYZ 0 734 0]>>endobj
166 0 obj<</Subtype/Link/Rect[124.5 380.2 212.2 393.2]/Border[0 0 0]/Dest[540 0 R/XYZ 0 696 0]>>endobj
167 0 obj<</Subtype/Link/Rect[124.5 367.0 223.2 380.0]/Border[0 0 0]/Dest[542 0 R/XYZ 0 734 0]>>endobj
168 0 obj<</Subtype/Link/Rect[124.5 353.8 245.8 366.8]/Border[0 0 0]/Dest[544 0 R/XYZ 0 734 0]>>endobj
169 0 obj<</Subtype/Link/Rect[124.5 340.6 242.1 353.6]/Border[0 0 0]/Dest[544 0 R/XYZ 0 514 0]>>endobj
170 0 obj<</Subtype/Link/Rect[124.5 327.4 193.6 340.4]/Border[0 0 0]/Dest[546 0 R/XYZ 0 734 0]>>endobj
171 0 obj<</Subtype/Link/Rect[168.8 314.2 211.2 327.2]/Border[0 0 0]/Dest[546 0 R/XYZ 0 700 0]>>endobj
172 0 obj<</Subtype/Link/Rect[168.8 301.0 210.6 314.0]/Border[0 0 0]/Dest[546 0 R/XYZ 0 602 0]>>endobj
173 0 obj<</Subtype/Link/Rect[168.8 287.8 261.9 300.8]/Border[0 0 0]/Dest[546 0 R/XYZ 0 491 0]>>endobj
174 0 obj<</Subtype/Link/Rect[80.2 274.6 170.7 287.6]/Border[0 0 0]/Dest[548 0 R/XYZ 0 734 0]>>endobj
175 0 obj<</Subtype/Link/Rect[80.2 261.4 155.4 274.4]/Border[0 0 0]/Dest[552 0 R/XYZ 0 734 0]>>endobj
176 0 obj<</Subtype/Link/Rect[124.5 248.2 216.8 261.2]/Border[0 0 0]/Dest[552 0 R/XYZ 0 696 0]>>endobj
177 0 obj<</Subtype/Link/Rect[124.5 235.0 207.3 248.0]/Border[0 0 0]/Dest[552 0 R/XYZ 0 568 0]>>endobj
178 0 obj<</Subtype/Link/Rect[124.5 221.8 225.9 234.8]/Border[0 0 0]/Dest[554 0 R/XYZ 0 705 0]>>endobj
179 0 obj<</Subtype/Link/Rect[168.8 208.6 237.8 221.6]/Border[0 0 0]/Dest[554 0 R/XYZ 0 630 0]>>endobj
180 0 obj<</Subtype/Link/Rect[168.8 195.4 237.2 208.4]/Border[0 0 0]/Dest[554 0 R/XYZ 0 571 0]>>endobj
181 0 obj<</Subtype/Link/Rect[168.8 182.2 259.5 195.2]/Border[0 0 0]/Dest[554 0 R/XYZ 0 513 0]>>endobj
182 0 obj<</Subtype/Link/Rect[168.8 169.0 236.0 182.0]/Border[0 0 0]/Dest[554 0 R/XYZ 0 455 0]>>endobj
183 0 obj<</Subtype/Link/Rect[168.8 155.8 234.1 168.8]/Border[0 0 0]/Dest[554 0 R/XYZ 0 383 0]>>endobj
184 0 obj<</Subtype/Link/Rect[168.8 142.6 241.5 155.6]/Border[0 0 0]/Dest[554 0 R/XYZ 0 325 0]>>endobj
185 0 obj<</Subtype/Link/Rect[168.8 129.4 239.6 142.4]/Border[0 0 0]/Dest[554 0 R/XYZ 0 266 0]>>endobj
186 0 obj<</Subtype/Link/Rect[168.8 116.2 257.7 129.2]/Border[0 0 0]/Dest[554 0 R/XYZ 0 208 0]>>endobj
187 0 obj<</Subtype/Link/Rect[168.8 103.0 255.8 116.0]/Border[0 0 0]/Dest[554 0 R/XYZ 0 149 0]>>endobj
188 0 obj<</Subtype/Link/Rect[174.2 89.8 268.7 102.8]/Border[0 0 0]/Dest[556 0 R/XYZ 0 734 0]>>endobj
189 0 obj<</Subtype/Link/Rect[174.2 76.6 266.8 89.6]/Border[0 0 0]/Dest[556 0 R/XYZ 0 675 0]>>endobj
190 0 obj<</Subtype/Link/Rect[174.2 63.4 248.2 76.4]/Border[0 0 0]/Dest[556 0 R/XYZ 0 617 0]>>endobj
191 0 obj[150 0 R
152 0 R
154 0 R
155 0 R
156 0 R
157 0 R
158 0 R
159 0 R
160 0 R
161 0 R
162 0 R
163 0 R
164 0 R
165 0 R
166 0 R
167 0 R
168 0 R
169 0 R
170 0 R
171 0 R
172 0 R
173 0 R
174 0 R
175 0 R
176 0 R
177 0 R
178 0 R
179 0 R
180 0 R
181 0 R
182 0 R
183 0 R
184 0 R
185 0 R
186 0 R
187 0 R
188 0 R
189 0 R
190 0 R]endobj
192 0 obj<</Subtype/Link/Rect[174.2 721.0 246.4 734.0]/Border[0 0 0]/Dest[556 0 R/XYZ 0 558 0]>>endobj
193 0 obj<</Subtype/Link/Rect[174.2 707.8 269.9 720.8]/Border[0 0 0]/Dest[556 0 R/XYZ 0 500 0]>>endobj
194 0 obj<</Subtype/Link/Rect[174.2 694.6 268.0 707.6]/Border[0 0 0]/Dest[556 0 R/XYZ 0 428 0]>>endobj
195 0 obj<</Subtype/Link/Rect[124.5 681.4 243.0 694.4]/Border[0 0 0]/Dest[556 0 R/XYZ 0 370 0]>>endobj
196 0 obj<</Subtype/Link/Rect[168.8 668.2 222.8 681.2]/Border[0 0 0]/Dest[556 0 R/XYZ 0 220 0]>>endobj
197 0 obj<</Subtype/Link/Rect[168.8 655.0 228.0 668.0]/Border[0 0 0]/Dest[558 0 R/XYZ 0 441 0]>>endobj
198 0 obj<</Subtype/Link/Rect[124.5 641.8 220.7 654.8]/Border[0 0 0]/Dest[560 0 R/XYZ 0 734 0]>>endobj
199 0 obj<</Subtype/Link/Rect[80.2 628.6 158.5 641.6]/Border[0 0 0]/Dest[562 0 R/XYZ 0 734 0]>>endobj
200 0 obj<</Subtype/Link/Rect[124.5 615.4 199.7 628.4]/Border[0 0 0]/Dest[562 0 R/XYZ 0 696 0]>>endobj
201 0 obj<</Subtype/Link/Rect[168.8 602.2 277.8 615.2]/Border[0 0 0]/Dest[562 0 R/XYZ 0 423 0]>>endobj
202 0 obj<</Subtype/Link/Rect[168.8 589.0 307.5 602.0]/Border[0 0 0]/Dest[562 0 R/XYZ 0 259 0]>>endobj
203 0 obj<</Subtype/Link/Rect[168.8 575.8 284.6 588.8]/Border[0 0 0]/Dest[564 0 R/XYZ 0 652 0]>>endobj
204 0 obj<</Subtype/Link/Rect[124.5 562.6 156.6 575.6]/Border[0 0 0]/Dest[564 0 R/XYZ 0 240 0]>>endobj
205 0 obj<</Subtype/Link/Rect[168.8 549.4 241.2 562.4]/Border[0 0 0]/Dest[566 0 R/XYZ 0 665 0]>>endobj
206 0 obj<</Subtype/Link/Rect[80.2 536.2 196.0 549.2]/Border[0 0 0]/Dest[568 0 R/XYZ 0 734 0]>>endobj
207 0 obj<</Subtype/Link/Rect[124.5 523.0 182.2 536.0]/Border[0 0 0]/Dest[568 0 R/XYZ 0 696 0]>>endobj
208 0 obj<</Subtype/Link/Rect[124.5 509.8 176.7 522.8]/Border[0 0 0]/Dest[568 0 R/XYZ 0 595 0]>>endobj
209 0 obj<</Subtype/Link/Rect[124.5 496.6 196.0 509.6]/Border[0 0 0]/Dest[568 0 R/XYZ 0 216 0]>>endobj
210 0 obj<</Subtype/Link/Rect[124.5 483.4 174.9 496.4]/Border[0 0 0]/Dest[570 0 R/XYZ 0 692 0]>>endobj
211 0 obj<</Subtype/Link/Rect[124.5 470.2 162.7 483.2]/Border[0 0 0]/Dest[570 0 R/XYZ 0 458 0]>>endobj
212 0 obj<</Subtype/Link/Rect[124.5 457.0 182.5 470.0]/Border[0 0 0]/Dest[572 0 R/XYZ 0 734 0]>>endobj
213 0 obj<</Subtype/Link/Rect[124.5 443.8 196.0 456.8]/Border[0 0 0]/Dest[572 0 R/XYZ 0 566 0]>>endobj
214 0 obj<</Subtype/Link/Rect[124.5 430.6 187.4 443.6]/Border[0 0 0]/Dest[572 0 R/XYZ 0 438 0]>>endobj
215 0 obj<</Subtype/Link/Rect[124.5 417.4 218.6 430.4]/Border[0 0 0]/Dest[572 0 R/XYZ 0 178 0]>>endobj
216 0 obj<</Subtype/Link/Rect[80.2 404.2 204.9 417.2]/Border[0 0 0]/Dest[576 0 R/XYZ 0 734 0]>>endobj
217 0 obj<</Subtype/Link/Rect[80.2 391.0 164.8 404.0]/Border[0 0 0]/Dest[580 0 R/XYZ 0 734 0]>>endobj
218 0 obj<</Subtype/Link/Rect[124.5 377.8 182.2 390.8]/Border[0 0 0]/Dest[580 0 R/XYZ 0 696 0]>>endobj
219 0 obj<</Subtype/Link/Rect[168.8 364.6 206.3 377.6]/Border[0 0 0]/Dest[582 0 R/XYZ 0 626 0]>>endobj
220 0 obj<</Subtype/Link/Rect[168.8 351.4 203.9 364.4]/Border[0 0 0]/Dest[582 0 R/XYZ 0 516 0]>>endobj
221 0 obj<</Subtype/Link/Rect[124.5 338.2 219.5 351.2]/Border[0 0 0]/Dest[582 0 R/XYZ 0 394 0]>>endobj
222 0 obj<</Subtype/Link/Rect[168.8 325.0 196.6 338.0]/Border[0 0 0]/Dest[582 0 R/XYZ 0 360 0]>>endobj
223 0 obj<</Subtype/Link/Rect[168.8 311.8 233.2 324.8]/Border[0 0 0]/Dest[584 0 R/XYZ 0 718 0]>>endobj
224 0 obj<</Subtype/Link/Rect[168.8 298.6 216.7 311.6]/Border[0 0 0]/Dest[584 0 R/XYZ 0 235 0]>>endobj
225 0 obj<</Subtype/Link/Rect[124.5 285.4 283.7 298.4]/Border[0 0 0]/Dest[604 0 R/XYZ 0 428 0]>>endobj
226 0 obj<</Subtype/Link/Rect[168.8 272.2 234.1 285.2]/Border[0 0 0]/Dest[604 0 R/XYZ 0 366 0]>>endobj
227 0 obj<</Subtype/Link/Rect[168.8 259.0 204.5 272.0]/Border[0 0 0]/Dest[606 0 R/XYZ 0 567 0]>>endobj
228 0 obj<</Subtype/Link/Rect[168.8 245.8 189.2 258.8]/Border[0 0 0]/Dest[614 0 R/XYZ 0 531 0]>>endobj
229 0 obj<</Subtype/Link/Rect[168.8 232.6 264.4 245.6]/Border[0 0 0]/Dest[614 0 R/XYZ 0 407 0]>>endobj
230 0 obj<</Subtype/Link/Rect[168.8 219.4 302.0 232.4]/Border[0 0 0]/Dest[616 0 R/XYZ 0 548 0]>>endobj
231 0 obj<</Subtype/Link/Rect[168.8 206.2 247.3 219.2]/Border[0 0 0]/Dest[616 0 R/XYZ 0 140 0]>>endobj
232 0 obj<</Subtype/Link/Rect[168.8 193.0 271.4 206.0]/Border[0 0 0]/Dest[618 0 R/XYZ 0 492 0]>>endobj
233 0 obj<</Subtype/Link/Rect[168.8 179.8 319.7 192.8]/Border[0 0 0]/Dest[618 0 R/XYZ 0 145 0]>>endobj
234 0 obj<</Subtype/Link/Rect[168.8 166.6 246.7 179.6]/Border[0 0 0]/Dest[620 0 R/XYZ 0 586 0]>>endobj
235 0 obj<</Subtype/Link/Rect[174.2 153.4 223.1 166.4]/Border[0 0 0]/Dest[620 0 R/XYZ 0 301 0]>>endobj
236 0 obj<</Subtype/Link/Rect[174.2 140.2 256.4 153.2]/Border[0 0 0]/Dest[622 0 R/XYZ 0 734 0]>>endobj
237 0 obj<</Subtype/Link/Rect[174.2 127.0 263.8 140.0]/Border[0 0 0]/Dest[622 0 R/XYZ 0 249 0]>>endobj
238 0 obj<</Subtype/Link/Rect[124.5 113.8 300.8 126.8]/Border[0 0 0]/Dest[624 0 R/XYZ 0 413 0]>>endobj
239 0 obj<</Subtype/Link/Rect[168.8 100.6 275.4 113.6]/Border[0 0 0]/Dest[626 0 R/XYZ 0 665 0]>>endobj
240 0 obj<</Subtype/Link/Rect[168.8 87.4 256.4 100.4]/Border[0 0 0]/Dest[626 0 R/XYZ 0 273 0]>>endobj
241 0 obj<</Subtype/Link/Rect[168.8 74.2 283.6 87.2]/Border[0 0 0]/Dest[628 0 R/XYZ 0 531 0]>>endobj
242 0 obj<</Subtype/Link/Rect[168.8 61.0 244.8 74.0]/Border[0 0 0]/Dest[628 0 R/XYZ 0 165 0]>>endobj
243 0 obj[192 0 R
193 0 R
194 0 R
195 0 R
196 0 R
197 0 R
198 0 R
199 0 R
200 0 R
201 0 R
202 0 R
203 0 R
204 0 R
205 0 R
206 0 R
207 0 R
208 0 R
209 0 R
210 0 R
211 0 R
212 0 R
213 0 R
214 0 R
215 0 R
216 0 R
217 0 R
218 0 R
219 0 R
220 0 R
221 0 R
222 0 R
223 0 R
224 0 R
225 0 R
226 0 R
227 0 R
228 0 R
229 0 R
230 0 R
231 0 R
232 0 R
233 0 R
234 0 R
235 0 R
236 0 R
237 0 R
238 0 R
239 0 R
240 0 R
241 0 R
242 0 R]endobj
244 0 obj<</Subtype/Link/Rect[168.8 721.0 245.5 734.0]/Border[0 0 0]/Dest[630 0 R/XYZ 0 353 0]>>endobj
245 0 obj<</Subtype/Link/Rect[124.5 707.8 261.7 720.8]/Border[0 0 0]/Dest[632 0 R/XYZ 0 734 0]>>endobj
246 0 obj<</Subtype/Link/Rect[168.8 694.6 239.3 707.6]/Border[0 0 0]/Dest[632 0 R/XYZ 0 658 0]>>endobj
247 0 obj<</Subtype/Link/Rect[168.8 681.4 223.8 694.4]/Border[0 0 0]/Dest[634 0 R/XYZ 0 734 0]>>endobj
248 0 obj<</Subtype/Link/Rect[124.5 668.2 264.4 681.2]/Border[0 0 0]/Dest[636 0 R/XYZ 0 705 0]>>endobj
249 0 obj<</Subtype/Link/Rect[168.8 655.0 243.6 668.0]/Border[0 0 0]/Dest[636 0 R/XYZ 0 577 0]>>endobj
250 0 obj<</Subtype/Link/Rect[168.8 641.8 257.3 654.8]/Border[0 0 0]/Dest[638 0 R/XYZ 0 734 0]>>endobj
251 0 obj<</Subtype/Link/Rect[124.5 628.6 345.7 641.6]/Border[0 0 0]/Dest[638 0 R/XYZ 0 433 0]>>endobj
252 0 obj<</Subtype/Link/Rect[168.8 615.4 220.4 628.4]/Border[0 0 0]/Dest[638 0 R/XYZ 0 400 0]>>endobj
253 0 obj<</Subtype/Link/Rect[168.8 602.2 210.0 615.2]/Border[0 0 0]/Dest[640 0 R/XYZ 0 734 0]>>endobj
254 0 obj<</Subtype/Link/Rect[168.8 589.0 217.9 602.0]/Border[0 0 0]/Dest[640 0 R/XYZ 0 385 0]>>endobj
255 0 obj<</Subtype/Link/Rect[124.5 575.8 193.2 588.8]/Border[0 0 0]/Dest[640 0 R/XYZ 0 128 0]>>endobj
256 0 obj<</Subtype/Link/Rect[168.8 562.6 251.9 575.6]/Border[0 0 0]/Dest[642 0 R/XYZ 0 633 0]>>endobj
257 0 obj<</Subtype/Link/Rect[168.8 549.4 254.4 562.4]/Border[0 0 0]/Dest[644 0 R/XYZ 0 665 0]>>endobj
258 0 obj<</Subtype/Link/Rect[85.8 536.2 200.3 549.2]/Border[0 0 0]/Dest[648 0 R/XYZ 0 734 0]>>endobj
259 0 obj<</Subtype/Link/Rect[130.0 523.0 170.0 536.0]/Border[0 0 0]/Dest[648 0 R/XYZ 0 696 0]>>endobj
260 0 obj<</Subtype/Link/Rect[130.0 509.8 308.4 522.8]/Border[0 0 0]/Dest[648 0 R/XYZ 0 621 0]>>endobj
261 0 obj<</Subtype/Link/Rect[130.0 496.6 217.0 509.6]/Border[0 0 0]/Dest[648 0 R/XYZ 0 361 0]>>endobj
262 0 obj<</Subtype/Link/Rect[130.0 483.4 360.7 496.4]/Border[0 0 0]/Dest[652 0 R/XYZ 0 692 0]>>endobj
263 0 obj<</Subtype/Link/Rect[130.0 470.2 306.3 483.2]/Border[0 0 0]/Dest[652 0 R/XYZ 0 630 0]>>endobj
264 0 obj<</Subtype/Link/Rect[85.8 457.0 189.3 470.0]/Border[0 0 0]/Dest[658 0 R/XYZ 0 734 0]>>endobj
265 0 obj<</Subtype/Link/Rect[130.0 443.8 199.0 456.8]/Border[0 0 0]/Dest[658 0 R/XYZ 0 696 0]>>endobj
266 0 obj<</Subtype/Link/Rect[85.8 430.6 211.0 443.6]/Border[0 0 0]/Dest[660 0 R/XYZ 0 734 0]>>endobj
267 0 obj<</Subtype/Link/Rect[130.0 417.4 245.6 430.4]/Border[0 0 0]/Dest[660 0 R/XYZ 0 696 0]>>endobj
268 0 obj<</Subtype/Link/Rect[130.0 404.2 234.2 417.2]/Border[0 0 0]/Dest[662 0 R/XYZ 0 639 0]>>endobj
269 0 obj<</Subtype/Link/Rect[130.0 391.0 289.8 404.0]/Border[0 0 0]/Dest[662 0 R/XYZ 0 498 0]>>endobj
270 0 obj<</Subtype/Link/Rect[130.0 377.8 162.7 390.8]/Border[0 0 0]/Dest[662 0 R/XYZ 0 198 0]>>endobj
271 0 obj<</Subtype/Link/Rect[174.2 364.6 228.3 377.6]/Border[0 0 0]/Dest[662 0 R/XYZ 0 165 0]>>endobj
272 0 obj<</Subtype/Link/Rect[174.2 351.4 240.8 364.4]/Border[0 0 0]/Dest[664 0 R/XYZ 0 734 0]>>endobj
273 0 obj<</Subtype/Link/Rect[174.2 338.2 239.0 351.2]/Border[0 0 0]/Dest[664 0 R/XYZ 0 596 0]>>endobj
274 0 obj<</Subtype/Link/Rect[130.0 325.0 194.8 338.0]/Border[0 0 0]/Dest[664 0 R/XYZ 0 485 0]>>endobj
275 0 obj<</Subtype/Link/Rect[174.2 311.8 305.9 324.8]/Border[0 0 0]/Dest[664 0 R/XYZ 0 451 0]>>endobj
276 0 obj<</Subtype/Link/Rect[174.2 298.6 215.5 311.6]/Border[0 0 0]/Dest[664 0 R/XYZ 0 366 0]>>endobj
277 0 obj<</Subtype/Link/Rect[130.0 285.4 229.6 298.4]/Border[0 0 0]/Dest[664 0 R/XYZ 0 229 0]>>endobj
278 0 obj<</Subtype/Link/Rect[130.0 272.2 165.1 285.2]/Border[0 0 0]/Dest[666 0 R/XYZ 0 489 0]>>endobj
279 0 obj<</Subtype/Link/Rect[85.8 259.0 259.0 272.0]/Border[0 0 0]/Dest[668 0 R/XYZ 0 734 0]>>endobj
280 0 obj<</Subtype/Link/Rect[130.0 245.8 187.8 258.8]/Border[0 0 0]/Dest[668 0 R/XYZ 0 696 0]>>endobj
281 0 obj<</Subtype/Link/Rect[130.0 232.6 215.6 245.6]/Border[0 0 0]/Dest[668 0 R/XYZ 0 568 0]>>endobj
282 0 obj<</Subtype/Link/Rect[130.0 219.4 218.9 221.4]/Border[0 0 0]/Dest[670 0 R/XYZ 0 718 0]>>endobj
283 0 obj[244 0 R
245 0 R
246 0 R
247 0 R
248 0 R
249 0 R
250 0 R
251 0 R
252 0 R
253 0 R
254 0 R
255 0 R
256 0 R
257 0 R
258 0 R
259 0 R
260 0 R
261 0 R
262 0 R
263 0 R
264 0 R
265 0 R
266 0 R
267 0 R
268 0 R
269 0 R
270 0 R
271 0 R
272 0 R
273 0 R
274 0 R
275 0 R
276 0 R
277 0 R
278 0 R
279 0 R
280 0 R
281 0 R
282 0 R]endobj
284 0 obj<</S/URI/URI(http://lxr.linux.no/source/Documentation/CodingStyle)>>endobj
285 0 obj<</Subtype/Link/Rect[72.0 499.0 310.3 512.0]/Border[0 0 0]/A 284 0 R>>endobj
286 0 obj<</S/URI/URI(http://www.fsf.org/prep/standards_toc.html)>>endobj
287 0 obj<</Subtype/Link/Rect[72.0 472.6 263.0 485.6]/Border[0 0 0]/A 286 0 R>>endobj
288 0 obj[285 0 R
287 0 R]endobj
289 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/cifsntdomain.txt)>>endobj
290 0 obj<</Subtype/Link/Rect[226.0 637.0 433.6 650.0]/Border[0 0 0]/A 289 0 R>>endobj
291 0 obj<</S/URI/URI(http://ntbugtraq.rc.on.ca/SCRIPTS/WA.EXE?A2=ind9708;L=ntbugtraq;O=A;P=2935)>>endobj
292 0 obj<</Subtype/Link/Rect[72.0 386.2 451.3 399.2]/Border[0 0 0]/A 291 0 R>>endobj
293 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/crypt.html)>>endobj
294 0 obj<</Subtype/Link/Rect[72.0 359.8 250.6 372.8]/Border[0 0 0]/A 293 0 R>>endobj
295 0 obj<</S/URI/URI(mailto:linus@incolumitas.se)>>endobj
296 0 obj<</Subtype/Link/Rect[244.7 333.4 317.4 346.4]/Border[0 0 0]/A 295 0 R>>endobj
297 0 obj<</S/URI/URI(http://samba.org/cgi-bin/mfs/01/digest/1997/97aug/0391.html)>>endobj
298 0 obj<</Subtype/Link/Rect[72.0 307.0 346.5 320.0]/Border[0 0 0]/A 297 0 R>>endobj
299 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/crypt.txt)>>endobj
300 0 obj<</Subtype/Link/Rect[72.0 280.6 242.0 293.6]/Border[0 0 0]/A 299 0 R>>endobj
301 0 obj[290 0 R
292 0 R
294 0 R
296 0 R
298 0 R
300 0 R]endobj
302 0 obj<</Dests 303 0 R>>endobj
303 0 obj<</Kids[304 0 R]>>endobj
304 0 obj<</Limits[(aen1008)(wins)]/Names[(aen1008)305 0 R(aen1019)306 0 R(aen103)307 0 R(aen1040)308 0 R(aen1053)309 0 R(aen1100)310 0 R(aen1127)311 0 R(aen1138)312 0 R(aen1177)313 0 R(aen1208)314 0 R(aen128)315 0 R(aen1365)316 0 R(aen1388)317 0 R(aen1399)318 0 R(aen1445)319 0 R(aen151)320 0 R(aen1571)321 0 R(aen1574)322 0 R(aen1588)323 0 R(aen159)324 0 R(aen1649)325 0 R(aen1688)326 0 R(aen1693)327 0 R(aen1704)328 0 R(aen1744)329 0 R(aen1755)330 0 R(aen179)331 0 R(aen1799)332 0 R(aen181)333 0 R(aen1819)334 0 R(aen184)335 0 R(aen1842)336 0 R(aen1854)337 0 R(aen188)338 0 R(aen1898)339 0 R(aen1939)340 0 R(aen1943)341 0 R(aen1962)342 0 R(aen1973)343 0 R(aen1977)344 0 R(aen1988)345 0 R(aen2001)346 0 R(aen2003)347 0 R(aen2006)348 0 R(aen2025)349 0 R(aen2027)350 0 R(aen2030)351 0 R(aen2054)352 0 R(aen2056)353 0 R(aen2063)354 0 R(aen2071)355 0 R(aen2075)356 0 R(aen2102)357 0 R(aen2130)358 0 R(aen2134)359 0 R(aen2165)360 0 R(aen2193)361 0 R(aen2232)362 0 R(aen2240)363 0 R(aen2259)364 0 R(aen2267)365 0 R(aen2275)366 0 R(aen2294)367 0 R(aen2306)368 0 R(aen2316)369 0 R(aen2327)370 0 R(aen2335)371 0 R(aen2339)372 0 R(aen2346)373 0 R(aen2359)374 0 R(aen2363)375 0 R(aen2370)376 0 R(aen2382)377 0 R(aen2386)378 0 R(aen2390)379 0 R(aen24)380 0 R(aen2425)381 0 R(aen2460)382 0 R(aen2468)383 0 R(aen2519)384 0 R(aen2550)385 0 R(aen2562)386 0 R(aen2568)387 0 R(aen2603)388 0 R(aen2623)389 0 R(aen2627)390 0 R(aen2638)391 0 R(aen2654)392 0 R(aen2656)393 0 R(aen2699)394 0 R(aen2709)395 0 R(aen2716)396 0 R(aen2724)397 0 R(aen2726)398 0 R(aen2761)399 0 R(aen2812)400 0 R(aen2815)401 0 R(aen2829)402 0 R(aen284)403 0 R(aen2847)404 0 R(aen288)405 0 R(aen2896)406 0 R(aen2899)407 0 R(aen2925)408 0 R(aen2959)409 0 R(aen2962)410 0 R(aen3033)411 0 R(aen3054)412 0 R(aen3071)413 0 R(aen3075)414 0 R(aen3086)415 0 R(aen3088)416 0 R(aen3091)417 0 R(aen3095)418 0 R(aen3098)419 0 R(aen3100)420 0 R(aen3103)421 0 R(aen3107)422 0 R(aen3121)423 0 R(aen3147)424 0 R(aen3151)425 0 R(aen3162)426 0 R(aen317)427 0 R(aen320)428 0 R(aen323)429 0 R(aen326)430 0 R(aen329)431 0 R(aen332)432 0 R(aen335)433 0 R(aen338)434 0 R(aen341)435 0 R(aen344)436 0 R(aen347)437 0 R(aen35)438 0 R(aen350)439 0 R(aen353)440 0 R(aen356)441 0 R(aen359)442 0 R(aen362)443 0 R(aen365)444 0 R(aen371)445 0 R(aen39)446 0 R(aen4)447 0 R(aen406)448 0 R(aen420)449 0 R(aen451)450 0 R(aen472)451 0 R(aen484)452 0 R(aen495)453 0 R(aen515)454 0 R(aen530)455 0 R(aen54)456 0 R(aen540)457 0 R(aen544)458 0 R(aen552)459 0 R(aen557)460 0 R(aen563)461 0 R(aen571)462 0 R(aen575)463 0 R(aen579)464 0 R(aen584)465 0 R(aen65)466 0 R(aen652)467 0 R(aen688)468 0 R(aen695)469 0 R(aen70)470 0 R(aen702)471 0 R(aen704)472 0 R(aen717)473 0 R(aen719)474 0 R(aen739)475 0 R(aen775)476 0 R(aen777)477 0 R(aen780)478 0 R(aen783)479 0 R(aen786)480 0 R(aen789)481 0 R(aen8)482 0 R(aen814)483 0 R(aen817)484 0 R(aen832)485 0 R(aen843)486 0 R(aen850)487 0 R(aen86)488 0 R(aen861)489 0 R(aen884)490 0 R(aen911)491 0 R(aen918)492 0 R(aen92)493 0 R(aen941)494 0 R(aen960)495 0 R(aen987)496 0 R(architecture)497 0 R(codingsuggestions)498 0 R(debug)499 0 R(internals)500 0 R(netbios)501 0 R(ntdomain)502 0 R(parsing)503 0 R(printing)504 0 R(pwencrypt)505 0 R(sam)506 0 R(samba-developers-guide)507 0 R(samba-developers-guide.html)508 0 R(smbpasswdfileformat)509 0 R(tracing)510 0 R(unix-smb)511 0 R(wins)512 0 R]>>endobj
305 0 obj<</D[592 0 R/XYZ 0 734 0]>>endobj
306 0 obj<</D[592 0 R/XYZ 0 639 0]>>endobj
307 0 obj<</D[540 0 R/XYZ 0 696 0]>>endobj
308 0 obj<</D[592 0 R/XYZ 0 439 0]>>endobj
309 0 obj<</D[592 0 R/XYZ 0 292 0]>>endobj
310 0 obj<</D[594 0 R/XYZ 0 626 0]>>endobj
311 0 obj<</D[594 0 R/XYZ 0 345 0]>>endobj
312 0 obj<</D[594 0 R/XYZ 0 251 0]>>endobj
313 0 obj<</D[596 0 R/XYZ 0 639 0]>>endobj
314 0 obj<</D[596 0 R/XYZ 0 413 0]>>endobj
315 0 obj<</D[542 0 R/XYZ 0 734 0]>>endobj
316 0 obj<</D[600 0 R/XYZ 0 679 0]>>endobj
317 0 obj<</D[600 0 R/XYZ 0 438 0]>>endobj
318 0 obj<</D[600 0 R/XYZ 0 344 0]>>endobj
319 0 obj<</D[602 0 R/XYZ 0 639 0]>>endobj
320 0 obj<</D[544 0 R/XYZ 0 734 0]>>endobj
321 0 obj<</D[604 0 R/XYZ 0 428 0]>>endobj
322 0 obj<</D[604 0 R/XYZ 0 366 0]>>endobj
323 0 obj<</D[606 0 R/XYZ 0 567 0]>>endobj
324 0 obj<</D[544 0 R/XYZ 0 514 0]>>endobj
325 0 obj<</D[610 0 R/XYZ 0 734 0]>>endobj
326 0 obj<</D[610 0 R/XYZ 0 467 0]>>endobj
327 0 obj<</D[610 0 R/XYZ 0 378 0]>>endobj
328 0 obj<</D[610 0 R/XYZ 0 283 0]>>endobj
329 0 obj<</D[612 0 R/XYZ 0 639 0]>>endobj
330 0 obj<</D[612 0 R/XYZ 0 545 0]>>endobj
331 0 obj<</D[546 0 R/XYZ 0 734 0]>>endobj
332 0 obj<</D[612 0 R/XYZ 0 213 0]>>endobj
333 0 obj<</D[546 0 R/XYZ 0 700 0]>>endobj
334 0 obj<</D[614 0 R/XYZ 0 705 0]>>endobj
335 0 obj<</D[546 0 R/XYZ 0 602 0]>>endobj
336 0 obj<</D[614 0 R/XYZ 0 531 0]>>endobj
337 0 obj<</D[614 0 R/XYZ 0 407 0]>>endobj
338 0 obj<</D[546 0 R/XYZ 0 491 0]>>endobj
339 0 obj<</D[616 0 R/XYZ 0 548 0]>>endobj
340 0 obj<</D[616 0 R/XYZ 0 140 0]>>endobj
341 0 obj<</D[618 0 R/XYZ 0 734 0]>>endobj
342 0 obj<</D[618 0 R/XYZ 0 586 0]>>endobj
343 0 obj<</D[618 0 R/XYZ 0 492 0]>>endobj
344 0 obj<</D[618 0 R/XYZ 0 433 0]>>endobj
345 0 obj<</D[618 0 R/XYZ 0 339 0]>>endobj
346 0 obj<</D[618 0 R/XYZ 0 145 0]>>endobj
347 0 obj<</D[618 0 R/XYZ 0 115 0]>>endobj
348 0 obj<</D[620 0 R/XYZ 0 734 0]>>endobj
349 0 obj<</D[620 0 R/XYZ 0 586 0]>>endobj
350 0 obj<</D[620 0 R/XYZ 0 556 0]>>endobj
351 0 obj<</D[620 0 R/XYZ 0 501 0]>>endobj
352 0 obj<</D[620 0 R/XYZ 0 301 0]>>endobj
353 0 obj<</D[620 0 R/XYZ 0 271 0]>>endobj
354 0 obj<</D[620 0 R/XYZ 0 203 0]>>endobj
355 0 obj<</D[622 0 R/XYZ 0 734 0]>>endobj
356 0 obj<</D[622 0 R/XYZ 0 675 0]>>endobj
357 0 obj<</D[622 0 R/XYZ 0 475 0]>>endobj
358 0 obj<</D[622 0 R/XYZ 0 249 0]>>endobj
359 0 obj<</D[622 0 R/XYZ 0 190 0]>>endobj
360 0 obj<</D[624 0 R/XYZ 0 639 0]>>endobj
361 0 obj<</D[624 0 R/XYZ 0 413 0]>>endobj
362 0 obj<</D[626 0 R/XYZ 0 665 0]>>endobj
363 0 obj<</D[626 0 R/XYZ 0 515 0]>>endobj
364 0 obj<</D[626 0 R/XYZ 0 367 0]>>endobj
365 0 obj<</D[626 0 R/XYZ 0 273 0]>>endobj
366 0 obj<</D[626 0 R/XYZ 0 135 0]>>endobj
367 0 obj<</D[628 0 R/XYZ 0 652 0]>>endobj
368 0 obj<</D[628 0 R/XYZ 0 531 0]>>endobj
369 0 obj<</D[628 0 R/XYZ 0 354 0]>>endobj
370 0 obj<</D[628 0 R/XYZ 0 260 0]>>endobj
371 0 obj<</D[628 0 R/XYZ 0 165 0]>>endobj
372 0 obj<</D[630 0 R/XYZ 0 734 0]>>endobj
373 0 obj<</D[630 0 R/XYZ 0 665 0]>>endobj
374 0 obj<</D[630 0 R/XYZ 0 353 0]>>endobj
375 0 obj<</D[630 0 R/XYZ 0 281 0]>>endobj
376 0 obj<</D[630 0 R/XYZ 0 213 0]>>endobj
377 0 obj<</D[632 0 R/XYZ 0 734 0]>>endobj
378 0 obj<</D[632 0 R/XYZ 0 658 0]>>endobj
379 0 obj<</D[632 0 R/XYZ 0 600 0]>>endobj
380 0 obj<</D[532 0 R/XYZ 0 672 0]>>endobj
381 0 obj<</D[632 0 R/XYZ 0 347 0]>>endobj
382 0 obj<</D[634 0 R/XYZ 0 734 0]>>endobj
383 0 obj<</D[634 0 R/XYZ 0 622 0]>>endobj
384 0 obj<</D[634 0 R/XYZ 0 264 0]>>endobj
385 0 obj<</D[636 0 R/XYZ 0 705 0]>>endobj
386 0 obj<</D[636 0 R/XYZ 0 577 0]>>endobj
387 0 obj<</D[636 0 R/XYZ 0 492 0]>>endobj
388 0 obj<</D[636 0 R/XYZ 0 239 0]>>endobj
389 0 obj<</D[638 0 R/XYZ 0 734 0]>>endobj
390 0 obj<</D[638 0 R/XYZ 0 675 0]>>endobj
391 0 obj<</D[638 0 R/XYZ 0 581 0]>>endobj
392 0 obj<</D[638 0 R/XYZ 0 433 0]>>endobj
393 0 obj<</D[638 0 R/XYZ 0 400 0]>>endobj
394 0 obj<</D[640 0 R/XYZ 0 734 0]>>endobj
395 0 obj<</D[640 0 R/XYZ 0 385 0]>>endobj
396 0 obj<</D[640 0 R/XYZ 0 128 0]>>endobj
397 0 obj<</D[642 0 R/XYZ 0 633 0]>>endobj
398 0 obj<</D[642 0 R/XYZ 0 603 0]>>endobj
399 0 obj<</D[642 0 R/XYZ 0 351 0]>>endobj
400 0 obj<</D[644 0 R/XYZ 0 665 0]>>endobj
401 0 obj<</D[644 0 R/XYZ 0 594 0]>>endobj
402 0 obj<</D[644 0 R/XYZ 0 407 0]>>endobj
403 0 obj<</D[552 0 R/XYZ 0 696 0]>>endobj
404 0 obj<</D[644 0 R/XYZ 0 141 0]>>endobj
405 0 obj<</D[552 0 R/XYZ 0 568 0]>>endobj
406 0 obj<</D[648 0 R/XYZ 0 696 0]>>endobj
407 0 obj<</D[648 0 R/XYZ 0 621 0]>>endobj
408 0 obj<</D[648 0 R/XYZ 0 361 0]>>endobj
409 0 obj<</D[652 0 R/XYZ 0 692 0]>>endobj
410 0 obj<</D[652 0 R/XYZ 0 630 0]>>endobj
411 0 obj<</D[658 0 R/XYZ 0 696 0]>>endobj
412 0 obj<</D[660 0 R/XYZ 0 696 0]>>endobj
413 0 obj<</D[662 0 R/XYZ 0 639 0]>>endobj
414 0 obj<</D[662 0 R/XYZ 0 498 0]>>endobj
415 0 obj<</D[662 0 R/XYZ 0 198 0]>>endobj
416 0 obj<</D[662 0 R/XYZ 0 165 0]>>endobj
417 0 obj<</D[664 0 R/XYZ 0 734 0]>>endobj
418 0 obj<</D[664 0 R/XYZ 0 596 0]>>endobj
419 0 obj<</D[664 0 R/XYZ 0 485 0]>>endobj
420 0 obj<</D[664 0 R/XYZ 0 451 0]>>endobj
421 0 obj<</D[664 0 R/XYZ 0 366 0]>>endobj
422 0 obj<</D[664 0 R/XYZ 0 229 0]>>endobj
423 0 obj<</D[666 0 R/XYZ 0 489 0]>>endobj
424 0 obj<</D[668 0 R/XYZ 0 696 0]>>endobj
425 0 obj<</D[668 0 R/XYZ 0 568 0]>>endobj
426 0 obj<</D[670 0 R/XYZ 0 718 0]>>endobj
427 0 obj<</D[554 0 R/XYZ 0 705 0]>>endobj
428 0 obj<</D[554 0 R/XYZ 0 630 0]>>endobj
429 0 obj<</D[554 0 R/XYZ 0 571 0]>>endobj
430 0 obj<</D[554 0 R/XYZ 0 513 0]>>endobj
431 0 obj<</D[554 0 R/XYZ 0 455 0]>>endobj
432 0 obj<</D[554 0 R/XYZ 0 383 0]>>endobj
433 0 obj<</D[554 0 R/XYZ 0 325 0]>>endobj
434 0 obj<</D[554 0 R/XYZ 0 266 0]>>endobj
435 0 obj<</D[554 0 R/XYZ 0 208 0]>>endobj
436 0 obj<</D[554 0 R/XYZ 0 149 0]>>endobj
437 0 obj<</D[556 0 R/XYZ 0 734 0]>>endobj
438 0 obj<</D[532 0 R/XYZ 0 201 0]>>endobj
439 0 obj<</D[556 0 R/XYZ 0 675 0]>>endobj
440 0 obj<</D[556 0 R/XYZ 0 617 0]>>endobj
441 0 obj<</D[556 0 R/XYZ 0 558 0]>>endobj
442 0 obj<</D[556 0 R/XYZ 0 500 0]>>endobj
443 0 obj<</D[556 0 R/XYZ 0 428 0]>>endobj
444 0 obj<</D[556 0 R/XYZ 0 370 0]>>endobj
445 0 obj<</D[556 0 R/XYZ 0 220 0]>>endobj
446 0 obj<</D[534 0 R/XYZ 0 705 0]>>endobj
447 0 obj<</D[524 0 R/XYZ 0 696 0]>>endobj
448 0 obj<</D[558 0 R/XYZ 0 441 0]>>endobj
449 0 obj<</D[560 0 R/XYZ 0 734 0]>>endobj
450 0 obj<</D[562 0 R/XYZ 0 696 0]>>endobj
451 0 obj<</D[562 0 R/XYZ 0 423 0]>>endobj
452 0 obj<</D[562 0 R/XYZ 0 259 0]>>endobj
453 0 obj<</D[564 0 R/XYZ 0 652 0]>>endobj
454 0 obj<</D[564 0 R/XYZ 0 240 0]>>endobj
455 0 obj<</D[566 0 R/XYZ 0 665 0]>>endobj
456 0 obj<</D[536 0 R/XYZ 0 696 0]>>endobj
457 0 obj<</D[568 0 R/XYZ 0 696 0]>>endobj
458 0 obj<</D[568 0 R/XYZ 0 595 0]>>endobj
459 0 obj<</D[568 0 R/XYZ 0 216 0]>>endobj
460 0 obj<</D[570 0 R/XYZ 0 692 0]>>endobj
461 0 obj<</D[570 0 R/XYZ 0 458 0]>>endobj
462 0 obj<</D[572 0 R/XYZ 0 734 0]>>endobj
463 0 obj<</D[572 0 R/XYZ 0 566 0]>>endobj
464 0 obj<</D[572 0 R/XYZ 0 438 0]>>endobj
465 0 obj<</D[572 0 R/XYZ 0 178 0]>>endobj
466 0 obj<</D[536 0 R/XYZ 0 529 0]>>endobj
467 0 obj<</D[580 0 R/XYZ 0 696 0]>>endobj
468 0 obj<</D[582 0 R/XYZ 0 626 0]>>endobj
469 0 obj<</D[582 0 R/XYZ 0 516 0]>>endobj
470 0 obj<</D[536 0 R/XYZ 0 335 0]>>endobj
471 0 obj<</D[582 0 R/XYZ 0 394 0]>>endobj
472 0 obj<</D[582 0 R/XYZ 0 360 0]>>endobj
473 0 obj<</D[584 0 R/XYZ 0 718 0]>>endobj
474 0 obj<</D[584 0 R/XYZ 0 688 0]>>endobj
475 0 obj<</D[584 0 R/XYZ 0 515 0]>>endobj
476 0 obj<</D[584 0 R/XYZ 0 235 0]>>endobj
477 0 obj<</D[584 0 R/XYZ 0 205 0]>>endobj
478 0 obj<</D[584 0 R/XYZ 0 151 0]>>endobj
479 0 obj<</D[586 0 R/XYZ 0 734 0]>>endobj
480 0 obj<</D[586 0 R/XYZ 0 665 0]>>endobj
481 0 obj<</D[586 0 R/XYZ 0 611 0]>>endobj
482 0 obj<</D[526 0 R/XYZ 0 734 0]>>endobj
483 0 obj<</D[586 0 R/XYZ 0 411 0]>>endobj
484 0 obj<</D[586 0 R/XYZ 0 356 0]>>endobj
485 0 obj<</D[586 0 R/XYZ 0 235 0]>>endobj
486 0 obj<</D[586 0 R/XYZ 0 141 0]>>endobj
487 0 obj<</D[588 0 R/XYZ 0 734 0]>>endobj
488 0 obj<</D[538 0 R/XYZ 0 734 0]>>endobj
489 0 obj<</D[588 0 R/XYZ 0 639 0]>>endobj
490 0 obj<</D[588 0 R/XYZ 0 465 0]>>endobj
491 0 obj<</D[588 0 R/XYZ 0 265 0]>>endobj
492 0 obj<</D[588 0 R/XYZ 0 197 0]>>endobj
493 0 obj<</D[538 0 R/XYZ 0 434 0]>>endobj
494 0 obj<</D[590 0 R/XYZ 0 665 0]>>endobj
495 0 obj<</D[590 0 R/XYZ 0 518 0]>>endobj
496 0 obj<</D[590 0 R/XYZ 0 279 0]>>endobj
497 0 obj<</D[536 0 R/XYZ 0 734 0]>>endobj
498 0 obj<</D[548 0 R/XYZ 0 734 0]>>endobj
499 0 obj<</D[540 0 R/XYZ 0 734 0]>>endobj
500 0 obj<</D[552 0 R/XYZ 0 734 0]>>endobj
501 0 obj<</D[532 0 R/XYZ 0 734 0]>>endobj
502 0 obj<</D[580 0 R/XYZ 0 734 0]>>endobj
503 0 obj<</D[562 0 R/XYZ 0 734 0]>>endobj
504 0 obj<</D[648 0 R/XYZ 0 734 0]>>endobj
505 0 obj<</D[668 0 R/XYZ 0 734 0]>>endobj
506 0 obj<</D[660 0 R/XYZ 0 734 0]>>endobj
507 0 obj<</D[524 0 R/XYZ 0 734 0]>>endobj
508 0 obj<</D[524 0 R/XYZ 0 734 0]>>endobj
509 0 obj<</D[670 0 R/XYZ 0 718 0]>>endobj
510 0 obj<</D[576 0 R/XYZ 0 734 0]>>endobj
511 0 obj<</D[568 0 R/XYZ 0 734 0]>>endobj
512 0 obj<</D[658 0 R/XYZ 0 734 0]>>endobj
513 0 obj<</Type/Pages/Count 80/Kids[514 0 R
516 0 R
518 0 R
520 0 R
522 0 R
524 0 R
526 0 R
528 0 R
530 0 R
532 0 R
534 0 R
536 0 R
538 0 R
540 0 R
542 0 R
544 0 R
546 0 R
548 0 R
550 0 R
552 0 R
554 0 R
556 0 R
558 0 R
560 0 R
562 0 R
564 0 R
566 0 R
568 0 R
570 0 R
572 0 R
574 0 R
576 0 R
578 0 R
580 0 R
582 0 R
584 0 R
586 0 R
588 0 R
590 0 R
592 0 R
594 0 R
596 0 R
598 0 R
600 0 R
602 0 R
604 0 R
606 0 R
608 0 R
610 0 R
612 0 R
614 0 R
616 0 R
618 0 R
620 0 R
622 0 R
624 0 R
626 0 R
628 0 R
630 0 R
632 0 R
634 0 R
636 0 R
638 0 R
640 0 R
642 0 R
644 0 R
646 0 R
648 0 R
650 0 R
652 0 R
654 0 R
656 0 R
658 0 R
660 0 R
662 0 R
664 0 R
666 0 R
668 0 R
670 0 R
672 0 R
]>>endobj
514 0 obj<</Type/Page/Parent 513 0 R/Contents 515 0 R/MediaBox[0 0 595 792]/Resources<</ProcSet[/PDF/Text]/Font<</F8 10 0 R/F9 11 0 R>>/XObject<<>>>>>>endobj
515 0 obj<</Filter/FlateDecode/Length 93        >>stream
x+ä2T0