1
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
10
* We use the 64-bit data structures on both 32- and 64-bit machines
11
* in order to write the code just once. The 64-bit data structure is
12
* written in the 32-bit format on the 32-bit machines.
20
static ElfPhdr *phdr[NSECT];
21
static ElfShdr *shdr[NSECT];
24
typedef struct Elfstring Elfstring;
31
static Elfstring elfstr[100];
35
Initialize the global variable that describes the ELF header. It will be updated as
36
we write section and prog headers.
44
// 64-bit architectures
47
hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
48
hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */
49
hdr.ehsize = ELF64HDRSIZE; /* Must be ELF64HDRSIZE */
50
hdr.phentsize = ELF64PHDRSIZE; /* Must be ELF64PHDRSIZE */
51
hdr.shentsize = ELF64SHDRSIZE; /* Must be ELF64SHDRSIZE */
54
// 32-bit architectures
56
hdr.phoff = ELF32HDRSIZE; /* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
57
hdr.shoff = ELF32HDRSIZE; /* Will move as we add PHeaders */
58
hdr.ehsize = ELF32HDRSIZE; /* Must be ELF32HDRSIZE */
59
hdr.phentsize = ELF32PHDRSIZE; /* Must be ELF32PHDRSIZE */
60
hdr.shentsize = ELF32SHDRSIZE; /* Must be ELF32SHDRSIZE */
106
elf32shdr(ElfShdr *e)
126
for (i = 0; i < hdr.shnum; i++)
128
return hdr.shnum * ELF64SHDRSIZE;
130
for (i = 0; i < hdr.shnum; i++)
132
return hdr.shnum * ELF32SHDRSIZE;
136
elfsetstring(char *s, int off)
138
if(nelfstr >= nelem(elfstr)) {
139
diag("too many elf strings");
142
elfstr[nelfstr].s = s;
143
elfstr[nelfstr].off = off;
153
for (i = 0; i < hdr.phnum; i++)
155
return hdr.phnum * ELF64PHDRSIZE;
157
for (i = 0; i < hdr.phnum; i++)
159
return hdr.phnum * ELF32PHDRSIZE;
168
if (hdr.phnum >= NSECT)
169
diag("too many phdrs");
171
phdr[hdr.phnum++] = e;
173
hdr.shoff += ELF64PHDRSIZE;
175
hdr.shoff += ELF32PHDRSIZE;
180
newElfShstrtab(vlong name)
182
hdr.shstrndx = hdr.shnum;
183
return newElfShdr(name);
187
newElfShdr(vlong name)
193
if (hdr.shnum >= NSECT) {
194
diag("too many shdrs");
196
shdr[hdr.shnum++] = e;
212
for (i = 0; i < EI_NIDENT; i++)
235
for (i = 0; i < EI_NIDENT; i++)
257
return elf64writehdr();
258
return elf32writehdr();
261
/* Taken directly from the definition document for ELF64 */
267
h = (h << 4) + *name++;
268
if (g = h & 0xf0000000)
276
elfwritedynent(Sym *s, int tag, uint64 val)
288
elfwritedynentsym(Sym *s, int tag, Sym *t)
298
elfwritedynentsymsize(Sym *s, int tag, Sym *t)
315
n = strlen(interp)+1;
316
seek(cout, ELFRESERVE-n, 0);
317
ewrite(cout, interp, n);
322
elfinterp(ElfShdr *sh, uint64 startva, char *p)
327
n = strlen(interp)+1;
328
sh->addr = startva + ELFRESERVE - n;
329
sh->off = ELFRESERVE - n;
339
int i, h, nbucket, b;
342
uint32 *chain, *buckets;
350
s = lookup(".hash", 0);
361
chain = malloc(nsym * sizeof(uint32));
362
buckets = malloc(nbucket * sizeof(uint32));
363
if(chain == nil || buckets == nil) {
365
diag("out of memory");
368
memset(chain, 0, nsym * sizeof(uint32));
369
memset(buckets, 0, nbucket * sizeof(uint32));
370
for(h = 0; h<NHASH; h++) {
371
for(sy=hash[h]; sy!=S; sy=sy->hash) {
376
name = sy->dynimpname;
379
for(pc = (uchar*)name; *pc; pc++) {
387
chain[sy->dynid] = buckets[b];
388
buckets[b] = sy->dynid;
392
adduint32(s, nbucket);
394
for(i = 0; i<nbucket; i++)
395
adduint32(s, buckets[i]);
396
for(i = 0; i<nsym; i++)
397
adduint32(s, chain[i]);
402
elfwritedynent(lookup(".dynamic", 0), DT_NULL, 0);
406
elfphload(Segment *seg)
418
ph->vaddr = seg->vaddr;
419
ph->paddr = seg->vaddr;
420
ph->memsz = seg->len;
421
ph->off = seg->fileoff;
422
ph->filesz = seg->filelen;
429
elfshbits(Section *sect)
434
for(i=0; i<nelfstr; i++) {
435
if(strcmp(sect->name, elfstr[i].s) == 0) {
440
diag("cannot find elf name %s", sect->name);
445
sh = newElfShdr(off);
446
if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen)
447
sh->type = SHT_PROGBITS;
449
sh->type = SHT_NOBITS;
450
sh->flags = SHF_ALLOC;
452
sh->flags |= SHF_EXECINSTR;
454
sh->flags |= SHF_WRITE;
455
sh->addr = sect->vaddr;
456
sh->addralign = PtrSize;
457
sh->size = sect->len;
458
sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr;