summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2002-05-24 06:24:40 +0000
committerru <ru@FreeBSD.org>2002-05-24 06:24:40 +0000
commit3d4d4bf6526b7c0ba67d8d3ee6b5d80604b66dee (patch)
tree54a7b9386a846a3c0355af17ba54cf6a40b54369 /usr.sbin
parentede3ec51b9ee94d21bf9a7addfcbf259fc9876ae (diff)
downloadFreeBSD-src-3d4d4bf6526b7c0ba67d8d3ee6b5d80604b66dee.zip
FreeBSD-src-3d4d4bf6526b7c0ba67d8d3ee6b5d80604b66dee.tar.gz
Handle endianness. This completes cross-support for sparc64.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/crunch/crunchide/endian.h57
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c95
2 files changed, 112 insertions, 40 deletions
diff --git a/usr.sbin/crunch/crunchide/endian.h b/usr.sbin/crunch/crunchide/endian.h
new file mode 100644
index 0000000..2234f78
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/endian.h
@@ -0,0 +1,57 @@
+/*
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#if __FreeBSD_version >= 500034
+#include <sys/endian.h>
+#else
+#include <machine/endian.h>
+
+#define bswap16(x) (uint16_t) \
+ ((x >> 8) | (x << 8))
+
+#define bswap32(x) (uint32_t) \
+ ((x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24))
+
+#define bswap64(x) (uint64_t) \
+ ((x >> 56) | ((x >> 40) & 0xff00) | ((x >> 24) & 0xff0000) | \
+ ((x >> 8) & 0xff000000) | ((x << 8) & ((uint64_t)0xff << 32)) | \
+ ((x << 24) & ((uint64_t)0xff << 40)) | \
+ ((x << 40) & ((uint64_t)0xff << 48)) | ((x << 56)))
+
+/*
+ * Host to big endian, host to little endian, big endian to host, and little
+ * endian to host byte order functions as detailed in byteorder(9).
+ */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define htobe16(x) bswap16((uint16_t)(x))
+#define htobe32(x) bswap32((uint32_t)(x))
+#define htobe64(x) bswap64((uint64_t)(x))
+#define htole16(x) ((uint16_t)(x))
+#define htole32(x) ((uint32_t)(x))
+#define htole64(x) ((uint64_t)(x))
+
+#define be16toh(x) bswap16((uint16_t)(x))
+#define be32toh(x) bswap32((uint32_t)(x))
+#define be64toh(x) bswap64((uint64_t)(x))
+#define le16toh(x) ((uint16_t)(x))
+#define le32toh(x) ((uint32_t)(x))
+#define le64toh(x) ((uint64_t)(x))
+#else /* _BYTE_ORDER != _LITTLE_ENDIAN */
+#define htobe16(x) ((uint16_t)(x))
+#define htobe32(x) ((uint32_t)(x))
+#define htobe64(x) ((uint64_t)(x))
+#define htole16(x) bswap16((uint16_t)(x))
+#define htole32(x) bswap32((uint32_t)(x))
+#define htole64(x) bswap64((uint64_t)(x))
+
+#define be16toh(x) ((uint16_t)(x))
+#define be32toh(x) ((uint32_t)(x))
+#define be64toh(x) ((uint64_t)(x))
+#define le16toh(x) bswap16((uint16_t)(x))
+#define le32toh(x) bswap32((uint32_t)(x))
+#define le64toh(x) bswap64((uint64_t)(x))
+#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
+#endif
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
index e14abd4..5750ced6 100644
--- a/usr.sbin/crunch/crunchide/exec_elf32.c
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -50,6 +50,7 @@ static const char rcsid[] =
#include <string.h>
#include <unistd.h>
+#include "endian.h"
#include "extern.h"
#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \
@@ -58,8 +59,10 @@ static const char rcsid[] =
#define __ELF_WORD_SIZE ELFSIZE
#if (ELFSIZE == 32)
#include <sys/elf32.h>
+#define xewtoh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x))
#elif (ELFSIZE == 64)
#include <sys/elf64.h>
+#define xewtoh(x) ((data == ELFDATA2MSB) ? be64toh(x) : le64toh(x))
#endif
#include <sys/elf_generic.h>
@@ -69,6 +72,10 @@ static const char rcsid[] =
#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
+#define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x))
+#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x))
+#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x))
+
struct listelem {
struct listelem *next;
void *mem;
@@ -127,6 +134,7 @@ ELFNAMEEND(check)(int fd, const char *fn)
{
Elf_Ehdr eh;
struct stat sb;
+ unsigned char data;
/*
* Check the header to maek sure it's an ELF file (of the
@@ -142,7 +150,9 @@ ELFNAMEEND(check)(int fd, const char *fn)
if (IS_ELF(eh) == 0)
return 0;
- switch (eh.e_machine) {
+ data = eh.e_ident[EI_DATA];
+
+ switch (xe16toh(eh.e_machine)) {
case EM_386: break;
case EM_ALPHA: break;
case EM_IA_64: break;
@@ -167,26 +177,30 @@ ELFNAMEEND(hide)(int fd, const char *fn)
struct listelem *relalist = NULL, *rellist = NULL, *tmpl;
ssize_t shdrsize;
int rv, i, weird;
+ unsigned char data;
rv = 0;
if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr)
goto bad;
- shdrsize = ehdr.e_shnum * ehdr.e_shentsize;
+ data = ehdr.e_ident[EI_DATA];
+
+ shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize);
if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL)
goto bad;
- if (xreadatoff(fd, shdrp, ehdr.e_shoff, shdrsize, fn) != shdrsize)
+ if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) !=
+ shdrsize)
goto bad;
symtabshdr = strtabshdr = NULL;
weird = 0;
- for (i = 0; i < ehdr.e_shnum; i++) {
- switch (shdrp[i].sh_type) {
+ for (i = 0; i < xe16toh(ehdr.e_shnum); i++) {
+ switch (xe32toh(shdrp[i].sh_type)) {
case SHT_SYMTAB:
if (symtabshdr != NULL)
weird = 1;
symtabshdr = &shdrp[i];
- strtabshdr = &shdrp[shdrp[i].sh_link];
+ strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)];
break;
case SHT_RELA:
tmpl = xmalloc(sizeof *tmpl, fn, "rela list element");
@@ -224,44 +238,44 @@ ELFNAMEEND(hide)(int fd, const char *fn)
*/
/* symbol table */
- if ((symtabp = xmalloc(symtabshdr->sh_size, fn, "symbol table"))
+ if ((symtabp = xmalloc(xewtoh(symtabshdr->sh_size), fn, "symbol table"))
== NULL)
goto bad;
- if (xreadatoff(fd, symtabp, symtabshdr->sh_offset, symtabshdr->sh_size,
- fn) != symtabshdr->sh_size)
+ if (xreadatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset),
+ xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size))
goto bad;
/* string table */
- if ((strtabp = xmalloc(strtabshdr->sh_size, fn, "string table"))
+ if ((strtabp = xmalloc(xewtoh(strtabshdr->sh_size), fn, "string table"))
== NULL)
goto bad;
- if (xreadatoff(fd, strtabp, strtabshdr->sh_offset, strtabshdr->sh_size,
- fn) != strtabshdr->sh_size)
+ if (xreadatoff(fd, strtabp, xewtoh(strtabshdr->sh_offset),
+ xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size))
goto bad;
/* any rela tables */
for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
- if ((tmpl->mem = xmalloc(tmpl->size, fn, "rela table"))
+ if ((tmpl->mem = xmalloc(xewtoh(tmpl->size), fn, "rela table"))
== NULL)
goto bad;
- if (xreadatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
- tmpl->size)
+ if (xreadatoff(fd, tmpl->mem, xewtoh(tmpl->file),
+ xewtoh(tmpl->size), fn) != xewtoh(tmpl->size))
goto bad;
}
/* any rel tables */
for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
- if ((tmpl->mem = xmalloc(tmpl->size, fn, "rel table"))
+ if ((tmpl->mem = xmalloc(xewtoh(tmpl->size), fn, "rel table"))
== NULL)
goto bad;
- if (xreadatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
- tmpl->size)
+ if (xreadatoff(fd, tmpl->mem, xewtoh(tmpl->file),
+ xewtoh(tmpl->size), fn) != xewtoh(tmpl->size))
goto bad;
}
/* Prepare data structures for symbol movement. */
- nsyms = symtabshdr->sh_size / symtabshdr->sh_entsize;
- nlocalsyms = symtabshdr->sh_info;
+ nsyms = xewtoh(symtabshdr->sh_size) / xewtoh(symtabshdr->sh_entsize);
+ nlocalsyms = xe32toh(symtabshdr->sh_info);
if ((symfwmap = xmalloc(nsyms * sizeof (Elf_Word), fn,
"symbol forward mapping table")) == NULL)
goto bad;
@@ -281,11 +295,11 @@ ELFNAMEEND(hide)(int fd, const char *fn)
sp = &symtabp[ewi];
/* if it's on our keep list, don't move it */
- if (in_keep_list(strtabp + sp->st_name))
+ if (in_keep_list(strtabp + xe32toh(sp->st_name)))
continue;
/* if it's an undefined symbol, keep it */
- if (sp->st_shndx == SHN_UNDEF)
+ if (xe16toh(sp->st_shndx) == SHN_UNDEF)
continue;
/* adjust the symbol so that it's local */
@@ -309,7 +323,7 @@ ELFNAMEEND(hide)(int fd, const char *fn)
nlocalsyms++; /* note new local sym */
}
- symtabshdr->sh_info = nlocalsyms;
+ symtabshdr->sh_info = htoxe32(nlocalsyms);
/* set up symbol # -> location mapping table */
for (ewi = 0; ewi < nsyms; ewi++)
@@ -319,14 +333,14 @@ ELFNAMEEND(hide)(int fd, const char *fn)
for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
Elf_Rela *relap = tmpl->mem;
- for (ewi = 0; ewi < tmpl->size / sizeof(*relap); ewi++) {
+ for (ewi = 0; ewi < xewtoh(tmpl->size) / sizeof(*relap); ewi++) {
relap[ewi].r_info =
#if (ELFSIZE == 32) /* XXX */
- symfwmap[ELF_R_SYM(relap[ewi].r_info)] << 8 |
- ELF_R_TYPE(relap[ewi].r_info);
+ symfwmap[ELF_R_SYM(xe32toh(relap[ewi].r_info))] << 8 |
+ ELF_R_TYPE(xe32toh(relap[ewi].r_info));
#elif (ELFSIZE == 64) /* XXX */
- symfwmap[ELF_R_SYM(relap[ewi].r_info)] << 32 |
- ELF_R_TYPE(relap[ewi].r_info);
+ symfwmap[ELF_R_SYM(xewtoh(relap[ewi].r_info))] << 32 |
+ ELF_R_TYPE(xewtoh(relap[ewi].r_info));
#endif /* XXX */
}
}
@@ -335,14 +349,14 @@ ELFNAMEEND(hide)(int fd, const char *fn)
for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
Elf_Rel *relp = tmpl->mem;
- for (ewi = 0; ewi < tmpl->size / sizeof *relp; ewi++) {
+ for (ewi = 0; ewi < xewtoh(tmpl->size) / sizeof *relp; ewi++) {
relp[ewi].r_info =
#if (ELFSIZE == 32) /* XXX */
- symfwmap[ELF_R_SYM(relp[ewi].r_info)] << 8 |
- ELF_R_TYPE(relp[ewi].r_info);
+ symfwmap[ELF_R_SYM(xe32toh(relp[ewi].r_info))] << 8 |
+ ELF_R_TYPE(xe32toh(relp[ewi].r_info));
#elif (ELFSIZE == 64) /* XXX */
- symfwmap[ELF_R_SYM(relp[ewi].r_info)] << 32 |
- ELF_R_TYPE(relp[ewi].r_info);
+ symfwmap[ELF_R_SYM(xewtoh(relp[ewi].r_info))] << 32 |
+ ELF_R_TYPE(xewtoh(relp[ewi].r_info));
#endif /* XXX */
}
}
@@ -350,19 +364,20 @@ ELFNAMEEND(hide)(int fd, const char *fn)
/*
* write new tables to the file
*/
- if (xwriteatoff(fd, shdrp, ehdr.e_shoff, shdrsize, fn) != shdrsize)
+ if (xwriteatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) !=
+ shdrsize)
goto bad;
- if (xwriteatoff(fd, symtabp, symtabshdr->sh_offset,
- symtabshdr->sh_size, fn) != symtabshdr->sh_size)
+ if (xwriteatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset),
+ xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size))
goto bad;
for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
- if (xwriteatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
- tmpl->size)
+ if (xwriteatoff(fd, tmpl->mem, xewtoh(tmpl->file),
+ xewtoh(tmpl->size), fn) != xewtoh(tmpl->size))
goto bad;
}
for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
- if (xwriteatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
- tmpl->size)
+ if (xwriteatoff(fd, tmpl->mem, xewtoh(tmpl->file),
+ xewtoh(tmpl->size), fn) != xewtoh(tmpl->size))
goto bad;
}
OpenPOWER on IntegriCloud