Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
977e19d6
Commit
977e19d6
authored
Dec 13, 2009
by
Hector Chu
Committed by
Russ Cox
Dec 13, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
8l: add support for PE output.
R=rsc
https://golang.org/cl/166080
parent
2ef330eb
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
329 additions
and
8 deletions
+329
-8
Makefile
src/cmd/8l/Makefile
+2
-0
asm.c
src/cmd/8l/asm.c
+9
-0
obj.c
src/cmd/8l/obj.c
+28
-3
pass.c
src/cmd/8l/pass.c
+38
-4
lex.c
src/cmd/cc/lex.c
+4
-1
pe.c
src/cmd/ld/pe.c
+157
-0
pe.h
src/cmd/ld/pe.h
+91
-0
No files found.
src/cmd/8l/Makefile
View file @
977e19d6
...
...
@@ -17,6 +17,7 @@ OFILES=\
obj.
$O
\
optab.
$O
\
pass.
$O
\
pe.
$O
\
span.
$O
\
go.
$O
\
...
...
@@ -25,6 +26,7 @@ HFILES=\
../8l/8.out.h
\
../ld/elf.h
\
../ld/macho.h
\
../ld/pe.h
\
$(TARG)
:
$(OFILES)
...
...
src/cmd/8l/asm.c
View file @
977e19d6
...
...
@@ -32,6 +32,7 @@
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
#define Dbufslop 100
...
...
@@ -531,6 +532,7 @@ asmb(void)
case
7
:
case
8
:
case
9
:
case
10
:
v
=
rnd
(
HEADR
+
textsize
,
INITRND
);
seek
(
cout
,
v
,
0
);
break
;
...
...
@@ -588,6 +590,7 @@ asmb(void)
case
7
:
case
8
:
case
9
:
case
10
:
symo
=
rnd
(
HEADR
+
textsize
,
INITRND
)
+
datsize
;
symo
=
rnd
(
symo
,
INITRND
);
break
;
...
...
@@ -605,6 +608,8 @@ asmb(void)
asmlc
();
if
(
dlm
)
asmdyn
();
if
(
HEADTYPE
==
10
)
strnput
(
""
,
INITRND
-
(
8
+
symsize
+
lcsize
)
%
INITRND
);
cflush
();
seek
(
cout
,
symo
,
0
);
lputl
(
symsize
);
...
...
@@ -1018,6 +1023,10 @@ asmb(void)
if
(
a
+
elfwriteinterp
()
>
ELFRESERVE
)
diag
(
"ELFRESERVE too small: %d > %d"
,
a
,
ELFRESERVE
);
break
;
case
10
:
asmbpe
();
break
;
}
cflush
();
}
...
...
src/cmd/8l/obj.c
View file @
977e19d6
...
...
@@ -33,6 +33,7 @@
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
#include <ar.h>
#ifndef DEFAULT
...
...
@@ -94,7 +95,7 @@ main(int argc, char *argv[])
listinit
();
memset
(
debug
,
0
,
sizeof
(
debug
));
nerrors
=
0
;
outfile
=
"8.out"
;
outfile
=
nil
;
HEADTYPE
=
-
1
;
INITTEXT
=
-
1
;
INITDAT
=
-
1
;
...
...
@@ -145,7 +146,7 @@ main(int argc, char *argv[])
if
(
*
argv
==
0
)
usage
();
libinit
();
mywhatsys
();
// get goos
if
(
HEADTYPE
==
-
1
)
{
HEADTYPE
=
2
;
...
...
@@ -161,9 +162,21 @@ main(int argc, char *argv[])
if
(
strcmp
(
goos
,
"freebsd"
)
==
0
)
HEADTYPE
=
9
;
else
print
(
"goos is not known: %sn"
,
goos
);
if
(
strcmp
(
goos
,
"mingw"
)
==
0
)
HEADTYPE
=
10
;
else
print
(
"goos is not known: %s
\n
"
,
goos
);
}
if
(
outfile
==
nil
)
{
if
(
HEADTYPE
==
10
)
outfile
=
"8.out.exe"
;
else
outfile
=
"8.out"
;
}
libinit
();
switch
(
HEADTYPE
)
{
default:
diag
(
"unknown -H option"
);
...
...
@@ -260,6 +273,16 @@ main(int argc, char *argv[])
if
(
INITRND
==
-
1
)
INITRND
=
4096
;
break
;
case
10
:
/* PE executable */
peinit
();
HEADR
=
PERESERVE
;
if
(
INITTEXT
==
-
1
)
INITTEXT
=
PEBASE
+
0x1000
;
if
(
INITDAT
==
-
1
)
INITDAT
=
0
;
if
(
INITRND
==
-
1
)
INITRND
=
PEALIGN
;
break
;
}
if
(
INITDAT
!=
0
&&
INITRND
!=
0
)
print
(
"warning: -D0x%lux is ignored because of -R0x%lux
\n
"
,
...
...
@@ -387,6 +410,8 @@ main(int argc, char *argv[])
doprof2
();
span
();
doinit
();
if
(
HEADTYPE
==
10
)
dope
();
asmb
();
undef
();
if
(
debug
[
'v'
])
{
...
...
src/cmd/8l/pass.c
View file @
977e19d6
...
...
@@ -358,6 +358,27 @@ patch(void)
s
=
lookup
(
"exit"
,
0
);
vexit
=
s
->
value
;
for
(
p
=
firstp
;
p
!=
P
;
p
=
p
->
link
)
{
if
(
HEADTYPE
==
10
)
{
// Convert
// op n(GS), reg
// to
// MOVL 0x2C(FS), reg
// op n(reg), reg
// The purpose of this patch is to fix some accesses
// to extern register variables (TLS) on Windows, as
// a different method is used to access them.
if
(
p
->
from
.
type
==
D_INDIR
+
D_GS
&&
p
->
to
.
type
>=
D_AX
&&
p
->
to
.
type
<=
D_DI
)
{
q
=
appendp
(
p
);
q
->
from
=
p
->
from
;
q
->
from
.
type
+=
p
->
to
.
type
-
D_GS
;
q
->
to
=
p
->
to
;
q
->
as
=
p
->
as
;
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_FS
;
p
->
from
.
offset
=
0x2C
;
}
}
if
(
p
->
as
==
ATEXT
)
curtext
=
p
;
if
(
p
->
as
==
ACALL
||
(
p
->
as
==
AJMP
&&
p
->
to
.
type
!=
D_BRANCH
))
{
...
...
@@ -575,10 +596,23 @@ dostkoff(void)
if
(
pmorestack
!=
P
)
if
(
!
(
p
->
from
.
scale
&
NOSPLIT
))
{
p
=
appendp
(
p
);
// load g into CX
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_GS
;
p
->
from
.
offset
=
tlsoffset
+
0
;
p
->
to
.
type
=
D_CX
;
if
(
HEADTYPE
==
10
)
{
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_FS
;
p
->
from
.
offset
=
0x2c
;
p
->
to
.
type
=
D_CX
;
p
=
appendp
(
p
);
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_CX
;
p
->
from
.
offset
=
0
;
p
->
to
.
type
=
D_CX
;
}
else
{
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_GS
;
p
->
from
.
offset
=
tlsoffset
+
0
;
p
->
to
.
type
=
D_CX
;
}
if
(
debug
[
'K'
])
{
// 8l -K means check not only for stack
...
...
src/cmd/cc/lex.c
View file @
977e19d6
...
...
@@ -38,8 +38,11 @@
int
systemtype
(
int
sys
)
{
#ifdef __MINGW32__
return
sys
&
Windows
;
#else
return
sys
&
Plan9
;
#endif
}
int
...
...
src/cmd/ld/pe.c
0 → 100644
View file @
977e19d6
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// PE (Portable Executable) file writing
// http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
#include <time.h>
#include "l.h"
#include "../ld/lib.h"
#include "../ld/pe.h"
static
int
pe64
;
static
int
nsect
;
static
int
sect_virt_begin
;
static
int
sect_raw_begin
=
PERESERVE
;
static
IMAGE_FILE_HEADER
fh
;
static
IMAGE_OPTIONAL_HEADER
oh
;
static
IMAGE_SECTION_HEADER
sh
[
16
];
static
IMAGE_SECTION_HEADER
*
textsect
,
*
datsect
,
*
bsssect
;
static
IMAGE_SECTION_HEADER
*
new_section
(
char
*
name
,
int
size
,
int
noraw
)
{
IMAGE_SECTION_HEADER
*
h
;
if
(
nsect
==
16
)
{
diag
(
"too many sections"
);
errorexit
();
}
h
=
&
sh
[
nsect
++
];
strncpy
(
h
->
Name
,
name
,
sizeof
(
h
->
Name
));
h
->
VirtualSize
=
size
;
if
(
!
sect_virt_begin
)
sect_virt_begin
=
0x1000
;
h
->
VirtualAddress
=
sect_virt_begin
;
sect_virt_begin
=
rnd
(
sect_virt_begin
+
size
,
0x1000
);
if
(
!
noraw
)
{
h
->
SizeOfRawData
=
rnd
(
size
,
PEALIGN
);
h
->
PointerToRawData
=
sect_raw_begin
;
sect_raw_begin
+=
h
->
SizeOfRawData
;
}
return
h
;
}
void
peinit
(
void
)
{
switch
(
thechar
)
{
// 64-bit architectures
case
'6'
:
pe64
=
1
;
break
;
// 32-bit architectures
default:
break
;
}
}
static
void
pewrite
(
void
)
{
int
i
,
j
;
strnput
(
"MZ"
,
0x3c
);
LPUT
(
0x40
);
// file offset to PE header
strnput
(
"PE"
,
4
);
for
(
i
=
0
;
i
<
sizeof
(
fh
);
i
++
)
cput
(((
char
*
)
&
fh
)[
i
]);
for
(
i
=
0
;
i
<
sizeof
(
oh
);
i
++
)
cput
(((
char
*
)
&
oh
)[
i
]);
for
(
i
=
0
;
i
<
nsect
;
i
++
)
for
(
j
=
0
;
j
<
sizeof
(
sh
[
i
]);
j
++
)
cput
(((
char
*
)
&
sh
[
i
])[
j
]);
}
void
dope
(
void
)
{
textsect
=
new_section
(
".text"
,
textsize
,
0
);
textsect
->
Characteristics
=
IMAGE_SCN_CNT_CODE
|
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_EXECUTE
|
IMAGE_SCN_MEM_READ
;
datsect
=
new_section
(
".data"
,
datsize
,
0
);
datsect
->
Characteristics
=
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_READ
|
IMAGE_SCN_MEM_WRITE
;
INITDAT
=
PEBASE
+
datsect
->
VirtualAddress
;
bsssect
=
new_section
(
".bss"
,
bsssize
,
1
);
bsssect
->
Characteristics
=
IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
IMAGE_SCN_MEM_READ
|
IMAGE_SCN_MEM_WRITE
;
}
void
asmbpe
(
void
)
{
switch
(
thechar
)
{
default:
diag
(
"unknown PE architecture"
);
errorexit
();
case
'6'
:
fh
.
Machine
=
IMAGE_FILE_MACHINE_AMD64
;
break
;
case
'8'
:
fh
.
Machine
=
IMAGE_FILE_MACHINE_I386
;
break
;
}
if
(
!
debug
[
's'
])
{
IMAGE_SECTION_HEADER
*
symsect
;
symsect
=
new_section
(
".symdat"
,
8
+
symsize
+
lcsize
,
0
);
symsect
->
Characteristics
=
IMAGE_SCN_MEM_READ
|
IMAGE_SCN_CNT_INITIALIZED_DATA
;
}
fh
.
NumberOfSections
=
nsect
;
fh
.
TimeDateStamp
=
time
(
0
);
fh
.
SizeOfOptionalHeader
=
sizeof
(
oh
);
fh
.
Characteristics
=
IMAGE_FILE_RELOCS_STRIPPED
|
IMAGE_FILE_EXECUTABLE_IMAGE
|
IMAGE_FILE_DEBUG_STRIPPED
;
if
(
thechar
==
'8'
)
fh
.
Characteristics
|=
IMAGE_FILE_32BIT_MACHINE
;
oh
.
Magic
=
0x10b
;
// PE32
oh
.
MajorLinkerVersion
=
1
;
oh
.
MinorLinkerVersion
=
0
;
oh
.
SizeOfCode
=
textsect
->
SizeOfRawData
;
oh
.
SizeOfInitializedData
=
datsect
->
SizeOfRawData
;
oh
.
SizeOfUninitializedData
=
bsssect
->
SizeOfRawData
;
oh
.
AddressOfEntryPoint
=
entryvalue
()
-
PEBASE
;
oh
.
BaseOfCode
=
textsect
->
VirtualAddress
;
oh
.
BaseOfData
=
datsect
->
VirtualAddress
;
oh
.
ImageBase
=
PEBASE
;
oh
.
SectionAlignment
=
0x00001000
;
oh
.
FileAlignment
=
PEALIGN
;
oh
.
MajorOperatingSystemVersion
=
4
;
oh
.
MinorOperatingSystemVersion
=
0
;
oh
.
MajorImageVersion
=
1
;
oh
.
MinorImageVersion
=
0
;
oh
.
MajorSubsystemVersion
=
4
;
oh
.
MinorSubsystemVersion
=
0
;
oh
.
SizeOfImage
=
sect_virt_begin
;
oh
.
SizeOfHeaders
=
PERESERVE
;
oh
.
Subsystem
=
3
;
// WINDOWS_CUI
oh
.
SizeOfStackReserve
=
0x00200000
;
oh
.
SizeOfStackCommit
=
0x00001000
;
oh
.
SizeOfHeapReserve
=
0x00100000
;
oh
.
SizeOfHeapCommit
=
0x00001000
;
oh
.
NumberOfRvaAndSizes
=
16
;
pewrite
();
}
src/cmd/ld/pe.h
0 → 100644
View file @
977e19d6
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
typedef
struct
{
uint16
Machine
;
uint16
NumberOfSections
;
uint32
TimeDateStamp
;
uint32
PointerToSymbolTable
;
uint32
NumberOfSymbols
;
uint16
SizeOfOptionalHeader
;
uint16
Characteristics
;
}
IMAGE_FILE_HEADER
;
typedef
struct
{
uint32
VirtualAddress
;
uint32
Size
;
}
IMAGE_DATA_DIRECTORY
;
typedef
struct
{
uint16
Magic
;
uint8
MajorLinkerVersion
;
uint8
MinorLinkerVersion
;
uint32
SizeOfCode
;
uint32
SizeOfInitializedData
;
uint32
SizeOfUninitializedData
;
uint32
AddressOfEntryPoint
;
uint32
BaseOfCode
;
uint32
BaseOfData
;
uint32
ImageBase
;
uint32
SectionAlignment
;
uint32
FileAlignment
;
uint16
MajorOperatingSystemVersion
;
uint16
MinorOperatingSystemVersion
;
uint16
MajorImageVersion
;
uint16
MinorImageVersion
;
uint16
MajorSubsystemVersion
;
uint16
MinorSubsystemVersion
;
uint32
Win32VersionValue
;
uint32
SizeOfImage
;
uint32
SizeOfHeaders
;
uint32
CheckSum
;
uint16
Subsystem
;
uint16
DllCharacteristics
;
uint32
SizeOfStackReserve
;
uint32
SizeOfStackCommit
;
uint32
SizeOfHeapReserve
;
uint32
SizeOfHeapCommit
;
uint32
LoaderFlags
;
uint32
NumberOfRvaAndSizes
;
IMAGE_DATA_DIRECTORY
DataDirectory
[
16
];
}
IMAGE_OPTIONAL_HEADER
;
typedef
struct
{
uint8
Name
[
8
];
uint32
VirtualSize
;
uint32
VirtualAddress
;
uint32
SizeOfRawData
;
uint32
PointerToRawData
;
uint32
PointerToRelocations
;
uint32
PointerToLineNumbers
;
uint16
NumberOfRelocations
;
uint16
NumberOfLineNumbers
;
uint32
Characteristics
;
}
IMAGE_SECTION_HEADER
;
#define PERESERVE 0x400
#define PEALIGN 0x200
#define PEBASE 0x00400000
enum
{
IMAGE_FILE_MACHINE_I386
=
0x14c
,
IMAGE_FILE_MACHINE_AMD64
=
0x8664
,
IMAGE_FILE_RELOCS_STRIPPED
=
0x0001
,
IMAGE_FILE_EXECUTABLE_IMAGE
=
0x0002
,
IMAGE_FILE_LARGE_ADDRESS_AWARE
=
0x0020
,
IMAGE_FILE_32BIT_MACHINE
=
0x0100
,
IMAGE_FILE_DEBUG_STRIPPED
=
0x0200
,
IMAGE_SCN_CNT_CODE
=
0x00000020
,
IMAGE_SCN_CNT_INITIALIZED_DATA
=
0x00000040
,
IMAGE_SCN_CNT_UNINITIALIZED_DATA
=
0x00000080
,
IMAGE_SCN_MEM_EXECUTE
=
0x20000000
,
IMAGE_SCN_MEM_READ
=
0x40000000
,
IMAGE_SCN_MEM_WRITE
=
0x80000000
,
};
void
peinit
(
void
);
void
dope
(
void
);
void
asmbpe
(
void
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment