From 1f12da0e82e1f93bb8b608307d38bc8e5d177169 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 15:00:01 +0000 Subject: [PATCH 001/142] Just checkpoint the WIP in order to be able to make the tree update easier. Note: this is currently not in a usable state as certain teardown parts are not called and the DOMAIN rework is missing. More to come soon and find its way to head. Obtained from: P4 //depot/user/bz/vimage/... Sponsored by: The FreeBSD Foundation --- sys/contrib/ipfilter/netinet/mlfk_ipl.c | 2 +- sys/dev/usb/net/usb_ethernet.c | 6 +- sys/kern/kern_shutdown.c | 11 +++ sys/kern/kern_timeout.c | 38 ++++++++ sys/kern/uipc_domain.c | 6 +- sys/net/if.c | 27 +++++- sys/net/if_disc.c | 4 +- sys/net/if_enc.c | 6 +- sys/net/pfil.c | 19 ++-- sys/net/vnet.c | 8 -- sys/netinet/igmp.c | 121 +++++++++++++----------- sys/netinet/in_proto.c | 18 ---- sys/netinet/ip_divert.c | 14 +-- sys/netinet/ip_mroute.c | 6 +- sys/netinet/ip_var.h | 3 - sys/netinet/raw_ip.c | 3 +- sys/netinet/sctp_bsd_addr.c | 3 + sys/netinet/sctp_pcb.c | 24 ++++- sys/netinet/sctp_usrreq.c | 4 +- sys/netinet/sctp_var.h | 1 - sys/netinet/tcp_subr.c | 3 +- sys/netinet/tcp_var.h | 3 - sys/netinet/udp_usrreq.c | 7 +- sys/netinet/udp_var.h | 4 - sys/netinet6/in6.c | 4 +- sys/netinet6/in6_ifattach.c | 26 +++++ sys/netinet6/in6_ifattach.h | 1 + sys/netinet6/in6_proto.c | 3 - sys/netinet6/ip6_input.c | 35 +------ sys/netinet6/ip6_mroute.c | 2 +- sys/netinet6/mld6.c | 10 +- sys/netinet6/nd6.c | 6 +- sys/netinet6/nd6.h | 3 - sys/netipsec/ipsec.c | 2 +- sys/netipsec/xform_tcp.c | 2 +- sys/netpfil/ipfw/dn_sched.h | 2 +- sys/netpfil/ipfw/ip_dummynet.c | 2 +- sys/netpfil/ipfw/ip_fw2.c | 2 +- sys/netpfil/ipfw/ip_fw_nat.c | 2 +- sys/netpfil/pf/if_pfsync.c | 1 + sys/netpfil/pf/pf_ioctl.c | 2 +- sys/sys/kernel.h | 5 +- 42 files changed, 258 insertions(+), 193 deletions(-) diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c index 83a91899005e..09e5fcb78de8 100644 --- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c +++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c @@ -287,7 +287,7 @@ static moduledata_t ipfiltermod = { }; -DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_FW, SI_ORDER_ANY); #ifdef MODULE_VERSION MODULE_VERSION(ipfilter, 1); #endif diff --git a/sys/dev/usb/net/usb_ethernet.c b/sys/dev/usb/net/usb_ethernet.c index 5350da950449..0b0350cea34b 100644 --- a/sys/dev/usb/net/usb_ethernet.c +++ b/sys/dev/usb/net/usb_ethernet.c @@ -641,5 +641,9 @@ uether_rxflush(struct usb_ether *ue) } } -DECLARE_MODULE(uether, uether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +/* + * USB net drivers are run by DRIVER_MODULE() thus SI_SUB_DRIVERS, + * SI_ORDER_MIDDLE. Run uether after that. + */ +DECLARE_MODULE(uether, uether_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); MODULE_VERSION(uether, 1); diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 87e7d6388a71..b44d1a7db924 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -899,3 +899,14 @@ mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); kdh->parity = kerneldump_parity(kdh); } + +#ifdef DDB +DB_SHOW_COMMAND(panic, db_show_panic) +{ + + if (panicstr == NULL) + db_printf("Not paniced\n"); + else + db_printf("panic: %s\n", panicstr); +} +#endif diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 9c9d25f56b1d..e4f27cc32c50 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "opt_callout_profiling.h" +#include "opt_ddb.h" #if defined(__arm__) #include "opt_timer.h" #endif @@ -60,6 +61,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef DDB +#include +#include +#endif + #ifdef SMP #include #endif @@ -1615,3 +1621,35 @@ SYSCTL_PROC(_kern, OID_AUTO, callout_stat, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_callout_stat, "I", "Dump immediate statistic snapshot of the scheduled callouts"); + +#ifdef DDB + +static void +_show_callout(struct callout *c) +{ + + db_printf("callout %p\n", c); +#define C_DB_PRINTF(f, e) db_printf(" %s = " f "\n", #e, c->e); + db_printf(" &c_links = %p\n", &(c->c_links)); + C_DB_PRINTF("%" PRId64, c_time); + C_DB_PRINTF("%" PRId64, c_precision); + C_DB_PRINTF("%p", c_arg); + C_DB_PRINTF("%p", c_func); + C_DB_PRINTF("%p", c_lock); + C_DB_PRINTF("%#x", c_flags); + C_DB_PRINTF("%#x", c_iflags); + C_DB_PRINTF("%d", c_cpu); +#undef C_DB_PRINTF +} + +DB_SHOW_COMMAND(callout, db_show_callout) +{ + + if (!have_addr) { + db_printf("usage: show callout \n"); + return; + } + + _show_callout((struct callout *)addr); +} +#endif /* DDB */ diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 6dc24f9b25bb..b77339394361 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -198,8 +198,12 @@ vnet_domain_uninit(void *arg) struct protosw *pr; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) - if (pr->pr_destroy) + if (pr->pr_destroy) { +#ifdef INVARIANTS + printf("%s: pr %p called pr_destroy\n", __func__, pr); +#endif (*pr->pr_destroy)(); + } if (dp->dom_destroy) (*dp->dom_destroy)(); } diff --git a/sys/net/if.c b/sys/net/if.c index 39656efa363d..c18b1cc0250f 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -384,6 +384,26 @@ vnet_if_uninit(const void *unused __unused) } VNET_SYSUNINIT(vnet_if_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST, vnet_if_uninit, NULL); + +/* + * XXX-BZ VNET; probably along with dom stuff. + * This is very wrong but MC currently implies that interfaces are + * gone before we can free it. This needs to be fied differently + * and this needs to be moved back to SI_SUB_INIT_IF. + */ +static void +vnet_if_return(const void *unused __unused) +{ + struct ifnet *ifp, *nifp; + + /* Return all inherited interfaces to their parent vnets. */ + TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { + if (ifp->if_home_vnet != ifp->if_vnet) + if_vmove(ifp, ifp->if_home_vnet); + } +} +VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, + vnet_if_return, NULL); #endif static void @@ -821,6 +841,7 @@ if_purgeaddrs(struct ifnet *ifp) { struct ifaddr *ifa, *next; + /* XXX IF_ADDR_R/WLOCK */ TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) { if (ifa->ifa_addr->sa_family == AF_LINK) continue; @@ -845,7 +866,9 @@ if_purgeaddrs(struct ifnet *ifp) continue; } #endif /* INET6 */ + IF_ADDR_WLOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); + IF_ADDR_WUNLOCK(ifp); ifa_free(ifa); } } @@ -979,7 +1002,9 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp) /* We can now free link ifaddr. */ if (!TAILQ_EMPTY(&ifp->if_addrhead)) { ifa = TAILQ_FIRST(&ifp->if_addrhead); + IF_ADDR_WLOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); + IF_ADDR_WUNLOCK(ifp); ifa_free(ifa); } } @@ -1285,7 +1310,7 @@ if_delgroups(struct ifnet *ifp) strlcpy(groupname, ifgl->ifgl_group->ifg_group, IFNAMSIZ); IF_ADDR_WLOCK(ifp); - TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); + TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); // <<<< IF_ADDR_WUNLOCK(ifp); TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index b6e1d203d214..67770699c6d4 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -137,7 +137,7 @@ vnet_disc_init(const void *unused __unused) V_disc_cloner = if_clone_simple(discname, disc_clone_create, disc_clone_destroy, 0); } -VNET_SYSINIT(vnet_disc_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSINIT(vnet_disc_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_disc_init, NULL); static void @@ -146,7 +146,7 @@ vnet_disc_uninit(const void *unused __unused) if_clone_detach(V_disc_cloner); } -VNET_SYSUNINIT(vnet_disc_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_disc_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_disc_uninit, NULL); static int diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c index e3bf5b846268..96c549d3e8ce 100644 --- a/sys/net/if_enc.c +++ b/sys/net/if_enc.c @@ -369,7 +369,7 @@ vnet_enc_init(const void *unused __unused) V_enc_cloner = if_clone_simple(encname, enc_clone_create, enc_clone_destroy, 1); } -VNET_SYSINIT(vnet_enc_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSINIT(vnet_enc_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_enc_init, NULL); static void @@ -378,7 +378,7 @@ vnet_enc_uninit(const void *unused __unused) if_clone_detach(V_enc_cloner); } -VNET_SYSUNINIT(vnet_enc_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_enc_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_enc_uninit, NULL); static int @@ -401,4 +401,4 @@ static moduledata_t enc_mod = { 0 }; -DECLARE_MODULE(if_enc, enc_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(if_enc, enc_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 2494deae2052..92c041dca11b 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -363,39 +363,34 @@ pfil_chain_remove(pfil_chain_t *chain, pfil_func_t func, void *arg) * Stuff that must be initialized for every instance (including the first of * course). */ -static int +static void vnet_pfil_init(const void *unused) { LIST_INIT(&V_pfil_head_list); PFIL_LOCK_INIT_REAL(&V_pfil_lock, "shared"); - return (0); } /* * Called for the removal of each instance. */ -static int +static void vnet_pfil_uninit(const void *unused) { - KASSERT(LIST_EMPTY(&V_pfil_head_list), + VNET_ASSERT(LIST_EMPTY(&V_pfil_head_list), ("%s: pfil_head_list %p not empty", __func__, &V_pfil_head_list)); PFIL_LOCK_DESTROY_REAL(&V_pfil_lock); - return (0); } -/* Define startup order. */ -#define PFIL_SYSINIT_ORDER SI_SUB_PROTO_BEGIN -#define PFIL_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */ -#define PFIL_VNET_ORDER (PFIL_MODEVENT_ORDER + 2) /* Later still. */ - /* * Starting up. * * VNET_SYSINIT is called for each existing vnet and each new vnet. + * Make sure the pfil bits are first before any possible subsystem which + * might piggyback on the SI_SUB_PROTO_PFIL. */ -VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, +VNET_SYSINIT(vnet_pfil_init, SI_SUB_PROTO_PFIL, SI_ORDER_FIRST, vnet_pfil_init, NULL); /* @@ -403,5 +398,5 @@ VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, * * VNET_SYSUNINIT is called for each exiting vnet as it exits. */ -VNET_SYSUNINIT(vnet_pfil_uninit, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER, +VNET_SYSUNINIT(vnet_pfil_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_FIRST, vnet_pfil_uninit, NULL); diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 6dddd3da4d50..93972be0905a 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -269,7 +269,6 @@ vnet_alloc(void) void vnet_destroy(struct vnet *vnet) { - struct ifnet *ifp, *nifp; SDT_PROBE2(vnet, functions, vnet_destroy, entry, __LINE__, vnet); KASSERT(vnet->vnet_sockcnt == 0, @@ -280,13 +279,6 @@ vnet_destroy(struct vnet *vnet) VNET_LIST_WUNLOCK(); CURVNET_SET_QUIET(vnet); - - /* Return all inherited interfaces to their parent vnets. */ - TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { - if (ifp->if_home_vnet != ifp->if_vnet) - if_vmove(ifp, ifp->if_home_vnet); - } - vnet_sysuninit(); CURVNET_RESTORE(); diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index d83348c758ed..c2d6d8afac1e 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -50,6 +50,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_ddb.h" + #include #include #include @@ -64,6 +66,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef DDB +#include +#endif + #include #include #include @@ -221,7 +227,8 @@ static VNET_DEFINE(int, current_state_timers_running); /* IGMPv1/v2 host #define V_state_change_timers_running VNET(state_change_timers_running) #define V_current_state_timers_running VNET(current_state_timers_running) -static VNET_DEFINE(LIST_HEAD(, igmp_ifsoftc), igi_head); +static VNET_DEFINE(LIST_HEAD(, igmp_ifsoftc), igi_head) = + LIST_HEAD_INITIALIZER(igi_head); static VNET_DEFINE(struct igmpstat, igmpstat) = { .igps_version = IGPS_VERSION_3, .igps_len = sizeof(struct igmpstat), @@ -659,16 +666,12 @@ igmp_ifdetach(struct ifnet *ifp) void igmp_domifdetach(struct ifnet *ifp) { - struct igmp_ifsoftc *igi; CTR3(KTR_IGMPV3, "%s: called for ifp %p(%s)", __func__, ifp, ifp->if_xname); IGMP_LOCK(); - - igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp; igi_delete_locked(ifp); - IGMP_UNLOCK(); } @@ -3593,70 +3596,74 @@ igmp_rec_type_to_str(const int type) } #endif -static void -igmp_init(void *unused __unused) -{ - - CTR1(KTR_IGMPV3, "%s: initializing", __func__); - - IGMP_LOCK_INIT(); - - m_raopt = igmp_ra_alloc(); - - netisr_register(&igmp_nh); -} -SYSINIT(igmp_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_init, NULL); - -static void -igmp_uninit(void *unused __unused) -{ - - CTR1(KTR_IGMPV3, "%s: tearing down", __func__); - - netisr_unregister(&igmp_nh); - - m_free(m_raopt); - m_raopt = NULL; - - IGMP_LOCK_DESTROY(); -} -SYSUNINIT(igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, igmp_uninit, NULL); - -static void -vnet_igmp_init(const void *unused __unused) -{ - - CTR1(KTR_IGMPV3, "%s: initializing", __func__); - - LIST_INIT(&V_igi_head); -} -VNET_SYSINIT(vnet_igmp_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_igmp_init, - NULL); - +#ifdef VIMAGE static void vnet_igmp_uninit(const void *unused __unused) { CTR1(KTR_IGMPV3, "%s: tearing down", __func__); - KASSERT(LIST_EMPTY(&V_igi_head), - ("%s: igi list not empty; ifnets not detached?", __func__)); + VNET_ASSERT(LIST_EMPTY(&V_igi_head), + ("%s: igi list %p not empty; ifnets not detached?", __func__, + &V_igi_head)); } -VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_igmp_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_igmp_uninit, NULL); +#endif + +#ifdef DDB +DB_SHOW_COMMAND(igi_list, db_show_igi_list) +{ + struct igmp_ifsoftc *igi, *tigi; + LIST_HEAD(_igi_list, igmp_ifsoftc) *igi_head; + + if (!have_addr) { + db_printf("usage: show igi_list \n"); + return; + } + igi_head = (struct _igi_list *)addr; + + LIST_FOREACH_SAFE(igi, igi_head, igi_link, tigi) { + db_printf("igmp_ifsoftc %p:\n", igi); + db_printf(" ifp %p\n", igi->igi_ifp); + db_printf(" version %u\n", igi->igi_version); + db_printf(" v1_timer %u\n", igi->igi_v1_timer); + db_printf(" v2_timer %u\n", igi->igi_v2_timer); + db_printf(" v3_timer %u\n", igi->igi_v3_timer); + db_printf(" flags %#x\n", igi->igi_flags); + db_printf(" rv %u\n", igi->igi_rv); + db_printf(" qi %u\n", igi->igi_qi); + db_printf(" qri %u\n", igi->igi_qri); + db_printf(" uri %u\n", igi->igi_uri); + /* SLIST_HEAD(,in_multi) igi_relinmhead */ + /* struct mbufq igi_gq; */ + db_printf("\n"); + } +} +#endif static int igmp_modevent(module_t mod, int type, void *unused __unused) { - switch (type) { - case MOD_LOAD: - case MOD_UNLOAD: - break; - default: - return (EOPNOTSUPP); - } - return (0); + switch (type) { + case MOD_LOAD: + CTR1(KTR_IGMPV3, "%s: initializing", __func__); + IGMP_LOCK_INIT(); + m_raopt = igmp_ra_alloc(); + netisr_register(&igmp_nh); + break; + case MOD_UNLOAD: + CTR1(KTR_IGMPV3, "%s: tearing down", __func__); + netisr_unregister(&igmp_nh); + m_free(m_raopt); + m_raopt = NULL; + IGMP_LOCK_DESTROY(); + break; + default: + return (EOPNOTSUPP); + } + return (0); } static moduledata_t igmp_mod = { @@ -3664,4 +3671,4 @@ static moduledata_t igmp_mod = { igmp_modevent, 0 }; -DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(igmp, igmp_mod, SI_SUB_PROTO_MC, SI_ORDER_ANY); diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 0ac91c72bb88..fb7ad762080c 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -118,9 +118,6 @@ struct protosw inetsw[] = { .pr_domain = &inetdomain, .pr_protocol = IPPROTO_IP, .pr_init = ip_init, -#ifdef VIMAGE - .pr_destroy = ip_destroy, -#endif .pr_slowtimo = ip_slowtimo, .pr_drain = ip_drain, .pr_usrreqs = &nousrreqs @@ -134,9 +131,6 @@ struct protosw inetsw[] = { .pr_ctlinput = udp_ctlinput, .pr_ctloutput = udp_ctloutput, .pr_init = udp_init, -#ifdef VIMAGE - .pr_destroy = udp_destroy, -#endif .pr_usrreqs = &udp_usrreqs }, { @@ -148,9 +142,6 @@ struct protosw inetsw[] = { .pr_ctlinput = tcp_ctlinput, .pr_ctloutput = tcp_ctloutput, .pr_init = tcp_init, -#ifdef VIMAGE - .pr_destroy = tcp_destroy, -#endif .pr_slowtimo = tcp_slowtimo, .pr_drain = tcp_drain, .pr_usrreqs = &tcp_usrreqs @@ -165,9 +156,6 @@ struct protosw inetsw[] = { .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, .pr_init = sctp_init, -#ifdef VIMAGE - .pr_destroy = sctp_finish, -#endif .pr_drain = sctp_drain, .pr_usrreqs = &sctp_usrreqs }, @@ -192,9 +180,6 @@ struct protosw inetsw[] = { .pr_ctlinput = udplite_ctlinput, .pr_ctloutput = udp_ctloutput, .pr_init = udplite_init, -#ifdef VIMAGE - .pr_destroy = udplite_destroy, -#endif .pr_usrreqs = &udp_usrreqs }, { @@ -342,9 +327,6 @@ IPPROTOSPACER, .pr_input = rip_input, .pr_ctloutput = rip_ctloutput, .pr_init = rip_init, -#ifdef VIMAGE - .pr_destroy = rip_destroy, -#endif .pr_usrreqs = &rip_usrreqs }, }; diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 3e3bc942df9e..1f4c85a1462f 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -168,6 +168,8 @@ div_destroy(void) in_pcbinfo_destroy(&V_divcbinfo); } +VNET_SYSUNINIT(divert, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, + div_destroy, NULL); /* * IPPROTO_DIVERT is not in the real IP protocol number space; this @@ -756,9 +758,6 @@ struct protosw div_protosw = { .pr_ctlinput = div_ctlinput, .pr_ctloutput = ip_ctloutput, .pr_init = div_init, -#ifdef VIMAGE - .pr_destroy = div_destroy, -#endif .pr_usrreqs = &div_usrreqs }; @@ -766,9 +765,7 @@ static int div_modevent(module_t mod, int type, void *unused) { int err = 0; -#ifndef VIMAGE int n; -#endif switch (type) { case MOD_LOAD: @@ -793,10 +790,6 @@ div_modevent(module_t mod, int type, void *unused) err = EPERM; break; case MOD_UNLOAD: -#ifdef VIMAGE - err = EPERM; - break; -#else /* * Forced unload. * @@ -821,7 +814,6 @@ div_modevent(module_t mod, int type, void *unused) div_destroy(); EVENTHANDLER_DEREGISTER(maxsockets_change, ip_divert_event_tag); break; -#endif /* !VIMAGE */ default: err = EOPNOTSUPP; break; @@ -835,6 +827,6 @@ static moduledata_t ipdivertmod = { 0 }; -DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_FW, SI_ORDER_ANY); MODULE_DEPEND(ipdivert, ipfw, 3, 3, 3); MODULE_VERSION(ipdivert, 1); diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index ffa88ae43ac0..d16cd6e979fa 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -2821,7 +2821,7 @@ vnet_mroute_init(const void *unused __unused) callout_init(&V_bw_meter_ch, 1); } -VNET_SYSINIT(vnet_mroute_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mroute_init, +VNET_SYSINIT(vnet_mroute_init, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mroute_init, NULL); static void @@ -2832,7 +2832,7 @@ vnet_mroute_uninit(const void *unused __unused) V_nexpire = NULL; } -VNET_SYSUNINIT(vnet_mroute_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, +VNET_SYSUNINIT(vnet_mroute_uninit, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, vnet_mroute_uninit, NULL); static int @@ -2945,4 +2945,4 @@ static moduledata_t ip_mroutemod = { 0 }; -DECLARE_MODULE(ip_mroute, ip_mroutemod, SI_SUB_PSEUDO, SI_ORDER_MIDDLE); +DECLARE_MODULE(ip_mroute, ip_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE); diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index f4ad4ffe0dd5..755c7d74aaa4 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -229,9 +229,6 @@ void ip_fillid(struct ip *); int rip_ctloutput(struct socket *, struct sockopt *); void rip_ctlinput(int, struct sockaddr *, void *); void rip_init(void); -#ifdef VIMAGE -void rip_destroy(void); -#endif int rip_input(struct mbuf **, int *, int); int rip_output(struct mbuf *, struct socket *, ...); int ipip_input(struct mbuf **, int *, int); diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 4e9fedaac817..cae542733523 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -215,12 +215,13 @@ rip_init(void) } #ifdef VIMAGE -void +static void rip_destroy(void) { in_pcbinfo_destroy(&V_ripcbinfo); } +VNET_SYSUNINIT(raw_ip, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, rip_destroy, NULL); #endif #ifdef INET diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index f638d213b5be..0fc7d12da026 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -293,6 +293,9 @@ sctp_addr_change(struct ifaddr *ifa, int cmd) { uint32_t ifa_flags = 0; + if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) + return; + /* * BSD only has one VRF, if this changes we will need to hook in the * right things here to get the id to pass to the address managment diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index fc3be4c955dc..d1e62c246169 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -5927,12 +5927,34 @@ sctp_pcb_finish(void) int i; struct sctp_iterator *it, *nit; + if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { + printf("%s: race condition on teardown.\n", __func__); + return; + } + SCTP_BASE_VAR(sctp_pcb_initialized) = 0; + /* * In FreeBSD the iterator thread never exits but we do clean up. * The only way FreeBSD reaches here is if we have VRF's but we * still add the ifdef to make it compile on old versions. */ +retry: + while (sctp_it_ctl.iterator_running != 0) + DELAY(1); SCTP_IPI_ITERATOR_WQ_LOCK(); + /* + * sctp_iterator_worker() might be working on an it entry without + * holding the lock. We won't find it on the list either and + * continue and free/destroy it. While holding the lock, spin, to + * avoid the race condition as sctp_iterator_worker() will have to + * wait to re-aquire the lock. + */ + if (sctp_it_ctl.cur_it != NULL || sctp_it_ctl.iterator_running != 0) { + SCTP_IPI_ITERATOR_WQ_UNLOCK(); + printf("%s: Iterator running while we held the lock. Retry.\n", + __func__); + goto retry; + } TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { if (it->vn != curvnet) { continue; @@ -5950,7 +5972,7 @@ sctp_pcb_finish(void) sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT; } SCTP_ITERATOR_UNLOCK(); - SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer)); + SCTP_OS_TIMER_STOP_DRAIN(&SCTP_BASE_INFO(addr_wq_timer.timer)); SCTP_WQ_ADDR_LOCK(); LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { LIST_REMOVE(wi, sctp_nxt_addr); diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 60deff0ff253..7a22857ae9f5 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -89,12 +89,12 @@ sctp_init(void) #endif } -void +static void sctp_finish(void) { sctp_pcb_finish(); } - +VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL); void diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index ae1b3eb3089d..55f825109bda 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -333,7 +333,6 @@ int sctp_input(struct mbuf **, int *, int); void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); void sctp_drain(void); void sctp_init(void); -void sctp_finish(void); int sctp_flush(struct socket *, int); int sctp_shutdown(struct socket *); void diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index c2e0696394a5..adea0f1f7890 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -714,7 +714,7 @@ tcp_init(void) } #ifdef VIMAGE -void +static void tcp_destroy(void) { int error; @@ -742,6 +742,7 @@ tcp_destroy(void) HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, error); } } +VNET_SYSUNINIT(tcp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_destroy, NULL); #endif void diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 8d76912275a1..e0c66559276b 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -736,9 +736,6 @@ struct tcpcb * tcp_drop(struct tcpcb *, int); void tcp_drain(void); void tcp_init(void); -#ifdef VIMAGE -void tcp_destroy(void); -#endif void tcp_fini(void *); char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *, const void *); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index f474a54db623..a20ad28261f8 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -269,20 +269,23 @@ udp_discardcb(struct udpcb *up) } #ifdef VIMAGE -void +static void udp_destroy(void) { in_pcbinfo_destroy(&V_udbinfo); uma_zdestroy(V_udpcb_zone); } +VNET_SYSUNINIT(udp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udp_destroy, NULL); -void +static void udplite_destroy(void) { in_pcbinfo_destroy(&V_ulitecbinfo); } +VNET_SYSUNINIT(udplite, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udplite_destroy, + NULL); #endif #ifdef INET diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 40d35ef43812..972ac8c618c8 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -169,10 +169,6 @@ void udplite_ctlinput(int, struct sockaddr *, void *); int udp_ctloutput(struct socket *, struct sockopt *); void udp_init(void); void udplite_init(void); -#ifdef VIMAGE -void udp_destroy(void); -void udplite_destroy(void); -#endif int udp_input(struct mbuf **, int *, int); void udplite_input(struct mbuf *, int); struct inpcb *udp_notify(struct inpcb *inp, int errno); diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 0f8fb67a143f..aa770199bd8e 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1552,7 +1552,7 @@ in6ifa_llaonifp(struct ifnet *ifp) if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) return (NULL); - if_addr_rlock(ifp); + IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET6) continue; @@ -1562,7 +1562,7 @@ in6ifa_llaonifp(struct ifnet *ifp) IN6_IS_ADDR_MC_NODELOCAL(&sin6->sin6_addr)) break; } - if_addr_runlock(ifp); + IF_ADDR_RUNLOCK(ifp); return ((struct in6_ifaddr *)ifa); } diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 64981b3e8f8d..471dd82e38a5 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -890,3 +890,29 @@ in6_purgemaddrs(struct ifnet *ifp) IN6_MULTI_UNLOCK(); } + +void +in6_ifattach_destroy(void) +{ + + callout_drain(&V_in6_tmpaddrtimer_ch); +} + +static void +in6_ifattach_init(void *dummy) +{ + + /* Timer for regeneranation of temporary addresses randomize ID. */ + callout_init(&V_in6_tmpaddrtimer_ch, 0); + callout_reset(&V_in6_tmpaddrtimer_ch, + (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor - + V_ip6_temp_regen_advance) * hz, + in6_tmpaddrtimer, curvnet); +} + +/* + * Cheat. + * This must be after route_init(), which is now SI_ORDER_THIRD. + */ +SYSINIT(in6_ifattach_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, + in6_ifattach_init, NULL); diff --git a/sys/netinet6/in6_ifattach.h b/sys/netinet6/in6_ifattach.h index af62731374f2..a5a82c048bd5 100644 --- a/sys/netinet6/in6_ifattach.h +++ b/sys/netinet6/in6_ifattach.h @@ -35,6 +35,7 @@ #ifdef _KERNEL void in6_ifattach(struct ifnet *, struct ifnet *); +void in6_ifattach_destroy(void); void in6_ifdetach(struct ifnet *); int in6_get_tmpifid(struct ifnet *, u_int8_t *, const u_int8_t *, int); void in6_tmpaddrtimer(void *); diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 4d328d282ec3..5dd946671667 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -152,9 +152,6 @@ struct protosw inet6sw[] = { .pr_domain = &inet6domain, .pr_protocol = IPPROTO_IPV6, .pr_init = ip6_init, -#ifdef VIMAGE - .pr_destroy = ip6_destroy, -#endif .pr_slowtimo = frag6_slowtimo, .pr_drain = frag6_drain, .pr_usrreqs = &nousrreqs, diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index e6c16a96844c..6b49b26de9aa 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -156,9 +156,6 @@ static struct netisr_handler ip6_direct_nh = { }; #endif -VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch); -#define V_in6_tmpaddrtimer_ch VNET(in6_tmpaddrtimer_ch) - VNET_DEFINE(struct pfil_head, inet6_pfil_hook); VNET_PCPUSTAT_DEFINE(struct ip6stat, ip6stat); @@ -170,7 +167,6 @@ VNET_PCPUSTAT_SYSUNINIT(ip6stat); struct rmlock in6_ifaddr_lock; RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); -static void ip6_init2(void *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); #ifdef PULLDOWN_TEST static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); @@ -331,39 +327,10 @@ ip6_destroy() } hashdestroy(V_in6_ifaddrhashtbl, M_IFADDR, V_in6_ifaddrhmask); nd6_destroy(); - callout_drain(&V_in6_tmpaddrtimer_ch); + in6_ifattach_destroy(); } #endif -static int -ip6_init2_vnet(const void *unused __unused) -{ - - /* nd6_timer_init */ - callout_init(&V_nd6_timer_ch, 0); - callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet); - - /* timer for regeneranation of temporary addresses randomize ID */ - callout_init(&V_in6_tmpaddrtimer_ch, 0); - callout_reset(&V_in6_tmpaddrtimer_ch, - (V_ip6_temp_preferred_lifetime - V_ip6_desync_factor - - V_ip6_temp_regen_advance) * hz, - in6_tmpaddrtimer, curvnet); - - return (0); -} - -static void -ip6_init2(void *dummy) -{ - - ip6_init2_vnet(NULL); -} - -/* cheat */ -/* This must be after route_init(), which is now SI_ORDER_THIRD */ -SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL); - static int ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off, int *nxt, int *ours) diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index f560dc527459..3ae900d6a7ac 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1966,4 +1966,4 @@ static moduledata_t ip6_mroutemod = { 0 }; -DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_ANY); diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 3c4cc99f1a5b..95fbafe27b9f 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -3264,7 +3264,7 @@ mld_init(void *unused __unused) mld_po.ip6po_prefer_tempaddr = IP6PO_TEMPADDR_NOTPREFER; mld_po.ip6po_flags = IP6PO_DONTFRAG; } -SYSINIT(mld_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_init, NULL); +SYSINIT(mld_init, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_init, NULL); static void mld_uninit(void *unused __unused) @@ -3273,7 +3273,7 @@ mld_uninit(void *unused __unused) CTR1(KTR_MLD, "%s: tearing down", __func__); MLD_LOCK_DESTROY(); } -SYSUNINIT(mld_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, mld_uninit, NULL); +SYSUNINIT(mld_uninit, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE, mld_uninit, NULL); static void vnet_mld_init(const void *unused __unused) @@ -3283,7 +3283,7 @@ vnet_mld_init(const void *unused __unused) LIST_INIT(&V_mli_head); } -VNET_SYSINIT(vnet_mld_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_init, +VNET_SYSINIT(vnet_mld_init, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mld_init, NULL); static void @@ -3295,7 +3295,7 @@ vnet_mld_uninit(const void *unused __unused) KASSERT(LIST_EMPTY(&V_mli_head), ("%s: mli list not empty; ifnets not detached?", __func__)); } -VNET_SYSUNINIT(vnet_mld_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_mld_uninit, +VNET_SYSUNINIT(vnet_mld_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mld_uninit, NULL); static int @@ -3317,4 +3317,4 @@ static moduledata_t mld_mod = { mld_modevent, 0 }; -DECLARE_MODULE(mld, mld_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +DECLARE_MODULE(mld, mld_mod, SI_SUB_PROTO_MC, SI_ORDER_ANY); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 7ca172cd449c..0c7a16f914cf 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -146,6 +146,7 @@ static VNET_DEFINE(struct callout, nd6_slowtimo_ch); #define V_nd6_slowtimo_ch VNET(nd6_slowtimo_ch) VNET_DEFINE(struct callout, nd6_timer_ch); +#define V_nd6_timer_ch VNET(nd6_timer_ch) static void nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) @@ -205,11 +206,14 @@ nd6_init(void) /* initialization of the default router list */ TAILQ_INIT(&V_nd_defrouter); - /* start timer */ + /* Start timers. */ callout_init(&V_nd6_slowtimo_ch, 0); callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, nd6_slowtimo, curvnet); + callout_init(&V_nd6_timer_ch, 0); + callout_reset(&V_nd6_timer_ch, hz, nd6_timer, curvnet); + nd6_dad_init(); if (IS_DEFAULT_VNET(curvnet)) lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event, diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 8a0a56e1b7f0..68d95f113b35 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -341,9 +341,6 @@ VNET_DECLARE(int, nd6_onlink_ns_rfc4861); #define nd6log(x) do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0) -VNET_DECLARE(struct callout, nd6_timer_ch); -#define V_nd6_timer_ch VNET(nd6_timer_ch) - /* nd6_rtr.c */ VNET_DECLARE(int, nd6_defifindex); VNET_DECLARE(int, ip6_desync_factor); /* seconds */ diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 68a67a7780b1..5edfd03af3f8 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -1709,7 +1709,7 @@ def_policy_init(const void *unused __unused) V_def_policy.policy = IPSEC_POLICY_NONE; V_def_policy.refcnt = 1; } -VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, +VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, def_policy_init, NULL); diff --git a/sys/netipsec/xform_tcp.c b/sys/netipsec/xform_tcp.c index 267e3777bfdd..6a55ed27f050 100644 --- a/sys/netipsec/xform_tcp.c +++ b/sys/netipsec/xform_tcp.c @@ -166,5 +166,5 @@ tcpsignature_attach(void) xform_register(&tcpsignature_xformsw); } -SYSINIT(tcpsignature_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, +SYSINIT(tcpsignature_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, tcpsignature_attach, NULL); diff --git a/sys/netpfil/ipfw/dn_sched.h b/sys/netpfil/ipfw/dn_sched.h index 4268edf0df2b..60ea1c215101 100644 --- a/sys/netpfil/ipfw/dn_sched.h +++ b/sys/netpfil/ipfw/dn_sched.h @@ -187,6 +187,6 @@ int dn_sched_modevent(module_t mod, int cmd, void *arg); #name, dn_sched_modevent, dnsched \ }; \ DECLARE_MODULE(name, name##_mod, \ - SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \ + SI_SUB_FW, SI_ORDER_ANY); \ MODULE_DEPEND(name, dummynet, 3, 3, 3) #endif /* _DN_SCHED_H */ diff --git a/sys/netpfil/ipfw/ip_dummynet.c b/sys/netpfil/ipfw/ip_dummynet.c index 425afcaa7a4e..22f1928b8693 100644 --- a/sys/netpfil/ipfw/ip_dummynet.c +++ b/sys/netpfil/ipfw/ip_dummynet.c @@ -2298,7 +2298,7 @@ static moduledata_t dummynet_mod = { "dummynet", dummynet_modevent, NULL }; -#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN +#define DN_SI_SUB SI_SUB_FW #define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */ DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD); MODULE_DEPEND(dummynet, ipfw, 3, 3, 3); diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index 750c81281818..c2e1590e2ec0 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -2883,7 +2883,7 @@ static moduledata_t ipfwmod = { }; /* Define startup order. */ -#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_SI_SUB_FIREWALL SI_SUB_FW #define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */ #define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */ #define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */ diff --git a/sys/netpfil/ipfw/ip_fw_nat.c b/sys/netpfil/ipfw/ip_fw_nat.c index df403982086b..5603e25bcdab 100644 --- a/sys/netpfil/ipfw/ip_fw_nat.c +++ b/sys/netpfil/ipfw/ip_fw_nat.c @@ -1213,7 +1213,7 @@ static moduledata_t ipfw_nat_mod = { }; /* Define startup order. */ -#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_FW #define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) /* after ipfw */ #define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) #define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 09d707c73dcf..f559e0b6a9da 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -2416,6 +2416,7 @@ static moduledata_t pfsync_mod = { #define PFSYNC_MODVER 1 +/* XXX-BZ recheck the r229853 comment once the shuffling is done. */ DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); MODULE_VERSION(pfsync, PFSYNC_MODVER); MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index a5a516fd3e5a..0943b58e4153 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -3789,5 +3789,5 @@ static moduledata_t pf_mod = { 0 }; -DECLARE_MODULE(pf, pf_mod, SI_SUB_PSEUDO, SI_ORDER_FIRST); +DECLARE_MODULE(pf, pf_mod, SI_SUB_FW, SI_ORDER_FIRST); MODULE_VERSION(pf, PF_MODVER); diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index dddf087ff15b..f1460087b091 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -136,10 +136,13 @@ enum sysinit_sub_id { SI_SUB_PSEUDO = 0x7000000, /* pseudo devices*/ SI_SUB_EXEC = 0x7400000, /* execve() handlers */ SI_SUB_PROTO_BEGIN = 0x8000000, /* VNET initialization */ + SI_SUB_PROTO_PFIL = 0x8100000, /* Intialize pfil before FWs */ SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/ SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */ + SI_SUB_PROTO_MC = 0x8700000, /* Multicast */ SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/ - SI_SUB_PROTO_IFATTACHDOMAIN = 0x8800001, /* domain dependent data init*/ + SI_SUB_FW = 0x8806000, /* Firewalls */ + SI_SUB_PROTO_IFATTACHDOMAIN = 0x8808000,/* domain dependent data init */ SI_SUB_PROTO_END = 0x8ffffff, /* VNET helper functions */ SI_SUB_KPROF = 0x9000000, /* kernel profiling*/ SI_SUB_KICK_SCHEDULER = 0xa000000, /* start the timeout events*/ From 0ea826e094f8e0314fece519c0a9bf59a077128a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:09:25 +0000 Subject: [PATCH 002/142] MFp4 @180892: With pr_destroy being gone, call ip6_destroy from an ordered NET_SYSUNINT. Make ip6_destroy() static as well. Sponsored by: The FreeBSD Foundation --- sys/netinet6/ip6_input.c | 6 ++++-- sys/netinet6/ip6_var.h | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 6b49b26de9aa..d7fc9eeaf33a 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -305,8 +305,8 @@ ip6proto_unregister(short ip6proto) } #ifdef VIMAGE -void -ip6_destroy() +static void +ip6_destroy(void *unused __unused) { int error; @@ -329,6 +329,8 @@ ip6_destroy() nd6_destroy(); in6_ifattach_destroy(); } + +VNET_SYSUNINIT(inet6, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_destroy, NULL); #endif static int diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index ef86eca9b037..c37881adcb44 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -354,9 +354,6 @@ int icmp6_ctloutput(struct socket *, struct sockopt *sopt); struct in6_ifaddr; void ip6_init(void); -#ifdef VIMAGE -void ip6_destroy(void); -#endif int ip6proto_register(short); int ip6proto_unregister(short); From f2cf0121cae2ba825db03c0225cc63e41e641359 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:22:03 +0000 Subject: [PATCH 003/142] MFp4 @180887: With pr_destroy being gone, call ip_destroy from an ordered VNET_SYSUNINT. Make ip_destroy() static. Sponsored by: The FreeBSD Foundation --- sys/netinet/ip_input.c | 6 ++++-- sys/netinet/ip_var.h | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 6f25e08b33f0..d5a98ee48cd9 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -361,8 +361,8 @@ ip_init(void) } #ifdef VIMAGE -void -ip_destroy(void) +static void +ip_destroy(void *unused __unused) { int error; @@ -388,6 +388,8 @@ ip_destroy(void) /* Destroy IP reassembly queue. */ ipreass_destroy(); } + +VNET_SYSUNINIT(ip, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip_destroy, NULL); #endif #ifdef RSS diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 755c7d74aaa4..847704fd1d7f 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -209,9 +209,6 @@ int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, u_long if_hwassist_flags); void ip_forward(struct mbuf *m, int srcrt); void ip_init(void); -#ifdef VIMAGE -void ip_destroy(void); -#endif extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, struct ip_moptions *); From 9ff1c4634f0cef0b9889b5325945931028c0f28b Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:26:58 +0000 Subject: [PATCH 004/142] Correct function arguments for SYSUNINITs. Obtained from: p4 @180886 Sponsored by: The FreeBSD Foundation --- sys/netinet/udp_usrreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index a20ad28261f8..c77455c5c2ac 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -270,7 +270,7 @@ udp_discardcb(struct udpcb *up) #ifdef VIMAGE static void -udp_destroy(void) +udp_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_udbinfo); @@ -279,7 +279,7 @@ udp_destroy(void) VNET_SYSUNINIT(udp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, udp_destroy, NULL); static void -udplite_destroy(void) +udplite_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_ulitecbinfo); From 8bdb5261e6ac7a799d435094ed3dd4078f3fd2e5 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:29:02 +0000 Subject: [PATCH 005/142] Correct function arguments for SYSUNINITs. Obtained from: p4 @180885 Sponsored by: The FreeBSD Foundation --- sys/netinet/tcp_subr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 7092cd6ec01e..0f30008c95e5 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -717,7 +717,7 @@ tcp_init(void) #ifdef VIMAGE static void -tcp_destroy(void) +tcp_destroy(void *unused __unused) { int error; From 4ce8702050f7c002934870f05e00348bffed0792 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:35:11 +0000 Subject: [PATCH 006/142] Correct function arguments for SYSUNINITs. Add #ifdef VIMAGE, as in other cases it's dead code. Obtained from: p4 @180832 Sponsored by: The FreeBSD Foundation --- sys/netinet/sctp_usrreq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 698ae5bb57c9..0e1c0c914b32 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -89,13 +89,14 @@ sctp_init(void) #endif } +#ifdef VIMAGE static void -sctp_finish(void) +sctp_finish(void *unused __unused) { sctp_pcb_finish(); } VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL); - +#endif void sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz) From 1bbe967cc4570f389983d2b6dd588ba0e74d8f89 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:37:17 +0000 Subject: [PATCH 007/142] Correct function arguments for SYSUNINITs. Obtained from: p4 @180834 Sponsored by: The FreeBSD Foundation --- sys/netinet/raw_ip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index c2f590280e61..74f426ed1a36 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -217,7 +217,7 @@ rip_init(void) #ifdef VIMAGE static void -rip_destroy(void) +rip_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_ripcbinfo); From bb84e3d77d4898cab47bdfbeff7e793cd0ec833b Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 18:39:23 +0000 Subject: [PATCH 008/142] Correct function arguments for SYSUNINITs. Sponsored by: The FreeBSD Foundation --- sys/netinet/ip_divert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 1f4c85a1462f..0b1fbb6b44a2 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -163,7 +163,7 @@ div_init(void) } static void -div_destroy(void) +div_destroy(void *unused __unused) { in_pcbinfo_destroy(&V_divcbinfo); From eef5775f02132bba8c6e86888cfa9e20e63ca223 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 Jan 2016 19:43:26 +0000 Subject: [PATCH 009/142] Fix build and avoid a double-free in the VIMAGE case. Sponsored by: The FreeBSD Foundation --- sys/netinet/ip_divert.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 0b1fbb6b44a2..287cd90de988 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -811,7 +811,9 @@ div_modevent(module_t mod, int type, void *unused) ip_divert_ptr = NULL; err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW); INP_INFO_WUNLOCK(&V_divcbinfo); - div_destroy(); +#ifndef VIMAGE + div_destroy(NULL); +#endif EVENTHANDLER_DEREGISTER(maxsockets_change, ip_divert_event_tag); break; default: From 27a01c6c0c0c12bfcbe1afeef186070fcb53a35f Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Jan 2016 11:05:13 +0000 Subject: [PATCH 010/142] Try to catch a couple of SCTP teardown race conditions. Saw all the printfs already. Note: not sure the atomics are needed but without them, the condition would never trigger, and we'd still see panics (which could have been due to the insert race). Will work my way backwards in case this stays stable. Sponsored by: The FreeBSD Foundation --- sys/netinet/sctp_asconf.c | 12 +++++++++++- sys/netinet/sctp_bsd_addr.c | 4 ++-- sys/netinet/sctp_pcb.c | 26 ++++++++++++++++++++------ sys/netinet/sctp_structs.h | 2 +- sys/netinet/sctputil.c | 4 ++-- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 540cc65ff08c..2f82b75158b4 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -3248,6 +3248,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, } else { struct sctp_asconf_iterator *asc; struct sctp_laddr *wi; + int ret; SCTP_MALLOC(asc, struct sctp_asconf_iterator *, sizeof(struct sctp_asconf_iterator), @@ -3269,7 +3270,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, wi->action = type; atomic_add_int(&ifa->refcount, 1); LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); - (void)sctp_initiate_iterator(sctp_asconf_iterator_ep, + ret = sctp_initiate_iterator(sctp_asconf_iterator_ep, sctp_asconf_iterator_stcb, sctp_asconf_iterator_ep_end, SCTP_PCB_ANY_FLAGS, @@ -3277,6 +3278,15 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, SCTP_ASOC_ANY_STATE, (void *)asc, 0, sctp_asconf_iterator_end, inp, 0); + if (ret) { + SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n"); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT); + atomic_add_int(&ifa->refcount, -1); + SCTP_DECR_LADDR_COUNT(); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi); + SCTP_FREE(asc, SCTP_M_ASC_IT); + return (EFAULT); + } } return (0); } else { diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 0fc7d12da026..3dc600b5a4d8 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -77,7 +77,7 @@ struct iterator_control sctp_it_ctl; void sctp_wakeup_iterator(void) { - wakeup(&sctp_it_ctl.iterator_running); + wakeup(&sctp_it_ctl.iterator_flags); } static void @@ -86,7 +86,7 @@ sctp_iterator_thread(void *v SCTP_UNUSED) SCTP_IPI_ITERATOR_WQ_LOCK(); /* In FreeBSD this thread never terminates. */ for (;;) { - msleep(&sctp_it_ctl.iterator_running, + msleep(&sctp_it_ctl.iterator_flags, &sctp_it_ctl.ipi_iterator_wq_mtx, 0, "waiting_for_work", 0); sctp_iterator_worker(); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index f2acc4a4af6f..0dcc2a2b3c58 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -5929,6 +5929,7 @@ sctp_pcb_finish(void) struct sctp_tagblock *twait_block, *prev_twait_block; struct sctp_laddr *wi, *nwi; int i; + unsigned int r; struct sctp_iterator *it, *nit; if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { @@ -5943,8 +5944,6 @@ sctp_pcb_finish(void) * still add the ifdef to make it compile on old versions. */ retry: - while (sctp_it_ctl.iterator_running != 0) - DELAY(1); SCTP_IPI_ITERATOR_WQ_LOCK(); /* * sctp_iterator_worker() might be working on an it entry without @@ -5953,10 +5952,13 @@ sctp_pcb_finish(void) * avoid the race condition as sctp_iterator_worker() will have to * wait to re-aquire the lock. */ - if (sctp_it_ctl.cur_it != NULL || sctp_it_ctl.iterator_running != 0) { + r = atomic_fetchadd_int(&sctp_it_ctl.iterator_running, 0); + if (r != 0 || sctp_it_ctl.cur_it != NULL) { SCTP_IPI_ITERATOR_WQ_UNLOCK(); - printf("%s: Iterator running while we held the lock. Retry.\n", - __func__); + /* XXX-BZ make this a statistics variable. */ + printf("%s: Iterator running while we held the lock. Retry. " + "r=%u cur_it=%p\n", __func__, r, sctp_it_ctl.cur_it); + DELAY(10); goto retry; } TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { @@ -7022,6 +7024,11 @@ sctp_initiate_iterator(inp_func inpf, if (af == NULL) { return (-1); } + if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { + printf("%s: abort on initialize being %d\n", __func__, + SCTP_BASE_VAR(sctp_pcb_initialized)); + return (-1); + } SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator), SCTP_M_ITER); if (it == NULL) { @@ -7060,9 +7067,16 @@ sctp_initiate_iterator(inp_func inpf, } SCTP_IPI_ITERATOR_WQ_LOCK(); + if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { + SCTP_IPI_ITERATOR_WQ_UNLOCK(); + printf("%s: rollback on initialize being %d it=%p\n", __func__, + SCTP_BASE_VAR(sctp_pcb_initialized), it); + SCTP_FREE(it, SCTP_M_ITER); + return (-1); + } TAILQ_INSERT_TAIL(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); - if (sctp_it_ctl.iterator_running == 0) { + if (atomic_fetchadd_int(&sctp_it_ctl.iterator_running, 0) == 0) { sctp_wakeup_iterator(); } SCTP_IPI_ITERATOR_WQ_UNLOCK(); diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 875665023201..fa44e2f236fa 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -180,7 +180,7 @@ struct iterator_control { SCTP_PROCESS_STRUCT thread_proc; struct sctpiterators iteratorhead; struct sctp_iterator *cur_it; - uint32_t iterator_running; + volatile uint32_t iterator_running; uint32_t iterator_flags; }; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 4cf134bf733c..1e0c28062f05 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1421,7 +1421,7 @@ sctp_iterator_worker(void) /* This function is called with the WQ lock in place */ - sctp_it_ctl.iterator_running = 1; + atomic_store_rel_int(&sctp_it_ctl.iterator_running, 1); TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { sctp_it_ctl.cur_it = it; /* now lets work on this one */ @@ -1434,7 +1434,7 @@ sctp_iterator_worker(void) SCTP_IPI_ITERATOR_WQ_LOCK(); /* sa_ignore FREED_MEMORY */ } - sctp_it_ctl.iterator_running = 0; + atomic_store_rel_int(&sctp_it_ctl.iterator_running, 0); return; } From ce1d6b0efafff8148d0526190169631dd208a040 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Jan 2016 12:50:02 +0000 Subject: [PATCH 011/142] Use sctp_asconf_iterator_end() rather than doing the cleanup manually. Sponsored by: The FreeBSD Foundation --- sys/netinet/sctp_asconf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 2f82b75158b4..328b3b5bb504 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -3281,10 +3281,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, if (ret) { SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n"); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT); - atomic_add_int(&ifa->refcount, -1); - SCTP_DECR_LADDR_COUNT(); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi); - SCTP_FREE(asc, SCTP_M_ASC_IT); + sctp_asconf_iterator_end(asc); return (EFAULT); } } From 765cf0b82508b80df8d01ee5e805767af3f37e97 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Jan 2016 12:51:12 +0000 Subject: [PATCH 012/142] Try to prevent an address (assoc) leak in one way or another when sctp_initiate_iterator() fails. Sponsored by: The FreeBSD Foundation --- sys/netinet/sctputil.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 1e0c28062f05..91c0c9720b43 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1470,7 +1470,9 @@ sctp_handle_addr_wq(void) if (asc->cnt == 0) { SCTP_FREE(asc, SCTP_M_ASC_IT); } else { - (void)sctp_initiate_iterator(sctp_asconf_iterator_ep, + int ret; + + ret = sctp_initiate_iterator(sctp_asconf_iterator_ep, sctp_asconf_iterator_stcb, NULL, /* No ep end for boundall */ SCTP_PCB_FLAGS_BOUNDALL, @@ -1478,6 +1480,21 @@ sctp_handle_addr_wq(void) SCTP_ASOC_ANY_STATE, (void *)asc, 0, sctp_asconf_iterator_end, NULL, 0); + if (ret) { + SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n"); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT); + /* XXX-BZ Freeing if we are stopping or put back on the addr_wq. */ + if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { + sctp_asconf_iterator_end(asc); + } else { + SCTP_WQ_ADDR_LOCK(); + LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) { + LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); + } + SCTP_WQ_ADDR_UNLOCK(); + SCTP_FREE(asc, SCTP_M_ASC_IT); + } + } } } From d30c4f99edd0046a7ec44f5a54b32b2c91b2a292 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Jan 2016 12:52:08 +0000 Subject: [PATCH 013/142] Noisy comments (not sure if the static would be valid for all SCTP implementations). Reorder some cleanup just to match the general order we normally use. Sponsored by: The FreeBSD Foundation --- sys/netinet/sctp_pcb.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 0dcc2a2b3c58..a399b5189077 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -5524,7 +5524,7 @@ sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa) /* * insert an laddr entry with the given ifa for the desired list */ -int +/* static in FreeBSD */ int sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act) { struct sctp_laddr *laddr; @@ -5550,7 +5550,7 @@ sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act) /* * Remove an laddr entry from the local address list (on an assoc) */ -void +/* static in FreeBSD */ void sctp_remove_laddr(struct sctp_laddr *laddr) { @@ -6045,6 +6045,14 @@ sctp_pcb_finish(void) SCTP_WQ_ADDR_DESTROY(); + /* Get rid of other stuff too. */ + if (SCTP_BASE_INFO(sctp_asochash) != NULL) + SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark)); + if (SCTP_BASE_INFO(sctp_ephash) != NULL) + SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark)); + if (SCTP_BASE_INFO(sctp_tcpephash) != NULL) + SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark)); + SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep)); SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc)); SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr)); @@ -6054,13 +6062,7 @@ sctp_pcb_finish(void) SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq)); SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf)); SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf_ack)); - /* Get rid of other stuff to */ - if (SCTP_BASE_INFO(sctp_asochash) != NULL) - SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark)); - if (SCTP_BASE_INFO(sctp_ephash) != NULL) - SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark)); - if (SCTP_BASE_INFO(sctp_tcpephash) != NULL) - SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark)); + #if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE); #endif From 70a09847413b845c64cee1dc59eb8ccfce27eb26 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Jan 2016 12:56:28 +0000 Subject: [PATCH 014/142] sctp_asconf_iterator_end() has an unused second argument; compiles better if you add it. Sponsored by: The FreeBSD Foundation --- sys/netinet/sctp_asconf.c | 2 +- sys/netinet/sctputil.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 328b3b5bb504..bc1572a86ec5 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -3281,7 +3281,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, if (ret) { SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n"); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT); - sctp_asconf_iterator_end(asc); + sctp_asconf_iterator_end(asc, 0); return (EFAULT); } } diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 91c0c9720b43..24b4b870bde2 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1485,7 +1485,7 @@ sctp_handle_addr_wq(void) SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT); /* XXX-BZ Freeing if we are stopping or put back on the addr_wq. */ if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { - sctp_asconf_iterator_end(asc); + sctp_asconf_iterator_end(asc, 0); } else { SCTP_WQ_ADDR_LOCK(); LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) { From a5243af2622328f6be57d9c4c7b89792557a609a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 3 Feb 2016 21:56:51 +0000 Subject: [PATCH 015/142] Code duplication but rib_head is special. Not found an easy way to go back and harmize the use cases among RIB, IPFW, PF yet but it's also not the scope of this work. Prevents instant panics on teardown and frees the FIB bits again. Sponsored by: The FreeBSD Foundation --- sys/net/route.c | 14 ++++++++++++++ sys/netinet/in_rmx.c | 3 ++- sys/netinet6/in6_rmx.c | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index 8ad0e24158c2..45f479c80ed1 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -353,10 +353,24 @@ rt_table_init(int offset) return (rh); } +static int +rt_freeentry(struct radix_node *rn, void *arg) +{ + struct radix_head * const rnh = arg; + struct radix_node *x; + + x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh); + if (x != NULL) + R_Free(x); + return (0); +} + void rt_table_destroy(struct rib_head *rh) { + rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head); + /* Assume table is already empty */ rw_destroy(&rh->rib_lock); free(rh, M_RTABLE); diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index c2a09e474793..2cface409d7f 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -133,7 +133,8 @@ int in_detachhead(void **head, int off) { - return (rn_detachhead(head)); + rt_table_destroy((struct rib_head *)(*head)); + return (1); } #endif diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index 38b4bf2cc35b..102ad506de78 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -237,7 +237,9 @@ in6_detachhead(void **head, int off) { callout_drain(&V_rtq_mtutimer); - return (rn_detachhead(head)); + rt_table_destroy((struct rib_head *)(*head)); + + return (1); } #endif From d6233babae3541871813265e44a4d87ead7f4bc5 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 10 Feb 2016 04:43:08 +0000 Subject: [PATCH 016/142] Break out the shared bits of the arm intrng definitions into sys/intr.h; leave the machine dependent bits in sys/arm/. This is in preparation for MIPS INTRNG work. Submitted by: Stanislav Galabov --- sys/arm/include/intr.h | 88 +--------------------------- sys/sys/intr.h | 130 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 87 deletions(-) create mode 100644 sys/sys/intr.h diff --git a/sys/arm/include/intr.h b/sys/arm/include/intr.h index 83a39379527f..2afda95698df 100644 --- a/sys/arm/include/intr.h +++ b/sys/arm/include/intr.h @@ -49,93 +49,7 @@ #define NIRQ 1024 /* XXX - It should be an option. */ #endif -#ifdef notyet -#define INTR_SOLO INTR_MD1 -typedef int intr_irq_filter_t(void *arg, struct trapframe *tf); -#else -typedef int intr_irq_filter_t(void *arg); -#endif - -#define INTR_ISRC_NAMELEN (MAXCOMLEN + 1) - -typedef void intr_ipi_filter_t(void *arg); - -enum intr_isrc_type { - INTR_ISRCT_NAMESPACE, - INTR_ISRCT_FDT -}; - -#define INTR_ISRCF_REGISTERED 0x01 /* registered in a controller */ -#define INTR_ISRCF_PERCPU 0x02 /* per CPU interrupt */ -#define INTR_ISRCF_BOUND 0x04 /* bound to a CPU */ - -/* Interrupt source definition. */ -struct intr_irqsrc { - device_t isrc_dev; /* where isrc is mapped */ - intptr_t isrc_xref; /* device reference key */ - uintptr_t isrc_data; /* device data for isrc */ - u_int isrc_irq; /* unique identificator */ - enum intr_isrc_type isrc_type; /* how is isrc decribed */ - u_int isrc_flags; - char isrc_name[INTR_ISRC_NAMELEN]; - uint16_t isrc_nspc_type; - uint16_t isrc_nspc_num; - enum intr_trigger isrc_trig; - enum intr_polarity isrc_pol; - cpuset_t isrc_cpu; /* on which CPUs is enabled */ - u_int isrc_index; - u_long * isrc_count; - u_int isrc_handlers; - struct intr_event * isrc_event; - intr_irq_filter_t * isrc_filter; - intr_ipi_filter_t * isrc_ipifilter; - void * isrc_arg; -#ifdef FDT - u_int isrc_ncells; - pcell_t isrc_cells[]; /* leave it last */ -#endif -}; - -void intr_irq_set_name(struct intr_irqsrc *isrc, const char *fmt, ...) - __printflike(2, 3); - -void intr_irq_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf); - -#define INTR_IRQ_NSPC_NONE 0 -#define INTR_IRQ_NSPC_PLAIN 1 -#define INTR_IRQ_NSPC_IRQ 2 -#define INTR_IRQ_NSPC_IPI 3 - -u_int intr_namespace_map_irq(device_t dev, uint16_t type, uint16_t num); -#ifdef FDT -u_int intr_fdt_map_irq(phandle_t, pcell_t *, u_int); -#endif - -int intr_pic_register(device_t dev, intptr_t xref); -int intr_pic_unregister(device_t dev, intptr_t xref); -int intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter, - void *arg, u_int ipicount); - -int intr_irq_add_handler(device_t dev, driver_filter_t, driver_intr_t, void *, - u_int, int, void **); -int intr_irq_remove_handler(device_t dev, u_int, void *); -int intr_irq_config(u_int, enum intr_trigger, enum intr_polarity); -int intr_irq_describe(u_int, void *, const char *); - -u_int intr_irq_next_cpu(u_int current_cpu, cpuset_t *cpumask); - -#ifdef SMP -int intr_irq_bind(u_int, int); - -void intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf); - -#define AISHF_NOALLOC 0x0001 - -int intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter, - void *arg, u_int flags); - -void intr_pic_init_secondary(void); -#endif +#include #else /* ARM_INTRNG */ diff --git a/sys/sys/intr.h b/sys/sys/intr.h new file mode 100644 index 000000000000..27310a48bf5e --- /dev/null +++ b/sys/sys/intr.h @@ -0,0 +1,130 @@ +/* $NetBSD: intr.h,v 1.7 2003/06/16 20:01:00 thorpej Exp $ */ + +/*- + * Copyright (c) 1997 Mark Brinicombe. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef _SYS_INTR_H_ +#define _SYS_INTR_H_ + +#ifdef notyet +#define INTR_SOLO INTR_MD1 +typedef int intr_irq_filter_t(void *arg, struct trapframe *tf); +#else +typedef int intr_irq_filter_t(void *arg); +#endif + +#define INTR_ISRC_NAMELEN (MAXCOMLEN + 1) + +typedef void intr_ipi_filter_t(void *arg); + +enum intr_isrc_type { + INTR_ISRCT_NAMESPACE, + INTR_ISRCT_FDT +}; + +#define INTR_ISRCF_REGISTERED 0x01 /* registered in a controller */ +#define INTR_ISRCF_PERCPU 0x02 /* per CPU interrupt */ +#define INTR_ISRCF_BOUND 0x04 /* bound to a CPU */ + +/* Interrupt source definition. */ +struct intr_irqsrc { + device_t isrc_dev; /* where isrc is mapped */ + intptr_t isrc_xref; /* device reference key */ + uintptr_t isrc_data; /* device data for isrc */ + u_int isrc_irq; /* unique identificator */ + enum intr_isrc_type isrc_type; /* how is isrc decribed */ + u_int isrc_flags; + char isrc_name[INTR_ISRC_NAMELEN]; + uint16_t isrc_nspc_type; + uint16_t isrc_nspc_num; + enum intr_trigger isrc_trig; + enum intr_polarity isrc_pol; + cpuset_t isrc_cpu; /* on which CPUs is enabled */ + u_int isrc_index; + u_long * isrc_count; + u_int isrc_handlers; + struct intr_event * isrc_event; + intr_irq_filter_t * isrc_filter; + intr_ipi_filter_t * isrc_ipifilter; + void * isrc_arg; +#ifdef FDT + u_int isrc_ncells; + pcell_t isrc_cells[]; /* leave it last */ +#endif +}; + +void intr_irq_set_name(struct intr_irqsrc *isrc, const char *fmt, ...) + __printflike(2, 3); + +void intr_irq_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf); + +#define INTR_IRQ_NSPC_NONE 0 +#define INTR_IRQ_NSPC_PLAIN 1 +#define INTR_IRQ_NSPC_IRQ 2 +#define INTR_IRQ_NSPC_IPI 3 + +u_int intr_namespace_map_irq(device_t dev, uint16_t type, uint16_t num); +#ifdef FDT +u_int intr_fdt_map_irq(phandle_t, pcell_t *, u_int); +#endif + +int intr_pic_register(device_t dev, intptr_t xref); +int intr_pic_unregister(device_t dev, intptr_t xref); +int intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter, + void *arg, u_int ipicount); + +int intr_irq_add_handler(device_t dev, driver_filter_t, driver_intr_t, void *, + u_int, int, void **); +int intr_irq_remove_handler(device_t dev, u_int, void *); +int intr_irq_config(u_int, enum intr_trigger, enum intr_polarity); +int intr_irq_describe(u_int, void *, const char *); + +u_int intr_irq_next_cpu(u_int current_cpu, cpuset_t *cpumask); + +#ifdef SMP +int intr_irq_bind(u_int, int); + +void intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf); + +#define AISHF_NOALLOC 0x0001 + +int intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter, + void *arg, u_int flags); + +void intr_pic_init_secondary(void); + +#endif +#endif /* _SYS_INTR_H */ From 39d9a52d997363b33f2d67c54e01313e87b201a4 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Wed, 10 Feb 2016 04:56:38 +0000 Subject: [PATCH 017/142] Add `stats' command to get ng_bridge(4) stats --- share/examples/jails/jng | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 445803db1ec2..ee850ea5cadc 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -154,6 +154,7 @@ usage() show \ show1 \ shutdown \ + stats \ ; do eval usage=\"\$jng_${action}_usage\" [ "$usage" ] || continue @@ -414,6 +415,39 @@ jng_shutdown() jng_show "$name" | xargs -rn1 -I eiface ngctl shutdown eiface: } +jng_stats_usage="stats NAME" +jng_stats_descr="Show ng_bridge link statistics for NAME interfaces" +jng_stats() +{ + local OPTIND=1 OPTARG flag + while getopts "" flag; do + case "$flag" in + *) action_usage stats # NOTREACHED + esac + done + shift $(( $OPTIND -1 )) + local name="$1" + [ "${name:-x}" = "${name#*[!0-9a-zA-Z_]}" -a $# -eq 1 ] || + action_usage stats # NOTREACHED + mustberoot_to_continue + for eiface in $( jng_show "$name" ); do + echo "$eiface:" + ngctl show $eiface: | awk ' + $3 == "bridge" && $5 ~ /^link/ { + bridge = $2 + link = substr($5, 5) + system(sprintf("ngctl msg %s: getstats %u", + bridge, link)) + }' | fmt 2 | awk ' + /=/ && fl = index($0, "=") { + printf "%20s = %s\n", + substr($0, 0, fl-1), + substr($0, 0, fl+1) + } + ' # END-QUOTE + done +} + ############################################################ MAIN # From 4bc7e098c7edf613fb4215f5e3edda78bf5c8d2d Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Wed, 10 Feb 2016 08:03:10 +0000 Subject: [PATCH 018/142] Correct PCI device description. Submitted by: Dmitry Luhtionov --- sys/dev/usb/controller/ehci_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c index 9b862a5a0181..3a6f7253a3ef 100644 --- a/sys/dev/usb/controller/ehci_pci.c +++ b/sys/dev/usb/controller/ehci_pci.c @@ -172,7 +172,7 @@ ehci_pci_match(device_t self) return ("Intel Lynx Point LP USB 2.0 controller USB"); case 0x00e01033: - return ("NEC uPD 720100 USB 2.0 controller"); + return ("NEC uPD 72010x USB 2.0 controller"); case 0x006810de: return "NVIDIA nForce2 USB 2.0 controller"; From 907fe11655521170cc0a0e46b69dfe359795bbf0 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 09:19:29 +0000 Subject: [PATCH 019/142] Update of the Allwinner drivers to: * Use the Linux compat string * Use EARLY_DRIVER_MODULE to attach at the right time * Add a generic A10 kernel config file * A20 now use generic_timer * Add two new dts files for Olimex boards * Update our custom DTS file for A10 and A20 to use the same compatible property names as the vendor ones. Submitted by: Emmanuel Vadot Differential Revision: https://reviews.freebsd.org/D4792 --- sys/arm/allwinner/a10_clk.c | 5 +- sys/arm/allwinner/a10_common.c | 2 +- sys/arm/allwinner/a10_ehci.c | 12 ++- sys/arm/allwinner/a10_gpio.c | 12 ++- sys/arm/allwinner/a10_mmc.c | 9 +- sys/arm/allwinner/a10_wdog.c | 2 +- sys/arm/allwinner/a20/a20_cpu_cfg.c | 3 +- sys/arm/allwinner/aintc.c | 11 +- sys/arm/allwinner/files.a10 | 1 + sys/arm/allwinner/files.allwinner | 1 - sys/arm/allwinner/if_emac.c | 2 +- sys/arm/allwinner/timer.c | 22 ++-- sys/arm/conf/A10 | 105 ++++++++++++++++++++ sys/arm/conf/A20 | 6 +- sys/arm64/arm64/swtch.S | 13 ++- sys/boot/fdt/dts/arm/bananapi.dts | 5 +- sys/boot/fdt/dts/arm/cubieboard2.dts | 76 ++------------ sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts | 40 ++++++++ sys/boot/fdt/dts/arm/olinuxino-lime.dts | 40 ++++++++ sys/boot/fdt/dts/arm/sun4i-a10.dtsi | 12 +-- sys/boot/fdt/dts/arm/sun7i-a20.dtsi | 58 +++++++---- sys/modules/dtb/allwinner/Makefile | 4 +- 22 files changed, 308 insertions(+), 133 deletions(-) create mode 100644 sys/arm/conf/A10 create mode 100644 sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts create mode 100644 sys/boot/fdt/dts/arm/olinuxino-lime.dts diff --git a/sys/arm/allwinner/a10_clk.c b/sys/arm/allwinner/a10_clk.c index eab95b0fe07f..d49e6d02dd56 100644 --- a/sys/arm/allwinner/a10_clk.c +++ b/sys/arm/allwinner/a10_clk.c @@ -109,7 +109,8 @@ static driver_t a10_ccm_driver = { static devclass_t a10_ccm_devclass; -DRIVER_MODULE(a10_ccm, simplebus, a10_ccm_driver, a10_ccm_devclass, 0, 0); +EARLY_DRIVER_MODULE(a10_ccm, simplebus, a10_ccm_driver, a10_ccm_devclass, 0, 0, + BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE); int a10_clk_usb_activate(void) @@ -200,7 +201,7 @@ a10_clk_gmac_activate(phandle_t node) /* Set GMAC mode. */ reg_value = CCM_GMAC_CLK_MII; - if (OF_getprop_alloc(node, "phy-type", 1, (void **)&phy_type) > 0) { + if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type) > 0) { if (strcasecmp(phy_type, "rgmii") == 0) reg_value = CCM_GMAC_CLK_RGMII | CCM_GMAC_MODE_RGMII; else if (strcasecmp(phy_type, "rgmii-bpi") == 0) { diff --git a/sys/arm/allwinner/a10_common.c b/sys/arm/allwinner/a10_common.c index dacb97ede707..d20853a0af40 100644 --- a/sys/arm/allwinner/a10_common.c +++ b/sys/arm/allwinner/a10_common.c @@ -50,7 +50,7 @@ fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, { int offset; - if (fdt_is_compatible(node, "allwinner,sun4i-ic")) + if (fdt_is_compatible(node, "allwinner,sun4i-a10-ic")) offset = 0; else if (fdt_is_compatible(node, "arm,gic")) offset = 32; diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c index 91f79d39c48d..5dbcdcba7b36 100644 --- a/sys/arm/allwinner/a10_ehci.c +++ b/sys/arm/allwinner/a10_ehci.c @@ -43,10 +43,10 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include -#include +#include #include #include @@ -90,6 +90,12 @@ static device_detach_t a10_ehci_detach; bs_r_1_proto(reversed); bs_w_1_proto(reversed); +static struct ofw_compat_data compat_data[] = { + {"allwinner,sun4i-a10-ehci", 1}, + {"allwinner,sun7i-a20-ehci", 1}, + {NULL, 0} +}; + static int a10_ehci_probe(device_t self) { @@ -97,7 +103,7 @@ a10_ehci_probe(device_t self) if (!ofw_bus_status_okay(self)) return (ENXIO); - if (!ofw_bus_is_compatible(self, "allwinner,usb-ehci")) + if (ofw_bus_search_compatible(self, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(self, EHCI_HC_DEVSTR); diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c index e3e247e5881c..cda2c7bd32db 100644 --- a/sys/arm/allwinner/a10_gpio.c +++ b/sys/arm/allwinner/a10_gpio.c @@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$"); #define A10_GPIO_INPUT 0 #define A10_GPIO_OUTPUT 1 +static struct ofw_compat_data compat_data[] = { + {"allwinner,sun4i-a10-pinctrl", 1}, + {"allwinner,sun7i-a20-pinctrl", 1}, + {NULL, 0} +}; + struct a10_gpio_softc { device_t sc_dev; device_t sc_busdev; @@ -373,7 +379,7 @@ a10_gpio_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-gpio")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Allwinner GPIO controller"); @@ -493,7 +499,9 @@ static driver_t a10_gpio_driver = { sizeof(struct a10_gpio_softc), }; -DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0); +EARLY_DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); + int a10_gpio_ethernet_activate(uint32_t func) diff --git a/sys/arm/allwinner/a10_mmc.c b/sys/arm/allwinner/a10_mmc.c index eee162168dd1..c4bb6df40f72 100644 --- a/sys/arm/allwinner/a10_mmc.c +++ b/sys/arm/allwinner/a10_mmc.c @@ -62,6 +62,12 @@ static int a10_mmc_pio_mode = 0; TUNABLE_INT("hw.a10.mmc.pio_mode", &a10_mmc_pio_mode); +static struct ofw_compat_data compat_data[] = { + {"allwinner,sun4i-a10-mmc", 1}, + {"allwinner,sun5i-a13-mmc", 1}, + {NULL, 0} +}; + struct a10_mmc_softc { bus_space_handle_t a10_bsh; bus_space_tag_t a10_bst; @@ -123,8 +129,9 @@ a10_mmc_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-mmc")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); + device_set_desc(dev, "Allwinner Integrated MMC/SD controller"); return (BUS_PROBE_DEFAULT); diff --git a/sys/arm/allwinner/a10_wdog.c b/sys/arm/allwinner/a10_wdog.c index 40609b00176c..1c0dd00e11fd 100644 --- a/sys/arm/allwinner/a10_wdog.c +++ b/sys/arm/allwinner/a10_wdog.c @@ -95,7 +95,7 @@ a10wd_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_is_compatible(dev, "allwinner,sun4i-wdt")) { + if (ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-wdt")) { device_set_desc(dev, "Allwinner A10 Watchdog"); return (BUS_PROBE_DEFAULT); } diff --git a/sys/arm/allwinner/a20/a20_cpu_cfg.c b/sys/arm/allwinner/a20/a20_cpu_cfg.c index ed0345af59c0..a0bdb5a0b46e 100644 --- a/sys/arm/allwinner/a20/a20_cpu_cfg.c +++ b/sys/arm/allwinner/a20/a20_cpu_cfg.c @@ -117,7 +117,8 @@ static driver_t a20_cpu_cfg_driver = { static devclass_t a20_cpu_cfg_devclass; -DRIVER_MODULE(a20_cpu_cfg, simplebus, a20_cpu_cfg_driver, a20_cpu_cfg_devclass, 0, 0); +EARLY_DRIVER_MODULE(a20_cpu_cfg, simplebus, a20_cpu_cfg_driver, a20_cpu_cfg_devclass, 0, 0, + BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); uint64_t a20_read_counter64(void) diff --git a/sys/arm/allwinner/aintc.c b/sys/arm/allwinner/aintc.c index ed5f1fc5ec17..a15ead18ad44 100644 --- a/sys/arm/allwinner/aintc.c +++ b/sys/arm/allwinner/aintc.c @@ -79,6 +79,12 @@ __FBSDID("$FreeBSD$"); #define SW_INT_ENABLE_REG(_b) (0x40 + ((_b) * 4)) #define SW_INT_MASK_REG(_b) (0x50 + ((_b) * 4)) +static struct ofw_compat_data compat_data[] = { + {"allwinner,sun4i-a10-ic", 1}, + {"allwinner,sun7i-a20-sc-nmi", 1}, + {NULL, 0} +}; + struct a10_aintc_softc { device_t sc_dev; struct resource * aintc_res; @@ -101,7 +107,7 @@ a10_aintc_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-ic")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "A10 AINTC Interrupt Controller"); return (BUS_PROBE_DEFAULT); @@ -158,7 +164,8 @@ static driver_t a10_aintc_driver = { static devclass_t a10_aintc_devclass; -DRIVER_MODULE(aintc, simplebus, a10_aintc_driver, a10_aintc_devclass, 0, 0); +EARLY_DRIVER_MODULE(aintc, simplebus, a10_aintc_driver, a10_aintc_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_FIRST); int arm_get_next_irq(int last_irq) diff --git a/sys/arm/allwinner/files.a10 b/sys/arm/allwinner/files.a10 index 9f28fc406f2d..44fe55f1b499 100644 --- a/sys/arm/allwinner/files.a10 +++ b/sys/arm/allwinner/files.a10 @@ -1,3 +1,4 @@ # $FreeBSD$ arm/allwinner/aintc.c standard +arm/allwinner/timer.c standard diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index 8606d914f4b3..5157850ada89 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -12,5 +12,4 @@ arm/allwinner/a10_wdog.c standard arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/allwinner_machdep.c standard arm/allwinner/if_emac.c optional emac -arm/allwinner/timer.c standard #arm/allwinner/console.c standard diff --git a/sys/arm/allwinner/if_emac.c b/sys/arm/allwinner/if_emac.c index 18aeb8fc14ba..22422fefdb68 100644 --- a/sys/arm/allwinner/if_emac.c +++ b/sys/arm/allwinner/if_emac.c @@ -756,7 +756,7 @@ static int emac_probe(device_t dev) { - if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-emac")) + if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-emac")) return (ENXIO); device_set_desc(dev, "A10/A20 EMAC ethernet controller"); diff --git a/sys/arm/allwinner/timer.c b/sys/arm/allwinner/timer.c index 7c2a34063145..d25aa3c354e3 100644 --- a/sys/arm/allwinner/timer.c +++ b/sys/arm/allwinner/timer.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #include -#include "a20/a20_cpu_cfg.h" +#include /** * Timer registers addr @@ -84,7 +84,6 @@ struct a10_timer_softc { uint32_t sc_period; uint32_t timer0_freq; struct eventtimer et; - uint8_t sc_timer_type; /* 0 for A10, 1 for A20 */ }; int a10_timer_get_timerfreq(struct a10_timer_softc *); @@ -127,10 +126,6 @@ timer_read_counter64(void) { uint32_t lo, hi; - /* In case of A20 get appropriate counter info */ - if (a10_timer_sc->sc_timer_type) - return (a20_read_counter64()); - /* Latch counter, wait for it to be ready to read. */ timer_write_4(a10_timer_sc, CNT64_CTRL_REG, CNT64_RL_EN); while (timer_read_4(a10_timer_sc, CNT64_CTRL_REG) & CNT64_RL_EN) @@ -146,14 +141,16 @@ static int a10_timer_probe(device_t dev) { struct a10_timer_softc *sc; + u_int soc_family; sc = device_get_softc(dev); - if (ofw_bus_is_compatible(dev, "allwinner,sun4i-timer")) - sc->sc_timer_type = 0; - else if (ofw_bus_is_compatible(dev, "allwinner,sun7i-timer")) - sc->sc_timer_type = 1; - else + if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-timer")) + return (ENXIO); + + soc_family = allwinner_soc_family(); + if (soc_family != ALLWINNERSOC_SUN4I && + soc_family != ALLWINNERSOC_SUN5I) return (ENXIO); device_set_desc(dev, "Allwinner A10/A20 timer"); @@ -352,7 +349,8 @@ static driver_t a10_timer_driver = { static devclass_t a10_timer_devclass; -DRIVER_MODULE(a10_timer, simplebus, a10_timer_driver, a10_timer_devclass, 0, 0); +EARLY_DRIVER_MODULE(a10_timer, simplebus, a10_timer_driver, a10_timer_devclass, 0, 0, + BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE); void DELAY(int usec) diff --git a/sys/arm/conf/A10 b/sys/arm/conf/A10 new file mode 100644 index 000000000000..31073c723e11 --- /dev/null +++ b/sys/arm/conf/A10 @@ -0,0 +1,105 @@ +# +# A10 -- Custom configuration for the AllWinner A10 SoC +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +ident A10 + +include "std.armv6" +include "../allwinner/std.a10" + +options HZ=100 +options SCHED_4BSD # 4BSD scheduler +options PLATFORM + +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options ALT_BREAK_TO_DEBUGGER +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options DIAGNOSTIC + +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=emac0 + +# MMC/SD/SDIO Card slot support +device mmc # mmc/sd bus +device mmcsd # mmc/sd flash cards + +# ATA controllers +device ahci # AHCI-compatible SATA controllers +#device ata # Legacy ATA/SATA controllers + +# Console and misc +device uart +device uart_ns8250 +device pty +device snp +device md +device random # Entropy device + +# I2C support +#device iicbus +#device iic + +# GPIO +device gpio +device gpioled + +device scbus # SCSI bus (required for ATA/SCSI) +device da # Direct Access (disks) +device pass # Passthrough device (direct ATA/SCSI access) + +# USB support +options USB_HOST_ALIGN=64 # Align usb buffers to cache line size. +device usb +options USB_DEBUG +#options USB_REQ_DEBUG +#options USB_VERBOSE +#device uhci +#device ohci +device ehci + +device umass + +# Ethernet +device loop +device ether +device mii +device bpf + +device emac + +# USB ethernet support, requires miibus +device miibus + +# Flattened Device Tree +options FDT # Configure using FDT/DTB data +makeoptions MODULES_EXTRA=dtb/allwinner diff --git a/sys/arm/conf/A20 b/sys/arm/conf/A20 index 353c5ece820f..cd0726454194 100644 --- a/sys/arm/conf/A20 +++ b/sys/arm/conf/A20 @@ -52,12 +52,12 @@ options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=dwc0 -# Boot device is 2nd slice on MMC/SD card -options ROOTDEVNAME=\"ufs:/dev/da0s2\" - # Interrupt controller device gic +# ARM Generic Timer +device generic_timer + # MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S index 3175e879114d..981dfebeb738 100644 --- a/sys/arm64/arm64/swtch.S +++ b/sys/arm64/arm64/swtch.S @@ -129,12 +129,6 @@ END(cpu_throw) * x3 to x7, x16 and x17 are caller saved */ ENTRY(cpu_switch) - /* Store the new curthread */ - str x1, [x18, #PC_CURTHREAD] - /* And the new pcb */ - ldr x4, [x1, #TD_PCB] - str x4, [x18, #PC_CURPCB] - /* * Save the old context. */ @@ -174,10 +168,15 @@ ENTRY(cpu_switch) mov x0, x19 #endif + /* Store the new curthread */ + str x1, [x18, #PC_CURTHREAD] + /* - * Restore the saved context. + * Restore the saved context and save it as the curpcb. */ ldr x4, [x1, #TD_PCB] + str x4, [x18, #PC_CURPCB] + /* * TODO: We may need to flush the cache here if switching diff --git a/sys/boot/fdt/dts/arm/bananapi.dts b/sys/boot/fdt/dts/arm/bananapi.dts index ee5ec76cbfab..b86da4559e47 100644 --- a/sys/boot/fdt/dts/arm/bananapi.dts +++ b/sys/boot/fdt/dts/arm/bananapi.dts @@ -28,7 +28,8 @@ /dts-v1/; -/include/ "sun7i-a20.dtsi" +#include "sun7i-a20.dtsi" + #include @@ -65,7 +66,7 @@ }; gmac@01c50000 { - phy-type = "rgmii-bpi"; + phy-mode = "rgmii-bpi"; status = "okay"; }; diff --git a/sys/boot/fdt/dts/arm/cubieboard2.dts b/sys/boot/fdt/dts/arm/cubieboard2.dts index 480df660e733..35e38362971f 100644 --- a/sys/boot/fdt/dts/arm/cubieboard2.dts +++ b/sys/boot/fdt/dts/arm/cubieboard2.dts @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 Ganbold Tsagaankhuu + * Copyright (c) 2016 Emmanuel Vadot * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,78 +23,19 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * $FreeBSD$ */ -/dts-v1/; - -/include/ "sun7i-a20.dtsi" - -#include +#include "sun7i-a20-cubieboard2.dts" / { - model = "Cubietech Cubieboard2"; - - memory { - device_type = "memory"; - reg = < 0x40000000 0x40000000 >; /* 1GB RAM */ - }; - - aliases { - soc = &SOC; - UART0 = &UART0; - }; - - SOC: a20 { - - usb1: usb@01c14000 { - status = "okay"; + soc@01c00000 { + ccm@01c20000 { + compatible = "allwinner,sun4i-ccm"; + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x01c20000 0x400 >; }; - - usb2: usb@01c1c000 { - status = "okay"; - }; - - UART0: serial@01c28000 { - status = "okay"; - }; - - mmc0: mmc@01c0f000 { - status = "okay"; - }; - - emac@01c0b000 { - status = "okay"; - }; - - gmac@01c50000 { - status = "okay"; - }; - - ahci: sata@01c18000 { - status = "okay"; - }; - }; - - leds { - compatible = "gpio-leds"; - - blue { - label = "cubieboard2:blue:usr"; - gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; - }; - - green { - label = "cubieboard2:green:usr"; - gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; - }; - }; - - chosen { - bootargs = "-v"; - stdin = "UART0"; - stdout = "UART0"; }; }; - diff --git a/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts new file mode 100644 index 000000000000..ffe0777b5c06 --- /dev/null +++ b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "sun7i-a20-olimex-som-evb.dts" + +/ { + soc@01c00000 { + ccm@01c20000 { + compatible = "allwinner,sun4i-ccm"; + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x01c20000 0x400 >; + }; + }; +}; diff --git a/sys/boot/fdt/dts/arm/olinuxino-lime.dts b/sys/boot/fdt/dts/arm/olinuxino-lime.dts new file mode 100644 index 000000000000..b965788991ea --- /dev/null +++ b/sys/boot/fdt/dts/arm/olinuxino-lime.dts @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "sun4i-a10-olinuxino-lime.dts" + +/ { + soc@01c00000 { + ccm@01c20000 { + compatible = "allwinner,sun4i-ccm"; + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x01c20000 0x400 >; + }; + }; +}; diff --git a/sys/boot/fdt/dts/arm/sun4i-a10.dtsi b/sys/boot/fdt/dts/arm/sun4i-a10.dtsi index 8b32725c8c6c..6a53c59fc24a 100644 --- a/sys/boot/fdt/dts/arm/sun4i-a10.dtsi +++ b/sys/boot/fdt/dts/arm/sun4i-a10.dtsi @@ -45,7 +45,7 @@ bus-frequency = <0>; AINTC: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; + compatible = "allwinner,sun4i-a10-ic"; interrupt-controller; #address-cells = <0>; #interrupt-cells = <1>; @@ -67,7 +67,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; interrupts = < 22 >; interrupt-parent = <&AINTC>; @@ -82,7 +82,7 @@ GPIO: gpio@01c20800 { #gpio-cells = <3>; - compatible = "allwinner,sun4i-gpio"; + compatible = "allwinner,sun4i-a10-pinctrl"; gpio-controller; reg =< 0x01c20800 0x400 >; interrupts = < 28 >; @@ -90,14 +90,14 @@ }; usb1: usb@01c14000 { - compatible = "allwinner,usb-ehci", "usb-ehci"; + compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; reg = <0x01c14000 0x1000>; interrupts = < 39 >; interrupt-parent = <&AINTC>; }; usb2: usb@01c1c000 { - compatible = "allwinner,usb-ehci", "usb-ehci"; + compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; reg = <0x01c1c000 0x1000>; interrupts = < 40 >; interrupt-parent = <&AINTC>; @@ -130,7 +130,7 @@ }; emac@01c0b000 { - compatible = "allwinner,sun4i-emac"; + compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; interrupts = <55>; interrupt-parent = <&AINTC>; diff --git a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi index b559e5ef7e32..4d1742cd51a4 100644 --- a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi +++ b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi @@ -26,6 +26,8 @@ * $FreeBSD$ */ +#include + / { compatible = "allwinner,sun7i-a20"; #address-cells = <1>; @@ -37,6 +39,14 @@ soc = &SOC; }; + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + }; + SOC: a20 { #address-cells = <1>; #size-cells = <1>; @@ -47,9 +57,12 @@ GIC: interrupt-controller@01c81000 { compatible = "arm,gic"; reg = <0x01c81000 0x1000>, /* Distributor Registers */ - <0x01c82000 0x0100>; /* CPU Interface Registers */ + <0x01c82000 0x0100>, /* CPU Interface Registers */ + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <3>; + interrupts = ; }; sramc@01c00000 { @@ -74,53 +87,59 @@ }; timer@01c20c00 { - compatible = "allwinner,sun7i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; - interrupts = < 22 >; + interrupts = , + , + , + , + , + ; interrupt-parent = <&GIC>; clock-frequency = < 24000000 >; }; watchdog@01c20c90 { - compatible = "allwinner,sun4i-wdt"; + compatible = "allwinner,sun4i-a10-wdt"; reg = <0x01c20c90 0x10>; }; pio: gpio@01c20800 { #gpio-cells = <3>; - compatible = "allwinner,sun4i-gpio"; + compatible = "allwinner,sun7i-a20-pinctrl"; gpio-controller; reg =< 0x01c20800 0x400 >; - interrupts = < 28 >; + interrupts = ; + interrupt-controller; + #interrupt-cells = <2>; interrupt-parent = <&GIC>; }; usb1: usb@01c14000 { - compatible = "allwinner,usb-ehci", "usb-ehci"; + compatible = "allwinner,sun7i-a20-ehci", "generic-ehci"; reg = <0x01c14000 0x1000>; - interrupts = < 39 >; + interrupts = ; interrupt-parent = <&GIC>; }; usb2: usb@01c1c000 { - compatible = "allwinner,usb-ehci", "usb-ehci"; + compatible = "allwinner,sun7i-a20-ehci", "generic-ehci"; reg = <0x01c1c000 0x1000>; - interrupts = < 40 >; + interrupts = ; interrupt-parent = <&GIC>; }; mmc0: mmc@01c0f000 { - compatible = "allwinner,sun4i-a10-mmc"; + compatible = "allwinner,sun5i-a13-mmc"; reg = <0x01c0f000 0x1000>; - interrupts = <32>; - interrupt-parent = <&GIC>; + interrupts = ; status = "disabled"; }; sata@01c18000 { compatible = "allwinner,sun4i-a10-ahci"; reg = <0x01c18000 0x1000>; - interrupts = <56>; + interrupts = ; interrupt-parent = <&GIC>; status = "disabled"; }; @@ -129,16 +148,15 @@ compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; reg-shift = <2>; - interrupts = <1>; - interrupt-parent = <&GIC>; + interrupts = ; current-speed = <115200>; clock-frequency = < 24000000 >; }; emac@01c0b000 { - compatible = "allwinner,sun4i-emac"; + compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; - interrupts = <55>; + interrupts = ; interrupt-parent = <&GIC>; status = "disabled"; }; @@ -146,7 +164,7 @@ gmac@01c50000 { compatible = "allwinner,sun7i-a20-gmac"; reg = <0x01c50000 0x10000>; - interrupts = <85>; + interrupts = ; interrupt-parent = <&GIC>; snps,pbl = <2>; snps,fixed-burst; diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile index 660ca97d7a64..80ac333d2f15 100644 --- a/sys/modules/dtb/allwinner/Makefile +++ b/sys/modules/dtb/allwinner/Makefile @@ -3,6 +3,8 @@ DTS= \ bananapi.dts \ cubieboard.dts \ - cubieboard2.dts + cubieboard2.dts \ + olimex-a20-som-evb.dts \ + olinuxino-lime.dts .include From fde0af719b0102d03ca7af7c5df3ce0ced7a5db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20E=C3=9Fer?= Date: Wed, 10 Feb 2016 09:40:45 +0000 Subject: [PATCH 020/142] Remove O_SYNC from the options passed to dbmopen(). The services db is created as a temporary file that is moved over the existing file after completion. Thus there is no need to immediately flush all created db records to the temporary file. This speeds up creation of the services db by a factor of 500 on my ZFS based /var/db filesytem (from 110 seconds to 0.235 seconds). MFC after: 1 week --- usr.sbin/services_mkdb/services_mkdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/services_mkdb/services_mkdb.c b/usr.sbin/services_mkdb/services_mkdb.c index 9ea66deed689..c928ea995837 100644 --- a/usr.sbin/services_mkdb/services_mkdb.c +++ b/usr.sbin/services_mkdb/services_mkdb.c @@ -141,7 +141,7 @@ main(int argc, char *argv[]) err(1, "Cannot install exit handler"); (void)snprintf(tname, sizeof(tname), "%s.tmp", dbname); - db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL | O_SYNC, + db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, &hinfo); if (!db) err(1, "Error opening temporary database `%s'", tname); From d664515e686723a9c7227e69dd0a44c1e15e9c2d Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 10:28:33 +0000 Subject: [PATCH 021/142] Revert an arm64 change that sneaked in with r295464. --- sys/arm64/arm64/swtch.S | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S index 981dfebeb738..3175e879114d 100644 --- a/sys/arm64/arm64/swtch.S +++ b/sys/arm64/arm64/swtch.S @@ -129,6 +129,12 @@ END(cpu_throw) * x3 to x7, x16 and x17 are caller saved */ ENTRY(cpu_switch) + /* Store the new curthread */ + str x1, [x18, #PC_CURTHREAD] + /* And the new pcb */ + ldr x4, [x1, #TD_PCB] + str x4, [x18, #PC_CURPCB] + /* * Save the old context. */ @@ -168,15 +174,10 @@ ENTRY(cpu_switch) mov x0, x19 #endif - /* Store the new curthread */ - str x1, [x18, #PC_CURTHREAD] - /* - * Restore the saved context and save it as the curpcb. + * Restore the saved context. */ ldr x4, [x1, #TD_PCB] - str x4, [x18, #PC_CURPCB] - /* * TODO: We may need to flush the cache here if switching From 1e76f8b89527a3aa83ca71c4ca3c4b2be3b28074 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Wed, 10 Feb 2016 12:14:56 +0000 Subject: [PATCH 022/142] sfxge: implement SIOCGI2C to read information from phy modules The IOCTL is used by 'ifconfig -v' to show SFP+/QSFP+ information including inventory information and dianostics (temperature, light levels, voltage etc). Reviewed by: gnn,melifaro Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D5240 --- sys/dev/sfxge/common/efx.h | 8 ++ sys/dev/sfxge/common/efx_mcdi.c | 212 ++++++++++++++++++++++++++++++++ sys/dev/sfxge/common/efx_mcdi.h | 8 ++ sys/dev/sfxge/common/efx_phy.c | 32 +++++ sys/dev/sfxge/sfxge.c | 24 ++++ 5 files changed, 284 insertions(+) diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h index ce705465ddf7..14374cfb75bd 100644 --- a/sys/dev/sfxge/common/efx.h +++ b/sys/dev/sfxge/common/efx.h @@ -879,6 +879,14 @@ efx_phy_media_type_get( __in efx_nic_t *enp, __out efx_phy_media_type_t *typep); +extern efx_rc_t +efx_phy_module_get_info( + __in efx_nic_t *enp, + __in uint8_t dev_addr, + __in uint8_t offset, + __in uint8_t len, + __out_bcount(len) uint8_t *data); + #if EFSYS_OPT_PHY_STATS /* START MKCONFIG GENERATED PhyHeaderStatsBlock 30ed56ad501f8e36 */ diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c index 9f7a9ffedd8c..bb9d9cf76be8 100644 --- a/sys/dev/sfxge/common/efx_mcdi.c +++ b/sys/dev/sfxge/common/efx_mcdi.c @@ -2078,5 +2078,217 @@ efx_mcdi_get_workarounds( return (rc); } +/* + * Size of media information page in accordance with SFF-8472 and SFF-8436. + * It is used in MCDI interface as well. + */ +#define EFX_PHY_MEDIA_INFO_PAGE_SIZE 0x80 + +static __checkReturn efx_rc_t +efx_mcdi_get_phy_media_info( + __in efx_nic_t *enp, + __in uint32_t mcdi_page, + __in uint8_t offset, + __in uint8_t len, + __out_bcount(len) uint8_t *data) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN, + MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN( + EFX_PHY_MEDIA_INFO_PAGE_SIZE))]; + efx_rc_t rc; + + EFSYS_ASSERT((uint32_t)offset + len <= EFX_PHY_MEDIA_INFO_PAGE_SIZE); + + (void) memset(payload, 0, sizeof (payload)); + req.emr_cmd = MC_CMD_GET_PHY_MEDIA_INFO; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = + MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(EFX_PHY_MEDIA_INFO_PAGE_SIZE); + + MCDI_IN_SET_DWORD(req, GET_PHY_MEDIA_INFO_IN_PAGE, mcdi_page); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used != + MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(EFX_PHY_MEDIA_INFO_PAGE_SIZE)) { + rc = EMSGSIZE; + goto fail2; + } + + if (MCDI_OUT_DWORD(req, GET_PHY_MEDIA_INFO_OUT_DATALEN) != + EFX_PHY_MEDIA_INFO_PAGE_SIZE) { + rc = EIO; + goto fail3; + } + + memcpy(data, + MCDI_OUT2(req, uint8_t, GET_PHY_MEDIA_INFO_OUT_DATA) + offset, + len); + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +/* + * 2-wire device address of the base information in accordance with SFF-8472 + * Diagnostic Monitoring Interface for Optical Transceivers section + * 4 Memory Organization. + */ +#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_BASE 0xA0 + +/* + * 2-wire device address of the digital diagnostics monitoring interface + * in accordance with SFF-8472 Diagnostic Monitoring Interface for Optical + * Transceivers section 4 Memory Organization. + */ +#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_DDM 0xA2 + +/* + * Hard wired 2-wire device address for QSFP+ in accordance with SFF-8436 + * QSFP+ 10 Gbs 4X PLUGGABLE TRANSCEIVER section 7.4 Device Addressing and + * Operation. + */ +#define EFX_PHY_MEDIA_INFO_DEV_ADDR_QSFP 0xA0 + + __checkReturn efx_rc_t +efx_mcdi_phy_module_get_info( + __in efx_nic_t *enp, + __in uint8_t dev_addr, + __in uint8_t offset, + __in uint8_t len, + __out_bcount(len) uint8_t *data) +{ + efx_port_t *epp = &(enp->en_port); + efx_rc_t rc; + uint32_t mcdi_lower_page; + uint32_t mcdi_upper_page; + + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + /* + * Map device address to MC_CMD_GET_PHY_MEDIA_INFO pages. + * Offset plus length interface allows to access page 0 only. + * I.e. non-zero upper pages are not accessible. + * See SFF-8472 section 4 Memory Organization and SFF-8436 section 7.6 + * QSFP+ Memory Map for details on how information is structured + * and accessible. + */ + switch (epp->ep_fixed_port_type) { + case EFX_PHY_MEDIA_SFP_PLUS: + /* + * In accordance with SFF-8472 Diagnostic Monitoring + * Interface for Optical Transceivers section 4 Memory + * Organization two 2-wire addresses are defined. + */ + switch (dev_addr) { + /* Base information */ + case EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_BASE: + /* + * MCDI page 0 should be used to access lower + * page 0 (0x00 - 0x7f) at the device address 0xA0. + */ + mcdi_lower_page = 0; + /* + * MCDI page 1 should be used to access upper + * page 0 (0x80 - 0xff) at the device address 0xA0. + */ + mcdi_upper_page = 1; + break; + /* Diagnostics */ + case EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_DDM: + /* + * MCDI page 2 should be used to access lower + * page 0 (0x00 - 0x7f) at the device address 0xA2. + */ + mcdi_lower_page = 2; + /* + * MCDI page 3 should be used to access upper + * page 0 (0x80 - 0xff) at the device address 0xA2. + */ + mcdi_upper_page = 3; + break; + default: + rc = ENOTSUP; + goto fail1; + } + break; + case EFX_PHY_MEDIA_QSFP_PLUS: + switch (dev_addr) { + case EFX_PHY_MEDIA_INFO_DEV_ADDR_QSFP: + /* + * MCDI page -1 should be used to access lower page 0 + * (0x00 - 0x7f). + */ + mcdi_lower_page = (uint32_t)-1; + /* + * MCDI page 0 should be used to access upper page 0 + * (0x80h - 0xff). + */ + mcdi_upper_page = 0; + break; + default: + rc = ENOTSUP; + goto fail1; + } + break; + default: + rc = ENOTSUP; + goto fail1; + } + + if (offset < EFX_PHY_MEDIA_INFO_PAGE_SIZE) { + uint8_t read_len = + MIN(len, EFX_PHY_MEDIA_INFO_PAGE_SIZE - offset); + + rc = efx_mcdi_get_phy_media_info(enp, + mcdi_lower_page, offset, read_len, data); + if (rc != 0) + goto fail2; + + data += read_len; + len -= read_len; + + offset = 0; + } else { + offset -= EFX_PHY_MEDIA_INFO_PAGE_SIZE; + } + + if (len > 0) { + EFSYS_ASSERT3U(len, <=, EFX_PHY_MEDIA_INFO_PAGE_SIZE); + EFSYS_ASSERT3U(offset, <, EFX_PHY_MEDIA_INFO_PAGE_SIZE); + + rc = efx_mcdi_get_phy_media_info(enp, + mcdi_upper_page, offset, len, data); + if (rc != 0) + goto fail3; + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} #endif /* EFSYS_OPT_MCDI */ diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h index dd1d76e5fafa..a96bd77df435 100644 --- a/sys/dev/sfxge/common/efx_mcdi.h +++ b/sys/dev/sfxge/common/efx_mcdi.h @@ -228,6 +228,14 @@ efx_mcdi_get_loopback_modes( __in efx_nic_t *enp); #endif /* EFSYS_OPT_LOOPBACK */ +extern __checkReturn efx_rc_t +efx_mcdi_phy_module_get_info( + __in efx_nic_t *enp, + __in uint8_t dev_addr, + __in uint8_t offset, + __in uint8_t len, + __out_bcount(len) uint8_t *data); + #define MCDI_IN(_emr, _type, _ofst) \ ((_type *)((_emr).emr_in_buf + (_ofst))) diff --git a/sys/dev/sfxge/common/efx_phy.c b/sys/dev/sfxge/common/efx_phy.c index 51e1ccb2e131..3fd4e086d861 100644 --- a/sys/dev/sfxge/common/efx_phy.c +++ b/sys/dev/sfxge/common/efx_phy.c @@ -560,6 +560,38 @@ efx_phy_media_type_get( *typep = epp->ep_fixed_port_type; } + __checkReturn efx_rc_t +efx_phy_module_get_info( + __in efx_nic_t *enp, + __in uint8_t dev_addr, + __in uint8_t offset, + __in uint8_t len, + __out_bcount(len) uint8_t *data) +{ + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT(data != NULL); + + if ((uint32_t)offset + len > 0xff) { + rc = EINVAL; + goto fail1; + } + + if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr, + offset, len, data)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #if EFSYS_OPT_PHY_STATS #if EFSYS_OPT_NAMES diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c index db6225dc600c..88e56bca2ef4 100644 --- a/sys/dev/sfxge/sfxge.c +++ b/sys/dev/sfxge/sfxge.c @@ -500,6 +500,30 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->media, command); break; +#ifdef SIOCGI2C + case SIOCGI2C: + { + struct ifi2creq i2c; + + error = copyin(ifr->ifr_data, &i2c, sizeof(i2c)); + if (error != 0) + break; + + if (i2c.len > sizeof(i2c.data)) { + error = EINVAL; + break; + } + + SFXGE_ADAPTER_LOCK(sc); + error = efx_phy_module_get_info(sc->enp, i2c.dev_addr, + i2c.offset, i2c.len, + &i2c.data[0]); + SFXGE_ADAPTER_UNLOCK(sc); + if (error == 0) + error = copyout(&i2c, ifr->ifr_data, sizeof(i2c)); + break; + } +#endif case SIOCGPRIVATE_0: error = priv_check(curthread, PRIV_DRIVER); if (error != 0) From e94b881ba14eef3512d966581806309728527e84 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Wed, 10 Feb 2016 14:48:49 +0000 Subject: [PATCH 023/142] Remove man page references to rndassociates.com, which has been taken over by a domain squatter. --- lib/libc/sys/jail.2 | 1 - usr.sbin/jail/jail.8 | 1 - usr.sbin/jail/jail.conf.5 | 1 - 3 files changed, 3 deletions(-) diff --git a/lib/libc/sys/jail.2 b/lib/libc/sys/jail.2 index a2d692ad2999..8b6add91c5ed 100644 --- a/lib/libc/sys/jail.2 +++ b/lib/libc/sys/jail.2 @@ -405,7 +405,6 @@ system calls appeared in The jail feature was written by .An Poul-Henning Kamp for R&D Associates -.Dq Li http://www.rndassociates.com/ who contributed it to .Fx . .An James Gritton diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index c9b79c4df16f..362e5b23a40a 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -1260,7 +1260,6 @@ The configuration file was introduced in The jail feature was written by .An Poul-Henning Kamp for R&D Associates -.Pa http://www.rndassociates.com/ who contributed it to .Fx . .Pp diff --git a/usr.sbin/jail/jail.conf.5 b/usr.sbin/jail/jail.conf.5 index d83bf611b68a..0241a0612abd 100644 --- a/usr.sbin/jail/jail.conf.5 +++ b/usr.sbin/jail/jail.conf.5 @@ -224,7 +224,6 @@ file was added in The jail feature was written by .An Poul-Henning Kamp for R&D Associates -.Pa http://www.rndassociates.com/ who contributed it to .Fx . .Pp From 1e2b39a3f2fdc80f9b44f310ab4a49791486866b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 15:56:52 +0000 Subject: [PATCH 024/142] Use OF_getencprop to read a property, it already handles the endian conversion so we don't need to pass the data through fdt32_to_cpu. --- sys/arm/arm/generic_timer.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c index fd1f029ae193..973920817014 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -361,11 +361,8 @@ arm_tmr_attach(device_t dev) /* Get the base clock frequency */ node = ofw_bus_get_node(dev); if (node > 0) { - error = OF_getprop(node, "clock-frequency", &clock, + error = OF_getencprop(node, "clock-frequency", &clock, sizeof(clock)); - if (error > 0) { - sc->clkfreq = fdt32_to_cpu(clock); - } } #endif From 0ba5cf0e445429647ca95f9bff3bc5fd7fc0fc8c Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Wed, 10 Feb 2016 16:13:59 +0000 Subject: [PATCH 025/142] Add new rc.conf parameter "jail_reverse_stop" When a user defines "jail_list" in rc.conf the jails are started in the order defined. Currently the jails are not are stopped in reverse order which may break dependencies between jails/services and prevent a clean shutdown. The new parameter "jail_reverse_stop" will shutdown jails in "jail_list" in reverse order when set to "YES". Please note that this does not affect manual invocation of the jail rc script. If a user runs the command # service jail stop jail1 jail2 jail3 the jails will be stopped in exactly the order specified regardless of jail_reverse_stop being defined in rc.conf. PR: 196152 Approved by: jamie MFC after: 1 week Relnotes: yes Differential Revision: https://reviews.freebsd.org/D5233 --- etc/defaults/rc.conf | 1 + etc/rc.d/jail | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 69b6d0f77bd0..b9c6b5cc4d6e 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -694,6 +694,7 @@ iovctl_files="" # Config files for iovctl(8) jail_enable="NO" # Set to NO to disable starting of any jails jail_parallel_start="NO" # Start jails in the background jail_list="" # Space separated list of names of jails +jail_reverse_stop="NO" # Stop jails in reverse order ############################################################## ### Define source_rc_confs, the mechanism used by /etc/rc.* ## diff --git a/etc/rc.d/jail b/etc/rc.d/jail index b33f1b9a2c23..2d4898969e0f 100755 --- a/etc/rc.d/jail +++ b/etc/rc.d/jail @@ -521,7 +521,11 @@ jail_stop() command=$jail_program rc_flags=$jail_flags command_args="-f $jail_conf -r" - $jail_jls name | while read _j; do + if checkyesno jail_reverse_stop; then + $jail_jls name | tail -r + else + $jail_jls name + fi | while read _j; do echo -n " $_j" _tmp=`mktemp -t jail` || exit 3 $command $rc_flags $command_args $_j >> $_tmp 2>&1 @@ -536,6 +540,7 @@ jail_stop() return ;; esac + checkyesno jail_reverse_stop && set -- $(reverse_list $@) for _j in $@; do _j=$(echo $_j | tr /. _) _jv=$(echo -n $_j | tr -c '[:alnum:]' _) @@ -571,5 +576,6 @@ jail_warn() load_rc_config $name case $# in 1) run_rc_command $@ ${jail_list:-_ALL} ;; -*) run_rc_command $@ ;; +*) jail_reverse_stop="no" + run_rc_command $@ ;; esac From c5fdd4d379fc3932f7988f7749015962c5c24e02 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 16:39:02 +0000 Subject: [PATCH 026/142] Only use fdt_pic_table when not using ARM_INTRNG --- sys/arm/qemu/virt_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm/qemu/virt_common.c b/sys/arm/qemu/virt_common.c index 0f407243cff4..8f843557be59 100644 --- a/sys/arm/qemu/virt_common.c +++ b/sys/arm/qemu/virt_common.c @@ -41,7 +41,9 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifdef ARM_INTRNG fdt_pic_decode_t fdt_pic_table[] = { &gic_decode_fdt, NULL }; +#endif From 09bcaf7acc5fba6514a4d8709bbc81e131daf4b0 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 16:44:20 +0000 Subject: [PATCH 027/142] Fix a logic inversion when checking for ARM_INTRNG Pointy hat to: andrew --- sys/arm/qemu/virt_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/qemu/virt_common.c b/sys/arm/qemu/virt_common.c index 8f843557be59..572fee8e7fcb 100644 --- a/sys/arm/qemu/virt_common.c +++ b/sys/arm/qemu/virt_common.c @@ -41,7 +41,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; -#ifdef ARM_INTRNG +#ifndef ARM_INTRNG fdt_pic_decode_t fdt_pic_table[] = { &gic_decode_fdt, NULL From 4f42bf9497e964a5de899fdb2e9367790a696f74 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 10 Feb 2016 16:49:20 +0000 Subject: [PATCH 028/142] Explicitly include . Previously we were pulling it in due to header pollution. --- sys/dev/uart/uart_bus_fdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c index 1498eb86b706..5308a2e7c41b 100644 --- a/sys/dev/uart/uart_bus_fdt.c +++ b/sys/dev/uart/uart_bus_fdt.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include "opt_platform.h" #include +#include #include #include #include From c5805a3debd4a2a0422c813cc5c2c720dd7331b9 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 10 Feb 2016 17:55:39 +0000 Subject: [PATCH 029/142] Remove stray semicolons from the iSCSI code. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- sys/cam/ctl/ctl.c | 4 ++-- sys/dev/iscsi/iscsi.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 4fdaa05d2e5b..1101d024f05e 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -5694,7 +5694,7 @@ ctl_write_same(struct ctl_scsiio *ctsio) */ if ((byte2 & SWS_NDOB) == 0 && (ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) { - ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK);; + ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; ctsio->kern_data_resid = 0; @@ -5742,7 +5742,7 @@ ctl_unmap(struct ctl_scsiio *ctsio) * malloc it and tell the caller the data buffer is here. */ if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) { - ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK);; + ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; ctsio->kern_data_resid = 0; diff --git a/sys/dev/iscsi/iscsi.h b/sys/dev/iscsi/iscsi.h index a2475f4ac8fb..3225649cc464 100644 --- a/sys/dev/iscsi/iscsi.h +++ b/sys/dev/iscsi/iscsi.h @@ -119,7 +119,7 @@ struct iscsi_session { char is_reason[ISCSI_REASON_LEN]; #ifdef ICL_KERNEL_PROXY - struct cv is_login_cv;; + struct cv is_login_cv; struct icl_pdu *is_login_pdu; #endif }; From 8e89d3a42a307f511b1998bdf62954c507ea0ce2 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Wed, 10 Feb 2016 17:57:24 +0000 Subject: [PATCH 030/142] Similar to r295116, add an additional 1 second sleep after calling ggatel before calling dd to defeat a race when writing out to the geom_gate(4) device MFC after: 1 month Reported by: Jenkins Sponsored by: EMC / Isilon Storage Division --- tests/sys/geom/class/gate/3_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/sys/geom/class/gate/3_test.sh b/tests/sys/geom/class/gate/3_test.sh index 8901aca6945b..3511df761ca6 100644 --- a/tests/sys/geom/class/gate/3_test.sh +++ b/tests/sys/geom/class/gate/3_test.sh @@ -27,6 +27,7 @@ if ! ggatel create -u $us /dev/$work; then exit 1 fi +sleep 1 dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1 conv=sync sleep 1 From ed6877ef4b151d98ee27ffca6b16e2e48e915242 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Wed, 10 Feb 2016 18:36:51 +0000 Subject: [PATCH 031/142] Garbage collect m_getclr(). --- sys/sys/mbuf.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 91dd8958c087..a4aa0bcf86bf 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -647,23 +647,6 @@ m_get(int how, short type) return (uma_zalloc_arg(zone_mbuf, &args, how)); } -/* - * XXX This should be deprecated, very little use. - */ -static __inline struct mbuf * -m_getclr(int how, short type) -{ - struct mbuf *m; - struct mb_args args; - - args.flags = 0; - args.type = type; - m = uma_zalloc_arg(zone_mbuf, &args, how); - if (m != NULL) - bzero(m->m_data, MLEN); - return (m); -} - static __inline struct mbuf * m_gethdr(int how, short type) { From b4b12e52fb02dfe381fe328b98511aa2087ca619 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Wed, 10 Feb 2016 18:54:18 +0000 Subject: [PATCH 032/142] Garbage collect unused arguments of m_init(). --- sys/dev/cxgb/cxgb_sge.c | 8 +++----- sys/dev/cxgbe/t4_sge.c | 2 +- sys/kern/kern_mbuf.c | 4 ++-- sys/netinet/tcp_pcap.c | 2 +- sys/sys/mbuf.h | 3 +-- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 2cfad262673b..a622fcfef566 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -795,12 +795,10 @@ free_rx_bufs(adapter_t *sc, struct sge_fl *q) bus_dmamap_unload(q->entry_tag, d->map); bus_dmamap_destroy(q->entry_tag, d->map); if (q->zone == zone_pack) { - m_init(d->m, zone_pack, MCLBYTES, - M_NOWAIT, MT_DATA, M_EXT); + m_init(d->m, M_NOWAIT, MT_DATA, M_EXT); uma_zfree(zone_pack, d->m); } else { - m_init(d->m, zone_mbuf, MLEN, - M_NOWAIT, MT_DATA, 0); + m_init(d->m, M_NOWAIT, MT_DATA, 0); uma_zfree(zone_mbuf, d->m); uma_zfree(q->zone, d->rxsd_cl); } @@ -2725,7 +2723,7 @@ get_packet(adapter_t *adap, unsigned int drop_thres, struct sge_qset *qs, if ((sopeop == RSPQ_SOP_EOP) || (sopeop == RSPQ_SOP)) flags |= M_PKTHDR; - m_init(m, fl->zone, fl->buf_size, M_NOWAIT, MT_DATA, flags); + m_init(m, M_NOWAIT, MT_DATA, flags); if (fl->zone == zone_pack) { /* * restore clobbered data pointer diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index b43cd5fdf108..0c3644d98afc 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -1570,7 +1570,7 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int fr_offset, MPASS(clm != NULL); m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE); /* No bzero required */ - if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA, + if (m_init(m, M_NOWAIT, MT_DATA, fr_offset == 0 ? M_PKTHDR | M_NOFREE : M_NOFREE)) return (NULL); fl->mbuf_inlined++; diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 55964398b6a1..148b52f8b9df 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -435,7 +435,7 @@ mb_ctor_mbuf(void *mem, int size, void *arg, int how) m = (struct mbuf *)mem; flags = args->flags; - error = m_init(m, NULL, size, how, type, flags); + error = m_init(m, how, type, flags); return (error); } @@ -635,7 +635,7 @@ mb_ctor_pack(void *mem, int size, void *arg, int how) trash_ctor(m->m_ext.ext_buf, MCLBYTES, arg, how); #endif - error = m_init(m, NULL, size, how, type, flags); + error = m_init(m, how, type, flags); /* m_ext is already initialized. */ m->m_data = m->m_ext.ext_buf; diff --git a/sys/netinet/tcp_pcap.c b/sys/netinet/tcp_pcap.c index f0c651dab555..41a7fbfc958d 100644 --- a/sys/netinet/tcp_pcap.c +++ b/sys/netinet/tcp_pcap.c @@ -341,7 +341,7 @@ tcp_pcap_add(struct tcphdr *th, struct mbuf *m, struct mbufq *queue) n = mhead; tcp_pcap_m_freem(n->m_next); - m_init(n, NULL, 0, M_NOWAIT, MT_DATA, 0); + m_init(n, M_NOWAIT, MT_DATA, 0); } } diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index a4aa0bcf86bf..8d35f33b12f4 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -618,8 +618,7 @@ m_getzone(int size) * should go away with constant propagation for !MGETHDR. */ static __inline int -m_init(struct mbuf *m, uma_zone_t zone __unused, int size __unused, int how, - short type, int flags) +m_init(struct mbuf *m, int how, short type, int flags) { int error; From 099ad7abd09ac0605017b365ed9bc96abee0189e Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 10 Feb 2016 19:01:26 +0000 Subject: [PATCH 033/142] Add a kern.icl.drivers sysctl, to retrieve the list of registered ICL drivers. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- sys/dev/iscsi/icl.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c index 2e92f2a4ed91..c679523ba819 100644 --- a/sys/dev/iscsi/icl.c +++ b/sys/dev/iscsi/icl.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -66,13 +67,42 @@ struct icl_softc { TAILQ_HEAD(, icl_module) sc_modules; }; +static int sysctl_kern_icl_drivers(SYSCTL_HANDLER_ARGS); +static MALLOC_DEFINE(M_ICL, "icl", "iSCSI Common Layer"); +static struct icl_softc *sc; + SYSCTL_NODE(_kern, OID_AUTO, icl, CTLFLAG_RD, 0, "iSCSI Common Layer"); int icl_debug = 1; SYSCTL_INT(_kern_icl, OID_AUTO, debug, CTLFLAG_RWTUN, &icl_debug, 0, "Enable debug messages"); +SYSCTL_PROC(_kern_icl, OID_AUTO, drivers, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, + NULL, 0, sysctl_kern_icl_drivers, "A", + "List of ICL drivers"); -static MALLOC_DEFINE(M_ICL, "icl", "iSCSI Common Layer"); -static struct icl_softc *sc; +static int +sysctl_kern_icl_drivers(SYSCTL_HANDLER_ARGS) +{ + const struct icl_module *im; + struct sbuf sb; + int error; + + sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND | SBUF_INCLUDENUL); + + sx_slock(&sc->sc_lock); + TAILQ_FOREACH(im, &sc->sc_modules, im_next) { + if (im != TAILQ_FIRST(&sc->sc_modules)) + sbuf_putc(&sb, ' '); + sbuf_printf(&sb, "%s", im->im_name); + } + sx_sunlock(&sc->sc_lock); + + error = sbuf_finish(&sb); + if (error == 0) + error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb)); + sbuf_delete(&sb); + return (error); +} static struct icl_module * icl_find(const char *name) From 888a18208d70e0395f1ba2a425a272996246174e Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 10 Feb 2016 19:39:36 +0000 Subject: [PATCH 034/142] Import ELF Tool Chain snapshot revision 3395 This is close to the upcoming 0.7.1 release. From http://svn.code.sf.net/p/elftoolchain/code --- INSTALL | 70 +- Makefile | 26 +- RELEASE-NOTES | 8 +- addr2line/addr2line.c | 8 +- addr2line/os.NetBSD.mk | 2 + ar/ar.c | 4 +- brandelf/brandelf.c | 4 +- common/elfdefinitions.h | 139 ++- common/native-elf-format | 4 +- cxxfilt/cxxfilt.c | 21 +- elfcopy/Makefile | 23 +- elfcopy/archive.c | 6 +- elfcopy/elfcopy.1 | 19 +- elfcopy/elfcopy.h | 3 +- elfcopy/main.c | 18 +- elfcopy/pe.c | 233 +++++ elfcopy/sections.c | 107 +- elfcopy/segments.c | 16 +- elfcopy/symbols.c | 120 ++- elfdump/elfdump.c | 370 ++++--- elfdump/os.NetBSD.mk | 2 + findtextrel/findtextrel.c | 12 +- ld/Makefile | 25 +- ld/amd64.c | 9 +- ld/bigmips_script.ld | 165 +++ ld/i386.c | 13 +- ld/ld_arch.c | 20 +- ld/ld_arch.h | 8 +- ld/ld_dynamic.c | 4 +- ld/ld_exp.c | 9 +- ld/ld_file.c | 5 +- ld/ld_layout.c | 10 +- ld/ld_output.c | 7 +- ld/ld_script.c | 41 +- ld/ld_script.h | 7 +- ld/ld_script_lexer.l | 5 +- ld/ld_script_parser.y | 25 +- ld/ld_strtab.c | 8 +- ld/ld_symbols.c | 5 +- ld/littlemips_script.ld | 165 +++ ld/mips.c | 403 ++++++++ ld/mips.h | 29 + libdwarf/_libdwarf.h | 10 +- libdwarf/dwarf.3 | 6 +- libdwarf/dwarf_str.c | 8 +- libdwarf/libdwarf.h | 4 +- libdwarf/libdwarf_rw.c | 14 +- libdwarf/os.NetBSD.mk | 2 + libelftc/Makefile | 13 +- libelftc/elftc_bfd_find_target.3 | 10 +- libelftc/elftc_copyfile.c | 24 +- libelftc/elftc_demangle.c | 10 +- libelftc/elftc_symbol_table_create.3 | 529 ---------- libelftc/libelftc.h | 6 +- libelftc/libelftc_bfdtarget.c | 26 +- libelftc/libelftc_dem_gnu3.c | 22 +- libelftc/make-toolchain-version | 4 +- libelftc/os.NetBSD.mk | 2 + libpe/Makefile | 32 + libpe/_libpe.h | 213 ++++ libpe/libpe.h | 121 +++ libpe/libpe_buffer.c | 185 ++++ libpe/libpe_coff.c | 535 ++++++++++ libpe/libpe_dos.c | 403 ++++++++ libpe/libpe_init.c | 145 +++ libpe/libpe_rich.c | 128 +++ libpe/libpe_section.c | 518 ++++++++++ libpe/libpe_utils.c | 69 ++ libpe/os.Linux.mk | 6 + libpe/os.NetBSD.mk | 2 + libpe/pe.h | 292 ++++++ libpe/pe_buffer.c | 100 ++ libpe/pe_cntl.c | 62 ++ libpe/pe_coff.c | 157 +++ libpe/pe_dos.c | 119 +++ libpe/pe_flag.c | 187 ++++ libpe/pe_init.c | 95 ++ libpe/pe_rich.c | 107 ++ libpe/pe_section.c | 213 ++++ libpe/pe_symtab.c | 86 ++ libpe/pe_update.c | 86 ++ mk/elftoolchain.components.mk | 21 + mk/elftoolchain.prog.mk | 14 +- nm/os.NetBSD.mk | 2 + readelf/os.NetBSD.mk | 2 + readelf/readelf.c | 108 +- size/os.NetBSD.mk | 2 + strings/os.NetBSD.mk | 2 + strings/strings.1 | 7 +- strings/strings.c | 12 +- test/ar/plugin/Makefile | 4 +- test/ar/plugin/ardiff.c | 19 +- test/ar/plugin/teraser.c | 6 +- test/ar/tc/usage-bi/usage-bi.err | 1 + test/elfcopy/plugin/Makefile | 4 +- test/elfcopy/plugin/ardiff.c | 19 +- test/elfcopy/plugin/teraser.c | 6 +- .../tc/elfcopy-L-1/out/elfcopy-L-1.out.shar | 26 +- .../tc/elfcopy-L-2/out/elfcopy-L-2.out.shar | 180 ++-- .../tc/elfcopy-N-1/out/elfcopy-N-1.out.shar | 32 +- .../tc/elfcopy-N-2/out/elfcopy-N-2.out.shar | 32 +- .../out/elfcopy-noops-1.out.shar | 66 +- .../out/elfcopy-noops-2.out.shar | 16 +- .../out/elfcopy-noops-3.out.shar | 16 +- .../out/elfcopy-noops-4.out.shar | 16 +- .../out/elfcopy-noops-5.out.shar | 16 +- .../out/elfcopy-noops-6.out.shar | 82 +- .../out/elfcopy-noops-7.out.shar | 364 +++---- .../out/elfcopy-noops-archive-1.out.shar | 112 +-- .../out/elfcopy-noops-archive-2.out.shar | 112 +-- .../out/elfcopy-rename-1.out.shar | 26 +- .../tc/strip-K-2/out/strip-K-2.out.shar | 30 +- .../tc/strip-all-1/out/strip-all-1.out.shar | 10 +- .../tc/strip-all-10/out/strip-all-10.out.shar | 4 +- .../tc/strip-all-2/out/strip-all-2.out.shar | 10 +- .../tc/strip-all-3/out/strip-all-3.out.shar | 10 +- .../tc/strip-all-4/out/strip-all-4.out.shar | 10 +- .../tc/strip-all-5/out/strip-all-5.out.shar | 8 +- .../tc/strip-all-6/out/strip-all-6.out.shar | 10 +- .../tc/strip-all-7/out/strip-all-7.out.shar | 10 +- .../tc/strip-all-8/out/strip-all-8.out.shar | 10 +- .../tc/strip-all-9/out/strip-all-9.out.shar | 16 +- .../out/strip-all-archive-1.out.shar | 24 +- .../out/strip-all-archive-2.out.shar | 18 +- .../strip-debug-1/out/strip-debug-1.out.shar | 400 ++++---- .../strip-debug-2/out/strip-debug-2.out.shar | 258 ++--- .../strip-debug-3/out/strip-debug-3.out.shar | 16 +- .../strip-debug-4/out/strip-debug-4.out.shar | 367 +++---- .../out/strip-onlydebug-1.out.shar | 946 +++++++++--------- .../out/strip-unneeded-1.out.shar | 388 +++---- .../out/strip-unneeded-2.out.shar | 16 +- test/elfdump/ts/dso1/@G%libelf.so.out | 2 +- test/elfdump/ts/dso1/@S@G%libelf.so.out | 74 +- test/elfdump/ts/dso1/@S@r%libelf.so.out | 74 +- test/elfdump/ts/dso2/@G%test.so.out | 40 +- test/elfdump/ts/dso2/@S@G%test.so.out | 15 + test/elfdump/ts/dso2/@S@r%test.so.out | 18 +- test/elfdump/ts/dso2/@e%test.so.out | 2 +- test/elfdump/ts/dso2/@e@i%test.so.out | 2 +- test/elfdump/ts/dso2/@e@p@c%test.so.out | 2 +- test/elfdump/ts/exec1/@G%ls.out | 2 +- test/elfdump/ts/exec1/@G@e%ls.out | 2 +- test/elfdump/ts/exec1/@S@G%ls.out | 140 +-- test/elfdump/ts/exec1/@S@r%ls.out | 140 +-- .../exec1/@S@r@N%.rela.dyn@N%.rela.plt%ls.out | 140 +-- test/elfdump/ts/exec2/@G%cp.out | 2 +- test/elfdump/ts/exec2/@G@e%cp.out | 2 +- test/elfdump/ts/exec2/@S@G%cp.out | 116 +-- test/elfdump/ts/exec2/@S@r%cp.out | 116 +-- test/libdwarf/ts/Makefile.tset | 8 +- 150 files changed, 8228 insertions(+), 3284 deletions(-) create mode 100644 addr2line/os.NetBSD.mk create mode 100644 elfcopy/pe.c create mode 100644 elfdump/os.NetBSD.mk create mode 100644 ld/bigmips_script.ld create mode 100644 ld/littlemips_script.ld create mode 100644 ld/mips.c create mode 100644 ld/mips.h create mode 100644 libdwarf/os.NetBSD.mk delete mode 100644 libelftc/elftc_symbol_table_create.3 create mode 100644 libelftc/os.NetBSD.mk create mode 100644 libpe/Makefile create mode 100644 libpe/_libpe.h create mode 100644 libpe/libpe.h create mode 100644 libpe/libpe_buffer.c create mode 100644 libpe/libpe_coff.c create mode 100644 libpe/libpe_dos.c create mode 100644 libpe/libpe_init.c create mode 100644 libpe/libpe_rich.c create mode 100644 libpe/libpe_section.c create mode 100644 libpe/libpe_utils.c create mode 100644 libpe/os.Linux.mk create mode 100644 libpe/os.NetBSD.mk create mode 100644 libpe/pe.h create mode 100644 libpe/pe_buffer.c create mode 100644 libpe/pe_cntl.c create mode 100644 libpe/pe_coff.c create mode 100644 libpe/pe_dos.c create mode 100644 libpe/pe_flag.c create mode 100644 libpe/pe_init.c create mode 100644 libpe/pe_rich.c create mode 100644 libpe/pe_section.c create mode 100644 libpe/pe_symtab.c create mode 100644 libpe/pe_update.c create mode 100644 mk/elftoolchain.components.mk create mode 100644 nm/os.NetBSD.mk create mode 100644 readelf/os.NetBSD.mk create mode 100644 size/os.NetBSD.mk create mode 100644 strings/os.NetBSD.mk diff --git a/INSTALL b/INSTALL index e6e9752e8291..d3eeaac3a859 100644 --- a/INSTALL +++ b/INSTALL @@ -14,13 +14,11 @@ operating systems. Operating System Version Supported Architectures ----------------- -------- ----------------------- `DragonFly BSD`_ 2.10.1 i386 - FreeBSD_ v8.2 amd64 & i386 - FreeBSD_ v10.1 i386 + FreeBSD_ 10.2 amd64 & i386 Minix_ 3.0.2 i386 - NetBSD_ v5.0.2 i386 + NetBSD_ 7.0 i386 OpenBSD_ v5.0 i386 - Ubuntu_ GNU/Linux 10.04LTS i386 & x86_64 - Ubuntu_ GNU/Linux 12.04LTS i386 & x86_64 + Ubuntu_ GNU/Linux 14.04LTS x86_64 ================= ======== ======================= .. _DragonFly BSD: http://www.dragonflybsd.org/ @@ -35,9 +33,9 @@ Building the Source Tree The core libraries and utilities that make up the software release are always built by default. Builds of the project's test suites (in the -``test/`` subdirectory), and of additional documentation (in the -directory ``documentation/``) are optional and will only be attempted -if these directories are present. +``test/`` subdirectory), and of additional documentation (in the directory +``documentation/``) are optional, and will only be attempted if these +directories are present. Prerequisites ------------- @@ -58,39 +56,24 @@ Prerequisites - Building additional documentation is not currently supported under DragonFly BSD. -:FreeBSD 8.2: +:FreeBSD 10.2: - The core libraries and utilities should build out of the box on a stock install of FreeBSD. - To build and run the test suite: #. The current release of the `Test Execution Toolkit`_ needs to - be downloaded and unpacked into the ``test/tet/`` directory. + be downloaded and unpacked into the ``test/tet/`` directory:: - #. The ``py-yaml`` package needs to be installed:: - - % sudo pkg_add -r py-yaml - - - To build additional documentation, the ``latex-pgf`` package is - needed:: - - % sudo pkg_add -r latex-pgf - -:FreeBSD 10.1: - - The core libraries and utilities should build out of the box on - a stock install of FreeBSD. - - - To build and run the test suite: - - #. The current release of the `Test Execution Toolkit`_ needs to - be downloaded and unpacked into the ``test/tet/`` directory. + % cd /test/tet + % tar -xf /PATH/TO/DOWNLOADED/TET-3.8-SOURCES #. The ``python`` and ``py27-yaml`` packages need to be installed:: % sudo pkg install python py27-yaml - Building additional documentation is not currently supported under - FreeBSD 10.1. + FreeBSD 10.2. :Minix 3.2.0: - The following packages are pre-requisites for building the @@ -152,9 +135,20 @@ Prerequisites - Building additional documentation is not currently supported under OpenBSD. -:NetBSD 5.0.2: - - The core libraries and utilities should build out of the box - on a stock install of NetBSD. +:NetBSD 7.0: + - The following packages are pre-requisites for building the + sources on NetBSD 7.0: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``libarchive`` An archive access library. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + # pkg_add libarchive - To build and run the test suite: @@ -165,7 +159,7 @@ Prerequisites #. The following additional package needs to be installed, as listed in the example command line below :: - % sudo pkg_add py26-yaml + % sudo pkg_add py27-yaml - Building additional documentation is not currently supported under NetBSD. @@ -213,9 +207,9 @@ Prerequisites % sudo apt-get install pgf -:Ubuntu GNU/Linux 12.04: +:Ubuntu GNU/Linux 14.04: - The following packages are pre-requisites for building the - sources on Ubuntu GNU/Linux 12.04: + sources on Ubuntu GNU/Linux 14.04: =================== ===================================== **Package** **Description** @@ -226,7 +220,7 @@ Prerequisites ``libarchive-dev`` Archive access library. ``libexpat1-dev`` An XML processing library. ``m4`` Macro processor. - ``pmake`` A ``make`` that uses BSD-make syntax. + ``bmake`` NetBSD ``make``. ``python-yaml`` A YAML library for Python. ``sharutils`` For ``uudecode``. ``zlib1g-dev`` Compression library. @@ -236,7 +230,7 @@ Prerequisites pre-requisites:: % sudo apt-get install bison build-essential flex libarchive-dev \ - m4 pmake zlib1g-dev + m4 bmake zlib1g-dev - To build and run the test suite: @@ -250,7 +244,7 @@ Prerequisites % sudo apt-get install libexpat1-dev python-yaml sharutils - Builds of additional documentation are not currently supported - under Ubuntu GNU/Linux 12.04. + under Ubuntu GNU/Linux 14.04. .. _Test Execution Toolkit: http://tetworks.opengroup.org/ .. _OpenGroup: http://www.opengroup.org/ @@ -316,7 +310,7 @@ website`_. .. _project website: http://elftoolchain.sourceforge.net/ -.. $Id: INSTALL 3193 2015-05-04 17:47:14Z jkoshy $ +.. $Id: INSTALL 3353 2016-01-18 21:50:13Z jkoshy $ .. Local Variables: .. mode: rst diff --git a/Makefile b/Makefile index b217fdda1f11..daf376f30a08 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ -# $Id: Makefile 3016 2014-04-10 16:01:42Z jkoshy $ +# $Id: Makefile 3382 2016-01-31 12:31:08Z jkoshy $ TOP= . +.include "${TOP}/mk/elftoolchain.components.mk" .include "${TOP}/mk/elftoolchain.os.mk" # Build configuration information first. @@ -13,10 +14,14 @@ SUBDIR += libdwarf # Build additional APIs. SUBDIR += libelftc +.if defined(WITH_PE) && ${WITH_PE:tl} == "yes" +SUBDIR += libpe +.endif -# Build the tools needed for the rest of the build. - -# SUBDIR += isa # ('isa' does not build on all platforms yet). +# The instruction set analyser. +.if defined(WITH_ISA) && ${WITH_ISA:tl} == "yes" +SUBDIR += isa # ('isa' does not build on all platforms yet). +.endif # Build tools after the libraries. SUBDIR += addr2line @@ -26,6 +31,7 @@ SUBDIR += cxxfilt SUBDIR += elfcopy SUBDIR += elfdump SUBDIR += findtextrel +SUBDIR += ld SUBDIR += nm SUBDIR += readelf SUBDIR += size @@ -33,12 +39,18 @@ SUBDIR += strings SUBDIR += tools # Build the test suites. -.if exists(${.CURDIR}/test) && defined(MKTESTS) && ${MKTESTS} == "yes" +.if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS:tl} == "yes" SUBDIR += test .endif +# Build additional build tooling. +.if defined(WITH_BUILD_TOOLS) && ${WITH_BUILD_TOOLS:tl} == "yes" +SUBDIR += tools +.endif + # Build documentation at the end. -.if exists(${.CURDIR}/documentation) && defined(MKDOC) && ${MKDOC} == "yes" +.if exists(${.CURDIR}/documentation) && defined(WITH_DOCUMENTATION) && \ + ${WITH_DOCUMENTATION:tl} == "yes" SUBDIR += documentation .endif @@ -49,7 +61,7 @@ SUBDIR += documentation # # Run the test suites. -.if exists(${.CURDIR}/test) && defined(MKTESTS) && ${MKTESTS} == "yes" +.if exists(${.CURDIR}/test) && defined(WITH_TESTS) && ${WITH_TESTS:tl} == "yes" run-tests: all .PHONY (cd ${.CURDIR}/test; ${MAKE} test) .endif diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 37e45bdfe303..0aa1c3d266bb 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,4 +1,4 @@ -.. $Id: RELEASE-NOTES 2599 2012-09-25 06:25:51Z jkoshy $ +.. $Id: RELEASE-NOTES 3353 2016-01-18 21:50:13Z jkoshy $ .. This file contains a template for use when writing release notes. .. It needs to be updated with release-specific content prior to @@ -96,11 +96,11 @@ systems: **Operating System** **Version** **Supported Architectures** -------------------- ----------- --------------------------- `DragonFly BSD`_ 2.10.1 i386 - FreeBSD_ v8.2 amd64 & i386 + FreeBSD_ 10.2 amd64 & i386 Minix_ 3.2.0 i386 - NetBSD_ v5.0.2 i386 + NetBSD_ 7.0 i386 OpenBSD_ v5.0 i386 - Ubuntu_ GNU/Linux 10.04LTS i386 & x86_64 + Ubuntu_ GNU/Linux 14.04LTS x86_64 ==================== =========== =========================== diff --git a/addr2line/addr2line.c b/addr2line/addr2line.c index 53105762565c..3cd8cb5389fe 100644 --- a/addr2line/addr2line.c +++ b/addr2line/addr2line.c @@ -40,7 +40,7 @@ #include "uthash.h" #include "_elftc.h" -ELFTC_VCSID("$Id: addr2line.c 3264 2015-11-30 05:38:14Z kaiwang27 $"); +ELFTC_VCSID("$Id: addr2line.c 3273 2015-12-11 21:38:57Z kaiwang27 $"); struct Func { char *name; @@ -368,7 +368,8 @@ print_inlines(struct CU *cu, struct Func *f, Dwarf_Unsigned call_file, printf("%s\n", f->name); } } - (void) printf("%s:%ju\n", base ? basename(file) : file, call_line); + (void) printf("%s:%ju\n", base ? basename(file) : file, + (uintmax_t) call_line); if (f->inlined_caller != NULL) print_inlines(cu, f->inlined_caller, f->call_file, @@ -562,7 +563,8 @@ translate(Dwarf_Debug dbg, Elf *e, const char* addrstr) } } - (void) printf("%s:%ju\n", base ? basename(file) : file, lineno); + (void) printf("%s:%ju\n", base ? basename(file) : file, + (uintmax_t) lineno); if (ret == DW_DLV_OK && inlines && cu != NULL && cu->srcfiles != NULL && f != NULL && f->inlined_caller != NULL) diff --git a/addr2line/os.NetBSD.mk b/addr2line/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/addr2line/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/ar/ar.c b/ar/ar.c index 62f0e55d5d31..1b60a12fd480 100644 --- a/ar/ar.c +++ b/ar/ar.c @@ -72,7 +72,7 @@ #include "ar.h" -ELFTC_VCSID("$Id: ar.c 3243 2015-08-31 19:28:45Z emaste $"); +ELFTC_VCSID("$Id: ar.c 3319 2016-01-13 21:37:53Z jkoshy $"); enum options { @@ -407,7 +407,7 @@ Usage: %s [options] archive file...\n\ -F FORMAT | --flavor=FORMAT\n\ Create archives with the specified format.\n\ -S Do not generate an archive symbol table.\n\ - -U Use original metadata, for unique archive checksums.\n" + -U Use original metadata for archive members.\n" static void bsdar_usage(void) diff --git a/brandelf/brandelf.c b/brandelf/brandelf.c index cbe5d6cabbb2..22166f796589 100644 --- a/brandelf/brandelf.c +++ b/brandelf/brandelf.c @@ -44,7 +44,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: brandelf.c 3234 2015-07-31 12:35:09Z emaste $"); +ELFTC_VCSID("$Id: brandelf.c 3354 2016-01-18 21:50:15Z jkoshy $"); static int elftype(const char *); static const char *iselftype(int); @@ -212,7 +212,7 @@ main(int argc, char **argv) /* * Update the ABI type. */ - ehdr.e_ident[EI_OSABI] = type; + ehdr.e_ident[EI_OSABI] = (unsigned char) type; if (gelf_update_ehdr(elf, &ehdr) == 0) { warnx("gelf_update_ehdr error: %s", elf_errmsg(-1)); diff --git a/common/elfdefinitions.h b/common/elfdefinitions.h index e953c924147d..fa6132d40adb 100644 --- a/common/elfdefinitions.h +++ b/common/elfdefinitions.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: elfdefinitions.h 3253 2015-10-10 18:31:33Z kaiwang27 $ + * $Id: elfdefinitions.h 3392 2016-02-05 19:51:22Z emaste $ */ /* @@ -1228,6 +1228,7 @@ _ELF_DEFINE_STB(STB_GLOBAL, 1, \ _ELF_DEFINE_STB(STB_WEAK, 2, \ "visible across all object files but with low precedence") \ _ELF_DEFINE_STB(STB_LOOS, 10, "start of OS-specific range") \ +_ELF_DEFINE_STB(STB_GNU_UNIQUE, 10, "unique symbol (GNU)") \ _ELF_DEFINE_STB(STB_HIOS, 12, "end of OS-specific range") \ _ELF_DEFINE_STB(STB_LOPROC, 13, \ "start of processor-specific range") \ @@ -1259,6 +1260,7 @@ _ELF_DEFINE_STT(STT_LOPROC, 13, \ "start of processor-specific types") \ _ELF_DEFINE_STT(STT_ARM_TFUNC, 13, "Thumb function (GNU)") \ _ELF_DEFINE_STT(STT_ARM_16BIT, 15, "Thumb label (GNU)") \ +_ELF_DEFINE_STT(STT_SPARC_REGISTER, 13, "SPARC register information") \ _ELF_DEFINE_STT(STT_HIPROC, 15, \ "end of processor-specific types") @@ -1395,7 +1397,7 @@ _ELF_DEFINE_RELOC(R_386_GOT32, 3) \ _ELF_DEFINE_RELOC(R_386_PLT32, 4) \ _ELF_DEFINE_RELOC(R_386_COPY, 5) \ _ELF_DEFINE_RELOC(R_386_GLOB_DAT, 6) \ -_ELF_DEFINE_RELOC(R_386_JMP_SLOT, 7) \ +_ELF_DEFINE_RELOC(R_386_JUMP_SLOT, 7) \ _ELF_DEFINE_RELOC(R_386_RELATIVE, 8) \ _ELF_DEFINE_RELOC(R_386_GOTOFF, 9) \ _ELF_DEFINE_RELOC(R_386_GOTPC, 10) \ @@ -1407,9 +1409,129 @@ _ELF_DEFINE_RELOC(R_386_PC8, 23) /* */ -#define _ELF_DEFINE_AARCH64_RELOCATIONS() \ -_ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \ -_ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \ +#define _ELF_DEFINE_AARCH64_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_AARCH64_NONE, 0) \ +_ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \ +_ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \ +_ELF_DEFINE_RELOC(R_AARCH64_ABS16, 259) \ +_ELF_DEFINE_RELOC(R_AARCH64_PREL64, 260) \ +_ELF_DEFINE_RELOC(R_AARCH64_PREL32, 261) \ +_ELF_DEFINE_RELOC(R_AARCH64_PREL16, 262) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0, 263) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0_NC, 264) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1, 265) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1_NC, 266) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2, 267) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2_NC, 268) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G3, 269) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G0, 270) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G1, 271) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G2, 272) \ +_ELF_DEFINE_RELOC(R_AARCH64_LD_PREL_LO19, 273) \ +_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_LO21, 274) \ +_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21, 275) \ +_ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21_NC, 276) \ +_ELF_DEFINE_RELOC(R_AARCH64_ADD_ABS_LO12_NC, 277) \ +_ELF_DEFINE_RELOC(R_AARCH64_LDST8_ABS_LO12_NC, 278) \ +_ELF_DEFINE_RELOC(R_AARCH64_TSTBR14, 279) \ +_ELF_DEFINE_RELOC(R_AARCH64_CONDBR19, 280) \ +_ELF_DEFINE_RELOC(R_AARCH64_JUMP26, 282) \ +_ELF_DEFINE_RELOC(R_AARCH64_CALL26, 283) \ +_ELF_DEFINE_RELOC(R_AARCH64_LDST16_ABS_LO12_NC, 284) \ +_ELF_DEFINE_RELOC(R_AARCH64_LDST32_ABS_LO12_NC, 285) \ +_ELF_DEFINE_RELOC(R_AARCH64_LDST64_ABS_LO12_NC, 286) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0, 287) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0_NC, 288) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1, 289) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1_NC, 290) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2, 291) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2_NC, 292) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G3, 293) \ +_ELF_DEFINE_RELOC(R_AARCH64_LDST128_ABS_LO12_NC, 299) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0, 300) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0_NC, 301) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1, 302) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1_NC, 303) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2, 304) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2_NC, 305) \ +_ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G3, 306) \ +_ELF_DEFINE_RELOC(R_AARCH64_GOTREL64, 307) \ +_ELF_DEFINE_RELOC(R_AARCH64_GOTREL32, 308) \ +_ELF_DEFINE_RELOC(R_AARCH64_GOT_LD_PREL19, 309) \ +_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTOFF_LO15, 310) \ +_ELF_DEFINE_RELOC(R_AARCH64_ADR_GOT_PAGE, 311) \ +_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 312) \ +_ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 313) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 512) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 513) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 514) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G1, 515) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G0_NC, 516) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PREL21, 517) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PAGE21, 518) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_LO12_NC, 519) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G1, 520) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G0_NC, 521) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LD_PREL19, 522) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G2, 523) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1, 524) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, 525) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0, 526) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, 527) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_HI12, 529) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, 530) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, 531) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, 532) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, 533) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, 534) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, 535) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, 536) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, 537) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, 538) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, 539) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, 540) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 541) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, 542) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, 543) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G2, 544) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1, 545) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 546) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0, 547) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 548) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_HI12, 549) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12, 550) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, 551) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12, 552) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, 553) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12, 554) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, 555) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12, 556) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, 557) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12, 558) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 559) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 560) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 561) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 562) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 563) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 564) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G1, 565) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 566) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LDR, 567) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD, 568) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_CALL, 569) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 570) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 571) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 572) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 573) \ +_ELF_DEFINE_RELOC(R_AARCH64_COPY, 1024) \ +_ELF_DEFINE_RELOC(R_AARCH64_GLOB_DAT, 1025) \ +_ELF_DEFINE_RELOC(R_AARCH64_JUMP_SLOT, 1026) \ +_ELF_DEFINE_RELOC(R_AARCH64_RELATIVE, 1027) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPREL64, 1028) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPMOD64, 1029) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLS_TPREL64, 1030) \ +_ELF_DEFINE_RELOC(R_AARCH64_TLSDESC, 1031) \ +_ELF_DEFINE_RELOC(R_AARCH64_IRELATIVE, 1032) /* * These are the symbols used in the Sun ``Linkers and Loaders @@ -1633,7 +1755,7 @@ _ELF_DEFINE_RELOC(R_IA_64_LTV32MSB, 0x74) \ _ELF_DEFINE_RELOC(R_IA_64_LTV32LSB, 0x75) \ _ELF_DEFINE_RELOC(R_IA_64_LTV64MSB, 0x76) \ _ELF_DEFINE_RELOC(R_IA_64_LTV64LSB, 0x77) \ -_ELF_DEFINE_RELOC(R_IA_64_PCREL21BIa, 0x79) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL21BI, 0x79) \ _ELF_DEFINE_RELOC(R_IA_64_PCREL22, 0x7A) \ _ELF_DEFINE_RELOC(R_IA_64_PCREL64I, 0x7B) \ _ELF_DEFINE_RELOC(R_IA_64_IPLTMSB, 0x80) \ @@ -1723,7 +1845,7 @@ _ELF_DEFINE_RELOC(R_PPC_REL32, 26) \ _ELF_DEFINE_RELOC(R_PPC_PLT32, 27) \ _ELF_DEFINE_RELOC(R_PPC_PLTREL32, 28) \ _ELF_DEFINE_RELOC(R_PPC_PLT16_LO, 29) \ -_ELF_DEFINE_RELOC(R_PPL_PLT16_HI, 30) \ +_ELF_DEFINE_RELOC(R_PPC_PLT16_HI, 30) \ _ELF_DEFINE_RELOC(R_PPC_PLT16_HA, 31) \ _ELF_DEFINE_RELOC(R_PPC_SDAREL16, 32) \ _ELF_DEFINE_RELOC(R_PPC_SECTOFF, 33) \ @@ -1926,7 +2048,7 @@ _ELF_DEFINE_RELOC(R_RISCV_SUB32, 39) \ _ELF_DEFINE_RELOC(R_RISCV_SUB64, 40) \ _ELF_DEFINE_RELOC(R_RISCV_GNU_VTINHERIT, 41) \ _ELF_DEFINE_RELOC(R_RISCV_GNU_VTENTRY, 42) \ -_ELF_DEFINE_RELOC(R_RISCV_ALIGN 43) \ +_ELF_DEFINE_RELOC(R_RISCV_ALIGN, 43) \ _ELF_DEFINE_RELOC(R_RISCV_RVC_BRANCH, 44) \ _ELF_DEFINE_RELOC(R_RISCV_RVC_JUMP, 45) @@ -2042,6 +2164,7 @@ _ELF_DEFINE_IA64_RELOCATIONS() \ _ELF_DEFINE_MIPS_RELOCATIONS() \ _ELF_DEFINE_PPC32_RELOCATIONS() \ _ELF_DEFINE_PPC64_RELOCATIONS() \ +_ELF_DEFINE_RISCV_RELOCATIONS() \ _ELF_DEFINE_SPARC_RELOCATIONS() \ _ELF_DEFINE_X86_64_RELOCATIONS() diff --git a/common/native-elf-format b/common/native-elf-format index d36ab53806de..2bdd914c3052 100755 --- a/common/native-elf-format +++ b/common/native-elf-format @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: native-elf-format 3186 2015-04-16 22:16:40Z emaste $ +# $Id: native-elf-format 3293 2016-01-07 19:26:27Z emaste $ # # Find the native ELF format for a host platform by compiling a # test object and examining the resulting object. @@ -33,6 +33,8 @@ $1 ~ "Data:" { $1 ~ "Machine:" { if (match($0, "Intel.*386")) { elfarch = "EM_386"; + } else if (match($0, "MIPS")) { + elfarch = "EM_MIPS"; } else if (match($0, ".*[xX]86-64")) { elfarch = "EM_X86_64"; } else { diff --git a/cxxfilt/cxxfilt.c b/cxxfilt/cxxfilt.c index 4efa45b33f22..9318c64f151f 100644 --- a/cxxfilt/cxxfilt.c +++ b/cxxfilt/cxxfilt.c @@ -35,7 +35,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: cxxfilt.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: cxxfilt.c 3356 2016-01-22 22:31:38Z jkoshy $"); #define STRBUFSZ 8192 @@ -112,11 +112,11 @@ find_format(const char *fstr) } static char * -demangle(char *name, int strict, int *pos) +demangle(char *name, int strict, size_t *pos) { static char dem[STRBUFSZ]; char nb[STRBUFSZ]; - int p, t; + size_t p, t; if (stripus && *name == '_') { strncpy(nb, name + 1, sizeof(nb) - 1); @@ -128,10 +128,10 @@ demangle(char *name, int strict, int *pos) nb[sizeof(nb) - 1] = '\0'; p = strlen(nb); - if (p <= 0) + if (p == 0) return NULL; - while (elftc_demangle(nb, dem, sizeof(dem), format) < 0) { + while (elftc_demangle(nb, dem, sizeof(dem), (unsigned) format) < 0) { if (!strict && p > 1) { nb[--p] = '\0'; continue; @@ -149,7 +149,8 @@ int main(int argc, char **argv) { char *dem, buf[STRBUFSZ]; - int c, i, p, s, opt; + size_t i, p, s; + int c, n, opt; while ((opt = getopt_long(argc, argv, "_nps:V", longopts, NULL)) != -1) { @@ -182,9 +183,9 @@ main(int argc, char **argv) argc -= optind; if (*argv != NULL) { - for (i = 0; i < argc; i++) { - if ((dem = demangle(argv[i], 1, NULL)) == NULL) - fprintf(stderr, "Failed: %s\n", argv[i]); + for (n = 0; n < argc; n++) { + if ((dem = demangle(argv[n], 1, NULL)) == NULL) + fprintf(stderr, "Failed: %s\n", argv[n]); else printf("%s\n", dem); } @@ -213,7 +214,7 @@ main(int argc, char **argv) if ((size_t) p >= sizeof(buf) - 1) warnx("buffer overflowed"); else - buf[p++] = c; + buf[p++] = (char) c; } } diff --git a/elfcopy/Makefile b/elfcopy/Makefile index cb1a31b400ee..8b208e0ff467 100644 --- a/elfcopy/Makefile +++ b/elfcopy/Makefile @@ -1,10 +1,13 @@ -# $Id: Makefile 2290 2011-12-04 07:20:46Z jkoshy $ +# $Id: Makefile 3381 2016-01-30 19:39:47Z jkoshy $ TOP= .. +.include "${TOP}/mk/elftoolchain.components.mk" + PROG= elfcopy -SRCS= archive.c ascii.c binary.c main.c sections.c segments.c symbols.c +SRCS= archive.c ascii.c binary.c main.c sections.c segments.c \ + symbols.c WARNS?= 5 @@ -15,14 +18,24 @@ LDADD= -lelf -lelftc LDADD+= -larchive .endif +.if defined(WITH_PE) && ${WITH_PE:tl} == "yes" +SRCS+= pe.c +CFLAGS+= -DWITH_PE=1 + +DPADD+= ${LIBPE} +LDADD+= -lpe +.endif + MAN= elfcopy.1 mcs.1 strip.1 +MLINKS= elfcopy.1 objcopy.1 NO_SHARED?= yes -LINKS= ${BINDIR}/elfcopy ${BINDIR}/strip \ - ${BINDIR}/elfcopy ${BINDIR}/mcs +LINKS= ${BINDIR}/elfcopy ${BINDIR}/mcs \ + ${BINDIR}/elfcopy ${BINDIR}/objcopy \ + ${BINDIR}/elfcopy ${BINDIR}/strip -EXTRA_TARGETS= strip mcs +EXTRA_TARGETS= mcs strip objcopy CLEANFILES+= ${EXTRA_TARGETS} diff --git a/elfcopy/archive.c b/elfcopy/archive.c index 682a1df66dcc..97e2498a66ff 100644 --- a/elfcopy/archive.c +++ b/elfcopy/archive.c @@ -38,7 +38,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: archive.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: archive.c 3287 2015-12-31 16:58:48Z emaste $"); #define _ARMAG_LEN 8 /* length of ar magic string */ #define _ARHDR_LEN 60 /* length of ar header */ @@ -382,7 +382,7 @@ ac_read_objs(struct elfcopy *ecp, int ifd) if (lseek(ifd, 0, SEEK_SET) == -1) err(EXIT_FAILURE, "lseek failed"); if ((a = archive_read_new()) == NULL) - errx(EXIT_FAILURE, "%s", archive_error_string(a)); + errx(EXIT_FAILURE, "archive_read_new failed"); archive_read_support_format_ar(a); AC(archive_read_open_fd(a, ifd, 10240)); for(;;) { @@ -443,7 +443,7 @@ ac_write_objs(struct elfcopy *ecp, int ofd) int nr; if ((a = archive_write_new()) == NULL) - errx(EXIT_FAILURE, "%s", archive_error_string(a)); + errx(EXIT_FAILURE, "archive_write_new failed"); archive_write_set_format_ar_svr4(a); AC(archive_write_open_fd(a, ofd)); diff --git a/elfcopy/elfcopy.1 b/elfcopy/elfcopy.1 index 83cda5d8c5f7..b7b0ce48dfa1 100644 --- a/elfcopy/elfcopy.1 +++ b/elfcopy/elfcopy.1 @@ -21,13 +21,14 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: elfcopy.1 3266 2015-12-07 15:38:26Z emaste $ +.\" $Id: elfcopy.1 3381 2016-01-30 19:39:47Z jkoshy $ .\" -.Dd December 7, 2015 +.Dd January 29, 2016 .Os .Dt ELFCOPY 1 .Sh NAME -.Nm elfcopy +.Nm elfcopy , +.Nm objcopy .Nd copy and translate object files .Sh SYNOPSIS .Nm @@ -85,7 +86,7 @@ .Sh DESCRIPTION The .Nm -utility copies the content of the ELF object named by argument +utility copies the content of the binary object named by argument .Ar infile to that named by argument .Ar outfile , @@ -121,6 +122,10 @@ to the output. .It Fl O Ar objformat | Fl -output-target= Ns Ar objformat Write the output file using the object format specified in argument .Ar objformat . +The argument +.Ar objformat +should be one of the target names recognized by +.Xr elftc_bfd_find_target 3 . .It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname Remove any section with name .Ar sectionname @@ -330,8 +335,14 @@ Do not copy symbols that are not needed for relocation processing. .Xr mcs 1 , .Xr strip 1 , .Xr elf 3 , +.Xr elftc_bfd_find_target 3 , .Xr ar 5 , .Xr elf 5 +.Sh COMPATIBILITY +The +.Nm +utility is expected to be option compatible with GNU +.Nm objcopy . .Sh HISTORY .Nm has been implemented by diff --git a/elfcopy/elfcopy.h b/elfcopy/elfcopy.h index 48574b55c65b..614c0e7e65bd 100644 --- a/elfcopy/elfcopy.h +++ b/elfcopy/elfcopy.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: elfcopy.h 3221 2015-05-24 23:42:43Z kaiwang27 $ + * $Id: elfcopy.h 3310 2016-01-10 09:10:54Z kaiwang27 $ */ #include @@ -287,6 +287,7 @@ struct section *create_external_section(struct elfcopy *_ecp, const char *_name, int _loadable); void create_external_symtab(struct elfcopy *_ecp); void create_ihex(int _ifd, int _ofd); +void create_pe(struct elfcopy *_ecp, int _ifd, int _ofd); void create_scn(struct elfcopy *_ecp); void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn); void create_symtab(struct elfcopy *_ecp); diff --git a/elfcopy/main.c b/elfcopy/main.c index e2685b476573..205466976a26 100644 --- a/elfcopy/main.c +++ b/elfcopy/main.c @@ -39,7 +39,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: main.c 3268 2015-12-07 20:30:55Z emaste $"); +ELFTC_VCSID("$Id: main.c 3381 2016-01-30 19:39:47Z jkoshy $"); enum options { @@ -722,6 +722,15 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst) create_srec(ecp, ofd, ofd0, dst != NULL ? dst : src); break; + case ETF_PE: + case ETF_EFI: +#if WITH_PE + create_pe(ecp, ofd, ofd0); +#else + errx(EXIT_FAILURE, "PE/EFI support not enabled" + " at compile time"); +#endif + break; default: errx(EXIT_FAILURE, "Internal: unsupported" " output flavour %d", ecp->oec); @@ -1345,6 +1354,9 @@ set_output_target(struct elfcopy *ecp, const char *target_name) ecp->oed = elftc_bfd_target_byteorder(tgt); ecp->oem = elftc_bfd_target_machine(tgt); } + if (ecp->otf == ETF_EFI || ecp->otf == ETF_PE) + ecp->oem = elftc_bfd_target_machine(tgt); + ecp->otgt = target_name; } @@ -1366,7 +1378,7 @@ set_osabi(struct elfcopy *ecp, const char *abi) #define ELFCOPY_USAGE_MESSAGE "\ Usage: %s [options] infile [outfile]\n\ - Transform an ELF object.\n\n\ + Transform object files.\n\n\ Options:\n\ -d | -g | --strip-debug Remove debugging information from the output.\n\ -j SECTION | --only-section=SECTION\n\ @@ -1382,6 +1394,8 @@ Usage: %s [options] infile [outfile]\n\ -N SYM | --strip-symbol=SYM Do not copy symbol SYM to the output.\n\ -O FORMAT | --output-target=FORMAT\n\ Specify object format for the output file.\n\ + FORMAT should be a target name understood by\n\ + elftc_bfd_find_target(3).\n\ -R NAME | --remove-section=NAME\n\ Remove the named section.\n\ -S | --strip-all Remove all symbol and relocation information\n\ diff --git a/elfcopy/pe.c b/elfcopy/pe.c new file mode 100644 index 000000000000..0d075c5c93c2 --- /dev/null +++ b/elfcopy/pe.c @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "elfcopy.h" + +ELFTC_VCSID("$Id: pe.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +/* Convert ELF object to Portable Executable (PE). */ +void +create_pe(struct elfcopy *ecp, int ifd, int ofd) +{ + Elf *e; + Elf_Scn *scn; + Elf_Data *d; + GElf_Ehdr eh; + GElf_Shdr sh; + PE *pe; + PE_Scn *ps; + PE_SecHdr psh; + PE_CoffHdr pch; + PE_OptHdr poh; + PE_Object po; + PE_Buffer *pb; + const char *name; + size_t indx; + int elferr, i; + + if (ecp->otf == ETF_EFI || ecp->oem == EM_X86_64) + po = PE_O_PE32P; + else + po = PE_O_PE32; + + if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) + errx(EXIT_FAILURE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + if (gelf_getehdr(e, &eh) == NULL) + errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", + elf_errmsg(-1)); + + if (elf_getshstrndx(ecp->ein, &indx) == 0) + errx(EXIT_FAILURE, "elf_getshstrndx() failed: %s", + elf_errmsg(-1)); + + if ((pe = pe_init(ofd, PE_C_WRITE, po)) == NULL) + err(EXIT_FAILURE, "pe_init() failed"); + + /* Setup PE COFF header. */ + memset(&pch, 0, sizeof(pch)); + switch (ecp->oem) { + case EM_386: + pch.ch_machine = IMAGE_FILE_MACHINE_I386; + break; + case EM_X86_64: + pch.ch_machine = IMAGE_FILE_MACHINE_AMD64; + break; + default: + pch.ch_machine = IMAGE_FILE_MACHINE_UNKNOWN; + break; + } + pch.ch_timestamp = (uint32_t) time(NULL); + if (pe_update_coff_header(pe, &pch) < 0) + err(EXIT_FAILURE, "pe_update_coff_header() failed"); + + /* Setup PE optional header. */ + memset(&poh, 0, sizeof(poh)); + if (ecp->otf == ETF_EFI) + poh.oh_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION; + poh.oh_entry = (uint32_t) eh.e_entry; + + /* + * Default section alignment and file alignment. (Here the + * section alignment is set to the default page size of the + * archs supported. We should use different section alignment + * for some arch. (e.g. IA64) + */ + poh.oh_secalign = 0x1000; + poh.oh_filealign = 0x200; + + /* Copy sections. */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + + /* + * Read in ELF section. + */ + + if (gelf_getshdr(scn, &sh) == NULL) { + warnx("gelf_getshdr() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) == + NULL) { + warnx("elf_strptr() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + + /* Skip sections unneeded. */ + if (strcmp(name, ".shstrtab") == 0 || + strcmp(name, ".symtab") == 0 || + strcmp(name, ".strtab") == 0) + continue; + + if ((d = elf_getdata(scn, NULL)) == NULL) { + warnx("elf_getdata() failed: %s", elf_errmsg(-1)); + (void) elf_errno(); + continue; + } + + if (strcmp(name, ".text") == 0) { + poh.oh_textbase = (uint32_t) sh.sh_addr; + poh.oh_textsize = (uint32_t) roundup(sh.sh_size, + poh.oh_filealign); + } else { + if (po == PE_O_PE32 && strcmp(name, ".data") == 0) + poh.oh_database = sh.sh_addr; + if (sh.sh_type == SHT_NOBITS) + poh.oh_bsssize += (uint32_t) + roundup(sh.sh_size, poh.oh_filealign); + else if (sh.sh_flags & SHF_ALLOC) + poh.oh_datasize += (uint32_t) + roundup(sh.sh_size, poh.oh_filealign); + } + + /* + * Create PE/COFF section. + */ + + if ((ps = pe_newscn(pe)) == NULL) { + warn("pe_newscn() failed"); + continue; + } + + /* + * Setup PE/COFF section header. The section name is not + * NUL-terminated if its length happens to be 8. Long + * section name should be truncated for PE image according + * to the PE/COFF specification. + */ + memset(&psh, 0, sizeof(psh)); + strncpy(psh.sh_name, name, sizeof(psh.sh_name)); + psh.sh_addr = sh.sh_addr; + psh.sh_virtsize = sh.sh_size; + if (sh.sh_type != SHT_NOBITS) + psh.sh_rawsize = sh.sh_size; + else + psh.sh_char |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; + + /* + * Translate ELF section flags to PE/COFF section flags. + */ + psh.sh_char |= IMAGE_SCN_MEM_READ; + if (sh.sh_flags & SHF_WRITE) + psh.sh_char |= IMAGE_SCN_MEM_WRITE; + if (sh.sh_flags & SHF_EXECINSTR) + psh.sh_char |= IMAGE_SCN_MEM_EXECUTE | + IMAGE_SCN_CNT_CODE; + if ((sh.sh_flags & SHF_ALLOC) && (psh.sh_char & 0xF0) == 0) + psh.sh_char |= IMAGE_SCN_CNT_INITIALIZED_DATA; + for (i = 0xE; i > 0; i--) { + if (sh.sh_addralign & (1U << (i - 1))) { + psh.sh_char |= i << 20; + break; + } + } + + /* Mark relocation section "discardable". */ + if (strcmp(name, ".reloc") == 0) + psh.sh_char |= IMAGE_SCN_MEM_DISCARDABLE; + + if (pe_update_section_header(ps, &psh) < 0) { + warn("pe_update_section_header() failed"); + continue; + } + + /* Copy section content. */ + if ((pb = pe_newbuffer(ps)) == NULL) { + warn("pe_newbuffer() failed"); + continue; + } + pb->pb_align = 1; + pb->pb_off = 0; + pb->pb_size = sh.sh_size; + pb->pb_buf = d->d_buf; + } + elferr = elf_errno(); + if (elferr != 0) + warnx("elf_nextscn() failed: %s", elf_errmsg(elferr)); + + /* Update PE optional header. */ + if (pe_update_opt_header(pe, &poh) < 0) + err(EXIT_FAILURE, "pe_update_opt_header() failed"); + + /* Write out PE/COFF object. */ + if (pe_update(pe) < 0) + err(EXIT_FAILURE, "pe_update() failed"); + + pe_finish(pe); + elf_end(e); +} diff --git a/elfcopy/sections.c b/elfcopy/sections.c index 0c18171752be..ff41015faeef 100644 --- a/elfcopy/sections.c +++ b/elfcopy/sections.c @@ -34,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: sections.c 3272 2015-12-11 20:00:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: sections.c 3346 2016-01-17 20:09:15Z kaiwang27 $"); static void add_gnu_debuglink(struct elfcopy *ecp); static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); @@ -223,6 +223,7 @@ static int is_debug_section(const char *name) { const char *dbg_sec[] = { + ".apple_", ".debug", ".gnu.linkonce.wi.", ".line", @@ -369,7 +370,7 @@ create_scn(struct elfcopy *ecp) is = NULL; while ((is = elf_nextscn(ecp->ein, is)) != NULL) { if (gelf_getshdr(is, &ish) == NULL) - errx(EXIT_FAILURE, "219 gelf_getshdr failed: %s", + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", elf_errmsg(-1)); if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) errx(EXIT_FAILURE, "elf_strptr failed: %s", @@ -416,12 +417,19 @@ create_scn(struct elfcopy *ecp) * is loadable, but if user explicitly set section flags * while neither "load" nor "alloc" is set, we make the * section unloadable. + * + * Sections in relocatable object is loadable if + * section flag SHF_ALLOC is set. */ if (sec_flags && (sec_flags & (SF_LOAD | SF_ALLOC)) == 0) s->loadable = 0; - else + else { s->loadable = add_to_inseg_list(ecp, s); + if ((ecp->flags & RELOCATABLE) && + (ish.sh_flags & SHF_ALLOC)) + s->loadable = 1; + } } else { /* Assuming .shstrtab is "unloadable". */ s = ecp->shstrtab; @@ -872,10 +880,10 @@ resync_sections(struct elfcopy *ecp) if (s->align == 0) s->align = 1; if (off <= s->off) { - if (!s->loadable) + if (!s->loadable || (ecp->flags & RELOCATABLE)) s->off = roundup(off, s->align); } else { - if (s->loadable) + if (s->loadable && (ecp->flags & RELOCATABLE) == 0) warnx("moving loadable section %s, " "is this intentional?", s->name); s->off = roundup(off, s->align); @@ -1025,8 +1033,11 @@ print_section(struct section *s) print_data(s->buf, s->sz); } else { id = NULL; - while ((id = elf_getdata(s->is, id)) != NULL) + while ((id = elf_getdata(s->is, id)) != NULL || + (id = elf_rawdata(s->is, id)) != NULL) { + (void) elf_errno(); print_data(id->d_buf, id->d_size); + } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_getdata() failed: %s", @@ -1046,7 +1057,9 @@ read_section(struct section *s, size_t *size) sz = 0; b = NULL; id = NULL; - while ((id = elf_getdata(s->is, id)) != NULL) { + while ((id = elf_getdata(s->is, id)) != NULL || + (id = elf_rawdata(s->is, id)) != NULL) { + (void) elf_errno(); if (b == NULL) b = malloc(id->d_size); else @@ -1074,10 +1087,10 @@ copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, GElf_Shdr ish, osh; if (gelf_getshdr(s->is, &ish) == NULL) - errx(EXIT_FAILURE, "526 gelf_getshdr() failed: %s", + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); if (gelf_getshdr(s->os, &osh) == NULL) - errx(EXIT_FAILURE, "529 gelf_getshdr() failed: %s", + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); if (copy) @@ -1094,19 +1107,32 @@ copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, if (sec_flags) { osh.sh_flags = 0; - if (sec_flags & SF_ALLOC) { + if (sec_flags & SF_ALLOC) osh.sh_flags |= SHF_ALLOC; - if (!s->loadable) - warnx("set SHF_ALLOC flag for " - "unloadable section %s", - s->name); - } if ((sec_flags & SF_READONLY) == 0) osh.sh_flags |= SHF_WRITE; if (sec_flags & SF_CODE) osh.sh_flags |= SHF_EXECINSTR; + if ((sec_flags & SF_CONTENTS) && + s->type == SHT_NOBITS && s->sz > 0) { + /* + * Convert SHT_NOBITS section to section with + * (zero'ed) content on file. + */ + osh.sh_type = s->type = SHT_PROGBITS; + if ((s->buf = calloc(1, s->sz)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + s->nocopy = 1; + } } else { osh.sh_flags = ish.sh_flags; + /* + * Newer binutils as(1) emits the section flag + * SHF_INFO_LINK for relocation sections. elfcopy + * emits this flag in the output section if it's + * missing in the input section, to remain compatible + * with binutils. + */ if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) osh.sh_flags |= SHF_INFO_LINK; } @@ -1132,11 +1158,14 @@ copy_data(struct section *s) return; if ((id = elf_getdata(s->is, NULL)) == NULL) { - elferr = elf_errno(); - if (elferr != 0) - errx(EXIT_FAILURE, "elf_getdata() failed: %s", - elf_errmsg(elferr)); - return; + (void) elf_errno(); + if ((id = elf_rawdata(s->is, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) + errx(EXIT_FAILURE, "failed to read section:" + " %s", s->name); + return; + } } if ((od = elf_newdata(s->os)) == NULL) @@ -1242,6 +1271,7 @@ insert_sections(struct elfcopy *ecp) struct sec_add *sa; struct section *s; size_t off; + uint64_t stype; /* Put these sections in the end of current list. */ off = 0; @@ -1256,8 +1286,20 @@ insert_sections(struct elfcopy *ecp) /* TODO: Add section header vma/lma, flag changes here */ + /* + * The default section type for user added section is + * SHT_PROGBITS. If the section name match certain patterns, + * elfcopy will try to set a more appropriate section type. + * However, data type is always set to ELF_T_BYTE and no + * translation is performed by libelf. + */ + stype = SHT_PROGBITS; + if (strcmp(sa->name, ".note") == 0 || + strncmp(sa->name, ".note.", strlen(".note.")) == 0) + stype = SHT_NOTE; + (void) create_external_section(ecp, sa->name, NULL, sa->content, - sa->size, off, SHT_PROGBITS, ELF_T_BYTE, 0, 1, 0, 0); + sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); } } @@ -1282,7 +1324,7 @@ update_shdr(struct elfcopy *ecp, int update_link) continue; if (gelf_getshdr(s->os, &osh) == NULL) - errx(EXIT_FAILURE, "668 gelf_getshdr failed: %s", + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", elf_errmsg(-1)); /* Find section name in string table and set sh_name. */ @@ -1361,7 +1403,7 @@ set_shstrtab(struct elfcopy *ecp) } if (gelf_getshdr(s->os, &sh) == NULL) - errx(EXIT_FAILURE, "692 gelf_getshdr() failed: %s", + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); sh.sh_addr = 0; sh.sh_addralign = 1; @@ -1428,14 +1470,17 @@ add_section(struct elfcopy *ecp, const char *arg) if (stat(fn, &sb) == -1) err(EXIT_FAILURE, "stat failed"); sa->size = sb.st_size; - if ((sa->content = malloc(sa->size)) == NULL) - err(EXIT_FAILURE, "malloc failed"); - if ((fp = fopen(fn, "r")) == NULL) - err(EXIT_FAILURE, "can not open %s", fn); - if (fread(sa->content, 1, sa->size, fp) == 0 || - ferror(fp)) - err(EXIT_FAILURE, "fread failed"); - fclose(fp); + if (sa->size > 0) { + if ((sa->content = malloc(sa->size)) == NULL) + err(EXIT_FAILURE, "malloc failed"); + if ((fp = fopen(fn, "r")) == NULL) + err(EXIT_FAILURE, "can not open %s", fn); + if (fread(sa->content, 1, sa->size, fp) == 0 || + ferror(fp)) + err(EXIT_FAILURE, "fread failed"); + fclose(fp); + } else + sa->content = NULL; STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); ecp->flags |= SEC_ADD; diff --git a/elfcopy/segments.c b/elfcopy/segments.c index 837cea5fdbe5..c003c1343e3c 100644 --- a/elfcopy/segments.c +++ b/elfcopy/segments.c @@ -34,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: segments.c 3269 2015-12-11 18:38:43Z kaiwang27 $"); +ELFTC_VCSID("$Id: segments.c 3340 2016-01-17 15:00:56Z kaiwang27 $"); static void insert_to_inseg_list(struct segment *seg, struct section *sec); @@ -107,11 +107,11 @@ adjust_addr(struct elfcopy *ecp) TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { /* Only adjust loadable section's address. */ - if (!s->loadable || s->seg == NULL) + if (!s->loadable) continue; /* Apply global LMA adjustment. */ - if (ecp->change_addr != 0) + if (ecp->change_addr != 0 && s->seg != NULL) s->lma += ecp->change_addr; if (!s->pseudo) { @@ -135,7 +135,10 @@ adjust_addr(struct elfcopy *ecp) */ TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { - /* Only adjust loadable section's LMA. */ + /* + * Only loadable section that's inside a segment can have + * LMA adjusted. + */ if (!s->loadable || s->seg == NULL) continue; @@ -173,7 +176,7 @@ adjust_addr(struct elfcopy *ecp) if (lma % s->align != 0) errx(EXIT_FAILURE, "The load address %#jx for " "section %s is not aligned to %ju", - (uintmax_t) lma, s->name, s->align); + (uintmax_t) lma, s->name, (uintmax_t) s->align); if (lma < s->lma) { /* Move section to lower address. */ @@ -214,7 +217,8 @@ adjust_addr(struct elfcopy *ecp) continue; errx(EXIT_FAILURE, "The extent of segment containing " "section %s overlaps with segment(%#jx,%#jx)", - s->name, seg->addr, seg->addr + seg->msz); + s->name, (uintmax_t) seg->addr, + (uintmax_t) (seg->addr + seg->msz)); } /* diff --git a/elfcopy/symbols.c b/elfcopy/symbols.c index 05bcd7a8e2f8..ae6193c212fe 100644 --- a/elfcopy/symbols.c +++ b/elfcopy/symbols.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -33,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: symbols.c 3222 2015-05-24 23:47:23Z kaiwang27 $"); +ELFTC_VCSID("$Id: symbols.c 3376 2016-01-26 18:41:39Z emaste $"); /* Symbol table buffer structure. */ struct symbuf { @@ -79,7 +80,6 @@ static int lookup_exact_string(hash_head *hash, const char *buf, static int generate_symbols(struct elfcopy *ecp); static void mark_reloc_symbols(struct elfcopy *ecp, size_t sc); static void mark_section_group_symbols(struct elfcopy *ecp, size_t sc); -static int match_wildcard(const char *name, const char *pattern); uint32_t str_hash(const char *s); /* Convenient bit vector operation macros. */ @@ -102,7 +102,8 @@ static int is_global_symbol(unsigned char st_info) { - if (GELF_ST_BIND(st_info) == STB_GLOBAL) + if (GELF_ST_BIND(st_info) == STB_GLOBAL || + GELF_ST_BIND(st_info) == STB_GNU_UNIQUE) return (1); return (0); @@ -190,12 +191,6 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s, SHN_UNDEF, /* st_shndx */ }; - if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) - return (0); - - if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL) - return (1); - /* * Keep the first symbol if it is the special reserved symbol. * XXX Should we generate one if it's missing? @@ -208,15 +203,34 @@ is_remove_symbol(struct elfcopy *ecp, size_t sc, int i, GElf_Sym *s, ecp->secndx[s->st_shndx] == 0) return (1); + /* Keep the symbol if specified by command line option -K. */ + if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) + return (0); + if (ecp->strip == STRIP_ALL) return (1); + /* Mark symbols used in relocation. */ if (ecp->v_rel == NULL) mark_reloc_symbols(ecp, sc); + /* Mark symbols used in section groups. */ if (ecp->v_grp == NULL) mark_section_group_symbols(ecp, sc); + /* + * Strip the symbol if specified by command line option -N, + * unless it's used in relocation. + */ + if (lookup_symop_list(ecp, name, SYMOP_STRIP) != NULL) { + if (BIT_ISSET(ecp->v_rel, i)) { + warnx("not stripping symbol `%s' because it is named" + " in a relocation", name); + return (0); + } + return (1); + } + if (is_needed_symbol(ecp, i, s)) return (0); @@ -565,8 +579,11 @@ generate_symbols(struct elfcopy *ecp) * If the symbol is a STT_SECTION symbol, mark the section * it points to. */ - if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && + sym.st_shndx < SHN_LORESERVE) { + assert(ecp->secndx[sym.st_shndx] < (uint64_t)ecp->nos); BIT_SET(ecp->v_secsym, ecp->secndx[sym.st_shndx]); + } } /* @@ -861,6 +878,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value, * It handles buffer growing, st_name calculating and st_shndx * updating for symbols with non-special section index. */ +#define _ST_NAME_EMPTY_l 0 +#define _ST_NAME_EMPTY_g -1 #define _ADDSYM(B, SZ) do { \ if (sy_buf->B##SZ == NULL) { \ sy_buf->B##SZ = malloc(sy_buf->B##cap * \ @@ -920,7 +939,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value, st_buf->B.sz += strlen(name) + 1; \ } \ } else \ - sy_buf->B##SZ[sy_buf->n##B##s].st_name = 0; \ + sy_buf->B##SZ[sy_buf->n##B##s].st_name = \ + (Elf##SZ##_Word)_ST_NAME_EMPTY_##B; \ sy_buf->n##B##s++; \ } while (0) @@ -945,6 +965,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value, ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz; #undef _ADDSYM +#undef _ST_NAME_EMPTY_l +#undef _ST_NAME_EMPTY_g } void @@ -961,10 +983,17 @@ finalize_external_symtab(struct elfcopy *ecp) sy_buf = ecp->symtab->buf; st_buf = ecp->strtab->buf; for (i = 0; (size_t) i < sy_buf->ngs; i++) { - if (ecp->oec == ELFCLASS32) - sy_buf->g32[i].st_name += st_buf->l.sz; - else - sy_buf->g64[i].st_name += st_buf->l.sz; + if (ecp->oec == ELFCLASS32) { + if (sy_buf->g32[i].st_name == (Elf32_Word)-1) + sy_buf->g32[i].st_name = 0; + else + sy_buf->g32[i].st_name += st_buf->l.sz; + } else { + if (sy_buf->g64[i].st_name == (Elf64_Word)-1) + sy_buf->g64[i].st_name = 0; + else + sy_buf->g64[i].st_name += st_buf->l.sz; + } } } @@ -1105,46 +1134,47 @@ add_to_symop_list(struct elfcopy *ecp, const char *name, const char *newname, { struct symop *s; - if ((s = lookup_symop_list(ecp, name, ~0U)) == NULL) { - if ((s = calloc(1, sizeof(*s))) == NULL) - errx(EXIT_FAILURE, "not enough memory"); - s->name = name; - if (op == SYMOP_REDEF) - s->newname = newname; - } + assert (name != NULL); + STAILQ_FOREACH(s, &ecp->v_symop, symop_list) + if (!strcmp(name, s->name)) + goto found; - s->op |= op; + if ((s = calloc(1, sizeof(*s))) == NULL) + errx(EXIT_FAILURE, "not enough memory"); STAILQ_INSERT_TAIL(&ecp->v_symop, s, symop_list); -} - -static int -match_wildcard(const char *name, const char *pattern) -{ - int reverse, match; - - reverse = 0; - if (*pattern == '!') { - reverse = 1; - pattern++; - } - - match = 0; - if (!fnmatch(pattern, name, 0)) - match = 1; - - return (reverse ? !match : match); + s->name = name; +found: + if (op == SYMOP_REDEF) + s->newname = newname; + s->op |= op; } struct symop * lookup_symop_list(struct elfcopy *ecp, const char *name, unsigned int op) { - struct symop *s; + struct symop *s, *ret; + const char *pattern; STAILQ_FOREACH(s, &ecp->v_symop, symop_list) { - if (name == NULL || !strcmp(name, s->name) || - ((ecp->flags & WILDCARD) && match_wildcard(name, s->name))) - if ((s->op & op) != 0) + if ((s->op & op) == 0) + continue; + if (name == NULL || !strcmp(name, s->name)) return (s); + if ((ecp->flags & WILDCARD) == 0) + continue; + + /* Handle wildcards. */ + pattern = s->name; + if (pattern[0] == '!') { + /* Negative match. */ + pattern++; + ret = NULL; + } else { + /* Regular wildcard match. */ + ret = s; + } + if (!fnmatch(pattern, name, 0)) + return (ret); } return (NULL); diff --git a/elfdump/elfdump.c b/elfdump/elfdump.c index baf99eee1e90..334d2856190a 100644 --- a/elfdump/elfdump.c +++ b/elfdump/elfdump.c @@ -50,7 +50,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: elfdump.c 3250 2015-10-06 13:56:15Z emaste $"); +ELFTC_VCSID("$Id: elfdump.c 3391 2016-02-05 19:43:01Z emaste $"); #if defined(ELFTC_NEED_ELF_NOTE_DEFINITION) #include "native-elf-format.h" @@ -155,77 +155,82 @@ le32dec(const void *pp) static const char * d_tags(uint64_t tag) { + static char unknown_buf[64]; + switch (tag) { - case 0: return "DT_NULL"; - case 1: return "DT_NEEDED"; - case 2: return "DT_PLTRELSZ"; - case 3: return "DT_PLTGOT"; - case 4: return "DT_HASH"; - case 5: return "DT_STRTAB"; - case 6: return "DT_SYMTAB"; - case 7: return "DT_RELA"; - case 8: return "DT_RELASZ"; - case 9: return "DT_RELAENT"; - case 10: return "DT_STRSZ"; - case 11: return "DT_SYMENT"; - case 12: return "DT_INIT"; - case 13: return "DT_FINI"; - case 14: return "DT_SONAME"; - case 15: return "DT_RPATH"; - case 16: return "DT_SYMBOLIC"; - case 17: return "DT_REL"; - case 18: return "DT_RELSZ"; - case 19: return "DT_RELENT"; - case 20: return "DT_PLTREL"; - case 21: return "DT_DEBUG"; - case 22: return "DT_TEXTREL"; - case 23: return "DT_JMPREL"; - case 24: return "DT_BIND_NOW"; - case 25: return "DT_INIT_ARRAY"; - case 26: return "DT_FINI_ARRAY"; - case 27: return "DT_INIT_ARRAYSZ"; - case 28: return "DT_FINI_ARRAYSZ"; - case 29: return "DT_RUNPATH"; - case 30: return "DT_FLAGS"; - case 32: return "DT_PREINIT_ARRAY"; /* XXX: DT_ENCODING */ - case 33: return "DT_PREINIT_ARRAYSZ"; + case DT_NULL: return "DT_NULL"; + case DT_NEEDED: return "DT_NEEDED"; + case DT_PLTRELSZ: return "DT_PLTRELSZ"; + case DT_PLTGOT: return "DT_PLTGOT"; + case DT_HASH: return "DT_HASH"; + case DT_STRTAB: return "DT_STRTAB"; + case DT_SYMTAB: return "DT_SYMTAB"; + case DT_RELA: return "DT_RELA"; + case DT_RELASZ: return "DT_RELASZ"; + case DT_RELAENT: return "DT_RELAENT"; + case DT_STRSZ: return "DT_STRSZ"; + case DT_SYMENT: return "DT_SYMENT"; + case DT_INIT: return "DT_INIT"; + case DT_FINI: return "DT_FINI"; + case DT_SONAME: return "DT_SONAME"; + case DT_RPATH: return "DT_RPATH"; + case DT_SYMBOLIC: return "DT_SYMBOLIC"; + case DT_REL: return "DT_REL"; + case DT_RELSZ: return "DT_RELSZ"; + case DT_RELENT: return "DT_RELENT"; + case DT_PLTREL: return "DT_PLTREL"; + case DT_DEBUG: return "DT_DEBUG"; + case DT_TEXTREL: return "DT_TEXTREL"; + case DT_JMPREL: return "DT_JMPREL"; + case DT_BIND_NOW: return "DT_BIND_NOW"; + case DT_INIT_ARRAY: return "DT_INIT_ARRAY"; + case DT_FINI_ARRAY: return "DT_FINI_ARRAY"; + case DT_INIT_ARRAYSZ: return "DT_INIT_ARRAYSZ"; + case DT_FINI_ARRAYSZ: return "DT_FINI_ARRAYSZ"; + case DT_RUNPATH: return "DT_RUNPATH"; + case DT_FLAGS: return "DT_FLAGS"; + case DT_PREINIT_ARRAY: return "DT_PREINIT_ARRAY"; /* XXX DT_ENCODING */ + case DT_PREINIT_ARRAYSZ:return "DT_PREINIT_ARRAYSZ"; /* 0x6000000D - 0x6ffff000 operating system-specific semantics */ - case 0x6ffffdf5: return "DT_GNU_PRELINKED"; - case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ"; - case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ"; - case 0x6ffffdf8: return "DT_SUNW_CHECKSUM"; - case 0x6ffffdf9: return "DT_PLTPADSZ"; - case 0x6ffffdfa: return "DT_MOVEENT"; - case 0x6ffffdfb: return "DT_MOVESZ"; - case 0x6ffffdfc: return "DT_FEATURE"; - case 0x6ffffdfd: return "DT_POSFLAG_1"; - case 0x6ffffdfe: return "DT_SYMINSZ"; - case 0x6ffffdff: return "DT_SYMINENT (DT_VALRNGHI)"; - case 0x6ffffe00: return "DT_ADDRRNGLO"; - case 0x6ffffef5: return "DT_GNU_HASH"; - case 0x6ffffef8: return "DT_GNU_CONFLICT"; - case 0x6ffffef9: return "DT_GNU_LIBLIST"; - case 0x6ffffefa: return "DT_CONFIG"; - case 0x6ffffefb: return "DT_DEPAUDIT"; - case 0x6ffffefc: return "DT_AUDIT"; - case 0x6ffffefd: return "DT_PLTPAD"; - case 0x6ffffefe: return "DT_MOVETAB"; - case 0x6ffffeff: return "DT_SYMINFO (DT_ADDRRNGHI)"; - case 0x6ffffff9: return "DT_RELACOUNT"; - case 0x6ffffffa: return "DT_RELCOUNT"; - case 0x6ffffffb: return "DT_FLAGS_1"; - case 0x6ffffffc: return "DT_VERDEF"; - case 0x6ffffffd: return "DT_VERDEFNUM"; - case 0x6ffffffe: return "DT_VERNEED"; - case 0x6fffffff: return "DT_VERNEEDNUM"; - case 0x6ffffff0: return "DT_GNU_VERSYM"; + case 0x6ffffdf5: return "DT_GNU_PRELINKED"; + case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ"; + case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ"; + case 0x6ffffdf8: return "DT_SUNW_CHECKSUM"; + case DT_PLTPADSZ: return "DT_PLTPADSZ"; + case DT_MOVEENT: return "DT_MOVEENT"; + case DT_MOVESZ: return "DT_MOVESZ"; + case 0x6ffffdfc: return "DT_FEATURE"; + case DT_POSFLAG_1: return "DT_POSFLAG_1"; + case DT_SYMINSZ: return "DT_SYMINSZ"; + case DT_SYMINENT: return "DT_SYMINENT (DT_VALRNGHI)"; + case DT_ADDRRNGLO: return "DT_ADDRRNGLO"; + case DT_GNU_HASH: return "DT_GNU_HASH"; + case 0x6ffffef8: return "DT_GNU_CONFLICT"; + case 0x6ffffef9: return "DT_GNU_LIBLIST"; + case 0x6ffffefa: return "DT_CONFIG"; + case 0x6ffffefb: return "DT_DEPAUDIT"; + case 0x6ffffefc: return "DT_AUDIT"; + case 0x6ffffefd: return "DT_PLTPAD"; + case 0x6ffffefe: return "DT_MOVETAB"; + case DT_SYMINFO: return "DT_SYMINFO (DT_ADDRRNGHI)"; + case DT_RELACOUNT: return "DT_RELACOUNT"; + case DT_RELCOUNT: return "DT_RELCOUNT"; + case DT_FLAGS_1: return "DT_FLAGS_1"; + case DT_VERDEF: return "DT_VERDEF"; + case DT_VERDEFNUM: return "DT_VERDEFNUM"; + case DT_VERNEED: return "DT_VERNEED"; + case DT_VERNEEDNUM: return "DT_VERNEEDNUM"; + case 0x6ffffff0: return "DT_GNU_VERSYM"; /* 0x70000000 - 0x7fffffff processor-specific semantics */ - case 0x70000000: return "DT_IA_64_PLT_RESERVE"; - case 0x7ffffffd: return "DT_SUNW_AUXILIARY"; - case 0x7ffffffe: return "DT_SUNW_USED"; - case 0x7fffffff: return "DT_SUNW_FILTER"; - default: return "ERROR: TAG NOT DEFINED"; + case 0x70000000: return "DT_IA_64_PLT_RESERVE"; + case 0x7ffffffd: return "DT_SUNW_AUXILIARY"; + case 0x7ffffffe: return "DT_SUNW_USED"; + case 0x7fffffff: return "DT_SUNW_FILTER"; } + + snprintf(unknown_buf, sizeof(unknown_buf), + "", (unsigned long long)tag); + return (unknown_buf); } static const char * @@ -313,42 +318,79 @@ sh_name(struct elfdump *ed, int ndx) /* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */ static const char * -sh_types(u_int64_t sht) { - switch (sht) { - case 0: return "SHT_NULL"; - case 1: return "SHT_PROGBITS"; - case 2: return "SHT_SYMTAB"; - case 3: return "SHT_STRTAB"; - case 4: return "SHT_RELA"; - case 5: return "SHT_HASH"; - case 6: return "SHT_DYNAMIC"; - case 7: return "SHT_NOTE"; - case 8: return "SHT_NOBITS"; - case 9: return "SHT_REL"; - case 10: return "SHT_SHLIB"; - case 11: return "SHT_DYNSYM"; - case 14: return "SHT_INIT_ARRAY"; - case 15: return "SHT_FINI_ARRAY"; - case 16: return "SHT_PREINIT_ARRAY"; - case 17: return "SHT_GROUP"; - case 18: return "SHT_SYMTAB_SHNDX"; - /* 0x60000000 - 0x6fffffff operating system-specific semantics */ - case 0x6ffffff0: return "XXX:VERSYM"; - case 0x6ffffff4: return "SHT_SUNW_dof"; - case 0x6ffffff6: return "SHT_GNU_HASH"; - case 0x6ffffff7: return "SHT_GNU_LIBLIST"; - case 0x6ffffffc: return "XXX:VERDEF"; - case 0x6ffffffd: return "SHT_SUNW(GNU)_verdef"; - case 0x6ffffffe: return "SHT_SUNW(GNU)_verneed"; - case 0x6fffffff: return "SHT_SUNW(GNU)_versym"; - /* 0x70000000 - 0x7fffffff processor-specific semantics */ - case 0x70000000: return "SHT_IA_64_EXT"; - case 0x70000001: return "SHT_IA_64_UNWIND"; - case 0x7ffffffd: return "XXX:AUXILIARY"; - case 0x7fffffff: return "XXX:FILTER"; - /* 0x80000000 - 0xffffffff application programs */ - default: return "ERROR: SHT NOT DEFINED"; +sh_types(uint64_t mach, uint64_t sht) { + static char unknown_buf[64]; + + if (sht < 0x60000000) { + switch (sht) { + case SHT_NULL: return "SHT_NULL"; + case SHT_PROGBITS: return "SHT_PROGBITS"; + case SHT_SYMTAB: return "SHT_SYMTAB"; + case SHT_STRTAB: return "SHT_STRTAB"; + case SHT_RELA: return "SHT_RELA"; + case SHT_HASH: return "SHT_HASH"; + case SHT_DYNAMIC: return "SHT_DYNAMIC"; + case SHT_NOTE: return "SHT_NOTE"; + case SHT_NOBITS: return "SHT_NOBITS"; + case SHT_REL: return "SHT_REL"; + case SHT_SHLIB: return "SHT_SHLIB"; + case SHT_DYNSYM: return "SHT_DYNSYM"; + case SHT_INIT_ARRAY: return "SHT_INIT_ARRAY"; + case SHT_FINI_ARRAY: return "SHT_FINI_ARRAY"; + case SHT_PREINIT_ARRAY: return "SHT_PREINIT_ARRAY"; + case SHT_GROUP: return "SHT_GROUP"; + case SHT_SYMTAB_SHNDX: return "SHT_SYMTAB_SHNDX"; + } + } else if (sht < 0x70000000) { + /* 0x60000000-0x6fffffff operating system-specific semantics */ + switch (sht) { + case 0x6ffffff0: return "XXX:VERSYM"; + case SHT_SUNW_dof: return "SHT_SUNW_dof"; + case SHT_GNU_HASH: return "SHT_GNU_HASH"; + case 0x6ffffff7: return "SHT_GNU_LIBLIST"; + case 0x6ffffffc: return "XXX:VERDEF"; + case SHT_SUNW_verdef: return "SHT_SUNW(GNU)_verdef"; + case SHT_SUNW_verneed: return "SHT_SUNW(GNU)_verneed"; + case SHT_SUNW_versym: return "SHT_SUNW(GNU)_versym"; + } + } else if (sht < 0x80000000) { + /* 0x70000000 - 0x7fffffff processor-specific semantics */ + switch (mach) { + case EM_ARM: + switch (sht) { + case SHT_ARM_EXIDX: return "SHT_ARM_EXIDX"; + case SHT_ARM_PREEMPTMAP: return "SHT_ARM_PREEMPTMAP"; + case SHT_ARM_ATTRIBUTES: return "SHT_ARM_ATTRIBUTES"; + case SHT_ARM_DEBUGOVERLAY: + return "SHT_ARM_DEBUGOVERLAY"; + case SHT_ARM_OVERLAYSECTION: + return "SHT_ARM_OVERLAYSECTION"; + } + break; + case EM_IA_64: + switch (sht) { + case 0x70000000: return "SHT_IA_64_EXT"; + case 0x70000001: return "SHT_IA_64_UNWIND"; + } + break; + case EM_MIPS: + switch (sht) { + case SHT_MIPS_REGINFO: return "SHT_MIPS_REGINFO"; + case SHT_MIPS_OPTIONS: return "SHT_MIPS_OPTIONS"; + case SHT_MIPS_ABIFLAGS: return "SHT_MIPS_ABIFLAGS"; + } + break; + } + switch (sht) { + case 0x7ffffffd: return "XXX:AUXILIARY"; + case 0x7fffffff: return "XXX:FILTER"; + } } + /* 0x80000000 - 0xffffffff application programs */ + + snprintf(unknown_buf, sizeof(unknown_buf), + "", (unsigned long long)sht); + return (unknown_buf); } /* @@ -390,22 +432,87 @@ sh_flags(uint64_t shf) return (flg); } -static const char *st_types[] = { - "STT_NOTYPE", "STT_OBJECT", "STT_FUNC", "STT_SECTION", "STT_FILE", - "STT_COMMON", "STT_TLS" -}; +static const char * +st_type(unsigned int mach, unsigned int type) +{ + static char s_type[32]; -static const char *st_types_S[] = { - "NOTY", "OBJT", "FUNC", "SECT", "FILE" -}; + switch (type) { + case STT_NOTYPE: return "STT_NOTYPE"; + case STT_OBJECT: return "STT_OBJECT"; + case STT_FUNC: return "STT_FUNC"; + case STT_SECTION: return "STT_SECTION"; + case STT_FILE: return "STT_FILE"; + case STT_COMMON: return "STT_COMMON"; + case STT_TLS: return "STT_TLS"; + case 13: + if (mach == EM_SPARCV9) + return "STT_SPARC_REGISTER"; + break; + } + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} -static const char *st_bindings[] = { - "STB_LOCAL", "STB_GLOBAL", "STB_WEAK" -}; +static const char * +st_type_S(unsigned int type) +{ + static char s_type[32]; -static const char *st_bindings_S[] = { - "LOCL", "GLOB", "WEAK" -}; + switch (type) { + case STT_NOTYPE: return "NOTY"; + case STT_OBJECT: return "OBJT"; + case STT_FUNC: return "FUNC"; + case STT_SECTION: return "SECT"; + case STT_FILE: return "FILE"; + } + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); +} + +static const char * +st_bindings(unsigned int sbind) +{ + static char s_sbind[32]; + + switch (sbind) { + case STB_LOCAL: return "STB_LOCAL"; + case STB_GLOBAL: return "STB_GLOBAL"; + case STB_WEAK: return "STB_WEAK"; + case STB_GNU_UNIQUE: return "STB_GNU_UNIQUE"; + default: + if (sbind >= STB_LOOS && sbind <= STB_HIOS) + return "OS"; + else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) + return "PROC"; + else + snprintf(s_sbind, sizeof(s_sbind), "", + sbind); + return (s_sbind); + } +} + +static const char * +st_bindings_S(unsigned int sbind) +{ + static char s_sbind[32]; + + switch (sbind) { + case STB_LOCAL: return "LOCL"; + case STB_GLOBAL: return "GLOB"; + case STB_WEAK: return "WEAK"; + case STB_GNU_UNIQUE: return "UNIQ"; + default: + if (sbind >= STB_LOOS && sbind <= STB_HIOS) + return "OS"; + else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) + return "PROC"; + else + snprintf(s_sbind, sizeof(s_sbind), "<%#x>", + sbind); + return (s_sbind); + } +} static unsigned char st_others[] = { 'D', 'I', 'H', 'P' @@ -426,7 +533,7 @@ r_type(unsigned int mach, unsigned int type) case 4: return "R_386_PLT32"; case 5: return "R_386_COPY"; case 6: return "R_386_GLOB_DAT"; - case 7: return "R_386_JMP_SLOT"; + case 7: return "R_386_JUMP_SLOT"; case 8: return "R_386_RELATIVE"; case 9: return "R_386_GOTOFF"; case 10: return "R_386_GOTPC"; @@ -769,7 +876,7 @@ r_type(unsigned int mach, unsigned int type) case 4: return "R_X86_64_PLT32"; case 5: return "R_X86_64_COPY"; case 6: return "R_X86_64_GLOB_DAT"; - case 7: return "R_X86_64_JMP_SLOT"; + case 7: return "R_X86_64_JUMP_SLOT"; case 8: return "R_X86_64_RELATIVE"; case 9: return "R_X86_64_GOTPCREL"; case 10: return "R_X86_64_32"; @@ -1608,7 +1715,8 @@ elf_print_shdr(struct elfdump *ed) else PRT(" sh_flags: 0\n"); PRT(" sh_size: %#-14jx", (uintmax_t)s->sz); - PRT(" sh_type: [ %s ]\n", sh_types(s->type)); + PRT(" sh_type: [ %s ]\n", + sh_types(ed->ehdr.e_machine, s->type)); PRT(" sh_offset: %#-14jx", (uintmax_t)s->off); PRT(" sh_entsize: %#jx\n", (uintmax_t)s->entsize); PRT(" sh_link: %-14u", s->link); @@ -1618,7 +1726,8 @@ elf_print_shdr(struct elfdump *ed) PRT("\n"); PRT("entry: %ju\n", (uintmax_t)i); PRT("\tsh_name: %s\n", s->name); - PRT("\tsh_type: %s\n", sh_types(s->type)); + PRT("\tsh_type: %s\n", + sh_types(ed->ehdr.e_machine, s->type)); PRT("\tsh_flags: %s\n", sh_flags(s->flags)); PRT("\tsh_addr: %#jx\n", (uintmax_t)s->addr); PRT("\tsh_offset: %ju\n", (uintmax_t)s->off); @@ -1745,8 +1854,8 @@ elf_print_symtab(struct elfdump *ed, int i) PRT("0x%8.8jx ", (uintmax_t)sym.st_size); else PRT("0x%12.12jx ", (uintmax_t)sym.st_size); - PRT("%s ", st_types_S[GELF_ST_TYPE(sym.st_info)]); - PRT("%s ", st_bindings_S[GELF_ST_BIND(sym.st_info)]); + PRT("%s ", st_type_S(GELF_ST_TYPE(sym.st_info))); + PRT("%s ", st_bindings_S(GELF_ST_BIND(sym.st_info))); PRT("%c ", st_others[sym.st_other]); PRT("%3u ", (vs == NULL ? 0 : vs[j])); PRT("%-11.11s ", sh_name(ed, sym.st_shndx)); @@ -1757,8 +1866,9 @@ elf_print_symtab(struct elfdump *ed, int i) PRT("\tst_value: %#jx\n", (uintmax_t)sym.st_value); PRT("\tst_size: %ju\n", (uintmax_t)sym.st_size); PRT("\tst_info: %s %s\n", - st_types[GELF_ST_TYPE(sym.st_info)], - st_bindings[GELF_ST_BIND(sym.st_info)]); + st_type(ed->ehdr.e_machine, + GELF_ST_TYPE(sym.st_info)), + st_bindings(GELF_ST_BIND(sym.st_info))); PRT("\tst_shndx: %ju\n", (uintmax_t)sym.st_shndx); } } @@ -2173,11 +2283,14 @@ elf_print_got_section(struct elfdump *ed, struct section *s) for(i = 0; i < len; i++) { PRT("[%5.5d] ", i); if (ed->ec == ELFCLASS32) { - PRT("%-8.8jx ", s->addr + i * s->entsize); + PRT("%-8.8jx ", + (uintmax_t) (s->addr + i * s->entsize)); PRT("%-8.8x ", *((uint32_t *)dst.d_buf + i)); } else { - PRT("%-16.16jx ", s->addr + i * s->entsize); - PRT("%-16.16jx ", *((uint64_t *)dst.d_buf + i)); + PRT("%-16.16jx ", + (uintmax_t) (s->addr + i * s->entsize)); + PRT("%-16.16jx ", + (uintmax_t) *((uint64_t *)dst.d_buf + i)); } PRT("%-18s ", r_type(ed->ehdr.e_machine, GELF_R_TYPE(got[i].u_r.rel.r_info))); @@ -2198,7 +2311,8 @@ elf_print_got_section(struct elfdump *ed, struct section *s) if (ed->ec == ELFCLASS32) PRT("\t%#x\n", *((uint32_t *)dst.d_buf + i)); else - PRT("\t%#jx\n", *((uint64_t *)dst.d_buf + i)); + PRT("\t%#jx\n", + (uintmax_t) *((uint64_t *)dst.d_buf + i)); } } } diff --git a/elfdump/os.NetBSD.mk b/elfdump/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/elfdump/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/findtextrel/findtextrel.c b/findtextrel/findtextrel.c index 91baa54618cd..ad493cf75398 100644 --- a/findtextrel/findtextrel.c +++ b/findtextrel/findtextrel.c @@ -38,7 +38,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: findtextrel.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: findtextrel.c 3359 2016-01-24 17:06:20Z jkoshy $"); static struct option longopts[] = { {"help", no_argument, NULL, 'H'}, @@ -70,11 +70,11 @@ version(void) static const char * find_symbol(const char *fn, Elf *e, Elf_Data *d, GElf_Shdr *sh, uintmax_t off) { - GElf_Sym sym; const char *name; + GElf_Sym sym; int i, len; - len = d->d_size / sh->sh_entsize; + len = (int) (d->d_size / sh->sh_entsize); for (i = 0; i < len; i++) { if (gelf_getsym(d, i, &sym) != &sym) { warnx("%s: gelf_getsym() failed: %s", fn, @@ -215,7 +215,7 @@ report_textrel(const char *fn, Elf *e, Dwarf_Debug dbg, uintmax_t off, out: if (found) - printf(", file: %s, line: %ju", file, lineno); + printf(", file: %s, line: %ju", file, (uintmax_t) lineno); /* * Reset internal CU pointer, so we will start from the first CU @@ -236,11 +236,11 @@ static void examine_reloc(const char *fn, Elf *e, Elf_Data *d, GElf_Shdr *sh, GElf_Phdr *ph, int phnum, Dwarf_Debug dbg, int *textrel) { - GElf_Rel rel; GElf_Rela rela; int i, j, len; + GElf_Rel rel; - len = d->d_size / sh->sh_entsize; + len = (int) (d->d_size / sh->sh_entsize); for (i = 0; i < len; i++) { if (sh->sh_type == SHT_REL) { if (gelf_getrel(d, i, &rel) != &rel) { diff --git a/ld/Makefile b/ld/Makefile index 64d4eb270b81..2037f01aa91e 100644 --- a/ld/Makefile +++ b/ld/Makefile @@ -1,9 +1,9 @@ -# $Id: Makefile 2910 2013-02-03 06:06:23Z kaiwang27 $ +# $Id: Makefile 3385 2016-01-31 14:26:26Z jkoshy $ TOP= .. PROG= ld -WARNS?= 6 +WARNS?= 5 SRCS= amd64.c \ amd64_script.c \ @@ -24,26 +24,31 @@ SRCS= amd64.c \ ld_path.c \ ld_reloc.c \ ld_script.c \ - ld_script_lexer.l \ - ld_script_parser.y \ ld_strtab.c \ ld_symbols.c \ ld_symver.c \ - y.tab.h + mips.c \ + littlemips_script.c \ + bigmips_script.c -.SUFFIXES: .ld .c -.ld.c: - awk -f ld_script.awk ${.ALLSRC} > ${.TARGET} +LSRC= ld_script_lexer.l +YSRC= ld_script_parser.y -GENSRCS= amd64_script.c i386_script.c +GENSRCS= amd64_script.c i386_script.c littlemips_script.c \ + bigmips_script.c -CLEANFILES+= y.tab.h ${GENSRCS} +CLEANFILES+= ${GENSRCS} DPADD= ${LIBELFTC} ${LIBELF} ${LIBDWARF} LDADD= -lelftc -ldwarf -lelf CFLAGS+= -I. -I${.CURDIR} +YFLAGS= -d NOMAN= +.SUFFIXES: .ld .c +.ld.c: + awk -f ld_script.awk ${.ALLSRC} > ${.TARGET} + .include "${TOP}/mk/elftoolchain.prog.mk" diff --git a/ld/amd64.c b/ld/amd64.c index 565995ba4809..e22520bfebf9 100644 --- a/ld/amd64.c +++ b/ld/amd64.c @@ -35,7 +35,7 @@ #include "ld_utils.h" #include "amd64.h" -ELFTC_VCSID("$Id: amd64.c 2963 2013-08-25 17:29:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: amd64.c 3390 2016-02-05 16:15:58Z emaste $"); static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset); @@ -115,7 +115,7 @@ _reloc2str(uint64_t r) case 4: return "R_X86_64_PLT32"; case 5: return "R_X86_64_COPY"; case 6: return "R_X86_64_GLOB_DAT"; - case 7: return "R_X86_64_JMP_SLOT"; + case 7: return "R_X86_64_JUMP_SLOT"; case 8: return "R_X86_64_RELATIVE"; case 9: return "R_X86_64_GOTPCREL"; case 10: return "R_X86_64_32"; @@ -133,7 +133,7 @@ _reloc2str(uint64_t r) case 22: return "R_X86_64_GOTTPOFF"; case 23: return "R_X86_64_TPOFF32"; default: - snprintf(s, sizeof(s), "", r); + snprintf(s, sizeof(s), "", (uintmax_t) r); return (s); } } @@ -268,12 +268,11 @@ static void _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb) { struct ld_input_section *is; - uint64_t off; is = _find_and_create_gotplt_section(ld, 1); /* Reserve a GOT entry for PLT. */ - off = ld_input_reserve_ibuf(is, 1); + (void) ld_input_reserve_ibuf(is, 1); /* * Record a R_X86_64_JUMP_SLOT entry for this symbol. Note that diff --git a/ld/bigmips_script.ld b/ld/bigmips_script.ld new file mode 100644 index 000000000000..7f60e19bd9f8 --- /dev/null +++ b/ld/bigmips_script.ld @@ -0,0 +1,165 @@ +/* $Id$ */ + +OUTPUT_FORMAT("elf32-bigmips") +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE (__executable_start = 0x00400000); + . = 0x00400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x00000000 + .plt : { *(.plt) } + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x00000000 + .fini : + { + KEEP(*(.fini)) + } = 0x00000000 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + + .tdata : ALIGN(4096) { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .dynamic : { *(.dynamic) } + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .got : { *(.got.plt) *(.got) } + .data : + { + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _gp = ALIGN(16) + 0x7ff0; + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + /* Align the end of data segment to page boundary. */ + . = ALIGN(. != 0 ? 4096 : 1); + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + _fbss = .; + .sbss : ALIGN(8) + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) *(.reginfo) } +} diff --git a/ld/i386.c b/ld/i386.c index fab5643f4fe9..760424a017a9 100644 --- a/ld/i386.c +++ b/ld/i386.c @@ -34,7 +34,7 @@ #include "ld_utils.h" #include "i386.h" -ELFTC_VCSID("$Id: i386.c 2967 2013-10-12 23:58:13Z kaiwang27 $"); +ELFTC_VCSID("$Id: i386.c 3391 2016-02-05 19:43:01Z emaste $"); static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset); @@ -93,7 +93,7 @@ _reloc2str(uint64_t r) case 4: return "R_386_PLT32"; case 5: return "R_386_COPY"; case 6: return "R_386_GLOB_DAT"; - case 7: return "R_386_JMP_SLOT"; + case 7: return "R_386_JUMP_SLOT"; case 8: return "R_386_RELATIVE"; case 9: return "R_386_GOTOFF"; case 10: return "R_386_GOTPC"; @@ -119,7 +119,7 @@ _reloc2str(uint64_t r) case 37: return "R_386_TLS_TPOFF32"; default: - snprintf(s, sizeof(s), "", r); + snprintf(s, sizeof(s), "", (uintmax_t) r); return (s); } } @@ -253,15 +253,14 @@ static void _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb) { struct ld_input_section *is; - uint64_t off; is = _find_and_create_gotplt_section(ld, 1); /* Reserve a GOT entry for PLT. */ - off = ld_input_reserve_ibuf(is, 1); + (void) ld_input_reserve_ibuf(is, 1); /* - * Record a R_386_JMP_SLOT entry for this symbol. Note that + * Record a R_386_JUMP_SLOT entry for this symbol. Note that * we don't need to record the offset (relative to the GOT section) * here, since the PLT relocations will be sorted later and we * will generate GOT section according to the new order. @@ -284,7 +283,7 @@ static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset) { - ld_reloc_create_entry(ld, ".rel.plt", NULL, R_386_JMP_SLOT, + ld_reloc_create_entry(ld, ".rel.plt", NULL, R_386_JUMP_SLOT, lsb, offset, 0); lsb->lsb_dynrel = 1; diff --git a/ld/ld_arch.c b/ld/ld_arch.c index 33baa132aaab..186beea7cb14 100644 --- a/ld/ld_arch.c +++ b/ld/ld_arch.c @@ -28,8 +28,9 @@ #include "ld_arch.h" #include "i386.h" #include "amd64.h" +#include "mips.h" -ELFTC_VCSID("$Id: ld_arch.c 2515 2012-06-06 23:05:00Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_arch.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); #define LD_DEFAULT_ARCH "amd64" @@ -48,6 +49,7 @@ ld_arch_init(struct ld *ld) i386_register(ld); amd64_register(ld); + mips_register(ld); /* * Find out default arch for output object. @@ -112,7 +114,8 @@ ld_arch_equal(struct ld_arch *a1, struct ld_arch *a2) } void -ld_arch_verify(struct ld *ld, const char *name, int mach) +ld_arch_verify(struct ld *ld, const char *name, int mach, int endian, + unsigned flags) { struct ld_arch *la; struct ld_state *ls; @@ -120,7 +123,7 @@ ld_arch_verify(struct ld *ld, const char *name, int mach) assert(ld->ld_arch != NULL); ls = &ld->ld_state; - if ((la = ld_arch_guess_arch_name(ld, mach)) == NULL) + if ((la = ld_arch_guess_arch_name(ld, mach, endian)) == NULL) ld_fatal(ld, "%s: ELF object architecture %#x not supported", name, mach); @@ -133,11 +136,17 @@ ld_arch_verify(struct ld *ld, const char *name, int mach) ld->ld_arch = la; } + if (ls->ls_first_elf_object) { + la->flags = flags; + } else if (la->merge_flags) { + la->merge_flags(ld, flags); + } + ls->ls_first_elf_object = 0; } struct ld_arch * -ld_arch_guess_arch_name(struct ld *ld, int mach) +ld_arch_guess_arch_name(struct ld *ld, int mach, int endian) { char arch[MAX_ARCH_NAME_LEN + 1]; @@ -152,7 +161,8 @@ ld_arch_guess_arch_name(struct ld *ld, int mach) break; case EM_MIPS: case EM_MIPS_RS3_LE: - snprintf(arch, sizeof(arch), "%s", "mips"); + snprintf(arch, sizeof(arch), "%s", + endian==ELFDATA2MSB ? "bigmips" : "littlemips"); break; case EM_PPC: case EM_PPC64: diff --git a/ld/ld_arch.h b/ld/ld_arch.h index f1f840339138..2165627d68d0 100644 --- a/ld/ld_arch.h +++ b/ld/ld_arch.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ld_arch.h 2913 2013-02-16 07:15:24Z kaiwang27 $ + * $Id: ld_arch.h 3281 2015-12-11 21:39:23Z kaiwang27 $ */ #define MAX_ARCH_NAME_LEN 64 @@ -47,11 +47,13 @@ struct ld_arch { void (*finalize_reloc)(struct ld *, struct ld_input_section *, struct ld_reloc_entry *); void (*finalize_got_and_plt)(struct ld *); + void (*merge_flags)(struct ld *, unsigned flags); int (*is_absolute_reloc)(uint64_t); int (*is_relative_reloc)(uint64_t); unsigned char reloc_is_64bit; unsigned char reloc_is_rela; size_t reloc_entsize; + unsigned flags; /* processor-specific flags */ UT_hash_handle hh; struct ld_arch *alias; }; @@ -59,7 +61,7 @@ struct ld_arch { void ld_arch_init(struct ld *); int ld_arch_equal(struct ld_arch *, struct ld_arch *); struct ld_arch *ld_arch_find(struct ld *, char *); -struct ld_arch *ld_arch_guess_arch_name(struct ld *, int); +struct ld_arch *ld_arch_guess_arch_name(struct ld *, int, int); void ld_arch_set(struct ld *, char *); void ld_arch_set_from_target(struct ld *); -void ld_arch_verify(struct ld *, const char *, int); +void ld_arch_verify(struct ld *, const char *, int, int, unsigned); diff --git a/ld/ld_dynamic.c b/ld/ld_dynamic.c index 371e0caa6677..aa0ab6991d71 100644 --- a/ld/ld_dynamic.c +++ b/ld/ld_dynamic.c @@ -37,7 +37,7 @@ #include "ld_symver.h" #include "ld_strtab.h" -ELFTC_VCSID("$Id: ld_dynamic.c 2965 2013-09-10 02:46:29Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_dynamic.c 3384 2016-01-31 13:12:41Z jkoshy $"); static void _check_dso_needed(struct ld *ld, struct ld_output *lo); static void _create_dynamic(struct ld *ld, struct ld_output *lo); @@ -253,7 +253,7 @@ _create_interp(struct ld *ld, struct ld_output *lo) if ((odb->odb_buf = calloc(odb->odb_size, 1)) == NULL) ld_fatal_std(ld, "calloc"); - strncpy(odb->odb_buf, interp, strlen(interp)); + strncpy((char*) odb->odb_buf, interp, strlen(interp)); odb->odb_buf[strlen(interp)] = '\0'; (void) ld_output_create_section_element(ld, os, OET_DATA_BUFFER, odb, diff --git a/ld/ld_exp.c b/ld/ld_exp.c index 8eb182c1a06e..9c57cd8b24ae 100644 --- a/ld/ld_exp.c +++ b/ld/ld_exp.c @@ -30,7 +30,7 @@ #include "ld_exp.h" #include "ld_layout.h" -ELFTC_VCSID("$Id: ld_exp.c 2526 2012-07-17 17:43:30Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_exp.c 3278 2015-12-11 21:39:13Z kaiwang27 $"); /* * Support routines for ldscript expression. @@ -202,7 +202,7 @@ ld_exp_eval(struct ld* ld, struct ld_exp *le) assert(le != NULL); switch (le->le_op) { case LEOP_ABS: - return (abs(_EXP_EVAL(le->le_e1))); + return (llabs(_EXP_EVAL(le->le_e1))); case LEOP_ADD: return (_EXP_EVAL(le->le_e1) + _EXP_EVAL(le->le_e2)); case LEOP_ADDR: @@ -569,7 +569,8 @@ static int64_t _func_data_segment_align(struct ld *ld, struct ld_exp *le) { struct ld_state *ls; - uint64_t maxpagesize, commonpagesize; + uint64_t maxpagesize; + /* uint64_t commonpagesize; */ /* * TODO: test if align to common page size use less number @@ -577,7 +578,7 @@ _func_data_segment_align(struct ld *ld, struct ld_exp *le) */ ls = &ld->ld_state; maxpagesize = _EXP_EVAL(le->le_e1); - commonpagesize = _EXP_EVAL(le->le_e2); + /* commonpagesize = _EXP_EVAL(le->le_e2); */ return (roundup(ls->ls_loc_counter, maxpagesize) + (ls->ls_loc_counter & (maxpagesize - 1))); diff --git a/ld/ld_file.c b/ld/ld_file.c index 4e9ae0057f72..b55918950f08 100644 --- a/ld/ld_file.c +++ b/ld/ld_file.c @@ -29,7 +29,7 @@ #include "ld_file.h" #include "ld_path.h" -ELFTC_VCSID("$Id: ld_file.c 2930 2013-03-17 22:54:26Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_file.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); /* * Support routines for input file handling. @@ -156,7 +156,8 @@ ld_file_load(struct ld *ld, struct ld_file *lf) ld_fatal(ld, "%s: unknown ELF type %u", ehdr.e_type); } - ld_arch_verify(ld, lf->lf_name, ehdr.e_machine); + ld_arch_verify(ld, lf->lf_name, ehdr.e_machine, ehdr.e_ident[EI_DATA], + ehdr.e_flags); } void diff --git a/ld/ld_layout.c b/ld/ld_layout.c index 11711b2d825a..c9ad07be26e3 100644 --- a/ld/ld_layout.c +++ b/ld/ld_layout.c @@ -39,7 +39,7 @@ #include "ld_symbols.h" #include "ld_strtab.h" -ELFTC_VCSID("$Id: ld_layout.c 2965 2013-09-10 02:46:29Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_layout.c 3276 2015-12-11 21:39:06Z kaiwang27 $"); struct ld_wildcard_match { char *wm_name; @@ -89,10 +89,8 @@ ld_layout_sections(struct ld *ld) struct ld_output *lo; struct ld_script *lds; struct ld_script_cmd *ldc; - struct ld_state *ls; int sections_cmd_exist; - ls = &ld->ld_state; lo = ld->ld_output; lds = ld->ld_scp; @@ -270,10 +268,10 @@ _print_section_layout(struct ld *ld, struct ld_output_section *os) printf(" %-14s", is->is_name); if (lo->lo_ec == ELFCLASS32) printf(" 0x%08jx", (uintmax_t) - os->os_addr + is->is_reloff); + (os->os_addr + is->is_reloff)); else printf(" 0x%016jx", (uintmax_t) - os->os_addr + is->is_reloff); + (os->os_addr + is->is_reloff)); if (is->is_size == 0) printf(" %10s", "0x0"); else @@ -885,7 +883,7 @@ ld_layout_insert_output_section(struct ld *ld, const char *name, } _os = STAILQ_NEXT(os, os_next); - if (_os == NULL && + if (_os != NULL && (_os->os_flags & SHF_ALLOC) != (flags & SHF_ALLOC)) break; } diff --git a/ld/ld_output.c b/ld/ld_output.c index 43ea818da2c8..fc4a7762af04 100644 --- a/ld/ld_output.c +++ b/ld/ld_output.c @@ -36,7 +36,7 @@ #include "ld_strtab.h" #include "ld_symbols.h" -ELFTC_VCSID("$Id: ld_output.c 2965 2013-09-10 02:46:29Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_output.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); static void _alloc_input_section_data(struct ld *ld, Elf_Scn *scn, struct ld_input_section *is); @@ -113,7 +113,7 @@ ld_output_init(struct ld *ld) eh.e_ident[EI_CLASS] = lo->lo_ec; eh.e_ident[EI_DATA] = lo->lo_endian; - eh.e_flags = 0; /* TODO */ + eh.e_flags = ld->ld_arch->flags; eh.e_machine = elftc_bfd_target_machine(ld->ld_otgt); if (ld->ld_dso || ld->ld_pie) eh.e_type = ET_DYN; @@ -916,7 +916,8 @@ ld_output_create(struct ld *ld) ld_input_alloc_internal_section_buffers(ld); /* Finalize PLT and GOT sections. */ - ld->ld_arch->finalize_got_and_plt(ld); + if (ld->ld_arch->finalize_got_and_plt) + ld->ld_arch->finalize_got_and_plt(ld); /* Join and sort dynamic relocation sections. */ _join_and_finalize_dynamic_reloc_sections(ld, lo); diff --git a/ld/ld_script.c b/ld/ld_script.c index 1e3d10437463..685c47d35d26 100644 --- a/ld/ld_script.c +++ b/ld/ld_script.c @@ -30,8 +30,9 @@ #include "ld_script.h" #include "ld_file.h" #include "ld_symbols.h" +#include "ld_output.h" -ELFTC_VCSID("$Id: ld_script.c 2881 2013-01-09 22:46:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_script.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); static void _input_file_add(struct ld *ld, struct ld_script_input_file *ldif); static void _overlay_section_free(void *ptr); @@ -145,6 +146,40 @@ ld_script_assign_free(struct ld_script_assign *lda) free(lda); } +static void +_update_variable_section(struct ld *ld, struct ld_script_variable *ldv) +{ + struct ld_output_section *os, *last; + + if (ldv->ldv_os_base) { + /* Get base address of the section. */ + STAILQ_FOREACH(os, &ld->ld_output->lo_oslist, os_next) { + if (strcmp(os->os_name, ldv->ldv_os_base) == 0) { + ldv->ldv_base = os->os_addr; + ldv->ldv_os_ref = ldv->ldv_os_base; + ldv->ldv_os_base = 0; + break; + } + } + } + + if (ldv->ldv_os_ref) { + /* Bind the symbol to the last section. */ + last = 0; + STAILQ_FOREACH(os, &ld->ld_output->lo_oslist, os_next) { + if (! os->os_empty) + last = os; + if (strcmp(os->os_name, ldv->ldv_os_ref) == 0) { + if (last) { + ldv->ldv_symbol->lsb_shndx = elf_ndxscn(last->os_scn); + } + ldv->ldv_os_ref = 0; + break; + } + } + } +} + void ld_script_process_assign(struct ld *ld, struct ld_script_assign *lda) { @@ -170,6 +205,10 @@ ld_script_process_assign(struct ld *ld, struct ld_script_assign *lda) (uintmax_t) ls->ls_loc_counter, (uintmax_t) ldv->ldv_val); ls->ls_loc_counter = (uint64_t) ldv->ldv_val; + + } else if (ldv->ldv_symbol != NULL) { + _update_variable_section(ld, ldv); + ldv->ldv_symbol->lsb_value = ldv->ldv_val + ldv->ldv_base; } lda->lda_res = ldv->ldv_val; } diff --git a/ld/ld_script.h b/ld/ld_script.h index ea862521c883..1de4ce0353e5 100644 --- a/ld/ld_script.h +++ b/ld/ld_script.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ld_script.h 2881 2013-01-09 22:46:54Z kaiwang27 $ + * $Id: ld_script.h 3281 2015-12-11 21:39:23Z kaiwang27 $ */ enum ld_script_cmd_type { @@ -198,8 +198,11 @@ struct ld_script_sections { struct ld_script_variable { char *ldv_name; /* variable name */ + char *ldv_os_base; /* add base address of this section */ + char *ldv_os_ref; /* link symbol to this section */ struct ld_symbol *ldv_symbol; /* assoicated symbol */ int64_t ldv_val; /* variable value */ + int64_t ldv_base; /* base value */ UT_hash_handle hh; /* hash handle */ }; @@ -242,6 +245,8 @@ struct ld_script { unsigned char lds_vn_name_omitted; /* version node w/o name exists */ struct ld_script_cmd_head lds_c; /* other ldscript cmd list */ struct ld_script_variable *lds_v; /* variable table */ + char *lds_last_os_name; /* last output section */ + char *lds_base_os_name; /* current output section */ }; struct ld_script_cmd *ld_script_assert(struct ld *, struct ld_exp *, char *); diff --git a/ld/ld_script_lexer.l b/ld/ld_script_lexer.l index 4a8ff9a2fdf6..f516da33a637 100644 --- a/ld/ld_script_lexer.l +++ b/ld/ld_script_lexer.l @@ -26,9 +26,9 @@ */ #include "ld.h" -#include "y.tab.h" +#include "ld_script_parser.h" -ELFTC_VCSID("$Id: ld_script_lexer.l 2875 2013-01-09 22:46:03Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_script_lexer.l 3385 2016-01-31 14:26:26Z jkoshy $"); #define YY_NO_UNPUT int lineno = 1; @@ -51,6 +51,7 @@ MATTR \(!?[rRwWxXaAiIlL]+\) %option noyywrap %option never-interactive +%option nounput %% diff --git a/ld/ld_script_parser.y b/ld/ld_script_parser.y index d2ffeeee1aa6..71c913145733 100644 --- a/ld/ld_script_parser.y +++ b/ld/ld_script_parser.y @@ -34,7 +34,7 @@ #include "ld_path.h" #include "ld_exp.h" -ELFTC_VCSID("$Id: ld_script_parser.y 2924 2013-03-17 22:53:36Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_script_parser.y 3281 2015-12-11 21:39:23Z kaiwang27 $"); struct yy_buffer_state; typedef struct yy_buffer_state *YY_BUFFER_STATE; @@ -756,7 +756,10 @@ sections_sub_command ; output_sections_desc - : ident output_section_addr_and_type ':' + : ident output_section_addr_and_type ':' { + /* Remember the name of last output section, needed later for assignment. */ + ld->ld_scp->lds_base_os_name = $1; + } output_section_lma output_section_align output_section_subalign @@ -772,16 +775,18 @@ output_sections_desc $$->ldso_name = $1; $$->ldso_vma = $2->ldl_entry; $$->ldso_type = $2->ldl_next->ldl_entry; - $$->ldso_lma = $4; - $$->ldso_align = $5; - $$->ldso_subalign = $6; - $$->ldso_constraint = $7; + $$->ldso_lma = $5; + $$->ldso_align = $6; + $$->ldso_subalign = $7; + $$->ldso_constraint = $8; memcpy(&$$->ldso_c, &ldso_c, sizeof(ldso_c)); - $$->ldso_region = $11; - $$->ldso_lma_region = $12; - $$->ldso_phdr = ld_script_list_reverse($13); - $$->ldso_fill = $14; + $$->ldso_region = $12; + $$->ldso_lma_region = $13; + $$->ldso_phdr = ld_script_list_reverse($14); + $$->ldso_fill = $15; STAILQ_INIT(&ldso_c); + ld->ld_scp->lds_base_os_name = 0; + ld->ld_scp->lds_last_os_name = $1; } ; diff --git a/ld/ld_strtab.c b/ld/ld_strtab.c index 59f0be2a228a..178f50fae479 100644 --- a/ld/ld_strtab.c +++ b/ld/ld_strtab.c @@ -27,7 +27,7 @@ #include "ld.h" #include "ld_strtab.h" -ELFTC_VCSID("$Id: ld_strtab.c 2965 2013-09-10 02:46:29Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_strtab.c 3279 2015-12-11 21:39:16Z kaiwang27 $"); #define _DEFAULT_STRTAB_SIZE 512 @@ -78,9 +78,6 @@ ld_strtab_free(struct ld_strtab *st) if (st == NULL) return; - free(st->st_buf); - free(st); - if (st->st_pool != NULL) { HASH_ITER(hh, st->st_pool, str, tmp) { HASH_DELETE(hh, st->st_pool, str); @@ -88,6 +85,9 @@ ld_strtab_free(struct ld_strtab *st) free(str); } } + + free(st->st_buf); + free(st); } char * diff --git a/ld/ld_symbols.c b/ld/ld_symbols.c index d49d638089b9..cb034a66b072 100644 --- a/ld/ld_symbols.c +++ b/ld/ld_symbols.c @@ -34,7 +34,7 @@ #include "ld_script.h" #include "ld_strtab.h" -ELFTC_VCSID("$Id: ld_symbols.c 2965 2013-09-10 02:46:29Z kaiwang27 $"); +ELFTC_VCSID("$Id: ld_symbols.c 3281 2015-12-11 21:39:23Z kaiwang27 $"); #define _INIT_SYMTAB_SIZE 128 @@ -171,6 +171,9 @@ ld_symbols_add_variable(struct ld *ld, struct ld_script_variable *ldv, if (hidden) lsb->lsb_other = STV_HIDDEN; lsb->lsb_ref_ndso = 1; + ldv->ldv_symbol = lsb; + ldv->ldv_os_ref = ld->ld_scp->lds_last_os_name; + ldv->ldv_os_base = ld->ld_scp->lds_base_os_name; if (ld->ld_var_symbols == NULL) { ld->ld_var_symbols = malloc(sizeof(*ld->ld_var_symbols)); diff --git a/ld/littlemips_script.ld b/ld/littlemips_script.ld new file mode 100644 index 000000000000..3fe3779a8cb7 --- /dev/null +++ b/ld/littlemips_script.ld @@ -0,0 +1,165 @@ +/* $Id$ */ + +OUTPUT_FORMAT("elf32-littlemips") +ENTRY(_start) +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + PROVIDE (__executable_start = 0x00400000); + . = 0x00400000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP(*(.init)) + } = 0x00000000 + .plt : { *(.plt) } + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + } = 0x00000000 + .fini : + { + KEEP(*(.fini)) + } = 0x00000000 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : { KEEP(*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + + .tdata : ALIGN(4096) { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + PROVIDE(__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE(__preinit_array_end = .); + PROVIDE(__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE(__init_array_end = .); + PROVIDE(__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE(__fini_array_end = .); + .dynamic : { *(.dynamic) } + .ctors : + { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors : + { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + .jcr : { KEEP(*(.jcr)) } + .got : { *(.got.plt) *(.got) } + .data : + { + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _gp = ALIGN(16) + 0x7ff0; + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + /* Align the end of data segment to page boundary. */ + . = ALIGN(. != 0 ? 4096 : 1); + _edata = .; + PROVIDE(edata = .); + __bss_start = .; + _fbss = .; + .sbss : ALIGN(8) + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE(end = .); + . = DATA_SEGMENT_END (.); + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF1 Extension */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /DISCARD/ : { *(.note.GNU-stack) *(.reginfo) } +} diff --git a/ld/mips.c b/ld/mips.c new file mode 100644 index 000000000000..59a92219a223 --- /dev/null +++ b/ld/mips.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2015 Serge Vakulenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ld.h" +#include "ld_arch.h" +#include "ld_dynamic.h" +#include "ld_input.h" +#include "ld_output.h" +#include "ld_reloc.h" +#include "ld_symbols.h" +#include "ld_utils.h" +#include "mips.h" + +#define EF_MIPS_ABI2 0x00000020 /* n32 abi */ +#define EF_MIPS_ABI 0x00007000 /* Application binary interface */ +#define E_MIPS_ABI_O32 0x00001000 /* MIPS 32 bit ABI (UCODE) */ +#define E_MIPS_ABI_O64 0x00002000 /* UCODE MIPS 64 bit ABI */ +#define E_MIPS_ABI_EABI32 0x00003000 /* Embedded ABI for 32-bit */ +#define E_MIPS_ABI_EABI64 0x00004000 /* Embedded ABI for 64-bit */ + +#define EF_MIPS_ASE_MDMX 0x08000000 /* MDMX multimedia extensions */ +#define EF_MIPS_ASE_M16 0x04000000 /* MIPS16e ISA extensions */ +#define EF_MIPS_ASE_MICROMIPS 0x02000000 /* MicroMIPS architecture */ + +#define EF_MIPS_ARCH_1 0x00000000 /* MIPS I instruction set */ +#define EF_MIPS_ARCH_2 0x10000000 /* MIPS II instruction set */ +#define EF_MIPS_ARCH_3 0x20000000 /* MIPS III instruction set */ +#define EF_MIPS_ARCH_4 0x30000000 /* MIPS IV instruction set */ +#define EF_MIPS_ARCH_5 0x40000000 /* Never introduced */ +#define EF_MIPS_ARCH_32 0x50000000 /* Mips32 Revision 1 */ +#define EF_MIPS_ARCH_64 0x60000000 /* Mips64 Revision 1 */ +#define EF_MIPS_ARCH_32R2 0x70000000 /* Mips32 Revision 2 */ +#define EF_MIPS_ARCH_64R2 0x80000000 /* Mips64 Revision 2 */ + +ELFTC_VCSID("$Id$"); + +static void +_scan_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre) +{ + + (void) is; + + switch (lre->lre_type) { + + case R_MIPS_NONE: + case R_MIPS_32: + case R_MIPS_26: + case R_MIPS_PC16: + case R_MIPS_GPREL16: + case R_MIPS_HI16: + case R_MIPS_LO16: + break; + + default: + ld_warn(ld, "can not handle relocation %ju", + lre->lre_type); + break; + } +} + +static void +_process_reloc(struct ld *ld, struct ld_input_section *is, + struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf) +{ + struct ld_output *lo = ld->ld_output; + uint32_t pc, s; + int32_t a, v, la; + static uint64_t gp; + static char gp_name[] = "_gp"; + + assert(lo != NULL); + + pc = lre->lre_offset + is->is_output->os_addr + is->is_reloff; + s = (uint32_t) lsb->lsb_value; + READ_32(buf + lre->lre_offset, a); + + switch (lre->lre_type) { + + case R_MIPS_NONE: + break; + + case R_MIPS_32: + /* 32-bit byte address. */ + v = s + a; + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_26: + /* Word address at lower 26 bits. */ + s += (a & 0x3ffffff) << 2; + v = (a & ~0x3ffffff) | ((s >> 2) & 0x3ffffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_PC16: + /* PC-relative word address at lower 16 bits. */ + s += ((a & 0xffff) << 2) - pc; + v = (a & ~0xffff) | ((s >> 2) & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_GPREL16: + /* GP-relative byte address at lower 16 bits. */ + if (! gp && ld_symbols_get_value(ld, gp_name, &gp) < 0) + ld_fatal(ld, "symbol _gp is undefined"); + + s += (int16_t)(a & 0xffff) - gp; + v = (a & ~0xffff) | (s & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_HI16: + /* 16-bit high part of address pair. */ + if (! STAILQ_NEXT(lre, lre_next) || + STAILQ_NEXT(lre, lre_next)->lre_type != R_MIPS_LO16) + ld_fatal(ld, "no LO16 after HI16 relocation"); + READ_32(buf + STAILQ_NEXT(lre, lre_next)->lre_offset, la); + s += (a << 16) + (int16_t)la; + v = (a & ~0xffff) | (((s - (int16_t)s) >> 16) & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + case R_MIPS_LO16: + /* 16-bit low part of address pair. */ + s += (int16_t)a; + v = (a & ~0xffff) | (s & 0xffff); + WRITE_32(buf + lre->lre_offset, v); + break; + + default: + ld_fatal(ld, "Relocation %d not supported", lre->lre_type); + break; + } +} + +/* + * Map flags into a valid MIPS architecture level value. + */ +static unsigned +_map_arch(unsigned flags) +{ + flags &= EF_MIPS_ARCH; + + switch (flags) { + default: + case EF_MIPS_ARCH_1: + return EF_MIPS_ARCH_1; + case EF_MIPS_ARCH_2: + case EF_MIPS_ARCH_3: + case EF_MIPS_ARCH_4: + case EF_MIPS_ARCH_5: + case EF_MIPS_ARCH_32: + case EF_MIPS_ARCH_64: + case EF_MIPS_ARCH_32R2: + case EF_MIPS_ARCH_64R2: + return flags; + } +} + +/* + * Merge architecture levels of two files. + */ +static unsigned +_merge_arch(unsigned old_arch, unsigned new_arch) +{ + unsigned base, extended; + + if (old_arch < new_arch) { + base = old_arch; + extended = new_arch; + } else if (old_arch > new_arch) { + base = new_arch; + extended = old_arch; + } else + return old_arch; + + switch (extended) { + default: + case EF_MIPS_ARCH_1: + case EF_MIPS_ARCH_2: + case EF_MIPS_ARCH_3: + case EF_MIPS_ARCH_4: + case EF_MIPS_ARCH_5: + return extended; + + case EF_MIPS_ARCH_32: + if (base <= EF_MIPS_ARCH_2) + return EF_MIPS_ARCH_32; + return EF_MIPS_ARCH_64; + + case EF_MIPS_ARCH_64: + return EF_MIPS_ARCH_64; + + case EF_MIPS_ARCH_32R2: + if (base <= EF_MIPS_ARCH_2 || base == EF_MIPS_ARCH_32) + return EF_MIPS_ARCH_32R2; + return EF_MIPS_ARCH_64R2; + + case EF_MIPS_ARCH_64R2: + return EF_MIPS_ARCH_64R2; + } +} + +static const char* +_abi_name(int flags) +{ + switch (flags & EF_MIPS_ABI) { + case 0: + return (flags & EF_MIPS_ABI2) ? "N32" : "none"; + case E_MIPS_ABI_O32: + return "O32"; + case E_MIPS_ABI_O64: + return "O64"; + case E_MIPS_ABI_EABI32: + return "EABI32"; + case E_MIPS_ABI_EABI64: + return "EABI64"; + default: + return "Unknown"; + } +} + +/* + * Merge options of application binary interface. + */ +static unsigned +_merge_abi(struct ld *ld, unsigned new_flags) +{ + int old = ld->ld_arch->flags & EF_MIPS_ABI; + int new = new_flags & EF_MIPS_ABI; + + if (old == 0) + return new; + + if (new != old && new != 0) + ld_fatal(ld, "ABI mismatch: linking '%s' module with previous '%s' modules", + _abi_name(new_flags), _abi_name(ld->ld_arch->flags)); + + return old; +} + +/* + * Merge options of application-specific extensions. + */ +static unsigned +_merge_ase(struct ld *ld, unsigned new_flags) +{ + int old_micro = ld->ld_arch->flags & EF_MIPS_ASE_MICROMIPS; + int new_micro = new_flags & EF_MIPS_ASE_MICROMIPS; + int old_m16 = ld->ld_arch->flags & EF_MIPS_ASE_M16; + int new_m16 = new_flags & EF_MIPS_ASE_M16; + + if ((old_m16 && new_micro) || (old_micro && new_m16)) + ld_fatal(ld, "ASE mismatch: linking '%s' module with previous '%s' modules", + new_m16 ? "MIPS16" : "microMIPS", + old_micro ? "microMIPS" : "MIPS16"); + return old_micro | new_micro | old_m16 | new_m16; +} + +/* + * Merge architecture-specific flags of the file to be linked + * into a resulting value for output file. + */ +static void +_merge_flags(struct ld *ld, unsigned new_flags) +{ + struct ld_arch *la = ld->ld_arch; + unsigned value; + + /* At least one .noreorder directive appeared in the source. */ + la->flags |= new_flags & EF_MIPS_NOREORDER; + + /* Merge position-independent flags. */ + if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0) != + ((la->flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)) + ld_warn(ld, "linking PIC files with non-PIC files"); + if (new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) + la->flags |= EF_MIPS_CPIC; + if (! (new_flags & EF_MIPS_PIC)) + la->flags &= ~EF_MIPS_PIC; + + /* Merge architecture level. */ + value = _merge_arch(_map_arch(la->flags), _map_arch(new_flags)); + la->flags &= ~EF_MIPS_ARCH; + la->flags |= value; + + /* Merge ABI options. */ + value = _merge_abi(ld, new_flags); + la->flags &= ~EF_MIPS_ABI; + la->flags |= value; + + /* Merge application-specific extensions. */ + value = _merge_ase(ld, new_flags); + la->flags &= ~EF_MIPS_ARCH_ASE; + la->flags |= value; +} + +static uint64_t +_get_max_page_size(struct ld *ld) +{ + + (void) ld; + + return 0x1000; +} + +static uint64_t +_get_common_page_size(struct ld *ld) +{ + + (void) ld; + + return 0x1000; +} + +static int +_is_absolute_reloc(uint64_t r) +{ + if (r == R_MIPS_32) + return 1; + + return 0; +} + +static int +_is_relative_reloc(uint64_t r) +{ + if (r == R_MIPS_REL32) + return 1; + + return 0; +} + +void +mips_register(struct ld *ld) +{ + struct ld_arch *mips_little_endian, *mips_big_endian; + + if ((mips_little_endian = calloc(1, sizeof(*mips_little_endian))) == NULL) + ld_fatal_std(ld, "calloc"); + if ((mips_big_endian = calloc(1, sizeof(*mips_big_endian))) == NULL) + ld_fatal_std(ld, "calloc"); + + /* + * Little endian. + */ + snprintf(mips_little_endian->name, sizeof(mips_little_endian->name), "%s", "littlemips"); + + mips_little_endian->script = littlemips_script; + mips_little_endian->get_max_page_size = _get_max_page_size; + mips_little_endian->get_common_page_size = _get_common_page_size; + mips_little_endian->scan_reloc = _scan_reloc; + mips_little_endian->process_reloc = _process_reloc; + mips_little_endian->is_absolute_reloc = _is_absolute_reloc; + mips_little_endian->is_relative_reloc = _is_relative_reloc; + mips_little_endian->merge_flags = _merge_flags; + mips_little_endian->reloc_is_64bit = 0; + mips_little_endian->reloc_is_rela = 0; + mips_little_endian->reloc_entsize = sizeof(Elf32_Rel); + + /* + * Big endian. + */ + snprintf(mips_big_endian->name, sizeof(mips_big_endian->name), "%s", "bigmips"); + + mips_big_endian->script = bigmips_script; + mips_big_endian->get_max_page_size = _get_max_page_size; + mips_big_endian->get_common_page_size = _get_common_page_size; + mips_big_endian->scan_reloc = _scan_reloc; + mips_big_endian->process_reloc = _process_reloc; + mips_big_endian->is_absolute_reloc = _is_absolute_reloc; + mips_big_endian->is_relative_reloc = _is_relative_reloc; + mips_little_endian->merge_flags = _merge_flags; + mips_big_endian->reloc_is_64bit = 0; + mips_big_endian->reloc_is_rela = 0; + mips_big_endian->reloc_entsize = sizeof(Elf32_Rel); + + HASH_ADD_STR(ld->ld_arch_list, name, mips_little_endian); + HASH_ADD_STR(ld->ld_arch_list, name, mips_big_endian); +} diff --git a/ld/mips.h b/ld/mips.h new file mode 100644 index 000000000000..90de4aa7fa94 --- /dev/null +++ b/ld/mips.h @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2015 Serge Vakulenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +char *littlemips_script; +char *bigmips_script; + +void mips_register(struct ld *); diff --git a/libdwarf/_libdwarf.h b/libdwarf/_libdwarf.h index e6eb496feed1..6658d2d2f6f4 100644 --- a/libdwarf/_libdwarf.h +++ b/libdwarf/_libdwarf.h @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _libdwarf.h 3164 2015-02-19 01:20:12Z kaiwang27 $ + * $Id: _libdwarf.h 3298 2016-01-09 15:43:31Z jkoshy $ */ #ifndef __LIBDWARF_H_ @@ -92,8 +92,8 @@ extern struct _libdwarf_globals _libdwarf; typedef struct _Dwarf_CU *Dwarf_CU; struct _Dwarf_AttrDef { - uint64_t ad_attrib; /* DW_AT_XXX */ - uint64_t ad_form; /* DW_FORM_XXX */ + Dwarf_Half ad_attrib; /* DW_AT_XXX */ + Dwarf_Half ad_form; /* DW_FORM_XXX */ uint64_t ad_offset; /* Offset in abbrev section. */ STAILQ_ENTRY(_Dwarf_AttrDef) ad_next; /* Next attribute define. */ }; @@ -102,8 +102,8 @@ struct _Dwarf_Attribute { Dwarf_Die at_die; /* Ptr to containing DIE. */ Dwarf_Die at_refdie; /* Ptr to reference DIE. */ uint64_t at_offset; /* Offset in info section. */ - uint64_t at_attrib; /* DW_AT_XXX */ - uint64_t at_form; /* DW_FORM_XXX */ + Dwarf_Half at_attrib; /* DW_AT_XXX */ + Dwarf_Half at_form; /* DW_FORM_XXX */ int at_indirect; /* Has indirect form. */ union { uint64_t u64; /* Unsigned value. */ diff --git a/libdwarf/dwarf.3 b/libdwarf/dwarf.3 index dbb417908094..863bee6dcfdf 100644 --- a/libdwarf/dwarf.3 +++ b/libdwarf/dwarf.3 @@ -21,7 +21,7 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: dwarf.3 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: dwarf.3 3295 2016-01-08 22:08:10Z jkoshy $ .\" .Dd December 21, 2014 .Os @@ -110,9 +110,7 @@ A pointer to an error handling function. .It Vt Dwarf_Line A descriptor for a source line. .It Vt Dwarf_Off -An unsigned file offset, corresponding to an -.Vt off_t -type supported by the underlying operating system. +An unsigned file offset. .It Vt Dwarf_P_Expr A descriptor for a location expression. .It Vt Dwarf_Ptr diff --git a/libdwarf/dwarf_str.c b/libdwarf/dwarf_str.c index 71a7f75b2842..c402f2181973 100644 --- a/libdwarf/dwarf_str.c +++ b/libdwarf/dwarf_str.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_str.c 2075 2011-10-27 03:47:28Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_str.c 3295 2016-01-08 22:08:10Z jkoshy $"); int dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, @@ -34,7 +34,7 @@ dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, { Dwarf_Section *ds; - if (dbg == NULL || offset < 0 || string == NULL || ret_strlen == NULL) { + if (dbg == NULL || string == NULL || ret_strlen == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } @@ -45,12 +45,12 @@ dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, return (DW_DLV_NO_ENTRY); } - if ((Dwarf_Unsigned) offset > ds->ds_size) { + if (offset > ds->ds_size) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } - if ((Dwarf_Unsigned) offset == ds->ds_size) { + if (offset == ds->ds_size) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } diff --git a/libdwarf/libdwarf.h b/libdwarf/libdwarf.h index 0cb8b1ae8cbc..02f0ce5f98df 100644 --- a/libdwarf/libdwarf.h +++ b/libdwarf/libdwarf.h @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: libdwarf.h 3174 2015-03-27 17:13:41Z emaste $ + * $Id: libdwarf.h 3295 2016-01-08 22:08:10Z jkoshy $ */ #ifndef _LIBDWARF_H_ @@ -33,7 +33,7 @@ #include typedef int Dwarf_Bool; -typedef off_t Dwarf_Off; +typedef uint64_t Dwarf_Off; typedef uint64_t Dwarf_Unsigned; typedef uint16_t Dwarf_Half; typedef uint8_t Dwarf_Small; diff --git a/libdwarf/libdwarf_rw.c b/libdwarf/libdwarf_rw.c index 8cb455124f4a..f0286d5fa831 100644 --- a/libdwarf/libdwarf_rw.c +++ b/libdwarf/libdwarf_rw.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_rw.c 3286 2015-12-31 16:45:46Z emaste $"); uint64_t _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) @@ -42,10 +42,13 @@ _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ case 1: ret |= src[0]; break; @@ -71,10 +74,13 @@ _dwarf_decode_lsb(uint8_t **data, int bytes_to_read) case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ case 1: ret |= src[0]; break; @@ -171,11 +177,14 @@ _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value, dst[6] = (value >> 48) & 0xff; dst[5] = (value >> 40) & 0xff; dst[4] = (value >> 32) & 0xff; + /* FALLTHROUGH */ case 4: dst[3] = (value >> 24) & 0xff; dst[2] = (value >> 16) & 0xff; + /* FALLTHROUGH */ case 2: dst[1] = (value >> 8) & 0xff; + /* FALLTHROUGH */ case 1: dst[0] = value & 0xff; break; @@ -222,13 +231,16 @@ _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value, dst[5] = (value >> 16) & 0xff; dst[4] = (value >> 24) & 0xff; value >>= 32; + /* FALLTHROUGH */ case 4: dst[3] = value & 0xff; dst[2] = (value >> 8) & 0xff; value >>= 16; + /* FALLTHROUGH */ case 2: dst[1] = value & 0xff; value >>= 8; + /* FALLTHROUGH */ case 1: dst[0] = value & 0xff; break; diff --git a/libdwarf/os.NetBSD.mk b/libdwarf/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/libdwarf/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/libelftc/Makefile b/libelftc/Makefile index a5fc2975097f..4af496b0b574 100644 --- a/libelftc/Makefile +++ b/libelftc/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2859 2013-01-05 09:21:54Z jkoshy $ +# $Id: Makefile 3292 2016-01-06 21:46:32Z jkoshy $ TOP= ${.CURDIR}/.. @@ -45,16 +45,7 @@ MLINKS= elftc_bfd_find_target.3 elftc_bfd_target_byteorder.3 \ elftc_string_table_create.3 elftc_string_table_destroy.3 \ elftc_string_table_create.3 elftc_string_table_image.3 \ elftc_string_table_create.3 elftc_string_table_insert.3 \ - elftc_string_table_create.3 elftc_string_table_lookup.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_create_nested.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_delete_name.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_delete_entry.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_destroy.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_from_section.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_insert.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_iterate.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_lookup.3 \ - elftc_symbol_table_create.3 elftc_symbol_table_to_image.3 + elftc_string_table_create.3 elftc_string_table_lookup.3 .if !make(clean) && !make(clobber) .BEGIN: .SILENT diff --git a/libelftc/elftc_bfd_find_target.3 b/libelftc/elftc_bfd_find_target.3 index 851ae314ea7e..20dea3cb97d9 100644 --- a/libelftc/elftc_bfd_find_target.3 +++ b/libelftc/elftc_bfd_find_target.3 @@ -21,7 +21,7 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: elftc_bfd_find_target.3 2251 2011-11-30 16:50:06Z jkoshy $ +.\" $Id: elftc_bfd_find_target.3 3348 2016-01-18 14:18:50Z emaste $ .\" .Dd November 30, 2011 .Os @@ -58,9 +58,11 @@ Binary object descriptors encapsulate properties of an object format such as its file representation, ELF class, and byte endianness. .Pp Known descriptor names and their properties include: -.Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "ELF Class" -.It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "ELF Class" +.Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "Bit Width" +.It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "Bit Width" .It Li binary Ta Binary Ta - Ta - +.It Li efi-app-ia32 Ta PE Ta LSB Ta 32 +.It Li efi-app-x86_64 Ta PE Ta LSB Ta 64 .It Li elf32-avr Ta ELF Ta LSB Ta 32 .It Li elf32-big Ta ELF Ta MSB Ta 32 .It Li elf32-bigarm Ta ELF Ta MSB Ta 32 @@ -101,6 +103,8 @@ Known descriptor names and their properties include: .It Li elf64-x86-64 Ta ELF Ta LSB Ta 64 .It Li elf64-x86-64-freebsd Ta ELF Ta LSB Ta 64 .It Li ihex Ta IHEX Ta - Ta - +.It Li pei-i386 Ta PE Ta LSB Ta 32 +.It Li pei-x86-64 Ta PE Ta LSB Ta 64 .It Li srec Ta SREC Ta - Ta - .It Li symbolsrec Ta SREC Ta - Ta - .El diff --git a/libelftc/elftc_copyfile.c b/libelftc/elftc_copyfile.c index 7df1678e702d..dac9c145beed 100644 --- a/libelftc/elftc_copyfile.c +++ b/libelftc/elftc_copyfile.c @@ -37,7 +37,7 @@ #include #endif -ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $"); +ELFTC_VCSID("$Id: elftc_copyfile.c 3297 2016-01-09 15:26:34Z jkoshy $"); /* * Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on @@ -47,11 +47,11 @@ ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $"); int elftc_copyfile(int ifd, int ofd) { + size_t file_size, n; int buf_mmapped; struct stat sb; char *b, *buf; - ssize_t nw; - size_t n; + ssize_t nr, nw; /* Determine the input file's size. */ if (fstat(ifd, &sb) < 0) @@ -63,12 +63,13 @@ elftc_copyfile(int ifd, int ofd) buf = NULL; buf_mmapped = 0; + file_size = (size_t) sb.st_size; #if ELFTC_HAVE_MMAP /* * Prefer mmap() if it is available. */ - buf = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0); + buf = mmap(NULL, file_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0); if (buf != MAP_FAILED) buf_mmapped = 1; else @@ -80,24 +81,27 @@ elftc_copyfile(int ifd, int ofd) * failed, allocate a buffer, and read in input data. */ if (buf_mmapped == false) { - if ((buf = malloc(sb.st_size)) == NULL) - return (-1); - if (read(ifd, buf, sb.st_size) != sb.st_size) { - free(buf); + if ((buf = malloc(file_size)) == NULL) return (-1); + b = buf; + for (n = file_size; n > 0; n -= (size_t) nr, b += nr) { + if ((nr = read(ifd, b, n)) < 0) { + free(buf); + return (-1); + } } } /* * Write data to the output file descriptor. */ - for (n = sb.st_size, b = buf; n > 0; n -= nw, b += nw) + for (n = file_size, b = buf; n > 0; n -= (size_t) nw, b += nw) if ((nw = write(ofd, b, n)) <= 0) break; /* Release the input buffer. */ #if ELFTC_HAVE_MMAP - if (buf_mmapped && munmap(buf, sb.st_size) < 0) + if (buf_mmapped && munmap(buf, file_size) < 0) return (-1); #endif diff --git a/libelftc/elftc_demangle.c b/libelftc/elftc_demangle.c index ff3095504286..945f777791be 100644 --- a/libelftc/elftc_demangle.c +++ b/libelftc/elftc_demangle.c @@ -33,10 +33,10 @@ #include "_libelftc.h" -ELFTC_VCSID("$Id: elftc_demangle.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elftc_demangle.c 3296 2016-01-09 14:17:28Z jkoshy $"); -static int -is_mangled(const char *s, int style) +static unsigned int +is_mangled(const char *s, unsigned int style) { switch (style) { @@ -58,7 +58,7 @@ is_mangled(const char *s, int style) } static char * -demangle(const char *s, int style, int rc) +demangle(const char *s, unsigned int style, unsigned int rc) { (void) rc; /* XXX */ @@ -76,7 +76,7 @@ int elftc_demangle(const char *mangledname, char *buffer, size_t bufsize, unsigned int flags) { - int style, rc; + unsigned int style, rc; char *rlt; style = flags & 0xFFFF; diff --git a/libelftc/elftc_symbol_table_create.3 b/libelftc/elftc_symbol_table_create.3 deleted file mode 100644 index 76f90e9c643d..000000000000 --- a/libelftc/elftc_symbol_table_create.3 +++ /dev/null @@ -1,529 +0,0 @@ -.\" Copyright (c) 2012 Joseph Koshy. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" This software is provided by Joseph Koshy ``as is'' and -.\" any express or implied warranties, including, but not limited to, the -.\" implied warranties of merchantability and fitness for a particular purpose -.\" are disclaimed. in no event shall Joseph Koshy be liable -.\" for any direct, indirect, incidental, special, exemplary, or consequential -.\" damages (including, but not limited to, procurement of substitute goods -.\" or services; loss of use, data, or profits; or business interruption) -.\" however caused and on any theory of liability, whether in contract, strict -.\" liability, or tort (including negligence or otherwise) arising in any way -.\" out of the use of this software, even if advised of the possibility of -.\" such damage. -.\" -.\" $Id: elftc_symbol_table_create.3 3182 2015-04-10 16:08:10Z emaste $ -.\" -.Dd December 29, 2012 -.Os -.Dt ELFTC_SYMBOL_TABLE_CREATE 3 -.Sh NAME -.Nm elftc_elf_symbol_table_from_section , -.Nm elftc_symbol_table_count , -.Nm elftc_symbol_table_create , -.Nm elftc_symbol_table_create_nested , -.Nm elftc_symbol_table_delete_name , -.Nm elftc_symbol_table_delete_entry , -.Nm elftc_symbol_table_destroy , -.Nm elftc_symbol_table_insert , -.Nm elftc_symbol_table_iterate , -.Nm elftc_symbol_table_lookup , -.Nm elftc_symbol_table_lookup_value , -.Nm elftc_symbol_table_replace , -.Nm elftc_symbol_table_sort , -.Nm elftc_symbol_table_step -.Nd symbol table management routines -.Sh SYNOPSIS -.In libelftc.h -.Bd -literal -typedef struct _Elftc_Symbol_Table Elftc_Symbol_Table; - -typedef struct _Elftc_Symbol { - ... library private fields ... - const char *sym_name; - uintptr_t sym_value; -} Elftc_Symbol; -.Ed -.Ft size_t -.Fn elftc_symbol_table_count "Elftc_Symbol_Table *table" -.Ft "Elftc_Symbol_Table *" -.Fo elftc_symbol_table_create -.Fa "size_t entrysize" -.Fa "int sizehint" -.Fc -.Ft "Elftc_Symbol_Table *" -.Fo elftc_symbol_table_create_nested -.Fa "Elftc_Symbol_Table *table" -.Fa "int sizehint" -.Fc -.Ft int -.Fo elftc_symbol_table_delete_name -.Fa "Elftc_Symbol_Table *table" -.Fa "const char *name" -.Fc -.Ft int -.Fo elftc_symbol_table_delete_entry -.Fa "Elftc_Symbol_Table *table" -.Fa "Elftc_Symbol *entry" -.Fc -.Ft int -.Fn elftc_symbol_table_destroy "Elftc_Symbol_Table *table" -.Ft "Elftc_Symbol *entry" -.Fo elftc_symbol_table_insert -.Fa "Elftc_Symbol_Table *table" -.Fa "const char *symbolname" -.Fa "int *status" -.Fc -.Ft int -.Fo elftc_symbol_table_iterate -.Fa "Elftc_Symbol_Table *table" -.Fa "int (*iterfn)(Elftc_Symbol *entry, void *cookie)" -.Fa "void *cookie" -.Fc -.Ft "Elftc_Symbol *" -.Fo elftc_symbol_table_lookup -.Fa "Elftc_Symbol_Table *table" -.Fa "const char *symbolname" -.Fc -.Ft "Elftc_Elf_Symbol *" -.Fo elftc_symbol_table_lookup_value -.Fa "Elftc_Symbol_Table *table" -.Fa "uintptr_t value" -.Fa "int searchflags" -.Fc -.Ft int -.Fo elftc_symbol_table_replace -.Fa "Elftc_Symbol_Table *table" -.Fa "Elftc_Symbol *sym1" -.Fa "Elftc_Symbol *sym2" -.Fc -.Ft int -.Fo elftc_symbol_table_sort -.Fa "Elftc_Symbol_Table *table" -.Fa "int (*cmpfn)(Elftc_Symbol *s1, Elftc_Symbol *s2)" -.Fc -.Ft "Elftc_Symbol *" -.Fo elftc_symbol_table_step -.Fa "Elftc_Symbol_Table *table" -.Fa "Elftc_Symbol *cursym" -.Fa "int direction" -.Fc -.Bd -literal -typedef struct _Elftc_Elf_Symbol { - ... library private fields ... - const char *sym_name; - Gelf_Sym sym_elf; -} Elftc_Elf_Symbol; -.Ed -.Ft "Elftc_Symbol_Table *" -.Fo elftc_elf_symbol_table_from_section -.Fa "Elf_Scn *symscn" -.Fa "Elf_Scn *strscn" -.Fc -.Sh DESCRIPTION -This manual page documents convenience routines for handling symbol -tables. -Two flavors of symbol tables are supported: -.Bl -bullet -compact -.It -.Dq Regular -symbol tables supporting insertion, deletion and lookup of entries by -name or by value, sorting of entries, and stepping through entries in -the table's current traversal order. -.It -.Dq ELF-centric -symbol tables support additional operations for conversions to and -from the symbol table format understood by -.Lb libelf . -.El -The default traversal order for a symbol table is the order in which -entries were inserted into it. -This traversal order may be changed using function -.Fn elftc_symbol_table_sort . -.Ss Operations on Regular Symbol Tables -Regular symbol tables use symbols that are subtypes of -.Vt Elftc_Symbol , -as described in the section -.Sx "Structure of a Symbol Table Entry" -below. -.Pp -Function -.Fn elftc_symbol_table_count -returns the number of entries currently in the symbol table. -.Pp -Function -.Fn elftc_symbol_table_create -creates a new, empty symbol table. -The argument -.Ar entrysize -specifies the size of each symbol table entry, as described -in the section -.Sx "Structure of a Symbol Table Entry" -below. -The argument -.Ar sizehint -specifies the expected number of symbol table entries. -If -.Ar sizehint -is zero, an implementation-defined default will be used. -.Pp -Function -.Fn elftc_symbol_table_create_nested -creates a symbol table whose search scope nests inside that of a -parent symbol table. -The argument -.Ar parent -specifies the parent symbol table to nest under. -The argument -.Ar sizehint -specifies the expected number of symbol table entries. -If -.Ar sizehint -is zero, an implementation-defined default will be used instead. -.Pp -The function -.Fn elftc_symbol_table_delete_name -removes the symbol entry named by the argument -.Ar name -from the symbol table specified by argument -.Ar table , -according to the rules described in section -.Sx "Symbol Search Rules" . -.Pp -The function -.Fn elftc_symbol_table_delete_entry -removes the symbol table entry specified by argument -.Ar entry -from the symbol table specified by argument -.Ar table . -.Pp -Function -.Fn elftc_symbol_table_destroy -is used to destroy a symbol table and free up its internal -resources. -.Pp -The function -.Fn elftc_symbol_table_insert -inserts a symbol entry for the name specified by argument -.Ar symbolname -into the symbol table specified by argument -.Ar table , -returning a pointer to a symbol table entry. -The argument -.Ar status -should point to a location that will be updated with one of -the following values: -.Bl -tag -width indent -compact -offset indent -.It Dv ELFTC_INSERT_ERROR -An error occurred during insertion of the symbol. -.It Dv ELFTC_INSERT_EXISTING -The name in argument -.Ar symbolname -was already in the symbol table, and a pointer to the existing -symbol table entry is being returned. -.It Dv ELFTC_INSERT_NEW -A new symbol table entry was allocated for the symbol name -in -.Ar symbolname . -The application will need to initialize the application-specific -fields of the symbol table entry. -.El -Insertion obeys the scoping rules described in section -.Sx "Symbol Search Rules" . -.Pp -The function -.Fn elftc_symbol_table_iterate -iterates over the symbol table specifed by argument -.Ar table , -applying the function pointed to by argument -.Ar iterfn -to each symbol table entry. -The return value from the function -.Ar iterfn -controls progress of the iteration: -.Bl -tag -width indent -compact -offset indent -.It Dv ELFTC_ITERATE_ABORT -Terminates the iteration. -.It Dv ELFTC_ITERATE_CONTINUE -Iteration will continue on to the next element in the symbol table. -.El -Argument -.Ar cookie -will be passed to each invocation of -.Ar iterfn , -and may be used to track persistent state. -The ordering of symbol table entries presented to function -.Ar iterfn -is not defined. -The behavior of the iteration is undefined if -.Ar iterfn -adds or deletes symbol entries from a symbol table that currently -being iterated through. -.Pp -Function -.Fn elftc_symbol_table_lookup -returns the symbol entry corresponding to the name of the symbol -in argument -.Ar symbolname . -.Pp -Function -.Fn elftc_symbol_table_lookup_value -returns the symbol entry that has a -.Va sym_value -field that is closest to the value specified in argument -.Ar value . -The argument -.Ar table -should point to a symbol table, that has been sorted -by a prior call to -.Fn elftc_symbol_table_sort . -The argument -.Ar searchflags -can be a combination of the following flags: -.Bl -tag -width indent -compact -offset indent -.It Dv ELFTC_SEARCH_FORWARD -Find the symbol entry with the next higher value in its -.Va sym_value -field. -.It Dv ELFTC_SEARCH_BACKWARD -Find the symbol entry with next lower value in its -.Va sym_value -field. -.El -If both -.Dv ELFTC_SEARCH_FORWARD -and -.Dv ELFTC_SEARCH_BACKWARD -are specified, then this function will return the symbol that is -closest to the argument -.Ar value . -.Pp -Function -.Fn elftc_symbol_table_replace -moves the symbol table entry pointed to by argument -.Ar sym2 -into the traversal position for the entry pointed to by -.Ar sym1 , -and implicitly deletes the entry pointed to by argument -.Ar sym1 . -Argument -.Ar table -should point to a valid symbol table. -.Pp -Function -.Fn elftc_symbol_table_sort -is used to define an ordering of symbol entries in a symbol -table. -This ordering will be associated with the symbol table till the next -call to function -.Fn elftc_symbol_table_insert , -.Fn elftc_symbol_table_delete_name -or -.Fn elftc_symbol_table_delete_entry . -The argument -.Ar cmpfn -should point to a function that compares two symbol entries pointed -to by -.Ar s1 -and -.Ar s2 -and returns -1, 0, or 1, depending whether -.Ar s1 -is less, equal to, or greater than -.Ar s2 -respectively. -.Pp -Function -.Fn elftc_symbol_table_step -is used to step to the next symbol in a sorted symbol table. -Argument -.Ar table -should point to a symbol table. -The argument -.Ar cursym -specifies the current symbol. -The argument -.Ar direction -specifies the direction to step: -.Bl -tag -width indent -compact -offset ident -.It Dv ELFTC_STEP_NEXT -Return the symbol which follows the argument -.Ar cursym -in the current traversal order. -If argument -.Ar cursym -is NULL, return the first symbol in the current -traversal order. -.It Dv ELFTC_STEP_PREVIOUS -Return the symbol which precedes the argument -.Ar cursym -in the current traversal order. -If argument -.Ar cursym -is NULL, return the last symbol in the current -traversal order. -.El -.Ss Operations on ELF-centric symbol tables -ELF-centric symbol tables use symbols that are subtypes of -.Vt Elftc_Elf_Symbol , -as described in the section -.Sx "Structure of a Symbol Table Entry" -below. -.Pp -In addition to the operations on regular symbol tables listed above, -these symbol tables may be used with the following additional -functions. -.Pp -The function -.Fn elftc_elf_symbol_table_from_section -builds a symbol table from the contents of an ELF section. -The argument -.Ar symscn -should reference an ELF section of type -.Dv SHT_SYMTAB -or -.Dv SHT_DYNSYM . -The argument -.Ar strscn -should reference an ELF section of type -.Dv SHT_STRTAB -containing the string table associated wit section -.Ar symscn . -.Ss Structure of a Symbol Table Entry -The symbol tables managed by -.Lb libelftc -are collections of symbol table entries. -Each entry should be a subtype of one of the -.Vt Elftc_Symbol -or -.Vt Elftc_Elf_Symbol -types. -In other words, each entry should have an -.Vt Elftc_Symbol -or -.Vt Elftc_Elf_Symbol -structure as its first member, before any application specific -fields. -For example: -.Bd -literal -offset indent -struct _MySymbol { - Elftc_Symbol sym_base; - ... other application-specific fields ... -}; -.Ed -.Pp -The size of the combined entry is indicated to the library -at the time of creating a new symbol table. -Applications may then cast the returned pointers from these -routines to the appropriate type: -.Bd -literal -offset indent -struct _MySymbol *mysym; - -mysym = (struct _MySymbol *) elftc_symbol_table_lookup(table, - name); -.Ed -.Pp -The -.Vt Elftc_Symbol -type has two public fields: -.Bl -tag -width ".Va sym_value" -compact -offset indent -.It Va sym_name -Points to a NUL-terminated string containing the symbol's name. -The application should not change the value of this field. -.It Va sym_value -The value associated with this symbol. -This field is entirely under the application's control. -.El -.Pp -The -.Vt Elftc_Elf_Symbol -type has two public fields: -.Bl -tag -width ".Va sym_value" -compact -offset indent -.It Va sym_name -Points to a NUL-terminated string containing the symbol's name. -The application should not change the value of this field. -.It Va sym_elf -A structure of type -.Vt Gelf_Sym -containing ELF symbol information. -This field is entirely under the application's control. -.El -.Ss Symbol Search Rules -During lookups, symbols are looked up first in the symbol table passed in -to the -.Fn elftc_symbol_table_lookup -function. -If the specified symbol is not found, and if the symbol table has a -parent, then the search continues recursively up the chain of parent -symbol tables till either a matching symbol is found or till there are -no more parent symbol tables to search in. -.Pp -Insertions and deletion only work on the specified symbol table and -do not recurse into parent symbol tables. -.Ss Memory Management -The -.Lb libelftc -manages its memory allocations. -Applications should not free the pointers returned by the -API documented in this manual page. -.Sh RETURN VALUES -Function -.Fn elftc_symbol_table_count -returns a count of the number of symbol table entries as an unsigned -value. -.Pp -Functions -.Fn elftc_symbol_table_create , -.Fn elftc_symbol_table_create_nested -and -.Fn elftc_symbol_table_from_section -return a pointer to an opaque structure of type -.Vt Elftc_Symbol_Table -on success, or return NULL in case of an error. -.Pp -Functions -.Fn elftc_symbol_table_delete_name , -.Fn elftc_symbol_table_delete_name -.Fn elftc_symbol_table_destroy , -.Fn elftc_symbol_table_replace -and -.Fn elftc_symbol_table_sort -return a non-zero value on success, or return zero in case of an error. -.Pp -Functions -.Fn elftc_symbol_table_insert , -.Fn elftc_symbol_table_lookup -and -.Fn elftc_symbol_table_lookup_value -return a pointer to a structure that is a subtype of -.Vt Elftc_Symbol -on success, or return NULL in case of an error. -.Pp -The function -.Fn elftc_symbol_table_step -return a pointer to a structure that is a subtype of -.Vt Elftc_Symbol -on success. -The function returns NULL if there are no more elements in the -specified traversal direction. -.Pp -The function -.Fn elftc_symbol_table_iterate -returns -.Dv ELFTC_ITERATE_SUCCESS -if the symbol table was successfully traversed, or -.Dv ELFTC_ITERATE_ABORT -in case the iteration function aborted the traversal. -.Sh SEE ALSO -.Xr dwarf 3 , -.Xr elf 3 , -.Xr elftc 3 diff --git a/libelftc/libelftc.h b/libelftc/libelftc.h index 062db318c4d2..e3adaf23c696 100644 --- a/libelftc/libelftc.h +++ b/libelftc/libelftc.h @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $ - * $Id: libelftc.h 3174 2015-03-27 17:13:41Z emaste $ + * $Id: libelftc.h 3309 2016-01-10 09:10:51Z kaiwang27 $ */ #ifndef _LIBELFTC_H_ @@ -46,7 +46,9 @@ typedef enum { ETF_ELF, ETF_BINARY, ETF_SREC, - ETF_IHEX + ETF_IHEX, + ETF_PE, + ETF_EFI, } Elftc_Bfd_Target_Flavor; /* diff --git a/libelftc/libelftc_bfdtarget.c b/libelftc/libelftc_bfdtarget.c index 00ba2254fc16..88f3220df0b0 100644 --- a/libelftc/libelftc_bfdtarget.c +++ b/libelftc/libelftc_bfdtarget.c @@ -30,7 +30,7 @@ #include "_libelftc.h" -ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3309 2016-01-10 09:10:51Z kaiwang27 $"); struct _Elftc_Bfd_Target _libelftc_targets[] = { @@ -374,6 +374,30 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = { .bt_type = ETF_SREC, }, + { + .bt_name = "efi-app-ia32", + .bt_type = ETF_EFI, + .bt_machine = EM_386, + }, + + { + .bt_name = "efi-app-x86_64", + .bt_type = ETF_EFI, + .bt_machine = EM_X86_64, + }, + + { + .bt_name = "pei-i386", + .bt_type = ETF_PE, + .bt_machine = EM_386, + }, + + { + .bt_name = "pei-x86-64", + .bt_type = ETF_PE, + .bt_machine = EM_X86_64, + }, + { .bt_name = NULL, .bt_type = ETF_NONE, diff --git a/libelftc/libelftc_dem_gnu3.c b/libelftc/libelftc_dem_gnu3.c index e8fd78fe0ded..f5ca7b312683 100644 --- a/libelftc/libelftc_dem_gnu3.c +++ b/libelftc/libelftc_dem_gnu3.c @@ -36,7 +36,7 @@ #include "_libelftc.h" -ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3212 2015-05-17 13:40:55Z kaiwang27 $"); +ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3291 2016-01-04 02:36:38Z emaste $"); /** * @file cpp_demangle.c @@ -1262,11 +1262,13 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) if (!cpp_demangle_push_str(ddata, "non-transaction clone for ", 26)) return (0); + break; case 't': default: if (!cpp_demangle_push_str(ddata, "transaction clone for ", 22)) return (0); + break; } ++ddata->cur; return (cpp_demangle_read_encoding(ddata)); @@ -1895,35 +1897,35 @@ cpp_demangle_read_subst(struct cpp_demangle_data *ddata) case SIMPLE_HASH('S', 'd'): /* std::basic_iostream > */ - if (!cpp_demangle_push_str(ddata, "std::iostream", 19)) + if (!cpp_demangle_push_str(ddata, "std::basic_iostream", 19)) return (0); - ddata->last_sname = "iostream"; + ddata->last_sname = "basic_iostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, - "std::iostream", 19)); + "std::basic_iostream", 19)); return (1); case SIMPLE_HASH('S', 'i'): /* std::basic_istream > */ - if (!cpp_demangle_push_str(ddata, "std::istream", 18)) + if (!cpp_demangle_push_str(ddata, "std::basic_istream", 18)) return (0); - ddata->last_sname = "istream"; + ddata->last_sname = "basic_istream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, - "std::istream", 18)); + "std::basic_istream", 18)); return (1); case SIMPLE_HASH('S', 'o'): /* std::basic_ostream > */ - if (!cpp_demangle_push_str(ddata, "std::ostream", 18)) + if (!cpp_demangle_push_str(ddata, "std::basic_ostream", 18)) return (0); - ddata->last_sname = "istream"; + ddata->last_sname = "basic_ostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, - "std::ostream", 18)); + "std::basic_ostream", 18)); return (1); case SIMPLE_HASH('S', 's'): diff --git a/libelftc/make-toolchain-version b/libelftc/make-toolchain-version index ac6155a49a00..8891258eeaf9 100755 --- a/libelftc/make-toolchain-version +++ b/libelftc/make-toolchain-version @@ -3,7 +3,7 @@ # This script generates a project-wide version identifier for use by # the `elftc_version()' API. # -# $Id: make-toolchain-version 2583 2012-09-14 09:49:25Z jkoshy $ +# $Id: make-toolchain-version 3299 2016-01-09 19:58:46Z jkoshy $ # # Defaults. @@ -64,7 +64,7 @@ done curdir=`pwd` cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"." -if [ -d .svn ]; then # FreeBSD and SF.Net sources. +if [ -d .svn -o -d ../.svn ]; then # FreeBSD and SF.Net sources. versionstring=" svn:"$(svnversion) elif [ -d CVS ]; then # NetBSD. versionstring=" cvs:unknown" diff --git a/libelftc/os.NetBSD.mk b/libelftc/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/libelftc/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/libpe/Makefile b/libpe/Makefile new file mode 100644 index 000000000000..d02fb5080ef6 --- /dev/null +++ b/libpe/Makefile @@ -0,0 +1,32 @@ +# $Id: Makefile 3349 2016-01-18 21:09:16Z jkoshy $ + +TOP= ${.CURDIR}/.. + +LIB= pe + +SRCS= libpe_buffer.c \ + libpe_coff.c \ + libpe_dos.c \ + libpe_init.c \ + libpe_rich.c \ + libpe_section.c \ + libpe_utils.c \ + pe_buffer.c \ + pe_cntl.c \ + pe_coff.c \ + pe_dos.c \ + pe_flag.c \ + pe_init.c \ + pe_rich.c \ + pe_section.c \ + pe_symtab.c \ + pe_update.c + +INCS= libpe.h pe.h +INCSDIR= /usr/include + +SHLIB_MAJOR= 1 + +WARNS?= 6 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/libpe/_libpe.h b/libpe/_libpe.h new file mode 100644 index 000000000000..1a83a674194a --- /dev/null +++ b/libpe/_libpe.h @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: _libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $ + */ + +#ifndef __LIBPE_H_ +#define __LIBPE_H_ + +#include +#include + +#include "libpe.h" + +#include "_elftc.h" + +typedef struct _PE_SecBuf { + PE_Buffer sb_pb; /* application buffer */ + PE_Scn *sb_ps; /* PE_Scn pointer */ + unsigned int sb_flags; /* buffer flags */ + STAILQ_ENTRY(_PE_SecBuf) sb_next; +} PE_SecBuf; + +struct _PE_Scn { + PE *ps_pe; /* PE descriptor */ + PE_SecHdr ps_sh; /* section header */ + unsigned int ps_ndx; /* 1-based section index */ + unsigned int ps_flags; /* section flags */ + unsigned int ps_falign; /* section file alignment */ + STAILQ_HEAD(, _PE_SecBuf) ps_b; /* buffer list */ + STAILQ_ENTRY(_PE_Scn) ps_next; +}; + +struct _PE { + int pe_fd; /* file descriptor */ + PE_Cmd pe_cmd; /* open mode */ + PE_Object pe_obj; /* PE32/PE32+/COFF */ + size_t pe_fsize; /* file size */ + unsigned int pe_flags; /* library flags */ + PE_DosHdr *pe_dh; /* MS-DOS header */ + char *pe_stub; /* MS-DOS stub */ + size_t pe_stub_ex; /* MS-DOS stub len (exclude hdr) */ + char *pe_stub_app; /* MS-DOS stub (app supplied) */ + size_t pe_stub_app_sz; /* MS-DOS stub len (app supplied) */ + PE_RichHdr *pe_rh; /* rich header */ + char *pe_rh_start; /* pointer to rich header */ + PE_CoffHdr *pe_ch; /* COFF header */ + PE_OptHdr *pe_oh; /* optional header */ + PE_DataDir *pe_dd; /* data directories */ + unsigned int pe_nscn; /* num. of sections */ + char *pe_symtab; /* COFF symbol table */ + size_t pe_symbtab_sz; /* size of symbol table */ + unsigned int pe_nsym; /* num. of symbols */ + unsigned int pe_rvamax; /* maximum RVA */ + STAILQ_HEAD(, _PE_Scn) pe_scn; /* section list */ +}; + +/* Library internal flags */ +#define LIBPE_F_API_MASK 0x000FFFU +#define LIBPE_F_SPECIAL_FILE 0x001000U +#define LIBPE_F_BAD_DOS_HEADER 0x002000U +#define LIBPE_F_BAD_PE_HEADER 0x004000U +#define LIBPE_F_BAD_COFF_HEADER 0x008000U +#define LIBPE_F_BAD_OPT_HEADER 0x010000U +#define LIBPE_F_BAD_SEC_HEADER 0x020000U +#define LIBPE_F_LOAD_DOS_STUB 0x040000U +#define LIBPE_F_FD_DONE 0x080000U +#define LIBPE_F_DIRTY_DOS_HEADER 0x100000U +#define LIBPE_F_DIRTY_COFF_HEADER 0x200000U +#define LIBPE_F_DIRTY_OPT_HEADER 0x400000U +#define LIBPE_F_DIRTY_SEC_HEADER 0x800000U + +/* Internal section flags */ +#define LIBPE_F_LOAD_SECTION 0x1000U +#define LIBPE_F_STRIP_SECTION 0x2000U + +/* Internal buffer flags */ +#define LIBPE_F_BUFFER_MALLOCED 0x1000U + +/* Library internal defines */ +#define PE_DOS_MAGIC 0x5a4dU +#define PE_RICH_TEXT "Rich" +#define PE_RICH_HIDDEN 0x536e6144U /* DanS */ +#define PE_SIGNATURE 0x4550U /* PE\0\0 */ +#define PE_COFF_OPT_SIZE_32 224 +#define PE_COFF_OPT_SIZE_32P 240 +#define PE_SYM_ENTRY_SIZE 18 + +/* Encode/Decode macros */ +#if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) +static __inline uint16_t +le16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[1] << 8) | p[0]); +} + +static __inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static __inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +static __inline void +le16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; +} + +static __inline void +le32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; +} + +static __inline void +le64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + le32enc(p, (uint32_t)(u & 0xffffffffU)); + le32enc(p + 4, (uint32_t)(u >> 32)); +} +#endif /* ELFTC_NEED_BYTEORDER_EXTENSIONS */ + +#define PE_READ16(p,v) do { \ + (v) = le16dec((p)); \ + (p) += 2; \ +} while(0) + +#define PE_READ32(p,v) do { \ + (v) = le32dec((p)); \ + (p) += 4; \ +} while(0) + +#define PE_WRITE16(p,v) do { \ + le16enc((p), (v)); \ + (p) += 2; \ +} while(0) + +#define PE_WRITE32(p,v) do { \ + le32enc((p), (v)); \ + (p) += 4; \ +} while(0) + + +/* Internal function declarations */ +off_t libpe_align(PE *, off_t, size_t); +PE_SecBuf *libpe_alloc_buffer(PE_Scn *, size_t); +PE_Scn *libpe_alloc_scn(PE *); +int libpe_load_all_sections(PE *); +int libpe_load_section(PE *, PE_Scn *); +int libpe_open_object(PE *); +int libpe_pad(PE *, size_t); +int libpe_parse_msdos_header(PE *, char *); +int libpe_parse_coff_header(PE *, char *); +int libpe_parse_rich_header(PE *); +int libpe_parse_section_headers(PE *); +int libpe_read_msdos_stub(PE *); +void libpe_release_buffer(PE_SecBuf *); +void libpe_release_object(PE *); +void libpe_release_scn(PE_Scn *); +size_t libpe_resync_buffers(PE_Scn *); +int libpe_resync_sections(PE *, off_t); +int libpe_write_buffers(PE_Scn *); +off_t libpe_write_coff_header(PE *, off_t); +off_t libpe_write_msdos_stub(PE *, off_t); +off_t libpe_write_pe_header(PE *, off_t); +off_t libpe_write_sections(PE *, off_t); +off_t libpe_write_section_headers(PE *, off_t); + +#endif /* !__LIBPE_H_ */ diff --git a/libpe/libpe.h b/libpe/libpe.h new file mode 100644 index 000000000000..3cec39a8f522 --- /dev/null +++ b/libpe/libpe.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: libpe.h 3312 2016-01-10 09:23:51Z kaiwang27 $ + */ + +#ifndef _LIBPE_H_ +#define _LIBPE_H_ + +#include + +#include "pe.h" + +/* Library private data structures */ +typedef struct _PE PE; +typedef struct _PE_Scn PE_Scn; + +/* Section buffers */ +typedef struct PE_Buffer { + unsigned int pb_align; + off_t pb_off; + size_t pb_size; + void *pb_buf; +} PE_Buffer; + +/* Object types */ +typedef enum { + PE_O_UNKNOWN = 0, + PE_O_PE32, + PE_O_PE32P, + PE_O_COFF, +} PE_Object; + +/* Commands */ +typedef enum { + PE_C_NULL = 0, + PE_C_CLR, + PE_C_FDDONE, + PE_C_FDREAD, + PE_C_RDWR, + PE_C_READ, + PE_C_SET, + PE_C_WRITE, + PE_C_NUM +} PE_Cmd; + +/* Flags defined by the API. */ +#define PE_F_DIRTY 0x001U +#define PE_F_STRIP_DOS_STUB 0x002U +#define PE_F_STRIP_RICH_HEADER 0x004U +#define PE_F_STRIP_SYMTAB 0x008U +#define PE_F_STRIP_DEBUG 0x010U +#define PE_F_STRIP_SECTION 0x020U + +#ifdef __cplusplus +extern "C" { +#endif + +PE_CoffHdr *pe_coff_header(PE *); +int pe_cntl(PE *, PE_Cmd); +PE_DataDir *pe_data_dir(PE *); +void pe_finish(PE *); +int pe_flag(PE *, PE_Cmd, unsigned int); +int pe_flag_buffer(PE_Buffer *, PE_Cmd, unsigned int); +int pe_flag_coff_header(PE *, PE_Cmd, unsigned int); +int pe_flag_data_dir(PE *, PE_Cmd, unsigned int); +int pe_flag_dos_header(PE *, PE_Cmd, unsigned int); +int pe_flag_opt_header(PE *, PE_Cmd, unsigned int); +int pe_flag_section_header(PE_Scn *, PE_Cmd, unsigned int); +int pe_flag_scn(PE_Scn *, PE_Cmd, unsigned int); +PE_Buffer *pe_getbuffer(PE_Scn *, PE_Buffer *); +PE_Scn *pe_getscn(PE *, size_t); +PE *pe_init(int, PE_Cmd, PE_Object); +PE_Scn *pe_insertscn(PE *, size_t); +PE_DosHdr *pe_msdos_header(PE *); +char *pe_msdos_stub(PE *, size_t *); +size_t pe_ndxscn(PE_Scn *); +PE_Buffer *pe_newbuffer(PE_Scn *); +PE_Scn *pe_newscn(PE *); +PE_Scn *pe_nextscn(PE *, PE_Scn *); +PE_Object pe_object(PE *); +PE_OptHdr *pe_opt_header(PE *); +PE_RichHdr *pe_rich_header(PE *); +int pe_rich_header_validate(PE *); +PE_SecHdr *pe_section_header(PE_Scn *); +off_t pe_update(PE *); +int pe_update_coff_header(PE *, PE_CoffHdr *); +int pe_update_opt_header(PE *, PE_OptHdr *); +int pe_update_data_dir(PE *, PE_DataDir *); +int ps_update_msdos_header(PE *, PE_DosHdr *); +int ps_update_msdos_stub(PE *, char *, size_t); +int pe_update_section_header(PE_Scn *, PE_SecHdr *); +int pe_update_symtab(PE *, char *, size_t, unsigned int); + +#ifdef __cplusplus +} +#endif + +#endif /* !_LIBPE_H_ */ diff --git a/libpe/libpe_buffer.c b/libpe/libpe_buffer.c new file mode 100644 index 000000000000..cc633dd04ee9 --- /dev/null +++ b/libpe/libpe_buffer.c @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_SecBuf * +libpe_alloc_buffer(PE_Scn *ps, size_t sz) +{ + PE_SecBuf *sb; + + if ((sb = malloc(sizeof(PE_SecBuf))) == NULL) { + errno = ENOMEM; + return (NULL); + } + + sb->sb_ps = ps; + sb->sb_flags = 0; + sb->sb_pb.pb_align = 1; + sb->sb_pb.pb_off = 0; + sb->sb_pb.pb_size = sz; + if (sz > 0) { + if ((sb->sb_pb.pb_buf = malloc(sz)) == NULL) { + free(sb); + errno = ENOMEM; + return (NULL); + } + sb->sb_flags |= LIBPE_F_BUFFER_MALLOCED; + } else + sb->sb_pb.pb_buf = NULL; + + STAILQ_INSERT_TAIL(&ps->ps_b, sb, sb_next); + + return (sb); +} + +void +libpe_release_buffer(PE_SecBuf *sb) +{ + PE_Scn *ps; + + assert(sb != NULL); + + ps = sb->sb_ps; + + STAILQ_REMOVE(&ps->ps_b, sb, _PE_SecBuf, sb_next); + + if (sb->sb_flags & LIBPE_F_BUFFER_MALLOCED) + free(sb->sb_pb.pb_buf); + + free(sb); +} + +static int +cmp_sb(PE_SecBuf *a, PE_SecBuf *b) +{ + + if (a->sb_pb.pb_off < b->sb_pb.pb_off) + return (-1); + else if (a->sb_pb.pb_off == b->sb_pb.pb_off) + return (0); + else + return (1); +} + +static void +sort_buffers(PE_Scn *ps) +{ + + if (STAILQ_EMPTY(&ps->ps_b)) + return; + + STAILQ_SORT(&ps->ps_b, _PE_SecBuf, sb_next, cmp_sb); +} + +size_t +libpe_resync_buffers(PE_Scn *ps) +{ + PE_SecBuf *sb; + PE_Buffer *pb; + size_t sz; + + assert(ps->ps_flags & LIBPE_F_LOAD_SECTION); + + sort_buffers(ps); + + sz = 0; + STAILQ_FOREACH(sb, &ps->ps_b, sb_next) { + if (ps->ps_flags & PE_F_DIRTY) + sb->sb_flags |= PE_F_DIRTY; + + pb = (PE_Buffer *) sb; + if (pb->pb_align > ps->ps_falign) + pb->pb_align = ps->ps_falign; + if (pb->pb_buf == NULL || pb->pb_size == 0) + continue; + + sz = roundup(sz, pb->pb_align); + + if (pb->pb_off != (off_t) sz) { + pb->pb_off = sz; + sb->sb_flags |= PE_F_DIRTY; + } + sz += pb->pb_size; + } + + return (sz); +} + +int +libpe_write_buffers(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb; + PE_Buffer *pb; + off_t off; + + assert(ps->ps_flags & LIBPE_F_LOAD_SECTION); + + pe = ps->ps_pe; + + off = 0; + STAILQ_FOREACH(sb, &ps->ps_b, sb_next) { + pb = &sb->sb_pb; + if (pb->pb_buf == NULL || pb->pb_size == 0) + continue; + + if ((sb->sb_flags & PE_F_DIRTY) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, (off_t) pb->pb_size, SEEK_CUR) < + 0) { + errno = EIO; + return (-1); + } + goto next_buf; + } + + if (pb->pb_off > off) { + if (libpe_pad(pe, pb->pb_off - off) < 0) + return (-1); + off = pb->pb_off; + } + + if (write(pe->pe_fd, pb->pb_buf, pb->pb_size) != + (ssize_t) pb->pb_size) { + errno = EIO; + return (-1); + } + + next_buf: + off += pb->pb_size; + } + + return (0); +} diff --git a/libpe/libpe_coff.c b/libpe/libpe_coff.c new file mode 100644 index 000000000000..e161f7c71864 --- /dev/null +++ b/libpe/libpe_coff.c @@ -0,0 +1,535 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_coff.c 3326 2016-01-16 17:46:17Z kaiwang27 $"); + +int +libpe_parse_coff_header(PE *pe, char *hdr) +{ + char tmp[128]; + PE_CoffHdr *ch; + PE_OptHdr *oh; + PE_DataDir *dd; + unsigned p, r, s; + int i; + + if ((ch = malloc(sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + + PE_READ16(hdr, ch->ch_machine); + PE_READ16(hdr, ch->ch_nsec); + PE_READ32(hdr, ch->ch_timestamp); + PE_READ32(hdr, ch->ch_symptr); + PE_READ32(hdr, ch->ch_nsym); + PE_READ16(hdr, ch->ch_optsize); + PE_READ16(hdr, ch->ch_char); + + pe->pe_ch = ch; + + /* + * The Optional header is omitted for object files. + */ + if (ch->ch_optsize == 0) + return (libpe_parse_section_headers(pe)); + + if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_oh = oh; + +#define READ_OPT(n) \ + do { \ + /* \ + * Since the Optional Header size is variable, we must \ + * check if the requested read size will overrun the \ + * remaining header bytes. \ + */ \ + if (p + (n) > ch->ch_optsize) { \ + /* Consume the "extra" bytes */ \ + r = ch->ch_optsize - p; \ + if (read(pe->pe_fd, tmp, r) != (ssize_t) r) { \ + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER;\ + return (0); \ + } \ + return (libpe_parse_section_headers(pe)); \ + } \ + if (read(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \ + pe->pe_flags |= LIBPE_F_BAD_OPT_HEADER; \ + return (0); \ + } \ + p += (n); \ + } while (0) +#define READ_OPT8(v) do { READ_OPT(1); (v) = *tmp; } while(0) +#define READ_OPT16(v) do { READ_OPT(2); (v) = le16dec(tmp); } while(0) +#define READ_OPT32(v) do { READ_OPT(4); (v) = le32dec(tmp); } while(0) +#define READ_OPT64(v) do { READ_OPT(8); (v) = le64dec(tmp); } while(0) + + /* + * Read in the Optional header. Size of some fields are depending + * on the PE format specified by the oh_magic field. (PE32 or PE32+) + */ + + p = 0; + READ_OPT16(oh->oh_magic); + if (oh->oh_magic == PE_FORMAT_32P) + pe->pe_obj = PE_O_PE32P; + READ_OPT8(oh->oh_ldvermajor); + READ_OPT8(oh->oh_ldverminor); + READ_OPT32(oh->oh_textsize); + READ_OPT32(oh->oh_datasize); + READ_OPT32(oh->oh_bsssize); + READ_OPT32(oh->oh_entry); + READ_OPT32(oh->oh_textbase); + if (oh->oh_magic != PE_FORMAT_32P) { + READ_OPT32(oh->oh_database); + READ_OPT32(oh->oh_imgbase); + } else + READ_OPT64(oh->oh_imgbase); + READ_OPT32(oh->oh_secalign); + READ_OPT32(oh->oh_filealign); + READ_OPT16(oh->oh_osvermajor); + READ_OPT16(oh->oh_osverminor); + READ_OPT16(oh->oh_imgvermajor); + READ_OPT16(oh->oh_imgverminor); + READ_OPT16(oh->oh_subvermajor); + READ_OPT16(oh->oh_subverminor); + READ_OPT32(oh->oh_win32ver); + READ_OPT32(oh->oh_imgsize); + READ_OPT32(oh->oh_hdrsize); + READ_OPT32(oh->oh_checksum); + READ_OPT16(oh->oh_subsystem); + READ_OPT16(oh->oh_dllchar); + if (oh->oh_magic != PE_FORMAT_32P) { + READ_OPT32(oh->oh_stacksizer); + READ_OPT32(oh->oh_stacksizec); + READ_OPT32(oh->oh_heapsizer); + READ_OPT32(oh->oh_heapsizec); + } else { + READ_OPT64(oh->oh_stacksizer); + READ_OPT64(oh->oh_stacksizec); + READ_OPT64(oh->oh_heapsizer); + READ_OPT64(oh->oh_heapsizec); + } + READ_OPT32(oh->oh_ldrflags); + READ_OPT32(oh->oh_ndatadir); + + /* + * Read in the Data Directories. + */ + + if (oh->oh_ndatadir > 0) { + if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dd = dd; + + dd->dd_total = oh->oh_ndatadir < PE_DD_MAX ? oh->oh_ndatadir : + PE_DD_MAX; + + for (i = 0; (uint32_t) i < dd->dd_total; i++) { + READ_OPT32(dd->dd_e[i].de_addr); + READ_OPT32(dd->dd_e[i].de_size); + } + } + + /* Consume the remaining bytes in the Optional header, if any. */ + if (ch->ch_optsize > p) { + r = ch->ch_optsize - p; + for (; r > 0; r -= s) { + s = r > sizeof(tmp) ? sizeof(tmp) : r; + if (read(pe->pe_fd, tmp, s) != (ssize_t) s) { + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER; + return (0); + } + } + } + + return (libpe_parse_section_headers(pe)); +} + +off_t +libpe_write_pe_header(PE *pe, off_t off) +{ + char tmp[4]; + + if (pe->pe_cmd == PE_C_RDWR && + (pe->pe_flags & LIBPE_F_BAD_PE_HEADER) == 0) { + assert(pe->pe_dh != NULL); + off = lseek(pe->pe_fd, (off_t) pe->pe_dh->dh_lfanew + 4, + SEEK_SET); + return (off); + } + + /* + * PE Header should to be aligned on 8-byte boundary according to + * the PE/COFF specification. + */ + if ((off = libpe_align(pe, off, 8)) < 0) + return (-1); + + le32enc(tmp, PE_SIGNATURE); + if (write(pe->pe_fd, tmp, sizeof(tmp)) != (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + + off += 4; + + pe->pe_flags &= ~LIBPE_F_BAD_PE_HEADER; + + /* Trigger rewrite for the following headers. */ + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (off); +} + +off_t +libpe_write_coff_header(PE *pe, off_t off) +{ + char tmp[128], *hdr; + PE_CoffHdr *ch; + PE_DataDir *dd; + PE_OptHdr *oh; + PE_Scn *ps; + PE_SecHdr *sh; + unsigned p; + uint32_t reloc_rva, reloc_sz; + int i, reloc; + + reloc = 0; + reloc_rva = reloc_sz = 0; + + if (pe->pe_cmd == PE_C_RDWR) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + + if ((pe->pe_flags & LIBPE_F_DIRTY_COFF_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_COFF_HEADER) == 0) { + if (lseek(pe->pe_fd, (off_t) sizeof(PE_CoffHdr), + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += sizeof(PE_CoffHdr); + assert(pe->pe_ch != NULL); + ch = pe->pe_ch; + goto coff_done; + } + + /* lseek(2) to the offset of the COFF header. */ + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + if (pe->pe_ch == NULL) { + if ((ch = calloc(1, sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_ch = ch; + + /* + * Default value for ch_machine if not provided by the + * application. + */ + if (pe->pe_obj == PE_O_PE32P) + ch->ch_machine = IMAGE_FILE_MACHINE_AMD64; + else + ch->ch_machine = IMAGE_FILE_MACHINE_I386; + + } else + ch = pe->pe_ch; + + if (!ch->ch_timestamp) + ch->ch_timestamp = time(NULL); + + if (pe->pe_obj == PE_O_PE32) { + if (!ch->ch_optsize) + ch->ch_optsize = PE_COFF_OPT_SIZE_32; + ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE | + IMAGE_FILE_32BIT_MACHINE; + } else if (pe->pe_obj == PE_O_PE32P) { + if (!ch->ch_optsize) + ch->ch_optsize = PE_COFF_OPT_SIZE_32P; + ch->ch_char |= IMAGE_FILE_EXECUTABLE_IMAGE | + IMAGE_FILE_LARGE_ADDRESS_AWARE; + } else + ch->ch_optsize = 0; + + /* + * COFF line number is deprecated by the PE/COFF + * specification. COFF symbol table is deprecated + * for executables. + */ + ch->ch_char |= IMAGE_FILE_LINE_NUMS_STRIPPED; + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) + ch->ch_char |= IMAGE_FILE_LOCAL_SYMS_STRIPPED; + + ch->ch_nsec = pe->pe_nscn; + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + + if (ps->ps_ndx == 0xFFFFFFFFU) { + ch->ch_symptr = sh->sh_rawptr; + ch->ch_nsym = pe->pe_nsym; + } + + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) { + if (ps->ps_ndx == (0xFFFF0000 | PE_DD_BASERELOC) || + strncmp(sh->sh_name, ".reloc", strlen(".reloc")) == + 0) { + reloc = 1; + reloc_rva = sh->sh_addr; + reloc_sz = sh->sh_virtsize; + } + } + } + + if (!reloc) + ch->ch_char |= IMAGE_FILE_RELOCS_STRIPPED; + + if (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) { + if (pe->pe_obj == PE_O_PE32) + ch->ch_optsize = PE_COFF_OPT_SIZE_32; + else if (pe->pe_obj == PE_O_PE32P) + ch->ch_optsize = PE_COFF_OPT_SIZE_32P; + else + ch->ch_optsize = 0; + } + + /* + * Write the COFF header. + */ + hdr = tmp; + PE_WRITE16(hdr, ch->ch_machine); + PE_WRITE16(hdr, ch->ch_nsec); + PE_WRITE32(hdr, ch->ch_timestamp); + PE_WRITE32(hdr, ch->ch_symptr); + PE_WRITE32(hdr, ch->ch_nsym); + PE_WRITE16(hdr, ch->ch_optsize); + PE_WRITE16(hdr, ch->ch_char); + if (write(pe->pe_fd, tmp, sizeof(PE_CoffHdr)) != + (ssize_t) sizeof(PE_CoffHdr)) { + errno = EIO; + return (-1); + } + +coff_done: + off += sizeof(PE_CoffHdr); + pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_COFF_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + if (ch->ch_optsize == 0) + return (off); + + /* + * Write the Optional header. + */ + + if (pe->pe_cmd == PE_C_RDWR) { + if ((pe->pe_flags & LIBPE_F_DIRTY_OPT_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_OPT_HEADER) == 0) { + if (lseek(pe->pe_fd, (off_t) ch->ch_optsize, + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += ch->ch_optsize; + return (off); + } + + } + + if (pe->pe_oh == NULL) { + if ((oh = calloc(1, sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_oh = oh; + } else + oh = pe->pe_oh; + + if (pe->pe_obj == PE_O_PE32) + oh->oh_magic = PE_FORMAT_32; + else + oh->oh_magic = PE_FORMAT_32P; + + /* + * LinkerVersion should not be less than 2.5, which will cause + * Windows to complain the executable is invalid in some case. + * By default we set LinkerVersion to 2.22 (binutils 2.22) + */ + if (!oh->oh_ldvermajor && !oh->oh_ldverminor) { + oh->oh_ldvermajor = 2; + oh->oh_ldverminor = 22; + } + + /* + * The library always tries to write out all 16 data directories + * but the actual data dir written will depend on ch_optsize. + */ + oh->oh_ndatadir = PE_DD_MAX; + + if (!oh->oh_filealign) + oh->oh_filealign = 0x200; + if (!oh->oh_secalign) + oh->oh_secalign = 0x1000; + oh->oh_hdrsize = roundup(off + ch->ch_optsize + pe->pe_nscn * + sizeof(PE_SecHdr), oh->oh_filealign); + oh->oh_imgsize = roundup(pe->pe_rvamax, oh->oh_secalign); + +#define WRITE_OPT(n) \ + do { \ + /* \ + * Since the Optional Header size is variable, we must \ + * check if the requested write size will overrun the \ + * remaining header bytes. \ + */ \ + if (p + (n) > ch->ch_optsize) { \ + /* Pad the "extra" bytes */ \ + if (libpe_pad(pe, ch->ch_optsize - p) < 0) { \ + errno = EIO; \ + return (-1); \ + } \ + goto opt_done; \ + } \ + if (write(pe->pe_fd, tmp, (n)) != (ssize_t) (n)) { \ + errno = EIO; \ + return (-1); \ + } \ + p += (n); \ + } while (0) +#define WRITE_OPT8(v) do { *tmp = (v); WRITE_OPT(1); } while(0) +#define WRITE_OPT16(v) do { le16enc(tmp, (v)); WRITE_OPT(2); } while(0) +#define WRITE_OPT32(v) do { le32enc(tmp, (v)); WRITE_OPT(4); } while(0) +#define WRITE_OPT64(v) do { le64enc(tmp, (v)); WRITE_OPT(8); } while(0) + + p = 0; + WRITE_OPT16(oh->oh_magic); + if (oh->oh_magic == PE_FORMAT_32P) + pe->pe_obj = PE_O_PE32P; + WRITE_OPT8(oh->oh_ldvermajor); + WRITE_OPT8(oh->oh_ldverminor); + WRITE_OPT32(oh->oh_textsize); + WRITE_OPT32(oh->oh_datasize); + WRITE_OPT32(oh->oh_bsssize); + WRITE_OPT32(oh->oh_entry); + WRITE_OPT32(oh->oh_textbase); + if (oh->oh_magic != PE_FORMAT_32P) { + WRITE_OPT32(oh->oh_database); + WRITE_OPT32(oh->oh_imgbase); + } else + WRITE_OPT64(oh->oh_imgbase); + WRITE_OPT32(oh->oh_secalign); + WRITE_OPT32(oh->oh_filealign); + WRITE_OPT16(oh->oh_osvermajor); + WRITE_OPT16(oh->oh_osverminor); + WRITE_OPT16(oh->oh_imgvermajor); + WRITE_OPT16(oh->oh_imgverminor); + WRITE_OPT16(oh->oh_subvermajor); + WRITE_OPT16(oh->oh_subverminor); + WRITE_OPT32(oh->oh_win32ver); + WRITE_OPT32(oh->oh_imgsize); + WRITE_OPT32(oh->oh_hdrsize); + WRITE_OPT32(oh->oh_checksum); + WRITE_OPT16(oh->oh_subsystem); + WRITE_OPT16(oh->oh_dllchar); + if (oh->oh_magic != PE_FORMAT_32P) { + WRITE_OPT32(oh->oh_stacksizer); + WRITE_OPT32(oh->oh_stacksizec); + WRITE_OPT32(oh->oh_heapsizer); + WRITE_OPT32(oh->oh_heapsizec); + } else { + WRITE_OPT64(oh->oh_stacksizer); + WRITE_OPT64(oh->oh_stacksizec); + WRITE_OPT64(oh->oh_heapsizer); + WRITE_OPT64(oh->oh_heapsizec); + } + WRITE_OPT32(oh->oh_ldrflags); + WRITE_OPT32(oh->oh_ndatadir); + + /* + * Write the Data Directories. + */ + + if (oh->oh_ndatadir > 0) { + if (pe->pe_dd == NULL) { + if ((dd = calloc(1, sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dd = dd; + dd->dd_total = PE_DD_MAX; + } else + dd = pe->pe_dd; + + assert(oh->oh_ndatadir <= PE_DD_MAX); + + if (reloc) { + dd->dd_e[PE_DD_BASERELOC].de_addr = reloc_rva; + dd->dd_e[PE_DD_BASERELOC].de_size = reloc_sz; + } + + for (i = 0; (uint32_t) i < dd->dd_total; i++) { + WRITE_OPT32(dd->dd_e[i].de_addr); + WRITE_OPT32(dd->dd_e[i].de_size); + } + } + + /* Pad the remaining bytes in the Optional header, if any. */ + if (ch->ch_optsize > p) { + if (libpe_pad(pe, ch->ch_optsize - p) < 0) { + errno = EIO; + return (-1); + } + } + +opt_done: + off += ch->ch_optsize; + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_OPT_HEADER; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (off); +} diff --git a/libpe/libpe_dos.c b/libpe/libpe_dos.c new file mode 100644 index 000000000000..a48ad1241597 --- /dev/null +++ b/libpe/libpe_dos.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +libpe_parse_msdos_header(PE *pe, char *hdr) +{ + PE_DosHdr *dh; + char coff[sizeof(PE_CoffHdr)]; + uint32_t pe_magic; + int i; + + if ((pe->pe_stub = malloc(sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + memcpy(pe->pe_stub, hdr, sizeof(PE_DosHdr)); + + if ((dh = malloc(sizeof(*dh))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dh = dh; + + /* Read the conventional MS-DOS EXE header. */ + memcpy(dh->dh_magic, hdr, 2); + hdr += 2; + PE_READ16(hdr, dh->dh_lastsize); + PE_READ16(hdr, dh->dh_nblock); + PE_READ16(hdr, dh->dh_nreloc); + PE_READ16(hdr, dh->dh_hdrsize); + PE_READ16(hdr, dh->dh_minalloc); + PE_READ16(hdr, dh->dh_maxalloc); + PE_READ16(hdr, dh->dh_ss); + PE_READ16(hdr, dh->dh_sp); + PE_READ16(hdr, dh->dh_checksum); + PE_READ16(hdr, dh->dh_ip); + PE_READ16(hdr, dh->dh_cs); + PE_READ16(hdr, dh->dh_relocpos); + PE_READ16(hdr, dh->dh_noverlay); + + /* Do not continue if the EXE is not a PE/NE/... (new executable) */ + if (dh->dh_relocpos != 0x40) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + for (i = 0; i < 4; i++) + PE_READ16(hdr, dh->dh_reserved1[i]); + PE_READ16(hdr, dh->dh_oemid); + PE_READ16(hdr, dh->dh_oeminfo); + for (i = 0; i < 10; i++) + PE_READ16(hdr, dh->dh_reserved2[i]); + PE_READ32(hdr, dh->dh_lfanew); + + /* Check if the e_lfanew pointer is valid. */ + if (dh->dh_lfanew > pe->pe_fsize - 4) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + if (dh->dh_lfanew < sizeof(PE_DosHdr) && + (pe->pe_flags & LIBPE_F_SPECIAL_FILE)) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + + if (dh->dh_lfanew > sizeof(PE_DosHdr)) { + pe->pe_stub_ex = dh->dh_lfanew - sizeof(PE_DosHdr); + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + /* Read in DOS stub now. */ + if (libpe_read_msdos_stub(pe) < 0) { + pe->pe_flags |= LIBPE_F_BAD_DOS_HEADER; + return (0); + } + } + } + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + /* Jump to the PE header. */ + if (lseek(pe->pe_fd, (off_t) dh->dh_lfanew, SEEK_SET) < 0) { + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + return (0); + } + } + + if (read(pe->pe_fd, &pe_magic, 4) != 4 || + htole32(pe_magic) != PE_SIGNATURE) { + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + return (0); + } + + if (read(pe->pe_fd, coff, sizeof(coff)) != (ssize_t) sizeof(coff)) { + pe->pe_flags |= LIBPE_F_BAD_COFF_HEADER; + return (0); + } + + return (libpe_parse_coff_header(pe, coff)); +} + +int +libpe_read_msdos_stub(PE *pe) +{ + void *m; + + assert(pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0); + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_SET) < + 0) { + errno = EIO; + goto fail; + } + } + + if ((m = realloc(pe->pe_stub, sizeof(PE_DosHdr) + pe->pe_stub_ex)) == + NULL) { + errno = ENOMEM; + goto fail; + } + pe->pe_stub = m; + + if (read(pe->pe_fd, pe->pe_stub + sizeof(PE_DosHdr), pe->pe_stub_ex) != + (ssize_t) pe->pe_stub_ex) { + errno = EIO; + goto fail; + } + + pe->pe_flags |= LIBPE_F_LOAD_DOS_STUB; + + /* Search for the Rich header embedded just before the PE header. */ + (void) libpe_parse_rich_header(pe); + + return (0); + +fail: + pe->pe_stub_ex = 0; + + return (-1); +} + +/* + * The "standard" MS-DOS stub displaying "This program cannot be run in + * DOS mode". + */ +static const char msdos_stub[] = { + '\x0e','\x1f','\xba','\x0e','\x00','\xb4','\x09','\xcd', + '\x21','\xb8','\x01','\x4c','\xcd','\x21','\x54','\x68', + '\x69','\x73','\x20','\x70','\x72','\x6f','\x67','\x72', + '\x61','\x6d','\x20','\x63','\x61','\x6e','\x6e','\x6f', + '\x74','\x20','\x62','\x65','\x20','\x72','\x75','\x6e', + '\x20','\x69','\x6e','\x20','\x44','\x4f','\x53','\x20', + '\x6d','\x6f','\x64','\x65','\x2e','\x0d','\x0d','\x0a', + '\x24','\x00','\x00','\x00','\x00','\x00','\x00','\x00', +}; + +static void +init_dos_header(PE_DosHdr *dh) +{ + + dh->dh_magic[0] = 'M'; + dh->dh_magic[1] = 'Z'; + dh->dh_lastsize = 144; + dh->dh_nblock = 3; + dh->dh_hdrsize = 4; + dh->dh_maxalloc = 65535; + dh->dh_sp = 184; + dh->dh_relocpos = 0x40; + dh->dh_lfanew = 0x80; +} + +off_t +libpe_write_msdos_stub(PE *pe, off_t off) +{ + PE_DosHdr *dh; + char tmp[sizeof(PE_DosHdr)], *hdr; + off_t d; + int i, strip_rich; + + strip_rich = 0; + + if (pe->pe_cmd == PE_C_RDWR) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + + if (pe->pe_dh != NULL && + (pe->pe_flags & PE_F_STRIP_DOS_STUB)) { + /* + * If we strip MS-DOS stub, everything after it + * needs rewritten. + */ + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + goto done; + } + + /* + * lseek(2) to the PE signature if MS-DOS stub is not + * modified. + */ + if (pe->pe_dh != NULL && + (pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) == 0 && + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 && + (pe->pe_flags & PE_F_STRIP_RICH_HEADER) == 0) { + if (lseek(pe->pe_fd, + (off_t) (sizeof(PE_DosHdr) + pe->pe_stub_ex), + SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off = sizeof(PE_DosHdr) + pe->pe_stub_ex; + goto done; + } + + /* Check if we should strip the Rich header. */ + if (pe->pe_dh != NULL && pe->pe_stub_app == NULL && + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) == 0 && + (pe->pe_flags & PE_F_STRIP_RICH_HEADER)) { + if ((pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + (void) libpe_read_msdos_stub(pe); + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + if (pe->pe_rh != NULL) { + strip_rich = 1; + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + } + } + + /* + * If length of MS-DOS stub will change, Mark the PE + * signature is broken so that the PE signature and the + * headers follow it will be rewritten. + * + * The sections should be loaded now since the stub might + * overwrite the section data. + */ + if ((pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) || + (pe->pe_stub_app != NULL && pe->pe_stub_app_sz != + sizeof(PE_DosHdr) + pe->pe_stub_ex) || strip_rich) { + if (libpe_load_all_sections(pe) < 0) + return (-1); + if (lseek(pe->pe_fd, off, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + pe->pe_flags |= LIBPE_F_BAD_PE_HEADER; + } + } + + if (pe->pe_flags & PE_F_STRIP_DOS_STUB) + goto done; + + /* Always use application supplied MS-DOS stub, if exists. */ + if (pe->pe_stub_app != NULL && pe->pe_stub_app_sz > 0) { + if (write(pe->pe_fd, pe->pe_stub_app, pe->pe_stub_app_sz) != + (ssize_t) pe->pe_stub_app_sz) { + errno = EIO; + return (-1); + } + off = pe->pe_stub_app_sz; + goto done; + } + + /* + * Write MS-DOS header. + */ + + if (pe->pe_dh == NULL) { + if ((dh = calloc(1, sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + pe->pe_dh = dh; + + init_dos_header(dh); + + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + } else + dh = pe->pe_dh; + + if (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER) + init_dos_header(dh); + + if (strip_rich) { + d = pe->pe_rh_start - pe->pe_stub; + dh->dh_lfanew = roundup(d, 8); + } + + if ((pe->pe_flags & LIBPE_F_DIRTY_DOS_HEADER) || + (pe->pe_flags & LIBPE_F_BAD_DOS_HEADER)) { + memcpy(tmp, dh->dh_magic, 2); + hdr = tmp + 2; + PE_WRITE16(hdr, dh->dh_lastsize); + PE_WRITE16(hdr, dh->dh_nblock); + PE_WRITE16(hdr, dh->dh_nreloc); + PE_WRITE16(hdr, dh->dh_hdrsize); + PE_WRITE16(hdr, dh->dh_minalloc); + PE_WRITE16(hdr, dh->dh_maxalloc); + PE_WRITE16(hdr, dh->dh_ss); + PE_WRITE16(hdr, dh->dh_sp); + PE_WRITE16(hdr, dh->dh_checksum); + PE_WRITE16(hdr, dh->dh_ip); + PE_WRITE16(hdr, dh->dh_cs); + PE_WRITE16(hdr, dh->dh_relocpos); + PE_WRITE16(hdr, dh->dh_noverlay); + for (i = 0; i < 4; i++) + PE_WRITE16(hdr, dh->dh_reserved1[i]); + PE_WRITE16(hdr, dh->dh_oemid); + PE_WRITE16(hdr, dh->dh_oeminfo); + for (i = 0; i < 10; i++) + PE_WRITE16(hdr, dh->dh_reserved2[i]); + PE_WRITE32(hdr, dh->dh_lfanew); + + if (write(pe->pe_fd, tmp, sizeof(tmp)) != + (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + } else { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, (off_t) sizeof(PE_DosHdr), SEEK_CUR) < + 0) { + errno = EIO; + return (-1); + } + } + + off = sizeof(PE_DosHdr); + + /* + * Write the MS-DOS stub. + */ + + if (strip_rich) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + assert(pe->pe_stub != NULL && pe->pe_rh_start != NULL); + d = pe->pe_rh_start - pe->pe_stub; + if (lseek(pe->pe_fd, d, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + off = d; + goto done; + } + + if (pe->pe_cmd == PE_C_RDWR) { + if (lseek(pe->pe_fd, (off_t) pe->pe_stub_ex, SEEK_CUR) < 0) { + errno = EIO; + return (-1); + } + off += pe->pe_stub_ex; + goto done; + } + + if (write(pe->pe_fd, msdos_stub, sizeof(msdos_stub)) != + (ssize_t) sizeof(msdos_stub)) { + errno = EIO; + return (-1); + } + off += sizeof(msdos_stub); + +done: + pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER; + pe->pe_flags &= ~LIBPE_F_BAD_DOS_HEADER; + + return (off); +} diff --git a/libpe/libpe_init.c b/libpe/libpe_init.c new file mode 100644 index 000000000000..2579774bf0c5 --- /dev/null +++ b/libpe/libpe_init.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +libpe_open_object(PE *pe) +{ + struct stat sb; + mode_t mode; + char magic[sizeof(PE_DosHdr)]; + + if (fstat(pe->pe_fd, &sb) < 0) + return (-1); + + mode = sb.st_mode; + pe->pe_fsize = (size_t) sb.st_size; + + /* Reject unsupported file types. */ + if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && + !S_ISSOCK(mode)) { + errno = EINVAL; + return (-1); + } + + /* Read/Write mode is not supported for non-regular file. */ + if (pe->pe_cmd == PE_C_RDWR && !S_ISREG(mode)) { + errno = EINVAL; + return (-1); + } + + /* The minimal file should at least contain a COFF header. */ + if (S_ISREG(mode) && pe->pe_fsize < sizeof(PE_CoffHdr)) { + errno = ENOENT; + return (-1); + } + + /* + * Search for MS-DOS header or COFF header. + */ + + if (read(pe->pe_fd, magic, 2) != 2) { + errno = EIO; + return (-1); + } + + if (magic[0] == 'M' && magic[1] == 'Z') { + pe->pe_obj = PE_O_PE32; + if (read(pe->pe_fd, &magic[2], sizeof(PE_DosHdr) - 2) != + (ssize_t) sizeof(PE_DosHdr) - 2) { + errno = EIO; + return (-1); + } + return (libpe_parse_msdos_header(pe, magic)); + + } else if (magic[0] == 'P' && magic[1] == 'E') { + if (read(pe->pe_fd, magic, 2) != 2) { + errno = EIO; + return (-1); + } + if (magic[0] == '\0' && magic[1] == '\0') { + pe->pe_obj = PE_O_PE32; + if (read(pe->pe_fd, magic, sizeof(PE_CoffHdr)) != + (ssize_t) sizeof(PE_CoffHdr)) { + errno = EIO; + return (-1); + } + return (libpe_parse_coff_header(pe, magic)); + } + errno = ENOENT; + return (-1); + + } else { + pe->pe_obj = PE_O_COFF; + if (read(pe->pe_fd, &magic[2], sizeof(PE_CoffHdr) - 2) != + (ssize_t) sizeof(PE_CoffHdr) - 2) { + errno = EIO; + return (-1); + } + return (libpe_parse_coff_header(pe, magic)); + } +} + +void +libpe_release_object(PE *pe) +{ + PE_Scn *ps, *_ps; + + if (pe->pe_dh) + free(pe->pe_dh); + + if (pe->pe_rh) { + free(pe->pe_rh->rh_compid); + free(pe->pe_rh->rh_cnt); + free(pe->pe_rh); + } + + if (pe->pe_ch) + free(pe->pe_ch); + + if (pe->pe_oh) + free(pe->pe_oh); + + if (pe->pe_dd) + free(pe->pe_dd); + + if (pe->pe_stub) + free(pe->pe_stub); + + STAILQ_FOREACH_SAFE(ps, &pe->pe_scn, ps_next, _ps) + libpe_release_scn(ps); + + free(pe); +} diff --git a/libpe/libpe_rich.c b/libpe/libpe_rich.c new file mode 100644 index 000000000000..4669a224d004 --- /dev/null +++ b/libpe/libpe_rich.c @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +static char * +memfind(char *s, const char *find, size_t slen, size_t flen) +{ + int i; + + if (slen == 0 || flen == 0 || flen > slen) + return (NULL); + + for (i = 0; (size_t) i <= slen - flen; i++) { + if (s[i] != find[0]) + continue; + if (flen == 1) + return (&s[i]); + if (memcmp(&s[i + 1], &find[1], flen - 1) == 0) + return (&s[i]); + } + + return (NULL); +} + +int +libpe_parse_rich_header(PE *pe) +{ + PE_RichHdr *rh; + char *p, *r, *s; + uint32_t x; + int found, i; + + assert(pe->pe_stub != NULL && pe->pe_stub_ex > 0); + + /* Search for the "Rich" keyword to locate the Rich header. */ + s = pe->pe_stub + sizeof(PE_DosHdr); + r = memfind(s, PE_RICH_TEXT, pe->pe_stub_ex, 4); + if (r == NULL || r + 8 > s + pe->pe_stub_ex) { + errno = ENOENT; + return (-1); + } + + if ((rh = calloc(1, sizeof(*rh))) == NULL) { + errno = ENOMEM; + return (-1); + } + + rh->rh_xor = le32dec(r + 4); /* Retrieve the "XOR mask" */ + + /* + * Search for the hidden keyword "DanS" by XOR the dwords before + * the "Rich" keyword with the XOR mask. + */ + found = 0; + for (p = r - 4; p >= s; p -= 4) { + x = le32dec(p) ^ rh->rh_xor; + if (x == PE_RICH_HIDDEN) { + found = 1; + break; + } + } + if (!found) { + free(rh); + errno = ENOENT; + return (-1); + } + + /* + * Found the "DanS" keyword, which is the start of the Rich header. + * The next step is to skip the first 16 bytes (DanS, XOR mask, + * XOR mask, XOR mask) and read the (compid,cnt) tuples. + */ + pe->pe_rh_start = p; + p += 16; + rh->rh_total = (r - p) / 8; + if ((rh->rh_compid = malloc(rh->rh_total * sizeof(*rh->rh_compid))) == + NULL) { + free(rh); + errno = ENOMEM; + return (-1); + } + if ((rh->rh_cnt = malloc(rh->rh_total * sizeof(*rh->rh_cnt))) == + NULL) { + free(rh->rh_compid); + free(rh); + errno = ENOMEM; + return (-1); + } + for (i = 0; (uint32_t) i < rh->rh_total; i++, p += 8) { + rh->rh_compid[i] = le32dec(p) ^ rh->rh_xor; + rh->rh_cnt[i] = le32dec(p + 4) ^ rh->rh_xor; + } + + pe->pe_rh = rh; + + return (0); +} diff --git a/libpe/libpe_section.c b/libpe/libpe_section.c new file mode 100644 index 000000000000..7ff63fbef60f --- /dev/null +++ b/libpe/libpe_section.c @@ -0,0 +1,518 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_Scn * +libpe_alloc_scn(PE *pe) +{ + PE_Scn *ps; + + if ((ps = calloc(1, sizeof(PE_Scn))) == NULL) { + errno = ENOMEM; + return (NULL); + } + STAILQ_INIT(&ps->ps_b); + ps->ps_pe = pe; + + return (ps); +} + +void +libpe_release_scn(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb, *_sb; + + assert(ps != NULL); + + pe = ps->ps_pe; + + STAILQ_REMOVE(&pe->pe_scn, ps, _PE_Scn, ps_next); + + STAILQ_FOREACH_SAFE(sb, &ps->ps_b, sb_next, _sb) + libpe_release_buffer(sb); + + free(ps); +} + +static int +cmp_scn(PE_Scn *a, PE_Scn *b) +{ + + if (a->ps_sh.sh_addr < b->ps_sh.sh_addr) + return (-1); + else if (a->ps_sh.sh_addr == b->ps_sh.sh_addr) + return (0); + else + return (1); +} + +static void +sort_sections(PE *pe) +{ + + if (STAILQ_EMPTY(&pe->pe_scn)) + return; + + /* Sort the list of Scn by RVA in ascending order. */ + STAILQ_SORT(&pe->pe_scn, _PE_Scn, ps_next, cmp_scn); +} + +int +libpe_parse_section_headers(PE *pe) +{ + char tmp[sizeof(PE_SecHdr)], *hdr; + PE_Scn *ps; + PE_SecHdr *sh; + PE_CoffHdr *ch; + PE_DataDir *dd; + int found, i; + + assert(pe->pe_ch != NULL); + + for (i = 0; (uint16_t) i < pe->pe_ch->ch_nsec; i++) { + if (read(pe->pe_fd, tmp, sizeof(PE_SecHdr)) != + (ssize_t) sizeof(PE_SecHdr)) { + pe->pe_flags |= LIBPE_F_BAD_SEC_HEADER; + return (0); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = ++pe->pe_nscn; /* Setion index is 1-based */ + sh = &ps->ps_sh; + + /* + * Note that the section name won't be NUL-terminated if + * its length happens to be 8. + */ + memcpy(sh->sh_name, tmp, sizeof(sh->sh_name)); + hdr = tmp + 8; + PE_READ32(hdr, sh->sh_virtsize); + PE_READ32(hdr, sh->sh_addr); + PE_READ32(hdr, sh->sh_rawsize); + PE_READ32(hdr, sh->sh_rawptr); + PE_READ32(hdr, sh->sh_relocptr); + PE_READ32(hdr, sh->sh_lineptr); + PE_READ16(hdr, sh->sh_nreloc); + PE_READ16(hdr, sh->sh_nline); + PE_READ32(hdr, sh->sh_char); + } + + /* + * For all the data directories that don't belong to any section, + * we create pseudo sections for them to make layout easier. + */ + dd = pe->pe_dd; + if (dd != NULL && dd->dd_total > 0) { + for (i = 0; (uint32_t) i < pe->pe_dd->dd_total; i++) { + if (dd->dd_e[i].de_size == 0) + continue; + found = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + if (dd->dd_e[i].de_addr >= sh->sh_addr && + dd->dd_e[i].de_addr + dd->dd_e[i].de_size <= + sh->sh_addr + sh->sh_virtsize) { + found = 1; + break; + } + } + if (found) + continue; + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFF0000U | i; + sh = &ps->ps_sh; + sh->sh_rawptr = dd->dd_e[i].de_addr; /* FIXME */ + sh->sh_rawsize = dd->dd_e[i].de_size; + } + } + + /* + * Also consider the COFF symbol table as a pseudo section. + */ + ch = pe->pe_ch; + if (ch->ch_nsym > 0) { + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFFFFFFU; + sh = &ps->ps_sh; + sh->sh_rawptr = ch->ch_symptr; + sh->sh_rawsize = ch->ch_nsym * PE_SYM_ENTRY_SIZE; + pe->pe_nsym = ch->ch_nsym; + } + + /* PE file headers initialization is complete if we reach here. */ + return (0); +} + +int +libpe_load_section(PE *pe, PE_Scn *ps) +{ + PE_SecHdr *sh; + PE_SecBuf *sb; + size_t sz; + char tmp[4]; + + assert(pe != NULL && ps != NULL); + assert((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0); + + sh = &ps->ps_sh; + + /* Allocate a PE_SecBuf struct without buffer for empty sections. */ + if (sh->sh_rawsize == 0) { + (void) libpe_alloc_buffer(ps, 0); + ps->ps_flags |= LIBPE_F_LOAD_SECTION; + return (0); + } + + if ((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0) { + if (lseek(pe->pe_fd, (off_t) sh->sh_rawptr, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + if ((sb = libpe_alloc_buffer(ps, sh->sh_rawsize)) == NULL) + return (-1); + + if (read(pe->pe_fd, sb->sb_pb.pb_buf, sh->sh_rawsize) != + (ssize_t) sh->sh_rawsize) { + errno = EIO; + return (-1); + } + + if (ps->ps_ndx == 0xFFFFFFFFU) { + /* + * Index 0xFFFFFFFF indicates this section is a pseudo + * section that contains the COFF symbol table. We should + * read in the string table right after it. + */ + if (read(pe->pe_fd, tmp, sizeof(tmp)) != + (ssize_t) sizeof(tmp)) { + errno = EIO; + return (-1); + } + sz = le32dec(tmp); + + /* + * The minimum value for the size field is 4, which indicates + * there is no string table. + */ + if (sz > 4) { + sz -= 4; + if ((sb = libpe_alloc_buffer(ps, sz)) == NULL) + return (-1); + if (read(pe->pe_fd, sb->sb_pb.pb_buf, sz) != + (ssize_t) sz) { + errno = EIO; + return (-1); + } + } + } + + ps->ps_flags |= LIBPE_F_LOAD_SECTION; + + return (0); +} + +int +libpe_load_all_sections(PE *pe) +{ + PE_Scn *ps; + PE_SecHdr *sh; + unsigned r, s; + off_t off; + char tmp[256]; + + /* Calculate the current offset into the file. */ + off = 0; + if (pe->pe_dh != NULL) + off += pe->pe_dh->dh_lfanew + 4; + if (pe->pe_ch != NULL) + off += sizeof(PE_CoffHdr) + pe->pe_ch->ch_optsize; + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_LOAD_SECTION) + continue; + sh = &ps->ps_sh; + + /* + * For special files, we consume the padding in between + * and advance to the section offset. + */ + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + /* Can't go backwards. */ + if (off > sh->sh_rawptr) { + errno = EIO; + return (-1); + } + if (off < sh->sh_rawptr) { + r = sh->sh_rawptr - off; + for (; r > 0; r -= s) { + s = r > sizeof(tmp) ? sizeof(tmp) : r; + if (read(pe->pe_fd, tmp, s) != + (ssize_t) s) { + errno = EIO; + return (-1); + } + } + } + } + + /* Load the section content. */ + if (libpe_load_section(pe, ps) < 0) + return (-1); + } + + return (0); +} + +int +libpe_resync_sections(PE *pe, off_t off) +{ + PE_Scn *ps; + PE_SecHdr *sh; + size_t falign, nsec; + + /* Firstly, sort all sections by their file offsets. */ + sort_sections(pe); + + /* Count the number of sections. */ + nsec = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + if (ps->ps_ndx & 0xFFFF0000U) + continue; + nsec++; + } + pe->pe_nscn = nsec; + + /* + * Calculate the file offset for the first section. (`off' is + * currently pointing to the COFF header.) + */ + off += sizeof(PE_CoffHdr); + if (pe->pe_ch != NULL && pe->pe_ch->ch_optsize > 0) + off += pe->pe_ch->ch_optsize; + else { + switch (pe->pe_obj) { + case PE_O_PE32: + off += PE_COFF_OPT_SIZE_32; + break; + case PE_O_PE32P: + off += PE_COFF_OPT_SIZE_32P; + break; + case PE_O_COFF: + default: + break; + } + } + off += nsec * sizeof(PE_SecHdr); + + /* + * Determine the file alignment for sections. + */ + if (pe->pe_oh != NULL && pe->pe_oh->oh_filealign > 0) + falign = pe->pe_oh->oh_filealign; + else { + /* + * Use the default file alignment defined by the + * PE/COFF specification. + */ + if (pe->pe_obj == PE_O_COFF) + falign = 4; + else + falign = 512; + } + + /* + * Step through each section (and pseduo section) and verify + * alignment constraint and overlapping, make adjustment if need. + */ + pe->pe_rvamax = 0; + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + + sh = &ps->ps_sh; + + if (sh->sh_addr + sh->sh_virtsize > pe->pe_rvamax) + pe->pe_rvamax = sh->sh_addr + sh->sh_virtsize; + + if (ps->ps_ndx & 0xFFFF0000U) + ps->ps_falign = 4; + else + ps->ps_falign = falign; + + off = roundup(off, ps->ps_falign); + + if (off != sh->sh_rawptr) + ps->ps_flags |= PE_F_DIRTY; + + if (ps->ps_flags & PE_F_DIRTY) { + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (libpe_load_section(pe, ps) < 0) + return (-1); + } + sh->sh_rawsize = libpe_resync_buffers(ps); + } + + /* + * Sections only contains uninitialized data should set + * PointerToRawData to zero according to the PE/COFF + * specification. + */ + if (sh->sh_rawsize == 0) + sh->sh_rawptr = 0; + else + sh->sh_rawptr = off; + + off += sh->sh_rawsize; + } + + return (0); +} + +off_t +libpe_write_section_headers(PE *pe, off_t off) +{ + char tmp[sizeof(PE_SecHdr)], *hdr; + PE_Scn *ps; + PE_SecHdr *sh; + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER || pe->pe_nscn == 0) + return (off); + + if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0) { + off += sizeof(PE_SecHdr) * pe->pe_ch->ch_nsec; + return (off); + } + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + if (ps->ps_ndx & 0xFFFF0000U) + continue; + if ((pe->pe_flags & LIBPE_F_DIRTY_SEC_HEADER) == 0 && + (ps->ps_flags & PE_F_DIRTY) == 0) + goto next_header; + + sh = &ps->ps_sh; + + memcpy(tmp, sh->sh_name, sizeof(sh->sh_name)); + hdr = tmp + 8; + PE_WRITE32(hdr, sh->sh_virtsize); + PE_WRITE32(hdr, sh->sh_addr); + PE_WRITE32(hdr, sh->sh_rawsize); + PE_WRITE32(hdr, sh->sh_rawptr); + PE_WRITE32(hdr, sh->sh_relocptr); + PE_WRITE32(hdr, sh->sh_lineptr); + PE_WRITE16(hdr, sh->sh_nreloc); + PE_WRITE16(hdr, sh->sh_nline); + PE_WRITE32(hdr, sh->sh_char); + + if (write(pe->pe_fd, tmp, sizeof(PE_SecHdr)) != + (ssize_t) sizeof(PE_SecHdr)) { + errno = EIO; + return (-1); + } + + next_header: + off += sizeof(PE_SecHdr); + } + + return (off); +} + +off_t +libpe_write_sections(PE *pe, off_t off) +{ + PE_Scn *ps; + PE_SecHdr *sh; + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) + return (off); + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + sh = &ps->ps_sh; + + if (ps->ps_flags & LIBPE_F_STRIP_SECTION) + continue; + + /* Skip empty sections. */ + if (sh->sh_rawptr == 0 || sh->sh_rawsize == 0) + continue; + + /* + * Padding between sections. (padding always written + * in case the the section headers or sections are + * moved or shrinked.) + */ + assert(off <= sh->sh_rawptr); + if (off < sh->sh_rawptr) + libpe_pad(pe, sh->sh_rawptr - off); + + if ((ps->ps_flags & PE_F_DIRTY) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + if (lseek(pe->pe_fd, + (off_t) (sh->sh_rawptr + sh->sh_rawsize), + SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + off = sh->sh_rawptr + sh->sh_rawsize; + continue; + } + + off = sh->sh_rawptr; + + if (libpe_write_buffers(ps) < 0) + return (-1); + + off += sh->sh_rawsize; + + ps->ps_flags &= ~PE_F_DIRTY; + } + + return (off); +} diff --git a/libpe/libpe_utils.c b/libpe/libpe_utils.c new file mode 100644 index 000000000000..9bc9a54bc4ea --- /dev/null +++ b/libpe/libpe_utils.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: libpe_utils.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +off_t +libpe_align(PE *pe, off_t off, size_t align) +{ + off_t n; + + assert(align > 0 && (align & (align - 1)) == 0); + + n = roundup(off, align); + if (n > off) { + if (libpe_pad(pe, n - off) < 0) + return (-1); + } + + return (n); +} + +int +libpe_pad(PE *pe, size_t pad) +{ + char tmp[128]; + size_t s; + + memset(tmp, 0, sizeof(tmp)); + for (; pad > 0; pad -= s) { + s = pad > sizeof(tmp) ? sizeof(tmp) : pad; + if (write(pe->pe_fd, tmp, s) != (ssize_t) s) { + errno = EIO; + return (-1); + } + } + + return (0); +} diff --git a/libpe/os.Linux.mk b/libpe/os.Linux.mk new file mode 100644 index 000000000000..ed5bdf00e835 --- /dev/null +++ b/libpe/os.Linux.mk @@ -0,0 +1,6 @@ +# $Id: os.Linux.mk 3312 2016-01-10 09:23:51Z kaiwang27 $ + +CFLAGS+= -Wall -Wno-unused-parameter -Wstrict-prototypes \ + -Wmissing-prototypes -Wpointer-arith -Wreturn-type \ + -Wcast-qual -Wwrite-strings -Wswitch -Wshadow \ + -Wcast-align -Wunused-parameter diff --git a/libpe/os.NetBSD.mk b/libpe/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/libpe/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/libpe/pe.h b/libpe/pe.h new file mode 100644 index 000000000000..5b6130e47a7f --- /dev/null +++ b/libpe/pe.h @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: pe.h 3312 2016-01-10 09:23:51Z kaiwang27 $ + */ + +#ifndef _PE_H_ +#define _PE_H_ + +#include + +/* + * MS-DOS header. + */ + +typedef struct _PE_DosHdr { + char dh_magic[2]; + uint16_t dh_lastsize; + uint16_t dh_nblock; + uint16_t dh_nreloc; + uint16_t dh_hdrsize; + uint16_t dh_minalloc; + uint16_t dh_maxalloc; + uint16_t dh_ss; + uint16_t dh_sp; + uint16_t dh_checksum; + uint16_t dh_ip; + uint16_t dh_cs; + uint16_t dh_relocpos; + uint16_t dh_noverlay; + uint16_t dh_reserved1[4]; + uint16_t dh_oemid; + uint16_t dh_oeminfo; + uint16_t dh_reserved2[10]; + uint32_t dh_lfanew; +} PE_DosHdr; + +/* + * Rich header. + */ + +typedef struct _PE_RichHdr { + uint32_t rh_xor; + uint32_t rh_total; + uint32_t *rh_compid; + uint32_t *rh_cnt; +} PE_RichHdr; + +/* + * COFF header: Machine Types. + */ + +#define IMAGE_FILE_MACHINE_UNKNOWN 0x0 /* not specified */ +#define IMAGE_FILE_MACHINE_AM33 0x1d3 /* Matsushita AM33 */ +#define IMAGE_FILE_MACHINE_AMD64 0x8664 /* x86-64 */ +#define IMAGE_FILE_MACHINE_ARM 0x1c0 /* ARM LE */ +#define IMAGE_FILE_MACHINE_ARMNT 0x1c4 /* ARMv7(or higher) Thumb */ +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 /* ARMv8 64-bit */ +#define IMAGE_FILE_MACHINE_EBC 0xebc /* EFI byte code */ +#define IMAGE_FILE_MACHINE_I386 0x14c /* x86 */ +#define IMAGE_FILE_MACHINE_IA64 0x200 /* IA64 */ +#define IMAGE_FILE_MACHINE_M32R 0x9041 /* Mitsubishi M32R LE */ +#define IMAGE_FILE_MACHINE_MIPS16 0x266 /* MIPS16 */ +#define IMAGE_FILE_MACHINE_MIPSFPU 0x366 /* MIPS with FPU */ +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 /* MIPS16 with FPU */ +#define IMAGE_FILE_MACHINE_POWERPC 0x1f0 /* Power PC LE */ +#define IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 /* Power PC floating point */ +#define IMAGE_FILE_MACHINE_R4000 0x166 /* MIPS R4000 LE */ +#define IMAGE_FILE_MACHINE_SH3 0x1a2 /* Hitachi SH3 */ +#define IMAGE_FILE_MACHINE_SH3DSP 0x1a3 /* Hitachi SH3 DSP */ +#define IMAGE_FILE_MACHINE_SH4 0x1a6 /* Hitachi SH4 */ +#define IMAGE_FILE_MACHINE_SH5 0x1a8 /* Hitachi SH5 */ +#define IMAGE_FILE_MACHINE_THUMB 0x1c2 /* ARM or Thumb interworking */ +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 /* MIPS LE WCE v2 */ + +/* + * COFF header: Characteristics + */ + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +/* + * COFF Header. + */ + +typedef struct _PE_CoffHdr { + uint16_t ch_machine; + uint16_t ch_nsec; + uint32_t ch_timestamp; + uint32_t ch_symptr; + uint32_t ch_nsym; + uint16_t ch_optsize; + uint16_t ch_char; +} PE_CoffHdr; + + +/* + * Optional Header: Subsystem. + */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 + +/* + * Optional Header: DLL Characteristics + */ + +#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE 0x0040 +#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY 0x0080 +#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION 0x0200 +#define IMAGE_DLL_CHARACTERISTICS_NO_SEH 0x0400 +#define IMAGE_DLL_CHARACTERISTICS_NO_BIND 0x0800 +#define IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER 0x2000 +#define IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +/* + * Optional Header. + */ + +#define PE_FORMAT_ROM 0x107 +#define PE_FORMAT_32 0x10b +#define PE_FORMAT_32P 0x20b + +typedef struct _PE_OptHdr { + uint16_t oh_magic; + uint8_t oh_ldvermajor; + uint8_t oh_ldverminor; + uint32_t oh_textsize; + uint32_t oh_datasize; + uint32_t oh_bsssize; + uint32_t oh_entry; + uint32_t oh_textbase; + uint32_t oh_database; + uint64_t oh_imgbase; + uint32_t oh_secalign; + uint32_t oh_filealign; + uint16_t oh_osvermajor; + uint16_t oh_osverminor; + uint16_t oh_imgvermajor; + uint16_t oh_imgverminor; + uint16_t oh_subvermajor; + uint16_t oh_subverminor; + uint32_t oh_win32ver; + uint32_t oh_imgsize; + uint32_t oh_hdrsize; + uint32_t oh_checksum; + uint16_t oh_subsystem; + uint16_t oh_dllchar; + uint64_t oh_stacksizer; + uint64_t oh_stacksizec; + uint64_t oh_heapsizer; + uint64_t oh_heapsizec; + uint32_t oh_ldrflags; + uint32_t oh_ndatadir; +} PE_OptHdr; + +/* + * Optional Header: Data Directories. + */ + +#define PE_DD_EXPORT 0 +#define PE_DD_IMPORT 1 +#define PE_DD_RESROUCE 2 +#define PE_DD_EXCEPTION 3 +#define PE_DD_CERTIFICATE 4 +#define PE_DD_BASERELOC 5 +#define PE_DD_DEBUG 6 +#define PE_DD_ARCH 7 +#define PE_DD_GLOBALPTR 8 +#define PE_DD_TLS 9 +#define PE_DD_LOADCONFIG 10 +#define PE_DD_BOUNDIMPORT 11 +#define PE_DD_IAT 12 +#define PE_DD_DELAYIMPORT 13 +#define PE_DD_CLRRUNTIME 14 +#define PE_DD_RESERVED 15 +#define PE_DD_MAX 16 + +typedef struct _PE_DataDirEntry { + uint32_t de_addr; + uint32_t de_size; +} PE_DataDirEntry; + +typedef struct _PE_DataDir { + PE_DataDirEntry dd_e[PE_DD_MAX]; + uint32_t dd_total; +} PE_DataDir; + +/* + * Section Headers: Section flags. + */ + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 +#define IMAGE_SCN_GPREL 0x00008000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +/* + * Section Headers. + */ + +typedef struct _PE_SecHdr { + char sh_name[8]; + uint32_t sh_virtsize; + uint32_t sh_addr; + uint32_t sh_rawsize; + uint32_t sh_rawptr; + uint32_t sh_relocptr; + uint32_t sh_lineptr; + uint16_t sh_nreloc; + uint16_t sh_nline; + uint32_t sh_char; +} PE_SecHdr; + +#endif /* !_PE_H_ */ diff --git a/libpe/pe_buffer.c b/libpe/pe_buffer.c new file mode 100644 index 000000000000..e4ac19fa04b8 --- /dev/null +++ b/libpe/pe_buffer.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_buffer.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_Buffer * +pe_getbuffer(PE_Scn *ps, PE_Buffer *pb) +{ + PE *pe; + PE_SecBuf *sb; + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + pe = ps->ps_pe; + + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + if (pe->pe_flags & LIBPE_F_SPECIAL_FILE) { + if (libpe_load_all_sections(pe) < 0) + return (NULL); + } else { + if (libpe_load_section(pe, ps) < 0) + return (NULL); + } + } + + sb = (PE_SecBuf *) pb; + + if (sb == NULL) + sb = STAILQ_FIRST(&ps->ps_b); + else + sb = STAILQ_NEXT(sb, sb_next); + + return ((PE_Buffer *) sb); +} + +PE_Buffer * +pe_newbuffer(PE_Scn *ps) +{ + PE *pe; + PE_SecBuf *sb; + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + pe = ps->ps_pe; + + if (pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps->ps_flags & LIBPE_F_LOAD_SECTION) == 0) { + if (libpe_load_section(pe, ps) < 0) + return (NULL); + } + + if ((sb = libpe_alloc_buffer(ps, 0)) == NULL) + return (NULL); + + sb->sb_flags |= PE_F_DIRTY; + ps->ps_flags |= PE_F_DIRTY; + + return ((PE_Buffer *) sb); +} diff --git a/libpe/pe_cntl.c b/libpe/pe_cntl.c new file mode 100644 index 000000000000..1fc8c474015e --- /dev/null +++ b/libpe/pe_cntl.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_cntl.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_cntl(PE *pe, PE_Cmd cmd) +{ + + if (pe == NULL) { + errno = EINVAL; + return (-1); + } + + switch (cmd) { + case PE_C_FDDONE: + pe->pe_flags |= LIBPE_F_FD_DONE; + break; + + case PE_C_FDREAD: + if (pe->pe_cmd == PE_C_WRITE) { + errno = EACCES; + return (-1); + } + if (libpe_load_all_sections(pe) < 0) + return (-1); + break; + + default: + errno = EINVAL; + return (-1); + } + + return (0); +} diff --git a/libpe/pe_coff.c b/libpe/pe_coff.c new file mode 100644 index 000000000000..d5cd83311a58 --- /dev/null +++ b/libpe/pe_coff.c @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_coff.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_CoffHdr * +pe_coff_header(PE *pe) +{ + + if (pe->pe_ch == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_ch); +} + +PE_OptHdr * +pe_opt_header(PE *pe) +{ + + if (pe->pe_oh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_oh); +} + +PE_DataDir * +pe_data_dir(PE *pe) +{ + + if (pe->pe_dd == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_dd); +} + +int +pe_update_coff_header(PE *pe, PE_CoffHdr *ch) +{ + + if (pe == NULL || ch == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_ch == NULL) { + if ((pe->pe_ch = malloc(sizeof(PE_CoffHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } else { + /* Rewrite optional header if `optsize' field changed. */ + if (pe->pe_ch->ch_optsize != ch->ch_optsize) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + } + + *pe->pe_ch = *ch; + + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + + return (0); +} + +int +pe_update_opt_header(PE *pe, PE_OptHdr *oh) +{ + + if (pe == NULL || oh == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_oh == NULL) { + if ((pe->pe_oh = malloc(sizeof(PE_OptHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_oh = *oh; + + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_update_data_dir(PE *pe, PE_DataDir *dd) +{ + + if (pe == NULL || dd == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_dd == NULL) { + if ((pe->pe_dd = malloc(sizeof(PE_DataDir))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_dd = *dd; + + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} diff --git a/libpe/pe_dos.c b/libpe/pe_dos.c new file mode 100644 index 000000000000..01ba42f44aae --- /dev/null +++ b/libpe/pe_dos.c @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_dos.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_DosHdr * +pe_msdos_header(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_dh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_dh); +} + +char * +pe_msdos_stub(PE *pe, size_t *len) +{ + + if (pe == NULL || len == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + (void) libpe_read_msdos_stub(pe); + } + + *len = sizeof(PE_DosHdr) + pe->pe_stub_ex; + + return (pe->pe_stub); +} + +int +ps_update_msdos_header(PE *pe, PE_DosHdr *dh) +{ + + if (pe == NULL || dh == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_dh == NULL) { + if ((pe->pe_dh = malloc(sizeof(PE_DosHdr))) == NULL) { + errno = ENOMEM; + return (-1); + } + } + + *pe->pe_dh = *dh; + + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + + return (0); +} + +int +ps_update_msdos_stub(PE *pe, char *dos_stub, size_t sz) +{ + + if (pe == NULL || dos_stub == NULL || sz == 0) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + pe->pe_stub_app = dos_stub; + pe->pe_stub_app_sz = sz; + + return (0); +} diff --git a/libpe/pe_flag.c b/libpe/pe_flag.c new file mode 100644 index 000000000000..c392a4d2eeaf --- /dev/null +++ b/libpe/pe_flag.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_flag.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_flag(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR)) { + errno = EINVAL; + return (-1); + } + + if ((flags & ~(PE_F_STRIP_DOS_STUB | PE_F_STRIP_RICH_HEADER | + PE_F_STRIP_SYMTAB | PE_F_STRIP_DEBUG)) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= flags; + else + pe->pe_flags &= ~flags; + + return (0); +} + +int +pe_flag_dos_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER; + + return (0); +} + +int +pe_flag_coff_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER; + + return (0); +} + +int +pe_flag_opt_header(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_flag_data_dir(PE *pe, PE_Cmd c, unsigned int flags) +{ + + if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; + + return (0); +} + +int +pe_flag_scn(PE_Scn *ps, PE_Cmd c, unsigned int flags) +{ + + if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~(PE_F_DIRTY | PE_F_STRIP_SECTION)) == 0) { + errno = EINVAL; + return (-1); + } + + if (c == PE_C_SET) + ps->ps_flags |= flags; + else + ps->ps_flags &= ~flags; + + return (0); +} + +int +pe_flag_section_header(PE_Scn *ps, PE_Cmd c, unsigned int flags) +{ + PE *pe; + + if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + pe = ps->ps_pe; + + /* The library doesn't support per section header dirty flag. */ + if (c == PE_C_SET) + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + else + pe->pe_flags &= ~LIBPE_F_DIRTY_SEC_HEADER; + + return (0); +} + +int +pe_flag_buffer(PE_Buffer *pb, PE_Cmd c, unsigned int flags) +{ + PE_SecBuf *sb; + + if (pb == NULL || (c != PE_C_SET && c != PE_C_CLR) || + (flags & ~PE_F_DIRTY) != 0) { + errno = EINVAL; + return (-1); + } + + sb = (PE_SecBuf *) pb; + + if (c == PE_C_SET) + sb->sb_flags |= flags; + else + sb->sb_flags &= ~flags; + + return (0); +} diff --git a/libpe/pe_init.c b/libpe/pe_init.c new file mode 100644 index 000000000000..4e2f22a260d2 --- /dev/null +++ b/libpe/pe_init.c @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2015 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_init.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE * +pe_init(int fd, PE_Cmd c, PE_Object o) +{ + PE *pe; + + if ((pe = calloc(1, sizeof(*pe))) == NULL) { + errno = ENOMEM; + return (NULL); + } + pe->pe_fd = fd; + pe->pe_cmd = c; + pe->pe_obj = o; + STAILQ_INIT(&pe->pe_scn); + + switch (c) { + case PE_C_READ: + case PE_C_RDWR: + if (libpe_open_object(pe) < 0) + goto init_fail; + break; + + case PE_C_WRITE: + if (o < PE_O_PE32 || o > PE_O_COFF) { + errno = EINVAL; + goto init_fail; + } + break; + + default: + errno = EINVAL; + goto init_fail; + } + + return (pe); + +init_fail: + pe_finish(pe); + return (NULL); +} + +void +pe_finish(PE *pe) +{ + + if (pe == NULL) + return; + + libpe_release_object(pe); +} + +PE_Object +pe_object(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (PE_O_UNKNOWN); + } + + return (pe->pe_obj); +} diff --git a/libpe/pe_rich.c b/libpe/pe_rich.c new file mode 100644 index 000000000000..ea1029e58f5f --- /dev/null +++ b/libpe/pe_rich.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_rich.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_RichHdr * +pe_rich_header(PE *pe) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_rh == NULL && pe->pe_stub_ex > 0 && + (pe->pe_flags & LIBPE_F_LOAD_DOS_STUB) == 0) { + assert((pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0); + (void) libpe_read_msdos_stub(pe); + } + + if (pe->pe_rh == NULL) { + errno = ENOENT; + return (NULL); + } + + return (pe->pe_rh); +} + +static uint32_t +rol32(uint32_t n, int c) +{ + + c &= 0x1f; + + return ((n << c) | (n >> (0x20 - c))); +} + +int +pe_rich_header_validate(PE *pe) +{ + PE_RichHdr *rh; + uint32_t cksum; + char *p; + int i, off; + + if (pe_rich_header(pe) == NULL) + return (-1); + + assert(pe->pe_rh_start != NULL); + + /* + * Initial value of the checksum is the offset to the begin of + * the Rich header. + */ + cksum = pe->pe_rh_start - pe->pe_stub; + + /* + * Add the bytes before the Rich header to the checksum, rotated + * left by the offset. + */ + for (p = pe->pe_stub; p < pe->pe_rh_start; p++) { + /* Skip dh_lfanew. */ + off = p - pe->pe_stub; + if (off >= 0x3c && off < 0x40) + continue; + cksum += rol32((unsigned char) *p, off); + } + + /* Add each compid rotated left by its count to the checksum. */ + rh = pe->pe_rh; + for (i = 0; (uint32_t) i < rh->rh_total; i++) + cksum += rol32(rh->rh_compid[i], rh->rh_cnt[i]); + + /* Validate the checksum with the XOR mask stored after "Rich". */ + if (cksum == rh->rh_xor) + return (1); + + return (0); +} diff --git a/libpe/pe_section.c b/libpe/pe_section.c new file mode 100644 index 000000000000..3e82d8480596 --- /dev/null +++ b/libpe/pe_section.c @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +PE_Scn * +pe_getscn(PE *pe, size_t ndx) +{ + PE_Scn *ps; + + if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) { + errno = EINVAL; + return (NULL); + } + + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_ndx == ndx) + return (ps); + } + + errno = ENOENT; + + return (NULL); +} + +size_t +pe_ndxscn(PE_Scn *ps) +{ + + if (ps == NULL) { + errno = EINVAL; + return (0); + } + + return (ps->ps_ndx); +} + +PE_Scn * +pe_nextscn(PE *pe, PE_Scn *ps) +{ + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (ps == NULL) + ps = STAILQ_FIRST(&pe->pe_scn); + else + ps = STAILQ_NEXT(ps, ps_next); + + while (ps != NULL) { + if (ps->ps_ndx >= 1 && ps->ps_ndx <= 0xFFFFU) + return (ps); + ps = STAILQ_NEXT(ps, ps_next); + } + + return (NULL); +} + +PE_Scn * +pe_newscn(PE *pe) +{ + PE_Scn *ps, *tps, *_tps; + + if (pe == NULL) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (NULL); + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) { + STAILQ_FOREACH_SAFE(tps, &pe->pe_scn, ps_next, _tps) + libpe_release_scn(tps); + pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER; + } + + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + + ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (ps); +} + +PE_Scn * +pe_insertscn(PE *pe, size_t ndx) +{ + PE_Scn *ps, *a, *b; + + if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) { + errno = EINVAL; + return (NULL); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (NULL); + } + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (NULL); + + if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) { + STAILQ_FOREACH_SAFE(a, &pe->pe_scn, ps_next, b) + libpe_release_scn(a); + pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER; + } + + b = NULL; + STAILQ_FOREACH(a, &pe->pe_scn, ps_next) { + if (a->ps_ndx & 0xFFFF0000U) + continue; + if (a->ps_ndx == ndx) + break; + b = a; + } + + if (a == NULL) { + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + if (b == NULL) + ps->ps_ndx = 1; + else + ps->ps_ndx = b->ps_ndx + 1; + } else if (b == NULL) { + STAILQ_INSERT_HEAD(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 1; + } else { + STAILQ_INSERT_AFTER(&pe->pe_scn, b, ps, ps_next); + ps->ps_ndx = ndx; + } + + a = ps; + while ((a = STAILQ_NEXT(a, ps_next)) != NULL) { + if ((a->ps_ndx & 0xFFFF0000U) == 0) + a->ps_ndx++; + } + + ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (ps); +} + +PE_SecHdr * +pe_section_header(PE_Scn *ps) +{ + + if (ps == NULL) { + errno = EINVAL; + return (NULL); + } + + return (&ps->ps_sh); +} + +int +pe_update_section_header(PE_Scn *ps, PE_SecHdr *sh) +{ + PE *pe; + + if (ps == NULL || sh == NULL) { + errno = EINVAL; + return (-1); + } + + pe = ps->ps_pe; + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + ps->ps_sh = *sh; + pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; + + return (0); +} diff --git a/libpe/pe_symtab.c b/libpe/pe_symtab.c new file mode 100644 index 000000000000..d0e90d14ad3e --- /dev/null +++ b/libpe/pe_symtab.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_symtab.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +int +pe_update_symtab(PE *pe, char *symtab, size_t sz, unsigned int nsym) +{ + PE_Scn *ps; + PE_SecBuf *sb; + PE_SecHdr *sh; + + if (pe == NULL || symtab == NULL || sz == 0) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + /* Remove the old symbol table. */ + STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + if (ps->ps_ndx == 0xFFFFFFFFU) + libpe_release_scn(ps); + } + + /* + * Insert the new symbol table. + */ + + if ((ps = libpe_alloc_scn(pe)) == NULL) + return (-1); + + STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); + ps->ps_ndx = 0xFFFFFFFFU; + ps->ps_flags |= PE_F_DIRTY; + + /* + * Set the symbol table section offset to the maximum to make sure + * that it will be placed in the end of the file during section + * layout. + */ + sh = &ps->ps_sh; + sh->sh_rawptr = 0xFFFFFFFFU; + sh->sh_rawsize = sz; + + /* Allocate the buffer. */ + if ((sb = libpe_alloc_buffer(ps, 0)) == NULL) + return (-1); + sb->sb_flags |= PE_F_DIRTY; + sb->sb_pb.pb_size = sz; + sb->sb_pb.pb_buf = symtab; + + pe->pe_nsym = nsym; + + return (0); +} diff --git a/libpe/pe_update.c b/libpe/pe_update.c new file mode 100644 index 000000000000..ec2b2e52492d --- /dev/null +++ b/libpe/pe_update.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2016 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "_libpe.h" + +ELFTC_VCSID("$Id: pe_update.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); + +off_t +pe_update(PE *pe) +{ + off_t off; + + if (pe == NULL) { + errno = EINVAL; + return (-1); + } + + if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { + errno = EACCES; + return (-1); + } + + if (pe->pe_cmd == PE_C_RDWR || (pe->pe_cmd == PE_C_WRITE && + (pe->pe_flags & LIBPE_F_SPECIAL_FILE) == 0)) { + if (lseek(pe->pe_fd, 0, SEEK_SET) < 0) { + errno = EIO; + return (-1); + } + } + + off = 0; + + if (pe->pe_obj == PE_O_PE32 || pe->pe_obj == PE_O_PE32P) { + if ((off = libpe_write_msdos_stub(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_pe_header(pe, off)) < 0) + return (-1); + } + + if (libpe_resync_sections(pe, off) < 0) + return (-1); + + if ((off = libpe_write_coff_header(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_section_headers(pe, off)) < 0) + return (-1); + + if ((off = libpe_write_sections(pe, off)) < 0) + return (-1); + + if (ftruncate(pe->pe_fd, off) < 0) { + errno = EIO; + return (-1); + } + + return (off); +} diff --git a/mk/elftoolchain.components.mk b/mk/elftoolchain.components.mk new file mode 100644 index 000000000000..44ba7893aa01 --- /dev/null +++ b/mk/elftoolchain.components.mk @@ -0,0 +1,21 @@ +# +# $Id: elftoolchain.components.mk 3316 2016-01-11 22:48:22Z jkoshy $ +# + +# Knobs to turn parts of the source tree on or off. + +# Build the automation tools. +WITH_BUILD_TOOLS= no + +# Build additional tutorial documentation. (Manual page generation is +# controlled by the 'MKDOC' knob). +WITH_DOCUMENTATION=yes + +# Build the instruction set analyser. +WITH_ISA= no + +# Build PE support. +WITH_PE= yes + +# Build test suites. +WITH_TESTS= yes diff --git a/mk/elftoolchain.prog.mk b/mk/elftoolchain.prog.mk index f19902a9a830..529171e22b53 100644 --- a/mk/elftoolchain.prog.mk +++ b/mk/elftoolchain.prog.mk @@ -1,7 +1,7 @@ # # Rules for building programs. # -# $Id: elftoolchain.prog.mk 2985 2014-03-06 03:24:35Z jkoshy $ +# $Id: elftoolchain.prog.mk 3352 2016-01-18 21:50:10Z jkoshy $ .if !defined(TOP) .error Make variable \"TOP\" has not been defined. @@ -36,6 +36,18 @@ _LDADD_LIBELFTC=${LDADD:M-lelftc} CFLAGS+= -I${TOP}/libelftc LDFLAGS+= -L${TOP}/libelftc .endif + +_LDADD_LIBPE=${LDADD:M-lpe} +.if !empty(_LDADD_LIBPE) +CFLAGS+= -I${TOP}/libpe +LDFLAGS+= -L${TOP}/libpe +.endif +.endif + +_LDADD_LIBARCHIVE=${LDADD:M-larchive} +.if !empty(_LDADD_LIBARCHIVE) && ${OS_HOST} == NetBSD +CFLAGS+= -I/usr/pkg/include +LDFLAGS+= -L/usr/pkg/lib .endif # diff --git a/nm/os.NetBSD.mk b/nm/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/nm/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/readelf/os.NetBSD.mk b/readelf/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/readelf/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/readelf/readelf.c b/readelf/readelf.c index 3b4b2d3c56b0..a8f5dd975382 100644 --- a/readelf/readelf.c +++ b/readelf/readelf.c @@ -47,7 +47,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: readelf.c 3271 2015-12-11 18:53:08Z kaiwang27 $"); +ELFTC_VCSID("$Id: readelf.c 3395 2016-02-10 16:29:44Z emaste $"); /* * readelf(1) options. @@ -338,7 +338,7 @@ static const char *phdr_type(unsigned int ptype); static const char *ppc_abi_fp(uint64_t fp); static const char *ppc_abi_vector(uint64_t vec); static const char *r_type(unsigned int mach, unsigned int type); -static void readelf_usage(void); +static void readelf_usage(int status); static void readelf_version(void); static void search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc); @@ -348,7 +348,7 @@ static void set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, Dwarf_Half ver); static const char *st_bind(unsigned int sbind); static const char *st_shndx(unsigned int shndx); -static const char *st_type(unsigned int stype); +static const char *st_type(unsigned int mach, unsigned int stype); static const char *st_vis(unsigned int svis); static const char *top_tag(unsigned int tag); static void unload_sections(struct readelf *re); @@ -958,6 +958,7 @@ st_bind(unsigned int sbind) case STB_LOCAL: return "LOCAL"; case STB_GLOBAL: return "GLOBAL"; case STB_WEAK: return "WEAK"; + case STB_GNU_UNIQUE: return "UNIQUE"; default: if (sbind >= STB_LOOS && sbind <= STB_HIOS) return "OS"; @@ -971,7 +972,7 @@ st_bind(unsigned int sbind) } static const char * -st_type(unsigned int stype) +st_type(unsigned int mach, unsigned int stype) { static char s_stype[32]; @@ -987,10 +988,12 @@ st_type(unsigned int stype) if (stype >= STT_LOOS && stype <= STT_HIOS) snprintf(s_stype, sizeof(s_stype), "OS+%#x", stype - STT_LOOS); - else if (stype >= STT_LOPROC && stype <= STT_HIPROC) + else if (stype >= STT_LOPROC && stype <= STT_HIPROC) { + if (mach == EM_SPARCV9 && stype == STT_SPARC_REGISTER) + return "REGISTER"; snprintf(s_stype, sizeof(s_stype), "PROC+%#x", stype - STT_LOPROC); - else + } else snprintf(s_stype, sizeof(s_stype), "", stype); return (s_stype); @@ -1053,8 +1056,9 @@ static struct { static const char * r_type(unsigned int mach, unsigned int type) { + static char s_type[32]; + switch(mach) { - case EM_NONE: return ""; case EM_386: case EM_IAMCU: switch(type) { @@ -1065,7 +1069,7 @@ r_type(unsigned int mach, unsigned int type) case 4: return "R_386_PLT32"; case 5: return "R_386_COPY"; case 6: return "R_386_GLOB_DAT"; - case 7: return "R_386_JMP_SLOT"; + case 7: return "R_386_JUMP_SLOT"; case 8: return "R_386_RELATIVE"; case 9: return "R_386_GOTOFF"; case 10: return "R_386_GOTPC"; @@ -1089,8 +1093,8 @@ r_type(unsigned int mach, unsigned int type) case 35: return "R_386_TLS_DTPMOD32"; case 36: return "R_386_TLS_DTPOFF32"; case 37: return "R_386_TLS_TPOFF32"; - default: return ""; } + break; case EM_AARCH64: switch(type) { case 0: return "R_AARCH64_NONE"; @@ -1145,6 +1149,16 @@ r_type(unsigned int mach, unsigned int type) case 311: return "R_AARCH64_ADR_GOT_PAGE"; case 312: return "R_AARCH64_LD64_GOT_LO12_NC"; case 313: return "R_AARCH64_LD64_GOTPAGE_LO15"; + case 560: return "R_AARCH64_TLSDESC_LD_PREL19"; + case 561: return "R_AARCH64_TLSDESC_ADR_PREL21"; + case 562: return "R_AARCH64_TLSDESC_ADR_PAGE21"; + case 563: return "R_AARCH64_TLSDESC_LD64_LO12"; + case 564: return "R_AARCH64_TLSDESC_ADD_LO12"; + case 565: return "R_AARCH64_TLSDESC_OFF_G1"; + case 566: return "R_AARCH64_TLSDESC_OFF_G0_NC"; + case 567: return "R_AARCH64_TLSDESC_LDR"; + case 568: return "R_AARCH64_TLSDESC_ADD"; + case 569: return "R_AARCH64_TLSDESC_CALL"; case 1024: return "R_AARCH64_COPY"; case 1025: return "R_AARCH64_GLOB_DAT"; case 1026: return "R_AARCH64_JUMP_SLOT"; @@ -1154,8 +1168,8 @@ r_type(unsigned int mach, unsigned int type) case 1030: return "R_AARCH64_TLS_TPREL64"; case 1031: return "R_AARCH64_TLSDESC"; case 1032: return "R_AARCH64_IRELATIVE"; - default: return ""; } + break; case EM_ARM: switch(type) { case 0: return "R_ARM_NONE"; @@ -1206,8 +1220,8 @@ r_type(unsigned int mach, unsigned int type) case 253: return "R_ARM_RABS32"; case 254: return "R_ARM_RPC24"; case 255: return "R_ARM_RBASE"; - default: return ""; } + break; case EM_IA_64: switch(type) { case 0: return "R_IA_64_NONE"; @@ -1290,8 +1304,8 @@ r_type(unsigned int mach, unsigned int type) case 182: return "R_IA_64_DTPREL64MSB"; case 183: return "R_IA_64_DTPREL64LSB"; case 186: return "R_IA_64_LTOFF_DTPREL22"; - default: return ""; } + break; case EM_MIPS: switch(type) { case 0: return "R_MIPS_NONE"; @@ -1324,9 +1338,8 @@ r_type(unsigned int mach, unsigned int type) case 48: return "R_MIPS_TLS_TPREL64"; case 49: return "R_MIPS_TLS_TPREL_HI16"; case 50: return "R_MIPS_TLS_TPREL_LO16"; - - default: return ""; } + break; case EM_PPC: switch(type) { case 0: return "R_PPC_NONE"; @@ -1406,8 +1419,8 @@ r_type(unsigned int mach, unsigned int type) case 114: return "R_PPC_EMB_RELST_HA"; case 115: return "R_PPC_EMB_BIT_FLD"; case 116: return "R_PPC_EMB_RELSDA"; - default: return ""; } + break; case EM_RISCV: switch(type) { case 0: return "R_RISCV_NONE"; @@ -1453,6 +1466,7 @@ r_type(unsigned int mach, unsigned int type) case 44: return "R_RISCV_RVC_BRANCH"; case 45: return "R_RISCV_RVC_JUMP"; } + break; case EM_SPARC: case EM_SPARCV9: switch(type) { @@ -1536,8 +1550,8 @@ r_type(unsigned int mach, unsigned int type) case 77: return "R_SPARC_TLS_DTPOFF64"; case 78: return "R_SPARC_TLS_TPOFF32"; case 79: return "R_SPARC_TLS_TPOFF64"; - default: return ""; } + break; case EM_X86_64: switch(type) { case 0: return "R_X86_64_NONE"; @@ -1547,7 +1561,7 @@ r_type(unsigned int mach, unsigned int type) case 4: return "R_X86_64_PLT32"; case 5: return "R_X86_64_COPY"; case 6: return "R_X86_64_GLOB_DAT"; - case 7: return "R_X86_64_JMP_SLOT"; + case 7: return "R_X86_64_JUMP_SLOT"; case 8: return "R_X86_64_RELATIVE"; case 9: return "R_X86_64_GOTPCREL"; case 10: return "R_X86_64_32"; @@ -1578,10 +1592,12 @@ r_type(unsigned int mach, unsigned int type) case 35: return "R_X86_64_TLSDESC_CALL"; case 36: return "R_X86_64_TLSDESC"; case 37: return "R_X86_64_IRELATIVE"; - default: return ""; } - default: return ""; + break; } + + snprintf(s_type, sizeof(s_type), "", type); + return (s_type); } static const char * @@ -3452,9 +3468,10 @@ dump_symtab(struct readelf *re, int i) continue; } printf("%6d:", j); - printf(" %16.16jx", (uintmax_t)sym.st_value); - printf(" %5ju", sym.st_size); - printf(" %-7s", st_type(GELF_ST_TYPE(sym.st_info))); + printf(" %16.16jx", (uintmax_t) sym.st_value); + printf(" %5ju", (uintmax_t) sym.st_size); + printf(" %-7s", st_type(re->ehdr.e_machine, + GELF_ST_TYPE(sym.st_info))); printf(" %-6s", st_bind(GELF_ST_BIND(sym.st_info))); printf(" %-8s", st_vis(GELF_ST_VISIBILITY(sym.st_other))); printf(" %3s", st_shndx(sym.st_shndx)); @@ -4287,7 +4304,7 @@ dump_compatibility_tag(uint8_t *p, uint8_t *pe) uint64_t val; val = _decode_uleb128(&p, pe); - printf("flag = %ju, vendor = %s\n", val, p); + printf("flag = %ju, vendor = %s\n", (uintmax_t) val, p); p += strlen((char *) p) + 1; return (p); @@ -4811,6 +4828,7 @@ dump_dwarf_line(struct readelf *re) } endoff = offset + length; + pe = (uint8_t *) d->d_buf + endoff; version = re->dw_read(d, &offset, 2); hdrlen = re->dw_read(d, &offset, dwarf_size); minlen = re->dw_read(d, &offset, 1); @@ -4876,7 +4894,6 @@ dump_dwarf_line(struct readelf *re) #define ADDRESS(x) ((((x) - opbase) / lrange) * minlen) p++; - pe = (uint8_t *) d->d_buf + endoff; printf("\n"); printf(" Line Number Statements:\n"); @@ -4981,7 +4998,8 @@ dump_dwarf_line(struct readelf *re) break; case DW_LNS_set_isa: isa = _decode_uleb128(&p, pe); - printf(" Set isa to %ju\n", isa); + printf(" Set isa to %ju\n", + (uintmax_t) isa); break; default: /* Unrecognized extended opcodes. */ @@ -5733,12 +5751,12 @@ dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base) } if (re->ec == ELFCLASS32) printf("%08jx %08jx\n", - ranges[j].dwr_addr1 + base0, - ranges[j].dwr_addr2 + base0); + (uintmax_t) (ranges[j].dwr_addr1 + base0), + (uintmax_t) (ranges[j].dwr_addr2 + base0)); else printf("%016jx %016jx\n", - ranges[j].dwr_addr1 + base0, - ranges[j].dwr_addr2 + base0); + (uintmax_t) (ranges[j].dwr_addr1 + base0), + (uintmax_t) (ranges[j].dwr_addr2 + base0)); } } @@ -6712,7 +6730,7 @@ dump_dwarf_loclist(struct readelf *re) set_cu_context(re, la->la_cu_psize, la->la_cu_osize, la->la_cu_ver); for (i = 0; i < lcnt; i++) { - printf(" %8.8jx ", la->la_off); + printf(" %8.8jx ", (uintmax_t) la->la_off); if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) { printf("\n"); continue; @@ -6834,13 +6852,15 @@ hex_dump(struct readelf *re) if (find_dumpop(re, (size_t) i, s->name, HEX_DUMP, -1) == NULL) continue; (void) elf_errno(); - if ((d = elf_getdata(s->scn, NULL)) == NULL) { + if ((d = elf_getdata(s->scn, NULL)) == NULL && + (d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } + (void) elf_errno(); if (d->d_size <= 0 || d->d_buf == NULL) { printf("\nSection '%s' has no data to dump.\n", s->name); @@ -6889,13 +6909,15 @@ str_dump(struct readelf *re) if (find_dumpop(re, (size_t) i, s->name, STR_DUMP, -1) == NULL) continue; (void) elf_errno(); - if ((d = elf_getdata(s->scn, NULL)) == NULL) { + if ((d = elf_getdata(s->scn, NULL)) == NULL && + (d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } + (void) elf_errno(); if (d->d_size <= 0 || d->d_buf == NULL) { printf("\nSection '%s' has no data to dump.\n", s->name); @@ -7354,10 +7376,13 @@ _read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ case 1: ret |= src[0]; break; @@ -7417,10 +7442,13 @@ _decode_lsb(uint8_t **data, int bytes_to_read) case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; + /* FALLTHROUGH */ case 1: ret |= src[0]; break; @@ -7473,7 +7501,7 @@ static int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe) { int64_t ret = 0; - uint8_t b; + uint8_t b = 0; int shift = 0; uint8_t *src = *dp; @@ -7542,6 +7570,10 @@ Usage: %s [options] file...\n\ -s | --syms | --symbols Print symbol tables.\n\ -t | --section-details Print additional information about sections.\n\ -v | --version Print a version identifier and exit.\n\ + -w[afilmoprsFLR] | --debug-dump={abbrev,aranges,decodedline,frames,\n\ + frames-interp,info,loc,macro,pubnames,\n\ + ranges,Ranges,rawline,str}\n\ + Display DWARF information.\n\ -x INDEX | --hex-dump=INDEX\n\ Display contents of a section as hexadecimal.\n\ -A | --arch-specific (accepted, but ignored)\n\ @@ -7558,10 +7590,10 @@ Usage: %s [options] file...\n\ static void -readelf_usage(void) +readelf_usage(int status) { fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); - exit(EXIT_FAILURE); + exit(status); } int @@ -7580,7 +7612,7 @@ main(int argc, char **argv) longopts, NULL)) != -1) { switch(opt) { case '?': - readelf_usage(); + readelf_usage(EXIT_SUCCESS); break; case 'A': re->options |= RE_AA; @@ -7605,7 +7637,7 @@ main(int argc, char **argv) re->options |= RE_G; break; case 'H': - readelf_usage(); + readelf_usage(EXIT_SUCCESS); break; case 'h': re->options |= RE_H; @@ -7683,7 +7715,7 @@ main(int argc, char **argv) argc -= optind; if (argc == 0 || re->options == 0) - readelf_usage(); + readelf_usage(EXIT_FAILURE); if (argc > 1) re->flags |= DISPLAY_FILENAME; diff --git a/size/os.NetBSD.mk b/size/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/size/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/strings/os.NetBSD.mk b/strings/os.NetBSD.mk new file mode 100644 index 000000000000..ae214e3115c0 --- /dev/null +++ b/strings/os.NetBSD.mk @@ -0,0 +1,2 @@ +# TODO(#511): Revert after the source tree is -Wconversion clean. +WARNS=5 diff --git a/strings/strings.1 b/strings/strings.1 index 15ad7a7f1eb3..205afdfc4505 100644 --- a/strings/strings.1 +++ b/strings/strings.1 @@ -22,9 +22,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: strings.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: strings.1 3360 2016-01-24 18:34:06Z jkoshy $ .\" -.Dd December 19, 2011 +.Dd January 24, 2016 .Dt STRINGS 1 .Os .Sh NAME @@ -100,6 +100,9 @@ Print a usage summary and exit. Print the contiguous character sequence of at least .Ar number characters long, instead of the default of 4 characters. +Argument +.Ar number +should specify a positive decimal integer. .It Fl o Equivalent to specifying .Fl t Ar o . diff --git a/strings/strings.c b/strings/strings.c index 6eab165e0bf4..f122eba34393 100644 --- a/strings/strings.c +++ b/strings/strings.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: strings.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: strings.c 3360 2016-01-24 18:34:06Z jkoshy $"); enum return_code { RETURN_OK, @@ -73,10 +74,10 @@ enum encoding_style { ((c) == '\t' || isprint((c)) || \ (encoding == ENCODING_8BIT && (c) > 127))) - -static int encoding_size, entire_file, min_len, show_filename, show_loc; +static int encoding_size, entire_file, show_filename, show_loc; static enum encoding_style encoding; static enum radix_style radix; +static intmax_t min_len; static struct option strings_longopts[] = { { "all", no_argument, NULL, 'a'}, @@ -144,7 +145,10 @@ main(int argc, char **argv) show_filename = 1; break; case 'n': - min_len = (int)strtoimax(optarg, (char**)NULL, 10); + min_len = strtoimax(optarg, (char**)NULL, 10); + if (min_len <= 0) + errx(EX_USAGE, "option -n should specify a " + "positive decimal integer."); break; case 'o': show_loc = 1; diff --git a/test/ar/plugin/Makefile b/test/ar/plugin/Makefile index f9644aea89f0..5585ec736634 100644 --- a/test/ar/plugin/Makefile +++ b/test/ar/plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 3192 2015-05-04 17:20:15Z jkoshy $ +# $Id: Makefile 3380 2016-01-29 07:53:10Z jkoshy $ PLUGINS= ardiff teraser @@ -11,7 +11,7 @@ ${PLUGINS}: test: .PHONY -clean cleandepend depend: .PHONY +clean cleandepend clobber depend: .PHONY .for plugin in ${PLUGINS} ${MAKE} -f Makefile.${plugin} ${.TARGET} .endfor diff --git a/test/ar/plugin/ardiff.c b/test/ar/plugin/ardiff.c index 907d1ea80da9..84048c632116 100644 --- a/test/ar/plugin/ardiff.c +++ b/test/ar/plugin/ardiff.c @@ -12,7 +12,7 @@ * By default, it compares nothing and consider the test "not ok" * iff it encounters errors while reading archive. * - * $Id: ardiff.c 3102 2014-10-29 21:09:01Z jkoshy $ + * $Id: ardiff.c 3364 2016-01-24 21:23:17Z jkoshy $ */ #include @@ -48,10 +48,9 @@ main(int argc, char **argv) char checksize; char checktime; char a1end; - ssize_t size1; - ssize_t size2; - char opt; - int r; + size_t size1; + size_t size2; + int opt, r; /* * Parse command line options. @@ -170,8 +169,8 @@ main(int argc, char **argv) * Compare member size if required. */ if (checksize || checkcont) { - size1 = archive_entry_size(e1); - size2 = archive_entry_size(e2); + size1 = (size_t) archive_entry_size(e1); + size2 = (size_t) archive_entry_size(e2); if (size1 != size2) filediff(tc, "member size differ", archive_entry_pathname(e1)); @@ -185,10 +184,12 @@ main(int argc, char **argv) filediff(tc, "not enough memory", NULL); if ((buf2 = malloc(size2)) == NULL) filediff(tc, "not enough memory", NULL); - if (archive_read_data(a1, buf1, size1) != size1) + if ((size_t) archive_read_data(a1, buf1, size1) != + size1) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); - if (archive_read_data(a2, buf2, size2) != size2) + if ((size_t) archive_read_data(a2, buf2, size2) != + size2) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); if (memcmp(buf1, buf2, size1) != 0) diff --git a/test/ar/plugin/teraser.c b/test/ar/plugin/teraser.c index d16752e7cefb..5fa08a0df540 100644 --- a/test/ar/plugin/teraser.c +++ b/test/ar/plugin/teraser.c @@ -2,7 +2,7 @@ * make it easy to `diff'. (option -e) * 2. Check the sanity of timestamp. (option -c) * - * $Id: teraser.c 3102 2014-10-29 21:09:01Z jkoshy $ + * $Id: teraser.c 3365 2016-01-24 21:26:46Z jkoshy $ */ #include @@ -25,14 +25,14 @@ static void usage(void); int main(int argc, char **argv) { - char opt; + int opt; char checktime; char erasetime; char buf[TSLEN + 1]; char *tc; int fd; int ts; - int now; + time_t now; FILE *ct, *ps; diff --git a/test/ar/tc/usage-bi/usage-bi.err b/test/ar/tc/usage-bi/usage-bi.err index b509d6c75712..99721eb4e035 100644 --- a/test/ar/tc/usage-bi/usage-bi.err +++ b/test/ar/tc/usage-bi/usage-bi.err @@ -30,3 +30,4 @@ Usage: ar [options] archive file... -F FORMAT | --flavor=FORMAT Create archives with the specified format. -S Do not generate an archive symbol table. + -U Use original metadata for archive members. diff --git a/test/elfcopy/plugin/Makefile b/test/elfcopy/plugin/Makefile index f9644aea89f0..5585ec736634 100644 --- a/test/elfcopy/plugin/Makefile +++ b/test/elfcopy/plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 3192 2015-05-04 17:20:15Z jkoshy $ +# $Id: Makefile 3380 2016-01-29 07:53:10Z jkoshy $ PLUGINS= ardiff teraser @@ -11,7 +11,7 @@ ${PLUGINS}: test: .PHONY -clean cleandepend depend: .PHONY +clean cleandepend clobber depend: .PHONY .for plugin in ${PLUGINS} ${MAKE} -f Makefile.${plugin} ${.TARGET} .endfor diff --git a/test/elfcopy/plugin/ardiff.c b/test/elfcopy/plugin/ardiff.c index 907d1ea80da9..0f2c0dde73c6 100644 --- a/test/elfcopy/plugin/ardiff.c +++ b/test/elfcopy/plugin/ardiff.c @@ -12,7 +12,7 @@ * By default, it compares nothing and consider the test "not ok" * iff it encounters errors while reading archive. * - * $Id: ardiff.c 3102 2014-10-29 21:09:01Z jkoshy $ + * $Id: ardiff.c 3366 2016-01-24 21:33:06Z jkoshy $ */ #include @@ -48,10 +48,9 @@ main(int argc, char **argv) char checksize; char checktime; char a1end; - ssize_t size1; - ssize_t size2; - char opt; - int r; + size_t size1; + size_t size2; + int opt, r; /* * Parse command line options. @@ -170,8 +169,8 @@ main(int argc, char **argv) * Compare member size if required. */ if (checksize || checkcont) { - size1 = archive_entry_size(e1); - size2 = archive_entry_size(e2); + size1 = (size_t) archive_entry_size(e1); + size2 = (size_t) archive_entry_size(e2); if (size1 != size2) filediff(tc, "member size differ", archive_entry_pathname(e1)); @@ -185,10 +184,12 @@ main(int argc, char **argv) filediff(tc, "not enough memory", NULL); if ((buf2 = malloc(size2)) == NULL) filediff(tc, "not enough memory", NULL); - if (archive_read_data(a1, buf1, size1) != size1) + if ((size_t) archive_read_data(a1, buf1, size1) != + size1) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); - if (archive_read_data(a2, buf2, size2) != size2) + if ((size_t) archive_read_data(a2, buf2, size2) != + size2) filediff(tc, "archive_read_data failed", archive_entry_pathname(e1)); if (memcmp(buf1, buf2, size1) != 0) diff --git a/test/elfcopy/plugin/teraser.c b/test/elfcopy/plugin/teraser.c index 0deb7cc90630..b29d44d5597e 100644 --- a/test/elfcopy/plugin/teraser.c +++ b/test/elfcopy/plugin/teraser.c @@ -2,7 +2,7 @@ * make it easy to `diff'. (option -e) * 2. Check the sanity of timestamp. (option -c) * - * $Id: teraser.c 3102 2014-10-29 21:09:01Z jkoshy $ + * $Id: teraser.c 3366 2016-01-24 21:33:06Z jkoshy $ */ #include @@ -25,14 +25,14 @@ static void usage(void); int main(int argc, char **argv) { - char opt; + int opt; char checktime; char erasetime; char buf[TSLEN + 1]; char *tc; int fd; int ts; - int now; + time_t now; FILE *ct, *ps; diff --git a/test/elfcopy/tc/elfcopy-L-1/out/elfcopy-L-1.out.shar b/test/elfcopy/tc/elfcopy-L-1/out/elfcopy-L-1.out.shar index 67ee9364d478..6d136d031c56 100644 --- a/test/elfcopy/tc/elfcopy-L-1/out/elfcopy-L-1.out.shar +++ b/test/elfcopy/tc/elfcopy-L-1/out/elfcopy-L-1.out.shar @@ -11,23 +11,23 @@ echo x - sym.o.1.uu sed 's/^X//' >sym.o.1.uu << 'cc3b7341ff25eb16b80756fcb867a66b' Xbegin 644 sym.o.1 -XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````"4`0```````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I XM(#0N,BXQ(#(P,#6UT86(`+G-Ta.out.1.uu << 'f933ed5eb3f7f89e0de47764c538d3cb' -Xbegin 755 a.out.1 -XM?T5,1@(!`0D```````````(`/@`!````L`1```````!``````````'@+```` +Xbegin 644 a.out.1 +XM?T5,1@(!`0D```````````(`/@`!````L`1```````!```````````@4```` XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` @@ -76,100 +76,100 @@ XM=')T86(`+FEN=&5R<``N;F]T92Y!0DDM=&%G`"YH87-H`"YD>6YS>6T`+F1Y XM;G-T<@`N9VYU+G9E``````````$````"@````@`````````&``````` -XM``!M`````0````8`````````.`1````````X!````````!,````````````` -XM```````$````````````````````:`````$````&`````````$P$0``````` -XM3`0```````!@````````````````````!``````````0`````````',````! -XM````!@````````"P!$```````+`$````````:`$``````````````````!`` -XM``````````````````!Y`````0````8`````````&`9````````8!@`````` -XM``X````````````````````$````````````````````?P````$````"```` -XM`````"8&0```````)@8```````"E`````````````````````0`````````` -XM`````````(<````!`````@````````#,!D```````,P&````````"``````` -XM``````````````0```````````````````"5`````0````,`````````V`90 -XM``````#8!@```````!@````````````````````(```````````````````` -XMFP````$````"`````````/`&4```````\`8```````#````````````````` -XM````"````````````````````*4````&`````P````````"P!U```````+`' -XM````````8`$````````%``````````@`````````$`````````"N`````0`` -XM``,`````````$`E0```````0"0```````!`````````````````````(```` -XM````````````````M0````$````#`````````"`)4```````(`D````````0 -XM````````````````````"````````````````````+P````!`````P`````` -XM```P"5```````#`)````````"`````````````````````@````````````` -XM``````#!`````0````,`````````.`E0```````X"0```````$`````````` -XM```````````(``````````@`````````Q@````@````#`````````'@)4``` -XM````>`D````````0````````````````````"````````````````````,L` -XM```!`````````````````````````'@)````````+`$````````````````` -XM``$````````````````````1`````P````````````````````````"D"@`` -XM`````-0````````````````````!`````````````````````0````(````` -XM````````````````````.!(```````"0!@```````!H````U````"``````` -XM```8``````````D````#`````````````````````````,@8````````^0$` -XM``````````````````$````````````````````````````````````````` -XM`````````````````P`!`,@!0````````````````````````P`"`.`!0``` -XM`````````````````````P`#`/@!0````````````````````````P`$`#@" -XM0````````````````````````P`%`"@#0````````````````````````P`& -XM`(8#0````````````````````````P`'`*`#0``````````````````````` -XM`P`(`,`#0````````````````````````P`)`#@$0``````````````````` -XM`````P`*`$P$0````````````````````````P`+`+`$0``````````````` -XM`````````P`,`!@&0````````````````````````P`-`"8&0``````````` -XM`````````````P`.`,P&0````````````````````````P`/`-@&4``````` -XM`````````````````P`0`/`&4````````````````````````P`1`+`'4``` -XM`````````````````````P`2`!`)4````````````````````````P`3`"`) -XM4````````````````````````P`4`#`)4````````````````````````P`5 -XM`#@)4````````````````````````P`6`'@)4``````````````````````` -XM`P`7`````````````````````````````P`8```````````````````````` -XM`````P`9`````````````````````````````P`:```````````````````` -XM```!````!`#Q_P`````````````````````(`````0`"`.`!0```````&``` -XM```````/````!`#Q_P`````````````````````M````!`#Q_P`````````` -XM```````````\````!`#Q_P`````````````````````/````!`#Q_P`````` -XM``````````````!'````!`#Q_P````````````````````!2`````0`2`!`) -XM4`````````````````!@`````0`3`"`)4`````````````````!N`````0`4 -XM`#`)4`````````````````![`````@`+`%`%0`````````````````"1```` -XM`0`6`'@)4````````0````````"@`````0`/`.@&4`````````````````"G -XM`````@`+`)`%0`````````````````!'````!`#Q_P`````````````````` -XM``"S`````0`2`!@)4`````````````````#``````0`3`"@)4``````````` -XM``````#-`````0`0`'@'4`````````````````#;`````0`4`#`)4``````` -XM``````````#G`````@`+`/`%0`````````````````#]````!`#Q_P`````` +XM`E0``````!X"0```````!`` +XM```````````````````(````````````````````RP````$````````````` +XM````````````>`D````````L`0```````````````````0`````````````` +XM`````!$````#`````````````````````````*0*````````U``````````` +XM``````````$````````````````````!`````@`````````````````````` +XM``!X"P```````)`&````````&@```#4````(`````````!@`````````"0`` +XM``,`````````````````````````"!(```````#Y`0`````````````````` +X0`0`````````````````````` X` Xend f933ed5eb3f7f89e0de47764c538d3cb echo x - a.out.uu sed 's/^X//' >a.out.uu << 'debc64a5f6aece67b22914f9f4be2988' -Xbegin 755 a.out +Xbegin 644 a.out XM?T5,1@(!`0D```````````(`/@`!````L`1```````!``````````'@+```` XM`````````$``.``'`$``&P`8``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` diff --git a/test/elfcopy/tc/elfcopy-N-1/out/elfcopy-N-1.out.shar b/test/elfcopy/tc/elfcopy-N-1/out/elfcopy-N-1.out.shar index 52ec049e7aaf..2098237cbc9c 100644 --- a/test/elfcopy/tc/elfcopy-N-1/out/elfcopy-N-1.out.shar +++ b/test/elfcopy/tc/elfcopy-N-1/out/elfcopy-N-1.out.shar @@ -9,29 +9,29 @@ # sym.o.uu # echo x - sym.o.1.uu -sed 's/^X//' >sym.o.1.uu << 'END-of-sym.o.1.uu' +sed 's/^X//' >sym.o.1.uu << 'cc3b7341ff25eb16b80756fcb867a66b' Xbegin 644 sym.o.1 -XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````"``0```````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I XM(#0N,BXQ(#(P,#6UT86(`+G-Tsym.o.uu << 'END-of-sym.o.uu' +sed 's/^X//' >sym.o.uu << '07b26866a0eaf5d2a40d8f75b1109c67' Xbegin 644 sym.o XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# @@ -52,6 +52,6 @@ XM`!(``0`5````,`````H````2``$``'1Edup.o.1.uu << 'END-of-dup.o.1.uu' +sed 's/^X//' >dup.o.1.uu << 'f11d3ae31690547dd28efbfd6006f908' Xbegin 644 dup.o.1 -XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````"$`0```````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I XM(#0N,BXQ(#(P,#6UT86(`+G-T%]F;V\`9F]O`&)A<@`` +XM``````````$```````````````0`\?\````````````````#``$````````` +XM`````````P`"``````````````````,``P`````````````````#``0`"``` +XM```````*````$@`!`!,````@````"@```!(``0`7````,`````H````2``$` +XM`'1Edup.o.uu << 'END-of-dup.o.uu' +sed 's/^X//' >dup.o.uu << 'b473e23605eb82e8423dd39bf18cc444' Xbegin 644 dup.o XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# @@ -52,6 +52,6 @@ XM`!(``0`<````,`````H````2``$``'1Epkill.new.uu << 'END-of-pkill.new.uu' -Xbegin 755 pkill.new -XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```#T+@```````#0`(``& +sed 's/^X//' >pkill.new.uu << '672fadc176202ece55dbb7d4b04d86b9' +Xbegin 644 pkill.new +XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```"\/@```````#0`(``& XM`"@`&P`8``8````T````-(`$"#2`!`C`````P`````4````$`````P```/0` XM``#T@`0(](`$"!4````5````!`````$````!``````````"`!`@`@`0(YBH` XM`.8J```%`````!````$```#H*@``Z+H$".BZ!`C$`0``R`(```8`````$``` @@ -278,31 +278,7 @@ XM=&%B`"YI;G1E6YS XM='(`+F=N=2YV97)S:6]N`"YG;G4N=F5R6YA;6EC`"YC=&]R`$``````````````0`````````1`````P``````````````)"X``,X````` -XM``````````$``````````0````(``````````````"PS``!@"0``&@```%(` -XM```$````$`````D````#``````````````",/```9@8``````````````0`` -XM`````````````````````````````````/2`!`@``````P`!```````,@00( +XM;G0``````````````````````````````/2`!`@``````P`!```````,@00( XM``````,``@``````)($$"``````#``,``````,B"!`@``````P`$``````#H XMA@0(``````,`!0``````+HD$"``````#``8``````+2)!`@``````P`'```` XM``#4B00(``````,`"```````'(H$"``````#``D``````(R+!`@``````P`* @@ -391,13 +367,37 @@ XM<$!`1D)31%\Q+C``;W!T:6YD0$!&0E-$7S$N,`!?7W-R9V5T0$!&0E-$7S$N XM,`!R96=C;VUP0$!&0E-$7S$N,`!A=&5X:71`0$9"4T1?,2XP`&=E='!I9$!` XM1D)31%\Q+C``pkill.uu << 'END-of-pkill.uu' -Xbegin 755 pkill +sed 's/^X//' >pkill.uu << '521a9e5ac40550eee504b066258ae35d' +Xbegin 644 pkill XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```#T+@```````#0`(``& XM`"@`&P`8``8````T````-(`$"#2`!`C`````P`````4````$`````P```/0` XM``#T@`0(](`$"!4````5````!`````$````!``````````"`!`@`@`0(YBH` @@ -781,6 +781,6 @@ XMls.new.uu << 'END-of-ls.new.uu' -Xbegin 755 ls.new +sed 's/^X//' >ls.new.uu << '546f75a0f05440808208cba22c526606' +Xbegin 644 ls.new XM?T5,1@$!`0D```````````(``P`!````D),$"#0```!T7@```````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(<%@` @@ -555,8 +555,8 @@ XM(0````4````"````1($$"$0!``!H`@``!``````````$````!````"<````+ XM`````@```*R#!`BL`P``4`4```4````!````!````!`````O`````P````(` XM``#\B`0(_`@```@#``````````````$`````````-P```/___V\"````!(P$ XM"`0,``"J````!``````````"`````@```$0```#^__]O`@```+",!`BP#``` -XM(`````4````!````!`````````!3````"0````(```#0C`0(T`P``#`````$ -XM``````````0````(````7`````D````"`````(T$"``-```@`@``!`````L` +XM(`````4````!````!`````````!3````"0```$(```#0C`0(T`P``#`````$ +XM``````````0````(````7`````D```!"`````(T$"``-```@`@``!`````L` XM```$````"````&4````!````!@```""/!`@@#P``$0``````````````!``` XM``````!@`````0````8````TCP0(-`\``%`$``````````````0````$```` XM:P````$````&````D),$")`3``!,0``````````````0`````````'$````! @@ -574,10 +574,10 @@ XM`.!:``#(`@`````````````!``````````$````#``````````````"H70`` X4S````````````````0`````````` X` Xend -END-of-ls.new.uu +546f75a0f05440808208cba22c526606 echo x - ls.uu -sed 's/^X//' >ls.uu << 'END-of-ls.uu' -Xbegin 755 ls +sed 's/^X//' >ls.uu << '4db11c737631d887608e3186a17a7a3e' +Xbegin 644 ls XM?T5,1@$!`0D```````````(``P`!````D),$"#0```!T7@```````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(<%@` @@ -1141,6 +1141,6 @@ XM`.!:``#(`@`````````````!``````````$````#``````````````"H70`` X4S````````````````0`````````` X` Xend -END-of-ls.uu +4db11c737631d887608e3186a17a7a3e exit diff --git a/test/elfcopy/tc/elfcopy-noops-3/out/elfcopy-noops-3.out.shar b/test/elfcopy/tc/elfcopy-noops-3/out/elfcopy-noops-3.out.shar index 40bc524b6440..43ace560bcec 100644 --- a/test/elfcopy/tc/elfcopy-noops-3/out/elfcopy-noops-3.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-3/out/elfcopy-noops-3.out.shar @@ -9,8 +9,8 @@ # ps.uu # echo x - ps.new.uu -sed 's/^X//' >ps.new.uu << 'END-of-ps.new.uu' -Xbegin 755 ps.new +sed 's/^X//' >ps.new.uu << 'cffb18ef50dd17690799ebccb9f304ef' +Xbegin 644 ps.new XM?T5,1@$!`0D```````````(``P`!````T)0$"#0````(>````````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(!&`` @@ -701,8 +701,8 @@ XM```$``````````0````$````)P````L````"````Q(,$",0#``"P!0``!0`` XM``$````$````$````"\````#`````@```'2)!`AT"0``+@,````````````` XM`0`````````W````____;P(```"BC`0(H@P``+8````$``````````(````" XM````1````/[__V\"````6(T$"%@-``!`````!0````(````$`````````%,` -XM```)`````@```)B-!`B8#0``,`````0`````````!`````@```!<````"0`` -XM``(```#(C00(R`T``$@"```$````"P````0````(````90````$````&```` +XM```)````0@```)B-!`B8#0``,`````0`````````!`````@```!<````"0`` +XM`$(```#(C00(R`T``$@"```$````"P````0````(````90````$````&```` XM$)`$"!`0```1```````````````$`````````&`````!````!@```"20!`@D XM$```H`0`````````````!`````0```!K`````0````8```#0E`0(T!0``%Q! XM`````````````!``````````<0````$````&````+-8$""Q6```,```````` @@ -719,10 +719,10 @@ XM"`````````##`````0``````````````V',``&,#``````````````$````` XK`````0````,``````````````#MW``#,```````````````!```````````` X` Xend -END-of-ps.new.uu +cffb18ef50dd17690799ebccb9f304ef echo x - ps.uu -sed 's/^X//' >ps.uu << 'END-of-ps.uu' -Xbegin 755 ps +sed 's/^X//' >ps.uu << '1d41113d6c473df8a15e4a4e0ea90bc3' +Xbegin 644 ps XM?T5,1@$!`0D```````````(``P`!````T)0$"#0````(>````````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(!&`` @@ -1431,6 +1431,6 @@ XM"`````````##`````0``````````````V',``&,#``````````````$````` XK`````0````,``````````````#MW``#,```````````````!```````````` X` Xend -END-of-ps.uu +1d41113d6c473df8a15e4a4e0ea90bc3 exit diff --git a/test/elfcopy/tc/elfcopy-noops-4/out/elfcopy-noops-4.out.shar b/test/elfcopy/tc/elfcopy-noops-4/out/elfcopy-noops-4.out.shar index 4ab2a51c2877..09672f7cb968 100644 --- a/test/elfcopy/tc/elfcopy-noops-4/out/elfcopy-noops-4.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-4/out/elfcopy-noops-4.out.shar @@ -9,8 +9,8 @@ # vi.uu # echo x - vi.new.uu -sed 's/^X//' >vi.new.uu << 'END-of-vi.new.uu' -Xbegin 755 vi.new +sed 's/^X//' >vi.new.uu << 'c6a212f79bb8cf302d242d299c785f85' +Xbegin 644 vi.new XM?T5,1@$!`0D```````````(``P`!````X*0$"#0````8IP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(@(\$ @@ -6794,8 +6794,8 @@ XM"$0!``"T!```!``````````$````!````"<````+`````@```/B%!`CX!0`` XM@`H```4````!````!````!`````O`````P````(```!XD`0(>!```-`$```` XM``````````$`````````-P```/___V\"````2)4$"$@5``!0`0``!``````` XM```"`````@```$0```#^__]O`@```)B6!`B8%@``(`````4````!````!``` -XM``````!3````"0````(```"XE@0(N!8``&`````$``````````0````(```` -XM7`````D````"````&)<$"!@7``"(!```!`````L````$````"````&4````! +XM``````!3````"0```$(```"XE@0(N!8``&`````$``````````0````(```` +XM7`````D```!"````&)<$"!@7``"(!```!`````L````$````"````&4````! XM````!@```*";!`B@&P``$0``````````````!`````````!@`````0````8` XM``"TFP0(M!L``"`)``````````````0````$````:P````$````&````X*0$ XM".`D```\Y0,````````````0`````````'$````!````!@```!R*"`@<"@0` @@ -6813,10 +6813,10 @@ XM```!``````````$````#``````````````!)I@0`S````````````````0`` X%```````` X` Xend -END-of-vi.new.uu +c6a212f79bb8cf302d242d299c785f85 echo x - vi.uu -sed 's/^X//' >vi.uu << 'END-of-vi.uu' -Xbegin 755 vi +sed 's/^X//' >vi.uu << '5f6cb34c34598fc980a32aede89eafe8' +Xbegin 644 vi XM?T5,1@$!`0D```````````(``P`!````X*0$"#0````8IP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(@(\$ @@ -13619,6 +13619,6 @@ XM```!``````````$````#``````````````!)I@0`S````````````````0`` X%```````` X` Xend -END-of-vi.uu +5f6cb34c34598fc980a32aede89eafe8 exit diff --git a/test/elfcopy/tc/elfcopy-noops-5/out/elfcopy-noops-5.out.shar b/test/elfcopy/tc/elfcopy-noops-5/out/elfcopy-noops-5.out.shar index e397a7620ae6..07731b10d3a3 100644 --- a/test/elfcopy/tc/elfcopy-noops-5/out/elfcopy-noops-5.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-5/out/elfcopy-noops-5.out.shar @@ -9,8 +9,8 @@ # tcsh.uu # echo x - tcsh.new.uu -sed 's/^X//' >tcsh.new.uu << 'END-of-tcsh.new.uu' -Xbegin 755 tcsh.new +sed 's/^X//' >tcsh.new.uu << '3ae563ac759cfb26a3b39b907ea0d291' +Xbegin 644 tcsh.new XM?T5,1@$!`0D```````````(``P`!````(*0$"#0```"HVP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(7)\$ @@ -7093,8 +7093,8 @@ XM!`A$`0``E`0```0`````````!`````0````G````"P````(```#8A00(V`4` XM```*```%`````0````0````0````+P````,````"````V(\$"-@/```X!0`` XM```````````!`````````#<```#___]O`@```!"5!`@0%0``0`$```0````` XM`````@````(```!$````_O__;P(```!0E@0(4!8``"`````%`````0````0` -XM````````4P````D````"````<)8$"'`6```@````!``````````$````"``` -XM`%P````)`````@```)"6!`B0%@``>`0```0````+````!`````@```!E```` +XM````````4P````D```!"````<)8$"'`6```@````!``````````$````"``` +XM`%P````)````0@```)"6!`B0%@``>`0```0````+````!`````@```!E```` XM`0````8````(FP0("!L``!$```````````````0`````````8`````$````& XM````')L$"!P;````"0`````````````$````!````&L````!````!@```""D XM!`@@)```W`P$````````````$`````````!Q`````0````8```#\L`@(_#`$ @@ -7112,10 +7112,10 @@ XM`````0`````````!`````P``````````````V=H$`,P```````````````$` X&```````` X` Xend -END-of-tcsh.new.uu +3ae563ac759cfb26a3b39b907ea0d291 echo x - tcsh.uu -sed 's/^X//' >tcsh.uu << 'END-of-tcsh.uu' -Xbegin 755 tcsh +sed 's/^X//' >tcsh.uu << 'e0b48b8aefb9960c9da54cac18bdcb01' +Xbegin 644 tcsh XM?T5,1@$!`0D```````````(``P`!````(*0$"#0```"HVP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(7)\$ @@ -14217,6 +14217,6 @@ XM`````0`````````!`````P``````````````V=H$`,P```````````````$` X&```````` X` Xend -END-of-tcsh.uu +e0b48b8aefb9960c9da54cac18bdcb01 exit diff --git a/test/elfcopy/tc/elfcopy-noops-6/out/elfcopy-noops-6.out.shar b/test/elfcopy/tc/elfcopy-noops-6/out/elfcopy-noops-6.out.shar index 4bf7a7a553d9..fca78bf34ab0 100644 --- a/test/elfcopy/tc/elfcopy-noops-6/out/elfcopy-noops-6.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-6/out/elfcopy-noops-6.out.shar @@ -9,9 +9,9 @@ # mcs.o.uu # echo x - mcs.o.1.uu -sed 's/^X//' >mcs.o.1.uu << 'END-of-mcs.o.1.uu' +sed 's/^X//' >mcs.o.1.uu << 'f795b6a491de52ced7008ed30e59ba9b' Xbegin 644 mcs.o.1 -XM?T5,1@$!`0D```````````$``P`!``````````````!\"0```````#0````` +XM?T5,1@$!`0D```````````$``P`!```````````````P#@```````#0````` XM`"@`"@`'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ XM,=*%P'0),=*#>"``#Y7"R8G0PXUV`%6)Y8/L&(E4)`3'1"0(`````(D$).C\ XM____,=*%P'0),=*#>!@`#Y7"R8G0PXUV`%6)Y8/L&,=$)`@`````B50D!(D$ @@ -65,47 +65,47 @@ XM;&]C(&9A:6QE9`!R96%L;&]C(&9A:6QE9``N6UT86(`+G-T``!4!P```A8``%P'```!"```;`<` -XM``(7``!T!P```0@``(`'```"'@``C`<```(6``"4!P```0@``*0'```"%P`` -XML`<```(6``"X!P```0@``,@'```"%P``T`<```(6``#8!P```0@``.@'```" -X;%P``\`<```(6``#X!P```0@```@(```"%P`` +XM```````````````````!```````````````$`/'_`````````````````P`! +XM``````````````````,``P`````````````````#``0`!P`````````M```` +XM`@`!`!@````P````+0````(``0`L````8````#8````"``$````````````` +XM`````P`&``````````````````,`!0`^```````````````0````30`````` +XM````````$````%<```"@````;`<``!(``0!D```````````````0````<``` +XM````````````$````'T``````````````!````")```````````````0```` +XMD```````````````$````)@``````````````!````"@```````````````0 +XM````IP``````````````$````*X``````````````!````"_```````````` +XM```0````R@``````````````$````,\``````````````!````#4```````` +XM```````0````W```````````````$````.D``````````````!````#T```` +XM```````````0````_@``````````````$`````\!`````````````!`````` +XM;6-S+F,`:7-?<')I;G1?'1S8VX`9V5L9E]G971S:&1R`&5L9E]G971D871A +XM`&UA;&QO8P!R96%L;&]C`'-T`!P=71S`'!U=&-H87(`9V5L9E]G +XM971E:&1R`&=E;&9?9G-I>F4`96QF7V5R``",!P```A8``)0'```!"```I`<` +XM``(7``"P!P```A8``+@'```!"```R`<```(7``#0!P```A8``-@'```!"``` +XMZ`<```(7``#P!P```A8``/@'```!"```"`@```(7```````````````````` +XM````````````````````````````````````'P````$````&`````````$`` +XM```,"``````````````0`````````!L````)````0`````````"`#```L`$` +XM``@````!````!`````@````E`````0````,`````````3`@````````````` +XM``````0`````````*P````@````#`````````$P(```````````````````$ +XM`````````#`````!``````````````!,"```,````````````````0`````` +XM```Y`````0```#(`````````?`@``+<```````````````$````!````$0`` +XM``,``````````````#,)``!(```````````````!``````````$````"```` +XM``````````!\"0``\`$```D````*````!````!`````)`````P`````````` +X;````;`L``!,!``````````````$````````` X` Xend -END-of-mcs.o.1.uu +f795b6a491de52ced7008ed30e59ba9b echo x - mcs.o.uu -sed 's/^X//' >mcs.o.uu << 'END-of-mcs.o.uu' +sed 's/^X//' >mcs.o.uu << '4890727b4c22736e61623154688c0ec6' Xbegin 644 mcs.o XM?T5,1@$!`0D```````````$``P`!``````````````!\"0```````#0````` XM`"@`"@`'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ @@ -199,6 +199,6 @@ XML`<```(6``"X!P```0@``,@'```"%P``T`<```(6``#8!P```0@``.@'```" X;%P``\`<```(6``#X!P```0@```@(```"%P`` X` Xend -END-of-mcs.o.uu +4890727b4c22736e61623154688c0ec6 exit diff --git a/test/elfcopy/tc/elfcopy-noops-7/out/elfcopy-noops-7.out.shar b/test/elfcopy/tc/elfcopy-noops-7/out/elfcopy-noops-7.out.shar index 6d711187a1e0..b936bcc3d407 100644 --- a/test/elfcopy/tc/elfcopy-noops-7/out/elfcopy-noops-7.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-7/out/elfcopy-noops-7.out.shar @@ -9,9 +9,9 @@ # sections.o.debug.uu # echo x - sections.o.debug.1.uu -sed 's/^X//' >sections.o.debug.1.uu << 'END-of-sections.o.debug.1.uu' +sed 's/^X//' >sections.o.debug.1.uu << '7441d94dfba58dda29235b0205ebc7b3' Xbegin 644 sections.o.debug.1 -XM?T5,1@$!`0D```````````$``P`!``````````````!86@```````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````"`=0```````#0````` XM`"@`&0`6`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R XM''<%.T$07```"````!<````(````!`````@```!>`````0`` -XM````````````"C@``#````````````````$`````````9P````$````R```` -XM`````#HX``":`@`````````````!`````0```'8````!````,@````````#4 -XM.@``+0``````````````!`````$```")`````0``````````````!#L``.0! -XM``````````````0`````````A0````D``````````````&!X``#P````%P`` -XM``T````$````"````)8````!``````````````#H/```&Q`````````````` -XM`0````````"E`````0```````````````TT``+L```````````````$````` -XM````H0````D``````````````%!Y```(````%P```!`````$````"````+D` -XM```!``````````````"^30``(````````````````0````````"U````"0`` -XM````````````6'D``!`````7````$@````0````(````R`````$````````` -XM`````-Y-``#(`@`````````````!`````````-8````!````,`````````"F -XM4```S@@``````````````0````$````1`````P``````````````=%D``.$` -XM``````````````$``````````0````(``````````````$!>```P!```&``` -XM`!8````$````$`````D````#``````````````!P8@``8`(````````````` -XM`0```````````````````````````````0``````````````!`#Q_P`````` -XM``````````,``0`````````````````#``,``````````````````P`$```` -XM``````````````,`!0`````````````````#``8``````````````````P`( -XM``P`````````=`````(``0`````````````````#``L`'P```(`#``!R```` -XM`@`!``````````````````,`#``O````,`P``"T````"``$`0P```&`,```V -XM`````@`!`%4```"@$```Z`````(``0`````````````````#``T````````` -XM`````````P`/``````````````````,`$``````````````````#`!(````` -XM`````````````P`4``````````````````,`%0`````````````````#``H` -XM8````(````#M`0``$@`!`&T``````````````!````!Z```````````````0 -XM````A@``````````````$````)<``````````````!````"B```````````` -XM```0````L@``````````````$````+H``````````````!````#%```````` -XM```````0````R@```'`"```,`0``$@`!`-8``````````````!````#D```` -XM```````````0````[@``````````````$````/\`````!````P(``!(``0`/ -XM`0`````````````0````&@$`````````````$````"$!`````````````!`` -XM```E`0``$`8``!8!```2``$`+P$`````````````$````#L!```P!P``.0$` -XM`!(``0!%`0`````````````0````3P$``'`(``#P`0``$@`!`%\!```````` -XM`````!````!E`0``8`H``"@!```2``$`<@$`````````````$````'\!```` -XM`````````!````"*`0``D`L``)<````2``$`F0$`````````````$````*`! -XM`````````````!````"G`0``H`P``/8#```2``$`L@$`````````````$``` -XM`,(!`````````````!````#4`0`````````````0````X`$````````````` -XM$````.L!`````````````!````#X`0`````````````0`````@(````````` -XM````$`````<"`````````````!`````/`@``D!$``%4'```2``$`'`(````` -XM````````$````"H"`````````````!`````Q`@`````````````0````.`(` -XM````````````$````$`"`````````````!````!,`@`````````````0```` -XM`'-E8W1I;VYS+F,`:6YS97)T7W1O7W-E8U]L:7-T`&%D9%]T;U]S:'-T5]S:&1R`%]?=61I=F1I,P!R97-Y;F-?'1S8VX`96QF7W-T```)`@```AT``!$"```!"0``(0(```(>```M`@```AT``#4"```!"0`` -XM10(```(>``!1`@```AT``%D"```!"0``:0(```(>``"1`@```A<``*8"```" -XM(```TP(```(:``#K`@```AD``/L"```"(0``'`,```(=```D`P```0D``#0# -XM```"'@``0`,```(=``!(`P```0D``%@#```"'@``8`,```(=``!H`P```0D` -XM`'@#```"'@``H`,```(B``"T`P```0D``+P#```"(@``Q`,```$)``#,`P`` -XM`B(``-0#```!"0``W`,```(B``#D`P```0D``.P#```"(@``)`0```$)``!* -XM!````B0``&@$```")0``PP0```(8```8!0```A<``$`%```"&0``9P4```(= -XM``!O!0```0D``'\%```"'@``AP4```$)``"3!0```B8``)\%```"'0``IP4` -XM``$)``"W!0```AX``,,%```"'0``RP4```$)``#;!0```AX``.<%```"'0`` -XM[P4```$)``#_!0```AX``#<&```"&```BP8```(H``"6!@```B$``.H&```" -XM'0``\@8```$)```"!P```AX```H'```"'0``$@<```$)```B!P```AX``$P' -XM```"%P``9@<```(7``#K!P```AD```4(```"'0``#0@```$)```="````AX` -XM`"D(```"'0``,0@```$)``!!"````AX``$T(```"'0``50@```$)``!E"``` -XM`AX``.@(```"*@``2PD```(7``!]"0```AD``.T)```"*@``#0H```$+```2 -XM"@```BP``"`*```"'0``*`H```$)```X"@```AX``$0*```"'0``3`H```$) -XM``!<"@```AX``'D*```"+@``E0H```(E``#L"@```B\``#0+```"'0``/`L` -XM``$)``!,"P```AX``%@+```"'0``8`L```$)``!P"P```AX``'@+```!"0`` -XMA`L```(>``"Y"P```C$``-P+```",@``%PP```$)```C#````AX``$8,```" -XM,```=@P```(P``"Y#````B4``,T,```!"0``&@T```(T```V#0```0D``&0- -XM```")0``N0T```(U``#*#0```B0``.`-```"&@``^`T```$)```)#@```0D` -XM`"4.```!"0``5`X```(V``!Q#@```A<``)4.```"-P``K0X```$)``#L#@`` -XM`BD``/D.```!"0``-0\```(P``!X#P```0D``)@/```"(0``M@\```(=``"^ -XM#P```0D``,X/```"'@``V@\```(=``#B#P```0D``/(/```"'@``_@\```(= -XM```&$````0D``!80```"'@``(A````(=```J$````0D``#H0```"'@``0A`` -XM``$)``!.$````B8``%H0```"'0``8A````$)``!R$````AX``'H0```"'0`` -XM@A````$)``"2$````AX``+40```!.```OQ````$Y``#M$````3@``/<0```! -XM.0``)A$```$Y```V$0```CH``$$1```!.0``4!$```(Z``!J$0```CL``'\1 -XM```".P``SA$```$)``#K$0```CT```P2```!"0``'1(```$)``!J$@```C(` -XM`)02```"/@``K!(```(H``#($@```C(``/$2```"%P``4A,```(A``"0$P`` -XM`C(``!L4```"/P``-A0```(Q``"'%````B<``*`4```",```[A0```(H``#Y -XM%````B$```<5```!.```%14```$Y``!E%0```D```+\5```"0```XQ4```(P -XM``#N%0```C\```86```"0```-!8```(^``!5%@```C```&`6```"/P``=!8` -XM``$)``"`%@```B8``(46```!.0``E18```(Z``#"%@```CL``/86```"*``` -XM&Q<```)!```[%P```AH``%$7```"-P``:!<```)"``""%P```C(``+07```" -XM,@``TA<```(=``#:%P```0D``.H7```"'@``\A<```$)``#^%P```B8```H8 -XM```"'0``$A@```$)```B&````AX``"X8```"'0``-A@```$)``!&&````AX` -XM`$L8```"(0``C1@```(O``#!&````AT``,D8```!"0``V1@```(>```&```` -XM`04```P````!%```$0````$4```5`````10``!D````!`@``'0````$"```A -XM`````0<``"@````!%```+P````$4```V`````10``#L````!%```2`````$4 -XM``!4`````10``&$````!%```9@````$4``!S`````10``'@````!%```A0`` -XM``$4``",`````10``),````!%```F`````$4``"E`````10``*P````!%``` -XML0````$4``#!`````10``,P````!%```UP````$4``#S`````10``/X````! -XM%```"0$```$4```5`0```10``",!```!%```.`$```$4``!K`0```10``'D! -XM```!%```E0$```$4``"C`0```10``+$!```!%```OP$```$4``#-`0```10` -XM`-L!```!%```]P$```$4```3`@```10``"$"```!%```/0(```$4``!+`@`` -XM`10``-`"```!%```_`(```$4```'`P```10``!(#```!%```-0,```$4``!# -XM`P```10``%(#```!%```70,```$4``!H`P```10``',#```!%```?@,```$4 -XM``")`P```10``)P#```!%```J@,```$4``"X`P```10``,8#```!%```U`,` -XM``$4``#B`P```10``/`#```!%```_@,```$4```,!````10``!H$```!%``` -XM*`0```$4```V!````10``$0$```!%```4@0```$4``!A!````10``'0$```! -XM%```@@0```$4``"0!````10``)X$```!%```K`0```$4``"Z!````10``,@$ -XM```!%```U@0```$4``#D!````10``/($```!%````04```$4```4!0```10` -XM`"(%```!%```,04```$4``!'!0```10``$T%```!%```6`4```$4``!F!0`` -XM`10``&P%```!%```<@4```$4``!X!0```10``'X%```!%```A`4```$4``"* -XM!0```10``)`%```!%```E@4```$4``""````10``&P(```!%```>P@```$4``"'"````10``.8(```!%``` -XM]`@```$4```0"0```10``!X)```!%```+`D```$4```Z"0```10``$@)```! -XM%```:PD```$4``!Y"0```10``(@)```!%```E`D```$4``"B"0```10``+D) -XM```!%```R`D```$4``#^"0```10```P*```!%```&@H```$4```H"@```10` -XM`$4*```!%```2PH```$4``!1"@```10``%<*```!%```70H```$4``!L"@`` -XM`10``'H*```!%```EPH```$4``"E"@```10``,(*```!%```T`H```$4``#M -XM"@```10``/L*```!%```&`L```$4```F"P```10``#T+```!%```2PL```$4 -XM``!B"P```10``'$+```!%```?0L```$4``"+"P```10``)D+```!%```T0L` -XM``$4``#?"P```10``.T+```!%```^PL```$4```)#````10``!<,```!%``` -XM)0P```$4```S#````10``$$,```!%```3PP```$4``!=#````10``&L,```! -XM%```>0P```$4``"'#````10``)4,```!%```HPP```$4``"Q#````10``+\, -XM```!%```S0P```$4``#;#````10``.D,```!%```]PP```$4```-#0```10` -XM`!0-```!`@``&`T```$"```<#0```1```"\-```!$```/@T```$0``!6#0`` -XM`10``%X-```!`@``8@T```$"``!F#0```1```'H-```!$```B`T```$0``"- -XM#0```10``)@-```!$```M`T```$4``"\#0```0(``,`-```!`@``Q`T```$0 -XM``#8#0```1```.8-```!$```]`T```$0```)#@```10``!0.```!$```&0X` -XM``$4```F#@```10``"X.```!`@``,@X```$"```V#@```1```$H.```!$``` -XM3PX```$4``!:#@```1```&@.```!$```;PX```$4``!W#@```0(``'L.```! -XM`@``?PX```$0``"3#@```1```*(.```!$```IPX```$4``"R#@```1```,L. -XM```!$```V@X```$0``#Q#@```10``/D.```!`@``_0X```$"```!#P```1`` -XM`!,/```!$```(@\```$0```Q#P```1```#8/```!%```00\```$0``!(#P`` -XM`10``%`/```!`@``5`\```$"``!8#P```1```&P/```!$```>P\```$0``"* -XM#P```1```(\/```!%```F@\```$0``#!#P```10``,D/```!`@``S0\```$" -XM``#1#P```1```.4/```!$```\P\```$0```3$````1```!H0```!%```)1`` -XM``$"```I$````0(``"T0```!$```0!````$0``!.$````1```%,0```!%``` -XM7A````$0``!S$````10``'X0```!$```A1````$4``"0$````0(``)00```! -XM`@``F!````$0``"K$````1```+`0```!%```NA````$0``#)$````1```-@0 -XM```!$```WA````$4``#I$````0(``.T0```!`@``\1````$0```$$0```1`` -XM``D1```!%```$Q$```$0```B$0```1```"@1```!%```,Q$```$"```W$0`` -XM`0(``#L1```!$```3A$```$0``!3$0```10``%T1```!$```;!$```$0``!R -XM$0```10``(X1```!%```J!$```$4``"O$0```0(``+,1```!`@``MQ$```$0 -XM``#*$0```1```-<1```!$```W!$```$4``#F$0```1```/01```!$```"!(` -XM``$4```2$@```1```!<2```!%```(1(```$0```J$@```1,``#L2```!`@`` -XM/Q(```$"``!($@```1```%`2```!%```?Q(```$4``"'$@```0(``(L2```! -XM`@``CQ(```$0``"A$@```1```+`2```!$```OA(```$0``#'$@```1,``-<2 -XM```!$```YA(```$3``#R$@```1```/L2```!$````A,```$4```P$P```10` -XM`%03```!%```8!,```$4``!W$P```10``(T3```!%```LA,```$4``#.$P`` -XM`10``-H3```!%```"A0```$4```6%````10``&X4```!%```>Q0```$4``"7 -XM%````10``,,4```!%```UA0```$4``#R%````10```D5```!%```+!4```$4 -XM```Z%0```10``$(5```!`@``1A4```$"``!*%0```1```%X5```!$```=14` -XM``$3``"+%0```1,``)05```!$```G14```$0``"W%0```1```-(5```!$``` -XM[!4```$3``#\%0```1````L6```!$P``(18```$3```J%@```1```#,6```! -XM$```1A8```$0``!4%@```1```%T6```!$```>18```$3``"+%@```1,``)06 -XM```!$```IQ8```$0``"T%@```0(``+@6```!`@``SA8```$"``#2%@```0(` -XM`-L6```!$```YA8```$3``#S%@```1,``/P6```!$```!1<```$0```.%P`` -XM`1,``!H7```!$```*!<```$4```U%P```10``,4````!`@``&`````$/```< -XM`````0(``#@````!#P``/`````$"``!8`````0\``%P````!`@``>`````$/ -XM``!\`````0(``)@````!#P``G`````$"``"X`````0\``+P````!`@``V``` -XM``$/``#<`````0(``/@````!#P``_`````$"```8`0```0\``!P!```!`@`` -XM.`$```$/```\`0```0(``%@!```!#P``7`$```$"``!P`0```0\``'0!```! -XM`@``B`$```$/``",`0```0(``*@!```!#P``K`$```$"``#(`0```0\``,P! -X>```!`@``!@````$&```&`````08``!`````!`@`` +XM```````````````````!```````````````$`/'_`````````````````P`! +XM``````````````````,``P`````````````````#``0````````````````` +XM`P`%``````````````````,`!@`````````````````#``@`#`````````!T +XM`````@`!``````````````````,`"P`?````@`,``'(````"``$````````` +XM`````````P`,`"\````P#```+0````(``0!#````8`P``#8````"``$`50`` +XM`*`0``#H`````@`!``````````````````,`#0`````````````````#``\` +XM`````````````````P`0``````````````````,`$@`````````````````# +XM`!0``````````````````P`5``````````````````,`"@!@````@````.T! +XM```2``$`;0``````````````$````'H``````````````!````"&```````` +XM```````0````EP``````````````$````*(``````````````!````"R```` +XM```````````0````N@``````````````$````,4``````````````!````#* +XM````<`(```P!```2``$`U@``````````````$````.0``````````````!`` +XM``#N```````````````0````_P`````$```#`@``$@`!``\!```````````` +XM`!`````:`0`````````````0````(0$`````````````$````"4!```0!@`` +XM%@$``!(``0`O`0`````````````0````.P$``#`'```Y`0``$@`!`$4!```` +XM`````````!````!/`0``<`@``/`!```2``$`7P$`````````````$````&4! +XM``!@"@``*`$``!(``0!R`0`````````````0````?P$`````````````$``` +XM`(H!``"0"P``EP```!(``0"9`0`````````````0````H`$````````````` +XM$````*'-C;@!E;&9?`!I;G-EF4`;&]O:W5P7W-E8U]A8W0``!A9&1?=&]?:6YS +XM96=?;&ES=`!E;&9?;F5X='-C;@!E;&9?0!S=')L96X`0!G96QF7V=E=')E;`!L;V]K=7!? +XM:V5E<%]S>6UL:7-T`)T````"%P``"0$```(8```[`0```AD``(D!```"&@`` +XMF`$```(;``#4`0```AP``.4!```"'0``[0$```$)``#]`0```AX```D"```" +XM'0``$0(```$)```A`@```AX``"T"```"'0``-0(```$)``!%`@```AX``%$" +XM```"'0``60(```$)``!I`@```AX``)$"```"%P``I@(```(@``#3`@```AH` +XM`.L"```"&0``^P(```(A```<`P```AT``"0#```!"0``-`,```(>``!``P`` +XM`AT``$@#```!"0``6`,```(>``!@`P```AT``&@#```!"0``>`,```(>``"@ +XM`P```B(``+0#```!"0``O`,```(B``#$`P```0D``,P#```"(@``U`,```$) +XM``#<`P```B(``.0#```!"0``[`,```(B```D!````0D``$H$```")```:`0` +XM``(E``##!````A@``!@%```"%P``0`4```(9``!G!0```AT``&\%```!"0`` +XM?P4```(>``"'!0```0D``),%```")@``GP4```(=``"G!0```0D``+<%```" +XM'@``PP4```(=``#+!0```0D``-L%```"'@``YP4```(=``#O!0```0D``/\% +XM```"'@``-P8```(8``"+!@```B@``)8&```"(0``Z@8```(=``#R!@```0D` +XM``('```"'@``"@<```(=```2!P```0D``"('```"'@``3`<```(7``!F!P`` +XM`A<``.L'```"&0``!0@```(=```-"````0D``!T(```"'@``*0@```(=```Q +XM"````0D``$$(```"'@``30@```(=``!5"````0D``&4(```"'@``Z`@```(J +XM``!+"0```A<``'T)```"&0``[0D```(J```-"@```0L``!(*```"+```(`H` +XM``(=```H"@```0D``#@*```"'@``1`H```(=``!,"@```0D``%P*```"'@`` +XM>0H```(N``"5"@```B4``.P*```"+P``-`L```(=```\"P```0D``$P+```" +XM'@``6`L```(=``!@"P```0D``'`+```"'@``>`L```$)``"$"P```AX``+D+ +XM```",0``W`L```(R```7#````0D``",,```"'@``1@P```(P``!V#````C`` +XM`+D,```")0``S0P```$)```:#0```C0``#8-```!"0``9`T```(E``"Y#0`` +XM`C4``,H-```")```X`T```(:``#X#0```0D```D.```!"0``)0X```$)``!4 +XM#@```C8``'$.```"%P``E0X```(W``"M#@```0D``.P.```"*0``^0X```$) +XM```U#P```C```'@/```!"0``F`\```(A``"V#P```AT``+X/```!"0``S@\` +XM``(>``#:#P```AT``.(/```!"0``\@\```(>``#^#P```AT```80```!"0`` +XM%A````(>```B$````AT``"H0```!"0``.A````(>``!"$````0D``$X0```" +XM)@``6A````(=``!B$````0D``'(0```"'@``>A````(=``""$````0D``)(0 +XM```"'@``M1````$X``"_$````3D``.T0```!.```]Q````$Y```F$0```3D` +XM`#81```".@``01$```$Y``!0$0```CH``&H1```".P``?Q$```([``#.$0`` +XM`0D``.L1```"/0``#!(```$)```=$@```0D``&H2```",@``E!(```(^``"L +XM$@```B@``,@2```",@``\1(```(7``!2$P```B$``)`3```",@``&Q0```(_ +XM```V%````C$``(<4```")P``H!0```(P``#N%````B@``/D4```"(0``!Q4` +XM``$X```5%0```3D``&45```"0```OQ4```)```#C%0```C```.X5```"/P`` +XM!A8```)````T%@```CX``%46```",```8!8```(_``!T%@```0D``(`6```" +XM)@``A18```$Y``"5%@```CH``,(6```".P``]A8```(H```;%P```D$``#L7 +XM```"&@``41<```(W``!H%P```D(``((7```",@``M!<```(R``#2%P```AT` +XM`-H7```!"0``ZA<```(>``#R%P```0D``/X7```")@``"A@```(=```2&``` +XM`0D``"(8```"'@``+A@```(=```V&````0D``$88```"'@``2Q@```(A``"- +XM&````B\``,$8```"'0``R1@```$)``#9&````AX```8````!!0``#`````$4 +XM```1`````10``!4````!%```&0````$"```=`````0(``"$````!!P``*``` +XM``$4```O`````10``#8````!%```.P````$4``!(`````10``%0````!%``` +XM80````$4``!F`````10``',````!%```>`````$4``"%`````10``(P````! +XM%```DP````$4``"8`````10``*4````!%```K`````$4``"Q`````10``,$` +XM```!%```S`````$4``#7`````10``/,````!%```_@````$4```)`0```10` +XM`!4!```!%```(P$```$4```X`0```10``&L!```!%```>0$```$4``"5`0`` +XM`10``*,!```!%```L0$```$4``"_`0```10``,T!```!%```VP$```$4``#W +XM`0```10``!,"```!%```(0(```$4```]`@```10``$L"```!%```T`(```$4 +XM``#\`@```10```<#```!%```$@,```$4```U`P```10``$,#```!%```4@,` +XM``$4``!=`P```10``&@#```!%```!0```10``.0%```!%```Z@4```$4``#P!0```10``/<% +XM```!%```"@8```$4```9!@```10``"4&```!%```,P8```$4``!!!@```10` +XM`$\&```!%```708```$4``!K!@```10``'D&```!%```AP8```$4``"5!@`` +XM`10``+`&```!%```NP8```$4``#&!@```10``-$&```!%```Y`8```$4``#S +XM!@```10``/\&```!%```#0<```$4```J!P```10``#D'```!%```10<```$4 +XM``!3!P```10``&$'```!%```;P<```$4``"+!P```10``)D'```!%```IP<` +XM``$4``"U!P```10``,,'```!%```T0<```$4``#?!P```10``/P'```!%``` +XM"P@```$4```7"````10``"4(```!%```,P@```$4``!!"````10``%X(```! +XM%```;`@```$4``!["````10``(<(```!%```Y@@```$4``#T"````10``!`) +XM```!%```'@D```$4```L"0```10``#H)```!%```2`D```$4``!K"0```10` +XM`'D)```!%```B`D```$4``"4"0```10``*()```!%```N0D```$4``#("0`` +XM`10``/X)```!%```#`H```$4```:"@```10``"@*```!%```10H```$4``!+ +XM"@```10``%$*```!%```5PH```$4``!="@```10``&P*```!%```>@H```$4 +XM``"7"@```10``*4*```!%```P@H```$4``#0"@```10``.T*```!%```^PH` +XM``$4```8"P```10``"8+```!%```/0L```$4``!+"P```10``&(+```!%``` +XM<0L```$4``!]"P```10``(L+```!%```F0L```$4``#1"P```10``-\+```! +XM%```[0L```$4``#["P```10```D,```!%```%PP```$4```E#````10``#,, +XM```!%```00P```$4``!/#````10``%T,```!%```:PP```$4``!Y#````10` +XM`(<,```!%```E0P```$4``"C#````10``+$,```!%```OPP```$4``#-#``` +XM`10``-L,```!%```Z0P```$4``#W#````10```T-```!%```%`T```$"```8 +XM#0```0(``!P-```!$```+PT```$0```^#0```1```%8-```!%```7@T```$" +XM``!B#0```0(``&8-```!$```>@T```$0``"(#0```1```(T-```!%```F`T` +XM``$0``"T#0```10``+P-```!`@``P`T```$"``#$#0```1```-@-```!$``` +XMY@T```$0``#T#0```1````D.```!%```%`X```$0```9#@```10``"8.```! +XM%```+@X```$"```R#@```0(``#8.```!$```2@X```$0``!/#@```10``%H. +XM```!$```:`X```$0``!O#@```10``'<.```!`@``>PX```$"``!_#@```1`` +XM`),.```!$```H@X```$0``"G#@```10``+(.```!$```RPX```$0``#:#@`` +XM`1```/$.```!%```^0X```$"``#]#@```0(```$/```!$```$P\```$0```B +XM#P```1```#$/```!$```-@\```$4``!!#P```1```$@/```!%```4`\```$" +XM``!4#P```0(``%@/```!$```;`\```$0``![#P```1```(H/```!$```CP\` +XM``$4``":#P```1```,$/```!%```R0\```$"``#-#P```0(``-$/```!$``` +XMY0\```$0``#S#P```1```!,0```!$```&A````$4```E$````0(``"D0```! +XM`@``+1````$0``!`$````1```$X0```!$```4Q````$4``!>$````1```',0 +XM```!%```?A````$0``"%$````10``)`0```!`@``E!````$"``"8$````1`` +XM`*L0```!$```L!````$4``"Z$````1```,D0```!$```V!````$0``#>$``` +XM`10``.D0```!`@``[1````$"``#Q$````1````01```!$```"1$```$4```3 +XM$0```1```"(1```!$```*!$```$4```S$0```0(``#<1```!`@``.Q$```$0 +XM``!.$0```1```%,1```!%```71$```$0``!L$0```1```'(1```!%```CA$` +XM``$4``"H$0```10``*\1```!`@``LQ$```$"``"W$0```1```,H1```!$``` +XMUQ$```$0``#<$0```10``.81```!$```]!$```$0```($@```10``!(2```! +XM$```%Q(```$4```A$@```1```"H2```!$P``.Q(```$"```_$@```0(``$@2 +XM```!$```4!(```$4``!_$@```10``(<2```!`@``BQ(```$"``"/$@```1`` +XM`*$2```!$```L!(```$0``"^$@```1```,<2```!$P``UQ(```$0``#F$@`` +XM`1,``/(2```!$```^Q(```$0```"$P```10``#`3```!%```5!,```$4``!@ +XM$P```10``'<3```!%```C1,```$4``"R$P```10``,X3```!%```VA,```$4 +XM```*%````10``!84```!%```;A0```$4``![%````10``)<4```!%```PQ0` +XM``$4``#6%````10``/(4```!%```"14```$4```L%0```10``#H5```!%``` +XM0A4```$"``!&%0```0(``$H5```!$```7A4```$0``!U%0```1,``(L5```! +XM$P``E!4```$0``"=%0```1```+<5```!$```TA4```$0``#L%0```1,``/P5 +XM```!$```"Q8```$3```A%@```1,``"H6```!$```,Q8```$0``!&%@```1`` +XM`%06```!$```718```$0``!Y%@```1,``(L6```!$P``E!8```$0``"G%@`` +XM`1```+06```!`@``N!8```$"``#.%@```0(``-(6```!`@``VQ8```$0``#F +XM%@```1,``/,6```!$P``_!8```$0```%%P```1````X7```!$P``&A<```$0 +XM```H%P```10``#47```!%```Q0````$"```8`````0\``!P````!`@``.``` +XM``$/```\`````0(``%@````!#P``7`````$"``!X`````0\``'P````!`@`` +XMF`````$/``"<`````0(``+@````!#P``O`````$"``#8`````0\``-P````! +XM`@``^`````$/``#\`````0(``!@!```!#P``'`$```$"```X`0```0\``#P! +XM```!`@``6`$```$/``!<`0```0(``'`!```!#P``=`$```$"``"(`0```0\` +XM`(P!```!`@``J`$```$/``"L`0```0(``,@!```!#P``S`$```$"```&```` +XM`08```8````!!@``$`````$"```````````````````````````````````` +XM````````````````````'P````$````&`````````$````#E&``````````` +XM```0`````````!L````)````0`````````#H8```P`8``!<````!````!``` +XM``@````E`````0````,`````````*!D```````````````````0````````` +XM*P````@````#`````````"@9```````````````````$`````````#`````! +XM```````````````H&0``*P,``````````````0````````!"`````0`````` +XM````````4QP``$,7``````````````$`````````/@````D```!````````` +XM`*AG``#(#```%P````8````$````"````%(````!``````````````"6,P`` +XM=`0``````````````0````````!.````"0```$``````````<'0```@````7 +XM````"`````0````(````7@````$```````````````HX```P```````````` +XM```!`````````&<````!````,@`````````Z.```F@(``````````````0`` +XM``$```!V`````0```#(`````````U#H``"T```````````````0````!```` +XMB0````$```````````````0[``#D`0`````````````$`````````(4````) +XM````0`````````!X=```\````!<````-````!`````@```"6`````0`````` +XM````````Z#P``!L0``````````````$`````````I0````$````````````` +XM``--``"[```````````````!`````````*$````)````0`````````!H=0`` +XM"````!<````0````!`````@```"Y`````0``````````````ODT``"`````` +XM``````````$`````````M0````D```!``````````'!U```0````%P```!(` +XM```$````"````,@````!``````````````#>30``R`(``````````````0`` +XM``````#6`````0```#``````````IE```,X(``````````````$````!```` +XM$0````,``````````````'19``#A```````````````!``````````$````" +XM``````````````!86@``,`0``!@````6````!````!`````)`````P`````` +X>````````B%X``&`"``````````````$````````` X` Xend -END-of-sections.o.debug.1.uu +7441d94dfba58dda29235b0205ebc7b3 echo x - sections.o.debug.uu -sed 's/^X//' >sections.o.debug.uu << 'END-of-sections.o.debug.uu' +sed 's/^X//' >sections.o.debug.uu << '07454e9209d1c5eccb83c5c72e752a37' Xbegin 644 sections.o.debug XM?T5,1@$!`0D```````````$``P`!``````````````!86@```````#0````` XM`"@`&0`6`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R @@ -1401,6 +1401,6 @@ XM`@``B`$```$/``",`0```0(``*@!```!#P``K`$```$"``#(`0```0\``,P! X>```!`@``!@````$&```&`````08``!`````!`@`` X` Xend -END-of-sections.o.debug.uu +07454e9209d1c5eccb83c5c72e752a37 exit diff --git a/test/elfcopy/tc/elfcopy-noops-archive-1/out/elfcopy-noops-archive-1.out.shar b/test/elfcopy/tc/elfcopy-noops-archive-1/out/elfcopy-noops-archive-1.out.shar index d1449fe14d6c..445b715cca3e 100644 --- a/test/elfcopy/tc/elfcopy-noops-archive-1/out/elfcopy-noops-archive-1.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-archive-1/out/elfcopy-noops-archive-1.out.shar @@ -11,87 +11,87 @@ echo x - liba.a.1.uu sed 's/^X//' >liba.a.1.uu << 'b253f047a1631a2a184043b6f45926f7' Xbegin 644 liba.a.1 -XM(3QA`!Y`&US9S$`;7-G,@!O=71P=71M'0`+F1A=&$` -XM+F)S6#[`C'1"0$`````,<$ XM)`````#H_/___\G#:&5L;&\L('=O6UT86(`+G-T6UT86(`+G-T````!4````````````` -XM``$`````````.`````$``````````````(T````F```````````````!```` -XM`````!$````#``````````````"S````00```````````````0`````````! -XM`````@``````````````A`(``+`````)````!P````0````0````"0````,` -XM`````````````#0#```A```````````````!```````````````````````` -XM```````!```````````````$`/'_`````````````````P`!```````````` -XM``````,``P`````````````````#``0``````````````````P`%```````` -XM``````````,`!@`&``````````D````1``,`"P````D````)````$0`#`!`` -XM````````)````!(``0`:```````````````0`````&$T+F,`;7-G,0!M`````@H````````````````````````````````````````````` +XM```````````?`````0````8`````````0````"0``````````````!`````` +XM````&P````D```!``````````,@!```@````"`````$````$````"````"4` +XM```!`````P````````!D````$@``````````````!``````````K````"``` +XM``,`````````>`````````````````````0`````````,`````$````"```` +XM`````'@````5```````````````!`````````#@````!``````````````"- +XM````)@```````````````0`````````1`````P``````````````LP```$$` +XM``````````````$``````````0````(``````````````/0```"P````"0`` +XM``<````$````$`````D````#``````````````"D`0``(0`````````````` +X(`0`````````` X` Xend b253f047a1631a2a184043b6f45926f7 diff --git a/test/elfcopy/tc/elfcopy-noops-archive-2/out/elfcopy-noops-archive-2.out.shar b/test/elfcopy/tc/elfcopy-noops-archive-2/out/elfcopy-noops-archive-2.out.shar index dfb04aa71f96..4a6544ec8d23 100644 --- a/test/elfcopy/tc/elfcopy-noops-archive-2/out/elfcopy-noops-archive-2.out.shar +++ b/test/elfcopy/tc/elfcopy-noops-archive-2/out/elfcopy-noops-archive-2.out.shar @@ -11,89 +11,89 @@ echo x - liblong.a.1.uu sed 's/^X//' >liblong.a.1.uu << '8eb77b0d36e0369a1b3adf0cc5ef193a' Xbegin 644 liblong.a.1 -XM(3QA2```'D@``"LX```K.```*SG-U;6UU;`!A`&US9P!P`!Y`&US9S$`;7-G,@!O=71P=71M7'!0`` +XM````````8`$````````T```````H``D`!@````````````````!5B>7'!0`` XM```%````BT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P XM,#6UT86(`+G-T`!Y``4````!!P``#P`` -XM``$(```9`````0<``"<````!"```+S(W("`@("`@("`@("`@(#$R,S$U,S,P -XM,C0@(#$P,#$@(#`@("`@(#$P,#8T-"`@.#@X("`@("`@(&`*?T5,1@$!`0D` -XM``````````$``P`!``````````````#T`````````#0``````"@`"@`'```` +XM``$(```9`````0<``"<````!"``````````````````````````````````` +XM`````````````````````!\````!````!@````````!`````,P`````````` +XM````$``````````;````"0```$``````````>`$``"`````'`````0````0` +XM```(````)0````$````#`````````'0````````````````````$```````` +XM`"L````(`````P````````!T````````````````````!``````````P```` +XM`0``````````````=````"8```````````````$`````````$0````,````` +XM`````````)H````Y```````````````!``````````$````"```````````` +XM``#4````D`````@````&````!````!`````)`````P``````````````9`$` +XM`!0```````````````$`````````+S(W("`@("`@("`@("`@(#$Q.30W-S'0`+F1A=&$`+F)S`````````````````````0`````````,`````$````"```````` -XM`'@````5```````````````!`````````#@````!``````````````"-```` -XM)@```````````````0`````````1`````P``````````````LP```$$````` -XM``````````$``````````0````(``````````````(0"``"P````"0````<` -XM```$````$`````D````#```````````````T`P``(0```````````````0`` -XM`````````````````````````````0``````````````!`#Q_P`````````` -XM``````,``0`````````````````#``,``````````````````P`$```````` -XM``````````,`!0`````````````````#``8`!@`````````)````$0`#``L` -XM```)````"0```!$``P`0`````````"0````2``$`&@``````````````$``` -XM``!A-"YC`&US9S$`;7-G,@!O=71P=71Msym.o.uu << '07b26866a0eaf5d2a40d8f75b1109c67' Xbegin 644 sym.o -XM?T5,1@$!`0D```````````$``P`!``````````````#@`````````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````"<`0```````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I XM(#0N,BXQ(#(P,#6UT86(`+G-Tsym.o.1.uu << 'END-of-sym.o.1.uu' +sed 's/^X//' >sym.o.1.uu << 'cc3b7341ff25eb16b80756fcb867a66b' Xbegin 644 sym.o.1 -XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` +XM?T5,1@$!`0D```````````$``P`!``````````````!``0```````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# XMC;8`````58GEN`````!=PXVV`````%6)Y;@`````7<,```!'0T,Z("A'3E4I XM(#0N,BXQ(#(P,#6UT86(`+G-Tsym.o.uu << 'END-of-sym.o.uu' +sed 's/^X//' >sym.o.uu << '07b26866a0eaf5d2a40d8f75b1109c67' Xbegin 644 sym.o XM?T5,1@$!`0D```````````$``P`!``````````````#8`````````#0````` XM`"@`"``%`````````````````%6)Y;@`````7<.-M@````!5B>6X`````%W# @@ -51,6 +51,6 @@ XM`!(``0`5````,`````H````2``$``'1Els.uu << 'END-of-ls.uu' -Xbegin 755 ls +sed 's/^X//' >ls.uu << '4db11c737631d887608e3186a17a7a3e' +Xbegin 644 ls XM?T5,1@$!`0D```````````(``P`!````D),$"#0```!T7@```````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(<%@` @@ -554,8 +554,8 @@ XM(0````4````"````1($$"$0!``!H`@``!``````````$````!````"<````+ XM`````@```*R#!`BL`P``4`4```4````!````!````!`````O`````P````(` XM``#\B`0(_`@```@#``````````````$`````````-P```/___V\"````!(P$ XM"`0,``"J````!``````````"`````@```$0```#^__]O`@```+",!`BP#``` -XM(`````4````!````!`````````!3````"0````(```#0C`0(T`P``#`````$ -XM``````````0````(````7`````D````"`````(T$"``-```@`@``!`````L` +XM(`````4````!````!`````````!3````"0```$(```#0C`0(T`P``#`````$ +XM``````````0````(````7`````D```!"`````(T$"``-```@`@``!`````L` XM```$````"````&4````!````!@```""/!`@@#P``$0``````````````!``` XM``````!@`````0````8````TCP0(-`\``%`$``````````````0````$```` XM:P````$````&````D),$")`3``!,0``````````````0`````````'$````! @@ -573,6 +573,6 @@ XM`.!:``#(`@`````````````!``````````$````#``````````````"H70`` X4S````````````````0`````````` X` Xend -END-of-ls.uu +4db11c737631d887608e3186a17a7a3e exit diff --git a/test/elfcopy/tc/strip-all-10/out/strip-all-10.out.shar b/test/elfcopy/tc/strip-all-10/out/strip-all-10.out.shar index 03641e9c55ec..7d0daf3ebb73 100644 --- a/test/elfcopy/tc/strip-all-10/out/strip-all-10.out.shar +++ b/test/elfcopy/tc/strip-all-10/out/strip-all-10.out.shar @@ -2530,9 +2530,9 @@ XM``0````````````````````G````!0````(`````````$`-````````0`P`` XM`````(0#````````!``````````(``````````0`````````+0````L````" XM`````````)@&0```````F`8```````#0"P````````4````!````"``````` XM```8`````````#4````#`````@````````!H$D```````&@2````````Z@,` -XM``````````````````$````````````````````]````!`````(````````` +XM``````````````````$````````````````````]````!````$(````````` XM6!9```````!8%@```````%`!````````!``````````(`````````!@````` -XM````1P````0````"`````````*@70```````J!<```````#`"0````````0` +XM````1P````0```!"`````````*@70```````J!<```````#`"0````````0` XM```)````"``````````8`````````%$````!````!@````````!P(4`````` XM`'`A````````#@```````````````````!````````````````````!,```` XM`0````8`````````@"%```````"`(0```````)`&```````````````````$ diff --git a/test/elfcopy/tc/strip-all-2/out/strip-all-2.out.shar b/test/elfcopy/tc/strip-all-2/out/strip-all-2.out.shar index ba58f923f30a..cb9aece58210 100644 --- a/test/elfcopy/tc/strip-all-2/out/strip-all-2.out.shar +++ b/test/elfcopy/tc/strip-all-2/out/strip-all-2.out.shar @@ -8,8 +8,8 @@ # ps.uu # echo x - ps.uu -sed 's/^X//' >ps.uu << 'END-of-ps.uu' -Xbegin 755 ps +sed 's/^X//' >ps.uu << '1d41113d6c473df8a15e4a4e0ea90bc3' +Xbegin 644 ps XM?T5,1@$!`0D```````````(``P`!````T)0$"#0````(>````````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(!&`` @@ -700,8 +700,8 @@ XM```$``````````0````$````)P````L````"````Q(,$",0#``"P!0``!0`` XM``$````$````$````"\````#`````@```'2)!`AT"0``+@,````````````` XM`0`````````W````____;P(```"BC`0(H@P``+8````$``````````(````" XM````1````/[__V\"````6(T$"%@-``!`````!0````(````$`````````%,` -XM```)`````@```)B-!`B8#0``,`````0`````````!`````@```!<````"0`` -XM``(```#(C00(R`T``$@"```$````"P````0````(````90````$````&```` +XM```)````0@```)B-!`B8#0``,`````0`````````!`````@```!<````"0`` +XM`$(```#(C00(R`T``$@"```$````"P````0````(````90````$````&```` XM$)`$"!`0```1```````````````$`````````&`````!````!@```"20!`@D XM$```H`0`````````````!`````0```!K`````0````8```#0E`0(T!0``%Q! XM`````````````!``````````<0````$````&````+-8$""Q6```,```````` @@ -718,6 +718,6 @@ XM"`````````##`````0``````````````V',``&,#``````````````$````` XK`````0````,``````````````#MW``#,```````````````!```````````` X` Xend -END-of-ps.uu +1d41113d6c473df8a15e4a4e0ea90bc3 exit diff --git a/test/elfcopy/tc/strip-all-3/out/strip-all-3.out.shar b/test/elfcopy/tc/strip-all-3/out/strip-all-3.out.shar index f7b6173e4c28..a2a657c0cfa1 100644 --- a/test/elfcopy/tc/strip-all-3/out/strip-all-3.out.shar +++ b/test/elfcopy/tc/strip-all-3/out/strip-all-3.out.shar @@ -8,8 +8,8 @@ # tcsh.uu # echo x - tcsh.uu -sed 's/^X//' >tcsh.uu << 'END-of-tcsh.uu' -Xbegin 755 tcsh +sed 's/^X//' >tcsh.uu << 'e0b48b8aefb9960c9da54cac18bdcb01' +Xbegin 644 tcsh XM?T5,1@$!`0D```````````(``P`!````(*0$"#0```"HVP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(7)\$ @@ -7092,8 +7092,8 @@ XM!`A$`0``E`0```0`````````!`````0````G````"P````(```#8A00(V`4` XM```*```%`````0````0````0````+P````,````"````V(\$"-@/```X!0`` XM```````````!`````````#<```#___]O`@```!"5!`@0%0``0`$```0````` XM`````@````(```!$````_O__;P(```!0E@0(4!8``"`````%`````0````0` -XM````````4P````D````"````<)8$"'`6```@````!``````````$````"``` -XM`%P````)`````@```)"6!`B0%@``>`0```0````+````!`````@```!E```` +XM````````4P````D```!"````<)8$"'`6```@````!``````````$````"``` +XM`%P````)````0@```)"6!`B0%@``>`0```0````+````!`````@```!E```` XM`0````8````(FP0("!L``!$```````````````0`````````8`````$````& XM````')L$"!P;````"0`````````````$````!````&L````!````!@```""D XM!`@@)```W`P$````````````$`````````!Q`````0````8```#\L`@(_#`$ @@ -7111,6 +7111,6 @@ XM`````0`````````!`````P``````````````V=H$`,P```````````````$` X&```````` X` Xend -END-of-tcsh.uu +e0b48b8aefb9960c9da54cac18bdcb01 exit diff --git a/test/elfcopy/tc/strip-all-4/out/strip-all-4.out.shar b/test/elfcopy/tc/strip-all-4/out/strip-all-4.out.shar index 4acf57ad90a0..1706b0b6bbb1 100644 --- a/test/elfcopy/tc/strip-all-4/out/strip-all-4.out.shar +++ b/test/elfcopy/tc/strip-all-4/out/strip-all-4.out.shar @@ -8,8 +8,8 @@ # vi.uu # echo x - vi.uu -sed 's/^X//' >vi.uu << 'END-of-vi.uu' -Xbegin 755 vi +sed 's/^X//' >vi.uu << '5f6cb34c34598fc980a32aede89eafe8' +Xbegin 644 vi XM?T5,1@$!`0D```````````(``P`!````X*0$"#0````8IP0``````#0`(``' XM`"@`&@`9``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0! XM```4@00(%($$"!4````5````!`````$````!``````````"`!`@`@`0(@(\$ @@ -6793,8 +6793,8 @@ XM"$0!``"T!```!``````````$````!````"<````+`````@```/B%!`CX!0`` XM@`H```4````!````!````!`````O`````P````(```!XD`0(>!```-`$```` XM``````````$`````````-P```/___V\"````2)4$"$@5``!0`0``!``````` XM```"`````@```$0```#^__]O`@```)B6!`B8%@``(`````4````!````!``` -XM``````!3````"0````(```"XE@0(N!8``&`````$``````````0````(```` -XM7`````D````"````&)<$"!@7``"(!```!`````L````$````"````&4````! +XM``````!3````"0```$(```"XE@0(N!8``&`````$``````````0````(```` +XM7`````D```!"````&)<$"!@7``"(!```!`````L````$````"````&4````! XM````!@```*";!`B@&P``$0``````````````!`````````!@`````0````8` XM``"TFP0(M!L``"`)``````````````0````$````:P````$````&````X*0$ XM".`D```\Y0,````````````0`````````'$````!````!@```!R*"`@<"@0` @@ -6812,6 +6812,6 @@ XM```!``````````$````#``````````````!)I@0`S````````````````0`` X%```````` X` Xend -END-of-vi.uu +5f6cb34c34598fc980a32aede89eafe8 exit diff --git a/test/elfcopy/tc/strip-all-5/out/strip-all-5.out.shar b/test/elfcopy/tc/strip-all-5/out/strip-all-5.out.shar index 96bcaf5a81ca..40c03cdbf86c 100644 --- a/test/elfcopy/tc/strip-all-5/out/strip-all-5.out.shar +++ b/test/elfcopy/tc/strip-all-5/out/strip-all-5.out.shar @@ -8,8 +8,8 @@ # pkill.uu # echo x - pkill.uu -sed 's/^X//' >pkill.uu << 'END-of-pkill.uu' -Xbegin 755 pkill +sed 's/^X//' >pkill.uu << '521a9e5ac40550eee504b066258ae35d' +Xbegin 644 pkill XM?T5,1@$!`0D```````````(``P`!````D(X$"#0```#D+@```````#0`(``& XM`"@`&0`8``8````T````-(`$"#2`!`C`````P`````4````$`````P```/0` XM``#T@`0(](`$"!4````5````!`````$````!``````````"`!`@`@`0(YBH` @@ -284,7 +284,7 @@ XM````````!`````0````G````"P````(```#(@@0(R`(``"`$```%`````0`` XM``0````0````+P````,````"````Z(8$".@&``!%`@`````````````!```` XM`````#<```#___]O`@```"Z)!`@N"0``A`````0``````````@````(```!$ XM````_O__;P(```"TB00(M`D``"`````%`````0````0`````````4P````D` -XM```"````U(D$"-0)``!(````!``````````$````"````%P````)`````@`` +XM``!"````U(D$"-0)``!(````!``````````$````"````%P````)````0@`` XM`!R*!`@<"@``<`$```0````+````!`````@```!E`````0````8```",BP0( XMC`L``!$```````````````0`````````8`````$````&````H(L$"*`+``#P XM`@`````````````$````!````&L````!````!@```)".!`B0#@``_!8````` @@ -301,6 +301,6 @@ XM``@`````````M0````$``````````````*PL``!X`0`````````````!```` XL``````$````#```````````````D+@``O@```````````````0`````````` X` Xend -END-of-pkill.uu +521a9e5ac40550eee504b066258ae35d exit diff --git a/test/elfcopy/tc/strip-all-6/out/strip-all-6.out.shar b/test/elfcopy/tc/strip-all-6/out/strip-all-6.out.shar index 8ffbaaa6455a..2571223c3692 100644 --- a/test/elfcopy/tc/strip-all-6/out/strip-all-6.out.shar +++ b/test/elfcopy/tc/strip-all-6/out/strip-all-6.out.shar @@ -9,7 +9,7 @@ # mcs.o.uu # echo x - mcs.o.1.uu -sed 's/^X//' >mcs.o.1.uu << 'END-of-mcs.o.1.uu' +sed 's/^X//' >mcs.o.1.uu << 'f795b6a491de52ced7008ed30e59ba9b' Xbegin 644 mcs.o.1 XM?T5,1@$!`0D```````````$``P`!``````````````!L"0```````#0````` XM`"@`"``'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ @@ -66,7 +66,7 @@ XM:&1R(&9A:6QE9#H@)7,`9V5L9E]F'0`+F1A=&$`+F)S XMmcs.o.uu << 'END-of-mcs.o.uu' +sed 's/^X//' >mcs.o.uu << '4890727b4c22736e61623154688c0ec6' Xbegin 644 mcs.o XM?T5,1@$!`0D```````````$``P`!``````````````!\"0```````#0````` XM`"@`"@`'`````````````````%6)Y8/L&(E4)`3'1"0(`````(D$).C\____ @@ -170,6 +170,6 @@ XML`<```(6``"X!P```0@``,@'```"%P``T`<```(6``#8!P```0@``.@'```" X;%P``\`<```(6``#X!P```0@```@(```"%P`` X` Xend -END-of-mcs.o.uu +4890727b4c22736e61623154688c0ec6 exit diff --git a/test/elfcopy/tc/strip-all-7/out/strip-all-7.out.shar b/test/elfcopy/tc/strip-all-7/out/strip-all-7.out.shar index 6e7c4727885b..59f78aa347a2 100644 --- a/test/elfcopy/tc/strip-all-7/out/strip-all-7.out.shar +++ b/test/elfcopy/tc/strip-all-7/out/strip-all-7.out.shar @@ -9,7 +9,7 @@ # sections.o.uu # echo x - sections.o.1.uu -sed 's/^X//' >sections.o.1.uu << 'END-of-sections.o.1.uu' +sed 's/^X//' >sections.o.1.uu << 'eb2ac2808b7045ab3c2faf26922f5e01' Xbegin 644 sections.o.1 XM?T5,1@$!`0D```````````$``P`!``````````````!H'````````#0````` XM`"@`"0`(`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R @@ -174,7 +174,7 @@ XM`&UO=FEN9R!L;V%D86)L92!S96-T:6]N+&ES('1H:7,@:6YT96YT:6]N86P_ XM```Nsections.o.uu << 'END-of-sections.o.uu' +sed 's/^X//' >sections.o.uu << 'f3eccedeeefe85afebc666fca5eb0742' Xbegin 644 sections.o XM?T5,1@$!`0D```````````$``P`!``````````````!X'````````#0````` XM`"@`"P`(`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R @@ -434,6 +434,6 @@ XM`#88```!!@``1A@```(5``!+&````A@``(T8```")@``P1@```(4``#)&``` X,`08``-D8```"%0`` X` Xend -END-of-sections.o.uu +f3eccedeeefe85afebc666fca5eb0742 exit diff --git a/test/elfcopy/tc/strip-all-8/out/strip-all-8.out.shar b/test/elfcopy/tc/strip-all-8/out/strip-all-8.out.shar index 36d2beb5b3dd..3a5c52f7387e 100644 --- a/test/elfcopy/tc/strip-all-8/out/strip-all-8.out.shar +++ b/test/elfcopy/tc/strip-all-8/out/strip-all-8.out.shar @@ -9,7 +9,7 @@ # sections.o.debug.uu # echo x - sections.o.debug.1.uu -sed 's/^X//' >sections.o.debug.1.uu << 'END-of-sections.o.debug.1.uu' +sed 's/^X//' >sections.o.debug.1.uu << '7441d94dfba58dda29235b0205ebc7b3' Xbegin 644 sections.o.debug.1 XM?T5,1@$!`0D```````````$``P`!``````````````!H'````````#0````` XM`"@`"0`(`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R @@ -174,7 +174,7 @@ XM`&UO=FEN9R!L;V%D86)L92!S96-T:6]N+&ES('1H:7,@:6YT96YT:6]N86P_ XM```Nsections.o.debug.uu << 'END-of-sections.o.debug.uu' +sed 's/^X//' >sections.o.debug.uu << '07454e9209d1c5eccb83c5c72e752a37' Xbegin 644 sections.o.debug XM?T5,1@$!`0D```````````$``P`!``````````````!86@```````#0````` XM`"@`&0`6`````````````````%6)Y5:)QE.+2'R)TX7)=#^+0A"+4A0[411R @@ -880,6 +880,6 @@ XM`@``B`$```$/``",`0```0(``*@!```!#P``K`$```$"``#(`0```0\``,P! X>```!`@``!@````$&```&`````08``!`````!`@`` X` Xend -END-of-sections.o.debug.uu +07454e9209d1c5eccb83c5c72e752a37 exit diff --git a/test/elfcopy/tc/strip-all-9/out/strip-all-9.out.shar b/test/elfcopy/tc/strip-all-9/out/strip-all-9.out.shar index 96d9028c57d3..c73f7e806239 100644 --- a/test/elfcopy/tc/strip-all-9/out/strip-all-9.out.shar +++ b/test/elfcopy/tc/strip-all-9/out/strip-all-9.out.shar @@ -9,8 +9,8 @@ # elfcopy.uu # echo x - elfcopy.1.uu -sed 's/^X//' >elfcopy.1.uu << 'END-of-elfcopy.1.uu' -Xbegin 755 elfcopy.1 +sed 's/^X//' >elfcopy.1.uu << 'e4e59173f6354081a9e3a7debde2f069' +Xbegin 644 elfcopy.1 XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````'B!```` XM`````````$``.``'`$``&@`9``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -759,8 +759,8 @@ XMT`M```````#0"P````````\#```````````````````!```````````````` XM````-P```/___V\"`````````.`.0```````X`X```````"@``````````0` XM`````````@`````````"`````````$0```#^__]O`@````````"`#T`````` XM`(`/````````0``````````%`````@````@```````````````````!3```` -XM!`````(`````````P`]```````#`#P```````'@`````````!``````````( -XM`````````!@`````````70````0````"`````````#@00```````.!`````` +XM!````$(`````````P`]```````#`#P```````'@`````````!``````````( +XM`````````!@`````````70````0```!"`````````#@00```````.!`````` XM``"0!@````````0````+````"``````````8`````````&<````!````!@`` XM``````#(%D```````,@6````````$P````````````````````0````````` XM``````````!B`````0````8`````````W!9```````#<%@```````'`$```` @@ -787,10 +787,10 @@ XM``````$````#`````````````````````````*:`````````S@`````````` X7``````````$````````````````````` X` Xend -END-of-elfcopy.1.uu +e4e59173f6354081a9e3a7debde2f069 echo x - elfcopy.uu -sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' -Xbegin 755 elfcopy +sed 's/^X//' >elfcopy.uu << '2151ae8f08071e33d3c60fbc8f2d2844' +Xbegin 644 elfcopy XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -3078,6 +3078,6 @@ XM7U)E9VES=&5R0VQAliba.a.1.uu << 'b253f047a1631a2a184043b6f45926f7' Xbegin 644 liba.a.1 -XM(3QA'0`+F1A=&$`+F)S6#[!C'1"0(```` XM`,=$)`0`````QP0D`````.C\____R<-M97-S86=E,0!M97-S86=E,@```&US @@ -57,7 +57,7 @@ XM9S$@/2`E'0`+F1A=&$`+F)S`````````````````````0`````````(`````$````" XM`````````'@````5```````````````!`````````"@````!```````````` diff --git a/test/elfcopy/tc/strip-all-archive-2/out/strip-all-archive-2.out.shar b/test/elfcopy/tc/strip-all-archive-2/out/strip-all-archive-2.out.shar index 1efbed52ab9b..a5c6f68e6a90 100644 --- a/test/elfcopy/tc/strip-all-archive-2/out/strip-all-archive-2.out.shar +++ b/test/elfcopy/tc/strip-all-archive-2/out/strip-all-archive-2.out.shar @@ -11,22 +11,22 @@ echo x - liblong.a.1.uu sed 's/^X//' >liblong.a.1.uu << '8eb77b0d36e0369a1b3adf0cc5ef193a' Xbegin 644 liblong.a.1 -XM(3QA7'!0`````%```` XMBT4,BU4(`<*A``````^OPEW#``!'0T,Z("A'3E4I(#0N,BXQ(#(P,#'0`+F1A=&$`+F)S6#[`C'1"0$`````,<$)`````#H_/___\G#:&5L;&\L('=O @@ -34,12 +34,12 @@ XM'0`+F1A=&$`+F)Ssections.o.1.uu << 'END-of-sections.o.1.uu' +sed 's/^X//' >sections.o.1.uu << 'eb2ac2808b7045ab3c2faf26922f5e01' Xbegin 644 sections.o.1 -XM?T5,1@(!`0D```````````$`/@`!`````````````````````````!`>```` +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````#`]```` XM`````````$```````$``#0`*`$B+E\````!(A=)T'TB+1B!(.T(@U(QT98`````$B+A\@```!(B49@2(N'R````$B) XM,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D @@ -182,207 +182,207 @@ XM`-L`````00X0A@)%#AA$#B"#`P``-````!P"````````[@8```!"#A!"#AA" XM#B!"#BA!#C!!#CA'#M`!@P>&!HP%C02.`X\"````````+G-Y;71A8@`N'-C;@!E;&9?6YC7W-E8W1I;VYS`'=A`!E;&9?;F5X='-C;@!E;&9?0!S=')N +XM8W!Y`&=E;&9?9V5T`````````.8!`````````@`` +XM`!8```#\__________`!`````````@```!4```#\__________4!```````` +XM"@````,````W``````````0"`````````@```!8```#\_________PX"```` +XM`````@```!4```#\_________Q,"````````"@````,```!5`````````"(" +XM`````````@```!8```#\_________T\"`````````@````\```#\________ +XM_V`"`````````@```!@```#\_________Y<"`````````@```!(```#\____ +XM_____Z@"`````````@```!$```#\_________[H"`````````@```!D```#\ +XM_________]L"`````````@```!4```#\_________^`"````````"@````,` +XM``!R`````````.\"`````````@```!8```#\__________D"`````````@`` +XM`!4```#\__________X"````````"@````,````W``````````T#```````` +XM`@```!8```#\_________Q0#`````````@```!4```#\_________QD#```` +XM````"@````,```".`````````"@#`````````@```!8```#\_________VD# +XM````````"@````,```"E`````````&X#`````````@```!H```#\________ +XM_W8#````````"@````,```"F`````````'L#`````````@```!H```#\____ +XM_____X,#````````"@````,```"N`````````(@#`````````@```!H```#\ +XM_________XT#````````"@````,```"V`````````)4#`````````@```!H` +XM``#\_________[T#````````"@````,```"V`````````/4#`````````@`` +XM`!P```#\_________Q`$`````````@```!T```#\_________V\$```````` +XM`@```!````#\_________[,$`````````@````\```#\_________]H$```` +XM`````@```!$```#\_________P8%`````````@```!4```#\_________PL% +XM````````"@````,```#``````````!H%`````````@```!8```#\________ +XM_Q\%````````"@````,```#8`````````"L%`````````@```!X```#\____ +XM_____S4%`````````@```!4```#\_________SH%````````"@````,````> +XM`````````$D%`````````@```!8```#\_________U,%`````````@```!4` +XM``#\_________U@%````````"@````,```#E`````````&<%`````````@`` +XM`!8```#\_________W$%`````````@```!4```#\_________W8%```````` +XM"@````,````W`````````(4%`````````@```!8```#\_________[4%```` +XM`````@```!````#\__________X%`````````@```"````#\_________PL& +XM`````````@```!D```#\_________U$&`````````@```!4```#\________ +XM_U8&````````"@````,````>`````````&4&`````````@```!8```#\____ +XM_____VP&`````````@```!4```#\_________W$&````````"@````,````# +XM`0```````(`&`````````@```!8```#\_________[T&`````````@````\` +XM``#\_________]$&`````````@````\```#\_________S\'`````````@`` +XM`!$```#\_________W4'`````````@```!4```#\_________WH'```````` +XM"@````,````<`0```````(D'`````````@```!8```#\_________Y,'```` +XM`````@```!4```#\_________Y@'````````"@````,````Z`0```````*<' +XM`````````@```!8```#\_________[$'`````````@```!4```#\________ +XM_[8'````````"@````,```!8`0```````,4'`````````@```!8```#\____ +XM_____TL(`````````@````\```#\_________VX(`````````@```!$```#\ +XM_________[,(````````"@````4``````````````+H(`````````@```",` +XM``#\_________\D(`````````@```!4```#\_________\X(````````"@`` +XM``,```!S`0```````-T(`````````@```!8```#\_________^<(```````` +XM`@```!4```#\_________^P(````````"@````,```!8`0```````/L(```` +XM`````@```!8```#\_________Q$)`````````@```"4```#\_________RD) +XM`````````@```!T```#\_________WH)`````````@```"8```#\________ +XM_[@)`````````@```!4```#\_________[T)````````"@````,```"1`0`` +XM`````,P)`````````@```!8```#\_________]8)`````````@```!4```#\ +XM_________]L)````````"@````,```"Y`0```````.H)`````````@```!8` +XM``#\_________^\)````````"@````,```"K`0```````/L)`````````@`` +XM`!8```#\_________S$*`````````@```"@```#\_________U0*```````` +XM`@```"D```#\_________VL*`````````@```"H```#\_________Y0*```` +XM````"@````,```#1`0```````)X*`````````@```!8```#\_________[<* +XM`````````@```"<```#\_________^<*`````````@```"<```#\________ +XM_T(+````````"@````,```"V`````````&D+````````"@````,```"F```` +XM`````(8+````````"@````,```"N`````````)<+````````"@````,```#C +XM`0```````*(+````````"P````,```#C`0```````*L+````````"P````,` +XM``#J`0```````+0+````````"P````,```#\`0```````+T+````````"P`` +XM``,````"`@```````.(+`````````@```"L```#\__________`+```````` +XM`@```"P```#\_________R(,`````````@```"<```#\_________W\,```` +XM`````@```!T```#\_________Y,,````````"P````,```"V`````````,L, +XM`````````@```"X```#\_________^@,`````````@```"\```#\________ +XM__\,`````````@````\```#\_________QT-`````````@```#````#\____ +XM_____U0-````````"@````,```"V`````````'X-`````````@```!P```#\ +XM_________Y,-`````````@```!(```#\_________[@-````````"@````,` +XM``"F`````````-(-````````"@````,```"N`````````!$.`````````@`` +XM`"X```#\_________RH.`````````@```"\```#\_________SX.```````` +XM`@```!(```#\_________TX.`````````@````\```#\_________VL.```` +XM`````@```#````#\_________YL.`````````@```!T```#\_________]P. +XM`````````@```#$```#\__________<.`````````@```"$```#\________ +XM_P$/`````````@```!D```#\_________Q`/`````````@```!4```#\____ +XM_____Q4/````````"@````,```".`````````"0/`````````@```!8```#\ +XM_________RD/`````````@```!D```#\_________TD/`````````@```!4` +XM``#\_________TX/````````"@````,````_`@```````%T/`````````@`` +XM`!8```#\_________V````$`````````````````````````"I````$``````````````` -XM``````````"Y````$`````````````````````````#!````$``````````` -XM``````````````#,````$`````````````````````````#1````$@`!`#`" -XM````````_`````````#=````$`````````````````````````#K````$``` -XM``````````````````````#U````$``````````````````````````&`0`` -XM$@`!`*`#````````Z0$````````6`0``$``````````````````````````A -XM`0``$``````````````````````````H`0``$``````````````````````` -XM```L`0``$@`!`)`%````````]``````````V`0``$``````````````````` -XM``````!"`0``$@`!`)`&````````.0$```````!,`0``$@`!`-`'```````` -XM+P$```````!<`0``$`````````````````````````!B`0``$@`!```)```` -XM````_P````````!O`0``$`````````````````````````!\`0``$``````` -XM``````````````````"'`0``$@`!```*````````H@````````"6`0``$``` -XM``````````````````````"=`0``$`````````````````````````"D`0`` -XM$`````````````````````````"K`0``$`````````````````````````"R -XM`0``$`````````````````````````"Z`0``$@`!`&`,````````I@,````` -XM``#%`0``$`````````````````````````#5`0``$``````````````````` -XM``````#A`0``$`````````````````````````#L`0``$``````````````` -XM``````````#^`0``$``````````````````````````+`@``$``````````` -XM```````````````5`@``$``````````````````````````:`@``$``````` -XM```````````````````B`@``$@`!`/`0````````[@8````````O`@``$``` -XM```````````````````````]`@``$`````````````````````````!$`@`` -XM$`````````````````````````!,`@``$`````````````````````````!8 -XM`@``$```````````````````````````:6YS97)T7W1O7W-E8U]L:7-T`&%D -XM9%]T;U]S:'-T5]S:&1R`')E`!I;G-EF4`;&]O:W5P7W-E8U]A8W0`'1S8VX`96QF7W-T0!G96QF7V=E=')E;`!L;V]K=7!? -XM:V5E<%]S>6UL:7-T``````"7``````````(````/````_/_________N```` -XM``````(````0````_/________\;`0````````(````1````_/________]9 -XM`0````````(````2````_/________]F`0````````(````3````_/______ -XM__^E`0````````(````4````_/________^T`0````````(````5````_/__ -XM______^Y`0````````H````#``````````````#(`0````````(````6```` -XM_/_________2`0````````(````5````_/_________7`0````````H````# -XM````'@````````#F`0````````(````6````_/_________P`0````````(` -XM```5````_/_________U`0````````H````#````-P`````````$`@`````` -XM``(````6````_/________\.`@````````(````5````_/________\3`@`` -XM``````H````#````50`````````B`@````````(````6````_/________]/ -XM`@````````(````/````_/________]@`@````````(````8````_/______ -XM__^7`@````````(````2````_/________^H`@````````(````1````_/__ -XM______^Z`@````````(````9````_/_________;`@````````(````5```` -XM_/_________@`@````````H````#````<@````````#O`@````````(````6 -XM````_/_________Y`@````````(````5````_/_________^`@````````H` -XM```#````-P`````````-`P````````(````6````_/________\4`P`````` -XM``(````5````_/________\9`P````````H````#````C@`````````H`P`` -XM``````(````6````_/________]I`P````````H````#````I0````````!N -XM`P````````(````:````_/________]V`P````````H````#````I@`````` -XM``![`P````````(````:````_/________^#`P````````H````#````K@`` -XM``````"(`P````````(````:````_/________^-`P````````H````#```` -XMM@````````"5`P````````(````:````_/________^]`P````````H````# -XM````M@````````#U`P````````(````<````_/________\0!`````````(` -XM```=````_/________]O!`````````(````0````_/________^S!``````` -XM``(````/````_/_________:!`````````(````1````_/________\&!0`` -XM``````(````5````_/________\+!0````````H````#````P``````````: -XM!0````````(````6````_/________\?!0````````H````#````V``````` -XM```K!0````````(````>````_/________\U!0````````(````5````_/__ -XM______\Z!0````````H````#````'@````````!)!0````````(````6```` -XM_/________]3!0````````(````5````_/________]8!0````````H````# -XM````Y0````````!G!0````````(````6````_/________]Q!0````````(` -XM```5````_/________]V!0````````H````#````-P````````"%!0`````` -XM``(````6````_/________^U!0````````(````0````_/_________^!0`` -XM``````(````@````_/________\+!@````````(````9````_/________]1 -XM!@````````(````5````_/________]6!@````````H````#````'@`````` -XM``!E!@````````(````6````_/________]L!@````````(````5````_/__ -XM______]Q!@````````H````#`````P$```````"`!@````````(````6```` -XM_/________^]!@````````(````/````_/_________1!@````````(````/ -XM````_/________\_!P````````(````1````_/________]U!P````````(` -XM```5````_/________]Z!P````````H````#````'`$```````")!P`````` -XM``(````6````_/________^3!P````````(````5````_/________^8!P`` -XM``````H````#````.@$```````"G!P````````(````6````_/________^Q -XM!P````````(````5````_/________^V!P````````H````#````6`$````` -XM``#%!P````````(````6````_/________]+"`````````(````/````_/__ -XM______]N"`````````(````1````_/________^S"`````````H````%```` -XM``````````"Z"`````````(````C````_/_________)"`````````(````5 -XM````_/_________."`````````H````#````"@`` -XM``````(````6````_/________^W"@````````(````G````_/_________G -XM"@````````(````G````_/________]""P````````H````#````M@`````` -XM``!I"P````````H````#````I@````````"&"P````````H````#````K@`` -XM``````"7"P````````H````#````XP$```````"B"P````````L````#```` -XMXP$```````"K"P````````L````#````Z@$```````"T"P````````L````# -XM````_`$```````"]"P````````L````#`````@(```````#B"P````````(` -XM```K````_/_________P"P````````(````L````_/________\B#``````` -XM``(````G````_/________]_#`````````(````=````_/________^3#``` -XM``````L````#````M@````````#+#`````````(````N````_/_________H -XM#`````````(````O````_/__________#`````````(````/````_/______ -XM__\=#0````````(````P````_/________]4#0````````H````#````M@`` -XM``````!^#0````````(````<````_/________^3#0````````(````2```` -XM_/________^X#0````````H````#````I@````````#2#0````````H````# -XM````K@`````````1#@````````(````N````_/________\J#@````````(` -XM```O````_/________\^#@````````(````2````_/________].#@`````` -XM``(````/````_/________]K#@````````(````P````_/________^;#@`` -XM``````(````=````_/_________<#@````````(````Q````_/_________W -XM#@````````(````A````_/________\!#P````````(````9````_/______ -XM__\0#P````````(````5````_/________\5#P````````H````#````C@`` -XM```````D#P````````(````6````_/________\I#P````````(````9```` -XM_/________])#P````````(````5````_/________].#P````````H````# -XM````/P(```````!=#P````````(````6````_/________]G#P````````(` -XM```5````_/________]L#P````````H````#````(P(```````![#P`````` -XM``(````6````_/________^%#P````````(````5````_/________^*#P`` -XM``````H````#````@P(```````"9#P````````(````6````_/________^C -XM#P````````(````5````_/________^H#P````````H````#````;0(````` -XM``"W#P````````(````6````_/________^\#P````````H````#````JP$` -XM``````#&#P````````(````>````_/_________0#P````````(````5```` -XM_/_________5#P````````H````#````"`(```````#D#P````````(````6 -XM````_/_________N#P````````(````5````_/_________S#P````````H` -XM```#````50(````````"$`````````(````6````_/________\F$``````` -XM``(````R````_/________\Q$`````````(````S````_/________]E$``` -XM``````(````R````_/________]P$`````````(````S````_/________^D -XM$`````````(````S````_/________^N$`````````(````T````_/______ -XM__^W$`````````(````S````_/________^_$`````````(````T````_/__ -XM_______3$`````````(````U````_/_________B$`````````(````U```` -XM_/________\W$0````````H````#````I@````````!7$0````````(````W -XM````_/________^`$0````````H````#````K@````````"2$0````````H` -XM```#````M@````````#J$0````````(````I````_/________\,$@`````` -XM``(````X````_/________\A$@````````(````@````_/________\[$@`` -XM``````(````I````_/________]9$@````````(````/````_/_________! -XM$@````````(````9````_/________\"$P````````(````I````_/______ -XM__^I$P````````(````K````_/_________!$P````````(````H````_/__ -XM______\)%`````````(````?````_/________\9%`````````(````G```` -XM_/________]@%`````````(````@````_/________]M%`````````(````9 -XM````_/________][%`````````(````R````_/________^*%`````````(` -XM```S````_/_________6%`````````(````Y````_/________\V%0`````` -XM``(````Y````_/________]0%0````````(````G````_/________]<%0`` -XM``````(````K````_/________]T%0````````(````Y````_/________^B -XM%0````````(````X````_/________^W%0````````(````G````_/______ -XM___`%0````````(````K````_/_________4%0````````H````#````O@(` -XM``````#@%0````````(````>````_/_________G%0````````(````S```` -XM_/_________Q%0````````(````T````_/________\E%@````````(````@ -XM````_/________]#%@````````(````Z````_/________]G%@````````(` -XM```2````_/________][%@````````(````P````_/________^1%@`````` -XM``(````[````_/________^J%@````````(````I````_/_________:%@`` -XM``````(````U````_/_________I%@````````(````I````_/________\3 -XM%P````````(````5````_/________\8%P````````H````#`````P$````` -XM```G%P````````(````6````_/________\L%P````````H````#````L`(` -XM```````V%P````````(````>````_/________]`%P````````(````5```` -XM_/________]%%P````````H````#````D0$```````!4%P````````(````6 -XM````_/________]>%P````````(````5````_/________]C%P````````H` -XM```#````/P(```````!R%P````````(````6````_/________]\%P`````` -XM``(````5````_/________^!%P````````H````#````F0(```````"0%P`` -XM``````(````6````_/________^5%P````````(````9````_/_________% -XM%P````````(````F````_/________]A`P````````(````:````_/______ -XM__\@``````````H````!```````````````X``````````H````!````<``` -XM``````!8``````````H````!````,`(```````"```````````H````!```` -XM,`,```````"8``````````H````!````H`,```````#(``````````H````! -XM````D`4```````#H``````````H````!````D`8````````(`0````````H` -XM```!````T`<````````P`0````````H````!``````D```````!0`0`````` -XM``H````!``````H```````!X`0````````H````!````L`H```````"0`0`` -XM``````H````!````X`H```````"H`0````````H````!````(`L```````#( -XM`0````````H````!````8`P``````````@````````H````!````$!`````` -X:```@`@````````H````!````\!`````````` +XM```````````````````````````````@`````0````8````````````````` +XM``!``````````-X7```````````````````0````````````````````&P`` +XM``0```!`````````````````````("8```````"0%0````````L````!```` +XM"``````````8`````````"8````!`````P```````````````````"`8```` +XM``````````````````````````0````````````````````L````"`````,` +XM```````````````````@&``````````````````````````````$```````` +XM````````````,0````$`````````````````````````(!@````````P```` +XM`````````````````0```````````````````#H````!````,@`````````` +XM`````````%`8````````UP(```````````````````$``````````0`````` +XM``!)`````0```#(````````````````````H&P```````"T````````````` +XM```````(``````````$`````````70````$````"```````````````````` +XM6!L```````!0`@``````````````````"````````````````````%@````$ +XM````0````````````````````+`[````````@`$````````+````"`````@` +XM````````&``````````1`````P````````````````````````"H'0`````` +XM`&<````````````````````!`````````````````````0````(````````` +XM````````````````$!X```````"@!0````````P````.````"``````````8 +XM``````````D````#`````````````````````````+`C````````;`(````` +X:``````````````$````````````````````` X` Xend -END-of-sections.o.1.uu +eb2ac2808b7045ab3c2faf26922f5e01 echo x - sections.o.uu -sed 's/^X//' >sections.o.uu << 'END-of-sections.o.uu' +sed 's/^X//' >sections.o.uu << 'f3eccedeeefe85afebc666fca5eb0742' Xbegin 644 sections.o XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@symbols.o.1.uu << 'END-of-symbols.o.1.uu' +sed 's/^X//' >symbols.o.1.uu << '7e9b8d093a79e3138d3b7dc9490f1606' Xbegin 644 symbols.o.1 -XM?T5,1@(!`0D```````````$`/@`!`````````````````````````)`<```` +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````%@O```` XM`````````$```````$``#``)``^V1P3`Z`0L`0^4P`^VP,,/MD<$P.@$A,`/ XME,`/ML##54B)]5-(@^P(2(N?T````$B%VW4+ZR%(BUL(2(7;=!A(BS-(B>_H XM`````(7`=>A(@\0(L`%;7<-(@\0(,6UT86(`+G-T6UL:7-T`'-T`!A -XM9&1?=&]?:V5E<%]L:7-T`&-R96%T95]S>6UT86(`8V]P>5]S:&1R`&=E;&9? -XM9V5T'1S8VX`96QF7W-TF4`96QF7V=E=&1A=&$`9V5L9E]G -XM971S>6T`8V]P>5]D871A`&=E;&9?=7!D871E7W-H9'(`96QF7V5R1$````````"````(````/S_________?A$````````*````!````(P````` -XM````C1$````````"````#0```/S_________2A,````````"````(0```/S_ -XM________=1,````````"````(0```/S_________M1,````````"````#``` -XM`/S_________RA,````````*````!````'X`````````UA,````````"```` -XM)````/S_________]Q,````````"````(0```/S_________4Q0````````" -XM````#````/S_________=A0````````"````(````/S_________>Q0````` -XM```*````!````"(`````````BA0````````"````#0```/S_________E!0` -XM```````"````(````/S_________F10````````*````!`````(!```````` -XMJ!0````````"````#0```/S_________VA0````````"````%````/S_____ -XM____^Q0````````"````$@```/S_________$A4````````"````%0```/S_ -XM________+A4````````"````$0```/S_________8A4````````"````%@`` -XM`/S_________=A4````````"````)0```/S_________B14````````"```` -XM)@```/S_________I14````````"````%P```/S_________[!4````````" -XM````'````/S_________3Q8````````"````)P```/S_________DA8````` -XM```*````!````$8!````````F18````````"````*````/S_________Q!8` -XM```````"````#````/S_________ZA8````````"````#````/S_________ -XM&1<````````"````(0```/S_________,A<````````"````&````/S_____ -XM____5A<````````"````(````/S_________6Q<````````*````!````.L` -XM````````:A<````````"````#0```/S_________?Q<````````"````#``` -XM`/S_________F1<````````*````!````-``````````I1<````````"```` -XM#0```/S_________JA<````````"````&````/S_________PQ<````````" -XM````(````/S_________R!<````````*````!````+D`````````UQ<````` -XM```"````#0```/S_________W!<````````*````!````'``````````YA<` -XM```````"````)````/S_________\!<````````"````(````/S_________ -XM]1<````````*````!````%<`````````!!@````````"````#0```/S_____ -XM____"1@````````*````!````'``````````%1@````````"````)````/S_ -XM________&A@````````*````!````'X`````````)!@````````"````)``` -XM`/S_________+A@````````"````(````/S_________,Q@````````*```` -XM!````#P`````````0A@````````"````#0```/S_________3!@````````" -XM````(````/S_________41@````````*````!````'0!````````8!@````` -XM```"````#0```/S_________D!@````````"````&````/S_________LA@` -XM```````"````#````/S_________[Q@````````"````*0```/S_________ -XM%!D````````"````(````/S_________&1D````````*````!````"\!```` -XM````*!D````````"````#0```/S_________,AD````````"````(````/S_ -XM________-QD````````*````!````!D!````````1AD````````"````#0`` -XM`/S_________(``````````*`````0``````````````.``````````*```` -XM`0```!``````````4``````````*`````0```"``````````<``````````* -XM`````0```'``````````B``````````*`````0```.``````````H``````` -X2```*`````0```%`!```````` +XM```````#``$```````````````````````$````"``$````````````0```` +XM`````!(````"``$`$``````````0```````````````#``8````````````` +XM```````````````#``,````````````````````````````#``0````````` +XM```````````````````#``4````````````````````````````#``<````` +XM`````````````````"(````2``$`(`````````!!`````````#8````0```` +XM`````````````````````#T````2``$`<`````````!F`````````$\````0 +XM`````````````````````````%8````0`````````````````````````%L` +XM```2``$`X`````````!F`````````&P````2``$`4`$```````#Z%P`````` +XM`'H````0`````````````````````````(0````0```````````````````` +XM`````)$````0`````````````````````````*$````0```````````````` +XM`````````*\````0`````````````````````````+8````0```````````` +XM`````````````,(````0`````````````````````````,T````0```````` +XM`````````````````-@````0`````````````````````````.(````0```` +XM`````````````````````.<````0`````````````````````````/,````0 +XM`````````````````````````/X````0``````````````````````````H! +XM```0`````````````````````````!8!```0```````````````````````` +XM`"`!```0`````````````````````````#$!```0```````````````````` +XM`````#P!```0`````````````````````````$0!```0```````````````` +XM`````````$L!```0`````````````````````````%,!```0```````````` +XM`````````````%6UL +XM:7-T`'-T`!A9&1? +XM=&]?:V5E<%]L:7-T`&-R96%T95]S>6UT86(`8V]P>5]S:&1R`&=E;&9?9V5T +XM'1S8VX`96QF7W-TF4`96QF7V=E=&1A=&$`9V5L9E]G971S +XM>6T`8V]P>5]D871A`&=E;&9?=7!D871E7W-H9'(`96QF7V5R1$` +XM```````"````(````/S_________?A$````````*````!````(P````````` +XMC1$````````"````#0```/S_________2A,````````"````(0```/S_____ +XM____=1,````````"````(0```/S_________M1,````````"````#````/S_ +XM________RA,````````*````!````'X`````````UA,````````"````)``` +XM`/S_________]Q,````````"````(0```/S_________4Q0````````"```` +XM#````/S_________=A0````````"````(````/S_________>Q0````````* +XM````!````"(`````````BA0````````"````#0```/S_________E!0````` +XM```"````(````/S_________F10````````*````!`````(!````````J!0` +XM```````"````#0```/S_________VA0````````"````%````/S_________ +XM^Q0````````"````$@```/S_________$A4````````"````%0```/S_____ +XM____+A4````````"````$0```/S_________8A4````````"````%@```/S_ +XM________=A4````````"````)0```/S_________B14````````"````)@`` +XM`/S_________I14````````"````%P```/S_________[!4````````"```` +XM'````/S_________3Q8````````"````)P```/S_________DA8````````* +XM````!````$8!````````F18````````"````*````/S_________Q!8````` +XM```"````#````/S_________ZA8````````"````#````/S_________&1<` +XM```````"````(0```/S_________,A<````````"````&````/S_________ +XM5A<````````"````(````/S_________6Q<````````*````!````.L````` +XM````:A<````````"````#0```/S_________?Q<````````"````#````/S_ +XM________F1<````````*````!````-``````````I1<````````"````#0`` +XM`/S_________JA<````````"````&````/S_________PQ<````````"```` +XM(````/S_________R!<````````*````!````+D`````````UQ<````````" +XM````#0```/S_________W!<````````*````!````'``````````YA<````` +XM```"````)````/S_________\!<````````"````(````/S_________]1<` +XM```````*````!````%<`````````!!@````````"````#0```/S_________ +XM"1@````````*````!````'``````````%1@````````"````)````/S_____ +XM____&A@````````*````!````'X`````````)!@````````"````)````/S_ +XM________+A@````````"````(````/S_________,Q@````````*````!``` +XM`#P`````````0A@````````"````#0```/S_________3!@````````"```` +XM(````/S_________41@````````*````!````'0!````````8!@````````" +XM````#0```/S_________D!@````````"````&````/S_________LA@````` +XM```"````#````/S_________[Q@````````"````*0```/S_________%!D` +XM```````"````(````/S_________&1D````````*````!````"\!```````` +XM*!D````````"````#0```/S_________,AD````````"````(````/S_____ +XM____-QD````````*````!````!D!````````1AD````````"````#0```/S_ +XM________(``````````*`````0``````````````.``````````*`````0`` +XM`!``````````4``````````*`````0```"``````````<``````````*```` +XM`0```'``````````B``````````*`````0```.``````````H``````````* +XM`````0```%`!```````````````````````````````````````````````` +XM`````````````````````````````````````````````"`````!````!@`` +XM`````````````````$``````````2AD``````````````````!`````````` +XM```````````;````!````$`````````````````````@(@```````*@,```` +XM````"@````$````(`````````!@`````````)@````$````#```````````` +XM````````C!D`````````````````````````````!``````````````````` +XM`"P````(`````P```````````````````(P9```````````````````````` +XM``````0````````````````````Q`````0````````````````````````", +XM&0```````#`````````````````````!````````````````````.@````$` +XM```R````````````````````O!D```````"L`0```````````````````0`` +XM```````!`````````$X````!`````@```````````````````&@;```````` +XMT`````````````````````@```````````````````!)````!````$`````` +XM``````````````#(+@```````)``````````"@````<````(`````````!@` +XM````````$0````,`````````````````````````.!P```````!8```````` +XM`````````````0````````````````````$````"```````````````````` +XM`````)`<````````\`,````````+````"0````@`````````&``````````) +XM`````P````````````````````````"`(````````)P!```````````````` +X2```!```````````````````` X` Xend -END-of-symbols.o.1.uu +7e9b8d093a79e3138d3b7dc9490f1606 echo x - symbols.o.uu -sed 's/^X//' >symbols.o.uu << 'END-of-symbols.o.uu' +sed 's/^X//' >symbols.o.uu << '4a9e1967a3d1d330020ec46c822fc6a0' Xbegin 644 symbols.o XM?T5,1@(!`0D```````````$`/@`!`````````````````````````,!C```` XM`````````$```````$``&@`7``^V1P3`Z`0L`0^4P`^VP,,/MD<$P.@$A,`/ @@ -1202,6 +1202,6 @@ XM```*````!@``````````````!@`````````*````!@``````````````$``` X5```````!`````@`````````````` X` Xend -END-of-symbols.o.uu +4a9e1967a3d1d330020ec46c822fc6a0 exit diff --git a/test/elfcopy/tc/strip-debug-3/out/strip-debug-3.out.shar b/test/elfcopy/tc/strip-debug-3/out/strip-debug-3.out.shar index a3ffa9c4b433..c4937a3302ea 100644 --- a/test/elfcopy/tc/strip-debug-3/out/strip-debug-3.out.shar +++ b/test/elfcopy/tc/strip-debug-3/out/strip-debug-3.out.shar @@ -9,8 +9,8 @@ # ls.uu # echo x - ls.1.uu -sed 's/^X//' >ls.1.uu << 'END-of-ls.1.uu' -Xbegin 755 ls.1 +sed 's/^X//' >ls.1.uu << 'd7b52e16e66a16e1176ab066b800c102' +Xbegin 444 ls.1 XM?T5,1@(!`0D```````````(`/@`!````H!M```````!``````````#!M```` XM`````````$``.``'`$``&@`9``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -643,9 +643,9 @@ XM`````!@`````````+P````,````"`````````%@,0```````6`P````````1 XM`P```````````````````0```````````````````#<```#___]O`@`````` XM``!J#T```````&H/````````J@`````````$``````````(``````````@`` XM``````!$````_O__;P(`````````&!!````````8$````````#`````````` -XM!0````$````(````````````````````4P````0````"`````````$@00``` +XM!0````$````(````````````````````4P````0```!"`````````$@00``` XM````2!````````"0``````````0`````````"``````````8`````````%T` -XM```$`````@````````#8$$```````-@0````````8`8````````$````"P`` +XM```$````0@````````#8$$```````-@0````````8`8````````$````"P`` XM``@`````````&`````````!G`````0````8`````````.!=````````X%P`` XM`````!,````````````````````$````````````````````8@````$````& XM`````````$P70```````3!<```````!0!```````````````````!``````` @@ -672,10 +672,10 @@ XM``````````````!?;````````,X````````````````````!```````````` X&```````` X` Xend -END-of-ls.1.uu +d7b52e16e66a16e1176ab066b800c102 echo x - ls.uu -sed 's/^X//' >ls.uu << 'END-of-ls.uu' -Xbegin 555 ls +sed 's/^X//' >ls.uu << '4db11c737631d887608e3186a17a7a3e' +Xbegin 444 ls XM?T5,1@(!`0D```````````(`/@`!````H!M```````!``````````#!M```` XM`````````$``.``'`$``&@`9``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -1337,6 +1337,6 @@ XM``````````````!?;````````,X````````````````````!```````````` X&```````` X` Xend -END-of-ls.uu +4db11c737631d887608e3186a17a7a3e exit diff --git a/test/elfcopy/tc/strip-debug-4/out/strip-debug-4.out.shar b/test/elfcopy/tc/strip-debug-4/out/strip-debug-4.out.shar index 0f80086e27ec..59d47aa55b4c 100644 --- a/test/elfcopy/tc/strip-debug-4/out/strip-debug-4.out.shar +++ b/test/elfcopy/tc/strip-debug-4/out/strip-debug-4.out.shar @@ -9,9 +9,9 @@ # elfcopy.uu # echo x - elfcopy.1.uu -sed 's/^X//' >elfcopy.1.uu << 'END-of-elfcopy.1.uu' -Xbegin 755 elfcopy.1 -XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````(B!```` +sed 's/^X//' >elfcopy.1.uu << 'e4e59173f6354081a9e3a7debde2f069' +Xbegin 644 elfcopy.1 +XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````("9```` XM`````````$``.``'`$``'``9``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` XM`,@!0```````R`%````````5`````````!4``````````0`````````!```` @@ -748,188 +748,189 @@ XM87-H`"YD>6YS>6T`+F1Y;G-T<@`N9VYU+G9E6YA;6EC`"YC XM=&]RE`````` -XM`*!Z````````H`$````````%``````````@`````````$`````````"X```` -XM`0````,`````````0'Q0``````!`?````````!`````````````````````( -XM````````````````````OP````$````#`````````%!\4```````4'P````` -XM```0````````````````````"````````````````````,8````!`````P`` -XM``````!@?%```````&!\````````"`````````````````````@````````` -XM``````````#+`````0````,`````````:'Q0``````!H?````````$@"```` -XM```````````````(``````````@`````````T`````@````#`````````+!^ -XM4```````L'X````````P````````````````````"``````````````````` -XM`-4````!`````````````````````````+!^````````]@$````````````` -XM``````$````````````````````1`````P````````````````````````"F -XM@````````-X````````````````````!`````````````````````0````(` -XM````````````````````````B(@`````````#P```````!L````S````"``` -XM```````8``````````D````#`````````````````````````(B7```````` -XM\P@```````````````````$````````````````````````````````````` -XM```````````````!`````0`"`.`!0```````&``````````(`````0`3`$!\ -XM4``````````````````6`````0`4`%!\4``````````````````D`````0`5 -XM`&!\4``````````````````Q`````@`,`/`;0`````````````````!'```` -XM`0`7`-1^4````````0````````!6`````0`0`'!R4`````````````````!= -XM`````@`,`#`<0`````````````````!I`````0`3`$A\4``````````````` -XM``!V`````0`4`%A\4`````````````````"#`````0`1`&AZ4``````````` -XM``````"1`````0`5`&!\4`````````````````"=`````@`,`!!I0``````` -XM``````````"S`````@`,`&`<0```````*0````````"_`````@`,`)`<0``` -XM````*0````````#)`````@`,`,`<0```````*0````````#7`````@`,`/`< -XM0```````CP8```````#C`````0`0`,!S4```````H`$```````#T`````0`0 -XM`(!R4```````0`$````````#`0```@`,`/`K0```````?0`````````6`0`` -XM`@`,`$`O0```````:P`````````F`0```@`,`-`V0```````(@`````````Z -XM`0```@`,```W0```````-P````````!,`0```@`,`-`\0```````VP`````` -XM``!7`0```@`,`)!-0```````$`````````!H`0```@`,`*!-0```````$``` -XM`````````````P`!`,@!0````````````````````````P`"`.`!0``````` -XM`````````````````P`#`/@!0````````````````````````P`$`%`$0``` -XM`````````````````````P`%`-`+0````````````````````````P`&`.`. -XM0````````````````````````P`'`(`/0````````````````````````P`( -XM`,`/0````````````````````````P`)`#@00``````````````````````` -XM`P`*`,@60````````````````````````P`+`-P60``````````````````` -XM`````P`,`%`;0````````````````````````P`-`#AI0``````````````` -XM`````````P`.`$AI0````````````````````````P`/`$1R0``````````` -XM`````````````P`0`&!R4````````````````````````P`1`&!U4``````` -XM`````````````````P`2`*!Z4````````````````````````P`3`$!\4``` -XM`````````````````````P`4`%!\4````````````````````````P`5`&!\ -XM4````````````````````````P`6`&A\4````````````````````````P`7 -XM`+!^4````````````````````````P`8``````````````````````!X`0`` -XM$@`,`"`U0```````_P````````"%`0``$@`,`*`Q0```````]`````````"/ -XM`0``$@```.P60```````D`````````"A`0``$@```/P60```````AP`````` -XM``"[`0``$@````P70```````%P$```````#2`0``$@```!P70```````314` -XM``````#G`0``$@`,`*`R0```````.0$```````#Q`0``$@```"P70``````` -XM?`$````````"`@``$@`,`'!.0```````9@`````````3`@``$0`2`*!Z4``` -XM```````````````<`@``$@```#P70```````V@(````````R`@``$@```$P7 -XM0```````G@````````!!`@``$@```%P70```````-`````````!3`@``$@`` -XM`&P70```````50````````!D`@``$@`,`)`X0```````%0$```````!X`@`` -XM$@`,`+`]0```````TPL```````"%`@``$@```'P70```````Y0````````"; -XM`@``$@`,`.!F0```````CP````````"I`@``$@```(P70```````B@`````` -XM``"Y`@``$@```)P70`````````````````#*`@``$@```*P70```````:@`` -XM``````#A`@``$0(0`&AR4`````````````````#N`@``$@```+P70``````` -XMX@`````````#`P``$@`,`.!.0```````^A<````````1`P``$@```,P70``` -XM````C`$````````K`P``$@`,`+`O0```````X@$````````[`P``$@```-P7 -XM0````````@````````!/`P``$@```.P70```````AP8```````!A`P``$@`` -XM`/P70```````.P````````!W`P``$@````P80```````&0$```````".`P`` -XM$@`,`.`S0```````.@$```````">`P``$@`*`,@60`````````````````"D -XM`P``$@```!P80```````)`````````"[`P``$@```"P80```````B``````` -XM``#*`P``$0`7`-A^4```````"`````````#2`P``$@```#P80```````3``` -XM``````#D`P``$@```$P80```````*0````````#U`P``$@```%P80``````` -XM-0`````````*!```$@```&P80```````:0$````````?!```$@```'P80``` -XM````:@`````````Y!```$0`7`+!^4```````!`````````!0!```$@```(P8 -XM0```````K0(```````!A!```$@```)P80```````%@````````!T!```$0`0 -XM`&!R4```````"`````````!_!```$@`,`"`V0```````H@````````".!``` -XM$@`,`%`;0```````DP````````"5!```$@```*P80```````E0````````"E -XM!```$@```+P80`````````````````"T!```$0`7`+A^4```````"``````` -XM``#%!```$@```,P80`````````````````#6!```$@```-P80```````2P`` -XM``````#L!```$@```.P80```````K`$````````'!0``$@`,`#`N0``````` -XM!P$````````3!0``$@`,`'!*0```````[@$````````=!0``$@`,`'!G0``` -XM````GP$````````N!0``$@```/P80```````*`````````!%!0``$@````P9 -XM0```````C`$```````!;!0``$@```!P90`````````````````!L!0``$@`` -XM`"P90```````-@````````""!0``$`#Q_[!^4`````````````````".!0`` -XM$@```#P90```````"P````````"D!0``$@```$P90`````````````````"T -XM!0``$@`,`(`C0```````<`@```````"Y!0``$@```%P90```````C0$````` -XM``#0!0``$@```&P90```````2@$```````#A!0``$@```'P90```````:@`` -XM``````#X!0``$@```(P90```````Z@`````````(!@``$@`,`'`L0``````` -XMM@$````````5!@``$@`,`+!-0```````00`````````I!@``$@```)P90``` -XM````A`$```````!`!@``$@```*P90```````XP$```````!4!@``$@```+P9 -XM0```````90````````!E!@``$@`-`#AI0`````````````````!K!@``$0`7 -XM`,!^4```````"`````````!_!@``$@```,P90```````#`````````"7!@`` -XM$@```-P90`````````````````"H!@``$@```.P90```````R@````````"Y -XM!@``$@```/P90```````2@$```````#.!@``$@````P:0```````)0`````` -XM``#@!@``$@```!P:0`````````````````#O!@``$@```"P:0``````````` -XM```````!!P``$@```#P:0```````Y@`````````3!P``$@```$P:0``````` -XMP0$````````N!P``$@```%P:0```````+P`````````]!P``$@```&P:0``` -XM````KP````````!.!P``$@```'P:0```````%P````````!B!P``$@`,`$`W -XM0```````20$```````!T!P``$@```(P:0```````J@````````""!P``$@`` -XM`)P:0```````*@$```````"4!P``$`#Q_[!^4`````````````````";!P`` -XM$@```*P:0`````````````````"L!P``$0`6`&A\4`````````````````#" -XM!P``$`#Q_^!^4`````````````````#'!P``$@```+P:0```````\@`````` -XM``#8!P``$0`7`,A^4```````"`````````#L!P``$@```,P:0```````=@`` -XM``````#[!P``$0`7`-!^4```````!``````````,"```$@```-P:0``````` -XM+P`````````="```$@`,``!.0```````9@`````````O"```$@`,`)!)0``` -XM````V0````````!!"```$@```.P:0```````'@````````!2"```$@```/P: -XM0```````N0$```````!M"```$@````P;0```````(0````````"""```$@`` -XM`!P;0```````0!?7T-43U)?14Y$7U\`7U]$5$]27T5.1%]?`%]? -XM1E)!345?14Y$7U\`7U]*0U)?14Y$7U\`7U]D;U]G;&]B86Q?8W1O6UB;VP`:6YS97)T7W-H=&%B`&-O<'E?9&%T80!F<')I -XM;G1F0$!&0E-$7S$N,`!E;&9?5]S -XM:&1R`&=E=&5N=D!`1D)31%\Q+C``861D7W1O7VME97!?;&ES=`!?1%E.04U) -XM0P!E;&9?9V5T9&%T84!`1D)31%\Q+C``<'5T8T!`1D)31%\Q+C``'1S8VY`0$9"4T1?,2XP`&=E;&9?9V5T6YC7W-E8W1I;VYS`%]I;FET`&=E;&9?;F5W<&AD -XM$!`1D)31%\Q+C``96YV:7)O;@!S=')N8W!Y0$!& -XM0E-$7S$N,`!S=')C:')`0$9"4T1?,2XP`&=E;&9?9G-I>F5`0$9"4T1?,2XP -XM`&5L9E]S=')P=')`0$9"4T1?,2XP`&5L9E]G971S:'-T$!`1D)31%\Q -XM+C``7U]I$!`1D)31%\Q+C``6UL -XM:7-T`&=E;&9?9V5T`````````$$"```2````7!=````````T```````` +XM`%,"```2````;!=```````!5`````````&0"```2``P`D#A````````5`0`` +XM`````'@"```2``P`L#U```````#3"P```````(4"```2````?!=```````#E +XM`````````)L"```2``P`X&9```````"/`````````*D"```2````C!=````` +XM``"*`````````+D"```2````G!=``````````````````,H"```2````K!=` +XM``````!J`````````.$"```1`A``:')0`````````````````.X"```2```` +XMO!=```````#B``````````,#```2``P`X$Y```````#Z%P```````!$#```2 +XM````S!=```````",`0```````"L#```2``P`L"]```````#B`0```````#L# +XM```2````W!=````````"`````````$\#```2````[!=```````"'!@`````` +XM`&$#```2````_!=````````[`````````'<#```2````#!A````````9`0`` +XM`````(X#```2``P`X#-````````Z`0```````)X#```2``H`R!9````````` +XM`````````*0#```2````'!A````````D`````````+L#```2````+!A````` +XM``"(`````````,H#```1`!<`V'Y0```````(`````````-(#```2````/!A` +XM``````!,`````````.0#```2````3!A````````I`````````/4#```2```` +XM7!A````````U``````````H$```2````;!A```````!I`0```````!\$```2 +XM````?!A```````!J`````````#D$```1`!<`L'Y0```````$`````````%`$ +XM```2````C!A```````"M`@```````&$$```2````G!A````````6```````` +XM`'0$```1`!``8')0```````(`````````'\$```2``P`(#9```````"B```` +XM`````(X$```2``P`4!M```````"3`````````)4$```2````K!A```````"5 +XM`````````*4$```2````O!A``````````````````+0$```1`!<`N'Y0```` +XM```(`````````,4$```2````S!A``````````````````-8$```2````W!A` +XM``````!+`````````.P$```2````[!A```````"L`0````````<%```2``P` +XM,"Y````````'`0```````!,%```2``P`<$I```````#N`0```````!T%```2 +XM``P`<&=```````"?`0```````"X%```2````_!A````````H`````````$4% +XM```2````#!E```````",`0```````%L%```2````'!E````````````````` +XM`&P%```2````+!E````````V`````````((%```0`/'_L'Y0```````````` +XM`````(X%```2````/!E````````+`````````*0%```2````3!E````````` +XM`````````+0%```2``P`@"-```````!P"````````+D%```2````7!E````` +XM``"-`0```````-`%```2````;!E```````!*`0```````.$%```2````?!E` +XM``````!J`````````/@%```2````C!E```````#J``````````@&```2``P` +XM<"Q```````"V`0```````!4&```2``P`L$U```````!!`````````"D&```2 +XM````G!E```````"$`0```````$`&```2````K!E```````#C`0```````%0& +XM```2````O!E```````!E`````````&4&```2``T`.&E````````````````` +XM`&L&```1`!<`P'Y0```````(`````````'\&```2````S!E````````,```` +XM`````)<&```2````W!E``````````````````*@&```2````[!E```````#* +XM`````````+D&```2````_!E```````!*`0```````,X&```2````#!I````` +XM```E`````````.`&```2````'!I``````````````````.\&```2````+!I` +XM``````````````````$'```2````/!I```````#F`````````!,'```2```` +XM3!I```````#!`0```````"X'```2````7!I````````O`````````#T'```2 +XM````;!I```````"O`````````$X'```2````?!I````````7`````````&(' +XM```2``P`0#=```````!)`0```````'0'```2````C!I```````"J```````` +XM`(('```2````G!I````````J`0```````)0'```0`/'_L'Y0```````````` +XM`````)L'```2````K!I``````````````````*P'```1`!8`:'Q0```````` +XM`````````,('```0`/'_X'Y0`````````````````,<'```2````O!I````` +XM``#R`````````-@'```1`!<`R'Y0```````(`````````.P'```2````S!I` +XM``````!V`````````/L'```1`!<`T'Y0```````$``````````P(```2```` +XMW!I````````O`````````!T(```2``P``$Y```````!F`````````"\(```2 +XM``P`D$E```````#9`````````$$(```2````[!I````````>`````````%(( +XM```2````_!I```````"Y`0```````&T(```2````#!M````````A```````` +XM`(((```2````'!M```````!S`0```````)T(```@```````````````````` +XM`````+$(```2````+!M````````+`````````,<(```2``P`8$Q````````E +XM`0```````-((```2````/!M```````!H`0```````.@(```2``P`L#E````` +XM```5`P````````!A8FET86<`7U]#5$]27TQ)4U1?7P!?7T143U)?3$E35%]? +XM`%]?2D-27TQ)4U1?7P!?7V1O7V=L;V)A;%]D=&]R5]L;VYG;W!T5]D +XM871A`&9P$!`1D)31%\Q +XM+C``9V5L9E]G971E:&1R0$!&0E-$7S$N,`!E;&9?=7!D871E0$!&0E-$7S$N +XM,`!C;W!Y7W-H9'(`9V5T96YV0$!&0E-$7S$N,`!A9&1?=&]?:V5E<%]L:7-T +XM`%]$64Y!34E#`&5L9E]G971D871A0$!&0E-$7S$N,`!P=71C0$!&0E-$7S$N +XM,`!S=')N8VUP0$!&0E-$7S$N,`!S=')D=7!`0$9"4T1?,2XP`&ES7W)E;6]V +XM95]R96QO8U]S96,`8V]P>5]C;VYT96YT`&5L9E]N97=D871A0$!&0E-$7S$N +XM,`!L;V]K=7!?6UT86(`9V5L9E]U<&1A=&5?6U`0$9"4T1?,2XP`'-T4!`1D)31%\Q+C``7T=,3T)! +XM3%]/1D93151?5$%"3$5?`%]E;F0`9F-L;W-E0$!&0E-$7S$N,`!?7W-T9&5R +XM&ET0$!&0E-$7S$N,`!A9&1?=&]?``````````$``````````@`````````&``````` +XM``!M````!````$(`````````.!!````````X$````````)`&````````!``` +XM``L````(`````````!@`````````=P````$````&`````````,@60``````` +XMR!8````````3````````````````````!````````````````````'(````! +XM````!@````````#<%D```````-P6````````<`0```````````````````0` +XM````````$`````````!]`````0````8`````````4!M```````!0&P`````` +XM`.A-```````````````````0````````````````````@P````$````&```` +XM`````#AI0```````.&D````````.````````````````````!``````````` +XM`````````(D````!`````@````````!(:4```````$AI````````_`@````` +XM``````````````@```````````````````"1`````0````(`````````1')` +XM``````!$<@````````@````````````````````$```````````````````` +XMGP````$````#`````````&!R4```````8'(``````````P`````````````` +XM````(````````````````````*4````!`````@````````!@=5```````&!U +XM````````0`4```````````````````@```````````````````"O````!@`` +XM``,`````````H'I0``````"@>@```````*`!````````!0`````````(```` +XM`````!``````````N`````$````#`````````$!\4```````0'P````````0 +XM````````````````````"````````````````````+\````!`````P`````` +XM``!0?%```````%!\````````$`````````````````````@````````````` +XM``````#&`````0````,`````````8'Q0``````!@?`````````@````````` +XM```````````(````````````````````RP````$````#`````````&A\4``` +XM````:'P```````!(`@``````````````````"``````````(`````````-`` +XM```(`````P````````"P?E```````+!^````````,``````````````````` +XM``@```````````````````#5`````0````````````````````````"P?@`` +XM`````/8!```````````````````!````````````````````$0````,````` +XM````````````````````IH````````#>`````````````````````0`````` +XM``````````````$````"`````````````````````````(B!``````````\` +XM```````;````,P````@`````````&``````````)`````P`````````````` +XM``````````"(D````````/,(```````````````````!```````````````` +X#```` X` Xend -END-of-elfcopy.1.uu +e4e59173f6354081a9e3a7debde2f069 echo x - elfcopy.uu -sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' -Xbegin 755 elfcopy +sed 's/^X//' >elfcopy.uu << '2151ae8f08071e33d3c60fbc8f2d2844' +Xbegin 644 elfcopy XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -3217,6 +3218,6 @@ XM7U)E9VES=&5R0VQAsections.o.1.uu << 'END-of-sections.o.1.uu' +sed 's/^X//' >sections.o.1.uu << 'eb2ac2808b7045ab3c2faf26922f5e01' Xbegin 644 sections.o.1 -XM?T5,1@(!`0D```````````$`/@`!`````````````````````````/!3```` +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````(B?```` XM`````````$```````$``&P`8``$1`24.$PL##AL.$0$2`1`&```")``+"SX+ XM`PX```,6``,..@L["TD3```$)``+"SX+`P@```4D``L+/@L```8/``L+```' XM#P`+"TD3```()@!)$P``"1,!`PX+"SH+.PL!$P``"@T``PXZ"SL+21,X"@`` @@ -489,479 +489,479 @@ XM=6=?;&EN90`N8V]M;65N=``N%P`````````````````` -XM$````````````````````!L````$`````````````````````````+AC```` -XM````D!4````````9`````0````@`````````&``````````F````"`````,` -XM``````````````````!````````````````````````````````$```````` -XM````````````+`````@````#````````````````````0``````````````` -XM````````````````!````````````````````#$````!```````````````` -XM`````````$``````````=0,```````````````````$````````````````` -XM``!$`````0````````````````````````"U`P````````(9```````````` -XM```````!````````````````````/P````0````````````````````````` -XM2'D````````@*````````!D````&````"``````````8`````````%4````! -XM`````````````````````````+<<````````@@0```````````````````$` -XM``````````````````!0````!`````````````````````````!HH0`````` -XM`!@`````````&0````@````(`````````!@`````````80````$````````` -XM````````````````.2$````````P`````````````````````0`````````` -XM`````````&H````(````,@```````````````````&DA````````UP(````` -XM``````````````$``````````0````````!Y````"````#(````````````` -XM``````!P(0```````"T````````````````````(``````````$````````` -XMC0````$`````````````````````````<"$```````#(`@`````````````` -XM````"````````````````````(@````$`````````````````````````("A -XM``````````,````````9````#0````@`````````&`````````"?````"``` -XM``(````````````````````X)````````%`"```````````````````(```` -XM````````````````F@````0`````````````````````````@*0```````"` -XM`0```````!D````/````"``````````8`````````*D````!```````````` -XM`````````````#@D````````#AX```````````````````$````````````` -XM``````"Y`````0````````````````````````!&0@```````+L````````` -XM```````````!````````````````````M`````0````````````````````` -XM`````*8````````8`````````!D````2````"``````````8`````````,X` -XM```!``````````````````````````%#````````,``````````````````` -XM``$```````````````````#)````!``````````````````````````8I@`` -XM`````#``````````&0```!0````(`````````!@`````````W0````$````` -XM````````````````````,4,```````#@!@```````````````````0`````` -XM`````````````.L````!````,````````````````````!%*````````Z`@` -XM``````````````````$``````````0`````````1`````P`````````````` -XM``````````#Y4@```````/8````````````````````!```````````````` -XM`````0````(`````````````````````````L%H```````"0!@```````!H` -XM```8````"``````````8``````````D````#```````````````````````` -XM`$!A````````=P(```````````````````$````````````````````````` -XM```````````````````````````!````!`#Q_P`````````````````````` -XM`````P`!`````````````````````````````P`#```````````````````` -XM`````````P`$`````````````````````````````P`%```````````````` -XM`````````````P`&`````````````````````````````P`(```````````` -XM```````````,`````@`!````````````<````````````````P`+```````` -XM```````````````?`````@`!`#`#````````:P```````````````P`,```` -XM```````````````````O`````@`!`+`*````````(@````````!#`````@`! -XM`.`*````````-P````````!5`````@`!`"`+````````0`$```````!G```` -XM`@`!`!`0````````VP```````````````P`-```````````````````````` -XM`````P`/`````````````````````````````P`1```````````````````` -XM`````````P`2`````````````````````````````P`4```````````````` -XM`````````````P`6`````````````````````````````P`7```````````` -XM`````````````````P`*``````````````````````!R````$@`!`'`````` -XM````M@$```````!_````$`````````````````````````",````$``````` -XM``````````````````"8````$`````````````````````````"I````$``` -XM``````````````````````"T````$`````````````````````````#$```` -XM$`````````````````````````#,````$`````````````````````````#7 -XM````$`````````````````````````#<````$@`!`#`"````````_``````` -XM``#H````$`````````````````````````#V````$``````````````````` -XM`````````0``$``````````````````````````1`0``$@`!`*`#```````` -XMZ0$````````A`0``$``````````````````````````L`0``$``````````` -XM```````````````S`0``$``````````````````````````W`0``$@`!`)`% -XM````````]`````````!!`0``$`````````````````````````!-`0``$@`! -XM`)`&````````.0$```````!7`0``$@`!`-`'````````+P$```````!G`0`` -XM$`````````````````````````!M`0``$@`!```)````````_P````````!Z -XM`0``$`````````````````````````"'`0``$``````````````````````` -XM``"2`0``$@`!```*````````H@````````"A`0``$``````````````````` -XM``````"H`0``$`````````````````````````"O`0``$``````````````` -XM``````````"V`0``$`````````````````````````"]`0``$``````````` -XM``````````````#%`0``$@`!`&`,````````I@,```````#0`0``$``````` -XM``````````````````#@`0``$`````````````````````````#L`0``$``` -XM``````````````````````#W`0``$``````````````````````````)`@`` -XM$``````````````````````````6`@``$``````````````````````````@ -XM`@``$``````````````````````````E`@``$``````````````````````` -XM```M`@``$@`!`/`0````````[@8````````Z`@``$``````````````````` -XM``````!(`@``$`````````````````````````!/`@``$``````````````` -XM``````````!7`@``$`````````````````````````!C`@``$``````````` -XM````````````````'-C;@!E;&9?6YC -XM7W-E8W1I;VYS`'=A`!E;&9? -XM;F5X='-C;@!E;&9?0!S=')N8W!Y`&=E;&9?9V5T -XM`````````.8!`````````@```"````#\__________`!`````````@```!\` -XM``#\__________4!````````"@````D````W``````````0"`````````@`` -XM`"````#\_________PX"`````````@```!\```#\_________Q,"```````` -XM"@````D```!5`````````"("`````````@```"````#\_________T\"```` -XM`````@```!D```#\_________V`"`````````@```"(```#\_________Y<" -XM`````````@```!P```#\_________Z@"`````````@```!L```#\________ -XM_[H"`````````@```",```#\_________]L"`````````@```!\```#\____ -XM_____^`"````````"@````D```!R`````````.\"`````````@```"````#\ -XM__________D"`````````@```!\```#\__________X"````````"@````D` -XM```W``````````T#`````````@```"````#\_________Q0#`````````@`` -XM`!\```#\_________QD#````````"@````D```".`````````"@#```````` -XM`@```"````#\_________VD#````````"@````D```"E`````````&X#```` -XM`````@```"0```#\_________W8#````````"@````D```"F`````````'L# -XM`````````@```"0```#\_________X,#````````"@````D```"N```````` -XM`(@#`````````@```"0```#\_________XT#````````"@````D```"V```` -XM`````)4#`````````@```"0```#\_________[T#````````"@````D```"V -XM`````````/4#`````````@```"8```#\_________Q`$`````````@```"<` -XM``#\_________V\$`````````@```!H```#\_________[,$`````````@`` -XM`!D```#\_________]H$`````````@```!L```#\_________P8%```````` -XM`@```!\```#\_________PL%````````"@````D```#``````````!H%```` -XM`````@```"````#\_________Q\%````````"@````D```#8`````````"L% -XM`````````@```"@```#\_________S4%`````````@```!\```#\________ -XM_SH%````````"@````D````>`````````$D%`````````@```"````#\____ -XM_____U,%`````````@```!\```#\_________U@%````````"@````D```#E -XM`````````&<%`````````@```"````#\_________W$%`````````@```!\` -XM``#\_________W8%````````"@````D````W`````````(4%`````````@`` -XM`"````#\_________[4%`````````@```!H```#\__________X%```````` -XM`@```"H```#\_________PL&`````````@```",```#\_________U$&```` -XM`````@```!\```#\_________U8&````````"@````D````>`````````&4& -XM`````````@```"````#\_________VP&`````````@```!\```#\________ -XM_W$&````````"@````D````#`0```````(`&`````````@```"````#\____ -XM_____[T&`````````@```!D```#\_________]$&`````````@```!D```#\ -XM_________S\'`````````@```!L```#\_________W4'`````````@```!\` -XM``#\_________WH'````````"@````D````<`0```````(D'`````````@`` -XM`"````#\_________Y,'`````````@```!\```#\_________Y@'```````` -XM"@````D````Z`0```````*<'`````````@```"````#\_________[$'```` -XM`````@```!\```#\_________[8'````````"@````D```!8`0```````,4' -XM`````````@```"````#\_________TL(`````````@```!D```#\________ -XM_VX(`````````@```!L```#\_________[,(````````"@````L````````` -XM`````+H(`````````@```"T```#\_________\D(`````````@```!\```#\ -XM_________\X(````````"@````D```!S`0```````-T(`````````@```"`` -XM``#\_________^<(`````````@```!\```#\_________^P(````````"@`` -XM``D```!8`0```````/L(`````````@```"````#\_________Q$)```````` -XM`@```"\```#\_________RD)`````````@```"<```#\_________WH)```` -XM`````@```#````#\_________[@)`````````@```!\```#\_________[T) -XM````````"@````D```"1`0```````,P)`````````@```"````#\________ -XM_]8)`````````@```!\```#\_________]L)````````"@````D```"Y`0`` -XM`````.H)`````````@```"````#\_________^\)````````"@````D```"K -XM`0```````/L)`````````@```"````#\_________S$*`````````@```#(` -XM``#\_________U0*`````````@```#,```#\_________VL*`````````@`` -XM`#0```#\_________Y0*````````"@````D```#1`0```````)X*```````` -XM`@```"````#\_________[<*`````````@```#$```#\_________^<*```` -XM`````@```#$```#\_________T(+````````"@````D```"V`````````&D+ -XM````````"@````D```"F`````````(8+````````"@````D```"N```````` -XM`)<+````````"@````D```#C`0```````*(+````````"P````D```#C`0`` -XM`````*L+````````"P````D```#J`0```````+0+````````"P````D```#\ -XM`0```````+T+````````"P````D````"`@```````.(+`````````@```#4` -XM``#\__________`+`````````@```#8```#\_________R(,`````````@`` -XM`#$```#\_________W\,`````````@```"<```#\_________Y,,```````` -XM"P````D```"V`````````,L,`````````@```#@```#\_________^@,```` -XM`````@```#D```#\__________\,`````````@```!D```#\_________QT- -XM`````````@```#H```#\_________U0-````````"@````D```"V```````` -XM`'X-`````````@```"8```#\_________Y,-`````````@```!P```#\____ -XM_____[@-````````"@````D```"F`````````-(-````````"@````D```"N -XM`````````!$.`````````@```#@```#\_________RH.`````````@```#D` -XM``#\_________SX.`````````@```!P```#\_________TX.`````````@`` -XM`!D```#\_________VL.`````````@```#H```#\_________YL.```````` -XM`@```"<```#\_________]P.`````````@```#L```#\__________<.```` -XM`````@```"L```#\_________P$/`````````@```",```#\_________Q`/ -XM`````````@```!\```#\_________Q4/````````"@````D```".```````` -XM`"0/`````````@```"````#\_________RD/`````````@```",```#\____ -XM_____TD/`````````@```!\```#\_________TX/````````"@````D````_ -XM`@```````%T/`````````@```"````#\_________V -XM%P```````"D`````````"@````<``````````````#``````````"@```!8` -XM``#_!P```````#<`````````"@```!8````O!P```````#X`````````"@`` -XM`!8```#I!0```````$,`````````"@```!8```!<`@```````%`````````` -XM"@```!8````7"````````%P`````````"@```!8```!/!P```````&D````` -XM````"@```!8```!Q`````````&X`````````"@```!8```!L!0```````'L` -XM````````"@```!8```#S!0```````(``````````"@```!8````T`P`````` -XM`(T`````````"@```!8```#E!@```````)0`````````"@```!8```!G"``` -XM`````)L`````````"@```!8```#B`0```````*``````````"@```!8```!P -XM!@```````+``````````"@```!8```#Q!P```````+T`````````"@```!8` -XM``"8`P```````,(`````````"@```!8```"+!0```````,T`````````"@`` -XM`!8```"M`0```````-@`````````"@```!8````Z!@```````/0````````` -XM"@```!8````$`P```````/\`````````"@```!8```#;`0````````H!```` -XM````"@```!8```"O!P```````!8!````````"@```!8```!X!````````"0! -XM````````"@```!8```",`````````#D!````````"@```!8````X`@`````` -XM`&P!````````"@```!8```"E`````````'H!````````"@```!8```"9!``` -XM`````)8!````````"@```!8```"<`````````*0!````````"@```!8```!] -XM`0```````+(!````````"@```!8```#Z`P```````,`!````````"@```!8` -XM```7`0```````,X!````````"@```!8```#1"````````-P!````````"@`` -XM`!8```"Q!0```````/@!````````"@```!8````N!0```````!0"```````` -XM"@```!8```#7"````````"("````````"@```!8```"1"````````#X"```` -XM````"@```!8```#*!@```````$T"````````"@```!8```!R`@```````-," -XM````````"@```!8````3`````````/\"````````"@```!8```"O"``````` -XM``P#````````"@```!8```!'!````````!$#````````"@```!8```#)!P`` -XM`````!P#````````"@```!8```"V`````````#\#````````"@```!8```#2 -XM!0```````$T#````````"@```!8```"%`P```````%P#````````"@```!8` -XM``"(!````````&<#````````"@```!8``````````````'(#````````"@`` -XM`!8````_`P```````'T#````````"@```!8```!^!````````(@#```````` -XM"@```!8```"D"````````),#````````"@```!8````Q!````````*8#```` -XM````"@```!8````)!P```````+0#````````"@```!8```"2!P```````,(# -XM````````"@```!8```"V!P```````-`#````````"@```!8```"L```````` -XM`-X#````````"@```!8```"E`0```````.P#````````"@```!8```#'```` -XM`````/H#````````"@```!8```!B``````````@$````````"@```!8```"R -XM`P```````!8$````````"@```!8```#P`````````"0$````````"@```!8` -XM``"P`@```````#($````````"@```!8````&!@```````$`$````````"@`` -XM`!8```!F`0```````$X$````````"@```!8```#;!0```````%P$```````` -XM"@```!8```#@`P```````&L$````````"@```!8```#F!P```````'X$```` -XM````"@```!8````S"````````(P$````````"@```!8```#W!@```````)H$ -XM````````"@```!8```"F!P```````*@$````````"@```!8```"-!@`````` -XM`+8$````````"@```!8````%!0```````,0$````````"@```!8```"K!``` -XM`````-($````````"@```!8````R!@```````.`$````````"@```!8```#8 -XM`P```````.X$````````"@```!8```"7"````````/P$````````"@```!8` -XM``!?`P````````L%````````"@```!8```#,`@```````!X%````````"@`` -XM`!8```#2!0```````"P%````````"@```!8```"%`P```````#L%```````` -XM"@```!8```"4!0```````%$%````````"@```!8````["````````%<%```` -XM````"@```!8````W`0```````&(%````````"@```!8```!+`0```````'`% -XM````````"@```!8````C!0```````'8%````````"@```!8```"Y!``````` -XM`'P%````````"@```!8```"=`P```````((%````````"@```!8```![`P`` -XM`````(@%````````"@```!8```!5!````````(X%````````"@```!8```"T -XM"````````)0%````````"@```!8```",`P```````)H%````````"@```!8` -XM``!7`````````*`%````````"@```!8```!O`P```````*8%````````"@`` -XM`!8```"G`P```````*P%````````"@```!8````]!````````+(%```````` -XM"@```!8```!:!P```````+@%````````"@```!8````H!@```````+X%```` -XM````"@```!8```#Y`@```````,0%````````"@```!8```#I!````````,H% -XM````````"@```!8```#%"````````-`%````````"@```!8````=`0`````` -XM`-8%````````"@```!8```""`@```````-P%````````"@```!8````2`P`` -XM`````.(%````````"@```!8```"V!@```````.@%````````"@```!8````+ -XM"````````.X%````````"@```!8```#/!````````/0%````````"@```!8` -XM```5`@```````/H%````````"@```!8```"2``````````$&````````"@`` -XM`!8````<`P```````!0&````````"@```!8````>!@```````",&```````` -XM"@```!8```#\!0```````"\&````````"@```!8```#3!@```````#T&```` -XM````"@```!8```#$!````````$L&````````"@```!8```!J!@```````%D& -XM````````"@```!8```!J`````````&<&````````"@```!8````+`P`````` -XM`'4&````````"@```!8```#_!@```````(,&````````"@```!8````#`0`` -XM`````)$&````````"@```!8```"*!P```````)\&````````"@```!8````> -XM!````````+H&````````"@```!8```!Y!P```````,4&````````"@```!8` -XM``#Y`````````-`&````````"@```!8```#1`0```````-L&````````"@`` -XM`!8```#)!0```````.X&````````"@```!8````>!@```````/T&```````` -XM"@```!8```!@!`````````D'````````"@```!8```"Q!@```````!<'```` -XM````"@```!8```"%`0```````#0'````````"@```!8````>!@```````$,' -XM````````"@```!8```"^!0```````$\'````````"@```!8```"Q!@`````` -XM`%T'````````"@```!8````/!0```````&L'````````"@```!8```!V!0`` -XM`````'D'````````"@```!8```"Z`P```````)4'````````"@```!8```#Z -XM`0```````*,'````````"@```!8````(!````````+$'````````"@```!8` -XM``"@`0```````+\'````````"@```!8```#C!0```````,T'````````"@`` -XM`!8````]`````````-L'````````"@```!8````7!````````.D'```````` -XM"@```!8```#!!@````````8(````````"@```!8````>!@```````!4(```` -XM````"@```!8```".`0```````"$(````````"@```!8```"Q!@```````"\( -XM````````"@```!8```""!P```````#T(````````"@```!8```#*!``````` -XM`$L(````````"@```!8````M`````````&@(````````"@```!8````)`0`` -XM`````'8(````````"@```!8```"V`0```````(4(````````"@```!8```": -XM!@```````)$(````````"@```!8```"Q!@```````/`(````````"@```!8` -XM``"_"````````/X(````````"@```!8````J!P```````!H)````````"@`` -XM`!8```!4`0```````"@)````````"@```!8```#^!````````#8)```````` -XM"@```!8```"2!````````$0)````````"@```!8````J"````````%()```` -XM````"@```!8```"?!P```````'4)````````"@```!8````)`0```````(,) -XM````````"@```!8```"V`0```````)()````````"@```!8````,`@`````` -XM`)X)````````"@```!8```#;!@```````*P)````````"@```!8```#`!P`` -XM`````,,)````````"@```!8````>!@```````-()````````"@```!8```#9 -XM``````````@*````````"@```!8````J!P```````!8*````````"@```!8` -XM```]`````````"0*````````"@```!8```"9!P```````#(*````````"@`` -XM`!8````E`P```````$\*````````"@```!8```#(`P```````%4*```````` -XM"@```!8```#/`````````%L*````````"@```!8```"?!````````&$*```` -XM````"@```!8```"A`@```````&<*````````"@```!8```"B!@```````'8* -XM````````"@```!8````G`@```````(0*````````"@```!8```#K`P`````` -XM`*$*````````"@```!8````G`@```````*\*````````"@```!8```#K`P`` -XM`````,P*````````"@```!8````G`@```````-H*````````"@```!8```#K -XM`P```````/<*````````"@```!8````G`@````````4+````````"@```!8` -XM``#K`P```````"(+````````"@```!8````G`@```````#`+````````"@`` -XM`!8```#K`P```````$<+````````"@```!8```#;!@```````%4+```````` -XM"@```!8```#`!P```````&P+````````"@```!8```!B!0```````'L+```` -XM````"@```!8```!'`@```````(<+````````"@```!8```!=`0```````)4+ -XM````````"@```!8```"S!````````*,+````````"@```!8```!``@`````` -XM`-L+````````"@```!8```"5!@```````.D+````````"@```!8```#!`P`` -XM`````/<+````````"@```!8```!0``````````4,````````"@```!8```!N -XM"````````!,,````````"@```!8````7!P```````"$,````````"@```!8` -XM``!*`P```````"\,````````"@```!8```"_`0```````#T,````````"@`` -XM`!8```">!0```````$L,````````"@```!8```!+!0```````%D,```````` -XM"@```!8```#>`@```````&<,````````"@```!8```!`"````````'4,```` -XM````"@```!8```!"!0```````(,,````````"@```!8```#Y!P```````)$, -XM````````"@```!8````N`P```````)\,````````"@```!8````E!``````` -XM`*T,````````"@```!8````W`````````+L,````````"@```!8```!H!``` -XM`````,H,````````"@```!8```#7`@```````-D,````````"@```!8````_ -XM`0```````.@,````````"@```!8```!R`0```````/<,````````"@```!8` -XM``"9!P````````8-````````"@```!8```!R!P```````!P-````````"@`` -XM`!8```!^"````````",-`````````0````(``````````````"L-```````` -XM`0````(```!P`````````&@-````````"@```!8````U!0```````'`-```` -XM`````0````(```!P`````````'@-`````````0````(````F`@```````(`- -XM````````"@```!(``````````````)0-````````"@```!(````Y```````` -XM`*(-````````"@```!(```""`````````*<-````````"@```!8```#3`P`` -XM`````+(-````````"@```!(```"X`````````,X-````````"@```!8```!$ -XM`````````-8-`````````0````(````P`@```````-X-`````````0````(` -XM```L`P```````.8-````````"@```!(````4`0```````/H-````````"@`` -XM`!(```")`0````````@.````````"@```!(```#2`0```````!8.```````` -XM"@```!(````(`@```````"L.````````"@```!8````!!````````#8.```` -XM````"@```!(```!1`@```````#L.````````"@```!8```!J`P```````$@. -XM````````"@```!8````.!@```````%`.`````````0````(````P`P`````` -XM`%@.`````````0````(```";`P```````&`.````````"@```!(```"'`@`` -XM`````'0.````````"@```!(```"_`@```````'D.````````"@```!8```"Q -XM!@```````(0.````````"@```!(```#U`@```````)(.````````"@```!(` -XM``!1`P```````)D.````````"@```!8```!:!@```````*$.`````````0`` -XM``(```"@`P```````*D.`````````0````(```")!0```````+$.```````` -XM"@```!(```":`P```````,4.````````"@```!(````W!````````-0.```` -XM````"@```!(```"3!````````-D.````````"@```!8```#!`````````.0. -XM````````"@```!(```#)!````````/T.````````"@```!(```#_!``````` -XM``P/````````"@```!(```!(!0```````",/````````"@```!8```"6`0`` -XM`````"L/`````````0````(```"0!0```````#,/`````````0````(```"$ -XM!@```````#L/````````"@```!(```!^!0```````$T/````````"@```!(` -XM``#>!0```````%P/````````"@```!(```!-!@```````&L/````````"@`` -XM`!(```"6!@```````'`/````````"@```!8````!!````````'L/```````` -XM"@```!(```#?!@```````((/````````"@```!8```#T!````````(H/```` -XM`````0````(```"0!@```````)(/`````````0````(```#)!P```````)H/ -XM````````"@```!(````5!P```````*X/````````"@```!(```!.!P`````` -XM`+T/````````"@```!(```"7!P```````,P/````````"@```!(```#-!P`` -XM`````-$/````````"@```!8```"Q!@```````-P/````````"@```!(````6 -XM"`````````,0````````"@```!8```"\`@````````L0`````````0````(` -XM``#0!P```````!,0`````````0````(```#_"````````!L0````````"@`` -XM`!(```!?"````````"\0````````"@```!(```#H"````````#T0```````` -XM"@```!(````Q"0```````%T0````````"@```!(```!G"0```````&00```` -XM````"@```!8````6!0```````'`0`````````0````(`````"0```````'@0 -XM`````````0````(```#_"0```````(`0````````"@```!(````B"@`````` -XM`)00````````"@```!(```"#"@```````*(0````````"@```!(```#,"@`` -XM`````*<0````````"@```!8````R`@```````+(0````````"@```!(```#O -XM"@```````,<0````````"@```!8````K!````````-(0````````"@```!(` -XM```2"P```````-D0````````"@```!8```#A`````````.00`````````0`` -XM``(`````"@```````.P0`````````0````(```"B"@```````/00```````` -XM"@```!(```!("P````````<1````````"@```!(```#0"P````````P1```` -XM````"@```!8```"Q!@```````!81````````"@```!(````L#````````"41 -XM````````"@```!(```"(#````````#01````````"@```!(```#D#``````` -XM`#H1````````"@```!8```!Y!@```````$41`````````0````(```"P"@`` -XM`````$T1`````````0````(```#2"@```````%41````````"@```!(````: -XM#0```````&@1````````"@```!(```!2#0```````&T1````````"@```!8` -XM``"Q!@```````'<1````````"@```!(```!U#0```````(81````````"@`` -XM`!(```"8#0```````(P1````````"@```!8```#H`0```````)<1```````` -XM`0````(```#@"@```````)\1`````````0````(````7"P```````*<1```` -XM````"@```!(```"[#0```````+H1````````"@```!(```#S#0```````+\1 -XM````````"@```!8```"Q!@```````,D1````````"@```!(````6#@`````` -XM`-@1````````"@```!(````Y#@```````-X1````````"@```!8````<```` -XM`````.\1````````"@```!8```"Q!@```````/H1````````"@```!8````+ -XM`````````"42````````"@```!8```#4!P```````#`2`````````0````(` -XM```@"P```````#@2`````````0````(```!@#````````$`2````````"@`` -XM`!(```!O#@```````%,2````````"@```!(```"H#@```````%@2```````` -XM"@```!8```"Q!@```````&(2````````"@```!(```#Q#@```````&<2```` -XM````"@```!4``````````````'H2````````"@```!(```!@#P```````(02 -XM`````````0````(```"6"P```````(P2`````````0````(```#X"P`````` -XM`)P2`````````0````(```"6"P```````*02`````````0````(```#>"P`` -XM`````+X2````````"@```!8```#E`@```````-H2````````"@```!8```#8 -XM`P```````.42````````"@```!8```"Q!@````````43````````"@```!8` -XM``#U`P```````!`3````````"@```!8````!!````````!T3````````"@`` -XM`!8```!G`@```````"03`````````0````(```!@#````````"P3```````` -XM`0````(````&$````````#03````````"@```!(```"I#P```````$<3```` -XM````"@```!(```!:$````````%03````````"@```!(```"C$````````%D3 -XM````````"@```!8```"Q!@```````&,3````````"@```!(```#_$``````` -XM`'$3````````"@```!(```"Z$0```````(43````````"@```!8```#U`P`` -XM`````)03````````"@```!8````!!````````)X3````````"@```!(```#P -XM$0```````*<3````````"@```!4```!``````````+D3````````"@```!4` -XM``"0`````````,(3````````"@```!(````F$@```````-03````````"@`` -XM`!(```!O$@```````.83````````"@```!(```#>$@```````.X3```````` -XM"@```!8```!Z`@```````!T4````````"@```!8```#="````````"44```` -XM`````0````(````0$````````"T4`````````0````(```#K$````````#44 -XM````````"@```!(````4$P```````$<4````````"@```!(```!T$P`````` -XM`%84````````"@```!(```#0$P```````&04````````"@```!(````L%``` -XM`````&T4````````"@```!4```!@`0```````'T4````````"@```!(```!B -XM%````````(P4````````"@```!4```"0`0```````)@4````````"@```!(` -XM``"^%````````*$4````````"@```!(````:%0```````*@4````````"@`` -XM`!8````J`0```````-84````````"@```!8```"Q!@```````/H4```````` -XM"@```!8```!%P```````/@6````````"@```!(```!V%0`````` -XM``P7````````"@```!(````G%@```````!H7````````"@```!(```"'%@`` -XM`````",7````````"@```!4```#@`0```````#D7````````"@```!4```!` -XM`@```````$(7````````"@```!(```"]%@```````$L7````````"@```!(` -XM```&%P```````&87````````"@```!(```!/%P```````&\7````````"@`` -XM`!(```"^%P```````'@7````````"@```!(````M&````````($7```````` -XM"@```!(```")&````````)L7````````"@```!4```"``P```````*L7```` -XM````"@```!(```#2&````````+H7````````"@```!4```"P`P```````-`7 -XM````````"@```!4````0!````````-D7````````"@```!(````(&0`````` -XM`.(7````````"@```!(````^&0```````/47````````"@```!(```#;&0`` -XM``````,8````````"@```!(```!=&@````````P8````````"@```!(```#? -XM&@```````"@8````````"@```!4````P!0```````#H8````````"@```!4` -XM``!P!0```````$,8````````"@```!(```"'&P```````%88````````"@`` -XM`!(```!5'````````&,8`````````0````(````-%````````&L8```````` -XM`0````(````Q%````````(48`````````0````(````=%````````(T8```` -XM`````0````(````Q%````````)H8````````"@```!(```">'````````*48 -XM````````"@```!4```#0!0```````+(8````````"@```!4````P!@`````` -XM`+L8````````"@```!(```#G'````````,08````````"@```!(```!I'0`` -XM`````,T8````````"@```!4```"P!@```````-D8````````"@```!(```"R -XM'0```````.<8````````"@```!8```!N!````````/08````````"@```!8` -XM``!/`@```````,4``````````0````(``````````````!P`````````"@`` -XM`!```````````````"```````````0````(``````````````#0````````` -XM"@```!```````````````#@``````````0````(```!P`````````%P````` -XM````"@```!```````````````&```````````0````(````P`@```````(P` -XM````````"@```!```````````````)```````````0````(````P`P`````` -XM`*P`````````"@```!```````````````+```````````0````(```"@`P`` -XM`````.0`````````"@```!```````````````.@``````````0````(```"0 -XM!0````````P!````````"@```!```````````````!`!`````````0````(` -XM``"0!@```````#0!````````"@```!```````````````#@!`````````0`` -XM``(```#0!P```````&0!````````"@```!```````````````&@!```````` -XM`0````(`````"0```````(P!````````"@```!```````````````)`!```` -XM`````0````(`````"@```````+P!````````"@```!```````````````,`! -XM`````````0````(```"P"@```````-P!````````"@```!`````````````` -XM`.`!`````````0````(```#@"@```````/P!````````"@```!`````````` -XM```````"`````````0````(````@"P```````"0"````````"@```!`````` -XM`````````"@"`````````0````(```!@#````````&0"````````"@```!`` -XM`````````````&@"`````````0````(````0$````````(P"````````"@`` -XM`!```````````````)`"`````````0````(```#P$````````"`````````` -XM"@````(``````````````#@`````````"@````(```!P`````````%@````` -XM````"@````(````P`@```````(``````````"@````(````P`P```````)@` -XM````````"@````(```"@`P```````,@`````````"@````(```"0!0`````` -XM`.@`````````"@````(```"0!@````````@!````````"@````(```#0!P`` -XM`````#`!````````"@````(`````"0```````%`!````````"@````(````` -XM"@```````'@!````````"@````(```"P"@```````)`!````````"@````(` -XM``#@"@```````*@!````````"@````(````@"P```````,@!````````"@`` -XM``(```!@#``````````"````````"@````(````0$````````"`"```````` -XM"@````(```#P$`````````8`````````"@````8```````````````8````` -XK````"@````8``````````````!```````````0````(````````````````` +XM```!````!`#Q_P```````````````````````````P`!```````````````` +XM`````````````P`#`````````````````````````````P`$```````````` +XM`````````````````P`%`````````````````````````````P`&```````` +XM`````````````````````P`(```````````````````````,`````@`!```` +XM````````<````````````````P`+```````````````````````?`````@`! +XM`#`#````````:P```````````````P`,```````````````````````O```` +XM`@`!`+`*````````(@````````!#`````@`!`.`*````````-P````````!5 +XM`````@`!`"`+````````0`$```````!G`````@`!`!`0````````VP`````` +XM`````````P`-`````````````````````````````P`/```````````````` +XM`````````````P`1`````````````````````````````P`2```````````` +XM`````````````````P`4`````````````````````````````P`6```````` +XM`````````````````````P`7`````````````````````````````P`*```` +XM``````````````````!R````$@`!`'``````````M@$```````!_````$``` +XM``````````````````````",````$`````````````````````````"8```` +XM$`````````````````````````"I````$`````````````````````````"T +XM````$`````````````````````````#$````$``````````````````````` +XM``#,````$`````````````````````````#7````$``````````````````` +XM``````#<````$@`!`#`"````````_`````````#H````$``````````````` +XM``````````#V````$````````````````````````````0``$``````````` +XM```````````````1`0``$@`!`*`#````````Z0$````````A`0``$``````` +XM```````````````````L`0``$``````````````````````````S`0``$``` +XM```````````````````````W`0``$@`!`)`%````````]`````````!!`0`` +XM$`````````````````````````!-`0``$@`!`)`&````````.0$```````!7 +XM`0``$@`!`-`'````````+P$```````!G`0``$``````````````````````` +XM``!M`0``$@`!```)````````_P````````!Z`0``$``````````````````` +XM``````"'`0``$`````````````````````````"2`0``$@`!```*```````` +XMH@````````"A`0``$`````````````````````````"H`0``$``````````` +XM``````````````"O`0``$`````````````````````````"V`0``$``````` +XM``````````````````"]`0``$`````````````````````````#%`0``$@`! +XM`&`,````````I@,```````#0`0``$`````````````````````````#@`0`` +XM$`````````````````````````#L`0``$`````````````````````````#W +XM`0``$``````````````````````````)`@``$``````````````````````` +XM```6`@``$``````````````````````````@`@``$``````````````````` +XM```````E`@``$``````````````````````````M`@``$@`!`/`0```````` +XM[@8````````Z`@``$`````````````````````````!(`@``$``````````` +XM``````````````!/`@``$`````````````````````````!7`@``$``````` +XM``````````````````!C`@``$```````````````````````````'-C;@!E;&9?6YC7W-E8W1I;VYS`'=A`!E;&9?;F5X='-C;@!E;&9?0!S +XM=')N8W!Y`&=E;&9?9V5T`````````.8!`````````@`` +XM`"````#\__________`!`````````@```!\```#\__________4!```````` +XM"@````D````W``````````0"`````````@```"````#\_________PX"```` +XM`````@```!\```#\_________Q,"````````"@````D```!5`````````"(" +XM`````````@```"````#\_________T\"`````````@```!D```#\________ +XM_V`"`````````@```"(```#\_________Y<"`````````@```!P```#\____ +XM_____Z@"`````````@```!L```#\_________[H"`````````@```",```#\ +XM_________]L"`````````@```!\```#\_________^`"````````"@````D` +XM``!R`````````.\"`````````@```"````#\__________D"`````````@`` +XM`!\```#\__________X"````````"@````D````W``````````T#```````` +XM`@```"````#\_________Q0#`````````@```!\```#\_________QD#```` +XM````"@````D```".`````````"@#`````````@```"````#\_________VD# +XM````````"@````D```"E`````````&X#`````````@```"0```#\________ +XM_W8#````````"@````D```"F`````````'L#`````````@```"0```#\____ +XM_____X,#````````"@````D```"N`````````(@#`````````@```"0```#\ +XM_________XT#````````"@````D```"V`````````)4#`````````@```"0` +XM``#\_________[T#````````"@````D```"V`````````/4#`````````@`` +XM`"8```#\_________Q`$`````````@```"<```#\_________V\$```````` +XM`@```!H```#\_________[,$`````````@```!D```#\_________]H$```` +XM`````@```!L```#\_________P8%`````````@```!\```#\_________PL% +XM````````"@````D```#``````````!H%`````````@```"````#\________ +XM_Q\%````````"@````D```#8`````````"L%`````````@```"@```#\____ +XM_____S4%`````````@```!\```#\_________SH%````````"@````D````> +XM`````````$D%`````````@```"````#\_________U,%`````````@```!\` +XM``#\_________U@%````````"@````D```#E`````````&<%`````````@`` +XM`"````#\_________W$%`````````@```!\```#\_________W8%```````` +XM"@````D````W`````````(4%`````````@```"````#\_________[4%```` +XM`````@```!H```#\__________X%`````````@```"H```#\_________PL& +XM`````````@```",```#\_________U$&`````````@```!\```#\________ +XM_U8&````````"@````D````>`````````&4&`````````@```"````#\____ +XM_____VP&`````````@```!\```#\_________W$&````````"@````D````# +XM`0```````(`&`````````@```"````#\_________[T&`````````@```!D` +XM``#\_________]$&`````````@```!D```#\_________S\'`````````@`` +XM`!L```#\_________W4'`````````@```!\```#\_________WH'```````` +XM"@````D````<`0```````(D'`````````@```"````#\_________Y,'```` +XM`````@```!\```#\_________Y@'````````"@````D````Z`0```````*<' +XM`````````@```"````#\_________[$'`````````@```!\```#\________ +XM_[8'````````"@````D```!8`0```````,4'`````````@```"````#\____ +XM_____TL(`````````@```!D```#\_________VX(`````````@```!L```#\ +XM_________[,(````````"@````L``````````````+H(`````````@```"T` +XM``#\_________\D(`````````@```!\```#\_________\X(````````"@`` +XM``D```!S`0```````-T(`````````@```"````#\_________^<(```````` +XM`@```!\```#\_________^P(````````"@````D```!8`0```````/L(```` +XM`````@```"````#\_________Q$)`````````@```"\```#\_________RD) +XM`````````@```"<```#\_________WH)`````````@```#````#\________ +XM_[@)`````````@```!\```#\_________[T)````````"@````D```"1`0`` +XM`````,P)`````````@```"````#\_________]8)`````````@```!\```#\ +XM_________]L)````````"@````D```"Y`0```````.H)`````````@```"`` +XM``#\_________^\)````````"@````D```"K`0```````/L)`````````@`` +XM`"````#\_________S$*`````````@```#(```#\_________U0*```````` +XM`@```#,```#\_________VL*`````````@```#0```#\_________Y0*```` +XM````"@````D```#1`0```````)X*`````````@```"````#\_________[<* +XM`````````@```#$```#\_________^<*`````````@```#$```#\________ +XM_T(+````````"@````D```"V`````````&D+````````"@````D```"F```` +XM`````(8+````````"@````D```"N`````````)<+````````"@````D```#C +XM`0```````*(+````````"P````D```#C`0```````*L+````````"P````D` +XM``#J`0```````+0+````````"P````D```#\`0```````+T+````````"P`` +XM``D````"`@```````.(+`````````@```#4```#\__________`+```````` +XM`@```#8```#\_________R(,`````````@```#$```#\_________W\,```` +XM`````@```"<```#\_________Y,,````````"P````D```"V`````````,L, +XM`````````@```#@```#\_________^@,`````````@```#D```#\________ +XM__\,`````````@```!D```#\_________QT-`````````@```#H```#\____ +XM_____U0-````````"@````D```"V`````````'X-`````````@```"8```#\ +XM_________Y,-`````````@```!P```#\_________[@-````````"@````D` +XM``"F`````````-(-````````"@````D```"N`````````!$.`````````@`` +XM`#@```#\_________RH.`````````@```#D```#\_________SX.```````` +XM`@```!P```#\_________TX.`````````@```!D```#\_________VL.```` +XM`````@```#H```#\_________YL.`````````@```"<```#\_________]P. +XM`````````@```#L```#\__________<.`````````@```"L```#\________ +XM_P$/`````````@```",```#\_________Q`/`````````@```!\```#\____ +XM_____Q4/````````"@````D```".`````````"0/`````````@```"````#\ +XM_________RD/`````````@```",```#\_________TD/`````````@```!\` +XM``#\_________TX/````````"@````D````_`@```````%T/`````````@`` +XM`"````#\_________V%P```````"D`````````"@`` +XM``<``````````````#``````````"@```!8```#_!P```````#<````````` +XM"@```!8````O!P```````#X`````````"@```!8```#I!0```````$,````` +XM````"@```!8```!<`@```````%``````````"@```!8````7"````````%P` +XM````````"@```!8```!/!P```````&D`````````"@```!8```!Q```````` +XM`&X`````````"@```!8```!L!0```````'L`````````"@```!8```#S!0`` +XM`````(``````````"@```!8````T`P```````(T`````````"@```!8```#E +XM!@```````)0`````````"@```!8```!G"````````)L`````````"@```!8` +XM``#B`0```````*``````````"@```!8```!P!@```````+``````````"@`` +XM`!8```#Q!P```````+T`````````"@```!8```"8`P```````,(````````` +XM"@```!8```"+!0```````,T`````````"@```!8```"M`0```````-@````` +XM````"@```!8````Z!@```````/0`````````"@```!8````$`P```````/\` +XM````````"@```!8```#;`0````````H!````````"@```!8```"O!P`````` +XM`!8!````````"@```!8```!X!````````"0!````````"@```!8```",```` +XM`````#D!````````"@```!8````X`@```````&P!````````"@```!8```"E +XM`````````'H!````````"@```!8```"9!````````)8!````````"@```!8` +XM``"<`````````*0!````````"@```!8```!]`0```````+(!````````"@`` +XM`!8```#Z`P```````,`!````````"@```!8````7`0```````,X!```````` +XM"@```!8```#1"````````-P!````````"@```!8```"Q!0```````/@!```` +XM````"@```!8````N!0```````!0"````````"@```!8```#7"````````"(" +XM````````"@```!8```"1"````````#X"````````"@```!8```#*!@`````` +XM`$T"````````"@```!8```!R`@```````-,"````````"@```!8````3```` +XM`````/\"````````"@```!8```"O"`````````P#````````"@```!8```!' +XM!````````!$#````````"@```!8```#)!P```````!P#````````"@```!8` +XM``"V`````````#\#````````"@```!8```#2!0```````$T#````````"@`` +XM`!8```"%`P```````%P#````````"@```!8```"(!````````&<#```````` +XM"@```!8``````````````'(#````````"@```!8````_`P```````'T#```` +XM````"@```!8```!^!````````(@#````````"@```!8```"D"````````),# +XM````````"@```!8````Q!````````*8#````````"@```!8````)!P`````` +XM`+0#````````"@```!8```"2!P```````,(#````````"@```!8```"V!P`` +XM`````-`#````````"@```!8```"L`````````-X#````````"@```!8```"E +XM`0```````.P#````````"@```!8```#'`````````/H#````````"@```!8` +XM``!B``````````@$````````"@```!8```"R`P```````!8$````````"@`` +XM`!8```#P`````````"0$````````"@```!8```"P`@```````#($```````` +XM"@```!8````&!@```````$`$````````"@```!8```!F`0```````$X$```` +XM````"@```!8```#;!0```````%P$````````"@```!8```#@`P```````&L$ +XM````````"@```!8```#F!P```````'X$````````"@```!8````S"``````` +XM`(P$````````"@```!8```#W!@```````)H$````````"@```!8```"F!P`` +XM`````*@$````````"@```!8```"-!@```````+8$````````"@```!8````% +XM!0```````,0$````````"@```!8```"K!````````-($````````"@```!8` +XM```R!@```````.`$````````"@```!8```#8`P```````.X$````````"@`` +XM`!8```"7"````````/P$````````"@```!8```!?`P````````L%```````` +XM"@```!8```#,`@```````!X%````````"@```!8```#2!0```````"P%```` +XM````"@```!8```"%`P```````#L%````````"@```!8```"4!0```````%$% +XM````````"@```!8````["````````%<%````````"@```!8````W`0`````` +XM`&(%````````"@```!8```!+`0```````'`%````````"@```!8````C!0`` +XM`````'8%````````"@```!8```"Y!````````'P%````````"@```!8```"= +XM`P```````((%````````"@```!8```![`P```````(@%````````"@```!8` +XM``!5!````````(X%````````"@```!8```"T"````````)0%````````"@`` +XM`!8```",`P```````)H%````````"@```!8```!7`````````*`%```````` +XM"@```!8```!O`P```````*8%````````"@```!8```"G`P```````*P%```` +XM````"@```!8````]!````````+(%````````"@```!8```!:!P```````+@% +XM````````"@```!8````H!@```````+X%````````"@```!8```#Y`@`````` +XM`,0%````````"@```!8```#I!````````,H%````````"@```!8```#%"``` +XM`````-`%````````"@```!8````=`0```````-8%````````"@```!8```"" +XM`@```````-P%````````"@```!8````2`P```````.(%````````"@```!8` +XM``"V!@```````.@%````````"@```!8````+"````````.X%````````"@`` +XM`!8```#/!````````/0%````````"@```!8````5`@```````/H%```````` +XM"@```!8```"2``````````$&````````"@```!8````<`P```````!0&```` +XM````"@```!8````>!@```````",&````````"@```!8```#\!0```````"\& +XM````````"@```!8```#3!@```````#T&````````"@```!8```#$!``````` +XM`$L&````````"@```!8```!J!@```````%D&````````"@```!8```!J```` +XM`````&<&````````"@```!8````+`P```````'4&````````"@```!8```#_ +XM!@```````(,&````````"@```!8````#`0```````)$&````````"@```!8` +XM``"*!P```````)\&````````"@```!8````>!````````+H&````````"@`` +XM`!8```!Y!P```````,4&````````"@```!8```#Y`````````-`&```````` +XM"@```!8```#1`0```````-L&````````"@```!8```#)!0```````.X&```` +XM````"@```!8````>!@```````/T&````````"@```!8```!@!`````````D' +XM````````"@```!8```"Q!@```````!<'````````"@```!8```"%`0`````` +XM`#0'````````"@```!8````>!@```````$,'````````"@```!8```"^!0`` +XM`````$\'````````"@```!8```"Q!@```````%T'````````"@```!8````/ +XM!0```````&L'````````"@```!8```!V!0```````'D'````````"@```!8` +XM``"Z`P```````)4'````````"@```!8```#Z`0```````*,'````````"@`` +XM`!8````(!````````+$'````````"@```!8```"@`0```````+\'```````` +XM"@```!8```#C!0```````,T'````````"@```!8````]`````````-L'```` +XM````"@```!8````7!````````.D'````````"@```!8```#!!@````````8( +XM````````"@```!8````>!@```````!4(````````"@```!8```".`0`````` +XM`"$(````````"@```!8```"Q!@```````"\(````````"@```!8```""!P`` +XM`````#T(````````"@```!8```#*!````````$L(````````"@```!8````M +XM`````````&@(````````"@```!8````)`0```````'8(````````"@```!8` +XM``"V`0```````(4(````````"@```!8```":!@```````)$(````````"@`` +XM`!8```"Q!@```````/`(````````"@```!8```"_"````````/X(```````` +XM"@```!8````J!P```````!H)````````"@```!8```!4`0```````"@)```` +XM````"@```!8```#^!````````#8)````````"@```!8```"2!````````$0) +XM````````"@```!8````J"````````%()````````"@```!8```"?!P`````` +XM`'4)````````"@```!8````)`0```````(,)````````"@```!8```"V`0`` +XM`````)()````````"@```!8````,`@```````)X)````````"@```!8```#; +XM!@```````*P)````````"@```!8```#`!P```````,,)````````"@```!8` +XM```>!@```````-()````````"@```!8```#9``````````@*````````"@`` +XM`!8````J!P```````!8*````````"@```!8````]`````````"0*```````` +XM"@```!8```"9!P```````#(*````````"@```!8````E`P```````$\*```` +XM````"@```!8```#(`P```````%4*````````"@```!8```#/`````````%L* +XM````````"@```!8```"?!````````&$*````````"@```!8```"A`@`````` +XM`&<*````````"@```!8```"B!@```````'8*````````"@```!8````G`@`` +XM`````(0*````````"@```!8```#K`P```````*$*````````"@```!8````G +XM`@```````*\*````````"@```!8```#K`P```````,P*````````"@```!8` +XM```G`@```````-H*````````"@```!8```#K`P```````/<*````````"@`` +XM`!8````G`@````````4+````````"@```!8```#K`P```````"(+```````` +XM"@```!8````G`@```````#`+````````"@```!8```#K`P```````$<+```` +XM````"@```!8```#;!@```````%4+````````"@```!8```#`!P```````&P+ +XM````````"@```!8```!B!0```````'L+````````"@```!8```!'`@`````` +XM`(<+````````"@```!8```!=`0```````)4+````````"@```!8```"S!``` +XM`````*,+````````"@```!8```!``@```````-L+````````"@```!8```"5 +XM!@```````.D+````````"@```!8```#!`P```````/<+````````"@```!8` +XM``!0``````````4,````````"@```!8```!N"````````!,,````````"@`` +XM`!8````7!P```````"$,````````"@```!8```!*`P```````"\,```````` +XM"@```!8```"_`0```````#T,````````"@```!8```">!0```````$L,```` +XM````"@```!8```!+!0```````%D,````````"@```!8```#>`@```````&<, +XM````````"@```!8```!`"````````'4,````````"@```!8```!"!0`````` +XM`(,,````````"@```!8```#Y!P```````)$,````````"@```!8````N`P`` +XM`````)\,````````"@```!8````E!````````*T,````````"@```!8````W +XM`````````+L,````````"@```!8```!H!````````,H,````````"@```!8` +XM``#7`@```````-D,````````"@```!8````_`0```````.@,````````"@`` +XM`!8```!R`0```````/<,````````"@```!8```"9!P````````8-```````` +XM"@```!8```!R!P```````!P-````````"@```!8```!^"````````",-```` +XM`````0````(``````````````"L-`````````0````(```!P`````````&@- +XM````````"@```!8````U!0```````'`-`````````0````(```!P```````` +XM`'@-`````````0````(````F`@```````(`-````````"@```!(````````` +XM`````)0-````````"@```!(````Y`````````*(-````````"@```!(```"" +XM`````````*<-````````"@```!8```#3`P```````+(-````````"@```!(` +XM``"X`````````,X-````````"@```!8```!$`````````-8-`````````0`` +XM``(````P`@```````-X-`````````0````(````L`P```````.8-```````` +XM"@```!(````4`0```````/H-````````"@```!(```")`0````````@.```` +XM````"@```!(```#2`0```````!8.````````"@```!(````(`@```````"L. +XM````````"@```!8````!!````````#8.````````"@```!(```!1`@`````` +XM`#L.````````"@```!8```!J`P```````$@.````````"@```!8````.!@`` +XM`````%`.`````````0````(````P`P```````%@.`````````0````(```"; +XM`P```````&`.````````"@```!(```"'`@```````'0.````````"@```!(` +XM``"_`@```````'D.````````"@```!8```"Q!@```````(0.````````"@`` +XM`!(```#U`@```````)(.````````"@```!(```!1`P```````)D.```````` +XM"@```!8```!:!@```````*$.`````````0````(```"@`P```````*D.```` +XM`````0````(```")!0```````+$.````````"@```!(```":`P```````,4. +XM````````"@```!(````W!````````-0.````````"@```!(```"3!``````` +XM`-D.````````"@```!8```#!`````````.0.````````"@```!(```#)!``` +XM`````/T.````````"@```!(```#_!`````````P/````````"@```!(```!( +XM!0```````",/````````"@```!8```"6`0```````"L/`````````0````(` +XM``"0!0```````#,/`````````0````(```"$!@```````#L/````````"@`` +XM`!(```!^!0```````$T/````````"@```!(```#>!0```````%P/```````` +XM"@```!(```!-!@```````&L/````````"@```!(```"6!@```````'`/```` +XM````"@```!8````!!````````'L/````````"@```!(```#?!@```````((/ +XM````````"@```!8```#T!````````(H/`````````0````(```"0!@`````` +XM`)(/`````````0````(```#)!P```````)H/````````"@```!(````5!P`` +XM`````*X/````````"@```!(```!.!P```````+T/````````"@```!(```"7 +XM!P```````,P/````````"@```!(```#-!P```````-$/````````"@```!8` +XM``"Q!@```````-P/````````"@```!(````6"`````````,0````````"@`` +XM`!8```"\`@````````L0`````````0````(```#0!P```````!,0```````` +XM`0````(```#_"````````!L0````````"@```!(```!?"````````"\0```` +XM````"@```!(```#H"````````#T0````````"@```!(````Q"0```````%T0 +XM````````"@```!(```!G"0```````&00````````"@```!8````6!0`````` +XM`'`0`````````0````(`````"0```````'@0`````````0````(```#_"0`` +XM`````(`0````````"@```!(````B"@```````)00````````"@```!(```"# +XM"@```````*(0````````"@```!(```#,"@```````*<0````````"@```!8` +XM```R`@```````+(0````````"@```!(```#O"@```````,<0````````"@`` +XM`!8````K!````````-(0````````"@```!(````2"P```````-D0```````` +XM"@```!8```#A`````````.00`````````0````(`````"@```````.P0```` +XM`````0````(```"B"@```````/00````````"@```!(```!("P````````<1 +XM````````"@```!(```#0"P````````P1````````"@```!8```"Q!@`````` +XM`!81````````"@```!(````L#````````"41````````"@```!(```"(#``` +XM`````#01````````"@```!(```#D#````````#H1````````"@```!8```!Y +XM!@```````$41`````````0````(```"P"@```````$T1`````````0````(` +XM``#2"@```````%41````````"@```!(````:#0```````&@1````````"@`` +XM`!(```!2#0```````&T1````````"@```!8```"Q!@```````'<1```````` +XM"@```!(```!U#0```````(81````````"@```!(```"8#0```````(P1```` +XM````"@```!8```#H`0```````)<1`````````0````(```#@"@```````)\1 +XM`````````0````(````7"P```````*<1````````"@```!(```"[#0`````` +XM`+H1````````"@```!(```#S#0```````+\1````````"@```!8```"Q!@`` +XM`````,D1````````"@```!(````6#@```````-@1````````"@```!(````Y +XM#@```````-X1````````"@```!8````<`````````.\1````````"@```!8` +XM``"Q!@```````/H1````````"@```!8````+`````````"42````````"@`` +XM`!8```#4!P```````#`2`````````0````(````@"P```````#@2```````` +XM`0````(```!@#````````$`2````````"@```!(```!O#@```````%,2```` +XM````"@```!(```"H#@```````%@2````````"@```!8```"Q!@```````&(2 +XM````````"@```!(```#Q#@```````&<2````````"@```!4````````````` +XM`'H2````````"@```!(```!@#P```````(02`````````0````(```"6"P`` +XM`````(P2`````````0````(```#X"P```````)P2`````````0````(```"6 +XM"P```````*02`````````0````(```#>"P```````+X2````````"@```!8` +XM``#E`@```````-H2````````"@```!8```#8`P```````.42````````"@`` +XM`!8```"Q!@````````43````````"@```!8```#U`P```````!`3```````` +XM"@```!8````!!````````!T3````````"@```!8```!G`@```````"03```` +XM`````0````(```!@#````````"P3`````````0````(````&$````````#03 +XM````````"@```!(```"I#P```````$<3````````"@```!(```!:$``````` +XM`%03````````"@```!(```"C$````````%D3````````"@```!8```"Q!@`` +XM`````&,3````````"@```!(```#_$````````'$3````````"@```!(```"Z +XM$0```````(43````````"@```!8```#U`P```````)03````````"@```!8` +XM```!!````````)X3````````"@```!(```#P$0```````*<3````````"@`` +XM`!4```!``````````+D3````````"@```!4```"0`````````,(3```````` +XM"@```!(````F$@```````-03````````"@```!(```!O$@```````.83```` +XM````"@```!(```#>$@```````.X3````````"@```!8```!Z`@```````!T4 +XM````````"@```!8```#="````````"44`````````0````(````0$``````` +XM`"T4`````````0````(```#K$````````#44````````"@```!(````4$P`` +XM`````$<4````````"@```!(```!T$P```````%84````````"@```!(```#0 +XM$P```````&04````````"@```!(````L%````````&T4````````"@```!4` +XM``!@`0```````'T4````````"@```!(```!B%````````(P4````````"@`` +XM`!4```"0`0```````)@4````````"@```!(```"^%````````*$4```````` +XM"@```!(````:%0```````*@4````````"@```!8````J`0```````-84```` +XM````"@```!8```"Q!@```````/H4````````"@```!8```!%P`` +XM`````/@6````````"@```!(```!V%0````````P7````````"@```!(````G +XM%@```````!H7````````"@```!(```"'%@```````",7````````"@```!4` +XM``#@`0```````#D7````````"@```!4```!``@```````$(7````````"@`` +XM`!(```"]%@```````$L7````````"@```!(````&%P```````&87```````` +XM"@```!(```!/%P```````&\7````````"@```!(```"^%P```````'@7```` +XM````"@```!(````M&````````($7````````"@```!(```")&````````)L7 +XM````````"@```!4```"``P```````*L7````````"@```!(```#2&``````` +XM`+H7````````"@```!4```"P`P```````-`7````````"@```!4````0!``` +XM`````-D7````````"@```!(````(&0```````.(7````````"@```!(````^ +XM&0```````/47````````"@```!(```#;&0````````,8````````"@```!(` +XM``!=&@````````P8````````"@```!(```#?&@```````"@8````````"@`` +XM`!4````P!0```````#H8````````"@```!4```!P!0```````$,8```````` +XM"@```!(```"'&P```````%88````````"@```!(```!5'````````&,8```` +XM`````0````(````-%````````&L8`````````0````(````Q%````````(48 +XM`````````0````(````=%````````(T8`````````0````(````Q%``````` +XM`)H8````````"@```!(```">'````````*48````````"@```!4```#0!0`` +XM`````+(8````````"@```!4````P!@```````+L8````````"@```!(```#G +XM'````````,08````````"@```!(```!I'0```````,T8````````"@```!4` +XM``"P!@```````-D8````````"@```!(```"R'0```````.<8````````"@`` +XM`!8```!N!````````/08````````"@```!8```!/`@```````,4````````` +XM`0````(``````````````!P`````````"@```!```````````````"`````` +XM`````0````(``````````````#0`````````"@```!```````````````#@` +XM`````````0````(```!P`````````%P`````````"@```!`````````````` +XM`&```````````0````(````P`@```````(P`````````"@```!`````````` +XM`````)```````````0````(````P`P```````*P`````````"@```!`````` +XM`````````+```````````0````(```"@`P```````.0`````````"@```!`` +XM`````````````.@``````````0````(```"0!0````````P!````````"@`` +XM`!```````````````!`!`````````0````(```"0!@```````#0!```````` +XM"@```!```````````````#@!`````````0````(```#0!P```````&0!```` +XM````"@```!```````````````&@!`````````0````(`````"0```````(P! +XM````````"@```!```````````````)`!`````````0````(`````"@`````` +XM`+P!````````"@```!```````````````,`!`````````0````(```"P"@`` +XM`````-P!````````"@```!```````````````.`!`````````0````(```#@ +XM"@```````/P!````````"@```!`````````````````"`````````0````(` +XM```@"P```````"0"````````"@```!```````````````"@"`````````0`` +XM``(```!@#````````&0"````````"@```!```````````````&@"```````` +XM`0````(````0$````````(P"````````"@```!```````````````)`"```` +XM`````0````(```#P$````````"``````````"@````(``````````````#@` +XM````````"@````(```!P`````````%@`````````"@````(````P`@`````` +XM`(``````````"@````(````P`P```````)@`````````"@````(```"@`P`` +XM`````,@`````````"@````(```"0!0```````.@`````````"@````(```"0 +XM!@````````@!````````"@````(```#0!P```````#`!````````"@````(` +XM````"0```````%`!````````"@````(`````"@```````'@!````````"@`` +XM``(```"P"@```````)`!````````"@````(```#@"@```````*@!```````` +XM"@````(````@"P```````,@!````````"@````(```!@#``````````"```` +XM````"@````(````0$````````"`"````````"@````(```#P$`````````8` +XM````````"@````8```````````````8`````````"@````8````````````` +XM`!```````````0````(````````````````````````````````````````` +XM```````````````````````````````````````````````````````````@ +XM````"`````8```````````````````!``````````-X7```````````````` +XM```0````````````````````&P````0```!`````````````````````^%P` +XM``````"0%0```````!D````!````"``````````8`````````"8````(```` +XM`P```````````````````$````````````````````````````````0````` +XM```````````````L````"`````,```````````````````!````````````` +XM```````````````````$````````````````````,0````$````````````` +XM````````````0`````````!U`P```````````````````0`````````````` +XM`````$0````!`````````````````````````+4#`````````AD````````` +XM``````````$````````````````````_````!````$`````````````````` +XM``"(<@```````"`H````````&0````8````(`````````!@`````````50`` +XM``$`````````````````````````MQP```````""!``````````````````` +XM`0```````````````````%`````$````0````````````````````*B:```` +XM````&``````````9````"`````@`````````&`````````!A`````0`````` +XM```````````````````Y(0```````#`````````````````````!```````` +XM````````````:@````@````R````````````````````:2$```````#7`@`` +XM`````````````````0`````````!`````````'D````(````,@`````````` +XM`````````'`A````````+0````````````````````@``````````0`````` +XM``"-`````0````````````````````````!P(0```````,@"```````````` +XM```````(````````````````````B`````0```!````````````````````` +XMP)H``````````P```````!D````-````"``````````8`````````)\````( +XM`````@```````````````````#@D````````4`(```````````````````@` +XM``````````````````":````!````$````````````````````#`G0`````` +XM`(`!````````&0````\````(`````````!@`````````J0````$````````` +XM````````````````."0````````.'@```````````````````0`````````` +XM`````````+D````!`````````````````````````$9"````````NP`````` +XM``````````````$```````````````````"T````!````$`````````````` +XM``````!`GP```````!@`````````&0```!(````(`````````!@````````` +XMS@````$``````````````````````````4,````````P```````````````` +XM`````0```````````````````,D````$````0````````````````````%B? +XM````````,``````````9````%`````@`````````&`````````#=`````0`` +XM```````````````````````Q0P```````.`&```````````````````!```` +XM````````````````ZP````$````P````````````````````$4H```````#H +XM"````````````````````0`````````!`````````!$````#```````````` +XM`````````````/E2````````]@````````````````````$````````````` +XM```````!`````@````````````````````````#P4P```````)`&```````` +XM&@```!@````(`````````!@`````````"0````,````````````````````` +XK````@%H```````!W`@```````````````````0`````````````````````` X` Xend -END-of-sections.o.1.uu +eb2ac2808b7045ab3c2faf26922f5e01 echo x - sections.o.uu -sed 's/^X//' >sections.o.uu << 'END-of-sections.o.uu' +sed 's/^X//' >sections.o.uu << 'f3eccedeeefe85afebc666fca5eb0742' Xbegin 644 sections.o XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@sections.o.1.uu << 'END-of-sections.o.1.uu' +sed 's/^X//' >sections.o.1.uu << 'eb2ac2808b7045ab3c2faf26922f5e01' Xbegin 644 sections.o.1 -XM?T5,1@(!`0D```````````$`/@`!`````````````````````````!`>```` +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````#@\```` XM`````````$```````$``#0`*`$B+E\````!(A=)T'TB+1B!(.T(@U(QT98`````$B+A\@```!(B49@2(N'R````$B) XM,$B-1EA(B8?(````PTB+0F!(B5982(E&8$B+0F!(B3!(C4982(E"8,-,B60D @@ -182,202 +182,202 @@ XM`-L`````00X0A@)%#AA$#B"#`P``-````!P"````````[@8```!"#A!"#AA" XM#B!"#BA!#C!!#CA'#M`!@P>&!HP%C02.`X\"````````+G-Y;71A8@`N'-C;@!E;&9?6YC7W-E8W1I;VYS`'=A`!E +XM;&9?;F5X='-C;@!E;&9?0!S=')N8W!Y`&=E;&9?9V5T"@`` +XM``````(````0````_/________^W"@````````(````A````_/_________G +XM"@````````(````A````_/________]""P````````H````"````M@`````` +XM``!I"P````````H````"````I@````````"&"P````````H````"````K@`` +XM``````"7"P````````H````"````XP$```````"B"P````````L````"```` +XMXP$```````"K"P````````L````"````Z@$```````"T"P````````L````" +XM````_`$```````"]"P````````L````"`````@(```````#B"P````````(` +XM```E````_/_________P"P````````(````F````_/________\B#``````` +XM``(````A````_/________]_#`````````(````7````_/________^3#``` +XM``````L````"````M@````````#+#`````````(````H````_/_________H +XM#`````````(````I````_/__________#`````````(````)````_/______ +XM__\=#0````````(````J````_/________]4#0````````H````"````M@`` +XM``````!^#0````````(````6````_/________^3#0````````(````,```` +XM_/________^X#0````````H````"````I@````````#2#0````````H````" +XM````K@`````````1#@````````(````H````_/________\J#@````````(` +XM```I````_/________\^#@````````(````,````_/________].#@`````` +XM``(````)````_/________]K#@````````(````J````_/________^;#@`` +XM``````(````7````_/_________<#@````````(````K````_/_________W +XM#@````````(````;````_/________\!#P````````(````3````_/______ +XM__\0#P````````(````/````_/________\5#P````````H````"````C@`` +XM```````D#P````````(````0````_/________\I#P````````(````3```` +XM_/________])#P````````(````/````_/________].#P````````H````" +XM````/P(```````!=#P````````(````0````_/________]G#P````````(` +XM```/````_/________]L#P````````H````"````(P(```````![#P`````` +XM``(````0````_/________^%#P````````(````/````_/________^*#P`` +XM``````H````"````@P(```````"9#P````````(````0````_/________^C +XM#P````````(````/````_/________^H#P````````H````"````;0(````` +XM``"W#P````````(````0````_/________^\#P````````H````"````JP$` +XM``````#&#P````````(````8````_/_________0#P````````(````/```` +XM_/_________5#P````````H````"````"`(```````#D#P````````(````0 +XM````_/_________N#P````````(````/````_/_________S#P````````H` +XM```"````50(````````"$`````````(````0````_/________\F$``````` +XM``(````L````_/________\Q$`````````(````M````_/________]E$``` +XM``````(````L````_/________]P$`````````(````M````_/________^D +XM$`````````(````M````_/________^N$`````````(````N````_/______ +XM__^W$`````````(````M````_/________^_$`````````(````N````_/__ +XM_______3$`````````(````O````_/_________B$`````````(````O```` +XM_/________\W$0````````H````"````I@````````!7$0````````(````Q +XM````_/________^`$0````````H````"````K@````````"2$0````````H` +XM```"````M@````````#J$0````````(````C````_/________\,$@`````` +XM``(````R````_/________\A$@````````(````:````_/________\[$@`` +XM``````(````C````_/________]9$@````````(````)````_/_________! +XM$@````````(````3````_/________\"$P````````(````C````_/______ +XM__^I$P````````(````E````_/_________!$P````````(````B````_/__ +XM______\)%`````````(````9````_/________\9%`````````(````A```` +XM_/________]@%`````````(````:````_/________]M%`````````(````3 +XM````_/________][%`````````(````L````_/________^*%`````````(` +XM```M````_/_________6%`````````(````S````_/________\V%0`````` +XM``(````S````_/________]0%0````````(````A````_/________]<%0`` +XM``````(````E````_/________]T%0````````(````S````_/________^B +XM%0````````(````R````_/________^W%0````````(````A````_/______ +XM___`%0````````(````E````_/_________4%0````````H````"````O@(` +XM``````#@%0````````(````8````_/_________G%0````````(````M```` +XM_/_________Q%0````````(````N````_/________\E%@````````(````: +XM````_/________]#%@````````(````T````_/________]G%@````````(` +XM```,````_/________][%@````````(````J````_/________^1%@`````` +XM``(````U````_/________^J%@````````(````C````_/_________:%@`` +XM``````(````O````_/_________I%@````````(````C````_/________\3 +XM%P````````(````/````_/________\8%P````````H````"`````P$````` +XM```G%P````````(````0````_/________\L%P````````H````"````L`(` +XM```````V%P````````(````8````_/________]`%P````````(````/```` +XM_/________]%%P````````H````"````D0$```````!4%P````````(````0 +XM````_/________]>%P````````(````/````_/________]C%P````````H` +XM```"````/P(```````!R%P````````(````0````_/________]\%P`````` +XM``(````/````_/________^!%P````````H````"````F0(```````"0%P`` +XM``````(````0````_/________^5%P````````(````3````_/_________% +XM%P````````(````@````_/________]A`P````````(````4````_/______ +XM__\@``````````H````!```````````````X``````````H````!````<``` +XM``````!8``````````H````!````,`(```````"```````````H````!```` +XM,`,```````"8``````````H````!````H`,```````#(``````````H````! +XM````D`4```````#H``````````H````!````D`8````````(`0````````H` +XM```!````T`<````````P`0````````H````!``````D```````!0`0`````` +XM``H````!``````H```````!X`0````````H````!````L`H```````"0`0`` +XM``````H````!````X`H```````"H`0````````H````!````(`L```````#( +XM`0````````H````!````8`P``````````@````````H````!````$!`````` +XM```@`@````````H````!````\!`````````````````````````````````` XM```````````````````````````````````````````````````````````` -XM```````````````````````````@`````0````8```````````````````!` -XM`````````-X7```````````````````0````````````````````&P````0` -XM````````````````````````:"@```````"0%0````````L````!````"``` -XM```````8`````````"8````!`````P```````````````````"`8```````` -XM``````````````````````0````````````````````L````"`````,````` -XM```````````````@&``````````````````````````````$```````````` -XM````````,0````$`````````````````````````(!@````````P```````` -XM`````````````0```````````````````#H````!````,@`````````````` -XM`````%`8````````UP(```````````````````$``````````0````````!) -XM`````0```#(````````````````````H&P```````"T````````````````` -XM```(``````````$`````````70````$````"````````````````````6!L` -XM``````!0`@``````````````````"````````````````````%@````$```` -XM`````````````````````/@]````````@`$````````+````"`````@````` -XM````&``````````1`````P````````````````````````"H'0```````&<` -XM```````````````````!`````````````````````0````(````````````` -XM````````````4"$````````0!0````````P````(````"``````````8```` -XM``````D````#`````````````````````````&`F````````!@(````````` -XM``````````$````````````````````````````````````````````````` -XM`````````P`!`````````````````````````````P`&```````````````` -XM`````````````P`'`````````````````````````````P`#```````````` -XM`````````````````P`$`````````````````````````````P`%```````` -XM`````````````````````P`(```````````````````````!````$@`!`'`` -XM````````M@$````````.````$``````````````````````````;````$``` -XM```````````````````````G````$``````````````````````````X```` -XM$`````````````````````````!#````$`````````````````````````!3 -XM````$`````````````````````````!;````$``````````````````````` -XM``!F````$`````````````````````````!K````$@`!`#`"````````_``` -XM``````!W````$`````````````````````````"%````$``````````````` -XM``````````"/````$`````````````````````````"@````$@`!`*`#```` -XM````Z0$```````"P````$`````````````````````````"[````$``````` -XM``````````````````#"````$`````````````````````````#&````$@`! -XM`)`%````````]`````````#0````$`````````````````````````#<```` -XM$@`!`)`&````````.0$```````#F````$@`!`-`'````````+P$```````#V -XM````$`````````````````````````#\````$@`!```)````````_P`````` -XM```)`0``$``````````````````````````6`0``$``````````````````` -XM```````A`0``$@`!```*````````H@`````````P`0``$``````````````` -XM```````````W`0``$``````````````````````````^`0``$``````````` -XM``````````````!%`0``$`````````````````````````!,`0``$``````` -XM``````````````````!4`0``$@`!`&`,````````I@,```````!?`0``$``` -XM``````````````````````!O`0``$`````````````````````````![`0`` -XM$`````````````````````````"&`0``$`````````````````````````"8 -XM`0``$`````````````````````````"E`0``$``````````````````````` -XM``"O`0``$`````````````````````````"T`0``$``````````````````` -XM``````"\`0``$@`!`/`0````````[@8```````#)`0``$``````````````` -XM``````````#7`0``$`````````````````````````#>`0``$``````````` -XM``````````````#F`0``$`````````````````````````#R`0``$``````` -XM````````````````````5]S:&1R`')E`!I;G-E -XMF4`;&]O:W5P7W-E8U]A -XM8W0`'1S8VX`96QF7W-T0!G96QF7V=E=')E;`!L;V]K=7!?:V5E<%]S>6UL:7-T````EP`````` -XM```"````"0```/S_________[@`````````"````"@```/S_________&P$` -XM```````"````"P```/S_________60$````````"````#````/S_________ -XM9@$````````"````#0```/S_________I0$````````"````#@```/S_____ -XM____M`$````````"````#P```/S_________N0$````````*`````@`````` -XM````````R`$````````"````$````/S_________T@$````````"````#P`` -XM`/S_________UP$````````*`````@```!X`````````Y@$````````"```` -XM$````/S_________\`$````````"````#P```/S_________]0$````````* -XM`````@```#<`````````!`(````````"````$````/S_________#@(````` -XM```"````#P```/S_________$P(````````*`````@```%4`````````(@(` -XM```````"````$````/S_________3P(````````"````"0```/S_________ -XM8`(````````"````$@```/S_________EP(````````"````#````/S_____ -XM____J`(````````"````"P```/S_________N@(````````"````$P```/S_ -XM________VP(````````"````#P```/S_________X`(````````*`````@`` -XM`'(`````````[P(````````"````$````/S_________^0(````````"```` -XM#P```/S__________@(````````*`````@```#<`````````#0,````````" -XM````$````/S_________%`,````````"````#P```/S_________&0,````` -XM```*`````@```(X`````````*`,````````"````$````/S_________:0,` -XM```````*`````@```*4`````````;@,````````"````%````/S_________ -XM=@,````````*`````@```*8`````````>P,````````"````%````/S_____ -XM____@P,````````*`````@```*X`````````B`,````````"````%````/S_ -XM________C0,````````*`````@```+8`````````E0,````````"````%``` -XM`/S_________O0,````````*`````@```+8`````````]0,````````"```` -XM%@```/S_________$`0````````"````%P```/S_________;P0````````" -XM````"@```/S_________LP0````````"````"0```/S_________V@0````` -XM```"````"P```/S_________!@4````````"````#P```/S_________"P4` -XM```````*`````@```,``````````&@4````````"````$````/S_________ -XM'P4````````*`````@```-@`````````*P4````````"````&````/S_____ -XM____-04````````"````#P```/S_________.@4````````*`````@```!X` -XM````````204````````"````$````/S_________4P4````````"````#P`` -XM`/S_________6`4````````*`````@```.4`````````9P4````````"```` -XM$````/S_________<04````````"````#P```/S_________=@4````````* -XM`````@```#<`````````A04````````"````$````/S_________M04````` -XM```"````"@```/S__________@4````````"````&@```/S_________"P8` -XM```````"````$P```/S_________408````````"````#P```/S_________ -XM5@8````````*`````@```!X`````````908````````"````$````/S_____ -XM____;`8````````"````#P```/S_________<08````````*`````@````,! -XM````````@`8````````"````$````/S_________O08````````"````"0`` -XM`/S_________T08````````"````"0```/S_________/P<````````"```` -XM"P```/S_________=0<````````"````#P```/S_________>@<````````* -XM`````@```!P!````````B0<````````"````$````/S_________DP<````` -XM```"````#P```/S_________F`<````````*`````@```#H!````````IP<` -XM```````"````$````/S_________L0<````````"````#P```/S_________ -XMM@<````````*`````@```%@!````````Q0<````````"````$````/S_____ -XM____2P@````````"````"0```/S_________;@@````````"````"P```/S_ -XM________LP@````````*`````P``````````````N@@````````"````'0`` -XM`/S_________R0@````````"````#P```/S_________S@@````````*```` -XM`@```',!````````W0@````````"````$````/S_________YP@````````" -XM````#P```/S_________[`@````````*`````@```%@!````````^P@````` -XM```"````$````/S_________$0D````````"````'P```/S_________*0D` -XM```````"````%P```/S_________>@D````````"````(````/S_________ -XMN`D````````"````#P```/S_________O0D````````*`````@```)$!```` -XM````S`D````````"````$````/S_________U@D````````"````#P```/S_ -XM________VPD````````*`````@```+D!````````Z@D````````"````$``` -XM`/S_________[PD````````*`````@```*L!````````^PD````````"```` -XM$````/S_________,0H````````"````(@```/S_________5`H````````" -XM````(P```/S_________:PH````````"````)````/S_________E`H````` -XM```*`````@```-$!````````G@H````````"````$````/S_________MPH` -XM```````"````(0```/S_________YPH````````"````(0```/S_________ -XM0@L````````*`````@```+8`````````:0L````````*`````@```*8````` -XM````A@L````````*`````@```*X`````````EPL````````*`````@```.,! -XM````````H@L````````+`````@```.,!````````JPL````````+`````@`` -XM`.H!````````M`L````````+`````@```/P!````````O0L````````+```` -XM`@````("````````X@L````````"````)0```/S_________\`L````````" -XM````)@```/S_________(@P````````"````(0```/S_________?PP````` -XM```"````%P```/S_________DPP````````+`````@```+8`````````RPP` -XM```````"````*````/S_________Z`P````````"````*0```/S_________ -XM_PP````````"````"0```/S_________'0T````````"````*@```/S_____ -XM____5`T````````*`````@```+8`````````?@T````````"````%@```/S_ -XM________DPT````````"````#````/S_________N`T````````*`````@`` -XM`*8`````````T@T````````*`````@```*X`````````$0X````````"```` -XM*````/S_________*@X````````"````*0```/S_________/@X````````" -XM````#````/S_________3@X````````"````"0```/S_________:PX````` -XM```"````*@```/S_________FPX````````"````%P```/S_________W`X` -XM```````"````*P```/S_________]PX````````"````&P```/S_________ -XM`0\````````"````$P```/S_________$`\````````"````#P```/S_____ -XM____%0\````````*`````@```(X`````````)`\````````"````$````/S_ -XM________*0\````````"````$P```/S_________20\````````"````#P`` -XM`/S_________3@\````````*`````@```#\"````````70\````````"```` -XM$````/S_________9P\````````"````#P```/S_________;`\````````* -XM`````@```","````````>P\````````"````$````/S_________A0\````` -XM```"````#P```/S_________B@\````````*`````@```(,"````````F0\` -XM```````"````$````/S_________HP\````````"````#P```/S_________ -XMJ`\````````*`````@```&T"````````MP\````````"````$````/S_____ -XM____O`\````````*`````@```*L!````````Q@\````````"````&````/S_ -XM________T`\````````"````#P```/S_________U0\````````*`````@`` -XM``@"````````Y`\````````"````$````/S_________[@\````````"```` -XM#P```/S_________\P\````````*`````@```%4"`````````A`````````" -XM````$````/S_________)A`````````"````+````/S_________,1`````` -XM```"````+0```/S_________91`````````"````+````/S_________Q0````````"```` -XM+````/S_________BA0````````"````+0```/S_________UA0````````" -XM````,P```/S_________-A4````````"````,P```/S_________4!4````` -XM```"````(0```/S_________7!4````````"````)0```/S_________=!4` -XM```````"````,P```/S_________HA4````````"````,@```/S_________ -XMMQ4````````"````(0```/S_________P!4````````"````)0```/S_____ -XM____U!4````````*`````@```+X"````````X!4````````"````&````/S_ -XM________YQ4````````"````+0```/S_________\14````````"````+@`` -XM`/S_________)18````````"````&@```/S_________0Q8````````"```` -XM-````/S_________9Q8````````"````#````/S_________>Q8````````" -XM````*@```/S_________D18````````"````-0```/S_________JA8````` -XM```"````(P```/S_________VA8````````"````+P```/S_________Z18` -XM```````"````(P```/S_________$Q<````````"````#P```/S_________ -XM&!<````````*`````@````,!````````)Q<````````"````$````/S_____ -XM____+!<````````*`````@```+`"````````-A<````````"````&````/S_ -XM________0!<````````"````#P```/S_________11<````````*`````@`` -XM`)$!````````5!<````````"````$````/S_________7A<````````"```` -XM#P```/S_________8Q<````````*`````@```#\"`````````$````` -XM```*`````0```+`*````````D`$````````*`````0```.`*````````J`$` -XM```````*`````0```"`+````````R`$````````*`````0```&`,```````` -XM``(````````*`````0```!`0````````(`(````````*`````0```/`0```` +XM(`````$````&````````````````````0`````````#>%P`````````````` +XM````$````````````````````!L````$````0````````````````````"@E +XM````````D!4````````+`````0````@`````````&``````````F`````0`` +XM``,````````````````````@&``````````````````````````````$```` +XM````````````````+`````@````#````````````````````(!@````````` +XM````````````````````!````````````````````#$````!```````````` +XM`````````````"`8````````,`````````````````````$````````````` +XM```````Z`````0```#(```````````````````!0&````````-<"```````` +XM```````````!``````````$`````````20````$````R```````````````` +XM````*!L````````M````````````````````"``````````!`````````%T` +XM```!`````@```````````````````%@;````````4`(````````````````` +XM``@```````````````````!8````!````$````````````````````"X.@`` +XM`````(`!````````"P````@````(`````````!@`````````$0````,````` +XM````````````````````J!T```````!G`````````````````````0`````` +XM``````````````$````"`````````````````````````!`>````````$`4` +XM```````,````"`````@`````````&``````````)`````P`````````````` +XM```````````@(P````````8"```````````````````!```````````````` X#```` X` Xend -END-of-sections.o.1.uu +eb2ac2808b7045ab3c2faf26922f5e01 echo x - sections.o.uu -sed 's/^X//' >sections.o.uu << 'END-of-sections.o.uu' +sed 's/^X//' >sections.o.uu << 'f3eccedeeefe85afebc666fca5eb0742' Xbegin 644 sections.o XM?T5,1@(!`0D```````````$`/@`!`````````````````````````"!Q```` XM`````````$```````$``&P`8`$B+E\````!(A=)T'TB+1B!(.T(@elfcopy.1.uu << 'END-of-elfcopy.1.uu' -Xbegin 755 elfcopy.1 +sed 's/^X//' >elfcopy.1.uu << 'e4e59173f6354081a9e3a7debde2f069' +Xbegin 644 elfcopy.1 XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````'B!```` XM`````````$``.``'`$``&@`9``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -759,8 +759,8 @@ XMT`M```````#0"P````````\#```````````````````!```````````````` XM````-P```/___V\"`````````.`.0```````X`X```````"@``````````0` XM`````````@`````````"`````````$0```#^__]O`@````````"`#T`````` XM`(`/````````0``````````%`````@````@```````````````````!3```` -XM!`````(`````````P`]```````#`#P```````'@`````````!``````````( -XM`````````!@`````````70````0````"`````````#@00```````.!`````` +XM!````$(`````````P`]```````#`#P```````'@`````````!``````````( +XM`````````!@`````````70````0```!"`````````#@00```````.!`````` XM``"0!@````````0````+````"``````````8`````````&<````!````!@`` XM``````#(%D```````,@6````````$P````````````````````0````````` XM``````````!B`````0````8`````````W!9```````#<%@```````'`$```` @@ -787,10 +787,10 @@ XM``````$````#`````````````````````````*:`````````S@`````````` X7``````````$````````````````````` X` Xend -END-of-elfcopy.1.uu +e4e59173f6354081a9e3a7debde2f069 echo x - elfcopy.uu -sed 's/^X//' >elfcopy.uu << 'END-of-elfcopy.uu' -Xbegin 755 elfcopy +sed 's/^X//' >elfcopy.uu << '2151ae8f08071e33d3c60fbc8f2d2844' +Xbegin 644 elfcopy XM?T5,1@(!`0D```````````(`/@`!````4!M```````!``````````#AM`0`` XM`````````$``.``'`$``)0`B``8````%````0`````````!``$```````$`` XM0```````B`$```````"(`0````````@``````````P````0```#(`0`````` @@ -3078,6 +3078,6 @@ XM7U)E9VES=&5R0VQA0; however -# TET 3.8's headers do not compile with -Wstrict-prototypes. -.if ${OS_HOST} != NetBSD +# TET 3.8's headers do not compile with -Wstrict-prototypes, so restrict the +# OSes for which we use a non-zero WARNS value. +.if ${OS_HOST} == FreeBSD || ${OS_HOST} == DragonFly || ${OS_HOST} == Minix WARNS?= 2 .endif From b1d46e7cb0eb6f54325513bc1b95e56d0cf336f4 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 10 Feb 2016 20:28:28 +0000 Subject: [PATCH 035/142] ntb_hw(4): Allow any x86 PAT caching flags for MW defaults Replace the hw.ntb.enable_writecombine tunable with hw.ntb.default_mw_pat. It can be set with several specific numerical values to select a caching type. Any bogus value is treated as Uncacheable (UC). The ntb_mw_set_wc() KPI has removed the restriction that the selected mode must be one of UC, WC, or WB. Sponsored by: EMC / Isilon Storage Division --- sys/dev/ntb/ntb_hw/ntb_hw.c | 55 +++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index f71d9e45ac23..44f51762a458 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -331,9 +331,43 @@ SYSCTL_UINT(_hw_ntb, OID_AUTO, debug_level, CTLFLAG_RWTUN, } \ } while (0) -static unsigned g_ntb_enable_wc = 1; -SYSCTL_UINT(_hw_ntb, OID_AUTO, enable_writecombine, CTLFLAG_RDTUN, - &g_ntb_enable_wc, 0, "Set to 1 to map memory windows write combining"); +#define _NTB_PAT_UC 0 +#define _NTB_PAT_WC 1 +#define _NTB_PAT_WT 4 +#define _NTB_PAT_WP 5 +#define _NTB_PAT_WB 6 +#define _NTB_PAT_UCM 7 +static unsigned g_ntb_mw_pat = _NTB_PAT_UC; +SYSCTL_UINT(_hw_ntb, OID_AUTO, default_mw_pat, CTLFLAG_RDTUN, + &g_ntb_mw_pat, 0, "Configure the default memory window cache flags (PAT): " + "UC: " __XSTRING(_NTB_PAT_UC) ", " + "WC: " __XSTRING(_NTB_PAT_WC) ", " + "WT: " __XSTRING(_NTB_PAT_WT) ", " + "WP: " __XSTRING(_NTB_PAT_WP) ", " + "WB: " __XSTRING(_NTB_PAT_WB) ", " + "UC-: " __XSTRING(_NTB_PAT_UCM)); + +static inline vm_memattr_t +ntb_pat_flags(void) +{ + + switch (g_ntb_mw_pat) { + case _NTB_PAT_WC: + return (VM_MEMATTR_WRITE_COMBINING); + case _NTB_PAT_WT: + return (VM_MEMATTR_WRITE_THROUGH); + case _NTB_PAT_WP: + return (VM_MEMATTR_WRITE_PROTECTED); + case _NTB_PAT_WB: + return (VM_MEMATTR_WRITE_BACK); + case _NTB_PAT_UCM: + return (VM_MEMATTR_WEAK_UNCACHEABLE); + case _NTB_PAT_UC: + /* FALLTHROUGH */ + default: + return (VM_MEMATTR_UNCACHEABLE); + } +} static int g_ntb_mw_idx = -1; SYSCTL_INT(_hw_ntb, OID_AUTO, b2b_mw_idx, CTLFLAG_RDTUN, &g_ntb_mw_idx, @@ -777,10 +811,13 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) bar->map_mode = VM_MEMATTR_UNCACHEABLE; print_map_success(ntb, bar, "mw"); - /* Mark bar region as write combining to improve performance. */ - mapmode = VM_MEMATTR_WRITE_COMBINING; - if (g_ntb_enable_wc == 0) - mapmode = VM_MEMATTR_WRITE_BACK; + /* + * Optionally, mark MW BARs as anything other than UC to improve + * performance. + */ + mapmode = ntb_pat_flags(); + if (mapmode == bar->map_mode) + return (0); rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mapmode); if (rc == 0) { @@ -2728,10 +2765,6 @@ ntb_mw_set_wc_internal(struct ntb_softc *ntb, unsigned idx, vm_memattr_t mode) if (bar->map_mode == mode) return (0); - if (mode != VM_MEMATTR_UNCACHEABLE && mode != VM_MEMATTR_DEFAULT && - mode != VM_MEMATTR_WRITE_COMBINING) - return (EINVAL); - rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mode); if (rc == 0) bar->map_mode = mode; From 6ea028df502670b7295b17f4224ad6ca1d54c6cc Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 10 Feb 2016 20:49:22 +0000 Subject: [PATCH 036/142] ntb_hw(4): Print correct PAT name for non-WC/WB types mapped at load Sponsored by: EMC / Isilon Storage Division --- sys/dev/ntb/ntb_hw/ntb_hw.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 44f51762a458..abfbf71acad3 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -369,6 +369,32 @@ ntb_pat_flags(void) } } +/* + * Well, this obviously doesn't belong here, but it doesn't seem to exist + * anywhere better yet. + */ +static inline const char * +ntb_vm_memattr_to_str(vm_memattr_t pat) +{ + + switch (pat) { + case VM_MEMATTR_WRITE_COMBINING: + return ("WRITE_COMBINING"); + case VM_MEMATTR_WRITE_THROUGH: + return ("WRITE_THROUGH"); + case VM_MEMATTR_WRITE_PROTECTED: + return ("WRITE_PROTECTED"); + case VM_MEMATTR_WRITE_BACK: + return ("WRITE_BACK"); + case VM_MEMATTR_WEAK_UNCACHEABLE: + return ("UNCACHED"); + case VM_MEMATTR_UNCACHEABLE: + return ("UNCACHEABLE"); + default: + return ("UNKNOWN"); + } +} + static int g_ntb_mw_idx = -1; SYSCTL_INT(_hw_ntb, OID_AUTO, b2b_mw_idx, CTLFLAG_RDTUN, &g_ntb_mw_idx, 0, "Use this memory window to access the peer NTB registers. A " @@ -828,8 +854,7 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) PCI_RID2BAR(bar->pci_resource_id), bar->vbase, (char *)bar->vbase + bar->size - 1, (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), - (mapmode == VM_MEMATTR_WRITE_COMBINING) ? "WRITE_COMBINING" - : "WRITE_BACK"); + ntb_vm_memattr_to_str(mapmode)); } else device_printf(ntb->device, "Unable to mark BAR%d v:[%p-%p] p:[%p-%p] as " @@ -837,8 +862,7 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) PCI_RID2BAR(bar->pci_resource_id), bar->vbase, (char *)bar->vbase + bar->size - 1, (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), - (mapmode == VM_MEMATTR_WRITE_COMBINING) ? "WRITE_COMBINING" - : "WRITE_BACK", rc); + ntb_vm_memattr_to_str(mapmode), rc); /* Proceed anyway */ return (0); } From 86a448c3a4bd5d826a6d91d06ef4143c0a8dd207 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 10 Feb 2016 21:16:37 +0000 Subject: [PATCH 037/142] Finish r173600. There is no need to test a condition if both cases result in the same value. Found by: PVS-Studio Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/kern/subr_turnstile.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c index 7765cbf68c64..57d9f0975d14 100644 --- a/sys/kern/subr_turnstile.c +++ b/sys/kern/subr_turnstile.c @@ -1026,8 +1026,7 @@ print_thread(struct thread *td, const char *prefix) { db_printf("%s%p (tid %d, pid %d, \"%s\")\n", prefix, td, td->td_tid, - td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name : - td->td_name); + td->td_proc->p_pid, td->td_name); } static void @@ -1109,8 +1108,7 @@ print_lockchain(struct thread *td, const char *prefix) */ while (!db_pager_quit) { db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid, - td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name : - td->td_name); + td->td_proc->p_pid, td->td_name); switch (td->td_state) { case TDS_INACTIVE: db_printf("is inactive\n"); @@ -1193,8 +1191,7 @@ print_sleepchain(struct thread *td, const char *prefix) */ while (!db_pager_quit) { db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid, - td->td_proc->p_pid, td->td_name[0] != '\0' ? td->td_name : - td->td_name); + td->td_proc->p_pid, td->td_name); switch (td->td_state) { case TDS_INACTIVE: db_printf("is inactive\n"); From 0be1e0e879733b5970fcf20d3b24533b3a22c401 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 10 Feb 2016 21:35:00 +0000 Subject: [PATCH 038/142] Remove useless checks for NULL before calling free(9), in the kernel elf linkers. Found by: Related PVS-Studio diagnostic Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/kern/link_elf.c | 27 +++++++------------ sys/kern/link_elf_obj.c | 57 ++++++++++++++--------------------------- 2 files changed, 28 insertions(+), 56 deletions(-) diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index bf2dfd00a375..1579c28dd3b1 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -1090,12 +1090,9 @@ link_elf_load_file(linker_class_t cls, const char* filename, vn_close(nd.ni_vp, FREAD, td->td_ucred, td); if (error != 0 && lf != NULL) linker_file_unload(lf, LINKER_UNLOAD_FORCE); - if (shdr != NULL) - free(shdr, M_LINKER); - if (firstpage != NULL) - free(firstpage, M_LINKER); - if (shstrs != NULL) - free(shstrs, M_LINKER); + free(shdr, M_LINKER); + free(firstpage, M_LINKER); + free(shstrs, M_LINKER); return (error); } @@ -1157,19 +1154,13 @@ link_elf_unload_file(linker_file_t file) + (ef->object->size << PAGE_SHIFT)); } #else - if (ef->address != NULL) - free(ef->address, M_LINKER); + free(ef->address, M_LINKER); #endif - if (ef->symbase != NULL) - free(ef->symbase, M_LINKER); - if (ef->strbase != NULL) - free(ef->strbase, M_LINKER); - if (ef->ctftab != NULL) - free(ef->ctftab, M_LINKER); - if (ef->ctfoff != NULL) - free(ef->ctfoff, M_LINKER); - if (ef->typoff != NULL) - free(ef->typoff, M_LINKER); + free(ef->symbase, M_LINKER); + free(ef->strbase, M_LINKER); + free(ef->ctftab, M_LINKER); + free(ef->ctfoff, M_LINKER); + free(ef->typoff, M_LINKER); } static void diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 00fe1e418642..4d08aba66589 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -898,8 +898,7 @@ link_elf_load_file(linker_class_t cls, const char *filename, vn_close(nd.ni_vp, FREAD, td->td_ucred, td); if (error && lf) linker_file_unload(lf, LINKER_UNLOAD_FORCE); - if (hdr) - free(hdr, M_LINKER); + free(hdr, M_LINKER); return error; } @@ -930,18 +929,12 @@ link_elf_unload_file(linker_file_t file) } } if (ef->preloaded) { - if (ef->reltab) - free(ef->reltab, M_LINKER); - if (ef->relatab) - free(ef->relatab, M_LINKER); - if (ef->progtab) - free(ef->progtab, M_LINKER); - if (ef->ctftab) - free(ef->ctftab, M_LINKER); - if (ef->ctfoff) - free(ef->ctfoff, M_LINKER); - if (ef->typoff) - free(ef->typoff, M_LINKER); + free(ef->reltab, M_LINKER); + free(ef->relatab, M_LINKER); + free(ef->progtab, M_LINKER); + free(ef->ctftab, M_LINKER); + free(ef->ctfoff, M_LINKER); + free(ef->typoff, M_LINKER); if (file->filename != NULL) preload_delete_name(file->filename); /* XXX reclaim module memory? */ @@ -949,37 +942,25 @@ link_elf_unload_file(linker_file_t file) } for (i = 0; i < ef->nreltab; i++) - if (ef->reltab[i].rel) - free(ef->reltab[i].rel, M_LINKER); + free(ef->reltab[i].rel, M_LINKER); for (i = 0; i < ef->nrelatab; i++) - if (ef->relatab[i].rela) - free(ef->relatab[i].rela, M_LINKER); - if (ef->reltab) - free(ef->reltab, M_LINKER); - if (ef->relatab) - free(ef->relatab, M_LINKER); - if (ef->progtab) - free(ef->progtab, M_LINKER); + free(ef->relatab[i].rela, M_LINKER); + free(ef->reltab, M_LINKER); + free(ef->relatab, M_LINKER); + free(ef->progtab, M_LINKER); if (ef->object) { vm_map_remove(kernel_map, (vm_offset_t) ef->address, (vm_offset_t) ef->address + (ef->object->size << PAGE_SHIFT)); } - if (ef->e_shdr) - free(ef->e_shdr, M_LINKER); - if (ef->ddbsymtab) - free(ef->ddbsymtab, M_LINKER); - if (ef->ddbstrtab) - free(ef->ddbstrtab, M_LINKER); - if (ef->shstrtab) - free(ef->shstrtab, M_LINKER); - if (ef->ctftab) - free(ef->ctftab, M_LINKER); - if (ef->ctfoff) - free(ef->ctfoff, M_LINKER); - if (ef->typoff) - free(ef->typoff, M_LINKER); + free(ef->e_shdr, M_LINKER); + free(ef->ddbsymtab, M_LINKER); + free(ef->ddbstrtab, M_LINKER); + free(ef->shstrtab, M_LINKER); + free(ef->ctftab, M_LINKER); + free(ef->ctfoff, M_LINKER); + free(ef->typoff, M_LINKER); } static const char * From 85704ba592cab85201dd16b0161bf61e540b349c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 10 Feb 2016 23:57:09 +0000 Subject: [PATCH 039/142] Update list of binutils controlled by WITHOUT_BINUTILS_BOOTSTRAP Tools removed from the list are now provided by the ELF Tool Chain project and are not controlled by the WITHOUT_BINUTILS_BOOTSTRAP knob. Sponsored by: The FreeBSD Foundation --- tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP b/tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP index 84ae1a1706f2..c64c46914c3a 100644 --- a/tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP +++ b/tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP @@ -1,6 +1,5 @@ .\" $FreeBSD$ -Set to not build binutils (as, c++-filt, gconv, -ld, nm, objcopy, objdump, readelf, size and strip) +Set to not build binutils (as, ld, objcopy and objdump) as part of the bootstrap process. .Bf -symbolic The option does not work for build targets unless some alternative From 201186d6ec0b956e80629aebd75a1a0e3aa182ac Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 11 Feb 2016 00:14:00 +0000 Subject: [PATCH 040/142] Add missing src.conf(5) descriptions for tool chain components Sponsored by: The FreeBSD Foundation --- tools/build/options/WITHOUT_ELFTOOLCHAIN_BOOTSTRAP | 7 +++++++ tools/build/options/WITH_BINUTILS | 3 +++ tools/build/options/WITH_BINUTILS_BOOTSTRAP | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 tools/build/options/WITHOUT_ELFTOOLCHAIN_BOOTSTRAP create mode 100644 tools/build/options/WITH_BINUTILS create mode 100644 tools/build/options/WITH_BINUTILS_BOOTSTRAP diff --git a/tools/build/options/WITHOUT_ELFTOOLCHAIN_BOOTSTRAP b/tools/build/options/WITHOUT_ELFTOOLCHAIN_BOOTSTRAP new file mode 100644 index 000000000000..85fa01eabd76 --- /dev/null +++ b/tools/build/options/WITHOUT_ELFTOOLCHAIN_BOOTSTRAP @@ -0,0 +1,7 @@ +.\" $FreeBSD$ +Set to not build ELF Tool Chain tools +(addr2line, nm, size, strings and strip) +as part of the bootstrap process. +.Bf -symbolic +An alternate bootstrap tool chain must be provided. +.Ef diff --git a/tools/build/options/WITH_BINUTILS b/tools/build/options/WITH_BINUTILS new file mode 100644 index 000000000000..619dc2161962 --- /dev/null +++ b/tools/build/options/WITH_BINUTILS @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Set to build and install binutils (as, ld, objcopy, and objdump) as part +of the normal system build. diff --git a/tools/build/options/WITH_BINUTILS_BOOTSTRAP b/tools/build/options/WITH_BINUTILS_BOOTSTRAP new file mode 100644 index 000000000000..f32cb0658d4d --- /dev/null +++ b/tools/build/options/WITH_BINUTILS_BOOTSTRAP @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Set build binutils (as, ld, objcopy and objdump) +as part of the bootstrap process. From 656cbd27d2cc7e864207ba71d10d9cd681e7f0ef Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 11 Feb 2016 00:30:51 +0000 Subject: [PATCH 041/142] Add WITH_GDB src.conf(5) description --- tools/build/options/WITH_GDB | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tools/build/options/WITH_GDB diff --git a/tools/build/options/WITH_GDB b/tools/build/options/WITH_GDB new file mode 100644 index 000000000000..994942e8ff9e --- /dev/null +++ b/tools/build/options/WITH_GDB @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Set to build +.Xr gdb 1 . From 78f6ea5440f43a014c10e03d32b6901f86cc65d8 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Thu, 11 Feb 2016 00:34:11 +0000 Subject: [PATCH 042/142] Ext4: fix handling of files with sparse blocks before extent's index. This is ongoing work from Damjan Jovanovic to improve ext4 read support with sparse files: Keep track of the first and last block in each extent as it descends down the extent tree, thus being able to work out that some blocks are sparse earlier. This solves an issue on r293680. In ext4_bmapext() start supporting the runb parameter, which appears to be the number of adjacent blocks prior to the block being converted in the same way that runp is the number of blocks after, speding up random access to mmaped files. PR: 206652 --- sys/fs/ext2fs/ext2_bmap.c | 4 +++ sys/fs/ext2fs/ext2_extents.c | 55 ++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index 8656e59ed8f0..8e5e9863aeae 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -114,6 +114,8 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) if (runp != NULL) *runp = path.ep_sparse_ext.e_len - (lbn - path.ep_sparse_ext.e_blk) - 1; + if (runb != NULL) + *runb = lbn - path.ep_sparse_ext.e_blk; } else { ep = path.ep_ext; if (ep == NULL) @@ -127,6 +129,8 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb) if (runp != NULL) *runp = ep->e_len - (lbn - ep->e_blk) - 1; + if (runb != NULL) + *runb = lbn - ep->e_blk; } } diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c index 1317fdcca2c4..230356c277f1 100644 --- a/sys/fs/ext2fs/ext2_extents.c +++ b/sys/fs/ext2fs/ext2_extents.c @@ -43,14 +43,17 @@ #include #include -static void ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path - *path, daddr_t lbn) +static int +ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path *path, + daddr_t lbn, daddr_t *first_lbn, daddr_t *last_lbn) { struct ext4_extent_header *ehp = path->ep_header; - struct ext4_extent_index *l, *r, *m; + struct ext4_extent_index *first, *last, *l, *r, *m; - l = (struct ext4_extent_index *)(char *)(ehp + 1); - r = (struct ext4_extent_index *)(char *)(ehp + 1) + ehp->eh_ecount - 1; + first = (struct ext4_extent_index *)(char *)(ehp + 1); + last = first + ehp->eh_ecount - 1; + l = first; + r = last; while (l <= r) { m = l + (r - l) / 2; if (lbn < m->ei_blk) @@ -59,11 +62,24 @@ static void ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path l = m + 1; } + if (l == first) { + path->ep_sparse_ext.e_blk = *first_lbn; + path->ep_sparse_ext.e_len = first->ei_blk - *first_lbn; + path->ep_sparse_ext.e_start_hi = 0; + path->ep_sparse_ext.e_start_lo = 0; + path->ep_is_sparse = 1; + return (1); + } path->ep_index = l - 1; + *first_lbn = path->ep_index->ei_blk; + if (path->ep_index < last) + *last_lbn = l->ei_blk - 1; + return (0); } static void -ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn) +ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn, + daddr_t first_lbn, daddr_t last_lbn) { struct ext4_extent_header *ehp = path->ep_header; struct ext4_extent *first, *l, *r, *m; @@ -83,8 +99,8 @@ ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn) } if (l == first) { - path->ep_sparse_ext.e_blk = lbn; - path->ep_sparse_ext.e_len = first->e_blk - lbn; + path->ep_sparse_ext.e_blk = first_lbn; + path->ep_sparse_ext.e_len = first->e_blk - first_lbn; path->ep_sparse_ext.e_start_hi = 0; path->ep_sparse_ext.e_start_lo = 0; path->ep_is_sparse = 1; @@ -92,11 +108,14 @@ ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn) } path->ep_ext = l - 1; if (path->ep_ext->e_blk + path->ep_ext->e_len <= lbn) { - path->ep_sparse_ext.e_blk = lbn; + path->ep_sparse_ext.e_blk = path->ep_ext->e_blk + + path->ep_ext->e_len; if (l <= (first + ehp->eh_ecount - 1)) - path->ep_sparse_ext.e_len = l->e_blk - lbn; - else // XXX: where does it end? - path->ep_sparse_ext.e_len = 1; + path->ep_sparse_ext.e_len = l->e_blk - + path->ep_sparse_ext.e_blk; + else + path->ep_sparse_ext.e_len = last_lbn - + path->ep_sparse_ext.e_blk + 1; path->ep_sparse_ext.e_start_hi = 0; path->ep_sparse_ext.e_start_lo = 0; path->ep_is_sparse = 1; @@ -162,10 +181,16 @@ ext4_ext_find_extent(struct m_ext2fs *fs, struct inode *ip, path->ep_header = ehp; + daddr_t first_lbn = 0; + daddr_t last_lbn = lblkno(ip->i_e2fs, ip->i_size); + for (i = ehp->eh_depth; i != 0; --i) { - ext4_ext_binsearch_index(ip, path, lbn); - path->ep_depth = 0; + path->ep_depth = i; path->ep_ext = NULL; + if (ext4_ext_binsearch_index(ip, path, lbn, &first_lbn, + &last_lbn)) { + return (path); + } nblk = (daddr_t)path->ep_index->ei_leaf_hi << 32 | path->ep_index->ei_leaf_lo; @@ -190,6 +215,6 @@ ext4_ext_find_extent(struct m_ext2fs *fs, struct inode *ip, path->ep_index = NULL; path->ep_is_sparse = 0; - ext4_ext_binsearch(ip, path, lbn); + ext4_ext_binsearch(ip, path, lbn, first_lbn, last_lbn); return (path); } From 1041b71deb4af2de7a7ac51b6cfe545d2566dd89 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Thu, 11 Feb 2016 01:16:57 +0000 Subject: [PATCH 043/142] Update leapsecond file in non-chroot environments. PR: 207095 Submitted by: madpilot MFC after: 3 days --- etc/rc.d/ntpd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/rc.d/ntpd b/etc/rc.d/ntpd index 7f28358d7a82..fe2fc4ba54ab 100755 --- a/etc/rc.d/ntpd +++ b/etc/rc.d/ntpd @@ -28,14 +28,14 @@ ntpd_precmd() rc_flags="-g $rc_flags" fi - if [ -z "$ntpd_chrootdir" ]; then - return 0; - fi - if [ ! -f $ntp_db_leapfile ]; then ntpd_fetch_leapfile fi + if [ -z "$ntpd_chrootdir" ]; then + return 0; + fi + # If running in a chroot cage, ensure that the appropriate files # exist inside the cage, as well as helper symlinks into the cage # from outside. From 71de598c86c9676f0a430c85488dd2b800c63958 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 11 Feb 2016 01:30:43 +0000 Subject: [PATCH 044/142] Document boot1.efi's handling of /boot.config, added in r294768 MFC after: 3 days Sponsored by: The FreeBSD Foundation --- share/man/man8/uefi.8 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/share/man/man8/uefi.8 b/share/man/man8/uefi.8 index c4ee8827679c..8e6eb846962d 100644 --- a/share/man/man8/uefi.8 +++ b/share/man/man8/uefi.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 26, 2015 +.Dd February 11, 2016 .Dt UEFI 8 .Os .Sh NAME @@ -73,6 +73,16 @@ as .Pa /EFI/BOOT/BOOTX64.EFI . .It .Pa boot1.efi +reads boot configuration from +.Pa /boot.config +or +.Pa /boot/config . +Unlike other first-stage boot loaders, +.Pa boot1.efi +passes the configuration to the next stage boot loader and does not +itself act on the contents of the file. +.It +.Pa boot1.efi locates the first partition with the type .Li freebsd-ufs , and from it loads @@ -112,6 +122,7 @@ typical non-default kernel (optional) .El .Sh SEE ALSO .Xr vt 4 , +.Xr boot.config 5 , .Xr msdosfs 5 , .Xr boot 8 , .Xr gpart 8 , From b4ccb55306fd27cb08caddf134d86119fd13943d Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 11 Feb 2016 02:02:01 +0000 Subject: [PATCH 045/142] Update uefi.8 for ZFS and multi device boot support As of r294068 boot1.efi can load loader.efi from ZFS. As of r295320 boot1.efi prefers to load loader.efi from the same device it was loaded from. MFC after: 3 days Sponsored by: The FreeBSD Foundation --- share/man/man8/uefi.8 | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/share/man/man8/uefi.8 b/share/man/man8/uefi.8 index 8e6eb846962d..a17fb08fe6dd 100644 --- a/share/man/man8/uefi.8 +++ b/share/man/man8/uefi.8 @@ -83,9 +83,17 @@ passes the configuration to the next stage boot loader and does not itself act on the contents of the file. .It .Pa boot1.efi -locates the first partition with the type -.Li freebsd-ufs , -and from it loads +searches partitions of type +.Li freebsd-ufs +and +.Li freebsd-zfs +for +.Pa loader.efi . +The search begins with partitions on the device from which +.Pa boot1.efi +was loaded, and continues with other available partitions. +.Pa boot1.efi +then loads and executes .Pa loader.efi . .It .Pa loader.efi @@ -146,19 +154,3 @@ Foundation sponsored portions of the work. EFI environment variables are not supported by .Xr loader 8 or the kernel. -.Pp -.Pa boot1.efi -loads -.Pa loader.efi -from the first FreeBSD-UFS file system it locates, even if it is on a -different disk. -.Pp -.Pa boot1.efi -cannot load -.Pa loader.efi -from a -.Xr ZFS 8 -file system. -As a result, -.Nm -does not support a typical root file system on ZFS configuration. From 9a8d0c1f0c39a4038d79d014a6bdd8e288d829c0 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:09:27 +0000 Subject: [PATCH 046/142] Begin the MIPS_INTRNG support. This is a prelude to intr-ng support for MIPS boards that need it - notably the CI20 port from kan@ that's upcoming, but also work that Stanislav is doing for the Mediatek platforms. This is the initial platform dependent bits in include/intr.h, some #defines for the nexus code for the intrng initialisation/runtime bits, some changed naming (which I'll fix later to be the same, much like what I did for ARM intr-ng) in exception.S, and the first cut at a PIC. Stanislav and I refactored out the common code for intrng support, so the mips intrng definitions are quite small (sys/mips/include/intr.h.) This is all work done by kan@, which stanislav has been cherry picking into common code for his mediatek chipset work. Tested: * Carambola2 - no regressions (not intr-ng though!) Submitted by: Stanislav Galabov Reviewed by: kan (original author) Differential Revision: https://reviews.freebsd.org/D5182 --- sys/mips/include/intr.h | 67 +++++ sys/mips/include/smp.h | 5 + sys/mips/mips/exception.S | 10 + sys/mips/mips/mips_pic.c | 512 ++++++++++++++++++++++++++++++++++++++ sys/mips/mips/nexus.c | 87 ++++++- 5 files changed, 679 insertions(+), 2 deletions(-) create mode 100644 sys/mips/include/intr.h create mode 100644 sys/mips/mips/mips_pic.c diff --git a/sys/mips/include/intr.h b/sys/mips/include/intr.h new file mode 100644 index 000000000000..28f798f42214 --- /dev/null +++ b/sys/mips/include/intr.h @@ -0,0 +1,67 @@ +/* $NetBSD: intr.h,v 1.7 2003/06/16 20:01:00 thorpej Exp $ */ + +/*- + * Copyright (c) 1997 Mark Brinicombe. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef _MACHINE_INTR_H_ +#define _MACHINE_INTR_H_ + +#ifdef MIPS_INTRNG + +#ifdef FDT +#include +#endif + +#include + +#ifndef NIRQ +#define NIRQ 128 +#endif + +#define INTR_IRQ_NSPC_SWI 4 + +/* MIPS compatibility for legacy mips code */ +void cpu_init_interrupts(void); +void cpu_establish_hardintr(const char *, driver_filter_t *, driver_intr_t *, + void *, int, int, void **); +void cpu_establish_softintr(const char *, driver_filter_t *, void (*)(void*), + void *, int, int, void **); +/* MIPS interrupt C entry point */ +void cpu_intr(struct trapframe *); + +#endif /* MIPS_INTRNG */ + +#endif /* _MACHINE_INTR_H */ diff --git a/sys/mips/include/smp.h b/sys/mips/include/smp.h index 0fcca9af1542..fa4cb5cc31de 100644 --- a/sys/mips/include/smp.h +++ b/sys/mips/include/smp.h @@ -21,6 +21,11 @@ #include +#ifdef MIPS_INTRNG +# define MIPS_IPI_COUNT 1 +# define INTR_IPI_COUNT MIPS_IPI_COUNT +#endif + /* * Interprocessor interrupts for SMP. */ diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 01fd2106e53a..ebfd84d6ca20 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -646,7 +646,11 @@ NESTED_NOPROFILE(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra) * Call the interrupt handler. a0 points at the saved frame. */ PTR_LA gp, _C_LABEL(_gp) +#ifdef MIPS_INTRNG + PTR_LA k0, _C_LABEL(intr_irq_handler) +#else PTR_LA k0, _C_LABEL(cpu_intr) +#endif jalr k0 REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging @@ -758,7 +762,11 @@ NESTED_NOPROFILE(MipsUserIntr, CALLFRAME_SIZ, ra) /* * Call the interrupt handler. */ +#ifdef MIPS_INTRNG + PTR_LA k0, _C_LABEL(intr_irq_handler) +#else PTR_LA k0, _C_LABEL(cpu_intr) +#endif jalr k0 REG_S a3, CALLFRAME_RA(sp) # for debugging @@ -1190,6 +1198,7 @@ FPReturn: PTR_ADDU sp, sp, CALLFRAME_SIZ END(MipsFPTrap) +#ifndef MIPS_INTRNG /* * Interrupt counters for vmstat. */ @@ -1216,6 +1225,7 @@ sintrcnt: #else .int INTRCNT_COUNT * (_MIPS_SZLONG / 8) * 2 #endif +#endif /* MIPS_INTRNG */ /* diff --git a/sys/mips/mips/mips_pic.c b/sys/mips/mips/mips_pic.c new file mode 100644 index 000000000000..c20bc8dabda1 --- /dev/null +++ b/sys/mips/mips/mips_pic.c @@ -0,0 +1,512 @@ +/*- + * Copyright (c) 2015 Alexander Kabaev + * Copyright (c) 2006 Oleksandr Tymoshenko + * Copyright (c) 2002-2004 Juli Mallett + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_platform.h" +#include "opt_hwpmc_hooks.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef FDT +#include +#include +#include +#include +#endif + +#include "pic_if.h" + +#define NHARD_IRQS 6 +#define NSOFT_IRQS 2 +#define NREAL_IRQS (NHARD_IRQS + NSOFT_IRQS) + +static int mips_pic_intr(void *); + +struct mips_pic_softc { + device_t pic_dev; + struct intr_irqsrc * pic_irqs[NREAL_IRQS]; + struct mtx mutex; + uint32_t nirqs; +}; + +static struct mips_pic_softc *pic_sc; + +#ifdef FDT +static struct ofw_compat_data compat_data[] = { + {"mti,cpu-interrupt-controller", true}, + {NULL, false} +}; +#endif + +#ifndef FDT +static void +mips_pic_identify(driver_t *drv, device_t parent) +{ + + BUS_ADD_CHILD(parent, 0, "cpupic", 0); +} +#endif + +static int +mips_pic_probe(device_t dev) +{ + +#ifdef FDT + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); +#endif + device_set_desc(dev, "MIPS32 Interrupt Controller"); + return (BUS_PROBE_DEFAULT); +} + +static inline void +pic_irq_unmask(struct mips_pic_softc *sc, u_int irq) +{ + + mips_wr_status(mips_rd_status() | ((1 << irq) << 8)); +} + +static inline void +pic_irq_mask(struct mips_pic_softc *sc, u_int irq) +{ + + mips_wr_status(mips_rd_status() & ~((1 << irq) << 8)); +} + +#ifdef SMP +static void +mips_pic_init_secondary(device_t dev) +{ +} +#endif /* SMP */ + +static inline intptr_t +pic_xref(device_t dev) +{ +#ifdef FDT + return (OF_xref_from_node(ofw_bus_get_node(dev))); +#else + return (0); +#endif +} + +static int +mips_pic_attach(device_t dev) +{ + struct mips_pic_softc *sc; + intptr_t xref = pic_xref(dev); + + if (pic_sc) + return (ENXIO); + + sc = device_get_softc(dev); + + sc->pic_dev = dev; + pic_sc = sc; + + /* Initialize mutex */ + mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN); + + /* Set the number of interrupts */ + sc->nirqs = nitems(sc->pic_irqs); + + /* + * Now, when everything is initialized, it's right time to + * register interrupt controller to interrupt framefork. + */ + if (intr_pic_register(dev, xref) != 0) { + device_printf(dev, "could not register PIC\n"); + goto cleanup; + } + + /* Claim our root controller role */ + if (intr_pic_claim_root(dev, xref, mips_pic_intr, sc, 0) != 0) { + device_printf(dev, "could not set PIC as a root\n"); + intr_pic_unregister(dev, xref); + goto cleanup; + } + + return (0); + +cleanup: + return(ENXIO); +} + +int +mips_pic_intr(void *arg) +{ + struct mips_pic_softc *sc = arg; + register_t cause, status; + struct intr_irqsrc *isrc; + int i, intr; + + cause = mips_rd_cause(); + status = mips_rd_status(); + intr = (cause & MIPS_INT_MASK) >> 8; + /* + * Do not handle masked interrupts. They were masked by + * pre_ithread function (mips_mask_XXX_intr) and will be + * unmasked once ithread is through with handler + */ + intr &= (status & MIPS_INT_MASK) >> 8; + while ((i = fls(intr)) != 0) { + i--; /* Get a 0-offset interrupt. */ + intr &= ~(1 << i); + + isrc = sc->pic_irqs[i]; + if (isrc == NULL) { + device_printf(sc->pic_dev, + "Stray interrupt %u detected\n", i); + pic_irq_mask(sc, i); + continue; + } + + intr_irq_dispatch(isrc, curthread->td_intr_frame); + } + + KASSERT(i == 0, ("all interrupts handled")); + +#ifdef HWPMC_HOOKS + if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) + pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); +#endif + return (FILTER_HANDLED); +} + +static int +pic_attach_isrc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int irq) +{ + + /* + * 1. The link between ISRC and controller must be set atomically. + * 2. Just do things only once in rare case when consumers + * of shared interrupt came here at the same moment. + */ + mtx_lock_spin(&sc->mutex); + if (sc->pic_irqs[irq] != NULL) { + mtx_unlock_spin(&sc->mutex); + return (sc->pic_irqs[irq] == isrc ? 0 : EEXIST); + } + sc->pic_irqs[irq] = isrc; + isrc->isrc_data = irq; + mtx_unlock_spin(&sc->mutex); + + if (irq < NSOFT_IRQS) + intr_irq_set_name(isrc, "sint%u", irq); + else if (irq < NREAL_IRQS) + intr_irq_set_name(isrc, "int%u", irq - NSOFT_IRQS); + else + panic("Invalid irq %u", irq); + return (0); +} + +static int +pic_detach_isrc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int irq) +{ + + mtx_lock_spin(&sc->mutex); + if (sc->pic_irqs[irq] != isrc) { + mtx_unlock_spin(&sc->mutex); + return (sc->pic_irqs[irq] == NULL ? 0 : EINVAL); + } + sc->pic_irqs[irq] = NULL; + isrc->isrc_data = 0; + mtx_unlock_spin(&sc->mutex); + + intr_irq_set_name(isrc, "%s", ""); + return (0); +} + +static int +pic_irq_from_nspc(struct mips_pic_softc *sc, u_int type, u_int num, u_int *irqp) +{ + + switch (type) { + case INTR_IRQ_NSPC_PLAIN: + *irqp = num; + return (*irqp < sc->nirqs ? 0 : EINVAL); + + case INTR_IRQ_NSPC_SWI: + *irqp = num; + return (num < NSOFT_IRQS ? 0 : EINVAL); + + case INTR_IRQ_NSPC_IRQ: + *irqp = num + NSOFT_IRQS; + return (num < NHARD_IRQS ? 0 : EINVAL); + + default: + return (EINVAL); + } +} + +static int +pic_map_nspc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp) +{ + int error; + + error = pic_irq_from_nspc(sc, isrc->isrc_nspc_type, isrc->isrc_nspc_num, + irqp); + if (error != 0) + return (error); + return (pic_attach_isrc(sc, isrc, *irqp)); +} + +#ifdef FDT +static int +pic_map_fdt(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp) +{ + u_int irq; + int error; + + irq = isrc->isrc_cells[0]; + + if (irq >= sc->nirqs) + return (EINVAL); + + error = pic_attach_isrc(sc, isrc, irq); + if (error != 0) + return (error); + + isrc->isrc_nspc_type = INTR_IRQ_NSPC_PLAIN; + isrc->isrc_nspc_num = irq; + isrc->isrc_trig = INTR_TRIGGER_CONFORM; + isrc->isrc_pol = INTR_POLARITY_CONFORM; + + *irqp = irq; + return (0); +} +#endif + +static int +mips_pic_register(device_t dev, struct intr_irqsrc *isrc, boolean_t *is_percpu) +{ + struct mips_pic_softc *sc = device_get_softc(dev); + u_int irq; + int error; + + if (isrc->isrc_type == INTR_ISRCT_NAMESPACE) + error = pic_map_nspc(sc, isrc, &irq); +#ifdef FDT + else if (isrc->isrc_type == INTR_ISRCT_FDT) + error = pic_map_fdt(sc, isrc, &irq); +#endif + else + return (EINVAL); + + if (error == 0) + *is_percpu = TRUE; + return (error); +} + +static void +mips_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) +{ + + if (isrc->isrc_trig == INTR_TRIGGER_CONFORM) + isrc->isrc_trig = INTR_TRIGGER_LEVEL; +} + +static void +mips_pic_enable_source(device_t dev, struct intr_irqsrc *isrc) +{ + struct mips_pic_softc *sc = device_get_softc(dev); + u_int irq = isrc->isrc_data; + + pic_irq_unmask(sc, irq); +} + +static void +mips_pic_disable_source(device_t dev, struct intr_irqsrc *isrc) +{ + struct mips_pic_softc *sc = device_get_softc(dev); + u_int irq = isrc->isrc_data; + + pic_irq_mask(sc, irq); +} + +static int +mips_pic_unregister(device_t dev, struct intr_irqsrc *isrc) +{ + struct mips_pic_softc *sc = device_get_softc(dev); + u_int irq = isrc->isrc_data; + + return (pic_detach_isrc(sc, isrc, irq)); +} + +static void +mips_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) +{ + + mips_pic_disable_source(dev, isrc); +} + +static void +mips_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) +{ + + mips_pic_enable_source(dev, isrc); +} + +static void +mips_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) +{ +} + +#ifdef SMP +static int +mips_pic_bind(device_t dev, struct intr_irqsrc *isrc) +{ + return (EOPNOTSUPP); +} + +static void +mips_pic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus) +{ +} +#endif + +static device_method_t mips_pic_methods[] = { + /* Device interface */ +#ifndef FDT + DEVMETHOD(device_identify, mips_pic_identify), +#endif + DEVMETHOD(device_probe, mips_pic_probe), + DEVMETHOD(device_attach, mips_pic_attach), + /* Interrupt controller interface */ + DEVMETHOD(pic_disable_source, mips_pic_disable_source), + DEVMETHOD(pic_enable_intr, mips_pic_enable_intr), + DEVMETHOD(pic_enable_source, mips_pic_enable_source), + DEVMETHOD(pic_post_filter, mips_pic_post_filter), + DEVMETHOD(pic_post_ithread, mips_pic_post_ithread), + DEVMETHOD(pic_pre_ithread, mips_pic_pre_ithread), + DEVMETHOD(pic_register, mips_pic_register), + DEVMETHOD(pic_unregister, mips_pic_unregister), +#ifdef SMP + DEVMETHOD(pic_bind, mips_pic_bind), + DEVMETHOD(pic_init_secondary, mips_pic_init_secondary), + DEVMETHOD(pic_ipi_send, mips_pic_ipi_send), +#endif + { 0, 0 } +}; + +static driver_t mips_pic_driver = { + "cpupic", + mips_pic_methods, + sizeof(struct mips_pic_softc), +}; + +static devclass_t mips_pic_devclass; + +#ifdef FDT +DRIVER_MODULE(cpupic, ofwbus, mips_pic_driver, mips_pic_devclass, 0, 0); +#else +DRIVER_MODULE(cpupic, nexus, mips_pic_driver, mips_pic_devclass, 0, 0); +#endif + +void +cpu_init_interrupts(void) +{ +} + +void +cpu_establish_hardintr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, void **cookiep) +{ + u_int vec; + int res; + + /* + * We have 6 levels, but thats 0 - 5 (not including 6) + */ + if (irq < 0 || irq >= NHARD_IRQS) + panic("%s called for unknown hard intr %d", __func__, irq); + + KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); + vec = intr_namespace_map_irq(pic_sc->pic_dev, INTR_IRQ_NSPC_IRQ, irq); + KASSERT(vec != NIRQ, ("Unable to map hard IRQ %d\n", irq)); + + res = intr_irq_add_handler(pic_sc->pic_dev, filt, handler, arg, vec, + flags, cookiep); + if (res != 0) panic("Unable to add hard IRQ %d handler", irq); + + (void)pic_irq_from_nspc(pic_sc, INTR_IRQ_NSPC_IRQ, irq, &vec); + KASSERT(pic_sc->pic_irqs[vec] != NULL, + ("Hard IRQ %d not registered\n", irq)); + intr_irq_set_name(pic_sc->pic_irqs[vec], "%s", name); +} + +void +cpu_establish_softintr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, + void **cookiep) +{ + u_int vec; + int res; + + if (irq < 0 || irq > NSOFT_IRQS) + panic("%s called for unknown soft intr %d", __func__, irq); + + KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); + vec = intr_namespace_map_irq(pic_sc->pic_dev, INTR_IRQ_NSPC_SWI, irq); + KASSERT(vec <= NIRQ, ("Unable to map soft IRQ %d\n", irq)); + + intr_irq_add_handler(pic_sc->pic_dev, filt, handler, arg, vec, + flags, cookiep); + if (res != 0) panic("Unable to add soft IRQ %d handler", irq); + + (void)pic_irq_from_nspc(pic_sc, INTR_IRQ_NSPC_SWI, irq, &vec); + KASSERT(pic_sc->pic_irqs[vec] != NULL, + ("Soft IRQ %d not registered\n", irq)); + intr_irq_set_name(pic_sc->pic_irqs[vec], "%s", name); +} + diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index d2ee6afbaa52..fb52fa902376 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -36,6 +36,7 @@ * this code implements the core resource managers for interrupt * requests and memory address space. */ +#include "opt_platform.h" #include __FBSDID("$FreeBSD$"); @@ -53,13 +54,23 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include +#ifdef MIPS_INTRNG +#include +#else +#include +#endif + #include "opt_platform.h" +#ifdef FDT +#include +#include "ofw_bus_if.h" +#endif + #undef NEXUS_DEBUG #ifdef NEXUS_DEBUG #define dprintf printf @@ -107,6 +118,19 @@ static int nexus_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg, void **cookiep); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); +#ifdef MIPS_INTRNG +#ifdef SMP +static int nexus_bind_intr(device_t, device_t, struct resource *, int); +#endif +#ifdef FDT +static int nexus_ofw_map_intr(device_t dev, device_t child, + phandle_t iparent, int icells, pcell_t *intr); +#endif +static int nexus_describe_intr(device_t dev, device_t child, + struct resource *irq, void *cookie, const char *descr); +static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol); +#endif static device_method_t nexus_methods[] = { /* Device interface */ @@ -127,6 +151,16 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_activate_resource,nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_hinted_child, nexus_hinted_child), +#ifdef MIPS_INTRNG + DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_describe_intr, nexus_describe_intr), +#ifdef SMP + DEVMETHOD(bus_bind_intr, nexus_bind_intr), +#endif +#ifdef FDT + DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), +#endif +#endif { 0, 0 } }; @@ -416,9 +450,16 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { - register_t s; int irq; +#ifdef MIPS_INTRNG + for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) { + intr_irq_add_handler(child, filt, intr, arg, irq, flags, + cookiep); + } +#else + register_t s; + s = intr_disable(); irq = rman_get_start(res); if (irq >= NUM_MIPS_IRQS) { @@ -429,6 +470,7 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, irq, flags, cookiep); intr_restore(s); +#endif return (0); } @@ -436,10 +478,51 @@ static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { +#ifdef MIPS_INTRNG + return (intr_irq_remove_handler(child, rman_get_start(r), ih)); +#else printf("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__); return (0); +#endif } +#ifdef MIPS_INTRNG +static int +nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol) +{ + + return (intr_irq_config(irq, trig, pol)); +} + +static int +nexus_describe_intr(device_t dev, device_t child, struct resource *irq, + void *cookie, const char *descr) +{ + + return (intr_irq_describe(rman_get_start(irq), cookie, descr)); +} + +#ifdef SMP +static int +nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) +{ + + return (intr_irq_bind(rman_get_start(irq), cpu)); +} +#endif + +#ifdef FDT +static int +nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, + pcell_t *intr) +{ + + return (intr_fdt_map_irq(iparent, intr, icells)); +} +#endif +#endif /* MIPS_INTRNG */ + static void nexus_hinted_child(device_t bus, const char *dname, int dunit) { From 4d125f57e13d70b60b39ea32cff9e7a137a7b190 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:13:53 +0000 Subject: [PATCH 047/142] Teach the MIPS ticker to attach itself properly when using INTRNG. Submitted by: Stanislav Galabov Reviewed by: kan Differential Revision: https://reviews.freebsd.org/D5183 --- sys/mips/mips/tick.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index 501e5bb7f3a0..b146ad7d3116 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -51,6 +51,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef MIPS_INTRNG +#include +#endif + uint64_t counter_freq; struct timecounter *platform_timecounter; @@ -324,12 +328,18 @@ static int clock_attach(device_t dev) { struct clock_softc *sc; +#ifndef MIPS_INTRNG int error; +#endif if (device_get_unit(dev) != 0) panic("can't attach more clocks"); softc = sc = device_get_softc(dev); +#ifdef MIPS_INTRNG + cpu_establish_hardintr("clock", clock_intr, NULL, sc, 5, INTR_TYPE_CLK, + NULL); +#else sc->intr_rid = 0; sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->intr_rid, 5, 5, 1, RF_ACTIVE); @@ -343,6 +353,7 @@ clock_attach(device_t dev) device_printf(dev, "bus_setup_intr returned %d\n", error); return (error); } +#endif sc->tc.tc_get_timecount = counter_get_timecount; sc->tc.tc_counter_mask = 0xffffffff; From 055ddb030466439c362b0b070e3bf5583ecb7550 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:15:43 +0000 Subject: [PATCH 048/142] Convert MIPS nexus and mips_pic to BUS_PASS Submitted by: Stanislav Galabov Reviewed by: kan Differential Revision: https://reviews.freebsd.org/D5196 --- sys/mips/mips/mips_pic.c | 6 ++++-- sys/mips/mips/nexus.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/mips/mips/mips_pic.c b/sys/mips/mips/mips_pic.c index c20bc8dabda1..250f8cf55cbc 100644 --- a/sys/mips/mips/mips_pic.c +++ b/sys/mips/mips/mips_pic.c @@ -448,9 +448,11 @@ static driver_t mips_pic_driver = { static devclass_t mips_pic_devclass; #ifdef FDT -DRIVER_MODULE(cpupic, ofwbus, mips_pic_driver, mips_pic_devclass, 0, 0); +EARLY_DRIVER_MODULE(cpupic, ofwbus, mips_pic_driver, mips_pic_devclass, 0, 0, + BUS_PASS_INTERRUPT); #else -DRIVER_MODULE(cpupic, nexus, mips_pic_driver, mips_pic_devclass, 0, 0); +EARLY_DRIVER_MODULE(cpupic, nexus, mips_pic_driver, mips_pic_devclass, 0, 0, + BUS_PASS_INTERRUPT); #endif void diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index fb52fa902376..6ab0da342572 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -576,4 +576,5 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) } } -DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); +EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, + BUS_PASS_BUS + BUS_PASS_ORDER_EARLY); From 7519c628d33bf5961f1709131784be40b5750db3 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:19:32 +0000 Subject: [PATCH 049/142] Remove bus space fdt for MIPS. This was originall done by kan@. Submitted by: Stanislav Galabov Reviewed by: kan Differential Revision: https://reviews.freebsd.org/D5184 --- sys/conf/files.mips | 1 - sys/mips/include/fdt.h | 2 +- sys/mips/mips/bus_space_fdt.c | 205 ---------------------------------- 3 files changed, 1 insertion(+), 207 deletions(-) delete mode 100644 sys/mips/mips/bus_space_fdt.c diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 0bd693891557..91d53aa1c768 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -7,7 +7,6 @@ # Arch dependent files mips/mips/autoconf.c standard mips/mips/bus_space_generic.c standard -mips/mips/bus_space_fdt.c optional fdt mips/mips/busdma_machdep.c standard mips/mips/cache.c standard mips/mips/cache_mipsNN.c standard diff --git a/sys/mips/include/fdt.h b/sys/mips/include/fdt.h index 72cc4850db66..62356b8e8416 100644 --- a/sys/mips/include/fdt.h +++ b/sys/mips/include/fdt.h @@ -40,7 +40,7 @@ #if defined(CPU_RMI) || defined(CPU_NLM) #define fdtbus_bs_tag rmi_uart_bus_space #else -#define fdtbus_bs_tag mips_bus_space_fdt +#define fdtbus_bs_tag mips_bus_space_generic #endif #endif /* _MACHINE_FDT_H_ */ diff --git a/sys/mips/mips/bus_space_fdt.c b/sys/mips/mips/bus_space_fdt.c deleted file mode 100644 index 0b147183b6c6..000000000000 --- a/sys/mips/mips/bus_space_fdt.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ -/*- - * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $ - * - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter - * $FreeBSD$ - */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -static int fdt_bs_map(void *, bus_addr_t, bus_size_t, int, - bus_space_handle_t *); - -static struct bus_space fdt_space = { - /* cookie */ - .bs_cookie = (void *) 0, - - /* mapping/unmapping */ - .bs_map = fdt_bs_map, - .bs_unmap = generic_bs_unmap, - .bs_subregion = generic_bs_subregion, - - /* allocation/deallocation */ - .bs_alloc = generic_bs_alloc, - .bs_free = generic_bs_free, - - /* barrier */ - .bs_barrier = generic_bs_barrier, - - /* read (single) */ - .bs_r_1 = generic_bs_r_1, - .bs_r_2 = generic_bs_r_2, - .bs_r_4 = generic_bs_r_4, - .bs_r_8 = generic_bs_r_8, - - /* read multiple */ - .bs_rm_1 = generic_bs_rm_1, - .bs_rm_2 = generic_bs_rm_2, - .bs_rm_4 = generic_bs_rm_4, - .bs_rm_8 = generic_bs_rm_8, - - /* read region */ - .bs_rr_1 = generic_bs_rr_1, - .bs_rr_2 = generic_bs_rr_2, - .bs_rr_4 = generic_bs_rr_4, - .bs_rr_8 = generic_bs_rr_8, - - /* write (single) */ - .bs_w_1 = generic_bs_w_1, - .bs_w_2 = generic_bs_w_2, - .bs_w_4 = generic_bs_w_4, - .bs_w_8 = generic_bs_w_8, - - /* write multiple */ - .bs_wm_1 = generic_bs_wm_1, - .bs_wm_2 = generic_bs_wm_2, - .bs_wm_4 = generic_bs_wm_4, - .bs_wm_8 = generic_bs_wm_8, - - /* write region */ - .bs_wr_1 = generic_bs_wr_1, - .bs_wr_2 = generic_bs_wr_2, - .bs_wr_4 = generic_bs_wr_4, - .bs_wr_8 = generic_bs_wr_8, - - /* set multiple */ - .bs_sm_1 = generic_bs_sm_1, - .bs_sm_2 = generic_bs_sm_2, - .bs_sm_4 = generic_bs_sm_4, - .bs_sm_8 = generic_bs_sm_8, - - /* set region */ - .bs_sr_1 = generic_bs_sr_1, - .bs_sr_2 = generic_bs_sr_2, - .bs_sr_4 = generic_bs_sr_4, - .bs_sr_8 = generic_bs_sr_8, - - /* copy */ - .bs_c_1 = generic_bs_c_1, - .bs_c_2 = generic_bs_c_2, - .bs_c_4 = generic_bs_c_4, - .bs_c_8 = generic_bs_c_8, - - /* read (single) stream */ - .bs_r_1_s = generic_bs_r_1, - .bs_r_2_s = generic_bs_r_2, - .bs_r_4_s = generic_bs_r_4, - .bs_r_8_s = generic_bs_r_8, - - /* read multiple stream */ - .bs_rm_1_s = generic_bs_rm_1, - .bs_rm_2_s = generic_bs_rm_2, - .bs_rm_4_s = generic_bs_rm_4, - .bs_rm_8_s = generic_bs_rm_8, - - /* read region stream */ - .bs_rr_1_s = generic_bs_rr_1, - .bs_rr_2_s = generic_bs_rr_2, - .bs_rr_4_s = generic_bs_rr_4, - .bs_rr_8_s = generic_bs_rr_8, - - /* write (single) stream */ - .bs_w_1_s = generic_bs_w_1, - .bs_w_2_s = generic_bs_w_2, - .bs_w_4_s = generic_bs_w_4, - .bs_w_8_s = generic_bs_w_8, - - /* write multiple stream */ - .bs_wm_1_s = generic_bs_wm_1, - .bs_wm_2_s = generic_bs_wm_2, - .bs_wm_4_s = generic_bs_wm_4, - .bs_wm_8_s = generic_bs_wm_8, - - /* write region stream */ - .bs_wr_1_s = generic_bs_wr_1, - .bs_wr_2_s = generic_bs_wr_2, - .bs_wr_4_s = generic_bs_wr_4, - .bs_wr_8_s = generic_bs_wr_8, -}; - -/* generic bus_space tag */ -bus_space_tag_t mips_bus_space_fdt = &fdt_space; - -static int -fdt_bs_map(void *t __unused, bus_addr_t addr, bus_size_t size __unused, - int flags __unused, bus_space_handle_t *bshp) -{ - - *bshp = MIPS_PHYS_TO_DIRECT_UNCACHED(addr); - return (0); -} From 67a2f29041b9d7b1513bb7a534dad32efc76220f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:19:58 +0000 Subject: [PATCH 050/142] Missing commit - remove MIPS fdt bus space. Differential Revision: https://reviews.freebsd.org/D5184 --- sys/mips/include/bus.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index 370d52f35ee4..5e85b17be6d4 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -721,7 +721,6 @@ void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \ */ DECLARE_BUS_SPACE_PROTOTYPES(generic); extern bus_space_tag_t mips_bus_space_generic; -extern bus_space_tag_t mips_bus_space_fdt; /* Special bus space for RMI processors */ #if defined(CPU_RMI) || defined (CPU_NLM) From 6d525d0af8be194cd15c71e69ed2239632210a14 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:23:02 +0000 Subject: [PATCH 051/142] Migrate the other MIPS24K SoC cores to use the CPU_MIPS24K option. --- sys/mips/conf/AR71XX_BASE | 2 +- sys/mips/conf/AR724X_BASE | 2 +- sys/mips/conf/AR91XX_BASE | 2 +- sys/mips/conf/QCA953X_BASE | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/mips/conf/AR71XX_BASE b/sys/mips/conf/AR71XX_BASE index 2b9d075e849e..a296eab860b8 100644 --- a/sys/mips/conf/AR71XX_BASE +++ b/sys/mips/conf/AR71XX_BASE @@ -9,7 +9,7 @@ machine mips mips ident AR71XX_BASE -cpu CPU_MIPS4KC +cpu CPU_MIPS24K makeoptions KERNLOADADDR=0x80050000 options HZ=1000 options HWPMC_HOOKS diff --git a/sys/mips/conf/AR724X_BASE b/sys/mips/conf/AR724X_BASE index c1145b710fce..662e8013377f 100644 --- a/sys/mips/conf/AR724X_BASE +++ b/sys/mips/conf/AR724X_BASE @@ -10,7 +10,7 @@ machine mips mips ident AR724X_BASE -cpu CPU_MIPS4KC +cpu CPU_MIPS24K makeoptions KERNLOADADDR=0x80050000 options HZ=1000 options HWPMC_HOOKS diff --git a/sys/mips/conf/AR91XX_BASE b/sys/mips/conf/AR91XX_BASE index 07e51218f172..982c386968e0 100644 --- a/sys/mips/conf/AR91XX_BASE +++ b/sys/mips/conf/AR91XX_BASE @@ -12,7 +12,7 @@ machine mips mips ident AR91XX_BASE -cpu CPU_MIPS4KC +cpu CPU_MIPS24K makeoptions KERNLOADADDR=0x80050000 options HZ=1000 diff --git a/sys/mips/conf/QCA953X_BASE b/sys/mips/conf/QCA953X_BASE index 3126f71c70a1..08de505430b2 100644 --- a/sys/mips/conf/QCA953X_BASE +++ b/sys/mips/conf/QCA953X_BASE @@ -12,7 +12,7 @@ machine mips mips ident QCA953X_BASE -cpu CPU_MIPS4KC +cpu CPU_MIPS24K makeoptions KERNLOADADDR=0x80050000 options HZ=1000 From 314d3ca236a0abbbe9c5f505e731c7b4a9fa8377 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 11 Feb 2016 06:24:34 +0000 Subject: [PATCH 052/142] Make bus_space_generic properly map/unmap memory (using pmap_mapdev and pmap_unmapdev respectively) so that resources are properly managed. This is work originally done by kan@. Stanislav picked it up as part of his Mediatek SoC work. Tested: * Carambola2, AR933x SoC Submitted by: Stanislav Galabov Reviewed by: kan Differential Revision: https://reviews.freebsd.org/D5184 --- sys/mips/mips/bus_space_generic.c | 11 ++++++----- sys/mips/mips/nexus.c | 26 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/sys/mips/mips/bus_space_generic.c b/sys/mips/mips/bus_space_generic.c index d82d97ee9af7..b57a7393791b 100644 --- a/sys/mips/mips/bus_space_generic.c +++ b/sys/mips/mips/bus_space_generic.c @@ -228,20 +228,21 @@ bus_space_tag_t mips_bus_space_generic = &generic_space; int generic_bs_map(void *t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, + bus_size_t size, int flags __unused, bus_space_handle_t *bshp) { - *bshp = addr; + *bshp = (bus_space_handle_t)pmap_mapdev((vm_paddr_t)addr, + (vm_size_t)size); return (0); } void -generic_bs_unmap(void *t __unused, bus_space_handle_t bh __unused, - bus_size_t size __unused) +generic_bs_unmap(void *t __unused, bus_space_handle_t bh, + bus_size_t size) { - /* Do nothing */ + pmap_unmapdev((vm_offset_t)bh, (vm_size_t)size); } int diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 6ab0da342572..f781248b769e 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -415,6 +415,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, void *vaddr; vm_paddr_t paddr; vm_size_t psize; + int err; /* * If this is a memory resource, use pmap_mapdev to map it. @@ -422,10 +423,14 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { paddr = rman_get_start(r); psize = rman_get_size(r); - vaddr = pmap_mapdev(paddr, psize); - - rman_set_virtual(r, vaddr); rman_set_bustag(r, mips_bus_space_generic); + err = bus_space_map(rman_get_bustag(r), paddr, psize, 0, + (bus_space_handle_t *)&vaddr); + if (err != 0) { + rman_deactivate_resource(r); + return (err); + } + rman_set_virtual(r, vaddr); rman_set_bushandle(r, (bus_space_handle_t)(uintptr_t)vaddr); } @@ -436,11 +441,16 @@ static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - vm_offset_t va; - - if (type == SYS_RES_MEMORY) { - va = (vm_offset_t)rman_get_virtual(r); - pmap_unmapdev(va, rman_get_size(r)); + bus_space_handle_t vaddr; + bus_size_t psize; + + vaddr = rman_get_bushandle(r); + + if (type == SYS_RES_MEMORY && vaddr != 0) { + psize = (bus_size_t)rman_get_size(r); + bus_space_unmap(rman_get_bustag(r), vaddr, psize); + rman_set_virtual(r, NULL); + rman_set_bushandle(r, 0); } return (rman_deactivate_resource(r)); From c7fc655f3f412529935e6eeee88d4941bec60906 Mon Sep 17 00:00:00 2001 From: Wojciech Macek Date: Thu, 11 Feb 2016 06:50:11 +0000 Subject: [PATCH 053/142] ARM64 disassembler: support for LDR instructions Implemented disassembly for a whole bunch of various ldr instructions. Obtained from: Semihalf Sponsored by: Cavium Approved by: cognet (mentor) Reviewed by: zbb Differential revision: https://reviews.freebsd.org/D5217 --- sys/arm64/arm64/disassem.c | 233 +++++++++++++++++++++++++++++++++++-- 1 file changed, 224 insertions(+), 9 deletions(-) diff --git a/sys/arm64/arm64/disassem.c b/sys/arm64/arm64/disassem.c index 46b62285f385..ce0bf7660b02 100644 --- a/sys/arm64/arm64/disassem.c +++ b/sys/arm64/arm64/disassem.c @@ -38,6 +38,16 @@ __FBSDID("$FreeBSD$"); #define ARM64_MAX_TOKEN_LEN 8 #define ARM64_MAX_TOKEN_CNT 10 +#define ARM_INSN_SIZE_OFFSET 30 +#define ARM_INSN_SIZE_MASK 0x3 + +/* Special options for instruction printing */ +#define OP_SIGN_EXT (1UL << 0) /* Sign-extend immediate value */ +#define OP_LITERAL (1UL << 1) /* Use literal (memory offset) */ +#define OP_MULT_4 (1UL << 2) /* Multiply immediate by 4 */ +#define OP_SF32 (1UL << 3) /* Force 32-bit access */ +#define OP_SF_INV (1UL << 6) /* SF is inverted (1 means 32 bit access) */ + static const char *w_reg[] = { "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", @@ -74,6 +84,10 @@ struct arm64_insn_token { enum arm64_format_type { TYPE_01, /* OP , , {, #} SF32/64 OP , , #{, } SF32/64 */ + TYPE_02, /* OP , [, #]{!}] SF32/64 + OP , [], #{!} SF32/64 + OP , , {, EXTEND AMOUNT } */ + TYPE_03, /* OP , #imm SF32/64 */ }; /* @@ -112,12 +126,57 @@ struct arm64_insn { * SHIFT - type of shift (instruction dependent) * IMM - immediate value * Rx - register number + * OPTION - command specific options + * SCALE - scaling of immediate value */ static struct arm64_insn arm64_i[] = { - { "add", "SF(1)|0001011|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)", TYPE_01, 0 }, - { "mov", "SF(1)|001000100000000000000|RN(5)|RD(5)", TYPE_01, 0 }, - { "add", "SF(1)|0010001|SHIFT(2)|IMM(12)|RN(5)|RD(5)", TYPE_01, 0 }, - { NULL, NULL } + { "add", "SF(1)|0001011|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)", + TYPE_01, 0 }, + { "mov", "SF(1)|001000100000000000000|RN(5)|RD(5)", + TYPE_01, 0 }, + { "add", "SF(1)|0010001|SHIFT(2)|IMM(12)|RN(5)|RD(5)", + TYPE_01, 0 }, + { "ldr", "1|SF(1)|111000010|IMM(9)|OPTION(2)|RN(5)|RT(5)", + TYPE_02, OP_SIGN_EXT }, /* ldr immediate post/pre index */ + { "ldr", "1|SF(1)|11100101|IMM(12)|RN(5)|RT(5)", + TYPE_02, 0 }, /* ldr immediate unsigned */ + { "ldr", "1|SF(1)|111000011|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, 0 }, /* ldr register */ + { "ldr", "0|SF(1)|011000|IMM(19)|RT(5)", + TYPE_03, OP_SIGN_EXT | OP_LITERAL | OP_MULT_4 }, /* ldr literal */ + { "ldrb", "00|111000010|IMM(9)|OPTION(2)|RN(5)|RT(5)", + TYPE_02, OP_SIGN_EXT | OP_SF32 }, /* ldrb immediate post/pre index */ + { "ldrb", "00|11100101|IMM(12)|RN(5)|RT(5)", + TYPE_02, OP_SF32 }, /* ldrb immediate unsigned */ + { "ldrb", "00|111000011|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, OP_SF32 }, /* ldrb register */ + { "ldrh", "01|111000010|IMM(9)|OPTION(2)|RN(5)|RT(5)", TYPE_02, + OP_SIGN_EXT | OP_SF32 }, /* ldrh immediate post/pre index */ + { "ldrh", "01|11100101|IMM(12)|RN(5)|RT(5)", + TYPE_02, OP_SF32 }, /* ldrh immediate unsigned */ + { "ldrh", "01|111000011|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, OP_SF32 }, /* ldrh register */ + { "ldrsb", "001110001|SF(1)|0|IMM(9)|OPTION(2)|RN(5)|RT(5)", + TYPE_02, OP_SIGN_EXT | OP_SF_INV }, /* ldrsb immediate post/pre index */ + { "ldrsb", "001110011|SF(1)|IMM(12)|RN(5)|RT(5)",\ + TYPE_02, OP_SF_INV}, /* ldrsb immediate unsigned */ + { "ldrsb", "001110001|SF(1)|1|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, OP_SF_INV }, /* ldrsb register */ + { "ldrsh", "011110001|SF(1)|0|IMM(9)|OPTION(2)|RN(5)|RT(5)", + TYPE_02, OP_SIGN_EXT | OP_SF_INV }, /* ldrsh immediate post/pre index */ + { "ldrsh", "011110011|SF(1)|IMM(12)|RN(5)|RT(5)", + TYPE_02, OP_SF_INV}, /* ldrsh immediate unsigned */ + { "ldrsh", "011110001|SF(1)|1|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, OP_SF_INV }, /* ldrsh register */ + { "ldrsw", "10111000100|IMM(9)|OPTION(2)|RN(5)|RT(5)", + TYPE_02, OP_SIGN_EXT }, /* ldrsw immediate post/pre index */ + { "ldrsw", "1011100110|IMM(12)|RN(5)|RT(5)", + TYPE_02, 0 }, /* ldrsw immediate unsigned */ + { "ldrsw", "10111000101|RM(5)|OPTION(3)|SCALE(1)|10|RN(5)|RT(5)", + TYPE_02, 0 }, /* ldrsw register */ + { "ldrsw", "10011000|IMM(19)|RT(5)", + TYPE_03, OP_SIGN_EXT | OP_LITERAL | OP_MULT_4 }, /* ldr literal */ + { NULL, NULL } }; static void @@ -240,6 +299,29 @@ arm64_disasm_read_token(struct arm64_insn *insn, u_int opcode, return (EINVAL); } +static int +arm64_disasm_read_token_sign_ext(struct arm64_insn *insn, u_int opcode, + const char *token, int *val) +{ + int i; + int msk; + + for (i = 0; i < ARM64_MAX_TOKEN_CNT; i++) { + if (strcmp(insn->tokens[i].name, token) == 0) { + msk = (1 << insn->tokens[i].len) - 1; + *val = ((opcode >> insn->tokens[i].pos) & msk); + + /* If last bit is 1, sign-extend the value */ + if (*val & (1 << (insn->tokens[i].len - 1))) + *val |= ~msk; + + return (0); + } + } + + return (EINVAL); +} + static const char * arm64_reg(int b64, int num) { @@ -257,11 +339,17 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt) uint32_t insn; int matchp; int ret; - int shift, rm, rd, rn, imm, sf; + int shift, rm, rt, rd, rn, imm, sf, idx, option, scale, amount; + int sign_ext; int rm_absent; + /* Indicate if immediate should be outside or inside brackets */ + int inside; + /* Print exclamation mark if pre-incremented */ + int pre; /* Initialize defaults, all are 0 except SF indicating 64bit access */ - shift = rd = rm = rn = imm = 0; + shift = rd = rm = rn = imm = idx = option = amount = scale = 0; + sign_ext = 0; sf = 1; matchp = 0; @@ -278,14 +366,33 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt) if (matchp == 0) goto undefined; + /* Global options */ + if (i_ptr->special_ops & OP_SF32) + sf = 0; + + /* Global optional tokens */ + arm64_disasm_read_token(i_ptr, insn, "SF", &sf); + if (i_ptr->special_ops & OP_SF_INV) + sf = 1 - sf; + if (arm64_disasm_read_token(i_ptr, insn, "SIGN", &sign_ext) == 0) + sign_ext = 1 - sign_ext; + if (i_ptr->special_ops & OP_SIGN_EXT) + sign_ext = 1; + if (sign_ext != 0) + arm64_disasm_read_token_sign_ext(i_ptr, insn, "IMM", &imm); + else + arm64_disasm_read_token(i_ptr, insn, "IMM", &imm); + if (i_ptr->special_ops & OP_MULT_4) + imm <<= 2; + + /* Print opcode by type */ switch (i_ptr->type) { case TYPE_01: /* OP , , {, #} SF32/64 OP , , #{, } SF32/64 */ /* Mandatory tokens */ - ret = arm64_disasm_read_token(i_ptr, insn, "SF", &sf); - ret |= arm64_disasm_read_token(i_ptr, insn, "RD", &rd); + ret = arm64_disasm_read_token(i_ptr, insn, "RD", &rd); ret |= arm64_disasm_read_token(i_ptr, insn, "RN", &rn); if (ret != 0) { printf("ERROR: Missing mandatory token for op %s type %d\n", @@ -294,7 +401,6 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt) } /* Optional tokens */ - arm64_disasm_read_token(i_ptr, insn, "IMM", &imm); arm64_disasm_read_token(i_ptr, insn, "SHIFT", &shift); rm_absent = arm64_disasm_read_token(i_ptr, insn, "RM", &rm); @@ -312,6 +418,115 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt) if (shift != 0) di->di_printf(" LSL #12"); } + break; + case TYPE_02: + /* OP , [, #]{!}] SF32/64 + OP , [], #{!} SF32/64 + OP , , {, EXTEND AMOUNT } */ + + /* Mandatory tokens */ + ret = arm64_disasm_read_token(i_ptr, insn, "RT", &rt); + ret |= arm64_disasm_read_token(i_ptr, insn, "RN", &rn); + if (ret != 0) { + printf("ERROR: Missing mandatory token for op %s type %d\n", + i_ptr->name, i_ptr->type); + goto undefined; + } + + /* Optional tokens */ + arm64_disasm_read_token(i_ptr, insn, "OPTION", &option); + arm64_disasm_read_token(i_ptr, insn, "SCALE", &scale); + rm_absent = arm64_disasm_read_token(i_ptr, insn, "RM", &rm); + + if (rm_absent) { + /* + * In unsigned operation, shift immediate value + * and reset options to default. + */ + if (sign_ext == 0) { + imm = imm << ((insn >> ARM_INSN_SIZE_OFFSET) & + ARM_INSN_SIZE_MASK); + option = 0; + } + switch (option) { + case 0x0: + pre = 0; + inside = 1; + break; + case 0x1: + pre = 0; + inside = 0; + break; + case 0x2: + default: + pre = 1; + inside = 1; + break; + } + + di->di_printf("%s\t%s, ", i_ptr->name, arm64_reg(sf, rt)); + if (inside != 0) { + di->di_printf("[%s", arm64_reg(1, rn)); + if (imm != 0) + di->di_printf(", #%d", imm); + di->di_printf("]"); + } else { + di->di_printf("[%s]", arm64_reg(1, rn)); + if (imm != 0) + di->di_printf(", #%d", imm); + } + if (pre != 0) + di->di_printf("!"); + } else { + /* Last bit of option field determines 32/64 bit offset */ + di->di_printf("%s\t%s, [%s, %s", i_ptr->name, + arm64_reg(sf, rt), arm64_reg(1, rn), + arm64_reg(option & 1, rm)); + + /* Calculate amount, it's op(31:30) */ + amount = (insn >> ARM_INSN_SIZE_OFFSET) & + ARM_INSN_SIZE_MASK; + + switch (option) { + case 0x2: + di->di_printf(", uxtw #%d", amount); + break; + case 0x3: + if (scale != 0) + di->di_printf(", lsl #%d", amount); + break; + case 0x6: + di->di_printf(", sxtw #%d", amount); + break; + case 0x7: + di->di_printf(", sxts #%d", amount); + break; + default: + di->di_printf(", RSVD"); + break; + } + di->di_printf("]"); + } + + break; + + case TYPE_03: + /* OP , #imm SF32/64 */ + + /* Mandatory tokens */ + ret = arm64_disasm_read_token(i_ptr, insn, "RT", &rt); + if (ret != 0) { + printf("ERROR: Missing mandatory token for op %s type %d\n", + i_ptr->name, i_ptr->type); + goto undefined; + } + + di->di_printf("%s\t%s, ", i_ptr->name, arm64_reg(sf, rt)); + if (i_ptr->special_ops & OP_LITERAL) + di->di_printf("0x%lx", loc + imm); + else + di->di_printf("#%d", imm); + break; default: goto undefined; From 3e9470b72175288bc32e87a00f6570b3924d52d2 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Thu, 11 Feb 2016 10:03:50 +0000 Subject: [PATCH 054/142] Use a pair of ifs when comparing the 32-bit flowid integers so that the sign bit doesn't cause an overflow. The overflow manifests itself as a sorting index wrap around in the middle of the sorted array, which is not a problem for the LRO code, but might be a problem for the logic inside qsort(). Reviewed by: gnn @ Sponsored by: Mellanox Technologies Differential Revision: https://reviews.freebsd.org/D5239 --- sys/netinet/tcp_lro.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c index d49071c50d28..62d8595c3f70 100644 --- a/sys/netinet/tcp_lro.c +++ b/sys/netinet/tcp_lro.c @@ -347,9 +347,10 @@ tcp_lro_mbuf_compare_header(const void *ppa, const void *ppb) if (ret != 0) goto done; - ret = ma->m_pkthdr.flowid - mb->m_pkthdr.flowid; - if (ret != 0) - goto done; + if (ma->m_pkthdr.flowid > mb->m_pkthdr.flowid) + return (1); + else if (ma->m_pkthdr.flowid < mb->m_pkthdr.flowid) + return (-1); ret = TCP_LRO_SEQUENCE(ma) - TCP_LRO_SEQUENCE(mb); done: From 75d36854d45b04c22bf9f68d5dad66c41d86d26e Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 11 Feb 2016 10:48:15 +0000 Subject: [PATCH 055/142] Remove unused Zedboard config files. files.zedboard was empty other than comments, and std.zedboard just pointed to files.zedboard and std.xilinx. --- sys/arm/conf/ZEDBOARD | 2 +- sys/arm/xilinx/zedboard/files.zedboard | 9 --------- sys/arm/xilinx/zedboard/std.zedboard | 8 -------- 3 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 sys/arm/xilinx/zedboard/files.zedboard delete mode 100644 sys/arm/xilinx/zedboard/std.zedboard diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index 6cdbf66c3253..7fca9372a58e 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -22,7 +22,7 @@ ident ZEDBOARD include "std.armv6" -include "../xilinx/zedboard/std.zedboard" +include "../xilinx/std.zynq7" options SCHED_ULE # ULE scheduler #options NFSSD # Network Filesystem Server diff --git a/sys/arm/xilinx/zedboard/files.zedboard b/sys/arm/xilinx/zedboard/files.zedboard deleted file mode 100644 index 8a1af16fa0a4..000000000000 --- a/sys/arm/xilinx/zedboard/files.zedboard +++ /dev/null @@ -1,9 +0,0 @@ -# -# files.zedboard -# -# $FreeBSD$ - -# We'll need board specific files once we start implementing drivers -# for Zedboard PL peripherals such as HDMI, VGA, or Audio Codecs. For -# now, nothing is needed. -# diff --git a/sys/arm/xilinx/zedboard/std.zedboard b/sys/arm/xilinx/zedboard/std.zedboard deleted file mode 100644 index 86f04f127714..000000000000 --- a/sys/arm/xilinx/zedboard/std.zedboard +++ /dev/null @@ -1,8 +0,0 @@ -# -# std.zedboard -# -# $FreeBSD$ - -include "../xilinx/std.zynq7" -files "../xilinx/zedboard/files.zedboard" - From 2150fb09b9ac202fe843c60e2f61b246f72da2a8 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Thu, 11 Feb 2016 11:21:45 +0000 Subject: [PATCH 056/142] Stop device enumeration when we see first empty slot. This fixes operation in QEMU and saves some booting time as well. Pointed out by: Sagar Karandikar Sponsored by: DARPA, AFRL Sponsored by: HEIF5 --- sys/riscv/htif/htif.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/riscv/htif/htif.c b/sys/riscv/htif/htif.c index 08e6a43c2b94..f8143dc694ba 100644 --- a/sys/riscv/htif/htif.c +++ b/sys/riscv/htif/htif.c @@ -183,9 +183,8 @@ htif_enumerate(struct htif_softc *sc) } len = strnlen(id, sizeof(id)); - if (len <= 0) { - continue; - } + if (len <= 0) + break; if (bootverbose) printf(" %d %s\n", i, id); From 647a3bac7e841c5335c42495608bc4bc1a70edd9 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 11 Feb 2016 11:49:27 +0000 Subject: [PATCH 057/142] Stop defining fdt_pic_table when building for ARM_INTRNG. --- sys/arm/altera/socfpga/socfpga_common.c | 2 ++ sys/arm/amlogic/aml8726/aml8726_machdep.c | 2 ++ sys/arm/annapurna/alpine/common.c | 2 ++ sys/arm/at91/at91_common.c | 2 ++ sys/arm/broadcom/bcm2835/bcm2835_common.c | 2 ++ sys/arm/freescale/imx/imx_common.c | 2 ++ sys/arm/freescale/vybrid/vf_common.c | 2 ++ sys/arm/lpc/lpc_intc.c | 2 ++ sys/arm/mv/mv_common.c | 2 ++ sys/arm/rockchip/rk30xx_common.c | 2 ++ sys/arm/samsung/exynos/exynos5_common.c | 2 ++ sys/arm/versatile/versatile_common.c | 2 ++ sys/arm/xilinx/zy7_machdep.c | 3 ++- 13 files changed, 26 insertions(+), 1 deletion(-) diff --git a/sys/arm/altera/socfpga/socfpga_common.c b/sys/arm/altera/socfpga/socfpga_common.c index 6531a416c1a9..3615c947af98 100644 --- a/sys/arm/altera/socfpga/socfpga_common.c +++ b/sys/arm/altera/socfpga/socfpga_common.c @@ -74,6 +74,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -92,3 +93,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_pic_decode_ic, NULL }; +#endif diff --git a/sys/arm/amlogic/aml8726/aml8726_machdep.c b/sys/arm/amlogic/aml8726/aml8726_machdep.c index e1cd1b9038af..1ad25b4191e7 100644 --- a/sys/arm/amlogic/aml8726/aml8726_machdep.c +++ b/sys/arm/amlogic/aml8726/aml8726_machdep.c @@ -184,6 +184,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG #ifndef DEV_GIC static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, @@ -212,3 +213,4 @@ fdt_pic_decode_t fdt_pic_table[] = { #endif NULL }; +#endif /* ARM_INTRNG */ diff --git a/sys/arm/annapurna/alpine/common.c b/sys/arm/annapurna/alpine/common.c index 774bf00aceca..5d45b553e07d 100644 --- a/sys/arm/annapurna/alpine/common.c +++ b/sys/arm/annapurna/alpine/common.c @@ -136,6 +136,7 @@ cpu_reset(void) while (1) {} } +#ifndef ARM_INTRNG static int alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt, int *trig, int *pol) @@ -158,3 +159,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &alpine_pic_decode_fdt, NULL }; +#endif diff --git a/sys/arm/at91/at91_common.c b/sys/arm/at91/at91_common.c index 9f960f67aa51..bc13196bffb1 100644 --- a/sys/arm/at91/at91_common.c +++ b/sys/arm/at91/at91_common.c @@ -53,6 +53,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_aic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -75,6 +76,7 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_aic_decode_ic, NULL }; +#endif static void at91_eoi(void *unused) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_common.c b/sys/arm/broadcom/bcm2835/bcm2835_common.c index a558ac827592..08f01a8968f2 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_common.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_common.c @@ -50,6 +50,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -70,3 +71,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_intc_decode_ic, NULL }; +#endif /* ARM_INTRNG */ diff --git a/sys/arm/freescale/imx/imx_common.c b/sys/arm/freescale/imx/imx_common.c index 0fe7082c75e4..50922e6aab4b 100644 --- a/sys/arm/freescale/imx/imx_common.c +++ b/sys/arm/freescale/imx/imx_common.c @@ -54,6 +54,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -70,3 +71,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_intc_decode_ic, NULL }; +#endif /* ARM_INTRNG */ diff --git a/sys/arm/freescale/vybrid/vf_common.c b/sys/arm/freescale/vybrid/vf_common.c index ffec9a3951c9..913902a71cb5 100644 --- a/sys/arm/freescale/vybrid/vf_common.c +++ b/sys/arm/freescale/vybrid/vf_common.c @@ -66,6 +66,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -84,3 +85,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_pic_decode_ic, NULL }; +#endif diff --git a/sys/arm/lpc/lpc_intc.c b/sys/arm/lpc/lpc_intc.c index bf26645d742c..d4b25172fa63 100644 --- a/sys/arm/lpc/lpc_intc.c +++ b/sys/arm/lpc/lpc_intc.c @@ -231,6 +231,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -248,3 +249,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_pic_decode_ic, NULL }; +#endif diff --git a/sys/arm/mv/mv_common.c b/sys/arm/mv/mv_common.c index afefc7f28600..ec55357c5cc7 100644 --- a/sys/arm/mv/mv_common.c +++ b/sys/arm/mv/mv_common.c @@ -2181,6 +2181,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -2204,6 +2205,7 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_pic_decode_ic, NULL }; +#endif uint64_t get_sar_value(void) diff --git a/sys/arm/rockchip/rk30xx_common.c b/sys/arm/rockchip/rk30xx_common.c index eff182453bc9..723c4291e039 100644 --- a/sys/arm/rockchip/rk30xx_common.c +++ b/sys/arm/rockchip/rk30xx_common.c @@ -42,6 +42,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -61,3 +62,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_aintc_decode_ic, NULL }; +#endif diff --git a/sys/arm/samsung/exynos/exynos5_common.c b/sys/arm/samsung/exynos/exynos5_common.c index 658efc417298..8818f0453d40 100644 --- a/sys/arm/samsung/exynos/exynos5_common.c +++ b/sys/arm/samsung/exynos/exynos5_common.c @@ -53,6 +53,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -71,3 +72,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_pic_decode_ic, NULL }; +#endif diff --git a/sys/arm/versatile/versatile_common.c b/sys/arm/versatile/versatile_common.c index bcb504a3b790..c47c298ce8d8 100644 --- a/sys/arm/versatile/versatile_common.c +++ b/sys/arm/versatile/versatile_common.c @@ -50,6 +50,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -70,3 +71,4 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_intc_decode_ic, NULL }; +#endif diff --git a/sys/arm/xilinx/zy7_machdep.c b/sys/arm/xilinx/zy7_machdep.c index f7080dc93d63..4b436839ecf0 100644 --- a/sys/arm/xilinx/zy7_machdep.c +++ b/sys/arm/xilinx/zy7_machdep.c @@ -98,6 +98,7 @@ struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; +#ifndef ARM_INTRNG static int fdt_gic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) @@ -117,7 +118,7 @@ fdt_pic_decode_t fdt_pic_table[] = { &fdt_gic_decode_ic, NULL }; - +#endif struct arm32_dma_range * bus_dma_get_range(void) From 780349944044e8f769bb0b93755178ac0fb22c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Thu, 11 Feb 2016 11:50:31 +0000 Subject: [PATCH 058/142] xen-netfront: remove pointless assignment in xn_ioctl The variable error is assigned to 0 before entering the switch. Assigning error to 0 before break pointless rewrites the real error value that should be returned. Coverity ID: 1304974 Submitted by: Wei Liu Reviewed by: royger Sponsored by: Citrix Systems R&D Differential revision: https://reviews.freebsd.org/D5250 --- sys/dev/xen/netfront/netfront.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index e940d93bfe05..89aef6298b2f 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -1863,7 +1863,6 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } sc->xn_if_flags = ifp->if_flags; XN_UNLOCK(sc); - error = 0; break; case SIOCSIFCAP: mask = ifr->ifr_reqcap ^ ifp->if_capenable; @@ -1898,7 +1897,6 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifp->if_capenable ^= IFCAP_LRO; } - error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: From d4dae2b1fb44e0205238cd5b1ec8bac2cd72d74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Thu, 11 Feb 2016 11:53:32 +0000 Subject: [PATCH 059/142] xen-netfront: rearrange error paths in setup_txqs Coverity spotted double free errors in error path. Fix that by removing the extraneous calls. Coverity ID: 1349798 Submitted by: Wei Liu Reviewed by: royger Sponsored by: Citrix Systems R&D Differential revision: https://reviews.freebsd.org/D5251 --- sys/dev/xen/netfront/netfront.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 89aef6298b2f..296c940f0836 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -906,11 +906,9 @@ setup_txqs(device_t dev, struct netfront_info *info, fail_bind_port: taskqueue_drain_all(txq->tq); fail_start_thread: - gnttab_free_grant_references(txq->gref_head); - free(txq->ring.sring, M_DEVBUF); - gnttab_end_foreign_access_ref(txq->ring_ref); buf_ring_free(txq->br, M_DEVBUF); taskqueue_free(txq->tq); + gnttab_end_foreign_access_ref(txq->ring_ref); fail_grant_ring: gnttab_free_grant_references(txq->gref_head); free(txq->ring.sring, M_DEVBUF); From 8133eda9219b461a35dc388323d03ac743d722ed Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 11:55:37 +0000 Subject: [PATCH 060/142] Minor clean-ups for ARM64 GICv3 and GIC drivers GICv3: - move ICC_SGI1R_EL1 definitions to armreg.h and use proper system register's names GIC: - remove unused functions Reviewed by: andrew Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5119 --- sys/arm64/arm64/gic.c | 23 ----------------------- sys/arm64/arm64/gic_v3.c | 11 ++++++----- sys/arm64/arm64/gic_v3_reg.h | 6 ------ sys/arm64/include/armreg.h | 9 +++++++++ 4 files changed, 15 insertions(+), 34 deletions(-) diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c index 823dd6110f3a..0a13b124a0ba 100644 --- a/sys/arm64/arm64/gic.c +++ b/sys/arm64/arm64/gic.c @@ -303,29 +303,6 @@ gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi) gic_d_write_4(sc, GICD_SGIR(0), val | ipi); } - -static int -arm_gic_ipi_read(device_t dev, int i) -{ - - if (i != -1) { - /* - * The intr code will automagically give the frame pointer - * if the interrupt argument is 0. - */ - if ((unsigned int)i > 16) - return (0); - return (i); - } - - return (0x3ff); -} - -static void -arm_gic_ipi_clear(device_t dev, int ipi) -{ - /* no-op */ -} #endif static device_method_t arm_gic_methods[] = { diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index b74a56a9a4b3..c2b97a3087e1 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -412,14 +412,15 @@ gic_v3_ipi_send(device_t dev, cpuset_t cpuset, u_int ipi) } } if (tlist) { - KASSERT((tlist & ~GICI_SGI_TLIST_MASK) == 0, + KASSERT((tlist & ~ICC_SGI1R_EL1_TL_MASK) == 0, ("Target list too long for GICv3 IPI")); /* Send SGI to CPUs in target list */ val = tlist; - val |= (uint64_t)CPU_AFF3(aff) << GICI_SGI_AFF3_SHIFT; - val |= (uint64_t)CPU_AFF2(aff) << GICI_SGI_AFF2_SHIFT; - val |= (uint64_t)CPU_AFF1(aff) << GICI_SGI_AFF1_SHIFT; - val |= (uint64_t)(ipi & GICI_SGI_IPI_MASK) << GICI_SGI_IPI_SHIFT; + val |= (uint64_t)CPU_AFF3(aff) << ICC_SGI1R_EL1_AFF3_SHIFT; + val |= (uint64_t)CPU_AFF2(aff) << ICC_SGI1R_EL1_AFF2_SHIFT; + val |= (uint64_t)CPU_AFF1(aff) << ICC_SGI1R_EL1_AFF1_SHIFT; + val |= (uint64_t)(ipi & ICC_SGI1R_EL1_SGIID_MASK) << + ICC_SGI1R_EL1_SGIID_SHIFT; gic_icc_write(SGI1R, val); } } diff --git a/sys/arm64/arm64/gic_v3_reg.h b/sys/arm64/arm64/gic_v3_reg.h index 17173def915f..2a2072fa57d5 100644 --- a/sys/arm64/arm64/gic_v3_reg.h +++ b/sys/arm64/arm64/gic_v3_reg.h @@ -356,12 +356,6 @@ /* * CPU interface */ -#define GICI_SGI_TLIST_MASK (0xffffUL) -#define GICI_SGI_AFF1_SHIFT (16UL) -#define GICI_SGI_AFF2_SHIFT (32UL) -#define GICI_SGI_AFF3_SHIFT (48UL) -#define GICI_SGI_IPI_MASK (0xfUL) -#define GICI_SGI_IPI_SHIFT (24UL) /* * Registers list (ICC_xyz_EL1): diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index 0c86462376fc..405f3bb8d0be 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -118,6 +118,15 @@ /* ICC_PMR_EL1 */ #define ICC_PMR_EL1_PRIO_MASK (0xFFUL) +/* ICC_SGI1R_EL1 */ +#define ICC_SGI1R_EL1_TL_MASK 0xffffUL +#define ICC_SGI1R_EL1_AFF1_SHIFT 16 +#define ICC_SGI1R_EL1_SGIID_SHIFT 24 +#define ICC_SGI1R_EL1_AFF2_SHIFT 32 +#define ICC_SGI1R_EL1_AFF3_SHIFT 48 +#define ICC_SGI1R_EL1_SGIID_MASK 0xfUL +#define ICC_SGI1R_EL1_IRM (0x1UL << 40) + /* ICC_SRE_EL1 */ #define ICC_SRE_EL1_SRE (1U << 0) From 8f28a42ee71491f086bb0704cb56eff4f7d7fa4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Thu, 11 Feb 2016 11:57:12 +0000 Subject: [PATCH 061/142] xen-netfront: remove useless NULL check in netif_free xn_ifp is allocated in create_netdev with if_alloc(IFT_ETHER). According to the current arrangement it can't be NULL. Coverity ID: 1349805 Submitted by: Wei Liu Reviewed by: royger Sponsored by: Citrix Systems R&D Differential revision: https://reviews.freebsd.org/D5252 --- sys/dev/xen/netfront/netfront.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 296c940f0836..41c70f14ab55 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -2280,11 +2280,9 @@ netif_free(struct netfront_info *np) netif_disconnect_backend(np); free(np->rxq, M_DEVBUF); free(np->txq, M_DEVBUF); - if (np->xn_ifp != NULL) { - ether_ifdetach(np->xn_ifp); - if_free(np->xn_ifp); - np->xn_ifp = NULL; - } + ether_ifdetach(np->xn_ifp); + if_free(np->xn_ifp); + np->xn_ifp = NULL; ifmedia_removeall(&np->sc_media); } From 513411c9f5993e6432e10bbb505bd6d8bd55bbc8 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 11:57:13 +0000 Subject: [PATCH 062/142] Fix bugs in interrupts allocation on ARM64 Separate interrupt descriptors lookup from allocation. It was possible to perform config on non-existing interrupt simply by allocating spurious descriptor. Must lock the interrupt descriptors table lookup to avoid mismatches. This ought to prevent trouble while setting up new interrupt and dispatching existing one. Use spin mutex rather than sleep mutex. This is mainly due to lock in arm_dispatch_intr. This should be eventually changed to a lock-less solution without walking through a linked list on each interrupt. Reviewed by: andrew, wma Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5121 --- sys/arm64/arm64/intr_machdep.c | 67 +++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/sys/arm64/arm64/intr_machdep.c b/sys/arm64/arm64/intr_machdep.c index 3389c69da942..70902ce2e776 100644 --- a/sys/arm64/arm64/intr_machdep.c +++ b/sys/arm64/arm64/intr_machdep.c @@ -105,7 +105,7 @@ static void intr_init(void *dummy __unused) { - mtx_init(&intr_list_lock, "intr sources lock", NULL, MTX_DEF); + mtx_init(&intr_list_lock, "intr sources lock", NULL, MTX_SPIN); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); @@ -123,33 +123,44 @@ intrcnt_setname(const char *name, u_int idx) } /* - * Get intr structure for the given interrupt number. - * Allocate one if this is the first time. - * (Similar to ppc's intr_lookup() but without actual - * lookup since irq number is an index in arm64_intrs[]). + * Find the interrupt descriptor in the list + * based on the hardware IRQ number. */ -static struct arm64_intr_entry * -intr_acquire(u_int hw_irq) +static __inline struct arm64_intr_entry * +intr_lookup_locked(u_int hw_irq) { struct arm64_intr_entry *intr; - mtx_lock(&intr_list_lock); - + mtx_assert(&intr_list_lock, MA_OWNED); SLIST_FOREACH(intr, &irq_slist_head, entries) { - if (intr->i_hw_irq == hw_irq) { - break; - } + if (intr->i_hw_irq == hw_irq) + return (intr); } + return (NULL); +} +/* + * Get intr structure for the given interrupt number. + * Allocate one if this is the first time. + */ +static struct arm64_intr_entry * +intr_allocate(u_int hw_irq) +{ + struct arm64_intr_entry *intr; + + /* Check if already allocated */ + mtx_lock_spin(&intr_list_lock); + intr = intr_lookup_locked(hw_irq); + mtx_unlock_spin(&intr_list_lock); if (intr != NULL) - goto out; + return (intr); /* Do not alloc another intr when max number of IRQs has been reached */ if (intrcntidx >= NIRQS) - goto out; + return (NULL); intr = malloc(sizeof(*intr), M_INTR, M_NOWAIT); if (intr == NULL) - goto out; + return (NULL); intr->i_event = NULL; intr->i_handlers = 0; @@ -158,9 +169,10 @@ intr_acquire(u_int hw_irq) intr->i_cntidx = atomic_fetchadd_int(&intrcntidx, 1); intr->i_cntp = &intrcnt[intr->i_cntidx]; intr->i_hw_irq = hw_irq; + mtx_lock_spin(&intr_list_lock); SLIST_INSERT_HEAD(&irq_slist_head, intr, entries); -out: - mtx_unlock(&intr_list_lock); + mtx_unlock_spin(&intr_list_lock); + return intr; } @@ -312,7 +324,7 @@ arm_setup_intr(const char *name, driver_filter_t *filt, driver_intr_t handler, struct arm64_intr_entry *intr; int error; - intr = intr_acquire(hw_irq); + intr = intr_allocate(hw_irq); if (intr == NULL) return (ENOMEM); @@ -336,7 +348,6 @@ arm_setup_intr(const char *name, driver_filter_t *filt, driver_intr_t handler, intr_priority(flags), flags, cookiep); if (!error) { - mtx_lock(&intr_list_lock); intrcnt_setname(intr->i_event->ie_fullname, intr->i_cntidx); intr->i_handlers++; @@ -349,7 +360,6 @@ arm_setup_intr(const char *name, driver_filter_t *filt, driver_intr_t handler, PIC_UNMASK(root_pic, intr->i_hw_irq); } - mtx_unlock(&intr_list_lock); } return (error); @@ -364,12 +374,10 @@ arm_teardown_intr(void *cookie) intr = intr_handler_source(cookie); error = intr_event_remove_handler(cookie); if (!error) { - mtx_lock(&intr_list_lock); intr->i_handlers--; if (intr->i_handlers == 0) PIC_MASK(root_pic, intr->i_hw_irq); intrcnt_setname(intr->i_event->ie_fullname, intr->i_cntidx); - mtx_unlock(&intr_list_lock); } return (error); @@ -380,9 +388,11 @@ arm_config_intr(u_int hw_irq, enum intr_trigger trig, enum intr_polarity pol) { struct arm64_intr_entry *intr; - intr = intr_acquire(hw_irq); + mtx_lock_spin(&intr_list_lock); + intr = intr_lookup_locked(hw_irq); + mtx_unlock_spin(&intr_list_lock); if (intr == NULL) - return (ENOMEM); + return (EINVAL); intr->i_trig = trig; intr->i_pol = pol; @@ -398,12 +408,9 @@ arm_dispatch_intr(u_int hw_irq, struct trapframe *tf) { struct arm64_intr_entry *intr; - SLIST_FOREACH(intr, &irq_slist_head, entries) { - if (intr->i_hw_irq == hw_irq) { - break; - } - } - + mtx_lock_spin(&intr_list_lock); + intr = intr_lookup_locked(hw_irq); + mtx_unlock_spin(&intr_list_lock); if (intr == NULL) goto stray; From be7aab76ecdcff209a1055c50fec8b48b1323b6e Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 11:58:27 +0000 Subject: [PATCH 063/142] Introduce bus_bind_intr method for ARM64 It can be used to bind specific interrupt to a particular CPU. Requires PIC support for interrupts binding. Reviewed by: wma Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5122 --- sys/arm64/arm64/intr_machdep.c | 80 +++++++++++++++++++++++++++++++++- sys/arm64/arm64/nexus.c | 16 ++++++- sys/arm64/arm64/pic_if.m | 12 +++-- sys/arm64/include/intr.h | 1 + 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/sys/arm64/arm64/intr_machdep.c b/sys/arm64/arm64/intr_machdep.c index 70902ce2e776..277e0c19da48 100644 --- a/sys/arm64/arm64/intr_machdep.c +++ b/sys/arm64/arm64/intr_machdep.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -84,6 +85,7 @@ struct arm64_intr_entry { u_int i_hw_irq; /* Physical interrupt number */ u_int i_cntidx; /* Index in intrcnt table */ u_int i_handlers; /* Allocated handlers */ + u_int i_cpu; /* Assigned CPU */ u_long *i_cntp; /* Interrupt hit counter */ }; @@ -162,6 +164,8 @@ intr_allocate(u_int hw_irq) if (intr == NULL) return (NULL); + /* The default CPU is 0 but can be changed later by bind or shuffle */ + intr->i_cpu = 0; intr->i_event = NULL; intr->i_handlers = 0; intr->i_trig = INTR_TRIGGER_CONFORM; @@ -176,6 +180,44 @@ intr_allocate(u_int hw_irq) return intr; } +static int +intr_assign_cpu(void *arg, int cpu) +{ +#ifdef SMP + struct arm64_intr_entry *intr; + int error; + + if (root_pic == NULL) + panic("Cannot assing interrupt to CPU. No PIC configured"); + /* + * Set the interrupt to CPU affinity. + * Do not configure this in hardware during early boot. + * We will pick up the assignment once the APs are started. + */ + if (cpu != NOCPU) { + intr = arg; + if (!cold && smp_started) { + /* + * Bind the interrupt immediately + * if SMP is up and running. + */ + error = PIC_BIND(root_pic, intr->i_hw_irq, cpu); + if (error == 0) + intr->i_cpu = cpu; + } else { + /* Postpone binding until SMP is operational */ + intr->i_cpu = cpu; + error = 0; + } + } else + error = 0; + + return (error); +#else + return (EOPNOTSUPP); +#endif +} + static void intr_pre_ithread(void *arg) { @@ -339,7 +381,7 @@ arm_setup_intr(const char *name, driver_filter_t *filt, driver_intr_t handler, if (intr->i_event == NULL) { error = intr_event_create(&intr->i_event, (void *)intr, 0, hw_irq, intr_pre_ithread, intr_post_ithread, - intr_post_filter, NULL, "irq%u", hw_irq); + intr_post_filter, intr_assign_cpu, "irq%u", hw_irq); if (error) return (error); } @@ -447,6 +489,42 @@ arm_cpu_intr(struct trapframe *tf) } #ifdef SMP +static void +arm_intr_smp_init(void *dummy __unused) +{ + struct arm64_intr_entry *intr; + int error; + + if (root_pic == NULL) + panic("Cannot assing interrupts to CPUs. No PIC configured"); + + mtx_lock_spin(&intr_list_lock); + SLIST_FOREACH(intr, &irq_slist_head, entries) { + mtx_unlock_spin(&intr_list_lock); + error = PIC_BIND(root_pic, intr->i_hw_irq, intr->i_cpu); + if (error != 0) + intr->i_cpu = 0; + mtx_lock_spin(&intr_list_lock); + } + mtx_unlock_spin(&intr_list_lock); +} +SYSINIT(arm_intr_smp_init, SI_SUB_SMP, SI_ORDER_ANY, arm_intr_smp_init, NULL); + +/* Attempt to bind the specified IRQ to the specified CPU. */ +int +arm_intr_bind(u_int hw_irq, int cpu) +{ + struct arm64_intr_entry *intr; + + mtx_lock_spin(&intr_list_lock); + intr = intr_lookup_locked(hw_irq); + mtx_unlock_spin(&intr_list_lock); + if (intr == NULL) + return (EINVAL); + + return (intr_event_bind(intr->i_event, cpu)); +} + void arm_setup_ipihandler(driver_filter_t *filt, u_int ipi) { diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 8290cffca792..611addd9ad4b 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -113,6 +113,9 @@ static int nexus_deactivate_resource(device_t, device_t, int, int, static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); +#ifdef SMP +static int nexus_bind_intr(device_t, device_t, struct resource *, int); +#endif #ifdef FDT static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, @@ -131,7 +134,9 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), - +#ifdef SMP + DEVMETHOD(bus_bind_intr, nexus_bind_intr), +#endif { 0, 0 } }; @@ -293,6 +298,15 @@ nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) return (arm_teardown_intr(ih)); } +#ifdef SMP +static int +nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) +{ + + return (arm_intr_bind(rman_get_start(irq), cpu)); +} +#endif + static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) diff --git a/sys/arm64/arm64/pic_if.m b/sys/arm64/arm64/pic_if.m index fe358c6bafa4..33d1bcd00aa5 100644 --- a/sys/arm64/arm64/pic_if.m +++ b/sys/arm64/arm64/pic_if.m @@ -34,7 +34,11 @@ INTERFACE pic; CODE { - static pic_translate_code_t pic_translate_code_default; + static int pic_bind_default(device_t dev, u_int irq, u_int cpu) + { + + return (EOPNOTSUPP); + } static void pic_translate_code_default(device_t dev, u_int irq, int code, enum intr_trigger *trig, enum intr_polarity *pol) @@ -60,11 +64,11 @@ CODE { } }; -METHOD void bind { +METHOD int bind { device_t dev; u_int irq; - cpuset_t cpumask; -}; + u_int cpu; +} DEFAULT pic_bind_default; METHOD void translate_code { device_t dev; diff --git a/sys/arm64/include/intr.h b/sys/arm64/include/intr.h index 067c69b8f98f..2d7da21701d0 100644 --- a/sys/arm64/include/intr.h +++ b/sys/arm64/include/intr.h @@ -49,6 +49,7 @@ void arm_unmask_irq(u_int); #ifdef SMP void arm_init_secondary(void); +int arm_intr_bind(u_int, int); void arm_setup_ipihandler(driver_filter_t *, u_int); void arm_unmask_ipi(u_int); #endif From 55bdcadded8821de56d970f2cd047f1650d9f4fe Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 11:59:32 +0000 Subject: [PATCH 064/142] Call pmc_hook() correctly in the ARM64 interrupt handler pmc_hook() was called only in case of the stray interrupt but should rather be called on each interrupt. Move in to the arm_cpu_intr() handler, out of the critical section too. Reviewed by: br Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5161 --- sys/arm64/arm64/intr_machdep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm64/arm64/intr_machdep.c b/sys/arm64/arm64/intr_machdep.c index 277e0c19da48..5994279bc2f4 100644 --- a/sys/arm64/arm64/intr_machdep.c +++ b/sys/arm64/arm64/intr_machdep.c @@ -473,10 +473,6 @@ arm_dispatch_intr(u_int hw_irq, struct trapframe *tf) if (intr != NULL) PIC_MASK(root_pic, intr->i_hw_irq); -#ifdef HWPMC_HOOKS - if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) - pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); -#endif } void @@ -486,6 +482,10 @@ arm_cpu_intr(struct trapframe *tf) critical_enter(); PIC_DISPATCH(root_pic, tf); critical_exit(); +#ifdef HWPMC_HOOKS + if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) + pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); +#endif } #ifdef SMP From 47a1ff355e399a6afe17def92c1acb1b34a677c3 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 12:01:33 +0000 Subject: [PATCH 065/142] Initially bind all interrupts to the boot CPU when using GICv3 This should be done by routing all interrupts to CPU0, different assignment will be induced by either interrupts shuffling or bus_bind_intr(). Reviewed by: wma Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5229 --- sys/arm64/arm64/gic_v3.c | 2 +- sys/arm64/arm64/gic_v3_its.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index c2b97a3087e1..9c24b39b6311 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -565,7 +565,7 @@ gic_v3_dist_init(struct gic_v3_softc *sc) /* * 4. Route all interrupts to boot CPU. */ - aff = CPU_AFFINITY(PCPU_GET(cpuid)); + aff = CPU_AFFINITY(0); for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i++) gic_d_write(sc, 4, GICD_IROUTER(i), aff); diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c index 7daeabe13482..f22e8aac9123 100644 --- a/sys/arm64/arm64/gic_v3_its.c +++ b/sys/arm64/arm64/gic_v3_its.c @@ -1430,10 +1430,10 @@ its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, } /* - * XXX ARM64TODO: Currently all interrupts are going - * to be bound to the CPU that performs the configuration. + * Initially all interrupts go to CPU0 but can be moved + * to another CPU by bus_bind_intr() or interrupts shuffling. */ - cpuid = PCPU_GET(cpuid); + cpuid = 0; newdev->col = sc->its_cols[cpuid]; TAILQ_INSERT_TAIL(&sc->its_dev_list, newdev, entry); From 907a0579aa85b84bb7c61b78b91e0130101e0628 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 12:03:11 +0000 Subject: [PATCH 066/142] Implement finer locking in ITS - Change locks' names to be more suitable - Don't use blocking mutex. Lock only basic operations such as lists or bitmaps modifications. Reviewed by: wma Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5230 --- sys/arm64/arm64/gic_v3_its.c | 57 ++++++++++++++++++++---------------- sys/arm64/arm64/gic_v3_var.h | 4 +-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c index f22e8aac9123..872468319797 100644 --- a/sys/arm64/arm64/gic_v3_its.c +++ b/sys/arm64/arm64/gic_v3_its.c @@ -197,9 +197,9 @@ gic_v3_its_attach(device_t dev) * Initialize sleep & spin mutex for ITS */ /* Protects ITS device list and assigned LPIs bitmaps. */ - mtx_init(&sc->its_mtx, "ITS sleep lock", NULL, MTX_DEF); + mtx_init(&sc->its_dev_lock, "ITS dev lock", NULL, MTX_SPIN); /* Protects access to ITS command circular buffer. */ - mtx_init(&sc->its_spin_mtx, "ITS spin lock", NULL, MTX_SPIN); + mtx_init(&sc->its_cmd_lock, "ITS cmd lock", NULL, MTX_SPIN); rid = 0; sc->its_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, @@ -1181,7 +1181,7 @@ its_cmd_alloc_locked(struct gic_v3_its_softc *sc) */ us_left = 1000000; - mtx_assert(&sc->its_spin_mtx, MA_OWNED); + mtx_assert(&sc->its_cmd_lock, MA_OWNED); while (its_cmd_queue_full(sc)) { if (us_left-- == 0) { /* Timeout while waiting for free command */ @@ -1334,11 +1334,11 @@ its_cmd_send(struct gic_v3_its_softc *sc, struct its_cmd_desc *desc) struct its_cmd_desc desc_sync; uint64_t target, cwriter; - mtx_lock_spin(&sc->its_spin_mtx); + mtx_lock_spin(&sc->its_cmd_lock); cmd = its_cmd_alloc_locked(sc); if (cmd == NULL) { device_printf(sc->dev, "could not allocate ITS command\n"); - mtx_unlock_spin(&sc->its_spin_mtx); + mtx_unlock_spin(&sc->its_cmd_lock); return (EBUSY); } @@ -1360,7 +1360,7 @@ its_cmd_send(struct gic_v3_its_softc *sc, struct its_cmd_desc *desc) cwriter = its_cmd_cwriter_offset(sc, sc->its_cmdq_write); gic_its_write(sc, 8, GITS_CWRITER, cwriter); cmd_write = sc->its_cmdq_write; - mtx_unlock_spin(&sc->its_spin_mtx); + mtx_unlock_spin(&sc->its_cmd_lock); its_cmd_wait_completion(sc, cmd, cmd_write); @@ -1372,7 +1372,7 @@ its_device_find_locked(struct gic_v3_its_softc *sc, device_t pci_dev) { struct its_dev *its_dev; - mtx_assert(&sc->its_mtx, MA_OWNED); + mtx_assert(&sc->its_dev_lock, MA_OWNED); /* Find existing device if any */ TAILQ_FOREACH(its_dev, &sc->its_dev_list, entry) { if (its_dev->pci_dev == pci_dev) @@ -1383,7 +1383,7 @@ its_device_find_locked(struct gic_v3_its_softc *sc, device_t pci_dev) } static struct its_dev * -its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, +its_device_alloc(struct gic_v3_its_softc *sc, device_t pci_dev, u_int nvecs) { struct its_dev *newdev; @@ -1391,10 +1391,12 @@ its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, uint32_t devid; u_int cpuid; size_t esize; + int err; - mtx_assert(&sc->its_mtx, MA_OWNED); + mtx_lock_spin(&sc->its_dev_lock); /* Find existing device if any */ newdev = its_device_find_locked(sc, pci_dev); + mtx_unlock_spin(&sc->its_dev_lock); if (newdev != NULL) return (newdev); @@ -1408,7 +1410,10 @@ its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, newdev->pci_dev = pci_dev; newdev->devid = devid; - if (lpi_alloc_chunk(sc, &newdev->lpis, nvecs) != 0) { + mtx_lock_spin(&sc->its_dev_lock); + err = lpi_alloc_chunk(sc, &newdev->lpis, nvecs); + mtx_unlock_spin(&sc->its_dev_lock); + if (err != 0) { free(newdev, M_GIC_V3_ITS); return (NULL); } @@ -1424,7 +1429,9 @@ its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, roundup2(roundup2(nvecs, 2) * esize, 0x100), M_GIC_V3_ITS, (M_NOWAIT | M_ZERO), 0, ~0UL, 0x100, 0); if (newdev->itt == 0) { + mtx_lock_spin(&sc->its_dev_lock); lpi_free_chunk(sc, &newdev->lpis); + mtx_unlock_spin(&sc->its_dev_lock); free(newdev, M_GIC_V3_ITS); return (NULL); } @@ -1436,7 +1443,9 @@ its_device_alloc_locked(struct gic_v3_its_softc *sc, device_t pci_dev, cpuid = 0; newdev->col = sc->its_cols[cpuid]; + mtx_lock_spin(&sc->its_dev_lock); TAILQ_INSERT_TAIL(&sc->its_dev_list, newdev, entry); + mtx_unlock_spin(&sc->its_dev_lock); /* Map device to its ITT */ its_cmd_mapd(sc, newdev, 1); @@ -1449,7 +1458,7 @@ its_device_asign_lpi_locked(struct gic_v3_its_softc *sc, struct its_dev *its_dev, u_int *irq) { - mtx_assert(&sc->its_mtx, MA_OWNED); + mtx_assert(&sc->its_dev_lock, MA_OWNED); if (its_dev->lpis.lpi_free == 0) { panic("Requesting more LPIs than allocated for this device. " "LPI num: %u, free %u", its_dev->lpis.lpi_num, @@ -1612,21 +1621,19 @@ gic_v3_its_alloc_msix(device_t dev, device_t pci_dev, int *irq) sc = device_get_softc(dev); - mtx_lock(&sc->its_mtx); nvecs = PCI_MSIX_NUM(pci_dev); /* * Allocate device as seen by ITS if not already available. * Notice that MSI-X interrupts are allocated on one-by-one basis. */ - its_dev = its_device_alloc_locked(sc, pci_dev, nvecs); - if (its_dev == NULL) { - mtx_unlock(&sc->its_mtx); + its_dev = its_device_alloc(sc, pci_dev, nvecs); + if (its_dev == NULL) return (ENOMEM); - } + mtx_lock_spin(&sc->its_dev_lock); its_device_asign_lpi_locked(sc, its_dev, irq); - mtx_unlock(&sc->its_mtx); + mtx_unlock_spin(&sc->its_dev_lock); return (0); } @@ -1640,18 +1647,16 @@ gic_v3_its_alloc_msi(device_t dev, device_t pci_dev, int count, int *irqs) sc = device_get_softc(dev); /* Allocate device as seen by ITS if not already available. */ - mtx_lock(&sc->its_mtx); - its_dev = its_device_alloc_locked(sc, pci_dev, count); - if (its_dev == NULL) { - mtx_unlock(&sc->its_mtx); + its_dev = its_device_alloc(sc, pci_dev, count); + if (its_dev == NULL) return (ENOMEM); - } + mtx_lock_spin(&sc->its_dev_lock); for (; count > 0; count--) { its_device_asign_lpi_locked(sc, its_dev, irqs); irqs++; } - mtx_unlock(&sc->its_mtx); + mtx_unlock_spin(&sc->its_dev_lock); return (0); } @@ -1668,9 +1673,9 @@ gic_v3_its_map_msi(device_t dev, device_t pci_dev, int irq, uint64_t *addr, sc = device_get_softc(dev); /* Verify that this device is allocated and owns this LPI */ - mtx_lock(&sc->its_mtx); - its_dev = its_device_find_locked(sc, pci_dev); - mtx_unlock(&sc->its_mtx); + mtx_lock_spin(&sc->its_dev_lock); + its_dev = its_device_find_locked(sc, pci_dev, 0); + mtx_unlock_spin(&sc->its_dev_lock); if (its_dev == NULL) return (EINVAL); diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index 8ebd144905f0..04fa67b620c0 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -230,8 +230,8 @@ struct gic_v3_its_softc { unsigned long * its_lpi_bitmap; uint32_t its_lpi_maxid; - struct mtx its_mtx; - struct mtx its_spin_mtx; + struct mtx its_dev_lock; + struct mtx its_cmd_lock; uint32_t its_socket; /* Socket number ITS is attached to */ }; From 6cd36342c059ec7ae14daa35a2d6f4710c375853 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 11 Feb 2016 12:04:58 +0000 Subject: [PATCH 067/142] Support interrupts binding in GICv3 and ITS - Add MOVI command and routine for the LPI migration - Allow to search for the ITS device descriptor using not only devID but also LPI number. - Bind SPIs in the Distributor - Don't bind its_dev to collection. Keep track of the collection IDs for each LPI. Reviewed by: wma Obtained from: Semihalf Sponsored by: Cavium Differential Revision: https://reviews.freebsd.org/D5231 --- sys/arm64/arm64/gic_v3.c | 24 ++++++ sys/arm64/arm64/gic_v3_its.c | 160 ++++++++++++++++++++++++++++------- sys/arm64/arm64/gic_v3_var.h | 18 +++- 3 files changed, 167 insertions(+), 35 deletions(-) diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 9c24b39b6311..d8434cf084ed 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include "gic_v3_var.h" /* Device and PIC methods */ +static int gic_v3_bind(device_t, u_int, u_int); static void gic_v3_dispatch(device_t, struct trapframe *); static void gic_v3_eoi(device_t, u_int); static void gic_v3_mask_irq(device_t, u_int); @@ -72,6 +73,7 @@ static device_method_t gic_v3_methods[] = { DEVMETHOD(device_detach, gic_v3_detach), /* PIC interface */ + DEVMETHOD(pic_bind, gic_v3_bind), DEVMETHOD(pic_dispatch, gic_v3_dispatch), DEVMETHOD(pic_eoi, gic_v3_eoi), DEVMETHOD(pic_mask, gic_v3_mask_irq), @@ -244,6 +246,28 @@ gic_v3_detach(device_t dev) /* * PIC interface. */ + +static int +gic_v3_bind(device_t dev, u_int irq, u_int cpuid) +{ + uint64_t aff; + struct gic_v3_softc *sc; + + sc = device_get_softc(dev); + + if (irq <= GIC_LAST_PPI) { + /* Can't bind PPI to another CPU but it's not an error */ + return (0); + } else if (irq >= GIC_FIRST_SPI && irq <= GIC_LAST_SPI) { + aff = CPU_AFFINITY(cpuid); + gic_d_write(sc, 4, GICD_IROUTER(irq), aff); + return (0); + } else if (irq >= GIC_FIRST_LPI) + return (lpi_migrate(dev, irq, cpuid)); + + return (EINVAL); +} + static void gic_v3_dispatch(device_t dev, struct trapframe *frame) { diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c index 872468319797..7a547c1cd70b 100644 --- a/sys/arm64/arm64/gic_v3_its.c +++ b/sys/arm64/arm64/gic_v3_its.c @@ -92,9 +92,13 @@ static void its_free_tables(struct gic_v3_its_softc *); static void its_init_commandq(struct gic_v3_its_softc *); static void its_init_cpu_collection(struct gic_v3_its_softc *); static uint32_t its_get_devid(device_t); +static struct its_dev * its_device_find_locked(struct gic_v3_its_softc *, + device_t, uint32_t); static int its_cmd_send(struct gic_v3_its_softc *, struct its_cmd_desc *); +static void its_cmd_movi(struct gic_v3_its_softc *, struct its_dev *, + struct its_col *, uint32_t); static void its_cmd_mapc(struct gic_v3_its_softc *, struct its_col *, uint8_t); static void its_cmd_mapvi(struct gic_v3_its_softc *, struct its_dev *, uint32_t, uint32_t); @@ -846,18 +850,28 @@ static int lpi_alloc_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic, u_int nvecs) { + u_int *col_ids; int fclr; /* First cleared bit */ uint8_t *bitmap; size_t nb, i; + col_ids = malloc(sizeof(*col_ids) * nvecs, M_GIC_V3_ITS, + (M_NOWAIT | M_ZERO)); + if (col_ids == NULL) + return (ENOMEM); + + mtx_lock_spin(&sc->its_dev_lock); bitmap = (uint8_t *)sc->its_lpi_bitmap; fclr = 0; retry: /* Check other bits - sloooow */ for (i = 0, nb = fclr; i < nvecs; i++, nb++) { - if (nb > sc->its_lpi_maxid) + if (nb > sc->its_lpi_maxid) { + mtx_unlock_spin(&sc->its_dev_lock); + free(col_ids, M_GIC_V3_ITS); return (EINVAL); + } if (isset(bitmap, nb)) { /* To little free bits in this area. Move on. */ @@ -870,6 +884,15 @@ lpi_alloc_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic, lpic->lpi_base = fclr + GIC_FIRST_LPI; lpic->lpi_num = nvecs; lpic->lpi_free = lpic->lpi_num; + lpic->lpi_col_ids = col_ids; + for (i = 0; i < lpic->lpi_num; i++) { + /* + * Initially all interrupts go to CPU0 but can be moved + * to another CPU by bus_bind_intr() or interrupts shuffling. + */ + lpic->lpi_col_ids[i] = 0; + } + mtx_unlock_spin(&sc->its_dev_lock); return (0); } @@ -885,6 +908,7 @@ lpi_free_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic) KASSERT((lpic->lpi_free == lpic->lpi_num), ("Trying to free LPI chunk that is still in use.\n")); + mtx_lock_spin(&sc->its_dev_lock); /* First bit of this chunk in a global bitmap */ start = lpic->lpi_base - GIC_FIRST_LPI; /* and last bit of this chunk... */ @@ -892,6 +916,10 @@ lpi_free_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic) /* Finally free this chunk */ bit_nclear(bitmap, start, end); + mtx_unlock_spin(&sc->its_dev_lock); + + free(lpic->lpi_col_ids, M_GIC_V3_ITS); + lpic->lpi_col_ids = NULL; } static void @@ -953,6 +981,32 @@ lpi_xmask_irq(device_t parent, uint32_t irq, boolean_t unmask) (unmask == TRUE) ? "unmask" : "mask", irq); } +int +lpi_migrate(device_t parent, uint32_t irq, u_int cpuid) +{ + struct gic_v3_its_softc *sc; + struct its_dev *its_dev; + struct its_col *col; + + sc = its_sc; + mtx_lock_spin(&sc->its_dev_lock); + its_dev = its_device_find_locked(sc, NULL, irq); + mtx_unlock_spin(&sc->its_dev_lock); + if (its_dev == NULL) { + /* Cannot migrate not configured LPI */ + return (ENXIO); + } + + /* Find local device's interrupt identifier */ + irq = irq - its_dev->lpis.lpi_base; + /* Move interrupt to another collection */ + col = sc->its_cols[cpuid]; + its_cmd_movi(sc, its_dev, col, irq); + its_dev->lpis.lpi_col_ids[irq] = cpuid; + + return (0); +} + void lpi_unmask_irq(device_t parent, uint32_t irq) { @@ -1052,6 +1106,20 @@ cmd_fix_endian(struct its_cmd *cmd) cmd->cmd_dword[i] = htole64(cmd->cmd_dword[i]); } +static void +its_cmd_movi(struct gic_v3_its_softc *sc, struct its_dev *its_dev, + struct its_col *col, uint32_t id) +{ + struct its_cmd_desc desc; + + desc.cmd_type = ITS_CMD_MOVI; + desc.cmd_desc_movi.its_dev = its_dev; + desc.cmd_desc_movi.col = col; + desc.cmd_desc_movi.id = id; + + its_cmd_send(sc, &desc); +} + static void its_cmd_mapc(struct gic_v3_its_softc *sc, struct its_col *col, uint8_t valid) { @@ -1073,9 +1141,15 @@ its_cmd_mapvi(struct gic_v3_its_softc *sc, struct its_dev *its_dev, uint32_t id, uint32_t pid) { struct its_cmd_desc desc; + struct its_col *col; + u_int col_id; + + col_id = its_dev->lpis.lpi_col_ids[id]; + col = sc->its_cols[col_id]; desc.cmd_type = ITS_CMD_MAPVI; desc.cmd_desc_mapvi.its_dev = its_dev; + desc.cmd_desc_mapvi.col = col; desc.cmd_desc_mapvi.id = id; desc.cmd_desc_mapvi.pid = pid; @@ -1083,14 +1157,23 @@ its_cmd_mapvi(struct gic_v3_its_softc *sc, struct its_dev *its_dev, } static void __unused -its_cmd_mapi(struct gic_v3_its_softc *sc, struct its_dev *its_dev, - uint32_t lpinum) +its_cmd_mapi(struct gic_v3_its_softc *sc, struct its_dev *its_dev, uint32_t pid) { struct its_cmd_desc desc; + struct its_col *col; + u_int col_id; + uint32_t id; + + KASSERT(pid >= its_dev->lpis.lpi_base, + ("%s: invalid pid: %d for the ITS device", __func__, pid)); + id = pid - its_dev->lpis.lpi_base; + col_id = its_dev->lpis.lpi_col_ids[id]; + col = sc->its_cols[col_id]; desc.cmd_type = ITS_CMD_MAPI; desc.cmd_desc_mapi.its_dev = its_dev; - desc.cmd_desc_mapi.lpinum = lpinum; + desc.cmd_desc_mapi.col = col; + desc.cmd_desc_mapi.pid = pid; its_cmd_send(sc, &desc); } @@ -1109,14 +1192,23 @@ its_cmd_mapd(struct gic_v3_its_softc *sc, struct its_dev *its_dev, } static void -its_cmd_inv(struct gic_v3_its_softc *sc, struct its_dev *its_dev, - uint32_t lpinum) +its_cmd_inv(struct gic_v3_its_softc *sc, struct its_dev *its_dev, uint32_t pid) { struct its_cmd_desc desc; + struct its_col *col; + u_int col_id; + uint32_t id; + + KASSERT(pid >= its_dev->lpis.lpi_base, + ("%s: invalid pid: %d for the ITS device", __func__, pid)); + id = pid - its_dev->lpis.lpi_base; + col_id = its_dev->lpis.lpi_col_ids[id]; + col = sc->its_cols[col_id]; desc.cmd_type = ITS_CMD_INV; - desc.cmd_desc_inv.lpinum = lpinum - its_dev->lpis.lpi_base; + desc.cmd_desc_inv.pid = pid - its_dev->lpis.lpi_base; desc.cmd_desc_inv.its_dev = its_dev; + desc.cmd_desc_inv.col = col; its_cmd_send(sc, &desc); } @@ -1216,13 +1308,19 @@ its_cmd_prepare(struct its_cmd *cmd, struct its_cmd_desc *desc) target = ITS_TARGET_NONE; switch (cmd_type) { + case ITS_CMD_MOVI: /* Move interrupt ID to another collection */ + target = desc->cmd_desc_movi.col->col_target; + cmd_format_command(cmd, ITS_CMD_MOVI); + cmd_format_id(cmd, desc->cmd_desc_movi.id); + cmd_format_col(cmd, desc->cmd_desc_movi.col->col_id); + cmd_format_devid(cmd, desc->cmd_desc_movi.its_dev->devid); + break; case ITS_CMD_SYNC: /* Wait for previous commands completion */ target = desc->cmd_desc_sync.col->col_target; cmd_format_command(cmd, ITS_CMD_SYNC); cmd_format_target(cmd, target); break; case ITS_CMD_MAPD: /* Assign ITT to device */ - target = desc->cmd_desc_mapd.its_dev->col->col_target; cmd_format_command(cmd, ITS_CMD_MAPD); cmd_format_itt(cmd, vtophys(desc->cmd_desc_mapd.its_dev->itt)); /* @@ -1249,25 +1347,25 @@ its_cmd_prepare(struct its_cmd *cmd, struct its_cmd_desc *desc) cmd_format_target(cmd, target); break; case ITS_CMD_MAPVI: - target = desc->cmd_desc_mapvi.its_dev->col->col_target; + target = desc->cmd_desc_mapvi.col->col_target; cmd_format_command(cmd, ITS_CMD_MAPVI); cmd_format_devid(cmd, desc->cmd_desc_mapvi.its_dev->devid); cmd_format_id(cmd, desc->cmd_desc_mapvi.id); cmd_format_pid(cmd, desc->cmd_desc_mapvi.pid); - cmd_format_col(cmd, desc->cmd_desc_mapvi.its_dev->col->col_id); + cmd_format_col(cmd, desc->cmd_desc_mapvi.col->col_id); break; case ITS_CMD_MAPI: - target = desc->cmd_desc_mapi.its_dev->col->col_target; + target = desc->cmd_desc_mapi.col->col_target; cmd_format_command(cmd, ITS_CMD_MAPI); cmd_format_devid(cmd, desc->cmd_desc_mapi.its_dev->devid); - cmd_format_id(cmd, desc->cmd_desc_mapi.lpinum); - cmd_format_col(cmd, desc->cmd_desc_mapi.its_dev->col->col_id); + cmd_format_id(cmd, desc->cmd_desc_mapi.pid); + cmd_format_col(cmd, desc->cmd_desc_mapi.col->col_id); break; case ITS_CMD_INV: - target = desc->cmd_desc_inv.its_dev->col->col_target; + target = desc->cmd_desc_inv.col->col_target; cmd_format_command(cmd, ITS_CMD_INV); cmd_format_devid(cmd, desc->cmd_desc_inv.its_dev->devid); - cmd_format_id(cmd, desc->cmd_desc_inv.lpinum); + cmd_format_id(cmd, desc->cmd_desc_inv.pid); break; case ITS_CMD_INVALL: cmd_format_command(cmd, ITS_CMD_INVALL); @@ -1367,16 +1465,28 @@ its_cmd_send(struct gic_v3_its_softc *sc, struct its_cmd_desc *desc) return (0); } +/* Find ITS device descriptor by pci_dev or irq number */ static struct its_dev * -its_device_find_locked(struct gic_v3_its_softc *sc, device_t pci_dev) +its_device_find_locked(struct gic_v3_its_softc *sc, device_t pci_dev, + uint32_t irq) { struct its_dev *its_dev; + struct lpi_chunk *lpis; mtx_assert(&sc->its_dev_lock, MA_OWNED); + KASSERT((pci_dev == NULL || irq == 0), + ("%s: Can't search by both pci_dev and irq number", __func__)); /* Find existing device if any */ TAILQ_FOREACH(its_dev, &sc->its_dev_list, entry) { - if (its_dev->pci_dev == pci_dev) - return (its_dev); + if (pci_dev != NULL) { + if (its_dev->pci_dev == pci_dev) + return (its_dev); + } else if (irq != 0) { + lpis = &its_dev->lpis; + if ((irq >= lpis->lpi_base) && + (irq < (lpis->lpi_base + lpis->lpi_num))) + return (its_dev); + } } return (NULL); @@ -1389,13 +1499,12 @@ its_device_alloc(struct gic_v3_its_softc *sc, device_t pci_dev, struct its_dev *newdev; uint64_t typer; uint32_t devid; - u_int cpuid; size_t esize; int err; mtx_lock_spin(&sc->its_dev_lock); /* Find existing device if any */ - newdev = its_device_find_locked(sc, pci_dev); + newdev = its_device_find_locked(sc, pci_dev, 0); mtx_unlock_spin(&sc->its_dev_lock); if (newdev != NULL) return (newdev); @@ -1410,9 +1519,7 @@ its_device_alloc(struct gic_v3_its_softc *sc, device_t pci_dev, newdev->pci_dev = pci_dev; newdev->devid = devid; - mtx_lock_spin(&sc->its_dev_lock); err = lpi_alloc_chunk(sc, &newdev->lpis, nvecs); - mtx_unlock_spin(&sc->its_dev_lock); if (err != 0) { free(newdev, M_GIC_V3_ITS); return (NULL); @@ -1429,20 +1536,11 @@ its_device_alloc(struct gic_v3_its_softc *sc, device_t pci_dev, roundup2(roundup2(nvecs, 2) * esize, 0x100), M_GIC_V3_ITS, (M_NOWAIT | M_ZERO), 0, ~0UL, 0x100, 0); if (newdev->itt == 0) { - mtx_lock_spin(&sc->its_dev_lock); lpi_free_chunk(sc, &newdev->lpis); - mtx_unlock_spin(&sc->its_dev_lock); free(newdev, M_GIC_V3_ITS); return (NULL); } - /* - * Initially all interrupts go to CPU0 but can be moved - * to another CPU by bus_bind_intr() or interrupts shuffling. - */ - cpuid = 0; - newdev->col = sc->its_cols[cpuid]; - mtx_lock_spin(&sc->its_dev_lock); TAILQ_INSERT_TAIL(&sc->its_dev_list, newdev, entry); mtx_unlock_spin(&sc->its_dev_lock); diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index 04fa67b620c0..b3c0e5235f53 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -96,6 +96,7 @@ struct lpi_chunk { u_int lpi_base; u_int lpi_num; u_int lpi_free; /* First free LPI in set */ + u_int *lpi_col_ids; }; /* ITS device */ @@ -109,8 +110,6 @@ struct its_dev { struct lpi_chunk lpis; /* Virtual address of ITT */ vm_offset_t itt; - /* Interrupt collection */ - struct its_col * col; }; TAILQ_HEAD(its_dev_list, its_dev); @@ -133,6 +132,7 @@ struct its_cmd { }; /* ITS commands encoding */ +#define ITS_CMD_MOVI (0x01) #define ITS_CMD_SYNC (0x05) #define ITS_CMD_MAPD (0x08) #define ITS_CMD_MAPC (0x09) @@ -171,6 +171,12 @@ struct its_cmd_desc { uint8_t cmd_type; union { + struct { + struct its_dev *its_dev; + struct its_col *col; + uint32_t id; + } cmd_desc_movi; + struct { struct its_col *col; } cmd_desc_sync; @@ -182,13 +188,15 @@ struct its_cmd_desc { struct { struct its_dev *its_dev; + struct its_col *col; uint32_t pid; uint32_t id; } cmd_desc_mapvi; struct { struct its_dev *its_dev; - uint32_t lpinum; + struct its_col *col; + uint32_t pid; } cmd_desc_mapi; struct { @@ -198,7 +206,8 @@ struct its_cmd_desc { struct { struct its_dev *its_dev; - uint32_t lpinum; + struct its_col *col; + uint32_t pid; } cmd_desc_inv; struct { @@ -257,6 +266,7 @@ int gic_v3_its_map_msi(device_t, device_t, int, uint64_t *, uint32_t *); int its_init_cpu(struct gic_v3_its_softc *); +int lpi_migrate(device_t, uint32_t, u_int); void lpi_unmask_irq(device_t, uint32_t); void lpi_mask_irq(device_t, uint32_t); /* From 64a982ea56e9ac15f2e2cd6d133d0990cf761961 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 11 Feb 2016 13:15:37 +0000 Subject: [PATCH 068/142] Migrate the PTE format for book-e to standardize on the 'indirect PTE' format Summary: The revised Book-E spec, adding the specification for the MMUv2 and e6500, includes a hardware PTE layout for indirect page tables. In order to support this in the future, migrate the PTE format to match the MMUv2 hardware PTE format. Test Plan: Boot tested on a P5020 board. Booted to multiuser mode. Differential Revision: https://reviews.freebsd.org/D5224 --- sys/powerpc/booke/pmap.c | 64 ++++++++++++++++------------------ sys/powerpc/booke/trap_subr.S | 13 +++---- sys/powerpc/include/pte.h | 46 ++++++++++++------------ sys/powerpc/powerpc/genassym.c | 8 +++-- 4 files changed, 66 insertions(+), 65 deletions(-) diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index d0712b4de17d..86da60a68808 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -412,13 +412,13 @@ tlb_calc_wimg(vm_paddr_t pa, vm_memattr_t ma) if (ma != VM_MEMATTR_DEFAULT) { switch (ma) { case VM_MEMATTR_UNCACHEABLE: - return (PTE_I | PTE_G); + return (MAS2_I | MAS2_G); case VM_MEMATTR_WRITE_COMBINING: case VM_MEMATTR_WRITE_BACK: case VM_MEMATTR_PREFETCHABLE: - return (PTE_I); + return (MAS2_I); case VM_MEMATTR_WRITE_THROUGH: - return (PTE_W | PTE_M); + return (MAS2_W | MAS2_M); } } @@ -900,8 +900,7 @@ pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, uint8_t flags) tlb_miss_lock(); tlb0_flush_entry(va); - pte->flags = 0; - pte->rpn = 0; + *pte = 0; tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -984,8 +983,8 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, uint32_t flags, pmap->pm_pdir[pdir_idx] = ptbl; } pte = &(pmap->pm_pdir[pdir_idx][ptbl_idx]); - pte->rpn = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m)); - pte->flags |= (PTE_VALID | flags); + *pte = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m)); + *pte |= (PTE_VALID | flags | PTE_PS_4KB); /* 4KB pages only */ tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -1041,9 +1040,9 @@ kernel_pte_alloc(vm_offset_t data_end, vm_offset_t addr, vm_offset_t pdir) */ for (va = addr; va < data_end; va += PAGE_SIZE) { pte = &(kernel_pmap->pm_pdir[PDIR_IDX(va)][PTBL_IDX(va)]); - pte->rpn = kernload + (va - kernstart); - pte->flags = PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | - PTE_VALID; + *pte = PTE_RPN_FROM_PA(kernload + (va - kernstart)); + *pte |= PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | + PTE_VALID | PTE_PS_4KB; } } @@ -1525,7 +1524,8 @@ mmu_booke_kenter_attr(mmu_t mmu, vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma) (va <= VM_MAX_KERNEL_ADDRESS)), ("mmu_booke_kenter: invalid va")); flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID; - flags |= tlb_calc_wimg(pa, ma); + flags |= tlb_calc_wimg(pa, ma) << PTE_MAS2_SHIFT; + flags |= PTE_PS_4KB; pte = pte_find(mmu, kernel_pmap, va); @@ -1540,17 +1540,15 @@ mmu_booke_kenter_attr(mmu_t mmu, vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma) tlb0_flush_entry(va); } - pte->rpn = PTE_RPN_FROM_PA(pa); - pte->flags = flags; + *pte = PTE_RPN_FROM_PA(pa) | flags; //debugf("mmu_booke_kenter: pdir_idx = %d ptbl_idx = %d va=0x%08x " // "pa=0x%08x rpn=0x%08x flags=0x%08x\n", // pdir_idx, ptbl_idx, va, pa, pte->rpn, pte->flags); /* Flush the real memory from the instruction cache. */ - if ((flags & (PTE_I | PTE_G)) == 0) { + if ((flags & (PTE_I | PTE_G)) == 0) __syncicache((void *)va, PAGE_SIZE); - } tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -1584,8 +1582,7 @@ mmu_booke_kremove(mmu_t mmu, vm_offset_t va) /* Invalidate entry in TLB0, update PTE. */ tlb0_flush_entry(va); - pte->flags = 0; - pte->rpn = 0; + *pte = 0; tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -1700,7 +1697,7 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, * Before actually updating pte->flags we calculate and * prepare its new value in a helper var. */ - flags = pte->flags; + flags = *pte; flags &= ~(PTE_UW | PTE_UX | PTE_SW | PTE_SX | PTE_MODIFIED); /* Wiring change, just update stats. */ @@ -1748,7 +1745,7 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, * are turning execute permissions on, icache should * be flushed. */ - if ((pte->flags & (PTE_UX | PTE_SX)) == 0) + if ((*pte & (PTE_UX | PTE_SX)) == 0) sync++; } @@ -1762,7 +1759,7 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, tlb_miss_lock(); tlb0_flush_entry(va); - pte->flags = flags; + *pte = flags; tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -2069,7 +2066,7 @@ mmu_booke_protect(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_page_dirty(m); tlb0_flush_entry(va); - pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED); + *pte &= ~(PTE_UW | PTE_SW | PTE_MODIFIED); tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -2114,7 +2111,7 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m) vm_page_dirty(m); /* Flush mapping from TLB0. */ - pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED); + *pte &= ~(PTE_UW | PTE_SW | PTE_MODIFIED); tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -2194,7 +2191,7 @@ mmu_booke_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, else pte_wbit = PTE_UW; - if ((pte->flags & pte_wbit) || ((prot & VM_PROT_WRITE) == 0)) { + if ((*pte & pte_wbit) || ((prot & VM_PROT_WRITE) == 0)) { if (vm_page_pa_tryrelock(pmap, PTE_PA(pte), &pa)) goto retry; m = PHYS_TO_VM_PAGE(PTE_PA(pte)); @@ -2340,14 +2337,15 @@ mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m) paddr = VM_PAGE_TO_PHYS(m); flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID; - flags |= tlb_calc_wimg(paddr, pmap_page_get_memattr(m)); + flags |= tlb_calc_wimg(paddr, pmap_page_get_memattr(m)) << PTE_MAS2_SHIFT; + flags |= PTE_PS_4KB; critical_enter(); qaddr = PCPU_GET(qmap_addr); pte = pte_find(mmu, kernel_pmap, qaddr); - KASSERT(pte->flags == 0, ("mmu_booke_quick_enter_page: PTE busy")); + KASSERT(*pte == 0, ("mmu_booke_quick_enter_page: PTE busy")); /* * XXX: tlbivax is broadcast to other cores, but qaddr should @@ -2357,8 +2355,7 @@ mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m) __asm __volatile("tlbivax 0, %0" :: "r"(qaddr & MAS2_EPN_MASK)); __asm __volatile("isync; msync"); - pte->rpn = paddr & ~PTE_PA_MASK; - pte->flags = flags; + *pte = PTE_RPN_FROM_PA(paddr) | flags; /* Flush the real memory from the instruction cache. */ if ((flags & (PTE_I | PTE_G)) == 0) @@ -2376,11 +2373,10 @@ mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr) KASSERT(PCPU_GET(qmap_addr) == addr, ("mmu_booke_quick_remove_page: invalid address")); - KASSERT(pte->flags != 0, + KASSERT(*pte != 0, ("mmu_booke_quick_remove_page: PTE not in use")); - pte->flags = 0; - pte->rpn = 0; + *pte = 0; critical_exit(); } @@ -2494,9 +2490,9 @@ mmu_booke_clear_modify(mmu_t mmu, vm_page_t m) mtx_lock_spin(&tlbivax_mutex); tlb_miss_lock(); - if (pte->flags & (PTE_SW | PTE_UW | PTE_MODIFIED)) { + if (*pte & (PTE_SW | PTE_UW | PTE_MODIFIED)) { tlb0_flush_entry(pv->pv_va); - pte->flags &= ~(PTE_SW | PTE_UW | PTE_MODIFIED | + *pte &= ~(PTE_SW | PTE_UW | PTE_MODIFIED | PTE_REFERENCED); } @@ -2538,7 +2534,7 @@ mmu_booke_ts_referenced(mmu_t mmu, vm_page_t m) tlb_miss_lock(); tlb0_flush_entry(pv->pv_va); - pte->flags &= ~PTE_REFERENCED; + *pte &= ~PTE_REFERENCED; tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); @@ -2577,7 +2573,7 @@ mmu_booke_unwire(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva) if (!PTE_ISWIRED(pte)) panic("mmu_booke_unwire: pte %p isn't wired", pte); - pte->flags &= ~PTE_WIRED; + *pte &= ~PTE_WIRED; pmap->pm_stats.wired_count--; } } diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S index 5f5f1aab3898..8737dbac6769 100644 --- a/sys/powerpc/booke/trap_subr.S +++ b/sys/powerpc/booke/trap_subr.S @@ -686,7 +686,7 @@ pte_lookup: * This load may cause a Data TLB miss for non-kernel pmap! */ lwz %r21, PTE_FLAGS(%r25) - andis. %r21, %r21, PTE_VALID@h + andi. %r21, %r21, PTE_VALID@l bne 2f 1: li %r25, 0 @@ -721,20 +721,21 @@ tlb_fill_entry: andi. %r22, %r21, (PTE_SW | PTE_UW)@l /* check if writable */ beq 2f - oris %r21, %r21, PTE_MODIFIED@h /* set modified bit */ + ori %r21, %r21, PTE_MODIFIED@l /* set modified bit */ 2: stwcx. %r21, %r23, %r25 /* write it back */ bne- 1b /* Update MAS2. */ - rlwimi %r27, %r21, 0, 27, 30 /* insert WIMG bits from pte */ + rlwimi %r27, %r21, 13, 27, 30 /* insert WIMG bits from pte */ /* Setup MAS3 value in r23. */ lwz %r23, PTE_RPN(%r25) /* get pte->rpn */ - rlwinm %r22, %r23, 12, 0, 20 /* extract MAS3 portion of RPN */ + rlwinm %r22, %r23, 20, 0, 11 /* extract MAS3 portion of RPN */ - rlwimi %r22, %r21, 24, 26, 31 /* insert protection bits from pte */ - rlwinm %r23, %r23, 12, 28, 31 /* MAS7 portion of RPN */ + rlwimi %r22, %r21, 30, 26, 31 /* insert protection bits from pte */ + rlwimi %r22, %r21, 20, 12, 19 /* insert lower 8 RPN bits to MAS3 */ + rlwinm %r23, %r23, 20, 24, 31 /* MAS7 portion of RPN */ /* Load MAS registers. */ mtspr SPR_MAS0, %r29 diff --git a/sys/powerpc/include/pte.h b/sys/powerpc/include/pte.h index 3a279295b237..7108072ed6a7 100644 --- a/sys/powerpc/include/pte.h +++ b/sys/powerpc/include/pte.h @@ -212,11 +212,7 @@ typedef struct lpte lpte_t; * page size is 4k (12-bit mask), so RPN can really fit into 24 bits. */ #ifndef LOCORE -struct pte { - vm_offset_t rpn; - uint32_t flags; -}; -typedef struct pte pte_t; +typedef uint64_t pte_t; #endif /* RPN mask, TLB0 4K pages */ @@ -225,13 +221,14 @@ typedef struct pte pte_t; #if defined(BOOKE_E500) /* PTE bits assigned to MAS2, MAS3 flags */ -#define PTE_W MAS2_W -#define PTE_I MAS2_I -#define PTE_M MAS2_M -#define PTE_G MAS2_G +#define PTE_MAS2_SHIFT 19 +#define PTE_W (MAS2_W << PTE_MAS2_SHIFT) +#define PTE_I (MAS2_I << PTE_MAS2_SHIFT) +#define PTE_M (MAS2_M << PTE_MAS2_SHIFT) +#define PTE_G (MAS2_G << PTE_MAS2_SHIFT) #define PTE_MAS2_MASK (MAS2_G | MAS2_M | MAS2_I | MAS2_W) -#define PTE_MAS3_SHIFT 8 +#define PTE_MAS3_SHIFT 2 #define PTE_UX (MAS3_UX << PTE_MAS3_SHIFT) #define PTE_SX (MAS3_SX << PTE_MAS3_SHIFT) #define PTE_UW (MAS3_UW << PTE_MAS3_SHIFT) @@ -241,6 +238,9 @@ typedef struct pte pte_t; #define PTE_MAS3_MASK ((MAS3_UX | MAS3_SX | MAS3_UW \ | MAS3_SW | MAS3_UR | MAS3_SR) << PTE_MAS3_SHIFT) +#define PTE_PS_SHIFT 8 +#define PTE_PS_4KB (2 << PTE_PS_SHIFT) + #elif defined(BOOKE_PPC4XX) #define PTE_WL1 TLB_WL1 @@ -262,21 +262,21 @@ typedef struct pte pte_t; #endif /* Other PTE flags */ -#define PTE_VALID 0x80000000 /* Valid */ -#define PTE_MODIFIED 0x40000000 /* Modified */ -#define PTE_WIRED 0x20000000 /* Wired */ -#define PTE_MANAGED 0x10000000 /* Managed */ -#define PTE_REFERENCED 0x04000000 /* Referenced */ +#define PTE_VALID 0x00000001 /* Valid */ +#define PTE_MODIFIED 0x00001000 /* Modified */ +#define PTE_WIRED 0x00002000 /* Wired */ +#define PTE_MANAGED 0x00000002 /* Managed */ +#define PTE_REFERENCED 0x00040000 /* Referenced */ /* Macro argument must of pte_t type. */ -#define PTE_PA_SHIFT 12 -#define PTE_RPN_FROM_PA(pa) ((pa) >> PTE_PA_SHIFT) -#define PTE_PA(pte) ((vm_paddr_t)((pte)->rpn) << PTE_PA_SHIFT) -#define PTE_ISVALID(pte) ((pte)->flags & PTE_VALID) -#define PTE_ISWIRED(pte) ((pte)->flags & PTE_WIRED) -#define PTE_ISMANAGED(pte) ((pte)->flags & PTE_MANAGED) -#define PTE_ISMODIFIED(pte) ((pte)->flags & PTE_MODIFIED) -#define PTE_ISREFERENCED(pte) ((pte)->flags & PTE_REFERENCED) +#define PTE_ARPN_SHIFT 12 +#define PTE_RPN_FROM_PA(pa) (((pa) & ~PAGE_MASK) << PTE_ARPN_SHIFT) +#define PTE_PA(pte) ((vm_paddr_t)(*pte >> PTE_ARPN_SHIFT) & ~PAGE_MASK) +#define PTE_ISVALID(pte) ((*pte) & PTE_VALID) +#define PTE_ISWIRED(pte) ((*pte) & PTE_WIRED) +#define PTE_ISMANAGED(pte) ((*pte) & PTE_MANAGED) +#define PTE_ISMODIFIED(pte) ((*pte) & PTE_MODIFIED) +#define PTE_ISREFERENCED(pte) ((*pte) & PTE_REFERENCED) #endif /* BOOKE */ #endif /* _MACHINE_PTE_H_ */ diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index 1faa0d69f299..44c0280de016 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -119,8 +119,12 @@ ASSYM(USER_SR, USER_SR); #endif #elif defined(BOOKE) ASSYM(PM_PDIR, offsetof(struct pmap, pm_pdir)); -ASSYM(PTE_RPN, offsetof(struct pte, rpn)); -ASSYM(PTE_FLAGS, offsetof(struct pte, flags)); +/* + * With pte_t being a bitfield struct, these fields cannot be addressed via + * offsetof(). + */ +ASSYM(PTE_RPN, 0); +ASSYM(PTE_FLAGS, sizeof(uint32_t)); #if defined(BOOKE_E500) ASSYM(TLB0_ENTRY_SIZE, sizeof(struct tlb_entry)); #endif From cfddfe4cd58c0ae66da6c4766c48758d20403bb3 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Thu, 11 Feb 2016 13:28:52 +0000 Subject: [PATCH 069/142] o Move non-generic kernel configuration out from GENERIC. o Add kernel configuration for QEMU. Both SPIKE and QEMU kernel configs are temporary (until we will be able to obtain DTB from loader). Sponsored by: DARPA, AFRL Sponsored by: HEIF5 --- sys/boot/fdt/dts/riscv/qemu.dts | 92 +++++++++++++++++++++++++++++++++ sys/riscv/conf/GENERIC | 3 -- sys/riscv/conf/QEMU | 26 ++++++++++ sys/riscv/conf/SPIKE | 26 ++++++++++ 4 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 sys/boot/fdt/dts/riscv/qemu.dts create mode 100644 sys/riscv/conf/QEMU create mode 100644 sys/riscv/conf/SPIKE diff --git a/sys/boot/fdt/dts/riscv/qemu.dts b/sys/boot/fdt/dts/riscv/qemu.dts new file mode 100644 index 000000000000..b9590a9b1982 --- /dev/null +++ b/sys/boot/fdt/dts/riscv/qemu.dts @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/dts-v1/; + +/ { + model = "QEMU RV64I"; + compatible = "riscv,rv64i"; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <1>; + + aliases { + console0 = &console0; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x8000000>; /* 128MB at 0x0 */ + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + #interrupt-cells = <1>; + + compatible = "simple-bus"; + ranges; + + pic0: pic@0 { + compatible = "riscv,pic"; + interrupt-controller; + }; + + timer0: timer@0 { + compatible = "riscv,timer"; + interrupts = < 1 >; + interrupt-parent = < &pic0 >; + clock-frequency = < 400000000 >; + }; + + htif0: htif@0 { + compatible = "riscv,htif"; + interrupts = < 0 >; + interrupt-parent = < &pic0 >; + + console0: console@0 { + compatible = "htif,console"; + status = "okay"; + }; + }; + }; + + chosen { + bootargs = "-v"; + stdin = "console0"; + stdout = "console0"; + }; +}; diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC index a32a1f24ecfb..2565921d5f2e 100644 --- a/sys/riscv/conf/GENERIC +++ b/sys/riscv/conf/GENERIC @@ -98,7 +98,4 @@ device md # Memory "disks" device gif # IPv6 and IPv4 tunneling device firmware # firmware assist module -# RISCVTODO: This needs to be done via loader (when it's available). options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=spike.dts diff --git a/sys/riscv/conf/QEMU b/sys/riscv/conf/QEMU new file mode 100644 index 000000000000..f04075a1e10a --- /dev/null +++ b/sys/riscv/conf/QEMU @@ -0,0 +1,26 @@ +# +# Kernel configuration file for QEMU emulator. +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +include GENERIC +ident QEMU + +# RISCVTODO: This needs to be done via loader (when it's available). +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=qemu.dts diff --git a/sys/riscv/conf/SPIKE b/sys/riscv/conf/SPIKE new file mode 100644 index 000000000000..583d5a98873c --- /dev/null +++ b/sys/riscv/conf/SPIKE @@ -0,0 +1,26 @@ +# +# Kernel configuration file for UCB Spike simulator. +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +include GENERIC +ident SPIKE + +# RISCVTODO: This needs to be done via loader (when it's available). +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=spike.dts From b2390166cd8fce1384deb41f35251571730c2ee7 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 11 Feb 2016 14:45:18 +0000 Subject: [PATCH 070/142] Explain that boot1.efi prefers ZFS over UFS Reported by: smh --- share/man/man8/uefi.8 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/share/man/man8/uefi.8 b/share/man/man8/uefi.8 index a17fb08fe6dd..4f7935ed5a7d 100644 --- a/share/man/man8/uefi.8 +++ b/share/man/man8/uefi.8 @@ -92,6 +92,13 @@ for The search begins with partitions on the device from which .Pa boot1.efi was loaded, and continues with other available partitions. +If both +.Li freebsd-ufs +and +.Li freebsd-zfs +partitions exist on the same device the +.Li freebsd-zfs +partition is preferred. .Pa boot1.efi then loads and executes .Pa loader.efi . From a633908d21a09028b220fe42549ff87ed942b62a Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Thu, 11 Feb 2016 15:27:14 +0000 Subject: [PATCH 071/142] Ext4: Use boolean type instead of '0' and '1' There are precedents of uses of bool in the kernel and it is incorrect style to use integers as replacement for a boolean type. --- sys/fs/ext2fs/ext2_extents.c | 14 +++++++------- sys/fs/ext2fs/ext2_extents.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c index 230356c277f1..a66f682788be 100644 --- a/sys/fs/ext2fs/ext2_extents.c +++ b/sys/fs/ext2fs/ext2_extents.c @@ -43,7 +43,7 @@ #include #include -static int +static bool ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn, daddr_t *first_lbn, daddr_t *last_lbn) { @@ -67,14 +67,14 @@ ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path *path, path->ep_sparse_ext.e_len = first->ei_blk - *first_lbn; path->ep_sparse_ext.e_start_hi = 0; path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = 1; - return (1); + path->ep_is_sparse = true; + return (true); } path->ep_index = l - 1; *first_lbn = path->ep_index->ei_blk; if (path->ep_index < last) *last_lbn = l->ei_blk - 1; - return (0); + return (false); } static void @@ -103,7 +103,7 @@ ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn, path->ep_sparse_ext.e_len = first->e_blk - first_lbn; path->ep_sparse_ext.e_start_hi = 0; path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = 1; + path->ep_is_sparse = true; return; } path->ep_ext = l - 1; @@ -118,7 +118,7 @@ ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn, path->ep_sparse_ext.e_blk + 1; path->ep_sparse_ext.e_start_hi = 0; path->ep_sparse_ext.e_start_lo = 0; - path->ep_is_sparse = 1; + path->ep_is_sparse = true; } } @@ -213,7 +213,7 @@ ext4_ext_find_extent(struct m_ext2fs *fs, struct inode *ip, path->ep_depth = i; path->ep_ext = NULL; path->ep_index = NULL; - path->ep_is_sparse = 0; + path->ep_is_sparse = false; ext4_ext_binsearch(ip, path, lbn, first_lbn, last_lbn); return (path); diff --git a/sys/fs/ext2fs/ext2_extents.h b/sys/fs/ext2fs/ext2_extents.h index 4ce16f3e69ba..70eb685bff2b 100644 --- a/sys/fs/ext2fs/ext2_extents.h +++ b/sys/fs/ext2fs/ext2_extents.h @@ -84,7 +84,7 @@ struct ext4_extent_cache { struct ext4_extent_path { uint16_t ep_depth; struct buf *ep_bp; - int ep_is_sparse; + bool ep_is_sparse; union { struct ext4_extent ep_sparse_ext; struct ext4_extent *ep_ext; From 34096f3c064e80254f7cff4a9bf43068320b0bd6 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 11 Feb 2016 16:43:23 +0000 Subject: [PATCH 072/142] Include the correct header to get a phandle_t needed by ofw_bus_if.h. While here only include opt_platform.h once. Sponsored by: ABT Systems Ltd --- sys/mips/mips/nexus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index f781248b769e..1e3d4093cb6f 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -64,10 +64,8 @@ __FBSDID("$FreeBSD$"); #include #endif -#include "opt_platform.h" - #ifdef FDT -#include +#include #include "ofw_bus_if.h" #endif From e24c5f9706c7df9bbd9a49f3a6d2dddb9e80b480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 11 Feb 2016 17:25:12 +0000 Subject: [PATCH 073/142] Apply upstream r3619, r3620, r3621: add insecure-lan-zone option --- Makefile.in | 9 +-- doc/example.conf.in | 6 +- doc/unbound.conf.5.in | 5 ++ services/localzone.c | 114 +++----------------------------- util/as112.c | 143 +++++++++++++++++++++++++++++++++++++++++ util/as112.h | 57 ++++++++++++++++ util/config_file.c | 3 + util/config_file.h | 4 +- util/configlexer.lex | 1 + util/configparser.y | 16 ++++- validator/val_anchor.c | 11 ++++ 11 files changed, 257 insertions(+), 112 deletions(-) create mode 100644 util/as112.c create mode 100644 util/as112.h diff --git a/Makefile.in b/Makefile.in index 282c7d683316..381c3836f19c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,7 +95,7 @@ PYUNBOUND_SRC= # libunbound_wrap.lo if python libunbound wrapper enabled. PYUNBOUND_OBJ=@PYUNBOUND_OBJ@ COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \ -util/data/dname.c util/data/msgencode.c util/data/msgparse.c \ +util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \ iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \ iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \ @@ -113,7 +113,7 @@ validator/val_neg.c validator/val_nsec3.c validator/val_nsec.c \ validator/val_secalgo.c validator/val_sigcrypt.c \ validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) $(DNSTAP_SRC) COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ -msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ +as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \ iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo \ outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \ @@ -595,6 +595,7 @@ depend: rm -f $(DEPEND_TMP) $(DEPEND_TMP2) # Dependencies +as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \ $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/locks.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h \ @@ -702,7 +703,7 @@ localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/serv $(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \ $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h \ - $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h + $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/as112.h mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ @@ -821,7 +822,7 @@ val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/as112.h validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ diff --git a/doc/example.conf.in b/doc/example.conf.in index ff90e3b715d6..cf9a4eef849a 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -508,13 +508,17 @@ server: # local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault # And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa. - # if unbound is running service for the local host then it is useful + # If unbound is running service for the local host then it is useful # to perform lan-wide lookups to the upstream, and unblock the # long list of local-zones above. If this unbound is a dns server # for a network of computers, disabled is better and stops information # leakage of local lan information. # unblock-lan-zones: no + # The insecure-lan-zones option disables validation for + # these zones, as if they were all listed as domain-insecure. + # insecure-lan-zones: no + # a number of locally served zones can be configured. # local-zone: # local-data: "" diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 51f7c4ed483e..cc4c1dfff63a 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -841,6 +841,11 @@ as a (DHCP-) DNS network resolver for a group of machines, where such lookups should be filtered (RFC compliance), this also stops potential data leakage about the local network to the upstream DNS servers. .TP +.B insecure\-lan\-zones: \fI +Default is disabled. If enabled, then reverse lookups in private +address space are not validated. This is usually required whenever +\fIunblock\-lan\-zones\fR is used. +.TP .B local\-zone: \fI Configure a local zone. The type determines the answer to give if there is no match from local\-data. The types are deny, refuse, static, diff --git a/services/localzone.c b/services/localzone.c index c50ad0f1586f..f3b30ae4c5e6 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -51,6 +51,7 @@ #include "util/netevent.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" +#include "util/as112.h" struct local_zones* local_zones_create(void) @@ -592,6 +593,7 @@ static int lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) { struct local_zone* z; + const char** zstr; /* this list of zones is from RFC 6303 */ @@ -654,110 +656,14 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) lock_rw_unlock(&z->lock); } - /* if unblock lan-zones, then do not add the zones below. - * we do add the zones above, about 127.0.0.1, because localhost is - * not on the lan. */ - if(cfg->unblock_lan_zones) - return 1; - - /* block LAN level zones */ - if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") || - !add_as112_default(zones, cfg, "16.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "17.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "18.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "19.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "20.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "21.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "22.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "23.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "24.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "25.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "26.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "27.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "28.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "29.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "30.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "31.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "168.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "0.in-addr.arpa.") || - !add_as112_default(zones, cfg, "64.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "65.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "66.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "67.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "68.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "69.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "70.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "71.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "72.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "73.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "74.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "75.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "76.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "77.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "78.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "79.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "80.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "81.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "82.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "83.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "84.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "85.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "86.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "87.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "88.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "89.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "90.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "91.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "92.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "93.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "94.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "95.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "96.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "97.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "98.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "99.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "101.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "102.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "103.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "104.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "105.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "106.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "107.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "108.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "109.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "110.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "111.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "112.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "114.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "115.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "116.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "117.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "118.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "119.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "120.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "121.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "122.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "123.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "124.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "125.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "126.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "127.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "254.169.in-addr.arpa.") || - !add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") || - !add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") || - !add_as112_default(zones, cfg, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") || - !add_as112_default(zones, cfg, "d.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) { - log_err("out of memory adding default zone"); - return 0; + /* block AS112 zones, unless asked not to */ + if(!cfg->unblock_lan_zones) { + for(zstr = as112_zones; *zstr; zstr++) { + if(!add_as112_default(zones, cfg, *zstr)) { + log_err("out of memory adding default zone"); + return 0; + } + } } return 1; } diff --git a/util/as112.c b/util/as112.c new file mode 100644 index 000000000000..6ee69404656e --- /dev/null +++ b/util/as112.c @@ -0,0 +1,143 @@ +/* + * util/as112.c - list of local zones. + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file provides a list of lan zones. + */ + +#include "util/as112.h" + +static const char* as112_zone_array[] = { + "10.in-addr.arpa.", + "16.172.in-addr.arpa.", + "17.172.in-addr.arpa.", + "18.172.in-addr.arpa.", + "19.172.in-addr.arpa.", + "20.172.in-addr.arpa.", + "21.172.in-addr.arpa.", + "22.172.in-addr.arpa.", + "23.172.in-addr.arpa.", + "24.172.in-addr.arpa.", + "25.172.in-addr.arpa.", + "26.172.in-addr.arpa.", + "27.172.in-addr.arpa.", + "28.172.in-addr.arpa.", + "29.172.in-addr.arpa.", + "30.172.in-addr.arpa.", + "31.172.in-addr.arpa.", + "168.192.in-addr.arpa.", + "0.in-addr.arpa.", + "64.100.in-addr.arpa.", + "65.100.in-addr.arpa.", + "66.100.in-addr.arpa.", + "67.100.in-addr.arpa.", + "68.100.in-addr.arpa.", + "69.100.in-addr.arpa.", + "70.100.in-addr.arpa.", + "71.100.in-addr.arpa.", + "72.100.in-addr.arpa.", + "73.100.in-addr.arpa.", + "74.100.in-addr.arpa.", + "75.100.in-addr.arpa.", + "76.100.in-addr.arpa.", + "77.100.in-addr.arpa.", + "78.100.in-addr.arpa.", + "79.100.in-addr.arpa.", + "80.100.in-addr.arpa.", + "81.100.in-addr.arpa.", + "82.100.in-addr.arpa.", + "83.100.in-addr.arpa.", + "84.100.in-addr.arpa.", + "85.100.in-addr.arpa.", + "86.100.in-addr.arpa.", + "87.100.in-addr.arpa.", + "88.100.in-addr.arpa.", + "89.100.in-addr.arpa.", + "90.100.in-addr.arpa.", + "91.100.in-addr.arpa.", + "92.100.in-addr.arpa.", + "93.100.in-addr.arpa.", + "94.100.in-addr.arpa.", + "95.100.in-addr.arpa.", + "96.100.in-addr.arpa.", + "97.100.in-addr.arpa.", + "98.100.in-addr.arpa.", + "99.100.in-addr.arpa.", + "100.100.in-addr.arpa.", + "101.100.in-addr.arpa.", + "102.100.in-addr.arpa.", + "103.100.in-addr.arpa.", + "104.100.in-addr.arpa.", + "105.100.in-addr.arpa.", + "106.100.in-addr.arpa.", + "107.100.in-addr.arpa.", + "108.100.in-addr.arpa.", + "109.100.in-addr.arpa.", + "110.100.in-addr.arpa.", + "111.100.in-addr.arpa.", + "112.100.in-addr.arpa.", + "113.100.in-addr.arpa.", + "114.100.in-addr.arpa.", + "115.100.in-addr.arpa.", + "116.100.in-addr.arpa.", + "117.100.in-addr.arpa.", + "118.100.in-addr.arpa.", + "119.100.in-addr.arpa.", + "120.100.in-addr.arpa.", + "121.100.in-addr.arpa.", + "122.100.in-addr.arpa.", + "123.100.in-addr.arpa.", + "124.100.in-addr.arpa.", + "125.100.in-addr.arpa.", + "126.100.in-addr.arpa.", + "127.100.in-addr.arpa.", + "254.169.in-addr.arpa.", + "2.0.192.in-addr.arpa.", + "100.51.198.in-addr.arpa.", + "113.0.203.in-addr.arpa.", + "255.255.255.255.in-addr.arpa.", + "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", + "d.f.ip6.arpa.", + "8.e.f.ip6.arpa.", + "9.e.f.ip6.arpa.", + "a.e.f.ip6.arpa.", + "b.e.f.ip6.arpa.", + "8.b.d.0.1.0.0.2.ip6.arpa.", + 0 +}; + +const char** as112_zones = as112_zone_array; diff --git a/util/as112.h b/util/as112.h new file mode 100644 index 000000000000..7d0329e82b68 --- /dev/null +++ b/util/as112.h @@ -0,0 +1,57 @@ +/* + * util/as112.c - list of local zones. + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file provides a list of lan zones + */ + +#ifndef UTIL_AS112_H +#define UTIL_AS112_H + +/** + * Array of text-format domain names of the AS112 zones. + * The array ends with NULL. "AS112" is a service on the internet that + * that this array is named after. The names in this list (or some of them) + * are null-routed by this service to avoid load on central servers caused by + * mistaken lookups for local content on the global internet. + * + * This is the list of names that unbound should not normally be sending + * on towards the internet, because they are local-use. + */ +extern const char** as112_zones; + +#endif diff --git a/util/config_file.c b/util/config_file.c index cc7d99086b81..81005a481aa8 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -210,6 +210,7 @@ config_create(void) cfg->local_zones_nodefault = NULL; cfg->local_data = NULL; cfg->unblock_lan_zones = 0; + cfg->insecure_lan_zones = 0; cfg->python_script = NULL; cfg->remote_control_enable = 0; cfg->control_ifs = NULL; @@ -458,6 +459,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_YNO("rrset-roundrobin:", rrset_roundrobin) else S_STRLIST("local-data:", local_data) else S_YNO("unblock-lan-zones:", unblock_lan_zones) + else S_YNO("insecure-lan-zones:", insecure_lan_zones) else S_YNO("control-enable:", remote_control_enable) else S_STRLIST("control-interface:", control_ifs) else S_NUMBER_NONZERO("control-port:", control_port) @@ -739,6 +741,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "minimal-responses", minimal_responses) else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin) else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones) + else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) else O_STR(opt, "python-script", python_script) else O_DEC(opt, "ratelimit", ratelimit) diff --git a/util/config_file.h b/util/config_file.h index 8fa163ed7cc9..c758d647550e 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -285,8 +285,10 @@ struct config_file { struct config_strlist* local_zones_nodefault; /** local data RRs configured */ struct config_strlist* local_data; - /** unblock lan zones (reverse lookups for 10/8 and so on) */ + /** unblock lan zones (reverse lookups for AS112 zones) */ int unblock_lan_zones; + /** insecure lan zones (don't validate AS112 zones) */ + int insecure_lan_zones; /** remote control section. enable toggle. */ int remote_control_enable; diff --git a/util/configlexer.lex b/util/configlexer.lex index 6637943e4826..7354cc10e4ec 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -319,6 +319,7 @@ local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } unblock-lan-zones{COLON} { YDVAR(1, VAR_UNBLOCK_LAN_ZONES) } +insecure-lan-zones{COLON} { YDVAR(1, VAR_INSECURE_LAN_ZONES) } statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) } statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) } extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) } diff --git a/util/configparser.y b/util/configparser.y index abc0bb0d77f8..a276faea90d3 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -106,7 +106,8 @@ extern struct config_parser_state* cfg_parser; %token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN -%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES +%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE +%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES %token VAR_INFRA_CACHE_MIN_RTT %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL %token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH @@ -180,7 +181,8 @@ content_server: server_num_threads | server_verbosity | server_port | server_log_queries | server_tcp_upstream | server_ssl_upstream | server_ssl_service_key | server_ssl_service_pem | server_ssl_port | server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | - server_so_reuseport | server_delay_close | server_unblock_lan_zones | + server_so_reuseport | server_delay_close | + server_unblock_lan_zones | server_insecure_lan_zones | server_dns64_prefix | server_dns64_synthall | server_infra_cache_min_rtt | server_harden_algo_downgrade | server_ip_transparent | server_ratelimit | server_ratelimit_slabs | @@ -722,6 +724,16 @@ server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG free($2); } ; +server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG + { + OUTYY(("P(server_insecure_lan_zones:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->insecure_lan_zones = + (strcmp($2, "yes")==0); + free($2); + } + ; server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG { OUTYY(("P(server_rrset_cache_size:%s)\n", $2)); diff --git a/validator/val_anchor.c b/validator/val_anchor.c index 845b54a2e85e..bc9f8b8773f9 100644 --- a/validator/val_anchor.c +++ b/validator/val_anchor.c @@ -48,6 +48,7 @@ #include "util/log.h" #include "util/net_help.h" #include "util/config_file.h" +#include "util/as112.h" #include "sldns/sbuffer.h" #include "sldns/rrdef.h" #include "sldns/str2wire.h" @@ -1044,8 +1045,18 @@ int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) { struct config_strlist* f; + const char** zstr; char* nm; sldns_buffer* parsebuf = sldns_buffer_new(65535); + if(cfg->insecure_lan_zones) { + for(zstr = as112_zones; *zstr; zstr++) { + if(!anchor_insert_insecure(anchors, *zstr)) { + log_err("error in insecure-lan-zones: %s", *zstr); + sldns_buffer_free(parsebuf); + return 0; + } + } + } for(f = cfg->domain_insecure; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; From 7b036d779062bb637c8a3c4c7db2a109003b7a91 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Thu, 11 Feb 2016 17:32:41 +0000 Subject: [PATCH 074/142] nvme: avoid duplicate SET_NUM_QUEUES commands nvme(4) issues a SET_NUM_QUEUES command during device initialization to ensure enough I/O queues exists for each of the MSI-X vectors we have allocated. The SET_NUM_QUEUES command is then issued again during nvme_ctrlr_start(), to ensure that is properly set after any controller reset. At least one NVMe drive exists which fails this second SET_NUM_QUEUES command during device initialization. So change nvme_ctrlr_start() to only issue its SET_NUM_QUEUES command when it is coming out of a reset - avoiding the duplicate SET_NUM_QUEUES during device initialization. Reported by: gallatin MFC after: 3 days Sponsored by: Intel --- sys/dev/nvme/nvme_ctrlr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index e400f52d84c3..4c8adc02f409 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -725,15 +725,17 @@ nvme_ctrlr_start(void *ctrlr_arg) * explicit specify how many queues it will use. This value should * never change between resets, so panic if somehow that does happen. */ - old_num_io_queues = ctrlr->num_io_queues; - if (nvme_ctrlr_set_num_qpairs(ctrlr) != 0) { - nvme_ctrlr_fail(ctrlr); - return; - } + if (ctrlr->is_resetting) { + old_num_io_queues = ctrlr->num_io_queues; + if (nvme_ctrlr_set_num_qpairs(ctrlr) != 0) { + nvme_ctrlr_fail(ctrlr); + return; + } - if (old_num_io_queues != ctrlr->num_io_queues) { - panic("num_io_queues changed from %u to %u", old_num_io_queues, - ctrlr->num_io_queues); + if (old_num_io_queues != ctrlr->num_io_queues) { + panic("num_io_queues changed from %u to %u", + old_num_io_queues, ctrlr->num_io_queues); + } } if (nvme_ctrlr_create_qpairs(ctrlr) != 0) { From 8232a681f5bcf2f9aa6303687cf5cd89336b7399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 11 Feb 2016 17:33:55 +0000 Subject: [PATCH 075/142] Remove unbound-contrl-setup since we use a local control socket which does not require keys. MFC after: 3 days Relnotes: yes --- ObsoleteFiles.inc | 2 ++ tools/build/mk/OptionalObsoleteFiles.inc | 1 - usr.sbin/unbound/control/Makefile | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 2f2505ac15f0..a5a7e3c8f84b 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20160211: Remove obsolete unbound-control-setup +OLD_FILES+=usr/sbin/unbound-control-setup # 20160116: Update mandoc to cvs snapshot 20160116 OLD_FILES+=usr/share/mdocml/example.style.css OLD_FILES+=usr/share/mdocml/style.css diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 37f624efb952..87a40ba583c9 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -7970,7 +7970,6 @@ OLD_FILES+=usr/sbin/unbound OLD_FILES+=usr/sbin/unbound-anchor OLD_FILES+=usr/sbin/unbound-checkconf OLD_FILES+=usr/sbin/unbound-control -OLD_FILES+=usr/sbin/unbound-control-setup OLD_FILES+=usr/share/man/man5/unbound.conf.5.gz OLD_FILES+=usr/share/man/man8/unbound-anchor.8.gz OLD_FILES+=usr/share/man/man8/unbound-checkconf.8.gz diff --git a/usr.sbin/unbound/control/Makefile b/usr.sbin/unbound/control/Makefile index 16141277bae3..824e44111fc0 100644 --- a/usr.sbin/unbound/control/Makefile +++ b/usr.sbin/unbound/control/Makefile @@ -7,7 +7,6 @@ UNBOUNDDIR= ${.CURDIR}/../../../contrib/unbound .PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/smallapp ${UNBOUNDDIR}/doc PROG= unbound-control -SCRIPTS= unbound-control-setup.sh SRCS= unbound-control.c worker_cb.c CFLAGS= -I${UNBOUNDDIR} -I${LDNSDIR} LIBADD= unbound crypto ssl pthread From a982c4c7f5f7635683cb70577478397c38bef54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 11 Feb 2016 17:48:15 +0000 Subject: [PATCH 076/142] Fix double-free error: r289419 moved all error handling in http_connect() to the end of the function, but did not remove a fetch_close() call which was made redundant by the one in the shared error-handling code. PR: 206774 Submitted by: Christian Heckendorf MFC after: 3 days --- lib/libfetch/http.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 206648dd464b..ca522a6bcb8c 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -1435,7 +1435,6 @@ http_connect(struct url *URL, struct url *purl, const char *flags) } if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && fetch_ssl(conn, URL, verbose) == -1) { - fetch_close(conn); /* grrr */ errno = EAUTH; fetch_syserr(); From 77fc1120a72d2f25be8c0f17e61440a8aa58d3d2 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 11 Feb 2016 18:01:10 +0000 Subject: [PATCH 077/142] Enable ARM_INTRNG on all kernel configs where we use the Generic Interrupt Controller. Sponsored by: ABT Systems Ltd --- sys/arm/conf/ALPINE | 1 + sys/arm/conf/ARMADA38X | 1 + sys/arm/conf/EXYNOS5.common | 2 ++ sys/arm/conf/ODROIDC1 | 1 + sys/arm/conf/PANDABOARD | 4 ++-- sys/arm/conf/RK3188 | 2 ++ sys/arm/conf/SOCKIT.common | 2 ++ sys/arm/conf/VIRT | 2 ++ sys/arm/conf/VSATV102 | 1 + sys/arm/conf/VYBRID | 2 ++ sys/arm/conf/ZEDBOARD | 2 ++ 11 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sys/arm/conf/ALPINE b/sys/arm/conf/ALPINE index bf1c42dde070..fa3086542fe8 100644 --- a/sys/arm/conf/ALPINE +++ b/sys/arm/conf/ALPINE @@ -37,6 +37,7 @@ options DDB #Enable the kernel debugger # Interrupt controller device gic +options ARM_INTRNG # Pseudo devices device loop diff --git a/sys/arm/conf/ARMADA38X b/sys/arm/conf/ARMADA38X index 03fdf3052860..ede1b74e63c1 100644 --- a/sys/arm/conf/ARMADA38X +++ b/sys/arm/conf/ARMADA38X @@ -62,6 +62,7 @@ device pci # Interrupt controllers device gic +options ARM_INTRNG # Timers device mpcore_timer diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index c1fa16942325..770a69088666 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -87,6 +87,8 @@ device dwmmc # Interrupt controller device gic +options ARM_INTRNG + # ARM Generic Timer device generic_timer diff --git a/sys/arm/conf/ODROIDC1 b/sys/arm/conf/ODROIDC1 index 88836e3f6388..550da8702e27 100644 --- a/sys/arm/conf/ODROIDC1 +++ b/sys/arm/conf/ODROIDC1 @@ -26,6 +26,7 @@ options SMP # Enable multiple cores # Interrupt controller device gic +options ARM_INTRNG options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=odroidc1.dts diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD index 3177900a7832..4eaa471e35dc 100644 --- a/sys/arm/conf/PANDABOARD +++ b/sys/arm/conf/PANDABOARD @@ -30,8 +30,6 @@ hints "PANDABOARD.hints" include "std.armv6" include "../ti/omap4/pandaboard/std.pandaboard" -options ARM_INTRNG # new interrupt framework - options HZ=100 options SCHED_ULE # ULE scheduler options PLATFORM @@ -62,6 +60,8 @@ options DDB # Enable the kernel debugger device fdt_pinctrl # Interrupt controller device gic +options ARM_INTRNG + # ARM MPCore timer device mpcore_timer diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index 246a66adb6ab..49c8eae57aa5 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -47,6 +47,8 @@ options ROOTDEVNAME=\"ufs:/dev/mmcsd0\" # Interrupt controller device gic +options ARM_INTRNG + # ARM MPCore timer device mpcore_timer diff --git a/sys/arm/conf/SOCKIT.common b/sys/arm/conf/SOCKIT.common index 65be347e597b..3365929d9d68 100644 --- a/sys/arm/conf/SOCKIT.common +++ b/sys/arm/conf/SOCKIT.common @@ -53,6 +53,8 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require # Interrupt controller device gic +options ARM_INTRNG + # ARM MPCore timer device mpcore_timer diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT index aa70fd5d4062..ee652b2fb15b 100644 --- a/sys/arm/conf/VIRT +++ b/sys/arm/conf/VIRT @@ -46,6 +46,8 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require # Interrupt controller device gic +options ARM_INTRNG + # ARM Generic Timer device generic_timer diff --git a/sys/arm/conf/VSATV102 b/sys/arm/conf/VSATV102 index f845594c3d59..96e3ba4a703d 100644 --- a/sys/arm/conf/VSATV102 +++ b/sys/arm/conf/VSATV102 @@ -26,6 +26,7 @@ options SMP # Enable multiple cores # Interrupt controller device gic +options ARM_INTRNG options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=vsatv102-m6.dts diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID index 0aa38ce8624d..471b8d5bda6c 100644 --- a/sys/arm/conf/VYBRID +++ b/sys/arm/conf/VYBRID @@ -62,6 +62,8 @@ options NO_SWAPPING # Interrupt controller device gic +options ARM_INTRNG + # ARM MPCore timer device mpcore_timer diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index 7fca9372a58e..41ec23a82ef5 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -52,6 +52,8 @@ options ROOTDEVNAME=\"ufs:mmcsd0s2a\" # Interrupt controller device gic +options ARM_INTRNG + # Cache controller device pl310 # PL310 L2 cache controller # ARM MPCore timer From b028cf319ec4d4985b7f7736eb2e79ad5a639657 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 11 Feb 2016 18:35:46 +0000 Subject: [PATCH 078/142] Use 4 spaces instead of a tab. --- sys/netinet/sctp_sysctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index e19793679984..7e38b7847842 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -426,11 +426,11 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS) xinpcb.maxqlen = 0; } else { xinpcb.qlen = so->so_qlen; - xinpcb.qlen_old = so->so_qlen > USHRT_MAX ? - USHRT_MAX : (uint16_t) so->so_qlen; + xinpcb.qlen_old = so->so_qlen > USHRT_MAX ? + USHRT_MAX : (uint16_t) so->so_qlen; xinpcb.maxqlen = so->so_qlimit; - xinpcb.maxqlen_old = so->so_qlimit > USHRT_MAX ? - USHRT_MAX : (uint16_t) so->so_qlimit; + xinpcb.maxqlen_old = so->so_qlimit > USHRT_MAX ? + USHRT_MAX : (uint16_t) so->so_qlimit; } SCTP_INP_INCR_REF(inp); SCTP_INP_RUNLOCK(inp); From e0c45153ac96bb850e2da30ddb364c8ee4611582 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Thu, 11 Feb 2016 18:37:02 +0000 Subject: [PATCH 079/142] Add example VIMAGE config required by vnet jails --- share/examples/jails/README | 8 +++++ share/examples/jails/VIMAGE | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 share/examples/jails/VIMAGE diff --git a/share/examples/jails/README b/share/examples/jails/README index ccff12c649d3..36268a9c2997 100644 --- a/share/examples/jails/README +++ b/share/examples/jails/README @@ -1,5 +1,13 @@ # $FreeBSD$ +The below 4 samples require a VIMAGE enabled kernel: + + # (as root) + $ cp VIMAGE /usr/src/sys/amd64/conf/ + $ cd /usr/src + $ make KERNCONF=VIMAGE kernel + $ reboot + Sample 1: jail.conf(5) $ cp jib jng /usr/sbin/ diff --git a/share/examples/jails/VIMAGE b/share/examples/jails/VIMAGE new file mode 100644 index 000000000000..82edaa231f13 --- /dev/null +++ b/share/examples/jails/VIMAGE @@ -0,0 +1,59 @@ +# $FreeBSD$ + +################################################################################ +######################### VIMAGE KERNEL CONFIGURATION ########################## +################################################################################ + +#################### Inheritance + +# +# Inherit from, and override `GENERIC' +# +include GENERIC # Base configuration file +ident VIMAGE # Kernel name + +################################################################################ +##################### ENABLE NON-INHERITED OPTIONS/DEVICES ##################### +################################################################################ + +#################### Non-GENERIC options + +# +# Network Virtualization for Jails +# +options VIMAGE # vnet paravirtualization + +# +# Netgraph based bridging for vnet jails +# NB: Not strictly necessary; will load automatically via KLD when needed +# +options NETGRAPH # netgraph(4) system +options NETGRAPH_BRIDGE # ng_bridge(4) +options NETGRAPH_EIFACE # ng_eiface(4) +options NETGRAPH_ETHER # ng_ether(4) +options NETGRAPH_SOCKET # ng_socket(4) + +#################### Non-GENERIC devices + +# +# if_bridge based bridging for vnet jails +# NB: Not strictly necessary; will load automatically via KLD when needed +# +device epair # epair(4) +device if_bridge # if_bridge(4) + +################################################################################ +################ DISABLE UNNECESSARY INHERITED OPTIONS/DEVICES ################ +################################################################################ + +#################### Disable select inherited options + +# none + +#################### Disable select inherited devices + +# none + +################################################################################ +# END +################################################################################ From 7e4b7c797aedd8ca17aa921d235120eff101f787 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Thu, 11 Feb 2016 21:28:34 +0000 Subject: [PATCH 080/142] Centralize MAC derivation formula --- share/examples/jails/jib | 162 +++++++++++++++++++++------------------ share/examples/jails/jng | 157 ++++++++++++++++++++----------------- 2 files changed, 175 insertions(+), 144 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index a93d2f2ed22f..68a95627b71f 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -170,6 +170,91 @@ action_usage() exit $FAILURE } +derive_mac() +{ + local OPTIND=1 OPTARG __flag + local __mac_num= __make_pair= + while getopts 2n: __flag; do + case "$__flag" in + 2) __make_pair=1 ;; + n) __mac_num=${OPTARG%%[^0-9]*} ;; + esac + done + shift $(( $OPTIND - 1 )) + + if [ ! "$__mac_num" ]; then + eval __mac_num=\${_${iface}_num:--1} + __mac_num=$(( $__mac_num + 1 )) + eval _${iface}_num=\$__mac_num + fi + + local __iface="$1" __name="$2" __var_to_set="$3" __var_to_set_b="$4" + local __iface_devid __new_devid __num __new_devid_b + # + # Calculate MAC address derived from given iface. + # + # The formula I'm using is ``NP:SS:SS:II:II:II'' where: + # + N denotes 4 bits used as a counter to support branching + # each parent interface up to 15 times under the same jail + # name (see S below). + # + P denotes the special nibble whose value, if one of + # 2, 6, A, or E (but usually 2) denotes a privately + # administered MAC address (while remaining routable). + # + S denotes 16 bits, the sum(1) value of the jail name. + # + I denotes bits that are inherited from parent interface. + # + # The S bits are a CRC-16 checksum of NAME, allowing the jail + # to change link numbers in ng_bridge(4) without affecting the + # MAC address. Meanwhile, if... + # + the jail NAME changes (e.g., it was duplicated and given + # a new name with no other changes) + # + the underlying network interface changes + # + the jail is moved to another host + # the MAC address will be recalculated to a new, similarly + # unique value preventing conflict. + # + __iface_devid=$( ifconfig $__iface ether | awk '/ether/,$0=$2' ) + __new_devid=${__iface_devid#??:??:??} + # :II:II:II => S:II:II:II + __num=$( set -- `echo -n "$__name" | sum` && echo $1 ) + __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid + # S:II:II:II => :SS:II:II:II + __num=$(( $__num >> 4 )) + __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid + # :SS:II:II:II => S:SS:II:II:II + __num=$(( $__num >> 4 )) + __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid + # S:SS:II:II:II => :SS:SS:II:II:II + __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid + # :SS:SS:II:II:II => P:SS:SS:II:II:II + case "$__iface_devid" in + ?2:*) __new_devid=a$__new_devid __new_devid_b=e$__new_devid ;; + ?[Ee]:*) __new_devid=2$__new_devid __new_devid_b=6$__new_devid ;; + *) __new_devid=2$__new_devid __new_devid_b=e$__new_devid + esac + # P:SS:SS:II:II:II => NP:SS:SS:II:II:II + __new_devid=$( printf %x $(( $__mac_num & 15 )) )$__new_devid + __new_devid_b=$( printf %x $(( $__mac_num & 15 )) )$__new_devid_b + + # + # Return derivative MAC address(es) + # + if [ "$__make_pair" ]; then + if [ "$__var_to_set" -a "$__var_to_set_b" ]; then + eval $__var_to_set=\$__new_devid + eval $__var_to_set_b=\$__new_devid_b + else + echo $__new_devid $__new_devid_b + fi + else + if [ "$__var_to_set" ]; then + eval $__var_to_set=\$__new_devid + else + echo $__new_devid + fi + fi +} + mustberoot_to_continue() { if [ "$( id -u )" -ne 0 ]; then @@ -198,8 +283,7 @@ jib_addm() mustberoot_to_continue - local iface iface_devid eiface_devid - local eiface_devid_a eiface_devid_b + local iface eiface_devid_a eiface_devid_b local new num quad i=0 for iface in $*; do @@ -231,79 +315,7 @@ jib_addm() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - # The formula I'm using is ``NP:SS:SS:II:II:II'' where: - # + N denotes 4 bits used as a counter to support branching - # each parent interface up to 15 times under the same jail - # name (see S below). - # + P denotes the special nibble whose value, if one of - # 2, 6, A, or E (but usually 2) denotes a privately - # administered MAC address (while remaining routable). - # + S denotes 16 bits, the sum(1) value of the jail name. - # + I denotes bits that are inherited from parent interface. - # - # The S bits are a CRC-16 checksum of NAME, allowing the jail - # to change the epair(4) generation order without affecting the - # MAC address. Meanwhile, if... - # + the jail NAME changes (e.g., it was duplicated and given - # a new name with no other changes) - # + the underlying network interface changes - # + the jail is moved to another host - # the MAC address will be recalculated to a new, similarly - # unique value preventing conflict. - # - iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' ) - eiface_devid=${iface_devid#??:??:??} - num=$( set -- `echo -n $name | sum` && echo $1 ) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad:$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - case "$iface_devid" in - ?[Ee]:*) - eiface_devid_a=2:$quad$eiface_devid - eiface_devid_b=6:$quad$eiface_devid - ;; - *) - eiface_devid_a=2:$quad$eiface_devid - eiface_devid_b=e:$quad$eiface_devid - esac - eval num=\$_${iface}_num - if [ "$num" ]; then - num=$(( $num + 1 )) - eval _${iface}_num=$num - else - num=0 - local _${iface}_num=$num - fi - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid_a=$quad$eiface_devid_a - eiface_devid_b=$quad$eiface_devid_b + derive_mac -2 $iface "$name" eiface_devid_a eiface_devid_b ifconfig "e${i}a_$name" ether $eiface_devid_a > /dev/null 2>&1 ifconfig "e${i}b_$name" ether $eiface_devid_b > /dev/null 2>&1 diff --git a/share/examples/jails/jng b/share/examples/jails/jng index ee850ea5cadc..6c25539bdb58 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -172,6 +172,91 @@ action_usage() exit $FAILURE } +derive_mac() +{ + local OPTIND=1 OPTARG __flag + local __mac_num= __make_pair= + while getopts 2n: __flag; do + case "$__flag" in + 2) __make_pair=1 ;; + n) __mac_num=${OPTARG%%[^0-9]*} ;; + esac + done + shift $(( $OPTIND - 1 )) + + if [ ! "$__mac_num" ]; then + eval __mac_num=\${_${iface}_num:--1} + __mac_num=$(( $__mac_num + 1 )) + eval _${iface}_num=\$__mac_num + fi + + local __iface="$1" __name="$2" __var_to_set="$3" __var_to_set_b="$4" + local __iface_devid __new_devid __num __new_devid_b + # + # Calculate MAC address derived from given iface. + # + # The formula I'm using is ``NP:SS:SS:II:II:II'' where: + # + N denotes 4 bits used as a counter to support branching + # each parent interface up to 15 times under the same jail + # name (see S below). + # + P denotes the special nibble whose value, if one of + # 2, 6, A, or E (but usually 2) denotes a privately + # administered MAC address (while remaining routable). + # + S denotes 16 bits, the sum(1) value of the jail name. + # + I denotes bits that are inherited from parent interface. + # + # The S bits are a CRC-16 checksum of NAME, allowing the jail + # to change link numbers in ng_bridge(4) without affecting the + # MAC address. Meanwhile, if... + # + the jail NAME changes (e.g., it was duplicated and given + # a new name with no other changes) + # + the underlying network interface changes + # + the jail is moved to another host + # the MAC address will be recalculated to a new, similarly + # unique value preventing conflict. + # + __iface_devid=$( ifconfig $__iface ether | awk '/ether/,$0=$2' ) + __new_devid=${__iface_devid#??:??:??} + # :II:II:II => S:II:II:II + __num=$( set -- `echo -n "$__name" | sum` && echo $1 ) + __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid + # S:II:II:II => :SS:II:II:II + __num=$(( $__num >> 4 )) + __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid + # :SS:II:II:II => S:SS:II:II:II + __num=$(( $__num >> 4 )) + __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid + # S:SS:II:II:II => :SS:SS:II:II:II + __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid + # :SS:SS:II:II:II => P:SS:SS:II:II:II + case "$__iface_devid" in + ?2:*) __new_devid=a$__new_devid __new_devid_b=e$__new_devid ;; + ?[Ee]:*) __new_devid=2$__new_devid __new_devid_b=6$__new_devid ;; + *) __new_devid=2$__new_devid __new_devid_b=e$__new_devid + esac + # P:SS:SS:II:II:II => NP:SS:SS:II:II:II + __new_devid=$( printf %x $(( $__mac_num & 15 )) )$__new_devid + __new_devid_b=$( printf %x $(( $__mac_num & 15 )) )$__new_devid_b + + # + # Return derivative MAC address(es) + # + if [ "$__make_pair" ]; then + if [ "$__var_to_set" -a "$__var_to_set_b" ]; then + eval $__var_to_set=\$__new_devid + eval $__var_to_set_b=\$__new_devid_b + else + echo $__new_devid $__new_devid_b + fi + else + if [ "$__var_to_set" ]; then + eval $__var_to_set=\$__new_devid + else + echo $__new_devid + fi + fi +} + mustberoot_to_continue() { if [ "$( id -u )" -ne 0 ]; then @@ -201,7 +286,7 @@ jng_bridge() mustberoot_to_continue - local iface iface_devid eiface eiface_devid + local iface eiface eiface_devid local new num quad i=0 for iface in $*; do @@ -262,74 +347,8 @@ jng_bridge() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - # The formula I'm using is ``NP:SS:SS:II:II:II'' where: - # + N denotes 4 bits used as a counter to support branching - # each parent interface up to 15 times under the same jail - # name (see S below). - # + P denotes the special nibble whose value, if one of - # 2, 6, A, or E (but usually 2) denotes a privately - # administered MAC address (while remaining routable). - # + S denotes 16 bits, the sum(1) value of the jail name. - # + I denotes bits that are inherited from parent interface. - # - # The S bits are a CRC-16 checksum of NAME, allowing the jail - # to change link numbers in ng_bridge(4) without affecting the - # MAC address. Meanwhile, if... - # + the jail NAME changes (e.g., it was duplicated and given - # a new name with no other changes) - # + the underlying network interface changes - # + the jail is moved to another host - # the MAC address will be recalculated to a new, similarly - # unique value preventing conflict. - # - iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' ) - eiface_devid=${iface_devid#??:??:??} - num=$( set -- `echo -n $name | sum` && echo $1 ) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad:$eiface_devid - num=$(( $num >> 4 )) - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - case "$iface_devid" in - ?2:*) eiface_devid=a:$quad$eiface_devid ;; - *) eiface_devid=2:$quad$eiface_devid - esac - eval num=\$_${iface}_num - if [ "$num" ]; then - num=$(( $num + 1 )) - eval _${iface}_num=$num - else - num=0 - local _${iface}_num=$num - fi - quad=$(( $num & 15 )) - case "$quad" in - 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; - 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; - esac - eiface_devid=$quad$eiface_devid - ifconfig $eiface ether $eiface_devid > /dev/null 2>&1 + derive_mac $iface "$name" eiface_devid + ifconfig $eiface ether $eiface_devid i=$(( $i + 1 )) # on to next ng{i}_name done # for iface From 5e4bc63b7cfe2b39fc02a4d0c9105da286fdfdd4 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 11 Feb 2016 21:32:23 +0000 Subject: [PATCH 081/142] o Gather all mbuf(9) allocation functions into kern_mbuf.c, and all mbuf(9) manipulation functions into uipc_mbuf.c. This looks like the initial intent, but had diffused in the last decade. o Gather all declarations in mbuf.h in one place and sort them. o Uninline m_clget() and m_cljget(). There are no functional changes in this patch. The patch comes from a larger version, where all mbuf(9) allocation was uninlined, which allowed to make mbuf(9) UMA zones private to kern_mbuf.c. The performance impact of the total uninlining is still unclear, so we are holding on now with larger version. Together with: melifaro, olivier --- sys/kern/kern_mbuf.c | 341 ++++++++++++++++++++++++++++++++++++++++--- sys/kern/uipc_mbuf.c | 285 +++--------------------------------- sys/sys/mbuf.h | 128 ++++++---------- 3 files changed, 385 insertions(+), 369 deletions(-) diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 148b52f8b9df..1586c16ebd38 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -44,8 +44,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include @@ -284,7 +282,6 @@ static void mb_dtor_clust(void *, int, void *); static void mb_dtor_pack(void *, int, void *); static int mb_zinit_pack(void *, int, int); static void mb_zfini_pack(void *, int); - static void mb_reclaim(uma_zone_t, int); static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int); @@ -644,24 +641,6 @@ mb_ctor_pack(void *mem, int size, void *arg, int how) return (error); } -int -m_pkthdr_init(struct mbuf *m, int how) -{ -#ifdef MAC - int error; -#endif - m->m_data = m->m_pktdat; - bzero(&m->m_pkthdr, sizeof(m->m_pkthdr)); -#ifdef MAC - /* If the label init fails, fail the alloc */ - error = mac_mbuf_init(m, how); - if (error) - return (error); -#endif - - return (0); -} - /* * This is the protocol drain routine. Called by UMA whenever any of the * mbuf zones is closed to its limit. @@ -683,3 +662,323 @@ mb_reclaim(uma_zone_t zone __unused, int pending __unused) if (pr->pr_drain != NULL) (*pr->pr_drain)(); } + +/* + * Clean up after mbufs with M_EXT storage attached to them if the + * reference count hits 1. + */ +void +mb_free_ext(struct mbuf *m) +{ + int freembuf; + + KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); + + /* + * Check if the header is embedded in the cluster. + */ + freembuf = (m->m_flags & M_NOFREE) ? 0 : 1; + + switch (m->m_ext.ext_type) { + case EXT_SFBUF: + sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2); + break; + case EXT_SFBUF_NOCACHE: + sf_ext_free_nocache(m->m_ext.ext_arg1, m->m_ext.ext_arg2); + break; + default: + KASSERT(m->m_ext.ext_cnt != NULL, + ("%s: no refcounting pointer on %p", __func__, m)); + /* + * Free attached storage if this mbuf is the only + * reference to it. + */ + if (*(m->m_ext.ext_cnt) != 1) { + if (atomic_fetchadd_int(m->m_ext.ext_cnt, -1) != 1) + break; + } + + switch (m->m_ext.ext_type) { + case EXT_PACKET: /* The packet zone is special. */ + if (*(m->m_ext.ext_cnt) == 0) + *(m->m_ext.ext_cnt) = 1; + uma_zfree(zone_pack, m); + return; /* Job done. */ + case EXT_CLUSTER: + uma_zfree(zone_clust, m->m_ext.ext_buf); + break; + case EXT_JUMBOP: + uma_zfree(zone_jumbop, m->m_ext.ext_buf); + break; + case EXT_JUMBO9: + uma_zfree(zone_jumbo9, m->m_ext.ext_buf); + break; + case EXT_JUMBO16: + uma_zfree(zone_jumbo16, m->m_ext.ext_buf); + break; + case EXT_NET_DRV: + case EXT_MOD_TYPE: + case EXT_DISPOSABLE: + *(m->m_ext.ext_cnt) = 0; + uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *, + m->m_ext.ext_cnt)); + /* FALLTHROUGH */ + case EXT_EXTREF: + KASSERT(m->m_ext.ext_free != NULL, + ("%s: ext_free not set", __func__)); + (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, + m->m_ext.ext_arg2); + break; + default: + KASSERT(m->m_ext.ext_type == 0, + ("%s: unknown ext_type", __func__)); + } + } + + if (freembuf) + uma_zfree(zone_mbuf, m); +} + +/* + * Official mbuf(9) allocation KPI for stack and drivers: + * + * m_get() - a single mbuf without any attachments, sys/mbuf.h. + * m_gethdr() - a single mbuf initialized as M_PKTHDR, sys/mbuf.h. + * m_getcl() - an mbuf + 2k cluster, sys/mbuf.h. + * m_clget() - attach cluster to already allocated mbuf. + * m_cljget() - attach jumbo cluster to already allocated mbuf. + * m_get2() - allocate minimum mbuf that would fit size argument. + * m_getm2() - allocate a chain of mbufs/clusters. + * m_extadd() - attach external cluster to mbuf. + * + * m_free() - free single mbuf with its tags and ext, sys/mbuf.h. + * m_freem() - free chain of mbufs. + */ + +int +m_clget(struct mbuf *m, int how) +{ + + KASSERT((m->m_flags & M_EXT) == 0, ("%s: mbuf %p has M_EXT", + __func__, m)); + m->m_ext.ext_buf = (char *)NULL; + uma_zalloc_arg(zone_clust, m, how); + /* + * On a cluster allocation failure, drain the packet zone and retry, + * we might be able to loosen a few clusters up on the drain. + */ + if ((how & M_NOWAIT) && (m->m_ext.ext_buf == NULL)) { + zone_drain(zone_pack); + uma_zalloc_arg(zone_clust, m, how); + } + return (m->m_flags & M_EXT); +} + +/* + * m_cljget() is different from m_clget() as it can allocate clusters without + * attaching them to an mbuf. In that case the return value is the pointer + * to the cluster of the requested size. If an mbuf was specified, it gets + * the cluster attached to it and the return value can be safely ignored. + * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. + */ +void * +m_cljget(struct mbuf *m, int how, int size) +{ + uma_zone_t zone; + + if (m != NULL) { + KASSERT((m->m_flags & M_EXT) == 0, ("%s: mbuf %p has M_EXT", + __func__, m)); + m->m_ext.ext_buf = NULL; + } + + zone = m_getzone(size); + return (uma_zalloc_arg(zone, m, how)); +} + +/* + * m_get2() allocates minimum mbuf that would fit "size" argument. + */ +struct mbuf * +m_get2(int size, int how, short type, int flags) +{ + struct mb_args args; + struct mbuf *m, *n; + + args.flags = flags; + args.type = type; + + if (size <= MHLEN || (size <= MLEN && (flags & M_PKTHDR) == 0)) + return (uma_zalloc_arg(zone_mbuf, &args, how)); + if (size <= MCLBYTES) + return (uma_zalloc_arg(zone_pack, &args, how)); + + if (size > MJUMPAGESIZE) + return (NULL); + + m = uma_zalloc_arg(zone_mbuf, &args, how); + if (m == NULL) + return (NULL); + + n = uma_zalloc_arg(zone_jumbop, m, how); + if (n == NULL) { + uma_zfree(zone_mbuf, m); + return (NULL); + } + + return (m); +} + +/* + * m_getjcl() returns an mbuf with a cluster of the specified size attached. + * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. + */ +struct mbuf * +m_getjcl(int how, short type, int flags, int size) +{ + struct mb_args args; + struct mbuf *m, *n; + uma_zone_t zone; + + if (size == MCLBYTES) + return m_getcl(how, type, flags); + + args.flags = flags; + args.type = type; + + m = uma_zalloc_arg(zone_mbuf, &args, how); + if (m == NULL) + return (NULL); + + zone = m_getzone(size); + n = uma_zalloc_arg(zone, m, how); + if (n == NULL) { + uma_zfree(zone_mbuf, m); + return (NULL); + } + return (m); +} + +/* + * Allocate a given length worth of mbufs and/or clusters (whatever fits + * best) and return a pointer to the top of the allocated chain. If an + * existing mbuf chain is provided, then we will append the new chain + * to the existing one but still return the top of the newly allocated + * chain. + */ +struct mbuf * +m_getm2(struct mbuf *m, int len, int how, short type, int flags) +{ + struct mbuf *mb, *nm = NULL, *mtail = NULL; + + KASSERT(len >= 0, ("%s: len is < 0", __func__)); + + /* Validate flags. */ + flags &= (M_PKTHDR | M_EOR); + + /* Packet header mbuf must be first in chain. */ + if ((flags & M_PKTHDR) && m != NULL) + flags &= ~M_PKTHDR; + + /* Loop and append maximum sized mbufs to the chain tail. */ + while (len > 0) { + if (len > MCLBYTES) + mb = m_getjcl(how, type, (flags & M_PKTHDR), + MJUMPAGESIZE); + else if (len >= MINCLSIZE) + mb = m_getcl(how, type, (flags & M_PKTHDR)); + else if (flags & M_PKTHDR) + mb = m_gethdr(how, type); + else + mb = m_get(how, type); + + /* Fail the whole operation if one mbuf can't be allocated. */ + if (mb == NULL) { + if (nm != NULL) + m_freem(nm); + return (NULL); + } + + /* Book keeping. */ + len -= M_SIZE(mb); + if (mtail != NULL) + mtail->m_next = mb; + else + nm = mb; + mtail = mb; + flags &= ~M_PKTHDR; /* Only valid on the first mbuf. */ + } + if (flags & M_EOR) + mtail->m_flags |= M_EOR; /* Only valid on the last mbuf. */ + + /* If mbuf was supplied, append new chain to the end of it. */ + if (m != NULL) { + for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next) + ; + mtail->m_next = nm; + mtail->m_flags &= ~M_EOR; + } else + m = nm; + + return (m); +} + +/*- + * Configure a provided mbuf to refer to the provided external storage + * buffer and setup a reference count for said buffer. If the setting + * up of the reference count fails, the M_EXT bit will not be set. If + * successfull, the M_EXT bit is set in the mbuf's flags. + * + * Arguments: + * mb The existing mbuf to which to attach the provided buffer. + * buf The address of the provided external storage buffer. + * size The size of the provided buffer. + * freef A pointer to a routine that is responsible for freeing the + * provided external storage buffer. + * args A pointer to an argument structure (of any type) to be passed + * to the provided freef routine (may be NULL). + * flags Any other flags to be passed to the provided mbuf. + * type The type that the external storage buffer should be + * labeled with. + * + * Returns: + * Nothing. + */ +int +m_extadd(struct mbuf *mb, caddr_t buf, u_int size, + void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2, + int flags, int type, int wait) +{ + KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__)); + + if (type != EXT_EXTREF) + mb->m_ext.ext_cnt = uma_zalloc(zone_ext_refcnt, wait); + + if (mb->m_ext.ext_cnt == NULL) + return (ENOMEM); + + *(mb->m_ext.ext_cnt) = 1; + mb->m_flags |= (M_EXT | flags); + mb->m_ext.ext_buf = buf; + mb->m_data = mb->m_ext.ext_buf; + mb->m_ext.ext_size = size; + mb->m_ext.ext_free = freef; + mb->m_ext.ext_arg1 = arg1; + mb->m_ext.ext_arg2 = arg2; + mb->m_ext.ext_type = type; + mb->m_ext.ext_flags = 0; + + return (0); +} + +/* + * Free an entire chain of mbufs and associated external buffers, if + * applicable. + */ +void +m_freem(struct mbuf *mb) +{ + + while (mb != NULL) + mb = m_free(mb); +} diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 0b0b69725316..143aea7401fa 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + int max_linkhdr; int max_protohdr; int max_hdr; @@ -131,269 +133,6 @@ CTASSERT(sizeof(m_assertbuf.m_slistpkt) == sizeof(m_assertbuf.m_nextpkt)); CTASSERT(sizeof(m_assertbuf.m_stailqpkt) == sizeof(m_assertbuf.m_nextpkt)); #endif -/* - * m_get2() allocates minimum mbuf that would fit "size" argument. - */ -struct mbuf * -m_get2(int size, int how, short type, int flags) -{ - struct mb_args args; - struct mbuf *m, *n; - - args.flags = flags; - args.type = type; - - if (size <= MHLEN || (size <= MLEN && (flags & M_PKTHDR) == 0)) - return (uma_zalloc_arg(zone_mbuf, &args, how)); - if (size <= MCLBYTES) - return (uma_zalloc_arg(zone_pack, &args, how)); - - if (size > MJUMPAGESIZE) - return (NULL); - - m = uma_zalloc_arg(zone_mbuf, &args, how); - if (m == NULL) - return (NULL); - - n = uma_zalloc_arg(zone_jumbop, m, how); - if (n == NULL) { - uma_zfree(zone_mbuf, m); - return (NULL); - } - - return (m); -} - -/* - * m_getjcl() returns an mbuf with a cluster of the specified size attached. - * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. - */ -struct mbuf * -m_getjcl(int how, short type, int flags, int size) -{ - struct mb_args args; - struct mbuf *m, *n; - uma_zone_t zone; - - if (size == MCLBYTES) - return m_getcl(how, type, flags); - - args.flags = flags; - args.type = type; - - m = uma_zalloc_arg(zone_mbuf, &args, how); - if (m == NULL) - return (NULL); - - zone = m_getzone(size); - n = uma_zalloc_arg(zone, m, how); - if (n == NULL) { - uma_zfree(zone_mbuf, m); - return (NULL); - } - return (m); -} - -/* - * Allocate a given length worth of mbufs and/or clusters (whatever fits - * best) and return a pointer to the top of the allocated chain. If an - * existing mbuf chain is provided, then we will append the new chain - * to the existing one but still return the top of the newly allocated - * chain. - */ -struct mbuf * -m_getm2(struct mbuf *m, int len, int how, short type, int flags) -{ - struct mbuf *mb, *nm = NULL, *mtail = NULL; - - KASSERT(len >= 0, ("%s: len is < 0", __func__)); - - /* Validate flags. */ - flags &= (M_PKTHDR | M_EOR); - - /* Packet header mbuf must be first in chain. */ - if ((flags & M_PKTHDR) && m != NULL) - flags &= ~M_PKTHDR; - - /* Loop and append maximum sized mbufs to the chain tail. */ - while (len > 0) { - if (len > MCLBYTES) - mb = m_getjcl(how, type, (flags & M_PKTHDR), - MJUMPAGESIZE); - else if (len >= MINCLSIZE) - mb = m_getcl(how, type, (flags & M_PKTHDR)); - else if (flags & M_PKTHDR) - mb = m_gethdr(how, type); - else - mb = m_get(how, type); - - /* Fail the whole operation if one mbuf can't be allocated. */ - if (mb == NULL) { - if (nm != NULL) - m_freem(nm); - return (NULL); - } - - /* Book keeping. */ - len -= M_SIZE(mb); - if (mtail != NULL) - mtail->m_next = mb; - else - nm = mb; - mtail = mb; - flags &= ~M_PKTHDR; /* Only valid on the first mbuf. */ - } - if (flags & M_EOR) - mtail->m_flags |= M_EOR; /* Only valid on the last mbuf. */ - - /* If mbuf was supplied, append new chain to the end of it. */ - if (m != NULL) { - for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next) - ; - mtail->m_next = nm; - mtail->m_flags &= ~M_EOR; - } else - m = nm; - - return (m); -} - -/* - * Free an entire chain of mbufs and associated external buffers, if - * applicable. - */ -void -m_freem(struct mbuf *mb) -{ - - while (mb != NULL) - mb = m_free(mb); -} - -/*- - * Configure a provided mbuf to refer to the provided external storage - * buffer and setup a reference count for said buffer. If the setting - * up of the reference count fails, the M_EXT bit will not be set. If - * successfull, the M_EXT bit is set in the mbuf's flags. - * - * Arguments: - * mb The existing mbuf to which to attach the provided buffer. - * buf The address of the provided external storage buffer. - * size The size of the provided buffer. - * freef A pointer to a routine that is responsible for freeing the - * provided external storage buffer. - * args A pointer to an argument structure (of any type) to be passed - * to the provided freef routine (may be NULL). - * flags Any other flags to be passed to the provided mbuf. - * type The type that the external storage buffer should be - * labeled with. - * - * Returns: - * Nothing. - */ -int -m_extadd(struct mbuf *mb, caddr_t buf, u_int size, - void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2, - int flags, int type, int wait) -{ - KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__)); - - if (type != EXT_EXTREF) - mb->m_ext.ext_cnt = uma_zalloc(zone_ext_refcnt, wait); - - if (mb->m_ext.ext_cnt == NULL) - return (ENOMEM); - - *(mb->m_ext.ext_cnt) = 1; - mb->m_flags |= (M_EXT | flags); - mb->m_ext.ext_buf = buf; - mb->m_data = mb->m_ext.ext_buf; - mb->m_ext.ext_size = size; - mb->m_ext.ext_free = freef; - mb->m_ext.ext_arg1 = arg1; - mb->m_ext.ext_arg2 = arg2; - mb->m_ext.ext_type = type; - mb->m_ext.ext_flags = 0; - - return (0); -} - -/* - * Non-directly-exported function to clean up after mbufs with M_EXT - * storage attached to them if the reference count hits 1. - */ -void -mb_free_ext(struct mbuf *m) -{ - int freembuf; - - KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m)); - - /* - * Check if the header is embedded in the cluster. - */ - freembuf = (m->m_flags & M_NOFREE) ? 0 : 1; - - switch (m->m_ext.ext_type) { - case EXT_SFBUF: - sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2); - break; - case EXT_SFBUF_NOCACHE: - sf_ext_free_nocache(m->m_ext.ext_arg1, m->m_ext.ext_arg2); - break; - default: - KASSERT(m->m_ext.ext_cnt != NULL, - ("%s: no refcounting pointer on %p", __func__, m)); - /* - * Free attached storage if this mbuf is the only - * reference to it. - */ - if (*(m->m_ext.ext_cnt) != 1) { - if (atomic_fetchadd_int(m->m_ext.ext_cnt, -1) != 1) - break; - } - - switch (m->m_ext.ext_type) { - case EXT_PACKET: /* The packet zone is special. */ - if (*(m->m_ext.ext_cnt) == 0) - *(m->m_ext.ext_cnt) = 1; - uma_zfree(zone_pack, m); - return; /* Job done. */ - case EXT_CLUSTER: - uma_zfree(zone_clust, m->m_ext.ext_buf); - break; - case EXT_JUMBOP: - uma_zfree(zone_jumbop, m->m_ext.ext_buf); - break; - case EXT_JUMBO9: - uma_zfree(zone_jumbo9, m->m_ext.ext_buf); - break; - case EXT_JUMBO16: - uma_zfree(zone_jumbo16, m->m_ext.ext_buf); - break; - case EXT_NET_DRV: - case EXT_MOD_TYPE: - case EXT_DISPOSABLE: - *(m->m_ext.ext_cnt) = 0; - uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *, - m->m_ext.ext_cnt)); - /* FALLTHROUGH */ - case EXT_EXTREF: - KASSERT(m->m_ext.ext_free != NULL, - ("%s: ext_free not set", __func__)); - (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1, - m->m_ext.ext_arg2); - break; - default: - KASSERT(m->m_ext.ext_type == 0, - ("%s: unknown ext_type", __func__)); - } - } - - if (freembuf) - uma_zfree(zone_mbuf, m); -} - /* * Attach the cluster from *m to *n, set up m_ext in *n * and bump the refcount of the cluster. @@ -534,6 +273,26 @@ m_sanity(struct mbuf *m0, int sanitize) #undef M_SANITY_ACTION } +/* + * Non-inlined part of m_init(). + */ +int +m_pkthdr_init(struct mbuf *m, int how) +{ +#ifdef MAC + int error; +#endif + m->m_data = m->m_pktdat; + bzero(&m->m_pkthdr, sizeof(m->m_pkthdr)); +#ifdef MAC + /* If the label init fails, fail the alloc */ + error = mac_mbuf_init(m, how); + if (error) + return (error); +#endif + + return (0); +} /* * "Move" mbuf pkthdr from "from" to "to". diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 8d35f33b12f4..133dfaab3440 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -528,7 +528,50 @@ extern uma_zone_t zone_ext_refcnt; void mb_dupcl(struct mbuf *, const struct mbuf *); void mb_free_ext(struct mbuf *); +void m_adj(struct mbuf *, int); +int m_apply(struct mbuf *, int, int, + int (*)(void *, void *, u_int), void *); +int m_append(struct mbuf *, int, c_caddr_t); +void m_cat(struct mbuf *, struct mbuf *); +void m_catpkt(struct mbuf *, struct mbuf *); +int m_clget(struct mbuf *m, int how); +void *m_cljget(struct mbuf *m, int how, int size); +struct mbuf *m_collapse(struct mbuf *, int, int); +void m_copyback(struct mbuf *, int, int, c_caddr_t); +void m_copydata(const struct mbuf *, int, int, caddr_t); +struct mbuf *m_copym(const struct mbuf *, int, int, int); +struct mbuf *m_copypacket(struct mbuf *, int); +void m_copy_pkthdr(struct mbuf *, struct mbuf *); +struct mbuf *m_copyup(struct mbuf *, int, int); +struct mbuf *m_defrag(struct mbuf *, int); +void m_demote_pkthdr(struct mbuf *); +void m_demote(struct mbuf *, int, int); +struct mbuf *m_devget(char *, int, int, struct ifnet *, + void (*)(char *, caddr_t, u_int)); +struct mbuf *m_dup(const struct mbuf *, int); +int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); +int m_extadd(struct mbuf *, caddr_t, u_int, + void (*)(struct mbuf *, void *, void *), void *, void *, + int, int, int); +u_int m_fixhdr(struct mbuf *); +struct mbuf *m_fragment(struct mbuf *, int, int); +void m_freem(struct mbuf *); +struct mbuf *m_get2(int, int, short, int); +struct mbuf *m_getjcl(int, short, int, int); +struct mbuf *m_getm2(struct mbuf *, int, int, short, int); +struct mbuf *m_getptr(struct mbuf *, int, int *); +u_int m_length(struct mbuf *, struct mbuf **); +int m_mbuftouio(struct uio *, struct mbuf *, int); +void m_move_pkthdr(struct mbuf *, struct mbuf *); int m_pkthdr_init(struct mbuf *, int); +struct mbuf *m_prepend(struct mbuf *, int, int); +void m_print(const struct mbuf *, int); +struct mbuf *m_pulldown(struct mbuf *, int, int, int *); +struct mbuf *m_pullup(struct mbuf *, int); +int m_sanity(struct mbuf *, int); +struct mbuf *m_split(struct mbuf *, int, int); +struct mbuf *m_uiotombuf(struct uio *, int, int, int, int); +struct mbuf *m_unshare(struct mbuf *, int); static __inline int m_gettype(int size) @@ -666,47 +709,6 @@ m_getcl(int how, short type, int flags) return (uma_zalloc_arg(zone_pack, &args, how)); } -static __inline int -m_clget(struct mbuf *m, int how) -{ - - KASSERT((m->m_flags & M_EXT) == 0, ("%s: mbuf %p has M_EXT", - __func__, m)); - m->m_ext.ext_buf = (char *)NULL; - uma_zalloc_arg(zone_clust, m, how); - /* - * On a cluster allocation failure, drain the packet zone and retry, - * we might be able to loosen a few clusters up on the drain. - */ - if ((how & M_NOWAIT) && (m->m_ext.ext_buf == NULL)) { - zone_drain(zone_pack); - uma_zalloc_arg(zone_clust, m, how); - } - return (m->m_flags & M_EXT); -} - -/* - * m_cljget() is different from m_clget() as it can allocate clusters without - * attaching them to an mbuf. In that case the return value is the pointer - * to the cluster of the requested size. If an mbuf was specified, it gets - * the cluster attached to it and the return value can be safely ignored. - * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. - */ -static __inline void * -m_cljget(struct mbuf *m, int how, int size) -{ - uma_zone_t zone; - - if (m != NULL) { - KASSERT((m->m_flags & M_EXT) == 0, ("%s: mbuf %p has M_EXT", - __func__, m)); - m->m_ext.ext_buf = NULL; - } - - zone = m_getzone(size); - return (uma_zalloc_arg(zone, m, how)); -} - static __inline void m_cljset(struct mbuf *m, void *cl, int type) { @@ -924,50 +926,6 @@ extern int max_linkhdr; /* Largest link-level header */ extern int max_protohdr; /* Largest protocol header */ extern int nmbclusters; /* Maximum number of clusters */ -struct uio; - -void m_adj(struct mbuf *, int); -int m_apply(struct mbuf *, int, int, - int (*)(void *, void *, u_int), void *); -int m_append(struct mbuf *, int, c_caddr_t); -void m_cat(struct mbuf *, struct mbuf *); -void m_catpkt(struct mbuf *, struct mbuf *); -int m_extadd(struct mbuf *, caddr_t, u_int, - void (*)(struct mbuf *, void *, void *), void *, void *, - int, int, int); -struct mbuf *m_collapse(struct mbuf *, int, int); -void m_copyback(struct mbuf *, int, int, c_caddr_t); -void m_copydata(const struct mbuf *, int, int, caddr_t); -struct mbuf *m_copym(const struct mbuf *, int, int, int); -struct mbuf *m_copypacket(struct mbuf *, int); -void m_copy_pkthdr(struct mbuf *, struct mbuf *); -struct mbuf *m_copyup(struct mbuf *, int, int); -struct mbuf *m_defrag(struct mbuf *, int); -void m_demote_pkthdr(struct mbuf *); -void m_demote(struct mbuf *, int, int); -struct mbuf *m_devget(char *, int, int, struct ifnet *, - void (*)(char *, caddr_t, u_int)); -struct mbuf *m_dup(const struct mbuf *, int); -int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); -u_int m_fixhdr(struct mbuf *); -struct mbuf *m_fragment(struct mbuf *, int, int); -void m_freem(struct mbuf *); -struct mbuf *m_get2(int, int, short, int); -struct mbuf *m_getjcl(int, short, int, int); -struct mbuf *m_getm2(struct mbuf *, int, int, short, int); -struct mbuf *m_getptr(struct mbuf *, int, int *); -u_int m_length(struct mbuf *, struct mbuf **); -int m_mbuftouio(struct uio *, struct mbuf *, int); -void m_move_pkthdr(struct mbuf *, struct mbuf *); -struct mbuf *m_prepend(struct mbuf *, int, int); -void m_print(const struct mbuf *, int); -struct mbuf *m_pulldown(struct mbuf *, int, int, int *); -struct mbuf *m_pullup(struct mbuf *, int); -int m_sanity(struct mbuf *, int); -struct mbuf *m_split(struct mbuf *, int, int); -struct mbuf *m_uiotombuf(struct uio *, int, int, int, int); -struct mbuf *m_unshare(struct mbuf *, int); - /*- * Network packets may have annotations attached by affixing a list of * "packet tags" to the pkthdr structure. Packet tags are dynamically From b35d45aadfb15e67ae5ea06ca13d445bd0b66a7c Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Thu, 11 Feb 2016 22:10:54 +0000 Subject: [PATCH 082/142] Add support for bridging iwn(4) based wlan(4) Documented in iwn(4), "Only one virtual interface may be configured at any time." However, netgraph with a cloned MAC address is able to communicate over an ng_eiface attached to an ng_bridge linked to the wlan(4) interface. While here, introduce syntax to specify the MAC address is to be cloned if the named interface begins with equals [=]. --- share/examples/jails/jng | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 6c25539bdb58..2f134a4ecdf9 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -265,7 +265,7 @@ mustberoot_to_continue() fi } -jng_bridge_usage="bridge [-b BRIDGE_NAME] NAME interface0 [interface1 ...]" +jng_bridge_usage="bridge [-b BRIDGE_NAME] NAME [=]iface0 [[=]iface1 ...]" jng_bridge_descr="Create ng0_NAME [ng1_NAME ...]" jng_bridge() { @@ -286,10 +286,15 @@ jng_bridge() mustberoot_to_continue - local iface eiface eiface_devid - local new num quad i=0 + local iface parent eiface eiface_devid + local new clone_mac num quad i=0 for iface in $*; do + clone_mac= + case "$iface" in + =*) iface=${iface#=} clone_mac=1 ;; + esac + # 0. Make sure the interface doesn't exist already eiface=ng${i}_$name ngctl msg "$eiface:" getifname > /dev/null 2>&1 && continue @@ -347,7 +352,23 @@ jng_bridge() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - derive_mac $iface "$name" eiface_devid + case "$iface" in + wlan[0-9]*) + parent=$( sysctl -n net.wlan.${iface#wlan}.%parent ) + case "$parent" in + iwn[0-9]*) + # iwn(4) supports only 1 virtual net at a time + # NB: Cloning MAC allows new interface to work + clone_mac=1 ;; + esac + esac + if [ "$clone_mac" ]; then + eiface_devid=$( + ifconfig $iface ether | awk '/ether/,$0=$2' + ) + else + derive_mac $iface "$name" eiface_devid + fi ifconfig $eiface ether $eiface_devid i=$(( $i + 1 )) # on to next ng{i}_name From e51963a7bb99543a4da1b579f861ad89b38bde3c Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 11 Feb 2016 22:29:39 +0000 Subject: [PATCH 083/142] Loopback addresses are 127.0.0.0/8, not 127.0.0.1/32. MFC after: 1 week --- sys/netinet/sctp_constants.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index a26bc5b5c333..5837f6f5666a 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -978,10 +978,7 @@ __FBSDID("$FreeBSD$"); (((uint8_t *)&(a)->s_addr)[1] == 168))) #define IN4_ISLOOPBACK_ADDRESS(a) \ - ((((uint8_t *)&(a)->s_addr)[0] == 127) && \ - (((uint8_t *)&(a)->s_addr)[1] == 0) && \ - (((uint8_t *)&(a)->s_addr)[2] == 0) && \ - (((uint8_t *)&(a)->s_addr)[3] == 1)) + (((uint8_t *)&(a)->s_addr)[0] == 127) #define IN4_ISLINKLOCAL_ADDRESS(a) \ ((((uint8_t *)&(a)->s_addr)[0] == 169) && \ From 78954c3be39ae4d9aa0c9206bb6b245307740427 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Fri, 12 Feb 2016 01:12:44 +0000 Subject: [PATCH 084/142] Refactor conversion to hex --- share/examples/jails/jib | 20 +++++++------------- share/examples/jails/jng | 20 +++++++------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 68a95627b71f..3cf6184c7398 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -214,25 +214,19 @@ derive_mac() # unique value preventing conflict. # __iface_devid=$( ifconfig $__iface ether | awk '/ether/,$0=$2' ) - __new_devid=${__iface_devid#??:??:??} - # :II:II:II => S:II:II:II + # ??:??:??:II:II:II + __new_devid=${__iface_devid#??:??:??} # => :II:II:II + # => :SS:SS:II:II:II __num=$( set -- `echo -n "$__name" | sum` && echo $1 ) - __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid - # S:II:II:II => :SS:II:II:II - __num=$(( $__num >> 4 )) - __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid - # :SS:II:II:II => S:SS:II:II:II - __num=$(( $__num >> 4 )) - __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid - # S:SS:II:II:II => :SS:SS:II:II:II - __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid - # :SS:SS:II:II:II => P:SS:SS:II:II:II + __new_devid=$( printf :%02x:%02x \ + $(( $__num >> 8 & 255 )) $(( $__num & 255 )) )$__new_devid + # => P:SS:SS:II:II:II case "$__iface_devid" in ?2:*) __new_devid=a$__new_devid __new_devid_b=e$__new_devid ;; ?[Ee]:*) __new_devid=2$__new_devid __new_devid_b=6$__new_devid ;; *) __new_devid=2$__new_devid __new_devid_b=e$__new_devid esac - # P:SS:SS:II:II:II => NP:SS:SS:II:II:II + # => NP:SS:SS:II:II:II __new_devid=$( printf %x $(( $__mac_num & 15 )) )$__new_devid __new_devid_b=$( printf %x $(( $__mac_num & 15 )) )$__new_devid_b diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 2f134a4ecdf9..8208c15b96fd 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -216,25 +216,19 @@ derive_mac() # unique value preventing conflict. # __iface_devid=$( ifconfig $__iface ether | awk '/ether/,$0=$2' ) - __new_devid=${__iface_devid#??:??:??} - # :II:II:II => S:II:II:II + # ??:??:??:II:II:II + __new_devid=${__iface_devid#??:??:??} # => :II:II:II + # => :SS:SS:II:II:II __num=$( set -- `echo -n "$__name" | sum` && echo $1 ) - __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid - # S:II:II:II => :SS:II:II:II - __num=$(( $__num >> 4 )) - __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid - # :SS:II:II:II => S:SS:II:II:II - __num=$(( $__num >> 4 )) - __new_devid=$( printf %x $(( $__num & 15 )) )$__new_devid - # S:SS:II:II:II => :SS:SS:II:II:II - __new_devid=:$( printf %x $(( $__num & 15 )) )$__new_devid - # :SS:SS:II:II:II => P:SS:SS:II:II:II + __new_devid=$( printf :%02x:%02x \ + $(( $__num >> 8 & 255 )) $(( $__num & 255 )) )$__new_devid + # => P:SS:SS:II:II:II case "$__iface_devid" in ?2:*) __new_devid=a$__new_devid __new_devid_b=e$__new_devid ;; ?[Ee]:*) __new_devid=2$__new_devid __new_devid_b=6$__new_devid ;; *) __new_devid=2$__new_devid __new_devid_b=e$__new_devid esac - # P:SS:SS:II:II:II => NP:SS:SS:II:II:II + # => NP:SS:SS:II:II:II __new_devid=$( printf %x $(( $__mac_num & 15 )) )$__new_devid __new_devid_b=$( printf %x $(( $__mac_num & 15 )) )$__new_devid_b From 1ccea30f7171f46d479a245c6f63238f552aea34 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Fri, 12 Feb 2016 01:41:40 +0000 Subject: [PATCH 085/142] Add syntax to disable MAC allocation Adding `!' before an interface name will disable MAC allocation, falling back to driver mechanics. Alternatively adding `=' before an interface name causes the MAC address to be cloned (for ng_bridge(4) back-end only). While here, disable the auto-detection of wlan* since this knocks the host off; requiring the host that defines the jail to explicitly enable this feature by preceding the interface with `='. --- share/examples/jails/jib | 19 ++++++++++++++----- share/examples/jails/jng | 27 ++++++++++----------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 3cf6184c7398..934b5ed76b42 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -257,7 +257,7 @@ mustberoot_to_continue() fi } -jib_addm_usage="addm [-b BRIDGE_NAME] NAME interface0 [interface1 ...]" +jib_addm_usage="addm [-b BRIDGE_NAME] NAME [!]iface0 [[!]iface1 ...]" jib_addm_descr="Creates e0b_NAME [e1b_NAME ...]" jib_addm() { @@ -278,9 +278,14 @@ jib_addm() mustberoot_to_continue local iface eiface_devid_a eiface_devid_b - local new num quad i=0 + local new no_derive num quad i=0 for iface in $*; do + no_derive= + case "$iface" in + !*) iface=${iface#!} no_derive=1 ;; + esac + # 1. Make sure the interface doesn't exist already ifconfig "e${i}a_$name" > /dev/null 2>&1 && continue @@ -309,9 +314,13 @@ jib_addm() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - derive_mac -2 $iface "$name" eiface_devid_a eiface_devid_b - ifconfig "e${i}a_$name" ether $eiface_devid_a > /dev/null 2>&1 - ifconfig "e${i}b_$name" ether $eiface_devid_b > /dev/null 2>&1 + eiface_devid_a= eiface_devid_b= + [ "$no_derive" ] || derive_mac -2 $iface "$name" \ + eiface_devid_a eiface_devid_b + if [ "$eiface_devid_a" -a "$eiface_devid_b" ]; then + ifconfig "e${i}a_$name" ether $eiface_devid_a + ifconfig "e${i}b_$name" ether $eiface_devid_b + fi > /dev/null 2>&1 i=$(( $i + 1 )) # on to next e{i}b_name done # for iface diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 8208c15b96fd..9b905c620323 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -259,7 +259,7 @@ mustberoot_to_continue() fi } -jng_bridge_usage="bridge [-b BRIDGE_NAME] NAME [=]iface0 [[=]iface1 ...]" +jng_bridge_usage="bridge [-b BRIDGE_NAME] NAME [!|=]iface0 [[!|=]iface1 ...]" jng_bridge_descr="Create ng0_NAME [ng1_NAME ...]" jng_bridge() { @@ -281,12 +281,14 @@ jng_bridge() mustberoot_to_continue local iface parent eiface eiface_devid - local new clone_mac num quad i=0 + local new clone_mac no_derive num quad i=0 for iface in $*; do clone_mac= + no_derive= case "$iface" in =*) iface=${iface#=} clone_mac=1 ;; + !*) iface=${iface#!} no_derive=1 ;; esac # 0. Make sure the interface doesn't exist already @@ -346,24 +348,15 @@ jng_bridge() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - case "$iface" in - wlan[0-9]*) - parent=$( sysctl -n net.wlan.${iface#wlan}.%parent ) - case "$parent" in - iwn[0-9]*) - # iwn(4) supports only 1 virtual net at a time - # NB: Cloning MAC allows new interface to work - clone_mac=1 ;; - esac - esac + eiface_devid= if [ "$clone_mac" ]; then - eiface_devid=$( - ifconfig $iface ether | awk '/ether/,$0=$2' - ) - else + eiface_devid=$( ifconfig $iface ether | + awk '/ether/,$0=$2' ) + elif [ ! "$no_derive" ]; then derive_mac $iface "$name" eiface_devid fi - ifconfig $eiface ether $eiface_devid + [ "$eiface_devid" ] && + ifconfig $eiface ether $eiface_devid > /dev/null 2>&1 i=$(( $i + 1 )) # on to next ng{i}_name done # for iface From 4fa10b673c14c87e6e44f267a6469879f44f6f9d Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Fri, 12 Feb 2016 02:50:36 +0000 Subject: [PATCH 086/142] Interpret vnet_interface/vnet.interface as array --- etc/rc.d/jail | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/jail b/etc/rc.d/jail index 2d4898969e0f..f7d6d3d26de6 100755 --- a/etc/rc.d/jail +++ b/etc/rc.d/jail @@ -33,7 +33,8 @@ need_dad_wait= # set it to $param. If not defined, $defval is used. # When $num is [0-9]*, ${jail_$jv_$name$num} are looked up and # $param is set by using +=. $num=0 is optional (params may start at 1). -# When $num is YN or NY, the value is interpret as boolean. +# When $num is YN or NY, the value is interpreted as boolean. +# When $num is @, the value is interpreted as an array separted by IFS. extract_var() { local i _jv _name _param _num _def _name1 _name2 @@ -78,6 +79,20 @@ extract_var() i=$(($i + 1)) done ;; + @) + _name1=jail_${_jv}_${_name} + _name2=jail_${_name} + eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\" + set -- $_tmpargs + if [ $# -gt 0 ]; then + echo -n " $_param = " + while [ $# -gt 1 ]; do + echo -n "\"$1\", " + shift + done + echo "\"$1\";" + fi + ;; *) _name1=jail_${_jv}_${_name} _name2=jail_${_name} @@ -190,7 +205,7 @@ parse_options() allow.raw_sockets NY YES else echo " vnet;" - extract_var $_jv vnet_interface vnet.interface - "" + extract_var $_jv vnet_interface vnet.interface @ "" fi echo " exec.clean;" From 4b9a5d61f20e0a2430fe4e755620eb223d502d5e Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Fri, 12 Feb 2016 02:53:44 +0000 Subject: [PATCH 087/142] Comments and fix small bug Reduce differences between jib/jng and fix a bug that would prevent additional interfaces from being created if the first of many already existed (counter wasn't incremented before calling only continue). --- share/examples/jails/jib | 19 +++++++++++-------- share/examples/jails/jng | 23 +++++++++++++---------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 934b5ed76b42..acf64acbeef3 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -286,13 +286,16 @@ jib_addm() !*) iface=${iface#!} no_derive=1 ;; esac - # 1. Make sure the interface doesn't exist already - ifconfig "e${i}a_$name" > /dev/null 2>&1 && continue + # Make sure the interface doesn't exist already + if ifconfig "e${i}a_$name" > /dev/null 2>&1; then + i=$(( $i + 1 )) + continue + fi - # 2. Bring the interface up + # Bring the interface up ifconfig $iface up || return - # 3. Make sure the interface has been bridged + # Make sure the interface has been bridged if ! ifconfig "$iface$bridge" > /dev/null 2>&1; then new=$( ifconfig bridge create ) || return ifconfig $new addm $iface || return @@ -300,18 +303,18 @@ jib_addm() ifconfig "$iface$bridge" up || return fi - # 4. Create a new interface to the bridge + # Create a new interface to the bridge new=$( ifconfig epair create ) || return ifconfig "$iface$bridge" addm $new || return - # 5. Rename the new interface + # Rename the new interface ifconfig $new name "e${i}a_$name" || return ifconfig ${new%a}b name "e${i}b_$name" || return ifconfig "e${i}a_$name" up || return ifconfig "e${i}b_$name" up || return # - # 6. Set the MAC address of the new interface using a sensible + # Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # eiface_devid_a= eiface_devid_b= @@ -322,7 +325,7 @@ jib_addm() ifconfig "e${i}b_$name" ether $eiface_devid_b fi > /dev/null 2>&1 - i=$(( $i + 1 )) # on to next e{i}b_name + i=$(( $i + 1 )) done # for iface } diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 9b905c620323..f9af70c1805e 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -291,18 +291,21 @@ jng_bridge() !*) iface=${iface#!} no_derive=1 ;; esac - # 0. Make sure the interface doesn't exist already + # Make sure the interface doesn't exist already eiface=ng${i}_$name - ngctl msg "$eiface:" getifname > /dev/null 2>&1 && continue + if ngctl msg "$eiface:" getifname > /dev/null 2>&1; then + i=$(( $i + 1 )) + continue + fi - # 1. Bring the interface up + # Bring the interface up ifconfig $iface up || return - # 2. Set promiscuous mode and don't overwrite src addr + # Set promiscuous mode and don't overwrite src addr ngctl msg $iface: setpromisc 1 || return ngctl msg $iface: setautosrc 0 || return - # 3. Make sure the interface has been bridged + # Make sure the interface has been bridged if ! ngctl info ${iface}bridge: > /dev/null 2>&1; then ngctl mkpeer $iface: bridge lower link0 || return ngctl connect $iface: $iface:lower upper link1 || @@ -310,7 +313,7 @@ jng_bridge() ngctl name $iface:lower ${iface}bridge || return fi - # 3.5. Optionally create a secondary bridge + # Optionally create a secondary bridge if [ "$bridge" != "bridge" ] && ! ngctl info "$iface$bridge:" > /dev/null 2>&1 then @@ -326,7 +329,7 @@ jng_bridge() return fi - # 4. Create a new interface to the bridge + # Create a new interface to the bridge num=2 while ngctl msg "$iface$bridge:" getstats $num > /dev/null 2>&1 do @@ -334,7 +337,7 @@ jng_bridge() done ngctl mkpeer "$iface$bridge:" eiface link$num ether || return - # 5. Rename the new interface + # Rename the new interface while [ ${#eiface} -gt 15 ]; do # OS limitation eiface=${eiface%?} done @@ -345,7 +348,7 @@ jng_bridge() ifconfig $eiface up || return # - # 6. Set the MAC address of the new interface using a sensible + # Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # eiface_devid= @@ -358,7 +361,7 @@ jng_bridge() [ "$eiface_devid" ] && ifconfig $eiface ether $eiface_devid > /dev/null 2>&1 - i=$(( $i + 1 )) # on to next ng{i}_name + i=$(( $i + 1 )) done # for iface } From 3c7b90774d09d8d7c367e4144f7d57b9bfb87498 Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Fri, 12 Feb 2016 05:14:58 +0000 Subject: [PATCH 088/142] UART: Fix spurious interrupts generated by ns8250 and lpc drivers: - don't enable transmitter empty interrupt before filling TX FIFO. - add missing uart_barrier() call in interrupt service routine --- sys/dev/uart/uart_dev_lpc.c | 5 +++-- sys/dev/uart/uart_dev_ns8250.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/dev/uart/uart_dev_lpc.c b/sys/dev/uart/uart_dev_lpc.c index 6cd10f1ae48c..9a3e12b840fe 100644 --- a/sys/dev/uart/uart_dev_lpc.c +++ b/sys/dev/uart/uart_dev_lpc.c @@ -659,6 +659,7 @@ lpc_ns8250_bus_ipend(struct uart_softc *sc) if (iir & IIR_TXRDY) { ipend |= SER_INT_TXIDLE; uart_setreg(bas, REG_IER, lpc_ns8250->ier); + uart_barrier(bas); } else ipend |= SER_INT_SIGCHG; } @@ -892,12 +893,12 @@ lpc_ns8250_bus_transmit(struct uart_softc *sc) uart_lock(sc->sc_hwmtx); while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) ; - uart_setreg(bas, REG_IER, lpc_ns8250->ier | IER_ETXRDY); - uart_barrier(bas); for (i = 0; i < sc->sc_txdatasz; i++) { uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); uart_barrier(bas); } + uart_setreg(bas, REG_IER, lpc_ns8250->ier | IER_ETXRDY); + uart_barrier(bas); sc->sc_txbusy = 1; uart_unlock(sc->sc_hwmtx); return (0); diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index 3bba676c5dc6..9802294d3038 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -708,6 +708,7 @@ ns8250_bus_ipend(struct uart_softc *sc) if (iir & IIR_TXRDY) { ipend |= SER_INT_TXIDLE; uart_setreg(bas, REG_IER, ns8250->ier); + uart_barrier(bas); } else ipend |= SER_INT_SIGCHG; } @@ -979,12 +980,12 @@ ns8250_bus_transmit(struct uart_softc *sc) uart_lock(sc->sc_hwmtx); while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) ; - uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); - uart_barrier(bas); for (i = 0; i < sc->sc_txdatasz; i++) { uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); uart_barrier(bas); } + uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); + uart_barrier(bas); if (broken_txfifo) ns8250_drain(bas, UART_DRAIN_TRANSMITTER); else From 0c8cc7b0761f924e0389b2cfac7e7aca417e3be7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 12 Feb 2016 07:19:59 +0000 Subject: [PATCH 089/142] Remove tautological cast. PR: 207068 Submitted by: joss.upton@yahoo.com MFC after: 2 weeks --- sys/dev/hwpmc/hwpmc_mod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 3a1d52a08d54..4a5586c98ea0 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -1483,7 +1483,7 @@ pmc_process_csw_out(struct thread *td) * increasing monotonically, modulo a 64 * bit wraparound. */ - KASSERT((int64_t) tmp >= 0, + KASSERT(tmp >= 0, ("[pmc,%d] negative increment cpu=%d " "ri=%d newvalue=%jx saved=%jx " "incr=%jx", __LINE__, cpu, ri, From 70c1d5a32a1aac6fc6541fc4097cdc69b4dc4fc1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 12 Feb 2016 07:20:27 +0000 Subject: [PATCH 090/142] Adjust the size of PMC_DEFAULT_DEBUG_FLAGS to match the size of the structure. PR: 207068 Submitted by: joss.upton@yahoo.com MFC after: 2 weeks --- sys/sys/pmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 4561ec6c2298..e559b7649db9 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -1033,7 +1033,7 @@ extern struct pmc_debugflags pmc_debugflags; #define KTR_PMC KTR_SUBSYS #define PMC_DEBUG_STRSIZE 128 -#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0 } +#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0, 0 } #define PMCDBG0(M, N, L, F) do { \ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ From 411c83ccd691eec84686df54c5cc7ee3cdbeb265 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 12 Feb 2016 07:27:24 +0000 Subject: [PATCH 091/142] If full width writes to the performance monitoring counters are supported, use full-width aliases MSRs for writes. This fixes the "[pmc,X] negative increment" assertion on the context switch when clipped counter value is sign-extended. Add definitions for the MSR IA32_PERF_CAPABILITIES needed to detect the feature. PR: 207068 Submitted by: joss.upton@yahoo.com MFC after: 2 weeks --- sys/dev/hwpmc/hwpmc_core.c | 36 +++++++++++++++++++++++++----------- sys/dev/hwpmc/hwpmc_core.h | 9 +++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index d26c9655a78c..f092a21d374c 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -103,6 +103,7 @@ static int core_iaf_npmc; static int core_iap_width; static int core_iap_npmc; +static int core_iap_wroffset; static int core_pcpu_noop(struct pmc_mdep *md, int cpu) @@ -2473,7 +2474,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_t *v) *v = tmp & ((1ULL << core_iap_width) - 1); PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, - ri, *v); + IAP_PMC0 + ri, *v); return (0); } @@ -2605,19 +2606,20 @@ iap_write_pmc(int cpu, int ri, pmc_value_t v) ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, - IAP_PMC0 + ri, v); - if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = iap_reload_count_to_perfctr_value(v); + v &= (1ULL << core_iap_width) - 1; + + PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, + IAP_PMC0 + ri, v); + /* - * Write the new value to the counter. The counter will be in - * a stopped state when the pcd_write() entry point is called. + * Write the new value to the counter (or it's alias). The + * counter will be in a stopped state when the pcd_write() + * entry point is called. */ - - wrmsr(IAP_PMC0 + ri, v & ((1ULL << core_iap_width) - 1)); - + wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v); return (0); } @@ -2700,7 +2702,7 @@ core_intr(int cpu, struct trapframe *tf) */ msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK; wrmsr(IAP_EVSEL0 + ri, msr); - wrmsr(IAP_PMC0 + ri, v); + wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v); if (error) continue; @@ -2814,7 +2816,7 @@ core2_intr(int cpu, struct trapframe *tf) (uintmax_t) v); /* Reload sampling count. */ - wrmsr(IAP_PMC0 + n, v); + wrmsr(core_iap_wroffset + IAP_PMC0 + n, v); } /* @@ -2865,6 +2867,18 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override) return (EPROGMISMATCH); } + core_iap_wroffset = 0; + if (cpu_feature2 & CPUID2_PDCM) { + if (rdmsr(IA32_PERF_CAPABILITIES) & PERFCAP_FW_WRITE) { + PMCDBG0(MDP, INI, 1, + "core-init full-width write supported"); + core_iap_wroffset = IAP_A_PMC0 - IAP_PMC0; + } else + PMCDBG0(MDP, INI, 1, + "core-init full-width write NOT supported"); + } else + PMCDBG0(MDP, INI, 1, "core-init pdcm not supported"); + core_pmcmask = 0; /* diff --git a/sys/dev/hwpmc/hwpmc_core.h b/sys/dev/hwpmc/hwpmc_core.h index 63b6d02d32ed..7196d9dfb1fa 100644 --- a/sys/dev/hwpmc/hwpmc_core.h +++ b/sys/dev/hwpmc/hwpmc_core.h @@ -29,6 +29,14 @@ #ifndef _DEV_HWPMC_CORE_H_ #define _DEV_HWPMC_CORE_H_ 1 +#define IA32_PERF_CAPABILITIES 0x345 +#define PERFCAP_LBR_FORMAT 0x003f +#define PERFCAP_PEBS_TRAP 0x0040 +#define PERFCAP_PEBS_SAVEARCH 0x0080 +#define PERFCAP_PEBS_RECFORMAT 0x0f00 +#define PERFCAP_SMM_FREEZE 0x1000 +#define PERFCAP_FW_WRITE 0x2000 /* full width write aliases */ + /* * Fixed-function PMCs. */ @@ -101,6 +109,7 @@ struct pmc_md_iap_op_pmcallocate { */ #define IAP_PMC0 0x0C1 +#define IAP_A_PMC0 0x4C1 /* * IAP_EVSEL(n) is laid out in the following way. From 90edf67ecf94bce51e6c823ee2a10a7b65f416f8 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 12 Feb 2016 07:38:19 +0000 Subject: [PATCH 092/142] POSIX states that #include shall make both mcontext_t and ucontext_t available. Our code even has XXX comment about this. Add a bit of compliance by moving struct __ucontext definition into sys/_ucontext.h and including it into signal.h and sys/ucontext.h. Several machine/ucontext.h headers were changed to use namespace-safe types (like uint64_t->__uint64_t) to not depend on sys/types.h. struct __stack_t from sys/signal.h is made always visible in private namespace to satisfy sys/_ucontext.h requirements. Apparently mips _types.h pollutes global namespace with f_register_t type definition. This commit does not try to fix the issue. PR: 207079 Reported and tested by: Ting-Wei Lan Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- include/signal.h | 3 +- sys/mips/include/ucontext.h | 10 +++---- sys/powerpc/include/ucontext.h | 10 +++---- sys/sparc64/include/ucontext.h | 10 +++---- sys/sys/_ucontext.h | 52 ++++++++++++++++++++++++++++++++++ sys/sys/signal.h | 23 ++++++++------- sys/sys/ucontext.h | 18 +----------- sys/x86/include/ucontext.h | 5 ++++ 8 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 sys/sys/_ucontext.h diff --git a/include/signal.h b/include/signal.h index 895ccc30bc06..33be55c6dd25 100644 --- a/include/signal.h +++ b/include/signal.h @@ -36,6 +36,8 @@ #include #include #include +#include +#include #if __BSD_VISIBLE /* @@ -114,7 +116,6 @@ void psignal(unsigned int, const char *); #if __BSD_VISIBLE int sigblock(int); -struct __ucontext; /* XXX spec requires a complete declaration. */ int sigreturn(const struct __ucontext *); int sigsetmask(int); int sigstack(const struct sigstack *, struct sigstack *); diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h index a37fe7ec8d72..2b1a952e80f0 100644 --- a/sys/mips/include/ucontext.h +++ b/sys/mips/include/ucontext.h @@ -50,13 +50,13 @@ typedef struct __mcontext { * struct sigcontext and ucontext_t at the same time. */ int mc_onstack; /* sigstack state to restore */ - register_t mc_pc; /* pc at time of signal */ - register_t mc_regs[32]; /* processor regs 0 to 31 */ - register_t sr; /* status register */ - register_t mullo, mulhi; /* mullo and mulhi registers... */ + __register_t mc_pc; /* pc at time of signal */ + __register_t mc_regs[32]; /* processor regs 0 to 31 */ + __register_t sr; /* status register */ + __register_t mullo, mulhi; /* mullo and mulhi registers... */ int mc_fpused; /* fp has been used */ f_register_t mc_fpregs[33]; /* fp regs 0 to 31 and csr */ - register_t mc_fpc_eir; /* fp exception instruction reg */ + __register_t mc_fpc_eir; /* fp exception instruction reg */ void *mc_tls; /* pointer to TLS area */ int __spare__[8]; /* XXX reserved */ } mcontext_t; diff --git a/sys/powerpc/include/ucontext.h b/sys/powerpc/include/ucontext.h index 34e391a9e131..42c39e1d66c9 100644 --- a/sys/powerpc/include/ucontext.h +++ b/sys/powerpc/include/ucontext.h @@ -42,11 +42,11 @@ typedef struct __mcontext { #define _MC_AV_VALID 0x02 int mc_onstack; /* saved onstack flag */ int mc_len; /* sizeof(__mcontext) */ - uint64_t mc_avec[32*2]; /* vector register file */ - uint32_t mc_av[2]; - register_t mc_frame[42]; - uint64_t mc_fpreg[33]; - uint64_t mc_vsxfpreg[32]; /* low-order half of VSR0-31 */ + __uint64_t mc_avec[32*2]; /* vector register file */ + __uint32_t mc_av[2]; + __register_t mc_frame[42]; + __uint64_t mc_fpreg[33]; + __uint64_t mc_vsxfpreg[32]; /* low-order half of VSR0-31 */ } mcontext_t __aligned(16); #if defined(_KERNEL) && defined(__powerpc64__) diff --git a/sys/sparc64/include/ucontext.h b/sys/sparc64/include/ucontext.h index 1c907fef9e6d..42deca8303f9 100644 --- a/sys/sparc64/include/ucontext.h +++ b/sys/sparc64/include/ucontext.h @@ -33,11 +33,11 @@ #define _MACHINE_UCONTEXT_H_ struct __mcontext { - uint64_t mc_global[8]; - uint64_t mc_out[8]; - uint64_t mc_local[8]; - uint64_t mc_in[8]; - uint32_t mc_fp[64]; + __uint64_t mc_global[8]; + __uint64_t mc_out[8]; + __uint64_t mc_local[8]; + __uint64_t mc_in[8]; + __uint32_t mc_fp[64]; } __aligned(64); typedef struct __mcontext mcontext_t; diff --git a/sys/sys/_ucontext.h b/sys/sys/_ucontext.h new file mode 100644 index 000000000000..17b3179dc7a7 --- /dev/null +++ b/sys/sys/_ucontext.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1999 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS__UCONTEXT_H_ +#define _SYS__UCONTEXT_H_ + +typedef struct __ucontext { + /* + * Keep the order of the first two fields. Also, + * keep them the first two fields in the structure. + * This way we can have a union with struct + * sigcontext and ucontext_t. This allows us to + * support them both at the same time. + * note: the union is not defined, though. + */ + __sigset_t uc_sigmask; + mcontext_t uc_mcontext; + + struct __ucontext *uc_link; + struct __stack_t uc_stack; + int uc_flags; + int __spare__[4]; +} ucontext_t; + +#endif /* _SYS__UCONTEXT_H */ diff --git a/sys/sys/signal.h b/sys/sys/signal.h index 259c39aed4f9..ab8fcf48647a 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -354,18 +354,10 @@ typedef void __siginfohandler_t(int, struct __siginfo *, void *); #endif #if __XSI_VISIBLE -/* - * Structure used in sigaltstack call. - */ #if __BSD_VISIBLE -typedef struct sigaltstack { -#else -typedef struct { +#define __stack_t sigaltstack #endif - void *ss_sp; /* signal stack base */ - __size_t ss_size; /* signal stack length */ - int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ -} stack_t; +typedef struct __stack_t stack_t; #define SS_ONSTACK 0x0001 /* take signal on alternate stack */ #define SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ @@ -373,6 +365,17 @@ typedef struct { #define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */ #endif +/* + * Structure used in sigaltstack call. Its definition is always + * needed for __ucontext. If __BSD_VISIBLE is defined, the structure + * tag is actually sigaltstack. + */ +struct __stack_t { + void *ss_sp; /* signal stack base */ + __size_t ss_size; /* signal stack length */ + int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ +}; + #if __BSD_VISIBLE /* * 4.3 compatibility: diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h index e80ed503a364..260c15751d2d 100644 --- a/sys/sys/ucontext.h +++ b/sys/sys/ucontext.h @@ -33,25 +33,9 @@ #include #include +#include -typedef struct __ucontext { - /* - * Keep the order of the first two fields. Also, - * keep them the first two fields in the structure. - * This way we can have a union with struct - * sigcontext and ucontext_t. This allows us to - * support them both at the same time. - * note: the union is not defined, though. - */ - sigset_t uc_sigmask; - mcontext_t uc_mcontext; - - struct __ucontext *uc_link; - stack_t uc_stack; - int uc_flags; #define UCF_SWAPPED 0x00000001 /* Used by swapcontext(3). */ - int __spare__[4]; -} ucontext_t; #if defined(_KERNEL) && defined(COMPAT_FREEBSD4) #if defined(__i386__) diff --git a/sys/x86/include/ucontext.h b/sys/x86/include/ucontext.h index 2173efd590cf..c429fd5b0e3a 100644 --- a/sys/x86/include/ucontext.h +++ b/sys/x86/include/ucontext.h @@ -162,4 +162,9 @@ typedef struct __mcontext { } mcontext_t; #endif /* __amd64__ */ +#ifdef __LINT__ +typedef struct __mcontext { +} mcontext_t; +#endif /* __LINT__ */ + #endif /* !_X86_UCONTEXT_H_ */ From c85285a96b1a6de70557d2953267b927ebf3cc08 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 12 Feb 2016 10:58:13 +0000 Subject: [PATCH 093/142] Don't check CmdSN for initial login request. This fixes connection errors for some initiators not starting CmdSN from zero. While there, fix wrong status details reported for couple errors. MFC after: 3 days --- usr.sbin/ctld/login.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index 72c23cebcf64..3710dbc4fd6c 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -126,15 +126,16 @@ login_receive(struct connection *conn, bool initial) log_errx(1, "received Login PDU with unsupported " "Version-min 0x%x", bhslr->bhslr_version_min); } - if (ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { - login_send_error(request, 0x02, 0x05); + if (initial == false && + ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { + login_send_error(request, 0x02, 0x00); log_errx(1, "received Login PDU with decreasing CmdSN: " "was %u, is %u", conn->conn_cmdsn, ntohl(bhslr->bhslr_cmdsn)); } if (initial == false && ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) { - login_send_error(request, 0x02, 0x05); + login_send_error(request, 0x02, 0x00); log_errx(1, "received Login PDU with wrong ExpStatSN: " "is %u, should be %u", ntohl(bhslr->bhslr_expstatsn), conn->conn_statsn); From 770fd1c976d93312b58c2017cf51685ea8946b5a Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 12 Feb 2016 12:38:04 +0000 Subject: [PATCH 094/142] Only update curthread and curpcb after we have finished using the old values. If switching from a thread that used floating-point registers to a thread that is still running, but holding the blocked_lock lock we would switch the curthread to the new (running) thread, then call critical_enter. This will non-atomically increment td_critnest, and later call critical_exit to non-atomically decrement this value. This can happen at the same time as the new thread is still running on the old core, also calling these functions. In this case there will be a race between these non-atomic operations. This can be an issue as we could loose one of these operations leading to the value to not return to zero. If, later on, we then hit a data abort we check if the td_critnest is zero. If this check fails we will panic the kernel. This has been observed when running pcmstat on a Cavium ThunderX. The pcm thread will use the blocked_lock lock and there is a high chance userspace will use the floating-point registers. When, later on, pmcstat triggers a data abort we will hit this panic. The fix is to update these values after storing the floating-point state. This means we use the correct curthread while storing the state so it will not be an issue that the changes to td_critnest are non-atomic. Sponsored by: ABT Systems Ltd --- sys/arm64/arm64/swtch.S | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S index 3175e879114d..35153c2a046e 100644 --- a/sys/arm64/arm64/swtch.S +++ b/sys/arm64/arm64/swtch.S @@ -129,12 +129,6 @@ END(cpu_throw) * x3 to x7, x16 and x17 are caller saved */ ENTRY(cpu_switch) - /* Store the new curthread */ - str x1, [x18, #PC_CURTHREAD] - /* And the new pcb */ - ldr x4, [x1, #TD_PCB] - str x4, [x18, #PC_CURPCB] - /* * Save the old context. */ @@ -174,10 +168,14 @@ ENTRY(cpu_switch) mov x0, x19 #endif + /* Store the new curthread */ + str x1, [x18, #PC_CURTHREAD] + /* - * Restore the saved context. + * Restore the saved context and set it as curpcb. */ ldr x4, [x1, #TD_PCB] + str x4, [x18, #PC_CURPCB] /* * TODO: We may need to flush the cache here if switching From f3d389ee9e1e0bb9cd9942c79cec094a06ed0dc4 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Fri, 12 Feb 2016 14:29:14 +0000 Subject: [PATCH 095/142] Use __uint64_t type for floating point registers as compiler don't know about __uint128_t yet. Discussed with: theraven, kib --- sys/riscv/include/ucontext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/riscv/include/ucontext.h b/sys/riscv/include/ucontext.h index 4fbf346af4b1..20b593c493ee 100644 --- a/sys/riscv/include/ucontext.h +++ b/sys/riscv/include/ucontext.h @@ -50,7 +50,7 @@ struct gpregs { }; struct fpregs { - __uint128_t fp_x[32]; + __uint64_t fp_x[64] __aligned(16); __uint64_t fp_fcsr; int fp_flags; int pad; From 0c0a157c15f0c1662630eaf7187b3faf448b4bbd Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 12 Feb 2016 16:59:42 +0000 Subject: [PATCH 096/142] Clarify the difference between 7- and 8-bit i2c addresses, used in FDT versus hints-based configuration, respectively. Reported by: Jukka Ukkonen --- share/man/man4/ds3231.4 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/share/man/man4/ds3231.4 b/share/man/man4/ds3231.4 index 348860aaa6b8..17ef67fcf482 100644 --- a/share/man/man4/ds3231.4 +++ b/share/man/man4/ds3231.4 @@ -110,8 +110,11 @@ that the .Nm is connected to. .It Va hint.ds3231.%d.addr -The i2c address of +The 8-bit i2c address of .Nm . +The default 8-bit address for +.Nm +is 0xd0. .El .Pp On a @@ -121,11 +124,11 @@ based system the following properties must be set: .It Va compatible Must always be set to "maxim,ds3231". .It Va reg -The i2c address of +The 7-bit i2c address of .Nm . -The default address for +The default 7-bit address for .Nm -is 0xd0. +is 0x68. .El .Sh SEE ALSO .Xr fdt 4 , From 3c56cded4e19a864f637663598f898478273a9ca Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Fri, 12 Feb 2016 17:03:24 +0000 Subject: [PATCH 097/142] Update .Dd for r295565 --- share/man/man4/ds3231.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/ds3231.4 b/share/man/man4/ds3231.4 index 17ef67fcf482..6fdcccc26eb4 100644 --- a/share/man/man4/ds3231.4 +++ b/share/man/man4/ds3231.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 6, 2015 +.Dd February 12, 2016 .Dt DS3231 4 .Os .Sh NAME From ee211e02684cddb2de7d78ccb26042829cf48f4f Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 12 Feb 2016 17:04:03 +0000 Subject: [PATCH 098/142] Stop adding an extra null terminator to strings, OF_getprop already returns a null terminated string. --- sys/arm/mv/twsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/arm/mv/twsi.c b/sys/arm/mv/twsi.c index dfd024395786..bd9b137072d7 100644 --- a/sys/arm/mv/twsi.c +++ b/sys/arm/mv/twsi.c @@ -401,10 +401,9 @@ mv_twsi_attach(device_t dev) for (child = OF_child(ofw_bus_get_node(dev)); child != 0; child = OF_peer(child)) { len = OF_getproplen(child, "model"); - if (len <= 0 || len > sizeof(dname) - 1) + if (len <= 0 || len > sizeof(dname)) continue; error = OF_getprop(child, "model", &dname, len); - dname[len + 1] = '\0'; if (error == -1) continue; len = strlen(dname); @@ -428,10 +427,9 @@ mv_twsi_attach(device_t dev) /* Get device driver name. */ len = OF_getproplen(child, "model"); - if (len <= 0 || len > sizeof(dname) - 1) + if (len <= 0 || len > sizeof(dname)) continue; OF_getprop(child, "model", &dname, len); - dname[len + 1] = '\0'; if (bootverbose) device_printf(dev, "adding a device %s at %d.\n", From 02686fb806f111c69ec6856e734c0cc1c53d0894 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Fri, 12 Feb 2016 17:55:06 +0000 Subject: [PATCH 099/142] Document the new jail_reverse_stop parameter While here clean up the documentation for jail_list PR: 196152 Approved by: jamie, wblock MFC after: 1 week, with r295471 Differential Revision: https://reviews.freebsd.org/D5243 --- share/man/man5/rc.conf.5 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index c66edeba3cb9..9b1b68c29ef1 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 9, 2015 +.Dd February 12, 2016 .Dt RC.CONF 5 .Os .Sh NAME @@ -3853,20 +3853,22 @@ for every jail in .Va jail_list . .It Va jail_list .Pq Vt str -A space separated list of names for jails. -If this variable is empty, -all of +A space-delimited list of jail names. +When left empty, all of the .Xr jail 8 -instances in the configuration file will be configured. -This is purely a configuration aid to help identify and -configure multiple jails. -The names specified in this list will be used to -identify settings common to an instance of a jail, -and should contain alphanumeric characters only. -The literal jail name of -.Dq Li 0 -.Pq zero -is not allowed. +instances defined in the configuration file are started. +The names specified in this list control the jail startup order. +.Xr jail 8 +instances missing from +.Va jail_list +must be started manually. +.It Va jail_reverse_stop +.Pq Vt bool +When set to +.Dq Li YES , +all configured jails in +.Va jail_list +are stopped in reverse order. .It Va jail_* variables Note that older releases supported per-jail configuration via .Xr rc.conf 5 From 748d440809cc37eed158c5ee5485c27b45afdce3 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Fri, 12 Feb 2016 20:14:03 +0000 Subject: [PATCH 100/142] Remove duplicate definition (CPL_TRACE_PKT_T5). --- sys/dev/cxgbe/common/t4_msg.h | 1 - sys/dev/cxgbe/t4_main.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/dev/cxgbe/common/t4_msg.h b/sys/dev/cxgbe/common/t4_msg.h index c30b6f1f4871..2d8460492b2c 100644 --- a/sys/dev/cxgbe/common/t4_msg.h +++ b/sys/dev/cxgbe/common/t4_msg.h @@ -126,7 +126,6 @@ enum { CPL_RDMA_IMM_DATA_SE = 0xAD, CPL_TRACE_PKT = 0xB0, - CPL_TRACE_PKT_T5 = 0x48, CPL_RX2TX_DATA = 0xB1, CPL_ISCSI_DATA = 0xB2, CPL_FCOE_DATA = 0xB3, diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 21d0cb8c3ecf..a3d83bdca21e 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -708,7 +708,7 @@ t4_attach(device_t dev) sc->fw_msg_handler[i] = fw_msg_not_handled; t4_register_cpl_handler(sc, CPL_SET_TCB_RPL, t4_filter_rpl); t4_register_cpl_handler(sc, CPL_TRACE_PKT, t4_trace_pkt); - t4_register_cpl_handler(sc, CPL_TRACE_PKT_T5, t5_trace_pkt); + t4_register_cpl_handler(sc, CPL_T5_TRACE_PKT, t5_trace_pkt); t4_init_sge_cpl_handlers(sc); /* Prepare the adapter for operation */ From 785eb42adf81e2572d594dcba805fb44bcabeadd Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 20:43:53 +0000 Subject: [PATCH 101/142] Clear the cookie pointer on error in tmpfs_readdir(). It is otherwise left dangling, and callers that request cookies always free the cookie buffer, even when VOP_READDIR(9) returns an error. This results in a double free if tmpfs_readdir() returns an error to the NFS server or the Linux getdents(2) emulation code. Reported by: pho MFC after: 1 week Security: double free of malloc(9)-backed memory Sponsored by: EMC / Isilon Storage Division --- sys/fs/tmpfs/tmpfs_vnops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 9bdb1e90917c..bf42ffedad8f 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1191,8 +1191,11 @@ tmpfs_readdir(struct vop_readdir_args *v) if (error == EJUSTRETURN) error = (uio->uio_resid != startresid) ? 0 : EINVAL; - if (error != 0 && cookies != NULL) + if (error != 0 && cookies != NULL && ncookies != NULL) { free(*cookies, M_TEMP); + *cookies = NULL; + *ncookies = 0; + } if (eofflag != NULL) *eofflag = From 97dca6a2075e11e8d9ba291ddd814f0fba08d603 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 20:46:53 +0000 Subject: [PATCH 102/142] Remove some unreferenced NDP debug variable definitions. MFC after: 1 week --- sys/netinet6/nd6.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 4371a024a7c0..da48a87e4898 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -113,11 +113,6 @@ VNET_DEFINE(int, nd6_debug) = 0; static eventhandler_tag lle_event_eh, iflladdr_event_eh; -/* for debugging? */ -#if 0 -static int nd6_inuse, nd6_allocated; -#endif - VNET_DEFINE(struct nd_drhead, nd_defrouter); VNET_DEFINE(struct nd_prhead, nd_prefix); From fc31564185dbdb73d0852ed4545fa0831ecf09bc Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 20:52:53 +0000 Subject: [PATCH 103/142] Fix style around allocations from M_IP6NDP. - Don't cast the return value of malloc(9). - Use M_ZERO instead of explicitly calling bzero(9). MFC after: 1 week --- sys/netinet6/nd6.c | 2 +- sys/netinet6/nd6_rtr.c | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index da48a87e4898..3655b4576d8c 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -243,7 +243,7 @@ nd6_ifattach(struct ifnet *ifp) { struct nd_ifinfo *nd; - nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK|M_ZERO); + nd = malloc(sizeof(*nd), M_IP6NDP, M_WAITOK | M_ZERO); nd->initialized = 1; nd->chlim = IPV6_DEFHLIM; diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index ca649081368c..895a06d8951b 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -779,11 +779,10 @@ defrtrlist_update(struct nd_defrouter *new) if (new->rtlifetime == 0) return (NULL); - n = (struct nd_defrouter *)malloc(sizeof(*n), M_IP6NDP, M_NOWAIT); + n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO); if (n == NULL) return (NULL); - bzero(n, sizeof(*n)); - *n = *new; + memcpy(n, new, sizeof(*n)); insert: /* @@ -826,10 +825,9 @@ pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr) { struct nd_pfxrouter *new; - new = (struct nd_pfxrouter *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); + new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO); if (new == NULL) return; - bzero(new, sizeof(*new)); new->router = dr; LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry); @@ -869,10 +867,9 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr, int error = 0; char ip6buf[INET6_ADDRSTRLEN]; - new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); + new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO); if (new == NULL) - return(ENOMEM); - bzero(new, sizeof(*new)); + return (ENOMEM); new->ndpr_ifp = pr->ndpr_ifp; new->ndpr_prefix = pr->ndpr_prefix; new->ndpr_plen = pr->ndpr_plen; From baebd3e54f2d6973cb67f29229937b39e35b78d3 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 20:55:22 +0000 Subject: [PATCH 104/142] Remove superfluous return statements from the neighbour discovery code. MFC after: 1 week --- sys/netinet6/nd6.c | 1 - sys/netinet6/nd6_nbr.c | 2 -- sys/netinet6/nd6_rtr.c | 3 --- 3 files changed, 6 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 3655b4576d8c..e30ace5f41fb 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2512,7 +2512,6 @@ clear_llinfo_pqueue(struct llentry *ln) } ln->la_hold = NULL; - return; } static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 3a4e8a0ba02c..1cb220d5b8be 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -584,7 +584,6 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, bad: m_freem(m); - return; } #ifndef BURN_BRIDGES @@ -1078,7 +1077,6 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, bad: m_freem(m); - return; } #ifndef BURN_BRIDGES diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 895a06d8951b..d9af24c35507 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -503,7 +503,6 @@ defrouter_addreq(struct nd_defrouter *new) } if (error == 0) new->installed = 1; - return; } struct nd_defrouter * @@ -702,8 +701,6 @@ defrouter_select(void) defrouter_delreq(installed_dr); defrouter_addreq(selected_dr); } - - return; } /* From f60d595f3435f9fe738825b66da7215617c0854b Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 21:01:53 +0000 Subject: [PATCH 105/142] Remove a bogus comment from nd6_na_input(). The splnet() call that it refers to has been removed, and a lock for the default router list is in fact needed. MFC after: 1 week --- sys/netinet6/nd6_nbr.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 1cb220d5b8be..5369df998b8b 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -863,12 +863,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) in6 = &ln->r_l3addr.addr6; - /* - * Lock to protect the default router list. - * XXX: this might be unnecessary, since this function - * is only called under the network software interrupt - * context. However, we keep it just for safety. - */ nd6_ifp = lltable_get_ifp(ln->lle_tbl); dr = defrouter_lookup(in6, nd6_ifp); if (dr) From a4a7c8254c77304e3645de9320176e589de2bfc0 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 21:06:48 +0000 Subject: [PATCH 106/142] Simplify defrtrlist_update() slightly in preparation for future changes. No functional change intended. MFC after: 1 week --- sys/netinet6/nd6_rtr.c | 55 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index d9af24c35507..a51fa7d40e77 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -734,42 +734,37 @@ static struct nd_defrouter * defrtrlist_update(struct nd_defrouter *new) { struct nd_defrouter *dr, *n; + int oldpref; if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) { /* entry exists */ if (new->rtlifetime == 0) { defrtrlist_del(dr); - dr = NULL; - } else { - int oldpref = rtpref(dr); - - /* override */ - dr->flags = new->flags; /* xxx flag check */ - dr->rtlifetime = new->rtlifetime; - dr->expire = new->expire; - - /* - * If the preference does not change, there's no need - * to sort the entries. Also make sure the selected - * router is still installed in the kernel. - */ - if (dr->installed && rtpref(new) == oldpref) - return (dr); - - /* - * preferred router may be changed, so relocate - * this router. - * XXX: calling TAILQ_REMOVE directly is a bad manner. - * However, since defrtrlist_del() has many side - * effects, we intentionally do so here. - * defrouter_select() below will handle routing - * changes later. - */ - TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry); - n = dr; - goto insert; + return (NULL); } - return (dr); + + oldpref = rtpref(dr); + + /* override */ + dr->flags = new->flags; /* xxx flag check */ + dr->rtlifetime = new->rtlifetime; + dr->expire = new->expire; + + /* + * If the preference does not change, there's no need + * to sort the entries. Also make sure the selected + * router is still installed in the kernel. + */ + if (dr->installed && rtpref(new) == oldpref) + return (dr); + + /* + * The preferred router may have changed, so relocate this + * router. + */ + TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry); + n = dr; + goto insert; } /* entry does not exist */ From c1da297433fb59835d18e704982748c1404b2542 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 12 Feb 2016 21:12:47 +0000 Subject: [PATCH 107/142] Add libpe for elfcopy(1) PE/COFF support Sponsored by: The FreeBSD Foundation --- Makefile.inc1 | 2 ++ lib/Makefile | 2 ++ lib/libpe/Makefile | 34 ++++++++++++++++++++++++++++++++++ share/mk/src.libnames.mk | 4 ++++ 4 files changed, 42 insertions(+) create mode 100644 lib/libpe/Makefile diff --git a/Makefile.inc1 b/Makefile.inc1 index 173f70e526be..63d1b2f7a122 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1638,6 +1638,7 @@ _binutils= gnu/usr.bin/binutils .endif .if ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no" _elftctools= lib/libelftc \ + lib/libpe \ usr.bin/elfcopy \ usr.bin/nm \ usr.bin/size \ @@ -1650,6 +1651,7 @@ _elftctools+= usr.bin/addr2line # If cross-building with an external binutils we still need to build strip for # the target (for at least crunchide). _elftctools= lib/libelftc \ + lib/libpe \ usr.bin/elfcopy .endif diff --git a/lib/Makefile b/lib/Makefile index ccc6507ff56e..699aa6ac7c02 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -80,6 +80,7 @@ SUBDIR= ${SUBDIR_ORDERED} \ libopie \ libpam \ libpcap \ + ${_libpe} \ libpjdlog \ ${_libpmc} \ ${_libproc} \ @@ -184,6 +185,7 @@ _cuse= libcuse .if ${MK_TOOLCHAIN} != "no" _libelftc= libelftc +_libpe= libpe .endif .if ${MK_FILE} != "no" diff --git a/lib/libpe/Makefile b/lib/libpe/Makefile new file mode 100644 index 000000000000..877b331d1013 --- /dev/null +++ b/lib/libpe/Makefile @@ -0,0 +1,34 @@ +# $FreeBSD$ +.include + +INTERNALLIB= + +ELFTCDIR= ${.CURDIR}/../../contrib/elftoolchain + +.PATH: ${ELFTCDIR}/libpe + +LIB= pe + +SRCS= libpe_buffer.c \ + libpe_coff.c \ + libpe_dos.c \ + libpe_init.c \ + libpe_rich.c \ + libpe_section.c \ + libpe_utils.c \ + pe_buffer.c \ + pe_cntl.c \ + pe_coff.c \ + pe_dos.c \ + pe_flag.c \ + pe_init.c \ + pe_rich.c \ + pe_section.c \ + pe_symtab.c \ + pe_update.c + +CFLAGS+=-I${ELFTCDIR}/libpe -I${ELFTCDIR}/common + +MAN= + +.include diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 28c23680d2fb..d27597f6641b 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -39,6 +39,7 @@ _INTERNALLIBS= \ openbsd \ opts \ parse \ + pe \ readline \ sl \ sm \ @@ -367,6 +368,9 @@ LDADD+= ${LDADD_${_l}} LIBELFTCDIR= ${OBJTOP}/lib/libelftc LIBELFTC?= ${LIBELFTCDIR}/libelftc.a +LIBPEDIR= ${OBJTOP}/lib/libpe +LIBPE?= ${LIBPEDIR}/libpe.a + LIBREADLINEDIR= ${OBJTOP}/gnu/lib/libreadline/readline LIBREADLINE?= ${LIBREADLINEDIR}/libreadline.a From 715f438b424fbb600eb866df46eb2dfe12817ac2 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 12 Feb 2016 21:15:31 +0000 Subject: [PATCH 108/142] elfcopy: enable PE and EFI support Sponsored by: The FreeBSD Foundation --- usr.bin/elfcopy/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usr.bin/elfcopy/Makefile b/usr.bin/elfcopy/Makefile index dc6dd47be719..0800a0c4fc88 100644 --- a/usr.bin/elfcopy/Makefile +++ b/usr.bin/elfcopy/Makefile @@ -17,13 +17,14 @@ CLEANFILES+= objcopy.1 PROG= elfcopy .endif -SRCS= archive.c ascii.c binary.c main.c sections.c segments.c symbols.c +SRCS= archive.c ascii.c binary.c main.c pe.c sections.c segments.c symbols.c WARNS?= 5 -LIBADD= archive elftc elf +LIBADD= archive elftc elf pe -CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common +CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/libpe -I${ELFTCDIR}/common +CFLAGS+=-DWITH_PE=1 MAN= ${PROG}.1 strip.1 From 01869be58ef1cd137a761d691a09be167749de15 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 21:15:57 +0000 Subject: [PATCH 109/142] Rename the flags field of struct nd_defrouter to "raflags". This field contains the flags inherited from the corresponding router advertisement message and is not for storing private state. MFC after: 1 week --- sys/netinet6/nd6.c | 2 +- sys/netinet6/nd6.h | 8 ++++---- sys/netinet6/nd6_rtr.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index e30ace5f41fb..010b7cca6660 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2550,7 +2550,7 @@ nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS) error = sa6_recoverscope(&d.rtaddr); if (error != 0) return (error); - d.flags = dr->flags; + d.flags = dr->raflags; d.rtlifetime = dr->rtlifetime; d.expire = dr->expire + (time_second - time_uptime); d.if_index = dr->ifp->if_index; diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 6ff4cac2918d..a11ec511629d 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -232,13 +232,13 @@ struct in6_ndifreq { ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) TAILQ_HEAD(nd_drhead, nd_defrouter); -struct nd_defrouter { +struct nd_defrouter { TAILQ_ENTRY(nd_defrouter) dr_entry; - struct in6_addr rtaddr; - u_char flags; /* flags on RA message */ + struct in6_addr rtaddr; + u_char raflags; /* flags on RA message */ u_short rtlifetime; u_long expire; - struct ifnet *ifp; + struct ifnet *ifp; int installed; /* is installed into kernel routing table */ }; diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index a51fa7d40e77..5f29b6637817 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -272,7 +272,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) bzero(&dr0, sizeof(dr0)); dr0.rtaddr = saddr6; - dr0.flags = nd_ra->nd_ra_flags_reserved; + dr0.raflags = nd_ra->nd_ra_flags_reserved; /* * Effectively-disable routes from RA messages when * ND6_IFF_NO_RADR enabled on the receiving interface or @@ -710,7 +710,7 @@ defrouter_select(void) static int rtpref(struct nd_defrouter *dr) { - switch (dr->flags & ND_RA_FLAG_RTPREF_MASK) { + switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) { case ND_RA_FLAG_RTPREF_HIGH: return (RTPREF_HIGH); case ND_RA_FLAG_RTPREF_MEDIUM: @@ -724,7 +724,7 @@ rtpref(struct nd_defrouter *dr) * serious bug of kernel internal. We thus always bark here. * Or, can we even panic? */ - log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->flags); + log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags); return (RTPREF_INVALID); } /* NOTREACHED */ @@ -746,7 +746,7 @@ defrtrlist_update(struct nd_defrouter *new) oldpref = rtpref(dr); /* override */ - dr->flags = new->flags; /* xxx flag check */ + dr->raflags = new->raflags; /* XXX flag check */ dr->rtlifetime = new->rtlifetime; dr->expire = new->expire; From eb3ff358dc04c85c50fdbf7eca384a1a5dab3592 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 12 Feb 2016 21:17:00 +0000 Subject: [PATCH 110/142] Add a missing newline to a log message. MFC after: 1 week --- sys/netinet6/scope6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 1a9d03800a47..a00842e5085c 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -371,7 +371,7 @@ sa6_recoverscope(struct sockaddr_in6 *sin6) zoneid != sin6->sin6_scope_id) { log(LOG_NOTICE, "%s: embedded scope mismatch: %s%%%d. " - "sin6_scope_id was overridden.", __func__, + "sin6_scope_id was overridden\n", __func__, ip6_sprintf(ip6buf, &sin6->sin6_addr), sin6->sin6_scope_id); } From e296c1df6f815671606b63d7304d26e536a958f0 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Fri, 12 Feb 2016 22:46:14 +0000 Subject: [PATCH 111/142] cd9660: More "check for NULL" cleaunps. Cleanup some checks for NULL. Most of these were always unnecessary and starting with r294954 brelse() doesn't need any NULL checks at all. For now keep the checks somewhat consistent with NetBSD in case we want to merge the cleanups to older versions. --- sys/fs/cd9660/cd9660_vfsops.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 983b869d8b32..bf18094639ee 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -309,13 +309,13 @@ iso_mountfs(devvp, mp) default: break; } - if (bp) { + if (bp != NULL) { brelse(bp); bp = NULL; } } vd_end: - if (bp) { + if (bp != NULL) { brelse(bp); bp = NULL; } @@ -474,11 +474,11 @@ iso_mountfs(devvp, mp) return 0; out: - if (bp) + if (bp != NULL) brelse(bp); - if (pribp) + if (pribp != NULL) brelse(pribp); - if (supbp) + if (supbp != NULL) brelse(supbp); if (cp != NULL) { DROP_GIANT(); @@ -751,8 +751,7 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) #if 0 if (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) { - if (bp != 0) - brelse(bp); + brelse(bp); printf("fhtovp: file start miss %d vs %d\n", isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length), ifhp->ifid_start); @@ -770,7 +769,7 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) * read the `.' entry out of a dir. */ ip->iso_start = ino >> imp->im_bshift; - if (bp != 0) + if (bp != NULL) brelse(bp); if ((error = cd9660_blkatoff(vp, (off_t)0, NULL, &bp)) != 0) { vput(vp); @@ -809,8 +808,7 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) break; } - if (bp != 0) - brelse(bp); + brelse(bp); /* * Initialize the associated vnode From 3ce83dbfcfcf82c33d6e0e7e5950293d10573077 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Sat, 13 Feb 2016 00:28:48 +0000 Subject: [PATCH 112/142] Fix missing description for command usage While "jng" or "jib" without arguments told you what each sub-command does, sub-command usage didn't tell you (e.g., "jng bridge" or "jib addm" gave only usage and not description). --- share/examples/jails/jib | 4 +++- share/examples/jails/jng | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index acf64acbeef3..b7d50f5d4c90 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -164,9 +164,11 @@ usage() action_usage() { - local usage action="$1" + local usage descr action="$1" eval usage=\"\$jib_${action}_usage\" echo "Usage: $pgm $usage" >&2 + eval descr=\"\$jib_${action}_descr\" + printf "\t%s\n" "$descr" exit $FAILURE } diff --git a/share/examples/jails/jng b/share/examples/jails/jng index f9af70c1805e..c243001cf951 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -166,9 +166,11 @@ usage() action_usage() { - local usage action="$1" + local usage descr action="$1" eval usage=\"\$jng_${action}_usage\" echo "Usage: $pgm $usage" >&2 + eval descr=\"\$jng_${action}_descr\" + printf "\t%s\n" "$descr" exit $FAILURE } From 007a703036a4df3dfcdd0e6e5b8c0392298adb68 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sat, 13 Feb 2016 02:55:45 +0000 Subject: [PATCH 113/142] ioat(4): Recheck status register on zero-descriptor wakeups Errors that halt the channel don't necessarily result in a completion update, apparently. Sponsored by: EMC / Isilon Storage Division --- sys/dev/ioat/ioat.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 956e8d1463f4..3215c6f65c40 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -630,8 +630,14 @@ ioat_process_events(struct ioat_softc *ioat) CTR0(KTR_IOAT, __func__); - if (status == ioat->last_seen) + if (status == ioat->last_seen) { + /* + * If we landed in process_events and nothing has been + * completed, check for a timeout due to channel halt. + */ + comp_update = ioat_get_chansts(ioat); goto out; + } while (1) { desc = ioat_get_ring_entry(ioat, ioat->tail); @@ -661,8 +667,10 @@ ioat_process_events(struct ioat_softc *ioat) ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN); mtx_unlock(&ioat->cleanup_lock); - ioat_putn(ioat, completed, IOAT_ACTIVE_DESCR_REF); - wakeup(&ioat->tail); + if (completed != 0) { + ioat_putn(ioat, completed, IOAT_ACTIVE_DESCR_REF); + wakeup(&ioat->tail); + } if (!is_ioat_halted(comp_update)) return; From 2dd7d0560aad8e717f15329e1814f654fe10547c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 13 Feb 2016 17:23:55 +0000 Subject: [PATCH 114/142] Hide ucontext_t and mcontext_t when neither POSIX nor XSI features are enabled in the compilation environment, i.e. for ANSI C use of #include . Requested and reviewed by: bde Sponsored by: The FreeBSD Foundation MFC after: 13 days --- include/signal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/signal.h b/include/signal.h index 33be55c6dd25..217faddea03d 100644 --- a/include/signal.h +++ b/include/signal.h @@ -36,8 +36,10 @@ #include #include #include +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #include #include +#endif #if __BSD_VISIBLE /* From 564af7a65425dc066b5edbf9813a524466b678d7 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sat, 13 Feb 2016 19:01:56 +0000 Subject: [PATCH 115/142] ioat(4): Decode/define more capabilities, operations These are defined in the Intel Haswell EDS volume 2 (registers) (507849 v2.1). Sponsored by: EMC / Isilon Storage Division --- sys/dev/ioat/ioat_hw.h | 8 +++++++- sys/dev/ioat/ioat_internal.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/sys/dev/ioat/ioat_hw.h b/sys/dev/ioat/ioat_hw.h index 46ffaeb9408d..6dfe9a63d944 100644 --- a/sys/dev/ioat/ioat_hw.h +++ b/sys/dev/ioat/ioat_hw.h @@ -56,8 +56,13 @@ __FBSDID("$FreeBSD$"); #define IOAT_DMACAPABILITY_OFFSET 0x10 #define IOAT_DMACAP_PB (1 << 0) +#define IOAT_DMACAP_CRC (1 << 1) +#define IOAT_DMACAP_MARKER_SKIP (1 << 2) +#define IOAT_DMACAP_OLD_XOR (1 << 3) #define IOAT_DMACAP_DCA (1 << 4) +#define IOAT_DMACAP_MOVECRC (1 << 5) #define IOAT_DMACAP_BFILL (1 << 6) +#define IOAT_DMACAP_EXT_APIC (1 << 7) #define IOAT_DMACAP_XOR (1 << 8) #define IOAT_DMACAP_PQ (1 << 9) #define IOAT_DMACAP_DMA_DIF (1 << 10) @@ -69,7 +74,8 @@ __FBSDID("$FreeBSD$"); #define IOAT_DMACAP_STR \ "\20\24Completion_Timeout_Support\23DMA_with_Multicasting_Support" \ "\22RAID_Super_descriptors\16Descriptor_Write_Back_Error_Support" \ - "\13DMA_with_DIF\12PQ\11XOR\07Block_Fill\05DCA\01Page_Break" + "\13DMA_with_DIF\12PQ\11XOR\10Extended_APIC_ID\07Block_Fill\06Move_CRC" \ + "\05DCA\04Old_XOR\03Marker_Skipping\02CRC\01Page_Break" /* DMA Channel Registers */ #define IOAT_CHANCTRL_OFFSET 0x80 diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h index 1b248513368e..42201bde3dfa 100644 --- a/sys/dev/ioat/ioat_internal.h +++ b/sys/dev/ioat/ioat_internal.h @@ -346,6 +346,22 @@ struct ioat_descriptor { bus_addr_t hw_desc_bus_addr; }; +/* Unsupported by this driver at this time. */ +#define IOAT_OP_MOVECRC 0x41 +#define IOAT_OP_MOVECRC_TEST 0x42 +#define IOAT_OP_MOVECRC_STORE 0x43 +#define IOAT_OP_CRC 0x81 +#define IOAT_OP_CRC_TEST 0x82 +#define IOAT_OP_CRC_STORE 0x83 +#define IOAT_OP_MARKER 0x84 + +/* + * Deprecated OPs -- v3 DMA generates an abort if given these. And this driver + * doesn't support anything older than v3. + */ +#define IOAT_OP_OLD_XOR 0x85 +#define IOAT_OP_OLD_XOR_VAL 0x86 + enum ioat_ref_kind { IOAT_DMAENGINE_REF = 0, IOAT_ACTIVE_DESCR_REF, From d2c55e5ad032e6063025a7c88f35680858f5c6ad Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sat, 13 Feb 2016 22:51:17 +0000 Subject: [PATCH 116/142] ioat(4): Also check for errors if the channel is suspended Sponsored by: EMC / Isilon Storage Division --- sys/dev/ioat/ioat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 3215c6f65c40..74de8baec646 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -672,7 +672,7 @@ ioat_process_events(struct ioat_softc *ioat) wakeup(&ioat->tail); } - if (!is_ioat_halted(comp_update)) + if (!is_ioat_halted(comp_update) && !is_ioat_suspended(comp_update)) return; ioat->stats.channel_halts++; From 374b05e1fff5071d5d630e94fa4b69c0488e3fde Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sat, 13 Feb 2016 22:51:25 +0000 Subject: [PATCH 117/142] ioat(4): On error detected in ithread, defer HW reset to taskqueue The I/OAT HW reset process may sleep, so it is invalid to perform a channel reset from the software interrupt thread. Sponsored by: EMC / Isilon Storage Division --- sys/dev/ioat/ioat.c | 19 +++++++++++++++++++ sys/dev/ioat/ioat_internal.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 74de8baec646..bcc4e9a46587 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -92,6 +93,7 @@ static void ioat_submit_single(struct ioat_softc *ioat); static void ioat_comp_update_map(void *arg, bus_dma_segment_t *seg, int nseg, int error); static int ioat_reset_hw(struct ioat_softc *ioat); +static void ioat_reset_hw_task(void *, int); static void ioat_setup_sysctl(device_t device); static int sysctl_handle_reset(SYSCTL_HANDLER_ARGS); static inline struct ioat_softc *ioat_get(struct ioat_softc *, @@ -308,6 +310,7 @@ ioat_detach(device_t device) ioat = DEVICE2SOFTC(device); ioat_test_detach(); + taskqueue_drain(taskqueue_thread, &ioat->reset_task); mtx_lock(IOAT_REFLK); ioat->quiescing = TRUE; @@ -414,6 +417,7 @@ ioat3_attach(device_t device) mtx_init(&ioat->submit_lock, "ioat_submit", NULL, MTX_DEF); mtx_init(&ioat->cleanup_lock, "ioat_cleanup", NULL, MTX_DEF); callout_init(&ioat->timer, 1); + TASK_INIT(&ioat->reset_task, 0, ioat_reset_hw_task, ioat); /* Establish lock order for Witness */ mtx_lock(&ioat->submit_lock); @@ -712,8 +716,23 @@ ioat_process_events(struct ioat_softc *ioat) mtx_unlock(&ioat->submit_lock); ioat_log_message(0, "Resetting channel to recover from error\n"); + error = taskqueue_enqueue(taskqueue_thread, &ioat->reset_task); + KASSERT(error == 0, + ("%s: taskqueue_enqueue failed: %d", __func__, error)); +} + +static void +ioat_reset_hw_task(void *ctx, int pending __unused) +{ + struct ioat_softc *ioat; + int error; + + ioat = ctx; + ioat_log_message(1, "%s: Resetting channel\n", __func__); + error = ioat_reset_hw(ioat); KASSERT(error == 0, ("%s: reset failed: %d", __func__, error)); + (void)error; } /* diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h index 42201bde3dfa..b33faea05fa5 100644 --- a/sys/dev/ioat/ioat_internal.h +++ b/sys/dev/ioat/ioat_internal.h @@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$"); #ifndef __IOAT_INTERNAL_H__ #define __IOAT_INTERNAL_H__ +#include + #define DEVICE2SOFTC(dev) ((struct ioat_softc *) device_get_softc(dev)) #define KTR_IOAT KTR_SPARE3 @@ -405,6 +407,7 @@ struct ioat_softc { bus_addr_t comp_update_bus_addr; struct callout timer; + struct task reset_task; boolean_t quiescing; boolean_t is_resize_pending; From ffc6b639c2ae1214cc8042c8372dd78be8aa0e03 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sun, 14 Feb 2016 02:28:59 +0000 Subject: [PATCH 118/142] hyperv/hn: Fix typo in comment Noticed by: avos Reviewed by: adrian, avos, Hongjiang Zhang Approved by: adrian MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5199 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index be43bf413302..b2a207905226 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -787,7 +787,7 @@ netvsc_channel_rollup(struct hv_device *device_ctx) /* * NOTE: - * This this function fails, then both txd and m_head0 will be freed + * If this function fails, then both txd and m_head0 will be freed. */ static int hn_encap(struct hn_softc *sc, struct hn_txdesc *txd, struct mbuf **m_head0) From fe3e4523996e3d2aa19eb57b5de30467411e6005 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sun, 14 Feb 2016 07:16:36 +0000 Subject: [PATCH 119/142] Reduce the number of supported WLAN keys in the rum driver, else we risk bit shifting overflows. Found by D5245 / PVS. MFC after: 1 week --- sys/dev/usb/wlan/if_rum.c | 6 +++--- sys/dev/usb/wlan/if_rumreg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 3fada69ec189..e428a8f500d1 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -2732,7 +2732,7 @@ rum_pair_key_del_cb(struct rum_softc *sc, union sec_param *data, DPRINTF("%s: removing key %d\n", __func__, k->wk_keyix); rum_clrbits(sc, (k->wk_keyix < 32) ? RT2573_SEC_CSR2 : RT2573_SEC_CSR3, 1 << (k->wk_keyix % 32)); - sc->keys_bmap &= ~(1 << k->wk_keyix); + sc->keys_bmap &= ~(1ULL << k->wk_keyix); if (--sc->vap_key_count[rvp_id] == 0) rum_clrbits(sc, RT2573_SEC_CSR4, 1 << rvp_id); } @@ -2749,8 +2749,8 @@ rum_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) { RUM_LOCK(sc); for (i = 0; i < RT2573_ADDR_MAX; i++) { - if ((sc->keys_bmap & (1 << i)) == 0) { - sc->keys_bmap |= 1 << i; + if ((sc->keys_bmap & (1ULL << i)) == 0) { + sc->keys_bmap |= (1ULL << i); *keyix = i; break; } diff --git a/sys/dev/usb/wlan/if_rumreg.h b/sys/dev/usb/wlan/if_rumreg.h index c673fd7975e6..f1f1195798bc 100644 --- a/sys/dev/usb/wlan/if_rumreg.h +++ b/sys/dev/usb/wlan/if_rumreg.h @@ -47,7 +47,7 @@ * H/w encryption/decryption support */ #define KEY_SIZE (IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE) -#define RT2573_ADDR_MAX 64 +#define RT2573_ADDR_MAX (32 / RT2573_SKEY_MAX) #define RT2573_SKEY_MAX 4 #define RT2573_SKEY(vap, kidx) (0x1000 + ((vap) * RT2573_SKEY_MAX + \ From 8cb15594b3041324e82a47d109a56d43e0d8ea1a Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sun, 14 Feb 2016 07:20:07 +0000 Subject: [PATCH 120/142] Fix variable assignment inside if-clause in the smsc driver. Found by D5245 / PVS. MFC after: 1 week --- sys/dev/usb/net/if_smsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index 19c46152eac5..e90e753b1391 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -1362,7 +1362,7 @@ smsc_chip_init(struct smsc_softc *sc) /* Reset the PHY */ smsc_write_reg(sc, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST); - if ((err = smsc_wait_for_bits(sc, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST) != 0)) { + if ((err = smsc_wait_for_bits(sc, SMSC_PM_CTRL, SMSC_PM_CTRL_PHY_RST)) != 0) { smsc_warn_printf(sc, "timed-out waiting for phy reset to complete\n"); goto init_failed; } From bcccdfa37bad4ddb6b564ec9d17908c0a8ffa321 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sun, 14 Feb 2016 13:42:16 +0000 Subject: [PATCH 121/142] Don't dereference a pointer immediately after determining that it is equal to NULL. [1] While I'm here, s/xb/xbd/ (the name changed a long time ago but this instance wasn't corrected). Reported by: PVS-Studio [1] --- sys/dev/xen/blkfront/blkfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index c193d84b5a2b..d35e04acb0b9 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -674,7 +674,7 @@ xbd_open(struct disk *dp) struct xbd_softc *sc = dp->d_drv1; if (sc == NULL) { - printf("xb%d: not found", sc->xbd_unit); + printf("xbd%d: not found", dp->d_unit); return (ENXIO); } From daa1a379ce523f7180e9570da56ad151729714a0 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Sun, 14 Feb 2016 14:23:56 +0000 Subject: [PATCH 122/142] Fix a bug that caused nothing to be skipped when skipping exactly the number of bytes present in a regular file was requested. Obtained from: OpenBSD --- usr.bin/hexdump/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/hexdump/display.c b/usr.bin/hexdump/display.c index 4ff33080780b..36230aa7da58 100644 --- a/usr.bin/hexdump/display.c +++ b/usr.bin/hexdump/display.c @@ -374,7 +374,7 @@ doskip(const char *fname, int statok) if (statok) { if (fstat(fileno(stdin), &sb)) err(1, "%s", fname); - if (S_ISREG(sb.st_mode) && skip >= sb.st_size) { + if (S_ISREG(sb.st_mode) && skip > sb.st_size) { address += sb.st_size; skip -= sb.st_size; return; From d5fb67a40124d6a7b19641a30541f6daefa25af3 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sun, 14 Feb 2016 16:18:39 +0000 Subject: [PATCH 123/142] Restore maximum number of host keys to 64. Discussed with: adrian @ and avos @ --- sys/dev/usb/wlan/if_rumreg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/wlan/if_rumreg.h b/sys/dev/usb/wlan/if_rumreg.h index f1f1195798bc..06c0a8120b2c 100644 --- a/sys/dev/usb/wlan/if_rumreg.h +++ b/sys/dev/usb/wlan/if_rumreg.h @@ -47,7 +47,7 @@ * H/w encryption/decryption support */ #define KEY_SIZE (IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE) -#define RT2573_ADDR_MAX (32 / RT2573_SKEY_MAX) +#define RT2573_ADDR_MAX 64 #define RT2573_SKEY_MAX 4 #define RT2573_SKEY(vap, kidx) (0x1000 + ((vap) * RT2573_SKEY_MAX + \ From 15147f076efb77b6bdbc23563b644383d35a3e57 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 14 Feb 2016 16:38:32 +0000 Subject: [PATCH 124/142] Remove an unused include. --- sys/arm/mv/twsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/arm/mv/twsi.c b/sys/arm/mv/twsi.c index bd9b137072d7..e0290a86121c 100644 --- a/sys/arm/mv/twsi.c +++ b/sys/arm/mv/twsi.c @@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include "iicbus_if.h" From 00e24e41738728b2630d69019c8b93ce9af17317 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Sun, 14 Feb 2016 19:52:50 +0000 Subject: [PATCH 125/142] ext2fs: Remove panics for rename() race conditions. Sync with r84642 from UFS: The panics are inappropriate because the IN_RENAME flag only fixes a few of the huge number of race conditions that can result in the source path becoming invalid even prior to the VOP_RENAME() call. Found accidentally while checking an issue from PVS Static Analysis. MFC after: 3 days --- sys/fs/ext2fs/ext2_vnops.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index bc239b8f1630..42e11c7174ac 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -985,10 +985,10 @@ ext2_rename(struct vop_rename_args *ap) dp = VTOI(fdvp); } else { /* - * From name has disappeared. + * From name has disappeared. IN_RENAME is not sufficient + * to protect against directory races due to timing windows, + * so we can't panic here. */ - if (doingdirectory) - panic("ext2_rename: lost dir entry"); vrele(ap->a_fvp); return (0); } @@ -1003,8 +1003,11 @@ ext2_rename(struct vop_rename_args *ap) * rename. */ if (xp != ip) { - if (doingdirectory) - panic("ext2_rename: lost dir entry"); + /* + * From name resolves to a different inode. IN_RENAME is + * not sufficient protection against timing window races + * so we can't panic here. + */ } else { /* * If the source is a directory with a From f98d21e56163bb76eff7c8fdee39c6d165931e17 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 14 Feb 2016 22:37:28 +0000 Subject: [PATCH 126/142] NTB: workaround for high traffic hardware hang This patch comes from Dave Jiang's Linux tree, davejiang/ntb. It hasn't been accepted into Linus' tree, so I do not have an authoritative SHA1 to point at. Original commit log: ===================================================================== A hardware errata causes the NTB to hang when heavy bi-directional traffic in addition to the usage of BAR0/1 (where the registers reside, including the doorbell registers to trigger interrupts). This workaround is only available on Haswell and Broadwell platform. The workaround is to enable split BAR in the BIOS to allow the 64bit BAR4 to be split into two 32bit BAR4 and BAR5. The BAR4 shall be pointed to LAPIC region of the remote host. We will bypass the db mechanism and directly trigger the MSIX interrupts. The offsets and vectors are exchanged during transport scratch pad negotiation. The scratch pads are now overloaded in order to allow the exchange of the information. This gets around using the doorbell and prevents the lockup with additional pcode changes in BIOS. Signed-off-by: Dave Jiang ===================================================================== Notable changes in the FreeBSD version of this patch: * The MSIX BAR is configurable, like hw.ntb.b2b_mw_idx (msix_mw_idx). The Linux version of the patch only uses BAR4. * MSIX negotiation aborts if the link goes down. Obtained from: Linux (Dual BSD/GPL driver) Sponsored by: EMC / Isilon Storage Division --- sys/dev/ntb/ntb_hw/ntb_hw.c | 439 +++++++++++++++++++++++++++++++--- sys/dev/ntb/ntb_hw/ntb_hw.h | 1 + sys/dev/ntb/ntb_hw/ntb_regs.h | 1 + 3 files changed, 406 insertions(+), 35 deletions(-) diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index abfbf71acad3..90b27a3f8b1f 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -42,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -70,6 +73,19 @@ __FBSDID("$FreeBSD$"); #define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev)) +#define NTB_MSIX_VER_GUARD 0xaabbccdd +#define NTB_MSIX_RECEIVED 0xe0f0e0f0 +#define ONE_MB (1024u * 1024) + +/* + * PCI constants could be somewhere more generic, but aren't defined/used in + * pci.c. + */ +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 + enum ntb_device_type { NTB_XEON, NTB_ATOM @@ -95,6 +111,18 @@ enum ntb_bar { NTB_MAX_BARS }; +enum { + NTB_MSIX_GUARD = 0, + NTB_MSIX_DATA0, + NTB_MSIX_DATA1, + NTB_MSIX_DATA2, + NTB_MSIX_OFS0, + NTB_MSIX_OFS1, + NTB_MSIX_OFS2, + NTB_MSIX_DONE, + NTB_MAX_MSIX_SPAD +}; + /* Device features and workarounds */ #define HAS_FEATURE(feature) \ ((ntb->features & (feature)) != 0) @@ -131,6 +159,7 @@ struct ntb_int_info { struct ntb_vec { struct ntb_softc *ntb; uint32_t num; + unsigned masked; }; struct ntb_reg { @@ -169,6 +198,11 @@ struct ntb_b2b_addr { uint64_t bar5_addr32; }; +struct ntb_msix_data { + uint32_t nmd_ofs; + uint32_t nmd_data; +}; + struct ntb_softc { device_t device; enum ntb_device_type type; @@ -178,6 +212,13 @@ struct ntb_softc { struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; uint32_t allocated_interrupts; + struct ntb_msix_data peer_msix_data[XEON_NONLINK_DB_MSIX_BITS]; + struct ntb_msix_data msix_data[XEON_NONLINK_DB_MSIX_BITS]; + bool peer_msix_good; + bool peer_msix_done; + struct ntb_pci_bar_info *peer_lapic_bar; + struct callout peer_msix_work; + struct callout heartbeat_timer; struct callout lr_timer; @@ -198,6 +239,7 @@ struct ntb_softc { /* Memory window used to access peer bar0 */ #define B2B_MW_DISABLED UINT8_MAX uint8_t b2b_mw_idx; + uint8_t msix_mw_idx; uint8_t mw_count; uint8_t spad_count; @@ -292,6 +334,8 @@ static inline void db_iowrite(struct ntb_softc *, uint64_t regoff, uint64_t); static inline void db_iowrite_raw(struct ntb_softc *, uint64_t regoff, uint64_t); static int ntb_create_msix_vec(struct ntb_softc *ntb, uint32_t num_vectors); static void ntb_free_msix_vec(struct ntb_softc *ntb); +static void ntb_get_msix_info(struct ntb_softc *ntb, uint32_t num_vectors); +static void ntb_exchange_msix(void *); static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); static void ntb_detect_max_mw(struct ntb_softc *ntb); static int ntb_detect_xeon(struct ntb_softc *ntb); @@ -308,7 +352,9 @@ static void xeon_set_pbar_xlat(struct ntb_softc *, uint64_t base_addr, enum ntb_bar idx); static int xeon_setup_b2b_mw(struct ntb_softc *, const struct ntb_b2b_addr *addr, const struct ntb_b2b_addr *peer_addr); +static int xeon_setup_msix_bar(struct ntb_softc *); static inline bool link_is_up(struct ntb_softc *ntb); +static inline bool _xeon_link_is_up(struct ntb_softc *ntb); static inline bool atom_link_is_err(struct ntb_softc *ntb); static inline enum ntb_speed ntb_link_sta_speed(struct ntb_softc *); static inline enum ntb_width ntb_link_sta_width(struct ntb_softc *); @@ -395,6 +441,13 @@ ntb_vm_memattr_to_str(vm_memattr_t pat) } } +static int g_ntb_msix_idx = 0; +SYSCTL_INT(_hw_ntb, OID_AUTO, msix_mw_idx, CTLFLAG_RDTUN, &g_ntb_msix_idx, + 0, "Use this memory window to access the peer MSIX message complex on " + "certain Xeon-based NTB systems, as a workaround for a hardware errata. " + "Like b2b_mw_idx, negative values index from the last available memory " + "window. (Applies on Xeon platforms with SB01BASE_LOCKUP errata.)"); + static int g_ntb_mw_idx = -1; SYSCTL_INT(_hw_ntb, OID_AUTO, b2b_mw_idx, CTLFLAG_RDTUN, &g_ntb_mw_idx, 0, "Use this memory window to access the peer NTB registers. A " @@ -593,10 +646,12 @@ ntb_attach(device_t device) ntb->type = p->type; ntb->features = p->features; ntb->b2b_mw_idx = B2B_MW_DISABLED; + ntb->msix_mw_idx = B2B_MW_DISABLED; /* Heartbeat timer for NTB_ATOM since there is no link interrupt */ callout_init(&ntb->heartbeat_timer, 1); callout_init(&ntb->lr_timer, 1); + callout_init(&ntb->peer_msix_work, 1); mtx_init(&ntb->db_mask_lock, "ntb hw bits", NULL, MTX_SPIN); mtx_init(&ntb->ctx_lock, "ntb ctx", NULL, MTX_DEF); @@ -621,6 +676,8 @@ ntb_attach(device_t device) if (error != 0) goto out; + ntb_spad_clear(ntb); + ntb_poll_link(ntb); ntb_sysctl_init(ntb); @@ -638,10 +695,14 @@ ntb_detach(device_t device) ntb = DEVICE2SOFTC(device); - if (ntb->self_reg != NULL) - ntb_db_set_mask(ntb, ntb->db_valid_mask); + if (ntb->self_reg != NULL) { + DB_MASK_LOCK(ntb); + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_valid_mask); + DB_MASK_UNLOCK(ntb); + } callout_drain(&ntb->heartbeat_timer); callout_drain(&ntb->lr_timer); + callout_drain(&ntb->peer_msix_work); pci_disable_busmaster(ntb->device); if (ntb->type == NTB_XEON) ntb_teardown_xeon(ntb); @@ -965,9 +1026,12 @@ ntb_init_isr(struct ntb_softc *ntb) ntb->last_ts = ticks; /* - * Mask all doorbell interrupts. + * Mask all doorbell interrupts. (Except link events!) */ - ntb_db_set_mask(ntb, ntb->db_valid_mask); + DB_MASK_LOCK(ntb); + ntb->db_mask = ntb->db_valid_mask; + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + DB_MASK_UNLOCK(ntb); num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device), ntb->db_count); @@ -992,12 +1056,20 @@ ntb_init_isr(struct ntb_softc *ntb) num_vectors = 1; if (ntb->type == NTB_XEON && num_vectors < ntb->db_vec_count) { + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + device_printf(ntb->device, + "Errata workaround does not support MSI or INTX\n"); + return (EINVAL); + } + ntb->db_vec_count = 1; ntb->db_vec_shift = XEON_DB_TOTAL_SHIFT; rc = ntb_setup_legacy_interrupt(ntb); } else { ntb_create_msix_vec(ntb, num_vectors); rc = ntb_setup_msix(ntb, num_vectors); + if (rc == 0 && HAS_FEATURE(NTB_SB01BASE_LOCKUP)) + ntb_get_msix_info(ntb, num_vectors); } if (rc != 0) { device_printf(ntb->device, @@ -1103,6 +1175,9 @@ void ntb_db_set_mask(struct ntb_softc *ntb, uint64_t bits) { + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) + return; + DB_MASK_LOCK(ntb); ntb->db_mask |= bits; db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); @@ -1118,6 +1193,9 @@ ntb_db_clear_mask(struct ntb_softc *ntb, uint64_t bits) (uintmax_t)(bits & ~ntb->db_valid_mask), (uintmax_t)ntb->db_valid_mask)); + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) + return; + DB_MASK_LOCK(ntb); ntb->db_mask &= ~bits; db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); @@ -1128,6 +1206,18 @@ uint64_t ntb_db_read(struct ntb_softc *ntb) { + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + uint64_t res; + unsigned i; + + res = 0; + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + if (ntb->msix_vec[i].masked != 0) + res |= ntb_db_vector_mask(ntb, i); + } + return (res); + } + return (db_ioread(ntb, ntb->self_reg->db_bell)); } @@ -1140,6 +1230,25 @@ ntb_db_clear(struct ntb_softc *ntb, uint64_t bits) (uintmax_t)(bits & ~ntb->db_valid_mask), (uintmax_t)ntb->db_valid_mask)); + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + unsigned i; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + if ((bits & ntb_db_vector_mask(ntb, i)) != 0) { + DB_MASK_LOCK(ntb); + if (ntb->msix_vec[i].masked != 0) { + /* XXX These need a public API. */ +#if 0 + pci_unmask_msix(ntb->device, i); +#endif + ntb->msix_vec[i].masked = 0; + } + DB_MASK_UNLOCK(ntb); + } + } + return; + } + db_iowrite(ntb, ntb->self_reg->db_bell, bits); } @@ -1166,6 +1275,19 @@ ntb_interrupt(struct ntb_softc *ntb, uint32_t vec) ntb_link_event(ntb); } + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP) && + (vec_mask & ntb->db_link_mask) == 0) { + DB_MASK_LOCK(ntb); + if (ntb->msix_vec[vec].masked == 0) { + /* XXX These need a public API. */ +#if 0 + pci_mask_msix(ntb->device, vec); +#endif + ntb->msix_vec[vec].masked = 1; + } + DB_MASK_UNLOCK(ntb); + } + if ((vec_mask & ntb->db_valid_mask) != 0) ntb_db_event(ntb, vec); } @@ -1211,6 +1333,38 @@ ntb_free_msix_vec(struct ntb_softc *ntb) ntb->msix_vec = NULL; } +static void +ntb_get_msix_info(struct ntb_softc *ntb, uint32_t num_vectors) +{ + struct pci_devinfo *dinfo; + struct pcicfg_msix *msix; + uint32_t laddr, data, i, offset; + + dinfo = device_get_ivars(ntb->device); + msix = &dinfo->cfg.msix; + + laddr = data = 0; + + for (i = 0; i < num_vectors; i++) { + offset = msix->msix_table_offset + i * PCI_MSIX_ENTRY_SIZE; + + laddr = bus_read_4(msix->msix_table_res, offset + + PCI_MSIX_ENTRY_LOWER_ADDR); + ntb_printf(2, "local lower MSIX addr(%u): 0x%x\n", i, laddr); + + KASSERT((laddr & MSI_INTEL_ADDR_BASE) == MSI_INTEL_ADDR_BASE, + ("local MSIX addr 0x%x not in MSI base 0x%x", laddr, + MSI_INTEL_ADDR_BASE)); + ntb->msix_data[i].nmd_ofs = laddr & ~MSI_INTEL_ADDR_BASE; + + data = bus_read_4(msix->msix_table_res, offset + + PCI_MSIX_ENTRY_DATA); + ntb_printf(2, "local MSIX data(%u): 0x%x\n", i, data); + + ntb->msix_data[i].nmd_data = data; + } +} + static struct ntb_hw_info * ntb_get_device_info(uint32_t device_id) { @@ -1263,9 +1417,12 @@ ntb_detect_xeon(struct ntb_softc *ntb) if ((ppd & XEON_PPD_SPLIT_BAR) != 0) ntb->features |= NTB_SPLIT_BAR; - /* SB01BASE_LOCKUP errata is a superset of SDOORBELL errata */ + /* + * SDOORBELL errata workaround gets in the way of SB01BASE_LOCKUP + * errata workaround; only do one at a time. + */ if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) - ntb->features |= NTB_SDOORBELL_LOCKUP; + ntb->features &= ~NTB_SDOORBELL_LOCKUP; conn_type = ppd & XEON_PPD_CONN_TYPE; switch (conn_type) { @@ -1329,19 +1486,28 @@ ntb_xeon_init_dev(struct ntb_softc *ntb) ntb->peer_reg = &xeon_b2b_reg; ntb->xlat_reg = &xeon_sec_xlat; - /* - * There is a Xeon hardware errata related to writes to SDOORBELL or - * B2BDOORBELL in conjunction with inbound access to NTB MMIO space, - * which may hang the system. To workaround this, use a memory - * window to access the interrupt and scratch pad registers on the - * remote system. - */ - if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP)) { + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + ntb->msix_mw_idx = (ntb->mw_count + g_ntb_msix_idx) % + ntb->mw_count; + ntb_printf(2, "Setting up MSIX mw idx %d means %u\n", + g_ntb_msix_idx, ntb->msix_mw_idx); + rc = ntb_mw_set_wc_internal(ntb, ntb->msix_mw_idx, + VM_MEMATTR_UNCACHEABLE); + KASSERT(rc == 0, ("shouldn't fail")); + } else if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP)) { + /* + * There is a Xeon hardware errata related to writes to SDOORBELL or + * B2BDOORBELL in conjunction with inbound access to NTB MMIO space, + * which may hang the system. To workaround this, use a memory + * window to access the interrupt and scratch pad registers on the + * remote system. + */ ntb->b2b_mw_idx = (ntb->mw_count + g_ntb_mw_idx) % ntb->mw_count; ntb_printf(2, "Setting up b2b mw idx %d means %u\n", g_ntb_mw_idx, ntb->b2b_mw_idx); - rc = ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, VM_MEMATTR_UNCACHEABLE); + rc = ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, + VM_MEMATTR_UNCACHEABLE); KASSERT(rc == 0, ("shouldn't fail")); } else if (HAS_FEATURE(NTB_B2BDOORBELL_BIT14)) /* @@ -1372,7 +1538,14 @@ ntb_xeon_init_dev(struct ntb_softc *ntb) /* * Mask all doorbell interrupts. */ - ntb_db_set_mask(ntb, ntb->db_valid_mask); + DB_MASK_LOCK(ntb); + ntb->db_mask = ntb->db_valid_mask; + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + DB_MASK_UNLOCK(ntb); + + rc = xeon_setup_msix_bar(ntb); + if (rc != 0) + return (rc); rc = ntb_init_isr(ntb); return (rc); @@ -1475,6 +1648,15 @@ xeon_reset_sbar_size(struct ntb_softc *ntb, enum ntb_bar idx, bar_sz--; else bar_sz = 0; + } else if (HAS_FEATURE(NTB_SB01BASE_LOCKUP) && + ntb_mw_to_bar(ntb, ntb->msix_mw_idx) == idx) { + /* Restrict LAPIC BAR to 1MB */ + pci_write_config(ntb->device, bar->psz_off, 20, 1); + pci_write_config(ntb->device, bar->ssz_off, 20, 1); + bar_sz = pci_read_config(ntb->device, bar->psz_off, 1); + bar_sz = pci_read_config(ntb->device, bar->ssz_off, 1); + (void)bar_sz; + return; } pci_write_config(ntb->device, bar->ssz_off, bar_sz, 1); bar_sz = pci_read_config(ntb->device, bar->ssz_off, 1); @@ -1485,29 +1667,38 @@ static void xeon_set_sbar_base_and_limit(struct ntb_softc *ntb, uint64_t bar_addr, enum ntb_bar idx, enum ntb_bar regbar) { - uint64_t reg_val; + uint64_t reg_val, lmt_addr; uint32_t base_reg, lmt_reg; bar_get_xlat_params(ntb, idx, &base_reg, NULL, &lmt_reg); if (idx == regbar) bar_addr += ntb->b2b_off; + lmt_addr = bar_addr; + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP) && + ntb_mw_to_bar(ntb, ntb->msix_mw_idx) == idx) + lmt_addr += ONE_MB; + + /* + * Set limit registers first to avoid an errata where setting the base + * registers locks the limit registers. + */ if (!bar_is_64bit(ntb, idx)) { + ntb_reg_write(4, lmt_reg, lmt_addr); + reg_val = ntb_reg_read(4, lmt_reg); + (void)reg_val; + ntb_reg_write(4, base_reg, bar_addr); reg_val = ntb_reg_read(4, base_reg); (void)reg_val; - - ntb_reg_write(4, lmt_reg, bar_addr); - reg_val = ntb_reg_read(4, lmt_reg); - (void)reg_val; } else { + ntb_reg_write(8, lmt_reg, lmt_addr); + reg_val = ntb_reg_read(8, lmt_reg); + (void)reg_val; + ntb_reg_write(8, base_reg, bar_addr); reg_val = ntb_reg_read(8, base_reg); (void)reg_val; - - ntb_reg_write(8, lmt_reg, bar_addr); - reg_val = ntb_reg_read(8, lmt_reg); - (void)reg_val; } } @@ -1527,6 +1718,37 @@ xeon_set_pbar_xlat(struct ntb_softc *ntb, uint64_t base_addr, enum ntb_bar idx) (void)base_addr; } +static int +xeon_setup_msix_bar(struct ntb_softc *ntb) +{ + struct ntb_pci_bar_info *lapic_bar; + enum ntb_bar bar_num; + int rc; + + if (!HAS_FEATURE(NTB_SB01BASE_LOCKUP)) + return (0); + + bar_num = ntb_mw_to_bar(ntb, ntb->msix_mw_idx); + lapic_bar = &ntb->bar_info[bar_num]; + + /* Restrict LAPIC BAR to 1MB */ + if (lapic_bar->size > ONE_MB) { + rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY, + lapic_bar->pci_resource, lapic_bar->pbase, + lapic_bar->pbase + ONE_MB - 1); + if (rc == 0) + lapic_bar->size = ONE_MB; + else { + ntb_printf(0, "Failed to shrink LAPIC BAR resource to " + "1 MB: %d\n", rc); + /* Ignore error */ + } + } + + ntb->peer_lapic_bar = lapic_bar; + return (0); +} + static int xeon_setup_b2b_mw(struct ntb_softc *ntb, const struct ntb_b2b_addr *addr, const struct ntb_b2b_addr *peer_addr) @@ -1605,6 +1827,43 @@ xeon_setup_b2b_mw(struct ntb_softc *ntb, const struct ntb_b2b_addr *addr, ntb_reg_write(8, XEON_SBAR2XLAT_OFFSET, 0); ntb_reg_write(8, XEON_SBAR4XLAT_OFFSET, 0); + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + size_t size, xlatoffset; + + switch (ntb_mw_to_bar(ntb, ntb->msix_mw_idx)) { + case NTB_B2B_BAR_1: + size = 8; + xlatoffset = XEON_SBAR2XLAT_OFFSET; + break; + case NTB_B2B_BAR_2: + xlatoffset = XEON_SBAR4XLAT_OFFSET; + if (HAS_FEATURE(NTB_SPLIT_BAR)) + size = 4; + else + size = 8; + break; + case NTB_B2B_BAR_3: + xlatoffset = XEON_SBAR5XLAT_OFFSET; + size = 4; + break; + default: + KASSERT(false, ("Bogus msix mw idx: %u", + ntb->msix_mw_idx)); + return (EINVAL); + } + + /* + * We point the chosen MSIX MW BAR xlat to remote LAPIC for + * workaround + */ + if (size == 4) + ntb_reg_write(4, xlatoffset, MSI_INTEL_ADDR_BASE); + else + ntb_reg_write(8, xlatoffset, MSI_INTEL_ADDR_BASE); + } + (void)ntb_reg_read(8, XEON_SBAR2XLAT_OFFSET); + (void)ntb_reg_read(8, XEON_SBAR4XLAT_OFFSET); + /* Zero outgoing translation limits (whole bar size windows) */ ntb_reg_write(8, XEON_PBAR2LMT_OFFSET, 0); ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0); @@ -1641,15 +1900,22 @@ xeon_setup_b2b_mw(struct ntb_softc *ntb, const struct ntb_b2b_addr *addr, return (0); } +static inline bool +_xeon_link_is_up(struct ntb_softc *ntb) +{ + + if (ntb->conn_type == NTB_CONN_TRANSPARENT) + return (true); + return ((ntb->lnk_sta & NTB_LINK_STATUS_ACTIVE) != 0); +} + static inline bool link_is_up(struct ntb_softc *ntb) { - if (ntb->type == NTB_XEON) { - if (ntb->conn_type == NTB_CONN_TRANSPARENT) - return (true); - return ((ntb->lnk_sta & NTB_LINK_STATUS_ACTIVE) != 0); - } + if (ntb->type == NTB_XEON) + return (_xeon_link_is_up(ntb) && (ntb->peer_msix_good || + !HAS_FEATURE(NTB_SB01BASE_LOCKUP))); KASSERT(ntb->type == NTB_ATOM, ("ntb type")); return ((ntb->ntb_ctl & ATOM_CNTL_LINK_DOWN) == 0); @@ -1988,6 +2254,19 @@ ntb_poll_link(struct ntb_softc *ntb) return (false); ntb->lnk_sta = reg_val; + + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + if (_xeon_link_is_up(ntb)) { + if (!ntb->peer_msix_good) { + callout_reset(&ntb->peer_msix_work, 0, + ntb_exchange_msix, ntb); + return (false); + } + } else { + ntb->peer_msix_good = false; + ntb->peer_msix_done = false; + } + } } return (true); } @@ -2416,12 +2695,70 @@ static unsigned ntb_user_mw_to_idx(struct ntb_softc *ntb, unsigned uidx) { - if (ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && - uidx >= ntb->b2b_mw_idx) - return (uidx + 1); + if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && + uidx >= ntb->b2b_mw_idx) || + (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) + uidx++; + if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && + uidx >= ntb->b2b_mw_idx) && + (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) + uidx++; return (uidx); } +static void +ntb_exchange_msix(void *ctx) +{ + struct ntb_softc *ntb; + uint32_t val; + unsigned i; + + ntb = ctx; + + if (ntb->peer_msix_done) + goto msix_done; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + ntb_peer_spad_write(ntb, NTB_MSIX_DATA0 + i, + ntb->msix_data[i].nmd_data); + ntb_peer_spad_write(ntb, NTB_MSIX_OFS0 + i, + ntb->msix_data[i].nmd_ofs); + } + ntb_peer_spad_write(ntb, NTB_MSIX_GUARD, NTB_MSIX_VER_GUARD); + + ntb_spad_read(ntb, NTB_MSIX_GUARD, &val); + if (val != NTB_MSIX_VER_GUARD) + goto reschedule; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + ntb_spad_read(ntb, NTB_MSIX_DATA0 + i, &val); + ntb->peer_msix_data[i].nmd_data = val; + ntb_spad_read(ntb, NTB_MSIX_OFS0 + i, &val); + ntb->peer_msix_data[i].nmd_ofs = val; + } + + ntb->peer_msix_done = true; + +msix_done: + ntb_peer_spad_write(ntb, NTB_MSIX_DONE, NTB_MSIX_RECEIVED); + ntb_spad_read(ntb, NTB_MSIX_DONE, &val); + if (val != NTB_MSIX_RECEIVED) + goto reschedule; + + ntb->peer_msix_good = true; + + ntb_poll_link(ntb); + ntb_link_event(ntb); + return; + +reschedule: + ntb->lnk_sta = pci_read_config(ntb->device, ntb->reg->lnk_sta, 2); + if (_xeon_link_is_up(ntb)) + callout_reset(&ntb->peer_msix_work, hz / 100, ntb_exchange_msix, ntb); + else + ntb_spad_clear(ntb); +} + /* * Public API to the rest of the OS */ @@ -2451,10 +2788,14 @@ ntb_get_max_spads(struct ntb_softc *ntb) uint8_t ntb_mw_count(struct ntb_softc *ntb) { + uint8_t res; + res = ntb->mw_count; if (ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0) - return (ntb->mw_count - 1); - return (ntb->mw_count); + res--; + if (ntb->msix_mw_idx != B2B_MW_DISABLED) + res--; + return (res); } /** @@ -2480,6 +2821,18 @@ ntb_spad_write(struct ntb_softc *ntb, unsigned int idx, uint32_t val) return (0); } +/* + * Zeros the local scratchpad. + */ +void +ntb_spad_clear(struct ntb_softc *ntb) +{ + unsigned i; + + for (i = 0; i < ntb->spad_count; i++) + ntb_spad_write(ntb, i, 0); +} + /** * ntb_spad_read() - read from the primary scratchpad register * @ntb: pointer to ntb_softc instance @@ -2808,6 +3161,22 @@ void ntb_peer_db_set(struct ntb_softc *ntb, uint64_t bit) { + if (HAS_FEATURE(NTB_SB01BASE_LOCKUP)) { + struct ntb_pci_bar_info *lapic; + unsigned i; + + lapic = ntb->peer_lapic_bar; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + if ((bit & ntb_db_vector_mask(ntb, i)) != 0) + bus_space_write_4(lapic->pci_bus_tag, + lapic->pci_bus_handle, + ntb->peer_msix_data[i].nmd_ofs, + ntb->peer_msix_data[i].nmd_data); + } + return; + } + if (HAS_FEATURE(NTB_SDOORBELL_LOCKUP)) { ntb_mw_write(2, XEON_PDOORBELL_OFFSET, bit); return; diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.h b/sys/dev/ntb/ntb_hw/ntb_hw.h index c35166c4c8f0..e2f45b20c753 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.h +++ b/sys/dev/ntb/ntb_hw/ntb_hw.h @@ -86,6 +86,7 @@ int ntb_mw_get_wc(struct ntb_softc *, unsigned mw_idx, vm_memattr_t *mode); int ntb_mw_set_wc(struct ntb_softc *, unsigned mw_idx, vm_memattr_t mode); uint8_t ntb_get_max_spads(struct ntb_softc *ntb); +void ntb_spad_clear(struct ntb_softc *ntb); int ntb_spad_write(struct ntb_softc *ntb, unsigned int idx, uint32_t val); int ntb_spad_read(struct ntb_softc *ntb, unsigned int idx, uint32_t *val); int ntb_peer_spad_write(struct ntb_softc *ntb, unsigned int idx, diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h index f50fd938ad8a..fb445d7d8020 100644 --- a/sys/dev/ntb/ntb_hw/ntb_regs.h +++ b/sys/dev/ntb/ntb_hw/ntb_regs.h @@ -44,6 +44,7 @@ #define XEON_DB_MSIX_VECTOR_COUNT 4 #define XEON_DB_MSIX_VECTOR_SHIFT 5 #define XEON_DB_LINK_BIT (1 << XEON_DB_LINK) +#define XEON_NONLINK_DB_MSIX_BITS 3 #define XEON_SPCICMD_OFFSET 0x0504 #define XEON_DEVCTRL_OFFSET 0x0598 From aa8dbafa71a5a0ac32f656ccb08a4982948cce06 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 14 Feb 2016 23:42:07 +0000 Subject: [PATCH 127/142] Create the twsi device option in preparation to move the driver to a common location. The device is also found in Allwinner SoCs. Sponsored by: ABT Systems Ltd --- sys/arm/conf/ARMADA38X | 1 + sys/arm/conf/ARMADAXP | 1 + sys/arm/conf/DB-78XXX | 1 + sys/arm/conf/DB-88F5XXX | 1 + sys/arm/conf/DB-88F6XXX | 1 + sys/arm/conf/DOCKSTAR | 1 + sys/arm/conf/DREAMPLUG-1001 | 1 + sys/arm/conf/NOTES | 3 +++ sys/arm/mv/files.mv | 2 +- 9 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/arm/conf/ARMADA38X b/sys/arm/conf/ARMADA38X index ede1b74e63c1..d6b36642e940 100644 --- a/sys/arm/conf/ARMADA38X +++ b/sys/arm/conf/ARMADA38X @@ -78,6 +78,7 @@ device da # I2C device iic device iicbus +device twsi #FDT options FDT diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP index f1b2776cd620..a57f783f4a05 100644 --- a/sys/arm/conf/ARMADAXP +++ b/sys/arm/conf/ARMADAXP @@ -90,6 +90,7 @@ device uart # I2C (TWSI) device iic device iicbus +device twsi #Network device ether diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX index d40990baf4b2..d387ca3272e0 100644 --- a/sys/arm/conf/DB-78XXX +++ b/sys/arm/conf/DB-78XXX @@ -82,6 +82,7 @@ device da # I2C (TWSI) device iic device iicbus +device twsi device ds133x # SATA diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX index 28f448ae472a..4e6f7f8893c2 100644 --- a/sys/arm/conf/DB-88F5XXX +++ b/sys/arm/conf/DB-88F5XXX @@ -74,6 +74,7 @@ options HZ=1000 # I2C (TWSI) device iic device iicbus +device twsi device ds133x # USB diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX index 9dafb820b3aa..09e5f0b3bb3a 100644 --- a/sys/arm/conf/DB-88F6XXX +++ b/sys/arm/conf/DB-88F6XXX @@ -87,6 +87,7 @@ device da # I2C (TWSI) device iic device iicbus +device twsi # SATA device mvs diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index c643b92eb14c..9a138bf8deb9 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -117,6 +117,7 @@ device u3g # USB-based 3G modems (Option, Huawei, Sierra) # I2C (TWSI) device iic device iicbus +device twsi # Sound device sound diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index b5f4bd4b02e2..5391d185ceb6 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -121,6 +121,7 @@ device u3g # USB-based 3G modems (Option, Huawei, Sierra) # I2C (TWSI) device iic device iicbus +device twsi # GPIO device gpio diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES index db64f8ebb625..d32e6d61ec64 100644 --- a/sys/arm/conf/NOTES +++ b/sys/arm/conf/NOTES @@ -51,6 +51,9 @@ device at91_board_tsc4370 device at91rm9200 device nand +# IIC +device twsi + nooptions SMP nooptions MAXCPU diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv index 791ef00993ab..33a7711c1374 100644 --- a/sys/arm/mv/files.mv +++ b/sys/arm/mv/files.mv @@ -19,7 +19,7 @@ arm/mv/mv_machdep.c standard arm/mv/mv_pci.c optional pci arm/mv/mv_ts.c standard arm/mv/timer.c standard -arm/mv/twsi.c optional iicbus +arm/mv/twsi.c optional twsi dev/cesa/cesa.c optional cesa dev/mge/if_mge.c optional mge From 632381ed9d54f8aaed2c9e5846bcc6ac04087d87 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 14 Feb 2016 23:51:13 +0000 Subject: [PATCH 128/142] Move the twsi driver source to be under iicbus. It is in a separate directory as it is expected multiple attachments will be added for the SoC families that use this hardware. Sponsored by: ABT Systems Ltd --- sys/arm/mv/files.mv | 1 - sys/conf/files.arm | 1 + sys/{arm/mv => dev/iicbus/twsi}/twsi.c | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename sys/{arm/mv => dev/iicbus/twsi}/twsi.c (100%) diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv index 33a7711c1374..e605aab06f0e 100644 --- a/sys/arm/mv/files.mv +++ b/sys/arm/mv/files.mv @@ -19,7 +19,6 @@ arm/mv/mv_machdep.c standard arm/mv/mv_pci.c optional pci arm/mv/mv_ts.c standard arm/mv/timer.c standard -arm/mv/twsi.c optional twsi dev/cesa/cesa.c optional cesa dev/mge/if_mge.c optional mge diff --git a/sys/conf/files.arm b/sys/conf/files.arm index bc5d8a39fd6d..ac8b4e8914e6 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -101,6 +101,7 @@ dev/fb/fb.c optional sc dev/fdt/fdt_arm_platform.c optional platform fdt dev/hwpmc/hwpmc_arm.c optional hwpmc dev/hwpmc/hwpmc_armv7.c optional hwpmc armv6 +dev/iicbus/twsi/twsi.c optional twsi dev/psci/psci.c optional psci dev/psci/psci_arm.S optional psci dev/syscons/scgfbrndr.c optional sc diff --git a/sys/arm/mv/twsi.c b/sys/dev/iicbus/twsi/twsi.c similarity index 100% rename from sys/arm/mv/twsi.c rename to sys/dev/iicbus/twsi/twsi.c From 0cc5515a857dcb298f6cd44184a933999711227b Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 15 Feb 2016 14:34:35 +0000 Subject: [PATCH 129/142] Allow MIPS INTRNG code to be built without FDT support. This patch allows the newly imported INTRNG code to be built without necessarily having FDT support in the kernel. This may be useful for some MIPS platforms that wish to move to INTRNG, but not to FDT at the same time. Basically all the code is already within ifdef's where FDT is concerned, it's just the headers that aren't. Submitted by: Stanislav Galabov Differential Revision: https://reviews.freebsd.org/D5249 --- sys/kern/subr_intr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 813f9eccdbea..9e7fcaf422d8 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -60,11 +60,13 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FDT #include #include #include #include +#endif #ifdef DDB #include From 5f250b53e808c9ec5cb18180114058cbdd5c72f6 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 15:11:26 +0000 Subject: [PATCH 130/142] Add support for the Allwinner i2c device. This is similar to the existing Marvell twsi part, however uses different register locations, as such split the existing driver into Marvell and Allwinner attachments. While here clean a few style issues. Submitted by: Emmanuel Vadot Differential Revision: https://reviews.freebsd.org/D4846 --- sys/arm/allwinner/a10_clk.c | 23 ++ sys/arm/allwinner/a10_clk.h | 4 + sys/arm/allwinner/files.allwinner | 1 + sys/arm/conf/A10 | 5 +- sys/arm/conf/A20 | 5 +- sys/arm/mv/files.mv | 1 + sys/dev/iicbus/twsi/a10_twsi.c | 131 ++++++++ sys/dev/iicbus/twsi/mv_twsi.c | 252 +++++++++++++++ sys/dev/iicbus/twsi/twsi.c | 512 ++++++++++-------------------- sys/dev/iicbus/twsi/twsi.h | 67 ++++ 10 files changed, 660 insertions(+), 341 deletions(-) create mode 100644 sys/dev/iicbus/twsi/a10_twsi.c create mode 100644 sys/dev/iicbus/twsi/mv_twsi.c create mode 100644 sys/dev/iicbus/twsi/twsi.h diff --git a/sys/arm/allwinner/a10_clk.c b/sys/arm/allwinner/a10_clk.c index d49e6d02dd56..177e5a3d4fda 100644 --- a/sys/arm/allwinner/a10_clk.c +++ b/sys/arm/allwinner/a10_clk.c @@ -400,6 +400,29 @@ a10_clk_mmc_cfg(int devid, int freq) return (0); } +int +a10_clk_i2c_activate(int devid) +{ + struct a10_ccm_softc *sc; + uint32_t reg_value; + + sc = a10_ccm_sc; + if (sc == NULL) + return (ENXIO); + + a10_clk_pll6_enable(); + + /* Gating APB clock for I2C/TWI */ + reg_value = ccm_read_4(sc, CCM_APB1_GATING); + if (devid == 4) + reg_value |= CCM_APB1_GATING_TWI << 15; + else + reg_value |= CCM_APB1_GATING_TWI << devid; + ccm_write_4(sc, CCM_APB1_GATING, reg_value); + + return (0); +} + int a10_clk_dmac_activate(void) { diff --git a/sys/arm/allwinner/a10_clk.h b/sys/arm/allwinner/a10_clk.h index 4df87cc21bfe..5cc8863421b3 100644 --- a/sys/arm/allwinner/a10_clk.h +++ b/sys/arm/allwinner/a10_clk.h @@ -121,6 +121,9 @@ /* AHB_GATING_REG1 */ #define CCM_AHB_GATING_GMAC (1 << 17) +/* APB1_GATING_REG */ +#define CCM_APB1_GATING_TWI (1 << 0) + #define CCM_USB_PHY (1 << 8) #define CCM_USB0_RESET (1 << 0) #define CCM_USB1_RESET (1 << 1) @@ -166,6 +169,7 @@ int a10_clk_gmac_activate(phandle_t); int a10_clk_ahci_activate(void); int a10_clk_mmc_activate(int); int a10_clk_mmc_cfg(int, int); +int a10_clk_i2c_activate(int); int a10_clk_dmac_activate(void); int a10_clk_codec_activate(unsigned int); diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index 5157850ada89..2db0da5dc424 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -12,4 +12,5 @@ arm/allwinner/a10_wdog.c standard arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/allwinner_machdep.c standard arm/allwinner/if_emac.c optional emac +dev/iicbus/twsi/a10_twsi.c optional twsi #arm/allwinner/console.c standard diff --git a/sys/arm/conf/A10 b/sys/arm/conf/A10 index 31073c723e11..577fa602e46d 100644 --- a/sys/arm/conf/A10 +++ b/sys/arm/conf/A10 @@ -66,8 +66,9 @@ device md device random # Entropy device # I2C support -#device iicbus -#device iic +device iicbus +device iic +device twsi # GPIO device gpio diff --git a/sys/arm/conf/A20 b/sys/arm/conf/A20 index cd0726454194..ded074a5240c 100644 --- a/sys/arm/conf/A20 +++ b/sys/arm/conf/A20 @@ -75,8 +75,9 @@ device md device random # Entropy device # I2C support -#device iicbus -#device iic +device iicbus +device iic +device twsi # GPIO device gpio diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv index e605aab06f0e..29edffbb13f0 100644 --- a/sys/arm/mv/files.mv +++ b/sys/arm/mv/files.mv @@ -21,6 +21,7 @@ arm/mv/mv_ts.c standard arm/mv/timer.c standard dev/cesa/cesa.c optional cesa +dev/iicbus/twsi/mv_twsi.c optional twsi dev/mge/if_mge.c optional mge dev/nand/nfc_mv.c optional nand dev/mvs/mvs_soc.c optional mvs diff --git a/sys/dev/iicbus/twsi/a10_twsi.c b/sys/dev/iicbus/twsi/a10_twsi.c new file mode 100644 index 000000000000..f07973e057f1 --- /dev/null +++ b/sys/dev/iicbus/twsi/a10_twsi.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "iicbus_if.h" + +#define TWI_ADDR 0x0 +#define TWI_XADDR 0x4 +#define TWI_DATA 0x8 +#define TWI_CNTR 0xC +#define TWI_STAT 0x10 +#define TWI_CCR 0x14 +#define TWI_SRST 0x18 +#define TWI_EFR 0x1C +#define TWI_LCR 0x20 + +static int +a10_twsi_probe(device_t dev) +{ + struct twsi_softc *sc; + + sc = device_get_softc(dev); + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-i2c")) + return (ENXIO); + + device_set_desc(dev, "Allwinner Integrated I2C Bus Controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +a10_twsi_attach(device_t dev) +{ + struct twsi_softc *sc; + + sc = device_get_softc(dev); + + /* Activate clock */ + a10_clk_i2c_activate(device_get_unit(dev)); + + sc->reg_data = TWI_DATA; + sc->reg_slave_addr = TWI_ADDR; + sc->reg_slave_ext_addr = TWI_XADDR; + sc->reg_control = TWI_CNTR; + sc->reg_status = TWI_STAT; + sc->reg_baud_rate = TWI_CCR; + sc->reg_soft_reset = TWI_SRST; + + /* Setup baud rate params */ + sc->baud_rate[IIC_SLOW].param = TWSI_BAUD_RATE_PARAM(11, 2); + sc->baud_rate[IIC_FAST].param = TWSI_BAUD_RATE_PARAM(11, 2); + sc->baud_rate[IIC_FASTEST].param = TWSI_BAUD_RATE_PARAM(2, 2); + + return (twsi_attach(dev)); +} + +static phandle_t +a10_twsi_get_node(device_t bus, device_t dev) +{ + return (ofw_bus_get_node(bus)); +} + +static device_method_t a10_twsi_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, a10_twsi_probe), + DEVMETHOD(device_attach, a10_twsi_attach), + + /* OFW methods */ + DEVMETHOD(ofw_bus_get_node, a10_twsi_get_node), + + { 0, 0 } +}; + +DEFINE_CLASS_1(iichb, a10_twsi_driver, a10_twsi_methods, + sizeof(struct twsi_softc), twsi_driver); + +static devclass_t a10_twsi_devclass; + +DRIVER_MODULE(a10_twsi, simplebus, a10_twsi_driver, a10_twsi_devclass, 0, 0); +DRIVER_MODULE(iicbus, a10_twsi, iicbus_driver, iicbus_devclass, 0, 0); +MODULE_DEPEND(a10_twsi, iicbus, 1, 1, 1); diff --git a/sys/dev/iicbus/twsi/mv_twsi.c b/sys/dev/iicbus/twsi/mv_twsi.c new file mode 100644 index 000000000000..db27366892eb --- /dev/null +++ b/sys/dev/iicbus/twsi/mv_twsi.c @@ -0,0 +1,252 @@ +/*- + * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. + * All rights reserved. + * + * Developed by Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell + * and Allwinner SoCs. Supports master operation only, and works in polling mode. + * + * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software + * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices". + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "iicbus_if.h" + +#define MV_TWSI_NAME "twsi" +#define IICBUS_DEVNAME "iicbus" + +#define TWSI_ADDR 0x00 +#define TWSI_DATA 0x04 +#define TWSI_CNTR 0x08 +#define TWSI_XADDR 0x10 +#define TWSI_STAT 0x0c +#define TWSI_BAUD_RATE 0x0c +#define TWSI_SRST 0x1c + +#define TWSI_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) +#define TWSI_BAUD_RATE_SLOW 50000 /* 50kHz */ +#define TWSI_BAUD_RATE_FAST 100000 /* 100kHz */ + +#define TWSI_DEBUG +#undef TWSI_DEBUG + +#ifdef TWSI_DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +static int mv_twsi_probe(device_t); +static int mv_twsi_attach(device_t); + +static struct ofw_compat_data compat_data[] = { + { "mrvl,twsi", true }, + { "marvell,mv64xxx-i2c", true }, + { NULL, false } +}; + +static device_method_t mv_twsi_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, mv_twsi_probe), + DEVMETHOD(device_attach, mv_twsi_attach), + + { 0, 0 } +}; + +DEFINE_CLASS_1(twsi, mv_twsi_driver, mv_twsi_methods, + sizeof(struct twsi_softc), twsi_driver); + +static devclass_t mv_twsi_devclass; + +DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0); +DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0); +MODULE_DEPEND(twsi, iicbus, 1, 1, 1); + +static int +mv_twsi_probe(device_t dev) +{ + struct twsi_softc *sc; + + sc = device_get_softc(dev); + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + sc->reg_data = TWSI_DATA; + sc->reg_slave_addr = TWSI_ADDR; + sc->reg_slave_ext_addr = TWSI_XADDR; + sc->reg_control = TWSI_CNTR; + sc->reg_status = TWSI_STAT; + sc->reg_baud_rate = TWSI_BAUD_RATE; + sc->reg_soft_reset = TWSI_SRST; + + device_set_desc(dev, "Marvell Integrated I2C Bus Controller"); + return (BUS_PROBE_DEFAULT); +} + +#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) +static void +mv_twsi_cal_baud_rate(const uint32_t target, struct twsi_baud_rate *rate) +{ + uint32_t clk, cur, diff, diff0; + int m, n, m0, n0; + + /* Calculate baud rate. */ + m0 = n0 = 4; /* Default values on reset */ + diff0 = 0xffffffff; + clk = get_tclk(); + + for (n = 0; n < 8; n++) { + for (m = 0; m < 16; m++) { + cur = TWSI_BAUD_RATE_RAW(clk,m,n); + diff = ABSSUB(target, cur); + if (diff < diff0) { + m0 = m; + n0 = n; + diff0 = diff; + } + } + } + rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); + rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); + rate->m = m0; + rate->n = n0; +} + +static int +mv_twsi_attach(device_t dev) +{ + struct twsi_softc *sc; + phandle_t child, iicbusnode; + device_t childdev; + struct iicbus_ivar *devi; + char dname[32]; /* 32 is taken from struct u_device */ + uint32_t paddr; + int len, error, ret; + + sc = device_get_softc(dev); + + mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &sc->baud_rate[IIC_SLOW]); + mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &sc->baud_rate[IIC_FAST]); + if (bootverbose) + device_printf(dev, "calculated baud rates are:\n" + " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n" + " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n", + sc->baud_rate[IIC_SLOW].raw / 1000, + sc->baud_rate[IIC_SLOW].m, + sc->baud_rate[IIC_SLOW].n, + sc->baud_rate[IIC_FAST].raw / 1000, + sc->baud_rate[IIC_FAST].m, + sc->baud_rate[IIC_FAST].n); + + + ret = twsi_attach(dev); + if (ret != 0) + return (ret); + + iicbusnode = 0; + /* Find iicbus as the child devices in the device tree. */ + for (child = OF_child(ofw_bus_get_node(dev)); child != 0; + child = OF_peer(child)) { + len = OF_getproplen(child, "model"); + if (len <= 0 || len > sizeof(dname)) + continue; + error = OF_getprop(child, "model", &dname, len); + if (error == -1) + continue; + len = strlen(dname); + if (len == strlen(IICBUS_DEVNAME) && + strncasecmp(dname, IICBUS_DEVNAME, len) == 0) { + iicbusnode = child; + break; + } + } + if (iicbusnode == 0) + goto attach_end; + + /* Attach child devices onto iicbus. */ + for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { + /* Get slave address. */ + error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); + if (error == -1) + error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); + if (error == -1) + continue; + + /* Get device driver name. */ + len = OF_getproplen(child, "model"); + if (len <= 0 || len > sizeof(dname)) + continue; + OF_getprop(child, "model", &dname, len); + + if (bootverbose) + device_printf(dev, "adding a device %s at %d.\n", + dname, fdt32_to_cpu(paddr)); + childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); + devi = IICBUS_IVAR(childdev); + devi->addr = fdt32_to_cpu(paddr); + } + +attach_end: + bus_generic_attach(sc->iicbus); + + return (0); +} diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c index e0290a86121c..c02cb8153bb1 100644 --- a/sys/dev/iicbus/twsi/twsi.c +++ b/sys/dev/iicbus/twsi/twsi.c @@ -31,7 +31,7 @@ /* * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell - * SoCs. Supports master operation only, and works in polling mode. + * and Allwinner SoCs. Supports master operation only, and works in polling mode. * * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices". @@ -62,156 +62,75 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include "iicbus_if.h" -#define MV_TWSI_NAME "twsi" -#define IICBUS_DEVNAME "iicbus" +#define TWSI_CONTROL_ACK (1 << 2) +#define TWSI_CONTROL_IFLG (1 << 3) +#define TWSI_CONTROL_STOP (1 << 4) +#define TWSI_CONTROL_START (1 << 5) +#define TWSI_CONTROL_TWSIEN (1 << 6) +#define TWSI_CONTROL_INTEN (1 << 7) -#define TWSI_SLAVE_ADDR 0x00 -#define TWSI_EXT_SLAVE_ADDR 0x10 -#define TWSI_DATA 0x04 +#define TWSI_STATUS_START 0x08 +#define TWSI_STATUS_RPTD_START 0x10 +#define TWSI_STATUS_ADDR_W_ACK 0x18 +#define TWSI_STATUS_DATA_WR_ACK 0x28 +#define TWSI_STATUS_ADDR_R_ACK 0x40 +#define TWSI_STATUS_DATA_RD_ACK 0x50 +#define TWSI_STATUS_DATA_RD_NOACK 0x58 -#define TWSI_CONTROL 0x08 -#define TWSI_CONTROL_ACK (1 << 2) -#define TWSI_CONTROL_IFLG (1 << 3) -#define TWSI_CONTROL_STOP (1 << 4) -#define TWSI_CONTROL_START (1 << 5) -#define TWSI_CONTROL_TWSIEN (1 << 6) -#define TWSI_CONTROL_INTEN (1 << 7) - -#define TWSI_STATUS 0x0c -#define TWSI_STATUS_START 0x08 -#define TWSI_STATUS_RPTD_START 0x10 -#define TWSI_STATUS_ADDR_W_ACK 0x18 -#define TWSI_STATUS_DATA_WR_ACK 0x28 -#define TWSI_STATUS_ADDR_R_ACK 0x40 -#define TWSI_STATUS_DATA_RD_ACK 0x50 -#define TWSI_STATUS_DATA_RD_NOACK 0x58 - -#define TWSI_BAUD_RATE 0x0c -#define TWSI_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) -#define TWSI_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) -#define TWSI_BAUD_RATE_SLOW 50000 /* 50kHz */ -#define TWSI_BAUD_RATE_FAST 100000 /* 100kHz */ - -#define TWSI_SOFT_RESET 0x1c - -#define TWSI_DEBUG +#define TWSI_DEBUG #undef TWSI_DEBUG -#ifdef TWSI_DEBUG -#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) +#ifdef TWSI_DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) #else -#define debugf(fmt, args...) +#define debugf(fmt, args...) #endif -struct mv_twsi_softc { - device_t dev; - struct resource *res[1]; /* SYS_RES_MEMORY */ - struct mtx mutex; - device_t iicbus; -}; - -static struct mv_twsi_baud_rate { - uint32_t raw; - int param; - int m; - int n; -} baud_rate[IIC_FASTEST + 1]; - -static int mv_twsi_probe(device_t); -static int mv_twsi_attach(device_t); -static int mv_twsi_detach(device_t); - -static int mv_twsi_reset(device_t dev, u_char speed, u_char addr, - u_char *oldaddr); -static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout); -static int mv_twsi_start(device_t dev, u_char slave, int timeout); -static int mv_twsi_stop(device_t dev); -static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, - int delay); -static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent, - int timeout); - static struct resource_spec res_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { -1, 0 } }; -static struct ofw_compat_data compat_data[] = { - { "mrvl,twsi", true }, - { "marvell,mv64xxx-i2c", true }, - { NULL, false } -}; - -static device_method_t mv_twsi_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, mv_twsi_probe), - DEVMETHOD(device_attach, mv_twsi_attach), - DEVMETHOD(device_detach, mv_twsi_detach), - - /* iicbus interface */ - DEVMETHOD(iicbus_callback, iicbus_null_callback), - DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start), - DEVMETHOD(iicbus_start, mv_twsi_start), - DEVMETHOD(iicbus_stop, mv_twsi_stop), - DEVMETHOD(iicbus_write, mv_twsi_write), - DEVMETHOD(iicbus_read, mv_twsi_read), - DEVMETHOD(iicbus_reset, mv_twsi_reset), - DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), - { 0, 0 } -}; - -static devclass_t mv_twsi_devclass; - -static driver_t mv_twsi_driver = { - MV_TWSI_NAME, - mv_twsi_methods, - sizeof(struct mv_twsi_softc), -}; - -DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0); -DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0); -MODULE_DEPEND(twsi, iicbus, 1, 1, 1); - static __inline uint32_t -TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off) +TWSI_READ(struct twsi_softc *sc, bus_size_t off) { return (bus_read_4(sc->res[0], off)); } static __inline void -TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val) +TWSI_WRITE(struct twsi_softc *sc, bus_size_t off, uint32_t val) { bus_write_4(sc->res[0], off, val); } static __inline void -twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask) +twsi_control_clear(struct twsi_softc *sc, uint32_t mask) { uint32_t val; - val = TWSI_READ(sc, TWSI_CONTROL); + val = TWSI_READ(sc, sc->reg_control); val &= ~mask; - TWSI_WRITE(sc, TWSI_CONTROL, val); + TWSI_WRITE(sc, sc->reg_control, val); } static __inline void -twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask) +twsi_control_set(struct twsi_softc *sc, uint32_t mask) { uint32_t val; - val = TWSI_READ(sc, TWSI_CONTROL); + val = TWSI_READ(sc, sc->reg_control); val |= mask; - TWSI_WRITE(sc, TWSI_CONTROL, val); + TWSI_WRITE(sc, sc->reg_control, val); } static __inline void -twsi_clear_iflg(struct mv_twsi_softc *sc) +twsi_clear_iflg(struct twsi_softc *sc) { DELAY(1000); @@ -227,11 +146,11 @@ twsi_clear_iflg(struct mv_twsi_softc *sc) * non-zero on timeout */ static int -twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask) +twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask) { timeout /= 10; - while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) { + while (!(TWSI_READ(sc, sc->reg_control) & mask)) { DELAY(10); if (--timeout < 0) return (timeout); @@ -247,7 +166,7 @@ twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask) * or TWSI_STATUS_RPTD_START */ static int -twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, +twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, u_char slave, int timeout) { int read_access, iflg_set = 0; @@ -257,7 +176,7 @@ twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, if (mask == TWSI_STATUS_RPTD_START) /* read IFLG to know if it should be cleared later; from NBSD */ - iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG; + iflg_set = TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG; twsi_control_set(sc, TWSI_CONTROL_START); @@ -278,14 +197,14 @@ twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, return (IIC_ETIMEOUT); } - status = TWSI_READ(sc, TWSI_STATUS); + status = TWSI_READ(sc, sc->reg_status); if (status != mask) { debugf("wrong status (%02x) after sending %sSTART condition\n", status, mask == TWSI_STATUS_START ? "" : "repeated "); return (IIC_ESTATUS); } - TWSI_WRITE(sc, TWSI_DATA, slave); + TWSI_WRITE(sc, sc->reg_data, slave); DELAY(1000); twsi_clear_iflg(sc); @@ -295,7 +214,7 @@ twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, } read_access = (slave & 0x1) ? 1 : 0; - status = TWSI_READ(sc, TWSI_STATUS); + status = TWSI_READ(sc, sc->reg_status); if (status != (read_access ? TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) { debugf("no ACK (status: %02x) after sending slave address\n", @@ -306,172 +225,13 @@ twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, return (IIC_NOERR); } -static int -mv_twsi_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) - return (ENXIO); - - device_set_desc(dev, "Marvell Integrated I2C Bus Controller"); - return (BUS_PROBE_DEFAULT); -} - -#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) -static void -mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate) -{ - uint32_t clk, cur, diff, diff0; - int m, n, m0, n0; - - /* Calculate baud rate. */ - m0 = n0 = 4; /* Default values on reset */ - diff0 = 0xffffffff; - clk = get_tclk(); - - for (n = 0; n < 8; n++) { - for (m = 0; m < 16; m++) { - cur = TWSI_BAUD_RATE_RAW(clk,m,n); - diff = ABSSUB(target, cur); - if (diff < diff0) { - m0 = m; - n0 = n; - diff0 = diff; - } - } - } - rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); - rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); - rate->m = m0; - rate->n = n0; -} - -static int -mv_twsi_attach(device_t dev) -{ - struct mv_twsi_softc *sc; - phandle_t child, iicbusnode; - device_t childdev; - struct iicbus_ivar *devi; - char dname[32]; /* 32 is taken from struct u_device */ - uint32_t paddr; - int len, error; - - sc = device_get_softc(dev); - sc->dev = dev; - bzero(baud_rate, sizeof(baud_rate)); - - mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF); - - /* Allocate IO resources */ - if (bus_alloc_resources(dev, res_spec, sc->res)) { - device_printf(dev, "could not allocate resources\n"); - mv_twsi_detach(dev); - return (ENXIO); - } - - mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]); - mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]); - if (bootverbose) - device_printf(dev, "calculated baud rates are:\n" - " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n" - " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n", - baud_rate[IIC_SLOW].raw / 1000, - baud_rate[IIC_SLOW].m, - baud_rate[IIC_SLOW].n, - baud_rate[IIC_FAST].raw / 1000, - baud_rate[IIC_FAST].m, - baud_rate[IIC_FAST].n); - - sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1); - if (sc->iicbus == NULL) { - device_printf(dev, "could not add iicbus child\n"); - mv_twsi_detach(dev); - return (ENXIO); - } - /* Attach iicbus. */ - bus_generic_attach(dev); - - iicbusnode = 0; - /* Find iicbus as the child devices in the device tree. */ - for (child = OF_child(ofw_bus_get_node(dev)); child != 0; - child = OF_peer(child)) { - len = OF_getproplen(child, "model"); - if (len <= 0 || len > sizeof(dname)) - continue; - error = OF_getprop(child, "model", &dname, len); - if (error == -1) - continue; - len = strlen(dname); - if (len == strlen(IICBUS_DEVNAME) && - strncasecmp(dname, IICBUS_DEVNAME, len) == 0) { - iicbusnode = child; - break; - } - } - if (iicbusnode == 0) - goto attach_end; - - /* Attach child devices onto iicbus. */ - for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { - /* Get slave address. */ - error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); - if (error == -1) - error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); - if (error == -1) - continue; - - /* Get device driver name. */ - len = OF_getproplen(child, "model"); - if (len <= 0 || len > sizeof(dname)) - continue; - OF_getprop(child, "model", &dname, len); - - if (bootverbose) - device_printf(dev, "adding a device %s at %d.\n", - dname, fdt32_to_cpu(paddr)); - childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); - devi = IICBUS_IVAR(childdev); - devi->addr = fdt32_to_cpu(paddr); - } - -attach_end: - bus_generic_attach(sc->iicbus); - - return (0); -} - -static int -mv_twsi_detach(device_t dev) -{ - struct mv_twsi_softc *sc; - int rv; - - sc = device_get_softc(dev); - - if ((rv = bus_generic_detach(dev)) != 0) - return (rv); - - if (sc->iicbus != NULL) - if ((rv = device_delete_child(dev, sc->iicbus)) != 0) - return (rv); - - bus_release_resources(dev, res_spec, sc->res); - - mtx_destroy(&sc->mutex); - return (0); -} - /* * Only slave mode supported, disregard [old]addr */ static int -mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) +twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) { - struct mv_twsi_softc *sc; + struct twsi_softc *sc; uint32_t param; sc = device_get_softc(dev); @@ -479,75 +239,30 @@ mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) switch (speed) { case IIC_SLOW: case IIC_FAST: - param = baud_rate[speed].param; + param = sc->baud_rate[speed].param; break; case IIC_FASTEST: case IIC_UNKNOWN: default: - param = baud_rate[IIC_FAST].param; + param = sc->baud_rate[IIC_FAST].param; break; } mtx_lock(&sc->mutex); - TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0); + TWSI_WRITE(sc, sc->reg_soft_reset, 0x0); DELAY(2000); - TWSI_WRITE(sc, TWSI_BAUD_RATE, param); - TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK); + TWSI_WRITE(sc, sc->reg_baud_rate, param); + TWSI_WRITE(sc, sc->reg_control, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK); DELAY(1000); mtx_unlock(&sc->mutex); return (0); } -/* - * timeout is given in us - */ static int -mv_twsi_repeated_start(device_t dev, u_char slave, int timeout) +twsi_stop(device_t dev) { - struct mv_twsi_softc *sc; - int rv; - - sc = device_get_softc(dev); - - mtx_lock(&sc->mutex); - rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, - timeout); - mtx_unlock(&sc->mutex); - - if (rv) { - mv_twsi_stop(dev); - return (rv); - } else - return (IIC_NOERR); -} - -/* - * timeout is given in us - */ -static int -mv_twsi_start(device_t dev, u_char slave, int timeout) -{ - struct mv_twsi_softc *sc; - int rv; - - sc = device_get_softc(dev); - - mtx_lock(&sc->mutex); - rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); - mtx_unlock(&sc->mutex); - - if (rv) { - mv_twsi_stop(dev); - return (rv); - } else - return (IIC_NOERR); -} - -static int -mv_twsi_stop(device_t dev) -{ - struct mv_twsi_softc *sc; + struct twsi_softc *sc; sc = device_get_softc(dev); @@ -560,10 +275,55 @@ mv_twsi_stop(device_t dev) return (IIC_NOERR); } +/* + * timeout is given in us + */ static int -mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) +twsi_repeated_start(device_t dev, u_char slave, int timeout) { - struct mv_twsi_softc *sc; + struct twsi_softc *sc; + int rv; + + sc = device_get_softc(dev); + + mtx_lock(&sc->mutex); + rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, + timeout); + mtx_unlock(&sc->mutex); + + if (rv) { + twsi_stop(dev); + return (rv); + } else + return (IIC_NOERR); +} + +/* + * timeout is given in us + */ +static int +twsi_start(device_t dev, u_char slave, int timeout) +{ + struct twsi_softc *sc; + int rv; + + sc = device_get_softc(dev); + + mtx_lock(&sc->mutex); + rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); + mtx_unlock(&sc->mutex); + + if (rv) { + twsi_stop(dev); + return (rv); + } else + return (IIC_NOERR); +} + +static int +twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) +{ + struct twsi_softc *sc; uint32_t status; int last_byte, rv; @@ -591,7 +351,7 @@ mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) goto out; } - status = TWSI_READ(sc, TWSI_STATUS); + status = TWSI_READ(sc, sc->reg_status); if (status != (last_byte ? TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) { debugf("wrong status (%02x) while reading\n", status); @@ -599,7 +359,7 @@ mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) goto out; } - *buf++ = TWSI_READ(sc, TWSI_DATA); + *buf++ = TWSI_READ(sc, sc->reg_data); (*read)++; } rv = IIC_NOERR; @@ -609,9 +369,9 @@ mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) } static int -mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) +twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) { - struct mv_twsi_softc *sc; + struct twsi_softc *sc; uint32_t status; int rv; @@ -620,7 +380,7 @@ mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) mtx_lock(&sc->mutex); *sent = 0; while (*sent < len) { - TWSI_WRITE(sc, TWSI_DATA, *buf++); + TWSI_WRITE(sc, sc->reg_data, *buf++); twsi_clear_iflg(sc); if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { @@ -629,7 +389,7 @@ mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) goto out; } - status = TWSI_READ(sc, TWSI_STATUS); + status = TWSI_READ(sc, sc->reg_status); if (status != TWSI_STATUS_DATA_WR_ACK) { debugf("wrong status (%02x) while writing\n", status); rv = IIC_ESTATUS; @@ -642,3 +402,81 @@ mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) mtx_unlock(&sc->mutex); return (rv); } + +int +twsi_attach(device_t dev) +{ + struct twsi_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + + mtx_init(&sc->mutex, device_get_nameunit(dev), "twsi", MTX_DEF); + + if (bus_alloc_resources(dev, res_spec, sc->res)) { + device_printf(dev, "could not allocate resources\n"); + twsi_detach(dev); + return (ENXIO); + } + + /* Attach the iicbus. */ + if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) { + device_printf(dev, "could not allocate iicbus instance\n"); + twsi_detach(dev); + return (ENXIO); + } + bus_generic_attach(dev); + + return (0); +} + +int +twsi_detach(device_t dev) +{ + struct twsi_softc *sc; + int rv; + + sc = device_get_softc(dev); + + if ((rv = bus_generic_detach(dev)) != 0) + return (rv); + + if (sc->iicbus != NULL) + if ((rv = device_delete_child(dev, sc->iicbus)) != 0) + return (rv); + + bus_release_resources(dev, res_spec, sc->res); + + mtx_destroy(&sc->mutex); + return (0); +} + +static device_method_t twsi_methods[] = { + /* device interface */ + DEVMETHOD(device_detach, twsi_detach), + + /* Bus interface */ + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + + /* iicbus interface */ + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_repeated_start, twsi_repeated_start), + DEVMETHOD(iicbus_start, twsi_start), + DEVMETHOD(iicbus_stop, twsi_stop), + DEVMETHOD(iicbus_write, twsi_write), + DEVMETHOD(iicbus_read, twsi_read), + DEVMETHOD(iicbus_reset, twsi_reset), + DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), + { 0, 0 } +}; + +DEFINE_CLASS_0(twsi, twsi_driver, twsi_methods, + sizeof(struct twsi_softc)); diff --git a/sys/dev/iicbus/twsi/twsi.h b/sys/dev/iicbus/twsi/twsi.h new file mode 100644 index 000000000000..a95db825f2c8 --- /dev/null +++ b/sys/dev/iicbus/twsi/twsi.h @@ -0,0 +1,67 @@ +/*- + * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. + * All rights reserved. + * + * Developed by Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _TWSI_H_ +#define _TWSI_H_ + +struct twsi_baud_rate { + uint32_t raw; + int param; + int m; + int n; +}; + +struct twsi_softc { + device_t dev; + struct resource *res[1]; /* SYS_RES_MEMORY */ + struct mtx mutex; + device_t iicbus; + + bus_size_t reg_data; + bus_size_t reg_slave_addr; + bus_size_t reg_slave_ext_addr; + bus_size_t reg_control; + bus_size_t reg_status; + bus_size_t reg_baud_rate; + bus_size_t reg_soft_reset; + struct twsi_baud_rate baud_rate[IIC_FASTEST + 1]; +}; + +DECLARE_CLASS(twsi_driver); + +#define TWSI_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) + +int twsi_attach(device_t); +int twsi_detach(device_t); + +#endif /* _TWSI_H_ */ From c2849e3c1168f3bcac6db908cd9096dc77f3af57 Mon Sep 17 00:00:00 2001 From: Svatopluk Kraus Date: Mon, 15 Feb 2016 15:28:56 +0000 Subject: [PATCH 131/142] Initial OMAP4 WUGEN pass-through driver. SPI interrupts are passed through WUGEN to GIC. Hardware initialization is left in state after reset as well as before. This is needed after an update of Linux dts files. --- sys/arm/ti/omap4/files.omap4 | 1 + sys/arm/ti/omap4/omap4_wugen.c | 228 +++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 sys/arm/ti/omap4/omap4_wugen.c diff --git a/sys/arm/ti/omap4/files.omap4 b/sys/arm/ti/omap4/files.omap4 index 36e41fc5e502..1f331fc9066c 100644 --- a/sys/arm/ti/omap4/files.omap4 +++ b/sys/arm/ti/omap4/files.omap4 @@ -12,6 +12,7 @@ arm/ti/omap4/omap4_l2cache.c optional pl310 arm/ti/omap4/omap4_prcm_clks.c standard arm/ti/omap4/omap4_scm_padconf.c standard arm/ti/omap4/omap4_mp.c optional smp +arm/ti/omap4/omap4_wugen.c standard arm/ti/twl/twl.c optional twl arm/ti/twl/twl_vreg.c optional twl twl_vreg diff --git a/sys/arm/ti/omap4/omap4_wugen.c b/sys/arm/ti/omap4/omap4_wugen.c new file mode 100644 index 000000000000..2b24eaf463e5 --- /dev/null +++ b/sys/arm/ti/omap4/omap4_wugen.c @@ -0,0 +1,228 @@ +/*- + * Copyright (c) 2016 Svatopluk Kraus + * Copyright (c) 2016 Michal Meloun + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "pic_if.h" + +static struct ofw_compat_data compat_data[] = { + {"ti,omap4-wugen-mpu", 1}, + {NULL, 0} +}; + +struct omap4_wugen_sc { + device_t sc_dev; + struct resource *sc_mem_res; + device_t sc_parent; +}; + +static int +omap4_wugen_register(device_t dev, struct intr_irqsrc *isrc, + boolean_t *is_percpu) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + return (PIC_REGISTER(sc->sc_parent, isrc, is_percpu)); +} + +static int +omap4_wugen_unregister(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + return (PIC_UNREGISTER(sc->sc_parent, isrc)); +} + +static void +omap4_wugen_enable_source(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_ENABLE_SOURCE(sc->sc_parent, isrc); +} + +static void +omap4_wugen_disable_source(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_DISABLE_SOURCE(sc->sc_parent, isrc); +} + +static void +omap4_wugen_enable_intr(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_ENABLE_INTR(sc->sc_parent, isrc); +} + +static void +omap4_wugen_pre_ithread(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_PRE_ITHREAD(sc->sc_parent, isrc); +} + + +static void +omap4_wugen_post_ithread(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_POST_ITHREAD(sc->sc_parent, isrc); +} + +static void +omap4_wugen_post_filter(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + PIC_POST_FILTER(sc->sc_parent, isrc); +} + +#ifdef SMP +static int +omap4_wugen_bind(device_t dev, struct intr_irqsrc *isrc) +{ + struct omap4_wugen_sc *sc = device_get_softc(dev); + + return (PIC_BIND(sc->sc_parent, isrc)); +} +#endif + +static int +omap4_wugen_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + return (BUS_PROBE_DEFAULT); +} + +static int +omap4_wugen_detach(device_t dev) +{ + struct omap4_wugen_sc *sc; + + sc = device_get_softc(dev); + if (sc->sc_mem_res != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + sc->sc_mem_res = NULL; + } + return (0); +} + +static int +omap4_wugen_attach(device_t dev) +{ + struct omap4_wugen_sc *sc; + phandle_t node; + phandle_t parent_xref; + int rid, rv; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + node = ofw_bus_get_node(dev); + + rv = OF_getencprop(node, "interrupt-parent", &parent_xref, + sizeof(parent_xref)); + if (rv <= 0) { + device_printf(dev, "can't read parent node property\n"); + goto fail; + } + sc->sc_parent = OF_device_from_xref(parent_xref); + if (sc->sc_parent == NULL) { + device_printf(dev, "can't find parent controller\n"); + goto fail; + } + + rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->sc_mem_res == NULL) { + device_printf(dev, "can't allocate resources\n"); + return (ENXIO); + } + + if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { + device_printf(dev, "can't register PIC\n"); + goto fail; + } + return (0); + +fail: + omap4_wugen_detach(dev); + return (ENXIO); +} + +static device_method_t omap4_wugen_methods[] = { + DEVMETHOD(device_probe, omap4_wugen_probe), + DEVMETHOD(device_attach, omap4_wugen_attach), + DEVMETHOD(device_detach, omap4_wugen_detach), + + /* Interrupt controller interface */ + DEVMETHOD(pic_register, omap4_wugen_register), + DEVMETHOD(pic_unregister, omap4_wugen_unregister), + DEVMETHOD(pic_enable_source, omap4_wugen_enable_source), + DEVMETHOD(pic_disable_source, omap4_wugen_disable_source), + DEVMETHOD(pic_enable_intr, omap4_wugen_enable_intr), + DEVMETHOD(pic_pre_ithread, omap4_wugen_pre_ithread), + DEVMETHOD(pic_post_ithread, omap4_wugen_post_ithread), + DEVMETHOD(pic_post_filter, omap4_wugen_post_filter), +#ifdef SMP + DEVMETHOD(pic_bind, omap4_wugen_bind), +#endif + DEVMETHOD_END +}; +devclass_t omap4_wugen_devclass; +DEFINE_CLASS_0(omap4_wugen, omap4_wugen_driver, omap4_wugen_methods, + sizeof(struct omap4_wugen_sc)); +EARLY_DRIVER_MODULE(omap4_wugen, simplebus, omap4_wugen_driver, + omap4_wugen_devclass, NULL, NULL, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE + 1); From 0df627dc54c8c7a1fb01a72667a389c714761b1a Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 16:55:44 +0000 Subject: [PATCH 132/142] Remove an unused static inline function. Sponsored by: ABT Systems Ltd --- sys/arm/arm/syscall.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sys/arm/arm/syscall.c b/sys/arm/arm/syscall.c index 061fda4fff1f..1ff48abd22e8 100644 --- a/sys/arm/arm/syscall.c +++ b/sys/arm/arm/syscall.c @@ -98,17 +98,6 @@ __FBSDID("$FreeBSD$"); void swi_handler(struct trapframe *); -static __inline void -call_trapsignal(struct thread *td, int sig, u_long code) -{ - ksiginfo_t ksi; - - ksiginfo_init_trap(&ksi); - ksi.ksi_signo = sig; - ksi.ksi_code = (int)code; - trapsignal(td, &ksi); -} - int cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) { From 96922be6b5ec14da450a281d32a3c8f7d7e918b0 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 17:05:03 +0000 Subject: [PATCH 133/142] Remove an unused FDT header, fdt_common.h should only be needed in a few places, mostly in sys/dev/fdt and legacy code. Sponsored by: ABT Systems Ltd --- sys/kern/subr_intr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 9e7fcaf422d8..7b5b77d58e6d 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -64,8 +64,6 @@ __FBSDID("$FreeBSD$"); #include #include #include - -#include #endif #ifdef DDB From 740be1dc584d14c781252d4c2de62e31a795ce28 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 17:14:10 +0000 Subject: [PATCH 134/142] Fix the spelling of OF_getencprop. It will fix the data correctly for the endian of the CPU so there is no need to call fdt32_to_cpu. Sponsored by: ABT Systems Ltd --- sys/dev/iicbus/twsi/mv_twsi.c | 9 ++++----- sys/dev/iicbus/twsi/twsi.c | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sys/dev/iicbus/twsi/mv_twsi.c b/sys/dev/iicbus/twsi/mv_twsi.c index db27366892eb..998a1978d37e 100644 --- a/sys/dev/iicbus/twsi/mv_twsi.c +++ b/sys/dev/iicbus/twsi/mv_twsi.c @@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include @@ -225,9 +224,9 @@ mv_twsi_attach(device_t dev) /* Attach child devices onto iicbus. */ for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { /* Get slave address. */ - error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); + error = OF_getencprop(child, "i2c-address", &paddr, sizeof(paddr)); if (error == -1) - error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); + error = OF_getencprop(child, "reg", &paddr, sizeof(paddr)); if (error == -1) continue; @@ -239,10 +238,10 @@ mv_twsi_attach(device_t dev) if (bootverbose) device_printf(dev, "adding a device %s at %d.\n", - dname, fdt32_to_cpu(paddr)); + dname, paddr); childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); devi = IICBUS_IVAR(childdev); - devi->addr = fdt32_to_cpu(paddr); + devi->addr = paddr; } attach_end: diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c index c02cb8153bb1..1b27956a0700 100644 --- a/sys/dev/iicbus/twsi/twsi.c +++ b/sys/dev/iicbus/twsi/twsi.c @@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include From 2082bf26c8702c3a464fe9145f13d1e5a4df84b2 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 15 Feb 2016 18:13:33 +0000 Subject: [PATCH 135/142] fputs: Return the number of bytes written. POSIX.1-2008 requires that successful completion simply return a non-negative integer. We have regularly returned a constant value. Another, equally valid, implementation convention implies returning the number of bytes written. Adopt this last convention to be in line with what Apple's libc does. POSIX also explicitly notes: Note that this implementation convention cannot be adhered to for strings longer than {INT_MAX} bytes as the value would not be representable in the return type of the function. For backwards-compatibility, implementations can return the number of bytes for strings of up to {INT_MAX} bytes, and return {INT_MAX} for all longer strings. Developers shouldn't depend specifically on either convention but the change may help port software from Apple. Differential Revision: https://reviews.freebsd.org/D442 (Partial) Obtained from: Apple Inc. (Libc 997.90.3 with changes) Relnotes: yes --- lib/libc/stdio/fputs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c index 32e57645f56a..d01097937583 100644 --- a/lib/libc/stdio/fputs.c +++ b/lib/libc/stdio/fputs.c @@ -37,6 +37,7 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include #include #include #include "un-namespace.h" @@ -62,5 +63,7 @@ fputs(const char * __restrict s, FILE * __restrict fp) ORIENT(fp, -1); retval = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); + if (retval == 0) + return (iov.iov_len > INT_MAX ? INT_MAX : uio.uio_resid); return (retval); } From 20055d7691836ae1b455e37e6afda9c101f56f98 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 15 Feb 2016 18:14:21 +0000 Subject: [PATCH 136/142] getln: We cannot expand the buffer beyond INT_MAX. In such cases return ENOMEM. This is a limitation of our implementation, alternatively you may consider getline(3). Differential Revision: https://reviews.freebsd.org/D442 (Partial) Obtained from: Apple Inc. (Libc 997.90.3) Relnotes: yes --- lib/libc/stdio/fgetln.3 | 5 ++++- lib/libc/stdio/fgetln.c | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3 index 4b83664d0338..7d4b89a5a06f 100644 --- a/lib/libc/stdio/fgetln.3 +++ b/lib/libc/stdio/fgetln.3 @@ -28,7 +28,7 @@ .\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd April 19, 1994 +.Dd February 15, 2016 .Dt FGETLN 3 .Os .Sh NAME @@ -97,6 +97,9 @@ These changes are lost as soon as the pointer becomes invalid. The argument .Fa stream is not a stream open for reading. +.It Bq Er ENOMEM +The internal line buffer could not be expanded due to lack of available memory, +or because it would need to expand beyond INT_MAX in size. .El .Pp The diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c index 1779de2ae559..1509bc880a4a 100644 --- a/lib/libc/stdio/fgetln.c +++ b/lib/libc/stdio/fgetln.c @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include +#include #include #include #include @@ -61,6 +63,10 @@ __slbexpand(FILE *fp, size_t newsize) #endif if (fp->_lb._size >= newsize) return (0); + if (newsize > INT_MAX) { + errno = ENOMEM; + return (-1); + } if ((p = realloc(fp->_lb._base, newsize)) == NULL) return (-1); fp->_lb._base = p; @@ -152,13 +158,14 @@ fgetln(FILE *fp, size_t *lenp) } *lenp = len; #ifdef notdef - fp->_lb._base[len] = 0; + fp->_lb._base[len] = '\0'; #endif FUNLOCKFILE(fp); return ((char *)fp->_lb._base); error: *lenp = 0; /* ??? */ + fp->_flags |= __SERR; FUNLOCKFILE(fp); return (NULL); /* ??? */ } From 4d1defda24fc358f7b95e515083a4c39c4172241 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 19:14:24 +0000 Subject: [PATCH 137/142] Set sc->clkfreq removed in r295470 Reported by: Jared McNeill Pointy-hat to: andrew --- sys/arm/arm/generic_timer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c index 973920817014..84e2cc3b4369 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -363,6 +363,8 @@ arm_tmr_attach(device_t dev) if (node > 0) { error = OF_getencprop(node, "clock-frequency", &clock, sizeof(clock)); + if (error > 0) + sc->clkfreq = clock; } #endif From 2ff143af3faaa22d99ed52e7cc85c3f06a5d5905 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 19:31:23 +0000 Subject: [PATCH 138/142] Add support for the AXP209 Power System Management IC. This allows boards with this and an Allwinner SoC to power off. Submitted by: Emmanuel Vadot Differential Revision: https://reviews.freebsd.org/D4954 --- sys/arm/allwinner/axp209.c | 182 ++++++++++++++++++++++++++++++ sys/arm/allwinner/files.allwinner | 1 + 2 files changed, 183 insertions(+) create mode 100644 sys/arm/allwinner/axp209.c diff --git a/sys/arm/allwinner/axp209.c b/sys/arm/allwinner/axp209.c new file mode 100644 index 000000000000..11479fa6f59f --- /dev/null +++ b/sys/arm/allwinner/axp209.c @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 2015 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); +/* +* X-Power AXP209 PMU for Allwinner SoCs +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "iicbus_if.h" + +/* Power State Register */ +#define AXP209_PSR 0x00 +#define AXP209_PSR_ACIN 0x80 +#define AXP209_PSR_VBUS 0x20 + +/* Shutdown and battery control */ +#define AXP209_SHUTBAT 0x32 +#define AXP209_SHUTBAT_SHUTDOWN 0x80 + +struct axp209_softc { + uint32_t addr; + struct intr_config_hook enum_hook; +}; + +static int +axp209_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) +{ + struct axp209_softc *sc = device_get_softc(dev); + struct iic_msg msg[2]; + + msg[0].slave = sc->addr; + msg[0].flags = IIC_M_WR; + msg[0].len = 1; + msg[0].buf = ® + + msg[1].slave = sc->addr; + msg[1].flags = IIC_M_RD; + msg[1].len = size; + msg[1].buf = data; + + return (iicbus_transfer(dev, msg, 2)); +} + +static int +axp209_write(device_t dev, uint8_t reg, uint8_t data) +{ + uint8_t buffer[2]; + struct axp209_softc *sc = device_get_softc(dev); + struct iic_msg msg; + + buffer[0] = reg; + buffer[1] = data; + + msg.slave = sc->addr; + msg.flags = IIC_M_WR; + msg.len = 2; + msg.buf = buffer; + + return (iicbus_transfer(dev, &msg, 1)); +} + +static void +axp209_shutdown(void *devp, int howto) +{ + device_t dev; + + if (!(howto & RB_POWEROFF)) + return; + dev = (device_t)devp; + + if (bootverbose) + device_printf(dev, "Shutdown AXP209\n"); + + axp209_write(dev, AXP209_SHUTBAT, AXP209_SHUTBAT_SHUTDOWN); +} + +static int +axp209_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "x-powers,axp209")) + return (ENXIO); + + device_set_desc(dev, "X-Power AXP209 Power Management Unit"); + + return (BUS_PROBE_DEFAULT); +} + +static int +axp209_attach(device_t dev) +{ + struct axp209_softc *sc; + uint8_t data; + uint8_t pwr_src; + char pwr_name[4][11] = {"Battery", "AC", "USB", "AC and USB"}; + + sc = device_get_softc(dev); + + sc->addr = iicbus_get_addr(dev); + + /* + * Read the Power State register + * bit 7 is AC presence, bit 5 is VBUS presence. + * If none are set then we are running from battery (obviously). + */ + axp209_read(dev, AXP209_PSR, &data, 1); + pwr_src = ((data & AXP209_PSR_ACIN) >> 7) | + ((data & AXP209_PSR_VBUS) >> 4); + + if (bootverbose) + device_printf(dev, "AXP209 Powered by %s\n", + pwr_name[pwr_src]); + + EVENTHANDLER_REGISTER(shutdown_final, axp209_shutdown, dev, + SHUTDOWN_PRI_LAST); + + return (0); +} + +static device_method_t axp209_methods[] = { + DEVMETHOD(device_probe, axp209_probe), + DEVMETHOD(device_attach, axp209_attach), + {0, 0}, +}; + +static driver_t axp209_driver = { + "axp209_pmu", + axp209_methods, + sizeof(struct axp209_softc), +}; + +static devclass_t axp209_devclass; + +DRIVER_MODULE(axp209, iicbus, axp209_driver, axp209_devclass, 0, 0); +MODULE_VERSION(axp209, 1); +MODULE_DEPEND(axp209, iicbus, 1, 1, 1); diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index 2db0da5dc424..cc4dd4832c56 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -11,6 +11,7 @@ arm/allwinner/a10_sramc.c standard arm/allwinner/a10_wdog.c standard arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/allwinner_machdep.c standard +arm/allwinner/axp209.c optional axp209 arm/allwinner/if_emac.c optional emac dev/iicbus/twsi/a10_twsi.c optional twsi #arm/allwinner/console.c standard From 501ce0d86b0f5cb82b3ba7a50bf0be80692cac80 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 15 Feb 2016 19:56:35 +0000 Subject: [PATCH 139/142] Add support for the Allwinner DMA controller. This will be used by the at least the audio codec driver currently in review. Submitted by: Jared McNeill Differential Revision: https://reviews.freebsd.org/D5050 --- sys/arm/allwinner/a10_dmac.c | 453 ++++++++++++++++++++++++++++ sys/arm/allwinner/a10_dmac.h | 158 ++++++++++ sys/arm/allwinner/files.allwinner | 2 + sys/arm/allwinner/sunxi_dma_if.m | 98 ++++++ sys/arm/conf/A10 | 1 + sys/arm/conf/A20 | 1 + sys/boot/fdt/dts/arm/sun7i-a20.dtsi | 7 + 7 files changed, 720 insertions(+) create mode 100644 sys/arm/allwinner/a10_dmac.c create mode 100644 sys/arm/allwinner/a10_dmac.h create mode 100644 sys/arm/allwinner/sunxi_dma_if.m diff --git a/sys/arm/allwinner/a10_dmac.c b/sys/arm/allwinner/a10_dmac.c new file mode 100644 index 000000000000..fefe27dc3d87 --- /dev/null +++ b/sys/arm/allwinner/a10_dmac.c @@ -0,0 +1,453 @@ +/*- + * Copyright (c) 2014-2016 Jared D. McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * Allwinner A10/A20 DMA controller + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include "sunxi_dma_if.h" + +#define NDMA_CHANNELS 8 +#define DDMA_CHANNELS 8 + +enum a10dmac_type { + CH_NDMA, + CH_DDMA +}; + +struct a10dmac_softc; + +struct a10dmac_channel { + struct a10dmac_softc * ch_sc; + uint8_t ch_index; + enum a10dmac_type ch_type; + void (*ch_callback)(void *); + void * ch_callbackarg; + uint32_t ch_regoff; +}; + +struct a10dmac_softc { + struct resource * sc_res[2]; + struct mtx sc_mtx; + void * sc_ih; + + struct a10dmac_channel sc_ndma_channels[NDMA_CHANNELS]; + struct a10dmac_channel sc_ddma_channels[DDMA_CHANNELS]; +}; + +static struct resource_spec a10dmac_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { -1, 0 } +}; + +#define DMA_READ(sc, reg) bus_read_4((sc)->sc_res[0], (reg)) +#define DMA_WRITE(sc, reg, val) bus_write_4((sc)->sc_res[0], (reg), (val)) +#define DMACH_READ(ch, reg) \ + DMA_READ((ch)->ch_sc, (reg) + (ch)->ch_regoff) +#define DMACH_WRITE(ch, reg, val) \ + DMA_WRITE((ch)->ch_sc, (reg) + (ch)->ch_regoff, (val)) + +static void a10dmac_intr(void *); + +static int +a10dmac_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-dma")) + return (ENXIO); + + device_set_desc(dev, "Allwinner DMA controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +a10dmac_attach(device_t dev) +{ + struct a10dmac_softc *sc; + unsigned int index; + int error; + + sc = device_get_softc(dev); + + if (bus_alloc_resources(dev, a10dmac_spec, sc->sc_res)) { + device_printf(dev, "cannot allocate resources for device\n"); + return (ENXIO); + } + + mtx_init(&sc->sc_mtx, "a10 dmac", NULL, MTX_SPIN); + + /* Activate DMA controller clock */ + a10_clk_dmac_activate(); + + /* Disable all interrupts and clear pending status */ + DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, 0); + DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, ~0); + + /* Initialize channels */ + for (index = 0; index < NDMA_CHANNELS; index++) { + sc->sc_ndma_channels[index].ch_sc = sc; + sc->sc_ndma_channels[index].ch_index = index; + sc->sc_ndma_channels[index].ch_type = CH_NDMA; + sc->sc_ndma_channels[index].ch_callback = NULL; + sc->sc_ndma_channels[index].ch_callbackarg = NULL; + sc->sc_ndma_channels[index].ch_regoff = AWIN_NDMA_REG(index); + DMACH_WRITE(&sc->sc_ndma_channels[index], AWIN_NDMA_CTL_REG, 0); + } + for (index = 0; index < DDMA_CHANNELS; index++) { + sc->sc_ddma_channels[index].ch_sc = sc; + sc->sc_ddma_channels[index].ch_index = index; + sc->sc_ddma_channels[index].ch_type = CH_DDMA; + sc->sc_ddma_channels[index].ch_callback = NULL; + sc->sc_ddma_channels[index].ch_callbackarg = NULL; + sc->sc_ddma_channels[index].ch_regoff = AWIN_DDMA_REG(index); + DMACH_WRITE(&sc->sc_ddma_channels[index], AWIN_DDMA_CTL_REG, 0); + } + + error = bus_setup_intr(dev, sc->sc_res[1], INTR_MPSAFE | INTR_TYPE_MISC, + NULL, a10dmac_intr, sc, &sc->sc_ih); + if (error != 0) { + device_printf(dev, "could not setup interrupt handler\n"); + bus_release_resources(dev, a10dmac_spec, sc->sc_res); + mtx_destroy(&sc->sc_mtx); + return (ENXIO); + } + + return (0); +} + +static void +a10dmac_intr(void *priv) +{ + struct a10dmac_softc *sc = priv; + uint32_t sta, bit, mask; + uint8_t index; + + sta = DMA_READ(sc, AWIN_DMA_IRQ_PEND_STA_REG); + DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, sta); + + while ((bit = ffs(sta & AWIN_DMA_IRQ_END_MASK)) != 0) { + mask = (1U << (bit - 1)); + sta &= ~mask; + /* + * Map status bit to channel number. The status register is + * encoded with two bits of status per channel (lowest bit + * is half transfer pending, highest bit is end transfer + * pending). The 8 normal DMA channel status are in the lower + * 16 bits and the 8 dedicated DMA channel status are in + * the upper 16 bits. The output is a channel number from 0-7. + */ + index = ((bit - 1) / 2) & 7; + if (mask & AWIN_DMA_IRQ_NDMA) { + if (sc->sc_ndma_channels[index].ch_callback == NULL) + continue; + sc->sc_ndma_channels[index].ch_callback( + sc->sc_ndma_channels[index].ch_callbackarg); + } else { + if (sc->sc_ddma_channels[index].ch_callback == NULL) + continue; + sc->sc_ddma_channels[index].ch_callback( + sc->sc_ddma_channels[index].ch_callbackarg); + } + } +} + +static uint32_t +a10dmac_read_ctl(struct a10dmac_channel *ch) +{ + if (ch->ch_type == CH_NDMA) { + return (DMACH_READ(ch, AWIN_NDMA_CTL_REG)); + } else { + return (DMACH_READ(ch, AWIN_DDMA_CTL_REG)); + } +} + +static void +a10dmac_write_ctl(struct a10dmac_channel *ch, uint32_t val) +{ + if (ch->ch_type == CH_NDMA) { + DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val); + } else { + DMACH_WRITE(ch, AWIN_DDMA_CTL_REG, val); + } +} + +static int +a10dmac_set_config(device_t dev, void *priv, const struct sunxi_dma_config *cfg) +{ + struct a10dmac_channel *ch = priv; + uint32_t val; + unsigned int dst_dw, dst_bl, dst_bs, dst_wc; + unsigned int src_dw, src_bl, src_bs, src_wc; + + switch (cfg->dst_width) { + case 8: + dst_dw = AWIN_DMA_CTL_DATA_WIDTH_8; + break; + case 16: + dst_dw = AWIN_DMA_CTL_DATA_WIDTH_16; + break; + case 32: + dst_dw = AWIN_DMA_CTL_DATA_WIDTH_32; + break; + default: + return (EINVAL); + } + switch (cfg->dst_burst_len) { + case 1: + dst_bl = AWIN_DMA_CTL_BURST_LEN_1; + break; + case 4: + dst_bl = AWIN_DMA_CTL_BURST_LEN_4; + break; + case 8: + dst_bl = AWIN_DMA_CTL_BURST_LEN_8; + break; + default: + return (EINVAL); + } + switch (cfg->src_width) { + case 8: + src_dw = AWIN_DMA_CTL_DATA_WIDTH_8; + break; + case 16: + src_dw = AWIN_DMA_CTL_DATA_WIDTH_16; + break; + case 32: + src_dw = AWIN_DMA_CTL_DATA_WIDTH_32; + break; + default: + return (EINVAL); + } + switch (cfg->src_burst_len) { + case 1: + src_bl = AWIN_DMA_CTL_BURST_LEN_1; + break; + case 4: + src_bl = AWIN_DMA_CTL_BURST_LEN_4; + break; + case 8: + src_bl = AWIN_DMA_CTL_BURST_LEN_8; + break; + default: + return (EINVAL); + } + + val = (dst_dw << AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT) | + (dst_bl << AWIN_DMA_CTL_DST_BURST_LEN_SHIFT) | + (cfg->dst_drqtype << AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT) | + (src_dw << AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT) | + (src_bl << AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT) | + (cfg->src_drqtype << AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT); + if (cfg->dst_noincr) { + val |= AWIN_NDMA_CTL_DST_ADDR_NOINCR; + } + if (cfg->src_noincr) { + val |= AWIN_NDMA_CTL_SRC_ADDR_NOINCR; + } + + if (ch->ch_type == CH_NDMA) { + DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val); + } else { + DMACH_WRITE(ch, AWIN_DDMA_CTL_REG, val); + + dst_bs = cfg->dst_blksize - 1; + dst_wc = cfg->dst_wait_cyc - 1; + src_bs = cfg->src_blksize - 1; + src_wc = cfg->src_wait_cyc - 1; + + DMACH_WRITE(ch, AWIN_DDMA_PARA_REG, + (dst_bs << AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT) | + (dst_wc << AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT) | + (src_bs << AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT) | + (src_wc << AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT)); + } + + return (0); +} + +static void * +a10dmac_alloc(device_t dev, bool dedicated, void (*cb)(void *), void *cbarg) +{ + struct a10dmac_softc *sc = device_get_softc(dev); + struct a10dmac_channel *ch_list; + struct a10dmac_channel *ch = NULL; + uint32_t irqen; + uint8_t ch_count, index; + + if (dedicated) { + ch_list = sc->sc_ddma_channels; + ch_count = DDMA_CHANNELS; + } else { + ch_list = sc->sc_ndma_channels; + ch_count = NDMA_CHANNELS; + } + + mtx_lock_spin(&sc->sc_mtx); + for (index = 0; index < ch_count; index++) { + if (ch_list[index].ch_callback == NULL) { + ch = &ch_list[index]; + ch->ch_callback = cb; + ch->ch_callbackarg = cbarg; + + irqen = DMA_READ(sc, AWIN_DMA_IRQ_EN_REG); + if (ch->ch_type == CH_NDMA) + irqen |= AWIN_DMA_IRQ_NDMA_END(index); + else + irqen |= AWIN_DMA_IRQ_DDMA_END(index); + DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, irqen); + + break; + } + } + mtx_unlock_spin(&sc->sc_mtx); + + return (ch); +} + +static void +a10dmac_free(device_t dev, void *priv) +{ + struct a10dmac_channel *ch = priv; + struct a10dmac_softc *sc = ch->ch_sc; + uint32_t irqen, sta, cfg; + + mtx_lock_spin(&sc->sc_mtx); + + irqen = DMA_READ(sc, AWIN_DMA_IRQ_EN_REG); + cfg = a10dmac_read_ctl(ch); + if (ch->ch_type == CH_NDMA) { + sta = AWIN_DMA_IRQ_NDMA_END(ch->ch_index); + cfg &= ~AWIN_NDMA_CTL_DMA_LOADING; + } else { + sta = AWIN_DMA_IRQ_DDMA_END(ch->ch_index); + cfg &= ~AWIN_DDMA_CTL_DMA_LOADING; + } + irqen &= ~sta; + a10dmac_write_ctl(ch, cfg); + DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, irqen); + DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, sta); + + ch->ch_callback = NULL; + ch->ch_callbackarg = NULL; + + mtx_unlock_spin(&sc->sc_mtx); +} + +static int +a10dmac_transfer(device_t dev, void *priv, bus_addr_t src, bus_addr_t dst, + size_t nbytes) +{ + struct a10dmac_channel *ch = priv; + uint32_t cfg; + + cfg = a10dmac_read_ctl(ch); + if (ch->ch_type == CH_NDMA) { + if (cfg & AWIN_NDMA_CTL_DMA_LOADING) + return (EBUSY); + + DMACH_WRITE(ch, AWIN_NDMA_SRC_ADDR_REG, src); + DMACH_WRITE(ch, AWIN_NDMA_DEST_ADDR_REG, dst); + DMACH_WRITE(ch, AWIN_NDMA_BC_REG, nbytes); + + cfg |= AWIN_NDMA_CTL_DMA_LOADING; + a10dmac_write_ctl(ch, cfg); + } else { + if (cfg & AWIN_DDMA_CTL_DMA_LOADING) + return (EBUSY); + + DMACH_WRITE(ch, AWIN_DDMA_SRC_START_ADDR_REG, src); + DMACH_WRITE(ch, AWIN_DDMA_DEST_START_ADDR_REG, dst); + DMACH_WRITE(ch, AWIN_DDMA_BC_REG, nbytes); + + cfg |= AWIN_DDMA_CTL_DMA_LOADING; + a10dmac_write_ctl(ch, cfg); + } + + return (0); +} + +static void +a10dmac_halt(device_t dev, void *priv) +{ + struct a10dmac_channel *ch = priv; + uint32_t cfg; + + cfg = a10dmac_read_ctl(ch); + if (ch->ch_type == CH_NDMA) { + cfg &= ~AWIN_NDMA_CTL_DMA_LOADING; + } else { + cfg &= ~AWIN_DDMA_CTL_DMA_LOADING; + } + a10dmac_write_ctl(ch, cfg); +} + +static device_method_t a10dmac_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, a10dmac_probe), + DEVMETHOD(device_attach, a10dmac_attach), + + /* sunxi DMA interface */ + DEVMETHOD(sunxi_dma_alloc, a10dmac_alloc), + DEVMETHOD(sunxi_dma_free, a10dmac_free), + DEVMETHOD(sunxi_dma_set_config, a10dmac_set_config), + DEVMETHOD(sunxi_dma_transfer, a10dmac_transfer), + DEVMETHOD(sunxi_dma_halt, a10dmac_halt), + + DEVMETHOD_END +}; + +static driver_t a10dmac_driver = { + "a10dmac", + a10dmac_methods, + sizeof(struct a10dmac_softc) +}; + +static devclass_t a10dmac_devclass; + +DRIVER_MODULE(a10dmac, simplebus, a10dmac_driver, a10dmac_devclass, 0, 0); diff --git a/sys/arm/allwinner/a10_dmac.h b/sys/arm/allwinner/a10_dmac.h new file mode 100644 index 000000000000..7b337b35bec9 --- /dev/null +++ b/sys/arm/allwinner/a10_dmac.h @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2014-2016 Jared D. McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _A10_DMAC_H_ +#define _A10_DMAC_H_ + +#define AWIN_DMA_IRQ_EN_REG 0x0000 +#define AWIN_DMA_IRQ_PEND_STA_REG 0x0004 +#define AWIN_NDMA_AUTO_GATE_REG 0x0008 +#define AWIN_NDMA_REG(n) (0x100+0x20*(n)) +#define AWIN_NDMA_CTL_REG 0x0000 +#define AWIN_NDMA_SRC_ADDR_REG 0x0004 +#define AWIN_NDMA_DEST_ADDR_REG 0x0008 +#define AWIN_NDMA_BC_REG 0x000c +#define AWIN_DDMA_REG(n) (0x300+0x20*(n)) +#define AWIN_DDMA_CTL_REG 0x0000 +#define AWIN_DDMA_SRC_START_ADDR_REG 0x0004 +#define AWIN_DDMA_DEST_START_ADDR_REG 0x0008 +#define AWIN_DDMA_BC_REG 0x000c +#define AWIN_DDMA_PARA_REG 0x0018 +#define AWIN_DMA_IRQ_END_MASK 0xaaaaaaaa +#define AWIN_DMA_IRQ_HF_MASK 0x55555555 +#define AWIN_DMA_IRQ_DDMA 0xffff0000 +#define AWIN_DMA_IRQ_DDMA_END(n) (1U << (17+2*(n))) +#define AWIN_DMA_IRQ_DDMA_HF(n) (1U << (16+2*(n))) +#define AWIN_DMA_IRQ_NDMA 0x0000ffff +#define AWIN_DMA_IRQ_NDMA_END(n) (1U << (1+2*(n))) +#define AWIN_DMA_IRQ_NDMA_HF(n) (1U << (0+2*(n))) +#define AWIN_NDMA_AUTO_GATING_DIS (1U << 16) +#define AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT 25 +#define AWIN_DMA_CTL_DST_DATA_WIDTH_MASK (3U << AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT) +#define AWIN_DMA_CTL_DATA_WIDTH_8 0 +#define AWIN_DMA_CTL_DATA_WIDTH_16 1 +#define AWIN_DMA_CTL_DATA_WIDTH_32 2 +#define AWIN_DMA_CTL_DST_BURST_LEN_SHIFT 23 +#define AWIN_DMA_CTL_DST_BURST_LEN_MASK (3 << AWIN_DMA_CTL_DST_BURST_LEN_SHIFT) +#define AWIN_DMA_CTL_BURST_LEN_1 0 +#define AWIN_DMA_CTL_BURST_LEN_4 1 +#define AWIN_DMA_CTL_BURST_LEN_8 2 +#define AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT 16 +#define AWIN_DMA_CTL_DST_DRQ_TYPE_MASK (0x1f << AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT) +#define AWIN_DMA_CTL_BC_REMAINING (1U << 15) +#define AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT 9 +#define AWIN_DMA_CTL_SRC_DATA_WIDTH_MASK (3U << AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT) +#define AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT 7 +#define AWIN_DMA_CTL_SRC_BURST_LEN_MASK (3U << AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT) +#define AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT 0 +#define AWIN_DMA_CTL_SRC_DRQ_TYPE_MASK (0x1f << AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT) +#define AWIN_NDMA_CTL_DMA_LOADING (1U << 31) +#define AWIN_NDMA_CTL_DMA_CONTIN_MODE (1U << 30) +#define AWIN_NDMA_CTL_WAIT_STATE_LOG2_SHIFT 27 +#define AWIN_NDMA_CTL_WAIT_STATE_LOG2_MASK (7U << AWIN_NDMA_CTL_WAIT_STATE_LOG2_SHIFT) +#define AWIN_NDMA_CTL_DST_NON_SECURE (1U << 22) +#define AWIN_NDMA_CTL_DST_ADDR_NOINCR (1U << 21) +#define AWIN_NDMA_CTL_DRQ_IRO 0 +#define AWIN_NDMA_CTL_DRQ_IR1 1 +#define AWIN_NDMA_CTL_DRQ_SPDIF 2 +#define AWIN_NDMA_CTL_DRQ_IISO 3 +#define AWIN_NDMA_CTL_DRQ_IIS1 4 +#define AWIN_NDMA_CTL_DRQ_AC97 5 +#define AWIN_NDMA_CTL_DRQ_IIS2 6 +#define AWIN_NDMA_CTL_DRQ_UARTO 8 +#define AWIN_NDMA_CTL_DRQ_UART1 9 +#define AWIN_NDMA_CTL_DRQ_UART2 10 +#define AWIN_NDMA_CTL_DRQ_UART3 11 +#define AWIN_NDMA_CTL_DRQ_UART4 12 +#define AWIN_NDMA_CTL_DRQ_UART5 13 +#define AWIN_NDMA_CTL_DRQ_UART6 14 +#define AWIN_NDMA_CTL_DRQ_UART7 15 +#define AWIN_NDMA_CTL_DRQ_DDC 16 +#define AWIN_NDMA_CTL_DRQ_USB_EP1 17 +#define AWIN_NDMA_CTL_DRQ_CODEC 19 +#define AWIN_NDMA_CTL_DRQ_SRAM 21 +#define AWIN_NDMA_CTL_DRQ_SDRAM 22 +#define AWIN_NDMA_CTL_DRQ_TP_AD 23 +#define AWIN_NDMA_CTL_DRQ_SPI0 24 +#define AWIN_NDMA_CTL_DRQ_SPI1 25 +#define AWIN_NDMA_CTL_DRQ_SPI2 26 +#define AWIN_NDMA_CTL_DRQ_SPI3 27 +#define AWIN_NDMA_CTL_DRQ_USB_EP2 28 +#define AWIN_NDMA_CTL_DRQ_USB_EP3 29 +#define AWIN_NDMA_CTL_DRQ_USB_EP4 30 +#define AWIN_NDMA_CTL_DRQ_USB_EP5 31 +#define AWIN_NDMA_CTL_SRC_NON_SECURE (1U << 6) +#define AWIN_NDMA_CTL_SRC_ADDR_NOINCR (1U << 5) +#define AWIN_NDMA_BC_COUNT 0x0003ffff +#define AWIN_DDMA_CTL_DMA_LOADING (1U << 31) +#define AWIN_DDMA_CTL_BUSY (1U << 30) +#define AWIN_DDMA_CTL_DMA_CONTIN_MODE (1U << 29) +#define AWIN_DDMA_CTL_DST_NON_SECURE (1U << 28) +#define AWIN_DDMA_CTL_DST_ADDR_MODE_SHIFT 21 +#define AWIN_DDMA_CTL_DST_ADDR_MODE_MASK (3U << AWIN_DDMA_CTL_DST_ADDR_MODE_SHIFT) +#define AWIN_DDMA_CTL_DMA_ADDR_LINEAR 0 +#define AWIN_DDMA_CTL_DMA_ADDR_IO 1 +#define AWIN_DDMA_CTL_DMA_ADDR_HPAGE 2 +#define AWIN_DDMA_CTL_DMA_ADDR_VPAGE 3 +#define AWIN_DDMA_CTL_DST_DRQ_TYPE_SHIFT 16 +#define AWIN_DDMA_CTL_DST_DRQ_TYPE_MASK (0x1f << AWIN_DDMA_CTL_DST_DRQ_TYPE_SHIFT) +#define AWIN_DDMA_CTL_DRQ_SRAM 0 +#define AWIN_DDMA_CTL_DRQ_SDRAM 1 +#define AWIN_DDMA_CTL_DRQ_NFC 3 +#define AWIN_DDMA_CTL_DRQ_USB0 4 +#define AWIN_DDMA_CTL_DRQ_EMAC_TX 6 +#define AWIN_DDMA_CTL_DRQ_EMAC_RX 7 +#define AWIN_DDMA_CTL_DRQ_SPI1_TX 8 +#define AWIN_DDMA_CTL_DRQ_SPI1_RX 9 +#define AWIN_DDMA_CTL_DRQ_SS_TX 10 +#define AWIN_DDMA_CTL_DRQ_SS_RX 11 +#define AWIN_DDMA_CTL_DRQ_TCON0 14 +#define AWIN_DDMA_CTL_DRQ_TCON1 15 +#define AWIN_DDMA_CTL_DRQ_MS_TX 23 +#define AWIN_DDMA_CTL_DRQ_MS_RX 23 +#define AWIN_DDMA_CTL_DRQ_HDMI_AUDIO 24 +#define AWIN_DDMA_CTL_DRQ_SPI0_TX 26 +#define AWIN_DDMA_CTL_DRQ_SPI0_RX 27 +#define AWIN_DDMA_CTL_DRQ_SPI2_TX 28 +#define AWIN_DDMA_CTL_DRQ_SPI2_RX 29 +#define AWIN_DDMA_CTL_DRQ_SPI3_TX 30 +#define AWIN_DDMA_CTL_DRQ_SPI3_RX 31 +#define AWIN_DDMA_CTL_SRC_NON_SECURE (1U << 12) +#define AWIN_DDMA_CTL_SRC_ADDR_MODE_SHIFT 5 +#define AWIN_DDMA_CTL_SRC_ADDR_MODE_MASK (3U << AWIN_DDMA_CTL_SRC_ADDR_MODE_SHIFT) +#define AWIN_DDMA_BC_COUNT 0x00003fff +#define AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT 24 +#define AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_MASK (0xff << AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT) +#define AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT 16 +#define AWIN_DDMA_PARA_DST_WAIT_CYC_MASK (0xff << AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT) +#define AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT 8 +#define AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_MASK (0xff << AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT) +#define AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT 0 +#define AWIN_DDMA_PARA_SRC_WAIT_CYC_MASK (0xff << AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT) + +#endif /* !_A10_DMAC_H_ */ diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index cc4dd4832c56..0cdd7b35153f 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -4,6 +4,7 @@ kern/kern_clocksource.c standard arm/allwinner/a10_ahci.c optional ahci arm/allwinner/a10_clk.c standard arm/allwinner/a10_common.c standard +arm/allwinner/a10_dmac.c standard arm/allwinner/a10_ehci.c optional ehci arm/allwinner/a10_gpio.c optional gpio arm/allwinner/a10_mmc.c optional mmc @@ -13,5 +14,6 @@ arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/allwinner_machdep.c standard arm/allwinner/axp209.c optional axp209 arm/allwinner/if_emac.c optional emac +arm/allwinner/sunxi_dma_if.m standard dev/iicbus/twsi/a10_twsi.c optional twsi #arm/allwinner/console.c standard diff --git a/sys/arm/allwinner/sunxi_dma_if.m b/sys/arm/allwinner/sunxi_dma_if.m new file mode 100644 index 000000000000..6e283b93cf41 --- /dev/null +++ b/sys/arm/allwinner/sunxi_dma_if.m @@ -0,0 +1,98 @@ +#- +# Copyright (c) 2016 Jared D. McNeill +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +INTERFACE sunxi_dma; + +HEADER { + #include + + struct sunxi_dma_config { + unsigned int dst_width; + unsigned int dst_burst_len; + unsigned int dst_drqtype; + bool dst_noincr; + unsigned int dst_blksize; /* DDMA-only */ + unsigned int dst_wait_cyc; /* DDMA-only */ + unsigned int src_width; + unsigned int src_burst_len; + unsigned int src_drqtype; + bool src_noincr; + unsigned int src_blksize; /* DDMA-only */ + unsigned int src_wait_cyc; /* DDMA-only */ + }; + + typedef void (*sunxi_dma_callback)(void *); +} + +# +# Allocate DMA channel +# +METHOD void * alloc { + device_t dev; + bool dedicated; + sunxi_dma_callback callback; + void *callback_arg; +}; + +# +# Free DMA channel +# +METHOD void free { + device_t dev; + void *dmachan; +}; + +# +# Set DMA channel configuration +# +METHOD int set_config { + device_t dev; + void *dmachan; + const struct sunxi_dma_config *cfg; +}; + +# +# Start DMA channel transfer +# +METHOD int transfer { + device_t dev; + void *dmachan; + bus_addr_t src; + bus_addr_t dst; + size_t nbytes; +}; + +# +# Halt DMA channel transfer +# +METHOD void halt { + device_t dev; + void *dmachan; +}; diff --git a/sys/arm/conf/A10 b/sys/arm/conf/A10 index 577fa602e46d..2cb71d45dac0 100644 --- a/sys/arm/conf/A10 +++ b/sys/arm/conf/A10 @@ -69,6 +69,7 @@ device random # Entropy device device iicbus device iic device twsi +device axp209 # AXP209 Power Management Unit # GPIO device gpio diff --git a/sys/arm/conf/A20 b/sys/arm/conf/A20 index ded074a5240c..23519ff54cf7 100644 --- a/sys/arm/conf/A20 +++ b/sys/arm/conf/A20 @@ -78,6 +78,7 @@ device random # Entropy device device iicbus device iic device twsi +device axp209 # AXP209 Power Management Unit # GPIO device gpio diff --git a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi index 4d1742cd51a4..607034397399 100644 --- a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi +++ b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi @@ -173,6 +173,13 @@ #address-cells = <1>; #size-cells = <0>; }; + + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <27>; + interrupt-parent = <&GIC>; + }; }; }; From 142482cda6c2a9e05489172a2bd40cf5c318f338 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 15 Feb 2016 20:26:40 +0000 Subject: [PATCH 140/142] Sign extend the error value for failing Linux/i386 system calls. This restores the mapping of Linux errors to native FreeBSD errno values after the refactoring in r288424. --- usr.bin/truss/amd64-linux32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index 2ede61757b03..873ef01ee386 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -115,6 +115,8 @@ amd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval, retval[0] = regs.r_rax & 0xffffffff; retval[1] = regs.r_rdx & 0xffffffff; *errorp = !!(regs.r_rflags & PSL_C); + if (*errorp) + retval[0] = (int)retval[0]; if (*errorp) { for (i = 0; i < nitems(bsd_to_linux_errno); i++) { From 623277619d20992ecaea04ba3ca3f4e9507f25f0 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 15 Feb 2016 20:27:16 +0000 Subject: [PATCH 141/142] Correct the ABI name for Linux/i386 binaries under FreeBSD/i386. This allows truss to work for these binaries again after r288424. MFC after: 3 days --- usr.bin/truss/i386-linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index fbc54a096d4f..c5f625d7303b 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -129,7 +129,7 @@ i386_linux_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) } static struct procabi i386_linux = { - "Linux ELF32", + "Linux ELF", SYSDECODE_ABI_LINUX, i386_linux_fetch_args, i386_linux_fetch_retval From 179a5a39a86db88c86540521cd1d9b404dbc40db Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 15 Feb 2016 21:18:52 +0000 Subject: [PATCH 142/142] fputs: Return the number of bytes written. Fix r295631: wrong value. Pointy hat: pfg (me) Pointed out by: bde --- lib/libc/stdio/fputs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c index d01097937583..1f9795a493fa 100644 --- a/lib/libc/stdio/fputs.c +++ b/lib/libc/stdio/fputs.c @@ -64,6 +64,6 @@ fputs(const char * __restrict s, FILE * __restrict fp) retval = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); if (retval == 0) - return (iov.iov_len > INT_MAX ? INT_MAX : uio.uio_resid); + return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len); return (retval); }