summaryrefslogtreecommitdiff
path: root/src/cmd/8l/asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8l/asm.c')
-rw-r--r--src/cmd/8l/asm.c97
1 files changed, 44 insertions, 53 deletions
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index e1ccfb8a3..22abd8049 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -519,7 +519,7 @@ doelf(void)
/* predefine strings we need for section headers */
shstrtab = lookup(".shstrtab", 0);
- shstrtab->type = SELFDATA;
+ shstrtab->type = SELFROSECT;
shstrtab->reachable = 1;
elfstr[ElfStrEmpty] = addstring(shstrtab, "");
@@ -551,21 +551,16 @@ doelf(void)
elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r");
- /* interpreter string */
- s = lookup(".interp", 0);
- s->reachable = 1;
- s->type = SELFDATA;
-
/* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0);
- s->type = SELFDATA;
+ s->type = SELFROSECT;
s->reachable = 1;
s->size += ELF32SYMSIZE;
/* dynamic string table */
s = lookup(".dynstr", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
if(s->size == 0)
addstring(s, "");
dynstr = s;
@@ -573,45 +568,45 @@ doelf(void)
/* relocation table */
s = lookup(".rel", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
/* global offset table */
s = lookup(".got", 0);
s->reachable = 1;
- s->type = SDATA; // writable, so not SELFDATA
+ s->type = SELFSECT; // writable
/* hash */
s = lookup(".hash", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
/* got.plt */
s = lookup(".got.plt", 0);
s->reachable = 1;
- s->type = SDATA; // writable, so not SELFDATA
+ s->type = SELFSECT; // writable
s = lookup(".plt", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
s = lookup(".rel.plt", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
s = lookup(".gnu.version", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
s = lookup(".gnu.version_r", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
elfsetupplt();
/* define dynamic elf table */
s = lookup(".dynamic", 0);
s->reachable = 1;
- s->type = SELFDATA;
+ s->type = SELFROSECT;
/*
* .dynamic table
@@ -638,8 +633,11 @@ doelf(void)
void
shsym(Elf64_Shdr *sh, Sym *s)
{
- sh->addr = symaddr(s);
- sh->off = datoff(sh->addr);
+ vlong addr;
+ addr = symaddr(s);
+ if(sh->flags&SHF_ALLOC)
+ sh->addr = addr;
+ sh->off = datoff(addr);
sh->size = s->size;
}
@@ -665,6 +663,7 @@ asmb(void)
ElfShdr *sh;
Section *sect;
Sym *sym;
+ int o;
int i;
if(debug['v'])
@@ -672,12 +671,12 @@ asmb(void)
Bflush(&bso);
sect = segtext.sect;
- seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+ cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
codeblk(sect->vaddr, sect->len);
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
for(sect = sect->next; sect != nil; sect = sect->next) {
- seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+ cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len);
}
@@ -685,7 +684,7 @@ asmb(void)
Bprint(&bso, "%5.2f datblk\n", cputime());
Bflush(&bso);
- seek(cout, segdata.fileoff, 0);
+ cseek(segdata.fileoff);
datblk(segdata.vaddr, segdata.filelen);
machlink = 0;
@@ -695,7 +694,7 @@ asmb(void)
if(iself) {
/* index of elf text section; needed by asmelfsym, double-checked below */
/* !debug['d'] causes extra sections before the .text section */
- elftextsh = 1;
+ elftextsh = 2;
if(!debug['d']) {
elftextsh += 10;
if(elfverneed)
@@ -742,7 +741,7 @@ asmb(void)
symo = rnd(symo, PEFILEALIGN);
break;
}
- seek(cout, symo, 0);
+ cseek(symo);
switch(HEADTYPE) {
default:
if(iself) {
@@ -750,7 +749,7 @@ asmb(void)
Bprint(&bso, "%5.2f elfsym\n", cputime());
asmelfsym();
cflush();
- ewrite(cout, elfstrdat, elfstrsize);
+ cwrite(elfstrdat, elfstrsize);
if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime());
@@ -781,7 +780,7 @@ asmb(void)
if(debug['v'])
Bprint(&bso, "%5.2f headr\n", cputime());
Bflush(&bso);
- seek(cout, 0L, 0);
+ cseek(0L);
switch(HEADTYPE) {
default:
if(iself)
@@ -932,6 +931,17 @@ asmb(void)
pph->paddr = INITTEXT - HEADR + pph->off;
pph->align = INITRND;
+ /*
+ * PHDR must be in a loaded segment. Adjust the text
+ * segment boundaries downwards to include it.
+ */
+ o = segtext.vaddr - pph->vaddr;
+ segtext.vaddr -= o;
+ segtext.len += o;
+ o = segtext.fileoff - pph->off;
+ segtext.fileoff -= o;
+ segtext.filelen += o;
+
if(!debug['d']) {
/* interpreter */
sh = newElfShdr(elfstr[ElfStrInterp]);
@@ -1072,6 +1082,11 @@ asmb(void)
ph->flags = PF_W+PF_R;
ph->align = 4;
+ sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
+ sh->type = SHT_STRTAB;
+ sh->addralign = 1;
+ shsym(sh, lookup(".shstrtab", 0));
+
if(elftextsh != eh->shnum)
diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
for(sect=segtext.sect; sect!=nil; sect=sect->next)
@@ -1097,11 +1112,6 @@ asmb(void)
dwarfaddelfheaders();
}
- sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
- sh->type = SHT_STRTAB;
- sh->addralign = 1;
- shsym(sh, lookup(".shstrtab", 0));
-
/* Main header */
eh->ident[EI_MAG0] = '\177';
eh->ident[EI_MAG1] = 'E';
@@ -1126,13 +1136,13 @@ asmb(void)
pph->memsz = pph->filesz;
}
- seek(cout, 0, 0);
+ cseek(0);
a = 0;
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
cflush();
- if(a+elfwriteinterp() > ELFRESERVE)
+ if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
@@ -1154,25 +1164,6 @@ s8put(char *n)
cput(name[i]);
}
-void
-cflush(void)
-{
- int n;
-
- n = sizeof(buf.cbuf) - cbc;
- if(n)
- ewrite(cout, buf.cbuf, n);
- cbp = buf.cbuf;
- cbc = sizeof(buf.cbuf);
-}
-
-/* Current position in file */
-vlong
-cpos(void)
-{
- return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
-}
-
int32
rnd(int32 v, int32 r)
{
@@ -1207,7 +1198,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
case SCONST:
case SRODATA:
case SDATA:
- case SELFDATA:
+ case SELFROSECT:
case SMACHO:
case SMACHOGOT:
case STYPE: