summaryrefslogtreecommitdiffstats
path: root/lib/libelf
diff options
context:
space:
mode:
authorjkoshy <jkoshy@FreeBSD.org>2008-03-02 06:33:10 +0000
committerjkoshy <jkoshy@FreeBSD.org>2008-03-02 06:33:10 +0000
commit380ba89956af6818d6332220c2ac73e73c5b8e93 (patch)
treecccf7db8b770eb3336b7ef87346bcae365aba628 /lib/libelf
parent1d45406e257b8f571cce9ac32cc46b11f62e2740 (diff)
downloadFreeBSD-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.c13
-rw-r--r--lib/libelf/gelf_rela.c14
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;
OpenPOWER on IntegriCloud