summaryrefslogtreecommitdiff
path: root/src/cmd/6l/asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6l/asm.c')
-rw-r--r--src/cmd/6l/asm.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index ba2074fde..dda19e48d 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -95,6 +95,8 @@ enum {
ElfStrStrtab,
ElfStrRelaPlt,
ElfStrPlt,
+ ElfStrGnuVersion,
+ ElfStrGnuVersionR,
NElfStr
};
@@ -436,6 +438,7 @@ adddynsym(Sym *s)
s->dynid = nelfsym++;
d = lookup(".dynsym", 0);
+
name = s->dynimpname;
if(name == nil)
name = s->name;
@@ -586,6 +589,8 @@ doelf(void)
elfstr[ElfStrRela] = addstring(shstrtab, ".rela");
elfstr[ElfStrRelaPlt] = addstring(shstrtab, ".rela.plt");
elfstr[ElfStrPlt] = addstring(shstrtab, ".plt");
+ elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
+ elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r");
/* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0);
@@ -629,6 +634,14 @@ doelf(void)
s = lookup(".rela.plt", 0);
s->reachable = 1;
s->type = SELFDATA;
+
+ s = lookup(".gnu.version", 0);
+ s->reachable = 1;
+ s->type = SELFDATA;
+
+ s = lookup(".gnu.version_r", 0);
+ s->reachable = 1;
+ s->type = SELFDATA;
/* define dynamic elf table */
s = lookup(".dynamic", 0);
@@ -653,7 +666,8 @@ doelf(void)
elfwritedynent(s, DT_PLTREL, DT_RELA);
elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rela.plt", 0));
elfwritedynentsym(s, DT_JMPREL, lookup(".rela.plt", 0));
- elfwritedynent(s, DT_NULL, 0);
+
+ // Do not write DT_NULL. elfdynhash will finish it.
}
}
@@ -681,7 +695,7 @@ asmb(void)
{
int32 magic;
int a, dynsym;
- vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink;
+ vlong vl, startva, symo, elfsymo, elfstro, elfsymsize, machlink;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
@@ -735,8 +749,11 @@ asmb(void)
/* index of elf text section; needed by asmelfsym, double-checked below */
/* !debug['d'] causes extra sections before the .text section */
elftextsh = 1;
- if(!debug['d'])
+ if(!debug['d']) {
elftextsh += 10;
+ if(elfverneed)
+ elftextsh += 2;
+ }
break;
case Hwindows:
break;
@@ -846,10 +863,7 @@ asmb(void)
/* elf amd-64 */
eh = getElfEhdr();
- fo = HEADR;
startva = INITTEXT - HEADR;
- va = startva + fo;
- w = segtext.filelen;
/* This null SHdr must appear before all others */
sh = newElfShdr(elfstr[ElfStrEmpty]);
@@ -923,6 +937,24 @@ asmb(void)
sh->addralign = 1;
shsym(sh, lookup(".dynstr", 0));
+ if(elfverneed) {
+ sh = newElfShdr(elfstr[ElfStrGnuVersion]);
+ sh->type = SHT_GNU_VERSYM;
+ sh->flags = SHF_ALLOC;
+ sh->addralign = 2;
+ sh->link = dynsym;
+ sh->entsize = 2;
+ shsym(sh, lookup(".gnu.version", 0));
+
+ sh = newElfShdr(elfstr[ElfStrGnuVersionR]);
+ sh->type = SHT_GNU_VERNEED;
+ sh->flags = SHF_ALLOC;
+ sh->addralign = 8;
+ sh->info = elfverneed;
+ sh->link = dynsym+1; // dynstr
+ shsym(sh, lookup(".gnu.version_r", 0));
+ }
+
sh = newElfShdr(elfstr[ElfStrRelaPlt]);
sh->type = SHT_RELA;
sh->flags = SHF_ALLOC;