diff options
| author | Rob Pike <r@golang.org> | 2009-07-21 15:10:47 -0700 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2009-07-21 15:10:47 -0700 |
| commit | 3d42e691b931d34f2a3fee0885368f42d84665fb (patch) | |
| tree | 1762de1e063f5d673eebcc64aa617480f43a0ae4 /src/cmd/ld | |
| parent | ff790f470462e315d810155b304306fec2b795be (diff) | |
| download | go-3d42e691b931d34f2a3fee0885368f42d84665fb.tar.xz | |
make 6l produce dynamically linked binaries (although they are fully statically linked as far
as go is concerned). the -d flag is now flipped; as on the mac, -d disables dynamic.
much remains to be improved to move the output closer to the gcc format.
R=rsc
DELTA=366 (310 added, 30 deleted, 26 changed)
OCL=31929
CL=31951
Diffstat (limited to 'src/cmd/ld')
| -rw-r--r-- | src/cmd/ld/elf64.c | 69 | ||||
| -rw-r--r-- | src/cmd/ld/elf64.h | 109 |
2 files changed, 171 insertions, 7 deletions
diff --git a/src/cmd/ld/elf64.c b/src/cmd/ld/elf64.c index ea1a39b418..dc9f4196b1 100644 --- a/src/cmd/ld/elf64.c +++ b/src/cmd/ld/elf64.c @@ -8,20 +8,25 @@ #define NSECT 16 static int numstr; +static int stroffset; static Elf64Hdr hdr; static Elf64PHdr *phdr[NSECT]; static Elf64SHdr *shdr[NSECT]; static char *sname[NSECT]; static char *str[NSECT]; +/* + Initialize the global variable that describes the ELF header. It will be updated as + we write section and prog headers. + */ void elf64init(void) { - hdr.phoff = ELF64HDRSIZE; - hdr.shoff = ELF64HDRSIZE; - hdr.ehsize = ELF64HDRSIZE; - hdr.phentsize = ELF64PHDRSIZE; - hdr.shentsize = ELF64SHDRSIZE; + hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */ + hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */ + hdr.ehsize = ELF64HDRSIZE; /* Must be ELF64HDRSIZE */ + hdr.phentsize = ELF64PHDRSIZE; /* Must be ELF64PHDRSIZE */ + hdr.shentsize = ELF64SHDRSIZE; /* Must be ELF64SHDRSIZE */ } void @@ -168,3 +173,57 @@ elf64writehdr() WPUT(hdr.shstrndx); return ELF64HDRSIZE; } + +/* Taken directly from the definition document for ELF64 */ +uint32 +elf64_hash(uchar *name) +{ + unsigned long h = 0, g; + while (*name) { + h = (h << 4) + *name++; + if (g = h & 0xf0000000) + h ^= g >> 24; + h &= 0x0fffffff; + } + return h; +} + +void +elf64writedynent(int tag, uint64 val) +{ + VPUT(tag); + VPUT(val); +} + +/* Where to write the next piece of data attached to an SHeader */ +uint64 elfaddr = ELF64FULLHDRSIZE; + +/* Mark a start location in the SHeader data */ +uint64 +startelf(void) +{ + seek(cout, elfaddr, 0); + return elfaddr; +} + +/* Mark the end of a location in the SHeader data */ +uint64 +endelf(void) +{ + uint64 p; + + cflush(); + p = seek(cout, 0, 1); + if (p < elfaddr) { + diag("endelf before elfaddr"); + } + if ((p & 7) != 0) { + p = (p + 7) & ~7LL; + seek(cout, p, 0); + } + elfaddr = p; + if (p > ELF64RESERVE) { + diag("endelf overflows reserve %lld\n", p); + } + return elfaddr; +} diff --git a/src/cmd/ld/elf64.h b/src/cmd/ld/elf64.h index f42ae94252..55d0ca3098 100644 --- a/src/cmd/ld/elf64.h +++ b/src/cmd/ld/elf64.h @@ -121,6 +121,7 @@ struct Elf64PHdr #define PT_DYNAMIC 2 /* Dynamic linking tables */ #define PT_INTERP 3 /* Program interpreter path name */ #define PT_NOTE 4 /* Note sections */ +#define PT_PHDR 6 /* Program header table */ /* P flags */ #define PF_X 0x1 /* Execute permission */ @@ -169,6 +170,103 @@ struct Elf64SHdr #define SHF_MASKOS 0x0F000000 /* Environment-specific use */ #define SHF_MASKPROC 0xF0000000 /* Processor-specific use */ + +typedef struct Elf64Dyn Elf64Dyn; +struct Elf64Dyn +{ + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +}; + +/* Dyn table entries */ +#define DT_NULL 0 /* ignored: Marks the end of the dynamic array */ +#define DT_NEEDED 1 /* d_val: The string table offset of the name of + a needed library. */ +#define DT_PLTRELSZ 2 /* d_val: Total size, in bytes, of the relocation + entries associated with the procedure linkage table. */ +#define DT_PLTGOT 3 /* d_ptr: Contains an address associated with the linkage + table. The specific meaning of this field is + processor-dependent. */ +#define DT_HASH 4 /* d_ptr: Address of the symbol hash table. */ +#define DT_STRTAB 5 /* d_ptr: Address of the dynamic string table. */ +#define DT_SYMTAB 6 /* d_ptr: Address of the dynamic symbol table. */ +#define DT_RELA 7 /* d_ptr Address of a relocation table with Elf64_Rela + entries. */ +#define DT_RELASZ 8 /* d_val: Total size, in bytes, of the DT_RELA relocation + table. */ +#define DT_RELAENT 9 /* d_val: Size, in bytes, of each DT_RELA relocation + entry. */ +#define DT_STRSZ 10 /* d_val: Total size, in bytes, of the string table. */ +#define DT_SYMENT 11 /* d_val: Size, in bytes, of each symbol table entry. */ +#define DT_INIT 12 /* d_ptr Address of the initialization function. */ +#define DT_FINI 13 /* d_ptr Address of the termination function. */ +#define DT_SONAME 14 /* d_val The string table offset of the name of this + shared object. */ +#define DT_RPATH 15 /* d_val The string table offset of a shared library + search path string. */ +#define DT_SYMBOLIC 16 /* ignored The presence of this dynamic table entry + modifies the symbol resolution algorithm for references + within the library. Symbols defined within the library + are used to resolve references before the dynamic + linker searches the usual search path. */ +#define DT_REL 17 /* d_ptr Address of a relocation table with Elf64_Rel + entries. */ +#define DT_RELSZ 18 /* d_val Total size, in bytes, of the DT_REL relocation + table. */ +#define DT_RELENT 19 /* d_val Size, in bytes, of each DT_REL relocation + entry. */ +#define DT_PLTREL 20 /* d_val Type of relocation entry used for the procedure + linkage table. The d_val member contains either DT_REL + or DT_RELA. */ +#define DT_DEBUG 21 /* d_ptr Reserved for debugger use. */ +#define DT_TEXTREL 22 /* ignored The presence of this dynamic table entry + signals that the relocation table contains relocations + for a non-writable segment. */ +#define DT_JMPREL 23 /* d_ptr Address of the relocations associated with the + procedure linkage table. */ +#define DT_BIND_NOW 24 /* ignored The presence of this dynamic table entry + signals that the dynamic loader should process all + relocations for this object before transferring + control to the program. */ +#define DT_INIT_ARRAY 25 /* d_ptr Pointer to an array of pointers to initialization + functions. */ +#define DT_FINI_ARRAY 26 /* d_ptr Pointer to an array of pointers to termination + functions. */ +#define DT_INIT_ARRAYSZ 27 /* d_val Size, in bytes, of the array of initialization + functions. */ +#define DT_FINI_ARRAYSZ 28 /* d_val Size, in bytes, of the array of termination + functions. */ +#define DT_LOOS 0x60000000 /* Defines a range of dynamic table tags that are reserved + for environment-specific use. */ +#define DT_HIOS 0x6FFFFFFF +#define DT_LOPROC 0x70000000 /* Defines a range of dynamic table tags that are + reserved for processor-specific use. */ +#define DT_HIPROC 0x7FFFFFFF + +typedef struct Elf64_Rel Elf64_Rel; +struct Elf64_Rel +{ + Elf64_Addr r_offset; /* Address of reference */ + Elf64_Xword r_info; /* Symbol index and type of relocation */ +}; +#define ELF64RELSIZE 8 + +typedef struct Elf64_Rela Elf64_Rela; +struct Elf64_Rela +{ + Elf64_Addr r_offset; /* Address of reference */ + Elf64_Xword r_info; /* Symbol index and type of relocation */ + Elf64_Sxword r_addend; /* Constant part of expression */ +}; +#define ELF64RELASIZE 24 + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffffL) +#define ELF64_R_INFO(s, t) (((s) << 32) + ((t) & 0xffffffffL)) + void elf64init(void); Elf64Hdr *getElf64Hdr(); Elf64SHdr *newElf64SHdr(char*); @@ -177,10 +275,17 @@ uint32 elf64writehdr(void); uint32 elf64writephdrs(void); uint32 elf64writeshdrs(void); void elf64writestrtable(void); - +void elf64writedynent(int, uint64); +uint32 elf64_hash(uchar*); +uint64 startelf(void); +uint64 endelf(void); extern int nume64phdr; extern int nume64shdr; #define STRTABSIZE 256 -/* Amount of space to reserve at the start of the file; may waste some */ +/* Amount of space available for Header, PHeaders and SHeaders */ #define ELF64FULLHDRSIZE 2048 +/* Space reserved after ELF64FULLHEADERSIZE for dynamic info */ +#define ELFDYNAMICSIZE 256 +/* Total amount of ELF space to reserve at the start of the file; may waste some */ +#define ELF64RESERVE 4096 |
