示例#1
0
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);

	}
}
示例#2
0
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, &section_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, &section_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, &section_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;
}
示例#3
0
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);
}