pike.git
/
NT
/
tools
/
pntld
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/NT/tools/pntld:1:
#!/usr/local/bin/pike // Partial linker for COFF files, written by Fredrik Hubinette 2000 // // Things left to do:
-
//
Merge
sections
-
//
Test
if
resulting
files work with cl.exe
+
//
Support
long-format import libaries
+
//
Merge
sections (
if
given
-O)
// Support line number information
-
+
// Test if resulting files work with cl.exe
// Support 64 bit architechtures
-
+
// Rename sections
+
// Support section symbols (used by pthread.lib)
-
+
// #define DEBUG
+
class Reloc { Symbol sym; int loc; int type; }; class Section { string name; int|string data; array(Reloc) relocs; int virtual_size; int characteristics;
-
+
+
array(Symbol) symbols_in_this_section=({});
}; class Symbol { string name; int value; Section section; int type; int cls; array(Symbol) aux;
pike.git/NT/tools/pntld:37:
mapping(string:Symbol) global_symbols=([]); array(Section) global_sections=({}); array(string) global_directives=({}); array(string) libpath=({}); array(string) libraries=({}); class Linker {
-
string ret="";
+
string stringtable="";
-
string symboltable="";
-
string sectiondata="";
-
string sectiontable="";
-
int num_symbols;
+
-
+
mapping(string:int) num_secnames=([]);
mapping(Symbol:int) symbol_to_number=([]);
-
-
int base;
-
int num_sections;
+
mapping(Section:int) section_to_number=([]); 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;
pike.git/NT/tools/pntld:75:
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("
Encoding
symbol
named
: %
s\n
",s->name);
+
werror("
Adding
symbol
[%d]
: %
s again\n
",
symbol_to_number[
s
]
-
1,s-
>name);
#endif
-
if(symbol_to_number[s])
+
return symbol_to_number[s]-1;
-
+
}
-
num_
symbols++
;
-
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 */
-
symbol_to_number[s]=sizeof(symbol_to_number)+1;
-
return
symbol_to_number[s]-1
;
+
int
num
=sizeof(symbol
_
to_number)
;
+
#ifdef
DEBUG
+
werror
("
Adding symbol [
%
d]:
%
s\n
",
num,
s->name)
;
+
#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;
-
section_to_number[
s
]
=++num_sections
;
-
return
section_to_number[s]-
1
;
+
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;
} int virtual_data_size(int|string s) { return intp(s) ? s : strlen(s); } int file_data_size(int|string s) { return intp(s) ? 0 : strlen(s); }
-
string out(
array(Section
)
sections,
-
array(Symbol) exports)
+
string out()
{
-
int
secnum
;
-
foreach(sections,
Section s) add_section(s)
;
-
foreach(exports,
Symbol s) add_symbol(s)
;
+
string
symboltable=""
;
+
string
sectiondata=""
;
+
string
sectiontable=""
;
-
+
int secnum_save=sizeof(section_to_number);
/* Actually output data */
-
Section
s;
-
base=20 /*coff*/ + sizeof(section_to_number) * 40;
-
for
(
int
secnum
=
1
;
s
=
search
(section_to_number
,
secnum
);
secnum++
)
+
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
)
{ #ifdef DEBUG
-
werror("Encoding section
named
: %s\n",s->name);
+
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), stringp(s->data) ? (base + strlen(sectiondata)) : 0, s->relocs && (base + strlen(sectiondata) + file_data_size(s->data)), 0, /* no linenums yet */
pike.git/NT/tools/pntld:152:
sectiondata+=s->data; if(s->relocs) foreach(s->relocs, Reloc r) sectiondata+=sprintf("%-4c%-4c%-2c", r->loc, add_symbol(r->sym), r->type); }
-
return
+
array(Symbol)
symbols=indices(symbol_to_number);
+
array(int) symnums=values(symbol_to_number);
+
sort(symnums, symbols);
+
+
foreach(symbols, 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",
+
strlen(sectiontable),
+
sizeof(section_to_number) * 40,
+
sizeof(sections) * 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), time(), base+strlen(sectiondata),
-
num
_
symbols
,
+
sizeof(symbol
_
to_number)
,
0, /* opt header size */ 0, /* no character */ sectiontable, sectiondata, symboltable, stringtable);
-
+
+
if(ret [ base + strlen(sectiondata)..
+
base+strlen(sectiondata)+strlen(symboltable) -1 ] != symboltable)
+
{
+
werror("Symbol table offset is wrong.\n");
+
exit(1);
}
-
+
return ret;
}
-
+
}
+
mapping machine_table = ([ 0:"Unknown", 0x14c:"Intel x86", ]); class Bitfield { array(string) names; string desc(int num)
pike.git/NT/tools/pntld:572:
string name=getCOFFstring(pos); int cls=i1(pos+16); int sect=i2(pos+12); int value=i4(pos+8); int type=i2(pos+14); if(sect > 32768) sect=65536-sect; Symbol s=Symbol(); s->name=name; s->value=value;
-
s->section=
sect>0
?
file_sections[sect-1]
: 0
;
+
if(sect > 0)
+
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]) { s=global_symbols[name]; if(s->section && sect > 0) werror("%s: Warning: Symbol %s redefined.\n", filename, name); } if(sect > 0) {
-
s->section
=
file_sections[sect-1];
+
s->section=file_sections[sect-1];
s->value = value; s->type = type; } global_symbols[name]=s; } file_symbols[e]=s; aux=i1(pos+17); pos+=18;
pike.git/NT/tools/pntld:652:
dumpSymTable(); dumpSECTS(); } int dumpPE(int pos) { #ifdef DEBUG write("Potential PE identifier at 0x%x ... ",pos); #endif
-
if(
data[
pos
..pos+3]
!="PE\0\0")
+
if(
range(
pos
,4)
!="PE\0\0")
{ #ifdef DEBUG write("No.\n"); #endif return 0; } else { #ifdef DEBUG write("Yes.\n"); #endif }
pike.git/NT/tools/pntld:764:
dumpImportLib(); }else{ dumpCOFF(0); } } } } int main(int argc, array(string) argv) {
-
int err;
+
int err
, export_all
;
int strip=0; string output="a.out"; // werror("%O\n",argv); werror("Pike Win32 partial linker.\n"
-
"$Id: pntld,v 1.
4
2000/12/
28
01
:
17
:
04
hubbe Exp $\n"
+
"$Id: pntld,v 1.
5
2000/12/
29
00
:
10
:
57
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"})}), )),array opt) { switch(opt[0]) { case "S": strip++; break; case "L": libpath|=({opt[1]}); break;
pike.git/NT/tools/pntld:802:
case "l": switch(opt[1]) { case "c": case "m": break; default: libraries|=({opt[1]}); } break;
+
case "a":
+
export_all++;
+
break;
+
case "output": output=opt[1]; break; } } if(getenv("NTLD_LIBRARY_PATH")) libpath|=getenv("NTLD_LIBRARY_PATH")/":"; if(getenv("NTLD_RUN_PATH"))
pike.git/NT/tools/pntld:865:
if(strip) { global_sections=Array.filter(global_sections, lambda(Section s) { return !(s->characteristics & CHR_LINK_MEM_DISCARDABLE); }); }
+
foreach(values(global_symbols), Symbol s)
+
if(s->section)
+
s->section->symbols_in_this_section+=({s});
+
+
Linker l=Linker();
+
if(sizeof(global_directives)) { Section s=Section(); s->name=".drectve"; s->data=global_directives * " "; s->characteristics = CHR_LINK_INFO | CHR_LINK_REMOVE | CHR_LINK_ALIGN_1; s->relocs=({});
-
global
_
sections=
(
{s}
)
+ global_sections
;
+
l->add
_
section
(
s
);
} if(err) exit(err); rm(output);
-
Stdio.write_file
(
output
,
-
Linker(
)->
out
(global_
sections
,
-
values
(global_symbols)));
+
+
+
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);
+
}else{
+
foreach(
global_
directives
,
string dir)
+
{
+
if(sscanf(dir,"-export:%s",string
sym))
+
{
+
//
werror("Exporting
symbol:
%O\n",sym);
+
l->add_symbol
(global_symbols
[sym]
)
;
+
}
+
}
+
}
+
+
Stdio.write_file(output, l->out(
));
exit(err); }