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
e1821692
Commit
e1821692
authored
Jul 11, 2014
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/ld: add go-specific dwarf type information
LGTM=r R=r CC=golang-codereviews
https://golang.org/cl/116720043
parent
90c146f3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
47 deletions
+65
-47
src/cmd/ld/dwarf.c
src/cmd/ld/dwarf.c
+65
-47
No files found.
src/cmd/ld/dwarf.c
View file @
e1821692
...
...
@@ -141,16 +141,22 @@ sleb128put(vlong v)
* only a handful of them. The DWARF spec places no restriction on
* the ordering of attributes in the Abbrevs and DIEs, and we will
* always write them out in the order of declaration in the abbrev.
* This implementation relies on tag, attr < 127, so they serialize as
* a char. Higher numbered user-defined tags or attributes can be used
* for storing internal data but won't be serialized.
*/
typedef
struct
DWAttrForm
DWAttrForm
;
struct
DWAttrForm
{
uint
8
attr
;
uint
16
attr
;
uint8
form
;
};
// Go-specific type attributes.
enum
{
DW_AT_go_kind
=
0x2900
,
DW_AT_go_key
=
0x2901
,
DW_AT_go_elem
=
0x2902
,
DW_AT_internal_location
=
253
,
// params and locals; not emitted
};
// Index into the abbrevs table below.
// Keep in sync with ispubname() and ispubtype() below.
// ispubtype considers >= NULLTYPE public
...
...
@@ -277,6 +283,7 @@ static struct DWAbbrev {
DW_AT_name
,
DW_FORM_string
,
DW_AT_encoding
,
DW_FORM_data1
,
DW_AT_byte_size
,
DW_FORM_data1
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
/* ARRAYTYPE */
...
...
@@ -286,6 +293,7 @@ static struct DWAbbrev {
DW_AT_name
,
DW_FORM_string
,
DW_AT_type
,
DW_FORM_ref_addr
,
DW_AT_byte_size
,
DW_FORM_udata
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
...
...
@@ -294,6 +302,8 @@ static struct DWAbbrev {
DW_TAG_typedef
,
DW_CHILDREN_no
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_type
,
DW_FORM_ref_addr
,
DW_AT_go_kind
,
DW_FORM_data1
,
DW_AT_go_elem
,
DW_FORM_ref_addr
,
0
,
0
},
...
...
@@ -302,6 +312,7 @@ static struct DWAbbrev {
DW_TAG_subroutine_type
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
// DW_AT_type, DW_FORM_ref_addr,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
...
...
@@ -310,6 +321,7 @@ static struct DWAbbrev {
DW_TAG_typedef
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_type
,
DW_FORM_ref_addr
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
...
...
@@ -318,6 +330,9 @@ static struct DWAbbrev {
DW_TAG_typedef
,
DW_CHILDREN_no
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_type
,
DW_FORM_ref_addr
,
DW_AT_go_kind
,
DW_FORM_data1
,
DW_AT_go_key
,
DW_FORM_ref_addr
,
DW_AT_go_elem
,
DW_FORM_ref_addr
,
0
,
0
},
...
...
@@ -326,6 +341,7 @@ static struct DWAbbrev {
DW_TAG_pointer_type
,
DW_CHILDREN_no
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_type
,
DW_FORM_ref_addr
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
/* BARE_PTRTYPE */
...
...
@@ -340,6 +356,8 @@ static struct DWAbbrev {
DW_TAG_structure_type
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_byte_size
,
DW_FORM_udata
,
DW_AT_go_kind
,
DW_FORM_data1
,
DW_AT_go_elem
,
DW_FORM_ref_addr
,
0
,
0
},
...
...
@@ -348,6 +366,7 @@ static struct DWAbbrev {
DW_TAG_structure_type
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_byte_size
,
DW_FORM_udata
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
...
...
@@ -356,6 +375,7 @@ static struct DWAbbrev {
DW_TAG_structure_type
,
DW_CHILDREN_yes
,
DW_AT_name
,
DW_FORM_string
,
DW_AT_byte_size
,
DW_FORM_udata
,
DW_AT_go_kind
,
DW_FORM_data1
,
0
,
0
},
...
...
@@ -371,7 +391,8 @@ static struct DWAbbrev {
static
void
writeabbrev
(
void
)
{
int
i
,
n
;
int
i
,
j
;
DWAttrForm
*
f
;
abbrevo
=
cpos
();
for
(
i
=
1
;
i
<
DW_NABRV
;
i
++
)
{
...
...
@@ -379,11 +400,13 @@ writeabbrev(void)
uleb128put
(
i
);
uleb128put
(
abbrevs
[
i
].
tag
);
cput
(
abbrevs
[
i
].
children
);
// 0 is not a valid attr or form, and DWAbbrev.attr is
// 0-terminated, so we can treat it as a string
n
=
strlen
((
char
*
)
abbrevs
[
i
].
attr
)
/
2
;
strnput
((
char
*
)
abbrevs
[
i
].
attr
,
(
n
+
1
)
*
sizeof
(
DWAttrForm
));
for
(
j
=
0
;
j
<
nelem
(
abbrevs
[
i
].
attr
);
j
++
)
{
f
=
&
abbrevs
[
i
].
attr
[
j
];
uleb128put
(
f
->
attr
);
uleb128put
(
f
->
form
);
if
(
f
->
attr
==
0
)
break
;
}
}
cput
(
0
);
abbrevsize
=
cpos
()
-
abbrevo
;
...
...
@@ -417,7 +440,7 @@ hashstr(char* s)
typedef
struct
DWAttr
DWAttr
;
struct
DWAttr
{
DWAttr
*
link
;
uint
8
atr
;
// DW_AT_
uint
16
atr
;
// DW_AT_
uint8
cls
;
// DW_CLS_
vlong
value
;
char
*
data
;
...
...
@@ -445,7 +468,7 @@ static DWDie dwtypes;
static
DWDie
dwglobals
;
static
DWAttr
*
newattr
(
DWDie
*
die
,
uint
8
attr
,
int
cls
,
vlong
value
,
char
*
data
)
newattr
(
DWDie
*
die
,
uint
16
attr
,
int
cls
,
vlong
value
,
char
*
data
)
{
DWAttr
*
a
;
...
...
@@ -463,7 +486,7 @@ newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
// name. getattr moves the desired one to the front so
// frequently searched ones are found faster.
static
DWAttr
*
getattr
(
DWDie
*
die
,
uint
8
attr
)
getattr
(
DWDie
*
die
,
uint
16
attr
)
{
DWAttr
*
a
,
*
b
;
...
...
@@ -622,7 +645,7 @@ adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
}
static
DWAttr
*
newrefattr
(
DWDie
*
die
,
uint
8
attr
,
DWDie
*
ref
)
newrefattr
(
DWDie
*
die
,
uint
16
attr
,
DWDie
*
ref
)
{
if
(
ref
==
nil
)
return
nil
;
...
...
@@ -762,22 +785,22 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
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
)
if
(
attr
->
atr
<
nelem
(
attrs
))
attrs
[
attr
->
atr
]
=
attr
;
for
(
af
=
abbrevs
[
abbrev
].
attr
;
af
->
attr
;
af
++
)
if
(
attrs
[
af
->
attr
])
putattr
(
abbrev
,
af
->
form
,
attrs
[
af
->
attr
]
->
cls
,
attrs
[
af
->
attr
]
->
value
,
attrs
[
af
->
attr
]
->
data
);
else
putattr
(
abbrev
,
af
->
form
,
0
,
0
,
nil
);
DWAttr
*
ap
;
for
(
af
=
abbrevs
[
abbrev
].
attr
;
af
->
attr
;
af
++
)
{
for
(
ap
=
attr
;
ap
;
ap
=
ap
->
link
)
{
if
(
ap
->
atr
==
af
->
attr
)
{
putattr
(
abbrev
,
af
->
form
,
ap
->
cls
,
ap
->
value
,
ap
->
data
);
goto
done
;
}
}
putattr
(
abbrev
,
af
->
form
,
0
,
0
,
nil
);
done:
;
}
}
static
void
putdie
(
DWDie
*
die
);
...
...
@@ -849,15 +872,6 @@ newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
newattr
(
die
,
DW_AT_location
,
DW_CLS_ADDRESS
,
addr
,
(
char
*
)
sym
);
}
// Fake attributes for slices, maps and channel
enum
{
DW_AT_internal_elem_type
=
250
,
// channels and slices
DW_AT_internal_key_type
=
251
,
// maps
DW_AT_internal_val_type
=
252
,
// maps
DW_AT_internal_location
=
253
,
// params and locals
};
static
DWDie
*
defptrto
(
DWDie
*
dwtype
);
// below
// Lookup predefined types
...
...
@@ -986,7 +1000,7 @@ defgotype(LSym *gotype)
die
=
newdie
(
&
dwtypes
,
DW_ABRV_CHANTYPE
,
name
);
newattr
(
die
,
DW_AT_byte_size
,
DW_CLS_CONSTANT
,
bytesize
,
0
);
s
=
decodetype_chanelem
(
gotype
);
newrefattr
(
die
,
DW_AT_
internal_elem_type
,
defgotype
(
s
));
newrefattr
(
die
,
DW_AT_
go_elem
,
defgotype
(
s
));
break
;
case
KindFunc
:
...
...
@@ -1024,9 +1038,9 @@ defgotype(LSym *gotype)
case
KindMap
:
die
=
newdie
(
&
dwtypes
,
DW_ABRV_MAPTYPE
,
name
);
s
=
decodetype_mapkey
(
gotype
);
newrefattr
(
die
,
DW_AT_
internal_key_type
,
defgotype
(
s
));
newrefattr
(
die
,
DW_AT_
go_key
,
defgotype
(
s
));
s
=
decodetype_mapvalue
(
gotype
);
newrefattr
(
die
,
DW_AT_
internal_val_type
,
defgotype
(
s
));
newrefattr
(
die
,
DW_AT_
go_elem
,
defgotype
(
s
));
break
;
case
KindPtr
:
...
...
@@ -1041,7 +1055,7 @@ defgotype(LSym *gotype)
dotypedef
(
&
dwtypes
,
name
,
die
);
newattr
(
die
,
DW_AT_byte_size
,
DW_CLS_CONSTANT
,
bytesize
,
0
);
s
=
decodetype_arrayelem
(
gotype
);
newrefattr
(
die
,
DW_AT_
internal_elem_type
,
defgotype
(
s
));
newrefattr
(
die
,
DW_AT_
go_elem
,
defgotype
(
s
));
break
;
case
KindString
:
...
...
@@ -1073,7 +1087,9 @@ defgotype(LSym *gotype)
diag
(
"dwarf: definition of unknown kind %d: %s"
,
kind
,
gotype
->
name
);
die
=
newdie
(
&
dwtypes
,
DW_ABRV_TYPEDECL
,
name
);
newrefattr
(
die
,
DW_AT_type
,
find_or_diag
(
&
dwtypes
,
"<unspecified>"
));
}
}
newattr
(
die
,
DW_AT_go_kind
,
DW_CLS_CONSTANT
,
kind
,
0
);
return
die
;
}
...
...
@@ -1168,7 +1184,7 @@ synthesizeslicetypes(DWDie *die)
if
(
die
->
abbrev
!=
DW_ABRV_SLICETYPE
)
continue
;
copychildren
(
die
,
prototype
);
elem
=
(
DWDie
*
)
getattr
(
die
,
DW_AT_
internal_elem_type
)
->
data
;
elem
=
(
DWDie
*
)
getattr
(
die
,
DW_AT_
go_elem
)
->
data
;
substitutetype
(
die
,
"array"
,
defptrto
(
elem
));
}
}
...
...
@@ -1214,8 +1230,8 @@ synthesizemaptypes(DWDie *die)
if
(
die
->
abbrev
!=
DW_ABRV_MAPTYPE
)
continue
;
keytype
=
walktypedef
((
DWDie
*
)
getattr
(
die
,
DW_AT_
internal_key_type
)
->
data
);
valtype
=
walktypedef
((
DWDie
*
)
getattr
(
die
,
DW_AT_
internal_val_type
)
->
data
);
keytype
=
walktypedef
((
DWDie
*
)
getattr
(
die
,
DW_AT_
go_key
)
->
data
);
valtype
=
walktypedef
((
DWDie
*
)
getattr
(
die
,
DW_AT_
go_elem
)
->
data
);
// compute size info like hashmap.c does.
a
=
getattr
(
keytype
,
DW_AT_byte_size
);
...
...
@@ -1306,7 +1322,7 @@ synthesizechantypes(DWDie *die)
for
(;
die
!=
nil
;
die
=
die
->
link
)
{
if
(
die
->
abbrev
!=
DW_ABRV_CHANTYPE
)
continue
;
elemtype
=
(
DWDie
*
)
getattr
(
die
,
DW_AT_
internal_elem_type
)
->
data
;
elemtype
=
(
DWDie
*
)
getattr
(
die
,
DW_AT_
go_elem
)
->
data
;
a
=
getattr
(
elemtype
,
DW_AT_byte_size
);
elemsize
=
a
?
a
->
value
:
PtrSize
;
...
...
@@ -2025,9 +2041,11 @@ dwarfemitdebugsections(void)
newdie
(
&
dwtypes
,
DW_ABRV_NULLTYPE
,
"<unspecified>"
);
newdie
(
&
dwtypes
,
DW_ABRV_NULLTYPE
,
"void"
);
newdie
(
&
dwtypes
,
DW_ABRV_BARE_PTRTYPE
,
"unsafe.Pointer"
);
die
=
newdie
(
&
dwtypes
,
DW_ABRV_BASETYPE
,
"uintptr"
);
// needed for array size
newattr
(
die
,
DW_AT_encoding
,
DW_CLS_CONSTANT
,
DW_ATE_unsigned
,
0
);
newattr
(
die
,
DW_AT_byte_size
,
DW_CLS_CONSTANT
,
PtrSize
,
0
);
newattr
(
die
,
DW_AT_go_kind
,
DW_CLS_CONSTANT
,
KindUintptr
,
0
);
// Needed by the prettyprinter code for interface inspection.
defgotype
(
lookup_or_diag
(
"type.runtime.rtype"
));
...
...
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