2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2N/A * Librtl_db brand plugin libraries should NOT directly invoke any 2N/A * libproc.so interfaces or be linked against libproc. If a librtl_db 2N/A * brand plugin library uses libproc.so interfaces then it may break 2N/A * any other librtld_db consumers (like mdb) that tries to attach 2N/A * to a branded process. The only safe interfaces that the a librtld_db 2N/A * brand plugin library can use to access a target process are the 2N/A * proc_service(3PROC) apis. 2N/A * M_DATA comes from some streams header file but is also redifined in 2N/A * For 32-bit versions of this library, this file get's compiled once. 2N/A * For 64-bit versions of this library, this file get's compiled twice, 2N/A * once with _ELF64 defined and once without. The expectation is that 2N/A * the 64-bit version of the library can properly deal with both 32-bit 2N/A * and 64-bit elf files, hence in the 64-bit library there are two copies 2N/A * of all the interfaces in this file, one set named *32 and one named *64. 2N/A * This also means that we need to be careful when declaring local pointers 2N/A * that point to objects in another processes address space, since these 2N/A * pointers may not match the current processes pointer width. Basically, 2N/A * we should not use any objects that change size between 32 and 64 bit 2N/A * modes like: long, void *, uintprt_t, caddr_t, psaddr_t, size_t, etc. 2N/A * Instead we should declare all pointers as uint32_t. Then when we 2N/A * are compiled to deal with 64-bit targets we'll re-define uing32_t 2N/A * Normally, the native Solaris librtldb_db plugin uses a bunch of different 2N/A * methods to try and find the rdebug structure associated with the target 2N/A * process we're debugging. For details on the different methods see 2N/A * _rd_reset32(). Thankfully our job is easier. We know that the brand 2N/A * library is always linked against the native linker, and when the 2N/A * process was first executed we saved off a pointer to the brand linkers 2N/A * rdebug structure in one of our brand specific aux vectors, 2N/A * AT_SUN_BRAND_COMMON_LDDATA. So we'll just look that up here. 2N/A ps_plog(
"brand_ldb_init: lookup of data model failed");
2N/A ps_plog(
"brand_ldb_init: no LDDATA found in aux vector");
2N/A * Ok. So this is kinda ugly. Basically we know that we're going to 2N/A * be parsing data from link maps that are generated by a Solaris 2N/A * linker. As it turns out, that's exactly what the default 2N/A * Solaris librtld_db library is designed to do. So rather than 2N/A * duplicate all that link map parsing code here we'll simply 2N/A * invoke the native librtld_db that normally does this, and when 2N/A * we do we'll point them at our emulation libraries link map. 2N/A * Of course these interfacess aren't really public interfaces 2N/A * and they take a "struct rd_agent" as a parameter. So here 2N/A * we'll allocate and initialize a new "struct rd_agent", point 2N/A * it at our emulation libraries link map, and initialize just 2N/A * enough of the structure to make the librtld_db interfaces 2N/A * that we want to use happy. 2N/A * When we get invoked from librtld_db, and we call back into it, 2N/A * librtld_db will once again check if there is a plugin and 2N/A * invoke it. Since we don't want to enter a recursive loop 2N/A * we're going to specify a different plugin interface for 2N/A * our linkmap, and these new plugin interfaces won't actually 2N/A * do anything other than return. 2N/A * validate_rdebug32() requires the following "struct rd_agent" 2N/A * members to be initialized: 2N/A * validate_rdebug32() initializes the following "struct rd_agent" 2N/A * rd_flags, rd_rdebugvers, rd_rtlddbpriv 2N/A ps_plog(
"brand_ldb_init: can't find valid r_debug data");
2N/A ps_plog(
"brand_ldb_fini: cleaning up brand helper");
2N/A * _rd_loadobj_iter32() requires the following "struct rd_agent" 2N/A * members to be initialized: 2N/A * rd_rtlddbpriv, rd_rdebugvers, rd_flags, 2N/A * rd_helper.rh_ops, rd_dmodel 2N/A * Librtld_db plugin linkage struct. 2N/A * When we get loaded by librtld_db, it will look for the symbol below 2N/A * to find our plugin entry points.