aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-08-21 20:18:00 +0000
committerRichard M. Stallman1996-08-21 20:18:00 +0000
commitd7b43eaa00c71f48a19134bf89751820f1ccf17b (patch)
tree900c40c728c9d75078025f924f0ffb196b978174 /src
parent18aa68c389251d4a2b9cafa5b49a4cfe41fae480 (diff)
downloademacs-d7b43eaa00c71f48a19134bf89751820f1ccf17b.tar.gz
emacs-d7b43eaa00c71f48a19134bf89751820f1ccf17b.zip
Conditionalize the changes below on not __linux__.
Include reloc.h and elf_abi.h. (rel_dyn_section, dynstr_section, dynsym_section): New variables. (old_data_scnhdr): New variable. (CHECK_SCNHDR): Compare just 8 chars of section name. (unexec): Check for rel_dyn_section, dynsym_section, dynstr_section. Do call update_dynamic_symbols. (update_dynamic_symbols): Finish it up and take away #if 0.
Diffstat (limited to 'src')
-rw-r--r--src/unexalpha.c151
1 files changed, 91 insertions, 60 deletions
diff --git a/src/unexalpha.c b/src/unexalpha.c
index 48b4059fcaf..2adfd1fa57e 100644
--- a/src/unexalpha.c
+++ b/src/unexalpha.c
@@ -31,6 +31,10 @@ Boston, MA 02111-1307, USA. */
31#include <aouthdr.h> 31#include <aouthdr.h>
32#include <scnhdr.h> 32#include <scnhdr.h>
33#include <syms.h> 33#include <syms.h>
34#ifndef __linux__
35# include <reloc.h>
36# include <elf_abi.h>
37#endif
34 38
35static void fatal_unexec (); 39static void fatal_unexec ();
36static void mark_x (); 40static void mark_x ();
@@ -52,11 +56,14 @@ static void mark_x ();
52extern int errno; 56extern int errno;
53extern char *strerror (); 57extern char *strerror ();
54 58
55void *sbrk(); 59void *sbrk ();
56 60
57#define EEOF -1 61#define EEOF -1
58 62
59static struct scnhdr *text_section; 63static struct scnhdr *text_section;
64static struct scnhdr *rel_dyn_section;
65static struct scnhdr *dynstr_section;
66static struct scnhdr *dynsym_section;
60static struct scnhdr *init_section; 67static struct scnhdr *init_section;
61static struct scnhdr *finit_section; 68static struct scnhdr *finit_section;
62static struct scnhdr *rdata_section; 69static struct scnhdr *rdata_section;
@@ -71,6 +78,8 @@ static struct scnhdr *sdata_section;
71static struct scnhdr *sbss_section; 78static struct scnhdr *sbss_section;
72static struct scnhdr *bss_section; 79static struct scnhdr *bss_section;
73 80
81static struct scnhdr old_data_scnhdr;
82
74static unsigned long Brk; 83static unsigned long Brk;
75 84
76struct headers { 85struct headers {
@@ -157,7 +166,7 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
157#define CHECK_SCNHDR(ptr, name, flags) \ 166#define CHECK_SCNHDR(ptr, name, flags) \
158 ptr = NULL; \ 167 ptr = NULL; \
159 for (i = 0; i < nhdr.fhdr.f_nscns && !ptr; i++) \ 168 for (i = 0; i < nhdr.fhdr.f_nscns && !ptr; i++) \
160 if (strcmp (nhdr.section[i].s_name, name) == 0) \ 169 if (strncmp (nhdr.section[i].s_name, name, 8) == 0) \
161 { \ 170 { \
162 if (nhdr.section[i].s_flags != flags) \ 171 if (nhdr.section[i].s_flags != flags) \
163 fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \ 172 fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \
@@ -167,6 +176,15 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
167 176
168 CHECK_SCNHDR (text_section, _TEXT, STYP_TEXT); 177 CHECK_SCNHDR (text_section, _TEXT, STYP_TEXT);
169 CHECK_SCNHDR (init_section, _INIT, STYP_INIT); 178 CHECK_SCNHDR (init_section, _INIT, STYP_INIT);
179#ifdef _REL_DYN
180 CHECK_SCNHDR (rel_dyn_section, _REL_DYN, STYP_REL_DYN);
181#endif /* _REL_DYN */
182#ifdef _DYNSYM
183 CHECK_SCNHDR (dynsym_section, _DYNSYM, STYP_DYNSYM);
184#endif /* _REL_DYN */
185#ifdef _DYNSTR
186 CHECK_SCNHDR (dynstr_section, _DYNSTR, STYP_DYNSTR);
187#endif /* _REL_DYN */
170#ifdef _FINI 188#ifdef _FINI
171 CHECK_SCNHDR (finit_section, _FINI, STYP_FINI); 189 CHECK_SCNHDR (finit_section, _FINI, STYP_FINI);
172#endif /* _FINI */ 190#endif /* _FINI */
@@ -200,6 +218,8 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
200 218
201 Brk = brk; 219 Brk = brk;
202 220
221 bcopy (data_section, &old_data_scnhdr, sizeof (old_data_scnhdr));
222
203 nhdr.aout.dsize = brk - DATA_START; 223 nhdr.aout.dsize = brk - DATA_START;
204 nhdr.aout.bsize = 0; 224 nhdr.aout.bsize = 0;
205 if (entry_address == 0) 225 if (entry_address == 0)
@@ -341,15 +361,8 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
341 stat.st_size - ohdr.fhdr.f_symptr - cbHDRR, 361 stat.st_size - ohdr.fhdr.f_symptr - cbHDRR,
342 "writing symbol table of %s", new_name); 362 "writing symbol table of %s", new_name);
343 363
344#if 0 364#ifndef __linux__
345 365 update_dynamic_symbols (oldptr, new_name, new, nhdr.aout);
346/* Not needed for now */
347
348 update_dynamic_symbols (oldptr, new_name, new, newsyms,
349 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->issExtMax,
350 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbExtOffset,
351 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbSsExtOffset);
352
353#endif 366#endif
354 367
355#undef symhdr 368#undef symhdr
@@ -364,69 +377,87 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
364} 377}
365 378
366 379
367#if 0
368
369/* Not needed for now */
370
371/* The following function updates the values of some symbols
372 that are used by the dynamic loader:
373
374 _edata
375 _end
376 380
377*/
378 381
382#ifndef __linux__
379 383
380update_dynamic_symbols (old, new_name, new, newsyms, nsyms, symoff, stroff) 384update_dynamic_symbols (old, new_name, new, aout)
381 char *old; /* Pointer to old executable */ 385 char *old; /* Pointer to old executable */
382 char *new_name; /* Name of new executable */ 386 char *new_name; /* Name of new executable */
383 int new; /* File descriptor for new executable */ 387 int new; /* File descriptor for new executable */
384 long newsyms; /* Offset of Symbol table in new executable */ 388 struct aouthdr aout; /* a.out info from the file header */
385 int nsyms; /* Number of symbol table entries */
386 long symoff; /* Offset of External Symbols in old file */
387 long stroff; /* Offset of string table in old file */
388{ 389{
389 long i; 390 typedef struct dynrel_info {
390 int found = 0; 391 char * addr;
391 EXTR n_end, n_edata; 392 unsigned type:8;
393 unsigned index:24;
394 unsigned info:8;
395 unsigned pad:8;
396 } dr_info;
397
398 int nsyms = rel_dyn_section->s_size / sizeof (struct dynrel_info);
399 int i;
400 dr_info * rd_base = (dr_info *) (old + rel_dyn_section->s_scnptr);
401 Elf32_Sym * ds_base = (Elf32_Sym *) (old + dynsym_section->s_scnptr);
392 402
393 /* We go through the symbol table entries until we have found the two 403 for (i = 0; i < nsyms; i++) {
394 symbols. */ 404 register Elf32_Sym x;
395 405
396 /* cbEXTR is the size of an external symbol table entry */ 406 if (rd_base[i].index == 0)
407 continue;
397 408
398 for (i = 0; i < nsyms && found < 2; i += cbEXTR) 409 x = ds_base[rd_base[i].index];
399 { 410
400 register pEXTR x = (pEXTR) (old + symoff + i); 411#if 0
401 char *s; 412 fprintf (stderr, "Object inspected: %s, addr = %lx, shndx = %x",
402 413 old + dynstr_section->s_scnptr + x.st_name, rd_base[i].addr, x.st_shndx);
403 s = old + stroff + x->asym.iss; /* name of the symbol */ 414#endif
404 415
405 if (!strcmp(s,"_edata")) 416
406 { 417 if ((ELF32_ST_BIND (x.st_info) == STB_GLOBAL)
407 found++; 418 && (x.st_shndx == 0)
408 bcopy (x, &n_edata, cbEXTR); 419 /* && (x.st_value == NULL) */
409 n_edata.asym.value = Brk; 420 ) {
410 SEEK (new, newsyms + cbHDRR + i, 421 /* OK, this is probably a reference to an object in a shared
411 "seeking to symbol _edata in %s", new_name); 422 library, so copy the old value. This is done in several steps:
412 WRITE (new, &n_edata, cbEXTR, 423 1. reladdr is the address of the location in question relative to
413 "writing symbol table entry for _edata into %s", new_name); 424 the start of the data section,
414 } 425 2. oldref is the addr is the mapped in temacs executable,
415 else if (!strcmp(s,"_end")) 426 3. newref is the address of the location in question in the
416 { 427 undumped executable,
417 found++; 428 4. len is the size of the object reference in bytes --
418 bcopy (x, &n_end, cbEXTR); 429 currently only 4 (long) and 8 (quad) are supported.
419 n_end.asym.value = Brk; 430 */
420 SEEK (new, newsyms + cbHDRR + i, 431 register unsigned long reladdr = rd_base[i].addr - old_data_scnhdr.s_vaddr;
421 "seeking to symbol _end in %s", new_name); 432 char * oldref = old + old_data_scnhdr.s_scnptr + reladdr;
422 WRITE (new, &n_end, cbEXTR, 433 unsigned long newref = aout.tsize + reladdr;
423 "writing symbol table entry for _end into %s", new_name); 434 int len;
424 } 435
436#if 0
437 fprintf (stderr, "...relocated\n");
438#endif
439
440 if (rd_base[i].type == R_REFLONG)
441 len = 4;
442 else if (rd_base[i].type == R_REFQUAD)
443 len = 8;
444 else
445 fatal_unexec ("unrecognized relocation type in .dyn.rel section (symbol #%d)", i);
446
447 SEEK (new, newref, "seeking to dynamic symbol in %s", new_name);
448 WRITE (new, oldref, len, "writing old dynrel info in %s", new_name);
425 } 449 }
426 450
451#if 0
452 else
453 fprintf (stderr, "...not relocated\n");
454#endif
455
456 }
457
427} 458}
428 459
429#endif 460#endif /* !__linux__ */
430 461
431 462
432/* 463/*