NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-arm/49299: earmv7hfeb kernels can not load modules



The following reply was made to PR port-arm/49299; it has been noted by GNATS.

From: Christos Zoulas <christos%zoulas.com@localhost>
To: "gnats-bugs%NetBSD.org@localhost" <gnats-bugs%NetBSD.org@localhost>
Cc: "port-arm-maintainer%netbsd.org@localhost" <port-arm-maintainer%netbsd.org@localhost>,
 "gnats-admin%netbsd.org@localhost" <gnats-admin%netbsd.org@localhost>,
 "netbsd-bugs%netbsd.org@localhost" <netbsd-bugs%netbsd.org@localhost>,
 "martin%NetBSD.org@localhost" <martin%NetBSD.org@localhost>
Subject: Re: port-arm/49299: earmv7hfeb kernels can not load modules
Date: Thu, 6 Nov 2014 18:49:02 -0500

 > +    if (ELF_ST_BIND(info) !=3D STB_LOCAL)
 > +        return Other;
 > +    if (ELF_ST_TYPE(info) !=3D STT_NOTYPE)
 > +        return Other;
 > +    if (strcmp(name, "$a") =3D=3D 0)
 > +        return ArmStart;
 > +    if (strncmp(name, "$a.", 3) =3D=3D 0)
 > +        return ArmStart;
 > +    if (strcmp(name, "$t") =3D=3D 0)
 > +        return ThumbStart;
 > +    if (strncmp(name, "$t.", 3) =3D=3D 0)
 > +        return ThumbStart;
 > +    if (strcmp(name, "$d") =3D=3D 0)
 > +        return DataStart;
 > +    if (strncmp(name, "$d.", 3) =3D=3D 0)
 > +        return DataStart;
 > +    return Other;
 > +}
 > +
 
 This sequence of strcmps can be made a lot more efficient with specialized c=
 ode (and smaller)
 
 > +static int
 > +be8_ksym_count(const char *name, int symindex, void *value, uint32_t size=
 ,
 > +    int info, void *cookie)
 > +{
 > +    size_t *res =3D cookie;
 > +    enum be8_magic_sym_type t =3D be8_sym_type(name, info);
 > +
 > +    if (t !=3D Other)
 > +        (*res)++;
 > +    return 0;
 > +}
 > +
 > +static int
 > +be8_ksym_add(const char *name, int symindex, void *value, uint32_t size,
 > +    int info, void *cookie)
 > +{
 > +    size_t ndx;
 > +    struct be8_marker_list *list =3D cookie;
 > +    enum be8_magic_sym_type t =3D be8_sym_type(name, info);
 > +
 > +    if (t =3D=3D Other)
 > +        return 0;
 > +
 > +    ndx =3D list->cnt++;
 > +    list->markers[ndx].type =3D t;
 > +    list->markers[ndx].addr =3D value;
 > +
 > +    return 0;
 > +}
 > +
 > +static int
 > +be8_ksym_comp(const void *a, const void *b)
 > +{
 > +    const struct be8_marker *ma =3D a, *mb =3D b;
 > +    uintptr_t va =3D (uintptr_t)ma->addr, vb =3D (uintptr_t)mb->addr;
 > +
 > +    if (va =3D=3D vb)
 > +        return 0;
 > +    if (va < vb)
 > +        return -1;
 > +    return 1;
 > +}
 > +
 > +static void
 > +be8_ksym_swap(void *start, size_t size, const struct be8_marker_list *lis=
 t)
 > +{
 > +    uintptr_t va_end =3D (uintptr_t)start + size;
 > +    size_t i;
 > +    uint32_t *p32, *p32_end, v32;
 > +    uint16_t *p16, *p16_end, v16;
 > +
 > +    /* find first relevant list entry */
 > +    for (i =3D 0; i < list->cnt; i++)
 > +        if (start <=3D list->markers[i].addr)
 > +            break;
 > +
 > +    /* swap all arm and thumb code parts of this section */
 > +    for ( ; i < list->cnt; i++) {
 > +        switch (list->markers[i].type) {
 > +        case ArmStart:
 > +            p32 =3D (uint32_t*)list->markers[i].addr;
 > +            p32_end =3D (uint32_t*)va_end;
 > +            if (i+1 < list->cnt) {
 > +                if ((uintptr_t)list->markers[i+1].addr
 > +                    < va_end)
 > +                    p32_end =3D (uint32_t*)
 > +                        list->markers[i+1].addr;
 > +            }
 > +            while (p32 < p32_end) {
 > +                v32 =3D bswap32(*p32);
 > +                *p32++ =3D v32;
 > +            }
 > +            break;
 > +        case ThumbStart:
 > +            p16 =3D (uint16_t*)list->markers[i].addr;
 > +            p16_end =3D (uint16_t*)va_end;
 > +            if (i+1 < list->cnt) {
 > +                if ((uintptr_t)list->markers[i+1].addr
 > +                    < va_end)
 > +                    p16_end =3D (uint16_t*)
 > +                        list->markers[i+1].addr;
 > +       =20
 
 I think a default and break here is better
 
 >    }
 > +            while (p16 < p16_end) {
 > +                v16 =3D bswap16(*p16);
 
 > +                *p16++ =3D v16;
 > +            }
 > +            break;
 > +        default:
 > +            break;
 > +        }
 > +    }
 > +}
 > +=20
 > +static void
 > +kobj_be8_fixup(kobj_t ko)
 > +{
 > +    size_t relsym_cnt =3D 0, i;
 > +    struct be8_marker_list list;
 > +    struct be8_marker tmp;
 > +
 > +    /*
 > +     * Count all special relocations symbols
 > +     */
 > +    ksyms_mod_foreach(ko->ko_name, be8_ksym_count, &relsym_cnt);
 > +
 > +    /*
 > +     * Provide storage for the address list and add the symbols
 > +     */
 > +    list.cnt =3D 0;
 > +    list.markers =3D kmem_alloc(relsym_cnt*sizeof(*list.markers), KM_SLEE=
 P);
 > +    ksyms_mod_foreach(ko->ko_name, be8_ksym_add, &list);
 > +    KASSERT(list.cnt =3D=3D relsym_cnt);
 > +
 > +    /*
 > +     * Sort symbols by ascending address
 > +     */
 > +    if (kheapsort(list.markers, relsym_cnt, sizeof(*list.markers),
 > +        be8_ksym_comp, &tmp) !=3D 0)
 > +        panic("could not sort be8 marker symbols");
 > +
 > +    /*
 > +     * Apply swaps to the .text section (XXX we do not have the
 > +     * section header available any more, it has been jetisoned
 > +     * already, so we can not check for all PROGBIT sections).
 > +     */
 > +    for (i =3D 0; i < ko->ko_nprogtab; i++) {
 > +        if (strcmp(ko->ko_progtab[i].name, ".text") !=3D 0)
 > +            continue;
 > +        be8_ksym_swap(ko->ko_progtab[i].addr,
 > +            (size_t)ko->ko_progtab[i].size,
 > +            &list);
 > +    }
 > +
 > +    /*
 > +     * Done, free list
 > +     */
 > +    kmem_free(list.markers, relsym_cnt*sizeof(*list.markers));
 > +}
 > +#endif
 > +
 >  int
 >  kobj_machdep(kobj_t ko, void *base, size_t size, bool load)
 >  {
 > @@ -212,6 +400,9 @@ kobj_machdep(kobj_t ko, void *base, size
 >          cpu_idcache_wbinv_range((vaddr_t)base, size);
 >          cpu_tlb_flushID();
 >  #endif
 > +#ifdef ARM_8EB
 > +        kobj_be8_fixup(ko);
 > +#endif
 >      }
 >=20
 >      return 0;
 >=20
 > --5mCyUwZo2JvN/JJP--
 >=20
 


Home | Main Index | Thread Index | Old Index