1 2712 nn35248 /* 2 2712 nn35248 * CDDL HEADER START 3 2712 nn35248 * 4 2712 nn35248 * The contents of this file are subject to the terms of the 5 2712 nn35248 * Common Development and Distribution License (the "License"). 6 2712 nn35248 * You may not use this file except in compliance with the License. 7 2712 nn35248 * 8 2712 nn35248 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 2712 nn35248 * or http://www.opensolaris.org/os/licensing. 10 2712 nn35248 * See the License for the specific language governing permissions 11 2712 nn35248 * and limitations under the License. 12 2712 nn35248 * 13 2712 nn35248 * When distributing Covered Code, include this CDDL HEADER in each 14 2712 nn35248 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 2712 nn35248 * If applicable, add the following below this CDDL HEADER, with the 16 2712 nn35248 * fields enclosed by brackets "[]" replaced with your own identifying 17 2712 nn35248 * information: Portions Copyright [yyyy] [name of copyright owner] 18 2712 nn35248 * 19 2712 nn35248 * CDDL HEADER END 20 2712 nn35248 */ 21 2712 nn35248 /* 22 6473 edp * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 2712 nn35248 * Use is subject to license terms. 24 2712 nn35248 */ 25 2712 nn35248 26 2712 nn35248 #pragma ident "%Z%%M% %I% %E% SMI" 27 2712 nn35248 28 2712 nn35248 #include <stdio.h> 29 2712 nn35248 #include <stdlib.h> 30 2712 nn35248 #include <string.h> 31 2712 nn35248 #include <strings.h> 32 2712 nn35248 #include <sys/types.h> 33 2712 nn35248 #include <sys/link.h> 34 2712 nn35248 #include <libproc.h> 35 2712 nn35248 #include <proc_service.h> 36 2712 nn35248 #include <rtld_db.h> 37 2712 nn35248 #include <synch.h> 38 6830 edp 39 2712 nn35248 #include <sys/lx_brand.h> 40 2712 nn35248 41 6830 edp /* 42 6830 edp * ATTENTION: 43 6830 edp * Librtl_db brand plugin libraries should NOT directly invoke any 44 6830 edp * libproc.so interfaces or be linked against libproc. If a librtl_db 45 6830 edp * brand plugin library uses libproc.so interfaces then it may break 46 6830 edp * any other librtld_db consumers (like mdb) that tries to attach 47 6830 edp * to a branded process. The only safe interfaces that the a librtld_db 48 6830 edp * brand plugin library can use to access a target process are the 49 6830 edp * proc_service(3PROC) apis. 50 6830 edp */ 51 2712 nn35248 52 6830 edp /* 53 6830 edp * M_DATA comes from some streams header file but is also redifined in 54 6830 edp * _rtld_db.h, so nuke the old streams definition here. 55 6830 edp */ 56 6830 edp #ifdef M_DATA 57 6830 edp #undef M_DATA 58 6830 edp #endif /* M_DATA */ 59 6830 edp 60 6830 edp /* 61 6830 edp * For 32-bit versions of this library, this file get's compiled once. 62 6830 edp * For 64-bit versions of this library, this file get's compiled twice, 63 6830 edp * once with _ELF64 defined and once without. The expectation is that 64 6830 edp * the 64-bit version of the library can properly deal with both 32-bit 65 6830 edp * and 64-bit elf files, hence in the 64-bit library there are two copies 66 6830 edp * of all the interfaces in this file, one set named *32 and one named *64. 67 6830 edp * 68 6830 edp * This also means that we need to be careful when declaring local pointers 69 6830 edp * that point to objects in another processes address space, since these 70 6830 edp * pointers may not match the current processes pointer width. Basically, 71 6830 edp * we should avoid using data types that change size between 32 and 64 bit 72 6830 edp * modes like: long, void *, uintprt_t, caddr_t, psaddr_t, size_t, etc. 73 6830 edp * Instead we should declare all pointers as uint32_t. Then when we 74 6830 edp * are compiled to deal with 64-bit targets we'll re-define uint32_t 75 6830 edp * to be a uint64_t. 76 6830 edp * 77 6830 edp * Finally, one last importante note. All the 64-bit elf file code 78 6830 edp * is never used and can't be tested. This is because we don't actually 79 6830 edp * support 64-bit Linux processes yet. The reason that we have it here 80 6830 edp * is because we want to support debugging 32-bit elf targets with the 81 6830 edp * 64-bit version of this library, so we need to have a 64-bit version 82 6830 edp * of this library. But a 64-bit version of this library is expected 83 6830 edp * to provide debugging interfaces for both 32 and 64-bit elf targets. 84 6830 edp * So we provide the 64-bit elf target interfaces, but they will never 85 6830 edp * be invoked and are untested. If we ever add support for 64-bit elf 86 6830 edp * Linux processes, we'll need to verify that this code works correctly 87 6830 edp * for those targets. 88 6830 edp */ 89 6830 edp #ifdef _LP64 90 6830 edp #ifdef _ELF64 91 6830 edp #define lx_ldb_get_dyns32 lx_ldb_get_dyns64 92 6830 edp #define lx_ldb_init32 lx_ldb_init64 93 6830 edp #define lx_ldb_fini32 lx_ldb_fini64 94 6830 edp #define lx_ldb_loadobj_iter32 lx_ldb_loadobj_iter64 95 6830 edp #define lx_ldb_getauxval32 lx_ldb_getauxval64 96 6830 edp #define lx_elf_props32 lx_elf_props64 97 6830 edp #define _rd_get_dyns32 _rd_get_dyns64 98 6830 edp #define _rd_get_ehdr32 _rd_get_ehdr64 99 6830 edp #define uint32_t uint64_t 100 6830 edp #define Elf32_Dyn Elf64_Dyn 101 6830 edp #define Elf32_Ehdr Elf64_Ehdr 102 6830 edp #define Elf32_Phdr Elf64_Phdr 103 6830 edp #endif /* _ELF64 */ 104 6830 edp #endif /* _LP64 */ 105 6830 edp 106 6830 edp /* Included from usr/src/cmd/sgs/librtld_db/common */ 107 6830 edp #include <_rtld_db.h> 108 2712 nn35248 109 2712 nn35248 typedef struct lx_rd { 110 6830 edp rd_agent_t *lr_rap; 111 6830 edp struct ps_prochandle *lr_php; /* proc handle pointer */ 112 6830 edp uint32_t lr_rdebug; /* address of lx r_debug */ 113 6830 edp uint32_t lr_exec; /* base address of executable */ 114 2712 nn35248 } lx_rd_t; 115 2712 nn35248 116 6830 edp typedef struct lx_link_map { 117 2712 nn35248 uint32_t lxm_addr; /* Base address shared object is loaded at. */ 118 2712 nn35248 uint32_t lxm_name; /* Absolute file name object was found in. */ 119 2712 nn35248 uint32_t lxm_ld; /* Dynamic section of the shared object. */ 120 6830 edp uint32_t lxm_next; /* Chain of loaded objects. */ 121 6830 edp } lx_link_map_t; 122 2712 nn35248 123 6830 edp typedef struct lx_r_debug { 124 2712 nn35248 int r_version; /* Version number for this protocol. */ 125 2712 nn35248 uint32_t r_map; /* Head of the chain of loaded objects. */ 126 2712 nn35248 127 2712 nn35248 /* 128 2712 nn35248 * This is the address of a function internal to the run-time linker, 129 2712 nn35248 * that will always be called when the linker begins to map in a 130 2712 nn35248 * library or unmap it, and again when the mapping change is complete. 131 2712 nn35248 * The debugger can set a breakpoint at this address if it wants to 132 2712 nn35248 * notice shared object mapping changes. 133 2712 nn35248 */ 134 2712 nn35248 uint32_t r_brk; 135 2712 nn35248 r_state_e r_state; /* defined the same way between lx/solaris */ 136 2712 nn35248 uint32_t r_ldbase; /* Base address the linker is loaded at. */ 137 6830 edp } lx_r_debug_t; 138 6830 edp 139 6830 edp static uint32_t 140 6830 edp lx_ldb_getauxval32(struct ps_prochandle *php, int type) 141 6830 edp { 142 6830 edp const auxv_t *auxvp = NULL; 143 6830 edp 144 6830 edp if (ps_pauxv(php, &auxvp) != PS_OK) 145 6830 edp return ((uint32_t)-1); 146 6830 edp 147 6830 edp while (auxvp->a_type != AT_NULL) { 148 6830 edp if (auxvp->a_type == type) 149 6830 edp return ((uint32_t)(uintptr_t)auxvp->a_un.a_ptr); 150 6830 edp auxvp++; 151 6830 edp } 152 6830 edp return ((uint32_t)-1); 153 6830 edp } 154 2712 nn35248 155 2712 nn35248 /* 156 2712 nn35248 * A key difference between the linux linker and ours' is that the linux 157 2712 nn35248 * linker adds the base address of segments to certain values in the 158 2712 nn35248 * segments' ELF header. As an example, look at the address of the 159 2712 nn35248 * DT_HASH hash table in a Solaris section - it is a relative address 160 2712 nn35248 * which locates the start of the hash table, relative to the beginning 161 2712 nn35248 * of the ELF file. However, when the linux linker loads a section, it 162 2712 nn35248 * modifies the in-memory ELF image by changing address of the hash 163 2712 nn35248 * table to be an absolute address. This is only done for libraries - not for 164 2712 nn35248 * executables. 165 2712 nn35248 * 166 2712 nn35248 * Solaris tools expect the relative address to remain relative, so 167 2712 nn35248 * here we will modify the in-memory ELF image so that it once again 168 2712 nn35248 * contains relative addresses. 169 2712 nn35248 * 170 2712 nn35248 * To accomplish this, we walk through all sections in the target. 171 2712 nn35248 * Linux sections are identified by pointing to the linux linker or libc in the 172 2712 nn35248 * DT_NEEDED section. For all matching sections, we subtract the segment 173 2712 nn35248 * base address to get back to relative addresses. 174 2712 nn35248 */ 175 6830 edp static rd_err_e 176 6830 edp lx_ldb_get_dyns32(rd_helper_data_t rhd, 177 6830 edp psaddr_t addr, void **dynpp, size_t *dynpp_sz) 178 2712 nn35248 { 179 6830 edp lx_rd_t *lx_rd = (lx_rd_t *)rhd; 180 6830 edp rd_agent_t *rap = lx_rd->lr_rap; 181 6830 edp Elf32_Ehdr ehdr; 182 6830 edp Elf32_Dyn *dynp = NULL; 183 6830 edp size_t dynp_sz; 184 6830 edp uint_t ndyns; 185 2712 nn35248 int i; 186 2712 nn35248 187 6830 edp ps_plog("lx_ldb_get_dyns: invoked for object at 0x%p", addr); 188 6473 edp 189 6830 edp /* Read in a copy of the ehdr */ 190 6830 edp if (_rd_get_ehdr32(rap, addr, &ehdr, NULL) != RD_OK) { 191 6830 edp ps_plog("lx_ldb_get_dyns: _rd_get_ehdr() failed"); 192 6830 edp return (RD_ERR); 193 2712 nn35248 } 194 2712 nn35248 195 6830 edp /* read out the PT_DYNAMIC elements for this object */ 196 6830 edp if (_rd_get_dyns32(rap, addr, &dynp, &dynp_sz) != RD_OK) { 197 6830 edp ps_plog("lx_ldb_get_dyns: _rd_get_dyns() failed"); 198 6830 edp return (RD_ERR); 199 2712 nn35248 } 200 2712 nn35248 201 2712 nn35248 /* 202 6830 edp * From here on out if we encounter an error we'll just return 203 6830 edp * success and pass back the unmolested dynamic elements that 204 6830 edp * we've already obtained. 205 2712 nn35248 */ 206 6830 edp *dynpp = dynp; 207 6830 edp *dynpp_sz = dynp_sz; 208 6830 edp ndyns = dynp_sz / sizeof (Elf32_Dyn); 209 2712 nn35248 210 6830 edp /* If this isn't a dynamic object, there's nothing left todo */ 211 6830 edp if (ehdr.e_type != ET_DYN) { 212 6830 edp ps_plog("lx_ldb_get_dyns: done: not a shared object"); 213 6830 edp return (RD_OK); 214 2712 nn35248 } 215 2712 nn35248 216 2712 nn35248 /* 217 6830 edp * Before we blindly start changing dynamic section addresses 218 6830 edp * we need to figure out if the current object that we're looking 219 6830 edp * at is a linux object or a solaris object. To do this first 220 6830 edp * we need to find the string tab dynamic section element. 221 2712 nn35248 */ 222 6830 edp for (i = 0; i < ndyns; i++) { 223 6830 edp if (dynp[i].d_tag == DT_STRTAB) 224 6830 edp break; 225 6830 edp } 226 6830 edp if (i == ndyns) { 227 6830 edp ps_plog("lx_ldb_get_dyns: " 228 6830 edp "failed to find string tab in the dynamic section"); 229 6830 edp return (RD_OK); 230 6830 edp } 231 6830 edp 232 6830 edp /* 233 6830 edp * Check if the strtab value looks like an offset or an address. 234 6830 edp * It's an offset if the value is less then the base address that 235 6830 edp * the object is loaded at, or if the value is less than the offset 236 6830 edp * of the section headers in the same elf object. This check isn't 237 6830 edp * perfect, but in practice it's good enough. 238 6830 edp */ 239 6830 edp if ((dynp[i].d_un.d_ptr < addr) || 240 6830 edp (dynp[i].d_un.d_ptr < ehdr.e_shoff)) { 241 6830 edp ps_plog("lx_ldb_get_dyns: " 242 6830 edp "doesn't appear to be an lx object"); 243 6830 edp return (RD_OK); 244 6830 edp } 245 6830 edp 246 6830 edp /* 247 6830 edp * This seems to be a a linux object, so we'll patch up the dynamic 248 6830 edp * section addresses 249 6830 edp */ 250 6830 edp ps_plog("lx_ldb_get_dyns: " 251 6830 edp "patching up lx object dynamic section addresses"); 252 6830 edp for (i = 0; i < ndyns; i++) { 253 6830 edp switch (dynp[i].d_tag) { 254 6830 edp case DT_PLTGOT: 255 2712 nn35248 case DT_HASH: 256 2712 nn35248 case DT_STRTAB: 257 2712 nn35248 case DT_SYMTAB: 258 6830 edp case DT_RELA: 259 6830 edp case DT_REL: 260 2712 nn35248 case DT_DEBUG: 261 2712 nn35248 case DT_JMPREL: 262 2712 nn35248 case DT_VERSYM: 263 6830 edp if (dynp[i].d_un.d_val > addr) { 264 6830 edp dynp[i].d_un.d_ptr -= addr; 265 2712 nn35248 } 266 2712 nn35248 break; 267 2712 nn35248 default: 268 2712 nn35248 break; 269 2712 nn35248 } 270 2712 nn35248 } 271 6830 edp return (RD_OK); 272 6830 edp } 273 6830 edp 274 6830 edp static void 275 6830 edp lx_ldb_fini32(rd_helper_data_t rhd) 276 6830 edp { 277 6830 edp lx_rd_t *lx_rd = (lx_rd_t *)rhd; 278 6830 edp ps_plog("lx_ldb_fini: cleaning up lx helper"); 279 6830 edp free(lx_rd); 280 2712 nn35248 } 281 2712 nn35248 282 2712 nn35248 /* 283 2712 nn35248 * The linux linker has an r_debug structure somewhere in its data section that 284 2712 nn35248 * contains the address of the head of the link map list. To find this, we will 285 2712 nn35248 * use the DT_DEBUG token in the executable's dynamic section. The linux linker 286 2712 nn35248 * wrote the address of its r_debug structure to the DT_DEBUG dynamic entry. We 287 2712 nn35248 * get the address of the executable's program headers from the 288 6473 edp * AT_SUN_BRAND_LX_PHDR aux vector entry. From there, we calculate the 289 6473 edp * address of the Elf header, and from there we can easily get to the DT_DEBUG 290 6473 edp * entry. 291 2712 nn35248 */ 292 6830 edp static rd_helper_data_t 293 6830 edp lx_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php) 294 2712 nn35248 { 295 6830 edp lx_rd_t *lx_rd; 296 6830 edp uint32_t addr, phdr_addr, dyn_addr; 297 6830 edp Elf32_Dyn *dyn; 298 6473 edp Elf32_Phdr phdr, *ph, *phdrs; 299 2712 nn35248 Elf32_Ehdr ehdr; 300 6830 edp int i, dyn_count; 301 2712 nn35248 302 6830 edp lx_rd = calloc(sizeof (lx_rd_t), 1); 303 6830 edp if (lx_rd == NULL) { 304 6830 edp ps_plog("lx_ldb_init: cannot allocate memory"); 305 2712 nn35248 return (NULL); 306 2712 nn35248 } 307 6830 edp lx_rd->lr_rap = rap; 308 6830 edp lx_rd->lr_php = php; 309 2712 nn35248 310 6830 edp phdr_addr = lx_ldb_getauxval32(php, AT_SUN_BRAND_LX_PHDR); 311 6473 edp if (phdr_addr == (uint32_t)-1) { 312 6830 edp ps_plog("lx_ldb_init: no LX_PHDR found in aux vector"); 313 6473 edp return (NULL); 314 6473 edp } 315 6830 edp ps_plog("lx_ldb_init: found LX_PHDR auxv phdr at: 0x%p", 316 6473 edp phdr_addr); 317 2712 nn35248 318 2712 nn35248 if (ps_pread(php, phdr_addr, &phdr, sizeof (phdr)) != PS_OK) { 319 6830 edp ps_plog("lx_ldb_init: couldn't read phdr at 0x%p", 320 2712 nn35248 phdr_addr); 321 6830 edp free(lx_rd); 322 2712 nn35248 return (NULL); 323 2712 nn35248 } 324 2712 nn35248 325 6473 edp /* The ELF headher should be before the program header in memory */ 326 6830 edp lx_rd->lr_exec = addr = phdr_addr - phdr.p_offset; 327 6830 edp if (ps_pread(php, addr, &ehdr, sizeof (ehdr)) != PS_OK) { 328 6830 edp ps_plog("lx_ldb_init: couldn't read ehdr at 0x%p", 329 6830 edp lx_rd->lr_exec); 330 6830 edp free(lx_rd); 331 2712 nn35248 return (NULL); 332 2712 nn35248 } 333 6830 edp ps_plog("lx_ldb_init: read ehdr at: 0x%p", addr); 334 2712 nn35248 335 2712 nn35248 if ((phdrs = malloc(ehdr.e_phnum * ehdr.e_phentsize)) == NULL) { 336 6830 edp ps_plog("lx_ldb_init: couldn't alloc phdrs memory"); 337 6830 edp free(lx_rd); 338 2712 nn35248 return (NULL); 339 2712 nn35248 } 340 2712 nn35248 341 2712 nn35248 if (ps_pread(php, phdr_addr, phdrs, ehdr.e_phnum * ehdr.e_phentsize) != 342 2712 nn35248 PS_OK) { 343 6830 edp ps_plog("lx_ldb_init: couldn't read phdrs at 0x%p", 344 2712 nn35248 phdr_addr); 345 6830 edp free(lx_rd); 346 2712 nn35248 free(phdrs); 347 2712 nn35248 return (NULL); 348 2712 nn35248 } 349 6830 edp ps_plog("lx_ldb_init: read %d phdrs at: 0x%p", 350 6473 edp ehdr.e_phnum, phdr_addr); 351 2712 nn35248 352 2712 nn35248 for (i = 0, ph = phdrs; i < ehdr.e_phnum; i++, 353 2712 nn35248 /*LINTED */ 354 2712 nn35248 ph = (Elf32_Phdr *)((char *)ph + ehdr.e_phentsize)) { 355 2712 nn35248 if (ph->p_type == PT_DYNAMIC) 356 2712 nn35248 break; 357 2712 nn35248 } 358 2712 nn35248 if (i == ehdr.e_phnum) { 359 6830 edp ps_plog("lx_ldb_init: no PT_DYNAMIC in executable"); 360 6830 edp free(lx_rd); 361 6473 edp free(phdrs); 362 6473 edp return (NULL); 363 6473 edp } 364 6830 edp ps_plog("lx_ldb_init: found PT_DYNAMIC phdr[%d] at: 0x%p", 365 6473 edp i, (phdr_addr + ((char *)ph - (char *)phdrs))); 366 6473 edp 367 6830 edp if ((dyn = malloc(ph->p_filesz)) == NULL) { 368 6830 edp ps_plog("lx_ldb_init: couldn't alloc for PT_DYNAMIC"); 369 6830 edp free(lx_rd); 370 2712 nn35248 free(phdrs); 371 2712 nn35248 return (NULL); 372 2712 nn35248 } 373 2712 nn35248 374 6830 edp dyn_addr = addr + ph->p_offset; 375 6830 edp dyn_count = ph->p_filesz / sizeof (Elf32_Dyn); 376 6830 edp if (ps_pread(php, dyn_addr, dyn, ph->p_filesz) != PS_OK) { 377 6830 edp ps_plog("lx_ldb_init: couldn't read dynamic at 0x%p", 378 6830 edp dyn_addr); 379 6830 edp free(lx_rd); 380 2712 nn35248 free(phdrs); 381 6830 edp free(dyn); 382 2712 nn35248 return (NULL); 383 2712 nn35248 } 384 6830 edp ps_plog("lx_ldb_init: read %d dynamic headers at: 0x%p", 385 6830 edp dyn_count, dyn_addr); 386 2712 nn35248 387 6830 edp for (i = 0; i < dyn_count; i++) { 388 6830 edp if (dyn[i].d_tag == DT_DEBUG) { 389 6830 edp lx_rd->lr_rdebug = dyn[i].d_un.d_ptr; 390 2712 nn35248 break; 391 2712 nn35248 } 392 2712 nn35248 } 393 2712 nn35248 free(phdrs); 394 6830 edp free(dyn); 395 2712 nn35248 396 6830 edp if (lx_rd->lr_rdebug == 0) { 397 6830 edp ps_plog("lx_ldb_init: no DT_DEBUG found in exe"); 398 6830 edp free(lx_rd); 399 2712 nn35248 return (NULL); 400 2712 nn35248 } 401 6830 edp ps_plog("lx_ldb_init: found DT_DEBUG: 0x%p", lx_rd->lr_rdebug); 402 2712 nn35248 403 6830 edp return ((rd_helper_data_t)lx_rd); 404 2712 nn35248 } 405 2712 nn35248 406 2712 nn35248 /* 407 2712 nn35248 * Given the address of an ELF object in the target, return its size and 408 2712 nn35248 * the proper link map ID. 409 2712 nn35248 */ 410 2712 nn35248 static size_t 411 6830 edp lx_elf_props32(struct ps_prochandle *php, uint32_t addr, psaddr_t *data_addr) 412 2712 nn35248 { 413 2712 nn35248 Elf32_Ehdr ehdr; 414 2712 nn35248 Elf32_Phdr *phdrs, *ph; 415 2712 nn35248 int i; 416 6473 edp uint32_t min = (uint32_t)-1; 417 6473 edp uint32_t max = 0; 418 2712 nn35248 size_t sz; 419 2712 nn35248 420 2712 nn35248 if (ps_pread(php, addr, &ehdr, sizeof (ehdr)) != PS_OK) { 421 6473 edp ps_plog("lx_elf_props: Couldn't read ELF header at 0x%p", 422 6473 edp addr); 423 2712 nn35248 return (0); 424 2712 nn35248 } 425 2712 nn35248 426 2712 nn35248 if ((phdrs = malloc(ehdr.e_phnum * ehdr.e_phentsize)) == NULL) 427 2712 nn35248 return (0); 428 2712 nn35248 429 2712 nn35248 if (ps_pread(php, addr + ehdr.e_phoff, phdrs, ehdr.e_phnum * 430 2712 nn35248 ehdr.e_phentsize) != PS_OK) { 431 6473 edp ps_plog("lx_elf_props: Couldn't read program headers at 0x%p", 432 2712 nn35248 addr + ehdr.e_phoff); 433 2712 nn35248 return (0); 434 2712 nn35248 } 435 2712 nn35248 436 2712 nn35248 for (i = 0, ph = phdrs; i < ehdr.e_phnum; i++, 437 2712 nn35248 /*LINTED */ 438 2712 nn35248 ph = (Elf32_Phdr *)((char *)ph + ehdr.e_phentsize)) { 439 2712 nn35248 440 2712 nn35248 if (ph->p_type != PT_LOAD) 441 2712 nn35248 continue; 442 2712 nn35248 443 2712 nn35248 if ((ph->p_flags & (PF_W | PF_R)) == (PF_W | PF_R)) { 444 2712 nn35248 *data_addr = ph->p_vaddr; 445 2712 nn35248 if (ehdr.e_type == ET_DYN) 446 2712 nn35248 *data_addr += addr; 447 2712 nn35248 if (*data_addr & (ph->p_align - 1)) 448 2712 nn35248 *data_addr = *data_addr & (~(ph->p_align -1)); 449 2712 nn35248 } 450 2712 nn35248 451 2712 nn35248 if (ph->p_vaddr < min) 452 2712 nn35248 min = ph->p_vaddr; 453 2712 nn35248 454 2712 nn35248 if (ph->p_vaddr > max) { 455 2712 nn35248 max = ph->p_vaddr; 456 2712 nn35248 sz = ph->p_memsz + max - min; 457 2712 nn35248 if (sz & (ph->p_align - 1)) 458 2712 nn35248 sz = (sz & (~(ph->p_align - 1))) + ph->p_align; 459 2712 nn35248 } 460 2712 nn35248 } 461 2712 nn35248 462 2712 nn35248 free(phdrs); 463 2712 nn35248 return (sz); 464 2712 nn35248 } 465 2712 nn35248 466 2712 nn35248 static int 467 6830 edp lx_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data) 468 2712 nn35248 { 469 6830 edp lx_rd_t *lx_rd = (lx_rd_t *)rhd; 470 6830 edp struct ps_prochandle *php = lx_rd->lr_php; 471 6830 edp lx_r_debug_t r_debug; 472 6830 edp lx_link_map_t map; 473 6473 edp uint32_t p = NULL; 474 2712 nn35248 int rc; 475 2712 nn35248 rd_loadobj_t exec; 476 2712 nn35248 477 2712 nn35248 if ((rc = ps_pread(php, (psaddr_t)lx_rd->lr_rdebug, &r_debug, 478 2712 nn35248 sizeof (r_debug))) != PS_OK) { 479 6830 edp ps_plog("lx_ldb_loadobj_iter: " 480 6830 edp "Couldn't read linux r_debug at 0x%p", lx_rd->lr_rdebug); 481 2712 nn35248 return (rc); 482 2712 nn35248 } 483 2712 nn35248 484 2712 nn35248 p = r_debug.r_map; 485 2712 nn35248 486 2712 nn35248 /* 487 2712 nn35248 * The first item on the link map list is for the executable, but it 488 2712 nn35248 * doesn't give us any useful information about it. We need to 489 2712 nn35248 * synthesize a rd_loadobj_t for the client. 490 2712 nn35248 * 491 2712 nn35248 * Linux doesn't give us the executable name, so we'll get it from 492 2712 nn35248 * the AT_EXECNAME entry instead. 493 2712 nn35248 */ 494 2712 nn35248 if ((rc = ps_pread(php, (psaddr_t)p, &map, sizeof (map))) != PS_OK) { 495 6830 edp ps_plog("lx_ldb_loadobj_iter: " 496 6830 edp "Couldn't read linux link map at 0x%p", p); 497 2712 nn35248 return (rc); 498 2712 nn35248 } 499 2712 nn35248 500 2712 nn35248 bzero(&exec, sizeof (exec)); 501 2712 nn35248 exec.rl_base = lx_rd->lr_exec; 502 2712 nn35248 exec.rl_dynamic = map.lxm_ld; 503 6830 edp exec.rl_nameaddr = lx_ldb_getauxval32(php, AT_SUN_EXECNAME); 504 2712 nn35248 exec.rl_lmident = LM_ID_BASE; 505 2712 nn35248 506 2712 nn35248 exec.rl_bend = exec.rl_base + 507 6830 edp lx_elf_props32(php, lx_rd->lr_exec, &exec.rl_data_base); 508 2712 nn35248 509 2712 nn35248 if ((*cb)(&exec, client_data) == 0) { 510 6830 edp ps_plog("lx_ldb_loadobj_iter: " 511 6830 edp "client callb failed for executable"); 512 2712 nn35248 return (PS_ERR); 513 2712 nn35248 } 514 2712 nn35248 515 2712 nn35248 for (p = map.lxm_next; p != NULL; p = map.lxm_next) { 516 2712 nn35248 rd_loadobj_t obj; 517 2712 nn35248 518 2712 nn35248 if ((rc = ps_pread(php, (psaddr_t)p, &map, sizeof (map))) != 519 2712 nn35248 PS_OK) { 520 6830 edp ps_plog("lx_ldb_loadobj_iter: " 521 6830 edp "Couldn't read lk map at %p", p); 522 2712 nn35248 return (rc); 523 2712 nn35248 } 524 2712 nn35248 525 2712 nn35248 /* 526 2712 nn35248 * The linux link map has less information than the Solaris one. 527 2712 nn35248 * We need to go fetch the missing information from the ELF 528 2712 nn35248 * headers. 529 2712 nn35248 */ 530 2712 nn35248 531 2712 nn35248 obj.rl_nameaddr = (psaddr_t)map.lxm_name; 532 2712 nn35248 obj.rl_base = map.lxm_addr; 533 2712 nn35248 obj.rl_refnameaddr = (psaddr_t)map.lxm_name; 534 2712 nn35248 obj.rl_plt_base = NULL; 535 2712 nn35248 obj.rl_plt_size = 0; 536 2712 nn35248 obj.rl_lmident = LM_ID_BASE; 537 2712 nn35248 538 2712 nn35248 /* 539 2712 nn35248 * Ugh - we have to walk the ELF stuff, find the PT_LOAD 540 2712 nn35248 * sections, and calculate the end of the file's mappings 541 2712 nn35248 * ourselves. 542 2712 nn35248 */ 543 2712 nn35248 544 2712 nn35248 obj.rl_bend = map.lxm_addr + 545 6830 edp lx_elf_props32(php, map.lxm_addr, &obj.rl_data_base); 546 2712 nn35248 obj.rl_padstart = obj.rl_base; 547 2712 nn35248 obj.rl_padend = obj.rl_bend; 548 2712 nn35248 obj.rl_dynamic = map.lxm_ld; 549 2712 nn35248 obj.rl_tlsmodid = 0; 550 2712 nn35248 551 6830 edp ps_plog("lx_ldb_loadobj_iter: 0x%p to 0x%p", 552 6473 edp obj.rl_base, obj.rl_bend); 553 2712 nn35248 554 2712 nn35248 if ((*cb)(&obj, client_data) == 0) { 555 6830 edp ps_plog("lx_ldb_loadobj_iter: " 556 6830 edp "Client callback failed on %s", map.lxm_name); 557 2712 nn35248 return (rc); 558 2712 nn35248 } 559 2712 nn35248 } 560 2712 nn35248 return (RD_OK); 561 2712 nn35248 } 562 6830 edp 563 6830 edp /* 564 6830 edp * Librtld_db plugin linkage struct. 565 6830 edp * 566 6830 edp * When we get loaded by librtld_db, it will look for the symbol below 567 6830 edp * to find our plugin entry points. 568 6830 edp */ 569 6830 edp rd_helper_ops_t RTLD_DB_BRAND_OPS = { 570 6830 edp LM_ID_BRAND, 571 6830 edp lx_ldb_init32, 572 6830 edp lx_ldb_fini32, 573 6830 edp lx_ldb_loadobj_iter32, 574 6830 edp lx_ldb_get_dyns32 575 6830 edp }; 576