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