diff options
| author | Russ Cox <rsc@golang.org> | 2010-09-19 22:10:34 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-09-19 22:10:34 -0400 |
| commit | af12feb8d514b5970c984be61b07c56e0e72b2ce (patch) | |
| tree | c18b5c9b0cabfd8ba2cf0abb12f73bfbf8c4d96b /src/cmd/ld/elf.c | |
| parent | afbee9d87d1ce9fd98e1beb9ac8945263c1f3e52 (diff) | |
| download | go-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.c | 80 |
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; +} |
