pike.git
/
NT
/
tools
/
pntld
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/NT/tools/pntld:22:
class Section { string name; int|string data; array(Reloc) relocs; int virtual_size; int characteristics;
+
/* internal stuff */
array(Symbol) symbols_in_this_section=({});
-
+
string file;
}; class Symbol { string name; int value; Section section; int type; int cls; array(Symbol) aux;
-
+
+
string demangle()
+
{
+
string ret=name;
+
sscanf(ret,"%s@",ret);
+
if( (type >> 4) == 2) ret+="()";
+
return ret;
+
}
}; mapping(string:Symbol) global_symbols=([]); array(Section) global_sections=({}); array(string) global_directives=({}); array(string) libpath=({}); array(string) libraries=({});
-
+
int err;
+
+
+
#define CHR_LINK_INFO 0x200
+
#define CHR_LINK_REMOVE 0x800
+
#define CHR_LINK_ALIGN_1 0x100000
+
#define CHR_LINK_MEM_DISCARDABLE 0x2000000
+
+
class Linker { string stringtable=""; mapping(string:int) num_secnames=([]); mapping(Symbol:int) symbol_to_number=([]); mapping(Section:int) section_to_number=([]);
-
+
mapping(string:int) directive_to_number=([]);
-
+
array get_ordered(mapping m)
+
{
+
array i=indices(m);
+
array v=values(m);
+
sort(v,i);
+
return i;
+
}
+
+
mapping(string:int) stringtablecache=([]); int add_string(string s) { int pos; // werror("Adding string: %O\n",s); s+="\0"; if(pos=stringtablecache[s]) return pos-1; pos=search(stringtable, s); if(pos == -1) { pos=strlen(stringtable); stringtable+=s; } stringtablecache[s]=pos-1; return pos; }
-
+
int add_directive(string d)
+
{
+
if(directive_to_number[d])
+
return directive_to_number[d]-1;
+
#ifdef DEBUG
+
werror("Adding directive: %O\n",d);
+
#endif
+
+
int num=sizeof(directive_to_number);
+
directive_to_number[d]=num+1;
+
return num;
+
}
+
string add_sym_name(string s) { if(strlen(s) <= 8) return s + "\0"*(8-strlen(s)); return sprintf("%-4c%-4c",0,add_string(s)); } int add_symbol(Symbol s) { if(symbol_to_number[s]) { #ifdef DEBUG
-
werror("Adding symbol [%d]: %s again\n",symbol_to_number[s]-1,s->name);
+
werror("Adding symbol [%d]: %s
@ %O:%O
again\n",
+
symbol_to_number[s]-1,s->name
,
+
s->section ? s->section->name : "",
+
s->section ? s->section->file : "",
+
);
#endif return symbol_to_number[s]-1; } int num=sizeof(symbol_to_number); #ifdef DEBUG
-
werror("Adding symbol [%d]: %
s\n
",num,s->name);
+
werror("Adding symbol [%d]: %
s @ %O:%O\n
",num,s->name
,
+
s->section ? s->section->name : "external",
+
s->section ? s->section->file : ""
);
#endif symbol_to_number[s]=num+1; if(s->section) add_section(s->section); return num; } int add_section(Section s) { if(section_to_number[s]) return section_to_number[s]-1;
-
+
string name=s->name;
+
sscanf(name,"%s$",name);
+
+
if(name == ".drectve")
+
{
+
#ifdef DEBUG
+
werror("Adding directives: %O\n",s->data);
+
#endif
+
map(s->data/" ",add_directive);
+
return -1;
+
}
+
+
#if 0
+
if(name == ".idata")
+
{
+
string name= ( s->file /"/" )[-1];
+
add_directive("-LIB:"+name);
+
/* import DLL instead of section */
+
return -1; /* undefined */
+
}
+
#endif
+
int num=sizeof(section_to_number); #ifdef DEBUG werror("Adding section [%d]: %s\n",num,s->name); #endif section_to_number[s]=num+1;
-
sscanf(s->name,"%s$",s->name);
-
s->name+="$"+ ++num_secnames[s->name];
+
if(s->relocs) foreach(s->relocs, Reloc r) add_symbol(r->sym); foreach(s->symbols_in_this_section, Symbol sym) add_symbol(sym); return num; }
pike.git/NT/tools/pntld:131:
return intp(s) ? s : strlen(s); } int file_data_size(int|string s) { return intp(s) ? 0 : strlen(s); } string out() {
+
+
if(sizeof(directive_to_number))
+
{
+
Section s=Section();
+
s->name=".drectve";
+
s->data=get_ordered(directive_to_number) * " ";
+
s->characteristics = CHR_LINK_INFO | CHR_LINK_REMOVE | CHR_LINK_ALIGN_1;
+
int num=sizeof(section_to_number);
+
section_to_number[s]=num+1;
+
add_section(s);
+
}
+
string symboltable=""; string sectiondata=""; string sectiontable=""; int secnum_save=sizeof(section_to_number); /* Actually output data */ int base=20 /*coff*/ + sizeof(section_to_number) * 40;
-
array
(
Section) sections=indices(section
_
to_number);
-
array
(
int) secnums=values(
section_to_number)
;
-
sort(secnums
,
sections);
-
-
foreach(sections,
Section s)
+
foreach
(
get
_
ordered
(section_to_number), Section s)
{ #ifdef DEBUG werror("Encoding section [%d]: %s\n",add_section(s),s->name); #endif sectiontable+= sprintf("%s%-4c%-4c%-4c%-4c%-4c%-4c%-2c%-2c%-4c", add_sym_name(s->name), s->virtual_size, 0, /* virtual address */ virtual_data_size(s->data),
pike.git/NT/tools/pntld:173:
sectiondata+=s->data; if(s->relocs) foreach(s->relocs, Reloc r) sectiondata+=sprintf("%-4c%-4c%-2c", r->loc, add_symbol(r->sym), r->type); }
-
array
(
Symbol) symbols=indices(symbol
_
to_number);
-
array
(
int) symnums=values(
symbol_to_number)
;
-
sort(symnums
,
symbols);
-
-
foreach(symbols,
Symbol s)
+
foreach
(
get
_
ordered
(symbol_to_number), Symbol s)
{ symboltable+=sprintf("%s%-4c%-2c%-2c%c%c", add_sym_name(s->name), s->value, s->section ? add_section(s->section) +1 : 0, s->type, s->cls, 0); /* aux symbols not supported */ } if( secnum_save != sizeof(section_to_number)) { werror("Sections appeared too late!\n"); exit(1); } if( strlen(sectiontable) != sizeof(section_to_number) * 40) {
-
werror("Complete failure %d != %d
(%d)
!\n",
+
werror("Complete failure %d != %d!\n",
strlen(sectiontable),
-
sizeof(section_to_number) * 40
,
-
sizeof(sections
)
* 40)
;
+
sizeof(section_to_number) * 40);
exit(1); } string ret= sprintf("%-2c%-2c%-4c%-4c%-4c%-2c%-2c" /* coff */ "%s%s%s%s" /* the rest */ , /* coff */ 0x14c, /* Intel x86 */ sizeof(section_to_number),
pike.git/NT/tools/pntld:319:
"LNK_NRELOC_OVFL", "MEM_DISCARDABLE", "MEM_NOT_CACHED", "MEM_NOT_PAGED", "MEM_SHARED", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE", );
-
#define CHR_LINK_INFO 0x200
-
#define CHR_LINK_REMOVE 0x800
-
#define CHR_LINK_ALIGN_1 0x100000
-
#define CHR_LINK_MEM_DISCARDABLE 0x2000000
-
-
+
class dumpfile { string filename; string data; int base; int stringtable; int symboltable, numsymbols; int sections, numsections;
pike.git/NT/tools/pntld:346:
array(Section) file_sections; void hexdump(int pos) { string x=data[pos..pos+128]; foreach(x/8,string line) { write("%06x: %{%02x %} %O\n",pos,values(line),line); pos+=strlen(x); }
+
string line=x%8;
+
write("%06x: %{%02x %} %s %O\n",
+
pos,
+
values(line),
+
" "*(8-strlen(line)),
+
line);
} int i4(int pos) { pos+=base; return data[pos] | (data[pos+1]<<8) | (data[pos+2]<<16) | (data[pos+3]<<24); } int i8(int pos) {
pike.git/NT/tools/pntld:479:
write("Ptr2RawData : %x\n",i4(pos+20)); write("Ptr2Relocs : %x\n",i4(pos+24)); write("Ptr2Linenums : %x\n",i4(pos+28)); write("num relocs : %x\n",i2(pos+32)); write("num linenums : %x\n",i2(pos+34)); write("characteristics : %s\n", caracter=section_character_descriptor->desc(i4(pos+36))); #endif file_sections[e]->name=getCOFFstring(pos);
+
file_sections[e]->file=filename;
if(i4(pos+20)) { file_sections[e]->data=range(i4(pos+20),i4(pos+16)); }else{ file_sections[e]->data=i4(pos+16); } file_sections[e]->virtual_size=i4(pos+8);; file_sections[e]->characteristics=i4(pos+36);
pike.git/NT/tools/pntld:645:
s->section=file_sections[sect-1]; s->type=type; s->cls=cls; s->aux=0; #define COFFSYM_external 2 switch(cls) { case COFFSYM_external:
-
if(global_symbols[
name
])
+
string tmpname=s->demangle();
+
+
if(global_symbols[
tmpname
])
{
-
s
=global_symbols[
name
];
-
if(
s
->section && sect > 0)
+
Symbol newsym
=global_symbols[
tmpname
];
+
if(
newsym
->section && sect > 0)
+
{
werror("%s: Warning: Symbol %s redefined.\n", filename, name);
-
+
newsym=s;
} if(sect > 0) {
-
+
if( (newsym->type >> 4) != (type>>4) )
+
{
+
werror("Warning: same symbol, different levels of indirection!!!!!!\n");
+
err++;
+
}
+
}
+
s=newsym;
+
}
+
+
if(sect > 0)
+
{
s->section=file_sections[sect-1]; s->value = value; s->type = type; }
-
global_symbols[
name
]=s;
+
global_symbols[
tmpname
]=s;
} file_symbols[e]=s; aux=i1(pos+17); pos+=18; for(int a=0;a<aux;a++) { pos+=18; e++;
pike.git/NT/tools/pntld:775:
dumpfile(data, pos+60, 0, name); } pos+=60; pos+=(size+1)&~1; } } void dumpImportLib() { string name= ( filename/"/" )[-1];
-
#if 0
+
sscanf(range(0,20), "%-2c%-2c%-2c%-2c%-4c%-4c%-2c%-2c", int sig1, int sig2, int version, int machine, int timestamp, int size_of_data, int ordinal, int type);
-
+
#if 0
write("Sig1 : %x\n",sig1); write("Sig2 : %x\n",sig2); write("version : %x\n",version); write("Machine : %x\n", machine); write("Time : %s",ctime(timestamp)); write("Ordinal : %x\n",ordinal); write("Type: : %x\n",type); write("Name : %s\n",nulltermstring(20)); write("Importing library: %O\n",name); #endif
-
+
#if 0
global_directives|=({ "-LIB:"+name });
-
+
#else
+
Section s=Section();
+
#if 0
+
s->name=".idata";
+
s->file=filename;
+
#else
+
s->name=".drectve";
+
// werror("Creating Directive -LIB:%s\n",name);
+
s->data = "-LIB:"+name;
+
s->file="autogenerated";
+
#endif
+
string symname=nulltermstring(20);
+
#ifdef DEBUG
+
werror("Importing symbol: %O\n",symname);
+
#endif
+
string tmpname=symname;
+
sscanf(tmpname,"%s@",tmpname);
+
+
Symbol sym=global_symbols[tmpname];
+
if(!sym)
+
global_symbols[tmpname]=sym=Symbol();
+
+
sym->name=symname;
+
sym->section=s;
+
sym->type=type; /* correct ???? */
+
sym->cls = COFFSYM_external;
+
+
+
symname="__imp_"+symname;
+
#ifdef DEBUG
+
werror("Importing symbol: %O\n",symname);
+
#endif
+
tmpname="__imp_"+tmpname+"()";
+
+
sym=global_symbols[tmpname];
+
if(!sym)
+
global_symbols[tmpname]=sym=Symbol();
+
+
sym->name=symname;
+
sym->section=s;
+
sym->type=type | (2<<4); /* correct ???? */
+
sym->cls = COFFSYM_external;
+
+
#endif
} void create(string d, void|int p, void|int len, void|string f) { base=p; data=d; filename=f; if(!len) len=strlen(d)-base; if(range(0,8) == "!<arch>\n")
pike.git/NT/tools/pntld:827:
dumpImportLib(); }else{ dumpCOFF(0); } } } } int main(int argc, array(string) argv) {
-
int
err,
export_all;
+
int export_all;
int strip=0; string output="a.out"; // werror("%O\n",argv); werror("Pike Win32 partial linker.\n"
-
"$Id: pntld,v 1.
5
2000
/
12
/
29
00
:
10
:
57
hubbe Exp $\n"
+
"$Id: pntld,v 1.
6
2001
/
01
/
04
02
:
15
:
44
hubbe Exp $\n"
"Written by Fredrik Hubinette 2000\n"); foreach(Getopt.find_all_options(argv,aggregate( ({"output",Getopt.HAS_ARG,({"-o"})}), ({"R",Getopt.HAS_ARG,({"-R"})}), ({"L",Getopt.HAS_ARG,({"-L"})}), ({"l",Getopt.HAS_ARG,({"-l"})}), ({"S",Getopt.NO_ARG,({"-S"})}), ({"a",Getopt.NO_ARG,({"-a"})}), ({"ignore","Getopt.HAS_ARG",({"-r","-i","-s","-g","-B","-W"})}),
pike.git/NT/tools/pntld:933:
if(strip) { global_sections=Array.filter(global_sections, lambda(Section s) { return !(s->characteristics & CHR_LINK_MEM_DISCARDABLE); }); }
+
if(err) exit(err);
+
+
/* perform fixups */
+
foreach(values(global_symbols), Symbol s) if(s->section) s->section->symbols_in_this_section+=({s});
-
Linker l=Linker();
-
-
if(
sizeof(global
_
directives
)
)
+
if(
!export
_
all
)
{
-
Section s=Section();
-
s
->name=".drectve";
-
s
->data=
global_directives
*
"
";
-
s->characteristics
=
CHR_LINK_INFO
|
CHR_LINK_REMOVE
|
CHR
_
LINK
_
ALIGN
_
1;
-
s->
relocs=({}
);
-
-
l
->
add_
section(s);
+
foreach(global_sections,
Section s
)
+
{
+
if(sscanf(s->name,".idata%*s"))
+
{
+
string name
=
( s->file /"/" )[-1];
+
Section
s2=Section
();
+
s2
->name=".drectve";
+
s2
->data
=
"-LIB:"+name;
+
foreach(s->symbols
_
in_this_section,
Symbol sym)
+
{
+
// werror(
"
Fixing
(%s) %s : %s\n
"
,name,s->name,sym->name)
;
+
sym
->
section
=
s2;
+
sym->value=0
;
+
if((sym
->
type >> 4)
=
= 2
)
+
{
+
werror("Warning: Symbol %s is double indirected!\n",sym
->
name
);
}
-
+
sym->type=2<<4;
+
}
+
}
+
}
+
}
-
+
if(err) exit(err);
-
rm(output);
+
-
+
Linker l=Linker();
-
+
map(global_directives, l->add_directive);
+
werror("Creating %s\n",output); if(export_all) {
-
foreach
(global_sections,
Section s)
l->add_section
(s
);
-
foreach
(values(global_symbols),
Symbol s)
l->add_symbol
(s
);
+
map
(global_sections, l->add_section);
+
map
(values(global_symbols), l->add_symbol);
}else{ foreach(global_directives, string dir) { if(sscanf(dir,"-export:%s",string sym)) { // werror("Exporting symbol: %O\n",sym);
-
+
if(global_symbols[sym])
l->add_symbol(global_symbols[sym]);
-
+
if(global_symbols[sym+"()"])
+
l->add_symbol(global_symbols[sym+"()"]);
} } }
-
+
if(err) exit(err);
+
rm(output);
Stdio.write_file(output, l->out()); exit(err); }