mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00:00
cmd/ld: place read-only data in non-executable segment
R=golang-dev, dave, r CC=golang-dev, nigeltao https://golang.org/cl/10713043
This commit is contained in:
parent
6c99b5c0d3
commit
d6d83c918c
@ -550,13 +550,20 @@ asmb(void)
|
||||
sect = segtext.sect;
|
||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||
codeblk(sect->vaddr, sect->len);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if(segrodata.filelen > 0) {
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f rodatblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
cseek(segrodata.fileoff);
|
||||
datblk(segrodata.vaddr, segrodata.filelen);
|
||||
}
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
@ -587,7 +594,7 @@ asmb(void)
|
||||
symo = HEADR+segtext.len+segdata.filelen;
|
||||
break;
|
||||
ElfSym:
|
||||
symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
|
||||
symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(HEADR+segrodata.filelen, INITRND)+segdata.filelen;
|
||||
symo = rnd(symo, INITRND);
|
||||
break;
|
||||
}
|
||||
|
@ -625,13 +625,20 @@ asmb(void)
|
||||
sect = segtext.sect;
|
||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||
codeblk(sect->vaddr, sect->len);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if(segrodata.filelen > 0) {
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f rodatblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
cseek(segrodata.fileoff);
|
||||
datblk(segrodata.vaddr, segrodata.filelen);
|
||||
}
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
@ -696,7 +703,7 @@ asmb(void)
|
||||
case Hfreebsd:
|
||||
case Hnetbsd:
|
||||
case Hopenbsd:
|
||||
symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen;
|
||||
symo = rnd(HEADR+segtext.len, INITRND)+rnd(segrodata.len, INITRND)+segdata.filelen;
|
||||
symo = rnd(symo, INITRND);
|
||||
break;
|
||||
case Hwindows:
|
||||
|
@ -595,13 +595,20 @@ asmb(void)
|
||||
sect = segtext.sect;
|
||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||
codeblk(sect->vaddr, sect->len);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if(segrodata.filelen > 0) {
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f rodatblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
cseek(segrodata.fileoff);
|
||||
datblk(segrodata.vaddr, segrodata.filelen);
|
||||
}
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
@ -655,7 +662,7 @@ asmb(void)
|
||||
symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
|
||||
break;
|
||||
Elfsym:
|
||||
symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
|
||||
symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(HEADR+segrodata.filelen, INITRND)+segdata.filelen;
|
||||
symo = rnd(symo, INITRND);
|
||||
break;
|
||||
case Hwindows:
|
||||
|
@ -1040,6 +1040,7 @@ dodata(void)
|
||||
int32 n;
|
||||
vlong datsize;
|
||||
Section *sect;
|
||||
Segment *segro;
|
||||
Sym *s, *last, **l;
|
||||
Sym *gcdata1, *gcbss1;
|
||||
|
||||
@ -1130,7 +1131,7 @@ dodata(void)
|
||||
sect->vaddr = datsize;
|
||||
s->sect = sect;
|
||||
s->type = SDATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
sect->len = datsize - sect->vaddr;
|
||||
}
|
||||
@ -1146,7 +1147,7 @@ dodata(void)
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SDATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
@ -1163,7 +1164,7 @@ dodata(void)
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SDATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
@ -1184,7 +1185,7 @@ dodata(void)
|
||||
s->sect = sect;
|
||||
s->type = SDATA;
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
gcaddsym(gcdata1, s, datsize - sect->vaddr); // gc
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
@ -1203,7 +1204,7 @@ dodata(void)
|
||||
for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
|
||||
s->sect = sect;
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
gcaddsym(gcbss1, s, datsize - sect->vaddr); // gc
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
@ -1222,7 +1223,7 @@ dodata(void)
|
||||
for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
@ -1241,7 +1242,7 @@ dodata(void)
|
||||
for(; s != nil && s->type == STLSBSS; s = s->next) {
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize;
|
||||
@ -1252,27 +1253,56 @@ dodata(void)
|
||||
diag("unexpected symbol type %d for %s", s->type, s->name);
|
||||
}
|
||||
|
||||
/* we finished segdata, begin segtext */
|
||||
/*
|
||||
* We finished data, begin read-only data.
|
||||
* Not all systems support a separate read-only non-executable data section.
|
||||
* ELF systems do.
|
||||
* OS X and Plan 9 do not.
|
||||
* Windows PE may, but if so we have not implemented it.
|
||||
* And if we're using external linking mode, the point is moot,
|
||||
* since it's not our decision; that code expects the sections in
|
||||
* segtext.
|
||||
*/
|
||||
if(iself && linkmode == LinkInternal)
|
||||
segro = &segrodata;
|
||||
else
|
||||
segro = &segtext;
|
||||
|
||||
s = datap;
|
||||
|
||||
datsize = 0;
|
||||
|
||||
/* read-only executable ELF, Mach-O sections */
|
||||
for(; s != nil && s->type < STYPE; s = s->next) {
|
||||
sect = addsection(&segtext, s->name, 04);
|
||||
sect->align = symalign(s);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = datsize;
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
sect->len = datsize - sect->vaddr;
|
||||
}
|
||||
|
||||
/* read-only data */
|
||||
sect = addsection(&segtext, ".rodata", 04);
|
||||
sect = addsection(segro, ".rodata", 04);
|
||||
sect->align = maxalign(s, STYPELINK-1);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = 0;
|
||||
lookup("rodata", 0)->sect = sect;
|
||||
lookup("erodata", 0)->sect = sect;
|
||||
datsize = 0;
|
||||
for(; s != nil && s->type < STYPELINK; s = s->next) {
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
|
||||
/* typelink */
|
||||
sect = addsection(&segtext, ".typelink", 04);
|
||||
sect = addsection(segro, ".typelink", 04);
|
||||
sect->align = maxalign(s, STYPELINK);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = datsize;
|
||||
@ -1282,13 +1312,13 @@ dodata(void)
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
|
||||
/* gosymtab */
|
||||
sect = addsection(&segtext, ".gosymtab", 04);
|
||||
sect = addsection(segro, ".gosymtab", 04);
|
||||
sect->align = maxalign(s, SPCLNTAB-1);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = datsize;
|
||||
@ -1298,13 +1328,13 @@ dodata(void)
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
|
||||
/* gopclntab */
|
||||
sect = addsection(&segtext, ".gopclntab", 04);
|
||||
sect = addsection(segro, ".gopclntab", 04);
|
||||
sect->align = maxalign(s, SELFROSECT-1);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = datsize;
|
||||
@ -1314,33 +1344,35 @@ dodata(void)
|
||||
datsize = aligndatsize(datsize, s);
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
}
|
||||
sect->len = datsize - sect->vaddr;
|
||||
|
||||
/* read-only ELF, Mach-O sections */
|
||||
for(; s != nil && s->type < SELFSECT; s = s->next) {
|
||||
sect = addsection(&segtext, s->name, 04);
|
||||
sect = addsection(segro, s->name, 04);
|
||||
sect->align = symalign(s);
|
||||
datsize = rnd(datsize, sect->align);
|
||||
sect->vaddr = datsize;
|
||||
s->sect = sect;
|
||||
s->type = SRODATA;
|
||||
s->value = datsize;
|
||||
s->value = datsize - sect->vaddr;
|
||||
growdatsize(&datsize, s);
|
||||
sect->len = datsize - sect->vaddr;
|
||||
}
|
||||
|
||||
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
|
||||
if(datsize != (uint32)datsize) {
|
||||
diag("text segment too large");
|
||||
diag("read-only data segment too large");
|
||||
}
|
||||
|
||||
/* number the sections */
|
||||
n = 1;
|
||||
for(sect = segtext.sect; sect != nil; sect = sect->next)
|
||||
sect->extnum = n++;
|
||||
for(sect = segrodata.sect; sect != nil; sect = sect->next)
|
||||
sect->extnum = n++;
|
||||
for(sect = segdata.sect; sect != nil; sect = sect->next)
|
||||
sect->extnum = n++;
|
||||
}
|
||||
@ -1402,6 +1434,7 @@ address(void)
|
||||
segtext.vaddr = va;
|
||||
segtext.fileoff = HEADR;
|
||||
for(s=segtext.sect; s != nil; s=s->next) {
|
||||
//print("%s at %#llux + %#llux\n", s->name, va, (vlong)s->len);
|
||||
va = rnd(va, s->align);
|
||||
s->vaddr = va;
|
||||
va += s->len;
|
||||
@ -1409,8 +1442,25 @@ address(void)
|
||||
segtext.len = va - INITTEXT;
|
||||
segtext.filelen = segtext.len;
|
||||
|
||||
va = rnd(va, INITRND);
|
||||
if(segrodata.sect != nil) {
|
||||
// align to page boundary so as not to mix
|
||||
// rodata and executable text.
|
||||
va = rnd(va, INITRND);
|
||||
|
||||
segrodata.rwx = 04;
|
||||
segrodata.vaddr = va;
|
||||
segrodata.fileoff = va - segtext.vaddr + segtext.fileoff;
|
||||
segrodata.filelen = 0;
|
||||
for(s=segrodata.sect; s != nil; s=s->next) {
|
||||
va = rnd(va, s->align);
|
||||
s->vaddr = va;
|
||||
va += s->len;
|
||||
}
|
||||
segrodata.len = va - segrodata.vaddr;
|
||||
segrodata.filelen = segrodata.len;
|
||||
}
|
||||
|
||||
va = rnd(va, INITRND);
|
||||
segdata.rwx = 06;
|
||||
segdata.vaddr = va;
|
||||
segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
|
||||
@ -1445,17 +1495,17 @@ address(void)
|
||||
segdata.filelen = bss->vaddr - segdata.vaddr;
|
||||
|
||||
text = segtext.sect;
|
||||
rodata = text->next;
|
||||
if(segrodata.sect)
|
||||
rodata = segrodata.sect;
|
||||
else
|
||||
rodata = text->next;
|
||||
typelink = rodata->next;
|
||||
symtab = typelink->next;
|
||||
pclntab = symtab->next;
|
||||
|
||||
for(sym = datap; sym != nil; sym = sym->next) {
|
||||
cursym = sym;
|
||||
if(sym->type < SNOPTRDATA)
|
||||
sym->value += rodata->vaddr;
|
||||
else
|
||||
sym->value += segdata.sect->vaddr;
|
||||
sym->value += sym->sect->vaddr;
|
||||
for(sub = sym->sub; sub != nil; sub = sub->sub)
|
||||
sub->value += sym->value;
|
||||
}
|
||||
|
@ -864,6 +864,8 @@ elfemitreloc(void)
|
||||
elfrelocsect(segtext.sect, textp);
|
||||
for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
|
||||
elfrelocsect(sect, datap);
|
||||
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
|
||||
elfrelocsect(sect, datap);
|
||||
for(sect=segdata.sect; sect!=nil; sect=sect->next)
|
||||
elfrelocsect(sect, datap);
|
||||
}
|
||||
@ -1001,7 +1003,7 @@ doelf(void)
|
||||
|
||||
s = lookup(".plt", 0);
|
||||
s->reachable = 1;
|
||||
s->type = SELFROSECT;
|
||||
s->type = SELFRXSECT;
|
||||
|
||||
elfsetupplt();
|
||||
|
||||
@ -1105,6 +1107,8 @@ asmbelfsetup(void)
|
||||
|
||||
for(sect=segtext.sect; sect!=nil; sect=sect->next)
|
||||
elfshalloc(sect);
|
||||
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
|
||||
elfshalloc(sect);
|
||||
for(sect=segdata.sect; sect!=nil; sect=sect->next)
|
||||
elfshalloc(sect);
|
||||
}
|
||||
@ -1232,6 +1236,8 @@ asmbelf(vlong symo)
|
||||
USED(resoff);
|
||||
|
||||
elfphload(&segtext);
|
||||
if(segrodata.sect != nil)
|
||||
elfphload(&segrodata);
|
||||
elfphload(&segdata);
|
||||
|
||||
/* Dynamic linking sections */
|
||||
@ -1397,12 +1403,16 @@ elfobj:
|
||||
|
||||
for(sect=segtext.sect; sect!=nil; sect=sect->next)
|
||||
elfshbits(sect);
|
||||
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
|
||||
elfshbits(sect);
|
||||
for(sect=segdata.sect; sect!=nil; sect=sect->next)
|
||||
elfshbits(sect);
|
||||
|
||||
if(linkmode == LinkExternal) {
|
||||
for(sect=segtext.sect; sect!=nil; sect=sect->next)
|
||||
elfshreloc(sect);
|
||||
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
|
||||
elfshreloc(sect);
|
||||
for(sect=segdata.sect; sect!=nil; sect=sect->next)
|
||||
elfshreloc(sect);
|
||||
// add a .note.GNU-stack section to mark the stack as non-executable
|
||||
|
@ -36,6 +36,13 @@
|
||||
|
||||
#include <ar.h>
|
||||
|
||||
enum
|
||||
{
|
||||
// Whether to assume that the external linker is "gold"
|
||||
// (http://sourceware.org/ml/binutils/2008-03/msg00162.html).
|
||||
AssumeGoldLinker = 0,
|
||||
};
|
||||
|
||||
int iconv(Fmt*);
|
||||
|
||||
char symname[] = SYMDEF;
|
||||
@ -676,6 +683,10 @@ hostlink(void)
|
||||
}
|
||||
if(HEADTYPE == Hdarwin)
|
||||
argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
|
||||
|
||||
if(iself && AssumeGoldLinker)
|
||||
argv[argc++] = "-Wl,--rosegment";
|
||||
|
||||
argv[argc++] = "-o";
|
||||
argv[argc++] = outfile;
|
||||
|
||||
|
@ -33,7 +33,11 @@ enum
|
||||
Sxxx,
|
||||
|
||||
/* order here is order in output file */
|
||||
/* readonly, executable */
|
||||
STEXT,
|
||||
SELFRXSECT,
|
||||
|
||||
/* readonly, non-executable */
|
||||
STYPE,
|
||||
SSTRING,
|
||||
SGOSTRING,
|
||||
@ -42,6 +46,8 @@ enum
|
||||
SSYMTAB,
|
||||
SPCLNTAB,
|
||||
SELFROSECT,
|
||||
|
||||
/* writable, non-executable */
|
||||
SMACHOPLT,
|
||||
SELFSECT,
|
||||
SMACHO, /* Mach-O __nl_symbol_ptr */
|
||||
@ -54,6 +60,7 @@ enum
|
||||
SNOPTRBSS,
|
||||
STLSBSS,
|
||||
|
||||
/* not mapped */
|
||||
SXREF,
|
||||
SMACHOSYMSTR,
|
||||
SMACHOSYMTAB,
|
||||
@ -177,6 +184,7 @@ enum
|
||||
};
|
||||
|
||||
EXTERN Segment segtext;
|
||||
EXTERN Segment segrodata;
|
||||
EXTERN Segment segdata;
|
||||
EXTERN Segment segdwarf;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user