ltrace-elf.c revision 5e463e029c5b6bb4eb5176ab62ee97d5399524fe
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 if (data->d_buf == NULL) /* NODATA section */ { \ 171 *retp = 0; \ 172 return 0; \ 173 } \ 174 \ 175 union { \ 176 uint##SIZE##_t dst; \ 177 char buf[0]; \ 178 } u; \ 179 memcpy(u.buf, data->d_buf + offset, sizeof(u.dst)); \ 180 *retp = u.dst; \ 181 return 0; \ 182 } 183 184DEF_READER(elf_read_u16, 16) 185DEF_READER(elf_read_u32, 32) 186DEF_READER(elf_read_u64, 64) 187 188#undef DEF_READER 189 190int 191open_elf(struct ltelf *lte, const char *filename) 192{ 193 lte->fd = open(filename, O_RDONLY); 194 if (lte->fd == -1) 195 return 1; 196 197 elf_version(EV_CURRENT); 198 199#ifdef HAVE_ELF_C_READ_MMAP 200 lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); 201#else 202 lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); 203#endif 204 205 if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) 206 error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); 207 208 if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) 209 error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", 210 filename); 211 212 if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) 213 error(EXIT_FAILURE, 0, 214 "\"%s\" is not an ELF executable nor shared library", 215 filename); 216 217 if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS 218 || lte->ehdr.e_machine != LT_ELF_MACHINE) 219#ifdef LT_ELF_MACHINE2 220 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 221 || lte->ehdr.e_machine != LT_ELF_MACHINE2) 222#endif 223#ifdef LT_ELF_MACHINE3 224 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 225 || lte->ehdr.e_machine != LT_ELF_MACHINE3) 226#endif 227 ) 228 error(EXIT_FAILURE, 0, 229 "\"%s\" is ELF from incompatible architecture", filename); 230 231 return 0; 232} 233 234static int 235do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias) 236{ 237 int i; 238 GElf_Addr relplt_addr = 0; 239 GElf_Addr soname_offset = 0; 240 241 debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); 242 debug(1, "Reading ELF from %s...", filename); 243 244 if (open_elf(lte, filename) < 0) 245 return -1; 246 247 /* Find out the base address. */ 248 { 249 GElf_Phdr phdr; 250 for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) { 251 if (phdr.p_type == PT_LOAD) { 252 lte->base_addr = phdr.p_vaddr - bias; 253 fprintf(stderr, 254 " + vaddr=%#lx, bias=%#lx, base=%#lx\n", 255 phdr.p_vaddr, bias, lte->base_addr); 256 break; 257 } 258 } 259 } 260 261 if (lte->base_addr == 0) { 262 fprintf(stderr, "Couldn't determine base address of %s\n", 263 filename); 264 return -1; 265 } 266 267 lte->bias = bias; 268 lte->entry_addr = lte->ehdr.e_entry + lte->bias; 269 270 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 271 Elf_Scn *scn; 272 GElf_Shdr shdr; 273 const char *name; 274 275 scn = elf_getscn(lte->elf, i); 276 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 277 error(EXIT_FAILURE, 0, 278 "Couldn't get section header from \"%s\"", 279 filename); 280 281 name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); 282 if (name == NULL) 283 error(EXIT_FAILURE, 0, 284 "Couldn't get section header from \"%s\"", 285 filename); 286 287 if (shdr.sh_type == SHT_SYMTAB) { 288 Elf_Data *data; 289 290 lte->symtab = elf_getdata(scn, NULL); 291 lte->symtab_count = shdr.sh_size / shdr.sh_entsize; 292 if ((lte->symtab == NULL 293 || elf_getdata(scn, lte->symtab) != NULL) 294 && opt_x != NULL) 295 error(EXIT_FAILURE, 0, 296 "Couldn't get .symtab data from \"%s\"", 297 filename); 298 299 scn = elf_getscn(lte->elf, shdr.sh_link); 300 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 301 error(EXIT_FAILURE, 0, 302 "Couldn't get section header from \"%s\"", 303 filename); 304 305 data = elf_getdata(scn, NULL); 306 if (data == NULL || elf_getdata(scn, data) != NULL 307 || shdr.sh_size != data->d_size || data->d_off) 308 error(EXIT_FAILURE, 0, 309 "Couldn't get .strtab data from \"%s\"", 310 filename); 311 312 lte->strtab = data->d_buf; 313 } else if (shdr.sh_type == SHT_DYNSYM) { 314 Elf_Data *data; 315 316 lte->dynsym = elf_getdata(scn, NULL); 317 lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; 318 if (lte->dynsym == NULL 319 || elf_getdata(scn, lte->dynsym) != NULL) 320 error(EXIT_FAILURE, 0, 321 "Couldn't get .dynsym data from \"%s\"", 322 filename); 323 324 scn = elf_getscn(lte->elf, shdr.sh_link); 325 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 326 error(EXIT_FAILURE, 0, 327 "Couldn't get section header from \"%s\"", 328 filename); 329 330 data = elf_getdata(scn, NULL); 331 if (data == NULL || elf_getdata(scn, data) != NULL 332 || shdr.sh_size != data->d_size || data->d_off) 333 error(EXIT_FAILURE, 0, 334 "Couldn't get .dynstr data from \"%s\"", 335 filename); 336 337 lte->dynstr = data->d_buf; 338 } else if (shdr.sh_type == SHT_DYNAMIC) { 339 Elf_Data *data; 340 size_t j; 341 342 lte->dyn_addr = shdr.sh_addr; 343 fprintf(stderr, "dyn_addr = %#lx\n", lte->dyn_addr); 344 extern void *dyn_addr; 345 dyn_addr = (void *)lte->dyn_addr; 346 lte->dyn_sz = shdr.sh_size; 347 348 data = elf_getdata(scn, NULL); 349 if (data == NULL || elf_getdata(scn, data) != NULL) 350 error(EXIT_FAILURE, 0, 351 "Couldn't get .dynamic data from \"%s\"", 352 filename); 353 354 for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { 355 GElf_Dyn dyn; 356 357 if (gelf_getdyn(data, j, &dyn) == NULL) 358 error(EXIT_FAILURE, 0, 359 "Couldn't get .dynamic data from \"%s\"", 360 filename); 361 if (dyn.d_tag == DT_JMPREL) 362 relplt_addr = dyn.d_un.d_ptr; 363 else if (dyn.d_tag == DT_PLTRELSZ) 364 lte->relplt_size = dyn.d_un.d_val; 365 else if (dyn.d_tag == DT_SONAME) 366 soname_offset = dyn.d_un.d_val; 367 } 368 } else if (shdr.sh_type == SHT_PROGBITS 369 || shdr.sh_type == SHT_NOBITS) { 370 if (strcmp(name, ".plt") == 0) { 371 lte->plt_addr = shdr.sh_addr; 372 lte->plt_size = shdr.sh_size; 373 lte->plt_data = elf_loaddata(scn, &shdr); 374 if (lte->plt_data == NULL) 375 fprintf(stderr, 376 "Can't load .plt data\n"); 377 if (shdr.sh_flags & SHF_EXECINSTR) 378 lte->lte_flags |= LTE_PLT_EXECUTABLE; 379 } 380#ifdef ARCH_SUPPORTS_OPD 381 else if (strcmp(name, ".opd") == 0) { 382 lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; 383 lte->opd_size = shdr.sh_size; 384 lte->opd = elf_rawdata(scn, NULL); 385 } 386#endif 387 } 388 } 389 390 if (lte->dynsym == NULL || lte->dynstr == NULL) 391 error(EXIT_FAILURE, 0, 392 "Couldn't find .dynsym or .dynstr in \"%s\"", filename); 393 394 if (!relplt_addr || !lte->plt_addr) { 395 debug(1, "%s has no PLT relocations", filename); 396 lte->relplt = NULL; 397 lte->relplt_count = 0; 398 } else if (lte->relplt_size == 0) { 399 debug(1, "%s has unknown PLT size", filename); 400 lte->relplt = NULL; 401 lte->relplt_count = 0; 402 } else { 403 404 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 405 Elf_Scn *scn; 406 GElf_Shdr shdr; 407 408 scn = elf_getscn(lte->elf, i); 409 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 410 error(EXIT_FAILURE, 0, 411 "Couldn't get section header from \"%s\"", 412 filename); 413 if (shdr.sh_addr == relplt_addr 414 && shdr.sh_size == lte->relplt_size) { 415 lte->relplt = elf_getdata(scn, NULL); 416 lte->relplt_count = 417 shdr.sh_size / shdr.sh_entsize; 418 if (lte->relplt == NULL 419 || elf_getdata(scn, lte->relplt) != NULL) 420 error(EXIT_FAILURE, 0, 421 "Couldn't get .rel*.plt data from \"%s\"", 422 filename); 423 break; 424 } 425 } 426 427 if (i == lte->ehdr.e_shnum) 428 error(EXIT_FAILURE, 0, 429 "Couldn't find .rel*.plt section in \"%s\"", 430 filename); 431 432 debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); 433 } 434 435 if (soname_offset != 0) 436 lte->soname = lte->dynstr + soname_offset; 437 438 if (arch_elf_init(lte) < 0) { 439 fprintf(stderr, "Backend initialization failed.\n"); 440 return -1; 441 } 442 443 return 0; 444} 445 446/* XXX temporarily non-static */ 447void 448do_close_elf(struct ltelf *lte) { 449 debug(DEBUG_FUNCTION, "do_close_elf()"); 450 arch_elf_destroy(lte); 451 elf_end(lte->elf); 452 close(lte->fd); 453} 454 455struct library * 456ltelf_read_library(struct Process *proc, const char *filename, GElf_Addr bias) 457{ 458 // XXX we leak LTE contents 459 struct ltelf lte = {}; 460 if (do_init_elf(<e, filename, bias) < 0) 461 return NULL; 462 proc->e_machine = lte.ehdr.e_machine; 463 464 struct library *lib = malloc(sizeof(*lib)); 465 char *libname = NULL; 466 if (lib == NULL) { 467 fail: 468 free(libname); 469 library_destroy(lib); 470 free(lib); 471 lib = NULL; 472 goto done; 473 } 474 475 if (lte.soname != NULL) 476 libname = strdup(lte.soname); 477 else 478 libname = strdup(filename); 479 if (libname == NULL) 480 goto fail; 481 482 target_address_t entry = (target_address_t)lte.entry_addr; 483 if (arch_translate_address(proc, entry + lte.bias, &entry) < 0) 484 goto fail; 485 486 library_init(lib, libname, 1); 487 lib->base = (target_address_t)lte.base_addr; 488 lib->entry = entry; 489 490 size_t i; 491 for (i = 0; i < lte.relplt_count; ++i) { 492 GElf_Rel rel; 493 GElf_Rela rela; 494 GElf_Sym sym; 495 void *ret; 496 497 if (lte.relplt->d_type == ELF_T_REL) { 498 ret = gelf_getrel(lte.relplt, i, &rel); 499 rela.r_offset = rel.r_offset; 500 rela.r_info = rel.r_info; 501 rela.r_addend = 0; 502 } else { 503 ret = gelf_getrela(lte.relplt, i, &rela); 504 } 505 506 if (ret == NULL 507 || ELF64_R_SYM(rela.r_info) >= lte.dynsym_count 508 || gelf_getsym(lte.dynsym, ELF64_R_SYM(rela.r_info), 509 &sym) == NULL) 510 error(EXIT_FAILURE, 0, 511 "Couldn't get relocation from \"%s\"", 512 filename); 513 514 char const *name = lte.dynstr + sym.st_name; 515 struct library_symbol *libsym; 516 switch (arch_elf_add_plt_entry(proc, <e, name, 517 &rela, i, &libsym)) { 518 case plt_default: 519 if (default_elf_add_plt_entry(proc, <e, name, 520 &rela, i, &libsym) < 0) 521 case plt_fail: 522 goto fail; 523 case plt_ok: 524 if (libsym != NULL) 525 library_add_symbol(lib, libsym); 526 } 527 } 528 529done: 530 do_close_elf(<e); 531 return lib; 532} 533 534struct library * 535ltelf_read_main_binary(struct Process *proc, const char *path) 536{ 537 fprintf(stderr, "ltelf_read_main_binary %d %s\n", proc->pid, path); 538 char *fname = pid2name(proc->pid); 539 struct library *lib = ltelf_read_library(proc, fname, 0); 540 if (lib != NULL) 541 library_set_name(lib, path, 0); 542 return lib; 543} 544