Chameleon

Chameleon Commit Details

Date:2011-05-30 23:53:55 (12 years 10 months ago)
Author:Evan Lojewski
Commit:927
Parents: 926
Message:Mach-o loader bugfix for dylibs.
Changes:
M/trunk/i386/boot2/modules.c
M/trunk/i386/boot2/modules.h

File differences

trunk/i386/boot2/modules.c
2222
2323
2424
25
26
25
26
2727
2828
2929
......
286286
287287
288288
289
289
290290
291291
292292
......
493493
494494
495495
496
497
498
496
497
498
499499
500500
501501
......
738738
739739
740740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
741763
742764
743765
744766
745
767
746768
747769
748770
......
762784
763785
764786
765
766787
767788
768789
......
792813
793814
794815
795
796
797
798
799
800
801
802
816
803817
804818
805819
......
819833
820834
821835
822
823
824
825
826
827
828
829
830
836
831837
832838
833839
......
848854
849855
850856
851
852
853
854
855
856
857
858
859
860
861
862
857
858
863859
864860
865861
866
867
868
869
870
871
872
873
874
875
876
862
877863
878864
879865
......
894880
895881
896882
897
898
899
900
901
902
903
904
883
905884
906885
907886
......
938917
939918
940919
941
942
943
944
945
946
947
948
920
949921
922
950923
951
952
953
954
955
956
957
958
959
960
961924
962925
963926
......
978941
979942
980943
944
981945
982946
983947
......
11401104
11411105
11421106
1107
11431108
11441109
11451110
1146
1111
11471112
11481113
11491114
#endif
// NOTE: Global so that modules can link with this
unsigned long long textAddress = 0;
unsigned long long textSection = 0;
UInt64 textAddress = 0;
UInt64 textSection = 0;
void* symbols_module_start = (void*)0xFFFFFFFF;// Global, value is populated by the makefile with actual address
}
#if CONFIG_MODULE_DEBUG
verbose("Unable to locate symbol %s\n", name);
printf("Unable to locate symbol %s\n", name);
getchar();
#endif
// Rebase the module before binding it.
if(dyldInfoCommand->rebase_off)rebase_macho(binary, (char*)dyldInfoCommand->rebase_off,dyldInfoCommand->rebase_size);
// Bind all symbols.
if(dyldInfoCommand->bind_off)bind_macho(binary, (char*)dyldInfoCommand->bind_off,dyldInfoCommand->bind_size);
if(dyldInfoCommand->weak_bind_off)bind_macho(binary, (char*)dyldInfoCommand->weak_bind_off,dyldInfoCommand->weak_bind_size);
if(dyldInfoCommand->lazy_bind_off)bind_macho(binary, (char*)dyldInfoCommand->lazy_bind_off,dyldInfoCommand->lazy_bind_size);
if(dyldInfoCommand->bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->bind_off,dyldInfoCommand->bind_size);
if(dyldInfoCommand->weak_bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->weak_bind_off,dyldInfoCommand->weak_bind_size);
if(dyldInfoCommand->lazy_bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->lazy_bind_off,dyldInfoCommand->lazy_bind_size);
}
return module_start;
}
UInt32 read_uleb(UInt8* bind_stream, unsigned int* i)
{
// Read in offset
UInt32 tmp = 0;
UInt8 bits = 0;
do
{
if(bits < sizeof(UInt32)*8) // hack
{
tmp |= (bind_stream[++(*i)] & 0x7f) << bits;
bits += 7;
}
else
{
++(*i);
}
}
while(bind_stream[*i] & 0x80);
return tmp;
}
// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp
// NOTE: this uses 32bit values, and not 64bit values.
// There is a possibility that this could cause issues,
// however the modules are 32 bits, so it shouldn't matter too much
void bind_macho(void* base, char* bind_stream, UInt32 size)
void bind_macho(void* base, UInt8* bind_stream, UInt32 size)
{
bind_stream += (UInt32)base;
UInt32 symbolAddr = 0xFFFFFFFF;
// Temperary variables
UInt8 bits = 0;
UInt32 tmp = 0;
UInt32 tmp2 = 0;
UInt32 index = 0;
break;
case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
libraryOrdinal = 0;
bits = 0;
do
{
libraryOrdinal |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
libraryOrdinal = read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
break;
case BIND_OPCODE_SET_ADDEND_SLEB:
addend = 0;
bits = 0;
do
{
addend |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
addend = read_uleb(bind_stream, &i);
if(!(bind_stream[i-1] & 0x40)) addend *= -1;
break;
while(index <= immediate);
segmentAddress = segCommand->fileoff;
// Read in offset
tmp = 0;
bits = 0;
do
{
tmp |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
segmentAddress += tmp;
segmentAddress += read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_ADD_ADDR_ULEB:
// Read in offset
tmp = 0;
bits = 0;
do
{
tmp |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
segmentAddress += tmp;
segmentAddress += read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_DO_BIND:
case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
// Read in offset
tmp = 0;
bits = 0;
do
{
tmp |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
tmp = read_uleb(bind_stream, &i);
if(symbolAddr != 0xFFFFFFFF)
{
break;
case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
tmp = 0;
bits = 0;
do
{
tmp |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
tmp = read_uleb(bind_stream, &i);
tmp2 = read_uleb(bind_stream, &i);
tmp2 = 0;
bits = 0;
do
{
tmp2 |= (bind_stream[++i] & 0x7f) << bits;
bits += 7;
}
while(bind_stream[i] & 0x80);
if(symbolAddr != 0xFFFFFFFF)
{
for(index = 0; index < tmp; index++)
i++;
}
}
inline void bind_location(UInt32* location, char* value, UInt32 addend, int type)
{
hooks = hooks->next;
}
}
#endif
/********************************************************************************/
/*dyld / Linker Interface*/
/*dyld / Linker Interface*/
/********************************************************************************/
void dyld_stub_binder()
trunk/i386/boot2/modules.h
1515
1616
1717
18
19
18
19
2020
2121
2222
2323
2424
2525
26
26
2727
2828
2929
......
8484
8585
8686
87
87
8888
8989
9090
#define MODULE_PATH"/Extra/modules/"
#define SYMBOLS_MODULE "Symbols.dylib"
#define VOID_SYMBOL"dyld_void_start"
extern unsigned long long textAddress;
extern unsigned long long textSection;
extern UInt64 textAddress;
extern UInt64 textSection;
typedef struct symbolList_t
{
char* symbol;
unsigned int addr;
UInt64 addr;
struct symbolList_t* next;
} symbolList_t;
char is64);
voidrebase_macho(void* base, char* rebase_stream, UInt32 size);
inline voidrebase_location(UInt32* location, char* base, int type);
voidbind_macho(void* base, char* bind_stream, UInt32 size);
voidbind_macho(void* base, UInt8* bind_stream, UInt32 size);
inline voidbind_location(UInt32* location, char* value, UInt32 addend, int type);

Archive Download the corresponding diff file

Revision: 927