aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@windriver.com>2006-08-17 14:50:32 -0500
committerMark Hatle <mark.hatle@windriver.com>2010-07-22 16:13:28 -0500
commitdcf432ba1a68b571aad7372beaa5fa6d796f6d14 (patch)
tree5388ee415370d9d5d7f773c5d02d1ea278744170
parent69e37874d30990880a2c196765920c8796be5fc4 (diff)
downloadprelink-cross-dcf432ba1a68b571aad7372beaa5fa6d796f6d14.tar.gz
prelink-cross-dcf432ba1a68b571aad7372beaa5fa6d796f6d14.tar.bz2
prelink-cross-dcf432ba1a68b571aad7372beaa5fa6d796f6d14.zip
Import from: prelink-endian-swap.patch
Source: Wind River Systems When using elfutils/libelf in prelink, it attempts to be helpful and do endian translations of most types. The ELF_T_BYTE type is not translated, and is used for the majority of the RELOCs, but not all of them. The patch only does internal endian swapping when the type is ELF_T_BYTE.
-rw-r--r--ChangeLog.cross5
-rw-r--r--src/data.c22
-rw-r--r--src/dso.c2
-rw-r--r--src/prelink.h2
4 files changed, 23 insertions, 8 deletions
diff --git a/ChangeLog.cross b/ChangeLog.cross
index 566751f..9ffca02 100644
--- a/ChangeLog.cross
+++ b/ChangeLog.cross
@@ -1,3 +1,8 @@
+2006-08-17 Mark Hatle <mark.hatle@windriver.com>
+
+ * data.c, dso.c, prelink.h: when using elfutils/libelf, we need
+ to byte swap only if the type is ELF_T_BYTE.
+
2006-08-10 Mark Hatle <mark.hatle@windriver.com>
* testsuite/Makefile.in: Allow testsuite to run using cross prelink.
diff --git a/src/data.c b/src/data.c
index ae48c6d..e4d06e1 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,12 +22,16 @@
uint##nn##_t \
read_u##le##nn (DSO *dso, GElf_Addr addr) \
{ \
- unsigned char *data = get_data (dso, addr, NULL); \
+ Elf_Type type; \
+ unsigned char *data = get_data (dso, addr, NULL, &type); \
\
if (data == NULL) \
return 0; \
\
- return buf_read_u##le##nn (data); \
+ if (type == ELF_T_BYTE) \
+ return buf_read_u##le##nn (data); \
+ else \
+ return *(uint##nn##_t *)data; \
}
#define WRITE(le,nn) \
@@ -35,12 +39,16 @@ int \
write_##le##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val) \
{ \
int sec; \
- unsigned char *data = get_data (dso, addr, &sec); \
+ Elf_Type type; \
+ unsigned char *data = get_data (dso, addr, &sec, &type); \
\
if (data == NULL) \
return -1; \
\
- buf_write_##le##nn (data, val); \
+ if (type == ELF_T_BYTE) \
+ buf_write_##le##nn (data, val); \
+ else \
+ *(uint##nn##_t *)data = val; \
elf_flagscn (dso->scn[sec], ELF_C_SET, ELF_F_DIRTY); \
return 0; \
}
@@ -48,7 +56,7 @@ write_##le##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val) \
#define READWRITE(le,nn) UREAD(le,nn) WRITE(le,nn)
unsigned char *
-get_data (DSO *dso, GElf_Addr addr, int *secp)
+get_data (DSO *dso, GElf_Addr addr, int *secp, Elf_Type *typep)
{
int sec = addr_to_sec (dso, addr);
Elf_Data *data = NULL;
@@ -62,8 +70,10 @@ get_data (DSO *dso, GElf_Addr addr, int *secp)
addr -= dso->shdr[sec].sh_addr;
while ((data = elf_getdata (dso->scn[sec], data)) != NULL)
if (data->d_off <= addr && data->d_off + data->d_size > addr)
+ {
+ if (typep) *typep = data->d_type;
return (unsigned char *) data->d_buf + (addr - data->d_off);
-
+ }
return NULL;
}
diff --git a/src/dso.c b/src/dso.c
index 50443af..af67d83 100644
--- a/src/dso.c
+++ b/src/dso.c
@@ -506,7 +506,7 @@ fdopen_dso (int fd, const char *name)
const char *soname;
soname = get_data (dso, dso->info[DT_STRTAB] + dso->info[DT_SONAME],
- NULL);
+ NULL, NULL);
if (soname && soname[0] != '\0')
dso->soname = (const char *) strdup (soname);
}
diff --git a/src/prelink.h b/src/prelink.h
index ae2e24e..8d147a4 100644
--- a/src/prelink.h
+++ b/src/prelink.h
@@ -206,7 +206,7 @@ int strtabfind (DSO *dso, int strndx, const char *name);
int shstrtabadd (DSO *dso, const char *name);
/* data.c */
-unsigned char * get_data (DSO *dso, GElf_Addr addr, int *scnp);
+unsigned char * get_data (DSO *dso, GElf_Addr addr, int *scnp, Elf_Type *typep);
#define READWRITEPROTO(le,nn) \
uint##nn##_t buf_read_u##le##nn (unsigned char *data); \
uint##nn##_t read_u##le##nn (DSO *dso, GElf_Addr addr); \