Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
032e5bfb
Commit
032e5bfb
authored
Sep 13, 2012
by
Jan Ziak
Committed by
Russ Cox
Sep 13, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ld: add .gcdata and .gcbss sections
R=rsc CC=golang-dev
https://golang.org/cl/6281048
parent
9a82324f
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
498 additions
and
346 deletions
+498
-346
src/cmd/5l/asm.c
src/cmd/5l/asm.c
+5
-1
src/cmd/6l/asm.c
src/cmd/6l/asm.c
+5
-1
src/cmd/8l/asm.c
src/cmd/8l/asm.c
+5
-1
src/cmd/gc/subr.c
src/cmd/gc/subr.c
+0
-1
src/cmd/ld/data.c
src/cmd/ld/data.c
+235
-105
src/cmd/ld/decodesym.c
src/cmd/ld/decodesym.c
+215
-0
src/cmd/ld/dwarf.c
src/cmd/ld/dwarf.c
+1
-235
src/cmd/ld/lib.h
src/cmd/ld/lib.h
+28
-2
src/cmd/ld/symtab.c
src/cmd/ld/symtab.c
+4
-0
No files found.
src/cmd/5l/asm.c
View file @
032e5bfb
...
...
@@ -505,6 +505,8 @@ doelf(void)
if
(
HEADTYPE
==
Hnetbsd
)
elfstr
[
ElfStrNoteNetbsdIdent
]
=
addstring
(
shstrtab
,
".note.netbsd.ident"
);
addstring
(
shstrtab
,
".rodata"
);
addstring
(
shstrtab
,
".gcdata"
);
addstring
(
shstrtab
,
".gcbss"
);
addstring
(
shstrtab
,
".gosymtab"
);
addstring
(
shstrtab
,
".gopclntab"
);
if
(
!
debug
[
's'
])
{
...
...
@@ -661,7 +663,7 @@ asmb(void)
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
codeblk
(
sect
->
vaddr
,
sect
->
len
);
/* output read-only data in text segment (rodata, gosymtab
and pclntab
) */
/* output read-only data in text segment (rodata, gosymtab
, pclntab, ...
) */
for
(
sect
=
sect
->
next
;
sect
!=
nil
;
sect
=
sect
->
next
)
{
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
datblk
(
sect
->
vaddr
,
sect
->
len
);
...
...
@@ -2274,6 +2276,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
case
SNOPTRDATA
:
case
SSYMTAB
:
case
SPCLNTAB
:
case
SGCDATA
:
case
SGCBSS
:
if
(
!
s
->
reachable
)
continue
;
put
(
s
,
s
->
name
,
'D'
,
s
->
value
,
s
->
size
,
s
->
version
,
s
->
gotype
);
...
...
src/cmd/6l/asm.c
View file @
032e5bfb
...
...
@@ -579,6 +579,8 @@ doelf(void)
elfstr
[
ElfStrNoteNetbsdIdent
]
=
addstring
(
shstrtab
,
".note.netbsd.ident"
);
addstring
(
shstrtab
,
".elfdata"
);
addstring
(
shstrtab
,
".rodata"
);
addstring
(
shstrtab
,
".gcdata"
);
addstring
(
shstrtab
,
".gcbss"
);
addstring
(
shstrtab
,
".gosymtab"
);
addstring
(
shstrtab
,
".gopclntab"
);
if
(
!
debug
[
's'
])
{
...
...
@@ -732,7 +734,7 @@ asmb(void)
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
codeblk
(
sect
->
vaddr
,
sect
->
len
);
/* output read-only data in text segment (rodata, gosymtab
and pclntab
) */
/* output read-only data in text segment (rodata, gosymtab
, pclntab, ...
) */
for
(
sect
=
sect
->
next
;
sect
!=
nil
;
sect
=
sect
->
next
)
{
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
datblk
(
sect
->
vaddr
,
sect
->
len
);
...
...
@@ -1200,6 +1202,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
case
SSTRING
:
case
SGOSTRING
:
case
SWINDOWS
:
case
SGCDATA
:
case
SGCBSS
:
if
(
!
s
->
reachable
)
continue
;
put
(
s
,
s
->
name
,
'D'
,
symaddr
(
s
),
s
->
size
,
s
->
version
,
s
->
gotype
);
...
...
src/cmd/8l/asm.c
View file @
032e5bfb
...
...
@@ -536,6 +536,8 @@ doelf(void)
elfstr
[
ElfStrNoteNetbsdIdent
]
=
addstring
(
shstrtab
,
".note.netbsd.ident"
);
addstring
(
shstrtab
,
".elfdata"
);
addstring
(
shstrtab
,
".rodata"
);
addstring
(
shstrtab
,
".gcdata"
);
addstring
(
shstrtab
,
".gcbss"
);
addstring
(
shstrtab
,
".gosymtab"
);
addstring
(
shstrtab
,
".gopclntab"
);
if
(
!
debug
[
's'
])
{
...
...
@@ -684,7 +686,7 @@ asmb(void)
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
codeblk
(
sect
->
vaddr
,
sect
->
len
);
/* output read-only data in text segment (rodata, gosymtab
and pclntab
) */
/* output read-only data in text segment (rodata, gosymtab
, pclntab, ...
) */
for
(
sect
=
sect
->
next
;
sect
!=
nil
;
sect
=
sect
->
next
)
{
cseek
(
sect
->
vaddr
-
segtext
.
vaddr
+
segtext
.
fileoff
);
datblk
(
sect
->
vaddr
,
sect
->
len
);
...
...
@@ -1266,6 +1268,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
case
SNOPTRDATA
:
case
SSYMTAB
:
case
SPCLNTAB
:
case
SGCDATA
:
case
SGCBSS
:
if
(
!
s
->
reachable
)
continue
;
put
(
s
,
s
->
name
,
'D'
,
symaddr
(
s
),
s
->
size
,
s
->
version
,
s
->
gotype
);
...
...
src/cmd/gc/subr.c
View file @
032e5bfb
...
...
@@ -3515,7 +3515,6 @@ ngotype(Node *n)
{
if
(
n
->
sym
!=
S
&&
n
->
realtype
!=
T
)
if
(
strncmp
(
n
->
sym
->
name
,
"autotmp_"
,
8
)
!=
0
)
if
(
strncmp
(
n
->
sym
->
name
,
"statictmp_"
,
8
)
!=
0
)
return
typename
(
n
->
realtype
)
->
left
->
sym
;
return
S
;
...
...
src/cmd/ld/data.c
View file @
032e5bfb
...
...
@@ -34,6 +34,7 @@
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/pe.h"
#include "../../pkg/runtime/mgc0.h"
void
dynreloc
(
void
);
static
vlong
addaddrplus4
(
Sym
*
s
,
Sym
*
t
,
int32
add
);
...
...
@@ -628,41 +629,51 @@ addstring(Sym *s, char *str)
}
vlong
adduintxx
(
Sym
*
s
,
uint64
v
,
int
wid
)
setuintxx
(
Sym
*
s
,
vlong
off
,
uint64
v
,
int
wid
)
{
int32
i
,
r
,
fl
;
int32
i
,
fl
;
vlong
o
;
uchar
*
cast
;
if
(
s
->
type
==
0
)
s
->
type
=
SDATA
;
s
->
reachable
=
1
;
r
=
s
->
size
;
s
->
size
+=
wid
;
if
(
s
->
size
<
off
+
wid
)
{
s
->
size
=
off
+
wid
;
symgrow
(
s
,
s
->
size
);
assert
(
r
+
wid
<=
s
->
size
);
}
fl
=
v
;
cast
=
(
uchar
*
)
&
fl
;
switch
(
wid
)
{
case
1
:
s
->
p
[
r
]
=
cast
[
inuxi1
[
0
]];
s
->
p
[
off
]
=
cast
[
inuxi1
[
0
]];
break
;
case
2
:
for
(
i
=
0
;
i
<
2
;
i
++
)
s
->
p
[
r
+
i
]
=
cast
[
inuxi2
[
i
]];
s
->
p
[
off
+
i
]
=
cast
[
inuxi2
[
i
]];
break
;
case
4
:
for
(
i
=
0
;
i
<
4
;
i
++
)
s
->
p
[
r
+
i
]
=
cast
[
inuxi4
[
i
]];
s
->
p
[
off
+
i
]
=
cast
[
inuxi4
[
i
]];
break
;
case
8
:
o
=
v
;
cast
=
(
uchar
*
)
&
o
;
for
(
i
=
0
;
i
<
8
;
i
++
)
s
->
p
[
r
+
i
]
=
cast
[
inuxi8
[
i
]];
s
->
p
[
off
+
i
]
=
cast
[
inuxi8
[
i
]];
break
;
}
return
r
;
return
off
;
}
vlong
adduintxx
(
Sym
*
s
,
uint64
v
,
int
wid
)
{
int32
off
;
off
=
s
->
size
;
setuintxx
(
s
,
off
,
v
,
wid
);
return
off
;
}
vlong
...
...
@@ -689,6 +700,30 @@ adduint64(Sym *s, uint64 v)
return
adduintxx
(
s
,
v
,
8
);
}
void
setuint8
(
Sym
*
s
,
vlong
r
,
uint8
v
)
{
setuintxx
(
s
,
r
,
v
,
1
);
}
void
setuint16
(
Sym
*
s
,
vlong
r
,
uint16
v
)
{
setuintxx
(
s
,
r
,
v
,
2
);
}
void
setuint32
(
Sym
*
s
,
vlong
r
,
uint32
v
)
{
setuintxx
(
s
,
r
,
v
,
4
);
}
void
setuint64
(
Sym
*
s
,
vlong
r
,
uint64
v
)
{
setuintxx
(
s
,
r
,
v
,
8
);
}
vlong
addaddrplus
(
Sym
*
s
,
Sym
*
t
,
int32
add
)
{
...
...
@@ -793,17 +828,87 @@ dosymtype(void)
}
}
static
int32
alignsymsize
(
int32
s
)
{
if
(
s
>=
PtrSize
)
s
=
rnd
(
s
,
PtrSize
);
else
if
(
s
>
2
)
s
=
rnd
(
s
,
4
);
return
s
;
}
static
int32
aligndatsize
(
int32
datsize
,
Sym
*
s
)
{
int32
t
;
if
(
s
->
align
!=
0
)
{
datsize
=
rnd
(
datsize
,
s
->
align
);
}
else
{
t
=
alignsymsize
(
s
->
size
);
if
(
t
&
1
)
{
;
}
else
if
(
t
&
2
)
datsize
=
rnd
(
datsize
,
2
);
else
if
(
t
&
4
)
datsize
=
rnd
(
datsize
,
4
);
else
datsize
=
rnd
(
datsize
,
8
);
}
return
datsize
;
}
static
void
gcaddsym
(
Sym
*
gc
,
Sym
*
s
,
int32
off
)
{
int32
a
;
Sym
*
gotype
;
if
(
s
->
size
<
PtrSize
)
return
;
if
(
strcmp
(
s
->
name
,
".string"
)
==
0
)
return
;
gotype
=
s
->
gotype
;
if
(
gotype
!=
nil
)
{
//print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name);
adduintxx
(
gc
,
GC_CALL
,
PtrSize
);
adduintxx
(
gc
,
off
,
PtrSize
);
addaddrplus
(
gc
,
decodetype_gc
(
gotype
),
1
*
PtrSize
);
}
else
{
//print("gcaddsym: %s %d <unknown type>\n", s->name, s->size);
for
(
a
=
-
off
&
(
PtrSize
-
1
);
a
+
PtrSize
<=
s
->
size
;
a
+=
PtrSize
)
{
adduintxx
(
gc
,
GC_APTR
,
PtrSize
);
adduintxx
(
gc
,
off
+
a
,
PtrSize
);
}
}
}
void
dodata
(
void
)
{
int32
t
,
datsize
;
Section
*
sect
,
*
noptr
;
Section
*
sect
;
Sym
*
s
,
*
last
,
**
l
;
Sym
*
gcdata1
,
*
gcbss1
;
if
(
debug
[
'v'
])
Bprint
(
&
bso
,
"%5.2f dodata
\n
"
,
cputime
());
Bflush
(
&
bso
);
// define garbage collection symbols
gcdata1
=
lookup
(
"gcdata1"
,
0
);
gcdata1
->
type
=
SGCDATA
;
gcdata1
->
reachable
=
1
;
gcbss1
=
lookup
(
"gcbss1"
,
0
);
gcbss1
->
type
=
SGCBSS
;
gcbss1
->
reachable
=
1
;
// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
adduintxx
(
gcdata1
,
0
,
PtrSize
);
adduintxx
(
gcbss1
,
0
,
PtrSize
);
last
=
nil
;
datap
=
nil
;
...
...
@@ -847,146 +952,164 @@ dodata(void)
datap
=
datsort
(
datap
);
/*
* allocate
data
sections. list is sorted by type,
* allocate sections. list is sorted by type,
* so we can just walk it for each piece we want to emit.
* segdata is processed before segtext, because we need
* to see all symbols in the .data and .bss sections in order
* to generate garbage collection information.
*/
/* read-only data */
sect
=
addsection
(
&
segtext
,
".rodata"
,
04
);
sect
->
vaddr
=
0
;
datsize
=
0
;
/* begin segdata */
/* skip symbols belonging to segtext */
s
=
datap
;
for
(;
s
!=
nil
&&
s
->
type
<
SSYMTAB
;
s
=
s
->
next
)
{
for
(;
s
!=
nil
&&
s
->
type
<
SELFSECT
;
s
=
s
->
next
);
/* writable ELF sections */
datsize
=
0
;
for
(;
s
!=
nil
&&
s
->
type
<
SNOPTRDATA
;
s
=
s
->
next
)
{
sect
=
addsection
(
&
segdata
,
s
->
name
,
06
);
if
(
s
->
align
!=
0
)
datsize
=
rnd
(
datsize
,
s
->
align
);
s
->
type
=
SRODATA
;
sect
->
vaddr
=
datsize
;
s
->
type
=
SDATA
;
s
->
value
=
datsize
;
datsize
+=
rnd
(
s
->
size
,
PtrSize
);
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
}
/*
gosymtab
*/
sect
=
addsection
(
&
seg
text
,
".gosymtab"
,
04
);
/*
pointer-free data
*/
sect
=
addsection
(
&
seg
data
,
".noptrdata"
,
06
);
sect
->
vaddr
=
datsize
;
for
(;
s
!=
nil
&&
s
->
type
<
SPCLNTAB
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
for
(;
s
!=
nil
&&
s
->
type
<
SDATA
;
s
=
s
->
next
)
{
s
->
type
=
SDATA
;
t
=
alignsymsize
(
s
->
size
);
datsize
=
aligndatsize
(
datsize
,
s
);
s
->
value
=
datsize
;
datsize
+=
s
->
size
;
datsize
+=
t
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
datsize
=
rnd
(
datsize
,
PtrSize
);
/*
gopclntab
*/
sect
=
addsection
(
&
seg
text
,
".gopclntab"
,
04
);
/*
data
*/
sect
=
addsection
(
&
seg
data
,
".data"
,
06
);
sect
->
vaddr
=
datsize
;
for
(;
s
!=
nil
&&
s
->
type
<
SELFROSECT
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
for
(;
s
!=
nil
&&
s
->
type
<
SBSS
;
s
=
s
->
next
)
{
s
->
type
=
SDATA
;
t
=
alignsymsize
(
s
->
size
);
datsize
=
aligndatsize
(
datsize
,
s
);
s
->
value
=
datsize
;
datsize
+=
s
->
size
;
gcaddsym
(
gcdata1
,
s
,
datsize
-
sect
->
vaddr
);
// gc
datsize
+=
t
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
datsize
=
rnd
(
datsize
,
PtrSize
);
/* read-only ELF sections */
for
(;
s
!=
nil
&&
s
->
type
<
SELFSECT
;
s
=
s
->
next
)
{
sect
=
addsection
(
&
segtext
,
s
->
name
,
04
);
if
(
s
->
align
!=
0
)
datsize
=
rnd
(
datsize
,
s
->
align
);
adduintxx
(
gcdata1
,
GC_END
,
PtrSize
);
setuintxx
(
gcdata1
,
0
,
sect
->
len
,
PtrSize
);
/* bss */
sect
=
addsection
(
&
segdata
,
".bss"
,
06
);
sect
->
vaddr
=
datsize
;
s
->
type
=
SRODATA
;
for
(;
s
!=
nil
&&
s
->
type
<
SNOPTRBSS
;
s
=
s
->
next
)
{
t
=
alignsymsize
(
s
->
size
);
datsize
=
aligndatsize
(
datsize
,
s
);
s
->
value
=
datsize
;
datsize
+=
rnd
(
s
->
size
,
PtrSize
);
gcaddsym
(
gcbss1
,
s
,
datsize
-
sect
->
vaddr
);
// gc
datsize
+=
t
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
datsize
=
rnd
(
datsize
,
PtrSize
);
adduintxx
(
gcbss1
,
GC_END
,
PtrSize
);
setuintxx
(
gcbss1
,
0
,
sect
->
len
,
PtrSize
);
/* pointer-free bss */
sect
=
addsection
(
&
segdata
,
".noptrbss"
,
06
);
sect
->
vaddr
=
datsize
;
for
(;
s
!=
nil
;
s
=
s
->
next
)
{
if
(
s
->
type
>
SNOPTRBSS
)
{
cursym
=
s
;
diag
(
"unexpected symbol type %d"
,
s
->
type
);
}
t
=
alignsymsize
(
s
->
size
);
datsize
=
aligndatsize
(
datsize
,
s
);
s
->
value
=
datsize
;
datsize
+=
t
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
datsize
=
rnd
(
datsize
,
PtrSize
);
/* writable ELF sections */
/* we finished segdata, begin segtext */
/* read-only data */
sect
=
addsection
(
&
segtext
,
".rodata"
,
04
);
sect
->
vaddr
=
0
;
datsize
=
0
;
for
(;
s
!=
nil
&&
s
->
type
<
SNOPTRDATA
;
s
=
s
->
next
)
{
sect
=
addsection
(
&
segdata
,
s
->
name
,
06
);
s
=
datap
;
for
(;
s
!=
nil
&&
s
->
type
<
SGCDATA
;
s
=
s
->
next
)
{
if
(
s
->
align
!=
0
)
datsize
=
rnd
(
datsize
,
s
->
align
);
sect
->
vaddr
=
datsize
;
s
->
type
=
SDATA
;
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
rnd
(
s
->
size
,
PtrSize
);
sect
->
len
=
datsize
-
sect
->
vaddr
;
}
/* pointer-free data, then data */
sect
=
addsection
(
&
segdata
,
".noptrdata"
,
06
);
sect
->
vaddr
=
datsize
;
noptr
=
sect
;
for
(;
;
s
=
s
->
next
)
{
if
((
s
==
nil
||
s
->
type
>=
SDATA
)
&&
sect
==
noptr
)
{
// finish noptrdata, start data
datsize
=
rnd
(
datsize
,
8
);
sect
->
len
=
datsize
-
sect
->
vaddr
;
sect
=
addsection
(
&
segdata
,
".data"
,
06
);
/* gcdata */
sect
=
addsection
(
&
segtext
,
".gcdata"
,
04
);
sect
->
vaddr
=
datsize
;
for
(;
s
!=
nil
&&
s
->
type
==
SGCDATA
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
s
->
size
;
}
if
(
s
==
nil
||
s
->
type
>=
SBSS
)
{
// finish data
sect
->
len
=
datsize
-
sect
->
vaddr
;
break
;
}
s
->
type
=
SDATA
;
t
=
s
->
size
;
if
(
t
>=
PtrSize
)
t
=
rnd
(
t
,
PtrSize
);
else
if
(
t
>
2
)
t
=
rnd
(
t
,
4
);
if
(
s
->
align
!=
0
)
datsize
=
rnd
(
datsize
,
s
->
align
);
else
if
(
t
&
1
)
{
;
}
else
if
(
t
&
2
)
datsize
=
rnd
(
datsize
,
2
);
else
if
(
t
&
4
)
datsize
=
rnd
(
datsize
,
4
);
else
datsize
=
rnd
(
datsize
,
8
);
datsize
=
rnd
(
datsize
,
PtrSize
);
/* gcbss */
sect
=
addsection
(
&
segtext
,
".gcbss"
,
04
);
sect
->
vaddr
=
datsize
;
for
(;
s
!=
nil
&&
s
->
type
==
SGCBSS
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
t
;
datsize
+=
s
->
size
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
datsize
=
rnd
(
datsize
,
PtrSize
);
/* bss, then pointer-free bss */
noptr
=
nil
;
sect
=
addsection
(
&
segdata
,
".bss"
,
06
);
/* gosymtab */
sect
=
addsection
(
&
segtext
,
".gosymtab"
,
04
);
sect
->
vaddr
=
datsize
;
for
(;
;
s
=
s
->
next
)
{
if
((
s
==
nil
||
s
->
type
>=
SNOPTRBSS
)
&&
noptr
==
nil
)
{
// finish bss, start noptrbss
datsize
=
rnd
(
datsize
,
8
);
for
(;
s
!=
nil
&&
s
->
type
<
SPCLNTAB
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
s
->
size
;
}
sect
->
len
=
datsize
-
sect
->
vaddr
;
sect
=
addsection
(
&
segdata
,
".noptrbss"
,
06
);
datsize
=
rnd
(
datsize
,
PtrSize
);
/* gopclntab */
sect
=
addsection
(
&
segtext
,
".gopclntab"
,
04
);
sect
->
vaddr
=
datsize
;
noptr
=
sect
;
for
(;
s
!=
nil
&&
s
->
type
<
SELFROSECT
;
s
=
s
->
next
)
{
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
s
->
size
;
}
if
(
s
==
nil
)
{
sect
->
len
=
datsize
-
sect
->
vaddr
;
break
;
}
if
(
s
->
type
>
SNOPTRBSS
)
{
cursym
=
s
;
diag
(
"unexpected symbol type %d"
,
s
->
type
);
}
t
=
s
->
size
;
if
(
t
>=
PtrSize
)
t
=
rnd
(
t
,
PtrSize
);
else
if
(
t
>
2
)
t
=
rnd
(
t
,
4
);
datsize
=
rnd
(
datsize
,
PtrSize
);
/* read-only ELF sections */
for
(;
s
!=
nil
&&
s
->
type
<
SELFSECT
;
s
=
s
->
next
)
{
sect
=
addsection
(
&
segtext
,
s
->
name
,
04
);
if
(
s
->
align
!=
0
)
datsize
=
rnd
(
datsize
,
s
->
align
);
else
if
(
t
&
1
)
{
;
}
else
if
(
t
&
2
)
datsize
=
rnd
(
datsize
,
2
);
else
if
(
t
&
4
)
datsize
=
rnd
(
datsize
,
4
);
else
datsize
=
rnd
(
datsize
,
8
);
sect
->
vaddr
=
datsize
;
s
->
type
=
SRODATA
;
s
->
value
=
datsize
;
datsize
+=
t
;
datsize
+=
rnd
(
s
->
size
,
PtrSize
);
sect
->
len
=
datsize
-
sect
->
vaddr
;
}
}
...
...
@@ -1038,6 +1161,7 @@ void
address
(
void
)
{
Section
*
s
,
*
text
,
*
data
,
*
rodata
,
*
symtab
,
*
pclntab
,
*
noptr
,
*
bss
,
*
noptrbss
;
Section
*
gcdata
,
*
gcbss
;
Sym
*
sym
,
*
sub
;
uvlong
va
;
...
...
@@ -1084,7 +1208,9 @@ address(void)
text
=
segtext
.
sect
;
rodata
=
text
->
next
;
symtab
=
rodata
->
next
;
gcdata
=
rodata
->
next
;
gcbss
=
gcdata
->
next
;
symtab
=
gcbss
->
next
;
pclntab
=
symtab
->
next
;
for
(
sym
=
datap
;
sym
!=
nil
;
sym
=
sym
->
next
)
{
...
...
@@ -1101,6 +1227,10 @@ address(void)
xdefine
(
"etext"
,
STEXT
,
text
->
vaddr
+
text
->
len
);
xdefine
(
"rodata"
,
SRODATA
,
rodata
->
vaddr
);
xdefine
(
"erodata"
,
SRODATA
,
rodata
->
vaddr
+
rodata
->
len
);
xdefine
(
"gcdata"
,
SGCDATA
,
gcdata
->
vaddr
);
xdefine
(
"egcdata"
,
SGCDATA
,
gcdata
->
vaddr
+
gcdata
->
len
);
xdefine
(
"gcbss"
,
SGCBSS
,
gcbss
->
vaddr
);
xdefine
(
"egcbss"
,
SGCBSS
,
gcbss
->
vaddr
+
gcbss
->
len
);
xdefine
(
"symtab"
,
SRODATA
,
symtab
->
vaddr
);
xdefine
(
"esymtab"
,
SRODATA
,
symtab
->
vaddr
+
symtab
->
len
);
xdefine
(
"pclntab"
,
SRODATA
,
pclntab
->
vaddr
);
...
...
src/cmd/ld/decodesym.c
0 → 100644
View file @
032e5bfb
// Copyright 2012 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.
#include "l.h"
#include "lib.h"
#include "../../pkg/runtime/typekind.h"
// Decoding the type.* symbols. This has to be in sync with
// ../../pkg/runtime/type.go, or more specificaly, with what
// ../gc/reflect.c stuffs in these.
static
Reloc
*
decode_reloc
(
Sym
*
s
,
int32
off
)
{
int
i
;
for
(
i
=
0
;
i
<
s
->
nr
;
i
++
)
if
(
s
->
r
[
i
].
off
==
off
)
return
s
->
r
+
i
;
return
nil
;
}
static
Sym
*
decode_reloc_sym
(
Sym
*
s
,
int32
off
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
off
);
if
(
r
==
nil
)
return
nil
;
return
r
->
sym
;
}
static
uvlong
decode_inuxi
(
uchar
*
p
,
int
sz
)
{
uint64
v
;
uint32
l
;
uchar
*
cast
,
*
inuxi
;
int
i
;
v
=
l
=
0
;
cast
=
nil
;
inuxi
=
nil
;
switch
(
sz
)
{
case
2
:
cast
=
(
uchar
*
)
&
l
;
inuxi
=
inuxi2
;
break
;
case
4
:
cast
=
(
uchar
*
)
&
l
;
inuxi
=
inuxi4
;
break
;
case
8
:
cast
=
(
uchar
*
)
&
v
;
inuxi
=
inuxi8
;
break
;
default:
diag
(
"dwarf: decode inuxi %d"
,
sz
);
errorexit
();
}
for
(
i
=
0
;
i
<
sz
;
i
++
)
cast
[
inuxi
[
i
]]
=
p
[
i
];
if
(
sz
==
8
)
return
v
;
return
l
;
}
// Type.commonType.kind
uint8
decodetype_kind
(
Sym
*
s
)
{
return
s
->
p
[
3
*
PtrSize
+
7
]
&
~
KindNoPointers
;
// 0x13 / 0x1f
}
// Type.commonType.size
vlong
decodetype_size
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
2
*
PtrSize
,
PtrSize
);
// 0x8 / 0x10
}
// Type.commonType.gc
Sym
*
decodetype_gc
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
3
*
PtrSize
+
8
+
1
*
PtrSize
);
}
// Type.ArrayType.elem and Type.SliceType.Elem
Sym
*
decodetype_arrayelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
vlong
decodetype_arraylen
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
PtrSize
);
}
// Type.PtrType.elem
Sym
*
decodetype_ptrelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
// Type.MapType.key, elem
Sym
*
decodetype_mapkey
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
Sym
*
decodetype_mapvalue
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
);
// 0x20 / 0x38
}
// Type.ChanType.elem
Sym
*
decodetype_chanelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
// Type.FuncType.dotdotdot
int
decodetype_funcdotdotdot
(
Sym
*
s
)
{
return
s
->
p
[
CommonSize
];
}
// Type.FuncType.in.len
int
decodetype_funcincount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
2
*
PtrSize
,
4
);
}
int
decodetype_funcoutcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
3
*
PtrSize
+
2
*
4
,
4
);
}
Sym
*
decodetype_funcintype
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
CommonSize
+
PtrSize
);
if
(
r
==
nil
)
return
nil
;
return
decode_reloc_sym
(
r
->
sym
,
r
->
add
+
i
*
PtrSize
);
}
Sym
*
decodetype_funcouttype
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
CommonSize
+
2
*
PtrSize
+
2
*
4
);
if
(
r
==
nil
)
return
nil
;
return
decode_reloc_sym
(
r
->
sym
,
r
->
add
+
i
*
PtrSize
);
}
// Type.StructType.fields.Slice::len
int
decodetype_structfieldcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
4
);
}
enum
{
StructFieldSize
=
5
*
PtrSize
};
// Type.StructType.fields[]-> name, typ and offset.
char
*
decodetype_structfieldname
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
// go.string."foo" 0x28 / 0x40
s
=
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
);
if
(
s
==
nil
)
// embedded structs have a nil name.
return
nil
;
r
=
decode_reloc
(
s
,
0
);
// s has a pointer to the string data at offset 0
if
(
r
==
nil
)
// shouldn't happen.
return
nil
;
return
(
char
*
)
r
->
sym
->
p
+
r
->
add
;
// the c-string
}
Sym
*
decodetype_structfieldtype
(
Sym
*
s
,
int
i
)
{
return
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
+
2
*
PtrSize
);
}
vlong
decodetype_structfieldoffs
(
Sym
*
s
,
int
i
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
+
4
*
PtrSize
,
4
);
}
// InterfaceTYpe.methods.len
vlong
decodetype_ifacemethodcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
4
);
}
src/cmd/ld/dwarf.c
View file @
032e5bfb
...
...
@@ -19,6 +19,7 @@
#include "../ld/elf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
#include "../../pkg/runtime/typekind.h"
/*
* Offsets and sizes of the debug_* sections in the cout file.
...
...
@@ -740,241 +741,6 @@ newabslocexprattr(DWDie *die, vlong addr)
memmove
(
die
->
attr
->
data
,
block
,
i
);
}
// Decoding the type.* symbols. This has to be in sync with
// ../../pkg/runtime/type.go, or more specificaly, with what
// ../gc/reflect.c stuffs in these.
enum
{
KindBool
=
1
,
KindInt
,
KindInt8
,
KindInt16
,
KindInt32
,
KindInt64
,
KindUint
,
KindUint8
,
KindUint16
,
KindUint32
,
KindUint64
,
KindUintptr
,
KindFloat32
,
KindFloat64
,
KindComplex64
,
KindComplex128
,
KindArray
,
KindChan
,
KindFunc
,
KindInterface
,
KindMap
,
KindPtr
,
KindSlice
,
KindString
,
KindStruct
,
KindUnsafePointer
,
KindNoPointers
=
1
<<
7
,
// size of Type interface header + CommonType structure.
CommonSize
=
2
*
PtrSize
+
6
*
PtrSize
+
8
,
};
static
Reloc
*
decode_reloc
(
Sym
*
s
,
int32
off
)
{
int
i
;
for
(
i
=
0
;
i
<
s
->
nr
;
i
++
)
if
(
s
->
r
[
i
].
off
==
off
)
return
s
->
r
+
i
;
return
nil
;
}
static
Sym
*
decode_reloc_sym
(
Sym
*
s
,
int32
off
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
off
);
if
(
r
==
nil
)
return
nil
;
return
r
->
sym
;
}
static
uvlong
decode_inuxi
(
uchar
*
p
,
int
sz
)
{
uint64
v
;
uint32
l
;
uchar
*
cast
,
*
inuxi
;
int
i
;
v
=
l
=
0
;
cast
=
nil
;
inuxi
=
nil
;
switch
(
sz
)
{
case
2
:
cast
=
(
uchar
*
)
&
l
;
inuxi
=
inuxi2
;
break
;
case
4
:
cast
=
(
uchar
*
)
&
l
;
inuxi
=
inuxi4
;
break
;
case
8
:
cast
=
(
uchar
*
)
&
v
;
inuxi
=
inuxi8
;
break
;
default:
diag
(
"dwarf: decode inuxi %d"
,
sz
);
errorexit
();
}
for
(
i
=
0
;
i
<
sz
;
i
++
)
cast
[
inuxi
[
i
]]
=
p
[
i
];
if
(
sz
==
8
)
return
v
;
return
l
;
}
// Type.commonType.kind
static
uint8
decodetype_kind
(
Sym
*
s
)
{
return
s
->
p
[
3
*
PtrSize
+
7
]
&
~
KindNoPointers
;
// 0x13 / 0x1f
}
// Type.commonType.size
static
vlong
decodetype_size
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
2
*
PtrSize
,
PtrSize
);
// 0x8 / 0x10
}
// Type.ArrayType.elem and Type.SliceType.Elem
static
Sym
*
decodetype_arrayelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
static
vlong
decodetype_arraylen
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
PtrSize
);
}
// Type.PtrType.elem
static
Sym
*
decodetype_ptrelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
// Type.MapType.key, elem
static
Sym
*
decodetype_mapkey
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
static
Sym
*
decodetype_mapvalue
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
);
// 0x20 / 0x38
}
// Type.ChanType.elem
static
Sym
*
decodetype_chanelem
(
Sym
*
s
)
{
return
decode_reloc_sym
(
s
,
CommonSize
);
// 0x1c / 0x30
}
// Type.FuncType.dotdotdot
static
int
decodetype_funcdotdotdot
(
Sym
*
s
)
{
return
s
->
p
[
CommonSize
];
}
// Type.FuncType.in.len
static
int
decodetype_funcincount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
2
*
PtrSize
,
4
);
}
static
int
decodetype_funcoutcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
3
*
PtrSize
+
2
*
4
,
4
);
}
static
Sym
*
decodetype_funcintype
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
CommonSize
+
PtrSize
);
if
(
r
==
nil
)
return
nil
;
return
decode_reloc_sym
(
r
->
sym
,
r
->
add
+
i
*
PtrSize
);
}
static
Sym
*
decodetype_funcouttype
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
r
=
decode_reloc
(
s
,
CommonSize
+
2
*
PtrSize
+
2
*
4
);
if
(
r
==
nil
)
return
nil
;
return
decode_reloc_sym
(
r
->
sym
,
r
->
add
+
i
*
PtrSize
);
}
// Type.StructType.fields.Slice::len
static
int
decodetype_structfieldcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
4
);
}
enum
{
StructFieldSize
=
5
*
PtrSize
};
// Type.StructType.fields[]-> name, typ and offset.
static
char
*
decodetype_structfieldname
(
Sym
*
s
,
int
i
)
{
Reloc
*
r
;
// go.string."foo" 0x28 / 0x40
s
=
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
);
if
(
s
==
nil
)
// embedded structs have a nil name.
return
nil
;
r
=
decode_reloc
(
s
,
0
);
// s has a pointer to the string data at offset 0
if
(
r
==
nil
)
// shouldn't happen.
return
nil
;
return
(
char
*
)
r
->
sym
->
p
+
r
->
add
;
// the c-string
}
static
Sym
*
decodetype_structfieldtype
(
Sym
*
s
,
int
i
)
{
return
decode_reloc_sym
(
s
,
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
+
2
*
PtrSize
);
}
static
vlong
decodetype_structfieldoffs
(
Sym
*
s
,
int
i
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
+
2
*
4
+
i
*
StructFieldSize
+
4
*
PtrSize
,
4
);
}
// InterfaceTYpe.methods.len
static
vlong
decodetype_ifacemethodcount
(
Sym
*
s
)
{
return
decode_inuxi
(
s
->
p
+
CommonSize
+
PtrSize
,
4
);
}
// Fake attributes for slices, maps and channel
enum
{
...
...
src/cmd/ld/lib.h
View file @
032e5bfb
...
...
@@ -39,6 +39,8 @@ enum
SSTRING
,
SGOSTRING
,
SRODATA
,
SGCDATA
,
SGCBSS
,
SSYMTAB
,
SPCLNTAB
,
SELFROSECT
,
...
...
@@ -186,14 +188,18 @@ void savedata(Sym*, Prog*, char*);
void
symgrow
(
Sym
*
,
int32
);
void
addstrdata
(
char
*
,
char
*
);
vlong
addstring
(
Sym
*
,
char
*
);
vlong
adduint8
(
Sym
*
,
uint8
);
vlong
adduint16
(
Sym
*
,
uint16
);
vlong
adduint32
(
Sym
*
,
uint32
);
vlong
adduint64
(
Sym
*
,
uint64
);
vlong
addaddr
(
Sym
*
,
Sym
*
);
vlong
addaddrplus
(
Sym
*
,
Sym
*
,
int32
);
vlong
addpcrelplus
(
Sym
*
,
Sym
*
,
int32
);
vlong
addsize
(
Sym
*
,
Sym
*
);
vlong
adduint8
(
Sym
*
,
uint8
);
vlong
adduint16
(
Sym
*
,
uint16
);
void
setuint8
(
Sym
*
,
vlong
,
uint8
);
void
setuint16
(
Sym
*
,
vlong
,
uint16
);
void
setuint32
(
Sym
*
,
vlong
,
uint32
);
void
setuint64
(
Sym
*
,
vlong
,
uint64
);
void
asmsym
(
void
);
void
asmelfsym
(
void
);
void
asmplan9sym
(
void
);
...
...
@@ -315,3 +321,23 @@ void cseek(vlong);
void
cwrite
(
void
*
,
int
);
void
importcycles
(
void
);
int
Zconv
(
Fmt
*
);
uint8
decodetype_kind
(
Sym
*
);
vlong
decodetype_size
(
Sym
*
);
Sym
*
decodetype_gc
(
Sym
*
);
Sym
*
decodetype_arrayelem
(
Sym
*
);
vlong
decodetype_arraylen
(
Sym
*
);
Sym
*
decodetype_ptrelem
(
Sym
*
);
Sym
*
decodetype_mapkey
(
Sym
*
);
Sym
*
decodetype_mapvalue
(
Sym
*
);
Sym
*
decodetype_chanelem
(
Sym
*
);
int
decodetype_funcdotdotdot
(
Sym
*
);
int
decodetype_funcincount
(
Sym
*
);
int
decodetype_funcoutcount
(
Sym
*
);
Sym
*
decodetype_funcintype
(
Sym
*
,
int
);
Sym
*
decodetype_funcouttype
(
Sym
*
,
int
);
int
decodetype_structfieldcount
(
Sym
*
);
char
*
decodetype_structfieldname
(
Sym
*
,
int
);
Sym
*
decodetype_structfieldtype
(
Sym
*
,
int
);
vlong
decodetype_structfieldoffs
(
Sym
*
,
int
);
vlong
decodetype_ifacemethodcount
(
Sym
*
);
src/cmd/ld/symtab.c
View file @
032e5bfb
...
...
@@ -339,6 +339,10 @@ symtab(void)
xdefine
(
"etext"
,
STEXT
,
0
);
xdefine
(
"rodata"
,
SRODATA
,
0
);
xdefine
(
"erodata"
,
SRODATA
,
0
);
xdefine
(
"gcdata"
,
SGCDATA
,
0
);
xdefine
(
"egcdata"
,
SGCDATA
,
0
);
xdefine
(
"gcbss"
,
SGCBSS
,
0
);
xdefine
(
"egcbss"
,
SGCBSS
,
0
);
xdefine
(
"noptrdata"
,
SNOPTRDATA
,
0
);
xdefine
(
"enoptrdata"
,
SNOPTRDATA
,
0
);
xdefine
(
"data"
,
SDATA
,
0
);
...
...
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