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
b433552e
Commit
b433552e
authored
Aug 30, 2010
by
Luuk van Dijk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
8l: emit DWARF in ELF.
R=rsc, r, ken2 CC=golang-dev
https://golang.org/cl/2004046
parent
5c603dbb
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
514 additions
and
449 deletions
+514
-449
src/cmd/6l/asm.c
src/cmd/6l/asm.c
+1
-2
src/cmd/6l/l.h
src/cmd/6l/l.h
+1
-1
src/cmd/8l/Makefile
src/cmd/8l/Makefile
+4
-1
src/cmd/8l/asm.c
src/cmd/8l/asm.c
+18
-2
src/cmd/8l/l.h
src/cmd/8l/l.h
+1
-0
src/cmd/8l/obj.c
src/cmd/8l/obj.c
+2
-0
src/cmd/ld/dwarf.c
src/cmd/ld/dwarf.c
+487
-443
No files found.
src/cmd/6l/asm.c
View file @
b433552e
...
...
@@ -641,8 +641,7 @@ asmb(void)
dwarfemitdebugsections
();
}
}
else
if
(
dlm
){
}
else
if
(
dlm
){
seek
(
cout
,
HEADR
+
textsize
+
datsize
,
0
);
asmdyn
();
cflush
();
...
...
src/cmd/6l/l.h
View file @
b433552e
...
...
@@ -394,9 +394,9 @@ Prog* brchain(Prog*);
Prog
*
brloop
(
Prog
*
);
void
buildop
(
void
);
void
cflush
(
void
);
vlong
cpos
(
void
);
void
ckoff
(
Sym
*
,
int32
);
Prog
*
copyp
(
Prog
*
);
vlong
cpos
(
void
);
double
cputime
(
void
);
void
datblk
(
int32
,
int32
);
void
deadcode
(
void
);
...
...
src/cmd/8l/Makefile
View file @
b433552e
...
...
@@ -9,8 +9,10 @@ TARG=8l
OFILES
=
\
asm.
$O
\
dwarf.
$O
\
elf.
$O
\
enam.
$O
\
go.
$O
\
lib.
$O
\
list.
$O
\
macho.
$O
\
...
...
@@ -19,11 +21,12 @@ OFILES=\
pass.
$O
\
pe.
$O
\
span.
$O
\
go.
$O
\
HFILES
=
\
l.h
\
../8l/8.out.h
\
../ld/dwarf.h
\
../ld/elf.h
\
../ld/macho.h
\
../ld/pe.h
\
...
...
src/cmd/8l/asm.c
View file @
b433552e
...
...
@@ -31,6 +31,7 @@
#include "l.h"
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/dwarf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
...
...
@@ -293,6 +294,7 @@ doelf(void)
elfstr
[
ElfStrGosymcounts
]
=
addstring
(
shstrtab
,
".gosymcounts"
);
elfstr
[
ElfStrGosymtab
]
=
addstring
(
shstrtab
,
".gosymtab"
);
elfstr
[
ElfStrGopclntab
]
=
addstring
(
shstrtab
,
".gopclntab"
);
dwarfaddshstrings
(
shstrtab
);
}
elfstr
[
ElfStrShstrtab
]
=
addstring
(
shstrtab
,
".shstrtab"
);
...
...
@@ -649,8 +651,13 @@ asmb(void)
lputl
(
symsize
);
lputl
(
lcsize
);
cflush
();
}
else
if
(
dlm
){
if
(
!
debug
[
's'
])
{
seek
(
cout
,
symo
+
8
+
symsize
+
lcsize
,
0
);
if
(
debug
[
'v'
])
Bprint
(
&
bso
,
"%5.2f dwarf
\n
"
,
cputime
());
dwarfemitdebugsections
();
}
}
else
if
(
dlm
){
seek
(
cout
,
HEADR
+
textsize
+
datsize
,
0
);
asmdyn
();
cflush
();
...
...
@@ -1042,6 +1049,8 @@ asmb(void)
sh
->
size
=
w
;
sh
->
addralign
=
1
;
sh
->
addr
=
symdatva
+
8
+
symsize
;
dwarfaddheaders
();
}
sh
=
newElfShstrtab
(
elfstr
[
ElfStrShstrtab
]);
...
...
@@ -1118,6 +1127,13 @@ cflush(void)
cbc
=
sizeof
(
buf
.
cbuf
);
}
/* Current position in file */
vlong
cpos
(
void
)
{
return
seek
(
cout
,
0
,
1
)
+
sizeof
(
buf
.
cbuf
)
-
cbc
;
}
void
datblk
(
int32
s
,
int32
n
)
{
...
...
src/cmd/8l/l.h
View file @
b433552e
...
...
@@ -345,6 +345,7 @@ Prog* brloop(Prog*);
void
cflush
(
void
);
void
ckoff
(
Sym
*
,
int32
);
Prog
*
copyp
(
Prog
*
);
vlong
cpos
(
void
);
double
cputime
(
void
);
void
datblk
(
int32
,
int32
);
void
diag
(
char
*
,
...);
...
...
src/cmd/8l/obj.c
View file @
b433552e
...
...
@@ -33,6 +33,7 @@
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/macho.h"
#include "../ld/dwarf.h"
#include "../ld/pe.h"
#include <ar.h>
...
...
@@ -604,6 +605,7 @@ loop:
histfrogp
++
;
}
else
collapsefrog
(
s
);
dwarfaddfrag
(
s
->
value
,
s
->
name
);
}
goto
loop
;
}
...
...
src/cmd/ld/dwarf.c
View file @
b433552e
...
...
@@ -2,11 +2,11 @@
// 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
"../ld/dwarf.h"
#include
"../ld/dwarf_defs.h"
#include
"../ld/elf.h"
#include
"l.h"
#include
"lib.h"
#include
"../ld/dwarf.h"
#include
"../ld/dwarf_defs.h"
#include
"../ld/elf.h"
/*
* Offsets and sizes of the .debug_* sections in the cout file.
...
...
@@ -37,8 +37,9 @@ struct DWAttrForm {
// index into the abbrevs table below.
enum
{
DW_ABRV_NULL
,
DW_ABRV_COMPUNIT
,
DW_ABRV_NULL
,
DW_ABRV_COMPUNIT
,
DW_ABRV_FUNCTION
,
DW_NABRV
};
...
...
@@ -48,18 +49,26 @@ struct DWAbbrev {
uint8
children
;
DWAttrForm
attr
[
30
];
}
abbrevs
[
DW_NABRV
]
=
{
/* The mandatory DW_ABRV_NULL entry. */
{
0
},
/* The mandatory DW_ABRV_NULL entry. */
{
0
},
/* COMPUNIT */
{
DW_TAG_compile_unit
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_language
,
DW_FORM_data1
,
DW_AT_low_pc
,
DW_FORM_addr
,
DW_AT_high_pc
,
DW_FORM_addr
,
DW_AT_stmt_list
,
DW_FORM_data4
,
0
,
0
},
DW_AT_name
,
DW_FORM_string
,
DW_AT_language
,
DW_FORM_data1
,
DW_AT_low_pc
,
DW_FORM_addr
,
DW_AT_high_pc
,
DW_FORM_addr
,
DW_AT_stmt_list
,
DW_FORM_data4
,
0
,
0
},
/* FUNCTION */
{
DW_TAG_subprogram
,
DW_CHILDREN_no
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_low_pc
,
DW_FORM_addr
,
DW_AT_high_pc
,
DW_FORM_addr
,
0
,
0
},
};
/*
...
...
@@ -72,19 +81,19 @@ struct DWAbbrev {
typedef
struct
DWAttr
DWAttr
;
struct
DWAttr
{
DWAttr
*
link
;
uint8
atr
;
// DW_AT_
uint8
cls
;
// DW_CLS_
vlong
value
;
char
*
data
;
DWAttr
*
link
;
uint8
atr
;
// DW_AT_
uint8
cls
;
// DW_CLS_
vlong
value
;
char
*
data
;
};
typedef
struct
DWDie
DWDie
;
struct
DWDie
{
int
abbrev
;
DWDie
*
link
;
DWDie
*
child
;
DWAttr
*
attr
;
int
abbrev
;
DWDie
*
link
;
DWDie
*
child
;
DWAttr
*
attr
;
};
// top level compilation unit DIE's
...
...
@@ -93,33 +102,45 @@ static DWDie *dwinfo;
static
DWDie
*
newdie
(
DWDie
*
link
,
int
abbrev
)
{
DWDie
*
die
;
DWDie
*
die
;
die
=
mal
(
sizeof
*
die
);
die
->
abbrev
=
abbrev
;
die
->
link
=
link
;
return
die
;
die
=
mal
(
sizeof
*
die
);
die
->
abbrev
=
abbrev
;
die
->
link
=
link
;
return
die
;
}
static
DWAttr
*
newattr
(
DWDie
*
die
,
uint8
attr
,
int
cls
,
vlong
value
,
char
*
data
)
{
DWAttr
*
a
;
a
=
mal
(
sizeof
*
a
);
a
->
link
=
die
->
attr
;
die
->
attr
=
a
;
a
->
atr
=
attr
;
a
->
cls
=
cls
;
a
->
value
=
value
;
a
->
data
=
data
;
return
a
;
DWAttr
*
a
;
a
=
mal
(
sizeof
*
a
);
a
->
link
=
die
->
attr
;
die
->
attr
=
a
;
a
->
atr
=
attr
;
a
->
cls
=
cls
;
a
->
value
=
value
;
a
->
data
=
data
;
return
a
;
}
static
void
addrput
(
vlong
addr
)
{
switch
(
PtrSize
)
{
case
4
:
LPUT
(
addr
);
break
;
case
8
:
VPUT
(
addr
);
break
;
}
}
static
void
uleb128put
(
uvlong
v
)
{
uint8
c
;
uint8
c
;
do
{
c
=
v
&
0x7f
;
...
...
@@ -132,116 +153,116 @@ uleb128put(uvlong v)
static
void
sleb128put
(
vlong
v
)
{
uint8
c
,
s
;
do
{
c
=
v
&
0x7f
;
s
=
c
&
0x40
;
v
>>=
7
;
if
((
v
!=
-
1
||
!
s
)
&&
(
v
!=
0
||
s
))
c
|=
0x80
;
cput
(
c
);
}
while
(
c
&
0x80
);
uint8
c
,
s
;
do
{
c
=
v
&
0x7f
;
s
=
c
&
0x40
;
v
>>=
7
;
if
((
v
!=
-
1
||
!
s
)
&&
(
v
!=
0
||
s
))
c
|=
0x80
;
cput
(
c
);
}
while
(
c
&
0x80
);
};
static
void
putattr
(
int
form
,
int
cls
,
vlong
value
,
char
*
data
)
{
switch
(
form
)
{
case
DW_FORM_addr
:
// address
VPUT
(
value
);
break
;
case
DW_FORM_block1
:
// block
value
&=
0xff
;
cput
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block2
:
// block
value
&=
0xffff
;
WPUT
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block4
:
// block
value
&=
0xffffffff
;
LPUT
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block
:
// block
uleb128put
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_data1
:
// constant
cput
(
value
);
break
;
case
DW_FORM_data2
:
// constant
WPUT
(
value
);
break
;
case
DW_FORM_data4
:
// constant, lineptr, loclistptr, macptr, rangelistptr
LPUT
(
value
);
break
;
case
DW_FORM_data8
:
// constant, lineptr, loclistptr, macptr, rangelistptr
VPUT
(
value
);
break
;
case
DW_FORM_sdata
:
// constant
sleb128put
(
value
);
break
;
case
DW_FORM_udata
:
// constant
uleb128put
(
value
);
break
;
case
DW_FORM_string
:
// string
strnput
(
data
,
value
+
1
);
break
;
case
DW_FORM_flag
:
// flag
cput
(
value
?
1
:
0
);
break
;
case
DW_FORM_strp
:
// string
case
DW_FORM_ref_addr
:
// reference
case
DW_FORM_ref1
:
// reference
case
DW_FORM_ref2
:
// reference
case
DW_FORM_ref4
:
// reference
case
DW_FORM_ref8
:
// reference
case
DW_FORM_ref_udata
:
// reference
case
DW_FORM_indirect
:
// (see Section 7.5.3)
default:
diag
(
"Unsupported atribute form %d / class %d"
,
form
,
cls
);
errorexit
();
}
switch
(
form
)
{
case
DW_FORM_addr
:
// address
addrput
(
value
);
break
;
case
DW_FORM_block1
:
// block
value
&=
0xff
;
cput
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block2
:
// block
value
&=
0xffff
;
WPUT
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block4
:
// block
value
&=
0xffffffff
;
LPUT
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_block
:
// block
uleb128put
(
value
);
while
(
value
--
)
cput
(
*
data
++
);
break
;
case
DW_FORM_data1
:
// constant
cput
(
value
);
break
;
case
DW_FORM_data2
:
// constant
WPUT
(
value
);
break
;
case
DW_FORM_data4
:
// constant, lineptr, loclistptr, macptr, rangelistptr
LPUT
(
value
);
break
;
case
DW_FORM_data8
:
// constant, lineptr, loclistptr, macptr, rangelistptr
VPUT
(
value
);
break
;
case
DW_FORM_sdata
:
// constant
sleb128put
(
value
);
break
;
case
DW_FORM_udata
:
// constant
uleb128put
(
value
);
break
;
case
DW_FORM_string
:
// string
strnput
(
data
,
value
+
1
);
break
;
case
DW_FORM_flag
:
// flag
cput
(
value
?
1
:
0
);
break
;
case
DW_FORM_strp
:
// string
case
DW_FORM_ref_addr
:
// reference
case
DW_FORM_ref1
:
// reference
case
DW_FORM_ref2
:
// reference
case
DW_FORM_ref4
:
// reference
case
DW_FORM_ref8
:
// reference
case
DW_FORM_ref_udata
:
// reference
case
DW_FORM_indirect
:
// (see Section 7.5.3)
default:
diag
(
"Unsupported atribute form %d / class %d"
,
form
,
cls
);
errorexit
();
}
}
static
void
putattrs
(
int
abbrev
,
DWAttr
*
attr
)
{
DWAttr
*
attrs
[
DW_AT_recursive
+
1
];
DWAttrForm
*
af
;
memset
(
attrs
,
0
,
sizeof
attrs
);
for
(
;
attr
;
attr
=
attr
->
link
)
attrs
[
attr
->
atr
]
=
attr
;
for
(
af
=
abbrevs
[
abbrev
].
attr
;
af
->
attr
;
af
++
)
if
(
attrs
[
af
->
attr
])
putattr
(
af
->
form
,
attrs
[
af
->
attr
]
->
cls
,
attrs
[
af
->
attr
]
->
value
,
attrs
[
af
->
attr
]
->
data
);
else
putattr
(
af
->
form
,
0
,
0
,
0
);
DWAttr
*
attrs
[
DW_AT_recursive
+
1
];
DWAttrForm
*
af
;
memset
(
attrs
,
0
,
sizeof
attrs
);
for
(
;
attr
;
attr
=
attr
->
link
)
attrs
[
attr
->
atr
]
=
attr
;
for
(
af
=
abbrevs
[
abbrev
].
attr
;
af
->
attr
;
af
++
)
if
(
attrs
[
af
->
attr
])
putattr
(
af
->
form
,
attrs
[
af
->
attr
]
->
cls
,
attrs
[
af
->
attr
]
->
value
,
attrs
[
af
->
attr
]
->
data
);
else
putattr
(
af
->
form
,
0
,
0
,
0
);
}
static
void
putdie
(
DWDie
*
die
);
...
...
@@ -249,35 +270,46 @@ static void putdie(DWDie* die);
static
void
putdies
(
DWDie
*
die
)
{
for
(;
die
;
die
=
die
->
link
)
putdie
(
die
);
for
(;
die
;
die
=
die
->
link
)
putdie
(
die
);
}
static
void
putdie
(
DWDie
*
die
)
{
uleb128put
(
die
->
abbrev
);
putattrs
(
die
->
abbrev
,
die
->
attr
);
if
(
abbrevs
[
die
->
abbrev
].
children
)
{
putdies
(
die
->
child
);
cput
(
0
);
}
uleb128put
(
die
->
abbrev
);
putattrs
(
die
->
abbrev
,
die
->
attr
);
if
(
abbrevs
[
die
->
abbrev
].
children
)
{
putdies
(
die
->
child
);
cput
(
0
);
}
}
static
void
reverselist
(
DWDie
**
list
)
{
DWDie
*
curr
,
*
prev
;
curr
=
*
list
;
prev
=
0
;
while
(
curr
)
{
DWDie
*
next
=
curr
->
link
;
curr
->
link
=
prev
;
prev
=
curr
;
curr
=
next
;
}
*
list
=
prev
;
DWDie
*
curr
,
*
prev
;
curr
=
*
list
;
prev
=
0
;
while
(
curr
)
{
DWDie
*
next
=
curr
->
link
;
curr
->
link
=
prev
;
prev
=
curr
;
curr
=
next
;
}
*
list
=
prev
;
}
static
void
reversetree
(
DWDie
**
list
)
{
DWDie
*
die
;
reverselist
(
list
);
if
(
*
list
!=
nil
&&
abbrevs
[(
*
list
)
->
abbrev
].
children
)
for
(
die
=
*
list
;
die
!=
nil
;
die
=
die
->
link
)
reversetree
(
&
die
->
child
);
}
/*
...
...
@@ -290,7 +322,7 @@ static int ftabsize;
void
dwarfaddfrag
(
int
n
,
char
*
frag
)
{
int
s
;
int
s
;
if
(
n
>=
ftabsize
)
{
s
=
ftabsize
;
...
...
@@ -308,19 +340,19 @@ dwarfaddfrag(int n, char *frag)
static
char
*
decodez
(
char
*
s
)
{
int
len
,
o
;
char
*
ss
,
*
f
;
char
*
r
,
*
rb
,
*
re
;
int
len
,
o
;
char
*
ss
,
*
f
;
char
*
r
,
*
rb
,
*
re
;
len
=
0
;
ss
=
s
+
1
;
// first is 0
while
((
o
=
((
uint8
)
ss
[
0
]
<<
8
)
|
(
uint8
)
ss
[
1
])
!=
0
)
{
while
((
o
=
((
uint8
)
ss
[
0
]
<<
8
)
|
(
uint8
)
ss
[
1
])
!=
0
)
{
if
(
o
<
0
||
o
>=
ftabsize
)
{
diag
(
"corrupt z entry"
);
return
0
;
}
f
=
ftab
[
o
];
if
(
!
f
)
{
if
(
f
==
nil
)
{
diag
(
"corrupt z entry"
);
return
0
;
}
...
...
@@ -351,60 +383,60 @@ decodez(char *s)
* The line history itself
*/
static
char
**
histfile
;
// [0] holds the empty string.
static
char
**
histfile
;
// [0] holds the empty string.
static
int
histfilesize
;
static
int
histfilecap
;
static
void
clearhistfile
(
void
)
{
int
i
;
int
i
;
// [0] holds the empty string.
for
(
i
=
1
;
i
<
histfilesize
;
i
++
)
free
(
histfile
[
i
]);
histfilesize
=
0
;
// [0] holds the empty string.
for
(
i
=
1
;
i
<
histfilesize
;
i
++
)
free
(
histfile
[
i
]);
histfilesize
=
0
;
}
static
int
addhistfile
(
char
*
zentry
)
{
char
*
fname
;
if
(
histfilesize
==
histfilecap
)
{
histfilecap
=
2
*
histfilecap
+
2
;
histfile
=
realloc
(
histfile
,
histfilecap
*
sizeof
(
char
*
));
}
if
(
histfilesize
==
0
)
histfile
[
histfilesize
++
]
=
"<eof>"
;
fname
=
decodez
(
zentry
);
if
(
fname
==
0
)
return
-
1
;
// Don't fill with duplicates (check only top one).
if
(
strcmp
(
fname
,
histfile
[
histfilesize
-
1
])
==
0
)
{
free
(
fname
);
return
histfilesize
-
1
;
}
histfile
[
histfilesize
++
]
=
fname
;
return
histfilesize
-
1
;
char
*
fname
;
if
(
histfilesize
==
histfilecap
)
{
histfilecap
=
2
*
histfilecap
+
2
;
histfile
=
realloc
(
histfile
,
histfilecap
*
sizeof
(
char
*
));
}
if
(
histfilesize
==
0
)
histfile
[
histfilesize
++
]
=
"<eof>"
;
fname
=
decodez
(
zentry
);
if
(
fname
==
0
)
return
-
1
;
// Don't fill with duplicates (check only top one).
if
(
strcmp
(
fname
,
histfile
[
histfilesize
-
1
])
==
0
)
{
free
(
fname
);
return
histfilesize
-
1
;
}
histfile
[
histfilesize
++
]
=
fname
;
return
histfilesize
-
1
;
}
// Go's runtime C sources are sane, and Go sources nest only 1 level,
// so 16 should be plenty.
static
struct
{
int
file
;
vlong
line
;
int
file
;
vlong
line
;
}
includestack
[
16
];
static
int
includetop
;
static
vlong
absline
;
typedef
struct
Linehist
Linehist
;
struct
Linehist
{
Linehist
*
link
;
vlong
absline
;
vlong
line
;
int
file
;
Linehist
*
link
;
vlong
absline
;
vlong
line
;
int
file
;
};
static
Linehist
*
linehist
;
...
...
@@ -412,101 +444,101 @@ static Linehist *linehist;
static
void
checknesting
(
void
)
{
int
i
;
if
(
includetop
<
0
)
{
diag
(
"corrupt z stack"
);
errorexit
();
}
if
(
includetop
>=
nelem
(
includestack
))
{
diag
(
"nesting too deep"
);
for
(
i
=
0
;
i
<
nelem
(
includestack
);
i
++
)
diag
(
"
\t
%s"
,
histfile
[
includestack
[
i
].
file
]);
errorexit
();
}
int
i
;
if
(
includetop
<
0
)
{
diag
(
"corrupt z stack"
);
errorexit
();
}
if
(
includetop
>=
nelem
(
includestack
))
{
diag
(
"nesting too deep"
);
for
(
i
=
0
;
i
<
nelem
(
includestack
);
i
++
)
diag
(
"
\t
%s"
,
histfile
[
includestack
[
i
].
file
]);
errorexit
();
}
}
/* find z and Z entries in the Auto list (of a Prog), and reset the history stack */
static
char
*
inithist
(
Auto
*
a
)
{
char
*
unitname
;
Linehist
*
lh
;
char
*
unitname
;
Linehist
*
lh
;
for
(;
a
;
a
=
a
->
link
)
if
(
a
->
type
==
D_FILE
)
break
;
if
(
a
==
nil
)
return
0
;
// We have a new history. They are guaranteed to come completely
// at the beginning of the compilation unit.
if
(
a
->
aoffset
!=
1
)
{
diag
(
"stray 'z' with offset %d"
,
a
->
aoffset
);
return
0
;
}
unitname
=
decodez
(
a
->
asym
->
name
);
// Clear the history.
clearhistfile
();
includetop
=
0
;
includestack
[
includetop
].
file
=
0
;
includestack
[
includetop
].
line
=
-
1
;
absline
=
0
;
while
(
linehist
!=
nil
)
{
lh
=
linehist
->
link
;
free
(
linehist
);
linehist
=
lh
;
}
// Construct the new one.
for
(;
a
;
a
=
a
->
link
)
{
if
(
a
->
type
==
D_FILE
)
{
// 'z'
int
f
=
addhistfile
(
a
->
asym
->
name
);
if
(
f
<
0
)
{
// pop file
includetop
--
;
checknesting
();
}
else
if
(
f
!=
includestack
[
includetop
].
file
)
{
// pushed a new file
includestack
[
includetop
].
line
+=
a
->
aoffset
-
absline
;
includetop
++
;
checknesting
();
includestack
[
includetop
].
file
=
f
;
includestack
[
includetop
].
line
=
1
;
}
absline
=
a
->
aoffset
;
}
else
if
(
a
->
type
==
D_FILE1
)
{
// 'Z'
// We could just fixup the current
// linehist->line, but there doesn't appear to
// be a guarantee that every 'Z' is preceded
// by it's own 'z', so do the safe thing and
// update the stack and push a new Linehist
// entry
includestack
[
includetop
].
line
=
a
->
aoffset
;
}
else
continue
;
if
(
linehist
==
0
||
linehist
->
absline
!=
absline
)
{
Linehist
*
lh
=
malloc
(
sizeof
*
lh
);
lh
->
link
=
linehist
;
lh
->
absline
=
absline
;
linehist
=
lh
;
}
linehist
->
file
=
includestack
[
includetop
].
file
;
linehist
->
line
=
includestack
[
includetop
].
line
;
}
return
unitname
;
break
;
if
(
a
==
nil
)
return
0
;
// We have a new history. They are guaranteed to come completely
// at the beginning of the compilation unit.
if
(
a
->
aoffset
!=
1
)
{
diag
(
"stray 'z' with offset %d"
,
a
->
aoffset
);
return
0
;
}
unitname
=
decodez
(
a
->
asym
->
name
);
// Clear the history.
clearhistfile
();
includetop
=
0
;
includestack
[
includetop
].
file
=
0
;
includestack
[
includetop
].
line
=
-
1
;
absline
=
0
;
while
(
linehist
!=
nil
)
{
lh
=
linehist
->
link
;
free
(
linehist
);
linehist
=
lh
;
}
// Construct the new one.
for
(;
a
;
a
=
a
->
link
)
{
if
(
a
->
type
==
D_FILE
)
{
// 'z'
int
f
=
addhistfile
(
a
->
asym
->
name
);
if
(
f
<
0
)
{
// pop file
includetop
--
;
checknesting
();
}
else
if
(
f
!=
includestack
[
includetop
].
file
)
{
// pushed a new file
includestack
[
includetop
].
line
+=
a
->
aoffset
-
absline
;
includetop
++
;
checknesting
();
includestack
[
includetop
].
file
=
f
;
includestack
[
includetop
].
line
=
1
;
}
absline
=
a
->
aoffset
;
}
else
if
(
a
->
type
==
D_FILE1
)
{
// 'Z'
// We could just fixup the current
// linehist->line, but there doesn't appear to
// be a guarantee that every 'Z' is preceded
// by it's own 'z', so do the safe thing and
// update the stack and push a new Linehist
// entry
includestack
[
includetop
].
line
=
a
->
aoffset
;
}
else
continue
;
if
(
linehist
==
0
||
linehist
->
absline
!=
absline
)
{
Linehist
*
lh
=
malloc
(
sizeof
*
lh
);
lh
->
link
=
linehist
;
lh
->
absline
=
absline
;
linehist
=
lh
;
}
linehist
->
file
=
includestack
[
includetop
].
file
;
linehist
->
line
=
includestack
[
includetop
].
line
;
}
return
unitname
;
}
static
Linehist
*
searchhist
(
vlong
absline
)
{
Linehist
*
lh
;
Linehist
*
lh
;
for
(
lh
=
linehist
;
lh
;
lh
=
lh
->
link
)
if
(
lh
->
absline
<=
absline
)
break
;
return
lh
;
for
(
lh
=
linehist
;
lh
;
lh
=
lh
->
link
)
if
(
lh
->
absline
<=
absline
)
break
;
return
lh
;
}
static
void
...
...
@@ -516,7 +548,7 @@ writeabbrev(void)
abbrevo
=
cpos
();
for
(
i
=
1
;
i
<
DW_NABRV
;
i
++
)
{
// See section 7.5.3
// See section 7.5.3
uleb128put
(
i
);
uleb128put
(
abbrevs
[
i
].
tag
);
cput
(
abbrevs
[
i
].
children
);
...
...
@@ -526,7 +558,7 @@ writeabbrev(void)
strnput
((
char
*
)
abbrevs
[
i
].
attr
,
(
n
+
1
)
*
sizeof
(
DWAttrForm
));
}
cput
(
0
);
cput
(
0
);
abbrevsize
=
cpos
()
-
abbrevo
;
}
...
...
@@ -534,10 +566,10 @@ writeabbrev(void)
static
int
guesslang
(
char
*
s
)
{
if
(
strlen
(
s
)
>=
3
&&
strcmp
(
s
+
strlen
(
s
)
-
3
,
".go"
)
==
0
)
return
DW_LANG_Go
;
if
(
strlen
(
s
)
>=
3
&&
strcmp
(
s
+
strlen
(
s
)
-
3
,
".go"
)
==
0
)
return
DW_LANG_Go
;
return
DW_LANG_C
;
return
DW_LANG_C
;
}
/*
...
...
@@ -546,30 +578,30 @@ guesslang(char *s)
*/
enum
{
LINE_BASE
=
-
1
,
LINE_RANGE
=
4
,
OPCODE_BASE
=
5
LINE_BASE
=
-
1
,
LINE_RANGE
=
4
,
OPCODE_BASE
=
5
};
static
void
putpclcdelta
(
vlong
delta_pc
,
vlong
delta_lc
)
{
if
(
LINE_BASE
<=
delta_lc
&&
delta_lc
<
LINE_BASE
+
LINE_RANGE
)
{
vlong
opcode
=
OPCODE_BASE
+
(
delta_lc
-
LINE_BASE
)
+
(
LINE_RANGE
*
delta_pc
);
if
(
OPCODE_BASE
<=
opcode
&&
opcode
<
256
)
{
cput
(
opcode
);
return
;
}
}
if
(
delta_pc
)
{
cput
(
DW_LNS_advance_pc
);
sleb128put
(
delta_pc
);
}
cput
(
DW_LNS_advance_line
);
sleb128put
(
delta_lc
);
cput
(
DW_LNS_copy
);
if
(
LINE_BASE
<=
delta_lc
&&
delta_lc
<
LINE_BASE
+
LINE_RANGE
)
{
vlong
opcode
=
OPCODE_BASE
+
(
delta_lc
-
LINE_BASE
)
+
(
LINE_RANGE
*
delta_pc
);
if
(
OPCODE_BASE
<=
opcode
&&
opcode
<
256
)
{
cput
(
opcode
);
return
;
}
}
if
(
delta_pc
)
{
cput
(
DW_LNS_advance_pc
);
sleb128put
(
delta_pc
);
}
cput
(
DW_LNS_advance_line
);
sleb128put
(
delta_lc
);
cput
(
DW_LNS_copy
);
}
...
...
@@ -581,132 +613,143 @@ putpclcdelta(vlong delta_pc, vlong delta_lc)
static
void
flushunit
(
vlong
pc
,
vlong
unitstart
)
{
vlong
here
;
if
(
dwinfo
!=
0
&&
pc
!=
0
)
{
newattr
(
dwinfo
,
DW_AT_high_pc
,
DW_CLS_ADDRESS
,
pc
,
0
);
}
if
(
unitstart
>=
0
)
{
cput
(
0
);
// start extended opcode
uleb128put
(
1
);
cput
(
DW_LNE_end_sequence
);
cflush
();
here
=
cpos
();
seek
(
cout
,
unitstart
,
0
);
LPUT
(
here
-
unitstart
-
sizeof
(
int32
));
cflush
();
seek
(
cout
,
here
,
0
);
}
vlong
here
;
if
(
dwinfo
!=
0
&&
pc
!=
0
)
{
newattr
(
dwinfo
,
DW_AT_high_pc
,
DW_CLS_ADDRESS
,
pc
,
0
);
}
if
(
unitstart
>=
0
)
{
cput
(
0
);
// start extended opcode
uleb128put
(
1
);
cput
(
DW_LNE_end_sequence
);
cflush
();
here
=
cpos
();
seek
(
cout
,
unitstart
,
0
);
LPUT
(
here
-
unitstart
-
sizeof
(
int32
));
cflush
();
seek
(
cout
,
here
,
0
);
}
}
static
void
writelines
(
void
)
{
Prog
*
p
,
*
q
;
Sym
*
s
;
char
*
unitname
;
vlong
unitstart
;
vlong
pc
,
lc
,
llc
,
lline
;
int
currfile
;
int
i
;
Linehist
*
lh
;
unitstart
=
-
1
;
pc
=
0
;
lc
=
1
;
llc
=
1
;
currfile
=
-
1
;
lineo
=
cpos
();
for
(
p
=
textp
;
p
!=
P
;
p
=
p
->
pcond
)
{
Prog
*
p
,
*
q
;
Sym
*
s
;
char
*
unitname
;
vlong
unitstart
;
vlong
pc
,
lc
,
llc
,
lline
;
int
currfile
;
int
i
;
Linehist
*
lh
;
unitstart
=
-
1
;
pc
=
0
;
lc
=
1
;
llc
=
1
;
currfile
=
-
1
;
lineo
=
cpos
();
for
(
p
=
textp
;
p
!=
P
;
p
=
p
->
pcond
)
{
s
=
p
->
from
.
sym
;
if
(
s
==
nil
||
s
->
type
!=
STEXT
)
{
diag
(
"->pcond was supposed to loop over STEXT: %P"
,
p
);
continue
;
}
// Look for history stack. If we find one,
// we're entering a new compilation unit
if
((
unitname
=
inithist
(
p
->
to
.
autom
))
!=
0
)
{
flushunit
(
pc
,
unitstart
);
unitstart
=
cpos
();
if
(
debug
[
'v'
]
>
1
)
{
print
(
"dwarf writelines found %s
\n
"
,
unitname
);
Linehist
*
lh
;
for
(
lh
=
linehist
;
lh
;
lh
=
lh
->
link
)
print
(
"
\t
%8lld: [%4lld]%s
\n
"
,
lh
->
absline
,
lh
->
line
,
histfile
[
lh
->
file
]);
}
dwinfo
=
newdie
(
dwinfo
,
DW_ABRV_COMPUNIT
);
newattr
(
dwinfo
,
DW_AT_name
,
DW_CLS_STRING
,
strlen
(
unitname
),
unitname
);
newattr
(
dwinfo
,
DW_AT_language
,
DW_CLS_CONSTANT
,
guesslang
(
unitname
),
0
);
newattr
(
dwinfo
,
DW_AT_stmt_list
,
DW_CLS_PTR
,
unitstart
-
lineo
,
0
);
newattr
(
dwinfo
,
DW_AT_low_pc
,
DW_CLS_ADDRESS
,
p
->
pc
,
0
);
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
LPUT
(
0
);
// unit_length (*), will be filled in later.
WPUT
(
3
);
// version
LPUT
(
11
);
// header_length (*)
cput
(
1
);
// minimum_instruction_length
cput
(
1
);
// default_is_stmt
cput
(
LINE_BASE
);
// line_base
cput
(
LINE_RANGE
);
// line_range
cput
(
OPCODE_BASE
);
// opcode_base (we only use 1..4)
cput
(
0
);
// standard_opcode_lengths[1]
cput
(
1
);
// standard_opcode_lengths[2]
cput
(
1
);
// standard_opcode_lengths[3]
cput
(
1
);
// standard_opcode_lengths[4]
cput
(
0
);
// include_directories (empty)
cput
(
0
);
// file_names (empty) (emitted by DW_LNE's below)
for
(
i
=
1
;
i
<
histfilesize
;
i
++
)
{
cput
(
0
);
// start extended opcode
uleb128put
(
1
+
strlen
(
histfile
[
i
])
+
4
);
cput
(
DW_LNE_define_file
);
strnput
(
histfile
[
i
],
strlen
(
histfile
[
i
])
+
4
);
// 4 zeros: the string termination + 3 fields.
}
pc
=
p
->
pc
;
currfile
=
1
;
lc
=
1
;
llc
=
1
;
cput
(
0
);
// start extended opcode
uleb128put
(
1
+
sizeof
pc
);
cput
(
DW_LNE_set_address
);
VPUT
(
pc
);
}
if
(
!
p
->
from
.
sym
->
reachable
)
continue
;
if
(
unitstart
<
0
)
{
diag
(
"Reachable code before seeing any history: %P"
,
p
);
continue
;
}
for
(
q
=
p
;
q
!=
P
&&
(
q
==
p
||
q
->
as
!=
ATEXT
);
q
=
q
->
link
)
{
lh
=
searchhist
(
q
->
line
);
if
(
!
lh
)
{
diag
(
"corrupt history or bad absolute line: %P"
,
q
);
continue
;
}
lline
=
lh
->
line
+
q
->
line
-
lh
->
absline
;
if
(
debug
[
'v'
]
>
1
)
print
(
"%6llux %s[%lld] %P
\n
"
,
q
->
pc
,
histfile
[
lh
->
file
],
lline
,
q
);
// Only emit a line program statement if line has changed.
if
(
q
->
line
==
lc
)
continue
;
if
(
currfile
!=
lh
->
file
)
{
currfile
=
lh
->
file
;
cput
(
DW_LNS_set_file
);
uleb128put
(
currfile
);
}
putpclcdelta
(
q
->
pc
-
pc
,
lline
-
llc
);
pc
=
q
->
pc
;
lc
=
q
->
line
;
llc
=
lline
;
}
}
flushunit
(
pc
,
unitstart
);
linesize
=
cpos
()
-
lineo
;
diag
(
"->pcond was supposed to loop over STEXT: %P"
,
p
);
continue
;
}
// Look for history stack. If we find one,
// we're entering a new compilation unit
if
((
unitname
=
inithist
(
p
->
to
.
autom
))
!=
0
)
{
flushunit
(
pc
,
unitstart
);
unitstart
=
cpos
();
if
(
debug
[
'v'
]
>
1
)
{
print
(
"dwarf writelines found %s
\n
"
,
unitname
);
Linehist
*
lh
;
for
(
lh
=
linehist
;
lh
;
lh
=
lh
->
link
)
print
(
"
\t
%8lld: [%4lld]%s
\n
"
,
lh
->
absline
,
lh
->
line
,
histfile
[
lh
->
file
]);
}
dwinfo
=
newdie
(
dwinfo
,
DW_ABRV_COMPUNIT
);
newattr
(
dwinfo
,
DW_AT_name
,
DW_CLS_STRING
,
strlen
(
unitname
),
unitname
);
newattr
(
dwinfo
,
DW_AT_language
,
DW_CLS_CONSTANT
,
guesslang
(
unitname
),
0
);
newattr
(
dwinfo
,
DW_AT_stmt_list
,
DW_CLS_PTR
,
unitstart
-
lineo
,
0
);
newattr
(
dwinfo
,
DW_AT_low_pc
,
DW_CLS_ADDRESS
,
p
->
pc
,
0
);
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
LPUT
(
0
);
// unit_length (*), will be filled in later.
WPUT
(
3
);
// version
LPUT
(
11
);
// header_length (*)
cput
(
1
);
// minimum_instruction_length
cput
(
1
);
// default_is_stmt
cput
(
LINE_BASE
);
// line_base
cput
(
LINE_RANGE
);
// line_range
cput
(
OPCODE_BASE
);
// opcode_base (we only use 1..4)
cput
(
0
);
// standard_opcode_lengths[1]
cput
(
1
);
// standard_opcode_lengths[2]
cput
(
1
);
// standard_opcode_lengths[3]
cput
(
1
);
// standard_opcode_lengths[4]
cput
(
0
);
// include_directories (empty)
cput
(
0
);
// file_names (empty) (emitted by DW_LNE's below)
for
(
i
=
1
;
i
<
histfilesize
;
i
++
)
{
cput
(
0
);
// start extended opcode
uleb128put
(
1
+
strlen
(
histfile
[
i
])
+
4
);
cput
(
DW_LNE_define_file
);
strnput
(
histfile
[
i
],
strlen
(
histfile
[
i
])
+
4
);
// 4 zeros: the string termination + 3 fields.
}
pc
=
p
->
pc
;
currfile
=
1
;
lc
=
1
;
llc
=
1
;
cput
(
0
);
// start extended opcode
uleb128put
(
1
+
PtrSize
);
cput
(
DW_LNE_set_address
);
addrput
(
pc
);
}
if
(
!
p
->
from
.
sym
->
reachable
)
continue
;
if
(
unitstart
<
0
)
{
diag
(
"reachable code before seeing any history: %P"
,
p
);
continue
;
}
dwinfo
->
child
=
newdie
(
dwinfo
->
child
,
DW_ABRV_FUNCTION
);
newattr
(
dwinfo
->
child
,
DW_AT_name
,
DW_CLS_STRING
,
strlen
(
s
->
name
),
s
->
name
);
newattr
(
dwinfo
->
child
,
DW_AT_low_pc
,
DW_CLS_ADDRESS
,
p
->
pc
,
0
);
if
(
debug
[
'v'
]
>
1
)
print
(
"frame offset: %d
\n
"
,
p
->
to
.
offset
);
// newattr(dwinfo->child, DW_AT_return_addr, DW_CLS_BLOCK, p->to.offset, 0);
for
(
q
=
p
;
q
!=
P
&&
(
q
==
p
||
q
->
as
!=
ATEXT
);
q
=
q
->
link
)
{
lh
=
searchhist
(
q
->
line
);
if
(
lh
==
nil
)
{
diag
(
"corrupt history or bad absolute line: %P"
,
q
);
continue
;
}
lline
=
lh
->
line
+
q
->
line
-
lh
->
absline
;
if
(
debug
[
'v'
]
>
1
)
print
(
"%6llux %s[%lld] %P
\n
"
,
q
->
pc
,
histfile
[
lh
->
file
],
lline
,
q
);
// Only emit a line program statement if line has changed.
if
(
q
->
line
==
lc
)
continue
;
if
(
currfile
!=
lh
->
file
)
{
currfile
=
lh
->
file
;
cput
(
DW_LNS_set_file
);
uleb128put
(
currfile
);
}
putpclcdelta
(
q
->
pc
-
pc
,
lline
-
llc
);
pc
=
q
->
pc
;
lc
=
q
->
line
;
llc
=
lline
;
}
newattr
(
dwinfo
->
child
,
DW_AT_high_pc
,
DW_CLS_ADDRESS
,
pc
,
0
);
}
flushunit
(
pc
,
unitstart
);
linesize
=
cpos
()
-
lineo
;
}
/*
...
...
@@ -715,41 +758,42 @@ writelines(void)
static
void
writeinfo
(
void
)
{
DWDie
*
compunit
;
vlong
unitstart
;
DWDie
*
compunit
;
vlong
unitstart
;
reverselist
(
&
dwinfo
);
reversetree
(
&
dwinfo
);
infoo
=
cpos
();
infoo
=
cpos
();
for
(
compunit
=
dwinfo
;
compunit
;
compunit
=
compunit
->
link
)
{
unitstart
=
cpos
();
for
(
compunit
=
dwinfo
;
compunit
;
compunit
=
compunit
->
link
)
{
unitstart
=
cpos
();
// Write .debug_info Compilation Unit Header (sec 7.5.1)
// Fields marked with (*) must be changed for 64-bit dwarf
LPUT
(
0
);
// unit_length (*), will be filled in later.
WPUT
(
3
);
// version
LPUT
(
0
);
// debug_abbrev_offset (*)
cput
(
8
);
// address_size
// Write .debug_info Compilation Unit Header (sec 7.5.1)
// Fields marked with (*) must be changed for 64-bit dwarf
LPUT
(
0
);
// unit_length (*), will be filled in later.
WPUT
(
3
);
// version
LPUT
(
0
);
// debug_abbrev_offset (*)
cput
(
PtrSize
);
// address_size
putdie
(
compunit
);
putdie
(
compunit
);
cflush
();
vlong
here
=
cpos
();
seek
(
cout
,
unitstart
,
0
);
LPUT
(
here
-
unitstart
-
sizeof
(
int32
));
cflush
();
seek
(
cout
,
here
,
0
);
}
cflush
();
vlong
here
=
cpos
();
seek
(
cout
,
unitstart
,
0
);
LPUT
(
here
-
unitstart
-
sizeof
(
int32
));
cflush
();
seek
(
cout
,
here
,
0
);
}
cflush
();
infosize
=
cpos
()
-
infoo
;
cflush
();
infosize
=
cpos
()
-
infoo
;
}
/*
* Elf sections.
*/
enum
{
enum
{
ElfStrDebugAbbrev
,
ElfStrDebugAranges
,
ElfStrDebugFrame
,
...
...
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