2023-06-20 12:20:57

by Masahiro Yamada

[permalink] [raw]
Subject: [PATCH 1/3] modpost: factor out inst location calculation to section_rel()

All the addend_*_rel() functions calculate the instruction location in
the same way.

Factor out the similar code to the caller. Squash reloc_location() too.

Signed-off-by: Masahiro Yamada <[email protected]>
---

scripts/mod/modpost.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 6e0b8be32648..2551ac9d5bd3 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1256,16 +1256,9 @@ static void check_section_mismatch(struct module *mod, struct elf_info *elf,
tosec, taddr);
}

-static unsigned int *reloc_location(struct elf_info *elf,
- Elf_Shdr *sechdr, Elf_Rela *r)
-{
- return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
-}
-
-static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+static int addend_386_rel(uint32_t *location, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
- unsigned int *location = reloc_location(elf, sechdr, r);

switch (r_typ) {
case R_386_32:
@@ -1302,11 +1295,10 @@ static int32_t sign_extend32(int32_t value, int index)
return (int32_t)(value << shift) >> shift;
}

-static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+static int addend_arm_rel(void *loc, struct elf_info *elf, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
- void *loc = reloc_location(elf, sechdr, r);
uint32_t inst, upper, lower, sign, j1, j2;
int32_t offset;

@@ -1396,11 +1388,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
return 0;
}

-static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+static int addend_mips_rel(uint32_t *location, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
- unsigned int *location = reloc_location(elf, sechdr, r);
- unsigned int inst;
+ uint32_t inst;

if (r_typ == R_MIPS_HI16)
return 1; /* skip this */
@@ -1502,6 +1493,8 @@ static void section_rel(struct module *mod, struct elf_info *elf,
return;

for (rel = start; rel < stop; rel++) {
+ void *loc;
+
r.r_offset = TO_NATIVE(rel->r_offset);
#if KERNEL_ELFCLASS == ELFCLASS64
if (elf->hdr->e_machine == EM_MIPS) {
@@ -1519,17 +1512,20 @@ static void section_rel(struct module *mod, struct elf_info *elf,
r_sym = ELF_R_SYM(r.r_info);
#endif
r.r_addend = 0;
+
+ loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
+
switch (elf->hdr->e_machine) {
case EM_386:
- if (addend_386_rel(elf, sechdr, &r))
+ if (addend_386_rel(loc, &r))
continue;
break;
case EM_ARM:
- if (addend_arm_rel(elf, sechdr, &r))
+ if (addend_arm_rel(loc, elf, &r))
continue;
break;
case EM_MIPS:
- if (addend_mips_rel(elf, sechdr, &r))
+ if (addend_mips_rel(loc, &r))
continue;
break;
default:
--
2.39.2



2023-06-20 12:39:15

by Masahiro Yamada

[permalink] [raw]
Subject: [PATCH 2/3] modpost: factor out Elf_Sym pointer calculation to section_rel()

Pass the Elf_Sym pointer to addend_arm_rel() as well as to
check_section_mismatch().

Signed-off-by: Masahiro Yamada <[email protected]>
---

scripts/mod/modpost.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2551ac9d5bd3..ffe45c54f024 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1295,10 +1295,9 @@ static int32_t sign_extend32(int32_t value, int index)
return (int32_t)(value << shift) >> shift;
}

-static int addend_arm_rel(void *loc, struct elf_info *elf, Elf_Rela *r)
+static int addend_arm_rel(void *loc, Elf_Sym *sym, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
- Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
uint32_t inst, upper, lower, sign, j1, j2;
int32_t offset;

@@ -1493,6 +1492,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
return;

for (rel = start; rel < stop; rel++) {
+ Elf_Sym *tsym;
void *loc;

r.r_offset = TO_NATIVE(rel->r_offset);
@@ -1514,6 +1514,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
r.r_addend = 0;

loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
+ tsym = elf->symtab_start + ELF_R_SYM(r.r_info);

switch (elf->hdr->e_machine) {
case EM_386:
@@ -1521,7 +1522,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
continue;
break;
case EM_ARM:
- if (addend_arm_rel(loc, elf, &r))
+ if (addend_arm_rel(loc, tsym, &r))
continue;
break;
case EM_MIPS:
@@ -1532,7 +1533,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
fatal("Please add code to calculate addend for this architecture\n");
}

- check_section_mismatch(mod, elf, elf->symtab_start + r_sym,
+ check_section_mismatch(mod, elf, tsym,
fsecndx, fromsec, r.r_offset, r.r_addend);
}
}
--
2.39.2


2023-06-22 18:29:09

by Nick Desaulniers

[permalink] [raw]
Subject: Re: [PATCH 1/3] modpost: factor out inst location calculation to section_rel()

On Tue, Jun 20, 2023 at 5:05 AM Masahiro Yamada <[email protected]> wrote:
>
> All the addend_*_rel() functions calculate the instruction location in
> the same way.
>
> Factor out the similar code to the caller. Squash reloc_location() too.
>
> Signed-off-by: Masahiro Yamada <[email protected]>
> ---
>
> scripts/mod/modpost.c | 28 ++++++++++++----------------
> 1 file changed, 12 insertions(+), 16 deletions(-)
>
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 6e0b8be32648..2551ac9d5bd3 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1256,16 +1256,9 @@ static void check_section_mismatch(struct module *mod, struct elf_info *elf,
> tosec, taddr);
> }
>
> -static unsigned int *reloc_location(struct elf_info *elf,
> - Elf_Shdr *sechdr, Elf_Rela *r)
> -{
> - return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
> -}
> -
> -static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> +static int addend_386_rel(uint32_t *location, Elf_Rela *r)
> {
> unsigned int r_typ = ELF_R_TYPE(r->r_info);
> - unsigned int *location = reloc_location(elf, sechdr, r);
>
> switch (r_typ) {
> case R_386_32:
> @@ -1302,11 +1295,10 @@ static int32_t sign_extend32(int32_t value, int index)
> return (int32_t)(value << shift) >> shift;
> }
>
> -static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> +static int addend_arm_rel(void *loc, struct elf_info *elf, Elf_Rela *r)
> {
> unsigned int r_typ = ELF_R_TYPE(r->r_info);
> Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
> - void *loc = reloc_location(elf, sechdr, r);
> uint32_t inst, upper, lower, sign, j1, j2;
> int32_t offset;
>
> @@ -1396,11 +1388,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> return 0;
> }
>
> -static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> +static int addend_mips_rel(uint32_t *location, Elf_Rela *r)
> {
> unsigned int r_typ = ELF_R_TYPE(r->r_info);
> - unsigned int *location = reloc_location(elf, sechdr, r);
> - unsigned int inst;
> + uint32_t inst;
>
> if (r_typ == R_MIPS_HI16)
> return 1; /* skip this */
> @@ -1502,6 +1493,8 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> return;
>
> for (rel = start; rel < stop; rel++) {
> + void *loc;
> +
> r.r_offset = TO_NATIVE(rel->r_offset);
> #if KERNEL_ELFCLASS == ELFCLASS64
> if (elf->hdr->e_machine == EM_MIPS) {
> @@ -1519,17 +1512,20 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> r_sym = ELF_R_SYM(r.r_info);
> #endif
> r.r_addend = 0;
> +
> + loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);

Can we compute `loc` only for the three machine types?

> +
> switch (elf->hdr->e_machine) {
> case EM_386:
> - if (addend_386_rel(elf, sechdr, &r))
> + if (addend_386_rel(loc, &r))
> continue;
> break;
> case EM_ARM:
> - if (addend_arm_rel(elf, sechdr, &r))
> + if (addend_arm_rel(loc, elf, &r))
> continue;
> break;
> case EM_MIPS:
> - if (addend_mips_rel(elf, sechdr, &r))
> + if (addend_mips_rel(loc, &r))
> continue;
> break;
> default:
> --
> 2.39.2
>


--
Thanks,
~Nick Desaulniers

2023-06-22 20:01:19

by Nick Desaulniers

[permalink] [raw]
Subject: Re: [PATCH 2/3] modpost: factor out Elf_Sym pointer calculation to section_rel()

On Tue, Jun 20, 2023 at 5:05 AM Masahiro Yamada <[email protected]> wrote:
>
> Pass the Elf_Sym pointer to addend_arm_rel() as well as to
> check_section_mismatch().
>
> Signed-off-by: Masahiro Yamada <[email protected]>

Thanks for the patch!
Reviewed-by: Nick Desaulniers <[email protected]>

> ---
>
> scripts/mod/modpost.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 2551ac9d5bd3..ffe45c54f024 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1295,10 +1295,9 @@ static int32_t sign_extend32(int32_t value, int index)
> return (int32_t)(value << shift) >> shift;
> }
>
> -static int addend_arm_rel(void *loc, struct elf_info *elf, Elf_Rela *r)
> +static int addend_arm_rel(void *loc, Elf_Sym *sym, Elf_Rela *r)
> {
> unsigned int r_typ = ELF_R_TYPE(r->r_info);
> - Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
> uint32_t inst, upper, lower, sign, j1, j2;
> int32_t offset;
>
> @@ -1493,6 +1492,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> return;
>
> for (rel = start; rel < stop; rel++) {
> + Elf_Sym *tsym;
> void *loc;
>
> r.r_offset = TO_NATIVE(rel->r_offset);
> @@ -1514,6 +1514,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> r.r_addend = 0;
>
> loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
> + tsym = elf->symtab_start + ELF_R_SYM(r.r_info);
>
> switch (elf->hdr->e_machine) {
> case EM_386:
> @@ -1521,7 +1522,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> continue;
> break;
> case EM_ARM:
> - if (addend_arm_rel(loc, elf, &r))
> + if (addend_arm_rel(loc, tsym, &r))
> continue;
> break;
> case EM_MIPS:
> @@ -1532,7 +1533,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> fatal("Please add code to calculate addend for this architecture\n");
> }
>
> - check_section_mismatch(mod, elf, elf->symtab_start + r_sym,
> + check_section_mismatch(mod, elf, tsym,
> fsecndx, fromsec, r.r_offset, r.r_addend);
> }
> }
> --
> 2.39.2
>


--
Thanks,
~Nick Desaulniers

2023-06-23 05:41:22

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 1/3] modpost: factor out inst location calculation to section_rel()

On Fri, Jun 23, 2023 at 3:25 AM Nick Desaulniers
<[email protected]> wrote:
>
> On Tue, Jun 20, 2023 at 5:05 AM Masahiro Yamada <[email protected]> wrote:
> >
> > All the addend_*_rel() functions calculate the instruction location in
> > the same way.
> >
> > Factor out the similar code to the caller. Squash reloc_location() too.
> >
> > Signed-off-by: Masahiro Yamada <[email protected]>
> > ---
> >
> > scripts/mod/modpost.c | 28 ++++++++++++----------------
> > 1 file changed, 12 insertions(+), 16 deletions(-)
> >
> > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > index 6e0b8be32648..2551ac9d5bd3 100644
> > --- a/scripts/mod/modpost.c
> > +++ b/scripts/mod/modpost.c
> > @@ -1256,16 +1256,9 @@ static void check_section_mismatch(struct module *mod, struct elf_info *elf,
> > tosec, taddr);
> > }
> >
> > -static unsigned int *reloc_location(struct elf_info *elf,
> > - Elf_Shdr *sechdr, Elf_Rela *r)
> > -{
> > - return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
> > -}
> > -
> > -static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> > +static int addend_386_rel(uint32_t *location, Elf_Rela *r)
> > {
> > unsigned int r_typ = ELF_R_TYPE(r->r_info);
> > - unsigned int *location = reloc_location(elf, sechdr, r);
> >
> > switch (r_typ) {
> > case R_386_32:
> > @@ -1302,11 +1295,10 @@ static int32_t sign_extend32(int32_t value, int index)
> > return (int32_t)(value << shift) >> shift;
> > }
> >
> > -static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> > +static int addend_arm_rel(void *loc, struct elf_info *elf, Elf_Rela *r)
> > {
> > unsigned int r_typ = ELF_R_TYPE(r->r_info);
> > Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
> > - void *loc = reloc_location(elf, sechdr, r);
> > uint32_t inst, upper, lower, sign, j1, j2;
> > int32_t offset;
> >
> > @@ -1396,11 +1388,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> > return 0;
> > }
> >
> > -static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
> > +static int addend_mips_rel(uint32_t *location, Elf_Rela *r)
> > {
> > unsigned int r_typ = ELF_R_TYPE(r->r_info);
> > - unsigned int *location = reloc_location(elf, sechdr, r);
> > - unsigned int inst;
> > + uint32_t inst;
> >
> > if (r_typ == R_MIPS_HI16)
> > return 1; /* skip this */
> > @@ -1502,6 +1493,8 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> > return;
> >
> > for (rel = start; rel < stop; rel++) {
> > + void *loc;
> > +
> > r.r_offset = TO_NATIVE(rel->r_offset);
> > #if KERNEL_ELFCLASS == ELFCLASS64
> > if (elf->hdr->e_machine == EM_MIPS) {
> > @@ -1519,17 +1512,20 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> > r_sym = ELF_R_SYM(r.r_info);
> > #endif
> > r.r_addend = 0;
> > +
> > + loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
>
> Can we compute `loc` only for the three machine types?



I believe you can compute the location in the same way for any architecture
because it is mentioned in ELF spec.

https://refspecs.linuxfoundation.org/elf/elf.pdf

Page 36.


r_offset
This member gives the location at which to apply the relocation action. For
a relocatable file, the value is the byte offset from the beginning of the
section to the storage unit affected by the relocation.







--
Best Regards
Masahiro Yamada

2023-06-23 17:46:21

by Nick Desaulniers

[permalink] [raw]
Subject: Re: [PATCH 1/3] modpost: factor out inst location calculation to section_rel()

On Thu, Jun 22, 2023 at 10:38 PM Masahiro Yamada <[email protected]> wrote:
>
> On Fri, Jun 23, 2023 at 3:25 AM Nick Desaulniers
> <[email protected]> wrote:
> >
> > On Tue, Jun 20, 2023 at 5:05 AM Masahiro Yamada <[email protected]> wrote:
> > >
> > > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > > index 6e0b8be32648..2551ac9d5bd3 100644
> > > --- a/scripts/mod/modpost.c
> > > +++ b/scripts/mod/modpost.c
> > > @@ -1519,17 +1512,20 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> > > r_sym = ELF_R_SYM(r.r_info);
> > > #endif
> > > r.r_addend = 0;
> > > +
> > > + loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
> >
> > Can we compute `loc` only for the three machine types?
>
>
>
> I believe you can compute the location in the same way for any architecture
> because it is mentioned in ELF spec.

Sure, but perhaps it's wasted work for other machine types?
--
Thanks,
~Nick Desaulniers

2023-06-24 09:24:01

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 1/3] modpost: factor out inst location calculation to section_rel()

On Sat, Jun 24, 2023 at 2:01 AM Nick Desaulniers
<[email protected]> wrote:
>
> On Thu, Jun 22, 2023 at 10:38 PM Masahiro Yamada <[email protected]> wrote:
> >
> > On Fri, Jun 23, 2023 at 3:25 AM Nick Desaulniers
> > <[email protected]> wrote:
> > >
> > > On Tue, Jun 20, 2023 at 5:05 AM Masahiro Yamada <[email protected]> wrote:
> > > >
> > > > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > > > index 6e0b8be32648..2551ac9d5bd3 100644
> > > > --- a/scripts/mod/modpost.c
> > > > +++ b/scripts/mod/modpost.c
> > > > @@ -1519,17 +1512,20 @@ static void section_rel(struct module *mod, struct elf_info *elf,
> > > > r_sym = ELF_R_SYM(r.r_info);
> > > > #endif
> > > > r.r_addend = 0;
> > > > +
> > > > + loc = sym_get_data_by_offset(elf, fsecndx, r.r_offset);
> > >
> > > Can we compute `loc` only for the three machine types?
> >
> >
> >
> > I believe you can compute the location in the same way for any architecture
> > because it is mentioned in ELF spec.
>
> Sure, but perhaps it's wasted work for other machine types?



I guess you missed the following code:


switch (elf->hdr->e_machine) {
case EM_386:
...
break;
case EM_ARM:
...
break;
case EM_MIPS:
...
break;
default:
fatal("Please add code to calculate addend for this architecture\n");
}




I believe other machines never call this function.
If it occurred, fatal() would immediately errors out,
but I have not heard such a breakage for far.

I believe only i386, mips and arm use REL.
The other architectures are RELA.



--
Best Regards
Masahiro Yamada