ltrace-elf.c revision b88fd6e8e3b03e4341dae540378bc7740ec2d2e5
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 Elf_Data *plt_data = NULL; 186 GElf_Addr ppcgot = 0; 187 188 /* Find out the bias. For DSOs, this will be just BASE, 189 * unless the DSO is pre-linked. For ET_EXEC files, this will 190 * turn out to be 0. */ 191 { 192 GElf_Phdr phdr; 193 for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) { 194 if (phdr.p_type == PT_LOAD) { 195 if (base == 0) 196 base = phdr.p_vaddr; 197 lte->base_addr = base; 198 lte->bias = lte->base_addr - phdr.p_vaddr; 199 fprintf(stderr, 200 " + vaddr=%#lx, base=%#lx, bias=%#lx\n", 201 lte->base_addr, base, lte->bias); 202 break; 203 } 204 } 205 } 206 207 lte->entry_addr = lte->ehdr.e_entry + lte->bias; 208 209 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 210 Elf_Scn *scn; 211 GElf_Shdr shdr; 212 const char *name; 213 214 scn = elf_getscn(lte->elf, i); 215 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 216 error(EXIT_FAILURE, 0, 217 "Couldn't get section header from \"%s\"", 218 filename); 219 220 name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); 221 if (name == NULL) 222 error(EXIT_FAILURE, 0, 223 "Couldn't get section header from \"%s\"", 224 filename); 225 226 if (shdr.sh_type == SHT_SYMTAB) { 227 Elf_Data *data; 228 229 lte->symtab = elf_getdata(scn, NULL); 230 lte->symtab_count = shdr.sh_size / shdr.sh_entsize; 231 if ((lte->symtab == NULL 232 || elf_getdata(scn, lte->symtab) != NULL) 233 && opt_x != NULL) 234 error(EXIT_FAILURE, 0, 235 "Couldn't get .symtab data from \"%s\"", 236 filename); 237 238 scn = elf_getscn(lte->elf, shdr.sh_link); 239 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 240 error(EXIT_FAILURE, 0, 241 "Couldn't get section header from \"%s\"", 242 filename); 243 244 data = elf_getdata(scn, NULL); 245 if (data == NULL || elf_getdata(scn, data) != NULL 246 || shdr.sh_size != data->d_size || data->d_off) 247 error(EXIT_FAILURE, 0, 248 "Couldn't get .strtab data from \"%s\"", 249 filename); 250 251 lte->strtab = data->d_buf; 252 } else if (shdr.sh_type == SHT_DYNSYM) { 253 Elf_Data *data; 254 255 lte->dynsym = elf_getdata(scn, NULL); 256 lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; 257 if (lte->dynsym == NULL 258 || elf_getdata(scn, lte->dynsym) != NULL) 259 error(EXIT_FAILURE, 0, 260 "Couldn't get .dynsym data from \"%s\"", 261 filename); 262 263 scn = elf_getscn(lte->elf, shdr.sh_link); 264 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 265 error(EXIT_FAILURE, 0, 266 "Couldn't get section header from \"%s\"", 267 filename); 268 269 data = elf_getdata(scn, NULL); 270 if (data == NULL || elf_getdata(scn, data) != NULL 271 || shdr.sh_size != data->d_size || data->d_off) 272 error(EXIT_FAILURE, 0, 273 "Couldn't get .dynstr data from \"%s\"", 274 filename); 275 276 lte->dynstr = data->d_buf; 277 } else if (shdr.sh_type == SHT_DYNAMIC) { 278 Elf_Data *data; 279 size_t j; 280 281 lte->dyn_addr = shdr.sh_addr; 282 fprintf(stderr, "dyn_addr = %#lx\n", lte->dyn_addr); 283 extern void *dyn_addr; 284 dyn_addr = (void *)lte->dyn_addr; 285 lte->dyn_sz = shdr.sh_size; 286 287 data = elf_getdata(scn, NULL); 288 if (data == NULL || elf_getdata(scn, data) != NULL) 289 error(EXIT_FAILURE, 0, 290 "Couldn't get .dynamic data from \"%s\"", 291 filename); 292 293 for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { 294 GElf_Dyn dyn; 295 296 if (gelf_getdyn(data, j, &dyn) == NULL) 297 error(EXIT_FAILURE, 0, 298 "Couldn't get .dynamic data from \"%s\"", 299 filename); 300 if (dyn.d_tag == DT_JMPREL) 301 relplt_addr = dyn.d_un.d_ptr; 302 else if (dyn.d_tag == DT_PLTRELSZ) 303 lte->relplt_size = dyn.d_un.d_val; 304 else if (dyn.d_tag == DT_SONAME) 305 soname_offset = dyn.d_un.d_val; 306 else if (arch_elf_dynamic_tag(lte, dyn) < 0) 307 goto backend_fail; 308 } 309 } else if (shdr.sh_type == SHT_PROGBITS 310 || shdr.sh_type == SHT_NOBITS) { 311 if (strcmp(name, ".plt") == 0) { 312 lte->plt_addr = shdr.sh_addr; 313 lte->plt_size = shdr.sh_size; 314 lte->plt_data = elf_loaddata(scn, &shdr); 315 if (lte->plt_data == NULL) 316 fprintf(stderr, 317 "Can't load .plt data\n"); 318 if (shdr.sh_flags & SHF_EXECINSTR) 319 lte->lte_flags |= LTE_PLT_EXECUTABLE; 320 } 321#ifdef ARCH_SUPPORTS_OPD 322 else if (strcmp(name, ".opd") == 0) { 323 lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; 324 lte->opd_size = shdr.sh_size; 325 lte->opd = elf_rawdata(scn, NULL); 326 } 327#endif 328 } 329 } 330 331 if (lte->dynsym == NULL || lte->dynstr == NULL) 332 error(EXIT_FAILURE, 0, 333 "Couldn't find .dynsym or .dynstr in \"%s\"", filename); 334 335 if (arch_elf_init(lte) < 0) { 336 backend_fail: 337 fprintf(stderr, "Backend initialization failed.\n"); 338 return -1; 339 } 340 341 if (!relplt_addr || !lte->plt_addr) { 342 debug(1, "%s has no PLT relocations", filename); 343 lte->relplt = NULL; 344 lte->relplt_count = 0; 345 } else if (lte->relplt_size == 0) { 346 debug(1, "%s has unknown PLT size", filename); 347 lte->relplt = NULL; 348 lte->relplt_count = 0; 349 } else { 350 351 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 352 Elf_Scn *scn; 353 GElf_Shdr shdr; 354 355 scn = elf_getscn(lte->elf, i); 356 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 357 error(EXIT_FAILURE, 0, 358 "Couldn't get section header from \"%s\"", 359 filename); 360 if (shdr.sh_addr == relplt_addr 361 && shdr.sh_size == lte->relplt_size) { 362 lte->relplt = elf_getdata(scn, NULL); 363 lte->relplt_count = 364 shdr.sh_size / shdr.sh_entsize; 365 if (lte->relplt == NULL 366 || elf_getdata(scn, lte->relplt) != NULL) 367 error(EXIT_FAILURE, 0, 368 "Couldn't get .rel*.plt data from \"%s\"", 369 filename); 370 break; 371 } 372 } 373 374 if (i == lte->ehdr.e_shnum) 375 error(EXIT_FAILURE, 0, 376 "Couldn't find .rel*.plt section in \"%s\"", 377 filename); 378 379 debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); 380 } 381 382 if (soname_offset != 0) 383 lte->soname = lte->dynstr + soname_offset; 384 385 return 0; 386} 387 388/* XXX temporarily non-static */ 389void 390do_close_elf(struct ltelf *lte) { 391 debug(DEBUG_FUNCTION, "do_close_elf()"); 392 elf_end(lte->elf); 393 close(lte->fd); 394} 395 396struct library * 397ltelf_read_library(const char *filename, GElf_Addr base) 398{ 399 // XXX we leak LTE contents 400 struct ltelf lte = {}; 401 if (do_init_elf(<e, filename, base) < 0) 402 return NULL; 403 proc->e_machine = lte.ehdr.e_machine; 404 405 struct library *lib = malloc(sizeof(*lib)); 406 char *soname = NULL; 407 if (lib == NULL) { 408 fail: 409 free(soname); 410 library_destroy(lib); 411 free(lib); 412 lib = NULL; 413 goto done; 414 } 415 416 if (lte.soname != NULL) { 417 soname = strdup(lte.soname); 418 if (soname == NULL) 419 goto fail; 420 } 421 422 library_init(lib, soname, soname != NULL); 423 lib->entry = (target_address_t)lte.entry_addr; 424 lib->base = (target_address_t)lte.base_addr; 425 426 size_t i; 427 for (i = 0; i < lte.relplt_count; ++i) { 428 GElf_Rel rel; 429 GElf_Rela rela; 430 GElf_Sym sym; 431 void *ret; 432 433 if (lte.relplt->d_type == ELF_T_REL) { 434 ret = gelf_getrel(lte.relplt, i, &rel); 435 rela.r_offset = rel.r_offset; 436 rela.r_info = rel.r_info; 437 rela.r_addend = 0; 438 } else { 439 ret = gelf_getrela(lte.relplt, i, &rela); 440 } 441 442 if (ret == NULL 443 || ELF64_R_SYM(rela.r_info) >= lte.dynsym_count 444 || gelf_getsym(lte.dynsym, ELF64_R_SYM(rela.r_info), 445 &sym) == NULL) 446 error(EXIT_FAILURE, 0, 447 "Couldn't get relocation from \"%s\"", 448 filename); 449 450 /* We will destroy the ELF object at the end of the 451 * scope. We need to copy the name for our purposes. 452 * XXX consider just keeping the ELF around. */ 453 char *name = strdup(lte.dynstr + sym.st_name); 454 if (name == NULL) { 455 fail2: 456 free(name); 457 goto fail; 458 } 459 460 enum toplt pltt = PLTS_ARE_EXECUTABLE(<e) 461 ? LS_TOPLT_EXEC : LS_TOPLT_POINT; 462 GElf_Addr addr = arch_plt_sym_val(<e, i, &rela); 463 464 struct library_symbol *libsym = malloc(sizeof(*libsym)); 465 if (libsym == NULL) 466 goto fail2; 467 library_symbol_init(libsym, lib, addr + lte.bias, name, 1, pltt, 468 ELF64_ST_BIND(sym.st_info) == STB_WEAK); 469 library_add_symbol(lib, libsym); 470 } 471 472done: 473 do_close_elf(<e); 474 return lib; 475} 476 477struct library * 478ltelf_read_main_binary(struct Process *proc, const char *path) 479{ 480 fprintf(stderr, "ltelf_read_main_binary %d %s\n", proc->pid, path); 481 char *fname = pid2name(proc->pid); 482 struct library *lib = ltelf_read_library(fname, 0); 483 library_set_name(lib, path, 0); 484 return lib; 485} 486