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