ltrace-elf.c revision ffd5aab0bddbbb7c650c2f5c12a48e0298f82516
1#include "config.h" 2 3#include <endian.h> 4#include <errno.h> 5#include <error.h> 6#include <fcntl.h> 7#include <gelf.h> 8#include <inttypes.h> 9#include <stdint.h> 10#include <stdlib.h> 11#include <string.h> 12#include <unistd.h> 13#include <assert.h> 14 15#include "common.h" 16#include "proc.h" 17#include "library.h" 18 19#ifdef PLT_REINITALISATION_BP 20extern char *PLTs_initialized_by_here; 21#endif 22 23#ifndef DT_PPC_GOT 24# define DT_PPC_GOT (DT_LOPROC + 0) 25#endif 26 27 28#ifndef ARCH_HAVE_LTELF_DATA 29int 30arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn) 31{ 32 return 0; 33} 34 35int 36arch_elf_init(struct ltelf *lte) 37{ 38 return 0; 39} 40#endif 41 42Elf_Data * 43elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr) 44{ 45 Elf_Data *data = elf_getdata(scn, NULL); 46 if (data == NULL || elf_getdata(scn, data) != NULL 47 || data->d_off || data->d_size != shdr->sh_size) 48 return NULL; 49 return data; 50} 51 52static int 53elf_get_section_if(struct ltelf *lte, Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr, 54 int (*predicate)(Elf_Scn *, GElf_Shdr *, void *data), 55 void *data) 56{ 57 int i; 58 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 59 Elf_Scn *scn; 60 GElf_Shdr shdr; 61 62 scn = elf_getscn(lte->elf, i); 63 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { 64 debug(1, "Couldn't read section or header."); 65 return -1; 66 } 67 if (predicate(scn, &shdr, data)) { 68 *tgt_sec = scn; 69 *tgt_shdr = shdr; 70 return 0; 71 } 72 } 73 return -1; 74 75} 76 77static int 78inside_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) 79{ 80 GElf_Addr addr = *(GElf_Addr *)data; 81 return addr >= shdr->sh_addr 82 && addr < shdr->sh_addr + shdr->sh_size; 83} 84 85int 86elf_get_section_covering(struct ltelf *lte, GElf_Addr addr, 87 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 88{ 89 return elf_get_section_if(lte, tgt_sec, tgt_shdr, 90 &inside_p, &addr); 91} 92 93static int 94type_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) 95{ 96 GElf_Word type = *(GElf_Word *)data; 97 return shdr->sh_type == type; 98} 99 100int 101elf_get_section_type(struct ltelf *lte, GElf_Word type, 102 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 103{ 104 return elf_get_section_if(lte, tgt_sec, tgt_shdr, 105 &type_p, &type); 106} 107 108static int 109need_data(Elf_Data *data, size_t offset, size_t size) 110{ 111 assert(data != NULL); 112 if (data->d_size < size || offset > data->d_size - size) { 113 debug(1, "Not enough data to read %zd-byte value" 114 " at offset %zd.", size, offset); 115 return -1; 116 } 117 return 0; 118} 119 120#define DEF_READER(NAME, SIZE) \ 121 int \ 122 NAME(Elf_Data *data, size_t offset, uint##SIZE##_t *retp) \ 123 { \ 124 if (!need_data(data, offset, SIZE / 8) < 0) \ 125 return -1; \ 126 \ 127 union { \ 128 uint##SIZE##_t dst; \ 129 char buf[0]; \ 130 } u; \ 131 memcpy(u.buf, data->d_buf + offset, sizeof(u.dst)); \ 132 *retp = u.dst; \ 133 return 0; \ 134 } 135 136DEF_READER(elf_read_u16, 16) 137DEF_READER(elf_read_u32, 32) 138DEF_READER(elf_read_u64, 64) 139 140#undef DEF_READER 141 142int 143open_elf(struct ltelf *lte, const char *filename) 144{ 145 lte->fd = open(filename, O_RDONLY); 146 if (lte->fd == -1) 147 return 1; 148 149 elf_version(EV_CURRENT); 150 151#ifdef HAVE_ELF_C_READ_MMAP 152 lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); 153#else 154 lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); 155#endif 156 157 if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) 158 error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); 159 160 if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) 161 error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", 162 filename); 163 164 if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) 165 error(EXIT_FAILURE, 0, 166 "\"%s\" is not an ELF executable nor shared library", 167 filename); 168 169 if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS 170 || lte->ehdr.e_machine != LT_ELF_MACHINE) 171#ifdef LT_ELF_MACHINE2 172 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 173 || lte->ehdr.e_machine != LT_ELF_MACHINE2) 174#endif 175#ifdef LT_ELF_MACHINE3 176 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 177 || lte->ehdr.e_machine != LT_ELF_MACHINE3) 178#endif 179 ) 180 error(EXIT_FAILURE, 0, 181 "\"%s\" is ELF from incompatible architecture", filename); 182 183 return 0; 184} 185 186static int 187do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias) 188{ 189 int i; 190 GElf_Addr relplt_addr = 0; 191 GElf_Addr soname_offset = 0; 192 193 debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); 194 debug(1, "Reading ELF from %s...", filename); 195 196 if (open_elf(lte, filename) < 0) 197 return -1; 198 199 /* Find out the base address. */ 200 { 201 GElf_Phdr phdr; 202 for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) { 203 if (phdr.p_type == PT_LOAD) { 204 lte->base_addr = phdr.p_vaddr - bias; 205 fprintf(stderr, 206 " + vaddr=%#lx, bias=%#lx, base=%#lx\n", 207 phdr.p_vaddr, bias, lte->base_addr); 208 break; 209 } 210 } 211 } 212 213 if (lte->base_addr == 0) { 214 fprintf(stderr, "Couldn't determine base address of %s\n", 215 filename); 216 return -1; 217 } 218 219 lte->bias = bias; 220 lte->entry_addr = lte->ehdr.e_entry + lte->bias; 221 222 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 223 Elf_Scn *scn; 224 GElf_Shdr shdr; 225 const char *name; 226 227 scn = elf_getscn(lte->elf, i); 228 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 229 error(EXIT_FAILURE, 0, 230 "Couldn't get section header from \"%s\"", 231 filename); 232 233 name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); 234 if (name == NULL) 235 error(EXIT_FAILURE, 0, 236 "Couldn't get section header from \"%s\"", 237 filename); 238 239 if (shdr.sh_type == SHT_SYMTAB) { 240 Elf_Data *data; 241 242 lte->symtab = elf_getdata(scn, NULL); 243 lte->symtab_count = shdr.sh_size / shdr.sh_entsize; 244 if ((lte->symtab == NULL 245 || elf_getdata(scn, lte->symtab) != NULL) 246 && opt_x != NULL) 247 error(EXIT_FAILURE, 0, 248 "Couldn't get .symtab data from \"%s\"", 249 filename); 250 251 scn = elf_getscn(lte->elf, shdr.sh_link); 252 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 253 error(EXIT_FAILURE, 0, 254 "Couldn't get section header from \"%s\"", 255 filename); 256 257 data = elf_getdata(scn, NULL); 258 if (data == NULL || elf_getdata(scn, data) != NULL 259 || shdr.sh_size != data->d_size || data->d_off) 260 error(EXIT_FAILURE, 0, 261 "Couldn't get .strtab data from \"%s\"", 262 filename); 263 264 lte->strtab = data->d_buf; 265 } else if (shdr.sh_type == SHT_DYNSYM) { 266 Elf_Data *data; 267 268 lte->dynsym = elf_getdata(scn, NULL); 269 lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; 270 if (lte->dynsym == NULL 271 || elf_getdata(scn, lte->dynsym) != NULL) 272 error(EXIT_FAILURE, 0, 273 "Couldn't get .dynsym data from \"%s\"", 274 filename); 275 276 scn = elf_getscn(lte->elf, shdr.sh_link); 277 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 278 error(EXIT_FAILURE, 0, 279 "Couldn't get section header from \"%s\"", 280 filename); 281 282 data = elf_getdata(scn, NULL); 283 if (data == NULL || elf_getdata(scn, data) != NULL 284 || shdr.sh_size != data->d_size || data->d_off) 285 error(EXIT_FAILURE, 0, 286 "Couldn't get .dynstr data from \"%s\"", 287 filename); 288 289 lte->dynstr = data->d_buf; 290 } else if (shdr.sh_type == SHT_DYNAMIC) { 291 Elf_Data *data; 292 size_t j; 293 294 lte->dyn_addr = shdr.sh_addr; 295 fprintf(stderr, "dyn_addr = %#lx\n", lte->dyn_addr); 296 extern void *dyn_addr; 297 dyn_addr = (void *)lte->dyn_addr; 298 lte->dyn_sz = shdr.sh_size; 299 300 data = elf_getdata(scn, NULL); 301 if (data == NULL || elf_getdata(scn, data) != NULL) 302 error(EXIT_FAILURE, 0, 303 "Couldn't get .dynamic data from \"%s\"", 304 filename); 305 306 for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { 307 GElf_Dyn dyn; 308 309 if (gelf_getdyn(data, j, &dyn) == NULL) 310 error(EXIT_FAILURE, 0, 311 "Couldn't get .dynamic data from \"%s\"", 312 filename); 313 if (dyn.d_tag == DT_JMPREL) 314 relplt_addr = dyn.d_un.d_ptr; 315 else if (dyn.d_tag == DT_PLTRELSZ) 316 lte->relplt_size = dyn.d_un.d_val; 317 else if (dyn.d_tag == DT_SONAME) 318 soname_offset = dyn.d_un.d_val; 319 else if (arch_elf_dynamic_tag(lte, dyn) < 0) 320 goto backend_fail; 321 } 322 } else if (shdr.sh_type == SHT_PROGBITS 323 || shdr.sh_type == SHT_NOBITS) { 324 if (strcmp(name, ".plt") == 0) { 325 lte->plt_addr = shdr.sh_addr; 326 lte->plt_size = shdr.sh_size; 327 lte->plt_data = elf_loaddata(scn, &shdr); 328 if (lte->plt_data == NULL) 329 fprintf(stderr, 330 "Can't load .plt data\n"); 331 if (shdr.sh_flags & SHF_EXECINSTR) 332 lte->lte_flags |= LTE_PLT_EXECUTABLE; 333 } 334#ifdef ARCH_SUPPORTS_OPD 335 else if (strcmp(name, ".opd") == 0) { 336 lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; 337 lte->opd_size = shdr.sh_size; 338 lte->opd = elf_rawdata(scn, NULL); 339 } 340#endif 341 } 342 } 343 344 if (lte->dynsym == NULL || lte->dynstr == NULL) 345 error(EXIT_FAILURE, 0, 346 "Couldn't find .dynsym or .dynstr in \"%s\"", filename); 347 348 if (arch_elf_init(lte) < 0) { 349 backend_fail: 350 fprintf(stderr, "Backend initialization failed.\n"); 351 return -1; 352 } 353 354 if (!relplt_addr || !lte->plt_addr) { 355 debug(1, "%s has no PLT relocations", filename); 356 lte->relplt = NULL; 357 lte->relplt_count = 0; 358 } else if (lte->relplt_size == 0) { 359 debug(1, "%s has unknown PLT size", filename); 360 lte->relplt = NULL; 361 lte->relplt_count = 0; 362 } else { 363 364 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 365 Elf_Scn *scn; 366 GElf_Shdr shdr; 367 368 scn = elf_getscn(lte->elf, i); 369 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 370 error(EXIT_FAILURE, 0, 371 "Couldn't get section header from \"%s\"", 372 filename); 373 if (shdr.sh_addr == relplt_addr 374 && shdr.sh_size == lte->relplt_size) { 375 lte->relplt = elf_getdata(scn, NULL); 376 lte->relplt_count = 377 shdr.sh_size / shdr.sh_entsize; 378 if (lte->relplt == NULL 379 || elf_getdata(scn, lte->relplt) != NULL) 380 error(EXIT_FAILURE, 0, 381 "Couldn't get .rel*.plt data from \"%s\"", 382 filename); 383 break; 384 } 385 } 386 387 if (i == lte->ehdr.e_shnum) 388 error(EXIT_FAILURE, 0, 389 "Couldn't find .rel*.plt section in \"%s\"", 390 filename); 391 392 debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); 393 } 394 395 if (soname_offset != 0) 396 lte->soname = lte->dynstr + soname_offset; 397 398 return 0; 399} 400 401/* XXX temporarily non-static */ 402void 403do_close_elf(struct ltelf *lte) { 404 debug(DEBUG_FUNCTION, "do_close_elf()"); 405 elf_end(lte->elf); 406 close(lte->fd); 407} 408 409struct library * 410ltelf_read_library(struct Process *proc, const char *filename, GElf_Addr bias) 411{ 412 // XXX we leak LTE contents 413 struct ltelf lte = {}; 414 if (do_init_elf(<e, filename, bias) < 0) 415 return NULL; 416 proc->e_machine = lte.ehdr.e_machine; 417 418 struct library *lib = malloc(sizeof(*lib)); 419 char *soname = NULL; 420 if (lib == NULL) { 421 fail: 422 free(soname); 423 library_destroy(lib); 424 free(lib); 425 lib = NULL; 426 goto done; 427 } 428 429 if (lte.soname != NULL) { 430 soname = strdup(lte.soname); 431 if (soname == NULL) 432 goto fail; 433 } 434 435 target_address_t entry = (target_address_t)lte.entry_addr; 436 if (arch_translate_address(proc, entry + lte.bias, &entry) < 0) 437 goto fail; 438 439 library_init(lib, soname, soname != NULL); 440 lib->base = (target_address_t)lte.base_addr; 441 lib->entry = entry; 442 443 size_t i; 444 for (i = 0; i < lte.relplt_count; ++i) { 445 GElf_Rel rel; 446 GElf_Rela rela; 447 GElf_Sym sym; 448 void *ret; 449 450 if (lte.relplt->d_type == ELF_T_REL) { 451 ret = gelf_getrel(lte.relplt, i, &rel); 452 rela.r_offset = rel.r_offset; 453 rela.r_info = rel.r_info; 454 rela.r_addend = 0; 455 } else { 456 ret = gelf_getrela(lte.relplt, i, &rela); 457 } 458 459 if (ret == NULL 460 || ELF64_R_SYM(rela.r_info) >= lte.dynsym_count 461 || gelf_getsym(lte.dynsym, ELF64_R_SYM(rela.r_info), 462 &sym) == NULL) 463 error(EXIT_FAILURE, 0, 464 "Couldn't get relocation from \"%s\"", 465 filename); 466 467 /* We will destroy the ELF object at the end of the 468 * scope. We need to copy the name for our purposes. 469 * XXX consider just keeping the ELF around. */ 470 char *name = strdup(lte.dynstr + sym.st_name); 471 if (name == NULL) { 472 fail2: 473 free(name); 474 goto fail; 475 } 476 477 enum toplt pltt = PLTS_ARE_EXECUTABLE(<e) 478 ? LS_TOPLT_EXEC : LS_TOPLT_POINT; 479 GElf_Addr addr = arch_plt_sym_val(<e, i, &rela); 480 481 struct library_symbol *libsym = malloc(sizeof(*libsym)); 482 if (libsym == NULL) 483 goto fail2; 484 485 target_address_t taddr = (target_address_t)(addr + lte.bias); 486 if (libsym == NULL 487 || arch_translate_address(proc, taddr, &taddr) < 0) { 488 free(libsym); 489 goto fail2; 490 } 491 492 library_symbol_init(libsym, lib, taddr, name, 1, pltt); 493 library_add_symbol(lib, libsym); 494 } 495 496done: 497 do_close_elf(<e); 498 return lib; 499} 500 501struct library * 502ltelf_read_main_binary(struct Process *proc, const char *path) 503{ 504 fprintf(stderr, "ltelf_read_main_binary %d %s\n", proc->pid, path); 505 char *fname = pid2name(proc->pid); 506 struct library *lib = ltelf_read_library(proc, fname, 0); 507 if (lib != NULL) 508 library_set_name(lib, path, 0); 509 return lib; 510} 511