Skip to content

Commit 44cf814

Browse files
Elias Naurrsc
Elias Naur
authored andcommitted
runtime, cmd/ld: make code more position-independent
Change the stack unwinding code to compensate for the dynamic relocation of symbols. Change the gc instruction GC_CALL to use a relative offset instead of an absolute address. R=golang-dev CC=golang-dev https://golang.org/cl/7248048
1 parent 11d16dc commit 44cf814

File tree

4 files changed

+6
-6
lines changed

4 files changed

+6
-6
lines changed

src/cmd/ld/data.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,6 @@ setuint64(Sym *s, vlong r, uint64 v)
748748
setuintxx(s, r, v, 8);
749749
}
750750

751-
/*
752751
static vlong
753752
addaddrpcrelplus(Sym *s, Sym *t, int32 add)
754753
{
@@ -769,7 +768,6 @@ addaddrpcrelplus(Sym *s, Sym *t, int32 add)
769768
r->add = add;
770769
return i;
771770
}
772-
*/
773771

774772
vlong
775773
addaddrplus(Sym *s, Sym *t, int32 add)
@@ -951,7 +949,7 @@ gcaddsym(Sym *gc, Sym *s, int32 off)
951949
//print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name);
952950
adduintxx(gc, GC_CALL, PtrSize);
953951
adduintxx(gc, off, PtrSize);
954-
addaddrplus(gc, decodetype_gc(gotype), 1*PtrSize);
952+
addaddrpcrelplus(gc, decodetype_gc(gotype), 4*PtrSize);
955953
} else {
956954
//print("gcaddsym: %s %d <unknown type>\n", s->name, s->size);
957955
for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) {

src/pkg/runtime/mgc0.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
663663
// Stack push.
664664
*stack_ptr-- = stack_top;
665665
stack_top = (Frame){1, 0, stack_top.b + pc[1], pc+3 /*return address*/};
666-
pc = (uintptr*)pc[2]; // target of the CALL instruction
666+
pc = (uintptr*)((byte*)pc + (uintptr)pc[2]); // target of the CALL instruction
667667
continue;
668668

669669
case GC_MAP_PTR:

src/pkg/runtime/mgc0.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// Meaning of arguments:
1313
// off Offset (in bytes) from the start of the current object
1414
// objgc Pointer to GC info of an object
15+
// objgcrel Offset to GC info of an object
1516
// len Length of an array
1617
// elemsize Size (in bytes) of an element
1718
// size Size (in bytes)
@@ -21,7 +22,7 @@ enum {
2122
GC_APTR, // Pointer to an arbitrary object. Args: (off)
2223
GC_ARRAY_START, // Start an array with a fixed length. Args: (off, len, elemsize)
2324
GC_ARRAY_NEXT, // The next element of an array. Args: none
24-
GC_CALL, // Call a subroutine. Args: (off, objgc)
25+
GC_CALL, // Call a subroutine. Args: (off, objgcrel)
2526
GC_MAP_PTR, // Go map. Args: (off, MapType*)
2627
GC_STRING, // Go string. Args: (off)
2728
GC_EFACE, // interface{}. Args: (off)

src/pkg/runtime/symtab.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ walksymtab(void (*fn)(Sym*))
9393

9494
static Func *func;
9595
static int32 nfunc;
96+
extern byte reloffset[];
9697

9798
static byte **fname;
9899
static int32 nfname;
@@ -118,7 +119,7 @@ dofunc(Sym *sym)
118119
}
119120
f = &func[nfunc++];
120121
f->name = runtime·gostringnocopy(sym->name);
121-
f->entry = sym->value;
122+
f->entry = sym->value + (uint64)reloffset;
122123
if(sym->symtype == 'L' || sym->symtype == 'l')
123124
f->frame = -sizeof(uintptr);
124125
break;

0 commit comments

Comments
 (0)