Commit 032e5bfb authored by Jan Ziak's avatar Jan Ziak Committed by Russ Cox

ld: add .gcdata and .gcbss sections

R=rsc
CC=golang-dev
https://golang.org/cl/6281048
parent 9a82324f
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
This diff is collapsed.
// 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);
}
......@@ -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 {
......
......@@ -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*);
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment