diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2008-03-02 06:33:10 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2008-03-02 06:33:10 +0000 |
commit | 380ba89956af6818d6332220c2ac73e73c5b8e93 (patch) | |
tree | cccf7db8b770eb3336b7ef87346bcae365aba628 /lib/libelf | |
parent | 1d45406e257b8f571cce9ac32cc46b11f62e2740 (diff) | |
download | FreeBSD-src-380ba89956af6818d6332220c2ac73e73c5b8e93.zip FreeBSD-src-380ba89956af6818d6332220c2ac73e73c5b8e93.tar.gz |
Translate the r_info field of ELF relocation records when converting
between 64 and 32 bit variants.
Submitted by: kaiw
Diffstat (limited to 'lib/libelf')
-rw-r--r-- | lib/libelf/gelf_rel.c | 13 | ||||
-rw-r--r-- | lib/libelf/gelf_rela.c | 14 |
2 files changed, 23 insertions, 4 deletions
diff --git a/lib/libelf/gelf_rel.c b/lib/libelf/gelf_rel.c index e9cf948..e2a9f90 100644 --- a/lib/libelf/gelf_rel.c +++ b/lib/libelf/gelf_rel.c @@ -78,7 +78,9 @@ gelf_getrel(Elf_Data *d, int ndx, GElf_Rel *dst) rel32 = (Elf32_Rel *) d->d_buf + ndx; dst->r_offset = (Elf64_Addr) rel32->r_offset; - dst->r_info = (Elf64_Xword) rel32->r_info; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rel32->r_info), + ELF32_R_TYPE(rel32->r_info)); } else { @@ -133,7 +135,14 @@ gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr) rel32 = (Elf32_Rel *) d->d_buf + ndx; LIBELF_COPY_U32(rel32, dr, r_offset); - LIBELF_COPY_U32(rel32, dr, r_info); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), + ELF64_R_TYPE(dr->r_info)); } else { rel64 = (Elf64_Rel *) d->d_buf + ndx; diff --git a/lib/libelf/gelf_rela.c b/lib/libelf/gelf_rela.c index 1549a53..572e2b7 100644 --- a/lib/libelf/gelf_rela.c +++ b/lib/libelf/gelf_rela.c @@ -78,7 +78,9 @@ gelf_getrela(Elf_Data *d, int ndx, GElf_Rela *dst) rela32 = (Elf32_Rela *) d->d_buf + ndx; dst->r_offset = (Elf64_Addr) rela32->r_offset; - dst->r_info = (Elf64_Xword) rela32->r_info; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rela32->r_info), + ELF32_R_TYPE(rela32->r_info)); dst->r_addend = (Elf64_Sxword) rela32->r_addend; } else { @@ -134,7 +136,15 @@ gelf_update_rela(Elf_Data *d, int ndx, GElf_Rela *dr) rela32 = (Elf32_Rela *) d->d_buf + ndx; LIBELF_COPY_U32(rela32, dr, r_offset); - LIBELF_COPY_U32(rela32, dr, r_info); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), + ELF64_R_TYPE(dr->r_info)); + LIBELF_COPY_S32(rela32, dr, r_addend); } else { rela64 = (Elf64_Rela *) d->d_buf + ndx; |