summaryrefslogtreecommitdiff
path: root/utils/ldd.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-09-22 00:20:12 +0000
committerMike Frysinger <vapier@gentoo.org>2005-09-22 00:20:12 +0000
commit3ae4f469bfd1fd10fc3e148f75cb9ba4eff9ecdb (patch)
tree3ac3145326f8cfd650e33cbc1fabcbbc91af48bc /utils/ldd.c
parent9186977b216f48391185164070b9765100520dab (diff)
clean 32bit-isms and make code 64/32 bit clean
Diffstat (limited to 'utils/ldd.c')
-rw-r--r--utils/ldd.c178
1 files changed, 113 insertions, 65 deletions
diff --git a/utils/ldd.c b/utils/ldd.c
index 0dc12ad01..51451809c 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -33,6 +33,7 @@
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
+#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -40,17 +41,19 @@
#include <sys/wait.h>
#include "bswap.h"
-#if defined (sun)
#include "link.h"
-#else
#include "elf.h"
-#endif
#include "dl-defs.h"
#ifdef DMALLOC
#include <dmalloc.h>
#endif
+#if defined(__alpha__)
+#define MATCH_MACHINE(x) (x == EM_ALPHA)
+#define ELFCLASSM ELFCLASS64
+#endif
+
#if defined(__arm__) || defined(__thumb__)
#define MATCH_MACHINE(x) (x == EM_ARM)
#define ELFCLASSM ELFCLASS32
@@ -61,6 +64,15 @@
#define ELFCLASSM ELFCLASS32
#endif
+#if defined(__hppa__)
+#define MATCH_MACHINE(x) (x == EM_PARISC)
+#if defined(__LP64__)
+#define ELFCLASSM ELFCLASS64
+#else
+#define ELFCLASSM ELFCLASS32
+#endif
+#endif
+
#if defined(__i386__)
#ifndef EM_486
#define MATCH_MACHINE(x) (x == EM_386)
@@ -70,6 +82,11 @@
#define ELFCLASSM ELFCLASS32
#endif
+#if defined(__ia64__)
+#define MATCH_MACHINE(x) (x == EM_IA_64)
+#define ELFCLASSM ELFCLASS64
+#endif
+
#if defined(__mc68000__)
#define MATCH_MACHINE(x) (x == EM_68K)
#define ELFCLASSM ELFCLASS32
@@ -80,7 +97,10 @@
#define ELFCLASSM ELFCLASS32
#endif
-#if defined(__powerpc__)
+#if defined(__powerpc64__)
+#define MATCH_MACHINE(x) (x == EM_PPC64)
+#define ELFCLASSM ELFCLASS64
+#elif defined(__powerpc__)
#define MATCH_MACHINE(x) (x == EM_PPC)
#define ELFCLASSM ELFCLASS32
#endif
@@ -90,12 +110,12 @@
#define ELFCLASSM ELFCLASS32
#endif
-#if defined (__v850e__)
+#if defined(__v850e__)
#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
#define ELFCLASSM ELFCLASS32
#endif
-#if defined (__sparc__)
+#if defined(__sparc__)
#define MATCH_MACHINE(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
#define ELFCLASSM ELFCLASS32
#endif
@@ -105,8 +125,24 @@
#define ELFCLASSM ELFCLASS32
#endif
+#if defined(__x86_64__)
+#define MATCH_MACHINE(x) (x == EM_X86_64)
+#define ELFCLASSM ELFCLASS64
+#endif
+
#ifndef MATCH_MACHINE
-#warning "You really should add a MATCH_MACHINE() macro for your architecture"
+# ifdef __linux__
+# include <asm/elf.h>
+# endif
+# ifdef ELF_ARCH
+# define MATCH_MACHINE(x) (x == ELF_ARCH)
+# endif
+# ifdef ELF_CLASS
+# define ELFCLASSM ELF_CLASS
+# endif
+#endif
+#ifndef MATCH_MACHINE
+# warning "You really should add a MATCH_MACHINE() macro for your architecture"
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -123,7 +159,7 @@ struct library {
};
struct library *lib_list = NULL;
char not_found[] = "not found";
-char *interp = NULL;
+char *interp_name = NULL;
char *interp_dir = NULL;
int byteswap;
static int interpreter_already_found=0;
@@ -136,26 +172,39 @@ inline uint32_t byteswap32_to_host(uint32_t value)
return(value);
}
}
+inline uint64_t byteswap64_to_host(uint64_t value)
+{
+ if (byteswap==1) {
+ return(bswap_64(value));
+ } else {
+ return(value);
+ }
+}
+#if ELFCLASSM == ELFCLASS32
+# define byteswap_to_host(x) byteswap32_to_host(x)
+#else
+# define byteswap_to_host(x) byteswap64_to_host(x)
+#endif
-Elf32_Shdr * elf_find_section_type( int key, Elf32_Ehdr *ehdr)
+ElfW(Shdr) * elf_find_section_type( int key, ElfW(Ehdr) *ehdr)
{
int j;
- Elf32_Shdr *shdr;
- shdr = (Elf32_Shdr *)(ehdr->e_shoff + (char *)ehdr);
+ ElfW(Shdr) *shdr;
+ shdr = (ElfW(Shdr) *)(ehdr->e_shoff + (char *)ehdr);
for (j = ehdr->e_shnum; --j>=0; ++shdr) {
- if (key==(int)byteswap32_to_host(shdr->sh_type)) {
+ if (key==byteswap32_to_host(shdr->sh_type)) {
return shdr;
}
}
return NULL;
}
-Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr)
+ElfW(Phdr) * elf_find_phdr_type( int type, ElfW(Ehdr) *ehdr)
{
int j;
- Elf32_Phdr *phdr = (Elf32_Phdr *)(ehdr->e_phoff + (char *)ehdr);
+ ElfW(Phdr) *phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (char *)ehdr);
for (j = ehdr->e_phnum; --j>=0; ++phdr) {
- if (type==(int)byteswap32_to_host(phdr->p_type)) {
+ if (type==byteswap32_to_host(phdr->p_type)) {
return phdr;
}
}
@@ -163,40 +212,40 @@ Elf32_Phdr * elf_find_phdr_type( int type, Elf32_Ehdr *ehdr)
}
/* Returns value if return_val==1, ptr otherwise */
-void * elf_find_dynamic(int const key, Elf32_Dyn *dynp,
- Elf32_Ehdr *ehdr, int return_val)
+void * elf_find_dynamic(int const key, ElfW(Dyn) *dynp,
+ ElfW(Ehdr) *ehdr, int return_val)
{
- Elf32_Phdr *pt_text = elf_find_phdr_type(PT_LOAD, ehdr);
- unsigned tx_reloc = byteswap32_to_host(pt_text->p_vaddr) - byteswap32_to_host(pt_text->p_offset);
- for (; DT_NULL!=byteswap32_to_host(dynp->d_tag); ++dynp) {
- if (key == (int)byteswap32_to_host(dynp->d_tag)) {
+ ElfW(Phdr) *pt_text = elf_find_phdr_type(PT_LOAD, ehdr);
+ unsigned tx_reloc = byteswap_to_host(pt_text->p_vaddr) - byteswap_to_host(pt_text->p_offset);
+ for (; DT_NULL!=byteswap_to_host(dynp->d_tag); ++dynp) {
+ if (key == byteswap_to_host(dynp->d_tag)) {
if (return_val == 1)
- return (void *)(intptr_t)byteswap32_to_host(dynp->d_un.d_val);
+ return (void *)byteswap_to_host(dynp->d_un.d_val);
else
- return (void *)(byteswap32_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr );
+ return (void *)(byteswap_to_host(dynp->d_un.d_val) - tx_reloc + (char *)ehdr );
}
}
return NULL;
}
-static char * elf_find_rpath(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic)
+static char * elf_find_rpath(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic)
{
- Elf32_Dyn *dyns;
+ ElfW(Dyn) *dyns;
- for (dyns=dynamic; byteswap32_to_host(dyns->d_tag)!=DT_NULL; ++dyns) {
- if (DT_RPATH == byteswap32_to_host(dyns->d_tag)) {
+ for (dyns=dynamic; byteswap_to_host(dyns->d_tag)!=DT_NULL; ++dyns) {
+ if (DT_RPATH == byteswap_to_host(dyns->d_tag)) {
char *strtab;
strtab = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0);
- return ((char*)strtab + byteswap32_to_host(dyns->d_un.d_val));
+ return ((char*)strtab + byteswap_to_host(dyns->d_un.d_val));
}
}
return NULL;
}
-int check_elf_header(Elf32_Ehdr *const ehdr)
+int check_elf_header(ElfW(Ehdr) *const ehdr)
{
- if (! ehdr || strncmp((void *)ehdr, ELFMAG, SELFMAG) != 0 ||
- ehdr->e_ident[EI_CLASS] != ELFCLASS32 ||
+ if (! ehdr || strncmp((char *)ehdr, ELFMAG, SELFMAG) != 0 ||
+ ehdr->e_ident[EI_CLASS] != ELFCLASSM ||
ehdr->e_ident[EI_VERSION] != EV_CURRENT)
{
return 1;
@@ -220,11 +269,11 @@ int check_elf_header(Elf32_Ehdr *const ehdr)
/* Be vary lazy, and only byteswap the stuff we use */
if (byteswap==1) {
- ehdr->e_type=bswap_16(ehdr->e_type);
- ehdr->e_phoff=bswap_32(ehdr->e_phoff);
- ehdr->e_shoff=bswap_32(ehdr->e_shoff);
- ehdr->e_phnum=bswap_16(ehdr->e_phnum);
- ehdr->e_shnum=bswap_16(ehdr->e_shnum);
+ ehdr->e_type = bswap_16(ehdr->e_type);
+ ehdr->e_phoff = byteswap_to_host(ehdr->e_phoff);
+ ehdr->e_shoff = byteswap_to_host(ehdr->e_shoff);
+ ehdr->e_phnum = bswap_16(ehdr->e_phnum);
+ ehdr->e_shnum = bswap_16(ehdr->e_shnum);
}
return 0;
@@ -357,7 +406,7 @@ static void search_for_named_library(char *name, char *result, const char *path_
*result = '\0';
}
-void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, struct library *lib)
+void locate_library_file(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic, int is_suid, struct library *lib)
{
char *buf;
char *path;
@@ -452,7 +501,7 @@ void locate_library_file(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_suid, stru
}
}
-static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char *s)
+static int add_library(ElfW(Ehdr)* ehdr, ElfW(Dyn)* dynamic, int is_setuid, char *s)
{
char *tmp, *tmp1, *tmp2;
struct library *cur, *newlib=lib_list;
@@ -468,10 +517,10 @@ static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char
}
/* We add ldso elsewhere */
- if (interpreter_already_found && (tmp=strrchr(interp, '/')) != NULL)
+ if (interpreter_already_found && (tmp=strrchr(interp_name, '/')) != NULL)
{
int len = strlen(interp_dir);
- if (strcmp(s, interp+1+len)==0)
+ if (strcmp(s, interp_name+1+len)==0)
return 1;
}
@@ -512,41 +561,41 @@ static int add_library(Elf32_Ehdr* ehdr, Elf32_Dyn* dynamic, int is_setuid, char
return 0;
}
-static void find_needed_libraries(Elf32_Ehdr* ehdr,
- Elf32_Dyn* dynamic, int is_setuid)
+static void find_needed_libraries(ElfW(Ehdr)* ehdr,
+ ElfW(Dyn)* dynamic, int is_setuid)
{
- Elf32_Dyn *dyns;
+ ElfW(Dyn) *dyns;
- for (dyns=dynamic; byteswap32_to_host(dyns->d_tag)!=DT_NULL; ++dyns) {
- if (DT_NEEDED == byteswap32_to_host(dyns->d_tag)) {
+ for (dyns=dynamic; byteswap_to_host(dyns->d_tag)!=DT_NULL; ++dyns) {
+ if (DT_NEEDED == byteswap_to_host(dyns->d_tag)) {
char *strtab;
strtab = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0);
add_library(ehdr, dynamic, is_setuid,
- (char*)strtab + byteswap32_to_host(dyns->d_un.d_val));
+ (char*)strtab + byteswap_to_host(dyns->d_un.d_val));
}
}
}
-static struct library * find_elf_interpreter(Elf32_Ehdr* ehdr)
+static struct library * find_elf_interpreter(ElfW(Ehdr)* ehdr)
{
- Elf32_Phdr *phdr;
+ ElfW(Phdr) *phdr;
- if (interpreter_already_found==1)
+ if (interpreter_already_found == 1)
return NULL;
phdr = elf_find_phdr_type(PT_INTERP, ehdr);
if (phdr) {
struct library *cur, *newlib=NULL;
- char *s = (char*)ehdr + byteswap32_to_host(phdr->p_offset);
+ char *s = (char*)ehdr + byteswap_to_host(phdr->p_offset);
char *tmp, *tmp1;
- interp = strdup(s);
+ interp_name = strdup(s);
interp_dir = strdup(s);
tmp = strrchr(interp_dir, '/');
if (*tmp)
*tmp = '\0';
else {
free(interp_dir);
- interp_dir = interp;
+ interp_dir = interp_name;
}
tmp1 = tmp = s;
while (*tmp) {
@@ -587,7 +636,7 @@ static struct library * find_elf_interpreter(Elf32_Ehdr* ehdr)
cur->next = newlib;
}
#endif
- interpreter_already_found=1;
+ interpreter_already_found = 1;
return newlib;
}
return NULL;
@@ -598,11 +647,11 @@ int find_dependancies(char* filename)
{
int is_suid = 0;
FILE *thefile;
- struct stat statbuf;
- Elf32_Ehdr *ehdr = NULL;
- Elf32_Shdr *dynsec = NULL;
- Elf32_Dyn *dynamic = NULL;
struct library *interp;
+ struct stat statbuf;
+ ElfW(Ehdr) *ehdr = NULL;
+ ElfW(Shdr) *dynsec = NULL;
+ ElfW(Dyn) *dynamic = NULL;
if (filename == not_found)
return 0;
@@ -621,14 +670,14 @@ int find_dependancies(char* filename)
return -1;
}
- if ((size_t)statbuf.st_size < sizeof(Elf32_Ehdr))
+ if ((size_t)statbuf.st_size < sizeof(ElfW(Ehdr)))
goto foo;
if (!S_ISREG(statbuf.st_mode))
goto foo;
/* mmap the file to make reading stuff from it effortless */
- ehdr = (Elf32_Ehdr *)mmap(0, statbuf.st_size,
+ ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size,
PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0);
if (ehdr == MAP_FAILED) {
fclose(thefile);
@@ -659,7 +708,7 @@ foo:
fprintf(stderr, "%s: is setuid\n", filename);
}
- interpreter_already_found=0;
+ interpreter_already_found = 0;
interp = find_elf_interpreter(ehdr);
#ifdef __LDSO_LDD_SUPPORT__
@@ -700,7 +749,7 @@ foo:
dynsec = elf_find_section_type(SHT_DYNAMIC, ehdr);
if (dynsec) {
- dynamic = (Elf32_Dyn*)(byteswap32_to_host(dynsec->sh_offset) + (intptr_t)ehdr);
+ dynamic = (ElfW(Dyn)*)(byteswap_to_host(dynsec->sh_offset) + (char *)ehdr);
find_needed_libraries(ehdr, dynamic, is_suid);
}
@@ -731,7 +780,7 @@ int main( int argc, char** argv)
continue;
}
- if(strcmp(*argv, "--help")==0) {
+ if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
fprintf(stderr, "Usage: ldd [OPTION]... FILE...\n");
fprintf(stderr, "\t--help\t\tprint this help and exit\n");
exit(EXIT_FAILURE);
@@ -773,8 +822,8 @@ int main( int argc, char** argv)
got_em_all=1;
printf("\t%s => %s (0x00000000)\n", cur->name, cur->path);
}
- if (interp && interpreter_already_found==1)
- printf("\t%s => %s (0x00000000)\n", interp, interp);
+ if (interp_name && interpreter_already_found==1)
+ printf("\t%s => %s (0x00000000)\n", interp_name, interp_name);
else
printf("\tnot a dynamic executable\n");
@@ -791,4 +840,3 @@ int main( int argc, char** argv)
return 0;
}
-