From f68eb8d50b11310628f53a9378bf612e8d4bfa09 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 4 Jun 2001 22:13:51 +0000 Subject: Teach the ldso stuff to use the proper elf.h header file, not a local copy. -Erik --- ldso/util/.cvsignore | 1 + ldso/util/Makefile | 22 +++++---- ldso/util/ldconfig.c | 3 +- ldso/util/ldd.c | 5 ++- ldso/util/readelf.h | 4 -- ldso/util/readelf2.c | 115 ------------------------------------------------ ldso/util/readsoname.c | 61 +++++++++++++++++++++++++ ldso/util/readsoname.h | 4 ++ ldso/util/readsoname2.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 198 insertions(+), 132 deletions(-) delete mode 100644 ldso/util/readelf.h delete mode 100644 ldso/util/readelf2.c create mode 100644 ldso/util/readsoname.c create mode 100644 ldso/util/readsoname.h create mode 100644 ldso/util/readsoname2.c (limited to 'ldso/util') diff --git a/ldso/util/.cvsignore b/ldso/util/.cvsignore index 65cb593d4..8d9e73db5 100644 --- a/ldso/util/.cvsignore +++ b/ldso/util/.cvsignore @@ -1,2 +1,3 @@ ldd ldconfig +readelf diff --git a/ldso/util/Makefile b/ldso/util/Makefile index a8f482f20..8fe733eb9 100644 --- a/ldso/util/Makefile +++ b/ldso/util/Makefile @@ -2,14 +2,15 @@ TOPDIR=../../ include $(TOPDIR)/ldso/Rules.mak CFLAGS += -DLDSO_ADDR="0x62f00020" # needed by ldd.o -CFLAGS += -I./ -I../../include/ -LDFLAGS += -nostdlib $(TOPDIR)lib/libc.a $(TOPDIR)lib/crt0.o $(GCCINCDIR)/../libgcc.a +#CFLAGS += -I./ -I../../include/ +#LDFLAGS += -nostdlib $(TOPDIR)lib/libc.a $(TOPDIR)lib/crt0.o $(GCCINCDIR)/../libgcc.a +LDFLAGS += $(TOPDIR)lib/libc.a $(TOPDIR)lib/crt0.o $(GCCINCDIR)/../libgcc.a -ALL = ldconfig ldd # lddstub +ALL = ldconfig ldd readelf # lddstub all: $(ALL) -CSRC= readelf.c ldconfig.c ldd.c +CSRC= readelf.c ldconfig.c ldd.c readsoname.c COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) @@ -17,13 +18,16 @@ $(COBJS): %.o : %.c $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o -readelf.o: readelf.c readelf2.c +readsoname.o: readsoname.c readsoname2.c -ldconfig: ldconfig.o readelf.o - $(CC) -static $(CFLAGS) $^ $(LDFLAGS) -o $@ +readelf: readelf.o + $(CC) $(CFLAGS) $^ -o $@ -ldd: ldd.o readelf.o - $(CC) -static $(CFLAGS) $^ $(LDFLAGS) -o $@ +ldconfig: ldconfig.o readsoname.o + $(CC) $(CFLAGS) $^ -o $@ + +ldd: ldd.o readsoname.o + $(CC) $(CFLAGS) $^ -o $@ #ifeq ($(DEBUG),true) #STUBFLAGS = -Wl,-dynamic-linker,../d-link/ld-linux.so diff --git a/ldso/util/ldconfig.c b/ldso/util/ldconfig.c index 55f79f773..58f9cb10b 100644 --- a/ldso/util/ldconfig.c +++ b/ldso/util/ldconfig.c @@ -38,9 +38,8 @@ #include #include #include - #include "../config.h" -#include "readelf.h" +#include "readsoname.h" struct exec { diff --git a/ldso/util/ldd.c b/ldso/util/ldd.c index ea4f1f5ef..dcf895d19 100644 --- a/ldso/util/ldd.c +++ b/ldso/util/ldd.c @@ -23,9 +23,10 @@ #include #include #include -#include "../d-link/elf.h" +#include +#include "../d-link/linuxelf.h" #include "../config.h" -#include "readelf.h" +#include "readsoname.h" struct exec { diff --git a/ldso/util/readelf.h b/ldso/util/readelf.h deleted file mode 100644 index 78d2216e0..000000000 --- a/ldso/util/readelf.h +++ /dev/null @@ -1,4 +0,0 @@ -char *readsoname(char *name, FILE *file, int expected_type, - int *type, int elfclass); -char *readsoname32(char *name, FILE *file, int expected_type, int *type); -char *readsoname64(char *name, FILE *file, int expected_type, int *type); diff --git a/ldso/util/readelf2.c b/ldso/util/readelf2.c deleted file mode 100644 index 1bf47b7c6..000000000 --- a/ldso/util/readelf2.c +++ /dev/null @@ -1,115 +0,0 @@ -char *readsonameXX(char *name, FILE *infile, int expected_type, int *type) -{ - ElfW(Ehdr) *epnt; - ElfW(Phdr) *ppnt; - int i, j; - char *header; - ElfW(Word) dynamic_addr = 0; - ElfW(Word) dynamic_size = 0; - unsigned long page_size = getpagesize(); - ElfW(Word) strtab_val = 0; - ElfW(Word) needed_val; - ElfW(Sword) loadaddr = -1; - ElfW(Dyn) *dpnt; - struct stat st; - char *needed; - char *soname = NULL; - int multi_libcs = 0; - - if(expected_type == LIB_DLL) - { - warn("%s does not match type specified for directory!", name); - expected_type = LIB_ANY; - } - - *type = LIB_ELF; - - if (fstat(fileno(infile), &st)) - return NULL; - header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0); - if (header == (caddr_t)-1) - return NULL; - - epnt = (ElfW(Ehdr) *)header; - if ((char *)(epnt+1) > (char *)(header + st.st_size)) - goto skip; - - ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff]; - if ((char *)ppnt < (char *)header || - (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size)) - goto skip; - - for(i = 0; i < epnt->e_phnum; i++) - { - if (loadaddr == -1 && ppnt->p_type == PT_LOAD) - loadaddr = (ppnt->p_vaddr & ~(page_size-1)) - - (ppnt->p_offset & ~(page_size-1)); - if(ppnt->p_type == 2) - { - dynamic_addr = ppnt->p_offset; - dynamic_size = ppnt->p_filesz; - }; - ppnt++; - }; - - dpnt = (ElfW(Dyn) *) &header[dynamic_addr]; - dynamic_size = dynamic_size / sizeof(ElfW(Dyn)); - if ((char *)dpnt < (char *)header || - (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size)) - goto skip; - - while (dpnt->d_tag != DT_NULL) - { - if (dpnt->d_tag == DT_STRTAB) - strtab_val = dpnt->d_un.d_val; - dpnt++; - }; - - if (!strtab_val) - goto skip; - - dpnt = (ElfW(Dyn) *) &header[dynamic_addr]; - while (dpnt->d_tag != DT_NULL) - { - if (dpnt->d_tag == DT_SONAME || dpnt->d_tag == DT_NEEDED) - { - needed_val = dpnt->d_un.d_val; - if (needed_val + strtab_val - loadaddr >= 0 || - needed_val + strtab_val - loadaddr < st.st_size) - { - needed = (char *) (header - loadaddr + strtab_val + needed_val); - - if (dpnt->d_tag == DT_SONAME) - soname = xstrdup(needed); - - for (j = 0; needed_tab[j].soname != NULL; j++) - { - if (strcmp(needed, needed_tab[j].soname) == 0) - { - if (*type != LIB_ELF && *type != needed_tab[j].type) - multi_libcs = 1; - *type = needed_tab[j].type; - } - } - } - } - dpnt++; - }; - - if (multi_libcs) - warn("%s appears to be for multiple libc's", name); - - /* If we could not deduce the libc type, and we know what to expect, set the type */ - if(*type == LIB_ELF && expected_type != LIB_ANY) *type = expected_type; - - if(expected_type != LIB_ANY && expected_type != LIB_ELF && - expected_type != *type) - { - warn("%s does not match type specified for directory!", name); - } - - skip: - munmap(header, st.st_size); - - return soname; -} diff --git a/ldso/util/readsoname.c b/ldso/util/readsoname.c new file mode 100644 index 000000000..db772f0ae --- /dev/null +++ b/ldso/util/readsoname.c @@ -0,0 +1,61 @@ +/* adapted from Eric Youngdale's readelf program */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../config.h" +#include "readsoname.h" + +void warn(char *fmt, ...); +char *xstrdup(char *); + +struct needed_tab +{ + char *soname; + int type; +}; + +struct needed_tab needed_tab[] = { + { "libc.so.5", LIB_ELF_LIBC5 }, + { "libm.so.5", LIB_ELF_LIBC5 }, + { "libdl.so.1", LIB_ELF_LIBC5 }, + { "libc.so.6", LIB_ELF_LIBC6 }, + { "libm.so.6", LIB_ELF_LIBC6 }, + { "libdl.so.2", LIB_ELF_LIBC6 }, + { NULL, LIB_ELF } +}; + +char *readsoname(char *name, FILE *infile, int expected_type, + int *type, int elfclass) +{ + char *res; + + if (elfclass == ELFCLASS32) + res = readsoname32(name, infile, expected_type, type); + else + { + res = readsoname64(name, infile, expected_type, type); +#if 0 + *type |= LIB_ELF64; +#endif + } + + return res; +} + +#undef __ELF_NATIVE_CLASS +#undef readsonameXX +#define readsonameXX readsoname32 +#define __ELF_NATIVE_CLASS 32 +#include "readsoname2.c" + +#undef __ELF_NATIVE_CLASS +#undef readsonameXX +#define readsonameXX readsoname64 +#define __ELF_NATIVE_CLASS 64 +#include "readsoname2.c" diff --git a/ldso/util/readsoname.h b/ldso/util/readsoname.h new file mode 100644 index 000000000..78d2216e0 --- /dev/null +++ b/ldso/util/readsoname.h @@ -0,0 +1,4 @@ +char *readsoname(char *name, FILE *file, int expected_type, + int *type, int elfclass); +char *readsoname32(char *name, FILE *file, int expected_type, int *type); +char *readsoname64(char *name, FILE *file, int expected_type, int *type); diff --git a/ldso/util/readsoname2.c b/ldso/util/readsoname2.c new file mode 100644 index 000000000..1bf47b7c6 --- /dev/null +++ b/ldso/util/readsoname2.c @@ -0,0 +1,115 @@ +char *readsonameXX(char *name, FILE *infile, int expected_type, int *type) +{ + ElfW(Ehdr) *epnt; + ElfW(Phdr) *ppnt; + int i, j; + char *header; + ElfW(Word) dynamic_addr = 0; + ElfW(Word) dynamic_size = 0; + unsigned long page_size = getpagesize(); + ElfW(Word) strtab_val = 0; + ElfW(Word) needed_val; + ElfW(Sword) loadaddr = -1; + ElfW(Dyn) *dpnt; + struct stat st; + char *needed; + char *soname = NULL; + int multi_libcs = 0; + + if(expected_type == LIB_DLL) + { + warn("%s does not match type specified for directory!", name); + expected_type = LIB_ANY; + } + + *type = LIB_ELF; + + if (fstat(fileno(infile), &st)) + return NULL; + header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0); + if (header == (caddr_t)-1) + return NULL; + + epnt = (ElfW(Ehdr) *)header; + if ((char *)(epnt+1) > (char *)(header + st.st_size)) + goto skip; + + ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff]; + if ((char *)ppnt < (char *)header || + (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size)) + goto skip; + + for(i = 0; i < epnt->e_phnum; i++) + { + if (loadaddr == -1 && ppnt->p_type == PT_LOAD) + loadaddr = (ppnt->p_vaddr & ~(page_size-1)) - + (ppnt->p_offset & ~(page_size-1)); + if(ppnt->p_type == 2) + { + dynamic_addr = ppnt->p_offset; + dynamic_size = ppnt->p_filesz; + }; + ppnt++; + }; + + dpnt = (ElfW(Dyn) *) &header[dynamic_addr]; + dynamic_size = dynamic_size / sizeof(ElfW(Dyn)); + if ((char *)dpnt < (char *)header || + (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size)) + goto skip; + + while (dpnt->d_tag != DT_NULL) + { + if (dpnt->d_tag == DT_STRTAB) + strtab_val = dpnt->d_un.d_val; + dpnt++; + }; + + if (!strtab_val) + goto skip; + + dpnt = (ElfW(Dyn) *) &header[dynamic_addr]; + while (dpnt->d_tag != DT_NULL) + { + if (dpnt->d_tag == DT_SONAME || dpnt->d_tag == DT_NEEDED) + { + needed_val = dpnt->d_un.d_val; + if (needed_val + strtab_val - loadaddr >= 0 || + needed_val + strtab_val - loadaddr < st.st_size) + { + needed = (char *) (header - loadaddr + strtab_val + needed_val); + + if (dpnt->d_tag == DT_SONAME) + soname = xstrdup(needed); + + for (j = 0; needed_tab[j].soname != NULL; j++) + { + if (strcmp(needed, needed_tab[j].soname) == 0) + { + if (*type != LIB_ELF && *type != needed_tab[j].type) + multi_libcs = 1; + *type = needed_tab[j].type; + } + } + } + } + dpnt++; + }; + + if (multi_libcs) + warn("%s appears to be for multiple libc's", name); + + /* If we could not deduce the libc type, and we know what to expect, set the type */ + if(*type == LIB_ELF && expected_type != LIB_ANY) *type = expected_type; + + if(expected_type != LIB_ANY && expected_type != LIB_ELF && + expected_type != *type) + { + warn("%s does not match type specified for directory!", name); + } + + skip: + munmap(header, st.st_size); + + return soname; +} -- cgit v1.2.3