aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld/elf.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-09-19 22:10:34 -0400
committerRuss Cox <rsc@golang.org>2010-09-19 22:10:34 -0400
commitaf12feb8d514b5970c984be61b07c56e0e72b2ce (patch)
treec18b5c9b0cabfd8ba2cf0abb12f73bfbf8c4d96b /src/cmd/ld/elf.c
parentafbee9d87d1ce9fd98e1beb9ac8945263c1f3e52 (diff)
downloadgo-af12feb8d514b5970c984be61b07c56e0e72b2ce.tar.xz
6l, 8l: clean up ELF code, fix NaCl
R=r CC=golang-dev https://golang.org/cl/2221042
Diffstat (limited to 'src/cmd/ld/elf.c')
-rw-r--r--src/cmd/ld/elf.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
index c5d58576dc..0ebdcf024c 100644
--- a/src/cmd/ld/elf.c
+++ b/src/cmd/ld/elf.c
@@ -21,6 +21,16 @@ static ElfPhdr *phdr[NSECT];
static ElfShdr *shdr[NSECT];
static char *interp;
+typedef struct Elfstring Elfstring;
+struct Elfstring
+{
+ char *s;
+ int off;
+};
+
+static Elfstring elfstr[100];
+static int nelfstr;
+
/*
Initialize the global variable that describes the ELF header. It will be updated as
we write section and prog headers.
@@ -122,6 +132,18 @@ elfwriteshdrs(void)
return hdr.shnum * ELF32SHDRSIZE;
}
+void
+elfsetstring(char *s, int off)
+{
+ if(nelfstr >= nelem(elfstr)) {
+ diag("too many elf strings");
+ errorexit();
+ }
+ elfstr[nelfstr].s = s;
+ elfstr[nelfstr].off = off;
+ nelfstr++;
+}
+
uint32
elfwritephdrs(void)
{
@@ -365,3 +387,61 @@ elfdynhash(int nsym)
free(chain);
free(buckets);
}
+
+ElfPhdr*
+elfphload(Segment *seg)
+{
+ ElfPhdr *ph;
+
+ ph = newElfPhdr();
+ ph->type = PT_LOAD;
+ if(seg->rwx & 4)
+ ph->flags |= PF_R;
+ if(seg->rwx & 2)
+ ph->flags |= PF_W;
+ if(seg->rwx & 1)
+ ph->flags |= PF_X;
+ ph->vaddr = seg->vaddr;
+ ph->paddr = seg->vaddr;
+ ph->memsz = seg->len;
+ ph->off = seg->fileoff;
+ ph->filesz = seg->filelen;
+ ph->align = INITRND;
+
+ return ph;
+}
+
+ElfShdr*
+elfshbits(Section *sect)
+{
+ int i, off;
+ ElfShdr *sh;
+
+ for(i=0; i<nelfstr; i++) {
+ if(strcmp(sect->name, elfstr[i].s) == 0) {
+ off = elfstr[i].off;
+ goto found;
+ }
+ }
+ diag("cannot find elf name %s", sect->name);
+ errorexit();
+ return nil;
+
+found:
+ sh = newElfShdr(off);
+ if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen)
+ sh->type = SHT_PROGBITS;
+ else
+ sh->type = SHT_NOBITS;
+ sh->flags = SHF_ALLOC;
+ if(sect->rwx & 1)
+ sh->flags |= SHF_EXECINSTR;
+ if(sect->rwx & 2)
+ sh->flags |= SHF_WRITE;
+ sh->addr = sect->vaddr;
+ sh->addralign = PtrSize;
+ sh->size = sect->len;
+ sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr;
+
+ return sh;
+}