diff --git a/src/bin/ld/Makefile b/src/bin/ld/Makefile index 768d90f..77d3e6a 100644 --- a/src/bin/ld/Makefile +++ b/src/bin/ld/Makefile @@ -15,7 +15,7 @@ REMOVE = rm -f #Objects -OBJS = main.o +OBJS = main.o findlibrary.o findfunc.o addlibrary.o #Startup File STARTUP = ../../lib/ubix/startup.o @@ -46,4 +46,4 @@ # Clean Up The junk clean: - $(REMOVE) $(OBJS) $(BINARY) + $(REMOVE) $(OBJS) $(OUTPUT) diff --git a/src/bin/ld/addlibrary.c b/src/bin/ld/addlibrary.c new file mode 100644 index 0000000..1d34271 --- /dev/null +++ b/src/bin/ld/addlibrary.c @@ -0,0 +1,121 @@ +#include +#include +#include "ld.h" + +ldLibrary *ldAddLibrary(char *lib) { + int i = 0x0; + int x = 0x0; + int rel = 0x0; + uInt32 *reMap = 0x0; + char *newLoc = 0x0; + FILE *linkerFd = 0x0; + ldLibrary *tmpLib = 0x0; + + tmpLib = (ldLibrary *)malloc(sizeof(ldLibrary)); + + if (tmpLib->output == 0x0) { + linkerFd = fopen(lib,"rb"); + if (linkerFd == 0x0) { + printf("Cant Open Library: %s\n",lib); + exit(-1); + } + tmpLib->output = (char *)malloc((linkerFd->size+0x4000)); + sprintf(tmpLib->name,lib); + } + + if (tmpLib->linkerHeader == 0x0) { + fseek(linkerFd,0x0,0x0); + tmpLib->linkerHeader = (elfHeader *)malloc(sizeof(elfHeader)); + fread(tmpLib->linkerHeader,sizeof(elfHeader),1,linkerFd); + } + + if (tmpLib->linkerProgramHeader == 0x0) { + tmpLib->linkerProgramHeader = (elfProgramHeader *)malloc(sizeof(elfProgramHeader)*tmpLib->linkerHeader->ePhnum); + fseek(linkerFd,tmpLib->linkerHeader->ePhoff,0); + fread(tmpLib->linkerProgramHeader,sizeof(elfProgramHeader),tmpLib->linkerHeader->ePhnum,linkerFd); + + for (i=0;ilinkerHeader->ePhnum;i++) { + switch (tmpLib->linkerProgramHeader[i].phType) { + case 1: + case 2: + newLoc = (char *)tmpLib->linkerProgramHeader[i].phVaddr + (uInt32)tmpLib->output; + fseek(linkerFd,tmpLib->linkerProgramHeader[i].phOffset,0); + fread(newLoc,tmpLib->linkerProgramHeader[i].phFilesz,1,linkerFd); + break; + default: + printf("Unhandled Header\n"); + break; + } + } + } + + if (tmpLib->linkerSectionHeader == 0x0) { + tmpLib->linkerSectionHeader = (elfSectionHeader *)malloc(sizeof(elfSectionHeader)*tmpLib->linkerHeader->eShnum); + fseek(linkerFd,tmpLib->linkerHeader->eShoff,0); + fread(tmpLib->linkerSectionHeader,sizeof(elfSectionHeader),tmpLib->linkerHeader->eShnum,linkerFd); + + if (tmpLib->linkerShStr == 0x0) { + tmpLib->linkerShStr = (char *)malloc(tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shOffset,0); + fread(tmpLib->linkerShStr,tmpLib->linkerSectionHeader[tmpLib->linkerHeader->eShstrndx].shSize,1,linkerFd); + } + + for (i=0x0;ilinkerHeader->eShnum;i++) { + switch (tmpLib->linkerSectionHeader[i].shType) { + case 3: + if (!strcmp((tmpLib->linkerShStr + tmpLib->linkerSectionHeader[i].shName),".dynstr")) { + if (tmpLib->linkerDynStr == 0x0) { + tmpLib->linkerDynStr = (char *)malloc(tmpLib->linkerSectionHeader[i].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[i].shOffset,0); + fread(tmpLib->linkerDynStr,tmpLib->linkerSectionHeader[i].shSize,1,linkerFd); + } + } + break; + case 9: + rel = i; + break; + case 11: + if (tmpLib->linkerRelSymTab == 0x0) { + tmpLib->linkerRelSymTab = (elfDynSym *)malloc(tmpLib->linkerSectionHeader[i].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[i].shOffset,0); + fread(tmpLib->linkerRelSymTab,tmpLib->linkerSectionHeader[i].shSize,1,linkerFd); + tmpLib->sym = i; + } + break; + } + } + } + + if (tmpLib->linkerElfRel == 0x0) { + tmpLib->linkerElfRel = (elfPltInfo *)malloc(tmpLib->linkerSectionHeader[rel].shSize); + fseek(linkerFd,tmpLib->linkerSectionHeader[rel].shOffset,0x0); + fread(tmpLib->linkerElfRel,tmpLib->linkerSectionHeader[rel].shSize,1,linkerFd); + + for (i=0x0;ilinkerSectionHeader[rel].shSize/sizeof(elfPltInfo);i++) { + x = ELF32_R_SYM(tmpLib->linkerElfRel[i].pltInfo); + reMap = (uInt32 *)((uInt32)tmpLib->output + tmpLib->linkerElfRel[i].pltOffset); + switch (ELF32_R_TYPE(tmpLib->linkerElfRel[i].pltInfo)) { + case R_386_32: + *reMap += ((uInt32)tmpLib->output + tmpLib->linkerRelSymTab[x].dynValue); + break; + case R_386_PC32: + *reMap += ((uInt32)tmpLib->output + tmpLib->linkerRelSymTab[x].dynValue) - (uInt32)reMap; + break; + case R_386_RELATIVE: + *reMap += (uInt32)tmpLib->output; + break; + default: + //printf("[0x%X][0x%X](%i)[%s]\n",elfRel[i].pltOffset,elfRel[i].pltInfo,x,elfGetRelType(ELF32_R_TYPE(elfRel[i].pltInfo))); + //printf("relTab [%s][0x%X][0x%X]\n",dynStr + relSymTab[x].dynName,relSymTab[x].dynValue,relSymTab[x].dynName); + printf("Unhandled sym\n"); + break; + } + } + } + libs->prev = tmpLib; + tmpLib->prev = 0x0; + tmpLib->next = libs; + libs = tmpLib; + + return(tmpLib); + } diff --git a/src/bin/ld/findfunc.c b/src/bin/ld/findfunc.c new file mode 100644 index 0000000..b17803e --- /dev/null +++ b/src/bin/ld/findfunc.c @@ -0,0 +1,24 @@ +#include +#include +#include "ld.h" + +uInt32 ldFindFunc(char *func,char *lib) { + int i = 0x0; + uInt32 *funcPtr = 0x0; + ldLibrary *libPtr = 0x0; + + libPtr = ldFindLibrary(lib); + if (libPtr == 0x0) { + libPtr = ldAddLibrary(lib); + } + + for (i=0x0;ilinkerSectionHeader[libPtr->sym].shSize/sizeof(elfDynSym);i++) { + if (!strcmp(func,(libPtr->linkerDynStr + libPtr->linkerRelSymTab[i].dynName))) { + funcPtr = (uInt32 *)((uInt32)(libPtr->linkerRelSymTab[i].dynValue) + (uInt32)libPtr->output); + break; + } + } + + return((uInt32)funcPtr); + } + diff --git a/src/bin/ld/findlibrary.c b/src/bin/ld/findlibrary.c new file mode 100644 index 0000000..f81c8d0 --- /dev/null +++ b/src/bin/ld/findlibrary.c @@ -0,0 +1,14 @@ +#include +#include "ld.h" + +ldLibrary *ldFindLibrary(char *lib) { + ldLibrary *tmpLibs = 0x0; + + for (tmpLibs = libs;tmpLibs;tmpLibs = tmpLibs->next) { + if (!strcmp(tmpLibs->name,lib)) { + return(tmpLibs); + } + } + + return(0x0); + } diff --git a/src/bin/ld/ld.h b/src/bin/ld/ld.h new file mode 100644 index 0000000..b651094 --- /dev/null +++ b/src/bin/ld/ld.h @@ -0,0 +1,30 @@ +#include +#include +#include "elf.h" + +typedef struct ldLibrary_s { + struct ldLibrary_s *next; + struct ldLibrary_s *prev; + char name[256]; + elfHeader *linkerHeader; + elfSectionHeader *linkerSectionHeader; + elfProgramHeader *linkerProgramHeader; + elfDynSym *linkerRelSymTab; + elfPltInfo *linkerElfRel; + char *linkerShStr; + char *linkerDynStr; + char *output; + int sym; + } ldLibrary; + +extern ldLibrary *libs; + +uInt32 ldFindFunc(char *,char *); +ldLibrary *ldFindLibrary(char *); +ldLibrary *ldAddLibrary(char *); + +/*** + $Log$ + END + ***/ + diff --git a/src/bin/ld/main.c b/src/bin/ld/main.c index 8c5a073..2cd1a6a 100644 --- a/src/bin/ld/main.c +++ b/src/bin/ld/main.c @@ -30,7 +30,7 @@ #include #include #include -#include "elf.h" +#include "ld.h" void _ld(); asm( @@ -43,7 +43,7 @@ " ret \n" ); -uInt32 ldFindFunc(char *func); +ldLibrary *libs = 0x0; elfHeader *binaryHeader = 0x0; elfSectionHeader *binarySectionHeader = 0x0; @@ -52,21 +52,11 @@ elfDynSym *binaryRelSymTab = 0x0; elfPltInfo *binaryElfRel = 0x0; -elfHeader *linkerHeader = 0x0; -elfSectionHeader *linkerSectionHeader = 0x0; -elfProgramHeader *linkerProgramHeader = 0x0; -elfDynSym *linkerRelSymTab = 0x0; -elfPltInfo *linkerElfRel = 0x0; -char *linkerShStr = 0x0; -char *linkerDynStr = 0x0; - -char *output = 0x0; -int sym = 0x0; - uInt32 ld(uInt32 got2,uInt32 entry) { int i = 0x0; int x = 0x0; int rel = 0x0; + uInt32 *reMap = 0x0; FILE *binaryFd = 0x0; binaryFd = malloc(sizeof(FILE)); @@ -123,129 +113,18 @@ i = (entry/sizeof(elfPltInfo)); x = ELF32_R_SYM(binaryElfRel[i].pltInfo); - //printf("Find Function [%s]\n",binaryDynStr + binaryRelSymTab[x].dynName); - i = ldFindFunc(binaryDynStr + binaryRelSymTab[x].dynName); + reMap = (uInt32 *)binaryElfRel[i].pltOffset; + *reMap = ldFindFunc(binaryDynStr + binaryRelSymTab[x].dynName,(char *)(binaryDynStr + 1)); free(binaryFd); - return(i); - } - -uInt32 ldFindFunc(char *func) { - int i = 0x0; - int x = 0x0; - int rel = 0x0; - uInt32 *funcPtr = 0x0; - uInt32 *reMap = 0x0; - char *newLoc = 0x0; - FILE *linkerFd = 0x0; - - if (output == 0x0) { - linkerFd = fopen("libc.so","rb"); - output = (char *)malloc((linkerFd->size+0x4000)); - } - - if (linkerHeader == 0x0) { - fseek(linkerFd,0x0,0x0); - linkerHeader = (elfHeader *)malloc(sizeof(elfHeader)); - fread(linkerHeader,sizeof(elfHeader),1,linkerFd); - } - - if (linkerProgramHeader == 0x0) { - linkerProgramHeader = (elfProgramHeader *)malloc(sizeof(elfProgramHeader)*linkerHeader->ePhnum); - fseek(linkerFd,linkerHeader->ePhoff,0); - fread(linkerProgramHeader,sizeof(elfProgramHeader),linkerHeader->ePhnum,linkerFd); - - for (i=0;iePhnum;i++) { - switch (linkerProgramHeader[i].phType) { - case 1: - case 2: - newLoc = (char *)linkerProgramHeader[i].phVaddr + (uInt32)output; - fseek(linkerFd,linkerProgramHeader[i].phOffset,0); - fread(newLoc,linkerProgramHeader[i].phFilesz,1,linkerFd); - break; - default: - printf("Unhandled Header\n"); - break; - } - } - } - - if (linkerSectionHeader == 0x0) { - linkerSectionHeader = (elfSectionHeader *)malloc(sizeof(elfSectionHeader)*linkerHeader->eShnum); - fseek(linkerFd,linkerHeader->eShoff,0); - fread(linkerSectionHeader,sizeof(elfSectionHeader),linkerHeader->eShnum,linkerFd); - - if (linkerShStr == 0x0) { - linkerShStr = (char *)malloc(linkerSectionHeader[linkerHeader->eShstrndx].shSize); - fseek(linkerFd,linkerSectionHeader[linkerHeader->eShstrndx].shOffset,0); - fread(linkerShStr,linkerSectionHeader[linkerHeader->eShstrndx].shSize,1,linkerFd); - } - - for (i=0x0;ieShnum;i++) { - switch (linkerSectionHeader[i].shType) { - case 3: - if (!strcmp((linkerShStr + linkerSectionHeader[i].shName),".dynstr")) { - if (linkerDynStr == 0x0) { - linkerDynStr = (char *)malloc(linkerSectionHeader[i].shSize); - fseek(linkerFd,linkerSectionHeader[i].shOffset,0); - fread(linkerDynStr,linkerSectionHeader[i].shSize,1,linkerFd); - } - } - break; - case 9: - rel = i; - break; - case 11: - if (linkerRelSymTab == 0x0) { - linkerRelSymTab = (elfDynSym *)malloc(linkerSectionHeader[i].shSize); - fseek(linkerFd,linkerSectionHeader[i].shOffset,0); - fread(linkerRelSymTab,linkerSectionHeader[i].shSize,1,linkerFd); - sym = i; - } - break; - } - } - } - - if (linkerElfRel == 0x0) { - linkerElfRel = (elfPltInfo *)malloc(linkerSectionHeader[rel].shSize); - fseek(linkerFd,linkerSectionHeader[rel].shOffset,0x0); - fread(linkerElfRel,linkerSectionHeader[rel].shSize,1,linkerFd); - - for (i=0x0;i kprintf + Revision 1.4 2004/06/16 16:31:58 reddawg ld.so: the dynamic linker works and has been tested @@ -266,3 +145,4 @@ END ***/ +