diff options
Diffstat (limited to 'src/cmd/6l/asm.c')
-rw-r--r-- | src/cmd/6l/asm.c | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 1fc3db98d..af00f5594 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -351,50 +351,65 @@ doelf(void) nsym = 1; // sym 0 is reserved for(h=0; h<NHASH; h++) { for(s=hash[h]; s!=S; s=s->link) { - if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->dynimpname == nil) + if(!s->reachable || (s->type != STEXT && s->type != SDATA && s->type != SBSS) || s->dynimpname == nil) continue; - d = lookup(".rela", 0); - addaddr(d, s); - adduint64(d, ELF64_R_INFO(nsym, R_X86_64_64)); - adduint64(d, 0); + if(!s->dynexport) { + d = lookup(".rela", 0); + addaddr(d, s); + adduint64(d, ELF64_R_INFO(nsym, R_X86_64_64)); + adduint64(d, 0); + } + nsym++; d = lookup(".dynsym", 0); adduint32(d, addstring(lookup(".dynstr", 0), s->dynimpname)); + /* type */ t = STB_GLOBAL << 4; - t |= STT_OBJECT; // works for func too, empirically + if(s->dynexport && s->type == STEXT) + t |= STT_FUNC; + else + t |= STT_OBJECT; adduint8(d, t); - adduint8(d, 0); /* reserved */ - adduint16(d, SHN_UNDEF); /* section where symbol is defined */ - adduint64(d, 0); /* value */ - adduint64(d, 0); /* size of object */ - if(needlib(s->dynimplib)) + /* reserved */ + adduint8(d, 0); + + /* section where symbol is defined */ + if(!s->dynexport) + adduint16(d, SHN_UNDEF); + else { + switch(s->type) { + default: + case STEXT: + t = 9; + break; + case SDATA: + t = 10; + break; + case SBSS: + t = 11; + break; + } + adduint16(d, t); + } + + /* value */ + if(!s->dynexport) + adduint64(d, 0); + else + addaddr(d, s); + + /* size of object */ + adduint64(d, 0); + + if(!s->dynexport && needlib(s->dynimplib)) elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->dynimplib)); } } - /* - * hash table. - * only entries that other objects need to find when - * linking us need to be in the table. right now that is - * no entries. - * - * freebsd insists on having chains enough for all - * the local symbols, though. for now, we just lay - * down a trivial hash table with 1 bucket and a long chain, - * because no one is actually looking for our symbols. - */ - s = lookup(".hash", 0); - s->type = SDATA; // TODO: rodata - s->reachable = 1; - adduint32(s, 1); // nbucket - adduint32(s, nsym); // nchain - adduint32(s, nsym-1); // bucket 0 - adduint32(s, 0); // chain 0 - for(h=1; h<nsym; h++) // chain nsym-1 -> nsym-2 -> ... -> 2 -> 1 -> 0 - adduint32(s, h-1); + elfdynhash(nsym); /* * .dynamic table |