void list_rels(vita_elf_t *ve) { vita_elf_rela_table_t *rtable; for (rtable = ve->rela_tables; rtable; rtable = rtable->next) { printf(" Relocations for section %d: %s\n", rtable->target_ndx, get_scndx_name(ve, rtable->target_ndx)); print_rtable(rtable); } }
int main(int argc, char *argv[]) { vita_elf_t *ve; vita_imports_t **imports; sce_module_info_t *module_info; sce_section_sizes_t section_sizes; void *encoded_modinfo; vita_elf_rela_table_t rtable = {}; int imports_count; int status = EXIT_SUCCESS; if (argc < 3) errx(EXIT_FAILURE,"Usage: vita-elf-create input-elf output-elf [extra.json ...]"); if ((ve = vita_elf_load(argv[1])) == NULL) return EXIT_FAILURE; if (!(imports = load_imports(argc, argv, &imports_count))) return EXIT_FAILURE; if (!vita_elf_lookup_imports(ve, imports, imports_count)) status = EXIT_FAILURE; if (ve->fstubs_ndx) { printf("Function stubs in section %d:\n", ve->fstubs_ndx); print_stubs(ve->fstubs, ve->num_fstubs); } if (ve->vstubs_ndx) { printf("Variable stubs in section %d:\n", ve->vstubs_ndx); print_stubs(ve->vstubs, ve->num_vstubs); } printf("Relocations:\n"); list_rels(ve); printf("Segments:\n"); list_segments(ve); module_info = sce_elf_module_info_create(ve); int total_size = sce_elf_module_info_get_size(module_info, §ion_sizes); int curpos = 0; printf("Total SCE data size: %d / %x\n", total_size, total_size); #define PRINTSEC(name) printf(" .%.*s.%s: %d (%x @ %x)\n", (int)strcspn(#name,"_"), #name, strchr(#name,'_')+1, section_sizes.name, section_sizes.name, curpos+ve->segments[0].vaddr+ve->segments[0].memsz); curpos += section_sizes.name PRINTSEC(sceModuleInfo_rodata); PRINTSEC(sceLib_ent); PRINTSEC(sceExport_rodata); PRINTSEC(sceLib_stubs); PRINTSEC(sceImport_rodata); PRINTSEC(sceFNID_rodata); PRINTSEC(sceFStub_rodata); PRINTSEC(sceVNID_rodata); PRINTSEC(sceVStub_rodata); strncpy(module_info->name, argv[1], sizeof(module_info->name) - 1); encoded_modinfo = sce_elf_module_info_encode( module_info, ve, §ion_sizes, &rtable); printf("Relocations from encoded modinfo:\n"); print_rtable(&rtable); FILE *outfile; Elf *dest; ASSERT(dest = elf_utils_copy_to_file(argv[2], ve->elf, &outfile)); ASSERT(elf_utils_duplicate_shstrtab(dest)); ASSERT(sce_elf_discard_invalid_relocs(ve, ve->rela_tables)); ASSERT(sce_elf_write_module_info(dest, ve, §ion_sizes, encoded_modinfo)); rtable.next = ve->rela_tables; ASSERT(sce_elf_write_rela_sections(dest, ve, &rtable)); ASSERT(sce_elf_rewrite_stubs(dest, ve)); ELF_ASSERT(elf_update(dest, ELF_C_WRITE) >= 0); elf_end(dest); ASSERT(sce_elf_set_headers(outfile, ve)); fclose(outfile); sce_elf_module_info_free(module_info); vita_elf_free(ve); int i; for (i = 0; i < imports_count; i++) { vita_imports_free(imports[i]); } free(imports); return status; failure: return EXIT_FAILURE; }
int client_dispatch(struct ntp_peer *p, u_int8_t settime) { struct ntp_msg msg; struct msghdr somsg; struct iovec iov[1]; struct timeval tv; char buf[NTP_MSGSIZE]; union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(tv))]; } cmsgbuf; struct cmsghdr *cmsg; ssize_t size; double T1, T2, T3, T4; time_t interval; bzero(&somsg, sizeof(somsg)); iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf); somsg.msg_iov = iov; somsg.msg_iovlen = 1; somsg.msg_control = cmsgbuf.buf; somsg.msg_controllen = sizeof(cmsgbuf.buf); T4 = getoffset(); if ((size = recvmsg(p->query->fd, &somsg, 0)) == -1) { if (errno == EHOSTUNREACH || errno == EHOSTDOWN || errno == ENETUNREACH || errno == ENETDOWN || errno == ECONNREFUSED || errno == EADDRNOTAVAIL || errno == ENOPROTOOPT || errno == ENOENT) { client_log_error(p, "recvmsg", errno); set_next(p, error_interval()); return (0); } else fatal("recvfrom"); } if (somsg.msg_flags & MSG_TRUNC) { client_log_error(p, "recvmsg packet", EMSGSIZE); set_next(p, error_interval()); return (0); } if (somsg.msg_flags & MSG_CTRUNC) { client_log_error(p, "recvmsg control data", E2BIG); set_next(p, error_interval()); return (0); } #ifdef HAVE_RTABLE if (p->rtable != -1 && setsockopt(p->query->fd, SOL_SOCKET, SO_RTABLE, &p->rtable, sizeof(p->rtable)) == -1) fatal("client_dispatch setsockopt SO_RTABLE"); #endif for (cmsg = CMSG_FIRSTHDR(&somsg); cmsg != NULL; cmsg = CMSG_NXTHDR(&somsg, cmsg)) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) { memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv)); T4 += tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec; break; } } if (T4 < JAN_1970) { client_log_error(p, "recvmsg control format", EBADF); set_next(p, error_interval()); return (0); } ntp_getmsg((struct sockaddr *)&p->addr->ss, buf, size, &msg); if (msg.orgtime.int_partl != p->query->msg.xmttime.int_partl || msg.orgtime.fractionl != p->query->msg.xmttime.fractionl) return (0); if ((msg.status & LI_ALARM) == LI_ALARM || msg.stratum == 0 || msg.stratum > NTP_MAXSTRATUM) { char s[16]; if ((msg.status & LI_ALARM) == LI_ALARM) { strlcpy(s, "alarm", sizeof(s)); } else if (msg.stratum == 0) { /* Kiss-o'-Death (KoD) packet */ strlcpy(s, "KoD", sizeof(s)); } else if (msg.stratum > NTP_MAXSTRATUM) { snprintf(s, sizeof(s), "stratum %d", msg.stratum); } interval = error_interval(); set_next(p, interval); log_info("reply from %s: not synced (%s), next query %llds", log_sockaddr((struct sockaddr *)&p->addr->ss), s, (long long)interval); return (0); } /* * From RFC 2030 (with a correction to the delay math): * * Timestamp Name ID When Generated * ------------------------------------------------------------ * Originate Timestamp T1 time request sent by client * Receive Timestamp T2 time request received by server * Transmit Timestamp T3 time reply sent by server * Destination Timestamp T4 time reply received by client * * The roundtrip delay d and local clock offset t are defined as * * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2. */ T1 = p->query->xmttime; T2 = lfp_to_d(msg.rectime); T3 = lfp_to_d(msg.xmttime); /* * XXX workaround: time_t / tv_sec must never wrap. * around 2020 we will need a solution (64bit time_t / tv_sec). * consider every answer with a timestamp beyond january 2030 bogus. */ if (T2 > JAN_2030 || T3 > JAN_2030) { set_next(p, error_interval()); return (0); } p->reply[p->shift].offset = ((T2 - T1) + (T3 - T4)) / 2; p->reply[p->shift].delay = (T4 - T1) - (T3 - T2); p->reply[p->shift].status.stratum = msg.stratum; if (p->reply[p->shift].delay < 0) { interval = error_interval(); set_next(p, interval); log_info("reply from %s: negative delay %fs, " "next query %llds", log_sockaddr((struct sockaddr *)&p->addr->ss), p->reply[p->shift].delay, (long long)interval); return (0); } p->reply[p->shift].error = (T2 - T1) - (T3 - T4); p->reply[p->shift].rcvd = getmonotime(); p->reply[p->shift].good = 1; p->reply[p->shift].status.leap = (msg.status & LIMASK); p->reply[p->shift].status.precision = msg.precision; p->reply[p->shift].status.rootdelay = sfp_to_d(msg.rootdelay); p->reply[p->shift].status.rootdispersion = sfp_to_d(msg.dispersion); p->reply[p->shift].status.refid = msg.refid; p->reply[p->shift].status.reftime = lfp_to_d(msg.reftime); p->reply[p->shift].status.poll = msg.ppoll; if (p->addr->ss.ss_family == AF_INET) { p->reply[p->shift].status.send_refid = ((struct sockaddr_in *)&p->addr->ss)->sin_addr.s_addr; } else if (p->addr->ss.ss_family == AF_INET6) { MD5_CTX context; u_int8_t digest[MD5_DIGEST_LENGTH]; MD5_Init(&context); MD5_Update(&context, ((struct sockaddr_in6 *)&p->addr->ss)-> sin6_addr.s6_addr, sizeof(struct in6_addr)); MD5_Final(digest, &context); memcpy((char *)&p->reply[p->shift].status.send_refid, digest, sizeof(u_int32_t)); } else p->reply[p->shift].status.send_refid = msg.xmttime.fractionl; if (p->trustlevel < TRUSTLEVEL_PATHETIC) interval = scale_interval(INTERVAL_QUERY_PATHETIC); else if (p->trustlevel < TRUSTLEVEL_AGGRESSIVE) interval = scale_interval(INTERVAL_QUERY_AGGRESSIVE); else interval = scale_interval(INTERVAL_QUERY_NORMAL); set_next(p, interval); p->state = STATE_REPLY_RECEIVED; /* every received reply which we do not discard increases trust */ if (p->trustlevel < TRUSTLEVEL_MAX) { if (p->trustlevel < TRUSTLEVEL_BADPEER && p->trustlevel + 1 >= TRUSTLEVEL_BADPEER) log_info("peer %s now valid", log_sockaddr((struct sockaddr *)&p->addr->ss)); p->trustlevel++; } log_debug("reply from %s: offset %f delay %f, " "next query %llds %s", log_sockaddr((struct sockaddr *)&p->addr->ss), p->reply[p->shift].offset, p->reply[p->shift].delay, (long long)interval, print_rtable(p->rtable)); client_update(p); if (settime) priv_settime(p->reply[p->shift].offset); if (++p->shift >= OFFSET_ARRAY_SIZE) p->shift = 0; return (0); }